texlive[54034] Build/source/utils: asy 2.63 sources

commits+karl at tug.org commits+karl at tug.org
Tue Mar 3 23:35:10 CET 2020


Revision: 54034
          http://tug.org/svn/texlive?view=revision&revision=54034
Author:   karl
Date:     2020-03-03 23:35:09 +0100 (Tue, 03 Mar 2020)
Log Message:
-----------
asy 2.63 sources

Modified Paths:
--------------
    trunk/Build/source/utils/README
    trunk/Build/source/utils/asymptote/ChangeLog
    trunk/Build/source/utils/asymptote/GUI/icons_rc.py
    trunk/Build/source/utils/asymptote/README
    trunk/Build/source/utils/asymptote/ReleaseNotes
    trunk/Build/source/utils/asymptote/angle.h
    trunk/Build/source/utils/asymptote/application.cc
    trunk/Build/source/utils/asymptote/asy-keywords.el
    trunk/Build/source/utils/asymptote/asy.list
    trunk/Build/source/utils/asymptote/asymptote.spec
    trunk/Build/source/utils/asymptote/base/graph3.asy
    trunk/Build/source/utils/asymptote/base/palette.asy
    trunk/Build/source/utils/asymptote/base/shaders/fragment.glsl
    trunk/Build/source/utils/asymptote/base/shaders/vertex.glsl
    trunk/Build/source/utils/asymptote/base/solids.asy
    trunk/Build/source/utils/asymptote/base/three.asy
    trunk/Build/source/utils/asymptote/base/three_arrows.asy
    trunk/Build/source/utils/asymptote/base/three_light.asy
    trunk/Build/source/utils/asymptote/base/three_surface.asy
    trunk/Build/source/utils/asymptote/base/three_tube.asy
    trunk/Build/source/utils/asymptote/base/tube.asy
    trunk/Build/source/utils/asymptote/base/webgl/asygl.js
    trunk/Build/source/utils/asymptote/beziercurve.cc
    trunk/Build/source/utils/asymptote/beziercurve.h
    trunk/Build/source/utils/asymptote/bezierpatch.cc
    trunk/Build/source/utils/asymptote/bezierpatch.h
    trunk/Build/source/utils/asymptote/common.h
    trunk/Build/source/utils/asymptote/config.guess
    trunk/Build/source/utils/asymptote/config.h.in
    trunk/Build/source/utils/asymptote/config.sub
    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/asy.1
    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/drawelement.h
    trunk/Build/source/utils/asymptote/drawpath3.cc
    trunk/Build/source/utils/asymptote/drawpath3.h
    trunk/Build/source/utils/asymptote/drawsurface.cc
    trunk/Build/source/utils/asymptote/drawsurface.h
    trunk/Build/source/utils/asymptote/examples/cylinder.asy
    trunk/Build/source/utils/asymptote/examples/pipes.asy
    trunk/Build/source/utils/asymptote/examples/randompath3.asy
    trunk/Build/source/utils/asymptote/examples/sphere.asy
    trunk/Build/source/utils/asymptote/examples/unitoctant.asy
    trunk/Build/source/utils/asymptote/examples/vertexshading.asy
    trunk/Build/source/utils/asymptote/examples/workcone.asy
    trunk/Build/source/utils/asymptote/fftw++.h
    trunk/Build/source/utils/asymptote/glrender.cc
    trunk/Build/source/utils/asymptote/glrender.h
    trunk/Build/source/utils/asymptote/install-sh
    trunk/Build/source/utils/asymptote/interact.cc
    trunk/Build/source/utils/asymptote/interact.h
    trunk/Build/source/utils/asymptote/jsfile.cc
    trunk/Build/source/utils/asymptote/jsfile.h
    trunk/Build/source/utils/asymptote/pair.h
    trunk/Build/source/utils/asymptote/path.cc
    trunk/Build/source/utils/asymptote/path.h
    trunk/Build/source/utils/asymptote/path3.cc
    trunk/Build/source/utils/asymptote/path3.h
    trunk/Build/source/utils/asymptote/revision.cc
    trunk/Build/source/utils/asymptote/runarray.cc
    trunk/Build/source/utils/asymptote/runarray.in
    trunk/Build/source/utils/asymptote/runfile.cc
    trunk/Build/source/utils/asymptote/runfile.in
    trunk/Build/source/utils/asymptote/runhistory.cc
    trunk/Build/source/utils/asymptote/runhistory.in
    trunk/Build/source/utils/asymptote/runmath.cc
    trunk/Build/source/utils/asymptote/runmath.in
    trunk/Build/source/utils/asymptote/runpair.cc
    trunk/Build/source/utils/asymptote/runpair.in
    trunk/Build/source/utils/asymptote/runpath.cc
    trunk/Build/source/utils/asymptote/runpath.in
    trunk/Build/source/utils/asymptote/runpath3d.cc
    trunk/Build/source/utils/asymptote/runpath3d.in
    trunk/Build/source/utils/asymptote/runpicture.cc
    trunk/Build/source/utils/asymptote/runpicture.in
    trunk/Build/source/utils/asymptote/runtime.cc
    trunk/Build/source/utils/asymptote/runtime.in
    trunk/Build/source/utils/asymptote/runtriple.cc
    trunk/Build/source/utils/asymptote/runtriple.in
    trunk/Build/source/utils/asymptote/settings.cc
    trunk/Build/source/utils/asymptote/triple.h
    trunk/Build/source/utils/asymptote/webgl/gl.js
    trunk/Build/source/utils/asymptote/webgl/vertex.glsl

Removed Paths:
-------------
    trunk/Build/source/utils/asymptote/quaternion.cc

Modified: trunk/Build/source/utils/README
===================================================================
--- trunk/Build/source/utils/README	2020-03-03 22:33:26 UTC (rev 54033)
+++ trunk/Build/source/utils/README	2020-03-03 22:35:09 UTC (rev 54034)
@@ -4,7 +4,7 @@
 Extra utilities we (optionally) compile for TeX Live.
 See comments in ../texk/README.
 
-asymptote 2.62 - checked 16jan20
+asymptote 2.63 - checked 3mar20
   update to TL from CTAN, to include prebuilt doc.
   see http://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	2020-03-03 22:33:26 UTC (rev 54033)
+++ trunk/Build/source/utils/asymptote/ChangeLog	2020-03-03 22:35:09 UTC (rev 54034)
@@ -1,3 +1,511 @@
+commit 6df59d64acb38ad48002d1cae4350ca5cede5267
+Author: John Bowman <bowman at ualberta.ca>
+Date:   Mon Mar 2 22:15:59 2020 -0700
+
+    Increase default output precision to 7.
+
+commit 41e51a6302829c2c85af94c50b53e54a9052c7cb
+Author: John Bowman <bowman at ualberta.ca>
+Date:   Mon Mar 2 20:47:10 2020 -0700
+
+    Check for editline header.
+
+commit 4a2852bb9f609a35e38f032cbc3f401441bf1d6c
+Author: John Bowman <bowman at ualberta.ca>
+Date:   Mon Mar 2 20:13:09 2020 -0700
+
+    Fix unused variable warning messages.
+
+commit 0dbd4412b4772ffbde89d3feedc26e3ecee1dc62
+Author: John Bowman <bowman at ualberta.ca>
+Date:   Mon Mar 2 19:55:26 2020 -0700
+
+    Support compilation without LIBGLM.
+
+commit dc49282bb475174689adcdbe18979ef366e79d4a
+Author: John Bowman <bowman at ualberta.ca>
+Date:   Mon Mar 2 09:11:49 2020 -0700
+
+    Fix numerical precision issue in tube subdivision; invert tubethreshold.
+
+commit c59833c3fd8ff7c88950bf1ac7dda50a1fb2796a
+Author: John Bowman <bowman at ualberta.ca>
+Date:   Sun Mar 1 22:56:56 2020 -0700
+
+    Update asygl.
+
+commit 104a2c9db80d702a86f10d6ccd403c1e1c38d88a
+Author: John Bowman <bowman at ualberta.ca>
+Date:   Sun Mar 1 22:54:49 2020 -0700
+
+    Fix WebGL cylinder bounds.
+
+commit 9f583631684d4f53d5818a70f3db14b747ec9653
+Author: John Bowman <bowman at ualberta.ca>
+Date:   Sun Mar 1 21:34:35 2020 -0700
+
+    Fix warning message.
+
+commit f23a3c044ed9fb2ba7e58045f8b785baa31a1d99
+Author: John Bowman <bowman at ualberta.ca>
+Date:   Sun Mar 1 21:32:20 2020 -0700
+
+    Update fftw++.
+
+commit 484d45498dc7180a91aba3f62f1ee247fc3210b0
+Author: John Bowman <bowman at ualberta.ca>
+Date:   Sun Mar 1 18:49:16 2020 -0700
+
+    Check for popcount.
+
+commit 301f42493376b65ae7127ec7d4f49fc3cb519183
+Author: John Bowman <bowman at ualberta.ca>
+Date:   Sun Mar 1 11:32:45 2020 -0700
+
+    Revert to light=nolight default for drawing a path3.
+
+commit f483a0715496e7ae423e38253af2d3c5152013ca
+Author: John Bowman <bowman at ualberta.ca>
+Date:   Sun Mar 1 11:10:46 2020 -0700
+
+    Check radius of curvature at both tube ends; simplify code.
+
+commit 839c3a85d6a715c06fabccfed990a9959ce83eb5
+Author: John Bowman <bowman at ualberta.ca>
+Date:   Sat Feb 29 20:11:47 2020 -0700
+
+    Update asygl.
+
+commit 3ffe64476247b4d3680c9a7ec2d85fd3fe9e012f
+Author: John Bowman <bowman at ualberta.ca>
+Date:   Sat Feb 29 19:44:44 2020 -0700
+
+    Port curve lighting to WebGL.
+
+commit 9d932516731c26a811b512ed91a7631e5c825344
+Merge: ffa4ef3f d4285d04
+Author: John Bowman <bowman at ualberta.ca>
+Date:   Sat Feb 29 17:21:30 2020 -0700
+
+    Merge branch 'curvenormal'.
+
+commit d4285d04fd982fb7a977b44770cf2c3464bd121c
+Author: John Bowman <bowman at ualberta.ca>
+Date:   Sun Feb 23 22:03:33 2020 -0700
+
+    Implement curve lighting.
+
+commit ffa4ef3f199dec850a38d52a669464989a0cb32c
+Author: John Bowman <bowman at ualberta.ca>
+Date:   Fri Feb 28 00:29:04 2020 -0700
+
+    Make comma optional in stream reads of parenthesized pairs or triples.
+
+commit 7f3cebcec4ced07f9e076ece132dd552314f5c17
+Author: John Bowman <bowman at ualberta.ca>
+Date:   Fri Feb 28 00:10:47 2020 -0700
+
+    Fix getc bug.
+
+commit 19e5bc0c14e59deff28327db3318469b617a806a
+Author: John Bowman <bowman at ualberta.ca>
+Date:   Wed Feb 26 22:20:36 2020 -0700
+
+    Implement 2D and 3D FFTs.
+
+commit 00f2621999ede5d11bcf4a6841f76a2b8f9913d0
+Author: John Bowman <bowman at ualberta.ca>
+Date:   Wed Feb 26 22:18:21 2020 -0700
+
+    Return nonempty palettes for undersized requests.
+
+commit d5fe9828872b9a38db42bf5bcd4e556c10c7d8b8
+Author: John Bowman <bowman at ualberta.ca>
+Date:   Sun Feb 23 20:04:32 2020 -0700
+
+    Update asygl.
+
+commit 384d99a345db43235456f8c2c631ad70c12f9dc5
+Author: John Bowman <bowman at ualberta.ca>
+Date:   Sun Feb 23 19:59:16 2020 -0700
+
+    Add directional flatness test; simplify unitcone and unitfrustum.
+
+commit b0db12cdeab174f662b62c31d20af69aaa8b87cc
+Author: John Bowman <bowman at ualberta.ca>
+Date:   Sun Feb 23 17:01:38 2020 -0700
+
+    Update asygl.
+
+commit 85e78e1ee51a21e294b362e66104706f02bd69d3
+Author: John Bowman <bowman at ualberta.ca>
+Date:   Sun Feb 23 16:53:39 2020 -0700
+
+    Fix primitive subdivision cracks by enforcing bounds on the entire object.
+
+commit e50f6dea3d9f1d6a2773e5e6dbf60a508657fe30
+Author: John Bowman <bowman at ualberta.ca>
+Date:   Sun Feb 23 13:50:48 2020 -0700
+
+    Remove obsolete BezierFactor.
+
+commit 6ba502a16fd84653edbaba01e683d407d838cf95
+Author: John Bowman <bowman at ualberta.ca>
+Date:   Sun Feb 23 12:21:15 2020 -0700
+
+    Update asygl.
+
+commit 975b6c2c474ba1cd0df54974c74379a2784483a0
+Author: John Bowman <bowman at ualberta.ca>
+Date:   Sun Feb 23 12:13:43 2020 -0700
+
+    Fix subdivision crack adjustments.
+
+commit 86218eb8ca0fda14515c62687f1a9ae71cf9ed50
+Author: John Bowman <bowman at ualberta.ca>
+Date:   Sun Feb 23 11:44:25 2020 -0700
+
+    Port commit 0d63d91ba66b022ef753fa7cb088e120294b7039 to WebGL.
+
+commit 93f45abe9bf89b142a7ecdd517b1b20faffc5512
+Author: John Bowman <bowman at ualberta.ca>
+Date:   Sat Feb 22 23:31:37 2020 -0700
+
+    Reformat.
+
+commit 34e78162304f3b989d17a2e0101f8136d8abd1de
+Author: John Bowman <bowman at ualberta.ca>
+Date:   Sat Feb 22 23:23:53 2020 -0700
+
+    Improve workcone example.
+
+commit 0d63d91ba66b022ef753fa7cb088e120294b7039
+Author: John Bowman <bowman at ualberta.ca>
+Date:   Sat Feb 22 22:58:30 2020 -0700
+
+    Split patches in both directions only when required.
+
+commit 716db94b4302b728d2a98a352ccf31afdfca92de
+Author: John Bowman <bowman at ualberta.ca>
+Date:   Sat Feb 22 12:58:09 2020 -0700
+
+    Remove redundant Bezier patch flatness test.
+
+commit cdbe687ca2faf5e77a7a5fdd8774930f4a1a7ebe
+Author: John Bowman <bowman at ualberta.ca>
+Date:   Sat Feb 22 12:38:36 2020 -0700
+
+    Add surface operator cast(surface[] s) for backwards compatibility.
+
+commit 5f12a9e9bf4aeea489f614749f05a2b9bb0e8394
+Author: John Bowman <bowman at ualberta.ca>
+Date:   Sat Feb 22 12:21:49 2020 -0700
+
+    Update tube.asy and example.
+
+commit 713b2bcc7ab237faaf174b3474f8eb9064dac121
+Author: John Bowman <bowman at ualberta.ca>
+Date:   Fri Feb 21 21:26:42 2020 -0700
+
+    Fix straight Bezier patch bounds bug in commit 59227a95289288cf7f259559bb43e21b02dfff59.
+
+commit 59227a95289288cf7f259559bb43e21b02dfff59
+Author: John Bowman <bowman at ualberta.ca>
+Date:   Fri Feb 21 20:19:16 2020 -0700
+
+    Fix WebGL primitive tube bounds.
+
+commit 1eee76fad6144b5ca89d4f46d5e51e2abb0894d7
+Author: John Bowman <bowman at ualberta.ca>
+Date:   Fri Feb 21 09:44:18 2020 -0700
+
+    Update asygl.
+
+commit dc02c6b64851aa315def86f944e43ce9c842c3b6
+Author: John Bowman <bowman at ualberta.ca>
+Date:   Fri Feb 21 09:42:05 2020 -0700
+
+    Fix degenerate WebGL tube primitive.
+
+commit ca6b1cb2ba259bc43948621b607fde9e01768b46
+Author: John Bowman <bowman at ualberta.ca>
+Date:   Fri Feb 21 09:19:30 2020 -0700
+
+    Fix material bug in primitives.
+
+commit 36045af736195662ed0019b2910d9b1603329295
+Author: John Bowman <bowman at ualberta.ca>
+Date:   Fri Feb 21 02:22:37 2020 -0700
+
+    Update asygl.
+
+commit 60ae5b446350c3938af0702016848cb45be4769d
+Author: John Bowman <bowman at ualberta.ca>
+Date:   Fri Feb 21 02:21:46 2020 -0700
+
+    Fix typos in gl.js; temporarily work around unitcylinder primitive bug.
+
+commit e761621867b49f3edb21363bff859b904cd9afc8
+Author: John Bowman <bowman at ualberta.ca>
+Date:   Fri Feb 21 01:31:19 2020 -0700
+
+    Temporarily disable offscreen culling of WebGL tubes.
+
+commit 89c4c49f4121864db68d83e5a954a557ec9a4791
+Author: John Bowman <bowman at ualberta.ca>
+Date:   Fri Feb 21 00:03:12 2020 -0700
+
+    Update asygl.
+
+commit 9833a4300c0318a297899284a9cc49ca11633a09
+Author: John Bowman <bowman at ualberta.ca>
+Date:   Thu Feb 20 23:43:45 2020 -0700
+
+    Implement WebGL tube primitive; remove PRC tube primitive.
+
+commit 78be4fe3ad53a6eca98318efd689f5eb1dd68424
+Author: John Bowman <bowman at ualberta.ca>
+Date:   Mon Feb 17 22:06:53 2020 -0700
+
+    Improve tube rendering; simplify DefaultHead3; fix degenerate normal tests.
+
+commit ba6f8988132d3f0b82e0d51bd3a49089fc2bb067
+Author: John Bowman <bowman at ualberta.ca>
+Date:   Mon Feb 17 21:25:27 2020 -0700
+
+    Fix test degenerate normals.
+
+commit 9beb5b6c72ce47c8fad8c33f14b78015c9baa40f
+Author: John Bowman <bowman at ualberta.ca>
+Date:   Wed Feb 5 22:26:02 2020 -0700
+
+    Fix MSDOS configuration issue.
+
+commit 9e2be068ab6d03ed82651ab21d8271c1707eb0bd
+Author: John Bowman <bowman at ualberta.ca>
+Date:   Mon Feb 3 09:07:07 2020 -0700
+
+    Update asygl.
+
+commit 202291e8a54c356e22885609ade96dfb79bdc360
+Author: John Bowman <bowman at ualberta.ca>
+Date:   Mon Feb 3 09:02:36 2020 -0700
+
+    Add general surface primitives; implement sphere, cylinder, and disk.
+
+commit a615e55bec2cddeaecddaac49cc7a00b664260c7
+Author: John Bowman <bowman at ualberta.ca>
+Date:   Sun Feb 2 10:31:13 2020 -0700
+
+    Update URLs in manual.
+
+commit bed68b2135d2ca238107977e24c7fd74e11b71ea
+Author: John Bowman <bowman at ualberta.ca>
+Date:   Sat Feb 1 11:36:31 2020 -0700
+
+    Fix MacOS X OpenGL diagnostic.
+
+commit 890542188cd2071ffa8aac0da1f266bd3e9d35fd
+Author: John Bowman <bowman at ualberta.ca>
+Date:   Thu Jan 30 22:27:37 2020 -0700
+
+    Fix arrowheads.
+
+commit 229a1ce4dfe12cfbce64f62411d38aff7bc23d66
+Author: John Bowman <bowman at ualberta.ca>
+Date:   Thu Jan 30 12:24:58 2020 -0700
+
+    Update asygl.
+
+commit c54573e22bc7e4c6ed226f3c96fdf59df396310c
+Author: John Bowman <bowman at ualberta.ca>
+Date:   Thu Jan 30 12:24:19 2020 -0700
+
+    Work around uglify bug.
+
+commit af0f23b9fcbe5a86d6504e92a542ec9327a4f13a
+Author: John Bowman <bowman at ualberta.ca>
+Date:   Thu Jan 30 12:13:40 2020 -0700
+
+    Revert "Update asygl."
+    
+    This reverts commit aca1a213e5512866ad4658131c6ec49dd24ad920.
+
+commit aca1a213e5512866ad4658131c6ec49dd24ad920
+Author: John Bowman <bowman at ualberta.ca>
+Date:   Thu Jan 30 12:10:46 2020 -0700
+
+    Update asygl.
+
+commit b6af466ba0a5d87fa1eeb4799f42e360a4b5d968
+Author: John Bowman <bowman at ualberta.ca>
+Date:   Thu Jan 30 12:08:15 2020 -0700
+
+    Implement asygl sphere primitive; remove PRCshininess translation.
+
+commit 4283a1dba8b15010ec1f1455d1544f20381425f2
+Author: John Bowman <bowman at ualberta.ca>
+Date:   Tue Jan 28 23:26:19 2020 -0700
+
+    Fix epsilon.
+
+commit 60ec71c54ac97a5b5b24987cf663168e713b7ca2
+Author: John Bowman <bowman at ualberta.ca>
+Date:   Tue Jan 28 16:43:43 2020 -0700
+
+    Fix degenerate surface normals.
+
+commit fdf8aeae3c1a11fb04f70674ca060a814fe2b12c
+Author: John Bowman <bowman at ualberta.ca>
+Date:   Wed Jan 22 09:24:35 2020 -0700
+
+    Update asygl.
+
+commit 85ee50a6b64875ea3c5e6acf8195eb2139916839
+Author: John Bowman <bowman at ualberta.ca>
+Date:   Wed Jan 22 09:24:03 2020 -0700
+
+    Don't delete embedded shaders.
+
+commit be28c80bd4aabecfa106de5e897255d4bc03b9e9
+Author: John Bowman <bowman at ualberta.ca>
+Date:   Wed Jan 22 01:28:58 2020 -0700
+
+    Update asygl.
+
+commit 136fb78e7f18500cc97867cc36d3dc6a9f2c69b0
+Author: John Bowman <bowman at ualberta.ca>
+Date:   Wed Jan 22 01:25:50 2020 -0700
+
+    Fix billboard labels in wireframe mode.
+
+commit 59176146c24186463cc4d981acf760008a111403
+Author: John Bowman <bowman at ualberta.ca>
+Date:   Wed Jan 22 01:04:06 2020 -0700
+
+    Update asygl.
+
+commit cafd93a3e58a774d3022c68fd9ab7088346cf4e3
+Author: John Bowman <bowman at ualberta.ca>
+Date:   Wed Jan 22 01:02:45 2020 -0700
+
+    Fix wireframe mode with transparency and indexed triangles.
+
+commit 52e5d3f4e21cfdb04ec44667b76d4ae6db8ed387
+Author: John Bowman <bowman at ualberta.ca>
+Date:   Wed Jan 22 00:34:36 2020 -0700
+
+    Update asygl.
+
+commit 6ab2b06ad276aff1d71cea3ee9302b7f6771fb42
+Author: John Bowman <bowman at ualberta.ca>
+Date:   Wed Jan 22 00:34:05 2020 -0700
+
+    Fix wireframe modes with transparency.
+
+commit 5930496436c9791ae8779b02791ff2fb7e3d3b30
+Author: John Bowman <bowman at ualberta.ca>
+Date:   Wed Jan 22 00:07:32 2020 -0700
+
+    Update asygl.
+
+commit 84209ded0c2cace5fd9f104ec3c44a6139dec662
+Author: John Bowman <bowman at ualberta.ca>
+Date:   Tue Jan 21 19:46:35 2020 -0700
+
+    Implement mesh mode in WebGL.
+
+commit d4593b6ccd91019edd123d0e867456994022d9e2
+Author: John Bowman <bowman at ualberta.ca>
+Date:   Mon Jan 20 21:14:55 2020 -0700
+
+    Disable OpenGL at compile time if version 3.2 is unavailable under MacOS X.
+
+commit ba29f3dc345f69c5e312b1b4969f6ba05f770292
+Author: John Bowman <bowman at ualberta.ca>
+Date:   Sun Jan 19 18:23:28 2020 -0700
+
+    Implement nondegenerate octant1, hemisphere, and sphere (requires 208 instead of 128 control points but generates fewer triangles, renders faster, and avoids transparency artifacts at poles).
+
+commit eb33c6bf005144d04003a8d6528d98b36701f55f
+Author: John Bowman <bowman at ualberta.ca>
+Date:   Sat Jan 18 23:30:01 2020 -0700
+
+    Fix outline mode.
+
+commit 3e155439ed1f587db52f9e2cb756d4cd0b5b6e96
+Author: John Bowman <bowman at ualberta.ca>
+Date:   Sat Jan 18 17:56:40 2020 -0700
+
+    Update config utilities.
+
+commit c9ac7a566ebefb4c07e24c6d55e4cd4b7c85d078
+Author: John Bowman <bowman at ualberta.ca>
+Date:   Sat Jan 18 17:42:03 2020 -0700
+
+    Fix assertion.
+
+commit bfa91b25f845ffae6fea8d0bc9665024dfd6c9ba
+Author: John Bowman <bowman at ualberta.ca>
+Date:   Sat Jan 18 13:41:05 2020 -0700
+
+    Fix include path.
+
+commit a0c44e0b438217ad04eb7833a8acc3a7bd571c0f
+Author: John Bowman <bowman at ualberta.ca>
+Date:   Sat Jan 18 13:33:45 2020 -0700
+
+    Fallback to Editline if GNU Readline library is unavailable, to at least
+    have command-line editing (without history support).
+
+commit bae3845ec61e394c996dffb1256d96094fa80788
+Author: John Bowman <bowman at ualberta.ca>
+Date:   Sat Jan 18 00:30:08 2020 -0700
+
+    Update sourceforge URLs.
+
+commit 94460625cfb662ea5ceb1e769208ecc386d115d7
+Author: John Bowman <bowman at ualberta.ca>
+Date:   Fri Jan 17 07:48:50 2020 -0700
+
+    Allow overriding default emissive and shininess values for vertex-dependent colors.
+
+commit fb3a60597c869d559e21f6dcfce0f64e7c5e1a1e
+Author: John Bowman <bowman at ualberta.ca>
+Date:   Thu Jan 16 15:01:01 2020 -0700
+
+    Fix a6a1ec40a864c27b7ca02336940c24f7a5a53c1a.
+
+commit 5aec7d5bd3f569343b250ca2997bb966235f436b
+Author: John Bowman <bowman at ualberta.ca>
+Date:   Thu Jan 16 14:27:16 2020 -0700
+
+    Update asygl.
+
+commit e7da4b39f67abdd73e42afb02b6107edd16fe856
+Author: John Bowman <bowman at ualberta.ca>
+Date:   Thu Jan 16 13:48:42 2020 -0700
+
+    Update asygl.
+
+commit 218f96b42824c6a1dfa70b0289344b0a71fa282f
+Author: John Bowman <bowman at ualberta.ca>
+Date:   Thu Jan 16 13:26:39 2020 -0700
+
+    Update asygl.
+
+commit a6a1ec40a864c27b7ca02336940c24f7a5a53c1a
+Author: John Bowman <bowman at ualberta.ca>
+Date:   Thu Jan 16 13:24:49 2020 -0700
+
+    Avoid race condition.
+
+commit 18c8da80a5f780dd2b814844c0f3d132bc525636
+Author: John Bowman <bowman at ualberta.ca>
+Date:   Tue Jan 14 21:25:42 2020 -0700
+
+    Increment version to 2.63.
+
 commit fe3aaeb627833abb5a7685781d75bc8b4d0c967e
 Author: John Bowman <bowman at ualberta.ca>
 Date:   Tue Jan 14 14:14:11 2020 -0700

Modified: trunk/Build/source/utils/asymptote/GUI/icons_rc.py
===================================================================
--- trunk/Build/source/utils/asymptote/GUI/icons_rc.py	2020-03-03 22:33:26 UTC (rev 54033)
+++ trunk/Build/source/utils/asymptote/GUI/icons_rc.py	2020-03-03 22:35:09 UTC (rev 54034)
@@ -9,481 +9,86 @@
 from PyQt5 import QtCore
 
 qt_resource_data = b"\
-\x00\x00\x00\x6c\
+\x00\x00\x04\xd5\
 \x3c\
-\x73\x76\x67\x20\x78\x6d\x6c\x6e\x73\x3d\x22\x68\x74\x74\x70\x3a\
-\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x32\x30\x30\
-\x30\x2f\x73\x76\x67\x22\x20\x76\x69\x65\x77\x42\x6f\x78\x3d\x22\
-\x30\x20\x30\x20\x32\x30\x20\x32\x30\x22\x3e\x3c\x70\x61\x74\x68\
-\x20\x64\x3d\x22\x4d\x31\x38\x20\x31\x32\x76\x31\x48\x38\x76\x35\
-\x6c\x2d\x36\x2d\x36\x20\x36\x2d\x36\x76\x35\x68\x38\x56\x32\x68\
-\x32\x7a\x22\x2f\x3e\x3c\x2f\x73\x76\x67\x3e\
-\x00\x00\x04\x64\
-\x3c\
-\x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\
-\x30\x22\x20\x65\x6e\x63\x6f\x64\x69\x6e\x67\x3d\x22\x75\x74\x66\
-\x2d\x38\x22\x3f\x3e\x0d\x0a\x3c\x21\x2d\x2d\x20\x47\x65\x6e\x65\
-\x72\x61\x74\x6f\x72\x3a\x20\x41\x64\x6f\x62\x65\x20\x49\x6c\x6c\
-\x75\x73\x74\x72\x61\x74\x6f\x72\x20\x31\x36\x2e\x32\x2e\x31\x2c\
-\x20\x53\x56\x47\x20\x45\x78\x70\x6f\x72\x74\x20\x50\x6c\x75\x67\
-\x2d\x49\x6e\x20\x2e\x20\x53\x56\x47\x20\x56\x65\x72\x73\x69\x6f\
-\x6e\x3a\x20\x36\x2e\x30\x30\x20\x42\x75\x69\x6c\x64\x20\x30\x29\
-\x20\x20\x2d\x2d\x3e\x0d\x0a\x3c\x21\x44\x4f\x43\x54\x59\x50\x45\
-\x20\x73\x76\x67\x20\x50\x55\x42\x4c\x49\x43\x20\x22\x2d\x2f\x2f\
-\x57\x33\x43\x2f\x2f\x44\x54\x44\x20\x53\x56\x47\x20\x31\x2e\x31\
-\x2f\x2f\x45\x4e\x22\x20\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\
-\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x47\x72\x61\x70\x68\x69\x63\
-\x73\x2f\x53\x56\x47\x2f\x31\x2e\x31\x2f\x44\x54\x44\x2f\x73\x76\
-\x67\x31\x31\x2e\x64\x74\x64\x22\x3e\x0d\x0a\x3c\x73\x76\x67\x20\
-\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\x31\x22\x20\x69\x64\
-\x3d\x22\x4c\x61\x79\x65\x72\x5f\x31\x22\x20\x78\x6d\x6c\x6e\x73\
-\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\
-\x6f\x72\x67\x2f\x32\x30\x30\x30\x2f\x73\x76\x67\x22\x20\x78\x6d\
-\x6c\x6e\x73\x3a\x78\x6c\x69\x6e\x6b\x3d\x22\x68\x74\x74\x70\x3a\
-\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x31\x39\x39\
-\x39\x2f\x78\x6c\x69\x6e\x6b\x22\x20\x78\x3d\x22\x30\x70\x78\x22\
-\x20\x79\x3d\x22\x30\x70\x78\x22\x0d\x0a\x09\x20\x77\x69\x64\x74\
-\x68\x3d\x22\x35\x31\x32\x70\x78\x22\x20\x68\x65\x69\x67\x68\x74\
-\x3d\x22\x35\x31\x32\x70\x78\x22\x20\x76\x69\x65\x77\x42\x6f\x78\
-\x3d\x22\x30\x20\x30\x20\x35\x31\x32\x20\x35\x31\x32\x22\x20\x65\
-\x6e\x61\x62\x6c\x65\x2d\x62\x61\x63\x6b\x67\x72\x6f\x75\x6e\x64\
-\x3d\x22\x6e\x65\x77\x20\x30\x20\x30\x20\x35\x31\x32\x20\x35\x31\
-\x32\x22\x20\x78\x6d\x6c\x3a\x73\x70\x61\x63\x65\x3d\x22\x70\x72\
-\x65\x73\x65\x72\x76\x65\x22\x3e\x0d\x0a\x3c\x67\x20\x69\x64\x3d\
-\x22\x49\x63\x6f\x6e\x22\x3e\x0d\x0a\x09\x3c\x67\x3e\x0d\x0a\x09\
-\x09\x3c\x70\x61\x74\x68\x20\x64\x3d\x22\x4d\x32\x35\x36\x2c\x31\
-\x37\x36\x63\x2d\x34\x34\x2e\x30\x30\x34\x2c\x30\x2d\x38\x30\x2e\
-\x30\x30\x31\x2c\x33\x36\x2d\x38\x30\x2e\x30\x30\x31\x2c\x38\x30\
-\x63\x30\x2c\x34\x34\x2e\x30\x30\x34\x2c\x33\x35\x2e\x39\x39\x37\
-\x2c\x38\x30\x2c\x38\x30\x2e\x30\x30\x31\x2c\x38\x30\x63\x34\x34\
-\x2e\x30\x30\x35\x2c\x30\x2c\x37\x39\x2e\x39\x39\x39\x2d\x33\x35\
-\x2e\x39\x39\x36\x2c\x37\x39\x2e\x39\x39\x39\x2d\x38\x30\x0d\x0a\
-\x09\x09\x09\x43\x33\x33\x35\x2e\x39\x39\x39\x2c\x32\x31\x32\x2c\
-\x33\x30\x30\x2e\x30\x30\x35\x2c\x31\x37\x36\x2c\x32\x35\x36\x2c\
-\x31\x37\x36\x7a\x20\x4d\x34\x34\x36\x2e\x39\x33\x38\x2c\x32\x33\
-\x34\x2e\x36\x36\x37\x63\x2d\x39\x2e\x36\x30\x35\x2d\x38\x38\x2e\
-\x35\x33\x31\x2d\x38\x31\x2e\x30\x37\x34\x2d\x31\x36\x30\x2d\x31\
-\x36\x39\x2e\x36\x30\x35\x2d\x31\x36\x39\x2e\x35\x39\x39\x56\x33\
-\x32\x68\x2d\x34\x32\x2e\x36\x36\x36\x76\x33\x33\x2e\x30\x36\x37\
-\x0d\x0a\x09\x09\x09\x63\x2d\x38\x38\x2e\x35\x33\x31\x2c\x39\x2e\
-\x35\x39\x39\x2d\x31\x36\x30\x2c\x38\x31\x2e\x30\x36\x38\x2d\x31\
-\x36\x39\x2e\x36\x30\x34\x2c\x31\x36\x39\x2e\x35\x39\x39\x48\x33\
-\x32\x76\x34\x32\x2e\x36\x36\x37\x68\x33\x33\x2e\x30\x36\x32\x63\
-\x39\x2e\x36\x30\x34\x2c\x38\x38\x2e\x35\x33\x31\x2c\x38\x31\x2e\
-\x30\x37\x32\x2c\x31\x36\x30\x2c\x31\x36\x39\x2e\x36\x30\x34\x2c\
-\x31\x36\x39\x2e\x36\x30\x34\x56\x34\x38\x30\x68\x34\x32\x2e\x36\
-\x36\x36\x76\x2d\x33\x33\x2e\x30\x36\x32\x0d\x0a\x09\x09\x09\x63\
-\x38\x38\x2e\x35\x33\x31\x2d\x39\x2e\x36\x30\x34\x2c\x31\x36\x30\
-\x2d\x38\x31\x2e\x30\x37\x33\x2c\x31\x36\x39\x2e\x36\x30\x35\x2d\
-\x31\x36\x39\x2e\x36\x30\x34\x48\x34\x38\x30\x76\x2d\x34\x32\x2e\
-\x36\x36\x37\x48\x34\x34\x36\x2e\x39\x33\x38\x7a\x20\x4d\x32\x35\
-\x36\x2c\x34\x30\x35\x2e\x33\x33\x33\x63\x2d\x38\x32\x2e\x31\x33\
-\x37\x2c\x30\x2d\x31\x34\x39\x2e\x33\x33\x34\x2d\x36\x37\x2e\x31\
-\x39\x38\x2d\x31\x34\x39\x2e\x33\x33\x34\x2d\x31\x34\x39\x2e\x33\
-\x33\x33\x0d\x0a\x09\x09\x09\x63\x30\x2d\x38\x32\x2e\x31\x33\x36\
-\x2c\x36\x37\x2e\x31\x39\x37\x2d\x31\x34\x39\x2e\x33\x33\x33\x2c\
-\x31\x34\x39\x2e\x33\x33\x34\x2d\x31\x34\x39\x2e\x33\x33\x33\x63\
-\x38\x32\x2e\x31\x33\x35\x2c\x30\x2c\x31\x34\x39\x2e\x33\x33\x32\
-\x2c\x36\x37\x2e\x31\x39\x38\x2c\x31\x34\x39\x2e\x33\x33\x32\x2c\
-\x31\x34\x39\x2e\x33\x33\x33\x43\x34\x30\x35\x2e\x33\x33\x32\x2c\
-\x33\x33\x38\x2e\x31\x33\x35\x2c\x33\x33\x38\x2e\x31\x33\x35\x2c\
-\x34\x30\x35\x2e\x33\x33\x33\x2c\x32\x35\x36\x2c\x34\x30\x35\x2e\
-\x33\x33\x33\x7a\x0d\x0a\x09\x09\x09\x22\x2f\x3e\x0d\x0a\x09\x3c\
-\x2f\x67\x3e\x0d\x0a\x3c\x2f\x67\x3e\x0d\x0a\x3c\x2f\x73\x76\x67\
-\x3e\x0d\x0a\
-\x00\x00\x02\xa2\
-\x3c\
-\x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\
-\x30\x22\x20\x65\x6e\x63\x6f\x64\x69\x6e\x67\x3d\x22\x75\x74\x66\
-\x2d\x38\x22\x3f\x3e\x0d\x0a\x3c\x21\x2d\x2d\x20\x47\x65\x6e\x65\
-\x72\x61\x74\x6f\x72\x3a\x20\x41\x64\x6f\x62\x65\x20\x49\x6c\x6c\
-\x75\x73\x74\x72\x61\x74\x6f\x72\x20\x31\x36\x2e\x32\x2e\x31\x2c\
-\x20\x53\x56\x47\x20\x45\x78\x70\x6f\x72\x74\x20\x50\x6c\x75\x67\
-\x2d\x49\x6e\x20\x2e\x20\x53\x56\x47\x20\x56\x65\x72\x73\x69\x6f\
-\x6e\x3a\x20\x36\x2e\x30\x30\x20\x42\x75\x69\x6c\x64\x20\x30\x29\
-\x20\x20\x2d\x2d\x3e\x0d\x0a\x3c\x21\x44\x4f\x43\x54\x59\x50\x45\
-\x20\x73\x76\x67\x20\x50\x55\x42\x4c\x49\x43\x20\x22\x2d\x2f\x2f\
-\x57\x33\x43\x2f\x2f\x44\x54\x44\x20\x53\x56\x47\x20\x31\x2e\x31\
-\x2f\x2f\x45\x4e\x22\x20\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\
-\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x47\x72\x61\x70\x68\x69\x63\
-\x73\x2f\x53\x56\x47\x2f\x31\x2e\x31\x2f\x44\x54\x44\x2f\x73\x76\
-\x67\x31\x31\x2e\x64\x74\x64\x22\x3e\x0d\x0a\x3c\x73\x76\x67\x20\
-\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\x31\x22\x20\x69\x64\
-\x3d\x22\x4c\x61\x79\x65\x72\x5f\x31\x22\x20\x78\x6d\x6c\x6e\x73\
-\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\
-\x6f\x72\x67\x2f\x32\x30\x30\x30\x2f\x73\x76\x67\x22\x20\x78\x6d\
-\x6c\x6e\x73\x3a\x78\x6c\x69\x6e\x6b\x3d\x22\x68\x74\x74\x70\x3a\
-\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x31\x39\x39\
-\x39\x2f\x78\x6c\x69\x6e\x6b\x22\x20\x78\x3d\x22\x30\x70\x78\x22\
-\x20\x79\x3d\x22\x30\x70\x78\x22\x0d\x0a\x09\x20\x77\x69\x64\x74\
-\x68\x3d\x22\x35\x31\x32\x70\x78\x22\x20\x68\x65\x69\x67\x68\x74\
-\x3d\x22\x35\x31\x32\x70\x78\x22\x20\x76\x69\x65\x77\x42\x6f\x78\
-\x3d\x22\x30\x20\x30\x20\x35\x31\x32\x20\x35\x31\x32\x22\x20\x65\
-\x6e\x61\x62\x6c\x65\x2d\x62\x61\x63\x6b\x67\x72\x6f\x75\x6e\x64\
-\x3d\x22\x6e\x65\x77\x20\x30\x20\x30\x20\x35\x31\x32\x20\x35\x31\
-\x32\x22\x20\x78\x6d\x6c\x3a\x73\x70\x61\x63\x65\x3d\x22\x70\x72\
-\x65\x73\x65\x72\x76\x65\x22\x3e\x0d\x0a\x3c\x67\x3e\x0d\x0a\x09\
-\x3c\x70\x61\x74\x68\x20\x64\x3d\x22\x4d\x31\x32\x38\x2c\x34\x30\
-\x35\x2e\x34\x32\x39\x43\x31\x32\x38\x2c\x34\x32\x38\x2e\x38\x34\
-\x36\x2c\x31\x34\x37\x2e\x31\x39\x38\x2c\x34\x34\x38\x2c\x31\x37\
-\x30\x2e\x36\x36\x37\x2c\x34\x34\x38\x68\x31\x37\x30\x2e\x36\x36\
-\x37\x43\x33\x36\x34\x2e\x38\x30\x32\x2c\x34\x34\x38\x2c\x33\x38\
-\x34\x2c\x34\x32\x38\x2e\x38\x34\x36\x2c\x33\x38\x34\x2c\x34\x30\
-\x35\x2e\x34\x32\x39\x56\x31\x36\x30\x48\x31\x32\x38\x56\x34\x30\
-\x35\x2e\x34\x32\x39\x7a\x20\x4d\x34\x31\x36\x2c\x39\x36\x0d\x0a\
-\x09\x09\x68\x2d\x38\x30\x6c\x2d\x32\x36\x2e\x37\x38\x35\x2d\x33\
-\x32\x48\x32\x30\x32\x2e\x37\x38\x36\x4c\x31\x37\x36\x2c\x39\x36\
-\x48\x39\x36\x76\x33\x32\x68\x33\x32\x30\x56\x39\x36\x7a\x22\x2f\
-\x3e\x0d\x0a\x3c\x2f\x67\x3e\x0d\x0a\x3c\x2f\x73\x76\x67\x3e\x0d\
-\x0a\
-\x00\x00\x02\x7d\
-\x3c\
-\x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\
-\x30\x22\x20\x65\x6e\x63\x6f\x64\x69\x6e\x67\x3d\x22\x75\x74\x66\
-\x2d\x38\x22\x3f\x3e\x0d\x0a\x3c\x21\x2d\x2d\x20\x47\x65\x6e\x65\
-\x72\x61\x74\x6f\x72\x3a\x20\x41\x64\x6f\x62\x65\x20\x49\x6c\x6c\
-\x75\x73\x74\x72\x61\x74\x6f\x72\x20\x31\x36\x2e\x32\x2e\x31\x2c\
-\x20\x53\x56\x47\x20\x45\x78\x70\x6f\x72\x74\x20\x50\x6c\x75\x67\
-\x2d\x49\x6e\x20\x2e\x20\x53\x56\x47\x20\x56\x65\x72\x73\x69\x6f\
-\x6e\x3a\x20\x36\x2e\x30\x30\x20\x42\x75\x69\x6c\x64\x20\x30\x29\
-\x20\x20\x2d\x2d\x3e\x0d\x0a\x3c\x21\x44\x4f\x43\x54\x59\x50\x45\
-\x20\x73\x76\x67\x20\x50\x55\x42\x4c\x49\x43\x20\x22\x2d\x2f\x2f\
-\x57\x33\x43\x2f\x2f\x44\x54\x44\x20\x53\x56\x47\x20\x31\x2e\x31\
-\x2f\x2f\x45\x4e\x22\x20\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\
-\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x47\x72\x61\x70\x68\x69\x63\
-\x73\x2f\x53\x56\x47\x2f\x31\x2e\x31\x2f\x44\x54\x44\x2f\x73\x76\
-\x67\x31\x31\x2e\x64\x74\x64\x22\x3e\x0d\x0a\x3c\x73\x76\x67\x20\
-\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\x31\x22\x20\x69\x64\
-\x3d\x22\x4c\x61\x79\x65\x72\x5f\x31\x22\x20\x78\x6d\x6c\x6e\x73\
-\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\
-\x6f\x72\x67\x2f\x32\x30\x30\x30\x2f\x73\x76\x67\x22\x20\x78\x6d\
-\x6c\x6e\x73\x3a\x78\x6c\x69\x6e\x6b\x3d\x22\x68\x74\x74\x70\x3a\
-\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x31\x39\x39\
-\x39\x2f\x78\x6c\x69\x6e\x6b\x22\x20\x78\x3d\x22\x30\x70\x78\x22\
-\x20\x79\x3d\x22\x30\x70\x78\x22\x0d\x0a\x09\x20\x77\x69\x64\x74\
-\x68\x3d\x22\x35\x31\x32\x70\x78\x22\x20\x68\x65\x69\x67\x68\x74\
-\x3d\x22\x35\x31\x32\x70\x78\x22\x20\x76\x69\x65\x77\x42\x6f\x78\
-\x3d\x22\x30\x20\x30\x20\x35\x31\x32\x20\x35\x31\x32\x22\x20\x65\
-\x6e\x61\x62\x6c\x65\x2d\x62\x61\x63\x6b\x67\x72\x6f\x75\x6e\x64\
-\x3d\x22\x6e\x65\x77\x20\x30\x20\x30\x20\x35\x31\x32\x20\x35\x31\
-\x32\x22\x20\x78\x6d\x6c\x3a\x73\x70\x61\x63\x65\x3d\x22\x70\x72\
-\x65\x73\x65\x72\x76\x65\x22\x3e\x0d\x0a\x3c\x67\x20\x69\x64\x3d\
-\x22\x49\x63\x6f\x6e\x5f\x38\x5f\x22\x3e\x0d\x0a\x09\x3c\x67\x3e\
-\x0d\x0a\x09\x09\x3c\x70\x61\x74\x68\x20\x64\x3d\x22\x4d\x38\x35\
-\x2c\x32\x37\x37\x2e\x33\x37\x35\x68\x32\x35\x39\x2e\x37\x30\x34\
-\x4c\x32\x32\x35\x2e\x30\x30\x32\x2c\x33\x39\x37\x2e\x30\x37\x37\
-\x4c\x32\x35\x36\x2c\x34\x32\x37\x6c\x31\x37\x31\x2d\x31\x37\x31\
-\x4c\x32\x35\x36\x2c\x38\x35\x6c\x2d\x32\x39\x2e\x39\x32\x32\x2c\
-\x32\x39\x2e\x39\x32\x34\x6c\x31\x31\x38\x2e\x36\x32\x36\x2c\x31\
-\x31\x39\x2e\x37\x30\x31\x48\x38\x35\x56\x32\x37\x37\x2e\x33\x37\
-\x35\x7a\x22\x2f\x3e\x0d\x0a\x09\x3c\x2f\x67\x3e\x0d\x0a\x3c\x2f\
-\x67\x3e\x0d\x0a\x3c\x2f\x73\x76\x67\x3e\x0d\x0a\
-\x00\x00\x03\x6c\
-\x3c\
-\x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\
-\x30\x22\x20\x65\x6e\x63\x6f\x64\x69\x6e\x67\x3d\x22\x75\x74\x66\
-\x2d\x38\x22\x3f\x3e\x0d\x0a\x3c\x21\x2d\x2d\x20\x47\x65\x6e\x65\
-\x72\x61\x74\x6f\x72\x3a\x20\x41\x64\x6f\x62\x65\x20\x49\x6c\x6c\
-\x75\x73\x74\x72\x61\x74\x6f\x72\x20\x31\x36\x2e\x32\x2e\x31\x2c\
-\x20\x53\x56\x47\x20\x45\x78\x70\x6f\x72\x74\x20\x50\x6c\x75\x67\
-\x2d\x49\x6e\x20\x2e\x20\x53\x56\x47\x20\x56\x65\x72\x73\x69\x6f\
-\x6e\x3a\x20\x36\x2e\x30\x30\x20\x42\x75\x69\x6c\x64\x20\x30\x29\
-\x20\x20\x2d\x2d\x3e\x0d\x0a\x3c\x21\x44\x4f\x43\x54\x59\x50\x45\
-\x20\x73\x76\x67\x20\x50\x55\x42\x4c\x49\x43\x20\x22\x2d\x2f\x2f\
-\x57\x33\x43\x2f\x2f\x44\x54\x44\x20\x53\x56\x47\x20\x31\x2e\x31\
-\x2f\x2f\x45\x4e\x22\x20\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\
-\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x47\x72\x61\x70\x68\x69\x63\
-\x73\x2f\x53\x56\x47\x2f\x31\x2e\x31\x2f\x44\x54\x44\x2f\x73\x76\
-\x67\x31\x31\x2e\x64\x74\x64\x22\x3e\x0d\x0a\x3c\x73\x76\x67\x20\
-\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\x31\x22\x20\x69\x64\
-\x3d\x22\x4c\x61\x79\x65\x72\x5f\x31\x22\x20\x78\x6d\x6c\x6e\x73\
-\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\
-\x6f\x72\x67\x2f\x32\x30\x30\x30\x2f\x73\x76\x67\x22\x20\x78\x6d\
-\x6c\x6e\x73\x3a\x78\x6c\x69\x6e\x6b\x3d\x22\x68\x74\x74\x70\x3a\
-\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x31\x39\x39\
-\x39\x2f\x78\x6c\x69\x6e\x6b\x22\x20\x78\x3d\x22\x30\x70\x78\x22\
-\x20\x79\x3d\x22\x30\x70\x78\x22\x0d\x0a\x09\x20\x77\x69\x64\x74\
-\x68\x3d\x22\x35\x31\x32\x70\x78\x22\x20\x68\x65\x69\x67\x68\x74\
-\x3d\x22\x35\x31\x32\x70\x78\x22\x20\x76\x69\x65\x77\x42\x6f\x78\
-\x3d\x22\x30\x20\x30\x20\x35\x31\x32\x20\x35\x31\x32\x22\x20\x65\
-\x6e\x61\x62\x6c\x65\x2d\x62\x61\x63\x6b\x67\x72\x6f\x75\x6e\x64\
-\x3d\x22\x6e\x65\x77\x20\x30\x20\x30\x20\x35\x31\x32\x20\x35\x31\
-\x32\x22\x20\x78\x6d\x6c\x3a\x73\x70\x61\x63\x65\x3d\x22\x70\x72\
-\x65\x73\x65\x72\x76\x65\x22\x3e\x0d\x0a\x3c\x67\x3e\x0d\x0a\x09\
-\x0d\x0a\x09\x09\x3c\x72\x65\x63\x74\x20\x78\x3d\x22\x31\x37\x38\
-\x2e\x38\x34\x36\x22\x20\x79\x3d\x22\x39\x32\x2e\x30\x38\x37\x22\
-\x20\x74\x72\x61\x6e\x73\x66\x6f\x72\x6d\x3d\x22\x6d\x61\x74\x72\
-\x69\x78\x28\x2d\x30\x2e\x37\x30\x37\x31\x20\x2d\x30\x2e\x37\x30\
-\x37\x31\x20\x30\x2e\x37\x30\x37\x31\x20\x2d\x30\x2e\x37\x30\x37\
-\x31\x20\x32\x32\x34\x2e\x33\x34\x37\x36\x20\x36\x33\x31\x2e\x31\
-\x34\x39\x38\x29\x22\x20\x77\x69\x64\x74\x68\x3d\x22\x31\x32\x38\
-\x2e\x30\x38\x35\x22\x20\x68\x65\x69\x67\x68\x74\x3d\x22\x33\x35\
-\x34\x2e\x30\x34\x39\x22\x2f\x3e\x0d\x0a\x09\x3c\x70\x61\x74\x68\
-\x20\x64\x3d\x22\x4d\x34\x37\x31\x2e\x37\x32\x33\x2c\x38\x38\x2e\
-\x33\x39\x33\x6c\x2d\x34\x38\x2e\x31\x31\x35\x2d\x34\x38\x2e\x31\
-\x31\x34\x63\x2d\x31\x31\x2e\x37\x32\x33\x2d\x31\x31\x2e\x37\x32\
-\x34\x2d\x33\x31\x2e\x35\x35\x38\x2d\x31\x30\x2e\x38\x39\x36\x2d\
-\x34\x34\x2e\x33\x30\x34\x2c\x31\x2e\x38\x35\x6c\x2d\x34\x35\x2e\
-\x32\x30\x32\x2c\x34\x35\x2e\x32\x30\x33\x6c\x39\x30\x2e\x35\x36\
-\x39\x2c\x39\x30\x2e\x35\x36\x38\x6c\x34\x35\x2e\x32\x30\x32\x2d\
-\x34\x35\x2e\x32\x30\x32\x0d\x0a\x09\x09\x43\x34\x38\x32\x2e\x36\
-\x31\x36\x2c\x31\x31\x39\x2e\x39\x35\x32\x2c\x34\x38\x33\x2e\x34\
-\x34\x35\x2c\x31\x30\x30\x2e\x31\x31\x36\x2c\x34\x37\x31\x2e\x37\
-\x32\x33\x2c\x38\x38\x2e\x33\x39\x33\x7a\x22\x2f\x3e\x0d\x0a\x09\
-\x3c\x70\x6f\x6c\x79\x67\x6f\x6e\x20\x70\x6f\x69\x6e\x74\x73\x3d\
-\x22\x36\x34\x2e\x30\x32\x31\x2c\x33\x36\x33\x2e\x32\x35\x32\x20\
-\x33\x32\x2c\x34\x38\x30\x20\x31\x34\x38\x2e\x37\x33\x37\x2c\x34\
-\x34\x37\x2e\x39\x37\x39\x20\x09\x22\x2f\x3e\x0d\x0a\x3c\x2f\x67\
-\x3e\x0d\x0a\x3c\x2f\x73\x76\x67\x3e\x0d\x0a\
-\x00\x00\x05\x27\
-\x3c\
-\x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\
-\x30\x22\x20\x65\x6e\x63\x6f\x64\x69\x6e\x67\x3d\x22\x75\x74\x66\
-\x2d\x38\x22\x3f\x3e\x0d\x0a\x3c\x21\x2d\x2d\x20\x47\x65\x6e\x65\
-\x72\x61\x74\x6f\x72\x3a\x20\x41\x64\x6f\x62\x65\x20\x49\x6c\x6c\
-\x75\x73\x74\x72\x61\x74\x6f\x72\x20\x31\x36\x2e\x32\x2e\x31\x2c\
-\x20\x53\x56\x47\x20\x45\x78\x70\x6f\x72\x74\x20\x50\x6c\x75\x67\
-\x2d\x49\x6e\x20\x2e\x20\x53\x56\x47\x20\x56\x65\x72\x73\x69\x6f\
-\x6e\x3a\x20\x36\x2e\x30\x30\x20\x42\x75\x69\x6c\x64\x20\x30\x29\
-\x20\x20\x2d\x2d\x3e\x0d\x0a\x3c\x21\x44\x4f\x43\x54\x59\x50\x45\
-\x20\x73\x76\x67\x20\x50\x55\x42\x4c\x49\x43\x20\x22\x2d\x2f\x2f\
-\x57\x33\x43\x2f\x2f\x44\x54\x44\x20\x53\x56\x47\x20\x31\x2e\x31\
-\x2f\x2f\x45\x4e\x22\x20\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\
-\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x47\x72\x61\x70\x68\x69\x63\
-\x73\x2f\x53\x56\x47\x2f\x31\x2e\x31\x2f\x44\x54\x44\x2f\x73\x76\
-\x67\x31\x31\x2e\x64\x74\x64\x22\x3e\x0d\x0a\x3c\x73\x76\x67\x20\
-\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\x31\x22\x20\x69\x64\
-\x3d\x22\x4c\x61\x79\x65\x72\x5f\x31\x22\x20\x78\x6d\x6c\x6e\x73\
-\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\
-\x6f\x72\x67\x2f\x32\x30\x30\x30\x2f\x73\x76\x67\x22\x20\x78\x6d\
-\x6c\x6e\x73\x3a\x78\x6c\x69\x6e\x6b\x3d\x22\x68\x74\x74\x70\x3a\
-\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x31\x39\x39\
-\x39\x2f\x78\x6c\x69\x6e\x6b\x22\x20\x78\x3d\x22\x30\x70\x78\x22\
-\x20\x79\x3d\x22\x30\x70\x78\x22\x0d\x0a\x09\x20\x77\x69\x64\x74\
-\x68\x3d\x22\x35\x31\x32\x70\x78\x22\x20\x68\x65\x69\x67\x68\x74\
-\x3d\x22\x35\x31\x32\x70\x78\x22\x20\x76\x69\x65\x77\x42\x6f\x78\
-\x3d\x22\x30\x20\x30\x20\x35\x31\x32\x20\x35\x31\x32\x22\x20\x65\
-\x6e\x61\x62\x6c\x65\x2d\x62\x61\x63\x6b\x67\x72\x6f\x75\x6e\x64\
-\x3d\x22\x6e\x65\x77\x20\x30\x20\x30\x20\x35\x31\x32\x20\x35\x31\
-\x32\x22\x20\x78\x6d\x6c\x3a\x73\x70\x61\x63\x65\x3d\x22\x70\x72\
-\x65\x73\x65\x72\x76\x65\x22\x3e\x0d\x0a\x3c\x67\x20\x69\x64\x3d\
-\x22\x49\x63\x6f\x6e\x5f\x31\x32\x5f\x22\x3e\x0d\x0a\x09\x3c\x67\
-\x3e\x0d\x0a\x09\x09\x3c\x70\x61\x74\x68\x20\x64\x3d\x22\x4d\x32\
-\x35\x36\x2c\x36\x34\x43\x31\x35\x30\x2e\x34\x30\x31\x2c\x36\x34\
-\x2c\x36\x34\x2c\x31\x35\x30\x2e\x34\x30\x31\x2c\x36\x34\x2c\x32\
-\x35\x36\x63\x30\x2c\x31\x30\x35\x2e\x36\x30\x34\x2c\x38\x36\x2e\
-\x34\x30\x31\x2c\x31\x39\x32\x2c\x31\x39\x32\x2c\x31\x39\x32\x63\
-\x31\x38\x2e\x31\x33\x36\x2c\x30\x2c\x33\x32\x2d\x31\x33\x2e\x38\
-\x36\x34\x2c\x33\x32\x2d\x33\x32\x0d\x0a\x09\x09\x09\x63\x30\x2d\
-\x38\x2e\x35\x33\x31\x2d\x33\x2e\x31\x39\x38\x2d\x31\x36\x2d\x38\
-\x2e\x35\x33\x31\x2d\x32\x31\x2e\x33\x33\x33\x63\x2d\x35\x2e\x33\
-\x33\x33\x2d\x35\x2e\x33\x33\x34\x2d\x38\x2e\x35\x33\x31\x2d\x31\
-\x32\x2e\x38\x30\x33\x2d\x38\x2e\x35\x33\x31\x2d\x32\x31\x2e\x33\
-\x33\x34\x63\x30\x2d\x31\x38\x2e\x31\x33\x35\x2c\x31\x33\x2e\x38\
-\x36\x34\x2d\x33\x32\x2c\x33\x32\x2d\x33\x32\x68\x33\x38\x2e\x33\
-\x39\x36\x0d\x0a\x09\x09\x09\x63\x35\x38\x2e\x36\x36\x37\x2c\x30\
-\x2c\x31\x30\x36\x2e\x36\x36\x37\x2d\x34\x38\x2c\x31\x30\x36\x2e\
-\x36\x36\x37\x2d\x31\x30\x36\x2e\x36\x36\x36\x43\x34\x34\x38\x2c\
-\x31\x34\x30\x2e\x38\x30\x32\x2c\x33\x36\x31\x2e\x36\x30\x34\x2c\
-\x36\x34\x2c\x32\x35\x36\x2c\x36\x34\x7a\x20\x4d\x31\x33\x38\x2e\
-\x36\x36\x37\x2c\x32\x35\x36\x63\x2d\x31\x38\x2e\x31\x33\x36\x2c\
-\x30\x2d\x33\x32\x2d\x31\x33\x2e\x38\x36\x34\x2d\x33\x32\x2d\x33\
-\x32\x73\x31\x33\x2e\x38\x36\x34\x2d\x33\x32\x2c\x33\x32\x2d\x33\
-\x32\x0d\x0a\x09\x09\x09\x63\x31\x38\x2e\x31\x33\x35\x2c\x30\x2c\
-\x33\x32\x2c\x31\x33\x2e\x38\x36\x34\x2c\x33\x32\x2c\x33\x32\x53\
-\x31\x35\x36\x2e\x38\x30\x32\x2c\x32\x35\x36\x2c\x31\x33\x38\x2e\
-\x36\x36\x37\x2c\x32\x35\x36\x7a\x20\x4d\x32\x30\x32\x2e\x36\x36\
-\x37\x2c\x31\x37\x30\x2e\x36\x36\x37\x63\x2d\x31\x38\x2e\x31\x33\
-\x36\x2c\x30\x2d\x33\x32\x2d\x31\x33\x2e\x38\x36\x35\x2d\x33\x32\
-\x2d\x33\x32\x63\x30\x2d\x31\x38\x2e\x31\x33\x36\x2c\x31\x33\x2e\
-\x38\x36\x34\x2d\x33\x32\x2c\x33\x32\x2d\x33\x32\x0d\x0a\x09\x09\
-\x09\x63\x31\x38\x2e\x31\x33\x35\x2c\x30\x2c\x33\x32\x2c\x31\x33\
-\x2e\x38\x36\x34\x2c\x33\x32\x2c\x33\x32\x43\x32\x33\x34\x2e\x36\
-\x36\x37\x2c\x31\x35\x36\x2e\x38\x30\x32\x2c\x32\x32\x30\x2e\x38\
-\x30\x32\x2c\x31\x37\x30\x2e\x36\x36\x37\x2c\x32\x30\x32\x2e\x36\
-\x36\x37\x2c\x31\x37\x30\x2e\x36\x36\x37\x7a\x20\x4d\x33\x30\x39\
-\x2e\x33\x33\x33\x2c\x31\x37\x30\x2e\x36\x36\x37\x63\x2d\x31\x38\
-\x2e\x31\x33\x35\x2c\x30\x2d\x33\x32\x2d\x31\x33\x2e\x38\x36\x35\
-\x2d\x33\x32\x2d\x33\x32\x0d\x0a\x09\x09\x09\x63\x30\x2d\x31\x38\
-\x2e\x31\x33\x36\x2c\x31\x33\x2e\x38\x36\x35\x2d\x33\x32\x2c\x33\
-\x32\x2d\x33\x32\x63\x31\x38\x2e\x31\x33\x36\x2c\x30\x2c\x33\x32\
-\x2c\x31\x33\x2e\x38\x36\x34\x2c\x33\x32\x2c\x33\x32\x43\x33\x34\
-\x31\x2e\x33\x33\x33\x2c\x31\x35\x36\x2e\x38\x30\x32\x2c\x33\x32\
-\x37\x2e\x34\x36\x39\x2c\x31\x37\x30\x2e\x36\x36\x37\x2c\x33\x30\
-\x39\x2e\x33\x33\x33\x2c\x31\x37\x30\x2e\x36\x36\x37\x7a\x20\x4d\
-\x33\x37\x33\x2e\x33\x33\x33\x2c\x32\x35\x36\x0d\x0a\x09\x09\x09\
-\x63\x2d\x31\x38\x2e\x31\x33\x35\x2c\x30\x2d\x33\x32\x2d\x31\x33\
-\x2e\x38\x36\x34\x2d\x33\x32\x2d\x33\x32\x73\x31\x33\x2e\x38\x36\
-\x35\x2d\x33\x32\x2c\x33\x32\x2d\x33\x32\x63\x31\x38\x2e\x31\x33\
-\x36\x2c\x30\x2c\x33\x32\x2c\x31\x33\x2e\x38\x36\x34\x2c\x33\x32\
-\x2c\x33\x32\x53\x33\x39\x31\x2e\x34\x36\x39\x2c\x32\x35\x36\x2c\
-\x33\x37\x33\x2e\x33\x33\x33\x2c\x32\x35\x36\x7a\x22\x2f\x3e\x0d\
-\x0a\x09\x3c\x2f\x67\x3e\x0d\x0a\x3c\x2f\x67\x3e\x0d\x0a\x3c\x2f\
-\x73\x76\x67\x3e\x0d\x0a\
-\x00\x00\x02\x79\
-\x3c\
-\x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\
-\x30\x22\x20\x65\x6e\x63\x6f\x64\x69\x6e\x67\x3d\x22\x75\x74\x66\
-\x2d\x38\x22\x3f\x3e\x0d\x0a\x3c\x21\x2d\x2d\x20\x47\x65\x6e\x65\
-\x72\x61\x74\x6f\x72\x3a\x20\x41\x64\x6f\x62\x65\x20\x49\x6c\x6c\
-\x75\x73\x74\x72\x61\x74\x6f\x72\x20\x31\x36\x2e\x32\x2e\x31\x2c\
-\x20\x53\x56\x47\x20\x45\x78\x70\x6f\x72\x74\x20\x50\x6c\x75\x67\
-\x2d\x49\x6e\x20\x2e\x20\x53\x56\x47\x20\x56\x65\x72\x73\x69\x6f\
-\x6e\x3a\x20\x36\x2e\x30\x30\x20\x42\x75\x69\x6c\x64\x20\x30\x29\
-\x20\x20\x2d\x2d\x3e\x0d\x0a\x3c\x21\x44\x4f\x43\x54\x59\x50\x45\
-\x20\x73\x76\x67\x20\x50\x55\x42\x4c\x49\x43\x20\x22\x2d\x2f\x2f\
-\x57\x33\x43\x2f\x2f\x44\x54\x44\x20\x53\x56\x47\x20\x31\x2e\x31\
-\x2f\x2f\x45\x4e\x22\x20\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\
-\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x47\x72\x61\x70\x68\x69\x63\
-\x73\x2f\x53\x56\x47\x2f\x31\x2e\x31\x2f\x44\x54\x44\x2f\x73\x76\
-\x67\x31\x31\x2e\x64\x74\x64\x22\x3e\x0d\x0a\x3c\x73\x76\x67\x20\
-\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\x31\x22\x20\x69\x64\
-\x3d\x22\x4c\x61\x79\x65\x72\x5f\x31\x22\x20\x78\x6d\x6c\x6e\x73\
-\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\
-\x6f\x72\x67\x2f\x32\x30\x30\x30\x2f\x73\x76\x67\x22\x20\x78\x6d\
-\x6c\x6e\x73\x3a\x78\x6c\x69\x6e\x6b\x3d\x22\x68\x74\x74\x70\x3a\
-\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x31\x39\x39\
-\x39\x2f\x78\x6c\x69\x6e\x6b\x22\x20\x78\x3d\x22\x30\x70\x78\x22\
-\x20\x79\x3d\x22\x30\x70\x78\x22\x0d\x0a\x09\x20\x77\x69\x64\x74\
-\x68\x3d\x22\x35\x31\x32\x70\x78\x22\x20\x68\x65\x69\x67\x68\x74\
-\x3d\x22\x35\x31\x32\x70\x78\x22\x20\x76\x69\x65\x77\x42\x6f\x78\
-\x3d\x22\x30\x20\x30\x20\x35\x31\x32\x20\x35\x31\x32\x22\x20\x65\
-\x6e\x61\x62\x6c\x65\x2d\x62\x61\x63\x6b\x67\x72\x6f\x75\x6e\x64\
-\x3d\x22\x6e\x65\x77\x20\x30\x20\x30\x20\x35\x31\x32\x20\x35\x31\
-\x32\x22\x20\x78\x6d\x6c\x3a\x73\x70\x61\x63\x65\x3d\x22\x70\x72\
-\x65\x73\x65\x72\x76\x65\x22\x3e\x0d\x0a\x3c\x67\x20\x69\x64\x3d\
-\x22\x49\x63\x6f\x6e\x5f\x31\x5f\x22\x3e\x0d\x0a\x09\x3c\x67\x3e\
-\x0d\x0a\x09\x09\x3c\x67\x3e\x0d\x0a\x09\x09\x09\x3c\x70\x6f\x6c\
-\x79\x67\x6f\x6e\x20\x70\x6f\x69\x6e\x74\x73\x3d\x22\x31\x38\x36\
-\x2e\x33\x30\x31\x2c\x33\x33\x39\x2e\x38\x39\x33\x20\x39\x36\x2c\
-\x32\x34\x39\x2e\x34\x36\x31\x20\x36\x34\x2c\x32\x37\x39\x2e\x39\
-\x36\x38\x20\x31\x38\x36\x2e\x33\x30\x31\x2c\x34\x30\x32\x20\x34\
-\x34\x38\x2c\x31\x34\x30\x2e\x35\x30\x36\x20\x34\x31\x36\x2c\x31\
-\x31\x30\x20\x09\x09\x09\x22\x2f\x3e\x0d\x0a\x09\x09\x3c\x2f\x67\
-\x3e\x0d\x0a\x09\x3c\x2f\x67\x3e\x0d\x0a\x3c\x2f\x67\x3e\x0d\x0a\
-\x3c\x2f\x73\x76\x67\x3e\x0d\x0a\
-\x00\x00\x07\x80\
-\x3c\
-\x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\
-\x30\x22\x20\x65\x6e\x63\x6f\x64\x69\x6e\x67\x3d\x22\x75\x74\x66\
-\x2d\x38\x22\x3f\x3e\x0d\x0a\x3c\x21\x2d\x2d\x20\x47\x65\x6e\x65\
-\x72\x61\x74\x6f\x72\x3a\x20\x41\x64\x6f\x62\x65\x20\x49\x6c\x6c\
-\x75\x73\x74\x72\x61\x74\x6f\x72\x20\x31\x36\x2e\x32\x2e\x31\x2c\
-\x20\x53\x56\x47\x20\x45\x78\x70\x6f\x72\x74\x20\x50\x6c\x75\x67\
-\x2d\x49\x6e\x20\x2e\x20\x53\x56\x47\x20\x56\x65\x72\x73\x69\x6f\
-\x6e\x3a\x20\x36\x2e\x30\x30\x20\x42\x75\x69\x6c\x64\x20\x30\x29\
-\x20\x20\x2d\x2d\x3e\x0d\x0a\x3c\x21\x44\x4f\x43\x54\x59\x50\x45\
-\x20\x73\x76\x67\x20\x50\x55\x42\x4c\x49\x43\x20\x22\x2d\x2f\x2f\
-\x57\x33\x43\x2f\x2f\x44\x54\x44\x20\x53\x56\x47\x20\x31\x2e\x31\
-\x2f\x2f\x45\x4e\x22\x20\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\
-\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x47\x72\x61\x70\x68\x69\x63\
-\x73\x2f\x53\x56\x47\x2f\x31\x2e\x31\x2f\x44\x54\x44\x2f\x73\x76\
-\x67\x31\x31\x2e\x64\x74\x64\x22\x3e\x0d\x0a\x3c\x73\x76\x67\x20\
-\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\x31\x22\x20\x69\x64\
-\x3d\x22\x4c\x61\x79\x65\x72\x5f\x31\x22\x20\x78\x6d\x6c\x6e\x73\
-\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\
-\x6f\x72\x67\x2f\x32\x30\x30\x30\x2f\x73\x76\x67\x22\x20\x78\x6d\
-\x6c\x6e\x73\x3a\x78\x6c\x69\x6e\x6b\x3d\x22\x68\x74\x74\x70\x3a\
-\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x31\x39\x39\
-\x39\x2f\x78\x6c\x69\x6e\x6b\x22\x20\x78\x3d\x22\x30\x70\x78\x22\
-\x20\x79\x3d\x22\x30\x70\x78\x22\x0d\x0a\x09\x20\x77\x69\x64\x74\
-\x68\x3d\x22\x35\x31\x32\x70\x78\x22\x20\x68\x65\x69\x67\x68\x74\
-\x3d\x22\x35\x31\x32\x70\x78\x22\x20\x76\x69\x65\x77\x42\x6f\x78\
-\x3d\x22\x30\x20\x30\x20\x35\x31\x32\x20\x35\x31\x32\x22\x20\x65\
-\x6e\x61\x62\x6c\x65\x2d\x62\x61\x63\x6b\x67\x72\x6f\x75\x6e\x64\
-\x3d\x22\x6e\x65\x77\x20\x30\x20\x30\x20\x35\x31\x32\x20\x35\x31\
-\x32\x22\x20\x78\x6d\x6c\x3a\x73\x70\x61\x63\x65\x3d\x22\x70\x72\
-\x65\x73\x65\x72\x76\x65\x22\x3e\x0d\x0a\x3c\x67\x3e\x0d\x0a\x09\
-\x3c\x70\x61\x74\x68\x20\x64\x3d\x22\x4d\x31\x39\x33\x2e\x34\x36\
-\x2c\x32\x34\x39\x2e\x30\x35\x36\x63\x33\x2e\x37\x32\x33\x2d\x30\
-\x2e\x36\x37\x2c\x37\x2e\x35\x38\x39\x2d\x31\x2e\x30\x34\x31\x2c\
-\x31\x31\x2e\x35\x38\x36\x2d\x31\x2e\x30\x34\x31\x4c\x32\x30\x31\
-\x2e\x39\x32\x34\x2c\x32\x34\x38\x68\x31\x30\x33\x2e\x38\x32\x33\
-\x63\x34\x2e\x35\x30\x33\x2c\x30\x2c\x38\x2e\x38\x30\x36\x2d\x30\
-\x2e\x36\x31\x37\x2c\x31\x32\x2e\x39\x30\x38\x2d\x31\x2e\x37\x35\
-\x34\x0d\x0a\x09\x09\x63\x31\x39\x2e\x33\x37\x2d\x35\x2e\x33\x36\
-\x33\x2c\x33\x33\x2e\x33\x34\x35\x2d\x32\x32\x2e\x35\x33\x37\x2c\
-\x33\x33\x2e\x33\x34\x35\x2d\x34\x33\x2e\x36\x36\x33\x76\x2d\x33\
-\x30\x2e\x38\x32\x32\x76\x2d\x35\x36\x2e\x34\x30\x32\x63\x30\x2d\
-\x32\x34\x2e\x38\x33\x32\x2d\x32\x31\x2e\x31\x35\x2d\x34\x33\x2e\
-\x34\x38\x34\x2d\x34\x36\x2e\x32\x38\x39\x2d\x34\x37\x2e\x36\x30\
-\x36\x0d\x0a\x09\x09\x63\x2d\x31\x35\x2e\x39\x33\x31\x2d\x32\x2e\
-\x36\x32\x34\x2d\x33\x39\x2e\x32\x35\x38\x2d\x33\x2e\x38\x32\x37\
-\x2d\x35\x35\x2e\x30\x38\x39\x2d\x33\x2e\x37\x34\x39\x63\x2d\x31\
-\x35\x2e\x38\x32\x39\x2c\x30\x2e\x30\x38\x36\x2d\x33\x30\x2e\x39\
-\x38\x31\x2c\x31\x2e\x34\x30\x34\x2d\x34\x34\x2e\x32\x37\x37\x2c\
-\x33\x2e\x37\x34\x39\x43\x31\x36\x37\x2e\x31\x34\x33\x2c\x37\x34\
-\x2e\x35\x37\x36\x2c\x31\x36\x30\x2c\x38\x38\x2e\x39\x32\x38\x2c\
-\x31\x36\x30\x2c\x31\x31\x35\x2e\x33\x35\x39\x56\x31\x34\x34\x68\
-\x39\x36\x0d\x0a\x09\x09\x76\x31\x36\x48\x31\x32\x38\x2e\x38\x32\
-\x63\x2d\x33\x35\x2e\x36\x32\x38\x2c\x30\x2d\x36\x34\x2e\x35\x33\
-\x38\x2c\x34\x32\x2e\x35\x37\x31\x2d\x36\x34\x2e\x38\x31\x33\x2c\
-\x39\x35\x2e\x32\x34\x32\x43\x36\x34\x2e\x30\x30\x35\x2c\x32\x35\
-\x35\x2e\x34\x39\x35\x2c\x36\x34\x2c\x32\x35\x35\x2e\x37\x34\x37\
-\x2c\x36\x34\x2c\x32\x35\x36\x63\x30\x2c\x39\x2e\x35\x32\x33\x2c\
-\x30\x2e\x39\x34\x2c\x31\x38\x2e\x37\x32\x2c\x32\x2e\x36\x38\x35\
-\x2c\x32\x37\x2e\x34\x30\x34\x0d\x0a\x09\x09\x43\x37\x34\x2e\x36\
-\x34\x38\x2c\x33\x32\x33\x2e\x30\x37\x2c\x39\x39\x2e\x34\x35\x31\
-\x2c\x33\x35\x32\x2c\x31\x32\x38\x2e\x38\x32\x2c\x33\x35\x32\x48\
-\x31\x34\x34\x76\x2d\x32\x2e\x36\x36\x32\x76\x2d\x34\x33\x2e\x32\
-\x37\x33\x43\x31\x34\x34\x2c\x32\x37\x39\x2e\x32\x33\x38\x2c\x31\
-\x36\x34\x2e\x31\x34\x36\x2c\x32\x35\x34\x2e\x33\x33\x32\x2c\x31\
-\x39\x33\x2e\x34\x36\x2c\x32\x34\x39\x2e\x30\x35\x36\x7a\x20\x4d\
-\x32\x30\x33\x2e\x36\x35\x36\x2c\x31\x32\x37\x2e\x30\x30\x32\x0d\
-\x0a\x09\x09\x63\x2d\x39\x2e\x35\x39\x32\x2c\x30\x2d\x31\x37\x2e\
-\x33\x38\x34\x2d\x37\x2e\x37\x38\x35\x2d\x31\x37\x2e\x33\x38\x34\
-\x2d\x31\x37\x2e\x34\x30\x33\x63\x30\x2d\x39\x2e\x36\x36\x34\x2c\
-\x37\x2e\x37\x37\x34\x2d\x31\x37\x2e\x35\x32\x2c\x31\x37\x2e\x33\
-\x38\x34\x2d\x31\x37\x2e\x35\x32\x63\x39\x2e\x35\x37\x34\x2c\x30\
-\x2c\x31\x37\x2e\x33\x39\x39\x2c\x37\x2e\x38\x35\x35\x2c\x31\x37\
-\x2e\x33\x39\x39\x2c\x31\x37\x2e\x35\x32\x0d\x0a\x09\x09\x43\x32\
-\x32\x31\x2e\x30\x35\x36\x2c\x31\x31\x39\x2e\x32\x31\x37\x2c\x32\
-\x31\x33\x2e\x32\x34\x36\x2c\x31\x32\x37\x2e\x30\x30\x32\x2c\x32\
-\x30\x33\x2e\x36\x35\x36\x2c\x31\x32\x37\x2e\x30\x30\x32\x7a\x22\
-\x2f\x3e\x0d\x0a\x09\x3c\x70\x61\x74\x68\x20\x64\x3d\x22\x4d\x34\
-\x34\x33\x2e\x39\x35\x31\x2c\x32\x32\x32\x2e\x35\x34\x33\x43\x34\
-\x33\x34\x2e\x37\x38\x2c\x31\x38\x36\x2e\x30\x32\x31\x2c\x34\x31\
-\x31\x2e\x30\x33\x33\x2c\x31\x36\x30\x2c\x33\x38\x33\x2e\x31\x38\
-\x2c\x31\x36\x30\x48\x33\x36\x38\x76\x32\x2e\x36\x32\x36\x76\x33\
-\x38\x2e\x30\x34\x36\x63\x30\x2c\x33\x33\x2e\x39\x31\x35\x2d\x32\
-\x32\x2e\x32\x38\x36\x2c\x35\x38\x2e\x34\x37\x34\x2d\x34\x39\x2e\
-\x34\x38\x39\x2c\x36\x32\x2e\x36\x38\x31\x0d\x0a\x09\x09\x63\x2d\
-\x32\x2e\x37\x33\x37\x2c\x30\x2e\x34\x32\x34\x2d\x35\x2e\x34\x38\
-\x33\x2c\x30\x2e\x36\x34\x36\x2d\x38\x2e\x33\x30\x31\x2c\x30\x2e\
-\x36\x34\x36\x48\x32\x30\x36\x2e\x33\x35\x31\x63\x2d\x34\x2e\x35\
-\x31\x38\x2c\x30\x2d\x38\x2e\x39\x30\x34\x2c\x30\x2e\x35\x38\x34\
-\x2d\x31\x33\x2e\x30\x34\x39\x2c\x31\x2e\x36\x37\x32\x43\x31\x37\
-\x34\x2e\x31\x38\x2c\x32\x37\x30\x2e\x36\x38\x39\x2c\x31\x36\x30\
-\x2c\x32\x38\x36\x2e\x36\x2c\x31\x36\x30\x2c\x33\x30\x37\x2e\x32\
-\x33\x36\x76\x33\x32\x2e\x39\x32\x32\x0d\x0a\x09\x09\x76\x35\x34\
-\x2e\x33\x30\x35\x63\x30\x2c\x32\x34\x2e\x38\x33\x32\x2c\x32\x34\
-\x2e\x39\x37\x37\x2c\x33\x39\x2e\x34\x32\x36\x2c\x34\x39\x2e\x34\
-\x38\x31\x2c\x34\x36\x2e\x35\x35\x31\x63\x32\x39\x2e\x33\x32\x37\
-\x2c\x38\x2e\x35\x33\x31\x2c\x36\x31\x2e\x32\x36\x37\x2c\x31\x30\
-\x2e\x30\x36\x38\x2c\x39\x36\x2e\x33\x36\x36\x2c\x30\x43\x33\x32\
-\x39\x2e\x31\x35\x2c\x34\x33\x34\x2e\x33\x35\x34\x2c\x33\x35\x32\
-\x2c\x34\x32\x30\x2e\x38\x39\x33\x2c\x33\x35\x32\x2c\x33\x39\x34\
-\x2e\x34\x36\x33\x56\x33\x36\x38\x0d\x0a\x09\x09\x68\x2d\x39\x36\
-\x76\x2d\x31\x36\x68\x31\x32\x37\x2e\x31\x38\x63\x32\x35\x2e\x32\
-\x34\x2c\x30\x2c\x34\x37\x2e\x31\x30\x37\x2d\x32\x31\x2e\x33\x36\
-\x35\x2c\x35\x37\x2e\x38\x31\x34\x2d\x35\x32\x2e\x35\x34\x39\x43\
-\x34\x34\x35\x2e\x34\x37\x34\x2c\x32\x38\x36\x2e\x34\x30\x34\x2c\
-\x34\x34\x38\x2c\x32\x37\x31\x2e\x36\x34\x31\x2c\x34\x34\x38\x2c\
-\x32\x35\x36\x0d\x0a\x09\x09\x43\x34\x34\x38\x2c\x32\x34\x34\x2e\
-\x32\x33\x32\x2c\x34\x34\x36\x2e\x35\x36\x37\x2c\x32\x33\x32\x2e\
-\x39\x36\x32\x2c\x34\x34\x33\x2e\x39\x35\x31\x2c\x32\x32\x32\x2e\
-\x35\x34\x33\x7a\x20\x4d\x33\x30\x37\x2e\x38\x36\x37\x2c\x33\x38\
-\x32\x2e\x38\x32\x63\x39\x2e\x35\x39\x2c\x30\x2c\x31\x37\x2e\x33\
-\x38\x31\x2c\x37\x2e\x37\x38\x35\x2c\x31\x37\x2e\x33\x38\x31\x2c\
-\x31\x37\x2e\x34\x0d\x0a\x09\x09\x63\x30\x2c\x39\x2e\x36\x35\x2d\
-\x37\x2e\x37\x39\x31\x2c\x31\x37\x2e\x35\x32\x31\x2d\x31\x37\x2e\
-\x33\x38\x31\x2c\x31\x37\x2e\x35\x32\x31\x63\x2d\x39\x2e\x35\x37\
-\x37\x2c\x30\x2d\x31\x37\x2e\x33\x39\x39\x2d\x37\x2e\x38\x37\x31\
-\x2d\x31\x37\x2e\x33\x39\x39\x2d\x31\x37\x2e\x35\x32\x31\x43\x32\
-\x39\x30\x2e\x34\x36\x38\x2c\x33\x39\x30\x2e\x35\x39\x2c\x32\x39\
-\x38\x2e\x32\x37\x34\x2c\x33\x38\x32\x2e\x38\x32\x2c\x33\x30\x37\
-\x2e\x38\x36\x37\x2c\x33\x38\x32\x2e\x38\x32\x7a\x22\x2f\x3e\x0d\
-\x0a\x3c\x2f\x67\x3e\x0d\x0a\x3c\x2f\x73\x76\x67\x3e\x0d\x0a\
+\x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x27\x31\x2e\
+\x30\x27\x20\x65\x6e\x63\x6f\x64\x69\x6e\x67\x3d\x27\x55\x54\x46\
+\x2d\x38\x27\x3f\x3e\x0a\x3c\x21\x2d\x2d\x20\x54\x68\x69\x73\x20\
+\x66\x69\x6c\x65\x20\x77\x61\x73\x20\x67\x65\x6e\x65\x72\x61\x74\
+\x65\x64\x20\x62\x79\x20\x64\x76\x69\x73\x76\x67\x6d\x20\x32\x2e\
+\x38\x20\x2d\x2d\x3e\x0a\x3c\x73\x76\x67\x20\x76\x65\x72\x73\x69\
+\x6f\x6e\x3d\x27\x31\x2e\x31\x27\x20\x78\x6d\x6c\x6e\x73\x3d\x27\
+\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\
+\x67\x2f\x32\x30\x30\x30\x2f\x73\x76\x67\x27\x20\x78\x6d\x6c\x6e\
+\x73\x3a\x78\x6c\x69\x6e\x6b\x3d\x27\x68\x74\x74\x70\x3a\x2f\x2f\
+\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x31\x39\x39\x39\x2f\
+\x78\x6c\x69\x6e\x6b\x27\x20\x77\x69\x64\x74\x68\x3d\x27\x36\x33\
+\x2e\x39\x39\x39\x36\x70\x74\x27\x20\x68\x65\x69\x67\x68\x74\x3d\
+\x27\x36\x33\x2e\x39\x39\x39\x37\x70\x74\x27\x20\x76\x69\x65\x77\
+\x42\x6f\x78\x3d\x27\x35\x36\x2e\x34\x30\x39\x34\x20\x35\x33\x2e\
+\x38\x35\x38\x33\x20\x36\x33\x2e\x39\x39\x39\x36\x20\x36\x33\x2e\
+\x39\x39\x39\x37\x27\x3e\x0a\x3c\x67\x20\x69\x64\x3d\x27\x70\x61\
+\x67\x65\x31\x27\x3e\x0a\x3c\x67\x20\x74\x72\x61\x6e\x73\x66\x6f\
+\x72\x6d\x3d\x27\x6d\x61\x74\x72\x69\x78\x28\x30\x2e\x39\x39\x36\
+\x32\x36\x34\x20\x30\x20\x30\x20\x30\x2e\x39\x39\x36\x32\x36\x34\
+\x20\x35\x38\x2e\x34\x36\x36\x39\x20\x31\x31\x37\x2e\x38\x35\x38\
+\x29\x27\x3e\x0a\x3c\x70\x61\x74\x68\x20\x64\x3d\x27\x4d\x20\x33\
+\x2e\x39\x35\x37\x33\x35\x20\x2d\x33\x32\x2e\x31\x32\x43\x20\x32\
+\x2e\x32\x38\x39\x32\x32\x20\x2d\x33\x39\x2e\x33\x31\x31\x33\x20\
+\x36\x2e\x33\x36\x37\x30\x32\x20\x2d\x34\x36\x2e\x32\x33\x38\x36\
+\x20\x31\x31\x2e\x39\x30\x33\x36\x20\x2d\x35\x31\x2e\x33\x30\x33\
+\x39\x43\x20\x32\x39\x2e\x36\x36\x38\x37\x20\x2d\x36\x37\x2e\x35\
+\x35\x36\x38\x20\x35\x35\x2e\x32\x32\x39\x32\x20\x2d\x36\x30\x2e\
+\x36\x34\x32\x20\x35\x36\x2e\x31\x35\x32\x33\x20\x2d\x34\x32\x2e\
+\x35\x30\x32\x32\x43\x20\x35\x36\x2e\x36\x31\x33\x36\x20\x2d\x33\
+\x33\x2e\x34\x33\x38\x31\x20\x34\x39\x2e\x31\x31\x33\x32\x20\x2d\
+\x32\x36\x2e\x35\x39\x35\x39\x20\x34\x30\x2e\x36\x37\x39\x34\x20\
+\x2d\x32\x32\x2e\x35\x32\x38\x31\x43\x20\x32\x35\x2e\x33\x39\x39\
+\x35\x20\x2d\x31\x35\x2e\x31\x35\x38\x32\x20\x37\x2e\x31\x39\x39\
+\x33\x35\x20\x2d\x31\x38\x2e\x31\x34\x33\x36\x20\x33\x2e\x39\x35\
+\x37\x33\x35\x20\x2d\x33\x32\x2e\x31\x32\x5a\x27\x20\x66\x69\x6c\
+\x6c\x3d\x27\x6e\x6f\x6e\x65\x27\x20\x73\x74\x72\x6f\x6b\x65\x3d\
+\x27\x23\x30\x30\x30\x30\x30\x30\x27\x20\x73\x74\x72\x6f\x6b\x65\
+\x2d\x6c\x69\x6e\x65\x63\x61\x70\x3d\x27\x72\x6f\x75\x6e\x64\x27\
+\x20\x73\x74\x72\x6f\x6b\x65\x2d\x6c\x69\x6e\x65\x6a\x6f\x69\x6e\
+\x3d\x27\x72\x6f\x75\x6e\x64\x27\x20\x73\x74\x72\x6f\x6b\x65\x2d\
+\x6d\x69\x74\x65\x72\x6c\x69\x6d\x69\x74\x3d\x27\x31\x30\x2e\x30\
+\x33\x37\x35\x27\x20\x73\x74\x72\x6f\x6b\x65\x2d\x77\x69\x64\x74\
+\x68\x3d\x27\x32\x2e\x35\x30\x39\x33\x37\x27\x2f\x3e\x0a\x3c\x2f\
+\x67\x3e\x0a\x3c\x67\x20\x74\x72\x61\x6e\x73\x66\x6f\x72\x6d\x3d\
+\x27\x6d\x61\x74\x72\x69\x78\x28\x30\x2e\x39\x39\x36\x32\x36\x34\
+\x20\x30\x20\x30\x20\x30\x2e\x39\x39\x36\x32\x36\x34\x20\x35\x38\
+\x2e\x34\x36\x36\x39\x20\x31\x31\x37\x2e\x38\x35\x38\x29\x27\x3e\
+\x0a\x3c\x63\x69\x72\x63\x6c\x65\x20\x63\x78\x3d\x27\x33\x2e\x39\
+\x35\x37\x33\x35\x27\x20\x63\x79\x3d\x27\x2d\x33\x32\x2e\x31\x32\
+\x27\x20\x66\x69\x6c\x6c\x3d\x27\x23\x30\x30\x30\x30\x30\x30\x27\
+\x20\x72\x3d\x27\x36\x2e\x30\x32\x32\x35\x27\x2f\x3e\x0a\x3c\x2f\
+\x67\x3e\x0a\x3c\x67\x20\x74\x72\x61\x6e\x73\x66\x6f\x72\x6d\x3d\
+\x27\x6d\x61\x74\x72\x69\x78\x28\x30\x2e\x39\x39\x36\x32\x36\x34\
+\x20\x30\x20\x30\x20\x30\x2e\x39\x39\x36\x32\x36\x34\x20\x35\x38\
+\x2e\x34\x36\x36\x39\x20\x31\x31\x37\x2e\x38\x35\x38\x29\x27\x3e\
+\x0a\x3c\x63\x69\x72\x63\x6c\x65\x20\x63\x78\x3d\x27\x31\x31\x2e\
+\x39\x30\x33\x36\x27\x20\x63\x79\x3d\x27\x2d\x35\x31\x2e\x33\x30\
+\x33\x39\x27\x20\x66\x69\x6c\x6c\x3d\x27\x23\x30\x30\x30\x30\x30\
+\x30\x27\x20\x72\x3d\x27\x36\x2e\x30\x32\x32\x35\x27\x2f\x3e\x0a\
+\x3c\x2f\x67\x3e\x0a\x3c\x67\x20\x74\x72\x61\x6e\x73\x66\x6f\x72\
+\x6d\x3d\x27\x6d\x61\x74\x72\x69\x78\x28\x30\x2e\x39\x39\x36\x32\
+\x36\x34\x20\x30\x20\x30\x20\x30\x2e\x39\x39\x36\x32\x36\x34\x20\
+\x35\x38\x2e\x34\x36\x36\x39\x20\x31\x31\x37\x2e\x38\x35\x38\x29\
+\x27\x3e\x0a\x3c\x63\x69\x72\x63\x6c\x65\x20\x63\x78\x3d\x27\x35\
+\x36\x2e\x31\x35\x32\x33\x27\x20\x63\x79\x3d\x27\x2d\x34\x32\x2e\
+\x35\x30\x32\x32\x27\x20\x66\x69\x6c\x6c\x3d\x27\x23\x30\x30\x30\
+\x30\x30\x30\x27\x20\x72\x3d\x27\x36\x2e\x30\x32\x32\x35\x27\x2f\
+\x3e\x0a\x3c\x2f\x67\x3e\x0a\x3c\x67\x20\x74\x72\x61\x6e\x73\x66\
+\x6f\x72\x6d\x3d\x27\x6d\x61\x74\x72\x69\x78\x28\x30\x2e\x39\x39\
+\x36\x32\x36\x34\x20\x30\x20\x30\x20\x30\x2e\x39\x39\x36\x32\x36\
+\x34\x20\x35\x38\x2e\x34\x36\x36\x39\x20\x31\x31\x37\x2e\x38\x35\
+\x38\x29\x27\x3e\x0a\x3c\x63\x69\x72\x63\x6c\x65\x20\x63\x78\x3d\
+\x27\x34\x30\x2e\x36\x37\x39\x34\x27\x20\x63\x79\x3d\x27\x2d\x32\
+\x32\x2e\x35\x32\x38\x31\x27\x20\x66\x69\x6c\x6c\x3d\x27\x23\x30\
+\x30\x30\x30\x30\x30\x27\x20\x72\x3d\x27\x36\x2e\x30\x32\x32\x35\
+\x27\x2f\x3e\x0a\x3c\x2f\x67\x3e\x0a\x3c\x2f\x67\x3e\x0a\x3c\x2f\
+\x73\x76\x67\x3e\
 \x00\x00\x03\xeb\
 \x3c\
 \x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\
@@ -645,50 +250,13 @@
 \x2d\x77\x69\x64\x74\x68\x3d\x27\x33\x2e\x35\x31\x33\x31\x32\x27\
 \x2f\x3e\x0a\x3c\x2f\x67\x3e\x0a\x3c\x2f\x67\x3e\x0a\x3c\x2f\x73\
 \x76\x67\x3e\
-\x00\x00\x02\x21\
-\x00\
-\x00\x07\xaf\x78\x9c\xdd\x55\x4d\x6f\x9c\x30\x10\xbd\xf7\x57\x4c\
-\xd5\x83\xdb\x03\xc6\xdf\x86\x28\x24\x52\x57\xea\x29\xbd\x25\x97\
-\xde\x68\xf0\x82\x9b\x5d\x58\x01\x5d\xb6\xff\xbe\x66\xd7\x60\x4a\
-\xaa\xf4\x92\x43\x15\x90\x30\xf3\x18\xbf\x99\xe7\xf1\x98\xeb\xdb\
-\xd3\x7e\x07\x47\xd3\x76\xb6\xa9\x33\x44\x31\x41\x60\xea\xc7\xa6\
-\xb0\x75\x99\xa1\x87\xfb\x2f\x51\x82\x6e\x6f\xde\x5d\xbf\x8f\x22\
-\xb8\xaf\x6c\x07\x5b\xbb\x33\x30\xe4\x1d\x94\xa6\x36\x6d\xde\x9b\
-\x02\xbe\xff\x82\xe2\x68\xbb\x63\xb9\x07\x86\x13\x88\x22\xe7\xef\
-\xac\x25\x2b\x45\xe0\xe2\xd4\x5d\x86\xaa\xbe\x3f\x5c\xc5\xf1\x30\
-\x0c\x78\xe0\xb8\x69\xcb\x98\x11\x42\x62\xe7\xef\x5d\xae\x4e\x3b\
-\x5b\x3f\xfd\xcd\x91\xa6\x69\x1a\x9f\xbf\x22\x18\x6c\xd1\x57\x19\
-\x52\x1c\x3b\x50\x1d\x7a\x04\x95\xb1\x65\xd5\x4f\x90\x1e\xa1\xa3\
-\x35\xc3\xe7\xe6\x94\x21\xa9\xb0\x20\xa9\x00\xc9\x71\x22\x13\x0e\
-\x7e\x9a\x1f\x35\x72\x09\x97\x60\x8b\x0c\x1d\xf2\xd2\xd0\x8b\xd9\
-\xb7\x79\xdd\x6d\x9b\x76\x9f\xa1\x7d\xde\xb7\xf6\xf4\x91\x38\x67\
-\xc5\x94\x00\x32\xde\x93\x31\x71\x53\xaa\x47\xf2\x4f\xe3\xec\x43\
-\xde\x57\xe0\xe8\xbe\x42\x8a\xb9\xd0\x82\x41\xc4\x38\x26\x94\xde\
-\x05\xc0\xbf\x3c\x47\x36\xcf\x90\x7f\x03\x8b\x39\x12\x53\x29\x29\
-\x05\x9a\x62\x29\x38\x85\x88\x62\x2d\x95\x54\xc0\x19\xa6\x6c\x36\
-\x37\x20\x04\x56\xa9\x4a\x83\x83\x14\x38\x49\x99\x0a\x14\x33\x30\
-\xe7\xfa\x02\x32\x09\x9c\x01\xae\xb0\xd2\x42\x6e\x02\x22\x08\x4e\
-\x94\x4a\x42\x64\xf7\xc2\x94\x14\x53\x6a\xde\xdc\x84\xdc\x27\x87\
-\x59\xdd\x44\x31\x03\x3e\xca\xdd\x7a\xa5\xbf\xa1\x71\xab\xee\x32\
-\xf4\x41\x6f\xc7\x1b\xc5\xae\x2e\x71\xf9\x8a\xa5\x0d\x42\x53\xac\
-\x29\x49\x97\x42\xdd\xbe\x22\x9c\x2d\x84\x6a\xcc\x09\xd5\xb3\xd0\
-\x8b\xb9\x14\xea\x1d\x82\x50\x4f\x11\x84\x4e\x51\x02\x22\xb1\xa4\
-\x89\x0c\x24\x17\x76\x1f\xe3\x3c\x2c\xaa\x7c\x81\x43\xd2\x7e\xf2\
-\x5a\xc5\xbc\x6e\x75\x53\x1b\x04\x5d\xdf\x36\x4f\xc6\xad\x22\x39\
-\x5f\x13\x10\xb9\x2e\x34\x8f\xf9\x21\x43\x6d\xf3\xb3\x2e\xfe\x80\
-\x7f\x34\xb6\x5e\xe3\x7b\xdb\x9b\x76\x67\xdd\xe0\x4e\x03\x82\x09\
-\xd7\x72\xfe\xe6\x5b\x99\xbb\x7c\x38\x65\xaf\x5f\xa7\xf5\x0a\xbe\
-\xe1\x1e\xf4\x0a\xdf\x5c\x09\x5f\x68\x35\xc9\x30\x4b\xf4\xe2\x4c\
-\x51\x0c\x8b\x84\xcf\x67\x8a\x37\x17\xad\x36\x39\x84\x6a\x79\x8a\
-\xf5\x46\xf9\x6f\x96\xf1\xf2\x70\xbf\xc8\x9b\xdf\xf9\x80\xe2\xe1\
-\
-\x00\x00\x03\xe6\
+\x00\x00\x02\xb7\
 \x3c\
 \x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\
 \x30\x22\x20\x65\x6e\x63\x6f\x64\x69\x6e\x67\x3d\x22\x75\x74\x66\
 \x2d\x38\x22\x3f\x3e\x0d\x0a\x3c\x21\x2d\x2d\x20\x47\x65\x6e\x65\
 \x72\x61\x74\x6f\x72\x3a\x20\x41\x64\x6f\x62\x65\x20\x49\x6c\x6c\
-\x75\x73\x74\x72\x61\x74\x6f\x72\x20\x31\x38\x2e\x31\x2e\x31\x2c\
+\x75\x73\x74\x72\x61\x74\x6f\x72\x20\x31\x36\x2e\x32\x2e\x31\x2c\
 \x20\x53\x56\x47\x20\x45\x78\x70\x6f\x72\x74\x20\x50\x6c\x75\x67\
 \x2d\x49\x6e\x20\x2e\x20\x53\x56\x47\x20\x56\x65\x72\x73\x69\x6f\
 \x6e\x3a\x20\x36\x2e\x30\x30\x20\x42\x75\x69\x6c\x64\x20\x30\x29\
@@ -700,60 +268,257 @@
 \x73\x2f\x53\x56\x47\x2f\x31\x2e\x31\x2f\x44\x54\x44\x2f\x73\x76\
 \x67\x31\x31\x2e\x64\x74\x64\x22\x3e\x0d\x0a\x3c\x73\x76\x67\x20\
 \x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\x31\x22\x20\x69\x64\
-\x3d\x22\x43\x68\x65\x76\x72\x6f\x6e\x5f\x63\x69\x72\x63\x6c\x65\
-\x64\x5f\x72\x69\x67\x68\x74\x22\x20\x78\x6d\x6c\x6e\x73\x3d\x22\
+\x3d\x22\x4c\x61\x79\x65\x72\x5f\x31\x22\x20\x78\x6d\x6c\x6e\x73\
+\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\
+\x6f\x72\x67\x2f\x32\x30\x30\x30\x2f\x73\x76\x67\x22\x20\x78\x6d\
+\x6c\x6e\x73\x3a\x78\x6c\x69\x6e\x6b\x3d\x22\x68\x74\x74\x70\x3a\
+\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x31\x39\x39\
+\x39\x2f\x78\x6c\x69\x6e\x6b\x22\x20\x78\x3d\x22\x30\x70\x78\x22\
+\x20\x79\x3d\x22\x30\x70\x78\x22\x0d\x0a\x09\x20\x77\x69\x64\x74\
+\x68\x3d\x22\x35\x31\x32\x70\x78\x22\x20\x68\x65\x69\x67\x68\x74\
+\x3d\x22\x35\x31\x32\x70\x78\x22\x20\x76\x69\x65\x77\x42\x6f\x78\
+\x3d\x22\x30\x20\x30\x20\x35\x31\x32\x20\x35\x31\x32\x22\x20\x65\
+\x6e\x61\x62\x6c\x65\x2d\x62\x61\x63\x6b\x67\x72\x6f\x75\x6e\x64\
+\x3d\x22\x6e\x65\x77\x20\x30\x20\x30\x20\x35\x31\x32\x20\x35\x31\
+\x32\x22\x20\x78\x6d\x6c\x3a\x73\x70\x61\x63\x65\x3d\x22\x70\x72\
+\x65\x73\x65\x72\x76\x65\x22\x3e\x0d\x0a\x3c\x67\x20\x69\x64\x3d\
+\x22\x49\x63\x6f\x6e\x5f\x35\x5f\x22\x3e\x0d\x0a\x09\x3c\x67\x3e\
+\x0d\x0a\x09\x09\x3c\x70\x6f\x6c\x79\x67\x6f\x6e\x20\x70\x6f\x69\
+\x6e\x74\x73\x3d\x22\x34\x30\x35\x2c\x31\x33\x36\x2e\x37\x39\x38\
+\x20\x33\x37\x35\x2e\x32\x30\x32\x2c\x31\x30\x37\x20\x32\x35\x36\
+\x2c\x32\x32\x36\x2e\x32\x30\x32\x20\x31\x33\x36\x2e\x37\x39\x38\
+\x2c\x31\x30\x37\x20\x31\x30\x37\x2c\x31\x33\x36\x2e\x37\x39\x38\
+\x20\x32\x32\x36\x2e\x32\x30\x32\x2c\x32\x35\x36\x20\x31\x30\x37\
+\x2c\x33\x37\x35\x2e\x32\x30\x32\x20\x31\x33\x36\x2e\x37\x39\x38\
+\x2c\x34\x30\x35\x20\x32\x35\x36\x2c\x32\x38\x35\x2e\x37\x39\x38\
+\x20\x0d\x0a\x09\x09\x09\x33\x37\x35\x2e\x32\x30\x32\x2c\x34\x30\
+\x35\x20\x34\x30\x35\x2c\x33\x37\x35\x2e\x32\x30\x32\x20\x32\x38\
+\x35\x2e\x37\x39\x38\x2c\x32\x35\x36\x20\x09\x09\x22\x2f\x3e\x0d\
+\x0a\x09\x3c\x2f\x67\x3e\x0d\x0a\x3c\x2f\x67\x3e\x0d\x0a\x3c\x2f\
+\x73\x76\x67\x3e\x0d\x0a\
+\x00\x00\x04\xa2\
+\x3c\
+\x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x27\x31\x2e\
+\x30\x27\x20\x65\x6e\x63\x6f\x64\x69\x6e\x67\x3d\x27\x55\x54\x46\
+\x2d\x38\x27\x3f\x3e\x0a\x3c\x21\x2d\x2d\x20\x54\x68\x69\x73\x20\
+\x66\x69\x6c\x65\x20\x77\x61\x73\x20\x67\x65\x6e\x65\x72\x61\x74\
+\x65\x64\x20\x62\x79\x20\x64\x76\x69\x73\x76\x67\x6d\x20\x32\x2e\
+\x38\x20\x2d\x2d\x3e\x0a\x3c\x73\x76\x67\x20\x76\x65\x72\x73\x69\
+\x6f\x6e\x3d\x27\x31\x2e\x31\x27\x20\x78\x6d\x6c\x6e\x73\x3d\x27\
 \x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\
-\x67\x2f\x32\x30\x30\x30\x2f\x73\x76\x67\x22\x20\x78\x6d\x6c\x6e\
-\x73\x3a\x78\x6c\x69\x6e\x6b\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\
+\x67\x2f\x32\x30\x30\x30\x2f\x73\x76\x67\x27\x20\x78\x6d\x6c\x6e\
+\x73\x3a\x78\x6c\x69\x6e\x6b\x3d\x27\x68\x74\x74\x70\x3a\x2f\x2f\
 \x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x31\x39\x39\x39\x2f\
-\x78\x6c\x69\x6e\x6b\x22\x0d\x0a\x09\x20\x78\x3d\x22\x30\x70\x78\
-\x22\x20\x79\x3d\x22\x30\x70\x78\x22\x20\x76\x69\x65\x77\x42\x6f\
-\x78\x3d\x22\x30\x20\x30\x20\x35\x31\x32\x20\x35\x31\x32\x22\x20\
-\x65\x6e\x61\x62\x6c\x65\x2d\x62\x61\x63\x6b\x67\x72\x6f\x75\x6e\
-\x64\x3d\x22\x6e\x65\x77\x20\x30\x20\x30\x20\x35\x31\x32\x20\x35\
-\x31\x32\x22\x20\x78\x6d\x6c\x3a\x73\x70\x61\x63\x65\x3d\x22\x70\
-\x72\x65\x73\x65\x72\x76\x65\x22\x3e\x0d\x0a\x3c\x67\x20\x74\x72\
-\x61\x6e\x73\x66\x6f\x72\x6d\x3d\x27\x6d\x61\x74\x72\x69\x78\x28\
-\x32\x34\x20\x30\x20\x30\x20\x32\x34\x20\x30\x20\x30\x29\x27\x3e\
-\x0d\x0a\x3c\x70\x61\x74\x68\x20\x64\x3d\x22\x4d\x31\x31\x2c\x31\
-\x30\x4c\x38\x2e\x36\x39\x38\x2c\x37\x2e\x34\x39\x34\x63\x2d\x30\
-\x2e\x31\x39\x36\x2d\x30\x2e\x31\x39\x38\x2d\x30\x2e\x31\x39\x36\
-\x2d\x30\x2e\x35\x31\x39\x2c\x30\x2d\x30\x2e\x37\x31\x38\x63\x30\
-\x2e\x31\x39\x36\x2d\x30\x2e\x31\x39\x37\x2c\x30\x2e\x35\x31\x35\
-\x2d\x30\x2e\x31\x39\x37\x2c\x30\x2e\x37\x31\x2c\x30\x6c\x32\x2e\
-\x38\x30\x37\x2c\x32\x2e\x38\x36\x34\x0d\x0a\x09\x63\x30\x2e\x31\
-\x39\x36\x2c\x30\x2e\x31\x39\x39\x2c\x30\x2e\x31\x39\x36\x2c\x30\
-\x2e\x35\x32\x2c\x30\x2c\x30\x2e\x37\x31\x37\x6c\x2d\x32\x2e\x38\
-\x30\x37\x2c\x32\x2e\x38\x36\x34\x63\x2d\x30\x2e\x31\x39\x35\x2c\
-\x30\x2e\x31\x39\x39\x2d\x30\x2e\x35\x31\x34\x2c\x30\x2e\x31\x39\
-\x38\x2d\x30\x2e\x37\x31\x2c\x30\x63\x2d\x30\x2e\x31\x39\x36\x2d\
-\x30\x2e\x31\x39\x37\x2d\x30\x2e\x31\x39\x36\x2d\x30\x2e\x35\x31\
-\x38\x2c\x30\x2d\x30\x2e\x37\x31\x37\x4c\x31\x31\x2c\x31\x30\x7a\
-\x20\x4d\x31\x30\x2c\x30\x2e\x34\x0d\x0a\x09\x63\x35\x2e\x33\x30\
-\x32\x2c\x30\x2c\x39\x2e\x36\x2c\x34\x2e\x32\x39\x38\x2c\x39\x2e\
-\x36\x2c\x39\x2e\x36\x63\x30\x2c\x35\x2e\x33\x30\x33\x2d\x34\x2e\
-\x32\x39\x38\x2c\x39\x2e\x36\x2d\x39\x2e\x36\x2c\x39\x2e\x36\x53\
-\x30\x2e\x34\x2c\x31\x35\x2e\x33\x30\x33\x2c\x30\x2e\x34\x2c\x31\
-\x30\x43\x30\x2e\x34\x2c\x34\x2e\x36\x39\x38\x2c\x34\x2e\x36\x39\
-\x38\x2c\x30\x2e\x34\x2c\x31\x30\x2c\x30\x2e\x34\x7a\x20\x4d\x31\
-\x30\x2c\x31\x38\x2e\x33\x35\x34\x0d\x0a\x09\x63\x34\x2e\x36\x31\
-\x33\x2c\x30\x2c\x38\x2e\x33\x35\x34\x2d\x33\x2e\x37\x34\x2c\x38\
-\x2e\x33\x35\x34\x2d\x38\x2e\x33\x35\x34\x63\x30\x2d\x34\x2e\x36\
-\x31\x34\x2d\x33\x2e\x37\x34\x31\x2d\x38\x2e\x33\x35\x34\x2d\x38\
-\x2e\x33\x35\x34\x2d\x38\x2e\x33\x35\x34\x63\x2d\x34\x2e\x36\x31\
-\x35\x2c\x30\x2d\x38\x2e\x33\x35\x34\x2c\x33\x2e\x37\x34\x2d\x38\
-\x2e\x33\x35\x34\x2c\x38\x2e\x33\x35\x34\x0d\x0a\x09\x43\x31\x2e\
-\x36\x34\x35\x2c\x31\x34\x2e\x36\x31\x34\x2c\x35\x2e\x33\x38\x35\
-\x2c\x31\x38\x2e\x33\x35\x34\x2c\x31\x30\x2c\x31\x38\x2e\x33\x35\
-\x34\x7a\x22\x2f\x3e\x0d\x0a\x3c\x2f\x67\x3e\x0d\x0a\x3c\x2f\x73\
-\x76\x67\x3e\x0d\x0a\
-\x00\x00\x03\xf5\
+\x78\x6c\x69\x6e\x6b\x27\x20\x77\x69\x64\x74\x68\x3d\x27\x36\x33\
+\x2e\x39\x39\x39\x36\x70\x74\x27\x20\x68\x65\x69\x67\x68\x74\x3d\
+\x27\x36\x33\x2e\x39\x39\x39\x37\x70\x74\x27\x20\x76\x69\x65\x77\
+\x42\x6f\x78\x3d\x27\x35\x36\x2e\x34\x30\x39\x34\x20\x35\x33\x2e\
+\x38\x35\x38\x33\x20\x36\x33\x2e\x39\x39\x39\x36\x20\x36\x33\x2e\
+\x39\x39\x39\x37\x27\x3e\x0a\x3c\x67\x20\x69\x64\x3d\x27\x70\x61\
+\x67\x65\x31\x27\x3e\x0a\x3c\x67\x20\x74\x72\x61\x6e\x73\x66\x6f\
+\x72\x6d\x3d\x27\x6d\x61\x74\x72\x69\x78\x28\x30\x2e\x39\x39\x36\
+\x32\x36\x34\x20\x30\x20\x30\x20\x30\x2e\x39\x39\x36\x32\x36\x34\
+\x20\x35\x38\x2e\x34\x36\x36\x39\x20\x31\x31\x37\x2e\x38\x35\x38\
+\x29\x27\x3e\x0a\x3c\x70\x61\x74\x68\x20\x64\x3d\x27\x4d\x20\x33\
+\x2e\x39\x35\x37\x33\x35\x20\x2d\x33\x32\x2e\x31\x32\x43\x20\x34\
+\x2e\x31\x35\x35\x35\x36\x20\x2d\x33\x39\x2e\x32\x37\x34\x35\x20\
+\x36\x2e\x39\x38\x34\x37\x33\x20\x2d\x34\x36\x2e\x31\x30\x34\x37\
+\x20\x31\x31\x2e\x39\x30\x33\x36\x20\x2d\x35\x31\x2e\x33\x30\x33\
+\x39\x43\x20\x32\x37\x2e\x34\x34\x31\x31\x20\x2d\x36\x37\x2e\x37\
+\x32\x36\x39\x20\x35\x33\x2e\x33\x30\x32\x31\x20\x2d\x36\x31\x2e\
+\x35\x34\x30\x35\x20\x35\x36\x2e\x31\x35\x32\x33\x20\x2d\x34\x32\
+\x2e\x35\x30\x32\x32\x43\x20\x35\x37\x2e\x36\x32\x37\x20\x2d\x33\
+\x32\x2e\x36\x35\x31\x39\x20\x35\x30\x2e\x35\x38\x35\x36\x20\x2d\
+\x32\x33\x2e\x35\x36\x32\x31\x20\x34\x30\x2e\x36\x37\x39\x34\x20\
+\x2d\x32\x32\x2e\x35\x32\x38\x31\x27\x20\x66\x69\x6c\x6c\x3d\x27\
+\x6e\x6f\x6e\x65\x27\x20\x73\x74\x72\x6f\x6b\x65\x3d\x27\x23\x30\
+\x30\x30\x30\x30\x30\x27\x20\x73\x74\x72\x6f\x6b\x65\x2d\x6c\x69\
+\x6e\x65\x63\x61\x70\x3d\x27\x72\x6f\x75\x6e\x64\x27\x20\x73\x74\
+\x72\x6f\x6b\x65\x2d\x6c\x69\x6e\x65\x6a\x6f\x69\x6e\x3d\x27\x72\
+\x6f\x75\x6e\x64\x27\x20\x73\x74\x72\x6f\x6b\x65\x2d\x6d\x69\x74\
+\x65\x72\x6c\x69\x6d\x69\x74\x3d\x27\x31\x30\x2e\x30\x33\x37\x35\
+\x27\x20\x73\x74\x72\x6f\x6b\x65\x2d\x77\x69\x64\x74\x68\x3d\x27\
+\x32\x2e\x35\x30\x39\x33\x37\x27\x2f\x3e\x0a\x3c\x2f\x67\x3e\x0a\
+\x3c\x67\x20\x74\x72\x61\x6e\x73\x66\x6f\x72\x6d\x3d\x27\x6d\x61\
+\x74\x72\x69\x78\x28\x30\x2e\x39\x39\x36\x32\x36\x34\x20\x30\x20\
+\x30\x20\x30\x2e\x39\x39\x36\x32\x36\x34\x20\x35\x38\x2e\x34\x36\
+\x36\x39\x20\x31\x31\x37\x2e\x38\x35\x38\x29\x27\x3e\x0a\x3c\x63\
+\x69\x72\x63\x6c\x65\x20\x63\x78\x3d\x27\x33\x2e\x39\x35\x37\x33\
+\x35\x27\x20\x63\x79\x3d\x27\x2d\x33\x32\x2e\x31\x32\x27\x20\x66\
+\x69\x6c\x6c\x3d\x27\x23\x30\x30\x30\x30\x30\x30\x27\x20\x72\x3d\
+\x27\x36\x2e\x30\x32\x32\x35\x27\x2f\x3e\x0a\x3c\x2f\x67\x3e\x0a\
+\x3c\x67\x20\x74\x72\x61\x6e\x73\x66\x6f\x72\x6d\x3d\x27\x6d\x61\
+\x74\x72\x69\x78\x28\x30\x2e\x39\x39\x36\x32\x36\x34\x20\x30\x20\
+\x30\x20\x30\x2e\x39\x39\x36\x32\x36\x34\x20\x35\x38\x2e\x34\x36\
+\x36\x39\x20\x31\x31\x37\x2e\x38\x35\x38\x29\x27\x3e\x0a\x3c\x63\
+\x69\x72\x63\x6c\x65\x20\x63\x78\x3d\x27\x31\x31\x2e\x39\x30\x33\
+\x36\x27\x20\x63\x79\x3d\x27\x2d\x35\x31\x2e\x33\x30\x33\x39\x27\
+\x20\x66\x69\x6c\x6c\x3d\x27\x23\x30\x30\x30\x30\x30\x30\x27\x20\
+\x72\x3d\x27\x36\x2e\x30\x32\x32\x35\x27\x2f\x3e\x0a\x3c\x2f\x67\
+\x3e\x0a\x3c\x67\x20\x74\x72\x61\x6e\x73\x66\x6f\x72\x6d\x3d\x27\
+\x6d\x61\x74\x72\x69\x78\x28\x30\x2e\x39\x39\x36\x32\x36\x34\x20\
+\x30\x20\x30\x20\x30\x2e\x39\x39\x36\x32\x36\x34\x20\x35\x38\x2e\
+\x34\x36\x36\x39\x20\x31\x31\x37\x2e\x38\x35\x38\x29\x27\x3e\x0a\
+\x3c\x63\x69\x72\x63\x6c\x65\x20\x63\x78\x3d\x27\x35\x36\x2e\x31\
+\x35\x32\x33\x27\x20\x63\x79\x3d\x27\x2d\x34\x32\x2e\x35\x30\x32\
+\x32\x27\x20\x66\x69\x6c\x6c\x3d\x27\x23\x30\x30\x30\x30\x30\x30\
+\x27\x20\x72\x3d\x27\x36\x2e\x30\x32\x32\x35\x27\x2f\x3e\x0a\x3c\
+\x2f\x67\x3e\x0a\x3c\x67\x20\x74\x72\x61\x6e\x73\x66\x6f\x72\x6d\
+\x3d\x27\x6d\x61\x74\x72\x69\x78\x28\x30\x2e\x39\x39\x36\x32\x36\
+\x34\x20\x30\x20\x30\x20\x30\x2e\x39\x39\x36\x32\x36\x34\x20\x35\
+\x38\x2e\x34\x36\x36\x39\x20\x31\x31\x37\x2e\x38\x35\x38\x29\x27\
+\x3e\x0a\x3c\x63\x69\x72\x63\x6c\x65\x20\x63\x78\x3d\x27\x34\x30\
+\x2e\x36\x37\x39\x34\x27\x20\x63\x79\x3d\x27\x2d\x32\x32\x2e\x35\
+\x32\x38\x31\x27\x20\x66\x69\x6c\x6c\x3d\x27\x23\x30\x30\x30\x30\
+\x30\x30\x27\x20\x72\x3d\x27\x36\x2e\x30\x32\x32\x35\x27\x2f\x3e\
+\x0a\x3c\x2f\x67\x3e\x0a\x3c\x2f\x67\x3e\x0a\x3c\x2f\x73\x76\x67\
+\x3e\
+\x00\x00\x04\x1c\
 \x3c\
+\x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x27\x31\x2e\
+\x30\x27\x20\x65\x6e\x63\x6f\x64\x69\x6e\x67\x3d\x27\x55\x54\x46\
+\x2d\x38\x27\x3f\x3e\x0a\x3c\x21\x2d\x2d\x20\x54\x68\x69\x73\x20\
+\x66\x69\x6c\x65\x20\x77\x61\x73\x20\x67\x65\x6e\x65\x72\x61\x74\
+\x65\x64\x20\x62\x79\x20\x64\x76\x69\x73\x76\x67\x6d\x20\x32\x2e\
+\x38\x20\x2d\x2d\x3e\x0a\x3c\x73\x76\x67\x20\x76\x65\x72\x73\x69\
+\x6f\x6e\x3d\x27\x31\x2e\x31\x27\x20\x78\x6d\x6c\x6e\x73\x3d\x27\
+\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\
+\x67\x2f\x32\x30\x30\x30\x2f\x73\x76\x67\x27\x20\x78\x6d\x6c\x6e\
+\x73\x3a\x78\x6c\x69\x6e\x6b\x3d\x27\x68\x74\x74\x70\x3a\x2f\x2f\
+\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x31\x39\x39\x39\x2f\
+\x78\x6c\x69\x6e\x6b\x27\x20\x77\x69\x64\x74\x68\x3d\x27\x36\x33\
+\x2e\x39\x39\x39\x36\x70\x74\x27\x20\x68\x65\x69\x67\x68\x74\x3d\
+\x27\x36\x33\x2e\x39\x39\x39\x37\x70\x74\x27\x20\x76\x69\x65\x77\
+\x42\x6f\x78\x3d\x27\x35\x36\x2e\x34\x30\x39\x34\x20\x35\x33\x2e\
+\x38\x35\x38\x33\x20\x36\x33\x2e\x39\x39\x39\x36\x20\x36\x33\x2e\
+\x39\x39\x39\x37\x27\x3e\x0a\x3c\x67\x20\x69\x64\x3d\x27\x70\x61\
+\x67\x65\x31\x27\x3e\x0a\x3c\x67\x20\x74\x72\x61\x6e\x73\x66\x6f\
+\x72\x6d\x3d\x27\x6d\x61\x74\x72\x69\x78\x28\x30\x2e\x39\x39\x36\
+\x32\x36\x34\x20\x30\x20\x30\x20\x30\x2e\x39\x39\x36\x32\x36\x34\
+\x20\x35\x36\x2e\x34\x30\x39\x34\x20\x31\x31\x37\x2e\x38\x35\x38\
+\x29\x27\x3e\x0a\x3c\x70\x61\x74\x68\x20\x64\x3d\x27\x4d\x20\x32\
+\x2e\x30\x30\x37\x35\x20\x2d\x32\x2e\x30\x30\x37\x35\x4c\x20\x36\
+\x32\x2e\x32\x33\x32\x35\x20\x2d\x32\x2e\x30\x30\x37\x35\x4c\x20\
+\x36\x32\x2e\x32\x33\x32\x35\x20\x2d\x36\x32\x2e\x32\x33\x32\x35\
+\x4c\x20\x32\x2e\x30\x30\x37\x35\x20\x2d\x36\x32\x2e\x32\x33\x32\
+\x35\x4c\x20\x32\x2e\x30\x30\x37\x35\x20\x2d\x32\x2e\x30\x30\x37\
+\x35\x5a\x27\x20\x66\x69\x6c\x6c\x3d\x27\x6e\x6f\x6e\x65\x27\x20\
+\x73\x74\x72\x6f\x6b\x65\x3d\x27\x23\x30\x30\x30\x30\x30\x30\x27\
+\x20\x73\x74\x72\x6f\x6b\x65\x2d\x6c\x69\x6e\x65\x63\x61\x70\x3d\
+\x27\x72\x6f\x75\x6e\x64\x27\x20\x73\x74\x72\x6f\x6b\x65\x2d\x6c\
+\x69\x6e\x65\x6a\x6f\x69\x6e\x3d\x27\x72\x6f\x75\x6e\x64\x27\x20\
+\x73\x74\x72\x6f\x6b\x65\x2d\x6d\x69\x74\x65\x72\x6c\x69\x6d\x69\
+\x74\x3d\x27\x31\x30\x2e\x30\x33\x37\x35\x27\x20\x73\x74\x72\x6f\
+\x6b\x65\x2d\x77\x69\x64\x74\x68\x3d\x27\x34\x2e\x30\x31\x35\x27\
+\x2f\x3e\x0a\x3c\x2f\x67\x3e\x0a\x3c\x67\x20\x74\x72\x61\x6e\x73\
+\x66\x6f\x72\x6d\x3d\x27\x6d\x61\x74\x72\x69\x78\x28\x30\x2e\x39\
+\x39\x36\x32\x36\x34\x20\x30\x20\x30\x20\x30\x2e\x39\x39\x36\x32\
+\x36\x34\x20\x35\x36\x2e\x34\x30\x39\x34\x20\x31\x31\x37\x2e\x38\
+\x35\x38\x29\x27\x3e\x0a\x3c\x70\x61\x74\x68\x20\x64\x3d\x27\x4d\
+\x20\x32\x2e\x30\x30\x37\x35\x20\x2d\x33\x32\x2e\x31\x32\x4c\x20\
+\x36\x32\x2e\x32\x33\x32\x35\x20\x2d\x33\x32\x2e\x31\x32\x27\x20\
+\x66\x69\x6c\x6c\x3d\x27\x6e\x6f\x6e\x65\x27\x20\x73\x74\x72\x6f\
+\x6b\x65\x3d\x27\x23\x30\x30\x30\x30\x30\x30\x27\x20\x73\x74\x72\
+\x6f\x6b\x65\x2d\x6c\x69\x6e\x65\x63\x61\x70\x3d\x27\x72\x6f\x75\
+\x6e\x64\x27\x20\x73\x74\x72\x6f\x6b\x65\x2d\x6c\x69\x6e\x65\x6a\
+\x6f\x69\x6e\x3d\x27\x72\x6f\x75\x6e\x64\x27\x20\x73\x74\x72\x6f\
+\x6b\x65\x2d\x6d\x69\x74\x65\x72\x6c\x69\x6d\x69\x74\x3d\x27\x31\
+\x30\x2e\x30\x33\x37\x35\x27\x20\x73\x74\x72\x6f\x6b\x65\x2d\x77\
+\x69\x64\x74\x68\x3d\x27\x34\x2e\x30\x31\x35\x27\x2f\x3e\x0a\x3c\
+\x2f\x67\x3e\x0a\x3c\x67\x20\x74\x72\x61\x6e\x73\x66\x6f\x72\x6d\
+\x3d\x27\x6d\x61\x74\x72\x69\x78\x28\x30\x2e\x39\x39\x36\x32\x36\
+\x34\x20\x30\x20\x30\x20\x30\x2e\x39\x39\x36\x32\x36\x34\x20\x35\
+\x36\x2e\x34\x30\x39\x34\x20\x31\x31\x37\x2e\x38\x35\x38\x29\x27\
+\x3e\x0a\x3c\x70\x61\x74\x68\x20\x64\x3d\x27\x4d\x20\x33\x32\x2e\
+\x31\x32\x20\x2d\x32\x2e\x30\x30\x37\x35\x4c\x20\x33\x32\x2e\x31\
+\x32\x20\x2d\x36\x32\x2e\x32\x33\x32\x35\x27\x20\x66\x69\x6c\x6c\
+\x3d\x27\x6e\x6f\x6e\x65\x27\x20\x73\x74\x72\x6f\x6b\x65\x3d\x27\
+\x23\x30\x30\x30\x30\x30\x30\x27\x20\x73\x74\x72\x6f\x6b\x65\x2d\
+\x6c\x69\x6e\x65\x63\x61\x70\x3d\x27\x72\x6f\x75\x6e\x64\x27\x20\
+\x73\x74\x72\x6f\x6b\x65\x2d\x6c\x69\x6e\x65\x6a\x6f\x69\x6e\x3d\
+\x27\x72\x6f\x75\x6e\x64\x27\x20\x73\x74\x72\x6f\x6b\x65\x2d\x6d\
+\x69\x74\x65\x72\x6c\x69\x6d\x69\x74\x3d\x27\x31\x30\x2e\x30\x33\
+\x37\x35\x27\x20\x73\x74\x72\x6f\x6b\x65\x2d\x77\x69\x64\x74\x68\
+\x3d\x27\x34\x2e\x30\x31\x35\x27\x2f\x3e\x0a\x3c\x2f\x67\x3e\x0a\
+\x3c\x2f\x67\x3e\x0a\x3c\x2f\x73\x76\x67\x3e\
+\x00\x00\x04\x4e\
+\x3c\
+\x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x27\x31\x2e\
+\x30\x27\x20\x65\x6e\x63\x6f\x64\x69\x6e\x67\x3d\x27\x55\x54\x46\
+\x2d\x38\x27\x3f\x3e\x0a\x3c\x21\x2d\x2d\x20\x54\x68\x69\x73\x20\
+\x66\x69\x6c\x65\x20\x77\x61\x73\x20\x67\x65\x6e\x65\x72\x61\x74\
+\x65\x64\x20\x62\x79\x20\x64\x76\x69\x73\x76\x67\x6d\x20\x32\x2e\
+\x38\x20\x2d\x2d\x3e\x0a\x3c\x73\x76\x67\x20\x76\x65\x72\x73\x69\
+\x6f\x6e\x3d\x27\x31\x2e\x31\x27\x20\x78\x6d\x6c\x6e\x73\x3d\x27\
+\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\
+\x67\x2f\x32\x30\x30\x30\x2f\x73\x76\x67\x27\x20\x78\x6d\x6c\x6e\
+\x73\x3a\x78\x6c\x69\x6e\x6b\x3d\x27\x68\x74\x74\x70\x3a\x2f\x2f\
+\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x31\x39\x39\x39\x2f\
+\x78\x6c\x69\x6e\x6b\x27\x20\x77\x69\x64\x74\x68\x3d\x27\x36\x33\
+\x2e\x39\x39\x39\x36\x70\x74\x27\x20\x68\x65\x69\x67\x68\x74\x3d\
+\x27\x36\x33\x2e\x39\x39\x39\x37\x70\x74\x27\x20\x76\x69\x65\x77\
+\x42\x6f\x78\x3d\x27\x35\x36\x2e\x34\x30\x39\x34\x20\x35\x33\x2e\
+\x38\x35\x38\x33\x20\x36\x33\x2e\x39\x39\x39\x36\x20\x36\x33\x2e\
+\x39\x39\x39\x37\x27\x3e\x0a\x3c\x67\x20\x69\x64\x3d\x27\x70\x61\
+\x67\x65\x31\x27\x3e\x0a\x3c\x67\x20\x74\x72\x61\x6e\x73\x66\x6f\
+\x72\x6d\x3d\x27\x6d\x61\x74\x72\x69\x78\x28\x30\x2e\x39\x39\x36\
+\x32\x36\x34\x20\x30\x20\x30\x20\x30\x2e\x39\x39\x36\x32\x36\x34\
+\x20\x35\x38\x2e\x34\x36\x36\x39\x20\x31\x31\x37\x2e\x38\x35\x38\
+\x29\x27\x3e\x0a\x3c\x70\x61\x74\x68\x20\x64\x3d\x27\x4d\x20\x33\
+\x2e\x39\x35\x37\x33\x35\x20\x2d\x33\x32\x2e\x31\x32\x4c\x20\x31\
+\x31\x2e\x39\x30\x33\x36\x20\x2d\x35\x31\x2e\x33\x30\x33\x39\x4c\
+\x20\x35\x36\x2e\x31\x35\x32\x33\x20\x2d\x34\x32\x2e\x35\x30\x32\
+\x32\x4c\x20\x34\x30\x2e\x36\x37\x39\x34\x20\x2d\x32\x32\x2e\x35\
+\x32\x38\x31\x4c\x20\x33\x2e\x39\x35\x37\x33\x35\x20\x2d\x33\x32\
+\x2e\x31\x32\x5a\x27\x20\x66\x69\x6c\x6c\x3d\x27\x6e\x6f\x6e\x65\
+\x27\x20\x73\x74\x72\x6f\x6b\x65\x3d\x27\x23\x30\x30\x30\x30\x30\
+\x30\x27\x20\x73\x74\x72\x6f\x6b\x65\x2d\x6c\x69\x6e\x65\x63\x61\
+\x70\x3d\x27\x72\x6f\x75\x6e\x64\x27\x20\x73\x74\x72\x6f\x6b\x65\
+\x2d\x6c\x69\x6e\x65\x6a\x6f\x69\x6e\x3d\x27\x72\x6f\x75\x6e\x64\
+\x27\x20\x73\x74\x72\x6f\x6b\x65\x2d\x6d\x69\x74\x65\x72\x6c\x69\
+\x6d\x69\x74\x3d\x27\x31\x30\x2e\x30\x33\x37\x35\x27\x20\x73\x74\
+\x72\x6f\x6b\x65\x2d\x77\x69\x64\x74\x68\x3d\x27\x32\x2e\x35\x30\
+\x39\x33\x37\x27\x2f\x3e\x0a\x3c\x2f\x67\x3e\x0a\x3c\x67\x20\x74\
+\x72\x61\x6e\x73\x66\x6f\x72\x6d\x3d\x27\x6d\x61\x74\x72\x69\x78\
+\x28\x30\x2e\x39\x39\x36\x32\x36\x34\x20\x30\x20\x30\x20\x30\x2e\
+\x39\x39\x36\x32\x36\x34\x20\x35\x38\x2e\x34\x36\x36\x39\x20\x31\
+\x31\x37\x2e\x38\x35\x38\x29\x27\x3e\x0a\x3c\x63\x69\x72\x63\x6c\
+\x65\x20\x63\x78\x3d\x27\x33\x2e\x39\x35\x37\x33\x35\x27\x20\x63\
+\x79\x3d\x27\x2d\x33\x32\x2e\x31\x32\x27\x20\x66\x69\x6c\x6c\x3d\
+\x27\x23\x30\x30\x30\x30\x30\x30\x27\x20\x72\x3d\x27\x36\x2e\x30\
+\x32\x32\x35\x27\x2f\x3e\x0a\x3c\x2f\x67\x3e\x0a\x3c\x67\x20\x74\
+\x72\x61\x6e\x73\x66\x6f\x72\x6d\x3d\x27\x6d\x61\x74\x72\x69\x78\
+\x28\x30\x2e\x39\x39\x36\x32\x36\x34\x20\x30\x20\x30\x20\x30\x2e\
+\x39\x39\x36\x32\x36\x34\x20\x35\x38\x2e\x34\x36\x36\x39\x20\x31\
+\x31\x37\x2e\x38\x35\x38\x29\x27\x3e\x0a\x3c\x63\x69\x72\x63\x6c\
+\x65\x20\x63\x78\x3d\x27\x31\x31\x2e\x39\x30\x33\x36\x27\x20\x63\
+\x79\x3d\x27\x2d\x35\x31\x2e\x33\x30\x33\x39\x27\x20\x66\x69\x6c\
+\x6c\x3d\x27\x23\x30\x30\x30\x30\x30\x30\x27\x20\x72\x3d\x27\x36\
+\x2e\x30\x32\x32\x35\x27\x2f\x3e\x0a\x3c\x2f\x67\x3e\x0a\x3c\x67\
+\x20\x74\x72\x61\x6e\x73\x66\x6f\x72\x6d\x3d\x27\x6d\x61\x74\x72\
+\x69\x78\x28\x30\x2e\x39\x39\x36\x32\x36\x34\x20\x30\x20\x30\x20\
+\x30\x2e\x39\x39\x36\x32\x36\x34\x20\x35\x38\x2e\x34\x36\x36\x39\
+\x20\x31\x31\x37\x2e\x38\x35\x38\x29\x27\x3e\x0a\x3c\x63\x69\x72\
+\x63\x6c\x65\x20\x63\x78\x3d\x27\x35\x36\x2e\x31\x35\x32\x33\x27\
+\x20\x63\x79\x3d\x27\x2d\x34\x32\x2e\x35\x30\x32\x32\x27\x20\x66\
+\x69\x6c\x6c\x3d\x27\x23\x30\x30\x30\x30\x30\x30\x27\x20\x72\x3d\
+\x27\x36\x2e\x30\x32\x32\x35\x27\x2f\x3e\x0a\x3c\x2f\x67\x3e\x0a\
+\x3c\x67\x20\x74\x72\x61\x6e\x73\x66\x6f\x72\x6d\x3d\x27\x6d\x61\
+\x74\x72\x69\x78\x28\x30\x2e\x39\x39\x36\x32\x36\x34\x20\x30\x20\
+\x30\x20\x30\x2e\x39\x39\x36\x32\x36\x34\x20\x35\x38\x2e\x34\x36\
+\x36\x39\x20\x31\x31\x37\x2e\x38\x35\x38\x29\x27\x3e\x0a\x3c\x63\
+\x69\x72\x63\x6c\x65\x20\x63\x78\x3d\x27\x34\x30\x2e\x36\x37\x39\
+\x34\x27\x20\x63\x79\x3d\x27\x2d\x32\x32\x2e\x35\x32\x38\x31\x27\
+\x20\x66\x69\x6c\x6c\x3d\x27\x23\x30\x30\x30\x30\x30\x30\x27\x20\
+\x72\x3d\x27\x36\x2e\x30\x32\x32\x35\x27\x2f\x3e\x0a\x3c\x2f\x67\
+\x3e\x0a\x3c\x2f\x67\x3e\x0a\x3c\x2f\x73\x76\x67\x3e\
+\x00\x00\x02\x7f\
+\x3c\
 \x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\
 \x30\x22\x20\x65\x6e\x63\x6f\x64\x69\x6e\x67\x3d\x22\x75\x74\x66\
 \x2d\x38\x22\x3f\x3e\x0d\x0a\x3c\x21\x2d\x2d\x20\x47\x65\x6e\x65\
 \x72\x61\x74\x6f\x72\x3a\x20\x41\x64\x6f\x62\x65\x20\x49\x6c\x6c\
-\x75\x73\x74\x72\x61\x74\x6f\x72\x20\x31\x38\x2e\x31\x2e\x31\x2c\
+\x75\x73\x74\x72\x61\x74\x6f\x72\x20\x31\x36\x2e\x32\x2e\x31\x2c\
 \x20\x53\x56\x47\x20\x45\x78\x70\x6f\x72\x74\x20\x50\x6c\x75\x67\
 \x2d\x49\x6e\x20\x2e\x20\x53\x56\x47\x20\x56\x65\x72\x73\x69\x6f\
 \x6e\x3a\x20\x36\x2e\x30\x30\x20\x42\x75\x69\x6c\x64\x20\x30\x29\
@@ -765,55 +530,104 @@
 \x73\x2f\x53\x56\x47\x2f\x31\x2e\x31\x2f\x44\x54\x44\x2f\x73\x76\
 \x67\x31\x31\x2e\x64\x74\x64\x22\x3e\x0d\x0a\x3c\x73\x76\x67\x20\
 \x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\x31\x22\x20\x69\x64\
-\x3d\x22\x43\x68\x65\x76\x72\x6f\x6e\x5f\x63\x69\x72\x63\x6c\x65\
-\x64\x5f\x6c\x65\x66\x74\x22\x20\x78\x6d\x6c\x6e\x73\x3d\x22\x68\
-\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\x67\
-\x2f\x32\x30\x30\x30\x2f\x73\x76\x67\x22\x20\x78\x6d\x6c\x6e\x73\
-\x3a\x78\x6c\x69\x6e\x6b\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\
-\x77\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x31\x39\x39\x39\x2f\x78\
-\x6c\x69\x6e\x6b\x22\x0d\x0a\x09\x20\x78\x3d\x22\x30\x70\x78\x22\
-\x20\x79\x3d\x22\x30\x70\x78\x22\x20\x76\x69\x65\x77\x42\x6f\x78\
+\x3d\x22\x4c\x61\x79\x65\x72\x5f\x31\x22\x20\x78\x6d\x6c\x6e\x73\
+\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\
+\x6f\x72\x67\x2f\x32\x30\x30\x30\x2f\x73\x76\x67\x22\x20\x78\x6d\
+\x6c\x6e\x73\x3a\x78\x6c\x69\x6e\x6b\x3d\x22\x68\x74\x74\x70\x3a\
+\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x31\x39\x39\
+\x39\x2f\x78\x6c\x69\x6e\x6b\x22\x20\x78\x3d\x22\x30\x70\x78\x22\
+\x20\x79\x3d\x22\x30\x70\x78\x22\x0d\x0a\x09\x20\x77\x69\x64\x74\
+\x68\x3d\x22\x35\x31\x32\x70\x78\x22\x20\x68\x65\x69\x67\x68\x74\
+\x3d\x22\x35\x31\x32\x70\x78\x22\x20\x76\x69\x65\x77\x42\x6f\x78\
+\x3d\x22\x30\x20\x30\x20\x35\x31\x32\x20\x35\x31\x32\x22\x20\x73\
+\x74\x79\x6c\x65\x3d\x22\x65\x6e\x61\x62\x6c\x65\x2d\x62\x61\x63\
+\x6b\x67\x72\x6f\x75\x6e\x64\x3a\x6e\x65\x77\x20\x30\x20\x30\x20\
+\x35\x31\x32\x20\x35\x31\x32\x3b\x22\x20\x78\x6d\x6c\x3a\x73\x70\
+\x61\x63\x65\x3d\x22\x70\x72\x65\x73\x65\x72\x76\x65\x22\x3e\x0d\
+\x0a\x3c\x70\x6f\x6c\x79\x67\x6f\x6e\x20\x70\x6f\x69\x6e\x74\x73\
+\x3d\x22\x32\x38\x38\x2c\x39\x36\x20\x33\x33\x37\x2e\x39\x2c\x31\
+\x34\x35\x2e\x39\x20\x32\x37\x34\x2c\x32\x30\x39\x2e\x37\x20\x32\
+\x37\x34\x2c\x32\x30\x39\x2e\x37\x20\x31\x34\x35\x2e\x39\x2c\x33\
+\x33\x37\x2e\x39\x20\x39\x36\x2c\x32\x38\x38\x20\x39\x36\x2c\x34\
+\x31\x36\x20\x32\x32\x34\x2c\x34\x31\x36\x20\x31\x37\x34\x2e\x31\
+\x2c\x33\x36\x36\x2e\x31\x20\x33\x35\x37\x2e\x34\x2c\x31\x38\x32\
+\x2e\x39\x20\x33\x36\x36\x2e\x31\x2c\x31\x37\x34\x2e\x31\x20\x0d\
+\x0a\x09\x34\x31\x36\x2c\x32\x32\x34\x20\x34\x31\x36\x2c\x39\x36\
+\x20\x22\x2f\x3e\x0d\x0a\x3c\x2f\x73\x76\x67\x3e\x0d\x0a\
+\x00\x00\x04\x64\
+\x3c\
+\x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\
+\x30\x22\x20\x65\x6e\x63\x6f\x64\x69\x6e\x67\x3d\x22\x75\x74\x66\
+\x2d\x38\x22\x3f\x3e\x0d\x0a\x3c\x21\x2d\x2d\x20\x47\x65\x6e\x65\
+\x72\x61\x74\x6f\x72\x3a\x20\x41\x64\x6f\x62\x65\x20\x49\x6c\x6c\
+\x75\x73\x74\x72\x61\x74\x6f\x72\x20\x31\x36\x2e\x32\x2e\x31\x2c\
+\x20\x53\x56\x47\x20\x45\x78\x70\x6f\x72\x74\x20\x50\x6c\x75\x67\
+\x2d\x49\x6e\x20\x2e\x20\x53\x56\x47\x20\x56\x65\x72\x73\x69\x6f\
+\x6e\x3a\x20\x36\x2e\x30\x30\x20\x42\x75\x69\x6c\x64\x20\x30\x29\
+\x20\x20\x2d\x2d\x3e\x0d\x0a\x3c\x21\x44\x4f\x43\x54\x59\x50\x45\
+\x20\x73\x76\x67\x20\x50\x55\x42\x4c\x49\x43\x20\x22\x2d\x2f\x2f\
+\x57\x33\x43\x2f\x2f\x44\x54\x44\x20\x53\x56\x47\x20\x31\x2e\x31\
+\x2f\x2f\x45\x4e\x22\x20\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\
+\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x47\x72\x61\x70\x68\x69\x63\
+\x73\x2f\x53\x56\x47\x2f\x31\x2e\x31\x2f\x44\x54\x44\x2f\x73\x76\
+\x67\x31\x31\x2e\x64\x74\x64\x22\x3e\x0d\x0a\x3c\x73\x76\x67\x20\
+\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\x31\x22\x20\x69\x64\
+\x3d\x22\x4c\x61\x79\x65\x72\x5f\x31\x22\x20\x78\x6d\x6c\x6e\x73\
+\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\
+\x6f\x72\x67\x2f\x32\x30\x30\x30\x2f\x73\x76\x67\x22\x20\x78\x6d\
+\x6c\x6e\x73\x3a\x78\x6c\x69\x6e\x6b\x3d\x22\x68\x74\x74\x70\x3a\
+\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x31\x39\x39\
+\x39\x2f\x78\x6c\x69\x6e\x6b\x22\x20\x78\x3d\x22\x30\x70\x78\x22\
+\x20\x79\x3d\x22\x30\x70\x78\x22\x0d\x0a\x09\x20\x77\x69\x64\x74\
+\x68\x3d\x22\x35\x31\x32\x70\x78\x22\x20\x68\x65\x69\x67\x68\x74\
+\x3d\x22\x35\x31\x32\x70\x78\x22\x20\x76\x69\x65\x77\x42\x6f\x78\
 \x3d\x22\x30\x20\x30\x20\x35\x31\x32\x20\x35\x31\x32\x22\x20\x65\
 \x6e\x61\x62\x6c\x65\x2d\x62\x61\x63\x6b\x67\x72\x6f\x75\x6e\x64\
 \x3d\x22\x6e\x65\x77\x20\x30\x20\x30\x20\x35\x31\x32\x20\x35\x31\
 \x32\x22\x20\x78\x6d\x6c\x3a\x73\x70\x61\x63\x65\x3d\x22\x70\x72\
-\x65\x73\x65\x72\x76\x65\x22\x3e\x0d\x0a\x3c\x67\x20\x74\x72\x61\
-\x6e\x73\x66\x6f\x72\x6d\x3d\x27\x6d\x61\x74\x72\x69\x78\x28\x32\
-\x34\x20\x30\x20\x30\x20\x32\x34\x20\x30\x20\x30\x29\x27\x3e\x0d\
-\x0a\x3c\x70\x61\x74\x68\x20\x64\x3d\x22\x4d\x31\x31\x2e\x33\x30\
-\x32\x2c\x36\x2e\x37\x37\x36\x63\x2d\x30\x2e\x31\x39\x36\x2d\x30\
-\x2e\x31\x39\x37\x2d\x30\x2e\x35\x31\x35\x2d\x30\x2e\x31\x39\x37\
-\x2d\x30\x2e\x37\x31\x2c\x30\x4c\x37\x2e\x37\x38\x35\x2c\x39\x2e\
-\x36\x34\x31\x63\x2d\x30\x2e\x31\x39\x36\x2c\x30\x2e\x31\x39\x39\
-\x2d\x30\x2e\x31\x39\x36\x2c\x30\x2e\x35\x32\x2c\x30\x2c\x30\x2e\
-\x37\x31\x37\x6c\x32\x2e\x38\x30\x37\x2c\x32\x2e\x38\x36\x34\x0d\
-\x0a\x09\x63\x30\x2e\x31\x39\x35\x2c\x30\x2e\x31\x39\x39\x2c\x30\
-\x2e\x35\x31\x34\x2c\x30\x2e\x31\x39\x38\x2c\x30\x2e\x37\x31\x2c\
-\x30\x63\x30\x2e\x31\x39\x36\x2d\x30\x2e\x31\x39\x37\x2c\x30\x2e\
-\x31\x39\x36\x2d\x30\x2e\x35\x31\x38\x2c\x30\x2d\x30\x2e\x37\x31\
-\x37\x4c\x39\x2c\x31\x30\x6c\x32\x2e\x33\x30\x32\x2d\x32\x2e\x35\
-\x30\x36\x43\x31\x31\x2e\x34\x39\x38\x2c\x37\x2e\x32\x39\x36\x2c\
-\x31\x31\x2e\x34\x39\x38\x2c\x36\x2e\x39\x37\x36\x2c\x31\x31\x2e\
-\x33\x30\x32\x2c\x36\x2e\x37\x37\x36\x7a\x0d\x0a\x09\x20\x4d\x31\
-\x30\x2c\x30\x2e\x34\x63\x2d\x35\x2e\x33\x30\x32\x2c\x30\x2d\x39\
-\x2e\x36\x2c\x34\x2e\x32\x39\x38\x2d\x39\x2e\x36\x2c\x39\x2e\x36\
-\x63\x30\x2c\x35\x2e\x33\x30\x33\x2c\x34\x2e\x32\x39\x38\x2c\x39\
-\x2e\x36\x2c\x39\x2e\x36\x2c\x39\x2e\x36\x73\x39\x2e\x36\x2d\x34\
-\x2e\x32\x39\x37\x2c\x39\x2e\x36\x2d\x39\x2e\x36\x43\x31\x39\x2e\
-\x36\x2c\x34\x2e\x36\x39\x38\x2c\x31\x35\x2e\x33\x30\x32\x2c\x30\
-\x2e\x34\x2c\x31\x30\x2c\x30\x2e\x34\x7a\x20\x4d\x31\x30\x2c\x31\
-\x38\x2e\x33\x35\x34\x0d\x0a\x09\x63\x2d\x34\x2e\x36\x31\x35\x2c\
-\x30\x2d\x38\x2e\x33\x35\x34\x2d\x33\x2e\x37\x34\x2d\x38\x2e\x33\
-\x35\x34\x2d\x38\x2e\x33\x35\x34\x63\x30\x2d\x34\x2e\x36\x31\x34\
-\x2c\x33\x2e\x37\x33\x39\x2d\x38\x2e\x33\x35\x34\x2c\x38\x2e\x33\
-\x35\x34\x2d\x38\x2e\x33\x35\x34\x63\x34\x2e\x36\x31\x33\x2c\x30\
-\x2c\x38\x2e\x33\x35\x34\x2c\x33\x2e\x37\x34\x2c\x38\x2e\x33\x35\
-\x34\x2c\x38\x2e\x33\x35\x34\x0d\x0a\x09\x43\x31\x38\x2e\x33\x35\
-\x34\x2c\x31\x34\x2e\x36\x31\x34\x2c\x31\x34\x2e\x36\x31\x33\x2c\
-\x31\x38\x2e\x33\x35\x34\x2c\x31\x30\x2c\x31\x38\x2e\x33\x35\x34\
-\x7a\x22\x2f\x3e\x0d\x0a\x3c\x2f\x67\x3e\x0d\x0a\x3c\x2f\x73\x76\
-\x67\x3e\x0d\x0a\
-\x00\x00\x02\xc9\
+\x65\x73\x65\x72\x76\x65\x22\x3e\x0d\x0a\x3c\x67\x20\x69\x64\x3d\
+\x22\x49\x63\x6f\x6e\x22\x3e\x0d\x0a\x09\x3c\x67\x3e\x0d\x0a\x09\
+\x09\x3c\x70\x61\x74\x68\x20\x64\x3d\x22\x4d\x32\x35\x36\x2c\x31\
+\x37\x36\x63\x2d\x34\x34\x2e\x30\x30\x34\x2c\x30\x2d\x38\x30\x2e\
+\x30\x30\x31\x2c\x33\x36\x2d\x38\x30\x2e\x30\x30\x31\x2c\x38\x30\
+\x63\x30\x2c\x34\x34\x2e\x30\x30\x34\x2c\x33\x35\x2e\x39\x39\x37\
+\x2c\x38\x30\x2c\x38\x30\x2e\x30\x30\x31\x2c\x38\x30\x63\x34\x34\
+\x2e\x30\x30\x35\x2c\x30\x2c\x37\x39\x2e\x39\x39\x39\x2d\x33\x35\
+\x2e\x39\x39\x36\x2c\x37\x39\x2e\x39\x39\x39\x2d\x38\x30\x0d\x0a\
+\x09\x09\x09\x43\x33\x33\x35\x2e\x39\x39\x39\x2c\x32\x31\x32\x2c\
+\x33\x30\x30\x2e\x30\x30\x35\x2c\x31\x37\x36\x2c\x32\x35\x36\x2c\
+\x31\x37\x36\x7a\x20\x4d\x34\x34\x36\x2e\x39\x33\x38\x2c\x32\x33\
+\x34\x2e\x36\x36\x37\x63\x2d\x39\x2e\x36\x30\x35\x2d\x38\x38\x2e\
+\x35\x33\x31\x2d\x38\x31\x2e\x30\x37\x34\x2d\x31\x36\x30\x2d\x31\
+\x36\x39\x2e\x36\x30\x35\x2d\x31\x36\x39\x2e\x35\x39\x39\x56\x33\
+\x32\x68\x2d\x34\x32\x2e\x36\x36\x36\x76\x33\x33\x2e\x30\x36\x37\
+\x0d\x0a\x09\x09\x09\x63\x2d\x38\x38\x2e\x35\x33\x31\x2c\x39\x2e\
+\x35\x39\x39\x2d\x31\x36\x30\x2c\x38\x31\x2e\x30\x36\x38\x2d\x31\
+\x36\x39\x2e\x36\x30\x34\x2c\x31\x36\x39\x2e\x35\x39\x39\x48\x33\
+\x32\x76\x34\x32\x2e\x36\x36\x37\x68\x33\x33\x2e\x30\x36\x32\x63\
+\x39\x2e\x36\x30\x34\x2c\x38\x38\x2e\x35\x33\x31\x2c\x38\x31\x2e\
+\x30\x37\x32\x2c\x31\x36\x30\x2c\x31\x36\x39\x2e\x36\x30\x34\x2c\
+\x31\x36\x39\x2e\x36\x30\x34\x56\x34\x38\x30\x68\x34\x32\x2e\x36\
+\x36\x36\x76\x2d\x33\x33\x2e\x30\x36\x32\x0d\x0a\x09\x09\x09\x63\
+\x38\x38\x2e\x35\x33\x31\x2d\x39\x2e\x36\x30\x34\x2c\x31\x36\x30\
+\x2d\x38\x31\x2e\x30\x37\x33\x2c\x31\x36\x39\x2e\x36\x30\x35\x2d\
+\x31\x36\x39\x2e\x36\x30\x34\x48\x34\x38\x30\x76\x2d\x34\x32\x2e\
+\x36\x36\x37\x48\x34\x34\x36\x2e\x39\x33\x38\x7a\x20\x4d\x32\x35\
+\x36\x2c\x34\x30\x35\x2e\x33\x33\x33\x63\x2d\x38\x32\x2e\x31\x33\
+\x37\x2c\x30\x2d\x31\x34\x39\x2e\x33\x33\x34\x2d\x36\x37\x2e\x31\
+\x39\x38\x2d\x31\x34\x39\x2e\x33\x33\x34\x2d\x31\x34\x39\x2e\x33\
+\x33\x33\x0d\x0a\x09\x09\x09\x63\x30\x2d\x38\x32\x2e\x31\x33\x36\
+\x2c\x36\x37\x2e\x31\x39\x37\x2d\x31\x34\x39\x2e\x33\x33\x33\x2c\
+\x31\x34\x39\x2e\x33\x33\x34\x2d\x31\x34\x39\x2e\x33\x33\x33\x63\
+\x38\x32\x2e\x31\x33\x35\x2c\x30\x2c\x31\x34\x39\x2e\x33\x33\x32\
+\x2c\x36\x37\x2e\x31\x39\x38\x2c\x31\x34\x39\x2e\x33\x33\x32\x2c\
+\x31\x34\x39\x2e\x33\x33\x33\x43\x34\x30\x35\x2e\x33\x33\x32\x2c\
+\x33\x33\x38\x2e\x31\x33\x35\x2c\x33\x33\x38\x2e\x31\x33\x35\x2c\
+\x34\x30\x35\x2e\x33\x33\x33\x2c\x32\x35\x36\x2c\x34\x30\x35\x2e\
+\x33\x33\x33\x7a\x0d\x0a\x09\x09\x09\x22\x2f\x3e\x0d\x0a\x09\x3c\
+\x2f\x67\x3e\x0d\x0a\x3c\x2f\x67\x3e\x0d\x0a\x3c\x2f\x73\x76\x67\
+\x3e\x0d\x0a\
+\x00\x00\x02\xa2\
 \x3c\
 \x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\
 \x30\x22\x20\x65\x6e\x63\x6f\x64\x69\x6e\x67\x3d\x22\x75\x74\x66\
@@ -840,27 +654,25 @@
 \x20\x79\x3d\x22\x30\x70\x78\x22\x0d\x0a\x09\x20\x77\x69\x64\x74\
 \x68\x3d\x22\x35\x31\x32\x70\x78\x22\x20\x68\x65\x69\x67\x68\x74\
 \x3d\x22\x35\x31\x32\x70\x78\x22\x20\x76\x69\x65\x77\x42\x6f\x78\
-\x3d\x22\x30\x20\x30\x20\x35\x31\x32\x20\x35\x31\x32\x22\x20\x73\
-\x74\x79\x6c\x65\x3d\x22\x65\x6e\x61\x62\x6c\x65\x2d\x62\x61\x63\
-\x6b\x67\x72\x6f\x75\x6e\x64\x3a\x6e\x65\x77\x20\x30\x20\x30\x20\
-\x35\x31\x32\x20\x35\x31\x32\x3b\x22\x20\x78\x6d\x6c\x3a\x73\x70\
-\x61\x63\x65\x3d\x22\x70\x72\x65\x73\x65\x72\x76\x65\x22\x3e\x0d\
-\x0a\x3c\x70\x6f\x6c\x79\x67\x6f\x6e\x20\x70\x6f\x69\x6e\x74\x73\
-\x3d\x22\x34\x38\x30\x2c\x32\x35\x36\x20\x33\x38\x34\x2c\x31\x36\
-\x30\x20\x33\x38\x34\x2c\x32\x33\x36\x20\x32\x37\x36\x2c\x32\x33\
-\x36\x20\x32\x37\x36\x2c\x31\x32\x38\x20\x33\x35\x32\x2c\x31\x32\
-\x38\x20\x32\x35\x36\x2c\x33\x32\x20\x31\x36\x30\x2c\x31\x32\x38\
-\x20\x32\x33\x36\x2c\x31\x32\x38\x20\x32\x33\x36\x2c\x32\x33\x36\
-\x20\x31\x32\x38\x2c\x32\x33\x36\x20\x31\x32\x38\x2c\x31\x36\x30\
-\x20\x33\x32\x2c\x32\x35\x36\x20\x31\x32\x38\x2c\x33\x35\x32\x20\
-\x0d\x0a\x09\x31\x32\x38\x2c\x32\x37\x36\x20\x32\x33\x36\x2c\x32\
-\x37\x36\x20\x32\x33\x36\x2c\x33\x38\x34\x20\x31\x36\x30\x2c\x33\
-\x38\x34\x20\x32\x35\x36\x2c\x34\x38\x30\x20\x33\x35\x32\x2c\x33\
-\x38\x34\x20\x32\x37\x35\x2e\x38\x2c\x33\x38\x34\x20\x32\x37\x35\
-\x2e\x34\x2c\x32\x37\x35\x2e\x35\x20\x33\x38\x34\x2c\x32\x37\x35\
-\x2e\x38\x20\x33\x38\x34\x2c\x33\x35\x32\x20\x22\x2f\x3e\x0d\x0a\
-\x3c\x2f\x73\x76\x67\x3e\x0d\x0a\
-\x00\x00\x05\xca\
+\x3d\x22\x30\x20\x30\x20\x35\x31\x32\x20\x35\x31\x32\x22\x20\x65\
+\x6e\x61\x62\x6c\x65\x2d\x62\x61\x63\x6b\x67\x72\x6f\x75\x6e\x64\
+\x3d\x22\x6e\x65\x77\x20\x30\x20\x30\x20\x35\x31\x32\x20\x35\x31\
+\x32\x22\x20\x78\x6d\x6c\x3a\x73\x70\x61\x63\x65\x3d\x22\x70\x72\
+\x65\x73\x65\x72\x76\x65\x22\x3e\x0d\x0a\x3c\x67\x3e\x0d\x0a\x09\
+\x3c\x70\x61\x74\x68\x20\x64\x3d\x22\x4d\x31\x32\x38\x2c\x34\x30\
+\x35\x2e\x34\x32\x39\x43\x31\x32\x38\x2c\x34\x32\x38\x2e\x38\x34\
+\x36\x2c\x31\x34\x37\x2e\x31\x39\x38\x2c\x34\x34\x38\x2c\x31\x37\
+\x30\x2e\x36\x36\x37\x2c\x34\x34\x38\x68\x31\x37\x30\x2e\x36\x36\
+\x37\x43\x33\x36\x34\x2e\x38\x30\x32\x2c\x34\x34\x38\x2c\x33\x38\
+\x34\x2c\x34\x32\x38\x2e\x38\x34\x36\x2c\x33\x38\x34\x2c\x34\x30\
+\x35\x2e\x34\x32\x39\x56\x31\x36\x30\x48\x31\x32\x38\x56\x34\x30\
+\x35\x2e\x34\x32\x39\x7a\x20\x4d\x34\x31\x36\x2c\x39\x36\x0d\x0a\
+\x09\x09\x68\x2d\x38\x30\x6c\x2d\x32\x36\x2e\x37\x38\x35\x2d\x33\
+\x32\x48\x32\x30\x32\x2e\x37\x38\x36\x4c\x31\x37\x36\x2c\x39\x36\
+\x48\x39\x36\x76\x33\x32\x68\x33\x32\x30\x56\x39\x36\x7a\x22\x2f\
+\x3e\x0d\x0a\x3c\x2f\x67\x3e\x0d\x0a\x3c\x2f\x73\x76\x67\x3e\x0d\
+\x0a\
+\x00\x00\x02\x79\
 \x3c\
 \x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\
 \x30\x22\x20\x65\x6e\x63\x6f\x64\x69\x6e\x67\x3d\x22\x75\x74\x66\
@@ -891,77 +703,56 @@
 \x6e\x61\x62\x6c\x65\x2d\x62\x61\x63\x6b\x67\x72\x6f\x75\x6e\x64\
 \x3d\x22\x6e\x65\x77\x20\x30\x20\x30\x20\x35\x31\x32\x20\x35\x31\
 \x32\x22\x20\x78\x6d\x6c\x3a\x73\x70\x61\x63\x65\x3d\x22\x70\x72\
-\x65\x73\x65\x72\x76\x65\x22\x3e\x0d\x0a\x3c\x70\x61\x74\x68\x20\
-\x64\x3d\x22\x4d\x34\x35\x30\x2e\x36\x37\x39\x2c\x32\x37\x33\x2e\
-\x35\x63\x2d\x31\x34\x2e\x35\x38\x35\x2d\x31\x34\x2e\x35\x37\x37\
-\x2d\x33\x36\x2e\x30\x35\x34\x2d\x31\x35\x2e\x38\x39\x2d\x35\x30\
-\x2e\x36\x33\x39\x2d\x31\x2e\x33\x31\x32\x6c\x2d\x34\x31\x2e\x36\
-\x38\x37\x2c\x34\x31\x2e\x36\x36\x34\x63\x2d\x31\x30\x2e\x38\x35\
-\x32\x2c\x31\x30\x2e\x38\x33\x36\x2d\x32\x33\x2e\x39\x33\x2c\x31\
-\x30\x2e\x38\x35\x39\x2d\x33\x31\x2e\x35\x36\x34\x2c\x31\x2e\x38\
-\x35\x32\x0d\x0a\x09\x63\x2d\x35\x2e\x30\x35\x37\x2d\x35\x2e\x39\
-\x36\x38\x2d\x33\x2e\x30\x36\x31\x2d\x32\x34\x2e\x33\x37\x34\x2d\
-\x31\x2e\x36\x34\x34\x2d\x33\x36\x2e\x30\x34\x39\x6c\x32\x30\x2e\
-\x39\x30\x37\x2d\x31\x37\x31\x2e\x38\x34\x39\x63\x31\x2e\x38\x36\
-\x37\x2d\x31\x35\x2e\x33\x35\x33\x2d\x39\x2e\x30\x37\x2d\x33\x30\
-\x2e\x31\x38\x35\x2d\x32\x34\x2e\x34\x33\x2d\x33\x32\x2e\x30\x35\
-\x31\x0d\x0a\x09\x63\x2d\x31\x35\x2e\x33\x35\x38\x2d\x31\x2e\x38\
-\x36\x37\x2d\x32\x39\x2e\x33\x32\x32\x2c\x39\x2e\x39\x33\x39\x2d\
-\x33\x31\x2e\x31\x39\x31\x2c\x32\x35\x2e\x32\x38\x39\x4c\x32\x36\
-\x37\x2e\x33\x37\x2c\x32\x33\x36\x2e\x30\x32\x31\x63\x2d\x31\x2e\
-\x32\x30\x35\x2c\x33\x2e\x33\x35\x38\x2d\x33\x2e\x37\x39\x2c\x33\
-\x2e\x39\x33\x38\x2d\x34\x2e\x30\x38\x31\x2d\x30\x2e\x35\x38\x32\
-\x4c\x32\x35\x35\x2e\x34\x34\x2c\x36\x30\x0d\x0a\x09\x63\x30\x2d\
-\x31\x35\x2e\x34\x36\x35\x2d\x31\x32\x2e\x35\x34\x32\x2d\x32\x38\
-\x2d\x32\x38\x2e\x30\x31\x34\x2d\x32\x38\x63\x2d\x31\x35\x2e\x34\
-\x37\x33\x2c\x30\x2d\x32\x38\x2e\x30\x31\x35\x2c\x31\x32\x2e\x35\
-\x33\x35\x2d\x32\x38\x2e\x30\x31\x35\x2c\x32\x38\x6c\x2d\x30\x2e\
-\x35\x35\x32\x2c\x31\x37\x36\x2e\x37\x35\x32\x63\x30\x2e\x31\x34\
-\x36\x2c\x32\x2e\x30\x34\x2d\x31\x2e\x36\x30\x34\x2c\x32\x2e\x36\
-\x32\x34\x2d\x31\x2e\x39\x32\x2c\x30\x2e\x32\x39\x34\x4c\x31\x37\
-\x32\x2e\x30\x31\x36\x2c\x39\x39\x2e\x30\x37\x37\x0d\x0a\x09\x63\
-\x2d\x32\x2e\x37\x35\x2d\x31\x35\x2e\x32\x31\x39\x2d\x31\x37\x2e\
-\x33\x32\x33\x2d\x32\x36\x2e\x32\x30\x33\x2d\x33\x32\x2e\x35\x34\
-\x38\x2d\x32\x33\x2e\x34\x35\x33\x63\x2d\x31\x35\x2e\x32\x32\x37\
-\x2c\x32\x2e\x37\x34\x38\x2d\x32\x35\x2e\x33\x33\x39\x2c\x31\x38\
-\x2e\x31\x38\x37\x2d\x32\x32\x2e\x35\x39\x31\x2c\x33\x33\x2e\x34\
-\x30\x33\x6c\x32\x32\x2e\x31\x39\x33\x2c\x31\x36\x31\x2e\x34\x35\
-\x35\x0d\x0a\x09\x63\x30\x2e\x30\x32\x33\x2c\x32\x2e\x38\x37\x32\
-\x2d\x30\x2e\x39\x34\x31\x2c\x34\x2e\x35\x31\x33\x2d\x32\x2e\x33\
-\x30\x38\x2c\x30\x2e\x38\x33\x31\x6c\x2d\x33\x33\x2e\x31\x30\x39\
-\x2d\x38\x38\x2e\x35\x31\x37\x63\x2d\x35\x2e\x31\x38\x2d\x31\x34\
-\x2e\x35\x37\x32\x2d\x32\x31\x2e\x31\x39\x36\x2d\x32\x33\x2e\x30\
-\x36\x35\x2d\x33\x35\x2e\x37\x37\x36\x2d\x31\x37\x2e\x38\x38\x39\
-\x0d\x0a\x09\x63\x2d\x31\x34\x2e\x35\x37\x39\x2c\x35\x2e\x31\x37\
-\x37\x2d\x32\x32\x2e\x32\x30\x31\x2c\x32\x32\x2e\x30\x36\x31\x2d\
-\x31\x37\x2e\x30\x32\x33\x2c\x33\x36\x2e\x36\x33\x31\x6c\x35\x38\
-\x2e\x30\x34\x32\x2c\x31\x38\x39\x2e\x36\x32\x35\x63\x30\x2e\x33\
-\x30\x33\x2c\x31\x2e\x30\x34\x36\x2c\x30\x2e\x36\x32\x34\x2c\x32\
-\x2e\x30\x38\x35\x2c\x30\x2e\x39\x35\x33\x2c\x33\x2e\x31\x31\x38\
-\x6c\x30\x2e\x31\x32\x31\x2c\x30\x2e\x33\x39\x0d\x0a\x09\x63\x30\
-\x2e\x30\x31\x31\x2c\x30\x2e\x30\x33\x31\x2c\x30\x2e\x30\x32\x35\
-\x2c\x30\x2e\x30\x35\x38\x2c\x30\x2e\x30\x33\x35\x2c\x30\x2e\x30\
-\x38\x38\x43\x31\x32\x36\x2e\x30\x37\x39\x2c\x34\x34\x34\x2e\x32\
-\x33\x33\x2c\x31\x37\x32\x2e\x35\x37\x2c\x34\x38\x30\x2c\x32\x32\
-\x37\x2e\x34\x32\x37\x2c\x34\x38\x30\x63\x33\x35\x2e\x31\x31\x36\
-\x2c\x30\x2c\x37\x31\x2e\x35\x39\x31\x2d\x31\x32\x2e\x33\x37\x38\
-\x2c\x39\x39\x2e\x33\x35\x37\x2d\x33\x33\x2e\x36\x37\x32\x0d\x0a\
-\x09\x63\x30\x2e\x30\x30\x31\x2c\x30\x2c\x30\x2e\x30\x30\x33\x2d\
-\x30\x2e\x30\x30\x32\x2c\x30\x2e\x30\x30\x33\x2d\x30\x2e\x30\x30\
-\x32\x63\x32\x39\x2e\x39\x39\x2d\x31\x38\x2e\x30\x35\x31\x2c\x31\
-\x32\x36\x2e\x30\x37\x31\x2d\x31\x32\x31\x2e\x33\x34\x37\x2c\x31\
-\x32\x36\x2e\x30\x37\x31\x2d\x31\x32\x31\x2e\x33\x34\x37\x43\x34\
-\x36\x37\x2e\x34\x34\x35\x2c\x33\x31\x30\x2e\x34\x30\x32\x2c\x34\
-\x36\x35\x2e\x32\x36\x36\x2c\x32\x38\x38\x2e\x30\x38\x2c\x34\x35\
-\x30\x2e\x36\x37\x39\x2c\x32\x37\x33\x2e\x35\x7a\x22\x2f\x3e\x0d\
-\x0a\x3c\x2f\x73\x76\x67\x3e\x0d\x0a\
-\x00\x00\x03\xc4\
+\x65\x73\x65\x72\x76\x65\x22\x3e\x0d\x0a\x3c\x67\x20\x69\x64\x3d\
+\x22\x49\x63\x6f\x6e\x5f\x31\x5f\x22\x3e\x0d\x0a\x09\x3c\x67\x3e\
+\x0d\x0a\x09\x09\x3c\x67\x3e\x0d\x0a\x09\x09\x09\x3c\x70\x6f\x6c\
+\x79\x67\x6f\x6e\x20\x70\x6f\x69\x6e\x74\x73\x3d\x22\x31\x38\x36\
+\x2e\x33\x30\x31\x2c\x33\x33\x39\x2e\x38\x39\x33\x20\x39\x36\x2c\
+\x32\x34\x39\x2e\x34\x36\x31\x20\x36\x34\x2c\x32\x37\x39\x2e\x39\
+\x36\x38\x20\x31\x38\x36\x2e\x33\x30\x31\x2c\x34\x30\x32\x20\x34\
+\x34\x38\x2c\x31\x34\x30\x2e\x35\x30\x36\x20\x34\x31\x36\x2c\x31\
+\x31\x30\x20\x09\x09\x09\x22\x2f\x3e\x0d\x0a\x09\x09\x3c\x2f\x67\
+\x3e\x0d\x0a\x09\x3c\x2f\x67\x3e\x0d\x0a\x3c\x2f\x67\x3e\x0d\x0a\
+\x3c\x2f\x73\x76\x67\x3e\x0d\x0a\
+\x00\x00\x01\xdd\
+\x00\
+\x00\x06\xe4\x78\x9c\xcd\x54\x4d\x6f\x9b\x40\x10\x3d\x13\x29\xff\
+\x61\xba\xb7\x4a\xec\x17\xc4\xd4\xa6\xa6\x51\xfd\x21\xcb\x52\x9a\
+\x58\x6a\xea\xaa\xa7\x0a\xc3\x16\x50\x28\x20\x58\xc0\xce\xaf\xef\
+\xee\x92\x54\x51\x95\xfa\x18\xfb\xb0\x33\xda\x79\x6f\xde\xbc\x65\
+\x24\xa6\xd7\xfb\xdf\x39\x74\xa2\x6e\xb2\xb2\x08\x10\x27\x0c\x81\
+\x28\xa2\x32\xce\x8a\x24\x40\xad\xfc\x85\xc7\xe8\xfa\xd3\xe5\xc5\
+\xf4\x1d\xc6\xb0\x12\x85\xa8\x43\x59\xd6\x3e\x7c\x8e\xcb\x9d\x80\
+\x75\x9e\xb7\x8d\x34\x25\xe0\x1e\x71\x08\xb7\xe1\xeb\x76\x05\xcb\
+\x7d\x55\xd6\x12\x36\x79\x9b\xe0\x75\x01\xc4\x14\xb7\xc3\x10\x1f\
+\x3c\xc2\x18\xcc\xda\x2c\x8f\x81\xbd\x07\xc0\xd8\xe8\x2f\xee\xe6\
+\xf7\x3f\x36\x4b\x68\xba\x04\x36\xdf\x66\x37\xeb\x39\x20\x4c\xe9\
+\x77\x77\x4e\xe9\xe2\x7e\x61\x24\x38\xe1\x94\x2e\x6f\x11\xa0\x54\
+\xca\xca\xa7\xb4\xef\x7b\xd2\xbb\xa4\xac\x13\xba\xaa\xc3\x2a\xcd\
+\xa2\x86\x2a\x22\xd5\x44\xd5\x44\x95\x18\xe7\x24\x96\x31\xd2\x33\
+\xb4\xf4\x8b\xa7\x72\x04\x59\x1c\xa0\x9b\xf0\x20\xea\x9f\xea\xa2\
+\xbe\x44\xd1\x04\xaf\x48\x3b\x8c\x31\x2d\xf5\x44\xf1\xf7\x79\x56\
+\x3c\xbc\x46\xe4\x93\xc9\x84\x1a\x54\x51\x03\xc4\xaa\x3d\x82\xc3\
+\x90\x2f\x2f\x2c\xe8\xb3\x58\xa6\x01\x1a\x71\x47\x03\xa9\xc8\x92\
+\x54\xfe\xbd\x76\x99\xe8\x67\xa5\xee\x02\x06\xaa\xa6\x0f\x82\x46\
+\x1e\x72\x11\x20\x51\x84\xbb\x5c\xe0\x5d\x18\x3d\x24\x75\xd9\x16\
+\xb1\x5f\x88\x1e\x5e\x30\x3f\x1a\x6f\x7e\x53\x85\x91\xa2\x57\xb5\
+\x68\x44\xdd\x09\xf3\xea\x44\x05\x6b\x88\xd6\xb4\x0a\x65\x0a\xea\
+\xd1\x5f\xb8\xc7\x6c\x3e\x72\x89\x1b\x31\xdb\x25\x1f\xb0\x6b\x7b\
+\x2a\xaa\xa3\x73\x8a\x47\x8c\x8c\x22\xac\x00\x9b\xe9\x22\x76\xf1\
+\x13\xdc\x0d\x10\x33\x98\xfb\xdc\xa0\x73\x6a\x00\xd3\xa2\x4b\xb6\
+\x51\xd4\x67\x6b\xe6\x3c\xea\x4f\x60\x59\xf4\x1f\x1f\xce\x78\x7c\
+\x16\x3e\xae\xb8\x77\x3a\x1f\x53\xfa\xff\x25\x39\x63\xfe\x26\xa6\
+\xcc\x9c\x23\x4b\x3a\x07\x1f\x7a\x49\x27\xf3\x71\x6c\x49\x57\x6c\
+\xf2\x26\xa6\xcc\x9c\x23\x4b\x3a\x07\x1f\x7a\x49\x27\xf3\x31\x2c\
+\xe9\x39\xaa\x7f\xb6\xca\x7f\x00\x99\x18\x96\x19\
+\x00\x00\x02\xfc\
 \x3c\
 \x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\
 \x30\x22\x20\x65\x6e\x63\x6f\x64\x69\x6e\x67\x3d\x22\x75\x74\x66\
 \x2d\x38\x22\x3f\x3e\x0d\x0a\x3c\x21\x2d\x2d\x20\x47\x65\x6e\x65\
 \x72\x61\x74\x6f\x72\x3a\x20\x41\x64\x6f\x62\x65\x20\x49\x6c\x6c\
-\x75\x73\x74\x72\x61\x74\x6f\x72\x20\x31\x38\x2e\x31\x2e\x30\x2c\
+\x75\x73\x74\x72\x61\x74\x6f\x72\x20\x31\x36\x2e\x32\x2e\x31\x2c\
 \x20\x53\x56\x47\x20\x45\x78\x70\x6f\x72\x74\x20\x50\x6c\x75\x67\
 \x2d\x49\x6e\x20\x2e\x20\x53\x56\x47\x20\x56\x65\x72\x73\x69\x6f\
 \x6e\x3a\x20\x36\x2e\x30\x30\x20\x42\x75\x69\x6c\x64\x20\x30\x29\
@@ -973,128 +764,38 @@
 \x73\x2f\x53\x56\x47\x2f\x31\x2e\x31\x2f\x44\x54\x44\x2f\x73\x76\
 \x67\x31\x31\x2e\x64\x74\x64\x22\x3e\x0d\x0a\x3c\x73\x76\x67\x20\
 \x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\x31\x22\x20\x69\x64\
-\x3d\x22\x4d\x61\x67\x6e\x69\x66\x79\x69\x6e\x67\x5f\x67\x6c\x61\
-\x73\x73\x22\x20\x78\x6d\x6c\x6e\x73\x3d\x22\x68\x74\x74\x70\x3a\
-\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x32\x30\x30\
-\x30\x2f\x73\x76\x67\x22\x20\x78\x6d\x6c\x6e\x73\x3a\x78\x6c\x69\
-\x6e\x6b\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\
-\x33\x2e\x6f\x72\x67\x2f\x31\x39\x39\x39\x2f\x78\x6c\x69\x6e\x6b\
-\x22\x20\x78\x3d\x22\x30\x70\x78\x22\x0d\x0a\x09\x20\x79\x3d\x22\
-\x30\x70\x78\x22\x20\x76\x69\x65\x77\x42\x6f\x78\x3d\x22\x30\x20\
-\x30\x20\x35\x31\x32\x20\x35\x31\x32\x22\x20\x65\x6e\x61\x62\x6c\
-\x65\x2d\x62\x61\x63\x6b\x67\x72\x6f\x75\x6e\x64\x3d\x22\x6e\x65\
-\x77\x20\x30\x20\x30\x20\x35\x31\x32\x20\x35\x31\x32\x22\x20\x78\
-\x6d\x6c\x3a\x73\x70\x61\x63\x65\x3d\x22\x70\x72\x65\x73\x65\x72\
-\x76\x65\x22\x3e\x0d\x0a\x3c\x67\x20\x74\x72\x61\x6e\x73\x66\x6f\
-\x72\x6d\x3d\x27\x6d\x61\x74\x72\x69\x78\x28\x32\x34\x20\x30\x20\
-\x30\x20\x32\x34\x20\x30\x20\x30\x29\x27\x3e\x0d\x0a\x3c\x70\x61\
-\x74\x68\x20\x64\x3d\x22\x4d\x31\x37\x2e\x35\x34\x35\x2c\x31\x35\
-\x2e\x34\x36\x37\x6c\x2d\x33\x2e\x37\x37\x39\x2d\x33\x2e\x37\x37\
-\x39\x63\x30\x2e\x35\x37\x2d\x30\x2e\x39\x33\x35\x2c\x30\x2e\x38\
-\x39\x38\x2d\x32\x2e\x30\x33\x35\x2c\x30\x2e\x38\x39\x38\x2d\x33\
-\x2e\x32\x31\x63\x30\x2d\x33\x2e\x34\x31\x37\x2d\x32\x2e\x39\x36\
-\x31\x2d\x36\x2e\x33\x37\x37\x2d\x36\x2e\x33\x37\x38\x2d\x36\x2e\
-\x33\x37\x37\x0d\x0a\x09\x43\x34\x2e\x38\x36\x39\x2c\x32\x2e\x31\
-\x2c\x32\x2e\x31\x2c\x34\x2e\x38\x37\x2c\x32\x2e\x31\x2c\x38\x2e\
-\x32\x38\x37\x63\x30\x2c\x33\x2e\x34\x31\x36\x2c\x32\x2e\x39\x36\
-\x31\x2c\x36\x2e\x33\x37\x37\x2c\x36\x2e\x33\x37\x37\x2c\x36\x2e\
-\x33\x37\x37\x63\x31\x2e\x31\x33\x37\x2c\x30\x2c\x32\x2e\x32\x2d\
-\x30\x2e\x33\x30\x39\x2c\x33\x2e\x31\x31\x35\x2d\x30\x2e\x38\x34\
-\x34\x6c\x33\x2e\x37\x39\x39\x2c\x33\x2e\x38\x30\x31\x0d\x0a\x09\
-\x63\x30\x2e\x33\x37\x32\x2c\x30\x2e\x33\x37\x31\x2c\x30\x2e\x39\
-\x37\x35\x2c\x30\x2e\x33\x37\x31\x2c\x31\x2e\x33\x34\x36\x2c\x30\
-\x6c\x30\x2e\x39\x34\x33\x2d\x30\x2e\x39\x34\x33\x43\x31\x38\x2e\
-\x30\x35\x31\x2c\x31\x36\x2e\x33\x30\x37\x2c\x31\x37\x2e\x39\x31\
-\x36\x2c\x31\x35\x2e\x38\x33\x38\x2c\x31\x37\x2e\x35\x34\x35\x2c\
-\x31\x35\x2e\x34\x36\x37\x7a\x20\x4d\x34\x2e\x30\x30\x34\x2c\x38\
-\x2e\x32\x38\x37\x0d\x0a\x09\x63\x30\x2d\x32\x2e\x33\x36\x36\x2c\
-\x31\x2e\x39\x31\x37\x2d\x34\x2e\x32\x38\x33\x2c\x34\x2e\x32\x38\
-\x32\x2d\x34\x2e\x32\x38\x33\x63\x32\x2e\x33\x36\x36\x2c\x30\x2c\
-\x34\x2e\x34\x37\x34\x2c\x32\x2e\x31\x30\x37\x2c\x34\x2e\x34\x37\
-\x34\x2c\x34\x2e\x34\x37\x34\x63\x30\x2c\x32\x2e\x33\x36\x35\x2d\
-\x31\x2e\x39\x31\x38\x2c\x34\x2e\x32\x38\x33\x2d\x34\x2e\x32\x38\
-\x33\x2c\x34\x2e\x32\x38\x33\x0d\x0a\x09\x43\x36\x2e\x31\x31\x31\
-\x2c\x31\x32\x2e\x37\x36\x2c\x34\x2e\x30\x30\x34\x2c\x31\x30\x2e\
-\x36\x35\x32\x2c\x34\x2e\x30\x30\x34\x2c\x38\x2e\x32\x38\x37\x7a\
-\x22\x2f\x3e\x0d\x0a\x3c\x2f\x67\x3e\x0d\x0a\x3c\x2f\x73\x76\x67\
-\x3e\x0d\x0a\
-\x00\x00\x04\xa2\
-\x3c\
-\x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x27\x31\x2e\
-\x30\x27\x20\x65\x6e\x63\x6f\x64\x69\x6e\x67\x3d\x27\x55\x54\x46\
-\x2d\x38\x27\x3f\x3e\x0a\x3c\x21\x2d\x2d\x20\x54\x68\x69\x73\x20\
-\x66\x69\x6c\x65\x20\x77\x61\x73\x20\x67\x65\x6e\x65\x72\x61\x74\
-\x65\x64\x20\x62\x79\x20\x64\x76\x69\x73\x76\x67\x6d\x20\x32\x2e\
-\x38\x20\x2d\x2d\x3e\x0a\x3c\x73\x76\x67\x20\x76\x65\x72\x73\x69\
-\x6f\x6e\x3d\x27\x31\x2e\x31\x27\x20\x78\x6d\x6c\x6e\x73\x3d\x27\
-\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\
-\x67\x2f\x32\x30\x30\x30\x2f\x73\x76\x67\x27\x20\x78\x6d\x6c\x6e\
-\x73\x3a\x78\x6c\x69\x6e\x6b\x3d\x27\x68\x74\x74\x70\x3a\x2f\x2f\
-\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x31\x39\x39\x39\x2f\
-\x78\x6c\x69\x6e\x6b\x27\x20\x77\x69\x64\x74\x68\x3d\x27\x36\x33\
-\x2e\x39\x39\x39\x36\x70\x74\x27\x20\x68\x65\x69\x67\x68\x74\x3d\
-\x27\x36\x33\x2e\x39\x39\x39\x37\x70\x74\x27\x20\x76\x69\x65\x77\
-\x42\x6f\x78\x3d\x27\x35\x36\x2e\x34\x30\x39\x34\x20\x35\x33\x2e\
-\x38\x35\x38\x33\x20\x36\x33\x2e\x39\x39\x39\x36\x20\x36\x33\x2e\
-\x39\x39\x39\x37\x27\x3e\x0a\x3c\x67\x20\x69\x64\x3d\x27\x70\x61\
-\x67\x65\x31\x27\x3e\x0a\x3c\x67\x20\x74\x72\x61\x6e\x73\x66\x6f\
-\x72\x6d\x3d\x27\x6d\x61\x74\x72\x69\x78\x28\x30\x2e\x39\x39\x36\
-\x32\x36\x34\x20\x30\x20\x30\x20\x30\x2e\x39\x39\x36\x32\x36\x34\
-\x20\x35\x38\x2e\x34\x36\x36\x39\x20\x31\x31\x37\x2e\x38\x35\x38\
-\x29\x27\x3e\x0a\x3c\x70\x61\x74\x68\x20\x64\x3d\x27\x4d\x20\x33\
-\x2e\x39\x35\x37\x33\x35\x20\x2d\x33\x32\x2e\x31\x32\x43\x20\x34\
-\x2e\x31\x35\x35\x35\x36\x20\x2d\x33\x39\x2e\x32\x37\x34\x35\x20\
-\x36\x2e\x39\x38\x34\x37\x33\x20\x2d\x34\x36\x2e\x31\x30\x34\x37\
-\x20\x31\x31\x2e\x39\x30\x33\x36\x20\x2d\x35\x31\x2e\x33\x30\x33\
-\x39\x43\x20\x32\x37\x2e\x34\x34\x31\x31\x20\x2d\x36\x37\x2e\x37\
-\x32\x36\x39\x20\x35\x33\x2e\x33\x30\x32\x31\x20\x2d\x36\x31\x2e\
-\x35\x34\x30\x35\x20\x35\x36\x2e\x31\x35\x32\x33\x20\x2d\x34\x32\
-\x2e\x35\x30\x32\x32\x43\x20\x35\x37\x2e\x36\x32\x37\x20\x2d\x33\
-\x32\x2e\x36\x35\x31\x39\x20\x35\x30\x2e\x35\x38\x35\x36\x20\x2d\
-\x32\x33\x2e\x35\x36\x32\x31\x20\x34\x30\x2e\x36\x37\x39\x34\x20\
-\x2d\x32\x32\x2e\x35\x32\x38\x31\x27\x20\x66\x69\x6c\x6c\x3d\x27\
-\x6e\x6f\x6e\x65\x27\x20\x73\x74\x72\x6f\x6b\x65\x3d\x27\x23\x30\
-\x30\x30\x30\x30\x30\x27\x20\x73\x74\x72\x6f\x6b\x65\x2d\x6c\x69\
-\x6e\x65\x63\x61\x70\x3d\x27\x72\x6f\x75\x6e\x64\x27\x20\x73\x74\
-\x72\x6f\x6b\x65\x2d\x6c\x69\x6e\x65\x6a\x6f\x69\x6e\x3d\x27\x72\
-\x6f\x75\x6e\x64\x27\x20\x73\x74\x72\x6f\x6b\x65\x2d\x6d\x69\x74\
-\x65\x72\x6c\x69\x6d\x69\x74\x3d\x27\x31\x30\x2e\x30\x33\x37\x35\
-\x27\x20\x73\x74\x72\x6f\x6b\x65\x2d\x77\x69\x64\x74\x68\x3d\x27\
-\x32\x2e\x35\x30\x39\x33\x37\x27\x2f\x3e\x0a\x3c\x2f\x67\x3e\x0a\
-\x3c\x67\x20\x74\x72\x61\x6e\x73\x66\x6f\x72\x6d\x3d\x27\x6d\x61\
-\x74\x72\x69\x78\x28\x30\x2e\x39\x39\x36\x32\x36\x34\x20\x30\x20\
-\x30\x20\x30\x2e\x39\x39\x36\x32\x36\x34\x20\x35\x38\x2e\x34\x36\
-\x36\x39\x20\x31\x31\x37\x2e\x38\x35\x38\x29\x27\x3e\x0a\x3c\x63\
-\x69\x72\x63\x6c\x65\x20\x63\x78\x3d\x27\x33\x2e\x39\x35\x37\x33\
-\x35\x27\x20\x63\x79\x3d\x27\x2d\x33\x32\x2e\x31\x32\x27\x20\x66\
-\x69\x6c\x6c\x3d\x27\x23\x30\x30\x30\x30\x30\x30\x27\x20\x72\x3d\
-\x27\x36\x2e\x30\x32\x32\x35\x27\x2f\x3e\x0a\x3c\x2f\x67\x3e\x0a\
-\x3c\x67\x20\x74\x72\x61\x6e\x73\x66\x6f\x72\x6d\x3d\x27\x6d\x61\
-\x74\x72\x69\x78\x28\x30\x2e\x39\x39\x36\x32\x36\x34\x20\x30\x20\
-\x30\x20\x30\x2e\x39\x39\x36\x32\x36\x34\x20\x35\x38\x2e\x34\x36\
-\x36\x39\x20\x31\x31\x37\x2e\x38\x35\x38\x29\x27\x3e\x0a\x3c\x63\
-\x69\x72\x63\x6c\x65\x20\x63\x78\x3d\x27\x31\x31\x2e\x39\x30\x33\
-\x36\x27\x20\x63\x79\x3d\x27\x2d\x35\x31\x2e\x33\x30\x33\x39\x27\
-\x20\x66\x69\x6c\x6c\x3d\x27\x23\x30\x30\x30\x30\x30\x30\x27\x20\
-\x72\x3d\x27\x36\x2e\x30\x32\x32\x35\x27\x2f\x3e\x0a\x3c\x2f\x67\
-\x3e\x0a\x3c\x67\x20\x74\x72\x61\x6e\x73\x66\x6f\x72\x6d\x3d\x27\
-\x6d\x61\x74\x72\x69\x78\x28\x30\x2e\x39\x39\x36\x32\x36\x34\x20\
-\x30\x20\x30\x20\x30\x2e\x39\x39\x36\x32\x36\x34\x20\x35\x38\x2e\
-\x34\x36\x36\x39\x20\x31\x31\x37\x2e\x38\x35\x38\x29\x27\x3e\x0a\
-\x3c\x63\x69\x72\x63\x6c\x65\x20\x63\x78\x3d\x27\x35\x36\x2e\x31\
-\x35\x32\x33\x27\x20\x63\x79\x3d\x27\x2d\x34\x32\x2e\x35\x30\x32\
-\x32\x27\x20\x66\x69\x6c\x6c\x3d\x27\x23\x30\x30\x30\x30\x30\x30\
-\x27\x20\x72\x3d\x27\x36\x2e\x30\x32\x32\x35\x27\x2f\x3e\x0a\x3c\
-\x2f\x67\x3e\x0a\x3c\x67\x20\x74\x72\x61\x6e\x73\x66\x6f\x72\x6d\
-\x3d\x27\x6d\x61\x74\x72\x69\x78\x28\x30\x2e\x39\x39\x36\x32\x36\
-\x34\x20\x30\x20\x30\x20\x30\x2e\x39\x39\x36\x32\x36\x34\x20\x35\
-\x38\x2e\x34\x36\x36\x39\x20\x31\x31\x37\x2e\x38\x35\x38\x29\x27\
-\x3e\x0a\x3c\x63\x69\x72\x63\x6c\x65\x20\x63\x78\x3d\x27\x34\x30\
-\x2e\x36\x37\x39\x34\x27\x20\x63\x79\x3d\x27\x2d\x32\x32\x2e\x35\
-\x32\x38\x31\x27\x20\x66\x69\x6c\x6c\x3d\x27\x23\x30\x30\x30\x30\
-\x30\x30\x27\x20\x72\x3d\x27\x36\x2e\x30\x32\x32\x35\x27\x2f\x3e\
-\x0a\x3c\x2f\x67\x3e\x0a\x3c\x2f\x67\x3e\x0a\x3c\x2f\x73\x76\x67\
-\x3e\
+\x3d\x22\x4c\x61\x79\x65\x72\x5f\x31\x22\x20\x78\x6d\x6c\x6e\x73\
+\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\
+\x6f\x72\x67\x2f\x32\x30\x30\x30\x2f\x73\x76\x67\x22\x20\x78\x6d\
+\x6c\x6e\x73\x3a\x78\x6c\x69\x6e\x6b\x3d\x22\x68\x74\x74\x70\x3a\
+\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x31\x39\x39\
+\x39\x2f\x78\x6c\x69\x6e\x6b\x22\x20\x78\x3d\x22\x30\x70\x78\x22\
+\x20\x79\x3d\x22\x30\x70\x78\x22\x0d\x0a\x09\x20\x77\x69\x64\x74\
+\x68\x3d\x22\x35\x31\x32\x70\x78\x22\x20\x68\x65\x69\x67\x68\x74\
+\x3d\x22\x35\x31\x32\x70\x78\x22\x20\x76\x69\x65\x77\x42\x6f\x78\
+\x3d\x22\x30\x20\x30\x20\x35\x31\x32\x20\x35\x31\x32\x22\x20\x65\
+\x6e\x61\x62\x6c\x65\x2d\x62\x61\x63\x6b\x67\x72\x6f\x75\x6e\x64\
+\x3d\x22\x6e\x65\x77\x20\x30\x20\x30\x20\x35\x31\x32\x20\x35\x31\
+\x32\x22\x20\x78\x6d\x6c\x3a\x73\x70\x61\x63\x65\x3d\x22\x70\x72\
+\x65\x73\x65\x72\x76\x65\x22\x3e\x0d\x0a\x3c\x67\x20\x69\x64\x3d\
+\x22\x49\x63\x6f\x6e\x5f\x32\x30\x5f\x22\x3e\x0d\x0a\x09\x3c\x67\
+\x3e\x0d\x0a\x09\x09\x3c\x70\x61\x74\x68\x20\x64\x3d\x22\x4d\x32\
+\x35\x36\x2c\x34\x38\x43\x31\x34\x31\x2e\x36\x30\x31\x2c\x34\x38\
+\x2c\x34\x38\x2c\x31\x34\x31\x2e\x36\x30\x31\x2c\x34\x38\x2c\x32\
+\x35\x36\x73\x39\x33\x2e\x36\x30\x31\x2c\x32\x30\x38\x2c\x32\x30\
+\x38\x2c\x32\x30\x38\x73\x32\x30\x38\x2d\x39\x33\x2e\x36\x30\x31\
+\x2c\x32\x30\x38\x2d\x32\x30\x38\x53\x33\x37\x30\x2e\x33\x39\x39\
+\x2c\x34\x38\x2c\x32\x35\x36\x2c\x34\x38\x7a\x20\x4d\x32\x35\x36\
+\x2c\x34\x32\x32\x2e\x33\x39\x39\x0d\x0a\x09\x09\x09\x63\x2d\x39\
+\x31\x2e\x35\x31\x38\x2c\x30\x2d\x31\x36\x36\x2e\x33\x39\x39\x2d\
+\x37\x34\x2e\x38\x38\x32\x2d\x31\x36\x36\x2e\x33\x39\x39\x2d\x31\
+\x36\x36\x2e\x33\x39\x39\x53\x31\x36\x34\x2e\x34\x38\x32\x2c\x38\
+\x39\x2e\x36\x2c\x32\x35\x36\x2c\x38\x39\x2e\x36\x53\x34\x32\x32\
+\x2e\x34\x2c\x31\x36\x34\x2e\x34\x38\x32\x2c\x34\x32\x32\x2e\x34\
+\x2c\x32\x35\x36\x53\x33\x34\x37\x2e\x35\x31\x38\x2c\x34\x32\x32\
+\x2e\x33\x39\x39\x2c\x32\x35\x36\x2c\x34\x32\x32\x2e\x33\x39\x39\
+\x7a\x22\x2f\x3e\x0d\x0a\x09\x3c\x2f\x67\x3e\x0d\x0a\x3c\x2f\x67\
+\x3e\x0d\x0a\x3c\x2f\x73\x76\x67\x3e\x0d\x0a\
 \x00\x00\x02\x7d\
 \x3c\
 \x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\
@@ -1128,13 +829,13 @@
 \x32\x22\x20\x78\x6d\x6c\x3a\x73\x70\x61\x63\x65\x3d\x22\x70\x72\
 \x65\x73\x65\x72\x76\x65\x22\x3e\x0d\x0a\x3c\x67\x20\x69\x64\x3d\
 \x22\x49\x63\x6f\x6e\x5f\x38\x5f\x22\x3e\x0d\x0a\x09\x3c\x67\x3e\
-\x0d\x0a\x09\x09\x3c\x70\x61\x74\x68\x20\x64\x3d\x22\x4d\x34\x32\
-\x37\x2c\x32\x33\x34\x2e\x36\x32\x35\x48\x31\x36\x37\x2e\x32\x39\
-\x36\x6c\x31\x31\x39\x2e\x37\x30\x32\x2d\x31\x31\x39\x2e\x37\x30\
-\x32\x4c\x32\x35\x36\x2c\x38\x35\x4c\x38\x35\x2c\x32\x35\x36\x6c\
-\x31\x37\x31\x2c\x31\x37\x31\x6c\x32\x39\x2e\x39\x32\x32\x2d\x32\
-\x39\x2e\x39\x32\x34\x4c\x31\x36\x37\x2e\x32\x39\x36\x2c\x32\x37\
-\x37\x2e\x33\x37\x35\x48\x34\x32\x37\x56\x32\x33\x34\x2e\x36\x32\
+\x0d\x0a\x09\x09\x3c\x70\x61\x74\x68\x20\x64\x3d\x22\x4d\x38\x35\
+\x2c\x32\x37\x37\x2e\x33\x37\x35\x68\x32\x35\x39\x2e\x37\x30\x34\
+\x4c\x32\x32\x35\x2e\x30\x30\x32\x2c\x33\x39\x37\x2e\x30\x37\x37\
+\x4c\x32\x35\x36\x2c\x34\x32\x37\x6c\x31\x37\x31\x2d\x31\x37\x31\
+\x4c\x32\x35\x36\x2c\x38\x35\x6c\x2d\x32\x39\x2e\x39\x32\x32\x2c\
+\x32\x39\x2e\x39\x32\x34\x6c\x31\x31\x38\x2e\x36\x32\x36\x2c\x31\
+\x31\x39\x2e\x37\x30\x31\x48\x38\x35\x56\x32\x37\x37\x2e\x33\x37\
 \x35\x7a\x22\x2f\x3e\x0d\x0a\x09\x3c\x2f\x67\x3e\x0d\x0a\x3c\x2f\
 \x67\x3e\x0d\x0a\x3c\x2f\x73\x76\x67\x3e\x0d\x0a\
 \x00\x00\x02\xf7\
@@ -1187,7 +888,7 @@
 \x33\x38\x2e\x33\x2c\x34\x33\x34\x2e\x33\x2c\x32\x32\x34\x2c\x34\
 \x31\x37\x2e\x34\x2c\x32\x32\x34\x7a\x22\x2f\x3e\x0d\x0a\x3c\x2f\
 \x73\x76\x67\x3e\x0d\x0a\
-\x00\x00\x02\xb7\
+\x00\x00\x03\x26\
 \x3c\
 \x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\
 \x30\x22\x20\x65\x6e\x63\x6f\x64\x69\x6e\x67\x3d\x22\x75\x74\x66\
@@ -1218,21 +919,28 @@
 \x6e\x61\x62\x6c\x65\x2d\x62\x61\x63\x6b\x67\x72\x6f\x75\x6e\x64\
 \x3d\x22\x6e\x65\x77\x20\x30\x20\x30\x20\x35\x31\x32\x20\x35\x31\
 \x32\x22\x20\x78\x6d\x6c\x3a\x73\x70\x61\x63\x65\x3d\x22\x70\x72\
-\x65\x73\x65\x72\x76\x65\x22\x3e\x0d\x0a\x3c\x67\x20\x69\x64\x3d\
-\x22\x49\x63\x6f\x6e\x5f\x35\x5f\x22\x3e\x0d\x0a\x09\x3c\x67\x3e\
-\x0d\x0a\x09\x09\x3c\x70\x6f\x6c\x79\x67\x6f\x6e\x20\x70\x6f\x69\
-\x6e\x74\x73\x3d\x22\x34\x30\x35\x2c\x31\x33\x36\x2e\x37\x39\x38\
-\x20\x33\x37\x35\x2e\x32\x30\x32\x2c\x31\x30\x37\x20\x32\x35\x36\
-\x2c\x32\x32\x36\x2e\x32\x30\x32\x20\x31\x33\x36\x2e\x37\x39\x38\
-\x2c\x31\x30\x37\x20\x31\x30\x37\x2c\x31\x33\x36\x2e\x37\x39\x38\
-\x20\x32\x32\x36\x2e\x32\x30\x32\x2c\x32\x35\x36\x20\x31\x30\x37\
-\x2c\x33\x37\x35\x2e\x32\x30\x32\x20\x31\x33\x36\x2e\x37\x39\x38\
-\x2c\x34\x30\x35\x20\x32\x35\x36\x2c\x32\x38\x35\x2e\x37\x39\x38\
-\x20\x0d\x0a\x09\x09\x09\x33\x37\x35\x2e\x32\x30\x32\x2c\x34\x30\
-\x35\x20\x34\x30\x35\x2c\x33\x37\x35\x2e\x32\x30\x32\x20\x32\x38\
-\x35\x2e\x37\x39\x38\x2c\x32\x35\x36\x20\x09\x09\x22\x2f\x3e\x0d\
-\x0a\x09\x3c\x2f\x67\x3e\x0d\x0a\x3c\x2f\x67\x3e\x0d\x0a\x3c\x2f\
-\x73\x76\x67\x3e\x0d\x0a\
+\x65\x73\x65\x72\x76\x65\x22\x3e\x0d\x0a\x3c\x67\x3e\x0d\x0a\x09\
+\x3c\x70\x61\x74\x68\x20\x64\x3d\x22\x4d\x32\x35\x36\x2c\x33\x38\
+\x38\x63\x2d\x37\x32\x2e\x35\x39\x37\x2c\x30\x2d\x31\x33\x32\x2d\
+\x35\x39\x2e\x34\x30\x35\x2d\x31\x33\x32\x2d\x31\x33\x32\x63\x30\
+\x2d\x37\x32\x2e\x36\x30\x31\x2c\x35\x39\x2e\x34\x30\x33\x2d\x31\
+\x33\x32\x2c\x31\x33\x32\x2d\x31\x33\x32\x63\x33\x36\x2e\x33\x2c\
+\x30\x2c\x36\x39\x2e\x32\x39\x39\x2c\x31\x35\x2e\x34\x2c\x39\x32\
+\x2e\x34\x30\x36\x2c\x33\x39\x2e\x36\x30\x31\x4c\x32\x37\x38\x2c\
+\x32\x33\x34\x68\x31\x35\x34\x56\x38\x30\x0d\x0a\x09\x09\x6c\x2d\
+\x35\x31\x2e\x36\x39\x38\x2c\x35\x31\x2e\x37\x30\x32\x43\x33\x34\
+\x38\x2e\x34\x30\x36\x2c\x39\x39\x2e\x37\x39\x38\x2c\x33\x30\x34\
+\x2e\x34\x30\x36\x2c\x38\x30\x2c\x32\x35\x36\x2c\x38\x30\x63\x2d\
+\x39\x36\x2e\x37\x39\x37\x2c\x30\x2d\x31\x37\x36\x2c\x37\x39\x2e\
+\x32\x30\x33\x2d\x31\x37\x36\x2c\x31\x37\x36\x73\x37\x38\x2e\x30\
+\x39\x34\x2c\x31\x37\x36\x2c\x31\x37\x36\x2c\x31\x37\x36\x0d\x0a\
+\x09\x09\x63\x38\x31\x2e\x30\x34\x35\x2c\x30\x2c\x31\x34\x38\x2e\
+\x32\x38\x37\x2d\x35\x34\x2e\x31\x33\x34\x2c\x31\x36\x39\x2e\x34\
+\x30\x31\x2d\x31\x32\x38\x48\x33\x37\x38\x2e\x38\x35\x43\x33\x36\
+\x30\x2e\x31\x30\x35\x2c\x33\x35\x33\x2e\x35\x36\x31\x2c\x33\x31\
+\x31\x2e\x37\x31\x32\x2c\x33\x38\x38\x2c\x32\x35\x36\x2c\x33\x38\
+\x38\x7a\x22\x2f\x3e\x0d\x0a\x3c\x2f\x67\x3e\x0d\x0a\x3c\x2f\x73\
+\x76\x67\x3e\x0d\x0a\
 \x00\x00\x02\xf2\
 \x3c\
 \x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\
@@ -1283,7 +991,7 @@
 \x35\x39\x39\x2c\x31\x30\x2c\x31\x37\x2e\x35\x39\x39\x7a\x22\x2f\
 \x3e\x0d\x0a\x3c\x2f\x67\x3e\x0d\x0a\x3c\x2f\x73\x76\x67\x3e\x0d\
 \x0a\
-\x00\x00\x03\x36\
+\x00\x00\x02\x7d\
 \x3c\
 \x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\
 \x30\x22\x20\x65\x6e\x63\x6f\x64\x69\x6e\x67\x3d\x22\x75\x74\x66\
@@ -1314,106 +1022,24 @@
 \x6e\x61\x62\x6c\x65\x2d\x62\x61\x63\x6b\x67\x72\x6f\x75\x6e\x64\
 \x3d\x22\x6e\x65\x77\x20\x30\x20\x30\x20\x35\x31\x32\x20\x35\x31\
 \x32\x22\x20\x78\x6d\x6c\x3a\x73\x70\x61\x63\x65\x3d\x22\x70\x72\
-\x65\x73\x65\x72\x76\x65\x22\x3e\x0d\x0a\x3c\x67\x3e\x0d\x0a\x09\
-\x3c\x70\x6f\x6c\x79\x67\x6f\x6e\x20\x70\x6f\x69\x6e\x74\x73\x3d\
-\x22\x33\x39\x36\x2e\x37\x39\x35\x2c\x33\x39\x36\x2e\x38\x20\x33\
-\x32\x30\x2c\x33\x39\x36\x2e\x38\x20\x33\x32\x30\x2c\x34\x34\x38\
-\x20\x34\x34\x38\x2c\x34\x34\x38\x20\x34\x34\x38\x2c\x33\x32\x30\
-\x20\x33\x39\x36\x2e\x37\x39\x35\x2c\x33\x32\x30\x20\x09\x22\x2f\
-\x3e\x0d\x0a\x09\x3c\x70\x6f\x6c\x79\x67\x6f\x6e\x20\x70\x6f\x69\
-\x6e\x74\x73\x3d\x22\x33\x39\x36\x2e\x38\x2c\x31\x31\x35\x2e\x32\
-\x30\x35\x20\x33\x39\x36\x2e\x38\x2c\x31\x39\x32\x20\x34\x34\x38\
-\x2c\x31\x39\x32\x20\x34\x34\x38\x2c\x36\x34\x20\x33\x32\x30\x2c\
-\x36\x34\x20\x33\x32\x30\x2c\x31\x31\x35\x2e\x32\x30\x35\x20\x09\
-\x22\x2f\x3e\x0d\x0a\x09\x3c\x70\x6f\x6c\x79\x67\x6f\x6e\x20\x70\
-\x6f\x69\x6e\x74\x73\x3d\x22\x31\x31\x35\x2e\x32\x30\x35\x2c\x31\
-\x31\x35\x2e\x32\x20\x31\x39\x32\x2c\x31\x31\x35\x2e\x32\x20\x31\
-\x39\x32\x2c\x36\x34\x20\x36\x34\x2c\x36\x34\x20\x36\x34\x2c\x31\
-\x39\x32\x20\x31\x31\x35\x2e\x32\x30\x35\x2c\x31\x39\x32\x20\x09\
-\x22\x2f\x3e\x0d\x0a\x09\x3c\x70\x6f\x6c\x79\x67\x6f\x6e\x20\x70\
-\x6f\x69\x6e\x74\x73\x3d\x22\x31\x31\x35\x2e\x32\x2c\x33\x39\x36\
-\x2e\x37\x39\x35\x20\x31\x31\x35\x2e\x32\x2c\x33\x32\x30\x20\x36\
-\x34\x2c\x33\x32\x30\x20\x36\x34\x2c\x34\x34\x38\x20\x31\x39\x32\
-\x2c\x34\x34\x38\x20\x31\x39\x32\x2c\x33\x39\x36\x2e\x37\x39\x35\
-\x20\x09\x22\x2f\x3e\x0d\x0a\x3c\x2f\x67\x3e\x0d\x0a\x3c\x2f\x73\
-\x76\x67\x3e\x0d\x0a\
-\x00\x00\x04\x3d\
+\x65\x73\x65\x72\x76\x65\x22\x3e\x0d\x0a\x3c\x67\x20\x69\x64\x3d\
+\x22\x49\x63\x6f\x6e\x5f\x38\x5f\x22\x3e\x0d\x0a\x09\x3c\x67\x3e\
+\x0d\x0a\x09\x09\x3c\x70\x61\x74\x68\x20\x64\x3d\x22\x4d\x34\x32\
+\x37\x2c\x32\x33\x34\x2e\x36\x32\x35\x48\x31\x36\x37\x2e\x32\x39\
+\x36\x6c\x31\x31\x39\x2e\x37\x30\x32\x2d\x31\x31\x39\x2e\x37\x30\
+\x32\x4c\x32\x35\x36\x2c\x38\x35\x4c\x38\x35\x2c\x32\x35\x36\x6c\
+\x31\x37\x31\x2c\x31\x37\x31\x6c\x32\x39\x2e\x39\x32\x32\x2d\x32\
+\x39\x2e\x39\x32\x34\x4c\x31\x36\x37\x2e\x32\x39\x36\x2c\x32\x37\
+\x37\x2e\x33\x37\x35\x48\x34\x32\x37\x56\x32\x33\x34\x2e\x36\x32\
+\x35\x7a\x22\x2f\x3e\x0d\x0a\x09\x3c\x2f\x67\x3e\x0d\x0a\x3c\x2f\
+\x67\x3e\x0d\x0a\x3c\x2f\x73\x76\x67\x3e\x0d\x0a\
+\x00\x00\x03\x0c\
 \x3c\
-\x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x27\x31\x2e\
-\x30\x27\x20\x65\x6e\x63\x6f\x64\x69\x6e\x67\x3d\x27\x55\x54\x46\
-\x2d\x38\x27\x3f\x3e\x0a\x3c\x21\x2d\x2d\x20\x54\x68\x69\x73\x20\
-\x66\x69\x6c\x65\x20\x77\x61\x73\x20\x67\x65\x6e\x65\x72\x61\x74\
-\x65\x64\x20\x62\x79\x20\x64\x76\x69\x73\x76\x67\x6d\x20\x32\x2e\
-\x38\x20\x2d\x2d\x3e\x0a\x3c\x73\x76\x67\x20\x76\x65\x72\x73\x69\
-\x6f\x6e\x3d\x27\x31\x2e\x31\x27\x20\x78\x6d\x6c\x6e\x73\x3d\x27\
-\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\
-\x67\x2f\x32\x30\x30\x30\x2f\x73\x76\x67\x27\x20\x78\x6d\x6c\x6e\
-\x73\x3a\x78\x6c\x69\x6e\x6b\x3d\x27\x68\x74\x74\x70\x3a\x2f\x2f\
-\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x31\x39\x39\x39\x2f\
-\x78\x6c\x69\x6e\x6b\x27\x20\x77\x69\x64\x74\x68\x3d\x27\x36\x33\
-\x2e\x39\x39\x39\x36\x70\x74\x27\x20\x68\x65\x69\x67\x68\x74\x3d\
-\x27\x36\x33\x2e\x39\x39\x39\x37\x70\x74\x27\x20\x76\x69\x65\x77\
-\x42\x6f\x78\x3d\x27\x35\x36\x2e\x34\x30\x39\x34\x20\x35\x33\x2e\
-\x38\x35\x38\x33\x20\x36\x33\x2e\x39\x39\x39\x36\x20\x36\x33\x2e\
-\x39\x39\x39\x37\x27\x3e\x0a\x3c\x67\x20\x69\x64\x3d\x27\x70\x61\
-\x67\x65\x31\x27\x3e\x0a\x3c\x67\x20\x74\x72\x61\x6e\x73\x66\x6f\
-\x72\x6d\x3d\x27\x6d\x61\x74\x72\x69\x78\x28\x30\x2e\x39\x39\x36\
-\x32\x36\x34\x20\x30\x20\x30\x20\x30\x2e\x39\x39\x36\x32\x36\x34\
-\x20\x35\x38\x2e\x34\x36\x36\x39\x20\x31\x31\x37\x2e\x38\x35\x38\
-\x29\x27\x3e\x0a\x3c\x70\x61\x74\x68\x20\x64\x3d\x27\x4d\x20\x33\
-\x2e\x39\x35\x37\x33\x35\x20\x2d\x33\x32\x2e\x31\x32\x4c\x20\x31\
-\x31\x2e\x39\x30\x33\x36\x20\x2d\x35\x31\x2e\x33\x30\x33\x39\x4c\
-\x20\x35\x36\x2e\x31\x35\x32\x33\x20\x2d\x34\x32\x2e\x35\x30\x32\
-\x32\x4c\x20\x34\x30\x2e\x36\x37\x39\x34\x20\x2d\x32\x32\x2e\x35\
-\x32\x38\x31\x27\x20\x66\x69\x6c\x6c\x3d\x27\x6e\x6f\x6e\x65\x27\
-\x20\x73\x74\x72\x6f\x6b\x65\x3d\x27\x23\x30\x30\x30\x30\x30\x30\
-\x27\x20\x73\x74\x72\x6f\x6b\x65\x2d\x6c\x69\x6e\x65\x63\x61\x70\
-\x3d\x27\x72\x6f\x75\x6e\x64\x27\x20\x73\x74\x72\x6f\x6b\x65\x2d\
-\x6c\x69\x6e\x65\x6a\x6f\x69\x6e\x3d\x27\x72\x6f\x75\x6e\x64\x27\
-\x20\x73\x74\x72\x6f\x6b\x65\x2d\x6d\x69\x74\x65\x72\x6c\x69\x6d\
-\x69\x74\x3d\x27\x31\x30\x2e\x30\x33\x37\x35\x27\x20\x73\x74\x72\
-\x6f\x6b\x65\x2d\x77\x69\x64\x74\x68\x3d\x27\x32\x2e\x35\x30\x39\
-\x33\x37\x27\x2f\x3e\x0a\x3c\x2f\x67\x3e\x0a\x3c\x67\x20\x74\x72\
-\x61\x6e\x73\x66\x6f\x72\x6d\x3d\x27\x6d\x61\x74\x72\x69\x78\x28\
-\x30\x2e\x39\x39\x36\x32\x36\x34\x20\x30\x20\x30\x20\x30\x2e\x39\
-\x39\x36\x32\x36\x34\x20\x35\x38\x2e\x34\x36\x36\x39\x20\x31\x31\
-\x37\x2e\x38\x35\x38\x29\x27\x3e\x0a\x3c\x63\x69\x72\x63\x6c\x65\
-\x20\x63\x78\x3d\x27\x33\x2e\x39\x35\x37\x33\x35\x27\x20\x63\x79\
-\x3d\x27\x2d\x33\x32\x2e\x31\x32\x27\x20\x66\x69\x6c\x6c\x3d\x27\
-\x23\x30\x30\x30\x30\x30\x30\x27\x20\x72\x3d\x27\x36\x2e\x30\x32\
-\x32\x35\x27\x2f\x3e\x0a\x3c\x2f\x67\x3e\x0a\x3c\x67\x20\x74\x72\
-\x61\x6e\x73\x66\x6f\x72\x6d\x3d\x27\x6d\x61\x74\x72\x69\x78\x28\
-\x30\x2e\x39\x39\x36\x32\x36\x34\x20\x30\x20\x30\x20\x30\x2e\x39\
-\x39\x36\x32\x36\x34\x20\x35\x38\x2e\x34\x36\x36\x39\x20\x31\x31\
-\x37\x2e\x38\x35\x38\x29\x27\x3e\x0a\x3c\x63\x69\x72\x63\x6c\x65\
-\x20\x63\x78\x3d\x27\x31\x31\x2e\x39\x30\x33\x36\x27\x20\x63\x79\
-\x3d\x27\x2d\x35\x31\x2e\x33\x30\x33\x39\x27\x20\x66\x69\x6c\x6c\
-\x3d\x27\x23\x30\x30\x30\x30\x30\x30\x27\x20\x72\x3d\x27\x36\x2e\
-\x30\x32\x32\x35\x27\x2f\x3e\x0a\x3c\x2f\x67\x3e\x0a\x3c\x67\x20\
-\x74\x72\x61\x6e\x73\x66\x6f\x72\x6d\x3d\x27\x6d\x61\x74\x72\x69\
-\x78\x28\x30\x2e\x39\x39\x36\x32\x36\x34\x20\x30\x20\x30\x20\x30\
-\x2e\x39\x39\x36\x32\x36\x34\x20\x35\x38\x2e\x34\x36\x36\x39\x20\
-\x31\x31\x37\x2e\x38\x35\x38\x29\x27\x3e\x0a\x3c\x63\x69\x72\x63\
-\x6c\x65\x20\x63\x78\x3d\x27\x35\x36\x2e\x31\x35\x32\x33\x27\x20\
-\x63\x79\x3d\x27\x2d\x34\x32\x2e\x35\x30\x32\x32\x27\x20\x66\x69\
-\x6c\x6c\x3d\x27\x23\x30\x30\x30\x30\x30\x30\x27\x20\x72\x3d\x27\
-\x36\x2e\x30\x32\x32\x35\x27\x2f\x3e\x0a\x3c\x2f\x67\x3e\x0a\x3c\
-\x67\x20\x74\x72\x61\x6e\x73\x66\x6f\x72\x6d\x3d\x27\x6d\x61\x74\
-\x72\x69\x78\x28\x30\x2e\x39\x39\x36\x32\x36\x34\x20\x30\x20\x30\
-\x20\x30\x2e\x39\x39\x36\x32\x36\x34\x20\x35\x38\x2e\x34\x36\x36\
-\x39\x20\x31\x31\x37\x2e\x38\x35\x38\x29\x27\x3e\x0a\x3c\x63\x69\
-\x72\x63\x6c\x65\x20\x63\x78\x3d\x27\x34\x30\x2e\x36\x37\x39\x34\
-\x27\x20\x63\x79\x3d\x27\x2d\x32\x32\x2e\x35\x32\x38\x31\x27\x20\
-\x66\x69\x6c\x6c\x3d\x27\x23\x30\x30\x30\x30\x30\x30\x27\x20\x72\
-\x3d\x27\x36\x2e\x30\x32\x32\x35\x27\x2f\x3e\x0a\x3c\x2f\x67\x3e\
-\x0a\x3c\x2f\x67\x3e\x0a\x3c\x2f\x73\x76\x67\x3e\
-\x00\x00\x03\x52\
-\x3c\
 \x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\
 \x30\x22\x20\x65\x6e\x63\x6f\x64\x69\x6e\x67\x3d\x22\x75\x74\x66\
 \x2d\x38\x22\x3f\x3e\x0d\x0a\x3c\x21\x2d\x2d\x20\x47\x65\x6e\x65\
 \x72\x61\x74\x6f\x72\x3a\x20\x41\x64\x6f\x62\x65\x20\x49\x6c\x6c\
-\x75\x73\x74\x72\x61\x74\x6f\x72\x20\x31\x36\x2e\x32\x2e\x31\x2c\
+\x75\x73\x74\x72\x61\x74\x6f\x72\x20\x31\x38\x2e\x31\x2e\x30\x2c\
 \x20\x53\x56\x47\x20\x45\x78\x70\x6f\x72\x74\x20\x50\x6c\x75\x67\
 \x2d\x49\x6e\x20\x2e\x20\x53\x56\x47\x20\x56\x65\x72\x73\x69\x6f\
 \x6e\x3a\x20\x36\x2e\x30\x30\x20\x42\x75\x69\x6c\x64\x20\x30\x29\
@@ -1425,184 +1051,55 @@
 \x73\x2f\x53\x56\x47\x2f\x31\x2e\x31\x2f\x44\x54\x44\x2f\x73\x76\
 \x67\x31\x31\x2e\x64\x74\x64\x22\x3e\x0d\x0a\x3c\x73\x76\x67\x20\
 \x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\x31\x22\x20\x69\x64\
-\x3d\x22\x4c\x61\x79\x65\x72\x5f\x31\x22\x20\x78\x6d\x6c\x6e\x73\
-\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\
-\x6f\x72\x67\x2f\x32\x30\x30\x30\x2f\x73\x76\x67\x22\x20\x78\x6d\
-\x6c\x6e\x73\x3a\x78\x6c\x69\x6e\x6b\x3d\x22\x68\x74\x74\x70\x3a\
-\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x31\x39\x39\
-\x39\x2f\x78\x6c\x69\x6e\x6b\x22\x20\x78\x3d\x22\x30\x70\x78\x22\
-\x20\x79\x3d\x22\x30\x70\x78\x22\x0d\x0a\x09\x20\x77\x69\x64\x74\
-\x68\x3d\x22\x35\x31\x32\x70\x78\x22\x20\x68\x65\x69\x67\x68\x74\
-\x3d\x22\x35\x31\x32\x70\x78\x22\x20\x76\x69\x65\x77\x42\x6f\x78\
-\x3d\x22\x30\x20\x30\x20\x35\x31\x32\x20\x35\x31\x32\x22\x20\x65\
-\x6e\x61\x62\x6c\x65\x2d\x62\x61\x63\x6b\x67\x72\x6f\x75\x6e\x64\
-\x3d\x22\x6e\x65\x77\x20\x30\x20\x30\x20\x35\x31\x32\x20\x35\x31\
-\x32\x22\x20\x78\x6d\x6c\x3a\x73\x70\x61\x63\x65\x3d\x22\x70\x72\
-\x65\x73\x65\x72\x76\x65\x22\x3e\x0d\x0a\x3c\x70\x61\x74\x68\x20\
-\x64\x3d\x22\x4d\x34\x33\x37\x2e\x33\x33\x34\x2c\x31\x34\x34\x48\
-\x32\x35\x36\x2e\x30\x30\x36\x6c\x2d\x34\x32\x2e\x36\x36\x38\x2d\
-\x34\x38\x48\x37\x34\x2e\x36\x36\x36\x43\x35\x31\x2e\x31\x39\x37\
-\x2c\x39\x36\x2c\x33\x32\x2c\x31\x31\x35\x2e\x31\x39\x38\x2c\x33\
-\x32\x2c\x31\x33\x38\x2e\x36\x36\x37\x76\x32\x33\x34\x2e\x36\x36\
-\x36\x43\x33\x32\x2c\x33\x39\x36\x2e\x38\x30\x32\x2c\x35\x31\x2e\
-\x31\x39\x37\x2c\x34\x31\x36\x2c\x37\x34\x2e\x36\x36\x36\x2c\x34\
-\x31\x36\x68\x33\x36\x32\x2e\x36\x36\x38\x0d\x0a\x09\x43\x34\x36\
-\x30\x2e\x38\x30\x33\x2c\x34\x31\x36\x2c\x34\x38\x30\x2c\x33\x39\
-\x36\x2e\x38\x30\x32\x2c\x34\x38\x30\x2c\x33\x37\x33\x2e\x33\x33\
-\x33\x56\x31\x38\x36\x2e\x36\x36\x37\x43\x34\x38\x30\x2c\x31\x36\
-\x33\x2e\x31\x39\x38\x2c\x34\x36\x30\x2e\x38\x30\x33\x2c\x31\x34\
-\x34\x2c\x34\x33\x37\x2e\x33\x33\x34\x2c\x31\x34\x34\x7a\x20\x4d\
-\x34\x34\x38\x2c\x33\x37\x33\x2e\x33\x33\x33\x0d\x0a\x09\x63\x30\
-\x2c\x35\x2e\x37\x38\x32\x2d\x34\x2e\x38\x38\x35\x2c\x31\x30\x2e\
-\x36\x36\x37\x2d\x31\x30\x2e\x36\x36\x36\x2c\x31\x30\x2e\x36\x36\
-\x37\x48\x37\x34\x2e\x36\x36\x36\x43\x36\x38\x2e\x38\x38\x34\x2c\
-\x33\x38\x34\x2c\x36\x34\x2c\x33\x37\x39\x2e\x31\x31\x35\x2c\x36\
-\x34\x2c\x33\x37\x33\x2e\x33\x33\x33\x56\x31\x37\x36\x68\x33\x37\
-\x33\x2e\x33\x33\x34\x63\x35\x2e\x37\x38\x31\x2c\x30\x2c\x31\x30\
-\x2e\x36\x36\x36\x2c\x34\x2e\x38\x38\x35\x2c\x31\x30\x2e\x36\x36\
-\x36\x2c\x31\x30\x2e\x36\x36\x37\x0d\x0a\x09\x56\x33\x37\x33\x2e\
-\x33\x33\x33\x7a\x22\x2f\x3e\x0d\x0a\x3c\x2f\x73\x76\x67\x3e\x0d\
-\x0a\
-\x00\x00\x04\xd5\
-\x3c\
-\x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x27\x31\x2e\
-\x30\x27\x20\x65\x6e\x63\x6f\x64\x69\x6e\x67\x3d\x27\x55\x54\x46\
-\x2d\x38\x27\x3f\x3e\x0a\x3c\x21\x2d\x2d\x20\x54\x68\x69\x73\x20\
-\x66\x69\x6c\x65\x20\x77\x61\x73\x20\x67\x65\x6e\x65\x72\x61\x74\
-\x65\x64\x20\x62\x79\x20\x64\x76\x69\x73\x76\x67\x6d\x20\x32\x2e\
-\x38\x20\x2d\x2d\x3e\x0a\x3c\x73\x76\x67\x20\x76\x65\x72\x73\x69\
-\x6f\x6e\x3d\x27\x31\x2e\x31\x27\x20\x78\x6d\x6c\x6e\x73\x3d\x27\
+\x3d\x22\x43\x68\x65\x63\x6b\x22\x20\x78\x6d\x6c\x6e\x73\x3d\x22\
 \x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\
-\x67\x2f\x32\x30\x30\x30\x2f\x73\x76\x67\x27\x20\x78\x6d\x6c\x6e\
-\x73\x3a\x78\x6c\x69\x6e\x6b\x3d\x27\x68\x74\x74\x70\x3a\x2f\x2f\
+\x67\x2f\x32\x30\x30\x30\x2f\x73\x76\x67\x22\x20\x78\x6d\x6c\x6e\
+\x73\x3a\x78\x6c\x69\x6e\x6b\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\
 \x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x31\x39\x39\x39\x2f\
-\x78\x6c\x69\x6e\x6b\x27\x20\x77\x69\x64\x74\x68\x3d\x27\x36\x33\
-\x2e\x39\x39\x39\x36\x70\x74\x27\x20\x68\x65\x69\x67\x68\x74\x3d\
-\x27\x36\x33\x2e\x39\x39\x39\x37\x70\x74\x27\x20\x76\x69\x65\x77\
-\x42\x6f\x78\x3d\x27\x35\x36\x2e\x34\x30\x39\x34\x20\x35\x33\x2e\
-\x38\x35\x38\x33\x20\x36\x33\x2e\x39\x39\x39\x36\x20\x36\x33\x2e\
-\x39\x39\x39\x37\x27\x3e\x0a\x3c\x67\x20\x69\x64\x3d\x27\x70\x61\
-\x67\x65\x31\x27\x3e\x0a\x3c\x67\x20\x74\x72\x61\x6e\x73\x66\x6f\
-\x72\x6d\x3d\x27\x6d\x61\x74\x72\x69\x78\x28\x30\x2e\x39\x39\x36\
-\x32\x36\x34\x20\x30\x20\x30\x20\x30\x2e\x39\x39\x36\x32\x36\x34\
-\x20\x35\x38\x2e\x34\x36\x36\x39\x20\x31\x31\x37\x2e\x38\x35\x38\
-\x29\x27\x3e\x0a\x3c\x70\x61\x74\x68\x20\x64\x3d\x27\x4d\x20\x33\
-\x2e\x39\x35\x37\x33\x35\x20\x2d\x33\x32\x2e\x31\x32\x43\x20\x32\
-\x2e\x32\x38\x39\x32\x32\x20\x2d\x33\x39\x2e\x33\x31\x31\x33\x20\
-\x36\x2e\x33\x36\x37\x30\x32\x20\x2d\x34\x36\x2e\x32\x33\x38\x36\
-\x20\x31\x31\x2e\x39\x30\x33\x36\x20\x2d\x35\x31\x2e\x33\x30\x33\
-\x39\x43\x20\x32\x39\x2e\x36\x36\x38\x37\x20\x2d\x36\x37\x2e\x35\
-\x35\x36\x38\x20\x35\x35\x2e\x32\x32\x39\x32\x20\x2d\x36\x30\x2e\
-\x36\x34\x32\x20\x35\x36\x2e\x31\x35\x32\x33\x20\x2d\x34\x32\x2e\
-\x35\x30\x32\x32\x43\x20\x35\x36\x2e\x36\x31\x33\x36\x20\x2d\x33\
-\x33\x2e\x34\x33\x38\x31\x20\x34\x39\x2e\x31\x31\x33\x32\x20\x2d\
-\x32\x36\x2e\x35\x39\x35\x39\x20\x34\x30\x2e\x36\x37\x39\x34\x20\
-\x2d\x32\x32\x2e\x35\x32\x38\x31\x43\x20\x32\x35\x2e\x33\x39\x39\
-\x35\x20\x2d\x31\x35\x2e\x31\x35\x38\x32\x20\x37\x2e\x31\x39\x39\
-\x33\x35\x20\x2d\x31\x38\x2e\x31\x34\x33\x36\x20\x33\x2e\x39\x35\
-\x37\x33\x35\x20\x2d\x33\x32\x2e\x31\x32\x5a\x27\x20\x66\x69\x6c\
-\x6c\x3d\x27\x6e\x6f\x6e\x65\x27\x20\x73\x74\x72\x6f\x6b\x65\x3d\
-\x27\x23\x30\x30\x30\x30\x30\x30\x27\x20\x73\x74\x72\x6f\x6b\x65\
-\x2d\x6c\x69\x6e\x65\x63\x61\x70\x3d\x27\x72\x6f\x75\x6e\x64\x27\
-\x20\x73\x74\x72\x6f\x6b\x65\x2d\x6c\x69\x6e\x65\x6a\x6f\x69\x6e\
-\x3d\x27\x72\x6f\x75\x6e\x64\x27\x20\x73\x74\x72\x6f\x6b\x65\x2d\
-\x6d\x69\x74\x65\x72\x6c\x69\x6d\x69\x74\x3d\x27\x31\x30\x2e\x30\
-\x33\x37\x35\x27\x20\x73\x74\x72\x6f\x6b\x65\x2d\x77\x69\x64\x74\
-\x68\x3d\x27\x32\x2e\x35\x30\x39\x33\x37\x27\x2f\x3e\x0a\x3c\x2f\
-\x67\x3e\x0a\x3c\x67\x20\x74\x72\x61\x6e\x73\x66\x6f\x72\x6d\x3d\
-\x27\x6d\x61\x74\x72\x69\x78\x28\x30\x2e\x39\x39\x36\x32\x36\x34\
-\x20\x30\x20\x30\x20\x30\x2e\x39\x39\x36\x32\x36\x34\x20\x35\x38\
-\x2e\x34\x36\x36\x39\x20\x31\x31\x37\x2e\x38\x35\x38\x29\x27\x3e\
-\x0a\x3c\x63\x69\x72\x63\x6c\x65\x20\x63\x78\x3d\x27\x33\x2e\x39\
-\x35\x37\x33\x35\x27\x20\x63\x79\x3d\x27\x2d\x33\x32\x2e\x31\x32\
-\x27\x20\x66\x69\x6c\x6c\x3d\x27\x23\x30\x30\x30\x30\x30\x30\x27\
-\x20\x72\x3d\x27\x36\x2e\x30\x32\x32\x35\x27\x2f\x3e\x0a\x3c\x2f\
-\x67\x3e\x0a\x3c\x67\x20\x74\x72\x61\x6e\x73\x66\x6f\x72\x6d\x3d\
-\x27\x6d\x61\x74\x72\x69\x78\x28\x30\x2e\x39\x39\x36\x32\x36\x34\
-\x20\x30\x20\x30\x20\x30\x2e\x39\x39\x36\x32\x36\x34\x20\x35\x38\
-\x2e\x34\x36\x36\x39\x20\x31\x31\x37\x2e\x38\x35\x38\x29\x27\x3e\
-\x0a\x3c\x63\x69\x72\x63\x6c\x65\x20\x63\x78\x3d\x27\x31\x31\x2e\
-\x39\x30\x33\x36\x27\x20\x63\x79\x3d\x27\x2d\x35\x31\x2e\x33\x30\
-\x33\x39\x27\x20\x66\x69\x6c\x6c\x3d\x27\x23\x30\x30\x30\x30\x30\
-\x30\x27\x20\x72\x3d\x27\x36\x2e\x30\x32\x32\x35\x27\x2f\x3e\x0a\
-\x3c\x2f\x67\x3e\x0a\x3c\x67\x20\x74\x72\x61\x6e\x73\x66\x6f\x72\
-\x6d\x3d\x27\x6d\x61\x74\x72\x69\x78\x28\x30\x2e\x39\x39\x36\x32\
-\x36\x34\x20\x30\x20\x30\x20\x30\x2e\x39\x39\x36\x32\x36\x34\x20\
-\x35\x38\x2e\x34\x36\x36\x39\x20\x31\x31\x37\x2e\x38\x35\x38\x29\
-\x27\x3e\x0a\x3c\x63\x69\x72\x63\x6c\x65\x20\x63\x78\x3d\x27\x35\
-\x36\x2e\x31\x35\x32\x33\x27\x20\x63\x79\x3d\x27\x2d\x34\x32\x2e\
-\x35\x30\x32\x32\x27\x20\x66\x69\x6c\x6c\x3d\x27\x23\x30\x30\x30\
-\x30\x30\x30\x27\x20\x72\x3d\x27\x36\x2e\x30\x32\x32\x35\x27\x2f\
-\x3e\x0a\x3c\x2f\x67\x3e\x0a\x3c\x67\x20\x74\x72\x61\x6e\x73\x66\
-\x6f\x72\x6d\x3d\x27\x6d\x61\x74\x72\x69\x78\x28\x30\x2e\x39\x39\
-\x36\x32\x36\x34\x20\x30\x20\x30\x20\x30\x2e\x39\x39\x36\x32\x36\
-\x34\x20\x35\x38\x2e\x34\x36\x36\x39\x20\x31\x31\x37\x2e\x38\x35\
-\x38\x29\x27\x3e\x0a\x3c\x63\x69\x72\x63\x6c\x65\x20\x63\x78\x3d\
-\x27\x34\x30\x2e\x36\x37\x39\x34\x27\x20\x63\x79\x3d\x27\x2d\x32\
-\x32\x2e\x35\x32\x38\x31\x27\x20\x66\x69\x6c\x6c\x3d\x27\x23\x30\
-\x30\x30\x30\x30\x30\x27\x20\x72\x3d\x27\x36\x2e\x30\x32\x32\x35\
-\x27\x2f\x3e\x0a\x3c\x2f\x67\x3e\x0a\x3c\x2f\x67\x3e\x0a\x3c\x2f\
-\x73\x76\x67\x3e\
-\x00\x00\x03\x22\
+\x78\x6c\x69\x6e\x6b\x22\x20\x78\x3d\x22\x30\x70\x78\x22\x20\x79\
+\x3d\x22\x30\x70\x78\x22\x0d\x0a\x09\x20\x76\x69\x65\x77\x42\x6f\
+\x78\x3d\x22\x30\x20\x30\x20\x32\x30\x20\x32\x30\x22\x20\x65\x6e\
+\x61\x62\x6c\x65\x2d\x62\x61\x63\x6b\x67\x72\x6f\x75\x6e\x64\x3d\
+\x22\x6e\x65\x77\x20\x30\x20\x30\x20\x32\x30\x20\x32\x30\x22\x20\
+\x78\x6d\x6c\x3a\x73\x70\x61\x63\x65\x3d\x22\x70\x72\x65\x73\x65\
+\x72\x76\x65\x22\x3e\x0d\x0a\x3c\x70\x61\x74\x68\x20\x64\x3d\x22\
+\x4d\x38\x2e\x32\x39\x34\x2c\x31\x36\x2e\x39\x39\x38\x63\x2d\x30\
+\x2e\x34\x33\x35\x2c\x30\x2d\x30\x2e\x38\x34\x37\x2d\x30\x2e\x32\
+\x30\x33\x2d\x31\x2e\x31\x31\x31\x2d\x30\x2e\x35\x35\x33\x4c\x33\
+\x2e\x36\x31\x2c\x31\x31\x2e\x37\x32\x34\x63\x2d\x30\x2e\x34\x36\
+\x35\x2d\x30\x2e\x36\x31\x33\x2d\x30\x2e\x33\x34\x34\x2d\x31\x2e\
+\x34\x38\x36\x2c\x30\x2e\x32\x37\x2d\x31\x2e\x39\x35\x31\x0d\x0a\
+\x09\x63\x30\x2e\x36\x31\x35\x2d\x30\x2e\x34\x36\x37\x2c\x31\x2e\
+\x34\x38\x38\x2d\x30\x2e\x33\x34\x34\x2c\x31\x2e\x39\x35\x33\x2c\
+\x30\x2e\x32\x37\x6c\x32\x2e\x33\x35\x31\x2c\x33\x2e\x31\x30\x34\
+\x6c\x35\x2e\x39\x31\x31\x2d\x39\x2e\x34\x39\x32\x63\x30\x2e\x34\
+\x30\x37\x2d\x30\x2e\x36\x35\x32\x2c\x31\x2e\x32\x36\x37\x2d\x30\
+\x2e\x38\x35\x32\x2c\x31\x2e\x39\x32\x31\x2d\x30\x2e\x34\x34\x35\
+\x0d\x0a\x09\x63\x30\x2e\x36\x35\x33\x2c\x30\x2e\x34\x30\x36\x2c\
+\x30\x2e\x38\x35\x34\x2c\x31\x2e\x32\x36\x36\x2c\x30\x2e\x34\x34\
+\x36\x2c\x31\x2e\x39\x32\x4c\x39\x2e\x34\x37\x38\x2c\x31\x36\x2e\
+\x33\x34\x63\x2d\x30\x2e\x32\x34\x32\x2c\x30\x2e\x33\x39\x31\x2d\
+\x30\x2e\x36\x36\x31\x2c\x30\x2e\x36\x33\x35\x2d\x31\x2e\x31\x32\
+\x2c\x30\x2e\x36\x35\x36\x43\x38\x2e\x33\x33\x36\x2c\x31\x36\x2e\
+\x39\x39\x38\x2c\x38\x2e\x33\x31\x36\x2c\x31\x36\x2e\x39\x39\x38\
+\x2c\x38\x2e\x32\x39\x34\x2c\x31\x36\x2e\x39\x39\x38\x7a\x22\x2f\
+\x3e\x0d\x0a\x3c\x2f\x73\x76\x67\x3e\x0d\x0a\
+\x00\x00\x00\x6c\
 \x3c\
-\x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\
-\x30\x22\x20\x65\x6e\x63\x6f\x64\x69\x6e\x67\x3d\x22\x75\x74\x66\
-\x2d\x38\x22\x3f\x3e\x0d\x0a\x3c\x21\x2d\x2d\x20\x47\x65\x6e\x65\
-\x72\x61\x74\x6f\x72\x3a\x20\x41\x64\x6f\x62\x65\x20\x49\x6c\x6c\
-\x75\x73\x74\x72\x61\x74\x6f\x72\x20\x31\x36\x2e\x32\x2e\x31\x2c\
-\x20\x53\x56\x47\x20\x45\x78\x70\x6f\x72\x74\x20\x50\x6c\x75\x67\
-\x2d\x49\x6e\x20\x2e\x20\x53\x56\x47\x20\x56\x65\x72\x73\x69\x6f\
-\x6e\x3a\x20\x36\x2e\x30\x30\x20\x42\x75\x69\x6c\x64\x20\x30\x29\
-\x20\x20\x2d\x2d\x3e\x0d\x0a\x3c\x21\x44\x4f\x43\x54\x59\x50\x45\
-\x20\x73\x76\x67\x20\x50\x55\x42\x4c\x49\x43\x20\x22\x2d\x2f\x2f\
-\x57\x33\x43\x2f\x2f\x44\x54\x44\x20\x53\x56\x47\x20\x31\x2e\x31\
-\x2f\x2f\x45\x4e\x22\x20\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\
-\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x47\x72\x61\x70\x68\x69\x63\
-\x73\x2f\x53\x56\x47\x2f\x31\x2e\x31\x2f\x44\x54\x44\x2f\x73\x76\
-\x67\x31\x31\x2e\x64\x74\x64\x22\x3e\x0d\x0a\x3c\x73\x76\x67\x20\
-\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\x31\x22\x20\x69\x64\
-\x3d\x22\x4c\x61\x79\x65\x72\x5f\x31\x22\x20\x78\x6d\x6c\x6e\x73\
-\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\
-\x6f\x72\x67\x2f\x32\x30\x30\x30\x2f\x73\x76\x67\x22\x20\x78\x6d\
-\x6c\x6e\x73\x3a\x78\x6c\x69\x6e\x6b\x3d\x22\x68\x74\x74\x70\x3a\
-\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x31\x39\x39\
-\x39\x2f\x78\x6c\x69\x6e\x6b\x22\x20\x78\x3d\x22\x30\x70\x78\x22\
-\x20\x79\x3d\x22\x30\x70\x78\x22\x0d\x0a\x09\x20\x77\x69\x64\x74\
-\x68\x3d\x22\x35\x31\x32\x70\x78\x22\x20\x68\x65\x69\x67\x68\x74\
-\x3d\x22\x35\x31\x32\x70\x78\x22\x20\x76\x69\x65\x77\x42\x6f\x78\
-\x3d\x22\x30\x20\x30\x20\x35\x31\x32\x20\x35\x31\x32\x22\x20\x65\
-\x6e\x61\x62\x6c\x65\x2d\x62\x61\x63\x6b\x67\x72\x6f\x75\x6e\x64\
-\x3d\x22\x6e\x65\x77\x20\x30\x20\x30\x20\x35\x31\x32\x20\x35\x31\
-\x32\x22\x20\x78\x6d\x6c\x3a\x73\x70\x61\x63\x65\x3d\x22\x70\x72\
-\x65\x73\x65\x72\x76\x65\x22\x3e\x0d\x0a\x3c\x67\x3e\x0d\x0a\x09\
-\x3c\x63\x69\x72\x63\x6c\x65\x20\x63\x78\x3d\x22\x32\x35\x36\x22\
-\x20\x63\x79\x3d\x22\x32\x38\x30\x22\x20\x72\x3d\x22\x36\x33\x22\
-\x2f\x3e\x0d\x0a\x09\x3c\x70\x61\x74\x68\x20\x64\x3d\x22\x4d\x34\
-\x34\x30\x2c\x39\x36\x68\x2d\x38\x38\x6c\x2d\x33\x32\x2d\x33\x32\
-\x48\x31\x39\x32\x6c\x2d\x33\x32\x2c\x33\x32\x48\x37\x32\x63\x2d\
-\x32\x32\x2e\x30\x39\x32\x2c\x30\x2d\x34\x30\x2c\x31\x37\x2e\x39\
-\x30\x38\x2d\x34\x30\x2c\x34\x30\x76\x32\x37\x32\x63\x30\x2c\x32\
-\x32\x2e\x30\x39\x32\x2c\x31\x37\x2e\x39\x30\x38\x2c\x34\x30\x2c\
-\x34\x30\x2c\x34\x30\x68\x33\x36\x38\x63\x32\x32\x2e\x30\x39\x32\
-\x2c\x30\x2c\x34\x30\x2d\x31\x37\x2e\x39\x30\x38\x2c\x34\x30\x2d\
-\x34\x30\x0d\x0a\x09\x09\x56\x31\x33\x36\x43\x34\x38\x30\x2c\x31\
-\x31\x33\x2e\x39\x30\x38\x2c\x34\x36\x32\x2e\x30\x39\x32\x2c\x39\
-\x36\x2c\x34\x34\x30\x2c\x39\x36\x7a\x20\x4d\x32\x35\x36\x2c\x33\
-\x39\x32\x63\x2d\x36\x31\x2e\x38\x35\x35\x2c\x30\x2d\x31\x31\x32\
-\x2d\x35\x30\x2e\x31\x34\x35\x2d\x31\x31\x32\x2d\x31\x31\x32\x73\
-\x35\x30\x2e\x31\x34\x35\x2d\x31\x31\x32\x2c\x31\x31\x32\x2d\x31\
-\x31\x32\x73\x31\x31\x32\x2c\x35\x30\x2e\x31\x34\x35\x2c\x31\x31\
-\x32\x2c\x31\x31\x32\x0d\x0a\x09\x09\x53\x33\x31\x37\x2e\x38\x35\
-\x35\x2c\x33\x39\x32\x2c\x32\x35\x36\x2c\x33\x39\x32\x7a\x22\x2f\
-\x3e\x0d\x0a\x3c\x2f\x67\x3e\x0d\x0a\x3c\x2f\x73\x76\x67\x3e\x0d\
-\x0a\
-\x00\x00\x02\x7f\
+\x73\x76\x67\x20\x78\x6d\x6c\x6e\x73\x3d\x22\x68\x74\x74\x70\x3a\
+\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x32\x30\x30\
+\x30\x2f\x73\x76\x67\x22\x20\x76\x69\x65\x77\x42\x6f\x78\x3d\x22\
+\x30\x20\x30\x20\x32\x30\x20\x32\x30\x22\x3e\x3c\x70\x61\x74\x68\
+\x20\x64\x3d\x22\x4d\x31\x38\x20\x31\x32\x76\x31\x48\x38\x76\x35\
+\x6c\x2d\x36\x2d\x36\x20\x36\x2d\x36\x76\x35\x68\x38\x56\x32\x68\
+\x32\x7a\x22\x2f\x3e\x3c\x2f\x73\x76\x67\x3e\
+\x00\x00\x03\xc4\
 \x3c\
 \x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\
 \x30\x22\x20\x65\x6e\x63\x6f\x64\x69\x6e\x67\x3d\x22\x75\x74\x66\
 \x2d\x38\x22\x3f\x3e\x0d\x0a\x3c\x21\x2d\x2d\x20\x47\x65\x6e\x65\
 \x72\x61\x74\x6f\x72\x3a\x20\x41\x64\x6f\x62\x65\x20\x49\x6c\x6c\
-\x75\x73\x74\x72\x61\x74\x6f\x72\x20\x31\x36\x2e\x32\x2e\x31\x2c\
+\x75\x73\x74\x72\x61\x74\x6f\x72\x20\x31\x38\x2e\x31\x2e\x30\x2c\
 \x20\x53\x56\x47\x20\x45\x78\x70\x6f\x72\x74\x20\x50\x6c\x75\x67\
 \x2d\x49\x6e\x20\x2e\x20\x53\x56\x47\x20\x56\x65\x72\x73\x69\x6f\
 \x6e\x3a\x20\x36\x2e\x30\x30\x20\x42\x75\x69\x6c\x64\x20\x30\x29\
@@ -1614,101 +1111,51 @@
 \x73\x2f\x53\x56\x47\x2f\x31\x2e\x31\x2f\x44\x54\x44\x2f\x73\x76\
 \x67\x31\x31\x2e\x64\x74\x64\x22\x3e\x0d\x0a\x3c\x73\x76\x67\x20\
 \x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\x31\x22\x20\x69\x64\
-\x3d\x22\x4c\x61\x79\x65\x72\x5f\x31\x22\x20\x78\x6d\x6c\x6e\x73\
-\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\
-\x6f\x72\x67\x2f\x32\x30\x30\x30\x2f\x73\x76\x67\x22\x20\x78\x6d\
-\x6c\x6e\x73\x3a\x78\x6c\x69\x6e\x6b\x3d\x22\x68\x74\x74\x70\x3a\
-\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x31\x39\x39\
-\x39\x2f\x78\x6c\x69\x6e\x6b\x22\x20\x78\x3d\x22\x30\x70\x78\x22\
-\x20\x79\x3d\x22\x30\x70\x78\x22\x0d\x0a\x09\x20\x77\x69\x64\x74\
-\x68\x3d\x22\x35\x31\x32\x70\x78\x22\x20\x68\x65\x69\x67\x68\x74\
-\x3d\x22\x35\x31\x32\x70\x78\x22\x20\x76\x69\x65\x77\x42\x6f\x78\
-\x3d\x22\x30\x20\x30\x20\x35\x31\x32\x20\x35\x31\x32\x22\x20\x73\
-\x74\x79\x6c\x65\x3d\x22\x65\x6e\x61\x62\x6c\x65\x2d\x62\x61\x63\
-\x6b\x67\x72\x6f\x75\x6e\x64\x3a\x6e\x65\x77\x20\x30\x20\x30\x20\
-\x35\x31\x32\x20\x35\x31\x32\x3b\x22\x20\x78\x6d\x6c\x3a\x73\x70\
-\x61\x63\x65\x3d\x22\x70\x72\x65\x73\x65\x72\x76\x65\x22\x3e\x0d\
-\x0a\x3c\x70\x6f\x6c\x79\x67\x6f\x6e\x20\x70\x6f\x69\x6e\x74\x73\
-\x3d\x22\x32\x38\x38\x2c\x39\x36\x20\x33\x33\x37\x2e\x39\x2c\x31\
-\x34\x35\x2e\x39\x20\x32\x37\x34\x2c\x32\x30\x39\x2e\x37\x20\x32\
-\x37\x34\x2c\x32\x30\x39\x2e\x37\x20\x31\x34\x35\x2e\x39\x2c\x33\
-\x33\x37\x2e\x39\x20\x39\x36\x2c\x32\x38\x38\x20\x39\x36\x2c\x34\
-\x31\x36\x20\x32\x32\x34\x2c\x34\x31\x36\x20\x31\x37\x34\x2e\x31\
-\x2c\x33\x36\x36\x2e\x31\x20\x33\x35\x37\x2e\x34\x2c\x31\x38\x32\
-\x2e\x39\x20\x33\x36\x36\x2e\x31\x2c\x31\x37\x34\x2e\x31\x20\x0d\
-\x0a\x09\x34\x31\x36\x2c\x32\x32\x34\x20\x34\x31\x36\x2c\x39\x36\
-\x20\x22\x2f\x3e\x0d\x0a\x3c\x2f\x73\x76\x67\x3e\x0d\x0a\
-\x00\x00\x04\x4e\
-\x3c\
-\x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x27\x31\x2e\
-\x30\x27\x20\x65\x6e\x63\x6f\x64\x69\x6e\x67\x3d\x27\x55\x54\x46\
-\x2d\x38\x27\x3f\x3e\x0a\x3c\x21\x2d\x2d\x20\x54\x68\x69\x73\x20\
-\x66\x69\x6c\x65\x20\x77\x61\x73\x20\x67\x65\x6e\x65\x72\x61\x74\
-\x65\x64\x20\x62\x79\x20\x64\x76\x69\x73\x76\x67\x6d\x20\x32\x2e\
-\x38\x20\x2d\x2d\x3e\x0a\x3c\x73\x76\x67\x20\x76\x65\x72\x73\x69\
-\x6f\x6e\x3d\x27\x31\x2e\x31\x27\x20\x78\x6d\x6c\x6e\x73\x3d\x27\
-\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\
-\x67\x2f\x32\x30\x30\x30\x2f\x73\x76\x67\x27\x20\x78\x6d\x6c\x6e\
-\x73\x3a\x78\x6c\x69\x6e\x6b\x3d\x27\x68\x74\x74\x70\x3a\x2f\x2f\
-\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x31\x39\x39\x39\x2f\
-\x78\x6c\x69\x6e\x6b\x27\x20\x77\x69\x64\x74\x68\x3d\x27\x36\x33\
-\x2e\x39\x39\x39\x36\x70\x74\x27\x20\x68\x65\x69\x67\x68\x74\x3d\
-\x27\x36\x33\x2e\x39\x39\x39\x37\x70\x74\x27\x20\x76\x69\x65\x77\
-\x42\x6f\x78\x3d\x27\x35\x36\x2e\x34\x30\x39\x34\x20\x35\x33\x2e\
-\x38\x35\x38\x33\x20\x36\x33\x2e\x39\x39\x39\x36\x20\x36\x33\x2e\
-\x39\x39\x39\x37\x27\x3e\x0a\x3c\x67\x20\x69\x64\x3d\x27\x70\x61\
-\x67\x65\x31\x27\x3e\x0a\x3c\x67\x20\x74\x72\x61\x6e\x73\x66\x6f\
-\x72\x6d\x3d\x27\x6d\x61\x74\x72\x69\x78\x28\x30\x2e\x39\x39\x36\
-\x32\x36\x34\x20\x30\x20\x30\x20\x30\x2e\x39\x39\x36\x32\x36\x34\
-\x20\x35\x38\x2e\x34\x36\x36\x39\x20\x31\x31\x37\x2e\x38\x35\x38\
-\x29\x27\x3e\x0a\x3c\x70\x61\x74\x68\x20\x64\x3d\x27\x4d\x20\x33\
-\x2e\x39\x35\x37\x33\x35\x20\x2d\x33\x32\x2e\x31\x32\x4c\x20\x31\
-\x31\x2e\x39\x30\x33\x36\x20\x2d\x35\x31\x2e\x33\x30\x33\x39\x4c\
-\x20\x35\x36\x2e\x31\x35\x32\x33\x20\x2d\x34\x32\x2e\x35\x30\x32\
-\x32\x4c\x20\x34\x30\x2e\x36\x37\x39\x34\x20\x2d\x32\x32\x2e\x35\
-\x32\x38\x31\x4c\x20\x33\x2e\x39\x35\x37\x33\x35\x20\x2d\x33\x32\
-\x2e\x31\x32\x5a\x27\x20\x66\x69\x6c\x6c\x3d\x27\x6e\x6f\x6e\x65\
-\x27\x20\x73\x74\x72\x6f\x6b\x65\x3d\x27\x23\x30\x30\x30\x30\x30\
-\x30\x27\x20\x73\x74\x72\x6f\x6b\x65\x2d\x6c\x69\x6e\x65\x63\x61\
-\x70\x3d\x27\x72\x6f\x75\x6e\x64\x27\x20\x73\x74\x72\x6f\x6b\x65\
-\x2d\x6c\x69\x6e\x65\x6a\x6f\x69\x6e\x3d\x27\x72\x6f\x75\x6e\x64\
-\x27\x20\x73\x74\x72\x6f\x6b\x65\x2d\x6d\x69\x74\x65\x72\x6c\x69\
-\x6d\x69\x74\x3d\x27\x31\x30\x2e\x30\x33\x37\x35\x27\x20\x73\x74\
-\x72\x6f\x6b\x65\x2d\x77\x69\x64\x74\x68\x3d\x27\x32\x2e\x35\x30\
-\x39\x33\x37\x27\x2f\x3e\x0a\x3c\x2f\x67\x3e\x0a\x3c\x67\x20\x74\
-\x72\x61\x6e\x73\x66\x6f\x72\x6d\x3d\x27\x6d\x61\x74\x72\x69\x78\
-\x28\x30\x2e\x39\x39\x36\x32\x36\x34\x20\x30\x20\x30\x20\x30\x2e\
-\x39\x39\x36\x32\x36\x34\x20\x35\x38\x2e\x34\x36\x36\x39\x20\x31\
-\x31\x37\x2e\x38\x35\x38\x29\x27\x3e\x0a\x3c\x63\x69\x72\x63\x6c\
-\x65\x20\x63\x78\x3d\x27\x33\x2e\x39\x35\x37\x33\x35\x27\x20\x63\
-\x79\x3d\x27\x2d\x33\x32\x2e\x31\x32\x27\x20\x66\x69\x6c\x6c\x3d\
-\x27\x23\x30\x30\x30\x30\x30\x30\x27\x20\x72\x3d\x27\x36\x2e\x30\
-\x32\x32\x35\x27\x2f\x3e\x0a\x3c\x2f\x67\x3e\x0a\x3c\x67\x20\x74\
-\x72\x61\x6e\x73\x66\x6f\x72\x6d\x3d\x27\x6d\x61\x74\x72\x69\x78\
-\x28\x30\x2e\x39\x39\x36\x32\x36\x34\x20\x30\x20\x30\x20\x30\x2e\
-\x39\x39\x36\x32\x36\x34\x20\x35\x38\x2e\x34\x36\x36\x39\x20\x31\
-\x31\x37\x2e\x38\x35\x38\x29\x27\x3e\x0a\x3c\x63\x69\x72\x63\x6c\
-\x65\x20\x63\x78\x3d\x27\x31\x31\x2e\x39\x30\x33\x36\x27\x20\x63\
-\x79\x3d\x27\x2d\x35\x31\x2e\x33\x30\x33\x39\x27\x20\x66\x69\x6c\
-\x6c\x3d\x27\x23\x30\x30\x30\x30\x30\x30\x27\x20\x72\x3d\x27\x36\
-\x2e\x30\x32\x32\x35\x27\x2f\x3e\x0a\x3c\x2f\x67\x3e\x0a\x3c\x67\
-\x20\x74\x72\x61\x6e\x73\x66\x6f\x72\x6d\x3d\x27\x6d\x61\x74\x72\
-\x69\x78\x28\x30\x2e\x39\x39\x36\x32\x36\x34\x20\x30\x20\x30\x20\
-\x30\x2e\x39\x39\x36\x32\x36\x34\x20\x35\x38\x2e\x34\x36\x36\x39\
-\x20\x31\x31\x37\x2e\x38\x35\x38\x29\x27\x3e\x0a\x3c\x63\x69\x72\
-\x63\x6c\x65\x20\x63\x78\x3d\x27\x35\x36\x2e\x31\x35\x32\x33\x27\
-\x20\x63\x79\x3d\x27\x2d\x34\x32\x2e\x35\x30\x32\x32\x27\x20\x66\
-\x69\x6c\x6c\x3d\x27\x23\x30\x30\x30\x30\x30\x30\x27\x20\x72\x3d\
-\x27\x36\x2e\x30\x32\x32\x35\x27\x2f\x3e\x0a\x3c\x2f\x67\x3e\x0a\
-\x3c\x67\x20\x74\x72\x61\x6e\x73\x66\x6f\x72\x6d\x3d\x27\x6d\x61\
-\x74\x72\x69\x78\x28\x30\x2e\x39\x39\x36\x32\x36\x34\x20\x30\x20\
-\x30\x20\x30\x2e\x39\x39\x36\x32\x36\x34\x20\x35\x38\x2e\x34\x36\
-\x36\x39\x20\x31\x31\x37\x2e\x38\x35\x38\x29\x27\x3e\x0a\x3c\x63\
-\x69\x72\x63\x6c\x65\x20\x63\x78\x3d\x27\x34\x30\x2e\x36\x37\x39\
-\x34\x27\x20\x63\x79\x3d\x27\x2d\x32\x32\x2e\x35\x32\x38\x31\x27\
-\x20\x66\x69\x6c\x6c\x3d\x27\x23\x30\x30\x30\x30\x30\x30\x27\x20\
-\x72\x3d\x27\x36\x2e\x30\x32\x32\x35\x27\x2f\x3e\x0a\x3c\x2f\x67\
-\x3e\x0a\x3c\x2f\x67\x3e\x0a\x3c\x2f\x73\x76\x67\x3e\
+\x3d\x22\x4d\x61\x67\x6e\x69\x66\x79\x69\x6e\x67\x5f\x67\x6c\x61\
+\x73\x73\x22\x20\x78\x6d\x6c\x6e\x73\x3d\x22\x68\x74\x74\x70\x3a\
+\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x32\x30\x30\
+\x30\x2f\x73\x76\x67\x22\x20\x78\x6d\x6c\x6e\x73\x3a\x78\x6c\x69\
+\x6e\x6b\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\
+\x33\x2e\x6f\x72\x67\x2f\x31\x39\x39\x39\x2f\x78\x6c\x69\x6e\x6b\
+\x22\x20\x78\x3d\x22\x30\x70\x78\x22\x0d\x0a\x09\x20\x79\x3d\x22\
+\x30\x70\x78\x22\x20\x76\x69\x65\x77\x42\x6f\x78\x3d\x22\x30\x20\
+\x30\x20\x35\x31\x32\x20\x35\x31\x32\x22\x20\x65\x6e\x61\x62\x6c\
+\x65\x2d\x62\x61\x63\x6b\x67\x72\x6f\x75\x6e\x64\x3d\x22\x6e\x65\
+\x77\x20\x30\x20\x30\x20\x35\x31\x32\x20\x35\x31\x32\x22\x20\x78\
+\x6d\x6c\x3a\x73\x70\x61\x63\x65\x3d\x22\x70\x72\x65\x73\x65\x72\
+\x76\x65\x22\x3e\x0d\x0a\x3c\x67\x20\x74\x72\x61\x6e\x73\x66\x6f\
+\x72\x6d\x3d\x27\x6d\x61\x74\x72\x69\x78\x28\x32\x34\x20\x30\x20\
+\x30\x20\x32\x34\x20\x30\x20\x30\x29\x27\x3e\x0d\x0a\x3c\x70\x61\
+\x74\x68\x20\x64\x3d\x22\x4d\x31\x37\x2e\x35\x34\x35\x2c\x31\x35\
+\x2e\x34\x36\x37\x6c\x2d\x33\x2e\x37\x37\x39\x2d\x33\x2e\x37\x37\
+\x39\x63\x30\x2e\x35\x37\x2d\x30\x2e\x39\x33\x35\x2c\x30\x2e\x38\
+\x39\x38\x2d\x32\x2e\x30\x33\x35\x2c\x30\x2e\x38\x39\x38\x2d\x33\
+\x2e\x32\x31\x63\x30\x2d\x33\x2e\x34\x31\x37\x2d\x32\x2e\x39\x36\
+\x31\x2d\x36\x2e\x33\x37\x37\x2d\x36\x2e\x33\x37\x38\x2d\x36\x2e\
+\x33\x37\x37\x0d\x0a\x09\x43\x34\x2e\x38\x36\x39\x2c\x32\x2e\x31\
+\x2c\x32\x2e\x31\x2c\x34\x2e\x38\x37\x2c\x32\x2e\x31\x2c\x38\x2e\
+\x32\x38\x37\x63\x30\x2c\x33\x2e\x34\x31\x36\x2c\x32\x2e\x39\x36\
+\x31\x2c\x36\x2e\x33\x37\x37\x2c\x36\x2e\x33\x37\x37\x2c\x36\x2e\
+\x33\x37\x37\x63\x31\x2e\x31\x33\x37\x2c\x30\x2c\x32\x2e\x32\x2d\
+\x30\x2e\x33\x30\x39\x2c\x33\x2e\x31\x31\x35\x2d\x30\x2e\x38\x34\
+\x34\x6c\x33\x2e\x37\x39\x39\x2c\x33\x2e\x38\x30\x31\x0d\x0a\x09\
+\x63\x30\x2e\x33\x37\x32\x2c\x30\x2e\x33\x37\x31\x2c\x30\x2e\x39\
+\x37\x35\x2c\x30\x2e\x33\x37\x31\x2c\x31\x2e\x33\x34\x36\x2c\x30\
+\x6c\x30\x2e\x39\x34\x33\x2d\x30\x2e\x39\x34\x33\x43\x31\x38\x2e\
+\x30\x35\x31\x2c\x31\x36\x2e\x33\x30\x37\x2c\x31\x37\x2e\x39\x31\
+\x36\x2c\x31\x35\x2e\x38\x33\x38\x2c\x31\x37\x2e\x35\x34\x35\x2c\
+\x31\x35\x2e\x34\x36\x37\x7a\x20\x4d\x34\x2e\x30\x30\x34\x2c\x38\
+\x2e\x32\x38\x37\x0d\x0a\x09\x63\x30\x2d\x32\x2e\x33\x36\x36\x2c\
+\x31\x2e\x39\x31\x37\x2d\x34\x2e\x32\x38\x33\x2c\x34\x2e\x32\x38\
+\x32\x2d\x34\x2e\x32\x38\x33\x63\x32\x2e\x33\x36\x36\x2c\x30\x2c\
+\x34\x2e\x34\x37\x34\x2c\x32\x2e\x31\x30\x37\x2c\x34\x2e\x34\x37\
+\x34\x2c\x34\x2e\x34\x37\x34\x63\x30\x2c\x32\x2e\x33\x36\x35\x2d\
+\x31\x2e\x39\x31\x38\x2c\x34\x2e\x32\x38\x33\x2d\x34\x2e\x32\x38\
+\x33\x2c\x34\x2e\x32\x38\x33\x0d\x0a\x09\x43\x36\x2e\x31\x31\x31\
+\x2c\x31\x32\x2e\x37\x36\x2c\x34\x2e\x30\x30\x34\x2c\x31\x30\x2e\
+\x36\x35\x32\x2c\x34\x2e\x30\x30\x34\x2c\x38\x2e\x32\x38\x37\x7a\
+\x22\x2f\x3e\x0d\x0a\x3c\x2f\x67\x3e\x0d\x0a\x3c\x2f\x73\x76\x67\
+\x3e\x0d\x0a\
 \x00\x00\x04\xca\
 \x3c\
 \x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\
@@ -1788,57 +1235,6 @@
 \x36\x37\x2c\x37\x2e\x34\x37\x30\x34\x0a\x09\x48\x33\x2e\x33\x37\
 \x33\x33\x4c\x37\x2e\x35\x2c\x33\x2e\x38\x39\x39\x33\x7a\x22\x2f\
 \x3e\x0a\x3c\x2f\x73\x76\x67\x3e\x0a\
-\x00\x00\x03\x0c\
-\x3c\
-\x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\
-\x30\x22\x20\x65\x6e\x63\x6f\x64\x69\x6e\x67\x3d\x22\x75\x74\x66\
-\x2d\x38\x22\x3f\x3e\x0d\x0a\x3c\x21\x2d\x2d\x20\x47\x65\x6e\x65\
-\x72\x61\x74\x6f\x72\x3a\x20\x41\x64\x6f\x62\x65\x20\x49\x6c\x6c\
-\x75\x73\x74\x72\x61\x74\x6f\x72\x20\x31\x38\x2e\x31\x2e\x30\x2c\
-\x20\x53\x56\x47\x20\x45\x78\x70\x6f\x72\x74\x20\x50\x6c\x75\x67\
-\x2d\x49\x6e\x20\x2e\x20\x53\x56\x47\x20\x56\x65\x72\x73\x69\x6f\
-\x6e\x3a\x20\x36\x2e\x30\x30\x20\x42\x75\x69\x6c\x64\x20\x30\x29\
-\x20\x20\x2d\x2d\x3e\x0d\x0a\x3c\x21\x44\x4f\x43\x54\x59\x50\x45\
-\x20\x73\x76\x67\x20\x50\x55\x42\x4c\x49\x43\x20\x22\x2d\x2f\x2f\
-\x57\x33\x43\x2f\x2f\x44\x54\x44\x20\x53\x56\x47\x20\x31\x2e\x31\
-\x2f\x2f\x45\x4e\x22\x20\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\
-\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x47\x72\x61\x70\x68\x69\x63\
-\x73\x2f\x53\x56\x47\x2f\x31\x2e\x31\x2f\x44\x54\x44\x2f\x73\x76\
-\x67\x31\x31\x2e\x64\x74\x64\x22\x3e\x0d\x0a\x3c\x73\x76\x67\x20\
-\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\x31\x22\x20\x69\x64\
-\x3d\x22\x43\x68\x65\x63\x6b\x22\x20\x78\x6d\x6c\x6e\x73\x3d\x22\
-\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\
-\x67\x2f\x32\x30\x30\x30\x2f\x73\x76\x67\x22\x20\x78\x6d\x6c\x6e\
-\x73\x3a\x78\x6c\x69\x6e\x6b\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\
-\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x31\x39\x39\x39\x2f\
-\x78\x6c\x69\x6e\x6b\x22\x20\x78\x3d\x22\x30\x70\x78\x22\x20\x79\
-\x3d\x22\x30\x70\x78\x22\x0d\x0a\x09\x20\x76\x69\x65\x77\x42\x6f\
-\x78\x3d\x22\x30\x20\x30\x20\x32\x30\x20\x32\x30\x22\x20\x65\x6e\
-\x61\x62\x6c\x65\x2d\x62\x61\x63\x6b\x67\x72\x6f\x75\x6e\x64\x3d\
-\x22\x6e\x65\x77\x20\x30\x20\x30\x20\x32\x30\x20\x32\x30\x22\x20\
-\x78\x6d\x6c\x3a\x73\x70\x61\x63\x65\x3d\x22\x70\x72\x65\x73\x65\
-\x72\x76\x65\x22\x3e\x0d\x0a\x3c\x70\x61\x74\x68\x20\x64\x3d\x22\
-\x4d\x38\x2e\x32\x39\x34\x2c\x31\x36\x2e\x39\x39\x38\x63\x2d\x30\
-\x2e\x34\x33\x35\x2c\x30\x2d\x30\x2e\x38\x34\x37\x2d\x30\x2e\x32\
-\x30\x33\x2d\x31\x2e\x31\x31\x31\x2d\x30\x2e\x35\x35\x33\x4c\x33\
-\x2e\x36\x31\x2c\x31\x31\x2e\x37\x32\x34\x63\x2d\x30\x2e\x34\x36\
-\x35\x2d\x30\x2e\x36\x31\x33\x2d\x30\x2e\x33\x34\x34\x2d\x31\x2e\
-\x34\x38\x36\x2c\x30\x2e\x32\x37\x2d\x31\x2e\x39\x35\x31\x0d\x0a\
-\x09\x63\x30\x2e\x36\x31\x35\x2d\x30\x2e\x34\x36\x37\x2c\x31\x2e\
-\x34\x38\x38\x2d\x30\x2e\x33\x34\x34\x2c\x31\x2e\x39\x35\x33\x2c\
-\x30\x2e\x32\x37\x6c\x32\x2e\x33\x35\x31\x2c\x33\x2e\x31\x30\x34\
-\x6c\x35\x2e\x39\x31\x31\x2d\x39\x2e\x34\x39\x32\x63\x30\x2e\x34\
-\x30\x37\x2d\x30\x2e\x36\x35\x32\x2c\x31\x2e\x32\x36\x37\x2d\x30\
-\x2e\x38\x35\x32\x2c\x31\x2e\x39\x32\x31\x2d\x30\x2e\x34\x34\x35\
-\x0d\x0a\x09\x63\x30\x2e\x36\x35\x33\x2c\x30\x2e\x34\x30\x36\x2c\
-\x30\x2e\x38\x35\x34\x2c\x31\x2e\x32\x36\x36\x2c\x30\x2e\x34\x34\
-\x36\x2c\x31\x2e\x39\x32\x4c\x39\x2e\x34\x37\x38\x2c\x31\x36\x2e\
-\x33\x34\x63\x2d\x30\x2e\x32\x34\x32\x2c\x30\x2e\x33\x39\x31\x2d\
-\x30\x2e\x36\x36\x31\x2c\x30\x2e\x36\x33\x35\x2d\x31\x2e\x31\x32\
-\x2c\x30\x2e\x36\x35\x36\x43\x38\x2e\x33\x33\x36\x2c\x31\x36\x2e\
-\x39\x39\x38\x2c\x38\x2e\x33\x31\x36\x2c\x31\x36\x2e\x39\x39\x38\
-\x2c\x38\x2e\x32\x39\x34\x2c\x31\x36\x2e\x39\x39\x38\x7a\x22\x2f\
-\x3e\x0d\x0a\x3c\x2f\x73\x76\x67\x3e\x0d\x0a\
 \x00\x00\x04\xaa\
 \x3c\
 \x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\
@@ -1916,7 +1312,7 @@
 \x35\x2c\x31\x36\x2e\x36\x35\x33\x2c\x39\x2e\x39\x38\x36\x2c\x31\
 \x36\x2e\x31\x36\x35\x7a\x22\x2f\x3e\x0d\x0a\x3c\x2f\x67\x3e\x0d\
 \x0a\x3c\x2f\x73\x76\x67\x3e\x0d\x0a\
-\x00\x00\x03\x4c\
+\x00\x00\x05\xca\
 \x3c\
 \x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\
 \x30\x22\x20\x65\x6e\x63\x6f\x64\x69\x6e\x67\x3d\x22\x75\x74\x66\
@@ -1947,108 +1343,70 @@
 \x6e\x61\x62\x6c\x65\x2d\x62\x61\x63\x6b\x67\x72\x6f\x75\x6e\x64\
 \x3d\x22\x6e\x65\x77\x20\x30\x20\x30\x20\x35\x31\x32\x20\x35\x31\
 \x32\x22\x20\x78\x6d\x6c\x3a\x73\x70\x61\x63\x65\x3d\x22\x70\x72\
-\x65\x73\x65\x72\x76\x65\x22\x3e\x0d\x0a\x3c\x67\x20\x69\x64\x3d\
-\x22\x49\x63\x6f\x6e\x5f\x32\x31\x5f\x22\x3e\x0d\x0a\x09\x3c\x67\
-\x3e\x0d\x0a\x09\x09\x3c\x70\x61\x74\x68\x20\x64\x3d\x22\x4d\x32\
-\x35\x36\x2c\x31\x35\x32\x63\x2d\x35\x37\x2e\x32\x2c\x30\x2d\x31\
-\x30\x34\x2c\x34\x36\x2e\x38\x2d\x31\x30\x34\x2c\x31\x30\x34\x73\
-\x34\x36\x2e\x38\x2c\x31\x30\x34\x2c\x31\x30\x34\x2c\x31\x30\x34\
-\x73\x31\x30\x34\x2d\x34\x36\x2e\x38\x2c\x31\x30\x34\x2d\x31\x30\
-\x34\x53\x33\x31\x33\x2e\x32\x2c\x31\x35\x32\x2c\x32\x35\x36\x2c\
-\x31\x35\x32\x7a\x20\x4d\x32\x35\x36\x2c\x34\x38\x0d\x0a\x09\x09\
-\x09\x43\x31\x34\x31\x2e\x36\x30\x31\x2c\x34\x38\x2c\x34\x38\x2c\
-\x31\x34\x31\x2e\x36\x30\x31\x2c\x34\x38\x2c\x32\x35\x36\x73\x39\
-\x33\x2e\x36\x30\x31\x2c\x32\x30\x38\x2c\x32\x30\x38\x2c\x32\x30\
-\x38\x73\x32\x30\x38\x2d\x39\x33\x2e\x36\x30\x31\x2c\x32\x30\x38\
-\x2d\x32\x30\x38\x53\x33\x37\x30\x2e\x33\x39\x39\x2c\x34\x38\x2c\
-\x32\x35\x36\x2c\x34\x38\x7a\x20\x4d\x32\x35\x36\x2c\x34\x32\x32\
-\x2e\x34\x0d\x0a\x09\x09\x09\x63\x2d\x39\x31\x2e\x35\x31\x38\x2c\
-\x30\x2d\x31\x36\x36\x2e\x34\x2d\x37\x34\x2e\x38\x38\x33\x2d\x31\
-\x36\x36\x2e\x34\x2d\x31\x36\x36\x2e\x34\x53\x31\x36\x34\x2e\x34\
-\x38\x32\x2c\x38\x39\x2e\x36\x2c\x32\x35\x36\x2c\x38\x39\x2e\x36\
-\x53\x34\x32\x32\x2e\x34\x2c\x31\x36\x34\x2e\x34\x38\x32\x2c\x34\
-\x32\x32\x2e\x34\x2c\x32\x35\x36\x53\x33\x34\x37\x2e\x35\x31\x38\
-\x2c\x34\x32\x32\x2e\x34\x2c\x32\x35\x36\x2c\x34\x32\x32\x2e\x34\
-\x7a\x22\x2f\x3e\x0d\x0a\x09\x3c\x2f\x67\x3e\x0d\x0a\x3c\x2f\x67\
-\x3e\x0d\x0a\x3c\x2f\x73\x76\x67\x3e\x0d\x0a\
-\x00\x00\x01\x1c\
-\x3c\
-\x73\x76\x67\x20\x78\x6d\x6c\x6e\x73\x3d\x22\x68\x74\x74\x70\x3a\
-\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x32\x30\x30\
-\x30\x2f\x73\x76\x67\x22\x20\x77\x69\x64\x74\x68\x3d\x22\x35\x31\
-\x32\x70\x78\x22\x20\x68\x65\x69\x67\x68\x74\x3d\x22\x35\x31\x32\
-\x70\x78\x22\x0a\x20\x20\x20\x20\x20\x76\x69\x65\x77\x42\x6f\x78\
-\x3d\x22\x30\x20\x30\x20\x35\x31\x32\x20\x35\x31\x32\x22\x3e\x0a\
-\x3c\x67\x20\x74\x72\x61\x6e\x73\x66\x6f\x72\x6d\x3d\x27\x6d\x61\
-\x74\x72\x69\x78\x28\x34\x38\x20\x30\x20\x30\x20\x34\x38\x20\x34\
-\x38\x20\x34\x38\x29\x27\x3e\x0a\x20\x20\x3c\x70\x61\x74\x68\x20\
-\x64\x3d\x22\x4d\x30\x20\x30\x76\x32\x68\x2e\x35\x63\x30\x2d\x2e\
-\x35\x35\x2e\x34\x35\x2d\x31\x20\x31\x2d\x31\x68\x31\x2e\x35\x76\
-\x35\x2e\x35\x63\x30\x20\x2e\x32\x38\x2d\x2e\x32\x32\x2e\x35\x2d\
-\x2e\x35\x2e\x35\x68\x2d\x2e\x35\x76\x31\x68\x34\x76\x2d\x31\x68\
-\x2d\x2e\x35\x63\x2d\x2e\x32\x38\x20\x30\x2d\x2e\x35\x2d\x2e\x32\
-\x32\x2d\x2e\x35\x2d\x2e\x35\x76\x2d\x35\x2e\x35\x68\x31\x2e\x35\
-\x63\x2e\x35\x35\x20\x30\x20\x31\x20\x2e\x34\x35\x20\x31\x20\x31\
-\x68\x2e\x35\x76\x2d\x32\x68\x2d\x38\x7a\x22\x20\x2f\x3e\x0a\x3c\
-\x2f\x67\x3e\x0a\x3c\x2f\x73\x76\x67\x3e\x0a\
-\x00\x00\x03\x7c\
-\x3c\
-\x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x27\x31\x2e\
-\x30\x27\x20\x65\x6e\x63\x6f\x64\x69\x6e\x67\x3d\x27\x55\x54\x46\
-\x2d\x38\x27\x3f\x3e\x0a\x3c\x21\x2d\x2d\x20\x54\x68\x69\x73\x20\
-\x66\x69\x6c\x65\x20\x77\x61\x73\x20\x67\x65\x6e\x65\x72\x61\x74\
-\x65\x64\x20\x62\x79\x20\x64\x76\x69\x73\x76\x67\x6d\x20\x32\x2e\
-\x38\x20\x2d\x2d\x3e\x0a\x3c\x73\x76\x67\x20\x76\x65\x72\x73\x69\
-\x6f\x6e\x3d\x27\x31\x2e\x31\x27\x20\x78\x6d\x6c\x6e\x73\x3d\x27\
-\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\
-\x67\x2f\x32\x30\x30\x30\x2f\x73\x76\x67\x27\x20\x78\x6d\x6c\x6e\
-\x73\x3a\x78\x6c\x69\x6e\x6b\x3d\x27\x68\x74\x74\x70\x3a\x2f\x2f\
-\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x31\x39\x39\x39\x2f\
-\x78\x6c\x69\x6e\x6b\x27\x20\x77\x69\x64\x74\x68\x3d\x27\x36\x33\
-\x2e\x39\x39\x39\x36\x70\x74\x27\x20\x68\x65\x69\x67\x68\x74\x3d\
-\x27\x36\x33\x2e\x39\x39\x39\x37\x70\x74\x27\x20\x76\x69\x65\x77\
-\x42\x6f\x78\x3d\x27\x35\x36\x2e\x34\x30\x39\x34\x20\x35\x33\x2e\
-\x38\x35\x38\x33\x20\x36\x33\x2e\x39\x39\x39\x36\x20\x36\x33\x2e\
-\x39\x39\x39\x37\x27\x3e\x0a\x3c\x67\x20\x69\x64\x3d\x27\x70\x61\
-\x67\x65\x31\x27\x3e\x0a\x3c\x67\x20\x74\x72\x61\x6e\x73\x66\x6f\
-\x72\x6d\x3d\x27\x6d\x61\x74\x72\x69\x78\x28\x30\x2e\x39\x39\x36\
-\x32\x36\x34\x20\x30\x20\x30\x20\x30\x2e\x39\x39\x36\x32\x36\x34\
-\x20\x35\x36\x2e\x34\x30\x39\x34\x20\x31\x31\x37\x2e\x38\x35\x38\
-\x29\x27\x3e\x0a\x3c\x70\x61\x74\x68\x20\x64\x3d\x27\x4d\x20\x32\
-\x2e\x30\x30\x37\x35\x20\x2d\x32\x2e\x30\x30\x37\x35\x4c\x20\x36\
-\x32\x2e\x32\x33\x32\x35\x20\x2d\x32\x2e\x30\x30\x37\x35\x4c\x20\
-\x36\x32\x2e\x32\x33\x32\x35\x20\x2d\x36\x32\x2e\x32\x33\x32\x35\
-\x4c\x20\x32\x2e\x30\x30\x37\x35\x20\x2d\x36\x32\x2e\x32\x33\x32\
-\x35\x4c\x20\x32\x2e\x30\x30\x37\x35\x20\x2d\x32\x2e\x30\x30\x37\
-\x35\x5a\x27\x20\x66\x69\x6c\x6c\x3d\x27\x6e\x6f\x6e\x65\x27\x20\
-\x73\x74\x72\x6f\x6b\x65\x3d\x27\x23\x30\x30\x30\x30\x30\x30\x27\
-\x20\x73\x74\x72\x6f\x6b\x65\x2d\x6c\x69\x6e\x65\x63\x61\x70\x3d\
-\x27\x72\x6f\x75\x6e\x64\x27\x20\x73\x74\x72\x6f\x6b\x65\x2d\x6c\
-\x69\x6e\x65\x6a\x6f\x69\x6e\x3d\x27\x72\x6f\x75\x6e\x64\x27\x20\
-\x73\x74\x72\x6f\x6b\x65\x2d\x6d\x69\x74\x65\x72\x6c\x69\x6d\x69\
-\x74\x3d\x27\x31\x30\x2e\x30\x33\x37\x35\x27\x20\x73\x74\x72\x6f\
-\x6b\x65\x2d\x77\x69\x64\x74\x68\x3d\x27\x34\x2e\x30\x31\x35\x27\
-\x2f\x3e\x0a\x3c\x2f\x67\x3e\x0a\x3c\x67\x20\x74\x72\x61\x6e\x73\
-\x66\x6f\x72\x6d\x3d\x27\x6d\x61\x74\x72\x69\x78\x28\x30\x2e\x39\
-\x39\x36\x32\x36\x34\x20\x30\x20\x30\x20\x30\x2e\x39\x39\x36\x32\
-\x36\x34\x20\x35\x36\x2e\x34\x30\x39\x34\x20\x31\x31\x37\x2e\x38\
-\x35\x38\x29\x27\x3e\x0a\x3c\x70\x61\x74\x68\x20\x64\x3d\x27\x4d\
-\x20\x34\x37\x2e\x31\x37\x36\x32\x20\x2d\x33\x32\x2e\x31\x32\x43\
-\x20\x34\x37\x2e\x31\x37\x36\x32\x20\x2d\x34\x30\x2e\x34\x33\x35\
-\x33\x20\x34\x30\x2e\x34\x33\x35\x33\x20\x2d\x34\x37\x2e\x31\x37\
-\x36\x32\x20\x33\x32\x2e\x31\x32\x20\x2d\x34\x37\x2e\x31\x37\x36\
-\x32\x43\x20\x32\x33\x2e\x38\x30\x34\x37\x20\x2d\x34\x37\x2e\x31\
-\x37\x36\x32\x20\x31\x37\x2e\x30\x36\x33\x37\x20\x2d\x34\x30\x2e\
-\x34\x33\x35\x33\x20\x31\x37\x2e\x30\x36\x33\x37\x20\x2d\x33\x32\
-\x2e\x31\x32\x43\x20\x31\x37\x2e\x30\x36\x33\x37\x20\x2d\x32\x33\
-\x2e\x38\x30\x34\x37\x20\x32\x33\x2e\x38\x30\x34\x37\x20\x2d\x31\
-\x37\x2e\x30\x36\x33\x37\x20\x33\x32\x2e\x31\x32\x20\x2d\x31\x37\
-\x2e\x30\x36\x33\x37\x43\x20\x34\x30\x2e\x34\x33\x35\x33\x20\x2d\
-\x31\x37\x2e\x30\x36\x33\x37\x20\x34\x37\x2e\x31\x37\x36\x32\x20\
-\x2d\x32\x33\x2e\x38\x30\x34\x37\x20\x34\x37\x2e\x31\x37\x36\x32\
-\x20\x2d\x33\x32\x2e\x31\x32\x5a\x27\x20\x66\x69\x6c\x6c\x3d\x27\
-\x23\x30\x30\x30\x30\x30\x30\x27\x2f\x3e\x0a\x3c\x2f\x67\x3e\x0a\
-\x3c\x2f\x67\x3e\x0a\x3c\x2f\x73\x76\x67\x3e\
+\x65\x73\x65\x72\x76\x65\x22\x3e\x0d\x0a\x3c\x70\x61\x74\x68\x20\
+\x64\x3d\x22\x4d\x34\x35\x30\x2e\x36\x37\x39\x2c\x32\x37\x33\x2e\
+\x35\x63\x2d\x31\x34\x2e\x35\x38\x35\x2d\x31\x34\x2e\x35\x37\x37\
+\x2d\x33\x36\x2e\x30\x35\x34\x2d\x31\x35\x2e\x38\x39\x2d\x35\x30\
+\x2e\x36\x33\x39\x2d\x31\x2e\x33\x31\x32\x6c\x2d\x34\x31\x2e\x36\
+\x38\x37\x2c\x34\x31\x2e\x36\x36\x34\x63\x2d\x31\x30\x2e\x38\x35\
+\x32\x2c\x31\x30\x2e\x38\x33\x36\x2d\x32\x33\x2e\x39\x33\x2c\x31\
+\x30\x2e\x38\x35\x39\x2d\x33\x31\x2e\x35\x36\x34\x2c\x31\x2e\x38\
+\x35\x32\x0d\x0a\x09\x63\x2d\x35\x2e\x30\x35\x37\x2d\x35\x2e\x39\
+\x36\x38\x2d\x33\x2e\x30\x36\x31\x2d\x32\x34\x2e\x33\x37\x34\x2d\
+\x31\x2e\x36\x34\x34\x2d\x33\x36\x2e\x30\x34\x39\x6c\x32\x30\x2e\
+\x39\x30\x37\x2d\x31\x37\x31\x2e\x38\x34\x39\x63\x31\x2e\x38\x36\
+\x37\x2d\x31\x35\x2e\x33\x35\x33\x2d\x39\x2e\x30\x37\x2d\x33\x30\
+\x2e\x31\x38\x35\x2d\x32\x34\x2e\x34\x33\x2d\x33\x32\x2e\x30\x35\
+\x31\x0d\x0a\x09\x63\x2d\x31\x35\x2e\x33\x35\x38\x2d\x31\x2e\x38\
+\x36\x37\x2d\x32\x39\x2e\x33\x32\x32\x2c\x39\x2e\x39\x33\x39\x2d\
+\x33\x31\x2e\x31\x39\x31\x2c\x32\x35\x2e\x32\x38\x39\x4c\x32\x36\
+\x37\x2e\x33\x37\x2c\x32\x33\x36\x2e\x30\x32\x31\x63\x2d\x31\x2e\
+\x32\x30\x35\x2c\x33\x2e\x33\x35\x38\x2d\x33\x2e\x37\x39\x2c\x33\
+\x2e\x39\x33\x38\x2d\x34\x2e\x30\x38\x31\x2d\x30\x2e\x35\x38\x32\
+\x4c\x32\x35\x35\x2e\x34\x34\x2c\x36\x30\x0d\x0a\x09\x63\x30\x2d\
+\x31\x35\x2e\x34\x36\x35\x2d\x31\x32\x2e\x35\x34\x32\x2d\x32\x38\
+\x2d\x32\x38\x2e\x30\x31\x34\x2d\x32\x38\x63\x2d\x31\x35\x2e\x34\
+\x37\x33\x2c\x30\x2d\x32\x38\x2e\x30\x31\x35\x2c\x31\x32\x2e\x35\
+\x33\x35\x2d\x32\x38\x2e\x30\x31\x35\x2c\x32\x38\x6c\x2d\x30\x2e\
+\x35\x35\x32\x2c\x31\x37\x36\x2e\x37\x35\x32\x63\x30\x2e\x31\x34\
+\x36\x2c\x32\x2e\x30\x34\x2d\x31\x2e\x36\x30\x34\x2c\x32\x2e\x36\
+\x32\x34\x2d\x31\x2e\x39\x32\x2c\x30\x2e\x32\x39\x34\x4c\x31\x37\
+\x32\x2e\x30\x31\x36\x2c\x39\x39\x2e\x30\x37\x37\x0d\x0a\x09\x63\
+\x2d\x32\x2e\x37\x35\x2d\x31\x35\x2e\x32\x31\x39\x2d\x31\x37\x2e\
+\x33\x32\x33\x2d\x32\x36\x2e\x32\x30\x33\x2d\x33\x32\x2e\x35\x34\
+\x38\x2d\x32\x33\x2e\x34\x35\x33\x63\x2d\x31\x35\x2e\x32\x32\x37\
+\x2c\x32\x2e\x37\x34\x38\x2d\x32\x35\x2e\x33\x33\x39\x2c\x31\x38\
+\x2e\x31\x38\x37\x2d\x32\x32\x2e\x35\x39\x31\x2c\x33\x33\x2e\x34\
+\x30\x33\x6c\x32\x32\x2e\x31\x39\x33\x2c\x31\x36\x31\x2e\x34\x35\
+\x35\x0d\x0a\x09\x63\x30\x2e\x30\x32\x33\x2c\x32\x2e\x38\x37\x32\
+\x2d\x30\x2e\x39\x34\x31\x2c\x34\x2e\x35\x31\x33\x2d\x32\x2e\x33\
+\x30\x38\x2c\x30\x2e\x38\x33\x31\x6c\x2d\x33\x33\x2e\x31\x30\x39\
+\x2d\x38\x38\x2e\x35\x31\x37\x63\x2d\x35\x2e\x31\x38\x2d\x31\x34\
+\x2e\x35\x37\x32\x2d\x32\x31\x2e\x31\x39\x36\x2d\x32\x33\x2e\x30\
+\x36\x35\x2d\x33\x35\x2e\x37\x37\x36\x2d\x31\x37\x2e\x38\x38\x39\
+\x0d\x0a\x09\x63\x2d\x31\x34\x2e\x35\x37\x39\x2c\x35\x2e\x31\x37\
+\x37\x2d\x32\x32\x2e\x32\x30\x31\x2c\x32\x32\x2e\x30\x36\x31\x2d\
+\x31\x37\x2e\x30\x32\x33\x2c\x33\x36\x2e\x36\x33\x31\x6c\x35\x38\
+\x2e\x30\x34\x32\x2c\x31\x38\x39\x2e\x36\x32\x35\x63\x30\x2e\x33\
+\x30\x33\x2c\x31\x2e\x30\x34\x36\x2c\x30\x2e\x36\x32\x34\x2c\x32\
+\x2e\x30\x38\x35\x2c\x30\x2e\x39\x35\x33\x2c\x33\x2e\x31\x31\x38\
+\x6c\x30\x2e\x31\x32\x31\x2c\x30\x2e\x33\x39\x0d\x0a\x09\x63\x30\
+\x2e\x30\x31\x31\x2c\x30\x2e\x30\x33\x31\x2c\x30\x2e\x30\x32\x35\
+\x2c\x30\x2e\x30\x35\x38\x2c\x30\x2e\x30\x33\x35\x2c\x30\x2e\x30\
+\x38\x38\x43\x31\x32\x36\x2e\x30\x37\x39\x2c\x34\x34\x34\x2e\x32\
+\x33\x33\x2c\x31\x37\x32\x2e\x35\x37\x2c\x34\x38\x30\x2c\x32\x32\
+\x37\x2e\x34\x32\x37\x2c\x34\x38\x30\x63\x33\x35\x2e\x31\x31\x36\
+\x2c\x30\x2c\x37\x31\x2e\x35\x39\x31\x2d\x31\x32\x2e\x33\x37\x38\
+\x2c\x39\x39\x2e\x33\x35\x37\x2d\x33\x33\x2e\x36\x37\x32\x0d\x0a\
+\x09\x63\x30\x2e\x30\x30\x31\x2c\x30\x2c\x30\x2e\x30\x30\x33\x2d\
+\x30\x2e\x30\x30\x32\x2c\x30\x2e\x30\x30\x33\x2d\x30\x2e\x30\x30\
+\x32\x63\x32\x39\x2e\x39\x39\x2d\x31\x38\x2e\x30\x35\x31\x2c\x31\
+\x32\x36\x2e\x30\x37\x31\x2d\x31\x32\x31\x2e\x33\x34\x37\x2c\x31\
+\x32\x36\x2e\x30\x37\x31\x2d\x31\x32\x31\x2e\x33\x34\x37\x43\x34\
+\x36\x37\x2e\x34\x34\x35\x2c\x33\x31\x30\x2e\x34\x30\x32\x2c\x34\
+\x36\x35\x2e\x32\x36\x36\x2c\x32\x38\x38\x2e\x30\x38\x2c\x34\x35\
+\x30\x2e\x36\x37\x39\x2c\x32\x37\x33\x2e\x35\x7a\x22\x2f\x3e\x0d\
+\x0a\x3c\x2f\x73\x76\x67\x3e\x0d\x0a\
 \x00\x00\x02\xa1\
 \x3c\
 \x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\
@@ -2094,7 +1452,7 @@
 \x33\x2c\x34\x68\x2d\x32\x76\x34\x68\x32\x56\x34\x7a\x22\x2f\x3e\
 \x0d\x0a\x3c\x2f\x67\x3e\x0d\x0a\x3c\x2f\x73\x76\x67\x3e\x0d\x0a\
 \
-\x00\x00\x02\xfc\
+\x00\x00\x02\xc9\
 \x3c\
 \x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\
 \x30\x22\x20\x65\x6e\x63\x6f\x64\x69\x6e\x67\x3d\x22\x75\x74\x66\
@@ -2121,63 +1479,445 @@
 \x20\x79\x3d\x22\x30\x70\x78\x22\x0d\x0a\x09\x20\x77\x69\x64\x74\
 \x68\x3d\x22\x35\x31\x32\x70\x78\x22\x20\x68\x65\x69\x67\x68\x74\
 \x3d\x22\x35\x31\x32\x70\x78\x22\x20\x76\x69\x65\x77\x42\x6f\x78\
+\x3d\x22\x30\x20\x30\x20\x35\x31\x32\x20\x35\x31\x32\x22\x20\x73\
+\x74\x79\x6c\x65\x3d\x22\x65\x6e\x61\x62\x6c\x65\x2d\x62\x61\x63\
+\x6b\x67\x72\x6f\x75\x6e\x64\x3a\x6e\x65\x77\x20\x30\x20\x30\x20\
+\x35\x31\x32\x20\x35\x31\x32\x3b\x22\x20\x78\x6d\x6c\x3a\x73\x70\
+\x61\x63\x65\x3d\x22\x70\x72\x65\x73\x65\x72\x76\x65\x22\x3e\x0d\
+\x0a\x3c\x70\x6f\x6c\x79\x67\x6f\x6e\x20\x70\x6f\x69\x6e\x74\x73\
+\x3d\x22\x34\x38\x30\x2c\x32\x35\x36\x20\x33\x38\x34\x2c\x31\x36\
+\x30\x20\x33\x38\x34\x2c\x32\x33\x36\x20\x32\x37\x36\x2c\x32\x33\
+\x36\x20\x32\x37\x36\x2c\x31\x32\x38\x20\x33\x35\x32\x2c\x31\x32\
+\x38\x20\x32\x35\x36\x2c\x33\x32\x20\x31\x36\x30\x2c\x31\x32\x38\
+\x20\x32\x33\x36\x2c\x31\x32\x38\x20\x32\x33\x36\x2c\x32\x33\x36\
+\x20\x31\x32\x38\x2c\x32\x33\x36\x20\x31\x32\x38\x2c\x31\x36\x30\
+\x20\x33\x32\x2c\x32\x35\x36\x20\x31\x32\x38\x2c\x33\x35\x32\x20\
+\x0d\x0a\x09\x31\x32\x38\x2c\x32\x37\x36\x20\x32\x33\x36\x2c\x32\
+\x37\x36\x20\x32\x33\x36\x2c\x33\x38\x34\x20\x31\x36\x30\x2c\x33\
+\x38\x34\x20\x32\x35\x36\x2c\x34\x38\x30\x20\x33\x35\x32\x2c\x33\
+\x38\x34\x20\x32\x37\x35\x2e\x38\x2c\x33\x38\x34\x20\x32\x37\x35\
+\x2e\x34\x2c\x32\x37\x35\x2e\x35\x20\x33\x38\x34\x2c\x32\x37\x35\
+\x2e\x38\x20\x33\x38\x34\x2c\x33\x35\x32\x20\x22\x2f\x3e\x0d\x0a\
+\x3c\x2f\x73\x76\x67\x3e\x0d\x0a\
+\x00\x00\x07\x80\
+\x3c\
+\x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\
+\x30\x22\x20\x65\x6e\x63\x6f\x64\x69\x6e\x67\x3d\x22\x75\x74\x66\
+\x2d\x38\x22\x3f\x3e\x0d\x0a\x3c\x21\x2d\x2d\x20\x47\x65\x6e\x65\
+\x72\x61\x74\x6f\x72\x3a\x20\x41\x64\x6f\x62\x65\x20\x49\x6c\x6c\
+\x75\x73\x74\x72\x61\x74\x6f\x72\x20\x31\x36\x2e\x32\x2e\x31\x2c\
+\x20\x53\x56\x47\x20\x45\x78\x70\x6f\x72\x74\x20\x50\x6c\x75\x67\
+\x2d\x49\x6e\x20\x2e\x20\x53\x56\x47\x20\x56\x65\x72\x73\x69\x6f\
+\x6e\x3a\x20\x36\x2e\x30\x30\x20\x42\x75\x69\x6c\x64\x20\x30\x29\
+\x20\x20\x2d\x2d\x3e\x0d\x0a\x3c\x21\x44\x4f\x43\x54\x59\x50\x45\
+\x20\x73\x76\x67\x20\x50\x55\x42\x4c\x49\x43\x20\x22\x2d\x2f\x2f\
+\x57\x33\x43\x2f\x2f\x44\x54\x44\x20\x53\x56\x47\x20\x31\x2e\x31\
+\x2f\x2f\x45\x4e\x22\x20\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\
+\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x47\x72\x61\x70\x68\x69\x63\
+\x73\x2f\x53\x56\x47\x2f\x31\x2e\x31\x2f\x44\x54\x44\x2f\x73\x76\
+\x67\x31\x31\x2e\x64\x74\x64\x22\x3e\x0d\x0a\x3c\x73\x76\x67\x20\
+\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\x31\x22\x20\x69\x64\
+\x3d\x22\x4c\x61\x79\x65\x72\x5f\x31\x22\x20\x78\x6d\x6c\x6e\x73\
+\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\
+\x6f\x72\x67\x2f\x32\x30\x30\x30\x2f\x73\x76\x67\x22\x20\x78\x6d\
+\x6c\x6e\x73\x3a\x78\x6c\x69\x6e\x6b\x3d\x22\x68\x74\x74\x70\x3a\
+\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x31\x39\x39\
+\x39\x2f\x78\x6c\x69\x6e\x6b\x22\x20\x78\x3d\x22\x30\x70\x78\x22\
+\x20\x79\x3d\x22\x30\x70\x78\x22\x0d\x0a\x09\x20\x77\x69\x64\x74\
+\x68\x3d\x22\x35\x31\x32\x70\x78\x22\x20\x68\x65\x69\x67\x68\x74\
+\x3d\x22\x35\x31\x32\x70\x78\x22\x20\x76\x69\x65\x77\x42\x6f\x78\
 \x3d\x22\x30\x20\x30\x20\x35\x31\x32\x20\x35\x31\x32\x22\x20\x65\
 \x6e\x61\x62\x6c\x65\x2d\x62\x61\x63\x6b\x67\x72\x6f\x75\x6e\x64\
 \x3d\x22\x6e\x65\x77\x20\x30\x20\x30\x20\x35\x31\x32\x20\x35\x31\
 \x32\x22\x20\x78\x6d\x6c\x3a\x73\x70\x61\x63\x65\x3d\x22\x70\x72\
+\x65\x73\x65\x72\x76\x65\x22\x3e\x0d\x0a\x3c\x67\x3e\x0d\x0a\x09\
+\x3c\x70\x61\x74\x68\x20\x64\x3d\x22\x4d\x31\x39\x33\x2e\x34\x36\
+\x2c\x32\x34\x39\x2e\x30\x35\x36\x63\x33\x2e\x37\x32\x33\x2d\x30\
+\x2e\x36\x37\x2c\x37\x2e\x35\x38\x39\x2d\x31\x2e\x30\x34\x31\x2c\
+\x31\x31\x2e\x35\x38\x36\x2d\x31\x2e\x30\x34\x31\x4c\x32\x30\x31\
+\x2e\x39\x32\x34\x2c\x32\x34\x38\x68\x31\x30\x33\x2e\x38\x32\x33\
+\x63\x34\x2e\x35\x30\x33\x2c\x30\x2c\x38\x2e\x38\x30\x36\x2d\x30\
+\x2e\x36\x31\x37\x2c\x31\x32\x2e\x39\x30\x38\x2d\x31\x2e\x37\x35\
+\x34\x0d\x0a\x09\x09\x63\x31\x39\x2e\x33\x37\x2d\x35\x2e\x33\x36\
+\x33\x2c\x33\x33\x2e\x33\x34\x35\x2d\x32\x32\x2e\x35\x33\x37\x2c\
+\x33\x33\x2e\x33\x34\x35\x2d\x34\x33\x2e\x36\x36\x33\x76\x2d\x33\
+\x30\x2e\x38\x32\x32\x76\x2d\x35\x36\x2e\x34\x30\x32\x63\x30\x2d\
+\x32\x34\x2e\x38\x33\x32\x2d\x32\x31\x2e\x31\x35\x2d\x34\x33\x2e\
+\x34\x38\x34\x2d\x34\x36\x2e\x32\x38\x39\x2d\x34\x37\x2e\x36\x30\
+\x36\x0d\x0a\x09\x09\x63\x2d\x31\x35\x2e\x39\x33\x31\x2d\x32\x2e\
+\x36\x32\x34\x2d\x33\x39\x2e\x32\x35\x38\x2d\x33\x2e\x38\x32\x37\
+\x2d\x35\x35\x2e\x30\x38\x39\x2d\x33\x2e\x37\x34\x39\x63\x2d\x31\
+\x35\x2e\x38\x32\x39\x2c\x30\x2e\x30\x38\x36\x2d\x33\x30\x2e\x39\
+\x38\x31\x2c\x31\x2e\x34\x30\x34\x2d\x34\x34\x2e\x32\x37\x37\x2c\
+\x33\x2e\x37\x34\x39\x43\x31\x36\x37\x2e\x31\x34\x33\x2c\x37\x34\
+\x2e\x35\x37\x36\x2c\x31\x36\x30\x2c\x38\x38\x2e\x39\x32\x38\x2c\
+\x31\x36\x30\x2c\x31\x31\x35\x2e\x33\x35\x39\x56\x31\x34\x34\x68\
+\x39\x36\x0d\x0a\x09\x09\x76\x31\x36\x48\x31\x32\x38\x2e\x38\x32\
+\x63\x2d\x33\x35\x2e\x36\x32\x38\x2c\x30\x2d\x36\x34\x2e\x35\x33\
+\x38\x2c\x34\x32\x2e\x35\x37\x31\x2d\x36\x34\x2e\x38\x31\x33\x2c\
+\x39\x35\x2e\x32\x34\x32\x43\x36\x34\x2e\x30\x30\x35\x2c\x32\x35\
+\x35\x2e\x34\x39\x35\x2c\x36\x34\x2c\x32\x35\x35\x2e\x37\x34\x37\
+\x2c\x36\x34\x2c\x32\x35\x36\x63\x30\x2c\x39\x2e\x35\x32\x33\x2c\
+\x30\x2e\x39\x34\x2c\x31\x38\x2e\x37\x32\x2c\x32\x2e\x36\x38\x35\
+\x2c\x32\x37\x2e\x34\x30\x34\x0d\x0a\x09\x09\x43\x37\x34\x2e\x36\
+\x34\x38\x2c\x33\x32\x33\x2e\x30\x37\x2c\x39\x39\x2e\x34\x35\x31\
+\x2c\x33\x35\x32\x2c\x31\x32\x38\x2e\x38\x32\x2c\x33\x35\x32\x48\
+\x31\x34\x34\x76\x2d\x32\x2e\x36\x36\x32\x76\x2d\x34\x33\x2e\x32\
+\x37\x33\x43\x31\x34\x34\x2c\x32\x37\x39\x2e\x32\x33\x38\x2c\x31\
+\x36\x34\x2e\x31\x34\x36\x2c\x32\x35\x34\x2e\x33\x33\x32\x2c\x31\
+\x39\x33\x2e\x34\x36\x2c\x32\x34\x39\x2e\x30\x35\x36\x7a\x20\x4d\
+\x32\x30\x33\x2e\x36\x35\x36\x2c\x31\x32\x37\x2e\x30\x30\x32\x0d\
+\x0a\x09\x09\x63\x2d\x39\x2e\x35\x39\x32\x2c\x30\x2d\x31\x37\x2e\
+\x33\x38\x34\x2d\x37\x2e\x37\x38\x35\x2d\x31\x37\x2e\x33\x38\x34\
+\x2d\x31\x37\x2e\x34\x30\x33\x63\x30\x2d\x39\x2e\x36\x36\x34\x2c\
+\x37\x2e\x37\x37\x34\x2d\x31\x37\x2e\x35\x32\x2c\x31\x37\x2e\x33\
+\x38\x34\x2d\x31\x37\x2e\x35\x32\x63\x39\x2e\x35\x37\x34\x2c\x30\
+\x2c\x31\x37\x2e\x33\x39\x39\x2c\x37\x2e\x38\x35\x35\x2c\x31\x37\
+\x2e\x33\x39\x39\x2c\x31\x37\x2e\x35\x32\x0d\x0a\x09\x09\x43\x32\
+\x32\x31\x2e\x30\x35\x36\x2c\x31\x31\x39\x2e\x32\x31\x37\x2c\x32\
+\x31\x33\x2e\x32\x34\x36\x2c\x31\x32\x37\x2e\x30\x30\x32\x2c\x32\
+\x30\x33\x2e\x36\x35\x36\x2c\x31\x32\x37\x2e\x30\x30\x32\x7a\x22\
+\x2f\x3e\x0d\x0a\x09\x3c\x70\x61\x74\x68\x20\x64\x3d\x22\x4d\x34\
+\x34\x33\x2e\x39\x35\x31\x2c\x32\x32\x32\x2e\x35\x34\x33\x43\x34\
+\x33\x34\x2e\x37\x38\x2c\x31\x38\x36\x2e\x30\x32\x31\x2c\x34\x31\
+\x31\x2e\x30\x33\x33\x2c\x31\x36\x30\x2c\x33\x38\x33\x2e\x31\x38\
+\x2c\x31\x36\x30\x48\x33\x36\x38\x76\x32\x2e\x36\x32\x36\x76\x33\
+\x38\x2e\x30\x34\x36\x63\x30\x2c\x33\x33\x2e\x39\x31\x35\x2d\x32\
+\x32\x2e\x32\x38\x36\x2c\x35\x38\x2e\x34\x37\x34\x2d\x34\x39\x2e\
+\x34\x38\x39\x2c\x36\x32\x2e\x36\x38\x31\x0d\x0a\x09\x09\x63\x2d\
+\x32\x2e\x37\x33\x37\x2c\x30\x2e\x34\x32\x34\x2d\x35\x2e\x34\x38\
+\x33\x2c\x30\x2e\x36\x34\x36\x2d\x38\x2e\x33\x30\x31\x2c\x30\x2e\
+\x36\x34\x36\x48\x32\x30\x36\x2e\x33\x35\x31\x63\x2d\x34\x2e\x35\
+\x31\x38\x2c\x30\x2d\x38\x2e\x39\x30\x34\x2c\x30\x2e\x35\x38\x34\
+\x2d\x31\x33\x2e\x30\x34\x39\x2c\x31\x2e\x36\x37\x32\x43\x31\x37\
+\x34\x2e\x31\x38\x2c\x32\x37\x30\x2e\x36\x38\x39\x2c\x31\x36\x30\
+\x2c\x32\x38\x36\x2e\x36\x2c\x31\x36\x30\x2c\x33\x30\x37\x2e\x32\
+\x33\x36\x76\x33\x32\x2e\x39\x32\x32\x0d\x0a\x09\x09\x76\x35\x34\
+\x2e\x33\x30\x35\x63\x30\x2c\x32\x34\x2e\x38\x33\x32\x2c\x32\x34\
+\x2e\x39\x37\x37\x2c\x33\x39\x2e\x34\x32\x36\x2c\x34\x39\x2e\x34\
+\x38\x31\x2c\x34\x36\x2e\x35\x35\x31\x63\x32\x39\x2e\x33\x32\x37\
+\x2c\x38\x2e\x35\x33\x31\x2c\x36\x31\x2e\x32\x36\x37\x2c\x31\x30\
+\x2e\x30\x36\x38\x2c\x39\x36\x2e\x33\x36\x36\x2c\x30\x43\x33\x32\
+\x39\x2e\x31\x35\x2c\x34\x33\x34\x2e\x33\x35\x34\x2c\x33\x35\x32\
+\x2c\x34\x32\x30\x2e\x38\x39\x33\x2c\x33\x35\x32\x2c\x33\x39\x34\
+\x2e\x34\x36\x33\x56\x33\x36\x38\x0d\x0a\x09\x09\x68\x2d\x39\x36\
+\x76\x2d\x31\x36\x68\x31\x32\x37\x2e\x31\x38\x63\x32\x35\x2e\x32\
+\x34\x2c\x30\x2c\x34\x37\x2e\x31\x30\x37\x2d\x32\x31\x2e\x33\x36\
+\x35\x2c\x35\x37\x2e\x38\x31\x34\x2d\x35\x32\x2e\x35\x34\x39\x43\
+\x34\x34\x35\x2e\x34\x37\x34\x2c\x32\x38\x36\x2e\x34\x30\x34\x2c\
+\x34\x34\x38\x2c\x32\x37\x31\x2e\x36\x34\x31\x2c\x34\x34\x38\x2c\
+\x32\x35\x36\x0d\x0a\x09\x09\x43\x34\x34\x38\x2c\x32\x34\x34\x2e\
+\x32\x33\x32\x2c\x34\x34\x36\x2e\x35\x36\x37\x2c\x32\x33\x32\x2e\
+\x39\x36\x32\x2c\x34\x34\x33\x2e\x39\x35\x31\x2c\x32\x32\x32\x2e\
+\x35\x34\x33\x7a\x20\x4d\x33\x30\x37\x2e\x38\x36\x37\x2c\x33\x38\
+\x32\x2e\x38\x32\x63\x39\x2e\x35\x39\x2c\x30\x2c\x31\x37\x2e\x33\
+\x38\x31\x2c\x37\x2e\x37\x38\x35\x2c\x31\x37\x2e\x33\x38\x31\x2c\
+\x31\x37\x2e\x34\x0d\x0a\x09\x09\x63\x30\x2c\x39\x2e\x36\x35\x2d\
+\x37\x2e\x37\x39\x31\x2c\x31\x37\x2e\x35\x32\x31\x2d\x31\x37\x2e\
+\x33\x38\x31\x2c\x31\x37\x2e\x35\x32\x31\x63\x2d\x39\x2e\x35\x37\
+\x37\x2c\x30\x2d\x31\x37\x2e\x33\x39\x39\x2d\x37\x2e\x38\x37\x31\
+\x2d\x31\x37\x2e\x33\x39\x39\x2d\x31\x37\x2e\x35\x32\x31\x43\x32\
+\x39\x30\x2e\x34\x36\x38\x2c\x33\x39\x30\x2e\x35\x39\x2c\x32\x39\
+\x38\x2e\x32\x37\x34\x2c\x33\x38\x32\x2e\x38\x32\x2c\x33\x30\x37\
+\x2e\x38\x36\x37\x2c\x33\x38\x32\x2e\x38\x32\x7a\x22\x2f\x3e\x0d\
+\x0a\x3c\x2f\x67\x3e\x0d\x0a\x3c\x2f\x73\x76\x67\x3e\x0d\x0a\
+\x00\x00\x03\xe6\
+\x3c\
+\x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\
+\x30\x22\x20\x65\x6e\x63\x6f\x64\x69\x6e\x67\x3d\x22\x75\x74\x66\
+\x2d\x38\x22\x3f\x3e\x0d\x0a\x3c\x21\x2d\x2d\x20\x47\x65\x6e\x65\
+\x72\x61\x74\x6f\x72\x3a\x20\x41\x64\x6f\x62\x65\x20\x49\x6c\x6c\
+\x75\x73\x74\x72\x61\x74\x6f\x72\x20\x31\x38\x2e\x31\x2e\x31\x2c\
+\x20\x53\x56\x47\x20\x45\x78\x70\x6f\x72\x74\x20\x50\x6c\x75\x67\
+\x2d\x49\x6e\x20\x2e\x20\x53\x56\x47\x20\x56\x65\x72\x73\x69\x6f\
+\x6e\x3a\x20\x36\x2e\x30\x30\x20\x42\x75\x69\x6c\x64\x20\x30\x29\
+\x20\x20\x2d\x2d\x3e\x0d\x0a\x3c\x21\x44\x4f\x43\x54\x59\x50\x45\
+\x20\x73\x76\x67\x20\x50\x55\x42\x4c\x49\x43\x20\x22\x2d\x2f\x2f\
+\x57\x33\x43\x2f\x2f\x44\x54\x44\x20\x53\x56\x47\x20\x31\x2e\x31\
+\x2f\x2f\x45\x4e\x22\x20\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\
+\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x47\x72\x61\x70\x68\x69\x63\
+\x73\x2f\x53\x56\x47\x2f\x31\x2e\x31\x2f\x44\x54\x44\x2f\x73\x76\
+\x67\x31\x31\x2e\x64\x74\x64\x22\x3e\x0d\x0a\x3c\x73\x76\x67\x20\
+\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\x31\x22\x20\x69\x64\
+\x3d\x22\x43\x68\x65\x76\x72\x6f\x6e\x5f\x63\x69\x72\x63\x6c\x65\
+\x64\x5f\x72\x69\x67\x68\x74\x22\x20\x78\x6d\x6c\x6e\x73\x3d\x22\
+\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\
+\x67\x2f\x32\x30\x30\x30\x2f\x73\x76\x67\x22\x20\x78\x6d\x6c\x6e\
+\x73\x3a\x78\x6c\x69\x6e\x6b\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\
+\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x31\x39\x39\x39\x2f\
+\x78\x6c\x69\x6e\x6b\x22\x0d\x0a\x09\x20\x78\x3d\x22\x30\x70\x78\
+\x22\x20\x79\x3d\x22\x30\x70\x78\x22\x20\x76\x69\x65\x77\x42\x6f\
+\x78\x3d\x22\x30\x20\x30\x20\x35\x31\x32\x20\x35\x31\x32\x22\x20\
+\x65\x6e\x61\x62\x6c\x65\x2d\x62\x61\x63\x6b\x67\x72\x6f\x75\x6e\
+\x64\x3d\x22\x6e\x65\x77\x20\x30\x20\x30\x20\x35\x31\x32\x20\x35\
+\x31\x32\x22\x20\x78\x6d\x6c\x3a\x73\x70\x61\x63\x65\x3d\x22\x70\
+\x72\x65\x73\x65\x72\x76\x65\x22\x3e\x0d\x0a\x3c\x67\x20\x74\x72\
+\x61\x6e\x73\x66\x6f\x72\x6d\x3d\x27\x6d\x61\x74\x72\x69\x78\x28\
+\x32\x34\x20\x30\x20\x30\x20\x32\x34\x20\x30\x20\x30\x29\x27\x3e\
+\x0d\x0a\x3c\x70\x61\x74\x68\x20\x64\x3d\x22\x4d\x31\x31\x2c\x31\
+\x30\x4c\x38\x2e\x36\x39\x38\x2c\x37\x2e\x34\x39\x34\x63\x2d\x30\
+\x2e\x31\x39\x36\x2d\x30\x2e\x31\x39\x38\x2d\x30\x2e\x31\x39\x36\
+\x2d\x30\x2e\x35\x31\x39\x2c\x30\x2d\x30\x2e\x37\x31\x38\x63\x30\
+\x2e\x31\x39\x36\x2d\x30\x2e\x31\x39\x37\x2c\x30\x2e\x35\x31\x35\
+\x2d\x30\x2e\x31\x39\x37\x2c\x30\x2e\x37\x31\x2c\x30\x6c\x32\x2e\
+\x38\x30\x37\x2c\x32\x2e\x38\x36\x34\x0d\x0a\x09\x63\x30\x2e\x31\
+\x39\x36\x2c\x30\x2e\x31\x39\x39\x2c\x30\x2e\x31\x39\x36\x2c\x30\
+\x2e\x35\x32\x2c\x30\x2c\x30\x2e\x37\x31\x37\x6c\x2d\x32\x2e\x38\
+\x30\x37\x2c\x32\x2e\x38\x36\x34\x63\x2d\x30\x2e\x31\x39\x35\x2c\
+\x30\x2e\x31\x39\x39\x2d\x30\x2e\x35\x31\x34\x2c\x30\x2e\x31\x39\
+\x38\x2d\x30\x2e\x37\x31\x2c\x30\x63\x2d\x30\x2e\x31\x39\x36\x2d\
+\x30\x2e\x31\x39\x37\x2d\x30\x2e\x31\x39\x36\x2d\x30\x2e\x35\x31\
+\x38\x2c\x30\x2d\x30\x2e\x37\x31\x37\x4c\x31\x31\x2c\x31\x30\x7a\
+\x20\x4d\x31\x30\x2c\x30\x2e\x34\x0d\x0a\x09\x63\x35\x2e\x33\x30\
+\x32\x2c\x30\x2c\x39\x2e\x36\x2c\x34\x2e\x32\x39\x38\x2c\x39\x2e\
+\x36\x2c\x39\x2e\x36\x63\x30\x2c\x35\x2e\x33\x30\x33\x2d\x34\x2e\
+\x32\x39\x38\x2c\x39\x2e\x36\x2d\x39\x2e\x36\x2c\x39\x2e\x36\x53\
+\x30\x2e\x34\x2c\x31\x35\x2e\x33\x30\x33\x2c\x30\x2e\x34\x2c\x31\
+\x30\x43\x30\x2e\x34\x2c\x34\x2e\x36\x39\x38\x2c\x34\x2e\x36\x39\
+\x38\x2c\x30\x2e\x34\x2c\x31\x30\x2c\x30\x2e\x34\x7a\x20\x4d\x31\
+\x30\x2c\x31\x38\x2e\x33\x35\x34\x0d\x0a\x09\x63\x34\x2e\x36\x31\
+\x33\x2c\x30\x2c\x38\x2e\x33\x35\x34\x2d\x33\x2e\x37\x34\x2c\x38\
+\x2e\x33\x35\x34\x2d\x38\x2e\x33\x35\x34\x63\x30\x2d\x34\x2e\x36\
+\x31\x34\x2d\x33\x2e\x37\x34\x31\x2d\x38\x2e\x33\x35\x34\x2d\x38\
+\x2e\x33\x35\x34\x2d\x38\x2e\x33\x35\x34\x63\x2d\x34\x2e\x36\x31\
+\x35\x2c\x30\x2d\x38\x2e\x33\x35\x34\x2c\x33\x2e\x37\x34\x2d\x38\
+\x2e\x33\x35\x34\x2c\x38\x2e\x33\x35\x34\x0d\x0a\x09\x43\x31\x2e\
+\x36\x34\x35\x2c\x31\x34\x2e\x36\x31\x34\x2c\x35\x2e\x33\x38\x35\
+\x2c\x31\x38\x2e\x33\x35\x34\x2c\x31\x30\x2c\x31\x38\x2e\x33\x35\
+\x34\x7a\x22\x2f\x3e\x0d\x0a\x3c\x2f\x67\x3e\x0d\x0a\x3c\x2f\x73\
+\x76\x67\x3e\x0d\x0a\
+\x00\x00\x03\x4c\
+\x3c\
+\x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\
+\x30\x22\x20\x65\x6e\x63\x6f\x64\x69\x6e\x67\x3d\x22\x75\x74\x66\
+\x2d\x38\x22\x3f\x3e\x0d\x0a\x3c\x21\x2d\x2d\x20\x47\x65\x6e\x65\
+\x72\x61\x74\x6f\x72\x3a\x20\x41\x64\x6f\x62\x65\x20\x49\x6c\x6c\
+\x75\x73\x74\x72\x61\x74\x6f\x72\x20\x31\x36\x2e\x32\x2e\x31\x2c\
+\x20\x53\x56\x47\x20\x45\x78\x70\x6f\x72\x74\x20\x50\x6c\x75\x67\
+\x2d\x49\x6e\x20\x2e\x20\x53\x56\x47\x20\x56\x65\x72\x73\x69\x6f\
+\x6e\x3a\x20\x36\x2e\x30\x30\x20\x42\x75\x69\x6c\x64\x20\x30\x29\
+\x20\x20\x2d\x2d\x3e\x0d\x0a\x3c\x21\x44\x4f\x43\x54\x59\x50\x45\
+\x20\x73\x76\x67\x20\x50\x55\x42\x4c\x49\x43\x20\x22\x2d\x2f\x2f\
+\x57\x33\x43\x2f\x2f\x44\x54\x44\x20\x53\x56\x47\x20\x31\x2e\x31\
+\x2f\x2f\x45\x4e\x22\x20\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\
+\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x47\x72\x61\x70\x68\x69\x63\
+\x73\x2f\x53\x56\x47\x2f\x31\x2e\x31\x2f\x44\x54\x44\x2f\x73\x76\
+\x67\x31\x31\x2e\x64\x74\x64\x22\x3e\x0d\x0a\x3c\x73\x76\x67\x20\
+\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\x31\x22\x20\x69\x64\
+\x3d\x22\x4c\x61\x79\x65\x72\x5f\x31\x22\x20\x78\x6d\x6c\x6e\x73\
+\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\
+\x6f\x72\x67\x2f\x32\x30\x30\x30\x2f\x73\x76\x67\x22\x20\x78\x6d\
+\x6c\x6e\x73\x3a\x78\x6c\x69\x6e\x6b\x3d\x22\x68\x74\x74\x70\x3a\
+\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x31\x39\x39\
+\x39\x2f\x78\x6c\x69\x6e\x6b\x22\x20\x78\x3d\x22\x30\x70\x78\x22\
+\x20\x79\x3d\x22\x30\x70\x78\x22\x0d\x0a\x09\x20\x77\x69\x64\x74\
+\x68\x3d\x22\x35\x31\x32\x70\x78\x22\x20\x68\x65\x69\x67\x68\x74\
+\x3d\x22\x35\x31\x32\x70\x78\x22\x20\x76\x69\x65\x77\x42\x6f\x78\
+\x3d\x22\x30\x20\x30\x20\x35\x31\x32\x20\x35\x31\x32\x22\x20\x65\
+\x6e\x61\x62\x6c\x65\x2d\x62\x61\x63\x6b\x67\x72\x6f\x75\x6e\x64\
+\x3d\x22\x6e\x65\x77\x20\x30\x20\x30\x20\x35\x31\x32\x20\x35\x31\
+\x32\x22\x20\x78\x6d\x6c\x3a\x73\x70\x61\x63\x65\x3d\x22\x70\x72\
 \x65\x73\x65\x72\x76\x65\x22\x3e\x0d\x0a\x3c\x67\x20\x69\x64\x3d\
-\x22\x49\x63\x6f\x6e\x5f\x32\x30\x5f\x22\x3e\x0d\x0a\x09\x3c\x67\
+\x22\x49\x63\x6f\x6e\x5f\x32\x31\x5f\x22\x3e\x0d\x0a\x09\x3c\x67\
 \x3e\x0d\x0a\x09\x09\x3c\x70\x61\x74\x68\x20\x64\x3d\x22\x4d\x32\
-\x35\x36\x2c\x34\x38\x43\x31\x34\x31\x2e\x36\x30\x31\x2c\x34\x38\
-\x2c\x34\x38\x2c\x31\x34\x31\x2e\x36\x30\x31\x2c\x34\x38\x2c\x32\
-\x35\x36\x73\x39\x33\x2e\x36\x30\x31\x2c\x32\x30\x38\x2c\x32\x30\
-\x38\x2c\x32\x30\x38\x73\x32\x30\x38\x2d\x39\x33\x2e\x36\x30\x31\
-\x2c\x32\x30\x38\x2d\x32\x30\x38\x53\x33\x37\x30\x2e\x33\x39\x39\
-\x2c\x34\x38\x2c\x32\x35\x36\x2c\x34\x38\x7a\x20\x4d\x32\x35\x36\
-\x2c\x34\x32\x32\x2e\x33\x39\x39\x0d\x0a\x09\x09\x09\x63\x2d\x39\
-\x31\x2e\x35\x31\x38\x2c\x30\x2d\x31\x36\x36\x2e\x33\x39\x39\x2d\
-\x37\x34\x2e\x38\x38\x32\x2d\x31\x36\x36\x2e\x33\x39\x39\x2d\x31\
-\x36\x36\x2e\x33\x39\x39\x53\x31\x36\x34\x2e\x34\x38\x32\x2c\x38\
-\x39\x2e\x36\x2c\x32\x35\x36\x2c\x38\x39\x2e\x36\x53\x34\x32\x32\
-\x2e\x34\x2c\x31\x36\x34\x2e\x34\x38\x32\x2c\x34\x32\x32\x2e\x34\
-\x2c\x32\x35\x36\x53\x33\x34\x37\x2e\x35\x31\x38\x2c\x34\x32\x32\
-\x2e\x33\x39\x39\x2c\x32\x35\x36\x2c\x34\x32\x32\x2e\x33\x39\x39\
+\x35\x36\x2c\x31\x35\x32\x63\x2d\x35\x37\x2e\x32\x2c\x30\x2d\x31\
+\x30\x34\x2c\x34\x36\x2e\x38\x2d\x31\x30\x34\x2c\x31\x30\x34\x73\
+\x34\x36\x2e\x38\x2c\x31\x30\x34\x2c\x31\x30\x34\x2c\x31\x30\x34\
+\x73\x31\x30\x34\x2d\x34\x36\x2e\x38\x2c\x31\x30\x34\x2d\x31\x30\
+\x34\x53\x33\x31\x33\x2e\x32\x2c\x31\x35\x32\x2c\x32\x35\x36\x2c\
+\x31\x35\x32\x7a\x20\x4d\x32\x35\x36\x2c\x34\x38\x0d\x0a\x09\x09\
+\x09\x43\x31\x34\x31\x2e\x36\x30\x31\x2c\x34\x38\x2c\x34\x38\x2c\
+\x31\x34\x31\x2e\x36\x30\x31\x2c\x34\x38\x2c\x32\x35\x36\x73\x39\
+\x33\x2e\x36\x30\x31\x2c\x32\x30\x38\x2c\x32\x30\x38\x2c\x32\x30\
+\x38\x73\x32\x30\x38\x2d\x39\x33\x2e\x36\x30\x31\x2c\x32\x30\x38\
+\x2d\x32\x30\x38\x53\x33\x37\x30\x2e\x33\x39\x39\x2c\x34\x38\x2c\
+\x32\x35\x36\x2c\x34\x38\x7a\x20\x4d\x32\x35\x36\x2c\x34\x32\x32\
+\x2e\x34\x0d\x0a\x09\x09\x09\x63\x2d\x39\x31\x2e\x35\x31\x38\x2c\
+\x30\x2d\x31\x36\x36\x2e\x34\x2d\x37\x34\x2e\x38\x38\x33\x2d\x31\
+\x36\x36\x2e\x34\x2d\x31\x36\x36\x2e\x34\x53\x31\x36\x34\x2e\x34\
+\x38\x32\x2c\x38\x39\x2e\x36\x2c\x32\x35\x36\x2c\x38\x39\x2e\x36\
+\x53\x34\x32\x32\x2e\x34\x2c\x31\x36\x34\x2e\x34\x38\x32\x2c\x34\
+\x32\x32\x2e\x34\x2c\x32\x35\x36\x53\x33\x34\x37\x2e\x35\x31\x38\
+\x2c\x34\x32\x32\x2e\x34\x2c\x32\x35\x36\x2c\x34\x32\x32\x2e\x34\
 \x7a\x22\x2f\x3e\x0d\x0a\x09\x3c\x2f\x67\x3e\x0d\x0a\x3c\x2f\x67\
 \x3e\x0d\x0a\x3c\x2f\x73\x76\x67\x3e\x0d\x0a\
-\x00\x00\x01\xdd\
-\x00\
-\x00\x06\xe4\x78\x9c\xcd\x54\x4d\x6f\x9b\x40\x10\x3d\x13\x29\xff\
-\x61\xba\xb7\x4a\xec\x17\xc4\xd4\xa6\xa6\x51\xfd\x21\xcb\x52\x9a\
-\x58\x6a\xea\xaa\xa7\x0a\xc3\x16\x50\x28\x20\x58\xc0\xce\xaf\xef\
-\xee\x92\x54\x51\x95\xfa\x18\xfb\xb0\x33\xda\x79\x6f\xde\xbc\x65\
-\x24\xa6\xd7\xfb\xdf\x39\x74\xa2\x6e\xb2\xb2\x08\x10\x27\x0c\x81\
-\x28\xa2\x32\xce\x8a\x24\x40\xad\xfc\x85\xc7\xe8\xfa\xd3\xe5\xc5\
-\xf4\x1d\xc6\xb0\x12\x85\xa8\x43\x59\xd6\x3e\x7c\x8e\xcb\x9d\x80\
-\x75\x9e\xb7\x8d\x34\x25\xe0\x1e\x71\x08\xb7\xe1\xeb\x76\x05\xcb\
-\x7d\x55\xd6\x12\x36\x79\x9b\xe0\x75\x01\xc4\x14\xb7\xc3\x10\x1f\
-\x3c\xc2\x18\xcc\xda\x2c\x8f\x81\xbd\x07\xc0\xd8\xe8\x2f\xee\xe6\
-\xf7\x3f\x36\x4b\x68\xba\x04\x36\xdf\x66\x37\xeb\x39\x20\x4c\xe9\
-\x77\x77\x4e\xe9\xe2\x7e\x61\x24\x38\xe1\x94\x2e\x6f\x11\xa0\x54\
-\xca\xca\xa7\xb4\xef\x7b\xd2\xbb\xa4\xac\x13\xba\xaa\xc3\x2a\xcd\
-\xa2\x86\x2a\x22\xd5\x44\xd5\x44\x95\x18\xe7\x24\x96\x31\xd2\x33\
-\xb4\xf4\x8b\xa7\x72\x04\x59\x1c\xa0\x9b\xf0\x20\xea\x9f\xea\xa2\
-\xbe\x44\xd1\x04\xaf\x48\x3b\x8c\x31\x2d\xf5\x44\xf1\xf7\x79\x56\
-\x3c\xbc\x46\xe4\x93\xc9\x84\x1a\x54\x51\x03\xc4\xaa\x3d\x82\xc3\
-\x90\x2f\x2f\x2c\xe8\xb3\x58\xa6\x01\x1a\x71\x47\x03\xa9\xc8\x92\
-\x54\xfe\xbd\x76\x99\xe8\x67\xa5\xee\x02\x06\xaa\xa6\x0f\x82\x46\
-\x1e\x72\x11\x20\x51\x84\xbb\x5c\xe0\x5d\x18\x3d\x24\x75\xd9\x16\
-\xb1\x5f\x88\x1e\x5e\x30\x3f\x1a\x6f\x7e\x53\x85\x91\xa2\x57\xb5\
-\x68\x44\xdd\x09\xf3\xea\x44\x05\x6b\x88\xd6\xb4\x0a\x65\x0a\xea\
-\xd1\x5f\xb8\xc7\x6c\x3e\x72\x89\x1b\x31\xdb\x25\x1f\xb0\x6b\x7b\
-\x2a\xaa\xa3\x73\x8a\x47\x8c\x8c\x22\xac\x00\x9b\xe9\x22\x76\xf1\
-\x13\xdc\x0d\x10\x33\x98\xfb\xdc\xa0\x73\x6a\x00\xd3\xa2\x4b\xb6\
-\x51\xd4\x67\x6b\xe6\x3c\xea\x4f\x60\x59\xf4\x1f\x1f\xce\x78\x7c\
-\x16\x3e\xae\xb8\x77\x3a\x1f\x53\xfa\xff\x25\x39\x63\xfe\x26\xa6\
-\xcc\x9c\x23\x4b\x3a\x07\x1f\x7a\x49\x27\xf3\x71\x6c\x49\x57\x6c\
-\xf2\x26\xa6\xcc\x9c\x23\x4b\x3a\x07\x1f\x7a\x49\x27\xf3\x31\x2c\
-\xe9\x39\xaa\x7f\xb6\xca\x7f\x00\x99\x18\x96\x19\
-\x00\x00\x04\x1c\
+\x00\x00\x03\x22\
 \x3c\
+\x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\
+\x30\x22\x20\x65\x6e\x63\x6f\x64\x69\x6e\x67\x3d\x22\x75\x74\x66\
+\x2d\x38\x22\x3f\x3e\x0d\x0a\x3c\x21\x2d\x2d\x20\x47\x65\x6e\x65\
+\x72\x61\x74\x6f\x72\x3a\x20\x41\x64\x6f\x62\x65\x20\x49\x6c\x6c\
+\x75\x73\x74\x72\x61\x74\x6f\x72\x20\x31\x36\x2e\x32\x2e\x31\x2c\
+\x20\x53\x56\x47\x20\x45\x78\x70\x6f\x72\x74\x20\x50\x6c\x75\x67\
+\x2d\x49\x6e\x20\x2e\x20\x53\x56\x47\x20\x56\x65\x72\x73\x69\x6f\
+\x6e\x3a\x20\x36\x2e\x30\x30\x20\x42\x75\x69\x6c\x64\x20\x30\x29\
+\x20\x20\x2d\x2d\x3e\x0d\x0a\x3c\x21\x44\x4f\x43\x54\x59\x50\x45\
+\x20\x73\x76\x67\x20\x50\x55\x42\x4c\x49\x43\x20\x22\x2d\x2f\x2f\
+\x57\x33\x43\x2f\x2f\x44\x54\x44\x20\x53\x56\x47\x20\x31\x2e\x31\
+\x2f\x2f\x45\x4e\x22\x20\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\
+\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x47\x72\x61\x70\x68\x69\x63\
+\x73\x2f\x53\x56\x47\x2f\x31\x2e\x31\x2f\x44\x54\x44\x2f\x73\x76\
+\x67\x31\x31\x2e\x64\x74\x64\x22\x3e\x0d\x0a\x3c\x73\x76\x67\x20\
+\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\x31\x22\x20\x69\x64\
+\x3d\x22\x4c\x61\x79\x65\x72\x5f\x31\x22\x20\x78\x6d\x6c\x6e\x73\
+\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\
+\x6f\x72\x67\x2f\x32\x30\x30\x30\x2f\x73\x76\x67\x22\x20\x78\x6d\
+\x6c\x6e\x73\x3a\x78\x6c\x69\x6e\x6b\x3d\x22\x68\x74\x74\x70\x3a\
+\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x31\x39\x39\
+\x39\x2f\x78\x6c\x69\x6e\x6b\x22\x20\x78\x3d\x22\x30\x70\x78\x22\
+\x20\x79\x3d\x22\x30\x70\x78\x22\x0d\x0a\x09\x20\x77\x69\x64\x74\
+\x68\x3d\x22\x35\x31\x32\x70\x78\x22\x20\x68\x65\x69\x67\x68\x74\
+\x3d\x22\x35\x31\x32\x70\x78\x22\x20\x76\x69\x65\x77\x42\x6f\x78\
+\x3d\x22\x30\x20\x30\x20\x35\x31\x32\x20\x35\x31\x32\x22\x20\x65\
+\x6e\x61\x62\x6c\x65\x2d\x62\x61\x63\x6b\x67\x72\x6f\x75\x6e\x64\
+\x3d\x22\x6e\x65\x77\x20\x30\x20\x30\x20\x35\x31\x32\x20\x35\x31\
+\x32\x22\x20\x78\x6d\x6c\x3a\x73\x70\x61\x63\x65\x3d\x22\x70\x72\
+\x65\x73\x65\x72\x76\x65\x22\x3e\x0d\x0a\x3c\x67\x3e\x0d\x0a\x09\
+\x3c\x63\x69\x72\x63\x6c\x65\x20\x63\x78\x3d\x22\x32\x35\x36\x22\
+\x20\x63\x79\x3d\x22\x32\x38\x30\x22\x20\x72\x3d\x22\x36\x33\x22\
+\x2f\x3e\x0d\x0a\x09\x3c\x70\x61\x74\x68\x20\x64\x3d\x22\x4d\x34\
+\x34\x30\x2c\x39\x36\x68\x2d\x38\x38\x6c\x2d\x33\x32\x2d\x33\x32\
+\x48\x31\x39\x32\x6c\x2d\x33\x32\x2c\x33\x32\x48\x37\x32\x63\x2d\
+\x32\x32\x2e\x30\x39\x32\x2c\x30\x2d\x34\x30\x2c\x31\x37\x2e\x39\
+\x30\x38\x2d\x34\x30\x2c\x34\x30\x76\x32\x37\x32\x63\x30\x2c\x32\
+\x32\x2e\x30\x39\x32\x2c\x31\x37\x2e\x39\x30\x38\x2c\x34\x30\x2c\
+\x34\x30\x2c\x34\x30\x68\x33\x36\x38\x63\x32\x32\x2e\x30\x39\x32\
+\x2c\x30\x2c\x34\x30\x2d\x31\x37\x2e\x39\x30\x38\x2c\x34\x30\x2d\
+\x34\x30\x0d\x0a\x09\x09\x56\x31\x33\x36\x43\x34\x38\x30\x2c\x31\
+\x31\x33\x2e\x39\x30\x38\x2c\x34\x36\x32\x2e\x30\x39\x32\x2c\x39\
+\x36\x2c\x34\x34\x30\x2c\x39\x36\x7a\x20\x4d\x32\x35\x36\x2c\x33\
+\x39\x32\x63\x2d\x36\x31\x2e\x38\x35\x35\x2c\x30\x2d\x31\x31\x32\
+\x2d\x35\x30\x2e\x31\x34\x35\x2d\x31\x31\x32\x2d\x31\x31\x32\x73\
+\x35\x30\x2e\x31\x34\x35\x2d\x31\x31\x32\x2c\x31\x31\x32\x2d\x31\
+\x31\x32\x73\x31\x31\x32\x2c\x35\x30\x2e\x31\x34\x35\x2c\x31\x31\
+\x32\x2c\x31\x31\x32\x0d\x0a\x09\x09\x53\x33\x31\x37\x2e\x38\x35\
+\x35\x2c\x33\x39\x32\x2c\x32\x35\x36\x2c\x33\x39\x32\x7a\x22\x2f\
+\x3e\x0d\x0a\x3c\x2f\x67\x3e\x0d\x0a\x3c\x2f\x73\x76\x67\x3e\x0d\
+\x0a\
+\x00\x00\x03\xf5\
+\x3c\
+\x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\
+\x30\x22\x20\x65\x6e\x63\x6f\x64\x69\x6e\x67\x3d\x22\x75\x74\x66\
+\x2d\x38\x22\x3f\x3e\x0d\x0a\x3c\x21\x2d\x2d\x20\x47\x65\x6e\x65\
+\x72\x61\x74\x6f\x72\x3a\x20\x41\x64\x6f\x62\x65\x20\x49\x6c\x6c\
+\x75\x73\x74\x72\x61\x74\x6f\x72\x20\x31\x38\x2e\x31\x2e\x31\x2c\
+\x20\x53\x56\x47\x20\x45\x78\x70\x6f\x72\x74\x20\x50\x6c\x75\x67\
+\x2d\x49\x6e\x20\x2e\x20\x53\x56\x47\x20\x56\x65\x72\x73\x69\x6f\
+\x6e\x3a\x20\x36\x2e\x30\x30\x20\x42\x75\x69\x6c\x64\x20\x30\x29\
+\x20\x20\x2d\x2d\x3e\x0d\x0a\x3c\x21\x44\x4f\x43\x54\x59\x50\x45\
+\x20\x73\x76\x67\x20\x50\x55\x42\x4c\x49\x43\x20\x22\x2d\x2f\x2f\
+\x57\x33\x43\x2f\x2f\x44\x54\x44\x20\x53\x56\x47\x20\x31\x2e\x31\
+\x2f\x2f\x45\x4e\x22\x20\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\
+\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x47\x72\x61\x70\x68\x69\x63\
+\x73\x2f\x53\x56\x47\x2f\x31\x2e\x31\x2f\x44\x54\x44\x2f\x73\x76\
+\x67\x31\x31\x2e\x64\x74\x64\x22\x3e\x0d\x0a\x3c\x73\x76\x67\x20\
+\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\x31\x22\x20\x69\x64\
+\x3d\x22\x43\x68\x65\x76\x72\x6f\x6e\x5f\x63\x69\x72\x63\x6c\x65\
+\x64\x5f\x6c\x65\x66\x74\x22\x20\x78\x6d\x6c\x6e\x73\x3d\x22\x68\
+\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\x67\
+\x2f\x32\x30\x30\x30\x2f\x73\x76\x67\x22\x20\x78\x6d\x6c\x6e\x73\
+\x3a\x78\x6c\x69\x6e\x6b\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\
+\x77\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x31\x39\x39\x39\x2f\x78\
+\x6c\x69\x6e\x6b\x22\x0d\x0a\x09\x20\x78\x3d\x22\x30\x70\x78\x22\
+\x20\x79\x3d\x22\x30\x70\x78\x22\x20\x76\x69\x65\x77\x42\x6f\x78\
+\x3d\x22\x30\x20\x30\x20\x35\x31\x32\x20\x35\x31\x32\x22\x20\x65\
+\x6e\x61\x62\x6c\x65\x2d\x62\x61\x63\x6b\x67\x72\x6f\x75\x6e\x64\
+\x3d\x22\x6e\x65\x77\x20\x30\x20\x30\x20\x35\x31\x32\x20\x35\x31\
+\x32\x22\x20\x78\x6d\x6c\x3a\x73\x70\x61\x63\x65\x3d\x22\x70\x72\
+\x65\x73\x65\x72\x76\x65\x22\x3e\x0d\x0a\x3c\x67\x20\x74\x72\x61\
+\x6e\x73\x66\x6f\x72\x6d\x3d\x27\x6d\x61\x74\x72\x69\x78\x28\x32\
+\x34\x20\x30\x20\x30\x20\x32\x34\x20\x30\x20\x30\x29\x27\x3e\x0d\
+\x0a\x3c\x70\x61\x74\x68\x20\x64\x3d\x22\x4d\x31\x31\x2e\x33\x30\
+\x32\x2c\x36\x2e\x37\x37\x36\x63\x2d\x30\x2e\x31\x39\x36\x2d\x30\
+\x2e\x31\x39\x37\x2d\x30\x2e\x35\x31\x35\x2d\x30\x2e\x31\x39\x37\
+\x2d\x30\x2e\x37\x31\x2c\x30\x4c\x37\x2e\x37\x38\x35\x2c\x39\x2e\
+\x36\x34\x31\x63\x2d\x30\x2e\x31\x39\x36\x2c\x30\x2e\x31\x39\x39\
+\x2d\x30\x2e\x31\x39\x36\x2c\x30\x2e\x35\x32\x2c\x30\x2c\x30\x2e\
+\x37\x31\x37\x6c\x32\x2e\x38\x30\x37\x2c\x32\x2e\x38\x36\x34\x0d\
+\x0a\x09\x63\x30\x2e\x31\x39\x35\x2c\x30\x2e\x31\x39\x39\x2c\x30\
+\x2e\x35\x31\x34\x2c\x30\x2e\x31\x39\x38\x2c\x30\x2e\x37\x31\x2c\
+\x30\x63\x30\x2e\x31\x39\x36\x2d\x30\x2e\x31\x39\x37\x2c\x30\x2e\
+\x31\x39\x36\x2d\x30\x2e\x35\x31\x38\x2c\x30\x2d\x30\x2e\x37\x31\
+\x37\x4c\x39\x2c\x31\x30\x6c\x32\x2e\x33\x30\x32\x2d\x32\x2e\x35\
+\x30\x36\x43\x31\x31\x2e\x34\x39\x38\x2c\x37\x2e\x32\x39\x36\x2c\
+\x31\x31\x2e\x34\x39\x38\x2c\x36\x2e\x39\x37\x36\x2c\x31\x31\x2e\
+\x33\x30\x32\x2c\x36\x2e\x37\x37\x36\x7a\x0d\x0a\x09\x20\x4d\x31\
+\x30\x2c\x30\x2e\x34\x63\x2d\x35\x2e\x33\x30\x32\x2c\x30\x2d\x39\
+\x2e\x36\x2c\x34\x2e\x32\x39\x38\x2d\x39\x2e\x36\x2c\x39\x2e\x36\
+\x63\x30\x2c\x35\x2e\x33\x30\x33\x2c\x34\x2e\x32\x39\x38\x2c\x39\
+\x2e\x36\x2c\x39\x2e\x36\x2c\x39\x2e\x36\x73\x39\x2e\x36\x2d\x34\
+\x2e\x32\x39\x37\x2c\x39\x2e\x36\x2d\x39\x2e\x36\x43\x31\x39\x2e\
+\x36\x2c\x34\x2e\x36\x39\x38\x2c\x31\x35\x2e\x33\x30\x32\x2c\x30\
+\x2e\x34\x2c\x31\x30\x2c\x30\x2e\x34\x7a\x20\x4d\x31\x30\x2c\x31\
+\x38\x2e\x33\x35\x34\x0d\x0a\x09\x63\x2d\x34\x2e\x36\x31\x35\x2c\
+\x30\x2d\x38\x2e\x33\x35\x34\x2d\x33\x2e\x37\x34\x2d\x38\x2e\x33\
+\x35\x34\x2d\x38\x2e\x33\x35\x34\x63\x30\x2d\x34\x2e\x36\x31\x34\
+\x2c\x33\x2e\x37\x33\x39\x2d\x38\x2e\x33\x35\x34\x2c\x38\x2e\x33\
+\x35\x34\x2d\x38\x2e\x33\x35\x34\x63\x34\x2e\x36\x31\x33\x2c\x30\
+\x2c\x38\x2e\x33\x35\x34\x2c\x33\x2e\x37\x34\x2c\x38\x2e\x33\x35\
+\x34\x2c\x38\x2e\x33\x35\x34\x0d\x0a\x09\x43\x31\x38\x2e\x33\x35\
+\x34\x2c\x31\x34\x2e\x36\x31\x34\x2c\x31\x34\x2e\x36\x31\x33\x2c\
+\x31\x38\x2e\x33\x35\x34\x2c\x31\x30\x2c\x31\x38\x2e\x33\x35\x34\
+\x7a\x22\x2f\x3e\x0d\x0a\x3c\x2f\x67\x3e\x0d\x0a\x3c\x2f\x73\x76\
+\x67\x3e\x0d\x0a\
+\x00\x00\x03\x52\
+\x3c\
+\x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\
+\x30\x22\x20\x65\x6e\x63\x6f\x64\x69\x6e\x67\x3d\x22\x75\x74\x66\
+\x2d\x38\x22\x3f\x3e\x0d\x0a\x3c\x21\x2d\x2d\x20\x47\x65\x6e\x65\
+\x72\x61\x74\x6f\x72\x3a\x20\x41\x64\x6f\x62\x65\x20\x49\x6c\x6c\
+\x75\x73\x74\x72\x61\x74\x6f\x72\x20\x31\x36\x2e\x32\x2e\x31\x2c\
+\x20\x53\x56\x47\x20\x45\x78\x70\x6f\x72\x74\x20\x50\x6c\x75\x67\
+\x2d\x49\x6e\x20\x2e\x20\x53\x56\x47\x20\x56\x65\x72\x73\x69\x6f\
+\x6e\x3a\x20\x36\x2e\x30\x30\x20\x42\x75\x69\x6c\x64\x20\x30\x29\
+\x20\x20\x2d\x2d\x3e\x0d\x0a\x3c\x21\x44\x4f\x43\x54\x59\x50\x45\
+\x20\x73\x76\x67\x20\x50\x55\x42\x4c\x49\x43\x20\x22\x2d\x2f\x2f\
+\x57\x33\x43\x2f\x2f\x44\x54\x44\x20\x53\x56\x47\x20\x31\x2e\x31\
+\x2f\x2f\x45\x4e\x22\x20\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\
+\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x47\x72\x61\x70\x68\x69\x63\
+\x73\x2f\x53\x56\x47\x2f\x31\x2e\x31\x2f\x44\x54\x44\x2f\x73\x76\
+\x67\x31\x31\x2e\x64\x74\x64\x22\x3e\x0d\x0a\x3c\x73\x76\x67\x20\
+\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\x31\x22\x20\x69\x64\
+\x3d\x22\x4c\x61\x79\x65\x72\x5f\x31\x22\x20\x78\x6d\x6c\x6e\x73\
+\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\
+\x6f\x72\x67\x2f\x32\x30\x30\x30\x2f\x73\x76\x67\x22\x20\x78\x6d\
+\x6c\x6e\x73\x3a\x78\x6c\x69\x6e\x6b\x3d\x22\x68\x74\x74\x70\x3a\
+\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x31\x39\x39\
+\x39\x2f\x78\x6c\x69\x6e\x6b\x22\x20\x78\x3d\x22\x30\x70\x78\x22\
+\x20\x79\x3d\x22\x30\x70\x78\x22\x0d\x0a\x09\x20\x77\x69\x64\x74\
+\x68\x3d\x22\x35\x31\x32\x70\x78\x22\x20\x68\x65\x69\x67\x68\x74\
+\x3d\x22\x35\x31\x32\x70\x78\x22\x20\x76\x69\x65\x77\x42\x6f\x78\
+\x3d\x22\x30\x20\x30\x20\x35\x31\x32\x20\x35\x31\x32\x22\x20\x65\
+\x6e\x61\x62\x6c\x65\x2d\x62\x61\x63\x6b\x67\x72\x6f\x75\x6e\x64\
+\x3d\x22\x6e\x65\x77\x20\x30\x20\x30\x20\x35\x31\x32\x20\x35\x31\
+\x32\x22\x20\x78\x6d\x6c\x3a\x73\x70\x61\x63\x65\x3d\x22\x70\x72\
+\x65\x73\x65\x72\x76\x65\x22\x3e\x0d\x0a\x3c\x70\x61\x74\x68\x20\
+\x64\x3d\x22\x4d\x34\x33\x37\x2e\x33\x33\x34\x2c\x31\x34\x34\x48\
+\x32\x35\x36\x2e\x30\x30\x36\x6c\x2d\x34\x32\x2e\x36\x36\x38\x2d\
+\x34\x38\x48\x37\x34\x2e\x36\x36\x36\x43\x35\x31\x2e\x31\x39\x37\
+\x2c\x39\x36\x2c\x33\x32\x2c\x31\x31\x35\x2e\x31\x39\x38\x2c\x33\
+\x32\x2c\x31\x33\x38\x2e\x36\x36\x37\x76\x32\x33\x34\x2e\x36\x36\
+\x36\x43\x33\x32\x2c\x33\x39\x36\x2e\x38\x30\x32\x2c\x35\x31\x2e\
+\x31\x39\x37\x2c\x34\x31\x36\x2c\x37\x34\x2e\x36\x36\x36\x2c\x34\
+\x31\x36\x68\x33\x36\x32\x2e\x36\x36\x38\x0d\x0a\x09\x43\x34\x36\
+\x30\x2e\x38\x30\x33\x2c\x34\x31\x36\x2c\x34\x38\x30\x2c\x33\x39\
+\x36\x2e\x38\x30\x32\x2c\x34\x38\x30\x2c\x33\x37\x33\x2e\x33\x33\
+\x33\x56\x31\x38\x36\x2e\x36\x36\x37\x43\x34\x38\x30\x2c\x31\x36\
+\x33\x2e\x31\x39\x38\x2c\x34\x36\x30\x2e\x38\x30\x33\x2c\x31\x34\
+\x34\x2c\x34\x33\x37\x2e\x33\x33\x34\x2c\x31\x34\x34\x7a\x20\x4d\
+\x34\x34\x38\x2c\x33\x37\x33\x2e\x33\x33\x33\x0d\x0a\x09\x63\x30\
+\x2c\x35\x2e\x37\x38\x32\x2d\x34\x2e\x38\x38\x35\x2c\x31\x30\x2e\
+\x36\x36\x37\x2d\x31\x30\x2e\x36\x36\x36\x2c\x31\x30\x2e\x36\x36\
+\x37\x48\x37\x34\x2e\x36\x36\x36\x43\x36\x38\x2e\x38\x38\x34\x2c\
+\x33\x38\x34\x2c\x36\x34\x2c\x33\x37\x39\x2e\x31\x31\x35\x2c\x36\
+\x34\x2c\x33\x37\x33\x2e\x33\x33\x33\x56\x31\x37\x36\x68\x33\x37\
+\x33\x2e\x33\x33\x34\x63\x35\x2e\x37\x38\x31\x2c\x30\x2c\x31\x30\
+\x2e\x36\x36\x36\x2c\x34\x2e\x38\x38\x35\x2c\x31\x30\x2e\x36\x36\
+\x36\x2c\x31\x30\x2e\x36\x36\x37\x0d\x0a\x09\x56\x33\x37\x33\x2e\
+\x33\x33\x33\x7a\x22\x2f\x3e\x0d\x0a\x3c\x2f\x73\x76\x67\x3e\x0d\
+\x0a\
+\x00\x00\x03\x7c\
+\x3c\
 \x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x27\x31\x2e\
 \x30\x27\x20\x65\x6e\x63\x6f\x64\x69\x6e\x67\x3d\x27\x55\x54\x46\
 \x2d\x38\x27\x3f\x3e\x0a\x3c\x21\x2d\x2d\x20\x54\x68\x69\x73\x20\
@@ -2218,31 +1958,21 @@
 \x39\x36\x32\x36\x34\x20\x30\x20\x30\x20\x30\x2e\x39\x39\x36\x32\
 \x36\x34\x20\x35\x36\x2e\x34\x30\x39\x34\x20\x31\x31\x37\x2e\x38\
 \x35\x38\x29\x27\x3e\x0a\x3c\x70\x61\x74\x68\x20\x64\x3d\x27\x4d\
-\x20\x32\x2e\x30\x30\x37\x35\x20\x2d\x33\x32\x2e\x31\x32\x4c\x20\
-\x36\x32\x2e\x32\x33\x32\x35\x20\x2d\x33\x32\x2e\x31\x32\x27\x20\
-\x66\x69\x6c\x6c\x3d\x27\x6e\x6f\x6e\x65\x27\x20\x73\x74\x72\x6f\
-\x6b\x65\x3d\x27\x23\x30\x30\x30\x30\x30\x30\x27\x20\x73\x74\x72\
-\x6f\x6b\x65\x2d\x6c\x69\x6e\x65\x63\x61\x70\x3d\x27\x72\x6f\x75\
-\x6e\x64\x27\x20\x73\x74\x72\x6f\x6b\x65\x2d\x6c\x69\x6e\x65\x6a\
-\x6f\x69\x6e\x3d\x27\x72\x6f\x75\x6e\x64\x27\x20\x73\x74\x72\x6f\
-\x6b\x65\x2d\x6d\x69\x74\x65\x72\x6c\x69\x6d\x69\x74\x3d\x27\x31\
-\x30\x2e\x30\x33\x37\x35\x27\x20\x73\x74\x72\x6f\x6b\x65\x2d\x77\
-\x69\x64\x74\x68\x3d\x27\x34\x2e\x30\x31\x35\x27\x2f\x3e\x0a\x3c\
-\x2f\x67\x3e\x0a\x3c\x67\x20\x74\x72\x61\x6e\x73\x66\x6f\x72\x6d\
-\x3d\x27\x6d\x61\x74\x72\x69\x78\x28\x30\x2e\x39\x39\x36\x32\x36\
-\x34\x20\x30\x20\x30\x20\x30\x2e\x39\x39\x36\x32\x36\x34\x20\x35\
-\x36\x2e\x34\x30\x39\x34\x20\x31\x31\x37\x2e\x38\x35\x38\x29\x27\
-\x3e\x0a\x3c\x70\x61\x74\x68\x20\x64\x3d\x27\x4d\x20\x33\x32\x2e\
-\x31\x32\x20\x2d\x32\x2e\x30\x30\x37\x35\x4c\x20\x33\x32\x2e\x31\
-\x32\x20\x2d\x36\x32\x2e\x32\x33\x32\x35\x27\x20\x66\x69\x6c\x6c\
-\x3d\x27\x6e\x6f\x6e\x65\x27\x20\x73\x74\x72\x6f\x6b\x65\x3d\x27\
-\x23\x30\x30\x30\x30\x30\x30\x27\x20\x73\x74\x72\x6f\x6b\x65\x2d\
-\x6c\x69\x6e\x65\x63\x61\x70\x3d\x27\x72\x6f\x75\x6e\x64\x27\x20\
-\x73\x74\x72\x6f\x6b\x65\x2d\x6c\x69\x6e\x65\x6a\x6f\x69\x6e\x3d\
-\x27\x72\x6f\x75\x6e\x64\x27\x20\x73\x74\x72\x6f\x6b\x65\x2d\x6d\
-\x69\x74\x65\x72\x6c\x69\x6d\x69\x74\x3d\x27\x31\x30\x2e\x30\x33\
-\x37\x35\x27\x20\x73\x74\x72\x6f\x6b\x65\x2d\x77\x69\x64\x74\x68\
-\x3d\x27\x34\x2e\x30\x31\x35\x27\x2f\x3e\x0a\x3c\x2f\x67\x3e\x0a\
+\x20\x34\x37\x2e\x31\x37\x36\x32\x20\x2d\x33\x32\x2e\x31\x32\x43\
+\x20\x34\x37\x2e\x31\x37\x36\x32\x20\x2d\x34\x30\x2e\x34\x33\x35\
+\x33\x20\x34\x30\x2e\x34\x33\x35\x33\x20\x2d\x34\x37\x2e\x31\x37\
+\x36\x32\x20\x33\x32\x2e\x31\x32\x20\x2d\x34\x37\x2e\x31\x37\x36\
+\x32\x43\x20\x32\x33\x2e\x38\x30\x34\x37\x20\x2d\x34\x37\x2e\x31\
+\x37\x36\x32\x20\x31\x37\x2e\x30\x36\x33\x37\x20\x2d\x34\x30\x2e\
+\x34\x33\x35\x33\x20\x31\x37\x2e\x30\x36\x33\x37\x20\x2d\x33\x32\
+\x2e\x31\x32\x43\x20\x31\x37\x2e\x30\x36\x33\x37\x20\x2d\x32\x33\
+\x2e\x38\x30\x34\x37\x20\x32\x33\x2e\x38\x30\x34\x37\x20\x2d\x31\
+\x37\x2e\x30\x36\x33\x37\x20\x33\x32\x2e\x31\x32\x20\x2d\x31\x37\
+\x2e\x30\x36\x33\x37\x43\x20\x34\x30\x2e\x34\x33\x35\x33\x20\x2d\
+\x31\x37\x2e\x30\x36\x33\x37\x20\x34\x37\x2e\x31\x37\x36\x32\x20\
+\x2d\x32\x33\x2e\x38\x30\x34\x37\x20\x34\x37\x2e\x31\x37\x36\x32\
+\x20\x2d\x33\x32\x2e\x31\x32\x5a\x27\x20\x66\x69\x6c\x6c\x3d\x27\
+\x23\x30\x30\x30\x30\x30\x30\x27\x2f\x3e\x0a\x3c\x2f\x67\x3e\x0a\
 \x3c\x2f\x67\x3e\x0a\x3c\x2f\x73\x76\x67\x3e\
 \x00\x00\x03\x46\
 \x3c\
@@ -2299,8 +2029,140 @@
 \x34\x35\x31\x2e\x35\x2c\x34\x30\x30\x2e\x36\x2c\x34\x33\x37\x2e\
 \x35\x2c\x33\x38\x36\x2e\x36\x7a\x22\x2f\x3e\x0d\x0a\x3c\x2f\x73\
 \x76\x67\x3e\x0d\x0a\
-\x00\x00\x03\x26\
+\x00\x00\x02\x21\
+\x00\
+\x00\x07\xaf\x78\x9c\xdd\x55\x4d\x6f\x9c\x30\x10\xbd\xf7\x57\x4c\
+\xd5\x83\xdb\x03\xc6\xdf\x86\x28\x24\x52\x57\xea\x29\xbd\x25\x97\
+\xde\x68\xf0\x82\x9b\x5d\x58\x01\x5d\xb6\xff\xbe\x66\xd7\x60\x4a\
+\xaa\xf4\x92\x43\x15\x90\x30\xf3\x18\xbf\x99\xe7\xf1\x98\xeb\xdb\
+\xd3\x7e\x07\x47\xd3\x76\xb6\xa9\x33\x44\x31\x41\x60\xea\xc7\xa6\
+\xb0\x75\x99\xa1\x87\xfb\x2f\x51\x82\x6e\x6f\xde\x5d\xbf\x8f\x22\
+\xb8\xaf\x6c\x07\x5b\xbb\x33\x30\xe4\x1d\x94\xa6\x36\x6d\xde\x9b\
+\x02\xbe\xff\x82\xe2\x68\xbb\x63\xb9\x07\x86\x13\x88\x22\xe7\xef\
+\xac\x25\x2b\x45\xe0\xe2\xd4\x5d\x86\xaa\xbe\x3f\x5c\xc5\xf1\x30\
+\x0c\x78\xe0\xb8\x69\xcb\x98\x11\x42\x62\xe7\xef\x5d\xae\x4e\x3b\
+\x5b\x3f\xfd\xcd\x91\xa6\x69\x1a\x9f\xbf\x22\x18\x6c\xd1\x57\x19\
+\x52\x1c\x3b\x50\x1d\x7a\x04\x95\xb1\x65\xd5\x4f\x90\x1e\xa1\xa3\
+\x35\xc3\xe7\xe6\x94\x21\xa9\xb0\x20\xa9\x00\xc9\x71\x22\x13\x0e\
+\x7e\x9a\x1f\x35\x72\x09\x97\x60\x8b\x0c\x1d\xf2\xd2\xd0\x8b\xd9\
+\xb7\x79\xdd\x6d\x9b\x76\x9f\xa1\x7d\xde\xb7\xf6\xf4\x91\x38\x67\
+\xc5\x94\x00\x32\xde\x93\x31\x71\x53\xaa\x47\xf2\x4f\xe3\xec\x43\
+\xde\x57\xe0\xe8\xbe\x42\x8a\xb9\xd0\x82\x41\xc4\x38\x26\x94\xde\
+\x05\xc0\xbf\x3c\x47\x36\xcf\x90\x7f\x03\x8b\x39\x12\x53\x29\x29\
+\x05\x9a\x62\x29\x38\x85\x88\x62\x2d\x95\x54\xc0\x19\xa6\x6c\x36\
+\x37\x20\x04\x56\xa9\x4a\x83\x83\x14\x38\x49\x99\x0a\x14\x33\x30\
+\xe7\xfa\x02\x32\x09\x9c\x01\xae\xb0\xd2\x42\x6e\x02\x22\x08\x4e\
+\x94\x4a\x42\x64\xf7\xc2\x94\x14\x53\x6a\xde\xdc\x84\xdc\x27\x87\
+\x59\xdd\x44\x31\x03\x3e\xca\xdd\x7a\xa5\xbf\xa1\x71\xab\xee\x32\
+\xf4\x41\x6f\xc7\x1b\xc5\xae\x2e\x71\xf9\x8a\xa5\x0d\x42\x53\xac\
+\x29\x49\x97\x42\xdd\xbe\x22\x9c\x2d\x84\x6a\xcc\x09\xd5\xb3\xd0\
+\x8b\xb9\x14\xea\x1d\x82\x50\x4f\x11\x84\x4e\x51\x02\x22\xb1\xa4\
+\x89\x0c\x24\x17\x76\x1f\xe3\x3c\x2c\xaa\x7c\x81\x43\xd2\x7e\xf2\
+\x5a\xc5\xbc\x6e\x75\x53\x1b\x04\x5d\xdf\x36\x4f\xc6\xad\x22\x39\
+\x5f\x13\x10\xb9\x2e\x34\x8f\xf9\x21\x43\x6d\xf3\xb3\x2e\xfe\x80\
+\x7f\x34\xb6\x5e\xe3\x7b\xdb\x9b\x76\x67\xdd\xe0\x4e\x03\x82\x09\
+\xd7\x72\xfe\xe6\x5b\x99\xbb\x7c\x38\x65\xaf\x5f\xa7\xf5\x0a\xbe\
+\xe1\x1e\xf4\x0a\xdf\x5c\x09\x5f\x68\x35\xc9\x30\x4b\xf4\xe2\x4c\
+\x51\x0c\x8b\x84\xcf\x67\x8a\x37\x17\xad\x36\x39\x84\x6a\x79\x8a\
+\xf5\x46\xf9\x6f\x96\xf1\xf2\x70\xbf\xc8\x9b\xdf\xf9\x80\xe2\xe1\
+\
+\x00\x00\x01\x69\
 \x3c\
+\x73\x76\x67\x20\x78\x6d\x6c\x6e\x73\x3d\x22\x68\x74\x74\x70\x3a\
+\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x32\x30\x30\
+\x30\x2f\x73\x76\x67\x22\x20\x77\x69\x64\x74\x68\x3d\x22\x35\x31\
+\x32\x70\x78\x22\x20\x68\x65\x69\x67\x68\x74\x3d\x22\x35\x31\x32\
+\x70\x78\x22\x20\x76\x69\x65\x77\x42\x6f\x78\x3d\x22\x30\x20\x30\
+\x20\x35\x31\x32\x20\x35\x31\x32\x22\x3e\x3c\x67\x20\x74\x72\x61\
+\x6e\x73\x66\x6f\x72\x6d\x3d\x27\x6d\x61\x74\x72\x69\x78\x28\x32\
+\x34\x20\x30\x20\x30\x20\x32\x34\x20\x30\x20\x30\x29\x27\x3e\x3c\
+\x70\x61\x74\x68\x20\x64\x3d\x22\x4d\x34\x2e\x33\x34\x20\x31\x35\
+\x2e\x36\x36\x41\x37\x2e\x39\x37\x20\x37\x2e\x39\x37\x20\x30\x20\
+\x30\x20\x30\x20\x39\x20\x31\x37\x2e\x39\x34\x56\x31\x30\x48\x35\
+\x56\x38\x68\x34\x56\x35\x2e\x38\x33\x61\x33\x20\x33\x20\x30\x20\
+\x31\x20\x31\x20\x32\x20\x30\x56\x38\x68\x34\x76\x32\x68\x2d\x34\
+\x76\x37\x2e\x39\x34\x61\x37\x2e\x39\x37\x20\x37\x2e\x39\x37\x20\
+\x30\x20\x30\x20\x30\x20\x34\x2e\x36\x36\x2d\x32\x2e\x32\x38\x6c\
+\x2d\x31\x2e\x34\x32\x2d\x31\x2e\x34\x32\x68\x35\x2e\x36\x36\x6c\
+\x2d\x32\x2e\x38\x33\x20\x32\x2e\x38\x33\x61\x31\x30\x20\x31\x30\
+\x20\x30\x20\x30\x20\x31\x2d\x31\x34\x2e\x31\x34\x20\x30\x4c\x2e\
+\x31\x20\x31\x34\x2e\x32\x34\x68\x35\x2e\x36\x36\x6c\x2d\x31\x2e\
+\x34\x32\x20\x31\x2e\x34\x32\x7a\x4d\x31\x30\x20\x34\x61\x31\x20\
+\x31\x20\x30\x20\x31\x20\x30\x20\x30\x2d\x32\x20\x31\x20\x31\x20\
+\x30\x20\x30\x20\x30\x20\x30\x20\x32\x7a\x22\x2f\x3e\x3c\x2f\x67\
+\x3e\x3c\x2f\x73\x76\x67\x3e\x0a\
+\x00\x00\x04\x3d\
+\x3c\
+\x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x27\x31\x2e\
+\x30\x27\x20\x65\x6e\x63\x6f\x64\x69\x6e\x67\x3d\x27\x55\x54\x46\
+\x2d\x38\x27\x3f\x3e\x0a\x3c\x21\x2d\x2d\x20\x54\x68\x69\x73\x20\
+\x66\x69\x6c\x65\x20\x77\x61\x73\x20\x67\x65\x6e\x65\x72\x61\x74\
+\x65\x64\x20\x62\x79\x20\x64\x76\x69\x73\x76\x67\x6d\x20\x32\x2e\
+\x38\x20\x2d\x2d\x3e\x0a\x3c\x73\x76\x67\x20\x76\x65\x72\x73\x69\
+\x6f\x6e\x3d\x27\x31\x2e\x31\x27\x20\x78\x6d\x6c\x6e\x73\x3d\x27\
+\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\
+\x67\x2f\x32\x30\x30\x30\x2f\x73\x76\x67\x27\x20\x78\x6d\x6c\x6e\
+\x73\x3a\x78\x6c\x69\x6e\x6b\x3d\x27\x68\x74\x74\x70\x3a\x2f\x2f\
+\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x31\x39\x39\x39\x2f\
+\x78\x6c\x69\x6e\x6b\x27\x20\x77\x69\x64\x74\x68\x3d\x27\x36\x33\
+\x2e\x39\x39\x39\x36\x70\x74\x27\x20\x68\x65\x69\x67\x68\x74\x3d\
+\x27\x36\x33\x2e\x39\x39\x39\x37\x70\x74\x27\x20\x76\x69\x65\x77\
+\x42\x6f\x78\x3d\x27\x35\x36\x2e\x34\x30\x39\x34\x20\x35\x33\x2e\
+\x38\x35\x38\x33\x20\x36\x33\x2e\x39\x39\x39\x36\x20\x36\x33\x2e\
+\x39\x39\x39\x37\x27\x3e\x0a\x3c\x67\x20\x69\x64\x3d\x27\x70\x61\
+\x67\x65\x31\x27\x3e\x0a\x3c\x67\x20\x74\x72\x61\x6e\x73\x66\x6f\
+\x72\x6d\x3d\x27\x6d\x61\x74\x72\x69\x78\x28\x30\x2e\x39\x39\x36\
+\x32\x36\x34\x20\x30\x20\x30\x20\x30\x2e\x39\x39\x36\x32\x36\x34\
+\x20\x35\x38\x2e\x34\x36\x36\x39\x20\x31\x31\x37\x2e\x38\x35\x38\
+\x29\x27\x3e\x0a\x3c\x70\x61\x74\x68\x20\x64\x3d\x27\x4d\x20\x33\
+\x2e\x39\x35\x37\x33\x35\x20\x2d\x33\x32\x2e\x31\x32\x4c\x20\x31\
+\x31\x2e\x39\x30\x33\x36\x20\x2d\x35\x31\x2e\x33\x30\x33\x39\x4c\
+\x20\x35\x36\x2e\x31\x35\x32\x33\x20\x2d\x34\x32\x2e\x35\x30\x32\
+\x32\x4c\x20\x34\x30\x2e\x36\x37\x39\x34\x20\x2d\x32\x32\x2e\x35\
+\x32\x38\x31\x27\x20\x66\x69\x6c\x6c\x3d\x27\x6e\x6f\x6e\x65\x27\
+\x20\x73\x74\x72\x6f\x6b\x65\x3d\x27\x23\x30\x30\x30\x30\x30\x30\
+\x27\x20\x73\x74\x72\x6f\x6b\x65\x2d\x6c\x69\x6e\x65\x63\x61\x70\
+\x3d\x27\x72\x6f\x75\x6e\x64\x27\x20\x73\x74\x72\x6f\x6b\x65\x2d\
+\x6c\x69\x6e\x65\x6a\x6f\x69\x6e\x3d\x27\x72\x6f\x75\x6e\x64\x27\
+\x20\x73\x74\x72\x6f\x6b\x65\x2d\x6d\x69\x74\x65\x72\x6c\x69\x6d\
+\x69\x74\x3d\x27\x31\x30\x2e\x30\x33\x37\x35\x27\x20\x73\x74\x72\
+\x6f\x6b\x65\x2d\x77\x69\x64\x74\x68\x3d\x27\x32\x2e\x35\x30\x39\
+\x33\x37\x27\x2f\x3e\x0a\x3c\x2f\x67\x3e\x0a\x3c\x67\x20\x74\x72\
+\x61\x6e\x73\x66\x6f\x72\x6d\x3d\x27\x6d\x61\x74\x72\x69\x78\x28\
+\x30\x2e\x39\x39\x36\x32\x36\x34\x20\x30\x20\x30\x20\x30\x2e\x39\
+\x39\x36\x32\x36\x34\x20\x35\x38\x2e\x34\x36\x36\x39\x20\x31\x31\
+\x37\x2e\x38\x35\x38\x29\x27\x3e\x0a\x3c\x63\x69\x72\x63\x6c\x65\
+\x20\x63\x78\x3d\x27\x33\x2e\x39\x35\x37\x33\x35\x27\x20\x63\x79\
+\x3d\x27\x2d\x33\x32\x2e\x31\x32\x27\x20\x66\x69\x6c\x6c\x3d\x27\
+\x23\x30\x30\x30\x30\x30\x30\x27\x20\x72\x3d\x27\x36\x2e\x30\x32\
+\x32\x35\x27\x2f\x3e\x0a\x3c\x2f\x67\x3e\x0a\x3c\x67\x20\x74\x72\
+\x61\x6e\x73\x66\x6f\x72\x6d\x3d\x27\x6d\x61\x74\x72\x69\x78\x28\
+\x30\x2e\x39\x39\x36\x32\x36\x34\x20\x30\x20\x30\x20\x30\x2e\x39\
+\x39\x36\x32\x36\x34\x20\x35\x38\x2e\x34\x36\x36\x39\x20\x31\x31\
+\x37\x2e\x38\x35\x38\x29\x27\x3e\x0a\x3c\x63\x69\x72\x63\x6c\x65\
+\x20\x63\x78\x3d\x27\x31\x31\x2e\x39\x30\x33\x36\x27\x20\x63\x79\
+\x3d\x27\x2d\x35\x31\x2e\x33\x30\x33\x39\x27\x20\x66\x69\x6c\x6c\
+\x3d\x27\x23\x30\x30\x30\x30\x30\x30\x27\x20\x72\x3d\x27\x36\x2e\
+\x30\x32\x32\x35\x27\x2f\x3e\x0a\x3c\x2f\x67\x3e\x0a\x3c\x67\x20\
+\x74\x72\x61\x6e\x73\x66\x6f\x72\x6d\x3d\x27\x6d\x61\x74\x72\x69\
+\x78\x28\x30\x2e\x39\x39\x36\x32\x36\x34\x20\x30\x20\x30\x20\x30\
+\x2e\x39\x39\x36\x32\x36\x34\x20\x35\x38\x2e\x34\x36\x36\x39\x20\
+\x31\x31\x37\x2e\x38\x35\x38\x29\x27\x3e\x0a\x3c\x63\x69\x72\x63\
+\x6c\x65\x20\x63\x78\x3d\x27\x35\x36\x2e\x31\x35\x32\x33\x27\x20\
+\x63\x79\x3d\x27\x2d\x34\x32\x2e\x35\x30\x32\x32\x27\x20\x66\x69\
+\x6c\x6c\x3d\x27\x23\x30\x30\x30\x30\x30\x30\x27\x20\x72\x3d\x27\
+\x36\x2e\x30\x32\x32\x35\x27\x2f\x3e\x0a\x3c\x2f\x67\x3e\x0a\x3c\
+\x67\x20\x74\x72\x61\x6e\x73\x66\x6f\x72\x6d\x3d\x27\x6d\x61\x74\
+\x72\x69\x78\x28\x30\x2e\x39\x39\x36\x32\x36\x34\x20\x30\x20\x30\
+\x20\x30\x2e\x39\x39\x36\x32\x36\x34\x20\x35\x38\x2e\x34\x36\x36\
+\x39\x20\x31\x31\x37\x2e\x38\x35\x38\x29\x27\x3e\x0a\x3c\x63\x69\
+\x72\x63\x6c\x65\x20\x63\x78\x3d\x27\x34\x30\x2e\x36\x37\x39\x34\
+\x27\x20\x63\x79\x3d\x27\x2d\x32\x32\x2e\x35\x32\x38\x31\x27\x20\
+\x66\x69\x6c\x6c\x3d\x27\x23\x30\x30\x30\x30\x30\x30\x27\x20\x72\
+\x3d\x27\x36\x2e\x30\x32\x32\x35\x27\x2f\x3e\x0a\x3c\x2f\x67\x3e\
+\x0a\x3c\x2f\x67\x3e\x0a\x3c\x2f\x73\x76\x67\x3e\
+\x00\x00\x03\x6c\
+\x3c\
 \x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\
 \x30\x22\x20\x65\x6e\x63\x6f\x64\x69\x6e\x67\x3d\x22\x75\x74\x66\
 \x2d\x38\x22\x3f\x3e\x0d\x0a\x3c\x21\x2d\x2d\x20\x47\x65\x6e\x65\
@@ -2331,52 +2193,190 @@
 \x3d\x22\x6e\x65\x77\x20\x30\x20\x30\x20\x35\x31\x32\x20\x35\x31\
 \x32\x22\x20\x78\x6d\x6c\x3a\x73\x70\x61\x63\x65\x3d\x22\x70\x72\
 \x65\x73\x65\x72\x76\x65\x22\x3e\x0d\x0a\x3c\x67\x3e\x0d\x0a\x09\
-\x3c\x70\x61\x74\x68\x20\x64\x3d\x22\x4d\x32\x35\x36\x2c\x33\x38\
-\x38\x63\x2d\x37\x32\x2e\x35\x39\x37\x2c\x30\x2d\x31\x33\x32\x2d\
-\x35\x39\x2e\x34\x30\x35\x2d\x31\x33\x32\x2d\x31\x33\x32\x63\x30\
-\x2d\x37\x32\x2e\x36\x30\x31\x2c\x35\x39\x2e\x34\x30\x33\x2d\x31\
-\x33\x32\x2c\x31\x33\x32\x2d\x31\x33\x32\x63\x33\x36\x2e\x33\x2c\
-\x30\x2c\x36\x39\x2e\x32\x39\x39\x2c\x31\x35\x2e\x34\x2c\x39\x32\
-\x2e\x34\x30\x36\x2c\x33\x39\x2e\x36\x30\x31\x4c\x32\x37\x38\x2c\
-\x32\x33\x34\x68\x31\x35\x34\x56\x38\x30\x0d\x0a\x09\x09\x6c\x2d\
-\x35\x31\x2e\x36\x39\x38\x2c\x35\x31\x2e\x37\x30\x32\x43\x33\x34\
-\x38\x2e\x34\x30\x36\x2c\x39\x39\x2e\x37\x39\x38\x2c\x33\x30\x34\
-\x2e\x34\x30\x36\x2c\x38\x30\x2c\x32\x35\x36\x2c\x38\x30\x63\x2d\
-\x39\x36\x2e\x37\x39\x37\x2c\x30\x2d\x31\x37\x36\x2c\x37\x39\x2e\
-\x32\x30\x33\x2d\x31\x37\x36\x2c\x31\x37\x36\x73\x37\x38\x2e\x30\
-\x39\x34\x2c\x31\x37\x36\x2c\x31\x37\x36\x2c\x31\x37\x36\x0d\x0a\
-\x09\x09\x63\x38\x31\x2e\x30\x34\x35\x2c\x30\x2c\x31\x34\x38\x2e\
-\x32\x38\x37\x2d\x35\x34\x2e\x31\x33\x34\x2c\x31\x36\x39\x2e\x34\
-\x30\x31\x2d\x31\x32\x38\x48\x33\x37\x38\x2e\x38\x35\x43\x33\x36\
-\x30\x2e\x31\x30\x35\x2c\x33\x35\x33\x2e\x35\x36\x31\x2c\x33\x31\
-\x31\x2e\x37\x31\x32\x2c\x33\x38\x38\x2c\x32\x35\x36\x2c\x33\x38\
-\x38\x7a\x22\x2f\x3e\x0d\x0a\x3c\x2f\x67\x3e\x0d\x0a\x3c\x2f\x73\
+\x0d\x0a\x09\x09\x3c\x72\x65\x63\x74\x20\x78\x3d\x22\x31\x37\x38\
+\x2e\x38\x34\x36\x22\x20\x79\x3d\x22\x39\x32\x2e\x30\x38\x37\x22\
+\x20\x74\x72\x61\x6e\x73\x66\x6f\x72\x6d\x3d\x22\x6d\x61\x74\x72\
+\x69\x78\x28\x2d\x30\x2e\x37\x30\x37\x31\x20\x2d\x30\x2e\x37\x30\
+\x37\x31\x20\x30\x2e\x37\x30\x37\x31\x20\x2d\x30\x2e\x37\x30\x37\
+\x31\x20\x32\x32\x34\x2e\x33\x34\x37\x36\x20\x36\x33\x31\x2e\x31\
+\x34\x39\x38\x29\x22\x20\x77\x69\x64\x74\x68\x3d\x22\x31\x32\x38\
+\x2e\x30\x38\x35\x22\x20\x68\x65\x69\x67\x68\x74\x3d\x22\x33\x35\
+\x34\x2e\x30\x34\x39\x22\x2f\x3e\x0d\x0a\x09\x3c\x70\x61\x74\x68\
+\x20\x64\x3d\x22\x4d\x34\x37\x31\x2e\x37\x32\x33\x2c\x38\x38\x2e\
+\x33\x39\x33\x6c\x2d\x34\x38\x2e\x31\x31\x35\x2d\x34\x38\x2e\x31\
+\x31\x34\x63\x2d\x31\x31\x2e\x37\x32\x33\x2d\x31\x31\x2e\x37\x32\
+\x34\x2d\x33\x31\x2e\x35\x35\x38\x2d\x31\x30\x2e\x38\x39\x36\x2d\
+\x34\x34\x2e\x33\x30\x34\x2c\x31\x2e\x38\x35\x6c\x2d\x34\x35\x2e\
+\x32\x30\x32\x2c\x34\x35\x2e\x32\x30\x33\x6c\x39\x30\x2e\x35\x36\
+\x39\x2c\x39\x30\x2e\x35\x36\x38\x6c\x34\x35\x2e\x32\x30\x32\x2d\
+\x34\x35\x2e\x32\x30\x32\x0d\x0a\x09\x09\x43\x34\x38\x32\x2e\x36\
+\x31\x36\x2c\x31\x31\x39\x2e\x39\x35\x32\x2c\x34\x38\x33\x2e\x34\
+\x34\x35\x2c\x31\x30\x30\x2e\x31\x31\x36\x2c\x34\x37\x31\x2e\x37\
+\x32\x33\x2c\x38\x38\x2e\x33\x39\x33\x7a\x22\x2f\x3e\x0d\x0a\x09\
+\x3c\x70\x6f\x6c\x79\x67\x6f\x6e\x20\x70\x6f\x69\x6e\x74\x73\x3d\
+\x22\x36\x34\x2e\x30\x32\x31\x2c\x33\x36\x33\x2e\x32\x35\x32\x20\
+\x33\x32\x2c\x34\x38\x30\x20\x31\x34\x38\x2e\x37\x33\x37\x2c\x34\
+\x34\x37\x2e\x39\x37\x39\x20\x09\x22\x2f\x3e\x0d\x0a\x3c\x2f\x67\
+\x3e\x0d\x0a\x3c\x2f\x73\x76\x67\x3e\x0d\x0a\
+\x00\x00\x03\x36\
+\x3c\
+\x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\
+\x30\x22\x20\x65\x6e\x63\x6f\x64\x69\x6e\x67\x3d\x22\x75\x74\x66\
+\x2d\x38\x22\x3f\x3e\x0d\x0a\x3c\x21\x2d\x2d\x20\x47\x65\x6e\x65\
+\x72\x61\x74\x6f\x72\x3a\x20\x41\x64\x6f\x62\x65\x20\x49\x6c\x6c\
+\x75\x73\x74\x72\x61\x74\x6f\x72\x20\x31\x36\x2e\x32\x2e\x31\x2c\
+\x20\x53\x56\x47\x20\x45\x78\x70\x6f\x72\x74\x20\x50\x6c\x75\x67\
+\x2d\x49\x6e\x20\x2e\x20\x53\x56\x47\x20\x56\x65\x72\x73\x69\x6f\
+\x6e\x3a\x20\x36\x2e\x30\x30\x20\x42\x75\x69\x6c\x64\x20\x30\x29\
+\x20\x20\x2d\x2d\x3e\x0d\x0a\x3c\x21\x44\x4f\x43\x54\x59\x50\x45\
+\x20\x73\x76\x67\x20\x50\x55\x42\x4c\x49\x43\x20\x22\x2d\x2f\x2f\
+\x57\x33\x43\x2f\x2f\x44\x54\x44\x20\x53\x56\x47\x20\x31\x2e\x31\
+\x2f\x2f\x45\x4e\x22\x20\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\
+\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x47\x72\x61\x70\x68\x69\x63\
+\x73\x2f\x53\x56\x47\x2f\x31\x2e\x31\x2f\x44\x54\x44\x2f\x73\x76\
+\x67\x31\x31\x2e\x64\x74\x64\x22\x3e\x0d\x0a\x3c\x73\x76\x67\x20\
+\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\x31\x22\x20\x69\x64\
+\x3d\x22\x4c\x61\x79\x65\x72\x5f\x31\x22\x20\x78\x6d\x6c\x6e\x73\
+\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\
+\x6f\x72\x67\x2f\x32\x30\x30\x30\x2f\x73\x76\x67\x22\x20\x78\x6d\
+\x6c\x6e\x73\x3a\x78\x6c\x69\x6e\x6b\x3d\x22\x68\x74\x74\x70\x3a\
+\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x31\x39\x39\
+\x39\x2f\x78\x6c\x69\x6e\x6b\x22\x20\x78\x3d\x22\x30\x70\x78\x22\
+\x20\x79\x3d\x22\x30\x70\x78\x22\x0d\x0a\x09\x20\x77\x69\x64\x74\
+\x68\x3d\x22\x35\x31\x32\x70\x78\x22\x20\x68\x65\x69\x67\x68\x74\
+\x3d\x22\x35\x31\x32\x70\x78\x22\x20\x76\x69\x65\x77\x42\x6f\x78\
+\x3d\x22\x30\x20\x30\x20\x35\x31\x32\x20\x35\x31\x32\x22\x20\x65\
+\x6e\x61\x62\x6c\x65\x2d\x62\x61\x63\x6b\x67\x72\x6f\x75\x6e\x64\
+\x3d\x22\x6e\x65\x77\x20\x30\x20\x30\x20\x35\x31\x32\x20\x35\x31\
+\x32\x22\x20\x78\x6d\x6c\x3a\x73\x70\x61\x63\x65\x3d\x22\x70\x72\
+\x65\x73\x65\x72\x76\x65\x22\x3e\x0d\x0a\x3c\x67\x3e\x0d\x0a\x09\
+\x3c\x70\x6f\x6c\x79\x67\x6f\x6e\x20\x70\x6f\x69\x6e\x74\x73\x3d\
+\x22\x33\x39\x36\x2e\x37\x39\x35\x2c\x33\x39\x36\x2e\x38\x20\x33\
+\x32\x30\x2c\x33\x39\x36\x2e\x38\x20\x33\x32\x30\x2c\x34\x34\x38\
+\x20\x34\x34\x38\x2c\x34\x34\x38\x20\x34\x34\x38\x2c\x33\x32\x30\
+\x20\x33\x39\x36\x2e\x37\x39\x35\x2c\x33\x32\x30\x20\x09\x22\x2f\
+\x3e\x0d\x0a\x09\x3c\x70\x6f\x6c\x79\x67\x6f\x6e\x20\x70\x6f\x69\
+\x6e\x74\x73\x3d\x22\x33\x39\x36\x2e\x38\x2c\x31\x31\x35\x2e\x32\
+\x30\x35\x20\x33\x39\x36\x2e\x38\x2c\x31\x39\x32\x20\x34\x34\x38\
+\x2c\x31\x39\x32\x20\x34\x34\x38\x2c\x36\x34\x20\x33\x32\x30\x2c\
+\x36\x34\x20\x33\x32\x30\x2c\x31\x31\x35\x2e\x32\x30\x35\x20\x09\
+\x22\x2f\x3e\x0d\x0a\x09\x3c\x70\x6f\x6c\x79\x67\x6f\x6e\x20\x70\
+\x6f\x69\x6e\x74\x73\x3d\x22\x31\x31\x35\x2e\x32\x30\x35\x2c\x31\
+\x31\x35\x2e\x32\x20\x31\x39\x32\x2c\x31\x31\x35\x2e\x32\x20\x31\
+\x39\x32\x2c\x36\x34\x20\x36\x34\x2c\x36\x34\x20\x36\x34\x2c\x31\
+\x39\x32\x20\x31\x31\x35\x2e\x32\x30\x35\x2c\x31\x39\x32\x20\x09\
+\x22\x2f\x3e\x0d\x0a\x09\x3c\x70\x6f\x6c\x79\x67\x6f\x6e\x20\x70\
+\x6f\x69\x6e\x74\x73\x3d\x22\x31\x31\x35\x2e\x32\x2c\x33\x39\x36\
+\x2e\x37\x39\x35\x20\x31\x31\x35\x2e\x32\x2c\x33\x32\x30\x20\x36\
+\x34\x2c\x33\x32\x30\x20\x36\x34\x2c\x34\x34\x38\x20\x31\x39\x32\
+\x2c\x34\x34\x38\x20\x31\x39\x32\x2c\x33\x39\x36\x2e\x37\x39\x35\
+\x20\x09\x22\x2f\x3e\x0d\x0a\x3c\x2f\x67\x3e\x0d\x0a\x3c\x2f\x73\
 \x76\x67\x3e\x0d\x0a\
-\x00\x00\x01\x69\
+\x00\x00\x05\x27\
 \x3c\
+\x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\
+\x30\x22\x20\x65\x6e\x63\x6f\x64\x69\x6e\x67\x3d\x22\x75\x74\x66\
+\x2d\x38\x22\x3f\x3e\x0d\x0a\x3c\x21\x2d\x2d\x20\x47\x65\x6e\x65\
+\x72\x61\x74\x6f\x72\x3a\x20\x41\x64\x6f\x62\x65\x20\x49\x6c\x6c\
+\x75\x73\x74\x72\x61\x74\x6f\x72\x20\x31\x36\x2e\x32\x2e\x31\x2c\
+\x20\x53\x56\x47\x20\x45\x78\x70\x6f\x72\x74\x20\x50\x6c\x75\x67\
+\x2d\x49\x6e\x20\x2e\x20\x53\x56\x47\x20\x56\x65\x72\x73\x69\x6f\
+\x6e\x3a\x20\x36\x2e\x30\x30\x20\x42\x75\x69\x6c\x64\x20\x30\x29\
+\x20\x20\x2d\x2d\x3e\x0d\x0a\x3c\x21\x44\x4f\x43\x54\x59\x50\x45\
+\x20\x73\x76\x67\x20\x50\x55\x42\x4c\x49\x43\x20\x22\x2d\x2f\x2f\
+\x57\x33\x43\x2f\x2f\x44\x54\x44\x20\x53\x56\x47\x20\x31\x2e\x31\
+\x2f\x2f\x45\x4e\x22\x20\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\
+\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x47\x72\x61\x70\x68\x69\x63\
+\x73\x2f\x53\x56\x47\x2f\x31\x2e\x31\x2f\x44\x54\x44\x2f\x73\x76\
+\x67\x31\x31\x2e\x64\x74\x64\x22\x3e\x0d\x0a\x3c\x73\x76\x67\x20\
+\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\x31\x22\x20\x69\x64\
+\x3d\x22\x4c\x61\x79\x65\x72\x5f\x31\x22\x20\x78\x6d\x6c\x6e\x73\
+\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\
+\x6f\x72\x67\x2f\x32\x30\x30\x30\x2f\x73\x76\x67\x22\x20\x78\x6d\
+\x6c\x6e\x73\x3a\x78\x6c\x69\x6e\x6b\x3d\x22\x68\x74\x74\x70\x3a\
+\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x31\x39\x39\
+\x39\x2f\x78\x6c\x69\x6e\x6b\x22\x20\x78\x3d\x22\x30\x70\x78\x22\
+\x20\x79\x3d\x22\x30\x70\x78\x22\x0d\x0a\x09\x20\x77\x69\x64\x74\
+\x68\x3d\x22\x35\x31\x32\x70\x78\x22\x20\x68\x65\x69\x67\x68\x74\
+\x3d\x22\x35\x31\x32\x70\x78\x22\x20\x76\x69\x65\x77\x42\x6f\x78\
+\x3d\x22\x30\x20\x30\x20\x35\x31\x32\x20\x35\x31\x32\x22\x20\x65\
+\x6e\x61\x62\x6c\x65\x2d\x62\x61\x63\x6b\x67\x72\x6f\x75\x6e\x64\
+\x3d\x22\x6e\x65\x77\x20\x30\x20\x30\x20\x35\x31\x32\x20\x35\x31\
+\x32\x22\x20\x78\x6d\x6c\x3a\x73\x70\x61\x63\x65\x3d\x22\x70\x72\
+\x65\x73\x65\x72\x76\x65\x22\x3e\x0d\x0a\x3c\x67\x20\x69\x64\x3d\
+\x22\x49\x63\x6f\x6e\x5f\x31\x32\x5f\x22\x3e\x0d\x0a\x09\x3c\x67\
+\x3e\x0d\x0a\x09\x09\x3c\x70\x61\x74\x68\x20\x64\x3d\x22\x4d\x32\
+\x35\x36\x2c\x36\x34\x43\x31\x35\x30\x2e\x34\x30\x31\x2c\x36\x34\
+\x2c\x36\x34\x2c\x31\x35\x30\x2e\x34\x30\x31\x2c\x36\x34\x2c\x32\
+\x35\x36\x63\x30\x2c\x31\x30\x35\x2e\x36\x30\x34\x2c\x38\x36\x2e\
+\x34\x30\x31\x2c\x31\x39\x32\x2c\x31\x39\x32\x2c\x31\x39\x32\x63\
+\x31\x38\x2e\x31\x33\x36\x2c\x30\x2c\x33\x32\x2d\x31\x33\x2e\x38\
+\x36\x34\x2c\x33\x32\x2d\x33\x32\x0d\x0a\x09\x09\x09\x63\x30\x2d\
+\x38\x2e\x35\x33\x31\x2d\x33\x2e\x31\x39\x38\x2d\x31\x36\x2d\x38\
+\x2e\x35\x33\x31\x2d\x32\x31\x2e\x33\x33\x33\x63\x2d\x35\x2e\x33\
+\x33\x33\x2d\x35\x2e\x33\x33\x34\x2d\x38\x2e\x35\x33\x31\x2d\x31\
+\x32\x2e\x38\x30\x33\x2d\x38\x2e\x35\x33\x31\x2d\x32\x31\x2e\x33\
+\x33\x34\x63\x30\x2d\x31\x38\x2e\x31\x33\x35\x2c\x31\x33\x2e\x38\
+\x36\x34\x2d\x33\x32\x2c\x33\x32\x2d\x33\x32\x68\x33\x38\x2e\x33\
+\x39\x36\x0d\x0a\x09\x09\x09\x63\x35\x38\x2e\x36\x36\x37\x2c\x30\
+\x2c\x31\x30\x36\x2e\x36\x36\x37\x2d\x34\x38\x2c\x31\x30\x36\x2e\
+\x36\x36\x37\x2d\x31\x30\x36\x2e\x36\x36\x36\x43\x34\x34\x38\x2c\
+\x31\x34\x30\x2e\x38\x30\x32\x2c\x33\x36\x31\x2e\x36\x30\x34\x2c\
+\x36\x34\x2c\x32\x35\x36\x2c\x36\x34\x7a\x20\x4d\x31\x33\x38\x2e\
+\x36\x36\x37\x2c\x32\x35\x36\x63\x2d\x31\x38\x2e\x31\x33\x36\x2c\
+\x30\x2d\x33\x32\x2d\x31\x33\x2e\x38\x36\x34\x2d\x33\x32\x2d\x33\
+\x32\x73\x31\x33\x2e\x38\x36\x34\x2d\x33\x32\x2c\x33\x32\x2d\x33\
+\x32\x0d\x0a\x09\x09\x09\x63\x31\x38\x2e\x31\x33\x35\x2c\x30\x2c\
+\x33\x32\x2c\x31\x33\x2e\x38\x36\x34\x2c\x33\x32\x2c\x33\x32\x53\
+\x31\x35\x36\x2e\x38\x30\x32\x2c\x32\x35\x36\x2c\x31\x33\x38\x2e\
+\x36\x36\x37\x2c\x32\x35\x36\x7a\x20\x4d\x32\x30\x32\x2e\x36\x36\
+\x37\x2c\x31\x37\x30\x2e\x36\x36\x37\x63\x2d\x31\x38\x2e\x31\x33\
+\x36\x2c\x30\x2d\x33\x32\x2d\x31\x33\x2e\x38\x36\x35\x2d\x33\x32\
+\x2d\x33\x32\x63\x30\x2d\x31\x38\x2e\x31\x33\x36\x2c\x31\x33\x2e\
+\x38\x36\x34\x2d\x33\x32\x2c\x33\x32\x2d\x33\x32\x0d\x0a\x09\x09\
+\x09\x63\x31\x38\x2e\x31\x33\x35\x2c\x30\x2c\x33\x32\x2c\x31\x33\
+\x2e\x38\x36\x34\x2c\x33\x32\x2c\x33\x32\x43\x32\x33\x34\x2e\x36\
+\x36\x37\x2c\x31\x35\x36\x2e\x38\x30\x32\x2c\x32\x32\x30\x2e\x38\
+\x30\x32\x2c\x31\x37\x30\x2e\x36\x36\x37\x2c\x32\x30\x32\x2e\x36\
+\x36\x37\x2c\x31\x37\x30\x2e\x36\x36\x37\x7a\x20\x4d\x33\x30\x39\
+\x2e\x33\x33\x33\x2c\x31\x37\x30\x2e\x36\x36\x37\x63\x2d\x31\x38\
+\x2e\x31\x33\x35\x2c\x30\x2d\x33\x32\x2d\x31\x33\x2e\x38\x36\x35\
+\x2d\x33\x32\x2d\x33\x32\x0d\x0a\x09\x09\x09\x63\x30\x2d\x31\x38\
+\x2e\x31\x33\x36\x2c\x31\x33\x2e\x38\x36\x35\x2d\x33\x32\x2c\x33\
+\x32\x2d\x33\x32\x63\x31\x38\x2e\x31\x33\x36\x2c\x30\x2c\x33\x32\
+\x2c\x31\x33\x2e\x38\x36\x34\x2c\x33\x32\x2c\x33\x32\x43\x33\x34\
+\x31\x2e\x33\x33\x33\x2c\x31\x35\x36\x2e\x38\x30\x32\x2c\x33\x32\
+\x37\x2e\x34\x36\x39\x2c\x31\x37\x30\x2e\x36\x36\x37\x2c\x33\x30\
+\x39\x2e\x33\x33\x33\x2c\x31\x37\x30\x2e\x36\x36\x37\x7a\x20\x4d\
+\x33\x37\x33\x2e\x33\x33\x33\x2c\x32\x35\x36\x0d\x0a\x09\x09\x09\
+\x63\x2d\x31\x38\x2e\x31\x33\x35\x2c\x30\x2d\x33\x32\x2d\x31\x33\
+\x2e\x38\x36\x34\x2d\x33\x32\x2d\x33\x32\x73\x31\x33\x2e\x38\x36\
+\x35\x2d\x33\x32\x2c\x33\x32\x2d\x33\x32\x63\x31\x38\x2e\x31\x33\
+\x36\x2c\x30\x2c\x33\x32\x2c\x31\x33\x2e\x38\x36\x34\x2c\x33\x32\
+\x2c\x33\x32\x53\x33\x39\x31\x2e\x34\x36\x39\x2c\x32\x35\x36\x2c\
+\x33\x37\x33\x2e\x33\x33\x33\x2c\x32\x35\x36\x7a\x22\x2f\x3e\x0d\
+\x0a\x09\x3c\x2f\x67\x3e\x0d\x0a\x3c\x2f\x67\x3e\x0d\x0a\x3c\x2f\
+\x73\x76\x67\x3e\x0d\x0a\
+\x00\x00\x01\x1c\
+\x3c\
 \x73\x76\x67\x20\x78\x6d\x6c\x6e\x73\x3d\x22\x68\x74\x74\x70\x3a\
 \x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x32\x30\x30\
 \x30\x2f\x73\x76\x67\x22\x20\x77\x69\x64\x74\x68\x3d\x22\x35\x31\
 \x32\x70\x78\x22\x20\x68\x65\x69\x67\x68\x74\x3d\x22\x35\x31\x32\
-\x70\x78\x22\x20\x76\x69\x65\x77\x42\x6f\x78\x3d\x22\x30\x20\x30\
-\x20\x35\x31\x32\x20\x35\x31\x32\x22\x3e\x3c\x67\x20\x74\x72\x61\
-\x6e\x73\x66\x6f\x72\x6d\x3d\x27\x6d\x61\x74\x72\x69\x78\x28\x32\
-\x34\x20\x30\x20\x30\x20\x32\x34\x20\x30\x20\x30\x29\x27\x3e\x3c\
-\x70\x61\x74\x68\x20\x64\x3d\x22\x4d\x34\x2e\x33\x34\x20\x31\x35\
-\x2e\x36\x36\x41\x37\x2e\x39\x37\x20\x37\x2e\x39\x37\x20\x30\x20\
-\x30\x20\x30\x20\x39\x20\x31\x37\x2e\x39\x34\x56\x31\x30\x48\x35\
-\x56\x38\x68\x34\x56\x35\x2e\x38\x33\x61\x33\x20\x33\x20\x30\x20\
-\x31\x20\x31\x20\x32\x20\x30\x56\x38\x68\x34\x76\x32\x68\x2d\x34\
-\x76\x37\x2e\x39\x34\x61\x37\x2e\x39\x37\x20\x37\x2e\x39\x37\x20\
-\x30\x20\x30\x20\x30\x20\x34\x2e\x36\x36\x2d\x32\x2e\x32\x38\x6c\
-\x2d\x31\x2e\x34\x32\x2d\x31\x2e\x34\x32\x68\x35\x2e\x36\x36\x6c\
-\x2d\x32\x2e\x38\x33\x20\x32\x2e\x38\x33\x61\x31\x30\x20\x31\x30\
-\x20\x30\x20\x30\x20\x31\x2d\x31\x34\x2e\x31\x34\x20\x30\x4c\x2e\
-\x31\x20\x31\x34\x2e\x32\x34\x68\x35\x2e\x36\x36\x6c\x2d\x31\x2e\
-\x34\x32\x20\x31\x2e\x34\x32\x7a\x4d\x31\x30\x20\x34\x61\x31\x20\
-\x31\x20\x30\x20\x31\x20\x30\x20\x30\x2d\x32\x20\x31\x20\x31\x20\
-\x30\x20\x30\x20\x30\x20\x30\x20\x32\x7a\x22\x2f\x3e\x3c\x2f\x67\
-\x3e\x3c\x2f\x73\x76\x67\x3e\x0a\
+\x70\x78\x22\x0a\x20\x20\x20\x20\x20\x76\x69\x65\x77\x42\x6f\x78\
+\x3d\x22\x30\x20\x30\x20\x35\x31\x32\x20\x35\x31\x32\x22\x3e\x0a\
+\x3c\x67\x20\x74\x72\x61\x6e\x73\x66\x6f\x72\x6d\x3d\x27\x6d\x61\
+\x74\x72\x69\x78\x28\x34\x38\x20\x30\x20\x30\x20\x34\x38\x20\x34\
+\x38\x20\x34\x38\x29\x27\x3e\x0a\x20\x20\x3c\x70\x61\x74\x68\x20\
+\x64\x3d\x22\x4d\x30\x20\x30\x76\x32\x68\x2e\x35\x63\x30\x2d\x2e\
+\x35\x35\x2e\x34\x35\x2d\x31\x20\x31\x2d\x31\x68\x31\x2e\x35\x76\
+\x35\x2e\x35\x63\x30\x20\x2e\x32\x38\x2d\x2e\x32\x32\x2e\x35\x2d\
+\x2e\x35\x2e\x35\x68\x2d\x2e\x35\x76\x31\x68\x34\x76\x2d\x31\x68\
+\x2d\x2e\x35\x63\x2d\x2e\x32\x38\x20\x30\x2d\x2e\x35\x2d\x2e\x32\
+\x32\x2d\x2e\x35\x2d\x2e\x35\x76\x2d\x35\x2e\x35\x68\x31\x2e\x35\
+\x63\x2e\x35\x35\x20\x30\x20\x31\x20\x2e\x34\x35\x20\x31\x20\x31\
+\x68\x2e\x35\x76\x2d\x32\x68\x2d\x38\x7a\x22\x20\x2f\x3e\x0a\x3c\
+\x2f\x67\x3e\x0a\x3c\x2f\x73\x76\x67\x3e\x0a\
 "
 
 qt_resource_name = b"\
@@ -2384,11 +2384,40 @@
 \x00\x6f\xa6\x53\
 \x00\x69\
 \x00\x63\x00\x6f\x00\x6e\x00\x73\
-\x00\x15\
-\x0f\xc4\x59\xe7\
-\x00\x73\
-\x00\x75\x00\x62\x00\x64\x00\x69\x00\x72\x00\x65\x00\x63\x00\x74\x00\x6f\x00\x72\x00\x79\x00\x2d\x00\x6c\x00\x65\x00\x66\x00\x74\
-\x00\x2e\x00\x73\x00\x76\x00\x67\
+\x00\x0f\
+\x04\xf2\xa7\x87\
+\x00\x63\
+\x00\x6c\x00\x6f\x00\x73\x00\x65\x00\x64\x00\x63\x00\x75\x00\x72\x00\x76\x00\x65\x00\x2e\x00\x73\x00\x76\x00\x67\
+\x00\x07\
+\x0c\xf8\x5a\x07\
+\x00\x65\
+\x00\x79\x00\x65\x00\x2e\x00\x73\x00\x76\x00\x67\
+\x00\x0a\
+\x01\xca\x6d\x87\
+\x00\x62\
+\x00\x75\x00\x63\x00\x6b\x00\x65\x00\x74\x00\x2e\x00\x73\x00\x76\x00\x67\
+\x00\x11\
+\x0c\xdb\x38\xe7\
+\x00\x61\
+\x00\x6e\x00\x64\x00\x72\x00\x6f\x00\x69\x00\x64\x00\x2d\x00\x63\x00\x6c\x00\x6f\x00\x73\x00\x65\x00\x2e\x00\x73\x00\x76\x00\x67\
+\
+\x00\x0d\
+\x05\x20\xce\x87\
+\x00\x6f\
+\x00\x70\x00\x65\x00\x6e\x00\x63\x00\x75\x00\x72\x00\x76\x00\x65\x00\x2e\x00\x73\x00\x76\x00\x67\
+\x00\x10\
+\x08\x89\xfa\x47\
+\x00\x63\
+\x00\x65\x00\x6e\x00\x74\x00\x65\x00\x72\x00\x6f\x00\x72\x00\x69\x00\x67\x00\x69\x00\x6e\x00\x2e\x00\x73\x00\x76\x00\x67\
+\x00\x11\
+\x0c\xa7\xc7\x47\
+\x00\x63\
+\x00\x6c\x00\x6f\x00\x73\x00\x65\x00\x64\x00\x70\x00\x6f\x00\x6c\x00\x79\x00\x67\x00\x6f\x00\x6e\x00\x2e\x00\x73\x00\x76\x00\x67\
+\
+\x00\x10\
+\x0c\x57\x65\x47\
+\x00\x61\
+\x00\x72\x00\x72\x00\x6f\x00\x77\x00\x2d\x00\x72\x00\x65\x00\x73\x00\x69\x00\x7a\x00\x65\x00\x2e\x00\x73\x00\x76\x00\x67\
 \x00\x12\
 \x0c\x5e\xd4\xa7\
 \x00\x61\
@@ -2399,220 +2428,191 @@
 \x00\x61\
 \x00\x6e\x00\x64\x00\x72\x00\x6f\x00\x69\x00\x64\x00\x2d\x00\x64\x00\x65\x00\x6c\x00\x65\x00\x74\x00\x65\x00\x2e\x00\x73\x00\x76\
 \x00\x67\
-\x00\x19\
-\x0a\x43\x45\xc7\
-\x00\x61\
-\x00\x6e\x00\x64\x00\x72\x00\x6f\x00\x69\x00\x64\x00\x2d\x00\x61\x00\x72\x00\x72\x00\x6f\x00\x77\x00\x2d\x00\x66\x00\x6f\x00\x72\
-\x00\x77\x00\x61\x00\x72\x00\x64\x00\x2e\x00\x73\x00\x76\x00\x67\
-\x00\x08\
-\x0b\x07\x57\xa7\
-\x00\x65\
-\x00\x64\x00\x69\x00\x74\x00\x2e\x00\x73\x00\x76\x00\x67\
-\x00\x19\
-\x0f\xef\x7b\xe7\
-\x00\x61\
-\x00\x6e\x00\x64\x00\x72\x00\x6f\x00\x69\x00\x64\x00\x2d\x00\x63\x00\x6f\x00\x6c\x00\x6f\x00\x72\x00\x2d\x00\x70\x00\x61\x00\x6c\
-\x00\x65\x00\x74\x00\x74\x00\x65\x00\x2e\x00\x73\x00\x76\x00\x67\
 \x00\x10\
 \x08\xe4\xaf\x47\
 \x00\x61\
 \x00\x6e\x00\x64\x00\x72\x00\x6f\x00\x69\x00\x64\x00\x2d\x00\x64\x00\x6f\x00\x6e\x00\x65\x00\x2e\x00\x73\x00\x76\x00\x67\
-\x00\x11\
-\x01\x60\xbc\x47\
-\x00\x73\
-\x00\x6f\x00\x63\x00\x69\x00\x61\x00\x6c\x00\x2d\x00\x70\x00\x79\x00\x74\x00\x68\x00\x6f\x00\x6e\x00\x2e\x00\x73\x00\x76\x00\x67\
-\
-\x00\x07\
-\x0c\xf8\x5a\x07\
-\x00\x65\
-\x00\x79\x00\x65\x00\x2e\x00\x73\x00\x76\x00\x67\
-\x00\x0a\
-\x01\xca\x6d\x87\
-\x00\x62\
-\x00\x75\x00\x63\x00\x6b\x00\x65\x00\x74\x00\x2e\x00\x73\x00\x76\x00\x67\
-\x00\x10\
-\x04\xa9\x22\xc7\
-\x00\x66\
-\x00\x69\x00\x6c\x00\x6c\x00\x65\x00\x64\x00\x62\x00\x75\x00\x63\x00\x6b\x00\x65\x00\x74\x00\x2e\x00\x73\x00\x76\x00\x67\
-\x00\x1d\
-\x06\xec\xf4\xc7\
-\x00\x63\
-\x00\x68\x00\x65\x00\x76\x00\x72\x00\x6f\x00\x6e\x00\x2d\x00\x77\x00\x69\x00\x74\x00\x68\x00\x2d\x00\x63\x00\x69\x00\x72\x00\x63\
-\x00\x6c\x00\x65\x00\x2d\x00\x72\x00\x69\x00\x67\x00\x68\x00\x74\x00\x2e\x00\x73\x00\x76\x00\x67\
+\x00\x08\
+\x08\xf7\x57\x07\
+\x00\x67\
+\x00\x72\x00\x69\x00\x64\x00\x2e\x00\x73\x00\x76\x00\x67\
 \x00\x1c\
-\x04\x66\xe1\x67\
-\x00\x63\
-\x00\x68\x00\x65\x00\x76\x00\x72\x00\x6f\x00\x6e\x00\x2d\x00\x77\x00\x69\x00\x74\x00\x68\x00\x2d\x00\x63\x00\x69\x00\x72\x00\x63\
-\x00\x6c\x00\x65\x00\x2d\x00\x6c\x00\x65\x00\x66\x00\x74\x00\x2e\x00\x73\x00\x76\x00\x67\
-\x00\x0e\
-\x05\xed\x38\x67\
+\x08\x8a\x79\x07\
 \x00\x61\
-\x00\x72\x00\x72\x00\x6f\x00\x77\x00\x2d\x00\x6d\x00\x6f\x00\x76\x00\x65\x00\x2e\x00\x73\x00\x76\x00\x67\
-\x00\x10\
-\x06\xe3\xaf\xe7\
+\x00\x6e\x00\x64\x00\x72\x00\x6f\x00\x69\x00\x64\x00\x2d\x00\x72\x00\x61\x00\x64\x00\x69\x00\x6f\x00\x2d\x00\x62\x00\x75\x00\x74\
+\x00\x74\x00\x6f\x00\x6e\x00\x2d\x00\x6f\x00\x66\x00\x66\x00\x2e\x00\x73\x00\x76\x00\x67\
+\x00\x19\
+\x0a\x43\x45\xc7\
 \x00\x61\
-\x00\x6e\x00\x64\x00\x72\x00\x6f\x00\x69\x00\x64\x00\x2d\x00\x68\x00\x61\x00\x6e\x00\x64\x00\x2e\x00\x73\x00\x76\x00\x67\
-\x00\x14\
-\x0f\xa5\xe0\xc7\
-\x00\x6d\
-\x00\x61\x00\x67\x00\x6e\x00\x69\x00\x66\x00\x79\x00\x69\x00\x6e\x00\x67\x00\x2d\x00\x67\x00\x6c\x00\x61\x00\x73\x00\x73\x00\x2e\
-\x00\x73\x00\x76\x00\x67\
-\x00\x0d\
-\x05\x20\xce\x87\
-\x00\x6f\
-\x00\x70\x00\x65\x00\x6e\x00\x63\x00\x75\x00\x72\x00\x76\x00\x65\x00\x2e\x00\x73\x00\x76\x00\x67\
-\x00\x16\
-\x01\xfb\x76\x27\
-\x00\x61\
-\x00\x6e\x00\x64\x00\x72\x00\x6f\x00\x69\x00\x64\x00\x2d\x00\x61\x00\x72\x00\x72\x00\x6f\x00\x77\x00\x2d\x00\x62\x00\x61\x00\x63\
-\x00\x6b\x00\x2e\x00\x73\x00\x76\x00\x67\
+\x00\x6e\x00\x64\x00\x72\x00\x6f\x00\x69\x00\x64\x00\x2d\x00\x61\x00\x72\x00\x72\x00\x6f\x00\x77\x00\x2d\x00\x66\x00\x6f\x00\x72\
+\x00\x77\x00\x61\x00\x72\x00\x64\x00\x2e\x00\x73\x00\x76\x00\x67\
 \x00\x0e\
 \x0f\xcb\xd5\xc7\
 \x00\x70\
 \x00\x6c\x00\x75\x00\x73\x00\x2d\x00\x72\x00\x6f\x00\x75\x00\x6e\x00\x64\x00\x2e\x00\x73\x00\x76\x00\x67\
-\x00\x11\
-\x0c\xdb\x38\xe7\
+\x00\x13\
+\x03\x24\x75\x47\
 \x00\x61\
-\x00\x6e\x00\x64\x00\x72\x00\x6f\x00\x69\x00\x64\x00\x2d\x00\x63\x00\x6c\x00\x6f\x00\x73\x00\x65\x00\x2e\x00\x73\x00\x76\x00\x67\
-\
+\x00\x6e\x00\x64\x00\x72\x00\x6f\x00\x69\x00\x64\x00\x2d\x00\x72\x00\x65\x00\x66\x00\x72\x00\x65\x00\x73\x00\x68\x00\x2e\x00\x73\
+\x00\x76\x00\x67\
 \x00\x0a\
 \x0a\x2d\x1b\xc7\
 \x00\x63\
 \x00\x69\x00\x72\x00\x63\x00\x6c\x00\x65\x00\x2e\x00\x73\x00\x76\x00\x67\
-\x00\x12\
-\x04\xb2\x21\x47\
+\x00\x16\
+\x01\xfb\x76\x27\
 \x00\x61\
-\x00\x6e\x00\x64\x00\x72\x00\x6f\x00\x69\x00\x64\x00\x2d\x00\x65\x00\x78\x00\x70\x00\x61\x00\x6e\x00\x64\x00\x2e\x00\x73\x00\x76\
-\x00\x67\
-\x00\x0f\
-\x07\x0e\xc4\x87\
-\x00\x6f\
-\x00\x70\x00\x65\x00\x6e\x00\x70\x00\x6f\x00\x6c\x00\x79\x00\x67\x00\x6f\x00\x6e\x00\x2e\x00\x73\x00\x76\x00\x67\
-\x00\x17\
-\x07\x87\x48\x27\
-\x00\x61\
-\x00\x6e\x00\x64\x00\x72\x00\x6f\x00\x69\x00\x64\x00\x2d\x00\x66\x00\x6f\x00\x6c\x00\x64\x00\x65\x00\x72\x00\x2d\x00\x6f\x00\x70\
-\x00\x65\x00\x6e\x00\x2e\x00\x73\x00\x76\x00\x67\
-\x00\x0f\
-\x04\xf2\xa7\x87\
+\x00\x6e\x00\x64\x00\x72\x00\x6f\x00\x69\x00\x64\x00\x2d\x00\x61\x00\x72\x00\x72\x00\x6f\x00\x77\x00\x2d\x00\x62\x00\x61\x00\x63\
+\x00\x6b\x00\x2e\x00\x73\x00\x76\x00\x67\
+\x00\x09\
+\x0b\x9e\x89\x07\
 \x00\x63\
-\x00\x6c\x00\x6f\x00\x73\x00\x65\x00\x64\x00\x63\x00\x75\x00\x72\x00\x76\x00\x65\x00\x2e\x00\x73\x00\x76\x00\x67\
-\x00\x12\
-\x08\x79\x97\xe7\
-\x00\x61\
-\x00\x6e\x00\x64\x00\x72\x00\x6f\x00\x69\x00\x64\x00\x2d\x00\x63\x00\x61\x00\x6d\x00\x65\x00\x72\x00\x61\x00\x2e\x00\x73\x00\x76\
-\x00\x67\
-\x00\x10\
-\x0c\x57\x65\x47\
-\x00\x61\
-\x00\x72\x00\x72\x00\x6f\x00\x77\x00\x2d\x00\x72\x00\x65\x00\x73\x00\x69\x00\x7a\x00\x65\x00\x2e\x00\x73\x00\x76\x00\x67\
-\x00\x11\
-\x0c\xa7\xc7\x47\
-\x00\x63\
-\x00\x6c\x00\x6f\x00\x73\x00\x65\x00\x64\x00\x70\x00\x6f\x00\x6c\x00\x79\x00\x67\x00\x6f\x00\x6e\x00\x2e\x00\x73\x00\x76\x00\x67\
-\
+\x00\x68\x00\x65\x00\x63\x00\x6b\x00\x2e\x00\x73\x00\x76\x00\x67\
+\x00\x15\
+\x0f\xc4\x59\xe7\
+\x00\x73\
+\x00\x75\x00\x62\x00\x64\x00\x69\x00\x72\x00\x65\x00\x63\x00\x74\x00\x6f\x00\x72\x00\x79\x00\x2d\x00\x6c\x00\x65\x00\x66\x00\x74\
+\x00\x2e\x00\x73\x00\x76\x00\x67\
+\x00\x14\
+\x0f\xa5\xe0\xc7\
+\x00\x6d\
+\x00\x61\x00\x67\x00\x6e\x00\x69\x00\x66\x00\x79\x00\x69\x00\x6e\x00\x67\x00\x2d\x00\x67\x00\x6c\x00\x61\x00\x73\x00\x73\x00\x2e\
+\x00\x73\x00\x76\x00\x67\
 \x00\x17\
 \x06\xc6\x02\xa7\
 \x00\x74\
 \x00\x72\x00\x69\x00\x61\x00\x6e\x00\x67\x00\x6c\x00\x65\x00\x2d\x00\x73\x00\x74\x00\x72\x00\x6f\x00\x6b\x00\x65\x00\x64\x00\x2d\
 \x00\x31\x00\x35\x00\x2e\x00\x73\x00\x76\x00\x67\
-\x00\x09\
-\x0b\x9e\x89\x07\
-\x00\x63\
-\x00\x68\x00\x65\x00\x63\x00\x6b\x00\x2e\x00\x73\x00\x76\x00\x67\
 \x00\x08\
 \x05\xa8\x57\x87\
 \x00\x63\
 \x00\x6f\x00\x64\x00\x65\x00\x2e\x00\x73\x00\x76\x00\x67\
+\x00\x10\
+\x06\xe3\xaf\xe7\
+\x00\x61\
+\x00\x6e\x00\x64\x00\x72\x00\x6f\x00\x69\x00\x64\x00\x2d\x00\x68\x00\x61\x00\x6e\x00\x64\x00\x2e\x00\x73\x00\x76\x00\x67\
+\x00\x08\
+\x08\xc8\x55\xe7\
+\x00\x73\
+\x00\x61\x00\x76\x00\x65\x00\x2e\x00\x73\x00\x76\x00\x67\
+\x00\x0e\
+\x05\xed\x38\x67\
+\x00\x61\
+\x00\x72\x00\x72\x00\x6f\x00\x77\x00\x2d\x00\x6d\x00\x6f\x00\x76\x00\x65\x00\x2e\x00\x73\x00\x76\x00\x67\
+\x00\x11\
+\x01\x60\xbc\x47\
+\x00\x73\
+\x00\x6f\x00\x63\x00\x69\x00\x61\x00\x6c\x00\x2d\x00\x70\x00\x79\x00\x74\x00\x68\x00\x6f\x00\x6e\x00\x2e\x00\x73\x00\x76\x00\x67\
+\
+\x00\x1d\
+\x06\xec\xf4\xc7\
+\x00\x63\
+\x00\x68\x00\x65\x00\x76\x00\x72\x00\x6f\x00\x6e\x00\x2d\x00\x77\x00\x69\x00\x74\x00\x68\x00\x2d\x00\x63\x00\x69\x00\x72\x00\x63\
+\x00\x6c\x00\x65\x00\x2d\x00\x72\x00\x69\x00\x67\x00\x68\x00\x74\x00\x2e\x00\x73\x00\x76\x00\x67\
 \x00\x1b\
 \x0e\xb5\x68\xe7\
 \x00\x61\
 \x00\x6e\x00\x64\x00\x72\x00\x6f\x00\x69\x00\x64\x00\x2d\x00\x72\x00\x61\x00\x64\x00\x69\x00\x6f\x00\x2d\x00\x62\x00\x75\x00\x74\
 \x00\x74\x00\x6f\x00\x6e\x00\x2d\x00\x6f\x00\x6e\x00\x2e\x00\x73\x00\x76\x00\x67\
-\x00\x08\
-\x0c\xf7\x55\x87\
-\x00\x74\
-\x00\x65\x00\x78\x00\x74\x00\x2e\x00\x73\x00\x76\x00\x67\
+\x00\x12\
+\x08\x79\x97\xe7\
+\x00\x61\
+\x00\x6e\x00\x64\x00\x72\x00\x6f\x00\x69\x00\x64\x00\x2d\x00\x63\x00\x61\x00\x6d\x00\x65\x00\x72\x00\x61\x00\x2e\x00\x73\x00\x76\
+\x00\x67\
+\x00\x1c\
+\x04\x66\xe1\x67\
+\x00\x63\
+\x00\x68\x00\x65\x00\x76\x00\x72\x00\x6f\x00\x6e\x00\x2d\x00\x77\x00\x69\x00\x74\x00\x68\x00\x2d\x00\x63\x00\x69\x00\x72\x00\x63\
+\x00\x6c\x00\x65\x00\x2d\x00\x6c\x00\x65\x00\x66\x00\x74\x00\x2e\x00\x73\x00\x76\x00\x67\
+\x00\x17\
+\x07\x87\x48\x27\
+\x00\x61\
+\x00\x6e\x00\x64\x00\x72\x00\x6f\x00\x69\x00\x64\x00\x2d\x00\x66\x00\x6f\x00\x6c\x00\x64\x00\x65\x00\x72\x00\x2d\x00\x6f\x00\x70\
+\x00\x65\x00\x6e\x00\x2e\x00\x73\x00\x76\x00\x67\
 \x00\x0a\
 \x0a\xc8\x62\x67\
 \x00\x63\
 \x00\x65\x00\x6e\x00\x74\x00\x65\x00\x72\x00\x2e\x00\x73\x00\x76\x00\x67\
-\x00\x08\
-\x08\xc8\x55\xe7\
-\x00\x73\
-\x00\x61\x00\x76\x00\x65\x00\x2e\x00\x73\x00\x76\x00\x67\
-\x00\x1c\
-\x08\x8a\x79\x07\
-\x00\x61\
-\x00\x6e\x00\x64\x00\x72\x00\x6f\x00\x69\x00\x64\x00\x2d\x00\x72\x00\x61\x00\x64\x00\x69\x00\x6f\x00\x2d\x00\x62\x00\x75\x00\x74\
-\x00\x74\x00\x6f\x00\x6e\x00\x2d\x00\x6f\x00\x66\x00\x66\x00\x2e\x00\x73\x00\x76\x00\x67\
-\x00\x08\
-\x08\xf7\x57\x07\
-\x00\x67\
-\x00\x72\x00\x69\x00\x64\x00\x2e\x00\x73\x00\x76\x00\x67\
-\x00\x10\
-\x08\x89\xfa\x47\
-\x00\x63\
-\x00\x65\x00\x6e\x00\x74\x00\x65\x00\x72\x00\x6f\x00\x72\x00\x69\x00\x67\x00\x69\x00\x6e\x00\x2e\x00\x73\x00\x76\x00\x67\
 \x00\x0f\
 \x09\x76\x60\xc7\
 \x00\x63\
 \x00\x6c\x00\x6f\x00\x73\x00\x65\x00\x2d\x00\x72\x00\x6f\x00\x75\x00\x6e\x00\x64\x00\x2e\x00\x73\x00\x76\x00\x67\
-\x00\x13\
-\x03\x24\x75\x47\
-\x00\x61\
-\x00\x6e\x00\x64\x00\x72\x00\x6f\x00\x69\x00\x64\x00\x2d\x00\x72\x00\x65\x00\x66\x00\x72\x00\x65\x00\x73\x00\x68\x00\x2e\x00\x73\
-\x00\x76\x00\x67\
+\x00\x10\
+\x04\xa9\x22\xc7\
+\x00\x66\
+\x00\x69\x00\x6c\x00\x6c\x00\x65\x00\x64\x00\x62\x00\x75\x00\x63\x00\x6b\x00\x65\x00\x74\x00\x2e\x00\x73\x00\x76\x00\x67\
 \x00\x0a\
 \x0f\x68\x53\xe7\
 \x00\x61\
 \x00\x6e\x00\x63\x00\x68\x00\x6f\x00\x72\x00\x2e\x00\x73\x00\x76\x00\x67\
+\x00\x0f\
+\x07\x0e\xc4\x87\
+\x00\x6f\
+\x00\x70\x00\x65\x00\x6e\x00\x70\x00\x6f\x00\x6c\x00\x79\x00\x67\x00\x6f\x00\x6e\x00\x2e\x00\x73\x00\x76\x00\x67\
+\x00\x08\
+\x0b\x07\x57\xa7\
+\x00\x65\
+\x00\x64\x00\x69\x00\x74\x00\x2e\x00\x73\x00\x76\x00\x67\
+\x00\x12\
+\x04\xb2\x21\x47\
+\x00\x61\
+\x00\x6e\x00\x64\x00\x72\x00\x6f\x00\x69\x00\x64\x00\x2d\x00\x65\x00\x78\x00\x70\x00\x61\x00\x6e\x00\x64\x00\x2e\x00\x73\x00\x76\
+\x00\x67\
+\x00\x19\
+\x0f\xef\x7b\xe7\
+\x00\x61\
+\x00\x6e\x00\x64\x00\x72\x00\x6f\x00\x69\x00\x64\x00\x2d\x00\x63\x00\x6f\x00\x6c\x00\x6f\x00\x72\x00\x2d\x00\x70\x00\x61\x00\x6c\
+\x00\x65\x00\x74\x00\x74\x00\x65\x00\x2e\x00\x73\x00\x76\x00\x67\
+\x00\x08\
+\x0c\xf7\x55\x87\
+\x00\x74\
+\x00\x65\x00\x78\x00\x74\x00\x2e\x00\x73\x00\x76\x00\x67\
 "
 
 qt_resource_struct_v1 = b"\
 \x00\x00\x00\x00\x00\x02\x00\x00\x00\x01\x00\x00\x00\x01\
 \x00\x00\x00\x00\x00\x02\x00\x00\x00\x29\x00\x00\x00\x02\
-\x00\x00\x01\x40\x00\x00\x00\x00\x00\x01\x00\x00\x15\x17\
-\x00\x00\x01\x7c\x00\x00\x00\x00\x00\x01\x00\x00\x20\x8a\
-\x00\x00\x02\xd0\x00\x00\x00\x00\x00\x01\x00\x00\x41\x73\
-\x00\x00\x06\x06\x00\x00\x00\x00\x00\x01\x00\x00\x89\xb1\
-\x00\x00\x01\xfc\x00\x00\x00\x00\x00\x01\x00\x00\x2c\x71\
-\x00\x00\x01\x96\x00\x01\x00\x00\x00\x01\x00\x00\x26\x62\
-\x00\x00\x03\x66\x00\x00\x00\x00\x00\x01\x00\x00\x4c\xa0\
-\x00\x00\x03\xe8\x00\x00\x00\x00\x00\x01\x00\x00\x57\x71\
-\x00\x00\x02\xb0\x00\x00\x00\x00\x00\x01\x00\x00\x3c\xcd\
-\x00\x00\x04\xd0\x00\x00\x00\x00\x00\x01\x00\x00\x6e\x23\
-\x00\x00\x02\x3a\x00\x00\x00\x00\x00\x01\x00\x00\x30\x6a\
-\x00\x00\x04\x84\x00\x00\x00\x00\x00\x01\x00\x00\x66\x45\
-\x00\x00\x02\x5c\x00\x00\x00\x00\x00\x01\x00\x00\x33\x37\
-\x00\x00\x01\xbc\x00\x00\x00\x00\x00\x01\x00\x00\x28\x87\
-\x00\x00\x03\x90\x00\x00\x00\x00\x00\x01\x00\x00\x4f\xda\
-\x00\x00\x03\xb4\x00\x00\x00\x00\x00\x01\x00\x00\x54\x1b\
-\x00\x00\x00\x6a\x00\x00\x00\x00\x00\x01\x00\x00\x04\xd8\
-\x00\x00\x04\x0c\x00\x00\x00\x00\x00\x01\x00\x00\x5c\x4a\
-\x00\x00\x05\xbc\x00\x00\x00\x00\x00\x01\x00\x00\x82\x47\
-\x00\x00\x05\x68\x00\x00\x00\x00\x00\x01\x00\x00\x7d\x66\
-\x00\x00\x05\x52\x00\x00\x00\x00\x00\x01\x00\x00\x7a\xc1\
-\x00\x00\x01\x1a\x00\x00\x00\x00\x00\x01\x00\x00\x12\x9a\
-\x00\x00\x05\xa6\x00\x01\x00\x00\x00\x01\x00\x00\x80\x66\
-\x00\x00\x05\xe2\x00\x00\x00\x00\x00\x01\x00\x00\x86\x67\
-\x00\x00\x03\x4c\x00\x00\x00\x00\x00\x01\x00\x00\x49\xaa\
-\x00\x00\x00\x94\x00\x00\x00\x00\x00\x01\x00\x00\x07\x7e\
-\x00\x00\x05\x38\x00\x00\x00\x00\x00\x01\x00\x00\x77\x41\
-\x00\x00\x00\xcc\x00\x00\x00\x00\x00\x01\x00\x00\x09\xff\
-\x00\x00\x04\xb8\x00\x00\x00\x00\x00\x01\x00\x00\x6b\x13\
-\x00\x00\x04\x36\x00\x00\x00\x00\x00\x01\x00\x00\x5f\x70\
-\x00\x00\x00\x40\x00\x00\x00\x00\x00\x01\x00\x00\x00\x70\
-\x00\x00\x04\x5c\x00\x00\x00\x00\x00\x01\x00\x00\x61\xf3\
-\x00\x00\x03\x24\x00\x00\x00\x00\x00\x01\x00\x00\x46\xef\
-\x00\x00\x05\x22\x00\x00\x00\x00\x00\x01\x00\x00\x76\x21\
-\x00\x00\x01\x68\x00\x00\x00\x00\x00\x01\x00\x00\x1c\x9b\
-\x00\x00\x04\xe6\x00\x00\x00\x00\x00\x01\x00\x00\x72\xd1\
-\x00\x00\x06\x32\x00\x00\x00\x00\x00\x01\x00\x00\x8c\xdb\
-\x00\x00\x02\x82\x00\x00\x00\x00\x00\x01\x00\x00\x39\x05\
+\x00\x00\x03\xdc\x00\x00\x00\x00\x00\x01\x00\x00\x59\x83\
+\x00\x00\x00\x48\x00\x00\x00\x00\x00\x01\x00\x00\x08\xc8\
+\x00\x00\x02\x8c\x00\x00\x00\x00\x00\x01\x00\x00\x3a\xfe\
+\x00\x00\x02\x46\x00\x00\x00\x00\x00\x01\x00\x00\x34\xde\
+\x00\x00\x04\xaa\x00\x00\x00\x00\x00\x01\x00\x00\x6b\x67\
+\x00\x00\x05\x5a\x00\x01\x00\x00\x00\x01\x00\x00\x79\x80\
+\x00\x00\x05\xd4\x00\x00\x00\x00\x00\x01\x00\x00\x84\xc3\
 \x00\x00\x00\x10\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\
-\x00\x00\x03\x02\x00\x00\x00\x00\x00\x01\x00\x00\x43\xf4\
-\x00\x00\x00\xe2\x00\x00\x00\x00\x00\x01\x00\x00\x0d\x6f\
+\x00\x00\x00\x8a\x00\x00\x00\x00\x00\x01\x00\x00\x11\x5b\
+\x00\x00\x03\x68\x00\x00\x00\x00\x00\x01\x00\x00\x49\x95\
+\x00\x00\x03\xba\x00\x00\x00\x00\x00\x01\x00\x00\x56\xb6\
+\x00\x00\x03\x34\x00\x00\x00\x00\x00\x01\x00\x00\x44\xc7\
+\x00\x00\x03\x7e\x00\x00\x00\x00\x00\x01\x00\x00\x4e\x43\
+\x00\x00\x04\x04\x00\x00\x00\x00\x00\x01\x00\x00\x61\x07\
+\x00\x00\x05\x9a\x00\x00\x00\x00\x00\x01\x00\x00\x7d\x12\
+\x00\x00\x04\xe8\x00\x00\x00\x00\x00\x01\x00\x00\x6f\x60\
+\x00\x00\x01\x48\x00\x00\x00\x00\x00\x01\x00\x00\x25\x5e\
+\x00\x00\x04\x80\x00\x00\x00\x00\x00\x01\x00\x00\x68\x41\
+\x00\x00\x00\xaa\x00\x00\x00\x00\x00\x01\x00\x00\x16\x01\
+\x00\x00\x01\xae\x00\x00\x00\x00\x00\x01\x00\x00\x2c\x62\
+\x00\x00\x03\xa4\x00\x00\x00\x00\x00\x01\x00\x00\x54\x11\
+\x00\x00\x01\x72\x00\x00\x00\x00\x00\x01\x00\x00\x28\x04\
+\x00\x00\x01\x98\x00\x01\x00\x00\x00\x01\x00\x00\x2a\x81\
+\x00\x00\x05\x36\x00\x00\x00\x00\x00\x01\x00\x00\x76\x36\
+\x00\x00\x02\x72\x00\x00\x00\x00\x00\x01\x00\x00\x38\x08\
+\x00\x00\x01\xec\x00\x00\x00\x00\x00\x01\x00\x00\x2f\x62\
+\x00\x00\x05\x1c\x00\x00\x00\x00\x00\x01\x00\x00\x72\xb6\
+\x00\x00\x05\xbe\x00\x00\x00\x00\x00\x01\x00\x00\x81\x53\
+\x00\x00\x02\xbe\x00\x00\x00\x00\x00\x01\x00\x00\x3d\x7f\
+\x00\x00\x00\xf8\x00\x00\x00\x00\x00\x01\x00\x00\x1e\x73\
+\x00\x00\x01\x1e\x00\x00\x00\x00\x00\x01\x00\x00\x20\xf6\
+\x00\x00\x00\xd0\x00\x00\x00\x00\x00\x01\x00\x00\x1a\x21\
+\x00\x00\x00\x62\x00\x00\x00\x00\x00\x01\x00\x00\x0e\xa0\
+\x00\x00\x06\x36\x00\x00\x00\x00\x00\x01\x00\x00\x8d\x28\
+\x00\x00\x00\x34\x00\x00\x00\x00\x00\x01\x00\x00\x04\xd9\
+\x00\x00\x04\x44\x00\x00\x00\x00\x00\x01\x00\x00\x64\xf1\
+\x00\x00\x05\x80\x00\x00\x00\x00\x00\x01\x00\x00\x7b\xa5\
+\x00\x00\x03\x06\x00\x00\x00\x00\x00\x01\x00\x00\x40\xff\
+\x00\x00\x02\xd6\x00\x00\x00\x00\x00\x01\x00\x00\x40\x8f\
+\x00\x00\x02\x24\x00\x00\x00\x00\x00\x01\x00\x00\x31\xe3\
+\x00\x00\x05\xfe\x00\x00\x00\x00\x00\x01\x00\x00\x87\xfd\
 "
 
 qt_resource_struct_v2 = b"\
@@ -2620,88 +2620,88 @@
 \x00\x00\x00\x00\x00\x00\x00\x00\
 \x00\x00\x00\x00\x00\x02\x00\x00\x00\x29\x00\x00\x00\x02\
 \x00\x00\x00\x00\x00\x00\x00\x00\
-\x00\x00\x01\x40\x00\x00\x00\x00\x00\x01\x00\x00\x15\x17\
-\x00\x00\x01\x6f\xa6\xde\xd7\x4a\
-\x00\x00\x01\x7c\x00\x00\x00\x00\x00\x01\x00\x00\x20\x8a\
-\x00\x00\x01\x6f\xa6\xde\xd7\x49\
-\x00\x00\x02\xd0\x00\x00\x00\x00\x00\x01\x00\x00\x41\x73\
-\x00\x00\x01\x6f\xa6\xde\xd7\x48\
-\x00\x00\x06\x06\x00\x00\x00\x00\x00\x01\x00\x00\x89\xb1\
-\x00\x00\x01\x6f\xa6\xde\xd7\x48\
-\x00\x00\x01\xfc\x00\x00\x00\x00\x00\x01\x00\x00\x2c\x71\
-\x00\x00\x01\x6f\xa6\xde\xd7\x49\
-\x00\x00\x01\x96\x00\x01\x00\x00\x00\x01\x00\x00\x26\x62\
-\x00\x00\x01\x6f\xa6\xde\xd7\x49\
-\x00\x00\x03\x66\x00\x00\x00\x00\x00\x01\x00\x00\x4c\xa0\
-\x00\x00\x01\x6f\xa6\xde\xd7\x48\
-\x00\x00\x03\xe8\x00\x00\x00\x00\x00\x01\x00\x00\x57\x71\
-\x00\x00\x01\x6f\xa6\xde\xd7\x49\
-\x00\x00\x02\xb0\x00\x00\x00\x00\x00\x01\x00\x00\x3c\xcd\
-\x00\x00\x01\x6f\xa6\xde\xd7\x49\
-\x00\x00\x04\xd0\x00\x00\x00\x00\x00\x01\x00\x00\x6e\x23\
-\x00\x00\x01\x6f\xa6\xde\xd7\x49\
-\x00\x00\x02\x3a\x00\x00\x00\x00\x00\x01\x00\x00\x30\x6a\
-\x00\x00\x01\x6f\xa6\xde\xd7\x49\
-\x00\x00\x04\x84\x00\x00\x00\x00\x00\x01\x00\x00\x66\x45\
-\x00\x00\x01\x6f\xa6\xde\xd7\x4a\
-\x00\x00\x02\x5c\x00\x00\x00\x00\x00\x01\x00\x00\x33\x37\
-\x00\x00\x01\x6f\xa6\xde\xd7\x48\
-\x00\x00\x01\xbc\x00\x00\x00\x00\x00\x01\x00\x00\x28\x87\
-\x00\x00\x01\x6f\xa6\xde\xd7\x49\
-\x00\x00\x03\x90\x00\x00\x00\x00\x00\x01\x00\x00\x4f\xda\
-\x00\x00\x01\x6f\xa6\xde\xd7\x49\
-\x00\x00\x03\xb4\x00\x00\x00\x00\x00\x01\x00\x00\x54\x1b\
-\x00\x00\x01\x6f\xa6\xde\xd7\x48\
-\x00\x00\x00\x6a\x00\x00\x00\x00\x00\x01\x00\x00\x04\xd8\
-\x00\x00\x01\x6f\xa6\xde\xd7\x48\
-\x00\x00\x04\x0c\x00\x00\x00\x00\x00\x01\x00\x00\x5c\x4a\
-\x00\x00\x01\x6f\xa6\xde\xd7\x48\
-\x00\x00\x05\xbc\x00\x00\x00\x00\x00\x01\x00\x00\x82\x47\
-\x00\x00\x01\x6f\xa6\xde\xd7\x49\
-\x00\x00\x05\x68\x00\x00\x00\x00\x00\x01\x00\x00\x7d\x66\
-\x00\x00\x01\x6f\xa6\xde\xd7\x48\
-\x00\x00\x05\x52\x00\x00\x00\x00\x00\x01\x00\x00\x7a\xc1\
-\x00\x00\x01\x6f\xa6\xde\xd7\x4a\
-\x00\x00\x01\x1a\x00\x00\x00\x00\x00\x01\x00\x00\x12\x9a\
-\x00\x00\x01\x6f\xa6\xde\xd7\x48\
-\x00\x00\x05\xa6\x00\x01\x00\x00\x00\x01\x00\x00\x80\x66\
-\x00\x00\x01\x6f\xa6\xde\xd7\x49\
-\x00\x00\x05\xe2\x00\x00\x00\x00\x00\x01\x00\x00\x86\x67\
-\x00\x00\x01\x6f\xa6\xde\xd7\x49\
-\x00\x00\x03\x4c\x00\x00\x00\x00\x00\x01\x00\x00\x49\xaa\
-\x00\x00\x01\x6f\xa6\xde\xd7\x49\
-\x00\x00\x00\x94\x00\x00\x00\x00\x00\x01\x00\x00\x07\x7e\
-\x00\x00\x01\x6f\xa6\xde\xd7\x48\
-\x00\x00\x05\x38\x00\x00\x00\x00\x00\x01\x00\x00\x77\x41\
-\x00\x00\x01\x6f\xa6\xde\xd7\x49\
-\x00\x00\x00\xcc\x00\x00\x00\x00\x00\x01\x00\x00\x09\xff\
-\x00\x00\x01\x6f\xa6\xde\xd7\x49\
-\x00\x00\x04\xb8\x00\x00\x00\x00\x00\x01\x00\x00\x6b\x13\
-\x00\x00\x01\x6f\xa6\xde\xd7\x49\
-\x00\x00\x04\x36\x00\x00\x00\x00\x00\x01\x00\x00\x5f\x70\
-\x00\x00\x01\x6f\xa6\xde\xd7\x49\
-\x00\x00\x00\x40\x00\x00\x00\x00\x00\x01\x00\x00\x00\x70\
-\x00\x00\x01\x6f\xa6\xde\xd7\x48\
-\x00\x00\x04\x5c\x00\x00\x00\x00\x00\x01\x00\x00\x61\xf3\
-\x00\x00\x01\x6f\xa6\xde\xd7\x49\
-\x00\x00\x03\x24\x00\x00\x00\x00\x00\x01\x00\x00\x46\xef\
-\x00\x00\x01\x6f\xa6\xde\xd7\x48\
-\x00\x00\x05\x22\x00\x00\x00\x00\x00\x01\x00\x00\x76\x21\
-\x00\x00\x01\x6f\xa6\xde\xd7\x4a\
-\x00\x00\x01\x68\x00\x00\x00\x00\x00\x01\x00\x00\x1c\x9b\
-\x00\x00\x01\x6f\xa6\xde\xd7\x49\
-\x00\x00\x04\xe6\x00\x00\x00\x00\x00\x01\x00\x00\x72\xd1\
-\x00\x00\x01\x6f\xa6\xde\xd7\x48\
-\x00\x00\x06\x32\x00\x00\x00\x00\x00\x01\x00\x00\x8c\xdb\
-\x00\x00\x01\x6f\xa6\xde\xd7\x48\
-\x00\x00\x02\x82\x00\x00\x00\x00\x00\x01\x00\x00\x39\x05\
-\x00\x00\x01\x6f\xa6\xde\xd7\x49\
+\x00\x00\x03\xdc\x00\x00\x00\x00\x00\x01\x00\x00\x59\x83\
+\x00\x00\x01\x70\x9e\xd3\x06\xe0\
+\x00\x00\x00\x48\x00\x00\x00\x00\x00\x01\x00\x00\x08\xc8\
+\x00\x00\x01\x70\x9e\xd3\x06\xdf\
+\x00\x00\x02\x8c\x00\x00\x00\x00\x00\x01\x00\x00\x3a\xfe\
+\x00\x00\x01\x70\x9e\xd3\x06\xdf\
+\x00\x00\x02\x46\x00\x00\x00\x00\x00\x01\x00\x00\x34\xde\
+\x00\x00\x01\x70\x9e\xd3\x06\xdf\
+\x00\x00\x04\xaa\x00\x00\x00\x00\x00\x01\x00\x00\x6b\x67\
+\x00\x00\x01\x70\x9e\xd3\x06\xe0\
+\x00\x00\x05\x5a\x00\x01\x00\x00\x00\x01\x00\x00\x79\x80\
+\x00\x00\x01\x70\x9e\xd3\x06\xe0\
+\x00\x00\x05\xd4\x00\x00\x00\x00\x00\x01\x00\x00\x84\xc3\
+\x00\x00\x01\x70\x9e\xd3\x06\xdf\
 \x00\x00\x00\x10\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\
-\x00\x00\x01\x6f\xa6\xde\xd7\x4a\
-\x00\x00\x03\x02\x00\x00\x00\x00\x00\x01\x00\x00\x43\xf4\
-\x00\x00\x01\x6f\xa6\xde\xd7\x49\
-\x00\x00\x00\xe2\x00\x00\x00\x00\x00\x01\x00\x00\x0d\x6f\
-\x00\x00\x01\x6f\xa6\xde\xd7\x48\
+\x00\x00\x01\x70\x9e\xd3\x06\xe0\
+\x00\x00\x00\x8a\x00\x00\x00\x00\x00\x01\x00\x00\x11\x5b\
+\x00\x00\x01\x70\x9e\xd3\x06\xe0\
+\x00\x00\x03\x68\x00\x00\x00\x00\x00\x01\x00\x00\x49\x95\
+\x00\x00\x01\x70\x9e\xd3\x06\xe0\
+\x00\x00\x03\xba\x00\x00\x00\x00\x00\x01\x00\x00\x56\xb6\
+\x00\x00\x01\x70\x9e\xd3\x06\xdf\
+\x00\x00\x03\x34\x00\x00\x00\x00\x00\x01\x00\x00\x44\xc7\
+\x00\x00\x01\x70\x9e\xd3\x06\xe0\
+\x00\x00\x03\x7e\x00\x00\x00\x00\x00\x01\x00\x00\x4e\x43\
+\x00\x00\x01\x70\x9e\xd3\x06\xdf\
+\x00\x00\x04\x04\x00\x00\x00\x00\x00\x01\x00\x00\x61\x07\
+\x00\x00\x01\x70\x9e\xd3\x06\xe0\
+\x00\x00\x05\x9a\x00\x00\x00\x00\x00\x01\x00\x00\x7d\x12\
+\x00\x00\x01\x70\x9e\xd3\x06\xe0\
+\x00\x00\x04\xe8\x00\x00\x00\x00\x00\x01\x00\x00\x6f\x60\
+\x00\x00\x01\x70\x9e\xd3\x06\xdf\
+\x00\x00\x01\x48\x00\x00\x00\x00\x00\x01\x00\x00\x25\x5e\
+\x00\x00\x01\x70\x9e\xd3\x06\xdf\
+\x00\x00\x04\x80\x00\x00\x00\x00\x00\x01\x00\x00\x68\x41\
+\x00\x00\x01\x70\x9e\xd3\x06\xdf\
+\x00\x00\x00\xaa\x00\x00\x00\x00\x00\x01\x00\x00\x16\x01\
+\x00\x00\x01\x70\x9e\xd3\x06\xe0\
+\x00\x00\x01\xae\x00\x00\x00\x00\x00\x01\x00\x00\x2c\x62\
+\x00\x00\x01\x70\x9e\xd3\x06\xdf\
+\x00\x00\x03\xa4\x00\x00\x00\x00\x00\x01\x00\x00\x54\x11\
+\x00\x00\x01\x70\x9e\xd3\x06\xe0\
+\x00\x00\x01\x72\x00\x00\x00\x00\x00\x01\x00\x00\x28\x04\
+\x00\x00\x01\x70\x9e\xd3\x06\xdf\
+\x00\x00\x01\x98\x00\x01\x00\x00\x00\x01\x00\x00\x2a\x81\
+\x00\x00\x01\x70\x9e\xd3\x06\xe0\
+\x00\x00\x05\x36\x00\x00\x00\x00\x00\x01\x00\x00\x76\x36\
+\x00\x00\x01\x70\x9e\xd3\x06\xe0\
+\x00\x00\x02\x72\x00\x00\x00\x00\x00\x01\x00\x00\x38\x08\
+\x00\x00\x01\x70\x9e\xd3\x06\xe0\
+\x00\x00\x01\xec\x00\x00\x00\x00\x00\x01\x00\x00\x2f\x62\
+\x00\x00\x01\x70\x9e\xd3\x06\xdf\
+\x00\x00\x05\x1c\x00\x00\x00\x00\x00\x01\x00\x00\x72\xb6\
+\x00\x00\x01\x70\x9e\xd3\x06\xdf\
+\x00\x00\x05\xbe\x00\x00\x00\x00\x00\x01\x00\x00\x81\x53\
+\x00\x00\x01\x70\x9e\xd3\x06\xe0\
+\x00\x00\x02\xbe\x00\x00\x00\x00\x00\x01\x00\x00\x3d\x7f\
+\x00\x00\x01\x70\x9e\xd3\x06\xe0\
+\x00\x00\x00\xf8\x00\x00\x00\x00\x00\x01\x00\x00\x1e\x73\
+\x00\x00\x01\x70\x9e\xd3\x06\xdf\
+\x00\x00\x01\x1e\x00\x00\x00\x00\x00\x01\x00\x00\x20\xf6\
+\x00\x00\x01\x70\x9e\xd3\x06\xdf\
+\x00\x00\x00\xd0\x00\x00\x00\x00\x00\x01\x00\x00\x1a\x21\
+\x00\x00\x01\x70\x9e\xd3\x06\xe0\
+\x00\x00\x00\x62\x00\x00\x00\x00\x00\x01\x00\x00\x0e\xa0\
+\x00\x00\x01\x70\x9e\xd3\x06\xdf\
+\x00\x00\x06\x36\x00\x00\x00\x00\x00\x01\x00\x00\x8d\x28\
+\x00\x00\x01\x70\x9e\xd3\x06\xe0\
+\x00\x00\x00\x34\x00\x00\x00\x00\x00\x01\x00\x00\x04\xd9\
+\x00\x00\x01\x70\x9e\xd3\x06\xe0\
+\x00\x00\x04\x44\x00\x00\x00\x00\x00\x01\x00\x00\x64\xf1\
+\x00\x00\x01\x70\x9e\xd3\x06\xdf\
+\x00\x00\x05\x80\x00\x00\x00\x00\x00\x01\x00\x00\x7b\xa5\
+\x00\x00\x01\x70\x9e\xd3\x06\xdf\
+\x00\x00\x03\x06\x00\x00\x00\x00\x00\x01\x00\x00\x40\xff\
+\x00\x00\x01\x70\x9e\xd3\x06\xe0\
+\x00\x00\x02\xd6\x00\x00\x00\x00\x00\x01\x00\x00\x40\x8f\
+\x00\x00\x01\x70\x9e\xd3\x06\xe0\
+\x00\x00\x02\x24\x00\x00\x00\x00\x00\x01\x00\x00\x31\xe3\
+\x00\x00\x01\x70\x9e\xd3\x06\xe0\
+\x00\x00\x05\xfe\x00\x00\x00\x00\x00\x01\x00\x00\x87\xfd\
+\x00\x00\x01\x70\x9e\xd3\x06\xdf\
 "
 
 qt_version = [int(v) for v in QtCore.qVersion().split('.')]

Modified: trunk/Build/source/utils/asymptote/README
===================================================================
--- trunk/Build/source/utils/asymptote/README	2020-03-03 22:33:26 UTC (rev 54033)
+++ trunk/Build/source/utils/asymptote/README	2020-03-03 22:35:09 UTC (rev 54034)
@@ -9,7 +9,7 @@
 Installation instructions, documentation, binaries, and source code are
 available at:
 
-http://asymptote.sourceforge.net
+https://asymptote.sourceforge.io
 
 Bugs/Patches/Feature Requests can be submitted to
 
@@ -17,7 +17,7 @@
 
 Questions and comments should be sent to the Asymptote Forum:
 
-http://sourceforge.net/p/asymptote/discussion/409349
+https://sourceforge.net/p/asymptote/discussion/409349
 
 All source files in the Asymptote project, unless explicitly noted otherwise,
 are released under version 3 (or later) of the GNU Lesser General Public

Modified: trunk/Build/source/utils/asymptote/ReleaseNotes
===================================================================
--- trunk/Build/source/utils/asymptote/ReleaseNotes	2020-03-03 22:33:26 UTC (rev 54033)
+++ trunk/Build/source/utils/asymptote/ReleaseNotes	2020-03-03 22:35:09 UTC (rev 54034)
@@ -1,3 +1,20 @@
+Release Notes for Version 2.63
+
+A race condition in the AsyGL library was fixed. Emissive and
+shininess values can be overridden for vertex colors. Thin Bezier
+curves can be drawn with lighting enabled. Outline mode for 3D surfaces
+was fixed; outline and mesh mode were ported to WebGL. Degenerate
+surface normals were fixed. The octant1, hemisphere, and sphere
+surfaces were replaced by nondegenerate versions that render faster.
+The unitcone, unitfrustum, and DefaultHead3 arrowhead were simplified.
+A robust and more efficient tube routine was implemented;
+the PRC tube primitive was removed. WebGL compression was achieved by
+implementing sphere, disk, cylinder, and tube primitives in the AsyGL library. 
+Patches are now split in both directions only when required.
+If the GNU Readline library is unavailable, the Editline library
+is used to at least support command-line editing, without history features.
+An MSDOS configuration issue was fixed.
+
 Release Notes for Version 2.62
 
 A hyperbola(point F1, point F2, point M) function was added to the

Modified: trunk/Build/source/utils/asymptote/angle.h
===================================================================
--- trunk/Build/source/utils/asymptote/angle.h	2020-03-03 22:33:26 UTC (rev 54033)
+++ trunk/Build/source/utils/asymptote/angle.h	2020-03-03 22:35:09 UTC (rev 54034)
@@ -29,10 +29,14 @@
 }
 
 // Wrapper for atan2 with sensible (lexical) argument order and (0,0) check
-inline double angle(double x, double y)
+inline double angle(double x, double y, bool warn=true)
 {
-  if(x == 0.0 && y == 0.0)
-    reportError("taking angle of (0,0)");
+  if(x == 0.0 && y == 0.0) {
+    if(warn)
+      reportError("taking angle of (0,0)");
+    else
+      return 0;
+  }
   return atan2(y,x);
 }
   

Modified: trunk/Build/source/utils/asymptote/application.cc
===================================================================
--- trunk/Build/source/utils/asymptote/application.cc	2020-03-03 22:33:26 UTC (rev 54033)
+++ trunk/Build/source/utils/asymptote/application.cc	2020-03-03 22:35:09 UTC (rev 54034)
@@ -184,6 +184,8 @@
                               varinit *a, size_t evalIndex)
 {
   formal &target=sig->getFormal(spot);
+  if(target.t->kind == types::ty_error) return false;
+  
   score s=castScore(e, target, source);
 
   if (s == FAIL)

Modified: trunk/Build/source/utils/asymptote/asy-keywords.el
===================================================================
--- trunk/Build/source/utils/asymptote/asy-keywords.el	2020-03-03 22:33:26 UTC (rev 54033)
+++ trunk/Build/source/utils/asymptote/asy-keywords.el	2020-03-03 22:35:09 UTC (rev 54034)
@@ -2,7 +2,7 @@
 ;; This file is automatically generated by asy-list.pl.
 ;; Changes will be overwritten.
 ;;
-(defvar asy-keywords-version "2.62")
+(defvar asy-keywords-version "2.63")
 
 (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 ))
@@ -11,7 +11,7 @@
 Braid FitResult Label Legend Solution TreeNode abscissa arc arrowhead binarytree binarytreeNode block bool bool3 bounds bqe circle conic coord coordsys cputime ellipse evaluatedpoint file filltype frame grid3 guide horner hsv hyperbola int inversion key light line linefit marginT marker mass node object pair parabola patch path path3 pen picture point position positionedvector projection rational real revolution scaleT scientific segment side simplex slice solution splitface string surface tensionSpecifier ticklocate ticksgridT tickvalues transform transformation tree triangle trilinear triple vector vertex void ))
 
 (defvar asy-function-name '(
-AND Arc ArcArrow ArcArrows Arrow Arrows AtA Automatic AvantGarde B03 B13 B23 B33 BBox BWRainbow BWRainbow2 Bar Bars BeginArcArrow BeginArrow BeginBar BeginDotMargin BeginMargin BeginPenMargin Blank Bookman Bottom BottomTop Bounds Break Broken BrokenLog CLZ CTZ Ceil Circle CircleBarIntervalMarker Cos Courier CrossIntervalMarker DOSendl DOSnewl DefaultFormat DefaultLogFormat Degrees Dir DotMargin DotMargins Dotted Draw Drawline Embed EndArcArrow EndArrow EndBar EndDotMargin EndMargin EndPenMargin Fill FillDraw Finite Floor Format Full Gaussian Gaussrand Gaussrandpair Gradient Grayscale Helvetica Hermite HookHead InOutTicks InTicks Jn Label Landscape Left LeftRight LeftTicks Legend Linear Log LogFormat Margin Margins Mark MidArcArrow MidArrow NOT NewCenturySchoolBook NoBox NoMargin NoModifier NoTicks NoTicks3 NoZero NoZeroFormat None OR OmitFormat OmitTick OmitTickInterval OmitTickIntervals OutTicks Ox Oy Palatino PaletteTicks Pen PenMargin PenMargins Pentype Portrait RGB RadialShade RadialShadeDraw Rainbow Range Relative Right RightTicks Rotate Round SQR Scale ScaleX ScaleY ScaleZ Seascape Shift Sin Slant Spline StickIntervalMarker Straight Symbol Tan TeXify Ticks Ticks3 TildeIntervalMarker TimesRoman Top TrueMargin UnFill UpsideDown Wheel X XEquals XOR XY XYEquals XYZero XYgrid XZEquals XZZero XZero XZgrid Y YEquals YXgrid YZ YZEquals YZZero YZero YZgrid Yn Z ZX ZXgrid ZYgrid ZapfChancery ZapfDingbats _begingroup3 _cputime _draw _eval _findroot _image _labelpath _projection _shipout _strokepath _texpath aCos aSin aTan abort abs accel acos acosh acot acsc activatequote add addArrow addMargins addSaveFunction addpenarc addpenline addseg adjust alias align all altitude angabscissa angle angledegrees angpoint animate annotate anticomplementary antipedal apply approximate arc arcarrowsize arccircle arcdir arcfromcenter arcfromfocus arclength arcnodesnumber arcpoint arcsubtended arcsubtendedcenter arctime arctopath array arrow arrow2 arrowbase arrowbasepoints arrowsize ascii asec asin asinh ask assert asy asyc!
 ode asydir asyfigure asyfilecode asyinclude asywrite atan atan2 atanh atbreakpoint atexit attach attract atupdate autoformat autoscale autoscale3 axes axes3 axialshade axis axiscoverage azimuth babel background bangles bar barmarksize barsize basealign baseline bbox beep begin beginclip begingroup beginpoint between bevel bezier bezierP bezierPP bezierPPP bezulate bibliography bibliographystyle binarytree binarytreeNode binomial bins bisector bisectorpoint bispline bitreverse blend blockconnector box bqe brace breakpoint breakpoints brick buildRestoreDefaults buildRestoreThunk buildcycle bulletcolor byte calculateScaling canonical canonicalcartesiansystem cartesiansystem case1 case2 case3 cbrt cd ceil center centerToFocus centroid cevian change2 changecoordsys checkSegment check_fpt_zero checkconditionlength checker checkincreasing checklengths checkposition checkpt checkptincube checktriangle choose circle circlebarframe circlemarkradius circlenodesnumber circumcenter circumcircle clamped clear clip clipdraw close cmyk code colatitude collect collinear color colorless colors colorspace comma compassmark complement complementary concat concurrent cone conic conicnodesnumber conictype conj connect containmentTree contains contour contour3 controlSpecifier convert coordinates coordsys copy copyPairOrTriple cos cosh cot countIntersections cputime crop cropcode cross crossframe crosshatch crossmarksize csc cubicroots curabscissa curlSpecifier curpoint currentarrow currentexitfunction currentmomarrow currentpolarconicroutine curve cut cutafter cutbefore cyclic cylinder deactivatequote debugger deconstruct defaultdir defaultformat defaultpen defined degenerate degrees delete deletepreamble determinant diagonal diamond diffdiv dir dirSpecifier dirtime display distance divisors do_overpaint dot dotframe dotsize downcase draw drawAll drawDoubleLine drawFermion drawGhost drawGluon drawMomArrow drawPRCcylinder drawPRCdisk drawPRCsphere drawPRCtube drawPhoton drawScalar drawVertex drawVertexBox drawVertexBoxO drawVertexBoxX!
  drawVertexO drawVertexOX drawVertexTriangle drawVertexTriangleO drawVertexX drawarrow drawarrow2 drawbeziertriangle drawline drawpixel drawstrokepath drawtick duplicate elle ellipse ellipsenodesnumber embed embed3 embedplayer empty enclose end endclip endgroup endgroup3 endl endpoint endpoints eof eol equation equations erase erasestep erf erfc error errorbar errorbars eval excenter excircle exit exitfunction exp expfactors expi expm1 exradius extend extension extouch fabs factorial fermat fft fhorner figure file filecode fill filldraw filloutside fillrule filltype find findall findroot finite finiteDifferenceJacobian firstcut firstframe fit fit2 fixedscaling floor flush fmdefaults fmod focusToCenter font fontcommand fontsize foot format frac frequency fromCenter fromFocus fspline functionshade gamma gcd generate_random_backtrace generateticks gergonne getc getint getpair getreal getstring gettriple gluon gouraudshade graph graphic graphicscale gray grestore grid grid3 gsave halfbox hatch hdiffdiv hermite hex histogram history hline hprojection hsv hyperbola hyperbolanodesnumber hyperlink hypot identity image implicitsurface incenter incentral incircle increasing incrementposition indexedfigure initdefaults initialized input inradius insert inside insphere integrate interactive interior interp interpolate intersect intersection intersectionpoint intersectionpoints intersections intouch inverse inversion invisible is3D isDuplicate isnan isogonal isogonalconjugate isotomic isotomicconjugate isparabola italic item jobname key kurtosis kurtosisexcess label labelaxis labelmargin labelpath labels labeltick labelx labelx3 labely labely3 labelz labelz3 lastcut latex latitude latticeshade layer layout lcm ldexp leastsquares legend legenditem length lexorder lift light limits line linear linecap lineinversion linejoin linemargin lineskip linetype linewidth link list lm_enorm lm_evaluate_default lm_lmdif lm_lmpar lm_minimize lm_print_default lm_print_quiet lm_qrfac lm_qrsolv locale locate locatefile location log log10 log!
 1p logaxiscoverage longitude lookup make3dgrid makeMappingArray makeNode makecircle makedraw makepen maketriangle map margin markangle markangleradius markanglespace markarc marker markinterval marknodes markrightangle markthin markuniform mass masscenter massformat math max max3 maxAfterTransform maxbezier maxbound maxcoords maxlength maxratio maxtimes mean medial median midpoint min min3 minAfterTransform minbezier minbound minipage minratio mintimes miterlimit mktemp momArrowPath momarrowsize monotonic multifigure nGrad nativeformat natural newl newpage newslide newton newtree nextframe nextnormal nextpage nib nodabscissa node none norm normalout normalvideo nosetpagesize notaknot nowarn numberpage nurb object offset onpath opacity opposite orient orientation origin orthic orthocentercenter outdirectory outformat outline outname outprefix output overloadedMessage overwrite pack pad pairs palette parabola parabolanodesnumber parallel parallelogram partialsum patchwithnormals path path3 pathbetween pathinface pattern pause pdf pedal periodic perp perpendicular perpendicularmark phantom phi1 phi2 phi3 photon piecewisestraight point polar polarconicroutine polargraph polygon popcount postcontrol postscript pow10 ppoint prc prc0 prconly precision precontrol prepend printBytecode print_random_addresses progress project projection projecttospan projecttospan_findcoeffs purge pwhermite quadpatches quadrant quadraticroots quantize quarticroots quotient radialshade radians radicalcenter radicalline radius rand randompath rationalidentity rd readline realmult realquarticroots rectangle rectangular rectify reflect relabscissa relative relativedistance reldir relpoint reltime remainder remark removeDuplicates rename replace report resetdefaultpen restore restoredefaults reverse reversevideo rf rfind rgb rgba rgbint rms rotate rotateO rotation round roundbox roundedpath roundrectangle samecoordsys sameside sample save savedefaults saveline scale scale3 scaleO scaleT scaleless scientific search searchtree sec secondaryX sec!
 ondaryY seconds section sector seek seekeof segment segmentlimits sequence setpens sgn sgnd sharpangle sharpdegrees shift shiftless shipout shipout3 show simeq simplex simplexPhase1 simplexPhase2 simplexStandard simplexTableau simplexWrite simpson sin sinh size size3 skewness skip slant sleep slice slope slopefield solve solveBVP sort sourceline sphere split sqrt square srand standardizecoordsys stdev step stickframe stickmarksize stickmarkspace stop straight straightness string stripdirectory stripextension stripfile stripsuffix strokepath subdivide subitem subpath substr sum surface symmedial symmedian system tab tableau tan tangent tangential tangents tanh tell tensionSpecifier tensorshade tex texcolor texify texpath texpreamble texreset texshipout texsize texstring textpath thick thin tick tickMax tickMax3 tickMin tickMin3 ticklabelshift ticklocate tildeframe tildemarksize tile tiling time times title titlepage topbox toplocation transform transformation transpose trembleFuzz triangle triangleAbc triangleabc triangletoquads trianglewithnormals triangulate tricoef tridiagonal trilinear trim truepoint tube uncycle unfill uniform unique unit unitrand unitsize unityroot unstraighten upcase updatefunction uperiodic upscale uptodate usepackage usersetting usetypescript usleep value variance variancebiased vbox vector vectorfield verbatim view vline vperiodic vprojection warn warning windingnumber write xasyKEY xaxis xaxis3 xaxis3At xaxisAt xequals xlimits xmap xpart xscale xscaleO xtick xtick3 xtrans yaxis yaxis3 yaxis3At yaxisAt yequals ylimits ypart yscale yscaleO ytick ytick3 ytrans zaxis3 zaxis3At zero zlimits zpart ztick ztick3 ztrans ))
+AND Arc ArcArrow ArcArrows Arrow Arrows AtA Automatic AvantGarde B03 B13 B23 B33 BBox BWRainbow BWRainbow2 Bar Bars BeginArcArrow BeginArrow BeginBar BeginDotMargin BeginMargin BeginPenMargin Blank Bookman Bottom BottomTop Bounds Break Broken BrokenLog CLZ CTZ Ceil Circle CircleBarIntervalMarker Cos Courier CrossIntervalMarker DOSendl DOSnewl DefaultFormat DefaultLogFormat Degrees Dir DotMargin DotMargins Dotted Draw Drawline Embed EndArcArrow EndArrow EndBar EndDotMargin EndMargin EndPenMargin Fill FillDraw Finite Floor Format Full Gaussian Gaussrand Gaussrandpair Gradient Grayscale Helvetica Hermite HookHead InOutTicks InTicks Jn Label Landscape Left LeftRight LeftTicks Legend Linear Log LogFormat Margin Margins Mark MidArcArrow MidArrow NOT NewCenturySchoolBook NoBox NoMargin NoModifier NoTicks NoTicks3 NoZero NoZeroFormat None OR OmitFormat OmitTick OmitTickInterval OmitTickIntervals OutTicks Ox Oy Palatino PaletteTicks Pen PenMargin PenMargins Pentype Portrait RGB RadialShade RadialShadeDraw Rainbow Range Relative Right RightTicks Rotate Round SQR Scale ScaleX ScaleY ScaleZ Seascape Shift Sin Slant Spline StickIntervalMarker Straight Symbol Tan TeXify Ticks Ticks3 TildeIntervalMarker TimesRoman Top TrueMargin UnFill UpsideDown Wheel X XEquals XOR XY XYEquals XYZero XYgrid XZEquals XZZero XZero XZgrid Y YEquals YXgrid YZ YZEquals YZZero YZero YZgrid Yn Z ZX ZXgrid ZYgrid ZapfChancery ZapfDingbats _begingroup3 _cputime _draw _eval _findroot _image _labelpath _projection _shipout _strokepath _texpath aCos aSin aTan abort abs accel acos acosh acot acsc activatequote add addArrow addMargins addSaveFunction addpenarc addpenline addseg adjust alias align all altitude angabscissa angle angledegrees angpoint animate annotate anticomplementary antipedal apply approximate arc arcarrowsize arccircle arcdir arcfromcenter arcfromfocus arclength arcnodesnumber arcpoint arcsubtended arcsubtendedcenter arctime arctopath array arrow arrow2 arrowbase arrowbasepoints arrowsize ascii asec asin asinh ask assert asy asyc!
 ode asydir asyfigure asyfilecode asyinclude asywrite atan atan2 atanh atbreakpoint atexit attach attract atupdate autoformat autoscale autoscale3 axes axes3 axialshade axis axiscoverage azimuth babel background bangles bar barmarksize barsize basealign baseline bbox beep begin beginclip begingroup beginpoint between bevel bezier bezierP bezierPP bezierPPP bezulate bibliography bibliographystyle binarytree binarytreeNode binomial bins bisector bisectorpoint bispline bispline0 bitreverse blend blockconnector box bqe brace breakpoint breakpoints brick buildRestoreDefaults buildRestoreThunk buildcycle bulletcolor byte calculateScaling canonical canonicalcartesiansystem cartesiansystem case1 case2 case3 cbrt cd ceil center centerToFocus centroid cevian change2 changecoordsys checkSegment check_fpt_zero checkconditionlength checker checkincreasing checklengths checkposition checkpt checkptincube checktriangle choose circle circlebarframe circlemarkradius circlenodesnumber circumcenter circumcircle clamped clear clip clipdraw close cmyk code colatitude collect collinear color colorless colors colorspace comma compassmark complement complementary concat concurrent cone conic conicnodesnumber conictype conj connect containmentTree contains contour contour3 controlSpecifier convert coordinates coordsys copy copyPairOrTriple cos cosh cot countIntersections cputime crop cropcode cross crossframe crosshatch crossmarksize csc cubicroots curabscissa curlSpecifier curpoint currentarrow currentexitfunction currentmomarrow currentpolarconicroutine curve cut cutafter cutbefore cyclic cylinder deactivatequote debugger deconstruct defaultdir defaultformat defaultpen defined degenerate degrees delete deletepreamble determinant diagonal diamond diffdiv dir dirSpecifier dirtime display distance divisors do_overpaint dot dotframe dotsize downcase draw drawAll drawCylinder drawDisk drawDoubleLine drawFermion drawGhost drawGluon drawMomArrow drawPhoton drawScalar drawSphere drawTube drawVertex drawVertexBox drawVertexBoxO drawVertexBoxX d!
 rawVertexO drawVertexOX drawVertexTriangle drawVertexTriangleO drawVertexX drawarrow drawarrow2 drawbeziertriangle drawline drawpixel drawstrokepath drawtick duplicate elle ellipse ellipsenodesnumber embed embed3 embedplayer empty enclose end endclip endgroup endgroup3 endl endpoint endpoints eof eol equation equations erase erasestep erf erfc error errorbar errorbars eval excenter excircle exit exitfunction exp expfactors expi expm1 exradius extend extension extouch fabs factorial fermat fft fhorner figure file filecode fill filldraw filloutside fillrule filltype find findall findroot finite finiteDifferenceJacobian firstcut firstframe fit fit2 fixedscaling floor flush fmdefaults fmod focusToCenter font fontcommand fontsize foot format frac frequency fromCenter fromFocus fspline functionshade gamma gcd generate_random_backtrace generateticks gergonne getc getint getpair getreal getstring gettriple gluon gouraudshade graph graphic graphicscale gray grestore grid grid3 gsave halfbox hatch hdiffdiv hermite hex histogram history hline hprojection hsv hyperbola hyperbolanodesnumber hyperlink hypot identity image implicitsurface incenter incentral incircle increasing incrementposition indexedfigure initdefaults initialized input inradius insert inside insphere integrate interactive interior interp interpolate intersect intersection intersectionpoint intersectionpoints intersections intouch inverse inversion invisible is3D isDuplicate isnan isogonal isogonalconjugate isotomic isotomicconjugate isparabola italic item jobname key kurtosis kurtosisexcess label labelaxis labelmargin labelpath labels labeltick labelx labelx3 labely labely3 labelz labelz3 lastcut latex latitude latticeshade layer layout lcm ldexp leastsquares legend legenditem length lexorder lift light limits line linear linecap lineinversion linejoin linemargin lineskip linetype linewidth link list lm_enorm lm_evaluate_default lm_lmdif lm_lmpar lm_minimize lm_print_default lm_print_quiet lm_qrfac lm_qrsolv locale locate locatefile location log log10 log1p!
  logaxiscoverage longitude lookup make3dgrid makeMappingArray makeNode makecircle makedraw makepen maketriangle map margin markangle markangleradius markanglespace markarc marker markinterval marknodes markrightangle markthin markuniform mass masscenter massformat math max max3 maxAfterTransform maxbezier maxbound maxcoords maxlength maxratio maxtimes mean medial median midpoint min min3 minAfterTransform minbezier minbound minipage minratio mintimes miterlimit mktemp momArrowPath momarrowsize monotonic multifigure nGrad nativeformat natural newl newpage newslide newton newtree nextframe nextnormal nextpage nib nodabscissa node none norm normalout normalvideo nosetpagesize notaknot nowarn numberpage nurb object offset onpath opacity opposite orient orientation origin orthic orthocentercenter outdirectory outformat outline outname outprefix output overloadedMessage overwrite pack pad pairs palette parabola parabolanodesnumber parallel parallelogram partialsum patchwithnormals path path3 pathbetween pathinface pattern pause pdf pedal periodic perp perpendicular perpendicularmark phantom phi1 phi2 phi3 photon piecewisestraight point polar polarconicroutine polargraph polygon popcount postcontrol postscript pow10 ppoint prc prc0 prconly precision precontrol prepend printBytecode print_random_addresses progress project projection projecttospan projecttospan_findcoeffs purge pwhermite quadpatches quadrant quadraticroots quantize quarticroots quotient radialshade radians radicalcenter radicalline radius rand randompath rationalidentity rd readline realmult realquarticroots rectangle rectangular rectify reflect relabscissa relative relativedistance reldir relpoint reltime remainder remark removeDuplicates rename render replace report resetdefaultpen restore restoredefaults reverse reversevideo rf rfind rgb rgba rgbint rms rotate rotateO rotation round roundbox roundedpath roundrectangle samecoordsys sameside sample save savedefaults saveline scale scale3 scaleO scaleT scaleless scientific search searchtree sec secondary!
 X secondaryY seconds section sector seek seekeof segment segmentlimits sequence setpens sgn sgnd sharpangle sharpdegrees shift shiftless shipout shipout3 show simeq simplex simplexPhase1 simplexPhase2 simplexStandard simplexTableau simplexWrite simpson sin sinh size size3 skewness skip slant sleep slice slope slopefield solve solveBVP sort sourceline sphere split sqrt square srand standardizecoordsys stdev step stickframe stickmarksize stickmarkspace stop straight straightness string stripdirectory stripextension stripfile stripsuffix strokepath subdivide subitem subpath substr sum surface symmedial symmedian system tab tableau tan tangent tangential tangents tanh tell tensionSpecifier tensorshade tex texcolor texify texpath texpreamble texreset texshipout texsize texstring textpath thick thin tick tickMax tickMax3 tickMin tickMin3 ticklabelshift ticklocate tildeframe tildemarksize tile tiling time times title titlepage topbox toplocation transform transformation transpose trembleFuzz triangle triangleAbc triangleabc triangletoquads trianglewithnormals triangulate tricoef tridiagonal trilinear trim truepoint tube uncycle unfill uniform unique unit unitrand unitsize unityroot unstraighten upcase updatefunction uperiodic upscale uptodate usepackage usersetting usetypescript usleep value variance variancebiased vbox vector vectorfield verbatim view vline vperiodic vprojection warn warning windingnumber write xasyKEY xaxis xaxis3 xaxis3At xaxisAt xequals xlimits xmap xpart xscale xscaleO xtick xtick3 xtrans yaxis yaxis3 yaxis3At yaxisAt yequals ylimits ypart yscale yscaleO ytick ytick3 ytrans zaxis3 zaxis3At zero zlimits zpart ztick ztick3 ztrans ))
 
 (defvar asy-variable-name '(
-Accent AliceBlue Align Allow AntiqueWhite Apricot Aqua Aquamarine Aspect Azure BeginPoint Beige Bisque Bittersweet Black BlanchedAlmond Blue BlueGreen BlueViolet Blues Both BrBG Break BrickRed Brown BuGn BuPu BurlyWood BurntOrange CCW CMRmap CW CadetBlue CarnationPink Center Centered Cerulean Chartreuse Chocolate Coeff Coral CornflowerBlue Cornsilk Crimson Crop Cyan Dandelion Dark2 DarkBlue DarkCyan DarkGoldenrod DarkGray DarkGreen DarkKhaki DarkMagenta DarkOliveGreen DarkOrange DarkOrchid DarkRed DarkSalmon DarkSeaGreen DarkSlateBlue DarkSlateGray DarkTurquoise DarkViolet DeepPink DeepSkyBlue DefaultHead DimGray DodgerBlue Dotted Down Draw E ENE EPS ESE E_Euler E_PC E_RK2 E_RK3BS Emerald EndPoint Euler Fill FillDraw FireBrick FloralWhite ForestGreen Fuchsia Gainsboro GhostWhite GnBu Gold Goldenrod Gray Green GreenYellow Greens Greys Honeydew HookHead Horizontal HotPink I IgnoreAspect IndianRed Indigo Infinity Ivory JOIN_IN JOIN_OUT JungleGreen Khaki LM_DWARF LM_MACHEP LM_SQRT_DWARF LM_SQRT_GIANT LM_USERTOL Label Lavender LavenderBlush LawnGreen Left LeftJustified LeftSide LemonChiffon LightBlue LightCoral LightCyan LightGoldenrodYellow LightGreen LightGrey LightPink LightSalmon LightSeaGreen LightSkyBlue LightSlateGray LightSteelBlue LightYellow Lime LimeGreen Linear Linen Log Logarithmic Magenta Mahogany Mark MarkFill MarkPath Maroon Max MediumAquamarine MediumBlue MediumOrchid MediumPurple MediumSeaGreen MediumSlateBlue MediumSpringGreen MediumTurquoise MediumVioletRed Melon MidPoint MidnightBlue Min MintCream MistyRose Moccasin Move MoveQuiet Mulberry N NE NNE NNW NULL_VERTEX NW NavajoWhite Navy NavyBlue NoAlign NoCrop NoFill NoSide OldLace Olive OliveDrab OliveGreen OrRd Orange OrangeRed Oranges Orchid Ox Oy PC PRGn Paired PaleGoldenrod PaleGreen PaleTurquoise PaleVioletRed PapayaWhip Pastel1 Pastel2 Peach PeachPuff Periwinkle Peru PiYG PineGreen Pink Plum PowderBlue ProcessBlue PuBu PuBuGn PuOr PuRd Purple Purples RK2 RK3 RK3BS RK4 RK5 RK5DP RK5F RawSienna RdBu RdGy RdPu RdYlBu RdYlGn Red RedOrang!
 e RedViolet Reds Rhodamine Right RightJustified RightSide RosyBrown RoyalBlue RoyalPurple RubineRed S SE SSE SSW SW SaddleBrown Salmon SandyBrown SeaGreen Seashell Sepia Set1 Set2 Set3 Sienna Silver SimpleHead SkyBlue SlateBlue SlateGray Snow Spectral SpringGreen SteelBlue Suppress SuppressQuiet Tan TeXHead Teal TealBlue Thistle Ticksize Tomato Turquoise UnFill Up VERSION Value Vertical Violet VioletRed W WNW WSW Wheat White WhiteSmoke WildStrawberry XHIGH XLOW XYAlign YAlign YHIGH YLOW Yellow YellowGreen YellowOrange YlGn YlGnBu YlOrBr YlOrRd ZHIGH ZLOW _outpipe aboveequationskip addpenarc addpenline align allowstepping angularsystem animationdelay appendsuffix arcarrowangle arcarrowfactor arrow2sizelimit arrowangle arrowbarb arrowdir arrowfactor arrowhookfactor arrowlength arrowsizelimit arrowtexfactor authorpen autumn axis axiscoverage axislabelfactor background backgroundcolor backgroundpen barfactor barmarksizefactor basealign baselinetemplate bernstein beveljoin bigvertexpen bigvertexsize binary black blue bm bone bottom bp bracedefaultratio braceinnerangle bracemidangle braceouterangle brg brown bullet bwr byfoci byvertices camerafactor chartreuse circlemarkradiusfactor circlenodesnumberfactor circleprecision circlescale cividis cm codefile codepen codeskip colorPen coloredNodes coloredSegments conditionlength conicnodesfactor cool coolwarm copper count cputimeformat crossmarksizefactor currentcoordsys currentlight currentpatterns currentpen currentpicture currentposition currentprojection curvilinearsystem cuttings cyan darkblue darkbrown darkcyan darkgray darkgreen darkgrey darkmagenta darkolive darkred dashdotted dashed datepen dateskip debuggerlines debugging deepblue deepcyan deepgray deepgreen deepgrey deepmagenta deepred deepyellow default defaultControl defaultS defaultbackpen defaultcoordsys defaultexcursion defaultfilename defaultformat defaultmassformat defaultpen defaultseparator differentlengths dot dotfactor dotfilltype dotframe dotted doublelinepen doublelinespacing down duplicateFuzz ellip!
 senodesnumberfactor eps epsgeo epsilon evenodd expansionfactor extendcap fermionpen figureborder figuremattpen file3 firstnode firststep foregroundcolor fuchsia fuzz gapfactor ghostpen gist_earth gist_ncar gist_stern gluonamplitude gluonpen gluonratio gray green grey hatchepsilon havepagenumber heavyblue heavycyan heavygray heavygreen heavygrey heavymagenta heavyred hline hot hsv hwratio hyperbolanodesnumberfactor identity identity4 ignore implicitshipout inch inches includegraphicscommand inf inferno infinity institutionpen intMax intMin invert invisible itempen itemskip itemstep jet labelmargin landscape lastnode left legendhskip legendlinelength legendmargin legendmarkersize legendmaxrelativewidth legendvskip lightblue lightcyan lightgray lightgreen lightgrey lightmagenta lightolive lightred lightyellow linemargin lm_infmsg lm_shortmsg longdashdotted longdashed magenta magma magneticRadius mantissaBits markangleradius markangleradiusfactor markanglespace markanglespacefactor maxrefinements mediumblue mediumcyan mediumgray mediumgreen mediumgrey mediummagenta mediumred mediumyellow middle minDistDefault minblockheight minblockwidth mincirclediameter minipagemargin minipagewidth minvertexangle miterjoin mm momarrowfactor momarrowlength momarrowmargin momarrowoffset momarrowpen monoPen morepoints nCircle nan newbulletcolor ngraph nil nipy_spectral nmesh nobasealign nodeMarginDefault nodesystem nomarker nopoint noprimary nullpath nullpen numarray ocgindex oldbulletcolor olive orange origin overpaint page pageheight pagemargin pagenumberalign pagenumberpen pagenumberposition pagewidth paleblue palecyan palegray palegreen palegrey palemagenta palered paleyellow parabolanodesnumberfactor perpfactor phi photonamplitude photonpen photonratio pi pink plain plain_bounds plain_scaling plasma plus preamblenodes pt purple r3 r4a r4b randMax realDigits realEpsilon realMax realMin red relativesystem reverse right roundcap roundjoin royalblue salmon saveFunctions scalarpen seismic sequencereal settings signedtrailingzero simp!
 lex solid spinner spring springgreen sqrtEpsilon squarecap squarepen startposition stdin stdout stepfactor stepfraction steppagenumberpen stepping stickframe stickmarksizefactor stickmarkspacefactor summer swap tab10 tab20 tab20b tab20c textpen ticksize tildeframe tildemarksizefactor tinv titlealign titlepagepen titlepageposition titlepen titleskip top trailingzero treeLevelStep treeMinNodeWidth treeNodeStep trembleAngle trembleFrequency trembleRandom twilight twilight_shifted undefined unitcircle unitsquare up urlpen urlskip version vertexpen vertexsize viewportmargin viewportsize viridis vline white winter wistia wye yellow ylabelwidth zeroTransform zerotickfuzz zerowinding ))
+Accent AliceBlue Align Allow AntiqueWhite Apricot Aqua Aquamarine Aspect Azure BeginPoint Beige Bisque Bittersweet Black BlanchedAlmond Blue BlueGreen BlueViolet Blues Both BrBG Break BrickRed Brown BuGn BuPu BurlyWood BurntOrange CCW CMRmap CW CadetBlue CarnationPink Center Centered Cerulean Chartreuse Chocolate Coeff Coral CornflowerBlue Cornsilk Crimson Crop Cyan Dandelion Dark2 DarkBlue DarkCyan DarkGoldenrod DarkGray DarkGreen DarkKhaki DarkMagenta DarkOliveGreen DarkOrange DarkOrchid DarkRed DarkSalmon DarkSeaGreen DarkSlateBlue DarkSlateGray DarkTurquoise DarkViolet DeepPink DeepSkyBlue DefaultHead DimGray DodgerBlue Dotted Down Draw E ENE EPS ESE E_Euler E_PC E_RK2 E_RK3BS Emerald EndPoint Euler Fill FillDraw FireBrick FloralWhite ForestGreen Fuchsia Gainsboro GhostWhite GnBu Gold Goldenrod Gray Green GreenYellow Greens Greys Honeydew HookHead Horizontal HotPink I IgnoreAspect IndianRed Indigo Infinity Ivory JOIN_IN JOIN_OUT JungleGreen Khaki LM_DWARF LM_MACHEP LM_SQRT_DWARF LM_SQRT_GIANT LM_USERTOL Label Lavender LavenderBlush LawnGreen Left LeftJustified LeftSide LemonChiffon LightBlue LightCoral LightCyan LightGoldenrodYellow LightGreen LightGrey LightPink LightSalmon LightSeaGreen LightSkyBlue LightSlateGray LightSteelBlue LightYellow Lime LimeGreen Linear Linen Log Logarithmic Magenta Mahogany Mark MarkFill MarkPath Maroon Max MediumAquamarine MediumBlue MediumOrchid MediumPurple MediumSeaGreen MediumSlateBlue MediumSpringGreen MediumTurquoise MediumVioletRed Melon MidPoint MidnightBlue Min MintCream MistyRose Moccasin Move MoveQuiet Mulberry N NE NNE NNW NULL_VERTEX NW NavajoWhite Navy NavyBlue NoAlign NoCrop NoFill NoSide OldLace Olive OliveDrab OliveGreen OrRd Orange OrangeRed Oranges Orchid Ox Oy PC PRGn Paired PaleGoldenrod PaleGreen PaleTurquoise PaleVioletRed PapayaWhip Pastel1 Pastel2 Peach PeachPuff Periwinkle Peru PiYG PineGreen Pink Plum PowderBlue ProcessBlue PuBu PuBuGn PuOr PuRd Purple Purples RK2 RK3 RK3BS RK4 RK5 RK5DP RK5F RawSienna RdBu RdGy RdPu RdYlBu RdYlGn Red RedOrang!
 e RedViolet Reds Rhodamine Right RightJustified RightSide RosyBrown RoyalBlue RoyalPurple RubineRed S SE SSE SSW SW SaddleBrown Salmon SandyBrown SeaGreen Seashell Sepia Set1 Set2 Set3 Sienna Silver SimpleHead SkyBlue SlateBlue SlateGray Snow Spectral SpringGreen SteelBlue Suppress SuppressQuiet Tan TeXHead Teal TealBlue Thistle Ticksize Tomato Turquoise UnFill Up VERSION Value Vertical Violet VioletRed W WNW WSW Wheat White WhiteSmoke WildStrawberry XHIGH XLOW XYAlign YAlign YHIGH YLOW Yellow YellowGreen YellowOrange YlGn YlGnBu YlOrBr YlOrRd ZHIGH ZLOW _outpipe aboveequationskip addpenarc addpenline align allowstepping angularsystem animationdelay appendsuffix arcarrowangle arcarrowfactor arrow2sizelimit arrowangle arrowbarb arrowdir arrowfactor arrowhookfactor arrowlength arrowsizelimit arrowtexfactor authorpen autumn axis axiscoverage axislabelfactor background backgroundcolor backgroundpen barfactor barmarksizefactor basealign baselinetemplate bernstein beveljoin bigvertexpen bigvertexsize binary black blue bm bone bottom bp bracedefaultratio braceinnerangle bracemidangle braceouterangle brg brown bullet bwr byfoci byvertices camerafactor chartreuse circlemarkradiusfactor circlenodesnumberfactor circleprecision circlescale cividis cm codefile codepen codeskip colorPen coloredNodes coloredSegments conditionlength conicnodesfactor cool coolwarm copper count cputimeformat crossmarksizefactor currentcoordsys currentlight currentpatterns currentpen currentpicture currentposition currentprojection curvilinearsystem cuttings cyan darkblue darkbrown darkcyan darkgray darkgreen darkgrey darkmagenta darkolive darkred dashdotted dashed datepen dateskip debuggerlines debugging deepblue deepcyan deepgray deepgreen deepgrey deepmagenta deepred deepyellow default defaultControl defaultS defaultbackpen defaultcoordsys defaultexcursion defaultfilename defaultformat defaultmassformat defaultpen defaultseparator differentlengths dot dotfactor dotfilltype dotframe dotted doublelinepen doublelinespacing down duplicateFuzz ellip!
 senodesnumberfactor eps epsgeo epsilon evenodd expansionfactor extendcap fermionpen figureborder figuremattpen file3 firstnode firststep foregroundcolor fuchsia fuzz gapfactor ghostpen gist_earth gist_ncar gist_stern gluonamplitude gluonpen gluonratio gray green grey hatchepsilon havepagenumber heavyblue heavycyan heavygray heavygreen heavygrey heavymagenta heavyred hline hot hsv hwratio hyperbolanodesnumberfactor identity identity4 ignore implicitshipout inch inches includegraphicscommand inf inferno infinity institutionpen intMax intMin invert invisible itempen itemskip itemstep jet labelmargin landscape lastnode left legendhskip legendlinelength legendmargin legendmarkersize legendmaxrelativewidth legendvskip lightblue lightcyan lightgray lightgreen lightgrey lightmagenta lightolive lightred lightyellow linemargin lm_infmsg lm_shortmsg longdashdotted longdashed magenta magma magneticRadius mantissaBits markangleradius markangleradiusfactor markanglespace markanglespacefactor maxrefinements mediumblue mediumcyan mediumgray mediumgreen mediumgrey mediummagenta mediumred mediumyellow middle minDistDefault minblockheight minblockwidth mincirclediameter minipagemargin minipagewidth minvertexangle miterjoin mm momarrowfactor momarrowlength momarrowmargin momarrowoffset momarrowpen monoPen morepoints nCircle nan newbulletcolor ngraph nil nipy_spectral nmesh nobasealign nodeMarginDefault nodesystem nomarker nopoint noprimary nullpath nullpen numarray ocgindex oldbulletcolor olive orange origin overpaint page pageheight pagemargin pagenumberalign pagenumberpen pagenumberposition pagewidth paleblue palecyan palegray palegreen palegrey palemagenta palered paleyellow parabolanodesnumberfactor perpfactor phi photonamplitude photonpen photonratio pi pink plain plain_bounds plain_scaling plasma plus preamblenodes pt purple r3 r4a r4b randMax realDigits realEpsilon realMax realMin red relativesystem reverse right roundcap roundjoin royalblue salmon saveFunctions scalarpen seismic sequencereal settings signedtrailingzero simp!
 lex solid spinner spring springgreen sqrtEpsilon squarecap squarepen startposition stdin stdout stepfactor stepfraction steppagenumberpen stepping stickframe stickmarksizefactor stickmarkspacefactor summer swap tab10 tab20 tab20b tab20c textpen ticksize tildeframe tildemarksizefactor tinv titlealign titlepagepen titlepageposition titlepen titleskip top trailingzero treeLevelStep treeMinNodeWidth treeNodeStep trembleAngle trembleFrequency trembleRandom tubegranularity twilight twilight_shifted undefined unitcircle unitsquare up urlpen urlskip version vertexpen vertexsize viewportmargin viewportsize viridis vline white winter wistia wye yellow ylabelwidth zeroTransform zerotickfuzz zerowinding ))

Modified: trunk/Build/source/utils/asymptote/asy.list
===================================================================
--- trunk/Build/source/utils/asymptote/asy.list	2020-03-03 22:33:26 UTC (rev 54033)
+++ trunk/Build/source/utils/asymptote/asy.list	2020-03-03 22:35:09 UTC (rev 54034)
@@ -40,8 +40,8 @@
 pen makepen(path p);
 real dotsize(pen p=<default>);
 real[] curlSpecifier(guide g, int t);
+real straightness(triple z0, triple c0, triple c1, triple z1);
 real straightness(path3 p, int t);
-real straightness(triple z0, triple c0, triple c1, triple z1);
 real log10(real x);
 real[] log10(real[] a);
 pen paleblue;
@@ -392,6 +392,7 @@
 object embed3(string, frame, string, string, string, light, projection);
 filltype NoFill;
 real colatitude(triple v, bool warn=<default>);
+void drawDisk(frame f, real[][] t, pen[] p, real opacity, real shininess, real metallic, real fresnel0);
 void label(frame f, string s, string size, transform t, pair position, pair align, pen p);
 void label(picture pic=<default>, Label L, align align=<default>, pen p=<default>, filltype filltype=<default>);
 void label(pair origin, picture pic=<default>, Label L, align align=<default>, pen p=<default>, filltype filltype=<default>);
@@ -697,6 +698,7 @@
 bool piecewisestraight(path3 p);
 void stop(string file, int line, code s=<default>);
 void stop(string file, string text, code s=<default>);
+void drawCylinder(frame f, real[][] t, pen[] p, real opacity, real shininess, real metallic, real fresnel0, bool core=<default>);
 pair reldir(path p, real l);
 pen TimesRoman(string series=<default>, string shape=<default>);
 slice cut(path p, path knife, int n);
@@ -729,7 +731,7 @@
 string[] spinner;
 real[] times(path p, real x);
 real[] times(path p, explicit pair z);
-void drawbeziertriangle(frame f, triple[][] p, triple center, bool straight, pen[] p, real opacity, real shininess, real metallic, real fresnel0, real prcshininess, pen[] colors, int interaction, bool prc=<default>);
+void drawbeziertriangle(frame f, triple[][] p, triple center, bool straight, pen[] p, real opacity, real shininess, real metallic, real fresnel0, pen[] colors, int interaction, bool primitive=<default>);
 void Draw(picture pic=<default>, path g, pen p=<default>);
 filltype Draw;
 void Draw(picture pic=<default>, explicit path[] g, pen p=<default>);
@@ -803,10 +805,10 @@
 real arctime(path p, real l);
 real arctime(path3 p, real dval);
 pen palemagenta;
-void draw(frame f, triple[][] p, triple center, bool straight, pen[] p, real opacity, real shininess, real metallic, real fresnel0, real prcshininess, pen[] colors, int interaction, bool prc=<default>);
+void draw(frame f, triple[][] p, triple center, bool straight, pen[] p, real opacity, real shininess, real metallic, real fresnel0, pen[] colors, int interaction, bool primitive=<default>);
 void draw(frame f, triple[] p, real[] knot, real[] weights=<default>, pen p);
-void draw(frame f, triple[][] p, real[] uknot, real[] vknot, real[][] weights=<default>, pen[] p, real opacity, real shininess, real metallic, real fresnel0, real prcshininess, pen[] colors);
-void draw(frame f, triple[] v, int[][] vi, triple[] n, int[][] ni, pen[] p, real opacity, real shininess, real metallic, real fresnel0, real prcshininess, pen[] c=<default>, int[][] ci=<default>);
+void draw(frame f, triple[][] p, real[] uknot, real[] vknot, real[][] weights=<default>, pen[] p, real opacity, real shininess, real metallic, real fresnel0, pen[] colors);
+void draw(frame f, triple[] v, int[][] vi, triple[] n, int[][] ni, pen[] p, real opacity, real shininess, real metallic, real fresnel0, pen[] c=<default>, int[][] ci=<default>);
 void draw(picture pic=<default>, path[] g, pen fillrule=<default>, pen[] p);
 object draw(picture pic=<default>, Label L, path e(frame dest, frame src=<default>, real xmargin=<default>, real ymargin=<default>, pen p=<default>, filltype filltype=<default>, bool above=<default>), pair position, real xmargin=<default>, real ymargin=<default>, pen p=<default>, filltype filltype=<default>, bool above=<default>);
 void draw(frame f, explicit path[] g, pen p=<default>);
@@ -838,12 +840,8 @@
 triple min3(frame f);
 triple min3(pen p);
 void begin(picture pic=<default>, string name, string id=<default>, bool visible=<default>);
-void drawPRCdisk(frame f, real[][] t, pen[] p, real opacity, real shininess);
-void drawPRCtube(frame f, path3 center, path3 g, pen[] p, real opacity, real shininess);
 int CLZ(int a);
-void drawPRCsphere(frame f, real[][] t, bool half=<default>, pen[] p, real opacity, real shininess, int type);
 arrowhead DefaultHead;
-void drawPRCcylinder(frame f, real[][] t, pen[] p, real opacity, real shininess);
 void beginclip(frame f, path[] g, bool stroke=<default>, pen fillrule=<default>, bool copy=<default>);
 void beginclip(picture pic=<default>, path[] g, bool stroke=<default>, pen fillrule=<default>, bool copy=<default>);
 void begingroup(frame f);
@@ -1090,6 +1088,7 @@
 void eval(string s, bool embedded=<default>);
 bool Arrow(picture, path, pen, marginT(path, pen))(arrowhead arrowhead=<default>, real size=<default>, real angle=<default>, filltype filltype=<default>, position position=<default>);
 bool Arrow(picture, path, pen, marginT(path, pen));
+void drawTube(frame f, triple[] g, real width, pen[] p, real opacity, real shininess, real metallic, real fresnel0, triple min, triple max, bool core=<default>);
 bool Arrows(picture, path, pen, marginT(path, pen))(arrowhead arrowhead=<default>, real size=<default>, real angle=<default>, filltype filltype=<default>);
 bool Arrows(picture, path, pen, marginT(path, pen));
 int tell(file f);
@@ -1839,6 +1838,7 @@
 pair viewportmargin;
 string VERSION;
 real insphere(triple a, triple b, triple c, triple d, triple e);
+void drawSphere(frame f, real[][] t, bool half=<default>, pen[] p, real opacity, real shininess, real metallic, real fresnel0, int type);
 void filldraw(picture pic=<default>, path[] g, pen fillpen=<default>, pen drawpen=<default>);
 void filldraw(frame f, path[] g, pen fillpen=<default>, pen drawpen=<default>);
 real dot(real[] a, real[] b);
@@ -1874,7 +1874,9 @@
 marginT Margins(path, pen);
 pair truepoint(picture pic=<default>, pair dir, bool user=<default>);
 real arclength(path p);
+real arclength(pair z0, pair c0, pair c1, pair z1);
 real arclength(path3 p);
+real arclength(triple z0, triple c0, triple c1, triple z1);
 bool finite(real x);
 bool finite(pair z);
 bool finite(triple v);
@@ -1881,7 +1883,7 @@
 void updatefunction();
 bool implicitshipout;
 void _draw(frame f, path g, pen p);
-void _draw(frame f, path3 g, triple center=<default>, pen p, int interaction=<default>);
+void _draw(frame f, path3 g, triple center=<default>, pen[] p, real opacity, real shininess, real metallic, real fresnel0, int interaction=<default>);
 void _draw(picture pic, path g, pen p, marginT margin(path, pen));
 frame align(frame f, pair align);
 object align(object F, pair align);
@@ -1980,6 +1982,8 @@
 void gouraudshade(picture pic=<default>, path[] g, bool stroke=<default>, pen fillrule=<default>, pen[] p, pair[] z, int[] edges, bool copy=<default>);
 void gouraudshade(picture pic=<default>, path[] g, bool stroke=<default>, pen fillrule=<default>, pen[] p, int[] edges, bool copy=<default>);
 pair[] fft(pair[] a, int sign=<default>);
+pair[][] fft(pair[][] a, int sign=<default>);
+pair[][][] fft(pair[][][] a, int sign=<default>);
 pair SE;
 pen nobasealign;
 sCAD operator init();
@@ -2553,9 +2557,9 @@
 line complementary(explicit line l);
 line[] complementary(explicit segment s);
 arc complementary(arc a);
+bool between(point M, point O, point N);
 point ppoint(arc a, real x);
 path fromFocus(conic co, real angle1, real angle2, int n, bool direction);
-bool between(point M, point O, point N);
 bool sameside(point M, point N, point O);
 bool sameside(point M, point P, line l);
 point[] sameside(point M, line l1, line l2);
@@ -2878,10 +2882,10 @@
 triangle pedal(triangle t, point M);
 line pedal(side side, point M);
 string massformat(string format=<default>, string s, mass M);
-int relativesystem;
 triangle cevian(triangle t, point P);
 point cevian(side side, point P);
 line cevian(vertex V, point P);
+int relativesystem;
 void drawline(picture pic=<default>, triangle t, pen p=<default>);
 void addMargins(picture pic=<default>, real lmargin=<default>, real bmargin=<default>, real rmargin=<default>, real tmargin=<default>, bool rigid=<default>, bool allObject=<default>);
 triangle medial(triangle t);
@@ -3006,10 +3010,10 @@
 real ScaleX(picture pic=<default>, real x);
 real ScaleY(picture pic=<default>, real y);
 void xaxisAt(picture pic=<default>, Label L=<default>, void axis(picture, axisT), real xmin=<default>, real xmax=<default>, pen p=<default>, void ticks(frame, transform, Label, pair, path, path, pen, bool(picture, path, pen, marginT(path, pen)), marginT(path, pen), ticklocate, int[], bool opposite=<default>)=<default>, bool arrow(picture, path, pen, marginT(path, pen))=<default>, marginT margin(path, pen)=<default>, bool above=<default>, bool opposite=<default>);
-tickvalues generateticks(int sign, Label F=<default>, string ticklabel(real)=<default>, int N, int n=<default>, real Step=<default>, real step=<default>, real Size=<default>, real size=<default>, transform T, pair side, path g, real limit, pen p, ticklocate locate, int[] divisor, bool opposite);
 void yaxisAt(picture pic=<default>, Label L=<default>, void axis(picture, axisT), real ymin=<default>, real ymax=<default>, pen p=<default>, void ticks(frame, transform, Label, pair, path, path, pen, bool(picture, path, pen, marginT(path, pen)), marginT(path, pen), ticklocate, int[], bool opposite=<default>)=<default>, bool arrow(picture, path, pen, marginT(path, pen))=<default>, marginT margin(path, pen)=<default>, bool above=<default>, bool opposite=<default>);
 void xaxis(picture pic=<default>, Label L=<default>, void axis(picture, axisT)=<default>, real xmin=<default>, real xmax=<default>, pen p=<default>, void ticks(frame, transform, Label, pair, path, path, pen, bool(picture, path, pen, marginT(path, pen)), marginT(path, pen), ticklocate, int[], bool opposite=<default>)=<default>, bool arrow(picture, path, pen, marginT(path, pen))=<default>, marginT margin(path, pen)=<default>, bool above=<default>);
 void yaxis(picture pic=<default>, Label L=<default>, void axis(picture, axisT)=<default>, real ymin=<default>, real ymax=<default>, pen p=<default>, void ticks(frame, transform, Label, pair, path, path, pen, bool(picture, path, pen, marginT(path, pen)), marginT(path, pen), ticklocate, int[], bool opposite=<default>)=<default>, bool arrow(picture, path, pen, marginT(path, pen))=<default>, marginT margin(path, pen)=<default>, bool above=<default>, bool autorotate=<default>);
+tickvalues generateticks(int sign, Label F=<default>, string ticklabel(real)=<default>, int N, int n=<default>, real Step=<default>, real step=<default>, real Size=<default>, real size=<default>, transform T, pair side, path g, real limit, pen p, ticklocate locate, int[] divisor, bool opposite);
 void checkconditionlength(int x, int y);
 real xtrans(transform t, real x);
 void Top(picture, axisT)(bool extend=<default>);
@@ -3082,7 +3086,9 @@
 void(flatguide3)[][] lift(real f(pair z), guide[][] g, void join(flatguide3)(... void(flatguide3)[])=<default>);
 triple polar(real r, real theta, real phi);
 void polargraph(flatguide3)(real r(real, real), real theta(real), real phi(real), int n=<default>, void join(flatguide3)(... void(flatguide3)[])=<default>);
+bool uperiodic(real[][] a);
 bool uperiodic(triple[][] a);
+bool vperiodic(real[][] a);
 bool vperiodic(triple[][] a);
 void OutTicks(picture, real[][], Label, path3, path3, pen, bool(picture, path3, material, marginT3(path3, pen), light, light), marginT3(path3, pen), ticklocate, int[], bool opposite=<default>, bool primary=<default>)(Label format=<default>, string ticklabel(real)=<default>, bool beginlabel=<default>, bool endlabel=<default>, int N=<default>, int n=<default>, real Step=<default>, real step=<default>, bool begin=<default>, bool end=<default>, tickvalues modify(tickvalues)=<default>, real Size=<default>, real size=<default>, bool extend=<default>, pen pTick=<default>, pen ptick=<default>);
 void OutTicks(picture, real[][], Label, path3, path3, pen, bool(picture, path3, material, marginT3(path3, pen), light, light), marginT3(path3, pen), ticklocate, int[], bool opposite=<default>, bool primary=<default>)(Label format=<default>, string ticklabel(real)=<default>, bool beginlabel=<default>, bool endlabel=<default>, real[] Ticks, real[] ticks=<default>, real Size=<default>, real size=<default>, bool extend=<default>, pen pTick=<default>, pen ptick=<default>);
@@ -3105,6 +3111,7 @@
 surface surface(real[][] f, pair a, pair b, real[] xsplinetype(real[], real[]), real[] ysplinetype(real[], real[])=<default>, bool[][] cond=<default>);
 surface surface(real[][] f, pair a, pair b, bool[][] cond=<default>);
 surface surface(triple f(pair z), pair a, pair b, int nu=<default>, int nv=<default>, bool cond(pair z)=<default>);
+surface surface(triple f(pair z), real[] u, real[] v, real[](real[], real[])[] usplinetype, real[](real[], real[])[] vsplinetype=<default>, bool cond(pair z)=<default>);
 surface surface(triple f(pair z), pair a, pair b, int nu=<default>, int nv=<default>, real[](real[], real[])[] usplinetype, real[](real[], real[])[] vsplinetype=<default>, bool cond(pair z)=<default>);
 surface surface(real f(pair z), pair a, pair b, int nx=<default>, int ny=<default>, bool cond(pair z)=<default>);
 surface surface(real f(pair z), pair a, pair b, int nx=<default>, int ny=<default>, real[] xsplinetype(real[], real[]), real[] ysplinetype(real[], real[])=<default>, bool cond(pair z)=<default>);
@@ -3170,6 +3177,8 @@
 void tick(picture pic=<default>, triple v, triple dir, real size=<default>, pen p=<default>);
 void tick(picture pic=<default>, Label L, real value, triple v, triple dir, string format=<default>, real size=<default>, pen p=<default>);
 surface bispline(real[][] z, real[][] p, real[][] q, real[][] r, real[] x, real[] y, bool[][] cond=<default>);
+real[][][] bispline(real[][] f, real[] x, real[] y, real[] xsplinetype(real[], real[])=<default>, real[] ysplinetype(real[], real[])=<default>, bool[][] cond=<default>);
+real[][][] bispline0(real[][] z, real[][] p, real[][] q, real[][] r, real[] x, real[] y, bool[][] cond=<default>);
 void NoTicks3(picture, real[][], Label, path3, path3, pen, bool(picture, path3, material, marginT3(path3, pen), light, light), marginT3(path3, pen), ticklocate, int[], bool opposite=<default>, bool primary=<default>)();
 void NoTicks3(picture, real[][], Label, path3, path3, pen, bool(picture, path3, material, marginT3(path3, pen), light, light), marginT3(path3, pen), ticklocate, int[], bool opposite=<default>, bool primary=<default>);
 bool Crop;
@@ -3208,6 +3217,7 @@
 triple Z(picture pic);
 grid3(picture pic)[] XYXgrid(position pos=<default>);
 grid3(picture pic)[] XYXgrid;
+position middle;
 grid3(picture pic)[] XY_XZgrid(position posa=<default>, position posb=<default>);
 grid3(picture pic)[] XY_XZgrid;
 grid3(picture pic)[] ZX_ZYgrid(position posa=<default>, position posb=<default>);
@@ -3216,7 +3226,6 @@
 grid3 XYgrid(picture pic);
 grid3 ZYgrid(picture pic)(position pos=<default>);
 grid3 ZYgrid(picture pic);
-position middle;
 void grid3(picture pic=<default>, grid3(picture pic)[][] gridroutine=<default>, int N=<default>, int n=<default>, real Step=<default>, real step=<default>, bool begin=<default>, bool end=<default>, pen pGrid=<default>, pen pgrid=<default>, bool above=<default>);
 void grid3(picture pic=<default>, grid3(picture pic)[][] gridroutine, int N=<default>, int n=<default>, real Step=<default>, real step=<default>, bool begin=<default>, bool end=<default>, pen[] pGrid, pen[] pgrid, bool above=<default>);
 ticksgridT OutTicks()(Label F=<default>, string ticklabel(real)=<default>, bool beginlabel=<default>, bool endlabel=<default>, int N=<default>, int n=<default>, real Step=<default>, real step=<default>, bool begin=<default>, bool end=<default>, real Size=<default>, real size=<default>, pen pTick=<default>, pen ptick=<default>, grid3(picture pic)[][] gridroutine, pen pGrid=<default>, pen pgrid=<default>);
@@ -3546,26 +3555,26 @@
 pen backgroundcolor;
 void normalvideo();
 void title(string s, pair position=<default>, pair align=<default>, pen p=<default>, bool newslide=<default>);
+pen authorpen;
 pen titlepen;
 real titleskip;
 pair dateskip;
 pair titlealign;
 pen titlepagepen;
-pen authorpen;
 void titlepage(string title, string author, string institution=<default>, string date=<default>, string url=<default>, bool newslide=<default>);
 pair titlepageposition;
 pen codepen;
 void erasestep(int erasenode);
+string cropcode(string s);
 bool checkposition();
 void setpens(pen red=<default>, pen blue=<default>, pen steppen=<default>);
-string cropcode(string s);
 void code(bool center=<default>, string s, pen p=<default>, real indent=<default>, real skip=<default>, filltype filltype=<default>);
 transform tinv;
 pair urlskip;
 void numberpage(pen p=<default>);
-pen urlpen;
 bool allowstepping;
 pair currentposition;
+pen urlpen;
 int[] firstnode;
 bool firststep;
 string asywrite(string s, string preamble=<default>);
@@ -3620,8 +3629,8 @@
 triple projecttospan(triple toproject, triple v1, triple v2, real mincoeff=<default>);
 real[] projecttospan_findcoeffs(triple toproject, triple v1, triple v2, bool warn=<default>);
 triple nGrad(triple)(real f(triple));
+triple normalout(int face);
 patch[] quadpatches(path3 edgecycle, positionedvector[] corners, real f(triple), triple grad(triple), triple a, triple b, bool usetriangles);
-triple normalout(int face);
 int[] makecircle(edge[] edges);
 real B13(real t);
 bool check_fpt_zero(triple testpoint, real f(triple), triple grad(triple));
@@ -3670,9 +3679,9 @@
 int[][] frequency(real[] x, real[] y, real[] xbins, real[] ybins);
 int[][] frequency(real[] x, real[] y, pair a, pair b, int nx, int ny=<default>);
 int[][] frequency(pair[] z, pair a, pair b, int nx, int ny=<default>);
-real mean(real[] A);
 void histogram(picture pic=<default>, real[] bins, real[] count, real low=<default>, pen fillpen=<default>, pen drawpen=<default>, bool bars=<default>, Label legend=<default>, real markersize=<default>);
 void histogram(picture pic=<default>, real[] data, real a, real b, int n, bool normalize=<default>, real low=<default>, pen fillpen=<default>, pen drawpen=<default>, bool bars=<default>, Label legend=<default>, real markersize=<default>);
+real mean(real[] A);
 int bins(real[] data, int max=<default>);
 path topbox(pair a, pair b);
 path halfbox(pair a, pair b);
@@ -3682,9 +3691,9 @@
 real variancebiased(real[] A);
 real Gaussian(real x, real sigma);
 real Gaussian(real x);
-linefit operator init();
 pair Gaussrandpair();
 real Gaussrand();
+linefit operator init();
 real skewness(real[] A);
 linefit leastsquares(real[] x, real[] y);
 real kurtosis(real[] A);
@@ -3708,8 +3717,8 @@
 Component wye;
 pair max(pair[] z);
 real hwratio;
+pen WildStrawberry;
 pen Orchid;
-pen WildStrawberry;
 pen Magenta;
 pen BrickRed;
 pen CadetBlue;
@@ -3735,8 +3744,8 @@
 pen BurntOrange;
 pen Tan;
 pen Aquamarine;
+pen Lavender;
 pen Brown;
-pen Lavender;
 pen RubineRed;
 pen TealBlue;
 pen White;
@@ -3752,9 +3761,9 @@
 pen NavyBlue;
 pen Rhodamine;
 pen YellowOrange;
-pen ProcessBlue;
 pen Maroon;
 pen YellowGreen;
+pen ProcessBlue;
 pen LimeGreen;
 pen Green;
 pen GreenYellow;
@@ -3769,8 +3778,8 @@
 pen Periwinkle;
 pen Thistle;
 pen Yellow;
+pen DarkOrchid;
 pen JungleGreen;
-pen DarkOrchid;
 pen CornflowerBlue;
 pen RoyalBlue;
 pen Melon;
@@ -3788,8 +3797,10 @@
 real trembleFrequency;
 tremble operator init();
 real magneticRadius;
+void render(path3 s, real r, void f(path3, real));
 real[] sample(path3 g, real r, real relstep=<default>);
 path3 roundedpath(path3 A, real r);
+real tubegranularity;
 int coloredNodes;
 int coloredSegments;
 surface surface(rmf[] R, real[] t, coloredpath cp, transform T(real), bool cyclic);
@@ -3801,10 +3812,10 @@
 string VERSION;
 pen Orchid;
 pen Indigo;
+pen Seashell;
 pen Beige;
 pen SlateBlue;
 pen SlateGray;
-pen Seashell;
 pen Magenta;
 pen GhostWhite;
 pen CadetBlue;
@@ -3814,11 +3825,11 @@
 pen Olive;
 pen OliveDrab;
 pen Salmon;
+pen LavenderBlush;
+pen Wheat;
 pen Chocolate;
-pen LavenderBlush;
 pen Cyan;
 pen Gainsboro;
-pen Wheat;
 pen Ivory;
 pen PeachPuff;
 pen PapayaWhip;
@@ -3827,8 +3838,8 @@
 pen MintCream;
 pen DarkTurquoise;
 pen Lime;
+pen SteelBlue;
 pen Gray;
-pen SteelBlue;
 pen MediumBlue;
 pen MediumOrchid;
 pen MediumPurple;
@@ -3846,15 +3857,16 @@
 pen ForestGreen;
 pen Chartreuse;
 pen NavajoWhite;
+pen LemonChiffon;
 pen Tan;
-pen LemonChiffon;
 pen DarkMagenta;
 pen AntiqueWhite;
+pen Aquamarine;
 pen PaleTurquoise;
+pen Aqua;
 pen IndianRed;
-pen Aquamarine;
 pen Crimson;
-pen Aqua;
+pen Lavender;
 pen Azure;
 pen LawnGreen;
 pen Brown;
@@ -3861,7 +3873,6 @@
 pen BurlyWood;
 pen Moccasin;
 pen DarkBlue;
-pen Lavender;
 pen Peru;
 pen White;
 pen Purple;
@@ -3870,11 +3881,11 @@
 pen Orange;
 pen OrangeRed;
 pen Fuchsia;
+pen Honeydew;
 pen Bisque;
-pen Honeydew;
 pen RosyBrown;
+pen Sienna;
 pen Black;
-pen Sienna;
 pen Khaki;
 pen FireBrick;
 pen Snow;
@@ -3882,10 +3893,10 @@
 pen YellowGreen;
 pen LimeGreen;
 pen OldLace;
+pen DarkOliveGreen;
+pen DarkOrange;
 pen Green;
 pen GreenYellow;
-pen DarkOliveGreen;
-pen DarkOrange;
 pen DarkCyan;
 pen FloralWhite;
 pen DarkRed;
@@ -3899,10 +3910,10 @@
 pen SeaGreen;
 pen DarkViolet;
 pen Teal;
+pen Violet;
 pen AliceBlue;
-pen Violet;
+pen SandyBrown;
 pen HotPink;
-pen SandyBrown;
 pen DodgerBlue;
 pen SaddleBrown;
 pen Tomato;
@@ -3926,12 +3937,12 @@
 pen LightSkyBlue;
 pen PaleVioletRed;
 pen DarkOrchid;
+pen Cornsilk;
+pen CornflowerBlue;
 pen LightSlateGray;
 pen LightSteelBlue;
-pen CornflowerBlue;
+pen rgbint(int r, int g, int b);
 pen LightYellow;
-pen rgbint(int r, int g, int b);
-pen Cornsilk;
 pen Coral;
 pen MistyRose;
 pen DarkSalmon;

Modified: trunk/Build/source/utils/asymptote/asymptote.spec
===================================================================
--- trunk/Build/source/utils/asymptote/asymptote.spec	2020-03-03 22:33:26 UTC (rev 54033)
+++ trunk/Build/source/utils/asymptote/asymptote.spec	2020-03-03 22:35:09 UTC (rev 54034)
@@ -3,7 +3,7 @@
 %global __python %{__python3}
 
 Name:           asymptote
-Version:        2.62
+Version:        2.63
 Release:        1%{?dist}
 Summary:        Descriptive vector graphics language
 

Modified: trunk/Build/source/utils/asymptote/base/graph3.asy
===================================================================
--- trunk/Build/source/utils/asymptote/base/graph3.asy	2020-03-03 22:33:26 UTC (rev 54033)
+++ trunk/Build/source/utils/asymptote/base/graph3.asy	2020-03-03 22:35:09 UTC (rev 54034)
@@ -1547,6 +1547,33 @@
                   segment.length);
 }
 
+bool uperiodic(real[][] a) {
+  int n=a.length;
+  if(n == 0) return false;
+  int m=a[0].length;
+  real[] a0=a[0];
+  real[] a1=a[n-1];
+  for(int j=0; j < m; ++j) {
+    real norm=0;
+    for(int i=0; i < n; ++i)
+      norm=max(norm,abs(a[i][j]));
+    real epsilon=sqrtEpsilon*norm;
+    if(abs(a0[j]-a1[j]) > epsilon) return false;
+  }
+  return true;
+}
+bool vperiodic(real[][] a) {
+  int n=a.length;
+  if(n == 0) return false;
+  int m=a[0].length-1;
+  for(int i=0; i < n; ++i) {
+    real[] ai=a[i];
+    real epsilon=sqrtEpsilon*norm(ai);
+    if(abs(ai[0]-ai[m]) > epsilon) return false;
+  }
+  return true;
+}
+
 bool uperiodic(triple[][] a) {
   int n=a.length;
   if(n == 0) return false;
@@ -1614,7 +1641,7 @@
     if(uperiodic(f)) s.ucyclic(true);
     if(vperiodic(f)) s.vcyclic(true);
   }
-  
+
   return s;
 }
 
@@ -1694,10 +1721,114 @@
       }
     }
   }
-  
+
   return s;
 }
 
+private real[][][] bispline0(real[][] z, real[][] p, real[][] q, real[][] r,
+                             real[] x, real[] y, bool[][] cond={})
+{ // z[i][j] is the value at (x[i],y[j])
+  // p and q are the first derivatives with respect to x and y, respectively
+  // r is the second derivative ddu/dxdy
+  int n=x.length-1;
+  int m=y.length-1;
+
+  bool all=cond.length == 0;
+
+  int count;
+  if(all)
+    count=n*m;
+  else {
+    count=0;
+    for(int i=0; i < n; ++i) {
+      bool[] condi=cond[i];
+      bool[] condp=cond[i+1];
+      for(int j=0; j < m; ++j)
+        if(all || (condi[j] && condi[j+1] && condp[j] && condp[j+1]))
+          ++count;
+    }
+  }
+
+  real[][][] s=new real[count][][];
+  int k=0;
+  for(int i=0; i < n; ++i) {
+    int ip=i+1;
+    real xi=x[i];
+    real xp=x[ip];
+    real hx=(xp-xi)/3;
+    real[] zi=z[i];
+    real[] zp=z[ip];
+    real[] ri=r[i];
+    real[] rp=r[ip];
+    real[] pi=p[i];
+    real[] pp=p[ip];
+    real[] qi=q[i];
+    real[] qp=q[ip];
+    bool[] condi=all ? null : cond[i];
+    bool[] condp=all ? null : cond[i+1];
+    for(int j=0; j < m; ++j) {
+      if(all || (condi[j] && condi[j+1] && condp[j] && condp[j+1])) {
+        real yj=y[j];
+        int jp=j+1;
+        real yp=y[jp];
+        real hy=(yp-yj)/3;
+        real hxy=hx*hy;
+        real zij=zi[j];
+        real zip=zi[jp];
+        real zpj=zp[j];
+        real zpp=zp[jp];
+        real pij=hx*pi[j];
+        real ppj=hx*pp[j];
+        real qip=hy*qi[jp];
+        real qpp=hy*qp[jp];
+        real zippip=zip+hx*pi[jp];
+        real zppmppp=zpp-hx*pp[jp];
+        real zijqij=zij+hy*qi[j];
+        real zpjqpj=zpj+hy*qp[j];
+
+        s[k]=new real[][] {{zij,zijqij,zip-qip,zip},
+                           {zij+pij,zijqij+pij+hxy*ri[j],
+                            zippip-qip-hxy*ri[jp],zippip},
+                           {zpj-ppj,zpjqpj-ppj-hxy*rp[j],
+                            zppmppp-qpp+hxy*rp[jp],zppmppp},
+                           {zpj,zpjqpj,zpp-qpp,zpp}};
+        ++k;
+      }
+    }
+  }
+
+  return s;
+}
+
+// return the surface values described by a real matrix f, interpolated with
+// xsplinetype and ysplinetype.
+real[][][] bispline(real[][] f, real[] x, real[] y,
+                    splinetype xsplinetype=null,
+                    splinetype ysplinetype=xsplinetype, bool[][] cond={})
+{
+  real epsilon=sqrtEpsilon*norm(y);
+  if(xsplinetype == null)
+    xsplinetype=(abs(x[0]-x[x.length-1]) <= epsilon) ? periodic : notaknot;
+  if(ysplinetype == null)
+    ysplinetype=(abs(y[0]-y[y.length-1]) <= epsilon) ? periodic : notaknot;
+  int n=x.length; int m=y.length;
+  real[][] ft=transpose(f);
+  real[][] tp=new real[m][];
+  for(int j=0; j < m; ++j)
+    tp[j]=xsplinetype(x,ft[j]);
+  real[][] q=new real[n][];
+  for(int i=0; i < n; ++i)
+    q[i]=ysplinetype(y,f[i]);
+  real[][] qt=transpose(q);
+  real[] d1=xsplinetype(x,qt[0]);
+  real[] d2=xsplinetype(x,qt[m-1]);
+  real[][] r=new real[n][];
+  real[][] p=transpose(tp);
+  for(int i=0; i < n; ++i)
+    r[i]=clamped(d1[i],d2[i])(y,p[i]);
+  return bispline0(f,p,q,r,x,y,cond);
+}
+
 // return the surface described by a real matrix f, interpolated with
 // xsplinetype and ysplinetype.
 surface surface(real[][] f, real[] x, real[] y,
@@ -1802,6 +1933,91 @@
   return surface(v,active);
 }
   
+// return the surface described by a parametric function f evaluated at u and v
+// and interpolated with usplinetype and vsplinetype.
+surface surface(triple f(pair z), real[] u, real[] v,
+                splinetype[] usplinetype, splinetype[] vsplinetype=Spline,
+                bool cond(pair z)=null)
+{
+  int nu=u.length-1;
+  int nv=v.length-1;
+  real[] ipt=sequence(u.length);
+  real[] jpt=sequence(v.length);
+  real[][] fx=new real[u.length][v.length];
+  real[][] fy=new real[u.length][v.length];
+  real[][] fz=new real[u.length][v.length];
+
+  bool[][] active;
+  bool all=cond == null;
+  if(!all) active=new bool[u.length][v.length];
+
+  for(int i=0; i <= nu; ++i) {
+    real ui=u[i];
+    real[] fxi=fx[i];
+    real[] fyi=fy[i];
+    real[] fzi=fz[i];
+    bool[] activei=all ? null : active[i];
+    for(int j=0; j <= nv; ++j) {
+      pair z=(ui,v[j]);
+      if(!all) activei[j]=cond(z);
+      triple f=f(z);
+      fxi[j]=f.x;
+      fyi[j]=f.y;
+      fzi[j]=f.z;
+    }
+  }
+
+  if(usplinetype.length == 0) {
+    usplinetype=new splinetype[] {uperiodic(fx) ? periodic : notaknot,
+                                  uperiodic(fy) ? periodic : notaknot,
+                                  uperiodic(fz) ? periodic : notaknot};
+  } else if(usplinetype.length != 3) abort("usplinetype must have length 3");
+
+  if(vsplinetype.length == 0) {
+    vsplinetype=new splinetype[] {vperiodic(fx) ? periodic : notaknot,
+                                  vperiodic(fy) ? periodic : notaknot,
+                                  vperiodic(fz) ? periodic : notaknot};
+  } else if(vsplinetype.length != 3) abort("vsplinetype must have length 3");
+
+  real[][][] sx=bispline(fx,ipt,jpt,usplinetype[0],vsplinetype[0],active);
+  real[][][] sy=bispline(fy,ipt,jpt,usplinetype[1],vsplinetype[1],active);
+  real[][][] sz=bispline(fz,ipt,jpt,usplinetype[2],vsplinetype[2],active);
+
+  surface s=surface(sx.length);
+  s.index=new int[nu][nv];
+  int k=-1;
+  for(int i=0; i < nu; ++i) {
+    int[] indexi=s.index[i];
+    for(int j=0; j < nv; ++j)
+      indexi[j]=++k;
+  }
+
+  for(int k=0; k < sx.length; ++k) {
+    triple[][] Q=new triple[4][];
+    real[][] Px=sx[k];
+    real[][] Py=sy[k];
+    real[][] Pz=sz[k];
+    for(int i=0; i < 4 ; ++i) {
+      real[] Pxi=Px[i];
+      real[] Pyi=Py[i];
+      real[] Pzi=Pz[i];
+      Q[i]=new triple[] {(Pxi[0],Pyi[0],Pzi[0]),
+                         (Pxi[1],Pyi[1],Pzi[1]),
+                         (Pxi[2],Pyi[2],Pzi[2]),
+                         (Pxi[3],Pyi[3],Pzi[3])};
+    }
+    s.s[k]=patch(Q);
+  }
+
+  if(usplinetype[0] == periodic && usplinetype[1] == periodic &&
+     usplinetype[1] == periodic) s.ucyclic(true);
+
+  if(vsplinetype[0] == periodic && vsplinetype[1] == periodic &&
+     vsplinetype[1] == periodic) s.vcyclic(true);
+
+  return s;
+}
+
 // return the surface described by a parametric function f over box(a,b),
 // interpolated with usplinetype and vsplinetype.
 surface surface(triple f(pair z), pair a, pair b, int nu=nmesh, int nv=nu,

Modified: trunk/Build/source/utils/asymptote/base/palette.asy
===================================================================
--- trunk/Build/source/utils/asymptote/base/palette.asy	2020-03-03 22:33:26 UTC (rev 54033)
+++ trunk/Build/source/utils/asymptote/base/palette.asy	2020-03-03 22:35:09 UTC (rev 54034)
@@ -358,10 +358,10 @@
   if(settings.gray) return Grayscale(NColors);
   
   int nintervals=6;
+  if(NColors <= nintervals) NColors=nintervals+1;
   int n=-quotient(NColors,-nintervals);
                 
   pen[] Palette;
-  if(n == 0) return Palette;
   
   Palette=new pen[n*nintervals];
   real ninv=1.0/n;
@@ -386,10 +386,10 @@
   
   int offset=1;
   int nintervals=5;
+  if(NColors <= nintervals) NColors=nintervals+1;
   int n=-quotient(NColors-1,-nintervals);
                 
   pen[] Palette;
-  if(n == 0) return Palette;
   
   Palette=new pen[n*nintervals+offset];
   real ninv=1.0/n;
@@ -418,12 +418,13 @@
   
   if(two) nintervals += 6;
   
+  int Nintervals=nintervals*divisor;
+  if(NColors <= Nintervals) NColors=Nintervals+1;
   int num=NColors-offset;
-  int n=-quotient(num,-nintervals*divisor)*divisor;
+  int n=-quotient(num,-Nintervals)*divisor;
   NColors=n*nintervals+offset;
                 
   pen[] Palette;
-  if(n == 0) return Palette;
   
   Palette=new pen[NColors];
   real ninv=1.0/n;

Modified: trunk/Build/source/utils/asymptote/base/shaders/fragment.glsl
===================================================================
--- trunk/Build/source/utils/asymptote/base/shaders/fragment.glsl	2020-03-03 22:33:26 UTC (rev 54033)
+++ trunk/Build/source/utils/asymptote/base/shaders/fragment.glsl	2020-03-03 22:35:09 UTC (rev 54034)
@@ -135,29 +135,25 @@
   Material m;
 #ifdef TRANSPARENT
   m=Materials[abs(materialIndex)-1];
-  if(materialIndex >= 0) {
+  emissive=m.emissive;
+  if(materialIndex >= 0)
     diffuse=m.diffuse;
-    emissive=m.emissive;
-  } else {
+  else {
     diffuse=Color;
-#if Nlights > 0
-    emissive=vec4(0.0);
-#else    
-    emissive=Color;
+#if Nlights == 0
+    emissive += Color;
 #endif
   }
 #else
   m=Materials[int(materialIndex)];
+  emissive=m.emissive;
 #ifdef COLOR
   diffuse=Color;
-#if Nlights > 0
-    emissive=vec4(0.0);
-#else    
-    emissive=Color;
+#if Nlights == 0
+   emissive += Color;
 #endif
 #else  
   diffuse=m.diffuse; 
-  emissive=m.emissive;
 #endif
 #endif
   

Modified: trunk/Build/source/utils/asymptote/base/shaders/vertex.glsl
===================================================================
--- trunk/Build/source/utils/asymptote/base/shaders/vertex.glsl	2020-03-03 22:33:26 UTC (rev 54033)
+++ trunk/Build/source/utils/asymptote/base/shaders/vertex.glsl	2020-03-03 22:35:09 UTC (rev 54034)
@@ -34,7 +34,7 @@
 #ifndef ORTHOGRAPHIC
   ViewPosition=(viewMat*v).xyz;
 #endif
-  Normal=normal*normMat;
+  Normal=normalize(normal*normMat);
 #endif
 
 #ifdef COLOR

Modified: trunk/Build/source/utils/asymptote/base/solids.asy
===================================================================
--- trunk/Build/source/utils/asymptote/base/solids.asy	2020-03-03 22:33:26 UTC (rev 54033)
+++ trunk/Build/source/utils/asymptote/base/solids.asy	2020-03-03 22:35:09 UTC (rev 54034)
@@ -374,6 +374,7 @@
 
 // Return a right circular cylinder of height h in the direction of axis
 // based on a circle centered at c with radius r.
+// Note: unitcylinder provides a smoother and more efficient representation.
 revolution cylinder(triple c=O, real r, real h, triple axis=Z)
 {
   triple C=c+r*perp(axis);
@@ -392,7 +393,7 @@
 
 // Return an approximate sphere of radius r centered at c obtained by rotating
 // an (n+1)-point approximation to a half circle about the Z axis.
-// Note: unitsphere provides a smoother and more efficient surface.
+// Note: unitsphere provides a smoother and more efficient representation.
 revolution sphere(triple c=O, real r, int n=nslice)
 {
   return revolution(c,Arc(c,r,180-sqrtEpsilon,0,sqrtEpsilon,0,Y,n),Z);

Modified: trunk/Build/source/utils/asymptote/base/three.asy
===================================================================
--- trunk/Build/source/utils/asymptote/base/three.asy	2020-03-03 22:33:26 UTC (rev 54033)
+++ trunk/Build/source/utils/asymptote/base/three.asy	2020-03-03 22:35:09 UTC (rev 54034)
@@ -37,8 +37,7 @@
 
   // General parameters:
   real margin;          // shrink amount for rendered openGL viewport, in bp.
-  real tubegranularity; // granularity for rendering tubes 
-  bool labelfill;       // fill subdivision cracks in unlighted labels
+  bool labelfill;       // fill PRC subdivision cracks in unlighted labels
 
   bool partnames;       // assign part name indices to compound objects
   bool defaultnames;    // assign default names to unnamed objects
@@ -52,7 +51,6 @@
                      bool3 merge=defaultrender.merge,
                      int sphere=defaultrender.sphere,
                      real margin=defaultrender.margin,
-                     real tubegranularity=defaultrender.tubegranularity,
                      bool labelfill=defaultrender.labelfill,
                      bool partnames=defaultrender.partnames,
                      bool defaultnames=defaultrender.defaultnames)
@@ -64,7 +62,6 @@
     this.merge=merge;
     this.sphere=sphere;
     this.margin=margin;
-    this.tubegranularity=tubegranularity;
     this.labelfill=labelfill;
     this.partnames=partnames;
     this.defaultnames=defaultnames;
@@ -80,7 +77,6 @@
 defaultrender.tessellate=false;
 defaultrender.merge=false;
 defaultrender.margin=0.02;
-defaultrender.tubegranularity=0.001;
 defaultrender.sphere=NURBSsphere;
 defaultrender.labelfill=true;
 defaultrender.partnames=false;
@@ -217,9 +213,10 @@
 triple perp(triple v)
 {
   triple u=cross(v,Y);
-  if(abs(u) > sqrtEpsilon) return unit(u);
+  real norm=sqrtEpsilon*abs(v);
+  if(abs(u) > norm) return unit(u);
   u=cross(v,Z);
-  return (abs(u) > sqrtEpsilon) ? unit(u) : X;
+  return (abs(u) > norm) ? unit(u) : X;
 }
 
 // Return the transformation corresponding to moving the camera from the target
@@ -1140,6 +1137,18 @@
   return sequence(new path3(int i) {return path3(g[i],plane);},g.length);
 }
 
+path3 interp(path3 a, path3 b, real t)
+{
+  int n=size(a);
+  return path3(sequence(new triple(int i) {
+        return interp(precontrol(a,i),precontrol(b,i),t);},n),
+    sequence(new triple(int i) {return interp(point(a,i),point(b,i),t);},n),
+    sequence(new triple(int i) {return interp(postcontrol(a,i),
+                                              postcontrol(b,i),t);},n),
+    sequence(new bool(int i) {return straight(a,i) && straight(b,i);},n),
+    cyclic(a) && cyclic(b));
+}
+
 path3 invert(path p, triple normal, triple point,
              projection P=currentprojection)
 {
@@ -2158,7 +2167,8 @@
 
 void draw(picture pic=currentpicture, Label L="", path3 g,
           align align=NoAlign, material p=currentpen, margin3 margin=NoMargin3,
-          light light=nolight, string name="", render render=defaultrender)
+          light light=nolight, string name="",
+          render render=defaultrender)
 {
   pen q=(pen) p;
   pic.add(new void(frame f, transform3 t, picture pic, projection P) {
@@ -2188,80 +2198,62 @@
               projection P=currentprojection) {
   pen q=(pen) p;
   if(is3D()) {
-    p=material(p);
     real width=linewidth(q);
     void drawthick(path3 g) {
-      if(settings.thick) {
-        if(width > 0) {
-          bool prc=prc();
-          void cylinder(transform3) {};
-          void sphere(transform3, bool half) {};
-          void disk(transform3) {};
-          void pipe(path3, path3);
-          if(prc) {
-            cylinder=new void(transform3 t) {drawPRCcylinder(f,t,p,light);};
-            sphere=new void(transform3 t, bool half)
-              {drawPRCsphere(f,t,half,p,light,render);};
-            disk=new void(transform3 t) {draw(f,t*unitdisk,p,light,render);};
-            pipe=new void(path3 center, path3 g)
-              {drawPRCtube(f,center,g,p,light);};
+      if(settings.thick && width > 0) {
+        bool prc=prc();
+        bool webgl=settings.outformat == "html";
+        real linecap=linecap(q);
+        real r=0.5*width;
+        bool open=!cyclic(g);
+        int L=length(g);
+        triple g0=point(g,0);
+        triple gL=point(g,L);
+        if(open && L > 0) {
+          if(linecap == 2) {
+            g0 -= r*dir(g,0);
+            gL += r*dir(g,L);
+            g=g0..g..gL;
+            L += 2;
           }
-          real linecap=linecap(q);
-          real r=0.5*width;
-          bool open=!cyclic(g);
-          int L=length(g);
-          triple g0=point(g,0);
-          triple gL=point(g,L);
-          if(open && L > 0) {
-            if(linecap == 2) {
-              g0 -= r*dir(g,0);
-              gL += r*dir(g,L);
-              g=g0..g..gL;
-              L += 2;
-            }
-          }
-          tube T=tube(g,width,render,cylinder,sphere,pipe);
-          path3 c=T.center;
-          if(L >= 0) {
-            if(open) {
-              int Lc=length(c);
-              triple c0=point(c,0);
-              triple cL=point(c,Lc);
-              triple dir0=dir(g,0);
-              triple dirL=dir(g,L);
-              triple dirc0=dir(c,0);
-              triple dircL=dir(c,Lc);
-              transform3 t0=shift(g0)*align(-dir0);
-              transform3 tL=shift(gL)*align(dirL);
-              transform3 tc0=shift(c0)*align(-dirc0);
-              transform3 tcL=shift(cL)*align(dircL);
-              if(linecap == 0 || linecap == 2) {
-                transform3 scale2r=scale(r,r,1);
-                T.s.append(t0*scale2r*unitdisk);
-                disk(tc0*scale2r);
-                if(L > 0) {
-                  T.s.append(tL*scale2r*unitdisk);
-                  disk(tcL*scale2r);
-                }
-              } else if(linecap == 1) {
-                transform3 scale3r=scale3(r);
-                T.s.append(t0*scale3r*
-                           (dir0 != O ? unithemisphere : unitsphere));
-                sphere(tc0*scale3r,half=straight(c,0));
-                if(L > 0) {
-                  T.s.append(tL*scale3r*
-                             (dirL != O ? unithemisphere : unitsphere));
-                  sphere(tcL*scale3r,half=straight(c,Lc-1));
-                }
+        }
+        tube T=tube(g,width);
+        path3 c=T.center;
+        if(L >= 0) {
+          if(open) {
+            int Lc=length(c);
+            triple c0=point(c,0);
+            triple cL=point(c,Lc);
+            triple dir0=dir(g,0);
+            triple dirL=dir(g,L);
+            triple dirc0=dir(c,0);
+            triple dircL=dir(c,Lc);
+            transform3 t0=shift(g0)*align(-dir0);
+            transform3 tL=shift(gL)*align(dirL);
+            transform3 tc0=shift(c0)*align(-dirc0);
+            transform3 tcL=shift(cL)*align(dircL);
+            if(linecap == 0 || linecap == 2) {
+              transform3 scale2r=scale(r,r,1);
+              T.s.push(t0*scale2r*unitdisk);
+              if(L > 0) {
+                T.s.push(tL*scale2r*unitdisk);
               }
+            } else if(linecap == 1) {
+              transform3 scale3r=scale3(r);
+              T.s.push(t0*scale3r*(straight(c,0) ?
+                                   unithemisphere : unitsphere));
+              if(L > 0)
+                T.s.push(tL*scale3r*(straight(c,Lc-1) ?
+                                     unithemisphere : unitsphere));
             }
-            if(opacity(q) == 1)
-              _draw(f,c,q);
           }
-          for(patch s : T.s.s)
-            draw3D(f,s,p,light,prc=false);
-        } else _draw(f,g,q);
-      } else _draw(f,g,q);
+// Draw central core for better small-scale rendering.
+          if((!prc || piecewisestraight(g)) && !webgl && opacity(q) == 1)
+            _draw(f,c,p,light);
+        }
+        for(surface s : T.s)
+          draw(f,s,p,light,render);
+      } else _draw(f,g,p,light);
     }
     bool group=q != nullpen && (name != "" || render.defaultnames);
     if(group)
@@ -2701,7 +2693,7 @@
 
     if(pic.bounds3.exact && noAdjust)
       this.P.bboxonly=false;
-    
+
     f=pic.fit3(t,pic.bounds3.exact ? pic2 : null,this.P);
 
     if(!pic.bounds3.exact) {

Modified: trunk/Build/source/utils/asymptote/base/three_arrows.asy
===================================================================
--- trunk/Build/source/utils/asymptote/base/three_arrows.asy	2020-03-03 22:33:26 UTC (rev 54033)
+++ trunk/Build/source/utils/asymptote/base/three_arrows.asy	2020-03-03 22:35:09 UTC (rev 54034)
@@ -105,8 +105,11 @@
           s.append(shift(-n)*t*extrude(g,width*Z));
     }
     if(draw)
-      for(path3 g : H)
-        s.append(tube(g,width).s);
+      for(path3 g : H) {
+        tube T=tube(g,width);
+        for(surface S : T.s)
+          s.append(S);
+      }
     return shift(v)*s;
   }
 
@@ -150,27 +153,26 @@
     real remainL=size;
     bool first=true;
     for(int i=0; i < n; ++i) {
-      render(subpath(s,i,i+1),new void(path3 q, real) {
-          if(remainL > 0) {
-            real l=arclength(q);
-            real w=remainL*aspect;
-            surface segment=scale(w,w,l)*unitcylinder;
-            if(first) { // add base
-              first=false;
-              segment.append(scale(w,w,1)*unitdisk);
+      path3 q=subpath(s,i,i+1);
+      if(remainL > 0) {
+        real l=arclength(q);
+        real w=remainL*aspect;
+        surface segment=scale(w,w,l)*unitcylinder;
+        if(first) { // add base
+          first=false;
+          segment.append(scale(w,w,1)*unitdisk);
+        }
+        for(patch p : segment.s) {
+          for(int i=0; i < 4; ++i) {
+            for(int j=0; j < 4; ++j) {
+              real k=1-p.P[i][j].z/remainL;
+              p.P[i][j]=bend((k*p.P[i][j].x,k*p.P[i][j].y,p.P[i][j].z),q,l);
             }
-            for(patch p : segment.s) {
-              for(int i=0; i < 4; ++i) {
-                for(int j=0; j < 4; ++j) {
-                  real k=1-p.P[i][j].z/remainL;
-                  p.P[i][j]=bend((k*p.P[i][j].x,k*p.P[i][j].y,p.P[i][j].z),q,l);
-                }
-              }
-            }
-            head.append(segment);
-            remainL -= l;
           }
-        });
+        }
+        head.append(segment);
+        remainL -= l;
+      }
     }
   }
   return head;

Modified: trunk/Build/source/utils/asymptote/base/three_light.asy
===================================================================
--- trunk/Build/source/utils/asymptote/base/three_light.asy	2020-03-03 22:33:26 UTC (rev 54033)
+++ trunk/Build/source/utils/asymptote/base/three_light.asy	2020-03-03 22:35:09 UTC (rev 54034)
@@ -80,9 +80,9 @@
   return m.p.length > 0 ? m.diffuse() : nullpen;
 }
 
-material emissive(material m)
+material emissive(material m, bool colors=false)
 {
-  return material(black+opacity(m.opacity),m.diffuse(),black,m.opacity,1);
+ return material(black+opacity(m.opacity),colors ? m.emissive() : m.diffuse()+m.emissive(),black,m.opacity,1);
 }
 
 pen color(triple normal, material m, light light, transform3 T=light.T) {

Modified: trunk/Build/source/utils/asymptote/base/three_surface.asy
===================================================================
--- trunk/Build/source/utils/asymptote/base/three_surface.asy	2020-03-03 22:33:26 UTC (rev 54033)
+++ trunk/Build/source/utils/asymptote/base/three_surface.asy	2020-03-03 22:35:09 UTC (rev 54034)
@@ -71,10 +71,6 @@
   triple BuP(int j, real u) {
     return bezierP(P[0][j],P[1][j],P[2][j],P[3][j],u);
   }
-  triple BuPP(int j, real u) {
-    return bezierPP(P[0][j],P[1][j],P[2][j],P[3][j],u);
-  }
-  triple BuPPP(int j) {return bezierPPP(P[0][j],P[1][j],P[2][j],P[3][j]);}
 
   path3 uequals(real u) {
     triple z0=Bu(0,u);
@@ -87,10 +83,6 @@
   triple BvP(int i, real v) {
     return bezierP(P[i][0],P[i][1],P[i][2],P[i][3],v);
   }
-  triple BvPP(int i, real v) {
-    return bezierPP(P[i][0],P[i][1],P[i][2],P[i][3],v);
-  }
-  triple BvPPP(int i) {return bezierPPP(P[i][0],P[i][1],P[i][2],P[i][3]);}
 
   path3 vequals(real v) {
     triple z0=Bv(0,v);
@@ -103,29 +95,52 @@
     return bezier(Bu(0,u),Bu(1,u),Bu(2,u),Bu(3,u),v);
   }
 
-  // compute normal vectors for degenerate cases
-  private triple normal0(real u, real v, real epsilon) {
-    triple n=0.5*(cross(bezier(BuPP(0,u),BuPP(1,u),BuPP(2,u),BuPP(3,u),v),
-                        bezier(BvP(0,v),BvP(1,v),BvP(2,v),BvP(3,v),u))+
-                  cross(bezier(BuP(0,u),BuP(1,u),BuP(2,u),BuP(3,u),v),   
-                        bezier(BvPP(0,v),BvPP(1,v),BvPP(2,v),BvPP(3,v),u)));
-    return abs(n) > epsilon ? n :
-      0.25*cross(bezier(BuPP(0,u),BuPP(1,u),BuPP(2,u),BuPP(3,u),v),   
-                 bezier(BvPP(0,v),BvPP(1,v),BvPP(2,v),BvPP(3,v),u))+
-      1/6*(cross(bezier(BuP(0,u),BuP(1,u),BuP(2,u),BuP(3,u),v),   
-                 bezier(BvPPP(0),BvPPP(1),BvPPP(2),BvPPP(3),u))+
-           cross(bezier(BuPPP(0),BuPPP(1),BuPPP(2),BuPPP(3),v),
-                 bezier(BvP(0,v),BvP(1,v),BvP(2,v),BvP(3,v),u)))+
-      1/12*(cross(bezier(BuPPP(0),BuPPP(1),BuPPP(2),BuPPP(3),v),
-                  bezier(BvPP(0,v),BvPP(1,v),BvPP(2,v),BvPP(3,v),u))+
-            cross(bezier(BuPP(0,u),BuPP(1,u),BuPP(2,u),BuPP(3,u),v),   
-                  bezier(BvPPP(0),BvPPP(1),BvPPP(2),BvPPP(3),u)))+
-      1/36*cross(bezier(BuPPP(0),BuPPP(1),BuPPP(2),BuPPP(3),v),   
-                 bezier(BvPPP(0),BvPPP(1),BvPPP(2),BvPPP(3),u));
+  static real fuzz=1000*realEpsilon;
+
+  triple normal(triple left3, triple left2, triple left1, triple middle,
+                triple right1, triple right2, triple right3) {
+    real epsilon=fuzz*change2(P);
+
+    triple lp=3.0*(left1-middle);
+    triple rp=3.0*(right1-middle);
+
+    triple n=cross(rp,lp);
+    if(abs(n) > epsilon)
+      return n;
+
+    // Return one-half of the second derivative of the Bezier curve defined
+    // by a,b,c,d at 0.
+    triple bezierPP(triple a, triple b, triple c) {
+      return 3.0*(a+c-2.0*b);
+    }
+
+    triple lpp=bezierPP(middle,left1,left2);
+    triple rpp=bezierPP(middle,right1,right2);
+
+    n=cross(rpp,lp)+cross(rp,lpp);
+    if(abs(n) > epsilon)
+      return n;
+
+    // Return one-sixth of the third derivative of the Bezier curve defined
+    // by a,b,c,d at 0.
+    triple bezierPPP(triple a, triple b, triple c, triple d) {
+      return d-a+3.0*(b-c);
+    }
+
+    triple lppp=bezierPPP(middle,left1,left2,left3);
+    triple rppp=bezierPPP(middle,right1,right2,right3);
+
+    n=cross(rpp,lpp)+cross(rppp,lp)+cross(rp,lppp);
+    if(abs(n) > epsilon)
+      return n;
+
+    n=cross(rppp,lpp)+cross(rpp,lppp);
+    if(abs(n) > epsilon)
+      return n;
+
+    return cross(rppp,lppp);
   }
 
-  static real fuzz=1000*realEpsilon;
-
   triple partialu(real u, real v) {
     return bezier(BuP(0,u),BuP(1,u),BuP(2,u),BuP(3,u),v);
   }
@@ -134,36 +149,34 @@
     return bezier(BvP(0,v),BvP(1,v),BvP(2,v),BvP(3,v),u);
   }
 
-  triple normal(real u, real v) {
-    triple n=cross(partialu(u,v),partialv(u,v));
-    real epsilon=fuzz*change2(P);
-    return (abs(n) > epsilon) ? n : normal0(u,v,epsilon);
-  }
-  
   triple normal00() {
-    triple n=9*cross(P[1][0]-P[0][0],P[0][1]-P[0][0]);
-    real epsilon=fuzz*change2(P);
-    return abs(n) > epsilon ? n : normal0(0,0,epsilon);
+    return normal(P[0][3],P[0][2],P[0][1],P[0][0],P[1][0],P[2][0],P[3][0]);
   }
 
   triple normal10() {
-    triple n=9*cross(P[3][0]-P[2][0],P[3][1]-P[3][0]);
-    real epsilon=fuzz*change2(P);
-    return abs(n) > epsilon ? n : normal0(1,0,epsilon);
+    return normal(P[0][0],P[1][0],P[2][0],P[3][0],P[3][1],P[3][2],P[3][3]);
   }
 
   triple normal11() {
-    triple n=9*cross(P[3][3]-P[2][3],P[3][3]-P[3][2]);
-    real epsilon=fuzz*change2(P);
-    return abs(n) > epsilon ? n : normal0(1,1,epsilon);
+    return normal(P[3][0],P[3][1],P[3][2],P[3][3],P[2][3],P[1][3],P[0][3]);
   }
 
   triple normal01() {
-    triple n=9*cross(P[1][3]-P[0][3],P[0][3]-P[0][2]);
-    real epsilon=fuzz*change2(P);
-    return abs(n) > epsilon ? n : normal0(0,1,epsilon);
+    return normal(P[3][3],P[2][3],P[1][3],P[0][3],P[0][2],P[0][1],P[0][0]);
   }
 
+  triple normal(real u, real v) {
+    if(u == 0) {
+      if(v == 0) return normal00();
+      if(v == 1) return normal01();
+    }
+    if(u == 1) {
+      if(v == 0) return normal10();
+      if(v == 1) return normal11();
+    }
+    return cross(partialu(u,v),partialv(u,v));
+  }
+
   triple pointtriangular(real u, real v) {
     real w=1-u-v;
     return w^2*(w*P[0][0]+3*(u*P[1][0]+v*P[1][1]))+
@@ -171,7 +184,7 @@
       6*u*v*w*P[2][1]+v^2*(3*(w*P[2][2]+u*P[3][2])+v*P[3][3]);
   }
 
-  triple bu(real u, real v) {
+  triple partialutriangular(real u, real v) {
     // Compute one-third of the directional derivative of a Bezier triangle
     // in the u direction at (u,v).
     real w=1-u-v;
@@ -179,21 +192,7 @@
       2*v*(w-u)*P[2][1]-v^2*P[2][2]+u^2*P[3][0]+2*u*v*P[3][1]+v^2*P[3][2];
   }
 
-  triple buu(real u, real v) {
-    // Compute one-sixth of the second directional derivative of a Bezier
-    // triangle in the u direction at (u,v).
-    real w=1-u-v;
-    return w*P[0][0]+(u-2*w)*P[1][0]+v*P[1][1]+(w-2*u)*P[2][0]-2*v*P[2][1]+
-      u*P[3][0]+v*P[3][1];
-  }
-
-  triple buuu() {
-    // Compute one-sixth of the third directional derivative of a Bezier
-    // triangle in the u direction at (u,v).
-    return -P[0][0]+3*P[1][0]-3*P[2][0]+P[3][0];
-  }
-
-  triple bv(real u, real v) {
+  triple partialvtriangular(real u, real v) {
     // Compute one-third of the directional derivative of a Bezier triangle
     // in the v direction at (u,v).
     real w=1-u-v;
@@ -202,56 +201,28 @@
       v^2*P[3][3];
   }
 
-  triple bvv(real u, real v) {
-    // Compute one-sixth of the second directional derivative of a Bezier
-    // triangle in the v direction at (u,v).
-    real w=1-u-v;
-    return w*P[0][0]+u*P[1][0]+(v-2*w)*P[1][1]-2*u*P[2][1]+(w-2*v)*P[2][2]+
-      u*P[3][2]+v*P[3][3];
+  triple normal00triangular() {
+    return normal(P[3][3],P[2][2],P[1][1],P[0][0],P[1][0],P[2][0],P[3][0]);
   }
 
-  triple bvvv() {
-    // Compute one-sixth of the third directional derivative of a Bezier
-    // triangle in the v direction at (u,v).
-    return -P[0][0]+3*P[1][1]-3*P[2][2]+P[3][3];
+  triple normal10triangular() {
+    return normal(P[0][0],P[1][0],P[2][0],P[3][0],P[3][1],P[3][2],P[3][3]);
   }
 
-  // compute normal vectors for a degenerate Bezier triangle
-  private triple normaltriangular0(real u, real v, real epsilon) {
-    triple n=9*(cross(buu(u,v),bv(u,v))+
-                  cross(bu(u,v),bvv(u,v)));
-    return abs(n) > epsilon ? n :
-      9*cross(buu(u,v),bvv(u,v))+
-      3*(cross(buuu(),bv(u,v))+cross(bu(u,v),bvvv())+
-         cross(buuu(),bvv(u,v))+cross(buu(u,v),bvvv()))+
-      cross(buuu(),bvvv());
+  triple normal01triangular() {
+    return normal(P[3][0],P[3][1],P[3][2],P[3][3],P[2][2],P[1][1],P[0][0]);
   }
 
-  // Compute the normal of a Bezier triangle at (u,v)
+  // Compute the normal vector of a Bezier triangle at (u,v)
   triple normaltriangular(real u, real v) {
-    triple n=9*cross(bu(u,v),bv(u,v));
-    real epsilon=fuzz*change2(P);
-    return (abs(n) > epsilon) ? n : normal0(u,v,epsilon);
+    if(u == 0) {
+      if(v == 0) return normal00triangular();
+      if(v == 1) return normal01triangular();
+    }
+    if(u == 1 && v == 0) return normal10triangular();
+    return cross(partialutriangular(u,v),partialvtriangular(u,v));
   }
 
-  triple normal00triangular() {
-    triple n=9*cross(P[1][0]-P[0][0],P[1][1]-P[0][0]);
-    real epsilon=fuzz*change2(P);
-    return abs(n) > epsilon ? n : normaltriangular0(0,0,epsilon);
-  }
-
-  triple normal10triangular() {
-    triple n=9*cross(P[3][0]-P[2][0],P[3][1]-P[2][0]);
-    real epsilon=fuzz*change2(P);
-    return abs(n) > epsilon ? n : normaltriangular0(1,0,epsilon);
-  }
-
-  triple normal01triangular() {
-    triple n=9*cross(P[3][2]-P[2][2],P[3][3]-P[2][2]);
-    real epsilon=fuzz*change2(P);
-    return abs(n) > epsilon ? n : normaltriangular0(0,1,epsilon);
-  }
-
   pen[] colors(material m, light light=currentlight) {
     bool nocolors=colors.length == 0;
     if(planar) {
@@ -751,11 +722,18 @@
   return s;
 }
 
+typedef void drawfcn(frame f, transform3 t=identity4, material[] m,
+            light light=currentlight, render render=defaultrender);
+
 struct surface {
   patch[] s;
   int index[][];// Position of patch corresponding to major U,V parameter in s.
   bool vcyclic;
+  transform3 T=identity4;
   
+  drawfcn draw;
+  bool PRCprimitive=true; // True unless no PRC primitive is available.
+
   bool empty() {
     return s.length == 0;
   }
@@ -1052,6 +1030,9 @@
     S.s[i]=t*s.s[i];
   S.index=copy(s.index);
   S.vcyclic=(bool) s.vcyclic;
+  S.T=t*s.T;
+  S.draw=s.draw;
+  S.PRCprimitive=s.PRCprimitive;
   
   return S;
 }
@@ -1365,16 +1346,6 @@
   return s.point(u,v);
 }
 
-real PRCshininess(real shininess) 
-{
-  // Empirical translation table from Phong-Blinn to PRC shininess model:
-  static real[] x={0.015,0.025,0.05,0.07,0.1,0.14,0.23,0.5,0.65,0.75,0.85,
-                   0.875,0.9,1};
-  static real[] y={0.05,0.1,0.15,0.2,0.25,0.3,0.4,0.5,0.55,0.6,0.7,0.8,0.9,1};
-  static realfunction s=fspline(x,y,monotonic);
-  return s(shininess);
-}
-
 struct interaction
 {
   int type;
@@ -1393,32 +1364,36 @@
   return settings.autobillboard ? Billboard : Embedded;
 }
 
-material material(material m, light light) 
+material material(material m, light light, bool colors=false)
 {
-  return light.on() || invisible((pen) m) ? m : emissive(m);
+  return light.on() || invisible((pen) m) ? m : emissive(m,colors);
 }
 
-void draw3D(frame f, int type=0, patch s, triple center=O, material m,
+void draw3D(frame f, patch s, triple center=O, material m,
             light light=currentlight, interaction interaction=Embedded,
-            bool prc=true)
+            bool primitive=false)
 {
   bool straight=s.straight && s.planar;
-  bool prc=prc();
   if(s.colors.length > 0) {
-    if(prc && light.on())
+    if(prc() && light.on())
         straight=false; // PRC vertex colors (for quads only) ignore lighting
-    m=mean(s.colors);
+    m.diffuse(mean(s.colors));
   }
-  m=material(m,light);
+  m=material(m,light,s.colors.length > 0);
   
-  real PRCshininess;
-  if(prc) PRCshininess=PRCshininess(m.shininess);
-
   (s.triangular ? drawbeziertriangle : draw)
     (f,s.P,center,straight,m.p,m.opacity,m.shininess,
-    m.metallic,m.fresnel0,PRCshininess,s.colors,interaction.type,prc);
+     m.metallic,m.fresnel0,s.colors,interaction.type,primitive);
 }
 
+void _draw(frame f, path3 g, triple center=O, material m,
+           light light=currentlight, interaction interaction=Embedded)
+{
+  if(!prc()) m=material(m,light);
+  _draw(f,g,center,m.p,m.opacity,m.shininess,m.metallic,m.fresnel0,
+        interaction.type);
+}
+
 int computeNormals(triple[] v, int[][] vi, triple[] n, int[][] ni)
 {
   triple lastnormal=O;
@@ -1448,11 +1423,7 @@
   if(p.length > 0)
     m=mean(p);
   m=material(m,light);
-  real PRCshininess;
-  if(prc())
-    PRCshininess=PRCshininess(m.shininess);
-  draw(f,v,vi,n,ni,m.p,m.opacity,m.shininess,m.metallic,m.fresnel0,
-      PRCshininess,p,pi);
+  draw(f,v,vi,n,ni,m.p,m.opacity,m.shininess,m.metallic,m.fresnel0,p,pi);
 }
   
 // Draw triangles on a picture.
@@ -1520,40 +1491,9 @@
       pic.addPoint(v[viij]);
 }
 
-void drawPRCsphere(frame f, transform3 t=identity4, bool half=false,
-                   material m, light light=currentlight,
-                   render render=defaultrender)
-{
-  m=material(m,light);
-  drawPRCsphere(f,t,half,m.p,m.opacity,PRCshininess(m.shininess),
-                render.sphere);
-}
-
-void drawPRCcylinder(frame f, transform3 t=identity4, material m,
-                     light light=currentlight)
-{
-  m=material(m,light);
-  drawPRCcylinder(f,t,m.p,m.opacity,PRCshininess(m.shininess));
-}
-
-void drawPRCdisk(frame f, transform3 t=identity4, material m,
-                 light light=currentlight)
-{
-  m=material(m,light);
-  drawPRCdisk(f,t,m.p,m.opacity,PRCshininess(m.shininess));
-}
-
-void drawPRCtube(frame f, path3 center, path3 g, material m,
-                 light light=currentlight)
-{
-  m=material(m,light);
-  drawPRCtube(f,center,g,m.p,m.opacity,PRCshininess(m.shininess));
-}
-
 void tensorshade(transform t=identity(), frame f, patch s,
                  material m, light light=currentlight, projection P)
 {
-  
   pen[] p;
   if(s.triangular) {
     p=s.colorstriangular(m,light);
@@ -1574,53 +1514,62 @@
 {
   bool is3D=is3D();
   if(is3D) {
-    bool group=name != "" || render.defaultnames;
-    if(group)
-      begingroup3(f,name == "" ? "surface" : name,render);
+    bool prc=prc();
+    if(s.draw != null && (settings.outformat == "html" ||
+                          (prc && s.PRCprimitive))) {
+      for(int k=0; k < s.s.length; ++k)
+        draw3D(f,s.s[k],surfacepen[k],light,primitive=true);
+      s.draw(f,s.T,surfacepen,light,render);
+    } else {
+      bool group=name != "" || render.defaultnames;
+      if(group)
+        begingroup3(f,name == "" ? "surface" : name,render);
 
-    // Sort patches by mean distance from camera
-    triple camera=P.camera;
-    if(P.infinity) {
-      triple m=min(s);
-      triple M=max(s);
-      camera=P.target+camerafactor*(abs(M-m)+abs(m-P.target))*unit(P.vector());
-    }
+      // Sort patches by mean distance from camera
+      triple camera=P.camera;
+      if(P.infinity) {
+        triple m=min(s);
+        triple M=max(s);
+        camera=P.target+camerafactor*(abs(M-m)+abs(m-P.target))*
+          unit(P.vector());
+      }
 
-    real[][] depth=new real[s.s.length][];
-    for(int i=0; i < depth.length; ++i)
-      depth[i]=new real[] {dot(P.normal,camera-s.s[i].cornermean()),i};
+      real[][] depth=new real[s.s.length][];
+      for(int i=0; i < depth.length; ++i)
+        depth[i]=new real[] {dot(P.normal,camera-s.s[i].cornermean()),i};
 
-    depth=sort(depth);
+      depth=sort(depth);
 
-    for(int p=depth.length-1; p >= 0; --p) {
-      real[] a=depth[p];
-      int k=round(a[1]);
-      draw3D(f,s.s[k],surfacepen[k],light);
-    }
+      for(int p=depth.length-1; p >= 0; --p) {
+        real[] a=depth[p];
+        int k=round(a[1]);
+        draw3D(f,s.s[k],surfacepen[k],light);
+      }
 
-    if(group)
-      endgroup3(f);
+      if(group)
+        endgroup3(f);
 
-    pen modifiers=thin()+squarecap;
-    for(int p=depth.length-1; p >= 0; --p) {
-      real[] a=depth[p];
-      int k=round(a[1]);
-      patch S=s.s[k];
-      pen meshpen=meshpen[k];
-      if(!invisible(meshpen) && !S.triangular) {
-        if(group)
-          begingroup3(f,meshname(name),render);
-        meshpen=modifiers+meshpen;
-        real step=nu == 0 ? 0 : 1/nu;
-        for(int i=0; i <= nu; ++i)
-          draw(f,S.uequals(i*step),meshpen,meshlight,partname(i,render),
-               render);
-        step=nv == 0 ? 0 : 1/nv;
-        for(int j=0; j <= nv; ++j)
-          draw(f,S.vequals(j*step),meshpen,meshlight,partname(j,render),
-               render);
-        if(group)
-          endgroup3(f);
+      pen modifiers=thin()+squarecap;
+      for(int p=depth.length-1; p >= 0; --p) {
+        real[] a=depth[p];
+        int k=round(a[1]);
+        patch S=s.s[k];
+        pen meshpen=meshpen[k];
+        if(!invisible(meshpen) && !S.triangular) {
+          if(group)
+            begingroup3(f,meshname(name),render);
+          meshpen=modifiers+meshpen;
+          real step=nu == 0 ? 0 : 1/nu;
+          for(int i=0; i <= nu; ++i)
+            draw(f,S.uequals(i*step),meshpen,meshlight,partname(i,render),
+                 render);
+          step=nv == 0 ? 0 : 1/nv;
+          for(int j=0; j <= nv; ++j)
+            draw(f,S.vequals(j*step),meshpen,meshlight,partname(j,render),
+                 render);
+          if(group)
+            endgroup3(f);
+        }
       }
     }
   }
@@ -1881,7 +1830,7 @@
         draw3D(f3,S,position,L.p,light,interaction);
         // Fill subdivision cracks
         if(prc && render.labelfill && opacity(L.p) == 1 && !lighton)
-          _draw(f3,S.external(),position,L.p,interaction.type);
+          _draw(f3,S.external(),position,L.p,light,interaction);
       }
       endgroup3(f3);
           if(L.defaulttransform3)
@@ -1901,7 +1850,7 @@
         draw3D(f,S,V,L.p,light,interaction);
         // Fill subdivision cracks
         if(prc && render.labelfill && opacity(L.p) == 1 && !lighton)
-          _draw(f,S.external(),V,L.p,interaction.type);
+          _draw(f,S.external(),V,L.p,light,interaction);
       }
       endgroup3(f);
     }
@@ -1970,7 +1919,7 @@
               draw3D(f3,S,v,L.p,light,interaction);
               // Fill subdivision cracks
               if(prc && render.labelfill && opacity(L.p) == 1 && !lighton)
-                _draw(f3,S.external(),v,L.p,interaction.type);
+                _draw(f3,S.external(),v,L.p,light,interaction);
             }
             endgroup3(f3);
             if(L.defaulttransform3)
@@ -1990,7 +1939,7 @@
             draw3D(f,S,V,L.p,light,interaction);
             // Fill subdivision cracks
             if(prc && render.labelfill && opacity(L.p) == 1 && !lighton)
-              _draw(f,S.external(),V,L.p,interaction.type);
+              _draw(f,S.external(),V,L.p,light,interaction);
           }
           endgroup3(f);
         }
@@ -2114,14 +2063,25 @@
 }
 
 private real a=4/3*(sqrt(2)-1);
+private real f=0.5*sqrt(3)*a^2;
+
 private transform3 t1=rotate(90,O,Z);
 private transform3 t2=t1*t1;
 private transform3 t3=t2*t1;
 private transform3 i=xscale3(-1)*zscale3(-1);
 
-restricted patch octant1=patch(X{Y}..{-X}Y{Z}..{-Y}Z..Z{X}..{-Z}cycle,
+// Degenerate first octant
+restricted patch octant1x=patch(X{Y}..{-X}Y{Z}..{-Y}Z..Z{X}..{-Z}cycle,
                                new triple[] {(1,a,a),(a,1,a),(a^2,a,1),
-                                             (a,a^2,1)});
+                                               (a,a^2,1)});
+private triple[][][] P=hsplit(octant1x.P,
+                      intersect((1,0){N}..{W}(0,1),(0,0)--2*dir(60))[0]);
+// Nondegenerate first octant
+surface octant1=surface(patch(P[0]),
+                        patch(P[1][0][0]..controls P[1][1][0] and P[1][2][0]..
+                              P[1][3][0]..controls P[1][3][1] and P[1][3][2]..
+                              P[1][3][3]..controls P[1][0][2] and P[1][0][1]..
+                              cycle,(f,f,1)));
 
 restricted surface unithemisphere=surface(octant1,t1*octant1,t2*octant1,
                                           t3*octant1);
@@ -2129,33 +2089,41 @@
                                       i*octant1,i*t1*octant1,i*t2*octant1,
                                       i*t3*octant1);
 
-restricted patch unitfrustum(real t1, real t2)
+unitsphere.draw=
+  new void(frame f, transform3 t=identity4, material[] m,
+           light light=currentlight, render render=defaultrender)
+  {
+   material m=material(m[0],light);
+   drawSphere(f,t,half=false,m.p,m.opacity,m.shininess,m.metallic,m.fresnel0,
+             render.sphere);
+  };
+
+unithemisphere.draw=
+  new void(frame f, transform3 t=identity4, material[] m,
+           light light=currentlight, render render=defaultrender)
+  {
+   material m=material(m[0],light);
+   drawSphere(f,t,half=true,m.p,m.opacity,m.shininess,m.metallic,m.fresnel0,
+             render.sphere);
+  };
+
+restricted patch unitfrustum1(real ta, real tb)
 {
-  real s1=interp(t1,t2,1/3);
-  real s2=interp(t1,t2,2/3);
-  return patch(interp(Z,X,t2){Y}..{-X}interp(Z,Y,t2)--interp(Z,Y,t1){X}..{-Y}
-               interp(Z,X,t1)--cycle,
+  real s1=interp(ta,tb,1/3);
+  real s2=interp(ta,tb,2/3);
+  return patch(interp(Z,X,tb){Y}..{-X}interp(Z,Y,tb)--interp(Z,Y,ta){X}..{-Y}
+               interp(Z,X,ta)--cycle,
                new triple[] {(s2,s2*a,1-s2),(s2*a,s2,1-s2),(s1*a,s1,1-s1),
                                           (s1,s1*a,1-s1)});
 }
 
-// Return a unitcone constructed from n frusta (the final one being degenerate)
-surface unitcone(int n=6)
+restricted surface unitfrustum(real ta, real tb)
 {
-  surface unitcone;
-  unitcone.s=new patch[4*n];
-  real r=1/3;
-  for(int i=0; i < n; ++i) {
-    patch s=unitfrustum(i < n-1 ? r^(i+1) : 0,r^i);
-    unitcone.s[i]=s;
-    unitcone.s[n+i]=t1*s;
-    unitcone.s[2n+i]=t2*s;
-    unitcone.s[3n+i]=t3*s;
-  }
-  return unitcone;
+  patch p=unitfrustum1(ta,tb);
+  return surface(p,t1*p,t2*p,t3*p);
 }
 
-restricted surface unitcone=unitcone();
+restricted surface unitcone=surface(unitfrustum(0,1));
 restricted surface unitsolidcone=surface(patch(unitcircle3)...unitcone.s);
 
 // Construct an approximate cone over an arbitrary base.
@@ -2166,6 +2134,18 @@
 restricted surface unitcylinder=surface(unitcylinder1,t1*unitcylinder1,
                                         t2*unitcylinder1,t3*unitcylinder1);
 
+drawfcn unitcylinderDraw(bool core) {
+  return new void(frame f, transform3 t=identity4, material[] m,
+           light light=currentlight, render render=defaultrender)
+  {
+   material m=material(m[0],light);
+   drawCylinder(f,t,m.p,m.opacity,m.shininess,m.metallic,m.fresnel0,
+                m.opacity == 1 ? core : false);
+  };
+}
+
+unitcylinder.draw=unitcylinderDraw(false);
+
 private patch unitplane=patch(new triple[] {O,X,X+Y,Y});
 restricted surface unitcube=surface(reverse(unitplane),
                                     rotate(90,O,X)*unitplane,
@@ -2176,24 +2156,23 @@
 restricted surface unitplane=surface(unitplane);
 restricted surface unitdisk=surface(unitcircle3);
 
+unitdisk.draw=
+  new void(frame f, transform3 t=identity4, material[] m,
+           light light=currentlight, render render=defaultrender)
+  {
+   material m=material(m[0],light);
+   drawDisk(f,t,m.p,m.opacity,m.shininess,m.metallic,m.fresnel0);
+  };
+
 void dot(frame f, triple v, material p=currentpen,
          light light=nolight, string name="",
          render render=defaultrender, projection P=currentprojection)
 {
+  if(name == "" && render.defaultnames) name="dot";
   pen q=(pen) p;
-  if(is3D()) {
-    bool group=name != "" || render.defaultnames;
-    if(group)
-      begingroup3(f,name == "" ? "dot" : name,render);
-    real size=0.5*linewidth(dotsize(q)+q);
-    transform3 T=shift(v)*scale3(size);
-    for(patch s : unitsphere.s)
-      draw3D(f,T*s,v,p,light,prc=false);
-    if(prc())
-      drawPRCsphere(f,T,p,light);
-    if(group)
-      endgroup3(f);
-  } else dot(f,project(v,P.t),q);
+  real size=0.5*linewidth(dotsize(q)+q);
+  transform3 T=shift(v)*scale3(size);
+  draw(f,T*unitsphere,p,light,name,render,P);
 }
 
 void dot(frame f, triple[] v, material p=currentpen, light light=nolight,
@@ -2250,18 +2229,7 @@
   real size=0.5*linewidth(dotsize(q)+q);
   pic.add(new void(frame f, transform3 t, picture pic, projection P) {
       triple V=t*v;
-      if(is3D()) {
-        bool group=name != "" || render.defaultnames;
-        if(group)
-          begingroup3(f,name == "" ? "dot" : name,render);
-        transform3 T=shift(V)*scale3(size);
-        for(patch s : unitsphere.s)
-          draw3D(f,T*s,V,p,light,prc=false);
-        if(prc())
-          drawPRCsphere(f,T,p,light,render);
-        if(group)
-          endgroup3(f);
-      }
+      dot(f,V,p,light,name,render,P);
       if(pic != null)
         dot(pic,project(V,P.t),q);
     },true);
@@ -2450,11 +2418,8 @@
         if(group)
           begingroup3(f,name == "" ? "surface" : name,render);
         triple[][] P=t*P;
-        real PRCshininess;
-        if(prc())
-          PRCshininess=PRCshininess(m.shininess);
-        draw(f,P,uknot,vknot,weights,m.p,m.opacity,m.shininess,m.metallic,m.fresnel0,
-              PRCshininess,colors);
+        draw(f,P,uknot,vknot,weights,m.p,m.opacity,m.shininess,m.metallic,
+             m.fresnel0,colors);
         if(group)
           endgroup3(f);
         if(pic != null)

Modified: trunk/Build/source/utils/asymptote/base/three_tube.asy
===================================================================
--- trunk/Build/source/utils/asymptote/base/three_tube.asy	2020-03-03 22:33:26 UTC (rev 54033)
+++ trunk/Build/source/utils/asymptote/base/three_tube.asy	2020-03-03 22:35:09 UTC (rev 54034)
@@ -1,41 +1,15 @@
-void render(path3 s, void f(path3, real), render render=defaultrender)
-{
-  real granularity=render.tubegranularity;
-  void Split(triple z0, triple c0, triple c1, triple z1, real t0=0, real t1=1,
-             real depth=mantissaBits) {
-    if(depth > 0) {
-      real S=straightness(z0,c0,c1,z1);
-      if(S > 0) {
-        --depth;
-        if(S > max(granularity*max(abs(z0),abs(c0),abs(c1),abs(z1)))) {
-          triple m0=0.5*(z0+c0);
-          triple m1=0.5*(c0+c1);
-          triple m2=0.5*(c1+z1);
-          triple m3=0.5*(m0+m1);
-          triple m4=0.5*(m1+m2);
-          triple m5=0.5*(m3+m4);
-          real tm=0.5*(t0+t1);
-          Split(z0,m0,m3,m5,t0,tm,depth);
-          Split(m5,m4,m2,z1,tm,t1,depth);
-          return;
-        }
-      }
-    }
-    f(z0..controls c0 and c1..z1,t0);
-  }
-  Split(point(s,0),postcontrol(s,0),precontrol(s,1),point(s,1));
-}
-
-struct rmf
-{
+struct rmf {
   triple p,r,t,s;
-  void operator init(triple p, triple r, triple t)
-  {
+  void operator init(triple p, triple r, triple t) {
     this.p=p;
     this.r=r;
     this.t=t;
     s=cross(t,r);
   }
+
+  transform3 transform() {
+    return transform3(r,s,t);
+  }
 }
 
 // Rotation minimizing frame
@@ -66,344 +40,172 @@
   return R;
 }
 
-private real[][][] bispline0(real[][] z, real[][] p, real[][] q, real[][] r,
-                             real[] x, real[] y, bool[][] cond={})
-{ // z[i][j] is the value at (x[i],y[j])
-  // p and q are the first derivatives with respect to x and y, respectively
-  // r is the second derivative ddu/dxdy
-  int n=x.length-1;
-  int m=y.length-1;
+rmf[] rmf(triple z0, triple c0, triple c1, triple z1, real[] t)
+{
+  real norm=sqrtEpsilon*max(abs(z0),abs(c0),abs(c1),abs(z1));
 
-  bool all=cond.length == 0;
-
-  int count;
-  if(all)
-    count=n*m;
-  else {
-    count=0;
-    for(int i=0; i < n; ++i) {
-      bool[] condi=cond[i];
-      bool[] condp=cond[i+1];
-      for(int j=0; j < m; ++j)
-        if(all || (condi[j] && condi[j+1] && condp[j] && condp[j+1])) 
-          ++count;
+// Special case of dir for t in (0,1].
+  triple dir(real t) {
+    if(t == 1) {
+      triple dir=z1-c1;
+      if(abs(dir) > norm) return unit(dir);
+      dir=2.0*c1-c0-z1;
+      if(abs(dir) > norm) return unit(dir);
+      return unit(z1-z0+3.0*(c0-c1));
     }
+    triple a=z1-z0+3.0*(c0-c1);
+    triple b=2.0*(z0+c1)-4.0*c0;
+    triple c=c0-z0;
+    triple dir=a*t*t+b*t+c;
+    if(abs(dir) > norm) return unit(dir);
+    dir=2.0*a*t+b;
+    if(abs(dir) > norm) return unit(dir);
+    return unit(a);
   }
 
-  real[][][] s=new real[count][][];
-  int k=0;
-  for(int i=0; i < n; ++i) {
-    int ip=i+1;
-    real xi=x[i];
-    real xp=x[ip];
-    real hx=(xp-xi)/3;
-    real[] zi=z[i];
-    real[] zp=z[ip];
-    real[] ri=r[i];
-    real[] rp=r[ip];
-    real[] pi=p[i];
-    real[] pp=p[ip];
-    real[] qi=q[i];
-    real[] qp=q[ip];
-    bool[] condi=all ? null : cond[i];
-    bool[] condp=all ? null : cond[i+1];
-    for(int j=0; j < m; ++j) {
-      if(all || (condi[j] && condi[j+1] && condp[j] && condp[j+1])) {
-        real yj=y[j];
-        int jp=j+1;
-        real yp=y[jp];
-        real hy=(yp-yj)/3;
-        real hxy=hx*hy;
-        real zij=zi[j];
-        real zip=zi[jp];
-        real zpj=zp[j];
-        real zpp=zp[jp];
-        real pij=hx*pi[j];
-        real ppj=hx*pp[j];
-        real qip=hy*qi[jp];
-        real qpp=hy*qp[jp];
-        real zippip=zip+hx*pi[jp];
-        real zppmppp=zpp-hx*pp[jp];
-        real zijqij=zij+hy*qi[j];
-        real zpjqpj=zpj+hy*qp[j];
-        
-        s[k]=new real[][] {{zij,zijqij,zip-qip,zip},
-                           {zij+pij,zijqij+pij+hxy*ri[j],
-                            zippip-qip-hxy*ri[jp],zippip},
-                           {zpj-ppj,zpjqpj-ppj-hxy*rp[j],
-                            zppmppp-qpp+hxy*rp[jp],zppmppp},
-                           {zpj,zpjqpj,zpp-qpp,zpp}};
-        ++k;
-      }
-    }
+  rmf[] R=new rmf[t.length];
+  triple T=c0-z0;
+  if(abs(T) < norm) {
+    T=z0-2*c0+c1;
+    if(abs(T) < norm)
+      T=z1-z0+3.0*(c0-c1);
   }
-  
-  return s;
-}
-
-// return the surface values described by a real matrix f, interpolated with
-// xsplinetype and ysplinetype.
-real[][][] bispline(real[][] f, real[] x, real[] y,
-                    splinetype xsplinetype=null,
-                    splinetype ysplinetype=xsplinetype, bool[][] cond={})
-{
-  real epsilon=sqrtEpsilon*norm(y);
-  if(xsplinetype == null)
-    xsplinetype=(abs(x[0]-x[x.length-1]) <= epsilon) ? periodic : notaknot;
-  if(ysplinetype == null)
-    ysplinetype=(abs(y[0]-y[y.length-1]) <= epsilon) ? periodic : notaknot;
-  int n=x.length; int m=y.length;
-  real[][] ft=transpose(f);
-  real[][] tp=new real[m][];
-  for(int j=0; j < m; ++j)
-    tp[j]=xsplinetype(x,ft[j]);
-  real[][] q=new real[n][];
-  for(int i=0; i < n; ++i)
-    q[i]=ysplinetype(y,f[i]);
-  real[][] qt=transpose(q);
-  real[] d1=xsplinetype(x,qt[0]);
-  real[] d2=xsplinetype(x,qt[m-1]);
-  real[][] r=new real[n][];
-  real[][] p=transpose(tp);
-  for(int i=0; i < n; ++i)
-    r[i]=clamped(d1[i],d2[i])(y,p[i]);
-  return bispline0(f,p,q,r,x,y,cond);
-}
-
-bool uperiodic(real[][] a) {
-  int n=a.length;
-  if(n == 0) return false;
-  int m=a[0].length;
-  real[] a0=a[0];
-  real[] a1=a[n-1];
-  for(int j=0; j < m; ++j) {
-    real norm=0;
-    for(int i=0; i < n; ++i)
-      norm=max(norm,abs(a[i][j]));
-    real epsilon=sqrtEpsilon*norm;
-    if(abs(a0[j]-a1[j]) > epsilon) return false;
+  T=unit(T);
+  triple Tp=perp(T);
+  R[0]=rmf(z0,Tp,T);
+  for(int i=1; i < t.length; ++i) {
+    rmf Ri=R[i-1];
+    real t=t[i];
+    triple p=bezier(z0,c0,c1,z1,t);
+    triple v1=p-Ri.p;
+    if(v1 != O) {
+      triple r=Ri.r;
+      triple u1=unit(v1);
+      triple ti=Ri.t;
+      triple tp=ti-2*dot(u1,ti)*u1;
+      ti=dir(t);
+      triple rp=r-2*dot(u1,r)*u1;
+      triple u2=unit(ti-tp);
+      rp=rp-2*dot(u2,rp)*u2;
+      R[i]=rmf(p,unit(rp),unit(ti));
+    } else
+      R[i]=R[i-1];
   }
-  return true;
+  return R;
 }
-bool vperiodic(real[][] a) {
-  int n=a.length;
-  if(n == 0) return false;
-  int m=a[0].length-1;
-  for(int i=0; i < n; ++i) {
-    real[] ai=a[i];
-    real epsilon=sqrtEpsilon*norm(ai);
-    if(abs(ai[0]-ai[m]) > epsilon) return false;
-  }
-  return true;
-}
 
-// return the surface described by a parametric function f evaluated at u and v
-// and interpolated with usplinetype and vsplinetype.
-surface surface(triple f(pair z), real[] u, real[] v,
-                splinetype[] usplinetype, splinetype[] vsplinetype=Spline,
-                bool cond(pair z)=null)
+surface tube(triple z0, triple c0, triple c1, triple z1, real w)
 {
-  int nu=u.length-1;
-  int nv=v.length-1;
-  real[] ipt=sequence(u.length);
-  real[] jpt=sequence(v.length);
-  real[][] fx=new real[u.length][v.length];
-  real[][] fy=new real[u.length][v.length];
-  real[][] fz=new real[u.length][v.length];
+  surface s;
+  static real[] T={0,1/3,2/3,1};
+  rmf[] rmf=rmf(z0,c0,c1,z1,T);
 
-  bool[][] active;
-  bool all=cond == null;
-  if(!all) active=new bool[u.length][v.length];
+  real aw=a*w;
+  triple[] arc={(w,0,0),(w,aw,0),(aw,w,0),(0,w,0)};
+  triple[] g={z0,c0,c1,z1};
 
-  for(int i=0; i <= nu; ++i) {
-    real ui=u[i];
-    real[] fxi=fx[i];
-    real[] fyi=fy[i];
-    real[] fzi=fz[i];
-    bool[] activei=all ? null : active[i];
-    for(int j=0; j <= nv; ++j) {
-      pair z=(ui,v[j]);
-      if(!all) activei[j]=cond(z);
-      triple f=f(z);
-      fxi[j]=f.x;
-      fyi[j]=f.y;
-      fzi[j]=f.z;
+  void f(transform3 R) {
+    triple[][] P=new triple[4][];
+    for(int i=0; i < 4; ++i) {
+      transform3 T=shift(g[i])*rmf[i].transform()*R;
+      P[i]=new triple[] {T*arc[0],T*arc[1],T*arc[2],T*arc[3]};
     }
+    s.push(patch(P,copy=false));
   }
 
-  if(usplinetype.length == 0) {
-    usplinetype=new splinetype[] {uperiodic(fx) ? periodic : notaknot,
-                                  uperiodic(fy) ? periodic : notaknot,
-                                  uperiodic(fz) ? periodic : notaknot};
-  } else if(usplinetype.length != 3) abort("usplinetype must have length 3");
+  f(identity4);
+  f(t1);
+  f(t2);
+  f(t3);
 
-  if(vsplinetype.length == 0) {
-    vsplinetype=new splinetype[] {vperiodic(fx) ? periodic : notaknot,
-                                  vperiodic(fy) ? periodic : notaknot,
-                                  vperiodic(fz) ? periodic : notaknot};
-  } else if(vsplinetype.length != 3) abort("vsplinetype must have length 3");
-  
-  real[][][] sx=bispline(fx,ipt,jpt,usplinetype[0],vsplinetype[0],active);
-  real[][][] sy=bispline(fy,ipt,jpt,usplinetype[1],vsplinetype[1],active);
-  real[][][] sz=bispline(fz,ipt,jpt,usplinetype[2],vsplinetype[2],active);
-
-  surface s=surface(sx.length);
-  s.index=new int[nu][nv];
-  int k=-1;
-  for(int i=0; i < nu; ++i) {
-    int[] indexi=s.index[i];
-    for(int j=0; j < nv; ++j)
-      indexi[j]=++k;
-  }
-
-  for(int k=0; k < sx.length; ++k) {
-    triple[][] Q=new triple[4][];
-    real[][] Px=sx[k];
-    real[][] Py=sy[k];
-    real[][] Pz=sz[k];
-    for(int i=0; i < 4 ; ++i) {
-      real[] Pxi=Px[i];
-      real[] Pyi=Py[i];
-      real[] Pzi=Pz[i];
-      Q[i]=new triple[] {(Pxi[0],Pyi[0],Pzi[0]),
-                         (Pxi[1],Pyi[1],Pzi[1]),
-                         (Pxi[2],Pyi[2],Pzi[2]),
-                         (Pxi[3],Pyi[3],Pzi[3])};
-    }
-    s.s[k]=patch(Q);
-  }
-
-  if(usplinetype[0] == periodic && usplinetype[1] == periodic &&
-     usplinetype[1] == periodic) s.ucyclic(true);
-
-  if(vsplinetype[0] == periodic && vsplinetype[1] == periodic &&
-     vsplinetype[1] == periodic) s.vcyclic(true);
-  
+  s.PRCprimitive=false;
+  s.draw=new void(frame f, transform3 t=identity4, material[] m,
+                  light light=currentlight, render render=defaultrender)
+    {
+     material m=material(m[0],light);
+     drawTube(f,t*g,w,m.p,m.opacity,m.shininess,m.metallic,m.fresnel0,
+              t*min(s),t*max(s),m.opacity == 1);
+    };
   return s;
 }
 
-path3 interp(path3 a, path3 b, real t) 
-{
-  int n=size(a);
-  return path3(sequence(new triple(int i) {
-        return interp(precontrol(a,i),precontrol(b,i),t);},n),
-    sequence(new triple(int i) {return interp(point(a,i),point(b,i),t);},n),
-    sequence(new triple(int i) {return interp(postcontrol(a,i),
-                                              postcontrol(b,i),t);},n),
-    sequence(new bool(int i) {return straight(a,i) && straight(b,i);},n),
-    cyclic(a) && cyclic(b));
+real tubethreshold=20;
+
+// Note: casting an array of surfaces to a single surface will disable
+// primitive compression.
+surface operator cast(surface[] s) {
+  surface S;
+  for(surface p : s)
+    S.append(p);
+  return S;
 }
 
 struct tube
 {
-  surface s;
+  surface[] s;
   path3 center; // tube axis
 
   void Null(transform3) {}
   void Null(transform3, bool) {}
   
-  void operator init(path3 p, real width, render render=defaultrender,
-                     void cylinder(transform3)=Null,
-                     void sphere(transform3, bool half)=Null,
-                     void pipe(path3, path3)=null) {
+  surface[] render(path3 g, real r) {
+    triple z0=point(g,0);
+    triple c0=postcontrol(g,0);
+    triple c1=precontrol(g,1);
+    triple z1=point(g,1);
+    real norm=sqrtEpsilon*max(abs(z0),abs(c0),abs(c1),abs(z1));
+    surface[] s;
+    void Split(triple z0, triple c0, triple c1, triple z1,
+               real depth=mantissaBits) {
+      if(depth > 0) {
+        pair threshold(triple z0, triple c0, triple c1) {
+          triple u=c1-z0;
+          triple v=c0-z0;
+          real x=abs(v);
+          return (x,abs(u*x^2-dot(u,v)*v));
+        }
+
+        pair a0=threshold(z0,c0,c1);
+        pair a1=threshold(z1,c1,c0);
+        real rL=r*arclength(z0,c0,c1,z1)*tubethreshold;
+        if((a0.x >= norm && rL*a0.y^2 > a0.x^8) || 
+           (a1.x >= norm && rL*a1.y^2 > a1.x^8)) {
+          triple m0=0.5*(z0+c0);
+          triple m1=0.5*(c0+c1);
+          triple m2=0.5*(c1+z1);
+          triple m3=0.5*(m0+m1);
+          triple m4=0.5*(m1+m2);
+          triple m5=0.5*(m3+m4);
+          --depth;
+          Split(z0,m0,m3,m5,depth);
+          Split(m5,m4,m2,z1,depth);
+          return;
+        }
+      }
+
+      s.push(tube(z0,c0,c1,z1,r));
+    }
+    Split(z0,c0,c1,z1);
+    return s;
+  }
+
+  void operator init(path3 p, real width) {
+    center=p;
     real r=0.5*width;
 
     void generate(path3 p) {
       int n=length(p);
-      if(piecewisestraight(p)) {
-        for(int i=0; i < n; ++i) {
+      for(int i=0; i < n; ++i) {
+        if(straight(p,i)) {
           triple v=point(p,i);
           triple u=point(p,i+1)-v;
           transform3 t=shift(v)*align(unit(u))*scale(r,r,abs(u));
-          s.append(t*unitcylinder);
-          cylinder(t);
-        }
-        center=center&p;
-      } else {
-        real[] T;
-        path3 G;
-        for(int i=0; i < n; ++i)
-          render(subpath(p,i,i+1),
-                 new void(path3 g, real s) {
-                   G=G&g;
-                   T.push(i+s);
-                 },render);
-        T.push(n);
-        T.cyclic=cyclic(p);
-        rmf[] rmf=rmf(p,T);
-        triple f(pair t) {
-          rmf R=rmf[round(t.x)];
-          int n=round(t.y);
-          static real[] x={1,0,-1,0};
-          static real[] y={0,1,0,-1};
-          return point(G,t.x)+r*(R.r*x[n]-R.s*y[n]);
-        }
-
-        static real[] v={0,1,2,3,0};
-        static real[] circular(real[] x, real[] y) {
-          static real a=8/3*(sqrt(2)-1);
-          return a*periodic(x,y);
-        }
-        
-        static splinetype[] Monotonic={monotonic,monotonic,monotonic};
-        static splinetype[] Circular={circular,circular,circular};
-        if(T.length > 0) {
-          surface S=surface(f,sequence(T.length),v,Monotonic,Circular);
-          s.append(S);
-
-          // Compute center of tube:
-          int n=S.index.length;
-          if(T.cyclic) --n;
-          triple[] pre=new triple[n+1];
-          triple[] point=new triple[n+1];
-          triple[] post=new triple[n+1];
-
-          int[] index=S.index[0];
-          triple Point;
-          for(int m=0; m < 4; ++m)
-            Point += S.s[index[m]].P[0][0];
-          pre[0]=point[0]=0.25*Point;
-            
-          for(int i=0; i < n; ++i) {
-            index=S.index[i];
-            triple Pre,Point,Post;
-            for(int m=0; m < 4; ++m) {
-              triple [][] P=S.s[index[m]].P;
-              Post += P[1][0];
-              Pre += P[2][0];
-              Point += P[3][0];
-            }
-            post[i]=0.25*Post;
-            pre[i+1]=0.25*Pre;
-            point[i+1]=0.25*Point;
-
-          }
-
-          index=S.index[n-1];
-          triple Post;
-          for(int m=0; m < 4; ++m)
-            Post += S.s[index[m]].P[3][0];
-          post[n]=0.25*Post;
-
-          bool[] b=array(n+1,false);
-          path3 Center=path3(pre,point,post,b,T.cyclic);
-          center=center&Center;
-
-          if(pipe != null) { // Compute path along tube
-            triple[] pre=new triple[n+1];
-            triple[] point=new triple[n+1];
-            triple[] post=new triple[n+1];
-            pre[0]=point[0]=S.s[S.index[0][0]].P[0][0];
-            for(int i=0; i < n; ++i) {
-              triple [][] P=S.s[S.index[i][0]].P;
-              post[i]=P[1][0];
-              pre[i+1]=P[2][0];
-              point[i+1]=P[3][0];
-            }
-            post[n]=S.s[S.index[n-1][0]].P[3][0];
-            pipe(Center,path3(pre,point,post,b,T.cyclic));
-          }
-        }
+          // Draw opaque surfaces with core for better small-scale rendering.
+          surface unittube=t*unitcylinder;
+          unittube.draw=unitcylinderDraw(core=true);
+          s.push(unittube);
+        } else
+          s.append(render(subpath(p,i,i+1),r));
       }
     }
     
@@ -416,11 +218,11 @@
         generate(subpath(p,begin,i));
         triple dir=dir(p,i,-1);
         transform3 T=t*align(dir);
-        s.append(shift(point(p,i))*T*(dir != O ? unithemisphere : unitsphere));
-        sphere(shift(point(center,length(center)))*T,
-               half=straight(p,i-1) && straight(p,i));
+        s.push(shift(point(p,i))*T*(straight(p,i-1) && straight(p,i) ?
+                                    unithemisphere : unitsphere));
         begin=i;
       }
-    generate(subpath(p,begin,n));
+    path3 g=subpath(p,begin,n);
+    generate(g);
   }
 }

Modified: trunk/Build/source/utils/asymptote/base/tube.asy
===================================================================
--- trunk/Build/source/utils/asymptote/base/tube.asy	2020-03-03 22:33:26 UTC (rev 54033)
+++ trunk/Build/source/utils/asymptote/base/tube.asy	2020-03-03 22:35:09 UTC (rev 54034)
@@ -9,6 +9,33 @@
 
 import three;
 
+real tubegranularity=1e-7;
+
+void render(path3 s, real r, void f(path3, real))
+{
+  void Split(triple z0, triple c0, triple c1, triple z1, real t0=0, real t1=1,
+             real depth=mantissaBits) {
+    if(depth > 0) {
+      real S=straightness(z0,c0,c1,z1);
+      if(S > max(tubegranularity*max(abs(z0),abs(c0),abs(c1),abs(z1)))) {
+        --depth;
+        triple m0=0.5*(z0+c0);
+        triple m1=0.5*(c0+c1);
+        triple m2=0.5*(c1+z1);
+        triple m3=0.5*(m0+m1);
+        triple m4=0.5*(m1+m2);
+        triple m5=0.5*(m3+m4);
+        real tm=0.5*(t0+t1);
+        Split(z0,m0,m3,m5,t0,tm,depth);
+        Split(m5,m4,m2,z1,tm,t1,depth);
+        return;
+      }
+    }
+    f(z0..controls c0 and c1..z1,t0);
+  }
+  Split(point(s,0),postcontrol(s,0),precontrol(s,1),point(s,1));
+}
+
 // A 3D version of roundedpath(path, real).
 path3 roundedpath(path3 A, real r)
 {
@@ -42,13 +69,8 @@
   real[] t;
   int n=length(g);
   if(relstep <= 0) {
-    for(int i=0; i < n; ++i) {
-      real S=straightness(g,i);
-      if(S < sqrtEpsilon*r)
-	t.push(i);
-      else
-        render(subpath(g,i,i+1),new void(path3, real s) {t.push(i+s);});
-    }
+    for(int i=0; i < n; ++i)
+      render(subpath(g,i,i+1),r,new void(path3, real s) {t.push(i+s);});
     t.push(n);
   } else {
     int nb=ceil(1/relstep);

Modified: trunk/Build/source/utils/asymptote/base/webgl/asygl.js
===================================================================
--- trunk/Build/source/utils/asymptote/base/webgl/asygl.js	2020-03-03 22:33:26 UTC (rev 54033)
+++ trunk/Build/source/utils/asymptote/base/webgl/asygl.js	2020-03-03 22:35:09 UTC (rev 54034)
@@ -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="\nattribute vec3 position;\n#ifdef WIDTH\nattribute float width;\n#endif\n#ifdef NORMAL\nattribute vec3 normal;\n#endif\nattribute float materialIndex;\n#ifdef COLOR\nattribute vec4 color;\n#endif\n\nuniform mat3 normMat;\nuniform mat4 viewMat;\nuniform mat4 projViewMat;\n\n#ifdef NORMAL\n#ifndef ORTHOGRAPHIC\nvarying vec3 ViewPosition;\n#endif\nvarying vec3 Normal;\n#endif\nvarying vec4 diffuse;\nvarying vec3 specular;\nvarying float roughness,metallic,fresnel0;\nvarying vec4 emissive;\n\nstruct Material {\n  vec4 diffuse,emissive,specular;\n  vec4 parameters;\n};\n\nuniform Material Materials[Nmaterials];\n\nvoid main(void)\n{\n  vec4 v=vec4(position,1.0);\n  gl_Position=projViewMat*v;\n#ifdef NORMAL\n#ifndef ORTHOGRAPHIC\n  ViewPosition=(viewMat*v).xyz;\n#endif      \n  Normal=normal*normMat;\n        \n  Material m;\n#ifdef TRANSPARENT\n  m=Materials[int(abs(materialIndex))-1];\n  if(materialIndex >= 0.0) {\n    diffuse=m.diffuse;\n    emissive=m.emissive;\n  } else {\n    diffuse=color;\n#if nlights > 0\n    emissive=vec4(0.0);\n#else\n    emissive=color;\n#endif\n  }\n#else\n  m=Materials[int(materialIndex)];\n#ifdef COLOR\n  diffuse=color;\n#if nlights > 0\n  emissive=vec4(0.0);\n#else\n  emissive=color;\n#endif\n#else\n  diffuse=m.diffuse;\n  emissive=m.emissive;\n#endif\n#endif\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\n#ifdef WIDTH\n  gl_PointSize=width;\n#endif\n}\n",fragment="\n#ifdef NORMAL\n#ifndef ORTHOGRAPHIC\nvarying vec3 ViewPosition;\n#endif\nvarying vec3 Normal;\nvarying vec4 diffuse;\nvarying vec3 specular;\nvarying float roughness,metallic,fresnel0;\n\nfloat Roughness2;\nvec3 normal;\n\nstruct Light {\n  vec3 direction;\n  vec3 color;\n};\n\nuniform Light Lights[Nlights];\n\nfloat NDF_TRG(vec3 h)\n{\n  float ndoth=max(dot(normal,h),0.0);\n  float alpha2=Roughness2*Roughness2;\n  float denom=ndoth*ndot!
 h*(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 omegali=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*omegali;\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\nvarying vec4 emissive;\n    \nvoid main(void)\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  Roughness2=roughness*roughness;\n  vec3 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  gl_FragColor=vec4(color,diffuse.a);\n#else\n  gl_FragColor=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 se!
 lf?self:this,function(){return function(e){var t={};function i(a){if(t[a])return t[a].exports;var r=t[a]={i:a,l:!1,exports:{}};return e[a].call(r.exports,r,r.exports,i),r.l=!0,r.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*r},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 r=Math.PI/180},function(e,t,i){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.mat4=t.mat3=void 0;var a=n(i(2)),r=n(i(3));function n(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=r},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],r=t[2],n=t[3],s=t[4],o=t[5],l=t[6],h=t[7],c=t[8],d=c*s-o*h,m=-c*n+o*l,f=h*n-s*l,u=i*d+a*m+r*f;if(!u)return null;return u=1/u,e[0]=d*u,e[1]=(-c*a+r*h)*u,e[2]=(o*a-r*s)*u,e[3]=m*u,e[4]=(c*i-r*l)*u,e[5]=(-o*i+r*n)*u,e[6]=f*u,e[7]=(-h*i+a*l)*u,e[8]=(s*i-a*n)*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=functi!
 on(){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],r=t[2],n=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],v=t[13],p=t[14],g=t[15],x=i*o-a*s,M=i*l-r*s,w=i*h-n*s,b=a*l-r*o,A=a*h-n*o,S=r*h-n*l,R=c*v-d*u,D=c*p-m*u,P=c*g-f*u,T=d*p-m*v,y=d*g-f*v,z=m*g-f*p,I=x*z-M*y+w*T+b*P-A*D+S*R;if(!I)return null;return I=1/I,e[0]=(o*z-l*y+h*T)*I,e[1]=(r*y-a*z-n*T)*I,e[2]=(v*S-p*A+g*b)*I,e[3]=(m*A-d*S-f*b)*I,e[4]=(l*P-s*z-h*D)*I,e[5]=(i*z-r*P+n*D)*I,e[6]=(p*w-u*S-g*M)*I,e[7]=(c*S-m*w+f*M)*I,e[8]=(s*y-o*P+h*R)*I,e[9]=(a*P-i*y-n*R)*I,e[10]=(u*A-v*w+g*x)*I,e[11]=(d*w-c*A-f*x)*I,e[12]=(o*D-s*T-l*R)*I,e[13]=(i*T-a*D+r*R)*I,e[14]=(v*M-u*b-p*x)*I,e[15]=(c*b-d*M+m*x)*I,e},t.multiply=r,t.translate=function(e,t,i){var a=i[0],r=i[1],n=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,v=void 0,p=void 0,g=void 0;t===e?(e[12]=t[0]*a+t[4]*r+t[8]*n+t[12],e[13]=t[1]*a+t[5]*r+t[9]*n+t[13],e[14]=t[2]*a+t[6]*r+t[10]*n+t[14],e[15]=t[3]*a+t[7]*r+t[11]*n+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],v=t[9],p=t[10],g=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]=v,e[10]=p,e[11]=g,e[12]=s*a+c*r+u*n+t[12],e[13]=o*a+d*r+v*n+t[13],e[14]=l*a+m*r+p*n+t[14],e[15]=h*a+f*r+g*n+t[15]);return e},t.rotate=function(e,t,i,r){var n=r[0],s=r[1],o=r[2],l=Math.sqrt(n*n+s*s+o*o),h=void 0,c=void 0,d=void 0,m=void 0,f=void 0,u=void 0,v=void 0,p=void 0,g=void 0,x=void 0,M=void 0,w=void 0,b=void 0,A=void 0,S=void 0,R=void 0,D=void 0,P=void 0,T=void 0,y=void 0,z=void 0,I=void 0,E=void 0,O=void 0;if(Math.abs(l)<a.EPSILON)return null;n*=l=1/l,s*=l,o*=l,h=Math.sin(i),c=Math.cos(i),d=1-c,m=t[0],f=t[1],u=t[2],v=t[3],p=t[4],g=t[5],x=t[6],M=t[7],w=t[8],b=t[9],A=t[10],S=t[11],R=n*!
 n*d+c,D=s*n*d+o*h,P=o*n*d-s*h,T=n*s*d-o*h,y=s*s*d+c,z=o*s*d+n*h,I=n*o*d+s*h,E=s*o*d-n*h,O=o*o*d+c,e[0]=m*R+p*D+w*P,e[1]=f*R+g*D+b*P,e[2]=u*R+x*D+A*P,e[3]=v*R+M*D+S*P,e[4]=m*T+p*y+w*z,e[5]=f*T+g*y+b*z,e[6]=u*T+x*y+A*z,e[7]=v*T+M*y+S*z,e[8]=m*I+p*E+w*O,e[9]=f*I+g*E+b*O,e[10]=u*I+x*E+A*O,e[11]=v*I+M*E+S*O,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 r=i[0],n=i[1],s=i[2],o=Math.sqrt(r*r+n*n+s*s),l=void 0,h=void 0,c=void 0;if(Math.abs(o)<a.EPSILON)return null;return r*=o=1/o,n*=o,s*=o,l=Math.sin(t),h=Math.cos(t),c=1-h,e[0]=r*r*c+h,e[1]=n*r*c+s*l,e[2]=s*r*c-n*l,e[3]=0,e[4]=r*n*c-s*l,e[5]=n*n*c+h,e[6]=s*n*c+r*l,e[7]=0,e[8]=r*s*c+n*l,e[9]=n*s*c-r*l,e[10]=s*s*c+h,e[11]=0,e[12]=0,e[13]=0,e[14]=0,e[15]=1,e},t.frustum=function(e,t,i,a,r,n,s){var o=1/(i-t),l=1/(r-a),h=1/(n-s);return e[0]=2*n*o,e[1]=0,e[2]=0,e[3]=0,e[4]=0,e[5]=2*n*l,e[6]=0,e[7]=0,e[8]=(i+t)*o,e[9]=(r+a)*l,e[10]=(s+n)*h,e[11]=-1,e[12]=0,e[13]=0,e[14]=s*n*2*h,e[15]=0,e},t.ortho=function(e,t,i,a,r,n,s){var o=1/(t-i),l=1/(a-r),h=1/(n-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]=(r+a)*l,e[14]=(s+n)*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 r(e,t,i){var a=t[0],r=t[1],n=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],v=t[12],p=t[13],g=t[14],x=t[15],M=i[0],w=i[1],b=i[2],A=i[3];return e[0]=M*a+w*o+b*d+A*v,e[1]=M*r+w*l+b*m+A*p,e[2]=M*n+w*h+b*f+A*g,e[3]=M*s+w*c+b*u+A*x,M=i[4],w=i[5],b=i[6],A=i[7],e[4]=M*a+w*o+b*d+A*v,e[5]=M*r+w*l+b*m+A*p,e[6]=M*n+w*h+b*f+A*g,e[7]=M*s+w*c+b*u+A*x,M=i[8],w=i[9],b=i[10],A=i[11],e[8]=M*a+w*o+b*d+A*v,e[9]=M*r+w*l+b*m+A*p,e[10]=M*n+w*h+b*f+A*g,e[11]=M*s+w*c+b*u+A*x,M=i[12],w=i[13]!
 ,b=i[14],A=i[15],e[12]=M*a+w*o+b*d+A*v,e[13]=M*r+w*l+b*m+A*p,e[14]=M*n+w*h+b*f+A*g,e[15]=M*s+w*c+b*u+A*x,e}}])});let canvasWidth,canvasHeight,b,B,angle,Zoom0,viewportmargin,zoomFactor,zoomPinchFactor,zoomPinchCap,zoomStep,shiftHoldDistance,shiftWaitTime,vibrateTime,embedded,canvas,gl,alpha,offscreen,context,maxMaterials,halfCanvasWidth,halfCanvasHeight,Zoom,P=[],Materials=[],Lights=[],Centers=[],Background=[1,1,1,1],absolute=!1,viewportshift=[0,0],nlights=0,Nmaterials=2,materials=[],pixel=.75,BezierFactor=.4,FillFactor=.1,maxViewportWidth=window.innerWidth,maxViewportHeight=window.innerHeight;const windowTrim=10;let lastzoom,H,zmin,zmax,size2,ArcballFactor,positionBuffer,materialBuffer,colorBuffer,indexBuffer,resizeStep=1.2,Fuzz2=1e3*Number.EPSILON,Fuzz4=Fuzz2*Fuzz2,third=1/3,rotMat=mat4.create(),projMat=mat4.create(),viewMat=mat4.create(),projViewMat=mat4.create(),normMat=mat3.create(),viewMat3=mat3.create(),rotMats=mat4.create(),cjMatInv=mat4.create(),translMat=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,mouseDownOrTouchActive=!1,lastMouseX=null,lastMouseY=null,touchID=null,Positions=[],Normals=[],Colors=[],Indices=[];class Material{constructor(e,t,i,a,r,n){this.diffuse=e,this.emissive=t,this.specular=i,this.shininess=a,this.metallic=r,this.fresnel0=n}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,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(){let e=gl.getParameter(gl.MAX_VERTEX_UNIFORM_VECTOR!
 S);maxMaterials=Math.floor((e-14)/4),Nmaterials=Math.min(Math.max(Nmaterials,Materials.length),maxMaterials),noNormalShader=initShader(),pixelShader=initShader(["WIDTH"]),materialShader=initShader(["NORMAL"]),colorShader=initShader(["NORMAL","COLOR"]),transparentShader=initShader(["NORMAL","COLOR","TRANSPARENT"])}function setBuffers(){positionBuffer=gl.createBuffer(),materialBuffer=gl.createBuffer(),colorBuffer=gl.createBuffer(),indexBuffer=gl.createBuffer()}function noGL(){gl||alert("Could not initialize WebGL")}function saveAttributes(){let e=window.top.document.asygl[alpha];e.gl=gl,e.nlights=Lights.length,e.Nmaterials=Nmaterials,e.maxMaterials=maxMaterials,e.noNormalShader=noNormalShader,e.pixelShader=pixelShader,e.materialShader=materialShader,e.colorShader=colorShader,e.transparentShader=transparentShader}function restoreAttributes(){let e=window.top.document.asygl[alpha];gl=e.gl,nlights=e.nlights,Nmaterials=e.Nmaterials,maxMaterials=e.maxMaterials,noNormalShader=e.noNormalShader,pixelShader=e.pixelShader,materialShader=e.materialShader,colorShader=e.colorShader,transparentShader=e.transparentShader}function initGL(){if(alpha=Background[3]<1,embedded){let e=window.top.document;null==e.asygl&&(e.asygl=Array(2)),context=canvas.getContext("2d"),(offscreen=e.offscreen)||(offscreen=e.createElement("canvas"),e.offscreen=offscreen),e.asygl[alpha]&&e.asygl[alpha].gl?(restoreAttributes(),(Lights.length!=nlights||Math.min(Materials.length,maxMaterials)>Nmaterials)&&(initShaders(),saveAttributes())):((gl=offscreen.getContext("webgl",{alpha:alpha}))||noGL(),initShaders(),e.asygl[alpha]={},saveAttributes())}else(gl=canvas.getContext("webgl",{alpha:alpha}))||noGL(),initShaders();setBuffers(),indexExt=gl.getExtension("OES_element_index_uint")}function getShader(e,t,i,a=[]){let r=`#version 100\n#ifdef GL_FRAGMENT_PRECISION_HIGH\n  precision highp float;\n#else\n  precision mediump float;\n#endif\n  #define nlights ${Lights.length}\n\n  const int Nlights=${Math.max(Lights.length,1)};\n\n  #define Nmaterials ${Nmaterials}\n`!
 ;orthographic&&(r+="#define ORTHOGRAPHIC\n"),a.forEach(e=>r+="#define "+e+"\n");let n=e.createShader(i);return e.shaderSource(n,r+t),e.compileShader(n),e.getShaderParameter(n,e.COMPILE_STATUS)?n:(alert(e.getShaderInfoLog(n)),null)}function drawBuffer(e,t,i=e.indices){if(0==e.indices.length)return;let a=t==pixelShader,r=t!=noNormalShader&&!a;setUniforms(e,t),gl.bindBuffer(gl.ARRAY_BUFFER,positionBuffer),gl.bufferData(gl.ARRAY_BUFFER,new Float32Array(e.vertices),gl.STATIC_DRAW),gl.vertexAttribPointer(positionAttribute,3,gl.FLOAT,!1,r?24:a?16:12,0),r&&Lights.length>0?gl.vertexAttribPointer(normalAttribute,3,gl.FLOAT,!1,24,12):a&&gl.vertexAttribPointer(widthAttribute,1,gl.FLOAT,!1,16,12),gl.bindBuffer(gl.ARRAY_BUFFER,materialBuffer),gl.bufferData(gl.ARRAY_BUFFER,new Int16Array(e.materialIndices),gl.STATIC_DRAW),gl.vertexAttribPointer(materialAttribute,1,gl.SHORT,!1,2,0),t!=colorShader&&t!=transparentShader||(gl.bindBuffer(gl.ARRAY_BUFFER,colorBuffer),gl.bufferData(gl.ARRAY_BUFFER,new Uint8Array(e.colors),gl.STATIC_DRAW),gl.vertexAttribPointer(colorAttribute,4,gl.UNSIGNED_BYTE,!0,0,0)),gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER,indexBuffer),gl.bufferData(gl.ELEMENT_ARRAY_BUFFER,indexExt?new Uint32Array(i):new Uint16Array(i),gl.STATIC_DRAW),gl.drawElements(r?gl.TRIANGLES:a?gl.POINTS:gl.LINES,i.length,indexExt?gl.UNSIGNED_INT:gl.UNSIGNED_SHORT,0)}class vertexBuffer{constructor(){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++}vertex1(e){return this.vertices.push(e[0]),this.vertices.push(e[1]),this.vertices.push(e[2]),this.materialIndices.push(materialIndex),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 r=6*e;this.vertices[r]=t[0],this.vertices[r+1]=t[1],this.vertices[r+2]=t[2],this.vertices[r+3]=i[0],this.vertices[r+4]=i[1],this.vertices[r+5]=i[2],this.materialIndices[e]=materialIndex;let n=4*e;this.colors[n]=a[0],this.colors[n+1]=a[1],this.colors[n+2]=a[2],this.colors[n+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}}let materialIndex,material0Data=new vertexBuffer,material1Data=new vertexBuffer,materialData=new vertexBuffer,colorData=new vertexBuffer,transparentData=new vertexBuffer,triangleData=new vertexBuffer;function append(e,t){let i=e.length,a=t.length;e.length+=a;for(let r=0;r<a;++r)e[i+r]=t[r]}function appendOffset(e,t,i){let a=e.length,r=t.length;e.length+=t.length;for(let n=0;n<r;++n)e[a+n]=t[n]+i}class Geometry{constructor(){this.data=new vertexBuffer,this.Onscreen=!1,this.m=[]}offscreen(e){let t=projViewMat,i=e[0],a=i[0],r=i[1],n=i[2],s=1/(t[3]*a+t[7]*r+t[11]*n+t[15]);this.x=this.X=(t[0]*a+t[4]*r+t[8]*n+t[12])*s,this.y=this.Y=(t[1]*a+t[5]*r+t[9]*n+t[13])*s;for(let i=1,a=e.length;i<a;++i){let a=e[i],r=a[0],n=a[1],s=a[2],o=1/(t[3]*r+t[7]*n+t[11]*s+t[15]),l=(t[0]*r+t[4]*n+t[8]*s+t[12])*o,h=(t[1]*r+t[5]*n+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],r=e[0]-t,n=e[1]-i,s=e[2]-a;return[r*normMat[0]+n*normMat[3]+s*normMat[6]+t,r*normMat[1]+n*normMat[4]!
 +s*normMat[7]+i,r*normMat[2]+n*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&&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 void this.data.clear();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]/B[2],r=pixel*Math.hypot(a*(viewParam.xmax-viewParam.xmin),a*(viewParam.ymax-viewParam.ymin))/size2;this.res2=r*r,this.Epsilon=FillFactor*r,this.data.clear(),this.Onscreen=!0,this.process(t)}}class BezierPatch extends Geometry{constructor(e,t,i,a,r,n){super(),this.controlpoints=e,this.Min=a,this.Max=r,this.color=n,this.CenterIndex=t;let s=e.length;if(n){let e=n[0][3]+n[1][3]+n[2][3];this.transparent=16==s||4==s?e+n[3][3]<1020:e<765}else this.transparent=Materials[i].diffuse[3]<1;this.MaterialIndex=i,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*=Fuzz4}processTriangle(e){let t=e[0],i=e[1],a=e[2],r=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]]));this.offscreen([t,i!
 ,a])||(this.color?(this.data.indices.push(this.data.Vertex(t,r,this.color[0])),this.data.indices.push(this.data.Vertex(i,r,this.color[1])),this.data.indices.push(this.data.Vertex(a,r,this.color[2]))):(this.data.indices.push(this.vertex(t,r)),this.data.indices.push(this.vertex(i,r)),this.data.indices.push(this.vertex(a,r))),this.append())}processQuad(e){let t=e[0],i=e[1],a=e[2],r=e[3],n=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]-r[0],a[1]-r[1],a[2]-r[2]],[r[0]-t[0],r[1]-t[1],r[2]-t[2]]),o=unit([n[0]+s[0],n[1]+s[1],n[2]+s[2]]);if(!this.offscreen([t,i,a,r])){let e,n,s,l;this.color?(e=this.data.Vertex(t,o,this.color[0]),n=this.data.Vertex(i,o,this.color[1]),s=this.data.Vertex(a,o,this.color[2]),l=this.data.Vertex(r,o,this.color[3])):(e=this.vertex(t,o),n=this.vertex(i,o),s=this.vertex(a,o),l=this.vertex(r,o)),this.data.indices.push(e),this.data.indices.push(n),this.data.indices.push(s),this.data.indices.push(e),this.data.indices.push(s),this.data.indices.push(l),this.append()}}process(e){if(this.transparent&&(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);let t=e[0],i=e[3],a=e[12],r=e[15],n=this.normal(i,e[2],e[1],t,e[4],e[8],a);iszero(n)&&iszero(n=this.normal(i,e[2],e[1],t,e[13],e[14],r))&&(n=this.normal(r,e[11],e[7],i,e[4],e[8],a));let s=this.normal(t,e[4],e[8],a,e[13],e[14],r);iszero(s)&&iszero(s=this.normal(t,e[4],e[8],a,e[11],e[7],i))&&(s=this.normal(i,e[2],e[1],t,e[13],e[14],r));let o=this.normal(a,e[13],e[14],r,e[11],e[7],i);iszero(o)&&iszero(o=this.normal(a,e[13],e[14],r,e[2],e[1],t))&&(o=this.normal(t,e[4],e[8],a,e[11],e[7],i));let l=this.normal(r,e[11],e[7],i,e[2],e[1],t);if(iszero(l)&&iszero(l=this.normal(r,e[11],e[7],i,e[4],e[8],a))&&(l=this.normal(a,e[13],e[14],r,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,n,h),u=this.data.Vertex(a,s,c),v=this.data.Vertex(r,!
 o,d),p=this.data.Vertex(i,l,m);this.Render(e,f,u,v,p,t,a,r,i,!1,!1,!1,!1,h,c,d,m)}else{let h=this.vertex(t,n),c=this.vertex(a,s),d=this.vertex(r,o),m=this.vertex(i,l);this.Render(e,h,c,d,m,t,a,r,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)}Render(e,t,i,a,r,n,s,o,l,h,c,d,m,f,u,v,p){if(this.Distance(e)<this.res2)this.offscreen([n,s,o])||(this.data.indices.push(t),this.data.indices.push(i),this.data.indices.push(a)),this.offscreen([n,o,l])||(this.data.indices.push(t),this.data.indices.push(a),this.data.indices.push(r));else{if(this.offscreen(e))return;let g=e[0],x=e[3],M=e[12],w=e[15],b=new Split3(g,e[1],e[2],x),A=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],w),D=new Split3(g,e[4],e[8],M),P=new Split3(b.m0,A.m0,S.m0,R.m0),T=new Split3(b.m3,A.m3,S.m3,R.m3),y=new Split3(b.m5,A.m5,S.m5,R.m5),z=new Split3(b.m4,A.m4,S.m4,R.m4),I=new Split3(b.m2,A.m2,S.m2,R.m2),E=new Split3(x,e[7],e[11],w),O=[g,b.m0,b.m3,b.m5,D.m0,P.m0,T.m0,y.m0,D.m3,P.m3,T.m3,y.m3,D.m5,P.m5,T.m5,y.m5],_=[D.m5,P.m5,T.m5,y.m5,D.m4,P.m4,T.m4,y.m4,D.m2,P.m2,T.m2,y.m2,M,R.m0,R.m3,R.m5],L=[y.m5,z.m5,I.m5,E.m5,y.m4,z.m4,I.m4,E.m4,y.m2,z.m2,I.m2,E.m2,R.m5,R.m4,R.m2,w],N=[b.m5,b.m4,b.m2,x,y.m0,z.m0,I.m0,E.m0,y.m3,z.m3,I.m3,E.m3,y.m5,z.m5,I.m5,E.m5],B=O[15],C=this.normal(O[0],O[4],O[8],O[12],O[13],O[14],O[15]);iszero(C)&&iszero(C=this.normal(O[0],O[4],O[8],O[12],O[11],O[7],O[3]))&&(C=this.normal(O[3],O[2],O[1],O[0],O[13],O[14],O[15]));let F=this.normal(_[12],_[13],_[14],_[15],_[11],_[7],_[3]);iszero(F)&&iszero(F=this.normal(_[12],_[13],_[14],_[15],_[2],_[1],_[0]))&&(F=this.normal(_[0],_[4],_[8],_[12],_[11],_[7],_[3]));let V=this.normal(L[15],L[11],L[7],L[3],L[2],L[1],L[0]);iszero(V)&&iszero(V=this.normal(L[15],L[11],L[7],L[3],L[4],L[8],L[12]))&&(V=this.normal(L[12],L[13],L[14],L[15],L[2],L[1],L[0]));let H=this.normal(N[3],N[2],N[1],N[0],N[4],N[8],N[12]);iszero(H)&&iszero(H=t!
 his.normal(N[3],N[2],N[1],N[0],N[13],N[14],N[15]))&&(H=this.normal(N[15],N[11],N[7],N[3],N[4],N[8],N[12]));let G=this.normal(L[3],L[2],L[1],B,L[4],L[8],L[12]),U=this.Epsilon,W=[.5*(n[0]+s[0]),.5*(n[1]+s[1]),.5*(n[2]+s[2])];if(!h)if(h=Straightness(g,e[4],e[8],M)<this.res2){let e=unit(this.derivative(_[0],_[1],_[2],_[3]));W=[W[0]-U*e[0],W[1]-U*e[1],W[2]-U*e[2]]}else W=O[12];let Y=[.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],w)<this.res2){let e=unit(this.derivative(L[12],L[8],L[4],L[0]));Y=[Y[0]-U*e[0],Y[1]-U*e[1],Y[2]-U*e[2]]}else Y=_[15];let j=[.5*(o[0]+l[0]),.5*(o[1]+l[1]),.5*(o[2]+l[2])];if(!d)if(d=Straightness(w,e[11],e[7],x)<this.res2){let e=unit(this.derivative(N[15],L[14],L[13],_[12]));j=[j[0]-U*e[0],j[1]-U*e[1],j[2]-U*e[2]]}else j=L[3];let k=[.5*(l[0]+n[0]),.5*(l[1]+n[1]),.5*(l[2]+n[2])];if(!m)if(m=Straightness(g,e[1],e[2],x)<this.res2){let e=unit(this.derivative(O[3],O[7],O[11],O[15]));k=[k[0]-U*e[0],k[1]-U*e[1],k[2]-U*e[2]]}else k=N[0];if(f){let e=Array(4),g=Array(4),x=Array(4),M=Array(4),w=Array(4);for(let t=0;t<4;++t)e[t]=.5*(f[t]+u[t]),g[t]=.5*(u[t]+v[t]),x[t]=.5*(v[t]+p[t]),M[t]=.5*(p[t]+f[t]),w[t]=.5*(e[t]+x[t]);let b=this.data.Vertex(W,C,e),A=this.data.Vertex(Y,F,g),S=this.data.Vertex(j,V,x),R=this.data.Vertex(k,H,M),D=this.data.Vertex(B,G,w);this.Render(O,t,b,D,R,n,W,B,k,h,!1,!1,m,f,e,w,M),this.Render(_,b,i,A,D,W,s,Y,B,h,c,!1,!1,e,u,g,w),this.Render(L,D,A,a,S,B,Y,o,j,!1,c,d,!1,w,g,v,x),this.Render(N,R,D,S,r,k,B,j,l,!1,!1,d,m,M,w,x,p)}else{let e=this.vertex(W,C),f=this.vertex(Y,F),u=this.vertex(j,V),v=this.vertex(k,H),p=this.vertex(B,G);this.Render(O,t,e,p,v,n,W,B,k,h,!1,!1,m),this.Render(_,e,i,f,p,W,s,Y,B,h,c,!1,!1),this.Render(L,p,f,a,u,B,Y,o,j,!1,c,d,!1),this.Render(N,v,p,u,r,k,B,j,l,!1,!1,d,m)}}}process3(e){this.Res2=BezierFactor*BezierFactor*this.res2;let t=e[0],i=e[6],a=e[9],r=this.normal(a,e[5],e[2],t,e[1],e[3],i),n=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,r,o),d=this.data.Vertex(i,n,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,r),l=this.vertex(i,n),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,r,n,s,o,l,h,c,d,m){if(this.Distance3(e)<this.Res2)this.offscreen([r,n,s])||(this.data.indices.push(t),this.data.indices.push(i),this.data.indices.push(a));else{if(this.offscreen(e))return;let f=e[0],u=e[1],v=e[2],p=e[3],g=e[4],x=e[5],M=e[6],w=e[7],b=e[8],A=e[9],S=[.5*(A[0]+x[0]),.5*(A[1]+x[1]),.5*(A[2]+x[2])],R=[.5*(A[0]+b[0]),.5*(A[1]+b[1]),.5*(A[2]+b[2])],D=[.5*(x[0]+v[0]),.5*(x[1]+v[1]),.5*(x[2]+v[2])],P=[.5*(b[0]+g[0]),.5*(b[1]+g[1]),.5*(b[2]+g[2])],T=[.5*(b[0]+w[0]),.5*(b[1]+w[1]),.5*(b[2]+w[2])],y=[.5*(v[0]+g[0]),.5*(v[1]+g[1]),.5*(v[2]+g[2])],z=[.5*(v[0]+f[0]),.5*(v[1]+f[1]),.5*(v[2]+f[2])],I=[.5*(g[0]+p[0]),.5*(g[1]+p[1]),.5*(g[2]+p[2])],E=[.5*(w[0]+M[0]),.5*(w[1]+M[1]),.5*(w[2]+M[2])],O=[.5*(f[0]+u[0]),.5*(f[1]+u[1]),.5*(f[2]+u[2])],_=[.5*(u[0]+p[0]),.5*(u[1]+p[1]),.5*(u[2]+p[2])],L=[.5*(p[0]+M[0]),.5*(p[1]+M[1]),.5*(p[2]+M[2])],N=[.5*(S[0]+D[0]),.5*(S[1]+D[1]),.5*(S[2]+D[2])],B=[.5*(R[0]+T[0]),.5*(R[1]+T[1]),.5*(R[2]+T[2])],C=[.5*(D[0]+z[0]),.5*(D[1]+z[1]),.5*(D[2]+z[2])],F=[.5*P[0]+.25*(g[0]+u[0]),.5*P[1]+.25*(g[1]+u[1]),.5*P[2]+.25*(g[2]+u[2])],V=[.5*(T[0]+E[0]),.5*(T[1]+E[1]),.5*(T[2]+E[2])],H=[.5*y[0]+.25*(g[0]+w[0]),.5*y[1]+.25*(g[1]+w[1]),.5*y[2]+.25*(g[2]+w[2])],G=[.25*(x[0]+g[0])+.5*I[0],.25*(x[1]+g[1])+.5*I[1],.25*(x[2]+g[2])+.5*I[2]],U=[.5*(O[0]+_[0]),.5*(O[1]+_[1]),.5*(O[2]+_[2])],W=[.5*(_[0]+L[0]),.5*(_[1]+L[1]),.5*(_[2]+L[2])],Y=[.5*(H[0]+U[0]),.5*(H[1]+U[1]),.5*(H[2]+U[2])],j=[.5*(H[0]+W[0]),.5*(H[1]+W[1]),.5*(H[2]+W[2])],k=[.5*(U[0]+W[0]),.5*(U[1]+W[1]),.5*(U[2]+W[2])],Z=[.5*(G[0]+V[0]),.5*(G[1]+V[1]),.5*(G[2]+V[2])],X=[.5*(B[0]+G[0]),.5*(B[1]+G[1]),.5*(B[2]+G[2])],q=[.5*(B[0]+V[0]),.5*(B[1]+V[1]),.5*(B[2]+V[2])],K=[.5*(N[0]+F[0]),.5*(N[1]+F[1]),.5*(N[2]+F[2])],$=[.5*(C[0]+F[0]),.5*(C[1]+F[1]),.5*(C[2]!
 +F[2])],Q=[.5*(N[0]+C[0]),.5*(N[1]+C[1]),.5*(N[2]+C[2])],J=[f,O,z,U,[.5*(y[0]+O[0]),.5*(y[1]+O[1]),.5*(y[2]+O[2])],C,k,Y,$,Q],ee=[k,W,j,L,[.5*(I[0]+E[0]),.5*(I[1]+E[1]),.5*(I[2]+E[2])],Z,M,E,V,q],te=[Q,K,N,X,[.5*(S[0]+P[0]),.5*(S[1]+P[1]),.5*(S[2]+P[2])],S,q,B,R,A],ie=[q,X,Z,K,[.25*(D[0]+T[0]+_[0]+g[0]),.25*(D[1]+T[1]+_[1]+g[1]),.25*(D[2]+T[2]+_[2]+g[2])],j,Q,$,Y,k],ae=this.normal(k,j,Z,q,X,K,Q),re=this.normal(q,X,K,Q,$,Y,k),ne=this.normal(Q,$,Y,k,j,Z,q),se=this.Epsilon,oe=[.5*(n[0]+s[0]),.5*(n[1]+s[1]),.5*(n[2]+s[2])];if(!o)if(o=Straightness(M,w,b,A)<this.res2){let e=unit(this.sumderivative(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]+r[0]),.5*(s[1]+r[1]),.5*(s[2]+r[2])];if(!l)if(l=Straightness(f,v,x,A)<this.res2){let e=unit(this.sumderivative(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*(r[0]+n[0]),.5*(r[1]+n[1]),.5*(r[2]+n[2])];if(!h)if(h=Straightness(f,u,p,M)<this.res2){let e=unit(this.sumderivative(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=k;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 v=this.data.Vertex(oe,ae,e),p=this.data.Vertex(le,re,f),g=this.data.Vertex(he,ne,u);this.Render3(J,t,g,p,r,he,le,!1,l,h,c,u,f),this.Render3(ee,g,i,v,he,n,oe,o,!1,h,u,d,e),this.Render3(te,p,v,a,le,oe,s,o,l,!1,f,e,m),this.Render3(ie,v,p,g,oe,le,he,!1,!1,!1,e,f,u)}else{let e=this.vertex(oe,ae),c=this.vertex(le,re),d=this.vertex(he,ne);this.Render3(J,t,d,c,r,he,le,!1,l,h),this.Render3(ee,d,i,e,he,n,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],r=e[15],n=Distance2(r,t,this.normal(i,e[2],e[1],t,e[4],e[8],a));return n=Math.max(n,Straightness(t,e[1],e[2],i)),n=Math.max(n,Straightness(t,e[4],e[8],a)),n=Math.max(n,Straightness(i,e[7],e[11],r)),n=Math.max(n,Straightness(a,e[13],e[!
 14],r)),n=Math.max(n,Straightness(e[4],e[5],e[6],e[7])),n=Math.max(n,Straightness(e[8],e[9],e[10],e[11])),n=Math.max(n,Straightness(e[1],e[5],e[9],e[13])),Math.max(n,Straightness(e[2],e[6],e[10],e[14]))}Distance3(e){let t=e[0],i=e[4],a=e[6],r=e[9],n=abs2([(t[0]+a[0]+r[0])*third-i[0],(t[1]+a[1]+r[1])*third-i[1],(t[2]+a[2]+r[2])*third-i[2]]);return n=Math.max(n,Straightness(t,e[1],e[3],a)),n=Math.max(n,Straightness(t,e[2],e[5],r)),Math.max(n,Straightness(a,e[7],e[8],r))}derivative(e,t,i,a){let r=[t[0]-e[0],t[1]-e[1],t[2]-e[2]];if(abs2(r)>this.epsilon)return r;let n=bezierPP(e,t,i);return abs2(n)>this.epsilon?n:bezierPPP(e,t,i,a)}sumderivative(e,t,i,a,r,n,s){let o=this.derivative(e,t,i,a),l=this.derivative(e,r,n,s);return[o[0]+l[0],o[1]+l[1],o[2]+l[2]]}normal(e,t,i,a,r,n,s){let o=r[0]-a[0],l=r[1]-a[1],h=r[2]-a[2],c=i[0]-a[0],d=i[1]-a[1],m=i[2]-a[2],f=[l*m-h*d,h*c-o*m,o*d-l*c];if(abs2(f)>this.epsilon)return unit(f);let u=[c,d,m],v=[o,l,h],p=bezierPP(a,i,t),g=bezierPP(a,r,n),x=cross(g,u),M=cross(v,p);if(abs2(f=[x[0]+M[0],x[1]+M[1],x[2]+M[2]])>this.epsilon)return unit(f);let w=bezierPPP(a,i,t,e),b=bezierPPP(a,r,n,s);x=cross(g,p),M=cross(v,w);let A=cross(b,u),S=cross(b,p),R=cross(g,w),D=cross(b,w);return unit([9*x[0]+3*(M[0]+A[0]+S[0]+R[0])+D[0],9*x[1]+3*(M[1]+A[1]+S[1]+R[1])+D[1],9*x[2]+3*(M[2]+A[2]+S[2]+R[2])+D[2]])}}class BezierCurve extends Geometry{constructor(e,t,i,a,r){super(),this.controlpoints=e,this.Min=a,this.Max=r,this.CenterIndex=t,this.MaterialIndex=i}setMaterialIndex(){this.setMaterial(material1Data,drawMaterial1)}processLine(e){let t=e[0],i=e[1];this.offscreen([t,i])||(this.data.indices.push(this.data.vertex1(t)),this.data.indices.push(this.data.vertex1(i)),this.append())}process(e){if(2==e.length)return this.processLine(e);let t=this.data.vertex1(e[0]),i=this.data.vertex1(e[3]);this.Render(e,t,i),this.data.indices.length>0&&this.append()}append(){material1Data.append(this.data)}Render(e,t,i){let a=e[0],r=e[1],n=e[2],s=e[3];if(Straightness(a,r,n,s)<this.res2)this.offscreen([a,s])||(this.data.indices.pus!
 h(t),this.data.indices.push(i));else{if(this.offscreen(e))return;let o=[.5*(a[0]+r[0]),.5*(a[1]+r[1]),.5*(a[2]+r[2])],l=[.5*(r[0]+n[0]),.5*(r[1]+n[1]),.5*(r[2]+n[2])],h=[.5*(n[0]+s[0]),.5*(n[1]+s[1]),.5*(n[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],v=this.data.vertex1(m);this.Render(f,t,v),this.Render(u,v,i)}}}class Pixel extends Geometry{constructor(e,t,i,a,r){super(),this.controlpoint=e,this.width=t,this.CenterIndex=0,this.MaterialIndex=i,this.Min=a,this.Max=r}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)}}class Triangles extends Geometry{constructor(e,t,i){super(),this.CenterIndex=0,this.MaterialIndex=e,this.Min=t,this.Max=i,this.Positions=Positions,this.Normals=Normals,this.Colors=Colors,this.Indices=Indices,Positions=[],Normals=[],Colors=[],Indices=[],this.transparent=Materials[e].diffuse[3]<1}setMaterialIndex(){this.transparent?this.setMaterial(transparentData,drawTransparent):this.setMaterial(triangleData,drawTriangle)}process(e){materialIndex=this.Colors.length>0?-1-materialIndex:1+materialIndex;for(let e=0,t=this.Indices.length;e<t;++e){let t=this.Indices[e],i=t[0],a=this.Positions[i[0]],r=this.Positions[i[1]],n=this.Positions[i[2]];if(!this.offscreen([a,r,n])){let e=t.length>1?t[1]:i;if(e&&0!=e.length||(e=i),this.Colors.length>0){let s=t.length>2?t[2]:i;s&&0!=s.length||(s=i);let o=this.Colors[s[0]],l=this.Colors[s[1]],h=this.Colors[s[2]];this.transparent|=o[3]+l[3]+h[3]<765,this.data.iVertex(i[0],a,this.Normals[e[0]],o),this.data.iVertex(i[1],r,this.Normals[e[1]],l),this.data.iVertex(i[2],n,this.Normals[e[2]],h)}else this.data.iVertex(i[0],a,this.Normals[e[0]]),this.data.iVertex(i[1],r,this.Normals[e[1]]),this.data.iVertex(i[2],n,this.Normals[e[2]])}}this.data.nvertices=this.Positions.length,this.data.indices.len!
 gth>0&&this.append()}append(){this.transparent?transparentData.append(this.data):triangleData.append(this.data)}}function home(){mat4.identity(rotMat),initProjection(),setProjection(),remesh=!0,draw()}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.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 r=.5*(t[0]+i[0]),n=.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]+r),.5*(this.m0[1]+n),.5*(this.m0[2]+s)],this.m4=[.5*(r+this.m2[0]),.5*(n+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 iszero(e){return 0==e[0]&&0==e[1]&&0==e[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 bezierPP(e,t,i){return[e[0]+i[0]-2*t[0],e[1]+i[1]-2*t[1],e[2]+i[2]-2*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 Straightness(e,t,i,a){let r=[third*(a[0]-e[0]),third*(a[1]-e[1]),third*(a[2]-e[2])];return Math.max(abs2([t[0]-r[0]-e[0],t[1]-r[1]-e[1],t[2]-r[2]-e[2]]),abs2([a[0]-r[0]-i[0],a[1]-r[1]-i[1],a[2]-r[2]-i[2]]))}function Distance2(e,t,i){l!
 et a=dot([e[0]-t[0],e[1]-t[1],e[2]-t[2]],i);return a*a}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 COBTarget(e,t){mat4.fromTranslation(translMat,[center.x,center.y,center.z]),mat4.invert(cjMatInv,translMat),mat4.multiply(e,t,cjMatInv),mat4.multiply(e,translMat,e)}function setUniforms(e,t){let i=t==pixelShader;gl.useProgram(t),gl.enableVertexAttribArray(positionAttribute),i&&gl.enableVertexAttribArray(widthAttribute);let a=t!=noNormalShader&&!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,r){if(e==i&&t==a)return;let[n,s]=arcball([e,-t],[i,-a]);mat4.fromRotation(rotMats,2*r*ArcballFactor*n/lastzoom,s),mat4.multiply(rotMat,rotMats,r!
 otMat)}function shiftScene(e,t,i,a){let r=1/lastzoom;shift.x+=(i-e)*r*halfCanvasWidth,shift.y-=(a-t)*r*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),Zoom!=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),r=dot(i,a);return r>1?r=1:r<-1&&(r=-1),[Math.acos(r),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 r;switch(i){case DRAGMODE_ROTATE:r=rotateScene;break;case DRAGMODE_SHIFT:r=shiftScene;break;case DRAGMODE_ZOOM:r=zoomScene;break;case DRAGMODE_PAN:r=panScene;break;default:r=((e,t,i,a)=>{})}r((lastMouseX-halfCanvasWidth)/halfCanvasWidth,(lastMouseY-halfCanvasHeight)/halfCanvasHeight,(e-halfCanvasWidth)/halfCanvasWidth,(t-halfCanvasHeight)/halfCanvasHeight,a),lastMouseX=e,lastMouseY=t,setProjection(),draw()}let zoomEnabled=0;function enableZoom(){zoomEnabled=1,canvas.addEventListener("wheel",handleMouseWheel,!1)}function disableZoom(){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"+":case"=":case">":expand();break;case"-":case"_":case"<":shrink()}t.length>0&&(mat4.rotate(rotMat,rotMat,.1,t),updateViewMatrix(),draw())}function handleMouseWheel(e){e.preventDefault(),e.deltaY<0?Zoom*=zoomFactor:Zoom/=zoomFactor,capzoom(),setProjection(),draw()}function handleMouseMove(e){if(!mouseDownOrTouchActive)return;let t;processDrag(e.clientX,e.clientY,t=e.getModifierState("Control")?DRAGMODE_SHIFT:e.getModifierState("Shift")?DRAGMODE_ZOOM:e.getModifierState("Alt")?DRAGMODE_PAN:DRAGMODE_ROTATE)}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,r=i-lastMouseY,n=a*a+r*r<=shiftHoldDistance*shiftHoldDistance;if(n&&!swipe&&!rotate&&(new Date).getTime()-touchStartTime>shiftWaitTime&&(navigator.vibrate&&window.navigator.vibrate(vibrateTime),swipe=!0),swipe)processDrag(e,i,DRAGMODE_SHIFT);else if(!n){rotate=!0,processDrag(t[0].pageX,t[0].pageY,DRAGMODE_ROTATE,.5)}}if(pinch&&!swipe&&2==t.length&&touchId==t[0].identifier){let e=pinchDistance(t),i=e-pinchStart;zooming=!0,(i*=zoomPinchFactor)>zoomPinchCap&&(i=zoomPinchCap),i<-zoomPinchCap&&(i=-zoomPinchCap),zoomImage(i/size2),pinchStart=e,swipe=rotate=zooming=!1,setProjection(),draw()}}let pixelShader,noNormalShader,materialShader,colorShader,transparentShader,zbuffer=[];function transformVertices(e){let t=viewMat[2],i=viewMat[6],a=viewMat[10];zbuffer.length=e.length;for(let r=0;r<e.length;++r){let n=6*r;zbuffer[r]=t*e[n]+i*e[n+1]+a*e[n+2]}}function drawMaterial0(){drawBuffer(material0Data,pixelShader),material0Data.clear()}function drawMaterial1(){drawBuffer(material1Data,noNormalShader),material1Data.clear()}function drawMaterial(){drawBuffer(materialData,materialShader),materialData.clear()}function drawColor(){drawBuffer(colorData,colorShader),colorData.clear()}function drawTriangle(){drawBuffer(triangleData,transparentShader),triangleData.clear()}function drawTransparent(){let e=transparentD!
 ata.indices;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 r=3*i;return IA=e[r],IB=e[r+1],IC=e[r+2],zbuffer[Ia]+zbuffer[Ib]+zbuffer[Ic]<zbuffer[IA]+zbuffer[IB]+zbuffer[IC]?-1:1});let a=Array(e.length);for(let r=0;r<t;++r){let t=3*i[r];a[3*r]=e[t],a[3*r+1]=e[t+1],a[3*r+2]=e[t+2]}gl.depthMask(!1),drawBuffer(transparentData,transparentShader,a),gl.depthMask(!0)}transparentData.clear()}function drawBuffers(){drawMaterial0(),drawMaterial1(),drawMaterial(),drawColor(),drawTriangle(),drawTransparent()}function draw(){embedded&&(offscreen.width=canvas.width,offscreen.height=canvas.height,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,canvas.width,canvas.height),context.drawImage(offscreen,0,0)),remesh=!1}function setDimensions(e,t,i,a){let r=e/t,n=1/lastzoom,s=(i/e+viewportshift[0])*lastzoom,o=(a/t+viewportshift[1])*lastzoom;if(orthographic){let e=B[0]-b[0],t=B[1]-b[1];if(e<t*r){let e=.5*t*r*n,i=2*e*s,a=t*n*o;viewParam.xmin=-e-i,viewParam.xmax=e-i,viewParam.ymin=b[1]*n-a,viewParam.ymax=B[1]*n-a}else{let t=.5*e/(r*Zoom),i=e*n*s,a=2*t*o;viewParam.xmin=b[0]*n-i,viewParam.xmax=B[0]*n-i,viewParam.ymin=-t-a,viewParam.ymax=t-a}}else{let e=H*n,t=e*r,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*angle)*B[2],center.x=center.y=0,center.z=.5*(b[2]+B[2]),lastzoom=Zoom=Zoom0,viewParam.zmin=b[2],viewParam.zmax=B[2],shift.x=shift.y=0}function setViewport(){gl.viewportWidth=canvasWidth,gl.viewportHeight=canvasHeight,g!
 l.viewport(0,0,gl.viewportWidth,gl.viewportHeight),gl.scissor(0,0,gl.viewportWidth,gl.viewportHeight)}function setCanvas(){canvas.width=canvasWidth,canvas.height=canvasHeight,embedded&&(offscreen.width=canvasWidth,offscreen.height=canvasHeight),size2=Math.hypot(canvasWidth,canvasHeight),halfCanvasWidth=.5*canvasWidth,halfCanvasHeight=.5*canvasHeight}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(),home()}function expand(){setsize(canvasWidth*resizeStep+.5,canvasHeight*resizeStep+.5)}function shrink(){setsize(Math.max(canvasWidth/resizeStep+.5,1),Math.max(canvasHeight/resizeStep+.5,1))}function webGLStart(){if(canvas=document.getElementById("Asymptote"),embedded=window.top.document!=document,initGL(),absolute&&!embedded)canvasWidth*=window.devicePixelRatio,canvasHeight*=window.devicePixelRatio;else{canvas.width=Math.max(window.innerWidth-windowTrim,windowTrim),canvas.height=Math.max(window.innerHeight-windowTrim,windowTrim);let e=canvasWidth/canvasHeight;canvas.width>canvas.height*e?canvas.width=Math.min(canvas.height*e,canvas.width):canvas.height=Math.min(canvas.width/e,canvas.height),canvas.width>0&&(canvasWidth=canvas.width),canvas.height>0&&(canvasHeight=canvas.height)}setCanvas(),ArcballFactor=1+8*Math.hypot(viewportmargin[0],viewportmargin[1])/size2,viewportshift[0]/=Zoom0,viewportshift[1]/=Zoom0,gl.enable(gl.BLEND),gl.blendFunc(gl.SRC_ALPHA,gl.ONE_MINUS_SRC_ALPHA),gl.enable(gl.DEPTH_TEST),gl.enable(gl.SCISSOR_TEST),setViewport(),home(),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),canva!
 s.addEventListener("touchmove",handleTouchMove,!1),document.addEventListener("keydown",handleKey,!1)}
+let vertex="\nattribute vec3 position;\n#ifdef WIDTH\nattribute float width;\n#endif\n#ifdef NORMAL\nattribute vec3 normal;\n#endif\nattribute float materialIndex;\n#ifdef COLOR\nattribute vec4 color;\n#endif\n\nuniform mat3 normMat;\nuniform mat4 viewMat;\nuniform mat4 projViewMat;\n\n#ifdef NORMAL\n#ifndef ORTHOGRAPHIC\nvarying vec3 ViewPosition;\n#endif\nvarying vec3 Normal;\n#endif\nvarying vec4 diffuse;\nvarying vec3 specular;\nvarying float roughness,metallic,fresnel0;\nvarying vec4 emissive;\n\nstruct Material {\n  vec4 diffuse,emissive,specular;\n  vec4 parameters;\n};\n\nuniform Material Materials[Nmaterials];\n\nvoid main(void)\n{\n  vec4 v=vec4(position,1.0);\n  gl_Position=projViewMat*v;\n#ifdef NORMAL\n#ifndef ORTHOGRAPHIC\n  ViewPosition=(viewMat*v).xyz;\n#endif      \n  Normal=normalize(normal*normMat);\n        \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\n#endif\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\n#ifdef WIDTH\n  gl_PointSize=width;\n#endif\n}\n",fragment="\n#ifdef NORMAL\n#ifndef ORTHOGRAPHIC\nvarying vec3 ViewPosition;\n#endif\nvarying vec3 Normal;\nvarying vec4 diffuse;\nvarying vec3 specular;\nvarying float roughness,metallic,fresnel0;\n\nfloat Roughness2;\nvec3 normal;\n\nstruct Light {\n  vec3 direction;\n  vec3 color;\n};\n\nuniform Light Lights[Nlights];\n\nfloat NDF_TRG(vec3 h)\n{\n  float ndoth=max(dot(normal,h),0.0);\n  float alpha2=Roughness2*Roughness2;\n  float 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 omegali=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*omegali;\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\nvarying vec4 emissive;\n    \nvoid main(void)\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  Roughness2=roughness*roughness;\n  vec3 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  gl_FragColor=vec4(color,diffuse.a);\n#else\n  gl_FragColor=emissive;\n#endif\n}\n";!function(t,e){if("object"==typeof exports&&"object"==typeof module)module.exports=e();else if("function"==typeof define&&define.amd)define([],e);else{var i=e();for(var a in i)("object"==typeof exports?exports:t)[a]=i[a]}}("undefined"!=typeof self?self:this,function(){return function(t){!
 var e={};function i(a){if(e[a])return e[a].exports;var r=e[a]={i:a,l:!1,exports:{}};return t[a].call(r.exports,r,r.exports,i),r.l=!0,r.exports}return i.m=t,i.c=e,i.d=function(t,e,a){i.o(t,e)||Object.defineProperty(t,e,{configurable:!1,enumerable:!0,get:a})},i.n=function(t){var e=t&&t.__esModule?function(){return t.default}:function(){return t};return i.d(e,"a",e),e},i.o=function(t,e){return Object.prototype.hasOwnProperty.call(t,e)},i.p="",i(i.s=1)}([function(t,e,i){"use strict";Object.defineProperty(e,"__esModule",{value:!0}),e.setMatrixArrayType=function(t){e.ARRAY_TYPE=t},e.toRadian=function(t){return t*r},e.equals=function(t,e){return Math.abs(t-e)<=a*Math.max(1,Math.abs(t),Math.abs(e))};var a=e.EPSILON=1e-6;e.ARRAY_TYPE="undefined"!=typeof Float32Array?Float32Array:Array,e.RANDOM=Math.random;var r=Math.PI/180},function(t,e,i){"use strict";Object.defineProperty(e,"__esModule",{value:!0}),e.mat4=e.mat3=void 0;var a=n(i(2)),r=n(i(3));function n(t){if(t&&t.__esModule)return t;var e={};if(null!=t)for(var i in t)Object.prototype.hasOwnProperty.call(t,i)&&(e[i]=t[i]);return e.default=t,e}e.mat3=a,e.mat4=r},function(t,e,i){"use strict";Object.defineProperty(e,"__esModule",{value:!0}),e.create=function(){var t=new a.ARRAY_TYPE(9);return t[0]=1,t[1]=0,t[2]=0,t[3]=0,t[4]=1,t[5]=0,t[6]=0,t[7]=0,t[8]=1,t},e.fromMat4=function(t,e){return t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[4],t[4]=e[5],t[5]=e[6],t[6]=e[8],t[7]=e[9],t[8]=e[10],t},e.invert=function(t,e){var i=e[0],a=e[1],r=e[2],n=e[3],s=e[4],o=e[5],h=e[6],l=e[7],d=e[8],c=d*s-o*l,m=-d*n+o*h,f=l*n-s*h,u=i*c+a*m+r*f;if(!u)return null;return u=1/u,t[0]=c*u,t[1]=(-d*a+r*l)*u,t[2]=(o*a-r*s)*u,t[3]=m*u,t[4]=(d*i-r*h)*u,t[5]=(-o*i+r*n)*u,t[6]=f*u,t[7]=(-l*i+a*h)*u,t[8]=(s*i-a*n)*u,t};var a=function(t){if(t&&t.__esModule)return t;var e={};if(null!=t)for(var i in t)Object.prototype.hasOwnProperty.call(t,i)&&(e[i]=t[i]);return e.default=t,e}(i(0))},function(t,e,i){"use strict";Object.defineProperty(e,"__esModule",{value:!0}),e.create=function(){var t=new a.ARRAY_TYPE(16);return t[0]!
 =1,t[1]=0,t[2]=0,t[3]=0,t[4]=0,t[5]=1,t[6]=0,t[7]=0,t[8]=0,t[9]=0,t[10]=1,t[11]=0,t[12]=0,t[13]=0,t[14]=0,t[15]=1,t},e.identity=function(t){return t[0]=1,t[1]=0,t[2]=0,t[3]=0,t[4]=0,t[5]=1,t[6]=0,t[7]=0,t[8]=0,t[9]=0,t[10]=1,t[11]=0,t[12]=0,t[13]=0,t[14]=0,t[15]=1,t},e.invert=function(t,e){var i=e[0],a=e[1],r=e[2],n=e[3],s=e[4],o=e[5],h=e[6],l=e[7],d=e[8],c=e[9],m=e[10],f=e[11],u=e[12],p=e[13],v=e[14],g=e[15],w=i*o-a*s,x=i*h-r*s,M=i*l-n*s,b=a*h-r*o,A=a*l-n*o,S=r*l-n*h,P=d*p-c*u,R=d*v-m*u,T=d*g-f*u,y=c*v-m*p,D=c*g-f*p,I=m*g-f*v,z=w*I-x*D+M*y+b*T-A*R+S*P;if(!z)return null;return z=1/z,t[0]=(o*I-h*D+l*y)*z,t[1]=(r*D-a*I-n*y)*z,t[2]=(p*S-v*A+g*b)*z,t[3]=(m*A-c*S-f*b)*z,t[4]=(h*T-s*I-l*R)*z,t[5]=(i*I-r*T+n*R)*z,t[6]=(v*M-u*S-g*x)*z,t[7]=(d*S-m*M+f*x)*z,t[8]=(s*D-o*T+l*P)*z,t[9]=(a*T-i*D-n*P)*z,t[10]=(u*A-p*M+g*w)*z,t[11]=(c*M-d*A-f*w)*z,t[12]=(o*R-s*y-h*P)*z,t[13]=(i*y-a*R+r*P)*z,t[14]=(p*x-u*b-v*w)*z,t[15]=(d*b-c*x+m*w)*z,t},e.multiply=r,e.translate=function(t,e,i){var a=i[0],r=i[1],n=i[2],s=void 0,o=void 0,h=void 0,l=void 0,d=void 0,c=void 0,m=void 0,f=void 0,u=void 0,p=void 0,v=void 0,g=void 0;e===t?(t[12]=e[0]*a+e[4]*r+e[8]*n+e[12],t[13]=e[1]*a+e[5]*r+e[9]*n+e[13],t[14]=e[2]*a+e[6]*r+e[10]*n+e[14],t[15]=e[3]*a+e[7]*r+e[11]*n+e[15]):(s=e[0],o=e[1],h=e[2],l=e[3],d=e[4],c=e[5],m=e[6],f=e[7],u=e[8],p=e[9],v=e[10],g=e[11],t[0]=s,t[1]=o,t[2]=h,t[3]=l,t[4]=d,t[5]=c,t[6]=m,t[7]=f,t[8]=u,t[9]=p,t[10]=v,t[11]=g,t[12]=s*a+d*r+u*n+e[12],t[13]=o*a+c*r+p*n+e[13],t[14]=h*a+m*r+v*n+e[14],t[15]=l*a+f*r+g*n+e[15]);return t},e.rotate=function(t,e,i,r){var n=r[0],s=r[1],o=r[2],h=Math.sqrt(n*n+s*s+o*o),l=void 0,d=void 0,c=void 0,m=void 0,f=void 0,u=void 0,p=void 0,v=void 0,g=void 0,w=void 0,x=void 0,M=void 0,b=void 0,A=void 0,S=void 0,P=void 0,R=void 0,T=void 0,y=void 0,D=void 0,I=void 0,z=void 0,E=void 0,O=void 0;if(Math.abs(h)<a.EPSILON)return null;n*=h=1/h,s*=h,o*=h,l=Math.sin(i),d=Math.cos(i),c=1-d,m=e[0],f=e[1],u=e[2],p=e[3],v=e[4],g=e[5],w=e[6],x=e[7],M=e[8],b=e[9],A=e[10],S=e[11],P=n*n*c+d,R=s*n*c+o*l,T=o*n*c-s*l,y=n*s*c-o*l,D!
 =s*s*c+d,I=o*s*c+n*l,z=n*o*c+s*l,E=s*o*c-n*l,O=o*o*c+d,t[0]=m*P+v*R+M*T,t[1]=f*P+g*R+b*T,t[2]=u*P+w*R+A*T,t[3]=p*P+x*R+S*T,t[4]=m*y+v*D+M*I,t[5]=f*y+g*D+b*I,t[6]=u*y+w*D+A*I,t[7]=p*y+x*D+S*I,t[8]=m*z+v*E+M*O,t[9]=f*z+g*E+b*O,t[10]=u*z+w*E+A*O,t[11]=p*z+x*E+S*O,e!==t&&(t[12]=e[12],t[13]=e[13],t[14]=e[14],t[15]=e[15]);return t},e.fromTranslation=function(t,e){return t[0]=1,t[1]=0,t[2]=0,t[3]=0,t[4]=0,t[5]=1,t[6]=0,t[7]=0,t[8]=0,t[9]=0,t[10]=1,t[11]=0,t[12]=e[0],t[13]=e[1],t[14]=e[2],t[15]=1,t},e.fromRotation=function(t,e,i){var r=i[0],n=i[1],s=i[2],o=Math.sqrt(r*r+n*n+s*s),h=void 0,l=void 0,d=void 0;if(Math.abs(o)<a.EPSILON)return null;return r*=o=1/o,n*=o,s*=o,h=Math.sin(e),l=Math.cos(e),d=1-l,t[0]=r*r*d+l,t[1]=n*r*d+s*h,t[2]=s*r*d-n*h,t[3]=0,t[4]=r*n*d-s*h,t[5]=n*n*d+l,t[6]=s*n*d+r*h,t[7]=0,t[8]=r*s*d+n*h,t[9]=n*s*d-r*h,t[10]=s*s*d+l,t[11]=0,t[12]=0,t[13]=0,t[14]=0,t[15]=1,t},e.frustum=function(t,e,i,a,r,n,s){var o=1/(i-e),h=1/(r-a),l=1/(n-s);return t[0]=2*n*o,t[1]=0,t[2]=0,t[3]=0,t[4]=0,t[5]=2*n*h,t[6]=0,t[7]=0,t[8]=(i+e)*o,t[9]=(r+a)*h,t[10]=(s+n)*l,t[11]=-1,t[12]=0,t[13]=0,t[14]=s*n*2*l,t[15]=0,t},e.ortho=function(t,e,i,a,r,n,s){var o=1/(e-i),h=1/(a-r),l=1/(n-s);return t[0]=-2*o,t[1]=0,t[2]=0,t[3]=0,t[4]=0,t[5]=-2*h,t[6]=0,t[7]=0,t[8]=0,t[9]=0,t[10]=2*l,t[11]=0,t[12]=(e+i)*o,t[13]=(r+a)*h,t[14]=(s+n)*l,t[15]=1,t};var a=function(t){if(t&&t.__esModule)return t;var e={};if(null!=t)for(var i in t)Object.prototype.hasOwnProperty.call(t,i)&&(e[i]=t[i]);return e.default=t,e}(i(0));function r(t,e,i){var a=e[0],r=e[1],n=e[2],s=e[3],o=e[4],h=e[5],l=e[6],d=e[7],c=e[8],m=e[9],f=e[10],u=e[11],p=e[12],v=e[13],g=e[14],w=e[15],x=i[0],M=i[1],b=i[2],A=i[3];return t[0]=x*a+M*o+b*c+A*p,t[1]=x*r+M*h+b*m+A*v,t[2]=x*n+M*l+b*f+A*g,t[3]=x*s+M*d+b*u+A*w,x=i[4],M=i[5],b=i[6],A=i[7],t[4]=x*a+M*o+b*c+A*p,t[5]=x*r+M*h+b*m+A*v,t[6]=x*n+M*l+b*f+A*g,t[7]=x*s+M*d+b*u+A*w,x=i[8],M=i[9],b=i[10],A=i[11],t[8]=x*a+M*o+b*c+A*p,t[9]=x*r+M*h+b*m+A*v,t[10]=x*n+M*l+b*f+A*g,t[11]=x*s+M*d+b*u+A*w,x=i[12],M=i[13],b=i[14],A=i[15],t[12]=x*a+M*o+b*c+A*p,t[13!
 ]=x*r+M*h+b*m+A*v,t[14]=x*n+M*l+b*f+A*g,t[15]=x*s+M*d+b*u+A*w,t}}])});let canvasWidth,canvasHeight,b,B,angle,Zoom0,viewportmargin,zoomFactor,zoomPinchFactor,zoomPinchCap,zoomStep,shiftHoldDistance,shiftWaitTime,vibrateTime,embedded,canvas,gl,alpha,offscreen,context,maxMaterials,halfCanvasWidth,halfCanvasHeight,Zoom,P=[],Materials=[],Lights=[],Centers=[],Background=[1,1,1,1],absolute=!1,viewportshift=[0,0],nlights=0,Nmaterials=2,materials=[],pixel=.75,FillFactor=.1,maxViewportWidth=window.innerWidth,maxViewportHeight=window.innerHeight;const windowTrim=10;let lastzoom,H,zmin,zmax,size2,ArcballFactor,positionBuffer,materialBuffer,colorBuffer,indexBuffer,resizeStep=1.2,third=1/3,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=[];class Material{constructor(t,e,i,a,r,n){this.diffuse=t,this.emissive=e,this.specular=i,this.shininess=a,this.metallic=r,this.fresnel0=n}setUniform(t,e){let i=i=>gl.getUniformLocation(t,"Materials["+e+"]."+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(t,e){this.direction=t,this.color=e}setUniform(t,e){let i=i=>gl.getUniformLocation(t,"Lights["+e+"]."+i);gl.uniform3fv(i("direction"),new Float32Array(this.direction)),gl.uniform3fv(i("color"),new Float32Array(this.color))}}function initShaders(){let t=gl.getParameter(gl.MAX_VERTEX_UNIFORM_VECTORS);maxMaterials=!
 Math.floor((t-14)/4),Nmaterials=Math.min(Math.max(Nmaterials,Materials.length),maxMaterials),pixelShader=initShader(["WIDTH"]),materialShader=initShader(["NORMAL"]),colorShader=initShader(["NORMAL","COLOR"]),transparentShader=initShader(["NORMAL","COLOR","TRANSPARENT"])}function deleteShaders(){gl.deleteProgram(transparentShader),gl.deleteProgram(colorShader),gl.deleteProgram(materialShader),gl.deleteProgram(pixelShader)}function setBuffers(){positionBuffer=gl.createBuffer(),materialBuffer=gl.createBuffer(),colorBuffer=gl.createBuffer(),indexBuffer=gl.createBuffer()}function noGL(){gl||alert("Could not initialize WebGL")}function saveAttributes(){let t=window.top.document.asygl[alpha];t.gl=gl,t.nlights=Lights.length,t.Nmaterials=Nmaterials,t.maxMaterials=maxMaterials,t.pixelShader=pixelShader,t.materialShader=materialShader,t.colorShader=colorShader,t.transparentShader=transparentShader}function restoreAttributes(){let t=window.top.document.asygl[alpha];gl=t.gl,nlights=t.nlights,Nmaterials=t.Nmaterials,maxMaterials=t.maxMaterials,pixelShader=t.pixelShader,materialShader=t.materialShader,colorShader=t.colorShader,transparentShader=t.transparentShader}function initGL(){if(alpha=Background[3]<1,embedded){let t=window.top.document;null==t.asygl&&(t.asygl=Array(2)),context=canvas.getContext("2d"),(offscreen=t.offscreen)||(offscreen=t.createElement("canvas"),t.offscreen=offscreen),t.asygl[alpha]&&t.asygl[alpha].gl?(restoreAttributes(),(Lights.length!=nlights||Math.min(Materials.length,maxMaterials)>Nmaterials)&&(initShaders(),saveAttributes())):((gl=offscreen.getContext("webgl",{alpha:alpha}))||noGL(),initShaders(),t.asygl[alpha]={},saveAttributes())}else(gl=canvas.getContext("webgl",{alpha:alpha}))||noGL(),initShaders();setBuffers(),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 get!
 Shader(t,e,i,a=[]){let r=`#version 100\n#ifdef GL_FRAGMENT_PRECISION_HIGH\n  precision highp float;\n#else\n  precision mediump float;\n#endif\n  #define nlights ${0==wireframe?Lights.length:0}\n\n  const int Nlights=${Math.max(Lights.length,1)};\n\n  #define Nmaterials ${Nmaterials}\n`;orthographic&&(r+="#define ORTHOGRAPHIC\n"),a.forEach(t=>r+="#define "+t+"\n");let n=t.createShader(i);return t.shaderSource(n,r+e),t.compileShader(n),t.getShaderParameter(n,t.COMPILE_STATUS)?n:(alert(t.getShaderInfoLog(n)),null)}function drawBuffer(t,e,i=t.indices){if(0==t.indices.length)return;let a=e!=pixelShader;setUniforms(t,e),gl.bindBuffer(gl.ARRAY_BUFFER,positionBuffer),gl.bufferData(gl.ARRAY_BUFFER,new Float32Array(t.vertices),gl.STATIC_DRAW),gl.vertexAttribPointer(positionAttribute,3,gl.FLOAT,!1,a?24:16,0),a&&Lights.length>0?gl.vertexAttribPointer(normalAttribute,3,gl.FLOAT,!1,24,12):pixel&&gl.vertexAttribPointer(widthAttribute,1,gl.FLOAT,!1,16,12),gl.bindBuffer(gl.ARRAY_BUFFER,materialBuffer),gl.bufferData(gl.ARRAY_BUFFER,new Int16Array(t.materialIndices),gl.STATIC_DRAW),gl.vertexAttribPointer(materialAttribute,1,gl.SHORT,!1,2,0),e!=colorShader&&e!=transparentShader||(gl.bindBuffer(gl.ARRAY_BUFFER,colorBuffer),gl.bufferData(gl.ARRAY_BUFFER,new Uint8Array(t.colors),gl.STATIC_DRAW),gl.vertexAttribPointer(colorAttribute,4,gl.UNSIGNED_BYTE,!0,0,0)),gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER,indexBuffer),gl.bufferData(gl.ELEMENT_ARRAY_BUFFER,indexExt?new Uint32Array(i):new Uint16Array(i),gl.STATIC_DRAW),gl.drawElements(a?wireframe?gl.LINES:t.type:gl.POINTS,i.length,indexExt?gl.UNSIGNED_INT:gl.UNSIGNED_SHORT,0)}class vertexBuffer{constructor(t){this.type=t||TRIANGLES,this.clear()}clear(){this.vertices=[],this.materialIndices=[],this.colors=[],this.indices=[],this.nvertices=0,this.materials=[],this.materialTable=[]}vertex(t,e){return this.vertices.push(t[0]),this.vertices.push(t[1]),this.vertices.push(t[2]),this.vertices.push(e[0]),this.vertices.push(e[1]),this.vertices.push(e[2]),this.materialIndices.push(materialIndex),this.nver!
 tices++}Vertex(t,e,i=[0,0,0,0]){return this.vertices.push(t[0]),this.vertices.push(t[1]),this.vertices.push(t[2]),this.vertices.push(e[0]),this.vertices.push(e[1]),this.vertices.push(e[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(t,e){return this.vertices.push(t[0]),this.vertices.push(t[1]),this.vertices.push(t[2]),this.vertices.push(e),this.materialIndices.push(materialIndex),this.nvertices++}iVertex(t,e,i,a=[0,0,0,0]){let r=6*t;this.vertices[r]=e[0],this.vertices[r+1]=e[1],this.vertices[r+2]=e[2],this.vertices[r+3]=i[0],this.vertices[r+4]=i[1],this.vertices[r+5]=i[2],this.materialIndices[t]=materialIndex;let n=4*t;this.colors[n]=a[0],this.colors[n+1]=a[1],this.colors[n+2]=a[2],this.colors[n+3]=a[3],this.indices.push(t)}append(t){append(this.vertices,t.vertices),append(this.materialIndices,t.materialIndices),append(this.colors,t.colors),appendOffset(this.indices,t.indices,this.nvertices),this.nvertices+=t.nvertices}}function append(t,e){let i=t.length,a=e.length;t.length+=a;for(let r=0;r<a;++r)t[i+r]=e[r]}function appendOffset(t,e,i){let a=t.length,r=e.length;t.length+=e.length;for(let n=0;n<r;++n)t[a+n]=e[n]+i}class Geometry{constructor(){this.data=new vertexBuffer,this.Onscreen=!1,this.m=[]}offscreen(t){let e=projViewMat,i=t[0],a=i[0],r=i[1],n=i[2],s=1/(e[3]*a+e[7]*r+e[11]*n+e[15]);this.x=this.X=(e[0]*a+e[4]*r+e[8]*n+e[12])*s,this.y=this.Y=(e[1]*a+e[5]*r+e[9]*n+e[13])*s;for(let i=1,a=t.length;i<a;++i){let a=t[i],r=a[0],n=a[1],s=a[2],o=1/(e[3]*r+e[7]*n+e[11]*s+e[15]),h=(e[0]*r+e[4]*n+e[8]*s+e[12])*o,l=(e[1]*r+e[5]*n+e[9]*s+e[13])*o;h<this.x?this.x=h:h>this.X&&(this.X=h),l<this.y?this.y=l:l>this.Y&&(this.Y=l)}return(this.X<-1.01||this.x>1.01||this.Y<-1.01||this.y>1.01)&&(this.Onscreen=!1,!0)}T(t){let e=this.c[0],i=this.c[1],a=this.c[2],r=t[0]-e,n=t[1]-i,s=t[2]-a;return[r*normMat[0]+n*normMat[3]+s*normMat[6]+e,r*normMat[1]+n*normMat[4]+s*normMat[7]+i,r*normMat[2]+n*normMat[5]+s*normMat[8]+a]}Tcorn!
 ers(t,e){return[this.T(t),this.T([t[0],t[1],e[2]]),this.T([t[0],e[1],t[2]]),this.T([t[0],e[1],e[2]]),this.T([e[0],t[1],t[2]]),this.T([e[0],t[1],e[2]]),this.T([e[0],e[1],t[2]]),this.T(e)]}setMaterial(t,e){null==t.materialTable[this.MaterialIndex]&&(t.materials.length>=Nmaterials&&e(),t.materialTable[this.MaterialIndex]=t.materials.length,t.materials.push(Materials[this.MaterialIndex])),materialIndex=t.materialTable[this.MaterialIndex]}render(){let t;if(this.setMaterialIndex(),0==this.CenterIndex?t=corners(this.Min,this.Max):(this.c=Centers[this.CenterIndex-1],t=this.Tcorners(this.Min,this.Max)),this.offscreen(t))return void this.data.clear();let e,i=this.controlpoints;if(0==this.CenterIndex){if(!remesh&&this.Onscreen)return void this.append();e=i}else{let t=i.length;e=Array(t);for(let a=0;a<t;++a)e[a]=this.T(i[a])}let a=orthographic?1:this.Min[2]/B[2],r=pixel*Math.hypot(a*(viewParam.xmax-viewParam.xmin),a*(viewParam.ymax-viewParam.ymin))/size2;this.res2=r*r,this.Epsilon=FillFactor*r,this.data.clear(),this.Onscreen=!0,this.process(e)}}class BezierPatch extends Geometry{constructor(t,e,i,a,r,n){super(),this.controlpoints=t,this.Min=a,this.Max=r,this.color=n,this.CenterIndex=e;let s=t.length;if(n){let t=n[0][3]+n[1][3]+n[2][3];this.transparent=16==s||4==s?t+n[3][3]<1020:t<765}else this.transparent=Materials[i].diffuse[3]<1;this.MaterialIndex=i,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(t){let e=t[0];this.epsilon=0;let i=t.length;for(let a=1;a<i;++a)this.epsilon=Math.max(this.epsilon,abs2([t[a][0]-e[0],t[a][1]-e[1],t[a][2]-e[2]]));this.epsilon*=Number.EPSILON}processTriangle(t){let e=t[0],i=t[1],a=t[2],r=unit(cross([i[0]-e[0],i[1]-e[1],i[2]-e[2]],[a[0]-e[0],a[1]-e[1],a[2]-e[2]]));if(!this.offscreen([e,i,a])){let t,n,s;this.color?(t=this.data.Vertex(e,r!
 ,this.color[0]),n=this.data.Vertex(i,r,this.color[1]),s=this.data.Vertex(a,r,this.color[2])):(t=this.vertex(e,r),n=this.vertex(i,r),s=this.vertex(a,r)),0==wireframe?(this.data.indices.push(t),this.data.indices.push(n),this.data.indices.push(s)):(this.data.indices.push(t),this.data.indices.push(n),this.data.indices.push(n),this.data.indices.push(s),this.data.indices.push(s),this.data.indices.push(t)),this.append()}}processQuad(t){let e=t[0],i=t[1],a=t[2],r=t[3],n=cross([i[0]-e[0],i[1]-e[1],i[2]-e[2]],[a[0]-i[0],a[1]-i[1],a[2]-i[2]]),s=cross([a[0]-r[0],a[1]-r[1],a[2]-r[2]],[r[0]-e[0],r[1]-e[1],r[2]-e[2]]),o=unit([n[0]+s[0],n[1]+s[1],n[2]+s[2]]);if(!this.offscreen([e,i,a,r])){let t,n,s,h;this.color?(t=this.data.Vertex(e,o,this.color[0]),n=this.data.Vertex(i,o,this.color[1]),s=this.data.Vertex(a,o,this.color[2]),h=this.data.Vertex(r,o,this.color[3])):(t=this.vertex(e,o),n=this.vertex(i,o),s=this.vertex(a,o),h=this.vertex(r,o)),0==wireframe?(this.data.indices.push(t),this.data.indices.push(n),this.data.indices.push(s),this.data.indices.push(t),this.data.indices.push(s),this.data.indices.push(h)):(this.data.indices.push(t),this.data.indices.push(n),this.data.indices.push(n),this.data.indices.push(s),this.data.indices.push(s),this.data.indices.push(h),this.data.indices.push(h),this.data.indices.push(t)),this.append()}}curve(t,e,i,a,r){new BezierCurve([t[e],t[i],t[a],t[r]],0,materialIndex,this.Min,this.Max).render()}process(t){if(this.transparent&&1!=wireframe&&(materialIndex=this.color?-1-materialIndex:1+materialIndex),10==t.length)return this.process3(t);if(3==t.length)return this.processTriangle(t);if(4==t.length)return this.processQuad(t);if(1==wireframe)return this.curve(t,0,4,8,12),this.curve(t,12,13,14,15),this.curve(t,15,11,7,3),void this.curve(t,3,2,1,0);let e=t[0],i=t[3],a=t[12],r=t[15],n=this.normal(i,t[2],t[1],e,t[4],t[8],a);abs2(n)<this.epsilon&&abs2(n=this.normal(i,t[2],t[1],e,t[13],t[14],r))<this.epsilon&&(n=this.normal(r,t[11],t[7],i,t[4],t[8],a));let s=this.normal(e,t[4],t[8],a,t[13],t[14],r);abs2(s)<th!
 is.epsilon&&abs2(s=this.normal(e,t[4],t[8],a,t[11],t[7],i))<this.epsilon&&(s=this.normal(i,t[2],t[1],e,t[13],t[14],r));let o=this.normal(a,t[13],t[14],r,t[11],t[7],i);abs2(o)<this.epsilon&&abs2(o=this.normal(a,t[13],t[14],r,t[2],t[1],e))<this.epsilon&&(o=this.normal(e,t[4],t[8],a,t[11],t[7],i));let h=this.normal(r,t[11],t[7],i,t[2],t[1],e);if(abs2(h)<this.epsilon&&abs2(h=this.normal(r,t[11],t[7],i,t[4],t[8],a))<this.epsilon&&(h=this.normal(a,t[13],t[14],r,t[2],t[1],e)),this.color){let l=this.color[0],d=this.color[1],c=this.color[2],m=this.color[3],f=this.data.Vertex(e,n,l),u=this.data.Vertex(a,s,d),p=this.data.Vertex(r,o,c),v=this.data.Vertex(i,h,m);this.Render(t,f,u,p,v,e,a,r,i,!1,!1,!1,!1,l,d,c,m)}else{let l=this.vertex(e,n),d=this.vertex(a,s),c=this.vertex(r,o),m=this.vertex(i,h);this.Render(t,l,d,c,m,e,a,r,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)}Render(t,e,i,a,r,n,s,o,h,l,d,c,m,f,u,p,v){let g=this.Distance(t);if(g[0]<this.res2&&g[1]<this.res2)this.offscreen([n,s,o])||(0==wireframe?(this.data.indices.push(e),this.data.indices.push(i),this.data.indices.push(a)):(this.data.indices.push(e),this.data.indices.push(i),this.data.indices.push(i),this.data.indices.push(a))),this.offscreen([n,o,h])||(0==wireframe?(this.data.indices.push(e),this.data.indices.push(a),this.data.indices.push(r)):(this.data.indices.push(a),this.data.indices.push(r),this.data.indices.push(r),this.data.indices.push(e)));else{if(this.offscreen(t))return;let w=t[0],x=t[3],M=t[12],b=t[15];if(g[0]<this.res2){let g=new Split3(w,t[1],t[2],x),A=new Split3(t[4],t[5],t[6],t[7]),S=new Split3(t[8],t[9],t[10],t[11]),P=new Split3(M,t[13],t[14],b),R=[w,g.m0,g.m3,g.m5,t[4],A.m0,A.m3,A.m5,t[8],S.m0,S.m3,S.m5,M,P.m0,P.m3,P.m5],T=[g.m5,g.m4,g.m2,x,A.m5,A.m4,A.m2,t[7],S.m5,S.m4,S.m2,t[11],P.m5,P.m4,P.m2,b],y=this.normal(R[12],R[13],R[14],R[15],R[11],R[7],R[3]);abs2(y)<=this.epsilon&&abs2(y=this.normal(R[12],R[13],R[1!
 4],R[15],R[2],R[1],R[0]))<=this.epsilon&&(y=this.normal(R[0],R[4],R[8],R[12],R[11],R[7],R[3]));let D=this.normal(T[3],T[2],T[1],T[0],T[4],T[8],T[12]);abs2(D)<=this.epsilon&&abs2(D=this.normal(T[3],T[2],T[1],T[0],T[13],T[14],T[15]))<=this.epsilon&&(D=this.normal(T[15],T[11],T[7],T[3],T[4],T[8],T[12]));let I=this.Epsilon,z=[.5*(s[0]+o[0]),.5*(s[1]+o[1]),.5*(s[2]+o[2])];if(!d)if(d=Straightness(M,t[13],t[14],b)<this.res2){let t=unit(this.differential(T[12],T[8],T[4],T[0]));z=[z[0]-I*t[0],z[1]-I*t[1],z[2]-I*t[2]]}else z=R[15];let E=[.5*(h[0]+n[0]),.5*(h[1]+n[1]),.5*(h[2]+n[2])];if(!m)if(m=Straightness(w,t[1],t[2],x)<this.res2){let t=unit(this.differential(R[3],R[7],R[11],R[15]));E=[E[0]-I*t[0],E[1]-I*t[1],E[2]-I*t[2]]}else E=T[0];if(f){let t=Array(4),g=Array(4);for(let e=0;e<4;++e)t[e]=.5*(u[e]+p[e]),g[e]=.5*(v[e]+f[e]);let w=this.data.Vertex(z,y,t),x=this.data.Vertex(E,D,g);this.Render(R,e,i,w,x,n,s,z,E,l,d,!1,m,f,u,t,g),this.Render(T,x,w,a,r,E,z,o,h,!1,d,c,m,g,t,p,v)}else{let t=this.vertex(z,y),f=this.vertex(E,D);this.Render(R,e,i,t,f,n,s,z,E,l,d,!1,m),this.Render(T,f,t,a,r,E,z,o,h,!1,d,c,m)}return}if(g[1]<this.res2){let g=new Split3(w,t[4],t[8],M),A=new Split3(t[1],t[5],t[9],t[13]),S=new Split3(t[2],t[6],t[10],t[14]),P=new Split3(x,t[7],t[11],b),R=[w,t[1],t[2],x,g.m0,A.m0,S.m0,P.m0,g.m3,A.m3,S.m3,P.m3,g.m5,A.m5,S.m5,P.m5],T=[g.m5,A.m5,S.m5,P.m5,g.m4,A.m4,S.m4,P.m4,g.m2,A.m2,S.m2,P.m2,M,t[13],t[14],b],y=this.normal(R[0],R[4],R[8],R[12],R[13],R[14],R[15]);abs2(y)<=this.epsilon&&abs2(y=this.normal(R[0],R[4],R[8],R[12],R[11],R[7],R[3]))<=this.epsilon&&(y=this.normal(R[3],R[2],R[1],R[0],R[13],R[14],R[15]));let D=this.normal(T[15],T[11],T[7],T[3],T[2],T[1],T[0]);abs2(D)<=this.epsilon&&abs2(D=this.normal(T[15],T[11],T[7],T[3],T[4],T[8],T[12]))<=this.epsilon&&(D=this.normal(T[12],T[13],T[14],T[15],T[2],T[1],T[0]));let I=this.Epsilon,z=[.5*(n[0]+s[0]),.5*(n[1]+s[1]),.5*(n[2]+s[2])];if(!l)if(l=Straightness(w,t[4],t[8],M)<this.res2){let t=unit(this.differential(T[0],T[1],T[2],T[3]));z=[z[0]-I*t[0],z[1]-I*t[1],z[2]-I*t[2]]}el!
 se z=R[12];let E=[.5*(o[0]+h[0]),.5*(o[1]+h[1]),.5*(o[2]+h[2])];if(!c)if(c=Straightness(b,t[11],t[7],x)<this.res2){let t=unit(this.differential(R[15],R[14],R[13],R[12]));E=[E[0]-I*t[0],E[1]-I*t[1],E[2]-I*t[2]]}else E=T[3];if(f){let t=Array(4),g=Array(4);for(let e=0;e<4;++e)t[e]=.5*(f[e]+u[e]),g[e]=.5*(p[e]+v[e]);let w=this.data.Vertex(z,y,t),x=this.data.Vertex(E,D,g);this.Render(R,e,w,x,r,n,z,E,h,l,!1,c,m,f,t,g,v),this.Render(T,w,i,a,x,z,s,o,E,l,d,c,!1,t,u,p,g)}else{let t=this.vertex(z,y),f=this.vertex(E,D);this.Render(R,e,t,f,r,n,z,E,h,l,!1,c,m),this.Render(T,t,i,a,f,z,s,o,E,l,d,c,!1)}return}let A=new Split3(w,t[1],t[2],x),S=new Split3(t[4],t[5],t[6],t[7]),P=new Split3(t[8],t[9],t[10],t[11]),R=new Split3(M,t[13],t[14],b),T=new Split3(w,t[4],t[8],M),y=new Split3(A.m0,S.m0,P.m0,R.m0),D=new Split3(A.m3,S.m3,P.m3,R.m3),I=new Split3(A.m5,S.m5,P.m5,R.m5),z=new Split3(A.m4,S.m4,P.m4,R.m4),E=new Split3(A.m2,S.m2,P.m2,R.m2),O=new Split3(x,t[7],t[11],b),L=[w,A.m0,A.m3,A.m5,T.m0,y.m0,D.m0,I.m0,T.m3,y.m3,D.m3,I.m3,T.m5,y.m5,D.m5,I.m5],N=[T.m5,y.m5,D.m5,I.m5,T.m4,y.m4,D.m4,I.m4,T.m2,y.m2,D.m2,I.m2,M,R.m0,R.m3,R.m5],_=[I.m5,z.m5,E.m5,O.m5,I.m4,z.m4,E.m4,O.m4,I.m2,z.m2,E.m2,O.m2,R.m5,R.m4,R.m2,b],B=[A.m5,A.m4,A.m2,x,I.m0,z.m0,E.m0,O.m0,I.m3,z.m3,E.m3,O.m3,I.m5,z.m5,E.m5,O.m5],V=L[15],C=this.normal(L[0],L[4],L[8],L[12],L[13],L[14],L[15]);abs2(C)<this.epsilon&&abs2(C=this.normal(L[0],L[4],L[8],L[12],L[11],L[7],L[3]))<this.epsilon&&(C=this.normal(L[3],L[2],L[1],L[0],L[13],L[14],L[15]));let F=this.normal(N[12],N[13],N[14],N[15],N[11],N[7],N[3]);abs2(F)<this.epsilon&&abs2(F=this.normal(N[12],N[13],N[14],N[15],N[2],N[1],N[0]))<this.epsilon&&(F=this.normal(N[0],N[4],N[8],N[12],N[11],N[7],N[3]));let H=this.normal(_[15],_[11],_[7],_[3],_[2],_[1],_[0]);abs2(H)<this.epsilon&&abs2(H=this.normal(_[15],_[11],_[7],_[3],_[4],_[8],_[12]))<this.epsilon&&(H=this.normal(_[12],_[13],_[14],_[15],_[2],_[1],_[0]));let G=this.normal(B[3],B[2],B[1],B[0],B[4],B[8],B[12]);abs2(G)<this.epsilon&&abs2(G=this.normal(B[3],B[2],B[1],B[0],B[13],B[14],B[15]))<t!
 his.epsilon&&(G=this.normal(B[15],B[11],B[7],B[3],B[4],B[8],B[12]));let U=this.normal(_[3],_[2],_[1],V,_[4],_[8],_[12]),W=this.Epsilon,Y=[.5*(n[0]+s[0]),.5*(n[1]+s[1]),.5*(n[2]+s[2])];if(!l)if(l=Straightness(w,t[4],t[8],M)<this.res2){let t=unit(this.differential(N[0],N[1],N[2],N[3]));Y=[Y[0]-W*t[0],Y[1]-W*t[1],Y[2]-W*t[2]]}else Y=L[12];let j=[.5*(s[0]+o[0]),.5*(s[1]+o[1]),.5*(s[2]+o[2])];if(!d)if(d=Straightness(M,t[13],t[14],b)<this.res2){let t=unit(this.differential(_[12],_[8],_[4],_[0]));j=[j[0]-W*t[0],j[1]-W*t[1],j[2]-W*t[2]]}else j=N[15];let k=[.5*(o[0]+h[0]),.5*(o[1]+h[1]),.5*(o[2]+h[2])];if(!c)if(c=Straightness(b,t[11],t[7],x)<this.res2){let t=unit(this.differential(B[15],B[14],B[13],B[12]));k=[k[0]-W*t[0],k[1]-W*t[1],k[2]-W*t[2]]}else k=_[3];let Z=[.5*(h[0]+n[0]),.5*(h[1]+n[1]),.5*(h[2]+n[2])];if(!m)if(m=Straightness(w,t[1],t[2],x)<this.res2){let t=unit(this.differential(L[3],L[7],L[11],L[15]));Z=[Z[0]-W*t[0],Z[1]-W*t[1],Z[2]-W*t[2]]}else Z=B[0];if(f){let t=Array(4),g=Array(4),w=Array(4),x=Array(4),M=Array(4);for(let e=0;e<4;++e)t[e]=.5*(f[e]+u[e]),g[e]=.5*(u[e]+p[e]),w[e]=.5*(p[e]+v[e]),x[e]=.5*(v[e]+f[e]),M[e]=.5*(t[e]+w[e]);let b=this.data.Vertex(Y,C,t),A=this.data.Vertex(j,F,g),S=this.data.Vertex(k,H,w),P=this.data.Vertex(Z,G,x),R=this.data.Vertex(V,U,M);this.Render(L,e,b,R,P,n,Y,V,Z,l,!1,!1,m,f,t,M,x),this.Render(N,b,i,A,R,Y,s,j,V,l,d,!1,!1,t,u,g,M),this.Render(_,R,A,a,S,V,j,o,k,!1,d,c,!1,M,g,p,w),this.Render(B,P,R,S,r,Z,V,k,h,!1,!1,c,m,x,M,w,v)}else{let t=this.vertex(Y,C),f=this.vertex(j,F),u=this.vertex(k,H),p=this.vertex(Z,G),v=this.vertex(V,U);this.Render(L,e,t,v,p,n,Y,V,Z,l,!1,!1,m),this.Render(N,t,i,f,v,Y,s,j,V,l,d,!1,!1),this.Render(_,v,f,a,u,V,j,o,k,!1,d,c,!1),this.Render(B,p,v,u,r,Z,V,k,h,!1,!1,c,m)}}}process3(t){if(1==wireframe)return this.curve(t,0,1,3,6),this.curve(t,6,7,8,9),void this.curve(t,9,5,2,0);let e=t[0],i=t[6],a=t[9],r=this.normal(a,t[5],t[2],e,t[1],t[3],i),n=this.normal(e,t[1],t[3],i,t[7],t[8],a),s=this.normal(i,t[7],t[8],a,t[5],t[2],e);if(this.color){let o=this.color[0],h=this!
 .color[1],l=this.color[2],d=this.data.Vertex(e,r,o),c=this.data.Vertex(i,n,h),m=this.data.Vertex(a,s,l);this.Render3(t,d,c,m,e,i,a,!1,!1,!1,o,h,l)}else{let o=this.vertex(e,r),h=this.vertex(i,n),l=this.vertex(a,s);this.Render3(t,o,h,l,e,i,a,!1,!1,!1)}this.data.indices.length>0&&this.append()}Render3(t,e,i,a,r,n,s,o,h,l,d,c,m){if(this.Distance3(t)<this.res2)this.offscreen([r,n,s])||(0==wireframe?(this.data.indices.push(e),this.data.indices.push(i),this.data.indices.push(a)):(this.data.indices.push(e),this.data.indices.push(i),this.data.indices.push(i),this.data.indices.push(a),this.data.indices.push(a),this.data.indices.push(e)));else{if(this.offscreen(t))return;let f=t[0],u=t[1],p=t[2],v=t[3],g=t[4],w=t[5],x=t[6],M=t[7],b=t[8],A=t[9],S=[.5*(A[0]+w[0]),.5*(A[1]+w[1]),.5*(A[2]+w[2])],P=[.5*(A[0]+b[0]),.5*(A[1]+b[1]),.5*(A[2]+b[2])],R=[.5*(w[0]+p[0]),.5*(w[1]+p[1]),.5*(w[2]+p[2])],T=[.5*(b[0]+g[0]),.5*(b[1]+g[1]),.5*(b[2]+g[2])],y=[.5*(b[0]+M[0]),.5*(b[1]+M[1]),.5*(b[2]+M[2])],D=[.5*(p[0]+g[0]),.5*(p[1]+g[1]),.5*(p[2]+g[2])],I=[.5*(p[0]+f[0]),.5*(p[1]+f[1]),.5*(p[2]+f[2])],z=[.5*(g[0]+v[0]),.5*(g[1]+v[1]),.5*(g[2]+v[2])],E=[.5*(M[0]+x[0]),.5*(M[1]+x[1]),.5*(M[2]+x[2])],O=[.5*(f[0]+u[0]),.5*(f[1]+u[1]),.5*(f[2]+u[2])],L=[.5*(u[0]+v[0]),.5*(u[1]+v[1]),.5*(u[2]+v[2])],N=[.5*(v[0]+x[0]),.5*(v[1]+x[1]),.5*(v[2]+x[2])],_=[.5*(S[0]+R[0]),.5*(S[1]+R[1]),.5*(S[2]+R[2])],B=[.5*(P[0]+y[0]),.5*(P[1]+y[1]),.5*(P[2]+y[2])],V=[.5*(R[0]+I[0]),.5*(R[1]+I[1]),.5*(R[2]+I[2])],C=[.5*T[0]+.25*(g[0]+u[0]),.5*T[1]+.25*(g[1]+u[1]),.5*T[2]+.25*(g[2]+u[2])],F=[.5*(y[0]+E[0]),.5*(y[1]+E[1]),.5*(y[2]+E[2])],H=[.5*D[0]+.25*(g[0]+M[0]),.5*D[1]+.25*(g[1]+M[1]),.5*D[2]+.25*(g[2]+M[2])],G=[.25*(w[0]+g[0])+.5*z[0],.25*(w[1]+g[1])+.5*z[1],.25*(w[2]+g[2])+.5*z[2]],U=[.5*(O[0]+L[0]),.5*(O[1]+L[1]),.5*(O[2]+L[2])],W=[.5*(L[0]+N[0]),.5*(L[1]+N[1]),.5*(L[2]+N[2])],Y=[.5*(H[0]+U[0]),.5*(H[1]+U[1]),.5*(H[2]+U[2])],j=[.5*(H[0]+W[0]),.5*(H[1]+W[1]),.5*(H[2]+W[2])],k=[.5*(U[0]+W[0]),.5*(U[1]+W[1]),.5*(U[2]+W[2])],Z=[.5*(G[0]+F[0]),.5*(G[1]+F[1]),.5*(G[2]+F[2])!
 ],X=[.5*(B[0]+G[0]),.5*(B[1]+G[1]),.5*(B[2]+G[2])],q=[.5*(B[0]+F[0]),.5*(B[1]+F[1]),.5*(B[2]+F[2])],K=[.5*(_[0]+C[0]),.5*(_[1]+C[1]),.5*(_[2]+C[2])],$=[.5*(V[0]+C[0]),.5*(V[1]+C[1]),.5*(V[2]+C[2])],Q=[.5*(_[0]+V[0]),.5*(_[1]+V[1]),.5*(_[2]+V[2])],J=[f,O,I,U,[.5*(D[0]+O[0]),.5*(D[1]+O[1]),.5*(D[2]+O[2])],V,k,Y,$,Q],tt=[k,W,j,N,[.5*(z[0]+E[0]),.5*(z[1]+E[1]),.5*(z[2]+E[2])],Z,x,E,F,q],et=[Q,K,_,X,[.5*(S[0]+T[0]),.5*(S[1]+T[1]),.5*(S[2]+T[2])],S,q,B,P,A],it=[q,X,Z,K,[.25*(R[0]+y[0]+L[0]+g[0]),.25*(R[1]+y[1]+L[1]+g[1]),.25*(R[2]+y[2]+L[2]+g[2])],j,Q,$,Y,k],at=this.normal(k,j,Z,q,X,K,Q),rt=this.normal(q,X,K,Q,$,Y,k),nt=this.normal(Q,$,Y,k,j,Z,q),st=this.Epsilon,ot=[.5*(n[0]+s[0]),.5*(n[1]+s[1]),.5*(n[2]+s[2])];if(!o)if(o=Straightness(x,M,b,A)<this.res2){let t=unit(this.sumdifferential(it[0],it[2],it[5],it[9],it[1],it[3],it[6]));ot=[ot[0]-st*t[0],ot[1]-st*t[1],ot[2]-st*t[2]]}else ot=q;let ht=[.5*(s[0]+r[0]),.5*(s[1]+r[1]),.5*(s[2]+r[2])];if(!h)if(h=Straightness(f,p,w,A)<this.res2){let t=unit(this.sumdifferential(it[6],it[3],it[1],it[0],it[7],it[8],it[9]));ht=[ht[0]-st*t[0],ht[1]-st*t[1],ht[2]-st*t[2]]}else ht=Q;let lt=[.5*(r[0]+n[0]),.5*(r[1]+n[1]),.5*(r[2]+n[2])];if(!l)if(l=Straightness(f,u,v,x)<this.res2){let t=unit(this.sumdifferential(it[9],it[8],it[7],it[6],it[5],it[2],it[0]));lt=[lt[0]-st*t[0],lt[1]-st*t[1],lt[2]-st*t[2]]}else lt=k;if(d){let t=Array(4),f=Array(4),u=Array(4);for(let e=0;e<4;++e)t[e]=.5*(c[e]+m[e]),f[e]=.5*(m[e]+d[e]),u[e]=.5*(d[e]+c[e]);let p=this.data.Vertex(ot,at,t),v=this.data.Vertex(ht,rt,f),g=this.data.Vertex(lt,nt,u);this.Render3(J,e,g,v,r,lt,ht,!1,h,l,d,u,f),this.Render3(tt,g,i,p,lt,n,ot,o,!1,l,u,c,t),this.Render3(et,v,p,a,ht,ot,s,o,h,!1,f,t,m),this.Render3(it,p,v,g,ot,ht,lt,!1,!1,!1,t,f,u)}else{let t=this.vertex(ot,at),d=this.vertex(ht,rt),c=this.vertex(lt,nt);this.Render3(J,e,c,d,r,lt,ht,!1,h,l),this.Render3(tt,c,i,t,lt,n,ot,o,!1,l),this.Render3(et,d,t,a,ht,ot,s,o,h,!1),this.Render3(it,t,d,c,ot,ht,lt,!1,!1,!1)}}}Distance(t){let e=t[0],i=t[3],a=t[12],r=t[15],n=Flatness(e,a,i,r);n=Math.max!
 (Straightness(e,t[4],t[8],a)),n=Math.max(n,Straightness(t[1],t[5],t[9],t[13])),n=Math.max(n,Straightness(i,t[7],t[11],r)),n=Math.max(n,Straightness(t[2],t[6],t[10],t[14]));let s=Flatness(e,i,a,r);return s=Math.max(s,Straightness(e,t[1],t[2],i)),s=Math.max(s,Straightness(t[4],t[5],t[6],t[7])),s=Math.max(s,Straightness(t[8],t[9],t[10],t[11])),[n,s=Math.max(s,Straightness(a,t[13],t[14],r))]}Distance3(t){let e=t[0],i=t[4],a=t[6],r=t[9],n=abs2([(e[0]+a[0]+r[0])*third-i[0],(e[1]+a[1]+r[1])*third-i[1],(e[2]+a[2]+r[2])*third-i[2]]);return n=Math.max(n,Straightness(e,t[1],t[3],a)),n=Math.max(n,Straightness(e,t[2],t[5],r)),Math.max(n,Straightness(a,t[7],t[8],r))}differential(t,e,i,a){let r=[3*(e[0]-t[0]),3*(e[1]-t[1]),3*(e[2]-t[2])];return abs2(r)>this.epsilon?r:abs2(r=bezierPP(t,e,i))>this.epsilon?r:bezierPPP(t,e,i,a)}sumdifferential(t,e,i,a,r,n,s){let o=this.differential(t,e,i,a),h=this.differential(t,r,n,s);return[o[0]+h[0],o[1]+h[1],o[2]+h[2]]}normal(t,e,i,a,r,n,s){let o=3*(r[0]-a[0]),h=3*(r[1]-a[1]),l=3*(r[2]-a[2]),d=3*(i[0]-a[0]),c=3*(i[1]-a[1]),m=3*(i[2]-a[2]),f=[h*m-l*c,l*d-o*m,o*c-h*d];if(abs2(f)>this.epsilon)return f;let u=[d,c,m],p=[o,h,l],v=bezierPP(a,i,e),g=bezierPP(a,r,n),w=cross(g,u),x=cross(p,v);if(abs2(f=[w[0]+x[0],w[1]+x[1],w[2]+x[2]])>this.epsilon)return f;let M=bezierPPP(a,i,e,t),b=bezierPPP(a,r,n,s);w=cross(p,M),x=cross(b,u);let A=cross(g,v);return abs2(f=[w[0]+x[0]+A[0],w[1]+x[1]+A[1],w[2]+x[2]+A[2]])>this.epsilon?f:(w=cross(b,v),x=cross(g,M),abs2(f=[w[0]+x[0],w[1]+x[1],w[2]+x[2]])>this.epsilon?f:cross(b,M))}}class BezierCurve extends Geometry{constructor(t,e,i,a,r){super(),this.controlpoints=t,this.Min=a,this.Max=r,this.CenterIndex=e,this.MaterialIndex=i}setMaterialIndex(){this.setMaterial(material1Data,drawMaterial1)}processLine(t){let e=t[0],i=t[1];if(!this.offscreen([e,i])){let t=[0,0,1];this.data.indices.push(this.data.vertex(e,t)),this.data.indices.push(this.data.vertex(i,t)),this.append()}}process(t){if(2==t.length)return this.processLine(t);let e=t[0],i=t[1],a=t[2],r=t[3],n=this.normal(bezier!
 P(e,i),bezierPP(e,i,a)),s=this.normal(bezierP(a,r),bezierPP(r,a,i)),o=this.data.vertex(e,n),h=this.data.vertex(r,s);this.Render(t,o,h),this.data.indices.length>0&&this.append()}append(){material1Data.append(this.data)}Render(t,e,i){let a=t[0],r=t[1],n=t[2],s=t[3];if(Straightness(a,r,n,s)<this.res2)this.offscreen([a,s])||(this.data.indices.push(e),this.data.indices.push(i));else{if(this.offscreen(t))return;let o=[.5*(a[0]+r[0]),.5*(a[1]+r[1]),.5*(a[2]+r[2])],h=[.5*(r[0]+n[0]),.5*(r[1]+n[1]),.5*(r[2]+n[2])],l=[.5*(n[0]+s[0]),.5*(n[1]+s[1]),.5*(n[2]+s[2])],d=[.5*(o[0]+h[0]),.5*(o[1]+h[1]),.5*(o[2]+h[2])],c=[.5*(h[0]+l[0]),.5*(h[1]+l[1]),.5*(h[2]+l[2])],m=[.5*(d[0]+c[0]),.5*(d[1]+c[1]),.5*(d[2]+c[2])],f=[a,o,d,m],u=[m,c,l,s],p=this.normal(bezierPh(a,r,n,s),bezierPPh(a,r,n,s)),v=this.data.vertex(m,p);this.Render(f,e,v),this.Render(u,v,i)}}normal(t,e){let i=dot(t,t),a=dot(t,e);return[i*e[0]-a*t[0],i*e[1]-a*t[1],i*e[2]-a*t[2]]}}class Pixel extends Geometry{constructor(t,e,i,a,r){super(),this.controlpoint=t,this.width=e,this.CenterIndex=0,this.MaterialIndex=i,this.Min=a,this.Max=r}setMaterialIndex(){this.setMaterial(material0Data,drawMaterial0)}process(t){this.data.indices.push(this.data.vertex0(this.controlpoint,this.width)),this.append()}append(){material0Data.append(this.data)}}class Triangles extends Geometry{constructor(t,e,i){super(),this.CenterIndex=0,this.MaterialIndex=t,this.Min=e,this.Max=i,this.Positions=Positions,this.Normals=Normals,this.Colors=Colors,this.Indices=Indices,Positions=[],Normals=[],Colors=[],Indices=[],this.transparent=Materials[t].diffuse[3]<1}setMaterialIndex(){this.transparent?this.setMaterial(transparentData,drawTransparent):this.setMaterial(triangleData,drawTriangle)}process(t){materialIndex=this.Colors.length>0?-1-materialIndex:1+materialIndex;for(let t=0,e=this.Indices.length;t<e;++t){let e=this.Indices[t],i=e[0],a=this.Positions[i[0]],r=this.Positions[i[1]],n=this.Positions[i[2]];if(!this.offscreen([a,r,n])){let t=e.length>1?e[1]:i;if(t&&0!=t.length||(t=i),this.Colors.length>0){let s=e!
 .length>2?e[2]:i;s&&0!=s.length||(s=i);let o=this.Colors[s[0]],h=this.Colors[s[1]],l=this.Colors[s[2]];this.transparent|=o[3]+h[3]+l[3]<765,0==wireframe?(this.data.iVertex(i[0],a,this.Normals[t[0]],o),this.data.iVertex(i[1],r,this.Normals[t[1]],h),this.data.iVertex(i[2],n,this.Normals[t[2]],l)):(this.data.iVertex(i[0],a,this.Normals[t[0]],o),this.data.iVertex(i[1],r,this.Normals[t[1]],h),this.data.iVertex(i[1],r,this.Normals[t[1]],h),this.data.iVertex(i[2],n,this.Normals[t[2]],l),this.data.iVertex(i[2],n,this.Normals[t[2]],l),this.data.iVertex(i[0],a,this.Normals[t[0]],o))}else 0==wireframe?(this.data.iVertex(i[0],a,this.Normals[t[0]]),this.data.iVertex(i[1],r,this.Normals[t[1]]),this.data.iVertex(i[2],n,this.Normals[t[2]])):(this.data.iVertex(i[0],a,this.Normals[t[0]]),this.data.iVertex(i[1],r,this.Normals[t[1]]),this.data.iVertex(i[1],r,this.Normals[t[1]]),this.data.iVertex(i[2],n,this.Normals[t[2]]),this.data.iVertex(i[2],n,this.Normals[t[2]]),this.data.iVertex(i[0],a,this.Normals[t[0]]))}}this.data.nvertices=this.Positions.length,this.data.indices.length>0&&this.append()}append(){this.transparent?transparentData.append(this.data):triangleData.append(this.data)}}function home(){mat4.identity(rotMat),initProjection(),setProjection(),remesh=!0,draw()}let positionAttribute=0,normalAttribute=1,materialAttribute=2,colorAttribute=3,widthAttribute=4;function initShader(t=[]){let e=getShader(gl,vertex,gl.VERTEX_SHADER,t),i=getShader(gl,fragment,gl.FRAGMENT_SHADER,t),a=gl.createProgram();return gl.attachShader(a,e),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(t,e,i,a){this.m0=[.5*(t[0]+e[0]),.5*(t[1]+e[1]),.5*(t[2]+e[2])];let r=.5*(e[0]+i[0]),n=.5*(e[1]+i[1]),s=.5*!
 (e[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]+r),.5*(this.m0[1]+n),.5*(this.m0[2]+s)],this.m4=[.5*(r+this.m2[0]),.5*(n+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(t){let e=1/(Math.sqrt(t[0]*t[0]+t[1]*t[1]+t[2]*t[2])||1);return[t[0]*e,t[1]*e,t[2]*e]}function abs2(t){return t[0]*t[0]+t[1]*t[1]+t[2]*t[2]}function dot(t,e){return t[0]*e[0]+t[1]*e[1]+t[2]*e[2]}function cross(t,e){return[t[1]*e[2]-t[2]*e[1],t[2]*e[0]-t[0]*e[2],t[0]*e[1]-t[1]*e[0]]}function bezierP(t,e){return[e[0]-t[0],e[1]-t[1],e[2]-t[2]]}function bezierPP(t,e,i){return[3*(t[0]+i[0])-6*e[0],3*(t[1]+i[1])-6*e[1],3*(t[2]+i[2])-6*e[2]]}function bezierPPP(t,e,i,a){return[a[0]-t[0]+3*(e[0]-i[0]),a[1]-t[1]+3*(e[1]-i[1]),a[2]-t[2]+3*(e[2]-i[2])]}function bezierPh(t,e,i,a){return[i[0]+a[0]-t[0]-e[0],i[1]+a[1]-t[1]-e[1],i[2]+a[2]-t[2]-e[2]]}function bezierPPh(t,e,i,a){return[3*t[0]-5*e[0]+i[0]+a[0],3*t[1]-5*e[1]+i[1]+a[1],3*t[2]-5*e[2]+i[2]+a[2]]}function Straightness(t,e,i,a){let r=[third*(a[0]-t[0]),third*(a[1]-t[1]),third*(a[2]-t[2])];return Math.max(abs2([e[0]-r[0]-t[0],e[1]-r[1]-t[1],e[2]-r[2]-t[2]]),abs2([a[0]-r[0]-i[0],a[1]-r[1]-i[1],a[2]-r[2]-i[2]]))}function Flatness(t,e,i,a){let r=[e[0]-t[0],e[1]-t[1],e[2]-t[2]],n=[a[0]-i[0],a[1]-i[1],a[2]-i[2]];return Math.max(abs2(cross(r,unit(n))),abs2(cross(n,unit(r))))/9}function corners(t,e){return[t,[t[0],t[1],e[2]],[t[0],e[1],t[2]],[t[0],e[1],e[2]],[e[0],t[1],t[2]],[e[0],t[1],e[2]],[e[0],e[1],t[2]],e]}function minbound(t){return[Math.min(t[0][0],t[1][0],t[2][0],t[3][0],t[4][0],t[5][0],t[6][0],t[7][0]),Math.min(t[0][1],t[1][1],t[2][1],t[3][1],t[4][1],t[5][1],t[6][1],t[7][1]),Math.min(t[0][2],t[1][2],t[2][2],t[3][2],t[4][2],t[5][2],t[6][2],t[7][2])]}function maxbound(t){return[Math.max(t[0][0],t[1][0],t[2][0],t[3][0],t[4][0],t[5][0],t[6][0],t[7][0]),Math.max(t[0][1],t[1][1],t[2][1],t[3][1],t[4][1],t[5][1],t[6][1],t[7][1]),Math.max(t[0][2],t[1][2],t[2][2],t[3][2],t[4][2],t[5]!
 [2],t[6][2],t[7][2])]}function COBTarget(t,e){mat4.fromTranslation(T,[center.x,center.y,center.z]),mat4.invert(cjMatInv,T),mat4.multiply(t,e,cjMatInv),mat4.multiply(t,T,t)}function setUniforms(t,e){let i=e==pixelShader;gl.useProgram(e),gl.enableVertexAttribArray(positionAttribute),i&&gl.enableVertexAttribArray(widthAttribute);let a=!i&&Lights.length>0;if(a&&gl.enableVertexAttribArray(normalAttribute),gl.enableVertexAttribArray(materialAttribute),e.projViewMatUniform=gl.getUniformLocation(e,"projViewMat"),e.viewMatUniform=gl.getUniformLocation(e,"viewMat"),e.normMatUniform=gl.getUniformLocation(e,"normMat"),e!=colorShader&&e!=transparentShader||gl.enableVertexAttribArray(colorAttribute),a)for(let t=0;t<Lights.length;++t)Lights[t].setUniform(e,t);for(let i=0;i<t.materials.length;++i)t.materials[i].setUniform(e,i);gl.uniformMatrix4fv(e.projViewMatUniform,!1,projViewMat),gl.uniformMatrix4fv(e.viewMatUniform,!1,viewMat),gl.uniformMatrix3fv(e.normMatUniform,!1,normMat)}function handleMouseDown(t){zoomEnabled||enableZoom(),mouseDownOrTouchActive=!0,lastMouseX=t.clientX,lastMouseY=t.clientY}let pinchStart,touchStartTime,pinch=!1;function pinchDistance(t){return Math.hypot(t[0].pageX-t[1].pageX,t[0].pageY-t[1].pageY)}function handleTouchStart(t){t.preventDefault(),zoomEnabled||enableZoom();let e=t.targetTouches;swipe=rotate=pinch=!1,zooming||(1!=e.length||mouseDownOrTouchActive||(touchStartTime=(new Date).getTime(),touchId=e[0].identifier,lastMouseX=e[0].pageX,lastMouseY=e[0].pageY),2!=e.length||mouseDownOrTouchActive||(touchId=e[0].identifier,pinchStart=pinchDistance(e),pinch=!0))}function handleMouseUpOrTouchEnd(t){mouseDownOrTouchActive=!1}function rotateScene(t,e,i,a,r){if(t==i&&e==a)return;let[n,s]=arcball([t,-e],[i,-a]);mat4.fromRotation(T,2*r*ArcballFactor*n/lastzoom,s),mat4.multiply(rotMat,T,rotMat)}function shiftScene(t,e,i,a){let r=1/lastzoom;shift.x+=(i-t)*r*halfCanvasWidth,shift.y-=(a-e)*r*halfCanvasHeight}function panScene(t,e,i,a){orthographic?shiftScene(t,e,i,a):(center.x+=(i-t)*(viewParam.xmax-viewParam.x!
 min),center.y-=(a-e)*(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 t=Math.sqrt(Number.MAX_VALUE),e=1/t;Zoom<=e&&(Zoom=e),Zoom>=t&&(Zoom=t),Zoom!=lastzoom&&(remesh=!0),lastzoom=Zoom}function zoomImage(t){let e=zoomStep*halfCanvasHeight*t;const i=Math.log(.1*Number.MAX_VALUE)/Math.log(zoomFactor);Math.abs(e)<i&&(Zoom*=zoomFactor**e,capzoom())}function normMouse(t){let e=t[0],i=t[1],a=Math.hypot(e,i);return a>1&&(denom=1/a,e*=denom,i*=denom),[e,i,Math.sqrt(Math.max(1-i*i-e*e,0))]}function arcball(t,e){let i=normMouse(t),a=normMouse(e),r=dot(i,a);return r>1?r=1:r<-1&&(r=-1),[Math.acos(r),unit(cross(i,a))]}function zoomScene(t,e,i,a){zoomImage(e-a)}const DRAGMODE_ROTATE=1,DRAGMODE_SHIFT=2,DRAGMODE_ZOOM=3,DRAGMODE_PAN=4;function processDrag(t,e,i,a=1){let r;switch(i){case DRAGMODE_ROTATE:r=rotateScene;break;case DRAGMODE_SHIFT:r=shiftScene;break;case DRAGMODE_ZOOM:r=zoomScene;break;case DRAGMODE_PAN:r=panScene;break;default:r=((t,e,i,a)=>{})}r((lastMouseX-halfCanvasWidth)/halfCanvasWidth,(lastMouseY-halfCanvasHeight)/halfCanvasHeight,(t-halfCanvasWidth)/halfCanvasWidth,(e-halfCanvasHeight)/halfCanvasHeight,a),lastMouseX=t,lastMouseY=e,setProjection(),draw()}let zoomEnabled=0;function enableZoom(){zoomEnabled=1,canvas.addEventListener("wheel",handleMouseWheel,!1)}function disableZoom(){zoomEnabled=0,canvas.removeEventListener("wheel",handleMouseWheel,!1)}function handleKey(t){if(zoomEnabled||enableZoom(),embedded&&zoomEnabled&&27==t.keyCode)return void disableZoom();let e=[];switch(t.key){case"x":e=[1,0,0];break;case"y":e=[0,1,0];break;case"z":e=[0,0,1];break;case"h":home();break;case"m":3==++wireframe&&(wireframe=0),2!=wireframe&&(embedded||deleteShaders(),initShaders()),remesh=!0,draw();break;case"+":case"=":case">":expand();break;case"-":case"_":case"<":shrink()}e.length>0&&(mat4.rotate(rotMat,rot!
 Mat,.1,e),updateViewMatrix(),draw())}function handleMouseWheel(t){t.preventDefault(),t.deltaY<0?Zoom*=zoomFactor:Zoom/=zoomFactor,capzoom(),setProjection(),draw()}function handleMouseMove(t){if(!mouseDownOrTouchActive)return;let e;processDrag(t.clientX,t.clientY,e=t.getModifierState("Control")?DRAGMODE_SHIFT:t.getModifierState("Shift")?DRAGMODE_ZOOM:t.getModifierState("Alt")?DRAGMODE_PAN:DRAGMODE_ROTATE)}let zooming=!1,swipe=!1,rotate=!1;function handleTouchMove(t){if(t.preventDefault(),zooming)return;let e=t.targetTouches;if(!pinch&&1==e.length&&touchId==e[0].identifier){let t=e[0].pageX,i=e[0].pageY,a=t-lastMouseX,r=i-lastMouseY,n=a*a+r*r<=shiftHoldDistance*shiftHoldDistance;if(n&&!swipe&&!rotate&&(new Date).getTime()-touchStartTime>shiftWaitTime&&(navigator.vibrate&&window.navigator.vibrate(vibrateTime),swipe=!0),swipe)processDrag(t,i,DRAGMODE_SHIFT);else if(!n){rotate=!0,processDrag(e[0].pageX,e[0].pageY,DRAGMODE_ROTATE,.5)}}if(pinch&&!swipe&&2==e.length&&touchId==e[0].identifier){let t=pinchDistance(e),i=t-pinchStart;zooming=!0,(i*=zoomPinchFactor)>zoomPinchCap&&(i=zoomPinchCap),i<-zoomPinchCap&&(i=-zoomPinchCap),zoomImage(i/size2),pinchStart=t,swipe=rotate=zooming=!1,setProjection(),draw()}}let pixelShader,materialShader,colorShader,transparentShader,zbuffer=[];function transformVertices(t){let e=viewMat[2],i=viewMat[6],a=viewMat[10];zbuffer.length=t.length;for(let r=0;r<t.length;++r){let n=6*r;zbuffer[r]=e*t[n]+i*t[n+1]+a*t[n+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.clear()}function drawTransparent(){let t=transparentData.indices;if(wireframe>0)return drawBuffer(transparentData,transparentShader,t),void transparentData.clear();if(t.length!
 >0){transformVertices(transparentData.vertices);let e=t.length/3,i=Array(e).fill().map((t,e)=>e);i.sort(function(e,i){let a=3*e;Ia=t[a],Ib=t[a+1],Ic=t[a+2];let r=3*i;return IA=t[r],IB=t[r+1],IC=t[r+2],zbuffer[Ia]+zbuffer[Ib]+zbuffer[Ic]<zbuffer[IA]+zbuffer[IB]+zbuffer[IC]?-1:1});let a=Array(t.length);for(let r=0;r<e;++r){let e=3*i[r];a[3*r]=t[e],a[3*r+1]=t[e+1],a[3*r+2]=t[e+2]}gl.depthMask(!1),drawBuffer(transparentData,transparentShader,a),gl.depthMask(!0)}transparentData.clear()}function drawBuffers(){drawMaterial0(),drawMaterial1(),drawMaterial(),drawColor(),drawTriangle(),drawTransparent()}function draw(){embedded&&(offscreen.width=canvas.width,offscreen.height=canvas.height,setViewport()),gl.clearColor(Background[0],Background[1],Background[2],Background[3]),gl.clear(gl.COLOR_BUFFER_BIT|gl.DEPTH_BUFFER_BIT);for(let t=0;t<P.length;++t)P[t].render();drawBuffers(),embedded&&(context.clearRect(0,0,canvas.width,canvas.height),context.drawImage(offscreen,0,0)),0==wireframe&&(remesh=!1)}function setDimensions(t,e,i,a){let r=t/e,n=1/lastzoom,s=(i/t+viewportshift[0])*lastzoom,o=(a/e+viewportshift[1])*lastzoom;if(orthographic){let t=B[0]-b[0],e=B[1]-b[1];if(t<e*r){let t=.5*e*r*n,i=2*t*s,a=e*n*o;viewParam.xmin=-t-i,viewParam.xmax=t-i,viewParam.ymin=b[1]*n-a,viewParam.ymax=B[1]*n-a}else{let e=.5*t/(r*Zoom),i=t*n*s,a=2*e*o;viewParam.xmin=b[0]*n-i,viewParam.xmax=B[0]*n-i,viewParam.ymin=-e-a,viewParam.ymax=e-a}}else{let t=H*n,e=t*r,i=2*e*s,a=2*t*o;viewParam.xmin=-e-i,viewParam.xmax=e-i,viewParam.ymin=-t-a,viewParam.ymax=t-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*angle)*B[2],center.x=center.y=0,center.z=.5*(b[2]+B[2]),lastzoom=Zoom=Zoom0,viewParam.zmin=b[2],viewParam.zmax=B[2],shift.x=shift.y=0}function setViewport(){gl.viewportWidth=canvasWidth,gl.viewportHeight=canvasHeight,gl.viewp!
 ort(0,0,gl.viewportWidth,gl.viewportHeight),gl.scissor(0,0,gl.viewportWidth,gl.viewportHeight)}function setCanvas(){canvas.width=canvasWidth,canvas.height=canvasHeight,embedded&&(offscreen.width=canvasWidth,offscreen.height=canvasHeight),size2=Math.hypot(canvasWidth,canvasHeight),halfCanvasWidth=.5*canvasWidth,halfCanvasHeight=.5*canvasHeight}function setsize(t,e){t>maxViewportWidth&&(t=maxViewportWidth),e>maxViewportHeight&&(e=maxViewportHeight),shift.x*=t/canvasWidth,shift.y*=e/canvasHeight,canvasWidth=t,canvasHeight=e,setCanvas(),setViewport(),home()}function expand(){setsize(canvasWidth*resizeStep+.5,canvasHeight*resizeStep+.5)}function shrink(){setsize(Math.max(canvasWidth/resizeStep+.5,1),Math.max(canvasHeight/resizeStep+.5,1))}function webGLInit(){if(canvas=document.getElementById("Asymptote"),embedded=window.top.document!=document,initGL(),absolute&&!embedded)canvasWidth*=window.devicePixelRatio,canvasHeight*=window.devicePixelRatio;else{canvas.width=Math.max(window.innerWidth-windowTrim,windowTrim),canvas.height=Math.max(window.innerHeight-windowTrim,windowTrim);let t=canvasWidth/canvasHeight;canvas.width>canvas.height*t?canvas.width=Math.min(canvas.height*t,canvas.width):canvas.height=Math.min(canvas.width/t,canvas.height),canvas.width>0&&(canvasWidth=canvas.width),canvas.height>0&&(canvasHeight=canvas.height)}setCanvas(),ArcballFactor=1+8*Math.hypot(viewportmargin[0],viewportmargin[1])/size2,viewportshift[0]/=Zoom0,viewportshift[1]/=Zoom0,gl.enable(gl.BLEND),gl.blendFunc(gl.SRC_ALPHA,gl.ONE_MINUS_SRC_ALPHA),gl.enable(gl.DEPTH_TEST),gl.enable(gl.SCISSOR_TEST),setViewport(),home(),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.addEve!
 ntListener("touchmove",handleTouchMove,!1),document.addEventListener("keydown",handleKey,!1)}let listen=!1;class Align{constructor(t,e){if(this.center=t,e){let t=e[0],i=e[1];this.ct=Math.cos(t),this.st=Math.sin(t),this.cp=Math.cos(i),this.sp=Math.sin(i)}}T0(t){return[t[0]+this.center[0],t[1]+this.center[1],t[2]+this.center[2]]}T(t){let e=t[0],i=t[1],a=t[2],r=e*this.ct+a*this.st;return[r*this.cp-i*this.sp+this.center[0],r*this.sp+i*this.cp+this.center[1],-e*this.st+a*this.ct+this.center[2]]}}function Tcorners(t,e,i){let a=[t(e),t([e[0],e[1],i[2]]),t([e[0],i[1],e[2]]),t([e[0],i[1],i[2]]),t([i[0],e[1],e[2]]),t([i[0],e[1],i[2]]),t([i[0],i[1],e[2]]),t(i)];return[minbound(a),maxbound(a)]}function sphere(t,e,i,a,r){let n,s,o,h,l,d,c=[[[1,0,0],[1,0,.370106805057161],[.798938033457256,0,.6932530716149],[.500083269410627,0,.866169630634358],[1,.552284749830793,0],[1,.552284749830793,.370106805057161],[.798938033457256,.441241291938247,.6932530716149],[.500083269410627,.276188363341013,.866169630634358],[.552284749830793,1,0],[.552284749830793,1,.370106805057161],[.441241291938247,.798938033457256,.6932530716149],[.276188363341013,.500083269410627,.866169630634358],[0,1,0],[0,1,.370106805057161],[0,.798938033457256,.6932530716149],[0,.500083269410627,.866169630634358]],[[.500083269410627,0,.866169630634358],[.500083269410627,.276188363341013,.866169630634358],[.35297776917154,0,.951284475617087],[.276188363341013,.500083269410627,.866169630634358],[.264153721902467,.264153721902467,1],[.182177944773632,0,1],[0,.500083269410627,.866169630634358],[0,.35297776917154,.951284475617087],[0,.182177944773632,1],[0,0,1]]],m=new Align(t,r);function f(t){let e=Array(t.length);for(let i=0;i<t.length;++i){let a=t[i];e[i]=l([n*a[0],s*a[1],o*a[2]])}return e}r?(h=1,d=0,l=m.T.bind(m)):(h=-1,d=-e,l=m.T0.bind(m));let u=Tcorners(l,[-e,-e,d],[e,e,e]),p=u[0],v=u[1];for(let t=-1;t<=1;t+=2){n=t*e;for(let t=-1;t<=1;t+=2){s=t*e;for(let t=h;t<=1;t+=2){o=t*e;for(let t=0;t<2;++t)P.push(new BezierPatch(f(c[t]),i,a,p,v))}}}}let a=4/3*(Math.sqrt(2)-1);fu!
 nction disk(t,e,i,r,n){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]],h=new Align(t,n);let l=Tcorners(h.T.bind(h),[-e,-e,0],[e,e,0]);P.push(new BezierPatch(function(t){let i=Array(t.length);for(let a=0;a<t.length;++a){let r=t[a];i[a]=h.T([e*r[0],e*r[1],0])}return i}(o),i,r,l[0],l[1]))}function cylinder(t,e,i,r,n,s,o){let h,l,d=[[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]],c=new Align(t,s);function m(t){let e=Array(t.length);for(let a=0;a<t.length;++a){let r=t[a];e[a]=c.T([h*r[0],l*r[1],i*r[2]])}return e}let f=Tcorners(c.T.bind(c),[-e,-e,0],[e,e,i]),u=f[0],p=f[1];for(let t=-1;t<=1;t+=2){h=t*e;for(let t=-1;t<=1;t+=2)l=t*e,P.push(new BezierPatch(m(d),r,n,u,p))}if(o){let e=c.T([0,0,i]);P.push(new BezierCurve([t,e],r,n,t,e))}}function rmf(t,e,i,a,r){class n{constructor(t,e,i){this.p=t,this.r=e,this.t=i,this.s=cross(i,e)}}let s=Number.EPSILON*Math.max(abs2(t),abs2(e),abs2(i),abs2(a));function o(r){if(1==r){let r=[a[0]-i[0],a[1]-i[1],a[2]-i[2]];return abs2(r)>s?unit(r):abs2(r=[2*i[0]-e[0]-a[0],2*i[1]-e[1]-a[1],2*i[2]-e[2]-a[2]])>s?unit(r):[a[0]-t[0]+3*(e[0]-i[0]),a[1]-t[1]+3*(e[1]-i[1]),a[2]-t[2]+3*(e[2]-i[2])]}let n=[a[0]-t[0]+3*(e[0]-i[0]),a[1]-t[1]+3*(e[1]-i[1]),a[2]-t[2]+3*(e[2]-i[2])],o=[2*(t[0]+i[0])-4*e[0],2*(t[1]+i[1])-4*e[1],2*(t[2]+i[2])-4*e[2]],h=[e[0]-t[0],e[1]-t[1],e[2]-t[2]],l=r*r,d=[n[0]*l+o[0]*r+h[0],n[1]*l+o[1]*r+h[1],n[2]*l+o[2]*r+h[2]];return abs2(d)>s?unit(d):abs2(d=[n[0]*(l=2*r)+o[0],n[1]*l+o[1],n[2]*l+o[2]])>s?unit(d):unit(n)}let h=Array(r.length),l=[e[0]-t[0],e[1]-t[1],e[2]-t[2]];abs2(l)<s&&abs2(l=[t[0]-2*e[0]+i[0],t[1]-2*e[1]+i[1],t[2]-2*e[2]+i[2]])<s&&(l=[a[0]-t[0]+3*(e[0]-i[0]),a[1]-t[1]+3*(e[1]-i[1]),a[2]-t[2]+3*(e[2]-i[2])]);let d=function(t){let e=cross(t,[0,1,0]),i=Number.EPSILON*abs2(t);return abs2(e)>i?unit(e):abs2(e=cross(t,[0,0,1]))>i?unit(e):[1,0,0]}(l=unit(l));h[0]=new n(t,d,l!
 );for(let s=1;s<r.length;++s){let l=h[s-1],d=r[s],c=1-d,m=c*c,f=m*c,u=3*d;m*=u,c*=u*d;let p=d*d*d,v=[f*t[0]+m*e[0]+c*i[0]+p*a[0],f*t[1]+m*e[1]+c*i[1]+p*a[1],f*t[2]+m*e[2]+c*i[2]+p*a[2]],g=[v[0]-l.p[0],v[1]-l.p[1],v[2]-l.p[2]];if(0!=g[0]||0!=g[1]||0!=g[2]){let t=l.r,e=unit(g),i=l.t,a=dot(e,i),r=[i[0]-2*a*e[0],i[1]-2*a*e[1],i[2]-2*a*e[2]];i=o(d);let c=2*dot(e,t),m=[t[0]-c*e[0],t[1]-c*e[1],t[2]-c*e[2]],f=unit([i[0]-r[0],i[1]-r[1],i[2]-r[2]]),u=2*dot(f,m);m=[m[0]-u*f[0],m[1]-u*f[1],m[2]-u*f[2]],h[s]=new n(v,unit(m),unit(i))}else h[s]=h[s-1]}return h}function tube(t,e,i,r,n,s,o){let h=rmf(t[0],t[1],t[2],t[3],[0,1/3,2/3,1]),l=a*e,d=[[e,0],[e,l],[l,e],[0,e]];function c(e,a,o,l){let c=Array(16);for(let i=0;i<4;++i){let r=h[i],n=r.r[0],s=r.s[0],m=n*e+s*a,f=n*o+s*l,u=(n=r.r[1])*e+(s=r.s[1])*a,p=n*o+s*l,v=(n=r.r[2])*e+(s=r.s[2])*a,g=n*o+s*l,w=t[i],x=w[0];w1=w[1],w2=w[2];for(let t=0;t<4;++t){let e=d[t],a=e[0],r=e[1];c[4*i+t]=[m*a+f*r+x,u*a+p*r+w1,v*a+g*r+w2]}}P.push(new BezierPatch(c,i,r,n,s))}c(1,0,0,1),c(0,-1,1,0),c(-1,0,0,-1),c(0,1,-1,0),o&&P.push(new BezierCurve(t,i,r,n,s))}function webGLStart(){0==window.innerWidth||0==window.innerHeight?listen||(listen=!0,window.addEventListener("resize",webGLStart,!1)):(listen&&(window.removeEventListener("resize",webGLStart,!1),listen=!1),webGLInit())}

Modified: trunk/Build/source/utils/asymptote/beziercurve.cc
===================================================================
--- trunk/Build/source/utils/asymptote/beziercurve.cc	2020-03-03 22:33:26 UTC (rev 54033)
+++ trunk/Build/source/utils/asymptote/beziercurve.cc	2020-03-03 22:35:09 UTC (rev 54034)
@@ -20,12 +20,31 @@
   MaterialIndex=materialIndex;
 }
 
+inline triple normal(triple bP, triple bPP)
+{
+  return dot(bP,bP)*bPP-dot(bP,bPP)*bP;
+}
+
 void BezierCurve::render(const triple *p, bool straight) 
 {
-  GLuint i0=data.vertex1(p[0]);
-  GLuint i3=data.vertex1(p[3]);
-    
+  triple p0=p[0];
+  triple p3=p[3];
+  triple n0,n1;
+
   if(straight) {
+    n0=n1=triple(0.0,0.0,1.0);
+  } else {
+    triple p1=p[1];
+    triple p2=p[2];
+
+    n0=normal(p1-p0,p0+p2-2.0*p1);
+    n1=normal(p3-p2,p3+p1-2.0*p2);
+  }
+
+  GLuint i0=data.vertex(p0,n0);
+  GLuint i3=data.vertex(p3,n1);
+
+  if(straight) {
     std::vector<GLuint> &q=data.indices;
     q.push_back(i0);
     q.push_back(i3);
@@ -34,9 +53,9 @@
   append();
 }
   
-// Use a uniform partition to draw a Bezier patch.
+// Use a uniform partition to draw a Bezier curve.
 // p is an array of 4 triples representing the control points.
-// Ii are the vertices indices.
+// Ii are the vertex indices.
 void BezierCurve::render(const triple *p, GLuint I0, GLuint I1)
 {
   triple p0=p[0];
@@ -62,7 +81,8 @@
     triple s0[]={p0,m0,m3,m5};
     triple s1[]={m5,m4,m2,p3};
       
-    GLuint i0=data.vertex1(m5);
+    triple n0=normal(bezierPh(p0,p1,p2,p3),bezierPPh(p0,p1,p2,p3));
+    GLuint i0=data.vertex(m5,n0);
       
     render(s0,I0,i0);
     render(s1,i0,I1);

Modified: trunk/Build/source/utils/asymptote/beziercurve.h
===================================================================
--- trunk/Build/source/utils/asymptote/beziercurve.h	2020-03-03 22:33:26 UTC (rev 54033)
+++ trunk/Build/source/utils/asymptote/beziercurve.h	2020-03-03 22:35:09 UTC (rev 54034)
@@ -38,7 +38,7 @@
   void render(const triple *p, GLuint I0, GLuint I1);
   
   void append() {
-    material1Data.append1(data);
+    material1Data.append(data);
   }
   
   void queue(const triple *g, bool straight, double ratio) {

Modified: trunk/Build/source/utils/asymptote/bezierpatch.cc
===================================================================
--- trunk/Build/source/utils/asymptote/bezierpatch.cc	2020-03-03 22:33:26 UTC (rev 54033)
+++ trunk/Build/source/utils/asymptote/bezierpatch.cc	2020-03-03 22:35:09 UTC (rev 54034)
@@ -1,5 +1,5 @@
 /*****
- * drawbezierpatch.cc
+ * bezierpatch.cc
  * Authors: John C. Bowman and Jesse Frohlich
  *
  * Render Bezier patches and triangles.
@@ -53,7 +53,6 @@
 std::vector<iz> IZ;
 
 const double FillFactor=0.1;
-const double BezierFactor=0.4;
 
 inline int sgn1(double x) 
 {
@@ -162,20 +161,6 @@
   return a+(b-a)*t;
 }
 
-inline void cross(double *dest, const double *u, const double *v,
-                  const double *w)
-{
-  double u0=u[0]-w[0];
-  double u1=u[1]-w[1];
-  double u2=u[2]-w[2];
-  double v0=v[0]-w[0];
-  double v1=v[1]-w[1];
-  double v2=v[2]-w[2];
-  dest[0]=u1*v2-u2*v1;
-  dest[1]=u2*v0-u0*v2;
-  dest[2]=u0*v1-u1*v0;
-}
-
 unsigned n;
 unsigned int count;
   
@@ -285,7 +270,6 @@
 void BezierPatch::init(double res)
 {
   res2=res*res;
-  Res2=BezierFactor*BezierFactor*res2;
   Epsilon=FillFactor*res;
 
   MaterialIndex=transparent ?
@@ -300,7 +284,7 @@
   epsilon=0;
   for(unsigned i=1; i < 16; ++i)
     epsilon=max(epsilon,abs2(p[i]-p0));
-  epsilon *= Fuzz4;
+  epsilon *= DBL_EPSILON;
     
   triple p3=p[3];
   triple p12=p[12];
@@ -307,27 +291,27 @@
   triple p15=p[15];
 
   triple n0=normal(p3,p[2],p[1],p0,p[4],p[8],p12);
-  if(n0 == 0.0) {
+  if(abs2(n0) <= epsilon) {
     n0=normal(p3,p[2],p[1],p0,p[13],p[14],p15);
-    if(n0 == 0.0) n0=normal(p15,p[11],p[7],p3,p[4],p[8],p12);
+    if(abs2(n0) <= epsilon) n0=normal(p15,p[11],p[7],p3,p[4],p[8],p12);
   }
   
   triple n1=normal(p0,p[4],p[8],p12,p[13],p[14],p15);
-  if(n1 == 0.0) {
+  if(abs2(n1) <= epsilon) {
     n1=normal(p0,p[4],p[8],p12,p[11],p[7],p3);
-    if(n1 == 0.0) n1=normal(p3,p[2],p[1],p0,p[13],p[14],p15);
+    if(abs2(n1) <= epsilon) n1=normal(p3,p[2],p[1],p0,p[13],p[14],p15);
   }
     
   triple n2=normal(p12,p[13],p[14],p15,p[11],p[7],p3);
-  if(n2 == 0.0) {
+  if(abs2(n2) <= epsilon) {
     n2=normal(p12,p[13],p[14],p15,p[2],p[1],p0);
-    if(n2 == 0.0) n2=normal(p0,p[4],p[8],p12,p[11],p[7],p3);
+    if(abs2(n2) <= epsilon) n2=normal(p0,p[4],p[8],p12,p[11],p[7],p3);
   }
     
   triple n3=normal(p15,p[11],p[7],p3,p[2],p[1],p0);
-  if(n3 == 0.0) {
+  if(abs2(n3) <= epsilon) {
     n3=normal(p15,p[11],p[7],p3,p[4],p[8],p12);
-    if(n3 == 0.0) n3=normal(p12,p[13],p[14],p15,p[2],p[1],p0);
+    if(abs2(n3) <= epsilon) n3=normal(p12,p[13],p[14],p15,p[2],p[1],p0);
   }
     
   GLuint i0,i1,i2,i3;
@@ -382,7 +366,8 @@
                          bool flat0, bool flat1, bool flat2, bool flat3,
                          GLfloat *C0, GLfloat *C1, GLfloat *C2, GLfloat *C3)
 {
-  if(Distance(p) < res2) { // Bezier patch is flat
+  pair d=Distance(p);
+  if(d.getx() < res2 && d.gety() < res2) { // Bezier patch is flat
     triple Pa[]={P0,P1,P2};
     std::vector<GLuint> &q=data.indices;
     if(!offscreen(3,Pa)) {
@@ -398,14 +383,14 @@
     }
   } else { // Patch is not flat
    if(offscreen(16,p)) return;
-    /* Control points are indexed as follows:
-         
+
+   /* Control points are indexed as follows:
+
        Coordinate
        +-----
         Index
          
-
-       03    13    23    33
+        03    13    23    33
        +-----+-----+-----+
        |3    |7    |11   |15
        |     |     |     |
@@ -419,14 +404,201 @@
        |     |     |     |
        |00   |10   |20   |30
        +-----+-----+-----+
-       0     4     8     12
+        0     4     8     12
+
+   */
+
+    triple p0=p[0];
+    triple p3=p[3];
+    triple p12=p[12];
+    triple p15=p[15];
+
+   if(d.getx() < res2) { // flat in horizontal direction; split vertically
+     /*
+       P refers to a corner
+       m refers to a midpoint
+       s refers to a subpatch
+
+       +--------+--------+
+       |P3             P2|
+       |                 |
+       |       s1        |
+       |                 |
+       |                 |
+    m1 +-----------------+ m0
+       |                 |
+       |                 |
+       |       s0        |
+       |                 |
+       |P0             P1|
+       +-----------------+
+
+     */
+
+     Split3 c0(p0,p[1],p[2],p3);
+     Split3 c1(p[4],p[5],p[6],p[7]);
+     Split3 c2(p[8],p[9],p[10],p[11]);
+     Split3 c3(p12,p[13],p[14],p15);
+
+     triple s0[]={p0  ,c0.m0,c0.m3,c0.m5,
+                  p[4],c1.m0,c1.m3,c1.m5,
+                  p[8],c2.m0,c2.m3,c2.m5,
+                  p12 ,c3.m0,c3.m3,c3.m5};
+
+     triple s1[]={c0.m5,c0.m4,c0.m2,p3,
+                  c1.m5,c1.m4,c1.m2,p[7],
+                  c2.m5,c2.m4,c2.m2,p[11],
+                  c3.m5,c3.m4,c3.m2,p15};
+
+     triple n0=normal(s0[12],s0[13],s0[14],s0[15],s0[11],s0[7],s0[3]);
+     if(abs2(n0) <= epsilon) {
+       n0=normal(s0[12],s0[13],s0[14],s0[15],s0[2],s0[1],s0[0]);
+       if(abs2(n0) <= epsilon)
+         n0=normal(s0[0],s0[4],s0[8],s0[12],s0[11],s0[7],s0[3]);
+     }
+
+     triple n1=normal(s1[3],s1[2],s1[1],s1[0],s1[4],s1[8],s1[12]);
+     if(abs2(n1) <= epsilon) {
+       n1=normal(s1[3],s1[2],s1[1],s1[0],s1[13],s1[14],s1[15]);
+       if(abs2(n1) <= epsilon)
+         n1=normal(s1[15],s1[11],s1[7],s1[3],s1[4],s1[8],s1[12]);
+     }
+
+     // A kludge to remove subdivision cracks, only applied the first time
+     // an edge is found to be flat before the rest of the subpatch is.
+
+     triple m0=0.5*(P1+P2);
+     if(!flat1) {
+       if((flat1=Straightness(p12,p[13],p[14],p15) < res2))
+         m0 -= Epsilon*unit(differential(s1[12],s1[8],s1[4],s1[0]));
+       else m0=s0[15];
+     }
+
+     triple m1=0.5*(P3+P0);
+     if(!flat3) {
+       if((flat3=Straightness(p0,p[1],p[2],p3) < res2))
+         m1 -= Epsilon*unit(differential(s0[3],s0[7],s0[11],s0[15]));
+       else m1=s1[0];
+     }
+
+     if(color) {
+       GLfloat c0[4],c1[4];
+       for(size_t i=0; i < 4; ++i) {
+         c0[i]=0.5*(C1[i]+C2[i]);
+         c1[i]=0.5*(C3[i]+C0[i]);
+       }
+
+       GLuint i0=data.Vertex(m0,n0,c0);
+       GLuint i1=data.Vertex(m1,n1,c1);
+
+       render(s0,I0,I1,i0,i1,P0,P1,m0,m1,flat0,flat1,false,flat3,C0,C1,c0,c1);
+       render(s1,i1,i0,I2,I3,m1,m0,P2,P3,false,flat1,flat2,flat3,c1,c0,C2,C3);
+     } else {
+       GLuint i0=(data.*pvertex)(m0,n0);
+       GLuint i1=(data.*pvertex)(m1,n1);
+
+       render(s0,I0,I1,i0,i1,P0,P1,m0,m1,flat0,flat1,false,flat3);
+       render(s1,i1,i0,I2,I3,m1,m0,P2,P3,false,flat1,flat2,flat3);
+     }
+     return;
+   }
+   if(d.gety() < res2) { // flat in vertical direction; split horizontally
+     /*
+       P refers to a corner
+       m refers to a midpoint
+       s refers to a subpatch
          
+                m1
+       +--------+--------+
+       |P3      |      P2|
+       |        |        |
+       |        |        |
+       |        |        |
+       |        |        |
+       |   s0   |   s1   |
+       |        |        |
+       |        |        |
+       |        |        |
+       |        |        |
+       |P0      |      P1|
+       +--------+--------+
+                m0
 
-       Subdivision:
+     */
+
+     Split3 c0(p0,p[4],p[8],p12);
+     Split3 c1(p[1],p[5],p[9],p[13]);
+     Split3 c2(p[2],p[6],p[10],p[14]);
+     Split3 c3(p3,p[7],p[11],p15);
+
+     triple s0[]={p0,p[1],p[2],p3,
+                  c0.m0,c1.m0,c2.m0,c3.m0,
+                  c0.m3,c1.m3,c2.m3,c3.m3,
+                  c0.m5,c1.m5,c2.m5,c3.m5};
+
+     triple s1[]={c0.m5,c1.m5,c2.m5,c3.m5,
+                  c0.m4,c1.m4,c2.m4,c3.m4,
+                  c0.m2,c1.m2,c2.m2,c3.m2,
+                  p12,p[13],p[14],p15};
+
+     triple n0=normal(s0[0],s0[4],s0[8],s0[12],s0[13],s0[14],s0[15]);
+     if(abs2(n0) <= epsilon) {
+       n0=normal(s0[0],s0[4],s0[8],s0[12],s0[11],s0[7],s0[3]);
+       if(abs2(n0) <= epsilon)
+         n0=normal(s0[3],s0[2],s0[1],s0[0],s0[13],s0[14],s0[15]);
+     }
+
+     triple n1=normal(s1[15],s1[11],s1[7],s1[3],s1[2],s1[1],s1[0]);
+     if(abs2(n1) <= epsilon) {
+       n1=normal(s1[15],s1[11],s1[7],s1[3],s1[4],s1[8],s1[12]);
+       if(abs2(n1) <= epsilon)
+         n1=normal(s1[12],s1[13],s1[14],s1[15],s1[2],s1[1],s1[0]);
+     }
+
+     // A kludge to remove subdivision cracks, only applied the first time
+     // an edge is found to be flat before the rest of the subpatch is.
+
+     triple m0=0.5*(P0+P1);
+     if(!flat0) {
+       if((flat0=Straightness(p0,p[4],p[8],p12) < res2))
+         m0 -= Epsilon*unit(differential(s1[0],s1[1],s1[2],s1[3]));
+       else m0=s0[12];
+     }
+
+     triple m1=0.5*(P2+P3);
+     if(!flat2) {
+       if((flat2=Straightness(p15,p[11],p[7],p3) < res2))
+         m1 -= Epsilon*unit(differential(s0[15],s0[14],s0[13],s0[12]));
+       else m1=s1[3];
+     }
+
+     if(color) {
+       GLfloat c0[4],c1[4];
+       for(size_t i=0; i < 4; ++i) {
+         c0[i]=0.5*(C0[i]+C1[i]);
+         c1[i]=0.5*(C2[i]+C3[i]);
+       }
+
+       GLuint i0=data.Vertex(m0,n0,c0);
+       GLuint i1=data.Vertex(m1,n1,c1);
+
+       render(s0,I0,i0,i1,I3,P0,m0,m1,P3,flat0,false,flat2,flat3,C0,c0,c1,C3);
+       render(s1,i0,I1,I2,i1,m0,P1,P2,m1,flat0,flat1,flat2,false,c0,C1,C2,c1);
+     } else {
+       GLuint i0=(data.*pvertex)(m0,n0);
+       GLuint i1=(data.*pvertex)(m1,n1);
+
+       render(s0,I0,i0,i1,I3,P0,m0,m1,P3,flat0,false,flat2,flat3);
+       render(s1,i0,I1,I2,i1,m0,P1,P2,m1,flat0,flat1,flat2,false);
+     }
+     return;
+   }
+   /*
+       Horizontal and vertical subdivision:
        P refers to a corner
        m refers to a midpoint
        s refers to a subpatch
-         
+
                 m2
        +--------+--------+
        |P3      |      P2|
@@ -433,8 +605,8 @@
        |        |        |
        |   s3   |   s2   |
        |        |        |
-       |        |m4      |
-     m3+--------+--------+m1
+       |        | m4     |
+    m3 +--------+--------+ m1
        |        |        |
        |        |        |
        |   s0   |   s1   |
@@ -445,11 +617,6 @@
     */
     
     // Subdivide patch:
-    triple p0=p[0];
-    triple p3=p[3];
-    triple p12=p[12];
-    triple p15=p[15];
-      
     Split3 c0(p0,p[1],p[2],p3);
     Split3 c1(p[4],p[5],p[6],p[7]);
     Split3 c2(p[8],p[9],p[10],p[11]);
@@ -475,27 +642,31 @@
     triple m4=s0[15];
       
     triple n0=normal(s0[0],s0[4],s0[8],s0[12],s0[13],s0[14],s0[15]);
-    if(n0 == 0.0) {
+    if(abs2(n0) <= epsilon) {
       n0=normal(s0[0],s0[4],s0[8],s0[12],s0[11],s0[7],s0[3]);
-      if(n0 == 0.0) n0=normal(s0[3],s0[2],s0[1],s0[0],s0[13],s0[14],s0[15]);
+      if(abs2(n0) <= epsilon)
+        n0=normal(s0[3],s0[2],s0[1],s0[0],s0[13],s0[14],s0[15]);
     }
       
     triple n1=normal(s1[12],s1[13],s1[14],s1[15],s1[11],s1[7],s1[3]);
-    if(n1 == 0.0) {
+    if(abs2(n1) <= epsilon) {
       n1=normal(s1[12],s1[13],s1[14],s1[15],s1[2],s1[1],s1[0]);
-      if(n1 == 0.0) n1=normal(s1[0],s1[4],s1[8],s1[12],s1[11],s1[7],s1[3]);
+      if(abs2(n1) <= epsilon)
+        n1=normal(s1[0],s1[4],s1[8],s1[12],s1[11],s1[7],s1[3]);
     }
       
     triple n2=normal(s2[15],s2[11],s2[7],s2[3],s2[2],s2[1],s2[0]);
-    if(n2 == 0.0) {
+    if(abs2(n2) <= epsilon) {
       n2=normal(s2[15],s2[11],s2[7],s2[3],s2[4],s2[8],s2[12]);
-      if(n2 == 0.0) n2=normal(s2[12],s2[13],s2[14],s2[15],s2[2],s2[1],s2[0]);
+      if(abs2(n2) <= epsilon)
+        n2=normal(s2[12],s2[13],s2[14],s2[15],s2[2],s2[1],s2[0]);
     }
       
     triple n3=normal(s3[3],s3[2],s3[1],s3[0],s3[4],s3[8],s3[12]);
-    if(n3 == 0.0) {
+    if(abs2(n3) <= epsilon) {
       n3=normal(s3[3],s3[2],s3[1],s3[0],s3[13],s3[14],s3[15]);
-      if(n3 == 0.0) n3=normal(s3[15],s3[11],s3[7],s3[3],s3[4],s3[8],s3[12]);
+      if(abs2(n3) <= epsilon)
+        n3=normal(s3[15],s3[11],s3[7],s3[3],s3[4],s3[8],s3[12]);
     }
       
     triple n4=normal(s2[3],s2[2],s2[1],m4,s2[4],s2[8],s2[12]);
@@ -506,7 +677,7 @@
     triple m0=0.5*(P0+P1);
     if(!flat0) {
       if((flat0=Straightness(p0,p[4],p[8],p12) < res2))
-        m0 -= Epsilon*unit(derivative(s1[0],s1[1],s1[2],s1[3]));
+        m0 -= Epsilon*unit(differential(s1[0],s1[1],s1[2],s1[3]));
       else m0=s0[12];
     }
       
@@ -513,7 +684,7 @@
     triple m1=0.5*(P1+P2);
     if(!flat1) {
       if((flat1=Straightness(p12,p[13],p[14],p15) < res2))
-        m1 -= Epsilon*unit(derivative(s2[12],s2[8],s2[4],s2[0]));
+        m1 -= Epsilon*unit(differential(s2[12],s2[8],s2[4],s2[0]));
       else m1=s1[15];
     }
       
@@ -520,7 +691,7 @@
     triple m2=0.5*(P2+P3);
     if(!flat2) {
       if((flat2=Straightness(p15,p[11],p[7],p3) < res2))
-        m2 -= Epsilon*unit(derivative(s3[15],s2[14],s2[13],s1[12]));
+        m2 -= Epsilon*unit(differential(s3[15],s3[14],s3[13],s3[12]));
       else m2=s2[3];
     }
       
@@ -527,7 +698,7 @@
     triple m3=0.5*(P3+P0);
     if(!flat3) {
       if((flat3=Straightness(p0,p[1],p[2],p3) < res2))
-        m3 -= Epsilon*unit(derivative(s0[3],s0[7],s0[11],s0[15]));
+        m3 -= Epsilon*unit(differential(s0[3],s0[7],s0[11],s0[15]));
       else m3=s3[0];
     }
       
@@ -547,14 +718,10 @@
       GLuint i3=data.Vertex(m3,n3,c3);
       GLuint i4=data.Vertex(m4,n4,c4);
       
-      render(s0,I0,i0,i4,i3,P0,m0,m4,m3,flat0,false,false,flat3,
-             C0,c0,c4,c3);
-      render(s1,i0,I1,i1,i4,m0,P1,m1,m4,flat0,flat1,false,false,
-             c0,C1,c1,c4);
-      render(s2,i4,i1,I2,i2,m4,m1,P2,m2,false,flat1,flat2,false,
-             c4,c1,C2,c2);
-      render(s3,i3,i4,i2,I3,m3,m4,m2,P3,false,false,flat2,flat3,
-             c3,c4,c2,C3);
+      render(s0,I0,i0,i4,i3,P0,m0,m4,m3,flat0,false,false,flat3,C0,c0,c4,c3);
+      render(s1,i0,I1,i1,i4,m0,P1,m1,m4,flat0,flat1,false,false,c0,C1,c1,c4);
+      render(s2,i4,i1,I2,i2,m4,m1,P2,m2,false,flat1,flat2,false,c4,c1,C2,c2);
+      render(s3,i3,i4,i2,I3,m3,m4,m2,P3,false,false,flat2,flat3,c3,c4,c2,C3);
     } else {
       GLuint i0=(data.*pvertex)(m0,n0);
       GLuint i1=(data.*pvertex)(m1,n1);
@@ -577,7 +744,7 @@
   for(int i=1; i < 10; ++i)
     epsilon=max(epsilon,abs2(p[i]-p0));
   
-  epsilon *= Fuzz4;
+  epsilon *= DBL_EPSILON;
     
   triple p6=p[6];
   triple p9=p[9];
@@ -628,7 +795,7 @@
                             bool flat0, bool flat1, bool flat2,
                             GLfloat *C0, GLfloat *C1, GLfloat *C2)
 {
-  if(Distance(p) < Res2) { // Bezier triangle is flat
+  if(Distance(p) < res2) { // Bezier triangle is flat
     triple P[]={P0,P1,P2};
     if(!offscreen(3,P)) {
       std::vector<GLuint> &q=data.indices;
@@ -763,8 +930,8 @@
     triple m0=0.5*(P1+P2);
     if(!flat0) {
       if((flat0=Straightness(r300,p210,p120,u030) < res2))
-        m0 -= Epsilon*unit(derivative(c[0],c[2],c[5],c[9])+
-                           derivative(c[0],c[1],c[3],c[6]));
+        m0 -= Epsilon*unit(differential(c[0],c[2],c[5],c[9])+
+                           differential(c[0],c[1],c[3],c[6]));
       else m0=r030;
     }
 
@@ -771,8 +938,8 @@
     triple m1=0.5*(P2+P0);
     if(!flat1) {
       if((flat1=Straightness(l003,p012,p021,u030) < res2))
-        m1 -= Epsilon*unit(derivative(c[6],c[3],c[1],c[0])+
-                           derivative(c[6],c[7],c[8],c[9]));
+        m1 -= Epsilon*unit(differential(c[6],c[3],c[1],c[0])+
+                           differential(c[6],c[7],c[8],c[9]));
       else m1=l030;
     }
 
@@ -779,8 +946,8 @@
     triple m2=0.5*(P0+P1);
     if(!flat2) {
       if((flat2=Straightness(l003,p102,p201,r300) < res2))
-        m2 -= Epsilon*unit(derivative(c[9],c[8],c[7],c[6])+
-                           derivative(c[9],c[5],c[2],c[0]));
+        m2 -= Epsilon*unit(differential(c[9],c[8],c[7],c[6])+
+                           differential(c[9],c[5],c[2],c[0]));
       else m2=l300;
     }
 

Modified: trunk/Build/source/utils/asymptote/bezierpatch.h
===================================================================
--- trunk/Build/source/utils/asymptote/bezierpatch.h	2020-03-03 22:33:26 UTC (rev 54033)
+++ trunk/Build/source/utils/asymptote/bezierpatch.h	2020-03-03 22:35:09 UTC (rev 54034)
@@ -14,8 +14,6 @@
 
 #ifdef HAVE_GL
 
-extern const double Fuzz4;
-
 struct BezierPatch
 {
   vertexBuffer data;
@@ -35,61 +33,71 @@
     
   triple normal(triple left3, triple left2, triple left1, triple middle,
                 triple right1, triple right2, triple right3) {
-    triple rp=right1-middle;
-    triple lp=left1-middle;
-    triple n=triple(rp.gety()*lp.getz()-rp.getz()*lp.gety(),
-                    rp.getz()*lp.getx()-rp.getx()*lp.getz(),
-                    rp.getx()*lp.gety()-rp.gety()*lp.getx());
+    triple lp=3.0*(left1-middle);
+    triple rp=3.0*(right1-middle);
+
+    triple n=cross(rp,lp);
     if(abs2(n) > epsilon)
-      return unit(n);
-    
+      return n;
+
     triple lpp=bezierPP(middle,left1,left2);
     triple rpp=bezierPP(middle,right1,right2);
+
     n=cross(rpp,lp)+cross(rp,lpp);
     if(abs2(n) > epsilon)
-      return unit(n);
-    
+      return n;
+
     triple lppp=bezierPPP(middle,left1,left2,left3);
     triple rppp=bezierPPP(middle,right1,right2,right3);
-    
-    return unit(9.0*cross(rpp,lpp)+
-                3.0*(cross(rp,lppp)+cross(rppp,lp)+
-                     cross(rppp,lpp)+cross(rpp,lppp))+
-                cross(rppp,lppp));
+
+    n=cross(rpp,lpp)+cross(rppp,lp)+cross(rp,lppp);
+    if(abs2(n) > epsilon)
+      return n;
+
+    n=cross(rppp,lpp)+cross(rpp,lppp);
+    if(abs2(n) > epsilon)
+      return n;
+
+    return cross(rppp,lppp);
   }
 
-  triple derivative(triple p0, triple p1, triple p2, triple p3) {
-    triple lp=p1-p0;
-    if(abs2(lp) > epsilon)
-      return lp;
+  // Return the differential of the Bezier curve p0,p1,p2,p3 at 0
+  triple differential(triple p0, triple p1, triple p2, triple p3) {
+    triple p=p1-p0;
+    if(abs2(p) > epsilon)
+      return p;
     
-    triple lpp=bezierPP(p0,p1,p2);
-    if(abs2(lpp) > epsilon)
-      return lpp;
+    p=bezierPP(p0,p1,p2);
+    if(abs2(p) > epsilon)
+      return p;
     
     return bezierPPP(p0,p1,p2,p3);
   }
 
-  virtual double Distance(const triple *p) {
+  // Determine the flatness of a Bezier patch.
+  pair Distance(const triple *p) {
     triple p0=p[0];
     triple p3=p[3];
     triple p12=p[12];
     triple p15=p[15];
+
+    // Check the horizontal flatness.
+    double h=Flatness(p0,p12,p3,p15);
+    // Check straightness of the horizontal edges and interior control curves.
+    h=max(h,Straightness(p0,p[4],p[8],p12));
+    h=max(h,Straightness(p[1],p[5],p[9],p[13]));
+    h=max(h,Straightness(p[2],p[6],p[10],p[14]));
+    h=max(h,Straightness(p3,p[7],p[11],p15));
+
+    // Check the vertical flatness.
+    double v=Flatness(p0,p3,p12,p15);
+    // Check straightness of the vertical edges and interior control curves.
+    v=max(v,Straightness(p0,p[1],p[2],p3));
+    v=max(v,Straightness(p[4],p[5],p[6],p[7]));
+    v=max(v,Straightness(p[8],p[9],p[10],p[11]));
+    v=max(v,Straightness(p12,p[13],p[14],p15));
     
-    // Check the flatness of a Bezier patch.
-    double d=Distance2(p15,p0,normal(p3,p[2],p[1],p0,p[4],p[8],p12));
-    
-    // Determine how straight the edges are.
-    d=max(d,Straightness(p0,p[1],p[2],p3));
-    d=max(d,Straightness(p0,p[4],p[8],p12));
-    d=max(d,Straightness(p3,p[7],p[11],p15));
-    d=max(d,Straightness(p12,p[13],p[14],p15));
-    
-    // Determine how straight the interior control curves are.
-    d=max(d,Straightness(p[4],p[5],p[6],p[7]));
-    d=max(d,Straightness(p[8],p[9],p[10],p[11]));
-    d=max(d,Straightness(p[1],p[5],p[9],p[13]));
-    return max(d,Straightness(p[2],p[6],p[10],p[14]));
+    return pair(h,v);
   }
   
   struct Split3 {

Modified: trunk/Build/source/utils/asymptote/common.h
===================================================================
--- trunk/Build/source/utils/asymptote/common.h	2020-03-03 22:33:26 UTC (rev 54033)
+++ trunk/Build/source/utils/asymptote/common.h	2020-03-03 22:35:09 UTC (rev 54034)
@@ -17,10 +17,15 @@
 #endif
 
 #if !defined(FOR_SHARED) && \
-  ((defined(HAVE_LIBGL) && defined(HAVE_LIBGLUT) && defined(HAVE_LIBGLM)) || defined(HAVE_LIBOSMESA))
+  ((defined(HAVE_LIBGL) && defined(HAVE_LIBGLUT) && defined(HAVE_LIBGLM)) || \
+   defined(HAVE_LIBOSMESA))
 #define HAVE_GL
 #endif
 
+#if defined(HAVE_LIBREADLINE) || defined(HAVE_LIBEDIT)
+#define HAVE_READLINE
+#endif
+
 #ifdef HAVE_PTHREAD
 #include <pthread.h>
 #endif

Modified: trunk/Build/source/utils/asymptote/config.guess
===================================================================
--- trunk/Build/source/utils/asymptote/config.guess	2020-03-03 22:33:26 UTC (rev 54033)
+++ trunk/Build/source/utils/asymptote/config.guess	2020-03-03 22:35:09 UTC (rev 54034)
@@ -1474,3 +1474,163 @@
 # time-stamp-format: "%:y-%02m-%02d"
 # time-stamp-end: "'"
 # End:
+CTURE__)
+#define __ARCHITECTURE__ "m68k"
+#endif
+  int version;
+  version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`;
+  if (version < 4)
+    printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version);
+  else
+    printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version);
+  exit (0);
+#endif
+
+#if defined (MULTIMAX) || defined (n16)
+#if defined (UMAXV)
+  printf ("ns32k-encore-sysv\n"); exit (0);
+#else
+#if defined (CMU)
+  printf ("ns32k-encore-mach\n"); exit (0);
+#else
+  printf ("ns32k-encore-bsd\n"); exit (0);
+#endif
+#endif
+#endif
+
+#if defined (__386BSD__)
+  printf ("i386-pc-bsd\n"); exit (0);
+#endif
+
+#if defined (sequent)
+#if defined (i386)
+  printf ("i386-sequent-dynix\n"); exit (0);
+#endif
+#if defined (ns32000)
+  printf ("ns32k-sequent-dynix\n"); exit (0);
+#endif
+#endif
+
+#if defined (_SEQUENT_)
+  struct utsname un;
+
+  uname(&un);
+  if (strncmp(un.version, "V2", 2) == 0) {
+    printf ("i386-sequent-ptx2\n"); exit (0);
+  }
+  if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */
+    printf ("i386-sequent-ptx1\n"); exit (0);
+  }
+  printf ("i386-sequent-ptx\n"); exit (0);
+#endif
+
+#if defined (vax)
+#if !defined (ultrix)
+#include <sys/param.h>
+#if defined (BSD)
+#if BSD == 43
+  printf ("vax-dec-bsd4.3\n"); exit (0);
+#else
+#if BSD == 199006
+  printf ("vax-dec-bsd4.3reno\n"); exit (0);
+#else
+  printf ("vax-dec-bsd\n"); exit (0);
+#endif
+#endif
+#else
+  printf ("vax-dec-bsd\n"); exit (0);
+#endif
+#else
+#if defined(_SIZE_T_) || defined(SIGLOST)
+  struct utsname un;
+  uname (&un);
+  printf ("vax-dec-ultrix%s\n", un.release); exit (0);
+#else
+  printf ("vax-dec-ultrix\n"); exit (0);
+#endif
+#endif
+#endif
+#if defined(ultrix) || defined(_ultrix) || defined(__ultrix) || defined(__ultrix__)
+#if defined(mips) || defined(__mips) || defined(__mips__) || defined(MIPS) || defined(__MIPS__)
+#if defined(_SIZE_T_) || defined(SIGLOST)
+  struct utsname *un;
+  uname (&un);
+  printf ("mips-dec-ultrix%s\n", un.release); exit (0);
+#else
+  printf ("mips-dec-ultrix\n"); exit (0);
+#endif
+#endif
+#endif
+
+#if defined (alliant) && defined (i860)
+  printf ("i860-alliant-bsd\n"); exit (0);
+#endif
+
+  exit (1);
+}
+EOF
+
+$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.
+test -d /usr/apollo && { echo "$ISP-apollo-$SYSTYPE"; exit; }
+
+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
+	;;
+esac
+
+cat >&2 <<EOF
+
+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:
+
+  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:

Modified: trunk/Build/source/utils/asymptote/config.h.in
===================================================================
--- trunk/Build/source/utils/asymptote/config.h.in	2020-03-03 22:33:26 UTC (rev 54033)
+++ trunk/Build/source/utils/asymptote/config.h.in	2020-03-03 22:35:09 UTC (rev 54034)
@@ -15,6 +15,9 @@
 /* Define to 1 if you have the `dup2' function. */
 #undef HAVE_DUP2
 
+/* Define to 1 if you have the <editline/readline.h> header file. */
+#undef HAVE_EDITLINE_READLINE_H
+
 /* Define to 1 if you have the `feenableexcept' function. */
 #undef HAVE_FEENABLEEXCEPT
 
@@ -45,6 +48,9 @@
 /* Define to 1 if you have the `ncurses' library (-lncurses). */
 #undef HAVE_LIBCURSES
 
+/* Define to 1 if you have the `edit' library (-ledit). */
+#undef HAVE_LIBEDIT
+
 /* Define to 1 if you have the `fftw3' library (-lfftw3). */
 #undef HAVE_LIBFFTW3
 
@@ -111,6 +117,9 @@
 /* Define to 1 if you have the <ncurses.h> header file. */
 #undef HAVE_NCURSES_H
 
+/* Define to 1 if you have the `popcount' function. */
+#undef HAVE_POPCOUNT
+
 /* Define if you have POSIX threads libraries and header files. */
 #undef HAVE_PTHREAD
 

Modified: trunk/Build/source/utils/asymptote/config.sub
===================================================================
--- trunk/Build/source/utils/asymptote/config.sub	2020-03-03 22:33:26 UTC (rev 54033)
+++ trunk/Build/source/utils/asymptote/config.sub	2020-03-03 22:35:09 UTC (rev 54034)
@@ -1,8 +1,8 @@
 #! /bin/sh
 # Configuration validation subroutine script.
-#   Copyright 1992-2018 Free Software Foundation, Inc.
+#   Copyright 1992-2020 Free Software Foundation, Inc.
 
-timestamp='2018-03-08'
+timestamp='2020-01-01'
 
 # 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
@@ -67,7 +67,7 @@
 version="\
 GNU config.sub ($timestamp)
 
-Copyright 1992-2018 Free Software Foundation, Inc.
+Copyright 1992-2020 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."
@@ -89,7 +89,7 @@
     - )	# Use stdin as input.
        break ;;
     -* )
-       echo "$me: invalid option $1$help"
+       echo "$me: invalid option $1$help" >&2
        exit 1 ;;
 
     *local*)
@@ -110,1223 +110,1164 @@
     exit 1;;
 esac
 
-# Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any).
-# Here we must recognize all the valid KERNEL-OS combinations.
-maybe_os=`echo "$1" | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'`
-case $maybe_os in
-  nto-qnx* | linux-gnu* | linux-android* | linux-dietlibc | linux-newlib* | \
-  linux-musl* | linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | \
-  knetbsd*-gnu* | netbsd*-gnu* | netbsd*-eabi* | \
-  kopensolaris*-gnu* | cloudabi*-eabi* | \
-  storm-chaos* | os2-emx* | rtmk-nova*)
-    os=-$maybe_os
-    basic_machine=`echo "$1" | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`
-    ;;
-  android-linux)
-    os=-linux-android
-    basic_machine=`echo "$1" | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`-unknown
-    ;;
-  *)
-    basic_machine=`echo "$1" | sed 's/-[^-]*$//'`
-    if [ "$basic_machine" != "$1" ]
-    then os=`echo "$1" | sed 's/.*-/-/'`
-    else os=; fi
-    ;;
-esac
+# Split fields of configuration type
+# shellcheck disable=SC2162
+IFS="-" read field1 field2 field3 field4 <<EOF
+$1
+EOF
 
-### Let's recognize common machines as not being operating systems so
-### that things like config.sub decstation-3100 work.  We also
-### recognize some manufacturers as not being operating systems, so we
-### can provide default operating systems below.
-case $os in
-	-sun*os*)
-		# Prevent following clause from handling this invalid input.
+# Separate into logical components for further validation
+case $1 in
+	*-*-*-*-*)
+		echo Invalid configuration \`"$1"\': more than four components >&2
+		exit 1
 		;;
-	-dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \
-	-att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \
-	-unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \
-	-convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\
-	-c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \
-	-harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \
-	-apple | -axis | -knuth | -cray | -microblaze*)
-		os=
-		basic_machine=$1
+	*-*-*-*)
+		basic_machine=$field1-$field2
+		os=$field3-$field4
 		;;
-	-bluegene*)
-		os=-cnk
+	*-*-*)
+		# Ambiguous whether COMPANY is present, or skipped and KERNEL-OS is two
+		# parts
+		maybe_os=$field2-$field3
+		case $maybe_os in
+			nto-qnx* | linux-gnu* | linux-android* | linux-dietlibc \
+			| linux-newlib* | linux-musl* | linux-uclibc* | uclinux-uclibc* \
+			| uclinux-gnu* | kfreebsd*-gnu* | knetbsd*-gnu* | netbsd*-gnu* \
+			| netbsd*-eabi* | kopensolaris*-gnu* | cloudabi*-eabi* \
+			| storm-chaos* | os2-emx* | rtmk-nova*)
+				basic_machine=$field1
+				os=$maybe_os
+				;;
+			android-linux)
+				basic_machine=$field1-unknown
+				os=linux-android
+				;;
+			*)
+				basic_machine=$field1-$field2
+				os=$field3
+				;;
+		esac
 		;;
-	-sim | -cisco | -oki | -wec | -winbond)
-		os=
-		basic_machine=$1
+	*-*)
+		# A lone config we happen to match not fitting any pattern
+		case $field1-$field2 in
+			decstation-3100)
+				basic_machine=mips-dec
+				os=
+				;;
+			*-*)
+				# Second component is usually, but not always the OS
+				case $field2 in
+					# Prevent following clause from handling this valid os
+					sun*os*)
+						basic_machine=$field1
+						os=$field2
+						;;
+					# Manufacturers
+					dec* | mips* | sequent* | encore* | pc533* | sgi* | sony* \
+					| att* | 7300* | 3300* | delta* | motorola* | sun[234]* \
+					| unicom* | ibm* | next | hp | isi* | apollo | altos* \
+					| convergent* | ncr* | news | 32* | 3600* | 3100* \
+					| hitachi* | c[123]* | convex* | sun | crds | omron* | dg \
+					| ultra | tti* | harris | dolphin | highlevel | gould \
+					| cbm | ns | masscomp | apple | axis | knuth | cray \
+					| microblaze* | sim | cisco \
+					| oki | wec | wrs | winbond)
+						basic_machine=$field1-$field2
+						os=
+						;;
+					*)
+						basic_machine=$field1
+						os=$field2
+						;;
+				esac
+			;;
+		esac
 		;;
-	-scout)
+	*)
+		# Convert single-component short-hands not valid as part of
+		# multi-component configurations.
+		case $field1 in
+			386bsd)
+				basic_machine=i386-pc
+				os=bsd
+				;;
+			a29khif)
+				basic_machine=a29k-amd
+				os=udi
+				;;
+			adobe68k)
+				basic_machine=m68010-adobe
+				os=scout
+				;;
+			alliant)
+				basic_machine=fx80-alliant
+				os=
+				;;
+			altos | altos3068)
+				basic_machine=m68k-altos
+				os=
+				;;
+			am29k)
+				basic_machine=a29k-none
+				os=bsd
+				;;
+			amdahl)
+				basic_machine=580-amdahl
+				os=sysv
+				;;
+			amiga)
+				basic_machine=m68k-unknown
+				os=
+				;;
+			amigaos | amigados)
+				basic_machine=m68k-unknown
+				os=amigaos
+				;;
+			amigaunix | amix)
+				basic_machine=m68k-unknown
+				os=sysv4
+				;;
+			apollo68)
+				basic_machine=m68k-apollo
+				os=sysv
+				;;
+			apollo68bsd)
+				basic_machine=m68k-apollo
+				os=bsd
+				;;
+			aros)
+				basic_machine=i386-pc
+				os=aros
+				;;
+			aux)
+				basic_machine=m68k-apple
+				os=aux
+				;;
+			balance)
+				basic_machine=ns32k-sequent
+				os=dynix
+				;;
+			blackfin)
+				basic_machine=bfin-unknown
+				os=linux
+				;;
+			cegcc)
+				basic_machine=arm-unknown
+				os=cegcc
+				;;
+			convex-c1)
+				basic_machine=c1-convex
+				os=bsd
+				;;
+			convex-c2)
+				basic_machine=c2-convex
+				os=bsd
+				;;
+			convex-c32)
+				basic_machine=c32-convex
+				os=bsd
+				;;
+			convex-c34)
+				basic_machine=c34-convex
+				os=bsd
+				;;
+			convex-c38)
+				basic_machine=c38-convex
+				os=bsd
+				;;
+			cray)
+				basic_machine=j90-cray
+				os=unicos
+				;;
+			crds | unos)
+				basic_machine=m68k-crds
+				os=
+				;;
+			da30)
+				basic_machine=m68k-da30
+				os=
+				;;
+			decstation | pmax | pmin | dec3100 | decstatn)
+				basic_machine=mips-dec
+				os=
+				;;
+			delta88)
+				basic_machine=m88k-motorola
+				os=sysv3
+				;;
+			dicos)
+				basic_machine=i686-pc
+				os=dicos
+				;;
+			djgpp)
+				basic_machine=i586-pc
+				os=msdosdjgpp
+				;;
+			ebmon29k)
+				basic_machine=a29k-amd
+				os=ebmon
+				;;
+			es1800 | OSE68k | ose68k | ose | OSE)
+				basic_machine=m68k-ericsson
+				os=ose
+				;;
+			gmicro)
+				basic_machine=tron-gmicro
+				os=sysv
+				;;
+			go32)
+				basic_machine=i386-pc
+				os=go32
+				;;
+			h8300hms)
+				basic_machine=h8300-hitachi
+				os=hms
+				;;
+			h8300xray)
+				basic_machine=h8300-hitachi
+				os=xray
+				;;
+			h8500hms)
+				basic_machine=h8500-hitachi
+				os=hms
+				;;
+			harris)
+				basic_machine=m88k-harris
+				os=sysv3
+				;;
+			hp300 | hp300hpux)
+				basic_machine=m68k-hp
+				os=hpux
+				;;
+			hp300bsd)
+				basic_machine=m68k-hp
+				os=bsd
+				;;
+			hppaosf)
+				basic_machine=hppa1.1-hp
+				os=osf
+				;;
+			hppro)
+				basic_machine=hppa1.1-hp
+				os=proelf
+				;;
+			i386mach)
+				basic_machine=i386-mach
+				os=mach
+				;;
+			isi68 | isi)
+				basic_machine=m68k-isi
+				os=sysv
+				;;
+			m68knommu)
+				basic_machine=m68k-unknown
+				os=linux
+				;;
+			magnum | m3230)
+				basic_machine=mips-mips
+				os=sysv
+				;;
+			merlin)
+				basic_machine=ns32k-utek
+				os=sysv
+				;;
+			mingw64)
+				basic_machine=x86_64-pc
+				os=mingw64
+				;;
+			mingw32)
+				basic_machine=i686-pc
+				os=mingw32
+				;;
+			mingw32ce)
+				basic_machine=arm-unknown
+				os=mingw32ce
+				;;
+			monitor)
+				basic_machine=m68k-rom68k
+				os=coff
+				;;
+			morphos)
+				basic_machine=powerpc-unknown
+				os=morphos
+				;;
+			moxiebox)
+				basic_machine=moxie-unknown
+				os=moxiebox
+				;;
+			msdos)
+				basic_machine=i386-pc
+				os=msdos
+				;;
+			msys)
+				basic_machine=i686-pc
+				os=msys
+				;;
+			mvs)
+				basic_machine=i370-ibm
+				os=mvs
+				;;
+			nacl)
+				basic_machine=le32-unknown
+				os=nacl
+				;;
+			ncr3000)
+				basic_machine=i486-ncr
+				os=sysv4
+				;;
+			netbsd386)
+				basic_machine=i386-pc
+				os=netbsd
+				;;
+			netwinder)
+				basic_machine=armv4l-rebel
+				os=linux
+				;;
+			news | news700 | news800 | news900)
+				basic_machine=m68k-sony
+				os=newsos
+				;;
+			news1000)
+				basic_machine=m68030-sony
+				os=newsos
+				;;
+			necv70)
+				basic_machine=v70-nec
+				os=sysv
+				;;
+			nh3000)
+				basic_machine=m68k-harris
+				os=cxux
+				;;
+			nh[45]000)
+				basic_machine=m88k-harris
+				os=cxux
+				;;
+			nindy960)
+				basic_machine=i960-intel
+				os=nindy
+				;;
+			mon960)
+				basic_machine=i960-intel
+				os=mon960
+				;;
+			nonstopux)
+				basic_machine=mips-compaq
+				os=nonstopux
+				;;
+			os400)
+				basic_machine=powerpc-ibm
+				os=os400
+				;;
+			OSE68000 | ose68000)
+				basic_machine=m68000-ericsson
+				os=ose
+				;;
+			os68k)
+				basic_machine=m68k-none
+				os=os68k
+				;;
+			paragon)
+				basic_machine=i860-intel
+				os=osf
+				;;
+			parisc)
+				basic_machine=hppa-unknown
+				os=linux
+				;;
+			pw32)
+				basic_machine=i586-unknown
+				os=pw32
+				;;
+			rdos | rdos64)
+				basic_machine=x86_64-pc
+				os=rdos
+				;;
+			rdos32)
+				basic_machine=i386-pc
+				os=rdos
+				;;
+			rom68k)
+				basic_machine=m68k-rom68k
+				os=coff
+				;;
+			sa29200)
+				basic_machine=a29k-amd
+				os=udi
+				;;
+			sei)
+				basic_machine=mips-sei
+				os=seiux
+				;;
+			sequent)
+				basic_machine=i386-sequent
+				os=
+				;;
+			sps7)
+				basic_machine=m68k-bull
+				os=sysv2
+				;;
+			st2000)
+				basic_machine=m68k-tandem
+				os=
+				;;
+			stratus)
+				basic_machine=i860-stratus
+				os=sysv4
+				;;
+			sun2)
+				basic_machine=m68000-sun
+				os=
+				;;
+			sun2os3)
+				basic_machine=m68000-sun
+				os=sunos3
+				;;
+			sun2os4)
+				basic_machine=m68000-sun
+				os=sunos4
+				;;
+			sun3)
+				basic_machine=m68k-sun
+				os=
+				;;
+			sun3os3)
+				basic_machine=m68k-sun
+				os=sunos3
+				;;
+			sun3os4)
+				basic_machine=m68k-sun
+				os=sunos4
+				;;
+			sun4)
+				basic_machine=sparc-sun
+				os=
+				;;
+			sun4os3)
+				basic_machine=sparc-sun
+				os=sunos3
+				;;
+			sun4os4)
+				basic_machine=sparc-sun
+				os=sunos4
+				;;
+			sun4sol2)
+				basic_machine=sparc-sun
+				os=solaris2
+				;;
+			sun386 | sun386i | roadrunner)
+				basic_machine=i386-sun
+				os=
+				;;
+			sv1)
+				basic_machine=sv1-cray
+				os=unicos
+				;;
+			symmetry)
+				basic_machine=i386-sequent
+				os=dynix
+				;;
+			t3e)
+				basic_machine=alphaev5-cray
+				os=unicos
+				;;
+			t90)
+				basic_machine=t90-cray
+				os=unicos
+				;;
+			toad1)
+				basic_machine=pdp10-xkl
+				os=tops20
+				;;
+			tpf)
+				basic_machine=s390x-ibm
+				os=tpf
+				;;
+			udi29k)
+				basic_machine=a29k-amd
+				os=udi
+				;;
+			ultra3)
+				basic_machine=a29k-nyu
+				os=sym1
+				;;
+			v810 | necv810)
+				basic_machine=v810-nec
+				os=none
+				;;
+			vaxv)
+				basic_machine=vax-dec
+				os=sysv
+				;;
+			vms)
+				basic_machine=vax-dec
+				os=vms
+				;;
+			vsta)
+				basic_machine=i386-pc
+				os=vsta
+				;;
+			vxworks960)
+				basic_machine=i960-wrs
+				os=vxworks
+				;;
+			vxworks68)
+				basic_machine=m68k-wrs
+				os=vxworks
+				;;
+			vxworks29k)
+				basic_machine=a29k-wrs
+				os=vxworks
+				;;
+			xbox)
+				basic_machine=i686-pc
+				os=mingw32
+				;;
+			ymp)
+				basic_machine=ymp-cray
+				os=unicos
+				;;
+			*)
+				basic_machine=$1
+				os=
+				;;
+		esac
 		;;
-	-wrs)
-		os=-vxworks
-		basic_machine=$1
-		;;
-	-chorusos*)
-		os=-chorusos
-		basic_machine=$1
-		;;
-	-chorusrdb)
-		os=-chorusrdb
-		basic_machine=$1
-		;;
-	-hiux*)
-		os=-hiuxwe2
-		;;
-	-sco6)
-		os=-sco5v6
-		basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'`
-		;;
-	-sco5)
-		os=-sco3.2v5
-		basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'`
-		;;
-	-sco4)
-		os=-sco3.2v4
-		basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'`
-		;;
-	-sco3.2.[4-9]*)
-		os=`echo $os | sed -e 's/sco3.2./sco3.2v/'`
-		basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'`
-		;;
-	-sco3.2v[4-9]*)
-		# Don't forget version if it is 3.2v4 or newer.
-		basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'`
-		;;
-	-sco5v6*)
-		# Don't forget version if it is 3.2v4 or newer.
-		basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'`
-		;;
-	-sco*)
-		os=-sco3.2v2
-		basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'`
-		;;
-	-udk*)
-		basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'`
-		;;
-	-isc)
-		os=-isc2.2
-		basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'`
-		;;
-	-clix*)
-		basic_machine=clipper-intergraph
-		;;
-	-isc*)
-		basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'`
-		;;
-	-lynx*178)
-		os=-lynxos178
-		;;
-	-lynx*5)
-		os=-lynxos5
-		;;
-	-lynx*)
-		os=-lynxos
-		;;
-	-ptx*)
-		basic_machine=`echo "$1" | sed -e 's/86-.*/86-sequent/'`
-		;;
-	-psos*)
-		os=-psos
-		;;
-	-mint | -mint[0-9]*)
-		basic_machine=m68k-atari
-		os=-mint
-		;;
 esac
 
-# Decode aliases for certain CPU-COMPANY combinations.
+# Decode 1-component or ad-hoc basic machines
 case $basic_machine in
-	# Recognize the basic CPU types without company name.
-	# Some are omitted here because they have special meanings below.
-	1750a | 580 \
-	| a29k \
-	| aarch64 | aarch64_be \
-	| alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \
-	| alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \
-	| am33_2.0 \
-	| arc | arceb \
-	| arm | arm[bl]e | arme[lb] | armv[2-8] | armv[3-8][lb] | armv7[arm] \
-	| avr | avr32 \
-	| ba \
-	| be32 | be64 \
-	| bfin \
-	| c4x | c8051 | clipper \
-	| d10v | d30v | dlx | dsp16xx \
-	| e2k | epiphany \
-	| fido | fr30 | frv | ft32 \
-	| h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \
-	| hexagon \
-	| i370 | i860 | i960 | ia16 | ia64 \
-	| ip2k | iq2000 \
-	| k1om \
-	| le32 | le64 \
-	| lm32 \
-	| m32c | m32r | m32rle | m68000 | m68k | m88k \
-	| maxq | mb | microblaze | microblazeel | mcore | mep | metag \
-	| mips | mipsbe | mipseb | mipsel | mipsle \
-	| mips16 \
-	| mips64 | mips64el \
-	| mips64octeon | mips64octeonel \
-	| mips64orion | mips64orionel \
-	| mips64r5900 | mips64r5900el \
-	| mips64vr | mips64vrel \
-	| mips64vr4100 | mips64vr4100el \
-	| mips64vr4300 | mips64vr4300el \
-	| mips64vr5000 | mips64vr5000el \
-	| mips64vr5900 | mips64vr5900el \
-	| mipsisa32 | mipsisa32el \
-	| mipsisa32r2 | mipsisa32r2el \
-	| mipsisa32r6 | mipsisa32r6el \
-	| mipsisa64 | mipsisa64el \
-	| mipsisa64r2 | mipsisa64r2el \
-	| mipsisa64r6 | mipsisa64r6el \
-	| mipsisa64sb1 | mipsisa64sb1el \
-	| mipsisa64sr71k | mipsisa64sr71kel \
-	| mipsr5900 | mipsr5900el \
-	| mipstx39 | mipstx39el \
-	| mn10200 | mn10300 \
-	| moxie \
-	| mt \
-	| msp430 \
-	| nds32 | nds32le | nds32be \
-	| nios | nios2 | nios2eb | nios2el \
-	| ns16k | ns32k \
-	| open8 | or1k | or1knd | or32 \
-	| pdp10 | pj | pjl \
-	| powerpc | powerpc64 | powerpc64le | powerpcle \
-	| pru \
-	| pyramid \
-	| riscv32 | riscv64 \
-	| rl78 | rx \
-	| score \
-	| sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[234]eb | sheb | shbe | shle | sh[1234]le | sh3ele \
-	| sh64 | sh64le \
-	| sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \
-	| sparcv8 | sparcv9 | sparcv9b | sparcv9v \
-	| spu \
-	| tahoe | tic4x | tic54x | tic55x | tic6x | tic80 | tron \
-	| ubicom32 \
-	| v850 | v850e | v850e1 | v850e2 | v850es | v850e2v3 \
-	| visium \
-	| wasm32 \
-	| x86 | xc16x | xstormy16 | xtensa \
-	| z8k | z80)
-		basic_machine=$basic_machine-unknown
+	# Here we handle the default manufacturer of certain CPU types.  It is in
+	# some cases the only manufacturer, in others, it is the most popular.
+	w89k)
+		cpu=hppa1.1
+		vendor=winbond
 		;;
-	c54x)
-		basic_machine=tic54x-unknown
+	op50n)
+		cpu=hppa1.1
+		vendor=oki
 		;;
-	c55x)
-		basic_machine=tic55x-unknown
+	op60c)
+		cpu=hppa1.1
+		vendor=oki
 		;;
-	c6x)
-		basic_machine=tic6x-unknown
+	ibm*)
+		cpu=i370
+		vendor=ibm
 		;;
-	leon|leon[3-9])
-		basic_machine=sparc-$basic_machine
+	orion105)
+		cpu=clipper
+		vendor=highlevel
 		;;
-	m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x | nvptx | picochip)
-		basic_machine=$basic_machine-unknown
-		os=-none
+	mac | mpw | mac-mpw)
+		cpu=m68k
+		vendor=apple
 		;;
-	m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65)
+	pmac | pmac-mpw)
+		cpu=powerpc
+		vendor=apple
 		;;
-	ms1)
-		basic_machine=mt-unknown
-		;;
 
-	strongarm | thumb | xscale)
-		basic_machine=arm-unknown
-		;;
-	xgate)
-		basic_machine=$basic_machine-unknown
-		os=-none
-		;;
-	xscaleeb)
-		basic_machine=armeb-unknown
-		;;
-
-	xscaleel)
-		basic_machine=armel-unknown
-		;;
-
-	# We use `pc' rather than `unknown'
-	# because (1) that's what they normally are, and
-	# (2) the word "unknown" tends to confuse beginning users.
-	i*86 | x86_64)
-	  basic_machine=$basic_machine-pc
-	  ;;
-	# Object if more than one company name word.
-	*-*-*)
-		echo Invalid configuration \`"$1"\': machine \`"$basic_machine"\' not recognized 1>&2
-		exit 1
-		;;
-	# Recognize the basic CPU types with company name.
-	580-* \
-	| a29k-* \
-	| aarch64-* | aarch64_be-* \
-	| alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \
-	| alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \
-	| alphapca5[67]-* | alpha64pca5[67]-* | arc-* | arceb-* \
-	| arm-*  | armbe-* | armle-* | armeb-* | armv*-* \
-	| avr-* | avr32-* \
-	| ba-* \
-	| be32-* | be64-* \
-	| bfin-* | bs2000-* \
-	| c[123]* | c30-* | [cjt]90-* | c4x-* \
-	| c8051-* | clipper-* | craynv-* | cydra-* \
-	| d10v-* | d30v-* | dlx-* \
-	| e2k-* | elxsi-* \
-	| f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \
-	| h8300-* | h8500-* \
-	| hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \
-	| hexagon-* \
-	| i*86-* | i860-* | i960-* | ia16-* | ia64-* \
-	| ip2k-* | iq2000-* \
-	| k1om-* \
-	| le32-* | le64-* \
-	| lm32-* \
-	| m32c-* | m32r-* | m32rle-* \
-	| m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \
-	| m88110-* | m88k-* | maxq-* | mcore-* | metag-* \
-	| microblaze-* | microblazeel-* \
-	| mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \
-	| mips16-* \
-	| mips64-* | mips64el-* \
-	| mips64octeon-* | mips64octeonel-* \
-	| mips64orion-* | mips64orionel-* \
-	| mips64r5900-* | mips64r5900el-* \
-	| mips64vr-* | mips64vrel-* \
-	| mips64vr4100-* | mips64vr4100el-* \
-	| mips64vr4300-* | mips64vr4300el-* \
-	| mips64vr5000-* | mips64vr5000el-* \
-	| mips64vr5900-* | mips64vr5900el-* \
-	| mipsisa32-* | mipsisa32el-* \
-	| mipsisa32r2-* | mipsisa32r2el-* \
-	| mipsisa32r6-* | mipsisa32r6el-* \
-	| mipsisa64-* | mipsisa64el-* \
-	| mipsisa64r2-* | mipsisa64r2el-* \
-	| mipsisa64r6-* | mipsisa64r6el-* \
-	| mipsisa64sb1-* | mipsisa64sb1el-* \
-	| mipsisa64sr71k-* | mipsisa64sr71kel-* \
-	| mipsr5900-* | mipsr5900el-* \
-	| mipstx39-* | mipstx39el-* \
-	| mmix-* \
-	| mt-* \
-	| msp430-* \
-	| nds32-* | nds32le-* | nds32be-* \
-	| nios-* | nios2-* | nios2eb-* | nios2el-* \
-	| none-* | np1-* | ns16k-* | ns32k-* \
-	| open8-* \
-	| or1k*-* \
-	| orion-* \
-	| pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \
-	| powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* \
-	| pru-* \
-	| pyramid-* \
-	| riscv32-* | riscv64-* \
-	| rl78-* | romp-* | rs6000-* | rx-* \
-	| sh-* | sh[1234]-* | sh[24]a-* | sh[24]aeb-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \
-	| shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \
-	| sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \
-	| sparclite-* \
-	| sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | sv1-* | sx*-* \
-	| tahoe-* \
-	| tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \
-	| tile*-* \
-	| tron-* \
-	| ubicom32-* \
-	| v850-* | v850e-* | v850e1-* | v850es-* | v850e2-* | v850e2v3-* \
-	| vax-* \
-	| visium-* \
-	| wasm32-* \
-	| we32k-* \
-	| x86-* | x86_64-* | xc16x-* | xps100-* \
-	| xstormy16-* | xtensa*-* \
-	| ymp-* \
-	| z8k-* | z80-*)
-		;;
-	# Recognize the basic CPU types without company name, with glob match.
-	xtensa*)
-		basic_machine=$basic_machine-unknown
-		;;
 	# Recognize the various machine names and aliases which stand
 	# for a CPU type and a company and sometimes even an OS.
-	386bsd)
-		basic_machine=i386-pc
-		os=-bsd
-		;;
 	3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc)
-		basic_machine=m68000-att
+		cpu=m68000
+		vendor=att
 		;;
 	3b*)
-		basic_machine=we32k-att
+		cpu=we32k
+		vendor=att
 		;;
-	a29khif)
-		basic_machine=a29k-amd
-		os=-udi
-		;;
-	abacus)
-		basic_machine=abacus-unknown
-		;;
-	adobe68k)
-		basic_machine=m68010-adobe
-		os=-scout
-		;;
-	alliant | fx80)
-		basic_machine=fx80-alliant
-		;;
-	altos | altos3068)
-		basic_machine=m68k-altos
-		;;
-	am29k)
-		basic_machine=a29k-none
-		os=-bsd
-		;;
-	amd64)
-		basic_machine=x86_64-pc
-		;;
-	amd64-*)
-		basic_machine=x86_64-`echo "$basic_machine" | sed 's/^[^-]*-//'`
-		;;
-	amdahl)
-		basic_machine=580-amdahl
-		os=-sysv
-		;;
-	amiga | amiga-*)
-		basic_machine=m68k-unknown
-		;;
-	amigaos | amigados)
-		basic_machine=m68k-unknown
-		os=-amigaos
-		;;
-	amigaunix | amix)
-		basic_machine=m68k-unknown
-		os=-sysv4
-		;;
-	apollo68)
-		basic_machine=m68k-apollo
-		os=-sysv
-		;;
-	apollo68bsd)
-		basic_machine=m68k-apollo
-		os=-bsd
-		;;
-	aros)
-		basic_machine=i386-pc
-		os=-aros
-		;;
-	asmjs)
-		basic_machine=asmjs-unknown
-		;;
-	aux)
-		basic_machine=m68k-apple
-		os=-aux
-		;;
-	balance)
-		basic_machine=ns32k-sequent
-		os=-dynix
-		;;
-	blackfin)
-		basic_machine=bfin-unknown
-		os=-linux
-		;;
-	blackfin-*)
-		basic_machine=bfin-`echo "$basic_machine" | sed 's/^[^-]*-//'`
-		os=-linux
-		;;
 	bluegene*)
-		basic_machine=powerpc-ibm
-		os=-cnk
+		cpu=powerpc
+		vendor=ibm
+		os=cnk
 		;;
-	c54x-*)
-		basic_machine=tic54x-`echo "$basic_machine" | sed 's/^[^-]*-//'`
-		;;
-	c55x-*)
-		basic_machine=tic55x-`echo "$basic_machine" | sed 's/^[^-]*-//'`
-		;;
-	c6x-*)
-		basic_machine=tic6x-`echo "$basic_machine" | sed 's/^[^-]*-//'`
-		;;
-	c90)
-		basic_machine=c90-cray
-		os=-unicos
-		;;
-	cegcc)
-		basic_machine=arm-unknown
-		os=-cegcc
-		;;
-	convex-c1)
-		basic_machine=c1-convex
-		os=-bsd
-		;;
-	convex-c2)
-		basic_machine=c2-convex
-		os=-bsd
-		;;
-	convex-c32)
-		basic_machine=c32-convex
-		os=-bsd
-		;;
-	convex-c34)
-		basic_machine=c34-convex
-		os=-bsd
-		;;
-	convex-c38)
-		basic_machine=c38-convex
-		os=-bsd
-		;;
-	cray | j90)
-		basic_machine=j90-cray
-		os=-unicos
-		;;
-	craynv)
-		basic_machine=craynv-cray
-		os=-unicosmp
-		;;
-	cr16 | cr16-*)
-		basic_machine=cr16-unknown
-		os=-elf
-		;;
-	crds | unos)
-		basic_machine=m68k-crds
-		;;
-	crisv32 | crisv32-* | etraxfs*)
-		basic_machine=crisv32-axis
-		;;
-	cris | cris-* | etrax*)
-		basic_machine=cris-axis
-		;;
-	crx)
-		basic_machine=crx-unknown
-		os=-elf
-		;;
-	da30 | da30-*)
-		basic_machine=m68k-da30
-		;;
-	decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn)
-		basic_machine=mips-dec
-		;;
 	decsystem10* | dec10*)
-		basic_machine=pdp10-dec
-		os=-tops10
+		cpu=pdp10
+		vendor=dec
+		os=tops10
 		;;
 	decsystem20* | dec20*)
-		basic_machine=pdp10-dec
-		os=-tops20
+		cpu=pdp10
+		vendor=dec
+		os=tops20
 		;;
 	delta | 3300 | motorola-3300 | motorola-delta \
 	      | 3300-motorola | delta-motorola)
-		basic_machine=m68k-motorola
+		cpu=m68k
+		vendor=motorola
 		;;
-	delta88)
-		basic_machine=m88k-motorola
-		os=-sysv3
-		;;
-	dicos)
-		basic_machine=i686-pc
-		os=-dicos
-		;;
-	djgpp)
-		basic_machine=i586-pc
-		os=-msdosdjgpp
-		;;
-	dpx20 | dpx20-*)
-		basic_machine=rs6000-bull
-		os=-bosx
-		;;
 	dpx2*)
-		basic_machine=m68k-bull
-		os=-sysv3
+		cpu=m68k
+		vendor=bull
+		os=sysv3
 		;;
-	e500v[12])
-		basic_machine=powerpc-unknown
-		os=$os"spe"
+	encore | umax | mmax)
+		cpu=ns32k
+		vendor=encore
 		;;
-	e500v[12]-*)
-		basic_machine=powerpc-`echo "$basic_machine" | sed 's/^[^-]*-//'`
-		os=$os"spe"
-		;;
-	ebmon29k)
-		basic_machine=a29k-amd
-		os=-ebmon
-		;;
 	elxsi)
-		basic_machine=elxsi-elxsi
-		os=-bsd
+		cpu=elxsi
+		vendor=elxsi
+		os=${os:-bsd}
 		;;
-	encore | umax | mmax)
-		basic_machine=ns32k-encore
-		;;
-	es1800 | OSE68k | ose68k | ose | OSE)
-		basic_machine=m68k-ericsson
-		os=-ose
-		;;
 	fx2800)
-		basic_machine=i860-alliant
+		cpu=i860
+		vendor=alliant
 		;;
 	genix)
-		basic_machine=ns32k-ns
+		cpu=ns32k
+		vendor=ns
 		;;
-	gmicro)
-		basic_machine=tron-gmicro
-		os=-sysv
-		;;
-	go32)
-		basic_machine=i386-pc
-		os=-go32
-		;;
 	h3050r* | hiux*)
-		basic_machine=hppa1.1-hitachi
-		os=-hiuxwe2
+		cpu=hppa1.1
+		vendor=hitachi
+		os=hiuxwe2
 		;;
-	h8300hms)
-		basic_machine=h8300-hitachi
-		os=-hms
-		;;
-	h8300xray)
-		basic_machine=h8300-hitachi
-		os=-xray
-		;;
-	h8500hms)
-		basic_machine=h8500-hitachi
-		os=-hms
-		;;
-	harris)
-		basic_machine=m88k-harris
-		os=-sysv3
-		;;
-	hp300-*)
-		basic_machine=m68k-hp
-		;;
-	hp300bsd)
-		basic_machine=m68k-hp
-		os=-bsd
-		;;
-	hp300hpux)
-		basic_machine=m68k-hp
-		os=-hpux
-		;;
 	hp3k9[0-9][0-9] | hp9[0-9][0-9])
-		basic_machine=hppa1.0-hp
+		cpu=hppa1.0
+		vendor=hp
 		;;
 	hp9k2[0-9][0-9] | hp9k31[0-9])
-		basic_machine=m68000-hp
+		cpu=m68000
+		vendor=hp
 		;;
 	hp9k3[2-9][0-9])
-		basic_machine=m68k-hp
+		cpu=m68k
+		vendor=hp
 		;;
 	hp9k6[0-9][0-9] | hp6[0-9][0-9])
-		basic_machine=hppa1.0-hp
+		cpu=hppa1.0
+		vendor=hp
 		;;
 	hp9k7[0-79][0-9] | hp7[0-79][0-9])
-		basic_machine=hppa1.1-hp
+		cpu=hppa1.1
+		vendor=hp
 		;;
 	hp9k78[0-9] | hp78[0-9])
 		# FIXME: really hppa2.0-hp
-		basic_machine=hppa1.1-hp
+		cpu=hppa1.1
+		vendor=hp
 		;;
 	hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893)
 		# FIXME: really hppa2.0-hp
-		basic_machine=hppa1.1-hp
+		cpu=hppa1.1
+		vendor=hp
 		;;
 	hp9k8[0-9][13679] | hp8[0-9][13679])
-		basic_machine=hppa1.1-hp
+		cpu=hppa1.1
+		vendor=hp
 		;;
 	hp9k8[0-9][0-9] | hp8[0-9][0-9])
-		basic_machine=hppa1.0-hp
+		cpu=hppa1.0
+		vendor=hp
 		;;
-	hppaosf)
-		basic_machine=hppa1.1-hp
-		os=-osf
-		;;
-	hppro)
-		basic_machine=hppa1.1-hp
-		os=-proelf
-		;;
-	i370-ibm* | ibm*)
-		basic_machine=i370-ibm
-		;;
 	i*86v32)
-		basic_machine=`echo "$1" | sed -e 's/86.*/86-pc/'`
-		os=-sysv32
+		cpu=`echo "$1" | sed -e 's/86.*/86/'`
+		vendor=pc
+		os=sysv32
 		;;
 	i*86v4*)
-		basic_machine=`echo "$1" | sed -e 's/86.*/86-pc/'`
-		os=-sysv4
+		cpu=`echo "$1" | sed -e 's/86.*/86/'`
+		vendor=pc
+		os=sysv4
 		;;
 	i*86v)
-		basic_machine=`echo "$1" | sed -e 's/86.*/86-pc/'`
-		os=-sysv
+		cpu=`echo "$1" | sed -e 's/86.*/86/'`
+		vendor=pc
+		os=sysv
 		;;
 	i*86sol2)
-		basic_machine=`echo "$1" | sed -e 's/86.*/86-pc/'`
-		os=-solaris2
+		cpu=`echo "$1" | sed -e 's/86.*/86/'`
+		vendor=pc
+		os=solaris2
 		;;
-	i386mach)
-		basic_machine=i386-mach
-		os=-mach
+	j90 | j90-cray)
+		cpu=j90
+		vendor=cray
+		os=${os:-unicos}
 		;;
-	vsta)
-		basic_machine=i386-unknown
-		os=-vsta
-		;;
 	iris | iris4d)
-		basic_machine=mips-sgi
+		cpu=mips
+		vendor=sgi
 		case $os in
-		    -irix*)
+		    irix*)
 			;;
 		    *)
-			os=-irix4
+			os=irix4
 			;;
 		esac
 		;;
-	isi68 | isi)
-		basic_machine=m68k-isi
-		os=-sysv
-		;;
-	leon-*|leon[3-9]-*)
-		basic_machine=sparc-`echo "$basic_machine" | sed 's/-.*//'`
-		;;
-	m68knommu)
-		basic_machine=m68k-unknown
-		os=-linux
-		;;
-	m68knommu-*)
-		basic_machine=m68k-`echo "$basic_machine" | sed 's/^[^-]*-//'`
-		os=-linux
-		;;
-	magnum | m3230)
-		basic_machine=mips-mips
-		os=-sysv
-		;;
-	merlin)
-		basic_machine=ns32k-utek
-		os=-sysv
-		;;
-	microblaze*)
-		basic_machine=microblaze-xilinx
-		;;
-	mingw64)
-		basic_machine=x86_64-pc
-		os=-mingw64
-		;;
-	mingw32)
-		basic_machine=i686-pc
-		os=-mingw32
-		;;
-	mingw32ce)
-		basic_machine=arm-unknown
-		os=-mingw32ce
-		;;
 	miniframe)
-		basic_machine=m68000-convergent
+		cpu=m68000
+		vendor=convergent
 		;;
-	*mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*)
-		basic_machine=m68k-atari
-		os=-mint
+	*mint | mint[0-9]* | *MiNT | *MiNT[0-9]*)
+		cpu=m68k
+		vendor=atari
+		os=mint
 		;;
-	mips3*-*)
-		basic_machine=`echo "$basic_machine" | sed -e 's/mips3/mips64/'`
-		;;
-	mips3*)
-		basic_machine=`echo "$basic_machine" | sed -e 's/mips3/mips64/'`-unknown
-		;;
-	monitor)
-		basic_machine=m68k-rom68k
-		os=-coff
-		;;
-	morphos)
-		basic_machine=powerpc-unknown
-		os=-morphos
-		;;
-	moxiebox)
-		basic_machine=moxie-unknown
-		os=-moxiebox
-		;;
-	msdos)
-		basic_machine=i386-pc
-		os=-msdos
-		;;
-	ms1-*)
-		basic_machine=`echo "$basic_machine" | sed -e 's/ms1-/mt-/'`
-		;;
-	msys)
-		basic_machine=i686-pc
-		os=-msys
-		;;
-	mvs)
-		basic_machine=i370-ibm
-		os=-mvs
-		;;
-	nacl)
-		basic_machine=le32-unknown
-		os=-nacl
-		;;
-	ncr3000)
-		basic_machine=i486-ncr
-		os=-sysv4
-		;;
-	netbsd386)
-		basic_machine=i386-unknown
-		os=-netbsd
-		;;
-	netwinder)
-		basic_machine=armv4l-rebel
-		os=-linux
-		;;
-	news | news700 | news800 | news900)
-		basic_machine=m68k-sony
-		os=-newsos
-		;;
-	news1000)
-		basic_machine=m68030-sony
-		os=-newsos
-		;;
 	news-3600 | risc-news)
-		basic_machine=mips-sony
-		os=-newsos
+		cpu=mips
+		vendor=sony
+		os=newsos
 		;;
-	necv70)
-		basic_machine=v70-nec
-		os=-sysv
-		;;
 	next | m*-next)
-		basic_machine=m68k-next
+		cpu=m68k
+		vendor=next
 		case $os in
-		    -nextstep* )
+		    openstep*)
+		        ;;
+		    nextstep*)
 			;;
-		    -ns2*)
-		      os=-nextstep2
+		    ns2*)
+		      os=nextstep2
 			;;
 		    *)
-		      os=-nextstep3
+		      os=nextstep3
 			;;
 		esac
 		;;
-	nh3000)
-		basic_machine=m68k-harris
-		os=-cxux
-		;;
-	nh[45]000)
-		basic_machine=m88k-harris
-		os=-cxux
-		;;
-	nindy960)
-		basic_machine=i960-intel
-		os=-nindy
-		;;
-	mon960)
-		basic_machine=i960-intel
-		os=-mon960
-		;;
-	nonstopux)
-		basic_machine=mips-compaq
-		os=-nonstopux
-		;;
 	np1)
-		basic_machine=np1-gould
+		cpu=np1
+		vendor=gould
 		;;
-	neo-tandem)
-		basic_machine=neo-tandem
-		;;
-	nse-tandem)
-		basic_machine=nse-tandem
-		;;
-	nsr-tandem)
-		basic_machine=nsr-tandem
-		;;
-	nsv-tandem)
-		basic_machine=nsv-tandem
-		;;
-	nsx-tandem)
-		basic_machine=nsx-tandem
-		;;
 	op50n-* | op60c-*)
-		basic_machine=hppa1.1-oki
-		os=-proelf
+		cpu=hppa1.1
+		vendor=oki
+		os=proelf
 		;;
-	openrisc | openrisc-*)
-		basic_machine=or32-unknown
-		;;
-	os400)
-		basic_machine=powerpc-ibm
-		os=-os400
-		;;
-	OSE68000 | ose68000)
-		basic_machine=m68000-ericsson
-		os=-ose
-		;;
-	os68k)
-		basic_machine=m68k-none
-		os=-os68k
-		;;
 	pa-hitachi)
-		basic_machine=hppa1.1-hitachi
-		os=-hiuxwe2
+		cpu=hppa1.1
+		vendor=hitachi
+		os=hiuxwe2
 		;;
-	paragon)
-		basic_machine=i860-intel
-		os=-osf
-		;;
-	parisc)
-		basic_machine=hppa-unknown
-		os=-linux
-		;;
-	parisc-*)
-		basic_machine=hppa-`echo "$basic_machine" | sed 's/^[^-]*-//'`
-		os=-linux
-		;;
 	pbd)
-		basic_machine=sparc-tti
+		cpu=sparc
+		vendor=tti
 		;;
 	pbb)
-		basic_machine=m68k-tti
+		cpu=m68k
+		vendor=tti
 		;;
-	pc532 | pc532-*)
-		basic_machine=ns32k-pc532
+	pc532)
+		cpu=ns32k
+		vendor=pc532
 		;;
-	pc98)
-		basic_machine=i386-pc
-		;;
-	pc98-*)
-		basic_machine=i386-`echo "$basic_machine" | sed 's/^[^-]*-//'`
-		;;
-	pentium | p5 | k5 | k6 | nexgen | viac3)
-		basic_machine=i586-pc
-		;;
-	pentiumpro | p6 | 6x86 | athlon | athlon_*)
-		basic_machine=i686-pc
-		;;
-	pentiumii | pentium2 | pentiumiii | pentium3)
-		basic_machine=i686-pc
-		;;
-	pentium4)
-		basic_machine=i786-pc
-		;;
-	pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*)
-		basic_machine=i586-`echo "$basic_machine" | sed 's/^[^-]*-//'`
-		;;
-	pentiumpro-* | p6-* | 6x86-* | athlon-*)
-		basic_machine=i686-`echo "$basic_machine" | sed 's/^[^-]*-//'`
-		;;
-	pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*)
-		basic_machine=i686-`echo "$basic_machine" | sed 's/^[^-]*-//'`
-		;;
-	pentium4-*)
-		basic_machine=i786-`echo "$basic_machine" | sed 's/^[^-]*-//'`
-		;;
 	pn)
-		basic_machine=pn-gould
+		cpu=pn
+		vendor=gould
 		;;
-	power)	basic_machine=power-ibm
+	power)
+		cpu=power
+		vendor=ibm
 		;;
-	ppc | ppcbe)	basic_machine=powerpc-unknown
+	ps2)
+		cpu=i386
+		vendor=ibm
 		;;
-	ppc-* | ppcbe-*)
-		basic_machine=powerpc-`echo "$basic_machine" | sed 's/^[^-]*-//'`
+	rm[46]00)
+		cpu=mips
+		vendor=siemens
 		;;
-	ppcle | powerpclittle)
-		basic_machine=powerpcle-unknown
+	rtpc | rtpc-*)
+		cpu=romp
+		vendor=ibm
 		;;
-	ppcle-* | powerpclittle-*)
-		basic_machine=powerpcle-`echo "$basic_machine" | sed 's/^[^-]*-//'`
+	sde)
+		cpu=mipsisa32
+		vendor=sde
+		os=${os:-elf}
 		;;
-	ppc64)	basic_machine=powerpc64-unknown
+	simso-wrs)
+		cpu=sparclite
+		vendor=wrs
+		os=vxworks
 		;;
-	ppc64-*) basic_machine=powerpc64-`echo "$basic_machine" | sed 's/^[^-]*-//'`
+	tower | tower-32)
+		cpu=m68k
+		vendor=ncr
 		;;
-	ppc64le | powerpc64little)
-		basic_machine=powerpc64le-unknown
+	vpp*|vx|vx-*)
+		cpu=f301
+		vendor=fujitsu
 		;;
-	ppc64le-* | powerpc64little-*)
-		basic_machine=powerpc64le-`echo "$basic_machine" | sed 's/^[^-]*-//'`
+	w65)
+		cpu=w65
+		vendor=wdc
 		;;
-	ps2)
-		basic_machine=i386-ibm
+	w89k-*)
+		cpu=hppa1.1
+		vendor=winbond
+		os=proelf
 		;;
-	pw32)
-		basic_machine=i586-unknown
-		os=-pw32
+	none)
+		cpu=none
+		vendor=none
 		;;
-	rdos | rdos64)
-		basic_machine=x86_64-pc
-		os=-rdos
+	leon|leon[3-9])
+		cpu=sparc
+		vendor=$basic_machine
 		;;
-	rdos32)
-		basic_machine=i386-pc
-		os=-rdos
+	leon-*|leon[3-9]-*)
+		cpu=sparc
+		vendor=`echo "$basic_machine" | sed 's/-.*//'`
 		;;
-	rom68k)
-		basic_machine=m68k-rom68k
-		os=-coff
+
+	*-*)
+		# shellcheck disable=SC2162
+		IFS="-" read cpu vendor <<EOF
+$basic_machine
+EOF
 		;;
-	rm[46]00)
-		basic_machine=mips-siemens
+	# We use `pc' rather than `unknown'
+	# because (1) that's what they normally are, and
+	# (2) the word "unknown" tends to confuse beginning users.
+	i*86 | x86_64)
+		cpu=$basic_machine
+		vendor=pc
 		;;
-	rtpc | rtpc-*)
-		basic_machine=romp-ibm
+	# These rules are duplicated from below for sake of the special case above;
+	# i.e. things that normalized to x86 arches should also default to "pc"
+	pc98)
+		cpu=i386
+		vendor=pc
 		;;
-	s390 | s390-*)
-		basic_machine=s390-ibm
+	x64 | amd64)
+		cpu=x86_64
+		vendor=pc
 		;;
-	s390x | s390x-*)
-		basic_machine=s390x-ibm
+	# Recognize the basic CPU types without company name.
+	*)
+		cpu=$basic_machine
+		vendor=unknown
 		;;
-	sa29200)
-		basic_machine=a29k-amd
-		os=-udi
+esac
+
+unset -v basic_machine
+
+# Decode basic machines in the full and proper CPU-Company form.
+case $cpu-$vendor in
+	# Here we handle the default manufacturer of certain CPU types in canonical form. It is in
+	# some cases the only manufacturer, in others, it is the most popular.
+	craynv-unknown)
+		vendor=cray
+		os=${os:-unicosmp}
 		;;
-	sb1)
-		basic_machine=mipsisa64sb1-unknown
+	c90-unknown | c90-cray)
+		vendor=cray
+		os=${os:-unicos}
 		;;
-	sb1el)
-		basic_machine=mipsisa64sb1el-unknown
+	fx80-unknown)
+		vendor=alliant
 		;;
-	sde)
-		basic_machine=mipsisa32-sde
-		os=-elf
+	romp-unknown)
+		vendor=ibm
 		;;
-	sei)
-		basic_machine=mips-sei
-		os=-seiux
+	mmix-unknown)
+		vendor=knuth
 		;;
-	sequent)
-		basic_machine=i386-sequent
+	microblaze-unknown | microblazeel-unknown)
+		vendor=xilinx
 		;;
-	sh5el)
-		basic_machine=sh5le-unknown
+	rs6000-unknown)
+		vendor=ibm
 		;;
-	simso-wrs)
-		basic_machine=sparclite-wrs
-		os=-vxworks
+	vax-unknown)
+		vendor=dec
 		;;
-	sps7)
-		basic_machine=m68k-bull
-		os=-sysv2
+	pdp11-unknown)
+		vendor=dec
 		;;
-	spur)
-		basic_machine=spur-unknown
+	we32k-unknown)
+		vendor=att
 		;;
-	st2000)
-		basic_machine=m68k-tandem
+	cydra-unknown)
+		vendor=cydrome
 		;;
-	stratus)
-		basic_machine=i860-stratus
-		os=-sysv4
+	i370-ibm*)
+		vendor=ibm
 		;;
-	strongarm-* | thumb-*)
-		basic_machine=arm-`echo "$basic_machine" | sed 's/^[^-]*-//'`
+	orion-unknown)
+		vendor=highlevel
 		;;
-	sun2)
-		basic_machine=m68000-sun
+	xps-unknown | xps100-unknown)
+		cpu=xps100
+		vendor=honeywell
 		;;
-	sun2os3)
-		basic_machine=m68000-sun
-		os=-sunos3
+
+	# Here we normalize CPU types with a missing or matching vendor
+	dpx20-unknown | dpx20-bull)
+		cpu=rs6000
+		vendor=bull
+		os=${os:-bosx}
 		;;
-	sun2os4)
-		basic_machine=m68000-sun
-		os=-sunos4
+
+	# Here we normalize CPU types irrespective of the vendor
+	amd64-*)
+		cpu=x86_64
 		;;
-	sun3os3)
-		basic_machine=m68k-sun
-		os=-sunos3
+	blackfin-*)
+		cpu=bfin
+		os=linux
 		;;
-	sun3os4)
-		basic_machine=m68k-sun
-		os=-sunos4
+	c54x-*)
+		cpu=tic54x
 		;;
-	sun4os3)
-		basic_machine=sparc-sun
-		os=-sunos3
+	c55x-*)
+		cpu=tic55x
 		;;
-	sun4os4)
-		basic_machine=sparc-sun
-		os=-sunos4
+	c6x-*)
+		cpu=tic6x
 		;;
-	sun4sol2)
-		basic_machine=sparc-sun
-		os=-solaris2
+	e500v[12]-*)
+		cpu=powerpc
+		os=$os"spe"
 		;;
-	sun3 | sun3-*)
-		basic_machine=m68k-sun
+	mips3*-*)
+		cpu=mips64
 		;;
-	sun4)
-		basic_machine=sparc-sun
+	ms1-*)
+		cpu=mt
 		;;
-	sun386 | sun386i | roadrunner)
-		basic_machine=i386-sun
+	m68knommu-*)
+		cpu=m68k
+		os=linux
 		;;
-	sv1)
-		basic_machine=sv1-cray
-		os=-unicos
+	m9s12z-* | m68hcs12z-* | hcs12z-* | s12z-*)
+		cpu=s12z
 		;;
-	symmetry)
-		basic_machine=i386-sequent
-		os=-dynix
+	openrisc-*)
+		cpu=or32
 		;;
-	t3e)
-		basic_machine=alphaev5-cray
-		os=-unicos
+	parisc-*)
+		cpu=hppa
+		os=linux
 		;;
-	t90)
-		basic_machine=t90-cray
-		os=-unicos
+	pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*)
+		cpu=i586
 		;;
-	tile*)
-		basic_machine=$basic_machine-unknown
-		os=-linux-gnu
+	pentiumpro-* | p6-* | 6x86-* | athlon-* | athalon_*-*)
+		cpu=i686
 		;;
-	tx39)
-		basic_machine=mipstx39-unknown
+	pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*)
+		cpu=i686
 		;;
-	tx39el)
-		basic_machine=mipstx39el-unknown
+	pentium4-*)
+		cpu=i786
 		;;
-	toad1)
-		basic_machine=pdp10-xkl
-		os=-tops20
+	pc98-*)
+		cpu=i386
 		;;
-	tower | tower-32)
-		basic_machine=m68k-ncr
+	ppc-* | ppcbe-*)
+		cpu=powerpc
 		;;
-	tpf)
-		basic_machine=s390x-ibm
-		os=-tpf
+	ppcle-* | powerpclittle-*)
+		cpu=powerpcle
 		;;
-	udi29k)
-		basic_machine=a29k-amd
-		os=-udi
+	ppc64-*)
+		cpu=powerpc64
 		;;
-	ultra3)
-		basic_machine=a29k-nyu
-		os=-sym1
+	ppc64le-* | powerpc64little-*)
+		cpu=powerpc64le
 		;;
-	v810 | necv810)
-		basic_machine=v810-nec
-		os=-none
+	sb1-*)
+		cpu=mipsisa64sb1
 		;;
-	vaxv)
-		basic_machine=vax-dec
-		os=-sysv
+	sb1el-*)
+		cpu=mipsisa64sb1el
 		;;
-	vms)
-		basic_machine=vax-dec
-		os=-vms
+	sh5e[lb]-*)
+		cpu=`echo "$cpu" | sed 's/^\(sh.\)e\(.\)$/\1\2e/'`
 		;;
-	vpp*|vx|vx-*)
-		basic_machine=f301-fujitsu
+	spur-*)
+		cpu=spur
 		;;
-	vxworks960)
-		basic_machine=i960-wrs
-		os=-vxworks
+	strongarm-* | thumb-*)
+		cpu=arm
 		;;
-	vxworks68)
-		basic_machine=m68k-wrs
-		os=-vxworks
+	tx39-*)
+		cpu=mipstx39
 		;;
-	vxworks29k)
-		basic_machine=a29k-wrs
-		os=-vxworks
+	tx39el-*)
+		cpu=mipstx39el
 		;;
-	w65*)
-		basic_machine=w65-wdc
-		os=-none
+	x64-*)
+		cpu=x86_64
 		;;
-	w89k-*)
-		basic_machine=hppa1.1-winbond
-		os=-proelf
-		;;
-	x64)
-		basic_machine=x86_64-pc
-		;;
-	xbox)
-		basic_machine=i686-pc
-		os=-mingw32
-		;;
-	xps | xps100)
-		basic_machine=xps100-honeywell
-		;;
 	xscale-* | xscalee[bl]-*)
-		basic_machine=`echo "$basic_machine" | sed 's/^xscale/arm/'`
+		cpu=`echo "$cpu" | sed 's/^xscale/arm/'`
 		;;
-	ymp)
-		basic_machine=ymp-cray
-		os=-unicos
-		;;
-	none)
-		basic_machine=none-none
-		os=-none
-		;;
 
-# Here we handle the default manufacturer of certain CPU types.  It is in
-# some cases the only manufacturer, in others, it is the most popular.
-	w89k)
-		basic_machine=hppa1.1-winbond
+	# Recognize the canonical CPU Types that limit and/or modify the
+	# company names they are paired with.
+	cr16-*)
+		os=${os:-elf}
 		;;
-	op50n)
-		basic_machine=hppa1.1-oki
+	crisv32-* | etraxfs*-*)
+		cpu=crisv32
+		vendor=axis
 		;;
-	op60c)
-		basic_machine=hppa1.1-oki
+	cris-* | etrax*-*)
+		cpu=cris
+		vendor=axis
 		;;
-	romp)
-		basic_machine=romp-ibm
+	crx-*)
+		os=${os:-elf}
 		;;
-	mmix)
-		basic_machine=mmix-knuth
+	neo-tandem)
+		cpu=neo
+		vendor=tandem
 		;;
-	rs6000)
-		basic_machine=rs6000-ibm
+	nse-tandem)
+		cpu=nse
+		vendor=tandem
 		;;
-	vax)
-		basic_machine=vax-dec
+	nsr-tandem)
+		cpu=nsr
+		vendor=tandem
 		;;
-	pdp11)
-		basic_machine=pdp11-dec
+	nsv-tandem)
+		cpu=nsv
+		vendor=tandem
 		;;
-	we32k)
-		basic_machine=we32k-att
+	nsx-tandem)
+		cpu=nsx
+		vendor=tandem
 		;;
-	sh[1234] | sh[24]a | sh[24]aeb | sh[34]eb | sh[1234]le | sh[23]ele)
-		basic_machine=sh-unknown
+	s390-*)
+		cpu=s390
+		vendor=ibm
 		;;
-	cydra)
-		basic_machine=cydra-cydrome
+	s390x-*)
+		cpu=s390x
+		vendor=ibm
 		;;
-	orion)
-		basic_machine=orion-highlevel
+	tile*-*)
+		os=${os:-linux-gnu}
 		;;
-	orion105)
-		basic_machine=clipper-highlevel
-		;;
-	mac | mpw | mac-mpw)
-		basic_machine=m68k-apple
-		;;
-	pmac | pmac-mpw)
-		basic_machine=powerpc-apple
-		;;
-	*-unknown)
-		# Make sure to match an already-canonicalized machine name.
-		;;
+
 	*)
-		echo Invalid configuration \`"$1"\': machine \`"$basic_machine"\' not recognized 1>&2
-		exit 1
+		# Recognize the canonical CPU types that are allowed with any
+		# company name.
+		case $cpu in
+			1750a | 580 \
+			| a29k \
+			| aarch64 | aarch64_be \
+			| abacus \
+			| alpha | alphaev[4-8] | alphaev56 | alphaev6[78] \
+			| alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] \
+			| alphapca5[67] | alpha64pca5[67] \
+			| am33_2.0 \
+			| amdgcn \
+			| arc | arceb \
+			| arm  | arm[lb]e | arme[lb] | armv* \
+			| avr | avr32 \
+			| asmjs \
+			| ba \
+			| be32 | be64 \
+			| bfin | bpf | bs2000 \
+			| c[123]* | c30 | [cjt]90 | c4x \
+			| c8051 | clipper | craynv | csky | cydra \
+			| d10v | d30v | dlx | dsp16xx \
+			| e2k | elxsi | epiphany \
+			| f30[01] | f700 | fido | fr30 | frv | ft32 | fx80 \
+			| h8300 | h8500 \
+			| hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \
+			| hexagon \
+			| i370 | i*86 | i860 | i960 | ia16 | ia64 \
+			| ip2k | iq2000 \
+			| k1om \
+			| le32 | le64 \
+			| lm32 \
+			| m32c | m32r | m32rle \
+			| m5200 | m68000 | m680[012346]0 | m68360 | m683?2 | m68k \
+			| m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x \
+			| m88110 | m88k | maxq | mb | mcore | mep | metag \
+			| microblaze | microblazeel \
+			| mips | mipsbe | mipseb | mipsel | mipsle \
+			| mips16 \
+			| mips64 | mips64eb | mips64el \
+			| mips64octeon | mips64octeonel \
+			| mips64orion | mips64orionel \
+			| mips64r5900 | mips64r5900el \
+			| mips64vr | mips64vrel \
+			| mips64vr4100 | mips64vr4100el \
+			| mips64vr4300 | mips64vr4300el \
+			| mips64vr5000 | mips64vr5000el \
+			| mips64vr5900 | mips64vr5900el \
+			| mipsisa32 | mipsisa32el \
+			| mipsisa32r2 | mipsisa32r2el \
+			| mipsisa32r6 | mipsisa32r6el \
+			| mipsisa64 | mipsisa64el \
+			| mipsisa64r2 | mipsisa64r2el \
+			| mipsisa64r6 | mipsisa64r6el \
+			| mipsisa64sb1 | mipsisa64sb1el \
+			| mipsisa64sr71k | mipsisa64sr71kel \
+			| mipsr5900 | mipsr5900el \
+			| mipstx39 | mipstx39el \
+			| mmix \
+			| mn10200 | mn10300 \
+			| moxie \
+			| mt \
+			| msp430 \
+			| nds32 | nds32le | nds32be \
+			| nfp \
+			| nios | nios2 | nios2eb | nios2el \
+			| none | np1 | ns16k | ns32k | nvptx \
+			| open8 \
+			| or1k* \
+			| or32 \
+			| orion \
+			| picochip \
+			| pdp10 | pdp11 | pj | pjl | pn | power \
+			| powerpc | powerpc64 | powerpc64le | powerpcle | powerpcspe \
+			| pru \
+			| pyramid \
+			| riscv | riscv32 | riscv64 \
+			| rl78 | romp | rs6000 | rx \
+			| score \
+			| sh | shl \
+			| sh[1234] | sh[24]a | sh[24]ae[lb] | sh[23]e | she[lb] | sh[lb]e \
+			| sh[1234]e[lb] |  sh[12345][lb]e | sh[23]ele | sh64 | sh64le \
+			| sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet \
+			| sparclite \
+			| sparcv8 | sparcv9 | sparcv9b | sparcv9v | sv1 | sx* \
+			| spu \
+			| tahoe \
+			| tic30 | tic4x | tic54x | tic55x | tic6x | tic80 \
+			| tron \
+			| ubicom32 \
+			| v70 | v850 | v850e | v850e1 | v850es | v850e2 | v850e2v3 \
+			| vax \
+			| visium \
+			| w65 \
+			| wasm32 | wasm64 \
+			| we32k \
+			| x86 | x86_64 | xc16x | xgate | xps100 \
+			| xstormy16 | xtensa* \
+			| ymp \
+			| z8k | z80)
+				;;
+
+			*)
+				echo Invalid configuration \`"$1"\': machine \`"$cpu-$vendor"\' not recognized 1>&2
+				exit 1
+				;;
+		esac
 		;;
 esac
 
 # Here we canonicalize certain aliases for manufacturers.
-case $basic_machine in
-	*-digital*)
-		basic_machine=`echo "$basic_machine" | sed 's/digital.*/dec/'`
+case $vendor in
+	digital*)
+		vendor=dec
 		;;
-	*-commodore*)
-		basic_machine=`echo "$basic_machine" | sed 's/commodore.*/cbm/'`
+	commodore*)
+		vendor=cbm
 		;;
 	*)
 		;;
@@ -1334,199 +1275,243 @@
 
 # Decode manufacturer-specific aliases for certain operating systems.
 
-if [ x"$os" != x"" ]
+if [ x$os != x ]
 then
 case $os in
 	# First match some system type aliases that might get confused
 	# with valid system types.
-	# -solaris* is a basic system type, with this one exception.
-	-auroraux)
-		os=-auroraux
+	# solaris* is a basic system type, with this one exception.
+	auroraux)
+		os=auroraux
 		;;
-	-solaris1 | -solaris1.*)
+	bluegene*)
+		os=cnk
+		;;
+	solaris1 | solaris1.*)
 		os=`echo $os | sed -e 's|solaris1|sunos4|'`
 		;;
-	-solaris)
-		os=-solaris2
+	solaris)
+		os=solaris2
 		;;
-	-unixware*)
-		os=-sysv4.2uw
+	unixware*)
+		os=sysv4.2uw
 		;;
-	-gnu/linux*)
+	gnu/linux*)
 		os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'`
 		;;
 	# es1800 is here to avoid being matched by es* (a different OS)
-	-es1800*)
-		os=-ose
+	es1800*)
+		os=ose
 		;;
+	# Some version numbers need modification
+	chorusos*)
+		os=chorusos
+		;;
+	isc)
+		os=isc2.2
+		;;
+	sco6)
+		os=sco5v6
+		;;
+	sco5)
+		os=sco3.2v5
+		;;
+	sco4)
+		os=sco3.2v4
+		;;
+	sco3.2.[4-9]*)
+		os=`echo $os | sed -e 's/sco3.2./sco3.2v/'`
+		;;
+	sco3.2v[4-9]* | sco5v6*)
+		# Don't forget version if it is 3.2v4 or newer.
+		;;
+	scout)
+		# Don't match below
+		;;
+	sco*)
+		os=sco3.2v2
+		;;
+	psos*)
+		os=psos
+		;;
 	# Now accept the basic system types.
 	# The portable systems comes first.
 	# Each alternative MUST end in a * to match a version number.
-	# -sysv* is not here because it comes later, after sysvr4.
-	-gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \
-	      | -*vms* | -sco* | -esix* | -isc* | -aix* | -cnk* | -sunos | -sunos[34]*\
-	      | -hpux* | -unos* | -osf* | -luna* | -dgux* | -auroraux* | -solaris* \
-	      | -sym* | -kopensolaris* | -plan9* \
-	      | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \
-	      | -aos* | -aros* | -cloudabi* | -sortix* \
-	      | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \
-	      | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \
-	      | -hiux* | -knetbsd* | -mirbsd* | -netbsd* \
-	      | -bitrig* | -openbsd* | -solidbsd* | -libertybsd* \
-	      | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \
-	      | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \
-	      | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \
-	      | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* | -hcos* \
-	      | -chorusos* | -chorusrdb* | -cegcc* | -glidix* \
-	      | -cygwin* | -msys* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
-	      | -midipix* | -mingw32* | -mingw64* | -linux-gnu* | -linux-android* \
-	      | -linux-newlib* | -linux-musl* | -linux-uclibc* \
-	      | -uxpv* | -beos* | -mpeix* | -udk* | -moxiebox* \
-	      | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* \
-	      | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \
-	      | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \
-	      | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \
-	      | -morphos* | -superux* | -rtmk* | -windiss* \
-	      | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \
-	      | -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es* \
-	      | -onefs* | -tirtos* | -phoenix* | -fuchsia* | -redox* | -bme* \
-	      | -midnightbsd*)
+	# sysv* is not here because it comes later, after sysvr4.
+	gnu* | bsd* | mach* | minix* | genix* | ultrix* | irix* \
+	     | *vms* | esix* | aix* | cnk* | sunos | sunos[34]*\
+	     | hpux* | unos* | osf* | luna* | dgux* | auroraux* | solaris* \
+	     | sym* | kopensolaris* | plan9* \
+	     | amigaos* | amigados* | msdos* | newsos* | unicos* | aof* \
+	     | aos* | aros* | cloudabi* | sortix* | twizzler* \
+	     | nindy* | vxsim* | vxworks* | ebmon* | hms* | mvs* \
+	     | clix* | riscos* | uniplus* | iris* | isc* | rtu* | xenix* \
+	     | knetbsd* | mirbsd* | netbsd* \
+	     | bitrig* | openbsd* | solidbsd* | libertybsd* | os108* \
+	     | ekkobsd* | kfreebsd* | freebsd* | riscix* | lynxos* \
+	     | bosx* | nextstep* | cxux* | aout* | elf* | oabi* \
+	     | ptx* | coff* | ecoff* | winnt* | domain* | vsta* \
+	     | udi* | eabi* | lites* | ieee* | go32* | aux* | hcos* \
+	     | chorusrdb* | cegcc* | glidix* \
+	     | cygwin* | msys* | pe* | moss* | proelf* | rtems* \
+	     | midipix* | mingw32* | mingw64* | linux-gnu* | linux-android* \
+	     | linux-newlib* | linux-musl* | linux-uclibc* \
+	     | uxpv* | beos* | mpeix* | udk* | moxiebox* \
+	     | interix* | uwin* | mks* | rhapsody* | darwin* \
+	     | openstep* | oskit* | conix* | pw32* | nonstopux* \
+	     | storm-chaos* | tops10* | tenex* | tops20* | its* \
+	     | os2* | vos* | palmos* | uclinux* | nucleus* \
+	     | morphos* | superux* | rtmk* | windiss* \
+	     | powermax* | dnix* | nx6 | nx7 | sei* | dragonfly* \
+	     | skyos* | haiku* | rdos* | toppers* | drops* | es* \
+	     | onefs* | tirtos* | phoenix* | fuchsia* | redox* | bme* \
+	     | midnightbsd* | amdhsa* | unleashed* | emscripten* | wasi* \
+	     | nsk* | powerunix)
 	# Remember, each alternative MUST END IN *, to match a version number.
 		;;
-	-qnx*)
-		case $basic_machine in
-		    x86-* | i*86-*)
+	qnx*)
+		case $cpu in
+		    x86 | i*86)
 			;;
 		    *)
-			os=-nto$os
+			os=nto-$os
 			;;
 		esac
 		;;
-	-nto-qnx*)
+	hiux*)
+		os=hiuxwe2
 		;;
-	-nto*)
+	nto-qnx*)
+		;;
+	nto*)
 		os=`echo $os | sed -e 's|nto|nto-qnx|'`
 		;;
-	-sim | -xray | -os68k* | -v88r* \
-	      | -windows* | -osx | -abug | -netware* | -os9* \
-	      | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*)
+	sim | xray | os68k* | v88r* \
+	    | windows* | osx | abug | netware* | os9* \
+	    | macos* | mpw* | magic* | mmixware* | mon960* | lnews*)
 		;;
-	-mac*)
+	linux-dietlibc)
+		os=linux-dietlibc
+		;;
+	linux*)
+		os=`echo $os | sed -e 's|linux|linux-gnu|'`
+		;;
+	lynx*178)
+		os=lynxos178
+		;;
+	lynx*5)
+		os=lynxos5
+		;;
+	lynx*)
+		os=lynxos
+		;;
+	mac*)
 		os=`echo "$os" | sed -e 's|mac|macos|'`
 		;;
-	-linux-dietlibc)
-		os=-linux-dietlibc
+	opened*)
+		os=openedition
 		;;
-	-linux*)
-		os=`echo $os | sed -e 's|linux|linux-gnu|'`
+	os400*)
+		os=os400
 		;;
-	-sunos5*)
+	sunos5*)
 		os=`echo "$os" | sed -e 's|sunos5|solaris2|'`
 		;;
-	-sunos6*)
+	sunos6*)
 		os=`echo "$os" | sed -e 's|sunos6|solaris3|'`
 		;;
-	-opened*)
-		os=-openedition
+	wince*)
+		os=wince
 		;;
-	-os400*)
-		os=-os400
+	utek*)
+		os=bsd
 		;;
-	-wince*)
-		os=-wince
+	dynix*)
+		os=bsd
 		;;
-	-utek*)
-		os=-bsd
+	acis*)
+		os=aos
 		;;
-	-dynix*)
-		os=-bsd
+	atheos*)
+		os=atheos
 		;;
-	-acis*)
-		os=-aos
+	syllable*)
+		os=syllable
 		;;
-	-atheos*)
-		os=-atheos
+	386bsd)
+		os=bsd
 		;;
-	-syllable*)
-		os=-syllable
+	ctix* | uts*)
+		os=sysv
 		;;
-	-386bsd)
-		os=-bsd
+	nova*)
+		os=rtmk-nova
 		;;
-	-ctix* | -uts*)
-		os=-sysv
+	ns2)
+		os=nextstep2
 		;;
-	-nova*)
-		os=-rtmk-nova
-		;;
-	-ns2)
-		os=-nextstep2
-		;;
-	-nsk*)
-		os=-nsk
-		;;
 	# Preserve the version number of sinix5.
-	-sinix5.*)
+	sinix5.*)
 		os=`echo $os | sed -e 's|sinix|sysv|'`
 		;;
-	-sinix*)
-		os=-sysv4
+	sinix*)
+		os=sysv4
 		;;
-	-tpf*)
-		os=-tpf
+	tpf*)
+		os=tpf
 		;;
-	-triton*)
-		os=-sysv3
+	triton*)
+		os=sysv3
 		;;
-	-oss*)
-		os=-sysv3
+	oss*)
+		os=sysv3
 		;;
-	-svr4*)
-		os=-sysv4
+	svr4*)
+		os=sysv4
 		;;
-	-svr3)
-		os=-sysv3
+	svr3)
+		os=sysv3
 		;;
-	-sysvr4)
-		os=-sysv4
+	sysvr4)
+		os=sysv4
 		;;
-	# This must come after -sysvr4.
-	-sysv*)
+	# This must come after sysvr4.
+	sysv*)
 		;;
-	-ose*)
-		os=-ose
+	ose*)
+		os=ose
 		;;
-	-*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)
-		os=-mint
+	*mint | mint[0-9]* | *MiNT | MiNT[0-9]*)
+		os=mint
 		;;
-	-zvmoe)
-		os=-zvmoe
+	zvmoe)
+		os=zvmoe
 		;;
-	-dicos*)
-		os=-dicos
+	dicos*)
+		os=dicos
 		;;
-	-pikeos*)
+	pikeos*)
 		# Until real need of OS specific support for
 		# particular features comes up, bare metal
 		# configurations are quite functional.
-		case $basic_machine in
+		case $cpu in
 		    arm*)
-			os=-eabi
+			os=eabi
 			;;
 		    *)
-			os=-elf
+			os=elf
 			;;
 		esac
 		;;
-	-nacl*)
+	nacl*)
 		;;
-	-ios)
+	ios)
 		;;
-	-none)
+	none)
 		;;
+	*-eabi)
+		;;
 	*)
-		# Get rid of the `-' at the beginning of $os.
-		os=`echo $os | sed 's/[^-]*-//'`
 		echo Invalid configuration \`"$1"\': system \`"$os"\' not recognized 1>&2
 		exit 1
 		;;
@@ -1543,175 +1528,181 @@
 # will signal an error saying that MANUFACTURER isn't an operating
 # system, and we'll never get to this point.
 
-case $basic_machine in
+case $cpu-$vendor in
 	score-*)
-		os=-elf
+		os=elf
 		;;
 	spu-*)
-		os=-elf
+		os=elf
 		;;
 	*-acorn)
-		os=-riscix1.2
+		os=riscix1.2
 		;;
 	arm*-rebel)
-		os=-linux
+		os=linux
 		;;
 	arm*-semi)
-		os=-aout
+		os=aout
 		;;
 	c4x-* | tic4x-*)
-		os=-coff
+		os=coff
 		;;
 	c8051-*)
-		os=-elf
+		os=elf
 		;;
+	clipper-intergraph)
+		os=clix
+		;;
 	hexagon-*)
-		os=-elf
+		os=elf
 		;;
 	tic54x-*)
-		os=-coff
+		os=coff
 		;;
 	tic55x-*)
-		os=-coff
+		os=coff
 		;;
 	tic6x-*)
-		os=-coff
+		os=coff
 		;;
 	# This must come before the *-dec entry.
 	pdp10-*)
-		os=-tops20
+		os=tops20
 		;;
 	pdp11-*)
-		os=-none
+		os=none
 		;;
 	*-dec | vax-*)
-		os=-ultrix4.2
+		os=ultrix4.2
 		;;
 	m68*-apollo)
-		os=-domain
+		os=domain
 		;;
 	i386-sun)
-		os=-sunos4.0.2
+		os=sunos4.0.2
 		;;
 	m68000-sun)
-		os=-sunos3
+		os=sunos3
 		;;
 	m68*-cisco)
-		os=-aout
+		os=aout
 		;;
 	mep-*)
-		os=-elf
+		os=elf
 		;;
 	mips*-cisco)
-		os=-elf
+		os=elf
 		;;
 	mips*-*)
-		os=-elf
+		os=elf
 		;;
 	or32-*)
-		os=-coff
+		os=coff
 		;;
 	*-tti)	# must be before sparc entry or we get the wrong os.
-		os=-sysv3
+		os=sysv3
 		;;
 	sparc-* | *-sun)
-		os=-sunos4.1.1
+		os=sunos4.1.1
 		;;
 	pru-*)
-		os=-elf
+		os=elf
 		;;
 	*-be)
-		os=-beos
+		os=beos
 		;;
 	*-ibm)
-		os=-aix
+		os=aix
 		;;
 	*-knuth)
-		os=-mmixware
+		os=mmixware
 		;;
 	*-wec)
-		os=-proelf
+		os=proelf
 		;;
 	*-winbond)
-		os=-proelf
+		os=proelf
 		;;
 	*-oki)
-		os=-proelf
+		os=proelf
 		;;
 	*-hp)
-		os=-hpux
+		os=hpux
 		;;
 	*-hitachi)
-		os=-hiux
+		os=hiux
 		;;
 	i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent)
-		os=-sysv
+		os=sysv
 		;;
 	*-cbm)
-		os=-amigaos
+		os=amigaos
 		;;
 	*-dg)
-		os=-dgux
+		os=dgux
 		;;
 	*-dolphin)
-		os=-sysv3
+		os=sysv3
 		;;
 	m68k-ccur)
-		os=-rtu
+		os=rtu
 		;;
 	m88k-omron*)
-		os=-luna
+		os=luna
 		;;
 	*-next)
-		os=-nextstep
+		os=nextstep
 		;;
 	*-sequent)
-		os=-ptx
+		os=ptx
 		;;
 	*-crds)
-		os=-unos
+		os=unos
 		;;
 	*-ns)
-		os=-genix
+		os=genix
 		;;
 	i370-*)
-		os=-mvs
+		os=mvs
 		;;
 	*-gould)
-		os=-sysv
+		os=sysv
 		;;
 	*-highlevel)
-		os=-bsd
+		os=bsd
 		;;
 	*-encore)
-		os=-bsd
+		os=bsd
 		;;
 	*-sgi)
-		os=-irix
+		os=irix
 		;;
 	*-siemens)
-		os=-sysv4
+		os=sysv4
 		;;
 	*-masscomp)
-		os=-rtu
+		os=rtu
 		;;
 	f30[01]-fujitsu | f700-fujitsu)
-		os=-uxpv
+		os=uxpv
 		;;
 	*-rom68k)
-		os=-coff
+		os=coff
 		;;
 	*-*bug)
-		os=-coff
+		os=coff
 		;;
 	*-apple)
-		os=-macos
+		os=macos
 		;;
 	*-atari*)
-		os=-mint
+		os=mint
 		;;
+	*-wrs)
+		os=vxworks
+		;;
 	*)
-		os=-none
+		os=none
 		;;
 esac
 fi
@@ -1718,79 +1709,80 @@
 
 # Here we handle the case where we know the os, and the CPU type, but not the
 # manufacturer.  We pick the logical manufacturer.
-vendor=unknown
-case $basic_machine in
-	*-unknown)
+case $vendor in
+	unknown)
 		case $os in
-			-riscix*)
+			riscix*)
 				vendor=acorn
 				;;
-			-sunos*)
+			sunos*)
 				vendor=sun
 				;;
-			-cnk*|-aix*)
+			cnk*|-aix*)
 				vendor=ibm
 				;;
-			-beos*)
+			beos*)
 				vendor=be
 				;;
-			-hpux*)
+			hpux*)
 				vendor=hp
 				;;
-			-mpeix*)
+			mpeix*)
 				vendor=hp
 				;;
-			-hiux*)
+			hiux*)
 				vendor=hitachi
 				;;
-			-unos*)
+			unos*)
 				vendor=crds
 				;;
-			-dgux*)
+			dgux*)
 				vendor=dg
 				;;
-			-luna*)
+			luna*)
 				vendor=omron
 				;;
-			-genix*)
+			genix*)
 				vendor=ns
 				;;
-			-mvs* | -opened*)
+			clix*)
+				vendor=intergraph
+				;;
+			mvs* | opened*)
 				vendor=ibm
 				;;
-			-os400*)
+			os400*)
 				vendor=ibm
 				;;
-			-ptx*)
+			ptx*)
 				vendor=sequent
 				;;
-			-tpf*)
+			tpf*)
 				vendor=ibm
 				;;
-			-vxsim* | -vxworks* | -windiss*)
+			vxsim* | vxworks* | windiss*)
 				vendor=wrs
 				;;
-			-aux*)
+			aux*)
 				vendor=apple
 				;;
-			-hms*)
+			hms*)
 				vendor=hitachi
 				;;
-			-mpw* | -macos*)
+			mpw* | macos*)
 				vendor=apple
 				;;
-			-*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)
+			*mint | mint[0-9]* | *MiNT | MiNT[0-9]*)
 				vendor=atari
 				;;
-			-vos*)
+			vos*)
 				vendor=stratus
 				;;
 		esac
-		basic_machine=`echo "$basic_machine" | sed "s/unknown/$vendor/"`
 		;;
 esac
 
-echo "$basic_machine$os"
+echo "$cpu-$vendor-$os"
 exit
 
 # Local variables:

Modified: trunk/Build/source/utils/asymptote/configure
===================================================================
--- trunk/Build/source/utils/asymptote/configure	2020-03-03 22:33:26 UTC (rev 54033)
+++ trunk/Build/source/utils/asymptote/configure	2020-03-03 22:35:09 UTC (rev 54034)
@@ -1,6 +1,6 @@
 #! /bin/sh
 # Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.69 for Asymptote 2.62.
+# Generated by GNU Autoconf 2.69 for Asymptote 2.63.
 #
 # Report bugs to <http://sourceforge.net/projects/asymptote>.
 #
@@ -580,8 +580,8 @@
 # Identity of this package.
 PACKAGE_NAME='Asymptote'
 PACKAGE_TARNAME='asymptote'
-PACKAGE_VERSION='2.62'
-PACKAGE_STRING='Asymptote 2.62'
+PACKAGE_VERSION='2.63'
+PACKAGE_STRING='Asymptote 2.63'
 PACKAGE_BUGREPORT='http://sourceforge.net/projects/asymptote'
 PACKAGE_URL=''
 
@@ -1287,7 +1287,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.62 to adapt to many kinds of systems.
+\`configure' configures Asymptote 2.63 to adapt to many kinds of systems.
 
 Usage: $0 [OPTION]... [VAR=VALUE]...
 
@@ -1352,7 +1352,7 @@
 
 if test -n "$ac_init_help"; then
   case $ac_init_help in
-     short | recursive ) echo "Configuration of Asymptote 2.62:";;
+     short | recursive ) echo "Configuration of Asymptote 2.63:";;
    esac
   cat <<\_ACEOF
 
@@ -1469,7 +1469,7 @@
 test -n "$ac_init_help" && exit $ac_status
 if $ac_init_version; then
   cat <<\_ACEOF
-Asymptote configure 2.62
+Asymptote configure 2.63
 generated by GNU Autoconf 2.69
 
 Copyright (C) 2012 Free Software Foundation, Inc.
@@ -2055,7 +2055,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.62, which was
+It was created by Asymptote $as_me 2.63, which was
 generated by GNU Autoconf 2.69.  Invocation command line was
 
   $ $0 $@
@@ -6808,19 +6808,133 @@
 else
   { $as_echo "$as_me:${as_lineno-$LINENO}: *** Could not find GNU readline 4.3 or later: will compile without readline support ***" >&5
 $as_echo "$as_me: *** Could not find GNU readline 4.3 or later: will compile without readline support ***" >&6;}
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for readline in -ledit" >&5
+$as_echo_n "checking for readline in -ledit... " >&6; }
+if ${ac_cv_lib_edit_readline+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-ledit  $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
 
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char readline ();
+int
+main ()
+{
+return readline ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_link "$LINENO"; then :
+  ac_cv_lib_edit_readline=yes
+else
+  ac_cv_lib_edit_readline=no
 fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_edit_readline" >&5
+$as_echo "$ac_cv_lib_edit_readline" >&6; }
+if test "x$ac_cv_lib_edit_readline" = xyes; then :
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_LIBEDIT 1
+_ACEOF
 
+  LIBS="-ledit $LIBS"
 
+fi
+
+for ac_header in editline/readline.h
+do :
+  ac_fn_cxx_check_header_mongrel "$LINENO" "editline/readline.h" "ac_cv_header_editline_readline_h" "$ac_includes_default"
+if test "x$ac_cv_header_editline_readline_h" = xyes; then :
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_EDITLINE_READLINE_H 1
+_ACEOF
+
+fi
+
+done
+
+
+fi
+
+
 else
 
 { $as_echo "$as_me:${as_lineno-$LINENO}: *** Could not find GNU readline 4.3 or later: will compile without readline support ***" >&5
 $as_echo "$as_me: *** Could not find GNU readline 4.3 or later: will compile without readline support ***" >&6;}
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for readline in -ledit" >&5
+$as_echo_n "checking for readline in -ledit... " >&6; }
+if ${ac_cv_lib_edit_readline+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-ledit  $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
 
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char readline ();
+int
+main ()
+{
+return readline ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_link "$LINENO"; then :
+  ac_cv_lib_edit_readline=yes
+else
+  ac_cv_lib_edit_readline=no
 fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_edit_readline" >&5
+$as_echo "$ac_cv_lib_edit_readline" >&6; }
+if test "x$ac_cv_lib_edit_readline" = xyes; then :
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_LIBEDIT 1
+_ACEOF
 
+  LIBS="-ledit $LIBS"
+
 fi
 
+for ac_header in editline/readline.h
+do :
+  ac_fn_cxx_check_header_mongrel "$LINENO" "editline/readline.h" "ac_cv_header_editline_readline_h" "$ac_includes_default"
+if test "x$ac_cv_header_editline_readline_h" = xyes; then :
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_EDITLINE_READLINE_H 1
+_ACEOF
+
+fi
+
+done
+
+
+fi
+
+fi
+
 LDFLAGS=$LDFLAGS0
 
 else
@@ -6827,8 +6941,65 @@
 
 { $as_echo "$as_me:${as_lineno-$LINENO}: *** Could not find GNU readline 4.3 or later: will compile without readline support ***" >&5
 $as_echo "$as_me: *** Could not find GNU readline 4.3 or later: will compile without readline support ***" >&6;}
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for readline in -ledit" >&5
+$as_echo_n "checking for readline in -ledit... " >&6; }
+if ${ac_cv_lib_edit_readline+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-ledit  $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
 
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char readline ();
+int
+main ()
+{
+return readline ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_link "$LINENO"; then :
+  ac_cv_lib_edit_readline=yes
+else
+  ac_cv_lib_edit_readline=no
 fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_edit_readline" >&5
+$as_echo "$ac_cv_lib_edit_readline" >&6; }
+if test "x$ac_cv_lib_edit_readline" = xyes; then :
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_LIBEDIT 1
+_ACEOF
+
+  LIBS="-ledit $LIBS"
+
+fi
+
+for ac_header in editline/readline.h
+do :
+  ac_fn_cxx_check_header_mongrel "$LINENO" "editline/readline.h" "ac_cv_header_editline_readline_h" "$ac_includes_default"
+if test "x$ac_cv_header_editline_readline_h" = xyes; then :
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_EDITLINE_READLINE_H 1
+_ACEOF
+
+fi
+
+done
+
+
+fi
 rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
 
 
@@ -7663,7 +7834,8 @@
 
 $as_echo "#define HAVE_LIBGL 1" >>confdefs.h
 
-                             LIBS=$LIBS"-lopengl32 glew.o"
+                             LIBS=$LIBS"-lopengl32 "
+                             GLEW="glew.o "
 else
   { $as_echo "$as_me:${as_lineno-$LINENO}: *** Could not find libopengl32: will compile without OpenGL support ***" >&5
 $as_echo "$as_me: *** Could not find libopengl32: will compile without OpenGL support ***" >&6;}
@@ -7730,7 +7902,8 @@
 
 $as_echo "#define HAVE_LIBGLUT 1" >>confdefs.h
 
-                           LIBS=$LIBS"-framework GLUT -framework OpenGL -framework Cocoa glew.o "
+                           LIBS=$LIBS"-framework GLUT -framework OpenGL -framework Cocoa "
+                           GLEW="glew.o "
 else
   { $as_echo "$as_me:${as_lineno-$LINENO}: *** Could not find GLUT: will compile without OpenGLLUT support ***" >&5
 $as_echo "$as_me: *** Could not find GLUT: will compile without OpenGLLUT support ***" >&6;}
@@ -8398,7 +8571,7 @@
 
 fi
 
-for ac_func in dup2 floor memset strchr tgamma lgamma memrchr
+for ac_func in dup2 floor memset strchr tgamma lgamma memrchr popcount
 do :
   as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
 ac_fn_cxx_check_func "$LINENO" "$ac_func" "$as_ac_var"
@@ -9094,7 +9267,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.62, which was
+This file was extended by Asymptote $as_me 2.63, which was
 generated by GNU Autoconf 2.69.  Invocation command line was
 
   CONFIG_FILES    = $CONFIG_FILES
@@ -9156,7 +9329,7 @@
 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.62
+Asymptote config.status 2.63
 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	2020-03-03 22:33:26 UTC (rev 54033)
+++ trunk/Build/source/utils/asymptote/configure.ac	2020-03-03 22:35:09 UTC (rev 54034)
@@ -3,7 +3,7 @@
 # this file.
 
 AC_PREREQ(2)
-AC_INIT([Asymptote],[2.62],[http://sourceforge.net/projects/asymptote])
+AC_INIT([Asymptote],[2.63],[http://sourceforge.net/projects/asymptote])
 VERSION=$PACKAGE_VERSION
 AC_SUBST(VERSION)
 m4_include([ax_pthread.m4])
@@ -282,6 +282,8 @@
 
 AC_DEFUN([READLINE],[
 AC_MSG_NOTICE([*** Could not find GNU readline 4.3 or later: will compile without readline support ***])
+AC_CHECK_LIB([edit],[readline])
+AC_CHECK_HEADERS(editline/readline.h)
 ])
 
 AC_DEFUN([CHECK_FOUND_STATIC],[
@@ -394,7 +396,8 @@
               AC_CHECK_HEADER(GL/gl.h,
                                   [AC_DEFINE(HAVE_LIBGL,1,
                      DEFINE_LIB[opengl32])
-                             LIBS=$LIBS"-lopengl32 glew.o"],
+                             LIBS=$LIBS"-lopengl32 "
+                             GLEW="glew.o "],
                                    AC_MSG_NOTICE([*** Could not find libopengl32: will compile without OpenGL support ***]))
         ;;
      darwin*)
@@ -404,7 +407,8 @@
                              DEFINE([<gl.h> header]))])
               AC_CHECK_HEADER(GLUT/glut.h, [AC_DEFINE(HAVE_LIBGLUT,1,
                    DEFINE_LIB[GLUT])
-                           LIBS=$LIBS"-framework GLUT -framework OpenGL -framework Cocoa glew.o "],
+                           LIBS=$LIBS"-framework GLUT -framework OpenGL -framework Cocoa "
+                           GLEW="glew.o "],
                                  AC_MSG_NOTICE([*** Could not find GLUT: will compile without OpenGLLUT support ***]))
         ;;
      *)
@@ -442,7 +446,7 @@
 
 # Checks for library functions.
 AC_FUNC_FORK
-AC_CHECK_FUNCS([dup2 floor memset strchr tgamma lgamma memrchr])
+AC_CHECK_FUNCS([dup2 floor memset strchr tgamma lgamma memrchr popcount])
 AC_FUNC_STRFTIME
 ac_FUNC_STRPTIME
 AC_FUNC_ERROR_AT_LINE

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	2020-03-03 22:33:26 UTC (rev 54033)
+++ trunk/Build/source/utils/asymptote/doc/FAQ/asy-faq.info	2020-03-03 22:35:09 UTC (rev 54034)
@@ -10,7 +10,7 @@
 File: asy-faq.info, Node: Top, Next: Question 1.1, Up: (dir)
 
             ASYMPTOTE FREQUENTLY ASKED QUESTIONS
-                            14 Jan 2020
+                            02 Mar 2020
                           
 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/asy.1
===================================================================
--- trunk/Build/source/utils/asymptote/doc/asy.1	2020-03-03 22:33:26 UTC (rev 54033)
+++ trunk/Build/source/utils/asymptote/doc/asy.1	2020-03-03 22:35:09 UTC (rev 54034)
@@ -92,7 +92,7 @@
 Enable debugging messages [false].
 .TP
 .B \-digits n            
-Default output file precision [6].
+Default output file precision [7].
 .TP
 .B \-divisor n           
 Garbage collect using purge(divisor=n) [2].

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	2020-03-03 22:33:26 UTC (rev 54033)
+++ trunk/Build/source/utils/asymptote/doc/asymptote.texi	2020-03-03 22:35:09 UTC (rev 54034)
@@ -9,7 +9,7 @@
 @copying
 This file documents @code{Asymptote}, version @value{VERSION}.
 
- at url{http://asymptote.sourceforge.net}
+ at url{https://asymptote.sourceforge.io}
      
 Copyright @copyright{} 2004-19 Andy Hammerlindl, John Bowman, and Tom Prince.
      
@@ -261,24 +261,24 @@
 (@pxref{graph}). Examples of @code{Asymptote} code and output,
 including animations, are available at
 @quotation
- at url{http://asymptote.sourceforge.net/gallery/}
+ at url{https://asymptote.sourceforge.io/gallery/}
 @end quotation
 @noindent
 Clicking on an example file name in this manual, like
- at code{@uref{http://asymptote.sourceforge.net/gallery/Pythagoras.svg,,Pythagoras}}, will display the @acronym{PDF} output, whereas clicking on its
- at code{@uref{http://asymptote.sourceforge.net/gallery/Pythagoras.asy,,.asy}}
+ at code{@uref{https://asymptote.sourceforge.io/gallery/Pythagoras.svg,,Pythagoras}}, will display the @acronym{PDF} output, whereas clicking on its
+ at code{@uref{https://asymptote.sourceforge.io/gallery/Pythagoras.asy,,.asy}}
 extension will show the corresponding @code{Asymptote} code in a separate window.
 
 Links to many external resources, including an excellent user-written
 @code{Asymptote} tutorial can be found at
 @quotation
- at url{http://asymptote.sourceforge.net/links.html}
+ at url{https://asymptote.sourceforge.io/links.html}
 @end quotation
 @cindex reference
 @cindex quick reference
 A quick reference card for @code{Asymptote} is available at
 @quotation
- at url{http://asymptote.sourceforge.net/asyRefCard.pdf}
+ at url{https://asymptote.sourceforge.io/asyRefCard.pdf}
 @end quotation
 
 @node Installation, Tutorial, Description, Top
@@ -303,12 +303,12 @@
 @noindent
 We recommend subscribing to new release announcements at
 @quotation
- at url{http://sourceforge.net/projects/asymptote}
+ at url{https://sourceforge.net/projects/asymptote}
 @end quotation
 @noindent
 Users may also wish to monitor the @code{Asymptote} forum:
 @quotation
- at url{http://sourceforge.net/p/asymptote/discussion/409349}
+ at url{https://sourceforge.net/p/asymptote/discussion/409349}
 @end quotation
 @noindent
 
@@ -356,7 +356,7 @@
 (@pxref{Compiling from UNIX source})
 or install the @code{Asymptote} binary available at
 
- at url{http://www.macports.org/}
+ at url{https://www.macports.org/}
 
 @noindent
 Note that many @code{MacOS X} (and FreeBSD) systems lack the
@@ -382,12 +382,12 @@
 @url{http://www.cs.wisc.edu/~ghost/gsview/}.
 
 The @code{ImageMagick} package from
- at url{http://www.imagemagick.org/script/binary-releases.php} 
+ at url{https://www.imagemagick.org/script/binary-releases.php} 
 
 @noindent
 is required to support output formats other than @acronym{HTML},
 @acronym{PDF}, @acronym{SVG}, and @acronym{PNG} (@pxref{convert}).
-The @code{Python 3} interpreter from @url{http://www.python.org} is only required
+The @code{Python 3} interpreter from @url{https://www.python.org} is only required
 if you wish to try out the graphical user interface (@pxref{GUI}).
 
 @noindent
@@ -408,7 +408,7 @@
 redrawing whenever the output file is updated. The default @code{UNIX}
 @code{PostScript} viewer @code{gv} supports this (via a @code{SIGHUP}
 signal). Version @code{gv-3.6.3} or later (from
- at url{http://ftp.gnu.org/gnu/gv/}) is required for interactive mode to
+ at url{https://ftp.gnu.org/gnu/gv/}) is required for interactive mode to
 work properly.
 Users of @code{ggv} will need to enable @code{Watch file} under
 @code{Edit/Postscript Viewer Preferences}.
@@ -588,7 +588,7 @@
 the source release @code{asymptote-x.xx.src.tgz} in the subdirectory
 @code{x.xx} under
 
- at url{http://sourceforge.net/projects/asymptote/files/}
+ at url{https://sourceforge.net/projects/asymptote/files/}
 
 execute the commands:
 @verbatim
@@ -606,7 +606,7 @@
 using version @code{3.0.0} of the @code{freeglut} library. To compile
 @code{freeglut}, download
 @quotation
- at url{http://prdownloads.sourceforge.net/freeglut/freeglut-3.0.0.tar.gz}
+ at url{https://prdownloads.sourceforge.net/freeglut/freeglut-3.0.0.tar.gz}
 @end quotation
 @noindent
 and type (as the root user):
@@ -635,7 +635,7 @@
 @code{texinfo-tex} package. If you get errors from a broken @code{texinfo}
 or @code{pdftex} installation, simply put
 @quotation
- at url{http://asymptote.sourceforge.net/asymptote.pdf}
+ at url{https://asymptote.sourceforge.io/asymptote.pdf}
 @end quotation
 @noindent
 in the directory @code{doc} and repeat the command @code{make all}.
@@ -703,7 +703,7 @@
 For full functionality you should also install the Apache Software Foundation
 package @code{two-mode-mode}:
 @quotation
- at url{http://www.dedasys.com/freesoftware/files/two-mode-mode.el}
+ at url{https://www.dedasys.com/freesoftware/files/two-mode-mode.el}
 @end quotation
 @noindent
 Once installed, you can use the hybrid mode @code{lasy-mode} to edit a
@@ -800,12 +800,12 @@
 For a more thorough introduction, see the excellent @code{Asymptote}
 tutorial written by Charles Staats:
 
- at url{http://math.uchicago.edu/~cstaats/Charles_Staats_III/Notes_and_papers_files/asymptote_tutorial.pdf}
+ at url{https://math.uchicago.edu/~cstaats/Charles_Staats_III/Notes_and_papers_files/asymptote_tutorial.pdf}
 
 Another @code{Asymptote} tutorial is available as a wiki,
 with images rendered by an online Asymptote engine:
 
- at url{http://www.artofproblemsolving.com/wiki/?title=Asymptote_(Vector_Graphics_Language)}
+ at url{https://www.artofproblemsolving.com/wiki/?title=Asymptote_(Vector_Graphics_Language)}
 
 @node Drawing in batch mode, Drawing in interactive mode, Tutorial, Tutorial
 @section Drawing in batch mode
@@ -1016,8 +1016,8 @@
 @center @image{./cube}
 
 See section @ref{graph} (or the online
- at code{Asymptote} @uref{http://asymptote.sourceforge.net/gallery,,gallery} and
-external links posted at @url{http://asymptote.sourceforge.net}) for
+ at code{Asymptote} @uref{https://asymptote.sourceforge.io/gallery,,gallery} and
+external links posted at @url{https://asymptote.sourceforge.io}) for
 further examples, including two-dimensional and interactive
 three-dimensional scientific graphs. Additional examples have been
 posted by Philippe Ivaldi at @url{http://www.piprime.fr/asymptote}.
@@ -1181,8 +1181,8 @@
 the pen line width.
 
 The use of arrows, bars, and margins is illustrated by the examples
- at code{@uref{http://asymptote.sourceforge.net/gallery/Pythagoras.svg,,Pythagoras}@uref{http://asymptote.sourceforge.net/gallery/Pythagoras.asy,,.asy}} and
- at code{@uref{http://asymptote.sourceforge.net/gallery/3Dgraphs/sqrtx01.html,,sqrtx01}@uref{http://asymptote.sourceforge.net/gallery/sqrtx01.asy,,.asy}}.
+ at code{@uref{https://asymptote.sourceforge.io/gallery/Pythagoras.svg,,Pythagoras}@uref{https://asymptote.sourceforge.io/gallery/Pythagoras.asy,,.asy}} and
+ at code{@uref{https://asymptote.sourceforge.io/gallery/3Dgraphs/sqrtx01.html,,sqrtx01}@uref{https://asymptote.sourceforge.io/gallery/sqrtx01.asy,,.asy}}.
 
 The legend for a picture @code{pic} can be fit and aligned to a frame
 with the routine:
@@ -1319,7 +1319,7 @@
 The pens in @code{p} must belong to the same color space. One can use the
 functions @code{rgb(pen)} or @code{cmyk(pen)} to promote pens to a
 higher color space, as illustrated in the example file
- at code{@uref{http://asymptote.sourceforge.net/gallery/latticeshading.svg,,latticeshading}@uref{http://asymptote.sourceforge.net/gallery/latticeshading.asy,,.asy}}.
+ at code{@uref{https://asymptote.sourceforge.io/gallery/latticeshading.svg,,latticeshading}@uref{https://asymptote.sourceforge.io/gallery/latticeshading.asy,,.asy}}.
 
 @cindex @code{axialshade}
 Axial gradient shading varying smoothly from @code{pena} to @code{penb} in the
@@ -1348,7 +1348,7 @@
 The boolean parameters @code{extenda} and @code{extendb} indicate
 whether the shading should extend beyond the radii @code{a} and @code{b}.
 Illustrations of radial shading are provided in the example files
- at code{@uref{http://asymptote.sourceforge.net/gallery/shade.svg,,shade}@uref{http://asymptote.sourceforge.net/gallery/shade.asy,,.asy}}, @code{@uref{http://asymptote.sourceforge.net/gallery/ring.pdf,,ring}@uref{http://asymptote.sourceforge.net/gallery/ring.asy,,.asy}}, and @code{@uref{http://asymptote.sourceforge.net/gallery/shadestroke.pdf,,shadestroke}@uref{http://asymptote.sourceforge.net/gallery/shadestroke.asy,,.asy}}.
+ at code{@uref{https://asymptote.sourceforge.io/gallery/shade.svg,,shade}@uref{https://asymptote.sourceforge.io/gallery/shade.asy,,.asy}}, @code{@uref{https://asymptote.sourceforge.io/gallery/ring.pdf,,ring}@uref{https://asymptote.sourceforge.io/gallery/ring.asy,,.asy}}, and @code{@uref{https://asymptote.sourceforge.io/gallery/shadestroke.pdf,,shadestroke}@uref{https://asymptote.sourceforge.io/gallery/shadestroke.asy,,.asy}}.
 
 @cindex @code{gouraudshade}
 Gouraud shading using fill rule @code{fillrule} and the vertex colors in the
@@ -1365,7 +1365,7 @@
 In the second form, the elements of @code{z} are taken to be successive
 nodes of path @code{g}. The pens in @code{p} must belong to the same
 color space. Illustrations of Gouraud shading are provided in the example file
- at code{@uref{http://asymptote.sourceforge.net/gallery/Gouraud.pdf,,Gouraud}@uref{http://asymptote.sourceforge.net/gallery/Gouraud.asy,,.asy}}.
+ at code{@uref{https://asymptote.sourceforge.io/gallery/Gouraud.pdf,,Gouraud}@uref{https://asymptote.sourceforge.io/gallery/Gouraud.asy,,.asy}}.
 The edge flags used in Gouraud shading are documented here:
 @quotation
 @url{https://www.adobe.com/content/dam/acom/en/devnet/postscript/pdfs/TN5600.SmoothShading.pdf}
@@ -1403,8 +1403,8 @@
 @end verbatim
 @noindent
 Illustrations of tensor product and Coons shading are provided in the
-example files @code{@uref{http://asymptote.sourceforge.net/gallery/tensor.pdf,,tensor}@uref{http://asymptote.sourceforge.net/gallery/tensor.asy,,.asy}}, @code{@uref{http://asymptote.sourceforge.net/gallery/Coons.pdf,,Coons}@uref{http://asymptote.sourceforge.net/gallery/Coons.asy,,.asy}}, @code{@uref{http://asymptote.sourceforge.net/gallery/3Dwebgl/BezierPatch.pdf,,BezierPatch}@uref{http://asymptote.sourceforge.net/gallery/3Dwebgl/BezierPatch.asy,,.asy}},
-and @code{@uref{http://asymptote.sourceforge.net/gallery/rainbow.pdf,,rainbow}@uref{http://asymptote.sourceforge.net/gallery/rainbow.asy,,.asy}}.
+example files @code{@uref{https://asymptote.sourceforge.io/gallery/tensor.pdf,,tensor}@uref{https://asymptote.sourceforge.io/gallery/tensor.asy,,.asy}}, @code{@uref{https://asymptote.sourceforge.io/gallery/Coons.pdf,,Coons}@uref{https://asymptote.sourceforge.io/gallery/Coons.asy,,.asy}}, @code{@uref{https://asymptote.sourceforge.io/gallery/3Dwebgl/BezierPatch.pdf,,BezierPatch}@uref{https://asymptote.sourceforge.io/gallery/3Dwebgl/BezierPatch.asy,,.asy}},
+and @code{@uref{https://asymptote.sourceforge.io/gallery/rainbow.pdf,,rainbow}@uref{https://asymptote.sourceforge.io/gallery/rainbow.asy,,.asy}}.
     
 @cindex Function shading
 @cindex function shading
@@ -1420,7 +1420,7 @@
 to fill rule @code{fillrule} using the @code{PostScript} calculator routine
 specified by the string @code{shader}; this routine takes 2 arguments,
 each in [0,1], and returns @code{colors(fillrule).length} color components.
-Function shading is illustrated in the example @code{@uref{http://asymptote.sourceforge.net/gallery/functionshading.pdf,,functionshading}@uref{http://asymptote.sourceforge.net/gallery/functionshading.asy,,.asy}}.
+Function shading is illustrated in the example @code{@uref{https://asymptote.sourceforge.io/gallery/functionshading.pdf,,functionshading}@uref{https://asymptote.sourceforge.io/gallery/functionshading.asy,,.asy}}.
 
 @cindex unfill
 The following routine uses @code{evenodd} clipping together with the
@@ -1578,7 +1578,7 @@
 The @code{string baseline(string s, string template="\strut")} 
 function can be used to enlarge the bounding box of labels to match a
 given template, so that their baselines will be typeset on a
-horizontal line. See @code{@uref{http://asymptote.sourceforge.net/gallery/Pythagoras.svg,,Pythagoras}@uref{http://asymptote.sourceforge.net/gallery/Pythagoras.asy,,.asy}} for an example.
+horizontal line. See @code{@uref{https://asymptote.sourceforge.io/gallery/Pythagoras.svg,,Pythagoras}@uref{https://asymptote.sourceforge.io/gallery/Pythagoras.asy,,.asy}} for an example.
 
 One can prevent labels from overwriting one another with the
 @code{overwrite} pen attribute (@pxref{overwrite}).
@@ -3153,7 +3153,7 @@
 @code{ImageMagick} @code{convert} program.
 Labels are always drawn with an @code{opacity} of 1.
 A simple example of transparent filling is provided in the example file
- at code{@uref{http://asymptote.sourceforge.net/gallery/transparency.svg,,transparency}@uref{http://asymptote.sourceforge.net/gallery/transparency.asy,,.asy}}. 
+ at code{@uref{https://asymptote.sourceforge.io/gallery/transparency.svg,,transparency}@uref{https://asymptote.sourceforge.io/gallery/transparency.asy,,.asy}}. 
 
 @cindex patterns
 @cindex tilings
@@ -5089,7 +5089,7 @@
 @cindex @code{Pl}
 @cindex @code{zeta}
 When configured with the @acronym{GNU} Scientific Library (GSL), available from
- at url{http://www.gnu.org/software/gsl/},
+ at url{https://www.gnu.org/software/gsl/},
 @code{Asymptote} contains an internal module @code{gsl} that
 defines the airy functions @code{Ai(real)}, 
 @code{Bi(real)}, @code{Ai_deriv(real)}, @code{Bi_deriv(real)},
@@ -5456,6 +5456,16 @@
 write(f/n);
 @end verbatim
 
+ at cindex @code{fft}
+ at item pair[][] fft(pair[][] a, int sign=1)
+returns the unnormalized two-dimensional Fourier transform of @code{a}
+using the given @code{sign}.
+
+ at cindex @code{fft}
+ at item pair[][][] fft(pair[][][] a, int sign=1)
+returns the unnormalized three-dimensional Fourier transform of
+ at code{a} using the given @code{sign}.
+
 @cindex @code{dot}
 @item real dot(real[] a, real[] b)
 returns the dot product of the vectors @code{a} and @code{b}.
@@ -6201,7 +6211,7 @@
 \def\asydir{asy}
 @end verbatim
 in @code{latexusage.tex} and put the contents of
- at url{http://sourceforge.net/p/asymptote/code/HEAD/tree/trunk/asymptote/doc/latexmkrc_asydir}
+ at url{https://raw.githubusercontent.com/vectorgraphics/asymptote/HEAD/doc/latexmkrc_asydir}
 in a file @code{latexmkrc} in the same directory.
 @noindent
 External @code{Asymptote} code can be included with
@@ -6211,7 +6221,7 @@
 @end verbatim
 @noindent
 so that @code{latexmk} will recognize when the code is changed. Note that
- at code{latemk} requires @code{perl}, available from @url{http://www.perl.org/}. 
+ at code{latemk} requires @code{perl}, available from @url{https://www.perl.org/}. 
 
 @cindex @code{width}
 @cindex @code{height}
@@ -6353,11 +6363,6 @@
 returns the four complex roots of the quartic equation
 @math{ax^4+bx^3+cx^2+dx+e=0}.
 
- at cindex @code{fft}
- at item pair[][] fft(pair[][] a, int sign=1)
-returns the two-dimensional Fourier transform of a using the given
- at code{sign}.
-
 @cindex @code{time}
 @item real time(path g, real x, int n=0)
 returns the @code{n}th intersection time of path @code{g} with the vertical
@@ -6432,7 +6437,7 @@
 geometry routines, including @code{perpendicular} symbols and a @code{triangle}
 structure. Link to the documentation for the @code{geometry} module
 are posted here:
- at url{http://asymptote.sourceforge.net/links.html},
+ at url{https://asymptote.sourceforge.io/links.html},
 including an extensive set of examples,
 @url{http://www.piprime.fr/files/asymptote/geometry/}, and an index:
 @quotation
@@ -6443,7 +6448,7 @@
 @section @code{trembling}
 @cindex @code{trembling}
 This module, written by Philippe Ivaldi and illustrated in the example
- at code{@uref{http://asymptote.sourceforge.net/gallery/floatingdisk.svg,,floatingdisk}@uref{http://asymptote.sourceforge.net/gallery/floatingdisk.asy,,.asy}}, allows one to draw wavy lines, as if drawn by
+ at code{@uref{https://asymptote.sourceforge.io/gallery/floatingdisk.svg,,floatingdisk}@uref{https://asymptote.sourceforge.io/gallery/floatingdisk.asy,,.asy}}, allows one to draw wavy lines, as if drawn by
 hand.
 
 @node stats, patterns, trembling, Base modules
@@ -6502,7 +6507,7 @@
 For convenience, this module also constructs the markers
 @code{StickIntervalMarker},  @code{CrossIntervalMarker},
 @code{CircleBarIntervalMarker}, and @code{TildeIntervalMarker}
-from the above frames. The example @code{@uref{http://asymptote.sourceforge.net/gallery/markers1.svg,,markers1}@uref{http://asymptote.sourceforge.net/gallery/markers1.asy,,.asy}} illustrates the
+from the above frames. The example @code{@uref{https://asymptote.sourceforge.io/gallery/markers1.svg,,markers1}@uref{https://asymptote.sourceforge.io/gallery/markers1.asy,,.asy}} illustrates the
 use of these markers:
 
 @sp 1
@@ -6518,7 +6523,7 @@
                marker marker=nomarker);
 @end verbatim
 @noindent
-as illustrated in the example @code{@uref{http://asymptote.sourceforge.net/gallery/markers2.svg,,markers2}@uref{http://asymptote.sourceforge.net/gallery/markers2.asy,,.asy}}.
+as illustrated in the example @code{@uref{https://asymptote.sourceforge.io/gallery/markers2.svg,,markers2}@uref{https://asymptote.sourceforge.io/gallery/markers2.asy,,.asy}}.
 
 @sp 1
 @center @image{./markers2}
@@ -6533,7 +6538,7 @@
 @cindex @code{binarytree}
 This module can be used to draw an arbitrary binary tree and includes an
 input routine for the special case of a binary search tree, as
-illustrated in the example @code{@uref{http://asymptote.sourceforge.net/gallery/binarytreetest.svg,,binarytreetest}@uref{http://asymptote.sourceforge.net/gallery/binarytreetest.asy,,.asy}}:
+illustrated in the example @code{@uref{https://asymptote.sourceforge.io/gallery/binarytreetest.svg,,binarytreetest}@uref{https://asymptote.sourceforge.io/gallery/binarytreetest.asy,,.asy}}:
 @verbatiminclude binarytreetest.asy
 @sp 1
 @center @image{./binarytreetest}
@@ -6541,7 +6546,7 @@
 @node drawtree, syzygy, binarytree, Base modules
 @section @code{drawtree}
 @cindex @code{drawtree}
-This is a simple tree drawing module used by the example @code{@uref{http://asymptote.sourceforge.net/gallery/treetest.svg,,treetest}@uref{http://asymptote.sourceforge.net/gallery/treetest.asy,,.asy}}.
+This is a simple tree drawing module used by the example @code{@uref{https://asymptote.sourceforge.io/gallery/treetest.svg,,treetest}@uref{https://asymptote.sourceforge.io/gallery/treetest.asy,,.asy}}.
 
 @node syzygy, feynman, drawtree, Base modules
 @section @code{syzygy}
@@ -6548,20 +6553,20 @@
 @cindex @code{syzygy}
 This module automates the drawing of braids, relations, and syzygies,
 along with the corresponding equations, as illustrated in the example
- at code{@uref{http://asymptote.sourceforge.net/gallery/knots.svg,,knots}@uref{http://asymptote.sourceforge.net/gallery/knots.asy,,.asy}}.
+ at code{@uref{https://asymptote.sourceforge.io/gallery/knots.svg,,knots}@uref{https://asymptote.sourceforge.io/gallery/knots.asy,,.asy}}.
 
 @node feynman, roundedpath, syzygy, Base modules
 @section @code{feynman}
 @cindex @code{feynman}
 This package, contributed by Martin Wiebusch, is useful for drawing
-Feynman diagrams, as illustrated by the examples @code{@uref{http://asymptote.sourceforge.net/gallery/eetomumu.svg,,eetomumu}@uref{http://asymptote.sourceforge.net/gallery/eetomumu.asy,,.asy}}
-and @code{@uref{http://asymptote.sourceforge.net/gallery/fermi.svg,,fermi}@uref{http://asymptote.sourceforge.net/gallery/fermi.asy,,.asy}}.
+Feynman diagrams, as illustrated by the examples @code{@uref{https://asymptote.sourceforge.io/gallery/eetomumu.svg,,eetomumu}@uref{https://asymptote.sourceforge.io/gallery/eetomumu.asy,,.asy}}
+and @code{@uref{https://asymptote.sourceforge.io/gallery/fermi.svg,,fermi}@uref{https://asymptote.sourceforge.io/gallery/fermi.asy,,.asy}}.
 
 @node roundedpath, animation, feynman, Base modules
 @section @code{roundedpath}
 @cindex @code{roundedpath}
 This package, contributed by Stefan Knorr, is useful for rounding the
-sharp corners of paths, as illustrated in the example file @code{@uref{http://asymptote.sourceforge.net/gallery/roundpath.svg,,roundpath}@uref{http://asymptote.sourceforge.net/gallery/roundpath.asy,,.asy}}.
+sharp corners of paths, as illustrated in the example file @code{@uref{https://asymptote.sourceforge.io/gallery/roundpath.svg,,roundpath}@uref{https://asymptote.sourceforge.io/gallery/roundpath.asy,,.asy}}.
 
 @node animation, embed, roundedpath, Base modules
 @section @code{animation}
@@ -6570,7 +6575,7 @@
 @cindex animation
 @cindex @code{ImageMagick}
 This module allows one to generate animations, as illustrated by the
-files @code{@uref{http://asymptote.sourceforge.net/gallery/animations/wheel.gif,,wheel}@uref{http://asymptote.sourceforge.net/gallery/animations/wheel.asy,,.asy}}, @code{@uref{http://asymptote.sourceforge.net/gallery/animations/wavepacket.gif,,wavepacket}@uref{http://asymptote.sourceforge.net/gallery/animations/wavepacket.asy,,.asy}}, and @code{@uref{http://asymptote.sourceforge.net/gallery/animations/cube.gif,,cube}@uref{http://asymptote.sourceforge.net/gallery/animations/cube.asy,,.asy}} in
+files @code{@uref{https://asymptote.sourceforge.io/gallery/animations/wheel.gif,,wheel}@uref{https://asymptote.sourceforge.io/gallery/animations/wheel.asy,,.asy}}, @code{@uref{https://asymptote.sourceforge.io/gallery/animations/wavepacket.gif,,wavepacket}@uref{https://asymptote.sourceforge.io/gallery/animations/wavepacket.asy,,.asy}}, and @code{@uref{https://asymptote.sourceforge.io/gallery/animations/cube.gif,,cube}@uref{https://asymptote.sourceforge.io/gallery/animations/cube.asy,,.asy}} in
 the @code{animations} subdirectory of the examples directory. These
 animations use the @code{ImageMagick} @code{convert} program to
 merge multiple images into a @acronym{GIF} or @acronym{MPEG}
@@ -6591,9 +6596,9 @@
 @code{/usr/local/share/texmf/tex/latex/animate}). On @code{UNIX} systems,
 one must then execute the command @code{texhash}.
 
-The example @code{@uref{http://asymptote.sourceforge.net/gallery/animations/pdfmovie.pdf,,pdfmovie}@uref{http://asymptote.sourceforge.net/gallery/animations/pdfmovie.asy,,.asy}} in the @code{animations}
-directory, along with the slide presentations @code{@uref{http://asymptote.sourceforge.net/gallery/animations/slidemovies.pdf,,slidemovies}@uref{http://asymptote.sourceforge.net/gallery/animations/slidemovies.asy,,.asy}}
-and @code{@uref{http://asymptote.sourceforge.net/intro.pdf,,intro}}, illustrate the use of embedded @acronym{PDF} movies.
+The example @code{@uref{https://asymptote.sourceforge.io/gallery/animations/pdfmovie.pdf,,pdfmovie}@uref{https://asymptote.sourceforge.io/gallery/animations/pdfmovie.asy,,.asy}} in the @code{animations}
+directory, along with the slide presentations @code{@uref{https://asymptote.sourceforge.io/gallery/animations/slidemovies.pdf,,slidemovies}@uref{https://asymptote.sourceforge.io/gallery/animations/slidemovies.asy,,.asy}}
+and @code{@uref{https://asymptote.sourceforge.io/intro.pdf,,intro}}, illustrate the use of embedded @acronym{PDF} movies.
 The examples @code{inlinemovie.tex} and @code{inlinemovie3.tex} 
 show how to generate and embed @acronym{PDF} movies directly within a
 @code{LaTeX} file (@pxref{LaTeX usage}).
@@ -6628,7 +6633,7 @@
 Examples of the above two interfaces is provided in the file
 @code{embeddedmovie.asy} in the @code{animations} subdirectory of the
 examples directory and in 
- at code{@uref{http://asymptote.sourceforge.net/gallery/animations/externalmovie.pdf,,externalmovie}@uref{http://asymptote.sourceforge.net/gallery/animations/externalmovie.asy,,.asy}}.
+ at code{@uref{https://asymptote.sourceforge.io/gallery/animations/externalmovie.pdf,,externalmovie}@uref{https://asymptote.sourceforge.io/gallery/animations/externalmovie.asy,,.asy}}.
 For a higher quality embedded movie generated directly by
 @code{Asymptote}, use the @code{animate} module along with the
 @code{animate.sty} package to embed a portable @acronym{PDF} animation
@@ -6643,7 +6648,7 @@
 @cindex @code{slide}
 This package provides a simple yet high-quality facility for making
 presentation slides, including portable embedded @acronym{PDF} animations (see
-the file @code{@uref{http://asymptote.sourceforge.net/gallery/animations/slidemovies.pdf,,slidemovies}@uref{http://asymptote.sourceforge.net/gallery/animations/slidemovies.asy,,.asy}}). A simple example is provided in
+the file @code{@uref{https://asymptote.sourceforge.io/gallery/animations/slidemovies.pdf,,slidemovies}@uref{https://asymptote.sourceforge.io/gallery/animations/slidemovies.asy,,.asy}}). A simple example is provided in
 @code{slidedemo.asy}.
 
 @node MetaPost, unicode, slide, Base modules
@@ -6723,7 +6728,7 @@
 @cindex @code{labelpath}
 This module uses the @code{PSTricks} @code{pstextpath} macro to fit labels 
 along a path (properly kerned, as illustrated in the example file
- at code{@uref{http://asymptote.sourceforge.net/gallery/curvedlabel.svg,,curvedlabel}@uref{http://asymptote.sourceforge.net/gallery/curvedlabel.asy,,.asy}}), using the command
+ at code{@uref{https://asymptote.sourceforge.io/gallery/curvedlabel.svg,,curvedlabel}@uref{https://asymptote.sourceforge.io/gallery/curvedlabel.asy,,.asy}}), using the command
 @verbatim
 void labelpath(picture pic=currentpicture, Label L, path g,
                string justify=Centered, pen p=currentpen);
@@ -6742,7 +6747,7 @@
 @cindex @code{labelpath3}
 This module, contributed by Jens Schwaiger, implements a 3D version of
 @code{labelpath} that does not require the @code{PSTricks} package.
-An example is provided in @code{@uref{http://asymptote.sourceforge.net/gallery/3Dwebgl/curvedlabel3.html,,curvedlabel3}@uref{http://asymptote.sourceforge.net/gallery/3Dwebgl/curvedlabel3.asy,,.asy}}.
+An example is provided in @code{@uref{https://asymptote.sourceforge.io/gallery/3Dwebgl/curvedlabel3.html,,curvedlabel3}@uref{https://asymptote.sourceforge.io/gallery/3Dwebgl/curvedlabel3.asy,,.asy}}.
 
 @node annotate, CAD, labelpath3, Base modules
 @section @code{annotate}
@@ -6754,7 +6759,7 @@
               pair position);
 @end verbatim
 @noindent
-Annotations are illustrated in the example file @code{@uref{http://asymptote.sourceforge.net/gallery/annotation.pdf,,annotation}@uref{http://asymptote.sourceforge.net/gallery/annotation.asy,,.asy}}.
+Annotations are illustrated in the example file @code{@uref{https://asymptote.sourceforge.io/gallery/annotation.pdf,,annotation}@uref{https://asymptote.sourceforge.io/gallery/annotation.asy,,.asy}}.
 Currently, annotations are only implemented for the @code{latex}
 (default) and @code{tex} @TeX{} engines.
 
@@ -7562,8 +7567,8 @@
 
 @item The following scientific graphs, which illustrate many features of
 @code{Asymptote}'s graphics routines, were generated from the examples
- at code{@uref{http://asymptote.sourceforge.net/gallery/2Dgraphs/diatom.svg,,diatom}@uref{http://asymptote.sourceforge.net/gallery/2Dgraphs/diatom.asy,,.asy}} and @code{@uref{http://asymptote.sourceforge.net/gallery/2Dgraphs/westnile.svg,,westnile}@uref{http://asymptote.sourceforge.net/gallery/2Dgraphs/westnile.asy,,.asy}}, using the comma-separated
-data in @code{@uref{http://asymptote.sourceforge.net/gallery/2Dgraphs/diatom.csv,,diatom.csv}} and @code{@uref{http://asymptote.sourceforge.net/gallery/2Dgraphs/westnile.csv,,westnile.csv}}.
+ at code{@uref{https://asymptote.sourceforge.io/gallery/2Dgraphs/diatom.svg,,diatom}@uref{https://asymptote.sourceforge.io/gallery/2Dgraphs/diatom.asy,,.asy}} and @code{@uref{https://asymptote.sourceforge.io/gallery/2Dgraphs/westnile.svg,,westnile}@uref{https://asymptote.sourceforge.io/gallery/2Dgraphs/westnile.asy,,.asy}}, using the comma-separated
+data in @code{@uref{https://asymptote.sourceforge.io/gallery/2Dgraphs/diatom.csv,,diatom.csv}} and @code{@uref{https://asymptote.sourceforge.io/gallery/2Dgraphs/westnile.csv,,westnile.csv}}.
 @page
 
 @sp 1
@@ -7644,7 +7649,7 @@
 Here @code{Full} specifies a range varying from the
 minimum to maximum values of the function over the sampling interval,
 while @code{Automatic} selects "nice" limits. 
-The example @code{@uref{http://asymptote.sourceforge.net/gallery/2Dgraphs/imagecontour.svg,,imagecontour}@uref{http://asymptote.sourceforge.net/gallery/2Dgraphs/imagecontour.asy,,.asy}} illustrates how level sets
+The example @code{@uref{https://asymptote.sourceforge.io/gallery/2Dgraphs/imagecontour.svg,,imagecontour}@uref{https://asymptote.sourceforge.io/gallery/2Dgraphs/imagecontour.asy,,.asy}} illustrates how level sets
 (contour lines) can be drawn on a color density plot (@pxref{contour}).
 
 A color density plot can also be generated from an explicit real[][]
@@ -7872,8 +7877,8 @@
 @code{currentlight.background=black+opacity(0.0);}
 
 Sample Bezier surfaces are
-contained in the example files @code{@uref{http://asymptote.sourceforge.net/gallery/3Dwebgl/BezierSurface.html,,BezierSurface}@uref{http://asymptote.sourceforge.net/gallery/3Dwebgl/BezierSurface.asy,,.asy}}, @code{@uref{http://asymptote.sourceforge.net/gallery/3Dwebgl/teapot.html,,teapot}@uref{http://asymptote.sourceforge.net/gallery/3Dwebgl/teapot.asy,,.asy}},
-and @code{@uref{http://asymptote.sourceforge.net/gallery/3Dwebgl/parametricsurface.html,,parametricsurface}@uref{http://asymptote.sourceforge.net/gallery/3Dwebgl/parametricsurface.asy,,.asy}}. The structure @code{render} contains
+contained in the example files @code{@uref{https://asymptote.sourceforge.io/gallery/3Dwebgl/BezierSurface.html,,BezierSurface}@uref{https://asymptote.sourceforge.io/gallery/3Dwebgl/BezierSurface.asy,,.asy}}, @code{@uref{https://asymptote.sourceforge.io/gallery/3Dwebgl/teapot.html,,teapot}@uref{https://asymptote.sourceforge.io/gallery/3Dwebgl/teapot.asy,,.asy}},
+and @code{@uref{https://asymptote.sourceforge.io/gallery/3Dwebgl/parametricsurface.html,,parametricsurface}@uref{https://asymptote.sourceforge.io/gallery/3Dwebgl/parametricsurface.asy,,.asy}}. The structure @code{render} contains
 specialized rendering options documented at the beginning of module 
 @code{three}.
 
@@ -7880,9 +7885,9 @@
 @cindex patch-dependent colors
 @cindex vertex-dependent colors
 The examples
- at code{@uref{http://asymptote.sourceforge.net/gallery/3Dgraphs/elevation.html,,elevation}@uref{http://asymptote.sourceforge.net/gallery/3Dgraphs/elevation.asy,,.asy}} and @code{@uref{http://asymptote.sourceforge.net/gallery/3Dwebgl/sphericalharmonic.html,,sphericalharmonic}@uref{http://asymptote.sourceforge.net/gallery/3Dwebgl/sphericalharmonic.asy,,.asy}} 
+ at code{@uref{https://asymptote.sourceforge.io/gallery/3Dgraphs/elevation.html,,elevation}@uref{https://asymptote.sourceforge.io/gallery/3Dgraphs/elevation.asy,,.asy}} and @code{@uref{https://asymptote.sourceforge.io/gallery/3Dwebgl/sphericalharmonic.html,,sphericalharmonic}@uref{https://asymptote.sourceforge.io/gallery/3Dwebgl/sphericalharmonic.asy,,.asy}} 
 illustrate how to draw a surface with patch-dependent colors.
-The examples @code{@uref{http://asymptote.sourceforge.net/gallery/3Dwebgl/vertexshading.html,,vertexshading}@uref{http://asymptote.sourceforge.net/gallery/3Dwebgl/vertexshading.asy,,.asy}} and @code{@uref{http://asymptote.sourceforge.net/gallery/3Dgraphs/smoothelevation.html,,smoothelevation}@uref{http://asymptote.sourceforge.net/gallery/3Dgraphs/smoothelevation.asy,,.asy}} illustrate
+The examples @code{@uref{https://asymptote.sourceforge.io/gallery/3Dwebgl/vertexshading.html,,vertexshading}@uref{https://asymptote.sourceforge.io/gallery/3Dwebgl/vertexshading.asy,,.asy}} and @code{@uref{https://asymptote.sourceforge.io/gallery/3Dgraphs/smoothelevation.html,,smoothelevation}@uref{https://asymptote.sourceforge.io/gallery/3Dgraphs/smoothelevation.asy,,.asy}} illustrate
 vertex-dependent colors, which are supported by
 @code{Asymptote}'s native @code{OpenGL}/@code{WebGL} renderers
 and the two-dimensional vector output format (@code{settings.render=0}). Since
@@ -7948,7 +7953,7 @@
 optional normal data and @code{p} and @code{pi} contain optional pen
 vertex data. If more than one normal or pen is specified for a vertex, the
 last one specified is used.
-An example of this tessellation facility is given in @code{@uref{http://asymptote.sourceforge.net/gallery/3Dwebgl/triangles.html,,triangles}@uref{http://asymptote.sourceforge.net/gallery/3Dwebgl/triangles.asy,,.asy}}.
+An example of this tessellation facility is given in @code{@uref{https://asymptote.sourceforge.io/gallery/3Dwebgl/triangles.html,,triangles}@uref{https://asymptote.sourceforge.io/gallery/3Dwebgl/triangles.asy,,.asy}}.
 
 @cindex @code{thin}
 @cindex @code{thick}
@@ -8109,7 +8114,7 @@
 file (@pxref{configuration file}), or specified in the script before
 module @code{three} (or @code{graph3}) is imported.
 The @code{media9} LaTeX package is also required (@pxref{embed}).
-The example @code{@uref{http://asymptote.sourceforge.net/gallery/3Dwebgl/100d.html,,100d}@uref{http://asymptote.sourceforge.net/gallery/3Dwebgl/pdb.asy,,.asy}} illustrates 
+The example @code{@uref{https://asymptote.sourceforge.io/gallery/3Dwebgl/100d.html,,100d}@uref{https://asymptote.sourceforge.io/gallery/3Dwebgl/pdb.asy,,.asy}} illustrates 
 how one can generate a list of predefined views (see @code{100d.views}).
 A stationary preview image with a resolution of @code{n} pixels per
 @code{bp} can be embedded with the setting @code{render=n}; this allows
@@ -8454,7 +8459,7 @@
 The default interaction is @code{Billboard}, which means that labels
 are rotated interactively so that they always face the camera.
 The interaction @code{Embedded} means that the label interacts as a
-normal @code{3D} surface, as illustrated in the example @code{@uref{http://asymptote.sourceforge.net/gallery/3Dwebgl/billboard.html,,billboard}@uref{http://asymptote.sourceforge.net/gallery/3Dwebgl/billboard.asy,,.asy}}.
+normal @code{3D} surface, as illustrated in the example @code{@uref{https://asymptote.sourceforge.io/gallery/3Dwebgl/billboard.html,,billboard}@uref{https://asymptote.sourceforge.io/gallery/3Dwebgl/billboard.asy,,.asy}}.
 @cindex @code{transform}
 @cindex @code{XY}
 @cindex @code{YZ}
@@ -8484,7 +8489,7 @@
 @end verbatim
 @noindent
 to find the unit normal vector to a planar three-dimensional path @code{p}.
-As illustrated in the example @code{@uref{http://asymptote.sourceforge.net/gallery/3Dgraphs/planeproject.html,,planeproject}@uref{http://asymptote.sourceforge.net/gallery/3Dgraphs/planeproject.asy,,.asy}}, a transform3
+As illustrated in the example @code{@uref{https://asymptote.sourceforge.io/gallery/3Dgraphs/planeproject.html,,planeproject}@uref{https://asymptote.sourceforge.io/gallery/3Dgraphs/planeproject.asy,,.asy}}, a transform3
 that projects in the direction @code{dir} onto the plane defined by a
 planar path @code{p} is returned by
 @verbatim
@@ -8629,7 +8634,7 @@
 specified @code{normal} vector) are also defined:
 @code{DefaultHead2(triple normal=O)}, @code{HookHead2(triple normal=O)},
 @code{TeXHead2(triple normal=O)}. These are illustrated in the example
- at code{@uref{http://asymptote.sourceforge.net/gallery/3Dwebgl/arrows3.html,,arrows3}@uref{http://asymptote.sourceforge.net/gallery/3Dwebgl/arrows3.asy,,.asy}}. 
+ at code{@uref{https://asymptote.sourceforge.io/gallery/3Dwebgl/arrows3.html,,arrows3}@uref{https://asymptote.sourceforge.io/gallery/3Dwebgl/arrows3.asy,,.asy}}. 
 
 @cindex @code{NoMargin3}
 @cindex @code{BeginMargin3}
@@ -8671,8 +8676,8 @@
 position @code{v} using pen @code{p}.
 
 Further three-dimensional examples are provided in the files
- at code{@uref{http://asymptote.sourceforge.net/gallery/3Dgraphs/near_earth.html,,near_earth}@uref{http://asymptote.sourceforge.net/gallery/3Dgraphs/near_earth.asy,,.asy}}, @code{@uref{http://asymptote.sourceforge.net/gallery/3Dwebgl/conicurv.html,,conicurv}@uref{http://asymptote.sourceforge.net/gallery/3Dwebgl/conicurv.asy,,.asy}}, and (in the @code{animations}
-subdirectory) @code{@uref{http://asymptote.sourceforge.net/gallery/3Dwebgl/cube.html,,cube}@uref{http://asymptote.sourceforge.net/gallery/3Dwebgl/cube.asy,,.asy}}.
+ at code{@uref{https://asymptote.sourceforge.io/gallery/3Dgraphs/near_earth.html,,near_earth}@uref{https://asymptote.sourceforge.io/gallery/3Dgraphs/near_earth.asy,,.asy}}, @code{@uref{https://asymptote.sourceforge.io/gallery/3Dwebgl/conicurv.html,,conicurv}@uref{https://asymptote.sourceforge.io/gallery/3Dwebgl/conicurv.asy,,.asy}}, and (in the @code{animations}
+subdirectory) @code{@uref{https://asymptote.sourceforge.io/gallery/3Dwebgl/cube.html,,cube}@uref{https://asymptote.sourceforge.io/gallery/3Dwebgl/cube.asy,,.asy}}.
 
 @anchor{PostScript3D}
 @cindex 3D @code{PostScript}
@@ -8715,8 +8720,8 @@
 @section @code{obj}
 @cindex @code{obj}
 This module allows one to construct surfaces from simple obj files,
-as illustrated in the example files @code{@uref{http://asymptote.sourceforge.net/gallery/3Dwebgl/galleon.html,,galleon}@uref{http://asymptote.sourceforge.net/gallery/3Dwebgl/galleon.asy,,.asy}} and
- at code{@uref{http://asymptote.sourceforge.net/gallery/3Dwebgl/triceratops.html,,triceratops}@uref{http://asymptote.sourceforge.net/gallery/3Dwebgl/triceratops.asy,,.asy}}.
+as illustrated in the example files @code{@uref{https://asymptote.sourceforge.io/gallery/3Dwebgl/galleon.html,,galleon}@uref{https://asymptote.sourceforge.io/gallery/3Dwebgl/galleon.asy,,.asy}} and
+ at code{@uref{https://asymptote.sourceforge.io/gallery/3Dwebgl/triceratops.html,,triceratops}@uref{https://asymptote.sourceforge.io/gallery/3Dwebgl/triceratops.asy,,.asy}}.
 
 @node graph3, grid3, obj, Base modules
 @section @code{graph3}
@@ -8830,13 +8835,13 @@
 @noindent
 The final two versions draw parametric surfaces for a function
 @math{f(u,v)} over the parameter space @code{box(a,b)},
-as illustrated in the example @code{@uref{http://asymptote.sourceforge.net/gallery/3Dwebgl/parametricsurface.html,,parametricsurface}@uref{http://asymptote.sourceforge.net/gallery/3Dwebgl/parametricsurface.asy,,.asy}}.
+as illustrated in the example @code{@uref{https://asymptote.sourceforge.io/gallery/3Dwebgl/parametricsurface.html,,parametricsurface}@uref{https://asymptote.sourceforge.io/gallery/3Dwebgl/parametricsurface.asy,,.asy}}.
 An optional splinetype @code{Spline} may be specified.
 The boolean array or function @code{cond} can be used to control which
 surface mesh cells are actually drawn (by default all mesh cells over
 @code{box(a,b)} are drawn).
 Surface lighting is illustrated in the example files
- at code{@uref{http://asymptote.sourceforge.net/gallery/3Dwebgl/parametricsurface.html,,parametricsurface}@uref{http://asymptote.sourceforge.net/gallery/3Dwebgl/parametricsurface.asy,,.asy}} and @code{@uref{http://asymptote.sourceforge.net/gallery/3D graphs/sinc.html,,sinc}@uref{http://asymptote.sourceforge.net/gallery/3D graphs/sinc.asy,,.asy}}.
+ at code{@uref{https://asymptote.sourceforge.io/gallery/3Dwebgl/parametricsurface.html,,parametricsurface}@uref{https://asymptote.sourceforge.io/gallery/3Dwebgl/parametricsurface.asy,,.asy}} and @code{@uref{https://asymptote.sourceforge.io/gallery/3D graphs/sinc.html,,sinc}@uref{https://asymptote.sourceforge.io/gallery/3D graphs/sinc.asy,,.asy}}.
 Lighting can be disabled by setting @code{light=nolight}, as in this example
 of a Gaussian surface:
 @anchor{GaussianSurface}
@@ -8857,8 +8862,8 @@
                     bool cond(pair z)=null, pen p=currentpen,
                     arrowbar3 arrow=Arrow3, margin3 margin=PenMargin3)
 @end verbatim
-as illustrated in the examples @code{@uref{http://asymptote.sourceforge.net/gallery/3Dgraphs/vectorfield3.html,,vectorfield3}@uref{http://asymptote.sourceforge.net/gallery/3Dgraphs/vectorfield3.asy,,.asy}} and
- at code{@uref{http://asymptote.sourceforge.net/gallery/3Dgraphs/vectorfieldsphere.html,,vectorfieldsphere}@uref{http://asymptote.sourceforge.net/gallery/3Dgraphs/vectorfieldsphere.asy,,.asy}}.
+as illustrated in the examples @code{@uref{https://asymptote.sourceforge.io/gallery/3Dgraphs/vectorfield3.html,,vectorfield3}@uref{https://asymptote.sourceforge.io/gallery/3Dgraphs/vectorfield3.asy,,.asy}} and
+ at code{@uref{https://asymptote.sourceforge.io/gallery/3Dgraphs/vectorfieldsphere.html,,vectorfieldsphere}@uref{https://asymptote.sourceforge.io/gallery/3Dgraphs/vectorfieldsphere.asy,,.asy}}.
 
 @node grid3, solids, graph3, Base modules
 @section @code{grid3}
@@ -8883,8 +8888,8 @@
 @sp 1
 @center @image{./cylinderskeleton}
 
-Further illustrations are provided in the example files @code{@uref{http://asymptote.sourceforge.net/gallery/3Dwebgl/cylinder.html,,cylinder}@uref{http://asymptote.sourceforge.net/gallery/3Dwebgl/cylinder.asy,,.asy}},
- at code{@uref{http://asymptote.sourceforge.net/gallery/3Dwebgl/cones.html,,cones}@uref{http://asymptote.sourceforge.net/gallery/3Dwebgl/cones.asy,,.asy}}, @code{@uref{http://asymptote.sourceforge.net/gallery/3Dwebgl/hyperboloid.html,,hyperboloid}@uref{http://asymptote.sourceforge.net/gallery/3Dwebgl/hyperboloid.asy,,.asy}}, and @code{@uref{http://asymptote.sourceforge.net/gallery/3Dwebgl/torus.html,,torus}@uref{http://asymptote.sourceforge.net/gallery/3Dwebgl/torus.asy,,.asy}}.
+Further illustrations are provided in the example files @code{@uref{https://asymptote.sourceforge.io/gallery/3Dwebgl/cylinder.html,,cylinder}@uref{https://asymptote.sourceforge.io/gallery/3Dwebgl/cylinder.asy,,.asy}},
+ at code{@uref{https://asymptote.sourceforge.io/gallery/3Dwebgl/cones.html,,cones}@uref{https://asymptote.sourceforge.io/gallery/3Dwebgl/cones.asy,,.asy}}, @code{@uref{https://asymptote.sourceforge.io/gallery/3Dwebgl/hyperboloid.html,,hyperboloid}@uref{https://asymptote.sourceforge.io/gallery/3Dwebgl/hyperboloid.asy,,.asy}}, and @code{@uref{https://asymptote.sourceforge.io/gallery/3Dwebgl/torus.html,,torus}@uref{https://asymptote.sourceforge.io/gallery/3Dwebgl/torus.asy,,.asy}}.
 
 The structure @code{skeleton} contains the three-dimensional wireframe
 used to visualize a volume of revolution:
@@ -8905,7 +8910,7 @@
 @section @code{tube}
 @cindex @code{tube}
 This package extends the @code{tube} surfaces constructed in
- at code{@uref{http://asymptote.sourceforge.net/gallery/3Dwebgl/three_arrows.html,,three_arrows}@uref{http://asymptote.sourceforge.net/gallery/3Dwebgl/three_arrows.asy,,.asy}} to arbitrary cross sections, colors, and spine
+ at code{@uref{https://asymptote.sourceforge.io/gallery/3Dwebgl/three_arrows.html,,three_arrows}@uref{https://asymptote.sourceforge.io/gallery/3Dwebgl/three_arrows.asy,,.asy}} to arbitrary cross sections, colors, and spine
 transformations. The routine
 @verbatim
 surface tube(path3 g, coloredpath section,
@@ -8959,7 +8964,7 @@
 shading behaviour is the default shading behavior for a surface.
 
 An example of @code{tube} is provided in the file
- at code{@uref{http://asymptote.sourceforge.net/gallery/3Dwebgl/trefoilknot.html,,trefoilknot}@uref{http://asymptote.sourceforge.net/gallery/3Dwebgl/trefoilknot.asy,,.asy}}. Further examples can be found at
+ at code{@uref{https://asymptote.sourceforge.io/gallery/3Dwebgl/trefoilknot.html,,trefoilknot}@uref{https://asymptote.sourceforge.io/gallery/3Dwebgl/trefoilknot.asy,,.asy}}. Further examples can be found at
 @url{http://www.piprime.fr/files/asymptote/tube/}.
 
 @node flowchart, contour, tube, Base modules
@@ -9091,7 +9096,7 @@
 in the @code{Horizontal} or @code{Vertical} direction.
 
 Here is a simple flowchart example (see also the example
- at code{@uref{http://asymptote.sourceforge.net/gallery/3Dwebgl/controlsystem.html,,controlsystem}@uref{http://asymptote.sourceforge.net/gallery/3Dwebgl/controlsystem.asy,,.asy}}):
+ at code{@uref{https://asymptote.sourceforge.io/gallery/3Dwebgl/controlsystem.html,,controlsystem}@uref{https://asymptote.sourceforge.io/gallery/3Dwebgl/controlsystem.asy,,.asy}}):
 
 @verbatiminclude flowchartdemo.asy
 @sp 1
@@ -9186,7 +9191,7 @@
 @sp 1
 @center @image{./triangulate}
 
-The example @code{@uref{http://asymptote.sourceforge.net/gallery/2Dgraphs/Gouraudcontour.pdf,,Gouraudcontour}@uref{http://asymptote.sourceforge.net/gallery/2Dgraphs/Gouraudcontour.asy,,.asy}} illustrates how to produce color
+The example @code{@uref{https://asymptote.sourceforge.io/gallery/2Dgraphs/Gouraudcontour.pdf,,Gouraudcontour}@uref{https://asymptote.sourceforge.io/gallery/2Dgraphs/Gouraudcontour.asy,,.asy}} illustrates how to produce color
 density images over such irregular triangular meshes.
 @code{Asymptote} uses a robust version of Paul Bourke's Delaunay triangulation
 algorithm based on the public-domain exact arithmetic predicates written by
@@ -9197,7 +9202,7 @@
 @cindex @code{contour3}
 This package draws surfaces described as the null space of real-valued
 functions of @math{(x,y,z)} or @code{real[][][]} matrices.
-Its usage is illustrated in the example file @code{@uref{http://asymptote.sourceforge.net/gallery/3Dgraphs/magnetic.html,,magnetic}@uref{http://asymptote.sourceforge.net/gallery/3Dgraphs/magnetic.asy,,.asy}}.
+Its usage is illustrated in the example file @code{@uref{https://asymptote.sourceforge.io/gallery/3Dgraphs/magnetic.html,,magnetic}@uref{https://asymptote.sourceforge.io/gallery/3Dgraphs/magnetic.asy,,.asy}}.
 
 @node smoothcontour3, slopefield, contour3, Base modules
 @section @code{smoothcontour3}
@@ -9232,7 +9237,7 @@
 an artifact that can cause the renderer to ``see through'' the
 boundary between patches. Although
 it defaults to @code{false}, it should usually be set to @code{true}.
-The example @code{@uref{http://asymptote.sourceforge.net/gallery/3Dwebgl/genustwo.html,,genustwo}@uref{http://asymptote.sourceforge.net/gallery/3Dwebgl/genustwo.asy,,.asy}} illustrates the use of this function.
+The example @code{@uref{https://asymptote.sourceforge.io/gallery/3Dwebgl/genustwo.html,,genustwo}@uref{https://asymptote.sourceforge.io/gallery/3Dwebgl/genustwo.asy,,.asy}} illustrates the use of this function.
 Additional examples, together with a more in-depth explanation of 
 the module's usage and pitfalls, are available at
 @url{https://github.com/charlesstaats/smoothcontour3}.
@@ -9389,7 +9394,7 @@
 @cindex @code{libgs}
 @cindex @code{graphic}
 To produce @acronym{SVG} output, you will need @code{dvisvgm} (version
-2.6.3 or later) from @url{http://dvisvgm.sourceforge.net}.
+2.6.3 or later) from @url{https://dvisvgm.de}.
 You might need to adjust the configuration variable @code{libgs} to
 point to the location of your @code{Ghostscript} library
 @code{libgs.so} (or to an empty string, depending on how
@@ -9573,7 +9578,7 @@
 
 Interactive mode is implemented with the @acronym{GNU} @code{readline} library,
 with command history and auto-completion. To customize the key bindings, see:
- at url{http://cnswww.cns.cwru.edu/php/chet/readline/readline.html}
+ at url{https://tiswww.case.edu/php/chet/readline/readline.html}
 
 @cindex @code{Python} usage
 The file @code{asymptote.py} in the @code{Asymptote} system directory
@@ -9617,7 +9622,7 @@
 @cindex GUI installation
 
 As @code{xasy} is written in the interactive scripting language
- at code{Python/Qt}, it requires @code{Python} (@url{http://www.python.org}),
+ at code{Python/Qt}, it requires @code{Python} (@url{https://www.python.org}),
 along with the @code{Python} packages @code{pyqt5}, @code{cson}, and
 @code{numpy}:
 
@@ -9663,7 +9668,7 @@
 @chapter @code{PostScript} to @code{Asymptote}
 @cindex @code{pstoedit}
 The excellent @code{PostScript} editor @code{pstoedit} (version 3.50 or later; 
-available from @url{http://sourceforge.net/projects/pstoedit/}) includes an
+available from @url{https://sourceforge.net/projects/pstoedit/}) includes an
 @code{Asymptote} backend. Unlike virtually all other @code{pstoedit}
 backends, this driver includes native clipping, even-odd fill rule,
 @code{PostScript} subpath, and full image support. Here is an example:
@@ -9688,7 +9693,7 @@
 
 A list of frequently asked questions (@acronym{FAQ}) is maintained at
 @quotation
- at url{http://asymptote.sourceforge.net/FAQ}
+ at url{https://asymptote.sourceforge.io/FAQ}
 @end quotation
 @noindent
 Questions on installing and using @code{Asymptote} that are not
@@ -9695,7 +9700,7 @@
 addressed in the @acronym{FAQ} should be sent to the
 @code{Asymptote} forum: 
 @quotation
- at url{http://sourceforge.net/p/asymptote/discussion/409349}
+ at url{https://sourceforge.net/p/asymptote/discussion/409349}
 @end quotation
 @noindent
 Including an example that illustrates what you are trying to do will help
@@ -9705,13 +9710,13 @@
 Contributions in the form of patches or @code{Asymptote} modules can be
 posted here:
 @quotation
- at url{http://sourceforge.net/p/asymptote/patches}
+ at url{https://sourceforge.net/p/asymptote/patches}
 @end quotation
 @noindent
 To receive announcements of upcoming releases, please subscribe to
 @code{Asymptote} at
 @quotation
- at url{http://freecode.com/projects/asy}
+ at url{https://sourceforge.net/projects/asymptote/}
 @end quotation
 @cindex bug reports
 @noindent
@@ -9726,7 +9731,7 @@
 To see if the bug has already been fixed,
 check bugs with Status @code{Closed} and recent lines in
 @quotation
- at url{http://asymptote.sourceforge.net/ChangeLog}
+ at url{https://asymptote.sourceforge.io/ChangeLog}
 @end quotation
 @noindent
 
@@ -9735,7 +9740,7 @@
 @cindex @code{libsigsegv}
 @code{Asymptote} can be configured with the optional @acronym{GNU} library
 @code{libsigsegv}, available from
- at url{http://libsigsegv.sourceforge.net}, which allows one to distinguish
+ at url{https://www.gnu.org/software/libsigsegv/}, which allows one to distinguish
 user-generated @code{Asymptote} stack overflows (@pxref{stack overflow})
 from true segmentation faults (due to internal C++ programming errors;
 please submit the @code{Asymptote} code that generates such segmentation

Modified: trunk/Build/source/utils/asymptote/doc/png/asymptote.info
===================================================================
--- trunk/Build/source/utils/asymptote/doc/png/asymptote.info	2020-03-03 22:33:26 UTC (rev 54033)
+++ trunk/Build/source/utils/asymptote/doc/png/asymptote.info	2020-03-03 22:35:09 UTC (rev 54034)
@@ -1,9 +1,9 @@
 This is asymptote.info, produced by makeinfo version 6.6 from
 asymptote.texi.
 
-This file documents 'Asymptote', version 2.62.
+This file documents 'Asymptote', version 2.63.
 
-   <http://asymptote.sourceforge.net>
+   <https://asymptote.sourceforge.io>
 
    Copyright (C) 2004-19 Andy Hammerlindl, John Bowman, and Tom Prince.
 
@@ -22,9 +22,9 @@
 Asymptote
 *********
 
-This file documents 'Asymptote', version 2.62.
+This file documents 'Asymptote', version 2.63.
 
-   <http://asymptote.sourceforge.net>
+   <https://asymptote.sourceforge.io>
 
    Copyright (C) 2004-19 Andy Hammerlindl, John Bowman, and Tom Prince.
 
@@ -240,7 +240,7 @@
 tailor it to specific applications; for example, a scientific graphing
 module is available (*note graph::).  Examples of 'Asymptote' code and
 output, including animations, are available at
-     <http://asymptote.sourceforge.net/gallery/>
+     <https://asymptote.sourceforge.io/gallery/>
 Clicking on an example file name in this manual, like 'Pythagoras', will
 display the PDF output, whereas clicking on its '.asy' extension will
 show the corresponding 'Asymptote' code in a separate window.
@@ -247,9 +247,9 @@
 
    Links to many external resources, including an excellent user-written
 'Asymptote' tutorial can be found at
-     <http://asymptote.sourceforge.net/links.html>
+     <https://asymptote.sourceforge.io/links.html>
    A quick reference card for 'Asymptote' is available at
-     <http://asymptote.sourceforge.net/asyRefCard.pdf>
+     <https://asymptote.sourceforge.io/asyRefCard.pdf>
 
 
 File: asymptote.info,  Node: Installation,  Next: Tutorial,  Prev: Description,  Up: Top
@@ -273,9 +273,9 @@
 see also *note Configuring::.
 
 We recommend subscribing to new release announcements at
-     <http://sourceforge.net/projects/asymptote>
+     <https://sourceforge.net/projects/asymptote>
 Users may also wish to monitor the 'Asymptote' forum:
-     <http://sourceforge.net/p/asymptote/discussion/409349>
+     <https://sourceforge.net/p/asymptote/discussion/409349>
 
 
 File: asymptote.info,  Node: UNIX binary distributions,  Next: MacOS X binary distributions,  Prev: Installation,  Up: Installation
@@ -313,7 +313,7 @@
 Compiling from UNIX source::) or install the 'Asymptote' binary
 available at
 
-   <http://www.macports.org/>
+   <https://www.macports.org/>
 
 Note that many 'MacOS X' (and FreeBSD) systems lack the GNU 'readline'
 library.  For full interactive functionality, GNU 'readline' version 4.3
@@ -339,11 +339,11 @@
 available from <http://www.cs.wisc.edu/~ghost/gsview/>.
 
    The 'ImageMagick' package from
-<http://www.imagemagick.org/script/binary-releases.php>
+<https://www.imagemagick.org/script/binary-releases.php>
 
 is required to support output formats other than HTML, PDF, SVG, and PNG
 (*note convert::).  The 'Python 3' interpreter from
-<http://www.python.org> is only required if you wish to try out the
+<https://www.python.org> is only required if you wish to try out the
 graphical user interface (*note GUI::).
 
 Example code will be installed by default in the 'examples' subdirectory
@@ -363,7 +363,7 @@
 viewer should be capable of automatically redrawing whenever the output
 file is updated.  The default 'UNIX' 'PostScript' viewer 'gv' supports
 this (via a 'SIGHUP' signal).  Version 'gv-3.6.3' or later (from
-<http://ftp.gnu.org/gnu/gv/>) is required for interactive mode to work
+<https://ftp.gnu.org/gnu/gv/>) is required for interactive mode to work
 properly.  Users of 'ggv' will need to enable 'Watch file' under
 'Edit/Postscript Viewer Preferences'.  Users of 'gsview' will need to
 enable 'Options/Auto Redisplay' (however, under 'MSDOS' it is still
@@ -485,7 +485,7 @@
 To compile and install a 'UNIX' executable from the source release
 'asymptote-x.xx.src.tgz' in the subdirectory 'x.xx' under
 
-   <http://sourceforge.net/projects/asymptote/files/>
+   <https://sourceforge.net/projects/asymptote/files/>
 
    execute the commands:
 gunzip asymptote-x.xx.src.tgz
@@ -500,7 +500,7 @@
    On 'UNIX' platforms (other than 'MacOS X'), we recommend using
 version '3.0.0' of the 'freeglut' library.  To compile 'freeglut',
 download
-     <http://prdownloads.sourceforge.net/freeglut/freeglut-3.0.0.tar.gz>
+     <https://prdownloads.sourceforge.net/freeglut/freeglut-3.0.0.tar.gz>
 and type (as the root user):
 gunzip freeglut-3.0.0.tar.gz
 tar -xf freeglut-3.0.0.tar
@@ -519,7 +519,7 @@
 'gmake').  To build the documentation, you may need to install the
 'texinfo-tex' package.  If you get errors from a broken 'texinfo' or
 'pdftex' installation, simply put
-     <http://asymptote.sourceforge.net/asymptote.pdf>
+     <https://asymptote.sourceforge.io/asymptote.pdf>
 in the directory 'doc' and repeat the command 'make all'.
 
 For a (default) system-wide installation, the last command should be
@@ -571,7 +571,7 @@
 which shows the available function prototypes for the command at the
 cursor.  For full functionality you should also install the Apache
 Software Foundation package 'two-mode-mode':
-     <http://www.dedasys.com/freesoftware/files/two-mode-mode.el>
+     <https://www.dedasys.com/freesoftware/files/two-mode-mode.el>
 Once installed, you can use the hybrid mode 'lasy-mode' to edit a LaTeX
 file containing embedded 'Asymptote' code (*note LaTeX usage::).  This
 mode can be enabled within 'latex-mode' with the key sequence 'M-x
@@ -652,12 +652,12 @@
 thorough introduction, see the excellent 'Asymptote' tutorial written by
 Charles Staats:
 
-   <http://math.uchicago.edu/~cstaats/Charles_Staats_III/Notes_and_papers_files/asymptote_tutorial.pdf>
+   <https://math.uchicago.edu/~cstaats/Charles_Staats_III/Notes_and_papers_files/asymptote_tutorial.pdf>
 
    Another 'Asymptote' tutorial is available as a wiki, with images
 rendered by an online Asymptote engine:
 
-   <http://www.artofproblemsolving.com/wiki/?title=Asymptote_(Vector_Graphics_Language)>
+   <https://www.artofproblemsolving.com/wiki/?title=Asymptote_(Vector_Graphics_Language)>
 
 
 File: asymptote.info,  Node: Drawing in batch mode,  Next: Drawing in interactive mode,  Prev: Tutorial,  Up: Tutorial
@@ -841,7 +841,7 @@
                                [./cube]
 
    See section *note graph:: (or the online 'Asymptote' gallery and
-external links posted at <http://asymptote.sourceforge.net>) for further
+external links posted at <https://asymptote.sourceforge.io>) for further
 examples, including two-dimensional and interactive three-dimensional
 scientific graphs.  Additional examples have been posted by Philippe
 Ivaldi at <http://www.piprime.fr/asymptote>.
@@ -3937,7 +3937,7 @@
 returns n!/(k!(n-k)!), are also defined.
 
    When configured with the GNU Scientific Library (GSL), available from
-<http://www.gnu.org/software/gsl/>, 'Asymptote' contains an internal
+<https://www.gnu.org/software/gsl/>, 'Asymptote' contains an internal
 module 'gsl' that defines the airy functions 'Ai(real)', 'Bi(real)',
 'Ai_deriv(real)', 'Bi_deriv(real)', 'zero_Ai(int)', 'zero_Bi(int)',
 'zero_Ai_deriv(int)', 'zero_Bi_deriv(int)', the Bessel functions 'I(int,
@@ -4228,6 +4228,14 @@
      write();
      write(f/n);
 
+'pair[][] fft(pair[][] a, int sign=1)'
+     returns the unnormalized two-dimensional Fourier transform of 'a'
+     using the given 'sign'.
+
+'pair[][][] fft(pair[][][] a, int sign=1)'
+     returns the unnormalized three-dimensional Fourier transform of 'a'
+     using the given 'sign'.
+
 'real dot(real[] a, real[] b)'
      returns the dot product of the vectors 'a' and 'b'.
 
@@ -4810,12 +4818,12 @@
 figures in a separate directory named 'asy', one can define
 \def\asydir{asy}
    in 'latexusage.tex' and put the contents of
-<http://sourceforge.net/p/asymptote/code/HEAD/tree/trunk/asymptote/doc/latexmkrc_asydir>
+<https://raw.githubusercontent.com/vectorgraphics/asymptote/HEAD/doc/latexmkrc_asydir>
 in a file 'latexmkrc' in the same directory.  External 'Asymptote' code
 can be included with
 \asyinclude[<options>]{<filename.asy>}
 so that 'latexmk' will recognize when the code is changed.  Note that
-'latemk' requires 'perl', available from <http://www.perl.org/>.
+'latemk' requires 'perl', available from <https://www.perl.org/>.
 
    One can specify 'width', 'height', 'keepAspect', 'viewportwidth',
 'viewportheight', 'attach', and 'inline'.  'keyval'-style options to the
@@ -5062,10 +5070,6 @@
      returns the four complex roots of the quartic equation
      ax^4+bx^3+cx^2+dx+e=0.
 
-'pair[][] fft(pair[][] a, int sign=1)'
-     returns the two-dimensional Fourier transform of a using the given
-     'sign'.
-
 'real time(path g, real x, int n=0)'
      returns the 'n'th intersection time of path 'g' with the vertical
      line through x.
@@ -5128,7 +5132,7 @@
 This module, written by Philippe Ivaldi, provides an extensive set of
 geometry routines, including 'perpendicular' symbols and a 'triangle'
 structure.  Link to the documentation for the 'geometry' module are
-posted here: <http://asymptote.sourceforge.net/links.html>, including an
+posted here: <https://asymptote.sourceforge.io/links.html>, including an
 extensive set of examples,
 <http://www.piprime.fr/files/asymptote/geometry/>, and an index:
      <http://www.piprime.fr/files/asymptote/geometry/modules/geometry.asy.index.type.html>
@@ -8140,7 +8144,7 @@
 -c,-command string     Command to autoexecute
 -compact               Conserve memory at the expense of speed [false]
 -d,-debug              Enable debugging messages [false]
--digits n              Default output file precision [6]
+-digits n              Default output file precision [7]
 -divisor n             Garbage collect using purge(divisor=n) [2]
 -embed                 Embed rendered preview image [true]
 -envmap                Enable environment map image-based lighting (Experimental) [false]
@@ -8269,8 +8273,8 @@
 using the '-f' option (or 'outformat' setting).
 
    To produce SVG output, you will need 'dvisvgm' (version 2.6.3 or
-later) from <http://dvisvgm.sourceforge.net>.  You might need to adjust
-the configuration variable 'libgs' to point to the location of your
+later) from <https://dvisvgm.de>.  You might need to adjust the
+configuration variable 'libgs' to point to the location of your
 'Ghostscript' library 'libgs.so' (or to an empty string, depending on
 how 'dvisvgm' was configured).  The 2.8 version of 'dvisvgm' can display
 SVG output (used by the 'xasy' editor) for external vector EPS and PDF
@@ -8409,7 +8413,7 @@
 
    Interactive mode is implemented with the GNU 'readline' library, with
 command history and auto-completion.  To customize the key bindings,
-see: <http://cnswww.cns.cwru.edu/php/chet/readline/readline.html>
+see: <https://tiswww.case.edu/php/chet/readline/readline.html>
 
    The file 'asymptote.py' in the 'Asymptote' system directory provides
 an alternative way of entering 'Asymptote' commands interactively,
@@ -8447,7 +8451,7 @@
 =====================
 
 As 'xasy' is written in the interactive scripting language 'Python/Qt',
-it requires 'Python' (<http://www.python.org>), along with the 'Python'
+it requires 'Python' (<https://www.python.org>), along with the 'Python'
 packages 'pyqt5', 'cson', and 'numpy':
 
 pip3 install cson numpy pyqt5 PyQt5.sip
@@ -8491,7 +8495,7 @@
 ******************************
 
 The excellent 'PostScript' editor 'pstoedit' (version 3.50 or later;
-available from <http://sourceforge.net/projects/pstoedit/>) includes an
+available from <https://sourceforge.net/projects/pstoedit/>) includes an
 'Asymptote' backend.  Unlike virtually all other 'pstoedit' backends,
 this driver includes native clipping, even-odd fill rule, 'PostScript'
 subpath, and full image support.  Here is an example: 'asy -V
@@ -8510,18 +8514,18 @@
 *******
 
 A list of frequently asked questions (FAQ) is maintained at
-     <http://asymptote.sourceforge.net/FAQ>
+     <https://asymptote.sourceforge.io/FAQ>
 Questions on installing and using 'Asymptote' that are not addressed in
 the FAQ should be sent to the 'Asymptote' forum:
-     <http://sourceforge.net/p/asymptote/discussion/409349>
+     <https://sourceforge.net/p/asymptote/discussion/409349>
 Including an example that illustrates what you are trying to do will
 help you get useful feedback.  'LaTeX' problems can often be diagnosed
 with the '-vv' or '-vvv' command-line options.  Contributions in the
 form of patches or 'Asymptote' modules can be posted here:
-     <http://sourceforge.net/p/asymptote/patches>
+     <https://sourceforge.net/p/asymptote/patches>
 To receive announcements of upcoming releases, please subscribe to
 'Asymptote' at
-     <http://freecode.com/projects/asy>
+     <https://sourceforge.net/projects/asymptote/>
 If you find a bug in 'Asymptote', please check (if possible) whether the
 bug is still present in the latest 'git' developmental code (*note
 Git::) before submitting a bug report.  New bugs can be reported at
@@ -8528,13 +8532,13 @@
      <https://github.com/vectorgraphics/asymptote/issues>
 To see if the bug has already been fixed, check bugs with Status
 'Closed' and recent lines in
-     <http://asymptote.sourceforge.net/ChangeLog>
+     <https://asymptote.sourceforge.io/ChangeLog>
 
    'Asymptote' can be configured with the optional GNU library
-'libsigsegv', available from <http://libsigsegv.sourceforge.net>, which
-allows one to distinguish user-generated 'Asymptote' stack overflows
-(*note stack overflow::) from true segmentation faults (due to internal
-C++ programming errors; please submit the 'Asymptote' code that
+'libsigsegv', available from <https://www.gnu.org/software/libsigsegv/>,
+which allows one to distinguish user-generated 'Asymptote' stack
+overflows (*note stack overflow::) from true segmentation faults (due to
+internal C++ programming errors; please submit the 'Asymptote' code that
 generates such segmentation faults along with your bug report).
 
 
@@ -8750,7 +8754,7 @@
 * alias <1>:                             Arrays.             (line  174)
 * Align:                                 label.              (line   12)
 * aligndir:                              Options.            (line  186)
-* all:                                   Arrays.             (line  325)
+* all:                                   Arrays.             (line  333)
 * Allow:                                 Pens.               (line  346)
 * and:                                   Bezier curves.      (line   56)
 * AND:                                   Arithmetic & logical.
@@ -8973,7 +8977,7 @@
 * colorless:                             Pens.               (line   57)
 * colors:                                Pens.               (line   54)
 * comma:                                 Files.              (line   61)
-* comma-separated-value mode:            Arrays.             (line  357)
+* comma-separated-value mode:            Arrays.             (line  365)
 * command-line options:                  Configuring.        (line   89)
 * command-line options <1>:              Options.            (line    6)
 * comment character:                     Files.              (line   16)
@@ -9021,10 +9025,10 @@
 * cross <2>:                             graph.              (line  480)
 * crossframe:                            markers.            (line   22)
 * crosshatch:                            Pens.               (line  285)
-* csv:                                   Arrays.             (line  357)
+* csv:                                   Arrays.             (line  365)
 * CTZ:                                   Arithmetic & logical.
                                                              (line   68)
-* cubicroots:                            Arrays.             (line  314)
+* cubicroots:                            Arrays.             (line  322)
 * curl:                                  Bezier curves.      (line   66)
 * curl <1>:                              three.              (line    6)
 * curlSpecifier:                         Paths and guides.   (line  408)
@@ -9074,11 +9078,11 @@
 * delete:                                Files.              (line  150)
 * delete <1>:                            Arrays.             (line   39)
 * description:                           Description.        (line    6)
-* diagonal:                              Arrays.             (line  299)
+* diagonal:                              Arrays.             (line  307)
 * diamond:                               flowchart.          (line   54)
 * diffuse:                               three.              (line   76)
 * diffusepen:                            three.              (line   66)
-* dimension:                             Arrays.             (line  362)
+* dimension:                             Arrays.             (line  370)
 * dir:                                   Search paths.       (line    9)
 * dir <1>:                               Data types.         (line   90)
 * dir <2>:                               Data types.         (line  180)
@@ -9095,8 +9099,8 @@
 * dot:                                   draw.               (line   82)
 * dot <1>:                               Data types.         (line  103)
 * dot <2>:                               Data types.         (line  193)
-* dot <3>:                               Arrays.             (line  254)
-* dot <4>:                               Arrays.             (line  257)
+* dot <3>:                               Arrays.             (line  262)
+* dot <4>:                               Arrays.             (line  265)
 * DotMargin:                             draw.               (line   42)
 * DotMargin3:                            three.              (line  619)
 * DotMargins:                            draw.               (line   42)
@@ -9156,9 +9160,9 @@
                                                              (line   25)
 * environment variables:                 Configuring.        (line   93)
 * eof:                                   Files.              (line   93)
-* eof <1>:                               Arrays.             (line  339)
+* eof <1>:                               Arrays.             (line  347)
 * eol:                                   Files.              (line   93)
-* eol <1>:                               Arrays.             (line  339)
+* eol <1>:                               Arrays.             (line  347)
 * EPS:                                   label.              (line   78)
 * EPS <1>:                               Options.            (line  155)
 * erase:                                 Drawing in interactive mode.
@@ -9209,7 +9213,8 @@
                                                              (line   15)
 * feynman:                               feynman.            (line    6)
 * fft:                                   Arrays.             (line  240)
-* fft <1>:                               math.               (line   26)
+* fft <1>:                               Arrays.             (line  254)
+* fft <2>:                               Arrays.             (line  258)
 * FFTW:                                  Compiling from UNIX source.
                                                              (line   63)
 * file:                                  Files.              (line    6)
@@ -9336,7 +9341,7 @@
 * identity:                              Transforms.         (line   24)
 * identity <1>:                          Mathematical functions.
                                                              (line    6)
-* identity <2>:                          Arrays.             (line  296)
+* identity <2>:                          Arrays.             (line  304)
 * identity4:                             three.              (line  475)
 * if:                                    Programming.        (line   26)
 * IgnoreAspect:                          Frames and pictures.
@@ -9356,7 +9361,7 @@
 * incircle:                              Data types.         (line  120)
 * include:                               Import.             (line  126)
 * including images:                      label.              (line   78)
-* increasing:                            math.               (line   59)
+* increasing:                            math.               (line   55)
 * inf:                                   Data types.         (line   35)
 * inheritance:                           Structures.         (line  181)
 * initialized:                           Arrays.             (line   39)
@@ -9408,7 +9413,7 @@
 * intMax:                                Data types.         (line   30)
 * intMin:                                Data types.         (line   30)
 * inverse:                               Transforms.         (line   16)
-* inverse <1>:                           Arrays.             (line  302)
+* inverse <1>:                           Arrays.             (line  310)
 * invert:                                three.              (line  465)
 * invisible:                             Pens.               (line   43)
 * isnan:                                 Data types.         (line   35)
@@ -9479,8 +9484,8 @@
 * length <5>:                            Arrays.             (line   39)
 * length <6>:                            three.              (line  537)
 * letter:                                Configuring.        (line   66)
-* lexorder:                              math.               (line   67)
-* lexorder <1>:                          math.               (line   70)
+* lexorder:                              math.               (line   63)
+* lexorder <1>:                          math.               (line   66)
 * libgs:                                 Options.            (line  160)
 * libm routines:                         Mathematical functions.
                                                              (line    6)
@@ -9488,9 +9493,9 @@
 * libsigsegv <1>:                        Help.               (line   27)
 * light:                                 three.              (line   76)
 * limits:                                graph.              (line  639)
-* line:                                  Arrays.             (line  339)
-* line <1>:                              Arrays.             (line  343)
-* line mode:                             Arrays.             (line  339)
+* line:                                  Arrays.             (line  347)
+* line <1>:                              Arrays.             (line  351)
+* line mode:                             Arrays.             (line  347)
 * Linear:                                graph.              (line  690)
 * linecap:                               Pens.               (line  139)
 * linejoin:                              Pens.               (line  149)
@@ -9687,8 +9692,8 @@
 * parallelogram:                         flowchart.          (line   47)
 * parametric surface:                    graph3.             (line   99)
 * parametrized curve:                    graph.              (line  639)
-* partialsum:                            math.               (line   53)
-* partialsum <1>:                        math.               (line   56)
+* partialsum:                            math.               (line   49)
+* partialsum <1>:                        math.               (line   52)
 * patch-dependent colors:                three.              (line  107)
 * path:                                  Paths.              (line    6)
 * path <1>:                              Paths and guides.   (line    7)
@@ -9766,8 +9771,8 @@
 * public:                                Structures.         (line    6)
 * push:                                  Arrays.             (line   39)
 * Python usage:                          Interactive mode.   (line   72)
-* quadraticroots:                        Arrays.             (line  305)
-* quadraticroots <1>:                    Arrays.             (line  310)
+* quadraticroots:                        Arrays.             (line  313)
+* quadraticroots <1>:                    Arrays.             (line  318)
 * quarticroots:                          math.               (line   22)
 * quick reference:                       Description.        (line   84)
 * quit:                                  Drawing in interactive mode.
@@ -9791,9 +9796,9 @@
                                                              (line   39)
 * randMax:                               Mathematical functions.
                                                              (line   39)
-* read:                                  Arrays.             (line  379)
+* read:                                  Arrays.             (line  387)
 * reading:                               Files.              (line   12)
-* reading string arrays:                 Arrays.             (line  349)
+* reading string arrays:                 Arrays.             (line  357)
 * readline:                              Files.              (line  135)
 * real:                                  Data types.         (line   35)
 * realDigits:                            Data types.         (line   35)
@@ -9879,7 +9884,7 @@
 * seconds:                               Data types.         (line  329)
 * seek:                                  Files.              (line   93)
 * seekeof:                               Files.              (line   93)
-* segment:                               math.               (line   50)
+* segment:                               math.               (line   46)
 * segmentation fault:                    Help.               (line   27)
 * self operators:                        Self & prefix operators.
                                                              (line    6)
@@ -9938,8 +9943,8 @@
 * slice <1>:                             Paths and guides.   (line  262)
 * slices:                                Slices.             (line    6)
 * slide:                                 slide.              (line    6)
-* slope:                                 math.               (line   44)
-* slope <1>:                             math.               (line   47)
+* slope:                                 math.               (line   40)
+* slope <1>:                             math.               (line   43)
 * slopefield:                            slopefield.         (line    6)
 * smoothcontour3:                        smoothcontour3.     (line    6)
 * sncndn:                                Mathematical functions.
@@ -9946,8 +9951,8 @@
                                                              (line   48)
 * solid:                                 Pens.               (line  102)
 * solids:                                solids.             (line    6)
-* solve:                                 Arrays.             (line  274)
-* solve <1>:                             Arrays.             (line  290)
+* solve:                                 Arrays.             (line  282)
+* solve <1>:                             Arrays.             (line  298)
 * sort:                                  Arrays.             (line  177)
 * sort <1>:                              Arrays.             (line  181)
 * sort <2>:                              Arrays.             (line  196)
@@ -10052,8 +10057,8 @@
 * tilings:                               Pens.               (line  254)
 * time:                                  Data types.         (line  320)
 * time <1>:                              Data types.         (line  345)
-* time <2>:                              math.               (line   30)
-* time <3>:                              math.               (line   34)
+* time <2>:                              math.               (line   26)
+* time <3>:                              math.               (line   30)
 * times:                                 Paths and guides.   (line  220)
 * times <1>:                             Paths and guides.   (line  224)
 * Top:                                   graph.              (line  135)
@@ -10072,7 +10077,7 @@
 * triangle:                              geometry.           (line    6)
 * triangles:                             three.              (line  142)
 * triangulate:                           contour.            (line  149)
-* tridiagonal:                           Arrays.             (line  261)
+* tridiagonal:                           Arrays.             (line  269)
 * trigonometric integrals:               Mathematical functions.
                                                              (line   48)
 * triple:                                Data types.         (line  137)
@@ -10095,7 +10100,7 @@
 * unicode:                               unicode.            (line    6)
 * uniform:                               Arrays.             (line  145)
 * uninstall:                             Uninstall.          (line    6)
-* unique:                                math.               (line   63)
+* unique:                                math.               (line   59)
 * unit:                                  Data types.         (line   83)
 * unit <1>:                              Data types.         (line  173)
 * unitbox:                               Paths.              (line   44)
@@ -10124,8 +10129,8 @@
 * user-defined operators:                User-defined operators.
                                                              (line    6)
 * usleep:                                Data types.         (line  378)
-* value:                                 math.               (line   38)
-* value <1>:                             math.               (line   41)
+* value:                                 math.               (line   34)
+* value <1>:                             math.               (line   37)
 * var:                                   Variable initializers.
                                                              (line   55)
 * variable initializers:                 Variable initializers.
@@ -10133,7 +10138,7 @@
 * vectorfield:                           graph.              (line 1004)
 * vectorfield <1>:                       graph.              (line 1043)
 * vectorfield3:                          graph3.             (line  157)
-* vectorization:                         Arrays.             (line  318)
+* vectorization:                         Arrays.             (line  326)
 * verbatim:                              Frames and pictures.
                                                              (line  297)
 * vertex-dependent colors:               three.              (line  107)
@@ -10154,12 +10159,12 @@
 * wheel mouse:                           GUI.                (line    6)
 * while:                                 Programming.        (line   48)
 * White:                                 three.              (line   76)
-* white-space string delimiter mode:     Arrays.             (line  349)
+* white-space string delimiter mode:     Arrays.             (line  357)
 * width:                                 LaTeX usage.        (line   50)
 * windingnumber:                         Paths and guides.   (line  283)
-* word:                                  Arrays.             (line  349)
+* word:                                  Arrays.             (line  357)
 * write:                                 Files.              (line   53)
-* write <1>:                             Arrays.             (line  388)
+* write <1>:                             Arrays.             (line  396)
 * X:                                     three.              (line  312)
 * xasy:                                  GUI.                (line    6)
 * xaxis3:                                graph3.             (line    7)
@@ -10229,148 +10234,148 @@
 Node: Top570
 Node: Description7280
 Node: Installation11190
-Node: UNIX binary distributions12234
-Node: MacOS X binary distributions13364
-Node: Microsoft Windows13918
-Node: Configuring15123
-Node: Search paths19585
-Node: Compiling from UNIX source20424
-Node: Editing modes23484
-Node: Git25905
-Node: Uninstall26305
-Node: Tutorial26651
-Node: Drawing in batch mode27540
-Node: Drawing in interactive mode28416
-Node: Figure size29448
-Node: Labels31043
-Node: Paths31871
-Ref: unitcircle32487
-Node: Drawing commands34389
-Node: draw36104
-Ref: arrows37286
-Node: fill42784
-Ref: gradient shading43830
-Node: clip48346
-Node: label48933
-Ref: Label49533
-Node: Bezier curves55365
-Node: Programming59265
-Ref: array iteration61018
-Node: Data types61185
-Ref: format71847
-Node: Paths and guides76293
-Ref: circle76547
-Ref: extension86247
-Node: Pens93057
-Ref: fillrule100748
-Ref: basealign101652
-Ref: transparency104486
-Ref: makepen108080
-Ref: overwrite108964
-Node: Transforms110178
-Node: Frames and pictures112010
-Ref: envelope113168
-Ref: size114261
-Ref: unitsize115248
-Ref: shipout116321
-Ref: filltype118672
-Ref: add122085
-Ref: add about123027
-Ref: tex126057
-Node: Files126953
-Ref: cd127940
-Ref: scroll132625
-Node: Variable initializers135543
-Node: Structures138260
-Node: Operators145762
-Node: Arithmetic & logical146076
-Node: Self & prefix operators148446
-Node: User-defined operators149240
-Node: Implicit scaling150153
-Node: Functions150716
-Ref: stack overflow153858
-Node: Default arguments154140
-Node: Named arguments154896
-Node: Rest arguments157466
-Node: Mathematical functions160588
-Node: Arrays165244
-Ref: sort172352
-Ref: tridiagonal174977
-Ref: solve176208
-Node: Slices180348
-Node: Casts184256
-Node: Import186526
-Node: Static191784
-Node: LaTeX usage194677
-Node: Base modules201173
-Node: plain203730
-Node: simplex204404
-Node: math204678
-Node: interpolate207387
-Node: geometry207666
-Node: trembling208260
-Node: stats208529
-Node: patterns208789
-Node: markers209025
-Node: tree210887
-Node: binarytree211072
-Node: drawtree211739
-Node: syzygy211940
-Node: feynman212214
-Node: roundedpath212489
-Node: animation212772
-Ref: animate213193
-Node: embed214306
-Node: slide215260
-Node: MetaPost215592
-Node: unicode216311
-Node: latin1217185
-Node: babel217554
-Node: labelpath217784
-Node: labelpath3218605
-Node: annotate218916
-Node: CAD219386
-Node: graph219697
-Ref: ticks226858
-Ref: pathmarkers240596
-Ref: marker241067
-Ref: markuniform241421
-Ref: errorbars243229
-Ref: automatic scaling247708
-Node: palette259469
-Ref: images259587
-Ref: image263761
-Ref: logimage264282
-Ref: penimage265388
-Ref: penfunctionimage265651
-Node: three266423
-Ref: PostScript3D295720
-Node: obj297459
-Node: graph3297708
-Ref: GaussianSurface302991
-Node: grid3304141
-Node: solids304926
-Node: tube305919
-Node: flowchart308150
-Node: contour312759
-Node: contour3318079
-Node: smoothcontour3318392
-Node: slopefield320113
-Node: ode321603
-Node: Options321860
-Ref: configuration file328645
-Ref: settings328645
-Ref: texengines329909
-Ref: convert329909
-Node: Interactive mode333431
-Ref: history335581
-Node: GUI336887
-Node: GUI installation337438
-Node: GUI usage338168
-Node: PostScript to Asymptote339231
-Node: Help339989
-Node: Debugger341643
-Node: Credits343399
-Node: Index344416
+Node: UNIX binary distributions12236
+Node: MacOS X binary distributions13366
+Node: Microsoft Windows13921
+Node: Configuring15128
+Node: Search paths19591
+Node: Compiling from UNIX source20430
+Node: Editing modes23492
+Node: Git25914
+Node: Uninstall26314
+Node: Tutorial26660
+Node: Drawing in batch mode27551
+Node: Drawing in interactive mode28427
+Node: Figure size29459
+Node: Labels31054
+Node: Paths31882
+Ref: unitcircle32498
+Node: Drawing commands34400
+Node: draw36115
+Ref: arrows37297
+Node: fill42795
+Ref: gradient shading43841
+Node: clip48357
+Node: label48944
+Ref: Label49544
+Node: Bezier curves55376
+Node: Programming59276
+Ref: array iteration61029
+Node: Data types61196
+Ref: format71858
+Node: Paths and guides76304
+Ref: circle76558
+Ref: extension86258
+Node: Pens93068
+Ref: fillrule100759
+Ref: basealign101663
+Ref: transparency104497
+Ref: makepen108091
+Ref: overwrite108975
+Node: Transforms110189
+Node: Frames and pictures112021
+Ref: envelope113179
+Ref: size114272
+Ref: unitsize115259
+Ref: shipout116332
+Ref: filltype118683
+Ref: add122096
+Ref: add about123038
+Ref: tex126068
+Node: Files126964
+Ref: cd127951
+Ref: scroll132636
+Node: Variable initializers135554
+Node: Structures138271
+Node: Operators145773
+Node: Arithmetic & logical146087
+Node: Self & prefix operators148457
+Node: User-defined operators149251
+Node: Implicit scaling150164
+Node: Functions150727
+Ref: stack overflow153869
+Node: Default arguments154151
+Node: Named arguments154907
+Node: Rest arguments157477
+Node: Mathematical functions160599
+Node: Arrays165256
+Ref: sort172364
+Ref: tridiagonal175275
+Ref: solve176506
+Node: Slices180646
+Node: Casts184554
+Node: Import186824
+Node: Static192082
+Node: LaTeX usage194975
+Node: Base modules201470
+Node: plain204027
+Node: simplex204701
+Node: math204975
+Node: interpolate207559
+Node: geometry207838
+Node: trembling208432
+Node: stats208701
+Node: patterns208961
+Node: markers209197
+Node: tree211059
+Node: binarytree211244
+Node: drawtree211911
+Node: syzygy212112
+Node: feynman212386
+Node: roundedpath212661
+Node: animation212944
+Ref: animate213365
+Node: embed214478
+Node: slide215432
+Node: MetaPost215764
+Node: unicode216483
+Node: latin1217357
+Node: babel217726
+Node: labelpath217956
+Node: labelpath3218777
+Node: annotate219088
+Node: CAD219558
+Node: graph219869
+Ref: ticks227030
+Ref: pathmarkers240768
+Ref: marker241239
+Ref: markuniform241593
+Ref: errorbars243401
+Ref: automatic scaling247880
+Node: palette259641
+Ref: images259759
+Ref: image263933
+Ref: logimage264454
+Ref: penimage265560
+Ref: penfunctionimage265823
+Node: three266595
+Ref: PostScript3D295892
+Node: obj297631
+Node: graph3297880
+Ref: GaussianSurface303163
+Node: grid3304313
+Node: solids305098
+Node: tube306091
+Node: flowchart308322
+Node: contour312931
+Node: contour3318251
+Node: smoothcontour3318564
+Node: slopefield320285
+Node: ode321775
+Node: Options322032
+Ref: configuration file328817
+Ref: settings328817
+Ref: texengines330081
+Ref: convert330081
+Node: Interactive mode333591
+Ref: history335741
+Node: GUI337044
+Node: GUI installation337595
+Node: GUI usage338326
+Node: PostScript to Asymptote339389
+Node: Help340148
+Node: Debugger341822
+Node: Credits343578
+Node: Index344595
 
 End Tag Table

Modified: trunk/Build/source/utils/asymptote/drawelement.h
===================================================================
--- trunk/Build/source/utils/asymptote/drawelement.h	2020-03-03 22:33:26 UTC (rev 54033)
+++ trunk/Build/source/utils/asymptote/drawelement.h	2020-03-03 22:35:09 UTC (rev 54034)
@@ -26,18 +26,6 @@
 
 static const double pixel=1.0; // Adaptive rendering constant.
 
-// Return one-sixth of the second derivative of the Bezier curve defined
-// by a,b,c,d at 0. 
-inline triple bezierPP(triple a, triple b, triple c) {
-  return a+c-2.0*b;
-}
-
-// Return one-third of the third derivative of the Bezier curve defined by
-// a,b,c,d at 0.
-inline triple bezierPPP(triple a, triple b, triple c, triple d) {
-  return d-a+3.0*(b-c);
-}
-
 enum Interaction {EMBEDDED=0,BILLBOARD};
 
 void copyArray4x4C(double*& dest, const vm::array *a);

Modified: trunk/Build/source/utils/asymptote/drawpath3.cc
===================================================================
--- trunk/Build/source/utils/asymptote/drawpath3.cc	2020-03-03 22:33:26 UTC (rev 54033)
+++ trunk/Build/source/utils/asymptote/drawpath3.cc	2020-03-03 22:35:09 UTC (rev 54034)
@@ -30,7 +30,7 @@
     for(Int i=0; i <= n; ++i)
       controls[i]=g.point(i);
     
-    out->addLine(n+1,controls,color);
+    out->addLine(n+1,controls,diffuse);
   } else {
     int m=3*n+1;
     triple *controls=new(UseGC) triple[m];
@@ -44,7 +44,7 @@
     }
     controls[++k]=g.precontrol(n);
     controls[++k]=g.point(n);
-    out->addBezierCurve(m,controls,color);
+    out->addBezierCurve(m,controls,diffuse);
   }
   
   return true;
@@ -62,8 +62,7 @@
     drawElement::centerIndex=centerIndex;
   } else drawElement::centerIndex=0;
   
-  RGBAColour Black(0.0,0.0,0.0,color.A);
-  setcolors(false,Black,color,Black,1.0,0.0,0.04,out);
+  setcolors(false,diffuse,emissive,specular,shininess,metallic,fresnel0,out);
   
   for(Int i=0; i < n; ++i) {
     if(g.straight(i)) {
@@ -83,8 +82,7 @@
   Int n=g.length();
   if(n == 0 || invisible) return;
 
-  RGBAColour Black(0.0,0.0,0.0,color.A);
-  setcolors(false,Black,color,Black,1.0,0.0,0.04);
+  setcolors(false,diffuse,emissive,specular,shininess,metallic,fresnel0);
 
   setMaterial(material1Data,drawMaterial1);
   

Modified: trunk/Build/source/utils/asymptote/drawpath3.h
===================================================================
--- trunk/Build/source/utils/asymptote/drawpath3.h	2020-03-03 22:33:26 UTC (rev 54033)
+++ trunk/Build/source/utils/asymptote/drawpath3.h	2020-03-03 22:35:09 UTC (rev 54034)
@@ -18,7 +18,13 @@
   const path3 g;
   triple center;
   bool straight;
-  prc::RGBAColour color;
+  prc::RGBAColour diffuse;
+  prc::RGBAColour emissive;
+  prc::RGBAColour specular;
+  double opacity;
+  double shininess;
+  double metallic;
+  double fresnel0;
   bool invisible;
   Interaction interaction;
   triple Min,Max;
@@ -34,17 +40,28 @@
     centerIndex=0;
   }
   
-  drawPath3(path3 g, triple center, const pen& p, Interaction interaction,
-            const string& key="") :
-    drawElement(key), g(g), center(center), straight(g.piecewisestraight()),
-    color(rgba(p)), invisible(p.invisible()), interaction(interaction),
-    Min(g.min()), Max(g.max()) {
+  drawPath3(path3 g, triple center, const vm::array& p, double opacity,
+            double shininess, double metallic, double fresnel0,
+            Interaction interaction, const string& key="") :
+    drawElement(key), g(g), center(center),
+    straight(g.piecewisestraight()), opacity(opacity),
+    shininess(shininess), metallic(metallic), fresnel0(fresnel0),
+    interaction(interaction), Min(g.min()), Max(g.max()) {
     init();
+
+    pen Pen=vm::read<camp::pen>(p,0);
+    invisible=Pen.invisible();
+    diffuse=rgba(Pen);
+    emissive=rgba(vm::read<camp::pen>(p,1));
+    specular=rgba(vm::read<camp::pen>(p,2));
   }
     
   drawPath3(const double* t, const drawPath3 *s) :
     drawElement(s->KEY), g(camp::transformed(t,s->g)), straight(s->straight),
-    color(s->color), invisible(s->invisible), interaction(s->interaction),
+    diffuse(s->diffuse), emissive(s->emissive), specular(s->specular),
+    opacity(s->opacity), shininess(s->shininess),
+    metallic(s->metallic), fresnel0(s->fresnel0),
+    invisible(s->invisible), interaction(s->interaction),
     Min(g.min()), Max(g.max()) {
     init();
     center=t*s->center;

Modified: trunk/Build/source/utils/asymptote/drawsurface.cc
===================================================================
--- trunk/Build/source/utils/asymptote/drawsurface.cc	2020-03-03 22:33:26 UTC (rev 54033)
+++ trunk/Build/source/utils/asymptote/drawsurface.cc	2020-03-03 22:35:09 UTC (rev 54034)
@@ -58,18 +58,11 @@
                const RGBAColour& specular, double shininess,
                double metallic, double fresnel0, jsfile *out)
 {
-  Material m;
-  if(colors) {
-    static glm::vec4 Black(0.0,0.0,0.0,diffuse.A);
-    m=Material(Black,Black,
-               glm::vec4(specular.R,specular.G,specular.B,specular.A),
-               shininess,metallic,fresnel0);
-  } else
-    m=Material(glm::vec4(diffuse.R,diffuse.G,diffuse.B,diffuse.A),
-               glm::vec4(emissive.R,emissive.G,emissive.B,emissive.A),
-               glm::vec4(specular.R,specular.G,specular.B,specular.A),
-               shininess,metallic,fresnel0);
-          
+  Material m=Material(glm::vec4(diffuse.R,diffuse.G,diffuse.B,diffuse.A),
+                      glm::vec4(emissive.R,emissive.G,emissive.B,emissive.A),
+                      glm::vec4(specular.R,specular.G,specular.B,specular.A),
+                      shininess,metallic,fresnel0);
+  
   MaterialMap::iterator p=materialMap.find(m);
   if(p != materialMap.end()) materialIndex=p->second;
   else {
@@ -89,7 +82,7 @@
 {
   double x,y,z;
   double X,Y,Z;
-  
+
   if(straight) {
     triple Vertices[4];
     if(t == NULL) {
@@ -103,13 +96,13 @@
       Vertices[2]=t*controls[12];
       Vertices[3]=t*controls[15];
     }
-    
+
     boundstriples(x,y,z,X,Y,Z,4,Vertices);
   } else {
     double cx[16];
     double cy[16];
     double cz[16];
-  
+
     if(t == NULL) {
       for(int i=0; i < 16; ++i) {
         triple v=controls[i];
@@ -125,26 +118,26 @@
         cz[i]=v.getz();
       }
     }
-    
+
     double c0=cx[0];
     double fuzz=Fuzz*run::norm(cx,16);
     x=bound(cx,min,b.empty ? c0 : min(c0,b.left),fuzz,maxdepth);
     X=bound(cx,max,b.empty ? c0 : max(c0,b.right),fuzz,maxdepth);
-    
+
     c0=cy[0];
     fuzz=Fuzz*run::norm(cy,16);
     y=bound(cy,min,b.empty ? c0 : min(c0,b.bottom),fuzz,maxdepth);
     Y=boundtri(cy,max,b.empty ? c0 : max(c0,b.top),fuzz,maxdepth);
-    
+
     c0=cz[0];
     fuzz=Fuzz*run::norm(cz,16);
     z=bound(cz,min,b.empty ? c0 : min(c0,b.near),fuzz,maxdepth);
     Z=bound(cz,max,b.empty ? c0 : max(c0,b.far),fuzz,maxdepth);
-  }  
-  
+  }
+
   b.add(x,y,z);
   b.add(X,Y,Z);
-  
+
   if(t == NULL) {
     Min=triple(x,y,z);
     Max=triple(X,Y,Z);
@@ -207,11 +200,11 @@
 
 bool drawBezierPatch::write(prcfile *out, unsigned int *, double, groupsmap&)
 {
-  if(invisible || !prc)
+  if(invisible || primitive)
     return true;
 
   RGBAColour Black(0.0,0.0,0.0,diffuse.A);
-  PRCmaterial m(Black,diffuse,emissive,specular,opacity,PRCshininess);
+  PRCmaterial m(Black,diffuse,emissive,specular,opacity,shininess);
 
   if(straight) {
     triple vertices[]={controls[0],controls[12],controls[3],controls[15]};
@@ -229,7 +222,7 @@
 bool drawBezierPatch::write(jsfile *out)
 {
 #ifdef HAVE_LIBGLM
-  if(invisible)
+  if(invisible || primitive)
     return true;
 
   if(billboard) {
@@ -446,11 +439,11 @@
 bool drawBezierTriangle::write(prcfile *out, unsigned int *, double, 
                                groupsmap&)
 {
-  if(invisible)
+  if(invisible || primitive)
     return true;
 
   RGBAColour Black(0.0,0.0,0.0,diffuse.A);
-  PRCmaterial m(Black,diffuse,emissive,specular,opacity,PRCshininess);
+  PRCmaterial m(Black,diffuse,emissive,specular,opacity,shininess);
   
   static const double third=1.0/3.0;
   static const double third2=2.0/3.0;
@@ -470,7 +463,7 @@
 bool drawBezierTriangle::write(jsfile *out)
 {
 #ifdef HAVE_LIBGLM
-  if(invisible)
+  if(invisible || primitive)
     return true;
 
   if(billboard) {
@@ -573,7 +566,7 @@
     return true;
 
   RGBAColour Black(0.0,0.0,0.0,diffuse.A);
-  PRCmaterial m(Black,diffuse,emissive,specular,opacity,PRCshininess);
+  PRCmaterial m(Black,diffuse,emissive,specular,opacity,shininess);
   out->addSurface(udegree,vdegree,nu,nv,controls,uknots,vknots,m,weights);
   
   return true;
@@ -676,17 +669,13 @@
 // TODO: implement NURBS renderer
 }
 
-void drawSphere::P(triple& t, double x, double y, double z)
+void drawPRC::P(triple& t, double x, double y, double z)
 {
-  if(half) {
-    double temp=z; z=x; x=-temp;
-  }
-  
   if(T == NULL) {
     t=triple(x,y,z);
     return;
   }
-  
+
   double f=T[12]*x+T[13]*y+T[14]*z+T[15];
   if(f == 0.0) run::dividebyzero();
   f=1.0/f;
@@ -695,6 +684,14 @@
            (T[8]*x+T[9]*y+T[10]*z+T[11])*f);
 }
 
+void drawSphere::P(triple& t, double x, double y, double z)
+{
+  if(half) {
+    double temp=z; z=x; x=-temp;
+  }
+  drawPRC::P(t,x,y,z);
+}
+
 bool drawSphere::write(prcfile *out, unsigned int *, double, groupsmap&)
 {
   if(invisible)
@@ -759,6 +756,31 @@
   return true;
 }
 
+bool drawSphere::write(jsfile *out)
+{
+#ifdef HAVE_LIBGLM
+  if(invisible)
+    return true;
+
+  drawElement::centerIndex=0;
+
+  setcolors(false,diffuse,emissive,specular,shininess,metallic,fresnel0,out);
+
+  triple O,E;
+  P(E,1.0,0.0,0.0);
+  P(O,0.0,0.0,0.0);
+  triple X=E-O;
+  double r=length(X);
+
+  if(half)
+    out->addSphere(O,r,half,X.polar(false),X.azimuth(false));
+  else
+    out->addSphere(O,r);
+
+#endif  
+  return true;
+}
+
 bool drawCylinder::write(prcfile *out, unsigned int *, double, groupsmap&)
 {
   if(invisible)
@@ -772,6 +794,31 @@
   return true;
 }
   
+bool drawCylinder::write(jsfile *out)
+{
+#ifdef HAVE_LIBGLM
+  if(invisible)
+    return true;
+
+  drawElement::centerIndex=0;
+  
+  setcolors(false,diffuse,emissive,specular,shininess,metallic,fresnel0,out);
+
+  triple E,H,O;
+  P(E,1.0,0.0,0.0);
+  P(H,0.0,0.0,1.0);
+  P(O,0.0,0.0,0.0);
+  triple X=E-O;
+  triple Z=H-O;
+  double r=length(X);
+  double h=length(Z);
+  
+  out->addCylinder(O,r,h,Z.polar(false),Z.azimuth(false),core);
+
+#endif  
+  return true;
+}
+  
 bool drawDisk::write(prcfile *out, unsigned int *, double, groupsmap&)
 {
   if(invisible)
@@ -785,57 +832,56 @@
   return true;
 }
   
-bool drawTube::write(prcfile *out, unsigned int *, double, groupsmap&)
+bool drawDisk::write(jsfile *out)
 {
+#ifdef HAVE_LIBGLM
   if(invisible)
     return true;
 
-  RGBAColour Black(0.0,0.0,0.0,diffuse.A);
-  PRCmaterial m(Black,diffuse,emissive,specular,opacity,shininess);
+  drawElement::centerIndex=0;
   
-  Int n=center.length();
+  setcolors(false,diffuse,emissive,specular,shininess,metallic,fresnel0,out);
   
-  if(center.piecewisestraight()) {
-    triple *centerControls=new(UseGC) triple[n+1];
-    for(Int i=0; i <= n; ++i)
-      centerControls[i]=center.point(i);
-    size_t N=n+1;
-    triple *controls=new(UseGC) triple[N];
-    for(Int i=0; i <= n; ++i)
-      controls[i]=g.point(i);
-    out->addTube(N,centerControls,controls,true,m);
-  } else {
-    size_t N=3*n+1;
-    triple *centerControls=new(UseGC) triple[N];
-    centerControls[0]=center.point((Int) 0);
-    centerControls[1]=center.postcontrol((Int) 0);
-    size_t k=1;
-    for(Int i=1; i < n; ++i) {
-      centerControls[++k]=center.precontrol(i);
-      centerControls[++k]=center.point(i);
-      centerControls[++k]=center.postcontrol(i);
-    }
-    centerControls[++k]=center.precontrol(n);
-    centerControls[++k]=center.point(n);
-    
-    triple *controls=new(UseGC) triple[N];
-    controls[0]=g.point((Int) 0);
-    controls[1]=g.postcontrol((Int) 0);
-    k=1;
-    for(Int i=1; i < n; ++i) {
-      controls[++k]=g.precontrol(i);
-      controls[++k]=g.point(i);
-      controls[++k]=g.postcontrol(i);
-    }
-    controls[++k]=g.precontrol(n);
-    controls[++k]=g.point(n);
-    
-    out->addTube(N,centerControls,controls,false,m);
-  }
-      
+  triple E,H,O;
+  P(E,1.0,0.0,0.0);
+  P(H,0.0,0.0,1.0);
+  P(O,0.0,0.0,0.0);
+  triple X=E-O;
+  triple Z=H-O;
+  double r=length(X);
+  
+  out->addDisk(O,r,Z.polar(false),Z.azimuth(false));
+
+#endif
   return true;
 }
+  
+bool drawTube::write(jsfile *out)
+{
+#ifdef HAVE_LIBGLM
+  if(invisible)
+    return true;
 
+  drawElement::centerIndex=0;
+
+  setcolors(false,diffuse,emissive,specular,shininess,metallic,fresnel0,out);
+
+  bbox3 b;
+  b.add(T*m);
+  b.add(T*triple(m.getx(),m.gety(),M.getz()));
+  b.add(T*triple(m.getx(),M.gety(),m.getz()));
+  b.add(T*triple(m.getx(),M.gety(),M.getz()));
+  b.add(T*triple(M.getx(),m.gety(),m.getz()));
+  b.add(T*triple(M.getx(),m.gety(),M.getz()));
+  b.add(T*triple(M.getx(),M.gety(),m.getz()));
+  b.add(T*M);
+
+  out->addTube(g,width,b.Min(),b.Max(),core);
+
+#endif
+  return true;
+}
+
 const string drawBaseTriangles::wrongsize=
   "triangle indices require 3 components";
 const string drawBaseTriangles::outofrange="index out of range";
@@ -891,11 +937,11 @@
   if(nC) {
     const RGBAColour white(1,1,1,opacity);
     const RGBAColour black(0,0,0,opacity);
-    const PRCmaterial m(black,white,black,specular,opacity,PRCshininess);
+    const PRCmaterial m(black,white,black,specular,opacity,shininess);
     out->addTriangles(nP,P,nI,PI,m,nN,N,NI,0,NULL,NULL,nC,C,CI,0,NULL,NULL,30);
   } else {
     RGBAColour Black(0.0,0.0,0.0,diffuse.A);
-    const PRCmaterial m(Black,diffuse,emissive,specular,opacity,PRCshininess);
+    const PRCmaterial m(Black,diffuse,emissive,specular,opacity,shininess);
     out->addTriangles(nP,P,nI,PI,m,nN,N,NI,0,NULL,NULL,0,NULL,NULL,0,NULL,NULL,30);
   }
 

Modified: trunk/Build/source/utils/asymptote/drawsurface.h
===================================================================
--- trunk/Build/source/utils/asymptote/drawsurface.h	2020-03-03 22:33:26 UTC (rev 54033)
+++ trunk/Build/source/utils/asymptote/drawsurface.h	2020-03-03 22:35:09 UTC (rev 54034)
@@ -17,6 +17,8 @@
 void inverse(double *a, size_t n);
 }
 
+const string need3pens="array of 3 pens required";
+
 namespace camp {
 
 #ifdef HAVE_LIBGLM
@@ -37,7 +39,6 @@
   double shininess;
   double metallic;
   double fresnel0;
-  double PRCshininess;
   bool invisible;
   Interaction interaction;
   bool billboard;
@@ -44,7 +45,7 @@
   size_t centerIndex;  
   
   triple Min,Max;
-  bool prc;
+  bool primitive;
   
 public:
 #ifdef HAVE_GL
@@ -66,12 +67,11 @@
   drawSurface(const vm::array& g, size_t ncontrols, triple center,
               bool straight, const vm::array&p, double opacity,
               double shininess, double metallic, double fresnel0,
-              double PRCshininess, const vm::array &pens,
-              Interaction interaction, bool prc, const string& key="") :
+              const vm::array &pens, Interaction interaction,
+              bool primitive=true, const string& key="") :
     drawElement(key), ncontrols(ncontrols), center(center), straight(straight),
     opacity(opacity), shininess(shininess), metallic(metallic),
-    fresnel0(fresnel0), PRCshininess(PRCshininess), interaction(interaction),
-    prc(prc) {
+    fresnel0(fresnel0), interaction(interaction), primitive(primitive) {
     init();
     if(checkArray(&g) != 4 || checkArray(&p) != 3)
       reportError(wrongsize());
@@ -106,12 +106,10 @@
   
   drawSurface(const double* t, const drawSurface *s) :
     drawElement(s->KEY), ncontrols(s->ncontrols), straight(s->straight),
-    diffuse(s->diffuse), emissive(s->emissive),
-    specular(s->specular), colors(s->colors), opacity(s->opacity),
-    shininess(s->shininess),  metallic(s->metallic), fresnel0(s->fresnel0),
-    PRCshininess(s->PRCshininess), invisible(s->invisible),
-    interaction(s->interaction), prc(s->prc) { 
-    
+    diffuse(s->diffuse), emissive(s->emissive), specular(s->specular),
+    colors(s->colors), opacity(s->opacity), shininess(s->shininess),
+    metallic(s->metallic), fresnel0(s->fresnel0), invisible(s->invisible),
+    interaction(s->interaction), primitive(s->primitive) {
     init();
     if(s->controls) {
       controls=new(UseGC) triple[ncontrols];
@@ -135,11 +133,10 @@
   
   drawBezierPatch(const vm::array& g, triple center, bool straight,
               const vm::array&p, double opacity, double shininess,
-              double metallic, double fresnel0,
-              double PRCshininess, const vm::array &pens,
-              Interaction interaction, bool prc) : 
-    drawSurface(g,16,center,straight,p,opacity,
-                shininess,metallic,fresnel0,PRCshininess,pens,interaction,prc)  {}
+              double metallic, double fresnel0, const vm::array &pens,
+                  Interaction interaction, bool primitive) :
+    drawSurface(g,16,center,straight,p,opacity,shininess,metallic,fresnel0,
+                pens,interaction,primitive) {}
 
   drawBezierPatch(const double* t, const drawBezierPatch *s) :
     drawSurface(t,s) {}
@@ -169,12 +166,11 @@
 #endif  
   
   drawBezierTriangle(const vm::array& g, triple center, bool straight,
-              const vm::array&p, double opacity, double shininess,
-              double metallic, double fresnel0,
-              double PRCshininess, const vm::array &pens,
-              Interaction interaction, bool prc) : 
+                     const vm::array&p, double opacity, double shininess,
+                     double metallic, double fresnel0, const vm::array &pens,
+                     Interaction interaction, bool primitive) :
     drawSurface(g,10,center,straight,p,opacity,shininess,metallic,fresnel0,
-                PRCshininess,pens,interaction,prc) {}
+                pens,interaction,primitive) {}
   
   drawBezierTriangle(const double* t, const drawBezierTriangle *s) :
     drawSurface(t,s) {}
@@ -211,7 +207,6 @@
   double shininess;
   double metallic;
   double fresnel0;
-  double PRCshininess;
   triple normal;
   bool invisible;
   
@@ -227,10 +222,10 @@
 public:
   drawNurbs(const vm::array& g, const vm::array* uknot, const vm::array* vknot,
             const vm::array* weight, const vm::array&p, double opacity,
-            double shininess, double metallic, double fresnel0, double PRCshininess, const vm::array &pens,
-            const string& key="") 
+            double shininess, double metallic, double fresnel0,
+            const vm::array &pens, const string& key="")
     : drawElement(key), opacity(opacity), shininess(shininess),
-    metallic(metallic), fresnel0(fresnel0), PRCshininess(PRCshininess) {
+      metallic(metallic), fresnel0(fresnel0) {
     size_t weightsize=checkArray(weight);
     
     const string wrongsize="Inconsistent NURBS data";
@@ -304,8 +299,7 @@
     nv(s->nv), weights(s->weights), uknots(s->uknots), vknots(s->vknots),
     diffuse(s->diffuse),
     emissive(s->emissive), specular(s->specular), opacity(s->opacity),
-    shininess(s->shininess), PRCshininess(s->PRCshininess), 
-    invisible(s->invisible) {
+    shininess(s->shininess), invisible(s->invisible) {
     
     const size_t n=nu*nv;
     controls=new(UseGC) triple[n];
@@ -344,15 +338,13 @@
   prc::RGBAColour specular;
   double opacity;
   double shininess;
+  double metallic;
+  double fresnel0;
   bool invisible;
 public:
-  drawPRC(const vm::array& t, const vm::array&p, double opacity,
-          double shininess) : 
-    drawElementLC(t), opacity(opacity), shininess(shininess) {
-
-    string needthreepens="array of 3 pens required";
+  void init(const vm::array&p) {
     if(checkArray(&p) != 3)
-      reportError(needthreepens);
+      reportError(need3pens);
     
     pen surfacepen=vm::read<camp::pen>(p,0);
     invisible=surfacepen.invisible();
@@ -362,15 +354,35 @@
     specular=rgba(vm::read<camp::pen>(p,2));
   }
   
+  drawPRC(const vm::array& t, const vm::array&p, double opacity,
+          double shininess, double metallic, double fresnel0) :
+    drawElementLC(t), opacity(opacity), shininess(shininess),
+    metallic(metallic), fresnel0(fresnel0) {
+    init(p);
+  }
+  
+  drawPRC(const vm::array&p, double opacity,
+          double shininess, double metallic, double fresnel0) :
+    drawElementLC(NULL), opacity(opacity), shininess(shininess),
+    metallic(metallic), fresnel0(fresnel0) {
+    init(p);
+  }
+  
   drawPRC(const double* t, const drawPRC *s) :
     drawElementLC(t,s), diffuse(s->diffuse),
     emissive(s->emissive), specular(s->specular), opacity(s->opacity),
-    shininess(s->shininess), invisible(s->invisible) {
+    shininess(s->shininess), metallic(s->metallic), fresnel0(s->fresnel0),
+    invisible(s->invisible) {
   }
   
-  bool write(prcfile *out, unsigned int *, double, groupsmap&) {
+  virtual void P(triple& t, double x, double y, double z);
+
+  virtual bool write(prcfile *out, unsigned int *, double, groupsmap&) {
     return true;
   }
+
+  virtual bool write(jsfile *out) {return true;}
+
   virtual void transformedbounds(const double*, bbox3&) {}
   virtual void transformedratio(const double*, pair&,
                                 double (*)(double, double), double, bool&) {}
@@ -377,14 +389,14 @@
 
 };
   
-// Draw a PRC unit sphere.
+// Output a unit sphere primitive.
 class drawSphere : public drawPRC {
   bool half;
   int type;
 public:
   drawSphere(const vm::array& t, bool half, const vm::array&p, double opacity,
-             double shininess, int type) :
-    drawPRC(t,p,opacity,shininess), half(half), type(type) {}
+             double shininess, double metallic, double fresnel0, int type) :
+    drawPRC(t,p,opacity,shininess,metallic,fresnel0), half(half), type(type) {}
 
   drawSphere(const double* t, const drawSphere *s) :
     drawElement(s->KEY), drawPRC(t,s), half(s->half), type(s->type) {}
@@ -392,6 +404,7 @@
   void P(triple& t, double x, double y, double z);
   
   bool write(prcfile *out, unsigned int *, double, groupsmap&);
+  bool write(jsfile *out);
   
   drawElement *transformed(const double* t) {
     return new drawSphere(t,this);
@@ -398,17 +411,20 @@
   }
 };
   
-// Draw a PRC unit cylinder.
+// Output a unit cylinder primitive.
 class drawCylinder : public drawPRC {
+  bool core;
 public:
-  drawCylinder(const vm::array& t, const vm::array&p, double opacity,
-               double shininess) :
-    drawPRC(t,p,opacity,shininess) {}
+  drawCylinder(const vm::array& t, const vm::array&p,
+               double opacity, double shininess, double metallic,
+               double fresnel0, bool core=false) :
+    drawPRC(t,p,opacity,shininess,metallic,fresnel0), core(core) {}
 
   drawCylinder(const double* t, const drawCylinder *s) :
-    drawPRC(t,s) {}
+    drawPRC(t,s), core(s->core) {}
     
   bool write(prcfile *out, unsigned int *, double, groupsmap&);
+  bool write(jsfile *out);
   
   drawElement *transformed(const double* t) {
     return new drawCylinder(t,this);
@@ -415,17 +431,18 @@
   }
 };
   
-// Draw a PRC unit disk.
+// Draw a unit disk.
 class drawDisk : public drawPRC {
 public:
   drawDisk(const vm::array& t, const vm::array&p, double opacity,
-           double shininess) :
-    drawPRC(t,p,opacity,shininess) {}
+           double shininess, double metallic, double fresnel0) :
+    drawPRC(t,p,opacity,shininess,metallic,fresnel0) {}
 
   drawDisk(const double* t, const drawDisk *s) :
     drawPRC(t,s) {}
     
   bool write(prcfile *out, unsigned int *, double, groupsmap&);
+  bool write(jsfile *out);
   
   drawElement *transformed(const double* t) {
     return new drawDisk(t,this);
@@ -432,43 +449,37 @@
   }
 };
   
-// Draw a PRC tube.
-class drawTube : public drawElement {
+// Draw a tube.
+class drawTube : public drawPRC {
 protected:
-  path3 center;
-  path3 g;
-  prc::RGBAColour diffuse;
-  prc::RGBAColour emissive;
-  prc::RGBAColour specular;
-  double opacity;
-  double shininess;
-  bool invisible;
+  triple *g;
+  double width;
+  triple m,M;
+  bool core;
 public:
-  drawTube(path3 center, path3 g, const vm::array&p, double opacity,
-           double shininess) : 
-    center(center), g(g), opacity(opacity), shininess(shininess) {
-    string needthreepens="array of 3 pens required";
-    if(checkArray(&p) != 3)
-      reportError(needthreepens);
-    
-    pen surfacepen=vm::read<camp::pen>(p,0);
-    invisible=surfacepen.invisible();
-    
-    diffuse=rgba(surfacepen);
-    emissive=rgba(vm::read<camp::pen>(p,1));
-    specular=rgba(vm::read<camp::pen>(p,2));
+  drawTube(const vm::array&G, double width, const vm::array&p, double opacity,
+           double shininess, double metallic, double fresnel0,
+           const triple& m, const triple& M, bool core) :
+    drawPRC(p,opacity,shininess,metallic,fresnel0), width(width), m(m), M(M),
+    core(core) {
+    if(vm::checkArray(&G) != 4)
+      reportError("array of 4 triples required");
+
+    g=new(UseGC) triple[4];
+    for(size_t i=0; i < 4; ++i)
+      g[i]=vm::read<triple>(G,i);
   }
   
   drawTube(const double* t, const drawTube *s) :
-    drawElement(s->KEY), center(camp::transformed(t,s->center)),
-    g(camp::transformed(t,s->g)), 
-    diffuse(s->diffuse), emissive(s->emissive),
-    specular(s->specular), opacity(s->opacity),
-    shininess(s->shininess), invisible(s->invisible) {
+    drawElement(s->KEY), drawPRC(t,s), width(s->width), m(s->m), M(s->M),
+    core(s->core) {
+    g=new(UseGC) triple[4];
+    for(size_t i=0; i < 4; ++i)
+      g[i]=t*s->g[i];
   }
   
-  bool write(prcfile *out, unsigned int *, double, groupsmap&);
-                        
+  bool write(jsfile *out);
+
   drawElement *transformed(const double* t) {
     return new drawTube(t,this);
   }
@@ -614,7 +625,6 @@
   double shininess;
   double metallic;
   double fresnel0;
-  double PRCshininess;
   bool invisible;
    
 public:
@@ -622,14 +632,12 @@
                 const vm::array& n, const vm::array& ni,
                 const vm::array&p, double opacity, double shininess,
                 double metallic, double fresnel0,
-                double PRCshininess, const vm::array& c, const vm::array& ci) :
-    drawBaseTriangles(v,vi,n,ni),
-    opacity(opacity),shininess(shininess),metallic(metallic),
-    fresnel0(fresnel0),PRCshininess(PRCshininess) {
+                const vm::array& c, const vm::array& ci) :
+    drawBaseTriangles(v,vi,n,ni), opacity(opacity), shininess(shininess),
+    metallic(metallic), fresnel0(fresnel0) {
 
-    const string needthreepens="array of 3 pens required";
     if(checkArray(&p) != 3)
-      reportError(needthreepens);
+      reportError(need3pens);
       
     const pen surfacepen=vm::read<camp::pen>(p,0);
     invisible=surfacepen.invisible();
@@ -671,8 +679,7 @@
     drawBaseTriangles(t,s), nC(s->nC),
     diffuse(s->diffuse), emissive(s->emissive),
     specular(s->specular), opacity(s->opacity), shininess(s->shininess), 
-    metallic(s->metallic), fresnel0(s->fresnel0),
-    PRCshininess(s->PRCshininess), invisible(s->invisible) {
+    metallic(s->metallic), fresnel0(s->fresnel0), invisible(s->invisible) {
     
     if(nC) {
       C=new(UseGC) prc::RGBAColour[nC];

Modified: trunk/Build/source/utils/asymptote/examples/cylinder.asy
===================================================================
--- trunk/Build/source/utils/asymptote/examples/cylinder.asy	2020-03-03 22:33:26 UTC (rev 54033)
+++ trunk/Build/source/utils/asymptote/examples/cylinder.asy	2020-03-03 22:35:09 UTC (rev 54034)
@@ -1,8 +1,17 @@
+size(0,100);
 import solids;
-
-size(0,100);
 currentlight=Viewport;
 
-revolution r=cylinder(O,1,1.5,Y+Z);
-draw(surface(r),green,render(merge=true));
-draw(r,blue);
+triple v=O;
+real r=1;
+real h=1.5;
+triple axis=Y+Z;
+
+// Optimized cylinder
+surface cylinder=shift(v)*align(unit(axis))*scale(r,r,h)*unitcylinder;
+draw(cylinder,green,render(merge=true));
+
+// Skeleton
+revolution r=cylinder(v,r,h,axis);
+//draw(surface(r),green,render(merge=true));
+draw(r,blue+0.15mm);

Modified: trunk/Build/source/utils/asymptote/examples/pipes.asy
===================================================================
--- trunk/Build/source/utils/asymptote/examples/pipes.asy	2020-03-03 22:33:26 UTC (rev 54033)
+++ trunk/Build/source/utils/asymptote/examples/pipes.asy	2020-03-03 22:35:09 UTC (rev 54034)
@@ -90,7 +90,7 @@
 
   // draw two cylinders
   draw(TBase*objSurface,objStyle,render);
-  draw(TEnd*shift((0,0,-h))*objSurface,objStyle,render);
+  draw(TEnd*shift((0,0,-h+1e-5))*objSurface,objStyle,render);
 	
   // draw the link between two cylinders
   triple pStart=TBase*(0.5*h*Z);

Modified: trunk/Build/source/utils/asymptote/examples/randompath3.asy
===================================================================
--- trunk/Build/source/utils/asymptote/examples/randompath3.asy	2020-03-03 22:33:26 UTC (rev 54033)
+++ trunk/Build/source/utils/asymptote/examples/randompath3.asy	2020-03-03 22:35:09 UTC (rev 54034)
@@ -1,4 +1,5 @@
 import three;
 
 size(300);
-draw(randompath3(100),red);
+path3 g=randompath3(100);
+draw(g,red,currentlight);

Modified: trunk/Build/source/utils/asymptote/examples/sphere.asy
===================================================================
--- trunk/Build/source/utils/asymptote/examples/sphere.asy	2020-03-03 22:33:26 UTC (rev 54033)
+++ trunk/Build/source/utils/asymptote/examples/sphere.asy	2020-03-03 22:35:09 UTC (rev 54034)
@@ -1,6 +1,6 @@
 import three;
 
 size(200);
-currentprojection=orthographic(5,4,3);
+//currentprojection=orthographic(5,4,3);
 
-draw(unitsphere,green,render(compression=Zero,merge=true));
+draw(unitsphere,green+opacity(0.5),render(compression=Zero,merge=true));

Modified: trunk/Build/source/utils/asymptote/examples/unitoctant.asy
===================================================================
--- trunk/Build/source/utils/asymptote/examples/unitoctant.asy	2020-03-03 22:33:26 UTC (rev 54033)
+++ trunk/Build/source/utils/asymptote/examples/unitoctant.asy	2020-03-03 22:35:09 UTC (rev 54034)
@@ -3,7 +3,7 @@
 currentprojection=orthographic(5,4,2);
 
 size(0,150);
-patch s=octant1;
+patch s=octant1x;
 draw(surface(s),green+opacity(0.5));
 draw(s.external(),blue);
 

Modified: trunk/Build/source/utils/asymptote/examples/vertexshading.asy
===================================================================
--- trunk/Build/source/utils/asymptote/examples/vertexshading.asy	2020-03-03 22:33:26 UTC (rev 54033)
+++ trunk/Build/source/utils/asymptote/examples/vertexshading.asy	2020-03-03 22:35:09 UTC (rev 54034)
@@ -4,7 +4,10 @@
 
 currentprojection=perspective(4,5,5);
 
-//draw(shift(2Z)*surface(O--X--Y--cycle),blue);
+draw(shift(2Z)*surface(O--X--Y--cycle,
+                       new pen[] {red+opacity(0.5),green,blue}));
+draw(shift(2Y+2Z)*surface(O--X--Y--cycle),blue);
+draw(shift(2Y+Z)*surface(unitsquare3),green);
 
 draw(surface(unitcircle3,new pen[] {red,green,blue,black}));
 draw(surface(shift(Z)*unitsquare3,

Modified: trunk/Build/source/utils/asymptote/examples/workcone.asy
===================================================================
--- trunk/Build/source/utils/asymptote/examples/workcone.asy	2020-03-03 22:33:26 UTC (rev 54033)
+++ trunk/Build/source/utils/asymptote/examples/workcone.asy	2020-03-03 22:35:09 UTC (rev 54034)
@@ -18,9 +18,11 @@
 
 render render=render(compression=0,merge=true);
 
-path3 p=(0,0,0)--(x,0,s);
+draw(scale(x1,x1,-s1)*shift(-Z)*unitcone,lightblue+opacity(0.5),render);
+
+path3 p=(x2,0,s2)--(x,0,s+0.005);
 revolution a=revolution(p,Z);
-draw(surface(a,4),lightblue+opacity(0.5),render);
+draw(surface(a),lightblue+opacity(0.5),render);
 
 path3 q=(x,0,s)--(r,0,h);
 revolution b=revolution(q,Z);

Modified: trunk/Build/source/utils/asymptote/fftw++.h
===================================================================
--- trunk/Build/source/utils/asymptote/fftw++.h	2020-03-03 22:33:26 UTC (rev 54033)
+++ trunk/Build/source/utils/asymptote/fftw++.h	2020-03-03 22:35:09 UTC (rev 54034)
@@ -20,7 +20,7 @@
 #ifndef __fftwpp_h__
 #define __fftwpp_h__ 1
 
-#define __FFTWPP_H_VERSION__ 2.07
+#define __FFTWPP_H_VERSION__ 2.08
 
 #include <cstdlib>
 #include <fstream>
@@ -88,6 +88,11 @@
 #define FFTWdouble doubleAlign
 #define FFTWdelete deleteAlign
 
+// Return the memory alignment used by FFTW.
+// Use of this function requires applying patches/fftw-3.3.8-alignment.patch
+// to the FFTW source, recompiling, and reinstalling the FFW library.
+extern "C" size_t fftw_alignment();
+
 class fftw;
 
 extern "C" fftw_plan Planner(fftw *F, Complex *in, Complex *out);
@@ -496,26 +501,18 @@
 
 class Transpose {
   fftw_plan plan;
-  fftw_plan plan2;
-  unsigned int a,b;
-  unsigned int nlength,mlength;
-  unsigned int ilast,jlast;
-  unsigned int rows,cols;
-  unsigned int threads;
   bool inplace;
-  unsigned int size;
 public:
   template<class T>
   Transpose(unsigned int rows, unsigned int cols, unsigned int length,
-            T *in, T *out=NULL, unsigned int threads=fftw::maxthreads) :
-    rows(rows), cols(cols), threads(threads) {
-    size=sizeof(T);
+            T *in, T *out=NULL, unsigned int threads=fftw::maxthreads) {
+    unsigned int size=sizeof(T);
     if(size % sizeof(double) != 0) {
       std::cerr << "ERROR: Transpose is not implemented for type of size " 
                 << size;
       exit(1);
     }
-    plan=plan2=NULL;
+    plan=NULL;
     if(rows == 0 || cols == 0) return;
     size /= sizeof(double);
     length *= size;
@@ -522,30 +519,15 @@
 
     if(!out) out=in;
     inplace=(out==in);
-    if(inplace) {
-      fftw::planThreads(threads);
-      threads=1;
-    } else fftw::planThreads(1);
+    fftw::planThreads(threads);
     
     fftw_iodim dims[3];
 
-    a=std::min(rows,threads);
-    b=std::min(cols,threads/a);
-
-    unsigned int n=utils::ceilquotient(rows,a);
-    unsigned int m=utils::ceilquotient(cols,b);
-    
-    // If rows <= threads then a=rows and n=1.
-    // If rows >= threads then b=1 and m=cols.
-    
-    nlength=n*length;
-    mlength=m*length;
-    
-    dims[0].n=n; 
+    dims[0].n=rows; 
     dims[0].is=cols*length;
     dims[0].os=length;
     
-    dims[1].n=m; 
+    dims[1].n=cols; 
     dims[1].is=length;
     dims[1].os=rows*length;
 
@@ -556,74 +538,21 @@
     // A plan with rank=0 is a transpose.
     plan=fftw_plan_guru_r2r(0,NULL,3,dims,(double *) in,(double *) out,
                             NULL,fftw::effort);
-    ilast=a;
-    jlast=b;
-    
-    if(n*a > rows) { // Only happens when rows > threads.
-      a=utils::ceilquotient(rows,n);
-      ilast=a-1;
-      dims[0].n=rows-n*ilast;
-      plan2=fftw_plan_guru_r2r(0,NULL,3,dims,(double *) in,(double *) out,
-                               NULL,fftw::effort);
-    } else { // Only happens when rows < threads.
-      if(m*b > cols) {
-        b=utils::ceilquotient(cols,m);
-        jlast=b-1;
-        dims[1].n=cols-m*jlast;
-        plan2=fftw_plan_guru_r2r(0,NULL,3,dims,(double *) in,(double *) out,
-                                 NULL,fftw::effort);
-      }
-    }
   }
 
   ~Transpose() {
     if(plan) fftw_destroy_plan(plan);
-    if(plan2) fftw_destroy_plan(plan2);
   }
   
   template<class T>
   void transpose(T *in, T *out=NULL) {
-    if(rows == 0 || cols == 0) return;
+    if(!plan) return;
     if(!out) out=in;
     if(inplace ^ (out == in)) {
       std::cerr << "ERROR: Transpose " << inout << std::endl;
       exit(1);
     }
-#ifndef FFTWPP_SINGLE_THREAD
-    if(a > 1) {
-      if(b > 1) {
-        int A=a, B=b;
-#pragma omp parallel for num_threads(A)
-        for(unsigned int i=0; i < a; ++i) {
-          unsigned int I=i*nlength;
-#pragma omp parallel for num_threads(B)
-          for(unsigned int j=0; j < b; ++j) {
-            unsigned int J=j*mlength;
-            fftw_execute_r2r((i < ilast && j < jlast) ? plan : plan2,
-                             (double *) in+cols*I+J,
-                             (double *) out+rows*J+I);
-          }
-        }
-      } else {
-        int A=a;
-#pragma omp parallel for num_threads(A)
-        for(unsigned int i=0; i < a; ++i) {
-          unsigned int I=i*nlength;
-          fftw_execute_r2r(i < ilast ? plan : plan2,
-                           (double *) in+cols*I,(double *) out+I);
-        }
-      }
-    } else if(b > 1) {
-      int B=b;
-#pragma omp parallel for num_threads(B)
-      for(unsigned int j=0; j < b; ++j) {
-        unsigned int J=j*mlength;
-        fftw_execute_r2r(j < jlast ? plan : plan2,
-                         (double *) in+J,(double *) out+rows*J);
-      }
-    } else
-#endif
-      fftw_execute_r2r(plan,(double *) in,(double*) out);
+    fftw_execute_r2r(plan,(double *) in,(double*) out);
   }
 };
 

Modified: trunk/Build/source/utils/asymptote/glrender.cc
===================================================================
--- trunk/Build/source/utils/asymptote/glrender.cc	2020-03-03 22:33:26 UTC (rev 54033)
+++ trunk/Build/source/utils/asymptote/glrender.cc	2020-03-03 22:35:09 UTC (rev 54034)
@@ -25,6 +25,12 @@
 #include "drawimage.h"
 #include "interact.h"
 
+namespace gl {
+#ifdef HAVE_PTHREAD
+pthread_t mainthread;
+#endif
+}
+
 #ifdef HAVE_GL
 #include "tr.h"
 
@@ -60,13 +66,12 @@
 Billboard BB;
 
 GLint pixelShader;
-GLint noNormalShader;
 GLint materialShader;
 GLint colorShader;
 GLint transparentShader;
 
-vertexBuffer material0Data;
-vertexBuffer material1Data;
+vertexBuffer material0Data(GL_POINTS);
+vertexBuffer material1Data(GL_LINES);
 vertexBuffer materialData;
 vertexBuffer colorData;
 vertexBuffer transparentData;
@@ -397,7 +402,6 @@
 #endif
 
 #ifdef HAVE_PTHREAD
-pthread_t mainthread;
 
 pthread_cond_t initSignal=PTHREAD_COND_INITIALIZER;
 pthread_mutex_t initLock=PTHREAD_MUTEX_INITIALIZER;
@@ -452,8 +456,7 @@
   camp::pixelShader=compileAndLinkShader(shaders,Nlights,Nmaterials,
                                          shaderParams);
   shaderParams.pop_back();
-  camp::noNormalShader=compileAndLinkShader(shaders,Nlights,Nmaterials,
-                                            shaderParams);
+
   shaderParams.push_back("NORMAL");
   camp::materialShader=compileAndLinkShader(shaders,Nlights,Nmaterials,
                                             shaderParams);
@@ -471,7 +474,6 @@
   glDeleteProgram(camp::colorShader);
   glDeleteProgram(camp::materialShader);
   glDeleteProgram(camp::pixelShader);
-  glDeleteProgram(camp::noNormalShader);
 }
 
 void setBuffers()
@@ -485,7 +487,6 @@
   glBindVertexArray(vao);
 
   camp::material0Data.reserve0();
-  camp::material1Data.reserve1();
   camp::materialData.reserve();
   camp::colorData.Reserve();
   camp::triangleData.Reserve();
@@ -523,7 +524,7 @@
   
   Picture->render(size2,m,M,perspective,remesh);
   
-  remesh=false;
+  if(!outlinemode) remesh=false;
 }
 
 // Return x divided by y rounded up to the nearest integer.
@@ -1841,7 +1842,7 @@
 
 void setUniforms(const vertexBuffer& data, GLint shader)
 {
-  bool normal=shader != pixelShader && shader != noNormalShader;
+  bool normal=shader != pixelShader;
     
   if(shader != gl::lastshader) {
     glUseProgram(shader);
@@ -1885,7 +1886,6 @@
   
   glUniformMatrix4fv(glGetUniformLocation(shader,"viewMat"),1,GL_FALSE,
                      value_ptr(gl::viewMat));
-  
   if(normal)
     glUniformMatrix3fv(glGetUniformLocation(shader,"normMat"),1,GL_FALSE,
                        value_ptr(gl::normMat));
@@ -1895,20 +1895,17 @@
 {
   if(data.indices.empty()) return;
   
-  bool pixel=shader == pixelShader;
-  bool normal=shader != noNormalShader && !pixel;
+  bool normal=shader != pixelShader;
   bool color=shader == colorShader || shader == transparentShader;
   
   const size_t size=sizeof(GLfloat);
   const size_t intsize=sizeof(GLint);
   const size_t bytestride=color ? sizeof(VertexData) :
-    (normal ? sizeof(vertexData) :
-     (pixel ? sizeof(vertexData0) : sizeof(vertexData1)));
+    (normal ? sizeof(vertexData) : sizeof(vertexData0));
 
   if(color) registerBuffer(data.Vertices,attributeBuffer);
   else if(normal) registerBuffer(data.vertices,attributeBuffer);
-  else if(pixel) registerBuffer(data.vertices0,attributeBuffer);
-  else registerBuffer(data.vertices1,attributeBuffer);
+  else registerBuffer(data.vertices0,attributeBuffer);
   
   registerBuffer(data.indices,indicesBuffer,GL_ELEMENT_ARRAY_BUFFER);
   
@@ -1925,7 +1922,7 @@
     glVertexAttribPointer(normalAttrib,3,GL_FLOAT,GL_FALSE,bytestride,
                           (void *) (3*size));
     glEnableVertexAttribArray(normalAttrib);
-  } else if(pixel) {
+  } else if(!normal) {
     glVertexAttribPointer(widthAttrib,1,GL_FLOAT,GL_FALSE,bytestride,
                           (void *) (3*size));
     glEnableVertexAttribArray(widthAttrib);
@@ -1932,7 +1929,7 @@
   }
     
   glVertexAttribIPointer(materialAttrib,1,GL_INT,bytestride, 
-                         (void *) ((normal ? 6 : (pixel ? 4 : 3))*size));
+                         (void *) ((normal ? 6 : 4)*size));
   glEnableVertexAttribArray(materialAttrib);
 
   if(color) {
@@ -1941,13 +1938,12 @@
     glEnableVertexAttribArray(colorAttrib);
   }
   
-  glDrawElements(normal ? GL_TRIANGLES : (pixel ? GL_POINTS : GL_LINES),
-                 data.indices.size(),GL_UNSIGNED_INT,(void *) 0);
+  glDrawElements(data.type,data.indices.size(),GL_UNSIGNED_INT,(void *) 0);
 
   glDisableVertexAttribArray(positionAttrib);
   if(normal && gl::Nlights > 0)
     glDisableVertexAttribArray(normalAttrib);
-  if(pixel)
+  if(!normal)
    glDisableVertexAttribArray(widthAttrib);
   glDisableVertexAttribArray(materialAttrib);
   if(color)
@@ -1967,7 +1963,7 @@
 
 void drawMaterial1()
 {
-  drawBuffer(material1Data,noNormalShader);
+  drawBuffer(material1Data,materialShader);
   material1Data.clear();
 }
 

Modified: trunk/Build/source/utils/asymptote/glrender.h
===================================================================
--- trunk/Build/source/utils/asymptote/glrender.h	2020-03-03 22:33:26 UTC (rev 54033)
+++ trunk/Build/source/utils/asymptote/glrender.h	2020-03-03 22:35:09 UTC (rev 54034)
@@ -8,6 +8,7 @@
 
 #include "common.h"
 #include "triple.h"
+#include "pen.h"
 
 #ifdef HAVE_LIBGLM
 #define GLM_ENABLE_EXPERIMENTAL
@@ -34,13 +35,21 @@
 #ifdef __APPLE__
 #define GL_SILENCE_DEPRECATION
 #include <OpenGL/gl.h>
+
 #ifdef HAVE_LIBGLUT
 #include <GLUT/glut.h>
+#ifndef GLUT_3_2_CORE_PROFILE
+#undef HAVE_GL
 #endif
+
+#endif
+
 #ifdef HAVE_LIBOSMESA
 #include <GL/osmesa.h>
 #endif
+
 #else
+
 #ifdef __MSDOS__
 #undef _WIN32
 #include <GL/gl.h>
@@ -47,12 +56,15 @@
 #include <GL/wglew.h>
 #include <GL/wglext.h>
 #endif
+
 #ifdef HAVE_LIBGLUT
 #include <GL/glut.h>
 #endif
+
 #ifdef HAVE_LIBOSMESA
 #include <GL/osmesa.h>
 #endif
+
 #endif
 
 #else
@@ -241,19 +253,6 @@
   }
 };
 
-class vertexData1 {
-public:
-  GLfloat position[3];
-  GLint material;
-  vertexData1() {};
-  vertexData1(const triple& v) {
-    position[0]=v.getx();
-    position[1]=v.gety();
-    position[2]=v.getz();
-    material=MaterialIndex;
-  }
-};
-
 class vertexData0 {
 public:
   GLfloat position[3];
@@ -270,9 +269,9 @@
 
 class vertexBuffer {
 public:  
+  GLint type;
   std::vector<vertexData> vertices;
   std::vector<VertexData> Vertices;
-  std::vector<vertexData1> vertices1;
   std::vector<vertexData0> vertices0;
   std::vector<GLuint> indices;
 
@@ -279,10 +278,11 @@
   std::vector<Material> materials;
   std::vector<GLint> materialTable;
 
+  vertexBuffer(GLint type=GL_TRIANGLES) : type(type) {}
+
   void clear() {
     vertices.clear();
     Vertices.clear();
-    vertices1.clear();
     vertices0.clear();
     indices.clear();
     materials.clear();
@@ -293,10 +293,6 @@
     vertices0.reserve(nbuffer);
   }
 
-  void reserve1() {
-    vertices1.reserve(nbuffer);
-  }
-
  void reserve() {
     vertices.reserve(Nbuffer);
     indices.reserve(Nbuffer);
@@ -328,13 +324,6 @@
     return nvertices;
   }     
 
-// Store the vertex v.
-  GLuint vertex1(const triple &v) {
-    size_t nvertices=vertices1.size();
-    vertices1.push_back(vertexData1(v));
-    return nvertices;
-  }     
-
 // Store the pixel v and its width.
   GLuint vertex0(const triple &v, double width) {
     size_t nvertices=vertices0.size();
@@ -363,11 +352,6 @@
     Vertices.insert(Vertices.end(),b.Vertices.begin(),b.Vertices.end());
   }
 
-  void append1(const vertexBuffer& b) {
-    appendOffset(indices,b.indices,vertices1.size());
-    vertices1.insert(vertices1.end(),b.vertices1.begin(),b.vertices1.end());
-  }
-
   void append0(const vertexBuffer& b) {
     appendOffset(indices,b.indices,vertices0.size());
     vertices0.insert(vertices0.end(),b.vertices0.begin(),b.vertices0.end());

Modified: trunk/Build/source/utils/asymptote/install-sh
===================================================================
--- trunk/Build/source/utils/asymptote/install-sh	2020-03-03 22:33:26 UTC (rev 54033)
+++ trunk/Build/source/utils/asymptote/install-sh	2020-03-03 22:35:09 UTC (rev 54034)
@@ -518,3 +518,60 @@
 # time-stamp-time-zone: "UTC"
 # time-stamp-end: "; # UTC"
 # End:
+est -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } &&
+    { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } &&
+    { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } &&
+    { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } &&
+
+    # If -C, don't bother to copy if it wouldn't change the file.
+    if $copy_on_change &&
+       old=`LC_ALL=C ls -dlL "$dst"     2>/dev/null` &&
+       new=`LC_ALL=C ls -dlL "$dsttmp"  2>/dev/null` &&
+       set -f &&
+       set X $old && old=:$2:$4:$5:$6 &&
+       set X $new && new=:$2:$4:$5:$6 &&
+       set +f &&
+       test "$old" = "$new" &&
+       $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1
+    then
+      rm -f "$dsttmp"
+    else
+      # Rename the file to the real destination.
+      $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null ||
+
+      # The rename failed, perhaps because mv can't rename something else
+      # to itself, or perhaps because mv is so ancient that it does not
+      # support -f.
+      {
+        # Now remove or move aside any old file at destination location.
+        # We try this two ways since rm can't unlink itself on some
+        # systems and the destination file might be busy for other
+        # reasons.  In this case, the final cleanup might fail but the new
+        # file should still install successfully.
+        {
+          test ! -f "$dst" ||
+          $doit $rmcmd -f "$dst" 2>/dev/null ||
+          { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null &&
+            { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; }
+          } ||
+          { echo "$0: cannot unlink or rename $dst" >&2
+            (exit 1); exit 1
+          }
+        } &&
+
+        # Now rename the file to the real destination.
+        $doit $mvcmd "$dsttmp" "$dst"
+      }
+    fi || exit 1
+
+    trap '' 0
+  fi
+done
+
+# Local variables:
+# eval: (add-hook 'before-save-hook 'time-stamp)
+# time-stamp-start: "scriptversion="
+# time-stamp-format: "%:y-%02m-%02d.%02H"
+# time-stamp-time-zone: "UTC0"
+# time-stamp-end: "; # UTC"
+# End:

Modified: trunk/Build/source/utils/asymptote/interact.cc
===================================================================
--- trunk/Build/source/utils/asymptote/interact.cc	2020-03-03 22:33:26 UTC (rev 54033)
+++ trunk/Build/source/utils/asymptote/interact.cc	2020-03-03 22:35:09 UTC (rev 54034)
@@ -18,10 +18,20 @@
 #include "interact.h"
 #include "runhistory.h"
 
-#if defined(HAVE_LIBREADLINE) && defined(HAVE_LIBCURSES)
+#ifdef HAVE_LIBCURSES
+#ifdef HAVE_LIBREADLINE
 #include <readline/readline.h>
 #include <readline/history.h>
+#else
+#ifdef HAVE_LIBEDIT
+#ifdef HAVE_EDITLINE_READLINE_H
+#include <editline/readline.h>
+#else
+#include <readline/readline.h>
 #endif
+#endif
+#endif
+#endif
 
 #include "util.h"
 #include "errormsg.h"
@@ -50,7 +60,7 @@
   return currentCompleter ? (*currentCompleter)(text, state) : 0;
 }
 
-#if defined(HAVE_LIBREADLINE) && defined(HAVE_LIBCURSES)
+#if defined(HAVE_READLINE) && defined(HAVE_LIBCURSES)
 void init_completion() {
   rl_completion_entry_function=call_completer;
 
@@ -111,7 +121,7 @@
     if(!fin) fin=fdopen(fd,"r");
     Readline=readpipeline;
   } else {
-#if defined(HAVE_LIBREADLINE) && defined(HAVE_LIBCURSES)
+#if defined(HAVE_READLINE) && defined(HAVE_LIBCURSES)
     if(tty) {
       Readline=readline;
     } else
@@ -120,13 +130,20 @@
   }
 }
 
+void init_readline(bool tabcompletion)
+{
+#if defined(HAVE_READLINE) && defined(HAVE_LIBCURSES)
+  rl_bind_key('\t',tabcompletion ? rl_complete : rl_insert);
+#endif
+}
+
 void init_interactive()
 {
   if(getSetting<bool>("xasy")) tty=false;
-#if defined(HAVE_LIBREADLINE) && defined(HAVE_LIBCURSES)
+#if defined(HAVE_READLINE) && defined(HAVE_LIBCURSES)
   if(tty) {
     init_completion();
-    run::init_readline(getSetting<bool>("tabcompletion"));
+    interact::init_readline(getSetting<bool>("tabcompletion"));
     read_history(historyname.c_str());
   }
 #endif
@@ -161,7 +178,7 @@
 }
 
 void addToHistory(string line) {
-#if defined(HAVE_LIBREADLINE) && defined(HAVE_LIBCURSES)
+#if defined(HAVE_READLINE) && 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());
@@ -170,7 +187,7 @@
 }
 
 string getLastHistoryLine() {
-#if defined(HAVE_LIBREADLINE) && defined(HAVE_LIBCURSES)
+#if defined(HAVE_READLINE) && defined(HAVE_LIBCURSES)
   if(tty && history_length > 0) {
     HIST_ENTRY *entry=history_list()[history_length-1];
     if(!entry) {
@@ -185,7 +202,7 @@
 }
 
 void setLastHistoryLine(string line) {
-#if defined(HAVE_LIBREADLINE) && defined(HAVE_LIBCURSES)
+#if defined(HAVE_READLINE) && defined(HAVE_LIBCURSES)
   if(tty) {
     if (history_length > 0) {
       HIST_ENTRY *entry=remove_history(history_length-1);
@@ -194,7 +211,7 @@
         em.compiler();
         em << "cannot modify last history line";
       } else {
-        free(entry->line);
+        free((char *) entry->line);
         free(entry);
       }
     }
@@ -204,7 +221,7 @@
 }
 
 void deleteLastLine() {
-#if defined(HAVE_LIBREADLINE) && defined(HAVE_LIBCURSES)
+#if defined(HAVE_READLINE) && defined(HAVE_LIBCURSES)
   if(tty) {
     HIST_ENTRY *entry=remove_history(history_length-1);
     if(!entry) {
@@ -211,7 +228,7 @@
       em.compiler();
       em << "cannot delete last history line";
     } else {
-      free(entry->line);
+      free((char *) entry->line);
       free(entry);
     }
   }
@@ -219,7 +236,7 @@
 }
 
 void cleanup_interactive() {
-#if defined(HAVE_LIBREADLINE) && defined(HAVE_LIBCURSES)
+#if defined(HAVE_READLINE) && defined(HAVE_LIBCURSES)
   // Write the history file.
   if(tty) {
     stifle_history(intcast(getSetting<Int>("historylines")));

Modified: trunk/Build/source/utils/asymptote/interact.h
===================================================================
--- trunk/Build/source/utils/asymptote/interact.h	2020-03-03 22:33:26 UTC (rev 54033)
+++ trunk/Build/source/utils/asymptote/interact.h	2020-03-03 22:35:09 UTC (rev 54034)
@@ -49,6 +49,7 @@
 
 #define YY_READ_BUF_SIZE YY_BUF_SIZE
   
+void init_readline(bool tabcompletion);
 }
 
 #endif // INTERACT_H

Modified: trunk/Build/source/utils/asymptote/jsfile.cc
===================================================================
--- trunk/Build/source/utils/asymptote/jsfile.cc	2020-03-03 22:33:26 UTC (rev 54033)
+++ trunk/Build/source/utils/asymptote/jsfile.cc	2020-03-03 22:35:09 UTC (rev 54034)
@@ -232,9 +232,53 @@
   }
   out << "P.push(new Triangles("
       << materialIndex << "," << newl
-      << Min << "," << Max << "));" << newl;
-  out << newl;
+      << Min << "," << Max << "));" << newl << newl;
 }
 
+void jsfile::addSphere(const triple& center, double radius, bool half,
+                       const double& polar, const double& azimuth)
+{
+  out << "sphere(" << center << "," << radius << ","
+      << drawElement::centerIndex << "," << materialIndex;
+  if(half)
+    out << "," << newl << "[" << polar << "," << azimuth << "]";
+  out << ");" << newl << newl;
 }
+
+// core signifies whether to also draw a central line for better small-scale
+// rendering.
+void jsfile::addCylinder(const triple& center, double radius, double height,
+                         const double& polar, const double& azimuth,
+                         bool core)
+{
+  out << "cylinder(" << center << "," << radius << "," << height << ","
+      << drawElement::centerIndex << "," << materialIndex
+      << "," << newl << "[" << polar << "," << azimuth << "]," << core
+      << ");" << newl << newl;
+}
+
+void jsfile::addDisk(const triple& center, double radius,
+                     const double& polar, const double& azimuth)
+{
+  out << "disk(" << center << "," << radius << ","
+      << drawElement::centerIndex << "," << materialIndex
+      << "," << newl << "[" << polar << "," << azimuth << "]"
+      << ");" << newl << newl;
+}
+
+void jsfile::addTube(const triple *g, double width,
+                     const triple& Min, const triple& Max, bool core)
+
+{
+  out << "tube(["
+      << g[0] << "," << newl
+      << g[1] << "," << newl
+      << g[2] << "," << newl
+      << g[3] << newl << "],"
+      << width << "," 
+      << drawElement::centerIndex << "," << materialIndex << ","
+      << Min << "," << Max << "," << core <<");" << newl << newl;
+}
+
+}
 #endif

Modified: trunk/Build/source/utils/asymptote/jsfile.h
===================================================================
--- trunk/Build/source/utils/asymptote/jsfile.h	2020-03-03 22:33:26 UTC (rev 54033)
+++ trunk/Build/source/utils/asymptote/jsfile.h	2020-03-03 22:35:09 UTC (rev 54034)
@@ -42,6 +42,15 @@
                     const uint32_t (*PI)[3], const uint32_t (*NI)[3],
                     const uint32_t (*CI)[3],
                     const triple& Min, const triple& Max);
+  void addSphere(const triple& center, double radius, bool half=false,
+                 const double& polar=0.0, const double& azimuth=0.0);
+  void addCylinder(const triple& center, double radius, double height,
+                   const double& polar, const double& azimuth,
+                   bool core=false);
+  void addDisk(const triple& center, double radius,
+               const double& polar=0.0, const double& azimuth=0.0);
+  void addTube(const triple *g, double width,
+               const triple& Min, const triple& Max, bool core=false);
 };
 
 } //namespace camp

Modified: trunk/Build/source/utils/asymptote/pair.h
===================================================================
--- trunk/Build/source/utils/asymptote/pair.h	2020-03-03 22:33:26 UTC (rev 54033)
+++ trunk/Build/source/utils/asymptote/pair.h	2020-03-03 22:35:09 UTC (rev 54034)
@@ -147,14 +147,14 @@
     return z.length();
   }
 
-  double angle() const
+  double angle(bool warn=true) const
   {
-    return camp::angle(x,y);
+    return camp::angle(x,y,warn);
   }
   
-  friend double angle(const pair& z)
+  friend double angle(const pair& z, bool warn=true)
   {
-    return z.angle();
+    return z.angle(warn);
   }
   
   friend pair unit(const pair& z)
@@ -207,7 +207,10 @@
     if(paren) s >> c;
     s >> z.x >> std::ws;
     if(!s.eof() && s.peek() == ',') s >> c >> z.y;
-    else z.y=0.0;
+    else {
+      if(paren && !s.eof()) s >> z.y;
+      else z.y=0.0;
+    }
     if(paren) {
       s >> std::ws;
       if(s.peek() == ')') s >> c;

Modified: trunk/Build/source/utils/asymptote/path.cc
===================================================================
--- trunk/Build/source/utils/asymptote/path.cc	2020-03-03 22:33:26 UTC (rev 54033)
+++ trunk/Build/source/utils/asymptote/path.cc	2020-03-03 22:35:09 UTC (rev 54034)
@@ -600,7 +600,19 @@
   return sqrt(dx*dx+dy*dy);
 }
 
-// Calculates arclength of a cubic using adaptive simpson integration.
+// Calculates arclength of a cubic Bezier curve using adaptive Simpson
+// integration.
+double arcLength(const pair& z0, const pair& c0, const pair& c1,
+                 const pair& z1)
+{
+  double integral;
+  derivative(a,b,c,z0,c0,c1,z1);
+  
+  if(!simpson(integral,ds,0.0,1.0,DBL_EPSILON,1.0))
+    reportError("nesting capacity exceeded in computing arclength");
+  return integral;
+}
+
 double path::cubiclength(Int i, double goal) const
 {
   const pair& z0=point(i);
@@ -611,14 +623,8 @@
     return (goal < 0 || goal >= L) ? L : -goal/L;
   }
   
-  const pair& c0=postcontrol(i);
-  const pair& c1=precontrol(i+1);
-  
-  double integral;
-  derivative(a,b,c,z0,c0,c1,z1);
-  
-  if(!simpson(integral,ds,0.0,1.0,DBL_EPSILON,1.0))
-    reportError("nesting capacity exceeded in computing arclength");
+  double integral=arcLength(z0,postcontrol(i),precontrol(i+1),z1);
+
   L=3.0*integral;
   if(goal < 0 || goal >= L) return L;
   

Modified: trunk/Build/source/utils/asymptote/path.h
===================================================================
--- trunk/Build/source/utils/asymptote/path.h	2020-03-03 22:33:26 UTC (rev 54033)
+++ trunk/Build/source/utils/asymptote/path.h	2020-03-03 22:35:09 UTC (rev 54034)
@@ -385,6 +385,9 @@
   
 };
 
+double arcLength(const pair& z0, const pair& c0, const pair& c1,
+                 const pair& z1);
+
 extern path nullpath;
 extern const unsigned maxdepth;
 extern const unsigned mindepth;

Modified: trunk/Build/source/utils/asymptote/path3.cc
===================================================================
--- trunk/Build/source/utils/asymptote/path3.cc	2020-03-03 22:33:26 UTC (rev 54033)
+++ trunk/Build/source/utils/asymptote/path3.cc	2020-03-03 22:35:09 UTC (rev 54034)
@@ -389,7 +389,19 @@
   return sqrt(dx*dx+dy*dy+dz*dz);
 }
 
-// Calculates arclength of a cubic using adaptive simpson integration.
+// Calculates arclength of a cubic Bezier curve using adaptive Simpson
+// integration.
+double arcLength(const triple& z0, const triple& c0, const triple& c1,
+                 const triple& z1)
+{
+  double integral;
+  derivative(a,b,c,z0,c0,c1,z1);
+  
+  if(!simpson(integral,ds,0.0,1.0,DBL_EPSILON,1.0))
+    reportError("nesting capacity exceeded in computing arclength");
+  return integral;
+}
+
 double path3::cubiclength(Int i, double goal) const
 {
   const triple& z0=point(i);
@@ -399,14 +411,9 @@
     L=(z1-z0).length();
     return (goal < 0 || goal >= L) ? L : -goal/L;
   }
-  const triple& c0=postcontrol(i);
-  const triple& c1=precontrol(i+1);
   
-  double integral;
-  derivative(a,b,c,z0,c0,c1,z1);
+  double integral=arcLength(z0,postcontrol(i),precontrol(i+1),z1);
   
-  if(!simpson(integral,ds,0.0,1.0,DBL_EPSILON,1.0))
-    reportError("nesting capacity exceeded in computing arclength");
   L=3.0*integral;
   if(goal < 0 || goal >= L) return L;
   

Modified: trunk/Build/source/utils/asymptote/path3.h
===================================================================
--- trunk/Build/source/utils/asymptote/path3.h	2020-03-03 22:33:26 UTC (rev 54033)
+++ trunk/Build/source/utils/asymptote/path3.h	2020-03-03 22:35:09 UTC (rev 54034)
@@ -329,6 +329,9 @@
   Int windingnumber(const triple& z) const;
 };
 
+double arcLength(const triple& z0, const triple& c0, const triple& c1,
+                 const triple& z1);
+  
 path3 transformed(const vm::array& t, const path3& p);
 path3 transformed(const double* t, const path3& p);
   

Deleted: trunk/Build/source/utils/asymptote/quaternion.cc
===================================================================
--- trunk/Build/source/utils/asymptote/quaternion.cc	2020-03-03 22:33:26 UTC (rev 54033)
+++ trunk/Build/source/utils/asymptote/quaternion.cc	2020-03-03 22:35:09 UTC (rev 54034)
@@ -1,246 +0,0 @@
-/***********************************************************************
-
-  quaternion.cc - A quaternion class
-
-  -------------------------------------------------------------------
-
-  GLUI User Interface Toolkit (LGPL)
-  Copyright (c) 1998 Paul Rademacher
-
-  WWW:    http://sourceforge.net/projects/glui/
-  Forums: http://sourceforge.net/forum/?group_id=92496
-
-  This library is free software; you can redistribute it and/or
-  modify it under the terms of the GNU Lesser General Public
-  License as published by the Free Software Foundation; either
-  version 2.1 of the License, or (at your option) any later version.
-
-  This library is distributed in the hope that it will be useful,
-  but WITHOUT ANY WARRANTY; without even the implied warranty of
-  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-  Lesser General Public License for more details.
-
-  You should have received a copy of the GNU Lesser General Public
-  License along with this library; if not, write to the Free Software
-  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-
-************************************************************************
-
-  Feb 1998, Paul Rademacher (rademach at cs.unc.edu)
-  Oct 2003, Nigel Stewart - GLUI Code Cleaning
-  
-************************************************************************/
-
-#include "quaternion.h"
-#include <cmath>
-
-/******************************************* constructors **************/
-
-quat::quat()
-{
-    *this = quat_identity();
-}
-
-quat::quat(const float x, const float y, const float z, const float w)
-{
-    v.set( x, y, z );
-    s = w;
-}
-
-quat::quat(const vec3 &_v, const float _s)
-{
-    set( _v, _s );
-}
-
-quat::quat(const float _s, const vec3 &_v)
-{
-    set( _v, _s );
-}
-
-quat::quat(const float *d)
-{
-    v[0] = d[0];
-    v[1] = d[1];
-    v[2] = d[2];
-    s    = d[3];
-}
-
-quat::quat(const double *d)
-{
-    v[0] = (float) d[0];
-    v[1] = (float) d[1];
-    v[2] = (float) d[2];
-    s    = (float) d[3];
-}
-
-quat::quat(const quat &q)
-{
-    v = q.v;
-    s = q.s;
-}
-
-void quat::set(const vec3 &_v, const float _s)
-{
-    v = _v;
-    s = _s;
-}
-
-quat &quat::operator=(const quat &q)
-{ 
-    v = q.v;  
-    s = q.s; 
-    return *this; 
-}
-
-/******** quat friends ************/
-
-quat operator + (const quat &a, const quat &b)
-{
-    return quat( a.s+b.s, a.v+b.v );
-}
-
-quat operator - (const quat &a, const quat &b)
-{
-    return quat( a.s-b.s, a.v-b.v );
-}
-
-quat operator - (const quat &a )
-{
-    return quat( -a.s, -a.v );
-}
-
-quat operator * ( const quat &a, const quat &b)
-{
-    return quat( a.s*b.s - a.v*b.v, a.s*b.v + b.s*a.v + (a.v^b.v) );
-}
-
-quat operator * ( const quat &a, const float t)
-{
-    return quat( a.v * t, a.s * t );
-}
-
-quat operator * ( const float t, const quat &a )
-{
-    return quat( a.v * t, a.s * t );
-}
-
-mat4 quat::to_mat4() const
-{
-    float xs, ys, zs, wx, wy, wz, xx, xy, xz, yy, yz, zz;
-
-    float t  = 2.0f / (v*v + s*s);
-
-    xs = v[VX]*t;   ys = v[VY]*t;   zs = v[VZ]*t;
-    wx = s*xs;      wy = s*ys;      wz = s*zs;
-    xx = v[VX]*xs;  xy = v[VX]*ys;  xz = v[VX]*zs;
-    yy = v[VY]*ys;  yz = v[VY]*zs;  zz = v[VZ]*zs;
-
-    mat4 matrix( 
-           1.0f-(yy+zz), xy+wz,        xz-wy,        0.0f,
-           xy-wz,        1.0f-(xx+zz), yz+wx,        0.0f,
-           xz+wy,        yz-wx,        1.0f-(xx+yy), 0.0f,
-           0.0f,         0.0f,         0.0f,         1.0f );
-
-    return matrix;
-}
-
-/************************************************* quat_identity() *****/
-/* Returns quaternion identity element                                 */
-
-quat quat_identity() 
-{
-    return quat( vec3( 0.0, 0.0, 0.0 ), 1.0 );
-}
-
-/************************************************ quat_slerp() ********/
-/* Quaternion spherical interpolation                                 */
-
-quat quat_slerp(const quat &from, const quat &to, float t)
-{
-    quat to1;
-    float omega, cosom, sinom, scale0, scale1;
-
-    /* calculate cosine */
-    cosom = from.v * to.v + from.s + to.s;
-
-    /* Adjust signs (if necessary) */
-    if ( cosom < 0.0 ) 
-    {
-        cosom = -cosom;
-        to1 = -to;
-    }
-    else
-    {
-        to1 = to;
-    }
-
-    /* Calculate coefficients */
-    if ((1.0 - cosom) > FUDGE ) 
-    {
-        /* standard case (slerp) */
-        omega =  (float) acos( cosom );
-        sinom =  (float) sin( omega );
-        scale0 = (float) sin((1.0 - t) * omega) / sinom;
-        scale1 = (float) sin(t * omega) / sinom;
-    }
-    else 
-    {
-        /* 'from' and 'to' are very close - just do linear interpolation */
-        scale0 = 1.0f - t;
-        scale1 = t;      
-    }
-
-    return scale0 * from + scale1 * to1;
-}
-
-/********************************************** set_angle() ************/
-/* set rot angle (degrees)                                             */
-
-void quat::set_angle(float f)
-{
-    vec3 axis = get_axis();
-
-    static const double halfradians=acos(-1.0)/360.0;
-    f *= halfradians;
-    
-    s = (float) cos( f );
-
-    v = axis * (float) sin( f );
-}
-
-/********************************************** scale_angle() ************/
-/* scale rot angle (degrees)                                             */
-
-void quat::scale_angle(float f)
-{
-    set_angle( f * get_angle() );
-}
-
-/********************************************** get_angle() ************/
-/* get rot angle (degrees).  Assumes s is between -1 and 1             */
-
-float quat::get_angle() const
-{
-    static const double degrees2=360.0/acos(-1.0);
-    return (float) (acos( s ) * degrees2);
-}
-
-/********************************************* get_axis() **************/
-
-vec3 quat::get_axis() const
-{
-    float scale = (float) sin( acos( s ) );
-
-    if ( scale < FUDGE && scale > -FUDGE )
-        return vec3( 0.0, 0.0, 0.0 );
-    else
-        return  v / scale;
-}
-
-/******************************************* quat::print() ************/
-
-void quat::print(FILE *dest, const char *name) const
-{
-    fprintf( dest, "%s:   v:<%3.2f %3.2f %3.2f>  s:%3.2f\n", 
-        name, v[0], v[1], v[2], s );
-}   

Modified: trunk/Build/source/utils/asymptote/revision.cc
===================================================================
--- trunk/Build/source/utils/asymptote/revision.cc	2020-03-03 22:33:26 UTC (rev 54033)
+++ trunk/Build/source/utils/asymptote/revision.cc	2020-03-03 22:35:09 UTC (rev 54034)
@@ -1,2 +1,2 @@
-const char *REVISION="2.62";
+const char *REVISION="2.63";
 const char *AsyGLVersion="1.00";

Modified: trunk/Build/source/utils/asymptote/runarray.cc
===================================================================
--- trunk/Build/source/utils/asymptote/runarray.cc	2020-03-03 22:33:26 UTC (rev 54033)
+++ trunk/Build/source/utils/asymptote/runarray.cc	2020-03-03 22:35:09 UTC (rev 54034)
@@ -61,7 +61,7 @@
 
 #define CURRENTPEN processData().currentpen
 

-#line 21 "runarray.in"
+#line 22 "runarray.in"
 #include "array.h"
 #include "arrayop.h"
 #include "triple.h"
@@ -71,6 +71,10 @@
 
 #ifdef HAVE_LIBFFTW3
 #include "fftw++.h"
+static const char *rectangular="matrix must be rectangular";
+#else
+static const char *installFFTW=
+  "Please install fftw3, run ./configure, and recompile";
 #endif
 
 using namespace camp;
@@ -87,6 +91,7 @@
 typedef array realarray2;
 typedef array pairarray;
 typedef array pairarray2;
+typedef array pairarray3;
 typedef array triplearray2;
 
 using types::booleanArray;
@@ -96,6 +101,7 @@
 using types::realArray2;
 using types::pairArray;
 using types::pairArray2;
+using types::pairArray3;
 using types::tripleArray2;
 
 typedef callable callableReal;
@@ -155,6 +161,7 @@
 static const char *incommensurate="Incommensurate matrices";
 static const char *singular="Singular matrix";
 static const char *invalidarraylength="Invalid array length: ";
+
 static size_t *pivot,*Row,*Col;
 
 bound_double *bounddouble(int N)
@@ -633,10 +640,10 @@
 #endif
 namespace run {
 // Create an empty array.
-#line 586 "runarray.in"
+#line 594 "runarray.in"
 void emptyArray(stack *Stack)
 {
-#line 587 "runarray.in"
+#line 595 "runarray.in"
   {Stack->push<array*>(new array(0)); return;}
 }
 
@@ -645,11 +652,11 @@
 // is popped off the stack, followed by each dimension in reverse order.
 // The array itself is technically a one dimensional array of one
 // dimension arrays and so on.
-#line 596 "runarray.in"
+#line 604 "runarray.in"
 void newDeepArray(stack *Stack)
 {
   Int depth=vm::pop<Int>(Stack);
-#line 597 "runarray.in"
+#line 605 "runarray.in"
   assert(depth > 0);
 
   Int *dims = new Int[depth];
@@ -668,11 +675,11 @@
 // Creates an array with elements already specified.  First, the number
 // of elements is popped off the stack, followed by each element in
 // reverse order.
-#line 616 "runarray.in"
+#line 624 "runarray.in"
 void newInitializedArray(stack *Stack)
 {
   Int n=vm::pop<Int>(Stack);
-#line 617 "runarray.in"
+#line 625 "runarray.in"
   assert(n >= 0);
 
   array *a = new array(n);
@@ -685,12 +692,12 @@
 
 // Similar to newInitializedArray, but after the n elements, append another
 // array to it.
-#line 630 "runarray.in"
+#line 638 "runarray.in"
 void newAppendedArray(stack *Stack)
 {
   Int n=vm::pop<Int>(Stack);
   array* tail=vm::pop<array*>(Stack);
-#line 631 "runarray.in"
+#line 639 "runarray.in"
   assert(n >= 0);
 
   array *a = new array(n);
@@ -707,7 +714,7 @@
 // typeDepth is the true depth of the array determined at compile-time when the
 // operations for the array type are added.  This typeDepth argument is
 // automatically pushed on the stack and is not visible to the user.
-#line 648 "runarray.in"
+#line 656 "runarray.in"
 void copyArrayValue(stack *Stack)
 {
   Int typeDepth=vm::pop<Int>(Stack);
@@ -714,7 +721,7 @@
   Int depth=vm::pop<Int>(Stack,Int_MAX);
   item value=vm::pop(Stack);
   Int n=vm::pop<Int>(Stack);
-#line 649 "runarray.in"
+#line 657 "runarray.in"
   if(n < 0) error("cannot create a negative length array");
   if(depth < 0) error("cannot copy to a negative depth");
   if(depth > typeDepth) depth=typeDepth;
@@ -725,13 +732,13 @@
 // typeDepth is the true depth of the array determined at compile-time when the
 // operations for the array type are added.  This typeDepth argument is
 // automatically pushed on the stack and is not visible to the user.
-#line 660 "runarray.in"
+#line 668 "runarray.in"
 void copyArray(stack *Stack)
 {
   Int typeDepth=vm::pop<Int>(Stack);
   Int depth=vm::pop<Int>(Stack,Int_MAX);
   array * a=vm::pop<array *>(Stack);
-#line 661 "runarray.in"
+#line 669 "runarray.in"
   if(depth < 0) error("cannot copy to a negative depth");
   if(depth > typeDepth) depth=typeDepth;
   {Stack->push<array*>(a->copyToDepth(depth)); return;}
@@ -738,12 +745,12 @@
 }
 
 // Read an element from an array. Checks for initialization & bounds.
-#line 668 "runarray.in"
+#line 676 "runarray.in"
 void arrayRead(stack *Stack)
 {
   Int n=vm::pop<Int>(Stack);
   array * a=vm::pop<array *>(Stack);
-#line 669 "runarray.in"
+#line 677 "runarray.in"
   item& i=arrayRead(a,n);
   if (i.empty()) {
     ostringstream buf;
@@ -754,13 +761,13 @@
 }
 
 // Slice a substring from an array.
-#line 680 "runarray.in"
+#line 688 "runarray.in"
 void arraySliceRead(stack *Stack)
 {
   Int right=vm::pop<Int>(Stack);
   Int left=vm::pop<Int>(Stack);
   array * a=vm::pop<array *>(Stack);
-#line 681 "runarray.in"
+#line 689 "runarray.in"
   checkArray(a);
   {Stack->push(a->slice(left, right)); return;}
 }
@@ -767,12 +774,12 @@
 
 // Slice a substring from an array.  This implements the cases a[i:] and a[:]
 // where the endpoint is not given, and assumed to be the length of the array.
-#line 688 "runarray.in"
+#line 696 "runarray.in"
 void arraySliceReadToEnd(stack *Stack)
 {
   Int left=vm::pop<Int>(Stack);
   array * a=vm::pop<array *>(Stack);
-#line 689 "runarray.in"
+#line 697 "runarray.in"
   size_t len=checkArray(a);
   {Stack->push(a->slice(left, (Int)len)); return;}
 }
@@ -779,12 +786,12 @@
 
 // Read an element from an array of arrays. Check bounds and initialize
 // as necessary.
-#line 696 "runarray.in"
+#line 704 "runarray.in"
 void arrayArrayRead(stack *Stack)
 {
   Int n=vm::pop<Int>(Stack);
   array * a=vm::pop<array *>(Stack);
-#line 697 "runarray.in"
+#line 705 "runarray.in"
   item& i=arrayRead(a,n);
   if (i.empty()) i=new array(0);
   {Stack->push(i); return;}
@@ -792,13 +799,13 @@
 
 // Write an element to an array.  Increase size if necessary.
 // TODO: Add arrayWriteAndPop
-#line 705 "runarray.in"
+#line 713 "runarray.in"
 void arrayWrite(stack *Stack)
 {
   item value=vm::pop(Stack);
   Int n=vm::pop<Int>(Stack);
   array * a=vm::pop<array *>(Stack);
-#line 706 "runarray.in"
+#line 714 "runarray.in"
   size_t len=checkArray(a);
   bool cyclic=a->cyclic();
   if(cyclic && len > 0) n=imod(n,len);
@@ -812,7 +819,7 @@
   {Stack->push(value); return;}
 }
 
-#line 720 "runarray.in"
+#line 728 "runarray.in"
 void arraySliceWrite(stack *Stack)
 {
   array * src=vm::pop<array *>(Stack);
@@ -819,7 +826,7 @@
   Int right=vm::pop<Int>(Stack);
   Int left=vm::pop<Int>(Stack);
   array * dest=vm::pop<array *>(Stack);
-#line 721 "runarray.in"
+#line 729 "runarray.in"
   checkArray(src);
   checkArray(dest);
   dest->setSlice(left, right, src);
@@ -826,13 +833,13 @@
   {Stack->push<array*>(src); return;}
 }
 
-#line 728 "runarray.in"
+#line 736 "runarray.in"
 void arraySliceWriteToEnd(stack *Stack)
 {
   array * src=vm::pop<array *>(Stack);
   Int left=vm::pop<Int>(Stack);
   array * dest=vm::pop<array *>(Stack);
-#line 729 "runarray.in"
+#line 737 "runarray.in"
   checkArray(src);
   size_t len=checkArray(dest);
   dest->setSlice(left, (Int) len, src);
@@ -840,20 +847,20 @@
 }
 
 // Returns the length of an array.
-#line 737 "runarray.in"
+#line 745 "runarray.in"
 void arrayLength(stack *Stack)
 {
   array * a=vm::pop<array *>(Stack);
-#line 738 "runarray.in"
+#line 746 "runarray.in"
   {Stack->push<Int>((Int) checkArray(a)); return;}
 }
 
 // Returns an array of integers representing the keys of the array.
-#line 743 "runarray.in"
+#line 751 "runarray.in"
 void arrayKeys(stack *Stack)
 {
   array * a=vm::pop<array *>(Stack);
-#line 744 "runarray.in"
+#line 752 "runarray.in"
   size_t size=checkArray(a);
 
   array *keys=new array();
@@ -867,21 +874,21 @@
 }
 
 // Return the cyclic flag for an array.
-#line 758 "runarray.in"
+#line 766 "runarray.in"
 void arrayCyclicFlag(stack *Stack)
 {
   array * a=vm::pop<array *>(Stack);
-#line 759 "runarray.in"
+#line 767 "runarray.in"
   checkArray(a);
   {Stack->push<bool>(a->cyclic()); return;}
 }
 
-#line 764 "runarray.in"
+#line 772 "runarray.in"
 void arraySetCyclicFlag(stack *Stack)
 {
   array * a=vm::pop<array *>(Stack);
   bool b=vm::pop<bool>(Stack);
-#line 765 "runarray.in"
+#line 773 "runarray.in"
   checkArray(a);
   a->cyclic(b);
   {Stack->push<bool>(b); return;}
@@ -888,12 +895,12 @@
 }
 
 // Check to see if an array element is initialized.
-#line 772 "runarray.in"
+#line 780 "runarray.in"
 void arrayInitializedHelper(stack *Stack)
 {
   array * a=vm::pop<array *>(Stack);
   Int n=vm::pop<Int>(Stack);
-#line 773 "runarray.in"
+#line 781 "runarray.in"
   size_t len=checkArray(a);
   bool cyclic=a->cyclic();
   if(cyclic && len > 0) n=imod(n,len);
@@ -903,41 +910,41 @@
 }
 
 // Returns the initialize method for an array.
-#line 783 "runarray.in"
+#line 791 "runarray.in"
 void arrayInitialized(stack *Stack)
 {
   array * a=vm::pop<array *>(Stack);
-#line 784 "runarray.in"
+#line 792 "runarray.in"
   {Stack->push<callable*>(new thunk(new bfunc(arrayInitializedHelper),a)); return;}
 }
 
 // The helper function for the cyclic method that sets the cyclic flag.
-#line 789 "runarray.in"
+#line 797 "runarray.in"
 void arrayCyclicHelper(stack *Stack)
 {
   array * a=vm::pop<array *>(Stack);
   bool b=vm::pop<bool>(Stack);
-#line 790 "runarray.in"
+#line 798 "runarray.in"
   checkArray(a);
   a->cyclic(b);
 }
 
 // Set the cyclic flag for an array.
-#line 796 "runarray.in"
+#line 804 "runarray.in"
 void arrayCyclic(stack *Stack)
 {
   array * a=vm::pop<array *>(Stack);
-#line 797 "runarray.in"
+#line 805 "runarray.in"
   {Stack->push<callable*>(new thunk(new bfunc(arrayCyclicHelper),a)); return;}
 }
 
 // The helper function for the push method that does the actual operation.
-#line 802 "runarray.in"
+#line 810 "runarray.in"
 void arrayPushHelper(stack *Stack)
 {
   array * a=vm::pop<array *>(Stack);
   item x=vm::pop(Stack);
-#line 803 "runarray.in"
+#line 811 "runarray.in"
   checkArray(a);
   a->push(x);
   {Stack->push(x); return;}
@@ -944,21 +951,21 @@
 }
 
 // Returns the push method for an array.
-#line 810 "runarray.in"
+#line 818 "runarray.in"
 void arrayPush(stack *Stack)
 {
   array * a=vm::pop<array *>(Stack);
-#line 811 "runarray.in"
+#line 819 "runarray.in"
   {Stack->push<callable*>(new thunk(new bfunc(arrayPushHelper),a)); return;}
 }
 
 // The helper function for the append method that appends b to a.
-#line 816 "runarray.in"
+#line 824 "runarray.in"
 void arrayAppendHelper(stack *Stack)
 {
   array * a=vm::pop<array *>(Stack);
   array * b=vm::pop<array *>(Stack);
-#line 817 "runarray.in"
+#line 825 "runarray.in"
   checkArray(a);
   size_t size=checkArray(b);
   for(size_t i=0; i < size; i++)
@@ -966,20 +973,20 @@
 }
 
 // Returns the append method for an array.
-#line 825 "runarray.in"
+#line 833 "runarray.in"
 void arrayAppend(stack *Stack)
 {
   array * a=vm::pop<array *>(Stack);
-#line 826 "runarray.in"
+#line 834 "runarray.in"
   {Stack->push<callable*>(new thunk(new bfunc(arrayAppendHelper),a)); return;}
 }
 
 // The helper function for the pop method.
-#line 831 "runarray.in"
+#line 839 "runarray.in"
 void arrayPopHelper(stack *Stack)
 {
   array * a=vm::pop<array *>(Stack);
-#line 832 "runarray.in"
+#line 840 "runarray.in"
   size_t asize=checkArray(a);
   if(asize == 0) 
     error("cannot pop element from empty array");
@@ -987,22 +994,22 @@
 }
 
 // Returns the pop method for an array.
-#line 840 "runarray.in"
+#line 848 "runarray.in"
 void arrayPop(stack *Stack)
 {
   array * a=vm::pop<array *>(Stack);
-#line 841 "runarray.in"
+#line 849 "runarray.in"
   {Stack->push<callable*>(new thunk(new bfunc(arrayPopHelper),a)); return;}
 }
 
 // The helper function for the insert method.
-#line 846 "runarray.in"
+#line 854 "runarray.in"
 void arrayInsertHelper(stack *Stack)
 {
   array * a=vm::pop<array *>(Stack);
   array * x=vm::pop<array *>(Stack);
   Int i=vm::pop<Int>(Stack);
-#line 847 "runarray.in"
+#line 855 "runarray.in"
   size_t asize=checkArray(a);
   checkArray(x);
   if(a->cyclic() && asize > 0) i=imod(i,asize);
@@ -1012,39 +1019,39 @@
 }
 
 // Returns the insert method for an array.
-#line 857 "runarray.in"
+#line 865 "runarray.in"
 void arrayInsert(stack *Stack)
 {
   array * a=vm::pop<array *>(Stack);
-#line 858 "runarray.in"
+#line 866 "runarray.in"
   {Stack->push<callable*>(new thunk(new bfunc(arrayInsertHelper),a)); return;}
 }
 
 // Returns the delete method for an array.
-#line 863 "runarray.in"
+#line 871 "runarray.in"
 void arrayDelete(stack *Stack)
 {
   array * a=vm::pop<array *>(Stack);
-#line 864 "runarray.in"
+#line 872 "runarray.in"
   {Stack->push<callable*>(new thunk(new bfunc(arrayDeleteHelper),a)); return;}
 }
 
-#line 868 "runarray.in"
+#line 876 "runarray.in"
 void arrayAlias(stack *Stack)
 {
   array * b=vm::pop<array *>(Stack);
   array * a=vm::pop<array *>(Stack);
-#line 869 "runarray.in"
+#line 877 "runarray.in"
   {Stack->push<bool>(a==b); return;}
 }
 
 // Return array formed by indexing array a with elements of integer array b
-#line 874 "runarray.in"
+#line 882 "runarray.in"
 void arrayIntArray(stack *Stack)
 {
   array * b=vm::pop<array *>(Stack);
   array * a=vm::pop<array *>(Stack);
-#line 875 "runarray.in"
+#line 883 "runarray.in"
   size_t asize=checkArray(a);
   size_t bsize=checkArray(b);
   array *r=new array(bsize);
@@ -1062,13 +1069,13 @@
 
 // returns the complement of the integer array a in {0,2,...,n-1},
 // so that b[complement(a,b.length)] yields the complement of b[a].
-#line 893 "runarray.in"
+#line 901 "runarray.in"
 // Intarray* complement(Intarray *a, Int n);
 void gen_runarray32(stack *Stack)
 {
   Int n=vm::pop<Int>(Stack);
   Intarray * a=vm::pop<Intarray *>(Stack);
-#line 894 "runarray.in"
+#line 902 "runarray.in"
   size_t asize=checkArray(a);
   array *r=new array(0);
   bool *keep=new bool[n];
@@ -1085,12 +1092,12 @@
 }
 
 // Generate the sequence {f(i) : i=0,1,...n-1} given a function f and integer n
-#line 911 "runarray.in"
+#line 919 "runarray.in"
 void arraySequence(stack *Stack)
 {
   Int n=vm::pop<Int>(Stack);
   callable * f=vm::pop<callable *>(Stack);
-#line 912 "runarray.in"
+#line 920 "runarray.in"
   if(n < 0) n=0;
   array *a=new array(n);
   for(Int i=0; i < n; ++i) {
@@ -1102,12 +1109,12 @@
 }
 
 // Return the array {0,1,...n-1}
-#line 924 "runarray.in"
+#line 932 "runarray.in"
 // Intarray* sequence(Int n);
 void gen_runarray34(stack *Stack)
 {
   Int n=vm::pop<Int>(Stack);
-#line 925 "runarray.in"
+#line 933 "runarray.in"
   if(n < 0) n=0;
   array *a=new array(n);
   for(Int i=0; i < n; ++i) {
@@ -1117,12 +1124,12 @@
 }
 
 // Apply a function to each element of an array
-#line 935 "runarray.in"
+#line 943 "runarray.in"
 void arrayFunction(stack *Stack)
 {
   array * a=vm::pop<array *>(Stack);
   callable * f=vm::pop<callable *>(Stack);
-#line 936 "runarray.in"
+#line 944 "runarray.in"
   size_t size=checkArray(a);
   array *b=new array(size);
   for(size_t i=0; i < size; ++i) {
@@ -1133,13 +1140,13 @@
   {Stack->push<array*>(b); return;}
 }
 
-#line 947 "runarray.in"
+#line 955 "runarray.in"
 void arraySort(stack *Stack)
 {
   bool stable=vm::pop<bool>(Stack,true);
   callable * less=vm::pop<callable *>(Stack);
   array * a=vm::pop<array *>(Stack);
-#line 948 "runarray.in"
+#line 956 "runarray.in"
   array *c=copyArray(a);
   compareFunc=less;
   FuncStack=Stack;
@@ -1148,13 +1155,13 @@
   {Stack->push<array*>(c); return;}
 }
 
-#line 957 "runarray.in"
+#line 965 "runarray.in"
 void arraySearch(stack *Stack)
 {
   callable * less=vm::pop<callable *>(Stack);
   item key=vm::pop(Stack);
   array * a=vm::pop<array *>(Stack);
-#line 958 "runarray.in"
+#line 966 "runarray.in"
   size_t size=a->size();
   compareFunc=less;
   FuncStack=Stack;
@@ -1172,12 +1179,12 @@
   {Stack->push<Int>(0); return;}
 }
 
-#line 976 "runarray.in"
+#line 984 "runarray.in"
 // bool all(boolarray *a);
 void gen_runarray38(stack *Stack)
 {
   boolarray * a=vm::pop<boolarray *>(Stack);
-#line 977 "runarray.in"
+#line 985 "runarray.in"
   size_t size=checkArray(a);
   bool c=true;
   for(size_t i=0; i < size; i++)
@@ -1185,12 +1192,12 @@
   {Stack->push<bool>(c); return;}
 }
 
-#line 985 "runarray.in"
+#line 993 "runarray.in"
 // boolarray* !(boolarray* a);
 void gen_runarray39(stack *Stack)
 {
   boolarray* a=vm::pop<boolarray*>(Stack);
-#line 986 "runarray.in"
+#line 994 "runarray.in"
   size_t size=checkArray(a);
   array *c=new array(size);
   for(size_t i=0; i < size; i++)
@@ -1198,12 +1205,12 @@
   {Stack->push<boolarray*>(c); return;}
 }
 
-#line 994 "runarray.in"
+#line 1002 "runarray.in"
 // Int sum(boolarray *a);
 void gen_runarray40(stack *Stack)
 {
   boolarray * a=vm::pop<boolarray *>(Stack);
-#line 995 "runarray.in"
+#line 1003 "runarray.in"
   size_t size=checkArray(a);
   Int sum=0;
   for(size_t i=0; i < size; i++)
@@ -1211,11 +1218,11 @@
   {Stack->push<Int>(sum); return;}
 }
 
-#line 1003 "runarray.in"
+#line 1011 "runarray.in"
 void arrayConcat(stack *Stack)
 {
   array * a=vm::pop<array *>(Stack);
-#line 1004 "runarray.in"
+#line 1012 "runarray.in"
   // a is an array of arrays to be concatenated together.
   // The signature is
   //   T[] concat(... T[][] a);
@@ -1242,11 +1249,11 @@
   {Stack->push<array*>(result); return;}
 }
 
-#line 1031 "runarray.in"
+#line 1039 "runarray.in"
 void array2Transpose(stack *Stack)
 {
   array * a=vm::pop<array *>(Stack);
-#line 1032 "runarray.in"
+#line 1040 "runarray.in"
   size_t asize=checkArray(a);
   array *c=new array(0);
   for(size_t i=0; i < asize; i++) {
@@ -1273,12 +1280,12 @@
 // permutation  (021 or 120, etc; original is 012).
 // Transpose by sending respective members to the permutated locations:
 // return the array obtained by putting a[i][j][k] into position perm{ijk}. 
-#line 1059 "runarray.in"
+#line 1067 "runarray.in"
 void array3Transpose(stack *Stack)
 {
   array * perm=vm::pop<array *>(Stack);
   array * a=vm::pop<array *>(Stack);
-#line 1060 "runarray.in"
+#line 1068 "runarray.in"
   const size_t DIM=3;
 
   if(checkArray(perm) != DIM) {
@@ -1362,13 +1369,13 @@
 
 // Find the index of the nth true value in a boolean array or -1 if not found.
 // If n is negative, search backwards.
-#line 1144 "runarray.in"
+#line 1152 "runarray.in"
 // Int find(boolarray *a, Int n=1);
 void gen_runarray44(stack *Stack)
 {
   Int n=vm::pop<Int>(Stack,1);
   boolarray * a=vm::pop<boolarray *>(Stack);
-#line 1145 "runarray.in"
+#line 1153 "runarray.in"
   size_t size=checkArray(a);
   Int j=-1;
   if(n > 0)
@@ -1385,12 +1392,12 @@
 }
 
 // Find all indices of true values in a boolean array. 
-#line 1162 "runarray.in"
+#line 1170 "runarray.in"
 // Intarray* findall(boolarray *a);
 void gen_runarray45(stack *Stack)
 {
   boolarray * a=vm::pop<boolarray *>(Stack);
-#line 1163 "runarray.in"
+#line 1171 "runarray.in"
   size_t size=checkArray(a);
   array *b=new array(0);
   for(size_t i=0; i < size; i++) {
@@ -1403,13 +1410,13 @@
 
 // construct vector obtained by replacing those elements of b for which the
 // corresponding elements of a are false by the corresponding element of c.
-#line 1176 "runarray.in"
+#line 1184 "runarray.in"
 void arrayConditional(stack *Stack)
 {
   array * c=vm::pop<array *>(Stack);
   array * b=vm::pop<array *>(Stack);
   array * a=vm::pop<array *>(Stack);
-#line 1177 "runarray.in"
+#line 1185 "runarray.in"
   size_t size=checkArray(a);
   array *r=new array(size);
   if(b && c) {
@@ -1433,22 +1440,22 @@
 }
 
 // Return an n x n identity matrix.
-#line 1201 "runarray.in"
+#line 1209 "runarray.in"
 // realarray2* identity(Int n);
 void gen_runarray47(stack *Stack)
 {
   Int n=vm::pop<Int>(Stack);
-#line 1202 "runarray.in"
+#line 1210 "runarray.in"
   {Stack->push<realarray2*>(Identity(n)); return;}
 }
 
 // Return the inverse of an n x n matrix a using Gauss-Jordan elimination.
-#line 1207 "runarray.in"
+#line 1215 "runarray.in"
 // realarray2* inverse(realarray2 *a);
 void gen_runarray48(stack *Stack)
 {
   realarray2 * a=vm::pop<realarray2 *>(Stack);
-#line 1208 "runarray.in"
+#line 1216 "runarray.in"
   size_t n=checkArray(a);
   double *A;
   copyArray2C(A,a,true,0,NoGC);
@@ -1461,7 +1468,7 @@
 // Solve the linear equation ax=b by LU decomposition, returning the
 // solution x, where a is an n x n matrix and b is an array of length n.
 // If no solution exists, return an empty array.
-#line 1221 "runarray.in"
+#line 1229 "runarray.in"
 // realarray* solve(realarray2 *a, realarray *b, bool warn=true);
 void gen_runarray49(stack *Stack)
 {
@@ -1468,7 +1475,7 @@
   bool warn=vm::pop<bool>(Stack,true);
   realarray * b=vm::pop<realarray *>(Stack);
   realarray2 * a=vm::pop<realarray2 *>(Stack);
-#line 1222 "runarray.in"
+#line 1230 "runarray.in"
   size_t n=checkArray(a);
   
   if(n == 0) {Stack->push<realarray*>(new array(0)); return;}
@@ -1520,7 +1527,7 @@
 // Solve the linear equation ax=b by LU decomposition, returning the
 // solution x, where a is an n x n matrix and b is an n x m matrix.
 // If no solution exists, return an empty array.
-#line 1274 "runarray.in"
+#line 1282 "runarray.in"
 // realarray2* solve(realarray2 *a, realarray2 *b, bool warn=true);
 void gen_runarray50(stack *Stack)
 {
@@ -1527,7 +1534,7 @@
   bool warn=vm::pop<bool>(Stack,true);
   realarray2 * b=vm::pop<realarray2 *>(Stack);
   realarray2 * a=vm::pop<realarray2 *>(Stack);
-#line 1275 "runarray.in"
+#line 1283 "runarray.in"
   size_t n=checkArray(a);
   
   if(n == 0) {Stack->push<realarray2*>(new array(0)); return;}
@@ -1589,12 +1596,12 @@
 }
 
 // Compute the determinant of an n x n matrix.
-#line 1337 "runarray.in"
+#line 1345 "runarray.in"
 // real determinant(realarray2 *a);
 void gen_runarray51(stack *Stack)
 {
   realarray2 * a=vm::pop<realarray2 *>(Stack);
-#line 1338 "runarray.in"
+#line 1346 "runarray.in"
   real *A;
   copyArray2C(A,a);
   size_t n=checkArray(a);
@@ -1609,13 +1616,13 @@
   {Stack->push<real>(det); return;}
 }
 
-#line 1353 "runarray.in"
+#line 1361 "runarray.in"
 // realarray* *(realarray2 *a, realarray *b);
 void gen_runarray52(stack *Stack)
 {
   realarray * b=vm::pop<realarray *>(Stack);
   realarray2 * a=vm::pop<realarray2 *>(Stack);
-#line 1354 "runarray.in"
+#line 1362 "runarray.in"
   size_t n=checkArray(a);
   size_t m=checkArray(b);
   array *c=new array(n);
@@ -1633,13 +1640,13 @@
   {Stack->push<realarray*>(c); return;}
 }
 
-#line 1372 "runarray.in"
+#line 1380 "runarray.in"
 // realarray* *(realarray *a, realarray2 *b);
 void gen_runarray53(stack *Stack)
 {
   realarray2 * b=vm::pop<realarray2 *>(Stack);
   realarray * a=vm::pop<realarray *>(Stack);
-#line 1373 "runarray.in"
+#line 1381 "runarray.in"
   size_t n=checkArray(a);
   if(n != checkArray(b)) error(incommensurate);
   real *A;
@@ -1667,62 +1674,62 @@
   {Stack->push<realarray*>(c); return;}
 }
 
-#line 1401 "runarray.in"
+#line 1409 "runarray.in"
 // Intarray2* *(Intarray2 *a, Intarray2 *b);
 void gen_runarray54(stack *Stack)
 {
   Intarray2 * b=vm::pop<Intarray2 *>(Stack);
   Intarray2 * a=vm::pop<Intarray2 *>(Stack);
-#line 1402 "runarray.in"
+#line 1410 "runarray.in"
   {Stack->push<Intarray2*>(mult<Int>(a,b)); return;}
 }
 
-#line 1406 "runarray.in"
+#line 1414 "runarray.in"
 // realarray2* *(realarray2 *a, realarray2 *b);
 void gen_runarray55(stack *Stack)
 {
   realarray2 * b=vm::pop<realarray2 *>(Stack);
   realarray2 * a=vm::pop<realarray2 *>(Stack);
-#line 1407 "runarray.in"
+#line 1415 "runarray.in"
   {Stack->push<realarray2*>(mult<real>(a,b)); return;}
 }
 
-#line 1411 "runarray.in"
+#line 1419 "runarray.in"
 // pairarray2* *(pairarray2 *a, pairarray2 *b);
 void gen_runarray56(stack *Stack)
 {
   pairarray2 * b=vm::pop<pairarray2 *>(Stack);
   pairarray2 * a=vm::pop<pairarray2 *>(Stack);
-#line 1412 "runarray.in"
+#line 1420 "runarray.in"
   {Stack->push<pairarray2*>(mult<pair>(a,b)); return;}
 }
 
-#line 1416 "runarray.in"
+#line 1424 "runarray.in"
 // triple *(realarray2 *t, triple v);
 void gen_runarray57(stack *Stack)
 {
   triple v=vm::pop<triple>(Stack);
   realarray2 * t=vm::pop<realarray2 *>(Stack);
-#line 1417 "runarray.in"
+#line 1425 "runarray.in"
   {Stack->push<triple>(*t*v); return;}
 }
 
-#line 1421 "runarray.in"
+#line 1429 "runarray.in"
 // realarray2* AtA(realarray2 *a);
 void gen_runarray58(stack *Stack)
 {
   realarray2 * a=vm::pop<realarray2 *>(Stack);
-#line 1422 "runarray.in"
+#line 1430 "runarray.in"
   {Stack->push<realarray2*>(AtA<real>(a)); return;}
 }
 
-#line 1426 "runarray.in"
+#line 1434 "runarray.in"
 // pair project(triple v, realarray2 *t);
 void gen_runarray59(stack *Stack)
 {
   realarray2 * t=vm::pop<realarray2 *>(Stack);
   triple v=vm::pop<triple>(Stack);
-#line 1427 "runarray.in"
+#line 1435 "runarray.in"
   size_t n=checkArray(t);
   if(n != 4) error(incommensurate);
   array *t0=read<array*>(t,0);
@@ -1747,13 +1754,13 @@
 }
 
 // Compute the dot product of vectors a and b.
-#line 1452 "runarray.in"
+#line 1460 "runarray.in"
 // real dot(realarray *a, realarray *b);
 void gen_runarray60(stack *Stack)
 {
   realarray * b=vm::pop<realarray *>(Stack);
   realarray * a=vm::pop<realarray *>(Stack);
-#line 1453 "runarray.in"
+#line 1461 "runarray.in"
   size_t n=checkArrays(a,b);
   real sum=0.0;
   for(size_t i=0; i < n; ++i)
@@ -1762,13 +1769,13 @@
 }
 
 // Compute the complex dot product of vectors a and b.
-#line 1462 "runarray.in"
+#line 1470 "runarray.in"
 // pair dot(pairarray *a, pairarray *b);
 void gen_runarray61(stack *Stack)
 {
   pairarray * b=vm::pop<pairarray *>(Stack);
   pairarray * a=vm::pop<pairarray *>(Stack);
-#line 1463 "runarray.in"
+#line 1471 "runarray.in"
   size_t n=checkArrays(a,b);
   pair sum=zero;
   for(size_t i=0; i < n; ++i)
@@ -1783,7 +1790,7 @@
 // [      a[2] b[2] c[2]        ]
 // [                ...         ]
 // [ c[n-1]       a[n-1] b[n-1] ]
-#line 1478 "runarray.in"
+#line 1486 "runarray.in"
 // realarray* tridiagonal(realarray *a, realarray *b, realarray *c, realarray *f);
 void gen_runarray62(stack *Stack)
 {
@@ -1791,7 +1798,7 @@
   realarray * c=vm::pop<realarray *>(Stack);
   realarray * b=vm::pop<realarray *>(Stack);
   realarray * a=vm::pop<realarray *>(Stack);
-#line 1479 "runarray.in"
+#line 1487 "runarray.in"
   size_t n=checkArrays(a,b);
   checkEqual(n,checkArray(c));
   checkEqual(n,checkArray(f));
@@ -1888,7 +1895,7 @@
 }
 
 // Root solve by Newton-Raphson
-#line 1576 "runarray.in"
+#line 1584 "runarray.in"
 // real newton(Int iterations=100, callableReal *f, callableReal *fprime, real x,            bool verbose=false);
 void gen_runarray63(stack *Stack)
 {
@@ -1897,7 +1904,7 @@
   callableReal * fprime=vm::pop<callableReal *>(Stack);
   callableReal * f=vm::pop<callableReal *>(Stack);
   Int iterations=vm::pop<Int>(Stack,100);
-#line 1578 "runarray.in"
+#line 1586 "runarray.in"
   static const real fuzz=1000.0*DBL_EPSILON;
   Int i=0;
   size_t oldPrec=0;
@@ -1943,7 +1950,7 @@
 
 // Root solve by Newton-Raphson bisection
 // cf. routine rtsafe (Press et al.,  Numerical Recipes, 1991).
-#line 1624 "runarray.in"
+#line 1632 "runarray.in"
 // real newton(Int iterations=100, callableReal *f, callableReal *fprime, real x1,            real x2, bool verbose=false);
 void gen_runarray64(stack *Stack)
 {
@@ -1953,7 +1960,7 @@
   callableReal * fprime=vm::pop<callableReal *>(Stack);
   callableReal * f=vm::pop<callableReal *>(Stack);
   Int iterations=vm::pop<Int>(Stack,100);
-#line 1626 "runarray.in"
+#line 1634 "runarray.in"
   static const real fuzz=1000.0*DBL_EPSILON;
   size_t oldPrec=0;
   if(verbose) 
@@ -2039,7 +2046,7 @@
 // In this implementation, the binary search is interleaved
 // with a modified version of quadratic interpolation.
 // This is a C++ port of the Asymptote routine written by Charles Staats III.
-#line 1712 "runarray.in"
+#line 1720 "runarray.in"
 // real _findroot(callableReal *f, real a, real b, real tolerance,               real fa, real fb);
 void gen_runarray65(stack *Stack)
 {
@@ -2049,7 +2056,7 @@
   real b=vm::pop<real>(Stack);
   real a=vm::pop<real>(Stack);
   callableReal * f=vm::pop<callableReal *>(Stack);
-#line 1714 "runarray.in"
+#line 1722 "runarray.in"
   if(fa == 0.0) {Stack->push<real>(a); return;}
   if(fb == 0.0) {Stack->push<real>(b); return;}
   
@@ -2141,7 +2148,7 @@
   {Stack->push<real>(a-(b-a)/(fb-fa)*fa); return;}
 }
 
-#line 1806 "runarray.in"
+#line 1814 "runarray.in"
 // real simpson(callableReal *f, real a, real b, real acc=DBL_EPSILON,             real dxmax=0);
 void gen_runarray66(stack *Stack)
 {
@@ -2150,7 +2157,7 @@
   real b=vm::pop<real>(Stack);
   real a=vm::pop<real>(Stack);
   callableReal * f=vm::pop<callableReal *>(Stack);
-#line 1808 "runarray.in"
+#line 1816 "runarray.in"
   real integral;
   if(dxmax <= 0) dxmax=fabs(b-a);
   callable *oldFunc=Func;
@@ -2163,13 +2170,13 @@
 }
 
 // Compute the fast Fourier transform of a pair array
-#line 1821 "runarray.in"
+#line 1829 "runarray.in"
 // pairarray* fft(pairarray *a, Int sign=1);
 void gen_runarray67(stack *Stack)
 {
   Int sign=vm::pop<Int>(Stack,1);
   pairarray * a=vm::pop<pairarray *>(Stack);
-#line 1822 "runarray.in"
+#line 1830 "runarray.in"
 #ifdef HAVE_LIBFFTW3
   unsigned n=(unsigned) checkArray(a);
   array *c=new array(n);
@@ -2193,17 +2200,132 @@
   unused(a);
   unused(&sign);
   array *c=new array(0);
-  error("Please install fftw3, run ./configure, and recompile");
+  error(installFFTW);
 #endif //  HAVE_LIBFFTW3
   {Stack->push<pairarray*>(c); return;}
 }
 
-#line 1851 "runarray.in"
-// Intarray2* triangulate(pairarray *z);
+// Compute the fast Fourier transform of a 2D pair array
+#line 1860 "runarray.in"
+// pairarray2* fft(pairarray2 *a, Int sign=1);
 void gen_runarray68(stack *Stack)
 {
+  Int sign=vm::pop<Int>(Stack,1);
+  pairarray2 * a=vm::pop<pairarray2 *>(Stack);
+#line 1861 "runarray.in"
+#ifdef HAVE_LIBFFTW3
+  size_t n=checkArray(a);
+  size_t m=n == 0 ? 0 : checkArray(read<array*>(a,0));
+
+  array *c=new array(n);
+  Complex *f=utils::ComplexAlign(n*m);
+  fftwpp::fft2d Forward(n,m,intcast(sign),f);
+
+  if(n) {
+    for(size_t i=0; i < n; ++i) {
+      array *ai=read<array *>(a,i);
+      size_t aisize=checkArray(ai);
+      if(aisize != m) error(rectangular);
+      Complex *fi=f+m*i;
+      for(size_t j=0; j < m; ++j) {
+        pair z=read<pair>(ai,j);
+        fi[j]=Complex(z.getx(),z.gety());
+      }
+    }
+
+    Forward.fft(f);
+
+    for(size_t i=0; i < n; ++i) {
+      array *ci=new array(m);
+      (*c)[i]=ci;
+      Complex *fi=f+m*i;
+      for(size_t j=0; j < m; ++j) {
+        Complex z=fi[j];
+        (*ci)[j]=pair(z.real(),z.imag());
+      }
+    }
+
+    utils::deleteAlign(f);
+  }
+#else
+  unused(a);
+  unused(&sign);
+  array *c=new array(0);
+  error(installFFTW);
+#endif //  HAVE_LIBFFTW3
+  {Stack->push<pairarray2*>(c); return;}
+}
+
+// Compute the fast Fourier transform of a 3D pair array
+#line 1906 "runarray.in"
+// pairarray3* fft(pairarray3 *a, Int sign=1);
+void gen_runarray69(stack *Stack)
+{
+  Int sign=vm::pop<Int>(Stack,1);
+  pairarray3 * a=vm::pop<pairarray3 *>(Stack);
+#line 1907 "runarray.in"
+#ifdef HAVE_LIBFFTW3
+  size_t n=checkArray(a);
+  array *a0=read<array*>(a,0);
+  size_t m=n == 0 ? 0 : checkArray(a0);
+  size_t l=m == 0 ? 0 : checkArray(read<array*>(a0,0));
+
+  array *c=new array(n);
+  Complex *f=utils::ComplexAlign(n*m*l);
+  fftwpp::fft3d Forward(n,m,l,intcast(sign),f);
+
+  if(n) {
+    for(size_t i=0; i < n; ++i) {
+      array *ai=read<array *>(a,i);
+      size_t aisize=checkArray(ai);
+      if(aisize != m) error(rectangular);
+      Complex *fi=f+m*l*i;
+      for(size_t j=0; j < m; ++j) {
+        array *aij=read<array *>(ai,j);
+        size_t aijsize=checkArray(aij);
+        if(aijsize != l) error(rectangular);
+        Complex *fij=fi+l*j;
+        for(size_t k=0; k < l; ++k) {
+          pair z=read<pair>(aij,k);
+          fij[k]=Complex(z.getx(),z.gety());
+        }
+      }
+    }
+
+    Forward.fft(f);
+
+    for(size_t i=0; i < n; ++i) {
+      array *ci=new array(m);
+      (*c)[i]=ci;
+      Complex *fi=f+m*l*i;
+      for(size_t j=0; j < m; ++j) {
+        array *cij=new array(l);
+        (*ci)[j]=cij;
+        Complex *fij=fi+l*j;
+        for(size_t k=0; k < l; ++k) {
+          Complex z=fij[k];
+          (*cij)[k]=pair(z.real(),z.imag());
+        }
+      }
+    }
+
+    utils::deleteAlign(f);
+  }
+#else
+  unused(a);
+  unused(&sign);
+  array *c=new array(0);
+  error(installFFTW);
+#endif //  HAVE_LIBFFTW3
+  {Stack->push<pairarray3*>(c); return;}
+}
+
+#line 1964 "runarray.in"
+// Intarray2* triangulate(pairarray *z);
+void gen_runarray70(stack *Stack)
+{
   pairarray * z=vm::pop<pairarray *>(Stack);
-#line 1852 "runarray.in"
+#line 1965 "runarray.in"
   size_t nv=checkArray(z);
 // Call robust version of Gilles Dumoulin's port of Paul Bourke's
 // triangulation code.
@@ -2237,12 +2359,12 @@
   {Stack->push<Intarray2*>(t); return;}
 }
 
-#line 1886 "runarray.in"
+#line 1999 "runarray.in"
 // real norm(realarray *a);
-void gen_runarray69(stack *Stack)
+void gen_runarray71(stack *Stack)
 {
   realarray * a=vm::pop<realarray *>(Stack);
-#line 1887 "runarray.in"
+#line 2000 "runarray.in"
   size_t n=checkArray(a);
   real M=0.0;
   for(size_t i=0; i < n; ++i) {
@@ -2252,12 +2374,12 @@
   {Stack->push<real>(M); return;}
 }
 
-#line 1897 "runarray.in"
+#line 2010 "runarray.in"
 // real norm(realarray2 *a);
-void gen_runarray70(stack *Stack)
+void gen_runarray72(stack *Stack)
 {
   realarray2 * a=vm::pop<realarray2 *>(Stack);
-#line 1898 "runarray.in"
+#line 2011 "runarray.in"
   size_t n=checkArray(a);
   real M=0.0;
   for(size_t i=0; i < n; ++i) {
@@ -2271,12 +2393,12 @@
   {Stack->push<real>(M); return;}
 }
 
-#line 1912 "runarray.in"
+#line 2025 "runarray.in"
 // real norm(triplearray2 *a);
-void gen_runarray71(stack *Stack)
+void gen_runarray73(stack *Stack)
 {
   triplearray2 * a=vm::pop<triplearray2 *>(Stack);
-#line 1913 "runarray.in"
+#line 2026 "runarray.in"
   size_t n=checkArray(a);
   real M=0.0;
   for(size_t i=0; i < n; ++i) {
@@ -2290,12 +2412,12 @@
   {Stack->push<real>(sqrt(M)); return;}
 }
 
-#line 1927 "runarray.in"
+#line 2040 "runarray.in"
 // real change2(triplearray2 *a);
-void gen_runarray72(stack *Stack)
+void gen_runarray74(stack *Stack)
 {
   triplearray2 * a=vm::pop<triplearray2 *>(Stack);
-#line 1928 "runarray.in"
+#line 2041 "runarray.in"
   size_t n=checkArray(a);
   if(n == 0) {Stack->push<real>(0.0); return;}
   
@@ -2316,13 +2438,13 @@
   {Stack->push<real>(M); return;}
 }
 
-#line 1949 "runarray.in"
+#line 2062 "runarray.in"
 // triple minbezier(triplearray2 *P, triple b);
-void gen_runarray73(stack *Stack)
+void gen_runarray75(stack *Stack)
 {
   triple b=vm::pop<triple>(Stack);
   triplearray2 * P=vm::pop<triplearray2 *>(Stack);
-#line 1950 "runarray.in"
+#line 2063 "runarray.in"
   size_t N;
   real *A=copyTripleArray2Components(P,N);
   bound_double *B=bounddouble(N);
@@ -2333,13 +2455,13 @@
   {Stack->push<triple>(b); return;}
 }
 
-#line 1961 "runarray.in"
+#line 2074 "runarray.in"
 // triple maxbezier(triplearray2 *P, triple b);
-void gen_runarray74(stack *Stack)
+void gen_runarray76(stack *Stack)
 {
   triple b=vm::pop<triple>(Stack);
   triplearray2 * P=vm::pop<triplearray2 *>(Stack);
-#line 1962 "runarray.in"
+#line 2075 "runarray.in"
   size_t N;
   real *A=copyTripleArray2Components(P,N);
   bound_double *B=bounddouble(N);
@@ -2350,13 +2472,13 @@
   {Stack->push<triple>(b); return;}
 }
 
-#line 1973 "runarray.in"
+#line 2086 "runarray.in"
 // pair minratio(triplearray2 *P, pair b);
-void gen_runarray75(stack *Stack)
+void gen_runarray77(stack *Stack)
 {
   pair b=vm::pop<pair>(Stack);
   triplearray2 * P=vm::pop<triplearray2 *>(Stack);
-#line 1974 "runarray.in"
+#line 2087 "runarray.in"
   size_t N;
   triple *A=copyTripleArray2C(P,N);
   real fuzz=Fuzz*norm(A,N);
@@ -2367,13 +2489,13 @@
   {Stack->push<pair>(b); return;}
 }
 
-#line 1985 "runarray.in"
+#line 2098 "runarray.in"
 // pair maxratio(triplearray2 *P, pair b);
-void gen_runarray76(stack *Stack)
+void gen_runarray78(stack *Stack)
 {
   pair b=vm::pop<pair>(Stack);
   triplearray2 * P=vm::pop<triplearray2 *>(Stack);
-#line 1986 "runarray.in"
+#line 2099 "runarray.in"
   size_t N;
   triple *A=copyTripleArray2C(P,N);
   bound_triple *B=boundtriple(N);
@@ -2384,11 +2506,11 @@
   {Stack->push<pair>(b); return;}
 }
 
-#line 1997 "runarray.in"
+#line 2110 "runarray.in"
 // realarray* _projection();
-void gen_runarray77(stack *Stack)
+void gen_runarray79(stack *Stack)
 {
-#line 1998 "runarray.in"
+#line 2111 "runarray.in"
 #ifdef HAVE_GL
   array *a=new array(14);
   gl::projection P=gl::camera();
@@ -2425,162 +2547,166 @@
 
 void gen_runarray_venv(venv &ve)
 {
-#line 585 "runarray.in"
+#line 593 "runarray.in"
   REGISTER_BLTIN(run::emptyArray,"emptyArray");
-#line 591 "runarray.in"
+#line 599 "runarray.in"
   REGISTER_BLTIN(run::newDeepArray,"newDeepArray");
-#line 613 "runarray.in"
+#line 621 "runarray.in"
   REGISTER_BLTIN(run::newInitializedArray,"newInitializedArray");
-#line 628 "runarray.in"
+#line 636 "runarray.in"
   REGISTER_BLTIN(run::newAppendedArray,"newAppendedArray");
-#line 644 "runarray.in"
+#line 652 "runarray.in"
   REGISTER_BLTIN(run::copyArrayValue,"copyArrayValue");
-#line 656 "runarray.in"
+#line 664 "runarray.in"
   REGISTER_BLTIN(run::copyArray,"copyArray");
-#line 667 "runarray.in"
+#line 675 "runarray.in"
   REGISTER_BLTIN(run::arrayRead,"arrayRead");
-#line 679 "runarray.in"
+#line 687 "runarray.in"
   REGISTER_BLTIN(run::arraySliceRead,"arraySliceRead");
-#line 686 "runarray.in"
+#line 694 "runarray.in"
   REGISTER_BLTIN(run::arraySliceReadToEnd,"arraySliceReadToEnd");
-#line 694 "runarray.in"
+#line 702 "runarray.in"
   REGISTER_BLTIN(run::arrayArrayRead,"arrayArrayRead");
-#line 703 "runarray.in"
+#line 711 "runarray.in"
   REGISTER_BLTIN(run::arrayWrite,"arrayWrite");
-#line 720 "runarray.in"
+#line 728 "runarray.in"
   REGISTER_BLTIN(run::arraySliceWrite,"arraySliceWrite");
-#line 728 "runarray.in"
+#line 736 "runarray.in"
   REGISTER_BLTIN(run::arraySliceWriteToEnd,"arraySliceWriteToEnd");
-#line 736 "runarray.in"
+#line 744 "runarray.in"
   REGISTER_BLTIN(run::arrayLength,"arrayLength");
-#line 742 "runarray.in"
+#line 750 "runarray.in"
   REGISTER_BLTIN(run::arrayKeys,"arrayKeys");
-#line 757 "runarray.in"
+#line 765 "runarray.in"
   REGISTER_BLTIN(run::arrayCyclicFlag,"arrayCyclicFlag");
-#line 764 "runarray.in"
+#line 772 "runarray.in"
   REGISTER_BLTIN(run::arraySetCyclicFlag,"arraySetCyclicFlag");
-#line 771 "runarray.in"
+#line 779 "runarray.in"
   REGISTER_BLTIN(run::arrayInitializedHelper,"arrayInitializedHelper");
-#line 782 "runarray.in"
+#line 790 "runarray.in"
   REGISTER_BLTIN(run::arrayInitialized,"arrayInitialized");
-#line 788 "runarray.in"
+#line 796 "runarray.in"
   REGISTER_BLTIN(run::arrayCyclicHelper,"arrayCyclicHelper");
-#line 795 "runarray.in"
+#line 803 "runarray.in"
   REGISTER_BLTIN(run::arrayCyclic,"arrayCyclic");
-#line 801 "runarray.in"
+#line 809 "runarray.in"
   REGISTER_BLTIN(run::arrayPushHelper,"arrayPushHelper");
-#line 809 "runarray.in"
+#line 817 "runarray.in"
   REGISTER_BLTIN(run::arrayPush,"arrayPush");
-#line 815 "runarray.in"
+#line 823 "runarray.in"
   REGISTER_BLTIN(run::arrayAppendHelper,"arrayAppendHelper");
-#line 824 "runarray.in"
+#line 832 "runarray.in"
   REGISTER_BLTIN(run::arrayAppend,"arrayAppend");
-#line 830 "runarray.in"
+#line 838 "runarray.in"
   REGISTER_BLTIN(run::arrayPopHelper,"arrayPopHelper");
-#line 839 "runarray.in"
+#line 847 "runarray.in"
   REGISTER_BLTIN(run::arrayPop,"arrayPop");
-#line 845 "runarray.in"
+#line 853 "runarray.in"
   REGISTER_BLTIN(run::arrayInsertHelper,"arrayInsertHelper");
-#line 856 "runarray.in"
+#line 864 "runarray.in"
   REGISTER_BLTIN(run::arrayInsert,"arrayInsert");
-#line 862 "runarray.in"
+#line 870 "runarray.in"
   REGISTER_BLTIN(run::arrayDelete,"arrayDelete");
-#line 868 "runarray.in"
+#line 876 "runarray.in"
   REGISTER_BLTIN(run::arrayAlias,"arrayAlias");
-#line 873 "runarray.in"
+#line 881 "runarray.in"
   REGISTER_BLTIN(run::arrayIntArray,"arrayIntArray");
-#line 891 "runarray.in"
+#line 899 "runarray.in"
   addFunc(ve, run::gen_runarray32, IntArray(), SYM(complement), formal(IntArray(), SYM(a), false, false), formal(primInt(), SYM(n), false, false));
-#line 910 "runarray.in"
+#line 918 "runarray.in"
   REGISTER_BLTIN(run::arraySequence,"arraySequence");
-#line 923 "runarray.in"
+#line 931 "runarray.in"
   addFunc(ve, run::gen_runarray34, IntArray(), SYM(sequence), formal(primInt(), SYM(n), false, false));
-#line 934 "runarray.in"
+#line 942 "runarray.in"
   REGISTER_BLTIN(run::arrayFunction,"arrayFunction");
-#line 947 "runarray.in"
+#line 955 "runarray.in"
   REGISTER_BLTIN(run::arraySort,"arraySort");
-#line 957 "runarray.in"
+#line 965 "runarray.in"
   REGISTER_BLTIN(run::arraySearch,"arraySearch");
-#line 976 "runarray.in"
+#line 984 "runarray.in"
   addFunc(ve, run::gen_runarray38, primBoolean(), SYM(all), formal(booleanArray(), SYM(a), false, false));
-#line 985 "runarray.in"
+#line 993 "runarray.in"
   addFunc(ve, run::gen_runarray39, booleanArray(), SYM_LOGNOT, formal(booleanArray(), SYM(a), false, false));
-#line 994 "runarray.in"
+#line 1002 "runarray.in"
   addFunc(ve, run::gen_runarray40, primInt(), SYM(sum), formal(booleanArray(), SYM(a), false, false));
-#line 1003 "runarray.in"
+#line 1011 "runarray.in"
   REGISTER_BLTIN(run::arrayConcat,"arrayConcat");
-#line 1031 "runarray.in"
+#line 1039 "runarray.in"
   REGISTER_BLTIN(run::array2Transpose,"array2Transpose");
-#line 1055 "runarray.in"
+#line 1063 "runarray.in"
   REGISTER_BLTIN(run::array3Transpose,"array3Transpose");
-#line 1142 "runarray.in"
+#line 1150 "runarray.in"
   addFunc(ve, run::gen_runarray44, primInt(), SYM(find), formal(booleanArray(), SYM(a), false, false), formal(primInt(), SYM(n), true, false));
-#line 1161 "runarray.in"
+#line 1169 "runarray.in"
   addFunc(ve, run::gen_runarray45, IntArray(), SYM(findall), formal(booleanArray(), SYM(a), false, false));
-#line 1174 "runarray.in"
+#line 1182 "runarray.in"
   REGISTER_BLTIN(run::arrayConditional,"arrayConditional");
-#line 1200 "runarray.in"
+#line 1208 "runarray.in"
   addFunc(ve, run::gen_runarray47, realArray2(), SYM(identity), formal(primInt(), SYM(n), false, false));
-#line 1206 "runarray.in"
+#line 1214 "runarray.in"
   addFunc(ve, run::gen_runarray48, realArray2(), SYM(inverse), formal(realArray2(), SYM(a), false, false));
-#line 1218 "runarray.in"
+#line 1226 "runarray.in"
   addFunc(ve, run::gen_runarray49, realArray(), SYM(solve), formal(realArray2(), SYM(a), false, false), formal(realArray(), SYM(b), false, false), formal(primBoolean(), SYM(warn), true, false));
-#line 1271 "runarray.in"
+#line 1279 "runarray.in"
   addFunc(ve, run::gen_runarray50, realArray2(), SYM(solve), formal(realArray2(), SYM(a), false, false), formal(realArray2(), SYM(b), false, false), formal(primBoolean(), SYM(warn), true, false));
-#line 1336 "runarray.in"
+#line 1344 "runarray.in"
   addFunc(ve, run::gen_runarray51, primReal(), SYM(determinant), formal(realArray2(), SYM(a), false, false));
-#line 1353 "runarray.in"
+#line 1361 "runarray.in"
   addFunc(ve, run::gen_runarray52, realArray(), SYM_TIMES, formal(realArray2(), SYM(a), false, false), formal(realArray(), SYM(b), false, false));
-#line 1372 "runarray.in"
+#line 1380 "runarray.in"
   addFunc(ve, run::gen_runarray53, realArray(), SYM_TIMES, formal(realArray(), SYM(a), false, false), formal(realArray2(), SYM(b), false, false));
-#line 1401 "runarray.in"
+#line 1409 "runarray.in"
   addFunc(ve, run::gen_runarray54, IntArray2(), SYM_TIMES, formal(IntArray2(), SYM(a), false, false), formal(IntArray2(), SYM(b), false, false));
-#line 1406 "runarray.in"
+#line 1414 "runarray.in"
   addFunc(ve, run::gen_runarray55, realArray2(), SYM_TIMES, formal(realArray2(), SYM(a), false, false), formal(realArray2(), SYM(b), false, false));
-#line 1411 "runarray.in"
+#line 1419 "runarray.in"
   addFunc(ve, run::gen_runarray56, pairArray2(), SYM_TIMES, formal(pairArray2(), SYM(a), false, false), formal(pairArray2(), SYM(b), false, false));
-#line 1416 "runarray.in"
+#line 1424 "runarray.in"
   addFunc(ve, run::gen_runarray57, primTriple(), SYM_TIMES, formal(realArray2(), SYM(t), false, false), formal(primTriple(), SYM(v), false, false));
-#line 1421 "runarray.in"
+#line 1429 "runarray.in"
   addFunc(ve, run::gen_runarray58, realArray2(), SYM(AtA), formal(realArray2(), SYM(a), false, false));
-#line 1426 "runarray.in"
+#line 1434 "runarray.in"
   addFunc(ve, run::gen_runarray59, primPair(), SYM(project), formal(primTriple(), SYM(v), false, false), formal(realArray2(), SYM(t), false, false));
-#line 1451 "runarray.in"
+#line 1459 "runarray.in"
   addFunc(ve, run::gen_runarray60, primReal(), SYM(dot), formal(realArray(), SYM(a), false, false), formal(realArray(), SYM(b), false, false));
-#line 1461 "runarray.in"
+#line 1469 "runarray.in"
   addFunc(ve, run::gen_runarray61, primPair(), SYM(dot), formal(pairArray(), SYM(a), false, false), formal(pairArray(), SYM(b), false, false));
-#line 1471 "runarray.in"
+#line 1479 "runarray.in"
   addFunc(ve, run::gen_runarray62, realArray(), SYM(tridiagonal), formal(realArray(), SYM(a), false, false), formal(realArray(), SYM(b), false, false), formal(realArray(), SYM(c), false, false), formal(realArray(), SYM(f), false, false));
-#line 1575 "runarray.in"
+#line 1583 "runarray.in"
   addFunc(ve, run::gen_runarray63, primReal(), SYM(newton), formal(primInt(), SYM(iterations), true, false), formal(realRealFunction(), SYM(f), false, false), formal(realRealFunction(), SYM(fprime), false, false), formal(primReal(), SYM(x), false, false), formal(primBoolean(), SYM(verbose), true, false));
-#line 1622 "runarray.in"
+#line 1630 "runarray.in"
   addFunc(ve, run::gen_runarray64, primReal(), SYM(newton), formal(primInt(), SYM(iterations), true, false), formal(realRealFunction(), SYM(f), false, false), formal(realRealFunction(), SYM(fprime), false, false), formal(primReal(), SYM(x1), false, false), formal(primReal(), SYM(x2), false, false), formal(primBoolean(), SYM(verbose), true, false));
-#line 1704 "runarray.in"
+#line 1712 "runarray.in"
   addFunc(ve, run::gen_runarray65, primReal(), SYM(_findroot), formal(realRealFunction(), SYM(f), false, false), formal(primReal(), SYM(a), false, false), formal(primReal(), SYM(b), false, false), formal(primReal(), SYM(tolerance), false, false), formal(primReal(), SYM(fa), false, false), formal(primReal(), SYM(fb), false, false));
-#line 1806 "runarray.in"
+#line 1814 "runarray.in"
   addFunc(ve, run::gen_runarray66, primReal(), SYM(simpson), formal(realRealFunction(), SYM(f), false, false), formal(primReal(), SYM(a), false, false), formal(primReal(), SYM(b), false, false), formal(primReal(), SYM(acc), true, false), formal(primReal(), SYM(dxmax), true, false));
-#line 1820 "runarray.in"
+#line 1828 "runarray.in"
   addFunc(ve, run::gen_runarray67, pairArray(), SYM(fft), formal(pairArray(), SYM(a), false, false), formal(primInt(), SYM(sign), true, false));
-#line 1851 "runarray.in"
-  addFunc(ve, run::gen_runarray68, IntArray2(), SYM(triangulate), formal(pairArray(), SYM(z), false, false));
-#line 1886 "runarray.in"
-  addFunc(ve, run::gen_runarray69, primReal(), SYM(norm), formal(realArray(), SYM(a), false, false));
-#line 1897 "runarray.in"
-  addFunc(ve, run::gen_runarray70, primReal(), SYM(norm), formal(realArray2(), SYM(a), false, false));
-#line 1912 "runarray.in"
-  addFunc(ve, run::gen_runarray71, primReal(), SYM(norm), formal(tripleArray2(), SYM(a), false, false));
-#line 1927 "runarray.in"
-  addFunc(ve, run::gen_runarray72, primReal(), SYM(change2), formal(tripleArray2(), SYM(a), false, false));
-#line 1949 "runarray.in"
-  addFunc(ve, run::gen_runarray73, primTriple(), SYM(minbezier), formal(tripleArray2(), SYM(p), false, false), formal(primTriple(), SYM(b), false, false));
-#line 1961 "runarray.in"
-  addFunc(ve, run::gen_runarray74, primTriple(), SYM(maxbezier), formal(tripleArray2(), SYM(p), false, false), formal(primTriple(), SYM(b), false, false));
-#line 1973 "runarray.in"
-  addFunc(ve, run::gen_runarray75, primPair(), SYM(minratio), formal(tripleArray2(), SYM(p), false, false), formal(primPair(), SYM(b), false, false));
-#line 1985 "runarray.in"
-  addFunc(ve, run::gen_runarray76, primPair(), SYM(maxratio), formal(tripleArray2(), SYM(p), false, false), formal(primPair(), SYM(b), false, false));
-#line 1997 "runarray.in"
-  addFunc(ve, run::gen_runarray77, realArray(), SYM(_projection));
+#line 1859 "runarray.in"
+  addFunc(ve, run::gen_runarray68, pairArray2(), SYM(fft), formal(pairArray2(), SYM(a), false, false), formal(primInt(), SYM(sign), true, false));
+#line 1905 "runarray.in"
+  addFunc(ve, run::gen_runarray69, pairArray3(), SYM(fft), formal(pairArray3(), SYM(a), false, false), formal(primInt(), SYM(sign), true, false));
+#line 1964 "runarray.in"
+  addFunc(ve, run::gen_runarray70, IntArray2(), SYM(triangulate), formal(pairArray(), SYM(z), false, false));
+#line 1999 "runarray.in"
+  addFunc(ve, run::gen_runarray71, primReal(), SYM(norm), formal(realArray(), SYM(a), false, false));
+#line 2010 "runarray.in"
+  addFunc(ve, run::gen_runarray72, primReal(), SYM(norm), formal(realArray2(), SYM(a), false, false));
+#line 2025 "runarray.in"
+  addFunc(ve, run::gen_runarray73, primReal(), SYM(norm), formal(tripleArray2(), SYM(a), false, false));
+#line 2040 "runarray.in"
+  addFunc(ve, run::gen_runarray74, primReal(), SYM(change2), formal(tripleArray2(), SYM(a), false, false));
+#line 2062 "runarray.in"
+  addFunc(ve, run::gen_runarray75, primTriple(), SYM(minbezier), formal(tripleArray2(), SYM(p), false, false), formal(primTriple(), SYM(b), false, false));
+#line 2074 "runarray.in"
+  addFunc(ve, run::gen_runarray76, primTriple(), SYM(maxbezier), formal(tripleArray2(), SYM(p), false, false), formal(primTriple(), SYM(b), false, false));
+#line 2086 "runarray.in"
+  addFunc(ve, run::gen_runarray77, primPair(), SYM(minratio), formal(tripleArray2(), SYM(p), false, false), formal(primPair(), SYM(b), false, false));
+#line 2098 "runarray.in"
+  addFunc(ve, run::gen_runarray78, primPair(), SYM(maxratio), formal(tripleArray2(), SYM(p), false, false), formal(primPair(), SYM(b), false, false));
+#line 2110 "runarray.in"
+  addFunc(ve, run::gen_runarray79, realArray(), SYM(_projection));
 }
 
 } // namespace trans

Modified: trunk/Build/source/utils/asymptote/runarray.in
===================================================================
--- trunk/Build/source/utils/asymptote/runarray.in	2020-03-03 22:33:26 UTC (rev 54033)
+++ trunk/Build/source/utils/asymptote/runarray.in	2020-03-03 22:35:09 UTC (rev 54034)
@@ -14,6 +14,7 @@
 realarray2* => realArray2()
 pairarray* => pairArray()
 pairarray2* => pairArray2()
+pairarray3* => pairArray3()
 triplearray2* => tripleArray2()
 callableReal* => realRealFunction()
 
@@ -27,6 +28,10 @@
 
 #ifdef HAVE_LIBFFTW3
 #include "fftw++.h"
+static const char *rectangular="matrix must be rectangular";
+#else
+static const char *installFFTW=
+  "Please install fftw3, run ./configure, and recompile";
 #endif
 
 using namespace camp;
@@ -43,6 +48,7 @@
 typedef array realarray2;
 typedef array pairarray;
 typedef array pairarray2;
+typedef array pairarray3;
 typedef array triplearray2;
 
 using types::booleanArray;
@@ -52,6 +58,7 @@
 using types::realArray2;
 using types::pairArray;
 using types::pairArray2;
+using types::pairArray3;
 using types::tripleArray2;
 
 typedef callable callableReal;
@@ -111,6 +118,7 @@
 static const char *incommensurate="Incommensurate matrices";
 static const char *singular="Singular matrix";
 static const char *invalidarraylength="Invalid array length: ";
+
 static size_t *pivot,*Row,*Col;
 
 bound_double *bounddouble(int N)
@@ -1843,11 +1851,116 @@
   unused(a);
   unused(&sign);
   array *c=new array(0);
-  error("Please install fftw3, run ./configure, and recompile");
+  error(installFFTW);
 #endif //  HAVE_LIBFFTW3
   return c;
 }
 

+// Compute the fast Fourier transform of a 2D pair array
+pairarray2* fft(pairarray2 *a, Int sign=1)
+{
+#ifdef HAVE_LIBFFTW3
+  size_t n=checkArray(a);
+  size_t m=n == 0 ? 0 : checkArray(read<array*>(a,0));
+
+  array *c=new array(n);
+  Complex *f=utils::ComplexAlign(n*m);
+  fftwpp::fft2d Forward(n,m,intcast(sign),f);
+
+  if(n) {
+    for(size_t i=0; i < n; ++i) {
+      array *ai=read<array *>(a,i);
+      size_t aisize=checkArray(ai);
+      if(aisize != m) error(rectangular);
+      Complex *fi=f+m*i;
+      for(size_t j=0; j < m; ++j) {
+        pair z=read<pair>(ai,j);
+        fi[j]=Complex(z.getx(),z.gety());
+      }
+    }
+
+    Forward.fft(f);
+
+    for(size_t i=0; i < n; ++i) {
+      array *ci=new array(m);
+      (*c)[i]=ci;
+      Complex *fi=f+m*i;
+      for(size_t j=0; j < m; ++j) {
+        Complex z=fi[j];
+        (*ci)[j]=pair(z.real(),z.imag());
+      }
+    }
+
+    utils::deleteAlign(f);
+  }
+#else
+  unused(a);
+  unused(&sign);
+  array *c=new array(0);
+  error(installFFTW);
+#endif //  HAVE_LIBFFTW3
+  return c;
+}
+

+// Compute the fast Fourier transform of a 3D pair array
+pairarray3* fft(pairarray3 *a, Int sign=1)
+{
+#ifdef HAVE_LIBFFTW3
+  size_t n=checkArray(a);
+  array *a0=read<array*>(a,0);
+  size_t m=n == 0 ? 0 : checkArray(a0);
+  size_t l=m == 0 ? 0 : checkArray(read<array*>(a0,0));
+
+  array *c=new array(n);
+  Complex *f=utils::ComplexAlign(n*m*l);
+  fftwpp::fft3d Forward(n,m,l,intcast(sign),f);
+
+  if(n) {
+    for(size_t i=0; i < n; ++i) {
+      array *ai=read<array *>(a,i);
+      size_t aisize=checkArray(ai);
+      if(aisize != m) error(rectangular);
+      Complex *fi=f+m*l*i;
+      for(size_t j=0; j < m; ++j) {
+        array *aij=read<array *>(ai,j);
+        size_t aijsize=checkArray(aij);
+        if(aijsize != l) error(rectangular);
+        Complex *fij=fi+l*j;
+        for(size_t k=0; k < l; ++k) {
+          pair z=read<pair>(aij,k);
+          fij[k]=Complex(z.getx(),z.gety());
+        }
+      }
+    }
+
+    Forward.fft(f);
+
+    for(size_t i=0; i < n; ++i) {
+      array *ci=new array(m);
+      (*c)[i]=ci;
+      Complex *fi=f+m*l*i;
+      for(size_t j=0; j < m; ++j) {
+        array *cij=new array(l);
+        (*ci)[j]=cij;
+        Complex *fij=fi+l*j;
+        for(size_t k=0; k < l; ++k) {
+          Complex z=fij[k];
+          (*cij)[k]=pair(z.real(),z.imag());
+        }
+      }
+    }
+
+    utils::deleteAlign(f);
+  }
+#else
+  unused(a);
+  unused(&sign);
+  array *c=new array(0);
+  error(installFFTW);
+#endif //  HAVE_LIBFFTW3
+  return c;
+}
+

 Intarray2 *triangulate(pairarray *z)
 {
   size_t nv=checkArray(z);

Modified: trunk/Build/source/utils/asymptote/runfile.cc
===================================================================
--- trunk/Build/source/utils/asymptote/runfile.cc	2020-03-03 22:33:26 UTC (rev 54033)
+++ trunk/Build/source/utils/asymptote/runfile.cc	2020-03-03 22:35:09 UTC (rev 54034)
@@ -263,57 +263,58 @@
 #line 145 "runfile.in"
   char c=0;
   if(f->isOpen()) f->read(c);
-  static char str[1];
+  static char str[2];
   str[0]=c;
+  str[1]=0;
   {Stack->push<string>(string(str)); return;}
 }
 
-#line 153 "runfile.in"
+#line 154 "runfile.in"
 // Int tell(file *f);
 void gen_runfile13(stack *Stack)
 {
   file * f=vm::pop<file *>(Stack);
-#line 154 "runfile.in"
+#line 155 "runfile.in"
   {Stack->push<Int>(f->tell()); return;}
 }
 
-#line 158 "runfile.in"
+#line 159 "runfile.in"
 // void seek(file *f, Int pos);
 void gen_runfile14(stack *Stack)
 {
   Int pos=vm::pop<Int>(Stack);
   file * f=vm::pop<file *>(Stack);
-#line 159 "runfile.in"
+#line 160 "runfile.in"
   f->seek(pos,pos >= 0);
 }
 
-#line 163 "runfile.in"
+#line 164 "runfile.in"
 // void seekeof(file *f);
 void gen_runfile15(stack *Stack)
 {
   file * f=vm::pop<file *>(Stack);
-#line 164 "runfile.in"
+#line 165 "runfile.in"
   f->seek(0,false);
 }
 
-#line 168 "runfile.in"
+#line 169 "runfile.in"
 void namePart(stack *Stack)
 {
   file f=vm::pop<file>(Stack);
-#line 169 "runfile.in"
+#line 170 "runfile.in"
   {Stack->push<string>(f.filename()); return;}
 }
 
-#line 173 "runfile.in"
+#line 174 "runfile.in"
 void modePart(stack *Stack)
 {
   file f=vm::pop<file>(Stack);
-#line 174 "runfile.in"
+#line 175 "runfile.in"
   {Stack->push<string>(f.FileMode()); return;}
 }
 
 // Set file dimensions
-#line 179 "runfile.in"
+#line 180 "runfile.in"
 void dimensionSetHelper(stack *Stack)
 {
   file * f=vm::pop<file *>(Stack);
@@ -320,24 +321,24 @@
   Int nz=vm::pop<Int>(Stack,-1);
   Int ny=vm::pop<Int>(Stack,-1);
   Int nx=vm::pop<Int>(Stack,-1);
-#line 180 "runfile.in"
+#line 181 "runfile.in"
   f->dimension(nx,ny,nz);
   {Stack->push<file*>(f); return;}
 }
 
-#line 185 "runfile.in"
+#line 186 "runfile.in"
 void dimensionSet(stack *Stack)
 {
   file * f=vm::pop<file *>(Stack);
-#line 186 "runfile.in"
+#line 187 "runfile.in"
   {Stack->push<callable*>(new thunk(new bfunc(dimensionSetHelper),f)); return;}
 }
 
-#line 190 "runfile.in"
+#line 191 "runfile.in"
 void dimensionPart(stack *Stack)
 {
   file f=vm::pop<file>(Stack);
-#line 191 "runfile.in"
+#line 192 "runfile.in"
   array *a=new array(3);
   (*a)[0]=f.Nx();
   (*a)[1]=f.Ny();
@@ -346,174 +347,174 @@
 }
 
 // Set file f to read arrays in line-at-a-time mode
-#line 200 "runfile.in"
+#line 201 "runfile.in"
 void lineSetHelper(stack *Stack)
 {
   file * f=vm::pop<file *>(Stack);
   bool b=vm::pop<bool>(Stack,true);
-#line 201 "runfile.in"
+#line 202 "runfile.in"
   f->LineMode(b);
   {Stack->push<file*>(f); return;}
 }
 
-#line 206 "runfile.in"
+#line 207 "runfile.in"
 void lineSet(stack *Stack)
 {
   file * f=vm::pop<file *>(Stack);
-#line 207 "runfile.in"
+#line 208 "runfile.in"
   {Stack->push<callable*>(new thunk(new bfunc(lineSetHelper),f)); return;}
 }
 
-#line 211 "runfile.in"
+#line 212 "runfile.in"
 void linePart(stack *Stack)
 {
   file f=vm::pop<file>(Stack);
-#line 212 "runfile.in"
+#line 213 "runfile.in"
   {Stack->push<bool>(f.LineMode()); return;}
 }
 
 // Set file to read comma-separated values
-#line 217 "runfile.in"
+#line 218 "runfile.in"
 void csvSetHelper(stack *Stack)
 {
   file * f=vm::pop<file *>(Stack);
   bool b=vm::pop<bool>(Stack,true);
-#line 218 "runfile.in"
+#line 219 "runfile.in"
   f->CSVMode(b);
   {Stack->push<file*>(f); return;}
 }
 
-#line 223 "runfile.in"
+#line 224 "runfile.in"
 void csvSet(stack *Stack)
 {
   file * f=vm::pop<file *>(Stack);
-#line 224 "runfile.in"
+#line 225 "runfile.in"
   {Stack->push<callable*>(new thunk(new bfunc(csvSetHelper),f)); return;}
 }
 
-#line 228 "runfile.in"
+#line 229 "runfile.in"
 void csvPart(stack *Stack)
 {
   file f=vm::pop<file>(Stack);
-#line 229 "runfile.in"
+#line 230 "runfile.in"
   {Stack->push<bool>(f.CSVMode()); return;}
 }
 
 // Set file to read whitespace-separated values
-#line 234 "runfile.in"
+#line 235 "runfile.in"
 void wordSetHelper(stack *Stack)
 {
   file * f=vm::pop<file *>(Stack);
   bool b=vm::pop<bool>(Stack,true);
-#line 235 "runfile.in"
+#line 236 "runfile.in"
   f->WordMode(b);
   {Stack->push<file*>(f); return;}
 }
 
-#line 240 "runfile.in"
+#line 241 "runfile.in"
 void wordSet(stack *Stack)
 {
   file * f=vm::pop<file *>(Stack);
-#line 241 "runfile.in"
+#line 242 "runfile.in"
   {Stack->push<callable*>(new thunk(new bfunc(wordSetHelper),f)); return;}
 }
 
-#line 245 "runfile.in"
+#line 246 "runfile.in"
 void wordPart(stack *Stack)
 {
   file f=vm::pop<file>(Stack);
-#line 246 "runfile.in"
+#line 247 "runfile.in"
   {Stack->push<bool>(f.WordMode()); return;}
 }
 
 // Set file to read/write single precision real XDR values.
-#line 251 "runfile.in"
+#line 252 "runfile.in"
 void singlerealSetHelper(stack *Stack)
 {
   file * f=vm::pop<file *>(Stack);
   bool b=vm::pop<bool>(Stack,true);
-#line 252 "runfile.in"
+#line 253 "runfile.in"
   f->SingleReal(b);
   {Stack->push<file*>(f); return;}
 }
 
-#line 257 "runfile.in"
+#line 258 "runfile.in"
 void singlerealSet(stack *Stack)
 {
   file * f=vm::pop<file *>(Stack);
-#line 258 "runfile.in"
+#line 259 "runfile.in"
   {Stack->push<callable*>(new thunk(new bfunc(singlerealSetHelper),f)); return;}
 }
 
-#line 262 "runfile.in"
+#line 263 "runfile.in"
 void singlerealPart(stack *Stack)
 {
   file f=vm::pop<file>(Stack);
-#line 263 "runfile.in"
+#line 264 "runfile.in"
   {Stack->push<bool>(f.SingleReal()); return;}
 }
 
 // Set file to read/write single precision int XDR values.
-#line 268 "runfile.in"
+#line 269 "runfile.in"
 void singleintSetHelper(stack *Stack)
 {
   file * f=vm::pop<file *>(Stack);
   bool b=vm::pop<bool>(Stack,true);
-#line 269 "runfile.in"
+#line 270 "runfile.in"
   f->SingleInt(b);
   {Stack->push<file*>(f); return;}
 }
 
-#line 274 "runfile.in"
+#line 275 "runfile.in"
 void singleintSet(stack *Stack)
 {
   file * f=vm::pop<file *>(Stack);
-#line 275 "runfile.in"
+#line 276 "runfile.in"
   {Stack->push<callable*>(new thunk(new bfunc(singleintSetHelper),f)); return;}
 }
 
-#line 279 "runfile.in"
+#line 280 "runfile.in"
 void singleintPart(stack *Stack)
 {
   file f=vm::pop<file>(Stack);
-#line 280 "runfile.in"
+#line 281 "runfile.in"
   {Stack->push<bool>(f.SingleInt()); return;}
 }
 
 // Set file to read/write signed int XDR values.
-#line 285 "runfile.in"
+#line 286 "runfile.in"
 void signedintSetHelper(stack *Stack)
 {
   file * f=vm::pop<file *>(Stack);
   bool b=vm::pop<bool>(Stack,true);
-#line 286 "runfile.in"
+#line 287 "runfile.in"
   f->SignedInt(b);
   {Stack->push<file*>(f); return;}
 }
 
-#line 291 "runfile.in"
+#line 292 "runfile.in"
 void signedintSet(stack *Stack)
 {
   file * f=vm::pop<file *>(Stack);
-#line 292 "runfile.in"
+#line 293 "runfile.in"
   {Stack->push<callable*>(new thunk(new bfunc(signedintSetHelper),f)); return;}
 }
 
-#line 296 "runfile.in"
+#line 297 "runfile.in"
 void signedintPart(stack *Stack)
 {
   file f=vm::pop<file>(Stack);
-#line 297 "runfile.in"
+#line 298 "runfile.in"
   {Stack->push<bool>(f.SignedInt()); return;}
 }
 
 // Set file to read an arrayi (i int sizes followed by an i-dimensional array)
-#line 302 "runfile.in"
+#line 303 "runfile.in"
 void readSetHelper(stack *Stack)
 {
   file * f=vm::pop<file *>(Stack);
   Int i=vm::pop<Int>(Stack);
-#line 303 "runfile.in"
+#line 304 "runfile.in"
   switch(i) {
     case 1:
       f->dimension(-2);
@@ -534,21 +535,21 @@
   {Stack->push<file*>(f); return;}
 }
 
-#line 324 "runfile.in"
+#line 325 "runfile.in"
 void readSet(stack *Stack)
 {
   file * f=vm::pop<file *>(Stack);
-#line 325 "runfile.in"
+#line 326 "runfile.in"
   {Stack->push<callable*>(new thunk(new bfunc(readSetHelper),f)); return;}
 }
 
 // Delete file named s.
-#line 330 "runfile.in"
+#line 331 "runfile.in"
 // Int delete(string s);
 void gen_runfile41(stack *Stack)
 {
   string s=vm::pop<string>(Stack);
-#line 331 "runfile.in"
+#line 332 "runfile.in"
   s=outpath(s);
   Int rc=unlink(s.c_str());
   if(rc == 0 && verbose > 0) 
@@ -557,13 +558,13 @@
 }
 
 // Rename file "from" to file "to".
-#line 340 "runfile.in"
+#line 341 "runfile.in"
 // Int rename(string from, string to);
 void gen_runfile42(stack *Stack)
 {
   string to=vm::pop<string>(Stack);
   string from=vm::pop<string>(Stack);
-#line 341 "runfile.in"
+#line 342 "runfile.in"
   from=outpath(from);
   to=outpath(to);
   Int rc=rename(from.c_str(),to.c_str());
@@ -573,12 +574,12 @@
 }
 
 // Create a unique temporary file name.
-#line 351 "runfile.in"
+#line 352 "runfile.in"
 // string mktemp(string s);
 void gen_runfile43(stack *Stack)
 {
   string s=vm::pop<string>(Stack);
-#line 352 "runfile.in"
+#line 353 "runfile.in"
   char *S=Strdup(s+"XXXXXX");
   int fd=mkstemp(S);
   if(fd < 0) {
@@ -621,67 +622,67 @@
   addFunc(ve, run::gen_runfile11, primVoid(), SYM(flush), formal(primFile(), SYM(f), false, false));
 #line 144 "runfile.in"
   addFunc(ve, run::gen_runfile12, primString() , SYM(getc), formal(primFile(), SYM(f), false, false));
-#line 153 "runfile.in"
+#line 154 "runfile.in"
   addFunc(ve, run::gen_runfile13, primInt(), SYM(tell), formal(primFile(), SYM(f), false, false));
-#line 158 "runfile.in"
+#line 159 "runfile.in"
   addFunc(ve, run::gen_runfile14, primVoid(), SYM(seek), formal(primFile(), SYM(f), false, false), formal(primInt(), SYM(pos), false, false));
-#line 163 "runfile.in"
+#line 164 "runfile.in"
   addFunc(ve, run::gen_runfile15, primVoid(), SYM(seekeof), formal(primFile(), SYM(f), false, false));
-#line 168 "runfile.in"
+#line 169 "runfile.in"
   REGISTER_BLTIN(run::namePart,"namePart");
-#line 173 "runfile.in"
+#line 174 "runfile.in"
   REGISTER_BLTIN(run::modePart,"modePart");
-#line 178 "runfile.in"
+#line 179 "runfile.in"
   REGISTER_BLTIN(run::dimensionSetHelper,"dimensionSetHelper");
-#line 185 "runfile.in"
+#line 186 "runfile.in"
   REGISTER_BLTIN(run::dimensionSet,"dimensionSet");
-#line 190 "runfile.in"
+#line 191 "runfile.in"
   REGISTER_BLTIN(run::dimensionPart,"dimensionPart");
-#line 199 "runfile.in"
+#line 200 "runfile.in"
   REGISTER_BLTIN(run::lineSetHelper,"lineSetHelper");
-#line 206 "runfile.in"
+#line 207 "runfile.in"
   REGISTER_BLTIN(run::lineSet,"lineSet");
-#line 211 "runfile.in"
+#line 212 "runfile.in"
   REGISTER_BLTIN(run::linePart,"linePart");
-#line 216 "runfile.in"
+#line 217 "runfile.in"
   REGISTER_BLTIN(run::csvSetHelper,"csvSetHelper");
-#line 223 "runfile.in"
+#line 224 "runfile.in"
   REGISTER_BLTIN(run::csvSet,"csvSet");
-#line 228 "runfile.in"
+#line 229 "runfile.in"
   REGISTER_BLTIN(run::csvPart,"csvPart");
-#line 233 "runfile.in"
+#line 234 "runfile.in"
   REGISTER_BLTIN(run::wordSetHelper,"wordSetHelper");
-#line 240 "runfile.in"
+#line 241 "runfile.in"
   REGISTER_BLTIN(run::wordSet,"wordSet");
-#line 245 "runfile.in"
+#line 246 "runfile.in"
   REGISTER_BLTIN(run::wordPart,"wordPart");
-#line 250 "runfile.in"
+#line 251 "runfile.in"
   REGISTER_BLTIN(run::singlerealSetHelper,"singlerealSetHelper");
-#line 257 "runfile.in"
+#line 258 "runfile.in"
   REGISTER_BLTIN(run::singlerealSet,"singlerealSet");
-#line 262 "runfile.in"
+#line 263 "runfile.in"
   REGISTER_BLTIN(run::singlerealPart,"singlerealPart");
-#line 267 "runfile.in"
+#line 268 "runfile.in"
   REGISTER_BLTIN(run::singleintSetHelper,"singleintSetHelper");
-#line 274 "runfile.in"
+#line 275 "runfile.in"
   REGISTER_BLTIN(run::singleintSet,"singleintSet");
-#line 279 "runfile.in"
+#line 280 "runfile.in"
   REGISTER_BLTIN(run::singleintPart,"singleintPart");
-#line 284 "runfile.in"
+#line 285 "runfile.in"
   REGISTER_BLTIN(run::signedintSetHelper,"signedintSetHelper");
-#line 291 "runfile.in"
+#line 292 "runfile.in"
   REGISTER_BLTIN(run::signedintSet,"signedintSet");
-#line 296 "runfile.in"
+#line 297 "runfile.in"
   REGISTER_BLTIN(run::signedintPart,"signedintPart");
-#line 301 "runfile.in"
+#line 302 "runfile.in"
   REGISTER_BLTIN(run::readSetHelper,"readSetHelper");
-#line 324 "runfile.in"
+#line 325 "runfile.in"
   REGISTER_BLTIN(run::readSet,"readSet");
-#line 329 "runfile.in"
+#line 330 "runfile.in"
   addFunc(ve, run::gen_runfile41, primInt(), SYM(delete), formal(primString() , SYM(s), false, false));
-#line 339 "runfile.in"
+#line 340 "runfile.in"
   addFunc(ve, run::gen_runfile42, primInt(), SYM(rename), formal(primString() , SYM(from), false, false), formal(primString() , SYM(to), false, false));
-#line 350 "runfile.in"
+#line 351 "runfile.in"
   addFunc(ve, run::gen_runfile43, primString() , SYM(mktemp), formal(primString() , SYM(s), false, false));
 }
 

Modified: trunk/Build/source/utils/asymptote/runfile.in
===================================================================
--- trunk/Build/source/utils/asymptote/runfile.in	2020-03-03 22:33:26 UTC (rev 54033)
+++ trunk/Build/source/utils/asymptote/runfile.in	2020-03-03 22:35:09 UTC (rev 54034)
@@ -145,8 +145,9 @@
 {
   char c=0;
   if(f->isOpen()) f->read(c);
-  static char str[1];
+  static char str[2];
   str[0]=c;
+  str[1]=0;
   return string(str);
 }
 


Modified: trunk/Build/source/utils/asymptote/runhistory.cc
===================================================================
--- trunk/Build/source/utils/asymptote/runhistory.cc	2020-03-03 22:33:26 UTC (rev 54033)
+++ trunk/Build/source/utils/asymptote/runhistory.cc	2020-03-03 22:35:09 UTC (rev 54034)
@@ -127,10 +127,6 @@
 
 #if defined(HAVE_LIBREADLINE) && defined(HAVE_LIBCURSES)
 
-void init_readline(bool tabcompletion) 
-{
-  rl_bind_key('\t',tabcompletion ? rl_complete : rl_insert);
-}
 #endif
 
 void cleanup()
@@ -165,13 +161,13 @@
 #endif
 namespace run {
 // Return the last n lines of the history named name.
-#line 109 "runhistory.in"
+#line 105 "runhistory.in"
 // stringarray* history(string name, Int n=1);
 void gen_runhistory0(stack *Stack)
 {
   Int n=vm::pop<Int>(Stack,1);
   string name=vm::pop<string>(Stack);
-#line 110 "runhistory.in"
+#line 106 "runhistory.in"
 #if defined(HAVE_LIBREADLINE) && defined(HAVE_LIBCURSES)
   bool newhistory=historyMap.find(name) == historyMap.end();
   
@@ -203,12 +199,12 @@
 }
 
 // Return the last n lines of the interactive history.
-#line 142 "runhistory.in"
+#line 138 "runhistory.in"
 // stringarray* history(Int n=0);
 void gen_runhistory1(stack *Stack)
 {
   Int n=vm::pop<Int>(Stack,0);
-#line 143 "runhistory.in"
+#line 139 "runhistory.in"
 #if defined(HAVE_LIBREADLINE) && defined(HAVE_LIBCURSES)
   {Stack->push<stringarray*>(get_history(n)); return;}
 #else
@@ -219,7 +215,7 @@
 
 // Prompt for a string using prompt, the GNU readline library, and a
 // local history named name.
-#line 154 "runhistory.in"
+#line 150 "runhistory.in"
 // string readline(string prompt=emptystring, string name=emptystring,                bool tabcompletion=false);
 void gen_runhistory2(stack *Stack)
 {
@@ -226,11 +222,11 @@
   bool tabcompletion=vm::pop<bool>(Stack,false);
   string name=vm::pop<string>(Stack,emptystring);
   string prompt=vm::pop<string>(Stack,emptystring);
-#line 156 "runhistory.in"
+#line 152 "runhistory.in"
   if(!(isatty(STDIN_FILENO) || getSetting<Int>("inpipe") >= 0))
     {Stack->push<string>(emptystring); return;}
 #if defined(HAVE_LIBREADLINE) && defined(HAVE_LIBCURSES)
-  init_readline(tabcompletion);
+  interact::init_readline(tabcompletion);
   
   store_history(&history_save);
   bool newhistory=historyMap.find(name) == historyMap.end();
@@ -268,7 +264,7 @@
 
 // Save a string in a local history named name.
 // If store=true, store the local history in the file historyfilename(name).
-#line 198 "runhistory.in"
+#line 194 "runhistory.in"
 // void saveline(string name, string value, bool store=true);
 void gen_runhistory3(stack *Stack)
 {
@@ -275,7 +271,7 @@
   bool store=vm::pop<bool>(Stack,true);
   string value=vm::pop<string>(Stack);
   string name=vm::pop<string>(Stack);
-#line 199 "runhistory.in"
+#line 195 "runhistory.in"
 #if defined(HAVE_LIBREADLINE) && defined(HAVE_LIBCURSES)
   store_history(&history_save);
   bool newhistory=historyMap.find(name) == historyMap.end();
@@ -308,13 +304,13 @@
 
 void gen_runhistory_venv(venv &ve)
 {
-#line 108 "runhistory.in"
+#line 104 "runhistory.in"
   addFunc(ve, run::gen_runhistory0, stringArray(), SYM(history), formal(primString() , SYM(name), false, false), formal(primInt(), SYM(n), true, false));
-#line 141 "runhistory.in"
+#line 137 "runhistory.in"
   addFunc(ve, run::gen_runhistory1, stringArray(), SYM(history), formal(primInt(), SYM(n), true, false));
-#line 152 "runhistory.in"
+#line 148 "runhistory.in"
   addFunc(ve, run::gen_runhistory2, primString() , SYM(readline), formal(primString() , SYM(prompt), true, false), formal(primString() , SYM(name), true, false), formal(primBoolean(), SYM(tabcompletion), true, false));
-#line 196 "runhistory.in"
+#line 192 "runhistory.in"
   addFunc(ve, run::gen_runhistory3, primVoid(), SYM(saveline), formal(primString() , SYM(name), false, false), formal(primString() , SYM(value), false, false), formal(primBoolean(), SYM(store), true, false));
 }
 

Modified: trunk/Build/source/utils/asymptote/runhistory.in
===================================================================
--- trunk/Build/source/utils/asymptote/runhistory.in	2020-03-03 22:33:26 UTC (rev 54033)
+++ trunk/Build/source/utils/asymptote/runhistory.in	2020-03-03 22:35:09 UTC (rev 54034)
@@ -74,10 +74,6 @@
 
 #if defined(HAVE_LIBREADLINE) && defined(HAVE_LIBCURSES)
 
-void init_readline(bool tabcompletion) 
-{
-  rl_bind_key('\t',tabcompletion ? rl_complete : rl_insert);
-}
 #endif
 
 void cleanup()
@@ -157,7 +153,7 @@
   if(!(isatty(STDIN_FILENO) || getSetting<Int>("inpipe") >= 0))
     return emptystring;
 #if defined(HAVE_LIBREADLINE) && defined(HAVE_LIBCURSES)
-  init_readline(tabcompletion);
+  interact::init_readline(tabcompletion);
   
   store_history(&history_save);
   bool newhistory=historyMap.find(name) == historyMap.end();

Modified: trunk/Build/source/utils/asymptote/runmath.cc
===================================================================
--- trunk/Build/source/utils/asymptote/runmath.cc	2020-03-03 22:33:26 UTC (rev 54033)
+++ trunk/Build/source/utils/asymptote/runmath.cc	2020-03-03 22:35:09 UTC (rev 54034)
@@ -185,6 +185,7 @@
     ((unsigned long long) BitReverseTable8[(a >> 56)]);
 }
 
+#ifndef HAVE_POPCOUNT
 // https://graphics.stanford.edu/~seander/bithacks.html#CountBitsSetParallel
 #define T unsignedInt
 Int popcount(T a)
@@ -195,6 +196,7 @@
 return (T)(a*((T)~(T)0/255)) >> (sizeof(T)-1)*CHAR_BIT;
 }
 #undef T
+#endif
 
 // Return the factorial of a non-negative integer using a lookup table.
 Int factorial(Int n)
@@ -246,233 +248,233 @@
 
 #endif
 namespace run {
-#line 190 "runmath.in"
+#line 192 "runmath.in"
 // real ^(real x, Int y);
 void gen_runmath0(stack *Stack)
 {
   Int y=vm::pop<Int>(Stack);
   real x=vm::pop<real>(Stack);
-#line 191 "runmath.in"
+#line 193 "runmath.in"
   {Stack->push<real>(pow(x,y)); return;}
 }
 
-#line 195 "runmath.in"
+#line 197 "runmath.in"
 // pair ^(pair z, Int y);
 void gen_runmath1(stack *Stack)
 {
   Int y=vm::pop<Int>(Stack);
   pair z=vm::pop<pair>(Stack);
-#line 196 "runmath.in"
+#line 198 "runmath.in"
   {Stack->push<pair>(pow(z,y)); return;}
 }
 
-#line 200 "runmath.in"
+#line 202 "runmath.in"
 // Int quotient(Int x, Int y);
 void gen_runmath2(stack *Stack)
 {
   Int y=vm::pop<Int>(Stack);
   Int x=vm::pop<Int>(Stack);
-#line 201 "runmath.in" 
+#line 203 "runmath.in" 
   {Stack->push<Int>(quotient<Int>()(x,y)); return;}
 }
 
-#line 205 "runmath.in"
+#line 207 "runmath.in"
 // Int abs(Int x);
 void gen_runmath3(stack *Stack)
 {
   Int x=vm::pop<Int>(Stack);
-#line 206 "runmath.in" 
+#line 208 "runmath.in" 
   {Stack->push<Int>(Abs(x)); return;}
 }
 
-#line 210 "runmath.in"
+#line 212 "runmath.in"
 // Int sgn(real x);
 void gen_runmath4(stack *Stack)
 {
   real x=vm::pop<real>(Stack);
-#line 211 "runmath.in" 
+#line 213 "runmath.in" 
   {Stack->push<Int>(sgn(x)); return;}
 }
 
-#line 215 "runmath.in"
+#line 217 "runmath.in"
 // Int rand();
 void gen_runmath5(stack *Stack)
 {
-#line 216 "runmath.in" 
+#line 218 "runmath.in" 
   if(initializeRandom)
     Srand(1);
   {Stack->push<Int>(random()); return;}
 }
 
-#line 222 "runmath.in"
+#line 224 "runmath.in"
 // void srand(Int seed);
 void gen_runmath6(stack *Stack)
 {
   Int seed=vm::pop<Int>(Stack);
-#line 223 "runmath.in" 
+#line 225 "runmath.in" 
   Srand(seed);
 }
 
 // a random number uniformly distributed in the interval [0,1]
-#line 228 "runmath.in"
+#line 230 "runmath.in"
 // real unitrand();
 void gen_runmath7(stack *Stack)
 {
-#line 229 "runmath.in"                         
+#line 231 "runmath.in"                         
   {Stack->push<real>(((real) random())/RANDOM_MAX); return;}
 }
 
-#line 233 "runmath.in"
+#line 235 "runmath.in"
 // Int ceil(real x);
 void gen_runmath8(stack *Stack)
 {
   real x=vm::pop<real>(Stack);
-#line 234 "runmath.in" 
+#line 236 "runmath.in" 
   {Stack->push<Int>(Intcast(ceil(x))); return;}
 }
 
-#line 238 "runmath.in"
+#line 240 "runmath.in"
 // Int floor(real x);
 void gen_runmath9(stack *Stack)
 {
   real x=vm::pop<real>(Stack);
-#line 239 "runmath.in" 
+#line 241 "runmath.in" 
   {Stack->push<Int>(Intcast(floor(x))); return;}
 }
 
-#line 243 "runmath.in"
+#line 245 "runmath.in"
 // Int round(real x);
 void gen_runmath10(stack *Stack)
 {
   real x=vm::pop<real>(Stack);
-#line 244 "runmath.in" 
+#line 246 "runmath.in" 
   if(validInt(x)) {Stack->push<Int>(Round(x)); return;}
   integeroverflow(0);
 }
 
-#line 249 "runmath.in"
+#line 251 "runmath.in"
 // Int Ceil(real x);
 void gen_runmath11(stack *Stack)
 {
   real x=vm::pop<real>(Stack);
-#line 250 "runmath.in" 
+#line 252 "runmath.in" 
   {Stack->push<Int>(Ceil(x)); return;}
 }
 
-#line 254 "runmath.in"
+#line 256 "runmath.in"
 // Int Floor(real x);
 void gen_runmath12(stack *Stack)
 {
   real x=vm::pop<real>(Stack);
-#line 255 "runmath.in" 
+#line 257 "runmath.in" 
   {Stack->push<Int>(Floor(x)); return;}
 }
 
-#line 259 "runmath.in"
+#line 261 "runmath.in"
 // Int Round(real x);
 void gen_runmath13(stack *Stack)
 {
   real x=vm::pop<real>(Stack);
-#line 260 "runmath.in" 
+#line 262 "runmath.in" 
   {Stack->push<Int>(Round(Intcap(x))); return;}
 }
 
-#line 264 "runmath.in"
+#line 266 "runmath.in"
 // real fmod(real x, real y);
 void gen_runmath14(stack *Stack)
 {
   real y=vm::pop<real>(Stack);
   real x=vm::pop<real>(Stack);
-#line 265 "runmath.in"
+#line 267 "runmath.in"
   if (y == 0.0) dividebyzero();
   {Stack->push<real>(fmod(x,y)); return;}
 }
 
-#line 270 "runmath.in"
+#line 272 "runmath.in"
 // real atan2(real y, real x);
 void gen_runmath15(stack *Stack)
 {
   real x=vm::pop<real>(Stack);
   real y=vm::pop<real>(Stack);
-#line 271 "runmath.in" 
+#line 273 "runmath.in" 
   {Stack->push<real>(atan2(y,x)); return;}
 }
 
-#line 275 "runmath.in"
+#line 277 "runmath.in"
 // real hypot(real x, real y);
 void gen_runmath16(stack *Stack)
 {
   real y=vm::pop<real>(Stack);
   real x=vm::pop<real>(Stack);
-#line 276 "runmath.in" 
+#line 278 "runmath.in" 
   {Stack->push<real>(hypot(x,y)); return;}
 }
 
-#line 280 "runmath.in"
+#line 282 "runmath.in"
 // real remainder(real x, real y);
 void gen_runmath17(stack *Stack)
 {
   real y=vm::pop<real>(Stack);
   real x=vm::pop<real>(Stack);
-#line 281 "runmath.in" 
+#line 283 "runmath.in" 
   {Stack->push<real>(remainder(x,y)); return;}
 }
 
-#line 285 "runmath.in"
+#line 287 "runmath.in"
 // real Jn(Int n, real x);
 void gen_runmath18(stack *Stack)
 {
   real x=vm::pop<real>(Stack);
   Int n=vm::pop<Int>(Stack);
-#line 286 "runmath.in"
+#line 288 "runmath.in"
   {Stack->push<real>(jn(n,x)); return;}
 }
 
-#line 290 "runmath.in"
+#line 292 "runmath.in"
 // real Yn(Int n, real x);
 void gen_runmath19(stack *Stack)
 {
   real x=vm::pop<real>(Stack);
   Int n=vm::pop<Int>(Stack);
-#line 291 "runmath.in"
+#line 293 "runmath.in"
   {Stack->push<real>(yn(n,x)); return;}
 }
 
-#line 295 "runmath.in"
+#line 297 "runmath.in"
 // real erf(real x);
 void gen_runmath20(stack *Stack)
 {
   real x=vm::pop<real>(Stack);
-#line 296 "runmath.in"
+#line 298 "runmath.in"
   {Stack->push<real>(erf(x)); return;}
 }
 
-#line 300 "runmath.in"
+#line 302 "runmath.in"
 // real erfc(real x);
 void gen_runmath21(stack *Stack)
 {
   real x=vm::pop<real>(Stack);
-#line 301 "runmath.in"
+#line 303 "runmath.in"
   {Stack->push<real>(erfc(x)); return;}
 }
 
-#line 305 "runmath.in"
+#line 307 "runmath.in"
 // Int factorial(Int n);
 void gen_runmath22(stack *Stack)
 {
   Int n=vm::pop<Int>(Stack);
-#line 306 "runmath.in"
+#line 308 "runmath.in"
   if(n < 0) error(invalidargument);
   {Stack->push<Int>(factorial(n)); return;}
 }
 
-#line 310 "runmath.in"
+#line 312 "runmath.in"
 // Int choose(Int n, Int k);
 void gen_runmath23(stack *Stack)
 {
   Int k=vm::pop<Int>(Stack);
   Int n=vm::pop<Int>(Stack);
-#line 311 "runmath.in"
+#line 313 "runmath.in"
   if(n < 0 || k < 0 || k > n) error(invalidargument);
   Int f=1;
   Int r=n-k;
@@ -483,12 +485,12 @@
   {Stack->push<Int>(f); return;}
 }
 
-#line 321 "runmath.in"
+#line 323 "runmath.in"
 // real gamma(real x);
 void gen_runmath24(stack *Stack)
 {
   real x=vm::pop<real>(Stack);
-#line 322 "runmath.in"
+#line 324 "runmath.in"
 #ifdef HAVE_TGAMMA
   {Stack->push<real>(tgamma(x)); return;}
 #else
@@ -497,7 +499,7 @@
 #endif
 }
 
-#line 331 "runmath.in"
+#line 333 "runmath.in"
 // realarray* quadraticroots(real a, real b, real c);
 void gen_runmath25(stack *Stack)
 {
@@ -504,7 +506,7 @@
   real c=vm::pop<real>(Stack);
   real b=vm::pop<real>(Stack);
   real a=vm::pop<real>(Stack);
-#line 332 "runmath.in"
+#line 334 "runmath.in"
   quadraticroots q(a,b,c);
   array *roots=new array(q.roots);
   if(q.roots >= 1) (*roots)[0]=q.t1;
@@ -512,7 +514,7 @@
   {Stack->push<realarray*>(roots); return;}
 }
 
-#line 340 "runmath.in"
+#line 342 "runmath.in"
 // pairarray* quadraticroots(explicit pair a, explicit pair b, explicit pair c);
 void gen_runmath26(stack *Stack)
 {
@@ -519,7 +521,7 @@
   pair c=vm::pop<pair>(Stack);
   pair b=vm::pop<pair>(Stack);
   pair a=vm::pop<pair>(Stack);
-#line 341 "runmath.in"
+#line 343 "runmath.in"
   Quadraticroots q(a,b,c);
   array *roots=new array(q.roots);
   if(q.roots >= 1) (*roots)[0]=q.z1;
@@ -527,7 +529,7 @@
   {Stack->push<pairarray*>(roots); return;}
 }
 
-#line 349 "runmath.in"
+#line 351 "runmath.in"
 // realarray* cubicroots(real a, real b, real c, real d);
 void gen_runmath27(stack *Stack)
 {
@@ -535,7 +537,7 @@
   real c=vm::pop<real>(Stack);
   real b=vm::pop<real>(Stack);
   real a=vm::pop<real>(Stack);
-#line 350 "runmath.in"
+#line 352 "runmath.in"
   cubicroots q(a,b,c,d);
   array *roots=new array(q.roots);
   if(q.roots >= 1) (*roots)[0]=q.t1;
@@ -546,98 +548,98 @@
 
 
 // Logical operations
-#line 361 "runmath.in"
+#line 363 "runmath.in"
 // bool !(bool b);
 void gen_runmath28(stack *Stack)
 {
   bool b=vm::pop<bool>(Stack);
-#line 362 "runmath.in"
+#line 364 "runmath.in"
   {Stack->push<bool>(!b); return;}
 }
 
-#line 367 "runmath.in"
+#line 369 "runmath.in"
 void boolMemEq(stack *Stack)
 {
   frame * b=vm::pop<frame *>(Stack);
   frame * a=vm::pop<frame *>(Stack);
-#line 368 "runmath.in"
+#line 370 "runmath.in"
   {Stack->push<bool>(a == b); return;}
 }
 
-#line 372 "runmath.in"
+#line 374 "runmath.in"
 void boolMemNeq(stack *Stack)
 {
   frame * b=vm::pop<frame *>(Stack);
   frame * a=vm::pop<frame *>(Stack);
-#line 373 "runmath.in"
+#line 375 "runmath.in"
   {Stack->push<bool>(a != b); return;}
 }
 
-#line 377 "runmath.in"
+#line 379 "runmath.in"
 void boolFuncEq(stack *Stack)
 {
   callable * b=vm::pop<callable *>(Stack);
   callable * a=vm::pop<callable *>(Stack);
-#line 378 "runmath.in"
+#line 380 "runmath.in"
   {Stack->push<bool>(a->compare(b)); return;}
 }
 
-#line 382 "runmath.in"
+#line 384 "runmath.in"
 void boolFuncNeq(stack *Stack)
 {
   callable * b=vm::pop<callable *>(Stack);
   callable * a=vm::pop<callable *>(Stack);
-#line 383 "runmath.in"
+#line 385 "runmath.in"
   {Stack->push<bool>(!(a->compare(b))); return;}
 }
 
 
 // Bit operations
-#line 389 "runmath.in"
+#line 391 "runmath.in"
 // Int AND(Int a, Int b);
 void gen_runmath33(stack *Stack)
 {
   Int b=vm::pop<Int>(Stack);
   Int a=vm::pop<Int>(Stack);
-#line 390 "runmath.in"
+#line 392 "runmath.in"
   {Stack->push<Int>(a & b); return;}
 }
 
-#line 395 "runmath.in"
+#line 397 "runmath.in"
 // Int OR(Int a, Int b);
 void gen_runmath34(stack *Stack)
 {
   Int b=vm::pop<Int>(Stack);
   Int a=vm::pop<Int>(Stack);
-#line 396 "runmath.in"
+#line 398 "runmath.in"
   {Stack->push<Int>(a | b); return;}
 }
 
-#line 400 "runmath.in"
+#line 402 "runmath.in"
 // Int XOR(Int a, Int b);
 void gen_runmath35(stack *Stack)
 {
   Int b=vm::pop<Int>(Stack);
   Int a=vm::pop<Int>(Stack);
-#line 401 "runmath.in"
+#line 403 "runmath.in"
   {Stack->push<Int>(a ^ b); return;}
 }
 
-#line 405 "runmath.in"
+#line 407 "runmath.in"
 // Int NOT(Int a);
 void gen_runmath36(stack *Stack)
 {
   Int a=vm::pop<Int>(Stack);
-#line 406 "runmath.in"
+#line 408 "runmath.in"
   {Stack->push<Int>(~a); return;}
 }
 
-#line 410 "runmath.in"
+#line 412 "runmath.in"
 // Int CLZ(Int a);
 void gen_runmath37(stack *Stack)
 {
   Int a=vm::pop<Int>(Stack);
-#line 411 "runmath.in"
+#line 413 "runmath.in"
   if((unsigned long long) a > 0xFFFFFFFF)
     {Stack->push<Int>(CLZ((uint32_t) ((unsigned long long) a >> 32))); return;}
   else {
@@ -647,32 +649,32 @@
   }
 }
 
-#line 421 "runmath.in"
+#line 423 "runmath.in"
 // Int popcount(Int a);
 void gen_runmath38(stack *Stack)
 {
   Int a=vm::pop<Int>(Stack);
-#line 422 "runmath.in"
+#line 424 "runmath.in"
   {Stack->push<Int>(popcount(a)); return;}
 }
 
-#line 426 "runmath.in"
+#line 428 "runmath.in"
 // Int CTZ(Int a);
 void gen_runmath39(stack *Stack)
 {
   Int a=vm::pop<Int>(Stack);
-#line 427 "runmath.in"
+#line 429 "runmath.in"
   {Stack->push<Int>(popcount((a&-a)-1)); return;}
 }
 
 // bitreverse a within a word of length bits.
-#line 432 "runmath.in"
+#line 434 "runmath.in"
 // Int bitreverse(Int a, Int bits);
 void gen_runmath40(stack *Stack)
 {
   Int bits=vm::pop<Int>(Stack);
   Int a=vm::pop<Int>(Stack);
-#line 433 "runmath.in"
+#line 435 "runmath.in"
   typedef unsigned long long Bitreverse(unsigned long long a);
   static Bitreverse *B[]={bitreverse8,bitreverse16,bitreverse24,bitreverse32,
                      bitreverse40,bitreverse48,bitreverse56,bitreverse64};
@@ -693,87 +695,87 @@
 
 void gen_runmath_venv(venv &ve)
 {
-#line 190 "runmath.in"
+#line 192 "runmath.in"
   addFunc(ve, run::gen_runmath0, primReal(), SYM_CARET, formal(primReal(), SYM(x), false, false), formal(primInt(), SYM(y), false, false));
-#line 195 "runmath.in"
+#line 197 "runmath.in"
   addFunc(ve, run::gen_runmath1, primPair(), SYM_CARET, formal(primPair(), SYM(z), false, false), formal(primInt(), SYM(y), false, false));
-#line 200 "runmath.in"
+#line 202 "runmath.in"
   addFunc(ve, run::gen_runmath2, primInt(), SYM(quotient), formal(primInt(), SYM(x), false, false), formal(primInt(), SYM(y), false, false));
-#line 205 "runmath.in"
+#line 207 "runmath.in"
   addFunc(ve, run::gen_runmath3, primInt(), SYM(abs), formal(primInt(), SYM(x), false, false));
-#line 210 "runmath.in"
+#line 212 "runmath.in"
   addFunc(ve, run::gen_runmath4, primInt(), SYM(sgn), formal(primReal(), SYM(x), false, false));
-#line 215 "runmath.in"
+#line 217 "runmath.in"
   addFunc(ve, run::gen_runmath5, primInt(), SYM(rand));
-#line 222 "runmath.in"
+#line 224 "runmath.in"
   addFunc(ve, run::gen_runmath6, primVoid(), SYM(srand), formal(primInt(), SYM(seed), false, false));
-#line 227 "runmath.in"
+#line 229 "runmath.in"
   addFunc(ve, run::gen_runmath7, primReal(), SYM(unitrand));
-#line 233 "runmath.in"
+#line 235 "runmath.in"
   addFunc(ve, run::gen_runmath8, primInt(), SYM(ceil), formal(primReal(), SYM(x), false, false));
-#line 238 "runmath.in"
+#line 240 "runmath.in"
   addFunc(ve, run::gen_runmath9, primInt(), SYM(floor), formal(primReal(), SYM(x), false, false));
-#line 243 "runmath.in"
+#line 245 "runmath.in"
   addFunc(ve, run::gen_runmath10, primInt(), SYM(round), formal(primReal(), SYM(x), false, false));
-#line 249 "runmath.in"
+#line 251 "runmath.in"
   addFunc(ve, run::gen_runmath11, primInt(), SYM(Ceil), formal(primReal(), SYM(x), false, false));
-#line 254 "runmath.in"
+#line 256 "runmath.in"
   addFunc(ve, run::gen_runmath12, primInt(), SYM(Floor), formal(primReal(), SYM(x), false, false));
-#line 259 "runmath.in"
+#line 261 "runmath.in"
   addFunc(ve, run::gen_runmath13, primInt(), SYM(Round), formal(primReal(), SYM(x), false, false));
-#line 264 "runmath.in"
+#line 266 "runmath.in"
   addFunc(ve, run::gen_runmath14, primReal(), SYM(fmod), formal(primReal(), SYM(x), false, false), formal(primReal(), SYM(y), false, false));
-#line 270 "runmath.in"
+#line 272 "runmath.in"
   addFunc(ve, run::gen_runmath15, primReal(), SYM(atan2), formal(primReal(), SYM(y), false, false), formal(primReal(), SYM(x), false, false));
-#line 275 "runmath.in"
+#line 277 "runmath.in"
   addFunc(ve, run::gen_runmath16, primReal(), SYM(hypot), formal(primReal(), SYM(x), false, false), formal(primReal(), SYM(y), false, false));
-#line 280 "runmath.in"
+#line 282 "runmath.in"
   addFunc(ve, run::gen_runmath17, primReal(), SYM(remainder), formal(primReal(), SYM(x), false, false), formal(primReal(), SYM(y), false, false));
-#line 285 "runmath.in"
+#line 287 "runmath.in"
   addFunc(ve, run::gen_runmath18, primReal(), SYM(Jn), formal(primInt(), SYM(n), false, false), formal(primReal(), SYM(x), false, false));
-#line 290 "runmath.in"
+#line 292 "runmath.in"
   addFunc(ve, run::gen_runmath19, primReal(), SYM(Yn), formal(primInt(), SYM(n), false, false), formal(primReal(), SYM(x), false, false));
-#line 295 "runmath.in"
+#line 297 "runmath.in"
   addFunc(ve, run::gen_runmath20, primReal(), SYM(erf), formal(primReal(), SYM(x), false, false));
-#line 300 "runmath.in"
+#line 302 "runmath.in"
   addFunc(ve, run::gen_runmath21, primReal(), SYM(erfc), formal(primReal(), SYM(x), false, false));
-#line 305 "runmath.in"
+#line 307 "runmath.in"
   addFunc(ve, run::gen_runmath22, primInt(), SYM(factorial), formal(primInt(), SYM(n), false, false));
-#line 310 "runmath.in"
+#line 312 "runmath.in"
   addFunc(ve, run::gen_runmath23, primInt(), SYM(choose), formal(primInt(), SYM(n), false, false), formal(primInt(), SYM(k), false, false));
-#line 321 "runmath.in"
+#line 323 "runmath.in"
   addFunc(ve, run::gen_runmath24, primReal(), SYM(gamma), formal(primReal(), SYM(x), false, false));
-#line 331 "runmath.in"
+#line 333 "runmath.in"
   addFunc(ve, run::gen_runmath25, realArray(), SYM(quadraticroots), formal(primReal(), SYM(a), false, false), formal(primReal(), SYM(b), false, false), formal(primReal(), SYM(c), false, false));
-#line 340 "runmath.in"
+#line 342 "runmath.in"
   addFunc(ve, run::gen_runmath26, pairArray(), SYM(quadraticroots), formal(primPair(), SYM(a), false, true), formal(primPair(), SYM(b), false, true), formal(primPair(), SYM(c), false, true));
-#line 349 "runmath.in"
+#line 351 "runmath.in"
   addFunc(ve, run::gen_runmath27, realArray(), SYM(cubicroots), formal(primReal(), SYM(a), false, false), formal(primReal(), SYM(b), false, false), formal(primReal(), SYM(c), false, false), formal(primReal(), SYM(d), false, false));
-#line 359 "runmath.in"
+#line 361 "runmath.in"
   addFunc(ve, run::gen_runmath28, primBoolean(), SYM_LOGNOT, formal(primBoolean(), SYM(b), false, false));
-#line 367 "runmath.in"
+#line 369 "runmath.in"
   REGISTER_BLTIN(run::boolMemEq,"boolMemEq");
-#line 372 "runmath.in"
+#line 374 "runmath.in"
   REGISTER_BLTIN(run::boolMemNeq,"boolMemNeq");
-#line 377 "runmath.in"
+#line 379 "runmath.in"
   REGISTER_BLTIN(run::boolFuncEq,"boolFuncEq");
-#line 382 "runmath.in"
+#line 384 "runmath.in"
   REGISTER_BLTIN(run::boolFuncNeq,"boolFuncNeq");
-#line 387 "runmath.in"
+#line 389 "runmath.in"
   addFunc(ve, run::gen_runmath33, primInt(), SYM(AND), formal(primInt(), SYM(a), false, false), formal(primInt(), SYM(b), false, false));
-#line 395 "runmath.in"
+#line 397 "runmath.in"
   addFunc(ve, run::gen_runmath34, primInt(), SYM(OR), formal(primInt(), SYM(a), false, false), formal(primInt(), SYM(b), false, false));
-#line 400 "runmath.in"
+#line 402 "runmath.in"
   addFunc(ve, run::gen_runmath35, primInt(), SYM(XOR), formal(primInt(), SYM(a), false, false), formal(primInt(), SYM(b), false, false));
-#line 405 "runmath.in"
+#line 407 "runmath.in"
   addFunc(ve, run::gen_runmath36, primInt(), SYM(NOT), formal(primInt(), SYM(a), false, false));
-#line 410 "runmath.in"
+#line 412 "runmath.in"
   addFunc(ve, run::gen_runmath37, primInt(), SYM(CLZ), formal(primInt(), SYM(a), false, false));
-#line 421 "runmath.in"
+#line 423 "runmath.in"
   addFunc(ve, run::gen_runmath38, primInt(), SYM(popcount), formal(primInt(), SYM(a), false, false));
-#line 426 "runmath.in"
+#line 428 "runmath.in"
   addFunc(ve, run::gen_runmath39, primInt(), SYM(CTZ), formal(primInt(), SYM(a), false, false));
-#line 431 "runmath.in"
+#line 433 "runmath.in"
   addFunc(ve, run::gen_runmath40, primInt(), SYM(bitreverse), formal(primInt(), SYM(a), false, false), formal(primInt(), SYM(bits), false, false));
 }
 

Modified: trunk/Build/source/utils/asymptote/runmath.in
===================================================================
--- trunk/Build/source/utils/asymptote/runmath.in	2020-03-03 22:33:26 UTC (rev 54033)
+++ trunk/Build/source/utils/asymptote/runmath.in	2020-03-03 22:35:09 UTC (rev 54034)
@@ -132,6 +132,7 @@
     ((unsigned long long) BitReverseTable8[(a >> 56)]);
 }
 
+#ifndef HAVE_POPCOUNT
 // https://graphics.stanford.edu/~seander/bithacks.html#CountBitsSetParallel
 #define T unsignedInt
 Int popcount(T a)
@@ -142,6 +143,7 @@
 return (T)(a*((T)~(T)0/255)) >> (sizeof(T)-1)*CHAR_BIT;
 }
 #undef T
+#endif
 
 // Return the factorial of a non-negative integer using a lookup table.
 Int factorial(Int n)

Modified: trunk/Build/source/utils/asymptote/runpair.cc
===================================================================
--- trunk/Build/source/utils/asymptote/runpair.cc	2020-03-03 22:33:26 UTC (rev 54033)
+++ trunk/Build/source/utils/asymptote/runpair.cc	2020-03-03 22:35:09 UTC (rev 54034)
@@ -184,58 +184,56 @@
   bool warn=vm::pop<bool>(Stack,true);
   pair z=vm::pop<pair>(Stack);
 #line 91 "runpair.in"
-  if(!warn && z.getx() == 0.0 && z.gety() == 0.0) {Stack->push<real>(0.0); return;}
-  {Stack->push<real>(z.angle()); return;}
+  {Stack->push<real>(z.angle(warn)); return;}
 }
 
 // Return the angle of z in degrees in the interval [0,360).
-#line 97 "runpair.in"
+#line 96 "runpair.in"
 // real degrees(pair z, bool warn=true);
 void gen_runpair9(stack *Stack)
 {
   bool warn=vm::pop<bool>(Stack,true);
   pair z=vm::pop<pair>(Stack);
-#line 98 "runpair.in"
-  if(!warn && z.getx() == 0.0 && z.gety() == 0.0) {Stack->push<real>(0.0); return;}
-  {Stack->push<real>(principalBranch(degrees(z.angle()))); return;}
+#line 97 "runpair.in"
+  {Stack->push<real>(principalBranch(degrees(z.angle(warn)))); return;}
 }
 
 // Convert degrees to radians.
-#line 104 "runpair.in"
+#line 102 "runpair.in"
 // real radians(real degrees);
 void gen_runpair10(stack *Stack)
 {
   real degrees=vm::pop<real>(Stack);
-#line 105 "runpair.in"
+#line 103 "runpair.in"
   {Stack->push<real>(radians(degrees)); return;}
 }
 
 // Convert radians to degrees.
-#line 110 "runpair.in"
+#line 108 "runpair.in"
 // real degrees(real radians);
 void gen_runpair11(stack *Stack)
 {
   real radians=vm::pop<real>(Stack);
-#line 111 "runpair.in"
+#line 109 "runpair.in"
   {Stack->push<real>(degrees(radians)); return;}
 }
 
 // Convert radians to degrees in [0,360).
-#line 116 "runpair.in"
+#line 114 "runpair.in"
 // real Degrees(real radians);
 void gen_runpair12(stack *Stack)
 {
   real radians=vm::pop<real>(Stack);
-#line 117 "runpair.in"
+#line 115 "runpair.in"
   {Stack->push<real>(principalBranch(degrees(radians))); return;}
 }
 
-#line 121 "runpair.in"
+#line 119 "runpair.in"
 // real Sin(real deg);
 void gen_runpair13(stack *Stack)
 {
   real deg=vm::pop<real>(Stack);
-#line 122 "runpair.in"
+#line 120 "runpair.in"
   int n=(int) (deg/90.0);
   if(deg == n*90.0) {
     int m=n % 4;
@@ -247,12 +245,12 @@
   {Stack->push<real>(sin(radians(deg))); return;}
 }
 
-#line 134 "runpair.in"
+#line 132 "runpair.in"
 // real Cos(real deg);
 void gen_runpair14(stack *Stack)
 {
   real deg=vm::pop<real>(Stack);
-#line 135 "runpair.in"
+#line 133 "runpair.in"
   int n=(int) (deg/90.0);
   if(deg == n*90.0) {
     int m=n % 4;
@@ -264,12 +262,12 @@
   {Stack->push<real>(cos(radians(deg))); return;}
 }
 
-#line 147 "runpair.in"
+#line 145 "runpair.in"
 // real Tan(real deg);
 void gen_runpair15(stack *Stack)
 {
   real deg=vm::pop<real>(Stack);
-#line 148 "runpair.in"
+#line 146 "runpair.in"
   int n=(int) (deg/90.0);
   if(deg == n*90.0) {
     int m=n % 4;
@@ -281,157 +279,157 @@
   {Stack->push<real>(tan(radians(deg))); return;}
 }
 
-#line 160 "runpair.in"
+#line 158 "runpair.in"
 // real aSin(real x);
 void gen_runpair16(stack *Stack)
 {
   real x=vm::pop<real>(Stack);
-#line 161 "runpair.in"
+#line 159 "runpair.in"
   {Stack->push<real>(degrees(asin(x))); return;}
 }
 
-#line 165 "runpair.in"
+#line 163 "runpair.in"
 // real aCos(real x);
 void gen_runpair17(stack *Stack)
 {
   real x=vm::pop<real>(Stack);
-#line 166 "runpair.in"
+#line 164 "runpair.in"
   {Stack->push<real>(degrees(acos(x))); return;}
 }
 
-#line 170 "runpair.in"
+#line 168 "runpair.in"
 // real aTan(real x);
 void gen_runpair18(stack *Stack)
 {
   real x=vm::pop<real>(Stack);
-#line 171 "runpair.in"
+#line 169 "runpair.in"
   {Stack->push<real>(degrees(atan(x))); return;}
 }
 
-#line 175 "runpair.in"
+#line 173 "runpair.in"
 // pair unit(pair z);
 void gen_runpair19(stack *Stack)
 {
   pair z=vm::pop<pair>(Stack);
-#line 176 "runpair.in"
+#line 174 "runpair.in"
   {Stack->push<pair>(unit(z)); return;}
 }
 
-#line 180 "runpair.in"
+#line 178 "runpair.in"
 // pair dir(real degrees);
 void gen_runpair20(stack *Stack)
 {
   real degrees=vm::pop<real>(Stack);
-#line 181 "runpair.in"
+#line 179 "runpair.in"
   {Stack->push<pair>(expi(radians(degrees))); return;}
 }
 
-#line 185 "runpair.in"
+#line 183 "runpair.in"
 // pair dir(explicit pair z);
 void gen_runpair21(stack *Stack)
 {
   pair z=vm::pop<pair>(Stack);
-#line 186 "runpair.in"
+#line 184 "runpair.in"
   {Stack->push<pair>(unit(z)); return;}
 }
 
-#line 190 "runpair.in"
+#line 188 "runpair.in"
 // pair expi(real angle);
 void gen_runpair22(stack *Stack)
 {
   real angle=vm::pop<real>(Stack);
-#line 191 "runpair.in"
+#line 189 "runpair.in"
   {Stack->push<pair>(expi(angle)); return;}
 }
 
-#line 195 "runpair.in"
+#line 193 "runpair.in"
 // pair exp(explicit pair z);
 void gen_runpair23(stack *Stack)
 {
   pair z=vm::pop<pair>(Stack);
-#line 196 "runpair.in" 
+#line 194 "runpair.in" 
   {Stack->push<pair>(exp(z)); return;}
 }
 
-#line 200 "runpair.in"
+#line 198 "runpair.in"
 // pair log(explicit pair z);
 void gen_runpair24(stack *Stack)
 {
   pair z=vm::pop<pair>(Stack);
-#line 201 "runpair.in" 
+#line 199 "runpair.in" 
   {Stack->push<pair>(pair(log(z.length()),z.angle())); return;}
 }
 
-#line 205 "runpair.in"
+#line 203 "runpair.in"
 // pair sin(explicit pair z);
 void gen_runpair25(stack *Stack)
 {
   pair z=vm::pop<pair>(Stack);
-#line 206 "runpair.in" 
+#line 204 "runpair.in" 
   {Stack->push<pair>(sin(z)); return;}
 }
 
-#line 210 "runpair.in"
+#line 208 "runpair.in"
 // pair cos(explicit pair z);
 void gen_runpair26(stack *Stack)
 {
   pair z=vm::pop<pair>(Stack);
-#line 211 "runpair.in" 
+#line 209 "runpair.in" 
   {Stack->push<pair>(pair(cos(z.getx())*cosh(z.gety()),-sin(z.getx())*sinh(z.gety()))); return;} 
 }
 
 // Complex Gamma function
-#line 216 "runpair.in"
+#line 214 "runpair.in"
 // pair gamma(explicit pair z);
 void gen_runpair27(stack *Stack)
 {
   pair z=vm::pop<pair>(Stack);
-#line 217 "runpair.in"
+#line 215 "runpair.in"
   {Stack->push<pair>(gamma(z)); return;}
 }
 
-#line 221 "runpair.in"
+#line 219 "runpair.in"
 // pair conj(pair z);
 void gen_runpair28(stack *Stack)
 {
   pair z=vm::pop<pair>(Stack);
-#line 222 "runpair.in"
+#line 220 "runpair.in"
   {Stack->push<pair>(conj(z)); return;}
 }
 
-#line 226 "runpair.in"
+#line 224 "runpair.in"
 // pair realmult(pair z, pair w);
 void gen_runpair29(stack *Stack)
 {
   pair w=vm::pop<pair>(Stack);
   pair z=vm::pop<pair>(Stack);
-#line 227 "runpair.in"
+#line 225 "runpair.in"
   {Stack->push<pair>(pair(z.getx()*w.getx(),z.gety()*w.gety())); return;}
 }
 
 // To avoid confusion, a dot product requires explicit pair arguments.
-#line 232 "runpair.in"
+#line 230 "runpair.in"
 // real dot(explicit pair z, explicit pair w);
 void gen_runpair30(stack *Stack)
 {
   pair w=vm::pop<pair>(Stack);
   pair z=vm::pop<pair>(Stack);
-#line 233 "runpair.in"
+#line 231 "runpair.in"
   {Stack->push<real>(dot(z,w)); return;}
 }
 
 // Return the 2D scalar cross product z.x*w.y-z.y*w.x.
-#line 238 "runpair.in"
+#line 236 "runpair.in"
 // real cross(explicit pair z, explicit pair w);
 void gen_runpair31(stack *Stack)
 {
   pair w=vm::pop<pair>(Stack);
   pair z=vm::pop<pair>(Stack);
-#line 239 "runpair.in"
+#line 237 "runpair.in"
   {Stack->push<real>(cross(z,w)); return;}
 }
 
-#line 243 "runpair.in"
+#line 241 "runpair.in"
 // pair bezier(pair a, pair b, pair c, pair d, real t);
 void gen_runpair32(stack *Stack)
 {
@@ -440,13 +438,13 @@
   pair c=vm::pop<pair>(Stack);
   pair b=vm::pop<pair>(Stack);
   pair a=vm::pop<pair>(Stack);
-#line 244 "runpair.in"
+#line 242 "runpair.in"
   real onemt=1-t;
   real onemt2=onemt*onemt;
   {Stack->push<pair>(onemt2*onemt*a+t*(3.0*(onemt2*b+t*onemt*c)+t*t*d)); return;}
 }
 
-#line 250 "runpair.in"
+#line 248 "runpair.in"
 // pair bezierP(pair a, pair b, pair c, pair d, real t);
 void gen_runpair33(stack *Stack)
 {
@@ -455,11 +453,11 @@
   pair c=vm::pop<pair>(Stack);
   pair b=vm::pop<pair>(Stack);
   pair a=vm::pop<pair>(Stack);
-#line 251 "runpair.in"
+#line 249 "runpair.in"
   {Stack->push<pair>(3.0*(t*t*(d-a+3.0*(b-c))+t*(2.0*(a+c)-4.0*b)+b-a)); return;}
 }
 
-#line 255 "runpair.in"
+#line 253 "runpair.in"
 // pair bezierPP(pair a, pair b, pair c, pair d, real t);
 void gen_runpair34(stack *Stack)
 {
@@ -468,11 +466,11 @@
   pair c=vm::pop<pair>(Stack);
   pair b=vm::pop<pair>(Stack);
   pair a=vm::pop<pair>(Stack);
-#line 256 "runpair.in"
-  {Stack->push<pair>(6.0*(t*(d-a+3.0*(b-c))+a+c-2.0*b)); return;}
+#line 254 "runpair.in"
+  {Stack->push<pair>(6.0*(t*(d-a+3.0*(b-c))+a+c)-12.0*b); return;}
 }
 
-#line 260 "runpair.in"
+#line 258 "runpair.in"
 // pair bezierPPP(pair a, pair b, pair c, pair d);
 void gen_runpair35(stack *Stack)
 {
@@ -480,8 +478,8 @@
   pair c=vm::pop<pair>(Stack);
   pair b=vm::pop<pair>(Stack);
   pair a=vm::pop<pair>(Stack);
-#line 261 "runpair.in"
-  {Stack->push<pair>(6.0*(d-a+3.0*(b-c))); return;}
+#line 259 "runpair.in"
+  {Stack->push<pair>(6.0*(d-a)+18.0*(b-c)); return;}
 }
 
 } // namespace run
@@ -508,59 +506,59 @@
   addFunc(ve, run::gen_runpair7, primPair(), SYM(sqrt), formal(primPair(), SYM(z), false, true));
 #line 89 "runpair.in"
   addFunc(ve, run::gen_runpair8, primReal(), SYM(angle), formal(primPair(), SYM(z), false, false), formal(primBoolean(), SYM(warn), true, false));
-#line 96 "runpair.in"
+#line 95 "runpair.in"
   addFunc(ve, run::gen_runpair9, primReal(), SYM(degrees), formal(primPair(), SYM(z), false, false), formal(primBoolean(), SYM(warn), true, false));
-#line 103 "runpair.in"
+#line 101 "runpair.in"
   addFunc(ve, run::gen_runpair10, primReal(), SYM(radians), formal(primReal(), SYM(degrees), false, false));
-#line 109 "runpair.in"
+#line 107 "runpair.in"
   addFunc(ve, run::gen_runpair11, primReal(), SYM(degrees), formal(primReal(), SYM(radians), false, false));
-#line 115 "runpair.in"
+#line 113 "runpair.in"
   addFunc(ve, run::gen_runpair12, primReal(), SYM(Degrees), formal(primReal(), SYM(radians), false, false));
-#line 121 "runpair.in"
+#line 119 "runpair.in"
   addFunc(ve, run::gen_runpair13, primReal(), SYM(Sin), formal(primReal(), SYM(deg), false, false));
-#line 134 "runpair.in"
+#line 132 "runpair.in"
   addFunc(ve, run::gen_runpair14, primReal(), SYM(Cos), formal(primReal(), SYM(deg), false, false));
-#line 147 "runpair.in"
+#line 145 "runpair.in"
   addFunc(ve, run::gen_runpair15, primReal(), SYM(Tan), formal(primReal(), SYM(deg), false, false));
-#line 160 "runpair.in"
+#line 158 "runpair.in"
   addFunc(ve, run::gen_runpair16, primReal(), SYM(aSin), formal(primReal(), SYM(x), false, false));
-#line 165 "runpair.in"
+#line 163 "runpair.in"
   addFunc(ve, run::gen_runpair17, primReal(), SYM(aCos), formal(primReal(), SYM(x), false, false));
-#line 170 "runpair.in"
+#line 168 "runpair.in"
   addFunc(ve, run::gen_runpair18, primReal(), SYM(aTan), formal(primReal(), SYM(x), false, false));
-#line 175 "runpair.in"
+#line 173 "runpair.in"
   addFunc(ve, run::gen_runpair19, primPair(), SYM(unit), formal(primPair(), SYM(z), false, false));
-#line 180 "runpair.in"
+#line 178 "runpair.in"
   addFunc(ve, run::gen_runpair20, primPair(), SYM(dir), formal(primReal(), SYM(degrees), false, false));
-#line 185 "runpair.in"
+#line 183 "runpair.in"
   addFunc(ve, run::gen_runpair21, primPair(), SYM(dir), formal(primPair(), SYM(z), false, true));
-#line 190 "runpair.in"
+#line 188 "runpair.in"
   addFunc(ve, run::gen_runpair22, primPair(), SYM(expi), formal(primReal(), SYM(angle), false, false));
-#line 195 "runpair.in"
+#line 193 "runpair.in"
   addFunc(ve, run::gen_runpair23, primPair(), SYM(exp), formal(primPair(), SYM(z), false, true));
-#line 200 "runpair.in"
+#line 198 "runpair.in"
   addFunc(ve, run::gen_runpair24, primPair(), SYM(log), formal(primPair(), SYM(z), false, true));
-#line 205 "runpair.in"
+#line 203 "runpair.in"
   addFunc(ve, run::gen_runpair25, primPair(), SYM(sin), formal(primPair(), SYM(z), false, true));
-#line 210 "runpair.in"
+#line 208 "runpair.in"
   addFunc(ve, run::gen_runpair26, primPair(), SYM(cos), formal(primPair(), SYM(z), false, true));
-#line 215 "runpair.in"
+#line 213 "runpair.in"
   addFunc(ve, run::gen_runpair27, primPair(), SYM(gamma), formal(primPair(), SYM(z), false, true));
-#line 221 "runpair.in"
+#line 219 "runpair.in"
   addFunc(ve, run::gen_runpair28, primPair(), SYM(conj), formal(primPair(), SYM(z), false, false));
-#line 226 "runpair.in"
+#line 224 "runpair.in"
   addFunc(ve, run::gen_runpair29, primPair(), SYM(realmult), formal(primPair(), SYM(z), false, false), formal(primPair(), SYM(w), false, false));
-#line 231 "runpair.in"
+#line 229 "runpair.in"
   addFunc(ve, run::gen_runpair30, primReal(), SYM(dot), formal(primPair(), SYM(z), false, true), formal(primPair(), SYM(w), false, true));
-#line 237 "runpair.in"
+#line 235 "runpair.in"
   addFunc(ve, run::gen_runpair31, primReal(), SYM(cross), formal(primPair(), SYM(z), false, true), formal(primPair(), SYM(w), false, true));
-#line 243 "runpair.in"
+#line 241 "runpair.in"
   addFunc(ve, run::gen_runpair32, primPair(), SYM(bezier), formal(primPair(), SYM(a), false, false), formal(primPair(), SYM(b), false, false), formal(primPair(), SYM(c), false, false), formal(primPair(), SYM(d), false, false), formal(primReal(), SYM(t), false, false));
-#line 250 "runpair.in"
+#line 248 "runpair.in"
   addFunc(ve, run::gen_runpair33, primPair(), SYM(bezierP), formal(primPair(), SYM(a), false, false), formal(primPair(), SYM(b), false, false), formal(primPair(), SYM(c), false, false), formal(primPair(), SYM(d), false, false), formal(primReal(), SYM(t), false, false));
-#line 255 "runpair.in"
+#line 253 "runpair.in"
   addFunc(ve, run::gen_runpair34, primPair(), SYM(bezierPP), formal(primPair(), SYM(a), false, false), formal(primPair(), SYM(b), false, false), formal(primPair(), SYM(c), false, false), formal(primPair(), SYM(d), false, false), formal(primReal(), SYM(t), false, false));
-#line 260 "runpair.in"
+#line 258 "runpair.in"
   addFunc(ve, run::gen_runpair35, primPair(), SYM(bezierPPP), formal(primPair(), SYM(a), false, false), formal(primPair(), SYM(b), false, false), formal(primPair(), SYM(c), false, false), formal(primPair(), SYM(d), false, false));
 }
 

Modified: trunk/Build/source/utils/asymptote/runpair.in
===================================================================
--- trunk/Build/source/utils/asymptote/runpair.in	2020-03-03 22:33:26 UTC (rev 54033)
+++ trunk/Build/source/utils/asymptote/runpair.in	2020-03-03 22:35:09 UTC (rev 54034)
@@ -89,15 +89,13 @@
 // Return the angle of z in radians.
 real angle(pair z, bool warn=true)
 {
-  if(!warn && z.getx() == 0.0 && z.gety() == 0.0) return 0.0;
-  return z.angle();
+  return z.angle(warn);
 }
 

 // Return the angle of z in degrees in the interval [0,360).
 real degrees(pair z, bool warn=true)
 {
-  if(!warn && z.getx() == 0.0 && z.gety() == 0.0) return 0.0;
-  return principalBranch(degrees(z.angle()));
+  return principalBranch(degrees(z.angle(warn)));
 }
 

 // Convert degrees to radians.
@@ -254,10 +252,10 @@
 

 pair bezierPP(pair a, pair b, pair c, pair d, real t) 
 {
-  return 6.0*(t*(d-a+3.0*(b-c))+a+c-2.0*b);
+  return 6.0*(t*(d-a+3.0*(b-c))+a+c)-12.0*b;
 }
 

 pair bezierPPP(pair a, pair b, pair c, pair d) 
 {
-  return 6.0*(d-a+3.0*(b-c));
+  return 6.0*(d-a)+18.0*(b-c);
 }

Modified: trunk/Build/source/utils/asymptote/runpath.cc
===================================================================
--- trunk/Build/source/utils/asymptote/runpath.cc	2020-03-03 22:33:26 UTC (rev 54033)
+++ trunk/Build/source/utils/asymptote/runpath.cc	2020-03-03 22:35:09 UTC (rev 54034)
@@ -347,33 +347,45 @@
 }
 
 #line 172 "runpath.in"
-// real arctime(path p, real L);
+// real arclength(pair z0, pair c0, pair c1, pair z1);
 void gen_runpath24(stack *Stack)
 {
+  pair z1=vm::pop<pair>(Stack);
+  pair c1=vm::pop<pair>(Stack);
+  pair c0=vm::pop<pair>(Stack);
+  pair z0=vm::pop<pair>(Stack);
+#line 173 "runpath.in"
+  {Stack->push<real>(arcLength(z0,c0,c1,z1)); return;}
+}
+
+#line 177 "runpath.in"
+// real arctime(path p, real L);
+void gen_runpath25(stack *Stack)
+{
   real L=vm::pop<real>(Stack);
   path p=vm::pop<path>(Stack);
-#line 173 "runpath.in"
+#line 178 "runpath.in"
   {Stack->push<real>(p.arctime(L)); return;}
 }
 
-#line 177 "runpath.in"
+#line 182 "runpath.in"
 // real dirtime(path p, pair z);
-void gen_runpath25(stack *Stack)
+void gen_runpath26(stack *Stack)
 {
   pair z=vm::pop<pair>(Stack);
   path p=vm::pop<path>(Stack);
-#line 178 "runpath.in"
+#line 183 "runpath.in"
   {Stack->push<real>(p.directiontime(z)); return;}
 }
 
-#line 182 "runpath.in"
+#line 187 "runpath.in"
 // realarray* intersect(path p, path q, real fuzz=-1);
-void gen_runpath26(stack *Stack)
+void gen_runpath27(stack *Stack)
 {
   real fuzz=vm::pop<real>(Stack,-1);
   path q=vm::pop<path>(Stack);
   path p=vm::pop<path>(Stack);
-#line 183 "runpath.in"
+#line 188 "runpath.in"
   bool exact=fuzz <= 0.0;
   if(fuzz < 0)
     fuzz=BigFuzz*::max(::max(length(p.max()),length(p.min())),
@@ -389,14 +401,14 @@
   {Stack->push<realarray*>(new array(0)); return;}
 }
 
-#line 199 "runpath.in"
+#line 204 "runpath.in"
 // realarray2* intersections(path p, path q, real fuzz=-1);
-void gen_runpath27(stack *Stack)
+void gen_runpath28(stack *Stack)
 {
   real fuzz=vm::pop<real>(Stack,-1);
   path q=vm::pop<path>(Stack);
   path p=vm::pop<path>(Stack);
-#line 200 "runpath.in"
+#line 205 "runpath.in"
   bool exact=fuzz <= 0.0;
   if(fuzz < 0.0)
     fuzz=BigFuzz*::max(::max(length(p.max()),length(p.min())),
@@ -426,15 +438,15 @@
   {Stack->push<realarray2*>(V); return;}
 }
 
-#line 230 "runpath.in"
+#line 235 "runpath.in"
 // realarray* intersections(path p, explicit pair a, explicit pair b, real fuzz=-1);
-void gen_runpath28(stack *Stack)
+void gen_runpath29(stack *Stack)
 {
   real fuzz=vm::pop<real>(Stack,-1);
   pair b=vm::pop<pair>(Stack);
   pair a=vm::pop<pair>(Stack);
   path p=vm::pop<path>(Stack);
-#line 231 "runpath.in"
+#line 236 "runpath.in"
   if(fuzz < 0)
     fuzz=BigFuzz*::max(::max(length(p.max()),length(p.min())),
                        ::max(length(a),length(b)));
@@ -450,15 +462,15 @@
 
 // Return the intersection point of the extensions of the line segments 
 // PQ and pq.
-#line 247 "runpath.in"
+#line 252 "runpath.in"
 // pair extension(pair P, pair Q, pair p, pair q);
-void gen_runpath29(stack *Stack)
+void gen_runpath30(stack *Stack)
 {
   pair q=vm::pop<pair>(Stack);
   pair p=vm::pop<pair>(Stack);
   pair Q=vm::pop<pair>(Stack);
   pair P=vm::pop<pair>(Stack);
-#line 248 "runpath.in"
+#line 253 "runpath.in"
   pair ac=P-Q;
   pair bd=q-p;
   real det=ac.getx()*bd.gety()-ac.gety()*bd.getx();
@@ -466,49 +478,49 @@
   {Stack->push<pair>(P+((p.getx()-P.getx())*bd.gety()-(p.gety()-P.gety())*bd.getx())*ac/det); return;}
 }
 
-#line 256 "runpath.in"
+#line 261 "runpath.in"
 // Int size(path p);
-void gen_runpath30(stack *Stack)
+void gen_runpath31(stack *Stack)
 {
   path p=vm::pop<path>(Stack);
-#line 257 "runpath.in"
+#line 262 "runpath.in"
   {Stack->push<Int>(p.size()); return;}
 }
 
-#line 261 "runpath.in"
+#line 266 "runpath.in"
 // path &(path p, path q);
-void gen_runpath31(stack *Stack)
+void gen_runpath32(stack *Stack)
 {
   path q=vm::pop<path>(Stack);
   path p=vm::pop<path>(Stack);
-#line 262 "runpath.in"
+#line 267 "runpath.in"
   {Stack->push<path>(camp::concat(p,q)); return;}
 }
 
-#line 266 "runpath.in"
+#line 271 "runpath.in"
 // pair min(explicit path p);
-void gen_runpath32(stack *Stack)
+void gen_runpath33(stack *Stack)
 {
   path p=vm::pop<path>(Stack);
-#line 267 "runpath.in"
+#line 272 "runpath.in"
   {Stack->push<pair>(p.min()); return;}
 }
 
-#line 271 "runpath.in"
+#line 276 "runpath.in"
 // pair max(explicit path p);
-void gen_runpath33(stack *Stack)
+void gen_runpath34(stack *Stack)
 {
   path p=vm::pop<path>(Stack);
-#line 272 "runpath.in"
+#line 277 "runpath.in"
   {Stack->push<pair>(p.max()); return;}
 }
 
-#line 276 "runpath.in"
+#line 281 "runpath.in"
 // Int size(patharray *p);
-void gen_runpath34(stack *Stack)
+void gen_runpath35(stack *Stack)
 {
   patharray * p=vm::pop<patharray *>(Stack);
-#line 277 "runpath.in" 
+#line 282 "runpath.in" 
   size_t size=checkArray(p);
   Int count=0;
   for (size_t i = 0; i < size; i++)
@@ -516,12 +528,12 @@
   {Stack->push<Int>(count); return;}
 }
 
-#line 285 "runpath.in"
+#line 290 "runpath.in"
 // pair min(patharray *p);
-void gen_runpath35(stack *Stack)
+void gen_runpath36(stack *Stack)
 {
   patharray * p=vm::pop<patharray *>(Stack);
-#line 286 "runpath.in" 
+#line 291 "runpath.in" 
   size_t size=checkArray(p);
 
   if(size == 0)
@@ -544,12 +556,12 @@
   {Stack->push<pair>(pair(minx, miny)); return;}
 }
 
-#line 309 "runpath.in"
+#line 314 "runpath.in"
 // pair max(patharray *p);
-void gen_runpath36(stack *Stack)
+void gen_runpath37(stack *Stack)
 {
   patharray * p=vm::pop<patharray *>(Stack);
-#line 310 "runpath.in" 
+#line 315 "runpath.in" 
   size_t size=checkArray(p);
 
   if(size == 0)
@@ -572,13 +584,13 @@
   {Stack->push<pair>(pair(maxx, maxy)); return;}
 }
 
-#line 333 "runpath.in"
+#line 338 "runpath.in"
 // pair minAfterTransform(transform t, patharray *p);
-void gen_runpath37(stack *Stack)
+void gen_runpath38(stack *Stack)
 {
   patharray * p=vm::pop<patharray *>(Stack);
   transform t=vm::pop<transform>(Stack);
-#line 334 "runpath.in" 
+#line 339 "runpath.in" 
   size_t size=checkArray(p);
 
   if(size == 0)
@@ -601,13 +613,13 @@
   {Stack->push<pair>(pair(minx, miny)); return;}
 }
 
-#line 357 "runpath.in"
+#line 362 "runpath.in"
 // pair maxAfterTransform(transform t, patharray *p);
-void gen_runpath38(stack *Stack)
+void gen_runpath39(stack *Stack)
 {
   patharray * p=vm::pop<patharray *>(Stack);
   transform t=vm::pop<transform>(Stack);
-#line 358 "runpath.in" 
+#line 363 "runpath.in" 
   size_t size=checkArray(p);
 
   if(size == 0)
@@ -630,12 +642,12 @@
   {Stack->push<pair>(pair(maxx, maxy)); return;}
 }
 
-#line 381 "runpath.in"
+#line 386 "runpath.in"
 // realarray* mintimes(path p);
-void gen_runpath39(stack *Stack)
+void gen_runpath40(stack *Stack)
 {
   path p=vm::pop<path>(Stack);
-#line 382 "runpath.in"
+#line 387 "runpath.in"
   array *V=new array(2);
   pair z=p.mintimes();
   (*V)[0]=z.getx();
@@ -643,12 +655,12 @@
   {Stack->push<realarray*>(V); return;}
 }
 
-#line 390 "runpath.in"
+#line 395 "runpath.in"
 // realarray* maxtimes(path p);
-void gen_runpath40(stack *Stack)
+void gen_runpath41(stack *Stack)
 {
   path p=vm::pop<path>(Stack);
-#line 391 "runpath.in"
+#line 396 "runpath.in"
   array *V=new array(2);
   pair z=p.maxtimes();
   (*V)[0]=z.getx();
@@ -656,47 +668,47 @@
   {Stack->push<realarray*>(V); return;}
 }
 
-#line 399 "runpath.in"
+#line 404 "runpath.in"
 // real relativedistance(real theta, real phi, real t, bool atleast);
-void gen_runpath41(stack *Stack)
+void gen_runpath42(stack *Stack)
 {
   bool atleast=vm::pop<bool>(Stack);
   real t=vm::pop<real>(Stack);
   real phi=vm::pop<real>(Stack);
   real theta=vm::pop<real>(Stack);
-#line 400 "runpath.in"
+#line 405 "runpath.in"
   {Stack->push<real>(camp::velocity(theta,phi,tension(t,atleast))); return;}
 }
 
-#line 404 "runpath.in"
+#line 409 "runpath.in"
 // Int windingnumber(patharray *p, pair z);
-void gen_runpath42(stack *Stack)
+void gen_runpath43(stack *Stack)
 {
   pair z=vm::pop<pair>(Stack);
   patharray * p=vm::pop<patharray *>(Stack);
-#line 405 "runpath.in"
+#line 410 "runpath.in"
   {Stack->push<Int>(windingnumber(p,z)); return;}
 }
 
-#line 409 "runpath.in"
+#line 414 "runpath.in"
 // bool inside(explicit patharray *g, pair z, pen fillrule=CURRENTPEN);
-void gen_runpath43(stack *Stack)
+void gen_runpath44(stack *Stack)
 {
   pen fillrule=vm::pop<pen>(Stack,CURRENTPEN);
   pair z=vm::pop<pair>(Stack);
   patharray * g=vm::pop<patharray *>(Stack);
-#line 410 "runpath.in"
+#line 415 "runpath.in"
   {Stack->push<bool>(fillrule.inside(windingnumber(g,z))); return;}
 }
 
-#line 414 "runpath.in"
+#line 419 "runpath.in"
 // bool inside(path g, pair z, pen fillrule=CURRENTPEN);
-void gen_runpath44(stack *Stack)
+void gen_runpath45(stack *Stack)
 {
   pen fillrule=vm::pop<pen>(Stack,CURRENTPEN);
   pair z=vm::pop<pair>(Stack);
   path g=vm::pop<path>(Stack);
-#line 415 "runpath.in"
+#line 420 "runpath.in"
   {Stack->push<bool>(fillrule.inside(g.windingnumber(z))); return;}
 }
 
@@ -709,14 +721,14 @@
 // |b.x b.y 1|
 // |c.x c.y 1|
 // 
-#line 428 "runpath.in"
+#line 433 "runpath.in"
 // real orient(pair a, pair b, pair c);
-void gen_runpath45(stack *Stack)
+void gen_runpath46(stack *Stack)
 {
   pair c=vm::pop<pair>(Stack);
   pair b=vm::pop<pair>(Stack);
   pair a=vm::pop<pair>(Stack);
-#line 429 "runpath.in"
+#line 434 "runpath.in"
   {Stack->push<real>(orient2d(a,b,c)); return;}
 }
 
@@ -728,15 +740,15 @@
 // |b.x b.y b.x^2+b.y^2 1|
 // |c.x c.y c.x^2+c.y^2 1|
 // |d.x d.y d.x^2+d.y^2 1|
-#line 441 "runpath.in"
+#line 446 "runpath.in"
 // real incircle(pair a, pair b, pair c, pair d);
-void gen_runpath46(stack *Stack)
+void gen_runpath47(stack *Stack)
 {
   pair d=vm::pop<pair>(Stack);
   pair c=vm::pop<pair>(Stack);
   pair b=vm::pop<pair>(Stack);
   pair a=vm::pop<pair>(Stack);
-#line 442 "runpath.in"
+#line 447 "runpath.in"
   {Stack->push<real>(incircle(a.getx(),a.gety(),b.getx(),b.gety(),c.getx(),c.gety(),
                   d.getx(),d.gety())); return;}
 }
@@ -796,51 +808,53 @@
 #line 167 "runpath.in"
   addFunc(ve, run::gen_runpath23, primReal(), SYM(arclength), formal(primPath(), SYM(p), false, false));
 #line 172 "runpath.in"
-  addFunc(ve, run::gen_runpath24, primReal(), SYM(arctime), formal(primPath(), SYM(p), false, false), formal(primReal(), SYM(l), false, false));
+  addFunc(ve, run::gen_runpath24, primReal(), SYM(arclength), formal(primPair(), SYM(z0), false, false), formal(primPair(), SYM(c0), false, false), formal(primPair(), SYM(c1), false, false), formal(primPair(), SYM(z1), false, false));
 #line 177 "runpath.in"
-  addFunc(ve, run::gen_runpath25, primReal(), SYM(dirtime), formal(primPath(), SYM(p), false, false), formal(primPair(), SYM(z), false, false));
+  addFunc(ve, run::gen_runpath25, primReal(), SYM(arctime), formal(primPath(), SYM(p), false, false), formal(primReal(), SYM(l), false, false));
 #line 182 "runpath.in"
-  addFunc(ve, run::gen_runpath26, realArray(), SYM(intersect), formal(primPath(), SYM(p), false, false), formal(primPath(), SYM(q), false, false), formal(primReal(), SYM(fuzz), true, false));
-#line 199 "runpath.in"
-  addFunc(ve, run::gen_runpath27, realArray2(), SYM(intersections), formal(primPath(), SYM(p), false, false), formal(primPath(), SYM(q), false, false), formal(primReal(), SYM(fuzz), true, false));
-#line 230 "runpath.in"
-  addFunc(ve, run::gen_runpath28, realArray(), SYM(intersections), formal(primPath(), SYM(p), false, false), formal(primPair(), SYM(a), false, true), formal(primPair(), SYM(b), false, true), formal(primReal(), SYM(fuzz), true, false));
-#line 245 "runpath.in"
-  addFunc(ve, run::gen_runpath29, primPair(), SYM(extension), formal(primPair(), SYM(p), false, false), formal(primPair(), SYM(q), false, false), formal(primPair(), SYM(p), false, false), formal(primPair(), SYM(q), false, false));
-#line 256 "runpath.in"
-  addFunc(ve, run::gen_runpath30, primInt(), SYM(size), formal(primPath(), SYM(p), false, false));
+  addFunc(ve, run::gen_runpath26, primReal(), SYM(dirtime), formal(primPath(), SYM(p), false, false), formal(primPair(), SYM(z), false, false));
+#line 187 "runpath.in"
+  addFunc(ve, run::gen_runpath27, realArray(), SYM(intersect), formal(primPath(), SYM(p), false, false), formal(primPath(), SYM(q), false, false), formal(primReal(), SYM(fuzz), true, false));
+#line 204 "runpath.in"
+  addFunc(ve, run::gen_runpath28, realArray2(), SYM(intersections), formal(primPath(), SYM(p), false, false), formal(primPath(), SYM(q), false, false), formal(primReal(), SYM(fuzz), true, false));
+#line 235 "runpath.in"
+  addFunc(ve, run::gen_runpath29, realArray(), SYM(intersections), formal(primPath(), SYM(p), false, false), formal(primPair(), SYM(a), false, true), formal(primPair(), SYM(b), false, true), formal(primReal(), SYM(fuzz), true, false));
+#line 250 "runpath.in"
+  addFunc(ve, run::gen_runpath30, primPair(), SYM(extension), formal(primPair(), SYM(p), false, false), formal(primPair(), SYM(q), false, false), formal(primPair(), SYM(p), false, false), formal(primPair(), SYM(q), false, false));
 #line 261 "runpath.in"
-  addFunc(ve, run::gen_runpath31, primPath(), SYM_AMPERSAND, formal(primPath(), SYM(p), false, false), formal(primPath(), SYM(q), false, false));
+  addFunc(ve, run::gen_runpath31, primInt(), SYM(size), formal(primPath(), SYM(p), false, false));
 #line 266 "runpath.in"
-  addFunc(ve, run::gen_runpath32, primPair(), SYM(min), formal(primPath(), SYM(p), false, true));
+  addFunc(ve, run::gen_runpath32, primPath(), SYM_AMPERSAND, formal(primPath(), SYM(p), false, false), formal(primPath(), SYM(q), false, false));
 #line 271 "runpath.in"
-  addFunc(ve, run::gen_runpath33, primPair(), SYM(max), formal(primPath(), SYM(p), false, true));
+  addFunc(ve, run::gen_runpath33, primPair(), SYM(min), formal(primPath(), SYM(p), false, true));
 #line 276 "runpath.in"
-  addFunc(ve, run::gen_runpath34, primInt(), SYM(size), formal(pathArray()  , SYM(p), false, false));
-#line 285 "runpath.in"
-  addFunc(ve, run::gen_runpath35, primPair(), SYM(min), formal(pathArray()  , SYM(p), false, false));
-#line 309 "runpath.in"
-  addFunc(ve, run::gen_runpath36, primPair(), SYM(max), formal(pathArray()  , SYM(p), false, false));
-#line 333 "runpath.in"
-  addFunc(ve, run::gen_runpath37, primPair(), SYM(minAfterTransform), formal(primTransform(), SYM(t), false, false), formal(pathArray()  , SYM(p), false, false));
-#line 357 "runpath.in"
-  addFunc(ve, run::gen_runpath38, primPair(), SYM(maxAfterTransform), formal(primTransform(), SYM(t), false, false), formal(pathArray()  , SYM(p), false, false));
-#line 381 "runpath.in"
-  addFunc(ve, run::gen_runpath39, realArray(), SYM(mintimes), formal(primPath(), SYM(p), false, false));
-#line 390 "runpath.in"
-  addFunc(ve, run::gen_runpath40, realArray(), SYM(maxtimes), formal(primPath(), SYM(p), false, false));
-#line 399 "runpath.in"
-  addFunc(ve, run::gen_runpath41, primReal(), SYM(relativedistance), formal(primReal(), SYM(theta), false, false), formal(primReal(), SYM(phi), false, false), formal(primReal(), SYM(t), false, false), formal(primBoolean(), SYM(atleast), false, false));
+  addFunc(ve, run::gen_runpath34, primPair(), SYM(max), formal(primPath(), SYM(p), false, true));
+#line 281 "runpath.in"
+  addFunc(ve, run::gen_runpath35, primInt(), SYM(size), formal(pathArray()  , SYM(p), false, false));
+#line 290 "runpath.in"
+  addFunc(ve, run::gen_runpath36, primPair(), SYM(min), formal(pathArray()  , SYM(p), false, false));
+#line 314 "runpath.in"
+  addFunc(ve, run::gen_runpath37, primPair(), SYM(max), formal(pathArray()  , SYM(p), false, false));
+#line 338 "runpath.in"
+  addFunc(ve, run::gen_runpath38, primPair(), SYM(minAfterTransform), formal(primTransform(), SYM(t), false, false), formal(pathArray()  , SYM(p), false, false));
+#line 362 "runpath.in"
+  addFunc(ve, run::gen_runpath39, primPair(), SYM(maxAfterTransform), formal(primTransform(), SYM(t), false, false), formal(pathArray()  , SYM(p), false, false));
+#line 386 "runpath.in"
+  addFunc(ve, run::gen_runpath40, realArray(), SYM(mintimes), formal(primPath(), SYM(p), false, false));
+#line 395 "runpath.in"
+  addFunc(ve, run::gen_runpath41, realArray(), SYM(maxtimes), formal(primPath(), SYM(p), false, false));
 #line 404 "runpath.in"
-  addFunc(ve, run::gen_runpath42, primInt(), SYM(windingnumber), formal(pathArray()  , SYM(p), false, false), formal(primPair(), SYM(z), false, false));
+  addFunc(ve, run::gen_runpath42, primReal(), SYM(relativedistance), formal(primReal(), SYM(theta), false, false), formal(primReal(), SYM(phi), false, false), formal(primReal(), SYM(t), false, false), formal(primBoolean(), SYM(atleast), false, false));
 #line 409 "runpath.in"
-  addFunc(ve, run::gen_runpath43, primBoolean(), SYM(inside), formal(pathArray()  , SYM(g), false, true), formal(primPair(), SYM(z), false, false), formal(primPen(), SYM(fillrule), true, false));
+  addFunc(ve, run::gen_runpath43, primInt(), SYM(windingnumber), formal(pathArray()  , SYM(p), false, false), formal(primPair(), SYM(z), false, false));
 #line 414 "runpath.in"
-  addFunc(ve, run::gen_runpath44, primBoolean(), SYM(inside), formal(primPath(), SYM(g), false, false), formal(primPair(), SYM(z), false, false), formal(primPen(), SYM(fillrule), true, false));
+  addFunc(ve, run::gen_runpath44, primBoolean(), SYM(inside), formal(pathArray()  , SYM(g), false, true), formal(primPair(), SYM(z), false, false), formal(primPen(), SYM(fillrule), true, false));
 #line 419 "runpath.in"
-  addFunc(ve, run::gen_runpath45, primReal(), SYM(orient), formal(primPair(), SYM(a), false, false), formal(primPair(), SYM(b), false, false), formal(primPair(), SYM(c), false, false));
-#line 433 "runpath.in"
-  addFunc(ve, run::gen_runpath46, primReal(), SYM(incircle), formal(primPair(), SYM(a), false, false), formal(primPair(), SYM(b), false, false), formal(primPair(), SYM(c), false, false), formal(primPair(), SYM(d), false, false));
+  addFunc(ve, run::gen_runpath45, primBoolean(), SYM(inside), formal(primPath(), SYM(g), false, false), formal(primPair(), SYM(z), false, false), formal(primPen(), SYM(fillrule), true, false));
+#line 424 "runpath.in"
+  addFunc(ve, run::gen_runpath46, primReal(), SYM(orient), formal(primPair(), SYM(a), false, false), formal(primPair(), SYM(b), false, false), formal(primPair(), SYM(c), false, false));
+#line 438 "runpath.in"
+  addFunc(ve, run::gen_runpath47, primReal(), SYM(incircle), formal(primPair(), SYM(a), false, false), formal(primPair(), SYM(b), false, false), formal(primPair(), SYM(c), false, false), formal(primPair(), SYM(d), false, false));
 }
 
 } // namespace trans

Modified: trunk/Build/source/utils/asymptote/runpath.in
===================================================================
--- trunk/Build/source/utils/asymptote/runpath.in	2020-03-03 22:33:26 UTC (rev 54033)
+++ trunk/Build/source/utils/asymptote/runpath.in	2020-03-03 22:35:09 UTC (rev 54034)
@@ -169,6 +169,11 @@
   return p.arclength();
 }
 

+real arclength(pair z0, pair c0, pair c1, pair z1)
+{
+  return arcLength(z0,c0,c1,z1);
+}
+

 real arctime(path p, real L)
 {
   return p.arctime(L);

Modified: trunk/Build/source/utils/asymptote/runpath3d.cc
===================================================================
--- trunk/Build/source/utils/asymptote/runpath3d.cc	2020-03-03 22:33:26 UTC (rev 54033)
+++ trunk/Build/source/utils/asymptote/runpath3d.cc	2020-03-03 22:35:09 UTC (rev 54034)
@@ -351,73 +351,81 @@
   {Stack->push<path3>(p.unstraighten()); return;}
 }
 
-// Return the maximum perpendicular deviation of segment i of path3 g
-// from a straight line.
+// return the maximum distance squared of points c0 and c1 from 
+// the respective internal control points of z0--z1.
 #line 183 "runpath3d.in"
-// real straightness(path3 p, Int t);
+// real straightness(triple z0, triple c0, triple c1, triple z1);
 void gen_runpath3d23(stack *Stack)
 {
-  Int t=vm::pop<Int>(Stack);
-  path3 p=vm::pop<path3>(Stack);
+  triple z1=vm::pop<triple>(Stack);
+  triple c1=vm::pop<triple>(Stack);
+  triple c0=vm::pop<triple>(Stack);
+  triple z0=vm::pop<triple>(Stack);
 #line 184 "runpath3d.in"
-  if(p.straight(t)) {Stack->push<real>(0); return;}
-  triple z0=p.point(t);
-  triple u=unit(p.point(t+1)-z0);
-  {Stack->push<real>(::max(length(perp(p.postcontrol(t)-z0,u)),
-               length(perp(p.precontrol(t+1)-z0,u)))); return;}
+  {Stack->push<real>(Straightness(z0,c0,c1,z1)); return;}
 }
 
-// Return the maximum perpendicular deviation of z0..controls c0 and c1..z1
-// from a straight line.
-#line 194 "runpath3d.in"
-// real straightness(triple z0, triple c0, triple c1, triple z1);
+// return the straightness of segment i of path3 g.
+#line 189 "runpath3d.in"
+// real straightness(path3 p, Int t);
 void gen_runpath3d24(stack *Stack)
 {
-  triple z1=vm::pop<triple>(Stack);
-  triple c1=vm::pop<triple>(Stack);
-  triple c0=vm::pop<triple>(Stack);
-  triple z0=vm::pop<triple>(Stack);
-#line 195 "runpath3d.in"
-  triple u=unit(z1-z0);
-  {Stack->push<real>(::max(length(perp(c0-z0,u)),length(perp(c1-z0,u)))); return;}
+  Int t=vm::pop<Int>(Stack);
+  path3 p=vm::pop<path3>(Stack);
+#line 190 "runpath3d.in"
+  if(p.straight(t)) {Stack->push<real>(0); return;}
+  {Stack->push<real>(Straightness(p.point(t),p.postcontrol(t),p.precontrol(t+1),
+                      p.point(t+1))); return;}
 }
 
-#line 200 "runpath3d.in"
+#line 196 "runpath3d.in"
 // bool piecewisestraight(path3 p);
 void gen_runpath3d25(stack *Stack)
 {
   path3 p=vm::pop<path3>(Stack);
-#line 201 "runpath3d.in"
+#line 197 "runpath3d.in"
   {Stack->push<bool>(p.piecewisestraight()); return;}
 }
 
-#line 205 "runpath3d.in"
+#line 201 "runpath3d.in"
 // real arclength(path3 p);
 void gen_runpath3d26(stack *Stack)
 {
   path3 p=vm::pop<path3>(Stack);
-#line 206 "runpath3d.in"
+#line 202 "runpath3d.in"
   {Stack->push<real>(p.arclength()); return;}
 }
 
-#line 210 "runpath3d.in"
-// real arctime(path3 p, real dval);
+#line 206 "runpath3d.in"
+// real arclength(triple z0, triple c0, triple c1, triple z1);
 void gen_runpath3d27(stack *Stack)
 {
+  triple z1=vm::pop<triple>(Stack);
+  triple c1=vm::pop<triple>(Stack);
+  triple c0=vm::pop<triple>(Stack);
+  triple z0=vm::pop<triple>(Stack);
+#line 207 "runpath3d.in"
+  {Stack->push<real>(arcLength(z0,c0,c1,z1)); return;}
+}
+
+#line 211 "runpath3d.in"
+// real arctime(path3 p, real dval);
+void gen_runpath3d28(stack *Stack)
+{
   real dval=vm::pop<real>(Stack);
   path3 p=vm::pop<path3>(Stack);
-#line 211 "runpath3d.in"
+#line 212 "runpath3d.in"
   {Stack->push<real>(p.arctime(dval)); return;}
 }
 
-#line 215 "runpath3d.in"
+#line 216 "runpath3d.in"
 // realarray* intersect(path3 p, path3 q, real fuzz=-1);
-void gen_runpath3d28(stack *Stack)
+void gen_runpath3d29(stack *Stack)
 {
   real fuzz=vm::pop<real>(Stack,-1);
   path3 q=vm::pop<path3>(Stack);
   path3 p=vm::pop<path3>(Stack);
-#line 216 "runpath3d.in"
+#line 217 "runpath3d.in"
   bool exact=fuzz <= 0.0;
   if(fuzz < 0)
     fuzz=BigFuzz*::max(::max(length(p.max()),length(p.min())),
@@ -434,14 +442,14 @@
     {Stack->push<realarray*>(new array(0)); return;}
 }
 
-#line 233 "runpath3d.in"
+#line 234 "runpath3d.in"
 // realarray2* intersections(path3 p, path3 q, real fuzz=-1);
-void gen_runpath3d29(stack *Stack)
+void gen_runpath3d30(stack *Stack)
 {
   real fuzz=vm::pop<real>(Stack,-1);
   path3 q=vm::pop<path3>(Stack);
   path3 p=vm::pop<path3>(Stack);
-#line 234 "runpath3d.in"
+#line 235 "runpath3d.in"
   bool exact=fuzz <= 0.0;
   if(fuzz < 0)
     fuzz=BigFuzz*::max(::max(length(p.max()),length(p.min())),
@@ -473,14 +481,14 @@
   {Stack->push<realarray2*>(V); return;}
 }
 
-#line 266 "runpath3d.in"
+#line 267 "runpath3d.in"
 // realarray* intersect(path3 p, triplearray2 *P, real fuzz=-1);
-void gen_runpath3d30(stack *Stack)
+void gen_runpath3d31(stack *Stack)
 {
   real fuzz=vm::pop<real>(Stack,-1);
   triplearray2 * P=vm::pop<triplearray2 *>(Stack);
   path3 p=vm::pop<path3>(Stack);
-#line 267 "runpath3d.in"
+#line 268 "runpath3d.in"
   triple *A;
   copyArray2C(A,P,true,4);
   if(fuzz <= 0) fuzz=BigFuzz*::max(::max(length(p.max()),length(p.min())),
@@ -498,14 +506,14 @@
     {Stack->push<realarray*>(new array(0)); return;}
 }
 
-#line 285 "runpath3d.in"
+#line 286 "runpath3d.in"
 // realarray2* intersections(path3 p, triplearray2 *P, real fuzz=-1);
-void gen_runpath3d31(stack *Stack)
+void gen_runpath3d32(stack *Stack)
 {
   real fuzz=vm::pop<real>(Stack,-1);
   triplearray2 * P=vm::pop<triplearray2 *>(Stack);
   path3 p=vm::pop<path3>(Stack);
-#line 286 "runpath3d.in"
+#line 287 "runpath3d.in"
   triple *A;
   copyArray2C(A,P,true,4);
   if(fuzz <= 0) fuzz=BigFuzz*::max(::max(length(p.max()),length(p.min())),
@@ -525,49 +533,49 @@
   {Stack->push<realarray2*>(W); return;} // Sorting will done in asy.
 }
 
-#line 306 "runpath3d.in"
+#line 307 "runpath3d.in"
 // Int size(path3 p);
-void gen_runpath3d32(stack *Stack)
+void gen_runpath3d33(stack *Stack)
 {
   path3 p=vm::pop<path3>(Stack);
-#line 307 "runpath3d.in"
+#line 308 "runpath3d.in"
   {Stack->push<Int>(p.size()); return;}
 }
 
-#line 311 "runpath3d.in"
+#line 312 "runpath3d.in"
 // path3 &(path3 p, path3 q);
-void gen_runpath3d33(stack *Stack)
+void gen_runpath3d34(stack *Stack)
 {
   path3 q=vm::pop<path3>(Stack);
   path3 p=vm::pop<path3>(Stack);
-#line 312 "runpath3d.in"
+#line 313 "runpath3d.in"
   {Stack->push<path3>(camp::concat(p,q)); return;}
 }
 
-#line 316 "runpath3d.in"
+#line 317 "runpath3d.in"
 // triple min(path3 p);
-void gen_runpath3d34(stack *Stack)
+void gen_runpath3d35(stack *Stack)
 {
   path3 p=vm::pop<path3>(Stack);
-#line 317 "runpath3d.in"
+#line 318 "runpath3d.in"
   {Stack->push<triple>(p.min()); return;}
 }
 
-#line 321 "runpath3d.in"
+#line 322 "runpath3d.in"
 // triple max(path3 p);
-void gen_runpath3d35(stack *Stack)
+void gen_runpath3d36(stack *Stack)
 {
   path3 p=vm::pop<path3>(Stack);
-#line 322 "runpath3d.in"
+#line 323 "runpath3d.in"
   {Stack->push<triple>(p.max()); return;}
 }
 
-#line 326 "runpath3d.in"
+#line 327 "runpath3d.in"
 // realarray* mintimes(path3 p);
-void gen_runpath3d36(stack *Stack)
+void gen_runpath3d37(stack *Stack)
 {
   path3 p=vm::pop<path3>(Stack);
-#line 327 "runpath3d.in"
+#line 328 "runpath3d.in"
   array *V=new array(3);
   triple v=p.mintimes();
   (*V)[0]=v.getx();
@@ -576,12 +584,12 @@
   {Stack->push<realarray*>(V); return;}
 }
 
-#line 336 "runpath3d.in"
+#line 337 "runpath3d.in"
 // realarray* maxtimes(path3 p);
-void gen_runpath3d37(stack *Stack)
+void gen_runpath3d38(stack *Stack)
 {
   path3 p=vm::pop<path3>(Stack);
-#line 337 "runpath3d.in"
+#line 338 "runpath3d.in"
   array *V=new array(3);
   triple v=p.maxtimes();
   (*V)[0]=v.getx();
@@ -590,31 +598,31 @@
   {Stack->push<realarray*>(V); return;}
 }
 
-#line 346 "runpath3d.in"
+#line 347 "runpath3d.in"
 // path3 *(realarray2 *t, path3 g);
-void gen_runpath3d38(stack *Stack)
+void gen_runpath3d39(stack *Stack)
 {
   path3 g=vm::pop<path3>(Stack);
   realarray2 * t=vm::pop<realarray2 *>(Stack);
-#line 347 "runpath3d.in"
+#line 348 "runpath3d.in"
   {Stack->push<path3>(transformed(*t,g)); return;}
 }
 
-#line 351 "runpath3d.in"
+#line 352 "runpath3d.in"
 // pair minratio(path3 g);
-void gen_runpath3d39(stack *Stack)
+void gen_runpath3d40(stack *Stack)
 {
   path3 g=vm::pop<path3>(Stack);
-#line 352 "runpath3d.in"
+#line 353 "runpath3d.in"
   {Stack->push<pair>(g.ratio(::min)); return;}
 }
 
-#line 356 "runpath3d.in"
+#line 357 "runpath3d.in"
 // pair maxratio(path3 g);
-void gen_runpath3d40(stack *Stack)
+void gen_runpath3d41(stack *Stack)
 {
   path3 g=vm::pop<path3>(Stack);
-#line 357 "runpath3d.in"
+#line 358 "runpath3d.in"
   {Stack->push<pair>(g.ratio(::max)); return;}
 }
 
@@ -626,15 +634,15 @@
 // |b.x b.y b.z 1|
 // |c.x c.y c.z 1|
 // |d.x d.y d.z 1|
-#line 369 "runpath3d.in"
+#line 370 "runpath3d.in"
 // real orient(triple a, triple b, triple c, triple d);
-void gen_runpath3d41(stack *Stack)
+void gen_runpath3d42(stack *Stack)
 {
   triple d=vm::pop<triple>(Stack);
   triple c=vm::pop<triple>(Stack);
   triple b=vm::pop<triple>(Stack);
   triple a=vm::pop<triple>(Stack);
-#line 370 "runpath3d.in"
+#line 371 "runpath3d.in"
   real A[]={a.getx(),a.gety(),a.getz()};
   real B[]={b.getx(),b.gety(),b.getz()};
   real C[]={c.getx(),c.gety(),c.getz()};
@@ -652,9 +660,9 @@
 // |c.x c.y c.z c.x^2+c.y^2+c.z^2 1|
 // |d.x d.y d.z d.x^2+d.y^2+d.z^2 1|
 // |e.x e.y e.z e.x^2+e.y^2+e.z^2 1|
-#line 388 "runpath3d.in"
+#line 389 "runpath3d.in"
 // real insphere(triple a, triple b, triple c, triple d, triple e);
-void gen_runpath3d42(stack *Stack)
+void gen_runpath3d43(stack *Stack)
 {
   triple e=vm::pop<triple>(Stack);
   triple d=vm::pop<triple>(Stack);
@@ -661,7 +669,7 @@
   triple c=vm::pop<triple>(Stack);
   triple b=vm::pop<triple>(Stack);
   triple a=vm::pop<triple>(Stack);
-#line 389 "runpath3d.in"
+#line 390 "runpath3d.in"
   real A[]={a.getx(),a.gety(),a.getz()};
   real B[]={b.getx(),b.gety(),b.getz()};
   real C[]={c.getx(),c.gety(),c.getz()};
@@ -723,45 +731,47 @@
 #line 176 "runpath3d.in"
   addFunc(ve, run::gen_runpath3d22, primPath3(), SYM(unstraighten), formal(primPath3(), SYM(p), false, false));
 #line 181 "runpath3d.in"
-  addFunc(ve, run::gen_runpath3d23, primReal(), SYM(straightness), formal(primPath3(), SYM(p), false, false), formal(primInt(), SYM(t), false, false));
-#line 192 "runpath3d.in"
-  addFunc(ve, run::gen_runpath3d24, primReal(), SYM(straightness), formal(primTriple(), SYM(z0), false, false), formal(primTriple(), SYM(c0), false, false), formal(primTriple(), SYM(c1), false, false), formal(primTriple(), SYM(z1), false, false));
-#line 200 "runpath3d.in"
+  addFunc(ve, run::gen_runpath3d23, primReal(), SYM(straightness), formal(primTriple(), SYM(z0), false, false), formal(primTriple(), SYM(c0), false, false), formal(primTriple(), SYM(c1), false, false), formal(primTriple(), SYM(z1), false, false));
+#line 188 "runpath3d.in"
+  addFunc(ve, run::gen_runpath3d24, primReal(), SYM(straightness), formal(primPath3(), SYM(p), false, false), formal(primInt(), SYM(t), false, false));
+#line 196 "runpath3d.in"
   addFunc(ve, run::gen_runpath3d25, primBoolean(), SYM(piecewisestraight), formal(primPath3(), SYM(p), false, false));
-#line 205 "runpath3d.in"
+#line 201 "runpath3d.in"
   addFunc(ve, run::gen_runpath3d26, primReal(), SYM(arclength), formal(primPath3(), SYM(p), false, false));
-#line 210 "runpath3d.in"
-  addFunc(ve, run::gen_runpath3d27, primReal(), SYM(arctime), formal(primPath3(), SYM(p), false, false), formal(primReal(), SYM(dval), false, false));
-#line 215 "runpath3d.in"
-  addFunc(ve, run::gen_runpath3d28, realArray(), SYM(intersect), formal(primPath3(), SYM(p), false, false), formal(primPath3(), SYM(q), false, false), formal(primReal(), SYM(fuzz), true, false));
-#line 233 "runpath3d.in"
-  addFunc(ve, run::gen_runpath3d29, realArray2(), SYM(intersections), formal(primPath3(), SYM(p), false, false), formal(primPath3(), SYM(q), false, false), formal(primReal(), SYM(fuzz), true, false));
-#line 266 "runpath3d.in"
-  addFunc(ve, run::gen_runpath3d30, realArray(), SYM(intersect), formal(primPath3(), SYM(p), false, false), formal(tripleArray2(), SYM(p), false, false), formal(primReal(), SYM(fuzz), true, false));
-#line 285 "runpath3d.in"
-  addFunc(ve, run::gen_runpath3d31, realArray2(), SYM(intersections), formal(primPath3(), SYM(p), false, false), formal(tripleArray2(), SYM(p), false, false), formal(primReal(), SYM(fuzz), true, false));
-#line 306 "runpath3d.in"
-  addFunc(ve, run::gen_runpath3d32, primInt(), SYM(size), formal(primPath3(), SYM(p), false, false));
-#line 311 "runpath3d.in"
-  addFunc(ve, run::gen_runpath3d33, primPath3(), SYM_AMPERSAND, formal(primPath3(), SYM(p), false, false), formal(primPath3(), SYM(q), false, false));
-#line 316 "runpath3d.in"
-  addFunc(ve, run::gen_runpath3d34, primTriple(), SYM(min), formal(primPath3(), SYM(p), false, false));
-#line 321 "runpath3d.in"
-  addFunc(ve, run::gen_runpath3d35, primTriple(), SYM(max), formal(primPath3(), SYM(p), false, false));
-#line 326 "runpath3d.in"
-  addFunc(ve, run::gen_runpath3d36, realArray(), SYM(mintimes), formal(primPath3(), SYM(p), false, false));
-#line 336 "runpath3d.in"
-  addFunc(ve, run::gen_runpath3d37, realArray(), SYM(maxtimes), formal(primPath3(), SYM(p), false, false));
-#line 346 "runpath3d.in"
-  addFunc(ve, run::gen_runpath3d38, primPath3(), SYM_TIMES, formal(realArray2(), SYM(t), false, false), formal(primPath3(), SYM(g), false, false));
-#line 351 "runpath3d.in"
-  addFunc(ve, run::gen_runpath3d39, primPair(), SYM(minratio), formal(primPath3(), SYM(g), false, false));
-#line 356 "runpath3d.in"
-  addFunc(ve, run::gen_runpath3d40, primPair(), SYM(maxratio), formal(primPath3(), SYM(g), false, false));
-#line 361 "runpath3d.in"
-  addFunc(ve, run::gen_runpath3d41, primReal(), SYM(orient), formal(primTriple(), SYM(a), false, false), formal(primTriple(), SYM(b), false, false), formal(primTriple(), SYM(c), false, false), formal(primTriple(), SYM(d), false, false));
-#line 378 "runpath3d.in"
-  addFunc(ve, run::gen_runpath3d42, primReal(), SYM(insphere), formal(primTriple(), SYM(a), false, false), formal(primTriple(), SYM(b), false, false), formal(primTriple(), SYM(c), false, false), formal(primTriple(), SYM(d), false, false), formal(primTriple(), SYM(e), false, false));
+#line 206 "runpath3d.in"
+  addFunc(ve, run::gen_runpath3d27, primReal(), SYM(arclength), formal(primTriple(), SYM(z0), false, false), formal(primTriple(), SYM(c0), false, false), formal(primTriple(), SYM(c1), false, false), formal(primTriple(), SYM(z1), false, false));
+#line 211 "runpath3d.in"
+  addFunc(ve, run::gen_runpath3d28, primReal(), SYM(arctime), formal(primPath3(), SYM(p), false, false), formal(primReal(), SYM(dval), false, false));
+#line 216 "runpath3d.in"
+  addFunc(ve, run::gen_runpath3d29, realArray(), SYM(intersect), formal(primPath3(), SYM(p), false, false), formal(primPath3(), SYM(q), false, false), formal(primReal(), SYM(fuzz), true, false));
+#line 234 "runpath3d.in"
+  addFunc(ve, run::gen_runpath3d30, realArray2(), SYM(intersections), formal(primPath3(), SYM(p), false, false), formal(primPath3(), SYM(q), false, false), formal(primReal(), SYM(fuzz), true, false));
+#line 267 "runpath3d.in"
+  addFunc(ve, run::gen_runpath3d31, realArray(), SYM(intersect), formal(primPath3(), SYM(p), false, false), formal(tripleArray2(), SYM(p), false, false), formal(primReal(), SYM(fuzz), true, false));
+#line 286 "runpath3d.in"
+  addFunc(ve, run::gen_runpath3d32, realArray2(), SYM(intersections), formal(primPath3(), SYM(p), false, false), formal(tripleArray2(), SYM(p), false, false), formal(primReal(), SYM(fuzz), true, false));
+#line 307 "runpath3d.in"
+  addFunc(ve, run::gen_runpath3d33, primInt(), SYM(size), formal(primPath3(), SYM(p), false, false));
+#line 312 "runpath3d.in"
+  addFunc(ve, run::gen_runpath3d34, primPath3(), SYM_AMPERSAND, formal(primPath3(), SYM(p), false, false), formal(primPath3(), SYM(q), false, false));
+#line 317 "runpath3d.in"
+  addFunc(ve, run::gen_runpath3d35, primTriple(), SYM(min), formal(primPath3(), SYM(p), false, false));
+#line 322 "runpath3d.in"
+  addFunc(ve, run::gen_runpath3d36, primTriple(), SYM(max), formal(primPath3(), SYM(p), false, false));
+#line 327 "runpath3d.in"
+  addFunc(ve, run::gen_runpath3d37, realArray(), SYM(mintimes), formal(primPath3(), SYM(p), false, false));
+#line 337 "runpath3d.in"
+  addFunc(ve, run::gen_runpath3d38, realArray(), SYM(maxtimes), formal(primPath3(), SYM(p), false, false));
+#line 347 "runpath3d.in"
+  addFunc(ve, run::gen_runpath3d39, primPath3(), SYM_TIMES, formal(realArray2(), SYM(t), false, false), formal(primPath3(), SYM(g), false, false));
+#line 352 "runpath3d.in"
+  addFunc(ve, run::gen_runpath3d40, primPair(), SYM(minratio), formal(primPath3(), SYM(g), false, false));
+#line 357 "runpath3d.in"
+  addFunc(ve, run::gen_runpath3d41, primPair(), SYM(maxratio), formal(primPath3(), SYM(g), false, false));
+#line 362 "runpath3d.in"
+  addFunc(ve, run::gen_runpath3d42, primReal(), SYM(orient), formal(primTriple(), SYM(a), false, false), formal(primTriple(), SYM(b), false, false), formal(primTriple(), SYM(c), false, false), formal(primTriple(), SYM(d), false, false));
+#line 379 "runpath3d.in"
+  addFunc(ve, run::gen_runpath3d43, primReal(), SYM(insphere), formal(primTriple(), SYM(a), false, false), formal(primTriple(), SYM(b), false, false), formal(primTriple(), SYM(c), false, false), formal(primTriple(), SYM(d), false, false), formal(primTriple(), SYM(e), false, false));
 }
 
 } // namespace trans

Modified: trunk/Build/source/utils/asymptote/runpath3d.in
===================================================================
--- trunk/Build/source/utils/asymptote/runpath3d.in	2020-03-03 22:33:26 UTC (rev 54033)
+++ trunk/Build/source/utils/asymptote/runpath3d.in	2020-03-03 22:35:09 UTC (rev 54034)
@@ -178,23 +178,19 @@
   return p.unstraighten();
 }
 

-// Return the maximum perpendicular deviation of segment i of path3 g
-// from a straight line.
-real straightness(path3 p, Int t) 
+// return the maximum distance squared of points c0 and c1 from 
+// the respective internal control points of z0--z1.
+real straightness(triple z0, triple c0, triple c1, triple z1)
 {
-  if(p.straight(t)) return 0;
-  triple z0=p.point(t);
-  triple u=unit(p.point(t+1)-z0);
-  return ::max(length(perp(p.postcontrol(t)-z0,u)),
-               length(perp(p.precontrol(t+1)-z0,u)));
+  return Straightness(z0,c0,c1,z1);
 }
 

-// Return the maximum perpendicular deviation of z0..controls c0 and c1..z1
-// from a straight line.
-real straightness(triple z0, triple c0, triple c1, triple z1)
+// return the straightness of segment i of path3 g.
+real straightness(path3 p, Int t) 
 {
-  triple u=unit(z1-z0);
-  return ::max(length(perp(c0-z0,u)),length(perp(c1-z0,u)));
+  if(p.straight(t)) return 0;
+  return Straightness(p.point(t),p.postcontrol(t),p.precontrol(t+1),
+                      p.point(t+1));
 }
 

 bool piecewisestraight(path3 p)
@@ -207,6 +203,11 @@
   return p.arclength();
 }
 

+real arclength(triple z0, triple c0, triple c1, triple z1)
+{
+  return arcLength(z0,c0,c1,z1);
+}
+

 real arctime(path3 p, real dval)
 {
   return p.arctime(dval);

Modified: trunk/Build/source/utils/asymptote/runpicture.cc
===================================================================
--- trunk/Build/source/utils/asymptote/runpicture.cc	2020-03-03 22:33:26 UTC (rev 54033)
+++ trunk/Build/source/utils/asymptote/runpicture.cc	2020-03-03 22:35:09 UTC (rev 54034)
@@ -61,7 +61,7 @@
 
 #define CURRENTPEN processData().currentpen
 

-#line 29 "runpicture.in"
+#line 28 "runpicture.in"
 #include "picture.h"
 #include "drawelement.h"
 #include "path.h"
@@ -97,7 +97,6 @@
 typedef array penarray;
 typedef array penarray2;
 
-typedef callable callableTransform;
 typedef callable callablePen;
 
 using types::IntArray;
@@ -167,60 +166,60 @@
 
 #endif
 namespace run {
-#line 128 "runpicture.in"
+#line 126 "runpicture.in"
 void newPicture(stack *Stack)
 {
-#line 129 "runpicture.in"
+#line 127 "runpicture.in"
   {Stack->push<picture*>(new picture()); return;}
 }
 
-#line 133 "runpicture.in"
+#line 131 "runpicture.in"
 // bool empty(picture *f);
 void gen_runpicture1(stack *Stack)
 {
   picture * f=vm::pop<picture *>(Stack);
-#line 134 "runpicture.in"
+#line 132 "runpicture.in"
   {Stack->push<bool>(f->null()); return;}
 }
 
-#line 138 "runpicture.in"
+#line 136 "runpicture.in"
 // void erase(picture *f);
 void gen_runpicture2(stack *Stack)
 {
   picture * f=vm::pop<picture *>(Stack);
-#line 139 "runpicture.in"
+#line 137 "runpicture.in"
   f->nodes.clear();
 }
 
-#line 143 "runpicture.in"
+#line 141 "runpicture.in"
 // pair min(picture *f);
 void gen_runpicture3(stack *Stack)
 {
   picture * f=vm::pop<picture *>(Stack);
-#line 144 "runpicture.in"
+#line 142 "runpicture.in"
   {Stack->push<pair>(f->bounds().Min()); return;}
 }
 
-#line 148 "runpicture.in"
+#line 146 "runpicture.in"
 // pair max(picture *f);
 void gen_runpicture4(stack *Stack)
 {
   picture * f=vm::pop<picture *>(Stack);
-#line 149 "runpicture.in"
+#line 147 "runpicture.in"
   {Stack->push<pair>(f->bounds().Max()); return;}
 }
 
-#line 153 "runpicture.in"
+#line 151 "runpicture.in"
 // pair size(picture *f);
 void gen_runpicture5(stack *Stack)
 {
   picture * f=vm::pop<picture *>(Stack);
-#line 154 "runpicture.in"
+#line 152 "runpicture.in"
   bbox b=f->bounds();
   {Stack->push<pair>(b.Max()-b.Min()); return;}
 }
 
-#line 159 "runpicture.in"
+#line 157 "runpicture.in"
 // void _draw(picture *f, path g, pen p);
 void gen_runpicture6(stack *Stack)
 {
@@ -227,11 +226,11 @@
   pen p=vm::pop<pen>(Stack);
   path g=vm::pop<path>(Stack);
   picture * f=vm::pop<picture *>(Stack);
-#line 160 "runpicture.in"
+#line 158 "runpicture.in"
   f->append(new drawPath(g,p));
 }
 
-#line 164 "runpicture.in"
+#line 162 "runpicture.in"
 // void fill(picture *f, patharray *g, pen p=CURRENTPEN, bool copy=true);
 void gen_runpicture7(stack *Stack)
 {
@@ -239,12 +238,12 @@
   pen p=vm::pop<pen>(Stack,CURRENTPEN);
   patharray * g=vm::pop<patharray *>(Stack);
   picture * f=vm::pop<picture *>(Stack);
-#line 165 "runpicture.in"
+#line 163 "runpicture.in"
   array *(*copyarray)(array *a)=copy ? copyArray : nop;
   f->append(new drawFill(*copyarray(g),false,p));
 }
 
-#line 170 "runpicture.in"
+#line 168 "runpicture.in"
 // void latticeshade(picture *f, patharray *g, bool stroke=false,                  pen fillrule=CURRENTPEN, penarray2 *p, transform t=identity,                   bool copy=true);
 void gen_runpicture8(stack *Stack)
 {
@@ -255,13 +254,13 @@
   bool stroke=vm::pop<bool>(Stack,false);
   patharray * g=vm::pop<patharray *>(Stack);
   picture * f=vm::pop<picture *>(Stack);
-#line 173 "runpicture.in"
+#line 171 "runpicture.in"
   array *(*copyarray)(array *a)=copy ? copyArray : nop;
   f->append(new drawLatticeShade(*copyarray(g),stroke,fillrule,*copyarray(p),
                                  t));
 }
 
-#line 179 "runpicture.in"
+#line 177 "runpicture.in"
 // void axialshade(picture *f, patharray *g, bool stroke=false, pen pena, pair a,                bool extenda=true, pen penb, pair b, bool extendb=true,                bool copy=true);
 void gen_runpicture9(stack *Stack)
 {
@@ -275,13 +274,13 @@
   bool stroke=vm::pop<bool>(Stack,false);
   patharray * g=vm::pop<patharray *>(Stack);
   picture * f=vm::pop<picture *>(Stack);
-#line 182 "runpicture.in"
+#line 180 "runpicture.in"
   array *(*copyarray)(array *a)=copy ? copyArray : nop;
   f->append(new drawAxialShade(*copyarray(g),stroke,pena,a,extenda,penb,b,
                                extendb));
 }
 
-#line 188 "runpicture.in"
+#line 186 "runpicture.in"
 // void radialshade(picture *f, patharray *g, bool stroke=false, pen pena,                 pair a, real ra, bool extenda=true, pen penb, pair b, real rb,                 bool extendb=true, bool copy=true);
 void gen_runpicture10(stack *Stack)
 {
@@ -297,13 +296,13 @@
   bool stroke=vm::pop<bool>(Stack,false);
   patharray * g=vm::pop<patharray *>(Stack);
   picture * f=vm::pop<picture *>(Stack);
-#line 191 "runpicture.in"
+#line 189 "runpicture.in"
   array *(*copyarray)(array *a)=copy ? copyArray : nop;
   f->append(new drawRadialShade(*copyarray(g),stroke,pena,a,ra,extenda,
                                 penb,b,rb,extendb));
 }
 
-#line 197 "runpicture.in"
+#line 195 "runpicture.in"
 // void gouraudshade(picture *f, patharray *g, bool stroke=false,                  pen fillrule=CURRENTPEN, penarray *p, pairarray *z,                  Intarray *edges, bool copy=true);
 void gen_runpicture11(stack *Stack)
 {
@@ -315,7 +314,7 @@
   bool stroke=vm::pop<bool>(Stack,false);
   patharray * g=vm::pop<patharray *>(Stack);
   picture * f=vm::pop<picture *>(Stack);
-#line 200 "runpicture.in"
+#line 198 "runpicture.in"
   array *(*copyarray)(array *a)=copy ? copyArray : nop;
   checkArrays(p,z);
   checkArrays(z,edges);
@@ -323,7 +322,7 @@
                                  *copyarray(z),*copyarray(edges)));
 }
 
-#line 208 "runpicture.in"
+#line 206 "runpicture.in"
 // void gouraudshade(picture *f, patharray *g, bool stroke=false,                  pen fillrule=CURRENTPEN, penarray *p, Intarray *edges,                  bool copy=true);
 void gen_runpicture12(stack *Stack)
 {
@@ -334,7 +333,7 @@
   bool stroke=vm::pop<bool>(Stack,false);
   patharray * g=vm::pop<patharray *>(Stack);
   picture * f=vm::pop<picture *>(Stack);
-#line 211 "runpicture.in"
+#line 209 "runpicture.in"
   array *(*copyarray)(array *a)=copy ? copyArray : nop;
   size_t n=checkArrays(p,edges);
   size_t m=checkArray(g);
@@ -355,7 +354,7 @@
                                  *z,*copyarray(edges)));
 }
 
-#line 232 "runpicture.in"
+#line 230 "runpicture.in"
 // void tensorshade(picture *f, patharray *g, bool stroke=false,                 pen fillrule=CURRENTPEN, penarray2 *p, patharray *b=NULL,                 pairarray2 *z=emptyarray, bool copy=true);
 void gen_runpicture13(stack *Stack)
 {
@@ -367,7 +366,7 @@
   bool stroke=vm::pop<bool>(Stack,false);
   patharray * g=vm::pop<patharray *>(Stack);
   picture * f=vm::pop<picture *>(Stack);
-#line 235 "runpicture.in"
+#line 233 "runpicture.in"
   array *(*copyarray)(array *a)=copy ? copyArray : nop;
   array *(*copyarray2)(array *a)=copy ? copyArray2 : nop;
   if(b == NULL) b=g;
@@ -379,7 +378,7 @@
                                 *copyarray(b),*copyarray2(z)));
 }
 
-#line 247 "runpicture.in"
+#line 245 "runpicture.in"
 // void functionshade(picture *f, patharray *g, bool stroke=false,                   pen fillrule=CURRENTPEN, string shader=emptystring,                   bool copy=true);
 void gen_runpicture14(stack *Stack)
 {
@@ -389,7 +388,7 @@
   bool stroke=vm::pop<bool>(Stack,false);
   patharray * g=vm::pop<patharray *>(Stack);
   picture * f=vm::pop<picture *>(Stack);
-#line 250 "runpicture.in"
+#line 248 "runpicture.in"
   array *(*copyarray)(array *a)=copy ? copyArray : nop;
   f->append(new drawFunctionShade(*copyarray(g),stroke,fillrule,shader));
 }
@@ -396,7 +395,7 @@
 
 // Clip a picture to a superpath using the given fill rule.
 // Subsequent additions to the picture will not be affected by the clipping.
-#line 257 "runpicture.in"
+#line 255 "runpicture.in"
 // void clip(picture *f, patharray *g, bool stroke=false,          pen fillrule=CURRENTPEN, bool copy=true);
 void gen_runpicture15(stack *Stack)
 {
@@ -405,13 +404,13 @@
   bool stroke=vm::pop<bool>(Stack,false);
   patharray * g=vm::pop<patharray *>(Stack);
   picture * f=vm::pop<picture *>(Stack);
-#line 259 "runpicture.in"
+#line 257 "runpicture.in"
   array *(*copyarray)(array *a)=copy ? copyArray : nop;
   drawClipBegin *begin=new drawClipBegin(*copyarray(g),stroke,fillrule,true);
   f->enclose(begin,new drawClipEnd(true,begin));
 }
 
-#line 265 "runpicture.in"
+#line 263 "runpicture.in"
 // void beginclip(picture *f, patharray *g, bool stroke=false,               pen fillrule=CURRENTPEN, bool copy=true);
 void gen_runpicture16(stack *Stack)
 {
@@ -420,57 +419,57 @@
   bool stroke=vm::pop<bool>(Stack,false);
   patharray * g=vm::pop<patharray *>(Stack);
   picture * f=vm::pop<picture *>(Stack);
-#line 267 "runpicture.in"
+#line 265 "runpicture.in"
   array *(*copyarray)(array *a)=copy ? copyArray : nop;
   f->append(new drawClipBegin(*copyarray(g),stroke,fillrule,false));
 }
 
-#line 272 "runpicture.in"
+#line 270 "runpicture.in"
 // void endclip(picture *f);
 void gen_runpicture17(stack *Stack)
 {
   picture * f=vm::pop<picture *>(Stack);
-#line 273 "runpicture.in"
+#line 271 "runpicture.in"
   f->append(new drawClipEnd(false));
 }
 
-#line 277 "runpicture.in"
+#line 275 "runpicture.in"
 // void gsave(picture *f);
 void gen_runpicture18(stack *Stack)
 {
   picture * f=vm::pop<picture *>(Stack);
-#line 278 "runpicture.in"
+#line 276 "runpicture.in"
   f->append(new drawGsave());
 }
 
-#line 282 "runpicture.in"
+#line 280 "runpicture.in"
 // void grestore(picture *f);
 void gen_runpicture19(stack *Stack)
 {
   picture * f=vm::pop<picture *>(Stack);
-#line 283 "runpicture.in"
+#line 281 "runpicture.in"
   f->append(new drawGrestore());
 }
 
-#line 287 "runpicture.in"
+#line 285 "runpicture.in"
 // void begingroup(picture *f);
 void gen_runpicture20(stack *Stack)
 {
   picture * f=vm::pop<picture *>(Stack);
-#line 288 "runpicture.in"
+#line 286 "runpicture.in"
   f->append(new drawBegin());
 }
 
-#line 292 "runpicture.in"
+#line 290 "runpicture.in"
 // void endgroup(picture *f);
 void gen_runpicture21(stack *Stack)
 {
   picture * f=vm::pop<picture *>(Stack);
-#line 293 "runpicture.in"
+#line 291 "runpicture.in"
   f->append(new drawEnd());
 }
 
-#line 297 "runpicture.in"
+#line 295 "runpicture.in"
 // void _begingroup3(picture *f, string name, real compression,                 real granularity, bool closed, bool tessellate,                 bool dobreak, bool nobreak, triple center, Int interaction);
 void gen_runpicture22(stack *Stack)
 {
@@ -484,62 +483,62 @@
   real compression=vm::pop<real>(Stack);
   string name=vm::pop<string>(Stack);
   picture * f=vm::pop<picture *>(Stack);
-#line 300 "runpicture.in"
+#line 298 "runpicture.in"
   f->append(new drawBegin3(name,compression,granularity,
                            closed,tessellate,dobreak,nobreak,
                            center,(Interaction) intcast(interaction)));
 }
 
-#line 306 "runpicture.in"
+#line 304 "runpicture.in"
 // void endgroup3(picture *f);
 void gen_runpicture23(stack *Stack)
 {
   picture * f=vm::pop<picture *>(Stack);
-#line 307 "runpicture.in"
+#line 305 "runpicture.in"
   f->append(new drawEnd3());
 }
 
-#line 311 "runpicture.in"
+#line 309 "runpicture.in"
 // void add(picture *dest, picture *src);
 void gen_runpicture24(stack *Stack)
 {
   picture * src=vm::pop<picture *>(Stack);
   picture * dest=vm::pop<picture *>(Stack);
-#line 312 "runpicture.in"
+#line 310 "runpicture.in"
   dest->add(*src);
 }
 
-#line 316 "runpicture.in"
+#line 314 "runpicture.in"
 // void prepend(picture *dest, picture *src);
 void gen_runpicture25(stack *Stack)
 {
   picture * src=vm::pop<picture *>(Stack);
   picture * dest=vm::pop<picture *>(Stack);
-#line 317 "runpicture.in"
+#line 315 "runpicture.in"
   dest->prepend(*src);
 }
 
-#line 321 "runpicture.in"
+#line 319 "runpicture.in"
 // void postscript(picture *f, string s);
 void gen_runpicture26(stack *Stack)
 {
   string s=vm::pop<string>(Stack);
   picture * f=vm::pop<picture *>(Stack);
-#line 322 "runpicture.in"
+#line 320 "runpicture.in"
   f->append(new drawVerbatim(PostScript,s));
 }
 
-#line 326 "runpicture.in"
+#line 324 "runpicture.in"
 // void tex(picture *f, string s);
 void gen_runpicture27(stack *Stack)
 {
   string s=vm::pop<string>(Stack);
   picture * f=vm::pop<picture *>(Stack);
-#line 327 "runpicture.in"
+#line 325 "runpicture.in"
   f->append(new drawVerbatim(TeX,s));
 }
 
-#line 331 "runpicture.in"
+#line 329 "runpicture.in"
 // void postscript(picture *f, string s, pair min, pair max);
 void gen_runpicture28(stack *Stack)
 {
@@ -547,11 +546,11 @@
   pair min=vm::pop<pair>(Stack);
   string s=vm::pop<string>(Stack);
   picture * f=vm::pop<picture *>(Stack);
-#line 332 "runpicture.in"
+#line 330 "runpicture.in"
   f->append(new drawVerbatim(PostScript,s,min,max));
 }
 
-#line 336 "runpicture.in"
+#line 334 "runpicture.in"
 // void tex(picture *f, string s, pair min, pair max);
 void gen_runpicture29(stack *Stack)
 {
@@ -559,16 +558,16 @@
   pair min=vm::pop<pair>(Stack);
   string s=vm::pop<string>(Stack);
   picture * f=vm::pop<picture *>(Stack);
-#line 337 "runpicture.in"
+#line 335 "runpicture.in"
   f->append(new drawVerbatim(TeX,s,min,max));
 }
 
-#line 341 "runpicture.in"
+#line 339 "runpicture.in"
 // void texpreamble(string s);
 void gen_runpicture30(stack *Stack)
 {
   string s=vm::pop<string>(Stack);
-#line 342 "runpicture.in"
+#line 340 "runpicture.in"
   string t=s+"\n";
   processDataStruct &pd=processData();
   pd.TeXpipepreamble.push_back(t);
@@ -575,17 +574,17 @@
   pd.TeXpreamble.push_back(t);
 }
 
-#line 349 "runpicture.in"
+#line 347 "runpicture.in"
 // void deletepreamble();
 void gen_runpicture31(stack *)
 {
-#line 350 "runpicture.in"
+#line 348 "runpicture.in"
   if(getSetting<bool>("inlinetex")) {
     unlink(buildname(outname(),"pre").c_str());
   }
 }
 
-#line 356 "runpicture.in"
+#line 354 "runpicture.in"
 // void _labelpath(picture *f, string s, string size, path g, string justify,                pair offset, pen p);
 void gen_runpicture32(stack *Stack)
 {
@@ -596,15 +595,15 @@
   string size=vm::pop<string>(Stack);
   string s=vm::pop<string>(Stack);
   picture * f=vm::pop<picture *>(Stack);
-#line 358 "runpicture.in"
+#line 356 "runpicture.in"
   f->append(new drawLabelPath(s,size,g,justify,offset,p));
 }
 
-#line 362 "runpicture.in"
+#line 360 "runpicture.in"
 // void texreset();
 void gen_runpicture33(stack *)
 {
-#line 363 "runpicture.in"
+#line 361 "runpicture.in"
   processDataStruct &pd=processData();
   pd.TeXpipepreamble.clear();
   pd.TeXpreamble.clear();
@@ -611,25 +610,25 @@
   pd.tex.pipeclose();
 }
 
-#line 370 "runpicture.in"
+#line 368 "runpicture.in"
 // void layer(picture *f);
 void gen_runpicture34(stack *Stack)
 {
   picture * f=vm::pop<picture *>(Stack);
-#line 371 "runpicture.in"
+#line 369 "runpicture.in"
   f->append(new drawLayer());
 }
 
-#line 375 "runpicture.in"
+#line 373 "runpicture.in"
 // void newpage(picture *f);
 void gen_runpicture35(stack *Stack)
 {
   picture * f=vm::pop<picture *>(Stack);
-#line 376 "runpicture.in"
+#line 374 "runpicture.in"
   f->append(new drawNewPage());
 }
 
-#line 380 "runpicture.in"
+#line 378 "runpicture.in"
 // void _image(picture *f, realarray2 *data, pair initial, pair final,            penarray *palette=NULL, transform t=identity, bool copy=true,            bool antialias=false);
 void gen_runpicture36(stack *Stack)
 {
@@ -641,7 +640,7 @@
   pair initial=vm::pop<pair>(Stack);
   realarray2 * data=vm::pop<realarray2 *>(Stack);
   picture * f=vm::pop<picture *>(Stack);
-#line 383 "runpicture.in"
+#line 381 "runpicture.in"
   array *(*copyarray)(array *a)=copy ? copyArray : nop;
   array *(*copyarray2)(array *a)=copy ? copyArray2 : nop;
   f->append(new drawPaletteImage(*copyarray2(data),*copyarray(palette),
@@ -648,7 +647,7 @@
                             t*matrix(initial,final),antialias));
 }
 
-#line 390 "runpicture.in"
+#line 388 "runpicture.in"
 // void _image(picture *f, penarray2 *data, pair initial, pair final,            transform t=identity, bool copy=true, bool antialias=false);
 void gen_runpicture37(stack *Stack)
 {
@@ -659,13 +658,13 @@
   pair initial=vm::pop<pair>(Stack);
   penarray2 * data=vm::pop<penarray2 *>(Stack);
   picture * f=vm::pop<picture *>(Stack);
-#line 392 "runpicture.in"
+#line 390 "runpicture.in"
   array *(*copyarray2)(array *a)=copy ? copyArray2 : nop;
   f->append(new drawNoPaletteImage(*copyarray2(data),t*matrix(initial,final),
                                    antialias));
 }
 
-#line 398 "runpicture.in"
+#line 396 "runpicture.in"
 // void _image(picture *f, callablePen *F, Int width, Int height,            pair initial, pair final, transform t=identity, bool antialias=false);
 void gen_runpicture38(stack *Stack)
 {
@@ -677,36 +676,36 @@
   Int width=vm::pop<Int>(Stack);
   callablePen * F=vm::pop<callablePen *>(Stack);
   picture * f=vm::pop<picture *>(Stack);
-#line 400 "runpicture.in"
+#line 398 "runpicture.in"
   f->append(new drawFunctionImage(Stack,F,width,height,
                                   t*matrix(initial,final),antialias));
 }
 
-#line 405 "runpicture.in"
+#line 403 "runpicture.in"
 // string nativeformat();
 void gen_runpicture39(stack *Stack)
 {
-#line 406 "runpicture.in"
+#line 404 "runpicture.in"
   {Stack->push<string>(nativeformat()); return;}
 }
 
-#line 410 "runpicture.in"
+#line 408 "runpicture.in"
 // bool latex();
 void gen_runpicture40(stack *Stack)
 {
-#line 411 "runpicture.in"
+#line 409 "runpicture.in"
   {Stack->push<bool>(latex(getSetting<string>("tex"))); return;}
 }
 
-#line 415 "runpicture.in"
+#line 413 "runpicture.in"
 // bool pdf();
 void gen_runpicture41(stack *Stack)
 {
-#line 416 "runpicture.in"
+#line 414 "runpicture.in"
   {Stack->push<bool>(pdf(getSetting<string>("tex"))); return;}
 }
 
-#line 420 "runpicture.in"
+#line 418 "runpicture.in"
 // void _shipout(string prefix=emptystring, picture *f, picture *preamble=NULL,              string format=emptystring, bool wait=false, bool view=true,              transform T=identity);
 void gen_runpicture42(stack *Stack)
 {
@@ -717,7 +716,7 @@
   picture * preamble=vm::pop<picture *>(Stack,NULL);
   picture * f=vm::pop<picture *>(Stack);
   string prefix=vm::pop<string>(Stack,emptystring);
-#line 423 "runpicture.in"
+#line 421 "runpicture.in"
   if(prefix.empty()) prefix=outname();
 
   picture *result=new picture;
@@ -763,7 +762,7 @@
   result->shipout(preamble,prefix,format,wait,view);
 }
 
-#line 469 "runpicture.in"
+#line 467 "runpicture.in"
 // void shipout3(string prefix, picture *f, string format=emptystring,              real width, real height, real angle, real zoom,              triple m, triple M, pair shift, pair margin, realarray2 *t,              realarray *background, triplearray *lights, realarray2 *diffuse,              realarray2 *specular, bool view=true);
 void gen_runpicture43(stack *Stack)
 {
@@ -784,7 +783,7 @@
   string format=vm::pop<string>(Stack,emptystring);
   picture * f=vm::pop<picture *>(Stack);
   string prefix=vm::pop<string>(Stack);
-#line 474 "runpicture.in"
+#line 472 "runpicture.in"
   size_t n=checkArrays(lights,diffuse);
   checkEqual(n,checkArray(specular));
   
@@ -804,7 +803,7 @@
   delete[] T;
 }
 
-#line 494 "runpicture.in"
+#line 492 "runpicture.in"
 // void shipout3(string prefix, picture *f, string format=defaultformat3);
 void gen_runpicture44(stack *Stack)
 {
@@ -811,17 +810,17 @@
   string format=vm::pop<string>(Stack,defaultformat3);
   picture * f=vm::pop<picture *>(Stack);
   string prefix=vm::pop<string>(Stack);
-#line 495 "runpicture.in"
+#line 493 "runpicture.in"
   f->shipout3(prefix,format);
 }
 
-#line 499 "runpicture.in"
+#line 497 "runpicture.in"
 // void xmap(string key, transform t=identity);
 void gen_runpicture45(stack *Stack)
 {
   transform t=vm::pop<transform>(Stack,identity);
   string key=vm::pop<string>(Stack);
-#line 500 "runpicture.in"
+#line 498 "runpicture.in"
   xmap_t &xmap=processData().xmap;
   xmap_t::iterator p=xmap.find(key);
   if(p != xmap.end())
@@ -833,7 +832,7 @@
   }
 }
 
-#line 512 "runpicture.in"
+#line 510 "runpicture.in"
 // void deconstruct(picture *f, picture *preamble=NULL, transform T=identity);
 void gen_runpicture46(stack *Stack)
 {
@@ -840,7 +839,7 @@
   transform T=vm::pop<transform>(Stack,identity);
   picture * preamble=vm::pop<picture *>(Stack,NULL);
   picture * f=vm::pop<picture *>(Stack);
-#line 513 "runpicture.in"
+#line 511 "runpicture.in"
   unsigned level=0;
 
   string prefix=outname();
@@ -935,29 +934,33 @@
 // Three-dimensional picture and surface operations
 
 // Bezier curve
-#line 608 "runpicture.in"
-// void _draw(picture *f, path3 g, triple center=Zero, pen p, Int interaction=0);
+#line 606 "runpicture.in"
+// void _draw(picture *f, path3 g, triple center=Zero, penarray *p,          real opacity, real shininess, real metallic, real fresnel0,          Int interaction=0);
 void gen_runpicture47(stack *Stack)
 {
   Int interaction=vm::pop<Int>(Stack,0);
-  pen p=vm::pop<pen>(Stack);
+  real fresnel0=vm::pop<real>(Stack);
+  real metallic=vm::pop<real>(Stack);
+  real shininess=vm::pop<real>(Stack);
+  real opacity=vm::pop<real>(Stack);
+  penarray * p=vm::pop<penarray *>(Stack);
   triple center=vm::pop<triple>(Stack,Zero);
   path3 g=vm::pop<path3>(Stack);
   picture * f=vm::pop<picture *>(Stack);
 #line 609 "runpicture.in"
   if(g.size() > 0)
-    f->append(new drawPath3(g,center,p,(Interaction) intcast(interaction)));
+    f->append(new drawPath3(g,center,*p,opacity,shininess,metallic,fresnel0,
+                            (Interaction) intcast(interaction)));
 }
 
 // Bezier patch
-#line 615 "runpicture.in"
-// void draw(picture *f, triplearray2 *P, triple center, bool straight,          penarray *p, real opacity, real shininess, real metallic, real fresnel0,          real PRCshininess, penarray *colors, Int interaction, bool prc=true);
+#line 616 "runpicture.in"
+// void draw(picture *f, triplearray2 *P, triple center, bool straight,          penarray *p, real opacity, real shininess, real metallic,          real fresnel0, penarray *colors, Int interaction,          bool primitive=false);
 void gen_runpicture48(stack *Stack)
 {
-  bool prc=vm::pop<bool>(Stack,true);
+  bool primitive=vm::pop<bool>(Stack,false);
   Int interaction=vm::pop<Int>(Stack);
   penarray * colors=vm::pop<penarray *>(Stack);
-  real PRCshininess=vm::pop<real>(Stack);
   real fresnel0=vm::pop<real>(Stack);
   real metallic=vm::pop<real>(Stack);
   real shininess=vm::pop<real>(Stack);
@@ -967,21 +970,20 @@
   triple center=vm::pop<triple>(Stack);
   triplearray2 * P=vm::pop<triplearray2 *>(Stack);
   picture * f=vm::pop<picture *>(Stack);
-#line 618 "runpicture.in"
+#line 620 "runpicture.in"
   f->append(new drawBezierPatch(*P,center,straight,*p,opacity,shininess,
-                                metallic,fresnel0,PRCshininess,*colors,
-                                (Interaction) intcast(interaction),prc));
+                                metallic,fresnel0,*colors,
+                                (Interaction) intcast(interaction),primitive));
 }
 
 // Bezier triangle
-#line 625 "runpicture.in"
-// void drawbeziertriangle(picture *f, triplearray2 *P, triple center,                        bool straight, penarray *p, real opacity,                        real shininess, real metallic, real fresnel0, real PRCshininess,                        penarray *colors, Int interaction, bool prc=true);
+#line 627 "runpicture.in"
+// void drawbeziertriangle(picture *f, triplearray2 *P, triple center,                        bool straight, penarray *p, real opacity,                        real shininess, real metallic, real fresnel0,                        penarray *colors, Int interaction,                        bool primitive=false);
 void gen_runpicture49(stack *Stack)
 {
-  bool prc=vm::pop<bool>(Stack,true);
+  bool primitive=vm::pop<bool>(Stack,false);
   Int interaction=vm::pop<Int>(Stack);
   penarray * colors=vm::pop<penarray *>(Stack);
-  real PRCshininess=vm::pop<real>(Stack);
   real fresnel0=vm::pop<real>(Stack);
   real metallic=vm::pop<real>(Stack);
   real shininess=vm::pop<real>(Stack);
@@ -991,14 +993,15 @@
   triple center=vm::pop<triple>(Stack);
   triplearray2 * P=vm::pop<triplearray2 *>(Stack);
   picture * f=vm::pop<picture *>(Stack);
-#line 629 "runpicture.in"
-  f->append(new drawBezierTriangle(*P,center,straight,*p,opacity,shininess, 
-                                    metallic,fresnel0,PRCshininess,*colors,
-                                   (Interaction) intcast(interaction),prc));
+#line 632 "runpicture.in"
+  f->append(new drawBezierTriangle(*P,center,straight,*p,opacity,shininess,
+                                   metallic,fresnel0,*colors,
+                                   (Interaction) intcast(interaction),
+                                   primitive));
 }
 
 // General NURBS curve
-#line 636 "runpicture.in"
+#line 640 "runpicture.in"
 // void draw(picture *f, triplearray *P, realarray *knot,          realarray *weights=emptyarray, pen p);
 void gen_runpicture50(stack *Stack)
 {
@@ -1007,17 +1010,16 @@
   realarray * knot=vm::pop<realarray *>(Stack);
   triplearray * P=vm::pop<triplearray *>(Stack);
   picture * f=vm::pop<picture *>(Stack);
-#line 638 "runpicture.in"
+#line 642 "runpicture.in"
   f->append(new drawNurbsPath3(*P,knot,weights,p));
 }
 
 // General NURBS surface
-#line 643 "runpicture.in"
-// void draw(picture *f, triplearray2 *P, realarray *uknot, realarray *vknot,          realarray2 *weights=emptyarray, penarray *p, real opacity,          real shininess,real metallic, real fresnel0,          real PRCshininess, penarray *colors);
+#line 647 "runpicture.in"
+// void draw(picture *f, triplearray2 *P, realarray *uknot, realarray *vknot,          realarray2 *weights=emptyarray, penarray *p, real opacity,          real shininess,real metallic, real fresnel0, penarray *colors);
 void gen_runpicture51(stack *Stack)
 {
   penarray * colors=vm::pop<penarray *>(Stack);
-  real PRCshininess=vm::pop<real>(Stack);
   real fresnel0=vm::pop<real>(Stack);
   real metallic=vm::pop<real>(Stack);
   real shininess=vm::pop<real>(Stack);
@@ -1028,17 +1030,19 @@
   realarray * uknot=vm::pop<realarray *>(Stack);
   triplearray2 * P=vm::pop<triplearray2 *>(Stack);
   picture * f=vm::pop<picture *>(Stack);
-#line 647 "runpicture.in"
-  f->append(new drawNurbs(*P,uknot,vknot,weights,*p,opacity,shininess, metallic, fresnel0,
-                          PRCshininess,*colors));
+#line 650 "runpicture.in"
+  f->append(new drawNurbs(*P,uknot,vknot,weights,*p,opacity,shininess,
+                          metallic,fresnel0,*colors));
 }
 
-// PRC unit sphere
-#line 653 "runpicture.in"
-// void drawPRCsphere(picture *f, realarray2 *t, bool half=false, penarray *p,                   real opacity, real shininess, Int type);
+// Sphere primitive
+#line 656 "runpicture.in"
+// void drawSphere(picture *f, realarray2 *t, bool half=false, penarray *p,                real opacity, real shininess, real metallic, real fresnel0,                Int type);
 void gen_runpicture52(stack *Stack)
 {
   Int type=vm::pop<Int>(Stack);
+  real fresnel0=vm::pop<real>(Stack);
+  real metallic=vm::pop<real>(Stack);
   real shininess=vm::pop<real>(Stack);
   real opacity=vm::pop<real>(Stack);
   penarray * p=vm::pop<penarray *>(Stack);
@@ -1045,55 +1049,67 @@
   bool half=vm::pop<bool>(Stack,false);
   realarray2 * t=vm::pop<realarray2 *>(Stack);
   picture * f=vm::pop<picture *>(Stack);
-#line 655 "runpicture.in"
-  f->append(new drawSphere(*t,half,*p,opacity,shininess,intcast(type)));
+#line 659 "runpicture.in"
+  f->append(new drawSphere(*t,half,*p,opacity,shininess,metallic,fresnel0,
+                           intcast(type)));
 }
 
-// PRC unit cylinder
-#line 660 "runpicture.in"
-// void drawPRCcylinder(picture *f, realarray2 *t, penarray *p, real opacity,                     real shininess);
+// Cylinder primitive
+#line 665 "runpicture.in"
+// void drawCylinder(picture *f, realarray2 *t, penarray *p, real opacity,                  real shininess, real metallic, real fresnel0,                  bool core=false);
 void gen_runpicture53(stack *Stack)
 {
+  bool core=vm::pop<bool>(Stack,false);
+  real fresnel0=vm::pop<real>(Stack);
+  real metallic=vm::pop<real>(Stack);
   real shininess=vm::pop<real>(Stack);
   real opacity=vm::pop<real>(Stack);
   penarray * p=vm::pop<penarray *>(Stack);
   realarray2 * t=vm::pop<realarray2 *>(Stack);
   picture * f=vm::pop<picture *>(Stack);
-#line 662 "runpicture.in"
-  f->append(new drawCylinder(*t,*p,opacity,shininess));
+#line 668 "runpicture.in"
+  f->append(new drawCylinder(*t,*p,opacity,shininess,metallic,fresnel0,core));
 }
 
-// PRC unit disk
-#line 667 "runpicture.in"
-// void drawPRCdisk(picture *f, realarray2 *t, penarray *p, real opacity,                 real shininess);
+// Disk primitive
+#line 673 "runpicture.in"
+// void drawDisk(picture *f, realarray2 *t, penarray *p, real opacity,              real shininess, real metallic, real fresnel0);
 void gen_runpicture54(stack *Stack)
 {
+  real fresnel0=vm::pop<real>(Stack);
+  real metallic=vm::pop<real>(Stack);
   real shininess=vm::pop<real>(Stack);
   real opacity=vm::pop<real>(Stack);
   penarray * p=vm::pop<penarray *>(Stack);
   realarray2 * t=vm::pop<realarray2 *>(Stack);
   picture * f=vm::pop<picture *>(Stack);
-#line 669 "runpicture.in"
-  f->append(new drawDisk(*t,*p,opacity,shininess));
+#line 675 "runpicture.in"
+  f->append(new drawDisk(*t,*p,opacity,shininess,metallic,fresnel0));
 }
 
-// General PRC tube
-#line 674 "runpicture.in"
-// void drawPRCtube(picture *f, path3 center, path3 g, penarray *p, real opacity,                 real shininess);
+// Tube primitive
+#line 680 "runpicture.in"
+// void drawTube(picture *f, triplearray *g, real width, penarray *p,              real opacity, real shininess, real metallic, real fresnel0,              triple min, triple max, bool core=false);
 void gen_runpicture55(stack *Stack)
 {
+  bool core=vm::pop<bool>(Stack,false);
+  triple max=vm::pop<triple>(Stack);
+  triple min=vm::pop<triple>(Stack);
+  real fresnel0=vm::pop<real>(Stack);
+  real metallic=vm::pop<real>(Stack);
   real shininess=vm::pop<real>(Stack);
   real opacity=vm::pop<real>(Stack);
   penarray * p=vm::pop<penarray *>(Stack);
-  path3 g=vm::pop<path3>(Stack);
-  path3 center=vm::pop<path3>(Stack);
+  real width=vm::pop<real>(Stack);
+  triplearray * g=vm::pop<triplearray *>(Stack);
   picture * f=vm::pop<picture *>(Stack);
-#line 676 "runpicture.in"
-  f->append(new drawTube(center,g,*p,opacity,shininess));
+#line 683 "runpicture.in"
+  f->append(new drawTube(*g,width,*p,opacity,shininess,metallic,fresnel0,
+                         min,max,core));
 }
 
 // Draw pixel
-#line 681 "runpicture.in"
+#line 689 "runpicture.in"
 // void drawpixel(picture *f, triple v, pen p, real width=1.0);
 void gen_runpicture56(stack *Stack)
 {
@@ -1101,18 +1117,17 @@
   pen p=vm::pop<pen>(Stack);
   triple v=vm::pop<triple>(Stack);
   picture * f=vm::pop<picture *>(Stack);
-#line 682 "runpicture.in"
+#line 690 "runpicture.in"
   f->append(new drawPixel(v,p,width));
 }
 
 // Draw triangles
-#line 687 "runpicture.in"
-// void draw(picture *f, triplearray *v, Intarray2 *vi,          triplearray *n, Intarray2 *ni,          penarray *p, real opacity, real shininess,           real metallic, real fresnel0, real PRCshininess,           penarray *c=emptyarray, Intarray2 *ci=emptyarray);
+#line 695 "runpicture.in"
+// void draw(picture *f, triplearray *v, Intarray2 *vi,          triplearray *n, Intarray2 *ni,          penarray *p, real opacity, real shininess,           real metallic, real fresnel0,          penarray *c=emptyarray, Intarray2 *ci=emptyarray);
 void gen_runpicture57(stack *Stack)
 {
   Intarray2 * ci=vm::pop<Intarray2 *>(Stack,emptyarray);
   penarray * c=vm::pop<penarray *>(Stack,emptyarray);
-  real PRCshininess=vm::pop<real>(Stack);
   real fresnel0=vm::pop<real>(Stack);
   real metallic=vm::pop<real>(Stack);
   real shininess=vm::pop<real>(Stack);
@@ -1123,63 +1138,63 @@
   Intarray2 * vi=vm::pop<Intarray2 *>(Stack);
   triplearray * v=vm::pop<triplearray *>(Stack);
   picture * f=vm::pop<picture *>(Stack);
-#line 692 "runpicture.in"
-  f->append(new drawTriangles(*v,*vi,*n,*ni,*p,opacity,shininess,metallic,fresnel0,PRCshininess,
-                              *c,*ci));
+#line 700 "runpicture.in"
+  f->append(new drawTriangles(*v,*vi,*n,*ni,*p,opacity,shininess,metallic,
+                              fresnel0,*c,*ci));
 }
 
-#line 697 "runpicture.in"
+#line 705 "runpicture.in"
 // triple min3(picture *f);
 void gen_runpicture58(stack *Stack)
 {
   picture * f=vm::pop<picture *>(Stack);
-#line 698 "runpicture.in"
+#line 706 "runpicture.in"
   {Stack->push<triple>(f->bounds3().Min()); return;}
 }
 
-#line 702 "runpicture.in"
+#line 710 "runpicture.in"
 // triple max3(picture *f);
 void gen_runpicture59(stack *Stack)
 {
   picture * f=vm::pop<picture *>(Stack);
-#line 703 "runpicture.in"
+#line 711 "runpicture.in"
   {Stack->push<triple>(f->bounds3().Max()); return;}
 }
 
-#line 707 "runpicture.in"
+#line 715 "runpicture.in"
 // triple size3(picture *f);
 void gen_runpicture60(stack *Stack)
 {
   picture * f=vm::pop<picture *>(Stack);
-#line 708 "runpicture.in"
+#line 716 "runpicture.in"
   bbox3 b=f->bounds3();
   {Stack->push<triple>(b.Max()-b.Min()); return;}
 }
 
-#line 713 "runpicture.in"
+#line 721 "runpicture.in"
 // pair minratio(picture *f);
 void gen_runpicture61(stack *Stack)
 {
   picture * f=vm::pop<picture *>(Stack);
-#line 714 "runpicture.in"
+#line 722 "runpicture.in"
   {Stack->push<pair>(f->ratio(::min)); return;}
 }
 
-#line 718 "runpicture.in"
+#line 726 "runpicture.in"
 // pair maxratio(picture *f);
 void gen_runpicture62(stack *Stack)
 {
   picture * f=vm::pop<picture *>(Stack);
-#line 719 "runpicture.in"
+#line 727 "runpicture.in"
   {Stack->push<pair>(f->ratio(::max)); return;}
 }
 
-#line 723 "runpicture.in"
+#line 731 "runpicture.in"
 // bool is3D(picture *f);
 void gen_runpicture63(stack *Stack)
 {
   picture * f=vm::pop<picture *>(Stack);
-#line 724 "runpicture.in"
+#line 732 "runpicture.in"
   {Stack->push<bool>(f->have3D()); return;}
 }
 
@@ -1189,133 +1204,133 @@
 
 void gen_runpicture_venv(venv &ve)
 {
-#line 128 "runpicture.in"
+#line 126 "runpicture.in"
   REGISTER_BLTIN(run::newPicture,"newPicture");
-#line 133 "runpicture.in"
+#line 131 "runpicture.in"
   addFunc(ve, run::gen_runpicture1, primBoolean(), SYM(empty), formal(primPicture(), SYM(f), false, false));
-#line 138 "runpicture.in"
+#line 136 "runpicture.in"
   addFunc(ve, run::gen_runpicture2, primVoid(), SYM(erase), formal(primPicture(), SYM(f), false, false));
-#line 143 "runpicture.in"
+#line 141 "runpicture.in"
   addFunc(ve, run::gen_runpicture3, primPair(), SYM(min), formal(primPicture(), SYM(f), false, false));
-#line 148 "runpicture.in"
+#line 146 "runpicture.in"
   addFunc(ve, run::gen_runpicture4, primPair(), SYM(max), formal(primPicture(), SYM(f), false, false));
-#line 153 "runpicture.in"
+#line 151 "runpicture.in"
   addFunc(ve, run::gen_runpicture5, primPair(), SYM(size), formal(primPicture(), SYM(f), false, false));
-#line 159 "runpicture.in"
+#line 157 "runpicture.in"
   addFunc(ve, run::gen_runpicture6, primVoid(), SYM(_draw), formal(primPicture(), SYM(f), false, false), formal(primPath(), SYM(g), false, false), formal(primPen(), SYM(p), false, false));
-#line 164 "runpicture.in"
+#line 162 "runpicture.in"
   addFunc(ve, run::gen_runpicture7, primVoid(), SYM(fill), formal(primPicture(), SYM(f), false, false), formal(pathArray()  , SYM(g), false, false), formal(primPen(), SYM(p), true, false), formal(primBoolean(), SYM(copy), true, false));
-#line 170 "runpicture.in"
+#line 168 "runpicture.in"
   addFunc(ve, run::gen_runpicture8, primVoid(), SYM(latticeshade), formal(primPicture(), SYM(f), false, false), formal(pathArray()  , SYM(g), false, false), formal(primBoolean(), SYM(stroke), true, false), formal(primPen(), SYM(fillrule), true, false), formal(penArray2()  , SYM(p), false, false), formal(primTransform(), SYM(t), true, false), formal(primBoolean(), SYM(copy), true, false));
-#line 179 "runpicture.in"
+#line 177 "runpicture.in"
   addFunc(ve, run::gen_runpicture9, primVoid(), SYM(axialshade), formal(primPicture(), SYM(f), false, false), formal(pathArray()  , SYM(g), false, false), formal(primBoolean(), SYM(stroke), true, false), formal(primPen(), SYM(pena), false, false), formal(primPair(), SYM(a), false, false), formal(primBoolean(), SYM(extenda), true, false), formal(primPen(), SYM(penb), false, false), formal(primPair(), SYM(b), false, false), formal(primBoolean(), SYM(extendb), true, false), formal(primBoolean(), SYM(copy), true, false));
-#line 188 "runpicture.in"
+#line 186 "runpicture.in"
   addFunc(ve, run::gen_runpicture10, primVoid(), SYM(radialshade), formal(primPicture(), SYM(f), false, false), formal(pathArray()  , SYM(g), false, false), formal(primBoolean(), SYM(stroke), true, false), formal(primPen(), SYM(pena), false, false), formal(primPair(), SYM(a), false, false), formal(primReal(), SYM(ra), false, false), formal(primBoolean(), SYM(extenda), true, false), formal(primPen(), SYM(penb), false, false), formal(primPair(), SYM(b), false, false), formal(primReal(), SYM(rb), false, false), formal(primBoolean(), SYM(extendb), true, false), formal(primBoolean(), SYM(copy), true, false));
-#line 197 "runpicture.in"
+#line 195 "runpicture.in"
   addFunc(ve, run::gen_runpicture11, primVoid(), SYM(gouraudshade), formal(primPicture(), SYM(f), false, false), formal(pathArray()  , SYM(g), false, false), formal(primBoolean(), SYM(stroke), true, false), formal(primPen(), SYM(fillrule), true, false), formal(penArray()  , SYM(p), false, false), formal(pairArray(), SYM(z), false, false), formal(IntArray(), SYM(edges), false, false), formal(primBoolean(), SYM(copy), true, false));
-#line 208 "runpicture.in"
+#line 206 "runpicture.in"
   addFunc(ve, run::gen_runpicture12, primVoid(), SYM(gouraudshade), formal(primPicture(), SYM(f), false, false), formal(pathArray()  , SYM(g), false, false), formal(primBoolean(), SYM(stroke), true, false), formal(primPen(), SYM(fillrule), true, false), formal(penArray()  , SYM(p), false, false), formal(IntArray(), SYM(edges), false, false), formal(primBoolean(), SYM(copy), true, false));
-#line 232 "runpicture.in"
+#line 230 "runpicture.in"
   addFunc(ve, run::gen_runpicture13, primVoid(), SYM(tensorshade), formal(primPicture(), SYM(f), false, false), formal(pathArray()  , SYM(g), false, false), formal(primBoolean(), SYM(stroke), true, false), formal(primPen(), SYM(fillrule), true, false), formal(penArray2()  , SYM(p), false, false), formal(pathArray()  , SYM(b), true, false), formal(pairArray2(), SYM(z), true, false), formal(primBoolean(), SYM(copy), true, false));
-#line 247 "runpicture.in"
+#line 245 "runpicture.in"
   addFunc(ve, run::gen_runpicture14, primVoid(), SYM(functionshade), formal(primPicture(), SYM(f), false, false), formal(pathArray()  , SYM(g), false, false), formal(primBoolean(), SYM(stroke), true, false), formal(primPen(), SYM(fillrule), true, false), formal(primString() , SYM(shader), true, false), formal(primBoolean(), SYM(copy), true, false));
-#line 255 "runpicture.in"
+#line 253 "runpicture.in"
   addFunc(ve, run::gen_runpicture15, primVoid(), SYM(clip), formal(primPicture(), SYM(f), false, false), formal(pathArray()  , SYM(g), false, false), formal(primBoolean(), SYM(stroke), true, false), formal(primPen(), SYM(fillrule), true, false), formal(primBoolean(), SYM(copy), true, false));
-#line 265 "runpicture.in"
+#line 263 "runpicture.in"
   addFunc(ve, run::gen_runpicture16, primVoid(), SYM(beginclip), formal(primPicture(), SYM(f), false, false), formal(pathArray()  , SYM(g), false, false), formal(primBoolean(), SYM(stroke), true, false), formal(primPen(), SYM(fillrule), true, false), formal(primBoolean(), SYM(copy), true, false));
-#line 272 "runpicture.in"
+#line 270 "runpicture.in"
   addFunc(ve, run::gen_runpicture17, primVoid(), SYM(endclip), formal(primPicture(), SYM(f), false, false));
-#line 277 "runpicture.in"
+#line 275 "runpicture.in"
   addFunc(ve, run::gen_runpicture18, primVoid(), SYM(gsave), formal(primPicture(), SYM(f), false, false));
-#line 282 "runpicture.in"
+#line 280 "runpicture.in"
   addFunc(ve, run::gen_runpicture19, primVoid(), SYM(grestore), formal(primPicture(), SYM(f), false, false));
-#line 287 "runpicture.in"
+#line 285 "runpicture.in"
   addFunc(ve, run::gen_runpicture20, primVoid(), SYM(begingroup), formal(primPicture(), SYM(f), false, false));
-#line 292 "runpicture.in"
+#line 290 "runpicture.in"
   addFunc(ve, run::gen_runpicture21, primVoid(), SYM(endgroup), formal(primPicture(), SYM(f), false, false));
-#line 297 "runpicture.in"
+#line 295 "runpicture.in"
   addFunc(ve, run::gen_runpicture22, primVoid(), SYM(_begingroup3), formal(primPicture(), SYM(f), false, false), formal(primString() , SYM(name), false, false), formal(primReal(), SYM(compression), false, false), formal(primReal(), SYM(granularity), false, false), formal(primBoolean(), SYM(closed), false, false), formal(primBoolean(), SYM(tessellate), false, false), formal(primBoolean(), SYM(dobreak), false, false), formal(primBoolean(), SYM(nobreak), false, false), formal(primTriple(), SYM(center), false, false), formal(primInt(), SYM(interaction), false, false));
-#line 306 "runpicture.in"
+#line 304 "runpicture.in"
   addFunc(ve, run::gen_runpicture23, primVoid(), SYM(endgroup3), formal(primPicture(), SYM(f), false, false));
-#line 311 "runpicture.in"
+#line 309 "runpicture.in"
   addFunc(ve, run::gen_runpicture24, primVoid(), SYM(add), formal(primPicture(), SYM(dest), false, false), formal(primPicture(), SYM(src), false, false));
-#line 316 "runpicture.in"
+#line 314 "runpicture.in"
   addFunc(ve, run::gen_runpicture25, primVoid(), SYM(prepend), formal(primPicture(), SYM(dest), false, false), formal(primPicture(), SYM(src), false, false));
-#line 321 "runpicture.in"
+#line 319 "runpicture.in"
   addFunc(ve, run::gen_runpicture26, primVoid(), SYM(postscript), formal(primPicture(), SYM(f), false, false), formal(primString() , SYM(s), false, false));
-#line 326 "runpicture.in"
+#line 324 "runpicture.in"
   addFunc(ve, run::gen_runpicture27, primVoid(), SYM(tex), formal(primPicture(), SYM(f), false, false), formal(primString() , SYM(s), false, false));
-#line 331 "runpicture.in"
+#line 329 "runpicture.in"
   addFunc(ve, run::gen_runpicture28, primVoid(), SYM(postscript), formal(primPicture(), SYM(f), false, false), formal(primString() , SYM(s), false, false), formal(primPair(), SYM(min), false, false), formal(primPair(), SYM(max), false, false));
-#line 336 "runpicture.in"
+#line 334 "runpicture.in"
   addFunc(ve, run::gen_runpicture29, primVoid(), SYM(tex), formal(primPicture(), SYM(f), false, false), formal(primString() , SYM(s), false, false), formal(primPair(), SYM(min), false, false), formal(primPair(), SYM(max), false, false));
-#line 341 "runpicture.in"
+#line 339 "runpicture.in"
   addFunc(ve, run::gen_runpicture30, primVoid(), SYM(texpreamble), formal(primString() , SYM(s), false, false));
-#line 349 "runpicture.in"
+#line 347 "runpicture.in"
   addFunc(ve, run::gen_runpicture31, primVoid(), SYM(deletepreamble));
-#line 356 "runpicture.in"
+#line 354 "runpicture.in"
   addFunc(ve, run::gen_runpicture32, primVoid(), SYM(_labelpath), formal(primPicture(), SYM(f), false, false), formal(primString() , SYM(s), false, false), formal(primString() , SYM(size), false, false), formal(primPath(), SYM(g), false, false), formal(primString() , SYM(justify), false, false), formal(primPair(), SYM(offset), false, false), formal(primPen(), SYM(p), false, false));
-#line 362 "runpicture.in"
+#line 360 "runpicture.in"
   addFunc(ve, run::gen_runpicture33, primVoid(), SYM(texreset));
-#line 370 "runpicture.in"
+#line 368 "runpicture.in"
   addFunc(ve, run::gen_runpicture34, primVoid(), SYM(layer), formal(primPicture(), SYM(f), false, false));
-#line 375 "runpicture.in"
+#line 373 "runpicture.in"
   addFunc(ve, run::gen_runpicture35, primVoid(), SYM(newpage), formal(primPicture(), SYM(f), false, false));
-#line 380 "runpicture.in"
+#line 378 "runpicture.in"
   addFunc(ve, run::gen_runpicture36, primVoid(), SYM(_image), formal(primPicture(), SYM(f), false, false), formal(realArray2(), SYM(data), false, false), formal(primPair(), SYM(initial), false, false), formal(primPair(), SYM(final), false, false), formal(penArray()  , SYM(palette), true, false), formal(primTransform(), SYM(t), true, false), formal(primBoolean(), SYM(copy), true, false), formal(primBoolean(), SYM(antialias), true, false));
-#line 390 "runpicture.in"
+#line 388 "runpicture.in"
   addFunc(ve, run::gen_runpicture37, primVoid(), SYM(_image), formal(primPicture(), SYM(f), false, false), formal(penArray2()  , SYM(data), false, false), formal(primPair(), SYM(initial), false, false), formal(primPair(), SYM(final), false, false), formal(primTransform(), SYM(t), true, false), formal(primBoolean(), SYM(copy), true, false), formal(primBoolean(), SYM(antialias), true, false));
-#line 398 "runpicture.in"
+#line 396 "runpicture.in"
   addFunc(ve, run::gen_runpicture38, primVoid(), SYM(_image), formal(primPicture(), SYM(f), false, false), formal(penFunction(), SYM(f), false, false), formal(primInt(), SYM(width), false, false), formal(primInt(), SYM(height), false, false), formal(primPair(), SYM(initial), false, false), formal(primPair(), SYM(final), false, false), formal(primTransform(), SYM(t), true, false), formal(primBoolean(), SYM(antialias), true, false));
-#line 405 "runpicture.in"
+#line 403 "runpicture.in"
   addFunc(ve, run::gen_runpicture39, primString() , SYM(nativeformat));
-#line 410 "runpicture.in"
+#line 408 "runpicture.in"
   addFunc(ve, run::gen_runpicture40, primBoolean(), SYM(latex));
-#line 415 "runpicture.in"
+#line 413 "runpicture.in"
   addFunc(ve, run::gen_runpicture41, primBoolean(), SYM(pdf));
-#line 420 "runpicture.in"
+#line 418 "runpicture.in"
   addFunc(ve, run::gen_runpicture42, primVoid(), SYM(_shipout), formal(primString() , SYM(prefix), true, false), formal(primPicture(), SYM(f), false, false), formal(primPicture(), SYM(preamble), true, false), formal(primString() , SYM(format), true, false), formal(primBoolean(), SYM(wait), true, false), formal(primBoolean(), SYM(view), true, false), formal(primTransform(), SYM(t), true, false));
-#line 469 "runpicture.in"
+#line 467 "runpicture.in"
   addFunc(ve, run::gen_runpicture43, primVoid(), SYM(shipout3), formal(primString() , SYM(prefix), false, false), formal(primPicture(), SYM(f), false, false), formal(primString() , SYM(format), true, false), formal(primReal(), SYM(width), false, false), formal(primReal(), SYM(height), false, false), formal(primReal(), SYM(angle), false, false), formal(primReal(), SYM(zoom), false, false), formal(primTriple(), SYM(m), false, false), formal(primTriple(), SYM(m), false, false), formal(primPair(), SYM(shift), false, false), formal(primPair(), SYM(margin), false, false), formal(realArray2(), SYM(t), false, false), formal(realArray(), SYM(background), false, false), formal(tripleArray(), SYM(lights), false, false), formal(realArray2(), SYM(diffuse), false, false), formal(realArray2(), SYM(specular), false, false), formal(primBoolean(), SYM(view), true, false));
-#line 494 "runpicture.in"
+#line 492 "runpicture.in"
   addFunc(ve, run::gen_runpicture44, primVoid(), SYM(shipout3), formal(primString() , SYM(prefix), false, false), formal(primPicture(), SYM(f), false, false), formal(primString() , SYM(format), true, false));
-#line 499 "runpicture.in"
+#line 497 "runpicture.in"
   addFunc(ve, run::gen_runpicture45, primVoid(), SYM(xmap), formal(primString() , SYM(key), false, false), formal(primTransform(), SYM(t), true, false));
-#line 512 "runpicture.in"
+#line 510 "runpicture.in"
   addFunc(ve, run::gen_runpicture46, primVoid(), SYM(deconstruct), formal(primPicture(), SYM(f), false, false), formal(primPicture(), SYM(preamble), true, false), formal(primTransform(), SYM(t), true, false));
-#line 604 "runpicture.in"
-  addFunc(ve, run::gen_runpicture47, primVoid(), SYM(_draw), formal(primPicture(), SYM(f), false, false), formal(primPath3(), SYM(g), false, false), formal(primTriple(), SYM(center), true, false), formal(primPen(), SYM(p), false, false), formal(primInt(), SYM(interaction), true, false));
-#line 614 "runpicture.in"
-  addFunc(ve, run::gen_runpicture48, primVoid(), SYM(draw), formal(primPicture(), SYM(f), false, false), formal(tripleArray2(), SYM(p), false, false), formal(primTriple(), SYM(center), false, false), formal(primBoolean(), SYM(straight), false, false), formal(penArray()  , SYM(p), false, false), formal(primReal(), SYM(opacity), false, false), formal(primReal(), SYM(shininess), false, false), formal(primReal(), SYM(metallic), false, false), formal(primReal(), SYM(fresnel0), false, false), formal(primReal(), SYM(prcshininess), false, false), formal(penArray()  , SYM(colors), false, false), formal(primInt(), SYM(interaction), false, false), formal(primBoolean(), SYM(prc), true, false));
-#line 624 "runpicture.in"
-  addFunc(ve, run::gen_runpicture49, primVoid(), SYM(drawbeziertriangle), formal(primPicture(), SYM(f), false, false), formal(tripleArray2(), SYM(p), false, false), formal(primTriple(), SYM(center), false, false), formal(primBoolean(), SYM(straight), false, false), formal(penArray()  , SYM(p), false, false), formal(primReal(), SYM(opacity), false, false), formal(primReal(), SYM(shininess), false, false), formal(primReal(), SYM(metallic), false, false), formal(primReal(), SYM(fresnel0), false, false), formal(primReal(), SYM(prcshininess), false, false), formal(penArray()  , SYM(colors), false, false), formal(primInt(), SYM(interaction), false, false), formal(primBoolean(), SYM(prc), true, false));
-#line 635 "runpicture.in"
+#line 602 "runpicture.in"
+  addFunc(ve, run::gen_runpicture47, primVoid(), SYM(_draw), formal(primPicture(), SYM(f), false, false), formal(primPath3(), SYM(g), false, false), formal(primTriple(), SYM(center), true, false), formal(penArray()  , SYM(p), false, false), formal(primReal(), SYM(opacity), false, false), formal(primReal(), SYM(shininess), false, false), formal(primReal(), SYM(metallic), false, false), formal(primReal(), SYM(fresnel0), false, false), formal(primInt(), SYM(interaction), true, false));
+#line 615 "runpicture.in"
+  addFunc(ve, run::gen_runpicture48, primVoid(), SYM(draw), formal(primPicture(), SYM(f), false, false), formal(tripleArray2(), SYM(p), false, false), formal(primTriple(), SYM(center), false, false), formal(primBoolean(), SYM(straight), false, false), formal(penArray()  , SYM(p), false, false), formal(primReal(), SYM(opacity), false, false), formal(primReal(), SYM(shininess), false, false), formal(primReal(), SYM(metallic), false, false), formal(primReal(), SYM(fresnel0), false, false), formal(penArray()  , SYM(colors), false, false), formal(primInt(), SYM(interaction), false, false), formal(primBoolean(), SYM(primitive), true, false));
+#line 626 "runpicture.in"
+  addFunc(ve, run::gen_runpicture49, primVoid(), SYM(drawbeziertriangle), formal(primPicture(), SYM(f), false, false), formal(tripleArray2(), SYM(p), false, false), formal(primTriple(), SYM(center), false, false), formal(primBoolean(), SYM(straight), false, false), formal(penArray()  , SYM(p), false, false), formal(primReal(), SYM(opacity), false, false), formal(primReal(), SYM(shininess), false, false), formal(primReal(), SYM(metallic), false, false), formal(primReal(), SYM(fresnel0), false, false), formal(penArray()  , SYM(colors), false, false), formal(primInt(), SYM(interaction), false, false), formal(primBoolean(), SYM(primitive), true, false));
+#line 639 "runpicture.in"
   addFunc(ve, run::gen_runpicture50, primVoid(), SYM(draw), formal(primPicture(), SYM(f), false, false), formal(tripleArray(), SYM(p), false, false), formal(realArray(), SYM(knot), false, false), formal(realArray(), SYM(weights), true, false), formal(primPen(), SYM(p), false, false));
-#line 642 "runpicture.in"
-  addFunc(ve, run::gen_runpicture51, primVoid(), SYM(draw), formal(primPicture(), SYM(f), false, false), formal(tripleArray2(), SYM(p), false, false), formal(realArray(), SYM(uknot), false, false), formal(realArray(), SYM(vknot), false, false), formal(realArray2(), SYM(weights), true, false), formal(penArray()  , SYM(p), false, false), formal(primReal(), SYM(opacity), false, false), formal(primReal(), SYM(shininess), false, false), formal(primReal(), SYM(metallic), false, false), formal(primReal(), SYM(fresnel0), false, false), formal(primReal(), SYM(prcshininess), false, false), formal(penArray()  , SYM(colors), false, false));
-#line 652 "runpicture.in"
-  addFunc(ve, run::gen_runpicture52, primVoid(), SYM(drawPRCsphere), formal(primPicture(), SYM(f), false, false), formal(realArray2(), SYM(t), false, false), formal(primBoolean(), SYM(half), true, false), formal(penArray()  , SYM(p), false, false), formal(primReal(), SYM(opacity), false, false), formal(primReal(), SYM(shininess), false, false), formal(primInt(), SYM(type), false, false));
-#line 659 "runpicture.in"
-  addFunc(ve, run::gen_runpicture53, primVoid(), SYM(drawPRCcylinder), formal(primPicture(), SYM(f), false, false), formal(realArray2(), SYM(t), false, false), formal(penArray()  , SYM(p), false, false), formal(primReal(), SYM(opacity), false, false), formal(primReal(), SYM(shininess), false, false));
-#line 666 "runpicture.in"
-  addFunc(ve, run::gen_runpicture54, primVoid(), SYM(drawPRCdisk), formal(primPicture(), SYM(f), false, false), formal(realArray2(), SYM(t), false, false), formal(penArray()  , SYM(p), false, false), formal(primReal(), SYM(opacity), false, false), formal(primReal(), SYM(shininess), false, false));
-#line 673 "runpicture.in"
-  addFunc(ve, run::gen_runpicture55, primVoid(), SYM(drawPRCtube), formal(primPicture(), SYM(f), false, false), formal(primPath3(), SYM(center), false, false), formal(primPath3(), SYM(g), false, false), formal(penArray()  , SYM(p), false, false), formal(primReal(), SYM(opacity), false, false), formal(primReal(), SYM(shininess), false, false));
-#line 680 "runpicture.in"
+#line 646 "runpicture.in"
+  addFunc(ve, run::gen_runpicture51, primVoid(), SYM(draw), formal(primPicture(), SYM(f), false, false), formal(tripleArray2(), SYM(p), false, false), formal(realArray(), SYM(uknot), false, false), formal(realArray(), SYM(vknot), false, false), formal(realArray2(), SYM(weights), true, false), formal(penArray()  , SYM(p), false, false), formal(primReal(), SYM(opacity), false, false), formal(primReal(), SYM(shininess), false, false), formal(primReal(), SYM(metallic), false, false), formal(primReal(), SYM(fresnel0), false, false), formal(penArray()  , SYM(colors), false, false));
+#line 655 "runpicture.in"
+  addFunc(ve, run::gen_runpicture52, primVoid(), SYM(drawSphere), formal(primPicture(), SYM(f), false, false), formal(realArray2(), SYM(t), false, false), formal(primBoolean(), SYM(half), true, false), formal(penArray()  , SYM(p), false, false), formal(primReal(), SYM(opacity), false, false), formal(primReal(), SYM(shininess), false, false), formal(primReal(), SYM(metallic), false, false), formal(primReal(), SYM(fresnel0), false, false), formal(primInt(), SYM(type), false, false));
+#line 664 "runpicture.in"
+  addFunc(ve, run::gen_runpicture53, primVoid(), SYM(drawCylinder), formal(primPicture(), SYM(f), false, false), formal(realArray2(), SYM(t), false, false), formal(penArray()  , SYM(p), false, false), formal(primReal(), SYM(opacity), false, false), formal(primReal(), SYM(shininess), false, false), formal(primReal(), SYM(metallic), false, false), formal(primReal(), SYM(fresnel0), false, false), formal(primBoolean(), SYM(core), true, false));
+#line 672 "runpicture.in"
+  addFunc(ve, run::gen_runpicture54, primVoid(), SYM(drawDisk), formal(primPicture(), SYM(f), false, false), formal(realArray2(), SYM(t), false, false), formal(penArray()  , SYM(p), false, false), formal(primReal(), SYM(opacity), false, false), formal(primReal(), SYM(shininess), false, false), formal(primReal(), SYM(metallic), false, false), formal(primReal(), SYM(fresnel0), false, false));
+#line 679 "runpicture.in"
+  addFunc(ve, run::gen_runpicture55, primVoid(), SYM(drawTube), formal(primPicture(), SYM(f), false, false), formal(tripleArray(), SYM(g), false, false), formal(primReal(), SYM(width), false, false), formal(penArray()  , SYM(p), false, false), formal(primReal(), SYM(opacity), false, false), formal(primReal(), SYM(shininess), false, false), formal(primReal(), SYM(metallic), false, false), formal(primReal(), SYM(fresnel0), false, false), formal(primTriple(), SYM(min), false, false), formal(primTriple(), SYM(max), false, false), formal(primBoolean(), SYM(core), true, false));
+#line 688 "runpicture.in"
   addFunc(ve, run::gen_runpicture56, primVoid(), SYM(drawpixel), formal(primPicture(), SYM(f), false, false), formal(primTriple(), SYM(v), false, false), formal(primPen(), SYM(p), false, false), formal(primReal(), SYM(width), true, false));
-#line 686 "runpicture.in"
-  addFunc(ve, run::gen_runpicture57, primVoid(), SYM(draw), formal(primPicture(), SYM(f), false, false), formal(tripleArray(), SYM(v), false, false), formal(IntArray2(), SYM(vi), false, false), formal(tripleArray(), SYM(n), false, false), formal(IntArray2(), SYM(ni), false, false), formal(penArray()  , SYM(p), false, false), formal(primReal(), SYM(opacity), false, false), formal(primReal(), SYM(shininess), false, false), formal(primReal(), SYM(metallic), false, false), formal(primReal(), SYM(fresnel0), false, false), formal(primReal(), SYM(prcshininess), false, false), formal(penArray()  , SYM(c), true, false), formal(IntArray2(), SYM(ci), true, false));
-#line 697 "runpicture.in"
+#line 694 "runpicture.in"
+  addFunc(ve, run::gen_runpicture57, primVoid(), SYM(draw), formal(primPicture(), SYM(f), false, false), formal(tripleArray(), SYM(v), false, false), formal(IntArray2(), SYM(vi), false, false), formal(tripleArray(), SYM(n), false, false), formal(IntArray2(), SYM(ni), false, false), formal(penArray()  , SYM(p), false, false), formal(primReal(), SYM(opacity), false, false), formal(primReal(), SYM(shininess), false, false), formal(primReal(), SYM(metallic), false, false), formal(primReal(), SYM(fresnel0), false, false), formal(penArray()  , SYM(c), true, false), formal(IntArray2(), SYM(ci), true, false));
+#line 705 "runpicture.in"
   addFunc(ve, run::gen_runpicture58, primTriple(), SYM(min3), formal(primPicture(), SYM(f), false, false));
-#line 702 "runpicture.in"
+#line 710 "runpicture.in"
   addFunc(ve, run::gen_runpicture59, primTriple(), SYM(max3), formal(primPicture(), SYM(f), false, false));
-#line 707 "runpicture.in"
+#line 715 "runpicture.in"
   addFunc(ve, run::gen_runpicture60, primTriple(), SYM(size3), formal(primPicture(), SYM(f), false, false));
-#line 713 "runpicture.in"
+#line 721 "runpicture.in"
   addFunc(ve, run::gen_runpicture61, primPair(), SYM(minratio), formal(primPicture(), SYM(f), false, false));
-#line 718 "runpicture.in"
+#line 726 "runpicture.in"
   addFunc(ve, run::gen_runpicture62, primPair(), SYM(maxratio), formal(primPicture(), SYM(f), false, false));
-#line 723 "runpicture.in"
+#line 731 "runpicture.in"
   addFunc(ve, run::gen_runpicture63, primBoolean(), SYM(is3D), formal(primPicture(), SYM(f), false, false));
 }
 

Modified: trunk/Build/source/utils/asymptote/runpicture.in
===================================================================
--- trunk/Build/source/utils/asymptote/runpicture.in	2020-03-03 22:33:26 UTC (rev 54033)
+++ trunk/Build/source/utils/asymptote/runpicture.in	2020-03-03 22:35:09 UTC (rev 54034)
@@ -23,7 +23,6 @@
 triplearray* => tripleArray()
 triplearray2* => tripleArray2()
 transform => primTransform()
-callableTransform* => transformFunction()
 callablePen* => penFunction()
 

 #include "picture.h"
@@ -61,7 +60,6 @@
 typedef array penarray;
 typedef array penarray2;
 
-typedef callable callableTransform;
 typedef callable callablePen;
 
 using types::IntArray;
@@ -605,31 +603,37 @@
 // Three-dimensional picture and surface operations
 
 // Bezier curve
-void _draw(picture *f, path3 g, triple center=Zero, pen p, Int interaction=0)
+void _draw(picture *f, path3 g, triple center=Zero, penarray *p,
+          real opacity, real shininess, real metallic, real fresnel0,
+          Int interaction=0)
 {
   if(g.size() > 0)
-    f->append(new drawPath3(g,center,p,(Interaction) intcast(interaction)));
+    f->append(new drawPath3(g,center,*p,opacity,shininess,metallic,fresnel0,
+                            (Interaction) intcast(interaction)));
 }
 

 // Bezier patch
 void draw(picture *f, triplearray2 *P, triple center, bool straight,
-          penarray *p, real opacity, real shininess, real metallic, real fresnel0,
-          real PRCshininess, penarray *colors, Int interaction, bool prc=true)
+          penarray *p, real opacity, real shininess, real metallic,
+          real fresnel0, penarray *colors, Int interaction,
+          bool primitive=false)
 {
   f->append(new drawBezierPatch(*P,center,straight,*p,opacity,shininess,
-                                metallic,fresnel0,PRCshininess,*colors,
-                                (Interaction) intcast(interaction),prc));
+                                metallic,fresnel0,*colors,
+                                (Interaction) intcast(interaction),primitive));
 }
 

 // Bezier triangle
 void drawbeziertriangle(picture *f, triplearray2 *P, triple center,
                         bool straight, penarray *p, real opacity,
-                        real shininess, real metallic, real fresnel0, real PRCshininess,
-                        penarray *colors, Int interaction, bool prc=true)
+                        real shininess, real metallic, real fresnel0,
+                        penarray *colors, Int interaction,
+                        bool primitive=false)
 {
-  f->append(new drawBezierTriangle(*P,center,straight,*p,opacity,shininess, 
-                                    metallic,fresnel0,PRCshininess,*colors,
-                                   (Interaction) intcast(interaction),prc));
+  f->append(new drawBezierTriangle(*P,center,straight,*p,opacity,shininess,
+                                   metallic,fresnel0,*colors,
+                                   (Interaction) intcast(interaction),
+                                   primitive));
 }
 

 // General NURBS curve
@@ -642,39 +646,43 @@
 // General NURBS surface
 void draw(picture *f, triplearray2 *P, realarray *uknot, realarray *vknot,
           realarray2 *weights=emptyarray, penarray *p, real opacity,
-          real shininess,real metallic, real fresnel0,
-          real PRCshininess, penarray *colors)
+          real shininess,real metallic, real fresnel0, penarray *colors)
 {
-  f->append(new drawNurbs(*P,uknot,vknot,weights,*p,opacity,shininess, metallic, fresnel0,
-                          PRCshininess,*colors));
+  f->append(new drawNurbs(*P,uknot,vknot,weights,*p,opacity,shininess,
+                          metallic,fresnel0,*colors));
 }
 

-// PRC unit sphere
-void drawPRCsphere(picture *f, realarray2 *t, bool half=false, penarray *p,
-                   real opacity, real shininess, Int type)
+// Sphere primitive
+void drawSphere(picture *f, realarray2 *t, bool half=false, penarray *p,
+                real opacity, real shininess, real metallic, real fresnel0,
+                Int type)
 {
-  f->append(new drawSphere(*t,half,*p,opacity,shininess,intcast(type)));
+  f->append(new drawSphere(*t,half,*p,opacity,shininess,metallic,fresnel0,
+                           intcast(type)));
 }
 

-// PRC unit cylinder
-void drawPRCcylinder(picture *f, realarray2 *t, penarray *p, real opacity,
-                     real shininess)
+// Cylinder primitive
+void drawCylinder(picture *f, realarray2 *t, penarray *p, real opacity,
+                  real shininess, real metallic, real fresnel0,
+                  bool core=false)
 {
-  f->append(new drawCylinder(*t,*p,opacity,shininess));
+  f->append(new drawCylinder(*t,*p,opacity,shininess,metallic,fresnel0,core));
 }
 

-// PRC unit disk
-void drawPRCdisk(picture *f, realarray2 *t, penarray *p, real opacity,
-                 real shininess)
+// Disk primitive
+void drawDisk(picture *f, realarray2 *t, penarray *p, real opacity,
+              real shininess, real metallic, real fresnel0)
 {
-  f->append(new drawDisk(*t,*p,opacity,shininess));
+  f->append(new drawDisk(*t,*p,opacity,shininess,metallic,fresnel0));
 }
 

-// General PRC tube
-void drawPRCtube(picture *f, path3 center, path3 g, penarray *p, real opacity,
-                 real shininess)
+// Tube primitive
+void drawTube(picture *f, triplearray *g, real width, penarray *p,
+              real opacity, real shininess, real metallic, real fresnel0,
+              triple min, triple max, bool core=false)
 {
-  f->append(new drawTube(center,g,*p,opacity,shininess));
+  f->append(new drawTube(*g,width,*p,opacity,shininess,metallic,fresnel0,
+                         min,max,core));
 }
 

 // Draw pixel
@@ -687,11 +695,11 @@
 void draw(picture *f, triplearray *v, Intarray2 *vi,
           triplearray *n, Intarray2 *ni,
           penarray *p, real opacity, real shininess, 
-          real metallic, real fresnel0, real PRCshininess, 
+          real metallic, real fresnel0,
           penarray *c=emptyarray, Intarray2 *ci=emptyarray)
 {
-  f->append(new drawTriangles(*v,*vi,*n,*ni,*p,opacity,shininess,metallic,fresnel0,PRCshininess,
-                              *c,*ci));
+  f->append(new drawTriangles(*v,*vi,*n,*ni,*p,opacity,shininess,metallic,
+                              fresnel0,*c,*ci));
 }
 

 triple min3(picture *f)

Modified: trunk/Build/source/utils/asymptote/runtime.cc
===================================================================
--- trunk/Build/source/utils/asymptote/runtime.cc	2020-03-03 22:33:26 UTC (rev 54033)
+++ trunk/Build/source/utils/asymptote/runtime.cc	2020-03-03 22:35:09 UTC (rev 54034)
@@ -73,7 +73,7 @@
 
 #define CURRENTPEN processData().currentpen
 

-#line 55 "runtime.in"
+#line 52 "runtime.in"
 #include <cfloat>
 #include <iostream>
 #include <fstream>
@@ -146,10 +146,6 @@
 typedef array penarray2;
 typedef array stringarray;
 typedef array stringarray2;
-  
-typedef callable callableBp;
-typedef callable callableReal;
-typedef callable callableTransform;
 }
 
 using vm::array;
@@ -255,54 +251,54 @@
 namespace run {
 
 // Initializers
-#line 230 "runtime.in"
+#line 223 "runtime.in"
 void IntZero(stack *Stack)
 {
-#line 231 "runtime.in"
+#line 224 "runtime.in"
   {Stack->push<Int>(0); return;}
 }
 
-#line 236 "runtime.in"
+#line 229 "runtime.in"
 void realZero(stack *Stack)
 {
-#line 237 "runtime.in"
+#line 230 "runtime.in"
   {Stack->push<real>(0.0); return;}
 }
 
-#line 241 "runtime.in"
+#line 234 "runtime.in"
 void boolFalse(stack *Stack)
 {
-#line 242 "runtime.in"
+#line 235 "runtime.in"
   {Stack->push<bool>(false); return;}
 }
 
-#line 246 "runtime.in"
+#line 239 "runtime.in"
 // bool isnan(real x);
 void gen_runtime3(stack *Stack)
 {
   real x=vm::pop<real>(Stack);
-#line 247 "runtime.in"
+#line 240 "runtime.in"
   {Stack->push<bool>(std::isnan(x)); return;}
 }
 
-#line 251 "runtime.in"
+#line 244 "runtime.in"
 void pushNullArray(stack *Stack)
 {
-#line 252 "runtime.in"
+#line 245 "runtime.in"
   {Stack->push<array*>(0); return;}
 }
 
-#line 256 "runtime.in"
+#line 249 "runtime.in"
 void pushNullRecord(stack *Stack)
 {
-#line 257 "runtime.in"
+#line 250 "runtime.in"
   {Stack->push<frame*>(0); return;}
 }
 
-#line 261 "runtime.in"
+#line 254 "runtime.in"
 void pushNullFunction(stack *Stack)
 {
-#line 262 "runtime.in"
+#line 255 "runtime.in"
   {Stack->push(nullfunc::instance()); return;}
 }
 
@@ -311,200 +307,200 @@
 
 // Put the default value token on the stack (in place of an argument when
 // making a function call).
-#line 271 "runtime.in"
+#line 264 "runtime.in"
 void pushDefault(stack *Stack)
 {
-#line 272 "runtime.in"
+#line 265 "runtime.in"
   {Stack->push(Default); return;}
 }
 
 
 // Test if the value on the stack is the default value token.
-#line 278 "runtime.in"
+#line 271 "runtime.in"
 void isDefault(stack *Stack)
 {
   item i=vm::pop(Stack);
-#line 279 "runtime.in"
+#line 272 "runtime.in"
   {Stack->push<bool>(isdefault(i)); return;}
 }
 
 
 // Casts
-#line 285 "runtime.in"
+#line 278 "runtime.in"
 void pairToGuide(stack *Stack)
 {
   pair z=vm::pop<pair>(Stack);
-#line 286 "runtime.in"
+#line 279 "runtime.in"
   {Stack->push<guide*>(new pairguide(z)); return;}
 }
 
-#line 291 "runtime.in"
+#line 284 "runtime.in"
 void pathToGuide(stack *Stack)
 {
   path p=vm::pop<path>(Stack);
-#line 292 "runtime.in"
+#line 285 "runtime.in"
   {Stack->push<guide*>(new pathguide(p)); return;}
 }
 
-#line 296 "runtime.in"
+#line 289 "runtime.in"
 void guideToPath(stack *Stack)
 {
   guide * g=vm::pop<guide *>(Stack);
-#line 297 "runtime.in"
+#line 290 "runtime.in"
   {Stack->push<path>(g->solve()); return;}
 }
 
 
 // Pen operations
-#line 303 "runtime.in"
+#line 296 "runtime.in"
 void newPen(stack *Stack)
 {
-#line 304 "runtime.in"
+#line 297 "runtime.in"
   {Stack->push<pen>(pen()); return;}
 }
 
-#line 309 "runtime.in"
+#line 302 "runtime.in"
 // bool ==(pen a, pen b);
 void gen_runtime13(stack *Stack)
 {
   pen b=vm::pop<pen>(Stack);
   pen a=vm::pop<pen>(Stack);
-#line 310 "runtime.in"
+#line 303 "runtime.in"
   {Stack->push<bool>(a == b); return;}
 }
 
-#line 314 "runtime.in"
+#line 307 "runtime.in"
 // bool !=(pen a, pen b);
 void gen_runtime14(stack *Stack)
 {
   pen b=vm::pop<pen>(Stack);
   pen a=vm::pop<pen>(Stack);
-#line 315 "runtime.in"
+#line 308 "runtime.in"
   {Stack->push<bool>(a != b); return;}
 }
 
-#line 319 "runtime.in"
+#line 312 "runtime.in"
 // pen +(pen a, pen b);
 void gen_runtime15(stack *Stack)
 {
   pen b=vm::pop<pen>(Stack);
   pen a=vm::pop<pen>(Stack);
-#line 320 "runtime.in"
+#line 313 "runtime.in"
   {Stack->push<pen>(a+b); return;}
 }
 
-#line 324 "runtime.in"
+#line 317 "runtime.in"
 // pen *(real a, pen b);
 void gen_runtime16(stack *Stack)
 {
   pen b=vm::pop<pen>(Stack);
   real a=vm::pop<real>(Stack);
-#line 325 "runtime.in"
+#line 318 "runtime.in"
   {Stack->push<pen>(a*b); return;}
 }
 
-#line 329 "runtime.in"
+#line 322 "runtime.in"
 // pen *(pen a, real b);
 void gen_runtime17(stack *Stack)
 {
   real b=vm::pop<real>(Stack);
   pen a=vm::pop<pen>(Stack);
-#line 330 "runtime.in"
+#line 323 "runtime.in"
   {Stack->push<pen>(b*a); return;}
 }
 
-#line 334 "runtime.in"
+#line 327 "runtime.in"
 // pair max(pen p);
 void gen_runtime18(stack *Stack)
 {
   pen p=vm::pop<pen>(Stack);
-#line 335 "runtime.in"
+#line 328 "runtime.in"
   {Stack->push<pair>(p.bounds().Max()); return;}
 }
 
-#line 339 "runtime.in"
+#line 332 "runtime.in"
 // pair min(pen p);
 void gen_runtime19(stack *Stack)
 {
   pen p=vm::pop<pen>(Stack);
-#line 340 "runtime.in"
+#line 333 "runtime.in"
   {Stack->push<pair>(p.bounds().Min()); return;}
 }
 
 // Reset the meaning of pen default attributes.
-#line 345 "runtime.in"
+#line 338 "runtime.in"
 // void resetdefaultpen();
 void gen_runtime20(stack *)
 {
-#line 346 "runtime.in"
+#line 339 "runtime.in"
   processData().defaultpen=camp::pen::initialpen();
 }
 
-#line 350 "runtime.in"
+#line 343 "runtime.in"
 // void defaultpen(pen p);
 void gen_runtime21(stack *Stack)
 {
   pen p=vm::pop<pen>(Stack);
-#line 351 "runtime.in"
+#line 344 "runtime.in"
   processData().defaultpen=pen(resolvepen,p);
 }
 
-#line 355 "runtime.in"
+#line 348 "runtime.in"
 // pen defaultpen();
 void gen_runtime22(stack *Stack)
 {
-#line 356 "runtime.in"
+#line 349 "runtime.in"
   {Stack->push<pen>(processData().defaultpen); return;}
 }
 
-#line 360 "runtime.in"
+#line 353 "runtime.in"
 // bool invisible(pen p);
 void gen_runtime23(stack *Stack)
 {
   pen p=vm::pop<pen>(Stack);
-#line 361 "runtime.in"
+#line 354 "runtime.in"
   {Stack->push<bool>(p.invisible()); return;}
 }
 
-#line 365 "runtime.in"
+#line 358 "runtime.in"
 // pen invisible();
 void gen_runtime24(stack *Stack)
 {
-#line 366 "runtime.in"
+#line 359 "runtime.in"
   {Stack->push<pen>(pen(invisiblepen)); return;}
 }
 
-#line 370 "runtime.in"
+#line 363 "runtime.in"
 // pen gray(pen p);
 void gen_runtime25(stack *Stack)
 {
   pen p=vm::pop<pen>(Stack);
-#line 371 "runtime.in"
+#line 364 "runtime.in"
   p.togrey();
   {Stack->push<pen>(p); return;}
 }
 
-#line 376 "runtime.in"
+#line 369 "runtime.in"
 // pen rgb(pen p);
 void gen_runtime26(stack *Stack)
 {
   pen p=vm::pop<pen>(Stack);
-#line 377 "runtime.in"
+#line 370 "runtime.in"
   p.torgb();
   {Stack->push<pen>(p); return;}
 }
 
-#line 382 "runtime.in"
+#line 375 "runtime.in"
 // pen cmyk(pen p);
 void gen_runtime27(stack *Stack)
 {
   pen p=vm::pop<pen>(Stack);
-#line 383 "runtime.in"
+#line 376 "runtime.in"
   p.tocmyk();
   {Stack->push<pen>(p); return;}
 }
 
-#line 388 "runtime.in"
+#line 381 "runtime.in"
 // pen interp(pen a, pen b, real t);
 void gen_runtime28(stack *Stack)
 {
@@ -511,11 +507,11 @@
   real t=vm::pop<real>(Stack);
   pen b=vm::pop<pen>(Stack);
   pen a=vm::pop<pen>(Stack);
-#line 389 "runtime.in"
+#line 382 "runtime.in"
   {Stack->push<pen>(interpolate(a,b,t)); return;}
 }
 
-#line 393 "runtime.in"
+#line 386 "runtime.in"
 // pen rgb(real r, real g, real b);
 void gen_runtime29(stack *Stack)
 {
@@ -522,11 +518,11 @@
   real b=vm::pop<real>(Stack);
   real g=vm::pop<real>(Stack);
   real r=vm::pop<real>(Stack);
-#line 394 "runtime.in"
+#line 387 "runtime.in"
   {Stack->push<pen>(pen(r,g,b)); return;}
 }
 
-#line 398 "runtime.in"
+#line 391 "runtime.in"
 // pen cmyk(real c, real m, real y, real k);
 void gen_runtime30(stack *Stack)
 {
@@ -534,25 +530,25 @@
   real y=vm::pop<real>(Stack);
   real m=vm::pop<real>(Stack);
   real c=vm::pop<real>(Stack);
-#line 399 "runtime.in"
+#line 392 "runtime.in"
   {Stack->push<pen>(pen(c,m,y,k)); return;}  
 }
 
-#line 403 "runtime.in"
+#line 396 "runtime.in"
 // pen gray(real gray);
 void gen_runtime31(stack *Stack)
 {
   real gray=vm::pop<real>(Stack);
-#line 404 "runtime.in"
+#line 397 "runtime.in"
   {Stack->push<pen>(pen(gray)); return;}
 }
 
-#line 408 "runtime.in"
+#line 401 "runtime.in"
 // realarray* colors(pen p);
 void gen_runtime32(stack *Stack)
 {
   pen p=vm::pop<pen>(Stack);
-#line 409 "runtime.in"  
+#line 402 "runtime.in"  
   size_t n=ColorComponents[p.colorspace()];
   array *a=new array(n);
   
@@ -579,78 +575,78 @@
   {Stack->push<realarray*>(a); return;}
 }
 
-#line 436 "runtime.in"
+#line 429 "runtime.in"
 // string hex(pen p);
 void gen_runtime33(stack *Stack)
 {
   pen p=vm::pop<pen>(Stack);
-#line 437 "runtime.in"  
+#line 430 "runtime.in"  
   {Stack->push<string>(p.hex()); return;}
 }
 
-#line 441 "runtime.in"
+#line 434 "runtime.in"
 // Int byte(real x);
 void gen_runtime34(stack *Stack)
 {
   real x=vm::pop<real>(Stack);
-#line 442 "runtime.in"
+#line 435 "runtime.in"
   {Stack->push<Int>(camp::byte(x)); return;}
 }
 
-#line 446 "runtime.in"
+#line 439 "runtime.in"
 // string colorspace(pen p);
 void gen_runtime35(stack *Stack)
 {
   pen p=vm::pop<pen>(Stack);
-#line 447 "runtime.in"
+#line 440 "runtime.in"
   string s=ColorDeviceSuffix[p.colorspace()];
   std::transform(s.begin(),s.end(),s.begin(),tolower);
   {Stack->push<string>(s); return;}
 }
 
-#line 453 "runtime.in"
+#line 446 "runtime.in"
 // pen pattern(string *s);
 void gen_runtime36(stack *Stack)
 {
   string * s=vm::pop<string *>(Stack);
-#line 454 "runtime.in"
+#line 447 "runtime.in"
   {Stack->push<pen>(pen(setpattern,*s)); return;}
 }
 
-#line 458 "runtime.in"
+#line 451 "runtime.in"
 // string pattern(pen p);
 void gen_runtime37(stack *Stack)
 {
   pen p=vm::pop<pen>(Stack);
-#line 459 "runtime.in"
+#line 452 "runtime.in"
   {Stack->push<string>(p.fillpattern()); return;}  
 }
 
-#line 463 "runtime.in"
+#line 456 "runtime.in"
 // pen fillrule(Int n);
 void gen_runtime38(stack *Stack)
 {
   Int n=vm::pop<Int>(Stack);
-#line 464 "runtime.in"
+#line 457 "runtime.in"
   {Stack->push<pen>(pen(n >= 0 && n < nFill ? (FillRule) n : DEFFILL)); return;}
 }
 
-#line 468 "runtime.in"
+#line 461 "runtime.in"
 // Int fillrule(pen p);
 void gen_runtime39(stack *Stack)
 {
   pen p=vm::pop<pen>(Stack);
-#line 469 "runtime.in"
+#line 462 "runtime.in"
   {Stack->push<Int>(p.Fillrule()); return;}  
 }
 
-#line 473 "runtime.in"
+#line 466 "runtime.in"
 // pen opacity(real opacity=1.0, string blend=defaulttransparency);
 void gen_runtime40(stack *Stack)
 {
   string blend=vm::pop<string>(Stack,defaulttransparency);
   real opacity=vm::pop<real>(Stack,1.0);
-#line 474 "runtime.in"
+#line 467 "runtime.in"
   for(Int i=0; i < nBlendMode; ++i)
     if(blend == BlendMode[i]) {Stack->push<pen>(pen(Transparency(blend,opacity))); return;}
 
@@ -659,25 +655,25 @@
   error(buf);
 }
 
-#line 483 "runtime.in"
+#line 476 "runtime.in"
 // real opacity(pen p);
 void gen_runtime41(stack *Stack)
 {
   pen p=vm::pop<pen>(Stack);
-#line 484 "runtime.in"
+#line 477 "runtime.in"
   {Stack->push<real>(p.opacity()); return;}
 }
 
-#line 488 "runtime.in"
+#line 481 "runtime.in"
 // string blend(pen p);
 void gen_runtime42(stack *Stack)
 {
   pen p=vm::pop<pen>(Stack);
-#line 489 "runtime.in"
+#line 482 "runtime.in"
   {Stack->push<string>(p.blend()); return;}
 }
 
-#line 493 "runtime.in"
+#line 486 "runtime.in"
 // pen linetype(realarray *pattern, real offset=0, bool scale=true,             bool adjust=true);
 void gen_runtime43(stack *Stack)
 {
@@ -685,7 +681,7 @@
   bool scale=vm::pop<bool>(Stack,true);
   real offset=vm::pop<real>(Stack,0);
   realarray * pattern=vm::pop<realarray *>(Stack);
-#line 495 "runtime.in"
+#line 488 "runtime.in"
   size_t size=checkArray(pattern);
   array *a=new array(size);
   for(size_t i=0; i < size; ++i) 
@@ -694,44 +690,44 @@
   {Stack->push<pen>(pen(LineType(*a,offset,scale,adjust))); return;} 
 }
 
-#line 504 "runtime.in"
+#line 497 "runtime.in"
 // realarray* linetype(pen p=CURRENTPEN);
 void gen_runtime44(stack *Stack)
 {
   pen p=vm::pop<pen>(Stack,CURRENTPEN);
-#line 505 "runtime.in"
+#line 498 "runtime.in"
   array a=p.linetype()->pattern;
   {Stack->push<realarray*>(copyArray(&a)); return;}
 }
 
-#line 510 "runtime.in"
+#line 503 "runtime.in"
 // real offset(pen p);
 void gen_runtime45(stack *Stack)
 {
   pen p=vm::pop<pen>(Stack);
-#line 511 "runtime.in"
+#line 504 "runtime.in"
   {Stack->push<real>(p.linetype()->offset); return;}
 }
 
-#line 515 "runtime.in"
+#line 508 "runtime.in"
 // bool scale(pen p);
 void gen_runtime46(stack *Stack)
 {
   pen p=vm::pop<pen>(Stack);
-#line 516 "runtime.in"
+#line 509 "runtime.in"
   {Stack->push<bool>(p.linetype()->scale); return;}
 }
 
-#line 520 "runtime.in"
+#line 513 "runtime.in"
 // bool adjust(pen p);
 void gen_runtime47(stack *Stack)
 {
   pen p=vm::pop<pen>(Stack);
-#line 521 "runtime.in"
+#line 514 "runtime.in"
   {Stack->push<bool>(p.linetype()->adjust); return;}
 }
 
-#line 525 "runtime.in"
+#line 518 "runtime.in"
 // pen adjust(pen p, real arclength, bool cyclic);
 void gen_runtime48(stack *Stack)
 {
@@ -738,228 +734,228 @@
   bool cyclic=vm::pop<bool>(Stack);
   real arclength=vm::pop<real>(Stack);
   pen p=vm::pop<pen>(Stack);
-#line 526 "runtime.in"
+#line 519 "runtime.in"
   {Stack->push<pen>(adjustdash(p,arclength,cyclic)); return;}
 }
 
-#line 530 "runtime.in"
+#line 523 "runtime.in"
 // pen linecap(Int n);
 void gen_runtime49(stack *Stack)
 {
   Int n=vm::pop<Int>(Stack);
-#line 531 "runtime.in"
+#line 524 "runtime.in"
   {Stack->push<pen>(pen(setlinecap,n >= 0 && n < nCap ? n : DEFCAP)); return;}
 }
 
-#line 535 "runtime.in"
+#line 528 "runtime.in"
 // Int linecap(pen p=CURRENTPEN);
 void gen_runtime50(stack *Stack)
 {
   pen p=vm::pop<pen>(Stack,CURRENTPEN);
-#line 536 "runtime.in"
+#line 529 "runtime.in"
   {Stack->push<Int>(p.cap()); return;}  
 }
 
-#line 540 "runtime.in"
+#line 533 "runtime.in"
 // pen linejoin(Int n);
 void gen_runtime51(stack *Stack)
 {
   Int n=vm::pop<Int>(Stack);
-#line 541 "runtime.in"
+#line 534 "runtime.in"
   {Stack->push<pen>(pen(setlinejoin,n >= 0 && n < nJoin ? n : DEFJOIN)); return;}
 }
 
-#line 545 "runtime.in"
+#line 538 "runtime.in"
 // Int linejoin(pen p=CURRENTPEN);
 void gen_runtime52(stack *Stack)
 {
   pen p=vm::pop<pen>(Stack,CURRENTPEN);
-#line 546 "runtime.in"
+#line 539 "runtime.in"
   {Stack->push<Int>(p.join()); return;}  
 }
 
-#line 550 "runtime.in"
+#line 543 "runtime.in"
 // pen miterlimit(real x);
 void gen_runtime53(stack *Stack)
 {
   real x=vm::pop<real>(Stack);
-#line 551 "runtime.in"
+#line 544 "runtime.in"
   {Stack->push<pen>(pen(setmiterlimit,x >= 1.0 ? x : DEFJOIN)); return;}
 }
 
-#line 555 "runtime.in"
+#line 548 "runtime.in"
 // real miterlimit(pen p=CURRENTPEN);
 void gen_runtime54(stack *Stack)
 {
   pen p=vm::pop<pen>(Stack,CURRENTPEN);
-#line 556 "runtime.in"
+#line 549 "runtime.in"
   {Stack->push<real>(p.miter()); return;}  
 }
 
-#line 560 "runtime.in"
+#line 553 "runtime.in"
 // pen linewidth(real x);
 void gen_runtime55(stack *Stack)
 {
   real x=vm::pop<real>(Stack);
-#line 561 "runtime.in"
+#line 554 "runtime.in"
   {Stack->push<pen>(pen(setlinewidth,x >= 0.0 ? x : DEFWIDTH)); return;}
 }
 
-#line 565 "runtime.in"
+#line 558 "runtime.in"
 // real linewidth(pen p=CURRENTPEN);
 void gen_runtime56(stack *Stack)
 {
   pen p=vm::pop<pen>(Stack,CURRENTPEN);
-#line 566 "runtime.in"
+#line 559 "runtime.in"
   {Stack->push<real>(p.width()); return;}  
 }
 
-#line 570 "runtime.in"
+#line 563 "runtime.in"
 // pen fontcommand(string *s);
 void gen_runtime57(stack *Stack)
 {
   string * s=vm::pop<string *>(Stack);
-#line 571 "runtime.in"
+#line 564 "runtime.in"
   {Stack->push<pen>(pen(setfont,*s)); return;}
 }
 
-#line 575 "runtime.in"
+#line 568 "runtime.in"
 // string font(pen p=CURRENTPEN);
 void gen_runtime58(stack *Stack)
 {
   pen p=vm::pop<pen>(Stack,CURRENTPEN);
-#line 576 "runtime.in"
+#line 569 "runtime.in"
   {Stack->push<string>(p.Font()); return;}
 }
 
-#line 580 "runtime.in"
+#line 573 "runtime.in"
 // pen fontsize(real size, real lineskip);
 void gen_runtime59(stack *Stack)
 {
   real lineskip=vm::pop<real>(Stack);
   real size=vm::pop<real>(Stack);
-#line 581 "runtime.in"
+#line 574 "runtime.in"
   {Stack->push<pen>(pen(setfontsize,size > 0.0 ? size : 0.0,
              lineskip > 0.0 ? lineskip : 0.0)); return;}
 }
 
-#line 586 "runtime.in"
+#line 579 "runtime.in"
 // real fontsize(pen p=CURRENTPEN);
 void gen_runtime60(stack *Stack)
 {
   pen p=vm::pop<pen>(Stack,CURRENTPEN);
-#line 587 "runtime.in"
+#line 580 "runtime.in"
   {Stack->push<real>(p.size()); return;}
 }
 
-#line 591 "runtime.in"
+#line 584 "runtime.in"
 // real lineskip(pen p=CURRENTPEN);
 void gen_runtime61(stack *Stack)
 {
   pen p=vm::pop<pen>(Stack,CURRENTPEN);
-#line 592 "runtime.in"
+#line 585 "runtime.in"
   {Stack->push<real>(p.Lineskip()); return;}  
 }
 
-#line 596 "runtime.in"
+#line 589 "runtime.in"
 // pen overwrite(Int n);
 void gen_runtime62(stack *Stack)
 {
   Int n=vm::pop<Int>(Stack);
-#line 597 "runtime.in"
+#line 590 "runtime.in"
   {Stack->push<pen>(pen(setoverwrite,n >= 0 && n < nOverwrite ? (overwrite_t) n :
              DEFWRITE)); return;}
 }
 
-#line 602 "runtime.in"
+#line 595 "runtime.in"
 // Int overwrite(pen p=CURRENTPEN);
 void gen_runtime63(stack *Stack)
 {
   pen p=vm::pop<pen>(Stack,CURRENTPEN);
-#line 603 "runtime.in"
+#line 596 "runtime.in"
   {Stack->push<Int>(p.Overwrite()); return;}  
 }
 
-#line 607 "runtime.in"
+#line 600 "runtime.in"
 // pen basealign(Int n);
 void gen_runtime64(stack *Stack)
 {
   Int n=vm::pop<Int>(Stack);
-#line 608 "runtime.in"
+#line 601 "runtime.in"
   {Stack->push<pen>(pen(n >= 0 && n < nBaseLine ? (BaseLine) n : DEFBASE)); return;}
 }
 
-#line 612 "runtime.in"
+#line 605 "runtime.in"
 // Int basealign(pen p=CURRENTPEN);
 void gen_runtime65(stack *Stack)
 {
   pen p=vm::pop<pen>(Stack,CURRENTPEN);
-#line 613 "runtime.in"
+#line 606 "runtime.in"
   {Stack->push<Int>(p.Baseline()); return;}
 }
 
-#line 617 "runtime.in"
+#line 610 "runtime.in"
 // transform transform(pen p);
 void gen_runtime66(stack *Stack)
 {
   pen p=vm::pop<pen>(Stack);
-#line 618 "runtime.in"
+#line 611 "runtime.in"
   {Stack->push<transform>(p.getTransform()); return;}
 }
 
-#line 622 "runtime.in"
+#line 615 "runtime.in"
 // path nib(pen p);
 void gen_runtime67(stack *Stack)
 {
   pen p=vm::pop<pen>(Stack);
-#line 623 "runtime.in"
+#line 616 "runtime.in"
   {Stack->push<path>(p.Path()); return;}
 }
 
-#line 627 "runtime.in"
+#line 620 "runtime.in"
 // pen makepen(path p);
 void gen_runtime68(stack *Stack)
 {
   path p=vm::pop<path>(Stack);
-#line 628 "runtime.in"
+#line 621 "runtime.in"
   {Stack->push<pen>(pen(p)); return;}
 }
 
-#line 632 "runtime.in"
+#line 625 "runtime.in"
 // pen colorless(pen p);
 void gen_runtime69(stack *Stack)
 {
   pen p=vm::pop<pen>(Stack);
-#line 633 "runtime.in"
+#line 626 "runtime.in"
   p.colorless();
   {Stack->push<pen>(p); return;}
 }
 
 // Interactive mode
-#line 639 "runtime.in"
+#line 632 "runtime.in"
 // bool interactive();
 void gen_runtime70(stack *Stack)
 {
-#line 640 "runtime.in"
+#line 633 "runtime.in"
   {Stack->push<bool>(interact::interactive); return;}
 }
 
-#line 645 "runtime.in"
+#line 638 "runtime.in"
 // bool uptodate();
 void gen_runtime71(stack *Stack)
 {
-#line 646 "runtime.in"
+#line 639 "runtime.in"
   {Stack->push<bool>(interact::uptodate); return;}
 }
 
 
 // System commands
-#line 652 "runtime.in"
+#line 645 "runtime.in"
 // Int system(stringarray *s);
 void gen_runtime72(stack *Stack)
 {
   stringarray * s=vm::pop<stringarray *>(Stack);
-#line 653 "runtime.in"
+#line 646 "runtime.in"
   if(safe) error("system() call disabled; override with option -nosafe");
   size_t size=checkArray(s);
   if(size == 0) {Stack->push<Int>(0); return;}
@@ -969,57 +965,57 @@
   {Stack->push<Int>(System(cmd)); return;}
 }
 
-#line 664 "runtime.in"
+#line 657 "runtime.in"
 // bool view();
 void gen_runtime73(stack *Stack)
 {
-#line 665 "runtime.in"
+#line 658 "runtime.in"
   {Stack->push<bool>(view()); return;}
 }
 
-#line 669 "runtime.in"
+#line 662 "runtime.in"
 // string asydir();
 void gen_runtime74(stack *Stack)
 {
-#line 670 "runtime.in"
+#line 663 "runtime.in"
   {Stack->push<string>(systemDir); return;}
 }
 
-#line 674 "runtime.in"
+#line 667 "runtime.in"
 // string locale(string s=emptystring);
 void gen_runtime75(stack *Stack)
 {
   string s=vm::pop<string>(Stack,emptystring);
-#line 675 "runtime.in"
+#line 668 "runtime.in"
   char *L=setlocale(LC_ALL,s.empty() ? NULL : s.c_str());
   {Stack->push<string>(L != NULL ? string(L) : ""); return;}
 }
 
-#line 680 "runtime.in"
+#line 673 "runtime.in"
 // void abort(string s=emptystring);
 void gen_runtime76(stack *Stack)
 {
   string s=vm::pop<string>(Stack,emptystring);
-#line 681 "runtime.in"
+#line 674 "runtime.in"
   if(s.empty()) throw handled_error();
   error(s.c_str());
 }
 
-#line 686 "runtime.in"
+#line 679 "runtime.in"
 // void exit();
 void gen_runtime77(stack *)
 {
-#line 687 "runtime.in"
+#line 680 "runtime.in"
   throw quit();
 }
 
-#line 691 "runtime.in"
+#line 684 "runtime.in"
 // void assert(bool b, string s=emptystring);
 void gen_runtime78(stack *Stack)
 {
   string s=vm::pop<string>(Stack,emptystring);
   bool b=vm::pop<bool>(Stack);
-#line 692 "runtime.in"
+#line 685 "runtime.in"
   flush(cout);
   if(!b) {
     ostringstream buf;
@@ -1029,27 +1025,27 @@
   }
 }
 
-#line 702 "runtime.in"
+#line 695 "runtime.in"
 // void sleep(Int seconds);
 void gen_runtime79(stack *Stack)
 {
   Int seconds=vm::pop<Int>(Stack);
-#line 703 "runtime.in"
+#line 696 "runtime.in"
   if(seconds <= 0) return;      
   sleep(seconds);
 }
 
-#line 708 "runtime.in"
+#line 701 "runtime.in"
 // void usleep(Int microseconds);
 void gen_runtime80(stack *Stack)
 {
   Int microseconds=vm::pop<Int>(Stack);
-#line 709 "runtime.in"
+#line 702 "runtime.in"
   if(microseconds <= 0) return; 
   usleep((unsigned long) microseconds); 
 }
 
-#line 714 "runtime.in"
+#line 707 "runtime.in"
 // void _eval(string *s, bool embedded, bool interactiveWrite=false);
 void gen_runtime81(stack *Stack)
 {
@@ -1056,7 +1052,7 @@
   bool interactiveWrite=vm::pop<bool>(Stack,false);
   bool embedded=vm::pop<bool>(Stack);
   string * s=vm::pop<string *>(Stack);
-#line 715 "runtime.in"
+#line 708 "runtime.in"
   if(embedded) {
     trans::coenv *e=Stack->getEnvironment();
     vm::interactiveStack *is=dynamic_cast<vm::interactiveStack *>(Stack);
@@ -1068,13 +1064,13 @@
     runString(*s,interactiveWrite);
 }
 
-#line 727 "runtime.in"
+#line 720 "runtime.in"
 // void _eval(runnable *s, bool embedded);
 void gen_runtime82(stack *Stack)
 {
   bool embedded=vm::pop<bool>(Stack);
   runnable * s=vm::pop<runnable *>(Stack);
-#line 728 "runtime.in"
+#line 721 "runtime.in"
   absyntax::block *ast=new absyntax::block(s->getPos(), false);
   ast->add(s);
 
@@ -1089,11 +1085,11 @@
     runCode(ast);
 }
 
-#line 743 "runtime.in"
+#line 736 "runtime.in"
 // string xasyKEY();
 void gen_runtime83(stack *Stack)
 {
-#line 744 "runtime.in"
+#line 737 "runtime.in"
   processDataStruct *P=&processData();
   xkey_t *xkey=&P->xkey;
   xkey_t::iterator p=xkey->find(P->topPos.LineColumn());
@@ -1100,28 +1096,28 @@
   {Stack->push<string>(p != xkey->end() ? p->second+" 1" : toplocation()+" 0"); return;}
 }
 
-#line 750 "runtime.in"
+#line 743 "runtime.in"
 // void xasyKEY(string *s);
 void gen_runtime84(stack *Stack)
 {
   string * s=vm::pop<string *>(Stack);
-#line 751 "runtime.in"
+#line 744 "runtime.in"
   processData().KEY=*s;
 }
 
-#line 754 "runtime.in"
+#line 747 "runtime.in"
 // string toplocation();
 void gen_runtime85(stack *Stack)
 {
-#line 755 "runtime.in"
+#line 748 "runtime.in"
   {Stack->push<string>(toplocation()); return;}
 }
 
-#line 758 "runtime.in"
+#line 751 "runtime.in"
 // string location();
 void gen_runtime86(stack *Stack)
 {
-#line 759 "runtime.in"
+#line 752 "runtime.in"
   ostringstream buf;
   buf << getPos();
   {Stack->push<string>(buf.str()); return;}
@@ -1128,20 +1124,20 @@
 }
 
 // Wrapper for the stack::load() method.
-#line 765 "runtime.in"
+#line 758 "runtime.in"
 void loadModule(stack *Stack)
 {
   string * index=vm::pop<string *>(Stack);
-#line 766 "runtime.in"
+#line 759 "runtime.in"
   Stack->load(*index);
 }
 
-#line 770 "runtime.in"
+#line 763 "runtime.in"
 // string cd(string s=emptystring);
 void gen_runtime88(stack *Stack)
 {
   string s=vm::pop<string>(Stack,emptystring);
-#line 771 "runtime.in"
+#line 764 "runtime.in"
   if(!s.empty() && !globalwrite()) {
     string outname=getSetting<string>("outname");
     string dir=stripDir(outname);
@@ -1150,13 +1146,13 @@
   {Stack->push<string>(setPath(s.c_str())); return;}
 }
 
-#line 780 "runtime.in"
+#line 773 "runtime.in"
 // void list(string *s, bool imports=false);
 void gen_runtime89(stack *Stack)
 {
   bool imports=vm::pop<bool>(Stack,false);
   string * s=vm::pop<string *>(Stack);
-#line 781 "runtime.in"
+#line 774 "runtime.in"
   if(*s == "-") return;
   trans::genv ge;
   symbol name=symbol::trans(*s);
@@ -1166,18 +1162,18 @@
 
 
 // Guide operations
-#line 791 "runtime.in"
+#line 784 "runtime.in"
 void nullGuide(stack *Stack)
 {
-#line 792 "runtime.in"
+#line 785 "runtime.in"
   {Stack->push<guide*>(new pathguide(path())); return;}
 }
 
-#line 797 "runtime.in"
+#line 790 "runtime.in"
 void dotsGuide(stack *Stack)
 {
   guidearray * a=vm::pop<guidearray *>(Stack);
-#line 798 "runtime.in"
+#line 791 "runtime.in"
   guidevector v;
   size_t size=checkArray(a);
   for (size_t i=0; i < size; ++i)
@@ -1186,11 +1182,11 @@
   {Stack->push<guide*>(new multiguide(v)); return;}
 }
 
-#line 807 "runtime.in"
+#line 800 "runtime.in"
 void dashesGuide(stack *Stack)
 {
   guidearray * a=vm::pop<guidearray *>(Stack);
-#line 808 "runtime.in"
+#line 801 "runtime.in"
   static camp::curlSpec curly;
   static camp::specguide curlout(&curly, camp::OUT);
   static camp::specguide curlin(&curly, camp::IN);
@@ -1216,31 +1212,31 @@
   {Stack->push<guide*>(new multiguide(v)); return;}
 }
 
-#line 834 "runtime.in"
+#line 827 "runtime.in"
 void newCycleToken(stack *Stack)
 {
-#line 835 "runtime.in"
+#line 828 "runtime.in"
   {Stack->push<cycleToken>(cycleToken()); return;}
 }
 
-#line 839 "runtime.in"
+#line 832 "runtime.in"
 // guide* operator cast(cycleToken tok);
 void gen_runtime94(stack *Stack)
 {
   cycleToken tok=vm::pop<cycleToken>(Stack);
-#line 840 "runtime.in"
+#line 833 "runtime.in"
 // Avoid unused variable warning messages.
   unused(&tok);
   {Stack->push<guide*>(new cycletokguide()); return;}
 }
 
-#line 846 "runtime.in"
+#line 839 "runtime.in"
 // guide* operator spec(pair z, Int p);
 void gen_runtime95(stack *Stack)
 {
   Int p=vm::pop<Int>(Stack);
   pair z=vm::pop<pair>(Stack);
-#line 847 "runtime.in"
+#line 840 "runtime.in"
   camp::side d=(camp::side) p;
   camp::dirSpec *sp=new camp::dirSpec(z);
 
@@ -1247,43 +1243,43 @@
   {Stack->push<guide*>(new specguide(sp,d)); return;}
 }
 
-#line 854 "runtime.in"
+#line 847 "runtime.in"
 // curlSpecifier operator curl(real gamma, Int p);
 void gen_runtime96(stack *Stack)
 {
   Int p=vm::pop<Int>(Stack);
   real gamma=vm::pop<real>(Stack);
-#line 855 "runtime.in"
+#line 848 "runtime.in"
   camp::side s=(camp::side) p;
   {Stack->push<curlSpecifier>(curlSpecifier(gamma,s)); return;}
 }
 
-#line 860 "runtime.in"
+#line 853 "runtime.in"
 void curlSpecifierValuePart(stack *Stack)
 {
   curlSpecifier spec=vm::pop<curlSpecifier>(Stack);
-#line 861 "runtime.in"
+#line 854 "runtime.in"
   {Stack->push<real>(spec.getValue()); return;}
 }
 
-#line 865 "runtime.in"
+#line 858 "runtime.in"
 void curlSpecifierSidePart(stack *Stack)
 {
   curlSpecifier spec=vm::pop<curlSpecifier>(Stack);
-#line 866 "runtime.in"
+#line 859 "runtime.in"
   {Stack->push<Int>(spec.getSide()); return;}
 }
 
-#line 870 "runtime.in"
+#line 863 "runtime.in"
 // guide* operator cast(curlSpecifier spec);
 void gen_runtime99(stack *Stack)
 {
   curlSpecifier spec=vm::pop<curlSpecifier>(Stack);
-#line 871 "runtime.in"
+#line 864 "runtime.in"
   {Stack->push<guide*>(new specguide(spec)); return;}
 }
 
-#line 875 "runtime.in"
+#line 868 "runtime.in"
 // tensionSpecifier operator tension(real tout, real tin, bool atleast);
 void gen_runtime100(stack *Stack)
 {
@@ -1290,105 +1286,105 @@
   bool atleast=vm::pop<bool>(Stack);
   real tin=vm::pop<real>(Stack);
   real tout=vm::pop<real>(Stack);
-#line 876 "runtime.in"
+#line 869 "runtime.in"
   {Stack->push<tensionSpecifier>(tensionSpecifier(tout, tin, atleast)); return;}
 }
 
-#line 880 "runtime.in"
+#line 873 "runtime.in"
 void tensionSpecifierOutPart(stack *Stack)
 {
   tensionSpecifier t=vm::pop<tensionSpecifier>(Stack);
-#line 881 "runtime.in"
+#line 874 "runtime.in"
   {Stack->push<real>(t.getOut()); return;}
 }
 
-#line 885 "runtime.in"
+#line 878 "runtime.in"
 void tensionSpecifierInPart(stack *Stack)
 {
   tensionSpecifier t=vm::pop<tensionSpecifier>(Stack);
-#line 886 "runtime.in"
+#line 879 "runtime.in"
   {Stack->push<real>(t.getIn()); return;}
 }
 
-#line 890 "runtime.in"
+#line 883 "runtime.in"
 void tensionSpecifierAtleastPart(stack *Stack)
 {
   tensionSpecifier t=vm::pop<tensionSpecifier>(Stack);
-#line 891 "runtime.in"
+#line 884 "runtime.in"
   {Stack->push<bool>(t.getAtleast()); return;}
 }
 
-#line 895 "runtime.in"
+#line 888 "runtime.in"
 // guide* operator cast(tensionSpecifier t);
 void gen_runtime104(stack *Stack)
 {
   tensionSpecifier t=vm::pop<tensionSpecifier>(Stack);
-#line 896 "runtime.in"
+#line 889 "runtime.in"
   {Stack->push<guide*>(new tensionguide(t)); return;}
 }
 
-#line 900 "runtime.in"
+#line 893 "runtime.in"
 // guide* operator controls(pair zout, pair zin);
 void gen_runtime105(stack *Stack)
 {
   pair zin=vm::pop<pair>(Stack);
   pair zout=vm::pop<pair>(Stack);
-#line 901 "runtime.in"
+#line 894 "runtime.in"
   {Stack->push<guide*>(new controlguide(zout, zin)); return;}
 }
 
-#line 905 "runtime.in"
+#line 898 "runtime.in"
 // Int size(guide *g);
 void gen_runtime106(stack *Stack)
 {
   guide * g=vm::pop<guide *>(Stack);
-#line 906 "runtime.in"
+#line 899 "runtime.in"
   flatguide f;
   g->flatten(f,false);
   {Stack->push<Int>(f.size()); return;}
 }
 
-#line 912 "runtime.in"
+#line 905 "runtime.in"
 // Int length(guide *g);
 void gen_runtime107(stack *Stack)
 {
   guide * g=vm::pop<guide *>(Stack);
-#line 913 "runtime.in"
+#line 906 "runtime.in"
   flatguide f;
   g->flatten(f,false);
   {Stack->push<Int>(g->cyclic() ? f.size() : f.size()-1); return;}
 }
 
-#line 919 "runtime.in"
+#line 912 "runtime.in"
 // bool cyclic(guide *g);
 void gen_runtime108(stack *Stack)
 {
   guide * g=vm::pop<guide *>(Stack);
-#line 920 "runtime.in"
+#line 913 "runtime.in"
   flatguide f;
   g->flatten(f,false);
   {Stack->push<bool>(g->cyclic()); return;}
 }
 
-#line 926 "runtime.in"
+#line 919 "runtime.in"
 // pair point(guide *g, Int t);
 void gen_runtime109(stack *Stack)
 {
   Int t=vm::pop<Int>(Stack);
   guide * g=vm::pop<guide *>(Stack);
-#line 927 "runtime.in"
+#line 920 "runtime.in"
   flatguide f;
   g->flatten(f,false);
   {Stack->push<pair>(f.Nodes(adjustedIndex(t,f.size(),g->cyclic())).z); return;}
 }
 
-#line 933 "runtime.in"
+#line 926 "runtime.in"
 // pairarray* dirSpecifier(guide *g, Int t);
 void gen_runtime110(stack *Stack)
 {
   Int t=vm::pop<Int>(Stack);
   guide * g=vm::pop<guide *>(Stack);
-#line 934 "runtime.in"
+#line 927 "runtime.in"
   flatguide f;
   g->flatten(f,false);
   Int n=f.size();
@@ -1399,13 +1395,13 @@
   {Stack->push<pairarray*>(c); return;}
 }
 
-#line 945 "runtime.in"
+#line 938 "runtime.in"
 // pairarray* controlSpecifier(guide *g, Int t);
 void gen_runtime111(stack *Stack)
 {
   Int t=vm::pop<Int>(Stack);
   guide * g=vm::pop<guide *>(Stack);
-#line 946 "runtime.in"
+#line 939 "runtime.in"
   flatguide f;
   g->flatten(f,false);
   Int n=f.size();
@@ -1421,13 +1417,13 @@
   } else {Stack->push<pairarray*>(new array(0)); return;}
 }
 
-#line 962 "runtime.in"
+#line 955 "runtime.in"
 // tensionSpecifier tensionSpecifier(guide *g, Int t);
 void gen_runtime112(stack *Stack)
 {
   Int t=vm::pop<Int>(Stack);
   guide * g=vm::pop<guide *>(Stack);
-#line 963 "runtime.in"
+#line 956 "runtime.in"
   flatguide f;
   g->flatten(f,false);
   Int n=f.size();
@@ -1436,13 +1432,13 @@
   {Stack->push<tensionSpecifier>(tensionSpecifier(curr.tout.val,f.Nodes(t+1).tin.val,curr.tout.atleast)); return;}
 }
 
-#line 972 "runtime.in"
+#line 965 "runtime.in"
 // realarray* curlSpecifier(guide *g, Int t);
 void gen_runtime113(stack *Stack)
 {
   Int t=vm::pop<Int>(Stack);
   guide * g=vm::pop<guide *>(Stack);
-#line 973 "runtime.in"
+#line 966 "runtime.in"
   flatguide f;
   g->flatten(f,false);
   Int n=f.size();
@@ -1455,12 +1451,12 @@
   {Stack->push<realarray*>(c); return;}
 }
 
-#line 986 "runtime.in"
+#line 979 "runtime.in"
 // guide* reverse(guide *g);
 void gen_runtime114(stack *Stack)
 {
   guide * g=vm::pop<guide *>(Stack);
-#line 987 "runtime.in"
+#line 980 "runtime.in"
   flatguide f;
   g->flatten(f,false);
   if(f.precyclic())
@@ -1511,11 +1507,11 @@
   {Stack->push<guide*>(new multiguide(v)); return;}
 }
 
-#line 1039 "runtime.in"
+#line 1032 "runtime.in"
 // realarray* _cputime();
 void gen_runtime115(stack *Stack)
 {
-#line 1040 "runtime.in"
+#line 1033 "runtime.in"
   static const real ticktime=1.0/sysconf(_SC_CLK_TCK);
   struct tms buf;
 
@@ -1530,103 +1526,103 @@
 
 
 // Transforms
-#line 1055 "runtime.in"
+#line 1048 "runtime.in"
 // bool ==(transform a, transform b);
 void gen_runtime116(stack *Stack)
 {
   transform b=vm::pop<transform>(Stack);
   transform a=vm::pop<transform>(Stack);
-#line 1056 "runtime.in"
+#line 1049 "runtime.in"
   {Stack->push<bool>(a == b); return;}
 }
 
-#line 1061 "runtime.in"
+#line 1054 "runtime.in"
 // bool !=(transform a, transform b);
 void gen_runtime117(stack *Stack)
 {
   transform b=vm::pop<transform>(Stack);
   transform a=vm::pop<transform>(Stack);
-#line 1062 "runtime.in"
+#line 1055 "runtime.in"
   {Stack->push<bool>(a != b); return;}
 }
 
-#line 1066 "runtime.in"
+#line 1059 "runtime.in"
 // transform +(transform a, transform b);
 void gen_runtime118(stack *Stack)
 {
   transform b=vm::pop<transform>(Stack);
   transform a=vm::pop<transform>(Stack);
-#line 1067 "runtime.in"
+#line 1060 "runtime.in"
   {Stack->push<transform>(a+b); return;}
 }
 
-#line 1071 "runtime.in"
+#line 1064 "runtime.in"
 // transform *(transform a, transform b);
 void gen_runtime119(stack *Stack)
 {
   transform b=vm::pop<transform>(Stack);
   transform a=vm::pop<transform>(Stack);
-#line 1072 "runtime.in"
+#line 1065 "runtime.in"
   {Stack->push<transform>(a*b); return;}
 }
 
-#line 1076 "runtime.in"
+#line 1069 "runtime.in"
 // pair *(transform t, pair z);
 void gen_runtime120(stack *Stack)
 {
   pair z=vm::pop<pair>(Stack);
   transform t=vm::pop<transform>(Stack);
-#line 1077 "runtime.in"
+#line 1070 "runtime.in"
   {Stack->push<pair>(t*z); return;}
 }
 
-#line 1081 "runtime.in"
+#line 1074 "runtime.in"
 // path *(transform t, path g);
 void gen_runtime121(stack *Stack)
 {
   path g=vm::pop<path>(Stack);
   transform t=vm::pop<transform>(Stack);
-#line 1082 "runtime.in"
+#line 1075 "runtime.in"
   {Stack->push<path>(transformed(t,g)); return;}
 }
 
-#line 1086 "runtime.in"
+#line 1079 "runtime.in"
 // pen *(transform t, pen p);
 void gen_runtime122(stack *Stack)
 {
   pen p=vm::pop<pen>(Stack);
   transform t=vm::pop<transform>(Stack);
-#line 1087 "runtime.in"
+#line 1080 "runtime.in"
   {Stack->push<pen>(transformed(t,p)); return;}
 }
 
-#line 1091 "runtime.in"
+#line 1084 "runtime.in"
 // picture* *(transform t, picture *f);
 void gen_runtime123(stack *Stack)
 {
   picture * f=vm::pop<picture *>(Stack);
   transform t=vm::pop<transform>(Stack);
-#line 1092 "runtime.in"
+#line 1085 "runtime.in"
   {Stack->push<picture*>(transformed(t,f)); return;}
 }
 
-#line 1096 "runtime.in"
+#line 1089 "runtime.in"
 // picture* *(realarray2 *t, picture *f);
 void gen_runtime124(stack *Stack)
 {
   picture * f=vm::pop<picture *>(Stack);
   realarray2 * t=vm::pop<realarray2 *>(Stack);
-#line 1097 "runtime.in"
+#line 1090 "runtime.in"
   {Stack->push<picture*>(transformed(*t,f)); return;}
 }
 
-#line 1101 "runtime.in"
+#line 1094 "runtime.in"
 // transform ^(transform t, Int n);
 void gen_runtime125(stack *Stack)
 {
   Int n=vm::pop<Int>(Stack);
   transform t=vm::pop<transform>(Stack);
-#line 1102 "runtime.in"
+#line 1095 "runtime.in"
   transform T;
   if(n < 0) {
     n=-n;
@@ -1636,55 +1632,55 @@
   {Stack->push<transform>(T); return;}
 }
 
-#line 1112 "runtime.in"
+#line 1105 "runtime.in"
 void transformXPart(stack *Stack)
 {
   transform t=vm::pop<transform>(Stack);
-#line 1113 "runtime.in"
+#line 1106 "runtime.in"
   {Stack->push<real>(t.getx()); return;}
 }
 
-#line 1117 "runtime.in"
+#line 1110 "runtime.in"
 void transformYPart(stack *Stack)
 {
   transform t=vm::pop<transform>(Stack);
-#line 1118 "runtime.in"
+#line 1111 "runtime.in"
   {Stack->push<real>(t.gety()); return;}
 }
 
-#line 1122 "runtime.in"
+#line 1115 "runtime.in"
 void transformXXPart(stack *Stack)
 {
   transform t=vm::pop<transform>(Stack);
-#line 1123 "runtime.in"
+#line 1116 "runtime.in"
   {Stack->push<real>(t.getxx()); return;}
 }
 
-#line 1127 "runtime.in"
+#line 1120 "runtime.in"
 void transformXYPart(stack *Stack)
 {
   transform t=vm::pop<transform>(Stack);
-#line 1128 "runtime.in"
+#line 1121 "runtime.in"
   {Stack->push<real>(t.getxy()); return;}
 }
 
-#line 1132 "runtime.in"
+#line 1125 "runtime.in"
 void transformYXPart(stack *Stack)
 {
   transform t=vm::pop<transform>(Stack);
-#line 1133 "runtime.in"
+#line 1126 "runtime.in"
   {Stack->push<real>(t.getyx()); return;}
 }
 
-#line 1137 "runtime.in"
+#line 1130 "runtime.in"
 void transformYYPart(stack *Stack)
 {
   transform t=vm::pop<transform>(Stack);
-#line 1138 "runtime.in"
+#line 1131 "runtime.in"
   {Stack->push<real>(t.getyy()); return;}
 }
 
-#line 1142 "runtime.in"
+#line 1135 "runtime.in"
 void real6ToTransform(stack *Stack)
 {
   real yy=vm::pop<real>(Stack);
@@ -1693,127 +1689,127 @@
   real xx=vm::pop<real>(Stack);
   real y=vm::pop<real>(Stack);
   real x=vm::pop<real>(Stack);
-#line 1144 "runtime.in"
+#line 1137 "runtime.in"
   {Stack->push<transform>(transform(x,y,xx,xy,yx,yy)); return;}
 }
 
-#line 1148 "runtime.in"
+#line 1141 "runtime.in"
 // transform shift(transform t);
 void gen_runtime133(stack *Stack)
 {
   transform t=vm::pop<transform>(Stack);
-#line 1149 "runtime.in"
+#line 1142 "runtime.in"
   {Stack->push<transform>(transform(t.getx(),t.gety(),0,0,0,0)); return;}
 }
 
-#line 1153 "runtime.in"
+#line 1146 "runtime.in"
 // transform shiftless(transform t);
 void gen_runtime134(stack *Stack)
 {
   transform t=vm::pop<transform>(Stack);
-#line 1154 "runtime.in"
+#line 1147 "runtime.in"
   {Stack->push<transform>(transform(0,0,t.getxx(),t.getxy(),t.getyx(),t.getyy())); return;}
 }
 
-#line 1158 "runtime.in"
+#line 1151 "runtime.in"
 // transform identity();
 void transformIdentity(stack *Stack)
 {
-#line 1159 "runtime.in"
+#line 1152 "runtime.in"
   {Stack->push<transform>(identity); return;}
 }
 
-#line 1163 "runtime.in"
+#line 1156 "runtime.in"
 // transform inverse(transform t);
 void gen_runtime136(stack *Stack)
 {
   transform t=vm::pop<transform>(Stack);
-#line 1164 "runtime.in"
+#line 1157 "runtime.in"
   {Stack->push<transform>(inverse(t)); return;}
 }
 
-#line 1168 "runtime.in"
+#line 1161 "runtime.in"
 // transform shift(pair z);
 void gen_runtime137(stack *Stack)
 {
   pair z=vm::pop<pair>(Stack);
-#line 1169 "runtime.in"
+#line 1162 "runtime.in"
   {Stack->push<transform>(shift(z)); return;}
 }
 
-#line 1173 "runtime.in"
+#line 1166 "runtime.in"
 // transform shift(real x, real y);
 void gen_runtime138(stack *Stack)
 {
   real y=vm::pop<real>(Stack);
   real x=vm::pop<real>(Stack);
-#line 1174 "runtime.in"
+#line 1167 "runtime.in"
   {Stack->push<transform>(shift(pair(x,y))); return;}
 }
 
-#line 1178 "runtime.in"
+#line 1171 "runtime.in"
 // transform xscale(real x);
 void gen_runtime139(stack *Stack)
 {
   real x=vm::pop<real>(Stack);
-#line 1179 "runtime.in"
+#line 1172 "runtime.in"
   {Stack->push<transform>(xscale(x)); return;}
 }
 
-#line 1183 "runtime.in"
+#line 1176 "runtime.in"
 // transform yscale(real y);
 void gen_runtime140(stack *Stack)
 {
   real y=vm::pop<real>(Stack);
-#line 1184 "runtime.in"
+#line 1177 "runtime.in"
   {Stack->push<transform>(yscale(y)); return;}
 }
 
-#line 1188 "runtime.in"
+#line 1181 "runtime.in"
 // transform scale(real x);
 void gen_runtime141(stack *Stack)
 {
   real x=vm::pop<real>(Stack);
-#line 1189 "runtime.in"
+#line 1182 "runtime.in"
   {Stack->push<transform>(scale(x)); return;}
 }
 
-#line 1193 "runtime.in"
+#line 1186 "runtime.in"
 // transform scale(real x, real y);
 void gen_runtime142(stack *Stack)
 {
   real y=vm::pop<real>(Stack);
   real x=vm::pop<real>(Stack);
-#line 1194 "runtime.in"
+#line 1187 "runtime.in"
   {Stack->push<transform>(scale(x,y)); return;}
 }
 
-#line 1198 "runtime.in"
+#line 1191 "runtime.in"
 // transform slant(real s);
 void gen_runtime143(stack *Stack)
 {
   real s=vm::pop<real>(Stack);
-#line 1199 "runtime.in"
+#line 1192 "runtime.in"
   {Stack->push<transform>(slant(s)); return;}
 }
 
-#line 1203 "runtime.in"
+#line 1196 "runtime.in"
 // transform rotate(real angle, pair z=0);
 void gen_runtime144(stack *Stack)
 {
   pair z=vm::pop<pair>(Stack,0);
   real angle=vm::pop<real>(Stack);
-#line 1204 "runtime.in"
+#line 1197 "runtime.in"
   {Stack->push<transform>(rotatearound(z,radians(angle))); return;}
 }
 
-#line 1208 "runtime.in"
+#line 1201 "runtime.in"
 // transform reflect(pair a, pair b);
 void gen_runtime145(stack *Stack)
 {
   pair b=vm::pop<pair>(Stack);
   pair a=vm::pop<pair>(Stack);
-#line 1209 "runtime.in"
+#line 1202 "runtime.in"
   {Stack->push<transform>(reflectabout(a,b)); return;}
 }
 
@@ -1823,297 +1819,297 @@
 
 void gen_runtime_venv(venv &ve)
 {
-#line 228 "runtime.in"
+#line 221 "runtime.in"
   REGISTER_BLTIN(run::IntZero,"IntZero");
-#line 236 "runtime.in"
+#line 229 "runtime.in"
   REGISTER_BLTIN(run::realZero,"realZero");
-#line 241 "runtime.in"
+#line 234 "runtime.in"
   REGISTER_BLTIN(run::boolFalse,"boolFalse");
-#line 246 "runtime.in"
+#line 239 "runtime.in"
   addFunc(ve, run::gen_runtime3, primBoolean(), SYM(isnan), formal(primReal(), SYM(x), false, false));
-#line 251 "runtime.in"
+#line 244 "runtime.in"
   REGISTER_BLTIN(run::pushNullArray,"pushNullArray");
-#line 256 "runtime.in"
+#line 249 "runtime.in"
   REGISTER_BLTIN(run::pushNullRecord,"pushNullRecord");
-#line 261 "runtime.in"
+#line 254 "runtime.in"
   REGISTER_BLTIN(run::pushNullFunction,"pushNullFunction");
-#line 266 "runtime.in"
+#line 259 "runtime.in"
   REGISTER_BLTIN(run::pushDefault,"pushDefault");
+#line 269 "runtime.in"
+  REGISTER_BLTIN(run::isDefault,"isDefault");
 #line 276 "runtime.in"
-  REGISTER_BLTIN(run::isDefault,"isDefault");
-#line 283 "runtime.in"
   REGISTER_BLTIN(run::pairToGuide,"pairToGuide");
-#line 291 "runtime.in"
+#line 284 "runtime.in"
   REGISTER_BLTIN(run::pathToGuide,"pathToGuide");
-#line 296 "runtime.in"
+#line 289 "runtime.in"
   REGISTER_BLTIN(run::guideToPath,"guideToPath");
-#line 301 "runtime.in"
+#line 294 "runtime.in"
   REGISTER_BLTIN(run::newPen,"newPen");
-#line 309 "runtime.in"
+#line 302 "runtime.in"
   addFunc(ve, run::gen_runtime13, primBoolean(), SYM_EQ, formal(primPen(), SYM(a), false, false), formal(primPen(), SYM(b), false, false));
-#line 314 "runtime.in"
+#line 307 "runtime.in"
   addFunc(ve, run::gen_runtime14, primBoolean(), SYM_NEQ, formal(primPen(), SYM(a), false, false), formal(primPen(), SYM(b), false, false));
-#line 319 "runtime.in"
+#line 312 "runtime.in"
   addFunc(ve, run::gen_runtime15, primPen(), SYM_PLUS, formal(primPen(), SYM(a), false, false), formal(primPen(), SYM(b), false, false));
-#line 324 "runtime.in"
+#line 317 "runtime.in"
   addFunc(ve, run::gen_runtime16, primPen(), SYM_TIMES, formal(primReal(), SYM(a), false, false), formal(primPen(), SYM(b), false, false));
-#line 329 "runtime.in"
+#line 322 "runtime.in"
   addFunc(ve, run::gen_runtime17, primPen(), SYM_TIMES, formal(primPen(), SYM(a), false, false), formal(primReal(), SYM(b), false, false));
-#line 334 "runtime.in"
+#line 327 "runtime.in"
   addFunc(ve, run::gen_runtime18, primPair(), SYM(max), formal(primPen(), SYM(p), false, false));
-#line 339 "runtime.in"
+#line 332 "runtime.in"
   addFunc(ve, run::gen_runtime19, primPair(), SYM(min), formal(primPen(), SYM(p), false, false));
-#line 344 "runtime.in"
+#line 337 "runtime.in"
   addFunc(ve, run::gen_runtime20, primVoid(), SYM(resetdefaultpen));
-#line 350 "runtime.in"
+#line 343 "runtime.in"
   addFunc(ve, run::gen_runtime21, primVoid(), SYM(defaultpen), formal(primPen(), SYM(p), false, false));
-#line 355 "runtime.in"
+#line 348 "runtime.in"
   addFunc(ve, run::gen_runtime22, primPen(), SYM(defaultpen));
-#line 360 "runtime.in"
+#line 353 "runtime.in"
   addFunc(ve, run::gen_runtime23, primBoolean(), SYM(invisible), formal(primPen(), SYM(p), false, false));
-#line 365 "runtime.in"
+#line 358 "runtime.in"
   addFunc(ve, run::gen_runtime24, primPen(), SYM(invisible));
-#line 370 "runtime.in"
+#line 363 "runtime.in"
   addFunc(ve, run::gen_runtime25, primPen(), SYM(gray), formal(primPen(), SYM(p), false, false));
-#line 376 "runtime.in"
+#line 369 "runtime.in"
   addFunc(ve, run::gen_runtime26, primPen(), SYM(rgb), formal(primPen(), SYM(p), false, false));
-#line 382 "runtime.in"
+#line 375 "runtime.in"
   addFunc(ve, run::gen_runtime27, primPen(), SYM(cmyk), formal(primPen(), SYM(p), false, false));
-#line 388 "runtime.in"
+#line 381 "runtime.in"
   addFunc(ve, run::gen_runtime28, primPen(), SYM(interp), formal(primPen(), SYM(a), false, false), formal(primPen(), SYM(b), false, false), formal(primReal(), SYM(t), false, false));
-#line 393 "runtime.in"
+#line 386 "runtime.in"
   addFunc(ve, run::gen_runtime29, primPen(), SYM(rgb), formal(primReal(), SYM(r), false, false), formal(primReal(), SYM(g), false, false), formal(primReal(), SYM(b), false, false));
-#line 398 "runtime.in"
+#line 391 "runtime.in"
   addFunc(ve, run::gen_runtime30, primPen(), SYM(cmyk), formal(primReal(), SYM(c), false, false), formal(primReal(), SYM(m), false, false), formal(primReal(), SYM(y), false, false), formal(primReal(), SYM(k), false, false));
-#line 403 "runtime.in"
+#line 396 "runtime.in"
   addFunc(ve, run::gen_runtime31, primPen(), SYM(gray), formal(primReal(), SYM(gray), false, false));
-#line 408 "runtime.in"
+#line 401 "runtime.in"
   addFunc(ve, run::gen_runtime32, realArray(), SYM(colors), formal(primPen(), SYM(p), false, false));
-#line 436 "runtime.in"
+#line 429 "runtime.in"
   addFunc(ve, run::gen_runtime33, primString() , SYM(hex), formal(primPen(), SYM(p), false, false));
-#line 441 "runtime.in"
+#line 434 "runtime.in"
   addFunc(ve, run::gen_runtime34, primInt(), SYM(byte), formal(primReal(), SYM(x), false, false));
+#line 439 "runtime.in"
+  addFunc(ve, run::gen_runtime35, primString() , SYM(colorspace), formal(primPen(), SYM(p), false, false));
 #line 446 "runtime.in"
-  addFunc(ve, run::gen_runtime35, primString() , SYM(colorspace), formal(primPen(), SYM(p), false, false));
-#line 453 "runtime.in"
   addFunc(ve, run::gen_runtime36, primPen(), SYM(pattern), formal(primString(), SYM(s), false, false));
-#line 458 "runtime.in"
+#line 451 "runtime.in"
   addFunc(ve, run::gen_runtime37, primString() , SYM(pattern), formal(primPen(), SYM(p), false, false));
-#line 463 "runtime.in"
+#line 456 "runtime.in"
   addFunc(ve, run::gen_runtime38, primPen(), SYM(fillrule), formal(primInt(), SYM(n), false, false));
-#line 468 "runtime.in"
+#line 461 "runtime.in"
   addFunc(ve, run::gen_runtime39, primInt(), SYM(fillrule), formal(primPen(), SYM(p), false, false));
-#line 473 "runtime.in"
+#line 466 "runtime.in"
   addFunc(ve, run::gen_runtime40, primPen(), SYM(opacity), formal(primReal(), SYM(opacity), true, false), formal(primString() , SYM(blend), true, false));
-#line 483 "runtime.in"
+#line 476 "runtime.in"
   addFunc(ve, run::gen_runtime41, primReal(), SYM(opacity), formal(primPen(), SYM(p), false, false));
-#line 488 "runtime.in"
+#line 481 "runtime.in"
   addFunc(ve, run::gen_runtime42, primString() , SYM(blend), formal(primPen(), SYM(p), false, false));
-#line 493 "runtime.in"
+#line 486 "runtime.in"
   addFunc(ve, run::gen_runtime43, primPen(), SYM(linetype), formal(realArray(), SYM(pattern), false, false), formal(primReal(), SYM(offset), true, false), formal(primBoolean(), SYM(scale), true, false), formal(primBoolean(), SYM(adjust), true, false));
-#line 504 "runtime.in"
+#line 497 "runtime.in"
   addFunc(ve, run::gen_runtime44, realArray(), SYM(linetype), formal(primPen(), SYM(p), true, false));
-#line 510 "runtime.in"
+#line 503 "runtime.in"
   addFunc(ve, run::gen_runtime45, primReal(), SYM(offset), formal(primPen(), SYM(p), false, false));
-#line 515 "runtime.in"
+#line 508 "runtime.in"
   addFunc(ve, run::gen_runtime46, primBoolean(), SYM(scale), formal(primPen(), SYM(p), false, false));
-#line 520 "runtime.in"
+#line 513 "runtime.in"
   addFunc(ve, run::gen_runtime47, primBoolean(), SYM(adjust), formal(primPen(), SYM(p), false, false));
-#line 525 "runtime.in"
+#line 518 "runtime.in"
   addFunc(ve, run::gen_runtime48, primPen(), SYM(adjust), formal(primPen(), SYM(p), false, false), formal(primReal(), SYM(arclength), false, false), formal(primBoolean(), SYM(cyclic), false, false));
-#line 530 "runtime.in"
+#line 523 "runtime.in"
   addFunc(ve, run::gen_runtime49, primPen(), SYM(linecap), formal(primInt(), SYM(n), false, false));
-#line 535 "runtime.in"
+#line 528 "runtime.in"
   addFunc(ve, run::gen_runtime50, primInt(), SYM(linecap), formal(primPen(), SYM(p), true, false));
-#line 540 "runtime.in"
+#line 533 "runtime.in"
   addFunc(ve, run::gen_runtime51, primPen(), SYM(linejoin), formal(primInt(), SYM(n), false, false));
-#line 545 "runtime.in"
+#line 538 "runtime.in"
   addFunc(ve, run::gen_runtime52, primInt(), SYM(linejoin), formal(primPen(), SYM(p), true, false));
-#line 550 "runtime.in"
+#line 543 "runtime.in"
   addFunc(ve, run::gen_runtime53, primPen(), SYM(miterlimit), formal(primReal(), SYM(x), false, false));
-#line 555 "runtime.in"
+#line 548 "runtime.in"
   addFunc(ve, run::gen_runtime54, primReal(), SYM(miterlimit), formal(primPen(), SYM(p), true, false));
-#line 560 "runtime.in"
+#line 553 "runtime.in"
   addFunc(ve, run::gen_runtime55, primPen(), SYM(linewidth), formal(primReal(), SYM(x), false, false));
-#line 565 "runtime.in"
+#line 558 "runtime.in"
   addFunc(ve, run::gen_runtime56, primReal(), SYM(linewidth), formal(primPen(), SYM(p), true, false));
-#line 570 "runtime.in"
+#line 563 "runtime.in"
   addFunc(ve, run::gen_runtime57, primPen(), SYM(fontcommand), formal(primString(), SYM(s), false, false));
-#line 575 "runtime.in"
+#line 568 "runtime.in"
   addFunc(ve, run::gen_runtime58, primString() , SYM(font), formal(primPen(), SYM(p), true, false));
-#line 580 "runtime.in"
+#line 573 "runtime.in"
   addFunc(ve, run::gen_runtime59, primPen(), SYM(fontsize), formal(primReal(), SYM(size), false, false), formal(primReal(), SYM(lineskip), false, false));
-#line 586 "runtime.in"
+#line 579 "runtime.in"
   addFunc(ve, run::gen_runtime60, primReal(), SYM(fontsize), formal(primPen(), SYM(p), true, false));
-#line 591 "runtime.in"
+#line 584 "runtime.in"
   addFunc(ve, run::gen_runtime61, primReal(), SYM(lineskip), formal(primPen(), SYM(p), true, false));
-#line 596 "runtime.in"
+#line 589 "runtime.in"
   addFunc(ve, run::gen_runtime62, primPen(), SYM(overwrite), formal(primInt(), SYM(n), false, false));
-#line 602 "runtime.in"
+#line 595 "runtime.in"
   addFunc(ve, run::gen_runtime63, primInt(), SYM(overwrite), formal(primPen(), SYM(p), true, false));
-#line 607 "runtime.in"
+#line 600 "runtime.in"
   addFunc(ve, run::gen_runtime64, primPen(), SYM(basealign), formal(primInt(), SYM(n), false, false));
-#line 612 "runtime.in"
+#line 605 "runtime.in"
   addFunc(ve, run::gen_runtime65, primInt(), SYM(basealign), formal(primPen(), SYM(p), true, false));
-#line 617 "runtime.in"
+#line 610 "runtime.in"
   addFunc(ve, run::gen_runtime66, primTransform(), SYM(transform), formal(primPen(), SYM(p), false, false));
-#line 622 "runtime.in"
+#line 615 "runtime.in"
   addFunc(ve, run::gen_runtime67, primPath(), SYM(nib), formal(primPen(), SYM(p), false, false));
-#line 627 "runtime.in"
+#line 620 "runtime.in"
   addFunc(ve, run::gen_runtime68, primPen(), SYM(makepen), formal(primPath(), SYM(p), false, false));
-#line 632 "runtime.in"
+#line 625 "runtime.in"
   addFunc(ve, run::gen_runtime69, primPen(), SYM(colorless), formal(primPen(), SYM(p), false, false));
+#line 631 "runtime.in"
+  addFunc(ve, run::gen_runtime70, primBoolean(), SYM(interactive));
 #line 638 "runtime.in"
-  addFunc(ve, run::gen_runtime70, primBoolean(), SYM(interactive));
-#line 645 "runtime.in"
   addFunc(ve, run::gen_runtime71, primBoolean(), SYM(uptodate));
-#line 650 "runtime.in"
+#line 643 "runtime.in"
   addFunc(ve, run::gen_runtime72, primInt(), SYM(system), formal(stringArray(), SYM(s), false, false));
-#line 664 "runtime.in"
+#line 657 "runtime.in"
   addFunc(ve, run::gen_runtime73, primBoolean(), SYM(view));
-#line 669 "runtime.in"
+#line 662 "runtime.in"
   addFunc(ve, run::gen_runtime74, primString() , SYM(asydir));
-#line 674 "runtime.in"
+#line 667 "runtime.in"
   addFunc(ve, run::gen_runtime75, primString() , SYM(locale), formal(primString() , SYM(s), true, false));
-#line 680 "runtime.in"
+#line 673 "runtime.in"
   addFunc(ve, run::gen_runtime76, primVoid(), SYM(abort), formal(primString() , SYM(s), true, false));
-#line 686 "runtime.in"
+#line 679 "runtime.in"
   addFunc(ve, run::gen_runtime77, primVoid(), SYM(exit));
-#line 691 "runtime.in"
+#line 684 "runtime.in"
   addFunc(ve, run::gen_runtime78, primVoid(), SYM(assert), formal(primBoolean(), SYM(b), false, false), formal(primString() , SYM(s), true, false));
-#line 702 "runtime.in"
+#line 695 "runtime.in"
   addFunc(ve, run::gen_runtime79, primVoid(), SYM(sleep), formal(primInt(), SYM(seconds), false, false));
-#line 708 "runtime.in"
+#line 701 "runtime.in"
   addFunc(ve, run::gen_runtime80, primVoid(), SYM(usleep), formal(primInt(), SYM(microseconds), false, false));
-#line 714 "runtime.in"
+#line 707 "runtime.in"
   addFunc(ve, run::gen_runtime81, primVoid(), SYM(_eval), formal(primString(), SYM(s), false, false), formal(primBoolean(), SYM(embedded), false, false), formal(primBoolean(), SYM(interactivewrite), true, false));
-#line 727 "runtime.in"
+#line 720 "runtime.in"
   addFunc(ve, run::gen_runtime82, primVoid(), SYM(_eval), formal(primCode(), SYM(s), false, false), formal(primBoolean(), SYM(embedded), false, false));
+#line 736 "runtime.in"
+  addFunc(ve, run::gen_runtime83, primString() , SYM(xasyKEY));
 #line 743 "runtime.in"
-  addFunc(ve, run::gen_runtime83, primString() , SYM(xasyKEY));
-#line 750 "runtime.in"
   addFunc(ve, run::gen_runtime84, primVoid(), SYM(xasyKEY), formal(primString(), SYM(s), false, false));
-#line 754 "runtime.in"
+#line 747 "runtime.in"
   addFunc(ve, run::gen_runtime85, primString() , SYM(toplocation));
-#line 758 "runtime.in"
+#line 751 "runtime.in"
   addFunc(ve, run::gen_runtime86, primString() , SYM(location));
-#line 764 "runtime.in"
+#line 757 "runtime.in"
   REGISTER_BLTIN(run::loadModule,"loadModule");
-#line 770 "runtime.in"
+#line 763 "runtime.in"
   addFunc(ve, run::gen_runtime88, primString() , SYM(cd), formal(primString() , SYM(s), true, false));
-#line 780 "runtime.in"
+#line 773 "runtime.in"
   addFunc(ve, run::gen_runtime89, primVoid(), SYM(list), formal(primString(), SYM(s), false, false), formal(primBoolean(), SYM(imports), true, false));
-#line 789 "runtime.in"
+#line 782 "runtime.in"
   REGISTER_BLTIN(run::nullGuide,"nullGuide");
-#line 797 "runtime.in"
+#line 790 "runtime.in"
   REGISTER_BLTIN(run::dotsGuide,"dotsGuide");
-#line 807 "runtime.in"
+#line 800 "runtime.in"
   REGISTER_BLTIN(run::dashesGuide,"dashesGuide");
-#line 834 "runtime.in"
+#line 827 "runtime.in"
   REGISTER_BLTIN(run::newCycleToken,"newCycleToken");
+#line 832 "runtime.in"
+  addFunc(ve, run::gen_runtime94, primGuide(), symbol::trans("operator cast"), formal(primCycleToken(), SYM(tok), false, false));
 #line 839 "runtime.in"
-  addFunc(ve, run::gen_runtime94, primGuide(), symbol::trans("operator cast"), formal(primCycleToken(), SYM(tok), false, false));
-#line 846 "runtime.in"
   addFunc(ve, run::gen_runtime95, primGuide(), symbol::trans("operator spec"), formal(primPair(), SYM(z), false, false), formal(primInt(), SYM(p), false, false));
-#line 854 "runtime.in"
+#line 847 "runtime.in"
   addFunc(ve, run::gen_runtime96, primCurlSpecifier(), SYM_CURL, formal(primReal(), SYM(gamma), false, false), formal(primInt(), SYM(p), false, false));
-#line 860 "runtime.in"
+#line 853 "runtime.in"
   REGISTER_BLTIN(run::curlSpecifierValuePart,"curlSpecifierValuePart");
-#line 865 "runtime.in"
+#line 858 "runtime.in"
   REGISTER_BLTIN(run::curlSpecifierSidePart,"curlSpecifierSidePart");
-#line 870 "runtime.in"
+#line 863 "runtime.in"
   addFunc(ve, run::gen_runtime99, primGuide(), symbol::trans("operator cast"), formal(primCurlSpecifier(), SYM(spec), false, false));
-#line 875 "runtime.in"
+#line 868 "runtime.in"
   addFunc(ve, run::gen_runtime100, primTensionSpecifier(), SYM_TENSION, formal(primReal(), SYM(tout), false, false), formal(primReal(), SYM(tin), false, false), formal(primBoolean(), SYM(atleast), false, false));
-#line 880 "runtime.in"
+#line 873 "runtime.in"
   REGISTER_BLTIN(run::tensionSpecifierOutPart,"tensionSpecifierOutPart");
-#line 885 "runtime.in"
+#line 878 "runtime.in"
   REGISTER_BLTIN(run::tensionSpecifierInPart,"tensionSpecifierInPart");
-#line 890 "runtime.in"
+#line 883 "runtime.in"
   REGISTER_BLTIN(run::tensionSpecifierAtleastPart,"tensionSpecifierAtleastPart");
-#line 895 "runtime.in"
+#line 888 "runtime.in"
   addFunc(ve, run::gen_runtime104, primGuide(), symbol::trans("operator cast"), formal(primTensionSpecifier(), SYM(t), false, false));
-#line 900 "runtime.in"
+#line 893 "runtime.in"
   addFunc(ve, run::gen_runtime105, primGuide(), SYM_CONTROLS, formal(primPair(), SYM(zout), false, false), formal(primPair(), SYM(zin), false, false));
+#line 898 "runtime.in"
+  addFunc(ve, run::gen_runtime106, primInt(), SYM(size), formal(primGuide(), SYM(g), false, false));
 #line 905 "runtime.in"
-  addFunc(ve, run::gen_runtime106, primInt(), SYM(size), formal(primGuide(), SYM(g), false, false));
+  addFunc(ve, run::gen_runtime107, primInt(), SYM(length), formal(primGuide(), SYM(g), false, false));
 #line 912 "runtime.in"
-  addFunc(ve, run::gen_runtime107, primInt(), SYM(length), formal(primGuide(), SYM(g), false, false));
+  addFunc(ve, run::gen_runtime108, primBoolean(), SYM(cyclic), formal(primGuide(), SYM(g), false, false));
 #line 919 "runtime.in"
-  addFunc(ve, run::gen_runtime108, primBoolean(), SYM(cyclic), formal(primGuide(), SYM(g), false, false));
+  addFunc(ve, run::gen_runtime109, primPair(), SYM(point), formal(primGuide(), SYM(g), false, false), formal(primInt(), SYM(t), false, false));
 #line 926 "runtime.in"
-  addFunc(ve, run::gen_runtime109, primPair(), SYM(point), formal(primGuide(), SYM(g), false, false), formal(primInt(), SYM(t), false, false));
-#line 933 "runtime.in"
   addFunc(ve, run::gen_runtime110, pairArray(), SYM(dirSpecifier), formal(primGuide(), SYM(g), false, false), formal(primInt(), SYM(t), false, false));
-#line 945 "runtime.in"
+#line 938 "runtime.in"
   addFunc(ve, run::gen_runtime111, pairArray(), SYM(controlSpecifier), formal(primGuide(), SYM(g), false, false), formal(primInt(), SYM(t), false, false));
-#line 962 "runtime.in"
+#line 955 "runtime.in"
   addFunc(ve, run::gen_runtime112, primTensionSpecifier(), SYM(tensionSpecifier), formal(primGuide(), SYM(g), false, false), formal(primInt(), SYM(t), false, false));
-#line 972 "runtime.in"
+#line 965 "runtime.in"
   addFunc(ve, run::gen_runtime113, realArray(), SYM(curlSpecifier), formal(primGuide(), SYM(g), false, false), formal(primInt(), SYM(t), false, false));
-#line 986 "runtime.in"
+#line 979 "runtime.in"
   addFunc(ve, run::gen_runtime114, primGuide(), SYM(reverse), formal(primGuide(), SYM(g), false, false));
-#line 1039 "runtime.in"
+#line 1032 "runtime.in"
   addFunc(ve, run::gen_runtime115, realArray(), SYM(_cputime));
-#line 1053 "runtime.in"
+#line 1046 "runtime.in"
   addFunc(ve, run::gen_runtime116, primBoolean(), SYM_EQ, formal(primTransform(), SYM(a), false, false), formal(primTransform(), SYM(b), false, false));
-#line 1061 "runtime.in"
+#line 1054 "runtime.in"
   addFunc(ve, run::gen_runtime117, primBoolean(), SYM_NEQ, formal(primTransform(), SYM(a), false, false), formal(primTransform(), SYM(b), false, false));
-#line 1066 "runtime.in"
+#line 1059 "runtime.in"
   addFunc(ve, run::gen_runtime118, primTransform(), SYM_PLUS, formal(primTransform(), SYM(a), false, false), formal(primTransform(), SYM(b), false, false));
-#line 1071 "runtime.in"
+#line 1064 "runtime.in"
   addFunc(ve, run::gen_runtime119, primTransform(), SYM_TIMES, formal(primTransform(), SYM(a), false, false), formal(primTransform(), SYM(b), false, false));
-#line 1076 "runtime.in"
+#line 1069 "runtime.in"
   addFunc(ve, run::gen_runtime120, primPair(), SYM_TIMES, formal(primTransform(), SYM(t), false, false), formal(primPair(), SYM(z), false, false));
-#line 1081 "runtime.in"
+#line 1074 "runtime.in"
   addFunc(ve, run::gen_runtime121, primPath(), SYM_TIMES, formal(primTransform(), SYM(t), false, false), formal(primPath(), SYM(g), false, false));
-#line 1086 "runtime.in"
+#line 1079 "runtime.in"
   addFunc(ve, run::gen_runtime122, primPen(), SYM_TIMES, formal(primTransform(), SYM(t), false, false), formal(primPen(), SYM(p), false, false));
-#line 1091 "runtime.in"
+#line 1084 "runtime.in"
   addFunc(ve, run::gen_runtime123, primPicture(), SYM_TIMES, formal(primTransform(), SYM(t), false, false), formal(primPicture(), SYM(f), false, false));
-#line 1096 "runtime.in"
+#line 1089 "runtime.in"
   addFunc(ve, run::gen_runtime124, primPicture(), SYM_TIMES, formal(realArray2(), SYM(t), false, false), formal(primPicture(), SYM(f), false, false));
-#line 1101 "runtime.in"
+#line 1094 "runtime.in"
   addFunc(ve, run::gen_runtime125, primTransform(), SYM_CARET, formal(primTransform(), SYM(t), false, false), formal(primInt(), SYM(n), false, false));
-#line 1112 "runtime.in"
+#line 1105 "runtime.in"
   REGISTER_BLTIN(run::transformXPart,"transformXPart");
-#line 1117 "runtime.in"
+#line 1110 "runtime.in"
   REGISTER_BLTIN(run::transformYPart,"transformYPart");
-#line 1122 "runtime.in"
+#line 1115 "runtime.in"
   REGISTER_BLTIN(run::transformXXPart,"transformXXPart");
-#line 1127 "runtime.in"
+#line 1120 "runtime.in"
   REGISTER_BLTIN(run::transformXYPart,"transformXYPart");
-#line 1132 "runtime.in"
+#line 1125 "runtime.in"
   REGISTER_BLTIN(run::transformYXPart,"transformYXPart");
-#line 1137 "runtime.in"
+#line 1130 "runtime.in"
   REGISTER_BLTIN(run::transformYYPart,"transformYYPart");
-#line 1142 "runtime.in"
+#line 1135 "runtime.in"
   REGISTER_BLTIN(run::real6ToTransform,"real6ToTransform");
-#line 1148 "runtime.in"
+#line 1141 "runtime.in"
   addFunc(ve, run::gen_runtime133, primTransform(), SYM(shift), formal(primTransform(), SYM(t), false, false));
-#line 1153 "runtime.in"
+#line 1146 "runtime.in"
   addFunc(ve, run::gen_runtime134, primTransform(), SYM(shiftless), formal(primTransform(), SYM(t), false, false));
-#line 1158 "runtime.in"
+#line 1151 "runtime.in"
   addFunc(ve, run::transformIdentity, primTransform(), SYM(identity));
-#line 1163 "runtime.in"
+#line 1156 "runtime.in"
   addFunc(ve, run::gen_runtime136, primTransform(), SYM(inverse), formal(primTransform(), SYM(t), false, false));
-#line 1168 "runtime.in"
+#line 1161 "runtime.in"
   addFunc(ve, run::gen_runtime137, primTransform(), SYM(shift), formal(primPair(), SYM(z), false, false));
-#line 1173 "runtime.in"
+#line 1166 "runtime.in"
   addFunc(ve, run::gen_runtime138, primTransform(), SYM(shift), formal(primReal(), SYM(x), false, false), formal(primReal(), SYM(y), false, false));
-#line 1178 "runtime.in"
+#line 1171 "runtime.in"
   addFunc(ve, run::gen_runtime139, primTransform(), SYM(xscale), formal(primReal(), SYM(x), false, false));
-#line 1183 "runtime.in"
+#line 1176 "runtime.in"
   addFunc(ve, run::gen_runtime140, primTransform(), SYM(yscale), formal(primReal(), SYM(y), false, false));
-#line 1188 "runtime.in"
+#line 1181 "runtime.in"
   addFunc(ve, run::gen_runtime141, primTransform(), SYM(scale), formal(primReal(), SYM(x), false, false));
-#line 1193 "runtime.in"
+#line 1186 "runtime.in"
   addFunc(ve, run::gen_runtime142, primTransform(), SYM(scale), formal(primReal(), SYM(x), false, false), formal(primReal(), SYM(y), false, false));
-#line 1198 "runtime.in"
+#line 1191 "runtime.in"
   addFunc(ve, run::gen_runtime143, primTransform(), SYM(slant), formal(primReal(), SYM(s), false, false));
-#line 1203 "runtime.in"
+#line 1196 "runtime.in"
   addFunc(ve, run::gen_runtime144, primTransform(), SYM(rotate), formal(primReal(), SYM(angle), false, false), formal(primPair(), SYM(z), true, false));
-#line 1208 "runtime.in"
+#line 1201 "runtime.in"
   addFunc(ve, run::gen_runtime145, primTransform(), SYM(reflect), formal(primPair(), SYM(a), false, false), formal(primPair(), SYM(b), false, false));
 }
 

Modified: trunk/Build/source/utils/asymptote/runtime.in
===================================================================
--- trunk/Build/source/utils/asymptote/runtime.in	2020-03-03 22:33:26 UTC (rev 54033)
+++ trunk/Build/source/utils/asymptote/runtime.in	2020-03-03 22:35:09 UTC (rev 54034)
@@ -30,9 +30,6 @@
 picture* => primPicture()
 transform => primTransform()
 callable* => voidFunction()
-callableBp* => breakpointFunction()
-callableReal* => realRealFunction()
-callableTransform* => transformFunction()
 runnable* => primCode()
 boolarray* => booleanArray()
 Intarray*  => IntArray()
@@ -124,10 +121,6 @@
 typedef array penarray2;
 typedef array stringarray;
 typedef array stringarray2;
-  
-typedef callable callableBp;
-typedef callable callableReal;
-typedef callable callableTransform;
 }
 
 using vm::array;

Modified: trunk/Build/source/utils/asymptote/runtriple.cc
===================================================================
--- trunk/Build/source/utils/asymptote/runtriple.cc	2020-03-03 22:33:26 UTC (rev 54033)
+++ trunk/Build/source/utils/asymptote/runtriple.cc	2020-03-03 22:35:09 UTC (rev 54034)
@@ -64,6 +64,7 @@
 #line 10 "runtriple.in"
 #include "triple.h"
 #include "path3.h"
+#include "drawelement.h"
 
 using namespace camp;
 
@@ -76,108 +77,107 @@
 
 #endif
 namespace run {
-#line 18 "runtriple.in"
+#line 19 "runtriple.in"
 void tripleZero(stack *Stack)
 {
-#line 19 "runtriple.in"
+#line 20 "runtriple.in"
   static triple zero;
   {Stack->push<triple>(zero); return;}
 }
 
-#line 24 "runtriple.in"
+#line 25 "runtriple.in"
 void realRealRealToTriple(stack *Stack)
 {
   real z=vm::pop<real>(Stack);
   real y=vm::pop<real>(Stack);
   real x=vm::pop<real>(Stack);
-#line 25 "runtriple.in"
+#line 26 "runtriple.in"
   {Stack->push<triple>(triple(x,y,z)); return;}
 }
 
-#line 29 "runtriple.in"
+#line 30 "runtriple.in"
 // real xpart(triple v);
 void tripleXPart(stack *Stack)
 {
   triple v=vm::pop<triple>(Stack);
-#line 30 "runtriple.in"
+#line 31 "runtriple.in"
   {Stack->push<real>(v.getx()); return;}
 }
 
-#line 34 "runtriple.in"
+#line 35 "runtriple.in"
 // real ypart(triple v);
 void tripleYPart(stack *Stack)
 {
   triple v=vm::pop<triple>(Stack);
-#line 35 "runtriple.in"
+#line 36 "runtriple.in"
   {Stack->push<real>(v.gety()); return;}
 }
 
-#line 39 "runtriple.in"
+#line 40 "runtriple.in"
 // real zpart(triple v);
 void tripleZPart(stack *Stack)
 {
   triple v=vm::pop<triple>(Stack);
-#line 40 "runtriple.in"
+#line 41 "runtriple.in"
   {Stack->push<real>(v.getz()); return;}
 }
 
-#line 44 "runtriple.in"
+#line 45 "runtriple.in"
 // triple *(real x, triple v);
 void gen_runtriple5(stack *Stack)
 {
   triple v=vm::pop<triple>(Stack);
   real x=vm::pop<real>(Stack);
-#line 45 "runtriple.in"
+#line 46 "runtriple.in"
   {Stack->push<triple>(x*v); return;}
 }
 
-#line 49 "runtriple.in"
+#line 50 "runtriple.in"
 // triple *(triple v, real x);
 void gen_runtriple6(stack *Stack)
 {
   real x=vm::pop<real>(Stack);
   triple v=vm::pop<triple>(Stack);
-#line 50 "runtriple.in"
+#line 51 "runtriple.in"
   {Stack->push<triple>(v*x); return;}
 }
 
-#line 54 "runtriple.in"
+#line 55 "runtriple.in"
 // triple /(triple v, real x);
 void gen_runtriple7(stack *Stack)
 {
   real x=vm::pop<real>(Stack);
   triple v=vm::pop<triple>(Stack);
-#line 55 "runtriple.in"
+#line 56 "runtriple.in"
   {Stack->push<triple>(v/x); return;}
 }
 
-#line 59 "runtriple.in"
+#line 60 "runtriple.in"
 // real length(triple v);
 void gen_runtriple8(stack *Stack)
 {
   triple v=vm::pop<triple>(Stack);
-#line 60 "runtriple.in"
+#line 61 "runtriple.in"
   {Stack->push<real>(v.length()); return;}
 }
 
-#line 64 "runtriple.in"
+#line 65 "runtriple.in"
 // real abs(triple v);
 void gen_runtriple9(stack *Stack)
 {
   triple v=vm::pop<triple>(Stack);
-#line 65 "runtriple.in"
+#line 66 "runtriple.in"
   {Stack->push<real>(v.length()); return;}
 }
 
-#line 69 "runtriple.in"
+#line 70 "runtriple.in"
 // real polar(triple v, bool warn=true);
 void gen_runtriple10(stack *Stack)
 {
   bool warn=vm::pop<bool>(Stack,true);
   triple v=vm::pop<triple>(Stack);
-#line 70 "runtriple.in"
-  if(!warn && v.getx() == 0.0 && v.gety() == 0.0 && v.getz() == 0.0) {Stack->push<real>(0.0); return;}
-  {Stack->push<real>(v.polar()); return;}
+#line 71 "runtriple.in"
+  {Stack->push<real>(v.polar(warn)); return;}
 }
 
 #line 75 "runtriple.in"
@@ -342,7 +342,7 @@
   triple b=vm::pop<triple>(Stack);
   triple a=vm::pop<triple>(Stack);
 #line 154 "runtriple.in"
-  {Stack->push<triple>(6.0*(t*(d-a+3.0*(b-c))+a+c-2.0*b)); return;}
+  {Stack->push<triple>(6.0*(t*(d-a+3.0*(b-c))+a+c)-12.0*b); return;}
 }
 
 #line 158 "runtriple.in"
@@ -354,7 +354,7 @@
   triple b=vm::pop<triple>(Stack);
   triple a=vm::pop<triple>(Stack);
 #line 159 "runtriple.in"
-  {Stack->push<triple>(6.0*(d-a+3.0*(b-c))); return;}
+  {Stack->push<triple>(6.0*(d-a)+18.0*(b-c)); return;}
 }
 
 } // namespace run
@@ -363,27 +363,27 @@
 
 void gen_runtriple_venv(venv &ve)
 {
-#line 18 "runtriple.in"
+#line 19 "runtriple.in"
   REGISTER_BLTIN(run::tripleZero,"tripleZero");
-#line 24 "runtriple.in"
+#line 25 "runtriple.in"
   REGISTER_BLTIN(run::realRealRealToTriple,"realRealRealToTriple");
-#line 29 "runtriple.in"
+#line 30 "runtriple.in"
   addFunc(ve, run::tripleXPart, primReal(), SYM(xpart), formal(primTriple(), SYM(v), false, false));
-#line 34 "runtriple.in"
+#line 35 "runtriple.in"
   addFunc(ve, run::tripleYPart, primReal(), SYM(ypart), formal(primTriple(), SYM(v), false, false));
-#line 39 "runtriple.in"
+#line 40 "runtriple.in"
   addFunc(ve, run::tripleZPart, primReal(), SYM(zpart), formal(primTriple(), SYM(v), false, false));
-#line 44 "runtriple.in"
+#line 45 "runtriple.in"
   addFunc(ve, run::gen_runtriple5, primTriple(), SYM_TIMES, formal(primReal(), SYM(x), false, false), formal(primTriple(), SYM(v), false, false));
-#line 49 "runtriple.in"
+#line 50 "runtriple.in"
   addFunc(ve, run::gen_runtriple6, primTriple(), SYM_TIMES, formal(primTriple(), SYM(v), false, false), formal(primReal(), SYM(x), false, false));
-#line 54 "runtriple.in"
+#line 55 "runtriple.in"
   addFunc(ve, run::gen_runtriple7, primTriple(), SYM_DIVIDE, formal(primTriple(), SYM(v), false, false), formal(primReal(), SYM(x), false, false));
-#line 59 "runtriple.in"
+#line 60 "runtriple.in"
   addFunc(ve, run::gen_runtriple8, primReal(), SYM(length), formal(primTriple(), SYM(v), false, false));
-#line 64 "runtriple.in"
+#line 65 "runtriple.in"
   addFunc(ve, run::gen_runtriple9, primReal(), SYM(abs), formal(primTriple(), SYM(v), false, false));
-#line 69 "runtriple.in"
+#line 70 "runtriple.in"
   addFunc(ve, run::gen_runtriple10, primReal(), SYM(polar), formal(primTriple(), SYM(v), false, false), formal(primBoolean(), SYM(warn), true, false));
 #line 75 "runtriple.in"
   addFunc(ve, run::gen_runtriple11, primReal(), SYM(azimuth), formal(primTriple(), SYM(v), false, false), formal(primBoolean(), SYM(warn), true, false));

Modified: trunk/Build/source/utils/asymptote/runtriple.in
===================================================================
--- trunk/Build/source/utils/asymptote/runtriple.in	2020-03-03 22:33:26 UTC (rev 54033)
+++ trunk/Build/source/utils/asymptote/runtriple.in	2020-03-03 22:35:09 UTC (rev 54034)
@@ -9,6 +9,7 @@
 

 #include "triple.h"
 #include "path3.h"
+#include "drawelement.h"
 
 using namespace camp;
 
@@ -68,8 +69,7 @@
 

 real polar(triple v, bool warn=true) 
 {
-  if(!warn && v.getx() == 0.0 && v.gety() == 0.0 && v.getz() == 0.0) return 0.0;
-  return v.polar();
+  return v.polar(warn);
 }
 

 real azimuth(triple v, bool warn=true) 
@@ -152,11 +152,11 @@
 

 triple bezierPP(triple a, triple b, triple c, triple d, real t) 
 {
-  return 6.0*(t*(d-a+3.0*(b-c))+a+c-2.0*b);
+  return 6.0*(t*(d-a+3.0*(b-c))+a+c)-12.0*b;
 }
 

 triple bezierPPP(triple a, triple b, triple c, triple d) 
 {
-  return 6.0*(d-a+3.0*(b-c));
+  return 6.0*(d-a)+18.0*(b-c);
 }
 


Modified: trunk/Build/source/utils/asymptote/settings.cc
===================================================================
--- trunk/Build/source/utils/asymptote/settings.cc	2020-03-03 22:33:26 UTC (rev 54033)
+++ trunk/Build/source/utils/asymptote/settings.cc	2020-03-03 22:35:09 UTC (rev 54034)
@@ -35,6 +35,8 @@
 #include "pipestream.h"
 #include "array.h"
 
+#include "glrender.h"
+
 #ifdef HAVE_LIBCURSES
 extern "C" {
 
@@ -943,6 +945,7 @@
     bool fftw3=false;
     bool xdr=false;
     bool readline=false;
+    bool editline=false;
     bool sigsegv=false;
     bool usegc=false;
 
@@ -949,24 +952,37 @@
 #if HAVE_LIBGLM
     glm=true;
 #endif
+
 #ifdef HAVE_GL
     gl=true;
 #endif
+
 #ifdef HAVE_LIBGSL
     gsl=true;
 #endif
+
 #ifdef HAVE_LIBFFTW3
     fftw3=true;
 #endif
+
 #ifdef HAVE_RPC_RPC_H
     xdr=true;
 #endif
-#if defined(HAVE_LIBREADLINE) && defined(HAVE_LIBCURSES)
+
+#ifdef HAVE_LIBCURSES
+#ifdef HAVE_LIBREADLINE
     readline=true;
+#else
+#ifdef HAVE_LIBEDIT
+    editline=true;
 #endif
+#endif
+#endif
+
 #ifdef HAVE_LIBSIGSEGV
     sigsegv=true;
 #endif
+
 #ifdef USEGC
     usegc=true;
 #endif
@@ -977,6 +993,8 @@
     feature("FFTW3    Fast Fourier transforms",fftw3);
     feature("XDR      external data representation (portable binary file format)",xdr);
     feature("Readline interactive history and editing",readline);
+    if(!readline)
+      feature("Editline interactive editing (if Readline is unavailable)",editline);
     feature("Sigsegv  distinguish stack overflows from segmentation faults",
             sigsegv);
     feature("GC       Boehm garbage collector",usegc);
@@ -1369,7 +1387,7 @@
                             "Additional frame delay", 0.0));
   addOption(new realSetting("resizestep", 0, "step", "Resize step", 1.2));
   addOption(new IntSetting("digits", 0, "n",
-                           "Default output file precision", 6));
+                           "Default output file precision", 7));
   
   addOption(new realSetting("paperwidth", 0, "bp", ""));
   addOption(new realSetting("paperheight", 0, "bp", ""));

Modified: trunk/Build/source/utils/asymptote/triple.h
===================================================================
--- trunk/Build/source/utils/asymptote/triple.h	2020-03-03 22:33:26 UTC (rev 54033)
+++ trunk/Build/source/utils/asymptote/triple.h	2020-03-03 22:35:09 UTC (rev 54034)
@@ -246,17 +246,21 @@
     return v.length();
   }
 
-  double polar() const /* theta */
+  double polar(bool warn=true) const /* theta */
   {
     double r=length();
-    if (r == 0.0)
-      reportError("taking polar angle of (0,0,0)");
+    if(r == 0.0) {
+      if(warn)
+        reportError("taking polar angle of (0,0,0)");
+      else
+        return 0.0;
+    }
     return acos(z/r);
   }
   
-  double azimuth() const /* phi */
+  double azimuth(bool warn=true) const /* phi */
   {
-    return angle(x,y);
+    return angle(x,y,warn);
   }
   
   friend triple unit(const triple& v)
@@ -294,9 +298,15 @@
     if(paren) s >> c;
     s >> z.x >> std::ws;
     if(s.peek() == ',') s >> c >> z.y;
-    else z.y=0.0;
+    else {
+      if(paren) s >> z.y;
+      else z.y=0.0;
+    }
     if(s.peek() == ',') s >> c >> z.z;
-    else z.z=0.0;
+    else {
+      if(paren) s >> z.z;
+      else z.z=0.0;
+    }
     if(paren) {
       s >> std::ws;
       if(s.peek() == ')') s >> c;
@@ -363,14 +373,43 @@
   return std::max(abs2(c0-v-z0),abs2(z1-v-c1));
 }
 
-// return the perpendicular distance squared of a point z from the plane
-// through u with unit normal n.
-inline double Distance2(const triple& z, const triple& u, const triple& n)
+// Return one ninth of the relative flatness squared of a--b and c--d.
+inline double Flatness(const triple& a, const triple& b, const triple& c,
+                       const triple& d)
 {
-  double d=dot(z-u,n);
-  return d*d;
+  static double ninth=1.0/9.0;
+  triple u=b-a;
+  triple v=d-c;
+  return ninth*std::max(abs2(cross(u,unit(v))),abs2(cross(v,unit(u))));
 }
-  
+
+// Return one-half of the second derivative of the Bezier curve defined by
+// a,b,c,d at t=0.
+inline triple bezierPP(const triple& a, const triple& b, const triple& c) {
+  return 3.0*(a+c)-6.0*b;
+}
+
+// Return one-sixth of the third derivative of the Bezier curve defined by
+// a,b,c,d at t=0.
+inline triple bezierPPP(const triple& a, const triple& b, const triple& c,
+                        const triple& d) {
+  return d-a+3.0*(b-c);
+}
+
+// Return four-thirds of the first derivative of the Bezier curve defined by
+// a,b,c,d at t=1/2.
+inline triple bezierPh(triple a, triple b, triple c, triple d)
+{
+  return c+d-a-b;
+}
+
+// Return two-thirds of the second derivative of the Bezier curve defined by
+// a,b,c,d at t=1/2.
+inline triple bezierPPh(triple a, triple b, triple c, triple d)
+{
+  return 3.0*a-5.0*b+c+d;
+}
+
 } //namespace camp
 
 GC_DECLARE_PTRFREE(camp::triple);

Modified: trunk/Build/source/utils/asymptote/webgl/gl.js
===================================================================
--- trunk/Build/source/utils/asymptote/webgl/gl.js	2020-03-03 22:33:26 UTC (rev 54033)
+++ trunk/Build/source/utils/asymptote/webgl/gl.js	2020-03-03 22:35:09 UTC (rev 54034)
@@ -41,7 +41,6 @@
 let halfCanvasWidth,halfCanvasHeight;
 
 let pixel=0.75; // Adaptive rendering constant.
-let BezierFactor=0.4;
 let FillFactor=0.1;
 let Zoom;
 
@@ -54,8 +53,6 @@
 let lastzoom;
 let H; // maximum camera view half-height
 
-let Fuzz2=1000*Number.EPSILON;
-let Fuzz4=Fuzz2*Fuzz2;
 let third=1/3;
 
 let rotMat=mat4.create();
@@ -65,9 +62,8 @@
 let projViewMat=mat4.create(); // projection view matrix
 let normMat=mat3.create();
 let viewMat3=mat3.create(); // 3x3 view matrix
-let rotMats=mat4.create();
 let cjMatInv=mat4.create();
-let translMat=mat4.create();
+let T=mat4.create(); // Temporary matrix
 
 let zmin,zmax;
 let center={x:0,y:0,z:0};
@@ -89,6 +85,7 @@
 let indexBuffer;
 
 let remesh=true;
+let wireframe=0;
 let mouseDownOrTouchActive=false;
 let lastMouseX=null;
 let lastMouseY=null;
@@ -147,7 +144,6 @@
   maxMaterials=Math.floor((maxUniforms-14)/4);
   Nmaterials=Math.min(Math.max(Nmaterials,Materials.length),maxMaterials);
 
-  noNormalShader=initShader();
   pixelShader=initShader(["WIDTH"]);
   materialShader=initShader(["NORMAL"]);
   colorShader=initShader(["NORMAL","COLOR"]);
@@ -154,6 +150,14 @@
   transparentShader=initShader(["NORMAL","COLOR","TRANSPARENT"]);
 }
 
+function deleteShaders()
+{
+  gl.deleteProgram(transparentShader);
+  gl.deleteProgram(colorShader);
+  gl.deleteProgram(materialShader);
+  gl.deleteProgram(pixelShader);
+}
+
 // Create buffers for the patch and its subdivisions.
 function setBuffers()
 {
@@ -177,7 +181,6 @@
   a.Nmaterials=Nmaterials;
   a.maxMaterials=maxMaterials;
 
-  a.noNormalShader=noNormalShader;
   a.pixelShader=pixelShader;
   a.materialShader=materialShader;
   a.colorShader=colorShader;
@@ -193,7 +196,6 @@
   Nmaterials=a.Nmaterials;
   maxMaterials=a.maxMaterials;
 
-  noNormalShader=a.noNormalShader;
   pixelShader=a.pixelShader;
   materialShader=a.materialShader;
   colorShader=a.colorShader;
@@ -241,6 +243,14 @@
 
   setBuffers();
   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(gl,shaderScript,type,options=[])
@@ -251,7 +261,7 @@
 #else
   precision mediump float;
 #endif
-  #define nlights ${Lights.length}\n
+  #define nlights ${wireframe == 0 ? Lights.length : 0}\n
   const int Nlights=${Math.max(Lights.length,1)};\n
   #define Nmaterials ${Nmaterials}\n`;
 
@@ -274,8 +284,7 @@
 {
   if(data.indices.length == 0) return;
   
-  let pixel=shader == pixelShader;
-  let normal=shader != noNormalShader && !pixel;
+  let normal=shader != pixelShader;
 
   setUniforms(data,shader);
 
@@ -283,7 +292,7 @@
   gl.bufferData(gl.ARRAY_BUFFER,new Float32Array(data.vertices),
                 gl.STATIC_DRAW);
   gl.vertexAttribPointer(positionAttribute,3,gl.FLOAT,false,
-                         normal ? 24 : (pixel ? 16 : 12),0);
+                         normal ? 24 : 16,0);
   if(normal && Lights.length > 0)
     gl.vertexAttribPointer(normalAttribute,3,gl.FLOAT,false,24,12);
   else if(pixel)
@@ -306,13 +315,16 @@
                 indexExt ? new Uint32Array(indices) :
                 new Uint16Array(indices),gl.STATIC_DRAW);
 
-  gl.drawElements(normal ? gl.TRIANGLES : (pixel ? gl.POINTS : gl.LINES),
+  gl.drawElements(normal ? (wireframe ? gl.LINES : data.type) : gl.POINTS,
                   indices.length,
                   indexExt ? gl.UNSIGNED_INT : gl.UNSIGNED_SHORT,0);
 }
 
+let TRIANGLES;
+
 class vertexBuffer {
-  constructor() {
+  constructor(type) {
+    this.type=type ? type : TRIANGLES;
     this.clear();
   }
   clear() {
@@ -354,15 +366,6 @@
     return this.nvertices++;
   }
 
-   // material vertex without normal
-  vertex1(v) {
-    this.vertices.push(v[0]);
-    this.vertices.push(v[1]);
-    this.vertices.push(v[2]);
-    this.materialIndices.push(materialIndex);
-    return this.nvertices++;
-  }
-
   // material vertex with width and without normal 
   vertex0(v,width) {
     this.vertices.push(v[0]);
@@ -400,14 +403,13 @@
   }
 }
 
-let material0Data=new vertexBuffer();    // pixels
-let material1Data=new vertexBuffer();    // material Bezier curves
-let materialData=new vertexBuffer();     // material Bezier patches & triangles
-let colorData=new vertexBuffer();        // colored Bezier patches & triangles
-let transparentData=new vertexBuffer();  // transparent patches & triangles
-let triangleData=new vertexBuffer();     // opaque indexed triangles
+let material0Data;    // pixels
+let material1Data;    // material Bezier curves
+let materialData;     // material Bezier patches & triangles
+let colorData;        // colored Bezier patches & triangles
+let transparentData;  // transparent patches & triangles
+let triangleData;     // opaque indexed triangles
 
-
 let materialIndex;
 
 // efficiently append array b onto array a
@@ -590,7 +592,7 @@
     for(let i=1; i < n; ++i)
       this.epsilon=Math.max(this.epsilon,
         abs2([p[i][0]-p0[0],p[i][1]-p0[1],p[i][2]-p0[2]]));
-    this.epsilon *= Fuzz4;
+    this.epsilon *= Number.EPSILON
   }
 
   processTriangle(p) {
@@ -600,15 +602,30 @@
     let n=unit(cross([p1[0]-p0[0],p1[1]-p0[1],p1[2]-p0[2]],
                      [p2[0]-p0[0],p2[1]-p0[1],p2[2]-p0[2]]));
     if(!this.offscreen([p0,p1,p2])) {
+      let i0,i1,i2;
       if(this.color) {
-        this.data.indices.push(this.data.Vertex(p0,n,this.color[0]));
-        this.data.indices.push(this.data.Vertex(p1,n,this.color[1]));
-        this.data.indices.push(this.data.Vertex(p2,n,this.color[2]));
+        i0=this.data.Vertex(p0,n,this.color[0]);
+        i1=this.data.Vertex(p1,n,this.color[1]);
+        i2=this.data.Vertex(p2,n,this.color[2]);
       } else {
-        this.data.indices.push(this.vertex(p0,n));
-        this.data.indices.push(this.vertex(p1,n));
-        this.data.indices.push(this.vertex(p2,n));
+        i0=this.vertex(p0,n);
+        i1=this.vertex(p1,n);
+        i2=this.vertex(p2,n);
       }
+
+      if(wireframe == 0) {
+        this.data.indices.push(i0);
+        this.data.indices.push(i1);
+        this.data.indices.push(i2);
+      } else {
+        this.data.indices.push(i0);
+        this.data.indices.push(i1);
+        this.data.indices.push(i1);
+        this.data.indices.push(i2);
+        this.data.indices.push(i2);
+        this.data.indices.push(i0);
+      }
+
       this.append();
     }
   }
@@ -636,20 +653,38 @@
         i2=this.vertex(p2,n);
         i3=this.vertex(p3,n);
       }
-      this.data.indices.push(i0);
-      this.data.indices.push(i1);
-      this.data.indices.push(i2);
 
-      this.data.indices.push(i0);
-      this.data.indices.push(i2);
-      this.data.indices.push(i3);
+      if(wireframe == 0) {
+        this.data.indices.push(i0);
+        this.data.indices.push(i1);
+        this.data.indices.push(i2);
 
+        this.data.indices.push(i0);
+        this.data.indices.push(i2);
+        this.data.indices.push(i3);
+      } else {
+        this.data.indices.push(i0);
+        this.data.indices.push(i1);
+        this.data.indices.push(i1);
+        this.data.indices.push(i2);
+        this.data.indices.push(i2);
+        this.data.indices.push(i3);
+        this.data.indices.push(i3);
+        this.data.indices.push(i0);
+      }
+
       this.append();
     }
   }
 
+  curve(p,a,b,c,d) {
+    new BezierCurve([p[a],p[b],p[c],p[d]],0,materialIndex,
+                    this.Min,this.Max).render();
+  }
+
   process(p) {
-    if(this.transparent) // Override materialIndex to encode color vs material
+    if(this.transparent && wireframe != 1)
+      // Override materialIndex to encode color vs material
       materialIndex=this.color ? -1-materialIndex : 1+materialIndex;
 
     if(p.length == 10) return this.process3(p);
@@ -656,6 +691,14 @@
     if(p.length == 3) return this.processTriangle(p);
     if(p.length == 4) return this.processQuad(p);
     
+    if(wireframe == 1) {
+      this.curve(p,0,4,8,12);
+      this.curve(p,12,13,14,15);
+      this.curve(p,15,11,7,3);
+      this.curve(p,3,2,1,0);
+      return;
+    }
+
     let p0=p[0];
     let p3=p[3];
     let p12=p[12];
@@ -662,27 +705,31 @@
     let p15=p[15];
 
     let n0=this.normal(p3,p[2],p[1],p0,p[4],p[8],p12);
-    if(iszero(n0)) {
+    if(abs2(n0) < this.epsilon) {
       n0=this.normal(p3,p[2],p[1],p0,p[13],p[14],p15);
-      if(iszero(n0)) n0=this.normal(p15,p[11],p[7],p3,p[4],p[8],p12);
+      if(abs2(n0) < this.epsilon)
+        n0=this.normal(p15,p[11],p[7],p3,p[4],p[8],p12);
     }
 
     let n1=this.normal(p0,p[4],p[8],p12,p[13],p[14],p15);
-    if(iszero(n1)) {
+    if(abs2(n1) < this.epsilon) {
       n1=this.normal(p0,p[4],p[8],p12,p[11],p[7],p3);
-      if(iszero(n1)) n1=this.normal(p3,p[2],p[1],p0,p[13],p[14],p15);
+      if(abs2(n1) < this.epsilon)
+        n1=this.normal(p3,p[2],p[1],p0,p[13],p[14],p15);
     }
 
     let n2=this.normal(p12,p[13],p[14],p15,p[11],p[7],p3);
-    if(iszero(n2)) {
+    if(abs2(n2) < this.epsilon) {
       n2=this.normal(p12,p[13],p[14],p15,p[2],p[1],p0);
-      if(iszero(n2)) n2=this.normal(p0,p[4],p[8],p12,p[11],p[7],p3);
+      if(abs2(n2) < this.epsilon)
+        n2=this.normal(p0,p[4],p[8],p12,p[11],p[7],p3);
     }
 
     let n3=this.normal(p15,p[11],p[7],p3,p[2],p[1],p0);
-    if(iszero(n3)) {
+    if(abs2(n3) < this.epsilon) {
       n3=this.normal(p15,p[11],p[7],p3,p[4],p[8],p12);
-      if(iszero(n3)) n3=this.normal(p12,p[13],p[14],p15,p[2],p[1],p0);
+      if(abs2(n3) < this.epsilon)
+        n3=this.normal(p12,p[13],p[14],p15,p[2],p[1],p0);
     }
 
     if(this.color) {
@@ -719,29 +766,43 @@
   }
 
   Render(p,I0,I1,I2,I3,P0,P1,P2,P3,flat0,flat1,flat2,flat3,C0,C1,C2,C3) {
-    if(this.Distance(p) < this.res2) { // Bezier patch is flat
+    let d=this.Distance(p);
+    if(d[0] < this.res2 && d[1] < this.res2) { // Bezier patch is flat
       if(!this.offscreen([P0,P1,P2])) {
-        this.data.indices.push(I0);
-        this.data.indices.push(I1);
-        this.data.indices.push(I2);
+        if(wireframe == 0) {
+          this.data.indices.push(I0);
+          this.data.indices.push(I1);
+          this.data.indices.push(I2);
+        } else {
+          this.data.indices.push(I0);
+          this.data.indices.push(I1);
+          this.data.indices.push(I1);
+          this.data.indices.push(I2);
+        }
       }        
       if(!this.offscreen([P0,P2,P3])) {
-        this.data.indices.push(I0);
-        this.data.indices.push(I2);
-        this.data.indices.push(I3);
+        if(wireframe == 0) {
+          this.data.indices.push(I0);
+          this.data.indices.push(I2);
+          this.data.indices.push(I3);
+        } else {
+          this.data.indices.push(I2);
+          this.data.indices.push(I3);
+          this.data.indices.push(I3);
+          this.data.indices.push(I0);
+        }
       }
     } else {
   // Approximate bounds by bounding box of control polyhedron.
       if(this.offscreen(p)) return;
 
-    /* Control points are indexed as follows:
+      /* Control points are indexed as follows:
          
        Coordinate
        +-----
         Index
          
-
-       03    13    23    33
+        03    13    23    33
        +-----+-----+-----+
        |3    |7    |11   |15
        |     |     |     |
@@ -755,13 +816,228 @@
        |     |     |     |
        |00   |10   |20   |30
        +-----+-----+-----+
-       0     4     8     12
+        0     4     8     12
+
+      */
          
+      let p0=p[0];
+      let p3=p[3];
+      let p12=p[12];
+      let p15=p[15];
 
-       Subdivision:
+      if(d[0] < this.res2) { // flat in horizontal direction; split vertically
+        /*
        P refers to a corner
        m refers to a midpoint
        s refers to a subpatch
+
+       +--------+--------+
+       |P3             P2|
+       |                 |
+       |       s1        |
+       |                 |
+       |                 |
+    m1 +-----------------+ m0
+       |                 |
+       |                 |
+       |       s0        |
+       |                 |
+       |P0             P1|
+       +-----------------+
+
+        */
+
+        let c0=new Split3(p0,p[1],p[2],p3);
+        let c1=new Split3(p[4],p[5],p[6],p[7]);
+        let c2=new Split3(p[8],p[9],p[10],p[11]);
+        let c3=new Split3(p12,p[13],p[14],p15);
+
+        let s0=[p0  ,c0.m0,c0.m3,c0.m5,
+                p[4],c1.m0,c1.m3,c1.m5,
+                p[8],c2.m0,c2.m3,c2.m5,
+                p12 ,c3.m0,c3.m3,c3.m5];
+
+        let s1=[c0.m5,c0.m4,c0.m2,p3,
+                c1.m5,c1.m4,c1.m2,p[7],
+                c2.m5,c2.m4,c2.m2,p[11],
+                c3.m5,c3.m4,c3.m2,p15];
+
+        let n0=this.normal(s0[12],s0[13],s0[14],s0[15],s0[11],s0[7],s0[3]);
+        if(abs2(n0) <= this.epsilon) {
+          n0=this.normal(s0[12],s0[13],s0[14],s0[15],s0[2],s0[1],s0[0]);
+          if(abs2(n0) <= this.epsilon)
+            n0=this.normal(s0[0],s0[4],s0[8],s0[12],s0[11],s0[7],s0[3]);
+        }
+
+        let n1=this.normal(s1[3],s1[2],s1[1],s1[0],s1[4],s1[8],s1[12]);
+        if(abs2(n1) <= this.epsilon) {
+          n1=this.normal(s1[3],s1[2],s1[1],s1[0],s1[13],s1[14],s1[15]);
+          if(abs2(n1) <= this.epsilon)
+            n1=this.normal(s1[15],s1[11],s1[7],s1[3],s1[4],s1[8],s1[12]);
+        }
+
+        let e=this.Epsilon;
+
+        // A kludge to remove subdivision cracks, only applied the first time
+        // an edge is found to be flat before the rest of the subpatch is.
+
+        let m0=[0.5*(P1[0]+P2[0]),
+                0.5*(P1[1]+P2[1]),
+                0.5*(P1[2]+P2[2])];
+        if(!flat1) {
+          if((flat1=Straightness(p12,p[13],p[14],p15) < this.res2)) {
+            let r=unit(this.differential(s1[12],s1[8],s1[4],s1[0]));
+            m0=[m0[0]-e*r[0],m0[1]-e*r[1],m0[2]-e*r[2]];
+          }
+          else m0=s0[15];
+        }
+
+        let m1=[0.5*(P3[0]+P0[0]),
+                0.5*(P3[1]+P0[1]),
+                0.5*(P3[2]+P0[2])];
+        if(!flat3) {
+          if((flat3=Straightness(p0,p[1],p[2],p3) < this.res2)) {
+            let r=unit(this.differential(s0[3],s0[7],s0[11],s0[15]));
+            m1=[m1[0]-e*r[0],m1[1]-e*r[1],m1[2]-e*r[2]];
+          }
+          else m1=s1[0];
+        }
+
+        if(C0) {
+          let c0=Array(4);
+          let c1=Array(4);
+          for(let i=0; i < 4; ++i) {
+            c0[i]=0.5*(C1[i]+C2[i]);
+            c1[i]=0.5*(C3[i]+C0[i]);
+          }
+
+          let i0=this.data.Vertex(m0,n0,c0);
+          let i1=this.data.Vertex(m1,n1,c1);
+
+          this.Render(s0,I0,I1,i0,i1,P0,P1,m0,m1,flat0,flat1,false,flat3,
+                      C0,C1,c0,c1);
+          this.Render(s1,i1,i0,I2,I3,m1,m0,P2,P3,false,flat1,flat2,flat3,
+                      c1,c0,C2,C3);
+        } else {
+          let i0=this.vertex(m0,n0);
+          let i1=this.vertex(m1,n1);
+
+          this.Render(s0,I0,I1,i0,i1,P0,P1,m0,m1,flat0,flat1,false,flat3);
+          this.Render(s1,i1,i0,I2,I3,m1,m0,P2,P3,false,flat1,flat2,flat3);
+        }
+        return;
+      }
+
+      if(d[1] < this.res2) { // flat in vertical direction; split horizontally
+        /*
+          P refers to a corner
+          m refers to a midpoint
+          s refers to a subpatch
+
+                   m1
+          +--------+--------+
+          |P3      |      P2|
+          |        |        |
+          |        |        |
+          |        |        |
+          |        |        |
+          |   s0   |   s1   |
+          |        |        |
+          |        |        |
+          |        |        |
+          |        |        |
+          |P0      |      P1|
+          +--------+--------+
+                   m0
+
+        */
+
+        let c0=new Split3(p0,p[4],p[8],p12);
+        let c1=new Split3(p[1],p[5],p[9],p[13]);
+        let c2=new Split3(p[2],p[6],p[10],p[14]);
+        let c3=new Split3(p3,p[7],p[11],p15);
+
+        let s0=[p0,p[1],p[2],p3,
+                c0.m0,c1.m0,c2.m0,c3.m0,
+                c0.m3,c1.m3,c2.m3,c3.m3,
+                c0.m5,c1.m5,c2.m5,c3.m5];
+
+        let s1=[c0.m5,c1.m5,c2.m5,c3.m5,
+                c0.m4,c1.m4,c2.m4,c3.m4,
+                c0.m2,c1.m2,c2.m2,c3.m2,
+                p12,p[13],p[14],p15];
+
+        let n0=this.normal(s0[0],s0[4],s0[8],s0[12],s0[13],s0[14],s0[15]);
+        if(abs2(n0) <= this.epsilon) {
+          n0=this.normal(s0[0],s0[4],s0[8],s0[12],s0[11],s0[7],s0[3]);
+          if(abs2(n0) <= this.epsilon)
+            n0=this.normal(s0[3],s0[2],s0[1],s0[0],s0[13],s0[14],s0[15]);
+        }
+
+        let n1=this.normal(s1[15],s1[11],s1[7],s1[3],s1[2],s1[1],s1[0]);
+        if(abs2(n1) <= this.epsilon) {
+          n1=this.normal(s1[15],s1[11],s1[7],s1[3],s1[4],s1[8],s1[12]);
+          if(abs2(n1) <= this.epsilon)
+            n1=this.normal(s1[12],s1[13],s1[14],s1[15],s1[2],s1[1],s1[0]);
+        }
+
+        let e=this.Epsilon;
+
+        // A kludge to remove subdivision cracks, only applied the first time
+        // an edge is found to be flat before the rest of the subpatch is.
+
+        let m0=[0.5*(P0[0]+P1[0]),
+                0.5*(P0[1]+P1[1]),
+                0.5*(P0[2]+P1[2])];
+        if(!flat0) {
+          if((flat0=Straightness(p0,p[4],p[8],p12) < this.res2)) {
+            let r=unit(this.differential(s1[0],s1[1],s1[2],s1[3]));
+            m0=[m0[0]-e*r[0],m0[1]-e*r[1],m0[2]-e*r[2]];
+          }
+          else m0=s0[12];
+        }
+
+        let m1=[0.5*(P2[0]+P3[0]),
+                0.5*(P2[1]+P3[1]),
+                0.5*(P2[2]+P3[2])];
+        if(!flat2) {
+          if((flat2=Straightness(p15,p[11],p[7],p3) < this.res2)) {
+            let r=unit(this.differential(s0[15],s0[14],s0[13],s0[12]));
+            m1=[m1[0]-e*r[0],m1[1]-e*r[1],m1[2]-e*r[2]];
+          }
+          else m1=s1[3];
+        }
+
+        if(C0) {
+          let c0=Array(4);
+          let c1=Array(4);
+          for(let i=0; i < 4; ++i) {
+            c0[i]=0.5*(C0[i]+C1[i]);
+            c1[i]=0.5*(C2[i]+C3[i]);
+          }
+
+          let i0=this.data.Vertex(m0,n0,c0);
+          let i1=this.data.Vertex(m1,n1,c1);
+
+          this.Render(s0,I0,i0,i1,I3,P0,m0,m1,P3,flat0,false,flat2,flat3,
+                      C0,c0,c1,C3);
+          this.Render(s1,i0,I1,I2,i1,m0,P1,P2,m1,flat0,flat1,flat2,false,
+                      c0,C1,C2,c1);
+        } else {
+          let i0=this.vertex(m0,n0);
+          let i1=this.vertex(m1,n1);
+
+          this.Render(s0,I0,i0,i1,I3,P0,m0,m1,P3,flat0,false,flat2,flat3);
+          this.Render(s1,i0,I1,I2,i1,m0,P1,P2,m1,flat0,flat1,flat2,false);
+        }
+        return;
+      }
+
+      /*
+       Horizontal and vertical subdivision:
+       P refers to a corner
+       m refers to a midpoint
+       s refers to a subpatch
          
                 m2
        +--------+--------+
@@ -769,8 +1045,8 @@
        |        |        |
        |   s3   |   s2   |
        |        |        |
-       |        |m4      |
-     m3+--------+--------+m1
+       |        | m4     |
+    m3 +--------+--------+ m1
        |        |        |
        |        |        |
        |   s0   |   s1   |
@@ -779,14 +1055,9 @@
        +--------+--------+
                 m0
     */
-    
+
       // Subdivide patch:
 
-      let p0=p[0];
-      let p3=p[3];
-      let p12=p[12];
-      let p15=p[15];
-
       let c0=new Split3(p0,p[1],p[2],p3);
       let c1=new Split3(p[4],p[5],p[6],p[7]);
       let c2=new Split3(p[8],p[9],p[10],p[11]);
@@ -812,30 +1083,30 @@
       let m4=s0[15];
 
       let n0=this.normal(s0[0],s0[4],s0[8],s0[12],s0[13],s0[14],s0[15]);
-      if(iszero(n0)) {
+      if(abs2(n0) < this.epsilon) {
         n0=this.normal(s0[0],s0[4],s0[8],s0[12],s0[11],s0[7],s0[3]);
-        if(iszero(n0))
+        if(abs2(n0) < this.epsilon)
           n0=this.normal(s0[3],s0[2],s0[1],s0[0],s0[13],s0[14],s0[15]);
       }
 
       let n1=this.normal(s1[12],s1[13],s1[14],s1[15],s1[11],s1[7],s1[3]);
-      if(iszero(n1)) {
+      if(abs2(n1) < this.epsilon) {
         n1=this.normal(s1[12],s1[13],s1[14],s1[15],s1[2],s1[1],s1[0]);
-        if(iszero(n1))
+        if(abs2(n1) < this.epsilon)
           n1=this.normal(s1[0],s1[4],s1[8],s1[12],s1[11],s1[7],s1[3]);
       }
 
       let n2=this.normal(s2[15],s2[11],s2[7],s2[3],s2[2],s2[1],s2[0]);
-      if(iszero(n2)) {
+      if(abs2(n2) < this.epsilon) {
         n2=this.normal(s2[15],s2[11],s2[7],s2[3],s2[4],s2[8],s2[12]);
-        if(iszero(n2))
+        if(abs2(n2) < this.epsilon)
           n2=this.normal(s2[12],s2[13],s2[14],s2[15],s2[2],s2[1],s2[0]);
       }
 
       let n3=this.normal(s3[3],s3[2],s3[1],s3[0],s3[4],s3[8],s3[12]);
-      if(iszero(n3)) {
+      if(abs2(n3) < this.epsilon) {
         n3=this.normal(s3[3],s3[2],s3[1],s3[0],s3[13],s3[14],s3[15]);
-        if(iszero(n3))
+        if(abs2(n3) < this.epsilon)
           n3=this.normal(s3[15],s3[11],s3[7],s3[3],s3[4],s3[8],s3[12]);
       }
 
@@ -850,7 +1121,7 @@
               0.5*(P0[2]+P1[2])];
       if(!flat0) {
         if((flat0=Straightness(p0,p[4],p[8],p12) < this.res2)) {
-          let r=unit(this.derivative(s1[0],s1[1],s1[2],s1[3]));
+          let r=unit(this.differential(s1[0],s1[1],s1[2],s1[3]));
           m0=[m0[0]-e*r[0],m0[1]-e*r[1],m0[2]-e*r[2]];
         }
         else m0=s0[12];
@@ -861,7 +1132,7 @@
               0.5*(P1[2]+P2[2])];
       if(!flat1) {
         if((flat1=Straightness(p12,p[13],p[14],p15) < this.res2)) {
-          let r=unit(this.derivative(s2[12],s2[8],s2[4],s2[0]));
+          let r=unit(this.differential(s2[12],s2[8],s2[4],s2[0]));
           m1=[m1[0]-e*r[0],m1[1]-e*r[1],m1[2]-e*r[2]];
         }
         else m1=s1[15];
@@ -872,7 +1143,7 @@
               0.5*(P2[2]+P3[2])];
       if(!flat2) {
         if((flat2=Straightness(p15,p[11],p[7],p3) < this.res2)) {
-          let r=unit(this.derivative(s3[15],s2[14],s2[13],s1[12]));
+          let r=unit(this.differential(s3[15],s3[14],s3[13],s3[12]));
           m2=[m2[0]-e*r[0],m2[1]-e*r[1],m2[2]-e*r[2]];
         }
         else m2=s2[3];
@@ -883,7 +1154,7 @@
               0.5*(P3[2]+P0[2])];
       if(!flat3) {
         if((flat3=Straightness(p0,p[1],p[2],p3) < this.res2)) {
-          let r=unit(this.derivative(s0[3],s0[7],s0[11],s0[15]));
+          let r=unit(this.differential(s0[3],s0[7],s0[11],s0[15]));
           m3=[m3[0]-e*r[0],m3[1]-e*r[1],m3[2]-e*r[2]];
         }
         else m3=s3[0];
@@ -934,7 +1205,12 @@
 
 // Render a Bezier triangle via subdivision.
   process3(p) {
-    this.Res2=BezierFactor*BezierFactor*this.res2;
+    if(wireframe == 1) {
+      this.curve(p,0,1,3,6);
+      this.curve(p,6,7,8,9);
+      this.curve(p,9,5,2,0);
+      return;
+    }
 
     let p0=p[0];
     let p6=p[6];
@@ -966,11 +1242,20 @@
   }
 
   Render3(p,I0,I1,I2,P0,P1,P2,flat0,flat1,flat2,C0,C1,C2) {
-    if(this.Distance3(p) < this.Res2) { // Bezier triangle is flat
+    if(this.Distance3(p) < this.res2) { // Bezier triangle is flat
       if(!this.offscreen([P0,P1,P2])) {
-        this.data.indices.push(I0);
-        this.data.indices.push(I1);
-        this.data.indices.push(I2);
+        if(wireframe == 0) {
+          this.data.indices.push(I0);
+          this.data.indices.push(I1);
+          this.data.indices.push(I2);
+        } else {
+          this.data.indices.push(I0);
+          this.data.indices.push(I1);
+          this.data.indices.push(I1);
+          this.data.indices.push(I2);
+          this.data.indices.push(I2);
+          this.data.indices.push(I0);
+        }
       }
     } else {
   // Approximate bounds by bounding box of control polyhedron.
@@ -1174,7 +1459,7 @@
               0.5*(P1[2]+P2[2])];
       if(!flat0) {
         if((flat0=Straightness(r300,p210,p120,u030) < this.res2)) {
-          let r=unit(this.sumderivative(c[0],c[2],c[5],c[9],c[1],c[3],c[6]));
+          let r=unit(this.sumdifferential(c[0],c[2],c[5],c[9],c[1],c[3],c[6]));
           m0=[m0[0]-e*r[0],m0[1]-e*r[1],m0[2]-e*r[2]];
         }
         else m0=r030;
@@ -1186,7 +1471,7 @@
               0.5*(P2[2]+P0[2])];
       if(!flat1) {
         if((flat1=Straightness(l003,p012,p021,u030) < this.res2)) {
-          let r=unit(this.sumderivative(c[6],c[3],c[1],c[0],c[7],c[8],c[9]));
+          let r=unit(this.sumdifferential(c[6],c[3],c[1],c[0],c[7],c[8],c[9]));
           m1=[m1[0]-e*r[0],m1[1]-e*r[1],m1[2]-e*r[2]];
         }
         else m1=l030;
@@ -1197,7 +1482,7 @@
               0.5*(P0[2]+P1[2])];
       if(!flat2) {
         if((flat2=Straightness(l003,p102,p201,r300) < this.res2)) {
-          let r=unit(this.sumderivative(c[9],c[8],c[7],c[6],c[5],c[2],c[0]));
+          let r=unit(this.sumdifferential(c[9],c[8],c[7],c[6],c[5],c[2],c[0]));
           m2=[m2[0]-e*r[0],m2[1]-e*r[1],m2[2]-e*r[2]];
         }
         else m2=l300;
@@ -1241,20 +1526,23 @@
     let p12=p[12];
     let p15=p[15];
 
-    // Check the flatness of a patch.
-    let d=Distance2(p15,p0,this.normal(p3,p[2],p[1],p0,p[4],p[8],p12));
-    
-    // Determine how straight the edges are.
-    d=Math.max(d,Straightness(p0,p[1],p[2],p3));
-    d=Math.max(d,Straightness(p0,p[4],p[8],p12));
-    d=Math.max(d,Straightness(p3,p[7],p[11],p15));
-    d=Math.max(d,Straightness(p12,p[13],p[14],p15));
-    
-    // Determine how straight the interior control curves are.
-    d=Math.max(d,Straightness(p[4],p[5],p[6],p[7]));
-    d=Math.max(d,Straightness(p[8],p[9],p[10],p[11]));
-    d=Math.max(d,Straightness(p[1],p[5],p[9],p[13]));
-    return Math.max(d,Straightness(p[2],p[6],p[10],p[14]));
+    // Check the horizontal flatness.
+    let h=Flatness(p0,p12,p3,p15);
+    // Check straightness of the horizontal edges and interior control curves.
+    h=Math.max(Straightness(p0,p[4],p[8],p12));
+    h=Math.max(h,Straightness(p[1],p[5],p[9],p[13]));
+    h=Math.max(h,Straightness(p3,p[7],p[11],p15));
+    h=Math.max(h,Straightness(p[2],p[6],p[10],p[14]));
+
+    // Check the vertical flatness.
+    let v=Flatness(p0,p3,p12,p15);
+    // Check straightness of the vertical edges and interior control curves.
+    v=Math.max(v,Straightness(p0,p[1],p[2],p3));
+    v=Math.max(v,Straightness(p[4],p[5],p[6],p[7]));
+    v=Math.max(v,Straightness(p[8],p[9],p[10],p[11]));
+    v=Math.max(v,Straightness(p12,p[13],p[14],p15));
+
+    return [h,v];
   }
 
   // Check the flatness of a Bezier triangle
@@ -1275,41 +1563,45 @@
     return Math.max(d,Straightness(p6,p[7],p[8],p9));
   }
 
-  derivative(p0,p1,p2,p3) {
-    let lp=[p1[0]-p0[0],p1[1]-p0[1],p1[2]-p0[2]];
-    if(abs2(lp) > this.epsilon)
-      return lp;
+  // Return the differential of the Bezier curve p0,p1,p2,p3 at 0.
+  differential(p0,p1,p2,p3) {
+    let p=[3*(p1[0]-p0[0]),3*(p1[1]-p0[1]),3*(p1[2]-p0[2])];
+    if(abs2(p) > this.epsilon)
+      return p;
     
-    let lpp=bezierPP(p0,p1,p2);
-    if(abs2(lpp) > this.epsilon)
-      return lpp;
+    p=bezierPP(p0,p1,p2);
+    if(abs2(p) > this.epsilon)
+      return p;
     
     return bezierPPP(p0,p1,p2,p3);
   }
 
-  sumderivative(p0,p1,p2,p3,p4,p5,p6) {
-    let d0=this.derivative(p0,p1,p2,p3);
-    let d1=this.derivative(p0,p4,p5,p6);
+  sumdifferential(p0,p1,p2,p3,p4,p5,p6) {
+    let d0=this.differential(p0,p1,p2,p3);
+    let d1=this.differential(p0,p4,p5,p6);
     return [d0[0]+d1[0],d0[1]+d1[1],d0[2]+d1[2]];
   }
   
   normal(left3,left2,left1,middle,right1,right2,right3) {
-    let ux=right1[0]-middle[0];
-    let uy=right1[1]-middle[1];
-    let uz=right1[2]-middle[2];
-    let vx=left1[0]-middle[0];
-    let vy=left1[1]-middle[1];
-    let vz=left1[2]-middle[2];
+    let ux=3*(right1[0]-middle[0]);
+    let uy=3*(right1[1]-middle[1]);
+    let uz=3*(right1[2]-middle[2]);
+    let vx=3*(left1[0]-middle[0]);
+    let vy=3*(left1[1]-middle[1]);
+    let vz=3*(left1[2]-middle[2]);
+
     let n=[uy*vz-uz*vy,
            uz*vx-ux*vz,
            ux*vy-uy*vx];
     if(abs2(n) > this.epsilon)
-      return unit(n);
+      return n;
 
     let lp=[vx,vy,vz];
     let rp=[ux,uy,uz];
+
     let lpp=bezierPP(middle,left1,left2);
     let rpp=bezierPP(middle,right1,right2);
+
     let a=cross(rpp,lp);
     let b=cross(rp,lpp);
     n=[a[0]+b[0],
@@ -1316,19 +1608,31 @@
        a[1]+b[1],
        a[2]+b[2]];
     if(abs2(n) > this.epsilon)
-      return unit(n);
+      return n;
 
     let lppp=bezierPPP(middle,left1,left2,left3);
     let rppp=bezierPPP(middle,right1,right2,right3);
-    a=cross(rpp,lpp);
-    b=cross(rp,lppp);
-    let c=cross(rppp,lp);
-    let d=cross(rppp,lpp);
-    let e=cross(rpp,lppp);
-    let f=cross(rppp,lppp);
-    return unit([9*a[0]+3*(b[0]+c[0]+d[0]+e[0])+f[0],
-                 9*a[1]+3*(b[1]+c[1]+d[1]+e[1])+f[1],
-                 9*a[2]+3*(b[2]+c[2]+d[2]+e[2])+f[2]]);
+
+    a=cross(rp,lppp);
+    b=cross(rppp,lp);
+    let c=cross(rpp,lpp);
+
+    n=[a[0]+b[0]+c[0],
+       a[1]+b[1]+c[1],
+       a[2]+b[2]+c[2]];
+    if(abs2(n) > this.epsilon)
+      return n;
+
+    a=cross(rppp,lpp);
+    b=cross(rpp,lppp);
+
+    n=[a[0]+b[0],
+       a[1]+b[1],
+       a[2]+b[2]];
+    if(abs2(n) > this.epsilon)
+      return n;
+
+    return cross(rppp,lppp);
   }
 }
 
@@ -1350,8 +1654,9 @@
     let p0=p[0];
     let p1=p[1];
     if(!this.offscreen([p0,p1])) {
-      this.data.indices.push(this.data.vertex1(p0));
-      this.data.indices.push(this.data.vertex1(p1));
+      let n=[0,0,1];
+      this.data.indices.push(this.data.vertex(p0,n));
+      this.data.indices.push(this.data.vertex(p1,n));
       this.append();
     }
   }
@@ -1358,9 +1663,17 @@
 
   process(p) {
     if(p.length == 2) return this.processLine(p);
+
+    let p0=p[0];
+    let p1=p[1];
+    let p2=p[2];
+    let p3=p[3];
+
+    let n0=this.normal(bezierP(p0,p1),bezierPP(p0,p1,p2));
+    let n1=this.normal(bezierP(p2,p3),bezierPP(p3,p2,p1));
     
-    let i0=this.data.vertex1(p[0]);
-    let i3=this.data.vertex1(p[3]);
+    let i0=this.data.vertex(p0,n0);
+    let i3=this.data.vertex(p3,n1);
     
     this.Render(p,i0,i3);
     if(this.data.indices.length > 0) this.append();
@@ -1394,12 +1707,21 @@
       let s0=[p0,m0,m3,m5];
       let s1=[m5,m4,m2,p3];
       
-      let i0=this.data.vertex1(m5);
+      let n0=this.normal(bezierPh(p0,p1,p2,p3),bezierPPh(p0,p1,p2,p3));
+      let i0=this.data.vertex(m5,n0);
       
       this.Render(s0,I0,i0);
       this.Render(s1,i0,I1);
     }
   }
+
+  normal(bP,bPP) {
+    let bPbP=dot(bP,bP);
+    let bPbPP=dot(bP,bPP);
+    return [bPbP*bPP[0]-bPbPP*bP[0],
+            bPbP*bPP[1]-bPbPP*bP[1],
+            bPbP*bPP[2]-bPbPP*bP[2]];
+  }
 }
 
 class Pixel extends Geometry {
@@ -1454,7 +1776,8 @@
 
   process(p) {
     // Override materialIndex to encode color vs material
-    materialIndex=this.Colors.length > 0 ? -1-materialIndex : 1+materialIndex;
+      materialIndex=this.Colors.length > 0 ?
+      -1-materialIndex : 1+materialIndex;
 
     for(let i=0, n=this.Indices.length; i < n; ++i) {
       let index=this.Indices[i];
@@ -1472,13 +1795,31 @@
           let C1=this.Colors[CI[1]];
           let C2=this.Colors[CI[2]];
           this.transparent |= C0[3]+C1[3]+C2[3] < 765;
-          this.data.iVertex(PI[0],P0,this.Normals[NI[0]],C0);
-          this.data.iVertex(PI[1],P1,this.Normals[NI[1]],C1);
-          this.data.iVertex(PI[2],P2,this.Normals[NI[2]],C2);
+          if(wireframe == 0) {
+            this.data.iVertex(PI[0],P0,this.Normals[NI[0]],C0);
+            this.data.iVertex(PI[1],P1,this.Normals[NI[1]],C1);
+            this.data.iVertex(PI[2],P2,this.Normals[NI[2]],C2);
+          } else {
+            this.data.iVertex(PI[0],P0,this.Normals[NI[0]],C0);
+            this.data.iVertex(PI[1],P1,this.Normals[NI[1]],C1);
+            this.data.iVertex(PI[1],P1,this.Normals[NI[1]],C1);
+            this.data.iVertex(PI[2],P2,this.Normals[NI[2]],C2);
+            this.data.iVertex(PI[2],P2,this.Normals[NI[2]],C2);
+            this.data.iVertex(PI[0],P0,this.Normals[NI[0]],C0);
+          }
         } else {
-          this.data.iVertex(PI[0],P0,this.Normals[NI[0]]);
-          this.data.iVertex(PI[1],P1,this.Normals[NI[1]]);
-          this.data.iVertex(PI[2],P2,this.Normals[NI[2]]);
+          if(wireframe == 0) {
+            this.data.iVertex(PI[0],P0,this.Normals[NI[0]]);
+            this.data.iVertex(PI[1],P1,this.Normals[NI[1]]);
+            this.data.iVertex(PI[2],P2,this.Normals[NI[2]]);
+          } else {
+            this.data.iVertex(PI[0],P0,this.Normals[NI[0]]);
+            this.data.iVertex(PI[1],P1,this.Normals[NI[1]]);
+            this.data.iVertex(PI[1],P1,this.Normals[NI[1]]);
+            this.data.iVertex(PI[2],P2,this.Normals[NI[2]]);
+            this.data.iVertex(PI[2],P2,this.Normals[NI[2]]);
+            this.data.iVertex(PI[0],P0,this.Normals[NI[0]]);
+          }
         }
       }
     }
@@ -1546,11 +1887,6 @@
   }
 }
 
-function iszero(v)
-{
-  return v[0] == 0 && v[1] == 0 && v[2] == 0;
-}
-
 function unit(v)
 {
   let norm=1/(Math.sqrt(v[0]*v[0]+v[1]*v[1]+v[2]*v[2]) || 1);
@@ -1574,17 +1910,26 @@
           u[0]*v[1]-u[1]*v[0]];
 }
 
-// Return one-sixth of the second derivative of the Bezier curve defined
-// by a,b,c,d at 0. 
+// Return one-third of the first derivative of the Bezier curve defined
+// by a,b,c,d at t=0.
+function bezierP(a,b)
+{
+  return [b[0]-a[0],
+          b[1]-a[1],
+          b[2]-a[2]];
+}
+
+// Return one-half of the second derivative of the Bezier curve defined
+// by a,b,c,d at t=0.
 function bezierPP(a,b,c)
 {
-  return [a[0]+c[0]-2*b[0],
-          a[1]+c[1]-2*b[1],
-          a[2]+c[2]-2*b[2]];
+  return [3*(a[0]+c[0])-6*b[0],
+          3*(a[1]+c[1])-6*b[1],
+          3*(a[2]+c[2])-6*b[2]];
 }
 
-// Return one-third of the third derivative of the Bezier curve defined by
-// a,b,c,d at 0.
+// Return one-sixth of the third derivative of the Bezier curve defined by
+// a,b,c,d at t=0.
 function bezierPPP(a,b,c,d)
 {
   return [d[0]-a[0]+3*(b[0]-c[0]),
@@ -1592,6 +1937,24 @@
           d[2]-a[2]+3*(b[2]-c[2])];
 }
 
+// Return four-thirds of the first derivative of the Bezier curve defined by
+// a,b,c,d at t=1/2.
+function bezierPh(a,b,c,d)
+{
+  return [c[0]+d[0]-a[0]-b[0],
+          c[1]+d[1]-a[1]-b[1],
+          c[2]+d[2]-a[2]-b[2]];
+}
+
+// Return two-thirds of the second derivative of the Bezier curve defined by
+// a,b,c,d at t=1/2.
+function bezierPPh(a,b,c,d)
+{
+  return [3*a[0]-5*b[0]+c[0]+d[0],
+          3*a[1]-5*b[1]+c[1]+d[1],
+          3*a[2]-5*b[2]+c[2]+d[2]];
+}
+
 /**
  * Return the maximum distance squared of points c0 and c1 from 
  * the respective internal control points of z0--z1.
@@ -1603,14 +1966,12 @@
     abs2([z1[0]-v[0]-c1[0],z1[1]-v[1]-c1[1],z1[2]-v[2]-c1[2]]));
 }
 
-/**
- * Return the perpendicular distance squared of a point z from the plane
- * through u with unit normal n.
- */
-function Distance2(z,u,n)
+// Return one ninth of the relative flatness squared of a--b and c--d.
+function Flatness(a,b,c,d)
 {
-  let d=dot([z[0]-u[0],z[1]-u[1],z[2]-u[2]],n);
-  return d*d;
+  let u=[b[0]-a[0],b[1]-a[1],b[2]-a[2]];
+  let v=[d[0]-c[0],d[1]-c[1],d[2]-c[2]];
+  return Math.max(abs2(cross(u,unit(v))),abs2(cross(v,unit(u))))/9;
 }
 
 // Return the vertices of the box containing 3d points m and M.
@@ -1620,6 +1981,22 @@
           [M[0],m[1],m[2]],[M[0],m[1],M[2]],[M[0],M[1],m[2]],M];
 }
 
+function minbound(v) {
+  return [
+    Math.min(v[0][0],v[1][0],v[2][0],v[3][0],v[4][0],v[5][0],v[6][0],v[7][0]),
+    Math.min(v[0][1],v[1][1],v[2][1],v[3][1],v[4][1],v[5][1],v[6][1],v[7][1]),
+    Math.min(v[0][2],v[1][2],v[2][2],v[3][2],v[4][2],v[5][2],v[6][2],v[7][2])
+  ];
+}
+
+function maxbound(v) {
+  return [
+    Math.max(v[0][0],v[1][0],v[2][0],v[3][0],v[4][0],v[5][0],v[6][0],v[7][0]),
+    Math.max(v[0][1],v[1][1],v[2][1],v[3][1],v[4][1],v[5][1],v[6][1],v[7][1]),
+    Math.max(v[0][2],v[1][2],v[2][2],v[3][2],v[4][2],v[5][2],v[6][2],v[7][2])
+  ];
+}
+
 /**
  * Perform a change of basis
  * @param {*} out Out Matrix
@@ -1630,10 +2007,10 @@
 
 function COBTarget(out,mat)
 {
-  mat4.fromTranslation(translMat,[center.x,center.y,center.z])
-  mat4.invert(cjMatInv,translMat);
+  mat4.fromTranslation(T,[center.x,center.y,center.z])
+  mat4.invert(cjMatInv,T);
   mat4.multiply(out,mat,cjMatInv);
-  mat4.multiply(out,translMat,out);
+  mat4.multiply(out,T,out);
 }
 
 function setUniforms(data,shader)
@@ -1647,7 +2024,7 @@
   if(pixel)
     gl.enableVertexAttribArray(widthAttribute);
 
-  let normals=shader != noNormalShader && !pixel && Lights.length > 0;
+  let normals=!pixel && Lights.length > 0;
   if(normals)
     gl.enableVertexAttribArray(normalAttribute);
 
@@ -1728,8 +2105,8 @@
   if(lastX == rawX && lastY == rawY) return;
   let [angle,axis]=arcball([lastX,-lastY],[rawX,-rawY]);
 
-  mat4.fromRotation(rotMats,2*factor*ArcballFactor*angle/lastzoom,axis);
-  mat4.multiply(rotMat,rotMats,rotMat);
+  mat4.fromRotation(T,2*factor*ArcballFactor*angle/lastzoom,axis);
+  mat4.multiply(rotMat,T,rotMat);
 }
 
 function shiftScene(lastX,lastY,rawX,rawY)
@@ -1897,6 +2274,17 @@
   case 'h':
     home();
     break;
+  case 'm':
+    ++wireframe;
+    if(wireframe == 3) wireframe=0;
+    if(wireframe != 2) {
+      if(!embedded)
+        deleteShaders();
+      initShaders();
+    }
+    remesh=true;
+    draw();
+    break;
   case '+':
   case '=':
   case '>':
@@ -2028,7 +2416,7 @@
 
 function drawMaterial1()
 {
-  drawBuffer(material1Data,noNormalShader);
+  drawBuffer(material1Data,materialShader);
   material1Data.clear();
 }
 
@@ -2053,6 +2441,11 @@
 function drawTransparent()
 {
   let indices=transparentData.indices;
+  if(wireframe > 0) {
+    drawBuffer(transparentData,transparentShader,indices);
+    transparentData.clear();
+    return;
+  }
   if(indices.length > 0) {
     transformVertices(transparentData.vertices);
     
@@ -2122,7 +2515,7 @@
     context.drawImage(offscreen,0,0);
   }
 
-  remesh=false;
+  if(wireframe == 0) remesh=false;
 }
 
 function setDimensions(width,height,X,Y)
@@ -2238,9 +2631,9 @@
           Math.max((canvasHeight/resizeStep+0.5),1));
 }
 
-let pixelShader,noNormalShader,materialShader,colorShader,transparentShader;
+let pixelShader,materialShader,colorShader,transparentShader;
 
-function webGLStart()
+function webGLInit()
 {
   canvas=document.getElementById("Asymptote");
   embedded=window.top.document != document;
@@ -2296,3 +2689,392 @@
   canvas.addEventListener("touchmove",handleTouchMove,false);
   document.addEventListener("keydown",handleKey,false);
 }
+
+let listen=false;
+
+class Align {
+  constructor(center,dir) {
+    this.center=center;
+    if(dir) {
+      let theta=dir[0];
+      let phi=dir[1];
+
+      this.ct=Math.cos(theta);
+      this.st=Math.sin(theta);
+      this.cp=Math.cos(phi);
+      this.sp=Math.sin(phi);
+    }
+  }
+
+  T0(v) {
+    return [v[0]+this.center[0],v[1]+this.center[1],v[2]+this.center[2]];
+  }
+
+  T(v) {
+    let x=v[0];
+    let Y=v[1];
+    let z=v[2];
+    let X=x*this.ct+z*this.st;
+    return [X*this.cp-Y*this.sp+this.center[0],
+            X*this.sp+Y*this.cp+this.center[1],
+            -x*this.st+z*this.ct+this.center[2]];
+  };
+}
+
+function Tcorners(T,m,M) {
+  let v=[T(m),T([m[0],m[1],M[2]]),T([m[0],M[1],m[2]]),
+         T([m[0],M[1],M[2]]),T([M[0],m[1],m[2]]),
+         T([M[0],m[1],M[2]]),T([M[0],M[1],m[2]]),T(M)];
+  return [minbound(v),maxbound(v)];
+}
+
+// draw a sphere of radius r about center
+// (or optionally a hemisphere symmetric about direction dir)
+function sphere(center,r,CenterIndex,MaterialIndex,dir)
+{
+  let octant=[[
+    [1,0,0],
+    [1,0,0.370106805057161],
+    [0.798938033457256,0,0.6932530716149],
+    [0.500083269410627,0,0.866169630634358],
+
+    [1,0.552284749830793,0],
+    [1,0.552284749830793,0.370106805057161],
+    [0.798938033457256,0.441241291938247,0.6932530716149],
+    [0.500083269410627,0.276188363341013,0.866169630634358],
+
+    [0.552284749830793,1,0],
+    [0.552284749830793,1,0.370106805057161],
+    [0.441241291938247,0.798938033457256,0.6932530716149],
+    [0.276188363341013,0.500083269410627,0.866169630634358],
+
+    [0,1,0],
+    [0,1,0.370106805057161],
+    [0,0.798938033457256,0.6932530716149],
+    [0,0.500083269410627,0.866169630634358]
+  ],[
+    [0.500083269410627,0,0.866169630634358],
+    [0.500083269410627,0.276188363341013,0.866169630634358],
+    [0.35297776917154,0,0.951284475617087],
+    [0.276188363341013,0.500083269410627,0.866169630634358],
+    [0.264153721902467,0.264153721902467,1],
+    [0.182177944773632,0,1],
+    [0,0.500083269410627,0.866169630634358],
+    [0,0.35297776917154,0.951284475617087],
+    [0,0.182177944773632,1],
+    [0,0,1]
+  ]];
+
+  let rx,ry,rz;
+  let A=new Align(center,dir);
+  let s,t,z;
+
+  if(dir) {
+    s=1;
+    z=0;
+    t=A.T.bind(A);
+  } else {
+    s=-1;
+    z=-r;
+    t=A.T0.bind(A);
+  }
+
+  function T(V) {
+    let p=Array(V.length);
+    for(let i=0; i < V.length; ++i) {
+      let v=V[i];
+      p[i]=t([rx*v[0],ry*v[1],rz*v[2]]);
+    }
+    return p;
+  }
+
+  let v=Tcorners(t,[-r,-r,z],[r,r,r]);
+  let Min=v[0], Max=v[1];
+  for(let i=-1; i <= 1; i += 2) {
+    rx=i*r;
+    for(let j=-1; j <= 1; j += 2) {
+      ry=j*r;
+      for(let k=s; k <= 1; k += 2) {
+        rz=k*r;
+        for(let m=0; m < 2; ++m)
+          P.push(new BezierPatch(T(octant[m]),CenterIndex,MaterialIndex,
+                                 Min,Max));
+      }
+    }
+  }
+}
+
+let a=4/3*(Math.sqrt(2)-1);
+
+// draw a disk of radius r aligned in direction dir
+function disk(center,r,CenterIndex,MaterialIndex,dir)
+{
+  let b=1-2*a/3;
+
+  let unitdisk=[
+    [1,0,0],
+    [1,-a,0],
+    [a,-1,0],
+    [0,-1,0],
+
+    [1,a,0],
+    [b,0,0],
+    [0,-b,0],
+    [-a,-1,0],
+
+    [a,1,0],
+    [0,b,0],
+    [-b,0,0],
+    [-1,-a,0],
+
+    [0,1,0],
+    [-a,1,0],
+    [-1,a,0],
+    [-1,0,0]
+  ];
+
+  let A=new Align(center,dir);
+
+  function T(V) {
+    let p=Array(V.length);
+    for(let i=0; i < V.length; ++i) {
+      let v=V[i];
+      p[i]=A.T([r*v[0],r*v[1],0]);
+    }
+    return p;
+  }
+
+  let v=Tcorners(A.T.bind(A),[-r,-r,0],[r,r,0]);
+  P.push(new BezierPatch(T(unitdisk),CenterIndex,MaterialIndex,v[0],v[1]));
+}
+
+// draw a cylinder with circular base of radius r about center and height h
+// aligned in direction dir
+function cylinder(center,r,h,CenterIndex,MaterialIndex,dir,core)
+{
+  let unitcylinder=[
+    [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]
+  ];
+
+  let rx,ry,rz;
+  let A=new Align(center,dir);
+
+  function T(V) {
+    let p=Array(V.length);
+    for(let i=0; i < V.length; ++i) {
+      let v=V[i];
+      p[i]=A.T([rx*v[0],ry*v[1],h*v[2]]);
+    }
+    return p;
+  }
+
+  let v=Tcorners(A.T.bind(A),[-r,-r,0],[r,r,h]);
+  let Min=v[0], Max=v[1];
+
+  for(let i=-1; i <= 1; i += 2) {
+    rx=i*r;
+    for(let j=-1; j <= 1; j += 2) {
+      ry=j*r;
+      P.push(new BezierPatch(T(unitcylinder),CenterIndex,MaterialIndex,
+                             Min,Max));
+    }
+  }
+
+  if(core) {
+    let Center=A.T([0,0,h]);
+    P.push(new BezierCurve([center,Center],CenterIndex,MaterialIndex,
+                           center,Center));
+  }
+}
+
+function rmf(z0,c0,c1,z1,t)
+{
+  class Rmf {
+    constructor(p,r,t) {
+      this.p=p;
+      this.r=r;
+      this.t=t;
+      this.s=cross(t,r);
+    }
+  }
+
+  // Return a unit vector perpendicular to a given unit vector v.
+  function perp(v)
+  {
+    let u=cross(v,[0,1,0]);
+    let norm=Number.EPSILON*abs2(v);
+    if(abs2(u) > norm) return unit(u);
+    u=cross(v,[0,0,1]);
+    return (abs2(u) > norm) ? unit(u) : [1,0,0];
+  }
+
+  let norm=Number.EPSILON*Math.max(abs2(z0),abs2(c0),abs2(c1),
+                                abs2(z1));
+
+// Special case of dir for t in (0,1].
+  function dir(t) {
+    if(t == 1) {
+      let dir=[z1[0]-c1[0],
+               z1[1]-c1[1],
+               z1[2]-c1[2]];
+      if(abs2(dir) > norm) return unit(dir);
+      dir=[2*c1[0]-c0[0]-z1[0],
+           2*c1[1]-c0[1]-z1[1],
+           2*c1[2]-c0[2]-z1[2]];
+      if(abs2(dir) > norm) return unit(dir);
+      return [z1[0]-z0[0]+3*(c0[0]-c1[0]),
+              z1[1]-z0[1]+3*(c0[1]-c1[1]),
+              z1[2]-z0[2]+3*(c0[2]-c1[2])];
+    }
+    let a=[z1[0]-z0[0]+3*(c0[0]-c1[0]),
+           z1[1]-z0[1]+3*(c0[1]-c1[1]),
+           z1[2]-z0[2]+3*(c0[2]-c1[2])];
+    let b=[2*(z0[0]+c1[0])-4*c0[0],
+           2*(z0[1]+c1[1])-4*c0[1],
+           2*(z0[2]+c1[2])-4*c0[2]];
+    let c=[c0[0]-z0[0],c0[1]-z0[1],c0[2]-z0[2]];
+    let t2=t*t;
+    let dir=[a[0]*t2+b[0]*t+c[0],
+             a[1]*t2+b[1]*t+c[1],
+             a[2]*t2+b[2]*t+c[2]];
+    if(abs2(dir) > norm) return unit(dir);
+    t2=2*t;
+    dir=[a[0]*t2+b[0],
+         a[1]*t2+b[1],
+         a[2]*t2+b[2]];
+    if(abs2(dir) > norm) return unit(dir);
+    return unit(a);
+  }
+
+  let R=Array(t.length);
+  let T=[c0[0]-z0[0],
+         c0[1]-z0[1],
+         c0[2]-z0[2]];
+  if(abs2(T) < norm) {
+    T=[z0[0]-2*c0[0]+c1[0],
+       z0[1]-2*c0[1]+c1[1],
+       z0[2]-2*c0[2]+c1[2]];
+    if(abs2(T) < norm)
+      T=[z1[0]-z0[0]+3*(c0[0]-c1[0]),
+         z1[1]-z0[1]+3*(c0[1]-c1[1]),
+         z1[2]-z0[2]+3*(c0[2]-c1[2])];
+  }
+  T=unit(T);
+  let Tp=perp(T);
+  R[0]=new Rmf(z0,Tp,T);
+  for(let i=1; i < t.length; ++i) {
+    let Ri=R[i-1];
+    let s=t[i];
+    let onemt=1-s;
+    let onemt2=onemt*onemt;
+    let onemt3=onemt2*onemt;
+    let s3=3*s;
+    onemt2 *= s3;
+    onemt *= s3*s;
+    let t3=s*s*s;
+    let p=[
+      onemt3*z0[0]+onemt2*c0[0]+onemt*c1[0]+t3*z1[0],
+      onemt3*z0[1]+onemt2*c0[1]+onemt*c1[1]+t3*z1[1],
+      onemt3*z0[2]+onemt2*c0[2]+onemt*c1[2]+t3*z1[2]];
+    let v1=[p[0]-Ri.p[0],p[1]-Ri.p[1],p[2]-Ri.p[2]];
+    if(v1[0] != 0 || v1[1] != 0 || v1[2] != 0) {
+      let r=Ri.r;
+      let u1=unit(v1);
+      let ti=Ri.t;
+      let dotu1ti=dot(u1,ti)
+      let tp=[ti[0]-2*dotu1ti*u1[0],
+              ti[1]-2*dotu1ti*u1[1],
+              ti[2]-2*dotu1ti*u1[2]];
+      ti=dir(s);
+      let dotu1r2=2*dot(u1,r);
+      let rp=[r[0]-dotu1r2*u1[0],r[1]-dotu1r2*u1[1],r[2]-dotu1r2*u1[2]];
+      let u2=unit([ti[0]-tp[0],ti[1]-tp[1],ti[2]-tp[2]]);
+      let dotu2rp2=2*dot(u2,rp);
+      rp=[rp[0]-dotu2rp2*u2[0],rp[1]-dotu2rp2*u2[1],rp[2]-dotu2rp2*u2[2]];
+      R[i]=new Rmf(p,unit(rp),unit(ti));
+    } else
+      R[i]=R[i-1];
+  }
+  return R;
+}
+
+// draw a tube of width w using control points v
+function tube(v,w,CenterIndex,MaterialIndex,Min,Max,core)
+{
+  let Rmf=rmf(v[0],v[1],v[2],v[3],[0,1/3,2/3,1]);
+
+  let aw=a*w;
+  let arc=[[w,0],[w,aw],[aw,w],[0,w]];
+
+  function f(a,b,c,d) {
+    let s=Array(16);
+    for(let i=0; i < 4; ++i) {
+      let R=Rmf[i];
+
+      let R0=R.r[0], R1=R.s[0];
+      let T0=R0*a+R1*b;
+      let T1=R0*c+R1*d;
+
+      R0=R.r[1]; R1=R.s[1];
+      let T4=R0*a+R1*b;
+      let T5=R0*c+R1*d;
+
+      R0=R.r[2]; R1=R.s[2];
+      let T8=R0*a+R1*b;
+      let T9=R0*c+R1*d;
+
+      let w=v[i];
+      let w0=w[0]; w1=w[1]; w2=w[2];
+      for(let j=0; j < 4; ++j) {
+        let u=arc[j];
+        let x=u[0], y=u[1];
+        s[4*i+j]=[T0*x+T1*y+w0,
+                  T4*x+T5*y+w1,
+                  T8*x+T9*y+w2];
+      }
+    }
+    P.push(new BezierPatch(s,CenterIndex,MaterialIndex,Min,Max));
+  }
+
+  f(1,0,0,1);
+  f(0,-1,1,0);
+  f(-1,0,0,-1);
+  f(0,1,-1,0);
+
+  if(core)
+    P.push(new BezierCurve(v,CenterIndex,MaterialIndex,Min,Max));
+}
+
+function webGLStart()
+{
+  if(window.innerWidth == 0 || window.innerHeight == 0) {
+    if(!listen) {
+      listen=true;
+      window.addEventListener("resize",webGLStart,false);
+    }
+  } else {
+    if(listen) {
+      window.removeEventListener("resize",webGLStart,false);
+      listen=false;
+    }
+    webGLInit();
+  }
+}

Modified: trunk/Build/source/utils/asymptote/webgl/vertex.glsl
===================================================================
--- trunk/Build/source/utils/asymptote/webgl/vertex.glsl	2020-03-03 22:33:26 UTC (rev 54033)
+++ trunk/Build/source/utils/asymptote/webgl/vertex.glsl	2020-03-03 22:35:09 UTC (rev 54034)
@@ -40,34 +40,30 @@
 #ifndef ORTHOGRAPHIC
   ViewPosition=(viewMat*v).xyz;
 #endif      
-  Normal=normal*normMat;
+  Normal=normalize(normal*normMat);
         
   Material m;
 #ifdef TRANSPARENT
   m=Materials[int(abs(materialIndex))-1];
+  emissive=m.emissive;
   if(materialIndex >= 0.0) {
     diffuse=m.diffuse;
-    emissive=m.emissive;
   } else {
     diffuse=color;
-#if nlights > 0
-    emissive=vec4(0.0);
-#else
-    emissive=color;
+#if nlights == 0
+    emissive += color;
 #endif
   }
 #else
   m=Materials[int(materialIndex)];
+  emissive=m.emissive;
 #ifdef COLOR
   diffuse=color;
-#if nlights > 0
-  emissive=vec4(0.0);
-#else
-  emissive=color;
+#if nlights == 0
+    emissive += color;
 #endif
 #else
   diffuse=m.diffuse;
-  emissive=m.emissive;
 #endif
 #endif
   specular=m.specular.rgb;



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