texlive[61672] Build/source/utils: asy 2.76 sources

commits+karl at tug.org commits+karl at tug.org
Thu Jan 20 22:32:09 CET 2022


Revision: 61672
          http://tug.org/svn/texlive?view=revision&revision=61672
Author:   karl
Date:     2022-01-20 22:32:08 +0100 (Thu, 20 Jan 2022)
Log Message:
-----------
asy 2.76 sources

Modified Paths:
--------------
    trunk/Build/source/utils/README
    trunk/Build/source/utils/asymptote/ChangeLog
    trunk/Build/source/utils/asymptote/GLTextures.h
    trunk/Build/source/utils/asymptote/README
    trunk/Build/source/utils/asymptote/ReleaseNotes
    trunk/Build/source/utils/asymptote/abs3doutfile.h
    trunk/Build/source/utils/asymptote/asy-keywords.el
    trunk/Build/source/utils/asymptote/asymptote.spec
    trunk/Build/source/utils/asymptote/base/v3d.asy
    trunk/Build/source/utils/asymptote/base/v3dheadertypes.asy
    trunk/Build/source/utils/asymptote/base/v3dtypes.asy
    trunk/Build/source/utils/asymptote/base/webgl/asygl.js
    trunk/Build/source/utils/asymptote/config.guess
    trunk/Build/source/utils/asymptote/configure
    trunk/Build/source/utils/asymptote/configure.ac
    trunk/Build/source/utils/asymptote/doc/CAD.pdf
    trunk/Build/source/utils/asymptote/doc/FAQ/asy-faq.info
    trunk/Build/source/utils/asymptote/doc/TeXShopAndAsymptote.pdf
    trunk/Build/source/utils/asymptote/doc/asy-latex.pdf
    trunk/Build/source/utils/asymptote/doc/asyRefCard.pdf
    trunk/Build/source/utils/asymptote/doc/asymptote.pdf
    trunk/Build/source/utils/asymptote/doc/asymptote.texi
    trunk/Build/source/utils/asymptote/doc/png/asymptote.info
    trunk/Build/source/utils/asymptote/drawsurface.h
    trunk/Build/source/utils/asymptote/glrender.cc
    trunk/Build/source/utils/asymptote/glrender.h
    trunk/Build/source/utils/asymptote/interact.cc
    trunk/Build/source/utils/asymptote/jsfile.cc
    trunk/Build/source/utils/asymptote/jsfile.h
    trunk/Build/source/utils/asymptote/lspserv.cc
    trunk/Build/source/utils/asymptote/main.cc
    trunk/Build/source/utils/asymptote/material.h
    trunk/Build/source/utils/asymptote/patches/dvipdf
    trunk/Build/source/utils/asymptote/picture.cc
    trunk/Build/source/utils/asymptote/revision.cc
    trunk/Build/source/utils/asymptote/settings.cc
    trunk/Build/source/utils/asymptote/symbol.h
    trunk/Build/source/utils/asymptote/symbolmaps.h
    trunk/Build/source/utils/asymptote/tinyexr.cc
    trunk/Build/source/utils/asymptote/v3dfile.cc
    trunk/Build/source/utils/asymptote/v3dfile.h
    trunk/Build/source/utils/asymptote/v3dheadertypes.csv
    trunk/Build/source/utils/asymptote/v3dheadertypes.h
    trunk/Build/source/utils/asymptote/v3dheadertypes.py
    trunk/Build/source/utils/asymptote/v3dtypes.h
    trunk/Build/source/utils/asymptote/v3dtypes.py
    trunk/Build/source/utils/asymptote/webgl/gl.js
    trunk/Build/source/utils/asymptote/webgl/license
    trunk/Build/source/utils/asymptote/xstream.h

Added Paths:
-----------
    trunk/Build/source/utils/asymptote/examples/twoSpheres.asy

Modified: trunk/Build/source/utils/README
===================================================================
--- trunk/Build/source/utils/README	2022-01-20 21:28:28 UTC (rev 61671)
+++ trunk/Build/source/utils/README	2022-01-20 21:32:08 UTC (rev 61672)
@@ -4,7 +4,7 @@
 Extra utilities we (optionally) compile for TeX Live.
 See comments in ../texk/README.
 
-asymptote 2.75 - checked 8jan22
+asymptote 2.76 - checked 20jan22
   update to TL from CTAN, to include prebuilt doc.
   see https://tug.org/texlive/build.html#asymptote
   and tlpkg/bin/tl-update-asy

Modified: trunk/Build/source/utils/asymptote/ChangeLog
===================================================================
--- trunk/Build/source/utils/asymptote/ChangeLog	2022-01-20 21:28:28 UTC (rev 61671)
+++ trunk/Build/source/utils/asymptote/ChangeLog	2022-01-20 21:32:08 UTC (rev 61672)
@@ -1,3 +1,259 @@
+commit ea218793876b65bbd50a842ede9fd003dcd90978
+Author: John Bowman <bowman at ualberta.ca>
+Date:   Wed Jan 19 21:56:54 2022 -0700
+
+    Implement --disable-threads configure option.
+
+commit 9c2c06849def96507147c2cab66e1da9ecd36d1b
+Author: John Bowman <bowman at ualberta.ca>
+Date:   Wed Jan 19 15:11:35 2022 -0700
+
+    Update asymptote.spec.
+
+commit 96f9ffde0b7a6b3b8f8b2906cd62858bbca64594
+Author: John Bowman <bowman at ualberta.ca>
+Date:   Wed Jan 19 15:10:10 2022 -0700
+
+    Port to OpenBSD.
+
+commit 81f988a7679b355edf2a7c3c2c6cf2f7d9ba88e1
+Author: John Bowman <bowman at ualberta.ca>
+Date:   Wed Jan 19 13:59:59 2022 -0700
+
+    Support compilation with editline but not readline installed.
+
+commit 07f71cdfd7ecec7cd2a9bac10dc0a432f5ad6b16
+Author: John Bowman <bowman at ualberta.ca>
+Date:   Wed Jan 19 11:31:11 2022 -0700
+
+    Update asygl.
+
+commit f5bc40b62a3ed7095aaaea03da43d86fba68d320
+Author: John Bowman <bowman at ualberta.ca>
+Date:   Wed Jan 19 11:30:08 2022 -0700
+
+    Set asyProjection=false if AWA has cleared currentprojection.
+
+commit dc6284164c5518bc5e7914db21613d383b784472
+Author: John Bowman <bowman at ualberta.ca>
+Date:   Wed Jan 19 08:27:37 2022 -0700
+
+    Support compilation without OpenGL again.
+
+commit 474a2fefda7f46706cb64348c7a96780773bed0d
+Author: John Bowman <bowman at ualberta.ca>
+Date:   Tue Jan 18 22:20:30 2022 -0700
+
+    Revert "Update asygl."
+    
+    This reverts commit 58dd3eb5cdbc07eeb28459fb0376e12de0fe8342.
+
+commit 58dd3eb5cdbc07eeb28459fb0376e12de0fe8342
+Author: John Bowman <bowman at ualberta.ca>
+Date:   Tue Jan 18 21:28:36 2022 -0700
+
+    Update asygl.
+
+commit 602d2864b88f752de06f93ffb9401d201afb741b
+Author: John Bowman <bowman at ualberta.ca>
+Date:   Tue Jan 18 21:25:50 2022 -0700
+
+    WebGL: Make currentprojection persistent under AWA, resettable with the h key.
+
+commit 2154532907ab2feadaa85132bc36f3333f92e058
+Author: John Bowman <bowman at ualberta.ca>
+Date:   Mon Jan 17 22:46:48 2022 -0700
+
+    Add example of 3D transparency; update credits.
+
+commit ea0197ffe7ede6065f49c617b5d4eed53d081b51
+Author: John Bowman <bowman at ualberta.ca>
+Date:   Mon Jan 17 16:51:26 2022 -0700
+
+    Update asygl.
+
+commit 737b1474d818fee9a56a9d354d9cdbb72896e36a
+Author: John Bowman <bowman at ualberta.ca>
+Date:   Mon Jan 17 16:45:42 2022 -0700
+
+    Fix perspective WebGL zoom; update AWA interface; make home (h key) reset camera.
+
+commit 55cef74a3cbf723acb22e94d3fc94bf6d94e5c03
+Author: John Bowman <bowman at ualberta.ca>
+Date:   Fri Jan 14 21:43:27 2022 -0700
+
+    Update asygl.
+
+commit d4384284d24de663df078bfdd12bb3cc92d1eb01
+Author: John Bowman <bowman at ualberta.ca>
+Date:   Fri Jan 14 21:40:40 2022 -0700
+
+    Fix WebGL zoom and AWA interface.
+
+commit ececb384b5d090b4762669384ef8e23a9c62b47d
+Author: John Bowman <bowman at ualberta.ca>
+Date:   Fri Jan 14 20:59:19 2022 -0700
+
+    Update asygl.
+
+commit e9ed81a252727b62cdc356675afd1a3ccdfed19f
+Author: John Bowman <bowman at ualberta.ca>
+Date:   Fri Jan 14 20:46:02 2022 -0700
+
+    Fix WebGL and v3d bounds, along with orthographic viewportshift.
+
+commit 36b3ac4071f60e93eb01d48d87ac406674602363
+Author: John Bowman <bowman at ualberta.ca>
+Date:   Thu Jan 13 21:44:17 2022 -0700
+
+    Port to MacOS X Mojave.
+
+commit 4b44415684c5691d5adba94090e65c32f28f6ead
+Author: John Bowman <bowman at ualberta.ca>
+Date:   Thu Jan 13 21:00:24 2022 -0700
+
+    Update asygl.
+
+commit 11791aeb58b1fef2eddd67137d74f17f6ff00f77
+Author: John Bowman <bowman at ualberta.ca>
+Date:   Thu Jan 13 20:57:59 2022 -0700
+
+    Update AWA camera interface.
+
+commit a50bfa364e9615571fca8603887f289c74529c0f
+Author: John Bowman <bowman at ualberta.ca>
+Date:   Thu Jan 13 11:35:32 2022 -0700
+
+    Update asymptote.spec.
+
+commit ebfb8abf123d7bef8c811267df0e706b5dec6f77
+Author: John Bowman <bowman at ualberta.ca>
+Date:   Mon Jan 10 22:49:43 2022 -0700
+
+    Update asygl.
+
+commit 9a3e2c57bacd2692310f74fac49c6fd84ba0f56b
+Author: John Bowman <bowman at ualberta.ca>
+Date:   Mon Jan 10 22:48:36 2022 -0700
+
+    Fix WebGL orthographic camera zoom.
+
+commit 58c7c1c73de228668058fca14402cc98dfb35232
+Author: John Bowman <bowman at ualberta.ca>
+Date:   Sun Jan 9 23:55:30 2022 -0700
+
+    Update asygl.
+
+commit e50bd57eec565f5844e883284ff9dbb9352a0e35
+Author: John Bowman <bowman at ualberta.ca>
+Date:   Sun Jan 9 23:54:44 2022 -0700
+
+    Fix WebGL perspective camera zoom.
+
+commit 67af72f3c39072b761d9ff4a2b6a8c79d964cd69
+Author: John Bowman <bowman at ualberta.ca>
+Date:   Sun Jan 9 16:07:27 2022 -0700
+
+    Improve WebGL camera dialogue.
+
+commit 8a3ce22eb86a100bcf595eaecca028737dba953a
+Author: John Bowman <bowman at ualberta.ca>
+Date:   Sun Jan 9 12:55:00 2022 -0700
+
+    Update asygl.
+
+commit 6c78b3774919d8d4cb67ca7ec90fee97334b852a
+Author: John Bowman <bowman at ualberta.ca>
+Date:   Sun Jan 9 12:53:02 2022 -0700
+
+    Fix WebGL camera zoom.
+
+commit 8aacd2ca1de83c434f642ea94700ffd6753f0a92
+Author: John Bowman <bowman at ualberta.ca>
+Date:   Sun Jan 9 09:02:05 2022 -0700
+
+    Set defaultfilename on reading V3D files from command line.
+
+commit 9c33d0c30ce70909819e4347fdb8887f4bf956b7
+Author: John Bowman <bowman at ualberta.ca>
+Date:   Sun Jan 9 09:01:48 2022 -0700
+
+    Update URL.
+
+commit 4c5698f614a27809203a2227a0365babf37cd732
+Author: John Bowman <bowman at ualberta.ca>
+Date:   Sat Jan 8 23:29:34 2022 -0700
+
+    Support compilation again without glm-devel library (not recommended,
+    as this will disable both WebGL and V3D support).
+
+commit 48f313effd296591c3c44155736ba98f03a68535
+Author: John Bowman <bowman at ualberta.ca>
+Date:   Sat Jan 8 11:03:55 2022 -0700
+
+    Work around undefined PATH_MAX on hurd-i386.
+
+commit 11446596bd9dfa23e4520dcf44459f9978097581
+Author: John Bowman <bowman at ualberta.ca>
+Date:   Sat Jan 8 00:00:06 2022 -0700
+
+    Fix v3d currentprojections.
+
+commit f94c059c64c75728aeb91baff8c56dac8a119aa9
+Author: John Bowman <bowman at ualberta.ca>
+Date:   Fri Jan 7 22:04:22 2022 -0700
+
+    Update asygl.
+
+commit b5796a262ddcab47a4e407cf23b6e00585dbb57d
+Author: John Bowman <bowman at ualberta.ca>
+Date:   Fri Jan 7 21:59:06 2022 -0700
+
+    Support 'c' (show camera) WebGL keyboard binding for orthographic projections
+    and offscreen rendering.
+
+commit c451c4ade38baeae87a2e2019c489350002f95f5
+Author: John Bowman <bowman at ualberta.ca>
+Date:   Fri Jan 7 21:41:34 2022 -0700
+
+    Update asygl.
+
+commit e36c308d119354b43f0cadae2d53bd5fc4a5110d
+Author: John Bowman <bowman at ualberta.ca>
+Date:   Fri Jan 7 21:34:15 2022 -0700
+
+    Add 'c' (show camera) keyboard binding to WebGL scenes.
+
+commit 59487ff216cf2c425a1e0b356b9f8d09c492f2e2
+Author: John Bowman <bowman at ualberta.ca>
+Date:   Fri Jan 7 09:01:01 2022 -0700
+
+    Update copyright years.
+
+commit 4f18f4fcb254a47f76ff832614154051960095fe
+Author: John Bowman <bowman at ualberta.ca>
+Date:   Fri Jan 7 08:15:02 2022 -0700
+
+    Fix typo #294.
+
+commit c4cd63b759f38a0c9d699713af8e7947dabe7ea0
+Author: John Bowman <bowman at ualberta.ca>
+Date:   Thu Jan 6 22:37:36 2022 -0700
+
+    Update asymptote.spec.
+
+commit bfc97490c7c17118bbe106adac7f4de63420c1dc
+Author: John Bowman <bowman at ualberta.ca>
+Date:   Thu Jan 6 22:06:42 2022 -0700
+
+    Update dvipdf.
+
+commit 41cf587359166f67b481e1fc87bfe6de24fe98ee
+Author: John Bowman <bowman at ualberta.ca>
+Date:   Thu Jan 6 17:07:28 2022 -0700
+
+    Increment version to 2.76.
+
 commit 587b26dca79cad5a31100a30bee9cc4a9dcd93e8
 Author: John Bowman <bowman at ualberta.ca>
 Date:   Thu Jan 6 14:15:06 2022 -0700

Modified: trunk/Build/source/utils/asymptote/GLTextures.h
===================================================================
--- trunk/Build/source/utils/asymptote/GLTextures.h	2022-01-20 21:28:28 UTC (rev 61671)
+++ trunk/Build/source/utils/asymptote/GLTextures.h	2022-01-20 21:32:08 UTC (rev 61672)
@@ -3,7 +3,11 @@
 //
 
 #pragma once
+
 #include "common.h"
+
+#ifdef HAVE_GL
+
 #include "GL/glew.h"
 
 namespace gl
@@ -125,3 +129,5 @@
 };
 
 } // namespace gl
+
+#endif

Modified: trunk/Build/source/utils/asymptote/README
===================================================================
--- trunk/Build/source/utils/asymptote/README	2022-01-20 21:28:28 UTC (rev 61671)
+++ trunk/Build/source/utils/asymptote/README	2022-01-20 21:32:08 UTC (rev 61672)
@@ -1,5 +1,5 @@
 			  ASYMPTOTE
-      Copyright 2004-21 Andy Hammerlindl, John Bowman, and Tom Prince
+      Copyright 2004-22 Andy Hammerlindl, John Bowman, and Tom Prince
 
 Asymptote is a powerful descriptive vector graphics language for technical
 drawing, inspired by MetaPost but with an improved C++-like

Modified: trunk/Build/source/utils/asymptote/ReleaseNotes
===================================================================
--- trunk/Build/source/utils/asymptote/ReleaseNotes	2022-01-20 21:28:28 UTC (rev 61671)
+++ trunk/Build/source/utils/asymptote/ReleaseNotes	2022-01-20 21:32:08 UTC (rev 61672)
@@ -1,3 +1,11 @@
+Release Notes for Version 2.76
+
+WebGL and V3D bounds were fixed, along with the WebGL zoom and viewportshift.
+Under the Asymptote Web Application, the currentprojection is now persistant;
+for other WebGL instances, the 'c' keyboard binding can be used to display
+the currentprojection. The correct defaultfilename is set on reading V3D
+files from the command line. Portability issues were addressed.
+
 Release Notes for Version 2.75
 
 A 2D transparency bug was fixed. Vim support was improved.

Modified: trunk/Build/source/utils/asymptote/abs3doutfile.h
===================================================================
--- trunk/Build/source/utils/asymptote/abs3doutfile.h	2022-01-20 21:28:28 UTC (rev 61671)
+++ trunk/Build/source/utils/asymptote/abs3doutfile.h	2022-01-20 21:32:08 UTC (rev 61672)
@@ -34,7 +34,9 @@
   virtual void addStraightBezierTriangle(
           triple const* controls, triple const& Min, triple const& Max, prc::RGBAColour const* c) = 0;
 
+#ifdef HAVE_LIBGLM
   virtual void addMaterial(Material const& mat) = 0;
+#endif
 
   virtual void addSphere(triple const& center, double radius) = 0;
 

Modified: trunk/Build/source/utils/asymptote/asy-keywords.el
===================================================================
--- trunk/Build/source/utils/asymptote/asy-keywords.el	2022-01-20 21:28:28 UTC (rev 61671)
+++ trunk/Build/source/utils/asymptote/asy-keywords.el	2022-01-20 21:32:08 UTC (rev 61672)
@@ -2,7 +2,7 @@
 ;; This file is automatically generated by asy-list.pl.
 ;; Changes will be overwritten.
 ;;
-(defvar asy-keywords-version "2.75")
+(defvar asy-keywords-version "2.76")
 
 (defvar asy-keyword-name '(
 and controls tension atleast curl if else while for do return break continue struct typedef new access import unravel from include quote static public private restricted this explicit true false null cycle newframe operator ))

Modified: trunk/Build/source/utils/asymptote/asymptote.spec
===================================================================
--- trunk/Build/source/utils/asymptote/asymptote.spec	2022-01-20 21:28:28 UTC (rev 61671)
+++ trunk/Build/source/utils/asymptote/asymptote.spec	2022-01-20 21:32:08 UTC (rev 61672)
@@ -3,7 +3,7 @@
 %global __python %{__python3}
 
 Name:           asymptote
-Version:        2.75
+Version:        2.76
 Release:        1%{?dist}
 Summary:        Descriptive vector graphics language
 
@@ -13,6 +13,7 @@
 Source:         http://downloads.sourceforge.net/sourceforge/asymptote/asymptote-%{version}.src.tgz
 BuildRoot:      %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
 
+BuildRequires:  gcc-c++
 BuildRequires:  ncurses-devel
 BuildRequires:  readline-devel
 BuildRequires:  fftw-devel >= 3.0
@@ -20,15 +21,19 @@
 BuildRequires:  gsl-devel
 BuildRequires:  glm-devel
 BuildRequires:  tetex-latex
-BuildRequires:  ghostscript >= 9.52
-BuildRequires:  dvisvgm >= 2.9.1
+BuildRequires:  ghostscript >= 9.55
 BuildRequires:  texinfo >= 4.7
-BuildRequires:  ImageMagick
+BuildRequires:  freeglut-devel
+BuildRequires:  zlib-devel
+BuildRequires:  libtool
 BuildRequires:  libtirpc-devel
 BuildRequires:  libboost-devel
+BuildRequires:  libglvnd-devel
 
 Requires:       tetex-latex
 Requires:       freeglut-devel >= 3.0.0
+Requires:       dvisvgm >= 2.9.1
+Requires:       ImageMagick
 Requires(post): /usr/bin/texhash /sbin/install-info
 Requires(postun): /usr/bin/texhash /sbin/install-info
 

Modified: trunk/Build/source/utils/asymptote/base/v3d.asy
===================================================================
--- trunk/Build/source/utils/asymptote/base/v3d.asy	2022-01-20 21:28:28 UTC (rev 61671)
+++ trunk/Build/source/utils/asymptote/base/v3d.asy	2022-01-20 21:32:08 UTC (rev 61672)
@@ -33,7 +33,8 @@
   bool orthographic;
   real angle;
   real Zoom0;
-  pair viewportMargin;
+  pair viewportshift;
+  pair viewportmargin;
 
   light light;
 
@@ -43,9 +44,13 @@
     triple center=0.5*(b.z+B.z)*Z;
 
     if(orthographic)
-      currentprojection=orthographic(Z,target=center);
+      currentprojection=orthographic(Z,target=center,Zoom0,
+                                     viewportshift=viewportshift);
     else
-      currentprojection=perspective(Z,Y,target=center,Zoom0,degrees(angle),autoadjust=false);
+      currentprojection=perspective(Z,Y,target=center,Zoom0,
+                                    degrees(2.0*atan(tan(0.5*angle)/Zoom0)),
+                                    viewportshift=viewportshift,
+                                    autoadjust=false);
     light.specular=light.diffuse;
     currentlight=light;
   }
@@ -204,9 +209,13 @@
           {
             ci.Zoom0=xdrfile;
           }
+        else if (headerKey==v3dheadertypes.viewportShift)
+          {
+            ci.viewportshift=xdrfile;
+          }
         else if (headerKey==v3dheadertypes.viewportMargin)
           {
-            ci.viewportMargin=xdrfile;
+            ci.viewportmargin=xdrfile;
           }
         else if (headerKey==v3dheadertypes.background)
           {

Modified: trunk/Build/source/utils/asymptote/base/v3dheadertypes.asy
===================================================================
--- trunk/Build/source/utils/asymptote/base/v3dheadertypes.asy	2022-01-20 21:28:28 UTC (rev 61671)
+++ trunk/Build/source/utils/asymptote/base/v3dheadertypes.asy	2022-01-20 21:32:08 UTC (rev 61672)
@@ -1,6 +1,6 @@
 // Enum class for v3dheadertypes
 // AUTO-GENERATED from v3dheadertypes.csv
-// Generated at 2022-01-06 15:01:16.486016
+// Generated at 2022-01-19 22:30:10.732250
 
 struct v3dheadertypes
 {
@@ -8,7 +8,7 @@
 // UINT  Canvas width
 
   int canvasHeight=2;
-// UINT  Canvas height
+// UINT  Canvas heighot
 
   int absolute=3;
 // BOOL  true: absolute size; false: scale to canvas
@@ -23,7 +23,7 @@
 // BOOL  true: orthographic; false: perspective
 
   int angleOfView=7;
-// REAL  Field of view angle
+// REAL  Field of view angle (in radians)
 
   int initialZoom=8;
 // REAL  Initial zoom

Modified: trunk/Build/source/utils/asymptote/base/v3dtypes.asy
===================================================================
--- trunk/Build/source/utils/asymptote/base/v3dtypes.asy	2022-01-20 21:28:28 UTC (rev 61671)
+++ trunk/Build/source/utils/asymptote/base/v3dtypes.asy	2022-01-20 21:32:08 UTC (rev 61672)
@@ -1,6 +1,6 @@
 // Enum class for v3dtypes
 // AUTO-GENERATED from v3dtypes.csv
-// Generated at 2022-01-06 15:01:16.457740
+// Generated at 2022-01-19 22:30:10.647049
 
 struct v3dtypes
 {

Modified: trunk/Build/source/utils/asymptote/base/webgl/asygl.js
===================================================================
--- trunk/Build/source/utils/asymptote/base/webgl/asygl.js	2022-01-20 21:28:28 UTC (rev 61671)
+++ trunk/Build/source/utils/asymptote/base/webgl/asygl.js	2022-01-20 21:32:08 UTC (rev 61672)
@@ -1,6 +1,6 @@
 /*@license
  AsyGL: Render Bezier patches and triangles via subdivision with WebGL.
-  Copyright 2019-2021: John C. Bowman and Supakorn "Jamie" Rassameemasmuang
+  Copyright 2019-2022: John C. Bowman and Supakorn "Jamie" Rassameemasmuang
   University of Alberta
 
 This program is free software; you can redistribute it and/or modify
@@ -36,4 +36,4 @@
 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 THE SOFTWARE.*/
-let vertex="\n#ifdef WEBGL2\n#define IN in\n#define OUT out\n#else\n#define IN attribute\n#define OUT varying\n#endif\n\nIN vec3 position;\n#ifdef WIDTH\nIN float width;\n#endif\n#ifdef NORMAL\nIN vec3 normal;\n#endif\n\nIN float materialIndex;\n\n#ifdef WEBGL2\nflat out int MaterialIndex;\n#ifdef COLOR\nOUT vec4 Color;\n#endif\n\n#else\nOUT vec4 diffuse;\nOUT vec3 specular;\nOUT float roughness,metallic,fresnel0;\nOUT vec4 emissive;\n\nstruct Material {\n  vec4 diffuse,emissive,specular;\n  vec4 parameters;\n};\n\nuniform Material Materials[Nmaterials];\n#endif\n\n#ifdef COLOR\nIN vec4 color;\n#endif\n\nuniform mat3 normMat;\nuniform mat4 viewMat;\nuniform mat4 projViewMat;\n\n#ifdef NORMAL\n#ifndef ORTHOGRAPHIC\nOUT vec3 ViewPosition;\n#endif\nOUT vec3 Normal;\n#endif\n\nvoid main(void)\n{\n  vec4 v=vec4(position,1.0);\n  gl_Position=projViewMat*v;\n\n#ifdef NORMAL\n#ifndef ORTHOGRAPHIC\n  ViewPosition=(viewMat*v).xyz;\n#endif\n  Normal=normalize(normal*normMat);\n#endif\n\n#ifdef WEBGL2\n  MaterialIndex=int(materialIndex);\n#ifdef COLOR\n  Color=color;\n#endif\n#else\n#ifdef NORMAL\n  Material m;\n#ifdef TRANSPARENT\n  m=Materials[int(abs(materialIndex))-1];\n  emissive=m.emissive;\n  if(materialIndex >= 0.0)\n    diffuse=m.diffuse;\n  else {\n    diffuse=color;\n#if nlights == 0\n    emissive += color;\n#endif\n  }\n#else\n  m=Materials[int(materialIndex)];\n  emissive=m.emissive;\n#ifdef COLOR\n  diffuse=color;\n#if nlights == 0\n    emissive += color;\n#endif\n#else\n  diffuse=m.diffuse;\n#endif // COLOR\n#endif // TRANSPARENT\n  specular=m.specular.rgb;\n  vec4 parameters=m.parameters;\n  roughness=1.0-parameters[0];\n  metallic=parameters[1];\n  fresnel0=parameters[2];\n#else\n  emissive=Materials[int(materialIndex)].emissive;\n#endif // NORMAL\n#endif // WEBGL2\n\n#ifdef WIDTH\n  gl_PointSize=width;\n#endif\n}\n",fragment="\n#ifdef WEBGL2\n#define IN in\nout vec4 outValue;\n#define OUTVALUE outValue\n#else\n#define IN varying\n#define OUTVALUE gl_FragColor\n#endif\n\n#ifdef WEBGL2\nflat in int !
 MaterialIndex;\n\nstruct Material {\n  vec4 diffuse,emissive,specular;\n  vec4 parameters;\n};\n\nuniform Material Materials[Nmaterials];\n\nvec4 diffuse;\nvec3 specular;\nfloat roughness,metallic,fresnel0;\nvec4 emissive;\n\n#ifdef COLOR\nin vec4 Color;\n#endif\n\n#else\nIN vec4 diffuse;\nIN vec3 specular;\nIN float roughness,metallic,fresnel0;\nIN vec4 emissive;\n#endif\n\n#ifdef NORMAL\n\n#ifndef ORTHOGRAPHIC\nIN vec3 ViewPosition;\n#endif\nIN vec3 Normal;\n\nvec3 normal;\n\nstruct Light {\n  vec3 direction;\n  vec3 color;\n};\n\nuniform Light Lights[Nlights];\n\n#ifdef USE_IBL\nuniform sampler2D reflBRDFSampler;\nuniform sampler2D diffuseSampler;\nuniform sampler2D reflImgSampler;\n\nconst float pi=acos(-1.0);\nconst float piInv=1.0/pi;\nconst float twopi=2.0*pi;\nconst float twopiInv=1.0/twopi;\n\n// (x,y,z) -> (r,theta,phi);\n// theta -> [0,pi]: colatitude\n// phi -> [-pi,pi]: longitude\nvec3 cart2sphere(vec3 cart)\n{\n  float x=cart.x;\n  float y=cart.z;\n  float z=cart.y;\n\n  float r=length(cart);\n  float theta=r > 0.0 ? acos(z/r) : 0.0;\n  float phi=atan(y,x);\n\n  return vec3(r,theta,phi);\n}\n\nvec2 normalizedAngle(vec3 cartVec)\n{\n  vec3 sphericalVec=cart2sphere(cartVec);\n  sphericalVec.y=sphericalVec.y*piInv;\n  sphericalVec.z=0.75-sphericalVec.z*twopiInv;\n  return sphericalVec.zy;\n}\n\nvec3 IBLColor(vec3 viewDir)\n{\n  vec3 IBLDiffuse=diffuse.rgb*texture(diffuseSampler,normalizedAngle(normal)).rgb;\n  vec3 reflectVec=normalize(reflect(-viewDir,normal));\n  vec2 reflCoord=normalizedAngle(reflectVec);\n  vec3 IBLRefl=textureLod(reflImgSampler,reflCoord,roughness*ROUGHNESS_STEP_COUNT).rgb;\n  vec2 IBLbrdf=texture(reflBRDFSampler,vec2(dot(normal,viewDir),roughness)).rg;\n  float specularMultiplier=fresnel0*IBLbrdf.x+IBLbrdf.y;\n  vec3 dielectric=IBLDiffuse+specularMultiplier*IBLRefl;\n  vec3 metal=diffuse.rgb*IBLRefl;\n  return mix(dielectric,metal,metallic);\n}\n#else\nfloat Roughness2;\nfloat NDF_TRG(vec3 h)\n{\n  float ndoth=max(dot(normal,h),0.0);\n  float alpha2=Roughness2*Roughness2;\n  flo!
 at denom=ndoth*ndoth*(alpha2-1.0)+1.0;\n  return denom != 0.0 ? alpha2/(denom*denom) : 0.0;\n}\n\nfloat GGX_Geom(vec3 v)\n{\n  float ndotv=max(dot(v,normal),0.0);\n  float ap=1.0+Roughness2;\n  float k=0.125*ap*ap;\n  return ndotv/((ndotv*(1.0-k))+k);\n}\n\nfloat Geom(vec3 v, vec3 l)\n{\n  return GGX_Geom(v)*GGX_Geom(l);\n}\n\nfloat Fresnel(vec3 h, vec3 v, float fresnel0)\n{\n  float a=1.0-max(dot(h,v),0.0);\n  float b=a*a;\n  return fresnel0+(1.0-fresnel0)*b*b*a;\n}\n\n// physical based shading using UE4 model.\nvec3 BRDF(vec3 viewDirection, vec3 lightDirection)\n{\n  vec3 lambertian=diffuse.rgb;\n  vec3 h=normalize(lightDirection+viewDirection);\n\n  float omegain=max(dot(viewDirection,normal),0.0);\n  float omegaln=max(dot(lightDirection,normal),0.0);\n\n  float D=NDF_TRG(h);\n  float G=Geom(viewDirection,lightDirection);\n  float F=Fresnel(h,viewDirection,fresnel0);\n\n  float denom=4.0*omegain*omegaln;\n  float rawReflectance=denom > 0.0 ? (D*G)/denom : 0.0;\n\n  vec3 dielectric=mix(lambertian,rawReflectance*specular,F);\n  vec3 metal=rawReflectance*diffuse.rgb;\n\n  return mix(dielectric,metal,metallic);\n}\n#endif\n\n#endif\n\nvoid main(void)\n{\n#ifdef WEBGL2\n#ifdef NORMAL\n  Material m;\n#ifdef TRANSPARENT\n  m=Materials[abs(MaterialIndex)-1];\n  emissive=m.emissive;\n  if(MaterialIndex >= 0)\n    diffuse=m.diffuse;\n  else {\n    diffuse=Color;\n#if nlights == 0\n    emissive += Color;\n#endif\n  }\n#else\n  m=Materials[MaterialIndex];\n  emissive=m.emissive;\n#ifdef COLOR\n  diffuse=Color;\n#if nlights == 0\n    emissive += Color;\n#endif\n#else\n  diffuse=m.diffuse;\n#endif // COLOR\n#endif // TRANSPARENT\n  specular=m.specular.rgb;\n  vec4 parameters=m.parameters;\n  roughness=1.0-parameters[0];\n  metallic=parameters[1];\n  fresnel0=parameters[2];\n#else\n  emissive=Materials[MaterialIndex].emissive;\n#endif // NORMAL\n#endif // WEBGL2\n\n#if defined(NORMAL) && nlights > 0\n  normal=normalize(Normal);\n  normal=gl_FrontFacing ? normal : -normal;\n#ifdef ORTHOGRAPHIC\n  vec3 viewDir=vec3(0.0,0.0,1.!
 0);\n#else\n  vec3 viewDir=-normalize(ViewPosition);\n#endif\n\nvec3 color;\n#ifdef USE_IBL\n  color=IBLColor(viewDir);\n#else\n  Roughness2=roughness*roughness;\n  color=emissive.rgb;\n  for(int i=0; i < nlights; ++i) {\n    Light Li=Lights[i];\n    vec3 L=Li.direction;\n    float cosTheta=max(dot(normal,L),0.0);\n    vec3 radiance=cosTheta*Li.color;\n    color += BRDF(viewDir,L)*radiance;\n  }\n#endif\n  OUTVALUE=vec4(color,diffuse.a);\n#else\n  OUTVALUE=emissive;\n#endif\n}\n";!function(e,t){if("object"==typeof exports&&"object"==typeof module)module.exports=t();else if("function"==typeof define&&define.amd)define([],t);else{var i=t();for(var a in i)("object"==typeof exports?exports:e)[a]=i[a]}}("undefined"!=typeof self?self:this,(function(){return function(e){var t={};function i(a){if(t[a])return t[a].exports;var n=t[a]={i:a,l:!1,exports:{}};return e[a].call(n.exports,n,n.exports,i),n.l=!0,n.exports}return i.m=e,i.c=t,i.d=function(e,t,a){i.o(e,t)||Object.defineProperty(e,t,{configurable:!1,enumerable:!0,get:a})},i.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return i.d(t,"a",t),t},i.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},i.p="",i(i.s=1)}([function(e,t,i){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.setMatrixArrayType=function(e){t.ARRAY_TYPE=e},t.toRadian=function(e){return e*n},t.equals=function(e,t){return Math.abs(e-t)<=a*Math.max(1,Math.abs(e),Math.abs(t))};var a=t.EPSILON=1e-6;t.ARRAY_TYPE="undefined"!=typeof Float32Array?Float32Array:Array,t.RANDOM=Math.random;var n=Math.PI/180},function(e,t,i){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.mat4=t.mat3=void 0;var a=r(i(2)),n=r(i(3));function r(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var i in e)Object.prototype.hasOwnProperty.call(e,i)&&(t[i]=e[i]);return t.default=e,t}t.mat3=a,t.mat4=n},function(e,t,i){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.create=function(){var e=new a.ARRAY_TYPE(9);return e[0]=1,e[1]=0,e[2]=0!
 ,e[3]=0,e[4]=1,e[5]=0,e[6]=0,e[7]=0,e[8]=1,e},t.fromMat4=function(e,t){return e[0]=t[0],e[1]=t[1],e[2]=t[2],e[3]=t[4],e[4]=t[5],e[5]=t[6],e[6]=t[8],e[7]=t[9],e[8]=t[10],e},t.invert=function(e,t){var i=t[0],a=t[1],n=t[2],r=t[3],s=t[4],o=t[5],l=t[6],h=t[7],c=t[8],d=c*s-o*h,m=-c*r+o*l,f=h*r-s*l,u=i*d+a*m+n*f;if(!u)return null;return u=1/u,e[0]=d*u,e[1]=(-c*a+n*h)*u,e[2]=(o*a-n*s)*u,e[3]=m*u,e[4]=(c*i-n*l)*u,e[5]=(-o*i+n*r)*u,e[6]=f*u,e[7]=(-h*i+a*l)*u,e[8]=(s*i-a*r)*u,e};var a=function(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var i in e)Object.prototype.hasOwnProperty.call(e,i)&&(t[i]=e[i]);return t.default=e,t}(i(0))},function(e,t,i){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.create=function(){var e=new a.ARRAY_TYPE(16);return e[0]=1,e[1]=0,e[2]=0,e[3]=0,e[4]=0,e[5]=1,e[6]=0,e[7]=0,e[8]=0,e[9]=0,e[10]=1,e[11]=0,e[12]=0,e[13]=0,e[14]=0,e[15]=1,e},t.identity=function(e){return e[0]=1,e[1]=0,e[2]=0,e[3]=0,e[4]=0,e[5]=1,e[6]=0,e[7]=0,e[8]=0,e[9]=0,e[10]=1,e[11]=0,e[12]=0,e[13]=0,e[14]=0,e[15]=1,e},t.invert=function(e,t){var i=t[0],a=t[1],n=t[2],r=t[3],s=t[4],o=t[5],l=t[6],h=t[7],c=t[8],d=t[9],m=t[10],f=t[11],u=t[12],p=t[13],g=t[14],v=t[15],x=i*o-a*s,w=i*l-n*s,M=i*h-r*s,b=a*l-n*o,T=a*h-r*o,S=n*h-r*l,R=c*p-d*u,I=c*g-m*u,A=c*v-f*u,E=d*g-m*p,P=d*v-f*p,L=m*v-f*g,D=x*L-w*P+M*E+b*A-T*I+S*R;if(!D)return null;return D=1/D,e[0]=(o*L-l*P+h*E)*D,e[1]=(n*P-a*L-r*E)*D,e[2]=(p*S-g*T+v*b)*D,e[3]=(m*T-d*S-f*b)*D,e[4]=(l*A-s*L-h*I)*D,e[5]=(i*L-n*A+r*I)*D,e[6]=(g*M-u*S-v*w)*D,e[7]=(c*S-m*M+f*w)*D,e[8]=(s*P-o*A+h*R)*D,e[9]=(a*A-i*P-r*R)*D,e[10]=(u*T-p*M+v*x)*D,e[11]=(d*M-c*T-f*x)*D,e[12]=(o*I-s*E-l*R)*D,e[13]=(i*E-a*I+n*R)*D,e[14]=(p*w-u*b-g*x)*D,e[15]=(c*b-d*w+m*x)*D,e},t.multiply=n,t.translate=function(e,t,i){var a=i[0],n=i[1],r=i[2],s=void 0,o=void 0,l=void 0,h=void 0,c=void 0,d=void 0,m=void 0,f=void 0,u=void 0,p=void 0,g=void 0,v=void 0;t===e?(e[12]=t[0]*a+t[4]*n+t[8]*r+t[12],e[13]=t[1]*a+t[5]*n+t[9]*r+t[13],e[14]=t[2]*a+t[6]*n+t[10]*r+t[14],e[15]=t[3]*a+t[7]*n+t[11]*r+t[15]):(s=t[0],o=t[1],l=t[2],!
 h=t[3],c=t[4],d=t[5],m=t[6],f=t[7],u=t[8],p=t[9],g=t[10],v=t[11],e[0]=s,e[1]=o,e[2]=l,e[3]=h,e[4]=c,e[5]=d,e[6]=m,e[7]=f,e[8]=u,e[9]=p,e[10]=g,e[11]=v,e[12]=s*a+c*n+u*r+t[12],e[13]=o*a+d*n+p*r+t[13],e[14]=l*a+m*n+g*r+t[14],e[15]=h*a+f*n+v*r+t[15]);return e},t.rotate=function(e,t,i,n){var r,s,o,l,h,c,d,m,f,u,p,g,v,x,w,M,b,T,S,R,I,A,E,P,L=n[0],D=n[1],y=n[2],O=Math.sqrt(L*L+D*D+y*y);if(Math.abs(O)<a.EPSILON)return null;L*=O=1/O,D*=O,y*=O,r=Math.sin(i),s=Math.cos(i),o=1-s,l=t[0],h=t[1],c=t[2],d=t[3],m=t[4],f=t[5],u=t[6],p=t[7],g=t[8],v=t[9],x=t[10],w=t[11],M=L*L*o+s,b=D*L*o+y*r,T=y*L*o-D*r,S=L*D*o-y*r,R=D*D*o+s,I=y*D*o+L*r,A=L*y*o+D*r,E=D*y*o-L*r,P=y*y*o+s,e[0]=l*M+m*b+g*T,e[1]=h*M+f*b+v*T,e[2]=c*M+u*b+x*T,e[3]=d*M+p*b+w*T,e[4]=l*S+m*R+g*I,e[5]=h*S+f*R+v*I,e[6]=c*S+u*R+x*I,e[7]=d*S+p*R+w*I,e[8]=l*A+m*E+g*P,e[9]=h*A+f*E+v*P,e[10]=c*A+u*E+x*P,e[11]=d*A+p*E+w*P,t!==e&&(e[12]=t[12],e[13]=t[13],e[14]=t[14],e[15]=t[15]);return e},t.fromTranslation=function(e,t){return e[0]=1,e[1]=0,e[2]=0,e[3]=0,e[4]=0,e[5]=1,e[6]=0,e[7]=0,e[8]=0,e[9]=0,e[10]=1,e[11]=0,e[12]=t[0],e[13]=t[1],e[14]=t[2],e[15]=1,e},t.fromRotation=function(e,t,i){var n,r,s,o=i[0],l=i[1],h=i[2],c=Math.sqrt(o*o+l*l+h*h);if(Math.abs(c)<a.EPSILON)return null;return o*=c=1/c,l*=c,h*=c,n=Math.sin(t),r=Math.cos(t),s=1-r,e[0]=o*o*s+r,e[1]=l*o*s+h*n,e[2]=h*o*s-l*n,e[3]=0,e[4]=o*l*s-h*n,e[5]=l*l*s+r,e[6]=h*l*s+o*n,e[7]=0,e[8]=o*h*s+l*n,e[9]=l*h*s-o*n,e[10]=h*h*s+r,e[11]=0,e[12]=0,e[13]=0,e[14]=0,e[15]=1,e},t.frustum=function(e,t,i,a,n,r,s){var o=1/(i-t),l=1/(n-a),h=1/(r-s);return e[0]=2*r*o,e[1]=0,e[2]=0,e[3]=0,e[4]=0,e[5]=2*r*l,e[6]=0,e[7]=0,e[8]=(i+t)*o,e[9]=(n+a)*l,e[10]=(s+r)*h,e[11]=-1,e[12]=0,e[13]=0,e[14]=s*r*2*h,e[15]=0,e},t.ortho=function(e,t,i,a,n,r,s){var o=1/(t-i),l=1/(a-n),h=1/(r-s);return e[0]=-2*o,e[1]=0,e[2]=0,e[3]=0,e[4]=0,e[5]=-2*l,e[6]=0,e[7]=0,e[8]=0,e[9]=0,e[10]=2*h,e[11]=0,e[12]=(t+i)*o,e[13]=(n+a)*l,e[14]=(s+r)*h,e[15]=1,e};var a=function(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var i in e)Object.prototype.hasOwnProperty.call(e,i)&&!
 (t[i]=e[i]);return t.default=e,t}(i(0));function n(e,t,i){var a=t[0],n=t[1],r=t[2],s=t[3],o=t[4],l=t[5],h=t[6],c=t[7],d=t[8],m=t[9],f=t[10],u=t[11],p=t[12],g=t[13],v=t[14],x=t[15],w=i[0],M=i[1],b=i[2],T=i[3];return e[0]=w*a+M*o+b*d+T*p,e[1]=w*n+M*l+b*m+T*g,e[2]=w*r+M*h+b*f+T*v,e[3]=w*s+M*c+b*u+T*x,w=i[4],M=i[5],b=i[6],T=i[7],e[4]=w*a+M*o+b*d+T*p,e[5]=w*n+M*l+b*m+T*g,e[6]=w*r+M*h+b*f+T*v,e[7]=w*s+M*c+b*u+T*x,w=i[8],M=i[9],b=i[10],T=i[11],e[8]=w*a+M*o+b*d+T*p,e[9]=w*n+M*l+b*m+T*g,e[10]=w*r+M*h+b*f+T*v,e[11]=w*s+M*c+b*u+T*x,w=i[12],M=i[13],b=i[14],T=i[15],e[12]=w*a+M*o+b*d+T*p,e[13]=w*n+M*l+b*m+T*g,e[14]=w*r+M*h+b*f+T*v,e[15]=w*s+M*c+b*u+T*x,e}}])}));let canvasWidth,canvasHeight,imageURL,image,minBound,maxBound,orthographic,angleOfView,initialZoom,viewportMargin,zoomFactor,zoomPinchFactor,zoomPinchCap,zoomStep,shiftHoldDistance,shiftWaitTime,vibrateTime,canvasWidth0,canvasHeight0,zoom0,embedded,canvas,gl,alpha,offscreen,context,maxMaterials,halfCanvasWidth,halfCanvasHeight,P=[],Materials=[],Lights=[],Centers=[],Background=[1,1,1,1],absolute=!1,ibl=!1,viewportShift=[0,0],webgl2=!1,nlights=0,Nmaterials=2,materials=[];const pixelResolution=.75,zoomRemeshFactor=1.5,FillFactor=.1,windowTrim=10,third=1/3;let Zoom,lastZoom,maxViewportWidth,maxViewportHeight,H,zmin,zmax,size2,ArcballFactor,rotMat=mat4.create(),projMat=mat4.create(),viewMat=mat4.create(),projViewMat=mat4.create(),normMat=mat3.create(),viewMat3=mat3.create(),cjMatInv=mat4.create(),T=mat4.create(),center={x:0,y:0,z:0},shift={x:0,y:0},viewParam={xmin:0,xmax:0,ymin:0,ymax:0,zmin:0,zmax:0},remesh=!0,wireframe=0,mouseDownOrTouchActive=!1,lastMouseX=null,lastMouseY=null,touchID=null,Positions=[],Normals=[],Colors=[],Indices=[],IBLReflMap=null,IBLDiffuseMap=null,IBLbdrfMap=null;function IBLReady(){return null!==IBLReflMap&&null!==IBLDiffuseMap&&null!==IBLbdrfMap}function SetIBL(){embedded||deleteShaders(),initShaders(ibl)}let roughnessStepCount=8;class Material{constructor(e,t,i,a,n,r){this.diffuse=e,this.emissive=t,this.specular=i,this.shininess=a,this.metallic=n,!
 this.fresnel0=r}setUniform(e,t){let i=i=>gl.getUniformLocation(e,"Materials["+t+"]."+i);gl.uniform4fv(i("diffuse"),new Float32Array(this.diffuse)),gl.uniform4fv(i("emissive"),new Float32Array(this.emissive)),gl.uniform4fv(i("specular"),new Float32Array(this.specular)),gl.uniform4f(i("parameters"),this.shininess,this.metallic,this.fresnel0,0)}}let indexExt,TRIANGLES,material0Data,material1Data,materialData,colorData,transparentData,triangleData,materialIndex,enumPointLight=1,enumDirectionalLight=2;class Light{constructor(e,t){this.direction=e,this.color=t}setUniform(e,t){let i=i=>gl.getUniformLocation(e,"Lights["+t+"]."+i);gl.uniform3fv(i("direction"),new Float32Array(this.direction)),gl.uniform3fv(i("color"),new Float32Array(this.color))}}function initShaders(e=!1){let t=gl.getParameter(gl.MAX_VERTEX_UNIFORM_VECTORS);maxMaterials=Math.floor((t-14)/4),Nmaterials=Math.min(Math.max(Nmaterials,Materials.length),maxMaterials),pixelOpt=["WIDTH"],materialOpt=["NORMAL"],colorOpt=["NORMAL","COLOR"],transparentOpt=["NORMAL","COLOR","TRANSPARENT"],e&&(materialOpt.push("USE_IBL"),transparentOpt.push("USE_IBL")),pixelShader=initShader(pixelOpt),materialShader=initShader(materialOpt),colorShader=initShader(colorOpt),transparentShader=initShader(transparentOpt)}function deleteShaders(){gl.deleteProgram(transparentShader),gl.deleteProgram(colorShader),gl.deleteProgram(materialShader),gl.deleteProgram(pixelShader)}function saveAttributes(){let e=webgl2?window.top.document.asygl2[alpha]:window.top.document.asygl[alpha];e.gl=gl,e.nlights=Lights.length,e.Nmaterials=Nmaterials,e.maxMaterials=maxMaterials,e.pixelShader=pixelShader,e.materialShader=materialShader,e.colorShader=colorShader,e.transparentShader=transparentShader}function restoreAttributes(){let e=webgl2?window.top.document.asygl2[alpha]:window.top.document.asygl[alpha];gl=e.gl,nlights=e.nlights,Nmaterials=e.Nmaterials,maxMaterials=e.maxMaterials,pixelShader=e.pixelShader,materialShader=e.materialShader,colorShader=e.colorShader,transparentShader=e.transparentShader}funct!
 ion webGL(e,t){let i;return webgl2&&(i=e.getContext("webgl2",{alpha:t}),embedded&&!i)?(webgl2=!1,ibl=!1,initGL(!1),null):(i||(webgl2=!1,ibl=!1,i=e.getContext("webgl",{alpha:t})),i||alert("Could not initialize WebGL"),i)}function initGL(e=!0){if(ibl&&(webgl2=!0),alpha=Background[3]<1,embedded){let t=window.top.document;if(e&&(context=canvas.getContext("2d")),offscreen=webgl2?t.offscreen2:t.offscreen,offscreen||(offscreen=t.createElement("canvas"),webgl2?t.offscreen2=offscreen:t.offscreen=offscreen),webgl2?t.asygl2||(t.asygl2=Array(2)):t.asygl||(t.asygl=Array(2)),asygl=webgl2?t.asygl2:t.asygl,asygl[alpha]&&asygl[alpha].gl)restoreAttributes(),(Lights.length!=nlights||Math.min(Materials.length,maxMaterials)>Nmaterials)&&(initShaders(),saveAttributes());else{if(rc=webGL(offscreen,alpha),!rc)return;gl=rc,initShaders(),webgl2?t.asygl2[alpha]={}:t.asygl[alpha]={},saveAttributes()}}else gl=webGL(canvas,alpha),initShaders();indexExt=gl.getExtension("OES_element_index_uint"),TRIANGLES=gl.TRIANGLES,material0Data=new vertexBuffer(gl.POINTS),material1Data=new vertexBuffer(gl.LINES),materialData=new vertexBuffer,colorData=new vertexBuffer,transparentData=new vertexBuffer,triangleData=new vertexBuffer}function getShader(e,t,i,a=[]){let n=webgl2?"300 es":"100",r=Array(...a),s=[["nlights",0==wireframe?Lights.length:0],["Nmaterials",Nmaterials]],o=[["int","Nlights",Math.max(Lights.length,1)]];webgl2&&r.push("WEBGL2"),ibl&&s.push(["ROUGHNESS_STEP_COUNT",roughnessStepCount.toFixed(2)]),orthographic&&r.push("ORTHOGRAPHIC"),macros_str=s.map(e=>`#define ${e[0]} ${e[1]}`).join("\n"),define_str=r.map(e=>"#define "+e).join("\n"),const_str=o.map(e=>`const ${e[0]} ${e[1]}=${e[2]};`).join("\n"),ext_str=[].map(e=>`#extension ${e}: enable`).join("\n"),shaderSrc=`#version ${n}\n${ext_str}\n${define_str}\n${const_str}\n${macros_str}\n\n\n#ifdef GL_FRAGMENT_PRECISION_HIGH\nprecision highp float;\n#else\nprecision mediump float;\n#endif\n  \n${t}\n  `;let l=e.createShader(i);return e.shaderSource(l,shaderSrc),e.compileShader(l),e.getShaderParamete!
 r(l,e.COMPILE_STATUS)?l:(alert(e.getShaderInfoLog(l)),null)}function registerBuffer(e,t,i,a=gl.ARRAY_BUFFER){return e.length>0&&(0==t&&(t=gl.createBuffer(),i=!0),gl.bindBuffer(a,t),i&&gl.bufferData(a,e,gl.STATIC_DRAW)),t}function drawBuffer(e,t,i=e.indices){if(0==e.indices.length)return;let a=t!=pixelShader;setUniforms(e,t),null!=IBLDiffuseMap&&(gl.activeTexture(gl.TEXTURE0),gl.bindTexture(gl.TEXTURE_2D,IBLbdrfMap),gl.uniform1i(gl.getUniformLocation(t,"reflBRDFSampler"),0),gl.activeTexture(gl.TEXTURE1),gl.bindTexture(gl.TEXTURE_2D,IBLDiffuseMap),gl.uniform1i(gl.getUniformLocation(t,"diffuseSampler"),1),gl.activeTexture(gl.TEXTURE2),gl.bindTexture(gl.TEXTURE_2D,IBLReflMap),gl.uniform1i(gl.getUniformLocation(t,"reflImgSampler"),2));let n=remesh||e.partial||!e.rendered;e.verticesBuffer=registerBuffer(new Float32Array(e.vertices),e.verticesBuffer,n),gl.vertexAttribPointer(positionAttribute,3,gl.FLOAT,!1,a?24:16,0),a?Lights.length>0&&gl.vertexAttribPointer(normalAttribute,3,gl.FLOAT,!1,24,12):gl.vertexAttribPointer(widthAttribute,1,gl.FLOAT,!1,16,12),e.materialsBuffer=registerBuffer(new Int16Array(e.materialIndices),e.materialsBuffer,n),gl.vertexAttribPointer(materialAttribute,1,gl.SHORT,!1,2,0),t!=colorShader&&t!=transparentShader||(e.colorsBuffer=registerBuffer(new Uint8Array(e.colors),e.colorsBuffer,n),gl.vertexAttribPointer(colorAttribute,4,gl.UNSIGNED_BYTE,!0,0,0)),e.indicesBuffer=registerBuffer(indexExt?new Uint32Array(i):new Uint16Array(i),e.indicesBuffer,n,gl.ELEMENT_ARRAY_BUFFER),e.rendered=!0,gl.drawElements(a?wireframe?gl.LINES:e.type:gl.POINTS,i.length,indexExt?gl.UNSIGNED_INT:gl.UNSIGNED_SHORT,0)}class vertexBuffer{constructor(e){this.type=e||TRIANGLES,this.verticesBuffer=0,this.materialsBuffer=0,this.colorsBuffer=0,this.indicesBuffer=0,this.rendered=!1,this.partial=!1,this.clear()}clear(){this.vertices=[],this.materialIndices=[],this.colors=[],this.indices=[],this.nvertices=0,this.materials=[],this.materialTable=[]}vertex(e,t){return this.vertices.push(e[0]),this.vertices.push(e[1]),this.vertices.push(e!
 [2]),this.vertices.push(t[0]),this.vertices.push(t[1]),this.vertices.push(t[2]),this.materialIndices.push(materialIndex),this.nvertices++}Vertex(e,t,i=[0,0,0,0]){return this.vertices.push(e[0]),this.vertices.push(e[1]),this.vertices.push(e[2]),this.vertices.push(t[0]),this.vertices.push(t[1]),this.vertices.push(t[2]),this.materialIndices.push(materialIndex),this.colors.push(i[0]),this.colors.push(i[1]),this.colors.push(i[2]),this.colors.push(i[3]),this.nvertices++}vertex0(e,t){return this.vertices.push(e[0]),this.vertices.push(e[1]),this.vertices.push(e[2]),this.vertices.push(t),this.materialIndices.push(materialIndex),this.nvertices++}iVertex(e,t,i,a=[0,0,0,0]){let n=6*e;this.vertices[n]=t[0],this.vertices[n+1]=t[1],this.vertices[n+2]=t[2],this.vertices[n+3]=i[0],this.vertices[n+4]=i[1],this.vertices[n+5]=i[2],this.materialIndices[e]=materialIndex;let r=4*e;this.colors[r]=a[0],this.colors[r+1]=a[1],this.colors[r+2]=a[2],this.colors[r+3]=a[3],this.indices.push(e)}append(e){append(this.vertices,e.vertices),append(this.materialIndices,e.materialIndices),append(this.colors,e.colors),appendOffset(this.indices,e.indices,this.nvertices),this.nvertices+=e.nvertices}}function append(e,t){let i=e.length,a=t.length;e.length+=a;for(let n=0;n<a;++n)e[i+n]=t[n]}function appendOffset(e,t,i){let a=e.length,n=t.length;e.length+=t.length;for(let r=0;r<n;++r)e[a+r]=t[r]+i}class Geometry{constructor(){this.data=new vertexBuffer,this.Onscreen=!1,this.m=[]}offscreen(e){let t=projViewMat,i=e[0],a=i[0],n=i[1],r=i[2],s=1/(t[3]*a+t[7]*n+t[11]*r+t[15]);this.x=this.X=(t[0]*a+t[4]*n+t[8]*r+t[12])*s,this.y=this.Y=(t[1]*a+t[5]*n+t[9]*r+t[13])*s;for(let i=1,a=e.length;i<a;++i){let a=e[i],n=a[0],r=a[1],s=a[2],o=1/(t[3]*n+t[7]*r+t[11]*s+t[15]),l=(t[0]*n+t[4]*r+t[8]*s+t[12])*o,h=(t[1]*n+t[5]*r+t[9]*s+t[13])*o;l<this.x?this.x=l:l>this.X&&(this.X=l),h<this.y?this.y=h:h>this.Y&&(this.Y=h)}return(this.X<-1.01||this.x>1.01||this.Y<-1.01||this.y>1.01)&&(this.Onscreen=!1,!0)}T(e){let t=this.c[0],i=this.c[1],a=this.c[2],n=e[0]-t,r=e[1]-i,s=e[2]-a;return!
 [n*normMat[0]+r*normMat[3]+s*normMat[6]+t,n*normMat[1]+r*normMat[4]+s*normMat[7]+i,n*normMat[2]+r*normMat[5]+s*normMat[8]+a]}Tcorners(e,t){return[this.T(e),this.T([e[0],e[1],t[2]]),this.T([e[0],t[1],e[2]]),this.T([e[0],t[1],t[2]]),this.T([t[0],e[1],e[2]]),this.T([t[0],e[1],t[2]]),this.T([t[0],t[1],e[2]]),this.T(t)]}setMaterial(e,t){null==e.materialTable[this.MaterialIndex]&&(e.materials.length>=Nmaterials&&(e.partial=!0,t()),e.materialTable[this.MaterialIndex]=e.materials.length,e.materials.push(Materials[this.MaterialIndex])),materialIndex=e.materialTable[this.MaterialIndex]}render(){let e;if(this.setMaterialIndex(),0==this.CenterIndex?e=corners(this.Min,this.Max):(this.c=Centers[this.CenterIndex-1],e=this.Tcorners(this.Min,this.Max)),this.offscreen(e))return this.data.clear(),void this.notRendered();let t,i=this.controlpoints;if(0==this.CenterIndex){if(!remesh&&this.Onscreen)return void this.append();t=i}else{let e=i.length;t=Array(e);for(let a=0;a<e;++a)t[a]=this.T(i[a])}let a=orthographic?1:this.Min[2]/maxBound[2],n=.75*Math.hypot(a*(viewParam.xmax-viewParam.xmin),a*(viewParam.ymax-viewParam.ymin))/size2;this.res2=n*n,this.Epsilon=.1*n,this.data.clear(),this.notRendered(),this.Onscreen=!0,this.process(t)}}class BezierPatch extends Geometry{constructor(e,t,i,a,n,r){super(),this.controlpoints=e,this.CenterIndex=t,this.MaterialIndex=i,this.Min=a,this.Max=n,this.color=r;let s=e.length;if(r){let e=r[0][3]+r[1][3]+r[2][3];this.transparent=16==s||4==s?e+r[3][3]<1020:e<765}else this.transparent=Materials[i].diffuse[3]<1;this.vertex=this.transparent?this.data.Vertex.bind(this.data):this.data.vertex.bind(this.data),this.L2norm(this.controlpoints)}setMaterialIndex(){this.transparent?this.setMaterial(transparentData,drawTransparent):this.color?this.setMaterial(colorData,drawColor):this.setMaterial(materialData,drawMaterial)}L2norm(e){let t=e[0];this.epsilon=0;let i=e.length;for(let a=1;a<i;++a)this.epsilon=Math.max(this.epsilon,abs2([e[a][0]-t[0],e[a][1]-t[1],e[a][2]-t[2]]));this.epsilon*=Number.EPSILON}processTriangle(!
 e){let t=e[0],i=e[1],a=e[2],n=unit(cross([i[0]-t[0],i[1]-t[1],i[2]-t[2]],[a[0]-t[0],a[1]-t[1],a[2]-t[2]]));if(!this.offscreen([t,i,a])){let e,r,s;this.color?(e=this.data.Vertex(t,n,this.color[0]),r=this.data.Vertex(i,n,this.color[1]),s=this.data.Vertex(a,n,this.color[2])):(e=this.vertex(t,n),r=this.vertex(i,n),s=this.vertex(a,n)),0==wireframe?(this.data.indices.push(e),this.data.indices.push(r),this.data.indices.push(s)):(this.data.indices.push(e),this.data.indices.push(r),this.data.indices.push(r),this.data.indices.push(s),this.data.indices.push(s),this.data.indices.push(e)),this.append()}}processQuad(e){let t=e[0],i=e[1],a=e[2],n=e[3],r=cross([i[0]-t[0],i[1]-t[1],i[2]-t[2]],[a[0]-i[0],a[1]-i[1],a[2]-i[2]]),s=cross([a[0]-n[0],a[1]-n[1],a[2]-n[2]],[n[0]-t[0],n[1]-t[1],n[2]-t[2]]),o=unit([r[0]+s[0],r[1]+s[1],r[2]+s[2]]);if(!this.offscreen([t,i,a,n])){let e,r,s,l;this.color?(e=this.data.Vertex(t,o,this.color[0]),r=this.data.Vertex(i,o,this.color[1]),s=this.data.Vertex(a,o,this.color[2]),l=this.data.Vertex(n,o,this.color[3])):(e=this.vertex(t,o),r=this.vertex(i,o),s=this.vertex(a,o),l=this.vertex(n,o)),0==wireframe?(this.data.indices.push(e),this.data.indices.push(r),this.data.indices.push(s),this.data.indices.push(e),this.data.indices.push(s),this.data.indices.push(l)):(this.data.indices.push(e),this.data.indices.push(r),this.data.indices.push(r),this.data.indices.push(s),this.data.indices.push(s),this.data.indices.push(l),this.data.indices.push(l),this.data.indices.push(e)),this.append()}}curve(e,t,i,a,n){new BezierCurve([e[t],e[i],e[a],e[n]],0,materialIndex,this.Min,this.Max).render()}process(e){if(this.transparent&&1!=wireframe&&(materialIndex=this.color?-1-materialIndex:1+materialIndex),10==e.length)return this.process3(e);if(3==e.length)return this.processTriangle(e);if(4==e.length)return this.processQuad(e);if(1==wireframe)return this.curve(e,0,4,8,12),this.curve(e,12,13,14,15),this.curve(e,15,11,7,3),void this.curve(e,3,2,1,0);let t=e[0],i=e[3],a=e[12],n=e[15],r=this.normal(i,e[2],e[1],t,e[4],e[8],a);abs2(r!
 )<this.epsilon&&(r=this.normal(i,e[2],e[1],t,e[13],e[14],n),abs2(r)<this.epsilon&&(r=this.normal(n,e[11],e[7],i,e[4],e[8],a)));let s=this.normal(t,e[4],e[8],a,e[13],e[14],n);abs2(s)<this.epsilon&&(s=this.normal(t,e[4],e[8],a,e[11],e[7],i),abs2(s)<this.epsilon&&(s=this.normal(i,e[2],e[1],t,e[13],e[14],n)));let o=this.normal(a,e[13],e[14],n,e[11],e[7],i);abs2(o)<this.epsilon&&(o=this.normal(a,e[13],e[14],n,e[2],e[1],t),abs2(o)<this.epsilon&&(o=this.normal(t,e[4],e[8],a,e[11],e[7],i)));let l=this.normal(n,e[11],e[7],i,e[2],e[1],t);if(abs2(l)<this.epsilon&&(l=this.normal(n,e[11],e[7],i,e[4],e[8],a),abs2(l)<this.epsilon&&(l=this.normal(a,e[13],e[14],n,e[2],e[1],t))),this.color){let h=this.color[0],c=this.color[1],d=this.color[2],m=this.color[3],f=this.data.Vertex(t,r,h),u=this.data.Vertex(a,s,c),p=this.data.Vertex(n,o,d),g=this.data.Vertex(i,l,m);this.Render(e,f,u,p,g,t,a,n,i,!1,!1,!1,!1,h,c,d,m)}else{let h=this.vertex(t,r),c=this.vertex(a,s),d=this.vertex(n,o),m=this.vertex(i,l);this.Render(e,h,c,d,m,t,a,n,i,!1,!1,!1,!1)}this.data.indices.length>0&&this.append()}append(){this.transparent?transparentData.append(this.data):this.color?colorData.append(this.data):materialData.append(this.data)}notRendered(){this.transparent?transparentData.rendered=!1:this.color?colorData.rendered=!1:materialData.rendered=!1}Render(e,t,i,a,n,r,s,o,l,h,c,d,m,f,u,p,g){let v=this.Distance(e);if(v[0]<this.res2&&v[1]<this.res2)this.offscreen([r,s,o])||(0==wireframe?(this.data.indices.push(t),this.data.indices.push(i),this.data.indices.push(a)):(this.data.indices.push(t),this.data.indices.push(i),this.data.indices.push(i),this.data.indices.push(a))),this.offscreen([r,o,l])||(0==wireframe?(this.data.indices.push(t),this.data.indices.push(a),this.data.indices.push(n)):(this.data.indices.push(a),this.data.indices.push(n),this.data.indices.push(n),this.data.indices.push(t)));else{if(this.offscreen(e))return;let x=e[0],w=e[3],M=e[12],b=e[15];if(v[0]<this.res2){let v=new Split3(x,e[1],e[2],w),T=new Split3(e[4],e[5],e[6],e[7]),S=new Split3(e[8],e[9]!
 ,e[10],e[11]),R=new Split3(M,e[13],e[14],b),I=[x,v.m0,v.m3,v.m5,e[4],T.m0,T.m3,T.m5,e[8],S.m0,S.m3,S.m5,M,R.m0,R.m3,R.m5],A=[v.m5,v.m4,v.m2,w,T.m5,T.m4,T.m2,e[7],S.m5,S.m4,S.m2,e[11],R.m5,R.m4,R.m2,b],E=this.normal(I[12],I[13],I[14],I[15],I[11],I[7],I[3]);abs2(E)<=this.epsilon&&(E=this.normal(I[12],I[13],I[14],I[15],I[2],I[1],I[0]),abs2(E)<=this.epsilon&&(E=this.normal(I[0],I[4],I[8],I[12],I[11],I[7],I[3])));let P=this.normal(A[3],A[2],A[1],A[0],A[4],A[8],A[12]);abs2(P)<=this.epsilon&&(P=this.normal(A[3],A[2],A[1],A[0],A[13],A[14],A[15]),abs2(P)<=this.epsilon&&(P=this.normal(A[15],A[11],A[7],A[3],A[4],A[8],A[12])));let L=this.Epsilon,D=[.5*(s[0]+o[0]),.5*(s[1]+o[1]),.5*(s[2]+o[2])];if(!c)if(c=Straightness(M,e[13],e[14],b)<this.res2){let e=unit(this.differential(A[12],A[8],A[4],A[0]));D=[D[0]-L*e[0],D[1]-L*e[1],D[2]-L*e[2]]}else D=I[15];let y=[.5*(l[0]+r[0]),.5*(l[1]+r[1]),.5*(l[2]+r[2])];if(!m)if(m=Straightness(x,e[1],e[2],w)<this.res2){let e=unit(this.differential(I[3],I[7],I[11],I[15]));y=[y[0]-L*e[0],y[1]-L*e[1],y[2]-L*e[2]]}else y=A[0];if(f){let e=Array(4),v=Array(4);for(let t=0;t<4;++t)e[t]=.5*(u[t]+p[t]),v[t]=.5*(g[t]+f[t]);let x=this.data.Vertex(D,E,e),w=this.data.Vertex(y,P,v);this.Render(I,t,i,x,w,r,s,D,y,h,c,!1,m,f,u,e,v),this.Render(A,w,x,a,n,y,D,o,l,!1,c,d,m,v,e,p,g)}else{let e=this.vertex(D,E),f=this.vertex(y,P);this.Render(I,t,i,e,f,r,s,D,y,h,c,!1,m),this.Render(A,f,e,a,n,y,D,o,l,!1,c,d,m)}return}if(v[1]<this.res2){let v=new Split3(x,e[4],e[8],M),T=new Split3(e[1],e[5],e[9],e[13]),S=new Split3(e[2],e[6],e[10],e[14]),R=new Split3(w,e[7],e[11],b),I=[x,e[1],e[2],w,v.m0,T.m0,S.m0,R.m0,v.m3,T.m3,S.m3,R.m3,v.m5,T.m5,S.m5,R.m5],A=[v.m5,T.m5,S.m5,R.m5,v.m4,T.m4,S.m4,R.m4,v.m2,T.m2,S.m2,R.m2,M,e[13],e[14],b],E=this.normal(I[0],I[4],I[8],I[12],I[13],I[14],I[15]);abs2(E)<=this.epsilon&&(E=this.normal(I[0],I[4],I[8],I[12],I[11],I[7],I[3]),abs2(E)<=this.epsilon&&(E=this.normal(I[3],I[2],I[1],I[0],I[13],I[14],I[15])));let P=this.normal(A[15],A[11],A[7],A[3],A[2],A[1],A[0]);abs2(P)<=this.epsilon&&(P=this.normal(A!
 [15],A[11],A[7],A[3],A[4],A[8],A[12]),abs2(P)<=this.epsilon&&(P=this.normal(A[12],A[13],A[14],A[15],A[2],A[1],A[0])));let L=this.Epsilon,D=[.5*(r[0]+s[0]),.5*(r[1]+s[1]),.5*(r[2]+s[2])];if(!h)if(h=Straightness(x,e[4],e[8],M)<this.res2){let e=unit(this.differential(A[0],A[1],A[2],A[3]));D=[D[0]-L*e[0],D[1]-L*e[1],D[2]-L*e[2]]}else D=I[12];let y=[.5*(o[0]+l[0]),.5*(o[1]+l[1]),.5*(o[2]+l[2])];if(!d)if(d=Straightness(b,e[11],e[7],w)<this.res2){let e=unit(this.differential(I[15],I[14],I[13],I[12]));y=[y[0]-L*e[0],y[1]-L*e[1],y[2]-L*e[2]]}else y=A[3];if(f){let e=Array(4),v=Array(4);for(let t=0;t<4;++t)e[t]=.5*(f[t]+u[t]),v[t]=.5*(p[t]+g[t]);let x=this.data.Vertex(D,E,e),w=this.data.Vertex(y,P,v);this.Render(I,t,x,w,n,r,D,y,l,h,!1,d,m,f,e,v,g),this.Render(A,x,i,a,w,D,s,o,y,h,c,d,!1,e,u,p,v)}else{let e=this.vertex(D,E),f=this.vertex(y,P);this.Render(I,t,e,f,n,r,D,y,l,h,!1,d,m),this.Render(A,e,i,a,f,D,s,o,y,h,c,d,!1)}return}let T=new Split3(x,e[1],e[2],w),S=new Split3(e[4],e[5],e[6],e[7]),R=new Split3(e[8],e[9],e[10],e[11]),I=new Split3(M,e[13],e[14],b),A=new Split3(x,e[4],e[8],M),E=new Split3(T.m0,S.m0,R.m0,I.m0),P=new Split3(T.m3,S.m3,R.m3,I.m3),L=new Split3(T.m5,S.m5,R.m5,I.m5),D=new Split3(T.m4,S.m4,R.m4,I.m4),y=new Split3(T.m2,S.m2,R.m2,I.m2),O=new Split3(w,e[7],e[11],b),B=[x,T.m0,T.m3,T.m5,A.m0,E.m0,P.m0,L.m0,A.m3,E.m3,P.m3,L.m3,A.m5,E.m5,P.m5,L.m5],N=[A.m5,E.m5,P.m5,L.m5,A.m4,E.m4,P.m4,L.m4,A.m2,E.m2,P.m2,L.m2,M,I.m0,I.m3,I.m5],z=[L.m5,D.m5,y.m5,O.m5,L.m4,D.m4,y.m4,O.m4,L.m2,D.m2,y.m2,O.m2,I.m5,I.m4,I.m2,b],_=[T.m5,T.m4,T.m2,w,L.m0,D.m0,y.m0,O.m0,L.m3,D.m3,y.m3,O.m3,L.m5,D.m5,y.m5,O.m5],C=B[15],V=this.normal(B[0],B[4],B[8],B[12],B[13],B[14],B[15]);abs2(V)<this.epsilon&&(V=this.normal(B[0],B[4],B[8],B[12],B[11],B[7],B[3]),abs2(V)<this.epsilon&&(V=this.normal(B[3],B[2],B[1],B[0],B[13],B[14],B[15])));let U=this.normal(N[12],N[13],N[14],N[15],N[11],N[7],N[3]);abs2(U)<this.epsilon&&(U=this.normal(N[12],N[13],N[14],N[15],N[2],N[1],N[0]),abs2(U)<this.epsilon&&(U=this.normal(N[0],N[4],N[8],N[12],N[11],N[7],N[3])));let H=t!
 his.normal(z[15],z[11],z[7],z[3],z[2],z[1],z[0]);abs2(H)<this.epsilon&&(H=this.normal(z[15],z[11],z[7],z[3],z[4],z[8],z[12]),abs2(H)<this.epsilon&&(H=this.normal(z[12],z[13],z[14],z[15],z[2],z[1],z[0])));let G=this.normal(_[3],_[2],_[1],_[0],_[4],_[8],_[12]);abs2(G)<this.epsilon&&(G=this.normal(_[3],_[2],_[1],_[0],_[13],_[14],_[15]),abs2(G)<this.epsilon&&(G=this.normal(_[15],_[11],_[7],_[3],_[4],_[8],_[12])));let F=this.normal(z[3],z[2],z[1],C,z[4],z[8],z[12]),X=this.Epsilon,W=[.5*(r[0]+s[0]),.5*(r[1]+s[1]),.5*(r[2]+s[2])];if(!h)if(h=Straightness(x,e[4],e[8],M)<this.res2){let e=unit(this.differential(N[0],N[1],N[2],N[3]));W=[W[0]-X*e[0],W[1]-X*e[1],W[2]-X*e[2]]}else W=B[12];let j=[.5*(s[0]+o[0]),.5*(s[1]+o[1]),.5*(s[2]+o[2])];if(!c)if(c=Straightness(M,e[13],e[14],b)<this.res2){let e=unit(this.differential(z[12],z[8],z[4],z[0]));j=[j[0]-X*e[0],j[1]-X*e[1],j[2]-X*e[2]]}else j=N[15];let Z=[.5*(o[0]+l[0]),.5*(o[1]+l[1]),.5*(o[2]+l[2])];if(!d)if(d=Straightness(b,e[11],e[7],w)<this.res2){let e=unit(this.differential(_[15],_[14],_[13],_[12]));Z=[Z[0]-X*e[0],Z[1]-X*e[1],Z[2]-X*e[2]]}else Z=z[3];let k=[.5*(l[0]+r[0]),.5*(l[1]+r[1]),.5*(l[2]+r[2])];if(!m)if(m=Straightness(x,e[1],e[2],w)<this.res2){let e=unit(this.differential(B[3],B[7],B[11],B[15]));k=[k[0]-X*e[0],k[1]-X*e[1],k[2]-X*e[2]]}else k=_[0];if(f){let e=Array(4),v=Array(4),x=Array(4),w=Array(4),M=Array(4);for(let t=0;t<4;++t)e[t]=.5*(f[t]+u[t]),v[t]=.5*(u[t]+p[t]),x[t]=.5*(p[t]+g[t]),w[t]=.5*(g[t]+f[t]),M[t]=.5*(e[t]+x[t]);let b=this.data.Vertex(W,V,e),T=this.data.Vertex(j,U,v),S=this.data.Vertex(Z,H,x),R=this.data.Vertex(k,G,w),I=this.data.Vertex(C,F,M);this.Render(B,t,b,I,R,r,W,C,k,h,!1,!1,m,f,e,M,w),this.Render(N,b,i,T,I,W,s,j,C,h,c,!1,!1,e,u,v,M),this.Render(z,I,T,a,S,C,j,o,Z,!1,c,d,!1,M,v,p,x),this.Render(_,R,I,S,n,k,C,Z,l,!1,!1,d,m,w,M,x,g)}else{let e=this.vertex(W,V),f=this.vertex(j,U),u=this.vertex(Z,H),p=this.vertex(k,G),g=this.vertex(C,F);this.Render(B,t,e,g,p,r,W,C,k,h,!1,!1,m),this.Render(N,e,i,f,g,W,s,j,C,h,c,!1,!1),this.Render(z,g,f,a,u,C,j,o,Z,!1,c!
 ,d,!1),this.Render(_,p,g,u,n,k,C,Z,l,!1,!1,d,m)}}}process3(e){if(1==wireframe)return this.curve(e,0,1,3,6),this.curve(e,6,7,8,9),void this.curve(e,9,5,2,0);let t=e[0],i=e[6],a=e[9],n=this.normal(a,e[5],e[2],t,e[1],e[3],i),r=this.normal(t,e[1],e[3],i,e[7],e[8],a),s=this.normal(i,e[7],e[8],a,e[5],e[2],t);if(this.color){let o=this.color[0],l=this.color[1],h=this.color[2],c=this.data.Vertex(t,n,o),d=this.data.Vertex(i,r,l),m=this.data.Vertex(a,s,h);this.Render3(e,c,d,m,t,i,a,!1,!1,!1,o,l,h)}else{let o=this.vertex(t,n),l=this.vertex(i,r),h=this.vertex(a,s);this.Render3(e,o,l,h,t,i,a,!1,!1,!1)}this.data.indices.length>0&&this.append()}Render3(e,t,i,a,n,r,s,o,l,h,c,d,m){if(this.Distance3(e)<this.res2)this.offscreen([n,r,s])||(0==wireframe?(this.data.indices.push(t),this.data.indices.push(i),this.data.indices.push(a)):(this.data.indices.push(t),this.data.indices.push(i),this.data.indices.push(i),this.data.indices.push(a),this.data.indices.push(a),this.data.indices.push(t)));else{if(this.offscreen(e))return;let f=e[0],u=e[1],p=e[2],g=e[3],v=e[4],x=e[5],w=e[6],M=e[7],b=e[8],T=e[9],S=[.5*(T[0]+x[0]),.5*(T[1]+x[1]),.5*(T[2]+x[2])],R=[.5*(T[0]+b[0]),.5*(T[1]+b[1]),.5*(T[2]+b[2])],I=[.5*(x[0]+p[0]),.5*(x[1]+p[1]),.5*(x[2]+p[2])],A=[.5*(b[0]+v[0]),.5*(b[1]+v[1]),.5*(b[2]+v[2])],E=[.5*(b[0]+M[0]),.5*(b[1]+M[1]),.5*(b[2]+M[2])],P=[.5*(p[0]+v[0]),.5*(p[1]+v[1]),.5*(p[2]+v[2])],L=[.5*(p[0]+f[0]),.5*(p[1]+f[1]),.5*(p[2]+f[2])],D=[.5*(v[0]+g[0]),.5*(v[1]+g[1]),.5*(v[2]+g[2])],y=[.5*(M[0]+w[0]),.5*(M[1]+w[1]),.5*(M[2]+w[2])],O=[.5*(f[0]+u[0]),.5*(f[1]+u[1]),.5*(f[2]+u[2])],B=[.5*(u[0]+g[0]),.5*(u[1]+g[1]),.5*(u[2]+g[2])],N=[.5*(g[0]+w[0]),.5*(g[1]+w[1]),.5*(g[2]+w[2])],z=[.5*(S[0]+I[0]),.5*(S[1]+I[1]),.5*(S[2]+I[2])],_=[.5*(R[0]+E[0]),.5*(R[1]+E[1]),.5*(R[2]+E[2])],C=[.5*(I[0]+L[0]),.5*(I[1]+L[1]),.5*(I[2]+L[2])],V=[.5*A[0]+.25*(v[0]+u[0]),.5*A[1]+.25*(v[1]+u[1]),.5*A[2]+.25*(v[2]+u[2])],U=[.5*(E[0]+y[0]),.5*(E[1]+y[1]),.5*(E[2]+y[2])],H=[.5*P[0]+.25*(v[0]+M[0]),.5*P[1]+.25*(v[1]+M[1]),.5*P[2]+.25*(v[2]+M[2])],G=[.25*(x[0]+v[0])+.5*D!
 [0],.25*(x[1]+v[1])+.5*D[1],.25*(x[2]+v[2])+.5*D[2]],F=[.5*(O[0]+B[0]),.5*(O[1]+B[1]),.5*(O[2]+B[2])],X=[.5*(B[0]+N[0]),.5*(B[1]+N[1]),.5*(B[2]+N[2])],W=[.5*(H[0]+F[0]),.5*(H[1]+F[1]),.5*(H[2]+F[2])],j=[.5*(H[0]+X[0]),.5*(H[1]+X[1]),.5*(H[2]+X[2])],Z=[.5*(F[0]+X[0]),.5*(F[1]+X[1]),.5*(F[2]+X[2])],k=[.5*(G[0]+U[0]),.5*(G[1]+U[1]),.5*(G[2]+U[2])],Y=[.5*(_[0]+G[0]),.5*(_[1]+G[1]),.5*(_[2]+G[2])],q=[.5*(_[0]+U[0]),.5*(_[1]+U[1]),.5*(_[2]+U[2])],$=[.5*(z[0]+V[0]),.5*(z[1]+V[1]),.5*(z[2]+V[2])],K=[.5*(C[0]+V[0]),.5*(C[1]+V[1]),.5*(C[2]+V[2])],Q=[.5*(z[0]+C[0]),.5*(z[1]+C[1]),.5*(z[2]+C[2])],J=[f,O,L,F,[.5*(P[0]+O[0]),.5*(P[1]+O[1]),.5*(P[2]+O[2])],C,Z,W,K,Q],ee=[Z,X,j,N,[.5*(D[0]+y[0]),.5*(D[1]+y[1]),.5*(D[2]+y[2])],k,w,y,U,q],te=[Q,$,z,Y,[.5*(S[0]+A[0]),.5*(S[1]+A[1]),.5*(S[2]+A[2])],S,q,_,R,T],ie=[q,Y,k,$,[.25*(I[0]+E[0]+B[0]+v[0]),.25*(I[1]+E[1]+B[1]+v[1]),.25*(I[2]+E[2]+B[2]+v[2])],j,Q,K,W,Z],ae=this.normal(Z,j,k,q,Y,$,Q),ne=this.normal(q,Y,$,Q,K,W,Z),re=this.normal(Q,K,W,Z,j,k,q),se=this.Epsilon,oe=[.5*(r[0]+s[0]),.5*(r[1]+s[1]),.5*(r[2]+s[2])];if(!o)if(o=Straightness(w,M,b,T)<this.res2){let e=unit(this.sumdifferential(ie[0],ie[2],ie[5],ie[9],ie[1],ie[3],ie[6]));oe=[oe[0]-se*e[0],oe[1]-se*e[1],oe[2]-se*e[2]]}else oe=q;let le=[.5*(s[0]+n[0]),.5*(s[1]+n[1]),.5*(s[2]+n[2])];if(!l)if(l=Straightness(f,p,x,T)<this.res2){let e=unit(this.sumdifferential(ie[6],ie[3],ie[1],ie[0],ie[7],ie[8],ie[9]));le=[le[0]-se*e[0],le[1]-se*e[1],le[2]-se*e[2]]}else le=Q;let he=[.5*(n[0]+r[0]),.5*(n[1]+r[1]),.5*(n[2]+r[2])];if(!h)if(h=Straightness(f,u,g,w)<this.res2){let e=unit(this.sumdifferential(ie[9],ie[8],ie[7],ie[6],ie[5],ie[2],ie[0]));he=[he[0]-se*e[0],he[1]-se*e[1],he[2]-se*e[2]]}else he=Z;if(c){let e=Array(4),f=Array(4),u=Array(4);for(let t=0;t<4;++t)e[t]=.5*(d[t]+m[t]),f[t]=.5*(m[t]+c[t]),u[t]=.5*(c[t]+d[t]);let p=this.data.Vertex(oe,ae,e),g=this.data.Vertex(le,ne,f),v=this.data.Vertex(he,re,u);this.Render3(J,t,v,g,n,he,le,!1,l,h,c,u,f),this.Render3(ee,v,i,p,he,r,oe,o,!1,h,u,d,e),this.Render3(te,g,p,a,le,oe,s,o,l,!1,f,e,m),this.R!
 ender3(ie,p,g,v,oe,le,he,!1,!1,!1,e,f,u)}else{let e=this.vertex(oe,ae),c=this.vertex(le,ne),d=this.vertex(he,re);this.Render3(J,t,d,c,n,he,le,!1,l,h),this.Render3(ee,d,i,e,he,r,oe,o,!1,h),this.Render3(te,c,e,a,le,oe,s,o,l,!1),this.Render3(ie,e,c,d,oe,le,he,!1,!1,!1)}}}Distance(e){let t=e[0],i=e[3],a=e[12],n=e[15],r=Flatness(t,a,i,n);r=Math.max(Straightness(t,e[4],e[8],a)),r=Math.max(r,Straightness(e[1],e[5],e[9],e[13])),r=Math.max(r,Straightness(i,e[7],e[11],n)),r=Math.max(r,Straightness(e[2],e[6],e[10],e[14]));let s=Flatness(t,i,a,n);return s=Math.max(s,Straightness(t,e[1],e[2],i)),s=Math.max(s,Straightness(e[4],e[5],e[6],e[7])),s=Math.max(s,Straightness(e[8],e[9],e[10],e[11])),s=Math.max(s,Straightness(a,e[13],e[14],n)),[r,s]}Distance3(e){let t=e[0],i=e[4],a=e[6],n=e[9],r=abs2([(t[0]+a[0]+n[0])*(1/3)-i[0],(t[1]+a[1]+n[1])*(1/3)-i[1],(t[2]+a[2]+n[2])*(1/3)-i[2]]);return r=Math.max(r,Straightness(t,e[1],e[3],a)),r=Math.max(r,Straightness(t,e[2],e[5],n)),Math.max(r,Straightness(a,e[7],e[8],n))}differential(e,t,i,a){let n=[3*(t[0]-e[0]),3*(t[1]-e[1]),3*(t[2]-e[2])];return abs2(n)>this.epsilon?n:(n=bezierPP(e,t,i),abs2(n)>this.epsilon?n:bezierPPP(e,t,i,a))}sumdifferential(e,t,i,a,n,r,s){let o=this.differential(e,t,i,a),l=this.differential(e,n,r,s);return[o[0]+l[0],o[1]+l[1],o[2]+l[2]]}normal(e,t,i,a,n,r,s){let o=3*(n[0]-a[0]),l=3*(n[1]-a[1]),h=3*(n[2]-a[2]),c=3*(i[0]-a[0]),d=3*(i[1]-a[1]),m=3*(i[2]-a[2]),f=[l*m-h*d,h*c-o*m,o*d-l*c];if(abs2(f)>this.epsilon)return f;let u=[c,d,m],p=[o,l,h],g=bezierPP(a,i,t),v=bezierPP(a,n,r),x=cross(v,u),w=cross(p,g);if(f=[x[0]+w[0],x[1]+w[1],x[2]+w[2]],abs2(f)>this.epsilon)return f;let M=bezierPPP(a,i,t,e),b=bezierPPP(a,n,r,s);x=cross(p,M),w=cross(b,u);let T=cross(v,g);return f=[x[0]+w[0]+T[0],x[1]+w[1]+T[1],x[2]+w[2]+T[2]],abs2(f)>this.epsilon?f:(x=cross(b,g),w=cross(v,M),f=[x[0]+w[0],x[1]+w[1],x[2]+w[2]],abs2(f)>this.epsilon?f:cross(b,M))}}class BezierCurve extends Geometry{constructor(e,t,i,a,n){super(),this.controlpoints=e,this.CenterIndex=t,this.MaterialIndex=i,this.Min=a,this.!
 Max=n}setMaterialIndex(){this.setMaterial(material1Data,drawMaterial1)}processLine(e){let t=e[0],i=e[1];if(!this.offscreen([t,i])){let e=[0,0,1];this.data.indices.push(this.data.vertex(t,e)),this.data.indices.push(this.data.vertex(i,e)),this.append()}}process(e){if(2==e.length)return this.processLine(e);let t=e[0],i=e[1],a=e[2],n=e[3],r=this.normal(bezierP(t,i),bezierPP(t,i,a)),s=this.normal(bezierP(a,n),bezierPP(n,a,i)),o=this.data.vertex(t,r),l=this.data.vertex(n,s);this.Render(e,o,l),this.data.indices.length>0&&this.append()}append(){material1Data.append(this.data)}notRendered(){material1Data.rendered=!1}Render(e,t,i){let a=e[0],n=e[1],r=e[2],s=e[3];if(Straightness(a,n,r,s)<this.res2)this.offscreen([a,s])||(this.data.indices.push(t),this.data.indices.push(i));else{if(this.offscreen(e))return;let o=[.5*(a[0]+n[0]),.5*(a[1]+n[1]),.5*(a[2]+n[2])],l=[.5*(n[0]+r[0]),.5*(n[1]+r[1]),.5*(n[2]+r[2])],h=[.5*(r[0]+s[0]),.5*(r[1]+s[1]),.5*(r[2]+s[2])],c=[.5*(o[0]+l[0]),.5*(o[1]+l[1]),.5*(o[2]+l[2])],d=[.5*(l[0]+h[0]),.5*(l[1]+h[1]),.5*(l[2]+h[2])],m=[.5*(c[0]+d[0]),.5*(c[1]+d[1]),.5*(c[2]+d[2])],f=[a,o,c,m],u=[m,d,h,s],p=this.normal(bezierPh(a,n,r,s),bezierPPh(a,n,r,s)),g=this.data.vertex(m,p);this.Render(f,t,g),this.Render(u,g,i)}}normal(e,t){let i=dot(e,e),a=dot(e,t);return[i*t[0]-a*e[0],i*t[1]-a*e[1],i*t[2]-a*e[2]]}}class Pixel extends Geometry{constructor(e,t,i,a,n){super(),this.controlpoint=e,this.width=t,this.CenterIndex=0,this.MaterialIndex=i,this.Min=a,this.Max=n}setMaterialIndex(){this.setMaterial(material0Data,drawMaterial0)}process(e){this.data.indices.push(this.data.vertex0(this.controlpoint,this.width)),this.append()}append(){material0Data.append(this.data)}notRendered(){material0Data.rendered=!1}}class Triangles extends Geometry{constructor(e,t,i,a){super(),this.CenterIndex=e,this.MaterialIndex=t,this.Min=i,this.Max=a,this.controlpoints=Positions,this.Normals=Normals,this.Colors=Colors,this.Indices=Indices,Positions=[],Normals=[],Colors=[],Indices=[],this.transparent=Materials[this.MaterialIndex].diffuse[3]!
 <1}setMaterialIndex(){this.transparent?this.setMaterial(transparentData,drawTransparent):this.setMaterial(triangleData,drawTriangle)}process(e){this.data.vertices=new Array(6*e.length),materialIndex=this.Colors.length>0?-1-materialIndex:1+materialIndex;for(let t=0,i=this.Indices.length;t<i;++t){let i=this.Indices[t],a=i[0],n=e[a[0]],r=e[a[1]],s=e[a[2]];if(!this.offscreen([n,r,s])){let e=i.length>1?i[1]:a;if(e&&0!=e.length||(e=a),this.Colors.length>0){let t=i.length>2?i[2]:a;t&&0!=t.length||(t=a);let o=this.Colors[t[0]],l=this.Colors[t[1]],h=this.Colors[t[2]];this.transparent|=o[3]+l[3]+h[3]<765,0==wireframe?(this.data.iVertex(a[0],n,this.Normals[e[0]],o),this.data.iVertex(a[1],r,this.Normals[e[1]],l),this.data.iVertex(a[2],s,this.Normals[e[2]],h)):(this.data.iVertex(a[0],n,this.Normals[e[0]],o),this.data.iVertex(a[1],r,this.Normals[e[1]],l),this.data.iVertex(a[1],r,this.Normals[e[1]],l),this.data.iVertex(a[2],s,this.Normals[e[2]],h),this.data.iVertex(a[2],s,this.Normals[e[2]],h),this.data.iVertex(a[0],n,this.Normals[e[0]],o))}else 0==wireframe?(this.data.iVertex(a[0],n,this.Normals[e[0]]),this.data.iVertex(a[1],r,this.Normals[e[1]]),this.data.iVertex(a[2],s,this.Normals[e[2]])):(this.data.iVertex(a[0],n,this.Normals[e[0]]),this.data.iVertex(a[1],r,this.Normals[e[1]]),this.data.iVertex(a[1],r,this.Normals[e[1]]),this.data.iVertex(a[2],s,this.Normals[e[2]]),this.data.iVertex(a[2],s,this.Normals[e[2]]),this.data.iVertex(a[0],n,this.Normals[e[0]]))}}this.data.nvertices=e.length,this.data.indices.length>0&&this.append()}append(){this.transparent?transparentData.append(this.data):triangleData.append(this.data)}notRendered(){this.transparent?transparentData.rendered=!1:triangleData.rendered=!1}}function redrawScene(){initProjection(),setProjection(),remesh=!0,drawScene()}function home(){mat4.identity(rotMat),redrawScene()}let positionAttribute=0,normalAttribute=1,materialAttribute=2,colorAttribute=3,widthAttribute=4;function initShader(e=[]){let t=getShader(gl,vertex,gl.VERTEX_SHADER,e),i=getShader(gl,fragment,gl.FRAGM!
 ENT_SHADER,e),a=gl.createProgram();return gl.attachShader(a,t),gl.attachShader(a,i),gl.bindAttribLocation(a,positionAttribute,"position"),gl.bindAttribLocation(a,normalAttribute,"normal"),gl.bindAttribLocation(a,materialAttribute,"materialIndex"),gl.bindAttribLocation(a,colorAttribute,"color"),gl.bindAttribLocation(a,widthAttribute,"width"),gl.linkProgram(a),gl.getProgramParameter(a,gl.LINK_STATUS)||alert("Could not initialize shaders"),a}class Split3{constructor(e,t,i,a){this.m0=[.5*(e[0]+t[0]),.5*(e[1]+t[1]),.5*(e[2]+t[2])];let n=.5*(t[0]+i[0]),r=.5*(t[1]+i[1]),s=.5*(t[2]+i[2]);this.m2=[.5*(i[0]+a[0]),.5*(i[1]+a[1]),.5*(i[2]+a[2])],this.m3=[.5*(this.m0[0]+n),.5*(this.m0[1]+r),.5*(this.m0[2]+s)],this.m4=[.5*(n+this.m2[0]),.5*(r+this.m2[1]),.5*(s+this.m2[2])],this.m5=[.5*(this.m3[0]+this.m4[0]),.5*(this.m3[1]+this.m4[1]),.5*(this.m3[2]+this.m4[2])]}}function unit(e){let t=1/(Math.sqrt(e[0]*e[0]+e[1]*e[1]+e[2]*e[2])||1);return[e[0]*t,e[1]*t,e[2]*t]}function abs2(e){return e[0]*e[0]+e[1]*e[1]+e[2]*e[2]}function dot(e,t){return e[0]*t[0]+e[1]*t[1]+e[2]*t[2]}function cross(e,t){return[e[1]*t[2]-e[2]*t[1],e[2]*t[0]-e[0]*t[2],e[0]*t[1]-e[1]*t[0]]}function bezierP(e,t){return[t[0]-e[0],t[1]-e[1],t[2]-e[2]]}function bezierPP(e,t,i){return[3*(e[0]+i[0])-6*t[0],3*(e[1]+i[1])-6*t[1],3*(e[2]+i[2])-6*t[2]]}function bezierPPP(e,t,i,a){return[a[0]-e[0]+3*(t[0]-i[0]),a[1]-e[1]+3*(t[1]-i[1]),a[2]-e[2]+3*(t[2]-i[2])]}function bezierPh(e,t,i,a){return[i[0]+a[0]-e[0]-t[0],i[1]+a[1]-e[1]-t[1],i[2]+a[2]-e[2]-t[2]]}function bezierPPh(e,t,i,a){return[3*e[0]-5*t[0]+i[0]+a[0],3*e[1]-5*t[1]+i[1]+a[1],3*e[2]-5*t[2]+i[2]+a[2]]}function Straightness(e,t,i,a){let n=[1/3*(a[0]-e[0]),1/3*(a[1]-e[1]),1/3*(a[2]-e[2])];return Math.max(abs2([t[0]-n[0]-e[0],t[1]-n[1]-e[1],t[2]-n[2]-e[2]]),abs2([a[0]-n[0]-i[0],a[1]-n[1]-i[1],a[2]-n[2]-i[2]]))}function Flatness(e,t,i,a){let n=[t[0]-e[0],t[1]-e[1],t[2]-e[2]],r=[a[0]-i[0],a[1]-i[1],a[2]-i[2]];return Math.max(abs2(cross(n,unit(r))),abs2(cross(r,unit(n))))/9}function corners(e,t){return[e,[e[0],e[1],t[2]]!
 ,[e[0],t[1],e[2]],[e[0],t[1],t[2]],[t[0],e[1],e[2]],[t[0],e[1],t[2]],[t[0],t[1],e[2]],t]}function minbound(e){return[Math.min(e[0][0],e[1][0],e[2][0],e[3][0],e[4][0],e[5][0],e[6][0],e[7][0]),Math.min(e[0][1],e[1][1],e[2][1],e[3][1],e[4][1],e[5][1],e[6][1],e[7][1]),Math.min(e[0][2],e[1][2],e[2][2],e[3][2],e[4][2],e[5][2],e[6][2],e[7][2])]}function maxbound(e){return[Math.max(e[0][0],e[1][0],e[2][0],e[3][0],e[4][0],e[5][0],e[6][0],e[7][0]),Math.max(e[0][1],e[1][1],e[2][1],e[3][1],e[4][1],e[5][1],e[6][1],e[7][1]),Math.max(e[0][2],e[1][2],e[2][2],e[3][2],e[4][2],e[5][2],e[6][2],e[7][2])]}function COBTarget(e,t){mat4.fromTranslation(T,[center.x,center.y,center.z]),mat4.invert(cjMatInv,T),mat4.multiply(e,t,cjMatInv),mat4.multiply(e,T,e)}function setUniforms(e,t){let i=t==pixelShader;gl.useProgram(t),gl.enableVertexAttribArray(positionAttribute),i&&gl.enableVertexAttribArray(widthAttribute);let a=!i&&Lights.length>0;if(a&&gl.enableVertexAttribArray(normalAttribute),gl.enableVertexAttribArray(materialAttribute),t.projViewMatUniform=gl.getUniformLocation(t,"projViewMat"),t.viewMatUniform=gl.getUniformLocation(t,"viewMat"),t.normMatUniform=gl.getUniformLocation(t,"normMat"),t!=colorShader&&t!=transparentShader||gl.enableVertexAttribArray(colorAttribute),a)for(let e=0;e<Lights.length;++e)Lights[e].setUniform(t,e);for(let i=0;i<e.materials.length;++i)e.materials[i].setUniform(t,i);gl.uniformMatrix4fv(t.projViewMatUniform,!1,projViewMat),gl.uniformMatrix4fv(t.viewMatUniform,!1,viewMat),gl.uniformMatrix3fv(t.normMatUniform,!1,normMat)}function handleMouseDown(e){zoomEnabled||enableZoom(),mouseDownOrTouchActive=!0,lastMouseX=e.clientX,lastMouseY=e.clientY}let pinchStart,touchStartTime,pinch=!1;function pinchDistance(e){return Math.hypot(e[0].pageX-e[1].pageX,e[0].pageY-e[1].pageY)}function handleTouchStart(e){e.preventDefault(),zoomEnabled||enableZoom();let t=e.targetTouches;swipe=rotate=pinch=!1,zooming||(1!=t.length||mouseDownOrTouchActive||(touchStartTime=(new Date).getTime(),touchId=t[0].identifier,lastMouseX=t[0].pageX,la!
 stMouseY=t[0].pageY),2!=t.length||mouseDownOrTouchActive||(touchId=t[0].identifier,pinchStart=pinchDistance(t),pinch=!0))}function handleMouseUpOrTouchEnd(e){mouseDownOrTouchActive=!1}function rotateScene(e,t,i,a,n){if(e==i&&t==a)return;let[r,s]=arcball([e,-t],[i,-a]);mat4.fromRotation(T,2*n*ArcballFactor*r/Zoom,s),mat4.multiply(rotMat,T,rotMat)}function shiftScene(e,t,i,a){let n=1/Zoom;shift.x+=(i-e)*n*halfCanvasWidth,shift.y-=(a-t)*n*halfCanvasHeight}function panScene(e,t,i,a){orthographic?shiftScene(e,t,i,a):(center.x+=(i-e)*(viewParam.xmax-viewParam.xmin),center.y-=(a-t)*(viewParam.ymax-viewParam.ymin))}function updateViewMatrix(){COBTarget(viewMat,rotMat),mat4.translate(viewMat,viewMat,[center.x,center.y,0]),mat3.fromMat4(viewMat3,viewMat),mat3.invert(normMat,viewMat3),mat4.multiply(projViewMat,projMat,viewMat)}function capzoom(){let e=Math.sqrt(Number.MAX_VALUE),t=1/e;Zoom<=t&&(Zoom=t),Zoom>=e&&(Zoom=e),(1.5*Zoom<lastZoom||Zoom>1.5*lastZoom)&&(remesh=!0,lastZoom=Zoom)}function zoomImage(e){let t=zoomStep*halfCanvasHeight*e;const i=Math.log(.1*Number.MAX_VALUE)/Math.log(zoomFactor);Math.abs(t)<i&&(Zoom*=zoomFactor**t,capzoom())}function normMouse(e){let t=e[0],i=e[1],a=Math.hypot(t,i);return a>1&&(denom=1/a,t*=denom,i*=denom),[t,i,Math.sqrt(Math.max(1-i*i-t*t,0))]}function arcball(e,t){let i=normMouse(e),a=normMouse(t),n=dot(i,a);return[n>1?0:n<-1?pi:Math.acos(n),unit(cross(i,a))]}function zoomScene(e,t,i,a){zoomImage(t-a)}const DRAGMODE_ROTATE=1,DRAGMODE_SHIFT=2,DRAGMODE_ZOOM=3,DRAGMODE_PAN=4;function processDrag(e,t,i,a=1){let n;switch(i){case 1:n=rotateScene;break;case 2:n=shiftScene;break;case 3:n=zoomScene;break;case 4:n=panScene;break;default:n=(e,t,i,a)=>{}}n((lastMouseX-halfCanvasWidth)/halfCanvasWidth,(lastMouseY-halfCanvasHeight)/halfCanvasHeight,(e-halfCanvasWidth)/halfCanvasWidth,(t-halfCanvasHeight)/halfCanvasHeight,a),lastMouseX=e,lastMouseY=t,setProjection(),drawScene()}let zoomEnabled=0;function enableZoom(){zoomEnabled=1,canvas.addEventListener("wheel",handleMouseWheel,!1)}function disableZ!
 oom(){zoomEnabled=0,canvas.removeEventListener("wheel",handleMouseWheel,!1)}function handleKey(e){if(zoomEnabled||enableZoom(),embedded&&zoomEnabled&&27==e.keyCode)return void disableZoom();let t=[];switch(e.key){case"x":t=[1,0,0];break;case"y":t=[0,1,0];break;case"z":t=[0,0,1];break;case"h":home();break;case"m":++wireframe,3==wireframe&&(wireframe=0),2!=wireframe&&(embedded||deleteShaders(),initShaders(ibl)),remesh=!0,drawScene();break;case"+":case"=":case">":expand();break;case"-":case"_":case"<":shrink()}t.length>0&&(mat4.rotate(rotMat,rotMat,.1,t),updateViewMatrix(),drawScene())}function setZoom(){capzoom(),setProjection(),drawScene()}function handleMouseWheel(e){e.preventDefault(),e.deltaY<0?Zoom*=zoomFactor:Zoom/=zoomFactor,setZoom()}function handleMouseMove(e){if(!mouseDownOrTouchActive)return;let t,i=e.clientX,a=e.clientY;t=e.getModifierState("Control")?2:e.getModifierState("Shift")?3:e.getModifierState("Alt")?4:1,processDrag(i,a,t)}let zooming=!1,swipe=!1,rotate=!1;function handleTouchMove(e){if(e.preventDefault(),zooming)return;let t=e.targetTouches;if(!pinch&&1==t.length&&touchId==t[0].identifier){let e=t[0].pageX,i=t[0].pageY,a=e-lastMouseX,n=i-lastMouseY,r=a*a+n*n<=shiftHoldDistance*shiftHoldDistance;if(r&&!swipe&&!rotate&&(new Date).getTime()-touchStartTime>shiftWaitTime&&(navigator.vibrate&&window.navigator.vibrate(vibrateTime),swipe=!0),swipe)processDrag(e,i,2);else if(!r){rotate=!0,processDrag(t[0].pageX,t[0].pageY,1,.5)}}if(pinch&&!swipe&&2==t.length&&touchId==t[0].identifier){let e=pinchDistance(t),i=e-pinchStart;zooming=!0,i*=zoomPinchFactor,i>zoomPinchCap&&(i=zoomPinchCap),i<-zoomPinchCap&&(i=-zoomPinchCap),zoomImage(i/size2),pinchStart=e,swipe=rotate=zooming=!1,setProjection(),drawScene()}}let pixelShader,materialShader,colorShader,transparentShader,zbuffer=[];function transformVertices(e){let t=viewMat[2],i=viewMat[6],a=viewMat[10];zbuffer.length=e.length;for(let n=0;n<e.length;++n){let r=6*n;zbuffer[n]=t*e[r]+i*e[r+1]+a*e[r+2]}}function drawMaterial0(){drawBuffer(material0Data,pixelShader!
 ),material0Data.clear()}function drawMaterial1(){drawBuffer(material1Data,materialShader),material1Data.clear()}function drawMaterial(){drawBuffer(materialData,materialShader),materialData.clear()}function drawColor(){drawBuffer(colorData,colorShader),colorData.clear()}function drawTriangle(){drawBuffer(triangleData,transparentShader),triangleData.rendered=!1,triangleData.clear()}function drawTransparent(){let e=transparentData.indices;if(wireframe>0)return drawBuffer(transparentData,transparentShader,e),void transparentData.clear();if(e.length>0){transformVertices(transparentData.vertices);let t=e.length/3,i=Array(t).fill().map((e,t)=>t);i.sort((function(t,i){let a=3*t;Ia=e[a],Ib=e[a+1],Ic=e[a+2];let n=3*i;return IA=e[n],IB=e[n+1],IC=e[n+2],zbuffer[Ia]+zbuffer[Ib]+zbuffer[Ic]<zbuffer[IA]+zbuffer[IB]+zbuffer[IC]?-1:1}));let a=Array(e.length);for(let n=0;n<t;++n){let t=3*i[n];a[3*n]=e[t],a[3*n+1]=e[t+1],a[3*n+2]=e[t+2]}gl.depthMask(!1),drawBuffer(transparentData,transparentShader,a),transparentData.rendered=!1,gl.depthMask(!0)}transparentData.clear()}function drawBuffers(){drawMaterial0(),drawMaterial1(),drawMaterial(),drawColor(),drawTriangle(),drawTransparent(),requestAnimationFrame(drawBuffers)}function drawScene(){embedded&&(offscreen.width=canvasWidth,offscreen.height=canvasHeight,setViewport()),gl.clearColor(Background[0],Background[1],Background[2],Background[3]),gl.clear(gl.COLOR_BUFFER_BIT|gl.DEPTH_BUFFER_BIT);for(let e=0;e<P.length;++e)P[e].render();drawBuffers(),embedded&&(context.clearRect(0,0,canvasWidth,canvasHeight),context.drawImage(offscreen,0,0)),0==wireframe&&(remesh=!1)}function setDimensions(e,t,i,a){let n=e/t,r=1/Zoom,s=(i/e+viewportShift[0])*Zoom,o=(a/t+viewportShift[1])*Zoom;if(orthographic){let e=maxBound[0]-minBound[0],t=maxBound[1]-minBound[1];if(e<t*n){let e=.5*t*n*r,i=2*e*s,a=t*r*o;viewParam.xmin=-e-i,viewParam.xmax=e-i,viewParam.ymin=minBound[1]*r-a,viewParam.ymax=maxBound[1]*r-a}else{let t=.5*e/(n*Zoom),i=e*r*s,a=2*t*o;viewParam.xmin=minBound[0]*r-i,viewParam.xmax=maxBound[0]*r-i,vi!
 ewParam.ymin=-t-a,viewParam.ymax=t-a}}else{let e=H*r,t=e*n,i=2*t*s,a=2*e*o;viewParam.xmin=-t-i,viewParam.xmax=t-i,viewParam.ymin=-e-a,viewParam.ymax=e-a}}function setProjection(){setDimensions(canvasWidth,canvasHeight,shift.x,shift.y),(orthographic?mat4.ortho:mat4.frustum)(projMat,viewParam.xmin,viewParam.xmax,viewParam.ymin,viewParam.ymax,-viewParam.zmax,-viewParam.zmin),updateViewMatrix()}function initProjection(){H=-Math.tan(.5*angleOfView)*maxBound[2],center.x=center.y=0,center.z=.5*(minBound[2]+maxBound[2]),lastZoom=Zoom=zoom0,viewParam.zmin=minBound[2],viewParam.zmax=maxBound[2],shift.x=shift.y=0}function setViewport(){gl.viewportWidth=canvasWidth,gl.viewportHeight=canvasHeight,gl.viewport(.5*(canvas.width-canvasWidth),.5*(canvas.height-canvasHeight),canvasWidth,canvasHeight),gl.scissor(0,0,canvas.width,canvas.height)}function setCanvas(){embedded&&(canvas.width=offscreen.width=canvasWidth,canvas.height=offscreen.height=canvasHeight),size2=Math.hypot(canvasWidth,canvasHeight),halfCanvasWidth=.5*canvas.width,halfCanvasHeight=.5*canvas.height,ArcballFactor=1+8*Math.hypot(viewportMargin[0],viewportMargin[1])/size2}function setsize(e,t){e>maxViewportWidth&&(e=maxViewportWidth),t>maxViewportHeight&&(t=maxViewportHeight),shift.x*=e/canvasWidth,shift.y*=t/canvasHeight,canvasWidth=e,canvasHeight=t,setCanvas(),setViewport(),setProjection(),remesh=!0}function resize(){if(zoom0=initialZoom,absolute&&!embedded)canvasWidth=canvasWidth0*window.devicePixelRatio,canvasHeight=canvasHeight0*window.devicePixelRatio;else{let e=canvasWidth0/canvasHeight0;canvasWidth=Math.max(window.innerWidth-10,10),canvasHeight=Math.max(window.innerHeight-10,10),!orthographic&&canvasWidth<canvasHeight*e&&(zoom0*=canvasWidth/(canvasHeight*e))}canvas.width=canvasWidth,canvas.height=canvasHeight;window.innerWidth,window.innerHeight;viewportShift[0]/=zoom0,viewportShift[1]/=zoom0,setsize(canvasWidth,canvasHeight),redrawScene()}function expand(){Zoom*=zoomFactor,setZoom()}function shrink(){Zoom/=zoomFactor,setZoom()}class Align{constructor(e,t){if!
 (this.center=e,t){let e=t[0],i=t[1];this.ct=Math.cos(e),this.st=Math.sin(e),this.cp=Math.cos(i),this.sp=Math.sin(i)}}T0(e){return[e[0]+this.center[0],e[1]+this.center[1],e[2]+this.center[2]]}T(e){let t=e[0],i=e[1],a=e[2],n=t*this.ct+a*this.st;return[n*this.cp-i*this.sp+this.center[0],n*this.sp+i*this.cp+this.center[1],-t*this.st+a*this.ct+this.center[2]]}}function Tcorners(e,t,i){let a=[e(t),e([t[0],t[1],i[2]]),e([t[0],i[1],t[2]]),e([t[0],i[1],i[2]]),e([i[0],t[1],t[2]]),e([i[0],t[1],i[2]]),e([i[0],i[1],t[2]]),e(i)];return[minbound(a),maxbound(a)]}function material(e,t,i,a,n,r){Materials.push(new Material(e,t,i,a,n,r))}function patch(e,t,i,a,n,r){P.push(new BezierPatch(e,t,i,a,n,r))}function curve(e,t,i,a,n){P.push(new BezierCurve(e,t,i,a,n))}function pixel(e,t,i,a,n){P.push(new Pixel(e,t,i,a,n))}function triangles(e,t,i,a){P.push(new Triangles(e,t,i,a))}function sphere(e,t,i,n,r){let s,o,l,h,c,d,m=.524670512339254,f=.595936986722291,u=.954967051233925,p=.0820155480083437,g=.996685028842544,v=.0549670512339254,x=.998880711874577,w=.0405017186586849,M=[[[1,0,0],[1,0,m],[f,0,u],[p,0,g],[1,a,0],[1,a,m],[f,a*f,u],[p,a*p,g],[a,1,0],[a,1,m],[a*f,f,u],[a*p,p,g],[0,1,0],[0,1,m],[0,f,u],[0,p,g]],[[p,0,g],[p,a*p,g],[v,0,x],[a*p,p,g],[w,w,1],[.05*a,0,1],[0,p,g],[0,v,x],[0,.05*a,1],[0,0,1]]],b=new Align(e,r);function T(e){let t=Array(e.length);for(let i=0;i<e.length;++i){let a=e[i];t[i]=c([s*a[0],o*a[1],l*a[2]])}return t}r?(h=1,d=0,c=b.T.bind(b)):(h=-1,d=-t,c=b.T0.bind(b));let S=Tcorners(c,[-t,-t,d],[t,t,t]),R=S[0],I=S[1];for(let e=-1;e<=1;e+=2){s=e*t;for(let e=-1;e<=1;e+=2){o=e*t;for(let e=h;e<=1;e+=2){l=e*t;for(let e=0;e<2;++e)P.push(new BezierPatch(T(M[e]),i,n,R,I))}}}}let a=4/3*(Math.sqrt(2)-1);function disk(e,t,i,n,r){let s=1-2*a/3,o=[[1,0,0],[1,-a,0],[a,-1,0],[0,-1,0],[1,a,0],[s,0,0],[0,-s,0],[-a,-1,0],[a,1,0],[0,s,0],[-s,0,0],[-1,-a,0],[0,1,0],[-a,1,0],[-1,a,0],[-1,0,0]],l=new Align(e,r);let h=Tcorners(l.T.bind(l),[-t,-t,0],[t,t,0]);P.push(new BezierPatch(function(e){let i=Array(e.length);for(let a=0;a<e.length;++a){l!
 et n=e[a];i[a]=l.T([t*n[0],t*n[1],0])}return i}(o),i,n,h[0],h[1]))}function cylinder(e,t,i,n,r,s,o){let l,h,c=[[1,0,0],[1,0,1/3],[1,0,2/3],[1,0,1],[1,a,0],[1,a,1/3],[1,a,2/3],[1,a,1],[a,1,0],[a,1,1/3],[a,1,2/3],[a,1,1],[0,1,0],[0,1,1/3],[0,1,2/3],[0,1,1]],d=new Align(e,s);function m(e){let t=Array(e.length);for(let a=0;a<e.length;++a){let n=e[a];t[a]=d.T([l*n[0],h*n[1],i*n[2]])}return t}let f=Tcorners(d.T.bind(d),[-t,-t,0],[t,t,i]),u=f[0],p=f[1];for(let e=-1;e<=1;e+=2){l=e*t;for(let e=-1;e<=1;e+=2)h=e*t,P.push(new BezierPatch(m(c),n,r,u,p))}if(o){let t=d.T([0,0,i]);P.push(new BezierCurve([e,t],n,r,e,t))}}function rmf(e,t,i,a,n){class r{constructor(e,t,i){this.p=e,this.r=t,this.t=i,this.s=cross(i,t)}}let s=Number.EPSILON*Math.max(abs2(e),abs2(t),abs2(i),abs2(a));function o(n){if(1==n){let n=[a[0]-i[0],a[1]-i[1],a[2]-i[2]];return abs2(n)>s?unit(n):(n=[2*i[0]-t[0]-a[0],2*i[1]-t[1]-a[1],2*i[2]-t[2]-a[2]],abs2(n)>s?unit(n):[a[0]-e[0]+3*(t[0]-i[0]),a[1]-e[1]+3*(t[1]-i[1]),a[2]-e[2]+3*(t[2]-i[2])])}let r=[a[0]-e[0]+3*(t[0]-i[0]),a[1]-e[1]+3*(t[1]-i[1]),a[2]-e[2]+3*(t[2]-i[2])],o=[2*(e[0]+i[0])-4*t[0],2*(e[1]+i[1])-4*t[1],2*(e[2]+i[2])-4*t[2]],l=[t[0]-e[0],t[1]-e[1],t[2]-e[2]],h=n*n,c=[r[0]*h+o[0]*n+l[0],r[1]*h+o[1]*n+l[1],r[2]*h+o[2]*n+l[2]];return abs2(c)>s?unit(c):(h=2*n,c=[r[0]*h+o[0],r[1]*h+o[1],r[2]*h+o[2]],abs2(c)>s?unit(c):unit(r))}let l=Array(n.length),h=[t[0]-e[0],t[1]-e[1],t[2]-e[2]];abs2(h)<s&&(h=[e[0]-2*t[0]+i[0],e[1]-2*t[1]+i[1],e[2]-2*t[2]+i[2]],abs2(h)<s&&(h=[a[0]-e[0]+3*(t[0]-i[0]),a[1]-e[1]+3*(t[1]-i[1]),a[2]-e[2]+3*(t[2]-i[2])])),h=unit(h);let c=function(e){let t=cross(e,[0,1,0]),i=Number.EPSILON*abs2(e);return abs2(t)>i?unit(t):(t=cross(e,[0,0,1]),abs2(t)>i?unit(t):[1,0,0])}(h);l[0]=new r(e,c,h);for(let s=1;s<n.length;++s){let h=l[s-1],c=n[s],d=1-c,m=d*d,f=m*d,u=3*c;m*=u,d*=u*c;let p=c*c*c,g=[f*e[0]+m*t[0]+d*i[0]+p*a[0],f*e[1]+m*t[1]+d*i[1]+p*a[1],f*e[2]+m*t[2]+d*i[2]+p*a[2]],v=[g[0]-h.p[0],g[1]-h.p[1],g[2]-h.p[2]];if(0!=v[0]||0!=v[1]||0!=v[2]){let e=h.r,t=unit(v),i=h.t,a=dot(t,i),n=[i[0]-2*a*t[0],i[!
 1]-2*a*t[1],i[2]-2*a*t[2]];i=o(c);let d=2*dot(t,e),m=[e[0]-d*t[0],e[1]-d*t[1],e[2]-d*t[2]],f=unit([i[0]-n[0],i[1]-n[1],i[2]-n[2]]),u=2*dot(f,m);m=[m[0]-u*f[0],m[1]-u*f[1],m[2]-u*f[2]],l[s]=new r(g,unit(m),unit(i))}else l[s]=l[s-1]}return l}function tube(e,t,i,n,r,s,o){let l=rmf(e[0],e[1],e[2],e[3],[0,1/3,2/3,1]),h=a*t,c=[[t,0],[t,h],[h,t],[0,t]];function d(t,a,o,h){let d=Array(16);for(let i=0;i<4;++i){let n=l[i],r=n.r[0],s=n.s[0],m=r*t+s*a,f=r*o+s*h;r=n.r[1],s=n.s[1];let u=r*t+s*a,p=r*o+s*h;r=n.r[2],s=n.s[2];let g=r*t+s*a,v=r*o+s*h,x=e[i],w=x[0];w1=x[1],w2=x[2];for(let e=0;e<4;++e){let t=c[e],a=t[0],n=t[1];d[4*i+e]=[m*a+f*n+w,u*a+p*n+w1,g*a+v*n+w2]}}P.push(new BezierPatch(d,i,n,r,s))}d(1,0,0,1),d(0,-1,1,0),d(-1,0,0,-1),d(0,1,-1,0),o&&P.push(new BezierCurve(e,i,n,r,s))}async function getReq(e){return(await fetch(e)).arrayBuffer()}function rgb(e){return e.getBytes().filter((e,t)=>t%4!=3)}function createTexture(e,t,i=gl.RGB16F){let a=e.width(),n=e.height(),r=gl.createTexture();return gl.activeTexture(gl.TEXTURE0+t),gl.bindTexture(gl.TEXTURE_2D,r),gl.pixelStorei(gl.UNPACK_ALIGNMENT,1),gl.texParameteri(gl.TEXTURE_2D,gl.TEXTURE_MIN_FILTER,gl.LINEAR),gl.texParameteri(gl.TEXTURE_2D,gl.TEXTURE_MAG_FILTER,gl.LINEAR),gl.texImage2D(gl.TEXTURE_2D,0,i,a,n,0,gl.RGB,gl.FLOAT,rgb(e)),r}async function initIBL(){let e=imageURL+image+"/";function t(e){return new Promise(t=>setTimeout(t,e))}for(;!Module.EXRLoader;)await t(0);promises=[getReq(imageURL+"refl.exr").then(e=>{let t=new Module.EXRLoader(e);IBLbdrfMap=createTexture(t,0)}),getReq(e+"diffuse.exr").then(e=>{let t=new Module.EXRLoader(e);IBLDiffuseMap=createTexture(t,1)})],refl_promise=[],refl_promise.push(getReq(e+"refl0.exr"));for(let t=1;t<=roughnessStepCount;++t)refl_promise.push(getReq(e+"refl"+t+"w.exr"));finished_promise=Promise.all(refl_promise).then(e=>{let t=gl.createTexture();gl.activeTexture(gl.TEXTURE0+2),gl.pixelStorei(gl.UNPACK_ALIGNMENT,1),gl.bindTexture(gl.TEXTURE_2D,t),gl.texParameteri(gl.TEXTURE_2D,gl.TEXTURE_MAX_LEVEL,e.length-1),gl.texParameteri(gl.TEXTURE!
 _2D,gl.TEXTURE_MIN_FILTER,gl.LINEAR_MIPMAP_LINEAR),gl.texParameteri(gl.TEXTURE_2D,gl.TEXTURE_MAG_FILTER,gl.LINEAR),gl.texParameterf(gl.TEXTURE_2D,gl.TEXTURE_MIN_LOD,0),gl.texParameterf(gl.TEXTURE_2D,gl.TEXTURE_MAX_LOD,roughnessStepCount);for(let t=0;t<e.length;++t){let i=new Module.EXRLoader(e[t]);gl.texImage2D(gl.TEXTURE_2D,t,gl.RGB16F,i.width(),i.height(),0,gl.RGB,gl.FLOAT,rgb(i))}IBLReflMap=t}),promises.push(finished_promise),await Promise.all(promises)}function webGLStart(){canvas=document.getElementById("Asymptote"),embedded=window.top.document!=document,initGL(),gl.enable(gl.BLEND),gl.blendFunc(gl.SRC_ALPHA,gl.ONE_MINUS_SRC_ALPHA),gl.enable(gl.DEPTH_TEST),gl.enable(gl.SCISSOR_TEST),canvas.onmousedown=handleMouseDown,document.onmouseup=handleMouseUpOrTouchEnd,document.onmousemove=handleMouseMove,canvas.onkeydown=handleKey,embedded||enableZoom(),canvas.addEventListener("touchstart",handleTouchStart,!1),canvas.addEventListener("touchend",handleMouseUpOrTouchEnd,!1),canvas.addEventListener("touchcancel",handleMouseUpOrTouchEnd,!1),canvas.addEventListener("touchleave",handleMouseUpOrTouchEnd,!1),canvas.addEventListener("touchmove",handleTouchMove,!1),document.addEventListener("keydown",handleKey,!1),canvasWidth0=canvasWidth,canvasHeight0=canvasHeight,mat4.identity(rotMat),0!=window.innerWidth&&0!=window.innerHeight&&resize(),window.addEventListener("resize",resize,!1),ibl&&initIBL().then(SetIBL).then(redrawScene)}
+let vertex="\n#ifdef WEBGL2\n#define IN in\n#define OUT out\n#else\n#define IN attribute\n#define OUT varying\n#endif\n\nIN vec3 position;\n#ifdef WIDTH\nIN float width;\n#endif\n#ifdef NORMAL\nIN vec3 normal;\n#endif\n\nIN float materialIndex;\n\n#ifdef WEBGL2\nflat out int MaterialIndex;\n#ifdef COLOR\nOUT vec4 Color;\n#endif\n\n#else\nOUT vec4 diffuse;\nOUT vec3 specular;\nOUT float roughness,metallic,fresnel0;\nOUT vec4 emissive;\n\nstruct Material {\n  vec4 diffuse,emissive,specular;\n  vec4 parameters;\n};\n\nuniform Material Materials[Nmaterials];\n#endif\n\n#ifdef COLOR\nIN vec4 color;\n#endif\n\nuniform mat3 normMat;\nuniform mat4 viewMat;\nuniform mat4 projViewMat;\n\n#ifdef NORMAL\n#ifndef ORTHOGRAPHIC\nOUT vec3 ViewPosition;\n#endif\nOUT vec3 Normal;\n#endif\n\nvoid main(void)\n{\n  vec4 v=vec4(position,1.0);\n  gl_Position=projViewMat*v;\n\n#ifdef NORMAL\n#ifndef ORTHOGRAPHIC\n  ViewPosition=(viewMat*v).xyz;\n#endif\n  Normal=normalize(normal*normMat);\n#endif\n\n#ifdef WEBGL2\n  MaterialIndex=int(materialIndex);\n#ifdef COLOR\n  Color=color;\n#endif\n#else\n#ifdef NORMAL\n  Material m;\n#ifdef TRANSPARENT\n  m=Materials[int(abs(materialIndex))-1];\n  emissive=m.emissive;\n  if(materialIndex >= 0.0)\n    diffuse=m.diffuse;\n  else {\n    diffuse=color;\n#if nlights == 0\n    emissive += color;\n#endif\n  }\n#else\n  m=Materials[int(materialIndex)];\n  emissive=m.emissive;\n#ifdef COLOR\n  diffuse=color;\n#if nlights == 0\n    emissive += color;\n#endif\n#else\n  diffuse=m.diffuse;\n#endif // COLOR\n#endif // TRANSPARENT\n  specular=m.specular.rgb;\n  vec4 parameters=m.parameters;\n  roughness=1.0-parameters[0];\n  metallic=parameters[1];\n  fresnel0=parameters[2];\n#else\n  emissive=Materials[int(materialIndex)].emissive;\n#endif // NORMAL\n#endif // WEBGL2\n\n#ifdef WIDTH\n  gl_PointSize=width;\n#endif\n}\n",fragment="\n#ifdef WEBGL2\n#define IN in\nout vec4 outValue;\n#define OUTVALUE outValue\n#else\n#define IN varying\n#define OUTVALUE gl_FragColor\n#endif\n\n#ifdef WEBGL2\nflat in int !
 MaterialIndex;\n\nstruct Material {\n  vec4 diffuse,emissive,specular;\n  vec4 parameters;\n};\n\nuniform Material Materials[Nmaterials];\n\nvec4 diffuse;\nvec3 specular;\nfloat roughness,metallic,fresnel0;\nvec4 emissive;\n\n#ifdef COLOR\nin vec4 Color;\n#endif\n\n#else\nIN vec4 diffuse;\nIN vec3 specular;\nIN float roughness,metallic,fresnel0;\nIN vec4 emissive;\n#endif\n\n#ifdef NORMAL\n\n#ifndef ORTHOGRAPHIC\nIN vec3 ViewPosition;\n#endif\nIN vec3 Normal;\n\nvec3 normal;\n\nstruct Light {\n  vec3 direction;\n  vec3 color;\n};\n\nuniform Light Lights[Nlights];\n\n#ifdef USE_IBL\nuniform sampler2D reflBRDFSampler;\nuniform sampler2D diffuseSampler;\nuniform sampler2D reflImgSampler;\n\nconst float pi=acos(-1.0);\nconst float piInv=1.0/pi;\nconst float twopi=2.0*pi;\nconst float twopiInv=1.0/twopi;\n\n// (x,y,z) -> (r,theta,phi);\n// theta -> [0,pi]: colatitude\n// phi -> [-pi,pi]: longitude\nvec3 cart2sphere(vec3 cart)\n{\n  float x=cart.x;\n  float y=cart.z;\n  float z=cart.y;\n\n  float r=length(cart);\n  float theta=r > 0.0 ? acos(z/r) : 0.0;\n  float phi=atan(y,x);\n\n  return vec3(r,theta,phi);\n}\n\nvec2 normalizedAngle(vec3 cartVec)\n{\n  vec3 sphericalVec=cart2sphere(cartVec);\n  sphericalVec.y=sphericalVec.y*piInv;\n  sphericalVec.z=0.75-sphericalVec.z*twopiInv;\n  return sphericalVec.zy;\n}\n\nvec3 IBLColor(vec3 viewDir)\n{\n  vec3 IBLDiffuse=diffuse.rgb*texture(diffuseSampler,normalizedAngle(normal)).rgb;\n  vec3 reflectVec=normalize(reflect(-viewDir,normal));\n  vec2 reflCoord=normalizedAngle(reflectVec);\n  vec3 IBLRefl=textureLod(reflImgSampler,reflCoord,roughness*ROUGHNESS_STEP_COUNT).rgb;\n  vec2 IBLbrdf=texture(reflBRDFSampler,vec2(dot(normal,viewDir),roughness)).rg;\n  float specularMultiplier=fresnel0*IBLbrdf.x+IBLbrdf.y;\n  vec3 dielectric=IBLDiffuse+specularMultiplier*IBLRefl;\n  vec3 metal=diffuse.rgb*IBLRefl;\n  return mix(dielectric,metal,metallic);\n}\n#else\nfloat Roughness2;\nfloat NDF_TRG(vec3 h)\n{\n  float ndoth=max(dot(normal,h),0.0);\n  float alpha2=Roughness2*Roughness2;\n  flo!
 at denom=ndoth*ndoth*(alpha2-1.0)+1.0;\n  return denom != 0.0 ? alpha2/(denom*denom) : 0.0;\n}\n\nfloat GGX_Geom(vec3 v)\n{\n  float ndotv=max(dot(v,normal),0.0);\n  float ap=1.0+Roughness2;\n  float k=0.125*ap*ap;\n  return ndotv/((ndotv*(1.0-k))+k);\n}\n\nfloat Geom(vec3 v, vec3 l)\n{\n  return GGX_Geom(v)*GGX_Geom(l);\n}\n\nfloat Fresnel(vec3 h, vec3 v, float fresnel0)\n{\n  float a=1.0-max(dot(h,v),0.0);\n  float b=a*a;\n  return fresnel0+(1.0-fresnel0)*b*b*a;\n}\n\n// physical based shading using UE4 model.\nvec3 BRDF(vec3 viewDirection, vec3 lightDirection)\n{\n  vec3 lambertian=diffuse.rgb;\n  vec3 h=normalize(lightDirection+viewDirection);\n\n  float omegain=max(dot(viewDirection,normal),0.0);\n  float omegaln=max(dot(lightDirection,normal),0.0);\n\n  float D=NDF_TRG(h);\n  float G=Geom(viewDirection,lightDirection);\n  float F=Fresnel(h,viewDirection,fresnel0);\n\n  float denom=4.0*omegain*omegaln;\n  float rawReflectance=denom > 0.0 ? (D*G)/denom : 0.0;\n\n  vec3 dielectric=mix(lambertian,rawReflectance*specular,F);\n  vec3 metal=rawReflectance*diffuse.rgb;\n\n  return mix(dielectric,metal,metallic);\n}\n#endif\n\n#endif\n\nvoid main(void)\n{\n#ifdef WEBGL2\n#ifdef NORMAL\n  Material m;\n#ifdef TRANSPARENT\n  m=Materials[abs(MaterialIndex)-1];\n  emissive=m.emissive;\n  if(MaterialIndex >= 0)\n    diffuse=m.diffuse;\n  else {\n    diffuse=Color;\n#if nlights == 0\n    emissive += Color;\n#endif\n  }\n#else\n  m=Materials[MaterialIndex];\n  emissive=m.emissive;\n#ifdef COLOR\n  diffuse=Color;\n#if nlights == 0\n    emissive += Color;\n#endif\n#else\n  diffuse=m.diffuse;\n#endif // COLOR\n#endif // TRANSPARENT\n  specular=m.specular.rgb;\n  vec4 parameters=m.parameters;\n  roughness=1.0-parameters[0];\n  metallic=parameters[1];\n  fresnel0=parameters[2];\n#else\n  emissive=Materials[MaterialIndex].emissive;\n#endif // NORMAL\n#endif // WEBGL2\n\n#if defined(NORMAL) && nlights > 0\n  normal=normalize(Normal);\n  normal=gl_FrontFacing ? normal : -normal;\n#ifdef ORTHOGRAPHIC\n  vec3 viewDir=vec3(0.0,0.0,1.!
 0);\n#else\n  vec3 viewDir=-normalize(ViewPosition);\n#endif\n\nvec3 color;\n#ifdef USE_IBL\n  color=IBLColor(viewDir);\n#else\n  Roughness2=roughness*roughness;\n  color=emissive.rgb;\n  for(int i=0; i < nlights; ++i) {\n    Light Li=Lights[i];\n    vec3 L=Li.direction;\n    float cosTheta=max(dot(normal,L),0.0);\n    vec3 radiance=cosTheta*Li.color;\n    color += BRDF(viewDir,L)*radiance;\n  }\n#endif\n  OUTVALUE=vec4(color,diffuse.a);\n#else\n  OUTVALUE=emissive;\n#endif\n}\n";!function(e,t){if("object"==typeof exports&&"object"==typeof module)module.exports=t();else if("function"==typeof define&&define.amd)define([],t);else{var i=t();for(var a in i)("object"==typeof exports?exports:e)[a]=i[a]}}("undefined"!=typeof self?self:this,(function(){return function(e){var t={};function i(a){if(t[a])return t[a].exports;var n=t[a]={i:a,l:!1,exports:{}};return e[a].call(n.exports,n,n.exports,i),n.l=!0,n.exports}return i.m=e,i.c=t,i.d=function(e,t,a){i.o(e,t)||Object.defineProperty(e,t,{configurable:!1,enumerable:!0,get:a})},i.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return i.d(t,"a",t),t},i.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},i.p="",i(i.s=1)}([function(e,t,i){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.setMatrixArrayType=function(e){t.ARRAY_TYPE=e},t.toRadian=function(e){return e*n},t.equals=function(e,t){return Math.abs(e-t)<=a*Math.max(1,Math.abs(e),Math.abs(t))};var a=t.EPSILON=1e-6;t.ARRAY_TYPE="undefined"!=typeof Float32Array?Float32Array:Array,t.RANDOM=Math.random;var n=Math.PI/180},function(e,t,i){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.mat4=t.mat3=void 0;var a=r(i(2)),n=r(i(3));function r(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var i in e)Object.prototype.hasOwnProperty.call(e,i)&&(t[i]=e[i]);return t.default=e,t}t.mat3=a,t.mat4=n},function(e,t,i){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.create=function(){var e=new a.ARRAY_TYPE(9);return e[0]=1,e[1]=0,e[2]=0!
 ,e[3]=0,e[4]=1,e[5]=0,e[6]=0,e[7]=0,e[8]=1,e},t.fromMat4=function(e,t){return e[0]=t[0],e[1]=t[1],e[2]=t[2],e[3]=t[4],e[4]=t[5],e[5]=t[6],e[6]=t[8],e[7]=t[9],e[8]=t[10],e},t.invert=function(e,t){var i=t[0],a=t[1],n=t[2],r=t[3],s=t[4],o=t[5],l=t[6],h=t[7],c=t[8],d=c*s-o*h,m=-c*r+o*l,f=h*r-s*l,u=i*d+a*m+n*f;if(!u)return null;return u=1/u,e[0]=d*u,e[1]=(-c*a+n*h)*u,e[2]=(o*a-n*s)*u,e[3]=m*u,e[4]=(c*i-n*l)*u,e[5]=(-o*i+n*r)*u,e[6]=f*u,e[7]=(-h*i+a*l)*u,e[8]=(s*i-a*r)*u,e};var a=function(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var i in e)Object.prototype.hasOwnProperty.call(e,i)&&(t[i]=e[i]);return t.default=e,t}(i(0))},function(e,t,i){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.create=function(){var e=new a.ARRAY_TYPE(16);return e[0]=1,e[1]=0,e[2]=0,e[3]=0,e[4]=0,e[5]=1,e[6]=0,e[7]=0,e[8]=0,e[9]=0,e[10]=1,e[11]=0,e[12]=0,e[13]=0,e[14]=0,e[15]=1,e},t.identity=function(e){return e[0]=1,e[1]=0,e[2]=0,e[3]=0,e[4]=0,e[5]=1,e[6]=0,e[7]=0,e[8]=0,e[9]=0,e[10]=1,e[11]=0,e[12]=0,e[13]=0,e[14]=0,e[15]=1,e},t.invert=function(e,t){var i=t[0],a=t[1],n=t[2],r=t[3],s=t[4],o=t[5],l=t[6],h=t[7],c=t[8],d=t[9],m=t[10],f=t[11],u=t[12],p=t[13],g=t[14],v=t[15],x=i*o-a*s,w=i*l-n*s,M=i*h-r*s,b=a*l-n*o,T=a*h-r*o,S=n*h-r*l,R=c*p-d*u,A=c*g-m*u,I=c*v-f*u,P=d*g-m*p,E=d*v-f*p,y=m*v-f*g,L=x*y-w*E+M*P+b*I-T*A+S*R;if(!L)return null;return L=1/L,e[0]=(o*y-l*E+h*P)*L,e[1]=(n*E-a*y-r*P)*L,e[2]=(p*S-g*T+v*b)*L,e[3]=(m*T-d*S-f*b)*L,e[4]=(l*I-s*y-h*A)*L,e[5]=(i*y-n*I+r*A)*L,e[6]=(g*M-u*S-v*w)*L,e[7]=(c*S-m*M+f*w)*L,e[8]=(s*E-o*I+h*R)*L,e[9]=(a*I-i*E-r*R)*L,e[10]=(u*T-p*M+v*x)*L,e[11]=(d*M-c*T-f*x)*L,e[12]=(o*A-s*P-l*R)*L,e[13]=(i*P-a*A+n*R)*L,e[14]=(p*w-u*b-g*x)*L,e[15]=(c*b-d*w+m*x)*L,e},t.multiply=n,t.translate=function(e,t,i){var a=i[0],n=i[1],r=i[2],s=void 0,o=void 0,l=void 0,h=void 0,c=void 0,d=void 0,m=void 0,f=void 0,u=void 0,p=void 0,g=void 0,v=void 0;t===e?(e[12]=t[0]*a+t[4]*n+t[8]*r+t[12],e[13]=t[1]*a+t[5]*n+t[9]*r+t[13],e[14]=t[2]*a+t[6]*n+t[10]*r+t[14],e[15]=t[3]*a+t[7]*n+t[11]*r+t[15]):(s=t[0],o=t[1],l=t[2],!
 h=t[3],c=t[4],d=t[5],m=t[6],f=t[7],u=t[8],p=t[9],g=t[10],v=t[11],e[0]=s,e[1]=o,e[2]=l,e[3]=h,e[4]=c,e[5]=d,e[6]=m,e[7]=f,e[8]=u,e[9]=p,e[10]=g,e[11]=v,e[12]=s*a+c*n+u*r+t[12],e[13]=o*a+d*n+p*r+t[13],e[14]=l*a+m*n+g*r+t[14],e[15]=h*a+f*n+v*r+t[15]);return e},t.rotate=function(e,t,i,n){var r,s,o,l,h,c,d,m,f,u,p,g,v,x,w,M,b,T,S,R,A,I,P,E,y=n[0],L=n[1],D=n[2],O=Math.sqrt(y*y+L*L+D*D);if(Math.abs(O)<a.EPSILON)return null;y*=O=1/O,L*=O,D*=O,r=Math.sin(i),s=Math.cos(i),o=1-s,l=t[0],h=t[1],c=t[2],d=t[3],m=t[4],f=t[5],u=t[6],p=t[7],g=t[8],v=t[9],x=t[10],w=t[11],M=y*y*o+s,b=L*y*o+D*r,T=D*y*o-L*r,S=y*L*o-D*r,R=L*L*o+s,A=D*L*o+y*r,I=y*D*o+L*r,P=L*D*o-y*r,E=D*D*o+s,e[0]=l*M+m*b+g*T,e[1]=h*M+f*b+v*T,e[2]=c*M+u*b+x*T,e[3]=d*M+p*b+w*T,e[4]=l*S+m*R+g*A,e[5]=h*S+f*R+v*A,e[6]=c*S+u*R+x*A,e[7]=d*S+p*R+w*A,e[8]=l*I+m*P+g*E,e[9]=h*I+f*P+v*E,e[10]=c*I+u*P+x*E,e[11]=d*I+p*P+w*E,t!==e&&(e[12]=t[12],e[13]=t[13],e[14]=t[14],e[15]=t[15]);return e},t.fromTranslation=function(e,t){return e[0]=1,e[1]=0,e[2]=0,e[3]=0,e[4]=0,e[5]=1,e[6]=0,e[7]=0,e[8]=0,e[9]=0,e[10]=1,e[11]=0,e[12]=t[0],e[13]=t[1],e[14]=t[2],e[15]=1,e},t.fromRotation=function(e,t,i){var n,r,s,o=i[0],l=i[1],h=i[2],c=Math.sqrt(o*o+l*l+h*h);if(Math.abs(c)<a.EPSILON)return null;return o*=c=1/c,l*=c,h*=c,n=Math.sin(t),r=Math.cos(t),s=1-r,e[0]=o*o*s+r,e[1]=l*o*s+h*n,e[2]=h*o*s-l*n,e[3]=0,e[4]=o*l*s-h*n,e[5]=l*l*s+r,e[6]=h*l*s+o*n,e[7]=0,e[8]=o*h*s+l*n,e[9]=l*h*s-o*n,e[10]=h*h*s+r,e[11]=0,e[12]=0,e[13]=0,e[14]=0,e[15]=1,e},t.frustum=function(e,t,i,a,n,r,s){var o=1/(i-t),l=1/(n-a),h=1/(r-s);return e[0]=2*r*o,e[1]=0,e[2]=0,e[3]=0,e[4]=0,e[5]=2*r*l,e[6]=0,e[7]=0,e[8]=(i+t)*o,e[9]=(n+a)*l,e[10]=(s+r)*h,e[11]=-1,e[12]=0,e[13]=0,e[14]=s*r*2*h,e[15]=0,e},t.ortho=function(e,t,i,a,n,r,s){var o=1/(t-i),l=1/(a-n),h=1/(r-s);return e[0]=-2*o,e[1]=0,e[2]=0,e[3]=0,e[4]=0,e[5]=-2*l,e[6]=0,e[7]=0,e[8]=0,e[9]=0,e[10]=2*h,e[11]=0,e[12]=(t+i)*o,e[13]=(n+a)*l,e[14]=(s+r)*h,e[15]=1,e};var a=function(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var i in e)Object.prototype.hasOwnProperty.call(e,i)&&!
 (t[i]=e[i]);return t.default=e,t}(i(0));function n(e,t,i){var a=t[0],n=t[1],r=t[2],s=t[3],o=t[4],l=t[5],h=t[6],c=t[7],d=t[8],m=t[9],f=t[10],u=t[11],p=t[12],g=t[13],v=t[14],x=t[15],w=i[0],M=i[1],b=i[2],T=i[3];return e[0]=w*a+M*o+b*d+T*p,e[1]=w*n+M*l+b*m+T*g,e[2]=w*r+M*h+b*f+T*v,e[3]=w*s+M*c+b*u+T*x,w=i[4],M=i[5],b=i[6],T=i[7],e[4]=w*a+M*o+b*d+T*p,e[5]=w*n+M*l+b*m+T*g,e[6]=w*r+M*h+b*f+T*v,e[7]=w*s+M*c+b*u+T*x,w=i[8],M=i[9],b=i[10],T=i[11],e[8]=w*a+M*o+b*d+T*p,e[9]=w*n+M*l+b*m+T*g,e[10]=w*r+M*h+b*f+T*v,e[11]=w*s+M*c+b*u+T*x,w=i[12],M=i[13],b=i[14],T=i[15],e[12]=w*a+M*o+b*d+T*p,e[13]=w*n+M*l+b*m+T*g,e[14]=w*r+M*h+b*f+T*v,e[15]=w*s+M*c+b*u+T*x,e}}])}));let Transform,canvasWidth,canvasHeight,imageURL,image,minBound,maxBound,orthographic,angleOfView,initialZoom,viewportMargin,zoomFactor,zoomPinchFactor,zoomPinchCap,zoomStep,shiftHoldDistance,shiftWaitTime,vibrateTime,canvasWidth0,canvasHeight0,zoom0,embedded,canvas,gl,alpha,offscreen,context,maxMaterials,halfCanvasWidth,halfCanvasHeight,P=[],Materials=[],Lights=[],Centers=[],Background=[1,1,1,1],absolute=!1,ibl=!1,viewportShift=[0,0],webgl2=!1,nlights=0,Nmaterials=2,materials=[];const pixelResolution=.75,zoomRemeshFactor=1.5,FillFactor=.1,windowTrim=10,third=1/3,pi=Math.acos(-1),radians=pi/180;let Zoom,lastZoom,xshift,yshift,maxViewportWidth,maxViewportHeight,H,zmin,zmax,size2,ArcballFactor,rotMat=mat4.create(),projMat=mat4.create(),viewMat=mat4.create(),projViewMat=mat4.create(),normMat=mat3.create(),viewMat3=mat3.create(),cjMatInv=mat4.create(),Temp=mat4.create(),center={x:0,y:0,z:0},shift={x:0,y:0},viewParam={xmin:0,xmax:0,ymin:0,ymax:0,zmin:0,zmax:0},remesh=!0,wireframe=0,mouseDownOrTouchActive=!1,lastMouseX=null,lastMouseY=null,touchID=null,Positions=[],Normals=[],Colors=[],Indices=[],IBLReflMap=null,IBLDiffuseMap=null,IBLbdrfMap=null;function IBLReady(){return null!==IBLReflMap&&null!==IBLDiffuseMap&&null!==IBLbdrfMap}function SetIBL(){embedded||deleteShaders(),initShaders(ibl)}let roughnessStepCount=8;class Material{constructor(e,t,i,a,n,r){this.diffuse=e,this.e!
 missive=t,this.specular=i,this.shininess=a,this.metallic=n,this.fresnel0=r}setUniform(e,t){let i=i=>gl.getUniformLocation(e,"Materials["+t+"]."+i);gl.uniform4fv(i("diffuse"),new Float32Array(this.diffuse)),gl.uniform4fv(i("emissive"),new Float32Array(this.emissive)),gl.uniform4fv(i("specular"),new Float32Array(this.specular)),gl.uniform4f(i("parameters"),this.shininess,this.metallic,this.fresnel0,0)}}let indexExt,TRIANGLES,material0Data,material1Data,materialData,colorData,transparentData,triangleData,materialIndex,enumPointLight=1,enumDirectionalLight=2;class Light{constructor(e,t){this.direction=e,this.color=t}setUniform(e,t){let i=i=>gl.getUniformLocation(e,"Lights["+t+"]."+i);gl.uniform3fv(i("direction"),new Float32Array(this.direction)),gl.uniform3fv(i("color"),new Float32Array(this.color))}}function initShaders(e=!1){let t=gl.getParameter(gl.MAX_VERTEX_UNIFORM_VECTORS);maxMaterials=Math.floor((t-14)/4),Nmaterials=Math.min(Math.max(Nmaterials,Materials.length),maxMaterials),pixelOpt=["WIDTH"],materialOpt=["NORMAL"],colorOpt=["NORMAL","COLOR"],transparentOpt=["NORMAL","COLOR","TRANSPARENT"],e&&(materialOpt.push("USE_IBL"),transparentOpt.push("USE_IBL")),pixelShader=initShader(pixelOpt),materialShader=initShader(materialOpt),colorShader=initShader(colorOpt),transparentShader=initShader(transparentOpt)}function deleteShaders(){gl.deleteProgram(transparentShader),gl.deleteProgram(colorShader),gl.deleteProgram(materialShader),gl.deleteProgram(pixelShader)}function saveAttributes(){let e=webgl2?window.top.document.asygl2[alpha]:window.top.document.asygl[alpha];e.gl=gl,e.nlights=Lights.length,e.Nmaterials=Nmaterials,e.maxMaterials=maxMaterials,e.pixelShader=pixelShader,e.materialShader=materialShader,e.colorShader=colorShader,e.transparentShader=transparentShader}function restoreAttributes(){let e=webgl2?window.top.document.asygl2[alpha]:window.top.document.asygl[alpha];gl=e.gl,nlights=e.nlights,Nmaterials=e.Nmaterials,maxMaterials=e.maxMaterials,pixelShader=e.pixelShader,materialShader=e.materialShader,colorShade!
 r=e.colorShader,transparentShader=e.transparentShader}function webGL(e,t){let i;return webgl2&&(i=e.getContext("webgl2",{alpha:t}),embedded&&!i)?(webgl2=!1,ibl=!1,initGL(!1),null):(i||(webgl2=!1,ibl=!1,i=e.getContext("webgl",{alpha:t})),i||alert("Could not initialize WebGL"),i)}function initGL(e=!0){if(ibl&&(webgl2=!0),alpha=Background[3]<1,embedded){let t=window.top.document;if(e&&(context=canvas.getContext("2d")),offscreen=webgl2?t.offscreen2:t.offscreen,offscreen||(offscreen=t.createElement("canvas"),webgl2?t.offscreen2=offscreen:t.offscreen=offscreen),webgl2?t.asygl2||(t.asygl2=Array(2)):t.asygl||(t.asygl=Array(2)),asygl=webgl2?t.asygl2:t.asygl,asygl[alpha]&&asygl[alpha].gl)restoreAttributes(),(Lights.length!=nlights||Math.min(Materials.length,maxMaterials)>Nmaterials)&&(initShaders(),saveAttributes());else{if(rc=webGL(offscreen,alpha),!rc)return;gl=rc,initShaders(),webgl2?t.asygl2[alpha]={}:t.asygl[alpha]={},saveAttributes()}}else gl=webGL(canvas,alpha),initShaders();indexExt=gl.getExtension("OES_element_index_uint"),TRIANGLES=gl.TRIANGLES,material0Data=new vertexBuffer(gl.POINTS),material1Data=new vertexBuffer(gl.LINES),materialData=new vertexBuffer,colorData=new vertexBuffer,transparentData=new vertexBuffer,triangleData=new vertexBuffer}function getShader(e,t,i,a=[]){let n=webgl2?"300 es":"100",r=Array(...a),s=[["nlights",0==wireframe?Lights.length:0],["Nmaterials",Nmaterials]],o=[["int","Nlights",Math.max(Lights.length,1)]];webgl2&&r.push("WEBGL2"),ibl&&s.push(["ROUGHNESS_STEP_COUNT",roughnessStepCount.toFixed(2)]),orthographic&&r.push("ORTHOGRAPHIC"),macros_str=s.map(e=>`#define ${e[0]} ${e[1]}`).join("\n"),define_str=r.map(e=>"#define "+e).join("\n"),const_str=o.map(e=>`const ${e[0]} ${e[1]}=${e[2]};`).join("\n"),ext_str=[].map(e=>`#extension ${e}: enable`).join("\n"),shaderSrc=`#version ${n}\n${ext_str}\n${define_str}\n${const_str}\n${macros_str}\n\n\n#ifdef GL_FRAGMENT_PRECISION_HIGH\nprecision highp float;\n#else\nprecision mediump float;\n#endif\n  \n${t}\n  `;let l=e.createShader(i);return e.shade!
 rSource(l,shaderSrc),e.compileShader(l),e.getShaderParameter(l,e.COMPILE_STATUS)?l:(alert(e.getShaderInfoLog(l)),null)}function registerBuffer(e,t,i,a=gl.ARRAY_BUFFER){return e.length>0&&(0==t&&(t=gl.createBuffer(),i=!0),gl.bindBuffer(a,t),i&&gl.bufferData(a,e,gl.STATIC_DRAW)),t}function drawBuffer(e,t,i=e.indices){if(0==e.indices.length)return;let a=t!=pixelShader;setUniforms(e,t),null!=IBLDiffuseMap&&(gl.activeTexture(gl.TEXTURE0),gl.bindTexture(gl.TEXTURE_2D,IBLbdrfMap),gl.uniform1i(gl.getUniformLocation(t,"reflBRDFSampler"),0),gl.activeTexture(gl.TEXTURE1),gl.bindTexture(gl.TEXTURE_2D,IBLDiffuseMap),gl.uniform1i(gl.getUniformLocation(t,"diffuseSampler"),1),gl.activeTexture(gl.TEXTURE2),gl.bindTexture(gl.TEXTURE_2D,IBLReflMap),gl.uniform1i(gl.getUniformLocation(t,"reflImgSampler"),2));let n=remesh||e.partial||!e.rendered;e.verticesBuffer=registerBuffer(new Float32Array(e.vertices),e.verticesBuffer,n),gl.vertexAttribPointer(positionAttribute,3,gl.FLOAT,!1,a?24:16,0),a?Lights.length>0&&gl.vertexAttribPointer(normalAttribute,3,gl.FLOAT,!1,24,12):gl.vertexAttribPointer(widthAttribute,1,gl.FLOAT,!1,16,12),e.materialsBuffer=registerBuffer(new Int16Array(e.materialIndices),e.materialsBuffer,n),gl.vertexAttribPointer(materialAttribute,1,gl.SHORT,!1,2,0),t!=colorShader&&t!=transparentShader||(e.colorsBuffer=registerBuffer(new Uint8Array(e.colors),e.colorsBuffer,n),gl.vertexAttribPointer(colorAttribute,4,gl.UNSIGNED_BYTE,!0,0,0)),e.indicesBuffer=registerBuffer(indexExt?new Uint32Array(i):new Uint16Array(i),e.indicesBuffer,n,gl.ELEMENT_ARRAY_BUFFER),e.rendered=!0,gl.drawElements(a?wireframe?gl.LINES:e.type:gl.POINTS,i.length,indexExt?gl.UNSIGNED_INT:gl.UNSIGNED_SHORT,0)}class vertexBuffer{constructor(e){this.type=e||TRIANGLES,this.verticesBuffer=0,this.materialsBuffer=0,this.colorsBuffer=0,this.indicesBuffer=0,this.rendered=!1,this.partial=!1,this.clear()}clear(){this.vertices=[],this.materialIndices=[],this.colors=[],this.indices=[],this.nvertices=0,this.materials=[],this.materialTable=[]}vertex(e,t){return this.vertic!
 es.push(e[0]),this.vertices.push(e[1]),this.vertices.push(e[2]),this.vertices.push(t[0]),this.vertices.push(t[1]),this.vertices.push(t[2]),this.materialIndices.push(materialIndex),this.nvertices++}Vertex(e,t,i=[0,0,0,0]){return this.vertices.push(e[0]),this.vertices.push(e[1]),this.vertices.push(e[2]),this.vertices.push(t[0]),this.vertices.push(t[1]),this.vertices.push(t[2]),this.materialIndices.push(materialIndex),this.colors.push(i[0]),this.colors.push(i[1]),this.colors.push(i[2]),this.colors.push(i[3]),this.nvertices++}vertex0(e,t){return this.vertices.push(e[0]),this.vertices.push(e[1]),this.vertices.push(e[2]),this.vertices.push(t),this.materialIndices.push(materialIndex),this.nvertices++}iVertex(e,t,i,a=[0,0,0,0]){let n=6*e;this.vertices[n]=t[0],this.vertices[n+1]=t[1],this.vertices[n+2]=t[2],this.vertices[n+3]=i[0],this.vertices[n+4]=i[1],this.vertices[n+5]=i[2],this.materialIndices[e]=materialIndex;let r=4*e;this.colors[r]=a[0],this.colors[r+1]=a[1],this.colors[r+2]=a[2],this.colors[r+3]=a[3],this.indices.push(e)}append(e){append(this.vertices,e.vertices),append(this.materialIndices,e.materialIndices),append(this.colors,e.colors),appendOffset(this.indices,e.indices,this.nvertices),this.nvertices+=e.nvertices}}function append(e,t){let i=e.length,a=t.length;e.length+=a;for(let n=0;n<a;++n)e[i+n]=t[n]}function appendOffset(e,t,i){let a=e.length,n=t.length;e.length+=t.length;for(let r=0;r<n;++r)e[a+r]=t[r]+i}class Geometry{constructor(){this.data=new vertexBuffer,this.Onscreen=!1,this.m=[]}offscreen(e){let t=projViewMat,i=e[0],a=i[0],n=i[1],r=i[2],s=1/(t[3]*a+t[7]*n+t[11]*r+t[15]);this.x=this.X=(t[0]*a+t[4]*n+t[8]*r+t[12])*s,this.y=this.Y=(t[1]*a+t[5]*n+t[9]*r+t[13])*s;for(let i=1,a=e.length;i<a;++i){let a=e[i],n=a[0],r=a[1],s=a[2],o=1/(t[3]*n+t[7]*r+t[11]*s+t[15]),l=(t[0]*n+t[4]*r+t[8]*s+t[12])*o,h=(t[1]*n+t[5]*r+t[9]*s+t[13])*o;l<this.x?this.x=l:l>this.X&&(this.X=l),h<this.y?this.y=h:h>this.Y&&(this.Y=h)}return(this.X<-1.01||this.x>1.01||this.Y<-1.01||this.y>1.01)&&(this.Onscreen=!1,!0)}T(e){let t=this.c[0!
 ],i=this..c[1],a=this.c[2],n=e[0]-t,r=e[1]-i,s=e[2]-a;return[n*normMat[0]+r*normMat[3]+s*normMat[6]+t,n*normMat[1]+r*normMat[4]+s*normMat[7]+i,n*normMat[2]+r*normMat[5]+s*normMat[8]+a]}Tcorners(e,t){return[this.T(e),this.T([e[0],e[1],t[2]]),this.T([e[0],t[1],e[2]]),this.T([e[0],t[1],t[2]]),this.T([t[0],e[1],e[2]]),this.T([t[0],e[1],t[2]]),this.T([t[0],t[1],e[2]]),this.T(t)]}setMaterial(e,t){null==e.materialTable[this.MaterialIndex]&&(e.materials.length>=Nmaterials&&(e.partial=!0,t()),e.materialTable[this.MaterialIndex]=e.materials.length,e.materials.push(Materials[this.MaterialIndex])),materialIndex=e.materialTable[this.MaterialIndex]}render(){let e;if(this.setMaterialIndex(),0==this.CenterIndex?e=corners(this.Min,this.Max):(this.c=Centers[this.CenterIndex-1],e=this.Tcorners(this.Min,this.Max)),this.offscreen(e))return this.data.clear(),void this.notRendered();let t,i=this.controlpoints;if(0==this.CenterIndex){if(!remesh&&this.Onscreen)return void this.append();t=i}else{let e=i.length;t=Array(e);for(let a=0;a<e;++a)t[a]=this.T(i[a])}let a=orthographic?1:this.Min[2]/maxBound[2],n=.75*Math.hypot(a*(viewParam.xmax-viewParam.xmin),a*(viewParam.ymax-viewParam.ymin))/size2;this.res2=n*n,this.Epsilon=.1*n,this.data.clear(),this.notRendered(),this.Onscreen=!0,this.process(t)}}class BezierPatch extends Geometry{constructor(e,t,i,a,n,r){super(),this.controlpoints=e,this.CenterIndex=t,this.MaterialIndex=i,this.Min=a,this.Max=n,this.color=r;let s=e.length;if(r){let e=r[0][3]+r[1][3]+r[2][3];this.transparent=16==s||4==s?e+r[3][3]<1020:e<765}else this.transparent=Materials[i].diffuse[3]<1;this.vertex=this.transparent?this.data.Vertex.bind(this.data):this.data.vertex.bind(this.data),this.L2norm(this.controlpoints)}setMaterialIndex(){this.transparent?this.setMaterial(transparentData,drawTransparent):this.color?this.setMaterial(colorData,drawColor):this.setMaterial(materialData,drawMaterial)}L2norm(e){let t=e[0];this.epsilon=0;let i=e.length;for(let a=1;a<i;++a)this.epsilon=Math.max(this.epsilon,abs2([e[a][0]-t[0],e[a][1]-t[1],e[!
 a][2]-t[2]]));this.epsilon*=Number.EPSILON}processTriangle(e){let t=e[0],i=e[1],a=e[2],n=unit(cross([i[0]-t[0],i[1]-t[1],i[2]-t[2]],[a[0]-t[0],a[1]-t[1],a[2]-t[2]]));if(!this.offscreen([t,i,a])){let e,r,s;this.color?(e=this.data.Vertex(t,n,this.color[0]),r=this.data.Vertex(i,n,this.color[1]),s=this.data.Vertex(a,n,this.color[2])):(e=this.vertex(t,n),r=this.vertex(i,n),s=this.vertex(a,n)),0==wireframe?(this.data.indices.push(e),this.data.indices.push(r),this.data.indices.push(s)):(this.data.indices.push(e),this.data.indices.push(r),this.data.indices.push(r),this.data.indices.push(s),this.data.indices.push(s),this.data.indices.push(e)),this.append()}}processQuad(e){let t=e[0],i=e[1],a=e[2],n=e[3],r=cross([i[0]-t[0],i[1]-t[1],i[2]-t[2]],[a[0]-i[0],a[1]-i[1],a[2]-i[2]]),s=cross([a[0]-n[0],a[1]-n[1],a[2]-n[2]],[n[0]-t[0],n[1]-t[1],n[2]-t[2]]),o=unit([r[0]+s[0],r[1]+s[1],r[2]+s[2]]);if(!this.offscreen([t,i,a,n])){let e,r,s,l;this.color?(e=this.data.Vertex(t,o,this.color[0]),r=this.data.Vertex(i,o,this.color[1]),s=this.data.Vertex(a,o,this.color[2]),l=this.data.Vertex(n,o,this.color[3])):(e=this.vertex(t,o),r=this.vertex(i,o),s=this.vertex(a,o),l=this.vertex(n,o)),0==wireframe?(this.data.indices.push(e),this.data.indices.push(r),this.data.indices.push(s),this.data.indices.push(e),this.data.indices.push(s),this.data.indices.push(l)):(this.data.indices.push(e),this.data.indices.push(r),this.data.indices.push(r),this.data.indices.push(s),this.data.indices.push(s),this.data.indices.push(l),this.data.indices.push(l),this.data.indices.push(e)),this.append()}}curve(e,t,i,a,n){new BezierCurve([e[t],e[i],e[a],e[n]],0,materialIndex,this.Min,this.Max).render()}process(e){if(this.transparent&&1!=wireframe&&(materialIndex=this.color?-1-materialIndex:1+materialIndex),10==e.length)return this.process3(e);if(3==e.length)return this.processTriangle(e);if(4==e.length)return this.processQuad(e);if(1==wireframe)return this.curve(e,0,4,8,12),this.curve(e,12,13,14,15),this.curve(e,15,11,7,3),void this.curve(e,3,2,1,0);let t=e[0],i=e[3],a=e[!
 12],n=e[15],r=this.normal(i,e[2],e[1],t,e[4],e[8],a);abs2(r)<this.epsilon&&(r=this.normal(i,e[2],e[1],t,e[13],e[14],n),abs2(r)<this.epsilon&&(r=this.normal(n,e[11],e[7],i,e[4],e[8],a)));let s=this.normal(t,e[4],e[8],a,e[13],e[14],n);abs2(s)<this.epsilon&&(s=this.normal(t,e[4],e[8],a,e[11],e[7],i),abs2(s)<this.epsilon&&(s=this.normal(i,e[2],e[1],t,e[13],e[14],n)));let o=this.normal(a,e[13],e[14],n,e[11],e[7],i);abs2(o)<this.epsilon&&(o=this.normal(a,e[13],e[14],n,e[2],e[1],t),abs2(o)<this.epsilon&&(o=this.normal(t,e[4],e[8],a,e[11],e[7],i)));let l=this.normal(n,e[11],e[7],i,e[2],e[1],t);if(abs2(l)<this.epsilon&&(l=this.normal(n,e[11],e[7],i,e[4],e[8],a),abs2(l)<this.epsilon&&(l=this.normal(a,e[13],e[14],n,e[2],e[1],t))),this.color){let h=this.color[0],c=this.color[1],d=this.color[2],m=this.color[3],f=this.data.Vertex(t,r,h),u=this.data.Vertex(a,s,c),p=this.data.Vertex(n,o,d),g=this.data.Vertex(i,l,m);this.Render(e,f,u,p,g,t,a,n,i,!1,!1,!1,!1,h,c,d,m)}else{let h=this.vertex(t,r),c=this.vertex(a,s),d=this.vertex(n,o),m=this.vertex(i,l);this.Render(e,h,c,d,m,t,a,n,i,!1,!1,!1,!1)}this.data.indices.length>0&&this.append()}append(){this.transparent?transparentData.append(this.data):this.color?colorData.append(this.data):materialData.append(this.data)}notRendered(){this.transparent?transparentData.rendered=!1:this.color?colorData.rendered=!1:materialData.rendered=!1}Render(e,t,i,a,n,r,s,o,l,h,c,d,m,f,u,p,g){let v=this.Distance(e);if(v[0]<this.res2&&v[1]<this.res2)this.offscreen([r,s,o])||(0==wireframe?(this.data.indices.push(t),this.data.indices.push(i),this.data.indices.push(a)):(this.data.indices.push(t),this.data.indices.push(i),this.data.indices.push(i),this.data.indices.push(a))),this.offscreen([r,o,l])||(0==wireframe?(this.data.indices.push(t),this.data.indices.push(a),this.data.indices.push(n)):(this.data.indices.push(a),this.data.indices.push(n),this.data.indices.push(n),this.data.indices.push(t)));else{if(this.offscreen(e))return;let x=e[0],w=e[3],M=e[12],b=e[15];if(v[0]<this.res2){let v=new Split3(x,e[1],e[2],!
 w),T=new Split3(e[4],e[5],e[6],e[7]),S=new Split3(e[8],e[9],e[10],e[11]),R=new Split3(M,e[13],e[14],b),A=[x,v.m0,v.m3,v.m5,e[4],T.m0,T.m3,T.m5,e[8],S.m0,S.m3,S.m5,M,R.m0,R.m3,R.m5],I=[v.m5,v.m4,v.m2,w,T.m5,T.m4,T.m2,e[7],S.m5,S.m4,S.m2,e[11],R.m5,R.m4,R.m2,b],P=this.normal(A[12],A[13],A[14],A[15],A[11],A[7],A[3]);abs2(P)<=this.epsilon&&(P=this.normal(A[12],A[13],A[14],A[15],A[2],A[1],A[0]),abs2(P)<=this.epsilon&&(P=this.normal(A[0],A[4],A[8],A[12],A[11],A[7],A[3])));let E=this.normal(I[3],I[2],I[1],I[0],I[4],I[8],I[12]);abs2(E)<=this.epsilon&&(E=this.normal(I[3],I[2],I[1],I[0],I[13],I[14],I[15]),abs2(E)<=this.epsilon&&(E=this.normal(I[15],I[11],I[7],I[3],I[4],I[8],I[12])));let y=this.Epsilon,L=[.5*(s[0]+o[0]),.5*(s[1]+o[1]),.5*(s[2]+o[2])];if(!c)if(c=Straightness(M,e[13],e[14],b)<this.res2){let e=unit(this.differential(I[12],I[8],I[4],I[0]));L=[L[0]-y*e[0],L[1]-y*e[1],L[2]-y*e[2]]}else L=A[15];let D=[.5*(l[0]+r[0]),.5*(l[1]+r[1]),.5*(l[2]+r[2])];if(!m)if(m=Straightness(x,e[1],e[2],w)<this.res2){let e=unit(this.differential(A[3],A[7],A[11],A[15]));D=[D[0]-y*e[0],D[1]-y*e[1],D[2]-y*e[2]]}else D=I[0];if(f){let e=Array(4),v=Array(4);for(let t=0;t<4;++t)e[t]=.5*(u[t]+p[t]),v[t]=.5*(g[t]+f[t]);let x=this.data.Vertex(L,P,e),w=this.data.Vertex(D,E,v);this.Render(A,t,i,x,w,r,s,L,D,h,c,!1,m,f,u,e,v),this.Render(I,w,x,a,n,D,L,o,l,!1,c,d,m,v,e,p,g)}else{let e=this.vertex(L,P),f=this.vertex(D,E);this.Render(A,t,i,e,f,r,s,L,D,h,c,!1,m),this.Render(I,f,e,a,n,D,L,o,l,!1,c,d,m)}return}if(v[1]<this.res2){let v=new Split3(x,e[4],e[8],M),T=new Split3(e[1],e[5],e[9],e[13]),S=new Split3(e[2],e[6],e[10],e[14]),R=new Split3(w,e[7],e[11],b),A=[x,e[1],e[2],w,v.m0,T.m0,S.m0,R.m0,v.m3,T.m3,S.m3,R.m3,v.m5,T.m5,S.m5,R.m5],I=[v.m5,T.m5,S.m5,R.m5,v.m4,T.m4,S.m4,R.m4,v.m2,T.m2,S.m2,R.m2,M,e[13],e[14],b],P=this.normal(A[0],A[4],A[8],A[12],A[13],A[14],A[15]);abs2(P)<=this.epsilon&&(P=this.normal(A[0],A[4],A[8],A[12],A[11],A[7],A[3]),abs2(P)<=this.epsilon&&(P=this.normal(A[3],A[2],A[1],A[0],A[13],A[14],A[15])));let E=this.normal(I[15],I[11],I[7],I!
 [3],I[2],I[1],I[0]);abs2(E)<=this.epsilon&&(E=this.normal(I[15],I[11],I[7],I[3],I[4],I[8],I[12]),abs2(E)<=this.epsilon&&(E=this.normal(I[12],I[13],I[14],I[15],I[2],I[1],I[0])));let y=this.Epsilon,L=[.5*(r[0]+s[0]),.5*(r[1]+s[1]),.5*(r[2]+s[2])];if(!h)if(h=Straightness(x,e[4],e[8],M)<this.res2){let e=unit(this.differential(I[0],I[1],I[2],I[3]));L=[L[0]-y*e[0],L[1]-y*e[1],L[2]-y*e[2]]}else L=A[12];let D=[.5*(o[0]+l[0]),.5*(o[1]+l[1]),.5*(o[2]+l[2])];if(!d)if(d=Straightness(b,e[11],e[7],w)<this.res2){let e=unit(this.differential(A[15],A[14],A[13],A[12]));D=[D[0]-y*e[0],D[1]-y*e[1],D[2]-y*e[2]]}else D=I[3];if(f){let e=Array(4),v=Array(4);for(let t=0;t<4;++t)e[t]=.5*(f[t]+u[t]),v[t]=.5*(p[t]+g[t]);let x=this.data.Vertex(L,P,e),w=this.data.Vertex(D,E,v);this.Render(A,t,x,w,n,r,L,D,l,h,!1,d,m,f,e,v,g),this.Render(I,x,i,a,w,L,s,o,D,h,c,d,!1,e,u,p,v)}else{let e=this.vertex(L,P),f=this.vertex(D,E);this.Render(A,t,e,f,n,r,L,D,l,h,!1,d,m),this.Render(I,e,i,a,f,L,s,o,D,h,c,d,!1)}return}let T=new Split3(x,e[1],e[2],w),S=new Split3(e[4],e[5],e[6],e[7]),R=new Split3(e[8],e[9],e[10],e[11]),A=new Split3(M,e[13],e[14],b),I=new Split3(x,e[4],e[8],M),P=new Split3(T.m0,S.m0,R.m0,A.m0),E=new Split3(T.m3,S.m3,R.m3,A.m3),y=new Split3(T.m5,S.m5,R.m5,A.m5),L=new Split3(T.m4,S.m4,R.m4,A.m4),D=new Split3(T.m2,S.m2,R.m2,A.m2),O=new Split3(w,e[7],e[11],b),B=[x,T.m0,T.m3,T.m5,I.m0,P.m0,E.m0,y.m0,I.m3,P.m3,E.m3,y.m3,I.m5,P.m5,E.m5,y.m5],N=[I.m5,P.m5,E.m5,y.m5,I.m4,P.m4,E.m4,y.m4,I.m2,P.m2,E.m2,y.m2,M,A.m0,A.m3,A.m5],z=[y.m5,L.m5,D.m5,O.m5,y.m4,L.m4,D.m4,O.m4,y.m2,L.m2,D.m2,O.m2,A.m5,A.m4,A.m2,b],_=[T.m5,T.m4,T.m2,w,y.m0,L.m0,D.m0,O.m0,y.m3,L.m3,D.m3,O.m3,y.m5,L.m5,D.m5,O.m5],C=B[15],V=this.normal(B[0],B[4],B[8],B[12],B[13],B[14],B[15]);abs2(V)<this.epsilon&&(V=this.normal(B[0],B[4],B[8],B[12],B[11],B[7],B[3]),abs2(V)<this.epsilon&&(V=this.normal(B[3],B[2],B[1],B[0],B[13],B[14],B[15])));let U=this.normal(N[12],N[13],N[14],N[15],N[11],N[7],N[3]);abs2(U)<this.epsilon&&(U=this.normal(N[12],N[13],N[14],N[15],N[2],N[1],N[0]),abs2(U)<this.epsilon&&(U=!
 this.normal(N[0],N[4],N[8],N[12],N[11],N[7],N[3])));let H=this.normal(z[15],z[11],z[7],z[3],z[2],z[1],z[0]);abs2(H)<this.epsilon&&(H=this.normal(z[15],z[11],z[7],z[3],z[4],z[8],z[12]),abs2(H)<this.epsilon&&(H=this.normal(z[12],z[13],z[14],z[15],z[2],z[1],z[0])));let G=this.normal(_[3],_[2],_[1],_[0],_[4],_[8],_[12]);abs2(G)<this.epsilon&&(G=this.normal(_[3],_[2],_[1],_[0],_[13],_[14],_[15]),abs2(G)<this.epsilon&&(G=this.normal(_[15],_[11],_[7],_[3],_[4],_[8],_[12])));let F=this.normal(z[3],z[2],z[1],C,z[4],z[8],z[12]),W=this.Epsilon,X=[.5*(r[0]+s[0]),.5*(r[1]+s[1]),.5*(r[2]+s[2])];if(!h)if(h=Straightness(x,e[4],e[8],M)<this.res2){let e=unit(this.differential(N[0],N[1],N[2],N[3]));X=[X[0]-W*e[0],X[1]-W*e[1],X[2]-W*e[2]]}else X=B[12];let j=[.5*(s[0]+o[0]),.5*(s[1]+o[1]),.5*(s[2]+o[2])];if(!c)if(c=Straightness(M,e[13],e[14],b)<this.res2){let e=unit(this.differential(z[12],z[8],z[4],z[0]));j=[j[0]-W*e[0],j[1]-W*e[1],j[2]-W*e[2]]}else j=N[15];let Z=[.5*(o[0]+l[0]),.5*(o[1]+l[1]),.5*(o[2]+l[2])];if(!d)if(d=Straightness(b,e[11],e[7],w)<this.res2){let e=unit(this.differential(_[15],_[14],_[13],_[12]));Z=[Z[0]-W*e[0],Z[1]-W*e[1],Z[2]-W*e[2]]}else Z=z[3];let k=[.5*(l[0]+r[0]),.5*(l[1]+r[1]),.5*(l[2]+r[2])];if(!m)if(m=Straightness(x,e[1],e[2],w)<this.res2){let e=unit(this.differential(B[3],B[7],B[11],B[15]));k=[k[0]-W*e[0],k[1]-W*e[1],k[2]-W*e[2]]}else k=_[0];if(f){let e=Array(4),v=Array(4),x=Array(4),w=Array(4),M=Array(4);for(let t=0;t<4;++t)e[t]=.5*(f[t]+u[t]),v[t]=.5*(u[t]+p[t]),x[t]=.5*(p[t]+g[t]),w[t]=.5*(g[t]+f[t]),M[t]=.5*(e[t]+x[t]);let b=this.data.Vertex(X,V,e),T=this.data.Vertex(j,U,v),S=this.data.Vertex(Z,H,x),R=this.data.Vertex(k,G,w),A=this.data.Vertex(C,F,M);this.Render(B,t,b,A,R,r,X,C,k,h,!1,!1,m,f,e,M,w),this.Render(N,b,i,T,A,X,s,j,C,h,c,!1,!1,e,u,v,M),this.Render(z,A,T,a,S,C,j,o,Z,!1,c,d,!1,M,v,p,x),this.Render(_,R,A,S,n,k,C,Z,l,!1,!1,d,m,w,M,x,g)}else{let e=this.vertex(X,V),f=this.vertex(j,U),u=this.vertex(Z,H),p=this.vertex(k,G),g=this.vertex(C,F);this.Render(B,t,e,g,p,r,X,C,k,h,!1,!1,m),this.Render(N,e,!
 i,f,g,X,s,j,C,h,c,!1,!1),this.Render(z,g,f,a,u,C,j,o,Z,!1,c,d,!1),this.Render(_,p,g,u,n,k,C,Z,l,!1,!1,d,m)}}}process3(e){if(1==wireframe)return this.curve(e,0,1,3,6),this.curve(e,6,7,8,9),void this.curve(e,9,5,2,0);let t=e[0],i=e[6],a=e[9],n=this.normal(a,e[5],e[2],t,e[1],e[3],i),r=this.normal(t,e[1],e[3],i,e[7],e[8],a),s=this.normal(i,e[7],e[8],a,e[5],e[2],t);if(this.color){let o=this.color[0],l=this.color[1],h=this.color[2],c=this.data.Vertex(t,n,o),d=this.data.Vertex(i,r,l),m=this.data.Vertex(a,s,h);this.Render3(e,c,d,m,t,i,a,!1,!1,!1,o,l,h)}else{let o=this.vertex(t,n),l=this.vertex(i,r),h=this.vertex(a,s);this.Render3(e,o,l,h,t,i,a,!1,!1,!1)}this.data.indices.length>0&&this.append()}Render3(e,t,i,a,n,r,s,o,l,h,c,d,m){if(this.Distance3(e)<this.res2)this.offscreen([n,r,s])||(0==wireframe?(this.data.indices.push(t),this.data.indices.push(i),this.data.indices.push(a)):(this.data.indices.push(t),this.data.indices.push(i),this.data.indices.push(i),this.data.indices.push(a),this.data.indices.push(a),this.data.indices.push(t)));else{if(this.offscreen(e))return;let f=e[0],u=e[1],p=e[2],g=e[3],v=e[4],x=e[5],w=e[6],M=e[7],b=e[8],T=e[9],S=[.5*(T[0]+x[0]),.5*(T[1]+x[1]),.5*(T[2]+x[2])],R=[.5*(T[0]+b[0]),.5*(T[1]+b[1]),.5*(T[2]+b[2])],A=[.5*(x[0]+p[0]),.5*(x[1]+p[1]),.5*(x[2]+p[2])],I=[.5*(b[0]+v[0]),.5*(b[1]+v[1]),.5*(b[2]+v[2])],P=[.5*(b[0]+M[0]),.5*(b[1]+M[1]),.5*(b[2]+M[2])],E=[.5*(p[0]+v[0]),.5*(p[1]+v[1]),.5*(p[2]+v[2])],y=[.5*(p[0]+f[0]),.5*(p[1]+f[1]),.5*(p[2]+f[2])],L=[.5*(v[0]+g[0]),.5*(v[1]+g[1]),.5*(v[2]+g[2])],D=[.5*(M[0]+w[0]),.5*(M[1]+w[1]),.5*(M[2]+w[2])],O=[.5*(f[0]+u[0]),.5*(f[1]+u[1]),.5*(f[2]+u[2])],B=[.5*(u[0]+g[0]),.5*(u[1]+g[1]),.5*(u[2]+g[2])],N=[.5*(g[0]+w[0]),.5*(g[1]+w[1]),.5*(g[2]+w[2])],z=[.5*(S[0]+A[0]),.5*(S[1]+A[1]),.5*(S[2]+A[2])],_=[.5*(R[0]+P[0]),.5*(R[1]+P[1]),.5*(R[2]+P[2])],C=[.5*(A[0]+y[0]),.5*(A[1]+y[1]),.5*(A[2]+y[2])],V=[.5*I[0]+.25*(v[0]+u[0]),.5*I[1]+.25*(v[1]+u[1]),.5*I[2]+.25*(v[2]+u[2])],U=[.5*(P[0]+D[0]),.5*(P[1]+D[1]),.5*(P[2]+D[2])],H=[.5*E[0]+.25*(v[0]+M[0]),.5*E[1]+.25*(!
 v[1]+M[1]),.5*E[2]+.25*(v[2]+M[2])],G=[.25*(x[0]+v[0])+.5*L[0],.25*(x[1]+v[1])+.5*L[1],.25*(x[2]+v[2])+.5*L[2]],F=[.5*(O[0]+B[0]),.5*(O[1]+B[1]),.5*(O[2]+B[2])],W=[.5*(B[0]+N[0]),.5*(B[1]+N[1]),.5*(B[2]+N[2])],X=[.5*(H[0]+F[0]),.5*(H[1]+F[1]),.5*(H[2]+F[2])],j=[.5*(H[0]+W[0]),.5*(H[1]+W[1]),.5*(H[2]+W[2])],Z=[.5*(F[0]+W[0]),.5*(F[1]+W[1]),.5*(F[2]+W[2])],k=[.5*(G[0]+U[0]),.5*(G[1]+U[1]),.5*(G[2]+U[2])],Y=[.5*(_[0]+G[0]),.5*(_[1]+G[1]),.5*(_[2]+G[2])],q=[.5*(_[0]+U[0]),.5*(_[1]+U[1]),.5*(_[2]+U[2])],$=[.5*(z[0]+V[0]),.5*(z[1]+V[1]),.5*(z[2]+V[2])],K=[.5*(C[0]+V[0]),.5*(C[1]+V[1]),.5*(C[2]+V[2])],Q=[.5*(z[0]+C[0]),.5*(z[1]+C[1]),.5*(z[2]+C[2])],J=[f,O,y,F,[.5*(E[0]+O[0]),.5*(E[1]+O[1]),.5*(E[2]+O[2])],C,Z,X,K,Q],ee=[Z,W,j,N,[.5*(L[0]+D[0]),.5*(L[1]+D[1]),.5*(L[2]+D[2])],k,w,D,U,q],te=[Q,$,z,Y,[.5*(S[0]+I[0]),.5*(S[1]+I[1]),.5*(S[2]+I[2])],S,q,_,R,T],ie=[q,Y,k,$,[.25*(A[0]+P[0]+B[0]+v[0]),.25*(A[1]+P[1]+B[1]+v[1]),.25*(A[2]+P[2]+B[2]+v[2])],j,Q,K,X,Z],ae=this.normal(Z,j,k,q,Y,$,Q),ne=this.normal(q,Y,$,Q,K,X,Z),re=this.normal(Q,K,X,Z,j,k,q),se=this.Epsilon,oe=[.5*(r[0]+s[0]),.5*(r[1]+s[1]),.5*(r[2]+s[2])];if(!o)if(o=Straightness(w,M,b,T)<this.res2){let e=unit(this.sumdifferential(ie[0],ie[2],ie[5],ie[9],ie[1],ie[3],ie[6]));oe=[oe[0]-se*e[0],oe[1]-se*e[1],oe[2]-se*e[2]]}else oe=q;let le=[.5*(s[0]+n[0]),.5*(s[1]+n[1]),.5*(s[2]+n[2])];if(!l)if(l=Straightness(f,p,x,T)<this.res2){let e=unit(this.sumdifferential(ie[6],ie[3],ie[1],ie[0],ie[7],ie[8],ie[9]));le=[le[0]-se*e[0],le[1]-se*e[1],le[2]-se*e[2]]}else le=Q;let he=[.5*(n[0]+r[0]),.5*(n[1]+r[1]),.5*(n[2]+r[2])];if(!h)if(h=Straightness(f,u,g,w)<this.res2){let e=unit(this.sumdifferential(ie[9],ie[8],ie[7],ie[6],ie[5],ie[2],ie[0]));he=[he[0]-se*e[0],he[1]-se*e[1],he[2]-se*e[2]]}else he=Z;if(c){let e=Array(4),f=Array(4),u=Array(4);for(let t=0;t<4;++t)e[t]=.5*(d[t]+m[t]),f[t]=.5*(m[t]+c[t]),u[t]=.5*(c[t]+d[t]);let p=this.data.Vertex(oe,ae,e),g=this.data.Vertex(le,ne,f),v=this.data.Vertex(he,re,u);this.Render3(J,t,v,g,n,he,le,!1,l,h,c,u,f),this.Render3(ee,v,i,p,he,r,oe,o,!1,!
 h,u,d,e),this.Render3(te,g,p,a,le,oe,s,o,l,!1,f,e,m),this.Render3(ie,p,g,v,oe,le,he,!1,!1,!1,e,f,u)}else{let e=this.vertex(oe,ae),c=this.vertex(le,ne),d=this.vertex(he,re);this.Render3(J,t,d,c,n,he,le,!1,l,h),this.Render3(ee,d,i,e,he,r,oe,o,!1,h),this.Render3(te,c,e,a,le,oe,s,o,l,!1),this.Render3(ie,e,c,d,oe,le,he,!1,!1,!1)}}}Distance(e){let t=e[0],i=e[3],a=e[12],n=e[15],r=Flatness(t,a,i,n);r=Math.max(Straightness(t,e[4],e[8],a)),r=Math.max(r,Straightness(e[1],e[5],e[9],e[13])),r=Math.max(r,Straightness(i,e[7],e[11],n)),r=Math.max(r,Straightness(e[2],e[6],e[10],e[14]));let s=Flatness(t,i,a,n);return s=Math.max(s,Straightness(t,e[1],e[2],i)),s=Math.max(s,Straightness(e[4],e[5],e[6],e[7])),s=Math.max(s,Straightness(e[8],e[9],e[10],e[11])),s=Math.max(s,Straightness(a,e[13],e[14],n)),[r,s]}Distance3(e){let t=e[0],i=e[4],a=e[6],n=e[9],r=abs2([(t[0]+a[0]+n[0])*(1/3)-i[0],(t[1]+a[1]+n[1])*(1/3)-i[1],(t[2]+a[2]+n[2])*(1/3)-i[2]]);return r=Math.max(r,Straightness(t,e[1],e[3],a)),r=Math.max(r,Straightness(t,e[2],e[5],n)),Math.max(r,Straightness(a,e[7],e[8],n))}differential(e,t,i,a){let n=[3*(t[0]-e[0]),3*(t[1]-e[1]),3*(t[2]-e[2])];return abs2(n)>this.epsilon?n:(n=bezierPP(e,t,i),abs2(n)>this.epsilon?n:bezierPPP(e,t,i,a))}sumdifferential(e,t,i,a,n,r,s){let o=this.differential(e,t,i,a),l=this.differential(e,n,r,s);return[o[0]+l[0],o[1]+l[1],o[2]+l[2]]}normal(e,t,i,a,n,r,s){let o=3*(n[0]-a[0]),l=3*(n[1]-a[1]),h=3*(n[2]-a[2]),c=3*(i[0]-a[0]),d=3*(i[1]-a[1]),m=3*(i[2]-a[2]),f=[l*m-h*d,h*c-o*m,o*d-l*c];if(abs2(f)>this.epsilon)return f;let u=[c,d,m],p=[o,l,h],g=bezierPP(a,i,t),v=bezierPP(a,n,r),x=cross(v,u),w=cross(p,g);if(f=[x[0]+w[0],x[1]+w[1],x[2]+w[2]],abs2(f)>this.epsilon)return f;let M=bezierPPP(a,i,t,e),b=bezierPPP(a,n,r,s);x=cross(p,M),w=cross(b,u);let T=cross(v,g);return f=[x[0]+w[0]+T[0],x[1]+w[1]+T[1],x[2]+w[2]+T[2]],abs2(f)>this.epsilon?f:(x=cross(b,g),w=cross(v,M),f=[x[0]+w[0],x[1]+w[1],x[2]+w[2]],abs2(f)>this.epsilon?f:cross(b,M))}}class BezierCurve extends Geometry{constructor(e,t,i,a,n){super(),this.controlpoints!
 =e,this.CenterIndex=t,this.MaterialIndex=i,this.Min=a,this.Max=n}setMaterialIndex(){this.setMaterial(material1Data,drawMaterial1)}processLine(e){let t=e[0],i=e[1];if(!this.offscreen([t,i])){let e=[0,0,1];this.data.indices.push(this.data.vertex(t,e)),this.data.indices.push(this.data.vertex(i,e)),this.append()}}process(e){if(2==e.length)return this.processLine(e);let t=e[0],i=e[1],a=e[2],n=e[3],r=this.normal(bezierP(t,i),bezierPP(t,i,a)),s=this.normal(bezierP(a,n),bezierPP(n,a,i)),o=this.data.vertex(t,r),l=this.data.vertex(n,s);this.Render(e,o,l),this.data.indices.length>0&&this.append()}append(){material1Data.append(this.data)}notRendered(){material1Data.rendered=!1}Render(e,t,i){let a=e[0],n=e[1],r=e[2],s=e[3];if(Straightness(a,n,r,s)<this.res2)this.offscreen([a,s])||(this.data.indices.push(t),this.data.indices.push(i));else{if(this.offscreen(e))return;let o=[.5*(a[0]+n[0]),.5*(a[1]+n[1]),.5*(a[2]+n[2])],l=[.5*(n[0]+r[0]),.5*(n[1]+r[1]),.5*(n[2]+r[2])],h=[.5*(r[0]+s[0]),.5*(r[1]+s[1]),.5*(r[2]+s[2])],c=[.5*(o[0]+l[0]),.5*(o[1]+l[1]),.5*(o[2]+l[2])],d=[.5*(l[0]+h[0]),.5*(l[1]+h[1]),.5*(l[2]+h[2])],m=[.5*(c[0]+d[0]),.5*(c[1]+d[1]),.5*(c[2]+d[2])],f=[a,o,c,m],u=[m,d,h,s],p=this.normal(bezierPh(a,n,r,s),bezierPPh(a,n,r,s)),g=this.data.vertex(m,p);this.Render(f,t,g),this.Render(u,g,i)}}normal(e,t){let i=dot(e,e),a=dot(e,t);return[i*t[0]-a*e[0],i*t[1]-a*e[1],i*t[2]-a*e[2]]}}class Pixel extends Geometry{constructor(e,t,i,a,n){super(),this.controlpoint=e,this.width=t,this.CenterIndex=0,this.MaterialIndex=i,this.Min=a,this.Max=n}setMaterialIndex(){this.setMaterial(material0Data,drawMaterial0)}process(e){this.data.indices.push(this.data.vertex0(this.controlpoint,this.width)),this.append()}append(){material0Data.append(this.data)}notRendered(){material0Data.rendered=!1}}class Triangles extends Geometry{constructor(e,t,i,a){super(),this.CenterIndex=e,this.MaterialIndex=t,this.Min=i,this.Max=a,this.controlpoints=Positions,this.Normals=Normals,this.Colors=Colors,this.Indices=Indices,Positions=[],Normals=[],Colors=[],Indices=[!
 ],this.transparent=Materials[this.MaterialIndex].diffuse[3]<1}setMaterialIndex(){this.transparent?this.setMaterial(transparentData,drawTransparent):this.setMaterial(triangleData,drawTriangle)}process(e){this.data.vertices=new Array(6*e.length),materialIndex=this.Colors.length>0?-1-materialIndex:1+materialIndex;for(let t=0,i=this.Indices.length;t<i;++t){let i=this.Indices[t],a=i[0],n=e[a[0]],r=e[a[1]],s=e[a[2]];if(!this.offscreen([n,r,s])){let e=i.length>1?i[1]:a;if(e&&0!=e.length||(e=a),this.Colors.length>0){let t=i.length>2?i[2]:a;t&&0!=t.length||(t=a);let o=this.Colors[t[0]],l=this.Colors[t[1]],h=this.Colors[t[2]];this.transparent|=o[3]+l[3]+h[3]<765,0==wireframe?(this.data.iVertex(a[0],n,this.Normals[e[0]],o),this.data.iVertex(a[1],r,this.Normals[e[1]],l),this.data.iVertex(a[2],s,this.Normals[e[2]],h)):(this.data.iVertex(a[0],n,this.Normals[e[0]],o),this.data.iVertex(a[1],r,this.Normals[e[1]],l),this.data.iVertex(a[1],r,this.Normals[e[1]],l),this.data.iVertex(a[2],s,this.Normals[e[2]],h),this.data.iVertex(a[2],s,this.Normals[e[2]],h),this.data.iVertex(a[0],n,this.Normals[e[0]],o))}else 0==wireframe?(this.data.iVertex(a[0],n,this.Normals[e[0]]),this.data.iVertex(a[1],r,this.Normals[e[1]]),this.data.iVertex(a[2],s,this.Normals[e[2]])):(this.data.iVertex(a[0],n,this.Normals[e[0]]),this.data.iVertex(a[1],r,this.Normals[e[1]]),this.data.iVertex(a[1],r,this.Normals[e[1]]),this.data.iVertex(a[2],s,this.Normals[e[2]]),this.data.iVertex(a[2],s,this.Normals[e[2]]),this.data.iVertex(a[0],n,this.Normals[e[0]]))}}this.data.nvertices=e.length,this.data.indices.length>0&&this.append()}append(){this.transparent?transparentData.append(this.data):triangleData.append(this.data)}notRendered(){this.transparent?transparentData.rendered=!1:triangleData.rendered=!1}}function redrawScene(){initProjection(),setProjection(),remesh=!0,drawScene()}function home(){mat4.identity(rotMat),redrawScene(),window.top.asyWebApplication&&window.top.asyWebApplication.setProjection(""),window.parent.asyProjection=!1}let positionAttribute=0,normalAtt!
 ribute=1,materialAttribute=2,colorAttribute=3,widthAttribute=4;function initShader(e=[]){let t=getShader(gl,vertex,gl.VERTEX_SHADER,e),i=getShader(gl,fragment,gl.FRAGMENT_SHADER,e),a=gl.createProgram();return gl.attachShader(a,t),gl.attachShader(a,i),gl.bindAttribLocation(a,positionAttribute,"position"),gl.bindAttribLocation(a,normalAttribute,"normal"),gl.bindAttribLocation(a,materialAttribute,"materialIndex"),gl.bindAttribLocation(a,colorAttribute,"color"),gl.bindAttribLocation(a,widthAttribute,"width"),gl.linkProgram(a),gl.getProgramParameter(a,gl.LINK_STATUS)||alert("Could not initialize shaders"),a}class Split3{constructor(e,t,i,a){this.m0=[.5*(e[0]+t[0]),.5*(e[1]+t[1]),.5*(e[2]+t[2])];let n=.5*(t[0]+i[0]),r=.5*(t[1]+i[1]),s=.5*(t[2]+i[2]);this.m2=[.5*(i[0]+a[0]),.5*(i[1]+a[1]),.5*(i[2]+a[2])],this.m3=[.5*(this.m0[0]+n),.5*(this.m0[1]+r),.5*(this.m0[2]+s)],this.m4=[.5*(n+this.m2[0]),.5*(r+this.m2[1]),.5*(s+this.m2[2])],this.m5=[.5*(this.m3[0]+this.m4[0]),.5*(this.m3[1]+this.m4[1]),.5*(this.m3[2]+this.m4[2])]}}function unit(e){let t=1/(Math.sqrt(e[0]*e[0]+e[1]*e[1]+e[2]*e[2])||1);return[e[0]*t,e[1]*t,e[2]*t]}function abs2(e){return e[0]*e[0]+e[1]*e[1]+e[2]*e[2]}function dot(e,t){return e[0]*t[0]+e[1]*t[1]+e[2]*t[2]}function cross(e,t){return[e[1]*t[2]-e[2]*t[1],e[2]*t[0]-e[0]*t[2],e[0]*t[1]-e[1]*t[0]]}function bezierP(e,t){return[t[0]-e[0],t[1]-e[1],t[2]-e[2]]}function bezierPP(e,t,i){return[3*(e[0]+i[0])-6*t[0],3*(e[1]+i[1])-6*t[1],3*(e[2]+i[2])-6*t[2]]}function bezierPPP(e,t,i,a){return[a[0]-e[0]+3*(t[0]-i[0]),a[1]-e[1]+3*(t[1]-i[1]),a[2]-e[2]+3*(t[2]-i[2])]}function bezierPh(e,t,i,a){return[i[0]+a[0]-e[0]-t[0],i[1]+a[1]-e[1]-t[1],i[2]+a[2]-e[2]-t[2]]}function bezierPPh(e,t,i,a){return[3*e[0]-5*t[0]+i[0]+a[0],3*e[1]-5*t[1]+i[1]+a[1],3*e[2]-5*t[2]+i[2]+a[2]]}function Straightness(e,t,i,a){let n=[1/3*(a[0]-e[0]),1/3*(a[1]-e[1]),1/3*(a[2]-e[2])];return Math.max(abs2([t[0]-n[0]-e[0],t[1]-n[1]-e[1],t[2]-n[2]-e[2]]),abs2([a[0]-n[0]-i[0],a[1]-n[1]-i[1],a[2]-n[2]-i[2]]))}function Flatness(e,t,i,a){let n=[t[0]-e[0],!
 t[1]-e[1],t[2]-e[2]],r=[a[0]-i[0],a[1]-i[1],a[2]-i[2]];return Math.max(abs2(cross(n,unit(r))),abs2(cross(r,unit(n))))/9}function corners(e,t){return[e,[e[0],e[1],t[2]],[e[0],t[1],e[2]],[e[0],t[1],t[2]],[t[0],e[1],e[2]],[t[0],e[1],t[2]],[t[0],t[1],e[2]],t]}function minbound(e){return[Math.min(e[0][0],e[1][0],e[2][0],e[3][0],e[4][0],e[5][0],e[6][0],e[7][0]),Math.min(e[0][1],e[1][1],e[2][1],e[3][1],e[4][1],e[5][1],e[6][1],e[7][1]),Math.min(e[0][2],e[1][2],e[2][2],e[3][2],e[4][2],e[5][2],e[6][2],e[7][2])]}function maxbound(e){return[Math.max(e[0][0],e[1][0],e[2][0],e[3][0],e[4][0],e[5][0],e[6][0],e[7][0]),Math.max(e[0][1],e[1][1],e[2][1],e[3][1],e[4][1],e[5][1],e[6][1],e[7][1]),Math.max(e[0][2],e[1][2],e[2][2],e[3][2],e[4][2],e[5][2],e[6][2],e[7][2])]}function COBTarget(e,t){mat4.fromTranslation(Temp,[center.x,center.y,center.z]),mat4.invert(cjMatInv,Temp),mat4.multiply(e,t,cjMatInv),mat4.multiply(e,Temp,e)}function setUniforms(e,t){let i=t==pixelShader;gl.useProgram(t),gl.enableVertexAttribArray(positionAttribute),i&&gl.enableVertexAttribArray(widthAttribute);let a=!i&&Lights.length>0;if(a&&gl.enableVertexAttribArray(normalAttribute),gl.enableVertexAttribArray(materialAttribute),t.projViewMatUniform=gl.getUniformLocation(t,"projViewMat"),t.viewMatUniform=gl.getUniformLocation(t,"viewMat"),t.normMatUniform=gl.getUniformLocation(t,"normMat"),t!=colorShader&&t!=transparentShader||gl.enableVertexAttribArray(colorAttribute),a)for(let e=0;e<Lights.length;++e)Lights[e].setUniform(t,e);for(let i=0;i<e.materials.length;++i)e.materials[i].setUniform(t,i);gl.uniformMatrix4fv(t.projViewMatUniform,!1,projViewMat),gl.uniformMatrix4fv(t.viewMatUniform,!1,viewMat),gl.uniformMatrix3fv(t.normMatUniform,!1,normMat)}function handleMouseDown(e){zoomEnabled||enableZoom(),mouseDownOrTouchActive=!0,lastMouseX=e.clientX,lastMouseY=e.clientY}let pinchStart,touchStartTime,pinch=!1;function pinchDistance(e){return Math.hypot(e[0].pageX-e[1].pageX,e[0].pageY-e[1].pageY)}function handleTouchStart(e){e.preventDefault(),zoomEnabled||enableZoom();!
 let t=e.targetTouches;swipe=rotate=pinch=!1,zooming||(1!=t.length||mouseDownOrTouchActive||(touchStartTime=(new Date).getTime(),touchId=t[0].identifier,lastMouseX=t[0].pageX,lastMouseY=t[0].pageY),2!=t.length||mouseDownOrTouchActive||(touchId=t[0].identifier,pinchStart=pinchDistance(t),pinch=!0))}function handleMouseUpOrTouchEnd(e){mouseDownOrTouchActive=!1}function rotateScene(e,t,i,a,n){if(e==i&&t==a)return;let[r,s]=arcball([e,-t],[i,-a]);mat4.fromRotation(Temp,2*n*ArcballFactor*r/Zoom,s),mat4.multiply(rotMat,Temp,rotMat)}function shiftScene(e,t,i,a){let n=1/Zoom;shift.x+=(i-e)*n*halfCanvasWidth,shift.y-=(a-t)*n*halfCanvasHeight}function panScene(e,t,i,a){orthographic?shiftScene(e,t,i,a):(center.x+=(i-e)*(viewParam.xmax-viewParam.xmin),center.y-=(a-t)*(viewParam.ymax-viewParam.ymin))}function updateViewMatrix(){COBTarget(viewMat,rotMat),mat4.translate(viewMat,viewMat,[center.x,center.y,0]),mat3.fromMat4(viewMat3,viewMat),mat3.invert(normMat,viewMat3),mat4.multiply(projViewMat,projMat,viewMat)}function capzoom(){let e=Math.sqrt(Number.MAX_VALUE),t=1/e;Zoom<=t&&(Zoom=t),Zoom>=e&&(Zoom=e),(1.5*Zoom<lastZoom||Zoom>1.5*lastZoom)&&(remesh=!0,lastZoom=Zoom)}function zoomImage(e){let t=zoomStep*halfCanvasHeight*e;const i=Math.log(.1*Number.MAX_VALUE)/Math.log(zoomFactor);Math.abs(t)<i&&(Zoom*=zoomFactor**t,capzoom())}function normMouse(e){let t=e[0],i=e[1],a=Math.hypot(t,i);return a>1&&(denom=1/a,t*=denom,i*=denom),[t,i,Math.sqrt(Math.max(1-i*i-t*t,0))]}function arcball(e,t){let i=normMouse(e),a=normMouse(t),n=dot(i,a);return[n>1?0:n<-1?pi:Math.acos(n),unit(cross(i,a))]}function zoomScene(e,t,i,a){zoomImage(t-a)}const DRAGMODE_ROTATE=1,DRAGMODE_SHIFT=2,DRAGMODE_ZOOM=3,DRAGMODE_PAN=4;function processDrag(e,t,i,a=1){let n;switch(i){case 1:n=rotateScene;break;case 2:n=shiftScene;break;case 3:n=zoomScene;break;case 4:n=panScene;break;default:n=(e,t,i,a)=>{}}n((lastMouseX-halfCanvasWidth)/halfCanvasWidth,(lastMouseY-halfCanvasHeight)/halfCanvasHeight,(e-halfCanvasWidth)/halfCanvasWidth,(t-halfCanvasHeight)/halfCanvasHeight!
 ,a),lastMouseX=e,lastMouseY=t,setProjection(),drawScene()}let zoomEnabled=0;function enableZoom(){zoomEnabled=1,canvas.addEventListener("wheel",handleMouseWheel,!1)}function disableZoom(){zoomEnabled=0,canvas.removeEventListener("wheel",handleMouseWheel,!1)}function Camera(){let e=Array(3),t=Array(3),i=Array(3),a=center.x,n=center.y,r=.5*(viewParam.zmin+viewParam.zmax);for(let s=0;s<3;++s){let o=0,l=0,h=0,c=4*s;for(let e=0;e<4;++e){let t=4*e,i=rotMat[t],s=rotMat[t+1],d=rotMat[t+2],m=rotMat[t+3],f=Transform[c+e];o+=f*(m-a*i-n*s-r*d),h+=f*s,l+=f*(m-a*i-n*s)}e[s]=o,t[s]=h,i[s]=l}return[e,t,i]}function projection(){if(null==Transform)return"";let e,t,i;[e,t,i]=Camera();let a=orthographic?"  orthographic(":"  perspective(",n="".padStart(a.length),r="currentprojection=\n"+a+"camera=("+e+"),\n"+n+"up=("+t+"),\n"+n+"target=("+i+"),\n"+n+"zoom="+Zoom*initialZoom/zoom0;return orthographic||(r+=",\n"+n+"angle="+2*Math.atan(Math.tan(.5*angleOfView)/Zoom)/radians),0==xshift&&0==yshift||(r+=",\n"+n+"viewportshift=("+xshift+","+yshift+")"),orthographic||(r+=",\n"+n+"autoadjust=false"),r+=");\n",window.parent.asyProjection=!0,r}function handleKey(e){if(zoomEnabled||enableZoom(),embedded&&zoomEnabled&&27==e.keyCode)return void disableZoom();let t=[];switch(e.key){case"x":t=[1,0,0];break;case"y":t=[0,1,0];break;case"z":t=[0,0,1];break;case"h":home();break;case"m":++wireframe,3==wireframe&&(wireframe=0),2!=wireframe&&(embedded||deleteShaders(),initShaders(ibl)),remesh=!0,drawScene();break;case"+":case"=":case">":expand();break;case"-":case"_":case"<":shrink();break;case"c":showCamera()}t.length>0&&(mat4.rotate(rotMat,rotMat,.1,t),updateViewMatrix(),drawScene())}function setZoom(){capzoom(),setProjection(),drawScene()}function handleMouseWheel(e){e.preventDefault(),e.deltaY<0?Zoom*=zoomFactor:Zoom/=zoomFactor,setZoom()}function handleMouseMove(e){if(!mouseDownOrTouchActive)return;let t,i=e.clientX,a=e.clientY;t=e.getModifierState("Control")?2:e.getModifierState("Shift")?3:e.getModifierState("Alt")?4:1,processDrag(i,a,t)}let zooming!
 =!1,swipe=!1,rotate=!1;function handleTouchMove(e){if(e.preventDefault(),zooming)return;let t=e.targetTouches;if(!pinch&&1==t.length&&touchId==t[0].identifier){let e=t[0].pageX,i=t[0].pageY,a=e-lastMouseX,n=i-lastMouseY,r=a*a+n*n<=shiftHoldDistance*shiftHoldDistance;if(r&&!swipe&&!rotate&&(new Date).getTime()-touchStartTime>shiftWaitTime&&(navigator.vibrate&&window.navigator.vibrate(vibrateTime),swipe=!0),swipe)processDrag(e,i,2);else if(!r){rotate=!0,processDrag(t[0].pageX,t[0].pageY,1,.5)}}if(pinch&&!swipe&&2==t.length&&touchId==t[0].identifier){let e=pinchDistance(t),i=e-pinchStart;zooming=!0,i*=zoomPinchFactor,i>zoomPinchCap&&(i=zoomPinchCap),i<-zoomPinchCap&&(i=-zoomPinchCap),zoomImage(i/size2),pinchStart=e,swipe=rotate=zooming=!1,setProjection(),drawScene()}}let pixelShader,materialShader,colorShader,transparentShader,zbuffer=[];function transformVertices(e){let t=viewMat[2],i=viewMat[6],a=viewMat[10];zbuffer.length=e.length;for(let n=0;n<e.length;++n){let r=6*n;zbuffer[n]=t*e[r]+i*e[r+1]+a*e[r+2]}}function drawMaterial0(){drawBuffer(material0Data,pixelShader),material0Data.clear()}function drawMaterial1(){drawBuffer(material1Data,materialShader),material1Data.clear()}function drawMaterial(){drawBuffer(materialData,materialShader),materialData.clear()}function drawColor(){drawBuffer(colorData,colorShader),colorData.clear()}function drawTriangle(){drawBuffer(triangleData,transparentShader),triangleData.rendered=!1,triangleData.clear()}function drawTransparent(){let e=transparentData.indices;if(wireframe>0)return drawBuffer(transparentData,transparentShader,e),void transparentData.clear();if(e.length>0){transformVertices(transparentData.vertices);let t=e.length/3,i=Array(t).fill().map((e,t)=>t);i.sort((function(t,i){let a=3*t;Ia=e[a],Ib=e[a+1],Ic=e[a+2];let n=3*i;return IA=e[n],IB=e[n+1],IC=e[n+2],zbuffer[Ia]+zbuffer[Ib]+zbuffer[Ic]<zbuffer[IA]+zbuffer[IB]+zbuffer[IC]?-1:1}));let a=Array(e.length);for(let n=0;n<t;++n){let t=3*i[n];a[3*n]=e[t],a[3*n+1]=e[t+1],a[3*n+2]=e[t+2]}gl.depthMask(!1),drawBuffer(transp!
 arentData,transparentShader,a),transparentData.rendered=!1,gl.depthMask(!0)}transparentData.clear()}function drawBuffers(){drawMaterial0(),drawMaterial1(),drawMaterial(),drawColor(),drawTriangle(),drawTransparent(),requestAnimationFrame(drawBuffers)}function drawScene(){embedded&&(offscreen.width=canvasWidth,offscreen.height=canvasHeight,setViewport()),gl.clearColor(Background[0],Background[1],Background[2],Background[3]),gl.clear(gl.COLOR_BUFFER_BIT|gl.DEPTH_BUFFER_BIT);for(let e=0;e<P.length;++e)P[e].render();drawBuffers(),embedded&&(context.clearRect(0,0,canvasWidth,canvasHeight),context.drawImage(offscreen,0,0)),0==wireframe&&(remesh=!1)}function setDimensions(e,t,i,a){let n=e/t;xshift=(i/e+viewportShift[0])*Zoom,yshift=(a/t+viewportShift[1])*Zoom;let r=1/Zoom;if(orthographic){let e=maxBound[0]-minBound[0],t=maxBound[1]-minBound[1];if(e<t*n){let e=.5*t*n*r,i=2*e*xshift,a=t*r*yshift;viewParam.xmin=-e-i,viewParam.xmax=e-i,viewParam.ymin=minBound[1]*r-a,viewParam.ymax=maxBound[1]*r-a}else{let t=.5*e*r/n,i=e*r*xshift,a=2*t*yshift;viewParam.xmin=minBound[0]*r-i,viewParam.xmax=maxBound[0]*r-i,viewParam.ymin=-t-a,viewParam.ymax=t-a}}else{let e=H*r,t=e*n,i=2*t*xshift,a=2*e*yshift;viewParam.xmin=-t-i,viewParam.xmax=t-i,viewParam.ymin=-e-a,viewParam.ymax=e-a}}function setProjection(){setDimensions(canvasWidth,canvasHeight,shift.x,shift.y),(orthographic?mat4.ortho:mat4.frustum)(projMat,viewParam.xmin,viewParam.xmax,viewParam.ymin,viewParam.ymax,-viewParam.zmax,-viewParam.zmin),updateViewMatrix(),window.top.asyWebApplication&&window.top.asyWebApplication.setProjection(projection())}function showCamera(){window.top.asyWebApplication||prompt("Ctrl+c Enter to copy currentprojection to clipboard; then append to asy file:",projection())}function initProjection(){H=-Math.tan(.5*angleOfView)*maxBound[2],center.x=center.y=0,center.z=.5*(minBound[2]+maxBound[2]),lastZoom=Zoom=zoom0,viewParam.zmin=minBound[2],viewParam.zmax=maxBound[2],shift.x=shift.y=0}function setViewport(){gl.viewportWidth=canvasWidth,gl.viewportHeight=canvasH!
 eight,gl..viewport(.5*(canvas.width-canvasWidth),.5*(canvas.height-canvasHeight),canvasWidth,canvasHeight),gl.scissor(0,0,canvas.width,canvas.height)}function setCanvas(){embedded&&(canvas.width=offscreen.width=canvasWidth,canvas.height=offscreen.height=canvasHeight),size2=Math.hypot(canvasWidth,canvasHeight),halfCanvasWidth=.5*canvas.width,halfCanvasHeight=.5*canvas.height,ArcballFactor=1+8*Math.hypot(viewportMargin[0],viewportMargin[1])/size2}function setsize(e,t){e>maxViewportWidth&&(e=maxViewportWidth),t>maxViewportHeight&&(t=maxViewportHeight),shift.x*=e/canvasWidth,shift.y*=t/canvasHeight,canvasWidth=e,canvasHeight=t,setCanvas(),setViewport(),setProjection(),remesh=!0}function resize(){if(zoom0=initialZoom,window.top.asyWebApplication&&""==window.top.asyWebApplication.getProjection()&&(window.parent.asyProjection=!1),absolute&&!embedded)canvasWidth=canvasWidth0*window.devicePixelRatio,canvasHeight=canvasHeight0*window.devicePixelRatio;else{let e=canvasWidth0/canvasHeight0;canvasWidth=Math.max(window.innerWidth-10,10),canvasHeight=Math.max(window.innerHeight-10,10),!orthographic&&!window.parent.asyProjection&&canvasWidth<canvasHeight*e&&(zoom0*=canvasWidth/(canvasHeight*e))}canvas.width=canvasWidth,canvas.height=canvasHeight;window.innerWidth,window.innerHeight;let e=1/zoom0;viewportShift[0]*=e,viewportShift[1]*=e,setsize(canvasWidth,canvasHeight),redrawScene()}function expand(){Zoom*=zoomFactor,setZoom()}function shrink(){Zoom/=zoomFactor,setZoom()}class Align{constructor(e,t){if(this.center=e,t){let e=t[0],i=t[1];this.ct=Math.cos(e),this.st=Math.sin(e),this.cp=Math.cos(i),this.sp=Math.sin(i)}}T0(e){return[e[0]+this.center[0],e[1]+this.center[1],e[2]+this.center[2]]}T(e){let t=e[0],i=e[1],a=e[2],n=t*this.ct+a*this.st;return[n*this.cp-i*this.sp+this.center[0],n*this.sp+i*this.cp+this.center[1],-t*this.st+a*this.ct+this.center[2]]}}function Tcorners(e,t,i){let a=[e(t),e([t[0],t[1],i[2]]),e([t[0],i[1],t[2]]),e([t[0],i[1],i[2]]),e([i[0],t[1],t[2]]),e([i[0],t[1],i[2]]),e([i[0],i[1],t[2]]),e(i)];return[minbound(a!
 ),maxbound(a)]}function material(e,t,i,a,n,r){Materials.push(new Material(e,t,i,a,n,r))}function patch(e,t,i,a,n,r){P.push(new BezierPatch(e,t,i,a,n,r))}function curve(e,t,i,a,n){P.push(new BezierCurve(e,t,i,a,n))}function pixel(e,t,i,a,n){P.push(new Pixel(e,t,i,a,n))}function triangles(e,t,i,a){P.push(new Triangles(e,t,i,a))}function sphere(e,t,i,n,r){let s,o,l,h,c,d,m=.524670512339254,f=.595936986722291,u=.954967051233925,p=.0820155480083437,g=.996685028842544,v=.0549670512339254,x=.998880711874577,w=.0405017186586849,M=[[[1,0,0],[1,0,m],[f,0,u],[p,0,g],[1,a,0],[1,a,m],[f,a*f,u],[p,a*p,g],[a,1,0],[a,1,m],[a*f,f,u],[a*p,p,g],[0,1,0],[0,1,m],[0,f,u],[0,p,g]],[[p,0,g],[p,a*p,g],[v,0,x],[a*p,p,g],[w,w,1],[.05*a,0,1],[0,p,g],[0,v,x],[0,.05*a,1],[0,0,1]]],b=new Align(e,r);function T(e){let t=Array(e.length);for(let i=0;i<e.length;++i){let a=e[i];t[i]=c([s*a[0],o*a[1],l*a[2]])}return t}r?(h=1,d=0,c=b.T.bind(b)):(h=-1,d=-t,c=b.T0.bind(b));let S=Tcorners(c,[-t,-t,d],[t,t,t]),R=S[0],A=S[1];for(let e=-1;e<=1;e+=2){s=e*t;for(let e=-1;e<=1;e+=2){o=e*t;for(let e=h;e<=1;e+=2){l=e*t;for(let e=0;e<2;++e)P.push(new BezierPatch(T(M[e]),i,n,R,A))}}}}let a=4/3*(Math.sqrt(2)-1);function disk(e,t,i,n,r){let s=1-2*a/3,o=[[1,0,0],[1,-a,0],[a,-1,0],[0,-1,0],[1,a,0],[s,0,0],[0,-s,0],[-a,-1,0],[a,1,0],[0,s,0],[-s,0,0],[-1,-a,0],[0,1,0],[-a,1,0],[-1,a,0],[-1,0,0]],l=new Align(e,r);let h=Tcorners(l.T.bind(l),[-t,-t,0],[t,t,0]);P.push(new BezierPatch(function(e){let i=Array(e.length);for(let a=0;a<e.length;++a){let n=e[a];i[a]=l.T([t*n[0],t*n[1],0])}return i}(o),i,n,h[0],h[1]))}function cylinder(e,t,i,n,r,s,o){let l,h,c=[[1,0,0],[1,0,1/3],[1,0,2/3],[1,0,1],[1,a,0],[1,a,1/3],[1,a,2/3],[1,a,1],[a,1,0],[a,1,1/3],[a,1,2/3],[a,1,1],[0,1,0],[0,1,1/3],[0,1,2/3],[0,1,1]],d=new Align(e,s);function m(e){let t=Array(e.length);for(let a=0;a<e.length;++a){let n=e[a];t[a]=d.T([l*n[0],h*n[1],i*n[2]])}return t}let f=Tcorners(d.T.bind(d),[-t,-t,0],[t,t,i]),u=f[0],p=f[1];for(let e=-1;e<=1;e+=2){l=e*t;for(let e=-1;e<=1;e+=2)h=e*t,P.push(new BezierPatch(m(c),n!
 ,r,u,p))}if(o){let t=d.T([0,0,i]);P.push(new BezierCurve([e,t],n,r,e,t))}}function rmf(e,t,i,a,n){class r{constructor(e,t,i){this.p=e,this.r=t,this.t=i,this.s=cross(i,t)}}let s=Number.EPSILON*Math.max(abs2(e),abs2(t),abs2(i),abs2(a));function o(n){if(1==n){let n=[a[0]-i[0],a[1]-i[1],a[2]-i[2]];return abs2(n)>s?unit(n):(n=[2*i[0]-t[0]-a[0],2*i[1]-t[1]-a[1],2*i[2]-t[2]-a[2]],abs2(n)>s?unit(n):[a[0]-e[0]+3*(t[0]-i[0]),a[1]-e[1]+3*(t[1]-i[1]),a[2]-e[2]+3*(t[2]-i[2])])}let r=[a[0]-e[0]+3*(t[0]-i[0]),a[1]-e[1]+3*(t[1]-i[1]),a[2]-e[2]+3*(t[2]-i[2])],o=[2*(e[0]+i[0])-4*t[0],2*(e[1]+i[1])-4*t[1],2*(e[2]+i[2])-4*t[2]],l=[t[0]-e[0],t[1]-e[1],t[2]-e[2]],h=n*n,c=[r[0]*h+o[0]*n+l[0],r[1]*h+o[1]*n+l[1],r[2]*h+o[2]*n+l[2]];return abs2(c)>s?unit(c):(h=2*n,c=[r[0]*h+o[0],r[1]*h+o[1],r[2]*h+o[2]],abs2(c)>s?unit(c):unit(r))}let l=Array(n.length),h=[t[0]-e[0],t[1]-e[1],t[2]-e[2]];abs2(h)<s&&(h=[e[0]-2*t[0]+i[0],e[1]-2*t[1]+i[1],e[2]-2*t[2]+i[2]],abs2(h)<s&&(h=[a[0]-e[0]+3*(t[0]-i[0]),a[1]-e[1]+3*(t[1]-i[1]),a[2]-e[2]+3*(t[2]-i[2])])),h=unit(h);let c=function(e){let t=cross(e,[0,1,0]),i=Number.EPSILON*abs2(e);return abs2(t)>i?unit(t):(t=cross(e,[0,0,1]),abs2(t)>i?unit(t):[1,0,0])}(h);l[0]=new r(e,c,h);for(let s=1;s<n.length;++s){let h=l[s-1],c=n[s],d=1-c,m=d*d,f=m*d,u=3*c;m*=u,d*=u*c;let p=c*c*c,g=[f*e[0]+m*t[0]+d*i[0]+p*a[0],f*e[1]+m*t[1]+d*i[1]+p*a[1],f*e[2]+m*t[2]+d*i[2]+p*a[2]],v=[g[0]-h.p[0],g[1]-h.p[1],g[2]-h.p[2]];if(0!=v[0]||0!=v[1]||0!=v[2]){let e=h.r,t=unit(v),i=h.t,a=dot(t,i),n=[i[0]-2*a*t[0],i[1]-2*a*t[1],i[2]-2*a*t[2]];i=o(c);let d=2*dot(t,e),m=[e[0]-d*t[0],e[1]-d*t[1],e[2]-d*t[2]],f=unit([i[0]-n[0],i[1]-n[1],i[2]-n[2]]),u=2*dot(f,m);m=[m[0]-u*f[0],m[1]-u*f[1],m[2]-u*f[2]],l[s]=new r(g,unit(m),unit(i))}else l[s]=l[s-1]}return l}function tube(e,t,i,n,r,s,o){let l=rmf(e[0],e[1],e[2],e[3],[0,1/3,2/3,1]),h=a*t,c=[[t,0],[t,h],[h,t],[0,t]];function d(t,a,o,h){let d=Array(16);for(let i=0;i<4;++i){let n=l[i],r=n.r[0],s=n.s[0],m=r*t+s*a,f=r*o+s*h;r=n.r[1],s=n.s[1];let u=r*t+s*a,p=r*o+s*h;r=n.r[2],s=n.s[2];let g=r*t+s*a,v=r*o+s*h,!
 x=e[i],w=x[0];w1=x[1],w2=x[2];for(let e=0;e<4;++e){let t=c[e],a=t[0],n=t[1];d[4*i+e]=[m*a+f*n+w,u*a+p*n+w1,g*a+v*n+w2]}}P.push(new BezierPatch(d,i,n,r,s))}d(1,0,0,1),d(0,-1,1,0),d(-1,0,0,-1),d(0,1,-1,0),o&&P.push(new BezierCurve(e,i,n,r,s))}async function getReq(e){return(await fetch(e)).arrayBuffer()}function rgb(e){return e.getBytes().filter((e,t)=>t%4!=3)}function createTexture(e,t,i=gl.RGB16F){let a=e.width(),n=e.height(),r=gl.createTexture();return gl.activeTexture(gl.TEXTURE0+t),gl.bindTexture(gl.TEXTURE_2D,r),gl.pixelStorei(gl.UNPACK_ALIGNMENT,1),gl.texParameteri(gl.TEXTURE_2D,gl.TEXTURE_MIN_FILTER,gl.LINEAR),gl.texParameteri(gl.TEXTURE_2D,gl.TEXTURE_MAG_FILTER,gl.LINEAR),gl.texImage2D(gl.TEXTURE_2D,0,i,a,n,0,gl.RGB,gl.FLOAT,rgb(e)),r}async function initIBL(){let e=imageURL+image+"/";function t(e){return new Promise(t=>setTimeout(t,e))}for(;!Module.EXRLoader;)await t(0);promises=[getReq(imageURL+"refl.exr").then(e=>{let t=new Module.EXRLoader(e);IBLbdrfMap=createTexture(t,0)}),getReq(e+"diffuse.exr").then(e=>{let t=new Module.EXRLoader(e);IBLDiffuseMap=createTexture(t,1)})],refl_promise=[],refl_promise.push(getReq(e+"refl0.exr"));for(let t=1;t<=roughnessStepCount;++t)refl_promise.push(getReq(e+"refl"+t+"w.exr"));finished_promise=Promise.all(refl_promise).then(e=>{let t=gl.createTexture();gl.activeTexture(gl.TEXTURE0+2),gl.pixelStorei(gl.UNPACK_ALIGNMENT,1),gl.bindTexture(gl.TEXTURE_2D,t),gl.texParameteri(gl.TEXTURE_2D,gl.TEXTURE_MAX_LEVEL,e.length-1),gl.texParameteri(gl.TEXTURE_2D,gl.TEXTURE_MIN_FILTER,gl.LINEAR_MIPMAP_LINEAR),gl.texParameteri(gl.TEXTURE_2D,gl.TEXTURE_MAG_FILTER,gl.LINEAR),gl.texParameterf(gl.TEXTURE_2D,gl.TEXTURE_MIN_LOD,0),gl.texParameterf(gl.TEXTURE_2D,gl.TEXTURE_MAX_LOD,roughnessStepCount);for(let t=0;t<e.length;++t){let i=new Module.EXRLoader(e[t]);gl.texImage2D(gl.TEXTURE_2D,t,gl.RGB16F,i.width(),i.height(),0,gl.RGB,gl.FLOAT,rgb(i))}IBLReflMap=t}),promises.push(finished_promise),await Promise.all(promises)}function webGLStart(){canvas=document.getElementById("Asymptote"),embedded=wi!
 ndow.top.document!=document,initGL(),gl.enable(gl.BLEND),gl.blendFunc(gl.SRC_ALPHA,gl.ONE_MINUS_SRC_ALPHA),gl.enable(gl.DEPTH_TEST),gl.enable(gl.SCISSOR_TEST),canvas.onmousedown=handleMouseDown,document.onmouseup=handleMouseUpOrTouchEnd,document.onmousemove=handleMouseMove,canvas.onkeydown=handleKey,embedded||enableZoom(),canvas.addEventListener("touchstart",handleTouchStart,!1),canvas.addEventListener("touchend",handleMouseUpOrTouchEnd,!1),canvas.addEventListener("touchcancel",handleMouseUpOrTouchEnd,!1),canvas.addEventListener("touchleave",handleMouseUpOrTouchEnd,!1),canvas.addEventListener("touchmove",handleTouchMove,!1),document.addEventListener("keydown",handleKey,!1),canvasWidth0=canvasWidth,canvasHeight0=canvasHeight,mat4.identity(rotMat),0!=window.innerWidth&&0!=window.innerHeight&&resize(),window.addEventListener("resize",resize,!1),ibl&&initIBL().then(SetIBL).then(redrawScene)}

Modified: trunk/Build/source/utils/asymptote/config.guess
===================================================================
--- trunk/Build/source/utils/asymptote/config.guess	2022-01-20 21:28:28 UTC (rev 61671)
+++ trunk/Build/source/utils/asymptote/config.guess	2022-01-20 21:32:08 UTC (rev 61672)
@@ -1,14 +1,12 @@
 #! /bin/sh
 # Attempt to guess a canonical system name.
-#   Copyright 1992-2022 Free Software Foundation, Inc.
+#   Copyright 1992-2018 Free Software Foundation, Inc.
 
-# shellcheck disable=SC2006,SC2268 # see below for rationale
+timestamp='2018-03-08'
 
-timestamp='2022-01-09'
-
 # This file is free software; you can redistribute it and/or modify it
 # under the terms of the GNU General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
+# the Free Software Foundation; either version 3 of the License, or
 # (at your option) any later version.
 #
 # This program is distributed in the hope that it will be useful, but
@@ -29,19 +27,11 @@
 # Originally written by Per Bothner; maintained since 2000 by Ben Elliston.
 #
 # You can get the latest version of this script from:
-# https://git.savannah.gnu.org/cgit/config.git/plain/config.guess
+# https://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess
 #
 # Please send patches to <config-patches at gnu.org>.
 
 
-# The "shellcheck disable" line above the timestamp inhibits complaints
-# about features and limitations of the classic Bourne shell that were
-# superseded or lifted in POSIX.  However, this script identifies a wide
-# variety of pre-POSIX systems that do not have POSIX shells at all, and
-# even some reasonably current systems (Solaris 10 as case-in-point) still
-# have a pre-POSIX /bin/sh.
-
-
 me=`echo "$0" | sed -e 's,.*/,,'`
 
 usage="\
@@ -60,7 +50,7 @@
 GNU config.guess ($timestamp)
 
 Originally written by Per Bothner.
-Copyright 1992-2022 Free Software Foundation, Inc.
+Copyright 1992-2018 Free Software Foundation, Inc.
 
 This is free software; see the source for copying conditions.  There is NO
 warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
@@ -94,8 +84,7 @@
   exit 1
 fi
 
-# Just in case it came from the environment.
-GUESS=
+trap 'exit 1' 1 2 15
 
 # CC_FOR_BUILD -- compiler used by this script. Note that the use of a
 # compiler to aid in system detection is discouraged as it requires
@@ -107,53 +96,49 @@
 
 # Portable tmp directory creation inspired by the Autoconf team.
 
-tmp=
-# shellcheck disable=SC2172
-trap 'test -z "$tmp" || rm -fr "$tmp"' 0 1 2 13 15
+set_cc_for_build='
+trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ;
+trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ;
+: ${TMPDIR=/tmp} ;
+ { tmp=`(umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } ||
+ { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } ||
+ { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir $tmp) && echo "Warning: creating insecure temp directory" >&2 ; } ||
+ { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ;
+dummy=$tmp/dummy ;
+tmpfiles="$dummy.c $dummy.o $dummy.rel $dummy" ;
+case $CC_FOR_BUILD,$HOST_CC,$CC in
+ ,,)    echo "int x;" > "$dummy.c" ;
+	for c in cc gcc c89 c99 ; do
+	  if ($c -c -o "$dummy.o" "$dummy.c") >/dev/null 2>&1 ; then
+	     CC_FOR_BUILD="$c"; break ;
+	  fi ;
+	done ;
+	if test x"$CC_FOR_BUILD" = x ; then
+	  CC_FOR_BUILD=no_compiler_found ;
+	fi
+	;;
+ ,,*)   CC_FOR_BUILD=$CC ;;
+ ,*,*)  CC_FOR_BUILD=$HOST_CC ;;
+esac ; set_cc_for_build= ;'
 
-set_cc_for_build() {
-    # prevent multiple calls if $tmp is already set
-    test "$tmp" && return 0
-    : "${TMPDIR=/tmp}"
-    # shellcheck disable=SC2039,SC3028
-    { tmp=`(umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } ||
-	{ test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir "$tmp" 2>/dev/null) ; } ||
-	{ tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir "$tmp" 2>/dev/null) && echo "Warning: creating insecure temp directory" >&2 ; } ||
-	{ echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; }
-    dummy=$tmp/dummy
-    case ${CC_FOR_BUILD-},${HOST_CC-},${CC-} in
-	,,)    echo "int x;" > "$dummy.c"
-	       for driver in cc gcc c89 c99 ; do
-		   if ($driver -c -o "$dummy.o" "$dummy.c") >/dev/null 2>&1 ; then
-		       CC_FOR_BUILD=$driver
-		       break
-		   fi
-	       done
-	       if test x"$CC_FOR_BUILD" = x ; then
-		   CC_FOR_BUILD=no_compiler_found
-	       fi
-	       ;;
-	,,*)   CC_FOR_BUILD=$CC ;;
-	,*,*)  CC_FOR_BUILD=$HOST_CC ;;
-    esac
-}
-
 # This is needed to find uname on a Pyramid OSx when run in the BSD universe.
 # (ghazi at noc.rutgers.edu 1994-08-24)
-if test -f /.attbin/uname ; then
+if (test -f /.attbin/uname) >/dev/null 2>&1 ; then
 	PATH=$PATH:/.attbin ; export PATH
 fi
 
 UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown
 UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown
-UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown
+UNAME_SYSTEM=`(uname -s) 2>/dev/null`  || UNAME_SYSTEM=unknown
 UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown
 
-case $UNAME_SYSTEM in
+case "$UNAME_SYSTEM" in
 Linux|GNU|GNU/*)
-	LIBC=unknown
+	# If the system lacks a compiler, then just pick glibc.
+	# We could probably try harder.
+	LIBC=gnu
 
-	set_cc_for_build
+	eval "$set_cc_for_build"
 	cat <<-EOF > "$dummy.c"
 	#include <features.h>
 	#if defined(__UCLIBC__)
@@ -160,37 +145,24 @@
 	LIBC=uclibc
 	#elif defined(__dietlibc__)
 	LIBC=dietlibc
-	#elif defined(__GLIBC__)
+	#else
 	LIBC=gnu
-	#else
-	#include <stdarg.h>
-	/* First heuristic to detect musl libc.  */
-	#ifdef __DEFINED_va_list
-	LIBC=musl
 	#endif
-	#endif
 	EOF
-	cc_set_libc=`$CC_FOR_BUILD -E "$dummy.c" 2>/dev/null | grep '^LIBC' | sed 's, ,,g'`
-	eval "$cc_set_libc"
+	eval "`$CC_FOR_BUILD -E "$dummy.c" 2>/dev/null | grep '^LIBC' | sed 's, ,,g'`"
 
-	# Second heuristic to detect musl libc.
-	if [ "$LIBC" = unknown ] &&
-	   command -v ldd >/dev/null &&
-	   ldd --version 2>&1 | grep -q ^musl; then
-		LIBC=musl
+	# If ldd exists, use it to detect musl libc.
+	if command -v ldd >/dev/null && \
+		ldd --version 2>&1 | grep -q ^musl
+	then
+	    LIBC=musl
 	fi
-
-	# If the system lacks a compiler, then just pick glibc.
-	# We could probably try harder.
-	if [ "$LIBC" = unknown ]; then
-		LIBC=gnu
-	fi
 	;;
 esac
 
 # Note: order is significant - the case branches are not exclusive.
 
-case $UNAME_MACHINE:$UNAME_SYSTEM:$UNAME_RELEASE:$UNAME_VERSION in
+case "$UNAME_MACHINE:$UNAME_SYSTEM:$UNAME_RELEASE:$UNAME_VERSION" in
     *:NetBSD:*:*)
 	# NetBSD (nbsd) targets should (where applicable) match one or
 	# more of the tuples: *-*-netbsdelf*, *-*-netbsdaout*,
@@ -202,12 +174,12 @@
 	#
 	# Note: NetBSD doesn't particularly care about the vendor
 	# portion of the name.  We always set it to "unknown".
+	sysctl="sysctl -n hw.machine_arch"
 	UNAME_MACHINE_ARCH=`(uname -p 2>/dev/null || \
-	    /sbin/sysctl -n hw.machine_arch 2>/dev/null || \
-	    /usr/sbin/sysctl -n hw.machine_arch 2>/dev/null || \
+	    "/sbin/$sysctl" 2>/dev/null || \
+	    "/usr/sbin/$sysctl" 2>/dev/null || \
 	    echo unknown)`
-	case $UNAME_MACHINE_ARCH in
-	    aarch64eb) machine=aarch64_be-unknown ;;
+	case "$UNAME_MACHINE_ARCH" in
 	    armeb) machine=armeb-unknown ;;
 	    arm*) machine=arm-unknown ;;
 	    sh3el) machine=shl-unknown ;;
@@ -216,18 +188,18 @@
 	    earmv*)
 		arch=`echo "$UNAME_MACHINE_ARCH" | sed -e 's,^e\(armv[0-9]\).*$,\1,'`
 		endian=`echo "$UNAME_MACHINE_ARCH" | sed -ne 's,^.*\(eb\)$,\1,p'`
-		machine=${arch}${endian}-unknown
+		machine="${arch}${endian}"-unknown
 		;;
-	    *) machine=$UNAME_MACHINE_ARCH-unknown ;;
+	    *) machine="$UNAME_MACHINE_ARCH"-unknown ;;
 	esac
 	# The Operating System including object format, if it has switched
 	# to ELF recently (or will in the future) and ABI.
-	case $UNAME_MACHINE_ARCH in
+	case "$UNAME_MACHINE_ARCH" in
 	    earm*)
 		os=netbsdelf
 		;;
 	    arm*|i386|m68k|ns32k|sh3*|sparc|vax)
-		set_cc_for_build
+		eval "$set_cc_for_build"
 		if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \
 			| grep -q __ELF__
 		then
@@ -243,7 +215,7 @@
 		;;
 	esac
 	# Determine ABI tags.
-	case $UNAME_MACHINE_ARCH in
+	case "$UNAME_MACHINE_ARCH" in
 	    earm*)
 		expr='s/^earmv[0-9]/-eabi/;s/eb$//'
 		abi=`echo "$UNAME_MACHINE_ARCH" | sed -e "$expr"`
@@ -254,7 +226,7 @@
 	# thus, need a distinct triplet. However, they do not need
 	# kernel version information, so it can be replaced with a
 	# suitable tag, in the style of linux-gnu.
-	case $UNAME_VERSION in
+	case "$UNAME_VERSION" in
 	    Debian*)
 		release='-gnu'
 		;;
@@ -265,57 +237,45 @@
 	# Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM:
 	# contains redundant information, the shorter form:
 	# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used.
-	GUESS=$machine-${os}${release}${abi-}
-	;;
+	echo "$machine-${os}${release}${abi}"
+	exit ;;
     *:Bitrig:*:*)
 	UNAME_MACHINE_ARCH=`arch | sed 's/Bitrig.//'`
-	GUESS=$UNAME_MACHINE_ARCH-unknown-bitrig$UNAME_RELEASE
-	;;
+	echo "$UNAME_MACHINE_ARCH"-unknown-bitrig"$UNAME_RELEASE"
+	exit ;;
     *:OpenBSD:*:*)
 	UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'`
-	GUESS=$UNAME_MACHINE_ARCH-unknown-openbsd$UNAME_RELEASE
-	;;
-    *:SecBSD:*:*)
-	UNAME_MACHINE_ARCH=`arch | sed 's/SecBSD.//'`
-	GUESS=$UNAME_MACHINE_ARCH-unknown-secbsd$UNAME_RELEASE
-	;;
+	echo "$UNAME_MACHINE_ARCH"-unknown-openbsd"$UNAME_RELEASE"
+	exit ;;
     *:LibertyBSD:*:*)
 	UNAME_MACHINE_ARCH=`arch | sed 's/^.*BSD\.//'`
-	GUESS=$UNAME_MACHINE_ARCH-unknown-libertybsd$UNAME_RELEASE
-	;;
+	echo "$UNAME_MACHINE_ARCH"-unknown-libertybsd"$UNAME_RELEASE"
+	exit ;;
     *:MidnightBSD:*:*)
-	GUESS=$UNAME_MACHINE-unknown-midnightbsd$UNAME_RELEASE
-	;;
+	echo "$UNAME_MACHINE"-unknown-midnightbsd"$UNAME_RELEASE"
+	exit ;;
     *:ekkoBSD:*:*)
-	GUESS=$UNAME_MACHINE-unknown-ekkobsd$UNAME_RELEASE
-	;;
+	echo "$UNAME_MACHINE"-unknown-ekkobsd"$UNAME_RELEASE"
+	exit ;;
     *:SolidBSD:*:*)
-	GUESS=$UNAME_MACHINE-unknown-solidbsd$UNAME_RELEASE
-	;;
-    *:OS108:*:*)
-	GUESS=$UNAME_MACHINE-unknown-os108_$UNAME_RELEASE
-	;;
+	echo "$UNAME_MACHINE"-unknown-solidbsd"$UNAME_RELEASE"
+	exit ;;
     macppc:MirBSD:*:*)
-	GUESS=powerpc-unknown-mirbsd$UNAME_RELEASE
-	;;
+	echo powerpc-unknown-mirbsd"$UNAME_RELEASE"
+	exit ;;
     *:MirBSD:*:*)
-	GUESS=$UNAME_MACHINE-unknown-mirbsd$UNAME_RELEASE
-	;;
+	echo "$UNAME_MACHINE"-unknown-mirbsd"$UNAME_RELEASE"
+	exit ;;
     *:Sortix:*:*)
-	GUESS=$UNAME_MACHINE-unknown-sortix
-	;;
-    *:Twizzler:*:*)
-	GUESS=$UNAME_MACHINE-unknown-twizzler
-	;;
+	echo "$UNAME_MACHINE"-unknown-sortix
+	exit ;;
     *:Redox:*:*)
-	GUESS=$UNAME_MACHINE-unknown-redox
-	;;
+	echo "$UNAME_MACHINE"-unknown-redox
+	exit ;;
     mips:OSF1:*.*)
-	GUESS=mips-dec-osf1
-	;;
+        echo mips-dec-osf1
+        exit ;;
     alpha:OSF1:*:*)
-	# Reset EXIT trap before exiting to avoid spurious non-zero exit code.
-	trap '' 0
 	case $UNAME_RELEASE in
 	*4.0)
 		UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'`
@@ -329,7 +289,7 @@
 	# covers most systems running today.  This code pipes the CPU
 	# types through head -n 1, so we only detect the type of CPU 0.
 	ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^  The alpha \(.*\) processor.*$/\1/p' | head -n 1`
-	case $ALPHA_CPU_TYPE in
+	case "$ALPHA_CPU_TYPE" in
 	    "EV4 (21064)")
 		UNAME_MACHINE=alpha ;;
 	    "EV4.5 (21064)")
@@ -366,121 +326,117 @@
 	# A Tn.n version is a released field test version.
 	# A Xn.n version is an unreleased experimental baselevel.
 	# 1.2 uses "1.2" for uname -r.
-	OSF_REL=`echo "$UNAME_RELEASE" | sed -e 's/^[PVTX]//' | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz`
-	GUESS=$UNAME_MACHINE-dec-osf$OSF_REL
-	;;
+	echo "$UNAME_MACHINE"-dec-osf"`echo "$UNAME_RELEASE" | sed -e 's/^[PVTX]//' | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz`"
+	# Reset EXIT trap before exiting to avoid spurious non-zero exit code.
+	exitcode=$?
+	trap '' 0
+	exit $exitcode ;;
     Amiga*:UNIX_System_V:4.0:*)
-	GUESS=m68k-unknown-sysv4
-	;;
+	echo m68k-unknown-sysv4
+	exit ;;
     *:[Aa]miga[Oo][Ss]:*:*)
-	GUESS=$UNAME_MACHINE-unknown-amigaos
-	;;
+	echo "$UNAME_MACHINE"-unknown-amigaos
+	exit ;;
     *:[Mm]orph[Oo][Ss]:*:*)
-	GUESS=$UNAME_MACHINE-unknown-morphos
-	;;
+	echo "$UNAME_MACHINE"-unknown-morphos
+	exit ;;
     *:OS/390:*:*)
-	GUESS=i370-ibm-openedition
-	;;
+	echo i370-ibm-openedition
+	exit ;;
     *:z/VM:*:*)
-	GUESS=s390-ibm-zvmoe
-	;;
+	echo s390-ibm-zvmoe
+	exit ;;
     *:OS400:*:*)
-	GUESS=powerpc-ibm-os400
-	;;
+	echo powerpc-ibm-os400
+	exit ;;
     arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*)
-	GUESS=arm-acorn-riscix$UNAME_RELEASE
-	;;
+	echo arm-acorn-riscix"$UNAME_RELEASE"
+	exit ;;
     arm*:riscos:*:*|arm*:RISCOS:*:*)
-	GUESS=arm-unknown-riscos
-	;;
+	echo arm-unknown-riscos
+	exit ;;
     SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*)
-	GUESS=hppa1.1-hitachi-hiuxmpp
-	;;
+	echo hppa1.1-hitachi-hiuxmpp
+	exit ;;
     Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*)
 	# akee at wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE.
-	case `(/bin/universe) 2>/dev/null` in
-	    att) GUESS=pyramid-pyramid-sysv3 ;;
-	    *)   GUESS=pyramid-pyramid-bsd   ;;
-	esac
-	;;
+	if test "`(/bin/universe) 2>/dev/null`" = att ; then
+		echo pyramid-pyramid-sysv3
+	else
+		echo pyramid-pyramid-bsd
+	fi
+	exit ;;
     NILE*:*:*:dcosx)
-	GUESS=pyramid-pyramid-svr4
-	;;
+	echo pyramid-pyramid-svr4
+	exit ;;
     DRS?6000:unix:4.0:6*)
-	GUESS=sparc-icl-nx6
-	;;
+	echo sparc-icl-nx6
+	exit ;;
     DRS?6000:UNIX_SV:4.2*:7* | DRS?6000:isis:4.2*:7*)
 	case `/usr/bin/uname -p` in
-	    sparc) GUESS=sparc-icl-nx7 ;;
-	esac
-	;;
+	    sparc) echo sparc-icl-nx7; exit ;;
+	esac ;;
     s390x:SunOS:*:*)
-	SUN_REL=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'`
-	GUESS=$UNAME_MACHINE-ibm-solaris2$SUN_REL
-	;;
+	echo "$UNAME_MACHINE"-ibm-solaris2"`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'`"
+	exit ;;
     sun4H:SunOS:5.*:*)
-	SUN_REL=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'`
-	GUESS=sparc-hal-solaris2$SUN_REL
-	;;
+	echo sparc-hal-solaris2"`echo "$UNAME_RELEASE"|sed -e 's/[^.]*//'`"
+	exit ;;
     sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*)
-	SUN_REL=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'`
-	GUESS=sparc-sun-solaris2$SUN_REL
-	;;
+	echo sparc-sun-solaris2"`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'`"
+	exit ;;
     i86pc:AuroraUX:5.*:* | i86xen:AuroraUX:5.*:*)
-	GUESS=i386-pc-auroraux$UNAME_RELEASE
-	;;
+	echo i386-pc-auroraux"$UNAME_RELEASE"
+	exit ;;
     i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*)
-	set_cc_for_build
+	eval "$set_cc_for_build"
 	SUN_ARCH=i386
 	# If there is a compiler, see if it is configured for 64-bit objects.
 	# Note that the Sun cc does not turn __LP64__ into 1 like gcc does.
 	# This test works for both compilers.
-	if test "$CC_FOR_BUILD" != no_compiler_found; then
+	if [ "$CC_FOR_BUILD" != no_compiler_found ]; then
 	    if (echo '#ifdef __amd64'; echo IS_64BIT_ARCH; echo '#endif') | \
-		(CCOPTS="" $CC_FOR_BUILD -m64 -E - 2>/dev/null) | \
+		(CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \
 		grep IS_64BIT_ARCH >/dev/null
 	    then
 		SUN_ARCH=x86_64
 	    fi
 	fi
-	SUN_REL=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'`
-	GUESS=$SUN_ARCH-pc-solaris2$SUN_REL
-	;;
+	echo "$SUN_ARCH"-pc-solaris2"`echo "$UNAME_RELEASE"|sed -e 's/[^.]*//'`"
+	exit ;;
     sun4*:SunOS:6*:*)
 	# According to config.sub, this is the proper way to canonicalize
 	# SunOS6.  Hard to guess exactly what SunOS6 will be like, but
 	# it's likely to be more like Solaris than SunOS4.
-	SUN_REL=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'`
-	GUESS=sparc-sun-solaris3$SUN_REL
-	;;
+	echo sparc-sun-solaris3"`echo "$UNAME_RELEASE"|sed -e 's/[^.]*//'`"
+	exit ;;
     sun4*:SunOS:*:*)
-	case `/usr/bin/arch -k` in
+	case "`/usr/bin/arch -k`" in
 	    Series*|S4*)
 		UNAME_RELEASE=`uname -v`
 		;;
 	esac
 	# Japanese Language versions have a version number like `4.1.3-JL'.
-	SUN_REL=`echo "$UNAME_RELEASE" | sed -e 's/-/_/'`
-	GUESS=sparc-sun-sunos$SUN_REL
-	;;
+	echo sparc-sun-sunos"`echo "$UNAME_RELEASE"|sed -e 's/-/_/'`"
+	exit ;;
     sun3*:SunOS:*:*)
-	GUESS=m68k-sun-sunos$UNAME_RELEASE
-	;;
+	echo m68k-sun-sunos"$UNAME_RELEASE"
+	exit ;;
     sun*:*:4.2BSD:*)
 	UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null`
 	test "x$UNAME_RELEASE" = x && UNAME_RELEASE=3
-	case `/bin/arch` in
+	case "`/bin/arch`" in
 	    sun3)
-		GUESS=m68k-sun-sunos$UNAME_RELEASE
+		echo m68k-sun-sunos"$UNAME_RELEASE"
 		;;
 	    sun4)
-		GUESS=sparc-sun-sunos$UNAME_RELEASE
+		echo sparc-sun-sunos"$UNAME_RELEASE"
 		;;
 	esac
-	;;
+	exit ;;
     aushp:SunOS:*:*)
-	GUESS=sparc-auspex-sunos$UNAME_RELEASE
-	;;
+	echo sparc-auspex-sunos"$UNAME_RELEASE"
+	exit ;;
     # The situation for MiNT is a little confusing.  The machine name
     # can be virtually everything (everything which is not
     # "atarist" or "atariste" at least should have a processor
@@ -490,43 +446,43 @@
     # MiNT.  But MiNT is downward compatible to TOS, so this should
     # be no problem.
     atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*)
-	GUESS=m68k-atari-mint$UNAME_RELEASE
-	;;
+	echo m68k-atari-mint"$UNAME_RELEASE"
+	exit ;;
     atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*)
-	GUESS=m68k-atari-mint$UNAME_RELEASE
-	;;
+	echo m68k-atari-mint"$UNAME_RELEASE"
+	exit ;;
     *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*)
-	GUESS=m68k-atari-mint$UNAME_RELEASE
-	;;
+	echo m68k-atari-mint"$UNAME_RELEASE"
+	exit ;;
     milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*)
-	GUESS=m68k-milan-mint$UNAME_RELEASE
-	;;
+	echo m68k-milan-mint"$UNAME_RELEASE"
+	exit ;;
     hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*)
-	GUESS=m68k-hades-mint$UNAME_RELEASE
-	;;
+	echo m68k-hades-mint"$UNAME_RELEASE"
+	exit ;;
     *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*)
-	GUESS=m68k-unknown-mint$UNAME_RELEASE
-	;;
+	echo m68k-unknown-mint"$UNAME_RELEASE"
+	exit ;;
     m68k:machten:*:*)
-	GUESS=m68k-apple-machten$UNAME_RELEASE
-	;;
+	echo m68k-apple-machten"$UNAME_RELEASE"
+	exit ;;
     powerpc:machten:*:*)
-	GUESS=powerpc-apple-machten$UNAME_RELEASE
-	;;
+	echo powerpc-apple-machten"$UNAME_RELEASE"
+	exit ;;
     RISC*:Mach:*:*)
-	GUESS=mips-dec-mach_bsd4.3
-	;;
+	echo mips-dec-mach_bsd4.3
+	exit ;;
     RISC*:ULTRIX:*:*)
-	GUESS=mips-dec-ultrix$UNAME_RELEASE
-	;;
+	echo mips-dec-ultrix"$UNAME_RELEASE"
+	exit ;;
     VAX*:ULTRIX*:*:*)
-	GUESS=vax-dec-ultrix$UNAME_RELEASE
-	;;
+	echo vax-dec-ultrix"$UNAME_RELEASE"
+	exit ;;
     2020:CLIX:*:* | 2430:CLIX:*:*)
-	GUESS=clipper-intergraph-clix$UNAME_RELEASE
-	;;
+	echo clipper-intergraph-clix"$UNAME_RELEASE"
+	exit ;;
     mips:*:*:UMIPS | mips:*:*:RISCos)
-	set_cc_for_build
+	eval "$set_cc_for_build"
 	sed 's/^	//' << EOF > "$dummy.c"
 #ifdef __cplusplus
 #include <stdio.h>  /* for printf() prototype */
@@ -552,79 +508,78 @@
 	  dummyarg=`echo "$UNAME_RELEASE" | sed -n 's/\([0-9]*\).*/\1/p'` &&
 	  SYSTEM_NAME=`"$dummy" "$dummyarg"` &&
 	    { echo "$SYSTEM_NAME"; exit; }
-	GUESS=mips-mips-riscos$UNAME_RELEASE
-	;;
+	echo mips-mips-riscos"$UNAME_RELEASE"
+	exit ;;
     Motorola:PowerMAX_OS:*:*)
-	GUESS=powerpc-motorola-powermax
-	;;
+	echo powerpc-motorola-powermax
+	exit ;;
     Motorola:*:4.3:PL8-*)
-	GUESS=powerpc-harris-powermax
-	;;
+	echo powerpc-harris-powermax
+	exit ;;
     Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*)
-	GUESS=powerpc-harris-powermax
-	;;
+	echo powerpc-harris-powermax
+	exit ;;
     Night_Hawk:Power_UNIX:*:*)
-	GUESS=powerpc-harris-powerunix
-	;;
+	echo powerpc-harris-powerunix
+	exit ;;
     m88k:CX/UX:7*:*)
-	GUESS=m88k-harris-cxux7
-	;;
+	echo m88k-harris-cxux7
+	exit ;;
     m88k:*:4*:R4*)
-	GUESS=m88k-motorola-sysv4
-	;;
+	echo m88k-motorola-sysv4
+	exit ;;
     m88k:*:3*:R3*)
-	GUESS=m88k-motorola-sysv3
-	;;
+	echo m88k-motorola-sysv3
+	exit ;;
     AViiON:dgux:*:*)
 	# DG/UX returns AViiON for all architectures
 	UNAME_PROCESSOR=`/usr/bin/uname -p`
-	if test "$UNAME_PROCESSOR" = mc88100 || test "$UNAME_PROCESSOR" = mc88110
+	if [ "$UNAME_PROCESSOR" = mc88100 ] || [ "$UNAME_PROCESSOR" = mc88110 ]
 	then
-	    if test "$TARGET_BINARY_INTERFACE"x = m88kdguxelfx || \
-	       test "$TARGET_BINARY_INTERFACE"x = x
+	    if [ "$TARGET_BINARY_INTERFACE"x = m88kdguxelfx ] || \
+	       [ "$TARGET_BINARY_INTERFACE"x = x ]
 	    then
-		GUESS=m88k-dg-dgux$UNAME_RELEASE
+		echo m88k-dg-dgux"$UNAME_RELEASE"
 	    else
-		GUESS=m88k-dg-dguxbcs$UNAME_RELEASE
+		echo m88k-dg-dguxbcs"$UNAME_RELEASE"
 	    fi
 	else
-	    GUESS=i586-dg-dgux$UNAME_RELEASE
+	    echo i586-dg-dgux"$UNAME_RELEASE"
 	fi
-	;;
+	exit ;;
     M88*:DolphinOS:*:*)	# DolphinOS (SVR3)
-	GUESS=m88k-dolphin-sysv3
-	;;
+	echo m88k-dolphin-sysv3
+	exit ;;
     M88*:*:R3*:*)
 	# Delta 88k system running SVR3
-	GUESS=m88k-motorola-sysv3
-	;;
+	echo m88k-motorola-sysv3
+	exit ;;
     XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3)
-	GUESS=m88k-tektronix-sysv3
-	;;
+	echo m88k-tektronix-sysv3
+	exit ;;
     Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD)
-	GUESS=m68k-tektronix-bsd
-	;;
+	echo m68k-tektronix-bsd
+	exit ;;
     *:IRIX*:*:*)
-	IRIX_REL=`echo "$UNAME_RELEASE" | sed -e 's/-/_/g'`
-	GUESS=mips-sgi-irix$IRIX_REL
-	;;
+	echo mips-sgi-irix"`echo "$UNAME_RELEASE"|sed -e 's/-/_/g'`"
+	exit ;;
     ????????:AIX?:[12].1:2)   # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX.
-	GUESS=romp-ibm-aix    # uname -m gives an 8 hex-code CPU id
-	;;                    # Note that: echo "'`uname -s`'" gives 'AIX '
+	echo romp-ibm-aix     # uname -m gives an 8 hex-code CPU id
+	exit ;;               # Note that: echo "'`uname -s`'" gives 'AIX '
     i*86:AIX:*:*)
-	GUESS=i386-ibm-aix
-	;;
+	echo i386-ibm-aix
+	exit ;;
     ia64:AIX:*:*)
-	if test -x /usr/bin/oslevel ; then
+	if [ -x /usr/bin/oslevel ] ; then
 		IBM_REV=`/usr/bin/oslevel`
 	else
-		IBM_REV=$UNAME_VERSION.$UNAME_RELEASE
+		IBM_REV="$UNAME_VERSION.$UNAME_RELEASE"
 	fi
-	GUESS=$UNAME_MACHINE-ibm-aix$IBM_REV
-	;;
+	echo "$UNAME_MACHINE"-ibm-aix"$IBM_REV"
+	exit ;;
     *:AIX:2:3)
 	if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then
-		set_cc_for_build
+		eval "$set_cc_for_build"
 		sed 's/^		//' << EOF > "$dummy.c"
 		#include <sys/systemcfg.h>
 
@@ -638,16 +593,16 @@
 EOF
 		if $CC_FOR_BUILD -o "$dummy" "$dummy.c" && SYSTEM_NAME=`"$dummy"`
 		then
-			GUESS=$SYSTEM_NAME
+			echo "$SYSTEM_NAME"
 		else
-			GUESS=rs6000-ibm-aix3.2.5
+			echo rs6000-ibm-aix3.2.5
 		fi
 	elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then
-		GUESS=rs6000-ibm-aix3.2.4
+		echo rs6000-ibm-aix3.2.4
 	else
-		GUESS=rs6000-ibm-aix3.2
+		echo rs6000-ibm-aix3.2
 	fi
-	;;
+	exit ;;
     *:AIX:*:[4567])
 	IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'`
 	if /usr/sbin/lsattr -El "$IBM_CPU_ID" | grep ' POWER' >/dev/null 2>&1; then
@@ -655,49 +610,49 @@
 	else
 		IBM_ARCH=powerpc
 	fi
-	if test -x /usr/bin/lslpp ; then
-		IBM_REV=`/usr/bin/lslpp -Lqc bos.rte.libc | \
+	if [ -x /usr/bin/lslpp ] ; then
+		IBM_REV=`/usr/bin/lslpp -Lqc bos.rte.libc |
 			   awk -F: '{ print $3 }' | sed s/[0-9]*$/0/`
 	else
-		IBM_REV=$UNAME_VERSION.$UNAME_RELEASE
+		IBM_REV="$UNAME_VERSION.$UNAME_RELEASE"
 	fi
-	GUESS=$IBM_ARCH-ibm-aix$IBM_REV
-	;;
+	echo "$IBM_ARCH"-ibm-aix"$IBM_REV"
+	exit ;;
     *:AIX:*:*)
-	GUESS=rs6000-ibm-aix
-	;;
+	echo rs6000-ibm-aix
+	exit ;;
     ibmrt:4.4BSD:*|romp-ibm:4.4BSD:*)
-	GUESS=romp-ibm-bsd4.4
-	;;
+	echo romp-ibm-bsd4.4
+	exit ;;
     ibmrt:*BSD:*|romp-ibm:BSD:*)            # covers RT/PC BSD and
-	GUESS=romp-ibm-bsd$UNAME_RELEASE    # 4.3 with uname added to
-	;;                                  # report: romp-ibm BSD 4.3
+	echo romp-ibm-bsd"$UNAME_RELEASE"   # 4.3 with uname added to
+	exit ;;                             # report: romp-ibm BSD 4.3
     *:BOSX:*:*)
-	GUESS=rs6000-bull-bosx
-	;;
+	echo rs6000-bull-bosx
+	exit ;;
     DPX/2?00:B.O.S.:*:*)
-	GUESS=m68k-bull-sysv3
-	;;
+	echo m68k-bull-sysv3
+	exit ;;
     9000/[34]??:4.3bsd:1.*:*)
-	GUESS=m68k-hp-bsd
-	;;
+	echo m68k-hp-bsd
+	exit ;;
     hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*)
-	GUESS=m68k-hp-bsd4.4
-	;;
+	echo m68k-hp-bsd4.4
+	exit ;;
     9000/[34678]??:HP-UX:*:*)
-	HPUX_REV=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*.[0B]*//'`
-	case $UNAME_MACHINE in
+	HPUX_REV=`echo "$UNAME_RELEASE"|sed -e 's/[^.]*.[0B]*//'`
+	case "$UNAME_MACHINE" in
 	    9000/31?)            HP_ARCH=m68000 ;;
 	    9000/[34]??)         HP_ARCH=m68k ;;
 	    9000/[678][0-9][0-9])
-		if test -x /usr/bin/getconf; then
+		if [ -x /usr/bin/getconf ]; then
 		    sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null`
 		    sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null`
-		    case $sc_cpu_version in
+		    case "$sc_cpu_version" in
 		      523) HP_ARCH=hppa1.0 ;; # CPU_PA_RISC1_0
 		      528) HP_ARCH=hppa1.1 ;; # CPU_PA_RISC1_1
 		      532)                      # CPU_PA_RISC2_0
-			case $sc_kernel_bits in
+			case "$sc_kernel_bits" in
 			  32) HP_ARCH=hppa2.0n ;;
 			  64) HP_ARCH=hppa2.0w ;;
 			  '') HP_ARCH=hppa2.0 ;;   # HP-UX 10.20
@@ -704,8 +659,8 @@
 			esac ;;
 		    esac
 		fi
-		if test "$HP_ARCH" = ""; then
-		    set_cc_for_build
+		if [ "$HP_ARCH" = "" ]; then
+		    eval "$set_cc_for_build"
 		    sed 's/^		//' << EOF > "$dummy.c"
 
 		#define _HPUX_SOURCE
@@ -743,9 +698,9 @@
 		    test -z "$HP_ARCH" && HP_ARCH=hppa
 		fi ;;
 	esac
-	if test "$HP_ARCH" = hppa2.0w
+	if [ "$HP_ARCH" = hppa2.0w ]
 	then
-	    set_cc_for_build
+	    eval "$set_cc_for_build"
 
 	    # hppa2.0w-hp-hpux* has a 64-bit kernel and a compiler generating
 	    # 32-bit code.  hppa64-hp-hpux* has the same kernel and a compiler
@@ -764,14 +719,14 @@
 		HP_ARCH=hppa64
 	    fi
 	fi
-	GUESS=$HP_ARCH-hp-hpux$HPUX_REV
-	;;
+	echo "$HP_ARCH"-hp-hpux"$HPUX_REV"
+	exit ;;
     ia64:HP-UX:*:*)
-	HPUX_REV=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*.[0B]*//'`
-	GUESS=ia64-hp-hpux$HPUX_REV
-	;;
+	HPUX_REV=`echo "$UNAME_RELEASE"|sed -e 's/[^.]*.[0B]*//'`
+	echo ia64-hp-hpux"$HPUX_REV"
+	exit ;;
     3050*:HI-UX:*:*)
-	set_cc_for_build
+	eval "$set_cc_for_build"
 	sed 's/^	//' << EOF > "$dummy.c"
 	#include <unistd.h>
 	int
@@ -799,36 +754,36 @@
 EOF
 	$CC_FOR_BUILD -o "$dummy" "$dummy.c" && SYSTEM_NAME=`"$dummy"` &&
 		{ echo "$SYSTEM_NAME"; exit; }
-	GUESS=unknown-hitachi-hiuxwe2
-	;;
+	echo unknown-hitachi-hiuxwe2
+	exit ;;
     9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:*)
-	GUESS=hppa1.1-hp-bsd
-	;;
+	echo hppa1.1-hp-bsd
+	exit ;;
     9000/8??:4.3bsd:*:*)
-	GUESS=hppa1.0-hp-bsd
-	;;
+	echo hppa1.0-hp-bsd
+	exit ;;
     *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*)
-	GUESS=hppa1.0-hp-mpeix
-	;;
+	echo hppa1.0-hp-mpeix
+	exit ;;
     hp7??:OSF1:*:* | hp8?[79]:OSF1:*:*)
-	GUESS=hppa1.1-hp-osf
-	;;
+	echo hppa1.1-hp-osf
+	exit ;;
     hp8??:OSF1:*:*)
-	GUESS=hppa1.0-hp-osf
-	;;
+	echo hppa1.0-hp-osf
+	exit ;;
     i*86:OSF1:*:*)
-	if test -x /usr/sbin/sysversion ; then
-	    GUESS=$UNAME_MACHINE-unknown-osf1mk
+	if [ -x /usr/sbin/sysversion ] ; then
+	    echo "$UNAME_MACHINE"-unknown-osf1mk
 	else
-	    GUESS=$UNAME_MACHINE-unknown-osf1
+	    echo "$UNAME_MACHINE"-unknown-osf1
 	fi
-	;;
+	exit ;;
     parisc*:Lites*:*:*)
-	GUESS=hppa1.1-hp-lites
-	;;
+	echo hppa1.1-hp-lites
+	exit ;;
     C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*)
-	GUESS=c1-convex-bsd
-	;;
+	echo c1-convex-bsd
+	exit ;;
     C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*)
 	if getsysinfo -f scalar_acc
 	then echo c32-convex-bsd
@@ -836,18 +791,17 @@
 	fi
 	exit ;;
     C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*)
-	GUESS=c34-convex-bsd
-	;;
+	echo c34-convex-bsd
+	exit ;;
     C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*)
-	GUESS=c38-convex-bsd
-	;;
+	echo c38-convex-bsd
+	exit ;;
     C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*)
-	GUESS=c4-convex-bsd
-	;;
+	echo c4-convex-bsd
+	exit ;;
     CRAY*Y-MP:*:*:*)
-	CRAY_REL=`echo "$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/'`
-	GUESS=ymp-cray-unicos$CRAY_REL
-	;;
+	echo ymp-cray-unicos"$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/'
+	exit ;;
     CRAY*[A-Z]90:*:*:*)
 	echo "$UNAME_MACHINE"-cray-unicos"$UNAME_RELEASE" \
 	| sed -e 's/CRAY.*\([A-Z]90\)/\1/' \
@@ -855,129 +809,103 @@
 	      -e 's/\.[^.]*$/.X/'
 	exit ;;
     CRAY*TS:*:*:*)
-	CRAY_REL=`echo "$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/'`
-	GUESS=t90-cray-unicos$CRAY_REL
-	;;
+	echo t90-cray-unicos"$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/'
+	exit ;;
     CRAY*T3E:*:*:*)
-	CRAY_REL=`echo "$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/'`
-	GUESS=alphaev5-cray-unicosmk$CRAY_REL
-	;;
+	echo alphaev5-cray-unicosmk"$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/'
+	exit ;;
     CRAY*SV1:*:*:*)
-	CRAY_REL=`echo "$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/'`
-	GUESS=sv1-cray-unicos$CRAY_REL
-	;;
+	echo sv1-cray-unicos"$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/'
+	exit ;;
     *:UNICOS/mp:*:*)
-	CRAY_REL=`echo "$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/'`
-	GUESS=craynv-cray-unicosmp$CRAY_REL
-	;;
+	echo craynv-cray-unicosmp"$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/'
+	exit ;;
     F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*)
 	FUJITSU_PROC=`uname -m | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz`
 	FUJITSU_SYS=`uname -p | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/\///'`
 	FUJITSU_REL=`echo "$UNAME_RELEASE" | sed -e 's/ /_/'`
-	GUESS=${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}
-	;;
+	echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
+	exit ;;
     5000:UNIX_System_V:4.*:*)
 	FUJITSU_SYS=`uname -p | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/\///'`
 	FUJITSU_REL=`echo "$UNAME_RELEASE" | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/ /_/'`
-	GUESS=sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}
-	;;
+	echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
+	exit ;;
     i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*)
-	GUESS=$UNAME_MACHINE-pc-bsdi$UNAME_RELEASE
-	;;
+	echo "$UNAME_MACHINE"-pc-bsdi"$UNAME_RELEASE"
+	exit ;;
     sparc*:BSD/OS:*:*)
-	GUESS=sparc-unknown-bsdi$UNAME_RELEASE
-	;;
+	echo sparc-unknown-bsdi"$UNAME_RELEASE"
+	exit ;;
     *:BSD/OS:*:*)
-	GUESS=$UNAME_MACHINE-unknown-bsdi$UNAME_RELEASE
-	;;
-    arm:FreeBSD:*:*)
-	UNAME_PROCESSOR=`uname -p`
-	set_cc_for_build
-	if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \
-	    | grep -q __ARM_PCS_VFP
-	then
-	    FREEBSD_REL=`echo "$UNAME_RELEASE" | sed -e 's/[-(].*//'`
-	    GUESS=$UNAME_PROCESSOR-unknown-freebsd$FREEBSD_REL-gnueabi
-	else
-	    FREEBSD_REL=`echo "$UNAME_RELEASE" | sed -e 's/[-(].*//'`
-	    GUESS=$UNAME_PROCESSOR-unknown-freebsd$FREEBSD_REL-gnueabihf
-	fi
-	;;
+	echo "$UNAME_MACHINE"-unknown-bsdi"$UNAME_RELEASE"
+	exit ;;
     *:FreeBSD:*:*)
 	UNAME_PROCESSOR=`/usr/bin/uname -p`
-	case $UNAME_PROCESSOR in
+	case "$UNAME_PROCESSOR" in
 	    amd64)
 		UNAME_PROCESSOR=x86_64 ;;
 	    i386)
 		UNAME_PROCESSOR=i586 ;;
 	esac
-	FREEBSD_REL=`echo "$UNAME_RELEASE" | sed -e 's/[-(].*//'`
-	GUESS=$UNAME_PROCESSOR-unknown-freebsd$FREEBSD_REL
-	;;
+	echo "$UNAME_PROCESSOR"-unknown-freebsd"`echo "$UNAME_RELEASE"|sed -e 's/[-(].*//'`"
+	exit ;;
     i*:CYGWIN*:*)
-	GUESS=$UNAME_MACHINE-pc-cygwin
-	;;
+	echo "$UNAME_MACHINE"-pc-cygwin
+	exit ;;
     *:MINGW64*:*)
-	GUESS=$UNAME_MACHINE-pc-mingw64
-	;;
+	echo "$UNAME_MACHINE"-pc-mingw64
+	exit ;;
     *:MINGW*:*)
-	GUESS=$UNAME_MACHINE-pc-mingw32
-	;;
+	echo "$UNAME_MACHINE"-pc-mingw32
+	exit ;;
     *:MSYS*:*)
-	GUESS=$UNAME_MACHINE-pc-msys
-	;;
+	echo "$UNAME_MACHINE"-pc-msys
+	exit ;;
     i*:PW*:*)
-	GUESS=$UNAME_MACHINE-pc-pw32
-	;;
-    *:SerenityOS:*:*)
-        GUESS=$UNAME_MACHINE-pc-serenity
-        ;;
+	echo "$UNAME_MACHINE"-pc-pw32
+	exit ;;
     *:Interix*:*)
-	case $UNAME_MACHINE in
+	case "$UNAME_MACHINE" in
 	    x86)
-		GUESS=i586-pc-interix$UNAME_RELEASE
-		;;
+		echo i586-pc-interix"$UNAME_RELEASE"
+		exit ;;
 	    authenticamd | genuineintel | EM64T)
-		GUESS=x86_64-unknown-interix$UNAME_RELEASE
-		;;
+		echo x86_64-unknown-interix"$UNAME_RELEASE"
+		exit ;;
 	    IA64)
-		GUESS=ia64-unknown-interix$UNAME_RELEASE
-		;;
+		echo ia64-unknown-interix"$UNAME_RELEASE"
+		exit ;;
 	esac ;;
     i*:UWIN*:*)
-	GUESS=$UNAME_MACHINE-pc-uwin
-	;;
+	echo "$UNAME_MACHINE"-pc-uwin
+	exit ;;
     amd64:CYGWIN*:*:* | x86_64:CYGWIN*:*:*)
-	GUESS=x86_64-pc-cygwin
-	;;
+	echo x86_64-unknown-cygwin
+	exit ;;
     prep*:SunOS:5.*:*)
-	SUN_REL=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'`
-	GUESS=powerpcle-unknown-solaris2$SUN_REL
-	;;
+	echo powerpcle-unknown-solaris2"`echo "$UNAME_RELEASE"|sed -e 's/[^.]*//'`"
+	exit ;;
     *:GNU:*:*)
 	# the GNU system
-	GNU_ARCH=`echo "$UNAME_MACHINE" | sed -e 's,[-/].*$,,'`
-	GNU_REL=`echo "$UNAME_RELEASE" | sed -e 's,/.*$,,'`
-	GUESS=$GNU_ARCH-unknown-$LIBC$GNU_REL
-	;;
+	echo "`echo "$UNAME_MACHINE"|sed -e 's,[-/].*$,,'`-unknown-$LIBC`echo "$UNAME_RELEASE"|sed -e 's,/.*$,,'`"
+	exit ;;
     *:GNU/*:*:*)
 	# other systems with GNU libc and userland
-	GNU_SYS=`echo "$UNAME_SYSTEM" | sed 's,^[^/]*/,,' | tr "[:upper:]" "[:lower:]"`
-	GNU_REL=`echo "$UNAME_RELEASE" | sed -e 's/[-(].*//'`
-	GUESS=$UNAME_MACHINE-unknown-$GNU_SYS$GNU_REL-$LIBC
-	;;
-    *:Minix:*:*)
-	GUESS=$UNAME_MACHINE-unknown-minix
-	;;
+	echo "$UNAME_MACHINE-unknown-`echo "$UNAME_SYSTEM" | sed 's,^[^/]*/,,' | tr "[:upper:]" "[:lower:]"``echo "$UNAME_RELEASE"|sed -e 's/[-(].*//'`-$LIBC"
+	exit ;;
+    i*86:Minix:*:*)
+	echo "$UNAME_MACHINE"-pc-minix
+	exit ;;
     aarch64:Linux:*:*)
-	GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
-	;;
+	echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
+	exit ;;
     aarch64_be:Linux:*:*)
 	UNAME_MACHINE=aarch64_be
-	GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
-	;;
+	echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
+	exit ;;
     alpha:Linux:*:*)
-	case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' /proc/cpuinfo 2>/dev/null` in
+	case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in
 	  EV5)   UNAME_MACHINE=alphaev5 ;;
 	  EV56)  UNAME_MACHINE=alphaev56 ;;
 	  PCA56) UNAME_MACHINE=alphapca56 ;;
@@ -988,189 +916,147 @@
 	esac
 	objdump --private-headers /bin/sh | grep -q ld.so.1
 	if test "$?" = 0 ; then LIBC=gnulibc1 ; fi
-	GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
-	;;
-    arc:Linux:*:* | arceb:Linux:*:* | arc32:Linux:*:* | arc64:Linux:*:*)
-	GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
-	;;
+	echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
+	exit ;;
+    arc:Linux:*:* | arceb:Linux:*:*)
+	echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
+	exit ;;
     arm*:Linux:*:*)
-	set_cc_for_build
+	eval "$set_cc_for_build"
 	if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \
 	    | grep -q __ARM_EABI__
 	then
-	    GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
+	    echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
 	else
 	    if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \
 		| grep -q __ARM_PCS_VFP
 	    then
-		GUESS=$UNAME_MACHINE-unknown-linux-${LIBC}eabi
+		echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"eabi
 	    else
-		GUESS=$UNAME_MACHINE-unknown-linux-${LIBC}eabihf
+		echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"eabihf
 	    fi
 	fi
-	;;
+	exit ;;
     avr32*:Linux:*:*)
-	GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
-	;;
+	echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
+	exit ;;
     cris:Linux:*:*)
-	GUESS=$UNAME_MACHINE-axis-linux-$LIBC
-	;;
+	echo "$UNAME_MACHINE"-axis-linux-"$LIBC"
+	exit ;;
     crisv32:Linux:*:*)
-	GUESS=$UNAME_MACHINE-axis-linux-$LIBC
-	;;
+	echo "$UNAME_MACHINE"-axis-linux-"$LIBC"
+	exit ;;
     e2k:Linux:*:*)
-	GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
-	;;
+	echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
+	exit ;;
     frv:Linux:*:*)
-	GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
-	;;
+	echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
+	exit ;;
     hexagon:Linux:*:*)
-	GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
-	;;
+	echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
+	exit ;;
     i*86:Linux:*:*)
-	GUESS=$UNAME_MACHINE-pc-linux-$LIBC
-	;;
+	echo "$UNAME_MACHINE"-pc-linux-"$LIBC"
+	exit ;;
     ia64:Linux:*:*)
-	GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
-	;;
+	echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
+	exit ;;
     k1om:Linux:*:*)
-	GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
-	;;
-    loongarch32:Linux:*:* | loongarch64:Linux:*:* | loongarchx32:Linux:*:*)
-	GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
-	;;
+	echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
+	exit ;;
     m32r*:Linux:*:*)
-	GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
-	;;
+	echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
+	exit ;;
     m68*:Linux:*:*)
-	GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
-	;;
+	echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
+	exit ;;
     mips:Linux:*:* | mips64:Linux:*:*)
-	set_cc_for_build
-	IS_GLIBC=0
-	test x"${LIBC}" = xgnu && IS_GLIBC=1
+	eval "$set_cc_for_build"
 	sed 's/^	//' << EOF > "$dummy.c"
 	#undef CPU
-	#undef mips
-	#undef mipsel
-	#undef mips64
-	#undef mips64el
-	#if ${IS_GLIBC} && defined(_ABI64)
-	LIBCABI=gnuabi64
-	#else
-	#if ${IS_GLIBC} && defined(_ABIN32)
-	LIBCABI=gnuabin32
-	#else
-	LIBCABI=${LIBC}
-	#endif
-	#endif
-
-	#if ${IS_GLIBC} && defined(__mips64) && defined(__mips_isa_rev) && __mips_isa_rev>=6
-	CPU=mipsisa64r6
-	#else
-	#if ${IS_GLIBC} && !defined(__mips64) && defined(__mips_isa_rev) && __mips_isa_rev>=6
-	CPU=mipsisa32r6
-	#else
-	#if defined(__mips64)
-	CPU=mips64
-	#else
-	CPU=mips
-	#endif
-	#endif
-	#endif
-
+	#undef ${UNAME_MACHINE}
+	#undef ${UNAME_MACHINE}el
 	#if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL)
-	MIPS_ENDIAN=el
+	CPU=${UNAME_MACHINE}el
 	#else
 	#if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB)
-	MIPS_ENDIAN=
+	CPU=${UNAME_MACHINE}
 	#else
-	MIPS_ENDIAN=
+	CPU=
 	#endif
 	#endif
 EOF
-	cc_set_vars=`$CC_FOR_BUILD -E "$dummy.c" 2>/dev/null | grep '^CPU\|^MIPS_ENDIAN\|^LIBCABI'`
-	eval "$cc_set_vars"
-	test "x$CPU" != x && { echo "$CPU${MIPS_ENDIAN}-unknown-linux-$LIBCABI"; exit; }
+	eval "`$CC_FOR_BUILD -E "$dummy.c" 2>/dev/null | grep '^CPU'`"
+	test "x$CPU" != x && { echo "$CPU-unknown-linux-$LIBC"; exit; }
 	;;
     mips64el:Linux:*:*)
-	GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
-	;;
+	echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
+	exit ;;
     openrisc*:Linux:*:*)
-	GUESS=or1k-unknown-linux-$LIBC
-	;;
+	echo or1k-unknown-linux-"$LIBC"
+	exit ;;
     or32:Linux:*:* | or1k*:Linux:*:*)
-	GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
-	;;
+	echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
+	exit ;;
     padre:Linux:*:*)
-	GUESS=sparc-unknown-linux-$LIBC
-	;;
+	echo sparc-unknown-linux-"$LIBC"
+	exit ;;
     parisc64:Linux:*:* | hppa64:Linux:*:*)
-	GUESS=hppa64-unknown-linux-$LIBC
-	;;
+	echo hppa64-unknown-linux-"$LIBC"
+	exit ;;
     parisc:Linux:*:* | hppa:Linux:*:*)
 	# Look for CPU level
 	case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in
-	  PA7*) GUESS=hppa1.1-unknown-linux-$LIBC ;;
-	  PA8*) GUESS=hppa2.0-unknown-linux-$LIBC ;;
-	  *)    GUESS=hppa-unknown-linux-$LIBC ;;
+	  PA7*) echo hppa1.1-unknown-linux-"$LIBC" ;;
+	  PA8*) echo hppa2.0-unknown-linux-"$LIBC" ;;
+	  *)    echo hppa-unknown-linux-"$LIBC" ;;
 	esac
-	;;
+	exit ;;
     ppc64:Linux:*:*)
-	GUESS=powerpc64-unknown-linux-$LIBC
-	;;
+	echo powerpc64-unknown-linux-"$LIBC"
+	exit ;;
     ppc:Linux:*:*)
-	GUESS=powerpc-unknown-linux-$LIBC
-	;;
+	echo powerpc-unknown-linux-"$LIBC"
+	exit ;;
     ppc64le:Linux:*:*)
-	GUESS=powerpc64le-unknown-linux-$LIBC
-	;;
+	echo powerpc64le-unknown-linux-"$LIBC"
+	exit ;;
     ppcle:Linux:*:*)
-	GUESS=powerpcle-unknown-linux-$LIBC
-	;;
-    riscv32:Linux:*:* | riscv32be:Linux:*:* | riscv64:Linux:*:* | riscv64be:Linux:*:*)
-	GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
-	;;
+	echo powerpcle-unknown-linux-"$LIBC"
+	exit ;;
+    riscv32:Linux:*:* | riscv64:Linux:*:*)
+	echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
+	exit ;;
     s390:Linux:*:* | s390x:Linux:*:*)
-	GUESS=$UNAME_MACHINE-ibm-linux-$LIBC
-	;;
+	echo "$UNAME_MACHINE"-ibm-linux-"$LIBC"
+	exit ;;
     sh64*:Linux:*:*)
-	GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
-	;;
+	echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
+	exit ;;
     sh*:Linux:*:*)
-	GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
-	;;
+	echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
+	exit ;;
     sparc:Linux:*:* | sparc64:Linux:*:*)
-	GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
-	;;
+	echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
+	exit ;;
     tile*:Linux:*:*)
-	GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
-	;;
+	echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
+	exit ;;
     vax:Linux:*:*)
-	GUESS=$UNAME_MACHINE-dec-linux-$LIBC
-	;;
+	echo "$UNAME_MACHINE"-dec-linux-"$LIBC"
+	exit ;;
     x86_64:Linux:*:*)
-	set_cc_for_build
-	LIBCABI=$LIBC
-	if test "$CC_FOR_BUILD" != no_compiler_found; then
-	    if (echo '#ifdef __ILP32__'; echo IS_X32; echo '#endif') | \
-		(CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \
-		grep IS_X32 >/dev/null
-	    then
-		LIBCABI=${LIBC}x32
-	    fi
-	fi
-	GUESS=$UNAME_MACHINE-pc-linux-$LIBCABI
-	;;
+	echo "$UNAME_MACHINE"-pc-linux-"$LIBC"
+	exit ;;
     xtensa*:Linux:*:*)
-	GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
-	;;
+	echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
+	exit ;;
     i*86:DYNIX/ptx:4*:*)
 	# ptx 4.0 does uname -s correctly, with DYNIX/ptx in there.
 	# earlier versions are messed up and put the nodename in both
 	# sysname and nodename.
-	GUESS=i386-sequent-sysv4
-	;;
+	echo i386-sequent-sysv4
+	exit ;;
     i*86:UNIX_SV:4.2MP:2.*)
 	# Unixware is an offshoot of SVR4, but it has its own version
 	# number series starting with 2...
@@ -1177,36 +1063,36 @@
 	# I am not positive that other SVR4 systems won't match this,
 	# I just have to hope.  -- rms.
 	# Use sysv4.2uw... so that sysv4* matches it.
-	GUESS=$UNAME_MACHINE-pc-sysv4.2uw$UNAME_VERSION
-	;;
+	echo "$UNAME_MACHINE"-pc-sysv4.2uw"$UNAME_VERSION"
+	exit ;;
     i*86:OS/2:*:*)
 	# If we were able to find `uname', then EMX Unix compatibility
 	# is probably installed.
-	GUESS=$UNAME_MACHINE-pc-os2-emx
-	;;
+	echo "$UNAME_MACHINE"-pc-os2-emx
+	exit ;;
     i*86:XTS-300:*:STOP)
-	GUESS=$UNAME_MACHINE-unknown-stop
-	;;
+	echo "$UNAME_MACHINE"-unknown-stop
+	exit ;;
     i*86:atheos:*:*)
-	GUESS=$UNAME_MACHINE-unknown-atheos
-	;;
+	echo "$UNAME_MACHINE"-unknown-atheos
+	exit ;;
     i*86:syllable:*:*)
-	GUESS=$UNAME_MACHINE-pc-syllable
-	;;
+	echo "$UNAME_MACHINE"-pc-syllable
+	exit ;;
     i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.[02]*:*)
-	GUESS=i386-unknown-lynxos$UNAME_RELEASE
-	;;
+	echo i386-unknown-lynxos"$UNAME_RELEASE"
+	exit ;;
     i*86:*DOS:*:*)
-	GUESS=$UNAME_MACHINE-pc-msdosdjgpp
-	;;
+	echo "$UNAME_MACHINE"-pc-msdosdjgpp
+	exit ;;
     i*86:*:4.*:*)
 	UNAME_REL=`echo "$UNAME_RELEASE" | sed 's/\/MP$//'`
 	if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then
-		GUESS=$UNAME_MACHINE-univel-sysv$UNAME_REL
+		echo "$UNAME_MACHINE"-univel-sysv"$UNAME_REL"
 	else
-		GUESS=$UNAME_MACHINE-pc-sysv$UNAME_REL
+		echo "$UNAME_MACHINE"-pc-sysv"$UNAME_REL"
 	fi
-	;;
+	exit ;;
     i*86:*:5:[678]*)
 	# UnixWare 7.x, OpenUNIX and OpenServer 6.
 	case `/bin/uname -X | grep "^Machine"` in
@@ -1214,12 +1100,12 @@
 	    *Pentium)	     UNAME_MACHINE=i586 ;;
 	    *Pent*|*Celeron) UNAME_MACHINE=i686 ;;
 	esac
-	GUESS=$UNAME_MACHINE-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION}
-	;;
+	echo "$UNAME_MACHINE-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}{$UNAME_VERSION}"
+	exit ;;
     i*86:*:3.2:*)
 	if test -f /usr/options/cb.name; then
 		UNAME_REL=`sed -n 's/.*Version //p' </usr/options/cb.name`
-		GUESS=$UNAME_MACHINE-pc-isc$UNAME_REL
+		echo "$UNAME_MACHINE"-pc-isc"$UNAME_REL"
 	elif /bin/uname -X 2>/dev/null >/dev/null ; then
 		UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')`
 		(/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486
@@ -1229,11 +1115,11 @@
 			&& UNAME_MACHINE=i686
 		(/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \
 			&& UNAME_MACHINE=i686
-		GUESS=$UNAME_MACHINE-pc-sco$UNAME_REL
+		echo "$UNAME_MACHINE"-pc-sco"$UNAME_REL"
 	else
-		GUESS=$UNAME_MACHINE-pc-sysv32
+		echo "$UNAME_MACHINE"-pc-sysv32
 	fi
-	;;
+	exit ;;
     pc:*:*:*)
 	# Left here for compatibility:
 	# uname -m prints for DJGPP always 'pc', but it prints nothing about
@@ -1241,31 +1127,31 @@
 	# Note: whatever this is, it MUST be the same as what config.sub
 	# prints for the "djgpp" host, or else GDB configure will decide that
 	# this is a cross-build.
-	GUESS=i586-pc-msdosdjgpp
-	;;
+	echo i586-pc-msdosdjgpp
+	exit ;;
     Intel:Mach:3*:*)
-	GUESS=i386-pc-mach3
-	;;
+	echo i386-pc-mach3
+	exit ;;
     paragon:*:*:*)
-	GUESS=i860-intel-osf1
-	;;
+	echo i860-intel-osf1
+	exit ;;
     i860:*:4.*:*) # i860-SVR4
 	if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then
-	  GUESS=i860-stardent-sysv$UNAME_RELEASE    # Stardent Vistra i860-SVR4
+	  echo i860-stardent-sysv"$UNAME_RELEASE" # Stardent Vistra i860-SVR4
 	else # Add other i860-SVR4 vendors below as they are discovered.
-	  GUESS=i860-unknown-sysv$UNAME_RELEASE     # Unknown i860-SVR4
+	  echo i860-unknown-sysv"$UNAME_RELEASE"  # Unknown i860-SVR4
 	fi
-	;;
+	exit ;;
     mini*:CTIX:SYS*5:*)
 	# "miniframe"
-	GUESS=m68010-convergent-sysv
-	;;
+	echo m68010-convergent-sysv
+	exit ;;
     mc68k:UNIX:SYSTEM5:3.51m)
-	GUESS=m68k-convergent-sysv
-	;;
+	echo m68k-convergent-sysv
+	exit ;;
     M680?0:D-NIX:5.3:*)
-	GUESS=m68k-diab-dnix
-	;;
+	echo m68k-diab-dnix
+	exit ;;
     M68*:*:R3V[5678]*:*)
 	test -r /sysV68 && { echo 'm68k-motorola-sysv'; exit; } ;;
     3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0 | S7501*:*:4.0:3.0)
@@ -1290,153 +1176,149 @@
 	/bin/uname -p 2>/dev/null | /bin/grep pteron >/dev/null \
 	    && { echo i586-ncr-sysv4.3"$OS_REL"; exit; } ;;
     m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*)
-	GUESS=m68k-unknown-lynxos$UNAME_RELEASE
-	;;
+	echo m68k-unknown-lynxos"$UNAME_RELEASE"
+	exit ;;
     mc68030:UNIX_System_V:4.*:*)
-	GUESS=m68k-atari-sysv4
-	;;
+	echo m68k-atari-sysv4
+	exit ;;
     TSUNAMI:LynxOS:2.*:*)
-	GUESS=sparc-unknown-lynxos$UNAME_RELEASE
-	;;
+	echo sparc-unknown-lynxos"$UNAME_RELEASE"
+	exit ;;
     rs6000:LynxOS:2.*:*)
-	GUESS=rs6000-unknown-lynxos$UNAME_RELEASE
-	;;
+	echo rs6000-unknown-lynxos"$UNAME_RELEASE"
+	exit ;;
     PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.[02]*:*)
-	GUESS=powerpc-unknown-lynxos$UNAME_RELEASE
-	;;
+	echo powerpc-unknown-lynxos"$UNAME_RELEASE"
+	exit ;;
     SM[BE]S:UNIX_SV:*:*)
-	GUESS=mips-dde-sysv$UNAME_RELEASE
-	;;
+	echo mips-dde-sysv"$UNAME_RELEASE"
+	exit ;;
     RM*:ReliantUNIX-*:*:*)
-	GUESS=mips-sni-sysv4
-	;;
+	echo mips-sni-sysv4
+	exit ;;
     RM*:SINIX-*:*:*)
-	GUESS=mips-sni-sysv4
-	;;
+	echo mips-sni-sysv4
+	exit ;;
     *:SINIX-*:*:*)
 	if uname -p 2>/dev/null >/dev/null ; then
 		UNAME_MACHINE=`(uname -p) 2>/dev/null`
-		GUESS=$UNAME_MACHINE-sni-sysv4
+		echo "$UNAME_MACHINE"-sni-sysv4
 	else
-		GUESS=ns32k-sni-sysv
+		echo ns32k-sni-sysv
 	fi
-	;;
+	exit ;;
     PENTIUM:*:4.0*:*)	# Unisys `ClearPath HMP IX 4000' SVR4/MP effort
 			# says <Richard.M.Bartel at ccMail.Census.GOV>
-	GUESS=i586-unisys-sysv4
-	;;
+	echo i586-unisys-sysv4
+	exit ;;
     *:UNIX_System_V:4*:FTX*)
 	# From Gerald Hewes <hewes at openmarket.com>.
 	# How about differentiating between stratus architectures? -djm
-	GUESS=hppa1.1-stratus-sysv4
-	;;
+	echo hppa1.1-stratus-sysv4
+	exit ;;
     *:*:*:FTX*)
 	# From seanf at swdc.stratus.com.
-	GUESS=i860-stratus-sysv4
-	;;
+	echo i860-stratus-sysv4
+	exit ;;
     i*86:VOS:*:*)
 	# From Paul.Green at stratus.com.
-	GUESS=$UNAME_MACHINE-stratus-vos
-	;;
+	echo "$UNAME_MACHINE"-stratus-vos
+	exit ;;
     *:VOS:*:*)
 	# From Paul.Green at stratus.com.
-	GUESS=hppa1.1-stratus-vos
-	;;
+	echo hppa1.1-stratus-vos
+	exit ;;
     mc68*:A/UX:*:*)
-	GUESS=m68k-apple-aux$UNAME_RELEASE
-	;;
+	echo m68k-apple-aux"$UNAME_RELEASE"
+	exit ;;
     news*:NEWS-OS:6*:*)
-	GUESS=mips-sony-newsos6
-	;;
+	echo mips-sony-newsos6
+	exit ;;
     R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*)
-	if test -d /usr/nec; then
-		GUESS=mips-nec-sysv$UNAME_RELEASE
+	if [ -d /usr/nec ]; then
+		echo mips-nec-sysv"$UNAME_RELEASE"
 	else
-		GUESS=mips-unknown-sysv$UNAME_RELEASE
+		echo mips-unknown-sysv"$UNAME_RELEASE"
 	fi
-	;;
+	exit ;;
     BeBox:BeOS:*:*)	# BeOS running on hardware made by Be, PPC only.
-	GUESS=powerpc-be-beos
-	;;
+	echo powerpc-be-beos
+	exit ;;
     BeMac:BeOS:*:*)	# BeOS running on Mac or Mac clone, PPC only.
-	GUESS=powerpc-apple-beos
-	;;
+	echo powerpc-apple-beos
+	exit ;;
     BePC:BeOS:*:*)	# BeOS running on Intel PC compatible.
-	GUESS=i586-pc-beos
-	;;
+	echo i586-pc-beos
+	exit ;;
     BePC:Haiku:*:*)	# Haiku running on Intel PC compatible.
-	GUESS=i586-pc-haiku
-	;;
+	echo i586-pc-haiku
+	exit ;;
     x86_64:Haiku:*:*)
-	GUESS=x86_64-unknown-haiku
-	;;
+	echo x86_64-unknown-haiku
+	exit ;;
     SX-4:SUPER-UX:*:*)
-	GUESS=sx4-nec-superux$UNAME_RELEASE
-	;;
+	echo sx4-nec-superux"$UNAME_RELEASE"
+	exit ;;
     SX-5:SUPER-UX:*:*)
-	GUESS=sx5-nec-superux$UNAME_RELEASE
-	;;
+	echo sx5-nec-superux"$UNAME_RELEASE"
+	exit ;;
     SX-6:SUPER-UX:*:*)
-	GUESS=sx6-nec-superux$UNAME_RELEASE
-	;;
+	echo sx6-nec-superux"$UNAME_RELEASE"
+	exit ;;
     SX-7:SUPER-UX:*:*)
-	GUESS=sx7-nec-superux$UNAME_RELEASE
-	;;
+	echo sx7-nec-superux"$UNAME_RELEASE"
+	exit ;;
     SX-8:SUPER-UX:*:*)
-	GUESS=sx8-nec-superux$UNAME_RELEASE
-	;;
+	echo sx8-nec-superux"$UNAME_RELEASE"
+	exit ;;
     SX-8R:SUPER-UX:*:*)
-	GUESS=sx8r-nec-superux$UNAME_RELEASE
-	;;
+	echo sx8r-nec-superux"$UNAME_RELEASE"
+	exit ;;
     SX-ACE:SUPER-UX:*:*)
-	GUESS=sxace-nec-superux$UNAME_RELEASE
-	;;
+	echo sxace-nec-superux"$UNAME_RELEASE"
+	exit ;;
     Power*:Rhapsody:*:*)
-	GUESS=powerpc-apple-rhapsody$UNAME_RELEASE
-	;;
+	echo powerpc-apple-rhapsody"$UNAME_RELEASE"
+	exit ;;
     *:Rhapsody:*:*)
-	GUESS=$UNAME_MACHINE-apple-rhapsody$UNAME_RELEASE
-	;;
-    arm64:Darwin:*:*)
-	GUESS=aarch64-apple-darwin$UNAME_RELEASE
-	;;
+	echo "$UNAME_MACHINE"-apple-rhapsody"$UNAME_RELEASE"
+	exit ;;
     *:Darwin:*:*)
-	UNAME_PROCESSOR=`uname -p`
-	case $UNAME_PROCESSOR in
-	    unknown) UNAME_PROCESSOR=powerpc ;;
-	esac
-	if command -v xcode-select > /dev/null 2> /dev/null && \
-		! xcode-select --print-path > /dev/null 2> /dev/null ; then
-	    # Avoid executing cc if there is no toolchain installed as
-	    # cc will be a stub that puts up a graphical alert
-	    # prompting the user to install developer tools.
-	    CC_FOR_BUILD=no_compiler_found
-	else
-	    set_cc_for_build
+	UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown
+	eval "$set_cc_for_build"
+	if test "$UNAME_PROCESSOR" = unknown ; then
+	    UNAME_PROCESSOR=powerpc
 	fi
-	if test "$CC_FOR_BUILD" != no_compiler_found; then
-	    if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \
-		   (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \
-		   grep IS_64BIT_ARCH >/dev/null
-	    then
-		case $UNAME_PROCESSOR in
-		    i386) UNAME_PROCESSOR=x86_64 ;;
-		    powerpc) UNAME_PROCESSOR=powerpc64 ;;
-		esac
+	if test "`echo "$UNAME_RELEASE" | sed -e 's/\..*//'`" -le 10 ; then
+	    if [ "$CC_FOR_BUILD" != no_compiler_found ]; then
+		if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \
+		       (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \
+		       grep IS_64BIT_ARCH >/dev/null
+		then
+		    case $UNAME_PROCESSOR in
+			i386) UNAME_PROCESSOR=x86_64 ;;
+			powerpc) UNAME_PROCESSOR=powerpc64 ;;
+		    esac
+		fi
+		# On 10.4-10.6 one might compile for PowerPC via gcc -arch ppc
+		if (echo '#ifdef __POWERPC__'; echo IS_PPC; echo '#endif') | \
+		       (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \
+		       grep IS_PPC >/dev/null
+		then
+		    UNAME_PROCESSOR=powerpc
+		fi
 	    fi
-	    # On 10.4-10.6 one might compile for PowerPC via gcc -arch ppc
-	    if (echo '#ifdef __POWERPC__'; echo IS_PPC; echo '#endif') | \
-		   (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \
-		   grep IS_PPC >/dev/null
-	    then
-		UNAME_PROCESSOR=powerpc
-	    fi
 	elif test "$UNAME_PROCESSOR" = i386 ; then
-	    # uname -m returns i386 or x86_64
-	    UNAME_PROCESSOR=$UNAME_MACHINE
+	    # Avoid executing cc on OS X 10.9, as it ships with a stub
+	    # that puts up a graphical alert prompting to install
+	    # developer tools.  Any system running Mac OS X 10.7 or
+	    # later (Darwin 11 and later) is required to have a 64-bit
+	    # processor. This is not true of the ARM version of Darwin
+	    # that Apple uses in portable devices.
+	    UNAME_PROCESSOR=x86_64
 	fi
-	GUESS=$UNAME_PROCESSOR-apple-darwin$UNAME_RELEASE
-	;;
+	echo "$UNAME_PROCESSOR"-apple-darwin"$UNAME_RELEASE"
+	exit ;;
     *:procnto*:*:* | *:QNX:[0123456789]*:*)
 	UNAME_PROCESSOR=`uname -p`
 	if test "$UNAME_PROCESSOR" = x86; then
@@ -1443,147 +1325,156 @@
 		UNAME_PROCESSOR=i386
 		UNAME_MACHINE=pc
 	fi
-	GUESS=$UNAME_PROCESSOR-$UNAME_MACHINE-nto-qnx$UNAME_RELEASE
-	;;
+	echo "$UNAME_PROCESSOR"-"$UNAME_MACHINE"-nto-qnx"$UNAME_RELEASE"
+	exit ;;
     *:QNX:*:4*)
-	GUESS=i386-pc-qnx
-	;;
+	echo i386-pc-qnx
+	exit ;;
     NEO-*:NONSTOP_KERNEL:*:*)
-	GUESS=neo-tandem-nsk$UNAME_RELEASE
-	;;
+	echo neo-tandem-nsk"$UNAME_RELEASE"
+	exit ;;
     NSE-*:NONSTOP_KERNEL:*:*)
-	GUESS=nse-tandem-nsk$UNAME_RELEASE
-	;;
+	echo nse-tandem-nsk"$UNAME_RELEASE"
+	exit ;;
     NSR-*:NONSTOP_KERNEL:*:*)
-	GUESS=nsr-tandem-nsk$UNAME_RELEASE
-	;;
+	echo nsr-tandem-nsk"$UNAME_RELEASE"
+	exit ;;
     NSV-*:NONSTOP_KERNEL:*:*)
-	GUESS=nsv-tandem-nsk$UNAME_RELEASE
-	;;
+	echo nsv-tandem-nsk"$UNAME_RELEASE"
+	exit ;;
     NSX-*:NONSTOP_KERNEL:*:*)
-	GUESS=nsx-tandem-nsk$UNAME_RELEASE
-	;;
+	echo nsx-tandem-nsk"$UNAME_RELEASE"
+	exit ;;
     *:NonStop-UX:*:*)
-	GUESS=mips-compaq-nonstopux
-	;;
+	echo mips-compaq-nonstopux
+	exit ;;
     BS2000:POSIX*:*:*)
-	GUESS=bs2000-siemens-sysv
-	;;
+	echo bs2000-siemens-sysv
+	exit ;;
     DS/*:UNIX_System_V:*:*)
-	GUESS=$UNAME_MACHINE-$UNAME_SYSTEM-$UNAME_RELEASE
-	;;
+	echo "$UNAME_MACHINE"-"$UNAME_SYSTEM"-"$UNAME_RELEASE"
+	exit ;;
     *:Plan9:*:*)
 	# "uname -m" is not consistent, so use $cputype instead. 386
 	# is converted to i386 for consistency with other x86
 	# operating systems.
-	if test "${cputype-}" = 386; then
+	if test "$cputype" = 386; then
 	    UNAME_MACHINE=i386
-	elif test "x${cputype-}" != x; then
-	    UNAME_MACHINE=$cputype
+	else
+	    UNAME_MACHINE="$cputype"
 	fi
-	GUESS=$UNAME_MACHINE-unknown-plan9
-	;;
+	echo "$UNAME_MACHINE"-unknown-plan9
+	exit ;;
     *:TOPS-10:*:*)
-	GUESS=pdp10-unknown-tops10
-	;;
+	echo pdp10-unknown-tops10
+	exit ;;
     *:TENEX:*:*)
-	GUESS=pdp10-unknown-tenex
-	;;
+	echo pdp10-unknown-tenex
+	exit ;;
     KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*)
-	GUESS=pdp10-dec-tops20
-	;;
+	echo pdp10-dec-tops20
+	exit ;;
     XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*)
-	GUESS=pdp10-xkl-tops20
-	;;
+	echo pdp10-xkl-tops20
+	exit ;;
     *:TOPS-20:*:*)
-	GUESS=pdp10-unknown-tops20
-	;;
+	echo pdp10-unknown-tops20
+	exit ;;
     *:ITS:*:*)
-	GUESS=pdp10-unknown-its
-	;;
+	echo pdp10-unknown-its
+	exit ;;
     SEI:*:*:SEIUX)
-	GUESS=mips-sei-seiux$UNAME_RELEASE
-	;;
+	echo mips-sei-seiux"$UNAME_RELEASE"
+	exit ;;
     *:DragonFly:*:*)
-	DRAGONFLY_REL=`echo "$UNAME_RELEASE" | sed -e 's/[-(].*//'`
-	GUESS=$UNAME_MACHINE-unknown-dragonfly$DRAGONFLY_REL
-	;;
+	echo "$UNAME_MACHINE"-unknown-dragonfly"`echo "$UNAME_RELEASE"|sed -e 's/[-(].*//'`"
+	exit ;;
     *:*VMS:*:*)
 	UNAME_MACHINE=`(uname -p) 2>/dev/null`
-	case $UNAME_MACHINE in
-	    A*) GUESS=alpha-dec-vms ;;
-	    I*) GUESS=ia64-dec-vms ;;
-	    V*) GUESS=vax-dec-vms ;;
+	case "$UNAME_MACHINE" in
+	    A*) echo alpha-dec-vms ; exit ;;
+	    I*) echo ia64-dec-vms ; exit ;;
+	    V*) echo vax-dec-vms ; exit ;;
 	esac ;;
     *:XENIX:*:SysV)
-	GUESS=i386-pc-xenix
-	;;
+	echo i386-pc-xenix
+	exit ;;
     i*86:skyos:*:*)
-	SKYOS_REL=`echo "$UNAME_RELEASE" | sed -e 's/ .*$//'`
-	GUESS=$UNAME_MACHINE-pc-skyos$SKYOS_REL
-	;;
+	echo "$UNAME_MACHINE"-pc-skyos"`echo "$UNAME_RELEASE" | sed -e 's/ .*$//'`"
+	exit ;;
     i*86:rdos:*:*)
-	GUESS=$UNAME_MACHINE-pc-rdos
-	;;
-    i*86:Fiwix:*:*)
-	GUESS=$UNAME_MACHINE-pc-fiwix
-	;;
-    *:AROS:*:*)
-	GUESS=$UNAME_MACHINE-unknown-aros
-	;;
+	echo "$UNAME_MACHINE"-pc-rdos
+	exit ;;
+    i*86:AROS:*:*)
+	echo "$UNAME_MACHINE"-pc-aros
+	exit ;;
     x86_64:VMkernel:*:*)
-	GUESS=$UNAME_MACHINE-unknown-esx
-	;;
+	echo "$UNAME_MACHINE"-unknown-esx
+	exit ;;
     amd64:Isilon\ OneFS:*:*)
-	GUESS=x86_64-unknown-onefs
+	echo x86_64-unknown-onefs
+	exit ;;
+esac
+
+echo "$0: unable to guess system type" >&2
+
+case "$UNAME_MACHINE:$UNAME_SYSTEM" in
+    mips:Linux | mips64:Linux)
+	# If we got here on MIPS GNU/Linux, output extra information.
+	cat >&2 <<EOF
+
+NOTE: MIPS GNU/Linux systems require a C compiler to fully recognize
+the system type. Please install a C compiler and try again.
+EOF
 	;;
-    *:Unleashed:*:*)
-	GUESS=$UNAME_MACHINE-unknown-unleashed$UNAME_RELEASE
-	;;
 esac
 
-# Do we have a guess based on uname results?
-if test "x$GUESS" != x; then
-    echo "$GUESS"
-    exit
-fi
+cat >&2 <<EOF
 
-# No uname command or uname output not recognized.
-set_cc_for_build
-cat > "$dummy.c" <<EOF
-#ifdef _SEQUENT_
-#include <sys/types.h>
-#include <sys/utsname.h>
-#endif
-#if defined(ultrix) || defined(_ultrix) || defined(__ultrix) || defined(__ultrix__)
-#if defined (vax) || defined (__vax) || defined (__vax__) || defined(mips) || defined(__mips) || defined(__mips__) || defined(MIPS) || defined(__MIPS__)
-#include <signal.h>
-#if defined(_SIZE_T_) || defined(SIGLOST)
-#include <sys/utsname.h>
-#endif
-#endif
-#endif
-main ()
-{
-#if defined (sony)
-#if defined (MIPSEB)
-  /* BFD wants "bsd" instead of "newsos".  Perhaps BFD should be changed,
-     I don't know....  */
-  printf ("mips-sony-bsd\n"); exit (0);
-#else
-#include <sys/param.h>
-  printf ("m68k-sony-newsos%s\n",
-#ifdef NEWSOS4
-  "4"
-#else
-  ""
-#endif
-  ); exit (0);
-#endif
-#endif
+This script (version $timestamp), has failed to recognize the
+operating system you are using. If your script is old, overwrite *all*
+copies of config.guess and config.sub with the latest versions from:
 
-#if defined (NeXT)
-#if !defined (__ARCHITECTURE__)
+  https://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess
+and
+  https://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub
+
+If $0 has already been updated, send the following data and any
+information you think might be pertinent to config-patches at gnu.org to
+provide the necessary information to handle your system.
+
+config.guess timestamp = $timestamp
+
+uname -m = `(uname -m) 2>/dev/null || echo unknown`
+uname -r = `(uname -r) 2>/dev/null || echo unknown`
+uname -s = `(uname -s) 2>/dev/null || echo unknown`
+uname -v = `(uname -v) 2>/dev/null || echo unknown`
+
+/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null`
+/bin/uname -X     = `(/bin/uname -X) 2>/dev/null`
+
+hostinfo               = `(hostinfo) 2>/dev/null`
+/bin/universe          = `(/bin/universe) 2>/dev/null`
+/usr/bin/arch -k       = `(/usr/bin/arch -k) 2>/dev/null`
+/bin/arch              = `(/bin/arch) 2>/dev/null`
+/usr/bin/oslevel       = `(/usr/bin/oslevel) 2>/dev/null`
+/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null`
+
+UNAME_MACHINE = "$UNAME_MACHINE"
+UNAME_RELEASE = "$UNAME_RELEASE"
+UNAME_SYSTEM  = "$UNAME_SYSTEM"
+UNAME_VERSION = "$UNAME_VERSION"
+EOF
+
+exit 1
+
+# Local variables:
+# eval: (add-hook 'before-save-hook 'time-stamp)
+# time-stamp-start: "timestamp='"
+# time-stamp-format: "%:y-%02m-%02d"
+# time-stamp-end: "'"
+# End:
+CTURE__)
 #define __ARCHITECTURE__ "m68k"
 #endif
   int version;
@@ -1679,7 +1570,7 @@
 }
 EOF
 
-$CC_FOR_BUILD -o "$dummy" "$dummy.c" 2>/dev/null && SYSTEM_NAME=`"$dummy"` &&
+$CC_FOR_BUILD -o "$dummy" "$dummy.c" 2>/dev/null && SYSTEM_NAME=`$dummy` &&
 	{ echo "$SYSTEM_NAME"; exit; }
 
 # Apollos put the system type in the environment.
@@ -1687,7 +1578,7 @@
 
 echo "$0: unable to guess system type" >&2
 
-case $UNAME_MACHINE:$UNAME_SYSTEM in
+case "$UNAME_MACHINE:$UNAME_SYSTEM" in
     mips:Linux | mips64:Linux)
 	# If we got here on MIPS GNU/Linux, output extra information.
 	cat >&2 <<EOF
@@ -1704,18 +1595,10 @@
 operating system you are using. If your script is old, overwrite *all*
 copies of config.guess and config.sub with the latest versions from:
 
-  https://git.savannah.gnu.org/cgit/config.git/plain/config.guess
+  https://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess
 and
-  https://git.savannah.gnu.org/cgit/config.git/plain/config.sub
-EOF
+  https://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub
 
-our_year=`echo $timestamp | sed 's,-.*,,'`
-thisyear=`date +%Y`
-# shellcheck disable=SC2003
-script_age=`expr "$thisyear" - "$our_year"`
-if test "$script_age" -lt 3 ; then
-   cat >&2 <<EOF
-
 If $0 has already been updated, send the following data and any
 information you think might be pertinent to config-patches at gnu.org to
 provide the necessary information to handle your system.
@@ -1742,7 +1625,6 @@
 UNAME_SYSTEM  = "$UNAME_SYSTEM"
 UNAME_VERSION = "$UNAME_VERSION"
 EOF
-fi
 
 exit 1
 

Modified: trunk/Build/source/utils/asymptote/configure
===================================================================
--- trunk/Build/source/utils/asymptote/configure	2022-01-20 21:28:28 UTC (rev 61671)
+++ trunk/Build/source/utils/asymptote/configure	2022-01-20 21:32:08 UTC (rev 61672)
@@ -1,8 +1,8 @@
 #! /bin/sh
 # Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.69 for Asymptote 2.75.
+# Generated by GNU Autoconf 2.69 for Asymptote 2.76.
 #
-# Report bugs to <https://sourceforge.net/projects/asymptote>.
+# Report bugs to <https://github.com/vectorgraphics/asymptote/issues>.
 #
 #
 # Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc.
@@ -267,10 +267,11 @@
     $as_echo "$0: be upgraded to zsh 4.3.4 or later."
   else
     $as_echo "$0: Please tell bug-autoconf at gnu.org and
-$0: https://sourceforge.net/projects/asymptote about your
-$0: system, including any error possibly output before this
-$0: message. Then install a modern shell, or manually run
-$0: the script under such a shell if you do have one."
+$0: https://github.com/vectorgraphics/asymptote/issues
+$0: about your system, including any error possibly output
+$0: before this message. Then install a modern shell, or
+$0: manually run the script under such a shell if you do
+$0: have one."
   fi
   exit 1
 fi
@@ -580,9 +581,9 @@
 # Identity of this package.
 PACKAGE_NAME='Asymptote'
 PACKAGE_TARNAME='asymptote'
-PACKAGE_VERSION='2.75'
-PACKAGE_STRING='Asymptote 2.75'
-PACKAGE_BUGREPORT='https://sourceforge.net/projects/asymptote'
+PACKAGE_VERSION='2.76'
+PACKAGE_STRING='Asymptote 2.76'
+PACKAGE_BUGREPORT='https://github.com/vectorgraphics/asymptote/issues'
 PACKAGE_URL=''
 
 # Factoring default headers for most tests.
@@ -727,6 +728,7 @@
 enable_gc
 enable_gc_debug
 enable_gc_full_debug
+enable_threads
 enable_sigsegv
 enable_curl
 enable_readline
@@ -1302,7 +1304,7 @@
   # Omit some internal or obsolete options to make the list less imposing.
   # This message is too long to be a string in the A/UX 3.1 sh.
   cat <<_ACEOF
-\`configure' configures Asymptote 2.75 to adapt to many kinds of systems.
+\`configure' configures Asymptote 2.76 to adapt to many kinds of systems.
 
 Usage: $0 [OPTION]... [VAR=VALUE]...
 
@@ -1368,7 +1370,7 @@
 
 if test -n "$ac_init_help"; then
   case $ac_init_help in
-     short | recursive ) echo "Configuration of Asymptote 2.75:";;
+     short | recursive ) echo "Configuration of Asymptote 2.76:";;
    esac
   cat <<\_ACEOF
 
@@ -1383,6 +1385,7 @@
              [=PREFIX]    use Boehm garbage collector installed in PREFIX
   --enable-gc-debug       enable (slow) garbage collector debugging
   --enable-gc-full-debug  enable (very slow) garbage collector backtrace
+  --enable-threads[=yes]  enable POSIX threads
   --enable-sigsegv[=yes]  enable GNU Stack Overflow Handler
   --enable-curl[=yes]     enable libcurl and compile with optional URL support
   --enable-readline[=yes] enable GNU Readline Library
@@ -1423,7 +1426,7 @@
 Use these variables to override the choices made by `configure' or to help
 it to find libraries and programs with nonstandard names/locations.
 
-Report bugs to <https://sourceforge.net/projects/asymptote>.
+Report bugs to <https://github.com/vectorgraphics/asymptote/issues>.
 _ACEOF
 ac_status=$?
 fi
@@ -1486,7 +1489,7 @@
 test -n "$ac_init_help" && exit $ac_status
 if $ac_init_version; then
   cat <<\_ACEOF
-Asymptote configure 2.75
+Asymptote configure 2.76
 generated by GNU Autoconf 2.69
 
 Copyright (C) 2012 Free Software Foundation, Inc.
@@ -1839,9 +1842,9 @@
 $as_echo "$as_me: WARNING: $2:     section \"Present But Cannot Be Compiled\"" >&2;}
     { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5
 $as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;}
-( $as_echo "## --------------------------------------------------------- ##
-## Report this to https://sourceforge.net/projects/asymptote ##
-## --------------------------------------------------------- ##"
+( $as_echo "## ----------------------------------------------------------------- ##
+## Report this to https://github.com/vectorgraphics/asymptote/issues ##
+## ----------------------------------------------------------------- ##"
      ) | sed "s/^/$as_me: WARNING:     /" >&2
     ;;
 esac
@@ -2072,7 +2075,7 @@
 This file contains any messages produced by compilers while
 running configure, to aid debugging if configure makes a mistake.
 
-It was created by Asymptote $as_me 2.75, which was
+It was created by Asymptote $as_me 2.76, which was
 generated by GNU Autoconf 2.69.  Invocation command line was
 
   $ $0 $@
@@ -5941,7 +5944,6 @@
 GCPPLIB=
 INCL="-I."
 GCNAME="Boehm Garbage Collector"
-GCOPTIONS="--disable-shared"
 if test "x$ac_cv_use_gc" != "xno" ; then
    OPTIONS=$OPTIONS"-DUSEGC "
    case _$ac_cv_use_gc in
@@ -6199,7 +6201,16 @@
 fi
 
 
+GCOPTIONS="--disable-shared "
+# Check whether --enable-threads was given.
+if test "${enable_threads+set}" = set; then :
+  enableval=$enable_threads;
+fi
 
+
+if test "x$enable_threads" != "xno"; then
+
+
 ac_ext=c
 ac_cpp='$CPP $CPPFLAGS'
 ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
@@ -6594,6 +6605,9 @@
 ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
 
 
+else
+   GCOPTIONS=$GCOPTIONS"--disable-threads "
+fi
 
 # Check whether --enable-sigsegv was given.
 if test "${enable_sigsegv+set}" = set; then :
@@ -6756,7 +6770,7 @@
 
 LSPLIBS=
 LSPLIB=
-if test "x$enable_lsp" != "xno"; then
+if test "x$enable_lsp" != "xno" -a "x$enable_threads" != "xno"; then
   { $as_echo "$as_me:${as_lineno-$LINENO}: checking for opendir in -lboost_filesystem" >&5
 $as_echo_n "checking for opendir in -lboost_filesystem... " >&6; }
 if ${ac_cv_lib_boost_filesystem_opendir+:} false; then :
@@ -9464,7 +9478,7 @@
 # report actual input values of CONFIG_FILES etc. instead of their
 # values after options handling.
 ac_log="
-This file was extended by Asymptote $as_me 2.75, which was
+This file was extended by Asymptote $as_me 2.76, which was
 generated by GNU Autoconf 2.69.  Invocation command line was
 
   CONFIG_FILES    = $CONFIG_FILES
@@ -9520,13 +9534,13 @@
 Configuration headers:
 $config_headers
 
-Report bugs to <https://sourceforge.net/projects/asymptote>."
+Report bugs to <https://github.com/vectorgraphics/asymptote/issues>."
 
 _ACEOF
 cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
 ac_cs_version="\\
-Asymptote config.status 2.75
+Asymptote config.status 2.76
 configured by $0, generated by GNU Autoconf 2.69,
   with options \\"\$ac_cs_config\\"
 

Modified: trunk/Build/source/utils/asymptote/configure.ac
===================================================================
--- trunk/Build/source/utils/asymptote/configure.ac	2022-01-20 21:28:28 UTC (rev 61671)
+++ trunk/Build/source/utils/asymptote/configure.ac	2022-01-20 21:32:08 UTC (rev 61672)
@@ -3,7 +3,7 @@
 # this file.
 
 AC_PREREQ(2)
-AC_INIT([Asymptote],[2.75],[https://sourceforge.net/projects/asymptote])
+AC_INIT([Asymptote],[2.76],[https://github.com/vectorgraphics/asymptote/issues])
 VERSION=$PACKAGE_VERSION
 AC_SUBST(VERSION)
 m4_include([ax_pthread.m4])
@@ -174,7 +174,6 @@
 GCPPLIB=
 INCL="-I."
 GCNAME="Boehm Garbage Collector"
-GCOPTIONS="--disable-shared"
 if test "x$ac_cv_use_gc" != "xno" ; then
    OPTIONS=$OPTIONS"-DUSEGC "
    case _$ac_cv_use_gc in
@@ -266,8 +265,17 @@
 AC_MSG_ERROR([*** Please install libm on your system ***]))
 AC_CHECK_LIB([z], [deflate],,
 AC_MSG_ERROR([*** Please install libz or zlib-devel on your system ***]))
-AX_PTHREAD
 
+GCOPTIONS="--disable-shared "
+AC_ARG_ENABLE(threads,
+[AS_HELP_STRING(--enable-threads[[[=yes]]],enable POSIX threads)])
+
+if test "x$enable_threads" != "xno"; then
+   AX_PTHREAD
+else
+   GCOPTIONS=$GCOPTIONS"--disable-threads "
+fi
+
 AC_ARG_ENABLE(sigsegv,
 [AS_HELP_STRING(--enable-sigsegv[[[=yes]]],enable GNU Stack Overflow Handler)])
 
@@ -288,7 +296,7 @@
 
 LSPLIBS=
 LSPLIB=
-if test "x$enable_lsp" != "xno"; then
+if test "x$enable_lsp" != "xno" -a "x$enable_threads" != "xno"; then
   AC_CHECK_LIB([boost_filesystem],[opendir],
   [AC_CHECK_LIB([boost_thread],[pthread_attr_getdetachstate],
   [AC_DEFINE(HAVE_LSP,1,DEFINE([Language server protocol]))

Modified: trunk/Build/source/utils/asymptote/doc/CAD.pdf
===================================================================
(Binary files differ)

Modified: trunk/Build/source/utils/asymptote/doc/FAQ/asy-faq.info
===================================================================
--- trunk/Build/source/utils/asymptote/doc/FAQ/asy-faq.info	2022-01-20 21:28:28 UTC (rev 61671)
+++ trunk/Build/source/utils/asymptote/doc/FAQ/asy-faq.info	2022-01-20 21:32:08 UTC (rev 61672)
@@ -10,7 +10,7 @@
 File: asy-faq.info, Node: Top, Next: Question 1.1, Up: (dir)
 
             ASYMPTOTE FREQUENTLY ASKED QUESTIONS
-                            2022-01-06
+                            2022-01-20
                           
 This is the list of Frequently Asked Questions about Asymptote (asy).
 

Modified: trunk/Build/source/utils/asymptote/doc/TeXShopAndAsymptote.pdf
===================================================================
(Binary files differ)

Modified: trunk/Build/source/utils/asymptote/doc/asy-latex.pdf
===================================================================
(Binary files differ)

Modified: trunk/Build/source/utils/asymptote/doc/asyRefCard.pdf
===================================================================
(Binary files differ)

Modified: trunk/Build/source/utils/asymptote/doc/asymptote.pdf
===================================================================
(Binary files differ)

Modified: trunk/Build/source/utils/asymptote/doc/asymptote.texi
===================================================================
--- trunk/Build/source/utils/asymptote/doc/asymptote.texi	2022-01-20 21:28:28 UTC (rev 61671)
+++ trunk/Build/source/utils/asymptote/doc/asymptote.texi	2022-01-20 21:32:08 UTC (rev 61672)
@@ -8148,7 +8148,7 @@
 @item Alt Right: rotate about the Z axis
 @end itemize
 
-The keyboard shortcuts are:
+The keyboard bindings are:
 @cindex keyboard bindings:
 @itemize
 @item h: home
@@ -10106,9 +10106,10 @@
 contributors include Orest Shardt, Jesse Frohlich, Michail Vidiassov,
 Charles Staats, Philippe Ivaldi, Olivier Guib@'e, Radoslav Marinov,
 Jeff Samuelson, Chris Savage, Jacques Pienaar, Mark Henning, Steve Melenchuk,
-Martin Wiebusch, Stefan Knorr, and Supakorn ``Jamie'' Rassameemasmuang.
-Pedram Emami developed the @code{Asymptote Web Application}
-hosted at @url{http://asymptote.ualberta.ca}:
+Martin Wiebusch, Stefan Knorr, Supakorn ``Jamie'' Rassameemasmuang,
+Jacob Skitsko, Joseph Chaumont, and Oliver Cheng. Pedram Emami
+developed the @code{Asymptote Web Application} hosted at
+ at url{http://asymptote.ualberta.ca}:
 
 @url{https://github.com/vectorgraphics/asymptote-http-server}
 

Modified: trunk/Build/source/utils/asymptote/doc/png/asymptote.info
===================================================================
--- trunk/Build/source/utils/asymptote/doc/png/asymptote.info	2022-01-20 21:28:28 UTC (rev 61671)
+++ trunk/Build/source/utils/asymptote/doc/png/asymptote.info	2022-01-20 21:32:08 UTC (rev 61672)
@@ -1,7 +1,7 @@
 This is asymptote.info, produced by makeinfo version 6.7 from
 asymptote.texi.
 
-This file documents 'Asymptote', version 2.75.
+This file documents 'Asymptote', version 2.76.
 
    <https://asymptote.sourceforge.io>
 
@@ -22,7 +22,7 @@
 Asymptote
 *********
 
-This file documents 'Asymptote', version 2.75.
+This file documents 'Asymptote', version 2.76.
 
    <https://asymptote.sourceforge.io>
 
@@ -7034,7 +7034,7 @@
         * Ctrl Right: rotate about the Y axis
         * Alt Right: rotate about the Z axis
 
-     The keyboard shortcuts are:
+     The keyboard bindings are:
         * h: home
         * f: toggle fitscreen
         * x: spin about the X axis
@@ -8865,9 +8865,9 @@
 include Orest Shardt, Jesse Frohlich, Michail Vidiassov, Charles Staats,
 Philippe Ivaldi, Olivier Guibé, Radoslav Marinov, Jeff Samuelson, Chris
 Savage, Jacques Pienaar, Mark Henning, Steve Melenchuk, Martin Wiebusch,
-Stefan Knorr, and Supakorn "Jamie" Rassameemasmuang.  Pedram Emami
-developed the 'Asymptote Web Application' hosted at
-<http://asymptote.ualberta.ca>:
+Stefan Knorr, Supakorn "Jamie" Rassameemasmuang, Jacob Skitsko, Joseph
+Chaumont, and Oliver Cheng.  Pedram Emami developed the 'Asymptote Web
+Application' hosted at <http://asymptote.ualberta.ca>:
 
    <https://github.com/vectorgraphics/asymptote-http-server>
 
@@ -10624,36 +10624,36 @@
 Ref: penimage268751
 Ref: penfunctionimage269014
 Node: three269786
-Ref: PostScript3D300087
-Node: obj301825
-Node: graph3302074
-Ref: GaussianSurface307356
-Node: grid3308506
-Node: solids309291
-Node: tube310283
-Node: flowchart312513
-Node: contour317156
-Node: contour3323664
-Node: smoothcontour3323976
-Node: slopefield325695
-Node: ode327184
-Node: Options327441
-Ref: configuration file334936
-Ref: settings334936
-Ref: texengines336200
-Ref: convert336200
-Node: Interactive mode339643
-Ref: history341792
-Node: GUI343095
-Node: GUI installation343645
-Node: GUI usage344378
-Node: Command-Line Interface345441
-Node: Language server protocol346883
-Node: PostScript to Asymptote348308
-Node: Help349086
-Node: Debugger350760
-Node: Credits352516
-Node: Index353693
+Ref: PostScript3D300086
+Node: obj301824
+Node: graph3302073
+Ref: GaussianSurface307355
+Node: grid3308505
+Node: solids309290
+Node: tube310282
+Node: flowchart312512
+Node: contour317155
+Node: contour3323663
+Node: smoothcontour3323975
+Node: slopefield325694
+Node: ode327183
+Node: Options327440
+Ref: configuration file334935
+Ref: settings334935
+Ref: texengines336199
+Ref: convert336199
+Node: Interactive mode339642
+Ref: history341791
+Node: GUI343094
+Node: GUI installation343644
+Node: GUI usage344377
+Node: Command-Line Interface345440
+Node: Language server protocol346882
+Node: PostScript to Asymptote348307
+Node: Help349085
+Node: Debugger350759
+Node: Credits352515
+Node: Index353738
 
 End Tag Table
 

Modified: trunk/Build/source/utils/asymptote/drawsurface.h
===================================================================
--- trunk/Build/source/utils/asymptote/drawsurface.h	2022-01-20 21:28:28 UTC (rev 61671)
+++ trunk/Build/source/utils/asymptote/drawsurface.h	2022-01-20 21:32:08 UTC (rev 61672)
@@ -125,10 +125,10 @@
     double prerender=settings::getSetting<double>("prerender");
     if(prerender <= 0.0) return 0.0;
     prerender=1.0/prerender;
-    double perspective=gl::orthographic ? 0.0 : 1.0/gl::zmax;
+    double perspective=gl::orthographic ? 0.0 : 1.0/gl::Zmax;
     double s=perspective ? Min.getz()*perspective : 1.0; // Move to glrender
-    triple b(gl::xmin,gl::ymin,gl::zmin);
-    triple B(gl::xmax,gl::ymax,gl::zmax);
+    triple b(gl::Xmin,gl::Ymin,gl::Zmin);
+    triple B(gl::Xmax,gl::Ymax,gl::Zmax);
     pair size3(s*(B.getx()-b.getx()),s*(B.gety()-b.gety()));
     pair size2(gl::fullWidth,gl::fullHeight);
     return prerender*size3.length()/size2.length();

Added: trunk/Build/source/utils/asymptote/examples/twoSpheres.asy
===================================================================
--- trunk/Build/source/utils/asymptote/examples/twoSpheres.asy	                        (rev 0)
+++ trunk/Build/source/utils/asymptote/examples/twoSpheres.asy	2022-01-20 21:32:08 UTC (rev 61672)
@@ -0,0 +1,17 @@
+import three;
+import palette;
+
+size(20cm);
+
+currentprojection=orthographic(1,1,1);
+
+draw(box((-2,-2,-1),(2,2,1)));
+
+draw(shift(-Z)*surface(box((-2,-2),(2,2))),blue);
+draw(shift(Z)*surface(box((-2,-2),(2,2))),orange+opacity(0.5));
+
+surface s=unitsphere;
+s.colors(palette(s.map(zpart),Gradient(green+opacity(0.6),white,
+                                       green+opacity(0.6))));
+draw(shift(0.5X+0.5Y)*s);
+draw(shift(-0.5X-0.5Y)*s);

Modified: trunk/Build/source/utils/asymptote/glrender.cc
===================================================================
--- trunk/Build/source/utils/asymptote/glrender.cc	2022-01-20 21:28:28 UTC (rev 61671)
+++ trunk/Build/source/utils/asymptote/glrender.cc	2022-01-20 21:32:08 UTC (rev 61672)
@@ -202,12 +202,13 @@
 double Angle;
 bool orthographic;
 double H;
+
 double xmin,xmax;
 double ymin,ymax;
-double zmin,zmax;
 
 double Xmin,Xmax;
 double Ymin,Ymax;
+double Zmin,Zmax;
 
 pair Shift;
 pair Margin;
@@ -291,7 +292,7 @@
   double Aspect=((double) Width)/Height;
   double xshift=(X/Width+Shift.getx()*Xfactor)*Zoom;
   double yshift=(Y/Height+Shift.gety()*Yfactor)*Zoom;
-  double Zoominv=1.0/lastzoom;
+  double Zoominv=1.0/Zoom;
   if(orthographic) {
     double xsize=Xmax-Xmin;
     double ysize=Ymax-Ymin;
@@ -304,7 +305,7 @@
       ymin=Ymin*Zoominv-Y0;
       ymax=Ymax*Zoominv-Y0;
     } else {
-      double r=0.5*xsize/(Aspect*Zoom);
+      double r=0.5*xsize*Zoominv/Aspect;
       double X0=(Xmax-Xmin)*Zoominv*xshift;
       double Y0=2.0*r*yshift;
       xmin=Xmin*Zoominv-X0;
@@ -348,8 +349,8 @@
 void setProjection()
 {
   setDimensions(Width,Height,X,Y);
-  if(orthographic) ortho(xmin,xmax,ymin,ymax,-zmax,-zmin);
-  else frustum(xmin,xmax,ymin,ymax,-zmax,-zmin);
+  if(orthographic) ortho(xmin,xmax,ymin,ymax,-Zmax,-Zmin);
+  else frustum(xmin,xmax,ymin,ymax,-Zmax,-Zmin);
 }
 
 void updateModelViewData()
@@ -401,10 +402,10 @@
   framecount=0;
 }
 
+double T[16];
+
 #ifdef HAVE_GL
 
-double T[16];
-
 #ifdef HAVE_LIBGLUT
 timeval lasttime;
 timeval lastframetime;
@@ -703,9 +704,9 @@
 
   glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
 
-  triple m(xmin,ymin,zmin);
-  triple M(xmax,ymax,zmax);
-  double perspective=orthographic ? 0.0 : 1.0/zmax;
+  triple m(xmin,ymin,Zmin);
+  triple M(xmax,ymax,Zmax);
+  double perspective=orthographic ? 0.0 : 1.0/Zmax;
 
   double size2=hypot(Width,Height);
 
@@ -753,7 +754,7 @@
       trImageBuffer(tr,GL_RGB,GL_UNSIGNED_BYTE,data);
 
       setDimensions(fullWidth,fullHeight,X/Width*fullWidth,Y/Width*fullWidth);
-      (orthographic ? trOrtho : trFrustum)(tr,xmin,xmax,ymin,ymax,-zmax,-zmin);
+      (orthographic ? trOrtho : trFrustum)(tr,xmin,xmax,ymin,ymax,-Zmax,-Zmin);
 
       size_t count=0;
       do {
@@ -1109,9 +1110,8 @@
   Animate=getSetting<bool>("autoplay");
   glutShowWindow();
   if(Zoom != lastzoom) remesh=true;
-
   lastzoom=Zoom;
-  double cz=0.5*(zmin+zmax);
+  double cz=0.5*(Zmin+Zmax);
 
   dviewMat=translate(translate(dmat4(1.0),dvec3(cx,cy,cz))*drotateMat,
                      dvec3(0,0,-cz));
@@ -1268,7 +1268,7 @@
   if(x != x0 || y != y0) {
     arcball A(glx(x0),gly(y0),glx(x),gly(y));
     triple v=A.axis;
-    drotateMat=glm::rotate<double>(2*A.angle/lastzoom*ArcballFactor,
+    drotateMat=glm::rotate<double>(2*A.angle/Zoom*ArcballFactor,
                                    glm::dvec3(v.getx(),v.gety(),v.getz()))*
       drotateMat;
     x0=x; y0=y;
@@ -1634,7 +1634,7 @@
 
   camp::Triple vCamera,vUp,vTarget;
 
-  double cz=0.5*(zmin+zmax);
+  double cz=0.5*(Zmin+Zmax);
 
   double *Rotate=value_ptr(drotateMat);
 
@@ -1803,11 +1803,11 @@
   Xmax=M.getx();
   Ymin=m.gety();
   Ymax=M.gety();
-  zmin=m.getz();
-  zmax=M.getz();
+  Zmin=m.getz();
+  Zmax=M.getz();
 
   orthographic=Angle == 0.0;
-  H=orthographic ? 0.0 : -tan(0.5*Angle)*zmax;
+  H=orthographic ? 0.0 : -tan(0.5*Angle)*Zmax;
 
   ignorezoom=false;
   Xfactor=Yfactor=1.0;
@@ -1850,6 +1850,9 @@
 #endif
 #endif
 
+  for(int i=0; i < 16; ++i)
+    T[i]=t[i];
+
   static bool initialized=false;
 
   if(!(initialized && (interact::interactive ||
@@ -1913,9 +1916,6 @@
     ArcballFactor=1+8.0*hypot(Margin.getx(),Margin.gety())/hypot(Width,Height);
 
 #ifdef HAVE_GL
-    for(int i=0; i < 16; ++i)
-      T[i]=t[i];
-
     Aspect=((double) Width)/Height;
 
     if(maxTileWidth <= 0) maxTileWidth=screenWidth;

Modified: trunk/Build/source/utils/asymptote/glrender.h
===================================================================
--- trunk/Build/source/utils/asymptote/glrender.h	2022-01-20 21:28:28 UTC (rev 61671)
+++ trunk/Build/source/utils/asymptote/glrender.h	2022-01-20 21:32:08 UTC (rev 61672)
@@ -115,9 +115,16 @@
 extern bool wireframeMode;
 
 extern bool orthographic;
+
+// 2D bounds
 extern double xmin,xmax;
 extern double ymin,ymax;
-extern double zmin,zmax;
+
+// 3D bounds
+extern double Xmin,Xmax;
+extern double Ymin,Ymax;
+extern double Zmin,Zmax;
+
 extern int fullWidth,fullHeight;
 extern double Zoom0;
 extern double Angle;
@@ -166,6 +173,7 @@
 extern const double *dView;
 
 extern double BBT[9];
+extern double T[16];
 
 extern bool format3dWait;
 

Modified: trunk/Build/source/utils/asymptote/interact.cc
===================================================================
--- trunk/Build/source/utils/asymptote/interact.cc	2022-01-20 21:28:28 UTC (rev 61671)
+++ trunk/Build/source/utils/asymptote/interact.cc	2022-01-20 21:32:08 UTC (rev 61672)
@@ -144,7 +144,7 @@
 void init_interactive()
 {
   if(getSetting<bool>("xasy")) tty=false;
-#if defined(HAVE_READLINE) && defined(HAVE_LIBCURSES)
+#if defined(HAVE_LIBREADLINE) && defined(HAVE_LIBCURSES)
   if(tty) {
     init_completion();
     interact::init_readline(getSetting<bool>("tabcompletion"));
@@ -186,7 +186,7 @@
 }
 
 void addToHistory(string line) {
-#if defined(HAVE_READLINE) && defined(HAVE_LIBCURSES)
+#if defined(HAVE_LIBREADLINE) && defined(HAVE_LIBCURSES)
   // Only add it if it has something other than newlines.
   if(tty && line.find_first_not_of('\n') != string::npos) {
     add_history(line.c_str());
@@ -210,7 +210,7 @@
 }
 
 void setLastHistoryLine(string line) {
-#if defined(HAVE_READLINE) && defined(HAVE_LIBCURSES)
+#if defined(HAVE_LIBREADLINE) && defined(HAVE_LIBCURSES)
   if(tty) {
     if (history_length > 0) {
       HIST_ENTRY *entry=remove_history(history_length-1);
@@ -229,7 +229,7 @@
 }
 
 void deleteLastLine() {
-#if defined(HAVE_READLINE) && defined(HAVE_LIBCURSES)
+#if defined(HAVE_LIBREADLINE) && defined(HAVE_LIBCURSES)
   if(tty) {
     HIST_ENTRY *entry=remove_history(history_length-1);
     if(!entry) {
@@ -244,7 +244,7 @@
 }
 
 void cleanup_interactive() {
-#if defined(HAVE_READLINE) && defined(HAVE_LIBCURSES)
+#if defined(HAVE_LIBREADLINE) && defined(HAVE_LIBCURSES)
   // Write the history file.
   if(tty) {
     stifle_history(intcast(getSetting<Int>("historylines")));

Modified: trunk/Build/source/utils/asymptote/jsfile.cc
===================================================================
--- trunk/Build/source/utils/asymptote/jsfile.cc	2022-01-20 21:28:28 UTC (rev 61671)
+++ trunk/Build/source/utils/asymptote/jsfile.cc	2022-01-20 21:32:08 UTC (rev 61672)
@@ -8,6 +8,10 @@
 
 namespace camp {
 
+#ifndef HAVE_LIBGLM
+size_t materialIndex=0;
+#endif
+
 jsfile::jsfile() : finished(false), fileName("")
 {
 
@@ -97,10 +101,9 @@
   finished=true;
 }
 
-#ifdef HAVE_LIBGLM
-
 void jsfile::comment(string name)
 {
+#ifdef HAVE_LIBGLM
   out << "<!-- Use the following line to embed this file within another web page:" << newl
       << newl
       << "<iframe src=\"" << name
@@ -109,6 +112,7 @@
       << "\" frameborder=\"0\"></iframe>" << newl
       << newl
       << "-->" << newl << newl;
+#endif
 }
 
 void jsfile::open(string name)
@@ -117,6 +121,7 @@
   comment(name);
   meta(name,false);
 
+#ifdef HAVE_LIBGLM
   out.precision(getSetting<Int>("digits"));
 
   bool ibl=getSetting<bool>("ibl");
@@ -148,9 +153,9 @@
     out << "image=\"" << getSetting<string>("image") << "\";" << newl << newl;
   }
   out << newl
-      <<  "minBound=[" << gl::xmin << "," << gl::ymin << "," << gl::zmin << "];"
+      <<  "minBound=[" << gl::Xmin << "," << gl::Ymin << "," << gl::Zmin << "];"
       << newl
-      <<  "maxBound=[" << gl::xmax << "," << gl::ymax << "," << gl::zmax << "];"
+      <<  "maxBound=[" << gl::Xmax << "," << gl::Ymax << "," << gl::Zmax << "];"
       << newl
       << "orthographic=" << gl::orthographic << ";"
       << newl
@@ -183,13 +188,19 @@
   out << "Background=[" << gl::Background[0] << "," << gl::Background[1] << ","
       << gl::Background[2] << "," << gl::Background[3] << "];"
       << newl << newl;
+  out << "Transform=[" << gl::T[0];
+  for(int i=1; i < 16; ++i)
+    out << "," << newl << gl::T[i];
+  out << "];" << newl << newl;
 
   camp::clearCenters();
   camp::clearMaterials();
+#endif
 }
 
 void jsfile::finish(string name)
 {
+#ifdef HAVE_LIBGLM
   finished=true;
   size_t ncenters=drawElement::centers.size();
   if(ncenters > 0) {
@@ -206,6 +217,7 @@
       << "\" style=\"border: none; cursor: pointer;\">"
       << newl << "</canvas>";
   footer(name);
+#endif
 }
 
 void jsfile::addColor(const prc::RGBAColour& c)
@@ -273,6 +285,7 @@
       << newl << newl;
 }
 
+#ifdef HAVE_LIBGLM
 void jsfile::addMaterial(Material const& material)
 {
   out << "material(" << newl
@@ -279,6 +292,7 @@
       << material
       << ");" << newl << newl;
 }
+#endif
 
 void jsfile::addTriangles(size_t nP, const triple* P, size_t nN,
                           const triple* N, size_t nC, const prc::RGBAColour* C,
@@ -400,6 +414,4 @@
   addRawPatch(controls,3,Min,Max,c,3);
 }
 
-#endif
-
 }

Modified: trunk/Build/source/utils/asymptote/jsfile.h
===================================================================
--- trunk/Build/source/utils/asymptote/jsfile.h	2022-01-20 21:28:28 UTC (rev 61671)
+++ trunk/Build/source/utils/asymptote/jsfile.h	2022-01-20 21:32:08 UTC (rev 61672)
@@ -44,7 +44,9 @@
   void addTube(const triple *g, double width,
                const triple& Min, const triple& Max, bool core) override;
 
+#ifdef HAVE_LIBGLM
   void addMaterial(Material const& mat) override;
+#endif
 
   void addSphere(triple const& center, double radius) override;
 
@@ -63,9 +65,7 @@
 
 
   void svgtohtml(string name);
-#ifdef HAVE_LIBGLM
   void precision(int digits) override {out.precision(digits);}
-#endif
 
 protected:
   void copy(string name, bool header=false);
@@ -76,7 +76,6 @@
 
 
 
-#ifdef HAVE_LIBGLM
   void open(string name);
   void comment(string name);
 
@@ -88,11 +87,9 @@
   void addSphere(const triple& center, double radius, bool half=false,
                  const double& polar=0.0, const double& azimuth=0.0);
 
-
 private:
   bool finished;
   string fileName;
-#endif
 };
 
 } //namespace camp

Modified: trunk/Build/source/utils/asymptote/lspserv.cc
===================================================================
--- trunk/Build/source/utils/asymptote/lspserv.cc	2022-01-20 21:28:28 UTC (rev 61671)
+++ trunk/Build/source/utils/asymptote/lspserv.cc	2022-01-20 21:32:08 UTC (rev 61672)
@@ -87,6 +87,9 @@
     bool isMntPath=false;
     char drive;
 
+#ifdef __GNU__
+#define PATH_MAX 4096
+#endif
     char actPath[PATH_MAX];
     (void) realpath(unixPath.c_str(), actPath);
     std::string fullPath(actPath);
@@ -301,7 +304,7 @@
 
   void AsymptoteLspServer::onInitialized(Notify_InitializedNotification::notify& notify)
   {
-    logInfo("server initalized notification");
+    logInfo("server initialized notification");
   }
 
   void AsymptoteLspServer::onExit(Notify_Exit::notify& notify)

Modified: trunk/Build/source/utils/asymptote/main.cc
===================================================================
--- trunk/Build/source/utils/asymptote/main.cc	2022-01-20 21:28:28 UTC (rev 61671)
+++ trunk/Build/source/utils/asymptote/main.cc	2022-01-20 21:32:08 UTC (rev 61672)
@@ -195,7 +195,8 @@
         string name=(getArg(ind));
         if(name == stripExt(name)+".v3d") {
           interact::uptodate=false;
-          runString("import v3d; importv3d(\""+name+"\");");
+          runString("import v3d; defaultfilename=\""+stripDir(name)+
+                    "\"; importv3d(\""+name+"\");");
         } else
           processFile(name,n > 1);
         try {

Modified: trunk/Build/source/utils/asymptote/material.h
===================================================================
--- trunk/Build/source/utils/asymptote/material.h	2022-01-20 21:28:28 UTC (rev 61671)
+++ trunk/Build/source/utils/asymptote/material.h	2022-01-20 21:32:08 UTC (rev 61672)
@@ -90,7 +90,7 @@
         << m.specular << "," << newl
         << m.parameters[0] << "," << newl
         << m.parameters[1] << "," << newl
-        << m.parameters[2] << newl;
+        << m.parameters[2];
     return out;
   }
 };

Modified: trunk/Build/source/utils/asymptote/patches/dvipdf
===================================================================
--- trunk/Build/source/utils/asymptote/patches/dvipdf	2022-01-20 21:28:28 UTC (rev 61671)
+++ trunk/Build/source/utils/asymptote/patches/dvipdf	2022-01-20 21:32:08 UTC (rev 61672)
@@ -1,5 +1,4 @@
 #!/bin/sh
-# $Id$
 # Convert DVI to PDF.
 #
 # Please contact Andrew Ford <A.Ford at ford-mason.co.uk> with any questions
@@ -12,7 +11,7 @@
 GS_EXECUTABLE=gs
 
 
-OPTIONS="-DSAFER -P"
+OPTIONS=""
 DVIPSOPTIONS=""
 while true
 do
@@ -31,7 +30,7 @@
 done
 
 if [ $# -lt 1 -o $# -gt 2 ]; then
-	echo "Usage: `basename $0` [options...] input.dvi [output.pdf]" 1>&2
+	echo "Usage: `basename \"$0\"` [options...] input.dvi [output.pdf]" 1>&2
 	exit 1
 fi
 
@@ -50,5 +49,4 @@
 
 # We have to include the options twice because -I only takes effect if it
 # appears before other options.
-exec dvips $DVIPSOPTIONS -q -f "$infile" | $GS_EXECUTABLE $OPTIONS -q -dNOPAUSE -dBATCH -sDEVICE=pdfwrite -sstdout=%stderr -sOutputFile="$outfile" $OPTIONS -c .setpdfwrite -
-
+exec dvips -Ppdf $DVIPSOPTIONS -q -f "$infile" | $GS_EXECUTABLE $OPTIONS -q -P- -dSAFER -dNOPAUSE -dBATCH -sDEVICE=pdfwrite -sstdout=%stderr -sOutputFile="$outfile" $OPTIONS -

Modified: trunk/Build/source/utils/asymptote/picture.cc
===================================================================
--- trunk/Build/source/utils/asymptote/picture.cc	2022-01-20 21:28:28 UTC (rev 61671)
+++ trunk/Build/source/utils/asymptote/picture.cc	2022-01-20 21:32:08 UTC (rev 61672)
@@ -973,6 +973,11 @@
     else htmlformat=false;
   }
 
+#ifndef HAVE_LIBGLM
+  if(outputformat == "v3d")
+    camp::reportError("to support V3 rendering, please install glm header files, run ./configure, and recompile");
+#endif
+
   bool svgformat=outputformat == "svg";
   bool png=outputformat == "png";
 
@@ -1356,7 +1361,6 @@
   bool webgl=format == "html";
 
 #ifndef HAVE_LIBGLM
-  if(webgl)
     camp::reportError("to support WebGL rendering, please install glm header files, run ./configure, and recompile");
 #endif
 
@@ -1501,7 +1505,9 @@
 #ifdef HAVE_GL
     if(format3dWait) {
       gl::format3dWait=false;
+#ifdef HAVE_PTHREAD
       endwait(initSignal,initLock);
+#endif
     }
 #endif
 

Modified: trunk/Build/source/utils/asymptote/revision.cc
===================================================================
--- trunk/Build/source/utils/asymptote/revision.cc	2022-01-20 21:28:28 UTC (rev 61671)
+++ trunk/Build/source/utils/asymptote/revision.cc	2022-01-20 21:32:08 UTC (rev 61672)
@@ -1,2 +1,2 @@
-const char *REVISION="2.75";
+const char *REVISION="2.76";
 const char *AsyGLVersion="1.01";

Modified: trunk/Build/source/utils/asymptote/settings.cc
===================================================================
--- trunk/Build/source/utils/asymptote/settings.cc	2022-01-20 21:28:28 UTC (rev 61671)
+++ trunk/Build/source/utils/asymptote/settings.cc	2022-01-20 21:32:08 UTC (rev 61672)
@@ -957,6 +957,7 @@
     bool editline=false;
     bool sigsegv=false;
     bool usegc=false;
+    bool usethreads=false;
 
 #if HAVE_LIBGLM
     glm=true;
@@ -1008,6 +1009,11 @@
     usegc=true;
 #endif
 
+#ifdef HAVE_PTHREAD
+    usethreads=true;
+#endif
+
+    feature("V3D      3D vector graphics output",glm && xdr);
     feature("WebGL    3D HTML rendering",glm);
 #ifdef HAVE_LIBOSMESA
     feature("OpenGL   3D OSMesa offscreen rendering",gl);
@@ -1026,6 +1032,7 @@
     feature("Sigsegv  Distinguish stack overflows from segmentation faults",
             sigsegv);
     feature("GC       Boehm garbage collector",usegc);
+    feature("threads  Render OpenGL in separate thread",usethreads);
   }
 
   bool getOption() {

Modified: trunk/Build/source/utils/asymptote/symbol.h
===================================================================
--- trunk/Build/source/utils/asymptote/symbol.h	2022-01-20 21:28:28 UTC (rev 61671)
+++ trunk/Build/source/utils/asymptote/symbol.h	2022-01-20 21:32:08 UTC (rev 61672)
@@ -29,8 +29,10 @@
     GC_set_free_space_divisor(2);
     mem::compact(0);
     GC_INIT();
+#ifdef HAVE_PTHREAD
     GC_allow_register_threads();
 #endif
+#endif
 
     // Put the symbol table into a state where symbols can be translated.
     initTable();

Modified: trunk/Build/source/utils/asymptote/symbolmaps.h
===================================================================
--- trunk/Build/source/utils/asymptote/symbolmaps.h	2022-01-20 21:28:28 UTC (rev 61671)
+++ trunk/Build/source/utils/asymptote/symbolmaps.h	2022-01-20 21:32:08 UTC (rev 61672)
@@ -148,7 +148,7 @@
 
     SymbolInfo(SymbolInfo const& symInfo) = default;
 
-    SymbolInfo& operator=(SymbolInfo const& symInfo) noexcept = default;
+    SymbolInfo& operator=(SymbolInfo const& symInfo) = default;
 
     SymbolInfo(SymbolInfo&& symInfo) noexcept :
             name(std::move(symInfo.name)), type(std::move(symInfo.type)), pos(std::move(symInfo.pos))

Modified: trunk/Build/source/utils/asymptote/tinyexr.cc
===================================================================
--- trunk/Build/source/utils/asymptote/tinyexr.cc	2022-01-20 21:28:28 UTC (rev 61671)
+++ trunk/Build/source/utils/asymptote/tinyexr.cc	2022-01-20 21:32:08 UTC (rev 61672)
@@ -7,8 +7,17 @@
 
 #include <zlib.h>
 
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
 #define TINYEXR_IMPLEMENTATION
 #define TINYEXR_USE_MINIZ 0
+
+#ifdef HAVE_PTHREAD
 #define TINYEXR_USE_THREAD 1
+#else
+#define TINYEXR_USE_THREAD 0
+#endif
 
-#include "cudareflect/tinyexr/tinyexr.h"
\ No newline at end of file
+#include "cudareflect/tinyexr/tinyexr.h"

Modified: trunk/Build/source/utils/asymptote/v3dfile.cc
===================================================================
--- trunk/Build/source/utils/asymptote/v3dfile.cc	2022-01-20 21:28:28 UTC (rev 61671)
+++ trunk/Build/source/utils/asymptote/v3dfile.cc	2022-01-20 21:32:08 UTC (rev 61672)
@@ -10,6 +10,8 @@
 
 #ifdef HAVE_RPC_RPC_H
 
+#ifdef HAVE_LIBGLM
+
 #include "drawelement.h"
 #include "makeUnique.h"
 
@@ -36,8 +38,8 @@
   headers.emplace_back(make_unique<Uint32Header>(v3dheadertypes::canvasWidth, gl::fullWidth));
   headers.emplace_back(make_unique<Uint32Header>(v3dheadertypes::canvasHeight, gl::fullHeight));
   headers.emplace_back(make_unique<Uint32Header>(v3dheadertypes::absolute, getSetting<bool>("absolute")));
-  headers.emplace_back(make_unique<TripleHeader>(v3dheadertypes::minBound, triple(gl::xmin, gl::ymin, gl::zmin)));
-  headers.emplace_back(make_unique<TripleHeader>(v3dheadertypes::maxBound, triple(gl::xmax, gl::ymax, gl::zmax)));
+  headers.emplace_back(make_unique<TripleHeader>(v3dheadertypes::minBound, triple(gl::Xmin, gl::Ymin, gl::Zmin)));
+  headers.emplace_back(make_unique<TripleHeader>(v3dheadertypes::maxBound, triple(gl::Xmax, gl:: Ymax, gl::Zmax)));
   headers.emplace_back(make_unique<Uint32Header>(v3dheadertypes::orthographic, gl::orthographic));
   headers.emplace_back(make_unique<DoubleHeader>(v3dheadertypes::angleOfView, gl::Angle));
   headers.emplace_back(make_unique<DoubleHeader>(v3dheadertypes::initialZoom, gl::Zoom0));
@@ -351,3 +353,5 @@
 } //namespace camp
 
 #endif
+
+#endif

Modified: trunk/Build/source/utils/asymptote/v3dfile.h
===================================================================
--- trunk/Build/source/utils/asymptote/v3dfile.h	2022-01-20 21:28:28 UTC (rev 61671)
+++ trunk/Build/source/utils/asymptote/v3dfile.h	2022-01-20 21:32:08 UTC (rev 61672)
@@ -106,8 +106,9 @@
   void addStraightBezierTriangle(
           triple const* controls, triple const& Min, triple const& Max, prc::RGBAColour const* c) override;
 
-
+#ifdef HAVE_LIBGLM
   void addMaterial(Material const& mat) override;
+#endif
 
   void addSphere(triple const& center, double radius) override;
   void addHemisphere(triple const& center, double radius, double const& polar, double const& azimuth) override;
@@ -137,7 +138,10 @@
 
 
 protected:
+#ifdef HAVE_LIBGLM
   void addvec4(glm::vec4 const& vec);
+#endif
+
   void addCenterIndexMat();
   void addIndices(uint32_t const* trip);
   void addTriples(triple const* triples, size_t n);

Modified: trunk/Build/source/utils/asymptote/v3dheadertypes.csv
===================================================================
--- trunk/Build/source/utils/asymptote/v3dheadertypes.csv	2022-01-20 21:28:28 UTC (rev 61671)
+++ trunk/Build/source/utils/asymptote/v3dheadertypes.csv	2022-01-20 21:32:08 UTC (rev 61672)
@@ -1,10 +1,10 @@
 canvasWidth,1,UINT        # Canvas width
-canvasHeight,2,UINT       # Canvas height
+canvasHeight,2,UINT       # Canvas heighot
 absolute,3,BOOL           # true: absolute size; false: scale to canvas
 minBound,4,TRIPLE         # Scene minimum bounding box corners
 maxBound,5,TRIPLE         # Scene maximum bounding box corners
 orthographic,6,BOOL       # true: orthographic; false: perspective
-angleOfView,7,REAL        # Field of view angle
+angleOfView,7,REAL        # Field of view angle (in radians)
 initialZoom,8,REAL        # Initial zoom
 viewportShift,9,PAIR      # Viewport shift (for perspective projection)
 viewportMargin,10,PAIR    # Margin around viewport

Modified: trunk/Build/source/utils/asymptote/v3dheadertypes.h
===================================================================
--- trunk/Build/source/utils/asymptote/v3dheadertypes.h	2022-01-20 21:28:28 UTC (rev 61671)
+++ trunk/Build/source/utils/asymptote/v3dheadertypes.h	2022-01-20 21:32:08 UTC (rev 61672)
@@ -1,6 +1,6 @@
 // Enum class for v3dheadertypes
 // AUTO-GENERATED from v3dheadertypes.csv
-// Generated at 2022-01-06 15:00:10.552025
+// Generated at 2022-01-19 22:28:57.698357
 
 namespace camp
 {
@@ -10,7 +10,7 @@
 // UINT  Canvas width
 
 canvasHeight=2,
-// UINT  Canvas height
+// UINT  Canvas heighot
 
 absolute=3,
 // BOOL  true: absolute size; false: scale to canvas
@@ -25,7 +25,7 @@
 // BOOL  true: orthographic; false: perspective
 
 angleOfView=7,
-// REAL  Field of view angle
+// REAL  Field of view angle (in radians)
 
 initialZoom=8,
 // REAL  Initial zoom

Modified: trunk/Build/source/utils/asymptote/v3dheadertypes.py
===================================================================
--- trunk/Build/source/utils/asymptote/v3dheadertypes.py	2022-01-20 21:28:28 UTC (rev 61671)
+++ trunk/Build/source/utils/asymptote/v3dheadertypes.py	2022-01-20 21:32:08 UTC (rev 61672)
@@ -1,7 +1,7 @@
 #!/usr/bin/env python3
 # Enum class for v3dheadertypes
 """ AUTO-GENERATED from v3dheadertypes.csv """
-# Generated at 2022-01-06 15:01:16.537064
+# Generated at 2022-01-19 22:30:10.805644
 
 class v3dheadertypes:
     v3dheadertypes_canvasWidth=1
@@ -8,7 +8,7 @@
     # UINT  Canvas width
 
     v3dheadertypes_canvasHeight=2
-    # UINT  Canvas height
+    # UINT  Canvas heighot
 
     v3dheadertypes_absolute=3
     # BOOL  true: absolute size; false: scale to canvas
@@ -23,7 +23,7 @@
     # BOOL  true: orthographic; false: perspective
 
     v3dheadertypes_angleOfView=7
-    # REAL  Field of view angle
+    # REAL  Field of view angle (in radians)
 
     v3dheadertypes_initialZoom=8
     # REAL  Initial zoom

Modified: trunk/Build/source/utils/asymptote/v3dtypes.h
===================================================================
--- trunk/Build/source/utils/asymptote/v3dtypes.h	2022-01-20 21:28:28 UTC (rev 61671)
+++ trunk/Build/source/utils/asymptote/v3dtypes.h	2022-01-20 21:32:08 UTC (rev 61672)
@@ -1,6 +1,6 @@
 // Enum class for v3dtypes
 // AUTO-GENERATED from v3dtypes.csv
-// Generated at 2022-01-06 15:00:10.567069
+// Generated at 2022-01-19 22:28:57.697646
 
 namespace camp
 {

Modified: trunk/Build/source/utils/asymptote/v3dtypes.py
===================================================================
--- trunk/Build/source/utils/asymptote/v3dtypes.py	2022-01-20 21:28:28 UTC (rev 61671)
+++ trunk/Build/source/utils/asymptote/v3dtypes.py	2022-01-20 21:32:08 UTC (rev 61672)
@@ -1,7 +1,7 @@
 #!/usr/bin/env python3
 # Enum class for v3dtypes
 """ AUTO-GENERATED from v3dtypes.csv """
-# Generated at 2022-01-06 15:01:16.518838
+# Generated at 2022-01-19 22:30:10.808545
 
 class v3dtypes:
     v3dtypes_material=1

Modified: trunk/Build/source/utils/asymptote/webgl/gl.js
===================================================================
--- trunk/Build/source/utils/asymptote/webgl/gl.js	2022-01-20 21:28:28 UTC (rev 61671)
+++ trunk/Build/source/utils/asymptote/webgl/gl.js	2022-01-20 21:32:08 UTC (rev 61672)
@@ -3,6 +3,8 @@
 let Lights=[]; // Array of lights
 let Centers=[]; // Array of billboard centers
 let Background=[1,1,1,1]; // Background color
+let Transform; // Transformation matrix T[4][4] that maps back to user
+// coordinates, with T[i][j] stored as element 4*i+j.
 
 let canvasWidth,canvasHeight; // Canvas width, height
 
@@ -53,9 +55,13 @@
 const FillFactor=0.1;
 const windowTrim=10;
 const third=1/3;
+const pi=Math.acos(-1.0);
+const radians=pi/180.0;
 
 let Zoom;
 let lastZoom;
+let xshift;
+let yshift;
 
 let maxViewportWidth;
 let maxViewportHeight;
@@ -70,7 +76,7 @@
 let normMat=mat3.create();
 let viewMat3=mat3.create(); // 3x3 view matrix
 let cjMatInv=mat4.create();
-let T=mat4.create(); // Temporary matrix
+let Temp=mat4.create();
 
 let zmin,zmax;
 let center={x:0,y:0,z:0};
@@ -1984,7 +1990,6 @@
     else
       triangleData.rendered=false;
   }
-
 }
 
 function redrawScene()
@@ -1999,6 +2004,10 @@
 {
   mat4.identity(rotMat);
   redrawScene();
+
+  if(window.top.asyWebApplication)
+    window.top.asyWebApplication.setProjection("");
+  window.parent.asyProjection=false;
 }
 
 let positionAttribute=0;
@@ -2163,10 +2172,10 @@
 
 function COBTarget(out,mat)
 {
-  mat4.fromTranslation(T,[center.x,center.y,center.z])
-  mat4.invert(cjMatInv,T);
+  mat4.fromTranslation(Temp,[center.x,center.y,center.z])
+  mat4.invert(cjMatInv,Temp);
   mat4.multiply(out,mat,cjMatInv);
-  mat4.multiply(out,T,out);
+  mat4.multiply(out,Temp,out);
 }
 
 function setUniforms(data,shader)
@@ -2261,15 +2270,15 @@
   if(lastX == rawX && lastY == rawY) return;
   let [angle,axis]=arcball([lastX,-lastY],[rawX,-rawY]);
 
-  mat4.fromRotation(T,2*factor*ArcballFactor*angle/Zoom,axis);
-  mat4.multiply(rotMat,T,rotMat);
+  mat4.fromRotation(Temp,2*factor*ArcballFactor*angle/Zoom,axis);
+  mat4.multiply(rotMat,Temp,rotMat);
 }
 
 function shiftScene(lastX,lastY,rawX,rawY)
 {
-  let zoominv=1/Zoom;
-  shift.x += (rawX-lastX)*zoominv*halfCanvasWidth;
-  shift.y -= (rawY-lastY)*zoominv*halfCanvasHeight;
+  let Zoominv=1/Zoom;
+  shift.x += (rawX-lastX)*Zoominv*halfCanvasWidth;
+  shift.y -= (rawY-lastY)*Zoominv*halfCanvasHeight;
 }
 
 function panScene(lastX,lastY,rawX,rawY)
@@ -2403,6 +2412,72 @@
   canvas.removeEventListener("wheel",handleMouseWheel,false);
 }
 
+function Camera()
+{
+  let vCamera=Array(3);
+  let vUp=Array(3);
+  let vTarget=Array(3);
+
+  let cx=center.x;
+  let cy=center.y;
+  let cz=0.5*(viewParam.zmin+viewParam.zmax);
+
+  for(let i=0; i < 3; ++i) {
+    let sumCamera=0.0, sumTarget=0.0, sumUp=0.0;
+    let i4=4*i;
+    for(let j=0; j < 4; ++j) {
+      let j4=4*j;
+      let R0=rotMat[j4];
+      let R1=rotMat[j4+1];
+      let R2=rotMat[j4+2];
+      let R3=rotMat[j4+3];
+      let T4ij=Transform[i4+j];
+      sumCamera += T4ij*(R3-cx*R0-cy*R1-cz*R2);
+      sumUp += T4ij*R1;
+      sumTarget += T4ij*(R3-cx*R0-cy*R1);
+    }
+    vCamera[i]=sumCamera;
+    vUp[i]=sumUp;
+    vTarget[i]=sumTarget;
+  }
+  return [vCamera,vUp,vTarget];
+}
+
+function projection()
+{
+  if(Transform == null) return "";
+
+  let camera,up,target;
+  [camera,up,target]=Camera();
+
+  let projection=orthographic ? "  orthographic(" : "  perspective(";
+  let indent="".padStart(projection.length);
+
+  let currentprojection="currentprojection="+"\n"+
+      projection+"camera=("+camera+"),\n"+
+      indent+"up=("+up+"),"+"\n"+
+      indent+"target=("+target+"),"+"\n"+
+      indent+"zoom="+Zoom*initialZoom/zoom0;
+
+  if(!orthographic)
+    currentprojection += ","+"\n"
+    +indent+"angle="+
+    2.0*Math.atan(Math.tan(0.5*angleOfView)/Zoom)/radians;
+
+  if(xshift != 0 || yshift != 0)
+    currentprojection += ","+"\n"+
+    indent+"viewportshift=("+xshift+","+yshift+")";
+
+  if(!orthographic)
+    currentprojection += ","+"\n"+
+    indent+"autoadjust=false";
+
+  currentprojection += ");"+"\n";
+
+  window.parent.asyProjection=true;
+  return currentprojection;
+}
+
 function handleKey(event)
 {
   let ESC=27;
@@ -2452,6 +2527,9 @@
   case '<':
     shrink();
     break;
+  case 'c':
+    showCamera();
+    break;
   default:
     break;
   }
@@ -2687,39 +2765,38 @@
 function setDimensions(width,height,X,Y)
 {
   let Aspect=width/height;
-  let zoominv=1/Zoom;
-  let xshift=(X/width+viewportShift[0])*Zoom;
-  let yshift=(Y/height+viewportShift[1])*Zoom;
-
+  xshift=(X/width+viewportShift[0])*Zoom;
+  yshift=(Y/height+viewportShift[1])*Zoom;
+  let Zoominv=1/Zoom;
   if(orthographic) {
     let xsize=maxBound[0]-minBound[0];
     let ysize=maxBound[1]-minBound[1];
     if(xsize < ysize*Aspect) {
-      let r=0.5*ysize*Aspect*zoominv;
+      let r=0.5*ysize*Aspect*Zoominv;
       let X0=2*r*xshift;
-      let Y0=ysize*zoominv*yshift;
+      let Y0=ysize*Zoominv*yshift;
       viewParam.xmin=-r-X0;
       viewParam.xmax=r-X0;
-      viewParam.ymin=minBound[1]*zoominv-Y0;
-      viewParam.ymax=maxBound[1]*zoominv-Y0;
+      viewParam.ymin=minBound[1]*Zoominv-Y0;
+      viewParam.ymax=maxBound[1]*Zoominv-Y0;
     } else {
-      let r=0.5*xsize/(Aspect*Zoom);
-      let X0=xsize*zoominv*xshift;
+      let r=0.5*xsize*Zoominv/Aspect;
+      let X0=xsize*Zoominv*xshift;
       let Y0=2*r*yshift;
-      viewParam.xmin=minBound[0]*zoominv-X0;
-      viewParam.xmax=maxBound[0]*zoominv-X0;
+      viewParam.xmin=minBound[0]*Zoominv-X0;
+      viewParam.xmax=maxBound[0]*Zoominv-X0;
       viewParam.ymin=-r-Y0;
       viewParam.ymax=r-Y0;
     }
   } else {
-      let r=H*zoominv;
-      let rAspect=r*Aspect;
-      let X0=2*rAspect*xshift;
-      let Y0=2*r*yshift;
-      viewParam.xmin=-rAspect-X0;
-      viewParam.xmax=rAspect-X0;
-      viewParam.ymin=-r-Y0;
-      viewParam.ymax=r-Y0;
+    let r=H*Zoominv;
+    let rAspect=r*Aspect;
+    let X0=2*rAspect*xshift;
+    let Y0=2*r*yshift;
+    viewParam.xmin=-rAspect-X0;
+    viewParam.xmax=rAspect-X0;
+    viewParam.ymin=-r-Y0;
+    viewParam.ymax=r-Y0;
   }
 }
 
@@ -2731,8 +2808,18 @@
     viewParam.ymin,viewParam.ymax,
     -viewParam.zmax,-viewParam.zmin);
   updateViewMatrix();
+
+  if(window.top.asyWebApplication)
+    window.top.asyWebApplication.setProjection(projection());
 }
 
+function showCamera()
+{
+  if(!window.top.asyWebApplication)
+    prompt("Ctrl+c Enter to copy currentprojection to clipboard; then append to asy file:",
+           projection());
+}
+
 function initProjection()
 {
   H=-Math.tan(0.5*angleOfView)*maxBound[2];
@@ -2792,6 +2879,10 @@
 {
   zoom0=initialZoom;
 
+  if(window.top.asyWebApplication &&
+     window.top.asyWebApplication.getProjection() == "")
+    window.parent.asyProjection=false;
+
   if(absolute && !embedded) {
     canvasWidth=canvasWidth0*window.devicePixelRatio;
     canvasHeight=canvasHeight0*window.devicePixelRatio;
@@ -2800,7 +2891,8 @@
     canvasWidth=Math.max(window.innerWidth-windowTrim,windowTrim);
     canvasHeight=Math.max(window.innerHeight-windowTrim,windowTrim);
 
-    if(!orthographic && canvasWidth < canvasHeight*Aspect)
+    if(!orthographic && !window.parent.asyProjection &&
+       canvasWidth < canvasHeight*Aspect)
       zoom0 *= canvasWidth/(canvasHeight*Aspect);
   }
 
@@ -2810,8 +2902,9 @@
   let maxViewportWidth=window.innerWidth;
   let maxViewportHeight=window.innerHeight;
 
-  viewportShift[0] /= zoom0;
-  viewportShift[1] /= zoom0;
+  let Zoominv=1/zoom0;
+  viewportShift[0] *= Zoominv;
+  viewportShift[1] *= Zoominv;
 
   setsize(canvasWidth,canvasHeight);
   redrawScene();

Modified: trunk/Build/source/utils/asymptote/webgl/license
===================================================================
--- trunk/Build/source/utils/asymptote/webgl/license	2022-01-20 21:28:28 UTC (rev 61671)
+++ trunk/Build/source/utils/asymptote/webgl/license	2022-01-20 21:32:08 UTC (rev 61672)
@@ -1,6 +1,6 @@
 /*@license
  AsyGL: Render Bezier patches and triangles via subdivision with WebGL.
-  Copyright 2019-2021: John C. Bowman and Supakorn "Jamie" Rassameemasmuang
+  Copyright 2019-2022: John C. Bowman and Supakorn "Jamie" Rassameemasmuang
   University of Alberta
 
 This program is free software; you can redistribute it and/or modify

Modified: trunk/Build/source/utils/asymptote/xstream.h
===================================================================
--- trunk/Build/source/utils/asymptote/xstream.h	2022-01-20 21:28:28 UTC (rev 61671)
+++ trunk/Build/source/utils/asymptote/xstream.h	2022-01-20 21:32:08 UTC (rev 61672)
@@ -57,6 +57,11 @@
 
 #endif
 
+#ifdef __OpenBSD__
+#define xdr_longlong_t xdr_int64_t
+#define xdr_u_longlong_t xdr_u_int64_t
+#endif
+
 #ifdef _POSIX_SOURCE
 #undef _POSIX_SOURCE
 #include <rpc/rpc.h>



More information about the tex-live-commits mailing list.