summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKarl Berry <karl@freefriends.org>2009-05-16 00:19:13 +0000
committerKarl Berry <karl@freefriends.org>2009-05-16 00:19:13 +0000
commitbab45528d65eaafe68a705dbb2a57075c7b7cbd8 (patch)
tree10b4ae2b5195c8dede153ab89359ec00f55f325f
parent8643d90372e9c31e0f461c15c596b60a545bd7d3 (diff)
asymptote 1.72 sources (not integrated into build yet)
git-svn-id: svn://tug.org/texlive/trunk@13110 c570f23f-e606-0410-a88d-b1316a301751
-rw-r--r--Build/source/utils/README3
-rw-r--r--Build/source/utils/asymptote/.cvsignore17
-rw-r--r--Build/source/utils/asymptote/BUGS5
-rw-r--r--Build/source/utils/asymptote/ChangeLog40409
-rw-r--r--Build/source/utils/asymptote/Compile10
-rw-r--r--Build/source/utils/asymptote/Delaunay.cc212
-rw-r--r--Build/source/utils/asymptote/Delaunay.h29
-rwxr-xr-xBuild/source/utils/asymptote/GUI/CubicBezier.py101
-rwxr-xr-xBuild/source/utils/asymptote/GUI/UndoRedoStack.py117
-rwxr-xr-xBuild/source/utils/asymptote/GUI/xasy.py35
-rwxr-xr-xBuild/source/utils/asymptote/GUI/xasy2asy.py785
-rwxr-xr-xBuild/source/utils/asymptote/GUI/xasyActions.py387
-rwxr-xr-xBuild/source/utils/asymptote/GUI/xasyBezierEditor.py208
-rwxr-xr-xBuild/source/utils/asymptote/GUI/xasyCodeEditor.py37
-rwxr-xr-xBuild/source/utils/asymptote/GUI/xasyColorPicker.py248
-rw-r--r--Build/source/utils/asymptote/GUI/xasyExample.asy63
-rwxr-xr-xBuild/source/utils/asymptote/GUI/xasyFile.py315
-rwxr-xr-xBuild/source/utils/asymptote/GUI/xasyGUIIcons.py92
-rwxr-xr-xBuild/source/utils/asymptote/GUI/xasyMainWin.py1742
-rwxr-xr-xBuild/source/utils/asymptote/GUI/xasyOptions.py126
-rwxr-xr-xBuild/source/utils/asymptote/GUI/xasyOptionsDialog.py245
-rw-r--r--Build/source/utils/asymptote/INSTALL275
-rw-r--r--Build/source/utils/asymptote/LICENSE674
-rw-r--r--Build/source/utils/asymptote/LICENSE.LESSER165
-rw-r--r--Build/source/utils/asymptote/Makefile.in258
-rw-r--r--Build/source/utils/asymptote/README41
-rw-r--r--Build/source/utils/asymptote/ReleaseNotes1350
-rw-r--r--Build/source/utils/asymptote/TODO22
-rw-r--r--Build/source/utils/asymptote/absyn.cc30
-rw-r--r--Build/source/utils/asymptote/absyn.h65
-rw-r--r--Build/source/utils/asymptote/access.cc133
-rw-r--r--Build/source/utils/asymptote/access.h119
-rw-r--r--Build/source/utils/asymptote/algebra3.cc1608
-rw-r--r--Build/source/utils/asymptote/algebra3.h484
-rw-r--r--Build/source/utils/asymptote/angle.h41
-rw-r--r--Build/source/utils/asymptote/application.cc371
-rw-r--r--Build/source/utils/asymptote/application.h285
-rw-r--r--Build/source/utils/asymptote/arcball.cc237
-rw-r--r--Build/source/utils/asymptote/arcball.h95
-rw-r--r--Build/source/utils/asymptote/array.cc191
-rw-r--r--Build/source/utils/asymptote/array.h112
-rw-r--r--Build/source/utils/asymptote/arrayop.h410
-rw-r--r--Build/source/utils/asymptote/asy-keywords.el17
-rwxr-xr-xBuild/source/utils/asymptote/asy-list.pl106
-rw-r--r--Build/source/utils/asymptote/asy.icobin0 -> 4286 bytes
-rw-r--r--Build/source/utils/asymptote/asy.rc26
-rw-r--r--Build/source/utils/asymptote/asymptote.nsi180
-rw-r--r--Build/source/utils/asymptote/asymptote.spec106
-rwxr-xr-xBuild/source/utils/asymptote/autogen.sh3
-rw-r--r--Build/source/utils/asymptote/base/CAD.asy367
-rw-r--r--Build/source/utils/asymptote/base/animate.asy3
-rw-r--r--Build/source/utils/asymptote/base/animation.asy179
-rw-r--r--Build/source/utils/asymptote/base/annotate.asy16
-rw-r--r--Build/source/utils/asymptote/base/asy-init.el4
l---------Build/source/utils/asymptote/base/asy-keywords.el1
-rw-r--r--Build/source/utils/asymptote/base/asy-mode.el1545
-rw-r--r--Build/source/utils/asymptote/base/asy.vim202
-rwxr-xr-xBuild/source/utils/asymptote/base/asymptote.py48
-rw-r--r--Build/source/utils/asymptote/base/babel.asy4
-rw-r--r--Build/source/utils/asymptote/base/bezulate.asy258
-rw-r--r--Build/source/utils/asymptote/base/binarytree.asy326
-rw-r--r--Build/source/utils/asymptote/base/bsp.asy207
-rw-r--r--Build/source/utils/asymptote/base/contour.asy682
-rw-r--r--Build/source/utils/asymptote/base/contour3.asy481
-rw-r--r--Build/source/utils/asymptote/base/drawtree.asy101
-rw-r--r--Build/source/utils/asymptote/base/embed.asy34
-rw-r--r--Build/source/utils/asymptote/base/external.asy36
-rw-r--r--Build/source/utils/asymptote/base/feynman.asy622
-rw-r--r--Build/source/utils/asymptote/base/flowchart.asy356
-rw-r--r--Build/source/utils/asymptote/base/fontsize.asy1
-rw-r--r--Build/source/utils/asymptote/base/geometry.asy7150
-rw-r--r--Build/source/utils/asymptote/base/graph.asy2203
-rw-r--r--Build/source/utils/asymptote/base/graph3.asy1926
-rw-r--r--Build/source/utils/asymptote/base/graph_settings.asy18
-rw-r--r--Build/source/utils/asymptote/base/grid3.asy399
-rw-r--r--Build/source/utils/asymptote/base/interpolate.asy140
-rw-r--r--Build/source/utils/asymptote/base/labelpath.asy28
-rw-r--r--Build/source/utils/asymptote/base/labelpath3.asy86
-rw-r--r--Build/source/utils/asymptote/base/latin1.asy2
-rw-r--r--Build/source/utils/asymptote/base/markers.asy217
-rw-r--r--Build/source/utils/asymptote/base/math.asy392
-rw-r--r--Build/source/utils/asymptote/base/metapost.asy19
-rw-r--r--Build/source/utils/asymptote/base/nopapersize.ps3
-rw-r--r--Build/source/utils/asymptote/base/obj.asy104
-rw-r--r--Build/source/utils/asymptote/base/ode.asy15
-rw-r--r--Build/source/utils/asymptote/base/palette.asy473
-rw-r--r--Build/source/utils/asymptote/base/patterns.asy102
-rw-r--r--Build/source/utils/asymptote/base/plain.asy270
-rw-r--r--Build/source/utils/asymptote/base/plain_Label.asy601
-rw-r--r--Build/source/utils/asymptote/base/plain_arcs.asy43
-rw-r--r--Build/source/utils/asymptote/base/plain_arrows.asy569
-rw-r--r--Build/source/utils/asymptote/base/plain_boxes.asy136
-rw-r--r--Build/source/utils/asymptote/base/plain_constants.asy157
-rw-r--r--Build/source/utils/asymptote/base/plain_debugger.asy86
-rw-r--r--Build/source/utils/asymptote/base/plain_filldraw.asy234
-rw-r--r--Build/source/utils/asymptote/base/plain_margins.asy99
-rw-r--r--Build/source/utils/asymptote/base/plain_markers.asy377
-rw-r--r--Build/source/utils/asymptote/base/plain_paths.asy380
-rw-r--r--Build/source/utils/asymptote/base/plain_pens.asy341
-rw-r--r--Build/source/utils/asymptote/base/plain_picture.asy1892
-rw-r--r--Build/source/utils/asymptote/base/plain_shipout.asy113
-rw-r--r--Build/source/utils/asymptote/base/plain_strings.asy183
-rw-r--r--Build/source/utils/asymptote/base/plain_xasy.asy128
-rw-r--r--Build/source/utils/asymptote/base/pstoedit.asy18
-rw-r--r--Build/source/utils/asymptote/base/reload.js23
-rw-r--r--Build/source/utils/asymptote/base/roundedpath.asy84
-rw-r--r--Build/source/utils/asymptote/base/simplex.asy272
-rw-r--r--Build/source/utils/asymptote/base/size10.asy12
-rw-r--r--Build/source/utils/asymptote/base/size11.asy12
-rw-r--r--Build/source/utils/asymptote/base/slide.asy574
-rw-r--r--Build/source/utils/asymptote/base/slopefield.asy87
-rw-r--r--Build/source/utils/asymptote/base/solids.asy395
-rw-r--r--Build/source/utils/asymptote/base/splinetype.asy238
-rw-r--r--Build/source/utils/asymptote/base/stats.asy292
-rw-r--r--Build/source/utils/asymptote/base/syzygy.asy936
-rw-r--r--Build/source/utils/asymptote/base/texcolors.asy68
-rw-r--r--Build/source/utils/asymptote/base/three.asy2614
-rw-r--r--Build/source/utils/asymptote/base/three_arrows.asy789
-rw-r--r--Build/source/utils/asymptote/base/three_light.asy167
-rw-r--r--Build/source/utils/asymptote/base/three_margins.asy104
-rw-r--r--Build/source/utils/asymptote/base/three_surface.asy1343
-rw-r--r--Build/source/utils/asymptote/base/tree.asy86
-rw-r--r--Build/source/utils/asymptote/base/trembling.asy369
-rw-r--r--Build/source/utils/asymptote/base/tube.asy210
-rw-r--r--Build/source/utils/asymptote/base/unicode.asy2
-rw-r--r--Build/source/utils/asymptote/base/version.asy1
-rw-r--r--Build/source/utils/asymptote/base/x11colors.asy145
-rw-r--r--Build/source/utils/asymptote/bbox.h229
-rw-r--r--Build/source/utils/asymptote/bbox3.h153
-rw-r--r--Build/source/utils/asymptote/builtin.cc1411
-rw-r--r--Build/source/utils/asymptote/builtin.h52
-rw-r--r--Build/source/utils/asymptote/callable.cc52
-rw-r--r--Build/source/utils/asymptote/callable.h74
-rw-r--r--Build/source/utils/asymptote/camp.l406
-rw-r--r--Build/source/utils/asymptote/camp.tab.cc3516
-rw-r--r--Build/source/utils/asymptote/camp.tab.h228
-rw-r--r--Build/source/utils/asymptote/camp.y642
-rw-r--r--Build/source/utils/asymptote/camperror.cc66
-rw-r--r--Build/source/utils/asymptote/camperror.h34
-rw-r--r--Build/source/utils/asymptote/castop.h179
-rw-r--r--Build/source/utils/asymptote/coder.cc278
-rw-r--r--Build/source/utils/asymptote/coder.h382
-rw-r--r--Build/source/utils/asymptote/coenv.cc47
-rw-r--r--Build/source/utils/asymptote/coenv.h40
-rw-r--r--Build/source/utils/asymptote/common.h57
-rw-r--r--Build/source/utils/asymptote/config.h.in221
-rwxr-xr-xBuild/source/utils/asymptote/configure12186
-rw-r--r--Build/source/utils/asymptote/configure.ac297
-rw-r--r--Build/source/utils/asymptote/constructor.cc140
-rw-r--r--Build/source/utils/asymptote/dec.cc827
-rw-r--r--Build/source/utils/asymptote/dec.h633
-rw-r--r--Build/source/utils/asymptote/doc/.cvsignore18
-rw-r--r--Build/source/utils/asymptote/doc/Bode.asy27
-rw-r--r--Build/source/utils/asymptote/doc/CAD.tex256
-rw-r--r--Build/source/utils/asymptote/doc/CAD1.asy43
-rw-r--r--Build/source/utils/asymptote/doc/CDlabel.asy14
-rw-r--r--Build/source/utils/asymptote/doc/FAQ/Makefile42
-rw-r--r--Build/source/utils/asymptote/doc/FAQ/asy-faq.bfnn1285
-rwxr-xr-xBuild/source/utils/asymptote/doc/FAQ/bfnnconv.pl298
l---------Build/source/utils/asymptote/doc/FAQ/install-sh1
-rw-r--r--Build/source/utils/asymptote/doc/FAQ/m-ascii.pl189
-rw-r--r--Build/source/utils/asymptote/doc/FAQ/m-html.pl341
-rw-r--r--Build/source/utils/asymptote/doc/FAQ/m-info.pl226
-rw-r--r--Build/source/utils/asymptote/doc/FAQ/m-lout.pl242
-rw-r--r--Build/source/utils/asymptote/doc/FAQ/m-post.pl189
-rw-r--r--Build/source/utils/asymptote/doc/GaussianSurface.asy21
-rw-r--r--Build/source/utils/asymptote/doc/HermiteSpline.asy14
-rw-r--r--Build/source/utils/asymptote/doc/Hobbycontrol.asy20
-rw-r--r--Build/source/utils/asymptote/doc/Hobbydir.asy21
-rw-r--r--Build/source/utils/asymptote/doc/Makefile.in96
-rw-r--r--Build/source/utils/asymptote/doc/asy.1250
-rw-r--r--Build/source/utils/asymptote/doc/asy.1.begin32
-rw-r--r--Build/source/utils/asymptote/doc/asy.1.end10
-rw-r--r--Build/source/utils/asymptote/doc/asycolors.sty72
-rw-r--r--Build/source/utils/asymptote/doc/asymptote.sty271
-rw-r--r--Build/source/utils/asymptote/doc/asymptote.texi9131
-rw-r--r--Build/source/utils/asymptote/doc/axis3.asy12
-rw-r--r--Build/source/utils/asymptote/doc/bezier.asy1
-rw-r--r--Build/source/utils/asymptote/doc/bezier2.asy21
-rw-r--r--Build/source/utils/asymptote/doc/beziercurve.asy12
-rw-r--r--Build/source/utils/asymptote/doc/bigsquare.asy2
-rw-r--r--Build/source/utils/asymptote/doc/binarytreetest.asy13
-rw-r--r--Build/source/utils/asymptote/doc/brokenaxis.asy25
-rw-r--r--Build/source/utils/asymptote/doc/colons.asy1
-rw-r--r--Build/source/utils/asymptote/doc/colors.asy116
-rw-r--r--Build/source/utils/asymptote/doc/cube.asy16
-rw-r--r--Build/source/utils/asymptote/doc/cylinderskeleton.asy6
-rw-r--r--Build/source/utils/asymptote/doc/datagraph.asy12
-rw-r--r--Build/source/utils/asymptote/doc/diagonal.asy1
-rw-r--r--Build/source/utils/asymptote/doc/diatom.asy129
-rw-r--r--Build/source/utils/asymptote/doc/diatom.csv28
-rw-r--r--Build/source/utils/asymptote/doc/dots.asy1
-rw-r--r--Build/source/utils/asymptote/doc/eetomumu.asy60
-rw-r--r--Build/source/utils/asymptote/doc/elliptic.asy115
-rw-r--r--Build/source/utils/asymptote/doc/errorbars.asy42
-rw-r--r--Build/source/utils/asymptote/doc/exp.asy14
-rw-r--r--Build/source/utils/asymptote/doc/external-proposal.html415
-rw-r--r--Build/source/utils/asymptote/doc/externalprc.tex12
-rw-r--r--Build/source/utils/asymptote/doc/extra/intro.asy909
-rw-r--r--Build/source/utils/asymptote/doc/extra/intro_.bbl13
-rw-r--r--Build/source/utils/asymptote/doc/filegraph.asy15
-rw-r--r--Build/source/utils/asymptote/doc/filegraph.dat4
-rw-r--r--Build/source/utils/asymptote/doc/flow.asy31
-rw-r--r--Build/source/utils/asymptote/doc/flowchartdemo.asy30
-rw-r--r--Build/source/utils/asymptote/doc/generalaxis.asy11
-rw-r--r--Build/source/utils/asymptote/doc/generalaxis3.asy13
-rw-r--r--Build/source/utils/asymptote/doc/graphmarkers.asy37
-rw-r--r--Build/source/utils/asymptote/doc/grid3xyz.asy17
-rw-r--r--Build/source/utils/asymptote/doc/hatch.asy11
-rw-r--r--Build/source/utils/asymptote/doc/helix.asy20
-rw-r--r--Build/source/utils/asymptote/doc/histogram.asy19
-rw-r--r--Build/source/utils/asymptote/doc/icon.asy22
-rw-r--r--Build/source/utils/asymptote/doc/image.asy22
-rw-r--r--Build/source/utils/asymptote/doc/imagecontour.asy40
l---------Build/source/utils/asymptote/doc/install-sh1
-rw-r--r--Build/source/utils/asymptote/doc/irregularcontour.asy19
-rw-r--r--Build/source/utils/asymptote/doc/join.asy15
-rw-r--r--Build/source/utils/asymptote/doc/join3.asy24
-rw-r--r--Build/source/utils/asymptote/doc/knots.asy27
-rw-r--r--Build/source/utils/asymptote/doc/labelsquare.asy6
-rw-r--r--Build/source/utils/asymptote/doc/latexusage.tex112
-rw-r--r--Build/source/utils/asymptote/doc/leastsquares.asy55
-rw-r--r--Build/source/utils/asymptote/doc/leastsquares.dat882
-rw-r--r--Build/source/utils/asymptote/doc/legend.asy15
-rw-r--r--Build/source/utils/asymptote/doc/lineargraph.asy16
-rw-r--r--Build/source/utils/asymptote/doc/lineargraph0.asy16
-rw-r--r--Build/source/utils/asymptote/doc/linetype.asy13
-rw-r--r--Build/source/utils/asymptote/doc/log2graph.asy17
-rw-r--r--Build/source/utils/asymptote/doc/loggraph.asy18
-rw-r--r--Build/source/utils/asymptote/doc/loggrid.asy13
-rw-r--r--Build/source/utils/asymptote/doc/logimage.asy22
-rw-r--r--Build/source/utils/asymptote/doc/logo.asy28
-rw-r--r--Build/source/utils/asymptote/doc/logticks.asy11
-rw-r--r--Build/source/utils/asymptote/doc/makepen.asy9
-rw-r--r--Build/source/utils/asymptote/doc/markers1.asy102
-rw-r--r--Build/source/utils/asymptote/doc/markers2.asy34
-rw-r--r--Build/source/utils/asymptote/doc/mexicanhat.asy22
-rw-r--r--Build/source/utils/asymptote/doc/monthaxis.asy17
-rw-r--r--Build/source/utils/asymptote/doc/multicontour.asy19
-rw-r--r--Build/source/utils/asymptote/doc/onecontour.asy5
-rw-r--r--Build/source/utils/asymptote/doc/options75
-rw-r--r--Build/source/utils/asymptote/doc/parametricgraph.asy16
-rw-r--r--Build/source/utils/asymptote/doc/penimage.asy14
-rw-r--r--Build/source/utils/asymptote/doc/pixel.pdfbin0 -> 2771 bytes
-rw-r--r--Build/source/utils/asymptote/doc/planes.asy19
-rw-r--r--Build/source/utils/asymptote/doc/png/Makefile46
-rw-r--r--Build/source/utils/asymptote/doc/png/Makefile.in46
-rw-r--r--Build/source/utils/asymptote/doc/quartercircle.asy2
-rw-r--r--Build/source/utils/asymptote/doc/reloadpdf.tex11
-rw-r--r--Build/source/utils/asymptote/doc/saddle.asy7
-rw-r--r--Build/source/utils/asymptote/doc/scaledgraph.asy15
-rw-r--r--Build/source/utils/asymptote/doc/secondaryaxis.asy32
-rw-r--r--Build/source/utils/asymptote/doc/secondaryaxis.csv1003
-rw-r--r--Build/source/utils/asymptote/doc/shadedtiling.asy12
-rw-r--r--Build/source/utils/asymptote/doc/slopefield1.asy9
-rw-r--r--Build/source/utils/asymptote/doc/square.asy1
-rw-r--r--Build/source/utils/asymptote/doc/subpictures.asy20
-rw-r--r--Build/source/utils/asymptote/doc/superpath.asy5
-rw-r--r--Build/source/utils/asymptote/doc/tile.asy13
-rw-r--r--Build/source/utils/asymptote/doc/triangulate.asy19
-rw-r--r--Build/source/utils/asymptote/doc/unitcircle3.asy9
-rw-r--r--Build/source/utils/asymptote/doc/vectorfield.asy9
-rw-r--r--Build/source/utils/asymptote/doc/westnile.asy64
-rw-r--r--Build/source/utils/asymptote/doc/westnile.csv402
-rw-r--r--Build/source/utils/asymptote/doc/xasy.1x27
-rw-r--r--Build/source/utils/asymptote/drawclipbegin.h90
-rw-r--r--Build/source/utils/asymptote/drawclipend.h65
-rw-r--r--Build/source/utils/asymptote/drawelement.h310
-rw-r--r--Build/source/utils/asymptote/drawfill.cc174
-rw-r--r--Build/source/utils/asymptote/drawfill.h186
-rw-r--r--Build/source/utils/asymptote/drawgrestore.h35
-rw-r--r--Build/source/utils/asymptote/drawgroup.h38
-rw-r--r--Build/source/utils/asymptote/drawgsave.h35
-rw-r--r--Build/source/utils/asymptote/drawimage.h72
-rw-r--r--Build/source/utils/asymptote/drawlabel.cc310
-rw-r--r--Build/source/utils/asymptote/drawlabel.h86
-rw-r--r--Build/source/utils/asymptote/drawlayer.h42
-rw-r--r--Build/source/utils/asymptote/drawpath.cc173
-rw-r--r--Build/source/utils/asymptote/drawpath.h34
-rw-r--r--Build/source/utils/asymptote/drawpath3.cc99
-rw-r--r--Build/source/utils/asymptote/drawpath3.h64
-rw-r--r--Build/source/utils/asymptote/drawsurface.cc299
-rw-r--r--Build/source/utils/asymptote/drawsurface.h145
-rw-r--r--Build/source/utils/asymptote/drawverbatim.h57
-rw-r--r--Build/source/utils/asymptote/entry.cc365
-rw-r--r--Build/source/utils/asymptote/entry.h392
-rw-r--r--Build/source/utils/asymptote/env.cc158
-rw-r--r--Build/source/utils/asymptote/env.h175
-rw-r--r--Build/source/utils/asymptote/envcompleter.cc58
-rw-r--r--Build/source/utils/asymptote/envcompleter.h41
-rw-r--r--Build/source/utils/asymptote/errormsg.cc104
-rw-r--r--Build/source/utils/asymptote/errormsg.h204
-rw-r--r--Build/source/utils/asymptote/errors92
-rw-r--r--Build/source/utils/asymptote/errortest.asy415
-rw-r--r--Build/source/utils/asymptote/examples/.cvsignore2
-rw-r--r--Build/source/utils/asymptote/examples/100d.views3
-rw-r--r--Build/source/utils/asymptote/examples/BezierPatch.asy14
-rw-r--r--Build/source/utils/asymptote/examples/BezierSurface.asy38
-rw-r--r--Build/source/utils/asymptote/examples/Coons.asy6
-rw-r--r--Build/source/utils/asymptote/examples/Gouraud.asy18
-rw-r--r--Build/source/utils/asymptote/examples/Gouraudcontour.asy31
-rw-r--r--Build/source/utils/asymptote/examples/Klein.asy19
-rw-r--r--Build/source/utils/asymptote/examples/Pythagoras.asy22
-rw-r--r--Build/source/utils/asymptote/examples/PythagoreanTree.asy20
-rw-r--r--Build/source/utils/asymptote/examples/RiemannSurface.asy13
-rw-r--r--Build/source/utils/asymptote/examples/RiemannSurfaceRoot.asy17
-rw-r--r--Build/source/utils/asymptote/examples/Sierpinski.asy17
-rw-r--r--Build/source/utils/asymptote/examples/advection.asy87
-rw-r--r--Build/source/utils/asymptote/examples/alignbox.asy9
-rw-r--r--Build/source/utils/asymptote/examples/alignedaxis.asy107
-rw-r--r--Build/source/utils/asymptote/examples/animations/cube.asy46
-rw-r--r--Build/source/utils/asymptote/examples/animations/dice.u3dbin0 -> 160672 bytes
-rw-r--r--Build/source/utils/asymptote/examples/animations/earthmoon.asy77
-rw-r--r--Build/source/utils/asymptote/examples/animations/embeddedmovie.asy24
-rw-r--r--Build/source/utils/asymptote/examples/animations/embeddedu3d.asy6
-rw-r--r--Build/source/utils/asymptote/examples/animations/externalmovie.asy17
-rw-r--r--Build/source/utils/asymptote/examples/animations/heatequation.asy76
-rw-r--r--Build/source/utils/asymptote/examples/animations/inlinemovie.tex51
-rw-r--r--Build/source/utils/asymptote/examples/animations/inlinemovie3.tex41
-rw-r--r--Build/source/utils/asymptote/examples/animations/pdfmovie.asy20
-rw-r--r--Build/source/utils/asymptote/examples/animations/slidemovies.asy47
-rw-r--r--Build/source/utils/asymptote/examples/animations/sphere.asy44
-rw-r--r--Build/source/utils/asymptote/examples/animations/torusanimation.asy41
-rw-r--r--Build/source/utils/asymptote/examples/animations/wavepacket.asy85
-rw-r--r--Build/source/utils/asymptote/examples/animations/wheel.asy53
-rw-r--r--Build/source/utils/asymptote/examples/annotation.asy13
-rw-r--r--Build/source/utils/asymptote/examples/arrows3.asy20
-rw-r--r--Build/source/utils/asymptote/examples/buildcycle.asy22
-rw-r--r--Build/source/utils/asymptote/examples/cardioid.asy15
-rw-r--r--Build/source/utils/asymptote/examples/centroidfg.asy38
-rw-r--r--Build/source/utils/asymptote/examples/cheese.asy12
-rw-r--r--Build/source/utils/asymptote/examples/circles.asy33
-rw-r--r--Build/source/utils/asymptote/examples/coag.asy16
-rw-r--r--Build/source/utils/asymptote/examples/colorplanes.asy22
-rw-r--r--Build/source/utils/asymptote/examples/condor.asy32
-rw-r--r--Build/source/utils/asymptote/examples/cones.asy16
-rw-r--r--Build/source/utils/asymptote/examples/conicurv.asy49
-rw-r--r--Build/source/utils/asymptote/examples/controlsystem.asy39
-rw-r--r--Build/source/utils/asymptote/examples/cos2theta.asy15
-rw-r--r--Build/source/utils/asymptote/examples/cosaddition.asy26
-rw-r--r--Build/source/utils/asymptote/examples/cpkcolors.asy259
-rw-r--r--Build/source/utils/asymptote/examples/curvedlabel.asy4
-rw-r--r--Build/source/utils/asymptote/examples/curvedlabel3.asy17
-rw-r--r--Build/source/utils/asymptote/examples/cyclohexane.asy73
-rw-r--r--Build/source/utils/asymptote/examples/cylinder.asy7
-rw-r--r--Build/source/utils/asymptote/examples/delu.asy29
-rw-r--r--Build/source/utils/asymptote/examples/dimension.asy23
-rw-r--r--Build/source/utils/asymptote/examples/dragon.asy66
-rw-r--r--Build/source/utils/asymptote/examples/electromagnetic.asy47
-rw-r--r--Build/source/utils/asymptote/examples/elevation.asy15
-rw-r--r--Build/source/utils/asymptote/examples/epix.asy14
-rw-r--r--Build/source/utils/asymptote/examples/equilateral.asy12
-rw-r--r--Build/source/utils/asymptote/examples/equilchord.asy21
-rw-r--r--Build/source/utils/asymptote/examples/extrudedcontour.asy22
-rw-r--r--Build/source/utils/asymptote/examples/fano.asy28
-rw-r--r--Build/source/utils/asymptote/examples/fermi.asy40
-rw-r--r--Build/source/utils/asymptote/examples/filesurface.asy34
-rw-r--r--Build/source/utils/asymptote/examples/filesurface.dat12
-rw-r--r--Build/source/utils/asymptote/examples/fillcontour.asy29
-rw-r--r--Build/source/utils/asymptote/examples/fin.asy152
-rw-r--r--Build/source/utils/asymptote/examples/fjortoft.asy27
-rw-r--r--Build/source/utils/asymptote/examples/floatingdisk.asy24
-rw-r--r--Build/source/utils/asymptote/examples/floor.asy28
-rw-r--r--Build/source/utils/asymptote/examples/fractaltree.asy27
-rw-r--r--Build/source/utils/asymptote/examples/functionshading.asy31
-rw-r--r--Build/source/utils/asymptote/examples/galleon.asy14
-rw-r--r--Build/source/utils/asymptote/examples/gamma.asy24
-rw-r--r--Build/source/utils/asymptote/examples/gamma3.asy29
-rw-r--r--Build/source/utils/asymptote/examples/grid.asy7
-rw-r--r--Build/source/utils/asymptote/examples/hierarchy.asy9
-rw-r--r--Build/source/utils/asymptote/examples/hyperboloid.asy8
-rw-r--r--Build/source/utils/asymptote/examples/hyperboloidsilhouette.asy9
-rw-r--r--Build/source/utils/asymptote/examples/imagehistogram.asy47
-rw-r--r--Build/source/utils/asymptote/examples/impact.asy28
-rw-r--r--Build/source/utils/asymptote/examples/integraltest.asy38
-rw-r--r--Build/source/utils/asymptote/examples/interpolate1.asy213
-rw-r--r--Build/source/utils/asymptote/examples/jump.asy14
-rw-r--r--Build/source/utils/asymptote/examples/label3.asy7
-rw-r--r--Build/source/utils/asymptote/examples/label3ribbon.asy6
-rw-r--r--Build/source/utils/asymptote/examples/label3solid.asy6
-rw-r--r--Build/source/utils/asymptote/examples/labelbox.asy11
-rw-r--r--Build/source/utils/asymptote/examples/laserlattice.asy44
-rw-r--r--Build/source/utils/asymptote/examples/latticeshading.asy7
-rw-r--r--Build/source/utils/asymptote/examples/lever.asy23
-rw-r--r--Build/source/utils/asymptote/examples/limit.asy28
-rw-r--r--Build/source/utils/asymptote/examples/lines.asy10
-rw-r--r--Build/source/utils/asymptote/examples/log.asy14
-rw-r--r--Build/source/utils/asymptote/examples/logdown.asy13
-rw-r--r--Build/source/utils/asymptote/examples/logo3.asy33
-rw-r--r--Build/source/utils/asymptote/examples/lowint.asy11
-rw-r--r--Build/source/utils/asymptote/examples/lowupint.asy31
-rw-r--r--Build/source/utils/asymptote/examples/magnetic.asy17
-rw-r--r--Build/source/utils/asymptote/examples/markregular.asy26
-rw-r--r--Build/source/utils/asymptote/examples/mosaic.asy165
-rw-r--r--Build/source/utils/asymptote/examples/mosquito.asy82
-rw-r--r--Build/source/utils/asymptote/examples/near_earth.asy56
-rw-r--r--Build/source/utils/asymptote/examples/oneoverx.asy17
-rw-r--r--Build/source/utils/asymptote/examples/orthocenter.asy41
-rw-r--r--Build/source/utils/asymptote/examples/parametricelevation.asy10
-rw-r--r--Build/source/utils/asymptote/examples/parametricsurface.asy22
-rw-r--r--Build/source/utils/asymptote/examples/partialsurface.asy29
-rw-r--r--Build/source/utils/asymptote/examples/pdb.asy157
-rw-r--r--Build/source/utils/asymptote/examples/phase.asy18
-rw-r--r--Build/source/utils/asymptote/examples/piicon.eps1135
-rw-r--r--Build/source/utils/asymptote/examples/pipeintersection.asy13
-rw-r--r--Build/source/utils/asymptote/examples/planeproject.asy18
-rw-r--r--Build/source/utils/asymptote/examples/polararea.asy38
-rw-r--r--Build/source/utils/asymptote/examples/polarcircle.asy30
-rw-r--r--Build/source/utils/asymptote/examples/poster.asy32
-rw-r--r--Build/source/utils/asymptote/examples/progrid.asy1
-rw-r--r--Build/source/utils/asymptote/examples/projectelevation.asy18
-rw-r--r--Build/source/utils/asymptote/examples/projectrevolution.asy15
-rw-r--r--Build/source/utils/asymptote/examples/rainbow.asy12
-rw-r--r--Build/source/utils/asymptote/examples/randompath3.asy3
-rw-r--r--Build/source/utils/asymptote/examples/ring.asy5
-rw-r--r--Build/source/utils/asymptote/examples/roundpath.asy32
-rw-r--r--Build/source/utils/asymptote/examples/sacone.asy23
-rw-r--r--Build/source/utils/asymptote/examples/sacone3D.asy13
-rw-r--r--Build/source/utils/asymptote/examples/sacylinder.asy26
-rw-r--r--Build/source/utils/asymptote/examples/sacylinder3D.asy14
-rw-r--r--Build/source/utils/asymptote/examples/shade.asy4
-rw-r--r--Build/source/utils/asymptote/examples/shadestroke.asy5
-rw-r--r--Build/source/utils/asymptote/examples/shellmethod.asy39
-rw-r--r--Build/source/utils/asymptote/examples/shellsqrtx01.asy34
-rw-r--r--Build/source/utils/asymptote/examples/sin1x.asy16
-rw-r--r--Build/source/utils/asymptote/examples/sinc.asy19
-rw-r--r--Build/source/utils/asymptote/examples/sinxlex.asy24
-rw-r--r--Build/source/utils/asymptote/examples/slidedemo.asy118
-rw-r--r--Build/source/utils/asymptote/examples/slidedemo_.bbl13
-rw-r--r--Build/source/utils/asymptote/examples/slidemovies.asy46
-rw-r--r--Build/source/utils/asymptote/examples/smoothelevation.asy24
-rw-r--r--Build/source/utils/asymptote/examples/sphere.asy6
-rw-r--r--Build/source/utils/asymptote/examples/spheresilhouette.asy9
-rw-r--r--Build/source/utils/asymptote/examples/sphereskeleton.asy9
-rw-r--r--Build/source/utils/asymptote/examples/sphericalharmonic.asy12
-rw-r--r--Build/source/utils/asymptote/examples/spiral.asy12
-rw-r--r--Build/source/utils/asymptote/examples/spline.asy25
-rw-r--r--Build/source/utils/asymptote/examples/spring.asy33
-rw-r--r--Build/source/utils/asymptote/examples/spring0.asy4
-rw-r--r--Build/source/utils/asymptote/examples/spring2.asy4
-rw-r--r--Build/source/utils/asymptote/examples/sqrtx01.asy25
-rw-r--r--Build/source/utils/asymptote/examples/sqrtx01y1.asy24
-rw-r--r--Build/source/utils/asymptote/examples/star.asy13
-rw-r--r--Build/source/utils/asymptote/examples/stroke3.asy2
-rw-r--r--Build/source/utils/asymptote/examples/strokepath.asy17
-rw-r--r--Build/source/utils/asymptote/examples/strokeshade.asy4
-rw-r--r--Build/source/utils/asymptote/examples/tanh.asy13
-rw-r--r--Build/source/utils/asymptote/examples/teapot.asy202
-rw-r--r--Build/source/utils/asymptote/examples/tensor.asy8
-rw-r--r--Build/source/utils/asymptote/examples/thermodynamics.asy131
-rw-r--r--Build/source/utils/asymptote/examples/torus.asy7
-rw-r--r--Build/source/utils/asymptote/examples/transparency.asy9
-rw-r--r--Build/source/utils/asymptote/examples/treetest.asy22
-rw-r--r--Build/source/utils/asymptote/examples/trefoilknot.asy23
-rw-r--r--Build/source/utils/asymptote/examples/triads.asy52
-rw-r--r--Build/source/utils/asymptote/examples/triangle.asy12
-rw-r--r--Build/source/utils/asymptote/examples/triceratops.asy9
-rw-r--r--Build/source/utils/asymptote/examples/tvgen.asy1314
-rw-r--r--Build/source/utils/asymptote/examples/twistedtubes.asy28
-rw-r--r--Build/source/utils/asymptote/examples/unitcircle.asy14
-rw-r--r--Build/source/utils/asymptote/examples/upint.asy13
-rw-r--r--Build/source/utils/asymptote/examples/vectorfield3.asy26
-rw-r--r--Build/source/utils/asymptote/examples/venn.asy37
-rw-r--r--Build/source/utils/asymptote/examples/vertexshading.asy10
-rw-r--r--Build/source/utils/asymptote/examples/washermethod.asy36
-rw-r--r--Build/source/utils/asymptote/examples/wedge.asy21
-rw-r--r--Build/source/utils/asymptote/examples/workcone.asy40
-rw-r--r--Build/source/utils/asymptote/examples/xsin1x.asy10
-rw-r--r--Build/source/utils/asymptote/examples/xxsq01.asy30
-rw-r--r--Build/source/utils/asymptote/examples/xxsq01x-1.asy34
-rw-r--r--Build/source/utils/asymptote/examples/xxsq01y.asy32
-rw-r--r--Build/source/utils/asymptote/examples/yingyang.asy7
-rw-r--r--Build/source/utils/asymptote/exp.cc1166
-rw-r--r--Build/source/utils/asymptote/exp.h966
-rw-r--r--Build/source/utils/asymptote/fftw++.cc16
-rw-r--r--Build/source/utils/asymptote/fftw++.h909
-rw-r--r--Build/source/utils/asymptote/fileio.cc168
-rw-r--r--Build/source/utils/asymptote/fileio.h685
-rw-r--r--Build/source/utils/asymptote/flatguide.cc49
-rw-r--r--Build/source/utils/asymptote/flatguide.h190
-rw-r--r--Build/source/utils/asymptote/fpu.h40
-rw-r--r--Build/source/utils/asymptote/frame.h76
-rw-r--r--Build/source/utils/asymptote/fundec.cc305
-rw-r--r--Build/source/utils/asymptote/fundec.h138
-rw-r--r--Build/source/utils/asymptote/genv.cc120
-rw-r--r--Build/source/utils/asymptote/genv.h61
-rw-r--r--Build/source/utils/asymptote/getopt.c1055
-rw-r--r--Build/source/utils/asymptote/getopt.h180
-rw-r--r--Build/source/utils/asymptote/getopt1.c188
-rw-r--r--Build/source/utils/asymptote/glrender.cc1306
-rw-r--r--Build/source/utils/asymptote/glrender.h66
-rw-r--r--Build/source/utils/asymptote/guide.cc37
-rw-r--r--Build/source/utils/asymptote/guide.h307
-rw-r--r--Build/source/utils/asymptote/guideflags.h17
-rw-r--r--Build/source/utils/asymptote/inst.h63
-rwxr-xr-xBuild/source/utils/asymptote/install-sh510
-rw-r--r--Build/source/utils/asymptote/interact.cc197
-rw-r--r--Build/source/utils/asymptote/interact.h52
-rw-r--r--Build/source/utils/asymptote/item.h201
-rw-r--r--Build/source/utils/asymptote/keywords.cc45
-rwxr-xr-xBuild/source/utils/asymptote/keywords.pl60
-rw-r--r--Build/source/utils/asymptote/knot.cc840
-rw-r--r--Build/source/utils/asymptote/knot.h533
-rw-r--r--Build/source/utils/asymptote/lex.yy.cc3191
-rw-r--r--Build/source/utils/asymptote/lexical.h23
-rw-r--r--Build/source/utils/asymptote/locate.cc102
-rw-r--r--Build/source/utils/asymptote/locate.h31
-rw-r--r--Build/source/utils/asymptote/main.cc196
-rw-r--r--Build/source/utils/asymptote/mathop.h319
-rw-r--r--Build/source/utils/asymptote/memory.h177
-rw-r--r--Build/source/utils/asymptote/mod.h41
-rw-r--r--Build/source/utils/asymptote/modifier.h41
-rw-r--r--Build/source/utils/asymptote/name.cc326
-rw-r--r--Build/source/utils/asymptote/name.h167
-rw-r--r--Build/source/utils/asymptote/newexp.cc180
-rw-r--r--Build/source/utils/asymptote/newexp.h58
-rw-r--r--Build/source/utils/asymptote/pair.h229
-rw-r--r--Build/source/utils/asymptote/parser.cc146
-rw-r--r--Build/source/utils/asymptote/parser.h29
-rw-r--r--Build/source/utils/asymptote/patches/README34
-rw-r--r--Build/source/utils/asymptote/patches/TkAlpha-Imaging-1.1.6.patch156
-rw-r--r--Build/source/utils/asymptote/patches/TkAlpha-Imaging-1.1.6msdos.patch52
-rw-r--r--Build/source/utils/asymptote/patches/bison.patch206
-rw-r--r--Build/source/utils/asymptote/patches/cygwin_glu.patch87
-rw-r--r--Build/source/utils/asymptote/patches/cygwin_xdr.patch447
-rwxr-xr-xBuild/source/utils/asymptote/patches/dvipdf54
-rw-r--r--Build/source/utils/asymptote/patches/flex.patch205
-rw-r--r--Build/source/utils/asymptote/patches/gc-7.0nomem.patch21
-rw-r--r--Build/source/utils/asymptote/patches/gc6.8_AIX.patch7
-rw-r--r--Build/source/utils/asymptote/patches/gcc3.3.2curses.patch7
-rw-r--r--Build/source/utils/asymptote/patches/movie15_20090323.patch11
-rw-r--r--Build/source/utils/asymptote/patches/movie15_dvipdfmx.patch43
-rw-r--r--Build/source/utils/asymptote/patches/movie15_dvipdfmx.sty4259
-rw-r--r--Build/source/utils/asymptote/patches/pstoedit-3.45asy.patch182
-rw-r--r--Build/source/utils/asymptote/path.cc1340
-rw-r--r--Build/source/utils/asymptote/path.h456
-rw-r--r--Build/source/utils/asymptote/path3.cc914
-rw-r--r--Build/source/utils/asymptote/path3.h386
-rw-r--r--Build/source/utils/asymptote/pen.h878
-rw-r--r--Build/source/utils/asymptote/picture.cc869
-rw-r--r--Build/source/utils/asymptote/picture.h127
-rw-r--r--Build/source/utils/asymptote/pipestream.h262
-rw-r--r--Build/source/utils/asymptote/prc/Makefile22
-rw-r--r--Build/source/utils/asymptote/prc/PRC.h303
-rw-r--r--Build/source/utils/asymptote/prc/PRCTools/Makefile48
-rw-r--r--Build/source/utils/asymptote/prc/PRCTools/bitData.cc258
-rw-r--r--Build/source/utils/asymptote/prc/PRCTools/bitData.h62
-rw-r--r--Build/source/utils/asymptote/prc/PRCTools/bitSearchDouble.cc67
-rw-r--r--Build/source/utils/asymptote/prc/PRCTools/bitSearchUI.cc65
-rw-r--r--Build/source/utils/asymptote/prc/PRCTools/describeMain.cc45
-rw-r--r--Build/source/utils/asymptote/prc/PRCTools/describePRC.cc2272
-rw-r--r--Build/source/utils/asymptote/prc/PRCTools/describePRC.h117
-rw-r--r--Build/source/utils/asymptote/prc/PRCTools/extractSections.cc46
-rw-r--r--Build/source/utils/asymptote/prc/PRCTools/iPRCFile.cc220
-rw-r--r--Build/source/utils/asymptote/prc/PRCTools/iPRCFile.h88
-rw-r--r--Build/source/utils/asymptote/prc/PRCTools/inflation.cc90
-rw-r--r--Build/source/utils/asymptote/prc/PRCTools/inflation.h31
-rw-r--r--Build/source/utils/asymptote/prc/PRCTools/inflationMain.cc55
-rw-r--r--Build/source/utils/asymptote/prc/PRCTools/makePRC.cc187
-rw-r--r--Build/source/utils/asymptote/prc/PRCbitStream.cc385
-rw-r--r--Build/source/utils/asymptote/prc/PRCbitStream.h70
-rw-r--r--Build/source/utils/asymptote/prc/PRCdouble.cc2119
-rw-r--r--Build/source/utils/asymptote/prc/PRCdouble.h117
-rw-r--r--Build/source/utils/asymptote/prc/oPRCFile.cc847
-rw-r--r--Build/source/utils/asymptote/prc/oPRCFile.h395
-rw-r--r--Build/source/utils/asymptote/prc/test.cc277
-rw-r--r--Build/source/utils/asymptote/prc/writePRC.cc178
-rw-r--r--Build/source/utils/asymptote/prc/writePRC.h172
-rw-r--r--Build/source/utils/asymptote/prcfile.h83
-rw-r--r--Build/source/utils/asymptote/predicates.cc2783
-rw-r--r--Build/source/utils/asymptote/predicates.h18
-rw-r--r--Build/source/utils/asymptote/primitives.h40
-rw-r--r--Build/source/utils/asymptote/process.cc883
-rw-r--r--Build/source/utils/asymptote/process.h117
-rw-r--r--Build/source/utils/asymptote/program.cc92
-rw-r--r--Build/source/utils/asymptote/program.h89
-rw-r--r--Build/source/utils/asymptote/psfile.cc688
-rw-r--r--Build/source/utils/asymptote/psfile.h358
-rw-r--r--Build/source/utils/asymptote/quaternion.cc242
-rw-r--r--Build/source/utils/asymptote/quaternion.h114
-rw-r--r--Build/source/utils/asymptote/record.cc76
-rw-r--r--Build/source/utils/asymptote/record.h128
-rw-r--r--Build/source/utils/asymptote/refaccess.cc54
-rw-r--r--Build/source/utils/asymptote/refaccess.h86
-rw-r--r--Build/source/utils/asymptote/rounding.h87
-rw-r--r--Build/source/utils/asymptote/runtime.cc9027
-rw-r--r--Build/source/utils/asymptote/runtime.h100
-rw-r--r--Build/source/utils/asymptote/runtime.in5818
-rwxr-xr-xBuild/source/utils/asymptote/runtime.pl182
-rw-r--r--Build/source/utils/asymptote/settings.cc1391
-rw-r--r--Build/source/utils/asymptote/settings.h121
-rw-r--r--Build/source/utils/asymptote/simpson.cc221
-rw-r--r--Build/source/utils/asymptote/stack.cc370
-rw-r--r--Build/source/utils/asymptote/stack.h167
-rw-r--r--Build/source/utils/asymptote/stm.cc383
-rw-r--r--Build/source/utils/asymptote/stm.h233
-rw-r--r--Build/source/utils/asymptote/symbol.cc24
-rw-r--r--Build/source/utils/asymptote/symbol.h91
-rw-r--r--Build/source/utils/asymptote/table.h141
-rw-r--r--Build/source/utils/asymptote/tests/Makefile14
-rw-r--r--Build/source/utils/asymptote/tests/TestLib.asy15
-rw-r--r--Build/source/utils/asymptote/tests/arith/integer.asy15
-rw-r--r--Build/source/utils/asymptote/tests/arith/pair.asy20
-rw-r--r--Build/source/utils/asymptote/tests/arith/real.asy18
-rw-r--r--Build/source/utils/asymptote/tests/arith/roots.asy96
-rw-r--r--Build/source/utils/asymptote/tests/arith/transform.asy25
-rw-r--r--Build/source/utils/asymptote/tests/arith/triple.asy11
-rw-r--r--Build/source/utils/asymptote/tests/array/array.asy49
-rw-r--r--Build/source/utils/asymptote/tests/array/delete.asy41
-rw-r--r--Build/source/utils/asymptote/tests/array/determinant.asy18
-rw-r--r--Build/source/utils/asymptote/tests/array/slice.asy232
-rw-r--r--Build/source/utils/asymptote/tests/array/solve.asy35
-rw-r--r--Build/source/utils/asymptote/tests/array/transpose.asy55
-rw-r--r--Build/source/utils/asymptote/tests/bench/6000circles.asy17
-rw-r--r--Build/source/utils/asymptote/tests/frames/loop.asy29
-rw-r--r--Build/source/utils/asymptote/tests/frames/stat.asy14
-rw-r--r--Build/source/utils/asymptote/tests/frames/stat2.asy17
-rw-r--r--Build/source/utils/asymptote/tests/gc/array.asy5
-rw-r--r--Build/source/utils/asymptote/tests/gc/file.asy7
-rw-r--r--Build/source/utils/asymptote/tests/gc/funcall.asy6
-rw-r--r--Build/source/utils/asymptote/tests/gc/guide.asy5
-rw-r--r--Build/source/utils/asymptote/tests/gc/path.asy8
-rw-r--r--Build/source/utils/asymptote/tests/gc/pen.asy4
-rw-r--r--Build/source/utils/asymptote/tests/gc/string.asy6
-rw-r--r--Build/source/utils/asymptote/tests/gc/struct.asy7
-rw-r--r--Build/source/utils/asymptote/tests/gc/transform.asy6
-rw-r--r--Build/source/utils/asymptote/tests/imp/unravel.asy95
-rw-r--r--Build/source/utils/asymptote/tests/output/Makefile41
-rw-r--r--Build/source/utils/asymptote/tests/output/circle.asy1
-rw-r--r--Build/source/utils/asymptote/tests/output/line.asy1
-rw-r--r--Build/source/utils/asymptote/tests/string/erase.asy9
-rw-r--r--Build/source/utils/asymptote/tests/string/find.asy8
-rw-r--r--Build/source/utils/asymptote/tests/string/insert.asy5
-rw-r--r--Build/source/utils/asymptote/tests/string/length.asy6
-rw-r--r--Build/source/utils/asymptote/tests/string/rfind.asy8
-rw-r--r--Build/source/utils/asymptote/tests/string/substr.asy6
-rw-r--r--Build/source/utils/asymptote/tests/types/cast.asy13
-rw-r--r--Build/source/utils/asymptote/tests/types/constructor.asy271
-rw-r--r--Build/source/utils/asymptote/tests/types/ecast.asy11
-rw-r--r--Build/source/utils/asymptote/tests/types/guide.asy144
-rw-r--r--Build/source/utils/asymptote/tests/types/init.asy17
-rw-r--r--Build/source/utils/asymptote/tests/types/resolve.asy12
-rw-r--r--Build/source/utils/asymptote/tests/types/shadow.asy17
-rw-r--r--Build/source/utils/asymptote/tests/types/spec.asy61
-rw-r--r--Build/source/utils/asymptote/texfile.cc266
-rw-r--r--Build/source/utils/asymptote/texfile.h199
-rw-r--r--Build/source/utils/asymptote/tr.cc496
-rw-r--r--Build/source/utils/asymptote/tr.h167
-rw-r--r--Build/source/utils/asymptote/transform.h243
-rw-r--r--Build/source/utils/asymptote/triple.h185
-rw-r--r--Build/source/utils/asymptote/types.cc525
-rw-r--r--Build/source/utils/asymptote/types.h606
-rw-r--r--Build/source/utils/asymptote/util.cc386
-rw-r--r--Build/source/utils/asymptote/util.h124
-rw-r--r--Build/source/utils/asymptote/varinit.cc79
-rw-r--r--Build/source/utils/asymptote/varinit.h87
-rw-r--r--Build/source/utils/asymptote/vm.h26
-rwxr-xr-xBuild/source/utils/asymptote/wce11
-rw-r--r--Build/source/utils/asymptote/xstream.h253
659 files changed, 203624 insertions, 0 deletions
diff --git a/Build/source/utils/README b/Build/source/utils/README
index e02858cb143..b1e370f6ef4 100644
--- a/Build/source/utils/README
+++ b/Build/source/utils/README
@@ -5,6 +5,9 @@ You may freely use, modify and/or distribute this file.
Extra utilities we (optionally) compile for TeX Live.
See comments in ../texk/README.
+asymptote 1.72 - ok 16may09
+ http://superb-east.dl.sourceforge.net/sourceforge/asymptote/asymptote-1.72.src.tgz
+
dialog 1.1-20080819 - ok 20mar09
ftp://invisible-island.net/dialog/dialog.tar.gz
diff --git a/Build/source/utils/asymptote/.cvsignore b/Build/source/utils/asymptote/.cvsignore
new file mode 100644
index 00000000000..df332c67bb9
--- /dev/null
+++ b/Build/source/utils/asymptote/.cvsignore
@@ -0,0 +1,17 @@
+*.d
+*.eps
+*.gif
+camp.tab.cc
+camp.tab.h
+camp.output
+lex.yy.cc
+asy
+configure
+config.status
+config.log
+Makefile
+autom4te.cache
+config.h
+config.h.in
+.asy_history
+genrun.cc
diff --git a/Build/source/utils/asymptote/BUGS b/Build/source/utils/asymptote/BUGS
new file mode 100644
index 00000000000..31f9954e86c
--- /dev/null
+++ b/Build/source/utils/asymptote/BUGS
@@ -0,0 +1,5 @@
+If you find a bug in Asymptote, please check (if possible) whether the bug
+is still present in the latest SVN version before submitting a bug report.
+
+New bugs can be submitted using the Bug Tracking System at
+http://asymptote.sourceforge.net/
diff --git a/Build/source/utils/asymptote/ChangeLog b/Build/source/utils/asymptote/ChangeLog
new file mode 100644
index 00000000000..f0a3fe80346
--- /dev/null
+++ b/Build/source/utils/asymptote/ChangeLog
@@ -0,0 +1,40409 @@
+------------------------------------------------------------------------
+r4264 | jcbowman | 2009-05-14 16:03:48 -0600 (Thu, 14 May 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/configure.ac
+
+Increment version to 1.72svn.
+
+------------------------------------------------------------------------
+r4263 | jcbowman | 2009-05-14 15:59:18 -0600 (Thu, 14 May 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/pipestream.h
+
+Re-introduce portable zombie-free fork.
+
+------------------------------------------------------------------------
+r4262 | jcbowman | 2009-05-14 15:05:21 -0600 (Thu, 14 May 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/three_arrows.asy
+
+Detect degenerate paths.
+
+------------------------------------------------------------------------
+r4261 | jcbowman | 2009-05-14 15:04:56 -0600 (Thu, 14 May 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/three_surface.asy
+
+Fix ambiguity in extrude.
+
+------------------------------------------------------------------------
+r4260 | jcbowman | 2009-05-14 12:52:03 -0600 (Thu, 14 May 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/configure.ac
+
+Force HAVE_LIBGLUT on darwin.
+
+------------------------------------------------------------------------
+r4259 | jcbowman | 2009-05-14 11:57:53 -0600 (Thu, 14 May 2009) | 3 lines
+Changed paths:
+ M /trunk/asymptote/patches/README
+ A /trunk/asymptote/patches/movie15_20090323.patch
+
+Add patch to workaround problem that shows up in the 2009/03/23 version of
+movie15.sty.
+
+------------------------------------------------------------------------
+r4258 | jcbowman | 2009-05-14 10:17:15 -0600 (Thu, 14 May 2009) | 1 line
+Changed paths:
+ M /trunk/asymptote/glrender.cc
+
+Fix spurious zooms due to menu interaction.
+------------------------------------------------------------------------
+r4257 | jcbowman | 2009-05-14 09:33:06 -0600 (Thu, 14 May 2009) | 1 line
+Changed paths:
+ M /trunk/asymptote/configure.ac
+
+Detect libGLU.
+------------------------------------------------------------------------
+r4256 | jcbowman | 2009-05-14 01:47:25 -0600 (Thu, 14 May 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/three_surface.asy
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/examples/label3solid.asy
+
+Change label3 to a routine extrude that returns a surface.
+
+------------------------------------------------------------------------
+r4255 | jcbowman | 2009-05-14 01:19:29 -0600 (Thu, 14 May 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/README
+ M /trunk/asymptote/tr.cc
+ M /trunk/asymptote/tr.h
+
+Work around old LGPLv2 license covering tr.h and tr.cc.
+
+------------------------------------------------------------------------
+r4254 | jcbowman | 2009-05-14 01:00:37 -0600 (Thu, 14 May 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/drawpath3.h
+ M /trunk/asymptote/drawsurface.cc
+ M /trunk/asymptote/drawsurface.h
+ M /trunk/asymptote/glrender.cc
+ M /trunk/asymptote/triple.h
+
+Report up and target camera parameters.
+
+------------------------------------------------------------------------
+r4253 | jcbowman | 2009-05-13 23:21:33 -0600 (Wed, 13 May 2009) | 6 lines
+Changed paths:
+ M /trunk/asymptote/base/three_arrows.asy
+ M /trunk/asymptote/base/three_surface.asy
+ M /trunk/asymptote/examples/label3ribbon.asy
+ A /trunk/asymptote/examples/label3solid.asy
+
+Generalize extrude.
+
+Implement label3 for drawing 3D solid labels (illustrated in label3solid.asy).
+
+Remove extra call to bezulate.
+
+------------------------------------------------------------------------
+r4252 | jcbowman | 2009-05-13 23:18:57 -0600 (Wed, 13 May 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/bezulate.asy
+ M /trunk/asymptote/base/plain_constants.asy
+
+Define mantissaBits.
+
+------------------------------------------------------------------------
+r4251 | jcbowman | 2009-05-13 23:17:50 -0600 (Wed, 13 May 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/plain_filldraw.asy
+
+Limit recursion.
+
+------------------------------------------------------------------------
+r4250 | jcbowman | 2009-05-13 11:40:56 -0600 (Wed, 13 May 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/three.asy
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/glrender.cc
+ M /trunk/asymptote/glrender.h
+ M /trunk/asymptote/picture.cc
+ M /trunk/asymptote/picture.h
+ M /trunk/asymptote/runtime.in
+
+Add menu item (c) Camera to output camera position.
+
+------------------------------------------------------------------------
+r4249 | jcbowman | 2009-05-12 14:24:34 -0600 (Tue, 12 May 2009) | 1 line
+Changed paths:
+ M /trunk/asymptote/asymptote.nsi
+
+Make asy.bat respect all command-line arguments.
+------------------------------------------------------------------------
+r4248 | jcbowman | 2009-05-12 14:07:54 -0600 (Tue, 12 May 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/graph3.asy
+ M /trunk/asymptote/doc/grid3xyz.asy
+ M /trunk/asymptote/examples/wedge.asy
+
+Fix axis label alignment.
+
+------------------------------------------------------------------------
+r4247 | jcbowman | 2009-05-12 11:21:38 -0600 (Tue, 12 May 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/grid3.asy
+
+Update call to ticks.
+
+------------------------------------------------------------------------
+r4246 | jcbowman | 2009-05-12 11:15:49 -0600 (Tue, 12 May 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/graph.asy
+ M /trunk/asymptote/base/graph3.asy
+
+Support optional margins for axes arrows.
+
+------------------------------------------------------------------------
+r4245 | jcbowman | 2009-05-12 10:49:58 -0600 (Tue, 12 May 2009) | 2 lines
+Changed paths:
+ A /trunk/asymptote/base/trembling.asy
+ M /trunk/asymptote/doc/asymptote.texi
+ A /trunk/asymptote/examples/floatingdisk.asy
+
+Add trembling module, courtesy of Philippe Ivaldi.
+
+------------------------------------------------------------------------
+r4244 | jcbowman | 2009-05-12 10:44:28 -0600 (Tue, 12 May 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/plain_Label.asy
+
+Fix rotated path label alignments.
+
+------------------------------------------------------------------------
+r4243 | jcbowman | 2009-05-12 02:17:46 -0600 (Tue, 12 May 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/geometry.asy
+
+Update comments.
+
+------------------------------------------------------------------------
+r4242 | jcbowman | 2009-05-12 02:01:22 -0600 (Tue, 12 May 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/geometry.asy
+ M /trunk/asymptote/doc/asymptote.texi
+
+Merge in Philippe Ivaldi's geometry module.
+
+------------------------------------------------------------------------
+r4241 | jcbowman | 2009-05-11 22:28:04 -0600 (Mon, 11 May 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/README
+ M /trunk/asymptote/doc/asymptote.texi
+
+Update license.
+
+------------------------------------------------------------------------
+r4240 | jcbowman | 2009-05-11 15:37:12 -0600 (Mon, 11 May 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/runtime.in
+
+Respect store argument of saveline.
+
+------------------------------------------------------------------------
+r4239 | jcbowman | 2009-05-11 12:59:15 -0600 (Mon, 11 May 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/graph3.asy
+
+Update Ticks3.
+
+------------------------------------------------------------------------
+r4238 | jcbowman | 2009-05-11 12:55:54 -0600 (Mon, 11 May 2009) | 4 lines
+Changed paths:
+ M /trunk/asymptote/base/graph.asy
+ M /trunk/asymptote/base/plain_strings.asy
+
+Implement signedtrailingzero.
+
+Fix left-justified trailingzero alignment.
+
+------------------------------------------------------------------------
+r4237 | jcbowman | 2009-05-11 11:39:52 -0600 (Mon, 11 May 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/plain_picture.asy
+ M /trunk/asymptote/examples/functionshading.asy
+
+Resolve ambiguity.
+
+------------------------------------------------------------------------
+r4236 | jcbowman | 2009-05-11 10:39:04 -0600 (Mon, 11 May 2009) | 4 lines
+Changed paths:
+ M /trunk/asymptote/base/plain_picture.asy
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/drawfill.cc
+ M /trunk/asymptote/drawfill.h
+ A /trunk/asymptote/examples/functionshading.asy
+ M /trunk/asymptote/pen.h
+ M /trunk/asymptote/psfile.h
+ M /trunk/asymptote/runtime.in
+ M /trunk/asymptote/texfile.h
+
+Implement PostScript calculcator function shading and example.
+
+Add default fillrule arguments to frame shading routines.
+
+------------------------------------------------------------------------
+r4235 | jcbowman | 2009-05-08 03:12:28 -0600 (Fri, 08 May 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/three_arrows.asy
+
+Continue splitting when radius of curvature is zero.
+
+------------------------------------------------------------------------
+r4234 | jcbowman | 2009-05-08 02:59:30 -0600 (Fri, 08 May 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/builtin.cc
+
+Add Philipp Stephani's GSL updates.
+
+------------------------------------------------------------------------
+r4233 | jcbowman | 2009-05-08 02:11:46 -0600 (Fri, 08 May 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/FAQ/asy-faq.bfnn
+ M /trunk/asymptote/doc/asymptote.texi
+
+Fix link; add missing index entries.
+
+------------------------------------------------------------------------
+r4232 | jcbowman | 2009-05-08 01:22:22 -0600 (Fri, 08 May 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/plain_Label.asy
+ M /trunk/asymptote/base/plain_arrows.asy
+ M /trunk/asymptote/base/three_arrows.asy
+
+Fix endpoint detection.
+
+------------------------------------------------------------------------
+r4231 | jcbowman | 2009-05-05 15:44:20 -0600 (Tue, 05 May 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/pen.h
+
+Fix write(pen).
+
+------------------------------------------------------------------------
+r4230 | jcbowman | 2009-05-01 14:42:31 -0600 (Fri, 01 May 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+
+Improve documentation of shipout.
+
+------------------------------------------------------------------------
+r4229 | jcbowman | 2009-04-30 11:52:51 -0600 (Thu, 30 Apr 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/examples/strokepath.asy
+
+Fix bounds.
+
+------------------------------------------------------------------------
+r4228 | jcbowman | 2009-04-30 11:46:33 -0600 (Thu, 30 Apr 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/examples/strokepath.asy
+
+Fix comment.
+
+------------------------------------------------------------------------
+r4227 | jcbowman | 2009-04-30 11:45:51 -0600 (Thu, 30 Apr 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/examples/strokepath.asy
+
+Improve example.
+
+------------------------------------------------------------------------
+r4226 | jcbowman | 2009-04-30 11:44:10 -0600 (Thu, 30 Apr 2009) | 2 lines
+Changed paths:
+ A /trunk/asymptote/examples/strokepath.asy
+
+Add strokepath example.
+
+------------------------------------------------------------------------
+r4225 | jcbowman | 2009-04-30 09:32:36 -0600 (Thu, 30 Apr 2009) | 2 lines
+Changed paths:
+ A /trunk/asymptote/examples/twistedtubes.asy
+
+Add twisted tubes example.
+
+------------------------------------------------------------------------
+r4224 | jcbowman | 2009-04-29 16:44:55 -0600 (Wed, 29 Apr 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/drawfill.cc
+ M /trunk/asymptote/drawfill.h
+ M /trunk/asymptote/psfile.cc
+ M /trunk/asymptote/psfile.h
+ M /trunk/asymptote/runtime.in
+
+Implement functionshade primitive.
+
+------------------------------------------------------------------------
+r4223 | jcbowman | 2009-04-27 22:14:04 -0600 (Mon, 27 Apr 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/plain_Label.asy
+
+Fix numerical resolution problem in label alignment.
+
+------------------------------------------------------------------------
+r4222 | jcbowman | 2009-04-27 19:13:42 -0600 (Mon, 27 Apr 2009) | 6 lines
+Changed paths:
+ M /trunk/asymptote/configure.ac
+ M /trunk/asymptote/settings.cc
+
+Add sysdir setting.
+
+Support automatic determination of sysdir from kpsewhich, if sysdir="".
+
+Add configure option --enable-tetex-build to force sysdir="".
+
+------------------------------------------------------------------------
+r4221 | jcbowman | 2009-04-27 11:42:19 -0600 (Mon, 27 Apr 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/three.asy
+
+Fix effective camera positions for oblique projections.
+
+------------------------------------------------------------------------
+r4220 | jcbowman | 2009-04-24 11:41:49 -0600 (Fri, 24 Apr 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/camperror.cc
+ M /trunk/asymptote/camperror.h
+ M /trunk/asymptote/errormsg.cc
+ M /trunk/asymptote/errormsg.h
+ M /trunk/asymptote/pipestream.h
+
+Abort on write to pipe failed error.
+
+------------------------------------------------------------------------
+r4219 | jcbowman | 2009-04-24 10:55:49 -0600 (Fri, 24 Apr 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/examples/animations/slidemovies.asy
+
+Generate wheel.mpg earlier.
+
+------------------------------------------------------------------------
+r4218 | jcbowman | 2009-04-24 10:25:53 -0600 (Fri, 24 Apr 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/common.h
+ M /trunk/asymptote/configure.ac
+ M /trunk/asymptote/drawpath3.cc
+ M /trunk/asymptote/drawsurface.cc
+ M /trunk/asymptote/drawsurface.h
+ M /trunk/asymptote/glrender.cc
+ M /trunk/asymptote/glrender.h
+ M /trunk/asymptote/main.cc
+ M /trunk/asymptote/picture.cc
+ M /trunk/asymptote/psfile.cc
+ M /trunk/asymptote/settings.cc
+ M /trunk/asymptote/tr.cc
+
+Explicitly check for libGLU.
+
+------------------------------------------------------------------------
+r4217 | jcbowman | 2009-04-24 01:59:54 -0600 (Fri, 24 Apr 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/psfile.cc
+
+Minor optimizations.
+
+------------------------------------------------------------------------
+r4216 | jcbowman | 2009-04-24 01:52:12 -0600 (Fri, 24 Apr 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/psfile.cc
+ M /trunk/asymptote/psfile.h
+
+Simplify dealiasing code.
+
+------------------------------------------------------------------------
+r4215 | jcbowman | 2009-04-24 00:35:32 -0600 (Fri, 24 Apr 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/psfile.cc
+ M /trunk/asymptote/psfile.h
+
+Optimize dealiasing of 3D rendered non-RGB images.
+
+------------------------------------------------------------------------
+r4214 | jcbowman | 2009-04-22 11:42:32 -0600 (Wed, 22 Apr 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/builtin.cc
+
+Rename test member function.
+
+------------------------------------------------------------------------
+r4213 | jcbowman | 2009-04-22 11:33:48 -0600 (Wed, 22 Apr 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/builtin.cc
+ M /trunk/asymptote/doc/asymptote.texi
+ A /trunk/asymptote/examples/cheese.asy
+ M /trunk/asymptote/examples/shellsqrtx01.asy
+ M /trunk/asymptote/examples/xxsq01y.asy
+
+Add example of defining a builtin asy struct.
+
+------------------------------------------------------------------------
+r4212 | jcbowman | 2009-04-22 10:52:30 -0600 (Wed, 22 Apr 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/builtin.cc
+
+Implement value-based addVariable routine.
+
+------------------------------------------------------------------------
+r4211 | jcbowman | 2009-04-19 13:56:00 -0600 (Sun, 19 Apr 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/three_arrows.asy
+ M /trunk/asymptote/path.h
+ M /trunk/asymptote/path3.h
+
+Check recursion depth.
+
+------------------------------------------------------------------------
+r4210 | jcbowman | 2009-04-19 10:34:12 -0600 (Sun, 19 Apr 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/three_arrows.asy
+
+Continue subdivision tests if zero radius of curvature is encountered.
+
+------------------------------------------------------------------------
+r4209 | jcbowman | 2009-04-18 23:52:51 -0600 (Sat, 18 Apr 2009) | 3 lines
+Changed paths:
+ M /trunk/asymptote/asymptote.spec
+ M /trunk/asymptote/base/plain_Label.asy
+ M /trunk/asymptote/base/tube.asy
+ M /trunk/asymptote/drawlabel.cc
+
+Change basealign so that "ace" and "acg" are always typeset at the same
+location.
+
+------------------------------------------------------------------------
+r4208 | jcbowman | 2009-04-18 16:57:05 -0600 (Sat, 18 Apr 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/three_arrows.asy
+
+Handle more degenerate cases.
+
+------------------------------------------------------------------------
+r4207 | jcbowman | 2009-04-18 15:42:21 -0600 (Sat, 18 Apr 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/three_arrows.asy
+
+Handle degenerate paths.
+
+------------------------------------------------------------------------
+r4206 | jcbowman | 2009-04-18 15:28:41 -0600 (Sat, 18 Apr 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/three.asy
+ M /trunk/asymptote/base/three_arrows.asy
+ M /trunk/asymptote/base/three_surface.asy
+ M /trunk/asymptote/base/tube.asy
+ M /trunk/asymptote/examples/condor.asy
+ A /trunk/asymptote/examples/randompath3.asy
+ M /trunk/asymptote/runtime.in
+
+Improve adaptive algorithm used for rendering thick lines and tubes.
+
+------------------------------------------------------------------------
+r4205 | jcbowman | 2009-04-18 06:56:28 -0600 (Sat, 18 Apr 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/flowchart.asy
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/examples/controlsystem.asy
+
+Fix circle ambiguity.
+
+------------------------------------------------------------------------
+r4204 | jcbowman | 2009-04-17 22:15:06 -0600 (Fri, 17 Apr 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/examples/condor.asy
+
+Change perspective.
+
+------------------------------------------------------------------------
+r4203 | jcbowman | 2009-04-17 22:07:43 -0600 (Fri, 17 Apr 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/examples/condor.asy
+
+Fix URL.
+
+------------------------------------------------------------------------
+r4202 | jcbowman | 2009-04-17 22:05:46 -0600 (Fri, 17 Apr 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/examples/condor.asy
+
+Use parametric mesh.
+
+------------------------------------------------------------------------
+r4201 | jcbowman | 2009-04-17 21:28:45 -0600 (Fri, 17 Apr 2009) | 2 lines
+Changed paths:
+ A /trunk/asymptote/examples/condor.asy (from /trunk/asymptote/examples/stealthdragon.asy:4200)
+ D /trunk/asymptote/examples/stealthdragon.asy
+
+Rename example; use smooth coloring.
+
+------------------------------------------------------------------------
+r4200 | jcbowman | 2009-04-15 23:35:07 -0600 (Wed, 15 Apr 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/examples/extrudedcontour.asy
+ A /trunk/asymptote/examples/stealthdragon.asy
+
+Add example.
+
+------------------------------------------------------------------------
+r4199 | jcbowman | 2009-04-15 23:28:57 -0600 (Wed, 15 Apr 2009) | 3 lines
+Changed paths:
+ M /trunk/asymptote/base/graph3.asy
+ M /trunk/asymptote/examples/partialsurface.asy
+
+Make boolean condition suppress function evaluation for linearly
+interpolated surfaces.
+
+------------------------------------------------------------------------
+r4198 | jcbowman | 2009-04-13 08:48:38 -0600 (Mon, 13 Apr 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/plain_pens.asy
+ M /trunk/asymptote/examples/animations/earthmoon.asy
+ A /trunk/asymptote/examples/extrudedcontour.asy
+
+Add operator +(pen, pen[]) and operator +(pen[], pen) and example.
+
+------------------------------------------------------------------------
+r4197 | jcbowman | 2009-04-12 23:04:57 -0600 (Sun, 12 Apr 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/examples/animations/earthmoon.asy
+
+Generate mpg file.
+
+------------------------------------------------------------------------
+r4196 | jcbowman | 2009-04-12 21:32:34 -0600 (Sun, 12 Apr 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/examples/animations/earthmoon.asy
+
+Produce an animated gif rather than an inline PDF movie (about 1/4 as big).
+
+------------------------------------------------------------------------
+r4195 | jcbowman | 2009-04-12 17:11:56 -0600 (Sun, 12 Apr 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/three_surface.asy
+
+Avoid nullpath3 has no points error when label is given nullpath3.
+
+------------------------------------------------------------------------
+r4194 | jcbowman | 2009-04-11 01:32:31 -0600 (Sat, 11 Apr 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/cube.asy
+
+Set dotgranularity=0 in cube example to force dots to be rendered as spheres.
+
+------------------------------------------------------------------------
+r4193 | jcbowman | 2009-04-10 22:03:19 -0600 (Fri, 10 Apr 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/examples/animations/torusanimation.asy
+
+Improve example to use a better (smooth) approximation to a torus.
+
+------------------------------------------------------------------------
+r4192 | jcbowman | 2009-04-10 15:10:27 -0600 (Fri, 10 Apr 2009) | 1 line
+Changed paths:
+ M /trunk/asymptote/configure.ac
+
+Increment version to 1.71svn.
+------------------------------------------------------------------------
+r4191 | jcbowman | 2009-04-10 12:57:02 -0600 (Fri, 10 Apr 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/asymptote.spec
+ M /trunk/asymptote/doc/asymptote.texi
+
+Add node.
+
+------------------------------------------------------------------------
+r4190 | jcbowman | 2009-04-10 11:35:11 -0600 (Fri, 10 Apr 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/runtime.in
+
+Optimize and improve valid range of choose(int n, int k).
+
+------------------------------------------------------------------------
+r4189 | jcbowman | 2009-04-10 10:48:31 -0600 (Fri, 10 Apr 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/examples/animations/torusanimation.asy
+
+Update example.
+
+------------------------------------------------------------------------
+r4188 | jcbowman | 2009-04-10 09:52:28 -0600 (Fri, 10 Apr 2009) | 4 lines
+Changed paths:
+ M /trunk/asymptote/base/animation.asy
+
+Handle spaces in incoming prefix.
+
+Add prefix arguments to fit function.
+
+------------------------------------------------------------------------
+r4187 | jcbowman | 2009-04-10 09:40:07 -0600 (Fri, 10 Apr 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/picture.cc
+
+Handle spaces in filenames when using pdflatex.
+
+------------------------------------------------------------------------
+r4186 | jcbowman | 2009-04-10 00:27:03 -0600 (Fri, 10 Apr 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/animation.asy
+
+Work around animation problems with spaces in filenames.
+
+------------------------------------------------------------------------
+r4185 | jcbowman | 2009-04-09 23:57:44 -0600 (Thu, 09 Apr 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/three_light.asy
+ M /trunk/asymptote/base/three_margins.asy
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/examples/fin.asy
+
+Add PenMargin2, etc., for planar arrowhead types like DefaultHead2.
+
+------------------------------------------------------------------------
+r4184 | jcbowman | 2009-04-09 17:57:52 -0600 (Thu, 09 Apr 2009) | 3 lines
+Changed paths:
+ A /trunk/asymptote/base/labelpath3.asy
+ M /trunk/asymptote/doc/asymptote.texi
+ A /trunk/asymptote/examples/curvedlabel3.asy
+
+Add labelpath3 module for typesetting curved labels in 3D and example,
+courtesy of Jens Schwaiger.
+
+------------------------------------------------------------------------
+r4183 | jcbowman | 2009-04-09 16:32:17 -0600 (Thu, 09 Apr 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/examples/teapot.asy
+
+Center target of teapot.
+
+------------------------------------------------------------------------
+r4182 | jcbowman | 2009-04-09 16:30:01 -0600 (Thu, 09 Apr 2009) | 3 lines
+Changed paths:
+ M /trunk/asymptote/base/plain_picture.asy
+ M /trunk/asymptote/base/three.asy
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/examples/gamma3.asy
+ M /trunk/asymptote/examples/sinc.asy
+ M /trunk/asymptote/examples/smoothelevation.asy
+ M /trunk/asymptote/runtime.in
+
+Add bool center=false parameter to projections to allow one to
+automatically center the target within the bounding volume.
+
+------------------------------------------------------------------------
+r4181 | jcbowman | 2009-04-07 21:05:53 -0600 (Tue, 07 Apr 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/FAQ/asy-faq.bfnn
+
+Fix clipping example.
+
+------------------------------------------------------------------------
+r4180 | jcbowman | 2009-04-07 16:02:10 -0600 (Tue, 07 Apr 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/FAQ/asy-faq.bfnn
+
+Minor update.
+
+------------------------------------------------------------------------
+r4179 | jcbowman | 2009-04-07 16:00:46 -0600 (Tue, 07 Apr 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/FAQ/asy-faq.bfnn
+
+Use locale.
+
+------------------------------------------------------------------------
+r4178 | jcbowman | 2009-04-07 15:46:44 -0600 (Tue, 07 Apr 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/FAQ/asy-faq.bfnn
+
+More updates.
+
+------------------------------------------------------------------------
+r4177 | jcbowman | 2009-04-07 15:41:08 -0600 (Tue, 07 Apr 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/FAQ/asy-faq.bfnn
+
+Fix typos.
+
+------------------------------------------------------------------------
+r4176 | jcbowman | 2009-04-06 15:55:08 -0600 (Mon, 06 Apr 2009) | 3 lines
+Changed paths:
+ M /trunk/asymptote/base/three_surface.asy
+ M /trunk/asymptote/examples/BezierPatch.asy
+
+Reserve surface(triple[][] P) for graphing a surface described by a matrix;
+use surface(patch(P)) instead.
+
+------------------------------------------------------------------------
+r4175 | jcbowman | 2009-04-06 03:39:14 -0600 (Mon, 06 Apr 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/builtin.cc
+
+Work around old compiler bug.
+
+------------------------------------------------------------------------
+r4174 | jcbowman | 2009-04-06 03:37:42 -0600 (Mon, 06 Apr 2009) | 1 line
+Changed paths:
+ M /trunk/asymptote/asymptote.spec
+ M /trunk/asymptote/configure.ac
+
+Increment version to 1.70svn.
+------------------------------------------------------------------------
+r4173 | jcbowman | 2009-04-06 02:02:44 -0600 (Mon, 06 Apr 2009) | 2 lines
+Changed paths:
+ A /trunk/asymptote/examples/animations/torusanimation.asy
+
+Add torus animation.
+
+------------------------------------------------------------------------
+r4172 | jcbowman | 2009-04-06 01:53:38 -0600 (Mon, 06 Apr 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/examples/animations/sphere.asy
+
+Reduce memory usage.
+
+------------------------------------------------------------------------
+r4171 | jcbowman | 2009-04-06 01:07:52 -0600 (Mon, 06 Apr 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/animation.asy
+ M /trunk/asymptote/examples/animations/heatequation.asy
+
+Force outformat="pdf" when producing PDF animations.
+
+------------------------------------------------------------------------
+r4170 | jcbowman | 2009-04-06 00:30:10 -0600 (Mon, 06 Apr 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/animation.asy
+ M /trunk/asymptote/base/three.asy
+ M /trunk/asymptote/examples/animations/heatequation.asy
+
+Change - delimiter to + for animation frames and preview images.
+
+------------------------------------------------------------------------
+r4169 | jcbowman | 2009-04-05 23:36:07 -0600 (Sun, 05 Apr 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/math.asy
+ M /trunk/asymptote/base/plain_constants.asy
+ M /trunk/asymptote/builtin.cc
+ M /trunk/asymptote/builtin.h
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/runtime.in
+
+Move extension routine and infinity constant to C++ code.
+
+------------------------------------------------------------------------
+r4168 | jcbowman | 2009-04-05 22:50:15 -0600 (Sun, 05 Apr 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/embed.asy
+
+Work around hyperref option clash.
+
+------------------------------------------------------------------------
+r4167 | jcbowman | 2009-04-05 21:26:41 -0600 (Sun, 05 Apr 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/camperror.cc
+
+Catch handled_errors (e.g. from ~psfile()) during throw handled_error().
+
+------------------------------------------------------------------------
+r4166 | jcbowman | 2009-04-05 17:08:33 -0600 (Sun, 05 Apr 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/animation.asy
+ M /trunk/asymptote/base/plain_boxes.asy
+ M /trunk/asymptote/base/plain_shipout.asy
+ M /trunk/asymptote/base/three.asy
+ M /trunk/asymptote/examples/animations/earthmoon.asy
+ M /trunk/asymptote/examples/animations/inlinemovie.tex
+ M /trunk/asymptote/examples/animations/inlinemovie3.tex
+ M /trunk/asymptote/examples/animations/slidemovies.asy
+
+Fix more animation prefix issues.
+
+------------------------------------------------------------------------
+r4165 | jcbowman | 2009-04-05 14:19:38 -0600 (Sun, 05 Apr 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/animation.asy
+ M /trunk/asymptote/examples/animations/inlinemovie.tex
+ M /trunk/asymptote/examples/animations/inlinemovie3.tex
+
+Keep keep flag.
+
+------------------------------------------------------------------------
+r4164 | jcbowman | 2009-04-05 13:21:13 -0600 (Sun, 05 Apr 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/animation.asy
+ M /trunk/asymptote/base/plain_arrows.asy
+ M /trunk/asymptote/base/plain_picture.asy
+ M /trunk/asymptote/base/plain_shipout.asy
+ M /trunk/asymptote/base/three.asy
+
+Move 3D code out of animation.asy.
+
+------------------------------------------------------------------------
+r4163 | jcbowman | 2009-04-05 12:02:17 -0600 (Sun, 05 Apr 2009) | 6 lines
+Changed paths:
+ M /trunk/asymptote/base/animation.asy
+ M /trunk/asymptote/base/plain_shipout.asy
+ M /trunk/asymptote/base/three.asy
+ A /trunk/asymptote/examples/animations/earthmoon.asy
+ A /trunk/asymptote/examples/animations/heatequation.asy
+ M /trunk/asymptote/examples/animations/inlinemovie.tex
+ M /trunk/asymptote/examples/animations/inlinemovie3.tex
+
+Fix inline pdf animations with multipage=false.
+
+Fix global scaling of 3D animations.
+
+Add heatequation and earthmoon examples.
+
+------------------------------------------------------------------------
+r4162 | jcbowman | 2009-04-04 14:26:55 -0600 (Sat, 04 Apr 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/three_surface.asy
+
+Minor optimization.
+
+------------------------------------------------------------------------
+r4161 | jcbowman | 2009-04-04 14:24:31 -0600 (Sat, 04 Apr 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/runtime.in
+
+Use a lookup table to compute factorial(int n).
+
+------------------------------------------------------------------------
+r4160 | jcbowman | 2009-04-04 12:50:14 -0600 (Sat, 04 Apr 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/plain_pens.asy
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/pen.h
+ M /trunk/asymptote/psfile.cc
+ M /trunk/asymptote/runtime.in
+
+Implement miterlimit.
+
+------------------------------------------------------------------------
+r4159 | jcbowman | 2009-04-04 11:26:43 -0600 (Sat, 04 Apr 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/graph.asy
+ M /trunk/asymptote/base/graph3.asy
+
+Fix use of baseline.
+
+------------------------------------------------------------------------
+r4158 | jcbowman | 2009-04-04 10:44:00 -0600 (Sat, 04 Apr 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/glrender.cc
+
+Disable old lights for multiple exports.
+
+------------------------------------------------------------------------
+r4157 | jcbowman | 2009-04-04 08:44:15 -0600 (Sat, 04 Apr 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/settings.cc
+
+Fix warning message.
+
+------------------------------------------------------------------------
+r4156 | jcbowman | 2009-04-04 08:41:58 -0600 (Sat, 04 Apr 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/settings.cc
+
+Add missing conditional.
+
+------------------------------------------------------------------------
+r4155 | jcbowman | 2009-04-04 00:31:39 -0600 (Sat, 04 Apr 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/examples/trefoilknot.asy
+
+Improve example.
+
+------------------------------------------------------------------------
+r4154 | jcbowman | 2009-04-04 00:24:39 -0600 (Sat, 04 Apr 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/symbol.cc
+ M /trunk/asymptote/symbol.h
+
+Remove unnecessary parameter.
+
+------------------------------------------------------------------------
+r4153 | jcbowman | 2009-04-04 00:22:37 -0600 (Sat, 04 Apr 2009) | 4 lines
+Changed paths:
+ M /trunk/asymptote/process.cc
+ M /trunk/asymptote/runtime.in
+ M /trunk/asymptote/settings.cc
+ M /trunk/asymptote/symbol.cc
+
+Fix type conflict by replacing settings.divisor with purge(divisor=0);
+divisor=0 means to use the previously set divisor (which defaults to 2, or the
+value specified on the command line with the -divisor option).
+
+------------------------------------------------------------------------
+r4152 | jcbowman | 2009-04-03 22:06:22 -0600 (Fri, 03 Apr 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/three.asy
+
+Increase orthographic viewportfactor.
+
+------------------------------------------------------------------------
+r4151 | jcbowman | 2009-04-02 00:05:50 -0600 (Thu, 02 Apr 2009) | 6 lines
+Changed paths:
+ M /trunk/asymptote/base/three.asy
+ M /trunk/asymptote/base/three_arrows.asy
+ M /trunk/asymptote/base/tube.asy
+ M /trunk/asymptote/doc/asymptote.texi
+
+Add missing 3D add function.
+
+Increase nsamples to 32.
+
+Remove nonselfintersecting restriction.
+
+------------------------------------------------------------------------
+r4150 | jcbowman | 2009-04-01 02:38:09 -0600 (Wed, 01 Apr 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/three_surface.asy
+
+Fix splitting.
+
+------------------------------------------------------------------------
+r4149 | jcbowman | 2009-03-31 20:31:48 -0600 (Tue, 31 Mar 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/path.cc
+ M /trunk/asymptote/path3.cc
+
+Increase fuzz; use static dxmin.
+
+------------------------------------------------------------------------
+r4148 | jcbowman | 2009-03-31 17:32:16 -0600 (Tue, 31 Mar 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/three_surface.asy
+
+Reorder tests.
+
+------------------------------------------------------------------------
+r4147 | jcbowman | 2009-03-31 17:27:53 -0600 (Tue, 31 Mar 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/three_surface.asy
+
+Check for triangles first.
+
+------------------------------------------------------------------------
+r4146 | jcbowman | 2009-03-31 16:54:09 -0600 (Tue, 31 Mar 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/three_surface.asy
+
+Split randomly to avoid returning a degenerate patch.
+
+------------------------------------------------------------------------
+r4145 | jcbowman | 2009-03-31 16:21:13 -0600 (Tue, 31 Mar 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/glrender.cc
+ M /trunk/asymptote/picture.cc
+
+Fix interactive rendering.
+
+------------------------------------------------------------------------
+r4144 | jcbowman | 2009-03-31 02:32:14 -0600 (Tue, 31 Mar 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/three_surface.asy
+
+Once an internal degeneracy is found, don't check any more boundary cases.
+
+------------------------------------------------------------------------
+r4143 | jcbowman | 2009-03-31 01:45:23 -0600 (Tue, 31 Mar 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/three_arrows.asy
+
+Increase nsamples.
+
+------------------------------------------------------------------------
+r4142 | jcbowman | 2009-03-31 00:39:32 -0600 (Tue, 31 Mar 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/three_arrows.asy
+ M /trunk/asymptote/base/three_surface.asy
+
+Split at the worst boundary degeneracy.
+
+------------------------------------------------------------------------
+r4141 | jcbowman | 2009-03-30 12:29:10 -0600 (Mon, 30 Mar 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/embed.asy
+ M /trunk/asymptote/base/external.asy
+
+Add unicode option to make new versions of hyperref happy.
+
+------------------------------------------------------------------------
+r4140 | jcbowman | 2009-03-30 08:44:30 -0600 (Mon, 30 Mar 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/animation.asy
+
+Pass animate the correct file name.
+
+------------------------------------------------------------------------
+r4139 | jcbowman | 2009-03-29 23:39:56 -0600 (Sun, 29 Mar 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/path.cc
+ M /trunk/asymptote/path3.cc
+
+Fix floating point exception caused by attempt to split paths of length 0.
+
+------------------------------------------------------------------------
+r4138 | jcbowman | 2009-03-29 23:07:13 -0600 (Sun, 29 Mar 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/math.asy
+ M /trunk/asymptote/base/plain_paths.asy
+ M /trunk/asymptote/doc/asymptote.texi
+
+Move inside(path, pen fillrule=currentpen) to plain_paths.asy.
+
+------------------------------------------------------------------------
+r4137 | jcbowman | 2009-03-29 20:57:00 -0600 (Sun, 29 Mar 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/pen.h
+
+Fix defaultpen(evenodd).
+
+------------------------------------------------------------------------
+r4136 | jcbowman | 2009-03-29 17:00:07 -0600 (Sun, 29 Mar 2009) | 3 lines
+Changed paths:
+ M /trunk/asymptote/path.cc
+
+Fix spurious "undefined" (on curve) return values from windingnumber;
+optimize handling of straight segments.
+
+------------------------------------------------------------------------
+r4135 | jcbowman | 2009-03-29 14:45:08 -0600 (Sun, 29 Mar 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/glrender.cc
+
+Always define glthread.
+
+------------------------------------------------------------------------
+r4134 | jcbowman | 2009-03-29 10:06:33 -0600 (Sun, 29 Mar 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.sty
+ M /trunk/asymptote/doc/asymptote.texi
+
+Release version 1.06 of asymptote.sty to fix undefined \ASYbox bug.
+
+------------------------------------------------------------------------
+r4133 | jcbowman | 2009-03-29 00:30:53 -0600 (Sun, 29 Mar 2009) | 5 lines
+Changed paths:
+ M /trunk/asymptote/base/three_surface.asy
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/examples/logo3.asy
+
+Automatically apply bezulate to path arrays. Surfaces should now be
+constructed directly from paths (and paths arrays), without first calling
+bezulate. An array of independent surfaces can still be constructed from a
+path array using a loop.
+
+------------------------------------------------------------------------
+r4132 | jcbowman | 2009-03-29 00:05:54 -0600 (Sun, 29 Mar 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/math.asy
+ M /trunk/asymptote/base/plain_pens.asy
+
+Fix inside(path,pen).
+
+------------------------------------------------------------------------
+r4131 | jcbowman | 2009-03-28 23:35:26 -0600 (Sat, 28 Mar 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/bezulate.asy
+
+Add Orest's connect patch to fix nesting.
+
+------------------------------------------------------------------------
+r4130 | jcbowman | 2009-03-28 23:11:34 -0600 (Sat, 28 Mar 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/bezulate.asy
+ M /trunk/asymptote/base/three_surface.asy
+
+Specify zerowindingnumber rule.
+
+------------------------------------------------------------------------
+r4129 | jcbowman | 2009-03-28 23:09:13 -0600 (Sat, 28 Mar 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/math.asy
+
+Improve inside(pair); add fillrule argument.
+
+------------------------------------------------------------------------
+r4128 | jcbowman | 2009-03-28 14:21:05 -0600 (Sat, 28 Mar 2009) | 4 lines
+Changed paths:
+ M /trunk/asymptote/base/three_surface.asy
+
+Remove internal patch degeneracies by splitting.
+
+Compute subpatches directly from control points.
+
+------------------------------------------------------------------------
+r4127 | jcbowman | 2009-03-28 12:24:17 -0600 (Sat, 28 Mar 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/runtime.in
+
+Implement factorial and choose functions.
+
+------------------------------------------------------------------------
+r4126 | jcbowman | 2009-03-28 12:18:16 -0600 (Sat, 28 Mar 2009) | 2 lines
+Changed paths:
+ D /trunk/asymptote/examples/intersectingpipes.asy
+ A /trunk/asymptote/examples/pipeintersection.asy (from /trunk/asymptote/examples/intersectingpipes.asy:4121)
+
+Rename example; use orthographic projection.
+
+------------------------------------------------------------------------
+r4125 | jcbowman | 2009-03-28 12:15:09 -0600 (Sat, 28 Mar 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/three.asy
+
+Make path(path3, pair(triple)) preserve straight flag.
+
+------------------------------------------------------------------------
+r4124 | jcbowman | 2009-03-28 12:08:55 -0600 (Sat, 28 Mar 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/glrender.cc
+ M /trunk/asymptote/picture.cc
+
+Fix quit deadlock.
+
+------------------------------------------------------------------------
+r4123 | jcbowman | 2009-03-28 00:11:09 -0600 (Sat, 28 Mar 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/drawlabel.cc
+
+Increase fuzz to accomodate italic "k".
+
+------------------------------------------------------------------------
+r4122 | oshardt | 2009-03-27 21:56:17 -0600 (Fri, 27 Mar 2009) | 1 line
+Changed paths:
+ M /trunk/asymptote/base/bezulate.asy
+
+Fix connect() to ensure that removed regions do not contain an inner curve. Add fuzz to intersections().
+------------------------------------------------------------------------
+r4121 | jcbowman | 2009-03-24 21:47:57 -0600 (Tue, 24 Mar 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/three_surface.asy
+ M /trunk/asymptote/examples/intersectingpipes.asy
+
+Add surface constructor for multiple surfaces.
+
+------------------------------------------------------------------------
+r4120 | jcbowman | 2009-03-24 21:32:54 -0600 (Tue, 24 Mar 2009) | 4 lines
+Changed paths:
+ M /trunk/asymptote/doc/FAQ/asy-faq.bfnn
+ A /trunk/asymptote/examples/intersectingpipes.asy
+
+Add intersecting pipes example.
+
+Update FAQ.
+
+------------------------------------------------------------------------
+r4119 | jcbowman | 2009-03-23 03:23:19 -0600 (Mon, 23 Mar 2009) | 1 line
+Changed paths:
+ M /trunk/asymptote/configure.ac
+
+Increment version to 1.69svn.
+------------------------------------------------------------------------
+r4118 | jcbowman | 2009-03-23 02:07:01 -0600 (Mon, 23 Mar 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/asymptote.spec
+ M /trunk/asymptote/examples/logo3.asy
+
+Update example.
+
+------------------------------------------------------------------------
+r4117 | jcbowman | 2009-03-23 01:45:58 -0600 (Mon, 23 Mar 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/examples/filesurface.asy
+
+Illustrate automated camera and target computation.
+
+------------------------------------------------------------------------
+r4116 | jcbowman | 2009-03-23 01:37:23 -0600 (Mon, 23 Mar 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/examples/animations/inlinemovie.tex
+
+Remove unnecessary index.
+
+------------------------------------------------------------------------
+r4115 | jcbowman | 2009-03-23 01:34:42 -0600 (Mon, 23 Mar 2009) | 8 lines
+Changed paths:
+ M /trunk/asymptote/Makefile.in
+ M /trunk/asymptote/base/animation.asy
+ M /trunk/asymptote/doc/asymptote.sty
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/examples/animations/inlinemovie.tex
+ A /trunk/asymptote/examples/animations/inlinemovie3.tex
+ M /trunk/asymptote/examples/animations/pdfmovie.asy
+
+Add support for and example of generating a 3D inline pdf movie.
+
+Remove hyphen from animation file prefix for compatibility with animategraphics.
+
+Force multipage=true in inlinetex mode.
+
+Update definition of ASYanimategraphics.
+
+------------------------------------------------------------------------
+r4114 | jcbowman | 2009-03-23 00:31:06 -0600 (Mon, 23 Mar 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/glrender.cc
+ M /trunk/asymptote/glrender.h
+ M /trunk/asymptote/main.cc
+ M /trunk/asymptote/settings.h
+
+Fix export deadlock.
+
+------------------------------------------------------------------------
+r4113 | jcbowman | 2009-03-22 21:42:52 -0600 (Sun, 22 Mar 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/three.asy
+
+Don't automatically move camera with target.
+
+------------------------------------------------------------------------
+r4112 | jcbowman | 2009-03-22 12:12:52 -0600 (Sun, 22 Mar 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/examples/filesurface.asy
+
+Update example.
+
+------------------------------------------------------------------------
+r4111 | jcbowman | 2009-03-22 12:11:41 -0600 (Sun, 22 Mar 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/plain_picture.asy
+ M /trunk/asymptote/base/three.asy
+ M /trunk/asymptote/examples/smoothelevation.asy
+
+Fix camera adjustment.
+
+------------------------------------------------------------------------
+r4110 | jcbowman | 2009-03-21 23:54:54 -0600 (Sat, 21 Mar 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/texfile.h
+
+Allow \par in a label.
+
+------------------------------------------------------------------------
+r4109 | jcbowman | 2009-03-21 23:49:23 -0600 (Sat, 21 Mar 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+
+Update documentation.
+
+------------------------------------------------------------------------
+r4108 | jcbowman | 2009-03-21 23:07:42 -0600 (Sat, 21 Mar 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/graph.asy
+ M /trunk/asymptote/base/graph3.asy
+ M /trunk/asymptote/base/plain_strings.asy
+ M /trunk/asymptote/doc/asymptote.texi
+
+Improve and generalize baseline.
+
+------------------------------------------------------------------------
+r4107 | jcbowman | 2009-03-20 23:26:20 -0600 (Fri, 20 Mar 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/runtime.in
+
+Look for exact intersections also when fuzz=0.
+
+------------------------------------------------------------------------
+r4106 | jcbowman | 2009-03-20 22:42:10 -0600 (Fri, 20 Mar 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.sty
+
+Suppress spurious space.
+
+------------------------------------------------------------------------
+r4105 | jcbowman | 2009-03-20 22:28:18 -0600 (Fri, 20 Mar 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/bezulate.asy
+ M /trunk/asymptote/base/bsp.asy
+ M /trunk/asymptote/base/graph3.asy
+ M /trunk/asymptote/base/plain_Label.asy
+ M /trunk/asymptote/base/plain_arrows.asy
+ M /trunk/asymptote/base/plain_constants.asy
+ M /trunk/asymptote/base/plain_picture.asy
+ M /trunk/asymptote/base/solids.asy
+ M /trunk/asymptote/base/three.asy
+ M /trunk/asymptote/base/three_arrows.asy
+ M /trunk/asymptote/base/three_surface.asy
+ M /trunk/asymptote/base/tube.asy
+ M /trunk/asymptote/doc/asymptote.texi
+
+Standardize sqrtEpsilon.
+
+------------------------------------------------------------------------
+r4104 | jcbowman | 2009-03-20 22:15:40 -0600 (Fri, 20 Mar 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.sty
+
+Remove unused line.
+
+------------------------------------------------------------------------
+r4103 | jcbowman | 2009-03-20 22:14:19 -0600 (Fri, 20 Mar 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/path.cc
+ M /trunk/asymptote/path.h
+ M /trunk/asymptote/path3.cc
+ M /trunk/asymptote/path3.h
+ M /trunk/asymptote/runtime.in
+
+Improve handling of intersection fuzz.
+
+------------------------------------------------------------------------
+r4102 | jcbowman | 2009-03-20 14:57:34 -0600 (Fri, 20 Mar 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/three_light.asy
+
+Handle invisible material.
+
+------------------------------------------------------------------------
+r4101 | jcbowman | 2009-03-20 14:28:23 -0600 (Fri, 20 Mar 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/graph.asy
+
+Respect user-specified step value.
+
+------------------------------------------------------------------------
+r4100 | jcbowman | 2009-03-19 02:59:14 -0600 (Thu, 19 Mar 2009) | 1 line
+Changed paths:
+ M /trunk/asymptote/configure.ac
+
+Increment version to 1.68svn.
+------------------------------------------------------------------------
+r4099 | jcbowman | 2009-03-19 01:33:53 -0600 (Thu, 19 Mar 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/asymptote.spec
+ M /trunk/asymptote/base/animation.asy
+
+Fix 3D animations with render > 0.
+
+------------------------------------------------------------------------
+r4098 | jcbowman | 2009-03-19 00:40:40 -0600 (Thu, 19 Mar 2009) | 1 line
+Changed paths:
+ M /trunk/asymptote/Makefile.in
+ M /trunk/asymptote/asymptote.nsi
+
+Don't force C:\Documents and Settings\bowman in asy.bat
+------------------------------------------------------------------------
+r4097 | jcbowman | 2009-03-18 14:18:11 -0600 (Wed, 18 Mar 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/three_surface.asy
+
+Remove normal fuzz.
+
+------------------------------------------------------------------------
+r4096 | jcbowman | 2009-03-18 02:51:53 -0600 (Wed, 18 Mar 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/three_surface.asy
+
+Fix overlap detection internal control points for short paths.
+
+------------------------------------------------------------------------
+r4095 | jcbowman | 2009-03-18 01:23:56 -0600 (Wed, 18 Mar 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/runtime.in
+
+Add file missed from last revision.
+
+------------------------------------------------------------------------
+r4094 | jcbowman | 2009-03-18 01:01:08 -0600 (Wed, 18 Mar 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/path.cc
+ M /trunk/asymptote/path3.cc
+
+Make intersection routines respect fuzz.
+
+------------------------------------------------------------------------
+r4093 | jcbowman | 2009-03-15 17:20:04 -0600 (Sun, 15 Mar 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/three_surface.asy
+
+Simplify normal calculation slightly.
+
+------------------------------------------------------------------------
+r4092 | jcbowman | 2009-03-15 15:32:07 -0600 (Sun, 15 Mar 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/math.asy
+
+Reduce Fuzz.
+
+------------------------------------------------------------------------
+r4091 | jcbowman | 2009-03-15 15:01:04 -0600 (Sun, 15 Mar 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/examples/smoothelevation.asy
+
+Allow prc output if render > 0.
+
+------------------------------------------------------------------------
+r4090 | jcbowman | 2009-03-15 00:09:54 -0600 (Sun, 15 Mar 2009) | 3 lines
+Changed paths:
+ M /trunk/asymptote/base/three.asy
+ M /trunk/asymptote/settings.cc
+
+Implement settings.auto3D (default true) so that one can disable the poster
+option of movie15.sty.
+
+------------------------------------------------------------------------
+r4089 | jcbowman | 2009-03-15 00:05:14 -0600 (Sun, 15 Mar 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/three_surface.asy
+
+Increase fuzz.
+
+------------------------------------------------------------------------
+r4088 | jcbowman | 2009-03-14 23:23:00 -0600 (Sat, 14 Mar 2009) | 3 lines
+Changed paths:
+ M /trunk/asymptote/base/three_surface.asy
+
+Detect and fix remaining cases of patch overlap due to normal reversal,
+using Rolle's theorem and a quartic root solve.
+
+------------------------------------------------------------------------
+r4087 | jcbowman | 2009-03-14 23:09:29 -0600 (Sat, 14 Mar 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/math.asy
+
+Detect numerical roots at infinity; increase Fuzz.
+
+------------------------------------------------------------------------
+r4086 | jcbowman | 2009-03-14 23:00:31 -0600 (Sat, 14 Mar 2009) | 7 lines
+Changed paths:
+ M /trunk/asymptote/base/plain_paths.asy
+ M /trunk/asymptote/path.cc
+ M /trunk/asymptote/path.h
+ M /trunk/asymptote/path3.cc
+ M /trunk/asymptote/runtime.in
+
+Make subpath preserve straight flag; optimize splitCubic for straight segments.
+
+Fix handling of straight flag in operator &(path,cycleToken); do nothing if
+path is already cyclic.
+
+Implement pair versions of Bezier functions.
+
+------------------------------------------------------------------------
+r4085 | jcbowman | 2009-03-14 15:25:45 -0600 (Sat, 14 Mar 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/flatguide.h
+ M /trunk/asymptote/guide.h
+ M /trunk/asymptote/path.cc
+
+Fix segmentation faults with operations on guide g=cycle.
+
+------------------------------------------------------------------------
+r4084 | oshardt | 2009-03-14 11:49:45 -0600 (Sat, 14 Mar 2009) | 1 line
+Changed paths:
+ M /trunk/asymptote/base/bezulate.asy
+
+Speed up curve sorting.
+------------------------------------------------------------------------
+r4083 | jcbowman | 2009-03-13 15:02:45 -0600 (Fri, 13 Mar 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/plain_constants.asy
+ M /trunk/asymptote/base/plain_paths.asy
+
+Fix buildcycle endpoints.
+
+------------------------------------------------------------------------
+r4082 | oshardt | 2009-03-11 21:44:52 -0600 (Wed, 11 Mar 2009) | 1 line
+Changed paths:
+ M /trunk/asymptote/base/bezulate.asy
+
+Use bounding box size to determine whether points are duplicates.
+------------------------------------------------------------------------
+r4081 | jcbowman | 2009-03-11 01:47:57 -0600 (Wed, 11 Mar 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/three_arrows.asy
+
+Force planar flag for arrow construction.
+
+------------------------------------------------------------------------
+r4080 | jcbowman | 2009-03-11 01:33:51 -0600 (Wed, 11 Mar 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/plain_arrows.asy
+
+Remove another degenerate segment.
+
+------------------------------------------------------------------------
+r4079 | jcbowman | 2009-03-11 01:25:36 -0600 (Wed, 11 Mar 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/plain_arrows.asy
+
+Work around bezulate bug by removing degeneracy.
+
+------------------------------------------------------------------------
+r4078 | jcbowman | 2009-03-11 00:18:34 -0600 (Wed, 11 Mar 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/three_surface.asy
+
+Fix planar surfaces.
+
+------------------------------------------------------------------------
+r4077 | jcbowman | 2009-03-10 23:45:25 -0600 (Tue, 10 Mar 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/three_surface.asy
+ M /trunk/asymptote/doc/asymptote.texi
+
+Simplify surface constructors; update documentation.
+
+------------------------------------------------------------------------
+r4076 | jcbowman | 2009-03-10 22:23:19 -0600 (Tue, 10 Mar 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/doc/extra/intro.asy
+ M /trunk/asymptote/examples/logo3.asy
+ M /trunk/asymptote/examples/shellmethod.asy
+ M /trunk/asymptote/examples/shellsqrtx01.asy
+ M /trunk/asymptote/examples/slidedemo.asy
+ M /trunk/asymptote/examples/washermethod.asy
+ M /trunk/asymptote/examples/xxsq01.asy
+ M /trunk/asymptote/examples/xxsq01x-1.asy
+ M /trunk/asymptote/examples/xxsq01y.asy
+
+Update examples.
+
+------------------------------------------------------------------------
+r4075 | jcbowman | 2009-03-10 22:06:09 -0600 (Tue, 10 Mar 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/three.asy
+
+Enable poster mode only when there is no rendered preview image.
+
+------------------------------------------------------------------------
+r4074 | jcbowman | 2009-03-10 21:34:37 -0600 (Tue, 10 Mar 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/three_surface.asy
+
+Add termination tests.
+
+------------------------------------------------------------------------
+r4073 | jcbowman | 2009-03-10 21:34:12 -0600 (Tue, 10 Mar 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/bezulate.asy
+ M /trunk/asymptote/base/three.asy
+
+Increase bezulate fuzz; add termination tests.
+
+------------------------------------------------------------------------
+r4072 | jcbowman | 2009-03-10 14:04:32 -0600 (Tue, 10 Mar 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/plain_constants.asy
+ M /trunk/asymptote/base/pstoedit.asy
+ M /trunk/asymptote/doc/asymptote.texi
+
+Add Align constant.
+
+------------------------------------------------------------------------
+r4071 | jcbowman | 2009-03-10 02:54:16 -0600 (Tue, 10 Mar 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/three_surface.asy
+ M /trunk/asymptote/doc/asymptote.texi
+
+Fix most instances of selfoverlapping patches.
+
+------------------------------------------------------------------------
+r4070 | jcbowman | 2009-03-09 21:38:52 -0600 (Mon, 09 Mar 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/drawfill.cc
+ M /trunk/asymptote/pen.h
+ M /trunk/asymptote/psfile.cc
+ M /trunk/asymptote/psfile.h
+
+Make axial and radial shading respect -gray, etc.
+
+------------------------------------------------------------------------
+r4069 | jcbowman | 2009-03-09 00:07:48 -0600 (Mon, 09 Mar 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/runtime.in
+
+Fix texpath control points for cyclic segments; respect straight flag.
+
+------------------------------------------------------------------------
+r4068 | jcbowman | 2009-03-08 16:11:51 -0600 (Sun, 08 Mar 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/three_surface.asy
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/doc/generalaxis3.asy
+ M /trunk/asymptote/examples/Klein.asy
+ M /trunk/asymptote/examples/arrows3.asy
+
+Slightly simplify normal calculation.
+
+------------------------------------------------------------------------
+r4067 | jcbowman | 2009-03-08 12:03:26 -0600 (Sun, 08 Mar 2009) | 4 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.sty
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/doc/latexusage.tex
+
+Make default viewportwidth \the\linewidth in inline mode and 0 in attached mode.
+
+Document asy environment options in asymptote.sty version 1.04.
+
+------------------------------------------------------------------------
+r4066 | jcbowman | 2009-03-08 09:23:09 -0600 (Sun, 08 Mar 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/graph.asy
+ M /trunk/asymptote/examples/filesurface.asy
+
+Simplify tick calculation.
+
+------------------------------------------------------------------------
+r4065 | jcbowman | 2009-03-08 01:18:52 -0700 (Sun, 08 Mar 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/graph.asy
+ M /trunk/asymptote/examples/filesurface.asy
+
+Improve tick selection.
+
+------------------------------------------------------------------------
+r4064 | jcbowman | 2009-03-08 00:02:42 -0700 (Sun, 08 Mar 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/examples/filesurface.asy
+
+Colorize example.
+
+------------------------------------------------------------------------
+r4063 | jcbowman | 2009-03-07 20:17:56 -0700 (Sat, 07 Mar 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/examples/100d.views
+
+Reinstate original views.
+
+------------------------------------------------------------------------
+r4062 | jcbowman | 2009-03-07 20:10:03 -0700 (Sat, 07 Mar 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/plain_picture.asy
+ M /trunk/asymptote/base/three.asy
+ M /trunk/asymptote/examples/filesurface.asy
+
+Fix camera adjustment.
+
+------------------------------------------------------------------------
+r4061 | jcbowman | 2009-03-07 15:23:58 -0700 (Sat, 07 Mar 2009) | 7 lines
+Changed paths:
+ M /trunk/asymptote/base/plain_picture.asy
+ M /trunk/asymptote/base/three.asy
+ M /trunk/asymptote/doc/asymptote.sty
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/doc/latexusage.tex
+
+Support keyval options width, height, viewportwidth, viewportheight, and
+attach in asy environment asymptote.sty.
+
+Remove obsolete asyattach environment.
+
+Move viewportsize to plain_picture.asy to support asymptote.sty.
+
+------------------------------------------------------------------------
+r4060 | jcbowman | 2009-03-07 11:14:05 -0700 (Sat, 07 Mar 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/graph.asy
+ M /trunk/asymptote/base/graph3.asy
+
+Better fix for unextended axes limits.
+
+------------------------------------------------------------------------
+r4059 | jcbowman | 2009-03-07 09:10:37 -0700 (Sat, 07 Mar 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+
+Update documentation of crop.
+
+------------------------------------------------------------------------
+r4058 | jcbowman | 2009-03-07 01:46:18 -0700 (Sat, 07 Mar 2009) | 2 lines
+Changed paths:
+ A /trunk/asymptote/examples/filesurface.asy
+ A /trunk/asymptote/examples/filesurface.dat
+
+Add example of a surface drawn using irregular data read from a file.
+
+------------------------------------------------------------------------
+r4057 | jcbowman | 2009-03-07 01:23:39 -0700 (Sat, 07 Mar 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/graph.asy
+ M /trunk/asymptote/base/graph3.asy
+
+Revert last change.
+
+------------------------------------------------------------------------
+r4056 | jcbowman | 2009-03-07 00:07:03 -0700 (Sat, 07 Mar 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/graph.asy
+ M /trunk/asymptote/base/graph3.asy
+
+Fix unextended axes limits and tick generation.
+
+------------------------------------------------------------------------
+r4055 | jcbowman | 2009-03-06 23:45:35 -0700 (Fri, 06 Mar 2009) | 4 lines
+Changed paths:
+ M /trunk/asymptote/base/plain_picture.asy
+ M /trunk/asymptote/base/three.asy
+ M /trunk/asymptote/doc/asymptote.texi
+
+Avoid redundant camera adjustment messages.
+
+Increase camerafactor to 2 again.
+
+------------------------------------------------------------------------
+r4054 | jcbowman | 2009-03-06 23:19:49 -0700 (Fri, 06 Mar 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/graph.asy
+
+Check crop argument.
+
+------------------------------------------------------------------------
+r4053 | jcbowman | 2009-03-06 22:52:12 -0700 (Fri, 06 Mar 2009) | 4 lines
+Changed paths:
+ M /trunk/asymptote/base/plain_picture.asy
+ M /trunk/asymptote/base/three.asy
+
+Improve automatic camera adjustment: relocate target to the center of
+the bounding box, if it lies outside, and reposition camera when aspect
+ratio is not preserved.
+
+------------------------------------------------------------------------
+r4052 | jcbowman | 2009-03-06 00:14:45 -0700 (Fri, 06 Mar 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/three.asy
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/doc/latexusage.tex
+
+Allow the user to specify a minimum viewportsize.
+
+------------------------------------------------------------------------
+r4051 | jcbowman | 2009-03-06 00:06:16 -0700 (Fri, 06 Mar 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/graph.asy
+
+Use a single call to clip in limits.
+
+------------------------------------------------------------------------
+r4050 | jcbowman | 2009-03-05 23:56:25 -0700 (Thu, 05 Mar 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/graph.asy
+ M /trunk/asymptote/base/plain_picture.asy
+
+Fix behaviour of xlimits(Crop) and ylimits(Crop) under picture transformation.
+
+------------------------------------------------------------------------
+r4049 | jcbowman | 2009-03-04 02:44:31 -0700 (Wed, 04 Mar 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/plain_picture.asy
+
+Increase camerafactor.
+
+------------------------------------------------------------------------
+r4048 | jcbowman | 2009-03-04 02:18:49 -0700 (Wed, 04 Mar 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/plain_picture.asy
+ M /trunk/asymptote/base/three.asy
+ M /trunk/asymptote/doc/generalaxis3.asy
+ M /trunk/asymptote/examples/100d.views
+ M /trunk/asymptote/examples/Klein.asy
+ M /trunk/asymptote/examples/pdb.asy
+
+Improve automatic camera adjustment.
+
+------------------------------------------------------------------------
+r4047 | jcbowman | 2009-03-04 01:09:19 -0700 (Wed, 04 Mar 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/glrender.cc
+
+Work around intermittent hang on exit.
+
+------------------------------------------------------------------------
+r4046 | jcbowman | 2009-03-03 01:19:52 -0700 (Tue, 03 Mar 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/three.asy
+ M /trunk/asymptote/doc/asymptote.sty
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/doc/latexusage.tex
+
+Make attached images printable.
+
+------------------------------------------------------------------------
+r4045 | jcbowman | 2009-03-02 18:03:03 -0700 (Mon, 02 Mar 2009) | 6 lines
+Changed paths:
+ M /trunk/asymptote/base/three.asy
+
+Turn poster off when we have our own preview image.
+
+Fix viewportmargin.
+
+Remove unwanted camera rescaling.
+
+------------------------------------------------------------------------
+r4044 | jcbowman | 2009-03-02 17:49:36 -0700 (Mon, 02 Mar 2009) | 5 lines
+Changed paths:
+ M /trunk/asymptote/base/embed.asy
+
+Fix spurious annotation question marks and print preview problems
+by removing workaround for BBox bug in obsolete 2008/01/16 version of
+movie15.sty. The now widely available 2008/10/08 version of movie15.sty is
+now compulsory.
+
+------------------------------------------------------------------------
+r4043 | jcbowman | 2009-03-02 14:45:00 -0700 (Mon, 02 Mar 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/graph.asy
+ M /trunk/asymptote/base/graph3.asy
+
+Fix slanted ticks.
+
+------------------------------------------------------------------------
+r4042 | jcbowman | 2009-03-01 22:58:58 -0700 (Sun, 01 Mar 2009) | 1 line
+Changed paths:
+ M /trunk/asymptote/base/animation.asy
+
+Fix animation prefix.
+------------------------------------------------------------------------
+r4041 | jcbowman | 2009-03-01 16:32:54 -0700 (Sun, 01 Mar 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/three_arrows.asy
+
+Fix planar arrows for 2D projections.
+
+------------------------------------------------------------------------
+r4040 | jcbowman | 2009-03-01 16:01:58 -0700 (Sun, 01 Mar 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/three.asy
+
+Allow one to disable poster option.
+
+------------------------------------------------------------------------
+r4039 | jcbowman | 2009-02-27 16:32:54 -0700 (Fri, 27 Feb 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/examples/arrows3.asy
+
+Resize example.
+
+------------------------------------------------------------------------
+r4038 | jcbowman | 2009-02-27 14:43:51 -0700 (Fri, 27 Feb 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/runtime.in
+
+Don't hide convert errors.
+
+------------------------------------------------------------------------
+r4037 | jcbowman | 2009-02-26 22:09:51 -0700 (Thu, 26 Feb 2009) | 2 lines
+Changed paths:
+ A /trunk/asymptote/examples/fin.asy
+
+Add example (contributed by Orest Shardt).
+
+------------------------------------------------------------------------
+r4036 | jcbowman | 2009-02-26 16:23:44 -0700 (Thu, 26 Feb 2009) | 1 line
+Changed paths:
+ M /trunk/asymptote/configure.ac
+
+Increment version to 1.67svn.
+------------------------------------------------------------------------
+r4035 | jcbowman | 2009-02-26 15:00:38 -0700 (Thu, 26 Feb 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/asymptote.spec
+ M /trunk/asymptote/base/animation.asy
+
+Fix outprefix.
+
+------------------------------------------------------------------------
+r4034 | jcbowman | 2009-02-26 09:01:58 -0700 (Thu, 26 Feb 2009) | 4 lines
+Changed paths:
+ M /trunk/asymptote/base/animation.asy
+ M /trunk/asymptote/runtime.in
+
+Remove animation optimization by default.
+
+Under MSWindows, suppress call to animate since it requires XWindows.
+
+------------------------------------------------------------------------
+r4033 | jcbowman | 2009-02-26 07:50:25 -0700 (Thu, 26 Feb 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/animation.asy
+ M /trunk/asymptote/base/three_arrows.asy
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/examples/RiemannSurface.asy
+ A /trunk/asymptote/examples/RiemannSurfaceRoot.asy
+
+Add optional direction argument to three-dimensional bars.
+
+------------------------------------------------------------------------
+r4032 | jcbowman | 2009-02-26 07:45:58 -0700 (Thu, 26 Feb 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/palette.asy
+
+Avoid division by zero when NColors=1.
+
+------------------------------------------------------------------------
+r4031 | jcbowman | 2009-02-26 05:45:26 -0700 (Thu, 26 Feb 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/texfile.h
+
+Fix alignment bug under pdflatex due to missing %.
+
+------------------------------------------------------------------------
+r4030 | jcbowman | 2009-02-25 22:04:31 -0700 (Wed, 25 Feb 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/examples/tvgen.asy
+
+Change guides into paths; update to LGPL.
+
+------------------------------------------------------------------------
+r4029 | jcbowman | 2009-02-25 16:21:27 -0700 (Wed, 25 Feb 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/plain_markers.asy
+
+Use integer division.
+
+------------------------------------------------------------------------
+r4028 | jcbowman | 2009-02-25 16:07:20 -0700 (Wed, 25 Feb 2009) | 4 lines
+Changed paths:
+ M /trunk/asymptote/exp.cc
+ M /trunk/asymptote/exp.h
+
+Remove "named argument may be mistaken for assignment" debugging warning as
+it discourages the use of named arguments and detracts from the usefulness of
+the -d option.
+
+------------------------------------------------------------------------
+r4027 | jcbowman | 2009-02-25 15:06:21 -0700 (Wed, 25 Feb 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/contour.asy
+
+Revert to interpolating function at midpoints.
+
+------------------------------------------------------------------------
+r4026 | jcbowman | 2009-02-24 09:51:11 -0700 (Tue, 24 Feb 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/three_arrows.asy
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/examples/arrows3.asy
+
+Add optional normal argument to DefaultHead2, HookHead2, and TeXHead2.
+
+------------------------------------------------------------------------
+r4025 | jcbowman | 2009-02-24 00:47:00 -0700 (Tue, 24 Feb 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/three_arrows.asy
+
+Fix Arrow3(TeXHead2).
+
+------------------------------------------------------------------------
+r4024 | jcbowman | 2009-02-24 00:35:08 -0700 (Tue, 24 Feb 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/plain_arrows.asy
+ M /trunk/asymptote/base/three_arrows.asy
+ M /trunk/asymptote/examples/arrows3.asy
+
+Fix alignment of DefaultHead2, HookHead2, and TeXHead2 arrowheads.
+
+------------------------------------------------------------------------
+r4023 | jcbowman | 2009-02-23 00:36:02 -0700 (Mon, 23 Feb 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/three_arrows.asy
+
+Improve thin 3D arrow handling.
+
+------------------------------------------------------------------------
+r4022 | jcbowman | 2009-02-22 23:01:42 -0700 (Sun, 22 Feb 2009) | 7 lines
+Changed paths:
+ M /trunk/asymptote/base/geometry.asy
+ M /trunk/asymptote/base/markers.asy
+ M /trunk/asymptote/base/patterns.asy
+ M /trunk/asymptote/base/plain_arrows.asy
+ M /trunk/asymptote/base/plain_boxes.asy
+ M /trunk/asymptote/base/plain_filldraw.asy
+ M /trunk/asymptote/base/plain_markers.asy
+ M /trunk/asymptote/base/three_arrows.asy
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/examples/arrows3.asy
+
+Make filltype a structure to allow extraction of type and pen parameters.
+
+Improve the appearance of DefaultHead2, HookHead2, and TeXHead2 (particularly
+with curved paths); standardize their usage with their 2D counterparts.
+
+Fix MidArcArrow(TeXHead) sizing.
+
+------------------------------------------------------------------------
+r4021 | jcbowman | 2009-02-22 20:32:38 -0700 (Sun, 22 Feb 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/FAQ/asy-faq.bfnn
+
+Untabify.
+
+------------------------------------------------------------------------
+r4020 | jcbowman | 2009-02-21 20:30:41 -0700 (Sat, 21 Feb 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/asy-mode.el
+
+Upgrade license to LPGL, as per email from Philippe.
+
+------------------------------------------------------------------------
+r4019 | jcbowman | 2009-02-21 16:39:27 -0700 (Sat, 21 Feb 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/three_arrows.asy
+ M /trunk/asymptote/examples/arrows3.asy
+
+Retune 3D arrow parameters.
+
+------------------------------------------------------------------------
+r4018 | jcbowman | 2009-02-21 16:03:22 -0700 (Sat, 21 Feb 2009) | 3 lines
+Changed paths:
+ A /trunk/asymptote/LICENSE.LESSER (from /trunk/asymptote/prc/LICENSE.LESSER:4016)
+ M /trunk/asymptote/fftw++.h
+ M /trunk/asymptote/main.cc
+ M /trunk/asymptote/pipestream.h
+ D /trunk/asymptote/prc/LICENSE.LESSER
+ M /trunk/asymptote/xstream.h
+
+Upgrade global license from GPL to LPGL (except as noted within individual
+files).
+
+------------------------------------------------------------------------
+r4017 | jcbowman | 2009-02-21 15:37:09 -0700 (Sat, 21 Feb 2009) | 2 lines
+Changed paths:
+ D /trunk/asymptote/base/featpost3D.asy
+ M /trunk/asymptote/doc/asymptote.texi
+
+Remove obsolete featpost3D.asy module.
+
+------------------------------------------------------------------------
+r4016 | jcbowman | 2009-02-21 14:56:33 -0700 (Sat, 21 Feb 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/plain_picture.asy
+ M /trunk/asymptote/base/three.asy
+ M /trunk/asymptote/doc/asymptote.texi
+
+Add bool autoadjust=true argument to perspective projection constructors.
+
+------------------------------------------------------------------------
+r4015 | jcbowman | 2009-02-21 12:26:15 -0700 (Sat, 21 Feb 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/plain_arrows.asy
+
+Fix TeXHead alignment for curved arrows along with endpoint appearance.
+
+------------------------------------------------------------------------
+r4014 | jcbowman | 2009-02-21 10:46:29 -0700 (Sat, 21 Feb 2009) | 3 lines
+Changed paths:
+ M /trunk/asymptote/base/plain_picture.asy
+ M /trunk/asymptote/base/three.asy
+
+Add autoadjust flag to projections to disable automatic camera adjustment
+(for experts only).
+
+------------------------------------------------------------------------
+r4013 | jcbowman | 2009-02-21 10:28:25 -0700 (Sat, 21 Feb 2009) | 7 lines
+Changed paths:
+ M /trunk/asymptote/base/plain_picture.asy
+ M /trunk/asymptote/base/solids.asy
+
+Fix transverse vs. longitudinal typo.
+
+Add slight hysteresis to camera adjustment.
+
+Always notify user if camera is moved, as transverse and longitudinal
+slices will have to be (manually) recomputed using the new camera position.
+
+------------------------------------------------------------------------
+r4012 | jcbowman | 2009-02-21 03:05:32 -0700 (Sat, 21 Feb 2009) | 2 lines
+Changed paths:
+ A /trunk/asymptote/examples/arrows3.asy
+
+Add 3D arrows example.
+
+------------------------------------------------------------------------
+r4011 | jcbowman | 2009-02-21 02:21:58 -0700 (Sat, 21 Feb 2009) | 6 lines
+Changed paths:
+ M /trunk/asymptote/base/three_arrows.asy
+ M /trunk/asymptote/doc/FAQ/asy-faq.bfnn
+
+Fix appearance of TeXHead3 on curved paths.
+
+Fix alignment of DefaultHead2, HookHead2, and TeXHead2 arrows.
+
+Pass arrowheadpen to 2D arrow routines when settings.render=0.
+
+------------------------------------------------------------------------
+r4010 | jcbowman | 2009-02-20 17:30:32 -0700 (Fri, 20 Feb 2009) | 4 lines
+Changed paths:
+ M /trunk/asymptote/base/plain_picture.asy
+ M /trunk/asymptote/base/three.asy
+ M /trunk/asymptote/doc/asymptote.texi
+
+Use abs(camera-target) rather than just the z component for camera adjustment.
+
+Add showtarget parameter to projections.
+
+------------------------------------------------------------------------
+r4009 | oshardt | 2009-02-19 20:14:42 -0700 (Thu, 19 Feb 2009) | 1 line
+Changed paths:
+ M /trunk/asymptote/base/three_arrows.asy
+
+Improve selecton of perpendicular vector.
+------------------------------------------------------------------------
+r4008 | jcbowman | 2009-02-19 16:46:20 -0700 (Thu, 19 Feb 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+
+Fix typo.
+
+------------------------------------------------------------------------
+r4007 | jcbowman | 2009-02-19 11:00:11 -0700 (Thu, 19 Feb 2009) | 1 line
+Changed paths:
+ M /trunk/asymptote/asymptote.spec
+ M /trunk/asymptote/configure.ac
+
+Increment version to 1.66svn.
+------------------------------------------------------------------------
+r4006 | jcbowman | 2009-02-19 09:33:22 -0700 (Thu, 19 Feb 2009) | 6 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/drawclipend.h
+ M /trunk/asymptote/settings.cc
+ M /trunk/asymptote/settings.h
+ M /trunk/asymptote/texfile.cc
+
+Fix pdflatex output.
+
+Implement xelatex engine.
+
+Fix xelatex alignment.
+
+------------------------------------------------------------------------
+r4005 | jcbowman | 2009-02-19 01:19:28 -0700 (Thu, 19 Feb 2009) | 1 line
+Changed paths:
+ M /trunk/asymptote/configure.ac
+
+Increment version to 1.65svn
+------------------------------------------------------------------------
+r4004 | jcbowman | 2009-02-19 00:24:03 -0700 (Thu, 19 Feb 2009) | 4 lines
+Changed paths:
+ M /trunk/asymptote/Makefile.in
+ M /trunk/asymptote/base/plain_shipout.asy
+
+Force shipped=true also for pictures.
+
+Install *.view files.
+
+------------------------------------------------------------------------
+r4003 | jcbowman | 2009-02-18 23:13:31 -0700 (Wed, 18 Feb 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/asymptote.spec
+ M /trunk/asymptote/base/slide.asy
+
+Change default value of ysize parameter of asyinclude.
+
+------------------------------------------------------------------------
+r4002 | jcbowman | 2009-02-18 23:08:44 -0700 (Wed, 18 Feb 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+ A /trunk/asymptote/examples/100d.views
+ A /trunk/asymptote/examples/cpkcolors.asy
+ A /trunk/asymptote/examples/pdb.asy
+
+Add Protein Data Bank example that illustrates how to set predefined views.
+
+------------------------------------------------------------------------
+r4001 | jcbowman | 2009-02-18 22:13:48 -0700 (Wed, 18 Feb 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/three.asy
+
+Change dots to underscores in movie15.sty file names.
+
+------------------------------------------------------------------------
+r4000 | jcbowman | 2009-02-18 21:03:22 -0700 (Wed, 18 Feb 2009) | 2 lines
+Changed paths:
+ A /trunk/asymptote/prc/LICENSE.LESSER
+
+Add text of LGPL license for PRC code; LICENSE is in parent directory.
+
+------------------------------------------------------------------------
+r3999 | jcbowman | 2009-02-18 21:01:08 -0700 (Wed, 18 Feb 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/prc/PRCTools/bitData.cc
+ M /trunk/asymptote/prc/PRCTools/bitData.h
+ M /trunk/asymptote/prc/PRCTools/bitSearchDouble.cc
+ M /trunk/asymptote/prc/PRCTools/bitSearchUI.cc
+ M /trunk/asymptote/prc/PRCTools/describeMain.cc
+ M /trunk/asymptote/prc/PRCTools/describePRC.cc
+ M /trunk/asymptote/prc/PRCTools/describePRC.h
+ M /trunk/asymptote/prc/PRCTools/extractSections.cc
+ M /trunk/asymptote/prc/PRCTools/iPRCFile.cc
+ M /trunk/asymptote/prc/PRCTools/iPRCFile.h
+ M /trunk/asymptote/prc/PRCTools/inflation.cc
+ M /trunk/asymptote/prc/PRCTools/inflation.h
+ M /trunk/asymptote/prc/PRCTools/inflationMain.cc
+ M /trunk/asymptote/prc/PRCTools/makePRC.cc
+ M /trunk/asymptote/prc/PRCbitStream.cc
+ M /trunk/asymptote/prc/PRCbitStream.h
+ M /trunk/asymptote/prc/oPRCFile.cc
+ M /trunk/asymptote/prc/oPRCFile.h
+ M /trunk/asymptote/prc/test.cc
+ M /trunk/asymptote/prc/writePRC.cc
+ M /trunk/asymptote/prc/writePRC.h
+
+Upgrade license of PRC code from GPL to LGPL (agreed to by Orest).
+
+------------------------------------------------------------------------
+r3998 | jcbowman | 2009-02-18 20:27:47 -0700 (Wed, 18 Feb 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/FAQ/asy-faq.bfnn
+
+Update FAQ.
+
+------------------------------------------------------------------------
+r3997 | jcbowman | 2009-02-18 19:38:33 -0700 (Wed, 18 Feb 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/extra/intro.asy
+
+Fix file path.
+
+------------------------------------------------------------------------
+r3996 | jcbowman | 2009-02-18 19:32:41 -0700 (Wed, 18 Feb 2009) | 4 lines
+Changed paths:
+ M /trunk/asymptote/base/slide.asy
+ M /trunk/asymptote/doc/GaussianSurface.asy
+ M /trunk/asymptote/doc/extra/intro.asy
+ M /trunk/asymptote/examples/slidedemo.asy
+
+Add interactive 3D examples to intro.asy.
+
+Make GaussianSurface smooth.
+
+------------------------------------------------------------------------
+r3995 | jcbowman | 2009-02-18 15:06:16 -0700 (Wed, 18 Feb 2009) | 4 lines
+Changed paths:
+ M /trunk/asymptote/base/animation.asy
+
+Strip directory from animation prefix.
+
+Don't delete generated animation.pdf file.
+
+------------------------------------------------------------------------
+r3994 | jcbowman | 2009-02-18 07:58:32 -0700 (Wed, 18 Feb 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/settings.cc
+
+Add support for xelatex pdf specials, using the "literal" keyword.
+
+------------------------------------------------------------------------
+r3993 | jcbowman | 2009-02-18 07:38:48 -0700 (Wed, 18 Feb 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/examples/slidedemo.asy
+
+Generate PythagoreanTree if needed.
+
+------------------------------------------------------------------------
+r3992 | jcbowman | 2009-02-17 21:34:10 -0700 (Tue, 17 Feb 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/three.asy
+
+Don't force target to be part of control volume for absolute projections.
+
+------------------------------------------------------------------------
+r3991 | jcbowman | 2009-02-17 21:25:41 -0700 (Tue, 17 Feb 2009) | 1 line
+Changed paths:
+ M /trunk/asymptote/configure.ac
+
+Increment version to 1.64svn.
+------------------------------------------------------------------------
+r3990 | jcbowman | 2009-02-17 19:51:20 -0700 (Tue, 17 Feb 2009) | 4 lines
+Changed paths:
+ M /trunk/asymptote/base/three.asy
+
+Force the target position to be inside the bounding volume.
+
+Remove duplicate definition of rectify(triple).
+
+------------------------------------------------------------------------
+r3989 | jcbowman | 2009-02-17 16:37:06 -0700 (Tue, 17 Feb 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/three_surface.asy
+
+Fix handling of invisible surfaces.
+
+------------------------------------------------------------------------
+r3988 | jcbowman | 2009-02-17 09:07:42 -0700 (Tue, 17 Feb 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/glrender.cc
+ M /trunk/asymptote/picture.cc
+
+Fix synchronization of interactive rendering.
+
+------------------------------------------------------------------------
+r3987 | jcbowman | 2009-02-17 01:05:33 -0700 (Tue, 17 Feb 2009) | 7 lines
+Changed paths:
+ M /trunk/asymptote/asymptote.spec
+ M /trunk/asymptote/base/embed.asy
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/drawelement.h
+ M /trunk/asymptote/patches/README
+ A /trunk/asymptote/patches/movie15_dvipdfmx.sty
+ M /trunk/asymptote/picture.cc
+ M /trunk/asymptote/texfile.cc
+ M /trunk/asymptote/texfile.h
+
+Avoid spurious xelatex warning messages due to null (placeholder) graphics
+files.
+
+Add patched version of movie15.sty for xelatex users' convenience.
+
+Simplify embed.asy.
+
+------------------------------------------------------------------------
+r3986 | jcbowman | 2009-02-17 00:30:54 -0700 (Tue, 17 Feb 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/contour.asy
+
+Improve guide collection for non-midpoint case.
+
+------------------------------------------------------------------------
+r3985 | jcbowman | 2009-02-15 12:20:10 -0700 (Sun, 15 Feb 2009) | 6 lines
+Changed paths:
+ M /trunk/asymptote/base/contour.asy
+ M /trunk/asymptote/base/contour3.asy
+ M /trunk/asymptote/doc/asymptote.texi
+
+Generalize definition of middle to arbitrary quadrilaterals.
+
+Avoid need for interpolating function at cell midpoint; use 2 triangles instead.
+
+Use nmesh instead of (poorly named) ncell parameter for 3D contours.
+
+------------------------------------------------------------------------
+r3984 | jcbowman | 2009-02-15 12:13:24 -0700 (Sun, 15 Feb 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/glrender.cc
+
+Handle degenerate and nondegenerate rendering consistently.
+
+------------------------------------------------------------------------
+r3983 | jcbowman | 2009-02-14 11:22:48 -0700 (Sat, 14 Feb 2009) | 4 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/examples/gamma3.asy
+ M /trunk/asymptote/examples/slidedemo.asy
+ M /trunk/asymptote/runtime.in
+
+Implement complex gamma function in C++ code.
+
+Add interactive 3D surface of revolution example to slidedemo.
+
+------------------------------------------------------------------------
+r3982 | jcbowman | 2009-02-14 09:58:01 -0700 (Sat, 14 Feb 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/three.asy
+
+Disable graphic generation when view=true.
+
+------------------------------------------------------------------------
+r3981 | jcbowman | 2009-02-13 00:10:23 -0700 (Fri, 13 Feb 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/embed.asy
+ M /trunk/asymptote/patches/README
+ A /trunk/asymptote/patches/movie15_dvipdfmx.patch
+
+Add 3D (and other multimedia) support for xelatex.
+
+------------------------------------------------------------------------
+r3980 | jcbowman | 2009-02-12 23:54:37 -0700 (Thu, 12 Feb 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/plain_shipout.asy
+
+Improve pdf format detection.
+
+------------------------------------------------------------------------
+r3979 | jcbowman | 2009-02-12 23:49:37 -0700 (Thu, 12 Feb 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/three.asy
+
+Fix preview generation.
+
+------------------------------------------------------------------------
+r3978 | jcbowman | 2009-02-12 22:42:05 -0700 (Thu, 12 Feb 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/slide.asy
+ M /trunk/asymptote/base/three.asy
+
+Automatically include rendered images when fitting nonprc pictures.
+
+------------------------------------------------------------------------
+r3977 | jcbowman | 2009-02-11 23:24:54 -0700 (Wed, 11 Feb 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/patches/pstoedit-3.45asy.patch
+
+Patch compilation errors in pstoedit-3.45.
+
+------------------------------------------------------------------------
+r3976 | jcbowman | 2009-02-11 23:16:52 -0700 (Wed, 11 Feb 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/graph.asy
+ M /trunk/asymptote/base/plain_arrows.asy
+ M /trunk/asymptote/base/plain_picture.asy
+ M /trunk/asymptote/base/stats.asy
+ M /trunk/asymptote/base/three.asy
+ M /trunk/asymptote/doc/FAQ/asy-faq.bfnn
+ M /trunk/asymptote/doc/log2graph.asy
+ M /trunk/asymptote/examples/electromagnetic.asy
+ M /trunk/asymptote/examples/logdown.asy
+
+Replace old-style constructors with operator init.
+
+------------------------------------------------------------------------
+r3975 | jcbowman | 2009-02-11 22:01:19 -0700 (Wed, 11 Feb 2009) | 4 lines
+Changed paths:
+ M /trunk/asymptote/base/graph.asy
+ M /trunk/asymptote/doc/log2graph.asy
+ A /trunk/asymptote/examples/electromagnetic.asy
+
+Add electromagnetic spectrum.
+
+Make minor ticks work properly with custom logarithmic axes.
+
+------------------------------------------------------------------------
+r3974 | jcbowman | 2009-02-11 16:17:38 -0700 (Wed, 11 Feb 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/castop.h
+ M /trunk/asymptote/doc/filegraph.dat
+
+Don't report error on eof after reading 0 values from file.
+
+------------------------------------------------------------------------
+r3973 | jcbowman | 2009-02-11 15:55:26 -0700 (Wed, 11 Feb 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/plain_markers.asy
+
+Handle one-column legends correctly (patch contributed by Martin Wiebusch).
+
+------------------------------------------------------------------------
+r3972 | jcbowman | 2009-02-11 15:33:45 -0700 (Wed, 11 Feb 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/pstoedit.asy
+ A /trunk/asymptote/examples/RiemannSurface.asy
+ M /trunk/asymptote/examples/logdown.asy
+
+Fix pstoedit support: remove duplicate beginclip/endclip functions.
+
+------------------------------------------------------------------------
+r3971 | jcbowman | 2009-02-11 00:29:52 -0700 (Wed, 11 Feb 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+
+Update unicode documentation.
+
+------------------------------------------------------------------------
+r3970 | jcbowman | 2009-02-10 23:22:23 -0700 (Tue, 10 Feb 2009) | 4 lines
+Changed paths:
+ M /trunk/asymptote/texfile.cc
+ M /trunk/asymptote/texfile.h
+
+Support xelatex again. Note that this experimental tex engine does not yet
+support pdf specials (required for label clipping and label transforms)
+or the movie15 package (required for 3D PDF files).
+
+------------------------------------------------------------------------
+r3969 | jcbowman | 2009-02-09 00:16:59 -0700 (Mon, 09 Feb 2009) | 1 line
+Changed paths:
+ M /trunk/asymptote/asymptote.spec
+ M /trunk/asymptote/configure.ac
+
+Increment version to 1.63svn.
+------------------------------------------------------------------------
+r3968 | jcbowman | 2009-02-08 23:00:12 -0700 (Sun, 08 Feb 2009) | 3 lines
+Changed paths:
+ M /trunk/asymptote/base/plain_pens.asy
+ M /trunk/asymptote/doc/asymptote.texi
+
+Implement a pen rgb(string s) routine that returns a pen corresponding to a
+given 6-character RGB hexidecimal string.
+
+------------------------------------------------------------------------
+r3967 | jcbowman | 2009-02-08 22:14:02 -0700 (Sun, 08 Feb 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/Delaunay.cc
+ M /trunk/asymptote/Delaunay.h
+ M /trunk/asymptote/absyn.h
+ M /trunk/asymptote/access.cc
+ M /trunk/asymptote/application.cc
+ M /trunk/asymptote/application.h
+ M /trunk/asymptote/arrayop.h
+ M /trunk/asymptote/bbox.h
+ M /trunk/asymptote/bbox3.h
+ M /trunk/asymptote/builtin.cc
+ M /trunk/asymptote/builtin.h
+ M /trunk/asymptote/castop.h
+ M /trunk/asymptote/coder.cc
+ M /trunk/asymptote/coder.h
+ M /trunk/asymptote/coenv.cc
+ M /trunk/asymptote/constructor.cc
+ M /trunk/asymptote/dec.cc
+ M /trunk/asymptote/dec.h
+ M /trunk/asymptote/drawclipbegin.h
+ M /trunk/asymptote/drawelement.h
+ M /trunk/asymptote/drawfill.cc
+ M /trunk/asymptote/drawfill.h
+ M /trunk/asymptote/drawimage.h
+ M /trunk/asymptote/drawlabel.cc
+ M /trunk/asymptote/drawlabel.h
+ M /trunk/asymptote/drawpath.cc
+ M /trunk/asymptote/drawpath3.cc
+ M /trunk/asymptote/drawpath3.h
+ M /trunk/asymptote/drawsurface.cc
+ M /trunk/asymptote/drawsurface.h
+ M /trunk/asymptote/drawverbatim.h
+ M /trunk/asymptote/entry.cc
+ M /trunk/asymptote/entry.h
+ M /trunk/asymptote/env.cc
+ M /trunk/asymptote/env.h
+ M /trunk/asymptote/errormsg.h
+ M /trunk/asymptote/exp.cc
+ M /trunk/asymptote/exp.h
+ M /trunk/asymptote/fftw++.h
+ M /trunk/asymptote/fileio.cc
+ M /trunk/asymptote/fileio.h
+ M /trunk/asymptote/frame.h
+ M /trunk/asymptote/fundec.cc
+ M /trunk/asymptote/fundec.h
+ M /trunk/asymptote/genv.cc
+ M /trunk/asymptote/getopt.h
+ M /trunk/asymptote/glrender.h
+ M /trunk/asymptote/guide.cc
+ M /trunk/asymptote/interact.cc
+ M /trunk/asymptote/item.h
+ M /trunk/asymptote/knot.cc
+ M /trunk/asymptote/knot.h
+ M /trunk/asymptote/locate.cc
+ M /trunk/asymptote/main.cc
+ M /trunk/asymptote/mathop.h
+ M /trunk/asymptote/memory.h
+ M /trunk/asymptote/name.cc
+ M /trunk/asymptote/newexp.cc
+ M /trunk/asymptote/newexp.h
+ M /trunk/asymptote/pair.h
+ M /trunk/asymptote/parser.cc
+ M /trunk/asymptote/parser.h
+ M /trunk/asymptote/path.cc
+ M /trunk/asymptote/path.h
+ M /trunk/asymptote/path3.cc
+ M /trunk/asymptote/path3.h
+ M /trunk/asymptote/pen.h
+ M /trunk/asymptote/picture.cc
+ M /trunk/asymptote/picture.h
+ M /trunk/asymptote/pipestream.h
+ M /trunk/asymptote/prcfile.h
+ M /trunk/asymptote/predicates.h
+ M /trunk/asymptote/process.cc
+ M /trunk/asymptote/process.h
+ M /trunk/asymptote/program.cc
+ M /trunk/asymptote/program.h
+ M /trunk/asymptote/psfile.cc
+ M /trunk/asymptote/psfile.h
+ M /trunk/asymptote/refaccess.cc
+ M /trunk/asymptote/refaccess.h
+ M /trunk/asymptote/runtime.in
+ M /trunk/asymptote/settings.cc
+ M /trunk/asymptote/simpson.cc
+ M /trunk/asymptote/stack.cc
+ M /trunk/asymptote/stack.h
+ M /trunk/asymptote/stm.cc
+ M /trunk/asymptote/stm.h
+ M /trunk/asymptote/symbol.h
+ M /trunk/asymptote/texfile.cc
+ M /trunk/asymptote/texfile.h
+ M /trunk/asymptote/transform.h
+ M /trunk/asymptote/triple.h
+ M /trunk/asymptote/types.cc
+ M /trunk/asymptote/types.h
+ M /trunk/asymptote/util.cc
+ M /trunk/asymptote/util.h
+ M /trunk/asymptote/varinit.cc
+ M /trunk/asymptote/varinit.h
+ M /trunk/asymptote/xstream.h
+
+Reformat C++ files.
+
+------------------------------------------------------------------------
+r3966 | jcbowman | 2009-02-08 21:22:15 -0700 (Sun, 08 Feb 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/CAD.asy
+ M /trunk/asymptote/base/animation.asy
+ M /trunk/asymptote/base/bezulate.asy
+ M /trunk/asymptote/base/contour.asy
+ M /trunk/asymptote/base/contour3.asy
+ M /trunk/asymptote/base/embed.asy
+ M /trunk/asymptote/base/external.asy
+ M /trunk/asymptote/base/flowchart.asy
+ M /trunk/asymptote/base/graph.asy
+ M /trunk/asymptote/base/graph3.asy
+ M /trunk/asymptote/base/grid3.asy
+ M /trunk/asymptote/base/markers.asy
+ M /trunk/asymptote/base/math.asy
+ M /trunk/asymptote/base/obj.asy
+ M /trunk/asymptote/base/ode.asy
+ M /trunk/asymptote/base/palette.asy
+ M /trunk/asymptote/base/patterns.asy
+ M /trunk/asymptote/base/plain.asy
+ M /trunk/asymptote/base/plain_Label.asy
+ M /trunk/asymptote/base/plain_arrows.asy
+ M /trunk/asymptote/base/plain_paths.asy
+
+Reformat and untabify base files.
+
+------------------------------------------------------------------------
+r3965 | jcbowman | 2009-02-08 10:19:04 -0700 (Sun, 08 Feb 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/plain_markers.asy
+ M /trunk/asymptote/base/plain_paths.asy
+ M /trunk/asymptote/doc/asymptote.texi
+
+Add Label arguments to more of the dot routines.
+
+------------------------------------------------------------------------
+r3964 | jcbowman | 2009-02-07 13:08:26 -0700 (Sat, 07 Feb 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/plain_markers.asy
+ M /trunk/asymptote/doc/asymptote.texi
+ A /trunk/asymptote/examples/markregular.asy
+
+Add parametric version of markuniform.
+
+------------------------------------------------------------------------
+r3963 | jcbowman | 2009-02-06 23:41:46 -0700 (Fri, 06 Feb 2009) | 3 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/runtime.in
+
+Implement int hex(string s) function that casts a hexidecimal string to an
+integer.
+
+------------------------------------------------------------------------
+r3962 | jcbowman | 2009-02-06 19:04:56 -0700 (Fri, 06 Feb 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/plain_markers.asy
+
+Add default picture argument.
+
+------------------------------------------------------------------------
+r3961 | jcbowman | 2009-02-05 02:38:31 -0700 (Thu, 05 Feb 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/picture.cc
+
+Fix asy -f pdf -o temp/venn.
+
+------------------------------------------------------------------------
+r3960 | jcbowman | 2009-02-05 02:36:16 -0700 (Thu, 05 Feb 2009) | 1 line
+Changed paths:
+ M /trunk/asymptote/configure.ac
+
+Increment version to 1.62svn.
+------------------------------------------------------------------------
+r3959 | jcbowman | 2009-02-05 01:35:32 -0700 (Thu, 05 Feb 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/examples/venn.asy
+
+Prevent multiple shipouts in venn example.
+
+------------------------------------------------------------------------
+r3958 | jcbowman | 2009-02-04 22:43:29 -0700 (Wed, 04 Feb 2009) | 4 lines
+Changed paths:
+ M /trunk/asymptote/base/nopapersize.ps
+ M /trunk/asymptote/picture.cc
+
+Change nopapersize.ps to use letterSize/a4size to work with the current
+MiKTeX version of dvips, which does not support the DVIPSRC environment
+variable.
+
+------------------------------------------------------------------------
+r3957 | jcbowman | 2009-02-04 22:14:53 -0700 (Wed, 04 Feb 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/glrender.cc
+
+Indent.
+
+------------------------------------------------------------------------
+r3956 | jcbowman | 2009-02-04 22:13:24 -0700 (Wed, 04 Feb 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/examples/shellsqrtx01.asy
+ M /trunk/asymptote/glrender.cc
+
+Fix aspect ratio on re-entry.
+
+------------------------------------------------------------------------
+r3955 | jcbowman | 2009-02-04 19:04:07 -0700 (Wed, 04 Feb 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/plain_pens.asy
+
+Add Pentype function to return a pen of increasing colour and linetype.
+
+------------------------------------------------------------------------
+r3954 | jcbowman | 2009-02-04 17:50:25 -0700 (Wed, 04 Feb 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/examples/galleon.asy
+
+Fix typo in URL.
+
+------------------------------------------------------------------------
+r3953 | jcbowman | 2009-02-04 08:57:55 -0700 (Wed, 04 Feb 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/glrender.cc
+
+Re-enable freeglut extensions to support user-specified multisampling again.
+
+------------------------------------------------------------------------
+r3952 | jcbowman | 2009-02-04 08:47:24 -0700 (Wed, 04 Feb 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/glrender.cc
+
+Destroy any existing export window before entering View mode.
+
+------------------------------------------------------------------------
+r3951 | jcbowman | 2009-02-03 23:46:20 -0700 (Tue, 03 Feb 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/runtime.in
+
+Remove spurious \phantom{+}.
+
+------------------------------------------------------------------------
+r3950 | jcbowman | 2009-02-03 23:33:34 -0700 (Tue, 03 Feb 2009) | 4 lines
+Changed paths:
+ M /trunk/asymptote/asymptote.spec
+ M /trunk/asymptote/doc/latexusage.tex
+ M /trunk/asymptote/picture.cc
+ M /trunk/asymptote/runtime.in
+ M /trunk/asymptote/settings.cc
+ M /trunk/asymptote/settings.h
+ M /trunk/asymptote/util.h
+
+Fix asydir(); under CYGWIN.
+
+Add missing CYGWIN prototype.
+
+------------------------------------------------------------------------
+r3949 | jcbowman | 2009-02-03 22:53:23 -0700 (Tue, 03 Feb 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/patches/dvipdf
+
+Remove -P pdf as this breaks file attachments.
+
+------------------------------------------------------------------------
+r3948 | jcbowman | 2009-02-03 22:32:40 -0700 (Tue, 03 Feb 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/glrender.cc
+
+Fix segmentation fault due to spurious window creation in export loop.
+
+------------------------------------------------------------------------
+r3947 | jcbowman | 2009-02-03 22:27:54 -0700 (Tue, 03 Feb 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/plain_strings.asy
+
+Add string[] to int[] ecast.
+
+------------------------------------------------------------------------
+r3946 | jcbowman | 2009-01-31 11:49:19 -0700 (Sat, 31 Jan 2009) | 4 lines
+Changed paths:
+ M /trunk/asymptote/picture.cc
+
+Fix dvipsOptions.
+
+Don't allow dvipsOptions to override -tnopapersize.
+
+------------------------------------------------------------------------
+r3945 | jcbowman | 2009-01-31 10:18:22 -0700 (Sat, 31 Jan 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/patches/dvipdf
+
+Update dvipdf to correspond to the latest ghostscript svn source.
+
+------------------------------------------------------------------------
+r3944 | jcbowman | 2009-01-31 08:29:42 -0700 (Sat, 31 Jan 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/solids.asy
+
+Warn that silhouette routine is intended only for 2d projections.
+
+------------------------------------------------------------------------
+r3943 | jcbowman | 2009-01-30 23:22:51 -0700 (Fri, 30 Jan 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/bezulate.asy
+
+Enforce the same zerowinding fillrule used by dvips.
+
+------------------------------------------------------------------------
+r3942 | jcbowman | 2009-01-30 23:07:10 -0700 (Fri, 30 Jan 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/nopapersize.ps
+ M /trunk/asymptote/picture.cc
+
+Rename nosize to nopapersize for clarity.
+
+------------------------------------------------------------------------
+r3941 | jcbowman | 2009-01-30 22:58:28 -0700 (Fri, 30 Jan 2009) | 4 lines
+Changed paths:
+ M /trunk/asymptote/Makefile.in
+ A /trunk/asymptote/base/nopapersize.ps
+ M /trunk/asymptote/picture.cc
+ M /trunk/asymptote/settings.cc
+ M /trunk/asymptote/settings.h
+
+Workaround dvips misconfiguration in TeXlive 2008 (and possibly other new TeX
+distributions) that introduces unwanted %%BeginPaperSize commands into the
+EPS output.
+
+------------------------------------------------------------------------
+r3940 | jcbowman | 2009-01-30 16:26:56 -0700 (Fri, 30 Jan 2009) | 4 lines
+Changed paths:
+ M /trunk/asymptote/base/asymptote.py
+ M /trunk/asymptote/process.cc
+ M /trunk/asymptote/settings.cc
+
+Reinstate -q (-quiet) option.
+
+Update asymptote.py to use -interactive option.
+
+------------------------------------------------------------------------
+r3939 | jcbowman | 2009-01-27 14:38:53 -0700 (Tue, 27 Jan 2009) | 3 lines
+Changed paths:
+ M /trunk/asymptote/picture.cc
+
+Work around dvips configuration errors on some systems by enforcing no
+paper type comments.
+
+------------------------------------------------------------------------
+r3938 | jcbowman | 2009-01-27 08:40:48 -0700 (Tue, 27 Jan 2009) | 2 lines
+Changed paths:
+ D /trunk/asymptote/examples/1overx.asy
+ A /trunk/asymptote/examples/oneoverx.asy (from /trunk/asymptote/examples/1overx.asy:3937)
+
+Rename file.
+
+------------------------------------------------------------------------
+r3937 | jcbowman | 2009-01-26 22:17:28 -0700 (Mon, 26 Jan 2009) | 1 line
+Changed paths:
+ M /trunk/asymptote/configure.ac
+
+Increment version to 1.61svn.
+------------------------------------------------------------------------
+r3936 | jcbowman | 2009-01-26 21:01:00 -0700 (Mon, 26 Jan 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/graph3.asy
+
+Fix surface condition type.
+
+------------------------------------------------------------------------
+r3935 | jcbowman | 2009-01-26 17:58:00 -0700 (Mon, 26 Jan 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/examples/floor.asy
+
+Simplify notation.
+
+------------------------------------------------------------------------
+r3934 | jcbowman | 2009-01-26 17:12:17 -0700 (Mon, 26 Jan 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/examples/floor.asy
+
+Remove diagnostics.
+
+------------------------------------------------------------------------
+r3933 | jcbowman | 2009-01-26 17:11:23 -0700 (Mon, 26 Jan 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/examples/floor.asy
+
+Improved marker alignment.
+
+------------------------------------------------------------------------
+r3932 | jcbowman | 2009-01-26 16:48:24 -0700 (Mon, 26 Jan 2009) | 3 lines
+Changed paths:
+ M /trunk/asymptote/base/graph.asy
+ M /trunk/asymptote/base/graph3.asy
+ M /trunk/asymptote/base/plain_constants.asy
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/examples/1overx.asy
+ M /trunk/asymptote/examples/gamma.asy
+
+Force a new guide after omitting points in conditional graphs; avoid
+spurious empty guides.
+
+------------------------------------------------------------------------
+r3931 | jcbowman | 2009-01-26 16:00:49 -0700 (Mon, 26 Jan 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/examples/floor.asy
+
+Improve axis label.
+
+------------------------------------------------------------------------
+r3930 | jcbowman | 2009-01-26 15:59:40 -0700 (Mon, 26 Jan 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/examples/floor.asy
+
+Simplify example.
+
+------------------------------------------------------------------------
+r3929 | jcbowman | 2009-01-26 15:56:55 -0700 (Mon, 26 Jan 2009) | 2 lines
+Changed paths:
+ A /trunk/asymptote/examples/floor.asy
+
+Add floor example.
+
+------------------------------------------------------------------------
+r3928 | jcbowman | 2009-01-26 12:54:20 -0700 (Mon, 26 Jan 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/pipestream.h
+
+Fix read from pipe failed error under MSDOS.
+
+------------------------------------------------------------------------
+r3927 | jcbowman | 2009-01-25 23:18:19 -0700 (Sun, 25 Jan 2009) | 3 lines
+Changed paths:
+ M /trunk/asymptote/GUI/xasy2asy.py
+ M /trunk/asymptote/asymptote.spec
+
+Allow xasy to be run from a write-protected directory under UNIX again
+by implementing broken (8.3) format tempdir workaround only for MSWindows.
+
+------------------------------------------------------------------------
+r3926 | jcbowman | 2009-01-25 08:58:27 -0700 (Sun, 25 Jan 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/glrender.cc
+
+Catch out of memory errors.
+
+------------------------------------------------------------------------
+r3925 | jcbowman | 2009-01-24 21:05:45 -0700 (Sat, 24 Jan 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/FAQ/asy-faq.bfnn
+
+Remove LocalWords from FAQ.
+
+------------------------------------------------------------------------
+r3924 | jcbowman | 2009-01-24 17:46:47 -0700 (Sat, 24 Jan 2009) | 3 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+
+Recommend svn version of freeglut only for UNIX systems with graphics cards
+that support multisampling.
+
+------------------------------------------------------------------------
+r3923 | jcbowman | 2009-01-24 17:29:36 -0700 (Sat, 24 Jan 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/glrender.cc
+ M /trunk/asymptote/psfile.cc
+ M /trunk/asymptote/texfile.cc
+
+Catch unhandled exception when exporting to write-protected directory.
+
+------------------------------------------------------------------------
+r3922 | jcbowman | 2009-01-24 15:21:27 -0700 (Sat, 24 Jan 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+
+Modify yum instructions for obtaining most recent version of Asymptote.
+
+------------------------------------------------------------------------
+r3921 | jcbowman | 2009-01-24 14:57:49 -0700 (Sat, 24 Jan 2009) | 8 lines
+Changed paths:
+ M /trunk/asymptote/base/graph.asy
+ M /trunk/asymptote/base/graph3.asy
+ M /trunk/asymptote/base/plain_constants.asy
+ M /trunk/asymptote/base/three.asy
+ M /trunk/asymptote/base/three_surface.asy
+ M /trunk/asymptote/doc/asymptote.texi
+
+Use default for bool3 initializer.
+
+Change condition array for graphs to bool3[].
+
+Add more bool3 support functions.
+
+Reformat base files.
+
+------------------------------------------------------------------------
+r3920 | jcbowman | 2009-01-24 12:34:04 -0700 (Sat, 24 Jan 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/three.asy
+
+Work around inability of movie15.sty package to handle spaces in filenames.
+
+------------------------------------------------------------------------
+r3919 | jcbowman | 2009-01-24 11:07:14 -0700 (Sat, 24 Jan 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/plain_strings.asy
+ M /trunk/asymptote/doc/asymptote.texi
+
+Add gettriple routine.
+
+------------------------------------------------------------------------
+r3918 | jcbowman | 2009-01-24 11:04:57 -0700 (Sat, 24 Jan 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/Makefile.in
+
+Don't regenerate asy-keywords.el with make install-asy.
+
+------------------------------------------------------------------------
+r3917 | jcbowman | 2009-01-24 10:30:30 -0700 (Sat, 24 Jan 2009) | 3 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+
+Emphasize that settings.outformat="pdf" must be set before three.asy (or
+graph3.asy) is imported.
+
+------------------------------------------------------------------------
+r3916 | jcbowman | 2009-01-24 10:05:21 -0700 (Sat, 24 Jan 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/three_surface.asy
+ M /trunk/asymptote/doc/asymptote.texi
+
+Document and standardize usage of bool3 type.
+
+------------------------------------------------------------------------
+r3915 | jcbowman | 2009-01-23 22:38:32 -0700 (Fri, 23 Jan 2009) | 6 lines
+Changed paths:
+ M /trunk/asymptote/base/graph.asy
+ M /trunk/asymptote/base/graph3.asy
+ M /trunk/asymptote/base/plain_constants.asy
+ M /trunk/asymptote/base/plain_paths.asy
+ M /trunk/asymptote/base/three.asy
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/examples/1overx.asy
+ M /trunk/asymptote/examples/gamma.asy
+
+Simplify and document graph interface routines.
+
+Make cond argument of graph a bool3(real) function, to allow one to
+distinguish between points that should not be plotted and points belonging
+to a new branch of the graph.
+
+------------------------------------------------------------------------
+r3914 | jcbowman | 2009-01-22 10:13:15 -0700 (Thu, 22 Jan 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/examples/1overx.asy
+
+Simplify example.
+
+------------------------------------------------------------------------
+r3913 | jcbowman | 2009-01-22 10:06:32 -0700 (Thu, 22 Jan 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/examples/1overx.asy
+
+Improve branch test.
+
+------------------------------------------------------------------------
+r3912 | jcbowman | 2009-01-21 23:00:55 -0700 (Wed, 21 Jan 2009) | 7 lines
+Changed paths:
+ M /trunk/asymptote/base/graph.asy
+ M /trunk/asymptote/base/graph3.asy
+ M /trunk/asymptote/base/plain_paths.asy
+ M /trunk/asymptote/base/three.asy
+ A /trunk/asymptote/examples/1overx.asy
+
+Make graph routines return a guide[].
+
+Add casts from guide and path arrays of length 1 to guides and paths,
+respectively.
+
+Add 1/x disconnected graph example.
+
+------------------------------------------------------------------------
+r3911 | jcbowman | 2009-01-21 21:31:18 -0700 (Wed, 21 Jan 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/quaternion.cc
+
+Avoid warning message.
+
+------------------------------------------------------------------------
+r3910 | jcbowman | 2009-01-21 21:24:26 -0700 (Wed, 21 Jan 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/colors.asy
+
+Use cmyk function.
+
+------------------------------------------------------------------------
+r3909 | jcbowman | 2009-01-21 21:22:08 -0700 (Wed, 21 Jan 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/graph3.asy
+
+Fix default condition arguments.
+
+------------------------------------------------------------------------
+r3908 | jcbowman | 2009-01-21 19:26:12 -0700 (Wed, 21 Jan 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/palette.asy
+
+Remove obsolete +cmyk construct.
+
+------------------------------------------------------------------------
+r3907 | jcbowman | 2009-01-21 17:33:26 -0700 (Wed, 21 Jan 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/main.cc
+
+Improve stack overflow diagnostics.
+
+------------------------------------------------------------------------
+r3906 | jcbowman | 2009-01-21 12:42:46 -0700 (Wed, 21 Jan 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/plain_pens.asy
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/mathop.h
+ M /trunk/asymptote/pen.h
+ M /trunk/asymptote/runtime.in
+
+In interp, first promote pens to the same colorspace.
+
+------------------------------------------------------------------------
+r3905 | jcbowman | 2009-01-20 00:06:34 -0700 (Tue, 20 Jan 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/graph.asy
+ M /trunk/asymptote/base/graph3.asy
+ M /trunk/asymptote/doc/asymptote.texi
+
+Add optional bool cond(real)=null to 2D and 3D graph routines for functions.
+
+------------------------------------------------------------------------
+r3904 | jcbowman | 2009-01-19 00:08:52 -0700 (Mon, 19 Jan 2009) | 1 line
+Changed paths:
+ M /trunk/asymptote/configure.ac
+
+Increment version to 1.60svn.
+------------------------------------------------------------------------
+r3903 | jcbowman | 2009-01-18 22:40:04 -0700 (Sun, 18 Jan 2009) | 4 lines
+Changed paths:
+ M /trunk/asymptote/base/slide.asy
+ M /trunk/asymptote/picture.cc
+ M /trunk/asymptote/runtime.in
+
+Clean up aux files.
+
+Fix aux conflicts in slide.asy.
+
+------------------------------------------------------------------------
+r3902 | jcbowman | 2009-01-18 22:05:29 -0700 (Sun, 18 Jan 2009) | 4 lines
+Changed paths:
+ M /trunk/asymptote/picture.cc
+
+Unlink texput files from proper directory.
+
+Remove any old texput.aux file before creating TeX pipe.
+
+------------------------------------------------------------------------
+r3901 | jcbowman | 2009-01-18 21:20:57 -0700 (Sun, 18 Jan 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/plain.asy
+
+Fix defaultfilename in asy(string).
+
+------------------------------------------------------------------------
+r3900 | jcbowman | 2009-01-18 15:59:34 -0700 (Sun, 18 Jan 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/roundedpath.asy
+
+Handle nonintersecting paths.
+
+------------------------------------------------------------------------
+r3899 | jcbowman | 2009-01-18 14:54:15 -0700 (Sun, 18 Jan 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/asymptote.spec
+ M /trunk/asymptote/settings.cc
+
+Add missing final long_opt entry.
+
+------------------------------------------------------------------------
+r3898 | jcbowman | 2009-01-18 12:59:10 -0700 (Sun, 18 Jan 2009) | 4 lines
+Changed paths:
+ M /trunk/asymptote/glrender.cc
+ M /trunk/asymptote/main.cc
+ M /trunk/asymptote/picture.cc
+ M /trunk/asymptote/settings.h
+
+Fix mixed export/View rendering.
+
+Wait for pid to finish with -nothreads.
+
+------------------------------------------------------------------------
+r3897 | jcbowman | 2009-01-17 12:33:51 -0700 (Sat, 17 Jan 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/examples/near_earth.asy
+
+Simplify example.
+
+------------------------------------------------------------------------
+r3896 | jcbowman | 2009-01-17 11:39:15 -0700 (Sat, 17 Jan 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/plain_pens.asy
+ M /trunk/asymptote/pen.h
+ M /trunk/asymptote/texfile.h
+
+Fix plain tex font scaling.
+
+------------------------------------------------------------------------
+r3895 | jcbowman | 2009-01-13 08:25:51 -0700 (Tue, 13 Jan 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+
+Fix typo in manual.
+
+------------------------------------------------------------------------
+r3894 | jcbowman | 2009-01-13 08:23:56 -0700 (Tue, 13 Jan 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/three_arrows.asy
+
+Transform margin paths.
+
+------------------------------------------------------------------------
+r3893 | jcbowman | 2009-01-13 08:14:11 -0700 (Tue, 13 Jan 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/three_arrows.asy
+
+Add missing filltype option for projected 2D arrowheads.
+
+------------------------------------------------------------------------
+r3892 | jcbowman | 2009-01-12 00:49:48 -0700 (Mon, 12 Jan 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/png/Makefile.in
+
+Clean up html files.
+
+------------------------------------------------------------------------
+r3891 | jcbowman | 2009-01-12 00:48:36 -0700 (Mon, 12 Jan 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/png/Makefile.in
+
+Generate html files into doc/png.
+
+------------------------------------------------------------------------
+r3890 | jcbowman | 2009-01-12 00:09:38 -0700 (Mon, 12 Jan 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/asymptote.nsi
+
+Set "Start in" directory for xasy to %USERPROFILE%.
+
+------------------------------------------------------------------------
+r3889 | jcbowman | 2009-01-12 00:02:03 -0700 (Mon, 12 Jan 2009) | 1 line
+Changed paths:
+ M /trunk/asymptote/configure.ac
+
+Increment version to 1.59svn.
+------------------------------------------------------------------------
+r3888 | jcbowman | 2009-01-11 22:38:42 -0700 (Sun, 11 Jan 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/three_arrows.asy
+ M /trunk/asymptote/doc/GaussianSurface.asy
+
+Draw 2D arrowheads when projecting to 2D.
+
+------------------------------------------------------------------------
+r3887 | jcbowman | 2009-01-11 18:06:17 -0700 (Sun, 11 Jan 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/Makefile.in
+
+Cache asy.list.
+
+------------------------------------------------------------------------
+r3886 | jcbowman | 2009-01-11 17:55:54 -0700 (Sun, 11 Jan 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/glrender.cc
+
+Fix include order.
+
+------------------------------------------------------------------------
+r3885 | jcbowman | 2009-01-11 17:30:14 -0700 (Sun, 11 Jan 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/GUI/xasy2asy.py
+ M /trunk/asymptote/glrender.cc
+
+Work around incompatibility of latex with DOS directory names.
+
+------------------------------------------------------------------------
+r3884 | jcbowman | 2009-01-11 13:00:17 -0700 (Sun, 11 Jan 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/glrender.cc
+
+Port to latest version of CYGWIN glut.h header file.
+
+------------------------------------------------------------------------
+r3883 | jcbowman | 2009-01-11 10:14:54 -0700 (Sun, 11 Jan 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/examples/hyperboloidsilhouette.asy
+
+Disable PRC for silhouette examples.
+
+------------------------------------------------------------------------
+r3882 | jcbowman | 2009-01-11 10:03:18 -0700 (Sun, 11 Jan 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/slide.asy
+
+Remove temporary asyinclude file.
+
+------------------------------------------------------------------------
+r3881 | jcbowman | 2009-01-11 08:42:47 -0700 (Sun, 11 Jan 2009) | 4 lines
+Changed paths:
+ M /trunk/asymptote/base/solids.asy
+ M /trunk/asymptote/examples/spheresilhouette.asy
+
+Draw a central transverse slice when m=1.
+
+Simplify spheresilhouette example.
+
+------------------------------------------------------------------------
+r3880 | jcbowman | 2009-01-10 23:11:57 -0700 (Sat, 10 Jan 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/examples/spheresilhouette.asy
+
+Increase example size.
+
+------------------------------------------------------------------------
+r3879 | jcbowman | 2009-01-10 23:09:42 -0700 (Sat, 10 Jan 2009) | 2 lines
+Changed paths:
+ A /trunk/asymptote/examples/hyperboloidsilhouette.asy
+ A /trunk/asymptote/examples/spheresilhouette.asy
+
+Add silhouette examples.
+
+------------------------------------------------------------------------
+r3878 | jcbowman | 2009-01-10 18:06:20 -0700 (Sat, 10 Jan 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/solids.asy
+ M /trunk/asymptote/examples/hyperboloid.asy
+
+Fix silhouette routine.
+
+------------------------------------------------------------------------
+r3877 | jcbowman | 2009-01-10 16:08:00 -0700 (Sat, 10 Jan 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/graph3.asy
+ M /trunk/asymptote/base/solids.asy
+
+Fix magnitude of pair axes label alignments.
+
+------------------------------------------------------------------------
+r3876 | jcbowman | 2009-01-10 11:32:02 -0700 (Sat, 10 Jan 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/graph3.asy
+
+Remove broken axis label alignment adjustment code.
+
+------------------------------------------------------------------------
+r3875 | jcbowman | 2009-01-09 22:43:57 -0700 (Fri, 09 Jan 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/three.asy
+
+Address nullpath issues.
+
+------------------------------------------------------------------------
+r3874 | jcbowman | 2009-01-08 22:31:58 -0700 (Thu, 08 Jan 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/examples/gamma3.asy
+
+Indicate real values with red.
+
+------------------------------------------------------------------------
+r3873 | jcbowman | 2009-01-08 22:00:07 -0700 (Thu, 08 Jan 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/palette.asy
+ M /trunk/asymptote/doc/asymptote.texi
+ A /trunk/asymptote/examples/gamma3.asy
+
+Add Wheel palette and example of complex Gamma function.
+
+------------------------------------------------------------------------
+r3872 | jcbowman | 2009-01-08 00:14:48 -0700 (Thu, 08 Jan 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.sty
+
+Fix conflict with breqn package.
+
+------------------------------------------------------------------------
+r3871 | jcbowman | 2009-01-06 22:02:00 -0700 (Tue, 06 Jan 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/three_arrows.asy
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/doc/markers2.asy
+
+Implement ArcArrow3, etc.
+
+------------------------------------------------------------------------
+r3870 | jcbowman | 2009-01-05 22:09:35 -0700 (Mon, 05 Jan 2009) | 4 lines
+Changed paths:
+ M /trunk/asymptote/base/plain_pens.asy
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/doc/markers2.asy
+ M /trunk/asymptote/pen.h
+
+Fix interp(pen,pen,real) by reverting to standard pen addition.
+
+Fix cmyk(rgb(black)).
+
+------------------------------------------------------------------------
+r3869 | hammera | 2009-01-04 13:47:12 -0700 (Sun, 04 Jan 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/exp.cc
+ M /trunk/asymptote/exp.h
+
+Report errors of arguments in illegal function call.
+
+------------------------------------------------------------------------
+r3868 | jcbowman | 2009-01-01 11:34:19 -0700 (Thu, 01 Jan 2009) | 2 lines
+Changed paths:
+ M /trunk/asymptote/Makefile.in
+
+Add missing file.
+
+------------------------------------------------------------------------
+r3867 | hammera | 2008-12-31 21:44:59 -0700 (Wed, 31 Dec 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/application.cc
+ M /trunk/asymptote/application.h
+ M /trunk/asymptote/builtin.cc
+ M /trunk/asymptote/exp.cc
+ M /trunk/asymptote/item.h
+ M /trunk/asymptote/types.cc
+ M /trunk/asymptote/types.h
+
+Added support for open function signatures.
+
+------------------------------------------------------------------------
+r3866 | jcbowman | 2008-12-31 16:29:27 -0700 (Wed, 31 Dec 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/TODO
+ M /trunk/asymptote/interact.cc
+ M /trunk/asymptote/settings.cc
+
+Exit interactive mode on EOF, unless exitonEOF=false.
+
+------------------------------------------------------------------------
+r3865 | jcbowman | 2008-12-31 15:10:39 -0700 (Wed, 31 Dec 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/TODO
+ M /trunk/asymptote/doc/asymptote.texi
+
+Add copy constructor TODO entry.
+
+------------------------------------------------------------------------
+r3864 | jcbowman | 2008-12-31 10:01:44 -0700 (Wed, 31 Dec 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+ A /trunk/asymptote/doc/scaledgraph.asy
+
+Add example of factoring out an axis scaling.
+
+------------------------------------------------------------------------
+r3863 | jcbowman | 2008-12-31 09:32:10 -0700 (Wed, 31 Dec 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/plain.asy
+ M /trunk/asymptote/builtin.cc
+ M /trunk/asymptote/runtime.in
+
+Change VERSION from a function to a constant.
+
+------------------------------------------------------------------------
+r3862 | jcbowman | 2008-12-31 08:19:16 -0700 (Wed, 31 Dec 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/main.cc
+ M /trunk/asymptote/picture.cc
+
+Allow compilation without HAVE_LIBGLUT.
+
+------------------------------------------------------------------------
+r3861 | jcbowman | 2008-12-30 22:19:29 -0700 (Tue, 30 Dec 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/asymptote.spec
+ M /trunk/asymptote/doc/FAQ/Makefile
+ M /trunk/asymptote/doc/Makefile.in
+ M /trunk/asymptote/doc/png/Makefile.in
+
+Clean up texput files.
+
+------------------------------------------------------------------------
+r3860 | jcbowman | 2008-12-30 22:10:19 -0700 (Tue, 30 Dec 2008) | 3 lines
+Changed paths:
+ M /trunk/asymptote/pen.h
+
+Revert previous pen changes; make operator + on grayscale pens a maximum
+operator.
+
+------------------------------------------------------------------------
+r3859 | jcbowman | 2008-12-30 16:46:26 -0700 (Tue, 30 Dec 2008) | 2 lines
+Changed paths:
+ A /trunk/asymptote/doc/png/Makefile.in
+
+Add missing file.
+
+------------------------------------------------------------------------
+r3858 | jcbowman | 2008-12-30 16:43:13 -0700 (Tue, 30 Dec 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/Makefile.in
+
+Add dependency.
+
+------------------------------------------------------------------------
+r3857 | jcbowman | 2008-12-30 16:31:36 -0700 (Tue, 30 Dec 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/pen.h
+
+Fix pen addition involving colorless pens.
+
+------------------------------------------------------------------------
+r3856 | jcbowman | 2008-12-30 16:13:45 -0700 (Tue, 30 Dec 2008) | 7 lines
+Changed paths:
+ M /trunk/asymptote/configure.ac
+ M /trunk/asymptote/doc/Makefile.in
+ M /trunk/asymptote/doc/asymptote.texi
+ A /trunk/asymptote/doc/png
+ M /trunk/asymptote/patches/README
+ M /trunk/asymptote/patches/dvipdf
+
+Build png images for manual in a separate directory so that they don't take
+precedence over pdf files.
+
+Center images in manual.
+
+Update modified dvipdf.
+
+------------------------------------------------------------------------
+r3855 | jcbowman | 2008-12-30 08:37:34 -0700 (Tue, 30 Dec 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/pen.h
+
+Make pen arithmetic consistent across colorspaces.
+
+------------------------------------------------------------------------
+r3854 | jcbowman | 2008-12-26 14:29:53 -0700 (Fri, 26 Dec 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/runtime.in
+
+Fix error message.
+
+------------------------------------------------------------------------
+r3853 | jcbowman | 2008-12-14 21:07:10 -0700 (Sun, 14 Dec 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/graph.asy
+
+Improve tick adjustment.
+
+------------------------------------------------------------------------
+r3852 | jcbowman | 2008-12-14 00:17:54 -0700 (Sun, 14 Dec 2008) | 1 line
+Changed paths:
+ M /trunk/asymptote/configure.ac
+
+Increment version to 1.58svn.
+------------------------------------------------------------------------
+r3851 | jcbowman | 2008-12-13 23:53:35 -0700 (Sat, 13 Dec 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/asymptote.nsi
+ M /trunk/asymptote/asymptote.spec
+
+Use asy.bat instead of asy.exe in MSWindows start menu link.
+
+------------------------------------------------------------------------
+r3850 | jcbowman | 2008-12-13 23:01:18 -0700 (Sat, 13 Dec 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/plain_Label.asy
+
+Resolve ambiguity.
+
+------------------------------------------------------------------------
+r3849 | jcbowman | 2008-12-13 22:50:31 -0700 (Sat, 13 Dec 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/plain_picture.asy
+
+Fix picture sizing with beginclip/endclip.
+
+------------------------------------------------------------------------
+r3848 | jcbowman | 2008-12-13 22:12:21 -0700 (Sat, 13 Dec 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/plain_picture.asy
+ M /trunk/asymptote/runtime.in
+
+Add beginclip(picture) and endclip(picture) functions.
+
+------------------------------------------------------------------------
+r3847 | jcbowman | 2008-12-13 21:55:58 -0700 (Sat, 13 Dec 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/plain_shipout.asy
+ M /trunk/asymptote/drawclipend.h
+ M /trunk/asymptote/drawlayer.h
+ M /trunk/asymptote/examples/alignbox.asy
+ M /trunk/asymptote/picture.cc
+ M /trunk/asymptote/runtime.in
+
+Allow clipping across page boundaries.
+
+------------------------------------------------------------------------
+r3846 | jcbowman | 2008-12-13 12:04:41 -0700 (Sat, 13 Dec 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/examples/alignbox.asy
+
+Simplify example.
+
+------------------------------------------------------------------------
+r3845 | jcbowman | 2008-12-13 12:02:09 -0700 (Sat, 13 Dec 2008) | 2 lines
+Changed paths:
+ A /trunk/asymptote/examples/alignbox.asy
+
+Add example of aligned objects and envelopes.
+
+------------------------------------------------------------------------
+r3844 | jcbowman | 2008-12-13 12:00:20 -0700 (Sat, 13 Dec 2008) | 4 lines
+Changed paths:
+ M /trunk/asymptote/base/plain_Label.asy
+ M /trunk/asymptote/base/plain_boxes.asy
+
+Add object(Label, envelope, ...) constructor.
+
+Support object transformation and alignment.
+
+------------------------------------------------------------------------
+r3843 | jcbowman | 2008-12-12 21:31:00 -0700 (Fri, 12 Dec 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/plain_pens.asy
+ M /trunk/asymptote/drawlabel.cc
+ M /trunk/asymptote/pen.h
+ M /trunk/asymptote/texfile.cc
+ M /trunk/asymptote/texfile.h
+
+Fix plain tex font size.
+
+------------------------------------------------------------------------
+r3842 | jcbowman | 2008-12-11 22:19:17 -0700 (Thu, 11 Dec 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/graph.asy
+
+Improve axis coverage calculation.
+
+------------------------------------------------------------------------
+r3841 | jcbowman | 2008-12-10 10:02:14 -0700 (Wed, 10 Dec 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/plain_pens.asy
+ M /trunk/asymptote/doc/asymptote.texi
+
+Simplify font(string name, real size).
+
+------------------------------------------------------------------------
+r3840 | hammera | 2008-12-10 09:43:09 -0700 (Wed, 10 Dec 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/interact.cc
+
+Handle empty history in get/setLastHistoryLine.
+
+------------------------------------------------------------------------
+r3839 | jcbowman | 2008-12-09 02:06:46 -0700 (Tue, 09 Dec 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/plain.asy
+
+Use defaultfilename in asy(string).
+
+------------------------------------------------------------------------
+r3838 | jcbowman | 2008-12-09 01:19:06 -0700 (Tue, 09 Dec 2008) | 7 lines
+Changed paths:
+ M /trunk/asymptote/base/animation.asy
+ M /trunk/asymptote/base/plain.asy
+ M /trunk/asymptote/base/plain_shipout.asy
+ M /trunk/asymptote/base/slide.asy
+ M /trunk/asymptote/base/three.asy
+ M /trunk/asymptote/picture.cc
+ M /trunk/asymptote/runtime.in
+ M /trunk/asymptote/settings.cc
+ M /trunk/asymptote/util.cc
+ M /trunk/asymptote/util.h
+
+All temporary files are now generated in the directory specified by the
+-outname command-line option.
+
+Make outname a read-only setting.
+
+Check if the output directory is writeable.
+
+------------------------------------------------------------------------
+r3837 | jcbowman | 2008-12-08 20:44:52 -0700 (Mon, 08 Dec 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/three.asy
+
+Add diagnostic.
+
+------------------------------------------------------------------------
+r3836 | jcbowman | 2008-12-08 20:44:17 -0700 (Mon, 08 Dec 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/asymptote.nsi
+
+Make default MSDOS "start-in" directory %USERPROFILE%.
+
+------------------------------------------------------------------------
+r3835 | jcbowman | 2008-12-08 20:43:28 -0700 (Mon, 08 Dec 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/fileio.h
+
+Fix diagnostic.
+
+------------------------------------------------------------------------
+r3834 | jcbowman | 2008-12-08 19:47:47 -0700 (Mon, 08 Dec 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/plain_pens.asy
+ M /trunk/asymptote/doc/asymptote.texi
+
+Add optional basesize parameter to font.
+
+------------------------------------------------------------------------
+r3833 | jcbowman | 2008-12-08 17:15:06 -0700 (Mon, 08 Dec 2008) | 3 lines
+Changed paths:
+ M /trunk/asymptote/doc/CDlabel.asy
+ M /trunk/asymptote/texfile.cc
+
+Fix pdflatex texengine; abandon xelatex support since xelatex does not
+support pdf specials anyway.
+
+------------------------------------------------------------------------
+r3832 | oshardt | 2008-12-08 15:44:46 -0700 (Mon, 08 Dec 2008) | 1 line
+Changed paths:
+ M /trunk/asymptote/GUI/xasyCodeEditor.py
+ M /trunk/asymptote/GUI/xasyMainWin.py
+
+Handle failure to lauch external editor cleanly.
+------------------------------------------------------------------------
+r3831 | jcbowman | 2008-12-07 13:57:02 -0700 (Sun, 07 Dec 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/BUGS
+
+Update link.
+
+------------------------------------------------------------------------
+r3830 | jcbowman | 2008-12-06 22:28:51 -0700 (Sat, 06 Dec 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+
+Update documentation of xasy installation.
+
+------------------------------------------------------------------------
+r3829 | jcbowman | 2008-12-05 21:46:08 -0700 (Fri, 05 Dec 2008) | 1 line
+Changed paths:
+ M /trunk/asymptote/asymptote.spec
+ M /trunk/asymptote/configure.ac
+
+Increment version to 1.57svn.
+------------------------------------------------------------------------
+r3828 | jcbowman | 2008-12-05 18:33:56 -0700 (Fri, 05 Dec 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/grid3.asy
+
+Fix documentation of grid3.
+
+------------------------------------------------------------------------
+r3827 | jcbowman | 2008-12-05 18:24:27 -0700 (Fri, 05 Dec 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/grid3.asy
+ M /trunk/asymptote/examples/smoothelevation.asy
+
+Add examples of using grid3 with scale(true).
+
+------------------------------------------------------------------------
+r3826 | jcbowman | 2008-12-05 18:24:04 -0700 (Fri, 05 Dec 2008) | 3 lines
+Changed paths:
+ M /trunk/asymptote/settings.cc
+ M /trunk/asymptote/texfile.h
+
+Fix bounding box bug by clearing \ASYbox dimensions for latex as well as for
+pdflatex.
+
+------------------------------------------------------------------------
+r3825 | jcbowman | 2008-12-05 18:21:06 -0700 (Fri, 05 Dec 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/plain_pens.asy
+
+Round font scaling to the nearest integer.
+
+------------------------------------------------------------------------
+r3824 | jcbowman | 2008-12-05 10:27:49 -0700 (Fri, 05 Dec 2008) | 4 lines
+Changed paths:
+ M /trunk/asymptote/base/grid3.asy
+ M /trunk/asymptote/base/slide.asy
+ M /trunk/asymptote/examples/logo3.asy
+ M /trunk/asymptote/examples/slidedemo.asy
+ M /trunk/asymptote/examples/smoothelevation.asy
+
+Add asyinclude function for including 3D PRC graphs in slides.
+
+Update grid3 documentation.
+
+------------------------------------------------------------------------
+r3823 | pivaldi | 2008-12-05 02:45:16 -0700 (Fri, 05 Dec 2008) | 1 line
+Changed paths:
+ M /trunk/asymptote/base/asy-mode.el
+
+Fix version
+------------------------------------------------------------------------
+r3822 | pivaldi | 2008-12-05 02:36:20 -0700 (Fri, 05 Dec 2008) | 1 line
+Changed paths:
+ M /trunk/asymptote/base/asy-mode.el
+
+Fix handling the environment asydef within lasy-mode.
+------------------------------------------------------------------------
+r3821 | jcbowman | 2008-12-04 09:26:58 -0700 (Thu, 04 Dec 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/picture.cc
+
+Fix shipout(wait=true).
+
+------------------------------------------------------------------------
+r3820 | jcbowman | 2008-12-02 03:24:02 -0700 (Tue, 02 Dec 2008) | 1 line
+Changed paths:
+ M /trunk/asymptote/asymptote.spec
+ M /trunk/asymptote/configure.ac
+
+Increment version to 1.56svn.
+------------------------------------------------------------------------
+r3819 | jcbowman | 2008-12-02 00:15:16 -0700 (Tue, 02 Dec 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/three.asy
+ M /trunk/asymptote/examples/BezierSurface.asy
+
+Remove obsolete field of view factor.
+
+------------------------------------------------------------------------
+r3818 | jcbowman | 2008-12-02 00:03:58 -0700 (Tue, 02 Dec 2008) | 6 lines
+Changed paths:
+ M /trunk/asymptote/base/three.asy
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/examples/BezierSurface.asy
+
+Add user=true argument to 3D point(picture) and size3(picture) routines;
+add truepoint routine.
+
+Add triple invert(pair z, projection P=currentprojection) routine that
+inverts a pair z onto the projection plane.
+
+------------------------------------------------------------------------
+r3817 | jcbowman | 2008-12-01 23:41:41 -0700 (Mon, 01 Dec 2008) | 4 lines
+Changed paths:
+ M /trunk/asymptote/flatguide.cc
+ M /trunk/asymptote/flatguide.h
+ M /trunk/asymptote/guide.h
+ M /trunk/asymptote/tests/types/guide.asy
+
+Fix more guide to path problems.
+
+Update guide tests.
+
+------------------------------------------------------------------------
+r3816 | jcbowman | 2008-12-01 11:47:38 -0700 (Mon, 01 Dec 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/psfile.cc
+
+Fix drawing of paths of length 0.
+
+------------------------------------------------------------------------
+r3815 | jcbowman | 2008-11-30 20:00:12 -0700 (Sun, 30 Nov 2008) | 1 line
+Changed paths:
+ M /trunk/asymptote/asymptote.spec
+ M /trunk/asymptote/configure.ac
+
+Increment version to 1.55svn.
+------------------------------------------------------------------------
+r3814 | jcbowman | 2008-11-30 17:19:15 -0700 (Sun, 30 Nov 2008) | 3 lines
+Changed paths:
+ M /trunk/asymptote/doc/Makefile.in
+ M /trunk/asymptote/doc/asymptote.texi
+
+Document need to remove latexusage_.pre along with latexusage-* and
+latexusage.aux when switching between latex and pdflatex usage.
+
+------------------------------------------------------------------------
+r3813 | jcbowman | 2008-11-30 16:42:36 -0700 (Sun, 30 Nov 2008) | 6 lines
+Changed paths:
+ M /trunk/asymptote/base/three.asy
+ M /trunk/asymptote/flatguide.h
+ M /trunk/asymptote/guide.cc
+ M /trunk/asymptote/guide.h
+ M /trunk/asymptote/runtime.in
+
+Fix final specifiers in guide examination routines and reverse(guide).
+
+Fix reverse(guide3).
+
+Control points should trump direction specifiers.
+
+------------------------------------------------------------------------
+r3812 | jcbowman | 2008-11-30 14:07:10 -0700 (Sun, 30 Nov 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/main.cc
+ M /trunk/asymptote/settings.cc
+
+Add threads setting (default is true except under MSDOS).
+
+------------------------------------------------------------------------
+r3811 | jcbowman | 2008-11-30 00:17:47 -0700 (Sun, 30 Nov 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/psfile.cc
+
+Fix curved cyclic paths of size 1.
+
+------------------------------------------------------------------------
+r3810 | jcbowman | 2008-11-29 23:46:09 -0700 (Sat, 29 Nov 2008) | 6 lines
+Changed paths:
+ M /trunk/asymptote/base/three.asy
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/runtime.in
+
+Add time argument to curlSpecifier to allow access to all curl specifiers.
+
+Fix reverse(guide).
+
+Add reverse(guide3).
+
+------------------------------------------------------------------------
+r3809 | jcbowman | 2008-11-29 11:51:20 -0700 (Sat, 29 Nov 2008) | 3 lines
+Changed paths:
+ M /trunk/asymptote/settings.cc
+
+Fix multiple file batch mode under MSWindows: only query the MSWindows
+registry once.
+
+------------------------------------------------------------------------
+r3808 | jcbowman | 2008-11-29 11:50:09 -0700 (Sat, 29 Nov 2008) | 4 lines
+Changed paths:
+ M /trunk/asymptote/glrender.cc
+ M /trunk/asymptote/picture.cc
+
+Fix compilation without HAVE_LIBPTHREAD.
+
+Call HideWindow under MSWindows when View=false.
+
+------------------------------------------------------------------------
+r3807 | jcbowman | 2008-11-27 23:51:31 -0700 (Thu, 27 Nov 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/three.asy
+ M /trunk/asymptote/base/three_surface.asy
+ M /trunk/asymptote/doc/asymptote.texi
+
+Respect 3D Label filltype when render=0.
+
+------------------------------------------------------------------------
+r3806 | jcbowman | 2008-11-27 15:08:09 -0700 (Thu, 27 Nov 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+
+Clarify that the native glut library is used instead of freeglut under MacOSX.
+
+------------------------------------------------------------------------
+r3805 | jcbowman | 2008-11-27 12:49:29 -0700 (Thu, 27 Nov 2008) | 1 line
+Changed paths:
+ M /trunk/asymptote/configure.ac
+
+Increment version to 1.54svn.
+------------------------------------------------------------------------
+r3804 | jcbowman | 2008-11-27 11:39:54 -0700 (Thu, 27 Nov 2008) | 5 lines
+Changed paths:
+ M /trunk/asymptote/asymptote.nsi
+ M /trunk/asymptote/asymptote.spec
+ M /trunk/asymptote/settings.cc
+
+Set environment variable CYGWIN=nodosfilewarning if it is undefined or empty.
+Note: this doesn't get uninstalled since it is the "right" default anyway.
+
+Rename asy-console.bat to asy.bat.
+
+------------------------------------------------------------------------
+r3803 | jcbowman | 2008-11-27 00:14:49 -0700 (Thu, 27 Nov 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/configure.ac
+
+Force CFLAGS="-g -O3" default again.
+
+------------------------------------------------------------------------
+r3802 | jcbowman | 2008-11-27 00:01:41 -0700 (Thu, 27 Nov 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/examples/tvgen.asy
+
+Output diagnostics only if verbose > 1.
+
+------------------------------------------------------------------------
+r3801 | jcbowman | 2008-11-26 23:58:03 -0700 (Wed, 26 Nov 2008) | 4 lines
+Changed paths:
+ M /trunk/asymptote/base/flowchart.asy
+ M /trunk/asymptote/doc/asymptote.texi
+
+Add minblockwidth, minblockheight, and mincirclediameter parameters.
+
+Change Horizontal and Vertical to a nonboolean type flowdir.
+
+------------------------------------------------------------------------
+r3800 | jcbowman | 2008-11-26 22:31:46 -0700 (Wed, 26 Nov 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/three.asy
+
+Fix PRC projection sizing when up != Z.
+
+------------------------------------------------------------------------
+r3799 | jcbowman | 2008-11-26 21:15:36 -0700 (Wed, 26 Nov 2008) | 4 lines
+Changed paths:
+ M /trunk/asymptote/glrender.cc
+ M /trunk/asymptote/picture.cc
+
+Add missing wait.
+
+Fix aspect ratio in interactive mode.
+
+------------------------------------------------------------------------
+r3798 | jcbowman | 2008-11-26 19:33:53 -0700 (Wed, 26 Nov 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/glrender.cc
+ M /trunk/asymptote/main.cc
+ M /trunk/asymptote/picture.cc
+ M /trunk/asymptote/settings.h
+
+Fix rendering logic.
+
+------------------------------------------------------------------------
+r3797 | jcbowman | 2008-11-26 14:46:04 -0700 (Wed, 26 Nov 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/three.asy
+
+Minor optimizations.
+
+------------------------------------------------------------------------
+r3796 | jcbowman | 2008-11-25 23:26:30 -0700 (Tue, 25 Nov 2008) | 4 lines
+Changed paths:
+ M /trunk/asymptote/base/tube.asy
+ M /trunk/asymptote/doc/asymptote.texi
+
+Change cyclic flag in the routine where the array is actually constructed.
+
+Make minor edits to tube documentation.
+
+------------------------------------------------------------------------
+r3795 | jcbowman | 2008-11-25 22:27:21 -0700 (Tue, 25 Nov 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.sty
+ M /trunk/asymptote/doc/latexusage.tex
+
+Enable the toolbar by default within the asyattach environment.
+
+------------------------------------------------------------------------
+r3794 | jcbowman | 2008-11-25 21:13:39 -0700 (Tue, 25 Nov 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/asymptote.nsi
+ M /trunk/asymptote/doc/latexusage.tex
+ M /trunk/asymptote/settings.cc
+
+Set CYGWIN=nodosfilewarning in asy rather than in a batch file.
+
+------------------------------------------------------------------------
+r3793 | jcbowman | 2008-11-25 21:12:13 -0700 (Tue, 25 Nov 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/pipestream.h
+
+Don't hang on exit from "Cannot execute latex" error.
+
+------------------------------------------------------------------------
+r3792 | pivaldi | 2008-11-25 16:02:34 -0700 (Tue, 25 Nov 2008) | 1 line
+Changed paths:
+ M /trunk/asymptote/base/tube.asy
+ M /trunk/asymptote/doc/asymptote.texi
+ A /trunk/asymptote/examples/trefoilknot.asy
+
+Replace step to relstep in tube.asy, add example of tube, document the package tube.asy
+------------------------------------------------------------------------
+r3791 | jcbowman | 2008-11-25 14:20:36 -0700 (Tue, 25 Nov 2008) | 3 lines
+Changed paths:
+ M /trunk/asymptote/base/graph3.asy
+ M /trunk/asymptote/base/plain_Label.asy
+ M /trunk/asymptote/base/three_surface.asy
+
+Distinguish between defaulttransform and defaulttransform3, so that
+label(scale(10)*"text",O) is projected onto the initial viewing plane.
+
+------------------------------------------------------------------------
+r3790 | jcbowman | 2008-11-25 13:44:44 -0700 (Tue, 25 Nov 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+
+Simplify freeglut svn-761 installation instructions.
+
+------------------------------------------------------------------------
+r3789 | jcbowman | 2008-11-25 12:16:48 -0700 (Tue, 25 Nov 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/errormsg.cc
+ M /trunk/asymptote/errormsg.h
+ M /trunk/asymptote/main.cc
+ M /trunk/asymptote/process.cc
+
+Catch out-of-memory errors in OpenGL renderer.
+
+------------------------------------------------------------------------
+r3788 | jcbowman | 2008-11-25 09:09:56 -0700 (Tue, 25 Nov 2008) | 3 lines
+Changed paths:
+ M /trunk/asymptote/asymptote.nsi
+
+Disable DOS path syntax warning in version 20080327 of cygwin.dll (which
+supports pthreads).
+
+------------------------------------------------------------------------
+r3787 | jcbowman | 2008-11-25 04:06:31 -0700 (Tue, 25 Nov 2008) | 1 line
+Changed paths:
+ M /trunk/asymptote/configure.ac
+
+Increment version to 1.53svn
+------------------------------------------------------------------------
+r3786 | jcbowman | 2008-11-25 00:02:46 -0700 (Tue, 25 Nov 2008) | 4 lines
+Changed paths:
+ M /trunk/asymptote/pipestream.h
+ M /trunk/asymptote/util.cc
+
+Use _exit instead of exit after fork as recommended by man page.
+
+Remove remaining piece of old fork wrapper code.
+
+------------------------------------------------------------------------
+r3785 | jcbowman | 2008-11-24 23:09:26 -0700 (Mon, 24 Nov 2008) | 3 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/glrender.cc
+ M /trunk/asymptote/picture.cc
+ M /trunk/asymptote/settings.cc
+
+Make antialias an integer parameter (default 2). Values bigger than 2 are
+currently respected only when converting from EPS or PDF formats.
+
+------------------------------------------------------------------------
+r3784 | jcbowman | 2008-11-24 22:30:57 -0700 (Mon, 24 Nov 2008) | 4 lines
+Changed paths:
+ M /trunk/asymptote/glrender.cc
+ M /trunk/asymptote/pipestream.h
+ M /trunk/asymptote/util.cc
+
+Don't call fitscreen() during interactive updates.
+
+Simplify forking in pipestream.h.
+
+------------------------------------------------------------------------
+r3783 | jcbowman | 2008-11-24 02:16:55 -0700 (Mon, 24 Nov 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/glrender.cc
+
+Fix multiple file aspect ratio issues.
+
+------------------------------------------------------------------------
+r3782 | jcbowman | 2008-11-24 01:57:28 -0700 (Mon, 24 Nov 2008) | 4 lines
+Changed paths:
+ M /trunk/asymptote/common.h
+ M /trunk/asymptote/configure.ac
+ M /trunk/asymptote/glrender.cc
+ M /trunk/asymptote/glrender.h
+ M /trunk/asymptote/main.cc
+ M /trunk/asymptote/picture.cc
+ M /trunk/asymptote/settings.h
+
+Fix exporting with -noV.
+
+Support machines without working POSIX threads.
+
+------------------------------------------------------------------------
+r3781 | jcbowman | 2008-11-23 17:19:34 -0700 (Sun, 23 Nov 2008) | 4 lines
+Changed paths:
+ M /trunk/asymptote/configure.ac
+ M /trunk/asymptote/main.cc
+ M /trunk/asymptote/prc/PRCTools/bitData.cc
+ M /trunk/asymptote/prc/PRCbitStream.cc
+ M /trunk/asymptote/prc/PRCdouble.cc
+ M /trunk/asymptote/prc/PRCdouble.h
+ M /trunk/asymptote/prc/oPRCFile.cc
+ M /trunk/asymptote/prc/oPRCFile.h
+
+Define standard symbol WORDS_BIG_ENDIAN or WORDS_LITTLE_ENDIAN, as appropriate.
+
+Add Orest's patch to support PRC output on bigendian machines.
+
+------------------------------------------------------------------------
+r3780 | jcbowman | 2008-11-23 15:47:28 -0700 (Sun, 23 Nov 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/glrender.cc
+ M /trunk/asymptote/glrender.h
+ M /trunk/asymptote/main.cc
+ M /trunk/asymptote/picture.cc
+ M /trunk/asymptote/settings.h
+
+Use gl::wait routine for thread synchronization.
+
+------------------------------------------------------------------------
+r3779 | jcbowman | 2008-11-23 02:00:14 -0700 (Sun, 23 Nov 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/tr.cc
+
+Support compilation again on systems without glut.
+
+------------------------------------------------------------------------
+r3778 | jcbowman | 2008-11-23 00:53:41 -0700 (Sun, 23 Nov 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/prc/PRCdouble.h
+
+Conditionally include config.h.
+
+------------------------------------------------------------------------
+r3777 | jcbowman | 2008-11-23 00:53:05 -0700 (Sun, 23 Nov 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/configure.ac
+
+Rename BIG_ENDIAN to IS_BIG_ENDIAN.
+
+------------------------------------------------------------------------
+r3776 | jcbowman | 2008-11-23 00:43:57 -0700 (Sun, 23 Nov 2008) | 3 lines
+Changed paths:
+ M /trunk/asymptote/configure.ac
+ M /trunk/asymptote/picture.cc
+ M /trunk/asymptote/prc/PRCdouble.h
+
+Add preliminary support for bigendian machines (PRC output is not yet
+working though).
+
+------------------------------------------------------------------------
+r3775 | jcbowman | 2008-11-23 00:12:57 -0700 (Sun, 23 Nov 2008) | 3 lines
+Changed paths:
+ M /trunk/asymptote/drawsurface.cc
+ M /trunk/asymptote/glrender.cc
+ M /trunk/asymptote/glrender.h
+ M /trunk/asymptote/main.cc
+ M /trunk/asymptote/memory.h
+ M /trunk/asymptote/picture.cc
+ M /trunk/asymptote/settings.h
+
+Use the main thread for OpenGL rendering to make MacOS happy; run asy in a
+secondary thread.
+
+------------------------------------------------------------------------
+r3774 | jcbowman | 2008-11-22 12:29:20 -0700 (Sat, 22 Nov 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/prc/PRCbitStream.cc
+
+Add assert.
+
+------------------------------------------------------------------------
+r3773 | jcbowman | 2008-11-22 11:03:14 -0700 (Sat, 22 Nov 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/INSTALL
+ M /trunk/asymptote/doc/asymptote.texi
+
+Update SVN instructions to not require SSL support.
+
+------------------------------------------------------------------------
+r3772 | jcbowman | 2008-11-22 11:00:27 -0700 (Sat, 22 Nov 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/runtime.in
+
+Fix bus error.
+
+------------------------------------------------------------------------
+r3771 | pivaldi | 2008-11-21 16:13:24 -0700 (Fri, 21 Nov 2008) | 1 line
+Changed paths:
+ M /trunk/asymptote/base/tube.asy
+
+Fix calculation of angle.
+------------------------------------------------------------------------
+r3770 | pivaldi | 2008-11-21 07:29:02 -0700 (Fri, 21 Nov 2008) | 1 line
+Changed paths:
+ M /trunk/asymptote/base/asy-mode.el
+
+asy-mode.el: define asy keywords properly.
+------------------------------------------------------------------------
+r3769 | jcbowman | 2008-11-21 00:55:51 -0700 (Fri, 21 Nov 2008) | 2 lines
+Changed paths:
+ A /trunk/asymptote/base/tube.asy
+
+Add Philippe's tube module.
+
+------------------------------------------------------------------------
+r3768 | jcbowman | 2008-11-21 00:20:14 -0700 (Fri, 21 Nov 2008) | 4 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/glrender.cc
+ M /trunk/asymptote/glrender.h
+ M /trunk/asymptote/patches/README
+ D /trunk/asymptote/patches/freeglut-2.4.0-svn759.patch
+ M /trunk/asymptote/picture.cc
+
+Improve thread synchronization and diagonistics.
+
+Remove freeglut-2.4.0-svn759.patch in favour of fixed svn 761.
+
+------------------------------------------------------------------------
+r3767 | jcbowman | 2008-11-20 01:40:24 -0700 (Thu, 20 Nov 2008) | 5 lines
+Changed paths:
+ M /trunk/asymptote/INSTALL
+ M /trunk/asymptote/configure.ac
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/glrender.cc
+ M /trunk/asymptote/glrender.h
+ M /trunk/asymptote/picture.cc
+
+Implement robust thread locking.
+
+Update installation instructions to use the system GC by default, now that we
+require a multithreaded version.
+
+------------------------------------------------------------------------
+r3766 | jcbowman | 2008-11-19 18:59:56 -0700 (Wed, 19 Nov 2008) | 3 lines
+Changed paths:
+ M /trunk/asymptote/glrender.cc
+
+Revert most of r3763 due to a reported segmentation fault and since
+glutGetModeValues isn't implemented for MSWindows anyway.
+
+------------------------------------------------------------------------
+r3765 | jcbowman | 2008-11-19 16:35:07 -0700 (Wed, 19 Nov 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/glrender.cc
+
+Revert r3762.
+
+------------------------------------------------------------------------
+r3764 | jcbowman | 2008-11-19 09:12:32 -0700 (Wed, 19 Nov 2008) | 2 lines
+Changed paths:
+ A /trunk/asymptote/examples/tvgen.asy
+
+Add television test pattern example.
+
+------------------------------------------------------------------------
+r3763 | jcbowman | 2008-11-19 00:19:29 -0700 (Wed, 19 Nov 2008) | 4 lines
+Changed paths:
+ M /trunk/asymptote/glrender.cc
+
+Simplify multisample negotiation by using glutGetModeValues.
+
+Backport code to freeglut-2.4.0.
+
+------------------------------------------------------------------------
+r3762 | jcbowman | 2008-11-18 23:20:29 -0700 (Tue, 18 Nov 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/glrender.cc
+
+Hide window again when View=false, even if iconify=false;
+
+------------------------------------------------------------------------
+r3761 | jcbowman | 2008-11-18 23:08:27 -0700 (Tue, 18 Nov 2008) | 4 lines
+Changed paths:
+ M /trunk/asymptote/base/obj.asy
+ M /trunk/asymptote/base/plain_constants.asy
+ M /trunk/asymptote/base/three_surface.asy
+
+Add bool3 type that takes on one of the values true, false, or default.
+
+Add planar argument to surface.
+
+------------------------------------------------------------------------
+r3760 | jcbowman | 2008-11-18 22:15:37 -0700 (Tue, 18 Nov 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/drawsurface.cc
+
+Fix vertex shading order in planar case.
+
+------------------------------------------------------------------------
+r3759 | jcbowman | 2008-11-18 21:43:51 -0700 (Tue, 18 Nov 2008) | 4 lines
+Changed paths:
+ M /trunk/asymptote/asymptote.spec
+ M /trunk/asymptote/glrender.cc
+ M /trunk/asymptote/glrender.h
+ M /trunk/asymptote/picture.cc
+
+Avoid POSIX thread deadlock.
+
+Fix rpm latex install directory.
+
+------------------------------------------------------------------------
+r3758 | jcbowman | 2008-11-18 13:46:51 -0700 (Tue, 18 Nov 2008) | 3 lines
+Changed paths:
+ M /trunk/asymptote/configure.ac
+ M /trunk/asymptote/glrender.h
+
+Work around nonstandardized signature of gluNurbsCallback on various MacOS
+platforms.
+
+------------------------------------------------------------------------
+r3757 | jcbowman | 2008-11-18 10:46:00 -0700 (Tue, 18 Nov 2008) | 5 lines
+Changed paths:
+ M /trunk/asymptote/base/plain_picture.asy
+ M /trunk/asymptote/base/plain_shipout.asy
+ M /trunk/asymptote/base/three.asy
+ M /trunk/asymptote/configure.ac
+ M /trunk/asymptote/glrender.cc
+ M /trunk/asymptote/glrender.h
+ M /trunk/asymptote/picture.cc
+ M /trunk/asymptote/picture.h
+ M /trunk/asymptote/runtime.in
+ M /trunk/asymptote/settings.cc
+
+Use POSIX threads instead of fork in OpenGL renderer.
+
+Make multisample an integer; if freeglut is used this parameter controls
+the multisampling width for screen images.
+
+------------------------------------------------------------------------
+r3756 | jcbowman | 2008-11-18 07:58:27 -0700 (Tue, 18 Nov 2008) | 2 lines
+Changed paths:
+ D /trunk/asymptote/patches/freeglut-2.4.0multisample.patch
+
+Remove obsolete patch.
+
+------------------------------------------------------------------------
+r3755 | jcbowman | 2008-11-17 12:12:46 -0700 (Mon, 17 Nov 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/configure.ac
+
+Install asymptote.sty and asycolors.sty in $TEXMFLOCAL/tex/latex.
+
+------------------------------------------------------------------------
+r3754 | jcbowman | 2008-11-16 17:08:46 -0700 (Sun, 16 Nov 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/asy-mode.el
+
+Fix indentation after struct.
+
+------------------------------------------------------------------------
+r3753 | jcbowman | 2008-11-16 16:36:38 -0700 (Sun, 16 Nov 2008) | 4 lines
+Changed paths:
+ M /trunk/asymptote/base/asy-mode.el
+
+Remove dependency on cc-mode.el source.
+
+Allow asy-mode.el to load even without asy-keywords.el.
+
+------------------------------------------------------------------------
+r3752 | pivaldi | 2008-11-15 12:01:48 -0700 (Sat, 15 Nov 2008) | 1 line
+Changed paths:
+ M /trunk/asymptote/base/markers.asy
+ M /trunk/asymptote/doc/markers2.asy
+
+fix markangle orientation.
+------------------------------------------------------------------------
+r3751 | jcbowman | 2008-11-15 09:28:48 -0700 (Sat, 15 Nov 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+
+Add missing sentence.
+
+------------------------------------------------------------------------
+r3750 | jcbowman | 2008-11-15 09:14:20 -0700 (Sat, 15 Nov 2008) | 3 lines
+Changed paths:
+ M /trunk/asymptote/base/plain_picture.asy
+ M /trunk/asymptote/doc/asymptote.texi
+
+Add optional user=false argument to min(picture), max(picture), and
+size(picture).
+
+------------------------------------------------------------------------
+r3749 | jcbowman | 2008-11-13 01:28:01 -0700 (Thu, 13 Nov 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/three.asy
+
+Fix degenerate thick line caps.
+
+------------------------------------------------------------------------
+r3748 | jcbowman | 2008-11-12 16:51:01 -0700 (Wed, 12 Nov 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/three.asy
+
+Don't discard 2D size constraints in draw.
+
+------------------------------------------------------------------------
+r3747 | jcbowman | 2008-11-12 13:59:16 -0700 (Wed, 12 Nov 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/patches/README
+ A /trunk/asymptote/patches/freeglut-2.4.0-svn759.patch
+
+Reinstate freeglut-2.4.0-svn759.patch which to fix multisampling bugs.
+
+------------------------------------------------------------------------
+r3746 | jcbowman | 2008-11-11 19:24:50 -0700 (Tue, 11 Nov 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/glrender.cc
+
+Hide window only if iconify is true.
+
+------------------------------------------------------------------------
+r3745 | jcbowman | 2008-11-11 16:09:29 -0700 (Tue, 11 Nov 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/glrender.h
+
+Fix logic in r3744.
+
+------------------------------------------------------------------------
+r3744 | jcbowman | 2008-11-11 16:05:01 -0700 (Tue, 11 Nov 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/glrender.h
+
+Combine both _GLUfuncptr MacOSX workarounds.
+
+------------------------------------------------------------------------
+r3743 | jcbowman | 2008-11-11 12:45:14 -0700 (Tue, 11 Nov 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/glrender.h
+
+Fix _GLUfuncptr detection.
+
+------------------------------------------------------------------------
+r3742 | jcbowman | 2008-11-11 10:42:51 -0700 (Tue, 11 Nov 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/glrender.h
+
+Support compilation under MacOSX 10.5.
+
+------------------------------------------------------------------------
+r3741 | jcbowman | 2008-11-11 03:31:25 -0700 (Tue, 11 Nov 2008) | 1 line
+Changed paths:
+ M /trunk/asymptote/configure.ac
+
+Increment version to 1.52svn.
+------------------------------------------------------------------------
+r3740 | jcbowman | 2008-11-11 02:34:18 -0700 (Tue, 11 Nov 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/asymptote.spec
+ M /trunk/asymptote/picture.cc
+
+Wait for completion of rendering.
+
+------------------------------------------------------------------------
+r3739 | jcbowman | 2008-11-11 01:26:45 -0700 (Tue, 11 Nov 2008) | 2 lines
+Changed paths:
+ D /trunk/asymptote/patches/cygwin_freeglut-2.4.0.patch
+ D /trunk/asymptote/patches/freeglut-2.4.0-svn759.patch
+
+Remove obsolete patches.
+
+------------------------------------------------------------------------
+r3738 | jcbowman | 2008-11-11 01:25:59 -0700 (Tue, 11 Nov 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/patches/README
+ A /trunk/asymptote/patches/freeglut-2.4.0multisample.patch
+
+Use a more robust patch to enable multisampling in freeglut-2.4.0.
+
+------------------------------------------------------------------------
+r3737 | jcbowman | 2008-11-11 01:03:48 -0700 (Tue, 11 Nov 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/picture.cc
+
+Fix warning message.
+
+------------------------------------------------------------------------
+r3736 | jcbowman | 2008-11-11 01:00:49 -0700 (Tue, 11 Nov 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/configure.ac
+ M /trunk/asymptote/picture.cc
+
+Change references to freeglut to glut.
+
+------------------------------------------------------------------------
+r3735 | jcbowman | 2008-11-11 00:57:27 -0700 (Tue, 11 Nov 2008) | 6 lines
+Changed paths:
+ M /trunk/asymptote/glrender.cc
+ M /trunk/asymptote/main.cc
+ M /trunk/asymptote/picture.cc
+
+Improve memory performance and reduce rendering conflicts by always forking;
+remove last dependence on freeglut.
+
+Don't solicit bug reports for segmentation faults caused by graphics driver
+bugs (e.g. on memory exhaustion).
+
+------------------------------------------------------------------------
+r3734 | jcbowman | 2008-11-10 23:53:34 -0700 (Mon, 10 Nov 2008) | 4 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/glrender.cc
+ M /trunk/asymptote/settings.cc
+
+Prevent multiple glInit calls.
+
+Use a separate multisample setting to control screen antialiasing.
+
+------------------------------------------------------------------------
+r3733 | jcbowman | 2008-11-10 20:31:57 -0700 (Mon, 10 Nov 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/glrender.cc
+
+Turn multisampling on only when View is true.
+
+------------------------------------------------------------------------
+r3732 | jcbowman | 2008-11-10 20:15:07 -0700 (Mon, 10 Nov 2008) | 1 line
+Changed paths:
+ M /trunk/asymptote/configure.ac
+
+Increment version to 1.51svn.
+------------------------------------------------------------------------
+r3731 | jcbowman | 2008-11-10 19:06:43 -0700 (Mon, 10 Nov 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/patches/README
+ A /trunk/asymptote/patches/cygwin_freeglut-2.4.0.patch
+
+Add multisampling patch for freeglut-2.4.0 under CYGWIN.
+
+------------------------------------------------------------------------
+r3730 | jcbowman | 2008-11-10 17:39:40 -0700 (Mon, 10 Nov 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/glrender.cc
+ M /trunk/asymptote/glrender.h
+
+Update CYGWIN port.
+
+------------------------------------------------------------------------
+r3729 | jcbowman | 2008-11-09 23:46:21 -0700 (Sun, 09 Nov 2008) | 4 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/glrender.cc
+ M /trunk/asymptote/patches/README
+ A /trunk/asymptote/patches/freeglut-2.4.0-svn759.patch
+
+Control multisampling with antialias flag.
+
+Add patch to bring freeglut-2.4.0 up to date, with multisampling support.
+
+------------------------------------------------------------------------
+r3728 | jcbowman | 2008-11-09 15:22:45 -0700 (Sun, 09 Nov 2008) | 4 lines
+Changed paths:
+ M /trunk/asymptote/drawsurface.cc
+ M /trunk/asymptote/glrender.cc
+
+Support multisampling; this requires the latest svn version of freeglut.
+
+Support -iconic and mouse wheel with the latest svn version of freeglut.
+
+------------------------------------------------------------------------
+r3727 | jcbowman | 2008-11-09 10:05:55 -0700 (Sun, 09 Nov 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/glrender.cc
+
+Don't allow tile size to exceed current window size.
+
+------------------------------------------------------------------------
+r3726 | jcbowman | 2008-11-09 01:02:17 -0700 (Sun, 09 Nov 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.sty
+
+Set default value of settings.render in asymptote.sty to 4.
+
+------------------------------------------------------------------------
+r3725 | jcbowman | 2008-11-09 01:00:15 -0700 (Sun, 09 Nov 2008) | 6 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/doc/latexusage.tex
+
+Illustrate the use of viewportmargin in latexusage.tex.
+
+Set the default value of settings.render in asymptote.sty to 4.
+
+Update documentation.
+
+------------------------------------------------------------------------
+r3724 | jcbowman | 2008-11-09 00:21:06 -0700 (Sun, 09 Nov 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/three.asy
+ M /trunk/asymptote/doc/asymptote.texi
+
+Add viewportmargin parameter.
+
+------------------------------------------------------------------------
+r3723 | jcbowman | 2008-11-08 17:41:51 -0700 (Sat, 08 Nov 2008) | 6 lines
+Changed paths:
+ M /trunk/asymptote/base/graph.asy
+ M /trunk/asymptote/base/graph3.asy
+ M /trunk/asymptote/base/grid3.asy
+ M /trunk/asymptote/base/markers.asy
+ M /trunk/asymptote/base/palette.asy
+ M /trunk/asymptote/base/plain_arrows.asy
+ M /trunk/asymptote/base/plain_boxes.asy
+ M /trunk/asymptote/base/plain_constants.asy
+ M /trunk/asymptote/base/plain_filldraw.asy
+ M /trunk/asymptote/base/plain_markers.asy
+ M /trunk/asymptote/base/plain_picture.asy
+ M /trunk/asymptote/base/three.asy
+ M /trunk/asymptote/doc/Makefile.in
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/doc/diatom.asy
+ M /trunk/asymptote/doc/errorbars.asy
+ M /trunk/asymptote/doc/imagecontour.asy
+ M /trunk/asymptote/doc/join3.asy
+ M /trunk/asymptote/doc/logimage.asy
+ M /trunk/asymptote/doc/markers1.asy
+ M /trunk/asymptote/examples/cardioid.asy
+ M /trunk/asymptote/examples/cos2theta.asy
+ M /trunk/asymptote/examples/hierarchy.asy
+ M /trunk/asymptote/examples/imagehistogram.asy
+ M /trunk/asymptote/examples/poster.asy
+
+Change Makefile.in to remove latexusage-* instead of latexusage_*.
+
+Change put=Above to above=true and put=Below to above=false.
+
+Remove constants Above and Below.
+
+------------------------------------------------------------------------
+r3722 | jcbowman | 2008-11-08 16:37:34 -0700 (Sat, 08 Nov 2008) | 8 lines
+Changed paths:
+ M /trunk/asymptote/base/three.asy
+ M /trunk/asymptote/doc/asymptote.sty
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/doc/latexusage.tex
+ M /trunk/asymptote/glrender.cc
+ M /trunk/asymptote/settings.cc
+
+Add embed option (default true) to allow one to suppress the embedding of a
+rendered preview image.
+
+Support file attachments in asymptote.sty; this is provides a better method
+for embedding 3D PRC files in a LaTeX document.
+
+Add iconify option.
+
+------------------------------------------------------------------------
+r3721 | jcbowman | 2008-11-07 16:49:58 -0700 (Fri, 07 Nov 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/settings.cc
+
+Set default maxtile to (0,0).
+
+------------------------------------------------------------------------
+r3720 | jcbowman | 2008-11-07 15:42:12 -0700 (Fri, 07 Nov 2008) | 4 lines
+Changed paths:
+ M /trunk/asymptote/base/three.asy
+ M /trunk/asymptote/base/three_surface.asy
+ M /trunk/asymptote/examples/wedge.asy
+
+Fix camera roll.
+
+Fix divide by zero error.
+
+------------------------------------------------------------------------
+r3719 | jcbowman | 2008-11-07 14:06:46 -0700 (Fri, 07 Nov 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/glrender.cc
+
+Fix rendering with -nofitscreen.
+
+------------------------------------------------------------------------
+r3718 | jcbowman | 2008-11-07 09:10:11 -0700 (Fri, 07 Nov 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/three.asy
+ M /trunk/asymptote/examples/sqrtx01.asy
+
+Fix PRC up vector.
+
+------------------------------------------------------------------------
+r3717 | jcbowman | 2008-11-07 06:26:34 -0700 (Fri, 07 Nov 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/asymptote.spec
+ M /trunk/asymptote/configure.ac
+ M /trunk/asymptote/glrender.h
+
+Fix glut.h path under MacOS.
+
+------------------------------------------------------------------------
+r3716 | jcbowman | 2008-11-07 06:17:41 -0700 (Fri, 07 Nov 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/configure.ac
+
+Fix detection of MacOS.
+
+------------------------------------------------------------------------
+r3715 | jcbowman | 2008-11-07 05:59:21 -0700 (Fri, 07 Nov 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+
+Improve documentation of add(picture).
+
+------------------------------------------------------------------------
+r3714 | jcbowman | 2008-11-06 23:51:09 -0700 (Thu, 06 Nov 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/configure.ac
+ M /trunk/asymptote/glrender.h
+ M /trunk/asymptote/tr.cc
+ M /trunk/asymptote/tr.h
+
+Add glut compilation support for MacOSX.
+
+------------------------------------------------------------------------
+r3713 | jcbowman | 2008-11-06 15:18:18 -0700 (Thu, 06 Nov 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/glrender.cc
+
+Initialize window to the maximum tile dimensions again.
+
+------------------------------------------------------------------------
+r3712 | jcbowman | 2008-11-06 15:07:51 -0700 (Thu, 06 Nov 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/settings.cc
+
+Change default value of maxtile to (800,800).
+
+------------------------------------------------------------------------
+r3711 | jcbowman | 2008-11-06 10:59:16 -0700 (Thu, 06 Nov 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+
+Recommend glOptions += " -iconic" for UNIX systems that support this.
+
+------------------------------------------------------------------------
+r3710 | jcbowman | 2008-11-06 10:36:15 -0700 (Thu, 06 Nov 2008) | 4 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/runtime.in
+
+Add interface to runtime view() function.
+
+Document use of glOptions=-iconic for UNIX systems.
+
+------------------------------------------------------------------------
+r3709 | jcbowman | 2008-11-06 10:05:59 -0700 (Thu, 06 Nov 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/glrender.cc
+
+Support -glOptions=-iconic for drivers that allow this.
+
+------------------------------------------------------------------------
+r3708 | jcbowman | 2008-11-06 09:27:46 -0700 (Thu, 06 Nov 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/glrender.cc
+
+Avoid rendering problems caused by iconic option.
+
+------------------------------------------------------------------------
+r3707 | jcbowman | 2008-11-06 08:17:16 -0700 (Thu, 06 Nov 2008) | 3 lines
+Changed paths:
+ M /trunk/asymptote/glrender.cc
+ M /trunk/asymptote/settings.cc
+
+Change default value of maxtile to (0,0), which now means to use the screen
+dimensions.
+
+------------------------------------------------------------------------
+r3706 | jcbowman | 2008-11-06 07:52:25 -0700 (Thu, 06 Nov 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/glrender.cc
+
+Use opaque value in glClearColor.
+
+------------------------------------------------------------------------
+r3705 | jcbowman | 2008-11-05 22:00:49 -0700 (Wed, 05 Nov 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/examples/near_earth.asy
+
+Add PenMargin3 to example.
+
+------------------------------------------------------------------------
+r3704 | jcbowman | 2008-11-05 17:21:12 -0700 (Wed, 05 Nov 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/glrender.cc
+
+With -noV, initialize the window to maxtile.
+
+------------------------------------------------------------------------
+r3703 | jcbowman | 2008-11-05 00:43:18 -0700 (Wed, 05 Nov 2008) | 4 lines
+Changed paths:
+ M /trunk/asymptote/base/three_arrows.asy
+ M /trunk/asymptote/base/three_margins.asy
+ M /trunk/asymptote/drawpath3.cc
+ M /trunk/asymptote/examples/shellmethod.asy
+ M /trunk/asymptote/examples/sqrtx01.asy
+ M /trunk/asymptote/examples/xxsq01x-1.asy
+
+Avoid glDisable(GL_LIGHTING) due to race condition.
+
+Improve Margin3.
+
+------------------------------------------------------------------------
+r3702 | jcbowman | 2008-11-04 23:07:04 -0700 (Tue, 04 Nov 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/three.asy
+ M /trunk/asymptote/base/three_arrows.asy
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/examples/sqrtx01.asy
+ M /trunk/asymptote/examples/workcone.asy
+ M /trunk/asymptote/examples/xxsq01y.asy
+
+Add support for three-dimensional dimension bars.
+
+------------------------------------------------------------------------
+r3701 | jcbowman | 2008-11-04 22:58:18 -0700 (Tue, 04 Nov 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/glrender.cc
+
+Simplify window initialization code.
+
+------------------------------------------------------------------------
+r3700 | jcbowman | 2008-11-04 15:43:44 -0700 (Tue, 04 Nov 2008) | 6 lines
+Changed paths:
+ M /trunk/asymptote/base/three_margins.asy
+ M /trunk/asymptote/base/three_surface.asy
+ M /trunk/asymptote/examples/sqrtx01.asy
+ A /trunk/asymptote/examples/wedge.asy
+
+Fix PenMargin3 and DotMargin3.
+
+Make dotsize consistent for pictures and frames.
+
+Reinstate wedge example.
+
+------------------------------------------------------------------------
+r3699 | jcbowman | 2008-11-04 13:34:48 -0700 (Tue, 04 Nov 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/latexusage.tex
+
+Update hyperref documentation.
+
+------------------------------------------------------------------------
+r3698 | jcbowman | 2008-11-04 11:40:54 -0700 (Tue, 04 Nov 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/solids.asy
+ M /trunk/asymptote/base/three.asy
+
+Standardize triple perp(triple); fix numerical precision issue.
+
+------------------------------------------------------------------------
+r3697 | jcbowman | 2008-11-03 23:50:49 -0700 (Mon, 03 Nov 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/obj.asy
+ M /trunk/asymptote/base/three_light.asy
+ M /trunk/asymptote/base/three_surface.asy
+ M /trunk/asymptote/examples/projectelevation.asy
+
+Fix more normal problems.
+
+------------------------------------------------------------------------
+r3696 | jcbowman | 2008-11-03 23:17:51 -0700 (Mon, 03 Nov 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/three_arrows.asy
+
+Use right-handed transformation.
+
+------------------------------------------------------------------------
+r3695 | jcbowman | 2008-11-03 02:25:16 -0700 (Mon, 03 Nov 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/configure.ac
+
+Decrement version to 1.50svn.
+
+------------------------------------------------------------------------
+r3694 | jcbowman | 2008-11-03 02:15:44 -0700 (Mon, 03 Nov 2008) | 1 line
+Changed paths:
+ M /trunk/asymptote/asymptote.spec
+ M /trunk/asymptote/configure.ac
+
+Increment version to 1.51svn.
+------------------------------------------------------------------------
+r3693 | jcbowman | 2008-11-03 01:12:27 -0700 (Mon, 03 Nov 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/examples/projectrevolution.asy
+
+Make example look better with render=0.
+
+------------------------------------------------------------------------
+r3692 | jcbowman | 2008-11-03 01:10:44 -0700 (Mon, 03 Nov 2008) | 4 lines
+Changed paths:
+ M /trunk/asymptote/doc/latexusage.tex
+ M /trunk/asymptote/runtime.in
+
+Fix example; texpath currently only handles standard font sizes.
+
+Fix handling of keep flag in texpath and strokepath.
+
+------------------------------------------------------------------------
+r3691 | jcbowman | 2008-11-03 00:43:59 -0700 (Mon, 03 Nov 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/examples/washermethod.asy
+
+Improve example.
+
+------------------------------------------------------------------------
+r3690 | jcbowman | 2008-11-03 00:38:07 -0700 (Mon, 03 Nov 2008) | 6 lines
+Changed paths:
+ M /trunk/asymptote/base/math.asy
+ M /trunk/asymptote/base/three.asy
+ M /trunk/asymptote/base/three_surface.asy
+ M /trunk/asymptote/examples/washermethod.asy
+ M /trunk/asymptote/glrender.cc
+
+Fix surface normal calculation.
+
+Add patch reverse(patch) function.
+
+Improve normal(path3); add normal(triple[]) for polygons.
+
+------------------------------------------------------------------------
+r3689 | jcbowman | 2008-11-02 18:52:42 -0700 (Sun, 02 Nov 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/three_surface.asy
+
+Add missing transform of normal vector.
+
+------------------------------------------------------------------------
+r3688 | jcbowman | 2008-11-02 13:50:09 -0700 (Sun, 02 Nov 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/plain_pens.asy
+ M /trunk/asymptote/doc/asymptote.texi
+
+Document glOptions=-indirect.
+
+------------------------------------------------------------------------
+r3687 | jcbowman | 2008-11-02 10:17:56 -0700 (Sun, 02 Nov 2008) | 4 lines
+Changed paths:
+ M /trunk/asymptote/base/plain_pens.asy
+
+Change mean(pen[]) to take a more useful opacity function.
+
+Add opacity argument to mean(pen[][]).
+
+------------------------------------------------------------------------
+r3686 | jcbowman | 2008-11-02 09:33:08 -0700 (Sun, 02 Nov 2008) | 5 lines
+Changed paths:
+ M /trunk/asymptote/base/plain_pens.asy
+ M /trunk/asymptote/base/three_surface.asy
+ M /trunk/asymptote/examples/vertexshading.asy
+
+Reinstate cornermean.
+
+Make mean(pen[]) return by default an interpolated pen with the minimum
+opacity of all given pens.
+
+------------------------------------------------------------------------
+r3685 | jcbowman | 2008-11-02 01:45:39 -0600 (Sun, 02 Nov 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/examples/projectelevation.asy
+
+Use vertex shading.
+
+------------------------------------------------------------------------
+r3684 | jcbowman | 2008-11-02 01:33:49 -0600 (Sun, 02 Nov 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/examples/parametricelevation.asy
+ M /trunk/asymptote/examples/projectrevolution.asy
+
+Update examples.
+
+------------------------------------------------------------------------
+r3683 | jcbowman | 2008-11-02 01:20:19 -0600 (Sun, 02 Nov 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/examples/projectelevation.asy
+
+Fix example.
+
+------------------------------------------------------------------------
+r3682 | jcbowman | 2008-11-02 01:15:59 -0600 (Sun, 02 Nov 2008) | 1 line
+Changed paths:
+ M /trunk/asymptote/configure.ac
+
+Increment version to 1.49svn.
+------------------------------------------------------------------------
+r3681 | jcbowman | 2008-11-01 23:49:11 -0600 (Sat, 01 Nov 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+
+Document how to draw surfaces with patch-dependent or vertex-dependent colors.
+
+------------------------------------------------------------------------
+r3680 | jcbowman | 2008-11-01 22:44:33 -0600 (Sat, 01 Nov 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/glrender.cc
+
+Remove old fitscreen code.
+
+------------------------------------------------------------------------
+r3679 | jcbowman | 2008-11-01 22:24:42 -0600 (Sat, 01 Nov 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+
+Document surface tube(path3 g, real width).
+
+------------------------------------------------------------------------
+r3678 | jcbowman | 2008-11-01 22:15:11 -0600 (Sat, 01 Nov 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/path.cc
+
+Fix incorrect precontrol output in write(path) introduced in r3554.
+
+------------------------------------------------------------------------
+r3677 | jcbowman | 2008-11-01 21:54:00 -0600 (Sat, 01 Nov 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/drawsurface.cc
+
+Account for perspective scaling in planar test.
+
+------------------------------------------------------------------------
+r3676 | oshardt | 2008-11-01 14:52:41 -0600 (Sat, 01 Nov 2008) | 1 line
+Changed paths:
+ M /trunk/asymptote/GUI/xasy2asy.py
+
+Use unstraighten() to obtain control points of straight segments.
+------------------------------------------------------------------------
+r3675 | jcbowman | 2008-11-01 14:13:16 -0600 (Sat, 01 Nov 2008) | 3 lines
+Changed paths:
+ M /trunk/asymptote/path.h
+ M /trunk/asymptote/runtime.in
+
+Implement path unstraighten(path), which returns a copy of the path with
+the straight flag turned off.
+
+------------------------------------------------------------------------
+r3674 | jcbowman | 2008-11-01 13:36:29 -0600 (Sat, 01 Nov 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/three.asy
+ M /trunk/asymptote/path3.cc
+
+Specify an angle precision for centering perspective drawings.
+
+------------------------------------------------------------------------
+r3673 | jcbowman | 2008-11-01 11:52:48 -0600 (Sat, 01 Nov 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/three.asy
+
+Increase angleiterations to 4.
+
+------------------------------------------------------------------------
+r3672 | jcbowman | 2008-11-01 11:35:33 -0600 (Sat, 01 Nov 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/glrender.cc
+
+Allow odd sized tiles again.
+
+------------------------------------------------------------------------
+r3671 | jcbowman | 2008-11-01 10:47:26 -0600 (Sat, 01 Nov 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/drawsurface.cc
+ M /trunk/asymptote/glrender.cc
+
+Set surface normals whenever light is on.
+
+------------------------------------------------------------------------
+r3670 | jcbowman | 2008-11-01 10:02:28 -0600 (Sat, 01 Nov 2008) | 4 lines
+Changed paths:
+ M /trunk/asymptote/base/plain_pens.asy
+ M /trunk/asymptote/base/three_surface.asy
+ A /trunk/asymptote/examples/BezierPatch.asy
+ M /trunk/asymptote/examples/elevation.asy
+ M /trunk/asymptote/examples/sphericalharmonic.asy
+
+Transpose surface.corners() and surface.map().
+
+Use mean corner pen for patch shading.
+
+------------------------------------------------------------------------
+r3669 | jcbowman | 2008-11-01 08:58:09 -0600 (Sat, 01 Nov 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/three.asy
+
+Increase angleiterations.
+
+------------------------------------------------------------------------
+r3668 | pivaldi | 2008-11-01 03:43:57 -0600 (Sat, 01 Nov 2008) | 1 line
+Changed paths:
+ M /trunk/asymptote/examples/projectelevation.asy
+
+update examples/projectelevation.asy
+------------------------------------------------------------------------
+r3667 | jcbowman | 2008-11-01 02:29:24 -0600 (Sat, 01 Nov 2008) | 4 lines
+Changed paths:
+ M /trunk/asymptote/base/three_surface.asy
+ M /trunk/asymptote/examples/elevation.asy
+ M /trunk/asymptote/examples/smoothelevation.asy
+ M /trunk/asymptote/examples/sphericalharmonic.asy
+
+Rename cornermap to map and cornermean to mapmean.
+
+Add triple[][] corner() and triple[] cornermean().
+
+------------------------------------------------------------------------
+r3666 | jcbowman | 2008-11-01 01:39:32 -0600 (Sat, 01 Nov 2008) | 10 lines
+Changed paths:
+ M /trunk/asymptote/base/obj.asy
+ M /trunk/asymptote/base/plain_pens.asy
+ M /trunk/asymptote/base/three.asy
+ M /trunk/asymptote/base/three_light.asy
+ M /trunk/asymptote/base/three_surface.asy
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/drawsurface.cc
+ M /trunk/asymptote/drawsurface.h
+ M /trunk/asymptote/examples/smoothelevation.asy
+ M /trunk/asymptote/glrender.cc
+ M /trunk/asymptote/runtime.in
+
+Support lighting with vertex shading.
+
+Fix surface lighting with render=0.
+
+Fix normal(path3).
+
+Move rgba pen packing and unpacking functions to plain_pens.asy.
+
+Implement pen mean(pen[]).
+
+------------------------------------------------------------------------
+r3665 | jcbowman | 2008-10-31 21:48:25 -0600 (Fri, 31 Oct 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/glrender.cc
+
+Force tile size to be even.
+
+------------------------------------------------------------------------
+r3664 | jcbowman | 2008-10-31 17:48:33 -0600 (Fri, 31 Oct 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/glrender.cc
+ M /trunk/asymptote/settings.cc
+
+Make maxviewport and maxtile pairs.
+
+------------------------------------------------------------------------
+r3663 | pivaldi | 2008-10-31 17:29:36 -0600 (Fri, 31 Oct 2008) | 1 line
+Changed paths:
+ M /trunk/asymptote/base/asy-mode.el
+
+asy-mode: warn cc-mode.el dependency.
+------------------------------------------------------------------------
+r3662 | jcbowman | 2008-10-31 17:18:14 -0600 (Fri, 31 Oct 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/configure.ac
+ M /trunk/asymptote/glrender.cc
+ M /trunk/asymptote/picture.cc
+ M /trunk/asymptote/settings.cc
+
+Support compilation under standard glut for systems without freeglut.
+
+------------------------------------------------------------------------
+r3661 | jcbowman | 2008-10-31 15:39:00 -0600 (Fri, 31 Oct 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/glrender.cc
+
+Fix fitscreen toggling.
+
+------------------------------------------------------------------------
+r3660 | jcbowman | 2008-10-31 15:34:07 -0600 (Fri, 31 Oct 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/glrender.cc
+ M /trunk/asymptote/settings.cc
+
+Add tilesize parameter to limit the maximum rendering tile size.
+
+------------------------------------------------------------------------
+r3659 | jcbowman | 2008-10-31 08:48:04 -0600 (Fri, 31 Oct 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/asy-mode.el
+
+Revert last change, which breaks tabbing after struct{}.
+
+------------------------------------------------------------------------
+r3658 | pivaldi | 2008-10-31 07:36:39 -0600 (Fri, 31 Oct 2008) | 1 line
+Changed paths:
+ M /trunk/asymptote/base/asy-mode.el
+
+asy-mode: fix cc-mode code source dependency.
+------------------------------------------------------------------------
+r3657 | jcbowman | 2008-10-31 01:12:53 -0600 (Fri, 31 Oct 2008) | 4 lines
+Changed paths:
+ M /trunk/asymptote/base/palette.asy
+ M /trunk/asymptote/base/three_surface.asy
+ M /trunk/asymptote/examples/elevation.asy
+ M /trunk/asymptote/examples/projectelevation.asy
+ A /trunk/asymptote/examples/smoothelevation.asy
+ M /trunk/asymptote/examples/sphericalharmonic.asy
+
+Simplify construction of elevation-colored surfaces.
+
+Add facility for vertex-shaded elevation surfaces.
+
+------------------------------------------------------------------------
+r3656 | jcbowman | 2008-10-30 23:42:55 -0600 (Thu, 30 Oct 2008) | 4 lines
+Changed paths:
+ M /trunk/asymptote/glrender.cc
+
+Fix initialization and translation issues.
+
+Remove unneeded CYGWIN restrictions.
+
+------------------------------------------------------------------------
+r3655 | jcbowman | 2008-10-30 22:04:53 -0600 (Thu, 30 Oct 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/glrender.cc
+
+Fix orthographic exports.
+
+------------------------------------------------------------------------
+r3654 | jcbowman | 2008-10-30 21:48:52 -0600 (Thu, 30 Oct 2008) | 7 lines
+Changed paths:
+ M /trunk/asymptote/Makefile.in
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/drawelement.h
+ M /trunk/asymptote/drawpath3.cc
+ M /trunk/asymptote/drawpath3.h
+ M /trunk/asymptote/drawsurface.cc
+ M /trunk/asymptote/drawsurface.h
+ M /trunk/asymptote/glrender.cc
+ M /trunk/asymptote/picture.cc
+ M /trunk/asymptote/picture.h
+ M /trunk/asymptote/settings.cc
+ A /trunk/asymptote/tr.cc
+ A /trunk/asymptote/tr.h
+
+Use Brian Paul's tr-1.3 package to support high-resolution OpenGL tiled
+rendering.
+
+Add antialias setting (default true).
+
+Change convert to use default antialias setting.
+
+------------------------------------------------------------------------
+r3653 | jcbowman | 2008-10-30 21:16:31 -0600 (Thu, 30 Oct 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/plain_boxes.asy
+
+Add roundbox envelope routine.
+
+------------------------------------------------------------------------
+r3652 | jcbowman | 2008-10-29 22:22:06 -0600 (Wed, 29 Oct 2008) | 6 lines
+Changed paths:
+ M /trunk/asymptote/base/obj.asy
+ M /trunk/asymptote/base/plain_markers.asy
+ M /trunk/asymptote/base/three.asy
+ M /trunk/asymptote/base/three_surface.asy
+ M /trunk/asymptote/doc/asymptote.texi
+
+Turn on straight flag only for piecewise straight planar paths.
+
+Force straight flag for all obj faces to avoid subdivision cracks.
+
+Make normal(path3) return immediately for nonplanar paths.
+
+------------------------------------------------------------------------
+r3651 | jcbowman | 2008-10-29 19:39:28 -0600 (Wed, 29 Oct 2008) | 5 lines
+Changed paths:
+ M /trunk/asymptote/base/plain_picture.asy
+ M /trunk/asymptote/doc/asymptote.texi
+
+Change signature of point to pair point(picture, pair, bool user=true) to
+allow a return value in PostScript coordinates.
+
+Remove framepoint in favour of truepoint(picture, pair, user=false).
+
+------------------------------------------------------------------------
+r3650 | jcbowman | 2008-10-29 17:10:25 -0600 (Wed, 29 Oct 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/plain_markers.asy
+
+Add maxheight, hstretch, and vstretch parameters to legend.
+
+------------------------------------------------------------------------
+r3649 | jcbowman | 2008-10-29 11:48:12 -0600 (Wed, 29 Oct 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/solids.asy
+ M /trunk/asymptote/doc/asymptote.texi
+
+Add defaultbackpen.
+
+------------------------------------------------------------------------
+r3648 | pivaldi | 2008-10-29 03:42:28 -0600 (Wed, 29 Oct 2008) | 1 line
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.sty
+
+Add TeX versioning
+------------------------------------------------------------------------
+r3647 | jcbowman | 2008-10-29 01:28:12 -0600 (Wed, 29 Oct 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/drawsurface.cc
+ M /trunk/asymptote/drawsurface.h
+ A /trunk/asymptote/examples/vertexshading.asy
+
+Support transparency in vertex shading.
+
+------------------------------------------------------------------------
+r3646 | jcbowman | 2008-10-29 00:50:50 -0600 (Wed, 29 Oct 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/three_surface.asy
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/drawpath3.cc
+ M /trunk/asymptote/drawsurface.cc
+ M /trunk/asymptote/drawsurface.h
+ M /trunk/asymptote/glrender.cc
+ M /trunk/asymptote/runtime.in
+
+Support vertex shading in OpenGL renderer.
+
+------------------------------------------------------------------------
+r3645 | jcbowman | 2008-10-28 17:40:42 -0600 (Tue, 28 Oct 2008) | 4 lines
+Changed paths:
+ M /trunk/asymptote/asymptote.spec
+ M /trunk/asymptote/base/three_light.asy
+ M /trunk/asymptote/base/three_surface.asy
+
+Use centroid rather than the first vertex for splitting surfaces.
+
+Rename unpack to real[] rgba(pen) and add inverse function pen rgb(real[]).
+
+------------------------------------------------------------------------
+r3644 | jcbowman | 2008-10-28 01:42:51 -0600 (Tue, 28 Oct 2008) | 6 lines
+Changed paths:
+ M /trunk/asymptote/base/bezulate.asy
+ M /trunk/asymptote/base/obj.asy
+ M /trunk/asymptote/base/three.asy
+ M /trunk/asymptote/base/three_surface.asy
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/doc/latexusage.tex
+ A /trunk/asymptote/examples/colorplanes.asy
+ A /trunk/asymptote/examples/projectelevation.asy
+ A /trunk/asymptote/examples/projectrevolution.asy
+
+Add a more versatile and more efficient surface constructor for convex and
+"piecewise-convex" three-dimensional paths; the planar(path3) constructor
+should now only be used for nonconvex paths.
+
+Update examples.
+
+------------------------------------------------------------------------
+r3643 | jcbowman | 2008-10-28 00:53:18 -0600 (Tue, 28 Oct 2008) | 6 lines
+Changed paths:
+ M /trunk/asymptote/base/three_arrows.asy
+ M /trunk/asymptote/doc/asymptote.texi
+
+Implement DefaultHead2(filltype filltype=Fill).
+
+Add optional filltype argument to HookHead2.
+
+Reduce adaptive thick line constant.
+
+------------------------------------------------------------------------
+r3642 | pivaldi | 2008-10-27 07:32:59 -0600 (Mon, 27 Oct 2008) | 1 line
+Changed paths:
+ M /trunk/asymptote/examples/parametricelevation.asy
+
+add size to parametricelevation.asy
+------------------------------------------------------------------------
+r3641 | pivaldi | 2008-10-26 17:53:47 -0600 (Sun, 26 Oct 2008) | 1 line
+Changed paths:
+ M /trunk/asymptote/glrender.cc
+
+revert wrong commit of glrender.cc
+------------------------------------------------------------------------
+r3640 | pivaldi | 2008-10-26 17:46:53 -0600 (Sun, 26 Oct 2008) | 1 line
+Changed paths:
+ M /trunk/asymptote/examples/sphericalharmonic.asy
+ M /trunk/asymptote/glrender.cc
+
+add size to sphericalharmonic.asy.
+------------------------------------------------------------------------
+r3639 | jcbowman | 2008-10-26 17:37:14 -0600 (Sun, 26 Oct 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/three_arrows.asy
+
+Further adaptive thick line improvements.
+
+------------------------------------------------------------------------
+r3638 | jcbowman | 2008-10-26 15:52:26 -0600 (Sun, 26 Oct 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/three_arrows.asy
+
+Improve thick line adaptive step routine.
+
+------------------------------------------------------------------------
+r3637 | jcbowman | 2008-10-26 14:35:58 -0600 (Sun, 26 Oct 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/three.asy
+
+Increase 3D margins.
+
+------------------------------------------------------------------------
+r3636 | jcbowman | 2008-10-25 22:46:42 -0600 (Sat, 25 Oct 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/obj.asy
+
+Work around Adobe Reader rendering bugs.
+
+------------------------------------------------------------------------
+r3635 | jcbowman | 2008-10-25 21:57:23 -0600 (Sat, 25 Oct 2008) | 4 lines
+Changed paths:
+ M /trunk/asymptote/base/graph3.asy
+ M /trunk/asymptote/base/plain_markers.asy
+
+Support 2D alignment of 3D axis labels.
+
+Use more efficient size(pic) routine in legend().
+
+------------------------------------------------------------------------
+r3634 | jcbowman | 2008-10-25 13:01:28 -0600 (Sat, 25 Oct 2008) | 6 lines
+Changed paths:
+ M /trunk/asymptote/base/palette.asy
+ M /trunk/asymptote/base/three_surface.asy
+ M /trunk/asymptote/doc/asymptote.texi
+ A /trunk/asymptote/examples/sphericalharmonic.asy
+
+Resolve ambiguity in draw(surface).
+
+Add Gradient palette that varies linearly over a specified range of pens.
+
+Add spherical harmonic example.
+
+------------------------------------------------------------------------
+r3633 | jcbowman | 2008-10-25 11:16:48 -0600 (Sat, 25 Oct 2008) | 4 lines
+Changed paths:
+ M /trunk/asymptote/doc/FAQ/asy-faq.bfnn
+ M /trunk/asymptote/doc/asymptote.texi
+ A /trunk/asymptote/examples/parametricelevation.asy
+ M /trunk/asymptote/runtime.in
+
+Standardize argument names of dir and expi.
+
+Add parametric surface with elevation-dependent colouring and no light effects.
+
+------------------------------------------------------------------------
+r3632 | jcbowman | 2008-10-24 08:31:50 -0600 (Fri, 24 Oct 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/solids.asy
+
+Fix a numerical precision issue.
+
+------------------------------------------------------------------------
+r3631 | jcbowman | 2008-10-23 02:18:43 -0600 (Thu, 23 Oct 2008) | 1 line
+Changed paths:
+ M /trunk/asymptote/configure.ac
+
+Increment version to 1.48svn.
+------------------------------------------------------------------------
+r3630 | jcbowman | 2008-10-23 00:48:28 -0600 (Thu, 23 Oct 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/three_surface.asy
+ M /trunk/asymptote/doc/asymptote.texi
+
+Add another draw routine for surfaces.
+
+------------------------------------------------------------------------
+r3629 | jcbowman | 2008-10-23 00:39:14 -0600 (Thu, 23 Oct 2008) | 7 lines
+Changed paths:
+ M /trunk/asymptote/base/obj.asy
+ M /trunk/asymptote/base/three.asy
+ M /trunk/asymptote/base/three_surface.asy
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/examples/galleon.asy
+ A /trunk/asymptote/examples/triceratops.asy
+
+Implement a more robust version of normal(path), returning O if the path is
+nonplanar.
+
+Handle nonplanar obj faces.
+
+Add triceratops example.
+
+------------------------------------------------------------------------
+r3628 | jcbowman | 2008-10-22 17:40:56 -0600 (Wed, 22 Oct 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/glrender.cc
+
+Re-enable high-resolution rendering.
+
+------------------------------------------------------------------------
+r3627 | jcbowman | 2008-10-22 16:59:21 -0600 (Wed, 22 Oct 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/runtime.in
+
+Remove diagnostic.
+
+------------------------------------------------------------------------
+r3626 | jcbowman | 2008-10-22 14:52:20 -0600 (Wed, 22 Oct 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/plain_paths.asy
+
+Fix strokepath(nullpath).
+
+------------------------------------------------------------------------
+r3625 | jcbowman | 2008-10-22 14:49:43 -0600 (Wed, 22 Oct 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/plain_paths.asy
+ M /trunk/asymptote/base/stats.asy
+ M /trunk/asymptote/runtime.in
+
+Fix strokepath.
+
+------------------------------------------------------------------------
+r3624 | jcbowman | 2008-10-22 01:55:06 -0600 (Wed, 22 Oct 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/three_surface.asy
+
+Bypass bezulate for paths of length 4.
+
+------------------------------------------------------------------------
+r3623 | jcbowman | 2008-10-21 21:05:17 -0600 (Tue, 21 Oct 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/three.asy
+ M /trunk/asymptote/base/three_surface.asy
+
+Use unit normal in planar.
+
+------------------------------------------------------------------------
+r3622 | jcbowman | 2008-10-21 20:50:31 -0600 (Tue, 21 Oct 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/three.asy
+ M /trunk/asymptote/path.cc
+
+Fix cyclic path bugs in write(path) and write(path3) introduced in r3554.
+
+------------------------------------------------------------------------
+r3621 | jcbowman | 2008-10-21 17:49:30 -0600 (Tue, 21 Oct 2008) | 14 lines
+Changed paths:
+ M /trunk/asymptote/base/three.asy
+ M /trunk/asymptote/base/three_arrows.asy
+ M /trunk/asymptote/base/three_surface.asy
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/examples/Klein.asy
+
+Implement HookHead2 and TeXHead2 arrowheads. These are 2D arrowheads
+lifted to 3D space and aligned according to the initial viewpoint.
+
+Add missing angle parameter in HooHead3.
+
+Simplify planar.
+
+Move arrowheadlight parameter out of Arrow3 and into arrow commands, so
+that the correct value of currentlight is used.
+
+Use tighter values for the margin parameters viewportfactor and anglefactor.
+
+Reduce angleiterations to 2.
+
+------------------------------------------------------------------------
+r3620 | jcbowman | 2008-10-21 13:36:45 -0600 (Tue, 21 Oct 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/glrender.cc
+
+Fit to screen by default.
+
+------------------------------------------------------------------------
+r3619 | jcbowman | 2008-10-21 11:52:54 -0600 (Tue, 21 Oct 2008) | 4 lines
+Changed paths:
+ M /trunk/asymptote/asymptote.spec
+ M /trunk/asymptote/base/plain_picture.asy
+ M /trunk/asymptote/base/three.asy
+ M /trunk/asymptote/base/three_arrows.asy
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/doc/cube.asy
+ M /trunk/asymptote/examples/galleon.asy
+
+Don't generate spurious "camera too close" errors for projections from infinity.
+
+Always use currentlight by default for drawing arrowheads.
+
+------------------------------------------------------------------------
+r3618 | jcbowman | 2008-10-21 09:02:46 -0600 (Tue, 21 Oct 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/CDlabel.asy
+
+Change text on sample CD label to something more Asymptote related.
+
+------------------------------------------------------------------------
+r3617 | jcbowman | 2008-10-21 01:52:33 -0600 (Tue, 21 Oct 2008) | 2 lines
+Changed paths:
+ A /trunk/asymptote/base/three_margins.asy
+
+Add missing file.
+
+------------------------------------------------------------------------
+r3616 | jcbowman | 2008-10-21 01:22:40 -0600 (Tue, 21 Oct 2008) | 2 lines
+Changed paths:
+ A /trunk/asymptote/base/obj.asy
+ M /trunk/asymptote/base/three_surface.asy
+ A /trunk/asymptote/examples/galleon.asy
+
+Add module for reading obj files and example.
+
+------------------------------------------------------------------------
+r3615 | jcbowman | 2008-10-20 23:05:56 -0600 (Mon, 20 Oct 2008) | 4 lines
+Changed paths:
+ M /trunk/asymptote/base/three.asy
+ M /trunk/asymptote/base/three_surface.asy
+ M /trunk/asymptote/doc/asymptote.texi
+
+Allow an array of meshpens when drawing surfaces.
+
+Update documentation.
+
+------------------------------------------------------------------------
+r3614 | jcbowman | 2008-10-20 21:48:12 -0600 (Mon, 20 Oct 2008) | 6 lines
+Changed paths:
+ M /trunk/asymptote/base/bezulate.asy
+ M /trunk/asymptote/base/three.asy
+ M /trunk/asymptote/base/three_surface.asy
+ M /trunk/asymptote/glrender.cc
+
+Move path length tests to surface constructor.
+
+Add bool warn=true to planar and normal(path3).
+
+Check incoming width and height parameters.
+
+------------------------------------------------------------------------
+r3613 | jcbowman | 2008-10-20 16:31:26 -0600 (Mon, 20 Oct 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/three.asy
+
+Fix prefix again.
+
+------------------------------------------------------------------------
+r3612 | jcbowman | 2008-10-20 16:19:41 -0600 (Mon, 20 Oct 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/three.asy
+ M /trunk/asymptote/base/three_arrows.asy
+ M /trunk/asymptote/doc/asymptote.texi
+
+Implement 3D margins.
+
+------------------------------------------------------------------------
+r3611 | hammera | 2008-10-20 12:25:25 -0600 (Mon, 20 Oct 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/syzygy.asy
+
+Fixed watch() and unwatch() to use atupdate().
+
+------------------------------------------------------------------------
+r3610 | jcbowman | 2008-10-20 01:36:47 -0600 (Mon, 20 Oct 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/three_surface.asy
+ M /trunk/asymptote/glrender.cc
+
+Add surface constructors for triangles.
+
+------------------------------------------------------------------------
+r3609 | jcbowman | 2008-10-19 20:54:46 -0600 (Sun, 19 Oct 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/three_surface.asy
+
+Add missing transform for projected 3D mesh lines.
+
+------------------------------------------------------------------------
+r3608 | jcbowman | 2008-10-19 19:47:40 -0600 (Sun, 19 Oct 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/three_surface.asy
+ M /trunk/asymptote/examples/elevation.asy
+
+Use cornermean instead of center.
+
+------------------------------------------------------------------------
+r3607 | jcbowman | 2008-10-19 19:26:02 -0600 (Sun, 19 Oct 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/grid3.asy
+
+Add missing put argument.
+
+------------------------------------------------------------------------
+r3606 | jcbowman | 2008-10-19 17:43:03 -0600 (Sun, 19 Oct 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/runtime.in
+
+Fix range check in both places; consolidate PostScript code.
+
+------------------------------------------------------------------------
+r3605 | jcbowman | 2008-10-19 17:27:37 -0600 (Sun, 19 Oct 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/runtime.in
+ M /trunk/asymptote/settings.cc
+
+Fix range check in strokepath (and potentially texpath).
+
+------------------------------------------------------------------------
+r3604 | jcbowman | 2008-10-19 16:32:44 -0600 (Sun, 19 Oct 2008) | 5 lines
+Changed paths:
+ M /trunk/asymptote/base/palette.asy
+ M /trunk/asymptote/doc/asymptote.texi
+ A /trunk/asymptote/examples/elevation.asy
+
+Implement functions that construct a pen array from a given function and
+palette.
+
+Add elevation example.
+
+------------------------------------------------------------------------
+r3603 | jcbowman | 2008-10-19 15:22:09 -0600 (Sun, 19 Oct 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/graph3.asy
+ M /trunk/asymptote/base/three_light.asy
+ M /trunk/asymptote/base/three_surface.asy
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/examples/epix.asy
+
+Add support for using a different surfacepen for each patch.
+
+------------------------------------------------------------------------
+r3602 | jcbowman | 2008-10-19 13:17:34 -0600 (Sun, 19 Oct 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/examples/epix.asy
+
+Document default pen argument of strokepath.
+
+------------------------------------------------------------------------
+r3601 | jcbowman | 2008-10-19 10:31:51 -0600 (Sun, 19 Oct 2008) | 3 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/runtime.in
+
+Implement path[] strokepath(path g, pen p), which returns the path array that
+PostScript would fill in drawing path g with pen p.
+
+------------------------------------------------------------------------
+r3600 | jcbowman | 2008-10-18 13:53:43 -0600 (Sat, 18 Oct 2008) | 1 line
+Changed paths:
+ M /trunk/asymptote/configure.ac
+
+Increment version to 1.47svn.
+------------------------------------------------------------------------
+r3599 | jcbowman | 2008-10-18 12:36:00 -0600 (Sat, 18 Oct 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/plain_shipout.asy
+ M /trunk/asymptote/doc/Makefile.in
+ M /trunk/asymptote/doc/asymptote.texi
+
+Allow one to disable embedding of inline PRC files within LaTeX.
+
+------------------------------------------------------------------------
+r3598 | jcbowman | 2008-10-18 11:48:45 -0600 (Sat, 18 Oct 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/asymptote.spec
+ M /trunk/asymptote/doc/Makefile.in
+
+Try to produce a preview image of latexusage for the manual.
+
+------------------------------------------------------------------------
+r3597 | jcbowman | 2008-10-18 11:01:22 -0600 (Sat, 18 Oct 2008) | 4 lines
+Changed paths:
+ M /trunk/asymptote/base/plain_shipout.asy
+ M /trunk/asymptote/examples/animations/sphere.asy
+ M /trunk/asymptote/picture.cc
+
+Signal an error if the user tries to render an image without freeglut.
+
+Support embedding of 3D PRC files when -render=0.
+
+------------------------------------------------------------------------
+r3596 | jcbowman | 2008-10-18 02:48:43 -0600 (Sat, 18 Oct 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/examples/Klein.asy
+ M /trunk/asymptote/examples/animations/sphere.asy
+
+Update examples.
+
+------------------------------------------------------------------------
+r3595 | jcbowman | 2008-10-18 02:35:15 -0600 (Sat, 18 Oct 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/examples/animations/sphere.asy
+
+Update example.
+
+------------------------------------------------------------------------
+r3594 | jcbowman | 2008-10-18 02:30:53 -0600 (Sat, 18 Oct 2008) | 1 line
+Changed paths:
+ M /trunk/asymptote/configure.ac
+
+Increment version to 1.46svn.
+------------------------------------------------------------------------
+r3593 | jcbowman | 2008-10-18 00:46:29 -0600 (Sat, 18 Oct 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/three.asy
+ M /trunk/asymptote/doc/asymptote.texi
+ A /trunk/asymptote/examples/planeproject.asy
+
+Add planeproject routines, courtesy of Philippe Ivaldi.
+
+------------------------------------------------------------------------
+r3592 | jcbowman | 2008-10-17 23:44:47 -0600 (Fri, 17 Oct 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/three_surface.asy
+ M /trunk/asymptote/doc/Makefile.in
+ M /trunk/asymptote/doc/asymptote.texi
+
+Documentation updates.
+
+------------------------------------------------------------------------
+r3591 | jcbowman | 2008-10-17 21:12:11 -0600 (Fri, 17 Oct 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/glrender.cc
+
+Fix fitting issues.
+
+------------------------------------------------------------------------
+r3590 | jcbowman | 2008-10-17 16:55:36 -0600 (Fri, 17 Oct 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/glrender.cc
+
+Fix handling of minimumsize.
+
+------------------------------------------------------------------------
+r3589 | jcbowman | 2008-10-17 16:07:48 -0600 (Fri, 17 Oct 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/three.asy
+
+Increase tolerance of normal(path3).
+
+------------------------------------------------------------------------
+r3588 | jcbowman | 2008-10-17 14:11:32 -0600 (Fri, 17 Oct 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/three.asy
+ M /trunk/asymptote/examples/BezierSurface.asy
+
+Standardize embed options; fix labels.
+
+------------------------------------------------------------------------
+r3587 | jcbowman | 2008-10-17 13:25:17 -0600 (Fri, 17 Oct 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+
+Add link to PRC specification.
+
+------------------------------------------------------------------------
+r3586 | jcbowman | 2008-10-17 11:52:14 -0600 (Fri, 17 Oct 2008) | 4 lines
+Changed paths:
+ M /trunk/asymptote/base/graph.asy
+ M /trunk/asymptote/base/graph3.asy
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/path.h
+ M /trunk/asymptote/path3.h
+ M /trunk/asymptote/runtime.in
+
+Fix dir normalizations.
+
+Ignore spurious warnings from degrees.
+
+------------------------------------------------------------------------
+r3585 | jcbowman | 2008-10-17 11:20:47 -0600 (Fri, 17 Oct 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/latexusage.tex
+
+Illustrate use of global TeX macro.
+
+------------------------------------------------------------------------
+r3584 | jcbowman | 2008-10-17 01:26:45 -0600 (Fri, 17 Oct 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+
+Document direction invert routine.
+
+------------------------------------------------------------------------
+r3583 | jcbowman | 2008-10-17 01:19:46 -0600 (Fri, 17 Oct 2008) | 4 lines
+Changed paths:
+ M /trunk/asymptote/base/solids.asy
+ M /trunk/asymptote/base/three_arrows.asy
+ M /trunk/asymptote/doc/asymptote.texi
+
+Fix DefaultHead3 size.
+
+Update documentation.
+
+------------------------------------------------------------------------
+r3582 | jcbowman | 2008-10-16 22:32:10 -0600 (Thu, 16 Oct 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/path.h
+ M /trunk/asymptote/runtime.in
+
+Add 2D versions of accel and radius of curvature functions.
+
+------------------------------------------------------------------------
+r3581 | jcbowman | 2008-10-16 21:48:08 -0600 (Thu, 16 Oct 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/three_arrows.asy
+ M /trunk/asymptote/drawsurface.cc
+ M /trunk/asymptote/path.h
+ M /trunk/asymptote/path3.h
+ M /trunk/asymptote/runtime.in
+
+Fix radius and non-normalized dir functions.
+
+------------------------------------------------------------------------
+r3580 | jcbowman | 2008-10-16 11:37:26 -0600 (Thu, 16 Oct 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/solids.asy
+
+Fix numerical resolution issue.
+
+------------------------------------------------------------------------
+r3579 | jcbowman | 2008-10-16 01:08:49 -0600 (Thu, 16 Oct 2008) | 8 lines
+Changed paths:
+ M /trunk/asymptote/base/three.asy
+ M /trunk/asymptote/base/three_arrows.asy
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/path.h
+ M /trunk/asymptote/path3.h
+ M /trunk/asymptote/runtime.in
+
+Add a routine to compute the radius of curvature of a path3 at a point.
+
+Improve adaptive thick line algorithm.
+
+Add option to suppress normalization of dir functions.
+
+Remove secondary camera adjustment call.
+
+------------------------------------------------------------------------
+r3578 | jcbowman | 2008-10-15 18:12:14 -0600 (Wed, 15 Oct 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/three_arrows.asy
+
+Minor optimization.
+
+------------------------------------------------------------------------
+r3577 | jcbowman | 2008-10-15 18:03:05 -0600 (Wed, 15 Oct 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/plain_arrows.asy
+ M /trunk/asymptote/base/three_arrows.asy
+
+Fix arrow3 sizing.
+
+------------------------------------------------------------------------
+r3576 | jcbowman | 2008-10-15 00:14:19 -0600 (Wed, 15 Oct 2008) | 4 lines
+Changed paths:
+ M /trunk/asymptote/base/plain_picture.asy
+ M /trunk/asymptote/base/three.asy
+ M /trunk/asymptote/base/three_surface.asy
+
+Implement triple invert(pair dir, triple v, projection P=currentprojection).
+
+Add a 3D arrow routine that accepts a pair direction.
+
+------------------------------------------------------------------------
+r3575 | jcbowman | 2008-10-14 23:42:35 -0600 (Tue, 14 Oct 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/plain_arrows.asy
+ M /trunk/asymptote/base/solids.asy
+ M /trunk/asymptote/base/three_arrows.asy
+ M /trunk/asymptote/base/three_surface.asy
+
+Add HookHead3 and TeXHead3 arrowhead styles.
+
+------------------------------------------------------------------------
+r3574 | jcbowman | 2008-10-14 17:16:17 -0600 (Tue, 14 Oct 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/path.cc
+ M /trunk/asymptote/path.h
+
+Optimize 2D arclength calculation for straight segments.
+
+------------------------------------------------------------------------
+r3573 | jcbowman | 2008-10-14 17:15:31 -0600 (Tue, 14 Oct 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/three_surface.asy
+
+Fix degenerate perp vector workaround.
+
+------------------------------------------------------------------------
+r3572 | jcbowman | 2008-10-14 17:14:27 -0600 (Tue, 14 Oct 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/path3.cc
+ M /trunk/asymptote/path3.h
+
+Optimize arclength calculation for straight segments.
+
+------------------------------------------------------------------------
+r3571 | jcbowman | 2008-10-14 15:24:08 -0600 (Tue, 14 Oct 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/three_surface.asy
+
+Fix degenerate perp vectors.
+
+------------------------------------------------------------------------
+r3570 | jcbowman | 2008-10-14 14:21:57 -0600 (Tue, 14 Oct 2008) | 4 lines
+Changed paths:
+ M /trunk/asymptote/base/bezulate.asy
+ M /trunk/asymptote/base/plain_picture.asy
+ M /trunk/asymptote/base/three.asy
+ M /trunk/asymptote/base/three_surface.asy
+ M /trunk/asymptote/path.cc
+
+Fix nullpath and nullpath3 issues.
+
+Use user coordinates in camera diagnostics.
+
+------------------------------------------------------------------------
+r3569 | jcbowman | 2008-10-14 11:01:52 -0600 (Tue, 14 Oct 2008) | 6 lines
+Changed paths:
+ M /trunk/asymptote/base/plain_arrows.asy
+ M /trunk/asymptote/base/solids.asy
+ M /trunk/asymptote/base/three.asy
+ M /trunk/asymptote/base/three_surface.asy
+
+Move surface constructor for surfaces of rotation from solids to three_surfaces.
+
+Add surface constructor planar(path3).
+
+Add path(path3, pair P(triple)=xypart) constructor.
+
+------------------------------------------------------------------------
+r3568 | jcbowman | 2008-10-13 22:40:10 -0600 (Mon, 13 Oct 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/solids.asy
+
+Fix degenerate perp vectors.
+
+------------------------------------------------------------------------
+r3567 | jcbowman | 2008-10-13 21:49:53 -0600 (Mon, 13 Oct 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/plain_picture.asy
+ M /trunk/asymptote/base/three.asy
+
+Improve automatic camera adjustment.
+
+------------------------------------------------------------------------
+r3566 | jcbowman | 2008-10-13 20:36:06 -0600 (Mon, 13 Oct 2008) | 6 lines
+Changed paths:
+ M /trunk/asymptote/base/solids.asy
+ M /trunk/asymptote/base/three_surface.asy
+ M /trunk/asymptote/drawelement.h
+ M /trunk/asymptote/drawsurface.cc
+ M /trunk/asymptote/drawsurface.h
+ M /trunk/asymptote/glrender.cc
+ M /trunk/asymptote/path3.h
+ M /trunk/asymptote/picture.cc
+ M /trunk/asymptote/runtime.in
+
+Fix transition between rendering algorithms.
+
+Fix handling of currentlight=nolight.
+
+Change default light for mesh lines to surface light.
+
+------------------------------------------------------------------------
+r3565 | jcbowman | 2008-10-13 13:28:07 -0600 (Mon, 13 Oct 2008) | 4 lines
+Changed paths:
+ M /trunk/asymptote/drawsurface.cc
+ M /trunk/asymptote/glrender.cc
+
+Fix window sizing problems.
+
+Tweak constant.
+
+------------------------------------------------------------------------
+r3564 | jcbowman | 2008-10-13 10:00:22 -0600 (Mon, 13 Oct 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/Makefile.in
+
+Install externalprc.tex.
+
+------------------------------------------------------------------------
+r3563 | jcbowman | 2008-10-13 01:26:29 -0600 (Mon, 13 Oct 2008) | 4 lines
+Changed paths:
+ M /trunk/asymptote/base/three_arrows.asy
+ M /trunk/asymptote/examples/sphereskeleton.asy
+ M /trunk/asymptote/examples/workcone.asy
+
+Avoid cracks in thick lines.
+
+Add connector sphere for cyclic paths.
+
+------------------------------------------------------------------------
+r3562 | jcbowman | 2008-10-13 00:44:45 -0600 (Mon, 13 Oct 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/three.asy
+
+Enable linetype offset.
+
+------------------------------------------------------------------------
+r3561 | jcbowman | 2008-10-12 23:39:48 -0600 (Sun, 12 Oct 2008) | 4 lines
+Changed paths:
+ M /trunk/asymptote/arrayop.h
+ M /trunk/asymptote/base/three_surface.asy
+ M /trunk/asymptote/drawsurface.cc
+ M /trunk/asymptote/drawsurface.h
+ M /trunk/asymptote/runtime.in
+
+Transform computed surface normals.
+
+Reduce planar normal constant for accurate rendering.
+
+------------------------------------------------------------------------
+r3560 | jcbowman | 2008-10-12 21:13:04 -0600 (Sun, 12 Oct 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/bezulate.asy
+ M /trunk/asymptote/drawsurface.cc
+
+Add Orest's patch to make short connections before longer ones.
+
+------------------------------------------------------------------------
+r3559 | jcbowman | 2008-10-12 13:35:26 -0600 (Sun, 12 Oct 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/bezulate.asy
+ M /trunk/asymptote/base/three_surface.asy
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/drawsurface.cc
+ M /trunk/asymptote/drawsurface.h
+ A /trunk/asymptote/examples/stroke3.asy
+ M /trunk/asymptote/examples/xxsq01x-1.asy
+ M /trunk/asymptote/glrender.cc
+ M /trunk/asymptote/runtime.in
+
+Fix rendering of planar surfaces.
+
+------------------------------------------------------------------------
+r3558 | jcbowman | 2008-10-12 11:33:24 -0600 (Sun, 12 Oct 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/three.asy
+
+Fix settings.render=0.
+
+------------------------------------------------------------------------
+r3557 | jcbowman | 2008-10-12 00:29:13 -0600 (Sun, 12 Oct 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/asymptote.spec
+
+Fix freeglut dependency.
+
+------------------------------------------------------------------------
+r3556 | jcbowman | 2008-10-11 23:59:50 -0600 (Sat, 11 Oct 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/asymptote.spec
+ M /trunk/asymptote/util.h
+
+Remove texhash dependency from RPM spec file.
+
+------------------------------------------------------------------------
+r3555 | jcbowman | 2008-10-11 23:10:17 -0600 (Sat, 11 Oct 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/drawelement.h
+ M /trunk/asymptote/drawpath3.cc
+ M /trunk/asymptote/drawsurface.cc
+ M /trunk/asymptote/drawsurface.h
+ M /trunk/asymptote/glrender.cc
+ A /trunk/asymptote/glrender.h
+ M /trunk/asymptote/picture.cc
+
+Speed up rendering of straight surfaces.
+
+------------------------------------------------------------------------
+r3554 | jcbowman | 2008-10-11 22:02:50 -0600 (Sat, 11 Oct 2008) | 4 lines
+Changed paths:
+ M /trunk/asymptote/base/plain_constants.asy
+ M /trunk/asymptote/base/plain_paths.asy
+ M /trunk/asymptote/base/three.asy
+ M /trunk/asymptote/knot.cc
+ M /trunk/asymptote/path.cc
+
+Treat duplicate nodes as straight segments.
+
+Make write(path) indicate straight segments, consistent with write(path3).
+
+------------------------------------------------------------------------
+r3553 | jcbowman | 2008-10-11 14:48:32 -0600 (Sat, 11 Oct 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/three.asy
+
+Size 2D and 3D objects consistently when render=0.
+
+------------------------------------------------------------------------
+r3552 | jcbowman | 2008-10-11 11:09:55 -0600 (Sat, 11 Oct 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/plain_picture.asy
+ M /trunk/asymptote/base/plain_shipout.asy
+ M /trunk/asymptote/base/three.asy
+
+Respect prefix and format arguments.
+
+------------------------------------------------------------------------
+r3551 | jcbowman | 2008-10-11 00:14:43 -0600 (Sat, 11 Oct 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/three.asy
+
+Fix normal for degenerate paths.
+
+------------------------------------------------------------------------
+r3550 | jcbowman | 2008-10-10 23:38:12 -0600 (Fri, 10 Oct 2008) | 4 lines
+Changed paths:
+ M /trunk/asymptote/base/three.asy
+ M /trunk/asymptote/runtime.in
+
+Resolve ambiguity.
+
+Optimize normal.
+
+------------------------------------------------------------------------
+r3549 | jcbowman | 2008-10-10 23:09:04 -0600 (Fri, 10 Oct 2008) | 5 lines
+Changed paths:
+ M /trunk/asymptote/base/three.asy
+ M /trunk/asymptote/base/three_arrows.asy
+ M /trunk/asymptote/examples/cones.asy
+ M /trunk/asymptote/runtime.in
+
+Fix straightness test.
+
+Draw a sphere if path3 has length 0 with roundcap but not squarecap or
+extendcap, consistent with the behaviour of PostScript in 2D.
+
+------------------------------------------------------------------------
+r3548 | jcbowman | 2008-10-10 21:40:24 -0600 (Fri, 10 Oct 2008) | 4 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/settings.cc
+
+Remove -unsafe option in favour of -nosafe setting.
+
+Remove unused code.
+
+------------------------------------------------------------------------
+r3547 | hammera | 2008-10-10 19:47:52 -0600 (Fri, 10 Oct 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/errors
+ M /trunk/asymptote/errortest.asy
+
+Added testing of permissions.
+
+------------------------------------------------------------------------
+r3546 | hammera | 2008-10-10 18:47:43 -0600 (Fri, 10 Oct 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/errors
+ M /trunk/asymptote/errortest.asy
+ M /trunk/asymptote/record.cc
+ M /trunk/asymptote/record.h
+ M /trunk/asymptote/settings.cc
+
+Added secure options as read-only settings.
+
+------------------------------------------------------------------------
+r3545 | hammera | 2008-10-10 17:42:54 -0600 (Fri, 10 Oct 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/exp.cc
+ M /trunk/asymptote/exp.h
+
+Added optional tests to audit the type and application caching.
+
+------------------------------------------------------------------------
+r3544 | jcbowman | 2008-10-10 17:35:57 -0600 (Fri, 10 Oct 2008) | 4 lines
+Changed paths:
+ M /trunk/asymptote/base/three.asy
+ M /trunk/asymptote/base/three_arrows.asy
+ M /trunk/asymptote/doc/asymptote.texi
+
+Document texpath.
+
+Standardize write(path3) formatting.
+
+------------------------------------------------------------------------
+r3543 | jcbowman | 2008-10-10 09:27:34 -0600 (Fri, 10 Oct 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/examples/equilchord.asy
+
+Fix example.
+
+------------------------------------------------------------------------
+r3542 | jcbowman | 2008-10-10 09:24:00 -0600 (Fri, 10 Oct 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/runtime.in
+
+Fix compilation error.
+
+------------------------------------------------------------------------
+r3541 | jcbowman | 2008-10-10 09:22:09 -0600 (Fri, 10 Oct 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/runtime.in
+
+Add missing return value.
+
+------------------------------------------------------------------------
+r3540 | jcbowman | 2008-10-10 09:10:00 -0600 (Fri, 10 Oct 2008) | 4 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/examples/teapot.asy
+ M /trunk/asymptote/runtime.in
+
+Document convert, animate, and system; add args option to animate.
+
+Fix segmentation fault in system.
+
+------------------------------------------------------------------------
+r3539 | jcbowman | 2008-10-10 08:18:48 -0600 (Fri, 10 Oct 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/three_light.asy
+ M /trunk/asymptote/doc/GaussianSurface.asy
+ M /trunk/asymptote/examples/teapot.asy
+
+Add files missing from last revision.
+
+------------------------------------------------------------------------
+r3538 | jcbowman | 2008-10-10 02:45:32 -0600 (Fri, 10 Oct 2008) | 13 lines
+Changed paths:
+ M /trunk/asymptote/base/graph3.asy
+ M /trunk/asymptote/base/plain_constants.asy
+ M /trunk/asymptote/base/plain_pens.asy
+ M /trunk/asymptote/base/solids.asy
+ M /trunk/asymptote/base/three.asy
+ M /trunk/asymptote/base/three_arrows.asy
+ M /trunk/asymptote/base/three_surface.asy
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/examples/parametricsurface.asy
+
+Make default surface color black now that lighting is on by default
+(otherwise planar surfaces might not be visible).
+
+Add unithemisphere.
+
+Draw hemispheres rather than spheres at joints.
+
+Simplify linecap code.
+
+Use linecap(0) by default for meshlines.
+
+Don't draw thin line if opacity of pen is less than 1.
+
+------------------------------------------------------------------------
+r3537 | jcbowman | 2008-10-10 00:58:16 -0600 (Fri, 10 Oct 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/graph.asy
+ M /trunk/asymptote/base/graph3.asy
+ M /trunk/asymptote/doc/asymptote.texi
+
+Add min and max arguments to axes and axes3.
+
+------------------------------------------------------------------------
+r3536 | jcbowman | 2008-10-10 00:52:48 -0600 (Fri, 10 Oct 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/examples/xxsq01.asy
+ M /trunk/asymptote/examples/xxsq01x-1.asy
+ M /trunk/asymptote/examples/xxsq01y.asy
+
+Simplify paths.
+
+------------------------------------------------------------------------
+r3535 | jcbowman | 2008-10-09 22:12:26 -0600 (Thu, 09 Oct 2008) | 3 lines
+Changed paths:
+ M /trunk/asymptote/base/plain_paths.asy
+ M /trunk/asymptote/base/three.asy
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/runtime.in
+
+Allow the specification of fuzz=0 in intersection routines (the new
+default, fuzz=-1, specifies a fixed multiple of the machine precision).
+
+------------------------------------------------------------------------
+r3534 | jcbowman | 2008-10-09 21:34:15 -0600 (Thu, 09 Oct 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/bezulate.asy
+
+Fix division by zero error.
+
+------------------------------------------------------------------------
+r3533 | oshardt | 2008-10-09 19:23:43 -0600 (Thu, 09 Oct 2008) | 1 line
+Changed paths:
+ M /trunk/asymptote/base/bezulate.asy
+
+Improve splitting of triangular patches.
+------------------------------------------------------------------------
+r3532 | jcbowman | 2008-10-09 01:23:49 -0600 (Thu, 09 Oct 2008) | 19 lines
+Changed paths:
+ M /trunk/asymptote/base/graph3.asy
+ M /trunk/asymptote/base/plain_picture.asy
+ M /trunk/asymptote/base/solids.asy
+ M /trunk/asymptote/base/three.asy
+ M /trunk/asymptote/base/three_light.asy
+ M /trunk/asymptote/base/three_surface.asy
+ M /trunk/asymptote/examples/cylinder.asy
+ M /trunk/asymptote/examples/hyperboloid.asy
+ A /trunk/asymptote/examples/impact.asy
+ A /trunk/asymptote/examples/sphereskeleton.asy
+
+Fix longitudinal lines in solids.asy.
+
+Split longitudinal curves into front and back pieces; add
+longintudinalpen=frontpen and longintudinalbackpen=backpen.
+
+Use longitudinalpen=nullpen instead of longitudinal=false.
+
+Make dash lengths in solids.asy consistent between different rendering modes.
+
+Fix OpenGL opacity calculation (only for settings.render=0).
+
+Set P.ninterpolate to 1 for projections from infinity.
+
+Fix 3D dashed lines for degenerate cyclic paths.
+
+Increase fuzz in 3D arc and Arc routines.
+
+Update cone radix in solids.asy.
+
+------------------------------------------------------------------------
+r3531 | jcbowman | 2008-10-08 21:57:16 -0600 (Wed, 08 Oct 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/path.cc
+ M /trunk/asymptote/path3.cc
+
+Fix arctime for cyclic paths of zero arclength.
+
+------------------------------------------------------------------------
+r3530 | jcbowman | 2008-10-07 15:50:10 -0600 (Tue, 07 Oct 2008) | 8 lines
+Changed paths:
+ M /trunk/asymptote/base/plain_arrows.asy
+ M /trunk/asymptote/base/three_arrows.asy
+ M /trunk/asymptote/base/three_surface.asy
+ M /trunk/asymptote/doc/asymptote.texi
+
+Reduce number of patches in unitcone.
+
+Rename solidcone to unitsolidcone.
+
+Improve appearance of straight arrows.
+
+Increase fuzz in arrow end tests.
+
+------------------------------------------------------------------------
+r3529 | jcbowman | 2008-10-07 14:27:36 -0600 (Tue, 07 Oct 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/graph3.asy
+
+Add arrow to NoTicks.
+
+------------------------------------------------------------------------
+r3528 | jcbowman | 2008-10-07 13:57:30 -0600 (Tue, 07 Oct 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/solids.asy
+
+Fix transverse slices.
+
+------------------------------------------------------------------------
+r3527 | jcbowman | 2008-10-07 12:00:47 -0600 (Tue, 07 Oct 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/solids.asy
+
+Give user control over slice Arc accuracy.
+
+------------------------------------------------------------------------
+r3526 | jcbowman | 2008-10-07 11:32:08 -0600 (Tue, 07 Oct 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/solids.asy
+
+Increase longitudinal epsilon.
+
+------------------------------------------------------------------------
+r3525 | jcbowman | 2008-10-06 16:49:30 -0600 (Mon, 06 Oct 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+
+Document need for version 2008/01/16 or later of the movie15 package.
+
+------------------------------------------------------------------------
+r3524 | jcbowman | 2008-10-06 16:19:50 -0600 (Mon, 06 Oct 2008) | 4 lines
+Changed paths:
+ M /trunk/asymptote/base/plain_paths.asy
+ M /trunk/asymptote/base/three.asy
+ M /trunk/asymptote/base/three_surface.asy
+ M /trunk/asymptote/doc/asymptote.texi
+
+Fix incorrect cast.
+
+Resolve ambiguities.
+
+------------------------------------------------------------------------
+r3523 | jcbowman | 2008-10-06 12:26:16 -0600 (Mon, 06 Oct 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+
+Update documentation.
+
+------------------------------------------------------------------------
+r3522 | jcbowman | 2008-10-06 12:05:43 -0600 (Mon, 06 Oct 2008) | 2 lines
+Changed paths:
+ A /trunk/asymptote/doc/reloadpdf.tex
+
+Add utility for forcing Adobe Reader to update all currently loaded documents.
+
+------------------------------------------------------------------------
+r3521 | jcbowman | 2008-10-06 11:24:49 -0600 (Mon, 06 Oct 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/runtime.in
+
+Use NUL instead of /dev/null under MSWindows.
+
+------------------------------------------------------------------------
+r3520 | jcbowman | 2008-10-06 05:36:07 -0600 (Mon, 06 Oct 2008) | 1 line
+Changed paths:
+ M /trunk/asymptote/configure.ac
+
+Increment version to 1.45svn.
+------------------------------------------------------------------------
+r3519 | jcbowman | 2008-10-06 03:48:54 -0600 (Mon, 06 Oct 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/asymptote.spec
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/doc/errorbars.asy
+ M /trunk/asymptote/doc/externalprc.tex
+ M /trunk/asymptote/doc/graphmarkers.asy
+ M /trunk/asymptote/doc/latexusage.tex
+ M /trunk/asymptote/doc/secondaryaxis.asy
+ M /trunk/asymptote/doc/westnile.asy
+
+Update documentation.
+
+------------------------------------------------------------------------
+r3518 | jcbowman | 2008-10-06 01:09:53 -0600 (Mon, 06 Oct 2008) | 7 lines
+Changed paths:
+ M /trunk/asymptote/base/embed.asy
+ D /trunk/asymptote/base/embedding.asy
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/doc/latexusage.tex
+ M /trunk/asymptote/examples/animations/externalmovie.asy
+
+Remove settings.tex="pdflatex" from embed.asy and move contents of
+embedding.asy into this file.
+
+Generalize movie15 patch to pdflatex; restore @ catcode to its previous value.
+
+Reduce size of manual.
+
+------------------------------------------------------------------------
+r3517 | jcbowman | 2008-10-05 21:20:57 -0600 (Sun, 05 Oct 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/embedding.asy
+
+Fix missing BBox bug in movie15 version 2008/01/16.
+
+------------------------------------------------------------------------
+r3516 | jcbowman | 2008-10-05 03:33:08 -0600 (Sun, 05 Oct 2008) | 6 lines
+Changed paths:
+ M /trunk/asymptote/base/graph.asy
+ M /trunk/asymptote/base/plain_picture.asy
+ M /trunk/asymptote/base/plain_shipout.asy
+ M /trunk/asymptote/base/three.asy
+ M /trunk/asymptote/doc/Makefile.in
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/doc/diatom.asy
+ M /trunk/asymptote/doc/latexusage.tex
+ M /trunk/asymptote/doc/leastsquares.asy
+ M /trunk/asymptote/examples/label3.asy
+ M /trunk/asymptote/examples/lever.asy
+ M /trunk/asymptote/examples/sinc.asy
+ M /trunk/asymptote/examples/yingyang.asy
+
+Handle degenerate scaling.
+
+Fix manual build problems.
+
+Update examples and documentation.
+
+------------------------------------------------------------------------
+r3515 | jcbowman | 2008-10-04 23:13:48 -0600 (Sat, 04 Oct 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/three.asy
+
+Fix absolute viewpoints.
+
+------------------------------------------------------------------------
+r3514 | jcbowman | 2008-10-04 19:18:49 -0600 (Sat, 04 Oct 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/externalprc.tex
+ M /trunk/asymptote/examples/washermethod.asy
+
+Fix example.
+
+------------------------------------------------------------------------
+r3513 | jcbowman | 2008-10-04 18:18:00 -0600 (Sat, 04 Oct 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/examples/cones.asy
+ M /trunk/asymptote/examples/epix.asy
+ M /trunk/asymptote/examples/partialsurface.asy
+ M /trunk/asymptote/examples/sinc.asy
+ M /trunk/asymptote/examples/washermethod.asy
+
+Fix examples.
+
+------------------------------------------------------------------------
+r3512 | jcbowman | 2008-10-04 17:12:05 -0600 (Sat, 04 Oct 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/three.asy
+
+Add file missing from last revision.
+
+------------------------------------------------------------------------
+r3511 | jcbowman | 2008-10-04 17:11:37 -0600 (Sat, 04 Oct 2008) | 4 lines
+Changed paths:
+ M /trunk/asymptote/base/plain_xasy.asy
+ M /trunk/asymptote/base/solids.asy
+ M /trunk/asymptote/base/three_surface.asy
+ M /trunk/asymptote/examples/sphere.asy
+
+Improve definition of unitcone.
+
+Make xasy work again with 3D pictures.
+
+------------------------------------------------------------------------
+r3510 | jcbowman | 2008-10-04 14:53:47 -0600 (Sat, 04 Oct 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/builtin.cc
+
+Remove interp(int,int,real).
+
+------------------------------------------------------------------------
+r3509 | jcbowman | 2008-10-04 11:45:14 -0600 (Sat, 04 Oct 2008) | 4 lines
+Changed paths:
+ M /trunk/asymptote/base/solids.asy
+ M /trunk/asymptote/base/three.asy
+ M /trunk/asymptote/base/three_arrows.asy
+ M /trunk/asymptote/examples/cones.asy
+
+Handle degenerate point in cone.
+
+Tweak parameter in thick lines.
+
+------------------------------------------------------------------------
+r3508 | jcbowman | 2008-10-04 01:15:46 -0600 (Sat, 04 Oct 2008) | 6 lines
+Changed paths:
+ M /trunk/asymptote/base/animation.asy
+ M /trunk/asymptote/base/plain_picture.asy
+ M /trunk/asymptote/base/three.asy
+ M /trunk/asymptote/base/three_arrows.asy
+ M /trunk/asymptote/base/three_surface.asy
+ M /trunk/asymptote/doc/Makefile.in
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/examples/animations/sphere.asy
+ M /trunk/asymptote/examples/epix.asy
+ M /trunk/asymptote/examples/partialsurface.asy
+ M /trunk/asymptote/examples/shellsqrtx01.asy
+ M /trunk/asymptote/examples/sinc.asy
+ M /trunk/asymptote/examples/sqrtx01.asy
+ M /trunk/asymptote/examples/washermethod.asy
+ M /trunk/asymptote/examples/xxsq01.asy
+ M /trunk/asymptote/examples/xxsq01y.asy
+
+Fix cracks in thick lines.
+
+Fix projection and clipping.
+
+Fix 3D animations.
+
+------------------------------------------------------------------------
+r3507 | jcbowman | 2008-10-03 17:21:00 -0600 (Fri, 03 Oct 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/Makefile.in
+
+Force -noprc during documentation builds.
+
+------------------------------------------------------------------------
+r3506 | hammera | 2008-10-03 17:07:00 -0600 (Fri, 03 Oct 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/application.cc
+
+Fixed matching of defaults for functions with rest arguments.
+
+------------------------------------------------------------------------
+r3505 | jcbowman | 2008-10-03 16:32:10 -0600 (Fri, 03 Oct 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/plain_shipout.asy
+ M /trunk/asymptote/doc/latexusage.tex
+ M /trunk/asymptote/examples/shellmethod.asy
+ D /trunk/asymptote/examples/wedge.asy
+
+Make latexusage produce a rendered image by default.
+
+------------------------------------------------------------------------
+r3504 | jcbowman | 2008-10-03 15:49:34 -0600 (Fri, 03 Oct 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/plain_shipout.asy
+ M /trunk/asymptote/doc/latexusage.tex
+
+Respect -noprc.
+
+------------------------------------------------------------------------
+r3503 | jcbowman | 2008-10-03 04:09:58 -0600 (Fri, 03 Oct 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+
+Remove references to obsolete modules.
+
+------------------------------------------------------------------------
+r3502 | jcbowman | 2008-10-03 03:43:53 -0600 (Fri, 03 Oct 2008) | 8 lines
+Changed paths:
+ M /trunk/asymptote/base/plain_shipout.asy
+ M /trunk/asymptote/base/three.asy
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/examples/animations/slidemovies.asy
+ M /trunk/asymptote/examples/sacone3D.asy
+ M /trunk/asymptote/examples/sacylinder3D.asy
+ M /trunk/asymptote/examples/shellsqrtx01.asy
+ M /trunk/asymptote/examples/sphere.asy
+ M /trunk/asymptote/examples/sqrtx01.asy
+ M /trunk/asymptote/examples/sqrtx01y1.asy
+ M /trunk/asymptote/examples/washermethod.asy
+ M /trunk/asymptote/examples/workcone.asy
+ M /trunk/asymptote/examples/xxsq01.asy
+ M /trunk/asymptote/examples/xxsq01y.asy
+
+Restore symmetric clipping planes.
+
+Fix embed ambiguity.
+
+Update examples.
+
+Make preliminary documentation updates.
+
+------------------------------------------------------------------------
+r3501 | jcbowman | 2008-10-03 01:01:09 -0600 (Fri, 03 Oct 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/graph3.asy
+ M /trunk/asymptote/doc/helix.asy
+ M /trunk/asymptote/examples/sinc.asy
+ M /trunk/asymptote/examples/xxsq01.asy
+
+Use a better default for tick and axis label selection.
+
+------------------------------------------------------------------------
+r3500 | jcbowman | 2008-10-03 00:02:26 -0600 (Fri, 03 Oct 2008) | 4 lines
+Changed paths:
+ M /trunk/asymptote/base/graph.asy
+ M /trunk/asymptote/base/graph3.asy
+ M /trunk/asymptote/base/grid3.asy
+ M /trunk/asymptote/base/plain_picture.asy
+ M /trunk/asymptote/base/three.asy
+ M /trunk/asymptote/doc/axis3.asy
+ A /trunk/asymptote/doc/externalprc.tex
+ M /trunk/asymptote/doc/generalaxis.asy
+ M /trunk/asymptote/doc/generalaxis3.asy
+ M /trunk/asymptote/doc/grid3xyz.asy
+ M /trunk/asymptote/doc/helix.asy
+ M /trunk/asymptote/examples/sinc.asy
+ A /trunk/asymptote/examples/strokeshade.asy
+ M /trunk/asymptote/examples/vectorfield3.asy
+
+Return a zero scaling when unbounded (revert r3371); see generalaxis3.
+
+Rename LeftTicks3 to InTicks, RightTicks3 to OutTicks, and Ticks3 to InOutTicks.
+
+------------------------------------------------------------------------
+r3499 | jcbowman | 2008-10-02 16:47:12 -0600 (Thu, 02 Oct 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/plain_shipout.asy
+
+Remove unused code.
+
+------------------------------------------------------------------------
+r3498 | jcbowman | 2008-10-02 16:43:22 -0600 (Thu, 02 Oct 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/plain_shipout.asy
+ M /trunk/asymptote/doc/asymptote.sty
+ M /trunk/asymptote/doc/latexusage.tex
+ M /trunk/asymptote/settings.cc
+
+Support PRC images even when inlinetex=false.
+
+------------------------------------------------------------------------
+r3497 | jcbowman | 2008-10-02 02:40:10 -0600 (Thu, 02 Oct 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/three.asy
+ M /trunk/asymptote/base/three_light.asy
+ M /trunk/asymptote/doc/latexusage.tex
+ M /trunk/asymptote/examples/BezierSurface.asy
+ M /trunk/asymptote/examples/parametricsurface.asy
+ M /trunk/asymptote/examples/xxsq01x-1.asy
+ M /trunk/asymptote/runtime.in
+
+Support PRC, with optional rendered preview, in inlinetex mode.
+
+------------------------------------------------------------------------
+r3496 | jcbowman | 2008-10-01 23:50:15 -0600 (Wed, 01 Oct 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/three.asy
+ M /trunk/asymptote/doc/latexusage.tex
+ M /trunk/asymptote/examples/shellmethod.asy
+
+Work around degenerate up vectors.
+
+------------------------------------------------------------------------
+r3495 | jcbowman | 2008-10-01 22:45:06 -0600 (Wed, 01 Oct 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/three.asy
+
+Fix perspective projections and clipping.
+
+------------------------------------------------------------------------
+r3494 | jcbowman | 2008-10-01 21:34:38 -0600 (Wed, 01 Oct 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/three.asy
+
+Fix reference vector indices.
+
+------------------------------------------------------------------------
+r3493 | jcbowman | 2008-10-01 20:56:14 -0600 (Wed, 01 Oct 2008) | 6 lines
+Changed paths:
+ M /trunk/asymptote/base/plain_paths.asy
+ M /trunk/asymptote/base/plain_shipout.asy
+ M /trunk/asymptote/base/three.asy
+ M /trunk/asymptote/base/three_light.asy
+ M /trunk/asymptote/doc/asymptote.sty
+ M /trunk/asymptote/settings.cc
+
+Support prc with pdflatex.
+
+Fix light transforms.
+
+Use sequence for array loops.
+
+------------------------------------------------------------------------
+r3492 | jcbowman | 2008-10-01 14:07:53 -0600 (Wed, 01 Oct 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/latexusage.tex
+ M /trunk/asymptote/runtime.in
+ M /trunk/asymptote/texfile.cc
+ M /trunk/asymptote/texfile.h
+
+Support texpath in inlinetex mode.
+
+------------------------------------------------------------------------
+r3491 | jcbowman | 2008-10-01 03:45:46 -0600 (Wed, 01 Oct 2008) | 7 lines
+Changed paths:
+ M /trunk/asymptote/base/three.asy
+ M /trunk/asymptote/base/three_surface.asy
+ M /trunk/asymptote/doc/helix.asy
+ M /trunk/asymptote/doc/latexusage.tex
+ M /trunk/asymptote/drawelement.h
+ M /trunk/asymptote/drawpath3.h
+ M /trunk/asymptote/drawsurface.cc
+ M /trunk/asymptote/drawsurface.h
+ M /trunk/asymptote/examples/shellmethod.asy
+ M /trunk/asymptote/examples/xxsq01x-1.asy
+ M /trunk/asymptote/glrender.cc
+ M /trunk/asymptote/path3.cc
+ M /trunk/asymptote/path3.h
+ M /trunk/asymptote/picture.cc
+ M /trunk/asymptote/picture.h
+ M /trunk/asymptote/runtime.in
+
+Fix sizing of perspective projections by usingd an accurate subdivison
+algorithm to calculate the optimal field of view angle.
+
+Use an accurate projected path3 bound for picture sizing.
+
+Optimize projection routines.
+
+------------------------------------------------------------------------
+r3490 | jcbowman | 2008-09-30 11:58:22 -0600 (Tue, 30 Sep 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/three_surface.asy
+
+Don't cache projected bounds.
+
+------------------------------------------------------------------------
+r3489 | jcbowman | 2008-09-30 10:59:03 -0600 (Tue, 30 Sep 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/three.asy
+
+Fix rendering from an absolute viewpoint.
+
+------------------------------------------------------------------------
+r3488 | jcbowman | 2008-09-30 03:53:15 -0600 (Tue, 30 Sep 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/three.asy
+
+Fix picture sizing and clipping plane.
+
+------------------------------------------------------------------------
+r3487 | jcbowman | 2008-09-30 02:14:12 -0600 (Tue, 30 Sep 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/three.asy
+
+Use a separate frame for preview rendering.
+
+------------------------------------------------------------------------
+r3486 | jcbowman | 2008-09-29 19:01:39 -0600 (Mon, 29 Sep 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/three.asy
+
+Minor optimizations.
+
+------------------------------------------------------------------------
+r3485 | jcbowman | 2008-09-29 03:39:09 -0600 (Mon, 29 Sep 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/glrender.cc
+
+Limit window to physical screen size under MSWindows due to OS limitations.
+
+------------------------------------------------------------------------
+r3484 | jcbowman | 2008-09-29 02:08:52 -0600 (Mon, 29 Sep 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/glrender.cc
+
+Fix window size checks.
+
+------------------------------------------------------------------------
+r3483 | jcbowman | 2008-09-29 01:41:25 -0600 (Mon, 29 Sep 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/drawpath3.cc
+
+Use gluEndCurve not gluEndSurface.
+
+------------------------------------------------------------------------
+r3482 | jcbowman | 2008-09-29 01:09:16 -0600 (Mon, 29 Sep 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/glrender.cc
+
+Allocate image rather than putting it on the stack.
+
+------------------------------------------------------------------------
+r3481 | jcbowman | 2008-09-29 00:47:41 -0600 (Mon, 29 Sep 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/solids.asy
+ M /trunk/asymptote/examples/cones.asy
+
+Optimize solids.asy.
+
+------------------------------------------------------------------------
+r3480 | jcbowman | 2008-09-28 23:01:01 -0600 (Sun, 28 Sep 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/glrender.cc
+
+Fix shrink (- or _) and expand (+ or =) keys.
+
+------------------------------------------------------------------------
+r3479 | jcbowman | 2008-09-28 22:25:20 -0600 (Sun, 28 Sep 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/glrender.cc
+
+Remove unneeded bzero.
+
+------------------------------------------------------------------------
+r3478 | jcbowman | 2008-09-28 22:22:19 -0600 (Sun, 28 Sep 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/join3.asy
+ M /trunk/asymptote/glrender.cc
+
+Port to cygwin.
+
+------------------------------------------------------------------------
+r3477 | jcbowman | 2008-09-28 21:46:48 -0600 (Sun, 28 Sep 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/configure.ac
+
+Fix cygwin configuration.
+
+------------------------------------------------------------------------
+r3476 | jcbowman | 2008-09-28 12:58:51 -0600 (Sun, 28 Sep 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/configure.ac
+ M /trunk/asymptote/glrender.cc
+ M /trunk/asymptote/picture.cc
+
+Support CYGWIN freeglut configuration.
+
+------------------------------------------------------------------------
+r3475 | jcbowman | 2008-09-28 11:56:33 -0600 (Sun, 28 Sep 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/three.asy
+
+Avoid redundant transformation for infinite projections.
+
+------------------------------------------------------------------------
+r3474 | jcbowman | 2008-09-28 11:47:50 -0600 (Sun, 28 Sep 2008) | 4 lines
+Changed paths:
+ M /trunk/asymptote/glrender.cc
+ M /trunk/asymptote/settings.cc
+
+Preserve aspect ratio on export.
+
+Work around viewport size driver bugs.
+
+------------------------------------------------------------------------
+r3473 | jcbowman | 2008-09-28 03:27:07 -0600 (Sun, 28 Sep 2008) | 10 lines
+Changed paths:
+ M /trunk/asymptote/configure.ac
+ M /trunk/asymptote/glrender.cc
+ A /trunk/asymptote/patches/cygwin_glu.patch
+ M /trunk/asymptote/picture.cc
+ M /trunk/asymptote/psfile.cc
+
+Port to cygwin.
+
+Wait until menu disappears before exporting.
+
+Right button without motion, in addition to middle button, now brings up menu.
+
+Fix export segmentation fault.
+
+Fix mesh mode.
+
+------------------------------------------------------------------------
+r3472 | jcbowman | 2008-09-27 10:37:38 -0600 (Sat, 27 Sep 2008) | 6 lines
+Changed paths:
+ M /trunk/asymptote/base/graph.asy
+ M /trunk/asymptote/base/graph3.asy
+ M /trunk/asymptote/base/plain_arcs.asy
+ M /trunk/asymptote/base/three.asy
+ M /trunk/asymptote/doc/asymptote.texi
+
+Add missing 2D Arc routiones.
+
+Remove unusual handling of negative radii.
+
+Update arc and Arc documentation.
+
+------------------------------------------------------------------------
+r3471 | jcbowman | 2008-09-27 03:17:06 -0600 (Sat, 27 Sep 2008) | 8 lines
+Changed paths:
+ M /trunk/asymptote/base/graph3.asy
+ M /trunk/asymptote/base/plain_arcs.asy
+ M /trunk/asymptote/base/solids.asy
+ M /trunk/asymptote/base/three.asy
+ M /trunk/asymptote/examples/shellmethod.asy
+ M /trunk/asymptote/glrender.cc
+
+Render at requested size in interactive mode.
+
+Fix transverse slices of solids of revolution.
+
+Simplify arc and Arc routines.
+
+Check for invalid normal vectors in 3D arc and Arc.
+
+------------------------------------------------------------------------
+r3470 | jcbowman | 2008-09-27 00:29:16 -0600 (Sat, 27 Sep 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/drawelement.h
+ M /trunk/asymptote/glrender.cc
+
+Preliminary changes to support CYGWIN.
+
+------------------------------------------------------------------------
+r3469 | jcbowman | 2008-09-27 00:18:48 -0600 (Sat, 27 Sep 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/plain_shipout.asy
+
+Remove psimage code.
+
+------------------------------------------------------------------------
+r3468 | jcbowman | 2008-09-26 23:38:00 -0600 (Fri, 26 Sep 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/Makefile.in
+ D /trunk/asymptote/base/silentPrint.js
+ M /trunk/asymptote/picture.cc
+ M /trunk/asymptote/settings.cc
+
+Remove obsolete psimage feature (use -render=n instead).
+
+------------------------------------------------------------------------
+r3467 | jcbowman | 2008-09-26 23:33:09 -0600 (Fri, 26 Sep 2008) | 17 lines
+Changed paths:
+ M /trunk/asymptote/array.h
+ M /trunk/asymptote/arrayop.h
+ M /trunk/asymptote/base/graph3.asy
+ D /trunk/asymptote/base/lights.js
+ M /trunk/asymptote/base/solids.asy
+ M /trunk/asymptote/base/three.asy
+ M /trunk/asymptote/base/three_light.asy
+ M /trunk/asymptote/base/three_surface.asy
+ M /trunk/asymptote/doc/flowchartdemo.asy
+ M /trunk/asymptote/drawelement.h
+ M /trunk/asymptote/drawpath3.cc
+ M /trunk/asymptote/drawpath3.h
+ M /trunk/asymptote/drawsurface.cc
+ M /trunk/asymptote/drawsurface.h
+ A /trunk/asymptote/examples/controlsystem.asy
+ M /trunk/asymptote/examples/shellmethod.asy
+ M /trunk/asymptote/examples/xxsq01x-1.asy
+ M /trunk/asymptote/glrender.cc
+ M /trunk/asymptote/path3.cc
+ M /trunk/asymptote/path3.h
+ M /trunk/asymptote/picture.cc
+ M /trunk/asymptote/picture.h
+ M /trunk/asymptote/runtime.in
+ M /trunk/asymptote/triple.h
+
+Fix path3 rendering.
+
+Add meshlight option to surface routines.
+
+Improve glrender mesh mode.
+
+Simplify light constructors.
+
+Clean up code.
+
+Remove OpenGL license from glrender.cc as the original code has been
+completely replaced by our own code.
+
+Update examples.
+
+Remove unused lights.js file.
+
+------------------------------------------------------------------------
+r3466 | jcbowman | 2008-09-26 12:53:55 -0600 (Fri, 26 Sep 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/flowchart.asy
+
+Make object argument optional in flowchart routines.
+
+------------------------------------------------------------------------
+r3465 | jcbowman | 2008-09-25 00:31:50 -0600 (Thu, 25 Sep 2008) | 8 lines
+Changed paths:
+ M /trunk/asymptote/Makefile.in
+ M /trunk/asymptote/array.h
+ M /trunk/asymptote/base/three.asy
+ M /trunk/asymptote/base/three_light.asy
+ M /trunk/asymptote/base/three_surface.asy
+ M /trunk/asymptote/builtin.cc
+ M /trunk/asymptote/builtin.h
+ M /trunk/asymptote/examples/hyperboloid.asy
+ M /trunk/asymptote/glrender.cc
+ M /trunk/asymptote/picture.cc
+ M /trunk/asymptote/picture.h
+ M /trunk/asymptote/runtime.in
+
+Standardize lightmodel with openGL; support multiple lights.
+
+Add viewport option to light to force lights to be fixed in the viewport frame.
+
+Communicate non-viewport lights to embedded PRC files.
+
+Add +/- expand/shrink keyboard shortcuts.
+
+------------------------------------------------------------------------
+r3464 | jcbowman | 2008-09-24 03:34:35 -0600 (Wed, 24 Sep 2008) | 9 lines
+Changed paths:
+ M /trunk/asymptote/Makefile.in
+ A /trunk/asymptote/base/lights.js
+ M /trunk/asymptote/base/plain_pens.asy
+ M /trunk/asymptote/base/plain_picture.asy
+ M /trunk/asymptote/base/plain_shipout.asy
+ M /trunk/asymptote/base/three.asy
+ M /trunk/asymptote/base/three_arrows.asy
+ M /trunk/asymptote/base/three_light.asy
+ M /trunk/asymptote/base/three_surface.asy
+ M /trunk/asymptote/drawsurface.cc
+ M /trunk/asymptote/glrender.cc
+ M /trunk/asymptote/settings.cc
+
+Replace the light model with the one used by openGL.
+
+Use nurb routine whenever the surface is not straight and the light is on.
+
+Add -nothin option to force pen thin to be set to the initial defaultpen.
+
+Support custom embedded javascript files via a script option to shipout;
+add lights.js example.
+
+------------------------------------------------------------------------
+r3463 | jcbowman | 2008-09-24 03:25:34 -0600 (Wed, 24 Sep 2008) | 3 lines
+Changed paths:
+ M /trunk/asymptote/pen.h
+
+Set the opacity of the sum of two pens to be the larger of the two
+opacities, adopting the blending mode of the second pen.
+
+------------------------------------------------------------------------
+r3462 | jcbowman | 2008-09-23 02:18:57 -0600 (Tue, 23 Sep 2008) | 4 lines
+Changed paths:
+ M /trunk/asymptote/base/three.asy
+ M /trunk/asymptote/base/three_light.asy
+ M /trunk/asymptote/base/three_surface.asy
+ M /trunk/asymptote/pen.h
+ M /trunk/asymptote/runtime.in
+
+Fix more material vs. pen problems.
+
+Improve degenerate normal test.
+
+------------------------------------------------------------------------
+r3461 | jcbowman | 2008-09-22 23:16:10 -0600 (Mon, 22 Sep 2008) | 11 lines
+Changed paths:
+ M /trunk/asymptote/base/contour3.asy
+ M /trunk/asymptote/base/graph3.asy
+ M /trunk/asymptote/base/plain_picture.asy
+ M /trunk/asymptote/base/three.asy
+ M /trunk/asymptote/base/three_light.asy
+ M /trunk/asymptote/base/three_surface.asy
+ M /trunk/asymptote/examples/cones.asy
+ M /trunk/asymptote/glrender.cc
+
+If the render value is negative, use 4 times its absolute value for rendering
+eps and pdf formats and 2 times its absolute value for rendering other formats.
+
+Turn light off for drawing meshes.
+
+Specify light coordinates in viewport frame.
+
+Fix line colors.
+
+Provide an optimized patch constructor for quadrilaterals.
+
+------------------------------------------------------------------------
+r3460 | jcbowman | 2008-09-22 17:24:11 -0600 (Mon, 22 Sep 2008) | 9 lines
+Changed paths:
+ M /trunk/asymptote/base/plain_Label.asy
+ M /trunk/asymptote/base/plain_shipout.asy
+ M /trunk/asymptote/base/three.asy
+ M /trunk/asymptote/base/three_light.asy
+ M /trunk/asymptote/glrender.cc
+ M /trunk/asymptote/settings.cc
+
+Remove preview option in favour of render=n > 0.
+
+Fix line material defaults.
+
+Viewer is no longer updated by erase() since we don't know whether the
+original picture was 2D or 3D and reloading acroread is slow.
+
+Spurious shipouts arising from cameralink are now suppressed.
+
+------------------------------------------------------------------------
+r3459 | jcbowman | 2008-09-22 14:51:56 -0600 (Mon, 22 Sep 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/three.asy
+ M /trunk/asymptote/examples/BezierSurface.asy
+ M /trunk/asymptote/glrender.cc
+ M /trunk/asymptote/settings.cc
+
+Add option -preview to render 3D preview image.
+
+------------------------------------------------------------------------
+r3458 | jcbowman | 2008-09-22 11:52:56 -0600 (Mon, 22 Sep 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/three_surface.asy
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/examples/parametricsurface.asy
+
+Remove obsolete outward flag.
+
+------------------------------------------------------------------------
+r3457 | jcbowman | 2008-09-22 09:05:17 -0600 (Mon, 22 Sep 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/three.asy
+
+Revert last change.
+
+------------------------------------------------------------------------
+r3456 | jcbowman | 2008-09-22 09:03:50 -0600 (Mon, 22 Sep 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/three.asy
+
+Suppress another unnecessary warning.
+
+------------------------------------------------------------------------
+r3455 | jcbowman | 2008-09-22 08:45:44 -0600 (Mon, 22 Sep 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/three.asy
+
+Suppress unnecessary warnings from automatic picture sizing.
+
+------------------------------------------------------------------------
+r3454 | jcbowman | 2008-09-22 03:05:03 -0600 (Mon, 22 Sep 2008) | 6 lines
+Changed paths:
+ M /trunk/asymptote/base/animation.asy
+ M /trunk/asymptote/base/three.asy
+ M /trunk/asymptote/base/three_light.asy
+ M /trunk/asymptote/glrender.cc
+ M /trunk/asymptote/runtime.in
+
+Support orthographic projections in PRC.
+
+Fix definition of emissive.
+
+Transform currentlight correctly in shipout3.
+
+------------------------------------------------------------------------
+r3453 | jcbowman | 2008-09-21 14:43:48 -0600 (Sun, 21 Sep 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/three.asy
+
+Fix orthographic and oblique clipping.
+
+------------------------------------------------------------------------
+r3452 | oshardt | 2008-09-21 14:10:34 -0600 (Sun, 21 Sep 2008) | 1 line
+Changed paths:
+ M /trunk/asymptote/glrender.cc
+
+Fix z rotation.
+------------------------------------------------------------------------
+r3451 | jcbowman | 2008-09-21 13:34:37 -0600 (Sun, 21 Sep 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/drawsurface.cc
+ M /trunk/asymptote/picture.h
+ M /trunk/asymptote/runtime.in
+
+Support compilation without freeglut.
+
+------------------------------------------------------------------------
+r3450 | jcbowman | 2008-09-21 11:33:45 -0600 (Sun, 21 Sep 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/three_surface.asy
+
+Fix normal0.
+
+------------------------------------------------------------------------
+r3449 | jcbowman | 2008-09-21 11:32:55 -0600 (Sun, 21 Sep 2008) | 4 lines
+Changed paths:
+ M /trunk/asymptote/base/plain_arrows.asy
+ M /trunk/asymptote/base/three_arrows.asy
+ M /trunk/asymptote/base/three_surface.asy
+
+Add optimized vertex normal routines.
+
+Add fuzz to arrow position test.
+
+------------------------------------------------------------------------
+r3448 | jcbowman | 2008-09-21 00:57:00 -0600 (Sun, 21 Sep 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/drawpath3.cc
+ M /trunk/asymptote/glrender.cc
+
+Fix includes.
+
+------------------------------------------------------------------------
+r3447 | jcbowman | 2008-09-21 00:52:01 -0600 (Sun, 21 Sep 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/three.asy
+ M /trunk/asymptote/examples/parametricsurface.asy
+ M /trunk/asymptote/glrender.cc
+
+Fix glOrtho parameters.
+
+------------------------------------------------------------------------
+r3446 | jcbowman | 2008-09-20 23:59:37 -0600 (Sat, 20 Sep 2008) | 4 lines
+Changed paths:
+ M /trunk/asymptote/base/three_surface.asy
+ M /trunk/asymptote/bbox.h
+ M /trunk/asymptote/bbox3.h
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/drawelement.h
+ M /trunk/asymptote/drawpath3.cc
+ M /trunk/asymptote/drawpath3.h
+ M /trunk/asymptote/drawsurface.cc
+ M /trunk/asymptote/drawsurface.h
+ M /trunk/asymptote/examples/parametricsurface.asy
+ M /trunk/asymptote/glrender.cc
+ M /trunk/asymptote/picture.cc
+ M /trunk/asymptote/picture.h
+ M /trunk/asymptote/runtime.in
+
+Improve surface culling.
+
+Use GLUnurb for rendering a path3 (unless it is piecewise straight).
+
+------------------------------------------------------------------------
+r3445 | oshardt | 2008-09-20 14:20:06 -0600 (Sat, 20 Sep 2008) | 1 line
+Changed paths:
+ D /trunk/asymptote/examples/animatations
+ A /trunk/asymptote/examples/slidemovies.asy (from /trunk/asymptote/examples/animatations:3444)
+
+Undo renaming of slidemovies.asy.
+------------------------------------------------------------------------
+r3444 | jcbowman | 2008-09-19 22:55:58 -0600 (Fri, 19 Sep 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/three.asy
+ M /trunk/asymptote/picture.cc
+
+Adjust rendering constants.
+
+------------------------------------------------------------------------
+r3443 | jcbowman | 2008-09-19 22:36:16 -0600 (Fri, 19 Sep 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/animation.asy
+ M /trunk/asymptote/doc/FAQ/asy-faq.bfnn
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/picture.cc
+ M /trunk/asymptote/settings.cc
+
+Update convert options; add convertOptions setting.
+
+------------------------------------------------------------------------
+r3442 | jcbowman | 2008-09-19 14:58:20 -0600 (Fri, 19 Sep 2008) | 4 lines
+Changed paths:
+ M /trunk/asymptote/base/three.asy
+ M /trunk/asymptote/drawelement.h
+ M /trunk/asymptote/drawpath3.cc
+ M /trunk/asymptote/drawsurface.cc
+ M /trunk/asymptote/drawsurface.h
+ M /trunk/asymptote/glrender.cc
+ M /trunk/asymptote/picture.cc
+ M /trunk/asymptote/picture.h
+ M /trunk/asymptote/runtime.in
+
+Allow compilation without freeglut library.
+
+Fix width and height sizing.
+
+------------------------------------------------------------------------
+r3441 | jcbowman | 2008-09-19 13:36:35 -0600 (Fri, 19 Sep 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/glrender.cc
+ M /trunk/asymptote/picture.cc
+ M /trunk/asymptote/settings.cc
+
+Use render setting for convert.
+
+------------------------------------------------------------------------
+r3440 | jcbowman | 2008-09-19 13:08:14 -0600 (Fri, 19 Sep 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/palette.asy
+
+Add antialias=false option to image routines.
+
+------------------------------------------------------------------------
+r3439 | jcbowman | 2008-09-19 12:44:53 -0600 (Fri, 19 Sep 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/main.cc
+ M /trunk/asymptote/settings.cc
+
+Improve configuration diagnostics.
+
+------------------------------------------------------------------------
+r3438 | jcbowman | 2008-09-19 01:59:23 -0600 (Fri, 19 Sep 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/psfile.cc
+
+Don't dealias last column of pixels.
+
+------------------------------------------------------------------------
+r3437 | jcbowman | 2008-09-19 01:55:18 -0600 (Fri, 19 Sep 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/psfile.cc
+
+Fix segmentation fault: don't dealias the top row of pixels.
+
+------------------------------------------------------------------------
+r3436 | jcbowman | 2008-09-19 01:20:05 -0600 (Fri, 19 Sep 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/drawimage.h
+ M /trunk/asymptote/glrender.cc
+ M /trunk/asymptote/runtime.in
+
+Support antialiasing of all images.
+
+------------------------------------------------------------------------
+r3435 | jcbowman | 2008-09-19 01:10:51 -0600 (Fri, 19 Sep 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/drawimage.h
+ M /trunk/asymptote/psfile.cc
+ M /trunk/asymptote/psfile.h
+
+Support inline antialiasing.
+
+------------------------------------------------------------------------
+r3434 | jcbowman | 2008-09-18 23:18:41 -0600 (Thu, 18 Sep 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/plain_shipout.asy
+ M /trunk/asymptote/base/three.asy
+ M /trunk/asymptote/glrender.cc
+ M /trunk/asymptote/settings.cc
+
+Improve rendering options.
+
+------------------------------------------------------------------------
+r3433 | jcbowman | 2008-09-18 12:25:57 -0600 (Thu, 18 Sep 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/psfile.cc
+
+Antialias export images.
+
+------------------------------------------------------------------------
+r3432 | jcbowman | 2008-09-18 12:11:57 -0600 (Thu, 18 Sep 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/three.asy
+ M /trunk/asymptote/glrender.cc
+
+Fix export.
+
+------------------------------------------------------------------------
+r3431 | jcbowman | 2008-09-18 03:47:05 -0600 (Thu, 18 Sep 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/drawelement.h
+ M /trunk/asymptote/drawpath3.cc
+ M /trunk/asymptote/drawpath3.h
+ M /trunk/asymptote/drawsurface.cc
+ M /trunk/asymptote/drawsurface.h
+ M /trunk/asymptote/glrender.cc
+ M /trunk/asymptote/picture.cc
+ M /trunk/asymptote/picture.h
+
+Simplify and optimize surface rendering.
+
+------------------------------------------------------------------------
+r3430 | jcbowman | 2008-09-18 02:23:07 -0600 (Thu, 18 Sep 2008) | 3 lines
+Changed paths:
+ M /trunk/asymptote/base/contour3.asy
+ M /trunk/asymptote/base/three_surface.asy
+ M /trunk/asymptote/drawsurface.cc
+ M /trunk/asymptote/drawsurface.h
+ M /trunk/asymptote/runtime.in
+
+Always use nurb rendering algorithm (with callback) for degenerate patches
+when the light is on.
+
+------------------------------------------------------------------------
+r3429 | jcbowman | 2008-09-18 00:17:53 -0600 (Thu, 18 Sep 2008) | 4 lines
+Changed paths:
+ M /trunk/asymptote/base/three.asy
+ M /trunk/asymptote/base/three_surface.asy
+ M /trunk/asymptote/drawelement.h
+ M /trunk/asymptote/drawpath3.cc
+ M /trunk/asymptote/drawpath3.h
+ M /trunk/asymptote/drawsurface.cc
+ M /trunk/asymptote/drawsurface.h
+ M /trunk/asymptote/glrender.cc
+ M /trunk/asymptote/picture.cc
+ M /trunk/asymptote/picture.h
+ M /trunk/asymptote/settings.cc
+
+Fix rendering artifacts at degenerate control points.
+
+Improve unitcone.
+
+------------------------------------------------------------------------
+r3428 | jcbowman | 2008-09-17 08:55:44 -0600 (Wed, 17 Sep 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/glrender.cc
+ M /trunk/asymptote/settings.cc
+
+Add a maxviewport setting for working around direct rendering driver bugs.
+
+------------------------------------------------------------------------
+r3427 | jcbowman | 2008-09-16 23:47:20 -0600 (Tue, 16 Sep 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/drawpath3.cc
+ M /trunk/asymptote/drawsurface.cc
+ M /trunk/asymptote/drawsurface.h
+ M /trunk/asymptote/examples/parametricsurface.asy
+ M /trunk/asymptote/glrender.cc
+ M /trunk/asymptote/picture.cc
+ M /trunk/asymptote/settings.cc
+
+Retune rendering parameters.
+
+------------------------------------------------------------------------
+r3426 | jcbowman | 2008-09-16 22:28:11 -0600 (Tue, 16 Sep 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/three.asy
+ M /trunk/asymptote/drawelement.h
+ M /trunk/asymptote/drawpath3.cc
+ M /trunk/asymptote/drawpath3.h
+ M /trunk/asymptote/drawsurface.cc
+ M /trunk/asymptote/drawsurface.h
+ M /trunk/asymptote/examples/parametricsurface.asy
+ M /trunk/asymptote/glrender.cc
+ M /trunk/asymptote/picture.cc
+ M /trunk/asymptote/picture.h
+ M /trunk/asymptote/runtime.in
+
+Add mesh mode menu.
+
+------------------------------------------------------------------------
+r3425 | jcbowman | 2008-09-16 19:34:29 -0600 (Tue, 16 Sep 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/three.asy
+ M /trunk/asymptote/glrender.cc
+
+Force a minimum rendering window size.
+
+------------------------------------------------------------------------
+r3424 | jcbowman | 2008-09-16 19:06:42 -0600 (Tue, 16 Sep 2008) | 3 lines
+Changed paths:
+ M /trunk/asymptote/base/contour3.asy
+ M /trunk/asymptote/base/three.asy
+ M /trunk/asymptote/base/three_surface.asy
+ M /trunk/asymptote/examples/label3.asy
+ M /trunk/asymptote/examples/label3ribbon.asy
+ M /trunk/asymptote/examples/magnetic.asy
+ M /trunk/asymptote/picture.cc
+
+Allow explicit surface normals to be specified (currently only respected
+when render=0).
+
+------------------------------------------------------------------------
+r3423 | jcbowman | 2008-09-16 17:42:33 -0600 (Tue, 16 Sep 2008) | 4 lines
+Changed paths:
+ M /trunk/asymptote/glrender.cc
+ M /trunk/asymptote/settings.cc
+
+Work around direct rendering segmentation faults.
+
+Improve full screen mode.
+
+------------------------------------------------------------------------
+r3422 | jcbowman | 2008-09-16 13:29:55 -0600 (Tue, 16 Sep 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/glrender.cc
+ M /trunk/asymptote/settings.cc
+
+Use fullscreen rendering by default.
+
+------------------------------------------------------------------------
+r3421 | jcbowman | 2008-09-16 09:21:24 -0600 (Tue, 16 Sep 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/drawpath3.cc
+ M /trunk/asymptote/drawpath3.h
+ M /trunk/asymptote/drawsurface.cc
+ M /trunk/asymptote/drawsurface.h
+ M /trunk/asymptote/glrender.cc
+
+Remove broken bounding box test optimization.
+
+------------------------------------------------------------------------
+r3420 | jcbowman | 2008-09-16 02:08:38 -0600 (Tue, 16 Sep 2008) | 7 lines
+Changed paths:
+ M /trunk/asymptote/base/three.asy
+ M /trunk/asymptote/base/three_surface.asy
+ M /trunk/asymptote/drawpath3.cc
+ M /trunk/asymptote/drawpath3.h
+ M /trunk/asymptote/drawsurface.cc
+ M /trunk/asymptote/drawsurface.h
+ M /trunk/asymptote/examples/parametricsurface.asy
+ M /trunk/asymptote/glrender.cc
+ M /trunk/asymptote/picture.cc
+ M /trunk/asymptote/picture.h
+ M /trunk/asymptote/runtime.in
+ M /trunk/asymptote/settings.cc
+
+Use hybrid EvalMesh2/NurbSurface rendering algorithm for better speed &
+accuracy.
+
+Remove localsub option.
+
+Rename int path3quality back to bool thick.
+
+------------------------------------------------------------------------
+r3419 | jcbowman | 2008-09-15 23:13:09 -0600 (Mon, 15 Sep 2008) | 4 lines
+Changed paths:
+ M /trunk/asymptote/glrender.cc
+
+Add toggle fullscreen menu option.
+
+Add further keycodes.
+
+------------------------------------------------------------------------
+r3418 | jcbowman | 2008-09-15 17:31:58 -0600 (Mon, 15 Sep 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/glrender.cc
+
+Initialize timer before spinning.
+
+------------------------------------------------------------------------
+r3417 | jcbowman | 2008-09-15 17:21:28 -0600 (Mon, 15 Sep 2008) | 4 lines
+Changed paths:
+ M /trunk/asymptote/glrender.cc
+
+Improve spin/arcball interaction.
+
+Make the Home menu item reset the zoom.
+
+------------------------------------------------------------------------
+r3416 | jcbowman | 2008-09-15 08:49:52 -0600 (Mon, 15 Sep 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/Makefile.in
+ M /trunk/asymptote/doc/Makefile.in
+
+Use -render=0 instead of -norender.
+
+------------------------------------------------------------------------
+r3415 | jcbowman | 2008-09-14 22:03:32 -0600 (Sun, 14 Sep 2008) | 4 lines
+Changed paths:
+ M /trunk/asymptote/glrender.cc
+ M /trunk/asymptote/path.h
+ M /trunk/asymptote/path3.h
+
+Use a better reference value in path and path3 dir functions.
+
+Fix zoom/rotate synchronization.
+
+------------------------------------------------------------------------
+r3414 | jcbowman | 2008-09-14 20:53:45 -0600 (Sun, 14 Sep 2008) | 4 lines
+Changed paths:
+ M /trunk/asymptote/path.h
+ M /trunk/asymptote/path3.h
+
+Simplify dir(path, real) and dir(path3, real) computations.
+
+Fix accel(path3, real).
+
+------------------------------------------------------------------------
+r3413 | jcbowman | 2008-09-14 09:56:50 -0600 (Sun, 14 Sep 2008) | 3 lines
+Changed paths:
+ M /trunk/asymptote/glrender.cc
+ M /trunk/asymptote/settings.cc
+
+Add position parameter to specify initial rendering screen position
+(negative components indicate relative to screen width or height).
+
+------------------------------------------------------------------------
+r3412 | jcbowman | 2008-09-14 09:23:08 -0600 (Sun, 14 Sep 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/three.asy
+ M /trunk/asymptote/examples/parametricsurface.asy
+ M /trunk/asymptote/glrender.cc
+ M /trunk/asymptote/picture.cc
+
+Add Export and Quit menu items.
+
+------------------------------------------------------------------------
+r3411 | jcbowman | 2008-09-14 03:05:29 -0600 (Sun, 14 Sep 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/picture.cc
+
+Remove remaining scale3D factor; retune adaptive constants.
+
+------------------------------------------------------------------------
+r3410 | jcbowman | 2008-09-14 02:44:01 -0600 (Sun, 14 Sep 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/plain_pens.asy
+ M /trunk/asymptote/base/three.asy
+ M /trunk/asymptote/drawelement.h
+ M /trunk/asymptote/drawpath3.cc
+ M /trunk/asymptote/drawsurface.cc
+ M /trunk/asymptote/drawsurface.h
+ M /trunk/asymptote/examples/parametricsurface.asy
+ M /trunk/asymptote/glrender.cc
+ M /trunk/asymptote/picture.cc
+ M /trunk/asymptote/prc/oPRCFile.cc
+ M /trunk/asymptote/prc/oPRCFile.h
+ M /trunk/asymptote/prcfile.h
+
+Move PRC cm scaling to a more sensible place.
+
+------------------------------------------------------------------------
+r3409 | jcbowman | 2008-09-14 01:10:13 -0600 (Sun, 14 Sep 2008) | 4 lines
+Changed paths:
+ M /trunk/asymptote/arcball.h
+ M /trunk/asymptote/base/plain_picture.asy
+ M /trunk/asymptote/base/plain_shipout.asy
+ M /trunk/asymptote/base/three.asy
+ M /trunk/asymptote/drawsurface.cc
+ M /trunk/asymptote/glrender.cc
+ M /trunk/asymptote/picture.cc
+ M /trunk/asymptote/picture.h
+ M /trunk/asymptote/runtime.in
+ M /trunk/asymptote/settings.cc
+
+Fix oblique transformations.
+
+Rename linequality to path3quality.
+
+------------------------------------------------------------------------
+r3408 | jcbowman | 2008-09-13 22:18:15 -0600 (Sat, 13 Sep 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/glrender.cc
+
+Add menu (middle mouse button) with Home and Spin options.
+
+------------------------------------------------------------------------
+r3407 | jcbowman | 2008-09-13 17:57:35 -0600 (Sat, 13 Sep 2008) | 4 lines
+Changed paths:
+ M /trunk/asymptote/base/plain_picture.asy
+ M /trunk/asymptote/base/plain_shipout.asy
+ M /trunk/asymptote/base/three.asy
+ M /trunk/asymptote/builtin.cc
+ M /trunk/asymptote/builtin.h
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/glrender.cc
+ M /trunk/asymptote/picture.cc
+ M /trunk/asymptote/picture.h
+ M /trunk/asymptote/pipestream.h
+ M /trunk/asymptote/runtime.in
+
+Support interactive rendering.
+
+Remove obsolete Wait and NoWait keywords.
+
+------------------------------------------------------------------------
+r3406 | jcbowman | 2008-09-13 13:14:55 -0600 (Sat, 13 Sep 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/three.asy
+ M /trunk/asymptote/glrender.cc
+ M /trunk/asymptote/picture.cc
+ M /trunk/asymptote/settings.cc
+
+Add linequality and twosided settings.
+
+------------------------------------------------------------------------
+r3405 | jcbowman | 2008-09-13 09:43:03 -0600 (Sat, 13 Sep 2008) | 5 lines
+Changed paths:
+ M /trunk/asymptote/base/three_surface.asy
+ M /trunk/asymptote/bbox3.h
+ M /trunk/asymptote/drawelement.h
+ M /trunk/asymptote/drawpath3.cc
+ M /trunk/asymptote/drawpath3.h
+ M /trunk/asymptote/drawsurface.cc
+ M /trunk/asymptote/drawsurface.h
+ M /trunk/asymptote/examples/BezierSurface.asy
+ M /trunk/asymptote/glrender.cc
+ M /trunk/asymptote/picture.cc
+ M /trunk/asymptote/picture.h
+ M /trunk/asymptote/runtime.in
+
+Compute surface bounds for transformed frames correctly.
+
+Speed up rendering by drawing only the surfaces and paths within the field
+of view.
+
+------------------------------------------------------------------------
+r3404 | jcbowman | 2008-09-12 21:48:33 -0600 (Fri, 12 Sep 2008) | 4 lines
+Changed paths:
+ M /trunk/asymptote/glrender.cc
+
+Fix mouse button zoom.
+
+Improve mouse bindings.
+
+------------------------------------------------------------------------
+r3403 | jcbowman | 2008-09-12 17:04:16 -0600 (Fri, 12 Sep 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/glrender.cc
+
+More zoom improvements.
+
+------------------------------------------------------------------------
+r3402 | jcbowman | 2008-09-12 16:23:47 -0600 (Fri, 12 Sep 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/glrender.cc
+
+Zoom on center of window; improve resizing.
+
+------------------------------------------------------------------------
+r3401 | jcbowman | 2008-09-12 00:42:43 -0600 (Fri, 12 Sep 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/three.asy
+
+Account for field of view factor of 0.6 (from javascript).
+
+------------------------------------------------------------------------
+r3400 | jcbowman | 2008-09-10 01:45:00 -0600 (Wed, 10 Sep 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/three.asy
+ M /trunk/asymptote/drawimage.h
+ M /trunk/asymptote/glrender.cc
+ M /trunk/asymptote/pen.h
+ M /trunk/asymptote/picture.cc
+ M /trunk/asymptote/psfile.cc
+ M /trunk/asymptote/psfile.h
+ M /trunk/asymptote/runtime.in
+
+Compress all images and encode them with ASCII85.
+
+------------------------------------------------------------------------
+r3399 | jcbowman | 2008-09-09 10:56:31 -0600 (Tue, 09 Sep 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/asy-mode.el
+
+Force use of new c-lang-defconst for proper indentation after struct.
+
+------------------------------------------------------------------------
+r3398 | jcbowman | 2008-09-09 02:57:38 -0600 (Tue, 09 Sep 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/plain_shipout.asy
+ M /trunk/asymptote/base/three.asy
+
+Fix add.
+
+------------------------------------------------------------------------
+r3397 | jcbowman | 2008-09-09 02:38:47 -0600 (Tue, 09 Sep 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/psfile.cc
+ M /trunk/asymptote/psfile.h
+
+Compress rendered images with zlib.
+
+------------------------------------------------------------------------
+r3396 | jcbowman | 2008-09-09 00:42:32 -0600 (Tue, 09 Sep 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/drawimage.h
+ M /trunk/asymptote/picture.cc
+ M /trunk/asymptote/psfile.cc
+ M /trunk/asymptote/psfile.h
+
+Support rendering into other colorspaces.
+
+------------------------------------------------------------------------
+r3395 | jcbowman | 2008-09-08 23:51:16 -0600 (Mon, 08 Sep 2008) | 4 lines
+Changed paths:
+ M /trunk/asymptote/base/plain_shipout.asy
+ M /trunk/asymptote/base/three.asy
+ M /trunk/asymptote/glrender.cc
+
+Fix zoom-dependence of arcball radius.
+
+Fix rendering problems with mixed 2D+3D drawings (ignore 2D drawing).
+
+------------------------------------------------------------------------
+r3394 | jcbowman | 2008-09-08 23:19:00 -0600 (Mon, 08 Sep 2008) | 10 lines
+Changed paths:
+ M /trunk/asymptote/base/three.asy
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/drawelement.h
+ M /trunk/asymptote/drawpath3.cc
+ M /trunk/asymptote/drawpath3.h
+ M /trunk/asymptote/drawsurface.cc
+ M /trunk/asymptote/drawsurface.h
+ M /trunk/asymptote/examples/parametricsurface.asy
+ M /trunk/asymptote/glrender.cc
+ M /trunk/asymptote/picture.cc
+ M /trunk/asymptote/picture.h
+
+Fix segmentation fault if renderer ends abnormally.
+
+Use color instead of material for path3 rendering, just as for prc.
+
+Add thicklocalsub parameter.
+
+Use two-sided lighting model.
+
+Fix handling of transparency.
+
+------------------------------------------------------------------------
+r3393 | jcbowman | 2008-09-08 02:54:29 -0600 (Mon, 08 Sep 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/Makefile.in
+ M /trunk/asymptote/doc/GaussianSurface.asy
+ M /trunk/asymptote/doc/Makefile.in
+
+Disable rendering during builds.
+
+------------------------------------------------------------------------
+r3392 | jcbowman | 2008-09-08 02:14:24 -0600 (Mon, 08 Sep 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/Makefile.in
+ A /trunk/asymptote/algebra3.cc
+ A /trunk/asymptote/algebra3.h
+ A /trunk/asymptote/arcball.cc
+ A /trunk/asymptote/arcball.h
+ M /trunk/asymptote/arrayop.h
+ M /trunk/asymptote/base/graph3.asy
+ M /trunk/asymptote/base/plain_picture.asy
+ M /trunk/asymptote/base/plain_shipout.asy
+ M /trunk/asymptote/base/solids.asy
+ M /trunk/asymptote/base/three.asy
+ M /trunk/asymptote/base/three_arrows.asy
+ M /trunk/asymptote/base/three_surface.asy
+ M /trunk/asymptote/builtin.cc
+ M /trunk/asymptote/builtin.h
+ M /trunk/asymptote/configure.ac
+ M /trunk/asymptote/drawelement.h
+ M /trunk/asymptote/drawimage.h
+ M /trunk/asymptote/drawpath3.cc
+ M /trunk/asymptote/drawpath3.h
+ M /trunk/asymptote/drawsurface.cc
+ M /trunk/asymptote/drawsurface.h
+ M /trunk/asymptote/examples/BezierSurface.asy
+ M /trunk/asymptote/examples/sinc.asy
+ M /trunk/asymptote/examples/teapot.asy
+ A /trunk/asymptote/glrender.cc
+ M /trunk/asymptote/mathop.h
+ M /trunk/asymptote/path3.cc
+ M /trunk/asymptote/path3.h
+ M /trunk/asymptote/picture.cc
+ M /trunk/asymptote/picture.h
+ M /trunk/asymptote/pipestream.h
+ M /trunk/asymptote/prcfile.h
+ M /trunk/asymptote/psfile.cc
+ M /trunk/asymptote/psfile.h
+ A /trunk/asymptote/quaternion.cc
+ A /trunk/asymptote/quaternion.h
+ M /trunk/asymptote/runtime.in
+ M /trunk/asymptote/settings.cc
+ M /trunk/asymptote/settings.h
+ M /trunk/asymptote/triple.h
+ M /trunk/asymptote/util.cc
+ M /trunk/asymptote/util.h
+
+Implement openGL-based adaptive-mesh renderer.
+
+------------------------------------------------------------------------
+r3391 | jcbowman | 2008-09-04 22:57:07 -0600 (Thu, 04 Sep 2008) | 4 lines
+Changed paths:
+ M /trunk/asymptote/base/graph3.asy
+
+Fix surface orientations.
+
+Optimizations array references.
+
+------------------------------------------------------------------------
+r3390 | jcbowman | 2008-08-29 21:53:57 -0600 (Fri, 29 Aug 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/plain_shipout.asy
+ M /trunk/asymptote/base/three.asy
+ M /trunk/asymptote/doc/join3.asy
+
+Allow 2D drawings under 3D drawings.
+
+------------------------------------------------------------------------
+r3389 | jcbowman | 2008-08-29 20:17:36 -0600 (Fri, 29 Aug 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/path.cc
+
+Use consistent notation for control points.
+
+------------------------------------------------------------------------
+r3388 | jcbowman | 2008-08-29 20:16:18 -0600 (Fri, 29 Aug 2008) | 4 lines
+Changed paths:
+ M /trunk/asymptote/base/graph.asy
+ M /trunk/asymptote/base/graph3.asy
+ M /trunk/asymptote/base/plain_picture.asy
+
+Turn off default graph autoscaling.
+
+Set extend=false by default for 3D axes.
+
+------------------------------------------------------------------------
+r3387 | jcbowman | 2008-08-29 20:14:29 -0600 (Fri, 29 Aug 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/three_surface.asy
+ M /trunk/asymptote/path3.cc
+ M /trunk/asymptote/runtime.in
+
+Rename Bezier/BezierP to bezier/bezierP.
+
+------------------------------------------------------------------------
+r3386 | jcbowman | 2008-08-29 12:36:21 -0600 (Fri, 29 Aug 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/three_arrows.asy
+
+Don't allow curve to reach surface of tube.
+
+------------------------------------------------------------------------
+r3385 | jcbowman | 2008-08-29 12:35:00 -0600 (Fri, 29 Aug 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/graph.asy
+
+Fix overflow problem.
+
+------------------------------------------------------------------------
+r3384 | jcbowman | 2008-08-29 10:12:37 -0600 (Fri, 29 Aug 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/drawpath.cc
+
+Re-enable adjustdash for paths.
+
+------------------------------------------------------------------------
+r3383 | jcbowman | 2008-08-29 01:50:34 -0600 (Fri, 29 Aug 2008) | 7 lines
+Changed paths:
+ M /trunk/asymptote/base/plain_picture.asy
+ M /trunk/asymptote/base/three.asy
+ M /trunk/asymptote/examples/shellmethod.asy
+
+Implement add(picture,picture,triple) for adding fixed sized 3D pictures
+about a point.
+
+Simplify arrow definition.
+
+Move supplementary 3D routines from plain_picture.asy to three.asy.
+
+------------------------------------------------------------------------
+r3382 | jcbowman | 2008-08-29 01:02:27 -0600 (Fri, 29 Aug 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/three.asy
+
+Add pen bounds to arrow routine.
+
+------------------------------------------------------------------------
+r3381 | jcbowman | 2008-08-29 00:54:30 -0600 (Fri, 29 Aug 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/Makefile.in
+
+Uninstall pixel.pdf.
+
+------------------------------------------------------------------------
+r3380 | jcbowman | 2008-08-28 09:00:49 -0600 (Thu, 28 Aug 2008) | 1 line
+Changed paths:
+ M /trunk/asymptote/Makefile.in
+
+Fix typo
+------------------------------------------------------------------------
+r3379 | jcbowman | 2008-08-28 09:00:30 -0600 (Thu, 28 Aug 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/Makefile.in
+
+Fix file location.
+
+------------------------------------------------------------------------
+r3378 | jcbowman | 2008-08-28 01:13:22 -0600 (Thu, 28 Aug 2008) | 10 lines
+Changed paths:
+ M /trunk/asymptote/Makefile.in
+ M /trunk/asymptote/base/graph3.asy
+ M /trunk/asymptote/base/three.asy
+ M /trunk/asymptote/base/three_surface.asy
+ M /trunk/asymptote/examples/conicurv.asy
+ M /trunk/asymptote/examples/epix.asy
+ M /trunk/asymptote/examples/equilchord.asy
+ M /trunk/asymptote/examples/near_earth.asy
+ M /trunk/asymptote/examples/partialsurface.asy
+ M /trunk/asymptote/examples/shellmethod.asy
+ M /trunk/asymptote/examples/vectorfield3.asy
+ M /trunk/asymptote/examples/xxsq01.asy
+ M /trunk/asymptote/patches/README
+ D /trunk/asymptote/patches/gc-7.1FreeBSD.patch
+
+Add missing 3D arrow and dot functions.
+
+Workaround singular matrices in align routines.
+
+Fix conditional drawing of surfaces.
+
+Update examples.
+
+Delete gc-7.1FreeBSD.patch as it isn't required any more under 7.0-RELEASE-p2.
+
+------------------------------------------------------------------------
+r3377 | jcbowman | 2008-08-27 23:11:31 -0600 (Wed, 27 Aug 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/drawpath.cc
+
+Fix segmentation fault.
+
+------------------------------------------------------------------------
+r3376 | jcbowman | 2008-08-27 21:58:08 -0600 (Wed, 27 Aug 2008) | 8 lines
+Changed paths:
+ M /trunk/asymptote/Makefile.in
+ M /trunk/asymptote/base/graph3.asy
+ A /trunk/asymptote/base/reload.js (from /trunk/asymptote/reload.js:3374)
+ A /trunk/asymptote/base/silentPrint.js (from /trunk/asymptote/silentPrint.js:3374)
+ M /trunk/asymptote/base/three.asy
+ D /trunk/asymptote/reload.js
+ D /trunk/asymptote/silentPrint.js
+
+Rename dir parameter of axes to align.
+
+Check that the sum of all dash lengths is positive.
+
+Install pixel.pdf in examples directory.
+
+Install silentPrint.js and reload.js in base directory.
+
+------------------------------------------------------------------------
+r3375 | jcbowman | 2008-08-27 21:28:11 -0600 (Wed, 27 Aug 2008) | 3 lines
+Changed paths:
+ M /trunk/asymptote/base/graph3.asy
+ M /trunk/asymptote/base/splinetype.asy
+ M /trunk/asymptote/base/three.asy
+ M /trunk/asymptote/base/three_surface.asy
+ M /trunk/asymptote/doc/GaussianSurface.asy
+ M /trunk/asymptote/examples/sinc.asy
+ M /trunk/asymptote/examples/spline.asy
+
+Add surface bicubic spline code (based on code contributed by Oliver Guibe
+and the method use in Scilab).
+
+------------------------------------------------------------------------
+r3374 | jcbowman | 2008-08-27 16:35:04 -0600 (Wed, 27 Aug 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/three_arrows.asy
+
+Improve the appearance of arrows on cyclic paths.
+
+------------------------------------------------------------------------
+r3373 | jcbowman | 2008-08-27 16:28:11 -0600 (Wed, 27 Aug 2008) | 6 lines
+Changed paths:
+ M /trunk/asymptote/base/plain_arrows.asy
+ M /trunk/asymptote/base/three.asy
+ M /trunk/asymptote/base/three_arrows.asy
+ M /trunk/asymptote/path.h
+ M /trunk/asymptote/path3.h
+ M /trunk/asymptote/picture.cc
+ M /trunk/asymptote/runtime.in
+ M /trunk/asymptote/settings.cc
+ M /trunk/asymptote/settings.h
+
+Implement more accurate and efficient version of accel(path3, double).
+
+Add missing begingroup3/endgroup3.
+
+Fix texengine vs. texcommand confusion.
+
+------------------------------------------------------------------------
+r3372 | jcbowman | 2008-08-27 15:39:43 -0600 (Wed, 27 Aug 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/plain_Label.asy
+
+Check for division by 0.
+
+------------------------------------------------------------------------
+r3371 | jcbowman | 2008-08-27 15:11:48 -0600 (Wed, 27 Aug 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/plain_picture.asy
+
+Return a unit scaling again when unbounded.
+
+------------------------------------------------------------------------
+r3370 | oshardt | 2008-08-27 14:38:39 -0600 (Wed, 27 Aug 2008) | 1 line
+Changed paths:
+ M /trunk/asymptote/prc/PRC.h
+
+Add header for uint32_t.
+------------------------------------------------------------------------
+r3369 | jcbowman | 2008-08-27 02:44:35 -0600 (Wed, 27 Aug 2008) | 4 lines
+Changed paths:
+ M /trunk/asymptote/base/plain_picture.asy
+ M /trunk/asymptote/base/three.asy
+ M /trunk/asymptote/base/three_surface.asy
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/examples/animations/cube.asy
+ M /trunk/asymptote/runtime.in
+
+Optimize projection routines.
+
+Update cube animation.
+
+------------------------------------------------------------------------
+r3368 | jcbowman | 2008-08-27 01:43:40 -0600 (Wed, 27 Aug 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/grid3.asy
+
+Rename keyword.
+
+------------------------------------------------------------------------
+r3367 | jcbowman | 2008-08-27 01:32:48 -0600 (Wed, 27 Aug 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/helix.asy
+ M /trunk/asymptote/examples/sinc.asy
+ M /trunk/asymptote/path3.h
+
+Update examples.
+
+------------------------------------------------------------------------
+r3366 | jcbowman | 2008-08-27 00:59:16 -0600 (Wed, 27 Aug 2008) | 6 lines
+Changed paths:
+ M /trunk/asymptote/base/graph.asy
+ M /trunk/asymptote/base/graph3.asy
+
+Try to draw labelled axes on the front boundary.
+
+Fix tick directions.
+
+Set axis types explicitly since axis members are volatile.
+
+------------------------------------------------------------------------
+r3365 | jcbowman | 2008-08-26 19:36:34 -0600 (Tue, 26 Aug 2008) | 4 lines
+Changed paths:
+ M /trunk/asymptote/base/three.asy
+ M /trunk/asymptote/base/three_surface.asy
+
+Fix path labels.
+
+Remove filltype argument from 3D functions.
+
+------------------------------------------------------------------------
+r3364 | jcbowman | 2008-08-26 18:48:43 -0600 (Tue, 26 Aug 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/three.asy
+ M /trunk/asymptote/drawpath.cc
+ M /trunk/asymptote/drawpath.h
+ M /trunk/asymptote/runtime.in
+
+Implement 3D dash length adjustment.
+
+------------------------------------------------------------------------
+r3363 | jcbowman | 2008-08-26 17:20:16 -0600 (Tue, 26 Aug 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/three_arrows.asy
+ M /trunk/asymptote/base/three_light.asy
+ M /trunk/asymptote/base/three_surface.asy
+
+Fix granularity; add arrowheadlight().
+
+------------------------------------------------------------------------
+r3362 | jcbowman | 2008-08-26 17:18:35 -0600 (Tue, 26 Aug 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/three.asy
+
+Make arrowheadlight=nolight by default for non-PRC drawings.
+
+------------------------------------------------------------------------
+r3361 | jcbowman | 2008-08-26 13:41:28 -0600 (Tue, 26 Aug 2008) | 14 lines
+Changed paths:
+ M /trunk/asymptote/base/graph3.asy
+ M /trunk/asymptote/base/plain_arrows.asy
+ M /trunk/asymptote/base/plain_picture.asy
+ M /trunk/asymptote/base/solids.asy
+ M /trunk/asymptote/base/three.asy
+ M /trunk/asymptote/base/three_arrows.asy
+ M /trunk/asymptote/base/three_light.asy
+ M /trunk/asymptote/base/three_surface.asy
+ M /trunk/asymptote/builtin.cc
+ M /trunk/asymptote/doc/unitcircle3.asy
+ M /trunk/asymptote/examples/vectorfield3.asy
+ M /trunk/asymptote/runtime.in
+
+Move operator * (transform3, triple) to C++ code.
+
+Remove align in favour of transpose(transform3); rename transform3 to align.
+
+Make arrowhead pen a material.
+
+Add arrowheadlight.
+
+Add light to PRC draw functions.
+
+Check all array pointers.
+
+Add operators == and != for pen arrays.
+
+------------------------------------------------------------------------
+r3360 | jcbowman | 2008-08-26 09:08:01 -0600 (Tue, 26 Aug 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/Makefile.in
+
+Turn off prc flag for documentation builds.
+
+------------------------------------------------------------------------
+r3359 | jcbowman | 2008-08-26 08:52:08 -0600 (Tue, 26 Aug 2008) | 6 lines
+Changed paths:
+ M /trunk/asymptote/base/graph3.asy
+ M /trunk/asymptote/base/three_arrows.asy
+ M /trunk/asymptote/doc/GaussianSurface.asy
+ M /trunk/asymptote/doc/cylinderskeleton.asy
+ M /trunk/asymptote/examples/vectorfield3.asy
+ M /trunk/asymptote/settings.cc
+
+Set settings.prc=true by default.
+
+Update examples.
+
+Check for nullsurface in three_arrows.
+
+------------------------------------------------------------------------
+r3358 | jcbowman | 2008-08-26 08:15:38 -0600 (Tue, 26 Aug 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/Makefile.in
+ M /trunk/asymptote/doc/GaussianSurface.asy
+ M /trunk/asymptote/doc/Makefile.in
+
+Update example.
+
+------------------------------------------------------------------------
+r3357 | jcbowman | 2008-08-26 08:00:19 -0600 (Tue, 26 Aug 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/helix.asy
+ A /trunk/asymptote/path3.h
+
+Add missing file.
+
+------------------------------------------------------------------------
+r3356 | jcbowman | 2008-08-26 02:07:26 -0600 (Tue, 26 Aug 2008) | 6 lines
+Changed paths:
+ M /trunk/asymptote/base/bsp.asy
+ M /trunk/asymptote/base/graph3.asy
+ M /trunk/asymptote/base/grid3.asy
+ M /trunk/asymptote/base/three.asy
+ M /trunk/asymptote/base/three_arrows.asy
+ M /trunk/asymptote/bbox.h
+ M /trunk/asymptote/bbox3.h
+ M /trunk/asymptote/builtin.cc
+ M /trunk/asymptote/drawpath3.cc
+ M /trunk/asymptote/drawpath3.h
+ M /trunk/asymptote/examples/parametricsurface.asy
+ M /trunk/asymptote/pair.h
+ M /trunk/asymptote/path.cc
+ M /trunk/asymptote/path.h
+ M /trunk/asymptote/path3.cc
+ M /trunk/asymptote/primitives.h
+ M /trunk/asymptote/runtime.in
+ M /trunk/asymptote/triple.h
+
+Speed up 3D graphics by moving path3 to C++ code.
+
+Fix 3D bounding box bugs.
+
+Remove remaining references to obsolete bbox3 structure.
+
+------------------------------------------------------------------------
+r3355 | jcbowman | 2008-08-26 01:38:13 -0600 (Tue, 26 Aug 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/three.asy
+
+Check all three coordinates in path3.bounds().
+
+------------------------------------------------------------------------
+r3354 | oshardt | 2008-08-25 20:45:07 -0600 (Mon, 25 Aug 2008) | 1 line
+Changed paths:
+ A /trunk/asymptote/examples/cyclohexane.asy
+
+Add cyclohexane example.
+------------------------------------------------------------------------
+r3353 | jcbowman | 2008-08-25 13:52:20 -0600 (Mon, 25 Aug 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/array.h
+
+Initialize cycle flag.
+
+------------------------------------------------------------------------
+r3352 | jcbowman | 2008-08-25 10:58:46 -0600 (Mon, 25 Aug 2008) | 2 lines
+Changed paths:
+ D /trunk/asymptote/doc/logo3.asy
+
+Remove duplicate file.
+
+------------------------------------------------------------------------
+r3351 | jcbowman | 2008-08-25 10:04:46 -0600 (Mon, 25 Aug 2008) | 6 lines
+Changed paths:
+ M /trunk/asymptote/base/graph3.asy
+ M /trunk/asymptote/base/three.asy
+ M /trunk/asymptote/base/three_surface.asy
+ A /trunk/asymptote/examples/logo3.asy
+ M /trunk/asymptote/settings.cc
+
+Add settings.thick option for rendering thick PRC lines (default is true).
+
+Don't force a mesh to be drawn when nolight is specified.
+
+Add Orest's 3D implementation of the Asymptote logo.
+
+------------------------------------------------------------------------
+r3350 | jcbowman | 2008-08-25 10:01:38 -0600 (Mon, 25 Aug 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/lineargraph.asy
+
+Use truepoint to attach legend in lineargraph.asy.
+
+------------------------------------------------------------------------
+r3349 | jcbowman | 2008-08-25 03:01:16 -0600 (Mon, 25 Aug 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/graph.asy
+ M /trunk/asymptote/base/graph3.asy
+
+Set both axis types; use symbolic values.
+
+------------------------------------------------------------------------
+r3348 | jcbowman | 2008-08-25 01:59:44 -0600 (Mon, 25 Aug 2008) | 4 lines
+Changed paths:
+ M /trunk/asymptote/base/grid3.asy
+ M /trunk/asymptote/doc/grid3xyz.asy
+
+Update grid3 to handle Arrow3.
+
+Use limits in grid3xyz.
+
+------------------------------------------------------------------------
+r3347 | jcbowman | 2008-08-25 01:11:07 -0600 (Mon, 25 Aug 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/three_surface.asy
+ M /trunk/asymptote/runtime.in
+
+Use all control points to compute normal vector of surfaces.
+
+------------------------------------------------------------------------
+r3346 | jcbowman | 2008-08-24 20:28:36 -0600 (Sun, 24 Aug 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/three_arrows.asy
+
+Remove unused code.
+
+------------------------------------------------------------------------
+r3345 | jcbowman | 2008-08-24 14:44:13 -0600 (Sun, 24 Aug 2008) | 8 lines
+Changed paths:
+ M /trunk/asymptote/base/plain_arrows.asy
+ M /trunk/asymptote/base/plain_picture.asy
+ M /trunk/asymptote/base/three.asy
+ M /trunk/asymptote/base/three_arrows.asy
+
+Improve arrow bounding box calculation.
+
+Fix 3D arrow positioning.
+
+Retune anglefactor for RPC angle calculation.
+
+Pass the correct size information to scale and scale3 when resizing.
+
+------------------------------------------------------------------------
+r3344 | jcbowman | 2008-08-23 13:58:27 -0600 (Sat, 23 Aug 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/three.asy
+ M /trunk/asymptote/base/three_surface.asy
+
+Implement unitdisk and linecap(0) and linecap(2).
+
+------------------------------------------------------------------------
+r3343 | jcbowman | 2008-08-23 12:21:52 -0600 (Sat, 23 Aug 2008) | 4 lines
+Changed paths:
+ M /trunk/asymptote/base/plain_shipout.asy
+ M /trunk/asymptote/base/solids.asy
+ M /trunk/asymptote/base/three.asy
+
+Support linecap(1) in 3D.
+
+Fix PRC mode.
+
+------------------------------------------------------------------------
+r3342 | jcbowman | 2008-08-23 03:46:16 -0600 (Sat, 23 Aug 2008) | 6 lines
+Changed paths:
+ M /trunk/asymptote/base/graph3.asy
+ M /trunk/asymptote/base/plain_picture.asy
+ M /trunk/asymptote/base/three.asy
+ M /trunk/asymptote/base/three_arrows.asy
+ M /trunk/asymptote/doc/helix.asy
+ M /trunk/asymptote/doc/unitcircle3.asy
+
+Add support for 3D arrows.
+
+Set uptodate=false in picture.add.
+
+Implement better workaround for missing movie15.sty.
+
+------------------------------------------------------------------------
+r3341 | jcbowman | 2008-08-23 00:51:45 -0600 (Sat, 23 Aug 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/cube.asy
+
+Update example.
+
+------------------------------------------------------------------------
+r3340 | jcbowman | 2008-08-23 00:46:57 -0600 (Sat, 23 Aug 2008) | 7 lines
+Changed paths:
+ M /trunk/asymptote/base/three.asy
+ M /trunk/asymptote/base/three_surface.asy
+
+Implement better workaround to allow nonPRC 3D output in the absence of the
+movie15.sty package.
+
+Rename unitcube to unitbox.
+
+Define surfaces unitplane and unitcube.
+
+------------------------------------------------------------------------
+r3339 | jcbowman | 2008-08-22 23:59:35 -0600 (Fri, 22 Aug 2008) | 8 lines
+Changed paths:
+ M /trunk/asymptote/base/plain_pens.asy
+ M /trunk/asymptote/base/solids.asy
+ M /trunk/asymptote/base/three_surface.asy
+ M /trunk/asymptote/examples/hyperboloid.asy
+
+Define pen thin=linewidth(0).
+
+Use thin pen by default for mesh lines and skeletons.
+
+Generalize revolution constructor based on a graph.
+
+Use operator .. in hyperboloid example.
+
+------------------------------------------------------------------------
+r3338 | oshardt | 2008-08-22 17:47:12 -0600 (Fri, 22 Aug 2008) | 1 line
+Changed paths:
+ M /trunk/asymptote/doc/logo3.asy
+
+Fix logo3.
+------------------------------------------------------------------------
+r3337 | oshardt | 2008-08-22 17:44:20 -0600 (Fri, 22 Aug 2008) | 1 line
+Changed paths:
+ M /trunk/asymptote/doc/logo3.asy
+
+Fix logo3.
+------------------------------------------------------------------------
+r3336 | oshardt | 2008-08-22 15:44:28 -0600 (Fri, 22 Aug 2008) | 1 line
+Changed paths:
+ A /trunk/asymptote/doc/logo3.asy
+
+Add 3D logo.
+------------------------------------------------------------------------
+r3335 | oshardt | 2008-08-22 14:21:48 -0600 (Fri, 22 Aug 2008) | 1 line
+Changed paths:
+ M /trunk/asymptote/prc/PRCTools/bitData.cc
+ M /trunk/asymptote/prc/PRCTools/describePRC.cc
+
+Improve debugging output.
+------------------------------------------------------------------------
+r3334 | jcbowman | 2008-08-22 12:35:50 -0600 (Fri, 22 Aug 2008) | 8 lines
+Changed paths:
+ M /trunk/asymptote/base/graph3.asy
+ M /trunk/asymptote/base/solids.asy
+ M /trunk/asymptote/base/three.asy
+ M /trunk/asymptote/base/three_arrows.asy
+ M /trunk/asymptote/base/three_surface.asy
+ M /trunk/asymptote/examples/cones.asy
+ M /trunk/asymptote/examples/cylinder.asy
+ M /trunk/asymptote/examples/hyperboloid.asy
+ M /trunk/asymptote/examples/sphere.asy
+ M /trunk/asymptote/examples/torus.asy
+ M /trunk/asymptote/examples/workcone.asy
+
+Use curved slices in solids; reduce the default value of nslice to 12.
+
+Standardize solids interface.
+
+Fix determinant of align and transform3.
+
+Use larger sphere fuzz in tube.
+
+------------------------------------------------------------------------
+r3333 | pivaldi | 2008-08-22 08:28:54 -0600 (Fri, 22 Aug 2008) | 1 line
+Changed paths:
+ M /trunk/asymptote/base/grid3.asy
+
+grid3.asy: set default value axis in routine (x/y/z)axis3.
+------------------------------------------------------------------------
+r3332 | pivaldi | 2008-08-22 08:18:27 -0600 (Fri, 22 Aug 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/grid3.asy
+
+grid3.asy: Renames (Left/Right)Ticks (Left/Right)Ticks3 for consistency.
+Remove an unnecessary parameter.
+------------------------------------------------------------------------
+r3331 | jcbowman | 2008-08-22 01:40:52 -0600 (Fri, 22 Aug 2008) | 4 lines
+Changed paths:
+ M /trunk/asymptote/base/graph3.asy
+
+Fix yaxis3 placement.
+
+Fix 3D Arc and Circle.
+
+------------------------------------------------------------------------
+r3330 | jcbowman | 2008-08-21 21:09:26 -0600 (Thu, 21 Aug 2008) | 4 lines
+Changed paths:
+ M /trunk/asymptote/prc/PRC.h
+ M /trunk/asymptote/prc/oPRCFile.cc
+ M /trunk/asymptote/prc/oPRCFile.h
+
+Add PRCVersion.
+
+Work around compiler bug in gcc-3.3.5.
+
+------------------------------------------------------------------------
+r3329 | oshardt | 2008-08-21 18:54:51 -0600 (Thu, 21 Aug 2008) | 1 line
+Changed paths:
+ M /trunk/asymptote/base/three_arrows.asy
+
+Add test for straightness.
+------------------------------------------------------------------------
+r3328 | jcbowman | 2008-08-21 09:54:29 -0600 (Thu, 21 Aug 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/graph3.asy
+ M /trunk/asymptote/base/three.asy
+
+Use unit normals in circle and Circle.
+
+------------------------------------------------------------------------
+r3327 | jcbowman | 2008-08-21 09:44:34 -0600 (Thu, 21 Aug 2008) | 3 lines
+Changed paths:
+ M /trunk/asymptote/texfile.cc
+
+Suppress page numbers for TeX engine; also suppress hoffset and voffset
+in inlinetex mode.
+
+------------------------------------------------------------------------
+r3326 | jcbowman | 2008-08-21 09:43:15 -0600 (Thu, 21 Aug 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/three_surface.asy
+
+Set straight only if no internal patch points are given.
+
+------------------------------------------------------------------------
+r3325 | jcbowman | 2008-08-21 03:48:06 -0600 (Thu, 21 Aug 2008) | 12 lines
+Changed paths:
+ M /trunk/asymptote/base/graph3.asy
+ M /trunk/asymptote/base/solids.asy
+ M /trunk/asymptote/base/three.asy
+ M /trunk/asymptote/base/three_arrows.asy
+ M /trunk/asymptote/base/three_surface.asy
+ M /trunk/asymptote/drawpath3.cc
+ M /trunk/asymptote/drawpath3.h
+ M /trunk/asymptote/drawsurface.cc
+ M /trunk/asymptote/drawsurface.h
+ M /trunk/asymptote/path.cc
+ M /trunk/asymptote/path3.cc
+ M /trunk/asymptote/prc/oPRCFile.cc
+ M /trunk/asymptote/prc/oPRCFile.h
+ M /trunk/asymptote/prcfile.h
+ M /trunk/asymptote/runtime.in
+
+Increase Fuzz to sqrtFuzz in min(surface) and max(surface) C++ routine.
+
+Expose granularity parameter to PRC surface drawing routines.
+
+Put PRC surface pens and parameters in a material structure.
+
+Add straight flag to surface.
+
+Speed up thick line drawing by optimizing straight case.
+
+Optimize align(triple) and implement its inverse, called transform3(triple).
+
+------------------------------------------------------------------------
+r3324 | oshardt | 2008-08-20 22:12:16 -0600 (Wed, 20 Aug 2008) | 1 line
+Changed paths:
+ M /trunk/asymptote/base/three_arrows.asy
+
+Add check for -X direction.
+------------------------------------------------------------------------
+r3323 | jcbowman | 2008-08-20 20:31:24 -0600 (Wed, 20 Aug 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/three.asy
+ M /trunk/asymptote/base/three_arrows.asy
+ M /trunk/asymptote/base/three_surface.asy
+ M /trunk/asymptote/drawpath3.cc
+
+Add hook for thick line PRC support.
+
+------------------------------------------------------------------------
+r3322 | jcbowman | 2008-08-20 17:30:04 -0600 (Wed, 20 Aug 2008) | 6 lines
+Changed paths:
+ M /trunk/asymptote/base/plain_arcs.asy
+ M /trunk/asymptote/base/plain_pens.asy
+ M /trunk/asymptote/base/three.asy
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/drawpath.cc
+ M /trunk/asymptote/examples/Klein.asy
+ M /trunk/asymptote/examples/parametricsurface.asy
+
+Make linewidth(0) draw the thinnest line supported by the output device.
+
+Redefine nullpen to linewidth(0)+invisible.
+
+Remove duplicate code.
+
+------------------------------------------------------------------------
+r3321 | jcbowman | 2008-08-20 15:45:25 -0600 (Wed, 20 Aug 2008) | 8 lines
+Changed paths:
+ M /trunk/asymptote/base/contour3.asy
+ M /trunk/asymptote/base/graph.asy
+ M /trunk/asymptote/base/graph3.asy
+ M /trunk/asymptote/base/solids.asy
+ M /trunk/asymptote/base/three.asy
+ M /trunk/asymptote/base/three_surface.asy
+ M /trunk/asymptote/examples/magnetic.asy
+
+Remove extra node from Circle.
+
+Add additional surface constructors.
+
+Fix transverse skeleton when angle2-angle1 < 360.
+
+Make contour3 return a surface.
+
+------------------------------------------------------------------------
+r3320 | jcbowman | 2008-08-20 10:06:35 -0600 (Wed, 20 Aug 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/graph.asy
+ M /trunk/asymptote/base/graph3.asy
+ M /trunk/asymptote/base/graph_settings.asy
+ M /trunk/asymptote/base/three.asy
+
+Fix Circle and Arc so that they are consistent with circle and arc.
+
+------------------------------------------------------------------------
+r3319 | oshardt | 2008-08-20 09:50:53 -0600 (Wed, 20 Aug 2008) | 1 line
+Changed paths:
+ A /trunk/asymptote/base/three_arrows.asy
+
+Add 3d support for thick lines and arrows.
+------------------------------------------------------------------------
+r3318 | jcbowman | 2008-08-20 03:52:42 -0600 (Wed, 20 Aug 2008) | 26 lines
+Changed paths:
+ A /trunk/asymptote/base/bsp.asy
+ M /trunk/asymptote/base/contour3.asy
+ M /trunk/asymptote/base/graph.asy
+ M /trunk/asymptote/base/graph3.asy
+ M /trunk/asymptote/base/grid3.asy
+ M /trunk/asymptote/base/palette.asy
+ M /trunk/asymptote/base/plain.asy
+ M /trunk/asymptote/base/plain_picture.asy
+ M /trunk/asymptote/base/plain_shipout.asy
+ M /trunk/asymptote/base/solids.asy
+ M /trunk/asymptote/base/syzygy.asy
+ M /trunk/asymptote/base/three.asy
+ M /trunk/asymptote/base/three_surface.asy
+ M /trunk/asymptote/doc/GaussianSurface.asy
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/doc/axis3.asy
+ M /trunk/asymptote/doc/cube.asy
+ M /trunk/asymptote/doc/flowchartdemo.asy
+ M /trunk/asymptote/doc/generalaxis.asy
+ M /trunk/asymptote/doc/generalaxis3.asy
+ M /trunk/asymptote/doc/grid3xyz.asy
+ M /trunk/asymptote/doc/helix.asy
+ M /trunk/asymptote/doc/join3.asy
+ M /trunk/asymptote/doc/lineargraph.asy
+ M /trunk/asymptote/doc/planes.asy
+ M /trunk/asymptote/examples/magnetic.asy
+ M /trunk/asymptote/examples/parametricsurface.asy
+ M /trunk/asymptote/examples/sinc.asy
+ M /trunk/asymptote/process.cc
+ M /trunk/asymptote/runtime.in
+
+Remove implicit casts from 3D to 2D objects (call project explicitly instead).
+
+Overhaul graph3 and grid3 to draw directly in 3D, keeping track of the
+picture bounds with an interface analogous to the graph2 routines (backwards
+incompatible).
+
+Update contour3 and solids to use new PRC-compatible surface drawing routines.
+
+Fix and optimize 3D fitting routines.
+
+Fix label bounds.
+
+Add functions XY(), etc., to force labels to be upright.
+
+Fix invert routine by adding missing shift terms.
+
+Make uptodate apply only to currentpicture.
+
+Add warn=true argument to solve routines.
+
+Simplify flowchartdemo deferred drawing.
+
+Move binary space partition code out of three.asy and into bsp.asy.
+
+Add operators == and != for real[][] and path3.
+
+------------------------------------------------------------------------
+r3317 | jcbowman | 2008-08-18 01:39:15 -0600 (Mon, 18 Aug 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/plain_Label.asy
+
+Fix align.is3D flag.
+
+------------------------------------------------------------------------
+r3316 | jcbowman | 2008-08-18 01:03:08 -0600 (Mon, 18 Aug 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/plain_Label.asy
+
+Fix Label diagnostic.
+
+------------------------------------------------------------------------
+r3315 | jcbowman | 2008-08-16 12:43:32 -0600 (Sat, 16 Aug 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/process.cc
+
+Use settings::outname instead of "out".
+
+------------------------------------------------------------------------
+r3314 | jcbowman | 2008-08-15 15:08:27 -0600 (Fri, 15 Aug 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/three_surface.asy
+
+Fix 3D label sizing.
+
+------------------------------------------------------------------------
+r3313 | jcbowman | 2008-08-15 14:57:09 -0600 (Fri, 15 Aug 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/three.asy
+
+Add operators == and != for path3.
+
+------------------------------------------------------------------------
+r3312 | jcbowman | 2008-08-15 01:13:17 -0600 (Fri, 15 Aug 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/plain_picture.asy
+
+Use currentprojection by default in min3(picture) and max3(picture).
+
+------------------------------------------------------------------------
+r3311 | jcbowman | 2008-08-15 01:02:58 -0600 (Fri, 15 Aug 2008) | 7 lines
+Changed paths:
+ M /trunk/asymptote/base/plain_picture.asy
+ M /trunk/asymptote/base/plain_shipout.asy
+ M /trunk/asymptote/base/three.asy
+ M /trunk/asymptote/base/three_surface.asy
+
+Remove width and height parameters from embed(picture).
+
+In embed(picture), avoid unused 2D bounding box calculation in final call
+to pic.fit3().
+
+Add embed options to shipout.
+
+------------------------------------------------------------------------
+r3310 | jcbowman | 2008-08-14 12:12:57 -0600 (Thu, 14 Aug 2008) | 6 lines
+Changed paths:
+ M /trunk/asymptote/base/plain_picture.asy
+ M /trunk/asymptote/base/stats.asy
+ M /trunk/asymptote/base/three.asy
+ M /trunk/asymptote/base/three_surface.asy
+
+Add drawer3 routine that works with pictures instead of frames.
+
+Make randompath(n) return a path of length n.
+
+Fix and optimize camera transforms.
+
+------------------------------------------------------------------------
+r3309 | jcbowman | 2008-08-14 01:42:05 -0600 (Thu, 14 Aug 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/plain_picture.asy
+ M /trunk/asymptote/base/three.asy
+
+Remove remaining "camera too close" messages (no longer needed).
+
+------------------------------------------------------------------------
+r3308 | jcbowman | 2008-08-14 01:28:15 -0600 (Thu, 14 Aug 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/plain_picture.asy
+
+Reinstate add(drawer d) function.
+
+------------------------------------------------------------------------
+r3307 | jcbowman | 2008-08-14 01:12:24 -0600 (Thu, 14 Aug 2008) | 8 lines
+Changed paths:
+ M /trunk/asymptote/base/bezulate.asy
+ M /trunk/asymptote/base/plain_arrows.asy
+ M /trunk/asymptote/base/plain_picture.asy
+ M /trunk/asymptote/base/plain_shipout.asy
+ M /trunk/asymptote/base/three.asy
+ M /trunk/asymptote/base/three_surface.asy
+
+Add path3 copy constructor.
+
+Automatically adjust camera so that entire picture is in front of camera.
+
+Add projection argument to shipout.
+
+Add min3(pic) and max3(pic) functions.
+
+------------------------------------------------------------------------
+r3306 | jcbowman | 2008-08-13 08:32:00 -0600 (Wed, 13 Aug 2008) | 6 lines
+Changed paths:
+ M /trunk/asymptote/base/plain_arrows.asy
+ M /trunk/asymptote/base/plain_picture.asy
+ M /trunk/asymptote/base/three.asy
+ M /trunk/asymptote/base/three_surface.asy
+ M /trunk/asymptote/drawsurface.cc
+ M /trunk/asymptote/drawsurface.h
+ M /trunk/asymptote/runtime.in
+
+Move projection and picture argument (for double deferred drawing) to drawer3.
+
+Fix duplicate calls to tensorshade.
+
+Re-enable surface transparency.
+
+------------------------------------------------------------------------
+r3305 | oshardt | 2008-08-12 12:47:25 -0600 (Tue, 12 Aug 2008) | 1 line
+Changed paths:
+ M /trunk/asymptote/base/three.asy
+
+Optimize 3d reflection routine.
+------------------------------------------------------------------------
+r3304 | jcbowman | 2008-08-12 09:50:14 -0600 (Tue, 12 Aug 2008) | 12 lines
+Changed paths:
+ M /trunk/asymptote/base/graph_settings.asy
+ M /trunk/asymptote/base/plain_Label.asy
+ M /trunk/asymptote/base/plain_arrows.asy
+ M /trunk/asymptote/base/plain_paths.asy
+ M /trunk/asymptote/base/plain_picture.asy
+ M /trunk/asymptote/base/stats.asy
+ M /trunk/asymptote/base/three.asy
+ M /trunk/asymptote/base/three_surface.asy
+ M /trunk/asymptote/runtime.in
+
+Add realmult(triple,triple).
+
+Remove "camera too close" checks.
+
+Fix randompath; add randompath3.
+
+Add draw(frame,surface) routine.
+
+Allow align parameter of Label to be a triple.
+
+Make size(picture) return max(pic)-min(pic), as with frames.
+
+------------------------------------------------------------------------
+r3303 | jcbowman | 2008-08-10 10:48:32 -0600 (Sun, 10 Aug 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/builtin.cc
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/runtime.in
+
+Add general T[] sort(T[] a, bool compare(T i, T j)) function.
+
+------------------------------------------------------------------------
+r3302 | jcbowman | 2008-08-09 08:40:53 -0600 (Sat, 09 Aug 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/three.asy
+
+Don't call surface mesh if meshpen == invisible.
+
+------------------------------------------------------------------------
+r3301 | jcbowman | 2008-08-09 00:04:52 -0600 (Sat, 09 Aug 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/path3.cc
+
+Increase fuzz in min(surface,projection) routine.
+
+------------------------------------------------------------------------
+r3300 | jcbowman | 2008-08-08 20:01:30 -0600 (Fri, 08 Aug 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/plain_picture.asy
+
+Fix picture min/max functions.
+
+------------------------------------------------------------------------
+r3299 | jcbowman | 2008-08-08 19:53:22 -0600 (Fri, 08 Aug 2008) | 8 lines
+Changed paths:
+ M /trunk/asymptote/base/plain_picture.asy
+ M /trunk/asymptote/base/three.asy
+ M /trunk/asymptote/picture.cc
+ M /trunk/asymptote/picture.h
+ M /trunk/asymptote/settings.cc
+
+Fix PRC angle computation.
+
+Rename reload to pdfreload (now disabled by default); add pdfreloadOptions.
+
+Fix empty picture check in max/min.
+
+Move default 3d embedding settings to defaultembed3options variable.
+
+------------------------------------------------------------------------
+r3298 | jcbowman | 2008-08-08 02:24:25 -0600 (Fri, 08 Aug 2008) | 4 lines
+Changed paths:
+ M /trunk/asymptote/base/plain_picture.asy
+ M /trunk/asymptote/base/three.asy
+
+Fix empty tests in picture min and max routines.
+
+Fix projection in draw(surface).
+
+------------------------------------------------------------------------
+r3297 | jcbowman | 2008-08-08 01:57:04 -0600 (Fri, 08 Aug 2008) | 6 lines
+Changed paths:
+ M /trunk/asymptote/base/three.asy
+ M /trunk/asymptote/base/three_surface.asy
+
+Compute PRC lens angle based on projected picture size.
+
+Support lens angle in viewpoint.
+
+Simplify embedprc options.
+
+------------------------------------------------------------------------
+r3296 | jcbowman | 2008-08-08 01:40:15 -0600 (Fri, 08 Aug 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/plain_strings.asy
+
+Fix handling of null deliminted entries in split.
+
+------------------------------------------------------------------------
+r3295 | jcbowman | 2008-08-07 23:28:33 -0600 (Thu, 07 Aug 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/plain_picture.asy
+
+Fix scale and scale3.
+
+------------------------------------------------------------------------
+r3294 | oshardt | 2008-08-07 11:54:41 -0600 (Thu, 07 Aug 2008) | 1 line
+Changed paths:
+ M /trunk/asymptote/base/three.asy
+
+Optimize routine for rotation of axes.
+------------------------------------------------------------------------
+r3293 | jcbowman | 2008-08-06 14:55:45 -0600 (Wed, 06 Aug 2008) | 4 lines
+Changed paths:
+ M /trunk/asymptote/base/plain_picture.asy
+ M /trunk/asymptote/base/three.asy
+ M /trunk/asymptote/base/three_surface.asy
+
+Support meshpen in PRC mode.
+
+Avoid duplicate drawing due to inexact bounds.
+
+------------------------------------------------------------------------
+r3292 | jcbowman | 2008-08-06 12:46:50 -0600 (Wed, 06 Aug 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/plain_picture.asy
+
+Fix supplementary scaling routines.
+
+------------------------------------------------------------------------
+r3291 | jcbowman | 2008-08-06 12:45:43 -0600 (Wed, 06 Aug 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/three.asy
+ M /trunk/asymptote/base/three_surface.asy
+ M /trunk/asymptote/drawsurface.h
+ M /trunk/asymptote/runtime.in
+
+Fix projection transformations.
+
+------------------------------------------------------------------------
+r3290 | oshardt | 2008-08-06 09:53:23 -0600 (Wed, 06 Aug 2008) | 1 line
+Changed paths:
+ M /trunk/asymptote/prc/writePRC.cc
+
+Fix uint32_t cast.
+------------------------------------------------------------------------
+r3289 | jcbowman | 2008-08-06 08:51:30 -0600 (Wed, 06 Aug 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/plain_Label.asy
+
+Cache return values of texpath.
+
+------------------------------------------------------------------------
+r3288 | jcbowman | 2008-08-06 08:16:37 -0600 (Wed, 06 Aug 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/drawtree.asy
+
+Apply submitted drawtree patches (Bug IDs 2031338,2031368, and 2031511).
+
+------------------------------------------------------------------------
+r3287 | jcbowman | 2008-08-06 00:57:49 -0600 (Wed, 06 Aug 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/grid3xyz.asy
+
+Remove obsolete call to aspect.
+
+------------------------------------------------------------------------
+r3286 | jcbowman | 2008-08-06 00:47:52 -0600 (Wed, 06 Aug 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/axis3.asy
+
+Temporarily revert change to allow svn builds.
+
+------------------------------------------------------------------------
+r3285 | jcbowman | 2008-08-06 00:36:59 -0600 (Wed, 06 Aug 2008) | 20 lines
+Changed paths:
+ M /trunk/asymptote/base/graph.asy
+ M /trunk/asymptote/base/math.asy
+ M /trunk/asymptote/base/plain_Label.asy
+ M /trunk/asymptote/base/plain_picture.asy
+ M /trunk/asymptote/base/three.asy
+ M /trunk/asymptote/base/three_surface.asy
+ M /trunk/asymptote/builtin.cc
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/doc/axis3.asy
+ M /trunk/asymptote/doc/cube.asy
+ M /trunk/asymptote/doc/generalaxis3.asy
+ M /trunk/asymptote/doc/helix.asy
+ M /trunk/asymptote/drawsurface.cc
+ M /trunk/asymptote/drawsurface.h
+ M /trunk/asymptote/examples/BezierSurface.asy
+ M /trunk/asymptote/examples/sinc.asy
+ M /trunk/asymptote/prc/writePRC.cc
+ M /trunk/asymptote/runtime.in
+
+Remove obsolete aspect ratio support from projection routines (use size3
+instead).
+
+Move diagonal(... real[] a) to runtime code.
+
+Add support for alternative PRC materials in surface routines.
+
+By default draw 3D labels without lighting effects.
+
+Add extra options string to PRC embed functions.
+
+Add min3(pen) and max3(pen) functions (only a spherical pen nib is currenty
+allowed).
+
+Remove unused cap functions from plain_picture.
+
+Fully implement drawerBound3 routines.
+
+Fix transform3 initialization in Label.
+
+------------------------------------------------------------------------
+r3284 | oshardt | 2008-08-05 19:09:40 -0600 (Tue, 05 Aug 2008) | 1 line
+Changed paths:
+ M /trunk/asymptote/prc/oPRCFile.cc
+ M /trunk/asymptote/prc/oPRCFile.h
+ M /trunk/asymptote/prcfile.h
+
+Add support for materials in prc.
+------------------------------------------------------------------------
+r3283 | jcbowman | 2008-08-05 11:12:08 -0600 (Tue, 05 Aug 2008) | 4 lines
+Changed paths:
+ M /trunk/asymptote/reload.js
+ M /trunk/asymptote/silentPrint.js
+
+Make reload load the document if not already active.
+
+Improve documentation.
+
+------------------------------------------------------------------------
+r3282 | jcbowman | 2008-08-05 10:48:27 -0600 (Tue, 05 Aug 2008) | 3 lines
+Changed paths:
+ M /trunk/asymptote/prc/oPRCFile.cc
+
+Avoid arbitrary default values; set line width to zero since that appears to
+be the only value implemented by Adobe Reader 8.1.2 and 9.0.
+
+------------------------------------------------------------------------
+r3281 | jcbowman | 2008-08-03 19:50:06 -0600 (Sun, 03 Aug 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/texfile.cc
+ M /trunk/asymptote/texfile.h
+
+Support ASYbase in texpath.
+
+------------------------------------------------------------------------
+r3280 | jcbowman | 2008-08-03 01:26:56 -0600 (Sun, 03 Aug 2008) | 4 lines
+Changed paths:
+ M /trunk/asymptote/base/three.asy
+ M /trunk/asymptote/picture.cc
+
+Remove quotes from viewerOptions.
+
+Optimize piecewisestraight.
+
+------------------------------------------------------------------------
+r3279 | jcbowman | 2008-08-02 22:49:09 -0600 (Sat, 02 Aug 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/three.asy
+
+Fix straight flag in drawprc.
+
+------------------------------------------------------------------------
+r3278 | jcbowman | 2008-08-02 22:37:56 -0600 (Sat, 02 Aug 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/three.asy
+
+Set straight flag on transformation.
+
+------------------------------------------------------------------------
+r3277 | jcbowman | 2008-08-02 20:34:36 -0600 (Sat, 02 Aug 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/settings.cc
+
+Automatically embed option defaults into descriptions.
+
+------------------------------------------------------------------------
+r3276 | jcbowman | 2008-08-02 18:01:40 -0600 (Sat, 02 Aug 2008) | 3 lines
+Changed paths:
+ M /trunk/asymptote/picture.cc
+ M /trunk/asymptote/settings.cc
+
+Only attempt reload if acroread process is already running; add reloaddelay
+parameter.
+
+------------------------------------------------------------------------
+r3275 | jcbowman | 2008-08-02 16:18:12 -0600 (Sat, 02 Aug 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/three_surface.asy
+
+Add unitcylinder.
+
+------------------------------------------------------------------------
+r3274 | jcbowman | 2008-08-02 14:19:23 -0600 (Sat, 02 Aug 2008) | 6 lines
+Changed paths:
+ M /trunk/asymptote/picture.cc
+ M /trunk/asymptote/picture.h
+ A /trunk/asymptote/reload.js
+ M /trunk/asymptote/settings.cc
+ M /trunk/asymptote/silentPrint.js
+ M /trunk/asymptote/util.cc
+ M /trunk/asymptote/util.h
+
+Add code to automatically reload pdf files in viewer if
+settings.reload=true (requires manual installation of reload.js in
+~/.adobe/Acrobat/x.x/JavaScripts/).
+
+Add psviewerOptions and pdfviewerOptions.
+
+------------------------------------------------------------------------
+r3273 | jcbowman | 2008-08-02 14:11:23 -0600 (Sat, 02 Aug 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/prc/oPRCFile.cc
+
+Simplify solid line pattern.
+
+------------------------------------------------------------------------
+r3272 | jcbowman | 2008-08-01 16:59:59 -0600 (Fri, 01 Aug 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/plain_shipout.asy
+
+Fix -psimage -tex pdflatex.
+
+------------------------------------------------------------------------
+r3271 | jcbowman | 2008-08-01 15:10:30 -0600 (Fri, 01 Aug 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/plain_shipout.asy
+ M /trunk/asymptote/picture.cc
+
+Remove interfering comments; change psimage timeout to 60 seconds.
+
+------------------------------------------------------------------------
+r3270 | jcbowman | 2008-08-01 10:36:55 -0600 (Fri, 01 Aug 2008) | 7 lines
+Changed paths:
+ M /trunk/asymptote/base/plain_shipout.asy
+ D /trunk/asymptote/print.js
+ M /trunk/asymptote/settings.cc
+ A /trunk/asymptote/silentPrint.js (from /trunk/asymptote/print.js:3269)
+
+Rename print.js to silentPrint.js; move all other Javascript commands to
+asy code.
+
+Check whether silentPrint is defined.
+
+Fix texengine(true).
+
+------------------------------------------------------------------------
+r3269 | jcbowman | 2008-08-01 01:58:03 -0600 (Fri, 01 Aug 2008) | 4 lines
+Changed paths:
+ M /trunk/asymptote/picture.cc
+ A /trunk/asymptote/print.js
+
+Add print.js; this should be put in ~/.adobe/Acrobat/8.0/JavaScripts/.
+
+Make -psimage give up on waiting for Adobe Reader to finish after 30 seconds.
+
+------------------------------------------------------------------------
+r3268 | jcbowman | 2008-08-01 01:43:50 -0600 (Fri, 01 Aug 2008) | 7 lines
+Changed paths:
+ M /trunk/asymptote/base/animation.asy
+ M /trunk/asymptote/base/plain_shipout.asy
+ M /trunk/asymptote/base/three.asy
+ M /trunk/asymptote/base/three_light.asy
+ M /trunk/asymptote/doc/GaussianSurface.asy
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/doc/cube.asy
+ M /trunk/asymptote/picture.cc
+ M /trunk/asymptote/runtime.in
+ M /trunk/asymptote/settings.cc
+ M /trunk/asymptote/settings.h
+
+Add -psimage option to dump rasterized postscript image of PRC scene.
+
+Force texpath to use latex/tex engine even with -tex pdflatex and -tex pdftex;
+add texdvicommand to specify an alternative latex/tex to dvi program.
+
+Use correct output prefix for intermediate PRC files.
+
+------------------------------------------------------------------------
+r3267 | jcbowman | 2008-07-31 22:23:29 -0600 (Thu, 31 Jul 2008) | 6 lines
+Changed paths:
+ M /trunk/asymptote/base/plain_Label.asy
+ M /trunk/asymptote/base/plain_picture.asy
+ M /trunk/asymptote/base/three_surface.asy
+
+Remove bulge from unitcube.
+
+Implement nolight with boolean variable.
+
+Fix sizing of transformed 3D pictures.
+
+------------------------------------------------------------------------
+r3266 | jcbowman | 2008-07-30 13:14:02 -0600 (Wed, 30 Jul 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/GUI/xasyOptionsDialog.py
+
+Use portable constructor for BooleanVar.
+
+------------------------------------------------------------------------
+r3265 | jcbowman | 2008-07-30 12:59:23 -0600 (Wed, 30 Jul 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/GUI/xasyOptions.py
+
+Move xasy.conf into ~/.asy directory.
+
+------------------------------------------------------------------------
+r3264 | jcbowman | 2008-07-30 11:02:46 -0600 (Wed, 30 Jul 2008) | 7 lines
+Changed paths:
+ M /trunk/asymptote/base/plain.asy
+ M /trunk/asymptote/base/plain_picture.asy
+ M /trunk/asymptote/base/plain_shipout.asy
+ M /trunk/asymptote/base/three.asy
+ M /trunk/asymptote/base/three_surface.asy
+ M /trunk/asymptote/doc/cube.asy
+ M /trunk/asymptote/examples/BezierSurface.asy
+
+Allow separate 2D and 3D picture sizes.
+
+Use double deferred drawing for 3D projection to allow control of the 3D aspect
+ratio and also the width and height of the final projected picture.
+
+Remove obsolete cycle3 variable.
+
+------------------------------------------------------------------------
+r3263 | jcbowman | 2008-07-29 16:56:42 -0600 (Tue, 29 Jul 2008) | 8 lines
+Changed paths:
+ M /trunk/asymptote/base/plain_Label.asy
+ M /trunk/asymptote/base/plain_picture.asy
+ M /trunk/asymptote/base/three.asy
+ M /trunk/asymptote/base/three_surface.asy
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/doc/cube.asy
+ M /trunk/asymptote/doc/unitcircle3.asy
+ M /trunk/asymptote/runtime.in
+
+Typeset 3D labels onto projection plane by default.
+
+Fix roll computation.
+
+Add transform3(triple u, triple v) that maps (X,Y) to (u,v).
+
+Add solidcone.
+
+------------------------------------------------------------------------
+r3262 | oshardt | 2008-07-29 14:47:55 -0600 (Tue, 29 Jul 2008) | 1 line
+Changed paths:
+ M /trunk/asymptote/GUI/xasyGUIIcons.py
+
+Use cleaner icons.
+------------------------------------------------------------------------
+r3261 | oshardt | 2008-07-29 12:40:49 -0600 (Tue, 29 Jul 2008) | 1 line
+Changed paths:
+ M /trunk/asymptote/Delaunay.cc
+
+Fix typo.
+------------------------------------------------------------------------
+r3260 | oshardt | 2008-07-29 12:38:40 -0600 (Tue, 29 Jul 2008) | 1 line
+Changed paths:
+ M /trunk/asymptote/prc/PRCTools/describePRC.cc
+ M /trunk/asymptote/prc/PRCTools/describePRC.h
+
+Describe scene display parameters.
+------------------------------------------------------------------------
+r3259 | oshardt | 2008-07-29 10:30:42 -0600 (Tue, 29 Jul 2008) | 1 line
+Changed paths:
+ M /trunk/asymptote/GUI/xasyMainWin.py
+
+Do not freeze while waiting for external editor to close.
+------------------------------------------------------------------------
+r3258 | jcbowman | 2008-07-28 23:53:30 -0600 (Mon, 28 Jul 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/path3.cc
+
+Fix hang in surface bbox routines.
+
+------------------------------------------------------------------------
+r3257 | jcbowman | 2008-07-28 23:04:58 -0600 (Mon, 28 Jul 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/three_surface.asy
+
+Add unit cone.
+
+------------------------------------------------------------------------
+r3256 | jcbowman | 2008-07-28 07:47:31 -0600 (Mon, 28 Jul 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/plain_Label.asy
+ M /trunk/asymptote/base/three.asy
+ M /trunk/asymptote/base/three_surface.asy
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/doc/saddle.asy
+ M /trunk/asymptote/doc/unitcircle3.asy
+
+Add support for path3 Labels.
+
+------------------------------------------------------------------------
+r3255 | jcbowman | 2008-07-27 23:09:39 -0600 (Sun, 27 Jul 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/Makefile.in
+
+Fix generation of asy-keywords.el.
+
+------------------------------------------------------------------------
+r3254 | jcbowman | 2008-07-27 22:57:25 -0600 (Sun, 27 Jul 2008) | 8 lines
+Changed paths:
+ M /trunk/asymptote/base/plain_Label.asy
+ M /trunk/asymptote/base/plain_picture.asy
+ M /trunk/asymptote/base/three.asy
+ M /trunk/asymptote/base/three_surface.asy
+ M /trunk/asymptote/doc/cube.asy
+ M /trunk/asymptote/examples/BezierSurface.asy
+ M /trunk/asymptote/examples/teapot.asy
+
+Defer projection of 3D (non-prc) pictures until drawing time.
+
+Express currentprojection in terms of user (picture) coordinates.
+
+Add missing tensorshade functions.
+
+Add casts from object to label and object to frame.
+
+------------------------------------------------------------------------
+r3253 | jcbowman | 2008-07-27 21:30:54 -0600 (Sun, 27 Jul 2008) | 8 lines
+Changed paths:
+ M /trunk/asymptote/base/animation.asy
+ M /trunk/asymptote/base/patterns.asy
+ M /trunk/asymptote/base/slide.asy
+ M /trunk/asymptote/castop.h
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/runtime.in
+
+Add locale() function to query/set current locale.
+
+Add locale string to format(string s, real x).
+
+Add string(int) function.
+
+Fix locale issues.
+
+------------------------------------------------------------------------
+r3252 | jcbowman | 2008-07-27 16:02:26 -0600 (Sun, 27 Jul 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/plain_strings.asy
+ M /trunk/asymptote/castop.h
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/runtime.in
+
+Make string(real, int digits=realDigits) use fixed notation.
+
+------------------------------------------------------------------------
+r3251 | jcbowman | 2008-07-27 00:12:38 -0600 (Sun, 27 Jul 2008) | 7 lines
+Changed paths:
+ M /trunk/asymptote/base/plain_Label.asy
+ M /trunk/asymptote/base/plain_picture.asy
+ M /trunk/asymptote/base/three.asy
+ M /trunk/asymptote/base/three_surface.asy
+ M /trunk/asymptote/doc/cube.asy
+ M /trunk/asymptote/examples/BezierSurface.asy
+ M /trunk/asymptote/examples/label3ribbon.asy
+
+Add three-dimensional Label support.
+
+Support adding a three-dimensional frame to a picture (positioned at the
+origin).
+
+Remove three-dimensional add functions in favour of embed.
+
+------------------------------------------------------------------------
+r3250 | jcbowman | 2008-07-26 18:22:39 -0600 (Sat, 26 Jul 2008) | 2 lines
+Changed paths:
+ D /trunk/asymptote/base/light.asy
+ D /trunk/asymptote/base/surface.asy
+ M /trunk/asymptote/base/three.asy
+ A /trunk/asymptote/base/three_light.asy (from /trunk/asymptote/base/light.asy:3249)
+ A /trunk/asymptote/base/three_surface.asy (from /trunk/asymptote/base/surface.asy:3249)
+
+Rename surface.asy to three_surface.asy and light.asy to three_light.asy.
+
+------------------------------------------------------------------------
+r3249 | jcbowman | 2008-07-26 18:15:03 -0600 (Sat, 26 Jul 2008) | 14 lines
+Changed paths:
+ M /trunk/asymptote/base/contour3.asy
+ M /trunk/asymptote/base/graph3.asy
+ M /trunk/asymptote/base/light.asy
+ M /trunk/asymptote/base/plain_constants.asy
+ M /trunk/asymptote/base/plain_paths.asy
+ M /trunk/asymptote/base/plain_picture.asy
+ M /trunk/asymptote/base/solids.asy
+ M /trunk/asymptote/base/surface.asy
+ M /trunk/asymptote/base/three.asy
+ M /trunk/asymptote/doc/cube.asy
+ M /trunk/asymptote/examples/BezierSurface.asy
+ M /trunk/asymptote/examples/label3.asy
+ M /trunk/asymptote/examples/label3ribbon.asy
+ M /trunk/asymptote/examples/teapot.asy
+ M /trunk/asymptote/path.h
+ M /trunk/asymptote/path3.cc
+ M /trunk/asymptote/runtime.in
+ M /trunk/asymptote/triple.h
+
+Move surface max and min functions to C++ code.
+
+Fix three-dimensional label functions.
+
+Implement unitsphere as an 8-patch Bezier approximation.
+
+Add three-dimensional dot functions.
+
+Include surface.asy and light.asy in three.asy.
+
+Remove casts from triple to pair and triple[][] to patch.
+
+Fix surface normals.
+
+------------------------------------------------------------------------
+r3248 | oshardt | 2008-07-26 08:14:27 -0600 (Sat, 26 Jul 2008) | 1 line
+Changed paths:
+ M /trunk/asymptote/base/bezulate.asy
+
+Preserve original path's direction for each new region created.
+------------------------------------------------------------------------
+r3247 | jcbowman | 2008-07-25 16:53:29 -0600 (Fri, 25 Jul 2008) | 4 lines
+Changed paths:
+ M /trunk/asymptote/base/bezulate.asy
+
+Fix removeDuplicates.
+
+Simplify uncycle.
+
+------------------------------------------------------------------------
+r3246 | jcbowman | 2008-07-25 15:38:43 -0600 (Fri, 25 Jul 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/bezulate.asy
+
+Use DBL_MANT_DIG for recursion depth limit.
+
+------------------------------------------------------------------------
+r3245 | jcbowman | 2008-07-23 02:16:40 -0600 (Wed, 23 Jul 2008) | 9 lines
+Changed paths:
+ M /trunk/asymptote/base/graph.asy
+ M /trunk/asymptote/base/graph3.asy
+ M /trunk/asymptote/base/plain_picture.asy
+ M /trunk/asymptote/base/surface.asy
+ M /trunk/asymptote/base/three.asy
+ A /trunk/asymptote/bbox3.h
+ M /trunk/asymptote/drawelement.h
+ M /trunk/asymptote/drawpath3.h
+ M /trunk/asymptote/drawsurface.h
+ M /trunk/asymptote/examples/BezierSurface.asy
+ M /trunk/asymptote/examples/label3.asy
+ M /trunk/asymptote/examples/label3ribbon.asy
+ M /trunk/asymptote/examples/teapot.asy
+ M /trunk/asymptote/picture.cc
+ M /trunk/asymptote/picture.h
+ M /trunk/asymptote/runtime.in
+ M /trunk/asymptote/settings.cc
+
+Generalize picture to handle 3D objects.
+
+Rename surface to patch; implement a surface structure to hold an array of
+patches.
+
+Implement simpler, faster surface bounding box routines.
+
+Add -prc setting (temporarily set to false) to enable prc output.
+
+------------------------------------------------------------------------
+r3244 | jcbowman | 2008-07-23 02:09:52 -0600 (Wed, 23 Jul 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/stats.asy
+
+Add randompath function.
+
+------------------------------------------------------------------------
+r3243 | jcbowman | 2008-07-23 02:02:59 -0600 (Wed, 23 Jul 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/embedding.asy
+
+Fix height and width units.
+
+------------------------------------------------------------------------
+r3242 | jcbowman | 2008-07-07 00:43:29 -0600 (Mon, 07 Jul 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/bbox.h
+ M /trunk/asymptote/path.cc
+
+Use bounding box rather than less efficient convex hull test in inside.
+
+------------------------------------------------------------------------
+r3241 | jcbowman | 2008-07-06 22:52:29 -0600 (Sun, 06 Jul 2008) | 2 lines
+Changed paths:
+ D /trunk/asymptote/xasy3
+
+Remove obsolete file.
+
+------------------------------------------------------------------------
+r3240 | jcbowman | 2008-07-06 17:23:42 -0600 (Sun, 06 Jul 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/Makefile.in
+ M /trunk/asymptote/patches/README
+ A /trunk/asymptote/patches/gc-7.1FreeBSD.patch
+
+Support compilation of gc-7.1 with gcc-4.3.1 on FreeBSD 4.10-RELEASE-p2.
+
+------------------------------------------------------------------------
+r3239 | pivaldi | 2008-07-06 14:40:28 -0600 (Sun, 06 Jul 2008) | 1 line
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+
+Fix the documentation of quarticroots.
+------------------------------------------------------------------------
+r3238 | jcbowman | 2008-07-05 22:21:50 -0600 (Sat, 05 Jul 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/Delaunay.cc
+
+Minor optimization.
+
+------------------------------------------------------------------------
+r3237 | jcbowman | 2008-07-05 22:11:36 -0600 (Sat, 05 Jul 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/configure.ac
+
+Remove HAVE_TRIANGLE configuration.
+
+------------------------------------------------------------------------
+r3236 | jcbowman | 2008-07-05 22:05:42 -0600 (Sat, 05 Jul 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/prc/oPRCFile.cc
+ M /trunk/asymptote/prc/writePRC.cc
+ M /trunk/asymptote/prc/writePRC.h
+
+Port prc code to cygwin.
+
+------------------------------------------------------------------------
+r3235 | jcbowman | 2008-07-05 14:11:53 -0600 (Sat, 05 Jul 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/Makefile.in
+
+Port version changes to msdos.
+
+------------------------------------------------------------------------
+r3234 | jcbowman | 2008-07-05 13:47:51 -0600 (Sat, 05 Jul 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/Makefile.in
+
+More version fixes.
+
+------------------------------------------------------------------------
+r3233 | jcbowman | 2008-07-05 13:32:18 -0600 (Sat, 05 Jul 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/Makefile.in
+
+Fix version.texi; cleanup temporary files.
+
+------------------------------------------------------------------------
+r3232 | jcbowman | 2008-07-05 12:54:47 -0600 (Sat, 05 Jul 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/Makefile.in
+
+Add prc dependency.
+
+------------------------------------------------------------------------
+r3231 | jcbowman | 2008-07-05 12:52:54 -0600 (Sat, 05 Jul 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/Makefile.in
+
+Create empty svnrevision.cc by default to force update.
+
+------------------------------------------------------------------------
+r3230 | jcbowman | 2008-07-05 12:42:22 -0600 (Sat, 05 Jul 2008) | 3 lines
+Changed paths:
+ M /trunk/asymptote/Makefile.in
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/patches/README
+ D /trunk/asymptote/patches/triangle.patch
+ M /trunk/asymptote/runtime.in
+
+Remove support for external triangle.shar.gz package now that Delaunay.cc
+is fixed.
+
+------------------------------------------------------------------------
+r3229 | jcbowman | 2008-07-05 12:26:50 -0600 (Sat, 05 Jul 2008) | 2 lines
+Changed paths:
+ D /trunk/asymptote/GUI/xasyVersion.py.in
+ M /trunk/asymptote/Makefile.in
+ D /trunk/asymptote/base/version.asy.in
+ M /trunk/asymptote/configure.ac
+ D /trunk/asymptote/doc/version.texi.in
+ M /trunk/asymptote/process.cc
+ M /trunk/asymptote/psfile.cc
+ M /trunk/asymptote/runtime.in
+ M /trunk/asymptote/settings.cc
+ M /trunk/asymptote/settings.h
+
+Include svn revision in version strings.
+
+------------------------------------------------------------------------
+r3228 | jcbowman | 2008-07-05 11:08:28 -0600 (Sat, 05 Jul 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/Delaunay.cc
+
+Fix supertriangle computation.
+
+------------------------------------------------------------------------
+r3227 | jcbowman | 2008-07-05 01:32:21 -0600 (Sat, 05 Jul 2008) | 4 lines
+Changed paths:
+ A /trunk/asymptote/base/bezulate.asy
+ M /trunk/asymptote/base/surface.asy
+ M /trunk/asymptote/base/three.asy
+ A /trunk/asymptote/examples/label3.asy
+
+Add bezier triangulation routines (developed by Orest Shardt).
+
+Add support for filled fonts.
+
+------------------------------------------------------------------------
+r3226 | jcbowman | 2008-07-05 00:37:42 -0600 (Sat, 05 Jul 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/surface.asy
+
+Fix surface constructor to handle all four intersection cases.
+
+------------------------------------------------------------------------
+r3225 | jcbowman | 2008-07-04 15:35:03 -0600 (Fri, 04 Jul 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/surface.asy
+ M /trunk/asymptote/doc/asymptote.texi
+
+Generalize planar surface constructor to handle a single interior intersection.
+
+------------------------------------------------------------------------
+r3224 | jcbowman | 2008-07-04 11:29:01 -0600 (Fri, 04 Jul 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/surface.asy
+ M /trunk/asymptote/path.cc
+
+Fix check in windingnumber for points on path.
+
+------------------------------------------------------------------------
+r3223 | oshardt | 2008-07-04 09:56:19 -0600 (Fri, 04 Jul 2008) | 1 line
+Changed paths:
+ M /trunk/asymptote/prc/oPRCFile.cc
+
+Fix parameterization interval of PRCline.
+------------------------------------------------------------------------
+r3222 | jcbowman | 2008-07-04 01:09:09 -0600 (Fri, 04 Jul 2008) | 3 lines
+Changed paths:
+ M /trunk/asymptote/base/surface.asy
+
+Add constructor for a (possibly) nonconvex cyclic path that returns an array of
+surfaces.
+
+------------------------------------------------------------------------
+r3221 | jcbowman | 2008-07-03 23:55:01 -0600 (Thu, 03 Jul 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/plain_picture.asy
+
+Suppress output by size when picture is empty.
+
+------------------------------------------------------------------------
+r3220 | jcbowman | 2008-07-03 23:25:31 -0600 (Thu, 03 Jul 2008) | 7 lines
+Changed paths:
+ M /trunk/asymptote/base/plain_constants.asy
+ M /trunk/asymptote/base/plain_paths.asy
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/path.cc
+
+Check for coincident subpaths in path.cc to avoid infinite loops.
+
+Define restricted int undefined to the the largest odd integer (returned by
+windingnumber for points on the path).
+
+Update documentation.
+
+------------------------------------------------------------------------
+r3219 | jcbowman | 2008-07-03 15:46:32 -0600 (Thu, 03 Jul 2008) | 4 lines
+Changed paths:
+ M /trunk/asymptote/path.cc
+
+Make windingnumber(g,z) return the largest odd integer when z lies on path g.
+
+Make inside return true for points on the boundary.
+
+------------------------------------------------------------------------
+r3218 | jcbowman | 2008-07-02 15:03:55 -0600 (Wed, 02 Jul 2008) | 3 lines
+Changed paths:
+ M /trunk/asymptote/path.cc
+
+Revert to original version of cubicroots to handle the case where one of the
+first two roots is near zero.
+
+------------------------------------------------------------------------
+r3217 | jcbowman | 2008-07-02 12:57:21 -0600 (Wed, 02 Jul 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/examples/advection.asy
+
+Update example.
+
+------------------------------------------------------------------------
+r3216 | jcbowman | 2008-07-01 22:29:10 -0600 (Tue, 01 Jul 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.sty
+
+Minor simplification.
+
+------------------------------------------------------------------------
+r3215 | jcbowman | 2008-07-01 20:27:06 -0600 (Tue, 01 Jul 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.sty
+
+Fix AsyPDF flag.
+
+------------------------------------------------------------------------
+r3214 | jcbowman | 2008-07-01 20:11:33 -0600 (Tue, 01 Jul 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/latexusage.tex
+ M /trunk/asymptote/drawclipbegin.h
+ M /trunk/asymptote/drawclipend.h
+ M /trunk/asymptote/settings.cc
+ M /trunk/asymptote/settings.h
+ M /trunk/asymptote/texfile.cc
+ M /trunk/asymptote/texfile.h
+
+Support clipping with tex and pdftex TeX engines again (broken since r2785).
+
+------------------------------------------------------------------------
+r3213 | jcbowman | 2008-07-01 20:08:52 -0600 (Tue, 01 Jul 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.sty
+
+Support xelatex.
+
+------------------------------------------------------------------------
+r3212 | jcbowman | 2008-07-01 00:19:54 -0600 (Tue, 01 Jul 2008) | 3 lines
+Changed paths:
+ M /trunk/asymptote/doc/FAQ/asy-faq.bfnn
+ M /trunk/asymptote/path.cc
+ M /trunk/asymptote/runtime.in
+
+Leave cubic root refinement to the user, to avoid potential root
+interchange problems.
+
+------------------------------------------------------------------------
+r3211 | jcbowman | 2008-06-30 22:27:13 -0600 (Mon, 30 Jun 2008) | 3 lines
+Changed paths:
+ M /trunk/asymptote/Delaunay.cc
+ M /trunk/asymptote/path.cc
+ M /trunk/asymptote/path.h
+ M /trunk/asymptote/predicates.cc
+ M /trunk/asymptote/predicates.h
+ M /trunk/asymptote/runtime.in
+
+Implement robust inside algorithm based on conditional subdivision and
+robust orient2d predicate.
+
+------------------------------------------------------------------------
+r3210 | jcbowman | 2008-06-30 17:51:39 -0600 (Mon, 30 Jun 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.sty
+ M /trunk/asymptote/doc/latexusage.tex
+
+Add option to force PDF output.
+
+------------------------------------------------------------------------
+r3209 | jcbowman | 2008-06-30 08:51:03 -0600 (Mon, 30 Jun 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/runtime.in
+
+Add side and incircle functions.
+
+------------------------------------------------------------------------
+r3208 | jcbowman | 2008-06-29 17:57:25 -0600 (Sun, 29 Jun 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/Delaunay.cc
+
+Minor optimizations.
+
+------------------------------------------------------------------------
+r3207 | jcbowman | 2008-06-29 16:33:57 -0600 (Sun, 29 Jun 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/Delaunay.cc
+
+Correct typo.
+
+------------------------------------------------------------------------
+r3206 | jcbowman | 2008-06-29 16:30:53 -0600 (Sun, 29 Jun 2008) | 4 lines
+Changed paths:
+ M /trunk/asymptote/Delaunay.cc
+ M /trunk/asymptote/Delaunay.h
+ M /trunk/asymptote/configure.ac
+ M /trunk/asymptote/doc/asymptote.texi
+ A /trunk/asymptote/predicates.cc
+ A /trunk/asymptote/predicates.h
+ A /trunk/asymptote/rounding.h
+ M /trunk/asymptote/runtime.in
+
+Fix segmentation fault in default Delaunay triangulation routine.
+
+Use Shewcuk's exact predicates in Delaunay triangulation.
+
+------------------------------------------------------------------------
+r3205 | jcbowman | 2008-06-28 23:16:00 -0600 (Sat, 28 Jun 2008) | 3 lines
+Changed paths:
+ M /trunk/asymptote/Delaunay.cc
+ M /trunk/asymptote/doc/triangulate.asy
+ M /trunk/asymptote/runtime.in
+
+Fix incorrect array size documentation of Delaunay.cc that can lead to a
+segmentation fault.
+
+------------------------------------------------------------------------
+r3204 | jcbowman | 2008-06-26 00:01:50 -0600 (Thu, 26 Jun 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/runtime.in
+ M /trunk/asymptote/tests/arith/roots.asy
+
+Minor optimization.
+
+------------------------------------------------------------------------
+r3203 | jcbowman | 2008-06-25 23:19:25 -0600 (Wed, 25 Jun 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/path.cc
+
+Try to refine calculated cubic roots with Newton-Raphson iteration.
+
+------------------------------------------------------------------------
+r3202 | jcbowman | 2008-06-25 22:40:12 -0600 (Wed, 25 Jun 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/path.cc
+
+Simplify cubicroots.
+
+------------------------------------------------------------------------
+r3201 | jcbowman | 2008-06-25 17:00:22 -0600 (Wed, 25 Jun 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/solids.asy
+ M /trunk/asymptote/bbox.h
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/path.cc
+ M /trunk/asymptote/path.h
+ M /trunk/asymptote/runtime.in
+
+Replace ytimes by real[] mintimes(path) and real[] maxtimes(path).
+
+------------------------------------------------------------------------
+r3200 | jcbowman | 2008-06-25 16:24:22 -0600 (Wed, 25 Jun 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/solids.asy
+
+Generalize last fix to an arbitrary axis.
+
+------------------------------------------------------------------------
+r3199 | jcbowman | 2008-06-25 15:04:03 -0600 (Wed, 25 Jun 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/solids.asy
+
+Handle degenerate cases.
+
+------------------------------------------------------------------------
+r3198 | jcbowman | 2008-06-25 00:38:12 -0600 (Wed, 25 Jun 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/path.cc
+
+Increase fuzz.
+
+------------------------------------------------------------------------
+r3197 | jcbowman | 2008-06-25 00:27:11 -0600 (Wed, 25 Jun 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/path.cc
+
+Fix numerical resolution problem in windingnumber.
+
+------------------------------------------------------------------------
+r3196 | jcbowman | 2008-06-24 23:45:50 -0600 (Tue, 24 Jun 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/path.cc
+
+Fix relative vs. absolute fuzz.
+
+------------------------------------------------------------------------
+r3195 | jcbowman | 2008-06-24 23:03:37 -0600 (Tue, 24 Jun 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/path.cc
+
+Adjust fuzz to fix remaining resolutions problems in windingnumber.
+
+------------------------------------------------------------------------
+r3194 | jcbowman | 2008-06-24 22:36:22 -0600 (Tue, 24 Jun 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/runtime.in
+
+Reinstate deleted function.
+
+------------------------------------------------------------------------
+r3193 | jcbowman | 2008-06-24 22:31:12 -0600 (Tue, 24 Jun 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/runtime.in
+
+Remove dir(path,real,int) since it is only needed internally.
+
+------------------------------------------------------------------------
+r3192 | jcbowman | 2008-06-24 22:20:09 -0600 (Tue, 24 Jun 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/path.cc
+
+Reinstate old inside function.
+
+------------------------------------------------------------------------
+r3191 | jcbowman | 2008-06-24 17:53:38 -0600 (Tue, 24 Jun 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/path.cc
+
+Use lineintersections routine to implement inside.
+
+------------------------------------------------------------------------
+r3190 | jcbowman | 2008-06-24 10:35:12 -0600 (Tue, 24 Jun 2008) | 4 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/path.cc
+ M /trunk/asymptote/path.h
+ M /trunk/asymptote/runtime.in
+
+Fix windingnumber by using robust predir and postdir functions.
+
+Expose dir(path,real,int).
+
+------------------------------------------------------------------------
+r3189 | jcbowman | 2008-06-23 23:42:18 -0600 (Mon, 23 Jun 2008) | 3 lines
+Changed paths:
+ M /trunk/asymptote/base/plain_paths.asy
+ M /trunk/asymptote/base/solids.asy
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/path.cc
+ M /trunk/asymptote/path.h
+ M /trunk/asymptote/runtime.in
+
+Add real[] ytimes(path g) function to return times at which path g reaches its
+minimum and maximum y extents.
+
+------------------------------------------------------------------------
+r3188 | jcbowman | 2008-06-23 22:40:14 -0600 (Mon, 23 Jun 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/path.cc
+ M /trunk/asymptote/path.h
+
+Consolidate bounding box code.
+
+------------------------------------------------------------------------
+r3187 | oshardt | 2008-06-23 18:04:57 -0600 (Mon, 23 Jun 2008) | 1 line
+Changed paths:
+ M /trunk/asymptote/prc/PRC.h
+ M /trunk/asymptote/prc/PRCTools/describePRC.cc
+ M /trunk/asymptote/prc/PRCTools/iPRCFile.cc
+
+Correct handling of uncompressed files. Add enums to PRC.h
+------------------------------------------------------------------------
+r3186 | jcbowman | 2008-06-23 17:48:23 -0600 (Mon, 23 Jun 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/path.cc
+ M /trunk/asymptote/path.h
+ M /trunk/asymptote/runtime.in
+
+Increase minimal fuzz in intersections.
+
+------------------------------------------------------------------------
+r3185 | jcbowman | 2008-06-23 15:03:49 -0600 (Mon, 23 Jun 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/path.cc
+
+Increase fuzz to improve detection of roots at numerical infinity.
+
+------------------------------------------------------------------------
+r3184 | jcbowman | 2008-06-23 11:18:40 -0600 (Mon, 23 Jun 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/runtime.in
+
+User -dSAFER also for deconstruction into png format.
+
+------------------------------------------------------------------------
+r3183 | jcbowman | 2008-06-23 11:00:40 -0600 (Mon, 23 Jun 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/common.h
+ M /trunk/asymptote/memory.h
+ M /trunk/asymptote/picture.cc
+ M /trunk/asymptote/runtime.in
+
+By default run gs with -dSAFER.
+
+------------------------------------------------------------------------
+r3182 | jcbowman | 2008-06-23 00:41:43 -0600 (Mon, 23 Jun 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/FAQ/asy-faq.bfnn
+ M /trunk/asymptote/doc/asymptote.texi
+
+Fix typo.
+
+------------------------------------------------------------------------
+r3181 | jcbowman | 2008-06-23 00:31:13 -0600 (Mon, 23 Jun 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/FAQ/asy-faq.bfnn
+
+Update link.
+
+------------------------------------------------------------------------
+r3180 | jcbowman | 2008-06-22 23:26:30 -0600 (Sun, 22 Jun 2008) | 8 lines
+Changed paths:
+ M /trunk/asymptote/base/graph3.asy
+ M /trunk/asymptote/base/plain_arcs.asy
+ M /trunk/asymptote/base/plain_boxes.asy
+ M /trunk/asymptote/base/plain_paths.asy
+ M /trunk/asymptote/base/solids.asy
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/path.cc
+ M /trunk/asymptote/path.h
+ M /trunk/asymptote/runtime.in
+ M /trunk/asymptote/triple.h
+
+Merge C++ intersect and intersection routines.
+
+Optimize intersection routines for paths containing straight segments.
+
+Add function real[] intersections(path p, pair a, pair b, real fuzz=0)
+to return all intersection times of path p with the (infinite) line
+through points a and b.
+
+------------------------------------------------------------------------
+r3179 | jcbowman | 2008-06-21 19:24:45 -0600 (Sat, 21 Jun 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/process.cc
+
+Fix -listvariables.
+
+------------------------------------------------------------------------
+r3178 | jcbowman | 2008-06-21 14:46:23 -0600 (Sat, 21 Jun 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/graph3.asy
+ M /trunk/asymptote/base/math.asy
+ M /trunk/asymptote/base/plain_arcs.asy
+ M /trunk/asymptote/base/plain_boxes.asy
+ M /trunk/asymptote/base/plain_paths.asy
+ M /trunk/asymptote/base/solids.asy
+ M /trunk/asymptote/base/three.asy
+
+Use new intersection routines; handle degenerate cases.
+
+------------------------------------------------------------------------
+r3177 | jcbowman | 2008-06-21 14:36:53 -0600 (Sat, 21 Jun 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/builtin.cc
+ M /trunk/asymptote/process.h
+ M /trunk/asymptote/runtime.in
+
+Use a process-specific currentpen.
+
+------------------------------------------------------------------------
+r3176 | jcbowman | 2008-06-21 12:24:39 -0600 (Sat, 21 Jun 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/examples/Gouraudcontour.asy
+
+Update example.
+
+------------------------------------------------------------------------
+r3175 | jcbowman | 2008-06-20 22:49:58 -0600 (Fri, 20 Jun 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/three.asy
+
+Fix roll parameter.
+
+------------------------------------------------------------------------
+r3174 | jcbowman | 2008-06-20 19:34:56 -0600 (Fri, 20 Jun 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/plain_paths.asy
+
+Rename intersectionsline to lineintersections.
+
+------------------------------------------------------------------------
+r3173 | jcbowman | 2008-06-20 16:56:05 -0600 (Fri, 20 Jun 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/plain_paths.asy
+
+Fix and standardize new intersection routines.
+
+------------------------------------------------------------------------
+r3172 | jcbowman | 2008-06-20 16:12:09 -0600 (Fri, 20 Jun 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/plain_paths.asy
+
+Improve intersection routines.
+
+------------------------------------------------------------------------
+r3171 | jcbowman | 2008-06-20 12:04:45 -0600 (Fri, 20 Jun 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/solids.asy
+
+Fix front/back detection when rotating about a point.
+
+------------------------------------------------------------------------
+r3170 | jcbowman | 2008-06-20 10:41:31 -0600 (Fri, 20 Jun 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/plain_paths.asy
+ M /trunk/asymptote/base/stats.asy
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/doc/multicontour.asy
+ M /trunk/asymptote/examples/delu.asy
+ M /trunk/asymptote/runtime.in
+
+Move unitrand to C++ code to avoid dependency on stats.asy.
+
+------------------------------------------------------------------------
+r3169 | jcbowman | 2008-06-20 10:23:21 -0600 (Fri, 20 Jun 2008) | 3 lines
+Changed paths:
+ M /trunk/asymptote/base/plain_paths.asy
+
+Implement improved version of intersections(point, pair p, pair q)
+that returns all intersection times with the (infinite) line through p and q.
+
+------------------------------------------------------------------------
+r3168 | jcbowman | 2008-06-20 01:44:26 -0600 (Fri, 20 Jun 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/asymptote.spec
+ M /trunk/asymptote/base/plain_paths.asy
+
+Add routine to compute the intersection times of a path and a line segment.
+
+------------------------------------------------------------------------
+r3167 | jcbowman | 2008-06-20 00:38:55 -0600 (Fri, 20 Jun 2008) | 5 lines
+Changed paths:
+ M /trunk/asymptote/base/animation.asy
+ M /trunk/asymptote/base/embed.asy
+ A /trunk/asymptote/base/embedding.asy
+ M /trunk/asymptote/base/external.asy
+ M /trunk/asymptote/base/plain.asy
+ M /trunk/asymptote/base/syzygy.asy
+ M /trunk/asymptote/base/three.asy
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/examples/BezierSurface.asy
+ M /trunk/asymptote/examples/label3ribbon.asy
+ M /trunk/asymptote/examples/teapot.asy
+ M /trunk/asymptote/process.h
+ M /trunk/asymptote/runtime.in
+
+Distinguish between updatefunction (used for interactive mode) and
+exitfunction (used to clean up intermediate files).
+
+Don't force settings.outformat="pdf" in three.asy.
+
+------------------------------------------------------------------------
+r3166 | jcbowman | 2008-06-20 00:07:38 -0600 (Fri, 20 Jun 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/three.asy
+
+Simplify nodes(int).
+
+------------------------------------------------------------------------
+r3165 | jcbowman | 2008-06-19 23:42:32 -0600 (Thu, 19 Jun 2008) | 6 lines
+Changed paths:
+ M /trunk/asymptote/base/surface.asy
+ M /trunk/asymptote/base/three.asy
+ A /trunk/asymptote/examples/label3ribbon.asy
+
+Change path3 lift(path) to a constructor.
+
+Add constructors to surface.asy.
+
+Add example of 3D extruded label contributed by Philippe Ivaldi.
+
+------------------------------------------------------------------------
+r3164 | jcbowman | 2008-06-19 22:38:42 -0600 (Thu, 19 Jun 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/prc/oPRCFile.cc
+
+Remove granularity for improved rendering.
+
+------------------------------------------------------------------------
+r3163 | jcbowman | 2008-06-19 15:43:45 -0600 (Thu, 19 Jun 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/logo.asy
+
+Replace axis call by explicit draw commands.
+
+------------------------------------------------------------------------
+r3162 | oshardt | 2008-06-19 15:04:04 -0600 (Thu, 19 Jun 2008) | 1 line
+Changed paths:
+ M /trunk/asymptote/prc/PRCbitStream.cc
+ M /trunk/asymptote/prc/PRCbitStream.h
+ M /trunk/asymptote/prc/oPRCFile.cc
+ M /trunk/asymptote/prc/writePRC.cc
+
+Fix PRCbitStream::getSize().
+------------------------------------------------------------------------
+r3161 | oshardt | 2008-06-19 14:33:11 -0600 (Thu, 19 Jun 2008) | 1 line
+Changed paths:
+ M /trunk/asymptote/prc/PRCTools/inflation.cc
+
+Fix decompress().
+------------------------------------------------------------------------
+r3160 | jcbowman | 2008-06-19 00:24:51 -0600 (Thu, 19 Jun 2008) | 4 lines
+Changed paths:
+ M /trunk/asymptote/base/three.asy
+
+Fix prc file count issue.
+
+Add preliminary support for 3d fonts.
+
+------------------------------------------------------------------------
+r3159 | jcbowman | 2008-06-18 22:31:55 -0600 (Wed, 18 Jun 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/three.asy
+ M /trunk/asymptote/examples/BezierSurface.asy
+ M /trunk/asymptote/examples/teapot.asy
+
+Fix projection units.
+
+------------------------------------------------------------------------
+r3158 | jcbowman | 2008-06-18 22:12:40 -0600 (Wed, 18 Jun 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/plain_Label.asy
+ M /trunk/asymptote/base/plain_pens.asy
+ M /trunk/asymptote/base/plain_picture.asy
+ M /trunk/asymptote/runtime.in
+
+Add texpath support for alignment and transforms.
+
+------------------------------------------------------------------------
+r3157 | jcbowman | 2008-06-18 22:10:43 -0600 (Wed, 18 Jun 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/process.cc
+
+Simplify reset.
+
+------------------------------------------------------------------------
+r3156 | oshardt | 2008-06-18 21:00:40 -0600 (Wed, 18 Jun 2008) | 1 line
+Changed paths:
+ M /trunk/asymptote/examples/teapot.asy
+
+Fix teapot example
+------------------------------------------------------------------------
+r3155 | jcbowman | 2008-06-18 15:17:02 -0600 (Wed, 18 Jun 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/runtime.in
+
+Avoid opening up an X11 window in texpath; use epswrite device instead.
+
+------------------------------------------------------------------------
+r3154 | jcbowman | 2008-06-18 14:56:22 -0600 (Wed, 18 Jun 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/runtime.in
+
+Add erase(frame) function.
+
+------------------------------------------------------------------------
+r3153 | jcbowman | 2008-06-18 13:02:13 -0600 (Wed, 18 Jun 2008) | 4 lines
+Changed paths:
+ M /trunk/asymptote/runtime.in
+ M /trunk/asymptote/texfile.cc
+ M /trunk/asymptote/texfile.h
+
+Make texpath work also with sqrt, fractions, and arrows.
+
+Add pen argument to texpath.
+
+------------------------------------------------------------------------
+r3152 | oshardt | 2008-06-18 12:51:32 -0600 (Wed, 18 Jun 2008) | 1 line
+Changed paths:
+ M /trunk/asymptote/base/three.asy
+ M /trunk/asymptote/examples/teapot.asy
+
+Use cm as units of camera properties.
+------------------------------------------------------------------------
+r3151 | oshardt | 2008-06-18 11:05:14 -0600 (Wed, 18 Jun 2008) | 1 line
+Changed paths:
+ M /trunk/asymptote/prc/oPRCFile.cc
+ M /trunk/asymptote/prc/writePRC.cc
+
+In PRC, always write at least 1 bit of user data.
+------------------------------------------------------------------------
+r3150 | jcbowman | 2008-06-18 10:20:19 -0600 (Wed, 18 Jun 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/graphmarkers.asy
+
+Fix formatting.
+
+------------------------------------------------------------------------
+r3149 | jcbowman | 2008-06-18 10:18:11 -0600 (Wed, 18 Jun 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+ A /trunk/asymptote/doc/graphmarkers.asy
+
+Add example of custom mark routine.
+
+------------------------------------------------------------------------
+r3148 | jcbowman | 2008-06-18 09:45:35 -0600 (Wed, 18 Jun 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/runtime.in
+
+Move default currentpen argument to C++ code.
+
+------------------------------------------------------------------------
+r3147 | jcbowman | 2008-06-17 22:45:59 -0600 (Tue, 17 Jun 2008) | 3 lines
+Changed paths:
+ M /trunk/asymptote/base/plain_filldraw.asy
+ M /trunk/asymptote/base/plain_picture.asy
+ M /trunk/asymptote/builtin.cc
+ M /trunk/asymptote/builtin.h
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/drawclipbegin.h
+ M /trunk/asymptote/drawelement.h
+ M /trunk/asymptote/drawfill.cc
+ M /trunk/asymptote/drawfill.h
+ M /trunk/asymptote/drawpath.cc
+ M /trunk/asymptote/drawpath.h
+ A /trunk/asymptote/examples/shadestroke.asy
+ M /trunk/asymptote/psfile.h
+ M /trunk/asymptote/runtime.in
+
+Add boolean stroke parameter to shading (and clipping) routines to shading of
+(and clipping to) stroked paths.
+
+------------------------------------------------------------------------
+r3146 | jcbowman | 2008-06-17 22:08:40 -0600 (Tue, 17 Jun 2008) | 3 lines
+Changed paths:
+ M /trunk/asymptote/base/three.asy
+ M /trunk/asymptote/examples/BezierSurface.asy
+
+Add routine projection perspective(string s) routine to extract current camera
+parameters from cameralink (Viewpoint).
+
+------------------------------------------------------------------------
+r3145 | oshardt | 2008-06-17 13:02:33 -0600 (Tue, 17 Jun 2008) | 1 line
+Changed paths:
+ M /trunk/asymptote/examples/teapot.asy
+
+Resize and give the teapot a bottom.
+------------------------------------------------------------------------
+r3144 | oshardt | 2008-06-17 12:09:30 -0600 (Tue, 17 Jun 2008) | 1 line
+Changed paths:
+ M /trunk/asymptote/GUI/xasyCodeEditor.py
+ M /trunk/asymptote/GUI/xasyMainWin.py
+ M /trunk/asymptote/GUI/xasyOptions.py
+ M /trunk/asymptote/GUI/xasyOptionsDialog.py
+
+Use external editor to edit code.
+------------------------------------------------------------------------
+r3143 | oshardt | 2008-06-16 17:21:07 -0600 (Mon, 16 Jun 2008) | 1 line
+Changed paths:
+ A /trunk/asymptote/prc/PRCTools/makePRC.cc
+
+Remove unnecessary casts.
+------------------------------------------------------------------------
+r3142 | oshardt | 2008-06-16 17:19:44 -0600 (Mon, 16 Jun 2008) | 1 line
+Changed paths:
+ M /trunk/asymptote/prc/PRCTools/Makefile
+ M /trunk/asymptote/prc/oPRCFile.cc
+ M /trunk/asymptote/prc/writePRC.h
+
+Remove unnecessary casts.
+------------------------------------------------------------------------
+r3141 | jcbowman | 2008-06-16 13:29:25 -0600 (Mon, 16 Jun 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/runtime.in
+ M /trunk/asymptote/texfile.cc
+ M /trunk/asymptote/texfile.h
+
+Fix and simplify texpath.
+
+------------------------------------------------------------------------
+r3140 | jcbowman | 2008-06-16 11:11:55 -0600 (Mon, 16 Jun 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/three.asy
+
+Use C locale for formatting embed arguments.
+
+------------------------------------------------------------------------
+r3139 | jcbowman | 2008-06-16 11:08:31 -0600 (Mon, 16 Jun 2008) | 3 lines
+Changed paths:
+ M /trunk/asymptote/picture.cc
+ M /trunk/asymptote/picture.h
+ M /trunk/asymptote/runtime.in
+ M /trunk/asymptote/types.cc
+ M /trunk/asymptote/types.h
+
+Add path[][] texpath(string s) routine to convert string into the paths
+that TeX would fill.
+
+------------------------------------------------------------------------
+r3138 | jcbowman | 2008-06-16 11:06:41 -0600 (Mon, 16 Jun 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/examples/BezierSurface.asy
+
+Add camera view link.
+
+------------------------------------------------------------------------
+r3137 | jcbowman | 2008-06-16 01:12:34 -0600 (Mon, 16 Jun 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/drawlabel.cc
+
+Implement better fix for basealign bounding box bug.
+
+------------------------------------------------------------------------
+r3136 | jcbowman | 2008-06-15 17:08:11 -0600 (Sun, 15 Jun 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/drawlabel.cc
+
+Fix bounding box with basealign pen.
+
+------------------------------------------------------------------------
+r3135 | jcbowman | 2008-06-15 10:32:44 -0600 (Sun, 15 Jun 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/three.asy
+
+Use static constant.
+
+------------------------------------------------------------------------
+r3134 | jcbowman | 2008-06-15 10:30:17 -0600 (Sun, 15 Jun 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/three.asy
+
+For orthographic/oblique projections, move camera further from origin.
+
+------------------------------------------------------------------------
+r3133 | jcbowman | 2008-06-14 10:12:59 -0600 (Sat, 14 Jun 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/picture.cc
+
+Minor diagnostic improvements.
+
+------------------------------------------------------------------------
+r3132 | jcbowman | 2008-06-14 10:04:27 -0600 (Sat, 14 Jun 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/slide.asy
+ M /trunk/asymptote/base/three.asy
+
+Avoid dereferencing null function.
+
+------------------------------------------------------------------------
+r3131 | jcbowman | 2008-06-14 09:34:00 -0600 (Sat, 14 Jun 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/three.asy
+
+Fix bug in face routines for orthographic and oblique projections.
+
+------------------------------------------------------------------------
+r3130 | oshardt | 2008-06-13 17:54:42 -0600 (Fri, 13 Jun 2008) | 1 line
+Changed paths:
+ M /trunk/asymptote/examples/teapot.asy
+ M /trunk/asymptote/prc/oPRCFile.cc
+ M /trunk/asymptote/prc/oPRCFile.h
+
+Fix IDs in PRC files.
+------------------------------------------------------------------------
+r3129 | jcbowman | 2008-06-13 16:12:17 -0600 (Fri, 13 Jun 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/three.asy
+
+Get PRC initial camera settings from projection.
+
+------------------------------------------------------------------------
+r3128 | jcbowman | 2008-06-13 08:15:38 -0600 (Fri, 13 Jun 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/slide.asy
+ M /trunk/asymptote/base/three.asy
+
+Clean up temporary files.
+
+------------------------------------------------------------------------
+r3127 | hammera | 2008-06-13 00:16:39 -0600 (Fri, 13 Jun 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/tests/types/shadow.asy
+
+Added semicolons.
+
+------------------------------------------------------------------------
+r3126 | hammera | 2008-06-12 22:56:47 -0600 (Thu, 12 Jun 2008) | 2 lines
+Changed paths:
+ A /trunk/asymptote/tests/types/shadow.asy
+
+Test access of shadowed variables by higher-order functions.
+
+------------------------------------------------------------------------
+r3125 | jcbowman | 2008-06-12 22:53:27 -0600 (Thu, 12 Jun 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/Makefile.in
+ M /trunk/asymptote/array.h
+ M /trunk/asymptote/arrayop.h
+ M /trunk/asymptote/base/plain_shipout.asy
+ M /trunk/asymptote/base/surface.asy
+ M /trunk/asymptote/base/three.asy
+ M /trunk/asymptote/builtin.cc
+ M /trunk/asymptote/configure.ac
+ M /trunk/asymptote/drawelement.h
+ A /trunk/asymptote/drawpath3.cc
+ A /trunk/asymptote/drawpath3.h
+ A /trunk/asymptote/drawsurface.cc
+ A /trunk/asymptote/drawsurface.h
+ M /trunk/asymptote/examples/BezierSurface.asy
+ M /trunk/asymptote/mathop.h
+ M /trunk/asymptote/pen.h
+ M /trunk/asymptote/picture.cc
+ M /trunk/asymptote/picture.h
+ A /trunk/asymptote/prcfile.h
+ M /trunk/asymptote/runtime.in
+ M /trunk/asymptote/settings.cc
+ M /trunk/asymptote/settings.h
+
+Add support for basic PRC operations (drawpath3 and drawsurface).
+
+------------------------------------------------------------------------
+r3124 | jcbowman | 2008-06-12 22:50:22 -0600 (Thu, 12 Jun 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/picture.cc
+
+Wait for pdfviewer to exit before restarting it.
+
+------------------------------------------------------------------------
+r3123 | oshardt | 2008-06-12 21:01:36 -0600 (Thu, 12 Jun 2008) | 1 line
+Changed paths:
+ A /trunk/asymptote/prc
+ A /trunk/asymptote/prc/Makefile
+ A /trunk/asymptote/prc/PRC.h
+ A /trunk/asymptote/prc/PRCTools
+ A /trunk/asymptote/prc/PRCTools/Makefile
+ A /trunk/asymptote/prc/PRCTools/bitData.cc
+ A /trunk/asymptote/prc/PRCTools/bitData.h
+ A /trunk/asymptote/prc/PRCTools/bitSearchDouble.cc
+ A /trunk/asymptote/prc/PRCTools/bitSearchUI.cc
+ A /trunk/asymptote/prc/PRCTools/describeMain.cc
+ A /trunk/asymptote/prc/PRCTools/describePRC.cc
+ A /trunk/asymptote/prc/PRCTools/describePRC.h
+ A /trunk/asymptote/prc/PRCTools/extractSections.cc
+ A /trunk/asymptote/prc/PRCTools/iPRCFile.cc
+ A /trunk/asymptote/prc/PRCTools/iPRCFile.h
+ A /trunk/asymptote/prc/PRCTools/inflation.cc
+ A /trunk/asymptote/prc/PRCTools/inflation.h
+ A /trunk/asymptote/prc/PRCTools/inflationMain.cc
+ A /trunk/asymptote/prc/PRCbitStream.cc
+ A /trunk/asymptote/prc/PRCbitStream.h
+ A /trunk/asymptote/prc/PRCdouble.cc
+ A /trunk/asymptote/prc/PRCdouble.h
+ A /trunk/asymptote/prc/oPRCFile.cc
+ A /trunk/asymptote/prc/oPRCFile.h
+ A /trunk/asymptote/prc/test.cc
+ A /trunk/asymptote/prc/writePRC.cc
+ A /trunk/asymptote/prc/writePRC.h
+
+Import code that implements support for saving 3D content to PRC files.
+------------------------------------------------------------------------
+r3122 | jcbowman | 2008-06-12 18:10:31 -0600 (Thu, 12 Jun 2008) | 3 lines
+Changed paths:
+ M /trunk/asymptote/picture.cc
+
+Since Adobe Acrobat doesn't yet have a file-watching capability,
+kill a running pdfviewer so that a file can be redrawn in interactive mode.
+
+------------------------------------------------------------------------
+r3121 | jcbowman | 2008-06-12 10:00:47 -0600 (Thu, 12 Jun 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.sty
+
+Make asymptote.sty work with the hebrew babel package.
+
+------------------------------------------------------------------------
+r3120 | jcbowman | 2008-06-12 09:16:07 -0600 (Thu, 12 Jun 2008) | 2 lines
+Changed paths:
+ A /trunk/asymptote/examples/logdown.asy
+
+Add example of downward-pointing logarithmic axis.
+
+------------------------------------------------------------------------
+r3119 | jcbowman | 2008-06-12 03:23:19 -0600 (Thu, 12 Jun 2008) | 1 line
+Changed paths:
+ M /trunk/asymptote/configure.ac
+
+Increment version to 1.44svn.
+------------------------------------------------------------------------
+r3118 | jcbowman | 2008-06-12 01:26:49 -0600 (Thu, 12 Jun 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/settings.cc
+
+Use international inch also in C++ code.
+
+------------------------------------------------------------------------
+r3117 | jcbowman | 2008-06-12 00:54:14 -0600 (Thu, 12 Jun 2008) | 4 lines
+Changed paths:
+ M /trunk/asymptote/runtime.in
+
+Fix potential segmentation fault in store_history.
+
+Move uptodate=true back to the beginning of shipout to avoid a race condition.
+
+------------------------------------------------------------------------
+r3116 | jcbowman | 2008-06-12 00:14:14 -0600 (Thu, 12 Jun 2008) | 3 lines
+Changed paths:
+ A /trunk/asymptote/base/size10.asy
+ A /trunk/asymptote/base/size11.asy
+
+Add modules to redefine LaTeX named fontsizes to correspond to
+\documentclass[10pt]{article} and \documentclass[11pt]{article}, respectively.
+
+------------------------------------------------------------------------
+r3115 | jcbowman | 2008-06-11 15:45:16 -0600 (Wed, 11 Jun 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/plain_constants.asy
+
+Use international inch conversion factor.
+
+------------------------------------------------------------------------
+r3114 | jcbowman | 2008-06-10 08:14:59 -0600 (Tue, 10 Jun 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/three.asy
+
+Add missing path3[] operator * (transform3 t, path3[] p).
+
+------------------------------------------------------------------------
+r3113 | jcbowman | 2008-06-09 00:59:31 -0600 (Mon, 09 Jun 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/Makefile.in
+ M /trunk/asymptote/configure.ac
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/patches/README
+ A /trunk/asymptote/patches/triangle.patch
+ M /trunk/asymptote/runtime.in
+
+Add optional support for Jonathan Shewchuk's more robust triangulation routines.
+
+------------------------------------------------------------------------
+r3112 | jcbowman | 2008-06-08 22:56:41 -0600 (Sun, 08 Jun 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/contour.asy
+ M /trunk/asymptote/base/contour3.asy
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/doc/irregularcontour.asy
+
+Add interface for drawing contours on arbitrary nonoverlapping meshes.
+
+------------------------------------------------------------------------
+r3111 | jcbowman | 2008-06-07 22:36:27 -0600 (Sat, 07 Jun 2008) | 3 lines
+Changed paths:
+ M /trunk/asymptote/base/plain_picture.asy
+ M /trunk/asymptote/doc/asymptote.texi
+
+Remove transform return value from add functions in favour of user-supplied
+add routine.
+
+------------------------------------------------------------------------
+r3110 | jcbowman | 2008-06-07 10:49:54 -0600 (Sat, 07 Jun 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/plain_picture.asy
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/examples/rainbow.asy
+
+Move draw(path[], pen[]) to plain_picture.asy.
+
+------------------------------------------------------------------------
+r3109 | pivaldi | 2008-06-07 10:02:20 -0600 (Sat, 07 Jun 2008) | 1 line
+Changed paths:
+ M /trunk/asymptote/base/asy-mode.el
+
+asy-mode.el: add asy to regexp matching environments with indentation at col 0 for begin/end.
+------------------------------------------------------------------------
+r3108 | jcbowman | 2008-06-06 12:18:07 -0600 (Fri, 06 Jun 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/three.asy
+
+Remove "paths in concatenation do not meet" also from three.asy.
+
+------------------------------------------------------------------------
+r3107 | jcbowman | 2008-06-06 10:59:22 -0600 (Fri, 06 Jun 2008) | 3 lines
+Changed paths:
+ M /trunk/asymptote/base/plain_picture.asy
+ M /trunk/asymptote/doc/asymptote.texi
+
+Return the transform that maps source coordinates to destination
+coordinates in add and attach.
+
+------------------------------------------------------------------------
+r3106 | jcbowman | 2008-06-06 10:56:10 -0600 (Fri, 06 Jun 2008) | 4 lines
+Changed paths:
+ M /trunk/asymptote/array.h
+ M /trunk/asymptote/base/plain_shipout.asy
+ M /trunk/asymptote/runtime.in
+
+Move uptodate=true to runtime.
+
+Improve diagnostics about incompatible array lengths.
+
+------------------------------------------------------------------------
+r3105 | jcbowman | 2008-06-06 09:52:43 -0600 (Fri, 06 Jun 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/process.cc
+
+Make interrupts set uptodate=true to avoid spurious shipouts.
+
+------------------------------------------------------------------------
+r3104 | jcbowman | 2008-06-06 09:51:37 -0600 (Fri, 06 Jun 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/graph.asy
+
+Fix secondary axis tick selection when automin=false.
+
+------------------------------------------------------------------------
+r3103 | hammera | 2008-06-05 15:45:47 -0600 (Thu, 05 Jun 2008) | 2 lines
+Changed paths:
+ A /trunk/asymptote/doc/external-proposal.html
+
+A preliminary proposal for how to defined Asymptote modules in C++.
+
+------------------------------------------------------------------------
+r3102 | jcbowman | 2008-06-05 08:58:18 -0600 (Thu, 05 Jun 2008) | 4 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/fileio.h
+ M /trunk/asymptote/guide.h
+ M /trunk/asymptote/path.cc
+ M /trunk/asymptote/runtime.in
+
+Allow precision setting to be queried.
+
+Write paths to the specified precision setting for a file.
+
+------------------------------------------------------------------------
+r3101 | jcbowman | 2008-06-05 08:35:35 -0600 (Thu, 05 Jun 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/builtin.cc
+
+Add expm1 function.
+
+------------------------------------------------------------------------
+r3100 | jcbowman | 2008-06-05 08:34:21 -0600 (Thu, 05 Jun 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/examples/triads.asy
+
+Add labels to example.
+
+------------------------------------------------------------------------
+r3099 | jcbowman | 2008-06-04 22:28:22 -0600 (Wed, 04 Jun 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/graph.asy
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/examples/cardioid.asy
+ M /trunk/asymptote/examples/cos2theta.asy
+
+Always draw 2D axes below picture by default.
+
+------------------------------------------------------------------------
+r3098 | jcbowman | 2008-06-04 21:00:36 -0600 (Wed, 04 Jun 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/texfile.h
+
+Simplify font variable definitions.
+
+------------------------------------------------------------------------
+r3097 | jcbowman | 2008-06-04 20:34:59 -0600 (Wed, 04 Jun 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/pen.h
+ M /trunk/asymptote/texfile.h
+
+Restore to correct initial font.
+
+------------------------------------------------------------------------
+r3096 | jcbowman | 2008-06-04 14:50:26 -0600 (Wed, 04 Jun 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/memory.h
+
+Add missing # sign.
+
+------------------------------------------------------------------------
+r3095 | hammera | 2008-06-03 21:54:04 -0600 (Tue, 03 Jun 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/entry.h
+ M /trunk/asymptote/env.cc
+ M /trunk/asymptote/env.h
+ M /trunk/asymptote/exp.cc
+ M /trunk/asymptote/exp.h
+ M /trunk/asymptote/name.cc
+ M /trunk/asymptote/name.h
+
+Removed matchCache entirely.
+
+------------------------------------------------------------------------
+r3094 | jcbowman | 2008-06-03 20:14:07 -0600 (Tue, 03 Jun 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/memory.h
+
+Handle undefined __GNU_C_PREREQ macros.
+
+------------------------------------------------------------------------
+r3093 | hammera | 2008-05-31 05:55:05 -0600 (Sat, 31 May 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/exp.cc
+ A /trunk/asymptote/tests/types/resolve.asy
+
+Disabled matchCaching dur to improperly handled cases.
+
+------------------------------------------------------------------------
+r3092 | hammera | 2008-05-31 05:54:24 -0600 (Sat, 31 May 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/TODO
+
+Ideas about unicode.
+
+------------------------------------------------------------------------
+r3091 | jcbowman | 2008-05-27 00:36:08 -0600 (Tue, 27 May 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/configure.ac
+ M /trunk/asymptote/memory.h
+ M /trunk/asymptote/runtime.in
+
+Work around broken gcc-4.1.2 tr1 headers.
+
+------------------------------------------------------------------------
+r3090 | jcbowman | 2008-05-26 23:41:28 -0600 (Mon, 26 May 2008) | 1 line
+Changed paths:
+ M /trunk/asymptote/Delaunay.h
+ M /trunk/asymptote/entry.h
+ M /trunk/asymptote/genv.cc
+ M /trunk/asymptote/memory.h
+ M /trunk/asymptote/path.cc
+ M /trunk/asymptote/runtime.in
+ M /trunk/asymptote/settings.cc
+ M /trunk/asymptote/simpson.cc
+ M /trunk/asymptote/util.cc
+ M /trunk/asymptote/util.h
+
+Port to gcc-4.3.0.
+------------------------------------------------------------------------
+r3089 | jcbowman | 2008-05-26 15:09:53 -0600 (Mon, 26 May 2008) | 2 lines
+Changed paths:
+ A /trunk/asymptote/base/ode.asy
+
+Add beginnings of an ode package.
+
+------------------------------------------------------------------------
+r3088 | jcbowman | 2008-05-22 01:02:23 -0600 (Thu, 22 May 2008) | 3 lines
+Changed paths:
+ M /trunk/asymptote/base/math.asy
+
+Make partialsum return an array of the same length as its argument
+(this is a backwards incompatible change).
+
+------------------------------------------------------------------------
+r3087 | jcbowman | 2008-05-07 22:52:35 -0600 (Wed, 07 May 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/INSTALL
+ M /trunk/asymptote/asymptote.spec
+ M /trunk/asymptote/configure.ac
+ M /trunk/asymptote/doc/asymptote.texi
+
+Update to gc-7.1.
+
+------------------------------------------------------------------------
+r3086 | jcbowman | 2008-05-07 22:50:36 -0600 (Wed, 07 May 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/runtime.in
+
+Return immediately for negative sleep arguments.
+
+------------------------------------------------------------------------
+r3085 | jcbowman | 2008-05-07 22:49:52 -0600 (Wed, 07 May 2008) | 2 lines
+Changed paths:
+ D /trunk/asymptote/examples/cardiod.asy
+ A /trunk/asymptote/examples/cardioid.asy (from /trunk/asymptote/examples/cardiod.asy:3080)
+
+Fix spelling of cardioid.
+
+------------------------------------------------------------------------
+r3084 | jcbowman | 2008-05-07 22:49:21 -0600 (Wed, 07 May 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/embed.asy
+
+Update URL.
+
+------------------------------------------------------------------------
+r3083 | oshardt | 2008-04-28 17:39:58 -0600 (Mon, 28 Apr 2008) | 1 line
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+
+Update links to TeX resources.
+------------------------------------------------------------------------
+r3082 | jcbowman | 2008-03-29 17:18:30 -0600 (Sat, 29 Mar 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/generalaxis3.asy
+
+Temporary fix for tick directions.
+
+------------------------------------------------------------------------
+r3081 | jcbowman | 2008-03-29 17:17:47 -0600 (Sat, 29 Mar 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+
+Add missing index entry for array.
+
+------------------------------------------------------------------------
+r3080 | jcbowman | 2008-03-29 17:10:46 -0600 (Sat, 29 Mar 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/multicontour.asy
+ M /trunk/asymptote/examples/gamma.asy
+
+Simplfify examples.
+
+------------------------------------------------------------------------
+r3079 | jcbowman | 2008-03-29 17:08:57 -0600 (Sat, 29 Mar 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/castop.h
+
+Improve bad string cast diagnostics.
+
+------------------------------------------------------------------------
+r3078 | jcbowman | 2008-03-29 17:08:34 -0600 (Sat, 29 Mar 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/plain_arrows.asy
+
+Add drawing routines for guide[] g.
+
+------------------------------------------------------------------------
+r3077 | jcbowman | 2008-03-29 17:06:54 -0600 (Sat, 29 Mar 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/plain_paths.asy
+
+Add path[] operator cast(guide[] g) cast.
+
+------------------------------------------------------------------------
+r3076 | jcbowman | 2008-03-29 17:06:20 -0600 (Sat, 29 Mar 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/plain_filldraw.asy
+
+Add draw(frame f, guide[] g, pen p=currentpen) routine.
+
+------------------------------------------------------------------------
+r3075 | jcbowman | 2008-03-29 17:04:45 -0600 (Sat, 29 Mar 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/plain_constants.asy
+
+Simplify definition of endl.
+
+------------------------------------------------------------------------
+r3074 | jcbowman | 2008-03-29 17:03:50 -0600 (Sat, 29 Mar 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/slide.asy
+
+Move title down slightly.
+
+------------------------------------------------------------------------
+r3073 | jcbowman | 2008-03-29 17:02:59 -0600 (Sat, 29 Mar 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/plain.asy
+ M /trunk/asymptote/doc/asymptote.texi
+
+Add void beep() function; document flush output suffix.
+
+------------------------------------------------------------------------
+r3072 | jcbowman | 2008-03-29 16:59:31 -0600 (Sat, 29 Mar 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/plain_strings.asy
+
+Add real[] operator ecast(string[] a).
+
+------------------------------------------------------------------------
+r3071 | jcbowman | 2008-03-26 21:35:28 -0600 (Wed, 26 Mar 2008) | 4 lines
+Changed paths:
+ M /trunk/asymptote/base/graph.asy
+
+Make tickmin a multiple of Step when automin=false.
+
+Don't override put=Above default for extended axes.
+
+------------------------------------------------------------------------
+r3070 | hammera | 2008-03-21 21:45:32 -0600 (Fri, 21 Mar 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/array.cc
+ M /trunk/asymptote/array.h
+ M /trunk/asymptote/builtin.cc
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/item.h
+ M /trunk/asymptote/runtime.in
+ A /trunk/asymptote/tests/array/array.asy
+
+Added array(n, value) function for making arrays of duplicates.
+
+------------------------------------------------------------------------
+r3069 | jcbowman | 2008-03-21 09:56:10 -0600 (Fri, 21 Mar 2008) | 3 lines
+Changed paths:
+ M /trunk/asymptote/picture.cc
+
+Force the default -D 600 dvips setting for proper label alignment (should
+have no other effect since we are not using bitmapped fonts).
+
+------------------------------------------------------------------------
+r3068 | oshardt | 2008-03-11 21:58:22 -0600 (Tue, 11 Mar 2008) | 1 line
+Changed paths:
+ M /trunk/asymptote/GUI/xasyBezierEditor.py
+ M /trunk/asymptote/GUI/xasyMainWin.py
+
+Fix handling of undo/redo while in bezier editing mode.
+------------------------------------------------------------------------
+r3067 | jcbowman | 2008-03-11 08:45:01 -0600 (Tue, 11 Mar 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/psfile.cc
+
+Force setdash when offset changes.
+
+------------------------------------------------------------------------
+r3066 | jcbowman | 2008-03-02 16:19:55 -0700 (Sun, 02 Mar 2008) | 5 lines
+Changed paths:
+ M /trunk/asymptote/base/asy-mode.el
+
+Make C-c C-c automatically kill a previous running Asymptote process without
+second-guessing user's intentions.
+
+Remove erroneous "Compilation errors,..." message generated by killed processes.
+
+------------------------------------------------------------------------
+r3065 | pivaldi | 2008-03-02 04:29:55 -0700 (Sun, 02 Mar 2008) | 1 line
+Changed paths:
+ M /trunk/asymptote/doc/penimage.asy
+
+Remove useless code in penimage.asy
+------------------------------------------------------------------------
+r3064 | jcbowman | 2008-03-01 23:55:37 -0700 (Sat, 01 Mar 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/examples/vectorfield3.asy
+
+Fix gradient.
+
+------------------------------------------------------------------------
+r3063 | jcbowman | 2008-03-01 23:53:08 -0700 (Sat, 01 Mar 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/examples/vectorfield3.asy
+
+Remove unused import.
+
+------------------------------------------------------------------------
+r3062 | jcbowman | 2008-03-01 23:49:23 -0700 (Sat, 01 Mar 2008) | 5 lines
+Changed paths:
+ M /trunk/asymptote/base/graph.asy
+ M /trunk/asymptote/base/graph3.asy
+ M /trunk/asymptote/doc/CDlabel.asy
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/doc/flow.asy
+ A /trunk/asymptote/doc/vectorfield.asy
+ A /trunk/asymptote/examples/vectorfield3.asy
+
+Improve one-dimensional vector field interface (this change is backwards
+incompatible).
+
+Support two-dimensional and three-dimensional vector fields.
+
+------------------------------------------------------------------------
+r3061 | jcbowman | 2008-03-01 17:14:38 -0700 (Sat, 01 Mar 2008) | 2 lines
+Changed paths:
+ A /trunk/asymptote/examples/partialsurface.asy
+
+Add example of conditional surface and transparent splitting plane.
+
+------------------------------------------------------------------------
+r3060 | jcbowman | 2008-03-01 15:38:14 -0700 (Sat, 01 Mar 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/graph3.asy
+ M /trunk/asymptote/doc/asymptote.texi
+
+Implement conditional drawing of surfaces meshes over box(a,b).
+
+------------------------------------------------------------------------
+r3059 | pivaldi | 2008-02-28 04:42:32 -0700 (Thu, 28 Feb 2008) | 1 line
+Changed paths:
+ M /trunk/asymptote/base/asy-mode.el
+
+Update asy-mode-version value.
+------------------------------------------------------------------------
+r3058 | pivaldi | 2008-02-28 04:40:49 -0700 (Thu, 28 Feb 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/asy-mode.el
+
+Fix critical bug in asy-mode.el:
+a new Asymptote compilation when a process was running erased the contents of some buffers.
+------------------------------------------------------------------------
+r3057 | jcbowman | 2008-02-27 00:25:25 -0700 (Wed, 27 Feb 2008) | 1 line
+Changed paths:
+ M /trunk/asymptote/configure.ac
+
+Increment version to 1.43svn.
+------------------------------------------------------------------------
+r3056 | jcbowman | 2008-02-26 22:57:08 -0700 (Tue, 26 Feb 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/examples/animations/cube.asy
+
+Project labels onto cube faces.
+
+------------------------------------------------------------------------
+r3055 | jcbowman | 2008-02-24 09:32:50 -0700 (Sun, 24 Feb 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/settings.cc
+
+Don't set sticky bit when creating ~/.asy directory.
+
+------------------------------------------------------------------------
+r3054 | jcbowman | 2008-02-24 01:18:00 -0700 (Sun, 24 Feb 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/slopefield.asy
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/doc/slopefield1.asy
+
+Add optional arrows to slopefield routines.
+
+------------------------------------------------------------------------
+r3053 | jcbowman | 2008-02-22 14:47:40 -0700 (Fri, 22 Feb 2008) | 5 lines
+Changed paths:
+ M /trunk/asymptote/base/plain_markers.asy
+ M /trunk/asymptote/base/three.asy
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/examples/spline.asy
+
+Add routines pairs(real[] x, real[] y) and triples(real[] x, real[] y,
+real[] z) as a replacement for the obsolete routine
+dot(picture pic=currentpicture, pair[] x, pair[] y, pen p=currentpen,
+ filltype filltype=Fill);
+
+------------------------------------------------------------------------
+r3052 | jcbowman | 2008-02-22 14:11:07 -0700 (Fri, 22 Feb 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/three.asy
+
+Remove ambiguity in scale.
+
+------------------------------------------------------------------------
+r3051 | jcbowman | 2008-02-22 12:12:12 -0700 (Fri, 22 Feb 2008) | 10 lines
+Changed paths:
+ M /trunk/asymptote/base/plain_markers.asy
+ M /trunk/asymptote/base/three.asy
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/runtime.in
+
+Use the exact derivative of the projection map to project a Label onto a
+given plane.
+
+Remove routine dot(picture pic=currentpicture, pair[] x, pair[] y,
+ pen p=currentpen, filltype filltype=Fill);
+
+Add dot(real[] a, real[] b) routine returning the dot product of two vectors.
+
+Update documentation.
+
+------------------------------------------------------------------------
+r3050 | jcbowman | 2008-02-20 13:35:14 -0700 (Wed, 20 Feb 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/extra/intro.asy
+ M /trunk/asymptote/doc/generalaxis.asy
+ M /trunk/asymptote/doc/latexusage.tex
+ M /trunk/asymptote/doc/saddle.asy
+ M /trunk/asymptote/doc/shadedtiling.asy
+ M /trunk/asymptote/doc/unitcircle3.asy
+ M /trunk/asymptote/doc/westnile.asy
+ M /trunk/asymptote/examples/animations/pdfmovie.asy
+ M /trunk/asymptote/examples/cardiod.asy
+ M /trunk/asymptote/examples/cos2theta.asy
+ M /trunk/asymptote/examples/equilchord.asy
+ M /trunk/asymptote/examples/fjortoft.asy
+ M /trunk/asymptote/examples/integraltest.asy
+ M /trunk/asymptote/examples/lowupint.asy
+ M /trunk/asymptote/examples/mosaic.asy
+ M /trunk/asymptote/examples/polararea.asy
+ M /trunk/asymptote/examples/sacone.asy
+ M /trunk/asymptote/examples/shellmethod.asy
+ M /trunk/asymptote/examples/shellsqrtx01.asy
+ M /trunk/asymptote/examples/sqrtx01.asy
+ M /trunk/asymptote/examples/sqrtx01y1.asy
+ M /trunk/asymptote/examples/venn.asy
+ M /trunk/asymptote/examples/washermethod.asy
+ M /trunk/asymptote/examples/wedge.asy
+ M /trunk/asymptote/examples/workcone.asy
+ M /trunk/asymptote/examples/xxsq01.asy
+ M /trunk/asymptote/examples/xxsq01x-1.asy
+ M /trunk/asymptote/examples/xxsq01y.asy
+
+More guide to path changes.
+
+------------------------------------------------------------------------
+r3049 | jcbowman | 2008-02-20 13:30:54 -0700 (Wed, 20 Feb 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/three.asy
+
+Minor optimization.
+
+------------------------------------------------------------------------
+r3048 | jcbowman | 2008-02-20 10:05:24 -0700 (Wed, 20 Feb 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/animation.asy
+
+Minor optimization.
+
+------------------------------------------------------------------------
+r3047 | jcbowman | 2008-02-20 09:53:48 -0700 (Wed, 20 Feb 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/animation.asy
+
+Simplify code.
+
+------------------------------------------------------------------------
+r3046 | jcbowman | 2008-02-18 13:19:42 -0700 (Mon, 18 Feb 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/animation.asy
+
+Add fit argument also for nonglobal animations.
+
+------------------------------------------------------------------------
+r3045 | jcbowman | 2008-02-18 11:07:11 -0700 (Mon, 18 Feb 2008) | 5 lines
+Changed paths:
+ M /trunk/asymptote/base/animation.asy
+ M /trunk/asymptote/base/plain_shipout.asy
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/examples/animations/wheel.asy
+
+Add fit argument to animation routines for adding an optionally filled
+bounding box to each movie frame.
+
+Add newpage(frame) function.
+
+------------------------------------------------------------------------
+r3044 | jcbowman | 2008-02-18 09:54:28 -0700 (Mon, 18 Feb 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/plain_shipout.asy
+
+Remove unused shipout predeclaration.
+
+------------------------------------------------------------------------
+r3043 | jcbowman | 2008-02-17 22:29:37 -0700 (Sun, 17 Feb 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/runtime.in
+
+Add missing explicit qualifier.
+
+------------------------------------------------------------------------
+r3042 | jcbowman | 2008-02-17 22:22:15 -0700 (Sun, 17 Feb 2008) | 4 lines
+Changed paths:
+ M /trunk/asymptote/base/plain_paths.asy
+ M /trunk/asymptote/base/plain_pens.asy
+ M /trunk/asymptote/base/plain_picture.asy
+ M /trunk/asymptote/builtin.cc
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/runtime.in
+
+Move definition of currentpen to C++ code.
+
+Add int inside(path p, path q, pen fillrule=currentpen) routine.
+
+------------------------------------------------------------------------
+r3041 | jcbowman | 2008-02-16 22:17:40 -0700 (Sat, 16 Feb 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/asymptote.spec
+ M /trunk/asymptote/base/three.asy
+
+Add routine for projecting a Label onto a given plane.
+
+------------------------------------------------------------------------
+r3040 | jcbowman | 2008-02-15 09:43:04 -0700 (Fri, 15 Feb 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/extra/intro.asy
+ M /trunk/asymptote/texfile.h
+
+Fix missing ASYbase declaration.
+
+------------------------------------------------------------------------
+r3039 | oshardt | 2008-02-13 19:21:00 -0700 (Wed, 13 Feb 2008) | 1 line
+Changed paths:
+ M /trunk/asymptote/GUI/xasyBezierEditor.py
+ M /trunk/asymptote/GUI/xasyMainWin.py
+
+Fix bug in cancellation of text addition.
+------------------------------------------------------------------------
+r3038 | jcbowman | 2008-02-13 15:24:27 -0700 (Wed, 13 Feb 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/picture.cc
+ M /trunk/asymptote/texfile.cc
+ M /trunk/asymptote/texfile.h
+
+Output TeX headers only when needed.
+
+------------------------------------------------------------------------
+r3037 | jcbowman | 2008-02-13 15:21:32 -0700 (Wed, 13 Feb 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/doc/extra/intro.asy
+
+Mention that transforms can also be applied to Labels.
+
+------------------------------------------------------------------------
+r3036 | jcbowman | 2008-02-11 14:19:08 -0700 (Mon, 11 Feb 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/FAQ/asy-faq.bfnn
+
+Update two arrow example.
+
+------------------------------------------------------------------------
+r3035 | jcbowman | 2008-02-11 13:49:15 -0700 (Mon, 11 Feb 2008) | 4 lines
+Changed paths:
+ M /trunk/asymptote/doc/FAQ/asy-faq.bfnn
+ M /trunk/asymptote/examples/dimension.asy
+
+Update documentation of arrowhead styles.
+
+Change guides to paths.
+
+------------------------------------------------------------------------
+r3034 | jcbowman | 2008-02-11 13:15:19 -0700 (Mon, 11 Feb 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+
+Move documentation of colorless(pen) to a better place.
+
+------------------------------------------------------------------------
+r3033 | jcbowman | 2008-02-11 03:14:56 -0700 (Mon, 11 Feb 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/imagecontour.asy
+ M /trunk/asymptote/examples/fillcontour.asy
+
+Simply and generalize contour value selection code.
+
+------------------------------------------------------------------------
+r3032 | jcbowman | 2008-02-08 21:58:31 -0700 (Fri, 08 Feb 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/graph.asy
+
+Make OmitTick do nothing when there are no major ticks.
+
+------------------------------------------------------------------------
+r3031 | hammera | 2008-02-05 18:25:23 -0700 (Tue, 05 Feb 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+
+Fixed typo in slice documentation.
+
+------------------------------------------------------------------------
+r3030 | jcbowman | 2008-02-05 09:01:26 -0700 (Tue, 05 Feb 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/plain.asy
+
+Avoid division by zero in uniform.
+
+------------------------------------------------------------------------
+r3029 | jcbowman | 2008-02-03 16:19:39 -0700 (Sun, 03 Feb 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+
+Update documentation regarding ImageMagick convert.
+
+------------------------------------------------------------------------
+r3028 | jcbowman | 2008-02-03 16:13:17 -0700 (Sun, 03 Feb 2008) | 4 lines
+Changed paths:
+ M /trunk/asymptote/base/animation.asy
+ M /trunk/asymptote/examples/animations/inlinemovie.tex
+
+Make movie generate multipage pdf animations when format="pdf" and global=true.
+
+Insist on pdflatex in animation.pdf().
+
+------------------------------------------------------------------------
+r3027 | jcbowman | 2008-02-03 16:08:56 -0700 (Sun, 03 Feb 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/drawlabel.cc
+
+Catch bad casts.
+
+------------------------------------------------------------------------
+r3026 | jcbowman | 2008-02-02 10:23:44 -0700 (Sat, 02 Feb 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/plain_pens.asy
+ M /trunk/asymptote/doc/asymptote.texi
+
+Add casts between hsv structure and pens; reduce angle to [0,360).
+
+------------------------------------------------------------------------
+r3025 | jcbowman | 2008-02-02 02:07:55 -0700 (Sat, 02 Feb 2008) | 1 line
+Changed paths:
+ M /trunk/asymptote/configure.ac
+
+Increment version to 1.42svn.
+------------------------------------------------------------------------
+r3024 | jcbowman | 2008-02-02 01:12:22 -0700 (Sat, 02 Feb 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/array.cc
+
+Fix type conflict.
+
+------------------------------------------------------------------------
+r3023 | jcbowman | 2008-02-02 00:05:46 -0700 (Sat, 02 Feb 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/plain_pens.asy
+ M /trunk/asymptote/doc/asymptote.texi
+
+Add support for HSV colorspace.
+
+------------------------------------------------------------------------
+r3022 | jcbowman | 2008-01-31 20:21:25 -0700 (Thu, 31 Jan 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+
+Minor edits.
+
+------------------------------------------------------------------------
+r3021 | hammera | 2008-01-30 18:42:11 -0700 (Wed, 30 Jan 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/TODO
+ M /trunk/asymptote/doc/asymptote.texi
+
+Documented slices.
+
+------------------------------------------------------------------------
+r3020 | hammera | 2008-01-30 13:28:01 -0700 (Wed, 30 Jan 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/array.cc
+ M /trunk/asymptote/tests/array/slice.asy
+
+Disallow A[5:2] and, for non-cyclic A, A[-1:] to play it safe.
+
+------------------------------------------------------------------------
+r3019 | jcbowman | 2008-01-30 12:24:17 -0700 (Wed, 30 Jan 2008) | 3 lines
+Changed paths:
+ M /trunk/asymptote/arrayop.h
+
+Change write to output nothing for uninitialized values instead of
+producing an error.
+
+------------------------------------------------------------------------
+r3018 | jcbowman | 2008-01-30 11:19:58 -0700 (Wed, 30 Jan 2008) | 5 lines
+Changed paths:
+ M /trunk/asymptote/base/plain.asy
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/runtime.in
+
+Add uniform(real a, real b, int n), which returns a uniform partition of
+[a,b] into n subintervals.
+
+Fix comment.
+
+------------------------------------------------------------------------
+r3017 | jcbowman | 2008-01-29 17:53:40 -0700 (Tue, 29 Jan 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/runtime.in
+
+Store history line immediately after input (as well at exit, after stifling).
+
+------------------------------------------------------------------------
+r3016 | jcbowman | 2008-01-29 08:23:30 -0700 (Tue, 29 Jan 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/examples/integraltest.asy
+ M /trunk/asymptote/runtime.in
+
+Add interface to simpson.
+
+------------------------------------------------------------------------
+r3015 | jcbowman | 2008-01-28 12:12:37 -0700 (Mon, 28 Jan 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+
+Format.
+
+------------------------------------------------------------------------
+r3014 | jcbowman | 2008-01-28 12:11:43 -0700 (Mon, 28 Jan 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+
+Move numerical routines to Mathematical functions section.
+
+------------------------------------------------------------------------
+r3013 | jcbowman | 2008-01-28 11:38:09 -0700 (Mon, 28 Jan 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/plain_paths.asy
+ M /trunk/asymptote/doc/asymptote.texi
+
+Make buildcycle return nullpath if less than two paths are specified.
+
+------------------------------------------------------------------------
+r3012 | jcbowman | 2008-01-28 10:56:44 -0700 (Mon, 28 Jan 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+
+Fix typo in documentation of complement.
+
+------------------------------------------------------------------------
+r3011 | jcbowman | 2008-01-28 10:35:52 -0700 (Mon, 28 Jan 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+
+Fix formatting.
+
+------------------------------------------------------------------------
+r3010 | hammera | 2008-01-27 11:05:40 -0700 (Sun, 27 Jan 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/array.cc
+ M /trunk/asymptote/array.h
+ M /trunk/asymptote/exp.cc
+ M /trunk/asymptote/exp.h
+ M /trunk/asymptote/runtime.in
+ M /trunk/asymptote/tests/array/slice.asy
+
+Implemented assignment to slices.
+
+------------------------------------------------------------------------
+r3009 | jcbowman | 2008-01-26 16:11:28 -0700 (Sat, 26 Jan 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/drawlabel.cc
+ M /trunk/asymptote/pipestream.h
+
+Shred TeX transcripts after each call to drawLabel::wait.
+
+------------------------------------------------------------------------
+r3008 | jcbowman | 2008-01-26 15:57:21 -0700 (Sat, 26 Jan 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/drawlabel.cc
+ M /trunk/asymptote/pipestream.h
+
+Output complete TeX diagnostics.
+
+------------------------------------------------------------------------
+r3007 | jcbowman | 2008-01-26 15:30:24 -0700 (Sat, 26 Jan 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/tests/Makefile
+ M /trunk/asymptote/tests/TestLib.asy
+
+Add blank lines between tests.
+
+------------------------------------------------------------------------
+r3006 | hammera | 2008-01-26 15:02:48 -0700 (Sat, 26 Jan 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/runtime.in
+
+Added null check for array slices.
+
+------------------------------------------------------------------------
+r3005 | jcbowman | 2008-01-26 14:57:19 -0700 (Sat, 26 Jan 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/Makefile.in
+
+Add array.
+
+------------------------------------------------------------------------
+r3004 | jcbowman | 2008-01-26 14:52:05 -0700 (Sat, 26 Jan 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/asymptote.spec
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/runtime.in
+
+Define complex exp, log, sin, and cos functions.
+
+------------------------------------------------------------------------
+r3003 | hammera | 2008-01-26 14:13:57 -0700 (Sat, 26 Jan 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/TODO
+ A /trunk/asymptote/array.cc
+ M /trunk/asymptote/array.h
+ M /trunk/asymptote/camp.y
+ M /trunk/asymptote/exp.cc
+ M /trunk/asymptote/exp.h
+ M /trunk/asymptote/runtime.in
+ A /trunk/asymptote/tests/array/slice.asy
+
+Added array slices.
+
+------------------------------------------------------------------------
+r3002 | jcbowman | 2008-01-26 10:19:22 -0700 (Sat, 26 Jan 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/examples/animations/slidemovies.asy
+
+Fix file paths.
+
+------------------------------------------------------------------------
+r3001 | jcbowman | 2008-01-26 10:14:03 -0700 (Sat, 26 Jan 2008) | 3 lines
+Changed paths:
+ M /trunk/asymptote/base/animate.asy
+ A /trunk/asymptote/base/animation.asy
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/examples/animations/cube.asy
+ M /trunk/asymptote/examples/animations/sphere.asy
+ M /trunk/asymptote/examples/animations/wavepacket.asy
+ M /trunk/asymptote/examples/animations/wheel.asy
+
+Remove dependence of non-PDF animations on animate.sty package by renaming
+animate.sty to animation.sty (PDF animations still need to import animate.sty).
+
+------------------------------------------------------------------------
+r3000 | hammera | 2008-01-26 09:18:56 -0700 (Sat, 26 Jan 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/TODO
+ M /trunk/asymptote/fundec.cc
+
+Report on error for rest args with default arguments.
+
+------------------------------------------------------------------------
+r2999 | hammera | 2008-01-26 09:07:52 -0700 (Sat, 26 Jan 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/TODO
+ M /trunk/asymptote/builtin.cc
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/runtime.in
+ M /trunk/asymptote/types.cc
+
+Added virtual field A.keys for arrays. concat now take a rest arg.
+
+------------------------------------------------------------------------
+r2998 | jcbowman | 2008-01-25 22:47:18 -0700 (Fri, 25 Jan 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/examples/transparency.asy
+ M /trunk/asymptote/picture.cc
+ M /trunk/asymptote/picture.h
+ M /trunk/asymptote/psfile.cc
+ M /trunk/asymptote/psfile.h
+ M /trunk/asymptote/runtime.in
+
+Make xasy respect transparency with png xformat.
+
+------------------------------------------------------------------------
+r2997 | jcbowman | 2008-01-25 19:51:26 -0700 (Fri, 25 Jan 2008) | 4 lines
+Changed paths:
+ M /trunk/asymptote/base/math.asy
+ M /trunk/asymptote/base/plain_arrows.asy
+ M /trunk/asymptote/base/plain_filldraw.asy
+ M /trunk/asymptote/doc/asymptote.texi
+
+Add drawpen argument to FillDraw.
+
+Handle nullpen when drawing arrows.
+
+------------------------------------------------------------------------
+r2996 | jcbowman | 2008-01-20 11:58:45 -0700 (Sun, 20 Jan 2008) | 12 lines
+Changed paths:
+ M /trunk/asymptote/base/flowchart.asy
+ M /trunk/asymptote/base/plain_Label.asy
+ M /trunk/asymptote/base/plain_boxes.asy
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/doc/latexusage.tex
+ M /trunk/asymptote/examples/labelbox.asy
+ M /trunk/asymptote/runtime.in
+
+Store and make use of the bounding path in the object structure to allow
+connections to noncardinal boundary points.
+
+Add constructors to the object structure.
+
+Remove obsolete function for drawing boxes on pictures in favour of
+draw(Label,box).
+
+Add dir(explicit pair z) function so that dir(E) is a synonym for E.
+
+Update documentation.
+
+------------------------------------------------------------------------
+r2995 | jcbowman | 2008-01-19 21:28:43 -0700 (Sat, 19 Jan 2008) | 2 lines
+Changed paths:
+ A /trunk/asymptote/examples/gamma.asy
+
+Add gamma function example.
+
+------------------------------------------------------------------------
+r2994 | jcbowman | 2008-01-19 18:03:13 -0700 (Sat, 19 Jan 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+
+Fix typo.
+
+------------------------------------------------------------------------
+r2993 | jcbowman | 2008-01-19 18:02:16 -0700 (Sat, 19 Jan 2008) | 5 lines
+Changed paths:
+ M /trunk/asymptote/base/plain_paths.asy
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/path.cc
+
+Improve buildcycle algorithm.
+
+Avoid numerical resolution issues by removing the "paths in concatenation
+do not meet" error.
+
+------------------------------------------------------------------------
+r2992 | jcbowman | 2008-01-17 16:29:08 -0700 (Thu, 17 Jan 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/math.asy
+ M /trunk/asymptote/base/plain_paths.asy
+ M /trunk/asymptote/doc/asymptote.texi
+
+Add intersection count to node and value routines.
+
+------------------------------------------------------------------------
+r2991 | jcbowman | 2008-01-17 16:24:27 -0700 (Thu, 17 Jan 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/flowchartdemo.asy
+
+Update example to show how to specify all pen colours.
+
+------------------------------------------------------------------------
+r2990 | pivaldi | 2008-01-12 10:53:17 -0700 (Sat, 12 Jan 2008) | 1 line
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+
+Fix typo
+------------------------------------------------------------------------
+r2989 | jcbowman | 2008-01-11 21:59:03 -0700 (Fri, 11 Jan 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/solids.asy
+ M /trunk/asymptote/doc/asymptote.texi
+
+Determine whether unsplit slices are should be drawn as front or back slices.
+
+------------------------------------------------------------------------
+r2988 | jcbowman | 2008-01-05 11:59:42 -0700 (Sat, 05 Jan 2008) | 1 line
+Changed paths:
+ M /trunk/asymptote/asymptote.spec
+ M /trunk/asymptote/configure.ac
+
+Increment version to 1.41svn.
+------------------------------------------------------------------------
+r2987 | jcbowman | 2008-01-05 11:02:27 -0700 (Sat, 05 Jan 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/solids.asy
+
+Fix nurb-related bug in solid shading.
+
+------------------------------------------------------------------------
+r2986 | jcbowman | 2008-01-05 10:40:31 -0700 (Sat, 05 Jan 2008) | 3 lines
+Changed paths:
+ M /trunk/asymptote/psfile.cc
+
+Fix PDF hatch width by disabling dynamics line width adjustment when
+producing pdf format.
+
+------------------------------------------------------------------------
+r2985 | jcbowman | 2008-01-05 09:50:59 -0700 (Sat, 05 Jan 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/examples/animations/inlinemovie.tex
+
+Omit control panel for second movie.
+
+------------------------------------------------------------------------
+r2984 | jcbowman | 2008-01-04 21:08:35 -0700 (Fri, 04 Jan 2008) | 1 line
+Changed paths:
+ M /trunk/asymptote/asymptote.spec
+ M /trunk/asymptote/configure.ac
+
+Increment version to 1.40svn.
+------------------------------------------------------------------------
+r2983 | jcbowman | 2008-01-04 19:48:57 -0700 (Fri, 04 Jan 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/examples/animations/inlinemovie.tex
+
+Fix inline embedded PDF animations.
+
+------------------------------------------------------------------------
+r2982 | jcbowman | 2008-01-04 19:28:04 -0700 (Fri, 04 Jan 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/animate.asy
+ M /trunk/asymptote/doc/asymptote.texi
+
+Delete intermediate animation file unless keep=true.
+
+------------------------------------------------------------------------
+r2981 | jcbowman | 2008-01-04 17:53:32 -0700 (Fri, 04 Jan 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/animate.asy
+ M /trunk/asymptote/examples/animations/inlinemovie.tex
+
+Use constructor to initialize animation.
+
+------------------------------------------------------------------------
+r2980 | jcbowman | 2008-01-04 17:23:54 -0700 (Fri, 04 Jan 2008) | 1 line
+Changed paths:
+ M /trunk/asymptote/configure.ac
+
+Increment version to 1.39svn.
+------------------------------------------------------------------------
+r2979 | jcbowman | 2008-01-04 13:09:26 -0700 (Fri, 04 Jan 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/pipestream.h
+
+Patch to support gcc-4.3.
+
+------------------------------------------------------------------------
+r2978 | jcbowman | 2008-01-04 12:53:56 -0700 (Fri, 04 Jan 2008) | 2 lines
+Changed paths:
+ D /trunk/asymptote/examples/animations/inlinemovie.asy
+ A /trunk/asymptote/examples/animations/inlinemovie.tex (from /trunk/asymptote/examples/inlinemovie.tex:2977)
+ D /trunk/asymptote/examples/inlinemovie.tex
+
+Move inlinemove.tex to animations directory.
+
+------------------------------------------------------------------------
+r2977 | jcbowman | 2008-01-04 12:52:04 -0700 (Fri, 04 Jan 2008) | 4 lines
+Changed paths:
+ M /trunk/asymptote/base/animate.asy
+ M /trunk/asymptote/doc/asymptote.sty
+ A /trunk/asymptote/examples/animatations (from /trunk/asymptote/examples/slidemovies.asy:2972)
+ A /trunk/asymptote/examples/animations/inlinemovie.asy
+ A /trunk/asymptote/examples/animations/slidemovies.asy (from /trunk/asymptote/examples/slidemovies.asy:2972)
+ M /trunk/asymptote/examples/inlinemovie.tex
+ D /trunk/asymptote/examples/slidemovies.asy
+
+Add argument global to animate constructor.
+
+Fix and illustrate inline animations.
+
+------------------------------------------------------------------------
+r2976 | jcbowman | 2008-01-03 21:13:31 -0700 (Thu, 03 Jan 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/three.asy
+
+Fix ambiguous call to dot(triple[]).
+
+------------------------------------------------------------------------
+r2975 | jcbowman | 2008-01-03 20:15:16 -0700 (Thu, 03 Jan 2008) | 5 lines
+Changed paths:
+ M /trunk/asymptote/base/animate.asy
+ M /trunk/asymptote/doc/asymptote.sty
+ M /trunk/asymptote/doc/asymptote.texi
+ A /trunk/asymptote/examples/inlinemovie.tex
+
+Support and illustrate embedding of inline pdf files even in absence of
+[inline] asymptote.sty option.
+
+Use multipage mode by default in animate.pdf().
+
+------------------------------------------------------------------------
+r2974 | jcbowman | 2008-01-03 17:06:40 -0700 (Thu, 03 Jan 2008) | 4 lines
+Changed paths:
+ M /trunk/asymptote/base/animate.asy
+ M /trunk/asymptote/doc/asymptote.texi
+
+Add constructor for animate.
+
+Update inline pdf movie documentation.
+
+------------------------------------------------------------------------
+r2973 | jcbowman | 2008-01-03 16:44:30 -0700 (Thu, 03 Jan 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/animate.asy
+
+Support multipage and inline pdf movies.
+
+------------------------------------------------------------------------
+r2972 | pivaldi | 2008-01-03 06:59:26 -0700 (Thu, 03 Jan 2008) | 1 line
+Changed paths:
+ M /trunk/asymptote/base/plain_arrows.asy
+
+Fix TeXHead path.
+------------------------------------------------------------------------
+r2971 | jcbowman | 2008-01-02 23:17:36 -0700 (Wed, 02 Jan 2008) | 8 lines
+Changed paths:
+ M /trunk/asymptote/base/plain_arrows.asy
+ M /trunk/asymptote/doc/asymptote.texi
+
+Document arrowhead styles.
+
+Rename arrowheadT to arrowhead.
+
+Add defaultfilltype to arrowhead.
+
+Fix direction bug in TeXhead.
+
+------------------------------------------------------------------------
+r2970 | pivaldi | 2008-01-02 19:12:25 -0700 (Wed, 02 Jan 2008) | 1 line
+Changed paths:
+ M /trunk/asymptote/base/plain_arrows.asy
+
+Provide Computer Modern arrow head.
+------------------------------------------------------------------------
+r2969 | jcbowman | 2008-01-01 15:17:29 -0700 (Tue, 01 Jan 2008) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/plain_arrows.asy
+
+Fix degenerate arrows.
+
+------------------------------------------------------------------------
+r2968 | jcbowman | 2007-12-30 23:57:24 -0700 (Sun, 30 Dec 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/plain_arrows.asy
+
+Add arrowhookfactor.
+
+------------------------------------------------------------------------
+r2967 | jcbowman | 2007-12-30 23:50:21 -0700 (Sun, 30 Dec 2007) | 4 lines
+Changed paths:
+ M /trunk/asymptote/base/plain_arrows.asy
+
+Support alternative arrowhead styles.
+
+Add SimpleHead and HookHead arrow styles (courtesy of Philippe Ivaldi).
+
+------------------------------------------------------------------------
+r2966 | jcbowman | 2007-12-30 23:46:56 -0700 (Sun, 30 Dec 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/plain_filldraw.asy
+
+Automatically reduce FillDraw to Draw for noncyclic paths.
+
+------------------------------------------------------------------------
+r2965 | jcbowman | 2007-12-29 10:37:13 -0700 (Sat, 29 Dec 2007) | 8 lines
+Changed paths:
+ M /trunk/asymptote/asymptote.spec
+ M /trunk/asymptote/base/plain_paths.asy
+ M /trunk/asymptote/base/solids.asy
+ M /trunk/asymptote/base/surface.asy
+ M /trunk/asymptote/base/three.asy
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/doc/saddle.asy
+ M /trunk/asymptote/path.cc
+ M /trunk/asymptote/path.h
+ M /trunk/asymptote/runtime.in
+
+Approximate nonuniform rational B-splines (nurbs) by adding additonal
+control points to Bezier curves (not yet optimal).
+
+Add operator &(path p, cycleToken tok).
+
+Update constructors in three.asy.
+
+
+------------------------------------------------------------------------
+r2964 | jcbowman | 2007-12-28 11:20:30 -0700 (Fri, 28 Dec 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/graph.asy
+
+In autoformat, try to add an extra digit of precision.
+
+------------------------------------------------------------------------
+r2963 | jcbowman | 2007-12-24 09:42:05 -0700 (Mon, 24 Dec 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/GUI/xasy2asy.py
+
+Handle output from xasy scripts.
+
+------------------------------------------------------------------------
+r2962 | jcbowman | 2007-12-24 09:06:39 -0700 (Mon, 24 Dec 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/Makefile.in
+ D /trunk/asymptote/xasy
+
+Have Makefile create symbolic link xasy.
+
+------------------------------------------------------------------------
+r2961 | oshardt | 2007-12-22 20:34:02 -0700 (Sat, 22 Dec 2007) | 1 line
+Changed paths:
+ M /trunk/asymptote/GUI/xasy2asy.py
+ M /trunk/asymptote/GUI/xasyMainWin.py
+
+Remove need for access to GUI widgets from threads other than main thread.
+------------------------------------------------------------------------
+r2960 | jcbowman | 2007-12-11 19:01:47 -0700 (Tue, 11 Dec 2007) | 2 lines
+Changed paths:
+ A /trunk/asymptote/doc/Hobbycontrol.asy
+ A /trunk/asymptote/doc/Hobbydir.asy
+ M /trunk/asymptote/doc/extra/intro.asy
+
+Add missing figures; remove duplicate line.
+
+------------------------------------------------------------------------
+r2959 | hammera | 2007-12-10 11:29:34 -0700 (Mon, 10 Dec 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/env.cc
+ M /trunk/asymptote/env.h
+ M /trunk/asymptote/exp.cc
+ M /trunk/asymptote/exp.h
+
+Clear the matchCatch after translating a module, for a modest speed-up.
+
+------------------------------------------------------------------------
+r2958 | jcbowman | 2007-12-09 22:37:42 -0700 (Sun, 09 Dec 2007) | 9 lines
+Changed paths:
+ M /trunk/asymptote/base/graph.asy
+ M /trunk/asymptote/base/graph3.asy
+ M /trunk/asymptote/doc/asymptote.texi
+
+Add optional xlabel and ylabel arguments to axes.
+
+Make default xlabel, ylabel, and zlabel arguments of 3D axes routines empty
+strings.
+
+Document axes.
+
+Untabify graph3.asy and graph.asy.
+
+------------------------------------------------------------------------
+r2957 | jcbowman | 2007-12-09 20:25:55 -0700 (Sun, 09 Dec 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/GUI/xasy2asy.py
+
+Remove unused import.
+
+------------------------------------------------------------------------
+r2956 | jcbowman | 2007-12-09 16:47:07 -0700 (Sun, 09 Dec 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/graph.asy
+ M /trunk/asymptote/base/graph3.asy
+ M /trunk/asymptote/base/interpolate.asy
+ M /trunk/asymptote/base/splinetype.asy
+
+Improve graph and interpolation array length diagnostics.
+
+------------------------------------------------------------------------
+r2955 | hammera | 2007-12-09 14:10:02 -0700 (Sun, 09 Dec 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/stm.cc
+
+Resolve ambiguous expressions during interactiveWrite (with a warning).
+
+------------------------------------------------------------------------
+r2954 | jcbowman | 2007-12-09 12:15:32 -0700 (Sun, 09 Dec 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/plain.asy
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/process.cc
+ M /trunk/asymptote/process.h
+ M /trunk/asymptote/runtime.in
+ M /trunk/asymptote/settings.cc
+
+Implement -c (command) option and exit() command.
+
+------------------------------------------------------------------------
+r2953 | jcbowman | 2007-12-09 10:49:08 -0700 (Sun, 09 Dec 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/castop.h
+ M /trunk/asymptote/fileio.h
+
+Make read1, read2, and read3 effective only for the current array read.
+
+------------------------------------------------------------------------
+r2952 | jcbowman | 2007-12-08 19:22:01 -0700 (Sat, 08 Dec 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/GUI/xasy2asy.py
+
+Output deconstruction errors to Asymptote Console window.
+
+------------------------------------------------------------------------
+r2951 | jcbowman | 2007-12-08 18:16:19 -0700 (Sat, 08 Dec 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/runtime.in
+
+Handle unclosed begingroups in deconstruct.
+
+------------------------------------------------------------------------
+r2950 | jcbowman | 2007-12-08 16:37:22 -0700 (Sat, 08 Dec 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/patches/README
+ A /trunk/asymptote/patches/pstoedit-3.45asy.patch
+
+Add patch to fix several problems with Asymptote backend for pstoedit-3.45.
+
+------------------------------------------------------------------------
+r2949 | jcbowman | 2007-12-08 14:17:13 -0700 (Sat, 08 Dec 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/runtime.in
+
+Ignore unclosed begingroups (to work around pstoedit problems).
+
+------------------------------------------------------------------------
+r2948 | jcbowman | 2007-12-08 14:13:07 -0700 (Sat, 08 Dec 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/bbox.h
+
+Fix empty clipping bbox.
+
+------------------------------------------------------------------------
+r2947 | jcbowman | 2007-12-08 10:43:45 -0700 (Sat, 08 Dec 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/examples/slidedemo.asy
+
+Show how to put a header on every page.
+
+------------------------------------------------------------------------
+r2946 | jcbowman | 2007-12-02 16:29:34 -0700 (Sun, 02 Dec 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/configure.ac
+
+Improve system gc detection.
+
+------------------------------------------------------------------------
+r2945 | jcbowman | 2007-12-02 10:58:15 -0700 (Sun, 02 Dec 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+
+Document \\ -> \\ mapping of double-quoted strings.
+
+------------------------------------------------------------------------
+r2944 | jcbowman | 2007-12-01 15:30:13 -0700 (Sat, 01 Dec 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/flowchart.asy
+ M /trunk/asymptote/doc/asymptote.texi
+
+Add default value of (0,0) to center.
+
+------------------------------------------------------------------------
+r2943 | jcbowman | 2007-12-01 15:24:03 -0700 (Sat, 01 Dec 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/flowchart.asy
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/doc/flowchartdemo.asy
+
+Add pen arguments to flowchart block routines.
+
+------------------------------------------------------------------------
+r2942 | jcbowman | 2007-11-28 01:28:22 -0700 (Wed, 28 Nov 2007) | 1 line
+Changed paths:
+ M /trunk/asymptote/configure.ac
+
+Increment version to 1.38svn.
+------------------------------------------------------------------------
+r2941 | jcbowman | 2007-11-28 00:37:17 -0700 (Wed, 28 Nov 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/GUI/xasy2asy.py
+ M /trunk/asymptote/GUI/xasyMainWin.py
+ M /trunk/asymptote/asymptote.nsi
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/util.h
+
+Final Windows tweaks.
+
+------------------------------------------------------------------------
+r2940 | jcbowman | 2007-11-27 23:05:09 -0700 (Tue, 27 Nov 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/plain_arrows.asy
+
+Remove min since intersections returns a sorted array.
+
+------------------------------------------------------------------------
+r2939 | jcbowman | 2007-11-27 22:41:59 -0700 (Tue, 27 Nov 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/doc/xasy.1x
+
+Document the -x option of xasy.
+
+------------------------------------------------------------------------
+r2938 | jcbowman | 2007-11-27 22:30:09 -0700 (Tue, 27 Nov 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/GUI/xasyMainWin.py
+
+Remove debugging test modification.
+
+------------------------------------------------------------------------
+r2937 | jcbowman | 2007-11-27 22:28:13 -0700 (Tue, 27 Nov 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+
+Update GUI installation documentation.
+
+------------------------------------------------------------------------
+r2936 | jcbowman | 2007-11-27 22:17:19 -0700 (Tue, 27 Nov 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/GUI/xasyMainWin.py
+
+Require Python 2.5 for MSWindows.
+
+------------------------------------------------------------------------
+r2935 | jcbowman | 2007-11-27 22:10:43 -0700 (Tue, 27 Nov 2007) | 2 lines
+Changed paths:
+ A /trunk/asymptote/patches/TkAlpha-Imaging-1.1.6msdos.patch
+
+Add version of PIL-1.1.6 patch used for MSDOS.
+
+------------------------------------------------------------------------
+r2934 | jcbowman | 2007-11-27 21:51:27 -0700 (Tue, 27 Nov 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/GUI/xasy2asy.py
+
+Output diagnostics from Asymptote in separate Tk window.
+
+------------------------------------------------------------------------
+r2933 | jcbowman | 2007-11-27 21:50:28 -0700 (Tue, 27 Nov 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/GUI/xasyMainWin.py
+
+Fix active Color button foreground.
+
+------------------------------------------------------------------------
+r2932 | oshardt | 2007-11-27 17:16:40 -0700 (Tue, 27 Nov 2007) | 1 line
+Changed paths:
+ M /trunk/asymptote/GUI/xasyMainWin.py
+
+Correct acquisition of lock for colour change.
+------------------------------------------------------------------------
+r2931 | jcbowman | 2007-11-27 16:23:59 -0700 (Tue, 27 Nov 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/fileio.cc
+ M /trunk/asymptote/interact.cc
+ M /trunk/asymptote/interact.h
+
+Add 's' scrolling option.
+
+------------------------------------------------------------------------
+r2930 | jcbowman | 2007-11-27 01:01:27 -0700 (Tue, 27 Nov 2007) | 2 lines
+Changed paths:
+ D /trunk/asymptote/GUI/xasyVersion.py
+ A /trunk/asymptote/GUI/xasyVersion.py.in (from /trunk/asymptote/GUI/xasyVersion.py:2920)
+ M /trunk/asymptote/configure.ac
+
+Configure xasy version.
+
+------------------------------------------------------------------------
+r2929 | jcbowman | 2007-11-27 01:00:47 -0700 (Tue, 27 Nov 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/fileio.cc
+
+Turn off scrolling when not a tty.
+
+------------------------------------------------------------------------
+r2928 | jcbowman | 2007-11-26 22:22:08 -0700 (Mon, 26 Nov 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/stats.asy
+ M /trunk/asymptote/doc/histogram.asy
+
+Add function to calculate "optimal" number of histogram bins.
+
+------------------------------------------------------------------------
+r2927 | jcbowman | 2007-11-26 17:54:59 -0700 (Mon, 26 Nov 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/examples/annotation.asy
+
+Force outformat="pdf".
+
+------------------------------------------------------------------------
+r2926 | jcbowman | 2007-11-26 17:54:03 -0700 (Mon, 26 Nov 2007) | 3 lines
+Changed paths:
+ M /trunk/asymptote/base/plain_arrows.asy
+
+When determining base points of arrows, always choose the closest
+intersection points (in terms of arclength) to the apex.
+
+------------------------------------------------------------------------
+r2925 | jcbowman | 2007-11-25 21:47:55 -0700 (Sun, 25 Nov 2007) | 7 lines
+Changed paths:
+ M /trunk/asymptote/GUI/xasy2asy.py
+ M /trunk/asymptote/GUI/xasyActions.py
+ M /trunk/asymptote/GUI/xasyFile.py
+ M /trunk/asymptote/GUI/xasyMainWin.py
+ M /trunk/asymptote/base/plain_shipout.asy
+ M /trunk/asymptote/base/plain_xasy.asy
+ M /trunk/asymptote/runtime.in
+
+Use a separate flag in indexedTransform to indicate GUI deletion, instead of
+zeroing out the transform. This produces clearer .asy output and
+allows deletion of objects to be undone, preserving the image transform,
+even after a deconstruct() (or by manual editing of the output code).
+
+Show asy diagnostics in console window.
+
+------------------------------------------------------------------------
+r2924 | jcbowman | 2007-11-24 23:23:19 -0700 (Sat, 24 Nov 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/arrayop.h
+ M /trunk/asymptote/fileio.cc
+ M /trunk/asymptote/fileio.h
+ M /trunk/asymptote/interact.cc
+ M /trunk/asymptote/interact.h
+
+Fix scrolling.
+
+------------------------------------------------------------------------
+r2923 | jcbowman | 2007-11-24 23:03:07 -0700 (Sat, 24 Nov 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/graph3.asy
+ M /trunk/asymptote/doc/helix.asy
+
+Improve 3d tick default directions.
+
+------------------------------------------------------------------------
+r2922 | jcbowman | 2007-11-24 06:42:14 -0700 (Sat, 24 Nov 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/graph.asy
+
+Return empty secondary axis picture without warning.
+
+------------------------------------------------------------------------
+r2921 | jcbowman | 2007-11-22 08:57:42 -0700 (Thu, 22 Nov 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/runtime.in
+
+Use unsigned long constant.
+
+------------------------------------------------------------------------
+r2920 | jcbowman | 2007-11-21 22:03:02 -0700 (Wed, 21 Nov 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/GUI/xasyMainWin.py
+
+Move existing releaseLock code, catching exceptions.
+
+------------------------------------------------------------------------
+r2919 | jcbowman | 2007-11-21 17:56:01 -0700 (Wed, 21 Nov 2007) | 11 lines
+Changed paths:
+ M /trunk/asymptote/base/markers.asy
+ M /trunk/asymptote/base/plain_arcs.asy
+ M /trunk/asymptote/base/plain_constants.asy
+ M /trunk/asymptote/base/plain_filldraw.asy
+ M /trunk/asymptote/base/plain_markers.asy
+ M /trunk/asymptote/base/plain_picture.asy
+ M /trunk/asymptote/base/three.asy
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/runtime.in
+
+Add transform scale(real x, real y).
+
+Add marker dot(pen p=currentpen, filltype filltype=Fill).
+
+Add comma terminator.
+
+Fix dot(frame f, pair z, pen p=currentpen, filltype filltype=Fill).
+
+Update documentation.
+
+
+------------------------------------------------------------------------
+r2918 | jcbowman | 2007-11-20 23:09:32 -0700 (Tue, 20 Nov 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/picture.cc
+ M /trunk/asymptote/runtime.in
+
+Work around ghostscript limitations.
+
+------------------------------------------------------------------------
+r2917 | jcbowman | 2007-11-20 22:42:11 -0700 (Tue, 20 Nov 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/GUI/xasy2asy.py
+
+Ensure originalImage is always defined.
+
+------------------------------------------------------------------------
+r2916 | jcbowman | 2007-11-20 22:41:00 -0700 (Tue, 20 Nov 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/GUI/xasyMainWin.py
+
+Release lock before quitting to allow saving.
+
+------------------------------------------------------------------------
+r2915 | oshardt | 2007-11-20 17:52:46 -0700 (Tue, 20 Nov 2007) | 1 line
+Changed paths:
+ M /trunk/asymptote/GUI/xasyMainWin.py
+
+Switch to selection mode after adding script item.
+------------------------------------------------------------------------
+r2914 | jcbowman | 2007-11-20 10:26:25 -0700 (Tue, 20 Nov 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/fileio.h
+
+Re-enable local directory output check.
+
+------------------------------------------------------------------------
+r2913 | jcbowman | 2007-11-19 23:00:56 -0700 (Mon, 19 Nov 2007) | 4 lines
+Changed paths:
+ M /trunk/asymptote/fileio.h
+
+Fix output(s,update=true) and boutput(s,update=true).
+
+Fix segmentation faults for attempted operations on closed files.
+
+------------------------------------------------------------------------
+r2912 | oshardt | 2007-11-19 21:00:18 -0700 (Mon, 19 Nov 2007) | 1 line
+Changed paths:
+ M /trunk/asymptote/GUI/xasyMainWin.py
+
+Change zoom selection method to an OptionMenu
+------------------------------------------------------------------------
+r2911 | jcbowman | 2007-11-19 20:34:47 -0700 (Mon, 19 Nov 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/Makefile.in
+
+Escape ^.
+
+------------------------------------------------------------------------
+r2910 | oshardt | 2007-11-19 20:19:13 -0700 (Mon, 19 Nov 2007) | 1 line
+Changed paths:
+ M /trunk/asymptote/GUI/xasyActions.py
+
+Account for magnification during undo/redo of translations
+------------------------------------------------------------------------
+r2909 | jcbowman | 2007-11-19 10:59:03 -0700 (Mon, 19 Nov 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+
+Fix typo.
+
+------------------------------------------------------------------------
+r2908 | jcbowman | 2007-11-19 00:22:35 -0700 (Mon, 19 Nov 2007) | 9 lines
+Changed paths:
+ M /trunk/asymptote/GUI/xasy.py
+ M /trunk/asymptote/GUI/xasy2asy.py
+ M /trunk/asymptote/GUI/xasyMainWin.py
+ M /trunk/asymptote/interact.cc
+
+Move xasy temporary directory deletion code into GUI.
+
+Avoid creating a second asy process if one already exists.
+
+Ignore ctrl-c interrupts from console.
+
+Move image file removal up one function level to avoid busy error under
+MSWindows.
+
+------------------------------------------------------------------------
+r2907 | jcbowman | 2007-11-18 23:25:22 -0700 (Sun, 18 Nov 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/GUI/xasy2asy.py
+ M /trunk/asymptote/GUI/xasyActions.py
+ M /trunk/asymptote/GUI/xasyMainWin.py
+
+Add Orest's latest fixes.
+
+------------------------------------------------------------------------
+r2906 | jcbowman | 2007-11-18 19:29:19 -0700 (Sun, 18 Nov 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/configure.ac
+
+Add informational message about use of system gc version.
+
+------------------------------------------------------------------------
+r2905 | jcbowman | 2007-11-18 17:41:19 -0700 (Sun, 18 Nov 2007) | 3 lines
+Changed paths:
+ M /trunk/asymptote/asymptote.spec
+ M /trunk/asymptote/configure.ac
+ M /trunk/asymptote/doc/asymptote.texi
+
+Make configure use a system version of Boehm GC if recommended local version
+of gc isn't present.
+
+------------------------------------------------------------------------
+r2904 | jcbowman | 2007-11-18 17:28:22 -0700 (Sun, 18 Nov 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/INSTALL
+
+Append generic configure instructions to INSTALL.
+
+------------------------------------------------------------------------
+r2903 | jcbowman | 2007-11-18 10:02:49 -0700 (Sun, 18 Nov 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/GUI/xasy2asy.py
+ M /trunk/asymptote/base/plain_xasy.asy
+ M /trunk/asymptote/interact.cc
+ M /trunk/asymptote/runtime.in
+
+Put deconstructed files in a temporary directory (removed on exit).
+
+------------------------------------------------------------------------
+r2902 | jcbowman | 2007-11-18 08:54:43 -0700 (Sun, 18 Nov 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/settings.cc
+
+Move workaround for broken curses.h file to proper place.
+
+------------------------------------------------------------------------
+r2901 | jcbowman | 2007-11-17 22:59:59 -0700 (Sat, 17 Nov 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/graph.asy
+
+Fix secondary axis bugs.
+
+------------------------------------------------------------------------
+r2900 | jcbowman | 2007-11-17 17:03:34 -0700 (Sat, 17 Nov 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/GUI/xasy.py
+
+Fix ctrl-c.
+
+------------------------------------------------------------------------
+r2899 | oshardt | 2007-11-17 11:47:31 -0700 (Sat, 17 Nov 2007) | 1 line
+Changed paths:
+ M /trunk/asymptote/GUI/xasy.py
+
+Provide a way to quickly close xasy from the command line.
+------------------------------------------------------------------------
+r2898 | oshardt | 2007-11-17 11:24:42 -0700 (Sat, 17 Nov 2007) | 1 line
+Changed paths:
+ M /trunk/asymptote/GUI/xasyActions.py
+ M /trunk/asymptote/GUI/xasyBezierEditor.py
+
+Fix bezier editor. Optimize undeletion of items from a script.
+------------------------------------------------------------------------
+r2897 | jcbowman | 2007-11-16 23:12:28 -0700 (Fri, 16 Nov 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/GUI/xasyMainWin.py
+
+xasy scripts should put temporary files in current directory, just like asy.
+
+------------------------------------------------------------------------
+r2896 | jcbowman | 2007-11-16 23:11:56 -0700 (Fri, 16 Nov 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/GUI/xasy2asy.py
+
+Remove temporary image files.
+
+------------------------------------------------------------------------
+r2895 | jcbowman | 2007-11-16 22:20:39 -0700 (Fri, 16 Nov 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/GUI/xasy2asy.py
+ M /trunk/asymptote/GUI/xasyMainWin.py
+ M /trunk/asymptote/runtime.in
+
+Limit maximum number of command-line arguments to ghostscript; render in blocks.
+
+------------------------------------------------------------------------
+r2894 | oshardt | 2007-11-14 21:10:57 -0700 (Wed, 14 Nov 2007) | 1 line
+Changed paths:
+ M /trunk/asymptote/GUI/xasyMainWin.py
+
+Improve handling of zoom slider.
+------------------------------------------------------------------------
+r2893 | jcbowman | 2007-11-14 20:25:31 -0700 (Wed, 14 Nov 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/patches/TkAlpha-Imaging-1.1.6.patch
+
+Move declarations.
+
+------------------------------------------------------------------------
+r2892 | jcbowman | 2007-11-14 17:52:35 -0700 (Wed, 14 Nov 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/patches/TkAlpha-Imaging-1.1.6.patch
+
+Remove unnecessary Tk_PhotoBlank call.
+
+------------------------------------------------------------------------
+r2891 | jcbowman | 2007-11-13 23:53:42 -0700 (Tue, 13 Nov 2007) | 3 lines
+Changed paths:
+ M /trunk/asymptote/patches/TkAlpha-Imaging-1.1.6.patch
+
+Add PIL_BACKGROUND and PIL_MAX_ALPHA_AREA environment variables for efficient
+alpha channel rendering.
+
+------------------------------------------------------------------------
+r2890 | jcbowman | 2007-11-13 20:03:45 -0700 (Tue, 13 Nov 2007) | 3 lines
+Changed paths:
+ M /trunk/asymptote/patches/TkAlpha-Imaging-1.1.6.patch
+
+Enable full alpha channel support only for objects of area < 10000 pixels,
+due to slow Tk alpha channel rendering.
+
+------------------------------------------------------------------------
+r2889 | oshardt | 2007-11-13 11:48:04 -0700 (Tue, 13 Nov 2007) | 1 line
+Changed paths:
+ M /trunk/asymptote/GUI/xasyMainWin.py
+
+Prevent redraw of canvas when zoom handler is invoked but magnification is not changed.
+------------------------------------------------------------------------
+r2888 | jcbowman | 2007-11-13 01:20:36 -0700 (Tue, 13 Nov 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/patches/README
+ M /trunk/asymptote/patches/TkAlpha-Imaging-1.1.6.patch
+
+A much better fix for PIL antialiasing and transparency that renders quickly.
+
+------------------------------------------------------------------------
+r2887 | oshardt | 2007-11-12 17:57:08 -0700 (Mon, 12 Nov 2007) | 1 line
+Changed paths:
+ M /trunk/asymptote/GUI/xasy2asy.py
+ M /trunk/asymptote/GUI/xasyMainWin.py
+
+Fix rotation to take into consideration the current magnification
+------------------------------------------------------------------------
+r2886 | oshardt | 2007-11-12 15:22:05 -0700 (Mon, 12 Nov 2007) | 1 line
+Changed paths:
+ M /trunk/asymptote/GUI/xasy2asy.py
+
+Fix error in handling of magnification in scripts
+------------------------------------------------------------------------
+r2885 | jcbowman | 2007-11-12 14:50:58 -0700 (Mon, 12 Nov 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/GUI/xasy2asy.py
+
+Use full precision constants.
+
+------------------------------------------------------------------------
+r2884 | oshardt | 2007-11-12 14:35:20 -0700 (Mon, 12 Nov 2007) | 1 line
+Changed paths:
+ M /trunk/asymptote/GUI/xasy.py
+ M /trunk/asymptote/GUI/xasy2asy.py
+ M /trunk/asymptote/GUI/xasyActions.py
+ M /trunk/asymptote/GUI/xasyMainWin.py
+
+Implement magnification option and zoom feature
+------------------------------------------------------------------------
+r2883 | jcbowman | 2007-11-12 00:28:55 -0700 (Mon, 12 Nov 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/drawlabel.cc
+ M /trunk/asymptote/lexical.h
+
+Replace locale-dependent call to atof() with locale-independent lexical::cast().
+
+------------------------------------------------------------------------
+r2882 | jcbowman | 2007-11-11 22:37:20 -0700 (Sun, 11 Nov 2007) | 4 lines
+Changed paths:
+ M /trunk/asymptote/GUI/xasy2asy.py
+ M /trunk/asymptote/base/plain_xasy.asy
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/picture.cc
+ M /trunk/asymptote/picture.h
+ M /trunk/asymptote/runtime.in
+ M /trunk/asymptote/settings.cc
+
+Speed up GUI deconstruction.
+
+Make "png" the default value of xformat.
+
+------------------------------------------------------------------------
+r2881 | oshardt | 2007-11-11 20:54:28 -0700 (Sun, 11 Nov 2007) | 1 line
+Changed paths:
+ M /trunk/asymptote/GUI/xasyActions.py
+
+Removed debugging information
+------------------------------------------------------------------------
+r2880 | jcbowman | 2007-11-07 22:01:26 -0700 (Wed, 07 Nov 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/plain_paths.asy
+
+Update intersectionspoints.
+
+------------------------------------------------------------------------
+r2879 | jcbowman | 2007-11-07 22:00:15 -0700 (Wed, 07 Nov 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+
+Update documentation.
+
+------------------------------------------------------------------------
+r2878 | jcbowman | 2007-11-07 21:35:19 -0700 (Wed, 07 Nov 2007) | 4 lines
+Changed paths:
+ M /trunk/asymptote/base/three.asy
+ M /trunk/asymptote/path.cc
+ M /trunk/asymptote/runtime.in
+
+Fix bug in intersections.
+
+Add optional fuzz parameter to intersections and intersectionpoints.
+
+------------------------------------------------------------------------
+r2877 | jcbowman | 2007-11-07 21:03:14 -0700 (Wed, 07 Nov 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/plain_strings.asy
+ M /trunk/asymptote/doc/asymptote.texi
+
+Add string[] split(string s, string delimiter).
+
+------------------------------------------------------------------------
+r2876 | jcbowman | 2007-11-04 21:25:35 -0700 (Sun, 04 Nov 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/interact.cc
+ M /trunk/asymptote/interact.h
+ M /trunk/asymptote/runtime.in
+ M /trunk/asymptote/settings.cc
+
+Disable readline history when reading from a pipe.
+
+------------------------------------------------------------------------
+r2875 | jcbowman | 2007-11-04 20:23:02 -0700 (Sun, 04 Nov 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+
+Update discussion of MSWindows configuration variables.
+
+------------------------------------------------------------------------
+r2874 | jcbowman | 2007-11-04 20:13:34 -0700 (Sun, 04 Nov 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/Makefile.in
+ D /trunk/asymptote/asyconsole.bat
+ M /trunk/asymptote/asymptote.nsi
+
+More windows installation fixes.
+
+------------------------------------------------------------------------
+r2873 | jcbowman | 2007-11-04 15:52:41 -0700 (Sun, 04 Nov 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/main.cc
+
+Make interactive mode exit with a zero return code.
+
+------------------------------------------------------------------------
+r2872 | jcbowman | 2007-11-04 15:27:28 -0700 (Sun, 04 Nov 2007) | 4 lines
+Changed paths:
+ M /trunk/asymptote/asyconsole.bat
+ M /trunk/asymptote/asymptote.nsi
+
+Fix Windows uninstall.
+
+Remove hard-wired path.
+
+------------------------------------------------------------------------
+r2871 | jcbowman | 2007-11-04 09:48:27 -0700 (Sun, 04 Nov 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/builtin.cc
+
+Add missing function.
+
+------------------------------------------------------------------------
+r2870 | jcbowman | 2007-11-03 16:50:29 -0600 (Sat, 03 Nov 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/arrayop.h
+ M /trunk/asymptote/builtin.cc
+
+Add real[] abs(pair[]) and real[] abs(triple[]) functions.
+
+------------------------------------------------------------------------
+r2869 | oshardt | 2007-11-03 12:24:00 -0600 (Sat, 03 Nov 2007) | 1 line
+Changed paths:
+ M /trunk/asymptote/GUI/xasyExample.asy
+
+Revert change to example.
+------------------------------------------------------------------------
+r2868 | oshardt | 2007-11-03 12:05:23 -0600 (Sat, 03 Nov 2007) | 1 line
+Changed paths:
+ M /trunk/asymptote/GUI/xasyExample.asy
+ M /trunk/asymptote/GUI/xasyMainWin.py
+
+Prompt user before opening a file if current document was modified.
+------------------------------------------------------------------------
+r2867 | jcbowman | 2007-11-02 23:09:45 -0600 (Fri, 02 Nov 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/Makefile.in
+ M /trunk/asymptote/asyconsole.bat
+ M /trunk/asymptote/asymptote.nsi
+ M /trunk/asymptote/asymptote.spec
+
+Add windows installation fixes.
+
+------------------------------------------------------------------------
+r2866 | jcbowman | 2007-11-02 16:13:23 -0600 (Fri, 02 Nov 2007) | 2 lines
+Changed paths:
+ A /trunk/asymptote/asyconsole.bat
+ M /trunk/asymptote/asymptote.nsi
+ M /trunk/asymptote/asymptote.spec
+
+Windows installation tweaks.
+
+------------------------------------------------------------------------
+r2865 | jcbowman | 2007-11-02 10:48:05 -0600 (Fri, 02 Nov 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/three.asy
+
+Handle degenerate reference vectors.
+
+------------------------------------------------------------------------
+r2864 | jcbowman | 2007-10-28 13:31:35 -0600 (Sun, 28 Oct 2007) | 3 lines
+Changed paths:
+ M /trunk/asymptote/base/three.asy
+
+Project all reference contributions in direction of maximum contribution,
+for numerical robustness.
+
+------------------------------------------------------------------------
+r2863 | jcbowman | 2007-10-28 12:16:24 -0600 (Sun, 28 Oct 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/three.asy
+ M /trunk/asymptote/doc/westnile.asy
+
+Improve reference vector calculation.
+
+------------------------------------------------------------------------
+r2862 | jcbowman | 2007-10-26 11:29:19 -0600 (Fri, 26 Oct 2007) | 3 lines
+Changed paths:
+ M /trunk/asymptote/fileio.cc
+
+Respect comments and double quotation marks in whitespace mode (just like
+cvs mode).
+
+------------------------------------------------------------------------
+r2861 | hammera | 2007-10-25 22:19:32 -0600 (Thu, 25 Oct 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/fundec.cc
+
+Test for invalid defvals in rest parameters.
+
+------------------------------------------------------------------------
+r2860 | hammera | 2007-10-25 22:01:21 -0600 (Thu, 25 Oct 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/fundec.cc
+ M /trunk/asymptote/fundec.h
+
+Removed unused code.
+
+------------------------------------------------------------------------
+r2859 | jcbowman | 2007-10-22 10:38:21 -0600 (Mon, 22 Oct 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/graph.asy
+ M /trunk/asymptote/doc/asymptote.texi
+
+Re-enable automatic logarithmic axis coverage routine.
+
+------------------------------------------------------------------------
+r2858 | jcbowman | 2007-10-19 22:55:13 -0600 (Fri, 19 Oct 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/pipestream.h
+
+Exit more gracefully under MSDOS when execvp fails.
+
+------------------------------------------------------------------------
+r2857 | jcbowman | 2007-10-19 21:34:04 -0600 (Fri, 19 Oct 2007) | 7 lines
+Changed paths:
+ M /trunk/asymptote/arrayop.h
+ M /trunk/asymptote/base/plain_paths.asy
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/path.cc
+ M /trunk/asymptote/runtime.in
+
+Implement firstcut and lastcut reliably in terms of a general cut(path p, path
+knife, int n) routine based on intersections.
+
+Increase the duplicate point detection fuzz.
+
+Automatically sort the array returned by intersections.
+
+------------------------------------------------------------------------
+r2856 | jcbowman | 2007-10-18 15:03:38 -0600 (Thu, 18 Oct 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/Makefile.in
+ M /trunk/asymptote/patches/README
+ A /trunk/asymptote/patches/gc-7.0nomem.patch
+
+Add patch to avoid segmentation fault with gc-7.0 on out-of-memory error.
+
+------------------------------------------------------------------------
+r2855 | jcbowman | 2007-10-18 14:15:53 -0600 (Thu, 18 Oct 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/runtime.in
+
+Make history() return the entire stored interactive history.
+
+------------------------------------------------------------------------
+r2854 | hammera | 2007-10-17 20:04:02 -0600 (Wed, 17 Oct 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/interact.cc
+ M /trunk/asymptote/process.cc
+
+Fix adding of automatic semicolons to the history.
+
+------------------------------------------------------------------------
+r2853 | hammera | 2007-10-17 19:59:11 -0600 (Wed, 17 Oct 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/TODO
+
+Fix default args for rest args.
+
+------------------------------------------------------------------------
+r2852 | jcbowman | 2007-10-16 22:05:12 -0600 (Tue, 16 Oct 2007) | 4 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/interact.cc
+ M /trunk/asymptote/process.cc
+ M /trunk/asymptote/runtime.in
+
+Add a routine history(int n=1) that returns the interactive history.
+
+Store auto-terminated lines in the interactive history.
+
+------------------------------------------------------------------------
+r2851 | jcbowman | 2007-10-15 09:42:00 -0600 (Mon, 15 Oct 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/graph.asy
+
+Try to use a smaller Step adjustment.
+
+------------------------------------------------------------------------
+r2850 | jcbowman | 2007-10-15 00:12:30 -0600 (Mon, 15 Oct 2007) | 4 lines
+Changed paths:
+ M /trunk/asymptote/asymptote.nsi
+ M /trunk/asymptote/asymptote.spec
+ M /trunk/asymptote/settings.cc
+
+Fix Asymptote path for MSWindows.
+
+Make uninstall remove Xasy start menu shortcut.
+
+------------------------------------------------------------------------
+r2849 | jcbowman | 2007-10-14 22:43:33 -0600 (Sun, 14 Oct 2007) | 2 lines
+Changed paths:
+ A /trunk/asymptote/asymptote.nsi
+
+Add Nullsoft installation script for MSWindows.
+
+------------------------------------------------------------------------
+r2848 | jcbowman | 2007-10-14 22:35:13 -0600 (Sun, 14 Oct 2007) | 3 lines
+Changed paths:
+ M /trunk/asymptote/settings.cc
+
+Under MSWindows, look for asy files in installation path instead of in
+uninstall path.
+
+------------------------------------------------------------------------
+r2847 | jcbowman | 2007-10-14 22:24:27 -0600 (Sun, 14 Oct 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/graph.asy
+
+Try to use at least two major ticks.
+
+------------------------------------------------------------------------
+r2846 | jcbowman | 2007-10-14 21:15:41 -0600 (Sun, 14 Oct 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/slide.asy
+
+Fix title("").
+
+------------------------------------------------------------------------
+r2845 | jcbowman | 2007-10-11 12:22:12 -0600 (Thu, 11 Oct 2007) | 1 line
+Changed paths:
+ M /trunk/asymptote/asymptote.spec
+ M /trunk/asymptote/configure.ac
+
+Increment version to 1.37svn.
+------------------------------------------------------------------------
+r2844 | jcbowman | 2007-10-11 11:31:34 -0600 (Thu, 11 Oct 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/drawgrestore.h
+ M /trunk/asymptote/drawgsave.h
+ M /trunk/asymptote/drawverbatim.h
+
+Fix bugs in tex(), postscript(), gsave(), and grestore() commands.
+
+------------------------------------------------------------------------
+r2843 | jcbowman | 2007-10-11 03:15:48 -0600 (Thu, 11 Oct 2007) | 1 line
+Changed paths:
+ M /trunk/asymptote/configure.ac
+
+Increment version to 1.36svn.
+------------------------------------------------------------------------
+r2842 | jcbowman | 2007-10-11 02:21:31 -0600 (Thu, 11 Oct 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/asymptote.spec
+ M /trunk/asymptote/drawpath.cc
+ M /trunk/asymptote/psfile.cc
+
+Fix numeric formatting of setdash arguments.
+
+------------------------------------------------------------------------
+r2841 | jcbowman | 2007-10-11 01:21:58 -0600 (Thu, 11 Oct 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/solids.asy
+
+Work around hang in intersect for nearly identical paths by adding some fuzz.
+
+------------------------------------------------------------------------
+r2840 | jcbowman | 2007-10-11 00:44:58 -0600 (Thu, 11 Oct 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/configure.ac
+
+Increment version to 1.35svn.
+
+------------------------------------------------------------------------
+r2839 | jcbowman | 2007-10-10 22:44:16 -0600 (Wed, 10 Oct 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/builtin.cc
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/mathop.h
+ M /trunk/asymptote/util.h
+ M /trunk/asymptote/xstream.h
+
+Add Cygwin fixes.
+
+------------------------------------------------------------------------
+r2838 | jcbowman | 2007-10-10 15:17:31 -0600 (Wed, 10 Oct 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+
+Update GUI documentation.
+
+------------------------------------------------------------------------
+r2837 | jcbowman | 2007-10-10 10:59:03 -0600 (Wed, 10 Oct 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/Makefile.in
+
+Make xasy a relative symbolic link.
+
+------------------------------------------------------------------------
+r2836 | jcbowman | 2007-10-10 09:00:51 -0600 (Wed, 10 Oct 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/asymptote.spec
+
+Update xasy file name.
+
+------------------------------------------------------------------------
+r2835 | jcbowman | 2007-10-10 08:42:59 -0600 (Wed, 10 Oct 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/Makefile.in
+
+Fix typo.
+
+------------------------------------------------------------------------
+r2834 | jcbowman | 2007-10-10 08:36:32 -0600 (Wed, 10 Oct 2007) | 2 lines
+Changed paths:
+ D /trunk/asymptote/GUI/xasy
+ A /trunk/asymptote/GUI/xasy.py (from /trunk/asymptote/GUI/xasy:2831)
+ M /trunk/asymptote/Makefile.in
+ M /trunk/asymptote/base/plain_xasy.asy
+ R /trunk/asymptote/xasy
+
+Install xasy and associated files.
+
+------------------------------------------------------------------------
+r2833 | jcbowman | 2007-10-09 22:12:51 -0600 (Tue, 09 Oct 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/asymptote.spec
+
+Update xasy location.
+
+------------------------------------------------------------------------
+r2832 | jcbowman | 2007-10-09 22:00:32 -0600 (Tue, 09 Oct 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/pstoedit.asy
+
+Remove obsolete reference to settings.deconstruct.
+
+------------------------------------------------------------------------
+r2831 | jcbowman | 2007-10-09 21:43:53 -0600 (Tue, 09 Oct 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/plain_markers.asy
+ M /trunk/asymptote/base/plain_xasy.asy
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/examples/jump.asy
+
+Replace opendot with filltype argument of UnFill to dot routines.
+
+------------------------------------------------------------------------
+r2830 | jcbowman | 2007-10-09 15:51:51 -0600 (Tue, 09 Oct 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/picture.cc
+
+Remove intermediate eps files in inline pdf mode.
+
+------------------------------------------------------------------------
+r2829 | jcbowman | 2007-10-09 15:05:23 -0600 (Tue, 09 Oct 2007) | 5 lines
+Changed paths:
+ M /trunk/asymptote/base/plain_paths.asy
+ M /trunk/asymptote/base/three.asy
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/path.cc
+ M /trunk/asymptote/path.h
+ M /trunk/asymptote/path3.cc
+ M /trunk/asymptote/runtime.in
+
+Implement an improved, robust version of intersect.
+
+Implement intersectionpoints in terms of a new more efficient and robust
+intersections routine.
+
+------------------------------------------------------------------------
+r2828 | jcbowman | 2007-10-09 15:01:41 -0600 (Tue, 09 Oct 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/histogram.asy
+ M /trunk/asymptote/doc/legend.asy
+ M /trunk/asymptote/doc/lineargraph0.asy
+
+Add trailingzero tick format.
+
+------------------------------------------------------------------------
+r2827 | jcbowman | 2007-10-07 11:00:47 -0600 (Sun, 07 Oct 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/drawclipbegin.h
+ M /trunk/asymptote/drawclipend.h
+ M /trunk/asymptote/drawelement.h
+ M /trunk/asymptote/drawlabel.cc
+ M /trunk/asymptote/drawlabel.h
+ M /trunk/asymptote/picture.cc
+
+Make r2785 changes work with deconstruct.
+
+------------------------------------------------------------------------
+r2826 | jcbowman | 2007-10-05 21:03:57 -0600 (Fri, 05 Oct 2007) | 4 lines
+Changed paths:
+ M /trunk/asymptote/base/graph.asy
+ M /trunk/asymptote/base/plain_strings.asy
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/doc/lineargraph.asy
+ M /trunk/asymptote/doc/parametricgraph.asy
+
+Adjust defaultformat for axes to make tick labels unique.
+
+Add general trailingzero format string; update examples.
+
+------------------------------------------------------------------------
+r2825 | jcbowman | 2007-10-03 14:22:52 -0600 (Wed, 03 Oct 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/graph.asy
+
+Improve autoscaling of graphs for close minimum and maximum values.
+
+------------------------------------------------------------------------
+r2824 | jcbowman | 2007-09-28 12:31:44 -0600 (Fri, 28 Sep 2007) | 2 lines
+Changed paths:
+ A /trunk/asymptote/examples/jump.asy
+
+Add example of opendot.
+
+------------------------------------------------------------------------
+r2823 | jcbowman | 2007-09-28 12:19:18 -0600 (Fri, 28 Sep 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/plain_markers.asy
+
+Add opendot routines.
+
+------------------------------------------------------------------------
+r2822 | hammera | 2007-09-24 21:11:00 -0600 (Mon, 24 Sep 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/fileio.h
+ M /trunk/asymptote/picture.cc
+ M /trunk/asymptote/process.cc
+ M /trunk/asymptote/process.h
+ M /trunk/asymptote/runtime.in
+ M /trunk/asymptote/texfile.cc
+ M /trunk/asymptote/texfile.h
+
+Changed global.back()-> to processData().
+
+------------------------------------------------------------------------
+r2821 | pivaldi | 2007-09-24 11:20:27 -0600 (Mon, 24 Sep 2007) | 1 line
+Changed paths:
+ M /trunk/asymptote/base/asy-mode.el
+
+Defer hard coded commands and options to variables.
+------------------------------------------------------------------------
+r2820 | jcbowman | 2007-09-23 10:45:41 -0600 (Sun, 23 Sep 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/picture.h
+ M /trunk/asymptote/runtime.in
+
+Fix shipout bug.
+
+------------------------------------------------------------------------
+r2819 | jcbowman | 2007-09-21 10:17:43 -0600 (Fri, 21 Sep 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/GUI/xasy2asy.py
+
+Remove obsolete -q option.
+
+------------------------------------------------------------------------
+r2818 | jcbowman | 2007-09-20 22:27:59 -0600 (Thu, 20 Sep 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/pen.h
+
+Change default LaTeX font to package-dependent setting.
+
+------------------------------------------------------------------------
+r2817 | jcbowman | 2007-09-19 21:46:56 -0600 (Wed, 19 Sep 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/configure.ac
+ M /trunk/asymptote/settings.cc
+
+Add modification of ncurses patch from mvid.
+
+------------------------------------------------------------------------
+r2816 | jcbowman | 2007-09-18 00:10:58 -0600 (Tue, 18 Sep 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/path.cc
+ M /trunk/asymptote/path.h
+ M /trunk/asymptote/path3.cc
+ M /trunk/asymptote/simpson.cc
+
+Avoid nesting capacity overflows in arctime.
+
+------------------------------------------------------------------------
+r2815 | jcbowman | 2007-09-16 20:57:35 -0600 (Sun, 16 Sep 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/runtime.in
+
+Add new magnification argument to shipout.
+
+------------------------------------------------------------------------
+r2814 | jcbowman | 2007-09-16 20:48:23 -0600 (Sun, 16 Sep 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/camperror.cc
+
+Make reportWarning generate a warning message only.
+
+------------------------------------------------------------------------
+r2813 | jcbowman | 2007-09-16 20:42:53 -0600 (Sun, 16 Sep 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/fileio.cc
+
+Ignore spurious final blank line when reading strings.
+
+------------------------------------------------------------------------
+r2812 | jcbowman | 2007-09-16 11:44:00 -0600 (Sun, 16 Sep 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/fileio.cc
+ M /trunk/asymptote/fileio.h
+
+Fix string csv reads.
+
+------------------------------------------------------------------------
+r2811 | jcbowman | 2007-09-15 22:12:21 -0600 (Sat, 15 Sep 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/fileio.cc
+
+Another comment fix for reading strings.
+
+------------------------------------------------------------------------
+r2810 | jcbowman | 2007-09-15 02:42:12 -0600 (Sat, 15 Sep 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/FAQ/asy-faq.bfnn
+
+Fix example.
+
+------------------------------------------------------------------------
+r2809 | jcbowman | 2007-09-15 02:40:06 -0600 (Sat, 15 Sep 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/FAQ/asy-faq.bfnn
+
+Fix typo.
+
+------------------------------------------------------------------------
+r2808 | jcbowman | 2007-09-15 02:38:23 -0600 (Sat, 15 Sep 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/FAQ/asy-faq.bfnn
+ M /trunk/asymptote/doc/asymptote.texi
+
+Fix errors in documentation and FAQ.
+
+------------------------------------------------------------------------
+r2807 | jcbowman | 2007-09-14 16:09:19 -0600 (Fri, 14 Sep 2007) | 4 lines
+Changed paths:
+ D /trunk/asymptote/doc/mosquito.csv
+ M /trunk/asymptote/fileio.cc
+
+Support comments when reading strings in cvs mode.
+
+Remove unused file.
+
+------------------------------------------------------------------------
+r2806 | jcbowman | 2007-09-12 19:42:40 -0600 (Wed, 12 Sep 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/settings.cc
+
+Improve description of interativeWrite.
+
+------------------------------------------------------------------------
+r2805 | hammera | 2007-09-08 11:48:06 -0600 (Sat, 08 Sep 2007) | 4 lines
+Changed paths:
+ M /trunk/asymptote/camp.y
+
+Fixed syntax to allow expressions such as (x);
+
+Based on a patch by Orest Shardt.
+
+------------------------------------------------------------------------
+r2804 | hammera | 2007-09-05 16:53:51 -0600 (Wed, 05 Sep 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/settings.cc
+ M /trunk/asymptote/stm.cc
+
+Added interactiveWrite option.
+
+------------------------------------------------------------------------
+r2803 | jcbowman | 2007-09-04 21:15:41 -0600 (Tue, 04 Sep 2007) | 4 lines
+Changed paths:
+ M /trunk/asymptote/configure.ac
+ M /trunk/asymptote/process.cc
+ M /trunk/asymptote/settings.cc
+
+Remove --enable-cplusplus option.
+
+Remove unused quiet option.
+
+------------------------------------------------------------------------
+r2802 | oshardt | 2007-09-03 12:01:42 -0600 (Mon, 03 Sep 2007) | 1 line
+Changed paths:
+ M /trunk/asymptote/GUI/xasy2asy.py
+ M /trunk/asymptote/GUI/xasyMainWin.py
+
+Implement pen validation
+------------------------------------------------------------------------
+r2801 | jcbowman | 2007-09-02 23:36:10 -0600 (Sun, 02 Sep 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/picture.cc
+ M /trunk/asymptote/picture.h
+ M /trunk/asymptote/runtime.in
+
+Make deconstruct close bboxout file.
+
+------------------------------------------------------------------------
+r2800 | jcbowman | 2007-09-02 23:21:29 -0600 (Sun, 02 Sep 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/GUI/xasyExample.asy
+
+Use indexedTransform constructor.
+
+------------------------------------------------------------------------
+r2799 | oshardt | 2007-09-02 21:01:09 -0600 (Sun, 02 Sep 2007) | 1 line
+Changed paths:
+ M /trunk/asymptote/GUI/xasy2asy.py
+ M /trunk/asymptote/GUI/xasyExample.asy
+ M /trunk/asymptote/GUI/xasyFile.py
+ M /trunk/asymptote/GUI/xasyMainWin.py
+ A /trunk/asymptote/GUI/xasyVersion.py
+
+Make various bug fixes and improvements.
+------------------------------------------------------------------------
+r2798 | oshardt | 2007-09-02 18:07:55 -0600 (Sun, 02 Sep 2007) | 1 line
+Changed paths:
+ M /trunk/asymptote/GUI/xasy2asy.py
+ M /trunk/asymptote/GUI/xasyMainWin.py
+
+Fix documentation request.
+------------------------------------------------------------------------
+r2797 | oshardt | 2007-09-02 17:59:21 -0600 (Sun, 02 Sep 2007) | 1 line
+Changed paths:
+ M /trunk/asymptote/GUI/xasyMainWin.py
+
+Temporarily remove zoom control until feature is implemented.
+------------------------------------------------------------------------
+r2796 | oshardt | 2007-09-02 17:46:34 -0600 (Sun, 02 Sep 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/GUI/xasyMainWin.py
+
+Improved text in dialogs.
+Made the loading and saving of files specified on the command line consistent.
+------------------------------------------------------------------------
+r2795 | jcbowman | 2007-09-01 22:34:02 -0600 (Sat, 01 Sep 2007) | 6 lines
+Changed paths:
+ M /trunk/asymptote/base/plain_picture.asy
+ M /trunk/asymptote/base/plain_xasy.asy
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/picture.cc
+ M /trunk/asymptote/picture.h
+ M /trunk/asymptote/process.h
+ M /trunk/asymptote/runtime.in
+ M /trunk/asymptote/settings.cc
+
+Standardize fillrule argument name.
+
+Add support for magnification.
+
+Remove unused code.
+
+------------------------------------------------------------------------
+r2794 | hammera | 2007-08-31 20:16:17 -0600 (Fri, 31 Aug 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/entry.cc
+ M /trunk/asymptote/entry.h
+
+Fixed bug regarding permission lists of types.
+
+------------------------------------------------------------------------
+r2793 | hammera | 2007-08-31 20:15:41 -0600 (Fri, 31 Aug 2007) | 3 lines
+Changed paths:
+ M /trunk/asymptote/dec.cc
+
+Corrected documentation.
+
+
+------------------------------------------------------------------------
+r2792 | hammera | 2007-08-31 20:15:16 -0600 (Fri, 31 Aug 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/parser.cc
+ M /trunk/asymptote/parser.h
+
+Made parameter name more descriptive.
+
+------------------------------------------------------------------------
+r2791 | jcbowman | 2007-08-31 08:35:08 -0600 (Fri, 31 Aug 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/FAQ/asy-faq.bfnn
+
+Use unique keys.
+
+------------------------------------------------------------------------
+r2790 | jcbowman | 2007-08-30 20:15:48 -0600 (Thu, 30 Aug 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/configure.ac
+
+Check for libcurses only if libncurses is not found.
+
+------------------------------------------------------------------------
+r2789 | jcbowman | 2007-08-29 13:56:57 -0600 (Wed, 29 Aug 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/GUI/xasy2asy.py
+ M /trunk/asymptote/GUI/xasyFile.py
+ M /trunk/asymptote/asymptote.spec
+ M /trunk/asymptote/base/plain_xasy.asy
+
+Use constructor for indexedTransform.
+
+------------------------------------------------------------------------
+r2788 | jcbowman | 2007-08-29 11:22:33 -0600 (Wed, 29 Aug 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/plain_shipout.asy
+ M /trunk/asymptote/base/plain_xasy.asy
+
+Fix shipout when inXasyMode is true.
+
+------------------------------------------------------------------------
+r2787 | oshardt | 2007-08-29 09:15:31 -0600 (Wed, 29 Aug 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/GUI/UndoRedoStack.py
+ M /trunk/asymptote/GUI/xasyMainWin.py
+
+Fix logic for recognizing modified files.
+Correct the logic for querying user about exporting modified files.
+------------------------------------------------------------------------
+r2786 | jcbowman | 2007-08-29 08:54:00 -0600 (Wed, 29 Aug 2007) | 3 lines
+Changed paths:
+ M /trunk/asymptote/drawclipbegin.h
+ M /trunk/asymptote/drawclipend.h
+ M /trunk/asymptote/psfile.h
+ M /trunk/asymptote/texfile.cc
+ M /trunk/asymptote/texfile.h
+
+Revert to gsave/grestore instead of clipsave/cliprestore due to pen caching
+assumptions.
+
+------------------------------------------------------------------------
+r2785 | jcbowman | 2007-08-28 09:30:26 -0600 (Tue, 28 Aug 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/drawclipbegin.h
+ M /trunk/asymptote/drawclipend.h
+ M /trunk/asymptote/texfile.cc
+
+Enclose tex clip within picture environment to avoid unwanted page breaks.
+
+------------------------------------------------------------------------
+r2784 | oshardt | 2007-08-27 15:48:38 -0600 (Mon, 27 Aug 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/GUI/xasyMainWin.py
+
+Prevent switching editing mode during incomplete drawing operation.
+Search for file with .asy extension if no .asy extension provided.
+------------------------------------------------------------------------
+r2783 | pivaldi | 2007-08-27 15:33:06 -0600 (Mon, 27 Aug 2007) | 1 line
+Changed paths:
+ M /trunk/asymptote/base/markers.asy
+
+markers.asy: compute golden mean in a static variable.
+------------------------------------------------------------------------
+r2782 | oshardt | 2007-08-27 15:23:17 -0600 (Mon, 27 Aug 2007) | 1 line
+Changed paths:
+ M /trunk/asymptote/GUI/xasy2asy.py
+ M /trunk/asymptote/GUI/xasyExample.asy
+
+Remove unneeded whitespace.
+------------------------------------------------------------------------
+r2781 | jcbowman | 2007-08-27 11:56:33 -0600 (Mon, 27 Aug 2007) | 6 lines
+Changed paths:
+ M /trunk/asymptote/GUI/xasyMainWin.py
+ M /trunk/asymptote/base/patterns.asy
+ M /trunk/asymptote/base/plain_shipout.asy
+ M /trunk/asymptote/base/plain_xasy.asy
+ M /trunk/asymptote/doc/asymptote.texi
+ R /trunk/asymptote/xasy
+
+Rename patterns to currentpatterns.
+
+Remove preamble option from shipout for consistency with xasy.
+
+Make explicit shipouts with options work with xasy.
+
+------------------------------------------------------------------------
+r2780 | jcbowman | 2007-08-27 10:33:40 -0600 (Mon, 27 Aug 2007) | 2 lines
+Changed paths:
+ A /trunk/asymptote/GUI/xasy (from /trunk/asymptote/GUI/xasy.py:2778)
+ D /trunk/asymptote/GUI/xasy.py
+ M /trunk/asymptote/GUI/xasyBezierEditor.py
+
+Rename xasy.py to xasy.
+
+------------------------------------------------------------------------
+r2779 | jcbowman | 2007-08-27 10:24:23 -0600 (Mon, 27 Aug 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/GUI/xasyExample.asy
+
+Update example.
+
+------------------------------------------------------------------------
+r2778 | pivaldi | 2007-08-26 19:13:14 -0600 (Sun, 26 Aug 2007) | 1 line
+Changed paths:
+ M /trunk/asymptote/base/markers.asy
+
+marker.asy: uniformize marker sizes and notation.
+------------------------------------------------------------------------
+r2777 | jcbowman | 2007-08-26 15:40:25 -0600 (Sun, 26 Aug 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+
+Explain how map is a special case of sequence.
+
+------------------------------------------------------------------------
+r2776 | jcbowman | 2007-08-26 13:28:09 -0600 (Sun, 26 Aug 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+
+Fix documentation of map.
+
+------------------------------------------------------------------------
+r2775 | jcbowman | 2007-08-24 11:00:05 -0600 (Fri, 24 Aug 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/picture.cc
+
+Simplify logic.
+
+------------------------------------------------------------------------
+r2774 | jcbowman | 2007-08-24 10:59:42 -0600 (Fri, 24 Aug 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/process.cc
+
+Make asy -o /dir/ file.asy output to /dir/file.eps.
+
+------------------------------------------------------------------------
+r2773 | jcbowman | 2007-08-16 08:23:05 -0600 (Thu, 16 Aug 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/extra/intro.asy
+
+Add discussion of 3D generalization of Hobby's algorithm.
+
+------------------------------------------------------------------------
+r2772 | jcbowman | 2007-08-14 04:39:42 -0600 (Tue, 14 Aug 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/graph.asy
+ M /trunk/asymptote/base/graph3.asy
+ M /trunk/asymptote/base/solids.asy
+
+Avoid evaluating function outside of [a,b] (due to finite numerical precision).
+
+------------------------------------------------------------------------
+r2771 | jcbowman | 2007-08-14 02:15:00 -0600 (Tue, 14 Aug 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+
+Fix accent.
+
+------------------------------------------------------------------------
+r2770 | jcbowman | 2007-08-11 04:01:15 -0600 (Sat, 11 Aug 2007) | 4 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.sty
+ M /trunk/asymptote/doc/asymptote.texi
+
+Use \PackageWarning instead of \message.
+
+Update list of contributors.
+
+------------------------------------------------------------------------
+r2769 | oshardt | 2007-08-09 12:13:42 -0600 (Thu, 09 Aug 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/GUI/xasyMainWin.py
+
+Use askopenfilename() instead of askopenfile()
+Use asksaveasfilename() instead of asksaveasfile()
+------------------------------------------------------------------------
+r2768 | oshardt | 2007-08-09 11:00:42 -0600 (Thu, 09 Aug 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/GUI/xasyMainWin.py
+
+Disabled tear-offs for improved crossplatform look and feel
+User is now asked about saving changes when closing a modified file
+------------------------------------------------------------------------
+r2767 | jcbowman | 2007-08-09 02:59:28 -0600 (Thu, 09 Aug 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/plain_shipout.asy
+ M /trunk/asymptote/runtime.in
+ M /trunk/asymptote/settings.cc
+
+Remove old GUI transform support.
+
+------------------------------------------------------------------------
+r2766 | jcbowman | 2007-08-09 02:34:50 -0600 (Thu, 09 Aug 2007) | 8 lines
+Changed paths:
+ M /trunk/asymptote/base/plain_filldraw.asy
+ M /trunk/asymptote/drawclipbegin.h
+ M /trunk/asymptote/drawclipend.h
+ M /trunk/asymptote/drawelement.h
+ M /trunk/asymptote/picture.cc
+ M /trunk/asymptote/psfile.cc
+ M /trunk/asymptote/psfile.h
+ M /trunk/asymptote/runtime.in
+ M /trunk/asymptote/settings.cc
+ M /trunk/asymptote/texfile.cc
+ M /trunk/asymptote/texfile.h
+
+Add -level option to specify PostScript level (default 3).
+
+Use more efficient clipsave/cliprestore commands with -level 3.
+
+Optimize printer stack use by pruning unneeded clipsave/cliprestore commands.
+
+Avoid nesting of clipsave/cliprestore commands when using UnFill.
+
+------------------------------------------------------------------------
+r2765 | oshardt | 2007-08-07 11:26:04 -0600 (Tue, 07 Aug 2007) | 1 line
+Changed paths:
+ M /trunk/asymptote/GUI/xasy2asy.py
+ M /trunk/asymptote/GUI/xasyActions.py
+ M /trunk/asymptote/GUI/xasyMainWin.py
+
+Changing the current pen's properties affects selected items
+------------------------------------------------------------------------
+r2764 | jcbowman | 2007-08-07 03:24:10 -0600 (Tue, 07 Aug 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/mathop.h
+ M /trunk/asymptote/runtime.in
+
+Compute pair^int by repeated multiplication, just like real^int.
+
+------------------------------------------------------------------------
+r2763 | oshardt | 2007-08-01 09:39:08 -0600 (Wed, 01 Aug 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/plain_shipout.asy
+ M /trunk/asymptote/base/plain_xasy.asy
+ M /trunk/asymptote/interact.cc
+ M /trunk/asymptote/runtime.in
+
+Removed signals for xasy
+Switched from GUIop to xformStack in shipout()
+------------------------------------------------------------------------
+r2762 | oshardt | 2007-07-31 15:05:37 -0600 (Tue, 31 Jul 2007) | 8 lines
+Changed paths:
+ M /trunk/asymptote/GUI/UndoRedoStack.py
+ M /trunk/asymptote/GUI/xasy2asy.py
+ M /trunk/asymptote/GUI/xasyActions.py
+ M /trunk/asymptote/GUI/xasyBezierEditor.py
+ M /trunk/asymptote/GUI/xasyFile.py
+ M /trunk/asymptote/GUI/xasyMainWin.py
+
+Fixed bugs in undo/redo
+Allowed nested begin/end actionGroups in UndoRedoStack
+Added forceAddition option to drawOnCanvas
+Added exitXasyMode() to end of files
+Implemented undo/redo for single item in a script
+Implemented undo/redo for clearing of an item's transforms
+Implemented undo/redo for drawing and deletion of a drawn item
+Implemented undo/redo for modification of a drawn item
+------------------------------------------------------------------------
+r2761 | oshardt | 2007-07-30 15:09:11 -0600 (Mon, 30 Jul 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/GUI/xasyActions.py
+ M /trunk/asymptote/GUI/xasyMainWin.py
+
+Added undo/redo for creation and editing of script items
+Added undo/redo for raising and lowering of items
+------------------------------------------------------------------------
+r2760 | oshardt | 2007-07-30 12:12:29 -0600 (Mon, 30 Jul 2007) | 3 lines
+Changed paths:
+ M /trunk/asymptote/GUI/xasy.py
+ M /trunk/asymptote/GUI/xasyActions.py
+ M /trunk/asymptote/GUI/xasyBezierEditor.py
+ M /trunk/asymptote/GUI/xasyCodeEditor.py
+ M /trunk/asymptote/GUI/xasyColorPicker.py
+ M /trunk/asymptote/GUI/xasyFile.py
+ M /trunk/asymptote/GUI/xasyMainWin.py
+ M /trunk/asymptote/GUI/xasyOptions.py
+ M /trunk/asymptote/GUI/xasyOptionsDialog.py
+
+Updated headers
+Modified method for storing undo/redo information for translations
+Implemented undo/redo for addition and modification of labels
+------------------------------------------------------------------------
+r2759 | jcbowman | 2007-07-29 17:22:45 -0600 (Sun, 29 Jul 2007) | 1 line
+Changed paths:
+ M /trunk/asymptote/configure.ac
+
+Increment version to 1.34svn.
+------------------------------------------------------------------------
+r2758 | jcbowman | 2007-07-29 10:25:12 -0600 (Sun, 29 Jul 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/picture.cc
+ M /trunk/asymptote/psfile.h
+ M /trunk/asymptote/settings.cc
+
+Fix interactive viewing.
+
+------------------------------------------------------------------------
+r2757 | jcbowman | 2007-07-29 03:29:03 -0600 (Sun, 29 Jul 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/xstream.h
+
+Remove extraneous preprocessor definitions.
+
+------------------------------------------------------------------------
+r2756 | jcbowman | 2007-07-29 02:36:43 -0600 (Sun, 29 Jul 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/configure.ac
+ M /trunk/asymptote/doc/Makefile.in
+ M /trunk/asymptote/xstream.h
+
+Add large file support.
+
+------------------------------------------------------------------------
+r2755 | jcbowman | 2007-07-28 13:41:50 -0600 (Sat, 28 Jul 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+
+Update list of contributors.
+
+------------------------------------------------------------------------
+r2754 | jcbowman | 2007-07-28 09:53:06 -0600 (Sat, 28 Jul 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/fileio.h
+
+Open input files in input-only mode.
+
+------------------------------------------------------------------------
+r2753 | jcbowman | 2007-07-28 09:19:07 -0600 (Sat, 28 Jul 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/drawlabel.cc
+
+Allow multiple invocations of labelpath.
+
+------------------------------------------------------------------------
+r2752 | oshardt | 2007-07-27 14:57:14 -0600 (Fri, 27 Jul 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/GUI/xasy2asy.py
+ M /trunk/asymptote/GUI/xasyMainWin.py
+
+Handle case of script that produces no images.
+Remove keyboard bindings for main window when using script editor.
+------------------------------------------------------------------------
+r2751 | oshardt | 2007-07-27 14:38:23 -0600 (Fri, 27 Jul 2007) | 1 line
+Changed paths:
+ M /trunk/asymptote/GUI/xasyMainWin.py
+
+Raising and lowering of script items preserves drawing order of all items in script
+------------------------------------------------------------------------
+r2750 | oshardt | 2007-07-27 14:23:57 -0600 (Fri, 27 Jul 2007) | 1 line
+Changed paths:
+ M /trunk/asymptote/GUI/xasyMainWin.py
+
+Fixed handling of deleted items.
+------------------------------------------------------------------------
+r2749 | jcbowman | 2007-07-27 14:05:08 -0600 (Fri, 27 Jul 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/pair.h
+ M /trunk/asymptote/path.cc
+ M /trunk/asymptote/runtime.in
+
+Work around old broken compilers.
+
+------------------------------------------------------------------------
+r2748 | jcbowman | 2007-07-27 13:13:41 -0600 (Fri, 27 Jul 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/pstoedit.asy
+
+Fix conditional.
+
+------------------------------------------------------------------------
+r2747 | oshardt | 2007-07-27 11:45:34 -0600 (Fri, 27 Jul 2007) | 1 line
+Changed paths:
+ M /trunk/asymptote/GUI/xasy2asy.py
+ M /trunk/asymptote/GUI/xasyMainWin.py
+ M /trunk/asymptote/GUI/xasyOptions.py
+
+Improved handling of missing asymptote executable on windows
+------------------------------------------------------------------------
+r2746 | oshardt | 2007-07-27 10:37:56 -0600 (Fri, 27 Jul 2007) | 1 line
+Changed paths:
+ M /trunk/asymptote/GUI/xasyMainWin.py
+
+Error fixed
+------------------------------------------------------------------------
+r2745 | oshardt | 2007-07-27 10:23:52 -0600 (Fri, 27 Jul 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/GUI/xasyOptions.py
+ M /trunk/asymptote/GUI/xasyOptionsDialog.py
+
+Check registry to find asy installation on windows.
+Add browse button for asy path selection
+------------------------------------------------------------------------
+r2744 | jcbowman | 2007-07-27 10:02:28 -0600 (Fri, 27 Jul 2007) | 4 lines
+Changed paths:
+ M /trunk/asymptote/base/surface.asy
+ A /trunk/asymptote/examples/teapot.asy
+
+Restrict projection bounding box recursion to a depth of 16.
+
+Add teapot example.
+
+------------------------------------------------------------------------
+r2743 | oshardt | 2007-07-27 09:46:58 -0600 (Fri, 27 Jul 2007) | 1 line
+Changed paths:
+ M /trunk/asymptote/base/pstoedit.asy
+
+Syntax fix
+------------------------------------------------------------------------
+r2742 | jcbowman | 2007-07-27 05:24:13 -0600 (Fri, 27 Jul 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/LICENSE
+ M /trunk/asymptote/README
+ M /trunk/asymptote/base/asy-mode.el
+ M /trunk/asymptote/base/binarytree.asy
+ M /trunk/asymptote/base/featpost3D.asy
+ M /trunk/asymptote/fftw++.h
+ M /trunk/asymptote/pipestream.h
+ M /trunk/asymptote/xstream.h
+
+Upgrade licence to GPL-3.0.
+
+------------------------------------------------------------------------
+r2741 | jcbowman | 2007-07-27 03:50:46 -0600 (Fri, 27 Jul 2007) | 6 lines
+Changed paths:
+ M /trunk/asymptote/base/math.asy
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/path.cc
+ M /trunk/asymptote/path.h
+ M /trunk/asymptote/runtime.in
+
+Add complex version of quadraticroots.
+
+Add quartic solver.
+
+Improve accuracy of cubicroots in degenerate cases.
+
+------------------------------------------------------------------------
+r2740 | jcbowman | 2007-07-27 01:26:24 -0600 (Fri, 27 Jul 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/plain_picture.asy
+
+Make min and max return (0,0) for an empty picture.
+
+------------------------------------------------------------------------
+r2739 | jcbowman | 2007-07-27 01:07:31 -0600 (Fri, 27 Jul 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/settings.cc
+
+Add cast; standardize formatting.
+
+------------------------------------------------------------------------
+r2738 | jcbowman | 2007-07-27 01:06:24 -0600 (Fri, 27 Jul 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/pair.h
+
+Add pair sqrt(pair) function (principal branch).
+
+------------------------------------------------------------------------
+r2737 | jcbowman | 2007-07-27 01:05:35 -0600 (Fri, 27 Jul 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/plain_picture.asy
+
+Fix picture scaling.
+
+------------------------------------------------------------------------
+r2736 | hammera | 2007-07-26 09:17:38 -0600 (Thu, 26 Jul 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/application.h
+ M /trunk/asymptote/parser.cc
+
+Edited comments.
+
+------------------------------------------------------------------------
+r2735 | oshardt | 2007-07-25 14:41:31 -0600 (Wed, 25 Jul 2007) | 1 line
+Changed paths:
+ M /trunk/asymptote/GUI/xasyOptions.py
+
+Removed unneeded message
+------------------------------------------------------------------------
+r2734 | oshardt | 2007-07-25 12:50:30 -0600 (Wed, 25 Jul 2007) | 1 line
+Changed paths:
+ M /trunk/asymptote/GUI/xasyMainWin.py
+
+Fixed rotation of multiple objects
+------------------------------------------------------------------------
+r2733 | oshardt | 2007-07-25 12:43:59 -0600 (Wed, 25 Jul 2007) | 1 line
+Changed paths:
+ M /trunk/asymptote/GUI/xasyMainWin.py
+
+Corrected divide-by-zero handling
+------------------------------------------------------------------------
+r2732 | oshardt | 2007-07-25 12:27:37 -0600 (Wed, 25 Jul 2007) | 1 line
+Changed paths:
+ M /trunk/asymptote/GUI/xasyMainWin.py
+
+Fixed button width
+------------------------------------------------------------------------
+r2731 | oshardt | 2007-07-25 11:11:13 -0600 (Wed, 25 Jul 2007) | 1 line
+Changed paths:
+ M /trunk/asymptote/GUI/xasy2asy.py
+ M /trunk/asymptote/GUI/xasyMainWin.py
+ M /trunk/asymptote/GUI/xasyOptions.py
+
+Fixes for Windows support
+------------------------------------------------------------------------
+r2730 | jcbowman | 2007-07-25 03:28:31 -0600 (Wed, 25 Jul 2007) | 4 lines
+Changed paths:
+ M /trunk/asymptote/GUI/xasy2asy.py
+ M /trunk/asymptote/base/plain_xasy.asy
+ M /trunk/asymptote/base/pstoedit.asy
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/runtime.in
+
+Remove deconstruct() and gui() in favour of settings.deconstruct.
+
+Rename deconstructpic to deconstruct; standardize arguments.
+
+------------------------------------------------------------------------
+r2729 | jcbowman | 2007-07-25 03:07:20 -0600 (Wed, 25 Jul 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/path.cc
+
+Revert r2722; update documentation.
+
+------------------------------------------------------------------------
+r2728 | oshardt | 2007-07-24 15:24:08 -0600 (Tue, 24 Jul 2007) | 1 line
+Changed paths:
+ M /trunk/asymptote/GUI/xasy2asy.py
+
+catch unnecessary exception
+------------------------------------------------------------------------
+r2727 | oshardt | 2007-07-24 14:53:55 -0600 (Tue, 24 Jul 2007) | 1 line
+Changed paths:
+ M /trunk/asymptote/GUI/UndoRedoStack.py
+ M /trunk/asymptote/GUI/xasyActions.py
+ M /trunk/asymptote/GUI/xasyMainWin.py
+
+Implemented undo and redo for shifts and rotations
+------------------------------------------------------------------------
+r2726 | oshardt | 2007-07-24 11:59:29 -0600 (Tue, 24 Jul 2007) | 1 line
+Changed paths:
+ A /trunk/asymptote/GUI/UndoRedoStack.py
+ A /trunk/asymptote/GUI/xasyActions.py
+
+Added skeleton for undo/redo operations
+------------------------------------------------------------------------
+r2725 | oshardt | 2007-07-24 11:58:58 -0600 (Tue, 24 Jul 2007) | 1 line
+Changed paths:
+ M /trunk/asymptote/GUI/xasy2asy.py
+ M /trunk/asymptote/GUI/xasyMainWin.py
+
+Added accelerators for menu items
+------------------------------------------------------------------------
+r2724 | oshardt | 2007-07-24 09:37:47 -0600 (Tue, 24 Jul 2007) | 1 line
+Changed paths:
+ M /trunk/asymptote/GUI/CubicBezier.py
+ M /trunk/asymptote/GUI/xasy.py
+ M /trunk/asymptote/GUI/xasy2asy.py
+ M /trunk/asymptote/GUI/xasyBezierEditor.py
+ M /trunk/asymptote/GUI/xasyMainWin.py
+ M /trunk/asymptote/GUI/xasyOptions.py
+
+Removed unneeded code; fixed export command
+------------------------------------------------------------------------
+r2723 | jcbowman | 2007-07-24 08:40:27 -0600 (Tue, 24 Jul 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/interact.cc
+
+Turn off readline editing when reading from a pipe.
+
+------------------------------------------------------------------------
+r2722 | jcbowman | 2007-07-24 03:51:06 -0600 (Tue, 24 Jul 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/path.cc
+
+List multiple cubic roots individually in all cases.
+
+------------------------------------------------------------------------
+r2721 | oshardt | 2007-07-23 14:08:12 -0600 (Mon, 23 Jul 2007) | 1 line
+Changed paths:
+ M /trunk/asymptote/base/plain_xasy.asy
+
+Additional parts for implementation of new deconstruction method
+------------------------------------------------------------------------
+r2720 | oshardt | 2007-07-23 14:07:03 -0600 (Mon, 23 Jul 2007) | 1 line
+Changed paths:
+ M /trunk/asymptote/GUI/xasyMainWin.py
+
+Implemented rotation of drawn and scripted items
+------------------------------------------------------------------------
+r2719 | oshardt | 2007-07-23 14:06:28 -0600 (Mon, 23 Jul 2007) | 1 line
+Changed paths:
+ M /trunk/asymptote/GUI/xasyFile.py
+
+Better parsing for script items
+------------------------------------------------------------------------
+r2718 | oshardt | 2007-07-23 14:05:38 -0600 (Mon, 23 Jul 2007) | 1 line
+Changed paths:
+ M /trunk/asymptote/GUI/xasy2asy.py
+
+Implemented new, cross-platform image deconstruction method
+------------------------------------------------------------------------
+r2717 | oshardt | 2007-07-23 14:03:34 -0600 (Mon, 23 Jul 2007) | 1 line
+Changed paths:
+ M /trunk/asymptote/runtime.in
+
+Added deconstructpic() for image deconstruction by GUI
+------------------------------------------------------------------------
+r2716 | oshardt | 2007-07-23 10:31:28 -0600 (Mon, 23 Jul 2007) | 1 line
+Changed paths:
+ M /trunk/asymptote/GUI/xasyCodeEditor.py
+ M /trunk/asymptote/GUI/xasyOptions.py
+
+Various improvements
+------------------------------------------------------------------------
+r2715 | hammera | 2007-07-23 10:23:31 -0600 (Mon, 23 Jul 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/camp.y
+
+Removed commented out code.
+
+------------------------------------------------------------------------
+r2714 | jcbowman | 2007-07-23 04:06:01 -0600 (Mon, 23 Jul 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/path.cc
+
+Change order of tests.
+
+------------------------------------------------------------------------
+r2713 | jcbowman | 2007-07-23 04:04:25 -0600 (Mon, 23 Jul 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/path.cc
+ M /trunk/asymptote/tests/arith/roots.asy
+
+Detect roots near zero in cubicroots.
+
+------------------------------------------------------------------------
+r2712 | jcbowman | 2007-07-21 06:19:10 -0600 (Sat, 21 Jul 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/surface.asy
+
+Add Radoslav's bbox and bbox3 code for surfaces.
+
+------------------------------------------------------------------------
+r2711 | jcbowman | 2007-07-19 16:30:26 -0600 (Thu, 19 Jul 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/Delaunay.cc
+
+Avoid potential uninitialized warnings with -finline-limit=400.
+
+------------------------------------------------------------------------
+r2710 | hammera | 2007-07-19 15:13:18 -0600 (Thu, 19 Jul 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/array.h
+ M /trunk/asymptote/callable.h
+ M /trunk/asymptote/drawclipbegin.h
+ M /trunk/asymptote/drawelement.h
+ M /trunk/asymptote/drawfill.h
+ M /trunk/asymptote/drawimage.h
+ M /trunk/asymptote/drawlabel.h
+ M /trunk/asymptote/drawpath.h
+ M /trunk/asymptote/drawverbatim.h
+ M /trunk/asymptote/errormsg.h
+ M /trunk/asymptote/guide.h
+ M /trunk/asymptote/item.h
+ M /trunk/asymptote/knot.h
+ M /trunk/asymptote/memory.h
+ M /trunk/asymptote/path.h
+ M /trunk/asymptote/pen.h
+ M /trunk/asymptote/picture.h
+ M /trunk/asymptote/program.h
+ M /trunk/asymptote/symbol.h
+ M /trunk/asymptote/types.h
+
+Removed erroneous GC_DECLARE_PTRFREE specifiers.
+
+------------------------------------------------------------------------
+r2709 | jcbowman | 2007-07-19 03:09:39 -0600 (Thu, 19 Jul 2007) | 1 line
+Changed paths:
+ M /trunk/asymptote/entry.h
+ M /trunk/asymptote/xstream.h
+
+Fix cxx errors.
+------------------------------------------------------------------------
+r2708 | jcbowman | 2007-07-19 02:51:23 -0600 (Thu, 19 Jul 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/Makefile.in
+ M /trunk/asymptote/configure.ac
+ D /trunk/asymptote/doc/Makefile
+ A /trunk/asymptote/doc/Makefile.in
+
+Workaround broken texi2dvi installations.
+
+------------------------------------------------------------------------
+r2707 | jcbowman | 2007-07-19 02:17:03 -0600 (Thu, 19 Jul 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/arrayop.h
+ M /trunk/asymptote/mathop.h
+ M /trunk/asymptote/runtime.in
+
+Trap quotient(intMin,-1).
+
+------------------------------------------------------------------------
+r2706 | hammera | 2007-07-18 22:28:58 -0600 (Wed, 18 Jul 2007) | 3 lines
+Changed paths:
+ M /trunk/asymptote/entry.cc
+ M /trunk/asymptote/entry.h
+
+Made the NOHASH venv interface compatible with the optimized hashtable venv.
+
+
+------------------------------------------------------------------------
+r2705 | hammera | 2007-07-18 21:37:52 -0600 (Wed, 18 Jul 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/entry.cc
+ M /trunk/asymptote/entry.h
+ M /trunk/asymptote/env.cc
+ M /trunk/asymptote/env.h
+ M /trunk/asymptote/exp.cc
+ M /trunk/asymptote/exp.h
+ M /trunk/asymptote/memory.h
+ M /trunk/asymptote/name.cc
+ M /trunk/asymptote/name.h
+ M /trunk/asymptote/types.cc
+ M /trunk/asymptote/types.h
+
+Added match caching and hashtable presizing optimizations.
+
+------------------------------------------------------------------------
+r2704 | hammera | 2007-07-18 21:35:20 -0600 (Wed, 18 Jul 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/envcompleter.cc
+
+Removed old code.
+
+------------------------------------------------------------------------
+r2703 | jcbowman | 2007-07-18 17:13:02 -0600 (Wed, 18 Jul 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/slide.asy
+
+Fix page numbering of slide presentations with -u stepping=true.
+
+------------------------------------------------------------------------
+r2702 | jcbowman | 2007-07-18 17:01:58 -0600 (Wed, 18 Jul 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/slide.asy
+
+Minor optimization.
+
+------------------------------------------------------------------------
+r2701 | jcbowman | 2007-07-18 16:39:08 -0600 (Wed, 18 Jul 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/asymptote.spec
+ M /trunk/asymptote/fpu.h
+ M /trunk/asymptote/parser.cc
+
+Remove further duplicate config.h imports.
+
+------------------------------------------------------------------------
+r2700 | jcbowman | 2007-07-18 16:21:52 -0600 (Wed, 18 Jul 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/builtin.cc
+ M /trunk/asymptote/common.h
+ M /trunk/asymptote/fileio.h
+ M /trunk/asymptote/genv.cc
+ M /trunk/asymptote/interact.h
+ M /trunk/asymptote/main.cc
+ M /trunk/asymptote/settings.cc
+ M /trunk/asymptote/util.h
+
+Eliminate multiple config.h includes.
+
+------------------------------------------------------------------------
+r2699 | jcbowman | 2007-07-18 15:52:01 -0600 (Wed, 18 Jul 2007) | 1 line
+Changed paths:
+ M /trunk/asymptote/picture.cc
+ M /trunk/asymptote/psfile.cc
+ M /trunk/asymptote/runtime.in
+ M /trunk/asymptote/util.cc
+ M /trunk/asymptote/util.h
+
+More cxx fixes.
+------------------------------------------------------------------------
+r2698 | jcbowman | 2007-07-18 15:42:41 -0600 (Wed, 18 Jul 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/common.h
+ M /trunk/asymptote/drawlabel.cc
+ M /trunk/asymptote/drawlabel.h
+ M /trunk/asymptote/fileio.cc
+ M /trunk/asymptote/fileio.h
+ M /trunk/asymptote/pen.h
+ M /trunk/asymptote/picture.cc
+ M /trunk/asymptote/picture.h
+ M /trunk/asymptote/runtime.in
+ M /trunk/asymptote/settings.cc
+
+Fix cxx warnings.
+
+------------------------------------------------------------------------
+r2697 | jcbowman | 2007-07-18 15:18:25 -0600 (Wed, 18 Jul 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/common.h
+
+Work around missing definitions of LONG_LONG_MAX, etc.
+
+------------------------------------------------------------------------
+r2696 | jcbowman | 2007-07-18 14:41:30 -0600 (Wed, 18 Jul 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/common.h
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/item.h
+ M /trunk/asymptote/path.h
+
+Move climits to proper place.
+
+------------------------------------------------------------------------
+r2695 | hammera | 2007-07-18 14:04:29 -0600 (Wed, 18 Jul 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/camp.y
+
+Removed unused OP token.
+
+------------------------------------------------------------------------
+r2694 | hammera | 2007-07-18 13:29:57 -0600 (Wed, 18 Jul 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+
+Changed arrowsize typos in documentation.
+
+------------------------------------------------------------------------
+r2693 | jcbowman | 2007-07-18 07:37:15 -0600 (Wed, 18 Jul 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/xstream.h
+
+Avoid conflict with definitions in types.h.
+
+------------------------------------------------------------------------
+r2692 | jcbowman | 2007-07-18 07:25:15 -0600 (Wed, 18 Jul 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/xstream.h
+
+Work around quad_t vs. long long conflict on 64 bit machines.
+
+------------------------------------------------------------------------
+r2691 | jcbowman | 2007-07-18 06:50:47 -0600 (Wed, 18 Jul 2007) | 4 lines
+Changed paths:
+ M /trunk/asymptote/common.h
+ M /trunk/asymptote/path.h
+
+Use LONG_LONG_MAX instead of LLONG_MAX.
+
+Add instructions for working around problems with old broken compilers.
+
+------------------------------------------------------------------------
+r2690 | jcbowman | 2007-07-18 06:21:48 -0600 (Wed, 18 Jul 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/common.h
+ M /trunk/asymptote/runtime.in
+
+Further portability fixes.
+
+------------------------------------------------------------------------
+r2689 | jcbowman | 2007-07-18 06:14:24 -0600 (Wed, 18 Jul 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/builtin.cc
+ M /trunk/asymptote/common.h
+ M /trunk/asymptote/configure.ac
+ M /trunk/asymptote/mathop.h
+
+Portability fixes.
+
+------------------------------------------------------------------------
+r2688 | jcbowman | 2007-07-18 05:50:11 -0600 (Wed, 18 Jul 2007) | 5 lines
+Changed paths:
+ M /trunk/asymptote/Delaunay.cc
+ M /trunk/asymptote/Delaunay.h
+ M /trunk/asymptote/absyn.cc
+ M /trunk/asymptote/absyn.h
+ M /trunk/asymptote/access.h
+ M /trunk/asymptote/application.cc
+ M /trunk/asymptote/application.h
+ M /trunk/asymptote/arrayop.h
+ M /trunk/asymptote/bbox.h
+ M /trunk/asymptote/builtin.cc
+ M /trunk/asymptote/camp.l
+ M /trunk/asymptote/castop.h
+ M /trunk/asymptote/coder.cc
+ M /trunk/asymptote/coder.h
+ M /trunk/asymptote/common.h
+ M /trunk/asymptote/constructor.cc
+ M /trunk/asymptote/dec.cc
+ M /trunk/asymptote/dec.h
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/drawelement.h
+ M /trunk/asymptote/drawlabel.cc
+ M /trunk/asymptote/drawlabel.h
+ M /trunk/asymptote/drawpath.cc
+ M /trunk/asymptote/errormsg.h
+ M /trunk/asymptote/exp.cc
+ M /trunk/asymptote/exp.h
+ M /trunk/asymptote/fileio.cc
+ M /trunk/asymptote/fileio.h
+ M /trunk/asymptote/flatguide.cc
+ M /trunk/asymptote/flatguide.h
+ M /trunk/asymptote/fpu.h
+ M /trunk/asymptote/frame.h
+ M /trunk/asymptote/fundec.cc
+ M /trunk/asymptote/fundec.h
+ M /trunk/asymptote/interact.cc
+ M /trunk/asymptote/interact.h
+ M /trunk/asymptote/item.h
+ M /trunk/asymptote/knot.cc
+ M /trunk/asymptote/knot.h
+ M /trunk/asymptote/mathop.h
+ M /trunk/asymptote/mod.h
+ M /trunk/asymptote/name.cc
+ M /trunk/asymptote/name.h
+ M /trunk/asymptote/newexp.cc
+ M /trunk/asymptote/newexp.h
+ M /trunk/asymptote/path.cc
+ M /trunk/asymptote/path.h
+ M /trunk/asymptote/path3.cc
+ M /trunk/asymptote/pen.h
+ M /trunk/asymptote/picture.cc
+ M /trunk/asymptote/picture.h
+ D /trunk/asymptote/pow.h
+ M /trunk/asymptote/primitives.h
+ M /trunk/asymptote/process.cc
+ M /trunk/asymptote/process.h
+ M /trunk/asymptote/program.cc
+ M /trunk/asymptote/psfile.cc
+ M /trunk/asymptote/psfile.h
+ M /trunk/asymptote/runtime.in
+ M /trunk/asymptote/settings.cc
+ M /trunk/asymptote/settings.h
+ M /trunk/asymptote/stack.cc
+ M /trunk/asymptote/stm.cc
+ M /trunk/asymptote/stm.h
+ M /trunk/asymptote/triple.h
+ M /trunk/asymptote/types.cc
+ M /trunk/asymptote/types.h
+ M /trunk/asymptote/util.cc
+ M /trunk/asymptote/util.h
+ M /trunk/asymptote/varinit.cc
+ M /trunk/asymptote/varinit.h
+ M /trunk/asymptote/xstream.h
+
+Change integer type to Int, which is set default in common.h to long long
+(typically a 64 bit integer).
+
+Add support for reading and writing 64 bit integers in binary and XDR modes.
+
+------------------------------------------------------------------------
+r2687 | jcbowman | 2007-07-18 05:09:44 -0600 (Wed, 18 Jul 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/main.cc
+
+Don't call locateFile with an empty file name.
+
+------------------------------------------------------------------------
+r2686 | jcbowman | 2007-07-18 04:47:45 -0600 (Wed, 18 Jul 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/extra/intro.asy
+
+Fix code for Bezier example.
+
+------------------------------------------------------------------------
+r2685 | pivaldi | 2007-07-17 15:18:50 -0600 (Tue, 17 Jul 2007) | 1 line
+Changed paths:
+ M /trunk/asymptote/base/grid3.asy
+
+grid3.asy: bug fix with perspective projection.
+------------------------------------------------------------------------
+r2684 | oshardt | 2007-07-16 09:35:44 -0600 (Mon, 16 Jul 2007) | 1 line
+Changed paths:
+ M /trunk/asymptote/GUI/xasyMainWin.py
+
+Fixed itemEdit index computation
+------------------------------------------------------------------------
+r2683 | jcbowman | 2007-07-13 17:50:11 -0600 (Fri, 13 Jul 2007) | 6 lines
+Changed paths:
+ M /trunk/asymptote/Makefile.in
+ M /trunk/asymptote/doc/Makefile
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/settings.cc
+
+Change search path order: directories specified by the dir configuration
+variable are now examined before the directory .asy in the user's home
+directory.
+
+Ignore user configuration files during installation.
+
+------------------------------------------------------------------------
+r2682 | pivaldi | 2007-07-13 09:03:59 -0600 (Fri, 13 Jul 2007) | 1 line
+Changed paths:
+ M /trunk/asymptote/base/asy-mode.el
+
+Bug fix in lasy-tags routine.
+------------------------------------------------------------------------
+r2681 | pivaldi | 2007-07-11 12:30:03 -0600 (Wed, 11 Jul 2007) | 1 line
+Changed paths:
+ M /trunk/asymptote/base/asy-mode.el
+
+Defer the copy of LaTeX-mode-map to lasy-mode-map after all personal configurations was loaded.
+------------------------------------------------------------------------
+r2680 | oshardt | 2007-07-11 12:07:48 -0600 (Wed, 11 Jul 2007) | 1 line
+Changed paths:
+ M /trunk/asymptote/GUI/xasy2asy.py
+
+Fixed verification of asy pipe creationy
+------------------------------------------------------------------------
+r2679 | pivaldi | 2007-07-11 08:25:31 -0600 (Wed, 11 Jul 2007) | 1 line
+Changed paths:
+ M /trunk/asymptote/base/asy-mode.el
+
+Provide real syntax highlighting support with two-mode-mode for lasy-mode
+------------------------------------------------------------------------
+r2678 | oshardt | 2007-07-09 15:42:28 -0600 (Mon, 09 Jul 2007) | 1 line
+Changed paths:
+ M /trunk/asymptote/GUI/xasy2asy.py
+ M /trunk/asymptote/GUI/xasyFile.py
+ M /trunk/asymptote/GUI/xasyMainWin.py
+
+Implemented pen parsing for label commands
+------------------------------------------------------------------------
+r2677 | oshardt | 2007-07-09 11:55:18 -0600 (Mon, 09 Jul 2007) | 1 line
+Changed paths:
+ M /trunk/asymptote/GUI/xasyMainWin.py
+
+Implemented raising and lowering of items
+------------------------------------------------------------------------
+r2676 | oshardt | 2007-07-09 09:54:01 -0600 (Mon, 09 Jul 2007) | 1 line
+Changed paths:
+ D /trunk/asymptote/GUI/xasyPenEditor.py
+
+Remove unneeded module
+------------------------------------------------------------------------
+r2675 | oshardt | 2007-07-09 09:31:46 -0600 (Mon, 09 Jul 2007) | 1 line
+Changed paths:
+ M /trunk/asymptote/GUI/xasy2asy.py
+ M /trunk/asymptote/GUI/xasyFile.py
+ M /trunk/asymptote/GUI/xasyMainWin.py
+
+Fix interrupted system call error
+------------------------------------------------------------------------
+r2674 | jcbowman | 2007-07-09 01:29:17 -0600 (Mon, 09 Jul 2007) | 1 line
+Changed paths:
+ M /trunk/asymptote/picture.cc
+ M /trunk/asymptote/process.h
+
+Fix texstream destructor so that texput files are removed.
+------------------------------------------------------------------------
+r2673 | jcbowman | 2007-07-09 00:51:17 -0600 (Mon, 09 Jul 2007) | 3 lines
+Changed paths:
+ M /trunk/asymptote/interact.cc
+
+Fix memory allocation incompatibility in workaround for old, broken
+readline libraries.
+
+------------------------------------------------------------------------
+r2672 | oshardt | 2007-07-08 16:31:16 -0600 (Sun, 08 Jul 2007) | 1 line
+Changed paths:
+ M /trunk/asymptote/GUI/xasyMainWin.py
+
+Fixed horizontal and vertical motion.
+------------------------------------------------------------------------
+r2671 | jcbowman | 2007-07-08 16:02:53 -0600 (Sun, 08 Jul 2007) | 1 line
+Changed paths:
+ A /trunk/asymptote/examples/rainbow.asy
+
+Add rainbow example.
+------------------------------------------------------------------------
+r2670 | jcbowman | 2007-07-08 13:30:11 -0600 (Sun, 08 Jul 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/examples/tensor.asy
+
+Standardize argument names.
+
+------------------------------------------------------------------------
+r2669 | jcbowman | 2007-07-08 13:28:58 -0600 (Sun, 08 Jul 2007) | 6 lines
+Changed paths:
+ M /trunk/asymptote/base/annotate.asy
+ M /trunk/asymptote/base/binarytree.asy
+ M /trunk/asymptote/base/flowchart.asy
+ M /trunk/asymptote/base/grid3.asy
+ M /trunk/asymptote/base/math.asy
+ M /trunk/asymptote/base/palette.asy
+ M /trunk/asymptote/base/plain_Label.asy
+ M /trunk/asymptote/base/plain_boxes.asy
+ M /trunk/asymptote/base/plain_picture.asy
+ M /trunk/asymptote/base/pstoedit.asy
+
+Make framepoint (and truepoint) work even when an exact picture size
+estimate is unavailable.
+
+Add boolean argument to deferred drawing routines to allow optimization in cases
+where an exact picture size estimate is available.
+
+------------------------------------------------------------------------
+r2668 | jcbowman | 2007-07-08 10:22:17 -0600 (Sun, 08 Jul 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/picture.cc
+
+Allow writing to file specified with -o /dir/file.eps again.
+
+------------------------------------------------------------------------
+r2667 | jcbowman | 2007-07-07 11:09:58 -0600 (Sat, 07 Jul 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/settings.cc
+
+Don't reset options after reading configuration file.
+
+------------------------------------------------------------------------
+r2666 | oshardt | 2007-07-06 21:38:51 -0600 (Fri, 06 Jul 2007) | 1 line
+Changed paths:
+ M /trunk/asymptote/GUI/xasy2asy.py
+ M /trunk/asymptote/GUI/xasyMainWin.py
+
+Improved selection mechanism
+------------------------------------------------------------------------
+r2665 | oshardt | 2007-07-06 20:40:09 -0600 (Fri, 06 Jul 2007) | 1 line
+Changed paths:
+ M /trunk/asymptote/base/plain_xasy.asy
+
+Shipouts inside a script no longer interfere with the rest of the document
+------------------------------------------------------------------------
+r2664 | oshardt | 2007-07-06 18:23:04 -0600 (Fri, 06 Jul 2007) | 1 line
+Changed paths:
+ M /trunk/asymptote/GUI/xasyCodeEditor.py
+
+Rename menu entries.
+------------------------------------------------------------------------
+r2663 | oshardt | 2007-07-06 11:10:24 -0600 (Fri, 06 Jul 2007) | 1 line
+Changed paths:
+ M /trunk/asymptote/GUI/xasy2asy.py
+ M /trunk/asymptote/GUI/xasyCodeEditor.py
+ M /trunk/asymptote/GUI/xasyMainWin.py
+ M /trunk/asymptote/GUI/xasyOptions.py
+ M /trunk/asymptote/GUI/xasyOptionsDialog.py
+
+All labels now deconstructed. Dialogs improved. Fixed duplicate image reception.
+------------------------------------------------------------------------
+r2662 | oshardt | 2007-07-05 15:59:40 -0600 (Thu, 05 Jul 2007) | 1 line
+Changed paths:
+ M /trunk/asymptote/GUI/xasyColorPicker.py
+
+Various improvements
+------------------------------------------------------------------------
+r2661 | oshardt | 2007-07-05 15:58:43 -0600 (Thu, 05 Jul 2007) | 1 line
+Changed paths:
+ M /trunk/asymptote/GUI/xasyOptionsDialog.py
+
+Implemented validation for asy path
+------------------------------------------------------------------------
+r2660 | pivaldi | 2007-07-05 08:36:39 -0600 (Thu, 05 Jul 2007) | 1 line
+Changed paths:
+ M /trunk/asymptote/base/asy-mode.el
+
+Minor edit.
+------------------------------------------------------------------------
+r2659 | pivaldi | 2007-07-05 07:51:32 -0600 (Thu, 05 Jul 2007) | 3 lines
+Changed paths:
+ M /trunk/asymptote/base/asy-mode.el
+
+asydef environment content routine uses region instead regexp matcher.
+Cleaning code.
+
+------------------------------------------------------------------------
+r2658 | jcbowman | 2007-07-04 21:47:39 -0600 (Wed, 04 Jul 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/locate.cc
+ M /trunk/asymptote/parser.h
+ M /trunk/asymptote/process.cc
+ M /trunk/asymptote/settings.cc
+
+Add configuration file loading diagostic.
+
+------------------------------------------------------------------------
+r2657 | oshardt | 2007-07-04 18:59:22 -0600 (Wed, 04 Jul 2007) | 1 line
+Changed paths:
+ M /trunk/asymptote/GUI/xasyMainWin.py
+
+Improved handling of default pen
+------------------------------------------------------------------------
+r2656 | oshardt | 2007-07-04 15:49:27 -0600 (Wed, 04 Jul 2007) | 1 line
+Changed paths:
+ M /trunk/asymptote/GUI/CubicBezier.py
+
+Fixed docstring
+------------------------------------------------------------------------
+r2655 | oshardt | 2007-07-04 15:48:42 -0600 (Wed, 04 Jul 2007) | 1 line
+Changed paths:
+ M /trunk/asymptote/GUI/xasy2asy.py
+ M /trunk/asymptote/GUI/xasyColorPicker.py
+ M /trunk/asymptote/GUI/xasyMainWin.py
+ M /trunk/asymptote/GUI/xasyOptions.py
+ M /trunk/asymptote/GUI/xasyOptionsDialog.py
+
+Implemented storage and retrieval of user preferences
+------------------------------------------------------------------------
+r2654 | pivaldi | 2007-07-04 15:36:24 -0600 (Wed, 04 Jul 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/asy-mode.el
+
+Write temporary file with region instead of regexp matcher to
+avoid Stack overflow when compiling a long file within lasy-mode.
+------------------------------------------------------------------------
+r2653 | jcbowman | 2007-07-04 06:44:17 -0600 (Wed, 04 Jul 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/TODO
+
+Remove completed item.
+
+------------------------------------------------------------------------
+r2652 | oshardt | 2007-07-03 16:02:32 -0600 (Tue, 03 Jul 2007) | 1 line
+Changed paths:
+ M /trunk/asymptote/GUI/xasyMainWin.py
+
+Selecting an item clears the highlight box
+------------------------------------------------------------------------
+r2651 | oshardt | 2007-07-03 16:00:01 -0600 (Tue, 03 Jul 2007) | 1 line
+Changed paths:
+ M /trunk/asymptote/GUI/xasyBezierEditor.py
+
+Improved handling of already-transformed shapes
+------------------------------------------------------------------------
+r2650 | oshardt | 2007-07-03 15:25:22 -0600 (Tue, 03 Jul 2007) | 1 line
+Changed paths:
+ M /trunk/asymptote/GUI/xasyColorPicker.py
+
+Fixed incorrect entry in xasyColorPicker
+------------------------------------------------------------------------
+r2649 | oshardt | 2007-07-03 15:21:36 -0600 (Tue, 03 Jul 2007) | 1 line
+Changed paths:
+ M /trunk/asymptote/GUI/xasyBezierEditor.py
+ M /trunk/asymptote/GUI/xasyMainWin.py
+
+Improved bezier editing and integration with xasyMainWin
+------------------------------------------------------------------------
+r2648 | oshardt | 2007-07-03 14:39:42 -0600 (Tue, 03 Jul 2007) | 1 line
+Changed paths:
+ A /trunk/asymptote/GUI/xasyBezierEditor.py
+ M /trunk/asymptote/GUI/xasyMainWin.py
+
+Added ability to graphically edit the nodes and control points of a bezier curve
+------------------------------------------------------------------------
+r2647 | oshardt | 2007-07-03 14:38:15 -0600 (Tue, 03 Jul 2007) | 1 line
+Changed paths:
+ M /trunk/asymptote/GUI/CubicBezier.py
+
+Faster computation of an upper bound for the bezier width
+------------------------------------------------------------------------
+r2646 | jcbowman | 2007-07-03 10:25:49 -0600 (Tue, 03 Jul 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/configure.ac
+
+Fix --enable-gc-full-debug.
+
+------------------------------------------------------------------------
+r2645 | jcbowman | 2007-07-03 10:13:53 -0600 (Tue, 03 Jul 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/INSTALL
+ M /trunk/asymptote/configure.ac
+ M /trunk/asymptote/doc/asymptote.texi
+
+Update to gc-7.0.
+
+------------------------------------------------------------------------
+r2644 | jcbowman | 2007-07-03 10:06:04 -0600 (Tue, 03 Jul 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+
+Add reference to Java-style array iteration.
+
+------------------------------------------------------------------------
+r2643 | jcbowman | 2007-07-03 09:56:07 -0600 (Tue, 03 Jul 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+
+Minor edits.
+
+------------------------------------------------------------------------
+r2642 | jcbowman | 2007-07-03 02:24:02 -0600 (Tue, 03 Jul 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/three.asy
+
+Minor simplification.
+
+------------------------------------------------------------------------
+r2641 | hammera | 2007-07-02 18:32:57 -0600 (Mon, 02 Jul 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+
+Added brief comment on extended for loops.
+
+------------------------------------------------------------------------
+r2640 | jcbowman | 2007-07-02 17:27:53 -0600 (Mon, 02 Jul 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/runtime.in
+
+Minor solve optimizations.
+
+------------------------------------------------------------------------
+r2639 | jcbowman | 2007-07-02 12:14:51 -0600 (Mon, 02 Jul 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/runtime.in
+
+Fix memory leak in matrix multiply.
+
+------------------------------------------------------------------------
+r2638 | hammera | 2007-07-02 07:11:48 -0600 (Mon, 02 Jul 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/camp.y
+ M /trunk/asymptote/stm.cc
+ M /trunk/asymptote/stm.h
+
+Simplify extended for loop syntax.
+
+------------------------------------------------------------------------
+r2637 | jcbowman | 2007-07-01 23:57:51 -0600 (Sun, 01 Jul 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/patches/README
+ D /trunk/asymptote/patches/gv-3.6.2.patch
+
+Update to gv-3.6.3.
+
+------------------------------------------------------------------------
+r2636 | jcbowman | 2007-06-30 01:11:04 -0600 (Sat, 30 Jun 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/array.h
+ M /trunk/asymptote/drawclipbegin.h
+ M /trunk/asymptote/drawelement.h
+ M /trunk/asymptote/drawfill.cc
+ M /trunk/asymptote/drawfill.h
+ M /trunk/asymptote/drawgrestore.h
+ M /trunk/asymptote/drawgroup.h
+ M /trunk/asymptote/drawgsave.h
+ M /trunk/asymptote/drawimage.h
+ M /trunk/asymptote/drawlayer.h
+ M /trunk/asymptote/psfile.cc
+ M /trunk/asymptote/psfile.h
+ M /trunk/asymptote/runtime.in
+
+More garbage collection improvements.
+
+------------------------------------------------------------------------
+r2635 | oshardt | 2007-06-29 15:37:09 -0600 (Fri, 29 Jun 2007) | 1 line
+Changed paths:
+ M /trunk/asymptote/GUI/xasy2asy.py
+
+Fixed syntax
+------------------------------------------------------------------------
+r2634 | oshardt | 2007-06-29 15:30:29 -0600 (Fri, 29 Jun 2007) | 1 line
+Changed paths:
+ A /trunk/asymptote/GUI
+ A /trunk/asymptote/GUI/CubicBezier.py
+ A /trunk/asymptote/GUI/xasy.py
+ A /trunk/asymptote/GUI/xasy2asy.py
+ A /trunk/asymptote/GUI/xasyCodeEditor.py
+ A /trunk/asymptote/GUI/xasyColorPicker.py
+ A /trunk/asymptote/GUI/xasyExample.asy
+ A /trunk/asymptote/GUI/xasyFile.py
+ A /trunk/asymptote/GUI/xasyGUIIcons.py
+ A /trunk/asymptote/GUI/xasyMainWin.py
+ A /trunk/asymptote/GUI/xasyOptions.py
+ A /trunk/asymptote/GUI/xasyOptionsDialog.py
+ A /trunk/asymptote/GUI/xasyPenEditor.py
+
+Checkin the code for the new GUI that is under development.
+------------------------------------------------------------------------
+r2633 | oshardt | 2007-06-29 15:29:21 -0600 (Fri, 29 Jun 2007) | 1 line
+Changed paths:
+ M /trunk/asymptote/base/plain_xasy.asy
+
+Improved the xformStack implementation
+------------------------------------------------------------------------
+r2632 | jcbowman | 2007-06-29 12:45:00 -0600 (Fri, 29 Jun 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/runtime.in
+
+Fix segmentation fault in complement.
+
+------------------------------------------------------------------------
+r2631 | jcbowman | 2007-06-29 02:00:20 -0600 (Fri, 29 Jun 2007) | 1 line
+Changed paths:
+ M /trunk/asymptote/configure.ac
+
+Increment version to 1.33svn.
+------------------------------------------------------------------------
+r2630 | jcbowman | 2007-06-29 00:42:03 -0600 (Fri, 29 Jun 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/callable.h
+
+More garbage collection tweaks.
+
+------------------------------------------------------------------------
+r2629 | jcbowman | 2007-06-29 00:23:03 -0600 (Fri, 29 Jun 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/Makefile.in
+
+Fix dependency.
+
+------------------------------------------------------------------------
+r2628 | jcbowman | 2007-06-29 00:04:58 -0600 (Fri, 29 Jun 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/asymptote.spec
+ M /trunk/asymptote/doc/Makefile
+
+Fix make install-all.
+
+------------------------------------------------------------------------
+r2627 | jcbowman | 2007-06-28 23:15:34 -0600 (Thu, 28 Jun 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/drawverbatim.h
+
+Declare drawverbatim to be atomic.
+
+------------------------------------------------------------------------
+r2626 | jcbowman | 2007-06-28 17:20:22 -0600 (Thu, 28 Jun 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/path.cc
+
+Fix bug in subpath.
+
+------------------------------------------------------------------------
+r2625 | jcbowman | 2007-06-28 12:13:02 -0600 (Thu, 28 Jun 2007) | 6 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/runtime.in
+ M /trunk/asymptote/util.cc
+ M /trunk/asymptote/util.h
+
+Allow cd() and cd("") even if globalwrite is false.
+
+Don't write cd path twice in interactive mode.
+
+Update diagnostics and documentation.
+
+------------------------------------------------------------------------
+r2624 | jcbowman | 2007-06-27 12:09:17 -0600 (Wed, 27 Jun 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/runtime.in
+
+Fix GC debugging.
+
+------------------------------------------------------------------------
+r2623 | jcbowman | 2007-06-27 11:22:17 -0600 (Wed, 27 Jun 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/path.cc
+ M /trunk/asymptote/path3.cc
+ M /trunk/asymptote/runtime.in
+ M /trunk/asymptote/tests/TestLib.asy
+ M /trunk/asymptote/triple.h
+
+More garbage collection tweaks/leak fixes.
+
+------------------------------------------------------------------------
+r2622 | jcbowman | 2007-06-27 02:19:14 -0600 (Wed, 27 Jun 2007) | 1 line
+Changed paths:
+ M /trunk/asymptote/configure.ac
+
+Increment version to 1.32svn.
+------------------------------------------------------------------------
+r2621 | jcbowman | 2007-06-27 00:47:19 -0600 (Wed, 27 Jun 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/settings.cc
+
+Fix segmentation fault in options processing.
+
+------------------------------------------------------------------------
+r2620 | jcbowman | 2007-06-27 00:31:52 -0600 (Wed, 27 Jun 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/Makefile.in
+
+Reinstate gc check.
+
+------------------------------------------------------------------------
+r2619 | jcbowman | 2007-06-27 00:28:06 -0600 (Wed, 27 Jun 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/Makefile.in
+
+Avoid makefile loops.
+
+------------------------------------------------------------------------
+r2618 | jcbowman | 2007-06-26 23:57:15 -0600 (Tue, 26 Jun 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/dec.cc
+
+Fix g++ warning.
+
+------------------------------------------------------------------------
+r2617 | jcbowman | 2007-06-26 15:35:03 -0600 (Tue, 26 Jun 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/dec.h
+
+Fix cxx warnings.
+
+------------------------------------------------------------------------
+r2616 | jcbowman | 2007-06-26 15:20:11 -0600 (Tue, 26 Jun 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/three.asy
+
+Fix nullpath3 min/max bugs.
+
+------------------------------------------------------------------------
+r2615 | jcbowman | 2007-06-26 15:17:14 -0600 (Tue, 26 Jun 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/plain_picture.asy
+ M /trunk/asymptote/drawpath.cc
+ M /trunk/asymptote/path.h
+ M /trunk/asymptote/runtime.in
+
+Fix nullpath max/min bugs.
+
+------------------------------------------------------------------------
+r2614 | jcbowman | 2007-06-26 14:49:05 -0600 (Tue, 26 Jun 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/path.cc
+ M /trunk/asymptote/path.h
+ M /trunk/asymptote/pen.h
+
+Minor path optimizations.
+
+------------------------------------------------------------------------
+r2613 | jcbowman | 2007-06-26 14:18:05 -0600 (Tue, 26 Jun 2007) | 9 lines
+Changed paths:
+ M /trunk/asymptote/array.h
+ M /trunk/asymptote/drawclipend.h
+ M /trunk/asymptote/drawelement.h
+ M /trunk/asymptote/drawlabel.h
+ M /trunk/asymptote/drawpath.cc
+ M /trunk/asymptote/drawpath.h
+ M /trunk/asymptote/errormsg.h
+ M /trunk/asymptote/guide.h
+ M /trunk/asymptote/item.h
+ M /trunk/asymptote/knot.h
+ M /trunk/asymptote/path.cc
+ M /trunk/asymptote/path.h
+ M /trunk/asymptote/pen.h
+ M /trunk/asymptote/picture.cc
+ M /trunk/asymptote/picture.h
+ M /trunk/asymptote/process.cc
+ M /trunk/asymptote/process.h
+ M /trunk/asymptote/program.h
+ M /trunk/asymptote/runtime.in
+ M /trunk/asymptote/settings.cc
+ M /trunk/asymptote/transform.h
+ M /trunk/asymptote/types.h
+
+Further garbage collection improvements: move pointers out of pen class.
+
+Add bool ==(path,path) operator.
+
+Move defaultpen into global; changes to defaultpen in config.asy will no
+longer be remembered (use the autoimport mechanism instead).
+
+Make the identity transform a constant.
+
+------------------------------------------------------------------------
+r2612 | jcbowman | 2007-06-25 17:20:00 -0600 (Mon, 25 Jun 2007) | 3 lines
+Changed paths:
+ M /trunk/asymptote/knot.h
+ M /trunk/asymptote/path.cc
+ M /trunk/asymptote/path.h
+ M /trunk/asymptote/runtime.in
+
+Avoid using a pointer in path class so that it can be allocated atomically
+by the garbage collector; this dramatically reduces memory usage.
+
+------------------------------------------------------------------------
+r2611 | jcbowman | 2007-06-25 16:57:22 -0600 (Mon, 25 Jun 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+
+Fixed typo.
+
+------------------------------------------------------------------------
+r2610 | jcbowman | 2007-06-25 16:41:37 -0600 (Mon, 25 Jun 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/pipestream.h
+ M /trunk/asymptote/util.cc
+
+Fix runaway asy process that occurs when tex pipe cannnot start tex engine.
+
+------------------------------------------------------------------------
+r2609 | jcbowman | 2007-06-25 13:41:06 -0600 (Mon, 25 Jun 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/runtime.in
+
+Fix time without HAVE_STRFTIME.
+
+------------------------------------------------------------------------
+r2608 | jcbowman | 2007-06-25 13:39:30 -0600 (Mon, 25 Jun 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/runtime.in
+
+Fix default time and opacity arguments.
+
+------------------------------------------------------------------------
+r2607 | jcbowman | 2007-06-25 11:21:36 -0600 (Mon, 25 Jun 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+
+Fix minor typos.
+
+------------------------------------------------------------------------
+r2606 | hammera | 2007-06-25 09:49:15 -0600 (Mon, 25 Jun 2007) | 4 lines
+Changed paths:
+ M /trunk/asymptote/camp.y
+ M /trunk/asymptote/dec.cc
+ M /trunk/asymptote/dec.h
+ M /trunk/asymptote/stm.cc
+ M /trunk/asymptote/stm.h
+ M /trunk/asymptote/symbol.h
+
+Added Java-style abbreviation for iterating over arrays.
+
+Arrays of functions still not fully supported.
+
+------------------------------------------------------------------------
+r2605 | jcbowman | 2007-06-25 01:46:20 -0600 (Mon, 25 Jun 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/pen.h
+ M /trunk/asymptote/picture.h
+ M /trunk/asymptote/triple.h
+
+Further garbage collection tweaks.
+
+------------------------------------------------------------------------
+r2604 | jcbowman | 2007-06-25 01:37:20 -0600 (Mon, 25 Jun 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/item.h
+
+Remove virtual destructor introduced in r2601 due to performance penalty.
+
+------------------------------------------------------------------------
+r2603 | jcbowman | 2007-06-25 01:28:48 -0600 (Mon, 25 Jun 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/builtin.cc
+
+Simplify arrayDeleteHelper, removing unused variable.
+
+------------------------------------------------------------------------
+r2602 | jcbowman | 2007-06-25 01:16:49 -0600 (Mon, 25 Jun 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/memory.h
+
+Fix --disable-gc.
+
+------------------------------------------------------------------------
+r2601 | jcbowman | 2007-06-25 01:05:39 -0600 (Mon, 25 Jun 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/dec.h
+ M /trunk/asymptote/fileio.h
+ M /trunk/asymptote/interact.cc
+ M /trunk/asymptote/item.h
+ M /trunk/asymptote/memory.h
+ M /trunk/asymptote/runtime.in
+ M /trunk/asymptote/transform.h
+
+Fix warning messages.
+
+------------------------------------------------------------------------
+r2600 | jcbowman | 2007-06-25 00:18:53 -0600 (Mon, 25 Jun 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/settings.cc
+
+Add header for isatty.
+
+------------------------------------------------------------------------
+r2599 | jcbowman | 2007-06-24 22:19:44 -0600 (Sun, 24 Jun 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/drawlabel.cc
+
+Revert r2598.
+
+------------------------------------------------------------------------
+r2598 | jcbowman | 2007-06-24 22:16:40 -0600 (Sun, 24 Jun 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/drawlabel.cc
+
+Improve tex diagnostics.
+
+------------------------------------------------------------------------
+r2597 | jcbowman | 2007-06-24 21:24:46 -0600 (Sun, 24 Jun 2007) | 4 lines
+Changed paths:
+ M /trunk/asymptote/examples/poster.asy
+ M /trunk/asymptote/pipestream.h
+
+Leave deletion of string last to the garbage collector.
+
+Omit spurious call to background();
+
+------------------------------------------------------------------------
+r2596 | jcbowman | 2007-06-24 13:43:20 -0600 (Sun, 24 Jun 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/plain_picture.asy
+
+Avoid warning messages with -d.
+
+------------------------------------------------------------------------
+r2595 | jcbowman | 2007-06-24 13:36:33 -0600 (Sun, 24 Jun 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/runtime.in
+
+Fix GC preprocessor directives.
+
+------------------------------------------------------------------------
+r2594 | jcbowman | 2007-06-24 01:55:10 -0600 (Sun, 24 Jun 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/knot.h
+ M /trunk/asymptote/settings.cc
+
+Further garbage collection tweaks; reinstate no_GCwarn.
+
+------------------------------------------------------------------------
+r2593 | jcbowman | 2007-06-24 01:03:20 -0600 (Sun, 24 Jun 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/Makefile.in
+
+Fix dependencies.
+
+------------------------------------------------------------------------
+r2592 | jcbowman | 2007-06-24 00:43:45 -0600 (Sun, 24 Jun 2007) | 3 lines
+Changed paths:
+ M /trunk/asymptote/configure.ac
+
+Don't link with libgccpp.a to increase speed, now that garbage collection
+has been carefully addressed.
+
+------------------------------------------------------------------------
+r2591 | jcbowman | 2007-06-24 00:26:18 -0600 (Sun, 24 Jun 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/memory.h
+ M /trunk/asymptote/settings.cc
+
+Support ./configure --disable-gc again.
+
+------------------------------------------------------------------------
+r2590 | jcbowman | 2007-06-24 00:08:47 -0600 (Sun, 24 Jun 2007) | 9 lines
+Changed paths:
+ M /trunk/asymptote/INSTALL
+ M /trunk/asymptote/configure.ac
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/genv.h
+ M /trunk/asymptote/runtime.in
+
+Re-enable GC_gcollect under MacOS.
+
+Update to gc-7.0alpha9 since this yields faster execution times.
+
+Change configure --enable-gc=VERSION so that VERSION now must include the
+"gc" prefix.
+
+Remove genv from gc.
+
+------------------------------------------------------------------------
+r2589 | jcbowman | 2007-06-23 23:03:28 -0600 (Sat, 23 Jun 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/picture.cc
+ M /trunk/asymptote/process.cc
+ M /trunk/asymptote/process.h
+ M /trunk/asymptote/settings.cc
+ M /trunk/asymptote/settings.h
+
+Move ShipoutNumber into globalData.
+
+------------------------------------------------------------------------
+r2588 | jcbowman | 2007-06-23 16:45:58 -0600 (Sat, 23 Jun 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/drawelement.h
+ M /trunk/asymptote/fileio.h
+ M /trunk/asymptote/picture.cc
+ M /trunk/asymptote/picture.h
+ M /trunk/asymptote/process.cc
+ M /trunk/asymptote/process.h
+ M /trunk/asymptote/runtime.in
+ M /trunk/asymptote/settings.cc
+ M /trunk/asymptote/settings.h
+ M /trunk/asymptote/texfile.cc
+ M /trunk/asymptote/texfile.h
+ M /trunk/asymptote/util.cc
+
+Use separate global variables for each process.
+
+------------------------------------------------------------------------
+r2587 | jcbowman | 2007-06-23 12:42:05 -0600 (Sat, 23 Jun 2007) | 4 lines
+Changed paths:
+ M /trunk/asymptote/Makefile.in
+ M /trunk/asymptote/configure.ac
+ M /trunk/asymptote/memory.h
+ M /trunk/asymptote/process.h
+ M /trunk/asymptote/runtime.in
+ M /trunk/asymptote/settings.cc
+
+Deconstruct files on termination.
+
+Improve support for garbage collection debugging.
+
+------------------------------------------------------------------------
+r2586 | jcbowman | 2007-06-23 00:58:28 -0600 (Sat, 23 Jun 2007) | 3 lines
+Changed paths:
+ M /trunk/asymptote/Makefile.in
+ M /trunk/asymptote/common.h
+ M /trunk/asymptote/entry.cc
+ M /trunk/asymptote/fileio.h
+ M /trunk/asymptote/guide.h
+ M /trunk/asymptote/pair.h
+ M /trunk/asymptote/process.cc
+ M /trunk/asymptote/process.h
+ M /trunk/asymptote/runtime.in
+ M /trunk/asymptote/triple.h
+ M /trunk/asymptote/types.cc
+
+Close any open files automatically at the end of each asy process (without
+relying on a finalizer).
+
+------------------------------------------------------------------------
+r2585 | jcbowman | 2007-06-22 16:58:19 -0600 (Fri, 22 Jun 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/envcompleter.cc
+ M /trunk/asymptote/envcompleter.h
+ M /trunk/asymptote/util.cc
+ M /trunk/asymptote/util.h
+
+Fix segmentation fault introduced in r2580.
+
+------------------------------------------------------------------------
+r2584 | jcbowman | 2007-06-22 01:23:46 -0600 (Fri, 22 Jun 2007) | 5 lines
+Changed paths:
+ M /trunk/asymptote/array.h
+ M /trunk/asymptote/bbox.h
+ M /trunk/asymptote/coder.cc
+ M /trunk/asymptote/coder.h
+ M /trunk/asymptote/drawelement.h
+ M /trunk/asymptote/errormsg.cc
+ M /trunk/asymptote/errormsg.h
+ M /trunk/asymptote/fileio.h
+ M /trunk/asymptote/fundec.cc
+ M /trunk/asymptote/guide.h
+ M /trunk/asymptote/memory.h
+ M /trunk/asymptote/modifier.h
+ M /trunk/asymptote/pair.h
+ M /trunk/asymptote/parser.cc
+ M /trunk/asymptote/path.h
+ M /trunk/asymptote/process.cc
+ M /trunk/asymptote/program.h
+ M /trunk/asymptote/stack.cc
+ M /trunk/asymptote/stack.h
+ M /trunk/asymptote/symbol.h
+ M /trunk/asymptote/tests/gc/file.asy
+ A /trunk/asymptote/tests/gc/struct.asy
+ A /trunk/asymptote/tests/gc/transform.asy
+ M /trunk/asymptote/types.h
+
+Improve garbage collection by using GC_DECLARE_PTRFREE statements; use
+vectors instead of deques everywhere.
+
+Change nullPos() to nullPos.
+
+------------------------------------------------------------------------
+r2583 | jcbowman | 2007-06-21 23:41:19 -0600 (Thu, 21 Jun 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+
+Document how arbitrary files can be imported in the configuration file.
+
+------------------------------------------------------------------------
+r2582 | jcbowman | 2007-06-21 23:08:18 -0600 (Thu, 21 Jun 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/picture.cc
+
+Improve LaTeX diagnostics.
+
+------------------------------------------------------------------------
+r2581 | jcbowman | 2007-06-20 23:14:46 -0600 (Wed, 20 Jun 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/process.cc
+ M /trunk/asymptote/process.h
+
+Remove unused variable.
+
+------------------------------------------------------------------------
+r2580 | jcbowman | 2007-06-20 17:52:58 -0600 (Wed, 20 Jun 2007) | 7 lines
+Changed paths:
+ M /trunk/asymptote/access.cc
+ M /trunk/asymptote/access.h
+ M /trunk/asymptote/array.h
+ M /trunk/asymptote/camp.l
+ M /trunk/asymptote/camp.y
+ M /trunk/asymptote/camperror.cc
+ M /trunk/asymptote/coenv.cc
+ M /trunk/asymptote/dec.cc
+ M /trunk/asymptote/dec.h
+ M /trunk/asymptote/entry.cc
+ M /trunk/asymptote/envcompleter.cc
+ M /trunk/asymptote/envcompleter.h
+ M /trunk/asymptote/errormsg.h
+ M /trunk/asymptote/exp.cc
+ M /trunk/asymptote/exp.h
+ M /trunk/asymptote/fundec.cc
+ M /trunk/asymptote/fundec.h
+ M /trunk/asymptote/genv.cc
+ M /trunk/asymptote/inst.h
+ M /trunk/asymptote/interact.cc
+ M /trunk/asymptote/item.h
+ M /trunk/asymptote/main.cc
+ M /trunk/asymptote/memory.h
+ M /trunk/asymptote/name.cc
+ M /trunk/asymptote/newexp.cc
+ M /trunk/asymptote/parser.cc
+ M /trunk/asymptote/picture.cc
+ M /trunk/asymptote/process.cc
+ M /trunk/asymptote/process.h
+ M /trunk/asymptote/runtime.in
+ M /trunk/asymptote/settings.cc
+ M /trunk/asymptote/stack.cc
+ M /trunk/asymptote/stm.cc
+ M /trunk/asymptote/util.cc
+ M /trunk/asymptote/util.h
+ M /trunk/asymptote/varinit.cc
+
+Use GC_malloc_ignore_off_page to fix major memory leak in garbage
+collection of STL containers.
+
+Fix minor memory leaks.
+
+Make em an errorstream rather than a pointer to one.
+
+------------------------------------------------------------------------
+r2579 | oshardt | 2007-06-20 17:25:31 -0600 (Wed, 20 Jun 2007) | 1 line
+Changed paths:
+ M /trunk/asymptote/settings.cc
+
+Added a new option to enable interactive mode on non-tty input streams. Made the signal option only affect the sending of signals without the side-effect of controlling interactive mode.
+------------------------------------------------------------------------
+r2578 | oshardt | 2007-06-19 09:55:10 -0600 (Tue, 19 Jun 2007) | 6 lines
+Changed paths:
+ M /trunk/asymptote/interact.cc
+ M /trunk/asymptote/picture.cc
+ M /trunk/asymptote/runtime.in
+
+Modified signal mechanism to send signals for each shipout and at end of each
+operation.
+
+Modified handling of items deleted by GUI: bbox scaled by 0, file deleted, and
+signal sent.
+
+------------------------------------------------------------------------
+r2577 | jcbowman | 2007-06-19 09:43:25 -0600 (Tue, 19 Jun 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/animate.asy
+
+Resolve purge ambiguity.
+
+------------------------------------------------------------------------
+r2576 | pivaldi | 2007-06-19 03:44:43 -0600 (Tue, 19 Jun 2007) | 1 line
+Changed paths:
+ M /trunk/asymptote/base/markers.asy
+
+Fix the filling path according to the margin in the routine markangle.
+------------------------------------------------------------------------
+r2575 | jcbowman | 2007-06-18 22:27:00 -0600 (Mon, 18 Jun 2007) | 4 lines
+Changed paths:
+ M /trunk/asymptote/base/graph.asy
+ M /trunk/asymptote/base/plain_picture.asy
+ M /trunk/asymptote/builtin.cc
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/types.cc
+
+Make the delete virtual member of arrays with no arguments delete all
+elements of the array (not called clear to avoid the need for adding
+yet another type-dependent virtual function).
+
+------------------------------------------------------------------------
+r2574 | pivaldi | 2007-06-18 16:44:27 -0600 (Mon, 18 Jun 2007) | 1 line
+Changed paths:
+ M /trunk/asymptote/base/markers.asy
+
+fix typo.
+------------------------------------------------------------------------
+r2573 | pivaldi | 2007-06-18 16:41:03 -0600 (Mon, 18 Jun 2007) | 1 line
+Changed paths:
+ M /trunk/asymptote/base/markers.asy
+
+Add option filltype to markangle.
+------------------------------------------------------------------------
+r2572 | jcbowman | 2007-06-18 16:01:22 -0600 (Mon, 18 Jun 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/main.cc
+
+Handle exceptions in doUnrestirctedList.
+
+------------------------------------------------------------------------
+r2571 | jcbowman | 2007-06-18 15:45:57 -0600 (Mon, 18 Jun 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/plain_shipout.asy
+
+Declare shipout before importing plain_xasy.
+
+------------------------------------------------------------------------
+r2570 | jcbowman | 2007-06-18 12:18:22 -0600 (Mon, 18 Jun 2007) | 4 lines
+Changed paths:
+ M /trunk/asymptote/builtin.cc
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/types.cc
+
+Change the return type of the array virtual member delete to void.
+
+Allow A.delete(0,A.length-1) on empty arrays.
+
+------------------------------------------------------------------------
+r2569 | jcbowman | 2007-06-18 11:59:33 -0600 (Mon, 18 Jun 2007) | 11 lines
+Changed paths:
+ M /trunk/asymptote/base/graph.asy
+ M /trunk/asymptote/base/plain_picture.asy
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/knot.cc
+ M /trunk/asymptote/main.cc
+ M /trunk/asymptote/memory.h
+ M /trunk/asymptote/process.cc
+ M /trunk/asymptote/runtime.in
+ M /trunk/asymptote/settings.cc
+ M /trunk/asymptote/settings.h
+
+Make A.initialized(int n) return false when n is out of bounds, without any
+warning message.
+
+Use A.delete(0,A.length-1) to clear arrays in base files, to help the
+garbage collector.
+
+Add options -compact and -divisor to give the user more control over
+garbage collection.
+
+Implement a purge() function that forces a garbage collection.
+
+------------------------------------------------------------------------
+r2568 | oshardt | 2007-06-18 11:10:53 -0600 (Mon, 18 Jun 2007) | 1 line
+Changed paths:
+ M /trunk/asymptote/base/asymptote.py
+
+Updated to use Python's subprocess module.
+------------------------------------------------------------------------
+r2567 | jcbowman | 2007-06-17 22:37:33 -0600 (Sun, 17 Jun 2007) | 3 lines
+Changed paths:
+ M /trunk/asymptote/transform.h
+
+Implement better workaround for uninitialized 'this.130' gcc-4.1.2 warning
+message (cf. r2186).
+
+------------------------------------------------------------------------
+r2566 | jcbowman | 2007-06-14 17:47:22 -0600 (Thu, 14 Jun 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/palette.asy
+
+Fix typo.
+
+------------------------------------------------------------------------
+r2565 | jcbowman | 2007-06-14 17:39:46 -0600 (Thu, 14 Jun 2007) | 7 lines
+Changed paths:
+ M /trunk/asymptote/base/graph.asy
+ M /trunk/asymptote/base/palette.asy
+ M /trunk/asymptote/doc/asymptote.texi
+
+Add pen[][] interpolate(real[][] f, pen[] palette) routine for use with
+latticeshade.
+
+Rename palette argument range to bounds to avoid confusion.
+
+Use an implicit bounds constructor.
+
+------------------------------------------------------------------------
+r2564 | oshardt | 2007-06-14 15:05:19 -0600 (Thu, 14 Jun 2007) | 1 line
+Changed paths:
+ M /trunk/asymptote/base/plain_xasy.asy
+
+Changed transform push(transform); to void push(transform); to remove output when called in interactive mode.
+------------------------------------------------------------------------
+r2563 | jcbowman | 2007-06-14 14:19:13 -0600 (Thu, 14 Jun 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/asymptote.spec
+ M /trunk/asymptote/doc/filegraph.asy
+
+Resolve ambiguity.
+
+------------------------------------------------------------------------
+r2562 | jcbowman | 2007-06-14 13:16:25 -0600 (Thu, 14 Jun 2007) | 3 lines
+Changed paths:
+ M /trunk/asymptote/main.cc
+ M /trunk/asymptote/memory.h
+ M /trunk/asymptote/process.cc
+
+Don't call GC_collect under MacOS X, as this can cause bus errors and it
+doesn't seem to be necessary anyway on this platform.
+
+------------------------------------------------------------------------
+r2561 | jcbowman | 2007-06-14 11:32:20 -0600 (Thu, 14 Jun 2007) | 4 lines
+Changed paths:
+ M /trunk/asymptote/base/graph.asy
+ M /trunk/asymptote/runtime.in
+
+Remove unused line.
+
+Add reference.
+
+------------------------------------------------------------------------
+r2560 | hammera | 2007-06-13 19:47:16 -0600 (Wed, 13 Jun 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/dec.cc
+ M /trunk/asymptote/fundec.cc
+
+Minor changes to comments.
+
+------------------------------------------------------------------------
+r2559 | hammera | 2007-06-13 15:57:37 -0600 (Wed, 13 Jun 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/TODO
+ M /trunk/asymptote/base/graph.asy
+ M /trunk/asymptote/dec.cc
+ M /trunk/asymptote/dec.h
+ M /trunk/asymptote/exp.cc
+ M /trunk/asymptote/fundec.cc
+ M /trunk/asymptote/fundec.h
+
+Fixed addOps to add fields when possible.
+
+------------------------------------------------------------------------
+r2558 | pivaldi | 2007-06-13 03:10:21 -0600 (Wed, 13 Jun 2007) | 1 line
+Changed paths:
+ M /trunk/asymptote/examples/animations/sphere.asy
+
+Suppress useless code.
+------------------------------------------------------------------------
+r2557 | jcbowman | 2007-06-13 01:42:21 -0600 (Wed, 13 Jun 2007) | 1 line
+Changed paths:
+ M /trunk/asymptote/configure.ac
+
+Increment version to 1.31svn.
+------------------------------------------------------------------------
+r2556 | jcbowman | 2007-06-12 23:30:11 -0600 (Tue, 12 Jun 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/palette.asy
+ M /trunk/asymptote/doc/asymptote.texi
+
+Add copy argument to allow one to disable data buffering.
+
+------------------------------------------------------------------------
+r2555 | jcbowman | 2007-06-12 22:42:44 -0600 (Tue, 12 Jun 2007) | 6 lines
+Changed paths:
+ M /trunk/asymptote/base/graph.asy
+ M /trunk/asymptote/base/graph3.asy
+ M /trunk/asymptote/base/math.asy
+ A /trunk/asymptote/examples/animations/sphere.asy
+
+Add segment routine.
+
+Optimize conditional graphs.
+
+Add modified sphere animation, courtesy of Olivier Guibe and Philippe Ivaldi.
+
+------------------------------------------------------------------------
+r2554 | jcbowman | 2007-06-12 16:56:48 -0600 (Tue, 12 Jun 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/Makefile.in
+
+Remove unused filename.
+
+------------------------------------------------------------------------
+r2553 | jcbowman | 2007-06-12 16:50:45 -0600 (Tue, 12 Jun 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/Makefile.in
+
+Fix dependency.
+
+------------------------------------------------------------------------
+r2552 | jcbowman | 2007-06-12 16:25:57 -0600 (Tue, 12 Jun 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/builtin.cc
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/fileio.cc
+ M /trunk/asymptote/fileio.h
+ M /trunk/asymptote/runtime.in
+
+Make the implicit initializer for file variables null.
+
+------------------------------------------------------------------------
+r2551 | jcbowman | 2007-06-12 15:57:18 -0600 (Tue, 12 Jun 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/picture.cc
+
+Use a single box file.
+
+------------------------------------------------------------------------
+r2550 | jcbowman | 2007-06-12 15:51:18 -0600 (Tue, 12 Jun 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/picture.cc
+
+Remove unused box file entry.
+
+------------------------------------------------------------------------
+r2549 | jcbowman | 2007-06-12 15:07:24 -0600 (Tue, 12 Jun 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/plain.asy
+ M /trunk/asymptote/main.cc
+ M /trunk/asymptote/picture.cc
+ M /trunk/asymptote/runtime.in
+
+Communicate to xasy via a single signal (SIGINT) and status file.
+
+------------------------------------------------------------------------
+r2548 | hammera | 2007-06-12 13:52:42 -0600 (Tue, 12 Jun 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/coder.h
+
+Fixed bug introduced by previous bug fix.
+
+------------------------------------------------------------------------
+r2547 | pivaldi | 2007-06-12 13:42:19 -0600 (Tue, 12 Jun 2007) | 1 line
+Changed paths:
+ M /trunk/asymptote/base/asy-mode.el
+
+Update documentation.
+------------------------------------------------------------------------
+r2546 | jcbowman | 2007-06-12 11:14:03 -0600 (Tue, 12 Jun 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/contour.asy
+ M /trunk/asymptote/base/graph_settings.asy
+
+Move definition of interpolate to graph_settings.
+
+------------------------------------------------------------------------
+r2545 | jcbowman | 2007-06-12 02:23:08 -0600 (Tue, 12 Jun 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/three.asy
+
+Add cast of triple[] to guide3[].
+
+------------------------------------------------------------------------
+r2544 | jcbowman | 2007-06-12 01:42:32 -0600 (Tue, 12 Jun 2007) | 8 lines
+Changed paths:
+ M /trunk/asymptote/builtin.cc
+ M /trunk/asymptote/doc/Makefile
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/doc/logo.asy
+ M /trunk/asymptote/flatguide.h
+ M /trunk/asymptote/picture.cc
+ M /trunk/asymptote/runtime.in
+ M /trunk/asymptote/xasy3
+
+Fix shipout format.
+
+Remove old PDFanim_temp_Guide references.
+
+Fix cxx errors.
+
+Document reverse(guide).
+
+------------------------------------------------------------------------
+r2543 | jcbowman | 2007-06-12 00:08:25 -0600 (Tue, 12 Jun 2007) | 8 lines
+Changed paths:
+ M /trunk/asymptote/base/plain.asy
+ M /trunk/asymptote/base/plain_shipout.asy
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/guide.cc
+ M /trunk/asymptote/guide.h
+ M /trunk/asymptote/knot.h
+ M /trunk/asymptote/runtime.in
+ M /trunk/asymptote/tests/types/guide.asy
+
+Simplify shipout signature (to support xasy development).
+
+Support internal cycles in guide examination routines.
+
+Add reverse(guide).
+
+Fix guide tests.
+
+------------------------------------------------------------------------
+r2542 | jcbowman | 2007-06-11 23:49:48 -0600 (Mon, 11 Jun 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/asy-mode.el
+
+Fix typos.
+
+------------------------------------------------------------------------
+r2541 | jcbowman | 2007-06-11 13:18:47 -0600 (Mon, 11 Jun 2007) | 4 lines
+Changed paths:
+ M /trunk/asymptote/errormsg.h
+ M /trunk/asymptote/interact.cc
+ M /trunk/asymptote/main.cc
+ M /trunk/asymptote/process.cc
+ M /trunk/asymptote/settings.cc
+
+Exit interactive mode on eof when stdin is not a tty.
+
+If -signal is not set and stdin is not a tty, don't use interactive mode.
+
+------------------------------------------------------------------------
+r2540 | pivaldi | 2007-06-11 08:01:51 -0600 (Mon, 11 Jun 2007) | 3 lines
+Changed paths:
+ M /trunk/asymptote/base/asy-mode.el
+
+Expand lasy-mode errors management (with Emacs 22 only).
+Defer all shell redirection to Emacs for supporting most shell.
+Compatibility running Windows.
+------------------------------------------------------------------------
+r2539 | jcbowman | 2007-06-10 18:09:37 -0600 (Sun, 10 Jun 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/geometry.asy
+ M /trunk/asymptote/examples/triangle.asy
+
+Update triangle example to use new simplified constructors.
+
+------------------------------------------------------------------------
+r2538 | jcbowman | 2007-06-10 17:26:31 -0600 (Sun, 10 Jun 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+
+Minor edits.
+
+------------------------------------------------------------------------
+r2537 | hammera | 2007-06-10 12:56:11 -0600 (Sun, 10 Jun 2007) | 4 lines
+Changed paths:
+ M /trunk/asymptote/Makefile.in
+ M /trunk/asymptote/TODO
+ M /trunk/asymptote/coder.h
+ A /trunk/asymptote/constructor.cc
+ M /trunk/asymptote/dec.cc
+ M /trunk/asymptote/dec.h
+ M /trunk/asymptote/doc/FAQ/asy-faq.bfnn
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/entry.h
+ M /trunk/asymptote/exp.h
+ M /trunk/asymptote/frame.h
+ M /trunk/asymptote/fundec.cc
+ M /trunk/asymptote/newexp.cc
+ M /trunk/asymptote/record.h
+ M /trunk/asymptote/tests/Makefile
+ M /trunk/asymptote/tests/imp/unravel.asy
+ A /trunk/asymptote/tests/types/constructor.asy
+ M /trunk/asymptote/types.h
+
+Added implicit constructors.
+
+Fixed bug with permissions in static methods.
+
+------------------------------------------------------------------------
+r2536 | jcbowman | 2007-06-10 08:01:22 -0600 (Sun, 10 Jun 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/runtime.in
+ M /trunk/asymptote/tests/arith/roots.asy
+
+Add test for newton root solver; fix diagnostics.
+
+------------------------------------------------------------------------
+r2535 | jcbowman | 2007-06-10 07:20:12 -0600 (Sun, 10 Jun 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/contour.asy
+
+Optimize join.
+
+------------------------------------------------------------------------
+r2534 | jcbowman | 2007-06-10 00:12:13 -0600 (Sun, 10 Jun 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/settings.cc
+
+Give preference to GPL over AFPL Ghostscript.
+
+------------------------------------------------------------------------
+r2533 | jcbowman | 2007-06-09 23:25:19 -0600 (Sat, 09 Jun 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/asy-mode.el
+
+Add Philippe's lasy-mode fixes, including support for tcsh.
+
+------------------------------------------------------------------------
+r2532 | jcbowman | 2007-06-09 12:29:29 -0600 (Sat, 09 Jun 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/plain_picture.asy
+
+Add bool copy=true argument to picture routines that buffer data.
+
+------------------------------------------------------------------------
+r2531 | jcbowman | 2007-06-09 04:10:23 -0600 (Sat, 09 Jun 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/process.cc
+
+Improve garbage handling of multiple-file runs.
+
+------------------------------------------------------------------------
+r2530 | jcbowman | 2007-06-09 02:57:12 -0600 (Sat, 09 Jun 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/plain_constants.asy
+ M /trunk/asymptote/builtin.cc
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/fileio.cc
+ M /trunk/asymptote/fileio.h
+ M /trunk/asymptote/runtime.in
+
+Remove default initializer for files.
+
+------------------------------------------------------------------------
+r2529 | oshardt | 2007-06-08 15:05:15 -0600 (Fri, 08 Jun 2007) | 1 line
+Changed paths:
+ M /trunk/asymptote/base/plain_xasy.asy
+
+switched xformStack from LIFO to FIFO
+------------------------------------------------------------------------
+r2528 | jcbowman | 2007-06-06 13:09:28 -0600 (Wed, 06 Jun 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/asy-mode.el
+
+Revert spurious asy-mode.el commit.
+
+------------------------------------------------------------------------
+r2527 | jcbowman | 2007-06-06 13:01:46 -0600 (Wed, 06 Jun 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/asy-mode.el
+ M /trunk/asymptote/base/plain_debugger.asy
+ M /trunk/asymptote/base/plain_strings.asy
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/runtime.in
+
+Split readline functionality into readline and saveline.
+
+------------------------------------------------------------------------
+r2526 | jcbowman | 2007-06-06 00:38:24 -0600 (Wed, 06 Jun 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/picture.cc
+
+Allow xformat to be any format supported by convert.
+
+------------------------------------------------------------------------
+r2525 | jcbowman | 2007-06-04 22:42:05 -0600 (Mon, 04 Jun 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/Makefile.in
+ M /trunk/asymptote/runtime.in
+
+Fix parallel bison and lex processing.
+
+------------------------------------------------------------------------
+r2524 | jcbowman | 2007-06-04 14:53:35 -0600 (Mon, 04 Jun 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/plain_picture.asy
+ A /trunk/asymptote/base/plain_xasy.asy (from /trunk/asymptote/base/xasy.asy:2523)
+ M /trunk/asymptote/base/slide.asy
+ M /trunk/asymptote/base/three.asy
+ D /trunk/asymptote/base/xasy.asy
+
+Rename xasy.asy to plain_xasy.asy and revert other r2521 changes.
+
+------------------------------------------------------------------------
+r2523 | jcbowman | 2007-06-03 22:15:09 -0600 (Sun, 03 Jun 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+
+Improve documentation.
+
+------------------------------------------------------------------------
+r2522 | jcbowman | 2007-06-03 22:10:34 -0600 (Sun, 03 Jun 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/runtime.in
+
+Add Newton-Raphson iteration and Newton-Raphosn bisection routines.
+
+------------------------------------------------------------------------
+r2521 | jcbowman | 2007-06-03 17:07:52 -0600 (Sun, 03 Jun 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/plain_picture.asy
+ M /trunk/asymptote/base/slide.asy
+ M /trunk/asymptote/base/three.asy
+ A /trunk/asymptote/base/xasy.asy
+
+Add support for new GUI xformStack (under development).
+
+------------------------------------------------------------------------
+r2520 | jcbowman | 2007-06-03 10:33:17 -0600 (Sun, 03 Jun 2007) | 3 lines
+Changed paths:
+ M /trunk/asymptote/base/animate.asy
+ M /trunk/asymptote/doc/asymptote.texi
+
+Require version 2007/05/24 or later of animate.sty package; remove
+file name padding workaround.
+
+------------------------------------------------------------------------
+r2519 | jcbowman | 2007-06-02 23:20:55 -0600 (Sat, 02 Jun 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/plain_strings.asy
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/runtime.in
+
+Generalize history to return an array of the n most recent history values.
+
+------------------------------------------------------------------------
+r2518 | jcbowman | 2007-06-02 22:39:49 -0600 (Sat, 02 Jun 2007) | 4 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/picture.cc
+ M /trunk/asymptote/settings.cc
+
+Add gsOptions configuration variable.
+
+Force embedding of all fonts in eps files.
+
+------------------------------------------------------------------------
+r2517 | jcbowman | 2007-06-02 17:11:22 -0600 (Sat, 02 Jun 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/picture.cc
+
+Force all fonts to be embedded in pdf files.
+
+------------------------------------------------------------------------
+r2516 | jcbowman | 2007-06-02 12:00:40 -0600 (Sat, 02 Jun 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/texfile.cc
+
+Force fixed format for compatibility with pdflatex.
+
+------------------------------------------------------------------------
+r2515 | jcbowman | 2007-06-02 01:30:15 -0600 (Sat, 02 Jun 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/asy-mode.el
+
+Fix indentation when byte-compiled cc-mode.elc is used.
+
+------------------------------------------------------------------------
+r2514 | jcbowman | 2007-06-01 18:08:13 -0600 (Fri, 01 Jun 2007) | 8 lines
+Changed paths:
+ M /trunk/asymptote/arrayop.h
+ M /trunk/asymptote/builtin.cc
+ M /trunk/asymptote/builtin.h
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/runtime.in
+ M /trunk/asymptote/runtime.pl
+ A /trunk/asymptote/tests/array/delete.asy
+ M /trunk/asymptote/types.cc
+
+Allow array insert to insert an array of the same type at a given index;
+insert now returns void.
+
+Allow delete to accept an index range and return the last item deleted.
+
+Add initialized(int n) array virtual member to detect whether element n is
+initialized.
+
+------------------------------------------------------------------------
+r2513 | jcbowman | 2007-06-01 11:04:43 -0600 (Fri, 01 Jun 2007) | 3 lines
+Changed paths:
+ M /trunk/asymptote/base/plain_strings.asy
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/runtime.in
+
+Split readline functionality into two routines: readline (with argument
+order now consistent with getstring) and history(string).
+
+------------------------------------------------------------------------
+r2512 | oshardt | 2007-06-01 11:01:58 -0600 (Fri, 01 Jun 2007) | 1 line
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+
+Fixed typo
+------------------------------------------------------------------------
+r2511 | jcbowman | 2007-06-01 10:01:28 -0600 (Fri, 01 Jun 2007) | 3 lines
+Changed paths:
+ M /trunk/asymptote/base/graph.asy
+
+Implement NoZero and NoZeroFormat with more general OmitTick and OmitFormat
+routines.
+
+------------------------------------------------------------------------
+r2510 | jcbowman | 2007-05-31 14:17:57 -0600 (Thu, 31 May 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/drawelement.h
+ M /trunk/asymptote/drawfill.h
+ M /trunk/asymptote/drawpath.cc
+ M /trunk/asymptote/psfile.cc
+ M /trunk/asymptote/psfile.h
+
+Avoid need to defer linewidth by moving setpen to the proper place.
+
+------------------------------------------------------------------------
+r2509 | jcbowman | 2007-05-31 13:53:57 -0600 (Thu, 31 May 2007) | 4 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/drawelement.h
+ M /trunk/asymptote/psfile.cc
+ M /trunk/asymptote/psfile.h
+ M /trunk/asymptote/settings.cc
+ M /trunk/asymptote/texfile.cc
+ M /trunk/asymptote/transform.h
+
+Omit identity concat commands.
+
+Put dynamic linewidth code in /Setlinewidth.
+
+------------------------------------------------------------------------
+r2508 | jcbowman | 2007-05-31 02:21:50 -0600 (Thu, 31 May 2007) | 4 lines
+Changed paths:
+ M /trunk/asymptote/base/plain_filldraw.asy
+ M /trunk/asymptote/psfile.cc
+ M /trunk/asymptote/psfile.h
+
+Fix linewidth.
+
+Fix division by zero.
+
+------------------------------------------------------------------------
+r2507 | jcbowman | 2007-05-31 01:51:14 -0600 (Thu, 31 May 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/psfile.cc
+
+Simplify linewidth deferral.
+
+------------------------------------------------------------------------
+r2506 | jcbowman | 2007-05-30 23:25:59 -0600 (Wed, 30 May 2007) | 4 lines
+Changed paths:
+ M /trunk/asymptote/psfile.cc
+ M /trunk/asymptote/psfile.h
+
+Defer dynamic linewidth until stroke time in case currentmatrix changes.
+
+Improve accuracy of dynamic linewidth calculation.
+
+------------------------------------------------------------------------
+r2505 | jcbowman | 2007-05-30 23:18:10 -0600 (Wed, 30 May 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/graph.asy
+
+Rename zerotick to zerotickfuzz for clarity.
+
+------------------------------------------------------------------------
+r2504 | jcbowman | 2007-05-30 17:53:52 -0600 (Wed, 30 May 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/graph.asy
+
+Make zero detection robust.
+
+------------------------------------------------------------------------
+r2503 | pivaldi | 2007-05-30 13:48:10 -0600 (Wed, 30 May 2007) | 1 line
+Changed paths:
+ M /trunk/asymptote/base/graph.asy
+
+Fix numerical precision in the routine NoZero
+------------------------------------------------------------------------
+r2502 | jcbowman | 2007-05-30 13:04:08 -0600 (Wed, 30 May 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/contour3.asy
+ M /trunk/asymptote/base/graph3.asy
+ M /trunk/asymptote/base/three.asy
+
+Fix orientation code.
+
+------------------------------------------------------------------------
+r2501 | jcbowman | 2007-05-30 12:37:44 -0600 (Wed, 30 May 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/contour3.asy
+
+Simplify and optimize normal calculation.
+
+------------------------------------------------------------------------
+r2500 | rmarinov | 2007-05-30 11:37:58 -0600 (Wed, 30 May 2007) | 1 line
+Changed paths:
+ M /trunk/asymptote/base/contour3.asy
+
+Changed the shading approach in base/contour3.asy .
+------------------------------------------------------------------------
+r2499 | jcbowman | 2007-05-30 01:32:47 -0600 (Wed, 30 May 2007) | 4 lines
+Changed paths:
+ M /trunk/asymptote/base/contour3.asy
+ M /trunk/asymptote/base/graph3.asy
+ M /trunk/asymptote/base/palette.asy
+ M /trunk/asymptote/base/plain_filldraw.asy
+ M /trunk/asymptote/base/plain_picture.asy
+ M /trunk/asymptote/base/solids.asy
+ M /trunk/asymptote/builtin.cc
+ M /trunk/asymptote/builtin.h
+ M /trunk/asymptote/doc/FAQ/asy-faq.bfnn
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/runtime.in
+
+Implement simplified (and slightly more efficient) gouraudshade interface.
+
+Reduce memory and CPU usage by avoiding duplicate buffering of picture data.
+
+------------------------------------------------------------------------
+r2498 | jcbowman | 2007-05-29 22:04:36 -0600 (Tue, 29 May 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/graph.asy
+ M /trunk/asymptote/doc/FAQ/asy-faq.bfnn
+
+Add tickmodifier NoZero and ticklabel format NoZeroFormat.
+
+------------------------------------------------------------------------
+r2497 | jcbowman | 2007-05-29 16:27:53 -0600 (Tue, 29 May 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/tests/TestLib.asy
+ A /trunk/asymptote/tests/array/transpose.asy
+ A /trunk/asymptote/tests/types/guide.asy
+
+New test routines.
+
+------------------------------------------------------------------------
+r2496 | jcbowman | 2007-05-29 16:08:06 -0600 (Tue, 29 May 2007) | 4 lines
+Changed paths:
+ M /trunk/asymptote/base/contour.asy
+ M /trunk/asymptote/base/graph.asy
+ M /trunk/asymptote/base/graph3.asy
+ M /trunk/asymptote/base/graph_settings.asy
+ M /trunk/asymptote/base/math.asy
+ M /trunk/asymptote/base/three.asy
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/runtime.in
+ M /trunk/asymptote/tests/array/solve.asy
+
+Move real[][] identity(int n) from math.asy to C++ code; add documentation.
+
+Avoid use of loops with join operator.
+
+------------------------------------------------------------------------
+r2495 | jcbowman | 2007-05-29 16:04:44 -0600 (Tue, 29 May 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/contour3.asy
+
+Minor optimization.
+
+------------------------------------------------------------------------
+r2494 | jcbowman | 2007-05-29 15:54:23 -0600 (Tue, 29 May 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/contour3.asy
+
+Cleaner optimization.
+
+------------------------------------------------------------------------
+r2493 | jcbowman | 2007-05-28 18:14:29 -0600 (Mon, 28 May 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/contour3.asy
+
+Remove extra loop variable.
+
+------------------------------------------------------------------------
+r2492 | jcbowman | 2007-05-28 18:11:05 -0600 (Mon, 28 May 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/contour3.asy
+
+Further optimizations.
+
+------------------------------------------------------------------------
+r2491 | jcbowman | 2007-05-28 16:44:44 -0600 (Mon, 28 May 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/contour3.asy
+ M /trunk/asymptote/doc/asymptote.texi
+
+Optimize number of calls to project; change return type of contour.
+
+------------------------------------------------------------------------
+r2490 | jcbowman | 2007-05-28 14:41:27 -0600 (Mon, 28 May 2007) | 6 lines
+Changed paths:
+ M /trunk/asymptote/fileio.cc
+ M /trunk/asymptote/process.cc
+
+Catch unhandled quit exception.
+
+Reset scroll lines to zero.
+
+Don't exit on interrupt during module load in interactive mode.
+
+------------------------------------------------------------------------
+r2489 | jcbowman | 2007-05-28 14:14:22 -0600 (Mon, 28 May 2007) | 4 lines
+Changed paths:
+ M /trunk/asymptote/base/contour3.asy
+
+Renamed particle to object.
+
+Minor optimization.
+
+------------------------------------------------------------------------
+r2488 | jcbowman | 2007-05-28 11:14:18 -0600 (Mon, 28 May 2007) | 8 lines
+Changed paths:
+ M /trunk/asymptote/base/plain.asy
+ M /trunk/asymptote/base/three.asy
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/runtime.in
+
+Implement optimized real multdiagonal(real[][] a, real[]b).
+
+Speed up project slightly by changing aspect from real[][] to real[].
+
+Make cputime().change return parent+child times.
+
+Add write(cputime).
+
+------------------------------------------------------------------------
+r2487 | jcbowman | 2007-05-27 22:29:01 -0600 (Sun, 27 May 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/plain.asy
+ M /trunk/asymptote/doc/asymptote.texi
+
+Added change.user and change.system fields to cputime().
+
+------------------------------------------------------------------------
+r2486 | jcbowman | 2007-05-27 22:25:31 -0600 (Sun, 27 May 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/runtime.in
+
+Optimize real[][] * real[].
+
+------------------------------------------------------------------------
+r2485 | jcbowman | 2007-05-27 09:53:28 -0600 (Sun, 27 May 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/asymptote.spec
+ M /trunk/asymptote/base/light.asy
+ M /trunk/asymptote/base/math.asy
+ M /trunk/asymptote/base/three.asy
+ M /trunk/asymptote/runtime.in
+
+Speed up 3D projection by moving matrix-matrix multipy to C++ code.
+
+------------------------------------------------------------------------
+r2484 | jcbowman | 2007-05-27 01:08:58 -0600 (Sun, 27 May 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+
+Minor clarification.
+
+------------------------------------------------------------------------
+r2483 | jcbowman | 2007-05-27 01:03:03 -0600 (Sun, 27 May 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/plain_paths.asy
+ M /trunk/asymptote/base/three.asy
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/guide.h
+ M /trunk/asymptote/mod.h
+ M /trunk/asymptote/path.cc
+ M /trunk/asymptote/path.h
+ M /trunk/asymptote/runtime.in
+
+Simplify, document, and port guide examination routines to three.asy.
+
+------------------------------------------------------------------------
+r2482 | jcbowman | 2007-05-26 10:13:48 -0600 (Sat, 26 May 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/guide.cc
+
+Fix potential uninitialized variable.
+
+------------------------------------------------------------------------
+r2481 | jcbowman | 2007-05-24 02:07:53 -0600 (Thu, 24 May 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/runtime.in
+
+Add bool cyclic(guide) routine.
+
+------------------------------------------------------------------------
+r2480 | jcbowman | 2007-05-24 01:53:03 -0600 (Thu, 24 May 2007) | 4 lines
+Changed paths:
+ M /trunk/asymptote/TODO
+ M /trunk/asymptote/flatguide.h
+ M /trunk/asymptote/guide.cc
+ M /trunk/asymptote/guide.h
+ M /trunk/asymptote/knot.h
+ M /trunk/asymptote/runtime.in
+
+Add routines to allow access to guide components.
+
+Add upcase and downcase routines.
+
+------------------------------------------------------------------------
+r2479 | jcbowman | 2007-05-23 22:48:23 -0600 (Wed, 23 May 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/extra/intro.asy
+
+Document bibtex usage.
+
+------------------------------------------------------------------------
+r2478 | jcbowman | 2007-05-23 22:47:47 -0600 (Wed, 23 May 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/Makefile.in
+
+Install intro.asy.
+
+------------------------------------------------------------------------
+r2477 | jcbowman | 2007-05-23 22:47:32 -0600 (Wed, 23 May 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/animate.asy
+
+Remove pdf() restriction.
+
+------------------------------------------------------------------------
+r2476 | oshardt | 2007-05-23 15:43:59 -0600 (Wed, 23 May 2007) | 1 line
+Changed paths:
+ M /trunk/asymptote/xasy3
+
+Fixed docs about base64
+------------------------------------------------------------------------
+r2475 | jcbowman | 2007-05-21 21:16:42 -0600 (Mon, 21 May 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/contour3.asy
+
+Use projection P; reduce number of calls to project.
+
+------------------------------------------------------------------------
+r2474 | jcbowman | 2007-05-19 14:16:43 -0600 (Sat, 19 May 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/examples/magnetic.asy
+
+Reduce resolution.
+
+------------------------------------------------------------------------
+r2473 | jcbowman | 2007-05-19 14:05:36 -0600 (Sat, 19 May 2007) | 1 line
+Changed paths:
+ M /trunk/asymptote/configure.ac
+
+Increment version to 1.30svn.
+------------------------------------------------------------------------
+r2472 | jcbowman | 2007-05-19 11:25:04 -0600 (Sat, 19 May 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+
+Update LocalWords.
+
+------------------------------------------------------------------------
+r2471 | jcbowman | 2007-05-19 11:16:54 -0600 (Sat, 19 May 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+
+Improve description of contour3.
+
+------------------------------------------------------------------------
+r2470 | jcbowman | 2007-05-19 11:08:13 -0600 (Sat, 19 May 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/xasy3
+
+Speed up tick handler.
+
+------------------------------------------------------------------------
+r2469 | jcbowman | 2007-05-19 10:44:24 -0600 (Sat, 19 May 2007) | 3 lines
+Changed paths:
+ M /trunk/asymptote/asymptote.spec
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/process.cc
+
+Reinstate abbreviation q for quit, unless there exists a top-level variable of
+this name.
+
+------------------------------------------------------------------------
+r2468 | jcbowman | 2007-05-19 02:02:28 -0600 (Sat, 19 May 2007) | 3 lines
+Changed paths:
+ M /trunk/asymptote/base/animate.asy
+ M /trunk/asymptote/base/embed.asy
+ M /trunk/asymptote/base/external.asy
+ D /trunk/asymptote/base/pdfanim.asy
+ M /trunk/asymptote/doc/Makefile
+ D /trunk/asymptote/doc/PDFAnim_temp_Guide.tex
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/doc/extra/intro.asy
+ D /trunk/asymptote/doc/pdfanim_temp.sty
+ M /trunk/asymptote/examples/animations/pdfmovie.asy
+ M /trunk/asymptote/examples/slidemovies.asy
+
+Use easier-to-use animate.sty package instead of interim pdfanim_temp.sty
+package for generating pdf animations.
+
+------------------------------------------------------------------------
+r2467 | jcbowman | 2007-05-19 00:48:09 -0600 (Sat, 19 May 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/contour.asy
+ A /trunk/asymptote/base/contour3.asy
+ M /trunk/asymptote/doc/asymptote.texi
+ D /trunk/asymptote/doc/contour1.asy
+ D /trunk/asymptote/doc/contour2.asy
+ D /trunk/asymptote/doc/contour3.asy
+ A /trunk/asymptote/doc/irregularcontour.asy (from /trunk/asymptote/doc/contour3.asy:2461)
+ A /trunk/asymptote/doc/multicontour.asy (from /trunk/asymptote/doc/contour2.asy:2461)
+ A /trunk/asymptote/doc/onecontour.asy (from /trunk/asymptote/doc/contour1.asy:2461)
+ A /trunk/asymptote/examples/magnetic.asy
+
+Add support for drawing zero-level sets of functions from R^3 to R.
+
+------------------------------------------------------------------------
+r2466 | jcbowman | 2007-05-19 00:37:10 -0600 (Sat, 19 May 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/stats.asy
+ M /trunk/asymptote/doc/histogram.asy
+
+Fill in potential gaps between histogram bars when bars=false.
+
+------------------------------------------------------------------------
+r2465 | jcbowman | 2007-05-19 00:11:06 -0600 (Sat, 19 May 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/stats.asy
+ M /trunk/asymptote/doc/histogram.asy
+
+Simplify histogram interface.
+
+------------------------------------------------------------------------
+r2464 | jcbowman | 2007-05-19 00:09:42 -0600 (Sat, 19 May 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/plain_filldraw.asy
+
+Fix FillDraw pens.
+
+------------------------------------------------------------------------
+r2463 | hammera | 2007-05-18 13:35:20 -0600 (Fri, 18 May 2007) | 3 lines
+Changed paths:
+ M /trunk/asymptote/dec.cc
+ M /trunk/asymptote/newexp.cc
+ M /trunk/asymptote/newexp.h
+
+Minor refactoring.
+
+
+------------------------------------------------------------------------
+r2462 | hammera | 2007-05-18 13:34:40 -0600 (Fri, 18 May 2007) | 3 lines
+Changed paths:
+ M /trunk/asymptote/errors
+ M /trunk/asymptote/fundec.cc
+ M /trunk/asymptote/varinit.cc
+
+Got rid of annoying "no default init for <error>" message.
+Fix a boolean flag mixup.
+
+------------------------------------------------------------------------
+r2461 | oshardt | 2007-05-18 11:08:24 -0600 (Fri, 18 May 2007) | 1 line
+Changed paths:
+ M /trunk/asymptote/patches/README
+
+Acknowledged source of Imaging-1.1.6 patch
+------------------------------------------------------------------------
+r2460 | oshardt | 2007-05-18 11:07:33 -0600 (Fri, 18 May 2007) | 1 line
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+
+Documented the enabling of PNG format in xasy
+------------------------------------------------------------------------
+r2459 | jcbowman | 2007-05-17 21:51:53 -0600 (Thu, 17 May 2007) | 2 lines
+Changed paths:
+ D /trunk/asymptote/xasy3Imgs
+
+Remove unused directory.
+
+------------------------------------------------------------------------
+r2458 | jcbowman | 2007-05-17 21:48:50 -0600 (Thu, 17 May 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/fpu.h
+
+Add default argument.
+
+------------------------------------------------------------------------
+r2457 | oshardt | 2007-05-17 14:47:36 -0600 (Thu, 17 May 2007) | 1 line
+Changed paths:
+ M /trunk/asymptote/xasy3
+
+Documented use of base64
+------------------------------------------------------------------------
+r2456 | oshardt | 2007-05-17 13:45:12 -0600 (Thu, 17 May 2007) | 1 line
+Changed paths:
+ M /trunk/asymptote/xasy3
+
+Provided ability to draw a selection box to select all items in the box. Added item scroll up/down feature. Embedded the toolbar icon images into the source code.
+------------------------------------------------------------------------
+r2455 | oshardt | 2007-05-17 13:42:01 -0600 (Thu, 17 May 2007) | 1 line
+Changed paths:
+ M /trunk/asymptote/xasy3Imgs/horizMove.gif
+ M /trunk/asymptote/xasy3Imgs/move.gif
+ M /trunk/asymptote/xasy3Imgs/rotate.gif
+ M /trunk/asymptote/xasy3Imgs/text.gif
+ M /trunk/asymptote/xasy3Imgs/vertiMove.gif
+
+Arrows in icons are now the same style as Asymptote arrows. Transparency of text.gif fixed.
+------------------------------------------------------------------------
+r2454 | jcbowman | 2007-05-17 09:19:11 -0600 (Thu, 17 May 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/stats.asy
+ M /trunk/asymptote/doc/histogram.asy
+
+Added support for fillpen, drawpen, and legend entries to histogram.
+
+------------------------------------------------------------------------
+r2453 | jcbowman | 2007-05-17 09:12:11 -0600 (Thu, 17 May 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/plain_markers.asy
+
+Adjust legendline length to account for marker size.
+
+------------------------------------------------------------------------
+r2452 | jcbowman | 2007-05-17 09:10:53 -0600 (Thu, 17 May 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/plain_arrows.asy
+
+Minor optimization.
+
+------------------------------------------------------------------------
+r2451 | oshardt | 2007-05-16 17:28:12 -0600 (Wed, 16 May 2007) | 1 line
+Changed paths:
+ M /trunk/asymptote/xasy3
+
+Improved handling of highlighting when mouse enters and leaves an item.
+------------------------------------------------------------------------
+r2450 | oshardt | 2007-05-16 15:09:06 -0600 (Wed, 16 May 2007) | 1 line
+Changed paths:
+ M /trunk/asymptote/xasy3
+
+Various improvements to xasy3 made including ability to select and move multiple objects, and fixed the ability to open additional files.
+------------------------------------------------------------------------
+r2449 | oshardt | 2007-05-16 15:04:29 -0600 (Wed, 16 May 2007) | 1 line
+Changed paths:
+ A /trunk/asymptote/xasy3Imgs/select.gif
+
+Added new icon for xasy3 toolbar.
+------------------------------------------------------------------------
+r2448 | oshardt | 2007-05-16 15:02:55 -0600 (Wed, 16 May 2007) | 1 line
+Changed paths:
+ M /trunk/asymptote/patches/TkAlpha-Imaging-1.1.6.patch
+
+Updated Imaging-1.1.6 patch to adhere to conventions of other patches.
+------------------------------------------------------------------------
+r2447 | jcbowman | 2007-05-16 07:29:59 -0600 (Wed, 16 May 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/xasy3
+
+Speed up tickHandler; use default asy xformat.
+
+------------------------------------------------------------------------
+r2446 | jcbowman | 2007-05-15 23:14:35 -0600 (Tue, 15 May 2007) | 4 lines
+Changed paths:
+ M /trunk/asymptote/patches/README
+ M /trunk/asymptote/picture.cc
+ M /trunk/asymptote/picture.h
+ M /trunk/asymptote/runtime.in
+ M /trunk/asymptote/settings.cc
+ M /trunk/asymptote/xasy
+ M /trunk/asymptote/xasy3
+
+Optionally support transparent png deconstruction.
+
+Work around half-pixel bounding box bug in Ghostscript pngalpha driver.
+
+------------------------------------------------------------------------
+r2445 | oshardt | 2007-05-15 15:04:55 -0600 (Tue, 15 May 2007) | 1 line
+Changed paths:
+ M /trunk/asymptote/patches/README
+ A /trunk/asymptote/patches/TkAlpha-Imaging-1.1.6.patch
+
+Provided a patch to allow better alpha support in the PIL's ImageTk for the new GUI
+------------------------------------------------------------------------
+r2444 | jcbowman | 2007-05-15 15:00:09 -0600 (Tue, 15 May 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+
+Fix typo.
+
+------------------------------------------------------------------------
+r2443 | jcbowman | 2007-05-15 10:37:32 -0600 (Tue, 15 May 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/math.asy
+
+Fix typo.
+
+------------------------------------------------------------------------
+r2442 | jcbowman | 2007-05-15 10:36:47 -0600 (Tue, 15 May 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/math.asy
+
+Fixed comment.
+
+------------------------------------------------------------------------
+r2441 | jcbowman | 2007-05-15 09:13:34 -0600 (Tue, 15 May 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/math.asy
+
+Fix increasing(real[],true).
+
+------------------------------------------------------------------------
+r2440 | jcbowman | 2007-05-15 08:53:40 -0600 (Tue, 15 May 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/interpolate.asy
+ M /trunk/asymptote/base/math.asy
+
+Check that array x is strictly increasing.
+
+------------------------------------------------------------------------
+r2439 | jcbowman | 2007-05-14 13:20:48 -0600 (Mon, 14 May 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/animate.asy
+ M /trunk/asymptote/main.cc
+ M /trunk/asymptote/picture.cc
+ M /trunk/asymptote/picture.h
+ M /trunk/asymptote/process.cc
+ M /trunk/asymptote/process.h
+ M /trunk/asymptote/runtime.in
+ M /trunk/asymptote/xasy
+ M /trunk/asymptote/xasy3
+
+Implement bidirectional signal handling to new GUI (under development).
+
+------------------------------------------------------------------------
+r2438 | jcbowman | 2007-05-13 10:07:35 -0600 (Sun, 13 May 2007) | 4 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.sty
+ M /trunk/asymptote/doc/asymptote.texi
+
+Generate begin and end figure comments.
+
+Documentation updates.
+
+------------------------------------------------------------------------
+r2437 | jcbowman | 2007-05-12 23:02:04 -0600 (Sat, 12 May 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/picture.cc
+
+Explicitly close EPS output file to avoid race condition with gv.
+
+------------------------------------------------------------------------
+r2436 | jcbowman | 2007-05-12 17:12:57 -0600 (Sat, 12 May 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/path.cc
+
+Increase arctime precision.
+
+------------------------------------------------------------------------
+r2435 | jcbowman | 2007-05-12 11:59:20 -0600 (Sat, 12 May 2007) | 4 lines
+Changed paths:
+ M /trunk/asymptote/base/three.asy
+ M /trunk/asymptote/path.cc
+ M /trunk/asymptote/path.h
+ M /trunk/asymptote/simpson.cc
+
+Fix remaining numerical resolution problems with dir.
+
+Avoid arctime error when goal == L.
+
+------------------------------------------------------------------------
+r2434 | oshardt | 2007-05-12 09:34:16 -0600 (Sat, 12 May 2007) | 1 line
+Changed paths:
+ M /trunk/asymptote/xasy3
+ D /trunk/asymptote/xasy3Imgs/RESET
+
+Fixed images for xasy3
+------------------------------------------------------------------------
+r2433 | oshardt | 2007-05-12 09:31:20 -0600 (Sat, 12 May 2007) | 1 line
+Changed paths:
+ A /trunk/asymptote/xasy3Imgs
+ A /trunk/asymptote/xasy3Imgs/RESET
+ A /trunk/asymptote/xasy3Imgs/drawBezi.gif
+ A /trunk/asymptote/xasy3Imgs/drawEllip.gif
+ A /trunk/asymptote/xasy3Imgs/drawLines.gif
+ A /trunk/asymptote/xasy3Imgs/drawPoly.gif
+ A /trunk/asymptote/xasy3Imgs/drawShape.gif
+ A /trunk/asymptote/xasy3Imgs/fillEllip.gif
+ A /trunk/asymptote/xasy3Imgs/fillPoly.gif
+ A /trunk/asymptote/xasy3Imgs/fillShape.gif
+ A /trunk/asymptote/xasy3Imgs/horizMove.gif
+ A /trunk/asymptote/xasy3Imgs/lower.gif
+ A /trunk/asymptote/xasy3Imgs/move.gif
+ A /trunk/asymptote/xasy3Imgs/raise.gif
+ A /trunk/asymptote/xasy3Imgs/rotate.gif
+ A /trunk/asymptote/xasy3Imgs/text.gif
+ A /trunk/asymptote/xasy3Imgs/vertiMove.gif
+
+Images for xasy3
+------------------------------------------------------------------------
+r2432 | oshardt | 2007-05-12 09:25:40 -0600 (Sat, 12 May 2007) | 1 line
+Changed paths:
+ A /trunk/asymptote/xasy3
+
+Added xasy3 - a new GUI
+------------------------------------------------------------------------
+r2431 | jcbowman | 2007-05-11 17:23:02 -0600 (Fri, 11 May 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/doc/datagraph.asy
+
+Documentation updates.
+
+------------------------------------------------------------------------
+r2430 | jcbowman | 2007-05-11 07:05:05 -0600 (Fri, 11 May 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/fileio.h
+
+Suppress extra newline on standard EOF reads in absence of readline library.
+
+------------------------------------------------------------------------
+r2429 | jcbowman | 2007-05-10 22:37:15 -0600 (Thu, 10 May 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/castop.h
+ M /trunk/asymptote/fileio.h
+
+Fix standard input of strings.
+
+------------------------------------------------------------------------
+r2428 | jcbowman | 2007-05-10 14:45:56 -0600 (Thu, 10 May 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/picture.cc
+ M /trunk/asymptote/runtime.in
+
+Change SIGUSR to SIGINT and output a final box file to indicate end-of-sequence.
+
+------------------------------------------------------------------------
+r2427 | jcbowman | 2007-05-10 14:44:57 -0600 (Thu, 10 May 2007) | 3 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/process.cc
+
+Remove "q" as abbreviation for interactive "quit" command now that
+"write(q)" at the prompt can be written simply as "q".
+
+------------------------------------------------------------------------
+r2426 | jcbowman | 2007-05-10 07:18:45 -0600 (Thu, 10 May 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/examples/spline.asy
+
+Document dot(picture,real[],real[],pen);
+
+------------------------------------------------------------------------
+r2425 | jcbowman | 2007-05-10 07:10:00 -0600 (Thu, 10 May 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/interpolate.asy
+ M /trunk/asymptote/base/plain_markers.asy
+ M /trunk/asymptote/base/splinetype.asy
+ M /trunk/asymptote/doc/asymptote.texi
+ A /trunk/asymptote/examples/spline.asy
+
+Add piecewise monotonic spline type and example.
+
+------------------------------------------------------------------------
+r2424 | jcbowman | 2007-05-09 23:05:15 -0600 (Wed, 09 May 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/three.asy
+ M /trunk/asymptote/path.cc
+ M /trunk/asymptote/path.h
+
+Use subpath to implement robust dir(path, real) function.
+
+------------------------------------------------------------------------
+r2423 | jcbowman | 2007-05-09 20:02:21 -0600 (Wed, 09 May 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/three.asy
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/doc/markers2.asy
+ M /trunk/asymptote/path.h
+
+Fix endpoint dir(path, real) calculation.
+
+------------------------------------------------------------------------
+r2422 | jcbowman | 2007-05-09 18:16:54 -0600 (Wed, 09 May 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/Makefile.in
+
+Use datarootdir.
+
+------------------------------------------------------------------------
+r2421 | jcbowman | 2007-05-09 18:15:43 -0600 (Wed, 09 May 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/configure.ac
+
+Support --enable-gc=PREFIX.
+
+------------------------------------------------------------------------
+r2420 | jcbowman | 2007-05-09 12:41:48 -0600 (Wed, 09 May 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/picture.cc
+
+When settings.signal=true, write a separate .box file for each object.
+
+------------------------------------------------------------------------
+r2419 | jcbowman | 2007-05-09 11:58:15 -0600 (Wed, 09 May 2007) | 6 lines
+Changed paths:
+ M /trunk/asymptote/base/three.asy
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/path.cc
+ M /trunk/asymptote/path.h
+ M /trunk/asymptote/runtime.in
+
+Port 2D dir changes to 3D.
+
+Standardize argument names for point, precontrol, postcontrol, dir, and subpath.
+
+Avoid numerical overflows in three.asy solver.
+
+------------------------------------------------------------------------
+r2418 | jcbowman | 2007-05-08 22:06:12 -0600 (Tue, 08 May 2007) | 4 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/drawpath.cc
+ M /trunk/asymptote/path.cc
+ M /trunk/asymptote/path.h
+ M /trunk/asymptote/runtime.in
+
+Fix definition of dir.
+
+Add optional final argument to dir specify incoming and outgoing directions.
+
+------------------------------------------------------------------------
+r2417 | jcbowman | 2007-05-08 13:10:09 -0600 (Tue, 08 May 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/runtime.in
+
+Swap xasy signals.
+
+------------------------------------------------------------------------
+r2416 | jcbowman | 2007-05-08 13:06:40 -0600 (Tue, 08 May 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+
+Fix URL formatting.
+
+------------------------------------------------------------------------
+r2415 | jcbowman | 2007-05-08 04:08:38 -0600 (Tue, 08 May 2007) | 1 line
+Changed paths:
+ M /trunk/asymptote/configure.ac
+
+Increment version to 1.29svn
+------------------------------------------------------------------------
+r2414 | jcbowman | 2007-05-08 03:16:55 -0600 (Tue, 08 May 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/plain_shipout.asy
+
+Force uptodate to be true just before call to C++ shipout routine.
+
+------------------------------------------------------------------------
+r2413 | jcbowman | 2007-05-08 03:09:49 -0600 (Tue, 08 May 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/Makefile.in
+
+Swap gc library load order.
+
+------------------------------------------------------------------------
+r2412 | jcbowman | 2007-05-07 23:38:33 -0600 (Mon, 07 May 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/castop.h
+ M /trunk/asymptote/fileio.h
+ M /trunk/asymptote/runtime.in
+
+Purge standard input after reading in interactive mode.
+
+------------------------------------------------------------------------
+r2411 | jcbowman | 2007-05-07 18:03:27 -0600 (Mon, 07 May 2007) | 3 lines
+Changed paths:
+ M /trunk/asymptote/interact.cc
+ M /trunk/asymptote/runtime.in
+
+Fix segmentation fault in readline() and runaway process on reading EOF from
+standard input in absence of readline library.
+
+------------------------------------------------------------------------
+r2410 | jcbowman | 2007-05-07 17:32:17 -0600 (Mon, 07 May 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/Makefile.in
+
+Add GCPPLIB target.
+
+------------------------------------------------------------------------
+r2409 | jcbowman | 2007-05-07 15:21:27 -0600 (Mon, 07 May 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/Makefile.in
+ M /trunk/asymptote/configure.ac
+ M /trunk/asymptote/doc/asymptote.texi
+
+Support parallel builds.
+
+------------------------------------------------------------------------
+r2408 | jcbowman | 2007-05-07 14:36:53 -0600 (Mon, 07 May 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/picture.cc
+ M /trunk/asymptote/runtime.in
+
+Use SIGUSR1 and SIGUSR2 to communicate with new version of xasy.
+
+------------------------------------------------------------------------
+r2407 | jcbowman | 2007-05-07 11:51:01 -0600 (Mon, 07 May 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/asymptote.spec
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/xstream.h
+
+Simplify and optimize xstream header.
+
+------------------------------------------------------------------------
+r2406 | jcbowman | 2007-05-07 02:04:59 -0600 (Mon, 07 May 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/picture.cc
+ M /trunk/asymptote/settings.cc
+
+Add dvipsOptions configuration variable.
+
+------------------------------------------------------------------------
+r2405 | jcbowman | 2007-05-07 01:32:37 -0600 (Mon, 07 May 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/fileio.h
+ M /trunk/asymptote/xstream.h
+
+Fix bug in xinput.
+
+------------------------------------------------------------------------
+r2404 | jcbowman | 2007-05-06 22:49:39 -0600 (Sun, 06 May 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/Makefile
+ M /trunk/asymptote/doc/asymptote.texi
+
+Further parallel documentation build improvements.
+
+------------------------------------------------------------------------
+r2403 | jcbowman | 2007-05-06 22:39:54 -0600 (Sun, 06 May 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/Makefile
+ M /trunk/asymptote/doc/asymptote.texi
+
+Improve support for parallel documentation builds.
+
+------------------------------------------------------------------------
+r2402 | jcbowman | 2007-05-06 22:03:35 -0600 (Sun, 06 May 2007) | 3 lines
+Changed paths:
+ M /trunk/asymptote/base/animate.asy
+
+Support nonglobal animations, where each frame is scaled and written to a
+file separately.
+
+------------------------------------------------------------------------
+r2401 | jcbowman | 2007-05-06 21:38:48 -0600 (Sun, 06 May 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/fftw++.h
+ M /trunk/asymptote/item.h
+
+Support gcc version 4.3.
+
+------------------------------------------------------------------------
+r2400 | jcbowman | 2007-05-06 14:10:08 -0600 (Sun, 06 May 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+
+Documentation updates.
+
+------------------------------------------------------------------------
+r2399 | jcbowman | 2007-05-06 13:53:36 -0600 (Sun, 06 May 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/Makefile
+
+Support parallel documentation builds.
+
+------------------------------------------------------------------------
+r2398 | jcbowman | 2007-05-06 12:03:58 -0600 (Sun, 06 May 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/Makefile.in
+ M /trunk/asymptote/doc/Makefile
+
+Remove intro target to avoid problems under Fedora Core 5.
+
+------------------------------------------------------------------------
+r2397 | jcbowman | 2007-05-06 11:31:08 -0600 (Sun, 06 May 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/plain_picture.asy
+ M /trunk/asymptote/base/plain_shipout.asy
+ M /trunk/asymptote/drawlabel.cc
+ M /trunk/asymptote/picture.cc
+
+Improve TeX error handling.
+
+------------------------------------------------------------------------
+r2396 | jcbowman | 2007-05-05 21:53:16 -0600 (Sat, 05 May 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/Makefile.in
+ M /trunk/asymptote/doc/Makefile
+
+Minor makefile edits.
+
+------------------------------------------------------------------------
+r2395 | jcbowman | 2007-05-05 10:54:13 -0600 (Sat, 05 May 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/asymptote.spec
+
+Update URL.
+
+------------------------------------------------------------------------
+r2394 | jcbowman | 2007-05-05 03:01:44 -0600 (Sat, 05 May 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/Makefile
+
+Clean up generated files.
+
+------------------------------------------------------------------------
+r2393 | jcbowman | 2007-05-05 03:00:52 -0600 (Sat, 05 May 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/configure.ac
+
+Increment version to 1.28svn.
+
+------------------------------------------------------------------------
+r2392 | jcbowman | 2007-05-05 01:49:44 -0600 (Sat, 05 May 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/runtime.in
+
+Fix warning messages.
+
+------------------------------------------------------------------------
+r2391 | jcbowman | 2007-05-05 01:35:45 -0600 (Sat, 05 May 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/fileio.h
+ M /trunk/asymptote/runtime.in
+
+Fix warning messages.
+
+------------------------------------------------------------------------
+r2390 | jcbowman | 2007-05-05 00:47:58 -0600 (Sat, 05 May 2007) | 4 lines
+Changed paths:
+ M /trunk/asymptote/base/animate.asy
+ M /trunk/asymptote/base/graph.asy
+ M /trunk/asymptote/base/palette.asy
+ A /trunk/asymptote/doc/HermiteSpline.asy
+
+Add example showing Hermite spline interpolation and filled cyclic crosses.
+
+Fix formatting.
+
+------------------------------------------------------------------------
+r2389 | jcbowman | 2007-05-05 00:07:03 -0600 (Sat, 05 May 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/palette.asy
+
+Optimize palette loops.
+
+------------------------------------------------------------------------
+r2388 | jcbowman | 2007-05-04 23:43:14 -0600 (Fri, 04 May 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/palette.asy
+
+Fix data cropping/scaling.
+
+------------------------------------------------------------------------
+r2387 | jcbowman | 2007-05-04 23:37:08 -0600 (Fri, 04 May 2007) | 3 lines
+Changed paths:
+ M /trunk/asymptote/base/plain_markers.asy
+ M /trunk/asymptote/doc/asymptote.texi
+
+Add modified version of Stefan Knorr's unit n-point cyclic cross, with optional
+end rounding.
+
+------------------------------------------------------------------------
+r2386 | jcbowman | 2007-05-04 19:36:04 -0600 (Fri, 04 May 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/picture.cc
+
+Add remaining fix for MSWindows version of TeXLive 2007.
+
+------------------------------------------------------------------------
+r2385 | jcbowman | 2007-05-04 17:35:06 -0600 (Fri, 04 May 2007) | 3 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.sty
+
+Work around jobname bug in MiKTeX 2.5 and 2.6: turn stars in file names
+(resulting from spaces, etc.) into underscores.
+
+------------------------------------------------------------------------
+r2384 | jcbowman | 2007-05-04 10:39:03 -0600 (Fri, 04 May 2007) | 4 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/drawlabel.cc
+ M /trunk/asymptote/drawlabel.h
+ M /trunk/asymptote/picture.cc
+ M /trunk/asymptote/pipestream.h
+ M /trunk/asymptote/settings.cc
+
+Simplify tex pipe handshaking and improve error detection.
+
+Support TeXLive 2007 under MSWindows.
+
+------------------------------------------------------------------------
+r2383 | jcbowman | 2007-05-03 23:01:43 -0600 (Thu, 03 May 2007) | 6 lines
+Changed paths:
+ M /trunk/asymptote/base/solids.asy
+ M /trunk/asymptote/base/three.asy
+
+Don't allow rotation about the zero vector.
+
+Ensure align always returns a right-handed transform (a rotation).
+
+Fix longitudinal skeleton detection when axis=-Z.
+
+------------------------------------------------------------------------
+r2382 | jcbowman | 2007-05-03 21:47:55 -0600 (Thu, 03 May 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/math.asy
+
+Add routine to return a diagonal matrix.
+
+------------------------------------------------------------------------
+r2381 | hammera | 2007-05-03 10:22:29 -0600 (Thu, 03 May 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/TODO
+
+Removed finished item.
+
+------------------------------------------------------------------------
+r2380 | hammera | 2007-05-03 10:15:03 -0600 (Thu, 03 May 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/primitives.h
+
+Fixed typo.
+
+------------------------------------------------------------------------
+r2379 | hammera | 2007-05-03 10:11:22 -0600 (Thu, 03 May 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/exp.h
+ M /trunk/asymptote/stm.cc
+
+Assign expression are no longer written at the prompt.
+
+------------------------------------------------------------------------
+r2378 | jcbowman | 2007-05-02 18:02:32 -0600 (Wed, 02 May 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/runtime.in
+ M /trunk/asymptote/settings.cc
+
+Add -signal option for signalling completion of shipout to xasy.
+
+------------------------------------------------------------------------
+r2377 | jcbowman | 2007-05-02 09:57:30 -0600 (Wed, 02 May 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/graph.asy
+ M /trunk/asymptote/base/interpolate.asy
+
+Simplify use of join operator.
+
+------------------------------------------------------------------------
+r2376 | jcbowman | 2007-05-02 09:56:36 -0600 (Wed, 02 May 2007) | 4 lines
+Changed paths:
+ M /trunk/asymptote/base/contour.asy
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/examples/fillcontour.asy
+
+Change return type of contour routines back to guide[][] both for backwards
+compatibility and in case user wants to connect smoothly to external
+noncyclic contours.
+
+------------------------------------------------------------------------
+r2375 | jcbowman | 2007-05-02 01:45:46 -0600 (Wed, 02 May 2007) | 11 lines
+Changed paths:
+ M /trunk/asymptote/TODO
+ M /trunk/asymptote/base/contour.asy
+ M /trunk/asymptote/base/graph.asy
+ M /trunk/asymptote/base/graph3.asy
+ M /trunk/asymptote/base/graph_settings.asy
+ M /trunk/asymptote/base/interpolate.asy
+ M /trunk/asymptote/base/math.asy
+ M /trunk/asymptote/base/palette.asy
+ A /trunk/asymptote/base/splinetype.asy
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/examples/fillcontour.asy
+
+Add Hermite spline graph interpolate type for smoothly joining sampled
+functions.
+
+Change return type of contour routines to path[][].
+
+Move splinetype routines to new file splinetype.asy.
+
+Add bool increasing(real[] x) routine to math.asy.
+
+Optimize image scaling.
+
+------------------------------------------------------------------------
+r2374 | jcbowman | 2007-05-02 01:38:41 -0600 (Wed, 02 May 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/guide.h
+
+Make guide precision consistent with path precision in diagnostics.
+
+------------------------------------------------------------------------
+r2373 | hammera | 2007-05-01 18:52:48 -0600 (Tue, 01 May 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/plain_paths.asy
+ M /trunk/asymptote/base/three.asy
+ M /trunk/asymptote/camp.l
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/guide.h
+ M /trunk/asymptote/knot.h
+ M /trunk/asymptote/primitives.h
+ M /trunk/asymptote/runtime.in
+ M /trunk/asymptote/tests/types/spec.asy
+ M /trunk/asymptote/types.cc
+
+Added curlSpecifier. Removed curl3.
+
+------------------------------------------------------------------------
+r2372 | hammera | 2007-05-01 11:37:51 -0600 (Tue, 01 May 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/plain_paths.asy
+ M /trunk/asymptote/base/three.asy
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/guide.h
+ M /trunk/asymptote/primitives.h
+ M /trunk/asymptote/runtime.in
+ M /trunk/asymptote/tests/types/spec.asy
+ M /trunk/asymptote/types.cc
+
+Added the tensionSpecifier type. Removed tension3.
+
+------------------------------------------------------------------------
+r2371 | jcbowman | 2007-04-30 21:18:41 -0600 (Mon, 30 Apr 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+
+Updated documentation regarding change from cycle3 to cycle.
+
+------------------------------------------------------------------------
+r2370 | hammera | 2007-04-30 00:22:30 -0600 (Mon, 30 Apr 2007) | 2 lines
+Changed paths:
+ A /trunk/asymptote/tests/types/spec.asy
+
+Test for the cycle keyword.
+
+------------------------------------------------------------------------
+r2369 | hammera | 2007-04-29 22:47:46 -0600 (Sun, 29 Apr 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/graph3.asy
+ M /trunk/asymptote/base/solids.asy
+ M /trunk/asymptote/base/surface.asy
+ M /trunk/asymptote/base/three.asy
+ M /trunk/asymptote/camp.l
+ M /trunk/asymptote/camp.y
+ M /trunk/asymptote/doc/GaussianSurface.asy
+ M /trunk/asymptote/doc/saddle.asy
+ M /trunk/asymptote/doc/unitcircle3.asy
+ M /trunk/asymptote/examples/conicurv.asy
+ M /trunk/asymptote/examples/equilchord.asy
+ M /trunk/asymptote/examples/near_earth.asy
+ M /trunk/asymptote/examples/shellmethod.asy
+ M /trunk/asymptote/examples/shellsqrtx01.asy
+ M /trunk/asymptote/examples/washermethod.asy
+ M /trunk/asymptote/examples/wedge.asy
+ M /trunk/asymptote/examples/xxsq01.asy
+ M /trunk/asymptote/examples/xxsq01x-1.asy
+ M /trunk/asymptote/examples/xxsq01y.asy
+ M /trunk/asymptote/exp.cc
+ M /trunk/asymptote/exp.h
+ M /trunk/asymptote/guide.h
+ M /trunk/asymptote/primitives.h
+ M /trunk/asymptote/runtime.in
+
+Added the cycleToken type. Changed cycle3 to cycle.
+
+------------------------------------------------------------------------
+r2368 | hammera | 2007-04-29 15:05:21 -0600 (Sun, 29 Apr 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/TODO
+ M /trunk/asymptote/builtin.cc
+ A /trunk/asymptote/primitives.h
+ M /trunk/asymptote/types.cc
+ M /trunk/asymptote/types.h
+
+Use an C Preprocessor X-Macro to create new primitive types.
+
+------------------------------------------------------------------------
+r2367 | hammera | 2007-04-28 15:56:59 -0600 (Sat, 28 Apr 2007) | 3 lines
+Changed paths:
+ D /trunk/asymptote/cast.h
+
+Remove old, unused source file.
+
+
+------------------------------------------------------------------------
+r2366 | jcbowman | 2007-04-28 11:39:37 -0600 (Sat, 28 Apr 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/Makefile
+ M /trunk/asymptote/doc/bezier2.asy
+ M /trunk/asymptote/doc/beziercurve.asy
+
+Make Bezier curve solid and control lines dashed.
+
+------------------------------------------------------------------------
+r2365 | jcbowman | 2007-04-28 01:15:13 -0600 (Sat, 28 Apr 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/interpolate.asy
+
+Minor optimizations.
+
+------------------------------------------------------------------------
+r2364 | jcbowman | 2007-04-28 00:37:32 -0600 (Sat, 28 Apr 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/interpolate.asy
+
+Remove unused array.
+
+------------------------------------------------------------------------
+r2363 | jcbowman | 2007-04-28 00:34:47 -0600 (Sat, 28 Apr 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/interpolate.asy
+
+Use a simpler argument list for clamped splines.
+
+------------------------------------------------------------------------
+r2362 | jcbowman | 2007-04-27 20:59:35 -0600 (Fri, 27 Apr 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/Makefile.in
+ M /trunk/asymptote/doc/Makefile
+ M /trunk/asymptote/doc/asymptote.texi
+ A /trunk/asymptote/doc/extra
+ A /trunk/asymptote/doc/extra/intro.asy (from /trunk/asymptote/doc/intro.asy:2357)
+ A /trunk/asymptote/doc/extra/intro_.bbl (from /trunk/asymptote/doc/intro_.bbl:2357)
+ D /trunk/asymptote/doc/intro.asy
+ D /trunk/asymptote/doc/intro_.bbl
+
+Don't try to build intro.pdf with default install (due to eforms dependency).
+
+------------------------------------------------------------------------
+r2361 | hammera | 2007-04-27 08:26:54 -0600 (Fri, 27 Apr 2007) | 3 lines
+Changed paths:
+ D /trunk/asymptote/cast.cc
+
+This file hasn't been used in ages
+
+
+------------------------------------------------------------------------
+r2360 | hammera | 2007-04-26 07:03:57 -0600 (Thu, 26 Apr 2007) | 3 lines
+Changed paths:
+ M /trunk/asymptote/runtime.in
+ M /trunk/asymptote/types.cc
+ M /trunk/asymptote/types.h
+
+Removed primArray. arrays are not primitive, and the type could only be only
+erroneously.
+
+------------------------------------------------------------------------
+r2359 | jcbowman | 2007-04-23 11:09:51 -0600 (Mon, 23 Apr 2007) | 7 lines
+Changed paths:
+ M /trunk/asymptote/castop.h
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/fileio.h
+ M /trunk/asymptote/runtime.in
+ M /trunk/asymptote/xstream.h
+
+Rename "append=false" argument of output, boutput, and xoutput to
+"update=false" and make it allow both reads and writes to the data file.
+
+Negative arguments to seek are relative to end of file.
+
+Add seekeof(file) to position file pointer to end-of-file.
+
+------------------------------------------------------------------------
+r2358 | jcbowman | 2007-04-21 21:38:16 -0600 (Sat, 21 Apr 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/Makefile
+
+Fix dependencies.
+
+------------------------------------------------------------------------
+r2357 | jcbowman | 2007-04-21 19:41:32 -0600 (Sat, 21 Apr 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/asymptote.spec
+ A /trunk/asymptote/doc/pixel.pdf
+ D /trunk/asymptote/doc/pixel.ps
+
+Distribute pixel.pdf rather than pixel.ps.
+
+------------------------------------------------------------------------
+r2356 | jcbowman | 2007-04-21 18:00:10 -0600 (Sat, 21 Apr 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/animate.asy
+ M /trunk/asymptote/doc/asymptote.texi
+
+Add ability to load pdf animations from an external file (one frame/page).
+
+------------------------------------------------------------------------
+r2355 | jcbowman | 2007-04-21 14:20:48 -0600 (Sat, 21 Apr 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/plain_filldraw.asy
+ M /trunk/asymptote/base/plain_picture.asy
+ M /trunk/asymptote/doc/asymptote.texi
+
+Make filloutside work with paths that extend beyond the current boundary.
+
+------------------------------------------------------------------------
+r2354 | jcbowman | 2007-04-21 10:55:14 -0600 (Sat, 21 Apr 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/graph.asy
+ M /trunk/asymptote/base/pdfanim.asy
+ M /trunk/asymptote/base/plain.asy
+ M /trunk/asymptote/base/slide.asy
+ M /trunk/asymptote/doc/Bode.asy
+ M /trunk/asymptote/doc/CAD1.asy
+ M /trunk/asymptote/doc/CDlabel.asy
+ M /trunk/asymptote/doc/colors.asy
+ M /trunk/asymptote/doc/contour2.asy
+ M /trunk/asymptote/doc/diatom.asy
+ M /trunk/asymptote/doc/flowchartdemo.asy
+ M /trunk/asymptote/doc/generalaxis.asy
+ M /trunk/asymptote/doc/generalaxis3.asy
+ M /trunk/asymptote/doc/image.asy
+ M /trunk/asymptote/doc/imagecontour.asy
+ M /trunk/asymptote/doc/intro.asy
+ M /trunk/asymptote/doc/join.asy
+ M /trunk/asymptote/doc/join3.asy
+ M /trunk/asymptote/doc/loggrid.asy
+ M /trunk/asymptote/doc/logimage.asy
+ M /trunk/asymptote/doc/logticks.asy
+ M /trunk/asymptote/doc/markers1.asy
+ M /trunk/asymptote/doc/markers2.asy
+ M /trunk/asymptote/doc/monthaxis.asy
+ M /trunk/asymptote/doc/secondaryaxis.asy
+ M /trunk/asymptote/doc/westnile.asy
+ M /trunk/asymptote/examples/BezierSurface.asy
+ M /trunk/asymptote/examples/Gouraudcontour.asy
+ M /trunk/asymptote/examples/advection.asy
+ M /trunk/asymptote/examples/conicurv.asy
+ M /trunk/asymptote/examples/dimension.asy
+ M /trunk/asymptote/examples/dragon.asy
+ M /trunk/asymptote/examples/fillcontour.asy
+ M /trunk/asymptote/examples/hyperboloid.asy
+ M /trunk/asymptote/examples/imagehistogram.asy
+ M /trunk/asymptote/examples/interpolate1.asy
+ M /trunk/asymptote/examples/latticeshading.asy
+ M /trunk/asymptote/examples/mosaic.asy
+ M /trunk/asymptote/examples/mosquito.asy
+ M /trunk/asymptote/examples/slidedemo.asy
+ M /trunk/asymptote/examples/slidemovies.asy
+ M /trunk/asymptote/examples/thermodynamics.asy
+
+Fix formatting.
+
+------------------------------------------------------------------------
+r2353 | jcbowman | 2007-04-21 10:44:18 -0600 (Sat, 21 Apr 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/asy-mode.el
+
+Fix top level indentation of braces.
+
+------------------------------------------------------------------------
+r2352 | jcbowman | 2007-04-20 23:01:52 -0600 (Fri, 20 Apr 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/intro.asy
+
+Simplify control panel.
+
+------------------------------------------------------------------------
+r2351 | jcbowman | 2007-04-20 22:51:17 -0600 (Fri, 20 Apr 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/intro.asy
+
+Added PDF rolling wheel animation.
+
+------------------------------------------------------------------------
+r2350 | jcbowman | 2007-04-20 22:50:13 -0600 (Fri, 20 Apr 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/animate.asy
+
+Delete temporary .aux file.
+
+------------------------------------------------------------------------
+r2349 | jcbowman | 2007-04-19 22:53:07 -0600 (Thu, 19 Apr 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/configure.ac
+
+Increment version to 1.27svn.
+
+------------------------------------------------------------------------
+r2348 | jcbowman | 2007-04-19 21:36:54 -0600 (Thu, 19 Apr 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/INSTALL
+ M /trunk/asymptote/asymptote.spec
+ M /trunk/asymptote/doc/asymptote.texi
+
+Rename source and UNIX binary files for compatibility with releaseforge.
+
+------------------------------------------------------------------------
+r2347 | jcbowman | 2007-04-19 18:22:10 -0600 (Thu, 19 Apr 2007) | 4 lines
+Changed paths:
+ M /trunk/asymptote/asymptote.spec
+ M /trunk/asymptote/base/three.asy
+ M /trunk/asymptote/knot.h
+
+Use a better camera-independent reference value for resolving path3 orientation.
+
+Check for negative curl values.
+
+------------------------------------------------------------------------
+r2346 | jcbowman | 2007-04-18 18:58:56 -0600 (Wed, 18 Apr 2007) | 5 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/patches/README
+ A /trunk/asymptote/patches/gv-3.6.2.patch
+ M /trunk/asymptote/picture.cc
+ M /trunk/asymptote/settings.cc
+ M /trunk/asymptote/settings.h
+
+Added patch to gv-3.6.2 to make redisplay work properly (and fix gv
+security hole).
+
+Removed --nowatch option from call to gv.
+
+------------------------------------------------------------------------
+r2345 | jcbowman | 2007-04-15 18:25:39 -0600 (Sun, 15 Apr 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/psfile.cc
+
+Remove unused (and unmatched) %%EndProlog line.
+
+------------------------------------------------------------------------
+r2344 | jcbowman | 2007-04-14 10:56:19 -0600 (Sat, 14 Apr 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+
+Remove unneeded access settings.
+
+------------------------------------------------------------------------
+r2343 | jcbowman | 2007-04-13 16:48:52 -0600 (Fri, 13 Apr 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/feynman.asy
+
+Support pdflatex texengine.
+
+------------------------------------------------------------------------
+r2342 | jcbowman | 2007-04-13 07:46:54 -0600 (Fri, 13 Apr 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/examples/integraltest.asy
+
+Improve example.
+
+------------------------------------------------------------------------
+r2341 | jcbowman | 2007-04-13 07:46:38 -0600 (Fri, 13 Apr 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/solids.asy
+
+Fix front/back transverse skeleton detection.
+
+------------------------------------------------------------------------
+r2340 | jcbowman | 2007-04-12 06:16:58 -0600 (Thu, 12 Apr 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/TODO
+
+New item.
+
+------------------------------------------------------------------------
+r2339 | jcbowman | 2007-04-11 21:21:57 -0600 (Wed, 11 Apr 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/TODO
+
+New item.
+
+------------------------------------------------------------------------
+r2338 | jcbowman | 2007-04-10 17:30:34 -0600 (Tue, 10 Apr 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/settings.cc
+
+Speed up detection code for old versions of gv.
+
+------------------------------------------------------------------------
+r2337 | jcbowman | 2007-04-10 13:44:56 -0600 (Tue, 10 Apr 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/FAQ/asy-faq.bfnn
+
+Add link to online example.
+
+------------------------------------------------------------------------
+r2336 | jcbowman | 2007-04-10 13:29:11 -0600 (Tue, 10 Apr 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/math.asy
+
+Add acsc, asec, and acot functions.
+
+------------------------------------------------------------------------
+r2335 | jcbowman | 2007-04-10 13:27:09 -0600 (Tue, 10 Apr 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+
+Fixed typo.
+
+------------------------------------------------------------------------
+r2334 | jcbowman | 2007-04-10 13:14:17 -0600 (Tue, 10 Apr 2007) | 5 lines
+Changed paths:
+ M /trunk/asymptote/base/graph.asy
+ M /trunk/asymptote/doc/Bode.asy
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/doc/brokenaxis.asy
+
+Implement Break tickmodifier to allow broken axes to work with automatic
+tick generation.
+
+Support broken logarithmic axes.
+
+------------------------------------------------------------------------
+r2333 | jcbowman | 2007-04-10 09:29:12 -0600 (Tue, 10 Apr 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/brokenaxis.asy
+
+Autogenerate tick values.
+
+------------------------------------------------------------------------
+r2332 | jcbowman | 2007-04-09 23:11:29 -0600 (Mon, 09 Apr 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/FAQ/asy-faq.bfnn
+
+Update FAQ.
+
+------------------------------------------------------------------------
+r2331 | jcbowman | 2007-04-09 23:02:39 -0600 (Mon, 09 Apr 2007) | 2 lines
+Changed paths:
+ A /trunk/asymptote/examples/alignedaxis.asy
+
+Add aligned axes example.
+
+------------------------------------------------------------------------
+r2330 | jcbowman | 2007-04-09 19:26:46 -0600 (Mon, 09 Apr 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/configure.ac
+
+Increment version to 1.26svn.
+
+------------------------------------------------------------------------
+r2329 | jcbowman | 2007-04-09 16:43:17 -0600 (Mon, 09 Apr 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/CAD.asy
+ M /trunk/asymptote/base/animate.asy
+ M /trunk/asymptote/base/binarytree.asy
+ M /trunk/asymptote/base/contour.asy
+ M /trunk/asymptote/base/embed.asy
+ M /trunk/asymptote/base/external.asy
+ M /trunk/asymptote/base/featpost3D.asy
+ M /trunk/asymptote/base/flowchart.asy
+ M /trunk/asymptote/base/geometry.asy
+ M /trunk/asymptote/base/graph.asy
+ M /trunk/asymptote/base/graph3.asy
+ M /trunk/asymptote/base/grid3.asy
+ M /trunk/asymptote/base/interpolate.asy
+ M /trunk/asymptote/base/labelpath.asy
+ M /trunk/asymptote/base/markers.asy
+ M /trunk/asymptote/base/pdfanim.asy
+ M /trunk/asymptote/base/plain.asy
+ M /trunk/asymptote/base/plain_Label.asy
+ M /trunk/asymptote/base/plain_arcs.asy
+ M /trunk/asymptote/base/plain_arrows.asy
+ M /trunk/asymptote/base/plain_boxes.asy
+ M /trunk/asymptote/base/plain_filldraw.asy
+ M /trunk/asymptote/base/plain_markers.asy
+ M /trunk/asymptote/base/plain_paths.asy
+ M /trunk/asymptote/base/plain_picture.asy
+ M /trunk/asymptote/base/plain_shipout.asy
+ M /trunk/asymptote/base/plain_strings.asy
+ M /trunk/asymptote/base/roundedpath.asy
+ M /trunk/asymptote/base/slide.asy
+ M /trunk/asymptote/base/stats.asy
+ M /trunk/asymptote/base/surface.asy
+ M /trunk/asymptote/base/syzygy.asy
+ M /trunk/asymptote/base/three.asy
+
+Untabified and standardized indentation of base files.
+
+------------------------------------------------------------------------
+r2328 | jcbowman | 2007-04-09 14:34:45 -0600 (Mon, 09 Apr 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+
+Update documentation.
+
+------------------------------------------------------------------------
+r2327 | jcbowman | 2007-04-09 14:27:36 -0600 (Mon, 09 Apr 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/interpolate.asy
+ M /trunk/asymptote/examples/interpolate1.asy
+
+Added spline interpolation routines.
+
+------------------------------------------------------------------------
+r2326 | jcbowman | 2007-04-09 11:41:35 -0600 (Mon, 09 Apr 2007) | 4 lines
+Changed paths:
+ A /trunk/asymptote/base/interpolate.asy
+ D /trunk/asymptote/doc/advection.asy
+ M /trunk/asymptote/doc/asymptote.texi
+ A /trunk/asymptote/examples/advection.asy (from /trunk/asymptote/doc/advection.asy:2317)
+ A /trunk/asymptote/examples/interpolate1.asy
+
+Add Olivier Guibe's interpolation module and example.
+
+Remove long examples from the documentation.
+
+------------------------------------------------------------------------
+r2325 | jcbowman | 2007-04-09 09:45:10 -0600 (Mon, 09 Apr 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/syzygy.asy
+ M /trunk/asymptote/doc/asymptote.texi
+
+Document syzygy module.
+
+------------------------------------------------------------------------
+r2324 | jcbowman | 2007-04-09 09:35:49 -0600 (Mon, 09 Apr 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/syzygy.asy
+
+Remove default initializers.
+
+------------------------------------------------------------------------
+r2323 | jcbowman | 2007-04-09 09:30:08 -0600 (Mon, 09 Apr 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/solids.asy
+
+Fix surface lighting.
+
+------------------------------------------------------------------------
+r2322 | jcbowman | 2007-04-09 00:27:58 -0600 (Mon, 09 Apr 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+
+Update documentation.
+
+------------------------------------------------------------------------
+r2321 | jcbowman | 2007-04-09 00:26:01 -0600 (Mon, 09 Apr 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/graph3.asy
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/examples/Klein.asy
+ M /trunk/asymptote/examples/parametricsurface.asy
+
+For parameterized surfaces, rename bool oriented=true to bool outward=false.
+
+------------------------------------------------------------------------
+r2320 | jcbowman | 2007-04-08 23:54:01 -0600 (Sun, 08 Apr 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+
+Improve discussion of surface orientation.
+
+------------------------------------------------------------------------
+r2319 | jcbowman | 2007-04-08 23:27:13 -0600 (Sun, 08 Apr 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+
+Document oriented option for drawing surfaces.
+
+------------------------------------------------------------------------
+r2318 | jcbowman | 2007-04-08 22:52:43 -0600 (Sun, 08 Apr 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/graph3.asy
+ M /trunk/asymptote/examples/Klein.asy
+
+Choose locally outward surface normal only for nonorientable surfaces.
+
+------------------------------------------------------------------------
+r2317 | jcbowman | 2007-04-08 21:41:35 -0600 (Sun, 08 Apr 2007) | 5 lines
+Changed paths:
+ M /trunk/asymptote/base/three.asy
+
+Make ^^ return a path3[] instead of a guide3[] for consistency with the 2D
+routines.
+
+Remove spurious specifier when writing a guide3.
+
+------------------------------------------------------------------------
+r2316 | jcbowman | 2007-04-08 17:43:53 -0600 (Sun, 08 Apr 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+
+Document string array reads under line mode.
+
+------------------------------------------------------------------------
+r2315 | jcbowman | 2007-04-08 17:31:00 -0600 (Sun, 08 Apr 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/fileio.cc
+ M /trunk/asymptote/fileio.h
+ M /trunk/asymptote/runtime.in
+
+Add white-space string delimiter mode word(file, bool b=true).
+
+------------------------------------------------------------------------
+r2314 | jcbowman | 2007-04-08 12:25:39 -0600 (Sun, 08 Apr 2007) | 3 lines
+Changed paths:
+ M /trunk/asymptote/picture.cc
+
+Explicitly write EPSF in output header rather than relying on dvips -E option
+(which doesn't work for even the first page of multipage documents).
+
+------------------------------------------------------------------------
+r2313 | jcbowman | 2007-04-07 23:21:51 -0600 (Sat, 07 Apr 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/graph3.asy
+
+More guide3 to path3 changes.
+
+------------------------------------------------------------------------
+r2312 | jcbowman | 2007-04-07 19:40:01 -0600 (Sat, 07 Apr 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/fileio.cc
+ M /trunk/asymptote/fileio.h
+
+Revert csv comment changes.
+
+------------------------------------------------------------------------
+r2311 | jcbowman | 2007-04-07 19:37:09 -0600 (Sat, 07 Apr 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/three.asy
+
+Remove spurious diagnostic.
+
+------------------------------------------------------------------------
+r2310 | jcbowman | 2007-04-07 18:43:10 -0600 (Sat, 07 Apr 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/geometry.asy
+ M /trunk/asymptote/base/graph.asy
+ M /trunk/asymptote/base/graph3.asy
+ M /trunk/asymptote/base/markers.asy
+ M /trunk/asymptote/base/palette.asy
+ M /trunk/asymptote/base/patterns.asy
+ M /trunk/asymptote/base/plain_arcs.asy
+ M /trunk/asymptote/base/plain_arrows.asy
+ M /trunk/asymptote/base/plain_boxes.asy
+ M /trunk/asymptote/base/plain_constants.asy
+ M /trunk/asymptote/base/plain_filldraw.asy
+ M /trunk/asymptote/base/plain_markers.asy
+ M /trunk/asymptote/base/plain_picture.asy
+ M /trunk/asymptote/base/solids.asy
+ M /trunk/asymptote/base/stats.asy
+ M /trunk/asymptote/base/three.asy
+ M /trunk/asymptote/doc/asymptote.texi
+
+Standardize path vs. guide.
+
+------------------------------------------------------------------------
+r2309 | jcbowman | 2007-04-07 18:42:27 -0600 (Sat, 07 Apr 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/FAQ/asy-faq.bfnn
+
+Update fixed graph size documentation.
+
+------------------------------------------------------------------------
+r2308 | jcbowman | 2007-04-07 18:41:29 -0600 (Sat, 07 Apr 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/filegraph.dat
+
+Added header comment line.
+
+------------------------------------------------------------------------
+r2307 | jcbowman | 2007-04-07 18:40:09 -0600 (Sat, 07 Apr 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/CAD.asy
+
+Standardized indentation.
+
+------------------------------------------------------------------------
+r2306 | jcbowman | 2007-04-07 18:38:28 -0600 (Sat, 07 Apr 2007) | 4 lines
+Changed paths:
+ M /trunk/asymptote/fileio.cc
+ M /trunk/asymptote/fileio.h
+
+Allow escaping of comment character in strings.
+
+Disable comment character when reading raw characters with getc(file).
+
+------------------------------------------------------------------------
+r2305 | jcbowman | 2007-04-07 02:10:49 -0600 (Sat, 07 Apr 2007) | 3 lines
+Changed paths:
+ M /trunk/asymptote/picture.cc
+
+Added -E option to dvips to force it to denote the file as EPSF
+(we nevertheless discard the computed dvips bounding box information).
+
+------------------------------------------------------------------------
+r2304 | jcbowman | 2007-04-06 16:25:57 -0600 (Fri, 06 Apr 2007) | 6 lines
+Changed paths:
+ M /trunk/asymptote/asymptote.spec
+ M /trunk/asymptote/base/plain_paths.asy
+ M /trunk/asymptote/base/three.asy
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/runtime.in
+
+Document reltime, relpoint, and midpoint routines.
+
+Add 3D midpoint routine.
+
+Standardize path arguments names.
+
+------------------------------------------------------------------------
+r2303 | jcbowman | 2007-04-06 00:31:29 -0600 (Fri, 06 Apr 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/slide.asy
+
+Clean up _slide*_.aux files.
+
+------------------------------------------------------------------------
+r2302 | jcbowman | 2007-04-06 00:19:31 -0600 (Fri, 06 Apr 2007) | 4 lines
+Changed paths:
+ M /trunk/asymptote/base/slide.asy
+ A /trunk/asymptote/base/syzygy.asy
+ A /trunk/asymptote/doc/eetomumu.asy (from /trunk/asymptote/examples/eetomumu.asy:2301)
+ A /trunk/asymptote/doc/elliptic.asy (from /trunk/asymptote/examples/elliptic.asy:2301)
+ M /trunk/asymptote/doc/intro.asy
+ A /trunk/asymptote/doc/knots.asy
+ A /trunk/asymptote/doc/pixel.ps
+ D /trunk/asymptote/examples/eetomumu.asy
+ D /trunk/asymptote/examples/elliptic.asy
+
+Updated intro.asy to Andy's talk at the University of Alberta.
+
+Addded syzygy module and knots.asy example.
+
+------------------------------------------------------------------------
+r2301 | jcbowman | 2007-04-04 09:16:45 -0600 (Wed, 04 Apr 2007) | 4 lines
+Changed paths:
+ M /trunk/asymptote/base/graph3.asy
+ A /trunk/asymptote/examples/Klein.asy
+
+Choose correct surface normal when calculating lighting.
+
+Added Klein bottle example.
+
+------------------------------------------------------------------------
+r2300 | jcbowman | 2007-04-03 23:14:18 -0600 (Tue, 03 Apr 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/graph3.asy
+ M /trunk/asymptote/base/solids.asy
+ M /trunk/asymptote/base/surface.asy
+
+Removed unused sign.
+
+------------------------------------------------------------------------
+r2299 | jcbowman | 2007-04-03 09:22:21 -0600 (Tue, 03 Apr 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/slide.asy
+
+Remove unused dependency on LaTeX "rotating" package.
+
+------------------------------------------------------------------------
+r2298 | jcbowman | 2007-04-02 11:29:48 -0600 (Mon, 02 Apr 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+
+Clarify nonroot install instructions.
+
+------------------------------------------------------------------------
+r2297 | jcbowman | 2007-04-01 13:48:00 -0600 (Sun, 01 Apr 2007) | 3 lines
+Changed paths:
+ M /trunk/asymptote/base/flowchart.asy
+ M /trunk/asymptote/doc/asymptote.texi
+
+Allow one to control the minimum width and height of flowchart blocks
+separately.
+
+------------------------------------------------------------------------
+r2296 | jcbowman | 2007-04-01 03:16:23 -0600 (Sun, 01 Apr 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/configure.ac
+
+Incremented version to 1.25svn.
+
+------------------------------------------------------------------------
+r2295 | jcbowman | 2007-04-01 02:37:10 -0600 (Sun, 01 Apr 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/FAQ/asy-faq.bfnn
+
+Fix formatting.
+
+------------------------------------------------------------------------
+r2294 | jcbowman | 2007-04-01 02:33:59 -0600 (Sun, 01 Apr 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/Makefile
+
+Simplify makefile.
+
+------------------------------------------------------------------------
+r2293 | jcbowman | 2007-04-01 02:24:24 -0600 (Sun, 01 Apr 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/FAQ/asy-faq.bfnn
+
+Fix backslash.
+
+------------------------------------------------------------------------
+r2292 | jcbowman | 2007-04-01 01:57:57 -0600 (Sun, 01 Apr 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+
+Fixed typo.
+
+------------------------------------------------------------------------
+r2291 | jcbowman | 2007-04-01 01:51:53 -0600 (Sun, 01 Apr 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/settings.cc
+
+Fix __CYGWIN__ preprocessor test.
+
+------------------------------------------------------------------------
+r2290 | jcbowman | 2007-04-01 01:36:06 -0600 (Sun, 01 Apr 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/three.asy
+
+Fix binary space partition camera positioning.
+
+------------------------------------------------------------------------
+r2289 | jcbowman | 2007-03-31 22:19:34 -0600 (Sat, 31 Mar 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/three.asy
+
+Added 3D version of intersectionpoints routine.
+
+------------------------------------------------------------------------
+r2288 | jcbowman | 2007-03-31 20:00:15 -0600 (Sat, 31 Mar 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/flowchart.asy
+ M /trunk/asymptote/doc/asymptote.texi
+
+Add optional fixed block size specifiers.
+
+------------------------------------------------------------------------
+r2287 | jcbowman | 2007-03-31 13:49:01 -0600 (Sat, 31 Mar 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/contour.asy
+ M /trunk/asymptote/base/graph3.asy
+ M /trunk/asymptote/base/math.asy
+ M /trunk/asymptote/base/plain_picture.asy
+ M /trunk/asymptote/base/stats.asy
+
+Remove workarounds for real[1][] bug fixed in r2274.
+
+------------------------------------------------------------------------
+r2286 | jcbowman | 2007-03-31 13:43:59 -0600 (Sat, 31 Mar 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/slide.asy
+
+Reimplement display.
+
+------------------------------------------------------------------------
+r2285 | jcbowman | 2007-03-31 10:40:17 -0600 (Sat, 31 Mar 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/secondaryaxis.asy
+
+Change && to &.
+
+------------------------------------------------------------------------
+r2284 | jcbowman | 2007-03-31 10:39:02 -0600 (Sat, 31 Mar 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/secondaryaxis.asy
+
+Change && to &.
+
+------------------------------------------------------------------------
+r2283 | jcbowman | 2007-03-31 10:35:47 -0600 (Sat, 31 Mar 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/leastsquares.asy
+
+Change && to &.
+
+------------------------------------------------------------------------
+r2282 | jcbowman | 2007-03-31 10:33:03 -0600 (Sat, 31 Mar 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/fontsize.asy
+ M /trunk/asymptote/doc/asymptote.texi
+
+Update fontsize to use fix-cm.sty instead of type1cm.sty.
+
+------------------------------------------------------------------------
+r2281 | jcbowman | 2007-03-29 11:37:29 -0600 (Thu, 29 Mar 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/stack.cc
+
+Clear errors encountered via debugging _eval.
+
+------------------------------------------------------------------------
+r2280 | jcbowman | 2007-03-28 12:57:14 -0600 (Wed, 28 Mar 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/graph.asy
+
+Fix default y tick values.
+
+------------------------------------------------------------------------
+r2279 | jcbowman | 2007-03-28 08:52:23 -0600 (Wed, 28 Mar 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+
+Update MacOS X binary URL.
+
+------------------------------------------------------------------------
+r2278 | jcbowman | 2007-03-28 08:07:49 -0600 (Wed, 28 Mar 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/plain_Label.asy
+
+Make angle(rotate(x)) always return x (mod 360).
+
+------------------------------------------------------------------------
+r2277 | jcbowman | 2007-03-27 12:17:00 -0600 (Tue, 27 Mar 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/TODO
+ M /trunk/asymptote/camp.y
+ M /trunk/asymptote/errormsg.cc
+ M /trunk/asymptote/errormsg.h
+
+Remove spurious line break after syntax errors.
+
+------------------------------------------------------------------------
+r2276 | jcbowman | 2007-03-27 09:41:53 -0600 (Tue, 27 Mar 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/Delaunay.cc
+
+Update URL.
+
+------------------------------------------------------------------------
+r2275 | jcbowman | 2007-03-27 09:34:58 -0600 (Tue, 27 Mar 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/Delaunay.cc
+
+Fix segmentation fault in Dumoulin's C++ port of Burke's Triangulation routine.
+
+------------------------------------------------------------------------
+r2274 | jcbowman | 2007-03-27 08:05:53 -0600 (Tue, 27 Mar 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/newexp.cc
+
+Fixed new real[1][] bug.
+
+------------------------------------------------------------------------
+r2273 | jcbowman | 2007-03-27 07:36:38 -0600 (Tue, 27 Mar 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/runtime.in
+
+Added bitwise NOT function.
+
+------------------------------------------------------------------------
+r2272 | jcbowman | 2007-03-27 06:54:12 -0600 (Tue, 27 Mar 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/runtime.in
+
+Rename intersect arguments to correspond to documentation.
+
+------------------------------------------------------------------------
+r2271 | jcbowman | 2007-03-27 06:53:31 -0600 (Tue, 27 Mar 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/psfile.cc
+
+Fix segmentation fault given real[n][0] data array.
+
+------------------------------------------------------------------------
+r2270 | jcbowman | 2007-03-26 13:28:28 -0600 (Mon, 26 Mar 2007) | 4 lines
+Changed paths:
+ M /trunk/asymptote/base/plain_picture.asy
+
+Added missing tensorshade picture arguments.
+
+Fixed ambiguity with "asy plain_picture.asy" test.
+
+------------------------------------------------------------------------
+r2269 | jcbowman | 2007-03-26 13:21:56 -0600 (Mon, 26 Mar 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/stats.asy
+
+Change array op && to &.
+
+------------------------------------------------------------------------
+r2268 | jcbowman | 2007-03-26 07:41:10 -0600 (Mon, 26 Mar 2007) | 4 lines
+Changed paths:
+ M /trunk/asymptote/settings.cc
+
+Use hard-wired postscript-to-tex scaling for clipping, rather than
+calculating it from defaultmatrix, to support explicit post-scaling of eps
+figures (e.g. with \includegraphics).
+
+------------------------------------------------------------------------
+r2267 | jcbowman | 2007-03-26 05:52:05 -0600 (Mon, 26 Mar 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/TODO
+ M /trunk/asymptote/doc/asymptote.texi
+
+Document multidimensional array initialization.
+
+------------------------------------------------------------------------
+r2266 | hammera | 2007-03-25 22:56:55 -0600 (Sun, 25 Mar 2007) | 1 line
+Changed paths:
+ M /trunk/asymptote/TODO
+
+
+------------------------------------------------------------------------
+r2265 | hammera | 2007-03-25 22:10:05 -0600 (Sun, 25 Mar 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/TODO
+ M /trunk/asymptote/exp.cc
+ M /trunk/asymptote/exp.h
+
+Removed array checking from && and ||.
+
+------------------------------------------------------------------------
+r2264 | jcbowman | 2007-03-25 01:24:51 -0600 (Sun, 25 Mar 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/settings.cc
+
+Revert r2257.
+
+------------------------------------------------------------------------
+r2263 | jcbowman | 2007-03-25 01:05:02 -0600 (Sun, 25 Mar 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+
+Document null instances of structures.
+
+------------------------------------------------------------------------
+r2262 | jcbowman | 2007-03-25 00:53:13 -0600 (Sun, 25 Mar 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/binarytree.asy
+
+Use null initializer for binarytreeNode.
+
+------------------------------------------------------------------------
+r2261 | jcbowman | 2007-03-25 00:23:46 -0600 (Sun, 25 Mar 2007) | 7 lines
+Changed paths:
+ M /trunk/asymptote/builtin.cc
+ M /trunk/asymptote/camp.y
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/runtime.in
+
+Added & and | boolean operators which work like && and || except that they
+always evaluate both arguments.
+
+Renamed array boolean operators && and || to & and |.
+
+Added AND, OR, and XOR bitwise functions of two integers.
+
+------------------------------------------------------------------------
+r2260 | jcbowman | 2007-03-24 12:19:48 -0600 (Sat, 24 Mar 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/Makefile
+
+Fix intro.pdf target.
+
+------------------------------------------------------------------------
+r2259 | jcbowman | 2007-03-24 11:28:46 -0600 (Sat, 24 Mar 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/slide.asy
+
+Simplify and improve implementation of figure().
+
+------------------------------------------------------------------------
+r2258 | jcbowman | 2007-03-24 11:28:08 -0600 (Sat, 24 Mar 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/intro.asy
+
+Use invisible figuremattpen for Asymptote logo.
+
+------------------------------------------------------------------------
+r2257 | jcbowman | 2007-03-24 11:27:25 -0600 (Sat, 24 Mar 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/Makefile
+ M /trunk/asymptote/settings.cc
+
+Enclose PostScript clipping code with gsave and grestore.
+
+------------------------------------------------------------------------
+r2256 | jcbowman | 2007-03-24 11:25:52 -0600 (Sat, 24 Mar 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/graph3.asy
+ M /trunk/asymptote/base/solids.asy
+ M /trunk/asymptote/base/surface.asy
+
+Move camera for infinite projections.
+
+------------------------------------------------------------------------
+r2255 | jcbowman | 2007-03-22 21:41:41 -0600 (Thu, 22 Mar 2007) | 3 lines
+Changed paths:
+ M /trunk/asymptote/camp.l
+ M /trunk/asymptote/camp.y
+ M /trunk/asymptote/doc/asymptote.texi
+
+Allow | as binary operator. Remove || and && from list as they always expand to
+a ? true : b and a ? b : false.
+
+------------------------------------------------------------------------
+r2254 | jcbowman | 2007-03-22 01:34:13 -0600 (Thu, 22 Mar 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/graph3.asy
+ M /trunk/asymptote/base/surface.asy
+ M /trunk/asymptote/base/three.asy
+ M /trunk/asymptote/doc/asymptote.texi
+
+For infinite projections, move camera to outside of bounding box.
+
+------------------------------------------------------------------------
+r2253 | jcbowman | 2007-03-21 06:42:18 -0600 (Wed, 21 Mar 2007) | 5 lines
+Changed paths:
+ M /trunk/asymptote/base/plain_constants.asy
+ M /trunk/asymptote/base/three.asy
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/path.cc
+
+Fix binary space partitioning for projections from infinity (oblique and
+orthographic).
+
+Generalize perspective projection to allow any target point.
+
+------------------------------------------------------------------------
+r2252 | jcbowman | 2007-03-19 01:23:53 -0600 (Mon, 19 Mar 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/three.asy
+
+Use local projection consistently in binary space partition splitting.
+
+------------------------------------------------------------------------
+r2251 | jcbowman | 2007-03-18 06:33:03 -0600 (Sun, 18 Mar 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/three.asy
+ M /trunk/asymptote/knot.h
+
+Check for tension < 0.75.
+
+------------------------------------------------------------------------
+r2250 | jcbowman | 2007-03-14 22:18:10 -0600 (Wed, 14 Mar 2007) | 6 lines
+Changed paths:
+ M /trunk/asymptote/asymptote.spec
+ M /trunk/asymptote/base/animate.asy
+ M /trunk/asymptote/base/binarytree.asy
+ M /trunk/asymptote/base/contour.asy
+ M /trunk/asymptote/base/flowchart.asy
+ M /trunk/asymptote/base/geometry.asy
+ M /trunk/asymptote/base/graph.asy
+ M /trunk/asymptote/base/grid3.asy
+ M /trunk/asymptote/base/light.asy
+ M /trunk/asymptote/base/plain.asy
+ M /trunk/asymptote/base/plain_Label.asy
+ M /trunk/asymptote/base/plain_margins.asy
+ M /trunk/asymptote/base/plain_markers.asy
+ M /trunk/asymptote/base/plain_paths.asy
+ M /trunk/asymptote/base/plain_picture.asy
+ M /trunk/asymptote/base/plain_shipout.asy
+ M /trunk/asymptote/base/simplex.asy
+ M /trunk/asymptote/base/solids.asy
+ M /trunk/asymptote/base/stats.asy
+ M /trunk/asymptote/base/surface.asy
+ M /trunk/asymptote/base/three.asy
+ M /trunk/asymptote/base/tree.asy
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/examples/elliptic.asy
+
+Update documentation of the implicit initializer for structures.
+
+Remove operator init() initializers that are no longer needed.
+
+Initialize Tension in three.asy with sensible defaults.
+
+------------------------------------------------------------------------
+r2249 | jcbowman | 2007-03-14 00:47:33 -0600 (Wed, 14 Mar 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/animate.asy
+ M /trunk/asymptote/doc/asymptote.sty
+ M /trunk/asymptote/runtime.in
+ M /trunk/asymptote/texfile.cc
+
+Support multiple pdf animations in inlinetex mode.
+
+------------------------------------------------------------------------
+r2248 | jcbowman | 2007-03-14 00:46:44 -0600 (Wed, 14 Mar 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/plain.asy
+ M /trunk/asymptote/base/plain_constants.asy
+ M /trunk/asymptote/base/plain_shipout.asy
+ M /trunk/asymptote/base/plain_strings.asy
+
+Minor reorganization.
+
+------------------------------------------------------------------------
+r2247 | jcbowman | 2007-03-14 00:44:28 -0600 (Wed, 14 Mar 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/process.cc
+
+Format.
+
+------------------------------------------------------------------------
+r2246 | hammera | 2007-03-13 21:48:12 -0600 (Tue, 13 Mar 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/dec.cc
+ M /trunk/asymptote/dec.h
+ M /trunk/asymptote/tests/types/init.asy
+
+Add automatic record initializers after the records are defined.
+
+------------------------------------------------------------------------
+r2245 | hammera | 2007-03-13 21:37:27 -0600 (Tue, 13 Mar 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/coder.h
+
+Added note about loop translation.
+
+------------------------------------------------------------------------
+r2244 | jcbowman | 2007-03-13 01:23:43 -0600 (Tue, 13 Mar 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.sty
+
+Input LaTeX preamble only in inline mode.
+
+------------------------------------------------------------------------
+r2243 | jcbowman | 2007-03-13 01:14:55 -0600 (Tue, 13 Mar 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/texfile.cc
+
+Work around pdflatex bug.
+
+------------------------------------------------------------------------
+r2242 | jcbowman | 2007-03-13 00:34:06 -0600 (Tue, 13 Mar 2007) | 5 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.sty
+ M /trunk/asymptote/doc/latexusage.tex
+ M /trunk/asymptote/texfile.cc
+
+In inlinetex mode, communicate the asy texpreamble to TeX via \jobname_.pre.
+
+Remove asypreamble environment; corresponding Asymptote commands should now
+be put in the asydef environment.
+
+------------------------------------------------------------------------
+r2241 | jcbowman | 2007-03-11 17:49:13 -0600 (Sun, 11 Mar 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/FAQ/asy-faq.bfnn
+ M /trunk/asymptote/doc/asymptote.texi
+
+Minor updates.
+
+------------------------------------------------------------------------
+r2240 | jcbowman | 2007-03-11 12:23:17 -0600 (Sun, 11 Mar 2007) | 4 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/settings.cc
+
+Make Ghostscript dependency explict for MSWindows.
+
+Check for GPL Ghostscript as well as AFPL Ghostscript.
+
+------------------------------------------------------------------------
+r2239 | jcbowman | 2007-03-11 11:15:00 -0600 (Sun, 11 Mar 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+
+Minor clarifications.
+
+------------------------------------------------------------------------
+r2238 | jcbowman | 2007-03-11 10:30:10 -0600 (Sun, 11 Mar 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/settings.cc
+ M /trunk/asymptote/util.cc
+ M /trunk/asymptote/util.h
+
+Simplify MSWindows registry lookup.
+
+------------------------------------------------------------------------
+r2237 | jcbowman | 2007-03-10 00:52:49 -0700 (Sat, 10 Mar 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/configure.ac
+
+Incremented version to 1.24svn.
+
+------------------------------------------------------------------------
+r2236 | jcbowman | 2007-03-10 00:13:56 -0700 (Sat, 10 Mar 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/asymptote.spec
+ M /trunk/asymptote/settings.cc
+
+Fix cxx warning.
+
+------------------------------------------------------------------------
+r2235 | jcbowman | 2007-03-09 23:56:52 -0700 (Fri, 09 Mar 2007) | 3 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/settings.cc
+
+Autoconfigure under MSWindows by querying the registry, so that Asymptote
+and the applications it depends on may now be installed in any location.
+
+------------------------------------------------------------------------
+r2234 | jcbowman | 2007-03-09 23:52:43 -0700 (Fri, 09 Mar 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/util.cc
+
+Check if hint is set before accessing it.
+
+------------------------------------------------------------------------
+r2233 | jcbowman | 2007-03-09 23:18:41 -0700 (Fri, 09 Mar 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/genv.cc
+
+Fix import gsl under MSWindows.
+
+------------------------------------------------------------------------
+r2232 | jcbowman | 2007-03-08 22:35:13 -0700 (Thu, 08 Mar 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.sty
+
+Simplify implementation of texpreamble environment.
+
+------------------------------------------------------------------------
+r2231 | jcbowman | 2007-03-08 22:03:33 -0700 (Thu, 08 Mar 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/latexusage.tex
+
+Fix typo.
+
+------------------------------------------------------------------------
+r2230 | jcbowman | 2007-03-08 21:59:11 -0700 (Thu, 08 Mar 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.sty
+
+Add empty postenvironment definitions.
+
+------------------------------------------------------------------------
+r2229 | jcbowman | 2007-03-08 21:35:25 -0700 (Thu, 08 Mar 2007) | 3 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.sty
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/doc/latexusage.tex
+
+Add texpreamble environment to contain the LaTeX preamble for both LaTeX
+and Asymptote.
+
+------------------------------------------------------------------------
+r2228 | jcbowman | 2007-03-08 11:44:25 -0700 (Thu, 08 Mar 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.sty
+
+Remove unused line.
+
+------------------------------------------------------------------------
+r2227 | jcbowman | 2007-03-07 23:43:48 -0700 (Wed, 07 Mar 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/plain.asy
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/settings.cc
+
+Add autoimport option.
+
+------------------------------------------------------------------------
+r2226 | jcbowman | 2007-03-06 11:17:22 -0700 (Tue, 06 Mar 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/picture.cc
+
+Allow shipout to write to other directories if and only if -global is true.
+
+------------------------------------------------------------------------
+r2225 | jcbowman | 2007-03-06 00:25:30 -0700 (Tue, 06 Mar 2007) | 3 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.sty
+
+Ensure colon is catcode other (12) so that TeX includes like
+\usepackage[frenchb]{babel} don't break inlinetex mode.
+
+------------------------------------------------------------------------
+r2224 | jcbowman | 2007-03-05 15:05:53 -0700 (Mon, 05 Mar 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/slide.asy
+ M /trunk/asymptote/examples/poster.asy
+
+Fix background picture sizing.
+
+------------------------------------------------------------------------
+r2223 | jcbowman | 2007-03-05 14:58:47 -0700 (Mon, 05 Mar 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/examples/poster.asy
+
+Set background size.
+
+------------------------------------------------------------------------
+r2222 | jcbowman | 2007-03-05 02:51:51 -0700 (Mon, 05 Mar 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/configure.ac
+
+Incremented version to 1.23svn.
+
+------------------------------------------------------------------------
+r2221 | jcbowman | 2007-03-05 02:01:16 -0700 (Mon, 05 Mar 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/runtime.in
+
+Added missing header.
+
+------------------------------------------------------------------------
+r2220 | jcbowman | 2007-03-05 01:33:43 -0700 (Mon, 05 Mar 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/graph3.asy
+
+Support legends in both forms of 3D contour drawing routines.
+
+------------------------------------------------------------------------
+r2219 | jcbowman | 2007-03-05 01:31:49 -0700 (Mon, 05 Mar 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/graph3.asy
+
+Support legends in 3D contour drawing routines.
+
+------------------------------------------------------------------------
+r2218 | jcbowman | 2007-03-05 00:58:37 -0700 (Mon, 05 Mar 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/FAQ/asy-faq.bfnn
+
+Add discussion of icomma package.
+
+------------------------------------------------------------------------
+r2217 | jcbowman | 2007-03-05 00:44:32 -0700 (Mon, 05 Mar 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/FAQ/asy-faq.bfnn
+ M /trunk/asymptote/runtime.in
+
+Fix format(-0.5) under locales with nonperiod decimal separator.
+
+------------------------------------------------------------------------
+r2216 | jcbowman | 2007-03-05 00:17:12 -0700 (Mon, 05 Mar 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/doc/diatom.asy
+
+Mention link page, including user-written Asymptote tutorial.
+
+------------------------------------------------------------------------
+r2215 | jcbowman | 2007-03-04 12:17:33 -0700 (Sun, 04 Mar 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/markers.asy
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/doc/markers1.asy
+
+Add predefined markers.
+
+------------------------------------------------------------------------
+r2214 | jcbowman | 2007-03-04 11:18:45 -0700 (Sun, 04 Mar 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+
+Minor edits.
+
+------------------------------------------------------------------------
+r2213 | jcbowman | 2007-03-04 11:10:23 -0700 (Sun, 04 Mar 2007) | 5 lines
+Changed paths:
+ M /trunk/asymptote/base/markers.asy
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/doc/markers1.asy
+ M /trunk/asymptote/doc/markers2.asy
+
+Renamed markuniform(int n, frame center, bool rotated=false) to
+markinterval(int n=1, frame f, bool rotated=false), which now centers n copies
+of frame f within uniformly space intervals in arclength along the path,
+optionally rotated by the angle of the local tangent.
+
+------------------------------------------------------------------------
+r2212 | jcbowman | 2007-03-04 10:16:14 -0700 (Sun, 04 Mar 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/Makefile
+
+Explicitly list intro.asy dependencies.
+
+------------------------------------------------------------------------
+r2211 | jcbowman | 2007-03-04 00:59:30 -0700 (Sun, 04 Mar 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/markers.asy
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/doc/errorbars.asy
+ A /trunk/asymptote/doc/markers1.asy (from /trunk/asymptote/examples/markers1.asy:2210)
+ A /trunk/asymptote/doc/markers2.asy (from /trunk/asymptote/examples/markers2.asy:2210)
+ D /trunk/asymptote/examples/markers1.asy
+ D /trunk/asymptote/examples/markers2.asy
+
+Updated marker documentation.
+
+------------------------------------------------------------------------
+r2210 | jcbowman | 2007-03-04 00:53:21 -0700 (Sun, 04 Mar 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/markers.asy
+ M /trunk/asymptote/base/plain_markers.asy
+ M /trunk/asymptote/examples/markers1.asy
+ M /trunk/asymptote/examples/markers2.asy
+
+Simplified/standardized markers interface.
+
+------------------------------------------------------------------------
+r2209 | jcbowman | 2007-03-04 00:47:51 -0700 (Sun, 04 Mar 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/three.asy
+
+Formatting.
+
+------------------------------------------------------------------------
+r2208 | jcbowman | 2007-03-04 00:47:38 -0700 (Sun, 04 Mar 2007) | 6 lines
+Changed paths:
+ M /trunk/asymptote/base/slide.asy
+ M /trunk/asymptote/doc/intro.asy
+
+Remove bibliography page numbers.
+
+Add Asymptote logo to intro.asy.
+
+Change clearpage to eject to avoid extra page.
+
+------------------------------------------------------------------------
+r2207 | jcbowman | 2007-03-04 00:45:34 -0700 (Sun, 04 Mar 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/palette.asy
+
+Draw minor ticks below palette box.
+
+------------------------------------------------------------------------
+r2206 | jcbowman | 2007-03-03 21:08:48 -0700 (Sat, 03 Mar 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/intro.asy
+
+Add short description of slide presentation package.
+
+------------------------------------------------------------------------
+r2205 | jcbowman | 2007-03-03 19:33:03 -0700 (Sat, 03 Mar 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/intro.asy
+
+Remove directory qualifier.
+
+------------------------------------------------------------------------
+r2204 | jcbowman | 2007-03-03 19:32:42 -0700 (Sat, 03 Mar 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/examples/animations/pdfmovie.asy
+
+Import pdfanim.
+
+------------------------------------------------------------------------
+r2203 | jcbowman | 2007-03-03 19:31:52 -0700 (Sat, 03 Mar 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/contour.asy
+
+Check incoming array bounds.
+
+------------------------------------------------------------------------
+r2202 | jcbowman | 2007-03-03 17:48:39 -0700 (Sat, 03 Mar 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/slide.asy
+
+Show page numbers on subsequent bibliography pages.
+
+------------------------------------------------------------------------
+r2201 | jcbowman | 2007-03-03 14:46:09 -0700 (Sat, 03 Mar 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/slide.asy
+
+Number last page before bibliography.
+
+------------------------------------------------------------------------
+r2200 | jcbowman | 2007-03-03 14:45:49 -0700 (Sat, 03 Mar 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/texfile.h
+
+Revert temporary patch.
+
+------------------------------------------------------------------------
+r2199 | jcbowman | 2007-03-03 13:37:29 -0700 (Sat, 03 Mar 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/plain_constants.asy
+ M /trunk/asymptote/doc/asymptote.texi
+
+Add implicit pen initializer defaultpen.
+
+------------------------------------------------------------------------
+r2198 | jcbowman | 2007-03-03 13:02:54 -0700 (Sat, 03 Mar 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/three.asy
+ M /trunk/asymptote/path.cc
+ M /trunk/asymptote/path3.cc
+
+Fix concatentation of nullpaths.
+
+------------------------------------------------------------------------
+r2197 | jcbowman | 2007-03-03 12:32:32 -0700 (Sat, 03 Mar 2007) | 7 lines
+Changed paths:
+ M /trunk/asymptote/camp.l
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/runtime.in
+
+Make seconds return -1 instead of 0 on failure, for consistency with UNIX
+mktime routine.
+
+Document workarounds for unimplemented "%Z" time zone specifier to seconds.
+
+Improve diagnostic.
+
+------------------------------------------------------------------------
+r2196 | pivaldi | 2007-03-02 15:06:35 -0700 (Fri, 02 Mar 2007) | 1 line
+Changed paths:
+ M /trunk/asymptote/base/markers.asy
+ M /trunk/asymptote/doc/asymptote.texi
+
+Minor changes/updates.
+------------------------------------------------------------------------
+r2195 | pivaldi | 2007-03-02 12:43:16 -0700 (Fri, 02 Mar 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/markers.asy
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/examples/markers2.asy
+
+Replacing the parameter 'frame markerframe=newframe' by 'marker marker=nomarker'
+in the routine 'markangle' of 'markers.asy'.
+------------------------------------------------------------------------
+r2194 | jcbowman | 2007-03-02 00:16:21 -0700 (Fri, 02 Mar 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/texfile.h
+
+Don't output texpreamble in inline mode.
+
+------------------------------------------------------------------------
+r2193 | pivaldi | 2007-03-01 15:28:33 -0700 (Thu, 01 Mar 2007) | 1 line
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+
+Correct typo.
+------------------------------------------------------------------------
+r2192 | pivaldi | 2007-03-01 15:15:58 -0700 (Thu, 01 Mar 2007) | 1 line
+Changed paths:
+ M /trunk/asymptote/base/markers.asy
+ M /trunk/asymptote/doc/asymptote.texi
+
+Documentation of the package markers.asy.
+------------------------------------------------------------------------
+r2191 | jcbowman | 2007-03-01 09:01:41 -0700 (Thu, 01 Mar 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/contour.asy
+ M /trunk/asymptote/base/graph3.asy
+ M /trunk/asymptote/examples/sinc.asy
+
+Added routines to facilitate drawing 3d contours.
+
+------------------------------------------------------------------------
+r2190 | pivaldi | 2007-03-01 08:37:30 -0700 (Thu, 01 Mar 2007) | 1 line
+Changed paths:
+ A /trunk/asymptote/examples/markers1.asy
+ A /trunk/asymptote/examples/markers2.asy
+
+Examples about the modules markers.asy
+------------------------------------------------------------------------
+r2189 | pivaldi | 2007-03-01 08:12:30 -0700 (Thu, 01 Mar 2007) | 1 line
+Changed paths:
+ A /trunk/asymptote/base/markers.asy
+
+Others mark routines and markers.
+------------------------------------------------------------------------
+r2188 | jcbowman | 2007-02-28 22:55:57 -0700 (Wed, 28 Feb 2007) | 3 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/fileio.h
+ M /trunk/asymptote/runtime.in
+
+Implemented binput and boutput functions for reading and writing in the native
+(nonportable) machine binary format.
+
+------------------------------------------------------------------------
+r2187 | jcbowman | 2007-02-28 17:54:28 -0700 (Wed, 28 Feb 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/INSTALL
+
+Document local installation.
+
+------------------------------------------------------------------------
+r2186 | jcbowman | 2007-02-28 17:29:42 -0700 (Wed, 28 Feb 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/transform.h
+
+Fix uninitialized 'this.130' warning message from gcc 4.1.1 and 4.1.2.
+
+------------------------------------------------------------------------
+r2185 | jcbowman | 2007-02-28 13:56:44 -0700 (Wed, 28 Feb 2007) | 4 lines
+Changed paths:
+ M /trunk/asymptote/base/animate.asy
+ M /trunk/asymptote/base/labelpath.asy
+ M /trunk/asymptote/base/plain_strings.asy
+ M /trunk/asymptote/base/slide.asy
+ M /trunk/asymptote/doc/intro.asy
+ M /trunk/asymptote/examples/animations/pdfmovie.asy
+ M /trunk/asymptote/picture.cc
+ M /trunk/asymptote/settings.cc
+ M /trunk/asymptote/settings.h
+
+Fix bool latex() and pdf().
+
+Remove lscape dependency and need for autorotation in slide.asy.
+
+------------------------------------------------------------------------
+r2184 | jcbowman | 2007-02-28 12:40:49 -0700 (Wed, 28 Feb 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/contour.asy
+
+Reactive begingroup.
+
+------------------------------------------------------------------------
+r2183 | jcbowman | 2007-02-28 00:35:32 -0700 (Wed, 28 Feb 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/process.cc
+ M /trunk/asymptote/runtime.in
+
+Fix cxx errors.
+
+------------------------------------------------------------------------
+r2182 | jcbowman | 2007-02-28 00:28:39 -0700 (Wed, 28 Feb 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/configure.ac
+
+Remove unused configuration variable AC_HEADER_STDBOOL.
+
+------------------------------------------------------------------------
+r2181 | jcbowman | 2007-02-28 00:17:09 -0700 (Wed, 28 Feb 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/runtime.in
+
+Fix cxx errors.
+
+------------------------------------------------------------------------
+r2180 | jcbowman | 2007-02-27 23:58:30 -0700 (Tue, 27 Feb 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/application.cc
+ M /trunk/asymptote/application.h
+ M /trunk/asymptote/common.h
+ M /trunk/asymptote/dec.cc
+ M /trunk/asymptote/dec.h
+ M /trunk/asymptote/drawelement.h
+ M /trunk/asymptote/entry.cc
+ M /trunk/asymptote/entry.h
+ M /trunk/asymptote/fundec.cc
+ M /trunk/asymptote/fundec.h
+ M /trunk/asymptote/genv.h
+ M /trunk/asymptote/locate.h
+ M /trunk/asymptote/picture.cc
+ M /trunk/asymptote/picture.h
+ M /trunk/asymptote/process.cc
+ M /trunk/asymptote/runtime.in
+ M /trunk/asymptote/settings.cc
+ M /trunk/asymptote/stack.cc
+ M /trunk/asymptote/stack.h
+ M /trunk/asymptote/stm.cc
+ M /trunk/asymptote/stm.h
+ M /trunk/asymptote/table.h
+ M /trunk/asymptote/texfile.cc
+ M /trunk/asymptote/texfile.h
+ M /trunk/asymptote/varinit.cc
+ M /trunk/asymptote/varinit.h
+
+Move mem::list out of common.h due to ambiguities under old cxx compiler.
+
+------------------------------------------------------------------------
+r2179 | jcbowman | 2007-02-27 23:09:49 -0700 (Tue, 27 Feb 2007) | 3 lines
+Changed paths:
+ M /trunk/asymptote/configure.ac
+
+Impose -finline-limit=400 on old (< 4.0.0) compilers to greatly speed up
+compilation.
+
+------------------------------------------------------------------------
+r2178 | jcbowman | 2007-02-27 20:00:26 -0700 (Tue, 27 Feb 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/absyn.cc
+ M /trunk/asymptote/absyn.h
+ M /trunk/asymptote/application.cc
+ M /trunk/asymptote/application.h
+ M /trunk/asymptote/array.h
+ M /trunk/asymptote/arrayop.h
+ M /trunk/asymptote/builtin.cc
+ M /trunk/asymptote/callable.h
+ M /trunk/asymptote/camperror.cc
+ M /trunk/asymptote/camperror.h
+ M /trunk/asymptote/cast.cc
+ M /trunk/asymptote/castop.h
+ M /trunk/asymptote/coder.cc
+ A /trunk/asymptote/common.h
+ M /trunk/asymptote/dec.cc
+ M /trunk/asymptote/dec.h
+ M /trunk/asymptote/drawelement.h
+ M /trunk/asymptote/drawlabel.cc
+ M /trunk/asymptote/drawlabel.h
+ M /trunk/asymptote/drawpath.cc
+ M /trunk/asymptote/drawverbatim.h
+ M /trunk/asymptote/entry.cc
+ M /trunk/asymptote/entry.h
+ M /trunk/asymptote/env.cc
+ M /trunk/asymptote/env.h
+ M /trunk/asymptote/envcompleter.cc
+ M /trunk/asymptote/envcompleter.h
+ M /trunk/asymptote/errormsg.cc
+ M /trunk/asymptote/errormsg.h
+ M /trunk/asymptote/exp.cc
+ M /trunk/asymptote/exp.h
+ M /trunk/asymptote/fftw++.cc
+ M /trunk/asymptote/fftw++.h
+ M /trunk/asymptote/fileio.cc
+ M /trunk/asymptote/fileio.h
+ M /trunk/asymptote/fundec.h
+ M /trunk/asymptote/genv.cc
+ M /trunk/asymptote/genv.h
+ M /trunk/asymptote/guide.h
+ M /trunk/asymptote/interact.cc
+ M /trunk/asymptote/interact.h
+ M /trunk/asymptote/item.h
+ M /trunk/asymptote/knot.cc
+ M /trunk/asymptote/lexical.h
+ M /trunk/asymptote/locate.cc
+ M /trunk/asymptote/locate.h
+ M /trunk/asymptote/main.cc
+ M /trunk/asymptote/mathop.h
+ M /trunk/asymptote/memory.h
+ M /trunk/asymptote/newexp.cc
+ M /trunk/asymptote/pair.h
+ M /trunk/asymptote/parser.cc
+ M /trunk/asymptote/parser.h
+ M /trunk/asymptote/path.h
+ M /trunk/asymptote/pen.h
+ M /trunk/asymptote/picture.cc
+ M /trunk/asymptote/picture.h
+ M /trunk/asymptote/pipestream.h
+ M /trunk/asymptote/process.cc
+ M /trunk/asymptote/process.h
+ M /trunk/asymptote/program.h
+ M /trunk/asymptote/psfile.cc
+ M /trunk/asymptote/psfile.h
+ M /trunk/asymptote/record.cc
+ M /trunk/asymptote/record.h
+ M /trunk/asymptote/runtime.in
+ M /trunk/asymptote/settings.cc
+ M /trunk/asymptote/settings.h
+ M /trunk/asymptote/stack.cc
+ M /trunk/asymptote/stack.h
+ M /trunk/asymptote/stm.h
+ M /trunk/asymptote/symbol.cc
+ M /trunk/asymptote/symbol.h
+ M /trunk/asymptote/table.h
+ M /trunk/asymptote/texfile.cc
+ M /trunk/asymptote/texfile.h
+ M /trunk/asymptote/triple.h
+ M /trunk/asymptote/types.cc
+ M /trunk/asymptote/types.h
+ M /trunk/asymptote/util.cc
+ M /trunk/asymptote/util.h
+ M /trunk/asymptote/varinit.cc
+ M /trunk/asymptote/varinit.h
+ M /trunk/asymptote/vm.h
+
+Put global name space qualifications in new common.h file.
+
+------------------------------------------------------------------------
+r2177 | jcbowman | 2007-02-27 10:08:33 -0700 (Tue, 27 Feb 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/texfile.h
+
+Make tex pipe aware of a previously generated aux file.
+
+------------------------------------------------------------------------
+r2176 | jcbowman | 2007-02-27 08:58:53 -0700 (Tue, 27 Feb 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/Makefile
+
+Fix makefile dependencies.
+
+------------------------------------------------------------------------
+r2175 | hammera | 2007-02-27 07:42:56 -0700 (Tue, 27 Feb 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/coder.h
+
+Fixed inTranslation to handle frames for loops.
+
+------------------------------------------------------------------------
+r2174 | jcbowman | 2007-02-27 00:10:31 -0700 (Tue, 27 Feb 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/slide.asy
+ M /trunk/asymptote/doc/Makefile
+ M /trunk/asymptote/doc/intro.asy
+
+Temporarily fix svn builds.
+
+------------------------------------------------------------------------
+r2173 | jcbowman | 2007-02-26 23:50:54 -0700 (Mon, 26 Feb 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/texfile.h
+
+Temporarily disable aux file input.
+
+------------------------------------------------------------------------
+r2172 | jcbowman | 2007-02-26 23:40:30 -0700 (Mon, 26 Feb 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/application.cc
+ M /trunk/asymptote/application.h
+ M /trunk/asymptote/cast.cc
+ M /trunk/asymptote/coder.h
+ M /trunk/asymptote/drawelement.h
+ M /trunk/asymptote/env.h
+ M /trunk/asymptote/errormsg.h
+ M /trunk/asymptote/locate.h
+ M /trunk/asymptote/main.cc
+ M /trunk/asymptote/picture.cc
+ M /trunk/asymptote/picture.h
+ M /trunk/asymptote/process.cc
+ M /trunk/asymptote/psfile.h
+ M /trunk/asymptote/settings.h
+ M /trunk/asymptote/symbol.h
+ M /trunk/asymptote/table.h
+ M /trunk/asymptote/texfile.cc
+ M /trunk/asymptote/texfile.h
+ M /trunk/asymptote/varinit.cc
+ M /trunk/asymptote/varinit.h
+
+Fix further memory leaks.
+
+------------------------------------------------------------------------
+r2171 | jcbowman | 2007-02-26 22:10:23 -0700 (Mon, 26 Feb 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/Makefile
+ M /trunk/asymptote/util.cc
+ M /trunk/asymptote/util.h
+
+Fixed segmentation fault.
+
+------------------------------------------------------------------------
+r2170 | jcbowman | 2007-02-26 21:53:35 -0700 (Mon, 26 Feb 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/Makefile
+ M /trunk/asymptote/doc/asymptote.texi
+
+Possible workaround for Makefile problem on Debian.
+
+------------------------------------------------------------------------
+r2169 | jcbowman | 2007-02-26 21:37:06 -0700 (Mon, 26 Feb 2007) | 3 lines
+Changed paths:
+ M /trunk/asymptote/Delaunay.cc
+ M /trunk/asymptote/absyn.cc
+ M /trunk/asymptote/absyn.h
+ M /trunk/asymptote/camp.l
+ M /trunk/asymptote/camp.y
+ M /trunk/asymptote/camperror.cc
+ M /trunk/asymptote/camperror.h
+ M /trunk/asymptote/castop.h
+ M /trunk/asymptote/dec.cc
+ M /trunk/asymptote/drawelement.h
+ M /trunk/asymptote/drawlabel.cc
+ M /trunk/asymptote/drawlabel.h
+ M /trunk/asymptote/drawpath.cc
+ M /trunk/asymptote/drawverbatim.h
+ M /trunk/asymptote/entry.cc
+ M /trunk/asymptote/env.cc
+ M /trunk/asymptote/envcompleter.cc
+ M /trunk/asymptote/errormsg.cc
+ M /trunk/asymptote/errormsg.h
+ M /trunk/asymptote/exp.cc
+ M /trunk/asymptote/exp.h
+ M /trunk/asymptote/fileio.cc
+ M /trunk/asymptote/fileio.h
+ M /trunk/asymptote/genv.cc
+ M /trunk/asymptote/inst.h
+ M /trunk/asymptote/interact.cc
+ M /trunk/asymptote/knot.cc
+ M /trunk/asymptote/lexical.h
+ M /trunk/asymptote/locate.cc
+ M /trunk/asymptote/locate.h
+ M /trunk/asymptote/main.cc
+ M /trunk/asymptote/mathop.h
+ M /trunk/asymptote/memory.h
+ M /trunk/asymptote/parser.cc
+ M /trunk/asymptote/parser.h
+ M /trunk/asymptote/picture.cc
+ M /trunk/asymptote/picture.h
+ M /trunk/asymptote/pipestream.h
+ M /trunk/asymptote/process.cc
+ M /trunk/asymptote/psfile.cc
+ M /trunk/asymptote/psfile.h
+ M /trunk/asymptote/record.cc
+ M /trunk/asymptote/record.h
+ M /trunk/asymptote/runtime.in
+ M /trunk/asymptote/settings.cc
+ M /trunk/asymptote/settings.h
+ M /trunk/asymptote/stack.cc
+ M /trunk/asymptote/symbol.cc
+ M /trunk/asymptote/symbol.h
+ M /trunk/asymptote/table.h
+ M /trunk/asymptote/texfile.cc
+ M /trunk/asymptote/texfile.h
+ M /trunk/asymptote/types.cc
+ M /trunk/asymptote/util.cc
+ M /trunk/asymptote/util.h
+ M /trunk/asymptote/vm.h
+
+Fix memory leaks by using mem::string, mem::istringstream,
+mem::ostringstream, and mem::stringbuf everywhere.
+
+------------------------------------------------------------------------
+r2168 | hammera | 2007-02-26 19:03:46 -0700 (Mon, 26 Feb 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/FAQ/asy-faq.bfnn
+
+Explained lifetime of loop variables.
+
+------------------------------------------------------------------------
+r2167 | jcbowman | 2007-02-26 17:22:21 -0700 (Mon, 26 Feb 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/FAQ/asy-faq.bfnn
+
+Update discussion of local variable allocation in loops.
+
+------------------------------------------------------------------------
+r2166 | hammera | 2007-02-26 09:07:53 -0700 (Mon, 26 Feb 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+
+Added documentation on static qualifiers in loops.
+
+------------------------------------------------------------------------
+r2165 | hammera | 2007-02-26 08:41:28 -0700 (Mon, 26 Feb 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/TODO
+
+Removed completed TODO item.
+
+------------------------------------------------------------------------
+r2164 | hammera | 2007-02-26 08:40:41 -0700 (Mon, 26 Feb 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/coder.cc
+ M /trunk/asymptote/coder.h
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/doc/diatom.asy
+ M /trunk/asymptote/inst.h
+ M /trunk/asymptote/program.cc
+ M /trunk/asymptote/program.h
+ M /trunk/asymptote/stack.cc
+ M /trunk/asymptote/stm.cc
+ A /trunk/asymptote/tests/frames/loop.asy
+
+Allocate variables in a loop iteration in their own frame.
+
+------------------------------------------------------------------------
+r2163 | jcbowman | 2007-02-26 00:36:35 -0700 (Mon, 26 Feb 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/embed.asy
+
+Force outputformat to "pdf".
+
+------------------------------------------------------------------------
+r2162 | jcbowman | 2007-02-26 00:35:40 -0700 (Mon, 26 Feb 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/pdfanim.asy
+
+Set outformat to pdf.
+
+------------------------------------------------------------------------
+r2161 | jcbowman | 2007-02-26 00:34:34 -0700 (Mon, 26 Feb 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/picture.cc
+
+Remove unwanted texput.pdf file.
+
+------------------------------------------------------------------------
+r2160 | jcbowman | 2007-02-25 11:22:00 -0700 (Sun, 25 Feb 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/slide.asy
+ M /trunk/asymptote/doc/asycolors.sty
+ M /trunk/asymptote/texfile.h
+
+Load color package even for TeX pipe.
+
+------------------------------------------------------------------------
+r2159 | jcbowman | 2007-02-25 11:12:13 -0700 (Sun, 25 Feb 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/geometry.asy
+
+Formatted.
+
+------------------------------------------------------------------------
+r2158 | jcbowman | 2007-02-25 11:01:12 -0700 (Sun, 25 Feb 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/slide.asy
+ M /trunk/asymptote/locate.cc
+ M /trunk/asymptote/runtime.in
+ M /trunk/asymptote/texfile.h
+
+Avoid duplicate .aux file inclusion (and duplicate labels).
+
+------------------------------------------------------------------------
+r2157 | jcbowman | 2007-02-25 09:54:30 -0700 (Sun, 25 Feb 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/pipestream.h
+
+Removed extra blank lines in tex pipe diagnostics.
+
+------------------------------------------------------------------------
+r2156 | pivaldi | 2007-02-25 08:08:43 -0700 (Sun, 25 Feb 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/geometry.asy
+ M /trunk/asymptote/base/plain_margins.asy
+
+Improve the function 'perpendicular' of geometry.asy.
+Add operator +(margin,margin) in plain_magin.asy.
+------------------------------------------------------------------------
+r2155 | jcbowman | 2007-02-25 08:02:11 -0700 (Sun, 25 Feb 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/slide.asy
+
+Simplified bullet command.
+
+------------------------------------------------------------------------
+r2154 | jcbowman | 2007-02-24 19:47:11 -0700 (Sat, 24 Feb 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/Makefile
+
+Load correct base files.
+
+------------------------------------------------------------------------
+r2153 | jcbowman | 2007-02-24 17:23:36 -0700 (Sat, 24 Feb 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/solids.asy
+
+Simplify skeleton routine interface.
+
+------------------------------------------------------------------------
+r2152 | jcbowman | 2007-02-24 17:15:39 -0700 (Sat, 24 Feb 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/solids.asy
+
+Split skeleton routines to provide finer control.
+
+------------------------------------------------------------------------
+r2151 | jcbowman | 2007-02-24 09:52:09 -0700 (Sat, 24 Feb 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/settings.cc
+
+Turn off setlocale warnings when not debugging.
+
+------------------------------------------------------------------------
+r2150 | jcbowman | 2007-02-24 09:51:43 -0700 (Sat, 24 Feb 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/drawlabel.cc
+
+Use namespace setitings.
+
+------------------------------------------------------------------------
+r2149 | pivaldi | 2007-02-24 03:52:50 -0700 (Sat, 24 Feb 2007) | 1 line
+Changed paths:
+ M /trunk/asymptote/base/asy-mode.el
+
+Correction of ps/pdf-view-command documentation.
+------------------------------------------------------------------------
+r2148 | jcbowman | 2007-02-22 13:21:01 -0700 (Thu, 22 Feb 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/Makefile
+ M /trunk/asymptote/doc/asy.1.begin
+
+Fix hyphens and formatting in man page.
+
+------------------------------------------------------------------------
+r2147 | jcbowman | 2007-02-22 13:06:48 -0700 (Thu, 22 Feb 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/slide.asy
+
+Change autorotation to true.
+
+------------------------------------------------------------------------
+r2146 | jcbowman | 2007-02-22 12:49:10 -0700 (Thu, 22 Feb 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+
+Updated Debian binary site.
+
+------------------------------------------------------------------------
+r2145 | jcbowman | 2007-02-22 00:36:59 -0700 (Thu, 22 Feb 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/intro.asy
+
+Generate more missing files.
+
+------------------------------------------------------------------------
+r2144 | jcbowman | 2007-02-22 00:34:49 -0700 (Thu, 22 Feb 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/asymptote.spec
+ M /trunk/asymptote/doc/intro.asy
+
+Autogenerate missing files.
+
+------------------------------------------------------------------------
+r2143 | jcbowman | 2007-02-22 00:17:06 -0700 (Thu, 22 Feb 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/xstream.h
+
+Make eof set fail bit.
+
+------------------------------------------------------------------------
+r2142 | jcbowman | 2007-02-22 00:14:51 -0700 (Thu, 22 Feb 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/xstream.h
+
+Make eof set fail().
+
+------------------------------------------------------------------------
+r2141 | jcbowman | 2007-02-21 23:45:12 -0700 (Wed, 21 Feb 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+
+Removed duplicate sentence.
+
+------------------------------------------------------------------------
+r2140 | jcbowman | 2007-02-21 23:43:07 -0700 (Wed, 21 Feb 2007) | 6 lines
+Changed paths:
+ M /trunk/asymptote/base/slide.asy
+ M /trunk/asymptote/doc/Makefile
+ M /trunk/asymptote/doc/asymptote.texi
+ A /trunk/asymptote/doc/filegraph.asy
+ A /trunk/asymptote/doc/filegraph.dat
+ A /trunk/asymptote/doc/intro.asy
+ A /trunk/asymptote/doc/intro_.bbl
+ M /trunk/asymptote/examples/slidedemo.asy
+ M /trunk/asymptote/picture.cc
+ M /trunk/asymptote/runtime.in
+ M /trunk/asymptote/settings.cc
+
+Added introductory Asymptote slide presentation (intro.pdf).
+
+Added keepaux option to keep intermediate LaTeX aux files.
+
+Added example filegraph.asy of graphing columns of data from a file.
+
+------------------------------------------------------------------------
+r2139 | jcbowman | 2007-02-21 21:40:34 -0700 (Wed, 21 Feb 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/graph.asy
+
+Fix logarithmic tick labels near the machine epsilon.
+
+------------------------------------------------------------------------
+r2138 | pivaldi | 2007-02-21 10:29:15 -0700 (Wed, 21 Feb 2007) | 1 line
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+
+typo correction.
+------------------------------------------------------------------------
+r2137 | jcbowman | 2007-02-21 09:56:54 -0700 (Wed, 21 Feb 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+
+Remove alien to deb conversion documentation.
+
+------------------------------------------------------------------------
+r2136 | jcbowman | 2007-02-21 09:47:55 -0700 (Wed, 21 Feb 2007) | 5 lines
+Changed paths:
+ M /trunk/asymptote/base/plain_strings.asy
+ M /trunk/asymptote/base/slide.asy
+ M /trunk/asymptote/doc/bezier2.asy
+ A /trunk/asymptote/doc/beziercurve.asy
+ M /trunk/asymptote/doc/datagraph.asy
+
+Support slide bibliography under pdflatex.
+
+Add string file(string) which reads file as a string, and verbatim
+typesetting command.
+
+------------------------------------------------------------------------
+r2135 | jcbowman | 2007-02-20 21:52:11 -0700 (Tue, 20 Feb 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/slide.asy
+
+Added missing space.
+
+------------------------------------------------------------------------
+r2134 | jcbowman | 2007-02-19 23:01:03 -0700 (Mon, 19 Feb 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/picture.cc
+
+Fix typo.
+
+------------------------------------------------------------------------
+r2133 | jcbowman | 2007-02-19 22:52:40 -0700 (Mon, 19 Feb 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/slide.asy
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/examples/slidedemo.asy
+
+Added backgroundcolor and foregroundcolor.
+
+------------------------------------------------------------------------
+r2132 | jcbowman | 2007-02-19 22:51:23 -0700 (Mon, 19 Feb 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/runtime.in
+
+Implement colorspace command for extracting colorspace of pens.
+
+------------------------------------------------------------------------
+r2131 | jcbowman | 2007-02-19 22:50:50 -0700 (Mon, 19 Feb 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/plain_strings.asy
+
+Implement verbatim command.
+
+------------------------------------------------------------------------
+r2130 | jcbowman | 2007-02-19 09:58:21 -0700 (Mon, 19 Feb 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/configure.ac
+
+Incremented version to 1.22svn.
+
+------------------------------------------------------------------------
+r2129 | jcbowman | 2007-02-19 09:08:21 -0700 (Mon, 19 Feb 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/settings.cc
+
+Fixed cxx warning.
+
+------------------------------------------------------------------------
+r2128 | jcbowman | 2007-02-19 08:56:20 -0700 (Mon, 19 Feb 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+
+Fixed typo.
+
+------------------------------------------------------------------------
+r2127 | jcbowman | 2007-02-19 08:18:14 -0700 (Mon, 19 Feb 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/pen.h
+ M /trunk/asymptote/psfile.cc
+
+Allow DEFCOLOR when promoting colorspaces.
+
+------------------------------------------------------------------------
+r2126 | jcbowman | 2007-02-19 00:54:23 -0700 (Mon, 19 Feb 2007) | 8 lines
+Changed paths:
+ M /trunk/asymptote/base/palette.asy
+ M /trunk/asymptote/examples/latticeshading.asy
+ M /trunk/asymptote/examples/sacone.asy
+ M /trunk/asymptote/pen.h
+ M /trunk/asymptote/psfile.cc
+ M /trunk/asymptote/psfile.h
+ M /trunk/asymptote/settings.cc
+ M /trunk/asymptote/settings.h
+
+Automatically promote colors to highest colorspace in shading and image
+routines.
+
+Fix grayscale and cmyk latticeshading.
+
+Significantly increase speed of image processing by caching bw, gray, rgb,
+and cmyk settings in a global variable.
+
+------------------------------------------------------------------------
+r2125 | jcbowman | 2007-02-19 00:51:41 -0700 (Mon, 19 Feb 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+
+Update documentation of Linear scaling type.
+
+------------------------------------------------------------------------
+r2124 | jcbowman | 2007-02-19 00:50:14 -0700 (Mon, 19 Feb 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/xasy
+
+Check array bounds.
+
+------------------------------------------------------------------------
+r2123 | jcbowman | 2007-02-19 00:49:34 -0700 (Mon, 19 Feb 2007) | 8 lines
+Changed paths:
+ M /trunk/asymptote/base/contour.asy
+ M /trunk/asymptote/examples/fillcontour.asy
+
+Collect double-vertex contours.
+
+Increase epsilon.
+
+Fix contour fill routine.
+
+Separate contour fill routine from palette computation.
+
+------------------------------------------------------------------------
+r2122 | jcbowman | 2007-02-19 00:42:43 -0700 (Mon, 19 Feb 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/asy-mode.el
+
+Added Philippe's improved show-function-at-point fix.
+
+------------------------------------------------------------------------
+r2121 | jcbowman | 2007-02-18 12:58:55 -0700 (Sun, 18 Feb 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/asy-mode.el
+
+Delete any existing *asy-help* buffer in asy-show-function-at-point.
+
+------------------------------------------------------------------------
+r2120 | jcbowman | 2007-02-17 09:37:26 -0700 (Sat, 17 Feb 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/graph.asy
+
+Improve tick calculation when Step > 0.
+
+------------------------------------------------------------------------
+r2119 | jcbowman | 2007-02-17 08:47:45 -0700 (Sat, 17 Feb 2007) | 4 lines
+Changed paths:
+ M /trunk/asymptote/base/graph.asy
+
+Fix tick calculation.
+
+Improve zero detection.
+
+------------------------------------------------------------------------
+r2118 | jcbowman | 2007-02-17 03:48:15 -0700 (Sat, 17 Feb 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/graph.asy
+
+Fix tick label scaling.
+
+------------------------------------------------------------------------
+r2117 | jcbowman | 2007-02-16 21:19:34 -0700 (Fri, 16 Feb 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/settings.cc
+
+Remove vv from settings module.
+
+------------------------------------------------------------------------
+r2116 | jcbowman | 2007-02-16 09:23:29 -0700 (Fri, 16 Feb 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/settings.cc
+
+Resolve -vv ambiguity.
+
+------------------------------------------------------------------------
+r2115 | pivaldi | 2007-02-15 04:00:02 -0700 (Thu, 15 Feb 2007) | 1 line
+Changed paths:
+ M /trunk/asymptote/base/plain_markers.asy
+
+Fix typo.
+------------------------------------------------------------------------
+r2114 | jcbowman | 2007-02-14 23:37:14 -0700 (Wed, 14 Feb 2007) | 6 lines
+Changed paths:
+ M /trunk/asymptote/base/slide.asy
+
+Fix spurious vertical shifting of bullets.
+
+Reimplemented figuremattpen.
+
+Make bibliography visible in reverse video.
+
+------------------------------------------------------------------------
+r2113 | jcbowman | 2007-02-14 14:02:00 -0700 (Wed, 14 Feb 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/settings.cc
+
+Added --version option.
+
+------------------------------------------------------------------------
+r2112 | pivaldi | 2007-02-14 04:51:45 -0700 (Wed, 14 Feb 2007) | 1 line
+Changed paths:
+ M /trunk/asymptote/base/asy-mode.el
+
+bug fix in asy-show-function-at-point
+------------------------------------------------------------------------
+r2111 | jcbowman | 2007-02-13 23:56:41 -0700 (Tue, 13 Feb 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/plain_paths.asy
+
+Resolve ambiguity in intersectionpoints.
+
+------------------------------------------------------------------------
+r2110 | jcbowman | 2007-02-13 22:41:42 -0700 (Tue, 13 Feb 2007) | 3 lines
+Changed paths:
+ M /trunk/asymptote/base/plain_markers.asy
+ M /trunk/asymptote/doc/asymptote.texi
+
+Add rotated option to mark_uniform to rotate marker frames by angle of
+local tangent.
+
+------------------------------------------------------------------------
+r2109 | jcbowman | 2007-02-13 22:40:33 -0700 (Tue, 13 Feb 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/plain_picture.asy
+
+Ignore empty picture bounds when adding pictures; simplify userBox and userClip.
+
+------------------------------------------------------------------------
+r2108 | jcbowman | 2007-02-13 15:08:01 -0700 (Tue, 13 Feb 2007) | 2 lines
+Changed paths:
+ A /trunk/asymptote/doc/FAQ/install-sh
+ A /trunk/asymptote/doc/install-sh
+ M /trunk/asymptote/install-sh
+
+Update to latest autoconf install-sh and patch it to ignore -p option.
+
+------------------------------------------------------------------------
+r2107 | jcbowman | 2007-02-12 21:44:06 -0700 (Mon, 12 Feb 2007) | 3 lines
+Changed paths:
+ M /trunk/asymptote/Makefile.in
+ M /trunk/asymptote/doc/asymptote.texi
+
+Add an ASYMPTOTE_SITEDIR environment variable listing additional
+directories to use for generating asy-mode.el keywords.
+
+------------------------------------------------------------------------
+r2106 | jcbowman | 2007-02-12 21:19:14 -0700 (Mon, 12 Feb 2007) | 4 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+
+Document new interactive calculator feature: expressions entered at the
+interactive prompt are automatically evaluated and written to stdout
+(provided a corresponding write method is defined).
+
+------------------------------------------------------------------------
+r2105 | jcbowman | 2007-02-12 20:47:36 -0700 (Mon, 12 Feb 2007) | 3 lines
+Changed paths:
+ A /trunk/asymptote/patches/gc6.8_AIX.patch
+
+Add patch to fix an incorrect Boehm garbage collector prototype in the file
+gc6.8/include/gc.h (version 6.8).
+
+------------------------------------------------------------------------
+r2104 | jcbowman | 2007-02-12 14:53:52 -0700 (Mon, 12 Feb 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/picture.cc
+ M /trunk/asymptote/settings.cc
+ M /trunk/asymptote/settings.h
+
+Added texcommand to allow one to override the tex engine command name.
+
+------------------------------------------------------------------------
+r2103 | jcbowman | 2007-02-12 12:54:38 -0700 (Mon, 12 Feb 2007) | 4 lines
+Changed paths:
+ M /trunk/asymptote/Makefile.in
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/patches/README
+
+Apply gc6.8 GC_INIT patch for AIX systems.
+
+Document gcc3.3.2curses.patch.
+
+------------------------------------------------------------------------
+r2102 | pivaldi | 2007-02-12 08:11:48 -0700 (Mon, 12 Feb 2007) | 1 line
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+
+Minor edit.
+------------------------------------------------------------------------
+r2101 | pivaldi | 2007-02-12 07:51:18 -0700 (Mon, 12 Feb 2007) | 1 line
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+
+Add brief documentation of lasy-mode, typing correction.
+------------------------------------------------------------------------
+r2100 | jcbowman | 2007-02-11 23:04:47 -0700 (Sun, 11 Feb 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/process.cc
+
+Fixed cxx warning message.
+
+------------------------------------------------------------------------
+r2099 | jcbowman | 2007-02-11 22:51:14 -0700 (Sun, 11 Feb 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/entry.cc
+
+Fix compilation under -DNOHASH.
+
+------------------------------------------------------------------------
+r2098 | jcbowman | 2007-02-11 22:36:38 -0700 (Sun, 11 Feb 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/symbol.h
+ M /trunk/asymptote/util.h
+
+Portability tweaks.
+
+------------------------------------------------------------------------
+r2097 | jcbowman | 2007-02-11 21:58:27 -0700 (Sun, 11 Feb 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/patches/gcc3.3.2curses.patch
+
+Use more portable context patch.
+
+------------------------------------------------------------------------
+r2096 | jcbowman | 2007-02-11 21:47:20 -0700 (Sun, 11 Feb 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/patches/gcc3.3.2curses.patch
+
+Make patch more portable.
+
+------------------------------------------------------------------------
+r2095 | pivaldi | 2007-02-11 19:07:13 -0700 (Sun, 11 Feb 2007) | 1 line
+Changed paths:
+ M /trunk/asymptote/base/asy-mode.el
+
+add (require 'wid-edit)
+------------------------------------------------------------------------
+r2094 | pivaldi | 2007-02-11 18:55:37 -0700 (Sun, 11 Feb 2007) | 1 line
+Changed paths:
+ M /trunk/asymptote/base/asy-mode.el
+
+Links pointing to the files are added when one shows for the command at the cursor by the key binding C-c ? within asy-mode.
+------------------------------------------------------------------------
+r2093 | jcbowman | 2007-02-11 14:32:47 -0700 (Sun, 11 Feb 2007) | 5 lines
+Changed paths:
+ M /trunk/asymptote/builtin.cc
+ M /trunk/asymptote/dec.cc
+ M /trunk/asymptote/entry.cc
+ M /trunk/asymptote/entry.h
+ M /trunk/asymptote/exp.cc
+ M /trunk/asymptote/fundec.cc
+ M /trunk/asymptote/name.cc
+ M /trunk/asymptote/record.cc
+ M /trunk/asymptote/settings.cc
+ M /trunk/asymptote/types.cc
+
+Add Andy's patch to store positions of definitions in entry class.
+
+Add a --where option to make --listvariables show where global functions
+and variables are declared.
+
+------------------------------------------------------------------------
+r2092 | hammera | 2007-02-11 10:32:21 -0700 (Sun, 11 Feb 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/knot.h
+
+Fixed typo.
+
+------------------------------------------------------------------------
+r2091 | pivaldi | 2007-02-11 07:42:07 -0700 (Sun, 11 Feb 2007) | 1 line
+Changed paths:
+ M /trunk/asymptote/base/asy-mode.el
+
+Allow to type when viewing compilation result within lasy-mode.
+------------------------------------------------------------------------
+r2090 | jcbowman | 2007-02-10 21:57:26 -0700 (Sat, 10 Feb 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/name.cc
+ M /trunk/asymptote/name.h
+
+Fixed typo.
+
+------------------------------------------------------------------------
+r2089 | pivaldi | 2007-02-10 09:28:02 -0700 (Sat, 10 Feb 2007) | 1 line
+Changed paths:
+ M /trunk/asymptote/base/asy-mode.el
+
+Support of the options of the environment asy and better management of the errors within lasy-mode.
+------------------------------------------------------------------------
+r2088 | jcbowman | 2007-02-09 23:36:57 -0700 (Fri, 09 Feb 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/INSTALL
+ M /trunk/asymptote/asymptote.spec
+ M /trunk/asymptote/configure.ac
+ M /trunk/asymptote/doc/Makefile
+ M /trunk/asymptote/doc/asymptote.texi
+
+Revert to gc6.8.tar.gz due to rpmbuild segmentation fault.
+
+------------------------------------------------------------------------
+r2087 | jcbowman | 2007-02-09 22:42:54 -0700 (Fri, 09 Feb 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/surface.asy
+
+Added surface operator * (transform3 t, surface s).
+
+------------------------------------------------------------------------
+r2086 | jcbowman | 2007-02-09 22:24:08 -0700 (Fri, 09 Feb 2007) | 4 lines
+Changed paths:
+ M /trunk/asymptote/base/graph.asy
+ M /trunk/asymptote/base/graph3.asy
+ M /trunk/asymptote/base/math.asy
+ M /trunk/asymptote/base/plain_Label.asy
+ M /trunk/asymptote/base/surface.asy
+
+Check for out of bounds mesh size and array indices.
+
+Use size(frame) function for max(frame)-min(frame).
+
+------------------------------------------------------------------------
+r2085 | jcbowman | 2007-02-09 22:18:43 -0700 (Fri, 09 Feb 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/runtime.in
+
+Check for attempts to create negative-length arrays.
+
+------------------------------------------------------------------------
+r2084 | jcbowman | 2007-02-09 21:08:29 -0700 (Fri, 09 Feb 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/binarytree.asy
+
+Removed unused line.
+
+------------------------------------------------------------------------
+r2083 | jcbowman | 2007-02-09 19:53:22 -0700 (Fri, 09 Feb 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/binarytree.asy
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/doc/binarytreetest.asy
+
+Implement an interface for drawing an arbitrary binary tree.
+
+------------------------------------------------------------------------
+r2082 | jcbowman | 2007-02-09 15:55:23 -0700 (Fri, 09 Feb 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/INSTALL
+ M /trunk/asymptote/doc/asymptote.texi
+
+Document GNU make requirement.
+
+------------------------------------------------------------------------
+r2081 | jcbowman | 2007-02-09 15:54:18 -0700 (Fri, 09 Feb 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/examples/curvedlabel.asy
+
+Changed capitalization.
+
+------------------------------------------------------------------------
+r2080 | jcbowman | 2007-02-09 15:46:39 -0700 (Fri, 09 Feb 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/settings.cc
+
+Ensure curses routines are declared with "C" linkage.
+
+------------------------------------------------------------------------
+r2079 | jcbowman | 2007-02-09 14:57:52 -0700 (Fri, 09 Feb 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/settings.cc
+
+Work around broken curses.h files.
+
+------------------------------------------------------------------------
+r2078 | jcbowman | 2007-02-09 12:37:34 -0700 (Fri, 09 Feb 2007) | 2 lines
+Changed paths:
+ D /trunk/asymptote/patches/AIXgcc3.3.2curses.patch
+ A /trunk/asymptote/patches/gcc3.3.2curses.patch (from /trunk/asymptote/patches/AIXgcc3.3.2curses.patch:2076)
+
+Renamed patch since this apparently affects both AIX and SGI systems.
+
+------------------------------------------------------------------------
+r2077 | jcbowman | 2007-02-09 00:27:54 -0700 (Fri, 09 Feb 2007) | 7 lines
+Changed paths:
+ M /trunk/asymptote/INSTALL
+ A /trunk/asymptote/base/labelpath.asy
+ M /trunk/asymptote/configure.ac
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/drawclipbegin.h
+ M /trunk/asymptote/drawelement.h
+ M /trunk/asymptote/drawlabel.cc
+ M /trunk/asymptote/drawlabel.h
+ M /trunk/asymptote/drawpath.cc
+ M /trunk/asymptote/drawpath.h
+ M /trunk/asymptote/drawverbatim.h
+ A /trunk/asymptote/examples/curvedlabel.asy
+ M /trunk/asymptote/path.cc
+ M /trunk/asymptote/path.h
+ M /trunk/asymptote/runtime.in
+ M /trunk/asymptote/settings.cc
+ M /trunk/asymptote/settings.h
+ M /trunk/asymptote/texfile.cc
+ M /trunk/asymptote/texfile.h
+ M /trunk/asymptote/transform.h
+
+Fixed bounding box computations of paths drawn with transformed pen nibs.
+
+Implemented optional labelpath interface to PSTricks pstextpath macro for
+drawing curved labels along paths.
+
+Updated to gc-7.0alpha7.
+
+------------------------------------------------------------------------
+r2076 | jcbowman | 2007-02-08 17:26:46 -0700 (Thu, 08 Feb 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/settings.cc
+
+Revert premature changes.
+
+------------------------------------------------------------------------
+r2075 | jcbowman | 2007-02-08 09:48:07 -0700 (Thu, 08 Feb 2007) | 3 lines
+Changed paths:
+ M /trunk/asymptote/main.cc
+ M /trunk/asymptote/settings.cc
+
+Added wait option that waits for all child processes to terminate (to work
+around emacs child-killing bug).
+
+------------------------------------------------------------------------
+r2074 | jcbowman | 2007-02-06 13:57:37 -0700 (Tue, 06 Feb 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/asy-mode.el
+
+Minor edits.
+
+------------------------------------------------------------------------
+r2073 | pivaldi | 2007-02-06 10:16:33 -0700 (Tue, 06 Feb 2007) | 1 line
+Changed paths:
+ M /trunk/asymptote/base/asy-mode.el
+
+Cleaning code, resolution conflict math-mode/lasy-mode, add options for compilation and management of errors.
+------------------------------------------------------------------------
+r2072 | jcbowman | 2007-02-05 07:08:03 -0700 (Mon, 05 Feb 2007) | 2 lines
+Changed paths:
+ A /trunk/asymptote/patches/AIXgcc3.3.2curses.patch
+
+Added patch for old broken gcc3.3.2 curses.h file under AIX.
+
+------------------------------------------------------------------------
+r2071 | jcbowman | 2007-02-04 18:26:12 -0700 (Sun, 04 Feb 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/plain_paths.asy
+
+Optimize intersectionpoints.
+
+------------------------------------------------------------------------
+r2070 | jcbowman | 2007-02-04 18:08:11 -0700 (Sun, 04 Feb 2007) | 3 lines
+Changed paths:
+ M /trunk/asymptote/base/graph.asy
+ M /trunk/asymptote/base/plain_paths.asy
+ M /trunk/asymptote/doc/asymptote.texi
+
+Added routine intersectionpoints(path p, path q) that returns an array of
+all intersection points of paths p and q.
+
+------------------------------------------------------------------------
+r2069 | jcbowman | 2007-02-04 17:50:53 -0700 (Sun, 04 Feb 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/examples/PythagoreanTree.asy
+
+Fill squares.
+
+------------------------------------------------------------------------
+r2068 | jcbowman | 2007-02-04 10:21:53 -0700 (Sun, 04 Feb 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/TODO
+
+New items.
+
+------------------------------------------------------------------------
+r2067 | jcbowman | 2007-02-03 21:48:07 -0700 (Sat, 03 Feb 2007) | 8 lines
+Changed paths:
+ M /trunk/asymptote/base/graph.asy
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/doc/loggraph.asy
+ M /trunk/asymptote/doc/logticks.asy
+
+Make the user-specified tick functions work consistently with the
+auto-generated tick routines; the actual tick value is now passed to the
+ticklabel formatting routine, even in the case of logarithmic axes.
+
+Separate the tick generation and drawing routines and add a tickmodifier
+routine to give users complete control over which of the auto-generated ticks
+actually get drawn.
+
+------------------------------------------------------------------------
+r2066 | jcbowman | 2007-02-03 15:38:42 -0700 (Sat, 03 Feb 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/examples/slidedemo.asy
+ A /trunk/asymptote/examples/slidedemo_.bbl
+
+Add bibliography example to slidedemo.
+
+------------------------------------------------------------------------
+r2065 | jcbowman | 2007-02-03 11:48:57 -0700 (Sat, 03 Feb 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/texfile.cc
+
+Add fuzz to textwidth and textheight to avoid overfull vbox.
+
+------------------------------------------------------------------------
+r2064 | jcbowman | 2007-02-03 02:33:38 -0700 (Sat, 03 Feb 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/slide.asy
+ M /trunk/asymptote/examples/slidedemo.asy
+ M /trunk/asymptote/examples/yingyang.asy
+ M /trunk/asymptote/picture.cc
+ M /trunk/asymptote/texfile.cc
+
+Implement slide presentation BibTeX citations and reference list.
+
+------------------------------------------------------------------------
+r2063 | jcbowman | 2007-01-31 23:41:43 -0700 (Wed, 31 Jan 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/slide.asy
+
+Set autorotate in PDF landscape mode, rather than forcing pdflatex.
+
+------------------------------------------------------------------------
+r2062 | jcbowman | 2007-01-30 10:35:17 -0700 (Tue, 30 Jan 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/runtime.in
+
+Leave the pair to angle conversion to dirSpec.
+
+------------------------------------------------------------------------
+r2061 | jcbowman | 2007-01-30 02:12:58 -0700 (Tue, 30 Jan 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/solids.asy
+ M /trunk/asymptote/doc/asymptote.texi
+
+Document skeleton structure.
+
+------------------------------------------------------------------------
+r2060 | jcbowman | 2007-01-30 01:59:34 -0700 (Tue, 30 Jan 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+
+Mention Imagemagick dependency in Windows installation notes.
+
+------------------------------------------------------------------------
+r2059 | jcbowman | 2007-01-28 19:00:41 -0700 (Sun, 28 Jan 2007) | 2 lines
+Changed paths:
+ A /trunk/asymptote/base/binarytree.asy
+ M /trunk/asymptote/doc/asymptote.texi
+ A /trunk/asymptote/doc/binarytreetest.asy
+
+Added Tobias' binary tree module.
+
+------------------------------------------------------------------------
+r2058 | jcbowman | 2007-01-28 14:51:04 -0700 (Sun, 28 Jan 2007) | 2 lines
+Changed paths:
+ A /trunk/asymptote/base/grid3.asy
+ M /trunk/asymptote/doc/asymptote.texi
+ A /trunk/asymptote/doc/grid3xyz.asy
+
+Added Philippe's grid3 contribution for drawing 3D grids.
+
+------------------------------------------------------------------------
+r2057 | jcbowman | 2007-01-28 11:59:14 -0700 (Sun, 28 Jan 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/settings.cc
+ M /trunk/asymptote/util.h
+
+CYGWIN updates.
+
+------------------------------------------------------------------------
+r2056 | jcbowman | 2007-01-28 10:29:02 -0700 (Sun, 28 Jan 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+
+Make definition of pair I=(0,1) explicit.
+
+------------------------------------------------------------------------
+r2055 | jcbowman | 2007-01-20 14:15:16 -0700 (Sat, 20 Jan 2007) | 4 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.sty
+ M /trunk/asymptote/doc/latexusage.tex
+
+In inline latex usage, do not scale picture by default. Use
+\begin{asy}[\the\linewidth]
+to recover previous default of scaling to line width.
+
+------------------------------------------------------------------------
+r2054 | jcbowman | 2007-01-18 22:28:21 -0700 (Thu, 18 Jan 2007) | 6 lines
+Changed paths:
+ M /trunk/asymptote/base/graph3.asy
+ M /trunk/asymptote/base/three.asy
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/psfile.cc
+
+Implement transparency for shading and image objects.
+
+Allow one to disable Gouraud shading when nsub=1.
+
+Allow draw(nullpath3..cycle3).
+
+------------------------------------------------------------------------
+r2053 | jcbowman | 2007-01-18 03:44:16 -0700 (Thu, 18 Jan 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/imagecontour.asy
+ M /trunk/asymptote/examples/fillcontour.asy
+
+Minor improvements.
+
+------------------------------------------------------------------------
+r2052 | hammera | 2007-01-16 21:00:37 -0700 (Tue, 16 Jan 2007) | 3 lines
+Changed paths:
+ M /trunk/asymptote/dec.h
+ M /trunk/asymptote/process.cc
+ M /trunk/asymptote/stm.cc
+
+Automatically write expression statements at the prompt.
+
+
+------------------------------------------------------------------------
+r2051 | jcbowman | 2007-01-10 17:39:03 -0700 (Wed, 10 Jan 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/palette.asy
+
+Added missing tickmin and tickmax bounds.
+
+------------------------------------------------------------------------
+r2050 | jcbowman | 2007-01-05 14:27:17 -0700 (Fri, 05 Jan 2007) | 2 lines
+Changed paths:
+ M /trunk/asymptote/process.cc
+
+Removed unused code.
+
+------------------------------------------------------------------------
+r2049 | jcbowman | 2006-12-28 22:56:30 -0700 (Thu, 28 Dec 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/configure.ac
+
+Incremented version to 1.21svn.
+
+------------------------------------------------------------------------
+r2048 | jcbowman | 2006-12-28 22:16:22 -0700 (Thu, 28 Dec 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/settings.cc
+
+Fixed cxx warnings.
+
+------------------------------------------------------------------------
+r2047 | jcbowman | 2006-12-28 21:42:55 -0700 (Thu, 28 Dec 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/util.cc
+
+Cleaned up cd diagnostics.
+
+------------------------------------------------------------------------
+r2046 | jcbowman | 2006-12-28 21:22:32 -0700 (Thu, 28 Dec 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/examples/fillcontour.asy
+
+Simplified example.
+
+------------------------------------------------------------------------
+r2045 | jcbowman | 2006-12-28 21:19:01 -0700 (Thu, 28 Dec 2006) | 4 lines
+Changed paths:
+ M /trunk/asymptote/base/contour.asy
+ M /trunk/asymptote/base/palette.asy
+ A /trunk/asymptote/examples/fillcontour.asy
+
+Fixed incorrect offset in palette.
+
+Added routine to fill cyclic contours and example.
+
+------------------------------------------------------------------------
+r2044 | jcbowman | 2006-12-28 10:01:47 -0700 (Thu, 28 Dec 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/process.cc
+ M /trunk/asymptote/runtime.in
+ M /trunk/asymptote/settings.cc
+ M /trunk/asymptote/util.cc
+ M /trunk/asymptote/util.h
+
+Added command-line option to set current directory.
+
+------------------------------------------------------------------------
+r2043 | jcbowman | 2006-12-28 08:55:13 -0700 (Thu, 28 Dec 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/imagecontour.asy
+
+Generalized example.
+
+------------------------------------------------------------------------
+r2042 | jcbowman | 2006-12-25 06:15:20 -0700 (Mon, 25 Dec 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/asymptote.spec
+ M /trunk/asymptote/doc/FAQ/asy-faq.bfnn
+
+Updated FAQ.
+
+------------------------------------------------------------------------
+r2041 | jcbowman | 2006-12-25 05:31:43 -0700 (Mon, 25 Dec 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/settings.cc
+ M /trunk/asymptote/util.cc
+ M /trunk/asymptote/util.h
+
+Clean up Getenv code.
+
+------------------------------------------------------------------------
+r2040 | jcbowman | 2006-12-23 15:51:41 -0700 (Sat, 23 Dec 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/picture.cc
+ M /trunk/asymptote/settings.cc
+ M /trunk/asymptote/util.cc
+
+Fixed texpath and diagnostics under MSWINDOWS.
+
+------------------------------------------------------------------------
+r2039 | jcbowman | 2006-12-17 09:45:04 -0700 (Sun, 17 Dec 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/asy-mode.el
+
+Remove texmathp stuff since this duplicates features in >= AUCTeX 11.82.
+
+------------------------------------------------------------------------
+r2038 | jcbowman | 2006-12-16 14:44:50 -0700 (Sat, 16 Dec 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/asy-mode.el
+ M /trunk/asymptote/examples/parametricsurface.asy
+
+Make asy-mode respect TeX-electric-sub-and-superscript.
+
+------------------------------------------------------------------------
+r2037 | jcbowman | 2006-12-14 10:42:16 -0700 (Thu, 14 Dec 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/dec.cc
+ M /trunk/asymptote/genv.cc
+ M /trunk/asymptote/parser.cc
+ M /trunk/asymptote/parser.h
+
+Improve loading/including diagnostics.
+
+------------------------------------------------------------------------
+r2036 | jcbowman | 2006-12-14 09:54:15 -0700 (Thu, 14 Dec 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/plain_Label.asy
+
+Fixed defaulttransform (e.g. to allow forcing of yaxis label angle).
+
+------------------------------------------------------------------------
+r2035 | jcbowman | 2006-12-14 01:32:35 -0700 (Thu, 14 Dec 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/three.asy
+
+Optimize real argument point, postcontrol, and precontrol functions.
+
+------------------------------------------------------------------------
+r2034 | jcbowman | 2006-12-13 15:16:24 -0700 (Wed, 13 Dec 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/examples/animations/cube.asy
+
+Simplify example.
+
+------------------------------------------------------------------------
+r2033 | jcbowman | 2006-12-13 12:06:37 -0700 (Wed, 13 Dec 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+
+Improve discussion of Bezier curve subdivision.
+
+------------------------------------------------------------------------
+r2032 | jcbowman | 2006-12-13 01:36:09 -0700 (Wed, 13 Dec 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/animate.asy
+ M /trunk/asymptote/examples/animations/wheel.asy
+
+Slow down wheel animation.
+
+------------------------------------------------------------------------
+r2031 | jcbowman | 2006-12-13 00:18:33 -0700 (Wed, 13 Dec 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/configure.ac
+
+Incremented version to 1.20svn.
+
+------------------------------------------------------------------------
+r2030 | jcbowman | 2006-12-12 18:11:44 -0700 (Tue, 12 Dec 2006) | 3 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+
+Emphasize that multiline mode is a setting that can be turned on and off
+within interactive mode.
+
+------------------------------------------------------------------------
+r2029 | jcbowman | 2006-12-12 16:17:30 -0700 (Tue, 12 Dec 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+
+Minor documentation updates.
+
+------------------------------------------------------------------------
+r2028 | jcbowman | 2006-12-12 12:01:14 -0700 (Tue, 12 Dec 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/runtime.in
+
+Make cd() reset path to program startup value.
+
+------------------------------------------------------------------------
+r2027 | jcbowman | 2006-12-12 11:47:29 -0700 (Tue, 12 Dec 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/runtime.in
+
+Updated documentation; fixed cd argument renaming.
+
+------------------------------------------------------------------------
+r2026 | jcbowman | 2006-12-12 11:17:43 -0700 (Tue, 12 Dec 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/process.cc
+ M /trunk/asymptote/runtime.in
+
+Interactive reset should not reset current path.
+
+------------------------------------------------------------------------
+r2025 | jcbowman | 2006-12-12 03:05:00 -0700 (Tue, 12 Dec 2006) | 3 lines
+Changed paths:
+ M /trunk/asymptote/base/solids.asy
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/examples/sacylinder3D.asy
+ M /trunk/asymptote/examples/wedge.asy
+
+Shift cylinder so that axis is c--c+h*unit(axis) for consistency with cone
+and generalized cylinder routine. This change is backwards incompatible.
+
+------------------------------------------------------------------------
+r2024 | jcbowman | 2006-12-12 02:29:45 -0700 (Tue, 12 Dec 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+
+Updated svn instructions.
+
+------------------------------------------------------------------------
+r2023 | jcbowman | 2006-12-12 02:25:22 -0700 (Tue, 12 Dec 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/graph3.asy
+ M /trunk/asymptote/base/graph_settings.asy
+ M /trunk/asymptote/base/math.asy
+ M /trunk/asymptote/base/plain_picture.asy
+ M /trunk/asymptote/base/slopefield.asy
+ A /trunk/asymptote/base/surface.asy
+ M /trunk/asymptote/base/three.asy
+ A /trunk/asymptote/doc/GaussianSurface.asy (from /trunk/asymptote/doc/surface.asy:2019)
+ M /trunk/asymptote/doc/asymptote.texi
+ A /trunk/asymptote/doc/slopefield1.asy
+ D /trunk/asymptote/doc/surface.asy
+ A /trunk/asymptote/examples/BezierSurface.asy
+ M /trunk/asymptote/examples/Coons.asy
+ M /trunk/asymptote/path.cc
+
+Implemented preliminary Bezier surface package.
+
+------------------------------------------------------------------------
+r2022 | jcbowman | 2006-12-12 02:09:10 -0700 (Tue, 12 Dec 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/asy-mode.el
+
+Require Common Lisp extensions.
+
+------------------------------------------------------------------------
+r2021 | hammera | 2006-12-08 18:59:58 -0700 (Fri, 08 Dec 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/TODO
+ M /trunk/asymptote/camp.l
+ M /trunk/asymptote/process.cc
+
+Added support for meaningless slashes at ends of lines.
+
+------------------------------------------------------------------------
+r2020 | jcbowman | 2006-12-08 11:06:02 -0700 (Fri, 08 Dec 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/pipestream.h
+ M /trunk/asymptote/process.cc
+ M /trunk/asymptote/runtime.in
+
+Fixed cxx errors.
+
+------------------------------------------------------------------------
+r2019 | jcbowman | 2006-12-08 10:12:41 -0700 (Fri, 08 Dec 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/Makefile.in
+ M /trunk/asymptote/asymptote.spec
+ M /trunk/asymptote/doc/FAQ/Makefile
+ M /trunk/asymptote/doc/Makefile
+
+Andy's port to nonbash shells.
+
+------------------------------------------------------------------------
+r2018 | jcbowman | 2006-12-08 02:02:12 -0700 (Fri, 08 Dec 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/picture.cc
+
+Fix epstopdf conversion of empty or tiny files.
+
+------------------------------------------------------------------------
+r2017 | jcbowman | 2006-12-08 01:46:52 -0700 (Fri, 08 Dec 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/drawlabel.cc
+
+Improve tex error handling.
+
+------------------------------------------------------------------------
+r2016 | jcbowman | 2006-12-08 01:05:47 -0700 (Fri, 08 Dec 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/latexusage.tex
+ M /trunk/asymptote/texfile.cc
+ M /trunk/asymptote/texfile.h
+
+Fix clipping in inline tex mode.
+
+------------------------------------------------------------------------
+r2015 | jcbowman | 2006-12-08 00:49:43 -0700 (Fri, 08 Dec 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/pipestream.h
+ M /trunk/asymptote/texfile.h
+
+Fixed clipping.
+
+------------------------------------------------------------------------
+r2014 | jcbowman | 2006-12-07 21:41:18 -0700 (Thu, 07 Dec 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/animate.asy
+ M /trunk/asymptote/doc/pdfanim_temp.sty
+ M /trunk/asymptote/drawlabel.cc
+ M /trunk/asymptote/pipestream.h
+ M /trunk/asymptote/settings.cc
+ M /trunk/asymptote/settings.h
+ M /trunk/asymptote/texfile.cc
+
+Fixed inlinetex mode.
+
+------------------------------------------------------------------------
+r2013 | jcbowman | 2006-12-06 22:45:16 -0700 (Wed, 06 Dec 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/drawlabel.cc
+ M /trunk/asymptote/picture.cc
+ M /trunk/asymptote/pipestream.h
+ M /trunk/asymptote/runtime.in
+ M /trunk/asymptote/settings.cc
+ M /trunk/asymptote/settings.h
+
+Repair tex pipe on missing math mode error.
+
+------------------------------------------------------------------------
+r2012 | jcbowman | 2006-12-05 14:13:45 -0700 (Tue, 05 Dec 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/examples/tensor.asy
+
+Use path instead of a guide.
+
+------------------------------------------------------------------------
+r2011 | jcbowman | 2006-12-05 14:13:19 -0700 (Tue, 05 Dec 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/examples/Coons.asy
+
+Remove explicit internal control points.
+
+------------------------------------------------------------------------
+r2010 | jcbowman | 2006-12-05 14:12:37 -0700 (Tue, 05 Dec 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/install-sh
+
+Remove bashism.
+
+------------------------------------------------------------------------
+r2009 | jcbowman | 2006-12-04 11:38:44 -0700 (Mon, 04 Dec 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/flowchart.asy
+ M /trunk/asymptote/doc/asymptote.texi
+
+Standardize flowchart argument names.
+
+------------------------------------------------------------------------
+r2008 | jcbowman | 2006-12-04 00:37:40 -0700 (Mon, 04 Dec 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/flowchart.asy
+
+Simplify flowchart block size calculation.
+
+------------------------------------------------------------------------
+r2007 | jcbowman | 2006-12-04 00:18:33 -0700 (Mon, 04 Dec 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/flowchart.asy
+ M /trunk/asymptote/base/plain_boxes.asy
+ M /trunk/asymptote/doc/advection.asy
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/doc/flowchartdemo.asy
+ M /trunk/asymptote/examples/labelbox.asy
+
+Make flowchart routines work with pictures as well as frames.
+
+------------------------------------------------------------------------
+r2006 | hammera | 2006-12-03 21:57:16 -0700 (Sun, 03 Dec 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/TODO
+
+Added note on backslashes.
+
+------------------------------------------------------------------------
+r2005 | jcbowman | 2006-12-03 10:46:53 -0700 (Sun, 03 Dec 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/plain_boxes.asy
+ M /trunk/asymptote/doc/advection.asy
+ M /trunk/asymptote/examples/labelbox.asy
+
+Renamed object constructor to draw.
+
+------------------------------------------------------------------------
+r2004 | jcbowman | 2006-12-03 10:33:49 -0700 (Sun, 03 Dec 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/plain_picture.asy
+ M /trunk/asymptote/doc/advection.asy
+ M /trunk/asymptote/doc/diatom.asy
+ M /trunk/asymptote/doc/flow.asy
+ M /trunk/asymptote/examples/labelbox.asy
+ M /trunk/asymptote/examples/mosaic.asy
+
+Implement add(picture pic=currentpicture, drawer d);
+
+------------------------------------------------------------------------
+r2003 | jcbowman | 2006-12-03 09:56:26 -0700 (Sun, 03 Dec 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/flowchart.asy
+ M /trunk/asymptote/base/plain_Label.asy
+ M /trunk/asymptote/base/plain_boxes.asy
+ M /trunk/asymptote/doc/advection.asy
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/examples/labelbox.asy
+
+Replace labelframe by existing object structure.
+
+------------------------------------------------------------------------
+r2002 | jcbowman | 2006-12-02 23:00:26 -0700 (Sat, 02 Dec 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/plain_boxes.asy
+ M /trunk/asymptote/doc/advection.asy
+ M /trunk/asymptote/examples/labelbox.asy
+
+Renamed envelope to labelframe and container to envelope.
+
+------------------------------------------------------------------------
+r2001 | jcbowman | 2006-12-02 22:19:41 -0700 (Sat, 02 Dec 2006) | 3 lines
+Changed paths:
+ M /trunk/asymptote/base/plain_boxes.asy
+ M /trunk/asymptote/doc/advection.asy
+ M /trunk/asymptote/examples/labelbox.asy
+ M /trunk/asymptote/settings.cc
+
+Introduce an envelope structure for supporting picture scaling when drawing
+boxes around labels.
+
+------------------------------------------------------------------------
+r2000 | jcbowman | 2006-12-02 22:17:56 -0700 (Sat, 02 Dec 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/generalaxis.asy
+ M /trunk/asymptote/doc/generalaxis3.asy
+ M /trunk/asymptote/doc/westnile.asy
+
+Updated to use new intersect routine.
+
+------------------------------------------------------------------------
+r1999 | jcbowman | 2006-12-02 22:13:45 -0700 (Sat, 02 Dec 2006) | 2 lines
+Changed paths:
+ A /trunk/asymptote/examples/fractaltree.asy
+
+Added fractral tree example.
+
+------------------------------------------------------------------------
+r1998 | jcbowman | 2006-12-02 16:25:09 -0700 (Sat, 02 Dec 2006) | 6 lines
+Changed paths:
+ M /trunk/asymptote/base/featpost3D.asy
+ M /trunk/asymptote/base/graph3.asy
+ M /trunk/asymptote/base/math.asy
+ M /trunk/asymptote/base/plain_arcs.asy
+ M /trunk/asymptote/base/plain_arrows.asy
+ M /trunk/asymptote/base/plain_paths.asy
+ M /trunk/asymptote/base/roundedpath.asy
+ M /trunk/asymptote/base/solids.asy
+ M /trunk/asymptote/base/three.asy
+ M /trunk/asymptote/doc/Makefile
+ D /trunk/asymptote/doc/asy.1
+ A /trunk/asymptote/doc/asy.1.begin
+ A /trunk/asymptote/doc/asy.1.end
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/path.cc
+ M /trunk/asymptote/path.h
+ M /trunk/asymptote/path3.cc
+ M /trunk/asymptote/process.cc
+ M /trunk/asymptote/runtime.in
+ M /trunk/asymptote/settings.cc
+ M /trunk/asymptote/triple.h
+
+Make intersect return an array of reals rather than a pair. In addition to
+being more logical, this helps avoid confusion between intersect and
+pair intersectionpoint().
+
+Autogenerate usage info in manual and man page.
+
+------------------------------------------------------------------------
+r1997 | hammera | 2006-12-01 22:10:09 -0700 (Fri, 01 Dec 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/process.cc
+
+Backslash now continues a line on the interactive prompt.
+
+------------------------------------------------------------------------
+r1996 | jcbowman | 2006-12-01 20:52:09 -0700 (Fri, 01 Dec 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/configure.ac
+ M /trunk/asymptote/runtime.in
+
+Minor diagnostic improvements.
+
+------------------------------------------------------------------------
+r1995 | jcbowman | 2006-12-01 17:33:22 -0700 (Fri, 01 Dec 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/configure.ac
+ M /trunk/asymptote/memory.h
+ M /trunk/asymptote/runtime.in
+
+Fixed compilation failure without GC_DEBUG.
+
+------------------------------------------------------------------------
+r1994 | hammera | 2006-12-01 09:08:14 -0700 (Fri, 01 Dec 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/Makefile.in
+ M /trunk/asymptote/configure.ac
+ M /trunk/asymptote/memory.h
+ M /trunk/asymptote/runtime.in
+
+Added gc debug option.
+
+------------------------------------------------------------------------
+r1993 | jcbowman | 2006-12-01 08:44:32 -0700 (Fri, 01 Dec 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/plain_Label.asy
+
+Remove shift from transform in Rotate(pair).
+
+------------------------------------------------------------------------
+r1992 | hammera | 2006-11-30 21:52:19 -0700 (Thu, 30 Nov 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/camp.l
+ M /trunk/asymptote/camp.y
+ M /trunk/asymptote/doc/asy.1
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/interact.cc
+ M /trunk/asymptote/interact.h
+ M /trunk/asymptote/parser.cc
+ M /trunk/asymptote/parser.h
+ M /trunk/asymptote/process.cc
+ M /trunk/asymptote/settings.cc
+
+Added multiline option for prompt.
+
+------------------------------------------------------------------------
+r1991 | jcbowman | 2006-11-30 08:54:39 -0700 (Thu, 30 Nov 2006) | 4 lines
+Changed paths:
+ M /trunk/asymptote/Makefile.in
+ M /trunk/asymptote/base/animate.asy
+ M /trunk/asymptote/base/embed.asy
+ M /trunk/asymptote/base/external.asy
+ M /trunk/asymptote/base/pdfanim.asy
+ M /trunk/asymptote/doc/Makefile
+ D /trunk/asymptote/doc/PDFAnim_Guide.tex
+ A /trunk/asymptote/doc/PDFAnim_temp_Guide.tex (from /trunk/asymptote/doc/PDFAnim_Guide.tex:1989)
+ M /trunk/asymptote/doc/asymptote.texi
+ D /trunk/asymptote/doc/pdfanim.sty
+ A /trunk/asymptote/doc/pdfanim_temp.sty (from /trunk/asymptote/doc/pdfanim.sty:1989)
+ M /trunk/asymptote/examples/animations/externalmovie.asy
+ M /trunk/asymptote/runtime.in
+
+Renamed pdfanim.sty to pdfanim_temp.sty pending 0.53 release of official pdfanim version.
+
+Delete temporary image and multipage PDF files used for animations.
+
+------------------------------------------------------------------------
+r1990 | jcbowman | 2006-11-29 13:36:09 -0700 (Wed, 29 Nov 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/plain_Label.asy
+
+Added Rotate(pair), fixed alignment positioning transformation.
+
+------------------------------------------------------------------------
+r1989 | jcbowman | 2006-11-29 13:04:47 -0700 (Wed, 29 Nov 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/PDFAnim_Guide.tex
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/doc/pdfanim.sty
+
+Changed pdfanim version to 0.52A.
+
+------------------------------------------------------------------------
+r1988 | jcbowman | 2006-11-29 12:00:23 -0700 (Wed, 29 Nov 2006) | 3 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/examples/animations/wheel.asy
+ M /trunk/asymptote/examples/slidedemo.asy
+ A /trunk/asymptote/examples/slidemovies.asy
+ M /trunk/asymptote/runtime.in
+
+Split slidedemo.asy into slidedemo.asy and slidemovie.asy.
+Minor diagnostic and documentation tweaks.
+
+------------------------------------------------------------------------
+r1987 | jcbowman | 2006-11-29 11:22:35 -0700 (Wed, 29 Nov 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/examples/slidedemo.asy
+
+Move settings.tex="pdflatex" earlier.
+
+------------------------------------------------------------------------
+r1986 | jcbowman | 2006-11-28 23:15:49 -0700 (Tue, 28 Nov 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/asymptote.spec
+ M /trunk/asymptote/doc/asymptote.texi
+ A /trunk/asymptote/examples/animations/dice.u3d
+ A /trunk/asymptote/examples/animations/embeddedu3d.asy
+ M /trunk/asymptote/examples/animations/pdfmovie.asy
+
+Added embedded U3D example.
+
+------------------------------------------------------------------------
+r1985 | jcbowman | 2006-11-28 18:08:46 -0700 (Tue, 28 Nov 2006) | 14 lines
+Changed paths:
+ M /trunk/asymptote/Makefile.in
+ M /trunk/asymptote/base/animate.asy
+ M /trunk/asymptote/base/embed.asy
+ A /trunk/asymptote/base/external.asy
+ A /trunk/asymptote/base/pdfanim.asy
+ M /trunk/asymptote/base/plain_picture.asy
+ M /trunk/asymptote/base/plain_shipout.asy
+ M /trunk/asymptote/base/plain_strings.asy
+ M /trunk/asymptote/base/slide.asy
+ M /trunk/asymptote/doc/Makefile
+ A /trunk/asymptote/doc/PDFAnim_Guide.tex
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/doc/latexusage.tex
+ M /trunk/asymptote/doc/loggraph.asy
+ M /trunk/asymptote/doc/loggrid.asy
+ A /trunk/asymptote/doc/pdfanim.sty
+ M /trunk/asymptote/drawlabel.cc
+ M /trunk/asymptote/drawlabel.h
+ M /trunk/asymptote/drawverbatim.h
+ M /trunk/asymptote/examples/animations/embeddedmovie.asy
+ A /trunk/asymptote/examples/animations/externalmovie.asy
+ A /trunk/asymptote/examples/animations/pdfmovie.asy
+ M /trunk/asymptote/examples/animations/wheel.asy
+ M /trunk/asymptote/examples/slidedemo.asy
+ M /trunk/asymptote/fileio.h
+ M /trunk/asymptote/picture.cc
+ M /trunk/asymptote/picture.h
+ M /trunk/asymptote/pipestream.h
+ M /trunk/asymptote/runtime.in
+ M /trunk/asymptote/settings.cc
+ M /trunk/asymptote/settings.h
+ M /trunk/asymptote/texfile.cc
+ M /trunk/asymptote/texfile.h
+ M /trunk/asymptote/util.cc
+ M /trunk/asymptote/util.h
+
+Support portable high-quality embedded PDF movies via pdfanim module and
+portable external movies of other formats via external module. Included
+enhanced version 0.53 of pdfanim.sty package, with updated documentation.
+
+Abort pfdlatex runs with fatal errors and display error.
+
+Add optional bounds arguments to verbatim postscript and tex commands.
+
+Document how to produce Debian binaries from RPM binaries.
+
+Fixed rescaling bug.
+
+Allow writing to local directory only; added -global option to override.
+
+------------------------------------------------------------------------
+r1984 | hammera | 2006-11-26 21:50:21 -0700 (Sun, 26 Nov 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/exp.cc
+ M /trunk/asymptote/exp.h
+
+Free some of the cached data in the abstract syntax tree.
+
+------------------------------------------------------------------------
+r1983 | hammera | 2006-11-25 15:32:18 -0700 (Sat, 25 Nov 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/entry.h
+ M /trunk/asymptote/env.h
+ M /trunk/asymptote/process.cc
+ M /trunk/asymptote/table.h
+
+Added collapseScope, so empty scopes won't pile up in runnable-at-a-time mode.
+
+------------------------------------------------------------------------
+r1982 | jcbowman | 2006-11-17 16:12:36 -0700 (Fri, 17 Nov 2006) | 4 lines
+Changed paths:
+ M /trunk/asymptote/base/plain_debugger.asy
+ M /trunk/asymptote/fileio.h
+
+Turn off scrolling during debugging.
+
+Fixed typo in debugging help.
+
+------------------------------------------------------------------------
+r1981 | jcbowman | 2006-11-17 00:22:16 -0700 (Fri, 17 Nov 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/math.asy
+
+Added routine to return an arbitrary point inside a cyclic path g.
+
+------------------------------------------------------------------------
+r1980 | jcbowman | 2006-11-17 00:20:18 -0700 (Fri, 17 Nov 2006) | 4 lines
+Changed paths:
+ M /trunk/asymptote/path.cc
+
+Guard against duplicate nodes in inside().
+
+Speed up inside() by testing for points outside of bounding box.
+
+------------------------------------------------------------------------
+r1979 | jcbowman | 2006-11-16 22:24:45 -0700 (Thu, 16 Nov 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/path.cc
+
+Fix numerical precision problem in windingnumber routine.
+
+------------------------------------------------------------------------
+r1978 | hammera | 2006-11-16 21:14:42 -0700 (Thu, 16 Nov 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/parser.cc
+ M /trunk/asymptote/settings.cc
+
+Reformatted long lines in the code.
+
+------------------------------------------------------------------------
+r1977 | hammera | 2006-11-16 21:03:17 -0700 (Thu, 16 Nov 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/settings.cc
+
+More string constant formatting.
+
+------------------------------------------------------------------------
+r1976 | hammera | 2006-11-16 20:56:40 -0700 (Thu, 16 Nov 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/picture.cc
+
+Split string constant to fit on line. (minor)
+
+------------------------------------------------------------------------
+r1975 | jcbowman | 2006-11-15 17:57:34 -0700 (Wed, 15 Nov 2006) | 4 lines
+Changed paths:
+ M /trunk/asymptote/base/plain_strings.asy
+ M /trunk/asymptote/doc/asymptote.texi
+
+Added string(real x) function.
+
+Removed unneeded public qualifiers from documentation.
+
+------------------------------------------------------------------------
+r1974 | jcbowman | 2006-11-15 17:49:19 -0700 (Wed, 15 Nov 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/wce
+
+Changed == to standard bash = syntax.
+
+------------------------------------------------------------------------
+r1973 | jcbowman | 2006-11-14 22:27:47 -0700 (Tue, 14 Nov 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/path.cc
+ M /trunk/asymptote/path.h
+ M /trunk/asymptote/runtime.in
+
+Make winding number of a cyclic path relative to a point visible to users.
+
+------------------------------------------------------------------------
+r1972 | jcbowman | 2006-11-14 14:40:00 -0700 (Tue, 14 Nov 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/leastsquares.asy
+
+Added example of cropping to axis limits.
+
+------------------------------------------------------------------------
+r1971 | jcbowman | 2006-11-14 14:37:16 -0700 (Tue, 14 Nov 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/brokenaxis.asy
+ M /trunk/asymptote/util.h
+
+Minor updates.
+
+------------------------------------------------------------------------
+r1970 | jcbowman | 2006-11-13 22:13:33 -0700 (Mon, 13 Nov 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/picture.cc
+ M /trunk/asymptote/settings.cc
+ M /trunk/asymptote/settings.h
+ M /trunk/asymptote/util.cc
+
+Fixed recently introduced bugs with -o option.
+
+------------------------------------------------------------------------
+r1969 | jcbowman | 2006-11-13 19:52:15 -0700 (Mon, 13 Nov 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/examples/animations/cube.asy
+ M /trunk/asymptote/examples/animations/wavepacket.asy
+ M /trunk/asymptote/examples/animations/wheel.asy
+
+Updated examples.
+
+------------------------------------------------------------------------
+r1968 | jcbowman | 2006-11-13 19:43:46 -0700 (Mon, 13 Nov 2006) | 4 lines
+Changed paths:
+ M /trunk/asymptote/base/animate.asy
+ M /trunk/asymptote/base/plain_picture.asy
+ M /trunk/asymptote/base/plain_shipout.asy
+ M /trunk/asymptote/doc/FAQ/asy-faq.bfnn
+ M /trunk/asymptote/doc/asymptote.texi
+
+Replace unitsize, xunitsize, and yunitsize arguments of shipout
+with a independent call to
+void unitsize(picture pic=currentpicture, real x, real y=x);
+
+------------------------------------------------------------------------
+r1967 | jcbowman | 2006-11-13 08:55:17 -0700 (Mon, 13 Nov 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/CDlabel.asy
+
+Remove unused line.
+
+------------------------------------------------------------------------
+r1966 | jcbowman | 2006-11-13 08:50:58 -0700 (Mon, 13 Nov 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/CDlabel.asy
+
+Minor adjustment.
+
+------------------------------------------------------------------------
+r1965 | jcbowman | 2006-11-13 08:46:54 -0700 (Mon, 13 Nov 2006) | 3 lines
+Changed paths:
+ M /trunk/asymptote/base/babel.asy
+ M /trunk/asymptote/base/plain_picture.asy
+ M /trunk/asymptote/doc/CDlabel.asy
+
+Make clipping set truesize coordinate to 0; updated CDlabel to illustrate
+this fix.
+
+------------------------------------------------------------------------
+r1964 | jcbowman | 2006-11-13 08:26:24 -0700 (Mon, 13 Nov 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/CDlabel.asy
+ M /trunk/asymptote/doc/asymptote.texi
+
+Added umlauts again.
+
+------------------------------------------------------------------------
+r1963 | jcbowman | 2006-11-12 09:45:34 -0700 (Sun, 12 Nov 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+
+Minor updates.
+
+------------------------------------------------------------------------
+r1962 | jcbowman | 2006-11-11 22:03:27 -0700 (Sat, 11 Nov 2006) | 5 lines
+Changed paths:
+ M /trunk/asymptote/base/animate.asy
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/examples/animations/cube.asy
+ A /trunk/asymptote/examples/animations/wavepacket.asy
+ M /trunk/asymptote/examples/animations/wheel.asy
+
+Automatically set the movie bounding box to the largest bounding box of all
+pictures.
+
+Support unitsize, xunitsize, and yunitsize in animations.
+
+------------------------------------------------------------------------
+r1961 | jcbowman | 2006-11-09 15:00:00 -0700 (Thu, 09 Nov 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+
+Update documentation.
+
+------------------------------------------------------------------------
+r1960 | jcbowman | 2006-11-09 14:59:31 -0700 (Thu, 09 Nov 2006) | 4 lines
+Changed paths:
+ M /trunk/asymptote/base/plain_picture.asy
+ M /trunk/asymptote/drawfill.cc
+ M /trunk/asymptote/examples/Coons.asy
+ M /trunk/asymptote/examples/tensor.asy
+ M /trunk/asymptote/runtime.in
+
+Fixed segmentation fault.
+
+Add default argument to tensorshade signature.
+
+------------------------------------------------------------------------
+r1959 | jcbowman | 2006-11-08 22:10:20 -0700 (Wed, 08 Nov 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/FAQ/asy-faq.bfnn
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/runtime.in
+
+Make seconds() portable (e.g. under CYGWIN).
+
+------------------------------------------------------------------------
+r1958 | jcbowman | 2006-11-07 15:51:09 -0700 (Tue, 07 Nov 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+
+Minor updates.
+
+------------------------------------------------------------------------
+r1957 | jcbowman | 2006-11-07 15:27:16 -0700 (Tue, 07 Nov 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/process.cc
+
+Overload postRun in iprompt.
+
+------------------------------------------------------------------------
+r1956 | hammera | 2006-11-07 10:48:58 -0700 (Tue, 07 Nov 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/FAQ/asy-faq.bfnn
+
+Changed a code example to use a variable inside the loop.
+
+------------------------------------------------------------------------
+r1955 | jcbowman | 2006-11-06 23:13:11 -0700 (Mon, 06 Nov 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/arrayop.h
+ M /trunk/asymptote/base/plain_picture.asy
+ M /trunk/asymptote/doc/CDlabel.asy
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/drawfill.cc
+ M /trunk/asymptote/drawfill.h
+ A /trunk/asymptote/examples/Coons.asy
+ A /trunk/asymptote/examples/tensor.asy
+ M /trunk/asymptote/psfile.cc
+ M /trunk/asymptote/psfile.h
+ M /trunk/asymptote/runtime.in
+
+Implemented tensor and Coons shading.
+
+------------------------------------------------------------------------
+r1954 | jcbowman | 2006-11-05 02:26:36 -0700 (Sun, 05 Nov 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/asymptote.spec
+ M /trunk/asymptote/configure.ac
+
+Incremented version to 1.19svn.
+
+------------------------------------------------------------------------
+r1953 | jcbowman | 2006-11-05 00:24:17 -0700 (Sun, 05 Nov 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/diatom.asy
+ M /trunk/asymptote/doc/diatom.csv
+
+Added example showing interaction of fixed-sized and scaled coordinates.
+
+------------------------------------------------------------------------
+r1952 | jcbowman | 2006-11-04 23:39:41 -0700 (Sat, 04 Nov 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/FAQ/asy-faq.bfnn
+
+Updated FAQ to include discussion of static variable allocation.
+
+------------------------------------------------------------------------
+r1951 | jcbowman | 2006-11-04 22:38:10 -0700 (Sat, 04 Nov 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/graph.asy
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/examples/sqrtx01.asy
+
+Make labelx, labely, xtick, and ytick respect graph (e.g. logarithmic) scaling.
+
+------------------------------------------------------------------------
+r1950 | jcbowman | 2006-11-04 17:46:14 -0700 (Sat, 04 Nov 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/FAQ/asy-faq.bfnn
+ M /trunk/asymptote/doc/asymptote.texi
+
+Updated FAQ and documentation.
+
+------------------------------------------------------------------------
+r1949 | jcbowman | 2006-11-04 11:49:12 -0700 (Sat, 04 Nov 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/castop.h
+
+Treat single reads just like array reads: in line mode, move position past any final eol.
+
+------------------------------------------------------------------------
+r1948 | jcbowman | 2006-11-04 01:09:14 -0700 (Sat, 04 Nov 2006) | 11 lines
+Changed paths:
+ M /trunk/asymptote/base/embed.asy
+ M /trunk/asymptote/base/fontsize.asy
+ M /trunk/asymptote/base/latin1.asy
+ M /trunk/asymptote/base/plain_strings.asy
+ M /trunk/asymptote/base/slide.asy
+ M /trunk/asymptote/base/unicode.asy
+ M /trunk/asymptote/doc/CDlabel.asy
+ M /trunk/asymptote/doc/asycolors.sty
+ M /trunk/asymptote/examples/slidedemo.asy
+ M /trunk/asymptote/picture.cc
+ M /trunk/asymptote/runtime.in
+ M /trunk/asymptote/settings.cc
+ M /trunk/asymptote/settings.h
+
+Make bool pdf() and bool latex() visible at asy level.
+
+Add string nativeformat().
+
+Update asycolors to remove pstricks dependency.
+
+Make slide package work with both latex and pdflatex; remove colordvi
+dependency.
+
+Check for latex mode in usepackage and minilatex.
+
+------------------------------------------------------------------------
+r1947 | jcbowman | 2006-11-03 22:25:12 -0700 (Fri, 03 Nov 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/drawclipbegin.h
+ M /trunk/asymptote/drawelement.h
+ M /trunk/asymptote/psfile.h
+ M /trunk/asymptote/settings.cc
+ M /trunk/asymptote/texfile.cc
+ M /trunk/asymptote/texfile.h
+
+Fixed clipping (UnFill) problem by avoiding LaTeX \put.
+
+------------------------------------------------------------------------
+r1946 | jcbowman | 2006-11-03 21:55:27 -0700 (Fri, 03 Nov 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/pen.h
+ M /trunk/asymptote/texfile.h
+
+Fixed pen caching problem.
+
+------------------------------------------------------------------------
+r1945 | cmsavage | 2006-11-03 16:14:45 -0700 (Fri, 03 Nov 2006) | 1 line
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+
+Updated palette documentation.
+------------------------------------------------------------------------
+r1944 | jcbowman | 2006-11-03 08:51:19 -0700 (Fri, 03 Nov 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/texfile.h
+
+Cache a separate copy of pen for tex mode.
+
+------------------------------------------------------------------------
+r1943 | jcbowman | 2006-11-03 00:59:03 -0700 (Fri, 03 Nov 2006) | 4 lines
+Changed paths:
+ M /trunk/asymptote/arrayop.h
+ M /trunk/asymptote/builtin.cc
+ M /trunk/asymptote/runtime.in
+
+Fix max(empty array) error message.
+
+Implement minbound and maxbound also for arrays of pairs and triples.
+
+------------------------------------------------------------------------
+r1942 | jcbowman | 2006-11-03 00:54:56 -0700 (Fri, 03 Nov 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/picture.cc
+
+Check for an existing viewer associated with the given outname.
+
+------------------------------------------------------------------------
+r1941 | jcbowman | 2006-11-03 00:14:25 -0700 (Fri, 03 Nov 2006) | 4 lines
+Changed paths:
+ M /trunk/asymptote/process.cc
+
+Call cleanup, not exitFunction in interactive postRun. Don't tamper with
+interactive flag: if exitFunction fails, interactive will not get reset and
+cleanup will not get called at all.
+
+------------------------------------------------------------------------
+r1940 | jcbowman | 2006-11-02 19:32:30 -0700 (Thu, 02 Nov 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/examples/imagehistogram.asy
+
+Use bin centers for point array.
+
+------------------------------------------------------------------------
+r1939 | jcbowman | 2006-11-02 10:43:32 -0700 (Thu, 02 Nov 2006) | 2 lines
+Changed paths:
+ A /trunk/asymptote/examples/imagehistogram.asy
+
+Added image histogram and contour example.
+
+------------------------------------------------------------------------
+r1938 | jcbowman | 2006-11-02 10:08:39 -0700 (Thu, 02 Nov 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/graph3.asy
+ M /trunk/asymptote/examples/parametricsurface.asy
+
+Fixed drawing of mesh only.
+
+------------------------------------------------------------------------
+r1937 | jcbowman | 2006-11-02 10:03:21 -0700 (Thu, 02 Nov 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/plain_picture.asy
+
+Check for division by zero in scale.
+
+------------------------------------------------------------------------
+r1936 | jcbowman | 2006-10-31 01:31:16 -0700 (Tue, 31 Oct 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/asymptote.spec
+ M /trunk/asymptote/configure.ac
+
+Incremented version to 1.18svn.
+
+------------------------------------------------------------------------
+r1935 | jcbowman | 2006-10-31 00:18:54 -0700 (Tue, 31 Oct 2006) | 4 lines
+Changed paths:
+ M /trunk/asymptote/main.cc
+ M /trunk/asymptote/symbol.cc
+ M /trunk/asymptote/symbol.h
+
+Work around garbage collection bus error on MacOS X.
+
+Call GC_Init during static initialization.
+
+------------------------------------------------------------------------
+r1934 | jcbowman | 2006-10-30 12:22:37 -0700 (Mon, 30 Oct 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/stats.asy
+ M /trunk/asymptote/doc/histogram.asy
+
+Added a uniform histogram routine.
+
+------------------------------------------------------------------------
+r1933 | jcbowman | 2006-10-30 11:41:38 -0700 (Mon, 30 Oct 2006) | 4 lines
+Changed paths:
+ M /trunk/asymptote/base/stats.asy
+ M /trunk/asymptote/doc/histogram.asy
+
+Reverse order of arguments of nonuniform frequency routines for consistency
+with other uniform frequency routines and image and graph routines.
+This change is backwards incompatible.
+
+------------------------------------------------------------------------
+r1932 | jcbowman | 2006-10-28 19:37:26 -0600 (Sat, 28 Oct 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/parser.cc
+ M /trunk/asymptote/parser.h
+ M /trunk/asymptote/process.cc
+ M /trunk/asymptote/process.h
+ M /trunk/asymptote/util.cc
+ M /trunk/asymptote/util.h
+
+Reduce number of mem::string/std::string conversions.
+
+------------------------------------------------------------------------
+r1931 | cmsavage | 2006-10-27 14:38:42 -0600 (Fri, 27 Oct 2006) | 1 line
+Changed paths:
+ M /trunk/asymptote/base/stats.asy
+
+Added 1d/2d frequency routines optimized for regular bin sizes.
+------------------------------------------------------------------------
+r1930 | jcbowman | 2006-10-27 14:13:39 -0600 (Fri, 27 Oct 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/FAQ/asy-faq.bfnn
+
+Updated FAQ.
+
+------------------------------------------------------------------------
+r1929 | jcbowman | 2006-10-26 22:27:54 -0600 (Thu, 26 Oct 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/stats.asy
+
+Improve optimization of 2d frequency routine.
+
+------------------------------------------------------------------------
+r1928 | jcbowman | 2006-10-26 22:13:46 -0600 (Thu, 26 Oct 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/stats.asy
+
+Declare fixed-sized arrays.
+
+------------------------------------------------------------------------
+r1927 | jcbowman | 2006-10-26 22:07:18 -0600 (Thu, 26 Oct 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/stats.asy
+
+Optimized 2d frequency routine.
+
+------------------------------------------------------------------------
+r1926 | jcbowman | 2006-10-25 01:41:55 -0600 (Wed, 25 Oct 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/asymptote.spec
+ M /trunk/asymptote/configure.ac
+
+Incremented version to 1.17svn.
+
+------------------------------------------------------------------------
+r1925 | jcbowman | 2006-10-25 00:26:11 -0600 (Wed, 25 Oct 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+
+Removed page break.
+
+------------------------------------------------------------------------
+r1924 | jcbowman | 2006-10-24 23:50:16 -0600 (Tue, 24 Oct 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/graph.asy
+ M /trunk/asymptote/base/plain_picture.asy
+
+Use pic.scaling in graph.asy.
+
+------------------------------------------------------------------------
+r1923 | jcbowman | 2006-10-24 23:43:12 -0600 (Tue, 24 Oct 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/parser.cc
+ M /trunk/asymptote/parser.h
+
+Move using std::string out of header file; pass references to strings.
+
+------------------------------------------------------------------------
+r1922 | jcbowman | 2006-10-24 23:34:58 -0600 (Tue, 24 Oct 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/process.cc
+ M /trunk/asymptote/process.h
+ M /trunk/asymptote/symbol.cc
+ M /trunk/asymptote/symbol.h
+
+Fixed memory leak.
+
+------------------------------------------------------------------------
+r1921 | jcbowman | 2006-10-24 21:50:49 -0600 (Tue, 24 Oct 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+
+Updated credits.
+
+------------------------------------------------------------------------
+r1920 | jcbowman | 2006-10-24 21:50:33 -0600 (Tue, 24 Oct 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/stats.asy
+
+Added 2d version of frequency binning routine.
+
+------------------------------------------------------------------------
+r1919 | jcbowman | 2006-10-24 11:28:01 -0600 (Tue, 24 Oct 2006) | 10 lines
+Changed paths:
+ M /trunk/asymptote/base/plain_markers.asy
+ M /trunk/asymptote/base/plain_picture.asy
+ M /trunk/asymptote/doc/FAQ/asy-faq.bfnn
+ M /trunk/asymptote/doc/asymptote.texi
+ A /trunk/asymptote/doc/legend.asy
+
+Added modified version of Mark Henning's multi-line legend routine.
+
+Added legend example.
+
+Renamed truepoint to framepoint; added truepoint function which works like
+point but accounts for fixed-sized objects.
+
+picture.calculateTransform now returns the actual transform used for
+fitting in the case where only an approximate picture size was available.
+
+------------------------------------------------------------------------
+r1918 | jcbowman | 2006-10-23 12:31:55 -0600 (Mon, 23 Oct 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+
+Changed ARCH to i386 since that is the only case that currently applies.
+
+------------------------------------------------------------------------
+r1917 | jcbowman | 2006-10-23 12:30:33 -0600 (Mon, 23 Oct 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/texfile.h
+
+Fixed \usepackage[inline]{asymptote}.
+
+------------------------------------------------------------------------
+r1916 | jcbowman | 2006-10-22 00:58:10 -0600 (Sun, 22 Oct 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/Makefile
+
+Run latex 3 times on CAD.
+
+------------------------------------------------------------------------
+r1915 | jcbowman | 2006-10-22 00:50:57 -0600 (Sun, 22 Oct 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/Makefile
+
+Remove temporary CAD files.
+
+------------------------------------------------------------------------
+r1914 | jcbowman | 2006-10-22 00:41:51 -0600 (Sun, 22 Oct 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/asymptote.spec
+ M /trunk/asymptote/configure.ac
+
+Incremented version to 1.16svn.
+
+------------------------------------------------------------------------
+r1913 | jcbowman | 2006-10-21 22:46:25 -0600 (Sat, 21 Oct 2006) | 2 lines
+Changed paths:
+ A /trunk/asymptote/base/CAD.asy
+ A /trunk/asymptote/doc/CAD.tex
+ A /trunk/asymptote/doc/CAD1.asy
+ M /trunk/asymptote/doc/Makefile
+ M /trunk/asymptote/doc/asymptote.texi
+
+Added Mark Henning's 2D CAD package (DIN 15).
+
+------------------------------------------------------------------------
+r1912 | jcbowman | 2006-10-21 22:23:26 -0600 (Sat, 21 Oct 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+
+Document restriction of annotations to tex and latex tex engines.
+
+------------------------------------------------------------------------
+r1911 | jcbowman | 2006-10-21 22:20:13 -0600 (Sat, 21 Oct 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/texfile.cc
+ M /trunk/asymptote/texfile.h
+
+Make graphics labels work with tex and pdftex engines.
+
+------------------------------------------------------------------------
+r1910 | jcbowman | 2006-10-21 21:00:37 -0600 (Sat, 21 Oct 2006) | 4 lines
+Changed paths:
+ M /trunk/asymptote/base/slide.asy
+ A /trunk/asymptote/doc/CDlabel.asy
+ M /trunk/asymptote/doc/asymptote.texi
+
+Added CDlabel example to illustrate clipping of graphics.
+
+Changed overfull slide error to warning.
+
+------------------------------------------------------------------------
+r1909 | jcbowman | 2006-10-21 18:00:29 -0600 (Sat, 21 Oct 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/picture.cc
+
+Remove temporary pdf files.
+
+------------------------------------------------------------------------
+r1908 | jcbowman | 2006-10-21 14:24:39 -0600 (Sat, 21 Oct 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/three.asy
+ M /trunk/asymptote/examples/animations/cube.asy
+
+Fixed cube animation.
+
+------------------------------------------------------------------------
+r1907 | jcbowman | 2006-10-21 00:17:26 -0600 (Sat, 21 Oct 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/texfile.cc
+
+Force unitlength=1pt in inline tex mode.
+
+------------------------------------------------------------------------
+r1906 | jcbowman | 2006-10-21 00:00:53 -0600 (Sat, 21 Oct 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/tests/array/determinant.asy
+
+Added further determinant of singular matrix tests.
+
+------------------------------------------------------------------------
+r1905 | jcbowman | 2006-10-20 23:54:40 -0600 (Fri, 20 Oct 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/runtime.in
+
+Determinant of a singular matrix should return 0, not an error.
+
+------------------------------------------------------------------------
+r1904 | jcbowman | 2006-10-19 23:56:09 -0600 (Thu, 19 Oct 2006) | 3 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/picture.cc
+ M /trunk/asymptote/psfile.h
+ M /trunk/asymptote/settings.cc
+ M /trunk/asymptote/texfile.cc
+ M /trunk/asymptote/texfile.h
+
+Use LaTeX color package for latex and pdflatex to keep latex informed of
+current color.
+
+------------------------------------------------------------------------
+r1903 | jcbowman | 2006-10-19 23:54:14 -0600 (Thu, 19 Oct 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/plain_pens.asy
+ M /trunk/asymptote/drawlabel.cc
+
+Fixed label fuzz.
+
+------------------------------------------------------------------------
+r1902 | jcbowman | 2006-10-16 17:01:07 -0600 (Mon, 16 Oct 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/drawelement.h
+ M /trunk/asymptote/drawfill.h
+
+Fixed incorrect path bounds in lattice shade.
+
+------------------------------------------------------------------------
+r1901 | jcbowman | 2006-10-16 13:07:45 -0600 (Mon, 16 Oct 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+
+Fixed typo.
+
+------------------------------------------------------------------------
+r1900 | jcbowman | 2006-10-16 07:52:33 -0600 (Mon, 16 Oct 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/settings.cc
+
+Another attempt at fixing compilation problem under MacOS X 10.3.9 (cf. r1290).
+
+------------------------------------------------------------------------
+r1899 | jcbowman | 2006-10-15 19:40:33 -0600 (Sun, 15 Oct 2006) | 4 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/settings.cc
+
+Fixed compilation problem under MacOS X 10.3.9.
+
+Rename configuation variable latex to texpath in documentation.
+
+------------------------------------------------------------------------
+r1898 | jcbowman | 2006-10-15 17:00:58 -0600 (Sun, 15 Oct 2006) | 6 lines
+Changed paths:
+ M /trunk/asymptote/base/plain_picture.asy
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/examples/poster.asy
+
+In cases like 2D graphs where only an approximate picture size estimate is
+available, adjust the transform so that the fitted frame meets the
+size specification. The pic.scale() routine (which scales the resulting
+frame, including fonts and true size objects) can enforce even better
+compliance in such cases, but should not normally be required.
+
+------------------------------------------------------------------------
+r1897 | jcbowman | 2006-10-14 23:16:14 -0600 (Sat, 14 Oct 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/FAQ/asy-faq.bfnn
+
+Minor clarification.
+
+------------------------------------------------------------------------
+r1896 | jcbowman | 2006-10-14 22:42:12 -0600 (Sat, 14 Oct 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/patches/README
+ D /trunk/asymptote/patches/gv-3.5.8-all.patch
+ D /trunk/asymptote/patches/gv-3.6.1-getopt.patch
+ D /trunk/asymptote/patches/gv-3.6.1-gs8.patch
+ D /trunk/asymptote/patches/gv-3.6.1-landscape.patch
+ D /trunk/asymptote/patches/gv-3.6.1-sigint.patch
+
+Remove gv patches since these are all in the long-awaited gv-3.6.2 release.
+
+------------------------------------------------------------------------
+r1895 | jcbowman | 2006-10-14 22:21:17 -0600 (Sat, 14 Oct 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/configure.ac
+
+Incremented version to 1.15svn.
+
+------------------------------------------------------------------------
+r1894 | jcbowman | 2006-10-14 19:50:30 -0600 (Sat, 14 Oct 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/examples/poster.asy
+
+Adjusted example.
+
+------------------------------------------------------------------------
+r1893 | jcbowman | 2006-10-14 19:23:21 -0600 (Sat, 14 Oct 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/FAQ/asy-faq.bfnn
+
+Updated FAQ.
+
+------------------------------------------------------------------------
+r1892 | jcbowman | 2006-10-14 19:11:41 -0600 (Sat, 14 Oct 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+
+Documented filloutside.
+
+------------------------------------------------------------------------
+r1891 | jcbowman | 2006-10-14 18:50:37 -0600 (Sat, 14 Oct 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/drawlabel.h
+ M /trunk/asymptote/main.cc
+ M /trunk/asymptote/texfile.cc
+ M /trunk/asymptote/texfile.h
+
+Fixed cxx warnings.
+
+------------------------------------------------------------------------
+r1890 | jcbowman | 2006-10-14 16:45:23 -0600 (Sat, 14 Oct 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/psfile.cc
+
+Added missing space.
+
+------------------------------------------------------------------------
+r1889 | jcbowman | 2006-10-14 16:40:18 -0600 (Sat, 14 Oct 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/psfile.cc
+ M /trunk/asymptote/tests/Makefile
+
+Support color fonts for pdftex and pdflatex.
+
+------------------------------------------------------------------------
+r1888 | jcbowman | 2006-10-14 16:21:59 -0600 (Sat, 14 Oct 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/palette.asy
+ M /trunk/asymptote/doc/asymptote.texi
+ A /trunk/asymptote/doc/penimage.asy
+ M /trunk/asymptote/drawimage.h
+ M /trunk/asymptote/psfile.cc
+ M /trunk/asymptote/psfile.h
+ M /trunk/asymptote/runtime.in
+
+Implement ability to draw images directly from a two-dimensional pen array.
+
+------------------------------------------------------------------------
+r1887 | jcbowman | 2006-10-14 15:26:59 -0600 (Sat, 14 Oct 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/plain_Label.asy
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/drawlabel.cc
+
+Fixed label alignment transformation; implemented general scaleless routine.
+
+------------------------------------------------------------------------
+r1886 | jcbowman | 2006-10-14 02:03:40 -0600 (Sat, 14 Oct 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/configure.ac
+ M /trunk/asymptote/runtime.in
+
+Fix readline test.
+
+------------------------------------------------------------------------
+r1885 | jcbowman | 2006-10-13 23:03:41 -0600 (Fri, 13 Oct 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/configure.ac
+
+Fix test for readline 4.2.
+
+------------------------------------------------------------------------
+r1884 | jcbowman | 2006-10-13 22:32:56 -0600 (Fri, 13 Oct 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/configure.ac
+ M /trunk/asymptote/doc/asymptote.texi
+
+Disable support for readline versions < 4.2.
+
+------------------------------------------------------------------------
+r1883 | jcbowman | 2006-10-13 16:50:51 -0600 (Fri, 13 Oct 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/drawlabel.cc
+
+Scale label fuzz to height+depth not width.
+
+------------------------------------------------------------------------
+r1882 | jcbowman | 2006-10-12 18:01:22 -0600 (Thu, 12 Oct 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.sty
+
+Define pdfoutput if necessary for older versions of latex.
+
+------------------------------------------------------------------------
+r1881 | jcbowman | 2006-10-12 17:30:14 -0600 (Thu, 12 Oct 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/asy.1
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/drawlabel.cc
+ M /trunk/asymptote/pen.h
+ M /trunk/asymptote/picture.cc
+ M /trunk/asymptote/psfile.cc
+ M /trunk/asymptote/psfile.h
+ M /trunk/asymptote/settings.cc
+ M /trunk/asymptote/settings.h
+ M /trunk/asymptote/texfile.cc
+ M /trunk/asymptote/texfile.h
+
+Implement tex and pdftex TeX engines.
+
+------------------------------------------------------------------------
+r1880 | jcbowman | 2006-10-12 00:05:50 -0600 (Thu, 12 Oct 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/drawlabel.cc
+
+Implemented more robust label fuzz calculation.
+
+------------------------------------------------------------------------
+r1879 | jcbowman | 2006-10-11 21:48:25 -0600 (Wed, 11 Oct 2006) | 4 lines
+Changed paths:
+ M /trunk/asymptote/doc/Makefile
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/doc/latexusage.tex
+ M /trunk/asymptote/texfile.cc
+
+Crop generated pdf files.
+
+Fixed pdf label transforms.
+
+------------------------------------------------------------------------
+r1878 | jcbowman | 2006-10-11 16:41:37 -0600 (Wed, 11 Oct 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/picture.cc
+ M /trunk/asymptote/picture.h
+
+Handle files with and without labels consistently under -tex=pdflatex.
+
+------------------------------------------------------------------------
+r1877 | jcbowman | 2006-10-11 08:43:27 -0600 (Wed, 11 Oct 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/asy-mode.el
+
+Added support for Emacs 21 (quickly tested with 21.4.1 only).
+
+------------------------------------------------------------------------
+r1876 | jcbowman | 2006-10-11 01:25:14 -0600 (Wed, 11 Oct 2006) | 6 lines
+Changed paths:
+ M /trunk/asymptote/doc/FAQ/asy-faq.bfnn
+ M /trunk/asymptote/doc/Makefile
+ M /trunk/asymptote/doc/asy.1
+ M /trunk/asymptote/doc/asymptote.sty
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/doc/latexusage.tex
+ M /trunk/asymptote/drawlabel.cc
+ M /trunk/asymptote/drawlabel.h
+ M /trunk/asymptote/picture.cc
+ M /trunk/asymptote/picture.h
+ M /trunk/asymptote/psfile.cc
+ M /trunk/asymptote/psfile.h
+ M /trunk/asymptote/settings.cc
+ M /trunk/asymptote/settings.h
+ M /trunk/asymptote/texfile.cc
+ M /trunk/asymptote/texfile.h
+
+Added support for alternate texengines (currently "latex", "pdflatex", "none").
+
+Support \usepackage[inline]{asymptote} under both latex and pdflatex.
+
+Clean up singleton path eps writes.
+
+------------------------------------------------------------------------
+r1875 | jcbowman | 2006-10-08 15:16:08 -0600 (Sun, 08 Oct 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/graph.asy
+
+Revert revisions 1867-1869.
+
+------------------------------------------------------------------------
+r1874 | jcbowman | 2006-10-07 14:00:36 -0600 (Sat, 07 Oct 2006) | 8 lines
+Changed paths:
+ M /trunk/asymptote/base/plain_Label.asy
+ M /trunk/asymptote/base/plain_filldraw.asy
+ M /trunk/asymptote/base/plain_pens.asy
+ M /trunk/asymptote/base/plain_picture.asy
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/drawclipbegin.h
+ M /trunk/asymptote/drawclipend.h
+ M /trunk/asymptote/drawelement.h
+ M /trunk/asymptote/drawgrestore.h
+ M /trunk/asymptote/drawgsave.h
+ M /trunk/asymptote/examples/animations/cube.asy
+ M /trunk/asymptote/pen.h
+ M /trunk/asymptote/psfile.h
+ M /trunk/asymptote/texfile.cc
+ M /trunk/asymptote/texfile.h
+
+Implemented general label clipping; removed evenoddoverlap and
+zerowindingoverlap fill rules as this functionality can be achieved at a higher
+level, using inside(path, pair, pen).
+
+Changed bool scale argument of Label structure to Shift, Rotate, Slant, or
+Scale, which indicates how the Label transforms with the embedding picture.
+
+
+------------------------------------------------------------------------
+r1873 | jcbowman | 2006-10-06 04:39:26 -0600 (Fri, 06 Oct 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/graph.asy
+
+Reset x and y boundRoutines after processing.
+
+------------------------------------------------------------------------
+r1872 | jcbowman | 2006-10-04 09:45:16 -0600 (Wed, 04 Oct 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/TODO
+
+Remove obsolete item.
+
+------------------------------------------------------------------------
+r1871 | jcbowman | 2006-10-03 22:15:25 -0600 (Tue, 03 Oct 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/graph.asy
+ M /trunk/asymptote/base/plain_filldraw.asy
+
+Remove further unneeded instantiations (as of revision 1870).
+
+------------------------------------------------------------------------
+r1870 | hammera | 2006-10-03 18:53:50 -0600 (Tue, 03 Oct 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/graph.asy
+ M /trunk/asymptote/dec.cc
+ M /trunk/asymptote/dec.h
+ M /trunk/asymptote/fundec.cc
+
+addOps now add operators as fields (so they can be imported).
+
+------------------------------------------------------------------------
+r1869 | jcbowman | 2006-10-03 17:47:39 -0600 (Tue, 03 Oct 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/graph.asy
+
+Allow use of UnFill in tick labels.
+
+------------------------------------------------------------------------
+r1868 | jcbowman | 2006-10-03 17:30:14 -0600 (Tue, 03 Oct 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/graph.asy
+
+Simplify general axis routine.
+
+------------------------------------------------------------------------
+r1867 | jcbowman | 2006-10-03 17:22:31 -0600 (Tue, 03 Oct 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/graph.asy
+
+Simplify call to ticks.
+
+------------------------------------------------------------------------
+r1866 | jcbowman | 2006-10-02 22:03:40 -0600 (Mon, 02 Oct 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/graph.asy
+ M /trunk/asymptote/base/plain_Label.asy
+ M /trunk/asymptote/doc/westnile.asy
+
+Move Label shift member into transform member.
+
+------------------------------------------------------------------------
+r1865 | jcbowman | 2006-10-01 18:12:11 -0600 (Sun, 01 Oct 2006) | 5 lines
+Changed paths:
+ M /trunk/asymptote/base/graph.asy
+ M /trunk/asymptote/base/palette.asy
+ M /trunk/asymptote/base/plain_Label.asy
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/doc/logo.asy
+ M /trunk/asymptote/drawlabel.cc
+ M /trunk/asymptote/drawlabel.h
+ M /trunk/asymptote/runtime.in
+ M /trunk/asymptote/texfile.cc
+ M /trunk/asymptote/texfile.h
+
+Implement general label transforms, including slant.
+
+Added option to Label to allow labels to scale and slant with pictures and
+frames.
+
+------------------------------------------------------------------------
+r1864 | jcbowman | 2006-09-30 14:26:05 -0600 (Sat, 30 Sep 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/picture.cc
+
+Fixed "Cannot write to venn_.tex" error under Windows XP.
+
+------------------------------------------------------------------------
+r1863 | jcbowman | 2006-09-30 10:56:10 -0600 (Sat, 30 Sep 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/Delaunay.cc
+ M /trunk/asymptote/asymptote.spec
+ M /trunk/asymptote/process.cc
+
+Fixed cxx errors and warnings.
+
+------------------------------------------------------------------------
+r1862 | jcbowman | 2006-09-27 15:58:38 -0600 (Wed, 27 Sep 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/plain_Label.asy
+
+Fixed transformation of label alignments.
+
+------------------------------------------------------------------------
+r1861 | jcbowman | 2006-09-27 00:22:53 -0600 (Wed, 27 Sep 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/graph.asy
+
+Make scale set automin and automax settings in autoscaleT.
+
+------------------------------------------------------------------------
+r1860 | jcbowman | 2006-09-26 23:41:09 -0600 (Tue, 26 Sep 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/plain_picture.asy
+
+Added boundRoutine[] bound to autoscaleT.
+
+------------------------------------------------------------------------
+r1859 | jcbowman | 2006-09-26 23:39:37 -0600 (Tue, 26 Sep 2006) | 3 lines
+Changed paths:
+ M /trunk/asymptote/base/graph.asy
+ M /trunk/asymptote/doc/asymptote.texi
+
+Improved graph routines: added xaxis and yaxis bounds communication,
+allow axes with ticks and unextended axes to be called on an empty picture.
+
+------------------------------------------------------------------------
+r1858 | jcbowman | 2006-09-26 22:18:06 -0600 (Tue, 26 Sep 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/examples/dimension.asy
+
+Simplified example.
+
+------------------------------------------------------------------------
+r1857 | jcbowman | 2006-09-25 06:03:16 -0600 (Mon, 25 Sep 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/plain_shipout.asy
+ M /trunk/asymptote/doc/FAQ/asy-faq.bfnn
+ M /trunk/asymptote/doc/asymptote.texi
+
+Allow for separate xunitsize and yunitsize scalings.
+
+------------------------------------------------------------------------
+r1856 | jcbowman | 2006-09-24 11:26:11 -0600 (Sun, 24 Sep 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+
+Improved documentation of tick extend option.
+
+------------------------------------------------------------------------
+r1855 | jcbowman | 2006-09-24 09:40:22 -0600 (Sun, 24 Sep 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/graph.asy
+ M /trunk/asymptote/base/graph_settings.asy
+
+Removed axislabelmargin.
+
+------------------------------------------------------------------------
+r1854 | jcbowman | 2006-09-24 00:59:08 -0600 (Sun, 24 Sep 2006) | 3 lines
+Changed paths:
+ M /trunk/asymptote/base/graph.asy
+
+The axislabelmargin setting should only affect alignment perpendicular to
+the axis.
+
+------------------------------------------------------------------------
+r1853 | jcbowman | 2006-09-24 00:38:54 -0600 (Sun, 24 Sep 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/graph.asy
+
+Adjust axis labels only in direction perpendicular to axis.
+
+------------------------------------------------------------------------
+r1852 | jcbowman | 2006-09-23 22:32:04 -0600 (Sat, 23 Sep 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/plain_arrows.asy
+
+Draw path label after drawing path.
+
+------------------------------------------------------------------------
+r1851 | jcbowman | 2006-09-21 12:28:57 -0600 (Thu, 21 Sep 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/plain_Label.asy
+
+Allow Label(Label,pair).
+
+------------------------------------------------------------------------
+r1850 | jcbowman | 2006-09-21 12:27:30 -0600 (Thu, 21 Sep 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/asy-mode.el
+
+Add partial support for xemacs.
+
+------------------------------------------------------------------------
+r1849 | jcbowman | 2006-09-21 01:21:34 -0600 (Thu, 21 Sep 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/texfile.h
+
+Leave vertical mode before put.
+
+------------------------------------------------------------------------
+r1848 | jcbowman | 2006-09-21 00:12:10 -0600 (Thu, 21 Sep 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+
+Fixed grammatical error.
+
+------------------------------------------------------------------------
+r1847 | jcbowman | 2006-09-21 00:08:42 -0600 (Thu, 21 Sep 2006) | 3 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+ A /trunk/asymptote/doc/mexicanhat.asy
+
+Added Mexican Hat (wavelet) example that nicely illustrates the distinction
+between guides and paths.
+
+------------------------------------------------------------------------
+r1846 | jcbowman | 2006-09-20 08:50:13 -0600 (Wed, 20 Sep 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/texfile.cc
+ M /trunk/asymptote/texfile.h
+
+Removed dependency on rotate.tex.
+
+------------------------------------------------------------------------
+r1845 | jcbowman | 2006-09-19 23:08:34 -0600 (Tue, 19 Sep 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.sty
+ M /trunk/asymptote/texfile.cc
+ M /trunk/asymptote/texfile.h
+
+Removed dependence on pstricks.
+
+------------------------------------------------------------------------
+r1844 | jcbowman | 2006-09-19 22:12:31 -0600 (Tue, 19 Sep 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/plain_filldraw.asy
+ M /trunk/asymptote/base/plain_picture.asy
+
+Added filloutside routines.
+
+------------------------------------------------------------------------
+r1843 | jcbowman | 2006-09-18 16:00:15 -0600 (Mon, 18 Sep 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/FAQ/asy-faq.bfnn
+ M /trunk/asymptote/settings.cc
+
+Ignore setlocale errors; improved discussion of setlocale in FAQ.
+
+------------------------------------------------------------------------
+r1842 | jcbowman | 2006-09-17 22:32:31 -0600 (Sun, 17 Sep 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/picture.cc
+
+Fix -aZ -f pdf.
+
+------------------------------------------------------------------------
+r1841 | jcbowman | 2006-09-17 22:18:06 -0600 (Sun, 17 Sep 2006) | 3 lines
+Changed paths:
+ M /trunk/asymptote/base/plain_filldraw.asy
+ M /trunk/asymptote/doc/asymptote.texi
+
+Standardized filltype definitions and added a Draw filltype (e.g. for drawing a
+bounding box around a label).
+
+------------------------------------------------------------------------
+r1840 | jcbowman | 2006-09-16 22:18:03 -0600 (Sat, 16 Sep 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/process.cc
+
+Fixed typos in comments.
+
+------------------------------------------------------------------------
+r1839 | jcbowman | 2006-09-16 21:50:16 -0600 (Sat, 16 Sep 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/asy.1
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/process.cc
+ M /trunk/asymptote/settings.cc
+
+Make -p option only effective in noninteractive mode.
+
+------------------------------------------------------------------------
+r1838 | jcbowman | 2006-09-16 15:39:41 -0600 (Sat, 16 Sep 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/plain_debugger.asy
+
+Accept ? as alternative to h (help).
+
+------------------------------------------------------------------------
+r1837 | jcbowman | 2006-09-16 15:38:37 -0600 (Sat, 16 Sep 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/plain_debugger.asy
+
+Quit (q) should turn off off debugging mode.
+
+------------------------------------------------------------------------
+r1836 | jcbowman | 2006-09-16 15:11:09 -0600 (Sat, 16 Sep 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/contour3.asy
+ M /trunk/asymptote/examples/Gouraudcontour.asy
+
+Minor simplifications.
+
+------------------------------------------------------------------------
+r1835 | jcbowman | 2006-09-16 15:05:59 -0600 (Sat, 16 Sep 2006) | 4 lines
+Changed paths:
+ M /trunk/asymptote/base/palette.asy
+ M /trunk/asymptote/doc/FAQ/asy-faq.bfnn
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/doc/contour3.asy
+ A /trunk/asymptote/examples/Gouraudcontour.asy
+
+Added irregular mesh image contour routines.
+
+Fixed documentation regarding explicits image bounds.
+
+------------------------------------------------------------------------
+r1834 | jcbowman | 2006-09-16 15:02:46 -0600 (Sat, 16 Sep 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/Delaunay.cc
+ M /trunk/asymptote/Delaunay.h
+ M /trunk/asymptote/runtime.in
+
+Fixed numerical precision issues; minor optimizations.
+
+------------------------------------------------------------------------
+r1833 | jcbowman | 2006-09-16 12:18:45 -0600 (Sat, 16 Sep 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/contour.asy
+
+Minor optimization.
+
+------------------------------------------------------------------------
+r1832 | jcbowman | 2006-09-16 01:32:59 -0600 (Sat, 16 Sep 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/FAQ/asy-faq.bfnn
+
+Fixed docref.
+
+------------------------------------------------------------------------
+r1831 | jcbowman | 2006-09-16 00:44:13 -0600 (Sat, 16 Sep 2006) | 4 lines
+Changed paths:
+ M /trunk/asymptote/doc/FAQ/Makefile
+ M /trunk/asymptote/doc/FAQ/asy-faq.bfnn
+ M /trunk/asymptote/doc/asymptote.texi
+
+Updated FAQ.
+
+Improved Makefile.
+
+------------------------------------------------------------------------
+r1830 | jcbowman | 2006-09-15 21:55:17 -0600 (Fri, 15 Sep 2006) | 4 lines
+Changed paths:
+ M /trunk/asymptote/base/contour.asy
+
+Added contour wrapper for explicit x and y arrays.
+
+Standardized contour argument names.
+
+------------------------------------------------------------------------
+r1829 | jcbowman | 2006-09-13 20:56:26 -0600 (Wed, 13 Sep 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/process.cc
+
+Fixed unhandled exception on startup.
+
+------------------------------------------------------------------------
+r1828 | hammera | 2006-09-13 19:40:19 -0600 (Wed, 13 Sep 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/interact.cc
+
+Ignore keyboard interrupts during readline.
+
+------------------------------------------------------------------------
+r1827 | jcbowman | 2006-09-13 00:25:47 -0600 (Wed, 13 Sep 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/FAQ/asy-faq.bfnn
+
+Modified example.
+
+------------------------------------------------------------------------
+r1826 | jcbowman | 2006-09-13 00:24:37 -0600 (Wed, 13 Sep 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/FAQ/asy-faq.bfnn
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/doc/linetype.asy
+
+Generalized axis alignment example.
+
+------------------------------------------------------------------------
+r1825 | jcbowman | 2006-09-12 23:45:10 -0600 (Tue, 12 Sep 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/graph.asy
+
+Fixed axisMin.
+
+------------------------------------------------------------------------
+r1824 | jcbowman | 2006-09-12 23:36:12 -0600 (Tue, 12 Sep 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/graph.asy
+
+Calculate, don't cache, axis userMin and userMax values.
+
+------------------------------------------------------------------------
+r1823 | jcbowman | 2006-09-12 01:02:42 -0600 (Tue, 12 Sep 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/TODO
+ M /trunk/asymptote/base/slide.asy
+ M /trunk/asymptote/doc/asy.1
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/picture.cc
+ M /trunk/asymptote/settings.cc
+
+Add PDF autorotate option; landscape slides now automatically turn this on.
+
+------------------------------------------------------------------------
+r1822 | jcbowman | 2006-09-11 22:24:22 -0600 (Mon, 11 Sep 2006) | 2 lines
+Changed paths:
+ A /trunk/asymptote/examples/buildcycle.asy
+
+Added example of buildcycle.
+
+------------------------------------------------------------------------
+r1821 | jcbowman | 2006-09-11 22:20:23 -0600 (Mon, 11 Sep 2006) | 4 lines
+Changed paths:
+ M /trunk/asymptote/base/plain_paths.asy
+ M /trunk/asymptote/doc/asymptote.texi
+
+Port and document MetaPost buildcycle.
+
+Document new behaviour of asy -l file...
+
+------------------------------------------------------------------------
+r1820 | jcbowman | 2006-09-11 21:45:35 -0600 (Mon, 11 Sep 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/drawpath.cc
+
+Allow draw(nullpath) again.
+
+------------------------------------------------------------------------
+r1819 | jcbowman | 2006-09-10 13:33:24 -0600 (Sun, 10 Sep 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/Makefile.in
+
+Fixed asy path and base directory.
+
+------------------------------------------------------------------------
+r1818 | jcbowman | 2006-09-09 21:55:55 -0600 (Sat, 09 Sep 2006) | 4 lines
+Changed paths:
+ M /trunk/asymptote/Makefile.in
+ M /trunk/asymptote/asy-list.pl
+ M /trunk/asymptote/base/asy-mode.el
+ M /trunk/asymptote/examples/slidedemo.asy
+
+Added type highlighting list to asy-keywords.el and asy-mode.el.
+
+Simplified building of asy-keywords.el.
+
+------------------------------------------------------------------------
+r1817 | hammera | 2006-09-09 12:26:29 -0600 (Sat, 09 Sep 2006) | 3 lines
+Changed paths:
+ M /trunk/asymptote/Makefile.in
+ M /trunk/asymptote/application.h
+ M /trunk/asymptote/dec.cc
+ M /trunk/asymptote/dec.h
+ M /trunk/asymptote/errormsg.h
+ M /trunk/asymptote/genv.cc
+ M /trunk/asymptote/interact.cc
+ M /trunk/asymptote/interact.h
+ M /trunk/asymptote/keywords.pl
+ M /trunk/asymptote/main.cc
+ M /trunk/asymptote/parser.cc
+ M /trunk/asymptote/parser.h
+ M /trunk/asymptote/picture.cc
+ A /trunk/asymptote/process.cc
+ A /trunk/asymptote/process.h
+ M /trunk/asymptote/runtime.in
+ M /trunk/asymptote/settings.cc
+ M /trunk/asymptote/settings.h
+ M /trunk/asymptote/stack.h
+ M /trunk/asymptote/stm.cc
+ M /trunk/asymptote/stm.h
+ M /trunk/asymptote/util.cc
+ M /trunk/asymptote/util.h
+
+Refactored interactive prompt. Moved asy code processing from main.cc to
+process.cc.
+
+------------------------------------------------------------------------
+r1816 | jcbowman | 2006-09-08 12:40:18 -0600 (Fri, 08 Sep 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/fileio.h
+
+Fixed infinite loop on stdin EOF during scrolling.
+
+------------------------------------------------------------------------
+r1815 | jcbowman | 2006-09-07 21:59:28 -0600 (Thu, 07 Sep 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/settings.cc
+
+Make last workaround CYGWIN specific.
+
+------------------------------------------------------------------------
+r1814 | jcbowman | 2006-09-07 07:56:04 -0600 (Thu, 07 Sep 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/configure.ac
+ M /trunk/asymptote/settings.cc
+
+Work around missing ncurses/term.h symbolic link under CYGWIN.
+
+------------------------------------------------------------------------
+r1813 | jcbowman | 2006-09-06 02:52:45 -0600 (Wed, 06 Sep 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/configure.ac
+
+Incremented version to 1.14svn.
+
+------------------------------------------------------------------------
+r1812 | jcbowman | 2006-09-05 22:47:22 -0600 (Tue, 05 Sep 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/Makefile.in
+
+Added path qualifier.
+
+------------------------------------------------------------------------
+r1811 | jcbowman | 2006-09-05 21:17:34 -0600 (Tue, 05 Sep 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/annotate.asy
+ M /trunk/asymptote/base/contour.asy
+ M /trunk/asymptote/base/drawtree.asy
+ M /trunk/asymptote/base/featpost3D.asy
+ M /trunk/asymptote/base/feynman.asy
+ M /trunk/asymptote/base/flowchart.asy
+ M /trunk/asymptote/base/geometry.asy
+ M /trunk/asymptote/base/graph.asy
+ M /trunk/asymptote/base/graph3.asy
+ M /trunk/asymptote/base/math.asy
+ M /trunk/asymptote/base/palette.asy
+ M /trunk/asymptote/base/patterns.asy
+ M /trunk/asymptote/base/plain.asy
+ M /trunk/asymptote/base/plain_Label.asy
+ M /trunk/asymptote/base/plain_arcs.asy
+ M /trunk/asymptote/base/plain_arrows.asy
+ M /trunk/asymptote/base/plain_boxes.asy
+ M /trunk/asymptote/base/plain_constants.asy
+ M /trunk/asymptote/base/plain_debugger.asy
+ M /trunk/asymptote/base/plain_filldraw.asy
+ M /trunk/asymptote/base/plain_margins.asy
+ M /trunk/asymptote/base/plain_markers.asy
+ M /trunk/asymptote/base/plain_paths.asy
+ M /trunk/asymptote/base/plain_pens.asy
+ M /trunk/asymptote/base/plain_picture.asy
+ M /trunk/asymptote/base/plain_shipout.asy
+ M /trunk/asymptote/base/plain_strings.asy
+ M /trunk/asymptote/base/pstoedit.asy
+ M /trunk/asymptote/base/roundedpath.asy
+ M /trunk/asymptote/base/simplex.asy
+ M /trunk/asymptote/base/slide.asy
+ M /trunk/asymptote/base/slopefield.asy
+ M /trunk/asymptote/base/solids.asy
+ M /trunk/asymptote/base/stats.asy
+ M /trunk/asymptote/base/three.asy
+
+Standardized indentation of and untabify base files.
+
+------------------------------------------------------------------------
+r1810 | jcbowman | 2006-09-05 10:24:50 -0600 (Tue, 05 Sep 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/FAQ/asy-faq.bfnn
+ M /trunk/asymptote/doc/asymptote.texi
+
+Updated documentation and FAQ.
+
+------------------------------------------------------------------------
+r1809 | jcbowman | 2006-09-05 10:24:30 -0600 (Tue, 05 Sep 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/Makefile.in
+
+Added html target for building html documentation from main directory.
+
+------------------------------------------------------------------------
+r1808 | jcbowman | 2006-09-05 00:24:39 -0600 (Tue, 05 Sep 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/FAQ/asy-faq.bfnn
+ M /trunk/asymptote/doc/asymptote.texi
+
+FAQ updates
+
+------------------------------------------------------------------------
+r1807 | jcbowman | 2006-09-04 23:13:53 -0600 (Mon, 04 Sep 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/asy-init.el
+ M /trunk/asymptote/base/asy-mode.el
+ M /trunk/asymptote/doc/asymptote.texi
+
+Explicitly load asy-mode.el in case an old compiled version exists.
+
+------------------------------------------------------------------------
+r1806 | jcbowman | 2006-09-04 23:04:52 -0600 (Mon, 04 Sep 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/asy.vim
+
+Color name updates.
+
+------------------------------------------------------------------------
+r1805 | jcbowman | 2006-09-04 22:29:45 -0600 (Mon, 04 Sep 2006) | 4 lines
+Changed paths:
+ M /trunk/asymptote/base/three.asy
+
+Project triple to align in call to label and Label.
+
+Cast triple to position.
+
+------------------------------------------------------------------------
+r1804 | jcbowman | 2006-09-04 22:18:35 -0600 (Mon, 04 Sep 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/three.asy
+
+Remove cast from triple to align.
+
+------------------------------------------------------------------------
+r1803 | jcbowman | 2006-09-04 22:12:03 -0600 (Mon, 04 Sep 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/asy-mode.el
+
+Make grep case-sensitive.
+
+------------------------------------------------------------------------
+r1802 | jcbowman | 2006-09-04 01:40:35 -0600 (Mon, 04 Sep 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/FAQ/asy-faq.bfnn
+
+More FAQ updates.
+
+------------------------------------------------------------------------
+r1801 | jcbowman | 2006-09-04 01:36:16 -0600 (Mon, 04 Sep 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/FAQ/asy-faq.bfnn
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/doc/latexusage.tex
+
+Updated FAQ.
+
+------------------------------------------------------------------------
+r1800 | jcbowman | 2006-09-04 01:30:35 -0600 (Mon, 04 Sep 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/plain_arrows.asy
+
+Allow arrowhead to be called with a position type.
+
+------------------------------------------------------------------------
+r1799 | jcbowman | 2006-09-04 01:29:06 -0600 (Mon, 04 Sep 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/graph.asy
+
+Use pTick as default for ptick.
+
+------------------------------------------------------------------------
+r1798 | jcbowman | 2006-09-03 12:05:53 -0600 (Sun, 03 Sep 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/picture.cc
+
+Revert last change.
+
+------------------------------------------------------------------------
+r1797 | jcbowman | 2006-09-03 11:49:35 -0600 (Sun, 03 Sep 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/picture.cc
+
+Close fout immediately to avoid race condition with gv in interactive mode.
+
+------------------------------------------------------------------------
+r1796 | jcbowman | 2006-09-03 09:05:31 -0600 (Sun, 03 Sep 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/Makefile.in
+ M /trunk/asymptote/doc/FAQ/Makefile
+ M /trunk/asymptote/doc/FAQ/asy-faq.bfnn
+ M /trunk/asymptote/doc/Makefile
+
+Install asy-faq.info with make install-all.
+
+------------------------------------------------------------------------
+r1795 | jcbowman | 2006-09-03 00:01:55 -0600 (Sun, 03 Sep 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/interact.cc
+
+Fixed cxx warning message.
+
+------------------------------------------------------------------------
+r1794 | jcbowman | 2006-09-02 23:45:44 -0600 (Sat, 02 Sep 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/Makefile.in
+
+Removed ASYMPTOTE_DIR.
+
+------------------------------------------------------------------------
+r1793 | jcbowman | 2006-09-02 23:42:37 -0600 (Sat, 02 Sep 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/FAQ/Makefile
+
+Simplified Makefile.
+
+------------------------------------------------------------------------
+r1792 | jcbowman | 2006-09-02 23:35:46 -0600 (Sat, 02 Sep 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/Makefile.in
+
+Distribute keywords.cc.
+
+------------------------------------------------------------------------
+r1791 | jcbowman | 2006-09-02 23:29:35 -0600 (Sat, 02 Sep 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/asymptote.spec
+ M /trunk/asymptote/keywords.pl
+
+Make keywords.pl executable.
+
+------------------------------------------------------------------------
+r1790 | jcbowman | 2006-09-02 23:20:58 -0600 (Sat, 02 Sep 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/Makefile.in
+ A /trunk/asymptote/doc/FAQ
+ A /trunk/asymptote/doc/FAQ/Makefile
+ A /trunk/asymptote/doc/FAQ/asy-faq.bfnn
+ A /trunk/asymptote/doc/FAQ/bfnnconv.pl
+ A /trunk/asymptote/doc/FAQ/m-ascii.pl
+ A /trunk/asymptote/doc/FAQ/m-html.pl
+ A /trunk/asymptote/doc/FAQ/m-info.pl
+ A /trunk/asymptote/doc/FAQ/m-lout.pl
+ A /trunk/asymptote/doc/FAQ/m-post.pl
+ M /trunk/asymptote/doc/Makefile
+
+Added Frequently Asked Questions (FAQ).
+
+------------------------------------------------------------------------
+r1789 | jcbowman | 2006-09-02 11:28:41 -0600 (Sat, 02 Sep 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/fileio.h
+
+Respect scroll setting only in interactive mode.
+
+------------------------------------------------------------------------
+r1788 | jcbowman | 2006-09-02 11:21:14 -0600 (Sat, 02 Sep 2006) | 6 lines
+Changed paths:
+ M /trunk/asymptote/Makefile.in
+ A /trunk/asymptote/asy-list.pl
+ M /trunk/asymptote/base/asy-init.el
+ M /trunk/asymptote/base/asy-mode.el
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/entry.cc
+
+Add Philippe's changes to asy-mode.el, including menu and asy-insinuate-latex.
+
+Handle shells other than bash in asy-mode.el.
+
+Autogenerate asy-keywords.el.
+
+------------------------------------------------------------------------
+r1787 | jcbowman | 2006-08-30 21:53:25 -0600 (Wed, 30 Aug 2006) | 6 lines
+Changed paths:
+ M /trunk/asymptote/base/plain_shipout.asy
+ M /trunk/asymptote/dec.cc
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/drawlabel.cc
+ M /trunk/asymptote/fundec.cc
+ M /trunk/asymptote/newexp.cc
+ M /trunk/asymptote/picture.cc
+ M /trunk/asymptote/picture.h
+ M /trunk/asymptote/psfile.cc
+ M /trunk/asymptote/psfile.h
+ M /trunk/asymptote/texfile.cc
+
+Make annotations with frame transformation; cleaned up @defspecial code.
+
+Check for successful PostScript writes.
+
+Standardize "Can't" vs. "Cannot".
+
+------------------------------------------------------------------------
+r1786 | jcbowman | 2006-08-30 21:48:31 -0600 (Wed, 30 Aug 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/plain_picture.asy
+
+Simplified calculateTransform logic.
+
+------------------------------------------------------------------------
+r1785 | jcbowman | 2006-08-30 21:46:56 -0600 (Wed, 30 Aug 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/examples/workcone.asy
+
+Improved example.
+
+------------------------------------------------------------------------
+r1784 | jcbowman | 2006-08-30 21:44:46 -0600 (Wed, 30 Aug 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/asy-mode.el
+
+Disable magic () parenthesis.
+
+------------------------------------------------------------------------
+r1783 | jcbowman | 2006-08-30 16:35:02 -0600 (Wed, 30 Aug 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/psfile.h
+
+Prevent exponential notation in %%BoudingBox.
+
+------------------------------------------------------------------------
+r1782 | hammera | 2006-08-30 13:11:11 -0600 (Wed, 30 Aug 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/tests/output/Makefile
+
+Test using a local version of asy.
+
+------------------------------------------------------------------------
+r1781 | hammera | 2006-08-30 13:10:08 -0600 (Wed, 30 Aug 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/tests/Makefile
+
+Don't run "../asy output/*.asy" as this doesn't test the files properly.
+
+------------------------------------------------------------------------
+r1780 | jcbowman | 2006-08-29 21:04:38 -0600 (Tue, 29 Aug 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/INSTALL
+ M /trunk/asymptote/configure.ac
+ M /trunk/asymptote/doc/asymptote.texi
+
+Updated to use gc6.8.
+
+------------------------------------------------------------------------
+r1779 | jcbowman | 2006-08-29 15:47:24 -0600 (Tue, 29 Aug 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/examples/shellmethod.asy
+ M /trunk/asymptote/examples/shellsqrtx01.asy
+ M /trunk/asymptote/examples/sqrtx01.asy
+ M /trunk/asymptote/examples/sqrtx01y1.asy
+ M /trunk/asymptote/examples/washermethod.asy
+ M /trunk/asymptote/examples/xxsq01.asy
+ M /trunk/asymptote/examples/xxsq01x-1.asy
+ M /trunk/asymptote/examples/xxsq01y.asy
+
+Reduce size of generated files.
+
+------------------------------------------------------------------------
+r1778 | jcbowman | 2006-08-29 11:30:15 -0600 (Tue, 29 Aug 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/examples/equilchord.asy
+ M /trunk/asymptote/examples/sacone.asy
+ A /trunk/asymptote/examples/sacone3D.asy
+ A /trunk/asymptote/examples/sacylinder.asy
+ A /trunk/asymptote/examples/sacylinder3D.asy
+ A /trunk/asymptote/examples/shellmethod.asy
+ A /trunk/asymptote/examples/shellsqrtx01.asy
+ M /trunk/asymptote/examples/sqrtx01.asy
+ M /trunk/asymptote/examples/sqrtx01y1.asy
+ A /trunk/asymptote/examples/washermethod.asy
+ M /trunk/asymptote/examples/wedge.asy
+ M /trunk/asymptote/examples/workcone.asy
+ M /trunk/asymptote/examples/xxsq01.asy
+ A /trunk/asymptote/examples/xxsq01x-1.asy
+ A /trunk/asymptote/examples/xxsq01y.asy
+
+More three-dimensional examples.
+
+------------------------------------------------------------------------
+r1777 | jcbowman | 2006-08-29 11:29:33 -0600 (Tue, 29 Aug 2006) | 4 lines
+Changed paths:
+ M /trunk/asymptote/base/solids.asy
+
+Fixed definition and documentation of cone.
+
+Added longitudinal pen to draw.
+
+------------------------------------------------------------------------
+r1776 | jcbowman | 2006-08-29 11:28:51 -0600 (Tue, 29 Aug 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/three.asy
+
+Added cast from triple to align.
+
+------------------------------------------------------------------------
+r1775 | jcbowman | 2006-08-28 22:35:39 -0600 (Mon, 28 Aug 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/three.asy
+ M /trunk/asymptote/doc/asymptote.texi
+
+Added up argument to projection routines to specify camera orientation.
+
+------------------------------------------------------------------------
+r1774 | jcbowman | 2006-08-27 20:58:32 -0600 (Sun, 27 Aug 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/graph3.asy
+ M /trunk/asymptote/doc/asymptote.texi
+
+Minor optimization and documentation updates.
+
+------------------------------------------------------------------------
+r1773 | jcbowman | 2006-08-27 18:53:20 -0600 (Sun, 27 Aug 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/graph3.asy
+ M /trunk/asymptote/base/math.asy
+ M /trunk/asymptote/base/palette.asy
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/doc/surface.asy
+ M /trunk/asymptote/drawpath.cc
+
+Cleaned up surface functions.
+
+------------------------------------------------------------------------
+r1772 | jcbowman | 2006-08-27 18:42:43 -0600 (Sun, 27 Aug 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/plain_debugger.asy
+
+Avoid warning message under -d.
+
+------------------------------------------------------------------------
+r1771 | jcbowman | 2006-08-27 14:08:51 -0600 (Sun, 27 Aug 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/asy-mode.el
+
+Moved documentation to beginning of file again.
+
+------------------------------------------------------------------------
+r1770 | jcbowman | 2006-08-27 13:44:12 -0600 (Sun, 27 Aug 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/asy-mode.el
+
+Disabled magic [] since this makes typing real[] awkward.
+
+------------------------------------------------------------------------
+r1769 | jcbowman | 2006-08-26 18:29:31 -0600 (Sat, 26 Aug 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/tests/gc/string.asy
+
+Removed obsolete comment.
+
+------------------------------------------------------------------------
+r1768 | jcbowman | 2006-08-26 15:44:33 -0600 (Sat, 26 Aug 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/asy-mode.el
+
+Don't indent after struct definition without optional ;
+
+------------------------------------------------------------------------
+r1767 | jcbowman | 2006-08-26 12:06:44 -0600 (Sat, 26 Aug 2006) | 3 lines
+Changed paths:
+ M /trunk/asymptote/base/asy-mode.el
+
+Disable magic {} as this makes grouping existing blocks of code (without
+going to the trouble of selecting a region) inconvenient.
+
+------------------------------------------------------------------------
+r1766 | jcbowman | 2006-08-26 12:01:32 -0600 (Sat, 26 Aug 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/asy-mode.el
+
+Fixed indentation of public/private permission modifiers.
+
+------------------------------------------------------------------------
+r1765 | jcbowman | 2006-08-26 11:59:21 -0600 (Sat, 26 Aug 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/graph.asy
+
+Fixed indentation.
+
+------------------------------------------------------------------------
+r1764 | jcbowman | 2006-08-26 01:07:35 -0600 (Sat, 26 Aug 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/asy-mode.el
+
+Mention two-mode-mode recommended package also in online documentation.
+
+------------------------------------------------------------------------
+r1763 | jcbowman | 2006-08-25 22:41:48 -0600 (Fri, 25 Aug 2006) | 3 lines
+Changed paths:
+ M /trunk/asymptote/base/asy-mode.el
+ M /trunk/asymptote/doc/asymptote.texi
+
+Remove the strict requirement of the two-mode-mode package for minimal
+functionality of asy-mode.el.
+
+------------------------------------------------------------------------
+r1762 | jcbowman | 2006-08-25 22:14:11 -0600 (Fri, 25 Aug 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/asy-mode.el
+ M /trunk/asymptote/doc/asymptote.texi
+
+Replaced asy-mode.el with slight improvement of Philippe Ivaldi's version.
+
+------------------------------------------------------------------------
+r1761 | jcbowman | 2006-08-24 21:18:05 -0600 (Thu, 24 Aug 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/plain_arrows.asy
+
+Check path[] index.
+
+------------------------------------------------------------------------
+r1760 | jcbowman | 2006-08-24 21:13:14 -0600 (Thu, 24 Aug 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/plain_arrows.asy
+ M /trunk/asymptote/base/plain_filldraw.asy
+ M /trunk/asymptote/base/plain_picture.asy
+
+Allow legends and markers when drawing superpaths.
+
+------------------------------------------------------------------------
+r1759 | jcbowman | 2006-08-24 11:28:50 -0600 (Thu, 24 Aug 2006) | 4 lines
+Changed paths:
+ M /trunk/asymptote/base/contour.asy
+ M /trunk/asymptote/base/graph.asy
+ A /trunk/asymptote/base/graph_settings.asy
+ M /trunk/asymptote/doc/contour2.asy
+
+Moved graph settings to separate module graph_settings.
+
+Renamed nmesh to ngraph.
+
+------------------------------------------------------------------------
+r1758 | jcbowman | 2006-08-23 22:47:44 -0600 (Wed, 23 Aug 2006) | 3 lines
+Changed paths:
+ M /trunk/asymptote/base/contour.asy
+ M /trunk/asymptote/base/palette.asy
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/doc/triangulate.asy
+
+Removed resolution arguments (nx and ny) from matrix contour routines;
+instead calculate these from the matrix itself.
+
+------------------------------------------------------------------------
+r1757 | jcbowman | 2006-08-22 09:00:55 -0600 (Tue, 22 Aug 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/drawpath.cc
+ M /trunk/asymptote/path.cc
+ M /trunk/asymptote/path.h
+
+Simplify calculation of cyclic path bounding boxes.
+
+------------------------------------------------------------------------
+r1756 | jcbowman | 2006-08-21 22:30:45 -0600 (Mon, 21 Aug 2006) | 4 lines
+Changed paths:
+ M /trunk/asymptote/drawpath.cc
+ M /trunk/asymptote/path.cc
+ M /trunk/asymptote/path.h
+
+Check that root is in range in bounds().
+
+Implemented general solution for pen padding/capping of paths.
+
+------------------------------------------------------------------------
+r1755 | jcbowman | 2006-08-20 22:22:33 -0600 (Sun, 20 Aug 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+
+Added link to externally contributed examples: http://home.tele2.fr/phivaldi/asymptote
+
+------------------------------------------------------------------------
+r1754 | jcbowman | 2006-08-20 21:56:22 -0600 (Sun, 20 Aug 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/drawpath.cc
+ M /trunk/asymptote/drawpath.h
+
+Account for pen cap contribution to bounding box.
+
+------------------------------------------------------------------------
+r1753 | hammera | 2006-08-20 00:20:41 -0600 (Sun, 20 Aug 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/dec.cc
+
+Exclude module accesses (and imports) from listing.
+
+------------------------------------------------------------------------
+r1752 | jcbowman | 2006-08-19 22:25:26 -0600 (Sat, 19 Aug 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/palette.asy
+ M /trunk/asymptote/doc/asymptote.texi
+
+Fixed image transposition.
+
+------------------------------------------------------------------------
+r1751 | jcbowman | 2006-08-19 18:13:36 -0600 (Sat, 19 Aug 2006) | 3 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/fileio.h
+ M /trunk/asymptote/settings.cc
+ M /trunk/asymptote/settings.h
+
+Discard extra characters after scroll commands (q).
+If scroll is negative, use one less than number of display lines.
+
+------------------------------------------------------------------------
+r1750 | jcbowman | 2006-08-19 09:44:40 -0600 (Sat, 19 Aug 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/util.cc
+
+Changed header.
+
+------------------------------------------------------------------------
+r1749 | jcbowman | 2006-08-18 16:07:59 -0600 (Fri, 18 Aug 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/palette.asy
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/doc/imagecontour.asy
+ M /trunk/asymptote/runtime.in
+
+Standardized image and contour conventions for matrices.
+
+------------------------------------------------------------------------
+r1748 | jcbowman | 2006-08-18 15:56:31 -0600 (Fri, 18 Aug 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/examples/slidedemo.asy
+
+Improved documentation of command-line arguments.
+
+------------------------------------------------------------------------
+r1747 | jcbowman | 2006-08-18 15:55:57 -0600 (Fri, 18 Aug 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/main.cc
+
+Removed unneeded settings qualifiers.
+
+------------------------------------------------------------------------
+r1746 | jcbowman | 2006-08-18 15:54:35 -0600 (Fri, 18 Aug 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/contour.asy
+
+Minor optimization.
+
+------------------------------------------------------------------------
+r1745 | jcbowman | 2006-08-18 15:52:27 -0600 (Fri, 18 Aug 2006) | 7 lines
+Changed paths:
+ M /trunk/asymptote/base/plain_constants.asy
+ M /trunk/asymptote/base/plain_paths.asy
+ M /trunk/asymptote/base/three.asy
+ M /trunk/asymptote/doc/asymptote.texi
+
+Changed write without data arguments to work consistently with the forms
+with data arguments:
+
+write(suffix suffix=endl);
+write(file fout, suffix suffix=none);
+
+
+------------------------------------------------------------------------
+r1744 | jcbowman | 2006-08-18 14:46:47 -0600 (Fri, 18 Aug 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/picture.cc
+
+Remove spurious grestore; if no labels move grestore before showpage.
+
+------------------------------------------------------------------------
+r1743 | jcbowman | 2006-08-17 14:29:46 -0600 (Thu, 17 Aug 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/Makefile.in
+
+Move GCLIBS dependency before others.
+
+------------------------------------------------------------------------
+r1742 | jcbowman | 2006-08-17 12:24:16 -0600 (Thu, 17 Aug 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/entry.cc
+
+Added missing brace.
+
+------------------------------------------------------------------------
+r1741 | jcbowman | 2006-08-17 11:41:33 -0600 (Thu, 17 Aug 2006) | 7 lines
+Changed paths:
+ M /trunk/asymptote/builtin.cc
+ M /trunk/asymptote/dec.cc
+ M /trunk/asymptote/dec.h
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/entry.cc
+ M /trunk/asymptote/entry.h
+ M /trunk/asymptote/env.h
+ M /trunk/asymptote/exp.cc
+ M /trunk/asymptote/fundec.cc
+ M /trunk/asymptote/name.cc
+ M /trunk/asymptote/newexp.cc
+ M /trunk/asymptote/record.cc
+ M /trunk/asymptote/runtime.in
+ M /trunk/asymptote/settings.cc
+ M /trunk/asymptote/types.cc
+
+Added whereDefined() to entry class.
+
+Implemented void list(string *s, bool imports=false); to list all
+global functions and variables in a module named by string s.
+
+Removed unneeded init_readline in readline() routine.
+
+------------------------------------------------------------------------
+r1740 | jcbowman | 2006-08-16 16:16:45 -0600 (Wed, 16 Aug 2006) | 4 lines
+Changed paths:
+ M /trunk/asymptote/base/graph.asy
+ M /trunk/asymptote/base/graph3.asy
+
+Fixed xtick default argument issue.
+
+Added 3d tick routines.
+
+------------------------------------------------------------------------
+r1739 | jcbowman | 2006-08-16 10:05:37 -0600 (Wed, 16 Aug 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/asy.1
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/entry.cc
+ M /trunk/asymptote/interact.cc
+
+Minor edits.
+
+------------------------------------------------------------------------
+r1738 | jcbowman | 2006-08-16 09:54:54 -0600 (Wed, 16 Aug 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/graph.asy
+
+Truncate out-of-bounds position parameters in labelaxis.
+
+------------------------------------------------------------------------
+r1737 | hammera | 2006-08-10 00:39:19 -0600 (Thu, 10 Aug 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+
+Partially undid last change.
+
+------------------------------------------------------------------------
+r1736 | hammera | 2006-08-10 00:32:54 -0600 (Thu, 10 Aug 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/asy.1
+ M /trunk/asymptote/doc/asymptote.texi
+
+Added tabcompletion to documentation.
+
+------------------------------------------------------------------------
+r1735 | jcbowman | 2006-08-09 08:21:11 -0600 (Wed, 09 Aug 2006) | 4 lines
+Changed paths:
+ M /trunk/asymptote/picture.cc
+ M /trunk/asymptote/picture.h
+
+Simplified texprocess and postprocess signatures.
+
+Removed diagnostic.
+
+------------------------------------------------------------------------
+r1734 | jcbowman | 2006-08-09 08:12:20 -0600 (Wed, 09 Aug 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/picture.cc
+
+Removed bounding box fuzz.
+
+------------------------------------------------------------------------
+r1733 | hammera | 2006-08-08 15:41:53 -0600 (Tue, 08 Aug 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/Makefile.in
+ M /trunk/asymptote/entry.cc
+ M /trunk/asymptote/entry.h
+ M /trunk/asymptote/env.h
+ A /trunk/asymptote/envcompleter.cc
+ A /trunk/asymptote/envcompleter.h
+ M /trunk/asymptote/interact.cc
+ M /trunk/asymptote/interact.h
+ A /trunk/asymptote/keywords.pl
+ M /trunk/asymptote/main.cc
+ M /trunk/asymptote/settings.cc
+ M /trunk/asymptote/table.h
+
+Added intelligent readline auto-completion based on the environment.
+
+------------------------------------------------------------------------
+r1732 | jcbowman | 2006-08-08 10:27:34 -0600 (Tue, 08 Aug 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+
+Documented interp.
+
+------------------------------------------------------------------------
+r1731 | jcbowman | 2006-08-08 04:02:56 -0600 (Tue, 08 Aug 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/examples/annotation.asy
+ M /trunk/asymptote/picture.cc
+
+Fixed page alignment.
+
+------------------------------------------------------------------------
+r1730 | jcbowman | 2006-08-07 20:20:15 -0600 (Mon, 07 Aug 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/picture.cc
+
+Added newl after gsave.
+
+------------------------------------------------------------------------
+r1729 | jcbowman | 2006-08-07 14:07:53 -0600 (Mon, 07 Aug 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/env.h
+ M /trunk/asymptote/genv.h
+
+Removed unused code.
+
+------------------------------------------------------------------------
+r1728 | jcbowman | 2006-08-07 09:46:36 -0600 (Mon, 07 Aug 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/runtime.in
+
+Turn off tab completion after readline.
+
+------------------------------------------------------------------------
+r1727 | jcbowman | 2006-08-07 09:36:42 -0600 (Mon, 07 Aug 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/main.cc
+
+Simplified interactive mode.
+
+------------------------------------------------------------------------
+r1726 | jcbowman | 2006-08-07 08:20:46 -0600 (Mon, 07 Aug 2006) | 3 lines
+Changed paths:
+ M /trunk/asymptote/base/plain_picture.asy
+ M /trunk/asymptote/doc/asy.1
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/drawelement.h
+ M /trunk/asymptote/examples/annotation.asy
+ M /trunk/asymptote/picture.cc
+ M /trunk/asymptote/picture.h
+ M /trunk/asymptote/psfile.cc
+ M /trunk/asymptote/psfile.h
+ M /trunk/asymptote/settings.cc
+ M /trunk/asymptote/texfile.cc
+ M /trunk/asymptote/texfile.h
+
+Simplified page alignment: -a Z nolonger implies -notex,
+annotation now works even with negative bounding box coordinates.
+
+------------------------------------------------------------------------
+r1725 | hammera | 2006-08-05 00:03:41 -0600 (Sat, 05 Aug 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/math.asy
+
+Removed accidentally added debugging output.
+
+------------------------------------------------------------------------
+r1724 | hammera | 2006-08-04 23:56:57 -0600 (Fri, 04 Aug 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/math.asy
+
+Fixed horizontal drawline bug.
+
+------------------------------------------------------------------------
+r1723 | jcbowman | 2006-08-03 06:47:03 -0600 (Thu, 03 Aug 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+
+Updated implicit scaling documentation.
+
+------------------------------------------------------------------------
+r1722 | jcbowman | 2006-08-02 13:02:50 -0600 (Wed, 02 Aug 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/stack.cc
+
+Check for interrupts on for(;;).
+
+------------------------------------------------------------------------
+r1721 | jcbowman | 2006-08-02 12:46:17 -0600 (Wed, 02 Aug 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/annotate.asy
+
+Removed unneeded %s.
+
+------------------------------------------------------------------------
+r1720 | jcbowman | 2006-08-02 12:38:03 -0600 (Wed, 02 Aug 2006) | 2 lines
+Changed paths:
+ A /trunk/asymptote/base/annotate.asy
+ M /trunk/asymptote/doc/asymptote.texi
+ A /trunk/asymptote/examples/annotation.asy
+
+Added support for Adobe Reader annotations.
+
+------------------------------------------------------------------------
+r1719 | hammera | 2006-08-01 13:17:50 -0600 (Tue, 01 Aug 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/asy.vim
+
+Improved highlighting of strings and scaling expressions.
+
+------------------------------------------------------------------------
+r1718 | hammera | 2006-08-01 13:16:51 -0600 (Tue, 01 Aug 2006) | 3 lines
+Changed paths:
+ M /trunk/asymptote/camp.y
+
+Allow empty test expression in for loop.
+
+
+------------------------------------------------------------------------
+r1717 | hammera | 2006-08-01 13:16:21 -0600 (Tue, 01 Aug 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/exp.h
+
+Clarified comments.
+
+------------------------------------------------------------------------
+r1716 | jcbowman | 2006-08-01 08:40:11 -0600 (Tue, 01 Aug 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/configure.ac
+
+Incremented version to 1.13svn.
+
+------------------------------------------------------------------------
+r1715 | jcbowman | 2006-08-01 06:46:11 -0600 (Tue, 01 Aug 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/fileio.h
+
+Fix cxx warning messages.
+
+------------------------------------------------------------------------
+r1714 | jcbowman | 2006-08-01 06:32:23 -0600 (Tue, 01 Aug 2006) | 3 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/settings.cc
+
+Use command-line version of ghostscript (gswin32c.exe) under MSDOS to avoid
+spurious ghostscript window when producing pdf files.
+
+------------------------------------------------------------------------
+r1713 | jcbowman | 2006-07-31 14:42:09 -0600 (Mon, 31 Jul 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/TODO
+
+Updated.
+
+------------------------------------------------------------------------
+r1712 | jcbowman | 2006-07-31 14:23:50 -0600 (Mon, 31 Jul 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/pen.h
+
+Simplify pen constructors.
+
+------------------------------------------------------------------------
+r1711 | jcbowman | 2006-07-31 14:12:33 -0600 (Mon, 31 Jul 2006) | 6 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/drawlabel.cc
+ A /trunk/asymptote/examples/transparency.asy
+ M /trunk/asymptote/pen.h
+ M /trunk/asymptote/picture.cc
+ M /trunk/asymptote/psfile.cc
+ M /trunk/asymptote/psfile.h
+ M /trunk/asymptote/runtime.in
+
+Implement transparency.
+
+Handle DEFLINE correctly.
+
+Change string to mem::string throughout pen class.
+
+------------------------------------------------------------------------
+r1710 | jcbowman | 2006-07-31 14:09:15 -0600 (Mon, 31 Jul 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/cylinderskeleton.asy
+
+Use heavygreen instead of green.
+
+------------------------------------------------------------------------
+r1709 | jcbowman | 2006-07-31 14:07:33 -0600 (Mon, 31 Jul 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/slide.asy
+ M /trunk/asymptote/examples/slidedemo.asy
+
+Added equations item.
+
+------------------------------------------------------------------------
+r1708 | hammera | 2006-07-30 00:22:40 -0600 (Sun, 30 Jul 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/exp.cc
+
+Delay call of getName, so that it is only called when the name is used.
+
+------------------------------------------------------------------------
+r1707 | jcbowman | 2006-07-22 13:43:23 -0600 (Sat, 22 Jul 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/drawlabel.cc
+
+Fixed label fuzz.
+
+------------------------------------------------------------------------
+r1706 | jcbowman | 2006-07-22 01:10:50 -0600 (Sat, 22 Jul 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+
+Minor additions to Help section.
+
+------------------------------------------------------------------------
+r1705 | jcbowman | 2006-07-22 01:08:18 -0600 (Sat, 22 Jul 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/drawlabel.cc
+
+Account for scale in label bounding box calculation.
+
+------------------------------------------------------------------------
+r1704 | jcbowman | 2006-07-22 01:07:15 -0600 (Sat, 22 Jul 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/plain.asy
+ M /trunk/asymptote/runtime.in
+
+Renamed interact() to interactive().
+
+------------------------------------------------------------------------
+r1703 | jcbowman | 2006-07-22 01:06:34 -0600 (Sat, 22 Jul 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/graph.asy
+
+Fix Step calculation (special case).
+
+------------------------------------------------------------------------
+r1702 | jcbowman | 2006-07-22 00:59:44 -0600 (Sat, 22 Jul 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/main.cc
+
+Interactive reset should call cleanup, not exitFunction, and set uptodate=true.
+
+------------------------------------------------------------------------
+r1701 | jcbowman | 2006-07-11 15:52:29 -0600 (Tue, 11 Jul 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/INSTALL
+
+Updated.
+
+------------------------------------------------------------------------
+r1700 | jcbowman | 2006-07-11 15:41:51 -0600 (Tue, 11 Jul 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/plain_pens.asy
+
+Added default pen argument to Dotted().
+
+------------------------------------------------------------------------
+r1699 | jcbowman | 2006-07-09 21:16:08 -0600 (Sun, 09 Jul 2006) | 5 lines
+Changed paths:
+ M /trunk/asymptote/arrayop.h
+ M /trunk/asymptote/asymptote.spec
+ M /trunk/asymptote/doc/asy.1
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/errormsg.h
+ M /trunk/asymptote/fileio.h
+ M /trunk/asymptote/runtime.in
+ M /trunk/asymptote/settings.cc
+ M /trunk/asymptote/settings.h
+
+Add q option to scroll facility to allow one to terminate scrolled output
+without causing an execution interrupt.
+
+Make scroll a setting instead of a function call.
+
+------------------------------------------------------------------------
+r1698 | jcbowman | 2006-07-08 22:10:25 -0600 (Sat, 08 Jul 2006) | 2 lines
+Changed paths:
+ D /trunk/asymptote/base/Label.asy
+ D /trunk/asymptote/base/arcs.asy
+ D /trunk/asymptote/base/arrows.asy
+ D /trunk/asymptote/base/boxes.asy
+ D /trunk/asymptote/base/constants.asy
+ D /trunk/asymptote/base/debugger.asy
+ D /trunk/asymptote/base/filldraw.asy
+ D /trunk/asymptote/base/margins.asy
+ D /trunk/asymptote/base/markers.asy
+ D /trunk/asymptote/base/paths.asy
+ D /trunk/asymptote/base/pens.asy
+ D /trunk/asymptote/base/picture.asy
+ M /trunk/asymptote/base/plain.asy
+ A /trunk/asymptote/base/plain_Label.asy (from /trunk/asymptote/base/Label.asy:1690)
+ A /trunk/asymptote/base/plain_arcs.asy (from /trunk/asymptote/base/arcs.asy:1690)
+ A /trunk/asymptote/base/plain_arrows.asy (from /trunk/asymptote/base/arrows.asy:1690)
+ A /trunk/asymptote/base/plain_boxes.asy (from /trunk/asymptote/base/boxes.asy:1690)
+ A /trunk/asymptote/base/plain_constants.asy (from /trunk/asymptote/base/constants.asy:1690)
+ A /trunk/asymptote/base/plain_debugger.asy (from /trunk/asymptote/base/debugger.asy:1690)
+ A /trunk/asymptote/base/plain_filldraw.asy (from /trunk/asymptote/base/filldraw.asy:1690)
+ A /trunk/asymptote/base/plain_margins.asy (from /trunk/asymptote/base/margins.asy:1690)
+ A /trunk/asymptote/base/plain_markers.asy (from /trunk/asymptote/base/markers.asy:1690)
+ A /trunk/asymptote/base/plain_paths.asy (from /trunk/asymptote/base/paths.asy:1690)
+ A /trunk/asymptote/base/plain_pens.asy (from /trunk/asymptote/base/pens.asy:1690)
+ A /trunk/asymptote/base/plain_picture.asy (from /trunk/asymptote/base/picture.asy:1690)
+ A /trunk/asymptote/base/plain_shipout.asy (from /trunk/asymptote/base/shipout.asy:1690)
+ A /trunk/asymptote/base/plain_strings.asy (from /trunk/asymptote/base/strings.asy:1690)
+ D /trunk/asymptote/base/shipout.asy
+ D /trunk/asymptote/base/strings.asy
+ M /trunk/asymptote/doc/asymptote.texi
+
+Added prefix plain_ to internal plain includes.
+
+------------------------------------------------------------------------
+r1697 | jcbowman | 2006-07-07 23:05:42 -0600 (Fri, 07 Jul 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/runtime.in
+
+Add missing clear() function to remove all breakpoints.
+
+------------------------------------------------------------------------
+r1696 | jcbowman | 2006-07-07 23:03:10 -0600 (Fri, 07 Jul 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/math.asy
+
+Simplified partialsum.
+
+------------------------------------------------------------------------
+r1695 | jcbowman | 2006-07-07 11:10:28 -0600 (Fri, 07 Jul 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+
+Removed page break.
+
+------------------------------------------------------------------------
+r1694 | jcbowman | 2006-07-07 11:06:25 -0600 (Fri, 07 Jul 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+
+Documented ellipse.
+
+------------------------------------------------------------------------
+r1693 | jcbowman | 2006-07-07 10:41:38 -0600 (Fri, 07 Jul 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/doc/bezier2.asy
+
+Moved "Drawing Commands" section to immediately follow tutorial.
+
+------------------------------------------------------------------------
+r1692 | jcbowman | 2006-07-06 16:30:18 -0600 (Thu, 06 Jul 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+
+Minor documentation improvements.
+
+------------------------------------------------------------------------
+r1691 | jcbowman | 2006-07-06 16:17:13 -0600 (Thu, 06 Jul 2006) | 4 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/doc/bezier.asy
+ M /trunk/asymptote/doc/bezier2.asy
+ M /trunk/asymptote/runtime.in
+
+Fixed documentation of periodic tridiagonal solver.
+
+Minor edits to Bezier curve documentation.
+
+------------------------------------------------------------------------
+r1690 | rmarinov | 2006-07-06 14:05:53 -0600 (Thu, 06 Jul 2006) | 1 line
+Changed paths:
+ A /trunk/asymptote/doc/bezier2.asy
+
+Added a bezier curves example - /doc/bezier2.asy .
+------------------------------------------------------------------------
+r1689 | jcbowman | 2006-07-06 10:55:47 -0600 (Thu, 06 Jul 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.sty
+
+Replace double quotes with single quotes for compatibility with \usepackage{german}.
+
+------------------------------------------------------------------------
+r1688 | rmarinov | 2006-07-06 10:55:47 -0600 (Thu, 06 Jul 2006) | 1 line
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+
+Added some more information on Bezier curves.
+------------------------------------------------------------------------
+r1687 | jcbowman | 2006-07-06 01:05:00 -0600 (Thu, 06 Jul 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/configure.ac
+
+Incremented version to 1.12svn.
+
+------------------------------------------------------------------------
+r1686 | jcbowman | 2006-07-06 00:10:14 -0600 (Thu, 06 Jul 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/stack.cc
+
+Support g++ 3.3.4.
+
+------------------------------------------------------------------------
+r1685 | jcbowman | 2006-07-05 23:53:55 -0600 (Wed, 05 Jul 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/asymptote.spec
+ M /trunk/asymptote/runtime.in
+ M /trunk/asymptote/stack.cc
+
+Fixed cxx warning messages.
+
+------------------------------------------------------------------------
+r1684 | jcbowman | 2006-07-05 22:39:14 -0600 (Wed, 05 Jul 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+
+Added reference to graph3.
+
+------------------------------------------------------------------------
+r1683 | jcbowman | 2006-07-05 12:28:58 -0600 (Wed, 05 Jul 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/debugger.asy
+ M /trunk/asymptote/runtime.in
+
+Renamed locate to locatefile.
+
+------------------------------------------------------------------------
+r1682 | jcbowman | 2006-07-05 01:15:18 -0600 (Wed, 05 Jul 2006) | 8 lines
+Changed paths:
+ M /trunk/asymptote/base/constants.asy
+ M /trunk/asymptote/base/debugger.asy
+ M /trunk/asymptote/base/picture.asy
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/errormsg.h
+ M /trunk/asymptote/main.cc
+ M /trunk/asymptote/runtime.in
+ M /trunk/asymptote/stack.cc
+ M /trunk/asymptote/stack.h
+ M /trunk/asymptote/types.h
+
+Debugger enhancements and minor fixes, including conditional breakpoints;
+renamed remove(string, int) to clear(string, int).
+
+Define min(... int[] a) and max(... int[] a).
+
+Moved realmult to runtime.
+
+
+------------------------------------------------------------------------
+r1681 | jcbowman | 2006-07-01 03:05:34 -0600 (Sat, 01 Jul 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/debugger.asy
+
+Removed spurious write.
+
+------------------------------------------------------------------------
+r1680 | jcbowman | 2006-07-01 03:03:41 -0600 (Sat, 01 Jul 2006) | 4 lines
+Changed paths:
+ M /trunk/asymptote/base/debugger.asy
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/errormsg.cc
+ M /trunk/asymptote/fileio.cc
+ M /trunk/asymptote/fileio.h
+ M /trunk/asymptote/runtime.in
+ M /trunk/asymptote/settings.cc
+ M /trunk/asymptote/stack.cc
+ M /trunk/asymptote/stack.h
+
+Simplified debugger: removed step, renamed line to step, and make trace toggle.
+
+Prune duplicate trace messages.
+
+------------------------------------------------------------------------
+r1679 | jcbowman | 2006-07-01 01:20:21 -0600 (Sat, 01 Jul 2006) | 6 lines
+Changed paths:
+ M /trunk/asymptote/base/animate.asy
+ M /trunk/asymptote/base/pens.asy
+ M /trunk/asymptote/base/picture.asy
+ M /trunk/asymptote/base/plain.asy
+ M /trunk/asymptote/base/shipout.asy
+ M /trunk/asymptote/base/slide.asy
+ M /trunk/asymptote/doc/asy.1
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/examples/animations/embeddedmovie.asy
+ M /trunk/asymptote/examples/animations/wheel.asy
+ M /trunk/asymptote/examples/slidedemo.asy
+ M /trunk/asymptote/picture.cc
+ M /trunk/asymptote/settings.cc
+
+Make access settings global.
+
+Added twice setting to resolve LaTeX references.
+
+Improve embedded movie example.
+
+------------------------------------------------------------------------
+r1678 | jcbowman | 2006-06-30 11:09:49 -0600 (Fri, 30 Jun 2006) | 4 lines
+Changed paths:
+ M /trunk/asymptote/examples/animations/embeddedmovie.asy
+ M /trunk/asymptote/runtime.in
+
+Generate wheel.mpg.
+
+Suppress vbv_delay overflow messages during mpeg merge.
+
+------------------------------------------------------------------------
+r1677 | jcbowman | 2006-06-30 10:34:52 -0600 (Fri, 30 Jun 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/graph.asy
+ M /trunk/asymptote/base/markers.asy
+
+Use defaultformat again instead of empty format string.
+
+------------------------------------------------------------------------
+r1676 | jcbowman | 2006-06-30 10:27:19 -0600 (Fri, 30 Jun 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+
+Improve discussion of stack overflow detection.
+
+------------------------------------------------------------------------
+r1675 | jcbowman | 2006-06-30 08:35:14 -0600 (Fri, 30 Jun 2006) | 2 lines
+Changed paths:
+ A /trunk/asymptote/examples/animations/embeddedmovie.asy
+
+Added missing file.
+
+------------------------------------------------------------------------
+r1674 | jcbowman | 2006-06-29 22:54:03 -0600 (Thu, 29 Jun 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/builtin.cc
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/runtime.in
+
+Added 3D array transpose and copy.
+
+------------------------------------------------------------------------
+r1673 | jcbowman | 2006-06-29 22:37:03 -0600 (Thu, 29 Jun 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/main.cc
+
+Prevent runtime errors and interrupts from resetting interactive environment.
+
+------------------------------------------------------------------------
+r1672 | jcbowman | 2006-06-29 22:35:10 -0600 (Thu, 29 Jun 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/arrayop.h
+
+Removed extra blank line at end of 3D array write.
+
+------------------------------------------------------------------------
+r1671 | jcbowman | 2006-06-29 17:10:05 -0600 (Thu, 29 Jun 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/asy.1
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/interact.cc
+ M /trunk/asymptote/settings.cc
+
+Moved introductory material into Tutorial section.
+
+------------------------------------------------------------------------
+r1670 | jcbowman | 2006-06-29 11:37:38 -0600 (Thu, 29 Jun 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/asymptote.py
+ M /trunk/asymptote/doc/asy.1
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/interact.cc
+ M /trunk/asymptote/main.cc
+
+Added prompt and quiet settings.
+
+------------------------------------------------------------------------
+r1669 | jcbowman | 2006-06-29 06:20:33 -0600 (Thu, 29 Jun 2006) | 3 lines
+Changed paths:
+ M /trunk/asymptote/main.cc
+
+Don't exit if stack overflow or segmentation fault handlers fail (to
+workaround broken libsigsegv-2.3; upgrading to libsigsegv-2.4 is recommended).
+
+------------------------------------------------------------------------
+r1668 | jcbowman | 2006-06-28 21:59:26 -0600 (Wed, 28 Jun 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+
+Renamed Examples section to Tutorial.
+
+------------------------------------------------------------------------
+r1667 | jcbowman | 2006-06-28 12:40:09 -0600 (Wed, 28 Jun 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/debugger.asy
+
+Removed unused line.
+
+------------------------------------------------------------------------
+r1666 | jcbowman | 2006-06-28 12:38:09 -0600 (Wed, 28 Jun 2006) | 10 lines
+Changed paths:
+ A /trunk/asymptote/base/debugger.asy
+ M /trunk/asymptote/base/plain.asy
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/runtime.in
+
+Moved debugger into separate base file debugger.asy.
+
+Added void stop(string file, string text); to stop at the first line in
+file containing the string text.
+
+Renamed q (quit) debugger command to x (exit); added q (quit) command that
+quits debugger and ends execution.
+
+Better fix for memory leak.
+
+------------------------------------------------------------------------
+r1665 | jcbowman | 2006-06-28 10:59:27 -0600 (Wed, 28 Jun 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+
+Minor documentation updates.
+
+------------------------------------------------------------------------
+r1664 | hammera | 2006-06-28 01:24:15 -0600 (Wed, 28 Jun 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/three.asy
+
+Ensured that the basis in lookAt() is orthonormal.
+
+------------------------------------------------------------------------
+r1663 | jcbowman | 2006-06-28 00:35:12 -0600 (Wed, 28 Jun 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/configure.ac
+
+Incremented version to 1.11svn.
+
+------------------------------------------------------------------------
+r1662 | jcbowman | 2006-06-28 00:03:25 -0600 (Wed, 28 Jun 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/picture.cc
+ M /trunk/asymptote/util.cc
+ M /trunk/asymptote/util.h
+
+Add support for spaces in Asymptote and output filenames.
+
+------------------------------------------------------------------------
+r1661 | jcbowman | 2006-06-27 22:51:10 -0600 (Tue, 27 Jun 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/picture.cc
+
+Added more quotes.
+
+------------------------------------------------------------------------
+r1660 | jcbowman | 2006-06-27 22:44:55 -0600 (Tue, 27 Jun 2006) | 4 lines
+Changed paths:
+ M /trunk/asymptote/picture.cc
+ M /trunk/asymptote/runtime.in
+ M /trunk/asymptote/util.cc
+
+Add more quotes for MSDOS users who like to use spaces in filenames.
+
+Remove quotes in diagnostic messages.
+
+------------------------------------------------------------------------
+r1659 | jcbowman | 2006-06-27 13:30:09 -0600 (Tue, 27 Jun 2006) | 4 lines
+Changed paths:
+ M /trunk/asymptote/base/plain.asy
+
+Cache source code in debugger.
+
+Move debugger help message to immediately before prompt.
+
+------------------------------------------------------------------------
+r1658 | jcbowman | 2006-06-27 12:42:03 -0600 (Tue, 27 Jun 2006) | 4 lines
+Changed paths:
+ M /trunk/asymptote/base/plain.asy
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/fileio.cc
+ M /trunk/asymptote/fileio.h
+ M /trunk/asymptote/stack.cc
+ M /trunk/asymptote/stack.h
+
+Extended and documented debugger.
+
+Fixed string reads of lines containing only whitespace.
+
+------------------------------------------------------------------------
+r1657 | jcbowman | 2006-06-27 01:47:31 -0600 (Tue, 27 Jun 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/errorbars.asy
+
+Fix drawpen.
+
+------------------------------------------------------------------------
+r1656 | jcbowman | 2006-06-27 01:45:40 -0600 (Tue, 27 Jun 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/filldraw.asy
+ M /trunk/asymptote/base/picture.asy
+ M /trunk/asymptote/doc/asymptote.texi
+
+Make default drawpen currentpen again.
+
+------------------------------------------------------------------------
+r1655 | jcbowman | 2006-06-27 01:31:48 -0600 (Tue, 27 Jun 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/plain.asy
+ M /trunk/asymptote/runtime.in
+ M /trunk/asymptote/stack.cc
+
+Work around atbreakpoint memory leak.
+
+------------------------------------------------------------------------
+r1654 | jcbowman | 2006-06-26 23:25:54 -0600 (Mon, 26 Jun 2006) | 4 lines
+Changed paths:
+ M /trunk/asymptote/base/filldraw.asy
+ M /trunk/asymptote/base/markers.asy
+ M /trunk/asymptote/base/picture.asy
+ M /trunk/asymptote/doc/advection.asy
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/doc/contour1.asy
+ M /trunk/asymptote/doc/contour2.asy
+ M /trunk/asymptote/doc/errorbars.asy
+ M /trunk/asymptote/examples/dimension.asy
+
+Make Fill and FillDraw work with markers and superpaths.
+
+Minor formatting updates.
+
+------------------------------------------------------------------------
+r1653 | jcbowman | 2006-06-26 22:23:17 -0600 (Mon, 26 Jun 2006) | 4 lines
+Changed paths:
+ M /trunk/asymptote/main.cc
+ M /trunk/asymptote/util.cc
+
+Suppress all errors when quiet=2.
+
+Catch handled_error in configuration files.
+
+------------------------------------------------------------------------
+r1652 | jcbowman | 2006-06-26 21:14:44 -0600 (Mon, 26 Jun 2006) | 4 lines
+Changed paths:
+ M /trunk/asymptote/base/graph3.asy
+ M /trunk/asymptote/doc/asymptote.texi
+ A /trunk/asymptote/examples/parametricsurface.asy
+
+Added parametric surface example.
+
+Distinguish between distances in front of and behind camera.
+
+------------------------------------------------------------------------
+r1651 | cmsavage | 2006-06-26 18:02:59 -0600 (Mon, 26 Jun 2006) | 1 line
+Changed paths:
+ M /trunk/asymptote/base/graph3.asy
+ M /trunk/asymptote/doc/asymptote.texi
+
+Implemented parametric surfaces. Surface fill/mesh is no longer drawn for nullpen arguments.
+------------------------------------------------------------------------
+r1650 | jcbowman | 2006-06-26 16:04:47 -0600 (Mon, 26 Jun 2006) | 4 lines
+Changed paths:
+ D /trunk/asymptote/base/debugger.asy
+ M /trunk/asymptote/base/plain.asy
+ M /trunk/asymptote/runtime.in
+ M /trunk/asymptote/stack.cc
+
+Fixed segmentation fault if atbreakpoint isn't defined.
+
+Moved debugger.asy into plain.asy.
+
+------------------------------------------------------------------------
+r1649 | jcbowman | 2006-06-26 02:02:39 -0600 (Mon, 26 Jun 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/stack.cc
+
+Support compilation under g++-3.3.4.
+
+------------------------------------------------------------------------
+r1648 | jcbowman | 2006-06-26 01:18:44 -0600 (Mon, 26 Jun 2006) | 2 lines
+Changed paths:
+ A /trunk/asymptote/base/debugger.asy
+ M /trunk/asymptote/errormsg.h
+ M /trunk/asymptote/runtime.in
+ M /trunk/asymptote/stack.cc
+ M /trunk/asymptote/stack.h
+ M /trunk/asymptote/types.h
+ M /trunk/asymptote/util.cc
+
+Debugger support.
+
+------------------------------------------------------------------------
+r1647 | jcbowman | 2006-06-25 22:13:21 -0600 (Sun, 25 Jun 2006) | 4 lines
+Changed paths:
+ M /trunk/asymptote/asymptote.spec
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/errormsg.cc
+ M /trunk/asymptote/errormsg.h
+ M /trunk/asymptote/main.cc
+ M /trunk/asymptote/runtime.in
+ M /trunk/asymptote/stack.cc
+ M /trunk/asymptote/stack.h
+
+Implement rudimentary debugger.
+
+Fix interrupts.
+
+------------------------------------------------------------------------
+r1646 | jcbowman | 2006-06-25 22:10:58 -0600 (Sun, 25 Jun 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/settings.cc
+
+Suppress stderr for gv workaround.
+
+------------------------------------------------------------------------
+r1645 | jcbowman | 2006-06-25 22:10:14 -0600 (Sun, 25 Jun 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/interact.cc
+ M /trunk/asymptote/picture.cc
+ M /trunk/asymptote/pipestream.h
+ M /trunk/asymptote/util.cc
+ M /trunk/asymptote/util.h
+
+Suppress stderr only for gv workaround.
+
+------------------------------------------------------------------------
+r1644 | jcbowman | 2006-06-25 19:20:24 -0600 (Sun, 25 Jun 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/util.cc
+
+Work around file descriptor problem with MikTeX 2.5.
+
+------------------------------------------------------------------------
+r1643 | jcbowman | 2006-06-23 21:03:52 -0600 (Fri, 23 Jun 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/parametricgraph.asy
+
+Added Crop argument.
+
+------------------------------------------------------------------------
+r1642 | jcbowman | 2006-06-23 21:02:52 -0600 (Fri, 23 Jun 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/configure.ac
+
+Added autoconf > 2.59 patch submitted by Chris.
+
+------------------------------------------------------------------------
+r1641 | cmsavage | 2006-06-23 18:06:33 -0600 (Fri, 23 Jun 2006) | 1 line
+Changed paths:
+ M /trunk/asymptote/base/graph.asy
+
+Added crop argument to limits to match xlimits.
+------------------------------------------------------------------------
+r1640 | cmsavage | 2006-06-23 18:04:34 -0600 (Fri, 23 Jun 2006) | 1 line
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+
+Corrected default crop argument of xlimits.
+------------------------------------------------------------------------
+r1639 | cmsavage | 2006-06-23 17:08:52 -0600 (Fri, 23 Jun 2006) | 1 line
+Changed paths:
+ M /trunk/asymptote/base/graph.asy
+ M /trunk/asymptote/doc/asymptote.texi
+
+Added picture argument and use of picture scaling to graph(...) functions that did not previously do this.
+------------------------------------------------------------------------
+r1638 | jcbowman | 2006-06-23 06:12:58 -0600 (Fri, 23 Jun 2006) | 6 lines
+Changed paths:
+ M /trunk/asymptote/LICENSE
+ M /trunk/asymptote/Makefile.in
+ M /trunk/asymptote/README
+ M /trunk/asymptote/configure.ac
+ M /trunk/asymptote/examples/elliptic.asy
+
+Changed Docdir to docdir; hopefully this won't conflict with next release
+of autoconf.
+
+Replaced GPL LICENSE with newer version (FSF forgot to bump the version
+number!).
+
+------------------------------------------------------------------------
+r1637 | jcbowman | 2006-06-22 16:35:05 -0600 (Thu, 22 Jun 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/asymptote.spec
+ M /trunk/asymptote/configure.ac
+
+Incremented version to 1.10svn.
+
+------------------------------------------------------------------------
+r1636 | jcbowman | 2006-06-22 13:52:31 -0600 (Thu, 22 Jun 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/settings.cc
+ M /trunk/asymptote/util.cc
+
+Make gv-3.6.1 bug workaround work with older versions like gv-3.5.8.
+
+------------------------------------------------------------------------
+r1635 | jcbowman | 2006-06-22 00:19:45 -0600 (Thu, 22 Jun 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/settings.cc
+
+Updated to MSDOS gs8.54.
+
+------------------------------------------------------------------------
+r1634 | jcbowman | 2006-06-22 00:18:51 -0600 (Thu, 22 Jun 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/configure.ac
+
+Incremented version to 1.09svn.
+
+------------------------------------------------------------------------
+r1633 | jcbowman | 2006-06-21 22:36:17 -0600 (Wed, 21 Jun 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/asymptote.spec
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/doc/triangulate.asy
+
+Documented int[][] triangulate(pair[] z); for creating a triangular mesh.
+
+------------------------------------------------------------------------
+r1632 | jcbowman | 2006-06-21 21:46:43 -0600 (Wed, 21 Jun 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/Makefile.in
+
+Fixed make distclean.
+
+------------------------------------------------------------------------
+r1631 | jcbowman | 2006-06-21 21:15:32 -0600 (Wed, 21 Jun 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/Makefile.in
+ M /trunk/asymptote/tests/Makefile
+
+Clean up unneeded files.
+
+------------------------------------------------------------------------
+r1630 | jcbowman | 2006-06-21 18:13:50 -0600 (Wed, 21 Jun 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/runtime.in
+
+Fixed warning messages.
+
+------------------------------------------------------------------------
+r1629 | jcbowman | 2006-06-21 16:41:19 -0600 (Wed, 21 Jun 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/Label.asy
+ M /trunk/asymptote/base/arrows.asy
+ M /trunk/asymptote/base/constants.asy
+ M /trunk/asymptote/base/contour.asy
+ M /trunk/asymptote/base/drawtree.asy
+ M /trunk/asymptote/base/featpost3D.asy
+ M /trunk/asymptote/base/feynman.asy
+ M /trunk/asymptote/base/filldraw.asy
+ M /trunk/asymptote/base/flowchart.asy
+ M /trunk/asymptote/base/geometry.asy
+ M /trunk/asymptote/base/graph.asy
+ M /trunk/asymptote/base/graph3.asy
+ M /trunk/asymptote/base/light.asy
+ M /trunk/asymptote/base/margins.asy
+ M /trunk/asymptote/base/markers.asy
+ M /trunk/asymptote/base/metapost.asy
+ M /trunk/asymptote/base/paths.asy
+ M /trunk/asymptote/base/patterns.asy
+ M /trunk/asymptote/base/pens.asy
+ M /trunk/asymptote/base/picture.asy
+ M /trunk/asymptote/base/plain.asy
+ M /trunk/asymptote/base/pstoedit.asy
+ M /trunk/asymptote/base/shipout.asy
+ M /trunk/asymptote/base/simplex.asy
+ M /trunk/asymptote/base/slide.asy
+ M /trunk/asymptote/base/slopefield.asy
+ M /trunk/asymptote/base/solids.asy
+ M /trunk/asymptote/base/stats.asy
+ M /trunk/asymptote/base/three.asy
+ M /trunk/asymptote/base/tree.asy
+
+Removed unneeded public modifiers.
+
+------------------------------------------------------------------------
+r1628 | jcbowman | 2006-06-21 16:35:07 -0600 (Wed, 21 Jun 2006) | 7 lines
+Changed paths:
+ M /trunk/asymptote/base/slide.asy
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/examples/slidedemo.asy
+ M /trunk/asymptote/pen.h
+ M /trunk/asymptote/runtime.in
+
+Added pen colorless(pen) function that strips pen color attributes (useful for
+avoiding color mixing).
+
+Fixed stepping bugs in slide on overfull slide; added institution field to
+titlepage.
+
+
+------------------------------------------------------------------------
+r1627 | jcbowman | 2006-06-20 21:40:06 -0600 (Tue, 20 Jun 2006) | 6 lines
+Changed paths:
+ M /trunk/asymptote/configure.ac
+
+Removed AC_FUNC_MALLOC and AC_FUNC_REALLOC as they seem to cause more
+problems than they solve.
+
+Fix help command by reverting broken Docdir change.
+
+
+------------------------------------------------------------------------
+r1626 | jcbowman | 2006-06-20 13:12:52 -0600 (Tue, 20 Jun 2006) | 4 lines
+Changed paths:
+ M /trunk/asymptote/base/contour.asy
+
+Increased epsilon to fix corner cases.
+
+Suppress null labels.
+
+------------------------------------------------------------------------
+r1625 | jcbowman | 2006-06-18 22:32:31 -0600 (Sun, 18 Jun 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/configure.ac
+
+Incremented version to 1.08svn.
+
+------------------------------------------------------------------------
+r1624 | jcbowman | 2006-06-18 21:34:40 -0600 (Sun, 18 Jun 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/settings.cc
+
+Fixed gv workaround.
+
+------------------------------------------------------------------------
+r1623 | jcbowman | 2006-06-18 20:51:25 -0600 (Sun, 18 Jun 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/configure.ac
+ M /trunk/asymptote/runtime.in
+ M /trunk/asymptote/util.h
+
+Fix cygwin build problems.
+
+------------------------------------------------------------------------
+r1622 | jcbowman | 2006-06-18 10:39:54 -0600 (Sun, 18 Jun 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/contour.asy
+ M /trunk/asymptote/base/slopefield.asy
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/doc/contour2.asy
+ M /trunk/asymptote/doc/logimage.asy
+
+Add and document contour labels.
+
+------------------------------------------------------------------------
+r1621 | jcbowman | 2006-06-18 01:37:48 -0600 (Sun, 18 Jun 2006) | 4 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/examples/laserlattice.asy
+
+Updated documentation regarding type-dependent array functions.
+
+Fixed example.
+
+------------------------------------------------------------------------
+r1620 | jcbowman | 2006-06-18 01:24:06 -0600 (Sun, 18 Jun 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+ A /trunk/asymptote/doc/imagecontour.asy
+
+Add imagecontour example.
+
+------------------------------------------------------------------------
+r1619 | jcbowman | 2006-06-18 01:03:23 -0600 (Sun, 18 Jun 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/graph.asy
+ M /trunk/asymptote/base/palette.asy
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/doc/image.asy
+ A /trunk/asymptote/doc/logimage.asy
+ D /trunk/asymptote/doc/mosquito.asy
+ A /trunk/asymptote/examples/mosquito.asy
+ M /trunk/asymptote/runtime.in
+
+Add improved and simplified version of Chris' palette modifications.
+
+------------------------------------------------------------------------
+r1618 | jcbowman | 2006-06-17 16:53:00 -0600 (Sat, 17 Jun 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/arrows.asy
+
+Fixed arcarrowsize.
+
+------------------------------------------------------------------------
+r1617 | jcbowman | 2006-06-17 16:49:51 -0600 (Sat, 17 Jun 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/math.asy
+ M /trunk/asymptote/runtime.in
+ M /trunk/asymptote/tests/TestLib.asy
+ M /trunk/asymptote/tests/array/determinant.asy
+ M /trunk/asymptote/tests/array/solve.asy
+
+Fixed and simplified LU decomposition, solve, and determinant.
+
+------------------------------------------------------------------------
+r1616 | jcbowman | 2006-06-17 04:56:37 -0600 (Sat, 17 Jun 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/tests/array/solve.asy
+
+Simplified test.
+
+------------------------------------------------------------------------
+r1615 | jcbowman | 2006-06-16 20:09:40 -0600 (Fri, 16 Jun 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/math.asy
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/doc/logo.asy
+ M /trunk/asymptote/runtime.in
+ M /trunk/asymptote/tests/array/solve.asy
+
+Optimized solve and inverse.
+
+------------------------------------------------------------------------
+r1614 | rmarinov | 2006-06-16 14:01:41 -0600 (Fri, 16 Jun 2006) | 1 line
+Changed paths:
+ M /trunk/asymptote/runtime.in
+ A /trunk/asymptote/tests/array/solve.asy
+
+Added LU decomposition instead of Gauss-Seidel method in solve. Gauss-Seidel method is still used for finding inverses. Added a test for both.
+------------------------------------------------------------------------
+r1613 | jcbowman | 2006-06-15 16:33:32 -0600 (Thu, 15 Jun 2006) | 4 lines
+Changed paths:
+ M /trunk/asymptote/base/arrows.asy
+ M /trunk/asymptote/base/constants.asy
+ M /trunk/asymptote/base/filldraw.asy
+ M /trunk/asymptote/base/markers.asy
+ M /trunk/asymptote/base/pens.asy
+ M /trunk/asymptote/base/picture.asy
+ M /trunk/asymptote/doc/asymptote.texi
+
+Renamed Fill filltype to FillDraw and added Fill filltype that only does a fill.
+
+Fixed arrowsize capping code and added arrowsizelimit.
+
+------------------------------------------------------------------------
+r1612 | jcbowman | 2006-06-15 14:41:13 -0600 (Thu, 15 Jun 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/builtin.cc
+ M /trunk/asymptote/camp.l
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/entry.cc
+ M /trunk/asymptote/modifier.h
+
+Renamed readable to restricted.
+
+------------------------------------------------------------------------
+r1611 | jcbowman | 2006-06-14 15:55:06 -0600 (Wed, 14 Jun 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/logo.asy
+
+Fine-tune logo.
+
+------------------------------------------------------------------------
+r1610 | jcbowman | 2006-06-14 00:15:22 -0600 (Wed, 14 Jun 2006) | 4 lines
+Changed paths:
+ M /trunk/asymptote/base/palette.asy
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/doc/flowchartdemo.asy
+
+Change defaultformat argument of PaletteTicks to "".
+
+Fix formatting issues.
+
+------------------------------------------------------------------------
+r1609 | hammera | 2006-06-13 17:23:58 -0600 (Tue, 13 Jun 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/TODO
+ M /trunk/asymptote/base/asy.vim
+ M /trunk/asymptote/builtin.cc
+ M /trunk/asymptote/camp.l
+ M /trunk/asymptote/camp.y
+ M /trunk/asymptote/coder.cc
+ M /trunk/asymptote/coder.h
+ M /trunk/asymptote/dec.cc
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/entry.cc
+ M /trunk/asymptote/modifier.h
+
+Added readable keyword, made public the default permission.
+
+------------------------------------------------------------------------
+r1608 | rmarinov | 2006-06-13 14:49:16 -0600 (Tue, 13 Jun 2006) | 1 line
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+
+Updated documentation for contours.
+------------------------------------------------------------------------
+r1607 | jcbowman | 2006-06-13 13:14:18 -0600 (Tue, 13 Jun 2006) | 6 lines
+Changed paths:
+ M /trunk/asymptote/Delaunay.cc
+ M /trunk/asymptote/Delaunay.h
+ M /trunk/asymptote/base/contour.asy
+ M /trunk/asymptote/base/pens.asy
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/doc/contour1.asy
+ M /trunk/asymptote/doc/contour2.asy
+ A /trunk/asymptote/doc/contour3.asy
+ A /trunk/asymptote/doc/triangulate.asy
+ M /trunk/asymptote/runtime.in
+
+Optimized postsorting of triangulate routine.
+
+Simplified contour interface.
+
+Added nonuniform contour mesh example.
+
+------------------------------------------------------------------------
+r1606 | jcbowman | 2006-06-13 12:34:14 -0600 (Tue, 13 Jun 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/arrows.asy
+
+Make arrowhead and arrowheadbbox public to allow them to be overloaded.
+
+------------------------------------------------------------------------
+r1605 | rmarinov | 2006-06-13 11:10:27 -0600 (Tue, 13 Jun 2006) | 1 line
+Changed paths:
+ M /trunk/asymptote/base/contour.asy
+ M /trunk/asymptote/runtime.in
+
+Added non-regularly spaced contouring.
+------------------------------------------------------------------------
+r1604 | jcbowman | 2006-06-13 01:00:48 -0600 (Tue, 13 Jun 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/drawlabel.cc
+
+Use random pair for overwrite moves when align=(0,0).
+
+------------------------------------------------------------------------
+r1603 | jcbowman | 2006-06-13 00:59:12 -0600 (Tue, 13 Jun 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/contour.asy
+ M /trunk/asymptote/base/plain.asy
+ M /trunk/asymptote/base/three.asy
+ M /trunk/asymptote/doc/contour1.asy
+ M /trunk/asymptote/doc/contour2.asy
+
+Formatting.
+
+------------------------------------------------------------------------
+r1602 | jcbowman | 2006-06-13 00:54:17 -0600 (Tue, 13 Jun 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/graph.asy
+
+Fixed secondary logarithmic axes.
+
+------------------------------------------------------------------------
+r1601 | jcbowman | 2006-06-13 00:34:56 -0600 (Tue, 13 Jun 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/graph.asy
+
+Fixed count computation (for endlabel=false).
+
+------------------------------------------------------------------------
+r1600 | jcbowman | 2006-06-13 00:25:17 -0600 (Tue, 13 Jun 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/graph.asy
+
+Fixed alignment of rotated tick labels.
+
+------------------------------------------------------------------------
+r1599 | jcbowman | 2006-06-12 22:37:10 -0600 (Mon, 12 Jun 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/contour.asy
+
+Implemented more efficient guide collection algorithm.
+
+------------------------------------------------------------------------
+r1598 | jcbowman | 2006-06-12 20:33:17 -0600 (Mon, 12 Jun 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/runtime.in
+
+Added string option to assert.
+
+------------------------------------------------------------------------
+r1597 | jcbowman | 2006-06-12 20:30:55 -0600 (Mon, 12 Jun 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/dec.cc
+
+Standardize "could not load module" error message.
+
+------------------------------------------------------------------------
+r1596 | jcbowman | 2006-06-12 20:29:02 -0600 (Mon, 12 Jun 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/errormsg.h
+ M /trunk/asymptote/stack.cc
+
+Use most up-to-date verbose setting for traceback.
+
+------------------------------------------------------------------------
+r1595 | rmarinov | 2006-06-12 10:23:59 -0600 (Mon, 12 Jun 2006) | 1 line
+Changed paths:
+ M /trunk/asymptote/Delaunay.h
+ M /trunk/asymptote/runtime.in
+
+Removed copying of unused variable in triangulation routine.
+------------------------------------------------------------------------
+r1594 | jcbowman | 2006-06-11 14:05:28 -0600 (Sun, 11 Jun 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/Delaunay.cc
+ M /trunk/asymptote/Delaunay.h
+
+Removed executable flag.
+
+------------------------------------------------------------------------
+r1593 | jcbowman | 2006-06-10 15:45:17 -0600 (Sat, 10 Jun 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/solids.asy
+
+Make currentprojection public.
+
+------------------------------------------------------------------------
+r1592 | jcbowman | 2006-06-10 15:42:22 -0600 (Sat, 10 Jun 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/graph3.asy
+ M /trunk/asymptote/base/light.asy
+ M /trunk/asymptote/base/solids.asy
+
+Import three as public so that currentprojection can be overridden.
+
+------------------------------------------------------------------------
+r1591 | hammera | 2006-06-10 13:55:29 -0600 (Sat, 10 Jun 2006) | 5 lines
+Changed paths:
+ M /trunk/asymptote/base/plain.asy
+ M /trunk/asymptote/base/three.asy
+
+Added addSaveFunction to extend save and restore.
+Moved projection code to three.asy.
+Handle degenerate cases in lookAt().
+
+
+------------------------------------------------------------------------
+r1590 | hammera | 2006-06-10 13:51:57 -0600 (Sat, 10 Jun 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+
+Noted built-in modules.
+
+------------------------------------------------------------------------
+r1589 | jcbowman | 2006-06-09 22:16:41 -0600 (Fri, 09 Jun 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/three.asy
+
+Removed unused subtraction.
+
+------------------------------------------------------------------------
+r1588 | jcbowman | 2006-06-09 22:05:53 -0600 (Fri, 09 Jun 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/three.asy
+
+Fix overhead/underhead views.
+
+------------------------------------------------------------------------
+r1587 | jcbowman | 2006-06-09 16:49:33 -0600 (Fri, 09 Jun 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/three.asy
+
+Added up argument to lookAt; remove lookAtOrigin in favour of lookAt(O,...).
+
+------------------------------------------------------------------------
+r1586 | jcbowman | 2006-06-09 12:21:26 -0600 (Fri, 09 Jun 2006) | 4 lines
+Changed paths:
+ M /trunk/asymptote/base/plain.asy
+ M /trunk/asymptote/base/three.asy
+ M /trunk/asymptote/doc/axis3.asy
+
+Simply support for custom projections.
+
+Reverse arguments of lookAt for clarity.
+
+------------------------------------------------------------------------
+r1585 | rmarinov | 2006-06-08 13:49:56 -0600 (Thu, 08 Jun 2006) | 1 line
+Changed paths:
+ M /trunk/asymptote/Delaunay.cc
+ M /trunk/asymptote/Delaunay.h
+ M /trunk/asymptote/runtime.in
+
+Fixed a problem with triangulation.
+------------------------------------------------------------------------
+r1584 | jcbowman | 2006-06-07 21:41:09 -0600 (Wed, 07 Jun 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+
+Fixed typo in configuration instructions.
+
+------------------------------------------------------------------------
+r1583 | jcbowman | 2006-06-07 17:00:16 -0600 (Wed, 07 Jun 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/Makefile.in
+
+Add Delaunay.
+
+------------------------------------------------------------------------
+r1582 | jcbowman | 2006-06-07 16:58:54 -0600 (Wed, 07 Jun 2006) | 4 lines
+Changed paths:
+ A /trunk/asymptote/Delaunay.cc
+ A /trunk/asymptote/Delaunay.h
+ M /trunk/asymptote/runtime.in
+
+Added Paul Bourke's Delaunay triangulation routine.
+
+Removed unneeded copyArray from inside.
+
+------------------------------------------------------------------------
+r1581 | jcbowman | 2006-06-07 14:22:18 -0600 (Wed, 07 Jun 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/solids.asy
+
+Fixed typo regarding cone vertex.
+
+------------------------------------------------------------------------
+r1580 | jcbowman | 2006-06-07 14:02:03 -0600 (Wed, 07 Jun 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/configure.ac
+ M /trunk/asymptote/doc/Makefile
+
+Fix configuration problems.
+
+------------------------------------------------------------------------
+r1579 | jcbowman | 2006-06-07 03:25:06 -0600 (Wed, 07 Jun 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/Makefile.in
+
+Remove docdir.
+
+------------------------------------------------------------------------
+r1578 | jcbowman | 2006-06-07 03:10:45 -0600 (Wed, 07 Jun 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/Makefile.in
+
+Remove unused docdir operations.
+
+------------------------------------------------------------------------
+r1577 | jcbowman | 2006-06-07 03:05:30 -0600 (Wed, 07 Jun 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/picture.cc
+ M /trunk/asymptote/settings.cc
+ M /trunk/asymptote/settings.h
+
+Implement work around for backwards-incompatible command-line options of gv-3.6.1.
+
+------------------------------------------------------------------------
+r1576 | jcbowman | 2006-06-07 02:47:32 -0600 (Wed, 07 Jun 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/Makefile.in
+
+Make docdir if it doesn't exist.
+
+------------------------------------------------------------------------
+r1575 | jcbowman | 2006-06-07 02:27:37 -0600 (Wed, 07 Jun 2006) | 4 lines
+Changed paths:
+ M /trunk/asymptote/Makefile.in
+ M /trunk/asymptote/base/pens.asy
+ M /trunk/asymptote/base/plain.asy
+ M /trunk/asymptote/configure.ac
+ M /trunk/asymptote/doc/asymptote.texi
+
+Fix default configure documentation directory setting.
+
+Document inclusion of Asymptote in Fedora Core Extras project.
+
+------------------------------------------------------------------------
+r1574 | jcbowman | 2006-06-07 01:40:43 -0600 (Wed, 07 Jun 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/Makefile.in
+ M /trunk/asymptote/configure.ac
+
+Added --with-docdir=PATH configure option.
+
+------------------------------------------------------------------------
+r1573 | jcbowman | 2006-06-06 23:12:16 -0600 (Tue, 06 Jun 2006) | 6 lines
+Changed paths:
+ M /trunk/asymptote/base/Label.asy
+ M /trunk/asymptote/base/flowchart.asy
+ A /trunk/asymptote/base/slopefield.asy (from /trunk/asymptote/base/slopefields.asy:1572)
+ D /trunk/asymptote/base/slopefields.asy
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/doc/flowchartdemo.asy
+
+Add object structure for handling frames and Labels on an equal footing.
+
+Add a pack routine for building compound frames from a list of objects.
+
+Simplify flowchart interface and example; fix frame/Label packing.
+
+------------------------------------------------------------------------
+r1572 | rmarinov | 2006-06-06 14:46:11 -0600 (Tue, 06 Jun 2006) | 1 line
+Changed paths:
+ A /trunk/asymptote/base/slopefields.asy
+ M /trunk/asymptote/doc/asymptote.texi
+
+Added slopefields module.
+------------------------------------------------------------------------
+r1571 | jcbowman | 2006-06-06 04:10:20 -0600 (Tue, 06 Jun 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/flowchart.asy
+ M /trunk/asymptote/doc/flowchartdemo.asy
+
+Fixed alignment problems, standardized usage.
+
+------------------------------------------------------------------------
+r1570 | smelenchuk | 2006-06-05 12:13:22 -0600 (Mon, 05 Jun 2006) | 1 line
+Changed paths:
+ M /trunk/asymptote/base/flowchart.asy
+
+Repair inconsistency in box height being used for vertically centering the header text in flowrectangle.
+------------------------------------------------------------------------
+r1569 | smelenchuk | 2006-06-05 11:52:27 -0600 (Mon, 05 Jun 2006) | 1 line
+Changed paths:
+ M /trunk/asymptote/base/flowchart.asy
+
+Tweak vertical margins on flowrectangle with header.
+------------------------------------------------------------------------
+r1568 | smelenchuk | 2006-06-05 09:31:06 -0600 (Mon, 05 Jun 2006) | 1 line
+Changed paths:
+ M /trunk/asymptote/base/flowchart.asy
+
+Adjust margins on flowrectangle (both with header and without).
+------------------------------------------------------------------------
+r1567 | jcbowman | 2006-06-04 21:49:17 -0600 (Sun, 04 Jun 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/filldraw.asy
+
+Make makepen fill nodes; fix infinite loops.
+
+------------------------------------------------------------------------
+r1566 | jcbowman | 2006-06-04 14:49:17 -0600 (Sun, 04 Jun 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/patterns.asy
+
+Added missing pen arguments in calls to hatch.
+
+------------------------------------------------------------------------
+r1565 | jcbowman | 2006-06-03 08:04:31 -0600 (Sat, 03 Jun 2006) | 6 lines
+Changed paths:
+ M /trunk/asymptote/base/graph.asy
+ M /trunk/asymptote/base/graph3.asy
+ M /trunk/asymptote/base/math.asy
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/runtime.in
+
+Fixed documentation of PaletteTicks.
+
+Renamed ngraph argument to n for consistency.
+
+Renamed straight(path) to piecewisestraight(path) and moved to runtime.in.
+
+------------------------------------------------------------------------
+r1564 | jcbowman | 2006-06-02 16:20:34 -0600 (Fri, 02 Jun 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/examples/dimension.asy
+
+Draw on frame f.
+
+------------------------------------------------------------------------
+r1563 | hammera | 2006-05-31 13:51:33 -0600 (Wed, 31 May 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+
+Clarified the non-behaviour of top level static modifiers.
+
+------------------------------------------------------------------------
+r1562 | hammera | 2006-05-31 13:42:21 -0600 (Wed, 31 May 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/coder.h
+ M /trunk/asymptote/dec.cc
+
+Added warning for top-level static modifiers.
+
+------------------------------------------------------------------------
+r1561 | jcbowman | 2006-05-31 12:45:50 -0600 (Wed, 31 May 2006) | 3 lines
+Changed paths:
+ M /trunk/asymptote/base/flowchart.asy
+
+Added flowblock initializer; removed unneeded new picture initializers.
+Added authors, improved indentation.
+
+------------------------------------------------------------------------
+r1560 | jcbowman | 2006-05-31 11:54:36 -0600 (Wed, 31 May 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/plain.asy
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/runtime.in
+
+Make cputime return a structure.
+
+------------------------------------------------------------------------
+r1559 | jcbowman | 2006-05-31 11:53:38 -0600 (Wed, 31 May 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/asymptote.spec
+
+Removed unneeded CFLAGS.
+
+------------------------------------------------------------------------
+r1558 | jcbowman | 2006-05-31 10:34:10 -0600 (Wed, 31 May 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/asymptote.spec
+
+Fix texinfo dependency.
+
+------------------------------------------------------------------------
+r1557 | jcbowman | 2006-05-31 10:21:34 -0600 (Wed, 31 May 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/Makefile.in
+ M /trunk/asymptote/asymptote.spec
+ M /trunk/asymptote/doc/Makefile
+
+More info updates.
+
+------------------------------------------------------------------------
+r1556 | jcbowman | 2006-05-31 07:03:42 -0600 (Wed, 31 May 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/runtime.in
+
+Add cputime() function.
+
+------------------------------------------------------------------------
+r1555 | jcbowman | 2006-05-31 06:24:26 -0600 (Wed, 31 May 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/asymptote.spec
+
+Use -O3 when building rpms.
+
+------------------------------------------------------------------------
+r1554 | jcbowman | 2006-05-31 06:13:43 -0600 (Wed, 31 May 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/examples/dimension.asy
+
+Fix picture scaling computation in dimension example.
+
+------------------------------------------------------------------------
+r1553 | jcbowman | 2006-05-31 05:18:53 -0600 (Wed, 31 May 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/slide.asy
+
+Improve diagnostics.
+
+------------------------------------------------------------------------
+r1552 | jcbowman | 2006-05-30 01:18:50 -0600 (Tue, 30 May 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/Makefile.in
+ M /trunk/asymptote/asymptote.spec
+
+Removed info dir entry in %files section; makedepend should respect cflags.
+
+------------------------------------------------------------------------
+r1551 | jcbowman | 2006-05-30 00:53:41 -0600 (Tue, 30 May 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/asymptote.spec
+
+Use make install-all in rpm spec file to install info pages as well.
+
+------------------------------------------------------------------------
+r1550 | jcbowman | 2006-05-30 00:53:15 -0600 (Tue, 30 May 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/Makefile.in
+
+Fix make uninstall.
+
+------------------------------------------------------------------------
+r1549 | jcbowman | 2006-05-30 00:28:36 -0600 (Tue, 30 May 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/Makefile.in
+
+Fix installation changes.
+
+------------------------------------------------------------------------
+r1548 | jcbowman | 2006-05-29 23:58:30 -0600 (Mon, 29 May 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/examples/epix.asy
+
+Update example to use new mesh resolution names.
+
+------------------------------------------------------------------------
+r1547 | jcbowman | 2006-05-29 23:57:15 -0600 (Mon, 29 May 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/Makefile.in
+
+Fix another relative path installation problem.
+
+------------------------------------------------------------------------
+r1546 | jcbowman | 2006-05-29 23:47:36 -0600 (Mon, 29 May 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/Makefile.in
+
+Fix installation of system asy files.
+
+------------------------------------------------------------------------
+r1545 | jcbowman | 2006-05-29 23:40:00 -0600 (Mon, 29 May 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/contour1.asy
+ M /trunk/asymptote/runtime.in
+
+Fix cxx warning message.
+
+------------------------------------------------------------------------
+r1544 | jcbowman | 2006-05-29 23:38:33 -0600 (Mon, 29 May 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+ A /trunk/asymptote/doc/contour1.asy (from /trunk/asymptote/doc/contourex1.asy:1543)
+ A /trunk/asymptote/doc/contour2.asy (from /trunk/asymptote/doc/contourex2.asy:1542)
+ D /trunk/asymptote/doc/contourex1.asy
+ D /trunk/asymptote/doc/contourex2.asy
+
+Renamed contour examples.
+
+------------------------------------------------------------------------
+r1543 | jcbowman | 2006-05-29 23:33:18 -0600 (Mon, 29 May 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/contour.asy
+ M /trunk/asymptote/base/pens.asy
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/doc/contourex1.asy
+
+Simplified contour interfaces by implicitly casting pen to pen(real).
+
+------------------------------------------------------------------------
+r1542 | jcbowman | 2006-05-29 22:06:37 -0600 (Mon, 29 May 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/Makefile.in
+ M /trunk/asymptote/asymptote.spec
+
+Change package group; request texi2dvi; install asy-init.el.
+
+------------------------------------------------------------------------
+r1541 | jcbowman | 2006-05-29 22:02:14 -0600 (Mon, 29 May 2006) | 2 lines
+Changed paths:
+ A /trunk/asymptote/base/asy-init.el
+
+Add emacs/xemacs init file for rpm installation.
+
+------------------------------------------------------------------------
+r1540 | jcbowman | 2006-05-29 22:01:05 -0600 (Mon, 29 May 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/plain.asy
+
+Move include shipout earlier.
+
+------------------------------------------------------------------------
+r1539 | rmarinov | 2006-05-29 15:46:10 -0600 (Mon, 29 May 2006) | 1 line
+Changed paths:
+ M /trunk/asymptote/base/contour.asy
+ M /trunk/asymptote/doc/asymptote.texi
+
+Added new interfaces to contour.asy
+------------------------------------------------------------------------
+r1538 | rmarinov | 2006-05-29 15:31:48 -0600 (Mon, 29 May 2006) | 1 line
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+ A /trunk/asymptote/doc/contourex1.asy
+ A /trunk/asymptote/doc/contourex2.asy
+
+Added basic documentation for contours.
+------------------------------------------------------------------------
+r1537 | jcbowman | 2006-05-28 22:40:13 -0600 (Sun, 28 May 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/contour.asy
+ M /trunk/asymptote/base/graph3.asy
+ M /trunk/asymptote/doc/asymptote.texi
+
+Minor optimizations; standardized mesh arguments (n -> nx, m -> ny).
+
+------------------------------------------------------------------------
+r1536 | jcbowman | 2006-05-28 18:07:12 -0600 (Sun, 28 May 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/contour.asy
+
+Further optimizations obtained by sorting contour array.
+
+------------------------------------------------------------------------
+r1535 | jcbowman | 2006-05-28 13:12:14 -0600 (Sun, 28 May 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/contour.asy
+
+Optimize.
+
+------------------------------------------------------------------------
+r1534 | jcbowman | 2006-05-26 22:19:37 -0600 (Fri, 26 May 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/asymptote.spec
+
+Add Jose's patch: list directories in %files section.
+
+------------------------------------------------------------------------
+r1533 | rmarinov | 2006-05-26 15:32:06 -0600 (Fri, 26 May 2006) | 1 line
+Changed paths:
+ M /trunk/asymptote/base/contour.asy
+
+Fixed a minor bug and added an additional interface option.
+------------------------------------------------------------------------
+r1532 | jcbowman | 2006-05-26 15:12:37 -0600 (Fri, 26 May 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/contour.asy
+
+Make pen argument a function.
+
+------------------------------------------------------------------------
+r1531 | jcbowman | 2006-05-26 15:02:09 -0600 (Fri, 26 May 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/contour.asy
+
+Standardized signatures; support contours of matrix data as well as functions.
+
+------------------------------------------------------------------------
+r1530 | jcbowman | 2006-05-26 11:36:37 -0600 (Fri, 26 May 2006) | 6 lines
+Changed paths:
+ M /trunk/asymptote/base/palette.asy
+ M /trunk/asymptote/base/pens.asy
+ M /trunk/asymptote/psfile.cc
+
+Make images and shading respect -gray, -rgb, -cmyk, and -bw.
+
+Make palette.asy use grayscale with -gray.
+
+Replace bool mono by settings.gray || settings.bw.
+
+------------------------------------------------------------------------
+r1529 | jcbowman | 2006-05-26 08:24:01 -0600 (Fri, 26 May 2006) | 5 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/runtime.in
+
+Add date arithmetic routines:
+time(int seconds, string format="");
+seconds(string t="", string format="");
+Make time() return the current time in the default UNIX format.
+
+------------------------------------------------------------------------
+r1528 | rmarinov | 2006-05-25 15:35:50 -0600 (Thu, 25 May 2006) | 1 line
+Changed paths:
+ M /trunk/asymptote/base/contour.asy
+
+Inserted a space between operator and .. .
+------------------------------------------------------------------------
+r1527 | jcbowman | 2006-05-25 14:50:32 -0600 (Thu, 25 May 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/configure.ac
+ M /trunk/asymptote/doc/asymptote.texi
+
+Changed 1.07cvs to 1.07svn.
+
+------------------------------------------------------------------------
+r1526 | rmarinov | 2006-05-25 13:17:55 -0600 (Thu, 25 May 2006) | 1 line
+Changed paths:
+ M /trunk/asymptote/base/contour.asy
+
+Fixed a formatting issue and a minor bug.
+------------------------------------------------------------------------
+r1525 | rmarinov | 2006-05-25 11:29:03 -0600 (Thu, 25 May 2006) | 1 line
+Changed paths:
+ M /trunk/asymptote/base/contour.asy
+
+Contour.asy now can choose interpolation operator; default is --.
+------------------------------------------------------------------------
+r1524 | jcbowman | 2006-05-25 10:43:46 -0600 (Thu, 25 May 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+ A /trunk/asymptote/doc/log2graph.asy
+
+Added example of log2 graph.
+
+------------------------------------------------------------------------
+r1523 | jcbowman | 2006-05-25 10:32:56 -0600 (Thu, 25 May 2006) | 4 lines
+Changed paths:
+ M /trunk/asymptote/base/graph.asy
+
+Fixed bug in YZero.
+
+Handle log graphs bases other than 10.
+
+------------------------------------------------------------------------
+r1522 | jcbowman | 2006-05-25 05:00:23 -0600 (Thu, 25 May 2006) | 5 lines
+Changed paths:
+ M /trunk/asymptote/base/contour.asy
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/runtime.in
+ M /trunk/asymptote/types.cc
+ M /trunk/asymptote/types.h
+
+Rename array virtual pull function to delete; handle case with negative
+argument.
+
+Add virtual insert function for arrays.
+
+------------------------------------------------------------------------
+r1521 | jcbowman | 2006-05-25 04:20:44 -0600 (Thu, 25 May 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/contour.asy
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/runtime.in
+ M /trunk/asymptote/types.cc
+ M /trunk/asymptote/types.h
+
+Added virtual pull function for arrays.
+
+------------------------------------------------------------------------
+r1520 | jcbowman | 2006-05-25 03:44:18 -0600 (Thu, 25 May 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/slide.asy
+
+Fix currentpicture.empty() test.
+
+------------------------------------------------------------------------
+r1519 | jcbowman | 2006-05-25 03:07:52 -0600 (Thu, 25 May 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/contour.asy
+
+Standardized argument names.
+
+------------------------------------------------------------------------
+r1518 | jcbowman | 2006-05-25 02:55:26 -0600 (Thu, 25 May 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/contour.asy
+
+Formatted.
+
+------------------------------------------------------------------------
+r1517 | jcbowman | 2006-05-25 02:30:13 -0600 (Thu, 25 May 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/solids.asy
+ D /trunk/asymptote/doc/cylinderoutline.asy
+ M /trunk/asymptote/examples/cylinder.asy
+ M /trunk/asymptote/examples/torus.asy
+
+Fixed longitudinal skeleton when c != O.
+
+------------------------------------------------------------------------
+r1516 | jcbowman | 2006-05-25 02:28:57 -0600 (Thu, 25 May 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/three.asy
+ M /trunk/asymptote/path.cc
+
+Minor optimizations.
+
+------------------------------------------------------------------------
+r1515 | jcbowman | 2006-05-25 02:27:52 -0600 (Thu, 25 May 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/drawfill.cc
+ M /trunk/asymptote/drawfill.h
+ M /trunk/asymptote/psfile.cc
+ M /trunk/asymptote/psfile.h
+
+Check colorspace argument for all forms of shading.
+
+------------------------------------------------------------------------
+r1514 | jcbowman | 2006-05-25 02:26:56 -0600 (Thu, 25 May 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/graph3.asy
+ M /trunk/asymptote/doc/asymptote.texi
+
+Added 3d axes routine.
+
+------------------------------------------------------------------------
+r1513 | rmarinov | 2006-05-24 15:45:34 -0600 (Wed, 24 May 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/contour.asy
+
+Now uses arrays.
+
+------------------------------------------------------------------------
+r1512 | jcbowman | 2006-05-24 15:08:08 -0600 (Wed, 24 May 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/three.asy
+ M /trunk/asymptote/path.cc
+
+Handle subpath arguments beyond boundaries.
+
+------------------------------------------------------------------------
+r1511 | jcbowman | 2006-05-24 11:25:27 -0600 (Wed, 24 May 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/contour.asy
+ M /trunk/asymptote/base/slide.asy
+ M /trunk/asymptote/examples/slidedemo.asy
+
+Added outline().
+
+------------------------------------------------------------------------
+r1510 | jcbowman | 2006-05-24 01:16:30 -0600 (Wed, 24 May 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/plain.asy
+
+Added reverse(triple[]).
+
+------------------------------------------------------------------------
+r1509 | jcbowman | 2006-05-24 00:28:55 -0600 (Wed, 24 May 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/path.cc
+
+Minor optimizations.
+
+------------------------------------------------------------------------
+r1508 | jcbowman | 2006-05-24 00:27:59 -0600 (Wed, 24 May 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/paths.asy
+ M /trunk/asymptote/base/three.asy
+
+Simplified code.
+
+------------------------------------------------------------------------
+r1507 | jcbowman | 2006-05-23 22:32:50 -0600 (Tue, 23 May 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/INSTALL
+
+Updated to mention Subversion instead of CVS.
+
+------------------------------------------------------------------------
+r1506 | jcbowman | 2006-05-23 22:27:31 -0600 (Tue, 23 May 2006) | 6 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/examples/slidedemo.asy
+ A /trunk/asymptote/examples/thermodynamics.asy
+
+Updated documentation for Subversion.
+
+Fixed list of autogenerated files in slidedemo.asy.
+
+Added missing file.
+
+------------------------------------------------------------------------
+r1505 | jcbowman | 2006-05-23 16:36:20 -0600 (Tue, 23 May 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/contour.asy
+
+Clarified comment about duplicate guides.
+
+------------------------------------------------------------------------
+r1504 | rmarinov | 2006-05-23 14:44:18 -0600 (Tue, 23 May 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/contour.asy
+
+basic .. routine
+
+------------------------------------------------------------------------
+r1503 | jcbowman | 2006-05-23 11:33:30 -0600 (Tue, 23 May 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/contour.asy
+
+Improved formatting.
+
+------------------------------------------------------------------------
+r1502 | rmarinov | 2006-05-23 11:26:18 -0600 (Tue, 23 May 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/contour.asy
+
+minor updates to contour.asy
+
+------------------------------------------------------------------------
+r1501 | jcbowman | 2006-05-23 10:46:50 -0600 (Tue, 23 May 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/solids.asy
+
+Fixed typo.
+
+------------------------------------------------------------------------
+r1500 | jcbowman | 2006-05-22 16:23:43 -0600 (Mon, 22 May 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/configure.ac
+
+Incremented version to 1.07cvs.
+
+------------------------------------------------------------------------
+r1499 | jcbowman | 2006-05-22 08:36:57 -0600 (Mon, 22 May 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/slide.asy
+
+Added figuremattpen optional argument.
+
+------------------------------------------------------------------------
+r1498 | jcbowman | 2006-05-22 08:36:14 -0600 (Mon, 22 May 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/asymptote.spec
+
+Fixed syntax.
+
+------------------------------------------------------------------------
+r1497 | jcbowman | 2006-05-22 00:17:35 -0600 (Mon, 22 May 2006) | 5 lines
+Changed paths:
+ M /trunk/asymptote/base/flowchart.asy
+ A /trunk/asymptote/doc/advection.asy
+ M /trunk/asymptote/doc/asymptote.texi
+ D /trunk/asymptote/doc/flowchart.asy
+ A /trunk/asymptote/doc/flowchartdemo.asy
+ D /trunk/asymptote/examples/flowchartdemo.asy
+
+
+Renamed old flowchart.asy example to advection.asy.
+
+Formatted flowchart.asy base file and example; standardized spellings, etc.
+
+------------------------------------------------------------------------
+r1496 | jcbowman | 2006-05-21 23:38:42 -0600 (Sun, 21 May 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/asymptote.spec
+
+Updated.
+
+------------------------------------------------------------------------
+r1495 | jcbowman | 2006-05-21 23:38:05 -0600 (Sun, 21 May 2006) | 4 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/main.cc
+ M /trunk/asymptote/texfile.cc
+ M /trunk/asymptote/texfile.h
+
+Restore TeXpipepreamble and TeXpreamble after eval(embedded=false).
+
+Restore settings between multiple file runs.
+
+------------------------------------------------------------------------
+r1494 | jcbowman | 2006-05-21 23:35:52 -0600 (Sun, 21 May 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/entry.cc
+
+More endl to newl changes.
+
+------------------------------------------------------------------------
+r1493 | jcbowman | 2006-05-21 23:34:29 -0600 (Sun, 21 May 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/fftw++.h
+
+Allow alignment checking to be disabled with -DNO_CHECK_ALIGN.
+
+------------------------------------------------------------------------
+r1492 | smelenchuk | 2006-05-21 14:00:13 -0600 (Sun, 21 May 2006) | 2 lines
+Changed paths:
+ A /trunk/asymptote/base/flowchart.asy
+ M /trunk/asymptote/doc/asymptote.texi
+ A /trunk/asymptote/examples/flowchartdemo.asy
+
+First version of the heavily-cleaned-up (originally externally contributed) flowchart module. A (very simple) demo has been added into examples and the documentation has a section on the module (could the docs be improved for it?).
+
+------------------------------------------------------------------------
+r1491 | jcbowman | 2006-05-21 02:39:14 -0600 (Sun, 21 May 2006) | 12 lines
+Changed paths:
+ M /trunk/asymptote/base/animate.asy
+ M /trunk/asymptote/base/plain.asy
+ M /trunk/asymptote/base/shipout.asy
+ M /trunk/asymptote/base/slide.asy
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/examples/slidedemo.asy
+ M /trunk/asymptote/picture.cc
+ M /trunk/asymptote/picture.h
+ M /trunk/asymptote/runtime.in
+
+
+Changed quiet=false option to view=true in shipout (backwards incompatible,
+but rarely used).
+
+Removed unused execute(string s, bool embedded=false) function.
+
+Added void asy(bool overwrite=false ... string[] s)
+to conditionally process each file name in array s in a new environment.
+Moved margin argument of figure in slide.asy to just after options.
+
+Make slidedemo.asy generate required files in case they don't exist.
+
+------------------------------------------------------------------------
+r1490 | jcbowman | 2006-05-21 02:02:42 -0600 (Sun, 21 May 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/main.cc
+
+Fixed segmentation fault with a future eval after an eval throws an exception.
+
+------------------------------------------------------------------------
+r1489 | jcbowman | 2006-05-21 00:38:22 -0600 (Sun, 21 May 2006) | 10 lines
+Changed paths:
+ M /trunk/asymptote/base/slide.asy
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/examples/slidedemo.asy
+
+
+Make titlepage and title by default call newslide, unless the
+currentpicture is empty.
+
+Added reverse video option to slidedemo.asy.
+
+Add an argument to newslide to allow stepping to be turned off for that slide.
+
+Updated slidedemo example.
+
+------------------------------------------------------------------------
+r1488 | jcbowman | 2006-05-21 00:34:16 -0600 (Sun, 21 May 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/filldraw.asy
+ M /trunk/asymptote/base/pens.asy
+
+Add optional x and y margin arguments to Fill.
+
+------------------------------------------------------------------------
+r1487 | jcbowman | 2006-05-21 00:29:44 -0600 (Sun, 21 May 2006) | 4 lines
+Changed paths:
+ M /trunk/asymptote/settings.cc
+
+Allow -u to be specified multiple times on command line.
+
+Make "open" the default pdf viewer for MacOS.
+
+------------------------------------------------------------------------
+r1486 | jcbowman | 2006-05-21 00:28:15 -0600 (Sun, 21 May 2006) | 3 lines
+Changed paths:
+ M /trunk/asymptote/Makefile.in
+ A /trunk/asymptote/doc/asycolors.sty
+
+Added asycolors.sty package to make LaTeX aware of CMYK versions of
+predefined Asymptote colours.
+
+------------------------------------------------------------------------
+r1485 | jcbowman | 2006-05-21 00:24:42 -0600 (Sun, 21 May 2006) | 4 lines
+Changed paths:
+ M /trunk/asymptote/exp.cc
+ M /trunk/asymptote/main.cc
+ M /trunk/asymptote/picture.cc
+ M /trunk/asymptote/texfile.cc
+
+Fixed -outformat pdf for papersizes like a4 with nonintegral bp dimensions.
+
+Improve performance by avoiding unnecessary flushing of output stream.
+
+------------------------------------------------------------------------
+r1484 | jcbowman | 2006-05-19 17:24:21 -0600 (Fri, 19 May 2006) | 4 lines
+Changed paths:
+ M /trunk/asymptote/runtime.in
+
+Make fft(real[]) a nop when not configured with fftw.
+
+Handle fft(new real[]) gracefully (returns an empty array).
+
+------------------------------------------------------------------------
+r1483 | rmarinov | 2006-05-19 10:31:11 -0600 (Fri, 19 May 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/contour.asy
+
+contour.asy now with guides, supports dashed lines
+
+------------------------------------------------------------------------
+r1482 | jcbowman | 2006-05-19 01:09:38 -0600 (Fri, 19 May 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/configure.ac
+
+Incremented version to 1.06cvs.
+
+------------------------------------------------------------------------
+r1481 | jcbowman | 2006-05-18 22:42:16 -0600 (Thu, 18 May 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/slide.asy
+
+Reduced default authorpen fontsize.
+
+------------------------------------------------------------------------
+r1480 | jcbowman | 2006-05-18 22:21:02 -0600 (Thu, 18 May 2006) | 6 lines
+Changed paths:
+ M /trunk/asymptote/base/graph.asy
+ M /trunk/asymptote/base/graph3.asy
+ M /trunk/asymptote/base/solids.asy
+ M /trunk/asymptote/base/three.asy
+ M /trunk/asymptote/doc/asymptote.texi
+ A /trunk/asymptote/doc/cylinderskeleton.asy
+ M /trunk/asymptote/examples/cones.asy
+ A /trunk/asymptote/examples/hyperboloid.asy
+ M /trunk/asymptote/examples/sphere.asy
+
+Added normal argument to Arc.
+
+Standardized arguments to revolution.
+
+Updated documentation and examples.
+
+------------------------------------------------------------------------
+r1479 | jcbowman | 2006-05-18 13:43:12 -0600 (Thu, 18 May 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/tests/Makefile
+ M /trunk/asymptote/tests/TestLib.asy
+ M /trunk/asymptote/tests/arith/roots.asy
+ A /trunk/asymptote/tests/array
+ A /trunk/asymptote/tests/array/determinant.asy
+ M /trunk/asymptote/tests/gc/file.asy
+
+Added determinant test.
+
+------------------------------------------------------------------------
+r1478 | jcbowman | 2006-05-18 13:04:15 -0600 (Thu, 18 May 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/math.asy
+
+Removed unnormalized epsilon from determinant.
+
+------------------------------------------------------------------------
+r1477 | jcbowman | 2006-05-18 12:48:10 -0600 (Thu, 18 May 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+
+Updated documentation: real a[] now constructs internal functions of real[].
+
+------------------------------------------------------------------------
+r1476 | hammera | 2006-05-18 12:17:29 -0600 (Thu, 18 May 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/TODO
+
+addOps for int x[] now implemented.
+
+------------------------------------------------------------------------
+r1475 | hammera | 2006-05-18 11:55:07 -0600 (Thu, 18 May 2006) | 3 lines
+Changed paths:
+ M /trunk/asymptote/dec.cc
+ M /trunk/asymptote/dec.h
+ M /trunk/asymptote/fundec.cc
+ M /trunk/asymptote/fundec.h
+
+Now add operations for all variable declarations of new arrays and functions.
+Removed old code.
+
+------------------------------------------------------------------------
+r1474 | jcbowman | 2006-05-18 04:14:06 -0600 (Thu, 18 May 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/examples/slidedemo.asy
+
+Explicitly document -u stepping=true.
+
+------------------------------------------------------------------------
+r1473 | jcbowman | 2006-05-18 03:53:10 -0600 (Thu, 18 May 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/drawpath.cc
+
+Fixed cxx warning.
+
+------------------------------------------------------------------------
+r1472 | jcbowman | 2006-05-18 03:29:48 -0600 (Thu, 18 May 2006) | 14 lines
+Changed paths:
+ M /trunk/asymptote/base/solids.asy
+ M /trunk/asymptote/base/three.asy
+ M /trunk/asymptote/doc/asymptote.texi
+ D /trunk/asymptote/doc/cylinder.asy
+ A /trunk/asymptote/doc/cylinderoutline.asy
+ A /trunk/asymptote/examples/cones.asy
+ A /trunk/asymptote/examples/cylinder.asy
+ A /trunk/asymptote/examples/torus.asy
+
+
+Implemented revolution struct in solid.asy for constructing, drawing, and
+filling surfaces of revolution.
+
+Added surfaces of revolution examples.
+
+Ported precontrol and postcontrol resolution fixes to three.asy.
+
+Added 3D version of relpoint functions.
+
+Fixed normal(path3).
+
+Updated documentation.
+
+------------------------------------------------------------------------
+r1471 | jcbowman | 2006-05-18 01:03:04 -0600 (Thu, 18 May 2006) | 2 lines
+Changed paths:
+ A /trunk/asymptote/examples/dimension.asy
+
+Added example showing how to scale only selective dimensions.
+
+------------------------------------------------------------------------
+r1470 | jcbowman | 2006-05-17 23:44:26 -0600 (Wed, 17 May 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/Makefile.in
+ M /trunk/asymptote/base/asymptote.py
+ M /trunk/asymptote/doc/Makefile
+ M /trunk/asymptote/doc/asymptote.texi
+
+Documented how to call Asymptote from Python.
+
+------------------------------------------------------------------------
+r1469 | jcbowman | 2006-05-17 23:07:49 -0600 (Wed, 17 May 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/examples/slidedemo.asy
+
+Make location of slidedemo explicit.
+
+------------------------------------------------------------------------
+r1468 | jcbowman | 2006-05-17 22:46:32 -0600 (Wed, 17 May 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/constants.asy
+
+Reduce infinity to avoid floating point exceptions with --- operator.
+
+------------------------------------------------------------------------
+r1467 | jcbowman | 2006-05-17 22:44:19 -0600 (Wed, 17 May 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/plain.asy
+ M /trunk/asymptote/base/slide.asy
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/examples/slidedemo.asy
+
+Allow stepping to be enabled from the command line: -u stepping=true.
+
+------------------------------------------------------------------------
+r1466 | jcbowman | 2006-05-17 22:39:49 -0600 (Wed, 17 May 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/graph.asy
+
+Added y and z autoscale arguments to scale().
+
+------------------------------------------------------------------------
+r1465 | jcbowman | 2006-05-17 22:15:27 -0600 (Wed, 17 May 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+ A /trunk/asymptote/doc/monthaxis.asy
+
+Added example showing how to label an axis with an arbitrary string.
+
+------------------------------------------------------------------------
+r1464 | jcbowman | 2006-05-16 01:40:57 -0600 (Tue, 16 May 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/tests/TestLib.asy
+ M /trunk/asymptote/tests/arith/integer.asy
+ M /trunk/asymptote/tests/arith/pair.asy
+ M /trunk/asymptote/tests/arith/real.asy
+ A /trunk/asymptote/tests/arith/roots.asy
+ M /trunk/asymptote/tests/arith/transform.asy
+ M /trunk/asymptote/tests/arith/triple.asy
+ M /trunk/asymptote/tests/frames/stat.asy
+ M /trunk/asymptote/tests/frames/stat2.asy
+ M /trunk/asymptote/tests/imp/unravel.asy
+ M /trunk/asymptote/tests/string/erase.asy
+ M /trunk/asymptote/tests/string/find.asy
+ M /trunk/asymptote/tests/string/insert.asy
+ M /trunk/asymptote/tests/string/length.asy
+ M /trunk/asymptote/tests/string/rfind.asy
+ M /trunk/asymptote/tests/string/substr.asy
+ M /trunk/asymptote/tests/types/cast.asy
+ M /trunk/asymptote/tests/types/ecast.asy
+ M /trunk/asymptote/tests/types/init.asy
+
+Improved test diagnostics by using internal assert(bool) function.
+
+------------------------------------------------------------------------
+r1463 | jcbowman | 2006-05-16 01:37:55 -0600 (Tue, 16 May 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/runtime.in
+
+Added assert(bool) function.
+
+------------------------------------------------------------------------
+r1462 | jcbowman | 2006-05-16 01:36:19 -0600 (Tue, 16 May 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/path.cc
+
+Fixed cubicroots when R=0.
+
+------------------------------------------------------------------------
+r1461 | jcbowman | 2006-05-16 01:34:48 -0600 (Tue, 16 May 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/errormsg.h
+
+Flush output stream on errors.
+
+------------------------------------------------------------------------
+r1460 | jcbowman | 2006-05-15 00:45:38 -0600 (Mon, 15 May 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/drawpath.cc
+ M /trunk/asymptote/pen.h
+ M /trunk/asymptote/psfile.cc
+ M /trunk/asymptote/runtime.in
+
+Added offset argument to linetype.
+
+------------------------------------------------------------------------
+r1459 | jcbowman | 2006-05-14 14:54:35 -0600 (Sun, 14 May 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/builtin.cc
+
+Remove unused argument.
+
+------------------------------------------------------------------------
+r1458 | jcbowman | 2006-05-14 14:48:42 -0600 (Sun, 14 May 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/builtin.cc
+ M /trunk/asymptote/builtin.h
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/genv.cc
+ M /trunk/asymptote/record.cc
+
+Move GSL functions into a separate module named gsl.
+
+------------------------------------------------------------------------
+r1457 | jcbowman | 2006-05-14 14:37:04 -0600 (Sun, 14 May 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/contour.asy
+
+Formatting.
+
+------------------------------------------------------------------------
+r1456 | jcbowman | 2006-05-14 11:29:08 -0600 (Sun, 14 May 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/asymptote.spec
+
+Removed aclocal and autoconf since Asymptote is distributed with configure.
+
+------------------------------------------------------------------------
+r1455 | hammera | 2006-05-13 12:33:45 -0600 (Sat, 13 May 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/builtin.cc
+ M /trunk/asymptote/builtin.h
+ M /trunk/asymptote/dec.cc
+ M /trunk/asymptote/dec.h
+ M /trunk/asymptote/env.cc
+ M /trunk/asymptote/env.h
+ M /trunk/asymptote/exp.cc
+ M /trunk/asymptote/fundec.cc
+ M /trunk/asymptote/record.cc
+ M /trunk/asymptote/record.h
+ M /trunk/asymptote/settings.cc
+ M /trunk/asymptote/types.h
+
+Moved addOps for types to builtin.cc. Added support for builtin structures.
+
+------------------------------------------------------------------------
+r1454 | hammera | 2006-05-13 09:52:19 -0600 (Sat, 13 May 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/exp.h
+
+Fixed typo.
+
+------------------------------------------------------------------------
+r1453 | jcbowman | 2006-05-13 00:53:22 -0600 (Sat, 13 May 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.sty
+ M /trunk/asymptote/runtime.in
+
+Removed quiet(bool) in favour of explicit setting.
+
+------------------------------------------------------------------------
+r1452 | jcbowman | 2006-05-13 00:20:07 -0600 (Sat, 13 May 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/asy.1
+
+Updated man page.
+
+------------------------------------------------------------------------
+r1451 | jcbowman | 2006-05-12 23:59:05 -0600 (Fri, 12 May 2006) | 2 lines
+Changed paths:
+ A /trunk/asymptote/asymptote.spec
+
+Added RPM spec file, courtesy of Jose Pedro Oliveira.
+
+------------------------------------------------------------------------
+r1450 | jcbowman | 2006-05-12 23:25:56 -0600 (Fri, 12 May 2006) | 11 lines
+Changed paths:
+ M /trunk/asymptote/Makefile.in
+ M /trunk/asymptote/configure.ac
+ M /trunk/asymptote/doc/asymptote.texi
+
+
+Moved asy.vim and asy-mode.el back to /usr/local/share/asymptote, where they
+really belong. Also put asymptote.py here.
+
+Revert default asymptote documentation directory to
+/usr/local/share/doc/asymptote (removed recently introduced version
+dependency, which made no sense since the system directory doesn't depend
+on a version number either: version checking is done in plain.asy).
+
+Updated documentation (including new sourceforge cvs instructions).
+
+------------------------------------------------------------------------
+r1449 | jcbowman | 2006-05-12 22:55:57 -0600 (Fri, 12 May 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/graph.asy
+ M /trunk/asymptote/base/graph3.asy
+
+Make Arc use degrees rather than radians.
+
+------------------------------------------------------------------------
+r1448 | jcbowman | 2006-05-12 22:54:38 -0600 (Fri, 12 May 2006) | 9 lines
+Changed paths:
+ M /trunk/asymptote/base/three.asy
+
+
+Fixed obliqueX and obliqueY camera positions.
+
+Make obliqueZ a synonym for oblique.
+
+Ignore spurious errors from longitude.
+
+Added missing (optional) normal argument to arc call.
+
+------------------------------------------------------------------------
+r1447 | jcbowman | 2006-05-12 22:47:41 -0600 (Fri, 12 May 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/filldraw.asy
+
+Added clipping margin to unfill.
+
+------------------------------------------------------------------------
+r1446 | jcbowman | 2006-05-12 22:46:54 -0600 (Fri, 12 May 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/exp.cc
+
+Added Andy's getApplication bug fix.
+
+------------------------------------------------------------------------
+r1445 | rmarinov | 2006-05-12 15:50:17 -0600 (Fri, 12 May 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/contour.asy
+
+lines of length <80. handles multiple contour lines at once for efficiency.
+
+------------------------------------------------------------------------
+r1444 | jcbowman | 2006-05-12 15:03:59 -0600 (Fri, 12 May 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/contour.asy
+
+Renamed pen argument.
+
+------------------------------------------------------------------------
+r1443 | rmarinov | 2006-05-12 13:05:34 -0600 (Fri, 12 May 2006) | 2 lines
+Changed paths:
+ A /trunk/asymptote/base/contour.asy
+
+added basic contouring routine
+
+------------------------------------------------------------------------
+r1442 | rmarinov | 2006-05-12 12:58:51 -0600 (Fri, 12 May 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/math.asy
+
+added general determinant
+
+------------------------------------------------------------------------
+r1441 | smelenchuk | 2006-05-12 10:40:23 -0600 (Fri, 12 May 2006) | 2 lines
+Changed paths:
+ A /trunk/asymptote/tests/arith/transform.asy
+
+More tests; these ones relate to transforms.
+
+------------------------------------------------------------------------
+r1440 | smelenchuk | 2006-05-12 10:19:44 -0600 (Fri, 12 May 2006) | 2 lines
+Changed paths:
+ D /trunk/asymptote/tests/arith/add.asy
+ A /trunk/asymptote/tests/arith/integer.asy
+ A /trunk/asymptote/tests/arith/pair.asy
+ A /trunk/asymptote/tests/arith/real.asy
+ A /trunk/asymptote/tests/arith/triple.asy
+
+Beginning to expand the arithmetic test. Now classifying as related to what type of data the tests are working with; each file contains several tests related to that type of data.
+
+------------------------------------------------------------------------
+r1439 | jcbowman | 2006-05-08 02:33:45 -0600 (Mon, 08 May 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/runtime.in
+ M /trunk/asymptote/settings.cc
+
+Fixed quiet(bool); improve settings diagnostic.
+
+------------------------------------------------------------------------
+r1438 | jcbowman | 2006-05-08 01:50:15 -0600 (Mon, 08 May 2006) | 14 lines
+Changed paths:
+ M /trunk/asymptote/INSTALL
+ M /trunk/asymptote/Makefile.in
+ M /trunk/asymptote/base/featpost3D.asy
+ M /trunk/asymptote/base/math.asy
+ M /trunk/asymptote/base/solids.asy
+ M /trunk/asymptote/base/three.asy
+ M /trunk/asymptote/configure.ac
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/examples/PythagoreanTree.asy
+ M /trunk/asymptote/examples/Sierpinski.asy
+ M /trunk/asymptote/examples/conicurv.asy
+ M /trunk/asymptote/examples/cosaddition.asy
+ M /trunk/asymptote/examples/sinxlex.asy
+ M /trunk/asymptote/examples/wedge.asy
+ M /trunk/asymptote/runtime.in
+
+Removed Degrees and Longitude in favour of degrees(warn=false) and Longitude(warn=false).
+
+Moved Sin, Cos, Tan, aSin, aCos, and aTan to runtime.in.
+
+Renamed double to real in runtime.in for compatibility with asy code.
+
+Moved examples to subdirectory of documentation directory.
+
+Don't automatically strip binary when installing.
+
+Generalized DESTDIR support.
+
+Documented optional packages in INSTALL.
+
+------------------------------------------------------------------------
+r1437 | jcbowman | 2006-05-08 01:36:48 -0600 (Mon, 08 May 2006) | 4 lines
+Changed paths:
+ M /trunk/asymptote/drawpath.cc
+
+
+In dash adjustment, always respect scaling to penwidth (when requested)
+and draw terminator if close to arclength.
+
+------------------------------------------------------------------------
+r1436 | jcbowman | 2006-05-06 21:39:22 -0600 (Sat, 06 May 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/exp.cc
+
+Improve ambiguous function signature diagnostics.
+
+------------------------------------------------------------------------
+r1435 | jcbowman | 2006-05-06 21:35:50 -0600 (Sat, 06 May 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/main.cc
+
+Turn of listvariables while reading config files.
+
+------------------------------------------------------------------------
+r1434 | jcbowman | 2006-05-06 04:30:43 -0600 (Sat, 06 May 2006) | 2 lines
+Changed paths:
+ A /trunk/asymptote/examples/Sierpinski.asy
+
+Added Sierpinski gasket example.
+
+------------------------------------------------------------------------
+r1433 | jcbowman | 2006-05-05 03:06:16 -0600 (Fri, 05 May 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/three.asy
+ M /trunk/asymptote/doc/asymptote.texi
+
+Added obligueY projection.
+
+------------------------------------------------------------------------
+r1432 | jcbowman | 2006-05-02 09:59:46 -0600 (Tue, 02 May 2006) | 11 lines
+Changed paths:
+ M /trunk/asymptote/base/slide.asy
+ M /trunk/asymptote/doc/asy.1
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/picture.cc
+ M /trunk/asymptote/picture.h
+ M /trunk/asymptote/settings.cc
+
+Removed oneFileView setting in favour of a new setting multipleView, under
+control of batchView.
+
+Renamed pagewidth/pageheight to paperwidth/paperheight to agree with
+documentation.
+
+Handle cases where paperwidth or paperheight are smaller than corresponding
+picture dimensions.
+
+Handle nonstandard paper sizes when producing pdf files.
+
+------------------------------------------------------------------------
+r1431 | jcbowman | 2006-05-02 06:27:12 -0600 (Tue, 02 May 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/builtin.cc
+
+Added realDigits (DBL_DIG).
+
+------------------------------------------------------------------------
+r1430 | jcbowman | 2006-05-01 21:50:09 -0600 (Mon, 01 May 2006) | 7 lines
+Changed paths:
+ M /trunk/asymptote/base/patterns.asy
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/runtime.in
+
+
+Added string string(real x, int digits) routine to cast a real to a string
+using precision digits in the C locale.
+
+Use string(real x, int digits) instead of the locale-dependent format
+function for postscript patterns.
+
+------------------------------------------------------------------------
+r1429 | jcbowman | 2006-04-29 07:37:10 -0600 (Sat, 29 Apr 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/three.asy
+
+Fixed rotate(real angle, triple u, triple v) when u != 0.
+
+------------------------------------------------------------------------
+r1428 | jcbowman | 2006-04-28 08:08:24 -0600 (Fri, 28 Apr 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/three.asy
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/doc/cube.asy
+
+Added obliqueX projection.
+
+------------------------------------------------------------------------
+r1427 | jcbowman | 2006-04-28 07:51:59 -0600 (Fri, 28 Apr 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/configure.ac
+
+Moved fftw header check back to original location.
+
+------------------------------------------------------------------------
+r1426 | jcbowman | 2006-04-28 06:51:52 -0600 (Fri, 28 Apr 2006) | 3 lines
+Changed paths:
+ M /trunk/asymptote/configure.ac
+
+
+Added missing space after -lgc; moved fftw header checks to header section.
+
+------------------------------------------------------------------------
+r1425 | jcbowman | 2006-04-25 19:29:36 -0600 (Tue, 25 Apr 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/picture.cc
+ M /trunk/asymptote/picture.h
+
+Apply dvips bounding box fuzz even when producing pdf format.
+
+------------------------------------------------------------------------
+r1424 | jcbowman | 2006-04-25 19:24:53 -0600 (Tue, 25 Apr 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+
+Fixed argument reversal in signature of one of the add routines.
+
+------------------------------------------------------------------------
+r1423 | jcbowman | 2006-04-24 02:01:16 -0600 (Mon, 24 Apr 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/configure.ac
+
+Incremented version to 1.05cvs.
+
+------------------------------------------------------------------------
+r1422 | jcbowman | 2006-04-24 00:42:48 -0600 (Mon, 24 Apr 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/builtin.cc
+
+Fixed cxx warnings.
+
+------------------------------------------------------------------------
+r1421 | jcbowman | 2006-04-24 00:37:11 -0600 (Mon, 24 Apr 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/picture.cc
+
+Removed unused variable.
+
+------------------------------------------------------------------------
+r1420 | jcbowman | 2006-04-24 00:03:05 -0600 (Mon, 24 Apr 2006) | 2 lines
+Changed paths:
+ A /trunk/asymptote/doc/flowchart.asy
+ D /trunk/asymptote/examples/flowchart.asy
+
+Move missing file flowchart.asy to correct directory.
+
+------------------------------------------------------------------------
+r1419 | jcbowman | 2006-04-23 23:53:36 -0600 (Sun, 23 Apr 2006) | 4 lines
+Changed paths:
+ M /trunk/asymptote/errors
+ M /trunk/asymptote/errortest.asy
+ M /trunk/asymptote/wce
+
+Make wce work even if configured with GSL library.
+
+Abort make if check fails.
+
+------------------------------------------------------------------------
+r1418 | jcbowman | 2006-04-23 23:39:25 -0600 (Sun, 23 Apr 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+
+Untabified.
+
+------------------------------------------------------------------------
+r1417 | jcbowman | 2006-04-23 23:33:26 -0600 (Sun, 23 Apr 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/three.asy
+
+Check also if first and second points are uncontrolled duplicates.
+
+------------------------------------------------------------------------
+r1416 | jcbowman | 2006-04-23 23:26:20 -0600 (Sun, 23 Apr 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/graph.asy
+ M /trunk/asymptote/doc/asymptote.texi
+
+Added parametric functions that accept an arbitrary sampling function.
+
+------------------------------------------------------------------------
+r1415 | jcbowman | 2006-04-23 11:56:09 -0600 (Sun, 23 Apr 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/slide.asy
+ M /trunk/asymptote/examples/poster.asy
+ M /trunk/asymptote/examples/slidedemo.asy
+
+Updated poster example to use slide.asy.
+
+------------------------------------------------------------------------
+r1414 | jcbowman | 2006-04-23 10:27:25 -0600 (Sun, 23 Apr 2006) | 5 lines
+Changed paths:
+ M /trunk/asymptote/doc/asy.1
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/settings.cc
+
+
+Change user variable to a string.
+
+Document how arbitrary Asymptote code can be specified on the command line.
+
+------------------------------------------------------------------------
+r1413 | jcbowman | 2006-04-23 01:24:45 -0600 (Sun, 23 Apr 2006) | 4 lines
+Changed paths:
+ M /trunk/asymptote/base/plain.asy
+ M /trunk/asymptote/base/slide.asy
+ M /trunk/asymptote/base/strings.asy
+ M /trunk/asymptote/doc/asymptote.texi
+ A /trunk/asymptote/examples/flowchart.asy
+ A /trunk/asymptote/examples/slidedemo.asy
+
+Added optional background and multiple figures to slide package.
+
+Updated documentation.
+
+------------------------------------------------------------------------
+r1412 | jcbowman | 2006-04-22 23:35:38 -0600 (Sat, 22 Apr 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/constants.asy
+ M /trunk/asymptote/base/graph.asy
+ M /trunk/asymptote/base/picture.asy
+ M /trunk/asymptote/doc/Bode.asy
+ M /trunk/asymptote/doc/asymptote.texi
+
+Replace infinities in userMax and userMin with boolean flags.
+
+------------------------------------------------------------------------
+r1411 | jcbowman | 2006-04-22 21:33:29 -0600 (Sat, 22 Apr 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/picture.cc
+
+Increased bounding box fuzz.
+
+------------------------------------------------------------------------
+r1410 | jcbowman | 2006-04-22 21:26:28 -0600 (Sat, 22 Apr 2006) | 14 lines
+Changed paths:
+ M /trunk/asymptote/base/constants.asy
+ M /trunk/asymptote/base/picture.asy
+ M /trunk/asymptote/base/shipout.asy
+ M /trunk/asymptote/base/slide.asy
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/picture.cc
+
+
+Updated call to add in slide.asy.
+
+Implemented fixedscaling(picture, pair min, pair max, pen) routine for
+using a fixed scaling to map user coordinates in box(min,max) to the
+desired picture size.
+
+Added UpsideDown orientation.
+
+Moved min and max of a real argument list to constants.asy.
+
+Always pass explicit pageWidth and pageHeight arguments to dvips rather
+than using the papertype.
+
+------------------------------------------------------------------------
+r1409 | jcbowman | 2006-04-22 05:03:27 -0600 (Sat, 22 Apr 2006) | 4 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/picture.cc
+ M /trunk/asymptote/runtime.in
+ M /trunk/asymptote/texfile.cc
+
+Fixed dvips bounding box.
+
+Added texreset function to reset tex environment.
+
+------------------------------------------------------------------------
+r1408 | jcbowman | 2006-04-21 10:47:35 -0600 (Fri, 21 Apr 2006) | 6 lines
+Changed paths:
+ M /trunk/asymptote/base/constants.asy
+ M /trunk/asymptote/base/markers.asy
+ M /trunk/asymptote/doc/asy.1
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/settings.cc
+
+
+Added general purpose real user command-line option.
+
+Legend skip is now based on the actual legend entry height, rather than on the
+fontsize.
+
+------------------------------------------------------------------------
+r1407 | jcbowman | 2006-04-21 09:52:06 -0600 (Fri, 21 Apr 2006) | 2 lines
+Changed paths:
+ A /trunk/asymptote/base/texcolors.asy
+ A /trunk/asymptote/base/x11colors.asy
+ M /trunk/asymptote/doc/asymptote.texi
+
+Added and documented texcolors and x11colors.
+
+------------------------------------------------------------------------
+r1406 | jcbowman | 2006-04-20 23:59:59 -0600 (Thu, 20 Apr 2006) | 6 lines
+Changed paths:
+ M /trunk/asymptote/base/pens.asy
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/drawpath.cc
+ M /trunk/asymptote/pen.h
+ M /trunk/asymptote/picture.cc
+ M /trunk/asymptote/runtime.in
+
+
+Improved linetype adjustment to arclength for short segments.
+
+Added optional boolean adjust argument to linetype to allow one to disable
+linetype adjustment.
+
+------------------------------------------------------------------------
+r1405 | jcbowman | 2006-04-20 20:48:40 -0600 (Thu, 20 Apr 2006) | 5 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/doc/loggraph.asy
+
+Documented pair Scale(picture pic=currentpicture, pair z) function for
+plotting in unscaled (graph) coordinates.
+
+Improved documentation of add for pictures and frames.
+
+------------------------------------------------------------------------
+r1404 | jcbowman | 2006-04-19 23:19:03 -0600 (Wed, 19 Apr 2006) | 7 lines
+Changed paths:
+ M /trunk/asymptote/base/arrows.asy
+ M /trunk/asymptote/base/drawtree.asy
+ M /trunk/asymptote/base/geometry.asy
+ M /trunk/asymptote/base/margins.asy
+ M /trunk/asymptote/base/markers.asy
+ M /trunk/asymptote/base/picture.asy
+ M /trunk/asymptote/base/slide.asy
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/doc/errorbars.asy
+ M /trunk/asymptote/doc/image.asy
+ M /trunk/asymptote/doc/lineargraph.asy
+ M /trunk/asymptote/doc/lineargraph0.asy
+ M /trunk/asymptote/doc/subpictures.asy
+ M /trunk/asymptote/examples/elliptic.asy
+ M /trunk/asymptote/examples/hierarchy.asy
+ M /trunk/asymptote/examples/laserlattice.asy
+ M /trunk/asymptote/examples/mosaic.asy
+
+
+Changed add and attach to take arguments in the same order as label,
+renaming "origin" to "position" and "dir" to "align".
+
+Removed the align argument of legend, which really belongs in the
+add/attach command.
+
+------------------------------------------------------------------------
+r1403 | jcbowman | 2006-04-19 22:54:16 -0600 (Wed, 19 Apr 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/examples/eetomumu.asy
+
+Fixed arrow alignment.
+
+------------------------------------------------------------------------
+r1402 | jcbowman | 2006-04-19 18:42:40 -0600 (Wed, 19 Apr 2006) | 5 lines
+Changed paths:
+ M /trunk/asymptote/drawlabel.cc
+ M /trunk/asymptote/picture.cc
+ M /trunk/asymptote/texfile.cc
+ M /trunk/asymptote/texfile.h
+
+
+Fixed alignment of postscript and tex layers by working around failure of
+includegraphics command (from LaTeX graphicx package) to respect
+HiResBoundingBox.
+
+------------------------------------------------------------------------
+r1401 | jcbowman | 2006-04-19 02:17:56 -0600 (Wed, 19 Apr 2006) | 2 lines
+Changed paths:
+ A /trunk/asymptote/base/asymptote.py
+
+Added Python module to allow access to Asymptote commands.
+
+------------------------------------------------------------------------
+r1400 | jcbowman | 2006-04-17 02:00:50 -0600 (Mon, 17 Apr 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/filldraw.asy
+
+Fixed clipping of remote labels near frame boundary by unfill.
+
+------------------------------------------------------------------------
+r1399 | jcbowman | 2006-04-17 01:38:57 -0600 (Mon, 17 Apr 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/picture.cc
+
+Improved alignment of tex and postscript layers.
+
+------------------------------------------------------------------------
+r1398 | hammera | 2006-04-16 16:10:47 -0600 (Sun, 16 Apr 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/TODO
+ M /trunk/asymptote/dec.cc
+ M /trunk/asymptote/entry.cc
+ M /trunk/asymptote/entry.h
+ M /trunk/asymptote/name.cc
+ M /trunk/asymptote/name.h
+
+Added permission checking for types.
+
+------------------------------------------------------------------------
+r1397 | jcbowman | 2006-04-14 15:19:52 -0600 (Fri, 14 Apr 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/graph.asy
+ M /trunk/asymptote/doc/asymptote.texi
+
+Make format="%" suppress tick labels for logarithmic axis.
+
+------------------------------------------------------------------------
+r1396 | jcbowman | 2006-04-14 02:20:31 -0600 (Fri, 14 Apr 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/pens.asy
+ M /trunk/asymptote/doc/colors.asy
+
+Change standard name for salmon colour to lightred.
+
+------------------------------------------------------------------------
+r1395 | jcbowman | 2006-04-14 02:13:08 -0600 (Fri, 14 Apr 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/runtime.in
+
+Fixed tension atleast (broken in autogenerated code since 0.96).
+
+------------------------------------------------------------------------
+r1394 | jcbowman | 2006-04-13 08:15:24 -0600 (Thu, 13 Apr 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/pens.asy
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/doc/colors.asy
+
+Renamed "strong" colors to "heavy".
+
+------------------------------------------------------------------------
+r1393 | jcbowman | 2006-04-13 01:12:55 -0600 (Thu, 13 Apr 2006) | 2 lines
+Changed paths:
+ A /trunk/asymptote/doc/colors.asy
+
+Display named colours.
+
+------------------------------------------------------------------------
+r1392 | jcbowman | 2006-04-13 00:53:19 -0600 (Thu, 13 Apr 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/pens.asy
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/examples/cardiod.asy
+
+Documented and systematized named colours.
+
+------------------------------------------------------------------------
+r1391 | jcbowman | 2006-04-12 21:08:55 -0600 (Wed, 12 Apr 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/slide.asy
+
+Respect orientation.
+
+------------------------------------------------------------------------
+r1390 | jcbowman | 2006-04-12 01:36:26 -0600 (Wed, 12 Apr 2006) | 5 lines
+Changed paths:
+ M /trunk/asymptote/base/Label.asy
+ M /trunk/asymptote/base/slide.asy
+
+
+Improved implementation of slide.asy.
+
+Accept label(frame, Label).
+
+------------------------------------------------------------------------
+r1389 | jcbowman | 2006-04-10 21:01:47 -0600 (Mon, 10 Apr 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/slide.asy
+
+Added subitem and automatic slide advance on overflow.
+
+------------------------------------------------------------------------
+r1388 | jcbowman | 2006-04-10 16:15:55 -0600 (Mon, 10 Apr 2006) | 2 lines
+Changed paths:
+ A /trunk/asymptote/base/slide.asy
+
+Slide presentation package.
+
+------------------------------------------------------------------------
+r1387 | jcbowman | 2006-04-10 15:42:51 -0600 (Mon, 10 Apr 2006) | 9 lines
+Changed paths:
+ M /trunk/asymptote/base/Label.asy
+ M /trunk/asymptote/base/constants.asy
+ M /trunk/asymptote/base/plain.asy
+ M /trunk/asymptote/base/shipout.asy
+ D /trunk/asymptote/base/transforms.asy
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/picture.cc
+ M /trunk/asymptote/runtime.in
+ M /trunk/asymptote/settings.cc
+ M /trunk/asymptote/settings.h
+
+
+Added default orientation variable (initially set to Portrait).
+
+Added custom pagewidth and pageheight settings.
+
+Moved transforms to runtime.in and Label.asy.
+
+Added tex usepackage(string) convenience routine.
+
+------------------------------------------------------------------------
+r1386 | jcbowman | 2006-04-10 15:38:02 -0600 (Mon, 10 Apr 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/asy.1
+
+Indicated default option values in man page summary.
+
+------------------------------------------------------------------------
+r1385 | jcbowman | 2006-04-09 15:00:12 -0600 (Sun, 09 Apr 2006) | 7 lines
+Changed paths:
+ M /trunk/asymptote/Makefile.in
+ M /trunk/asymptote/doc/Makefile
+
+
+Added DESTDIR support: make DESTDIR=DIR will prepend DIR to the
+installation directories (intended as a temporary location to facilitate
+the build process only).
+
+Added -p option to install (and -m 755 to install asy and install xasy).
+
+------------------------------------------------------------------------
+r1384 | jcbowman | 2006-04-09 14:51:32 -0600 (Sun, 09 Apr 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/configure.ac
+
+Fixed name of gsl header in message.
+
+------------------------------------------------------------------------
+r1383 | jcbowman | 2006-04-09 10:13:40 -0600 (Sun, 09 Apr 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/graph.asy
+ M /trunk/asymptote/base/picture.asy
+
+In tick bounds estimate, don't warn about unbounded picture scaling.
+
+------------------------------------------------------------------------
+r1382 | jcbowman | 2006-04-09 01:10:31 -0600 (Sun, 09 Apr 2006) | 3 lines
+Changed paths:
+ M /trunk/asymptote/builtin.cc
+ M /trunk/asymptote/configure.ac
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/stack.cc
+ M /trunk/asymptote/vm.h
+
+Added selected special functions from GNU scientific library, when
+available (additional special functions can easily be added, on request).
+
+------------------------------------------------------------------------
+r1381 | jcbowman | 2006-04-09 00:42:37 -0600 (Sun, 09 Apr 2006) | 4 lines
+Changed paths:
+ M /trunk/asymptote/base/graph.asy
+ M /trunk/asymptote/doc/asymptote.texi
+
+Added Ticks specifier that draws ticks on both sides of path.
+
+Fixed miscellaneous errors in the documentation.
+
+------------------------------------------------------------------------
+r1380 | jcbowman | 2006-04-09 00:39:32 -0600 (Sun, 09 Apr 2006) | 3 lines
+Changed paths:
+ M /trunk/asymptote/base/math.asy
+ M /trunk/asymptote/examples/lines.asy
+ M /trunk/asymptote/examples/star.asy
+
+Renamed zeta to unityroot for clarity (and to avoid confusion with Riemann
+zeta function).
+
+------------------------------------------------------------------------
+r1379 | jcbowman | 2006-04-09 00:37:42 -0600 (Sun, 09 Apr 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/shipout.asy
+ M /trunk/asymptote/base/strings.asy
+
+Moved newpage() routine to shipout().
+
+------------------------------------------------------------------------
+r1378 | jcbowman | 2006-04-09 00:36:59 -0600 (Sun, 09 Apr 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/pens.asy
+
+Added real lineskip() routine (returns lineskip of currentpen).
+
+------------------------------------------------------------------------
+r1377 | jcbowman | 2006-04-09 00:35:33 -0600 (Sun, 09 Apr 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/runtime.in
+
+Fix name of fontsize lineskip argument.
+
+------------------------------------------------------------------------
+r1376 | jcbowman | 2006-04-09 00:34:30 -0600 (Sun, 09 Apr 2006) | 3 lines
+Changed paths:
+ M /trunk/asymptote/interact.cc
+
+
+Remove reliance of replacement readline routine on strdup.
+
+------------------------------------------------------------------------
+r1375 | jcbowman | 2006-04-06 08:05:17 -0600 (Thu, 06 Apr 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/asy-mode.el
+
+Use turn-on-font-lock for Xemacs.
+
+------------------------------------------------------------------------
+r1374 | jcbowman | 2006-04-05 21:29:56 -0600 (Wed, 05 Apr 2006) | 3 lines
+Changed paths:
+ M /trunk/asymptote/base/asy-mode.el
+
+
+Make asy-mode.el ignore global-font-lock-mode for Xemacs.
+
+------------------------------------------------------------------------
+r1373 | jcbowman | 2006-04-05 21:24:09 -0600 (Wed, 05 Apr 2006) | 9 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/main.cc
+ M /trunk/asymptote/runtime.in
+ M /trunk/asymptote/settings.cc
+
+
+Added locale support and ', I, and F format specifiers.
+
+Moved miscellaneous settings code from main.cc to settings.cc.
+
+Added default settings to option summary; identity command-line only options.
+
+Updated documentation.
+
+------------------------------------------------------------------------
+r1372 | jcbowman | 2006-04-05 21:20:58 -0600 (Wed, 05 Apr 2006) | 10 lines
+Changed paths:
+ M /trunk/asymptote/base/picture.asy
+
+
+Improved picture sizing diagnostics.
+
+Added max(picture pic=currentpicture) and min(picture pic=currentpicture)
+functions.
+
+Added pair truepoint(picture pic=currentpicture, pair dir) function that
+works like point but uses the actual picture size instead of userMin and
+userMax members.
+
+------------------------------------------------------------------------
+r1371 | jcbowman | 2006-04-05 21:18:34 -0600 (Wed, 05 Apr 2006) | 3 lines
+Changed paths:
+ M /trunk/asymptote/base/graph.asy
+
+Replace identity() with better approximation pic.calculateTransform() in
+axis picture bounds calculation.
+
+------------------------------------------------------------------------
+r1370 | jcbowman | 2006-04-05 21:17:03 -0600 (Wed, 05 Apr 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/pens.asy
+
+Make colorPen[] and monoPen[] public.
+
+------------------------------------------------------------------------
+r1369 | jcbowman | 2006-04-05 21:16:10 -0600 (Wed, 05 Apr 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/simplex.asy
+
+Fixed typos in comments.
+
+------------------------------------------------------------------------
+r1368 | jcbowman | 2006-04-05 20:22:16 -0600 (Wed, 05 Apr 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/configure.ac
+
+Incremented version to 1.04cvs.
+
+------------------------------------------------------------------------
+r1367 | jcbowman | 2006-03-29 23:08:56 -0700 (Wed, 29 Mar 2006) | 14 lines
+Changed paths:
+ M /trunk/asymptote/base/constants.asy
+ M /trunk/asymptote/base/graph3.asy
+ A /trunk/asymptote/base/solids.asy
+ M /trunk/asymptote/base/three.asy
+ M /trunk/asymptote/doc/asymptote.texi
+ A /trunk/asymptote/doc/cylinder.asy
+ M /trunk/asymptote/runtime.in
+
+Added Degrees function; like degrees(pair) but returns 0 for (0,0) argument.
+
+Added minbound and maxbound functions for triples.
+
+Moved minbound, maxbound, and Longitude functions to runtime code.
+
+Added min(guide3[]) and max(guide3[]) functions.
+
+For convenience added xaxis(triple,real) functions, etc.
+
+Added solid geometry package with cylinder routines.
+
+Updated documentation.
+
+------------------------------------------------------------------------
+r1366 | jcbowman | 2006-03-29 22:27:11 -0700 (Wed, 29 Mar 2006) | 3 lines
+Changed paths:
+ M /trunk/asymptote/path.cc
+ M /trunk/asymptote/path3.cc
+
+Added limit maxIntersectCount=100000 on maximum number of calls to
+intersectcubics per cubic segment.
+
+------------------------------------------------------------------------
+r1365 | jcbowman | 2006-03-28 12:33:39 -0700 (Tue, 28 Mar 2006) | 3 lines
+Changed paths:
+ M /trunk/asymptote/TODO
+
+Removed TODO item regarding extending runnable-at-a-time mode to inner
+code levels as this is no longer needed.
+
+------------------------------------------------------------------------
+r1364 | jcbowman | 2006-03-27 01:13:26 -0700 (Mon, 27 Mar 2006) | 3 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/main.cc
+ D /trunk/asymptote/pool.h
+
+Fixed memory leak in interactive mode by using an implementation of reset
+that is closer to the environment reset used between multiple file runs.
+
+------------------------------------------------------------------------
+r1363 | jcbowman | 2006-03-25 22:15:50 -0700 (Sat, 25 Mar 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+
+Fixed indentation.
+
+------------------------------------------------------------------------
+r1362 | jcbowman | 2006-03-25 22:14:21 -0700 (Sat, 25 Mar 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/genv.cc
+
+Fixed typos.
+
+------------------------------------------------------------------------
+r1361 | jcbowman | 2006-03-25 10:25:37 -0700 (Sat, 25 Mar 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+
+Updated CJK documentation.
+
+------------------------------------------------------------------------
+r1360 | jcbowman | 2006-03-24 21:38:01 -0700 (Fri, 24 Mar 2006) | 6 lines
+Changed paths:
+ M /trunk/asymptote/base/pens.asy
+ M /trunk/asymptote/doc/asymptote.texi
+
+Added real fontsize() routine.
+
+Documented real fontsize(pen p=currentpen).
+
+Documented use of CJK fonts.
+
+------------------------------------------------------------------------
+r1359 | jcbowman | 2006-03-20 21:48:46 -0700 (Mon, 20 Mar 2006) | 11 lines
+Changed paths:
+ M /trunk/asymptote/base/three.asy
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/fileio.h
+ M /trunk/asymptote/interact.cc
+ M /trunk/asymptote/parser.cc
+ M /trunk/asymptote/runtime.in
+ M /trunk/asymptote/util.cc
+
+
+Implemented interactive mode (without command-line editing and history) even
+in absence of readline library.
+
+Made minor change to System diagnostic messages.
+
+Changed invert: triple invert(pair z, triple normal, triple point) projects
+onto the plane perpendicular to normal and passing through point.
+
+Updated Debian URL.
+
+------------------------------------------------------------------------
+r1358 | jcbowman | 2006-03-19 08:17:07 -0700 (Sun, 19 Mar 2006) | 6 lines
+Changed paths:
+ M /trunk/asymptote/base/three.asy
+ M /trunk/asymptote/doc/asy.1
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/settings.cc
+
+
+Added function triple invert(pair v, real z, projection P=currentprojection)
+to map v onto (x,y,z) by inverting the projection P onto a constant z plane.
+
+Minor documentation updates.
+
+------------------------------------------------------------------------
+r1357 | jcbowman | 2006-03-16 23:10:58 -0700 (Thu, 16 Mar 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/pen.h
+ M /trunk/asymptote/triple.h
+
+Support compilation under gcc-4.1.0.
+
+------------------------------------------------------------------------
+r1356 | jcbowman | 2006-03-14 21:36:32 -0700 (Tue, 14 Mar 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/three.asy
+
+Fixed return type of three-dimensional intersectionpoint routines.
+
+------------------------------------------------------------------------
+r1355 | jcbowman | 2006-03-12 13:21:27 -0700 (Sun, 12 Mar 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/configure.ac
+
+Incremented version to 1.03cvs.
+
+------------------------------------------------------------------------
+r1354 | jcbowman | 2006-03-12 11:27:03 -0700 (Sun, 12 Mar 2006) | 4 lines
+Changed paths:
+ M /trunk/asymptote/base/graph3.asy
+ M /trunk/asymptote/main.cc
+
+Fixed surface lighting colours; respect projection argument.
+
+Removed test diagnostic.
+
+------------------------------------------------------------------------
+r1353 | hammera | 2006-03-12 11:17:32 -0700 (Sun, 12 Mar 2006) | 3 lines
+Changed paths:
+ M /trunk/asymptote/tests/output/Makefile
+
+Added a .ls file to check the presence of large output files before they are
+deleted.
+
+------------------------------------------------------------------------
+r1352 | jcbowman | 2006-03-12 09:05:51 -0700 (Sun, 12 Mar 2006) | 4 lines
+Changed paths:
+ M /trunk/asymptote/interact.cc
+ M /trunk/asymptote/picture.cc
+ M /trunk/asymptote/runtime.in
+ M /trunk/asymptote/settings.cc
+ M /trunk/asymptote/util.cc
+
+Avoid need for single quotes around path settings in MSWINDOWS.
+
+Fix configuration diagnostics.
+
+------------------------------------------------------------------------
+r1351 | jcbowman | 2006-03-11 22:03:49 -0700 (Sat, 11 Mar 2006) | 4 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+
+Documented how to install in alternate locations under MSDOS.
+
+Fixed typo in configuration instructions.
+
+------------------------------------------------------------------------
+r1350 | jcbowman | 2006-03-11 16:33:51 -0700 (Sat, 11 Mar 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/examples/sinc.asy
+
+Simplified example.
+
+------------------------------------------------------------------------
+r1349 | jcbowman | 2006-03-11 16:16:25 -0700 (Sat, 11 Mar 2006) | 16 lines
+Changed paths:
+ M /trunk/asymptote/base/graph3.asy
+ M /trunk/asymptote/base/light.asy
+ M /trunk/asymptote/base/three.asy
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/doc/surface.asy
+ A /trunk/asymptote/examples/sinc.asy
+
+Implemented surface lighting and example of sinc function.
+
+Changed signature of subsampled surface routine (argument nsub now preceeds
+pairs a and b).
+
+Changed light.init constructor into
+light(triple source, shadefcn shade=defaultshade).
+
+Added cast from triple to light.
+
+Made currentlight public; added nolight variable.
+
+Renamed projectXY to xypart.
+
+Added XY() and XYZ() members to bbox3.
+
+------------------------------------------------------------------------
+r1348 | jcbowman | 2006-03-11 15:39:34 -0700 (Sat, 11 Mar 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/graph.asy
+
+Fixed axis label alignment when sign=-1.
+
+------------------------------------------------------------------------
+r1347 | jcbowman | 2006-03-10 21:18:54 -0700 (Fri, 10 Mar 2006) | 3 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/patches/README
+ D /trunk/asymptote/patches/pstoedit-3.43asy.patch
+
+
+Removed pstoedit patches (included in pstoedit-3.44); updated documentation.
+
+------------------------------------------------------------------------
+r1346 | jcbowman | 2006-03-10 12:19:57 -0700 (Fri, 10 Mar 2006) | 8 lines
+Changed paths:
+ M /trunk/asymptote/Makefile.in
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/runtime.in
+
+
+Allow make to inherit LDFLAGS from configure.
+
+Allow and document installation without root privileges.
+
+Document configuring to search for includes and libraries in nonstandard
+locations.
+
+------------------------------------------------------------------------
+r1345 | jcbowman | 2006-03-09 23:19:06 -0700 (Thu, 09 Mar 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+
+Updated configuration file documentation.
+
+------------------------------------------------------------------------
+r1344 | jcbowman | 2006-03-09 20:54:33 -0700 (Thu, 09 Mar 2006) | 8 lines
+Changed paths:
+ M /trunk/asymptote/main.cc
+ M /trunk/asymptote/settings.cc
+
+
+Catch errors thrown by parser while reading configuration file.
+
+Recompute search path after reading configuration files and command-line
+options in case dir was changed.
+
+Move MSWindows .asy initialization directory to %USERPROFILE%.
+
+------------------------------------------------------------------------
+r1343 | jcbowman | 2006-03-07 12:37:44 -0700 (Tue, 07 Mar 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/builtin.cc
+
+Fixed type of randMax.
+
+------------------------------------------------------------------------
+r1342 | jcbowman | 2006-03-07 03:01:26 -0700 (Tue, 07 Mar 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/pstoedit.asy
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/examples/animations/wheel.asy
+ D /trunk/asymptote/patches/pstoedit-3.42asy.patch
+ A /trunk/asymptote/patches/pstoedit-3.43asy.patch
+
+Updated pstoedit patch.
+
+------------------------------------------------------------------------
+r1341 | jcbowman | 2006-03-06 19:29:18 -0700 (Mon, 06 Mar 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/configure.ac
+
+Incremented version to 1.02cvs.
+
+------------------------------------------------------------------------
+r1340 | jcbowman | 2006-03-06 17:23:18 -0700 (Mon, 06 Mar 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/graph3.asy
+ M /trunk/asymptote/doc/asymptote.texi
+
+Fixed bug in surface plot of a matrix.
+
+------------------------------------------------------------------------
+r1339 | jcbowman | 2006-03-06 13:58:35 -0700 (Mon, 06 Mar 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/configure.ac
+
+Incremented version to 1.01cvs.
+
+------------------------------------------------------------------------
+r1338 | jcbowman | 2006-03-06 09:33:54 -0700 (Mon, 06 Mar 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/configure.ac
+ M /trunk/asymptote/runtime.in
+
+Workaround broken GNU readline/history library on MacOS.
+
+------------------------------------------------------------------------
+r1337 | jcbowman | 2006-03-06 00:10:54 -0700 (Mon, 06 Mar 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/runtime.in
+
+Fixed cxx warning messages.
+
+------------------------------------------------------------------------
+r1336 | jcbowman | 2006-03-05 23:19:09 -0700 (Sun, 05 Mar 2006) | 3 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+
+Moved detailed discussion of growing list of base modules closer to the end
+of the documentation.
+
+------------------------------------------------------------------------
+r1335 | jcbowman | 2006-03-05 22:52:10 -0700 (Sun, 05 Mar 2006) | 4 lines
+Changed paths:
+ M /trunk/asymptote/base/filldraw.asy
+ M /trunk/asymptote/configure.ac
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/examples/poster.asy
+
+Updated to use gc6.7 by default.
+
+Added RadialShade filltype.
+
+------------------------------------------------------------------------
+r1334 | jcbowman | 2006-03-05 22:03:49 -0700 (Sun, 05 Mar 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/arrows.asy
+
+Remove blank legend entries.
+
+------------------------------------------------------------------------
+r1333 | jcbowman | 2006-03-05 21:46:24 -0700 (Sun, 05 Mar 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/pen.h
+
+Fixed pen bounds (too large by a factor of 2).
+
+------------------------------------------------------------------------
+r1332 | jcbowman | 2006-03-05 20:37:48 -0700 (Sun, 05 Mar 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/palette.asy
+
+Fixed transformation of palette bar.
+
+------------------------------------------------------------------------
+r1331 | jcbowman | 2006-03-05 18:45:09 -0700 (Sun, 05 Mar 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/graph.asy
+
+Removed empty picture check in xlimits and ylimits.
+
+------------------------------------------------------------------------
+r1330 | jcbowman | 2006-03-05 18:02:27 -0700 (Sun, 05 Mar 2006) | 12 lines
+Changed paths:
+ M /trunk/asymptote/base/arrows.asy
+ M /trunk/asymptote/base/markers.asy
+ M /trunk/asymptote/base/math.asy
+ M /trunk/asymptote/base/palette.asy
+ M /trunk/asymptote/base/picture.asy
+ M /trunk/asymptote/castop.h
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/fileio.cc
+ M /trunk/asymptote/fileio.h
+ M /trunk/asymptote/runtime.in
+
+Moved linear solve and matrix inversion to C++ code; simplified memory
+allocation in tridiagonal.
+
+Added seek and tell functions for positioning input files.
+
+Make images transform properly.
+
+Make legend argument to draw a Label type (currently only the string and pen
+members are used). Added length and skip arguments to frame legend(...).
+
+Removed side effects from eol(file).
+
+------------------------------------------------------------------------
+r1329 | jcbowman | 2006-03-04 21:25:50 -0700 (Sat, 04 Mar 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/runtime.pl
+
+Generate correct #line comments.
+
+------------------------------------------------------------------------
+r1328 | hammera | 2006-03-04 16:17:55 -0700 (Sat, 04 Mar 2006) | 5 lines
+Changed paths:
+ M /trunk/asymptote/tests/output/Makefile
+
+Log the stdout and stderr of the asy process.
+
+Changed the -inlinetex option to -keep so that the calls to external programs
+(eg. latex and convert) can be diffed.
+
+------------------------------------------------------------------------
+r1327 | hammera | 2006-03-04 15:47:12 -0700 (Sat, 04 Mar 2006) | 3 lines
+Changed paths:
+ M /trunk/asymptote/picture.cc
+ M /trunk/asymptote/picture.h
+ M /trunk/asymptote/pipestream.h
+
+Now delete texput.log when the pipe to the tex process is closed (to ensure its
+deletion with the --inlinetex option). Also delete texput.aux.
+
+------------------------------------------------------------------------
+r1326 | jcbowman | 2006-03-03 08:56:54 -0700 (Fri, 03 Mar 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/math.asy
+
+Fixed bug in pivot vectorization in solve.
+
+------------------------------------------------------------------------
+r1325 | hammera | 2006-03-02 12:46:57 -0700 (Thu, 02 Mar 2006) | 2 lines
+Changed paths:
+ A /trunk/asymptote/tests/output
+ A /trunk/asymptote/tests/output/Makefile
+ A /trunk/asymptote/tests/output/circle.asy
+ A /trunk/asymptote/tests/output/line.asy
+
+Initial check-in of output testing.
+
+------------------------------------------------------------------------
+r1324 | jcbowman | 2006-03-01 12:02:39 -0700 (Wed, 01 Mar 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/configure.ac
+
+Added INCL for enable-gc=system.
+
+------------------------------------------------------------------------
+r1323 | jcbowman | 2006-02-27 00:54:06 -0700 (Mon, 27 Feb 2006) | 12 lines
+Changed paths:
+ A /trunk/asymptote/base/embed.asy
+ M /trunk/asymptote/base/picture.asy
+ M /trunk/asymptote/base/strings.asy
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/examples/animations/wheel.asy
+ M /trunk/asymptote/examples/orthocenter.asy
+ M /trunk/asymptote/picture.cc
+ M /trunk/asymptote/texfile.h
+
+
+Renamed includegraphics to graphic.
+
+Added embed module to interface with LaTeX movie15 package for embedding
+movies, sounds and 3D objects into a PDF file.
+
+Don't attempt to resize unbounded pictures.
+
+Output LaTeX pipe diagnostics even when verbose <= 1.
+
+Added \begin{document} to LaTeX pipe.
+
+------------------------------------------------------------------------
+r1322 | jcbowman | 2006-02-26 21:59:42 -0700 (Sun, 26 Feb 2006) | 2 lines
+Changed paths:
+ A /trunk/asymptote/examples/poster.asy
+
+Added poster example.
+
+------------------------------------------------------------------------
+r1321 | jcbowman | 2006-02-19 19:59:50 -0700 (Sun, 19 Feb 2006) | 5 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/main.cc
+ M /trunk/asymptote/runtime.in
+ M /trunk/asymptote/settings.cc
+
+Add configuration dir to search path; search for configuration file in
+standard search paths (in usual order).
+
+Remember defaultpen set in configuration file.
+
+------------------------------------------------------------------------
+r1320 | jcbowman | 2006-02-19 10:03:00 -0700 (Sun, 19 Feb 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/arrows.asy
+
+Always draw arrows with solid linetype.
+
+------------------------------------------------------------------------
+r1319 | jcbowman | 2006-02-18 12:31:50 -0700 (Sat, 18 Feb 2006) | 11 lines
+Changed paths:
+ M /trunk/asymptote/base/graph.asy
+ M /trunk/asymptote/castop.h
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/mathop.h
+ M /trunk/asymptote/runtime.in
+ M /trunk/asymptote/settings.cc
+ M /trunk/asymptote/stack.cc
+ M /trunk/asymptote/vm.h
+
+
+Updated MSDOS default of gs8.51 to gs8.53.
+
+Changed default for xlimits and ylimits to NoCrop.
+
+Work around unused variable warning messages when XDR support is disabled.
+
+Cleaned up error calls.
+
+Updated documentation.
+
+------------------------------------------------------------------------
+r1318 | jcbowman | 2006-02-17 21:17:15 -0700 (Fri, 17 Feb 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/Makefile.in
+
+Added missing $(GCLIBS) dependency.
+
+------------------------------------------------------------------------
+r1317 | jcbowman | 2006-02-17 19:57:33 -0700 (Fri, 17 Feb 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/Makefile.in
+
+Added camp.tab.h entry again.
+
+------------------------------------------------------------------------
+r1316 | jcbowman | 2006-02-08 11:45:48 -0700 (Wed, 08 Feb 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/filldraw.asy
+
+Removed +solid from Fill and NoFill.
+
+------------------------------------------------------------------------
+r1315 | jcbowman | 2006-02-08 09:06:36 -0700 (Wed, 08 Feb 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/runtime.in
+
+Added missing xpart, ypart, zpart functions for triples.
+
+------------------------------------------------------------------------
+r1314 | jcbowman | 2006-02-07 22:13:08 -0700 (Tue, 07 Feb 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/palette.asy
+ M /trunk/asymptote/psfile.cc
+
+Fixed reversed image dimensions for colour density plots.
+
+------------------------------------------------------------------------
+r1313 | jcbowman | 2006-02-07 22:06:39 -0700 (Tue, 07 Feb 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/runtime.in
+
+Added missing xpart and ypart functions.
+
+------------------------------------------------------------------------
+r1312 | jcbowman | 2006-02-06 00:58:25 -0700 (Mon, 06 Feb 2006) | 4 lines
+Changed paths:
+ M /trunk/asymptote/camperror.cc
+ M /trunk/asymptote/picture.cc
+
+Signal an error if write to final output file fails.
+
+Removed "camp: " from camp error messages for brevity.
+
+------------------------------------------------------------------------
+r1311 | jcbowman | 2006-01-28 21:32:32 -0700 (Sat, 28 Jan 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+
+Added link to Dario Teixeira's Asymptote and LaTeX Integration Guide.
+
+------------------------------------------------------------------------
+r1310 | jcbowman | 2006-01-28 19:43:37 -0700 (Sat, 28 Jan 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/animate.asy
+ M /trunk/asymptote/runtime.in
+
+Added file prefix option to animate and merge.
+
+------------------------------------------------------------------------
+r1309 | jcbowman | 2006-01-28 03:25:25 -0700 (Sat, 28 Jan 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+
+Added index entries.
+
+------------------------------------------------------------------------
+r1308 | jcbowman | 2006-01-27 23:28:16 -0700 (Fri, 27 Jan 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/runtime.in
+
+Allow format("%",1).
+
+------------------------------------------------------------------------
+r1307 | jcbowman | 2006-01-27 23:04:49 -0700 (Fri, 27 Jan 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/graph.asy
+
+Set tickMin to a and tickMax to b if Step is 0.
+
+------------------------------------------------------------------------
+r1306 | jcbowman | 2006-01-17 13:17:27 -0700 (Tue, 17 Jan 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/graph.asy
+
+Added check for empty picture in xlimits and ylimits.
+
+------------------------------------------------------------------------
+r1305 | jcbowman | 2006-01-17 13:12:17 -0700 (Tue, 17 Jan 2006) | 5 lines
+Changed paths:
+ M /trunk/asymptote/Makefile.in
+ M /trunk/asymptote/runtime.in
+ M /trunk/asymptote/settings.cc
+
+Better dependency tracking.
+
+Removed MSDOS compiler flag in favour of __CYGWIN__. This will make cygwin
+defaults identical with those under MSDOS (outside of cygwin).
+
+------------------------------------------------------------------------
+r1304 | jcbowman | 2006-01-17 00:36:01 -0700 (Tue, 17 Jan 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/interact.cc
+
+Fixed cxx warning.
+
+------------------------------------------------------------------------
+r1303 | jcbowman | 2006-01-16 23:45:28 -0700 (Mon, 16 Jan 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/Makefile.in
+ M /trunk/asymptote/runtime.pl
+
+Added Tom's alternative way of making runtime.pl not update runtime.h.
+
+------------------------------------------------------------------------
+r1302 | jcbowman | 2006-01-14 16:20:05 -0700 (Sat, 14 Jan 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/asy.1
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/settings.cc
+
+Documented inlinetex mode.
+
+------------------------------------------------------------------------
+r1301 | jcbowman | 2006-01-14 16:10:11 -0700 (Sat, 14 Jan 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/feynman.asy
+
+Updates to feyman.asy: improved photon line, use align structures.
+
+------------------------------------------------------------------------
+r1300 | jcbowman | 2006-01-10 23:40:36 -0700 (Tue, 10 Jan 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/runtime.pl
+
+Added #line directives in runtime.cc.
+
+------------------------------------------------------------------------
+r1299 | jcbowman | 2006-01-10 14:18:01 -0700 (Tue, 10 Jan 2006) | 4 lines
+Changed paths:
+ M /trunk/asymptote/pair.h
+ M /trunk/asymptote/runtime.in
+
+Fixed segmentation fault when bad format string is given to format.
+
+Fixed cast: (pair) "1".
+
+------------------------------------------------------------------------
+r1298 | hammera | 2006-01-06 21:57:38 -0700 (Fri, 06 Jan 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/three.asy
+
+Added transform3 multiplication (aliased from math).
+
+------------------------------------------------------------------------
+r1297 | jcbowman | 2006-01-03 22:45:46 -0700 (Tue, 03 Jan 2006) | 4 lines
+Changed paths:
+ M /trunk/asymptote/TODO
+ M /trunk/asymptote/base/math.asy
+ M /trunk/asymptote/base/strings.asy
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/interact.cc
+ M /trunk/asymptote/runtime.in
+
+Don't exit interactive mode on EOF (ctrl-d).
+
+Added tab completion option and default prompt="" to readline.
+
+------------------------------------------------------------------------
+r1296 | jcbowman | 2006-01-03 01:58:20 -0700 (Tue, 03 Jan 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/settings.cc
+
+Fixed cxx error.
+
+------------------------------------------------------------------------
+r1295 | jcbowman | 2006-01-02 23:16:01 -0700 (Mon, 02 Jan 2006) | 5 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/runtime.in
+
+
+Changed complement to int[] complement(int[] a, int n);
+this returns the complement of the integer array a in {1,2,...,n}, so that
+b[complement(a,b.length)] yields the complement of b[a].
+
+------------------------------------------------------------------------
+r1294 | jcbowman | 2006-01-02 23:13:52 -0700 (Mon, 02 Jan 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/Makefile.in
+
+Removed unused line.
+
+------------------------------------------------------------------------
+r1293 | jcbowman | 2006-01-02 18:52:58 -0700 (Mon, 02 Jan 2006) | 17 lines
+Changed paths:
+ M /trunk/asymptote/Makefile.in
+ M /trunk/asymptote/base/strings.asy
+ M /trunk/asymptote/camp.l
+ M /trunk/asymptote/dec.h
+ M /trunk/asymptote/doc/asy.1
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/interact.cc
+ M /trunk/asymptote/interact.h
+ M /trunk/asymptote/main.cc
+ M /trunk/asymptote/runtime.in
+ M /trunk/asymptote/settings.cc
+ M /trunk/asymptote/settings.h
+ M /trunk/asymptote/types.cc
+ M /trunk/asymptote/types.h
+
+
+Added interface to GNU readline library to allow editing with history when
+reading data from stdin. Updated getstring, getreal, etc. in strings.asy to
+use this new readline function.
+
+Added complement(int[] a, T[] b) function to return the complement of the
+integer array a in {1,2,...,b.length}, so that b[complement(a,b)] yields the
+complement of b[a].
+
+Generated dataSettings from a templated struct; added intSetting.
+
+Added historylines option (default is still 1000).
+
+Added array check to arrayConditional.
+
+Updated documentation.
+
+------------------------------------------------------------------------
+r1292 | jcbowman | 2006-01-02 18:25:08 -0700 (Mon, 02 Jan 2006) | 2 lines
+Changed paths:
+ M /trunk/asymptote/entry.h
+
+Formatted.
+
+------------------------------------------------------------------------
+r1291 | jcbowman | 2006-01-01 03:41:06 -0700 (Sun, 01 Jan 2006) | 4 lines
+Changed paths:
+ M /trunk/asymptote/main.cc
+
+Move more initialization code before setOptions.
+
+Check em in signal handlers.
+
+------------------------------------------------------------------------
+r1290 | jcbowman | 2005-12-31 11:22:58 -0700 (Sat, 31 Dec 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/settings.cc
+
+Address compilation problem under MacOS X 10.3.9.
+
+------------------------------------------------------------------------
+r1289 | jcbowman | 2005-12-30 23:19:29 -0700 (Fri, 30 Dec 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/configure.ac
+
+Incremented version to 1.00cvs.
+
+------------------------------------------------------------------------
+r1288 | jcbowman | 2005-12-30 22:35:36 -0700 (Fri, 30 Dec 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+
+Minor documentation updates.
+
+------------------------------------------------------------------------
+r1287 | jcbowman | 2005-12-30 22:05:36 -0700 (Fri, 30 Dec 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/settings.cc
+
+Added missing (mem::string).
+
+------------------------------------------------------------------------
+r1286 | jcbowman | 2005-12-30 17:54:53 -0700 (Fri, 30 Dec 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/settings.cc
+
+Defer initialization of settingsModule to solve race condition.
+
+------------------------------------------------------------------------
+r1285 | jcbowman | 2005-12-30 12:21:12 -0700 (Fri, 30 Dec 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/main.cc
+
+Fixed MacOS bus error by initializing GC before calling setOptions.
+
+------------------------------------------------------------------------
+r1284 | jcbowman | 2005-12-30 12:11:10 -0700 (Fri, 30 Dec 2005) | 6 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/main.cc
+ M /trunk/asymptote/wce
+
+Don't stop running after first error in a runnable if -debug is set.
+
+Updated wce.
+
+Documented contributed MacOS X binary.
+
+------------------------------------------------------------------------
+r1283 | jcbowman | 2005-12-30 01:56:51 -0700 (Fri, 30 Dec 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/configure.ac
+
+Incremented version to 0.99cvs.
+
+------------------------------------------------------------------------
+r1282 | jcbowman | 2005-12-30 01:06:29 -0700 (Fri, 30 Dec 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+
+Minor documentation updates.
+
+------------------------------------------------------------------------
+r1281 | jcbowman | 2005-12-30 00:54:53 -0700 (Fri, 30 Dec 2005) | 12 lines
+Changed paths:
+ M /trunk/asymptote/builtin.cc
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/interact.cc
+ M /trunk/asymptote/main.cc
+ M /trunk/asymptote/picture.cc
+ M /trunk/asymptote/refaccess.h
+ M /trunk/asymptote/runtime.in
+ M /trunk/asymptote/settings.cc
+ M /trunk/asymptote/util.cc
+
+
+Fixed compilation problem under g++-3.3.4.
+
+Change addConstant to use item.
+
+Search in usual paths for config.asy if ~/.asy/config.asy is not found.
+
+Convert configuration variable names to lower case.
+
+Update diagnostics and documentation: emphasize use of configuration
+variables instead of system environment variables.
+
+------------------------------------------------------------------------
+r1280 | jcbowman | 2005-12-29 20:38:05 -0700 (Thu, 29 Dec 2005) | 3 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/doc/latexusage.tex
+
+Removed mention of obsolete -t option from documentation, which is no
+longer required for inline tex mode.
+
+------------------------------------------------------------------------
+r1279 | jcbowman | 2005-12-29 18:52:38 -0700 (Thu, 29 Dec 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/builtin.cc
+ M /trunk/asymptote/genv.cc
+ M /trunk/asymptote/main.cc
+ M /trunk/asymptote/refaccess.cc
+ M /trunk/asymptote/refaccess.h
+ M /trunk/asymptote/runtime.in
+ M /trunk/asymptote/settings.cc
+ M /trunk/asymptote/settings.h
+
+Fixed cxx errors.
+
+------------------------------------------------------------------------
+r1278 | jcbowman | 2005-12-29 16:40:42 -0700 (Thu, 29 Dec 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/picture.asy
+
+Suppress warning messages when shipping out an empty picture.
+
+------------------------------------------------------------------------
+r1277 | jcbowman | 2005-12-29 12:01:06 -0700 (Thu, 29 Dec 2005) | 8 lines
+Changed paths:
+ M /trunk/asymptote/base/constants.asy
+ M /trunk/asymptote/base/filldraw.asy
+ M /trunk/asymptote/base/graph.asy
+ M /trunk/asymptote/base/simplex.asy
+ M /trunk/asymptote/base/stats.asy
+ M /trunk/asymptote/base/three.asy
+ M /trunk/asymptote/builtin.cc
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/main.cc
+ M /trunk/asymptote/runtime.in
+ M /trunk/asymptote/settings.cc
+
+Implemented machine constants as variables rather than functions.
+
+Added ASYMPTOTE_CONFIG environment variable.
+
+Moved ASYMPTOTE_DIR environment variable to settings.
+
+Do an initial read of command line in case CONFIG or DIR were specified.
+
+------------------------------------------------------------------------
+r1276 | jcbowman | 2005-12-29 01:32:35 -0700 (Thu, 29 Dec 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/builtin.cc
+ M /trunk/asymptote/main.cc
+ M /trunk/asymptote/picture.cc
+ M /trunk/asymptote/settings.cc
+ M /trunk/asymptote/settings.h
+
+Moved ASYMPTOTE_PAPERTYPE to settings.
+
+------------------------------------------------------------------------
+r1275 | hammera | 2005-12-29 00:49:29 -0700 (Thu, 29 Dec 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/util.cc
+
+Moved argument parsing to avoid writing to memory between a fork and an exec.
+
+------------------------------------------------------------------------
+r1274 | jcbowman | 2005-12-29 00:24:38 -0700 (Thu, 29 Dec 2005) | 5 lines
+Changed paths:
+ M /trunk/asymptote/interact.cc
+ M /trunk/asymptote/main.cc
+ M /trunk/asymptote/picture.cc
+ M /trunk/asymptote/runtime.in
+ M /trunk/asymptote/settings.cc
+ M /trunk/asymptote/settings.h
+
+
+Moved environment variables into settings.
+
+Call doConfig before reading command line options.
+
+------------------------------------------------------------------------
+r1273 | jcbowman | 2005-12-28 22:43:14 -0700 (Wed, 28 Dec 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/constants.asy
+ M /trunk/asymptote/builtin.cc
+ M /trunk/asymptote/runtime.in
+
+Implemented addConstant and pi example.
+
+------------------------------------------------------------------------
+r1272 | jcbowman | 2005-12-28 10:16:22 -0700 (Wed, 28 Dec 2005) | 13 lines
+Changed paths:
+ M /trunk/asymptote/dec.cc
+ M /trunk/asymptote/doc/asy.1
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/interact.cc
+ M /trunk/asymptote/main.cc
+ M /trunk/asymptote/picture.cc
+ M /trunk/asymptote/settings.cc
+
+
+Removed ~/.asy/options in favour of ~/.asy/config.asy.
+
+Add "Including filename" diagostic.
+
+Fixed localhistory.
+
+Speed up initialization by turning off autoplain when reading configure file.
+
+Rename position to align.
+
+Updated documentation.
+
+------------------------------------------------------------------------
+r1271 | jcbowman | 2005-12-28 00:15:07 -0700 (Wed, 28 Dec 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/runtime.in
+
+Fixed verbose flag.
+
+------------------------------------------------------------------------
+r1270 | jcbowman | 2005-12-28 00:10:28 -0700 (Wed, 28 Dec 2005) | 11 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.sty
+ M /trunk/asymptote/drawlabel.cc
+ M /trunk/asymptote/exp.cc
+ M /trunk/asymptote/genv.cc
+ M /trunk/asymptote/guide.h
+ M /trunk/asymptote/knot.cc
+ M /trunk/asymptote/main.cc
+ M /trunk/asymptote/picture.cc
+ M /trunk/asymptote/pipestream.h
+ M /trunk/asymptote/settings.cc
+ M /trunk/asymptote/settings.h
+ M /trunk/asymptote/stack.cc
+ M /trunk/asymptote/texfile.cc
+ M /trunk/asymptote/texfile.h
+ M /trunk/asymptote/util.cc
+
+
+Removed -t option, which is no longer needed to produce inline tex code.
+
+Removed unused settings code.
+
+Added -nov option.
+
+Improved formatting of option messages.
+
+Hide oneFileView and inlinetex (formerly texmode) from help menu.
+
+------------------------------------------------------------------------
+r1269 | jcbowman | 2005-12-26 14:38:04 -0700 (Mon, 26 Dec 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/graph.asy
+ M /trunk/asymptote/base/picture.asy
+
+Fixed tick computation in xaxis and yaxis when explicit limits are given.
+
+------------------------------------------------------------------------
+r1268 | hammera | 2005-12-24 18:15:55 -0700 (Sat, 24 Dec 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/settings.cc
+
+Removed the -n, -no option in favour of -blah/-noblah style negations.
+
+------------------------------------------------------------------------
+r1267 | hammera | 2005-12-24 00:42:42 -0700 (Sat, 24 Dec 2005) | 3 lines
+Changed paths:
+ M /trunk/asymptote/settings.cc
+
+Improved error reporting when parsing command line options
+Autogenerate -help output.
+
+------------------------------------------------------------------------
+r1266 | hammera | 2005-12-23 22:39:56 -0700 (Fri, 23 Dec 2005) | 4 lines
+Changed paths:
+ M /trunk/asymptote/Makefile.in
+ M /trunk/asymptote/access.cc
+ M /trunk/asymptote/access.h
+ M /trunk/asymptote/coder.cc
+ M /trunk/asymptote/coder.h
+ M /trunk/asymptote/dec.cc
+ M /trunk/asymptote/drawlabel.cc
+ M /trunk/asymptote/exp.cc
+ M /trunk/asymptote/genv.cc
+ M /trunk/asymptote/guide.h
+ M /trunk/asymptote/interact.cc
+ M /trunk/asymptote/knot.cc
+ M /trunk/asymptote/locate.h
+ M /trunk/asymptote/main.cc
+ M /trunk/asymptote/pen.h
+ M /trunk/asymptote/picture.cc
+ M /trunk/asymptote/pipestream.h
+ M /trunk/asymptote/record.cc
+ M /trunk/asymptote/record.h
+ A /trunk/asymptote/refaccess.cc
+ A /trunk/asymptote/refaccess.h
+ M /trunk/asymptote/runtime.in
+ M /trunk/asymptote/settings.cc
+ M /trunk/asymptote/settings.h
+ M /trunk/asymptote/stack.cc
+ M /trunk/asymptote/texfile.cc
+ M /trunk/asymptote/texfile.h
+ M /trunk/asymptote/util.cc
+
+Added a settings module. Re-implemented command line options to modify
+variables of the settings module. Added refaccess to access C++ variables as
+Asymptote variables.
+
+------------------------------------------------------------------------
+r1265 | jcbowman | 2005-12-21 22:22:04 -0700 (Wed, 21 Dec 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/fileio.cc
+ M /trunk/asymptote/fileio.h
+
+Fixed string reads.
+
+------------------------------------------------------------------------
+r1264 | jcbowman | 2005-12-17 18:12:21 -0700 (Sat, 17 Dec 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/fileio.cc
+
+Check for cvsmode in ignoreComment.
+
+------------------------------------------------------------------------
+r1263 | jcbowman | 2005-12-17 16:29:17 -0700 (Sat, 17 Dec 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/fileio.cc
+
+Allow comments within 3d data blocks.
+
+------------------------------------------------------------------------
+r1262 | jcbowman | 2005-12-17 14:26:22 -0700 (Sat, 17 Dec 2005) | 6 lines
+Changed paths:
+ M /trunk/asymptote/arrayop.h
+ M /trunk/asymptote/base/Label.asy
+ M /trunk/asymptote/base/arcs.asy
+ M /trunk/asymptote/base/constants.asy
+ M /trunk/asymptote/base/paths.asy
+ M /trunk/asymptote/base/three.asy
+ M /trunk/asymptote/builtin.cc
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/fileio.h
+ M /trunk/asymptote/main.cc
+
+Removed writeP in favour of write.
+
+Stop running after first error in a runnable.
+
+Standardized write argument names.
+
+------------------------------------------------------------------------
+r1261 | jcbowman | 2005-12-17 01:17:37 -0700 (Sat, 17 Dec 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/pens.asy
+
+Added fonts.
+
+------------------------------------------------------------------------
+r1260 | jcbowman | 2005-12-17 01:11:45 -0700 (Sat, 17 Dec 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/builtin.cc
+ M /trunk/asymptote/types.h
+
+Fixed cxx errors and warning messages.
+
+------------------------------------------------------------------------
+r1259 | jcbowman | 2005-12-17 00:54:31 -0700 (Sat, 17 Dec 2005) | 8 lines
+Changed paths:
+ M /trunk/asymptote/TODO
+ M /trunk/asymptote/access.cc
+ M /trunk/asymptote/access.h
+ M /trunk/asymptote/application.cc
+ M /trunk/asymptote/arrayop.h
+ A /trunk/asymptote/base/Label.asy
+ A /trunk/asymptote/base/arcs.asy
+ A /trunk/asymptote/base/arrows.asy
+ A /trunk/asymptote/base/boxes.asy
+ A /trunk/asymptote/base/constants.asy
+ A /trunk/asymptote/base/filldraw.asy
+ M /trunk/asymptote/base/geometry.asy
+ M /trunk/asymptote/base/graph.asy
+ A /trunk/asymptote/base/margins.asy
+ A /trunk/asymptote/base/markers.asy
+ A /trunk/asymptote/base/paths.asy
+ A /trunk/asymptote/base/pens.asy
+ A /trunk/asymptote/base/picture.asy
+ M /trunk/asymptote/base/plain.asy
+ A /trunk/asymptote/base/shipout.asy
+ A /trunk/asymptote/base/strings.asy
+ A /trunk/asymptote/base/transforms.asy
+ M /trunk/asymptote/builtin.cc
+ M /trunk/asymptote/builtin.h
+ M /trunk/asymptote/dec.cc
+ M /trunk/asymptote/dec.h
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/fundec.cc
+ M /trunk/asymptote/fundec.h
+ M /trunk/asymptote/mathop.h
+ M /trunk/asymptote/runtime.in
+ M /trunk/asymptote/runtime.pl
+ M /trunk/asymptote/types.cc
+ M /trunk/asymptote/types.h
+
+Added type-dependent function and record operators to parent record.
+
+Cleaned up builtin.cc.
+
+Moved two- and three-dimensional array min and max functions to C++ code.
+
+Split plain.asy into many subfiles (using include rather than import for speed).
+
+------------------------------------------------------------------------
+r1258 | jcbowman | 2005-12-15 13:29:49 -0700 (Thu, 15 Dec 2005) | 6 lines
+Changed paths:
+ M /trunk/asymptote/base/plain.asy
+ M /trunk/asymptote/builtin.cc
+ M /trunk/asymptote/builtin.h
+ M /trunk/asymptote/runtime.in
+ M /trunk/asymptote/runtime.pl
+
+Allow explicit keywords in autogenerated code.
+
+Moved default arguments from plain.asy to runtime.in.
+
+Respect currentpen nib.
+
+------------------------------------------------------------------------
+r1257 | jcbowman | 2005-12-15 02:58:25 -0700 (Thu, 15 Dec 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/configure.ac
+
+Incremented version to 0.98cvs.
+
+------------------------------------------------------------------------
+r1256 | jcbowman | 2005-12-15 02:07:14 -0700 (Thu, 15 Dec 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/drawelement.h
+ M /trunk/asymptote/pen.h
+ M /trunk/asymptote/runtime.in
+
+Fixed pen transform bug.
+
+------------------------------------------------------------------------
+r1255 | jcbowman | 2005-12-15 00:36:26 -0700 (Thu, 15 Dec 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/interact.cc
+
+Make recent readline startup changes compatible with readline-4.0 under UNIX.
+
+------------------------------------------------------------------------
+r1254 | jcbowman | 2005-12-15 00:13:45 -0700 (Thu, 15 Dec 2005) | 3 lines
+Changed paths:
+ M /trunk/asymptote/base/plain.asy
+ M /trunk/asymptote/builtin.cc
+ M /trunk/asymptote/dec.cc
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/errors
+ M /trunk/asymptote/fundec.cc
+ M /trunk/asymptote/runtime.in
+ M /trunk/asymptote/types.cc
+ M /trunk/asymptote/types.h
+
+Added missing names and fixed incorrect names for builtin function arguments.
+Removed duplicate functions.
+
+------------------------------------------------------------------------
+r1253 | jcbowman | 2005-12-14 22:29:34 -0700 (Wed, 14 Dec 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/interact.cc
+
+Workaround readline incompatibility under MacOS X 10.4.3.
+
+------------------------------------------------------------------------
+r1252 | jcbowman | 2005-12-14 17:47:01 -0700 (Wed, 14 Dec 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/configure.ac
+
+Incremented version to 0.97cvs.
+
+------------------------------------------------------------------------
+r1251 | jcbowman | 2005-12-14 17:08:33 -0700 (Wed, 14 Dec 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/picture.cc
+ M /trunk/asymptote/pipestream.h
+ M /trunk/asymptote/settings.cc
+ M /trunk/asymptote/settings.h
+
+Make MSDOS binary work under both MSWINDOWS and CYGWIN.
+
+------------------------------------------------------------------------
+r1250 | jcbowman | 2005-12-14 01:22:10 -0700 (Wed, 14 Dec 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+
+Fixed spelling.
+
+------------------------------------------------------------------------
+r1249 | jcbowman | 2005-12-14 01:20:27 -0700 (Wed, 14 Dec 2005) | 3 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+
+Document that the -V option under MSDOS is the default only when a single
+file is given.
+
+------------------------------------------------------------------------
+r1248 | jcbowman | 2005-12-14 00:58:29 -0700 (Wed, 14 Dec 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/runtime.in
+
+Fixed cxx warning messages.
+
+------------------------------------------------------------------------
+r1247 | jcbowman | 2005-12-14 00:52:52 -0700 (Wed, 14 Dec 2005) | 7 lines
+Changed paths:
+ M /trunk/asymptote/application.cc
+ M /trunk/asymptote/arrayop.h
+ M /trunk/asymptote/builtin.cc
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/fundec.h
+ M /trunk/asymptote/types.cc
+ M /trunk/asymptote/types.h
+
+Allow explicit keyword in builtin function definitions.
+
+Added write(file fout=stdout, string s="", explicit T[] x ... T[][]);
+function for writing a list of vectors as columns.
+
+Updated documentation of write routines.
+
+------------------------------------------------------------------------
+r1246 | jcbowman | 2005-12-13 22:39:31 -0700 (Tue, 13 Dec 2005) | 3 lines
+Changed paths:
+ M /trunk/asymptote/array.h
+ M /trunk/asymptote/arrayop.h
+ M /trunk/asymptote/builtin.cc
+ M /trunk/asymptote/runtime.in
+
+Fix segmentation fault by checking for null arrays in dotsGuide,
+dashesGuide, and 3d intersect.
+
+------------------------------------------------------------------------
+r1245 | jcbowman | 2005-12-13 15:50:41 -0700 (Tue, 13 Dec 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/runtime.in
+
+Fixed order of autogenerated newAppendedArray arguments.
+
+------------------------------------------------------------------------
+r1244 | jcbowman | 2005-12-13 15:07:35 -0700 (Tue, 13 Dec 2005) | 6 lines
+Changed paths:
+ M /trunk/asymptote/interact.h
+ M /trunk/asymptote/main.cc
+ D /trunk/asymptote/runtime.cc
+ D /trunk/asymptote/runtime.h
+ M /trunk/asymptote/runtime.in
+ M /trunk/asymptote/runtime.pl
+
+Fixed cxx error and warning messages.
+
+Make time(string) simply return format string on systems without strftime.
+
+Removed generated files.
+
+------------------------------------------------------------------------
+r1243 | jcbowman | 2005-12-13 13:21:58 -0700 (Tue, 13 Dec 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/Makefile.in
+ M /trunk/asymptote/arrayop.h
+ M /trunk/asymptote/base/plain.asy
+ M /trunk/asymptote/builtin.cc
+ M /trunk/asymptote/builtin.h
+ M /trunk/asymptote/cast.cc
+ M /trunk/asymptote/castop.h
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/drawclipbegin.h
+ M /trunk/asymptote/env.cc
+ M /trunk/asymptote/env.h
+ M /trunk/asymptote/exp.cc
+ D /trunk/asymptote/genrun.h
+ M /trunk/asymptote/genv.cc
+ M /trunk/asymptote/picture.cc
+ M /trunk/asymptote/picture.h
+ M /trunk/asymptote/runtime.cc
+ M /trunk/asymptote/runtime.h
+ M /trunk/asymptote/runtime.in
+ M /trunk/asymptote/runtime.pl
+ M /trunk/asymptote/types.cc
+
+Autogenerate remaining runtime functions, producing runtime.cc and runtime.h.
+
+------------------------------------------------------------------------
+r1242 | jcbowman | 2005-12-12 02:36:28 -0700 (Mon, 12 Dec 2005) | 7 lines
+Changed paths:
+ M /trunk/asymptote/builtin.cc
+ M /trunk/asymptote/runtime.cc
+ M /trunk/asymptote/runtime.in
+ M /trunk/asymptote/runtime.pl
+ M /trunk/asymptote/transform.h
+
+Make default transform constructor the identity.
+
+Allow operator keyword in autogenerated functions (optional, except for
+operator *).
+
+Autogenerate more runtime functions.
+
+------------------------------------------------------------------------
+r1241 | jcbowman | 2005-12-11 23:06:44 -0700 (Sun, 11 Dec 2005) | 4 lines
+Changed paths:
+ M /trunk/asymptote/builtin.cc
+ M /trunk/asymptote/runtime.cc
+ M /trunk/asymptote/runtime.in
+ M /trunk/asymptote/runtime.pl
+
+Fixed comment handling of runtime.pl; added prototype comments.
+
+Autogenerate remaining array functions.
+
+------------------------------------------------------------------------
+r1240 | jcbowman | 2005-12-11 10:58:39 -0700 (Sun, 11 Dec 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/arrayop.h
+ M /trunk/asymptote/builtin.cc
+ M /trunk/asymptote/runtime.cc
+ M /trunk/asymptote/runtime.h
+ M /trunk/asymptote/runtime.in
+ M /trunk/asymptote/runtime.pl
+
+Autogenerate runtime array operations.
+
+------------------------------------------------------------------------
+r1239 | jcbowman | 2005-12-08 23:12:37 -0700 (Thu, 08 Dec 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/builtin.cc
+ M /trunk/asymptote/runtime.cc
+ M /trunk/asymptote/runtime.in
+
+Autogenerate more runtime functions.
+
+------------------------------------------------------------------------
+r1238 | jcbowman | 2005-12-06 23:48:40 -0700 (Tue, 06 Dec 2005) | 7 lines
+Changed paths:
+ M /trunk/asymptote/base/plain.asy
+ M /trunk/asymptote/builtin.cc
+ M /trunk/asymptote/builtin.h
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/drawlabel.cc
+ M /trunk/asymptote/drawlabel.h
+ M /trunk/asymptote/runtime.cc
+ M /trunk/asymptote/runtime.h
+ M /trunk/asymptote/runtime.in
+ M /trunk/asymptote/runtime.pl
+ M /trunk/asymptote/stack.h
+
+Updated runtime.pl to generate named arguments and optional default values.
+
+Auto-generate many more runtime routines.
+
+Use transform and pen instead of transform* and pen* for consistency with other
+types.
+
+------------------------------------------------------------------------
+r1237 | jcbowman | 2005-12-06 23:37:08 -0700 (Tue, 06 Dec 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/application.h
+
+Fixed recently-introduced memory leak.
+
+------------------------------------------------------------------------
+r1236 | hammera | 2005-12-06 14:50:41 -0700 (Tue, 06 Dec 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/camp.y
+
+Made brackets part of the syntax for 'quote'.
+
+------------------------------------------------------------------------
+r1235 | jcbowman | 2005-12-06 09:09:49 -0700 (Tue, 06 Dec 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/exp.cc
+ M /trunk/asymptote/exp.h
+
+Formatting.
+
+------------------------------------------------------------------------
+r1234 | jcbowman | 2005-12-06 00:38:54 -0700 (Tue, 06 Dec 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/builtin.cc
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/types.h
+
+Implement named arguments for builtin functions.
+
+------------------------------------------------------------------------
+r1233 | jcbowman | 2005-12-06 00:00:26 -0700 (Tue, 06 Dec 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/main.cc
+
+Make translate (-s option) work with eval (requires running codelets).
+
+------------------------------------------------------------------------
+r1232 | hammera | 2005-12-05 19:05:04 -0700 (Mon, 05 Dec 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/application.cc
+ M /trunk/asymptote/application.h
+
+Fixed sequenced evaluation of packed arguments.
+
+------------------------------------------------------------------------
+r1231 | jcbowman | 2005-12-05 00:21:12 -0700 (Mon, 05 Dec 2005) | 7 lines
+Changed paths:
+ M /trunk/asymptote/arrayop.h
+ M /trunk/asymptote/base/plain.asy
+ M /trunk/asymptote/base/three.asy
+ M /trunk/asymptote/builtin.cc
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/doc/makepen.asy
+ M /trunk/asymptote/fileio.h
+ M /trunk/asymptote/fundec.cc
+ M /trunk/asymptote/item.h
+ M /trunk/asymptote/runtime.cc
+ M /trunk/asymptote/runtime.h
+ M /trunk/asymptote/stack.h
+ M /trunk/asymptote/types.h
+ M /trunk/asymptote/varinit.h
+
+
+Optimized isDefault test.
+
+Implemented default function arguments for builtin functions.
+
+Made write routines builtin functions.
+
+------------------------------------------------------------------------
+r1230 | jcbowman | 2005-12-03 22:49:58 -0700 (Sat, 03 Dec 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/fundec.h
+
+Remove obsolete remark about default function arguments.
+
+------------------------------------------------------------------------
+r1229 | jcbowman | 2005-12-02 23:10:00 -0700 (Fri, 02 Dec 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/doc/makepen.asy
+
+Documented makepen, nib, Sin, Cos, Tan, aSin, aCos, aTan, and fontcommand.
+
+------------------------------------------------------------------------
+r1228 | jcbowman | 2005-12-02 22:27:03 -0700 (Fri, 02 Dec 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+
+Documented BeginPoint, MidPoint, EndPoint.
+
+------------------------------------------------------------------------
+r1227 | jcbowman | 2005-12-02 09:44:21 -0700 (Fri, 02 Dec 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/plain.asy
+
+Removed unneeded assignment.
+
+------------------------------------------------------------------------
+r1226 | jcbowman | 2005-12-02 09:14:28 -0700 (Fri, 02 Dec 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/plain.asy
+
+Replaced midarrow routine with generalized arrow routine.
+
+------------------------------------------------------------------------
+r1225 | jcbowman | 2005-12-02 04:00:36 -0700 (Fri, 02 Dec 2005) | 3 lines
+Changed paths:
+ M /trunk/asymptote/base/plain.asy
+
+Do MidArrow and MidArcArrow size adjustment in PostScript rather than user
+coordinates.
+
+------------------------------------------------------------------------
+r1224 | jcbowman | 2005-12-01 23:19:21 -0700 (Thu, 01 Dec 2005) | 5 lines
+Changed paths:
+ M /trunk/asymptote/base/plain.asy
+ A /trunk/asymptote/base/roundedpath.asy
+ M /trunk/asymptote/doc/asymptote.texi
+ A /trunk/asymptote/examples/mosaic.asy
+ A /trunk/asymptote/examples/roundpath.asy
+
+Added contributed examples and a routine to round the sharp corners of a
+path.
+
+Reordered the list of available modules.
+
+------------------------------------------------------------------------
+r1223 | jcbowman | 2005-12-01 20:46:26 -0700 (Thu, 01 Dec 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/pair.h
+ M /trunk/asymptote/path.cc
+
+Handle angle(0,0) condition robustly.
+
+------------------------------------------------------------------------
+r1222 | jcbowman | 2005-12-01 16:10:59 -0700 (Thu, 01 Dec 2005) | 7 lines
+Changed paths:
+ M /trunk/asymptote/base/plain.asy
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/doc/makepen.asy
+ M /trunk/asymptote/pair.h
+ M /trunk/asymptote/path.cc
+
+
+Ignore angle(0,0) errors in dirtime.
+
+Preserve output precision when outputting paths of any length.
+
+Fixed makepen draw routine (makedraw).
+
+------------------------------------------------------------------------
+r1221 | jcbowman | 2005-11-30 23:48:00 -0700 (Wed, 30 Nov 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/plain.asy
+
+Minor optimization of makepen draw.
+
+------------------------------------------------------------------------
+r1220 | jcbowman | 2005-11-30 22:12:08 -0700 (Wed, 30 Nov 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/plain.asy
+ M /trunk/asymptote/doc/makepen.asy
+
+Revert broken optimization of makepen draw.
+
+------------------------------------------------------------------------
+r1219 | jcbowman | 2005-11-30 09:21:12 -0700 (Wed, 30 Nov 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/plain.asy
+
+Simplified makepen draw; extend to cyclic paths.
+
+------------------------------------------------------------------------
+r1218 | jcbowman | 2005-11-30 01:41:52 -0700 (Wed, 30 Nov 2005) | 3 lines
+Changed paths:
+ M /trunk/asymptote/base/plain.asy
+ A /trunk/asymptote/doc/makepen.asy
+ M /trunk/asymptote/pen.h
+ M /trunk/asymptote/runtime.cc
+ M /trunk/asymptote/runtime.in
+
+Added MetaPost-like makepen that works for any polygonal (possibly
+nonconvex) cyclic path.
+
+------------------------------------------------------------------------
+r1217 | jcbowman | 2005-11-29 22:03:47 -0700 (Tue, 29 Nov 2005) | 6 lines
+Changed paths:
+ M /trunk/asymptote/main.cc
+
+
+Call purge after each interactive line to close any files that have gone
+out of scope.
+
+Suppress interactive update on exit.
+
+------------------------------------------------------------------------
+r1216 | jcbowman | 2005-11-28 18:37:48 -0700 (Mon, 28 Nov 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/main.cc
+
+Make estack and sstack static local variables.
+
+------------------------------------------------------------------------
+r1215 | jcbowman | 2005-11-28 18:03:56 -0700 (Mon, 28 Nov 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/graph.asy
+
+Added filltype to labeltick.
+
+------------------------------------------------------------------------
+r1214 | jcbowman | 2005-11-27 22:45:17 -0700 (Sun, 27 Nov 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/picture.cc
+
+Fix -o - with labels.
+
+------------------------------------------------------------------------
+r1213 | jcbowman | 2005-11-27 22:21:02 -0700 (Sun, 27 Nov 2005) | 4 lines
+Changed paths:
+ M /trunk/asymptote/TODO
+ A /trunk/asymptote/base/light.asy
+ M /trunk/asymptote/base/three.asy
+ M /trunk/asymptote/doc/asymptote.texi
+ A /trunk/asymptote/examples/sphere.asy
+ M /trunk/asymptote/picture.cc
+ M /trunk/asymptote/settings.cc
+ M /trunk/asymptote/settings.h
+
+Added example of 3d lighting effects for a sphere, using Gouraud shading.
+
+When running MSDOS binary under CYGWIN, use UNIX line terminator.
+
+------------------------------------------------------------------------
+r1212 | jcbowman | 2005-11-26 16:01:52 -0700 (Sat, 26 Nov 2005) | 4 lines
+Changed paths:
+ M /trunk/asymptote/base/three.asy
+
+Check for null binary space partition.
+
+Move normal==O test to face.
+
+------------------------------------------------------------------------
+r1211 | jcbowman | 2005-11-26 13:53:12 -0700 (Sat, 26 Nov 2005) | 5 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/picture.cc
+
+
+Make -o - work without labels.
+
+Document how to pass options to convert.
+
+------------------------------------------------------------------------
+r1210 | jcbowman | 2005-11-25 16:50:23 -0700 (Fri, 25 Nov 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+
+Minor improvements.
+
+------------------------------------------------------------------------
+r1209 | jcbowman | 2005-11-25 01:51:13 -0700 (Fri, 25 Nov 2005) | 6 lines
+Changed paths:
+ M /trunk/asymptote/base/plain.asy
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/main.cc
+
+
+Added unitsize argument to shipout command (makes user coordinates
+represent multiples of unitsize).
+
+Suppress final call to exitfunction when exiting interactive mode.
+
+------------------------------------------------------------------------
+r1208 | jcbowman | 2005-11-23 23:36:47 -0700 (Wed, 23 Nov 2005) | 6 lines
+Changed paths:
+ M /trunk/asymptote/interact.cc
+ M /trunk/asymptote/settings.cc
+
+Under MSDOS, turn off the default -V option if more than one file is
+specified on the command line.
+
+Under MSDOS, by default bind Delete and Insert keys to delete-char and
+overwrite-mode, respectively.
+
+------------------------------------------------------------------------
+r1207 | jcbowman | 2005-11-23 17:36:54 -0700 (Wed, 23 Nov 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/Makefile.in
+
+Install *.dat and piicon.eps files.
+
+------------------------------------------------------------------------
+r1206 | jcbowman | 2005-11-23 16:37:39 -0700 (Wed, 23 Nov 2005) | 3 lines
+Changed paths:
+ M /trunk/asymptote/interact.h
+ M /trunk/asymptote/picture.cc
+ M /trunk/asymptote/pipestream.h
+ M /trunk/asymptote/runtime.cc
+ M /trunk/asymptote/texfile.cc
+ M /trunk/asymptote/texfile.h
+
+Always destroy tex pipe at cleanup (e.g., in case a label contains a \gdef
+command).
+
+------------------------------------------------------------------------
+r1205 | jcbowman | 2005-11-23 16:35:02 -0700 (Wed, 23 Nov 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/main.cc
+
+Unwrap wrapper.
+
+------------------------------------------------------------------------
+r1204 | jcbowman | 2005-11-23 13:06:56 -0700 (Wed, 23 Nov 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/dec.cc
+
+Fixed segmentation fault with unravel and from access in parse diagnostic.
+
+------------------------------------------------------------------------
+r1203 | jcbowman | 2005-11-23 08:53:43 -0700 (Wed, 23 Nov 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+
+Documented ImageMagick convert dependency of GUI xasy.
+
+------------------------------------------------------------------------
+r1202 | jcbowman | 2005-11-22 22:04:34 -0700 (Tue, 22 Nov 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/asy.1
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/doc/xasy.1x
+ M /trunk/asymptote/settings.cc
+
+Renamed -n option to -nV. Used -n (or -no) to negate next option.
+
+------------------------------------------------------------------------
+r1201 | jcbowman | 2005-11-22 15:25:52 -0700 (Tue, 22 Nov 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/configure.ac
+
+Use kpsewhich to help find default latex path.
+
+------------------------------------------------------------------------
+r1200 | jcbowman | 2005-11-22 14:29:47 -0700 (Tue, 22 Nov 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/main.cc
+ M /trunk/asymptote/parser.cc
+
+Improved diagnostics.
+
+------------------------------------------------------------------------
+r1199 | jcbowman | 2005-11-22 14:24:25 -0700 (Tue, 22 Nov 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/genv.cc
+
+Check for module recursion after call to parseFile.
+
+------------------------------------------------------------------------
+r1198 | jcbowman | 2005-11-22 13:31:44 -0700 (Tue, 22 Nov 2005) | 7 lines
+Changed paths:
+ M /trunk/asymptote/base/graph.asy
+ M /trunk/asymptote/base/plain.asy
+ M /trunk/asymptote/doc/asymptote.texi
+
+
+Removed incorrect (and unnecessary) addPoint call from xaxis and yaxis.
+
+Made axisT readable outside of graph module. Made standard axis types public.
+
+Document custom axis types.
+
+------------------------------------------------------------------------
+r1197 | jcbowman | 2005-11-22 01:19:48 -0700 (Tue, 22 Nov 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/configure.ac
+
+Incremented version to 0.96cvs.
+
+------------------------------------------------------------------------
+r1196 | jcbowman | 2005-11-22 00:04:17 -0700 (Tue, 22 Nov 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+
+Fixed indentation.
+
+------------------------------------------------------------------------
+r1195 | jcbowman | 2005-11-21 23:54:03 -0700 (Mon, 21 Nov 2005) | 11 lines
+Changed paths:
+ M /trunk/asymptote/builtin.cc
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/fileio.h
+ M /trunk/asymptote/interact.cc
+ M /trunk/asymptote/interact.h
+ M /trunk/asymptote/main.cc
+ M /trunk/asymptote/runtime.cc
+ M /trunk/asymptote/runtime.h
+ M /trunk/asymptote/runtime.in
+
+
+Reimplemented reset keyword in interactive mode to restore the environment
+except for the setting of scroll().
+
+Interactive input now does an automatic reset.
+
+Added link to the GNU readline library documentation for customizing
+interactive key bindings.
+
+Fixed hang in scroll mode on EOF.
+
+------------------------------------------------------------------------
+r1194 | jcbowman | 2005-11-21 23:33:20 -0700 (Mon, 21 Nov 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/plain.asy
+
+Move legend.append to appropriate place.
+
+------------------------------------------------------------------------
+r1193 | jcbowman | 2005-11-21 14:15:15 -0700 (Mon, 21 Nov 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/texfile.cc
+ M /trunk/asymptote/texfile.h
+
+Use scalebox only where necessary, to reduce LaTeX memory usage.
+
+------------------------------------------------------------------------
+r1192 | jcbowman | 2005-11-20 14:50:51 -0700 (Sun, 20 Nov 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/application.h
+
+Plugged remaining memory leak.
+
+------------------------------------------------------------------------
+r1191 | jcbowman | 2005-11-20 11:08:29 -0700 (Sun, 20 Nov 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/application.h
+
+Plug another memory leak.
+
+------------------------------------------------------------------------
+r1190 | jcbowman | 2005-11-20 10:41:04 -0700 (Sun, 20 Nov 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/application.h
+
+Fixed memory leak.
+
+------------------------------------------------------------------------
+r1189 | jcbowman | 2005-11-19 11:00:13 -0700 (Sat, 19 Nov 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/main.cc
+
+Put GC warnings under control of -d option.
+
+------------------------------------------------------------------------
+r1188 | jcbowman | 2005-11-18 22:52:49 -0700 (Fri, 18 Nov 2005) | 3 lines
+Changed paths:
+ M /trunk/asymptote/main.cc
+
+Suppress GC warning messages (in particular: "Repeated allocation of very
+large block").
+
+------------------------------------------------------------------------
+r1187 | jcbowman | 2005-11-18 22:46:59 -0700 (Fri, 18 Nov 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/interact.cc
+ M /trunk/asymptote/interact.h
+ M /trunk/asymptote/main.cc
+
+Make interactive input command reset the environment.
+
+------------------------------------------------------------------------
+r1186 | hammera | 2005-11-17 22:21:02 -0700 (Thu, 17 Nov 2005) | 2 lines
+Changed paths:
+ A /trunk/asymptote/tests/imp
+ A /trunk/asymptote/tests/imp/unravel.asy
+
+Added testing for unravel.
+
+------------------------------------------------------------------------
+r1185 | jcbowman | 2005-11-17 09:31:08 -0700 (Thu, 17 Nov 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+
+Removed old documentation.
+
+------------------------------------------------------------------------
+r1184 | jcbowman | 2005-11-17 00:23:28 -0700 (Thu, 17 Nov 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/configure.ac
+
+Incremented version to 0.95cvs.
+
+------------------------------------------------------------------------
+r1183 | jcbowman | 2005-11-16 23:14:51 -0700 (Wed, 16 Nov 2005) | 5 lines
+Changed paths:
+ M /trunk/asymptote/base/plain.asy
+ M /trunk/asymptote/camp.y
+ M /trunk/asymptote/dec.cc
+ M /trunk/asymptote/dec.h
+ M /trunk/asymptote/doc/asymptote.texi
+
+Changed import graph; to abbrevation for access graph; unravel graph.
+Also: import graph as graph2d; means access graph as graph2d; unravel graph2d.
+
+Updated documentation; removed descriptions of old import scheme.
+
+------------------------------------------------------------------------
+r1182 | jcbowman | 2005-11-16 17:25:21 -0700 (Wed, 16 Nov 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.sty
+ M /trunk/asymptote/runtime.in
+
+Force quiet mode with running embedded latex files.
+
+------------------------------------------------------------------------
+r1181 | jcbowman | 2005-11-16 16:51:06 -0700 (Wed, 16 Nov 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/entry.h
+
+Reduce memory usage.
+
+------------------------------------------------------------------------
+r1180 | jcbowman | 2005-11-16 16:07:28 -0700 (Wed, 16 Nov 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/main.cc
+
+Use a vector instead of a list for estack and sstack.
+
+------------------------------------------------------------------------
+r1179 | jcbowman | 2005-11-16 14:31:07 -0700 (Wed, 16 Nov 2005) | 4 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.sty
+ M /trunk/asymptote/texfile.h
+
+Reverse order of pstricks and graphicx also in asymptote.sty.
+
+Fixed formatting.
+
+------------------------------------------------------------------------
+r1178 | hammera | 2005-11-16 14:05:25 -0700 (Wed, 16 Nov 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/entry.cc
+
+Slight refactoring.
+
+------------------------------------------------------------------------
+r1177 | jcbowman | 2005-11-16 13:32:30 -0700 (Wed, 16 Nov 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/texfile.cc
+ M /trunk/asymptote/texfile.h
+
+Workaround scalebox problem with old versions of pstricks.
+
+------------------------------------------------------------------------
+r1176 | hammera | 2005-11-16 12:03:55 -0700 (Wed, 16 Nov 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/geometry.asy
+ M /trunk/asymptote/entry.cc
+ M /trunk/asymptote/entry.h
+ M /trunk/asymptote/exp.h
+ M /trunk/asymptote/name.cc
+ M /trunk/asymptote/name.h
+
+Fixed frame loading issues with imported types.
+
+------------------------------------------------------------------------
+r1175 | jcbowman | 2005-11-16 02:31:20 -0700 (Wed, 16 Nov 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/configure.ac
+
+Incremented version to 0.94cvs.
+
+------------------------------------------------------------------------
+r1174 | jcbowman | 2005-11-16 02:06:51 -0700 (Wed, 16 Nov 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/picture.cc
+
+Fixed cygwin problem.
+
+------------------------------------------------------------------------
+r1173 | jcbowman | 2005-11-16 01:36:10 -0700 (Wed, 16 Nov 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/Makefile
+
+Added mkdir.
+
+------------------------------------------------------------------------
+r1172 | jcbowman | 2005-11-16 01:27:04 -0700 (Wed, 16 Nov 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/texfile.cc
+
+Revert to pstricks colors instead of color.sty due to problems under FreeBSD.
+
+------------------------------------------------------------------------
+r1171 | jcbowman | 2005-11-16 01:14:50 -0700 (Wed, 16 Nov 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/configure.ac
+ M /trunk/asymptote/runtime.in
+
+Workaround missing C99 gamma function under FreeBSD.
+
+------------------------------------------------------------------------
+r1170 | jcbowman | 2005-11-16 00:31:40 -0700 (Wed, 16 Nov 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+
+Documentation updates.
+
+------------------------------------------------------------------------
+r1169 | jcbowman | 2005-11-16 00:24:03 -0700 (Wed, 16 Nov 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/asy-mode.el
+
+Added new keyword.
+
+------------------------------------------------------------------------
+r1168 | jcbowman | 2005-11-16 00:12:02 -0700 (Wed, 16 Nov 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/mathop.h
+
+Fixed more cxx warnings.
+
+------------------------------------------------------------------------
+r1167 | jcbowman | 2005-11-16 00:09:16 -0700 (Wed, 16 Nov 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/settings.cc
+
+Fixed cxx errors and warnings.
+
+------------------------------------------------------------------------
+r1166 | jcbowman | 2005-11-16 00:01:34 -0700 (Wed, 16 Nov 2005) | 2 lines
+Changed paths:
+ A /trunk/asymptote/base/version.asy.in
+
+Version template.
+
+------------------------------------------------------------------------
+r1165 | jcbowman | 2005-11-15 23:49:51 -0700 (Tue, 15 Nov 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/plain.asy
+ M /trunk/asymptote/configure.ac
+ M /trunk/asymptote/runtime.in
+
+Added version check to plain.asy.
+
+------------------------------------------------------------------------
+r1164 | jcbowman | 2005-11-15 23:19:59 -0700 (Tue, 15 Nov 2005) | 6 lines
+Changed paths:
+ M /trunk/asymptote/doc/asy.1
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/interact.cc
+ M /trunk/asymptote/settings.cc
+ M /trunk/asymptote/settings.h
+
+Put history in ~/.asy/history by default unless -localhistory is specified.
+
+Renamed ~/.asyrc to ~/.asy/options
+
+Updated documentation.
+
+------------------------------------------------------------------------
+r1163 | jcbowman | 2005-11-15 21:03:28 -0700 (Tue, 15 Nov 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/settings.cc
+
+Read command line style-parameters from $HOME/.asyrc
+
+------------------------------------------------------------------------
+r1162 | jcbowman | 2005-11-15 17:50:15 -0700 (Tue, 15 Nov 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/feynman.asy
+ M /trunk/asymptote/base/geometry.asy
+ M /trunk/asymptote/base/graph.asy
+ M /trunk/asymptote/base/graph3.asy
+ M /trunk/asymptote/base/metapost.asy
+ M /trunk/asymptote/base/plain.asy
+ M /trunk/asymptote/base/pstoedit.asy
+ M /trunk/asymptote/base/three.asy
+ M /trunk/asymptote/examples/elliptic.asy
+
+Removed superfluous static modifiers.
+
+------------------------------------------------------------------------
+r1161 | jcbowman | 2005-11-15 15:07:01 -0700 (Tue, 15 Nov 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/graph3.asy
+ M /trunk/asymptote/base/math.asy
+ M /trunk/asymptote/doc/asymptote.texi
+
+Added surface graph of matrices.
+
+------------------------------------------------------------------------
+r1160 | jcbowman | 2005-11-15 13:51:50 -0700 (Tue, 15 Nov 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/graph3.asy
+ M /trunk/asymptote/doc/cube.asy
+ M /trunk/asymptote/doc/generalaxis3.asy
+ M /trunk/asymptote/doc/helix.asy
+ M /trunk/asymptote/doc/join3.asy
+ M /trunk/asymptote/doc/surface.asy
+ M /trunk/asymptote/examples/epix.asy
+
+Importing graph3 should publically import graph and three.
+
+------------------------------------------------------------------------
+r1159 | jcbowman | 2005-11-15 12:06:59 -0700 (Tue, 15 Nov 2005) | 4 lines
+Changed paths:
+ M /trunk/asymptote/base/plain.asy
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/drawlabel.cc
+ M /trunk/asymptote/drawlabel.h
+ M /trunk/asymptote/runtime.in
+ M /trunk/asymptote/texfile.cc
+ M /trunk/asymptote/texfile.h
+
+Implemented horizontal and vertical label scaling.
+
+Cleaned up Label code in plain.asy.
+
+------------------------------------------------------------------------
+r1158 | jcbowman | 2005-11-14 13:09:17 -0700 (Mon, 14 Nov 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/mathop.h
+
+Optimized integer overflow checks.
+
+------------------------------------------------------------------------
+r1157 | jcbowman | 2005-11-14 01:16:15 -0700 (Mon, 14 Nov 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/builtin.cc
+ M /trunk/asymptote/castop.h
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/mathop.h
+ M /trunk/asymptote/runtime.cc
+ M /trunk/asymptote/runtime.in
+
+Added checks for integer overflow.
+
+------------------------------------------------------------------------
+r1156 | jcbowman | 2005-11-14 00:57:47 -0700 (Mon, 14 Nov 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/main.cc
+
+Handle parse errors.
+
+------------------------------------------------------------------------
+r1155 | hammera | 2005-11-13 21:47:56 -0700 (Sun, 13 Nov 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+
+Minor edits.
+
+------------------------------------------------------------------------
+r1154 | jcbowman | 2005-11-13 18:47:17 -0700 (Sun, 13 Nov 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+
+Documented "from m unravel c as C;" syntax.
+
+------------------------------------------------------------------------
+r1153 | jcbowman | 2005-11-13 18:34:03 -0700 (Sun, 13 Nov 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+
+Minor update.
+
+------------------------------------------------------------------------
+r1152 | jcbowman | 2005-11-13 18:30:54 -0700 (Sun, 13 Nov 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+
+Documented unravel and include. Updated documentation of execute and eval.
+
+------------------------------------------------------------------------
+r1151 | hammera | 2005-11-13 15:29:51 -0700 (Sun, 13 Nov 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+
+Describes new importing system.
+
+------------------------------------------------------------------------
+r1150 | jcbowman | 2005-11-13 02:11:08 -0700 (Sun, 13 Nov 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/main.cc
+
+Fixed memory leak.
+
+------------------------------------------------------------------------
+r1149 | jcbowman | 2005-11-12 22:39:26 -0700 (Sat, 12 Nov 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/errormsg.h
+
+Removed constructor added in error.
+
+------------------------------------------------------------------------
+r1148 | jcbowman | 2005-11-12 22:36:26 -0700 (Sat, 12 Nov 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/builtin.cc
+ M /trunk/asymptote/coder.h
+ M /trunk/asymptote/dec.cc
+ M /trunk/asymptote/errormsg.h
+ M /trunk/asymptote/exp.h
+ M /trunk/asymptote/genv.h
+ M /trunk/asymptote/main.cc
+ M /trunk/asymptote/memory.h
+ M /trunk/asymptote/runtime.cc
+ M /trunk/asymptote/runtime.in
+ M /trunk/asymptote/stack.h
+ M /trunk/asymptote/table.h
+ M /trunk/asymptote/util.h
+
+Fixed cxx errors and warnings.
+
+------------------------------------------------------------------------
+r1147 | hammera | 2005-11-12 15:47:06 -0700 (Sat, 12 Nov 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/entry.cc
+ M /trunk/asymptote/entry.h
+
+Added venv::add to NOHASH.
+
+------------------------------------------------------------------------
+r1146 | jcbowman | 2005-11-12 15:18:24 -0700 (Sat, 12 Nov 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/dec.cc
+
+Another workaround for gcc 3.3.4 problems.
+
+------------------------------------------------------------------------
+r1145 | jcbowman | 2005-11-12 14:57:02 -0700 (Sat, 12 Nov 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/main.cc
+
+Workaround problem with gcc-3.3.4.
+
+------------------------------------------------------------------------
+r1144 | jcbowman | 2005-11-12 14:22:28 -0700 (Sat, 12 Nov 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/runtime.in
+
+Added erf,erc, and gamma functions.
+
+------------------------------------------------------------------------
+r1143 | jcbowman | 2005-11-12 12:43:42 -0700 (Sat, 12 Nov 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/runtime.cc
+
+Make quotient(int,int) consistent with %.
+
+------------------------------------------------------------------------
+r1142 | jcbowman | 2005-11-12 00:56:01 -0700 (Sat, 12 Nov 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/camp.l
+
+Fix **.
+
+------------------------------------------------------------------------
+r1141 | hammera | 2005-11-11 17:38:32 -0700 (Fri, 11 Nov 2005) | 3 lines
+Changed paths:
+ M /trunk/asymptote/camp.y
+ M /trunk/asymptote/dec.cc
+ M /trunk/asymptote/dec.h
+ M /trunk/asymptote/env.cc
+ M /trunk/asymptote/env.h
+ M /trunk/asymptote/genv.cc
+ M /trunk/asymptote/genv.h
+ M /trunk/asymptote/main.cc
+ M /trunk/asymptote/runtime.cc
+
+Replaced std::string with mem::string for genv.
+Moved error reporting associated with 'as'.
+
+------------------------------------------------------------------------
+r1140 | jcbowman | 2005-11-11 17:22:40 -0700 (Fri, 11 Nov 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/picture.cc
+
+Added missing delete.
+
+------------------------------------------------------------------------
+r1139 | jcbowman | 2005-11-11 00:14:34 -0700 (Fri, 11 Nov 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/picture.cc
+
+Make bounding box computation work with -o -.
+
+------------------------------------------------------------------------
+r1138 | jcbowman | 2005-11-10 23:37:34 -0700 (Thu, 10 Nov 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/picture.cc
+
+Allow outputting to standard output with "-o -" command line option.
+
+------------------------------------------------------------------------
+r1137 | jcbowman | 2005-11-10 22:59:13 -0700 (Thu, 10 Nov 2005) | 5 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/picture.cc
+ M /trunk/asymptote/settings.cc
+
+Set default pdf viewer to acroread under UNIX, just like under MSDOS.
+
+Removed pdf fuzz (a workaround for a pdf-viewing problem only of gv, not
+other pdf viewers).
+
+------------------------------------------------------------------------
+r1136 | hammera | 2005-11-10 09:02:55 -0700 (Thu, 10 Nov 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/application.cc
+ M /trunk/asymptote/application.h
+
+Refactored argument matching functions.
+
+------------------------------------------------------------------------
+r1135 | jcbowman | 2005-11-10 01:56:24 -0700 (Thu, 10 Nov 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/interact.cc
+
+Removed old interactive buffer flushing code.
+
+------------------------------------------------------------------------
+r1134 | jcbowman | 2005-11-10 00:58:13 -0700 (Thu, 10 Nov 2005) | 3 lines
+Changed paths:
+ M /trunk/asymptote/base/plain.asy
+ M /trunk/asymptote/builtin.cc
+ M /trunk/asymptote/dec.h
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/doc/shadedtiling.asy
+ M /trunk/asymptote/examples/Gouraud.asy
+ M /trunk/asymptote/examples/latticeshading.asy
+ M /trunk/asymptote/examples/ring.asy
+ M /trunk/asymptote/examples/shade.asy
+
+Choose more descriptive names latticeshade, axialshade, radialshade, and
+gouraudshade for shading routines.
+
+------------------------------------------------------------------------
+r1133 | jcbowman | 2005-11-10 00:17:56 -0700 (Thu, 10 Nov 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/fileio.cc
+
+Respect final null entry when reading data in cvs mode (fixed).
+
+------------------------------------------------------------------------
+r1132 | jcbowman | 2005-11-09 22:53:32 -0700 (Wed, 09 Nov 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/camp.l
+
+Flush input buffer every time we enter parser.
+
+------------------------------------------------------------------------
+r1131 | jcbowman | 2005-11-09 19:49:29 -0700 (Wed, 09 Nov 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/asy-mode.el
+ M /trunk/asymptote/examples/treetest.asy
+
+Added new keywords; fixed treetest.
+
+------------------------------------------------------------------------
+r1130 | jcbowman | 2005-11-09 19:35:22 -0700 (Wed, 09 Nov 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/plain.asy
+ M /trunk/asymptote/base/three.asy
+ M /trunk/asymptote/doc/asymptote.texi
+
+Documentation updates.
+
+------------------------------------------------------------------------
+r1129 | hammera | 2005-11-08 23:36:03 -0700 (Tue, 08 Nov 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/asy.vim
+ M /trunk/asymptote/base/plain.asy
+ M /trunk/asymptote/base/three.asy
+ M /trunk/asymptote/camp.l
+ M /trunk/asymptote/camp.y
+ M /trunk/asymptote/dec.cc
+ M /trunk/asymptote/dec.h
+ M /trunk/asymptote/entry.cc
+ M /trunk/asymptote/entry.h
+ M /trunk/asymptote/env.h
+ M /trunk/asymptote/fundec.cc
+ M /trunk/asymptote/stm.cc
+ M /trunk/asymptote/stm.h
+ M /trunk/asymptote/tests/Makefile
+
+Extended access and unravel syntax.
+
+------------------------------------------------------------------------
+r1128 | jcbowman | 2005-11-08 22:23:54 -0700 (Tue, 08 Nov 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/main.cc
+
+Make embedded evals work within exitfunction.
+
+------------------------------------------------------------------------
+r1127 | jcbowman | 2005-11-08 22:05:11 -0700 (Tue, 08 Nov 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/plain.asy
+ M /trunk/asymptote/builtin.cc
+ M /trunk/asymptote/interact.cc
+ M /trunk/asymptote/main.cc
+ M /trunk/asymptote/parser.cc
+ M /trunk/asymptote/picture.cc
+ M /trunk/asymptote/runtime.cc
+ M /trunk/asymptote/runtime.h
+ M /trunk/asymptote/runtime.in
+
+Reimplemented GUI support.
+
+------------------------------------------------------------------------
+r1126 | hammera | 2005-11-08 16:55:03 -0700 (Tue, 08 Nov 2005) | 3 lines
+Changed paths:
+ M /trunk/asymptote/dec.cc
+ M /trunk/asymptote/genv.cc
+ M /trunk/asymptote/genv.h
+ M /trunk/asymptote/parser.cc
+
+Check for infinite recursion when loading modules.
+Add position info (markTrans) for codelets.
+
+------------------------------------------------------------------------
+r1125 | jcbowman | 2005-11-08 13:30:10 -0700 (Tue, 08 Nov 2005) | 3 lines
+Changed paths:
+ M /trunk/asymptote/base/plain.asy
+ M /trunk/asymptote/builtin.cc
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/examples/hierarchy.asy
+
+
+Renamed defaultpen() to resetdefaultpen and getdefaultpen() to defaultpen().
+
+------------------------------------------------------------------------
+r1124 | jcbowman | 2005-11-08 13:11:06 -0700 (Tue, 08 Nov 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/errors
+ M /trunk/asymptote/genv.cc
+ M /trunk/asymptote/wce
+
+Updated diagostics.
+
+------------------------------------------------------------------------
+r1123 | jcbowman | 2005-11-08 11:58:07 -0700 (Tue, 08 Nov 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/TODO
+ M /trunk/asymptote/main.cc
+
+Re-implemented -p (parse) and -s (translate) options.
+
+------------------------------------------------------------------------
+r1122 | jcbowman | 2005-11-08 09:39:14 -0700 (Tue, 08 Nov 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/plain.asy
+ M /trunk/asymptote/camp.l
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/patches/dvipdf
+
+Corrections from import merge.
+
+------------------------------------------------------------------------
+r1121 | jcbowman | 2005-11-08 02:36:32 -0700 (Tue, 08 Nov 2005) | 7 lines
+Changed paths:
+ M /trunk/asymptote/camp.y
+ M /trunk/asymptote/dec.h
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/errormsg.cc
+ M /trunk/asymptote/interact.cc
+ M /trunk/asymptote/main.cc
+ M /trunk/asymptote/runtime.cc
+
+
+Reimplemented import "file" syntax.
+
+Interactive mode updates; reimplemented interactive "input" command.
+
+Documented true interactive mode.
+
+------------------------------------------------------------------------
+r1120 | jcbowman | 2005-11-08 00:22:41 -0700 (Tue, 08 Nov 2005) | 3 lines
+Changed paths:
+ M /trunk/asymptote/Makefile.in
+ M /trunk/asymptote/configure.ac
+ M /trunk/asymptote/doc/Makefile
+
+Facilitate optional installation of documentation and examples to different
+directories.
+
+------------------------------------------------------------------------
+r1119 | jcbowman | 2005-11-08 00:19:24 -0700 (Tue, 08 Nov 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/errorbars.asy
+
+Added missing picture arguments to graph.
+
+------------------------------------------------------------------------
+r1118 | jcbowman | 2005-11-07 22:26:21 -0700 (Mon, 07 Nov 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/examples/animations/cube.asy
+ M /trunk/asymptote/examples/animations/wheel.asy
+ M /trunk/asymptote/fileio.cc
+ M /trunk/asymptote/fileio.h
+
+Remaining import updates.
+
+------------------------------------------------------------------------
+r1116 | hammera | 2005-11-07 09:57:39 -0700 (Mon, 07 Nov 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/Makefile.in
+ M /trunk/asymptote/absyn.h
+ M /trunk/asymptote/access.cc
+ M /trunk/asymptote/access.h
+ M /trunk/asymptote/application.h
+ M /trunk/asymptote/arrayop.h
+ A /trunk/asymptote/base/animate.asy
+ M /trunk/asymptote/base/asy.vim
+ M /trunk/asymptote/base/featpost3D.asy
+ M /trunk/asymptote/base/geometry.asy
+ M /trunk/asymptote/base/graph.asy
+ M /trunk/asymptote/base/graph3.asy
+ M /trunk/asymptote/base/palette.asy
+ M /trunk/asymptote/base/plain.asy
+ M /trunk/asymptote/base/simplex.asy
+ M /trunk/asymptote/base/stats.asy
+ M /trunk/asymptote/base/three.asy
+ M /trunk/asymptote/builtin.cc
+ M /trunk/asymptote/camp.l
+ M /trunk/asymptote/camp.y
+ M /trunk/asymptote/coder.cc
+ M /trunk/asymptote/coder.h
+ M /trunk/asymptote/coenv.h
+ M /trunk/asymptote/dec.cc
+ M /trunk/asymptote/dec.h
+ M /trunk/asymptote/doc/asymptote.sty
+ M /trunk/asymptote/entry.cc
+ M /trunk/asymptote/entry.h
+ M /trunk/asymptote/env.cc
+ M /trunk/asymptote/env.h
+ M /trunk/asymptote/examples/Pythagoras.asy
+ M /trunk/asymptote/examples/orthocenter.asy
+ M /trunk/asymptote/exp.cc
+ M /trunk/asymptote/exp.h
+ M /trunk/asymptote/fileio.h
+ M /trunk/asymptote/fundec.cc
+ M /trunk/asymptote/genv.cc
+ M /trunk/asymptote/genv.h
+ D /trunk/asymptote/import.cc
+ D /trunk/asymptote/import.h
+ D /trunk/asymptote/importaccess.h
+ M /trunk/asymptote/interact.cc
+ M /trunk/asymptote/interact.h
+ M /trunk/asymptote/locate.cc
+ M /trunk/asymptote/main.cc
+ M /trunk/asymptote/name.cc
+ M /trunk/asymptote/name.h
+ M /trunk/asymptote/newexp.cc
+ M /trunk/asymptote/newexp.h
+ M /trunk/asymptote/parser.cc
+ M /trunk/asymptote/patches/dvipdf
+ M /trunk/asymptote/picture.cc
+ M /trunk/asymptote/record.cc
+ M /trunk/asymptote/record.h
+ M /trunk/asymptote/runtime.cc
+ M /trunk/asymptote/runtime.h
+ M /trunk/asymptote/runtime.in
+ M /trunk/asymptote/settings.cc
+ M /trunk/asymptote/settings.h
+ M /trunk/asymptote/stack.cc
+ M /trunk/asymptote/stack.h
+ M /trunk/asymptote/stm.cc
+ M /trunk/asymptote/stm.h
+ M /trunk/asymptote/table.h
+ M /trunk/asymptote/types.cc
+ M /trunk/asymptote/types.h
+
+Merged in changes from the import branch.
+
+------------------------------------------------------------------------
+r1110 | jcbowman | 2005-11-06 16:36:58 -0700 (Sun, 06 Nov 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/camp.l
+ M /trunk/asymptote/doc/asymptote.texi
+
+Fixed lexer error.
+
+------------------------------------------------------------------------
+r1108 | jcbowman | 2005-11-05 20:45:10 -0700 (Sat, 05 Nov 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/camp.l
+ M /trunk/asymptote/doc/asymptote.texi
+
+Removed # and ## as admissible operators.
+
+------------------------------------------------------------------------
+r1107 | jcbowman | 2005-11-03 10:44:07 -0700 (Thu, 03 Nov 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/fileio.cc
+
+Temporarily deactive last change.
+
+------------------------------------------------------------------------
+r1106 | jcbowman | 2005-11-03 10:32:41 -0700 (Thu, 03 Nov 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/fileio.cc
+ M /trunk/asymptote/fileio.h
+
+Respect final null entry when reading data in cvs mode.
+
+------------------------------------------------------------------------
+r1104 | jcbowman | 2005-11-02 22:46:58 -0700 (Wed, 02 Nov 2005) | 4 lines
+Changed paths:
+ A /trunk/asymptote/base/fontsize.asy
+ M /trunk/asymptote/camp.l
+ M /trunk/asymptote/camp.y
+ M /trunk/asymptote/doc/asymptote.texi
+
+Added infix operators << >> @ @@ $ $$ # ##.
+
+New module fontsize.asy supports nonstandard fonts.
+
+------------------------------------------------------------------------
+r1093 | jcbowman | 2005-10-30 03:41:06 -0700 (Sun, 30 Oct 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/camp.y
+
+Allow expressions of the form (0,0,0){x,y,z}.
+
+------------------------------------------------------------------------
+r1092 | jcbowman | 2005-10-30 03:34:35 -0700 (Sun, 30 Oct 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/camp.l
+ M /trunk/asymptote/camp.y
+ M /trunk/asymptote/doc/asymptote.texi
+
+Removed operator symbols consisting of letters enclosed by colons.
+
+------------------------------------------------------------------------
+r1087 | jcbowman | 2005-10-28 23:31:17 -0600 (Fri, 28 Oct 2005) | 3 lines
+Changed paths:
+ M /trunk/asymptote/camp.l
+ M /trunk/asymptote/camp.y
+ M /trunk/asymptote/doc/asymptote.texi
+
+Additional operator symbols can now be formed by enclosing any combination
+of letters (including the underscore character) in colons.
+
+------------------------------------------------------------------------
+r1086 | jcbowman | 2005-10-28 21:56:53 -0600 (Fri, 28 Oct 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/plain.asy
+ M /trunk/asymptote/camp.l
+
+Re-added tension3 and curl3 operators.
+
+------------------------------------------------------------------------
+r1082 | jcbowman | 2005-10-27 22:08:47 -0600 (Thu, 27 Oct 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/configure.ac
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/doc/version.texi.in
+ M /trunk/asymptote/psfile.cc
+
+Documentation now refers to Datadir variable rather than /usr/local/share.
+
+------------------------------------------------------------------------
+r1080 | jcbowman | 2005-10-26 12:28:04 -0600 (Wed, 26 Oct 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+
+Fixed typo.
+
+------------------------------------------------------------------------
+r1074 | jcbowman | 2005-10-24 22:54:56 -0600 (Mon, 24 Oct 2005) | 5 lines
+Changed paths:
+ M /trunk/asymptote/main.cc
+
+Return a definite return code (rather than an error count that overflows
+after 256 errors). Also check for parse and translation errors.
+A return code of 0 means successful; 1 means a user error occurred;
+-1 signals a misconfiguration error (pipe, fork, or exec failed).
+
+------------------------------------------------------------------------
+r1073 | jcbowman | 2005-10-24 22:02:19 -0600 (Mon, 24 Oct 2005) | 6 lines
+Changed paths:
+ M /trunk/asymptote/base/plain.asy
+ M /trunk/asymptote/doc/Makefile
+ M /trunk/asymptote/doc/asymptote.texi
+
+Set default put argument of box and ellipse functions to Above.
+
+Use convert instead of dvipng in doc/Makefile.
+
+Updated Debian URL.
+
+------------------------------------------------------------------------
+r1069 | jcbowman | 2005-10-23 02:15:00 -0600 (Sun, 23 Oct 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/configure.ac
+
+Incremented version to 0.93cvs.
+
+------------------------------------------------------------------------
+r1068 | jcbowman | 2005-10-23 01:48:50 -0600 (Sun, 23 Oct 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/runtime.cc
+
+Fixed cd diagnostic.
+
+------------------------------------------------------------------------
+r1067 | jcbowman | 2005-10-23 00:50:35 -0600 (Sun, 23 Oct 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/drawlabel.cc
+
+Fixed label bbox bug.
+
+------------------------------------------------------------------------
+r1066 | jcbowman | 2005-10-22 23:15:14 -0600 (Sat, 22 Oct 2005) | 5 lines
+Changed paths:
+ M /trunk/asymptote/base/plain.asy
+ M /trunk/asymptote/base/three.asy
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/doc/helix.asy
+ M /trunk/asymptote/path.cc
+
+
+Fixed intersect fuzz calculation.
+
+Implemented means of adjusting 3d aspect ratio.
+
+------------------------------------------------------------------------
+r1065 | jcbowman | 2005-10-22 10:49:28 -0600 (Sat, 22 Oct 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/xasy
+
+Updated xasy to generate GUI(int) frames instead of gui(int).
+
+------------------------------------------------------------------------
+r1064 | jcbowman | 2005-10-22 04:25:01 -0600 (Sat, 22 Oct 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/bbox.h
+ M /trunk/asymptote/runtime.in
+
+Workaround missing round function under FreeBSD.
+
+------------------------------------------------------------------------
+r1063 | jcbowman | 2005-10-22 03:41:04 -0600 (Sat, 22 Oct 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/path.cc
+
+Fixed cxx errors.
+
+------------------------------------------------------------------------
+r1060 | jcbowman | 2005-10-22 02:54:14 -0600 (Sat, 22 Oct 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/brokenaxis.asy
+
+Fixed example.
+
+------------------------------------------------------------------------
+r1059 | jcbowman | 2005-10-22 02:51:32 -0600 (Sat, 22 Oct 2005) | 2 lines
+Changed paths:
+ A /trunk/asymptote/doc/brokenaxis.asy
+
+Added missing example.
+
+------------------------------------------------------------------------
+r1058 | jcbowman | 2005-10-22 02:48:56 -0600 (Sat, 22 Oct 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/graph.asy
+ M /trunk/asymptote/doc/asymptote.texi
+
+Added scaleT Broken and example of broken x axis.
+
+------------------------------------------------------------------------
+r1057 | jcbowman | 2005-10-22 01:45:58 -0600 (Sat, 22 Oct 2005) | 5 lines
+Changed paths:
+ M /trunk/asymptote/base/plain.asy
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/doc/errorbars.asy
+ M /trunk/asymptote/doc/image.asy
+ M /trunk/asymptote/doc/subpictures.asy
+ M /trunk/asymptote/examples/elliptic.asy
+ M /trunk/asymptote/examples/laserlattice.asy
+ M /trunk/asymptote/examples/progrid.asy
+
+
+Moved dir argument of picture.fit() to add(frame,pair) and attach(frame,pair).
+
+Added frame align(frame f, pair dir) for aligning frames.
+
+------------------------------------------------------------------------
+r1056 | jcbowman | 2005-10-22 00:03:18 -0600 (Sat, 22 Oct 2005) | 5 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/doc/errorbars.asy
+
+Implemented a new struct marker to hold marker data, including a general
+markroutine. Included both the default marknodes routine and a
+markuniform(int n) routine which draws n markers at evenly spaced
+intervals along the arclength of the path.
+
+------------------------------------------------------------------------
+r1055 | jcbowman | 2005-10-21 02:12:29 -0600 (Fri, 21 Oct 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/main.cc
+ M /trunk/asymptote/picture.cc
+ M /trunk/asymptote/util.cc
+ M /trunk/asymptote/util.h
+ M /trunk/asymptote/xasy
+
+Don't strip directory from explicit output filenames.
+
+------------------------------------------------------------------------
+r1054 | jcbowman | 2005-10-21 01:23:16 -0600 (Fri, 21 Oct 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/plain.asy
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/doc/lineargraph.asy
+ M /trunk/asymptote/doc/lineargraph0.asy
+
+Documentation updates.
+
+------------------------------------------------------------------------
+r1053 | jcbowman | 2005-10-20 01:36:43 -0600 (Thu, 20 Oct 2005) | 26 lines
+Changed paths:
+ M /trunk/asymptote/Makefile.in
+ M /trunk/asymptote/base/math.asy
+ M /trunk/asymptote/base/plain.asy
+ M /trunk/asymptote/base/three.asy
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/doc/lineargraph.asy
+ M /trunk/asymptote/doc/lineargraph0.asy
+ M /trunk/asymptote/knot.cc
+ M /trunk/asymptote/picture.cc
+ M /trunk/asymptote/texfile.cc
+
+
+Added CPPFLAGS option to configure.ac (equivalent to CFLAGS).
+
+Fixed spurious overwrite messages.
+
+Added fuzz to label clipping to retain labels exactly on boundary.
+
+Moved intersectionpoint to plain.asy and added documentation.
+
+Renamed intersection in math.asy to intersect to intersect.
+
+Added UnFill filltype for clipping underneath frames, pictures, and labels,
+with examples.
+
+Make save/restore respect currentprojection.
+
+Added 3d intersectionpoint routines to three.asy.
+
+Added instructions for setting environment variables under MSWindows XP.
+
+Removed ymargin=infinity in favour of ymargin=xmargin.
+
+Documented use of Cyrillic fonts.
+
+Documented that \end{asy} environment must appear on a line by itself.
+
+------------------------------------------------------------------------
+r1047 | jcbowman | 2005-10-15 03:14:38 -0600 (Sat, 15 Oct 2005) | 3 lines
+Changed paths:
+ M /trunk/asymptote/base/graph.asy
+
+Fix precision errors at +/-1e-4; default format changes to scientific
+notation here.
+
+------------------------------------------------------------------------
+r1046 | jcbowman | 2005-10-14 22:07:16 -0600 (Fri, 14 Oct 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/plain.asy
+
+Fixed inside(path,pair).
+
+------------------------------------------------------------------------
+r1038 | jcbowman | 2005-10-14 01:16:49 -0600 (Fri, 14 Oct 2005) | 37 lines
+Changed paths:
+ M /trunk/asymptote/INSTALL
+ M /trunk/asymptote/base/graph.asy
+ M /trunk/asymptote/base/math.asy
+ M /trunk/asymptote/base/plain.asy
+ M /trunk/asymptote/base/three.asy
+ M /trunk/asymptote/builtin.cc
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/doc/leastsquares.asy
+ M /trunk/asymptote/drawclipbegin.h
+ M /trunk/asymptote/drawclipend.h
+ M /trunk/asymptote/drawelement.h
+ M /trunk/asymptote/drawfill.h
+ M /trunk/asymptote/drawlabel.cc
+ M /trunk/asymptote/drawlabel.h
+ M /trunk/asymptote/examples/animations/cube.asy
+ A /trunk/asymptote/examples/laserlattice.asy
+ A /trunk/asymptote/examples/star.asy
+ M /trunk/asymptote/knot.cc
+ M /trunk/asymptote/pair.h
+ M /trunk/asymptote/path.cc
+ M /trunk/asymptote/path.h
+ M /trunk/asymptote/pen.h
+ M /trunk/asymptote/picture.cc
+ M /trunk/asymptote/picture.h
+ M /trunk/asymptote/psfile.h
+ M /trunk/asymptote/runtime.cc
+ M /trunk/asymptote/runtime.h
+ M /trunk/asymptote/runtime.in
+ M /trunk/asymptote/texfile.cc
+ M /trunk/asymptote/texfile.h
+
+
+Implemented robust real cubic root solver.
+
+Removed inside, quadratic solver, and intersect routines from math.asy in
+place of internal C++ routines. Changed DOUBLE to TWO, etc., to avoid
+confusion with double roots.
+
+Implemented function bool inside(path g, pair z, pen p=currentpen);
+to test whether a point is inside a cyclic path.
+
+Implemented clipping of labels. Added two new fill rules to allow labels
+centered within the clipped region to overlap the clipping boundary.
+
+Clipping now clips all layers of a picture, not just the most recent one.
+
+Fixed bug in precontrol and postcontrol.
+
+Fixed floating point exception in complex powers when base is zero.
+
+Added Floor, Ceil, and Round functions that don't produce floating point
+exceptions.
+
+Made the default axis for logarithmic scaling YEquals(1) and XEquals(1).
+
+Made currentpicture the default picture in Scale(pair).
+
+Added begingroup/endgroup pairs to filldraw.
+
+Changed plane interface to return a representation of the plane through
+point O with normal cross(u,v).
+
+Draw over existing TeX layers when doing 3d hidden surface removal.
+
+Added face labels to cube animation.
+
+Updated installation instructions.
+
+------------------------------------------------------------------------
+r1035 | hammera | 2005-10-13 13:04:36 -0600 (Thu, 13 Oct 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/exp.cc
+ M /trunk/asymptote/exp.h
+
+Fixed prettyprinting of joinExp.
+
+------------------------------------------------------------------------
+r1034 | hammera | 2005-10-13 12:43:16 -0600 (Thu, 13 Oct 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/env.cc
+ M /trunk/asymptote/exp.cc
+
+More specific error message for casting.
+
+------------------------------------------------------------------------
+r1033 | hammera | 2005-10-13 12:42:41 -0600 (Thu, 13 Oct 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/stm.cc
+
+Fixed indenting for parse output.
+
+------------------------------------------------------------------------
+r1032 | jcbowman | 2005-10-13 09:01:13 -0600 (Thu, 13 Oct 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/knot.h
+
+Fixed control point bug introduced by recent straight flag fix.
+
+------------------------------------------------------------------------
+r1031 | jcbowman | 2005-10-12 16:29:21 -0600 (Wed, 12 Oct 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/plain.asy
+
+Make default value of picture.keepAspect true.
+
+------------------------------------------------------------------------
+r1030 | jcbowman | 2005-10-12 14:02:37 -0600 (Wed, 12 Oct 2005) | 4 lines
+Changed paths:
+ M /trunk/asymptote/base/plain.asy
+
+
+Use picture defaults as default parameters in fit and size functions
+(locally resolved default function arguments now allow this).
+
+------------------------------------------------------------------------
+r1027 | hammera | 2005-10-11 19:29:11 -0600 (Tue, 11 Oct 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/flatguide.cc
+ M /trunk/asymptote/knot.cc
+ M /trunk/asymptote/knot.h
+
+Straight flags are preserved when using a path as part of a guide.
+
+------------------------------------------------------------------------
+r1026 | hammera | 2005-10-07 21:57:39 -0600 (Fri, 07 Oct 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/fundec.cc
+
+Default arguments are evaluated "out-of-order" like variable initializers.
+
+------------------------------------------------------------------------
+r1024 | jcbowman | 2005-10-07 14:58:33 -0600 (Fri, 07 Oct 2005) | 6 lines
+Changed paths:
+ M /trunk/asymptote/Makefile.in
+ M /trunk/asymptote/base/three.asy
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/doc/planes.asy
+ A /trunk/asymptote/examples/animations
+ A /trunk/asymptote/examples/animations/cube.asy
+ A /trunk/asymptote/examples/animations/wheel.asy
+ D /trunk/asymptote/examples/cubeanimation.asy
+ D /trunk/asymptote/examples/wheelanimation.asy
+
+
+Moved animations to animations subdirectory of examples directory.
+
+plane(triple u, triple v, triple O=three.O) now returns the plane through
+point O with normal cross(u,v)
+
+------------------------------------------------------------------------
+r1023 | jcbowman | 2005-10-07 02:22:25 -0600 (Fri, 07 Oct 2005) | 9 lines
+Changed paths:
+ M /trunk/asymptote/base/plain.asy
+ M /trunk/asymptote/base/three.asy
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/doc/planes.asy
+ A /trunk/asymptote/examples/cubeanimation.asy
+ M /trunk/asymptote/examples/wheelanimation.asy
+ M /trunk/asymptote/runtime.cc
+
+
+Simplified plane(triple, triple, triple).
+
+Simplified Pen(int).
+
+merge no longer waits for animation to complete.
+
+Added rotating cube animation.
+
+------------------------------------------------------------------------
+r1022 | jcbowman | 2005-10-06 11:46:16 -0600 (Thu, 06 Oct 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/loggrid.asy
+
+Fixed formatting.
+
+------------------------------------------------------------------------
+r1021 | jcbowman | 2005-10-06 11:17:13 -0600 (Thu, 06 Oct 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/loggrid.asy
+
+Added linewidth().
+
+------------------------------------------------------------------------
+r1020 | jcbowman | 2005-10-06 11:11:05 -0600 (Thu, 06 Oct 2005) | 5 lines
+Changed paths:
+ M /trunk/asymptote/base/feynman.asy
+ M /trunk/asymptote/base/plain.asy
+ M /trunk/asymptote/builtin.cc
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/examples/conicurv.asy
+ M /trunk/asymptote/examples/triads.asy
+ M /trunk/asymptote/examples/wheelanimation.asy
+
+Removed implicit cast from real to pen; added pen operator +(pen p, real w)
+and defaultpen(real) instead.
+
+To avoid confusion, a dot product now requires explicit pair arguments.
+
+------------------------------------------------------------------------
+r1018 | jcbowman | 2005-10-06 10:05:56 -0600 (Thu, 06 Oct 2005) | 2 lines
+Changed paths:
+ A /trunk/asymptote/examples/epix.asy
+
+Added new 3d surface example.
+
+------------------------------------------------------------------------
+r1016 | jcbowman | 2005-10-05 23:55:15 -0600 (Wed, 05 Oct 2005) | 4 lines
+Changed paths:
+ M /trunk/asymptote/base/plain.asy
+ M /trunk/asymptote/doc/asymptote.texi
+ A /trunk/asymptote/doc/leastsquares.asy
+ A /trunk/asymptote/doc/leastsquares.dat
+
+Added example of reading column data from a file and a least squares fit.
+
+Changed xsize and ysize arguments of size to simply x and y.
+
+------------------------------------------------------------------------
+r1015 | jcbowman | 2005-10-05 19:51:32 -0600 (Wed, 05 Oct 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/plain.asy
+ M /trunk/asymptote/doc/asymptote.texi
+
+Added keepAspect=Aspect option to size(pic,real).
+
+------------------------------------------------------------------------
+r1014 | jcbowman | 2005-10-05 19:44:19 -0600 (Wed, 05 Oct 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/stats.asy
+
+Added colinearity checks to leastsquares.
+
+------------------------------------------------------------------------
+r1013 | jcbowman | 2005-10-05 01:49:20 -0600 (Wed, 05 Oct 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/graph.asy
+
+Use local copy of ticklabel and Label context variables.
+
+------------------------------------------------------------------------
+r1012 | jcbowman | 2005-10-05 00:12:20 -0600 (Wed, 05 Oct 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/graph.asy
+
+Reduce default axis coverage limit to 80%.
+
+------------------------------------------------------------------------
+r1011 | jcbowman | 2005-10-04 21:48:00 -0600 (Tue, 04 Oct 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+
+Minor documentation updates.
+
+------------------------------------------------------------------------
+r1010 | jcbowman | 2005-10-04 16:13:55 -0600 (Tue, 04 Oct 2005) | 4 lines
+Changed paths:
+ M /trunk/asymptote/picture.cc
+ M /trunk/asymptote/settings.cc
+
+Fixed default location of python under MSDOS.
+
+Improved ASYMPTOTE_PYTHON/ASYMPTOTE_XASY diagnostics.
+
+------------------------------------------------------------------------
+r1009 | jcbowman | 2005-10-04 15:43:14 -0600 (Tue, 04 Oct 2005) | 7 lines
+Changed paths:
+ M /trunk/asymptote/base/plain.asy
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/genv.cc
+ M /trunk/asymptote/main.cc
+ M /trunk/asymptote/picture.cc
+ M /trunk/asymptote/runtime.in
+ M /trunk/asymptote/settings.cc
+ M /trunk/asymptote/settings.h
+
+Added Windows support for xasy, including an environment variable for
+finding Python.
+
+Allow GUI mode in interactive mode.
+
+Added gui(real x=1) function to turn on GUI mode.
+
+------------------------------------------------------------------------
+r1008 | jcbowman | 2005-10-04 11:27:41 -0600 (Tue, 04 Oct 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/runtime.cc
+
+Remove intermediate gif files before viewing animation.
+
+------------------------------------------------------------------------
+r1007 | jcbowman | 2005-10-04 11:20:56 -0600 (Tue, 04 Oct 2005) | 3 lines
+Changed paths:
+ M /trunk/asymptote/base/plain.asy
+ M /trunk/asymptote/builtin.cc
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/examples/wheelanimation.asy
+ D /trunk/asymptote/patches/ImageMagick.patch
+ M /trunk/asymptote/picture.cc
+ M /trunk/asymptote/picture.h
+ M /trunk/asymptote/runtime.cc
+ M /trunk/asymptote/settings.cc
+ M /trunk/asymptote/settings.h
+
+Added quiet option to override -V command line option, say for producing
+animated gifs. If the -V option is given, gifmerge now calls animate.
+
+------------------------------------------------------------------------
+r1006 | jcbowman | 2005-10-04 00:30:27 -0600 (Tue, 04 Oct 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/configure.ac
+
+Incremented version to 0.92cvs.
+
+------------------------------------------------------------------------
+r1005 | jcbowman | 2005-10-03 23:39:06 -0600 (Mon, 03 Oct 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/plain.asy
+
+Fixed GUI transforms: grouping should not depend on deconstruct flag.
+
+------------------------------------------------------------------------
+r1004 | jcbowman | 2005-10-03 23:06:24 -0600 (Mon, 03 Oct 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/configure.ac
+
+Incremented version to 0.91cvs.
+
+------------------------------------------------------------------------
+r1002 | jcbowman | 2005-10-03 21:24:51 -0600 (Mon, 03 Oct 2005) | 3 lines
+Changed paths:
+ M /trunk/asymptote/examples/limit.asy
+ M /trunk/asymptote/pipestream.h
+ M /trunk/asymptote/util.cc
+
+
+Flush stdout immediately before calls to fork() to avoid duplicate output.
+
+------------------------------------------------------------------------
+r1001 | jcbowman | 2005-10-03 02:36:26 -0600 (Mon, 03 Oct 2005) | 4 lines
+Changed paths:
+ M /trunk/asymptote/application.cc
+ M /trunk/asymptote/application.h
+ M /trunk/asymptote/base/plain.asy
+ M /trunk/asymptote/base/three.asy
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/exp.cc
+ M /trunk/asymptote/exp.h
+ M /trunk/asymptote/fundec.cc
+ M /trunk/asymptote/runtime.cc
+ M /trunk/asymptote/runtime.h
+ M /trunk/asymptote/types.h
+
+
+Added Andy's changes to evaluate default function arguments in the defining
+scope of the function, not in the scope of the caller.
+
+------------------------------------------------------------------------
+r1000 | jcbowman | 2005-10-03 02:20:02 -0600 (Mon, 03 Oct 2005) | 9 lines
+Changed paths:
+ M /trunk/asymptote/arrayop.h
+ M /trunk/asymptote/base/plain.asy
+ M /trunk/asymptote/base/three.asy
+ M /trunk/asymptote/builtin.cc
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/fileio.cc
+ M /trunk/asymptote/fileio.h
+ M /trunk/asymptote/runtime.cc
+ M /trunk/asymptote/runtime.h
+
+Generalized write to handle an arbitrary number of data values; improved
+documentation.
+
+Generate standard casts via templates.
+
+Added == and != for files.
+
+Allow casting of null to file.
+
+------------------------------------------------------------------------
+r998 | jcbowman | 2005-10-03 01:08:44 -0600 (Mon, 03 Oct 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/path.cc
+ M /trunk/asymptote/path3.cc
+
+Readded depth limit to intersect routines to prevent stack overflow.
+
+------------------------------------------------------------------------
+r997 | jcbowman | 2005-10-02 15:42:30 -0600 (Sun, 02 Oct 2005) | 3 lines
+Changed paths:
+ M /trunk/asymptote/base/three.asy
+ M /trunk/asymptote/path.cc
+ M /trunk/asymptote/path3.cc
+
+Enforce a minimum value of fuzz in intersect routines to prevent infinite
+loops.
+
+------------------------------------------------------------------------
+r995 | jcbowman | 2005-10-02 01:20:15 -0600 (Sun, 02 Oct 2005) | 13 lines
+Changed paths:
+ M /trunk/asymptote/base/graph.asy
+ M /trunk/asymptote/base/plain.asy
+ M /trunk/asymptote/base/three.asy
+ M /trunk/asymptote/doc/asy.1
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/doc/helix.asy
+ M /trunk/asymptote/doc/join3.asy
+ M /trunk/asymptote/doc/westnile.asy
+ M /trunk/asymptote/drawlabel.cc
+ M /trunk/asymptote/picture.cc
+ M /trunk/asymptote/texfile.h
+
+Fixed depth handling of deferred TeX labels.
+
+Fixed error in man page (-t option).
+
+Fixed interaction of overwrite(Move) with "%" tick formats.
+
+Improved 3d axis label positioning.
+
+Added rotate(explicit pair dir) and rotate(explicit triple dir) for
+rotating text along a line in the direction dir.
+
+Updated helix example to illustrate rotated tick and axis labels.
+
+------------------------------------------------------------------------
+r994 | jcbowman | 2005-09-30 23:40:32 -0600 (Fri, 30 Sep 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/configure.ac
+
+Incremented version to 0.90cvs.
+
+------------------------------------------------------------------------
+r993 | jcbowman | 2005-09-30 22:42:16 -0600 (Fri, 30 Sep 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+
+Documented min(frame) and max(frame).
+
+------------------------------------------------------------------------
+r992 | jcbowman | 2005-09-30 14:55:59 -0600 (Fri, 30 Sep 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/graph.asy
+
+Don't upscale logarithmic range when automax=false.
+
+------------------------------------------------------------------------
+r991 | jcbowman | 2005-09-30 12:42:28 -0600 (Fri, 30 Sep 2005) | 4 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/picture.cc
+
+Renamed temporary included PostScript file suffix from "ps" to "eps".
+
+Removed all references to mailing list, as it is no longer in use.
+
+------------------------------------------------------------------------
+r990 | jcbowman | 2005-09-30 07:50:18 -0600 (Fri, 30 Sep 2005) | 4 lines
+Changed paths:
+ M /trunk/asymptote/base/graph.asy
+ M /trunk/asymptote/base/plain.asy
+ M /trunk/asymptote/doc/asymptote.texi
+ A /trunk/asymptote/examples/limit.asy
+
+Fixed .gui processing.
+
+Added new example.
+
+------------------------------------------------------------------------
+r988 | jcbowman | 2005-09-29 19:53:03 -0600 (Thu, 29 Sep 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/graph.asy
+ M /trunk/asymptote/doc/Bode.asy
+ M /trunk/asymptote/doc/asymptote.texi
+ A /trunk/asymptote/doc/logticks.asy
+
+Allow overriding of ticklabel routine for logarithmic axis; added example.
+
+------------------------------------------------------------------------
+r986 | jcbowman | 2005-09-29 18:04:46 -0600 (Thu, 29 Sep 2005) | 4 lines
+Changed paths:
+ M /trunk/asymptote/base/graph.asy
+ M /trunk/asymptote/base/palette.asy
+ M /trunk/asymptote/base/plain.asy
+ M /trunk/asymptote/doc/Bode.asy
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/doc/datagraph.asy
+ M /trunk/asymptote/doc/diatom.asy
+ M /trunk/asymptote/doc/generalaxis.asy
+ M /trunk/asymptote/doc/generalaxis3.asy
+
+Standardized arguments to LeftTicks, etc.
+
+Fixed user-specified logarithmic ticks.
+
+------------------------------------------------------------------------
+r985 | jcbowman | 2005-09-29 01:50:22 -0600 (Thu, 29 Sep 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/configure.ac
+
+Incremented version to 0.89cvs.
+
+------------------------------------------------------------------------
+r984 | jcbowman | 2005-09-28 23:53:39 -0600 (Wed, 28 Sep 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/Makefile
+
+Only build required images.
+
+------------------------------------------------------------------------
+r982 | jcbowman | 2005-09-28 23:37:23 -0600 (Wed, 28 Sep 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/doc/flow.asy
+
+Minor documentation updates.
+
+------------------------------------------------------------------------
+r981 | jcbowman | 2005-09-28 18:01:47 -0600 (Wed, 28 Sep 2005) | 8 lines
+Changed paths:
+ M /trunk/asymptote/base/graph.asy
+ M /trunk/asymptote/base/plain.asy
+ M /trunk/asymptote/doc/asymptote.texi
+ A /trunk/asymptote/doc/flow.asy
+ D /trunk/asymptote/examples/flow.asy
+ M /trunk/asymptote/fileio.cc
+ M /trunk/asymptote/runtime.cc
+
+Fixed missing label on thinned logarithmic graphs.
+
+Documented getstring and getreal.
+
+Documented vectorfield and flow example.
+
+Fixed cxx warning messages.
+
+------------------------------------------------------------------------
+r978 | jcbowman | 2005-09-28 14:51:47 -0600 (Wed, 28 Sep 2005) | 10 lines
+Changed paths:
+ M /trunk/asymptote/TODO
+ M /trunk/asymptote/base/graph.asy
+ M /trunk/asymptote/base/graph3.asy
+ M /trunk/asymptote/base/plain.asy
+ M /trunk/asymptote/base/three.asy
+ M /trunk/asymptote/camp.l
+ M /trunk/asymptote/doc/Makefile
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/doc/axis3.asy
+ M /trunk/asymptote/doc/generalaxis.asy
+ M /trunk/asymptote/doc/generalaxis3.asy
+ M /trunk/asymptote/doc/helix.asy
+ M /trunk/asymptote/doc/join.asy
+ A /trunk/asymptote/doc/join3.asy
+ A /trunk/asymptote/doc/saddle.asy
+ M /trunk/asymptote/doc/surface.asy
+ M /trunk/asymptote/doc/unitcircle3.asy
+ M /trunk/asymptote/examples/elliptic.asy
+
+Simplified, improved, and documented 3d axes routines.
+
+Renamed tickspec to ticklocate. Documented ticklocate.
+
+Removed unused symbols from camp.l.
+
+Removed spurious nullpaths from :: and ---.
+
+Documented deconstruction of guides.
+
+------------------------------------------------------------------------
+r977 | jcbowman | 2005-09-27 01:42:24 -0600 (Tue, 27 Sep 2005) | 5 lines
+Changed paths:
+ M /trunk/asymptote/base/plain.asy
+ M /trunk/asymptote/camperror.cc
+ M /trunk/asymptote/camperror.h
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/doc/latexusage.tex
+ M /trunk/asymptote/drawlabel.cc
+ M /trunk/asymptote/drawlabel.h
+ M /trunk/asymptote/runtime.in
+
+Added a second optional string to Label to provide an estimate for the label
+size when an undefined label is encountered with the -t option.
+
+Fixed box(Label).
+
+------------------------------------------------------------------------
+r975 | jcbowman | 2005-09-26 23:28:56 -0600 (Mon, 26 Sep 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/patches/pstoedit-3.42asy.patch
+
+Updated pstoedit patch to put brackets around rotated strings.
+
+------------------------------------------------------------------------
+r974 | jcbowman | 2005-09-26 23:09:02 -0600 (Mon, 26 Sep 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/plain.asy
+ M /trunk/asymptote/builtin.cc
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/fileio.cc
+ M /trunk/asymptote/fileio.h
+ M /trunk/asymptote/runtime.cc
+
+Implemented data file comment character (# by default).
+
+------------------------------------------------------------------------
+r973 | jcbowman | 2005-09-26 09:05:45 -0600 (Mon, 26 Sep 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/graph.asy
+
+Used scaled epsilon to adjust right-hand axis limit.
+
+------------------------------------------------------------------------
+r972 | jcbowman | 2005-09-25 23:45:48 -0600 (Sun, 25 Sep 2005) | 25 lines
+Changed paths:
+ M /trunk/asymptote/Makefile.in
+ M /trunk/asymptote/base/graph.asy
+ M /trunk/asymptote/base/graph3.asy
+ M /trunk/asymptote/base/math.asy
+ M /trunk/asymptote/base/plain.asy
+ M /trunk/asymptote/base/pstoedit.asy
+ M /trunk/asymptote/base/three.asy
+ M /trunk/asymptote/bbox.h
+ M /trunk/asymptote/builtin.cc
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/doc/generalaxis.asy
+ M /trunk/asymptote/doc/generalaxis3.asy
+ M /trunk/asymptote/doc/latexusage.tex
+ M /trunk/asymptote/patches/README
+ D /trunk/asymptote/patches/pstoedit-3.41asy.patch
+ A /trunk/asymptote/patches/pstoedit-3.42asy.patch
+ M /trunk/asymptote/path.cc
+ M /trunk/asymptote/path.h
+ A /trunk/asymptote/path3.cc
+ M /trunk/asymptote/runtime.cc
+ M /trunk/asymptote/runtime.h
+ M /trunk/asymptote/runtime.in
+ D /trunk/asymptote/triple.cc
+ M /trunk/asymptote/triple.h
+
+
+Added fuzz parameter to intersect routines for finding intersections with
+circular approximations, etc. Also fixed these routines for paths
+consisting of a single point.
+
+Moved 3d intersect routine to C++ for speed.
+
+Cache 2d path bounding box.
+
+Added 3d version of expi.
+
+Increased accuracy of true Arc and Circle to approximately machine precision.
+
+Added 3d true Arc and Circle.
+
+Added 3d polargraph function.
+
+Renamed triple.cc to path3.cc.
+
+Added missing triple to path3 cast.
+
+Added patch to pstoedit-3.42 to support PNG to EPS conversion.
+
+Updated documentation.
+
+------------------------------------------------------------------------
+r971 | jcbowman | 2005-09-25 21:56:47 -0600 (Sun, 25 Sep 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/drawlabel.cc
+
+Fixed base alignment in new deferred TeX alignment scheme.
+
+------------------------------------------------------------------------
+r970 | jcbowman | 2005-09-23 22:04:54 -0600 (Fri, 23 Sep 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/three.asy
+
+Fixed shift(c) in 3d circle.
+
+------------------------------------------------------------------------
+r969 | jcbowman | 2005-09-23 09:42:46 -0600 (Fri, 23 Sep 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/camp.l
+
+Fixed "\\".
+
+------------------------------------------------------------------------
+r968 | jcbowman | 2005-09-23 01:15:56 -0600 (Fri, 23 Sep 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/interact.cc
+
+Added missing header.
+
+------------------------------------------------------------------------
+r967 | jcbowman | 2005-09-23 01:07:53 -0600 (Fri, 23 Sep 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/runtime.cc
+
+Make merge use environment variable ASYMPTOTE_CONVERT.
+
+------------------------------------------------------------------------
+r966 | jcbowman | 2005-09-23 01:02:48 -0600 (Fri, 23 Sep 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/picture.cc
+ M /trunk/asymptote/pipestream.h
+ M /trunk/asymptote/settings.cc
+ M /trunk/asymptote/settings.h
+ M /trunk/asymptote/util.cc
+ M /trunk/asymptote/util.h
+
+Added an environment variable for the location of every external command.
+
+------------------------------------------------------------------------
+r965 | jcbowman | 2005-09-22 23:54:43 -0600 (Thu, 22 Sep 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/graph.asy
+ A /trunk/asymptote/examples/flow.asy
+
+Added vectorfield routine and example.
+
+------------------------------------------------------------------------
+r963 | jcbowman | 2005-09-22 23:23:39 -0600 (Thu, 22 Sep 2005) | 11 lines
+Changed paths:
+ M /trunk/asymptote/doc/asy.1
+ M /trunk/asymptote/doc/asymptote.sty
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/doc/latexusage.tex
+ M /trunk/asymptote/drawlabel.cc
+ M /trunk/asymptote/drawlabel.h
+ M /trunk/asymptote/patches/README
+ A /trunk/asymptote/patches/dvipdf
+ M /trunk/asymptote/picture.cc
+ M /trunk/asymptote/pipestream.h
+ M /trunk/asymptote/settings.cc
+ M /trunk/asymptote/settings.h
+ M /trunk/asymptote/texfile.cc
+ M /trunk/asymptote/texfile.h
+
+
+Added [inline] option to asymptote.sty to use inline LaTeX code instead of
+eps files, making LaTeX symbols visible to the \begin{asy}...\end{asy}
+environment. In this mode, Asymptote correctly aligns LaTeX symbols defined
+outside of the \begin{asy}...\end{asy} environment, but treats their size
+as zero.
+
+Added -t option to asy to request inline LaTeX code to be generated.
+
+Added modified dvipdf that accepts the dvips -z hyperdvi option.
+
+------------------------------------------------------------------------
+r962 | jcbowman | 2005-09-21 19:06:07 -0600 (Wed, 21 Sep 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/latexusage.tex
+
+Updated axis call.
+
+------------------------------------------------------------------------
+r961 | jcbowman | 2005-09-21 17:58:34 -0600 (Wed, 21 Sep 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/picture.cc
+ M /trunk/asymptote/runtime.cc
+
+Replace system calls to rm/del by unlink().
+
+------------------------------------------------------------------------
+r960 | jcbowman | 2005-09-21 02:32:44 -0600 (Wed, 21 Sep 2005) | 21 lines
+Changed paths:
+ M /trunk/asymptote/base/graph.asy
+ M /trunk/asymptote/base/graph3.asy
+ M /trunk/asymptote/base/palette.asy
+ M /trunk/asymptote/base/plain.asy
+ M /trunk/asymptote/base/three.asy
+ M /trunk/asymptote/doc/Bode.asy
+ M /trunk/asymptote/doc/asymptote.texi
+ A /trunk/asymptote/doc/axis3.asy
+ M /trunk/asymptote/doc/exp.asy
+ M /trunk/asymptote/doc/generalaxis.asy
+ M /trunk/asymptote/doc/generalaxis3.asy
+ M /trunk/asymptote/doc/secondaryaxis.asy
+ M /trunk/asymptote/examples/equilchord.asy
+ M /trunk/asymptote/examples/integraltest.asy
+ M /trunk/asymptote/examples/log.asy
+ M /trunk/asymptote/examples/spiral.asy
+ M /trunk/asymptote/examples/sqrtx01.asy
+ M /trunk/asymptote/examples/sqrtx01y1.asy
+ M /trunk/asymptote/examples/triads.asy
+ M /trunk/asymptote/examples/wedge.asy
+ M /trunk/asymptote/examples/wheelanimation.asy
+ M /trunk/asymptote/examples/xxsq01.asy
+ M /trunk/asymptote/path.cc
+ M /trunk/asymptote/path.h
+
+
+Fixed segmentation fault in straight.
+
+Fixed bug in setting straight flag in reverse.
+
+Fixed axis label placement for slanted (but straight) axes.
+
+Improved tick label positioning with slanted ticks.
+
+Simplified 3d axis routines; added autolimits function to implement 3d
+autoscaling.
+
+Don't cache Ticksize and ticksize.
+
+Standardized xaxis, yaxis, xequals, yequals calls (Label now appears
+immediately after picture argument).
+
+Check for empty pictures when drawing axes with ticks.
+
+Updated documentation and examples.
+
+------------------------------------------------------------------------
+r959 | jcbowman | 2005-09-20 02:39:57 -0600 (Tue, 20 Sep 2005) | 16 lines
+Changed paths:
+ M /trunk/asymptote/INSTALL
+ M /trunk/asymptote/TODO
+ M /trunk/asymptote/base/graph.asy
+ M /trunk/asymptote/base/graph3.asy
+ M /trunk/asymptote/base/plain.asy
+ M /trunk/asymptote/configure.ac
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/doc/datagraph.asy
+ M /trunk/asymptote/doc/diatom.asy
+ M /trunk/asymptote/doc/generalaxis.asy
+ A /trunk/asymptote/doc/generalaxis3.asy
+ M /trunk/asymptote/doc/lineargraph.asy
+ M /trunk/asymptote/doc/secondaryaxis.asy
+ M /trunk/asymptote/runtime.cc
+ M /trunk/asymptote/util.h
+
+
+Overhaul and major clean up of 2d graph module; to support 3d axes,
+partitioning is now done in tick value space rather than with respect to
+arclength.
+
+Added 3d graph axes (xaxis, yaxis, zaxis, and general axis) and generalaxis3
+example.
+
+Format "" is now treated as defaultformat (use "%" to suppress labels).
+
+Updated gc to 6.6.
+
+Under MSDOS, change "rm" to "del" in merge utility.
+
+Don't print hints when there is no environment variable.
+
+------------------------------------------------------------------------
+r955 | hammera | 2005-09-16 09:36:50 -0600 (Fri, 16 Sep 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/name.cc
+
+Fixed error reporting bug.
+
+------------------------------------------------------------------------
+r954 | jcbowman | 2005-09-14 07:46:33 -0600 (Wed, 14 Sep 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/Makefile.in
+
+Changed make to $(MAKE) for portability.
+
+------------------------------------------------------------------------
+r953 | jcbowman | 2005-09-14 01:25:28 -0600 (Wed, 14 Sep 2005) | 7 lines
+Changed paths:
+ M /trunk/asymptote/base/three.asy
+
+Changed nullpath to nullpath3 to avoid ambiguities.
+
+Set initial precontrol point and final postcontrol point of noncyclic paths
+to the corresponding node.
+
+Fixed the length of a cyclic path3.
+
+------------------------------------------------------------------------
+r952 | jcbowman | 2005-09-14 01:17:44 -0600 (Wed, 14 Sep 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/runtime.cc
+
+Added snprintf workaround for non-C99 compliant systems.
+
+------------------------------------------------------------------------
+r951 | jcbowman | 2005-09-13 09:49:18 -0600 (Tue, 13 Sep 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/pipestream.h
+ M /trunk/asymptote/util.cc
+
+Added missing headers for Solaris/Sparc.
+
+------------------------------------------------------------------------
+r950 | jcbowman | 2005-09-12 19:47:44 -0600 (Mon, 12 Sep 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/types.cc
+
+Fixed pair.z and triple.xx bugs.
+
+------------------------------------------------------------------------
+r949 | jcbowman | 2005-09-12 17:11:54 -0600 (Mon, 12 Sep 2005) | 3 lines
+Changed paths:
+ M /trunk/asymptote/base/graph.asy
+
+
+Added some comments to graph.asy.
+
+------------------------------------------------------------------------
+r948 | jcbowman | 2005-09-12 13:40:40 -0600 (Mon, 12 Sep 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/math.asy
+
+Optimized matrix times vector.
+
+------------------------------------------------------------------------
+r947 | jcbowman | 2005-09-12 11:35:34 -0600 (Mon, 12 Sep 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/geometry.asy
+ M /trunk/asymptote/examples/Pythagoras.asy
+ M /trunk/asymptote/examples/orthocenter.asy
+
+Standardized perpendicular.
+
+------------------------------------------------------------------------
+r946 | jcbowman | 2005-09-11 23:48:47 -0600 (Sun, 11 Sep 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/three.asy
+ M /trunk/asymptote/builtin.cc
+ M /trunk/asymptote/camp.l
+ M /trunk/asymptote/camp.y
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/doc/join.asy
+
+Added 2d & 3d Metapost & operator (like --, but omits the duplicate point).
+
+------------------------------------------------------------------------
+r945 | jcbowman | 2005-09-11 00:34:52 -0600 (Sun, 11 Sep 2005) | 3 lines
+Changed paths:
+ M /trunk/asymptote/doc/Makefile
+ M /trunk/asymptote/doc/asymptote.texi
+
+
+Fixed resolution problems of png figures in html manual.
+
+------------------------------------------------------------------------
+r944 | jcbowman | 2005-09-11 00:04:12 -0600 (Sun, 11 Sep 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+ A /trunk/asymptote/patches/ImageMagick.patch
+
+Reorganized installation instructions.
+
+------------------------------------------------------------------------
+r943 | jcbowman | 2005-09-10 23:33:39 -0600 (Sat, 10 Sep 2005) | 5 lines
+Changed paths:
+ M /trunk/asymptote/application.cc
+ M /trunk/asymptote/application.h
+ M /trunk/asymptote/doc/asymptote.texi
+
+
+Handle errors due nonarray rest formals gracefully.
+
+Improved formatting.
+
+------------------------------------------------------------------------
+r942 | jcbowman | 2005-09-10 16:10:36 -0600 (Sat, 10 Sep 2005) | 11 lines
+Changed paths:
+ M /trunk/asymptote/INSTALL
+ M /trunk/asymptote/Makefile.in
+ M /trunk/asymptote/doc/Makefile
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/errors
+
+
+Updated list of errors.
+
+Changed make test to make check.
+
+"make all"/"make install" now build/install asy, asymptote.pdf, and man pages
+but not asymptote.dvi, asymptote.info, or asymptote.html
+(use make install-all if you want these too).
+
+Documented workaround for broken pdftex installations.
+
+------------------------------------------------------------------------
+r941 | jcbowman | 2005-09-10 00:38:55 -0600 (Sat, 10 Sep 2005) | 4 lines
+Changed paths:
+ M /trunk/asymptote/base/feynman.asy
+ M /trunk/asymptote/builtin.cc
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/runtime.cc
+ M /trunk/asymptote/runtime.h
+
+
+Removed scale(pair) in favour of scale(abs(z))*rotate(degrees(z)) to avoid
+confusion with xscale(z.x)*yscale(z.y).
+
+------------------------------------------------------------------------
+r940 | jcbowman | 2005-09-09 23:58:11 -0600 (Fri, 09 Sep 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/plain.asy
+ M /trunk/asymptote/doc/asymptote.texi
+
+Don't cache MidArrow and Bar sizes.
+
+------------------------------------------------------------------------
+r939 | jcbowman | 2005-09-08 22:24:26 -0600 (Thu, 08 Sep 2005) | 8 lines
+Changed paths:
+ M /trunk/asymptote/base/geometry.asy
+ M /trunk/asymptote/base/three.asy
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/examples/Pythagoras.asy
+ M /trunk/asymptote/examples/cosaddition.asy
+
+
+More intuitive interface: perpendicular(pair z, pair align) now uses an
+alignment argument.
+
+Documented virtual structure functions.
+
+Updated documentation to emphasize that face is derived from picture.
+
+------------------------------------------------------------------------
+r938 | jcbowman | 2005-09-08 10:38:27 -0600 (Thu, 08 Sep 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+
+Updated Help section.
+
+------------------------------------------------------------------------
+r937 | jcbowman | 2005-09-07 12:13:36 -0600 (Wed, 07 Sep 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+
+Updated documentation.
+
+------------------------------------------------------------------------
+r936 | jcbowman | 2005-09-07 08:45:08 -0600 (Wed, 07 Sep 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+
+Document structure inheritance.
+
+------------------------------------------------------------------------
+r935 | jcbowman | 2005-09-07 02:22:17 -0600 (Wed, 07 Sep 2005) | 7 lines
+Changed paths:
+ M /trunk/asymptote/base/graph.asy
+ M /trunk/asymptote/base/plain.asy
+ M /trunk/asymptote/base/three.asy
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/doc/diatom.asy
+ M /trunk/asymptote/doc/surface.asy
+ M /trunk/asymptote/doc/unitcircle3.asy
+ M /trunk/asymptote/drawpath.cc
+ M /trunk/asymptote/examples/wheelanimation.asy
+
+
+Fixed floating point exception problems in axes routines.
+
+Check for negative linetype arguments.
+
+Minor example updates.
+
+------------------------------------------------------------------------
+r934 | hammera | 2005-09-06 21:40:47 -0600 (Tue, 06 Sep 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/name.h
+ M /trunk/asymptote/runtime.cc
+
+Changed indenting.
+
+------------------------------------------------------------------------
+r933 | jcbowman | 2005-09-06 01:42:51 -0600 (Tue, 06 Sep 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/configure.ac
+
+Incremented version to 0.88cvs.
+
+------------------------------------------------------------------------
+r932 | jcbowman | 2005-09-06 01:01:17 -0600 (Tue, 06 Sep 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/doc/unitcircle3.asy
+
+Minor documentation updates.
+
+------------------------------------------------------------------------
+r931 | jcbowman | 2005-09-06 00:26:06 -0600 (Tue, 06 Sep 2005) | 3 lines
+Changed paths:
+ M /trunk/asymptote/access.h
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/entry.h
+ M /trunk/asymptote/exp.h
+
+
+Fixed cxx warning messages.
+
+------------------------------------------------------------------------
+r930 | jcbowman | 2005-09-05 23:59:01 -0600 (Mon, 05 Sep 2005) | 8 lines
+Changed paths:
+ M /trunk/asymptote/TODO
+ M /trunk/asymptote/base/patterns.asy
+ M /trunk/asymptote/base/plain.asy
+ M /trunk/asymptote/doc/asymptote.texi
+ A /trunk/asymptote/doc/unitcircle3.asy
+ M /trunk/asymptote/examples/conicurv.asy
+
+
+Added pen option to filltype to specify an interior pen distinct from the
+boundary pen. Removed Filltype in patterns in favour of a deferred filltype.
+
+Removed explicit size arguments from bbox (as done with shipout some time ago).
+
+Updated filltype and 3d documentation.
+
+------------------------------------------------------------------------
+r929 | jcbowman | 2005-09-05 22:01:25 -0600 (Mon, 05 Sep 2005) | 25 lines
+Changed paths:
+ M /trunk/asymptote/TODO
+ M /trunk/asymptote/base/drawtree.asy
+ M /trunk/asymptote/base/math.asy
+ M /trunk/asymptote/base/plain.asy
+ M /trunk/asymptote/base/three.asy
+ M /trunk/asymptote/base/tree.asy
+ M /trunk/asymptote/builtin.cc
+ M /trunk/asymptote/dec.cc
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/doc/helix.asy
+ A /trunk/asymptote/doc/planes.asy
+ M /trunk/asymptote/doc/subpictures.asy
+ M /trunk/asymptote/doc/surface.asy
+ M /trunk/asymptote/examples/conicurv.asy
+ M /trunk/asymptote/examples/near_earth.asy
+ D /trunk/asymptote/examples/planes.asy
+ M /trunk/asymptote/runtime.cc
+ M /trunk/asymptote/runtime.h
+ M /trunk/asymptote/types.cc
+
+
+Implemented general hidden surface removal using a binary space partition.
+
+Fixed perspective and orthographic when camera is below the XY plane.
+Also added perspective(real,real,real) and orthographic(real,real,real)
+functions.
+
+Fixed draw((0,0,0)..(1,0,0)) and draw((0,0,0)).
+
+Added convenient 3d circle and arc functions.
+
+Added abs(triple) (equivalent to length(triple)).
+
+Added Longitude(triple), which ignores errors along +/- Z axis.
+
+Ported near_earth and conicurv examples from featpost3D.asy to three.asy.
+
+Added == and != for structures (equivalent to alias and !alias, respectively).
+
+For convenience, array push members now return the pushed element.
+
+Added missing shift in Label.out(frame).
+
+Updated documentation.
+
+------------------------------------------------------------------------
+r928 | hammera | 2005-09-03 20:33:09 -0600 (Sat, 03 Sep 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/coder.h
+ M /trunk/asymptote/entry.cc
+ M /trunk/asymptote/entry.h
+ M /trunk/asymptote/name.cc
+
+Added permissions back in.
+
+------------------------------------------------------------------------
+r927 | hammera | 2005-09-03 14:05:22 -0600 (Sat, 03 Sep 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/tests/Makefile
+ A /trunk/asymptote/tests/frames
+ A /trunk/asymptote/tests/frames/stat.asy
+ A /trunk/asymptote/tests/frames/stat2.asy
+ A /trunk/asymptote/tests/types
+ A /trunk/asymptote/tests/types/cast.asy
+ A /trunk/asymptote/tests/types/ecast.asy
+ A /trunk/asymptote/tests/types/init.asy
+
+Added more testing.
+
+------------------------------------------------------------------------
+r926 | hammera | 2005-09-03 14:04:15 -0600 (Sat, 03 Sep 2005) | 8 lines
+Changed paths:
+ M /trunk/asymptote/Makefile.in
+ M /trunk/asymptote/access.cc
+ M /trunk/asymptote/access.h
+ M /trunk/asymptote/camp.l
+ M /trunk/asymptote/camp.y
+ M /trunk/asymptote/coder.cc
+ M /trunk/asymptote/coder.h
+ M /trunk/asymptote/coenv.cc
+ M /trunk/asymptote/dec.cc
+ M /trunk/asymptote/dec.h
+ M /trunk/asymptote/entry.cc
+ M /trunk/asymptote/entry.h
+ M /trunk/asymptote/env.h
+ M /trunk/asymptote/exp.cc
+ M /trunk/asymptote/exp.h
+ M /trunk/asymptote/frame.h
+ A /trunk/asymptote/fundec.cc
+ A /trunk/asymptote/fundec.h
+ M /trunk/asymptote/import.cc
+ M /trunk/asymptote/importaccess.h
+ A /trunk/asymptote/modifier.h
+ M /trunk/asymptote/name.cc
+ M /trunk/asymptote/name.h
+ M /trunk/asymptote/newexp.cc
+ M /trunk/asymptote/newexp.h
+ M /trunk/asymptote/record.h
+ M /trunk/asymptote/varinit.cc
+ M /trunk/asymptote/varinit.h
+
+Refactoring!
+
+- most #include "camp.tab.h" lines removed in favor of modifier.h
+- access now uses actions (READ, WRITE, CALL) to control encoding
+- fundef and newFunctionExp merged
+- name refactor, and it also uses actions
+- permission information moved to varEntry (but not in use yet)
+
+------------------------------------------------------------------------
+r925 | jcbowman | 2005-09-01 15:26:50 -0600 (Thu, 01 Sep 2005) | 5 lines
+Changed paths:
+ M /trunk/asymptote/base/graph.asy
+ M /trunk/asymptote/base/graph3.asy
+ M /trunk/asymptote/base/three.asy
+ M /trunk/asymptote/doc/surface.asy
+
+
+Moved surface to graph3.
+
+Added 3d analogues of 2d graph functions.
+
+------------------------------------------------------------------------
+r924 | jcbowman | 2005-09-01 12:52:52 -0600 (Thu, 01 Sep 2005) | 9 lines
+Changed paths:
+ M /trunk/asymptote/TODO
+ M /trunk/asymptote/base/math.asy
+ M /trunk/asymptote/base/three.asy
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/doc/helix.asy
+ M /trunk/asymptote/doc/surface.asy
+
+
+Added numerically robust quadratic equation solver.
+
+Added min(path3) and max(path3) functions.
+
+Simplified and documented 3d arc (analogous to 2d arc).
+
+Implemented path3 to guide3 cast.
+
+------------------------------------------------------------------------
+r923 | jcbowman | 2005-09-01 02:12:51 -0600 (Thu, 01 Sep 2005) | 4 lines
+Changed paths:
+ M /trunk/asymptote/TODO
+ M /trunk/asymptote/base/three.asy
+ M /trunk/asymptote/doc/surface.asy
+ M /trunk/asymptote/path.cc
+
+Added 3d intersect and dir functions.
+
+Added 3d arc function that is consistent with the usual circle approximation.
+
+------------------------------------------------------------------------
+r922 | jcbowman | 2005-08-31 18:26:04 -0600 (Wed, 31 Aug 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/geometry.asy
+
+Removed diagnostic.
+
+------------------------------------------------------------------------
+r921 | jcbowman | 2005-08-31 18:23:57 -0600 (Wed, 31 Aug 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/geometry.asy
+ M /trunk/asymptote/base/three.asy
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/examples/triangle.asy
+ M /trunk/asymptote/record.h
+
+Documented constructors; changed triangle.asy to use a constructor.
+
+------------------------------------------------------------------------
+r920 | jcbowman | 2005-08-31 16:58:55 -0600 (Wed, 31 Aug 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/TODO
+ M /trunk/asymptote/coder.cc
+ M /trunk/asymptote/frame.h
+
+Fixed permissions for static functions in structs.
+
+------------------------------------------------------------------------
+r919 | jcbowman | 2005-08-31 11:24:46 -0600 (Wed, 31 Aug 2005) | 8 lines
+Changed paths:
+ M /trunk/asymptote/base/three.asy
+ M /trunk/asymptote/doc/Makefile
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/doc/datagraph.asy
+ M /trunk/asymptote/doc/image.asy
+ M /trunk/asymptote/doc/lineargraph0.asy
+ M /trunk/asymptote/doc/loggrid.asy
+ M /trunk/asymptote/doc/secondaryaxis.asy
+ A /trunk/asymptote/doc/subpictures.asy
+ M /trunk/asymptote/doc/superpath.asy
+
+Simplified path3 constructor.
+
+Added subpicture example.
+
+Fixed datagraph example.
+
+Minor documentation updates.
+
+------------------------------------------------------------------------
+r918 | jcbowman | 2005-08-31 01:41:29 -0600 (Wed, 31 Aug 2005) | 5 lines
+Changed paths:
+ M /trunk/asymptote/TODO
+ M /trunk/asymptote/base/three.asy
+
+Use same internal structure for path3 as for path, to facilitate port of
+various path.cc functions to 3d.
+
+Added subpath & associated functions.
+
+------------------------------------------------------------------------
+r917 | jcbowman | 2005-08-30 00:07:16 -0600 (Tue, 30 Aug 2005) | 6 lines
+Changed paths:
+ M /trunk/asymptote/base/plain.asy
+
+
+Expose Relative(pair) alignment function.
+
+Use arclength rather than length for determining default label position on
+paths.
+
+------------------------------------------------------------------------
+r916 | jcbowman | 2005-08-29 23:24:20 -0600 (Mon, 29 Aug 2005) | 5 lines
+Changed paths:
+ M /trunk/asymptote/Makefile.in
+ M /trunk/asymptote/TODO
+ M /trunk/asymptote/base/three.asy
+ M /trunk/asymptote/doc/surface.asy
+ M /trunk/asymptote/guide.h
+ M /trunk/asymptote/path.cc
+ M /trunk/asymptote/path.h
+ M /trunk/asymptote/runtime.in
+ A /trunk/asymptote/triple.cc
+ M /trunk/asymptote/triple.h
+
+
+Added path3 type. Separated project into path3 conversion and projection.
+
+Added 3d arclength and arctime functions.
+
+------------------------------------------------------------------------
+r915 | jcbowman | 2005-08-28 23:19:54 -0600 (Sun, 28 Aug 2005) | 3 lines
+Changed paths:
+ M /trunk/asymptote/base/three.asy
+
+For surface plots on a regular mesh, handle hidden surfaces from any camera
+location.
+
+------------------------------------------------------------------------
+r914 | jcbowman | 2005-08-28 03:16:04 -0600 (Sun, 28 Aug 2005) | 10 lines
+Changed paths:
+ M /trunk/asymptote/base/feynman.asy
+ M /trunk/asymptote/base/graph.asy
+ M /trunk/asymptote/base/plain.asy
+ M /trunk/asymptote/doc/Makefile
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/examples/eetomumu.asy
+
+Added Relative(real) and Relative(pair) functions for labelling paths
+relative to the total arclength and local path direction.
+
+Feynman updates (including new function texshipout); moved MidArrow and added
+MidArcArrow to plain.asy.
+
+Fixed optional position argument of BeginArrow, etc.
+
+Update documentation; simplified Makefile.
+
+------------------------------------------------------------------------
+r913 | jcbowman | 2005-08-25 14:44:40 -0600 (Thu, 25 Aug 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/configure.ac
+
+Incremented version to 0.87cvs.
+
+------------------------------------------------------------------------
+r912 | jcbowman | 2005-08-25 11:43:04 -0600 (Thu, 25 Aug 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/Makefile
+
+Fixed make clean.
+
+------------------------------------------------------------------------
+r911 | jcbowman | 2005-08-25 11:35:32 -0600 (Thu, 25 Aug 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/Makefile
+
+Fixed problems with make man.
+
+------------------------------------------------------------------------
+r910 | jcbowman | 2005-08-25 11:14:51 -0600 (Thu, 25 Aug 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/configure.ac
+
+Incremented version to 0.86cvs.
+
+------------------------------------------------------------------------
+r909 | jcbowman | 2005-08-25 04:10:49 -0600 (Thu, 25 Aug 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/Makefile
+
+Makefile tweaks.
+
+------------------------------------------------------------------------
+r908 | jcbowman | 2005-08-25 03:45:18 -0600 (Thu, 25 Aug 2005) | 4 lines
+Changed paths:
+ M /trunk/asymptote/doc/Makefile
+ M /trunk/asymptote/picture.cc
+
+Add hyperlinks to pdf manual; fixed margins.
+
+Use imdisplay for ImageMagick display under MSDOS.
+
+------------------------------------------------------------------------
+r907 | jcbowman | 2005-08-25 01:55:51 -0600 (Thu, 25 Aug 2005) | 5 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/mod.h
+ M /trunk/asymptote/runtime.cc
+ M /trunk/asymptote/settings.cc
+
+ASYMPTOTE_DIR can now be a list of directories (separated by : under UNIX
+and ; under MSDOS).
+
+Fixed size_t errors.
+
+------------------------------------------------------------------------
+r906 | jcbowman | 2005-08-25 00:38:31 -0600 (Thu, 25 Aug 2005) | 19 lines
+Changed paths:
+ M /trunk/asymptote/base/asy-mode.el
+ M /trunk/asymptote/base/asy.vim
+ M /trunk/asymptote/base/plain.asy
+ M /trunk/asymptote/base/three.asy
+ M /trunk/asymptote/builtin.cc
+ M /trunk/asymptote/camp.l
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/doc/surface.asy
+ M /trunk/asymptote/knot.cc
+ M /trunk/asymptote/knot.h
+ M /trunk/asymptote/runtime.cc
+ M /trunk/asymptote/runtime.h
+ M /trunk/asymptote/settings.cc
+ M /trunk/asymptote/types.cc
+
+
+Added curl3 operator.
+
+Implemented 3d generalization of Hobby's Metafont angle calculation
+that is invariant to rotation and reduces to his 2d splines in the planar case.
+
+Removed 3d direction specifiers (no longer required) from circle example in
+surface.asy.
+
+Merged and simplified tridiagonal solvers.
+
+When writing paths, output direction angles in degrees.
+
+Handle null cyclic arrays.
+
+Added min() and max() members of picture to calculate the picture size to date.
+
+Updated documentation.
+
+------------------------------------------------------------------------
+r905 | jcbowman | 2005-08-23 10:40:35 -0600 (Tue, 23 Aug 2005) | 3 lines
+Changed paths:
+ M /trunk/asymptote/picture.cc
+
+Diable automatic rotation of pdf files "based on the predominant orientation
+of the text on each page".
+
+------------------------------------------------------------------------
+r904 | jcbowman | 2005-08-18 20:24:56 -0600 (Thu, 18 Aug 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/runtime.cc
+
+Include boundary conditions in solution of Dirichlet tridiagonal solver.
+
+------------------------------------------------------------------------
+r903 | jcbowman | 2005-08-18 03:01:56 -0600 (Thu, 18 Aug 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/runtime.cc
+
+Fixed special case of periodic tridiagonal solver.
+
+------------------------------------------------------------------------
+r902 | jcbowman | 2005-08-18 02:27:01 -0600 (Thu, 18 Aug 2005) | 5 lines
+Changed paths:
+ M /trunk/asymptote/array.h
+ M /trunk/asymptote/base/graph.asy
+ M /trunk/asymptote/base/three.asy
+ M /trunk/asymptote/builtin.cc
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/doc/westnile.asy
+ M /trunk/asymptote/mod.h
+ M /trunk/asymptote/runtime.cc
+ M /trunk/asymptote/runtime.h
+ M /trunk/asymptote/types.cc
+
+
+Allow cyclic indices only on arrays with virtual cyclic flag set to true.
+
+Added Dirichlet and periodic tridiagonal solvers.
+
+------------------------------------------------------------------------
+r901 | jcbowman | 2005-08-17 01:33:03 -0600 (Wed, 17 Aug 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/plain.asy
+
+Reduce infinity for tension at least infinity on alpha platform.
+
+------------------------------------------------------------------------
+r900 | jcbowman | 2005-08-17 01:10:37 -0600 (Wed, 17 Aug 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/interact.cc
+ M /trunk/asymptote/settings.cc
+ M /trunk/asymptote/settings.h
+
+Make interactive help work in MSDOS.
+
+------------------------------------------------------------------------
+r899 | jcbowman | 2005-08-16 21:58:04 -0600 (Tue, 16 Aug 2005) | 3 lines
+Changed paths:
+ M /trunk/asymptote/configure.ac
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/interact.cc
+ M /trunk/asymptote/picture.cc
+ M /trunk/asymptote/settings.cc
+ M /trunk/asymptote/settings.h
+ M /trunk/asymptote/util.cc
+ M /trunk/asymptote/util.h
+
+Added online help option; exit is now a synonym for quit in
+interactive mode.
+
+------------------------------------------------------------------------
+r898 | jcbowman | 2005-08-16 11:21:25 -0600 (Tue, 16 Aug 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/Makefile.in
+ M /trunk/asymptote/asy.ico
+ M /trunk/asymptote/doc/icon.asy
+
+Improved icon.
+
+------------------------------------------------------------------------
+r897 | jcbowman | 2005-08-16 01:37:41 -0600 (Tue, 16 Aug 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/Makefile.in
+ M /trunk/asymptote/asy.ico
+ M /trunk/asymptote/asy.rc
+ A /trunk/asymptote/doc/icon.asy
+
+Fixed MSDOS build; improved icon.
+
+------------------------------------------------------------------------
+r896 | jcbowman | 2005-08-16 00:46:23 -0600 (Tue, 16 Aug 2005) | 2 lines
+Changed paths:
+ A /trunk/asymptote/asy.rc
+
+Windows resource template.
+
+------------------------------------------------------------------------
+r895 | jcbowman | 2005-08-16 00:45:31 -0600 (Tue, 16 Aug 2005) | 4 lines
+Changed paths:
+ M /trunk/asymptote/Compile
+ M /trunk/asymptote/Makefile.in
+ M /trunk/asymptote/README
+ A /trunk/asymptote/asy.ico
+ M /trunk/asymptote/base/simplex.asy
+ M /trunk/asymptote/configure.ac
+ M /trunk/asymptote/doc/asymptote.texi
+
+
+Improved configuration; added icon for Microsoft Windows.
+Updated documentation.
+
+------------------------------------------------------------------------
+r894 | hammera | 2005-08-15 21:56:13 -0600 (Mon, 15 Aug 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/simplex.asy
+
+Generalized bug fix in simplex.
+
+------------------------------------------------------------------------
+r893 | jcbowman | 2005-08-13 20:05:49 -0600 (Sat, 13 Aug 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/configure.ac
+
+Incremented version to 0.85cvs.
+
+------------------------------------------------------------------------
+r892 | jcbowman | 2005-08-13 16:04:24 -0600 (Sat, 13 Aug 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/Makefile.in
+
+Added compilation option msdos for producing Microsoft binaries.
+
+------------------------------------------------------------------------
+r891 | jcbowman | 2005-08-13 15:23:33 -0600 (Sat, 13 Aug 2005) | 2 lines
+Changed paths:
+ D /trunk/asymptote/base/graph3d.asy
+
+Removed obsolete file.
+
+------------------------------------------------------------------------
+r890 | jcbowman | 2005-08-13 14:29:43 -0600 (Sat, 13 Aug 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/simplex.asy
+
+Workaround truesize=0 bug in simplex.asy.
+
+------------------------------------------------------------------------
+r889 | jcbowman | 2005-08-13 02:14:40 -0600 (Sat, 13 Aug 2005) | 6 lines
+Changed paths:
+ M /trunk/asymptote/array.h
+ M /trunk/asymptote/base/math.asy
+ M /trunk/asymptote/base/palette.asy
+ M /trunk/asymptote/base/plain.asy
+ M /trunk/asymptote/builtin.cc
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/drawelement.h
+ M /trunk/asymptote/drawfill.cc
+ M /trunk/asymptote/drawfill.h
+ A /trunk/asymptote/examples/latticeshading.asy
+ M /trunk/asymptote/psfile.cc
+ M /trunk/asymptote/psfile.h
+ M /trunk/asymptote/runtime.cc
+ M /trunk/asymptote/runtime.h
+ M /trunk/asymptote/transform.h
+ M /trunk/asymptote/types.cc
+ M /trunk/asymptote/types.h
+
+
+Added lattice gradient shading; check pen size in Gouraud shading to avoid
+segmentation fault.
+
+Copy data and palette arrays in palette.asy.
+
+------------------------------------------------------------------------
+r888 | jcbowman | 2005-08-12 22:06:54 -0600 (Fri, 12 Aug 2005) | 5 lines
+Changed paths:
+ M /trunk/asymptote/base/three.asy
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/examples/Gouraud.asy
+ M /trunk/asymptote/transform.h
+
+Added 3d reflections.
+
+Swapped triple arguments of rotate(real,triple,triple) for consistency
+with the 2d reflect(pair,pair) syntax.
+
+------------------------------------------------------------------------
+r887 | jcbowman | 2005-08-12 18:58:04 -0600 (Fri, 12 Aug 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/arrayop.h
+ M /trunk/asymptote/runtime.cc
+ M /trunk/asymptote/runtime.h
+
+Removed (size_t) array.size() casts as they are no longer needed.
+
+------------------------------------------------------------------------
+r886 | jcbowman | 2005-08-12 17:43:09 -0600 (Fri, 12 Aug 2005) | 4 lines
+Changed paths:
+ M /trunk/asymptote/base/plain.asy
+ M /trunk/asymptote/builtin.cc
+ M /trunk/asymptote/camp.l
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/drawfill.cc
+ M /trunk/asymptote/drawfill.h
+ M /trunk/asymptote/drawimage.h
+ A /trunk/asymptote/examples/Gouraud.asy
+ M /trunk/asymptote/psfile.cc
+ M /trunk/asymptote/psfile.h
+ M /trunk/asymptote/runtime.cc
+ M /trunk/asymptote/runtime.h
+
+Added support for Gouraud shading.
+
+Moved nullpath into plain.asy.
+
+------------------------------------------------------------------------
+r885 | jcbowman | 2005-08-12 14:01:12 -0600 (Fri, 12 Aug 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/graph.asy
+ M /trunk/asymptote/base/palette.asy
+ M /trunk/asymptote/base/plain.asy
+ M /trunk/asymptote/doc/asymptote.texi
+
+Cleaned up autosize code; more pair to align changes.
+
+------------------------------------------------------------------------
+r884 | jcbowman | 2005-08-12 01:22:26 -0600 (Fri, 12 Aug 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/graph.asy
+ M /trunk/asymptote/examples/coag.asy
+
+Updated example; removed extra instance of defaultformat.
+
+------------------------------------------------------------------------
+r883 | jcbowman | 2005-08-12 01:04:45 -0600 (Fri, 12 Aug 2005) | 34 lines
+Changed paths:
+ M /trunk/asymptote/base/drawtree.asy
+ M /trunk/asymptote/base/featpost3D.asy
+ M /trunk/asymptote/base/graph.asy
+ M /trunk/asymptote/base/palette.asy
+ M /trunk/asymptote/base/plain.asy
+ M /trunk/asymptote/base/pstoedit.asy
+ M /trunk/asymptote/builtin.cc
+ M /trunk/asymptote/camp.y
+ M /trunk/asymptote/dec.cc
+ M /trunk/asymptote/doc/Bode.asy
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/doc/datagraph.asy
+ M /trunk/asymptote/doc/diatom.asy
+ M /trunk/asymptote/doc/generalaxis.asy
+ M /trunk/asymptote/doc/helix.asy
+ M /trunk/asymptote/doc/latexusage.tex
+ M /trunk/asymptote/doc/lineargraph.asy
+ M /trunk/asymptote/doc/mosquito.asy
+ M /trunk/asymptote/doc/secondaryaxis.asy
+ M /trunk/asymptote/doc/surface.asy
+ M /trunk/asymptote/doc/westnile.asy
+ M /trunk/asymptote/env.h
+ M /trunk/asymptote/examples/cardiod.asy
+ M /trunk/asymptote/examples/circles.asy
+ M /trunk/asymptote/examples/cos2theta.asy
+ M /trunk/asymptote/examples/cosaddition.asy
+ M /trunk/asymptote/examples/delu.asy
+ M /trunk/asymptote/examples/elliptic.asy
+ M /trunk/asymptote/examples/fjortoft.asy
+ M /trunk/asymptote/examples/hierarchy.asy
+ M /trunk/asymptote/examples/labelbox.asy
+ M /trunk/asymptote/examples/log.asy
+ M /trunk/asymptote/examples/near_earth.asy
+ M /trunk/asymptote/examples/orthocenter.asy
+ M /trunk/asymptote/examples/phase.asy
+ M /trunk/asymptote/examples/polarcircle.asy
+ M /trunk/asymptote/examples/sin1x.asy
+ M /trunk/asymptote/examples/sinxlex.asy
+ M /trunk/asymptote/examples/sqrtx01.asy
+ M /trunk/asymptote/examples/sqrtx01y1.asy
+ M /trunk/asymptote/examples/triads.asy
+ M /trunk/asymptote/examples/unitcircle.asy
+ M /trunk/asymptote/examples/venn.asy
+ M /trunk/asymptote/examples/wheelanimation.asy
+ M /trunk/asymptote/examples/xxsq01.asy
+ M /trunk/asymptote/exp.cc
+ M /trunk/asymptote/exp.h
+ M /trunk/asymptote/patches/README
+ D /trunk/asymptote/patches/pstoedit-3.40asy.patch
+ A /trunk/asymptote/patches/pstoedit-3.41asy.patch
+ M /trunk/asymptote/pen.h
+ M /trunk/asymptote/runtime.cc
+ M /trunk/asymptote/runtime.h
+ M /trunk/asymptote/types.cc
+ M /trunk/asymptote/types.h
+
+
+Put label parameters in a structure called Label, to which a string can be
+cast, and which can be rotated and shifted (in Postscript coordinates).
+
+Updated examples and documentation.
+
+Fixed automatic sizing under picture transformation (particularly under
+rotation) and handling of an unspecified size in one direction (denoted by
+infinity).
+
+Added size(real Size) function that ensures each dimension is no more than
+Size.
+
+Added scale(bool) function for enabling or disabling autoscaling in both
+directions.
+
+Simplified 2d graph and palette code.
+
+Added begingroup/endgroup checks.
+
+Added array append method.
+
+Removed unused duplicate variable check code.
+
+Added virtual transform components and transform 6-tuple notation.
+
+Added pen and filltype to Legend.
+
+Removed labeldot(z) in favour of dot(Label,z).
+Removed labelbox and labelellipse in favour of box and ellipse.
+Removed labelxtick and labelytick in favour of xtick and ytick.
+
+Updated pstoedit support.
+
+------------------------------------------------------------------------
+r882 | jcbowman | 2005-08-06 22:49:23 -0600 (Sat, 06 Aug 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/plain.asy
+ M /trunk/asymptote/base/three.asy
+ M /trunk/asymptote/builtin.cc
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/drawclipbegin.h
+ M /trunk/asymptote/drawelement.h
+ M /trunk/asymptote/drawfill.cc
+ M /trunk/asymptote/drawfill.h
+ M /trunk/asymptote/picture.cc
+ M /trunk/asymptote/picture.h
+ M /trunk/asymptote/runtime.cc
+ M /trunk/asymptote/runtime.h
+ M /trunk/asymptote/runtime.in
+
+Used cast from path to path[] (superpath) to simply fill and clip code.
+
+------------------------------------------------------------------------
+r881 | jcbowman | 2005-08-06 09:18:40 -0600 (Sat, 06 Aug 2005) | 6 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/fileio.cc
+ M /trunk/asymptote/fileio.h
+ M /trunk/asymptote/interact.cc
+ M /trunk/asymptote/picture.cc
+ M /trunk/asymptote/util.cc
+
+Remove .asy_input on exit.
+
+Disable display (which requires Xwindows) under MSDOS.
+
+Minor documentation updates.
+
+------------------------------------------------------------------------
+r880 | jcbowman | 2005-08-06 02:26:52 -0600 (Sat, 06 Aug 2005) | 10 lines
+Changed paths:
+ M /trunk/asymptote/base/graph.asy
+ A /trunk/asymptote/base/graph3.asy
+ M /trunk/asymptote/base/palette.asy
+ M /trunk/asymptote/doc/Bode.asy
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/doc/bigsquare.asy
+ M /trunk/asymptote/doc/datagraph.asy
+ M /trunk/asymptote/doc/diagonal.asy
+ M /trunk/asymptote/doc/errorbars.asy
+ M /trunk/asymptote/doc/exp.asy
+ M /trunk/asymptote/doc/generalaxis.asy
+ M /trunk/asymptote/doc/hatch.asy
+ M /trunk/asymptote/doc/helix.asy
+ M /trunk/asymptote/doc/histogram.asy
+ M /trunk/asymptote/doc/image.asy
+ M /trunk/asymptote/doc/labelsquare.asy
+ M /trunk/asymptote/doc/lineargraph.asy
+ M /trunk/asymptote/doc/lineargraph0.asy
+ M /trunk/asymptote/doc/loggraph.asy
+ A /trunk/asymptote/doc/loggrid.asy
+ M /trunk/asymptote/doc/mosquito.asy
+ M /trunk/asymptote/doc/parametricgraph.asy
+ M /trunk/asymptote/doc/quartercircle.asy
+ M /trunk/asymptote/doc/secondaryaxis.asy
+ M /trunk/asymptote/doc/shadedtiling.asy
+ M /trunk/asymptote/doc/square.asy
+ M /trunk/asymptote/doc/superpath.asy
+ M /trunk/asymptote/doc/tile.asy
+
+Added simpler helix example.
+
+Moved pticklabel to LeftTicks, etc., as the argument plabel. Added pTick and
+ptick pen types for drawing big and small ticks with different sizes,
+bool beginlabel and endlabel for suppressing first and last labels,
+and extend for drawing ticks across the graph (useful for superimposing a grid
+on the graph).
+
+Improved optional first and last tick/label suppression.
+
+------------------------------------------------------------------------
+r879 | jcbowman | 2005-08-05 00:11:15 -0600 (Fri, 05 Aug 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/locate.cc
+ M /trunk/asymptote/picture.cc
+ M /trunk/asymptote/settings.cc
+ M /trunk/asymptote/util.cc
+ M /trunk/asymptote/util.h
+
+MSDOS environment variable tweaks.
+
+------------------------------------------------------------------------
+r878 | jcbowman | 2005-08-03 21:19:47 -0600 (Wed, 03 Aug 2005) | 11 lines
+Changed paths:
+ M /trunk/asymptote/doc/asy.1
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/locate.cc
+ M /trunk/asymptote/picture.cc
+ M /trunk/asymptote/settings.cc
+ M /trunk/asymptote/settings.h
+ M /trunk/asymptote/util.cc
+ M /trunk/asymptote/util.h
+
+Fixed MSDOS interactive mode: the postscript viewer child process should exit,
+not return. Searching for an available postscript viewer is not possible in
+general (but the desired viewer can be specified with the appropriate
+environment variable).
+
+Added environment variable ASYMPTOTE_GS and drag and drop support.
+
+Make -V the default under MSDOS. Added -n (-noView) option.
+
+Updated documentation.
+
+------------------------------------------------------------------------
+r877 | hammera | 2005-08-03 00:40:41 -0600 (Wed, 03 Aug 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+
+''
+
+------------------------------------------------------------------------
+r876 | jcbowman | 2005-08-02 16:56:01 -0600 (Tue, 02 Aug 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/configure.ac
+ M /trunk/asymptote/drawlabel.cc
+ A /trunk/asymptote/patches/cygwin_xdr.patch
+ M /trunk/asymptote/picture.cc
+ M /trunk/asymptote/util.h
+
+Port to MSDOS (via CYGWIN).
+
+------------------------------------------------------------------------
+r875 | jcbowman | 2005-07-30 18:06:58 -0600 (Sat, 30 Jul 2005) | 2 lines
+Changed paths:
+ D /trunk/asymptote/doc/shade.asy
+ M /trunk/asymptote/knot.cc
+
+Removed unused file.
+
+------------------------------------------------------------------------
+r874 | jcbowman | 2005-07-30 18:05:56 -0600 (Sat, 30 Jul 2005) | 5 lines
+Changed paths:
+ M /trunk/asymptote/base/plain.asy
+ M /trunk/asymptote/base/three.asy
+ M /trunk/asymptote/doc/asymptote.texi
+ A /trunk/asymptote/examples/shade.asy
+
+
+Changed operator :: and operator --- to loops.
+
+Simplified fill commands.
+
+------------------------------------------------------------------------
+r873 | jcbowman | 2005-07-28 16:11:45 -0600 (Thu, 28 Jul 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/picture.cc
+
+Remove %%DocumentPaperSizes: comment inserted by dvips 5.95a.
+
+------------------------------------------------------------------------
+r872 | jcbowman | 2005-07-23 20:44:32 -0600 (Sat, 23 Jul 2005) | 9 lines
+Changed paths:
+ M /trunk/asymptote/base/graph.asy
+ M /trunk/asymptote/base/graph3d.asy
+ M /trunk/asymptote/base/plain.asy
+ M /trunk/asymptote/base/three.asy
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/doc/exp.asy
+ M /trunk/asymptote/doc/latexusage.tex
+ M /trunk/asymptote/doc/parametricgraph.asy
+ M /trunk/asymptote/doc/surface.asy
+ M /trunk/asymptote/examples/cardiod.asy
+ M /trunk/asymptote/examples/centroidfg.asy
+ M /trunk/asymptote/examples/cos2theta.asy
+ M /trunk/asymptote/examples/integraltest.asy
+ M /trunk/asymptote/examples/log.asy
+ M /trunk/asymptote/examples/lowupint.asy
+ M /trunk/asymptote/examples/polararea.asy
+ M /trunk/asymptote/examples/polarcircle.asy
+ M /trunk/asymptote/examples/spiral.asy
+ M /trunk/asymptote/examples/sqrtx01.asy
+ M /trunk/asymptote/examples/sqrtx01y1.asy
+ M /trunk/asymptote/examples/tanh.asy
+ M /trunk/asymptote/examples/xxsq01.asy
+
+
+Simplified graph routines.
+
+Fixed nullguide3 problems.
+
+Began graph3d construction.
+
+Updated documentation and examples.
+
+------------------------------------------------------------------------
+r871 | jcbowman | 2005-07-19 01:21:19 -0600 (Tue, 19 Jul 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+
+Updated menus.
+
+------------------------------------------------------------------------
+r870 | jcbowman | 2005-07-19 01:20:58 -0600 (Tue, 19 Jul 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/configure.ac
+
+Incremented version to 0.84cvs.
+
+------------------------------------------------------------------------
+r869 | jcbowman | 2005-07-19 01:09:04 -0600 (Tue, 19 Jul 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/errors
+ M /trunk/asymptote/errortest.asy
+
+Updated error test.
+
+------------------------------------------------------------------------
+r868 | jcbowman | 2005-07-19 00:20:13 -0600 (Tue, 19 Jul 2005) | 5 lines
+Changed paths:
+ M /trunk/asymptote/base/three.asy
+ M /trunk/asymptote/doc/asymptote.texi
+
+
+Changed default angle for oblique projection to 45 degrees.
+
+Updated documentation.
+
+------------------------------------------------------------------------
+r867 | jcbowman | 2005-07-19 00:09:44 -0600 (Tue, 19 Jul 2005) | 15 lines
+Changed paths:
+ M /trunk/asymptote/base/plain.asy
+ M /trunk/asymptote/base/three.asy
+ M /trunk/asymptote/builtin.cc
+ M /trunk/asymptote/camp.l
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/doc/cube.asy
+ A /trunk/asymptote/doc/helix.asy
+ M /trunk/asymptote/knot.h
+ M /trunk/asymptote/runtime.cc
+ M /trunk/asymptote/runtime.h
+ M /trunk/asymptote/triple.h
+
+Used existing internal function relativedistance for control point
+computations.
+
+Renamed path3 to flatguide3.
+
+Added tension3 specifier.
+
+Standardized 3d angles, rotations, and scalings.
+
+Added guide3 operator :: and ---.
+
+Added write(path[]) and write(guide3[]).
+
+Added helix example and updated documentation.
+
+------------------------------------------------------------------------
+r866 | jcbowman | 2005-07-18 12:17:33 -0600 (Mon, 18 Jul 2005) | 3 lines
+Changed paths:
+ M /trunk/asymptote/base/three.asy
+ M /trunk/asymptote/doc/surface.asy
+
+Determined correct signs in direction-to-control point calculation;
+propagate directions across nodes.
+
+------------------------------------------------------------------------
+r865 | jcbowman | 2005-07-18 00:38:55 -0600 (Mon, 18 Jul 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/three.asy
+
+Implement preliminary 3d direction to control point conversion.
+
+------------------------------------------------------------------------
+r864 | jcbowman | 2005-07-17 22:52:16 -0600 (Sun, 17 Jul 2005) | 3 lines
+Changed paths:
+ M /trunk/asymptote/base/graph.asy
+ M /trunk/asymptote/base/palette.asy
+ M /trunk/asymptote/base/patterns.asy
+ M /trunk/asymptote/base/plain.asy
+ M /trunk/asymptote/doc/Bode.asy
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/doc/diatom.asy
+ M /trunk/asymptote/doc/generalaxis.asy
+ M /trunk/asymptote/doc/image.asy
+ M /trunk/asymptote/doc/parametricgraph.asy
+
+Move math mode ($ delimiters) to within defaultformat string, to allow use of
+non-math mode fonts in tick labels (by providing a nondefault format string).
+
+------------------------------------------------------------------------
+r863 | jcbowman | 2005-07-17 19:20:33 -0600 (Sun, 17 Jul 2005) | 7 lines
+Changed paths:
+ M /trunk/asymptote/base/geometry.asy
+ M /trunk/asymptote/base/math.asy
+ M /trunk/asymptote/base/plain.asy
+ M /trunk/asymptote/builtin.cc
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/knot.cc
+ M /trunk/asymptote/runtime.cc
+ M /trunk/asymptote/runtime.h
+
+
+Fixed bug in string font(pen).
+
+Changed Angle(pair) to degrees(pair).
+
+Added Degrees(pair).
+
+------------------------------------------------------------------------
+r862 | jcbowman | 2005-07-17 15:36:54 -0600 (Sun, 17 Jul 2005) | 3 lines
+Changed paths:
+ M /trunk/asymptote/castop.h
+
+Allow reading three-dimensional arrays in line mode by recognizing blank
+lines as block delimiters.
+
+------------------------------------------------------------------------
+r861 | jcbowman | 2005-07-17 00:56:24 -0600 (Sun, 17 Jul 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/graph.asy
+ M /trunk/asymptote/base/palette.asy
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/doc/datagraph.asy
+
+Added pticklabel option for drawing tick labels with a different pen.
+
+------------------------------------------------------------------------
+r860 | jcbowman | 2005-07-17 00:02:10 -0600 (Sun, 17 Jul 2005) | 5 lines
+Changed paths:
+ M /trunk/asymptote/base/graph.asy
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/doc/datagraph.asy
+ M /trunk/asymptote/doc/surface.asy
+ A /trunk/asymptote/examples/coag.asy
+ A /trunk/asymptote/examples/sqrtx01y1.asy
+ A /trunk/asymptote/examples/xxsq01.asy
+
+
+Added labelxtick and labelytick. Fixed tick size and shift in xtick.
+
+Updated documentation; added examples.
+
+------------------------------------------------------------------------
+r859 | jcbowman | 2005-07-16 19:25:01 -0600 (Sat, 16 Jul 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/graph.asy
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/examples/wheelanimation.asy
+
+Fixed problems with autoscaling and unextended axes.
+
+------------------------------------------------------------------------
+r858 | jcbowman | 2005-07-16 16:11:52 -0600 (Sat, 16 Jul 2005) | 4 lines
+Changed paths:
+ M /trunk/asymptote/base/graph.asy
+ M /trunk/asymptote/base/plain.asy
+ M /trunk/asymptote/base/simplex.asy
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/doc/latexusage.tex
+
+Renamed internal xequals and yequals routines to yaxisAt and xaxisAt.
+For clarity, renamed xline and yline routines to xequals and yequals.
+Added initializers.
+
+------------------------------------------------------------------------
+r857 | jcbowman | 2005-07-16 15:27:57 -0600 (Sat, 16 Jul 2005) | 3 lines
+Changed paths:
+ M /trunk/asymptote/settings.cc
+
+Disabled -laat while line-at-a-time mode is under construction (due to
+known segmentation fault).
+
+------------------------------------------------------------------------
+r856 | jcbowman | 2005-07-16 15:25:11 -0600 (Sat, 16 Jul 2005) | 4 lines
+Changed paths:
+ M /trunk/asymptote/base/featpost3D.asy
+ M /trunk/asymptote/base/graph.asy
+ M /trunk/asymptote/base/math.asy
+ M /trunk/asymptote/base/three.asy
+ M /trunk/asymptote/builtin.cc
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/doc/cube.asy
+ M /trunk/asymptote/examples/venn.asy
+ M /trunk/asymptote/runtime.cc
+ M /trunk/asymptote/runtime.h
+
+Added and documented remaining triple functions.
+
+Renamed Dot to dot and Cross to cross.
+
+------------------------------------------------------------------------
+r855 | jcbowman | 2005-07-15 23:24:33 -0600 (Fri, 15 Jul 2005) | 14 lines
+Changed paths:
+ M /trunk/asymptote/base/graph3d.asy
+ M /trunk/asymptote/base/plain.asy
+ M /trunk/asymptote/base/three.asy
+ M /trunk/asymptote/camp.l
+ M /trunk/asymptote/camp.y
+ M /trunk/asymptote/doc/asymptote.texi
+ A /trunk/asymptote/doc/colons.asy
+ M /trunk/asymptote/doc/cube.asy
+ A /trunk/asymptote/doc/dots.asy
+ A /trunk/asymptote/doc/join.asy
+ A /trunk/asymptote/doc/surface.asy
+ M /trunk/asymptote/examples/planes.asy
+ M /trunk/asymptote/frame.h
+ M /trunk/asymptote/knot.cc
+ M /trunk/asymptote/stack.cc
+
+
+Simplified three.asy; added oblique projection and ^^ operator.
+
+Added Metapost --- operator; allow :: to accept a direction specifier.
+
+Allow user-defined ++ binary operator (for consistency with -- binary
+operator).
+
+Minor knot velocity optimizations.
+
+Added surface example to documentation; updated cube example.
+
+Updated documentation; fixed cxx warning messages.
+
+------------------------------------------------------------------------
+r854 | hammera | 2005-07-15 18:08:15 -0600 (Fri, 15 Jul 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/flatguide.h
+
+Fixed crash caused by fixing previous crash.
+
+------------------------------------------------------------------------
+r853 | hammera | 2005-07-14 23:55:20 -0600 (Thu, 14 Jul 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/knot.cc
+
+Handle tensions in straight sections of paths as MetaPost does.
+
+------------------------------------------------------------------------
+r852 | hammera | 2005-07-14 23:36:10 -0600 (Thu, 14 Jul 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/flatguide.h
+ M /trunk/asymptote/knot.cc
+
+Fixed controls versus direction specifiers crash.
+
+------------------------------------------------------------------------
+r851 | jcbowman | 2005-07-13 23:49:56 -0600 (Wed, 13 Jul 2005) | 11 lines
+Changed paths:
+ M /trunk/asymptote/array.h
+ M /trunk/asymptote/base/math.asy
+ M /trunk/asymptote/base/plain.asy
+ M /trunk/asymptote/base/three.asy
+ M /trunk/asymptote/camp.y
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/runtime.cc
+ M /trunk/asymptote/runtime.h
+ M /trunk/asymptote/types.cc
+ M /trunk/asymptote/types.h
+
+Added array pop function.
+
+Give DIRTAG the same precedence as CONTROLS and TENSION.
+
+Added replacement :: for Metapost ... joiner (which selects an
+inflection-free path where possible).
+
+Added 3d direction specifiers, pending 3d conversion to control points...
+
+Added triple write and interp functions to plain.asy.
+
+------------------------------------------------------------------------
+r850 | jcbowman | 2005-07-13 12:43:04 -0600 (Wed, 13 Jul 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/knot.cc
+
+Formatting.
+
+------------------------------------------------------------------------
+r849 | jcbowman | 2005-07-13 10:22:40 -0600 (Wed, 13 Jul 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/three.asy
+
+Cleaned up controls.
+
+------------------------------------------------------------------------
+r848 | jcbowman | 2005-07-13 02:25:08 -0600 (Wed, 13 Jul 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/three.asy
+
+Renamed cycle3 to cycle.
+
+------------------------------------------------------------------------
+r847 | jcbowman | 2005-07-13 02:18:10 -0600 (Wed, 13 Jul 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/three.asy
+
+Renamed controls3 to controls.
+
+------------------------------------------------------------------------
+r846 | jcbowman | 2005-07-13 01:45:11 -0600 (Wed, 13 Jul 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/three.asy
+
+Added controls3.
+
+------------------------------------------------------------------------
+r845 | jcbowman | 2005-07-12 22:42:28 -0600 (Tue, 12 Jul 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/knot.cc
+
+Compute knot solving constants.
+
+------------------------------------------------------------------------
+r844 | jcbowman | 2005-07-12 22:41:55 -0600 (Tue, 12 Jul 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/arrayop.h
+ M /trunk/asymptote/builtin.cc
+
+Fixed write(guide).
+
+------------------------------------------------------------------------
+r843 | jcbowman | 2005-07-12 17:54:48 -0600 (Tue, 12 Jul 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/camp.l
+ M /trunk/asymptote/camp.y
+
+Allow operator ::.
+
+------------------------------------------------------------------------
+r842 | jcbowman | 2005-07-12 14:51:53 -0600 (Tue, 12 Jul 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/configure.ac
+ M /trunk/asymptote/interact.cc
+
+Added explicit check for readline remove_history.
+
+------------------------------------------------------------------------
+r841 | jcbowman | 2005-07-12 14:29:30 -0600 (Tue, 12 Jul 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+
+Readded installation hint about ancient readline versions.
+
+------------------------------------------------------------------------
+r840 | jcbowman | 2005-07-12 01:33:20 -0600 (Tue, 12 Jul 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/three.asy
+
+Fixed lookAtOrigin.
+
+------------------------------------------------------------------------
+r839 | jcbowman | 2005-07-11 23:40:32 -0600 (Mon, 11 Jul 2005) | 5 lines
+Changed paths:
+ M /trunk/asymptote/base/math.asy
+ M /trunk/asymptote/base/three.asy
+ M /trunk/asymptote/builtin.cc
+ M /trunk/asymptote/cast.cc
+ M /trunk/asymptote/pair.h
+ M /trunk/asymptote/triple.h
+
+
+Updates to triple and three.asy.
+
+Removed unused code.
+
+------------------------------------------------------------------------
+r838 | jcbowman | 2005-07-11 17:51:26 -0600 (Mon, 11 Jul 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/featpost3D.asy
+ M /trunk/asymptote/base/graph3d.asy
+ M /trunk/asymptote/base/math.asy
+ M /trunk/asymptote/builtin.cc
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/doc/cube.asy
+ M /trunk/asymptote/examples/conicurv.asy
+ M /trunk/asymptote/examples/near_earth.asy
+ M /trunk/asymptote/examples/planes.asy
+ M /trunk/asymptote/runtime.cc
+ M /trunk/asymptote/runtime.h
+ A /trunk/asymptote/triple.h
+
+Replaced vector by triple.
+
+------------------------------------------------------------------------
+r837 | jcbowman | 2005-07-11 13:40:51 -0600 (Mon, 11 Jul 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/three.asy
+ M /trunk/asymptote/exp.cc
+
+Fixed casting error message.
+
+------------------------------------------------------------------------
+r836 | jcbowman | 2005-07-11 09:03:05 -0600 (Mon, 11 Jul 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/angle.h
+ M /trunk/asymptote/base/stats.asy
+ M /trunk/asymptote/base/three.asy
+ M /trunk/asymptote/builtin.cc
+ M /trunk/asymptote/camp.y
+ M /trunk/asymptote/exp.cc
+ M /trunk/asymptote/exp.h
+ M /trunk/asymptote/fileio.h
+ M /trunk/asymptote/pair.h
+ M /trunk/asymptote/runtime.cc
+ M /trunk/asymptote/runtime.h
+ M /trunk/asymptote/runtime.in
+ M /trunk/asymptote/types.cc
+ M /trunk/asymptote/types.h
+
+Added triple type.
+
+------------------------------------------------------------------------
+r835 | hammera | 2005-07-08 18:07:10 -0600 (Fri, 08 Jul 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/three.asy
+
+Graphing tests.
+
+------------------------------------------------------------------------
+r834 | hammera | 2005-07-08 16:19:37 -0600 (Fri, 08 Jul 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/main.cc
+
+Moved laat diagnostic.
+
+------------------------------------------------------------------------
+r833 | hammera | 2005-07-08 12:23:29 -0600 (Fri, 08 Jul 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/coder.cc
+ M /trunk/asymptote/coder.h
+ M /trunk/asymptote/frame.h
+ M /trunk/asymptote/genv.cc
+ M /trunk/asymptote/genv.h
+ M /trunk/asymptote/item.h
+ M /trunk/asymptote/main.cc
+ M /trunk/asymptote/settings.cc
+ M /trunk/asymptote/settings.h
+ M /trunk/asymptote/stack.cc
+ M /trunk/asymptote/stack.h
+ M /trunk/asymptote/stm.h
+
+Proof-of-concept code for true line-at-a-time mode.
+
+------------------------------------------------------------------------
+r832 | jcbowman | 2005-07-07 16:32:43 -0600 (Thu, 07 Jul 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/plain.asy
+
+Removed path to pair[] ecast.
+
+------------------------------------------------------------------------
+r831 | jcbowman | 2005-07-07 14:51:54 -0600 (Thu, 07 Jul 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/examples/dragon.asy
+
+Updated example.
+
+------------------------------------------------------------------------
+r830 | jcbowman | 2005-07-07 14:51:10 -0600 (Thu, 07 Jul 2005) | 3 lines
+Changed paths:
+ M /trunk/asymptote/base/plain.asy
+ M /trunk/asymptote/base/three.asy
+ M /trunk/asymptote/doc/asymptote.texi
+
+Removed explicit pair[] to guide casts in favour of operator --(...) and
+operator ..(...).
+
+------------------------------------------------------------------------
+r829 | jcbowman | 2005-07-07 10:40:14 -0600 (Thu, 07 Jul 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/configure.ac
+
+Fixed default CFLAGS.
+
+------------------------------------------------------------------------
+r828 | jcbowman | 2005-07-07 09:42:18 -0600 (Thu, 07 Jul 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/configure.ac
+
+Fixed CFLAGS.
+
+------------------------------------------------------------------------
+r827 | jcbowman | 2005-07-07 01:42:09 -0600 (Thu, 07 Jul 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/asy.1
+ M /trunk/asymptote/doc/asymptote.texi
+
+Updated documentation.
+
+------------------------------------------------------------------------
+r826 | jcbowman | 2005-07-07 01:37:36 -0600 (Thu, 07 Jul 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/configure.ac
+
+Fixed error in CFLAGS.
+
+------------------------------------------------------------------------
+r825 | jcbowman | 2005-07-06 20:21:56 -0600 (Wed, 06 Jul 2005) | 10 lines
+Changed paths:
+ M /trunk/asymptote/base/graph.asy
+ M /trunk/asymptote/base/plain.asy
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/doc/parametricgraph.asy
+ M /trunk/asymptote/examples/dragon.asy
+ M /trunk/asymptote/examples/sin1x.asy
+
+
+Added implicit pair[] to guide and guide[] casts and explicit path to
+pair[] casts.
+
+Removed unnecessary guide=nullpath argument from graph calls.
+
+Renamed LinearInterp to Straight, to correspond to straight(path).
+
+Updated nullpath documentation to correspond to new solver.
+
+------------------------------------------------------------------------
+r824 | jcbowman | 2005-07-06 14:50:50 -0600 (Wed, 06 Jul 2005) | 3 lines
+Changed paths:
+ M /trunk/asymptote/settings.cc
+
+Removed -version command-line option to avoid ambiguity with -verbose
+(so that -vv, -vvv etc. will still work).
+
+------------------------------------------------------------------------
+r823 | hammera | 2005-07-06 09:11:39 -0600 (Wed, 06 Jul 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/entry.h
+
+Change NOHASH to use #ifdef.
+
+------------------------------------------------------------------------
+r822 | hammera | 2005-07-05 21:26:42 -0600 (Tue, 05 Jul 2005) | 2 lines
+Changed paths:
+ A /trunk/asymptote/base/three.asy
+
+Three dimensional drawing routines (in development).
+
+------------------------------------------------------------------------
+r821 | hammera | 2005-07-05 14:25:56 -0600 (Tue, 05 Jul 2005) | 3 lines
+Changed paths:
+ M /trunk/asymptote/builtin.cc
+ M /trunk/asymptote/exp.cc
+ M /trunk/asymptote/exp.h
+ M /trunk/asymptote/flatguide.h
+ M /trunk/asymptote/knot.cc
+ M /trunk/asymptote/knot.h
+ M /trunk/asymptote/types.h
+
+Join operators now use rest arguments.
+Fixed a bug in solving empty guides.
+
+------------------------------------------------------------------------
+r820 | hammera | 2005-07-05 14:24:33 -0600 (Tue, 05 Jul 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/dec.cc
+ M /trunk/asymptote/dec.h
+ M /trunk/asymptote/newexp.cc
+ M /trunk/asymptote/newexp.h
+
+Combined duplicate code for function defitions.
+
+------------------------------------------------------------------------
+r819 | jcbowman | 2005-07-04 16:36:50 -0600 (Mon, 04 Jul 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+
+Minor documentation updates.
+
+------------------------------------------------------------------------
+r818 | hammera | 2005-07-04 11:46:43 -0600 (Mon, 04 Jul 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/entry.cc
+ M /trunk/asymptote/entry.h
+ M /trunk/asymptote/genv.h
+ M /trunk/asymptote/record.h
+
+Added back venv::list().
+
+------------------------------------------------------------------------
+r817 | jcbowman | 2005-07-03 10:16:43 -0600 (Sun, 03 Jul 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/asy.1
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/settings.cc
+
+Added -version command line option.
+
+------------------------------------------------------------------------
+r816 | jcbowman | 2005-07-03 00:12:58 -0600 (Sun, 03 Jul 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/configure.ac
+
+Incremented version to 0.83cvs.
+
+------------------------------------------------------------------------
+r815 | jcbowman | 2005-07-02 23:02:03 -0600 (Sat, 02 Jul 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/asy.1
+
+Updated man page.
+
+------------------------------------------------------------------------
+r814 | jcbowman | 2005-07-02 22:51:28 -0600 (Sat, 02 Jul 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/frame.h
+ M /trunk/asymptote/inst.h
+ M /trunk/asymptote/stack.cc
+ M /trunk/asymptote/stack.h
+
+Fixed cxx warning messages.
+
+------------------------------------------------------------------------
+r813 | jcbowman | 2005-07-02 22:16:17 -0600 (Sat, 02 Jul 2005) | 3 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/exp.cc
+ M /trunk/asymptote/settings.cc
+ M /trunk/asymptote/settings.h
+
+Added -d command-line option to produce extra debugging messages
+(currently only "named argument may be mistaken for assignment" warning).
+
+------------------------------------------------------------------------
+r812 | jcbowman | 2005-07-02 21:39:27 -0600 (Sat, 02 Jul 2005) | 5 lines
+Changed paths:
+ M /trunk/asymptote/base/graph.asy
+ M /trunk/asymptote/base/plain.asy
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/doc/exp.asy
+ M /trunk/asymptote/doc/westnile.asy
+ M /trunk/asymptote/examples/centroidfg.asy
+ M /trunk/asymptote/examples/integraltest.asy
+ M /trunk/asymptote/examples/log.asy
+ M /trunk/asymptote/examples/lowupint.asy
+ M /trunk/asymptote/examples/phase.asy
+ M /trunk/asymptote/examples/spiral.asy
+
+
+Added arrow option to axes routines.
+
+Renamed xlabel and ylabel back to labelx and labely, respectively.
+
+------------------------------------------------------------------------
+r811 | jcbowman | 2005-07-02 16:07:35 -0600 (Sat, 02 Jul 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/access.h
+ M /trunk/asymptote/frame.h
+ M /trunk/asymptote/inst.h
+ M /trunk/asymptote/stack.cc
+ M /trunk/asymptote/stack.h
+
+Revert last changes.
+
+------------------------------------------------------------------------
+r810 | jcbowman | 2005-07-02 15:46:09 -0600 (Sat, 02 Jul 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/access.h
+ M /trunk/asymptote/configure.ac
+ M /trunk/asymptote/frame.h
+ M /trunk/asymptote/inst.h
+ M /trunk/asymptote/stack.cc
+ M /trunk/asymptote/stack.h
+
+Fixed more cxx warning messages.
+
+------------------------------------------------------------------------
+r809 | jcbowman | 2005-07-02 14:23:42 -0600 (Sat, 02 Jul 2005) | 5 lines
+Changed paths:
+ M /trunk/asymptote/Makefile.in
+ M /trunk/asymptote/configure.ac
+ M /trunk/asymptote/dec.cc
+ M /trunk/asymptote/frame.h
+
+
+Added configure option to detect ext/hash_map and set -DNOHASH accordingly.
+
+Fixed cxx warning messages.
+
+------------------------------------------------------------------------
+r808 | jcbowman | 2005-07-02 12:11:44 -0600 (Sat, 02 Jul 2005) | 3 lines
+Changed paths:
+ M /trunk/asymptote/base/graph.asy
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/doc/datagraph.asy
+ M /trunk/asymptote/doc/exp.asy
+ M /trunk/asymptote/doc/westnile.asy
+ M /trunk/asymptote/examples/centroidfg.asy
+ M /trunk/asymptote/examples/integraltest.asy
+ M /trunk/asymptote/examples/log.asy
+ M /trunk/asymptote/examples/lowupint.asy
+ M /trunk/asymptote/examples/phase.asy
+ M /trunk/asymptote/examples/spiral.asy
+
+Standardized xtick and ytick routines.
+Renamed labelx to xlabel and labely to ylabel.
+
+------------------------------------------------------------------------
+r807 | hammera | 2005-07-02 11:45:31 -0600 (Sat, 02 Jul 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/entry.cc
+ M /trunk/asymptote/entry.h
+ M /trunk/asymptote/env.h
+ M /trunk/asymptote/import.h
+ M /trunk/asymptote/memory.h
+ M /trunk/asymptote/types.cc
+ M /trunk/asymptote/types.h
+
+Added NOHASH option to compile on non-gcc compilers.
+
+------------------------------------------------------------------------
+r806 | hammera | 2005-07-02 09:55:32 -0600 (Sat, 02 Jul 2005) | 2 lines
+Changed paths:
+ A /trunk/asymptote/varinit.cc
+ A /trunk/asymptote/varinit.h
+
+Excised from exp.h so that dec.h includes less.
+
+------------------------------------------------------------------------
+r805 | hammera | 2005-07-02 09:49:23 -0600 (Sat, 02 Jul 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/Makefile.in
+ M /trunk/asymptote/camp.l
+ M /trunk/asymptote/camp.y
+ M /trunk/asymptote/dec.cc
+ M /trunk/asymptote/dec.h
+ M /trunk/asymptote/exp.cc
+ M /trunk/asymptote/exp.h
+ M /trunk/asymptote/stm.cc
+
+Allow dimensions for types in cast expression.
+
+------------------------------------------------------------------------
+r804 | jcbowman | 2005-07-02 03:24:05 -0600 (Sat, 02 Jul 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/graph.asy
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/doc/datagraph.asy
+ A /trunk/asymptote/doc/errorbars.asy
+
+Added ability to specify custom tick locations.
+
+------------------------------------------------------------------------
+r803 | jcbowman | 2005-07-01 22:58:28 -0600 (Fri, 01 Jul 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/runtime.cc
+
+Fix warning messages when XDR is disabled.
+
+------------------------------------------------------------------------
+r802 | jcbowman | 2005-07-01 22:57:53 -0600 (Fri, 01 Jul 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/graph.asy
+
+Added more default initializers.
+
+------------------------------------------------------------------------
+r801 | jcbowman | 2005-07-01 18:30:30 -0600 (Fri, 01 Jul 2005) | 3 lines
+Changed paths:
+ M /trunk/asymptote/TODO
+ M /trunk/asymptote/camp.y
+ M /trunk/asymptote/doc/asymptote.texi
+
+Allow explicit casts to any name. Documented general implicit and explicit
+casts.
+
+------------------------------------------------------------------------
+r800 | jcbowman | 2005-06-30 22:57:13 -0600 (Thu, 30 Jun 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/TODO
+ M /trunk/asymptote/doc/asymptote.texi
+
+Documented named function arguments and rest parameters.
+
+------------------------------------------------------------------------
+r799 | jcbowman | 2005-06-30 20:34:33 -0600 (Thu, 30 Jun 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/application.cc
+ M /trunk/asymptote/application.h
+ M /trunk/asymptote/exp.h
+ A /trunk/asymptote/patches/README
+ M /trunk/asymptote/patches/bison.patch
+ M /trunk/asymptote/types.cc
+
+Fixed warning messages; updated bison patch to bison-2.0a.
+
+------------------------------------------------------------------------
+r798 | jcbowman | 2005-06-30 16:45:32 -0600 (Thu, 30 Jun 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/env.h
+ M /trunk/asymptote/types.h
+
+Fixed more warning messages.
+
+------------------------------------------------------------------------
+r797 | jcbowman | 2005-06-30 16:42:23 -0600 (Thu, 30 Jun 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/fileio.h
+ M /trunk/asymptote/memory.h
+ M /trunk/asymptote/types.h
+
+Fixed cxx errors and warnings.
+
+------------------------------------------------------------------------
+r796 | jcbowman | 2005-06-30 16:38:14 -0600 (Thu, 30 Jun 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/util.cc
+
+Replaced strdup by strcpy.
+
+------------------------------------------------------------------------
+r795 | jcbowman | 2005-06-30 12:41:57 -0600 (Thu, 30 Jun 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/plain.asy
+ M /trunk/asymptote/builtin.cc
+ M /trunk/asymptote/camp.l
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/exp.cc
+ M /trunk/asymptote/exp.h
+ M /trunk/asymptote/runtime.cc
+ M /trunk/asymptote/runtime.h
+
+Renamed nullframe to newframe.
+
+------------------------------------------------------------------------
+r794 | jcbowman | 2005-06-29 21:04:53 -0600 (Wed, 29 Jun 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/fileio.h
+ M /trunk/asymptote/main.cc
+
+Fixed memory leak and segmentation fault in fileio garbage collection.
+
+------------------------------------------------------------------------
+r793 | jcbowman | 2005-06-29 20:58:11 -0600 (Wed, 29 Jun 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/plain.asy
+
+Renamed write function keywords.
+
+------------------------------------------------------------------------
+r792 | jcbowman | 2005-06-29 10:15:51 -0600 (Wed, 29 Jun 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/geometry.asy
+ M /trunk/asymptote/base/graph.asy
+ M /trunk/asymptote/base/graph3d.asy
+ M /trunk/asymptote/base/math.asy
+ M /trunk/asymptote/base/palette.asy
+ M /trunk/asymptote/base/patterns.asy
+ M /trunk/asymptote/base/plain.asy
+ M /trunk/asymptote/base/stats.asy
+ M /trunk/asymptote/base/tree.asy
+ M /trunk/asymptote/examples/triangle.asy
+
+Extend use of operator init().
+
+------------------------------------------------------------------------
+r791 | jcbowman | 2005-06-29 09:59:15 -0600 (Wed, 29 Jun 2005) | 4 lines
+Changed paths:
+ M /trunk/asymptote/base/plain.asy
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/doc/datagraph.asy
+ M /trunk/asymptote/doc/diatom.asy
+ M /trunk/asymptote/doc/image.asy
+ M /trunk/asymptote/doc/logo.asy
+ M /trunk/asymptote/doc/mosquito.asy
+ M /trunk/asymptote/doc/shadedtiling.asy
+ M /trunk/asymptote/examples/PythagoreanTree.asy
+ M /trunk/asymptote/examples/elliptic.asy
+ M /trunk/asymptote/examples/equilchord.asy
+ M /trunk/asymptote/examples/fjortoft.asy
+ M /trunk/asymptote/examples/planes.asy
+ M /trunk/asymptote/examples/venn.asy
+ M /trunk/asymptote/examples/wheelanimation.asy
+
+
+Added default initializer to picture; removed "=new picture" from examples.
+Documented operator init().
+
+------------------------------------------------------------------------
+r790 | jcbowman | 2005-06-29 09:11:58 -0600 (Wed, 29 Jun 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/graph.asy
+
+Removed ticksT tag.
+
+------------------------------------------------------------------------
+r789 | jcbowman | 2005-06-29 00:38:20 -0600 (Wed, 29 Jun 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/locate.cc
+ M /trunk/asymptote/locate.h
+ M /trunk/asymptote/memory.h
+
+Fixed memory leak in locateFile.
+
+------------------------------------------------------------------------
+r788 | jcbowman | 2005-06-28 16:16:00 -0600 (Tue, 28 Jun 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/xstream.h
+
+Removed unnecessary semicolons.
+
+------------------------------------------------------------------------
+r787 | jcbowman | 2005-06-28 15:56:58 -0600 (Tue, 28 Jun 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/application.h
+
+Added virtual destructor.
+
+------------------------------------------------------------------------
+r786 | jcbowman | 2005-06-28 15:53:29 -0600 (Tue, 28 Jun 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/callable.h
+ M /trunk/asymptote/fileio.h
+ M /trunk/asymptote/guide.h
+ M /trunk/asymptote/knot.h
+ M /trunk/asymptote/memory.h
+ M /trunk/asymptote/program.h
+ M /trunk/asymptote/types.h
+
+Added virtual destructors.
+
+------------------------------------------------------------------------
+r785 | jcbowman | 2005-06-28 14:49:30 -0600 (Tue, 28 Jun 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/plain.asy
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/examples/lowint.asy
+ M /trunk/asymptote/examples/spiral.asy
+ M /trunk/asymptote/examples/sqrtx01.asy
+ M /trunk/asymptote/examples/workcone.asy
+ M /trunk/asymptote/examples/yingyang.asy
+
+Remove xsize, ysize, and keepAspect from shipout, in favour of size().
+
+------------------------------------------------------------------------
+r784 | jcbowman | 2005-06-28 13:58:03 -0600 (Tue, 28 Jun 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/configure.ac
+
+Added -lgccpp also with --enable-gc=system.
+
+------------------------------------------------------------------------
+r783 | hammera | 2005-06-28 10:12:57 -0600 (Tue, 28 Jun 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/plain.asy
+
+Put reverse functions back in.
+
+------------------------------------------------------------------------
+r782 | hammera | 2005-06-28 10:01:21 -0600 (Tue, 28 Jun 2005) | 10 lines
+Changed paths:
+ M /trunk/asymptote/Makefile.in
+ M /trunk/asymptote/TODO
+ A /trunk/asymptote/application.cc
+ A /trunk/asymptote/application.h
+ M /trunk/asymptote/base/plain.asy
+ M /trunk/asymptote/builtin.cc
+ M /trunk/asymptote/camp.l
+ M /trunk/asymptote/camp.y
+ M /trunk/asymptote/cast.cc
+ M /trunk/asymptote/cast.h
+ M /trunk/asymptote/coder.h
+ M /trunk/asymptote/coenv.cc
+ M /trunk/asymptote/coenv.h
+ M /trunk/asymptote/configure.ac
+ M /trunk/asymptote/dec.cc
+ M /trunk/asymptote/dec.h
+ M /trunk/asymptote/entry.cc
+ M /trunk/asymptote/entry.h
+ M /trunk/asymptote/env.cc
+ M /trunk/asymptote/env.h
+ M /trunk/asymptote/exp.cc
+ M /trunk/asymptote/exp.h
+ M /trunk/asymptote/genv.cc
+ M /trunk/asymptote/genv.h
+ M /trunk/asymptote/import.cc
+ M /trunk/asymptote/import.h
+ M /trunk/asymptote/main.cc
+ M /trunk/asymptote/memory.h
+ M /trunk/asymptote/name.cc
+ M /trunk/asymptote/name.h
+ M /trunk/asymptote/newexp.cc
+ M /trunk/asymptote/record.cc
+ M /trunk/asymptote/record.h
+ M /trunk/asymptote/runtime.cc
+ M /trunk/asymptote/runtime.h
+ M /trunk/asymptote/stm.cc
+ M /trunk/asymptote/symbol.cc
+ M /trunk/asymptote/symbol.h
+ M /trunk/asymptote/types.cc
+ M /trunk/asymptote/types.h
+
+Results of type overhaul:
+ - venv now uses a hashtable to quickly look up variable of a specific type
+ - initializers and casts are now functions in the environment
+ - matching arguments to signatures handled by application class
+ - (side-effects of) expressions are evaulated left-to-right
+ - exp::trans(e, target) split into transToType (which implicitly casts) and
+ transToType (which doesn't)
+ - added keyword and rest arguments
+ - added formal class to types
+
+------------------------------------------------------------------------
+r781 | jcbowman | 2005-06-26 16:51:59 -0600 (Sun, 26 Jun 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/util.cc
+
+Work around spurious uninitialized warning message under gcc 3.3.3.
+
+------------------------------------------------------------------------
+r780 | jcbowman | 2005-06-26 10:51:17 -0600 (Sun, 26 Jun 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/util.cc
+
+Code cleanup.
+
+------------------------------------------------------------------------
+r779 | jcbowman | 2005-06-26 08:43:12 -0600 (Sun, 26 Jun 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/util.cc
+
+Allow use of single quotes to prevent system command word splitting on spaces.
+
+------------------------------------------------------------------------
+r778 | jcbowman | 2005-06-25 15:49:08 -0600 (Sat, 25 Jun 2005) | 6 lines
+Changed paths:
+ M /trunk/asymptote/base/plain.asy
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/drawfill.cc
+ M /trunk/asymptote/runtime.cc
+ M /trunk/asymptote/runtime.h
+
+
+Fixed bug in fill, due to a numerical precision issue, which shows up with
+g++-4.00 under optimization.
+
+Removed unused routine and declarations.
+
+------------------------------------------------------------------------
+r777 | jcbowman | 2005-06-25 14:11:19 -0600 (Sat, 25 Jun 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/table.h
+
+Removed unused virtual destructor.
+
+------------------------------------------------------------------------
+r776 | jcbowman | 2005-06-25 12:33:59 -0600 (Sat, 25 Jun 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/feynman.asy
+ M /trunk/asymptote/base/graph.asy
+ M /trunk/asymptote/base/patterns.asy
+ M /trunk/asymptote/base/plain.asy
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/examples/workcone.asy
+
+Simplified tag handling.
+
+------------------------------------------------------------------------
+r774 | jcbowman | 2005-06-25 00:14:38 -0600 (Sat, 25 Jun 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/plain.asy
+
+Replace OverwriteT with integer variables.
+
+------------------------------------------------------------------------
+r773 | jcbowman | 2005-06-24 18:58:34 -0600 (Fri, 24 Jun 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/plain.asy
+
+Simplified coding of endl and tab qualifiers.
+
+------------------------------------------------------------------------
+r771 | jcbowman | 2005-06-23 16:34:34 -0600 (Thu, 23 Jun 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/configure.ac
+
+Incremented version to 0.82cvs.
+
+------------------------------------------------------------------------
+r770 | jcbowman | 2005-06-23 16:08:48 -0600 (Thu, 23 Jun 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+
+Fixed indentation.
+
+------------------------------------------------------------------------
+r769 | jcbowman | 2005-06-23 15:55:47 -0600 (Thu, 23 Jun 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/drawelement.h
+ M /trunk/asymptote/guide.h
+ M /trunk/asymptote/knot.h
+ M /trunk/asymptote/pen.h
+ M /trunk/asymptote/runtime.cc
+ M /trunk/asymptote/types.cc
+
+Fixed g++-4.0.0 warning messages.
+
+------------------------------------------------------------------------
+r768 | jcbowman | 2005-06-23 15:54:46 -0600 (Thu, 23 Jun 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/table.h
+
+Fixed cxx compilation error.
+
+------------------------------------------------------------------------
+r767 | rtprince | 2005-06-23 00:45:25 -0600 (Thu, 23 Jun 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/runtime.h
+
+Cleanup headers.
+
+------------------------------------------------------------------------
+r766 | rtprince | 2005-06-22 23:53:11 -0600 (Wed, 22 Jun 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/main.cc
+
+Maybe fix GC on darwin.
+
+------------------------------------------------------------------------
+r765 | jcbowman | 2005-06-22 10:54:03 -0600 (Wed, 22 Jun 2005) | 4 lines
+Changed paths:
+ M /trunk/asymptote/arrayop.h
+ M /trunk/asymptote/base/plain.asy
+ M /trunk/asymptote/builtin.cc
+
+
+Replaced writeP in favour of write; added writen entry points for pen,
+guide, and transform.
+
+------------------------------------------------------------------------
+r764 | hammera | 2005-06-22 10:16:11 -0600 (Wed, 22 Jun 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/knot.cc
+
+Fixed solving bug.
+
+------------------------------------------------------------------------
+r763 | jcbowman | 2005-06-21 22:27:52 -0600 (Tue, 21 Jun 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/graph.asy
+
+Allow graphs with just one data point.
+
+------------------------------------------------------------------------
+r762 | jcbowman | 2005-06-20 17:03:14 -0600 (Mon, 20 Jun 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/feynman.asy
+ M /trunk/asymptote/examples/eetomumu.asy
+
+Feynman updates.
+
+------------------------------------------------------------------------
+r761 | rtprince | 2005-06-19 23:18:55 -0600 (Sun, 19 Jun 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/Makefile.in
+ M /trunk/asymptote/access.cc
+ M /trunk/asymptote/access.h
+ A /trunk/asymptote/array.h
+ M /trunk/asymptote/arrayop.h
+ M /trunk/asymptote/builtin.cc
+ M /trunk/asymptote/builtin.h
+ A /trunk/asymptote/callable.cc
+ A /trunk/asymptote/callable.h
+ M /trunk/asymptote/coder.h
+ M /trunk/asymptote/dec.cc
+ M /trunk/asymptote/drawimage.h
+ M /trunk/asymptote/exp.cc
+ M /trunk/asymptote/exp.h
+ D /trunk/asymptote/inst.cc
+ M /trunk/asymptote/inst.h
+ M /trunk/asymptote/main.cc
+ M /trunk/asymptote/name.cc
+ M /trunk/asymptote/newexp.cc
+ A /trunk/asymptote/program.cc
+ A /trunk/asymptote/program.h
+ M /trunk/asymptote/psfile.h
+ M /trunk/asymptote/record.cc
+ M /trunk/asymptote/record.h
+ M /trunk/asymptote/runtime.cc
+ M /trunk/asymptote/runtime.h
+ M /trunk/asymptote/stack.cc
+ M /trunk/asymptote/stack.h
+ M /trunk/asymptote/vm.h
+
+Split up inst.h.
+
+------------------------------------------------------------------------
+r760 | rtprince | 2005-06-19 17:53:14 -0600 (Sun, 19 Jun 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/table.h
+
+gcc4 is more const.
+
+------------------------------------------------------------------------
+r759 | jcbowman | 2005-06-19 14:16:22 -0600 (Sun, 19 Jun 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/configure.ac
+
+Incremented version to 0.81cvs.
+
+------------------------------------------------------------------------
+r758 | jcbowman | 2005-06-19 12:08:27 -0600 (Sun, 19 Jun 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/INSTALL
+ M /trunk/asymptote/configure.ac
+ M /trunk/asymptote/doc/asymptote.texi
+
+Upgrade to use Boehm gc6.5 garbage collector.
+
+------------------------------------------------------------------------
+r757 | jcbowman | 2005-06-19 11:43:34 -0600 (Sun, 19 Jun 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/pool.h
+
+Tom's patch to pool segmentation fault.
+
+------------------------------------------------------------------------
+r756 | rtprince | 2005-06-18 10:44:58 -0600 (Sat, 18 Jun 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/coder.cc
+ M /trunk/asymptote/inst.h
+
+Remove obsolete maxStackSize.
+
+------------------------------------------------------------------------
+r755 | jcbowman | 2005-06-18 10:27:49 -0600 (Sat, 18 Jun 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/plain.asy
+
+Deep copy all members of picture.
+
+------------------------------------------------------------------------
+r754 | jcbowman | 2005-06-18 09:59:39 -0600 (Sat, 18 Jun 2005) | 2 lines
+Changed paths:
+ A /trunk/asymptote/INSTALL
+
+Quick installation instructions.
+
+------------------------------------------------------------------------
+r753 | rtprince | 2005-06-18 00:28:36 -0600 (Sat, 18 Jun 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/Makefile.in
+ A /trunk/asymptote/tests/arith
+ A /trunk/asymptote/tests/arith/add.asy
+ A /trunk/asymptote/tests/bench
+ A /trunk/asymptote/tests/bench/6000circles.asy
+
+Tests.
+
+------------------------------------------------------------------------
+r752 | jcbowman | 2005-06-17 23:35:20 -0600 (Fri, 17 Jun 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/configure.ac
+
+Incremented version to 0.80cvs.
+
+------------------------------------------------------------------------
+r751 | jcbowman | 2005-06-17 22:49:15 -0600 (Fri, 17 Jun 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/Makefile.in
+
+Removed unused features.
+
+------------------------------------------------------------------------
+r750 | jcbowman | 2005-06-17 22:32:31 -0600 (Fri, 17 Jun 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/runtime.in
+
+Fixed cxx warning messages.
+
+------------------------------------------------------------------------
+r749 | jcbowman | 2005-06-17 22:06:19 -0600 (Fri, 17 Jun 2005) | 3 lines
+Changed paths:
+ M /trunk/asymptote/base/graph.asy
+ M /trunk/asymptote/base/plain.asy
+ A /trunk/asymptote/doc/Bode.asy
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/doc/secondaryaxis.asy
+
+Check for empty picture in secondary axes routines; added another example
+of a secondary axis.
+
+------------------------------------------------------------------------
+r748 | rtprince | 2005-06-17 21:27:16 -0600 (Fri, 17 Jun 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/Makefile.in
+ M /trunk/asymptote/builtin.cc
+ A /trunk/asymptote/genrun.h
+ M /trunk/asymptote/runtime.cc
+ M /trunk/asymptote/runtime.in
+ M /trunk/asymptote/runtime.pl
+ A /trunk/asymptote/tests/Makefile
+ A /trunk/asymptote/tests/TestLib.asy
+ A /trunk/asymptote/tests/string
+ A /trunk/asymptote/tests/string/erase.asy
+ A /trunk/asymptote/tests/string/find.asy
+ A /trunk/asymptote/tests/string/insert.asy
+ A /trunk/asymptote/tests/string/length.asy
+ A /trunk/asymptote/tests/string/rfind.asy
+ A /trunk/asymptote/tests/string/substr.asy
+ M /trunk/asymptote/wce
+
+Automate testing.
+
+------------------------------------------------------------------------
+r747 | rtprince | 2005-06-17 21:21:51 -0600 (Fri, 17 Jun 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/coder.cc
+ M /trunk/asymptote/coder.h
+ M /trunk/asymptote/inst.cc
+ M /trunk/asymptote/inst.h
+ M /trunk/asymptote/stack.cc
+
+Change vm::program to holds insts directly.
+
+------------------------------------------------------------------------
+r746 | rtprince | 2005-06-17 21:20:48 -0600 (Fri, 17 Jun 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/Makefile.in
+ M /trunk/asymptote/builtin.cc
+ M /trunk/asymptote/builtin.h
+ M /trunk/asymptote/runtime.in
+ M /trunk/asymptote/runtime.pl
+
+Compile genrun.cc seprately.
+
+------------------------------------------------------------------------
+r745 | rtprince | 2005-06-17 21:19:51 -0600 (Fri, 17 Jun 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/camperror.cc
+ M /trunk/asymptote/main.cc
+ M /trunk/asymptote/stack.h
+ M /trunk/asymptote/tests/gc/file.asy
+ A /trunk/asymptote/vm.h
+
+Move vm interface to vm.h.
+
+------------------------------------------------------------------------
+r744 | rtprince | 2005-06-17 18:48:32 -0600 (Fri, 17 Jun 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/configure.ac
+ M /trunk/asymptote/fileio.h
+ M /trunk/asymptote/main.cc
+ M /trunk/asymptote/memory.h
+ M /trunk/asymptote/pool.h
+ M /trunk/asymptote/tests/gc/file.asy
+
+Properly collect fileio.
+
+------------------------------------------------------------------------
+r743 | rtprince | 2005-06-16 00:20:47 -0600 (Thu, 16 Jun 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/runtime.cc
+
+item handles GC allocation.
+
+------------------------------------------------------------------------
+r742 | jcbowman | 2005-06-16 00:12:16 -0600 (Thu, 16 Jun 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/runtime.cc
+
+Readded 2005-05-26 fix for substr bug.
+
+------------------------------------------------------------------------
+r741 | rtprince | 2005-06-15 23:47:13 -0600 (Wed, 15 Jun 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/absyn.h
+ M /trunk/asymptote/access.h
+ M /trunk/asymptote/dec.cc
+ M /trunk/asymptote/dec.h
+ M /trunk/asymptote/drawelement.h
+ M /trunk/asymptote/entry.h
+ M /trunk/asymptote/errormsg.h
+ M /trunk/asymptote/exp.h
+ M /trunk/asymptote/flatguide.h
+ M /trunk/asymptote/frame.h
+ M /trunk/asymptote/import.h
+ M /trunk/asymptote/inst.h
+ M /trunk/asymptote/main.cc
+ M /trunk/asymptote/memory.h
+ M /trunk/asymptote/pen.h
+ M /trunk/asymptote/runtime.cc
+ M /trunk/asymptote/stm.h
+ M /trunk/asymptote/table.h
+ M /trunk/asymptote/tests/gc/file.asy
+ M /trunk/asymptote/tests/gc/pen.asy
+ M /trunk/asymptote/types.h
+
+Make evrything use GC (except fileio).
+
+------------------------------------------------------------------------
+r740 | jcbowman | 2005-06-14 22:33:17 -0600 (Tue, 14 Jun 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/plain.asy
+
+Don't allow a picture to be added to itself.
+
+------------------------------------------------------------------------
+r739 | jcbowman | 2005-06-14 20:30:06 -0600 (Tue, 14 Jun 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/castop.h
+
+Backported recent castop.h change to g++ 3.3.4.
+
+------------------------------------------------------------------------
+r738 | hammera | 2005-06-14 15:23:42 -0600 (Tue, 14 Jun 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/exp.cc
+ M /trunk/asymptote/exp.h
+
+Added getType caching.
+
+------------------------------------------------------------------------
+r737 | jcbowman | 2005-06-13 10:28:09 -0600 (Mon, 13 Jun 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/configure.ac
+ M /trunk/asymptote/memory.h
+
+Reverted gc/gc.h change back to gc.h.
+
+------------------------------------------------------------------------
+r736 | rtprince | 2005-06-11 14:04:12 -0600 (Sat, 11 Jun 2005) | 2 lines
+Changed paths:
+ A /trunk/asymptote/tests/gc/pen.asy
+
+Test collecting pens.
+
+------------------------------------------------------------------------
+r732 | jcbowman | 2005-06-04 13:51:44 -0600 (Sat, 04 Jun 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+
+Document type1cm.
+
+------------------------------------------------------------------------
+r731 | jcbowman | 2005-05-31 23:33:39 -0600 (Tue, 31 May 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/graph.asy
+ M /trunk/asymptote/base/stats.asy
+ M /trunk/asymptote/doc/diatom.asy
+
+Fixed autoscaling of scaled axes, e.g. Linear(x) with x != 1.
+
+------------------------------------------------------------------------
+r728 | jcbowman | 2005-05-29 10:06:31 -0600 (Sun, 29 May 2005) | 2 lines
+Changed paths:
+ A /trunk/asymptote/examples/PythagoreanTree.asy
+
+Added asymmetric Pythagorean tree example.
+
+------------------------------------------------------------------------
+r727 | jcbowman | 2005-05-29 10:05:48 -0600 (Sun, 29 May 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/math.asy
+
+Added aSin, aCos, aTan functions.
+
+------------------------------------------------------------------------
+r726 | jcbowman | 2005-05-27 16:33:21 -0600 (Fri, 27 May 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/configure.ac
+ M /trunk/asymptote/memory.h
+
+Changes for Debian port.
+
+------------------------------------------------------------------------
+r725 | jcbowman | 2005-05-27 15:41:56 -0600 (Fri, 27 May 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/access.h
+ M /trunk/asymptote/entry.h
+ M /trunk/asymptote/frame.h
+ M /trunk/asymptote/import.h
+ M /trunk/asymptote/table.h
+ M /trunk/asymptote/types.h
+
+Fixed memory leaks.
+
+------------------------------------------------------------------------
+r724 | jcbowman | 2005-05-27 02:16:14 -0600 (Fri, 27 May 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/main.cc
+
+Fixed memory leak.
+
+------------------------------------------------------------------------
+r723 | jcbowman | 2005-05-27 00:44:19 -0600 (Fri, 27 May 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/access.h
+ M /trunk/asymptote/entry.h
+ M /trunk/asymptote/frame.h
+ M /trunk/asymptote/import.h
+ M /trunk/asymptote/table.h
+ M /trunk/asymptote/types.h
+
+Added Tom's remaining garbage collection changes.
+
+------------------------------------------------------------------------
+r722 | jcbowman | 2005-05-27 00:09:58 -0600 (Fri, 27 May 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/fileio.h
+ M /trunk/asymptote/main.cc
+
+Garbage collect files on explicit closure and at exit.
+
+------------------------------------------------------------------------
+r721 | jcbowman | 2005-05-26 09:55:30 -0600 (Thu, 26 May 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/item.h
+ M /trunk/asymptote/runtime.cc
+
+Fixed substr bug.
+
+------------------------------------------------------------------------
+r717 | hammera | 2005-05-20 10:48:54 -0600 (Fri, 20 May 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/plain.asy
+
+Changed wording in comments. Indenting.
+
+------------------------------------------------------------------------
+r714 | rtprince | 2005-05-19 23:45:26 -0600 (Thu, 19 May 2005) | 4 lines
+Changed paths:
+ M /trunk/asymptote/builtin.cc
+ M /trunk/asymptote/cast.cc
+ M /trunk/asymptote/castop.h
+ M /trunk/asymptote/coder.cc
+ M /trunk/asymptote/coder.h
+ M /trunk/asymptote/exp.cc
+ M /trunk/asymptote/fileio.h
+ M /trunk/asymptote/item.h
+ M /trunk/asymptote/memory.h
+ M /trunk/asymptote/runtime.cc
+ M /trunk/asymptote/runtime.in
+ M /trunk/asymptote/tests/gc/string.asy
+
+Use mem::string during runtime.
+Make encode(inst) private.
+item.h calls new(UseGC).
+
+------------------------------------------------------------------------
+r713 | jcbowman | 2005-05-19 10:16:48 -0600 (Thu, 19 May 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/configure.ac
+
+Incremented version to 0.79cvs.
+
+------------------------------------------------------------------------
+r712 | jcbowman | 2005-05-19 09:15:54 -0600 (Thu, 19 May 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/memory.h
+
+Disable GC_STRING for now.
+
+------------------------------------------------------------------------
+r711 | jcbowman | 2005-05-18 23:27:15 -0600 (Wed, 18 May 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/camp.l
+ M /trunk/asymptote/util.h
+
+Port to cygwin.
+
+------------------------------------------------------------------------
+r710 | jcbowman | 2005-05-18 14:34:42 -0600 (Wed, 18 May 2005) | 3 lines
+Changed paths:
+ M /trunk/asymptote/fileio.h
+
+Move file back under control of memory::managed to ensure deconstructor is
+called.
+
+------------------------------------------------------------------------
+r709 | rtprince | 2005-05-18 12:41:26 -0600 (Wed, 18 May 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/coder.cc
+ M /trunk/asymptote/coder.h
+ M /trunk/asymptote/inst.cc
+ M /trunk/asymptote/inst.h
+ M /trunk/asymptote/item.h
+ M /trunk/asymptote/stack.cc
+
+Use item for everthing in inst.
+
+------------------------------------------------------------------------
+r708 | rtprince | 2005-05-18 12:37:44 -0600 (Wed, 18 May 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/memory.h
+
+Define mem::string.
+
+------------------------------------------------------------------------
+r707 | rtprince | 2005-05-18 12:36:17 -0600 (Wed, 18 May 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/dec.cc
+ M /trunk/asymptote/genv.cc
+ M /trunk/asymptote/newexp.cc
+
+Use coder::encode everywhere.
+
+------------------------------------------------------------------------
+r705 | rtprince | 2005-05-18 10:50:31 -0600 (Wed, 18 May 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/memory.h
+
+Cleanup memory.h.
+
+------------------------------------------------------------------------
+r703 | jcbowman | 2005-05-18 09:17:32 -0600 (Wed, 18 May 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/pipestream.h
+ M /trunk/asymptote/util.cc
+
+Changed index to strchr for cygwin port.
+
+------------------------------------------------------------------------
+r702 | jcbowman | 2005-05-18 09:17:09 -0600 (Wed, 18 May 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/configure.ac
+
+Fixed LIB.
+
+------------------------------------------------------------------------
+r699 | jcbowman | 2005-05-14 22:29:43 -0600 (Sat, 14 May 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/configure.ac
+
+Check headers earlier.
+
+------------------------------------------------------------------------
+r698 | jcbowman | 2005-05-14 22:26:46 -0600 (Sat, 14 May 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/configure.ac
+
+Make --enable-gc=system also check for gc.h.
+
+------------------------------------------------------------------------
+r697 | jcbowman | 2005-05-12 15:56:27 -0600 (Thu, 12 May 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/inst.h
+
+Workaround "GC Warning: Repeated allocation of very large block" messages.
+
+------------------------------------------------------------------------
+r696 | jcbowman | 2005-05-12 15:54:42 -0600 (Thu, 12 May 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/arrayop.h
+ M /trunk/asymptote/mathop.h
+
+Fix NaN handling.
+
+------------------------------------------------------------------------
+r695 | jcbowman | 2005-05-12 08:56:42 -0600 (Thu, 12 May 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/graph.asy
+
+Better checkaxis test.
+
+------------------------------------------------------------------------
+r694 | jcbowman | 2005-05-11 22:07:40 -0600 (Wed, 11 May 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/configure.ac
+ M /trunk/asymptote/doc/asymptote.texi
+
+Added --enable-gc=system configuration option to use system libgc and libgccp.
+
+------------------------------------------------------------------------
+r693 | jcbowman | 2005-05-11 03:52:11 -0600 (Wed, 11 May 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/memory.h
+
+Define traceable_allocator when garbage collection is disabled.
+
+------------------------------------------------------------------------
+r692 | jcbowman | 2005-05-10 21:52:35 -0600 (Tue, 10 May 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/arrayop.h
+ M /trunk/asymptote/base/math.asy
+ M /trunk/asymptote/builtin.cc
+ M /trunk/asymptote/doc/asymptote.texi
+
+Added binary search routine.
+
+------------------------------------------------------------------------
+r691 | jcbowman | 2005-05-10 16:34:50 -0600 (Tue, 10 May 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/configure.ac
+
+Incremented version to 0.78cvs.
+
+------------------------------------------------------------------------
+r690 | jcbowman | 2005-05-10 14:56:30 -0600 (Tue, 10 May 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/dec.cc
+ M /trunk/asymptote/dec.h
+ M /trunk/asymptote/exp.h
+ M /trunk/asymptote/inst.h
+ M /trunk/asymptote/item.h
+ M /trunk/asymptote/stm.h
+ M /trunk/asymptote/types.h
+
+Recommitted changes: 2005-05-10 rtprince
+
+------------------------------------------------------------------------
+r689 | jcbowman | 2005-05-10 13:56:23 -0600 (Tue, 10 May 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/dec.cc
+ M /trunk/asymptote/dec.h
+ M /trunk/asymptote/exp.h
+ M /trunk/asymptote/inst.h
+ M /trunk/asymptote/item.h
+ M /trunk/asymptote/stm.h
+ M /trunk/asymptote/types.h
+
+Revert broken changes: 2005-05-10 rtprince.
+
+------------------------------------------------------------------------
+r688 | rtprince | 2005-05-10 12:36:42 -0600 (Tue, 10 May 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/dec.cc
+ M /trunk/asymptote/dec.h
+ M /trunk/asymptote/exp.h
+ M /trunk/asymptote/inst.h
+ M /trunk/asymptote/stm.h
+ M /trunk/asymptote/types.h
+
+Make CVS -lgccpp clean.
+
+------------------------------------------------------------------------
+r687 | rtprince | 2005-05-10 12:31:32 -0600 (Tue, 10 May 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/item.h
+
+Make item use new(UseGC).
+
+------------------------------------------------------------------------
+r686 | rtprince | 2005-05-10 11:43:15 -0600 (Tue, 10 May 2005) | 2 lines
+Changed paths:
+ A /trunk/asymptote/tests
+ A /trunk/asymptote/tests/gc
+ A /trunk/asymptote/tests/gc/array.asy
+ A /trunk/asymptote/tests/gc/file.asy
+ A /trunk/asymptote/tests/gc/funcall.asy
+ A /trunk/asymptote/tests/gc/guide.asy
+ A /trunk/asymptote/tests/gc/path.asy
+ A /trunk/asymptote/tests/gc/string.asy
+
+Add some tests.
+
+------------------------------------------------------------------------
+r685 | jcbowman | 2005-05-10 11:16:21 -0600 (Tue, 10 May 2005) | 2 lines
+Changed paths:
+ D /trunk/asymptote/examples/Geometry.asy
+ A /trunk/asymptote/examples/orthocenter.asy
+
+Renamed example.
+
+------------------------------------------------------------------------
+r684 | jcbowman | 2005-05-10 04:37:53 -0600 (Tue, 10 May 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/Makefile.in
+ M /trunk/asymptote/configure.ac
+ M /trunk/asymptote/doc/asymptote.texi
+ D /trunk/asymptote/gc6.3.tar.gz
+
+Distribute Boehm GC as a separate package.
+
+------------------------------------------------------------------------
+r683 | jcbowman | 2005-05-09 23:08:51 -0600 (Mon, 09 May 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/memory.h
+
+Fixed error in map & multimap.
+
+------------------------------------------------------------------------
+r682 | jcbowman | 2005-05-09 22:49:00 -0600 (Mon, 09 May 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/absyn.h
+ M /trunk/asymptote/access.h
+ M /trunk/asymptote/entry.h
+ M /trunk/asymptote/errormsg.h
+ M /trunk/asymptote/frame.h
+ M /trunk/asymptote/import.h
+ M /trunk/asymptote/inst.h
+ M /trunk/asymptote/main.cc
+ M /trunk/asymptote/memory.h
+ A /trunk/asymptote/pool.h
+ M /trunk/asymptote/table.h
+ M /trunk/asymptote/types.h
+
+Fixed parser leak again.
+
+------------------------------------------------------------------------
+r681 | jcbowman | 2005-05-09 21:57:44 -0600 (Mon, 09 May 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/stack.cc
+
+Fixed broken draw call.
+
+------------------------------------------------------------------------
+r680 | jcbowman | 2005-05-09 16:41:16 -0600 (Mon, 09 May 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/runtime.cc
+
+More gc string updates.
+
+------------------------------------------------------------------------
+r679 | jcbowman | 2005-05-09 16:22:25 -0600 (Mon, 09 May 2005) | 2 lines
+Changed paths:
+ D /trunk/asymptote/gc_atomic.h
+
+Unused file.
+
+------------------------------------------------------------------------
+r678 | jcbowman | 2005-05-09 14:01:57 -0600 (Mon, 09 May 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/memory.h
+
+Handle out of memory errors gracefully.
+
+------------------------------------------------------------------------
+r677 | rtprince | 2005-05-09 13:22:55 -0600 (Mon, 09 May 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/dec.cc
+
+list<decid *> is from mem::.
+
+------------------------------------------------------------------------
+r676 | rtprince | 2005-05-09 13:17:32 -0600 (Mon, 09 May 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/stack.h
+
+Make theStack be mem::deque.
+
+------------------------------------------------------------------------
+r675 | jcbowman | 2005-05-09 10:25:33 -0600 (Mon, 09 May 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/configure.ac
+ M /trunk/asymptote/main.cc
+ D /trunk/asymptote/pool.h
+
+Fixed segmentation fault.
+
+------------------------------------------------------------------------
+r674 | rtprince | 2005-05-09 05:24:22 -0600 (Mon, 09 May 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/picture.cc
+
+Dont gc non-heap string.
+
+------------------------------------------------------------------------
+r673 | rtprince | 2005-05-09 04:58:00 -0600 (Mon, 09 May 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/Makefile.in
+
+Fix makefile. :-(
+
+------------------------------------------------------------------------
+r672 | rtprince | 2005-05-09 04:56:30 -0600 (Mon, 09 May 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/drawelement.h
+ M /trunk/asymptote/exp.cc
+ M /trunk/asymptote/item.h
+ M /trunk/asymptote/picture.cc
+ M /trunk/asymptote/psfile.h
+ M /trunk/asymptote/runtime.cc
+ M /trunk/asymptote/stack.cc
+
+More gc fixes.
+
+------------------------------------------------------------------------
+r671 | rtprince | 2005-05-09 04:34:48 -0600 (Mon, 09 May 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/Makefile.in
+ M /trunk/asymptote/absyn.h
+ M /trunk/asymptote/access.h
+ M /trunk/asymptote/configure.ac
+ M /trunk/asymptote/dec.h
+ M /trunk/asymptote/drawlabel.cc
+ M /trunk/asymptote/entry.h
+ M /trunk/asymptote/errormsg.h
+ M /trunk/asymptote/exp.h
+ M /trunk/asymptote/frame.h
+ M /trunk/asymptote/import.h
+ M /trunk/asymptote/inst.h
+ M /trunk/asymptote/item.h
+ M /trunk/asymptote/main.cc
+ M /trunk/asymptote/memory.h
+ M /trunk/asymptote/parser.cc
+ M /trunk/asymptote/picture.cc
+ M /trunk/asymptote/stack.cc
+ M /trunk/asymptote/stack.h
+ M /trunk/asymptote/stm.h
+ M /trunk/asymptote/table.h
+ M /trunk/asymptote/texfile.h
+ M /trunk/asymptote/types.h
+
+GC fixes. We dont need mempool.
+
+------------------------------------------------------------------------
+r670 | jcbowman | 2005-05-09 03:10:23 -0600 (Mon, 09 May 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/drawpath.cc
+ M /trunk/asymptote/picture.cc
+ M /trunk/asymptote/pool.h
+
+Fixed cxx errors.
+
+------------------------------------------------------------------------
+r669 | jcbowman | 2005-05-09 02:58:55 -0600 (Mon, 09 May 2005) | 5 lines
+Changed paths:
+ M /trunk/asymptote/absyn.h
+ M /trunk/asymptote/access.h
+ M /trunk/asymptote/camperror.h
+ D /trunk/asymptote/collect.h
+ M /trunk/asymptote/configure.ac
+ M /trunk/asymptote/drawelement.h
+ M /trunk/asymptote/drawlabel.cc
+ M /trunk/asymptote/drawpath.cc
+ M /trunk/asymptote/entry.h
+ M /trunk/asymptote/errormsg.h
+ M /trunk/asymptote/exp.h
+ M /trunk/asymptote/frame.h
+ M /trunk/asymptote/guide.h
+ M /trunk/asymptote/import.h
+ M /trunk/asymptote/inst.h
+ M /trunk/asymptote/item.h
+ M /trunk/asymptote/knot.cc
+ M /trunk/asymptote/knot.h
+ M /trunk/asymptote/lexical.h
+ M /trunk/asymptote/main.cc
+ M /trunk/asymptote/memory.h
+ M /trunk/asymptote/pair.h
+ M /trunk/asymptote/picture.cc
+ M /trunk/asymptote/picture.h
+ D /trunk/asymptote/pool.cc
+ M /trunk/asymptote/pool.h
+ M /trunk/asymptote/psfile.h
+ M /trunk/asymptote/runtime.cc
+ M /trunk/asymptote/texfile.h
+ M /trunk/asymptote/types.h
+
+
+Fixed memory leak in parser and translator.
+
+Cleaned up interface to the Boehm garbage collector.
+
+------------------------------------------------------------------------
+r668 | jcbowman | 2005-05-08 23:06:28 -0600 (Sun, 08 May 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/Makefile.in
+ M /trunk/asymptote/absyn.h
+ M /trunk/asymptote/access.h
+ M /trunk/asymptote/configure.ac
+ M /trunk/asymptote/drawelement.h
+ M /trunk/asymptote/entry.h
+ M /trunk/asymptote/errormsg.h
+ M /trunk/asymptote/exp.h
+ M /trunk/asymptote/fileio.h
+ M /trunk/asymptote/frame.h
+ M /trunk/asymptote/guide.h
+ M /trunk/asymptote/import.h
+ M /trunk/asymptote/inst.h
+ M /trunk/asymptote/item.h
+ M /trunk/asymptote/knot.cc
+ M /trunk/asymptote/knot.h
+ M /trunk/asymptote/main.cc
+ M /trunk/asymptote/pair.h
+ M /trunk/asymptote/parser.cc
+ M /trunk/asymptote/path.h
+ M /trunk/asymptote/pen.h
+ M /trunk/asymptote/picture.cc
+ M /trunk/asymptote/picture.h
+ M /trunk/asymptote/runtime.cc
+ M /trunk/asymptote/stack.cc
+ M /trunk/asymptote/texfile.h
+ M /trunk/asymptote/transform.h
+ M /trunk/asymptote/types.h
+
+Revert 2005-05-09 and 2005-05-08 rtprince changes.
+
+------------------------------------------------------------------------
+r667 | rtprince | 2005-05-08 22:16:41 -0600 (Sun, 08 May 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/picture.h
+
+Fix picture.
+
+------------------------------------------------------------------------
+r666 | rtprince | 2005-05-08 21:24:28 -0600 (Sun, 08 May 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/inst.h
+ M /trunk/asymptote/item.h
+
+Fix item gc handling.
+
+------------------------------------------------------------------------
+r665 | rtprince | 2005-05-08 21:12:42 -0600 (Sun, 08 May 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/path.h
+
+Collect path.
+
+------------------------------------------------------------------------
+r664 | rtprince | 2005-05-08 20:35:08 -0600 (Sun, 08 May 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/transform.h
+
+Collect transform.
+
+------------------------------------------------------------------------
+r663 | rtprince | 2005-05-08 19:56:00 -0600 (Sun, 08 May 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/Makefile.in
+ A /trunk/asymptote/gc_atomic.h
+ A /trunk/asymptote/memory.h
+ M /trunk/asymptote/picture.cc
+ M /trunk/asymptote/picture.h
+ M /trunk/asymptote/runtime.cc
+
+Create gc_atomic, and make picture use it.
+
+------------------------------------------------------------------------
+r662 | rtprince | 2005-05-08 19:37:29 -0600 (Sun, 08 May 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/pen.h
+
+Make pen garbage collected.
+
+------------------------------------------------------------------------
+r661 | rtprince | 2005-05-08 19:34:56 -0600 (Sun, 08 May 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/drawelement.h
+ M /trunk/asymptote/picture.cc
+ M /trunk/asymptote/picture.h
+ M /trunk/asymptote/runtime.cc
+
+Make picture and drawElement garabage collected.
+
+------------------------------------------------------------------------
+r660 | rtprince | 2005-05-08 17:11:34 -0600 (Sun, 08 May 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/inst.h
+ M /trunk/asymptote/item.h
+ M /trunk/asymptote/main.cc
+ M /trunk/asymptote/parser.cc
+ A /trunk/asymptote/pool.cc
+ M /trunk/asymptote/stack.cc
+
+Add gc for vm only. (untested)
+
+------------------------------------------------------------------------
+r659 | rtprince | 2005-05-08 17:01:19 -0600 (Sun, 08 May 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/configure.ac
+
+We don't want libgccpp.
+
+------------------------------------------------------------------------
+r658 | rtprince | 2005-05-08 16:57:11 -0600 (Sun, 08 May 2005) | 2 lines
+Changed paths:
+ A /trunk/asymptote/pool.h
+
+Re-add pool.h.
+
+------------------------------------------------------------------------
+r657 | rtprince | 2005-05-08 16:55:24 -0600 (Sun, 08 May 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/absyn.h
+ M /trunk/asymptote/access.h
+ M /trunk/asymptote/drawelement.h
+ M /trunk/asymptote/entry.h
+ M /trunk/asymptote/errormsg.h
+ M /trunk/asymptote/exp.h
+ M /trunk/asymptote/fileio.h
+ M /trunk/asymptote/frame.h
+ M /trunk/asymptote/guide.h
+ M /trunk/asymptote/import.h
+ M /trunk/asymptote/inst.h
+ M /trunk/asymptote/item.h
+ M /trunk/asymptote/knot.cc
+ M /trunk/asymptote/knot.h
+ M /trunk/asymptote/main.cc
+ M /trunk/asymptote/pair.h
+ M /trunk/asymptote/path.h
+ M /trunk/asymptote/pen.h
+ M /trunk/asymptote/picture.cc
+ M /trunk/asymptote/picture.h
+ M /trunk/asymptote/runtime.cc
+ M /trunk/asymptote/stack.cc
+ M /trunk/asymptote/texfile.h
+ M /trunk/asymptote/transform.h
+ M /trunk/asymptote/types.h
+
+Revert GC changes. (not tested)
+
+------------------------------------------------------------------------
+r656 | jcbowman | 2005-05-08 08:57:01 -0600 (Sun, 08 May 2005) | 2 lines
+Changed paths:
+ A /trunk/asymptote/examples/piicon.eps
+
+Figure for Geometry.asy.
+
+------------------------------------------------------------------------
+r655 | jcbowman | 2005-05-08 00:29:32 -0600 (Sun, 08 May 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/Makefile.in
+
+Minor fixes.
+
+------------------------------------------------------------------------
+r654 | jcbowman | 2005-05-08 00:17:30 -0600 (Sun, 08 May 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/Makefile.in
+
+Workaround Makefile problem in gc6.3.
+
+------------------------------------------------------------------------
+r653 | jcbowman | 2005-05-08 00:16:45 -0600 (Sun, 08 May 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/stack.cc
+
+Move trace/interrupt check to beginning of virtual machine loop.
+
+------------------------------------------------------------------------
+r652 | jcbowman | 2005-05-08 00:05:59 -0600 (Sun, 08 May 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/Makefile.in
+ D /trunk/asymptote/gc6.3.tar
+ A /trunk/asymptote/gc6.3.tar.gz
+
+Revert to distributing Boehm GC as tar.gz file.
+
+------------------------------------------------------------------------
+r651 | jcbowman | 2005-05-08 00:01:56 -0600 (Sun, 08 May 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/gc6.3.tar
+
+Fixed corrupted tar file.
+
+------------------------------------------------------------------------
+r650 | jcbowman | 2005-05-07 23:52:27 -0600 (Sat, 07 May 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/Makefile.in
+ A /trunk/asymptote/gc6.3.tar
+ D /trunk/asymptote/gc6.3.tar.gz
+
+Distribute Boehm GC as a tar file rather than tar.gz file.
+
+------------------------------------------------------------------------
+r649 | jcbowman | 2005-05-07 23:40:14 -0600 (Sat, 07 May 2005) | 4 lines
+Changed paths:
+ A /trunk/asymptote/base/geometry.asy
+ M /trunk/asymptote/base/math.asy
+ M /trunk/asymptote/doc/asymptote.texi
+ A /trunk/asymptote/examples/Geometry.asy
+ M /trunk/asymptote/examples/Pythagoras.asy
+ M /trunk/asymptote/examples/cosaddition.asy
+ D /trunk/asymptote/examples/geometry.asy
+ D /trunk/asymptote/examples/sflogo.eps
+ M /trunk/asymptote/examples/sinxlex.asy
+ M /trunk/asymptote/examples/triangle.asy
+
+
+Added beginnings of a geometry module, including a triangle structure and
+functions to draw interior arcs of triangles and perpendicular symbols.
+
+------------------------------------------------------------------------
+r648 | jcbowman | 2005-05-07 21:31:23 -0600 (Sat, 07 May 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/Makefile.in
+ M /trunk/asymptote/configure.ac
+ D /trunk/asymptote/pool.h
+
+Distribute generated source files.
+
+------------------------------------------------------------------------
+r647 | jcbowman | 2005-05-07 21:30:48 -0600 (Sat, 07 May 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/runtime.cc
+
+Fixed type of argument of dividebyzero.
+
+------------------------------------------------------------------------
+r646 | jcbowman | 2005-05-07 21:05:28 -0600 (Sat, 07 May 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/collect.h
+ M /trunk/asymptote/mathop.h
+ M /trunk/asymptote/runtime.cc
+
+cxx updates.
+
+------------------------------------------------------------------------
+r645 | jcbowman | 2005-05-07 20:35:51 -0600 (Sat, 07 May 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/stack.cc
+ M /trunk/asymptote/stack.h
+
+DEBUG_STACK updates.
+
+------------------------------------------------------------------------
+r644 | jcbowman | 2005-05-07 20:07:39 -0600 (Sat, 07 May 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/drawelement.h
+ M /trunk/asymptote/drawpath.cc
+ M /trunk/asymptote/main.cc
+ M /trunk/asymptote/picture.cc
+ M /trunk/asymptote/picture.h
+ D /trunk/asymptote/pool.cc
+ M /trunk/asymptote/settings.cc
+ M /trunk/asymptote/settings.h
+ M /trunk/asymptote/texfile.cc
+ M /trunk/asymptote/texfile.h
+
+Minor garbage collection updates.
+
+------------------------------------------------------------------------
+r643 | jcbowman | 2005-05-07 11:56:54 -0600 (Sat, 07 May 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/configure.ac
+
+Autoconf backwards compatibility workaround.
+
+------------------------------------------------------------------------
+r642 | jcbowman | 2005-05-07 11:50:19 -0600 (Sat, 07 May 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/main.cc
+
+Renamed COLLECT to USEGC.
+
+------------------------------------------------------------------------
+r641 | jcbowman | 2005-05-07 11:49:25 -0600 (Sat, 07 May 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/Makefile.in
+ A /trunk/asymptote/collect.h
+ M /trunk/asymptote/configure.ac
+ M /trunk/asymptote/main.cc
+ M /trunk/asymptote/pair.h
+ M /trunk/asymptote/types.h
+
+Added configuration to optionally disable garbage collection.
+
+------------------------------------------------------------------------
+r640 | jcbowman | 2005-05-07 09:48:46 -0600 (Sat, 07 May 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/Makefile.in
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/inst.h
+
+Fixed Makefile dependencies.
+
+------------------------------------------------------------------------
+r639 | jcbowman | 2005-05-07 01:38:08 -0600 (Sat, 07 May 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/Makefile.in
+ M /trunk/asymptote/TODO
+ M /trunk/asymptote/absyn.cc
+ M /trunk/asymptote/absyn.h
+ M /trunk/asymptote/access.h
+ M /trunk/asymptote/builtin.cc
+ M /trunk/asymptote/camp.l
+ M /trunk/asymptote/camp.y
+ M /trunk/asymptote/camperror.cc
+ M /trunk/asymptote/camperror.h
+ M /trunk/asymptote/cast.cc
+ M /trunk/asymptote/castop.h
+ M /trunk/asymptote/configure.ac
+ M /trunk/asymptote/drawclipbegin.h
+ M /trunk/asymptote/drawclipend.h
+ M /trunk/asymptote/drawelement.h
+ M /trunk/asymptote/drawimage.h
+ M /trunk/asymptote/drawlabel.cc
+ M /trunk/asymptote/drawlabel.h
+ M /trunk/asymptote/drawpath.cc
+ M /trunk/asymptote/drawpath.h
+ M /trunk/asymptote/drawverbatim.h
+ M /trunk/asymptote/entry.h
+ M /trunk/asymptote/errormsg.cc
+ M /trunk/asymptote/errormsg.h
+ M /trunk/asymptote/exp.cc
+ M /trunk/asymptote/exp.h
+ M /trunk/asymptote/fileio.cc
+ M /trunk/asymptote/fileio.h
+ M /trunk/asymptote/frame.h
+ A /trunk/asymptote/gc6.3.tar.gz
+ M /trunk/asymptote/genv.cc
+ M /trunk/asymptote/genv.h
+ M /trunk/asymptote/guide.h
+ M /trunk/asymptote/import.h
+ M /trunk/asymptote/inst.h
+ M /trunk/asymptote/interact.cc
+ M /trunk/asymptote/item.h
+ M /trunk/asymptote/knot.cc
+ M /trunk/asymptote/knot.h
+ M /trunk/asymptote/lexical.h
+ M /trunk/asymptote/locate.cc
+ M /trunk/asymptote/locate.h
+ M /trunk/asymptote/main.cc
+ M /trunk/asymptote/pair.h
+ M /trunk/asymptote/parser.cc
+ M /trunk/asymptote/parser.h
+ M /trunk/asymptote/path.cc
+ M /trunk/asymptote/path.h
+ M /trunk/asymptote/pen.h
+ M /trunk/asymptote/picture.cc
+ M /trunk/asymptote/picture.h
+ M /trunk/asymptote/pipestream.h
+ M /trunk/asymptote/psfile.cc
+ M /trunk/asymptote/psfile.h
+ M /trunk/asymptote/runtime.cc
+ M /trunk/asymptote/runtime.in
+ M /trunk/asymptote/settings.cc
+ M /trunk/asymptote/settings.h
+ M /trunk/asymptote/stack.cc
+ M /trunk/asymptote/stack.h
+ M /trunk/asymptote/symbol.cc
+ M /trunk/asymptote/symbol.h
+ M /trunk/asymptote/texfile.cc
+ M /trunk/asymptote/texfile.h
+ M /trunk/asymptote/transform.h
+ M /trunk/asymptote/types.cc
+ M /trunk/asymptote/types.h
+ M /trunk/asymptote/util.cc
+ M /trunk/asymptote/util.h
+
+Implemented Boehm garbage collection.
+
+------------------------------------------------------------------------
+r638 | hammera | 2005-05-05 22:32:22 -0600 (Thu, 05 May 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/knot.cc
+
+Fixed solveSection bug.
+
+------------------------------------------------------------------------
+r637 | jcbowman | 2005-05-05 13:34:40 -0600 (Thu, 05 May 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/palette.asy
+
+Added missing comma.
+
+------------------------------------------------------------------------
+r636 | jcbowman | 2005-05-05 13:32:53 -0600 (Thu, 05 May 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/graph.asy
+ M /trunk/asymptote/base/palette.asy
+ M /trunk/asymptote/base/plain.asy
+ M /trunk/asymptote/doc/westnile.asy
+
+Addressed pen plabel vs p issues.
+
+------------------------------------------------------------------------
+r635 | jcbowman | 2005-05-05 01:36:58 -0600 (Thu, 05 May 2005) | 6 lines
+Changed paths:
+ M /trunk/asymptote/base/plain.asy
+ M /trunk/asymptote/builtin.cc
+ M /trunk/asymptote/dec.cc
+ M /trunk/asymptote/dec.h
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/genv.cc
+ M /trunk/asymptote/runtime.cc
+ M /trunk/asymptote/runtime.h
+
+Renamed eval(f(T), T[] A) to map(f(T), T[] A).
+
+Documented eval(string) and make eval autoload plain.
+
+Implemented T[] concat(T[] A, T[] B) to concatenate two arrays into a new one.
+
+------------------------------------------------------------------------
+r634 | jcbowman | 2005-05-05 00:46:04 -0600 (Thu, 05 May 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/math.asy
+
+Added pair exp(pair) and pair log(pair).
+
+------------------------------------------------------------------------
+r633 | jcbowman | 2005-05-04 23:35:48 -0600 (Wed, 04 May 2005) | 4 lines
+Changed paths:
+ M /trunk/asymptote/base/graph.asy
+ M /trunk/asymptote/base/math.asy
+ M /trunk/asymptote/base/palette.asy
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/runtime.cc
+
+Make int quotient(int,int) portable.
+
+Updated base files to use quotient for integer division.
+
+------------------------------------------------------------------------
+r632 | jcbowman | 2005-05-04 23:19:03 -0600 (Wed, 04 May 2005) | 3 lines
+Changed paths:
+ M /trunk/asymptote/builtin.cc
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/mathop.h
+ M /trunk/asymptote/runtime.cc
+ M /trunk/asymptote/runtime.h
+
+Make int/int return a real, as is normally desired; the new function
+int quotient(int,int) returns an integer quotient.
+
+------------------------------------------------------------------------
+r631 | jcbowman | 2005-05-04 21:55:59 -0600 (Wed, 04 May 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/TODO
+
+Updated TODO items.
+
+------------------------------------------------------------------------
+r630 | jcbowman | 2005-05-04 21:55:18 -0600 (Wed, 04 May 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/picture.cc
+
+List iterator simplification.
+
+------------------------------------------------------------------------
+r629 | jcbowman | 2005-05-04 21:44:31 -0600 (Wed, 04 May 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/plain.asy
+
+Added reltime(path, real).
+
+------------------------------------------------------------------------
+r628 | jcbowman | 2005-05-04 21:40:58 -0600 (Wed, 04 May 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/asy.1
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/entry.cc
+
+Make -l option list available global variables as well as functions.
+
+------------------------------------------------------------------------
+r627 | jcbowman | 2005-05-03 22:24:17 -0600 (Tue, 03 May 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+
+Minor updates.
+
+------------------------------------------------------------------------
+r626 | jcbowman | 2005-05-03 22:23:34 -0600 (Tue, 03 May 2005) | 3 lines
+Changed paths:
+ M /trunk/asymptote/parser.cc
+
+For portability, explicitly check that input file isn't a directory on systems
+with stat.
+
+------------------------------------------------------------------------
+r625 | jcbowman | 2005-05-02 21:14:15 -0600 (Mon, 02 May 2005) | 2 lines
+Changed paths:
+ A /trunk/asymptote/examples/triangle.asy
+
+Added example of a transformable triangle structure.
+
+------------------------------------------------------------------------
+r624 | jcbowman | 2005-05-02 16:20:02 -0600 (Mon, 02 May 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/configure.ac
+
+Incremented version to 0.77cvs.
+
+------------------------------------------------------------------------
+r623 | jcbowman | 2005-05-02 15:27:57 -0600 (Mon, 02 May 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/examples/spring.asy
+
+Added PenMargin.
+
+------------------------------------------------------------------------
+r622 | jcbowman | 2005-05-02 15:20:05 -0600 (Mon, 02 May 2005) | 4 lines
+Changed paths:
+ M /trunk/asymptote/doc/asy.1
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/entry.cc
+ M /trunk/asymptote/entry.h
+ M /trunk/asymptote/genv.cc
+ M /trunk/asymptote/genv.h
+ M /trunk/asymptote/main.cc
+ M /trunk/asymptote/record.h
+ M /trunk/asymptote/settings.cc
+ M /trunk/asymptote/settings.h
+ M /trunk/asymptote/types.cc
+
+Added -l option to list available global functions.
+
+Documentation default structure constructors.
+
+------------------------------------------------------------------------
+r621 | jcbowman | 2005-05-02 00:42:53 -0600 (Mon, 02 May 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/plain.asy
+
+Added missing plabel.
+
+------------------------------------------------------------------------
+r620 | jcbowman | 2005-05-02 00:11:49 -0600 (Mon, 02 May 2005) | 5 lines
+Changed paths:
+ M /trunk/asymptote/interact.cc
+ M /trunk/asymptote/interact.h
+ M /trunk/asymptote/main.cc
+ M /trunk/asymptote/pipestream.h
+ M /trunk/asymptote/runtime.cc
+ M /trunk/asymptote/texfile.h
+
+
+Improved error handling in pipestream; wrap fork to avoid zombies.
+
+TeX errors should force TeX pipe to be closed.
+
+------------------------------------------------------------------------
+r619 | jcbowman | 2005-05-02 00:09:25 -0600 (Mon, 02 May 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/examples/sin1x.asy
+ M /trunk/asymptote/examples/sqrtx01.asy
+ M /trunk/asymptote/examples/wedge.asy
+ M /trunk/asymptote/examples/xsin1x.asy
+
+Updated examples.
+
+------------------------------------------------------------------------
+r618 | jcbowman | 2005-05-02 00:09:10 -0600 (Mon, 02 May 2005) | 3 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/doc/latexusage.tex
+
+
+Updated documentation.
+
+------------------------------------------------------------------------
+r617 | jcbowman | 2005-05-02 00:08:38 -0600 (Mon, 02 May 2005) | 3 lines
+Changed paths:
+ M /trunk/asymptote/castop.h
+
+
+Don't push a final null entry when reading an array in line mode.
+
+------------------------------------------------------------------------
+r616 | jcbowman | 2005-05-02 00:07:12 -0600 (Mon, 02 May 2005) | 14 lines
+Changed paths:
+ M /trunk/asymptote/base/graph.asy
+ M /trunk/asymptote/base/palette.asy
+ M /trunk/asymptote/base/plain.asy
+
+
+Fixed grouping in add(pair,frame,frame,group).
+
+Added put argument to pic.add, attach, etc.
+
+Added plabel argument to draw to allow labels and legends to use a different
+pen than the curve itself.
+
+Rearranged plabel and p arguments in axis routines for consistency.
+
+Added getstring and getreal functions.
+
+Added Mark, MarkFill frame arrays and Mark(int) function.
+
+------------------------------------------------------------------------
+r615 | jcbowman | 2005-05-02 00:04:54 -0600 (Mon, 02 May 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/math.asy
+
+Added node, value, and slope functions for paths.
+
+------------------------------------------------------------------------
+r614 | rtprince | 2005-04-30 22:38:32 -0600 (Sat, 30 Apr 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/camperror.cc
+ M /trunk/asymptote/camperror.h
+ M /trunk/asymptote/drawclipend.h
+ M /trunk/asymptote/errormsg.cc
+ M /trunk/asymptote/errormsg.h
+ M /trunk/asymptote/fileio.h
+ M /trunk/asymptote/pair.h
+ M /trunk/asymptote/path.cc
+ M /trunk/asymptote/path.h
+ M /trunk/asymptote/psfile.cc
+ M /trunk/asymptote/psfile.h
+ M /trunk/asymptote/stack.cc
+ M /trunk/asymptote/transform.h
+ M /trunk/asymptote/util.cc
+
+Make camperror throw instead of queuing.
+
+------------------------------------------------------------------------
+r613 | hammera | 2005-04-30 20:31:09 -0600 (Sat, 30 Apr 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/camp.l
+ M /trunk/asymptote/camp.y
+
+''
+
+------------------------------------------------------------------------
+r612 | hammera | 2005-04-30 16:29:58 -0600 (Sat, 30 Apr 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/exp.cc
+ M /trunk/asymptote/exp.h
+
+Allowed more implicit scaling.
+
+------------------------------------------------------------------------
+r611 | hammera | 2005-04-30 14:49:34 -0600 (Sat, 30 Apr 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/camp.y
+
+Changed precedence for implicit scaling.
+
+------------------------------------------------------------------------
+r610 | jcbowman | 2005-04-25 23:43:36 -0600 (Mon, 25 Apr 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/examples/near_earth.asy
+ M /trunk/asymptote/main.cc
+
+Flush exited child processes (zombies) in batch mode.
+
+------------------------------------------------------------------------
+r609 | jcbowman | 2005-04-25 23:41:46 -0600 (Mon, 25 Apr 2005) | 4 lines
+Changed paths:
+ M /trunk/asymptote/picture.cc
+
+Workaround interactive mode bug introduced by recent changes to main.cc.
+
+On multiple file runs, texpreamble should appear before any other commands.
+
+------------------------------------------------------------------------
+r608 | jcbowman | 2005-04-25 22:21:57 -0600 (Mon, 25 Apr 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/TODO
+ M /trunk/asymptote/base/graph.asy
+ M /trunk/asymptote/examples/near_earth.asy
+
+Added example of 3d featpost3d arc.
+
+------------------------------------------------------------------------
+r607 | rtprince | 2005-04-24 21:04:01 -0600 (Sun, 24 Apr 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/parser.cc
+
+Make parseStdin() turn of lex debuging.
+
+------------------------------------------------------------------------
+r606 | jcbowman | 2005-04-24 10:44:05 -0600 (Sun, 24 Apr 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/plain.asy
+
+Added Dotted(pen) function which returns a dotted pen at double the linewidth.
+
+------------------------------------------------------------------------
+r605 | jcbowman | 2005-04-23 17:16:57 -0600 (Sat, 23 Apr 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/fileio.h
+
+Clear existing errors on reading from standard input.
+
+------------------------------------------------------------------------
+r604 | rtprince | 2005-04-23 15:15:33 -0600 (Sat, 23 Apr 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/main.cc
+
+Fix interrupt handling.
+
+------------------------------------------------------------------------
+r603 | rtprince | 2005-04-22 11:56:07 -0600 (Fri, 22 Apr 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/parser.cc
+
+Cleanup.
+
+------------------------------------------------------------------------
+r602 | jcbowman | 2005-04-22 08:43:55 -0600 (Fri, 22 Apr 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/parser.cc
+
+Fixed compilation error.
+
+------------------------------------------------------------------------
+r601 | rtprince | 2005-04-22 07:49:16 -0600 (Fri, 22 Apr 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/parser.cc
+
+Fix segfault.
+
+------------------------------------------------------------------------
+r600 | jcbowman | 2005-04-22 03:21:09 -0600 (Fri, 22 Apr 2005) | 3 lines
+Changed paths:
+ M /trunk/asymptote/camp.l
+ M /trunk/asymptote/castop.h
+ M /trunk/asymptote/configure.ac
+ M /trunk/asymptote/doc/asymptote.texi
+ A /trunk/asymptote/lexical.h
+ M /trunk/asymptote/settings.cc
+
+Replaced boost::lexical_cast with lexical.h to remove last remaining
+dependency on boost header files.
+
+------------------------------------------------------------------------
+r599 | rtprince | 2005-04-21 22:51:44 -0600 (Thu, 21 Apr 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/main.cc
+ M /trunk/asymptote/runtime.cc
+
+Cleanup.
+
+------------------------------------------------------------------------
+r598 | rtprince | 2005-04-21 22:47:56 -0600 (Thu, 21 Apr 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/main.cc
+
+Refactoring main.cc.
+
+------------------------------------------------------------------------
+r597 | rtprince | 2005-04-21 21:27:46 -0600 (Thu, 21 Apr 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/genv.cc
+ M /trunk/asymptote/main.cc
+
+More refactoring in main.cc
+
+------------------------------------------------------------------------
+r596 | rtprince | 2005-04-21 21:03:35 -0600 (Thu, 21 Apr 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/main.cc
+ M /trunk/asymptote/runtime.cc
+ M /trunk/asymptote/util.cc
+ M /trunk/asymptote/util.h
+
+findextension is used only to strip suffix. So strip it.
+
+------------------------------------------------------------------------
+r595 | rtprince | 2005-04-21 13:38:38 -0600 (Thu, 21 Apr 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/main.cc
+
+FIx interactive.
+
+------------------------------------------------------------------------
+r594 | rtprince | 2005-04-21 00:59:52 -0600 (Thu, 21 Apr 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/main.cc
+
+More main.cc cleanup.
+
+------------------------------------------------------------------------
+r593 | rtprince | 2005-04-21 00:55:02 -0600 (Thu, 21 Apr 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/main.cc
+
+Simplify error handling.
+
+------------------------------------------------------------------------
+r592 | rtprince | 2005-04-21 00:33:24 -0600 (Thu, 21 Apr 2005) | 4 lines
+Changed paths:
+ M /trunk/asymptote/main.cc
+
+Start pulling appart main(), so it easier to
+change and understand. Doesn't do much, but
+gives a a place to start.
+
+------------------------------------------------------------------------
+r591 | rtprince | 2005-04-21 00:07:46 -0600 (Thu, 21 Apr 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/errors
+ M /trunk/asymptote/wce
+
+Update ./wce.
+
+------------------------------------------------------------------------
+r590 | rtprince | 2005-04-20 23:40:57 -0600 (Wed, 20 Apr 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/exp.h
+ M /trunk/asymptote/newexp.h
+ M /trunk/asymptote/stm.cc
+
+Remove warning about side-effects.
+
+------------------------------------------------------------------------
+r589 | jcbowman | 2005-04-20 23:17:54 -0600 (Wed, 20 Apr 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/configure.ac
+
+Incremented version to 0.76cvs.
+
+------------------------------------------------------------------------
+r588 | jcbowman | 2005-04-20 22:41:08 -0600 (Wed, 20 Apr 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/graph.asy
+ M /trunk/asymptote/doc/asymptote.texi
+
+Documented xline and yline.
+
+------------------------------------------------------------------------
+r587 | jcbowman | 2005-04-20 18:59:59 -0600 (Wed, 20 Apr 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/diatom.asy
+
+More updates.
+
+------------------------------------------------------------------------
+r586 | jcbowman | 2005-04-20 18:58:48 -0600 (Wed, 20 Apr 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/diatom.asy
+
+Updated axis call.
+
+------------------------------------------------------------------------
+r585 | jcbowman | 2005-04-20 16:03:54 -0600 (Wed, 20 Apr 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+
+Updated binary installation instructions.
+
+------------------------------------------------------------------------
+r584 | jcbowman | 2005-04-20 14:03:36 -0600 (Wed, 20 Apr 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/palette.asy
+
+Update yaxis call.
+
+------------------------------------------------------------------------
+r583 | jcbowman | 2005-04-20 11:53:41 -0600 (Wed, 20 Apr 2005) | 7 lines
+Changed paths:
+ M /trunk/asymptote/genv.cc
+ M /trunk/asymptote/genv.h
+ M /trunk/asymptote/knot.cc
+ M /trunk/asymptote/main.cc
+ M /trunk/asymptote/parser.cc
+ M /trunk/asymptote/runtime.cc
+
+
+Consolidated autoload code.
+
+Suppressed "could not load" error message in interactive mode.
+
+Fixed gcc 3.2 warnings and error message.
+
+------------------------------------------------------------------------
+r582 | jcbowman | 2005-04-20 11:51:58 -0600 (Wed, 20 Apr 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/math.asy
+
+Added linear interpolation and binary search routines.
+
+------------------------------------------------------------------------
+r581 | jcbowman | 2005-04-20 11:49:16 -0600 (Wed, 20 Apr 2005) | 5 lines
+Changed paths:
+ M /trunk/asymptote/base/graph.asy
+ M /trunk/asymptote/doc/asymptote.texi
+
+Moved put argument to axis routines to end of argument list, for
+consistency with draw.
+
+Added xline and yline interfaces to axis routines.
+
+------------------------------------------------------------------------
+r580 | rtprince | 2005-04-20 11:38:23 -0600 (Wed, 20 Apr 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/main.cc
+ M /trunk/asymptote/runtime.cc
+ M /trunk/asymptote/stack.cc
+ M /trunk/asymptote/stack.h
+
+Change stack::run(lambda*) to a free function vm::run.
+
+------------------------------------------------------------------------
+r579 | rtprince | 2005-04-20 11:18:23 -0600 (Wed, 20 Apr 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/main.cc
+ M /trunk/asymptote/parser.cc
+
+Fix handling of bad parse.
+
+------------------------------------------------------------------------
+r578 | jcbowman | 2005-04-20 09:51:49 -0600 (Wed, 20 Apr 2005) | 2 lines
+Changed paths:
+ D /trunk/asymptote/libboost
+
+''
+
+------------------------------------------------------------------------
+r577 | rtprince | 2005-04-20 08:31:22 -0600 (Wed, 20 Apr 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/parser.cc
+
+Refactor doParse().
+
+------------------------------------------------------------------------
+r576 | jcbowman | 2005-04-19 22:56:48 -0600 (Tue, 19 Apr 2005) | 3 lines
+Changed paths:
+ M /trunk/asymptote/base/stats.asy
+
+Fixed definition of correlation coefficient; added fit function to
+linefit struct.
+
+------------------------------------------------------------------------
+r575 | jcbowman | 2005-04-19 19:59:25 -0600 (Tue, 19 Apr 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/interact.cc
+ M /trunk/asymptote/parser.cc
+
+Implemented portable way of testing for directories (but not null files).
+
+------------------------------------------------------------------------
+r574 | jcbowman | 2005-04-19 14:55:14 -0600 (Tue, 19 Apr 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/errormsg.cc
+ M /trunk/asymptote/main.cc
+ M /trunk/asymptote/parser.cc
+
+Fixed stdin handling of parser.cc.
+
+------------------------------------------------------------------------
+r573 | rtprince | 2005-04-19 10:08:39 -0600 (Tue, 19 Apr 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/parser.cc
+
+*** empty log message ***
+
+------------------------------------------------------------------------
+r572 | jcbowman | 2005-04-19 08:05:31 -0600 (Tue, 19 Apr 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/errormsg.cc
+ M /trunk/asymptote/errors
+ M /trunk/asymptote/main.cc
+
+Fixed more bugs associated with new parser.
+
+------------------------------------------------------------------------
+r571 | jcbowman | 2005-04-19 01:31:02 -0600 (Tue, 19 Apr 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/interact.cc
+
+filebuf should not be static; fixed error message.
+
+------------------------------------------------------------------------
+r570 | jcbowman | 2005-04-19 01:25:18 -0600 (Tue, 19 Apr 2005) | 3 lines
+Changed paths:
+ M /trunk/asymptote/interact.cc
+
+Interactive input command now checks for a directory or null file.
+Print an error if input file can't be loaded.
+
+------------------------------------------------------------------------
+r569 | jcbowman | 2005-04-18 23:35:01 -0600 (Mon, 18 Apr 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/runtime.cc
+
+Make execute() autoload plain (and any gui file) again.
+
+------------------------------------------------------------------------
+r568 | jcbowman | 2005-04-18 23:28:58 -0600 (Mon, 18 Apr 2005) | 7 lines
+Changed paths:
+ M /trunk/asymptote/Makefile.in
+ M /trunk/asymptote/builtin.cc
+ M /trunk/asymptote/camp.l
+ M /trunk/asymptote/genv.cc
+ M /trunk/asymptote/genv.h
+ M /trunk/asymptote/interact.cc
+ M /trunk/asymptote/main.cc
+ A /trunk/asymptote/parser.cc
+ A /trunk/asymptote/parser.h
+ M /trunk/asymptote/runtime.cc
+ M /trunk/asymptote/runtime.h
+ M /trunk/asymptote/runtime.in
+ M /trunk/asymptote/settings.cc
+ M /trunk/asymptote/settings.h
+
+
+Re-added new parser, with fixes for standard input bugs (including a
+segmentation fault with -p option).
+
+Attempting to read a directory or a null file now returns
+"error: could not load module" instead of generating an exception.
+
+------------------------------------------------------------------------
+r567 | jcbowman | 2005-04-18 23:24:33 -0600 (Mon, 18 Apr 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/graph.asy
+
+Changed default value of axislabelmargin to 1.
+
+------------------------------------------------------------------------
+r566 | rtprince | 2005-04-18 21:59:13 -0600 (Mon, 18 Apr 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/main.cc
+
+Don't segfault on -p if we can't parse the file, but don't report an error.
+
+------------------------------------------------------------------------
+r565 | jcbowman | 2005-04-18 21:37:18 -0600 (Mon, 18 Apr 2005) | 3 lines
+Changed paths:
+ M /trunk/asymptote/fileio.cc
+ M /trunk/asymptote/main.cc
+ D /trunk/asymptote/parser.cc
+ D /trunk/asymptote/parser.h
+ M /trunk/asymptote/runtime.cc
+ M /trunk/asymptote/runtime.in
+
+
+Fixed cxx errors and and warnings; removed unused parser files.
+
+------------------------------------------------------------------------
+r564 | jcbowman | 2005-04-18 21:10:28 -0600 (Mon, 18 Apr 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/Makefile.in
+ M /trunk/asymptote/builtin.cc
+ M /trunk/asymptote/camp.l
+ M /trunk/asymptote/genv.cc
+ M /trunk/asymptote/genv.h
+ M /trunk/asymptote/interact.cc
+ M /trunk/asymptote/main.cc
+ M /trunk/asymptote/runtime.cc
+ M /trunk/asymptote/runtime.h
+ M /trunk/asymptote/settings.cc
+ M /trunk/asymptote/settings.h
+
+Revert to old parser until bugs in new parser are fixed.
+
+------------------------------------------------------------------------
+r563 | jcbowman | 2005-04-18 00:50:08 -0600 (Mon, 18 Apr 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/fileio.cc
+
+Fixed bug in csv mode when line mode is not set.
+
+------------------------------------------------------------------------
+r562 | rtprince | 2005-04-15 21:56:04 -0600 (Fri, 15 Apr 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote
+ M /trunk/asymptote/.cvsignore
+ M /trunk/asymptote/Makefile.in
+ M /trunk/asymptote/builtin.cc
+ M /trunk/asymptote/runtime.cc
+ M /trunk/asymptote/runtime.pl
+
+runtime.pl updates. Actually use the generated code.
+
+------------------------------------------------------------------------
+r561 | rtprince | 2005-04-15 19:52:18 -0600 (Fri, 15 Apr 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/runtime.in
+
+Typos.
+
+------------------------------------------------------------------------
+r560 | rtprince | 2005-04-15 19:45:07 -0600 (Fri, 15 Apr 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/inst.h
+
+inst.h cleanups.
+
+------------------------------------------------------------------------
+r559 | rtprince | 2005-04-15 18:42:28 -0600 (Fri, 15 Apr 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/item.h
+
+Implement type query for vm::item.
+
+------------------------------------------------------------------------
+r558 | rtprince | 2005-04-15 18:24:59 -0600 (Fri, 15 Apr 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/inst.h
+
+We use item to store string* in inst.
+
+------------------------------------------------------------------------
+r557 | rtprince | 2005-04-15 17:21:55 -0600 (Fri, 15 Apr 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/runtime.in
+ M /trunk/asymptote/runtime.pl
+
+Fixes for runtime.pl script.
+
+------------------------------------------------------------------------
+r556 | rtprince | 2005-04-15 16:00:18 -0600 (Fri, 15 Apr 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/Makefile.in
+ M /trunk/asymptote/runtime.in
+ M /trunk/asymptote/runtime.pl
+
+Fixes for runtime.pl script.
+
+------------------------------------------------------------------------
+r555 | rtprince | 2005-04-15 15:36:25 -0600 (Fri, 15 Apr 2005) | 2 lines
+Changed paths:
+ A /trunk/asymptote/runtime.in
+ A /trunk/asymptote/runtime.pl
+
+Initial runtime.pl script.
+
+------------------------------------------------------------------------
+r554 | rtprince | 2005-04-14 11:16:21 -0600 (Thu, 14 Apr 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/builtin.cc
+ M /trunk/asymptote/parser.cc
+ M /trunk/asymptote/parser.h
+ M /trunk/asymptote/runtime.cc
+ M /trunk/asymptote/runtime.h
+
+Add eval.
+
+------------------------------------------------------------------------
+r553 | rtprince | 2005-04-14 11:06:44 -0600 (Thu, 14 Apr 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/genv.cc
+ M /trunk/asymptote/genv.h
+ M /trunk/asymptote/main.cc
+
+Move interactive logic out of genv to main.
+
+------------------------------------------------------------------------
+r552 | jcbowman | 2005-04-14 07:40:55 -0600 (Thu, 14 Apr 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/plain.asy
+
+Interactive mode update.
+
+------------------------------------------------------------------------
+r551 | jcbowman | 2005-04-13 21:43:07 -0600 (Wed, 13 Apr 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/configure.ac
+
+Incremented version to 0.75cvs.
+
+------------------------------------------------------------------------
+r550 | jcbowman | 2005-04-13 21:10:38 -0600 (Wed, 13 Apr 2005) | 3 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+
+Removed figures with shading since from manual since many printers don't
+understand PostScript 3.
+
+------------------------------------------------------------------------
+r549 | jcbowman | 2005-04-13 20:42:00 -0600 (Wed, 13 Apr 2005) | 3 lines
+Changed paths:
+ M /trunk/asymptote/base/palette.asy
+
+Reduced default number of colors in images to work around postscript/pdf
+limitations (this prevented recent manuals from being printed).
+
+------------------------------------------------------------------------
+r548 | jcbowman | 2005-04-13 20:09:21 -0600 (Wed, 13 Apr 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/lineargraph.asy
+ M /trunk/asymptote/doc/lineargraph0.asy
+ M /trunk/asymptote/locate.cc
+ M /trunk/asymptote/settings.cc
+
+Fixed segmentation fault in version 0.73.
+
+------------------------------------------------------------------------
+r547 | rtprince | 2005-04-13 18:48:48 -0600 (Wed, 13 Apr 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/entry.cc
+
+overloaded::simplify() handles allocation.
+
+------------------------------------------------------------------------
+r546 | rtprince | 2005-04-13 17:57:38 -0600 (Wed, 13 Apr 2005) | 4 lines
+Changed paths:
+ M /trunk/asymptote/coder.cc
+ M /trunk/asymptote/frame.h
+ M /trunk/asymptote/inst.cc
+ M /trunk/asymptote/inst.h
+ M /trunk/asymptote/item.h
+ M /trunk/asymptote/runtime.cc
+ M /trunk/asymptote/stack.cc
+ M /trunk/asymptote/stack.h
+
+Make vm::frames extendable, and make function excplicitly allocate their
+local variables. This might be a first step towards true interactive
+support or caching modules from one run to another.
+
+------------------------------------------------------------------------
+r545 | jcbowman | 2005-04-13 11:07:58 -0600 (Wed, 13 Apr 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/configure.ac
+
+Incremented version to 0.74cvs.
+
+------------------------------------------------------------------------
+r544 | jcbowman | 2005-04-13 11:00:39 -0600 (Wed, 13 Apr 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/runtime.cc
+
+Make nullpath static.
+
+------------------------------------------------------------------------
+r543 | jcbowman | 2005-04-13 09:58:55 -0600 (Wed, 13 Apr 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+
+Minor updates.
+
+------------------------------------------------------------------------
+r542 | jcbowman | 2005-04-13 09:44:54 -0600 (Wed, 13 Apr 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/runtime.cc
+
+Push constructed objects as pointers.
+
+------------------------------------------------------------------------
+r541 | jcbowman | 2005-04-13 09:04:07 -0600 (Wed, 13 Apr 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/inst.cc
+ M /trunk/asymptote/inst.h
+
+Fixed sign of virtual assembly code line numbers.
+
+------------------------------------------------------------------------
+r540 | jcbowman | 2005-04-13 06:21:17 -0600 (Wed, 13 Apr 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/inst.cc
+ M /trunk/asymptote/inst.h
+ M /trunk/asymptote/stack.cc
+
+Fixed more warning messages.
+
+------------------------------------------------------------------------
+r539 | jcbowman | 2005-04-13 05:36:59 -0600 (Wed, 13 Apr 2005) | 6 lines
+Changed paths:
+ M /trunk/asymptote/arrayop.h
+ M /trunk/asymptote/castop.h
+ M /trunk/asymptote/drawpath.cc
+ M /trunk/asymptote/fileio.h
+ M /trunk/asymptote/main.cc
+ M /trunk/asymptote/pen.h
+ M /trunk/asymptote/picture.cc
+ M /trunk/asymptote/psfile.cc
+ M /trunk/asymptote/runtime.cc
+ M /trunk/asymptote/texfile.cc
+ M /trunk/asymptote/util.cc
+
+Accept cast of empty string to 0.
+
+Use string.empty() everywhere.
+
+Minor formatting changes.
+
+------------------------------------------------------------------------
+r538 | rtprince | 2005-04-13 00:36:07 -0600 (Wed, 13 Apr 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/inst.cc
+ M /trunk/asymptote/inst.h
+ M /trunk/asymptote/item.h
+
+Don't use boost iterator facade.
+
+------------------------------------------------------------------------
+r537 | rtprince | 2005-04-13 00:16:15 -0600 (Wed, 13 Apr 2005) | 3 lines
+Changed paths:
+ M /trunk/asymptote/item.h
+
+vm::item doesn't need to be memory::managed,
+since vm::frame is memory::managed_array.
+
+------------------------------------------------------------------------
+r536 | rtprince | 2005-04-13 00:04:31 -0600 (Wed, 13 Apr 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/locate.cc
+
+Fix absolute filename handling.
+
+------------------------------------------------------------------------
+r535 | jcbowman | 2005-04-12 23:41:53 -0600 (Tue, 12 Apr 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/arrayop.h
+ M /trunk/asymptote/castop.h
+ M /trunk/asymptote/inst.cc
+ M /trunk/asymptote/runtime.cc
+
+Fixed more cxx warnings.
+
+------------------------------------------------------------------------
+r534 | jcbowman | 2005-04-12 23:21:02 -0600 (Tue, 12 Apr 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/arrayop.h
+ M /trunk/asymptote/castop.h
+ M /trunk/asymptote/item.h
+ M /trunk/asymptote/knot.cc
+ M /trunk/asymptote/parser.cc
+ M /trunk/asymptote/runtime.cc
+ M /trunk/asymptote/runtime.h
+
+Fixed cxx warning messages.
+
+------------------------------------------------------------------------
+r533 | jcbowman | 2005-04-12 22:42:21 -0600 (Tue, 12 Apr 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/castop.h
+ M /trunk/asymptote/fileio.h
+ M /trunk/asymptote/item.h
+ M /trunk/asymptote/runtime.cc
+
+Further minor optimizations.
+
+------------------------------------------------------------------------
+r532 | jcbowman | 2005-04-12 15:36:18 -0600 (Tue, 12 Apr 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/item.h
+
+Removed unused friend declaration.
+
+------------------------------------------------------------------------
+r531 | jcbowman | 2005-04-12 14:26:17 -0600 (Tue, 12 Apr 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/inst.h
+ M /trunk/asymptote/item.h
+ M /trunk/asymptote/stack.cc
+
+Replaced boost::any with a much faster type-safe union.
+
+------------------------------------------------------------------------
+r530 | rtprince | 2005-04-12 14:17:09 -0600 (Tue, 12 Apr 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/arrayop.h
+ M /trunk/asymptote/mathop.h
+
+mathop's don't need vm::stack.
+
+------------------------------------------------------------------------
+r529 | rtprince | 2005-04-12 14:08:33 -0600 (Tue, 12 Apr 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/arrayop.h
+ M /trunk/asymptote/castop.h
+ M /trunk/asymptote/inst.cc
+ M /trunk/asymptote/main.cc
+ M /trunk/asymptote/mathop.h
+ M /trunk/asymptote/runtime.cc
+ M /trunk/asymptote/runtime.h
+ M /trunk/asymptote/stack.cc
+ M /trunk/asymptote/stack.h
+
+Move curPos out of vm::stack.
+
+------------------------------------------------------------------------
+r528 | rtprince | 2005-04-11 19:21:59 -0600 (Mon, 11 Apr 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/dec.cc
+
+Push empty item instead of (void*)0.
+
+------------------------------------------------------------------------
+r527 | rtprince | 2005-04-11 14:42:08 -0600 (Mon, 11 Apr 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/Makefile.in
+ M /trunk/asymptote/camp.l
+ M /trunk/asymptote/genv.cc
+ A /trunk/asymptote/parser.cc
+ A /trunk/asymptote/parser.h
+
+Seperate parser code from camp.l and genv.cc into parser.{h,cc}.
+
+------------------------------------------------------------------------
+r526 | rtprince | 2005-04-11 14:40:13 -0600 (Mon, 11 Apr 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/settings.cc
+
+Change ./ to . in searchPath to avoid .//file.asy in messages.
+
+------------------------------------------------------------------------
+r525 | rtprince | 2005-04-11 14:28:03 -0600 (Mon, 11 Apr 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/Makefile.in
+ M /trunk/asymptote/genv.cc
+ M /trunk/asymptote/interact.cc
+ A /trunk/asymptote/locate.cc
+ A /trunk/asymptote/locate.h
+ M /trunk/asymptote/settings.cc
+ M /trunk/asymptote/settings.h
+
+Reimplement locateFile using std::string.
+
+------------------------------------------------------------------------
+r524 | jcbowman | 2005-04-09 21:20:51 -0600 (Sat, 09 Apr 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/picture.cc
+ M /trunk/asymptote/runtime.cc
+ M /trunk/asymptote/texfile.cc
+ M /trunk/asymptote/texfile.h
+
+Fixed texpreamble for multiple files and latex asy environment.
+
+------------------------------------------------------------------------
+r523 | jcbowman | 2005-04-09 16:26:50 -0600 (Sat, 09 Apr 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/metapost.asy
+ M /trunk/asymptote/examples/conicurv.asy
+
+Removed nonscalable fonts.
+
+------------------------------------------------------------------------
+r522 | jcbowman | 2005-04-08 23:52:01 -0600 (Fri, 08 Apr 2005) | 7 lines
+Changed paths:
+ M /trunk/asymptote/base/plain.asy
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/examples/hierarchy.asy
+
+
+box(frame), ellipse(frame), labelbox(frame), labelellipse(frame) now
+return the boundary as a guide.
+
+box(frame) and ellipse(frame) prepend to frame for filling with a
+background colour, as illustrated in hierarchy.asy.
+
+------------------------------------------------------------------------
+r521 | jcbowman | 2005-04-08 14:54:13 -0600 (Fri, 08 Apr 2005) | 2 lines
+Changed paths:
+ A /trunk/asymptote/examples/hierarchy.asy
+
+Example of labelellipse.
+
+------------------------------------------------------------------------
+r520 | jcbowman | 2005-04-08 14:52:47 -0600 (Fri, 08 Apr 2005) | 3 lines
+Changed paths:
+ M /trunk/asymptote/base/plain.asy
+ M /trunk/asymptote/doc/asymptote.texi
+
+Added ellipse(frame) and labelellipse(frame,string,position).
+Renamed bbox(frame) to box(frame) for consistency.
+
+------------------------------------------------------------------------
+r519 | jcbowman | 2005-04-08 14:34:04 -0600 (Fri, 08 Apr 2005) | 3 lines
+Changed paths:
+ M /trunk/asymptote/inst.h
+
+Workaround for bug in build 1671 of gcc (version 3.3 20030304) under Darwin
+(MacOS).
+
+------------------------------------------------------------------------
+r518 | rtprince | 2005-04-06 20:39:19 -0600 (Wed, 06 Apr 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/stack.cc
+
+Cache *ip as reference rather than pointer.
+
+------------------------------------------------------------------------
+r517 | jcbowman | 2005-04-06 15:46:08 -0600 (Wed, 06 Apr 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/main.cc
+
+Added check to interrupt handler.
+
+------------------------------------------------------------------------
+r516 | jcbowman | 2005-04-06 14:01:41 -0600 (Wed, 06 Apr 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/errormsg.h
+
+Fixed cxx warning messages.
+
+------------------------------------------------------------------------
+r515 | jcbowman | 2005-04-06 13:47:25 -0600 (Wed, 06 Apr 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/camperror.h
+ M /trunk/asymptote/errormsg.cc
+ M /trunk/asymptote/errormsg.h
+ M /trunk/asymptote/main.cc
+ M /trunk/asymptote/stack.cc
+
+Optimized main loop.
+
+------------------------------------------------------------------------
+r514 | rtprince | 2005-04-06 00:20:40 -0600 (Wed, 06 Apr 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/inst.cc
+
+Use error from stack.cc instead of calling em->runtime directly.
+
+------------------------------------------------------------------------
+r513 | jcbowman | 2005-04-05 22:53:43 -0600 (Tue, 05 Apr 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/errormsg.h
+ M /trunk/asymptote/stack.cc
+ M /trunk/asymptote/stack.h
+
+minor optimizations
+
+------------------------------------------------------------------------
+r512 | jcbowman | 2005-04-05 19:31:54 -0600 (Tue, 05 Apr 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/errormsg.cc
+
+Reformatted.
+
+------------------------------------------------------------------------
+r511 | rtprince | 2005-04-05 11:46:44 -0600 (Tue, 05 Apr 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/errormsg.cc
+
+Operator precedence fix.
+
+------------------------------------------------------------------------
+r510 | rtprince | 2005-04-05 08:42:47 -0600 (Tue, 05 Apr 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/stack.h
+
+We don't use stack:ip any more.
+
+------------------------------------------------------------------------
+r509 | rtprince | 2005-04-05 08:39:25 -0600 (Tue, 05 Apr 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/coder.cc
+ M /trunk/asymptote/coder.h
+ M /trunk/asymptote/inst.cc
+ M /trunk/asymptote/inst.h
+ M /trunk/asymptote/stack.cc
+ M /trunk/asymptote/stack.h
+
+Reapply curPos patch.
+
+------------------------------------------------------------------------
+r508 | rtprince | 2005-04-05 08:38:12 -0600 (Tue, 05 Apr 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/errormsg.cc
+
+Fix interactive error reporting.
+
+------------------------------------------------------------------------
+r507 | rtprince | 2005-04-05 01:15:37 -0600 (Tue, 05 Apr 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/camp.l
+ M /trunk/asymptote/errormsg.cc
+ M /trunk/asymptote/errormsg.h
+
+Track line numbers in position instead of fileinfo.
+
+------------------------------------------------------------------------
+r506 | rtprince | 2005-04-05 01:13:43 -0600 (Tue, 05 Apr 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/coder.cc
+
+Don't access program.encode directly.
+
+------------------------------------------------------------------------
+r505 | jcbowman | 2005-04-04 14:22:06 -0600 (Mon, 04 Apr 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/picture.cc
+
+prepend should insert after beginning of layer
+
+------------------------------------------------------------------------
+r504 | jcbowman | 2005-04-04 14:07:22 -0600 (Mon, 04 Apr 2005) | 4 lines
+Changed paths:
+ M /trunk/asymptote/errormsg.cc
+ M /trunk/asymptote/picture.cc
+ M /trunk/asymptote/picture.h
+ M /trunk/asymptote/runtime.cc
+
+Make empty() use nodes.empty() rather than nodes.size().
+
+STL list portability fixes.
+
+------------------------------------------------------------------------
+r503 | jcbowman | 2005-04-04 10:29:54 -0600 (Mon, 04 Apr 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/graph.asy
+ M /trunk/asymptote/doc/asymptote.texi
+
+Ignore crop() on an empty picture.
+
+------------------------------------------------------------------------
+r502 | jcbowman | 2005-04-04 00:21:02 -0600 (Mon, 04 Apr 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/configure.ac
+
+Incremented version to 0.73cvs.
+
+------------------------------------------------------------------------
+r501 | jcbowman | 2005-04-03 23:32:55 -0600 (Sun, 03 Apr 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/errormsg.cc
+ M /trunk/asymptote/errormsg.h
+
+Removed spurious blank tracing lines.
+
+------------------------------------------------------------------------
+r500 | jcbowman | 2005-04-03 23:06:37 -0600 (Sun, 03 Apr 2005) | 7 lines
+Changed paths:
+ M /trunk/asymptote/coder.cc
+ M /trunk/asymptote/coder.h
+ M /trunk/asymptote/errormsg.cc
+ M /trunk/asymptote/errormsg.h
+ M /trunk/asymptote/inst.cc
+ M /trunk/asymptote/inst.h
+ M /trunk/asymptote/main.cc
+ M /trunk/asymptote/stack.cc
+ M /trunk/asymptote/stack.h
+
+Revert fileposition changes again, due to segmentation fault with -vvvvv.
+
+Moved line-number tracing code into main loop.
+
+Avoid the need for the lastpos variable by moving stack s out of main loop
+in main.cc.
+
+------------------------------------------------------------------------
+r499 | jcbowman | 2005-04-03 21:33:06 -0600 (Sun, 03 Apr 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/coder.cc
+ M /trunk/asymptote/coder.h
+ M /trunk/asymptote/inst.cc
+ M /trunk/asymptote/inst.h
+ M /trunk/asymptote/stack.cc
+ M /trunk/asymptote/stack.h
+
+Reinstated new file position code w/segmentation fault bug fixed.
+
+------------------------------------------------------------------------
+r498 | jcbowman | 2005-04-03 20:18:15 -0600 (Sun, 03 Apr 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/coder.cc
+ M /trunk/asymptote/coder.h
+ M /trunk/asymptote/errormsg.h
+ M /trunk/asymptote/inst.cc
+ M /trunk/asymptote/inst.h
+ M /trunk/asymptote/stack.cc
+ M /trunk/asymptote/stack.h
+
+Backout 2005-03-17 runtime file position changes to avoid a segmentation fault.
+
+------------------------------------------------------------------------
+r497 | jcbowman | 2005-04-02 21:38:47 -0700 (Sat, 02 Apr 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/runtime.cc
+
+Check for space format specifier as well as plus in format(string,real).
+
+------------------------------------------------------------------------
+r496 | jcbowman | 2005-04-02 21:21:30 -0700 (Sat, 02 Apr 2005) | 5 lines
+Changed paths:
+ M /trunk/asymptote/base/plain.asy
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/examples/yingyang.asy
+
+Removed deconstruct flag from picture in favour of group option to picture
+and frame add routines.
+
+Updated documentation.
+
+------------------------------------------------------------------------
+r495 | jcbowman | 2005-04-02 16:29:41 -0700 (Sat, 02 Apr 2005) | 2 lines
+Changed paths:
+ A /trunk/asymptote/drawgroup.h
+
+Added missing file.
+
+------------------------------------------------------------------------
+r494 | jcbowman | 2005-04-02 16:17:16 -0700 (Sat, 02 Apr 2005) | 4 lines
+Changed paths:
+ M /trunk/asymptote/base/graph.asy
+ M /trunk/asymptote/base/plain.asy
+ M /trunk/asymptote/base/pstoedit.asy
+ M /trunk/asymptote/base/stats.asy
+ M /trunk/asymptote/builtin.cc
+ M /trunk/asymptote/drawclipbegin.h
+ M /trunk/asymptote/drawclipend.h
+ M /trunk/asymptote/drawelement.h
+ M /trunk/asymptote/drawlayer.h
+ M /trunk/asymptote/picture.cc
+ M /trunk/asymptote/picture.h
+ M /trunk/asymptote/runtime.cc
+ M /trunk/asymptote/runtime.h
+ M /trunk/asymptote/transform.h
+ M /trunk/asymptote/types.cc
+ M /trunk/asymptote/types.h
+
+Reimplemented deconstruction at a lower level to allow both pictures and frames
+to be deconstructed (or grouped with begingroup/endgroup). Deconstruction
+now works properly with clipping and erasing.
+
+------------------------------------------------------------------------
+r493 | jcbowman | 2005-04-01 21:22:03 -0700 (Fri, 01 Apr 2005) | 4 lines
+Changed paths:
+ M /trunk/asymptote/drawelement.h
+ M /trunk/asymptote/drawlabel.cc
+ M /trunk/asymptote/drawlabel.h
+ M /trunk/asymptote/picture.cc
+
+Check that drawLabel::bounds is called before drawLabel::write.
+
+Remove unused setup code.
+
+------------------------------------------------------------------------
+r492 | jcbowman | 2005-04-01 11:37:28 -0700 (Fri, 01 Apr 2005) | 7 lines
+Changed paths:
+ M /trunk/asymptote/base/plain.asy
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/doc/lineargraph.asy
+ D /trunk/asymptote/doc/lineargraph2.asy
+
+Added attach(pair,picture,frame) to automatically increase the
+picture size to accomodate adding a frame about a user coordinate.
+
+Added warning about erasing deconstructed pictures.
+
+Updated lineargraph and documentation to use attach.
+
+------------------------------------------------------------------------
+r491 | jcbowman | 2005-03-31 22:14:38 -0700 (Thu, 31 Mar 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/picture.cc
+
+Reset bounding box when prepending.
+
+------------------------------------------------------------------------
+r490 | jcbowman | 2005-03-31 21:47:16 -0700 (Thu, 31 Mar 2005) | 12 lines
+Changed paths:
+ M /trunk/asymptote/base/drawtree.asy
+ M /trunk/asymptote/base/graph.asy
+ M /trunk/asymptote/base/plain.asy
+ M /trunk/asymptote/doc/loggraph.asy
+ M /trunk/asymptote/drawclipend.h
+ M /trunk/asymptote/errors
+ M /trunk/asymptote/examples/labelbox.asy
+ M /trunk/asymptote/picture.cc
+ M /trunk/asymptote/picture.h
+
+Fixed label alignment vs. positioning transformation problem.
+
+Removed frame labelBox() in favour of void labelbox(frame); updated example.
+
+Make logarithmic checks in autoscale conditional.
+
+xlimits and ylimits now adjust deferred drawing bounds.
+
+Simplified bboxstack handling.
+
+Updated "errors" list.
+
+------------------------------------------------------------------------
+r489 | jcbowman | 2005-03-31 14:37:05 -0700 (Thu, 31 Mar 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/Makefile.in
+ M /trunk/asymptote/configure.ac
+ M /trunk/asymptote/doc/asymptote.texi
+ D /trunk/asymptote/locate.cc
+ D /trunk/asymptote/locate.h
+
+Revert configuration to only require boost headers.
+
+------------------------------------------------------------------------
+r488 | jcbowman | 2005-03-31 12:15:17 -0700 (Thu, 31 Mar 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/camp.l
+ M /trunk/asymptote/errormsg.cc
+ M /trunk/asymptote/interact.cc
+
+Backout boost fixes.
+
+------------------------------------------------------------------------
+r487 | rtprince | 2005-03-31 12:08:04 -0700 (Thu, 31 Mar 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/camp.l
+ M /trunk/asymptote/errormsg.cc
+ M /trunk/asymptote/errormsg.h
+ M /trunk/asymptote/genv.cc
+ M /trunk/asymptote/interact.cc
+ M /trunk/asymptote/settings.cc
+ M /trunk/asymptote/settings.h
+
+Revert boost::filesystem changes.
+
+------------------------------------------------------------------------
+r486 | jcbowman | 2005-03-31 00:22:29 -0700 (Thu, 31 Mar 2005) | 9 lines
+Changed paths:
+ M /trunk/asymptote/base/math.asy
+ M /trunk/asymptote/doc/asymptote.texi
+
+
+Added explicit linear equation solver; used to handle general matrix inversion.
+
+Fixed return type of real[][] * real[].
+
+Hard coded 2x2 and 3x3 determinants.
+
+Update documentation.
+
+------------------------------------------------------------------------
+r485 | jcbowman | 2005-03-30 18:06:36 -0700 (Wed, 30 Mar 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/libboost/operations_posix_windows.cc
+
+Fixed cxx warning message.
+
+------------------------------------------------------------------------
+r484 | jcbowman | 2005-03-30 17:54:42 -0700 (Wed, 30 Mar 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+
+Minor updates.
+
+------------------------------------------------------------------------
+r483 | jcbowman | 2005-03-30 17:15:06 -0700 (Wed, 30 Mar 2005) | 3 lines
+Changed paths:
+ M /trunk/asymptote/Makefile.in
+ M /trunk/asymptote/configure.ac
+ M /trunk/asymptote/doc/asymptote.texi
+ A /trunk/asymptote/libboost
+ A /trunk/asymptote/libboost/convenience.cc
+ A /trunk/asymptote/libboost/exception.cc
+ A /trunk/asymptote/libboost/operations_posix_windows.cc
+ A /trunk/asymptote/libboost/path_posix_windows.cc
+
+Added portable version of boost::filesystem for systems without boost
+library, in particular for linux-alpha cxx compiler.
+
+------------------------------------------------------------------------
+r482 | jcbowman | 2005-03-28 20:22:47 -0700 (Mon, 28 Mar 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+
+Updated documentation.
+
+------------------------------------------------------------------------
+r481 | jcbowman | 2005-03-28 20:06:24 -0700 (Mon, 28 Mar 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/configure.ac
+
+Allow compatibility with older versions of autoconf.
+
+------------------------------------------------------------------------
+r480 | jcbowman | 2005-03-28 16:11:35 -0700 (Mon, 28 Mar 2005) | 9 lines
+Changed paths:
+ M /trunk/asymptote/Makefile.in
+ M /trunk/asymptote/base/graph.asy
+ M /trunk/asymptote/base/plain.asy
+ M /trunk/asymptote/base/stats.asy
+ M /trunk/asymptote/camp.l
+ M /trunk/asymptote/configure.ac
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/doc/histogram.asy
+ M /trunk/asymptote/errormsg.cc
+ M /trunk/asymptote/runtime.cc
+ M /trunk/asymptote/util.h
+
+Updated configuration and documentation regarding boost-1.32.0 library.
+
+Improved format(string,real).
+
+Generalized histogram and changed order of arguments of frequency and histogram
+(bin boundaries are now given before the data).
+
+Fixed problems with Log(false,false).
+
+------------------------------------------------------------------------
+r479 | jcbowman | 2005-03-25 10:56:40 -0700 (Fri, 25 Mar 2005) | 4 lines
+Changed paths:
+ M /trunk/asymptote/drawclipbegin.h
+ M /trunk/asymptote/drawclipend.h
+ M /trunk/asymptote/drawelement.h
+ M /trunk/asymptote/drawimage.h
+ M /trunk/asymptote/drawlabel.cc
+ M /trunk/asymptote/drawlabel.h
+ M /trunk/asymptote/drawpath.cc
+ M /trunk/asymptote/drawpath.h
+ M /trunk/asymptote/picture.cc
+ M /trunk/asymptote/picture.h
+
+Cache drawelement bbox contributions where possible.
+
+Make bboxstack local to picture frame.
+
+------------------------------------------------------------------------
+r478 | rtprince | 2005-03-24 22:46:41 -0700 (Thu, 24 Mar 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc
+ M /trunk/asymptote/doc/.cvsignore
+
+We generate .png's.
+
+------------------------------------------------------------------------
+r477 | rtprince | 2005-03-24 19:51:59 -0700 (Thu, 24 Mar 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/genv.h
+
+Don't have symbolToFile anymore.
+
+------------------------------------------------------------------------
+r476 | rtprince | 2005-03-24 18:00:39 -0700 (Thu, 24 Mar 2005) | 3 lines
+Changed paths:
+ M /trunk/asymptote/Makefile.in
+ M /trunk/asymptote/camp.l
+ M /trunk/asymptote/errormsg.cc
+ M /trunk/asymptote/errormsg.h
+ M /trunk/asymptote/genv.cc
+ M /trunk/asymptote/interact.cc
+ A /trunk/asymptote/locate.cc
+ A /trunk/asymptote/locate.h
+ M /trunk/asymptote/settings.cc
+ M /trunk/asymptote/settings.h
+
+Use boost::filesystem for find files to parse.
+Move file locating logic to locate.{cc,h}.
+
+------------------------------------------------------------------------
+r475 | jcbowman | 2005-03-24 17:34:14 -0700 (Thu, 24 Mar 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/lineargraph.asy
+ M /trunk/asymptote/doc/lineargraph2.asy
+
+Simplified legend examples.
+
+------------------------------------------------------------------------
+r474 | jcbowman | 2005-03-24 07:35:06 -0700 (Thu, 24 Mar 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/doc/bigsquare.asy
+ M /trunk/asymptote/doc/cube.asy
+ M /trunk/asymptote/doc/datagraph.asy
+ M /trunk/asymptote/doc/diagonal.asy
+ M /trunk/asymptote/doc/exp.asy
+ M /trunk/asymptote/doc/generalaxis.asy
+ M /trunk/asymptote/doc/hatch.asy
+ M /trunk/asymptote/doc/histogram.asy
+ M /trunk/asymptote/doc/image.asy
+ M /trunk/asymptote/doc/labelsquare.asy
+ M /trunk/asymptote/doc/latexusage.tex
+ M /trunk/asymptote/doc/lineargraph.asy
+ M /trunk/asymptote/doc/lineargraph0.asy
+ M /trunk/asymptote/doc/lineargraph2.asy
+ M /trunk/asymptote/doc/loggraph.asy
+ M /trunk/asymptote/doc/mosquito.asy
+ M /trunk/asymptote/doc/parametricgraph.asy
+ M /trunk/asymptote/doc/quartercircle.asy
+ M /trunk/asymptote/doc/secondaryaxis.asy
+ M /trunk/asymptote/doc/shade.asy
+ M /trunk/asymptote/doc/shadedtiling.asy
+ M /trunk/asymptote/doc/square.asy
+ M /trunk/asymptote/doc/superpath.asy
+ M /trunk/asymptote/doc/tile.asy
+
+Workaround makeinfo indentation bug.
+
+------------------------------------------------------------------------
+r473 | jcbowman | 2005-03-24 07:02:51 -0700 (Thu, 24 Mar 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+
+Fixed typos.
+
+------------------------------------------------------------------------
+r472 | jcbowman | 2005-03-23 19:49:30 -0700 (Wed, 23 Mar 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/examples/labelbox.asy
+
+Simplified example.
+
+------------------------------------------------------------------------
+r471 | rtprince | 2005-03-23 19:13:13 -0700 (Wed, 23 Mar 2005) | 3 lines
+Changed paths:
+ M /trunk/asymptote/genv.cc
+ M /trunk/asymptote/genv.h
+ M /trunk/asymptote/main.cc
+
+Have main load plain.asy and ${outname}.gui explicitly,
+rather than doing it implicitly in genv::genv().
+
+------------------------------------------------------------------------
+r470 | jcbowman | 2005-03-23 13:25:54 -0700 (Wed, 23 Mar 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/graph.asy
+
+optimized crop()
+
+------------------------------------------------------------------------
+r469 | rtprince | 2005-03-23 10:14:24 -0700 (Wed, 23 Mar 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/castop.h
+
+*** empty log message ***
+
+------------------------------------------------------------------------
+r468 | jcbowman | 2005-03-22 22:27:53 -0700 (Tue, 22 Mar 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/configure.ac
+
+Incremented version to 0.72cvs.
+
+------------------------------------------------------------------------
+r467 | jcbowman | 2005-03-22 22:03:18 -0700 (Tue, 22 Mar 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+
+Document leastsquare routine.
+
+------------------------------------------------------------------------
+r466 | jcbowman | 2005-03-22 21:50:22 -0700 (Tue, 22 Mar 2005) | 2 lines
+Changed paths:
+ D /trunk/asymptote/knotlist.cc
+ D /trunk/asymptote/knotlist.h
+ D /trunk/asymptote/pathlist.cc
+ D /trunk/asymptote/pathlist.h
+
+Removed obsolete files.
+
+------------------------------------------------------------------------
+r465 | jcbowman | 2005-03-22 21:32:58 -0700 (Tue, 22 Mar 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/plain.asy
+ M /trunk/asymptote/doc/asymptote.texi
+ A /trunk/asymptote/examples/elliptic.asy
+ A /trunk/asymptote/examples/lines.asy
+ D /trunk/asymptote/examples/linetest.asy
+
+Documented save() and restore(). Renamed linetest.asy to lines.asy.
+
+------------------------------------------------------------------------
+r464 | jcbowman | 2005-03-22 20:51:41 -0700 (Tue, 22 Mar 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/math.asy
+ M /trunk/asymptote/doc/asymptote.texi
+ A /trunk/asymptote/examples/linetest.asy
+
+Added and documented Andy's drawline routine.
+
+------------------------------------------------------------------------
+r463 | hammera | 2005-03-22 20:43:51 -0700 (Tue, 22 Mar 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/plain.asy
+
+Added saving and restoring of the graphics state.
+
+------------------------------------------------------------------------
+r462 | jcbowman | 2005-03-22 20:14:57 -0700 (Tue, 22 Mar 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/plain.asy
+ M /trunk/asymptote/picture.cc
+ M /trunk/asymptote/picture.h
+
+Cache picture bounds.
+
+------------------------------------------------------------------------
+r461 | jcbowman | 2005-03-22 16:30:09 -0700 (Tue, 22 Mar 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/graph.asy
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/doc/parametricgraph.asy
+
+Reinstated crop; use current value of userMin/userMax in xlimits and ylimits.
+
+------------------------------------------------------------------------
+r460 | jcbowman | 2005-03-22 14:05:30 -0700 (Tue, 22 Mar 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/doc/histogram.asy
+ A /trunk/asymptote/doc/lineargraph0.asy
+
+Added further legend example.
+
+------------------------------------------------------------------------
+r459 | rtprince | 2005-03-22 09:25:12 -0700 (Tue, 22 Mar 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/pool.h
+
+cxx doesn't like const objects in containers.
+
+------------------------------------------------------------------------
+r458 | jcbowman | 2005-03-22 08:21:43 -0700 (Tue, 22 Mar 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+ A /trunk/asymptote/doc/lineargraph2.asy
+
+Document alternative for legend fitting.
+
+------------------------------------------------------------------------
+r457 | jcbowman | 2005-03-21 23:10:38 -0700 (Mon, 21 Mar 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/knot.cc
+
+More cxx warnings fixed.
+
+------------------------------------------------------------------------
+r456 | jcbowman | 2005-03-21 22:56:46 -0700 (Mon, 21 Mar 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/knot.cc
+
+Fixed g++ warning messages.
+
+------------------------------------------------------------------------
+r455 | jcbowman | 2005-03-21 22:54:01 -0700 (Mon, 21 Mar 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/exp.cc
+ M /trunk/asymptote/exp.h
+ M /trunk/asymptote/knot.cc
+ M /trunk/asymptote/knot.h
+ M /trunk/asymptote/pool.cc
+
+Fixed warnings/errors under cxx.
+
+------------------------------------------------------------------------
+r454 | rtprince | 2005-03-21 22:37:08 -0700 (Mon, 21 Mar 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/inst.h
+ A /trunk/asymptote/item.h
+
+Move vm::item to its own file.
+
+------------------------------------------------------------------------
+r453 | rtprince | 2005-03-21 22:32:30 -0700 (Mon, 21 Mar 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/types.h
+
+Header file cleanup.
+
+------------------------------------------------------------------------
+r452 | jcbowman | 2005-03-21 22:17:08 -0700 (Mon, 21 Mar 2005) | 6 lines
+Changed paths:
+ M /trunk/asymptote/base/palette.asy
+ M /trunk/asymptote/base/plain.asy
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/doc/datagraph.asy
+ M /trunk/asymptote/doc/image.asy
+ M /trunk/asymptote/doc/lineargraph.asy
+
+Make legend a separate picture that can be positioned and aligned like any
+other picture (see lineargraph.asy example). The legend must now be
+explicitly added to the picture, for example, with add(point(E),legend(20E));
+
+Palette also now returns a new picture.
+
+------------------------------------------------------------------------
+r451 | jcbowman | 2005-03-21 21:02:56 -0700 (Mon, 21 Mar 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/xasy
+
+Updated move limits to be compatible with SW alignment.
+
+------------------------------------------------------------------------
+r450 | rtprince | 2005-03-21 16:28:54 -0700 (Mon, 21 Mar 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/runtime.cc
+
+Use free function vm::pop instead of vm::stack::pop.
+
+------------------------------------------------------------------------
+r449 | rtprince | 2005-03-21 16:27:31 -0700 (Mon, 21 Mar 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/types.cc
+
+std::equal is much faster than explicit iteration.
+
+------------------------------------------------------------------------
+r448 | hammera | 2005-03-21 12:31:47 -0700 (Mon, 21 Mar 2005) | 4 lines
+Changed paths:
+ M /trunk/asymptote/Makefile.in
+ M /trunk/asymptote/base/plain.asy
+ M /trunk/asymptote/builtin.cc
+ M /trunk/asymptote/camp.l
+ M /trunk/asymptote/camp.y
+ M /trunk/asymptote/exp.cc
+ M /trunk/asymptote/exp.h
+ A /trunk/asymptote/flatguide.cc
+ A /trunk/asymptote/flatguide.h
+ M /trunk/asymptote/genv.cc
+ M /trunk/asymptote/guide.cc
+ M /trunk/asymptote/guide.h
+ M /trunk/asymptote/guideflags.h
+ A /trunk/asymptote/knot.cc
+ A /trunk/asymptote/knot.h
+ M /trunk/asymptote/mathop.h
+ A /trunk/asymptote/mod.h
+ M /trunk/asymptote/path.cc
+ M /trunk/asymptote/path.h
+ M /trunk/asymptote/runtime.cc
+ M /trunk/asymptote/runtime.h
+ M /trunk/asymptote/types.cc
+ M /trunk/asymptote/types.h
+
+Replaced the implementation of solving guides into paths.
+
+Refactored the abstract syntax of operators.
+
+------------------------------------------------------------------------
+r447 | jcbowman | 2005-03-21 11:04:22 -0700 (Mon, 21 Mar 2005) | 4 lines
+Changed paths:
+ M /trunk/asymptote/base/graph.asy
+ M /trunk/asymptote/base/plain.asy
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/doc/datagraph.asy
+ M /trunk/asymptote/doc/diatom.asy
+
+Changed marker filltype default to NoFill.
+
+Introduced Above/Below and Crop/NoCrop variables.
+
+------------------------------------------------------------------------
+r446 | jcbowman | 2005-03-21 11:03:57 -0700 (Mon, 21 Mar 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/builtin.cc
+
+Code cleanup.
+
+------------------------------------------------------------------------
+r445 | rtprince | 2005-03-21 10:06:20 -0700 (Mon, 21 Mar 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/pool.cc
+
+memory::insert(poolitem) was eating most of the runtime. Use std::deque instead of std::set.
+
+------------------------------------------------------------------------
+r444 | jcbowman | 2005-03-21 02:23:10 -0700 (Mon, 21 Mar 2005) | 6 lines
+Changed paths:
+ M /trunk/asymptote/base/graph.asy
+ M /trunk/asymptote/base/plain.asy
+ M /trunk/asymptote/castop.h
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/doc/datagraph.asy
+ M /trunk/asymptote/doc/diatom.asy
+ M /trunk/asymptote/doc/exp.asy
+ M /trunk/asymptote/doc/loggraph.asy
+ M /trunk/asymptote/doc/parametricgraph.asy
+ M /trunk/asymptote/doc/secondaryaxis.asy
+ M /trunk/asymptote/examples/cardiod.asy
+ M /trunk/asymptote/mathop.h
+ M /trunk/asymptote/picture.cc
+
+Prepend only nonextended axes in current layer.
+
+Fixed xlimits and ylimits; removed obsolete crop() routine.
+
+Updated documentation.
+
+------------------------------------------------------------------------
+r443 | jcbowman | 2005-03-20 18:48:04 -0700 (Sun, 20 Mar 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/examples/cardiod.asy
+
+Draw axis on top of cardiod.
+
+------------------------------------------------------------------------
+r442 | jcbowman | 2005-03-20 17:33:14 -0700 (Sun, 20 Mar 2005) | 5 lines
+Changed paths:
+ M /trunk/asymptote/base/graph.asy
+ M /trunk/asymptote/base/palette.asy
+ M /trunk/asymptote/base/plain.asy
+ M /trunk/asymptote/builtin.cc
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/doc/diatom.asy
+ M /trunk/asymptote/doc/exp.asy
+ M /trunk/asymptote/picture.cc
+ M /trunk/asymptote/picture.h
+ M /trunk/asymptote/runtime.cc
+ M /trunk/asymptote/runtime.h
+ M /trunk/asymptote/types.cc
+
+
+By default, draw axes before other objects in current layer.
+
+Fixed frame alignment scaling.
+
+------------------------------------------------------------------------
+r441 | rtprince | 2005-03-20 17:32:39 -0700 (Sun, 20 Mar 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/castop.h
+ M /trunk/asymptote/mathop.h
+
+Add include guards.
+
+------------------------------------------------------------------------
+r440 | jcbowman | 2005-03-20 17:12:50 -0700 (Sun, 20 Mar 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/stats.asy
+
+Added least-squares fit.
+
+------------------------------------------------------------------------
+r439 | rtprince | 2005-03-20 17:03:45 -0700 (Sun, 20 Mar 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/arrayop.h
+ M /trunk/asymptote/builtin.cc
+ M /trunk/asymptote/castop.h
+ M /trunk/asymptote/mathop.h
+ M /trunk/asymptote/runtime.cc
+ M /trunk/asymptote/stack.h
+
+Use free function vm::pop instead of vm::stack::pop.
+
+------------------------------------------------------------------------
+r438 | jcbowman | 2005-03-19 01:26:51 -0700 (Sat, 19 Mar 2005) | 7 lines
+Changed paths:
+ M /trunk/asymptote/base/plain.asy
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/fileio.h
+ M /trunk/asymptote/runtime.cc
+ M /trunk/asymptote/stack.cc
+
+
+Added append boolean option to output and xoutput.
+
+Omit "runtime" from error().
+
+Added frame marker(path g, pen p=currentpen).
+
+------------------------------------------------------------------------
+r437 | rtprince | 2005-03-18 15:41:29 -0700 (Fri, 18 Mar 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/absyn.h
+ M /trunk/asymptote/access.h
+ M /trunk/asymptote/drawelement.h
+ M /trunk/asymptote/entry.h
+ M /trunk/asymptote/errormsg.h
+ M /trunk/asymptote/fileio.h
+ M /trunk/asymptote/frame.h
+ M /trunk/asymptote/guide.h
+ M /trunk/asymptote/import.h
+ M /trunk/asymptote/inst.h
+ M /trunk/asymptote/main.cc
+ M /trunk/asymptote/path.h
+ M /trunk/asymptote/pen.h
+ M /trunk/asymptote/picture.h
+ M /trunk/asymptote/pool.cc
+ M /trunk/asymptote/pool.h
+ M /trunk/asymptote/transform.h
+ M /trunk/asymptote/types.h
+
+Rename namespace mempool to memory.
+
+------------------------------------------------------------------------
+r436 | rtprince | 2005-03-18 15:23:24 -0700 (Fri, 18 Mar 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/castop.h
+ M /trunk/asymptote/mathop.h
+
+Add file headers to castop.h, mathop.h.
+
+------------------------------------------------------------------------
+r435 | rtprince | 2005-03-18 15:17:06 -0700 (Fri, 18 Mar 2005) | 3 lines
+Changed paths:
+ M /trunk/asymptote/arrayop.h
+ M /trunk/asymptote/builtin.cc
+ M /trunk/asymptote/builtin.h
+ M /trunk/asymptote/cast.cc
+ A /trunk/asymptote/castop.h
+ M /trunk/asymptote/genv.cc
+ A /trunk/asymptote/mathop.h
+ M /trunk/asymptote/runtime.cc
+ M /trunk/asymptote/runtime.h
+ M /trunk/asymptote/stack.cc
+ M /trunk/asymptote/stack.h
+
+Move all template runtime code into dedicated files castop.h and mathop.h.
+Cleanup all refrences to stack.h, so it isn't needlessly included.
+
+------------------------------------------------------------------------
+r434 | rtprince | 2005-03-18 14:33:24 -0700 (Fri, 18 Mar 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/drawelement.h
+
+Header include cleanup.
+
+------------------------------------------------------------------------
+r433 | jcbowman | 2005-03-17 23:08:01 -0700 (Thu, 17 Mar 2005) | 4 lines
+Changed paths:
+ M /trunk/asymptote/base/graph.asy
+ M /trunk/asymptote/base/plain.asy
+
+Allow one to turn on autoscaling again with xlimits(infinity,infinity), etc.
+
+Accept an overall scaling of frame alignment shifts.
+
+------------------------------------------------------------------------
+r432 | jcbowman | 2005-03-17 22:32:30 -0700 (Thu, 17 Mar 2005) | 4 lines
+Changed paths:
+ M /trunk/asymptote/base/graph.asy
+ M /trunk/asymptote/base/plain.asy
+
+Fixed interaction of new automin/automax scale flags with xlimits/ylimits.
+
+Use a small tick by default for unlabelled intermediate decade ticks.
+
+------------------------------------------------------------------------
+r431 | rtprince | 2005-03-17 16:41:41 -0700 (Thu, 17 Mar 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/stack.cc
+ M /trunk/asymptote/stack.h
+
+Remove UNALIAS, since it is no longer needed.
+
+------------------------------------------------------------------------
+r430 | rtprince | 2005-03-17 16:33:16 -0700 (Thu, 17 Mar 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/coder.cc
+ M /trunk/asymptote/coder.h
+ M /trunk/asymptote/errormsg.h
+ M /trunk/asymptote/inst.cc
+ M /trunk/asymptote/inst.h
+ M /trunk/asymptote/stack.cc
+ M /trunk/asymptote/stack.h
+
+Simplify runtime file position reporting.
+
+------------------------------------------------------------------------
+r429 | rtprince | 2005-03-17 15:26:35 -0700 (Thu, 17 Mar 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/stack.cc
+ M /trunk/asymptote/stack.h
+
+Start refactoring stack::run.
+
+------------------------------------------------------------------------
+r428 | rtprince | 2005-03-17 15:24:34 -0700 (Thu, 17 Mar 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/dec.cc
+ M /trunk/asymptote/genv.cc
+ M /trunk/asymptote/inst.cc
+ M /trunk/asymptote/inst.h
+ M /trunk/asymptote/newexp.cc
+ M /trunk/asymptote/stack.cc
+
+Replace inst::alloc with inst::makefunc + inst::popcall.
+
+------------------------------------------------------------------------
+r427 | rtprince | 2005-03-17 15:16:44 -0700 (Thu, 17 Mar 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/access.cc
+ M /trunk/asymptote/access.h
+ M /trunk/asymptote/inst.cc
+ M /trunk/asymptote/inst.h
+ M /trunk/asymptote/main.cc
+ M /trunk/asymptote/runtime.cc
+ M /trunk/asymptote/stack.cc
+ M /trunk/asymptote/stack.h
+
+stack::globals is obsolete. Get rid of it.
+
+------------------------------------------------------------------------
+r426 | rtprince | 2005-03-16 22:38:04 -0700 (Wed, 16 Mar 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/coder.cc
+ M /trunk/asymptote/coder.h
+ M /trunk/asymptote/stm.cc
+
+Fix return breakage.
+
+------------------------------------------------------------------------
+r425 | jcbowman | 2005-03-16 22:09:05 -0700 (Wed, 16 Mar 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/graph.asy
+
+Don't draw logarithmic subticks by default when number of big ticks > 2.
+
+------------------------------------------------------------------------
+r424 | jcbowman | 2005-03-16 22:01:16 -0700 (Wed, 16 Mar 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/graph.asy
+
+Show 10 subticks by default for thinned logarithmic graphs.
+
+------------------------------------------------------------------------
+r423 | jcbowman | 2005-03-16 21:17:20 -0700 (Wed, 16 Mar 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/errormsg.cc
+
+Fixed interactive line number reporting for files that are input.
+
+------------------------------------------------------------------------
+r422 | jcbowman | 2005-03-16 15:32:31 -0700 (Wed, 16 Mar 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/builtin.h
+
+Fixed more cxx warning messages.
+
+------------------------------------------------------------------------
+r421 | jcbowman | 2005-03-16 14:52:12 -0700 (Wed, 16 Mar 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/builtin.h
+
+Fixed cxx unused variable warning messages.
+
+------------------------------------------------------------------------
+r420 | jcbowman | 2005-03-16 14:35:40 -0700 (Wed, 16 Mar 2005) | 11 lines
+Changed paths:
+ M /trunk/asymptote/base/drawtree.asy
+ M /trunk/asymptote/base/graph.asy
+ M /trunk/asymptote/base/math.asy
+ M /trunk/asymptote/base/palette.asy
+ M /trunk/asymptote/base/plain.asy
+ M /trunk/asymptote/base/stats.asy
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/doc/datagraph.asy
+ A /trunk/asymptote/doc/histogram.asy
+ M /trunk/asymptote/doc/image.asy
+ M /trunk/asymptote/doc/latexusage.tex
+ M /trunk/asymptote/doc/mosquito.asy
+ M /trunk/asymptote/examples/labelbox.asy
+ M /trunk/asymptote/examples/sqrtx01.asy
+
+
+Added frame alignment (analogous to label alignment) for positioning frames
+on picture.
+
+Generalized and simplified palette bar interface by using frame alignment.
+
+Renamed addabout to add, drawabout to draw, fillabout to fill, and
+filldrawabout to filldraw.
+
+Updated documentation; added examples of frame alignment and histograms.
+
+------------------------------------------------------------------------
+r419 | rtprince | 2005-03-16 12:12:31 -0700 (Wed, 16 Mar 2005) | 3 lines
+Changed paths:
+ M /trunk/asymptote/coder.cc
+ M /trunk/asymptote/dec.cc
+ M /trunk/asymptote/genv.cc
+ M /trunk/asymptote/inst.cc
+ M /trunk/asymptote/inst.h
+ M /trunk/asymptote/main.cc
+ M /trunk/asymptote/newexp.cc
+ M /trunk/asymptote/record.cc
+ M /trunk/asymptote/record.h
+ M /trunk/asymptote/stack.cc
+ M /trunk/asymptote/stack.h
+ M /trunk/asymptote/stm.cc
+
+A record (and module) is just a function that allows you to access its
+variables after it is done. Implement them this way.
+
+------------------------------------------------------------------------
+r418 | rtprince | 2005-03-16 10:44:40 -0700 (Wed, 16 Mar 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/access.cc
+ M /trunk/asymptote/access.h
+ M /trunk/asymptote/builtin.cc
+
+We don't use opcodes for functions any more, so remove instAccess.
+
+------------------------------------------------------------------------
+r417 | jcbowman | 2005-03-15 22:39:30 -0700 (Tue, 15 Mar 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+
+Documented bool empty(frame).
+
+------------------------------------------------------------------------
+r416 | jcbowman | 2005-03-15 22:26:58 -0700 (Tue, 15 Mar 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/TODO
+ M /trunk/asymptote/arrayop.h
+ M /trunk/asymptote/builtin.cc
+ M /trunk/asymptote/builtin.h
+ M /trunk/asymptote/dec.cc
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/inst.cc
+ M /trunk/asymptote/inst.h
+ M /trunk/asymptote/runtime.cc
+ M /trunk/asymptote/runtime.h
+ M /trunk/asymptote/stack.cc
+
+Changed arithmetic opcodes to functions.
+
+------------------------------------------------------------------------
+r415 | rtprince | 2005-03-15 21:05:15 -0700 (Tue, 15 Mar 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/absyn.h
+ M /trunk/asymptote/stm.cc
+ M /trunk/asymptote/stm.h
+
+We don't treat files specially, so get rid of class.
+
+------------------------------------------------------------------------
+r414 | jcbowman | 2005-03-15 13:54:29 -0700 (Tue, 15 Mar 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/errormsg.h
+ M /trunk/asymptote/stack.cc
+
+Moved interrupt check into main loop.
+
+------------------------------------------------------------------------
+r413 | rtprince | 2005-03-15 11:26:47 -0700 (Tue, 15 Mar 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/symbol.h
+
+The only symbols should be coming from symbol::trans().
+
+------------------------------------------------------------------------
+r412 | rtprince | 2005-03-15 11:25:12 -0700 (Tue, 15 Mar 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/runtime.cc
+
+Use get<>() instead of any_cast<>().
+
+------------------------------------------------------------------------
+r411 | rtprince | 2005-03-15 11:10:03 -0700 (Tue, 15 Mar 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/Compile
+
+Use $(OPTS) instead of $(OPT), which doesn't exsist.
+
+------------------------------------------------------------------------
+r410 | jcbowman | 2005-03-14 21:49:40 -0700 (Mon, 14 Mar 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/configure.ac
+
+Incremented version to 0.71cvs.
+
+------------------------------------------------------------------------
+r409 | jcbowman | 2005-03-14 21:33:12 -0700 (Mon, 14 Mar 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/fpu.h
+
+Added missing #endif.
+
+------------------------------------------------------------------------
+r408 | jcbowman | 2005-03-14 21:32:02 -0700 (Mon, 14 Mar 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/fpu.h
+
+Fixed preprocessor conditionals.
+
+------------------------------------------------------------------------
+r407 | jcbowman | 2005-03-14 21:18:31 -0700 (Mon, 14 Mar 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/fpu.h
+
+Fixed dummy fpu exception support for machines lacking C99 fenv routines.
+
+------------------------------------------------------------------------
+r406 | jcbowman | 2005-03-14 20:48:27 -0700 (Mon, 14 Mar 2005) | 5 lines
+Changed paths:
+ M /trunk/asymptote/Makefile.in
+ M /trunk/asymptote/patches/gv-3.5.8-all.patch
+ A /trunk/asymptote/patches/gv-3.6.1-sigint.patch
+
+Removed reference to deleted xdr files.
+
+Added gv sigint.patch to prevent interactive interrupts from closing the
+gv window.
+
+------------------------------------------------------------------------
+r405 | jcbowman | 2005-03-14 20:46:14 -0700 (Mon, 14 Mar 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/util.h
+
+Added missing prototypes for cxx compiler.
+
+------------------------------------------------------------------------
+r404 | jcbowman | 2005-03-14 20:31:12 -0700 (Mon, 14 Mar 2005) | 11 lines
+Changed paths:
+ M /trunk/asymptote/arrayop.h
+ M /trunk/asymptote/builtin.cc
+ M /trunk/asymptote/builtin.h
+ M /trunk/asymptote/configure.ac
+ M /trunk/asymptote/dec.cc
+ M /trunk/asymptote/doc/asy.1
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/errormsg.cc
+ M /trunk/asymptote/errormsg.h
+ M /trunk/asymptote/fileio.h
+ M /trunk/asymptote/fpu.h
+ M /trunk/asymptote/genv.cc
+ M /trunk/asymptote/interact.cc
+ M /trunk/asymptote/interact.h
+ M /trunk/asymptote/main.cc
+ M /trunk/asymptote/picture.cc
+ M /trunk/asymptote/pipestream.h
+ M /trunk/asymptote/runtime.cc
+ M /trunk/asymptote/runtime.h
+ M /trunk/asymptote/settings.cc
+ M /trunk/asymptote/settings.h
+ M /trunk/asymptote/stack.cc
+ M /trunk/asymptote/util.cc
+ M /trunk/asymptote/util.h
+
+Improved error and interrupt (ctrl-c) handling in interactive mode.
+
+Mask floating point errors by default in interactive mode.
+
+By first issuing an explicit reset command, code can now be entered prior
+to executing an interactive input commands.
+
+Added scroll(int n) and string cd(string) commands.
+
+Added Jn and Yn Bessel functions.
+
+------------------------------------------------------------------------
+r403 | jcbowman | 2005-03-13 21:38:38 -0700 (Sun, 13 Mar 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/math.asy
+
+Fixed bug in extension with a robust (and faster) parametric solver.
+
+------------------------------------------------------------------------
+r402 | jcbowman | 2005-03-12 04:25:01 -0700 (Sat, 12 Mar 2005) | 5 lines
+Changed paths:
+ M /trunk/asymptote/base/plain.asy
+ M /trunk/asymptote/builtin.cc
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/pen.h
+ M /trunk/asymptote/runtime.cc
+ M /trunk/asymptote/runtime.h
+ M /trunk/asymptote/settings.cc
+ M /trunk/asymptote/settings.h
+
+Added -bw option to convert all colors to black and white.
+
+Removed double(file) in favour of single(file,false); also added
+csv(file,false) and linemode(file,false).
+
+------------------------------------------------------------------------
+r401 | jcbowman | 2005-03-12 03:19:52 -0700 (Sat, 12 Mar 2005) | 4 lines
+Changed paths:
+ M /trunk/asymptote/BUGS
+ M /trunk/asymptote/base/palette.asy
+ M /trunk/asymptote/base/pstoedit.asy
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/doc/image.asy
+ D /trunk/asymptote/doc/image.xdr
+ M /trunk/asymptote/patches/pstoedit-3.40asy.patch
+
+Minor change to palette interface.
+
+Replaced image.asy with more compact example to reduce distributed file sizes.
+
+------------------------------------------------------------------------
+r400 | jcbowman | 2005-03-12 01:22:59 -0700 (Sat, 12 Mar 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/patches/pstoedit-3.40asy.patch
+
+Removed textpen argument from image labels.
+
+------------------------------------------------------------------------
+r399 | jcbowman | 2005-03-12 00:57:32 -0700 (Sat, 12 Mar 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/patches/pstoedit-3.40asy.patch
+
+Fixed image support for pstoedit asy backend.
+
+------------------------------------------------------------------------
+r398 | jcbowman | 2005-03-10 18:01:45 -0700 (Thu, 10 Mar 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/graph.asy
+
+Thin crowded logarithmic axis.
+
+------------------------------------------------------------------------
+r397 | jcbowman | 2005-03-10 16:20:02 -0700 (Thu, 10 Mar 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/examples/wedge.asy
+ M /trunk/asymptote/examples/wheelanimation.asy
+
+Updated examples to use XEquals rather than xequals.
+
+------------------------------------------------------------------------
+r396 | jcbowman | 2005-03-10 16:12:52 -0700 (Thu, 10 Mar 2005) | 11 lines
+Changed paths:
+ M /trunk/asymptote/base/graph.asy
+ M /trunk/asymptote/base/palette.asy
+ M /trunk/asymptote/base/plain.asy
+ M /trunk/asymptote/builtin.cc
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/doc/secondaryaxis.asy
+ M /trunk/asymptote/runtime.cc
+ M /trunk/asymptote/runtime.h
+
+
+Generalized secondary axes to handle any scaling (e.g. logarithmic) and
+removed the two bool options (no longer needed).
+
+Improved tick divisor calculation when automin=false and automax=false.
+
+Added and documented file double(file) to complement file single(file)
+for setting the precision of real XDR reads and writes.
+
+Cleaned up automin and automax in scaleT and autoscaleT.
+
+------------------------------------------------------------------------
+r395 | jcbowman | 2005-03-10 07:21:59 -0700 (Thu, 10 Mar 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/Makefile.in
+
+Removed unneeded -I- compilation flag.
+
+------------------------------------------------------------------------
+r394 | jcbowman | 2005-03-09 22:53:24 -0700 (Wed, 09 Mar 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/configure.ac
+
+Incremented version to 0.70cvs.
+
+------------------------------------------------------------------------
+r393 | jcbowman | 2005-03-09 22:34:58 -0700 (Wed, 09 Mar 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/Makefile.in
+
+Install xdr image in examples directory.
+
+------------------------------------------------------------------------
+r392 | jcbowman | 2005-03-09 22:21:56 -0700 (Wed, 09 Mar 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/picture.h
+
+Fixed warning message.
+
+------------------------------------------------------------------------
+r391 | jcbowman | 2005-03-09 21:53:55 -0700 (Wed, 09 Mar 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/image.asy
+
+Fixed font.
+
+------------------------------------------------------------------------
+r390 | jcbowman | 2005-03-09 21:44:32 -0700 (Wed, 09 Mar 2005) | 3 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+
+Recommended use of XEquals and YEquals axes over internal xequals and
+yequals routines.
+
+------------------------------------------------------------------------
+r389 | jcbowman | 2005-03-09 21:20:38 -0700 (Wed, 09 Mar 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/patches/pstoedit-3.40asy.patch
+
+Suppressed misleading warning message.
+
+------------------------------------------------------------------------
+r388 | jcbowman | 2005-03-09 20:47:55 -0700 (Wed, 09 Mar 2005) | 2 lines
+Changed paths:
+ A /trunk/asymptote/examples/equilateral.asy
+
+New example.
+
+------------------------------------------------------------------------
+r387 | jcbowman | 2005-03-09 20:42:55 -0700 (Wed, 09 Mar 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/math.asy
+ M /trunk/asymptote/doc/asymptote.texi
+
+Fixed numerical precision bug in extension (in math.asy, reported by Gao).
+
+------------------------------------------------------------------------
+r386 | jcbowman | 2005-03-09 20:07:45 -0700 (Wed, 09 Mar 2005) | 7 lines
+Changed paths:
+ M /trunk/asymptote/base/graph.asy
+ M /trunk/asymptote/base/palette.asy
+ M /trunk/asymptote/base/plain.asy
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/doc/datagraph.asy
+ M /trunk/asymptote/doc/image.asy
+ A /trunk/asymptote/doc/image.xdr
+
+Fixed secondary axis tick selection;
+Improved tick selection for crowded axis when automin or automax=false.
+Added n-point unit cross routine.
+Added Grayscale and Rainbow palettes.
+Documented color density images, palettes, and mark option to draw routine,
+with examples.
+
+------------------------------------------------------------------------
+r385 | jcbowman | 2005-03-08 22:34:28 -0700 (Tue, 08 Mar 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/palette.asy
+ M /trunk/asymptote/base/plain.asy
+ M /trunk/asymptote/doc/image.asy
+
+Slightly reduce default number of colors to workaround gs pdf limitations.
+
+------------------------------------------------------------------------
+r384 | jcbowman | 2005-03-07 22:56:26 -0700 (Mon, 07 Mar 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/secondaryaxis.asy
+ A /trunk/asymptote/drawimage.h
+
+Added missing file.
+
+------------------------------------------------------------------------
+r383 | jcbowman | 2005-03-07 22:31:44 -0700 (Mon, 07 Mar 2005) | 14 lines
+Changed paths:
+ M /trunk/asymptote/base/graph.asy
+ A /trunk/asymptote/base/palette.asy
+ M /trunk/asymptote/base/plain.asy
+ M /trunk/asymptote/base/pstoedit.asy
+ M /trunk/asymptote/builtin.cc
+ A /trunk/asymptote/doc/image.asy
+ M /trunk/asymptote/doc/secondaryaxis.asy
+ M /trunk/asymptote/drawelement.h
+ M /trunk/asymptote/fileio.h
+ M /trunk/asymptote/pen.h
+ M /trunk/asymptote/picture.h
+ M /trunk/asymptote/psfile.cc
+ M /trunk/asymptote/psfile.h
+ M /trunk/asymptote/runtime.cc
+ M /trunk/asymptote/runtime.h
+ M /trunk/asymptote/types.cc
+ M /trunk/asymptote/types.h
+
+Added support for generating image density plots and palettes.
+
+Added support for data markers, including cross, plus, and polygon markers.
+
+Added min and max functions for 2d and 3d arrays.
+
+Fixed tick divisors in secondary axes.
+
+Deep copy path arrays to avoid suprises.
+
+Fixed limits() in graph.asy.
+
+Respect "#" in format strings (allows trailing zeros).
+
+------------------------------------------------------------------------
+r382 | jcbowman | 2005-03-05 12:16:18 -0700 (Sat, 05 Mar 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/secondaryaxis.asy
+
+More general example of secondary axis.
+
+------------------------------------------------------------------------
+r381 | jcbowman | 2005-03-05 12:14:54 -0700 (Sat, 05 Mar 2005) | 3 lines
+Changed paths:
+ M /trunk/asymptote/base/graph.asy
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/doc/loggraph.asy
+
+Fixed secondary axes bug;
+xlimits, ylimits, and limits now use properly scaled user values.
+
+------------------------------------------------------------------------
+r380 | jcbowman | 2005-02-27 20:51:58 -0700 (Sun, 27 Feb 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/graph.asy
+ M /trunk/asymptote/base/math.asy
+ M /trunk/asymptote/base/plain.asy
+
+Minor optimizations.
+
+------------------------------------------------------------------------
+r379 | jcbowman | 2005-02-27 11:40:32 -0700 (Sun, 27 Feb 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/latexusage.tex
+ M /trunk/asymptote/examples/venn.asy
+
+Adjusted margins so that arrows all have same length.
+
+------------------------------------------------------------------------
+r378 | jcbowman | 2005-02-27 11:23:50 -0700 (Sun, 27 Feb 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/patches/pstoedit-3.40asy.patch
+
+Updates to support Microsoft Windows.
+
+------------------------------------------------------------------------
+r377 | jcbowman | 2005-02-27 09:49:10 -0700 (Sun, 27 Feb 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/plain.asy
+
+Fixed finite(pair).
+
+------------------------------------------------------------------------
+r376 | jcbowman | 2005-02-27 05:29:47 -0700 (Sun, 27 Feb 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/configure.ac
+
+Incremented version to 0.69cvs.
+
+------------------------------------------------------------------------
+r375 | jcbowman | 2005-02-27 04:59:56 -0700 (Sun, 27 Feb 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/plain.asy
+ M /trunk/asymptote/base/simplex.asy
+
+Added Andy's constraint removal code for even better simplex optimization.
+
+------------------------------------------------------------------------
+r374 | jcbowman | 2005-02-26 22:14:35 -0700 (Sat, 26 Feb 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/examples/venn.asy
+
+Updated to use Margin rather than subpath.
+
+------------------------------------------------------------------------
+r373 | jcbowman | 2005-02-26 22:00:33 -0700 (Sat, 26 Feb 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/configure.ac
+
+Incremented version to 0.68cvs.
+
+------------------------------------------------------------------------
+r372 | jcbowman | 2005-02-26 19:48:49 -0700 (Sat, 26 Feb 2005) | 9 lines
+Changed paths:
+ M /trunk/asymptote/base/plain.asy
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/drawlabel.cc
+ A /trunk/asymptote/patches/gv-3.6.1-getopt.patch
+ A /trunk/asymptote/patches/gv-3.6.1-gs8.patch
+ A /trunk/asymptote/patches/gv-3.6.1-landscape.patch
+ M /trunk/asymptote/patches/pstoedit-3.40asy.patch
+ M /trunk/asymptote/pen.h
+
+Initialize font explicitly to ensure compatibility between tex pipe and
+final latex processing and to ensure tex pipe font is properly reinitialized.
+
+If picture cannot be fit to requested size, scale size by sqrt(2) and retry.
+
+Added gv-3.6.1 patches; updated documentation.
+
+Modified pstoedit patch to remove unneeded shipout().
+
+------------------------------------------------------------------------
+r371 | jcbowman | 2005-02-26 14:55:50 -0700 (Sat, 26 Feb 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/feynman.asy
+ M /trunk/asymptote/examples/eetomumu.asy
+
+arrowsize updates
+
+------------------------------------------------------------------------
+r370 | jcbowman | 2005-02-26 01:23:43 -0700 (Sat, 26 Feb 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/simplex.asy
+
+Removed superflous constraints before solving linear programming problem.
+
+------------------------------------------------------------------------
+r369 | jcbowman | 2005-02-25 22:51:35 -0700 (Fri, 25 Feb 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/simplex.asy
+
+Check that r.c >= 0 in selectVar (this guarantees that r.t[col] < 0).
+
+------------------------------------------------------------------------
+r368 | jcbowman | 2005-02-25 20:31:21 -0700 (Fri, 25 Feb 2005) | 6 lines
+Changed paths:
+ M /trunk/asymptote/base/graph.asy
+ M /trunk/asymptote/base/plain.asy
+ M /trunk/asymptote/base/simplex.asy
+ M /trunk/asymptote/doc/asymptote.texi
+
+Optimized simplex pivoting.
+
+Made global constants static.
+
+Fixed recently introduced error in relative(picture, pair).
+
+------------------------------------------------------------------------
+r367 | jcbowman | 2005-02-25 11:11:52 -0700 (Fri, 25 Feb 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/graph.asy
+ M /trunk/asymptote/doc/asymptote.texi
+
+Minor errorbar updates.
+
+------------------------------------------------------------------------
+r366 | jcbowman | 2005-02-25 11:11:20 -0700 (Fri, 25 Feb 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/feynman.asy
+
+arrowsize updates
+
+------------------------------------------------------------------------
+r365 | jcbowman | 2005-02-21 23:41:54 -0700 (Mon, 21 Feb 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/configure.ac
+
+Incremented version to 0.67cvs.
+
+------------------------------------------------------------------------
+r364 | jcbowman | 2005-02-21 22:41:21 -0700 (Mon, 21 Feb 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/picture.cc
+ M /trunk/asymptote/xasy
+
+Improved selection highlighting in GUI.
+
+------------------------------------------------------------------------
+r363 | jcbowman | 2005-02-20 23:12:23 -0700 (Sun, 20 Feb 2005) | 3 lines
+Changed paths:
+ M /trunk/asymptote/pen.h
+ M /trunk/asymptote/runtime.cc
+
+Put quotes around outputted font command string.
+Set camp::TeXcontaminated to false upon decontaminating.
+
+------------------------------------------------------------------------
+r362 | jcbowman | 2005-02-20 21:57:04 -0700 (Sun, 20 Feb 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/main.cc
+ M /trunk/asymptote/runtime.cc
+
+Moved interactive rejectline code back into main.cc.
+
+------------------------------------------------------------------------
+r361 | jcbowman | 2005-02-20 21:16:09 -0700 (Sun, 20 Feb 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/drawlabel.cc
+ M /trunk/asymptote/main.cc
+ M /trunk/asymptote/picture.cc
+ M /trunk/asymptote/picture.h
+ M /trunk/asymptote/runtime.cc
+
+Moved cleanup functions into exitFunction.
+
+------------------------------------------------------------------------
+r360 | jcbowman | 2005-02-20 20:41:20 -0700 (Sun, 20 Feb 2005) | 10 lines
+Changed paths:
+ M /trunk/asymptote/TODO
+ M /trunk/asymptote/base/graph.asy
+ M /trunk/asymptote/base/plain.asy
+ M /trunk/asymptote/builtin.cc
+ M /trunk/asymptote/builtin.h
+ M /trunk/asymptote/doc/asymptote.sty
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/doc/bezier.asy
+ M /trunk/asymptote/doc/bigsquare.asy
+ M /trunk/asymptote/doc/cube.asy
+ M /trunk/asymptote/doc/datagraph.asy
+ M /trunk/asymptote/doc/diagonal.asy
+ M /trunk/asymptote/doc/diatom.asy
+ M /trunk/asymptote/doc/exp.asy
+ M /trunk/asymptote/doc/generalaxis.asy
+ M /trunk/asymptote/doc/hatch.asy
+ M /trunk/asymptote/doc/labelsquare.asy
+ M /trunk/asymptote/doc/latexusage.tex
+ M /trunk/asymptote/doc/lineargraph.asy
+ M /trunk/asymptote/doc/linetype.asy
+ M /trunk/asymptote/doc/loggraph.asy
+ M /trunk/asymptote/doc/logo.asy
+ M /trunk/asymptote/doc/mosquito.asy
+ M /trunk/asymptote/doc/parametricgraph.asy
+ M /trunk/asymptote/doc/quartercircle.asy
+ M /trunk/asymptote/doc/secondaryaxis.asy
+ M /trunk/asymptote/doc/shade.asy
+ M /trunk/asymptote/doc/shadedtiling.asy
+ M /trunk/asymptote/doc/square.asy
+ M /trunk/asymptote/doc/superpath.asy
+ M /trunk/asymptote/doc/tile.asy
+ M /trunk/asymptote/doc/westnile.asy
+ M /trunk/asymptote/examples/Pythagoras.asy
+ M /trunk/asymptote/examples/cardiod.asy
+ M /trunk/asymptote/examples/centroidfg.asy
+ M /trunk/asymptote/examples/circles.asy
+ M /trunk/asymptote/examples/conicurv.asy
+ M /trunk/asymptote/examples/cos2theta.asy
+ M /trunk/asymptote/examples/cosaddition.asy
+ M /trunk/asymptote/examples/delu.asy
+ M /trunk/asymptote/examples/dragon.asy
+ M /trunk/asymptote/examples/eetomumu.asy
+ M /trunk/asymptote/examples/equilchord.asy
+ M /trunk/asymptote/examples/fano.asy
+ M /trunk/asymptote/examples/fermi.asy
+ M /trunk/asymptote/examples/fjortoft.asy
+ M /trunk/asymptote/examples/geometry.asy
+ M /trunk/asymptote/examples/grid.asy
+ M /trunk/asymptote/examples/integraltest.asy
+ M /trunk/asymptote/examples/labelbox.asy
+ M /trunk/asymptote/examples/lever.asy
+ M /trunk/asymptote/examples/log.asy
+ M /trunk/asymptote/examples/near_earth.asy
+ M /trunk/asymptote/examples/phase.asy
+ M /trunk/asymptote/examples/planes.asy
+ M /trunk/asymptote/examples/polararea.asy
+ M /trunk/asymptote/examples/polarcircle.asy
+ M /trunk/asymptote/examples/progrid.asy
+ M /trunk/asymptote/examples/ring.asy
+ M /trunk/asymptote/examples/sacone.asy
+ M /trunk/asymptote/examples/sin1x.asy
+ M /trunk/asymptote/examples/sinxlex.asy
+ M /trunk/asymptote/examples/spring0.asy
+ M /trunk/asymptote/examples/spring2.asy
+ M /trunk/asymptote/examples/tanh.asy
+ M /trunk/asymptote/examples/treetest.asy
+ M /trunk/asymptote/examples/unitcircle.asy
+ M /trunk/asymptote/examples/upint.asy
+ M /trunk/asymptote/examples/wedge.asy
+ M /trunk/asymptote/examples/xsin1x.asy
+ M /trunk/asymptote/genv.cc
+ M /trunk/asymptote/interact.cc
+ M /trunk/asymptote/picture.cc
+ M /trunk/asymptote/runtime.cc
+ M /trunk/asymptote/runtime.h
+ M /trunk/asymptote/settings.cc
+ M /trunk/asymptote/settings.h
+
+Added atexit function.
+
+A shipout() command is added implicitly at file exit if no previous shipout
+commands have been executed. The examples were updated to remove any
+unnecessary shipout() calls.
+
+Used atexit to clean up asymptote.sty and interactive mode.
+
+Files with no drawing commands now work with -f pdf.
+
+------------------------------------------------------------------------
+r359 | jcbowman | 2005-02-20 02:07:38 -0700 (Sun, 20 Feb 2005) | 3 lines
+Changed paths:
+ M /trunk/asymptote/base/graph.asy
+ M /trunk/asymptote/base/plain.asy
+
+Fixed (logarithmic and other) scalings of XEquals and YEquals axes and
+errorbars.
+
+------------------------------------------------------------------------
+r358 | jcbowman | 2005-02-20 01:28:25 -0700 (Sun, 20 Feb 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+
+Fixed typo.
+
+------------------------------------------------------------------------
+r357 | jcbowman | 2005-02-20 01:25:04 -0700 (Sun, 20 Feb 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/configure.ac
+
+Incremented version to 0.66cvs.
+
+------------------------------------------------------------------------
+r356 | jcbowman | 2005-02-20 00:47:46 -0700 (Sun, 20 Feb 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/Makefile.in
+ M /trunk/asymptote/doc/asymptote.texi
+
+Fixed location of latexusage.tex.
+
+------------------------------------------------------------------------
+r355 | jcbowman | 2005-02-20 00:39:25 -0700 (Sun, 20 Feb 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/configure.ac
+
+Incremented version to 0.65cvs.
+
+------------------------------------------------------------------------
+r354 | jcbowman | 2005-02-19 23:28:21 -0700 (Sat, 19 Feb 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/examples/treetest.asy
+
+Fixed typos in example.
+
+------------------------------------------------------------------------
+r353 | jcbowman | 2005-02-19 23:19:39 -0700 (Sat, 19 Feb 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/feynman.asy
+ M /trunk/asymptote/base/plain.asy
+ M /trunk/asymptote/doc/mosquito.asy
+ M /trunk/asymptote/doc/westnile.asy
+
+Updated examples.
+
+------------------------------------------------------------------------
+r352 | jcbowman | 2005-02-19 23:00:14 -0700 (Sat, 19 Feb 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/examples/eetomumu.asy
+
+Linewidth change.
+
+------------------------------------------------------------------------
+r351 | jcbowman | 2005-02-19 22:57:01 -0700 (Sat, 19 Feb 2005) | 3 lines
+Changed paths:
+ M /trunk/asymptote/base/graph.asy
+ M /trunk/asymptote/base/plain.asy
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/doc/datagraph.asy
+ M /trunk/asymptote/examples/cosaddition.asy
+ M /trunk/asymptote/examples/delu.asy
+ M /trunk/asymptote/examples/equilchord.asy
+ M /trunk/asymptote/examples/fjortoft.asy
+ M /trunk/asymptote/examples/geometry.asy
+ M /trunk/asymptote/examples/lever.asy
+ M /trunk/asymptote/examples/near_earth.asy
+ M /trunk/asymptote/examples/polararea.asy
+ M /trunk/asymptote/examples/polarcircle.asy
+ M /trunk/asymptote/examples/sacone.asy
+ M /trunk/asymptote/examples/sinxlex.asy
+ M /trunk/asymptote/examples/unitcircle.asy
+
+Added DotMargin margin qualifier.
+Updated examples to use margins.
+
+------------------------------------------------------------------------
+r350 | jcbowman | 2005-02-19 21:40:42 -0700 (Sat, 19 Feb 2005) | 7 lines
+Changed paths:
+ M /trunk/asymptote/base/feynman.asy
+ M /trunk/asymptote/base/graph.asy
+ M /trunk/asymptote/base/math.asy
+ M /trunk/asymptote/base/plain.asy
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/doc/datagraph.asy
+ M /trunk/asymptote/examples/Pythagoras.asy
+ M /trunk/asymptote/examples/polararea.asy
+ M /trunk/asymptote/examples/spring.asy
+ M /trunk/asymptote/examples/triads.asy
+
+Added errorbar routines to graph.asy.
+
+Changed arrowhead and dimension bar default size specifiers:
+arrowsize to arrowsize(pen p=currentpen),
+arcarrowsize to arcarrowsize(pen p=currentpen),
+barsize to barsize(pen p=currentpen).
+
+------------------------------------------------------------------------
+r349 | jcbowman | 2005-02-19 18:29:46 -0700 (Sat, 19 Feb 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/runtime.cc
+
+Fixed bug in eval(f(T), T[] A).
+
+------------------------------------------------------------------------
+r348 | jcbowman | 2005-02-19 11:35:38 -0700 (Sat, 19 Feb 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+
+Documented real[] A vs. real A[] issue.
+
+------------------------------------------------------------------------
+r347 | jcbowman | 2005-02-19 10:50:51 -0700 (Sat, 19 Feb 2005) | 4 lines
+Changed paths:
+ M /trunk/asymptote/base/plain.asy
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/doc/latexusage.tex
+ M /trunk/asymptote/examples/sqrtx01.asy
+
+Documented and improved margin routines.
+
+Included correct latexusage file in documentation.
+
+------------------------------------------------------------------------
+r346 | jcbowman | 2005-02-18 23:32:16 -0700 (Fri, 18 Feb 2005) | 6 lines
+Changed paths:
+ M /trunk/asymptote/Makefile.in
+ M /trunk/asymptote/base/feynman.asy
+ M /trunk/asymptote/base/plain.asy
+ M /trunk/asymptote/doc/asymptote.sty
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/doc/latexusage.tex
+ M /trunk/asymptote/examples/Pythagoras.asy
+ M /trunk/asymptote/examples/sqrtx01.asy
+
+Added Margin, PenMargin, and TrueMargin drawing qualifiers.
+
+Fixed name conflicts between asymptote.sty and comment.sty.
+
+Install latexusage.tex with examples.
+
+------------------------------------------------------------------------
+r345 | jcbowman | 2005-02-18 15:07:55 -0700 (Fri, 18 Feb 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/exp.cc
+
+Fix diagnostic.
+
+------------------------------------------------------------------------
+r344 | jcbowman | 2005-02-18 14:13:16 -0700 (Fri, 18 Feb 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/exp.cc
+
+Fixed segmentation fault in anonymous function diagnostic.
+
+------------------------------------------------------------------------
+r343 | jcbowman | 2005-02-18 02:32:37 -0700 (Fri, 18 Feb 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/configure.ac
+
+Incremented version to 0.64cvs.
+
+------------------------------------------------------------------------
+r342 | jcbowman | 2005-02-18 01:54:40 -0700 (Fri, 18 Feb 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/picture.cc
+
+Reset lastpen on every call to texinit.
+
+------------------------------------------------------------------------
+r341 | jcbowman | 2005-02-18 01:32:44 -0700 (Fri, 18 Feb 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/configure.ac
+
+Fixed harmless typo.
+
+------------------------------------------------------------------------
+r340 | jcbowman | 2005-02-18 01:28:13 -0700 (Fri, 18 Feb 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/configure.ac
+
+Incremented version to 0.63cvs.
+
+------------------------------------------------------------------------
+r339 | jcbowman | 2005-02-18 00:27:57 -0700 (Fri, 18 Feb 2005) | 3 lines
+Changed paths:
+ M /trunk/asymptote/pen.h
+ M /trunk/asymptote/psfile.h
+
+Fixed shading colorspace & fillrule/baseline output strings;
+removed unwanted space from gsave/grestore.
+
+------------------------------------------------------------------------
+r338 | jcbowman | 2005-02-17 23:38:20 -0700 (Thu, 17 Feb 2005) | 6 lines
+Changed paths:
+ M /trunk/asymptote/base/plain.asy
+ M /trunk/asymptote/base/pstoedit.asy
+ M /trunk/asymptote/builtin.cc
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/doc/labelsquare.asy
+ M /trunk/asymptote/doc/latexusage.tex
+ M /trunk/asymptote/drawlabel.cc
+ M /trunk/asymptote/drawlabel.h
+ M /trunk/asymptote/examples/geometry.asy
+ M /trunk/asymptote/examples/sqrtx01.asy
+ M /trunk/asymptote/pen.h
+ M /trunk/asymptote/runtime.cc
+ M /trunk/asymptote/runtime.h
+
+Added basealign pen type to align labels using the TeX baseline, if
+applicable, rather than using the full bounding box. (The default continues
+to be nobasealign).
+
+Documentation improved in several areas.
+
+------------------------------------------------------------------------
+r337 | jcbowman | 2005-02-17 07:57:51 -0700 (Thu, 17 Feb 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/util.h
+
+Added missing include.
+
+------------------------------------------------------------------------
+r336 | jcbowman | 2005-02-17 00:02:35 -0700 (Thu, 17 Feb 2005) | 2 lines
+Changed paths:
+ A /trunk/asymptote/doc/labelsquare.asy
+
+Simple example of label positioning.
+
+------------------------------------------------------------------------
+r335 | jcbowman | 2005-02-16 23:56:21 -0700 (Wed, 16 Feb 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+
+Corrected index entry.
+
+------------------------------------------------------------------------
+r334 | jcbowman | 2005-02-16 23:54:19 -0700 (Wed, 16 Feb 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/util.h
+
+Workaround broken cxx linux-alpha headers.
+
+------------------------------------------------------------------------
+r333 | jcbowman | 2005-02-16 23:38:29 -0700 (Wed, 16 Feb 2005) | 11 lines
+Changed paths:
+ M /trunk/asymptote/README
+ M /trunk/asymptote/base/plain.asy
+ M /trunk/asymptote/builtin.cc
+ M /trunk/asymptote/camp.l
+ M /trunk/asymptote/configure.ac
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/doc/bigsquare.asy
+ M /trunk/asymptote/examples/geometry.asy
+ A /trunk/asymptote/examples/sflogo.eps
+ M /trunk/asymptote/patches/pstoedit-3.40asy.patch
+ M /trunk/asymptote/pipestream.h
+ M /trunk/asymptote/runtime.cc
+ M /trunk/asymptote/runtime.h
+ M /trunk/asymptote/texfile.cc
+ M /trunk/asymptote/texfile.h
+ M /trunk/asymptote/util.h
+
+EPS files (and other formats supported by \includegraphics) can now be
+included and positioned just like any other LaTeX label (the include
+function has been changed to return a string containing an includegraphics
+command that can be used with label).
+
+Added image support to pstoedit backend.
+
+Fixed compilation problems under Solaris.
+
+Updated documentation.
+
+------------------------------------------------------------------------
+r332 | rtprince | 2005-02-16 10:43:22 -0700 (Wed, 16 Feb 2005) | 4 lines
+Changed paths:
+ M /trunk/asymptote/Makefile.in
+ M /trunk/asymptote/configure.ac
+
+CFLAGS is already subst'd by AC_PROG_CC.
+CXX defaults to g++ if it is available (AC_PROG_CXX).
+Define CC in Makefile if we get it from AC_PROG_CC.
+
+------------------------------------------------------------------------
+r331 | jcbowman | 2005-02-16 10:42:33 -0700 (Wed, 16 Feb 2005) | 3 lines
+Changed paths:
+ M /trunk/asymptote/absyn.cc
+ M /trunk/asymptote/absyn.h
+ M /trunk/asymptote/camp.l
+ M /trunk/asymptote/camp.y
+ M /trunk/asymptote/dec.cc
+ M /trunk/asymptote/dec.h
+ M /trunk/asymptote/exp.cc
+ M /trunk/asymptote/exp.h
+ M /trunk/asymptote/genv.cc
+ M /trunk/asymptote/genv.h
+ M /trunk/asymptote/main.cc
+ M /trunk/asymptote/name.cc
+ M /trunk/asymptote/name.h
+ M /trunk/asymptote/newexp.cc
+ M /trunk/asymptote/newexp.h
+ M /trunk/asymptote/stm.cc
+ M /trunk/asymptote/stm.h
+ M /trunk/asymptote/types.cc
+ M /trunk/asymptote/types.h
+
+Changed namespace absyn to absyntax to avoid conflicts with class of same
+name under some compilers.
+
+------------------------------------------------------------------------
+r330 | jcbowman | 2005-02-16 10:24:02 -0700 (Wed, 16 Feb 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/camp.l
+
+Namespace as -> absyn.
+
+------------------------------------------------------------------------
+r329 | jcbowman | 2005-02-16 10:18:44 -0700 (Wed, 16 Feb 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/camp.y
+
+Namespace as -> absyn.
+
+------------------------------------------------------------------------
+r328 | jcbowman | 2005-02-16 10:14:02 -0700 (Wed, 16 Feb 2005) | 3 lines
+Changed paths:
+ M /trunk/asymptote/absyn.cc
+ M /trunk/asymptote/absyn.h
+ M /trunk/asymptote/configure.ac
+ M /trunk/asymptote/dec.cc
+ M /trunk/asymptote/dec.h
+ M /trunk/asymptote/exp.cc
+ M /trunk/asymptote/exp.h
+ M /trunk/asymptote/genv.cc
+ M /trunk/asymptote/genv.h
+ M /trunk/asymptote/main.cc
+ M /trunk/asymptote/name.cc
+ M /trunk/asymptote/name.h
+ M /trunk/asymptote/newexp.cc
+ M /trunk/asymptote/newexp.h
+ M /trunk/asymptote/stm.cc
+ M /trunk/asymptote/stm.h
+ M /trunk/asymptote/types.cc
+ M /trunk/asymptote/types.h
+
+Renamed namespace "as" to "absyn" to work around Solaris namespace pollution.
+Added CXX=g++ to configure.ac and removed -DNDEBUG flag.
+
+------------------------------------------------------------------------
+r327 | jcbowman | 2005-02-15 21:23:14 -0700 (Tue, 15 Feb 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/picture.cc
+
+Clip should insert beginclip at beginning of current layer.
+
+------------------------------------------------------------------------
+r326 | jcbowman | 2005-02-15 16:46:32 -0700 (Tue, 15 Feb 2005) | 8 lines
+Changed paths:
+ M /trunk/asymptote/base/plain.asy
+ A /trunk/asymptote/base/pstoedit.asy
+ M /trunk/asymptote/builtin.cc
+ M /trunk/asymptote/patches/pstoedit-3.40asy.patch
+ M /trunk/asymptote/runtime.cc
+
+Reinstated underlying frame clipping for picture clipping (with transform
+bug fix), allowing picture unfill to be properly implemented (using frame
+unfill).
+
+Moved beginclip, endclip, gsave, and grestore to pstoedit.asy.
+
+Fixed remaining gsave/grestore bugs in Asymptote backend to pstoedit.
+
+------------------------------------------------------------------------
+r325 | jcbowman | 2005-02-15 01:01:03 -0700 (Tue, 15 Feb 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/plain.asy
+
+Code clean up; added pair min(path[]) and max(path[]) functions.
+
+------------------------------------------------------------------------
+r324 | jcbowman | 2005-02-14 22:25:28 -0700 (Mon, 14 Feb 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/configure.ac
+
+Incremented version to 0.62cvs.
+
+------------------------------------------------------------------------
+r323 | jcbowman | 2005-02-14 20:39:00 -0700 (Mon, 14 Feb 2005) | 2 lines
+Changed paths:
+ A /trunk/asymptote/doc/cube.asy
+ A /trunk/asymptote/doc/superpath.asy
+
+New examples.
+
+------------------------------------------------------------------------
+r322 | jcbowman | 2005-02-14 19:57:01 -0700 (Mon, 14 Feb 2005) | 2 lines
+Changed paths:
+ A /trunk/asymptote/drawgrestore.h
+ A /trunk/asymptote/drawgsave.h
+
+Added PostScript grestore/gsave objects.
+
+------------------------------------------------------------------------
+r321 | jcbowman | 2005-02-14 19:54:11 -0700 (Mon, 14 Feb 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+
+Fixed spelling and grammar.
+
+------------------------------------------------------------------------
+r320 | jcbowman | 2005-02-14 18:01:27 -0700 (Mon, 14 Feb 2005) | 5 lines
+Changed paths:
+ M /trunk/asymptote/base/asy.vim
+ M /trunk/asymptote/base/plain.asy
+ M /trunk/asymptote/builtin.cc
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/drawclipbegin.h
+ M /trunk/asymptote/drawclipend.h
+ M /trunk/asymptote/drawlabel.cc
+ M /trunk/asymptote/drawlabel.h
+ A /trunk/asymptote/patches/pstoedit-3.40asy.patch
+ M /trunk/asymptote/runtime.cc
+ M /trunk/asymptote/runtime.h
+
+Added Asymptote backend and support for pstoedit, including native
+clipping and subpaths.
+
+Added Postscript font and scaled TeX font support.
+
+------------------------------------------------------------------------
+r319 | jcbowman | 2005-02-13 14:57:10 -0700 (Sun, 13 Feb 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/plain.asy
+ M /trunk/asymptote/doc/asymptote.texi
+
+Added warning message and documentation about clipping deconstructed objects.
+
+------------------------------------------------------------------------
+r318 | jcbowman | 2005-02-13 14:36:46 -0700 (Sun, 13 Feb 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/asy.1
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/pen.h
+ M /trunk/asymptote/settings.cc
+ M /trunk/asymptote/settings.h
+
+Added -gray option.
+
+------------------------------------------------------------------------
+r317 | jcbowman | 2005-02-13 11:21:41 -0700 (Sun, 13 Feb 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/Makefile.in
+ M /trunk/asymptote/doc/asymptote.texi
+
+Install documentation examples and data files in examples directory.
+
+------------------------------------------------------------------------
+r316 | jcbowman | 2005-02-13 11:08:12 -0700 (Sun, 13 Feb 2005) | 7 lines
+Changed paths:
+ M /trunk/asymptote/Makefile.in
+ M /trunk/asymptote/base/graph.asy
+ M /trunk/asymptote/base/plain.asy
+ M /trunk/asymptote/builtin.cc
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/drawclipbegin.h
+ M /trunk/asymptote/drawclipend.h
+ M /trunk/asymptote/drawelement.h
+ M /trunk/asymptote/drawlabel.cc
+ A /trunk/asymptote/examples/labelbox.asy
+ M /trunk/asymptote/examples/ring.asy
+ M /trunk/asymptote/examples/yingyang.asy
+ M /trunk/asymptote/picture.cc
+ M /trunk/asymptote/psfile.h
+ M /trunk/asymptote/runtime.cc
+ M /trunk/asymptote/runtime.h
+
+Reimplemented picture clipping to fix transformation and layering of
+clipped pictures.
+
+Use correct font and fontsize for computing label bounding boxes.
+
+Use -O0 for producing dependency data.
+
+------------------------------------------------------------------------
+r315 | jcbowman | 2005-02-12 02:26:46 -0700 (Sat, 12 Feb 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/featpost3D.asy
+
+Added background variable.
+
+------------------------------------------------------------------------
+r314 | jcbowman | 2005-02-12 02:21:42 -0700 (Sat, 12 Feb 2005) | 20 lines
+Changed paths:
+ M /trunk/asymptote/README
+ A /trunk/asymptote/base/drawtree.asy
+ M /trunk/asymptote/base/graph3d.asy
+ M /trunk/asymptote/base/metapost.asy
+ M /trunk/asymptote/base/patterns.asy
+ M /trunk/asymptote/base/plain.asy
+ M /trunk/asymptote/builtin.cc
+ M /trunk/asymptote/camp.l
+ M /trunk/asymptote/camp.y
+ M /trunk/asymptote/doc/Makefile
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/doc/shadedtiling.asy
+ M /trunk/asymptote/doc/tile.asy
+ M /trunk/asymptote/drawclipbegin.h
+ M /trunk/asymptote/drawclipend.h
+ M /trunk/asymptote/drawelement.h
+ M /trunk/asymptote/drawfill.cc
+ M /trunk/asymptote/drawfill.h
+ M /trunk/asymptote/drawlabel.cc
+ M /trunk/asymptote/drawlabel.h
+ M /trunk/asymptote/drawpath.cc
+ A /trunk/asymptote/examples/ring.asy
+ A /trunk/asymptote/examples/treetest.asy
+ M /trunk/asymptote/pen.h
+ M /trunk/asymptote/psfile.cc
+ M /trunk/asymptote/psfile.h
+ M /trunk/asymptote/runtime.cc
+ M /trunk/asymptote/runtime.h
+ M /trunk/asymptote/settings.cc
+ M /trunk/asymptote/texfile.cc
+ M /trunk/asymptote/types.cc
+ M /trunk/asymptote/types.h
+
+Added drawing, filling, and clipping of compound paths built up with a pen
+lift (moveto) operator ^^ instead of --.
+
+Added functions to unfill a region to transparent background.
+
+Added zerowinding and evenodd pen types for filling and clipping.
+
+Introduced pen types squarecap, roundcap, extendcap, miterjoin,
+roundjoin, beveljoin to replace linecap(Square) calls, etc.
+
+Added checker pattern.
+
+Added LaTeX NFSS and TeX fonts and ability to override default baselineskip.
+
+Fixed bug in LaTeX rotation angle output format.
+
+Added contributed tree drawing script and example.
+
+Updated documentation.
+
+------------------------------------------------------------------------
+r313 | jcbowman | 2005-02-09 08:08:27 -0700 (Wed, 09 Feb 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/asy-mode.el
+ M /trunk/asymptote/base/asy.vim
+
+Editing mode updates.
+
+------------------------------------------------------------------------
+r312 | jcbowman | 2005-02-09 07:40:20 -0700 (Wed, 09 Feb 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/plain.asy
+ M /trunk/asymptote/doc/Makefile
+
+Renamed labelframe to labelBox; added labelbox(frame).
+
+------------------------------------------------------------------------
+r311 | jcbowman | 2005-02-08 22:46:20 -0700 (Tue, 08 Feb 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/plain.asy
+
+added labelframe and point(frame,dir) routines.
+
+------------------------------------------------------------------------
+r310 | hammera | 2005-02-08 14:45:32 -0700 (Tue, 08 Feb 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/asy.vim
+
+Changed string highlighting to recognize double \ escapes.
+
+------------------------------------------------------------------------
+r309 | jcbowman | 2005-02-05 14:43:28 -0700 (Sat, 05 Feb 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/Makefile.in
+ M /trunk/asymptote/base/feynman.asy
+ M /trunk/asymptote/base/patterns.asy
+ M /trunk/asymptote/base/plain.asy
+ M /trunk/asymptote/configure.ac
+ M /trunk/asymptote/doc/Makefile
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/doc/bigsquare.asy
+ M /trunk/asymptote/doc/hatch.asy
+ M /trunk/asymptote/doc/quartercircle.asy
+ M /trunk/asymptote/doc/tile.asy
+
+Updated documentation and pattern examples.
+
+------------------------------------------------------------------------
+r308 | jcbowman | 2005-02-04 21:49:13 -0700 (Fri, 04 Feb 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/patterns.asy
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/doc/hatch.asy
+
+Added brick pattern.
+
+------------------------------------------------------------------------
+r307 | jcbowman | 2005-02-04 15:15:16 -0700 (Fri, 04 Feb 2005) | 9 lines
+Changed paths:
+ M /trunk/asymptote/base/feynman.asy
+ A /trunk/asymptote/base/patterns.asy
+ M /trunk/asymptote/base/plain.asy
+ M /trunk/asymptote/builtin.cc
+ M /trunk/asymptote/doc/asy.1
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/doc/hatch.asy
+ M /trunk/asymptote/doc/shadedtiling.asy
+ A /trunk/asymptote/doc/tile.asy
+ M /trunk/asymptote/drawpath.cc
+ M /trunk/asymptote/pen.h
+ M /trunk/asymptote/runtime.cc
+ M /trunk/asymptote/settings.cc
+
+Added bool option to linetype to disable automatic scaling of linetype
+parameters with pen size. Fixed segmentation fault and float point
+exception in adjust_dash in drawpath.cc.
+
+Added bbox(Background) option for producing a nontransparent background.
+
+Moved simplified pattern routines and builtin patterns hatch, crosshatch,
+and tile to patterns.asy. Updated examples and documentation.
+
+------------------------------------------------------------------------
+r306 | jcbowman | 2005-02-03 20:05:37 -0700 (Thu, 03 Feb 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/interact.cc
+ M /trunk/asymptote/interact.h
+
+Fixed recently broken interact mode.
+
+------------------------------------------------------------------------
+r305 | jcbowman | 2005-02-03 12:18:20 -0700 (Thu, 03 Feb 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/Makefile.in
+ M /trunk/asymptote/configure.ac
+
+Moved default CFLAGS into configure.ac
+
+------------------------------------------------------------------------
+r304 | jcbowman | 2005-02-02 12:16:31 -0700 (Wed, 02 Feb 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/Makefile.in
+
+Fixed optimization flags (revert last change).
+
+------------------------------------------------------------------------
+r303 | rtprince | 2005-02-02 07:40:53 -0700 (Wed, 02 Feb 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/Makefile.in
+
+Stanardize CFLAGS handling.
+
+------------------------------------------------------------------------
+r302 | jcbowman | 2005-02-02 05:16:25 -0700 (Wed, 02 Feb 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/interact.cc
+ M /trunk/asymptote/interact.h
+
+Fixed header problems under FreeBSD.
+
+------------------------------------------------------------------------
+r301 | jcbowman | 2005-02-01 23:54:33 -0700 (Tue, 01 Feb 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/configure.ac
+
+Incremented version to 0.61cvs.
+
+------------------------------------------------------------------------
+r300 | jcbowman | 2005-02-01 23:10:58 -0700 (Tue, 01 Feb 2005) | 2 lines
+Changed paths:
+ A /trunk/asymptote/examples/grid.asy
+ M /trunk/asymptote/picture.cc
+
+Interactive mode automatically restarts ASYMPTOTE_PSVIEWER in case it exited.
+
+------------------------------------------------------------------------
+r299 | jcbowman | 2005-02-01 23:07:24 -0700 (Tue, 01 Feb 2005) | 3 lines
+Changed paths:
+ M /trunk/asymptote/base/math.asy
+
+Added picture grid(int Nx, int Ny, pen p=currentpen) function for
+generating square lattices.
+
+------------------------------------------------------------------------
+r298 | jcbowman | 2005-02-01 23:04:57 -0700 (Tue, 01 Feb 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+
+Simplified binary installation instructions; updated hatch.asy listing.
+
+------------------------------------------------------------------------
+r297 | rtprince | 2005-02-01 09:03:21 -0700 (Tue, 01 Feb 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/knotlist.cc
+
+Fix path solving. Strange place for a bug.
+
+------------------------------------------------------------------------
+r296 | jcbowman | 2005-02-01 01:52:50 -0700 (Tue, 01 Feb 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/path.cc
+
+Removed extra newline from diagnostic.
+
+------------------------------------------------------------------------
+r295 | jcbowman | 2005-02-01 00:43:33 -0700 (Tue, 01 Feb 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/builtin.cc
+ M /trunk/asymptote/runtime.cc
+ M /trunk/asymptote/runtime.h
+
+Fixed namespace/function conflicts.
+
+------------------------------------------------------------------------
+r294 | jcbowman | 2005-02-01 00:33:26 -0700 (Tue, 01 Feb 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/arrayop.h
+ M /trunk/asymptote/builtin.cc
+ M /trunk/asymptote/fileio.h
+ M /trunk/asymptote/interact.cc
+ M /trunk/asymptote/runtime.cc
+ M /trunk/asymptote/runtime.h
+ M /trunk/asymptote/settings.cc
+ M /trunk/asymptote/settings.h
+
+Fixed interactive mode to suppress standard I/O also from static imports.
+
+------------------------------------------------------------------------
+r293 | jcbowman | 2005-01-31 20:41:57 -0700 (Mon, 31 Jan 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/runtime.cc
+
+Fix rfind(string s, string t) and update documentation of string functions.
+
+------------------------------------------------------------------------
+r292 | jcbowman | 2005-01-31 17:42:04 -0700 (Mon, 31 Jan 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/plain.asy
+ M /trunk/asymptote/builtin.cc
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/fileio.h
+ M /trunk/asymptote/runtime.cc
+
+Add facility for checking to see if a file exists, using bool error(file).
+
+------------------------------------------------------------------------
+r291 | jcbowman | 2005-01-31 15:15:48 -0700 (Mon, 31 Jan 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/plain.asy
+ M /trunk/asymptote/builtin.cc
+ M /trunk/asymptote/interact.cc
+ M /trunk/asymptote/picture.cc
+ M /trunk/asymptote/runtime.cc
+ M /trunk/asymptote/runtime.h
+
+Fixed multiple interactive shipouts in graphs with legends.
+
+------------------------------------------------------------------------
+r290 | jcbowman | 2005-01-30 23:21:33 -0700 (Sun, 30 Jan 2005) | 3 lines
+Changed paths:
+ M /trunk/asymptote/main.cc
+ M /trunk/asymptote/picture.cc
+
+Interactive mode now supports inputting files with multiple shipouts.
+Interactive mode disables deconstruction (xasy).
+
+------------------------------------------------------------------------
+r289 | jcbowman | 2005-01-30 22:17:47 -0700 (Sun, 30 Jan 2005) | 4 lines
+Changed paths:
+ M /trunk/asymptote/base/plain.asy
+ M /trunk/asymptote/texfile.h
+
+Fixed endl and tab in plain.asy to produce C strings.
+Fixed recently broken include command.
+Renamed internal symbol ASYalign to more meaningful ASYbase in baseline.
+
+------------------------------------------------------------------------
+r288 | jcbowman | 2005-01-30 21:46:28 -0700 (Sun, 30 Jan 2005) | 3 lines
+Changed paths:
+ M /trunk/asymptote/arrayop.h
+ M /trunk/asymptote/fileio.cc
+ M /trunk/asymptote/fileio.h
+ M /trunk/asymptote/interact.cc
+ M /trunk/asymptote/runtime.cc
+ M /trunk/asymptote/runtime.h
+
+Put file back into mempool by making typein and typeout variables rather
+than pointers.
+
+------------------------------------------------------------------------
+r287 | jcbowman | 2005-01-30 17:44:14 -0700 (Sun, 30 Jan 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/examples/cosaddition.asy
+ M /trunk/asymptote/examples/sinxlex.asy
+
+Updated examples to use math.arc routine.
+
+------------------------------------------------------------------------
+r286 | jcbowman | 2005-01-30 15:55:47 -0700 (Sun, 30 Jan 2005) | 3 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/errormsg.h
+ M /trunk/asymptote/interact.cc
+
+Allow optional Asymptote commands to be specified on the same line as
+interactive input command.
+
+------------------------------------------------------------------------
+r285 | jcbowman | 2005-01-30 11:15:01 -0700 (Sun, 30 Jan 2005) | 6 lines
+Changed paths:
+ M /trunk/asymptote/Makefile.in
+ M /trunk/asymptote/dec.cc
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/fileio.cc
+ M /trunk/asymptote/fileio.h
+ M /trunk/asymptote/genv.cc
+ M /trunk/asymptote/genv.h
+ M /trunk/asymptote/interact.cc
+ M /trunk/asymptote/interact.h
+ M /trunk/asymptote/main.cc
+ M /trunk/asymptote/runtime.cc
+
+Buffer stdin in interactive mode.
+Changed Import to input, which includes code directly into Asymptote, so
+that the user has access to the same environment that the code sees.
+Cleaned up fileio and removed it from mempool due to conflict with iostream
+routines.
+
+------------------------------------------------------------------------
+r284 | jcbowman | 2005-01-28 20:04:41 -0700 (Fri, 28 Jan 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/plain.asy
+ M /trunk/asymptote/texfile.h
+
+Add baseline TeX code back into texfile.h from plain.asy.
+
+------------------------------------------------------------------------
+r283 | jcbowman | 2005-01-28 02:54:10 -0700 (Fri, 28 Jan 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/configure.ac
+
+Incremented version to 0.60cvs.
+
+------------------------------------------------------------------------
+r282 | jcbowman | 2005-01-28 01:21:34 -0700 (Fri, 28 Jan 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/Makefile.in
+
+Makedepend updates.
+
+------------------------------------------------------------------------
+r281 | jcbowman | 2005-01-28 01:09:05 -0700 (Fri, 28 Jan 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/Makefile.in
+
+More makefile tweaks.
+
+------------------------------------------------------------------------
+r280 | jcbowman | 2005-01-28 00:40:32 -0700 (Fri, 28 Jan 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/Makefile
+
+Final makefile updates.
+
+------------------------------------------------------------------------
+r279 | jcbowman | 2005-01-28 00:15:07 -0700 (Fri, 28 Jan 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/configure.ac
+ M /trunk/asymptote/runtime.cc
+
+Automatically check for broken rpc/xdr headers.
+
+------------------------------------------------------------------------
+r278 | jcbowman | 2005-01-27 23:01:20 -0700 (Thu, 27 Jan 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/path.cc
+
+Fixed bounds to be consistent with behaviour of new quadratic solver.
+
+------------------------------------------------------------------------
+r277 | jcbowman | 2005-01-27 22:41:06 -0700 (Thu, 27 Jan 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/path.cc
+
+Implemented robust, accurate quadratic equation solver (used in dirtime).
+
+------------------------------------------------------------------------
+r276 | jcbowman | 2005-01-27 16:20:26 -0700 (Thu, 27 Jan 2005) | 5 lines
+Changed paths:
+ M /trunk/asymptote/Makefile.in
+ M /trunk/asymptote/configure.ac
+ M /trunk/asymptote/doc/Makefile
+ M /trunk/asymptote/doc/asymptote.texi
+ A /trunk/asymptote/getopt.c
+ A /trunk/asymptote/getopt.h
+ A /trunk/asymptote/getopt1.c
+ M /trunk/asymptote/settings.cc
+
+Added getopt for systems without full GNU getopt support (e.g. cygwin,
+FreeBSD).
+
+Use "make all/make install" to produce/install both asy and man pages.
+
+------------------------------------------------------------------------
+r275 | rtprince | 2005-01-27 00:30:12 -0700 (Thu, 27 Jan 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/path.cc
+
+Better? quadratic routine.
+
+------------------------------------------------------------------------
+r274 | rtprince | 2005-01-26 11:06:22 -0700 (Wed, 26 Jan 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/path.cc
+
+Use solveQuadratic for path::bounds as well.
+
+------------------------------------------------------------------------
+r273 | rtprince | 2005-01-26 10:44:00 -0700 (Wed, 26 Jan 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/path.cc
+
+Fix fuzz case in cubic dir.
+
+------------------------------------------------------------------------
+r272 | rtprince | 2005-01-26 10:37:55 -0700 (Wed, 26 Jan 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/pair.h
+
+Duplicate code.
+
+------------------------------------------------------------------------
+r271 | jcbowman | 2005-01-26 09:47:50 -0700 (Wed, 26 Jan 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/pair.h
+ M /trunk/asymptote/path.cc
+
+Added fuzz to fix dirtime(unitcircle,dir(-45)) bug under make OPT=-g.
+
+------------------------------------------------------------------------
+r270 | jcbowman | 2005-01-26 01:14:32 -0700 (Wed, 26 Jan 2005) | 9 lines
+Changed paths:
+ A /trunk/asymptote/base/babel.asy
+ M /trunk/asymptote/base/math.asy
+ M /trunk/asymptote/base/plain.asy
+ M /trunk/asymptote/camp.l
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/doc/latexusage.tex
+ M /trunk/asymptote/examples/integraltest.asy
+ M /trunk/asymptote/examples/lowupint.asy
+ M /trunk/asymptote/examples/polararea.asy
+ M /trunk/asymptote/examples/sqrtx01.asy
+ M /trunk/asymptote/exp.cc
+
+Implemented all ANSI C character string escape sequences for C strings.
+Removed all escape sequences from TeX strings except for \", which maps to ".
+Added support for LaTeX babel package.
+
+Improved arc so that it coincides exactly with circle approximation for all
+angles. Added triangle arc routine to math.asy.
+
+Renamed gray to lightgray in the example files.
+
+------------------------------------------------------------------------
+r269 | jcbowman | 2005-01-25 09:02:15 -0700 (Tue, 25 Jan 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/dec.cc
+
+Fixed explicit keyword (broken in dec.cc 1.8 on 2005-01-19).
+
+------------------------------------------------------------------------
+r268 | jcbowman | 2005-01-22 01:55:26 -0700 (Sat, 22 Jan 2005) | 3 lines
+Changed paths:
+ M /trunk/asymptote/base/plain.asy
+ M /trunk/asymptote/examples/planes.asy
+ M /trunk/asymptote/examples/sinxlex.asy
+ M /trunk/asymptote/examples/unitcircle.asy
+
+Renamed gray to lightgray; gray now means gray(0.5).
+Added colorPens and monoPens lists and boolean variable mono.
+
+------------------------------------------------------------------------
+r267 | jcbowman | 2005-01-22 00:14:42 -0700 (Sat, 22 Jan 2005) | 3 lines
+Changed paths:
+ M /trunk/asymptote/pen.h
+
+TRANSPARENT pen now has higher precedence that DEFCOLOR; also output
+"invisible" for this pen color.
+
+------------------------------------------------------------------------
+r266 | jcbowman | 2005-01-21 23:48:56 -0700 (Fri, 21 Jan 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/runtime.cc
+
+Added checks on string position arguments.
+
+------------------------------------------------------------------------
+r265 | rtprince | 2005-01-21 06:44:46 -0700 (Fri, 21 Jan 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/camp.l
+
+Handle invalid numbers gracefully.
+
+------------------------------------------------------------------------
+r264 | jcbowman | 2005-01-20 21:35:54 -0700 (Thu, 20 Jan 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/plain.asy
+ M /trunk/asymptote/camp.l
+
+Fixed cstring so that '\\' produces a backslash.
+
+------------------------------------------------------------------------
+r263 | rtprince | 2005-01-20 15:35:38 -0700 (Thu, 20 Jan 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/camp.l
+
+Add C-style strings delimited by '. (e.g. '\n' instead of "\\n").
+
+------------------------------------------------------------------------
+r262 | jcbowman | 2005-01-20 03:14:02 -0700 (Thu, 20 Jan 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/plain.asy
+
+More arc improvements.
+
+------------------------------------------------------------------------
+r261 | jcbowman | 2005-01-20 01:19:33 -0700 (Thu, 20 Jan 2005) | 4 lines
+Changed paths:
+ M /trunk/asymptote/TODO
+ M /trunk/asymptote/base/featpost3D.asy
+ M /trunk/asymptote/base/feynman.asy
+ M /trunk/asymptote/base/plain.asy
+ A /trunk/asymptote/examples/eetomumu.asy
+ A /trunk/asymptote/examples/fermi.asy
+ D /trunk/asymptote/examples/gluon.asy
+ M /trunk/asymptote/picture.cc
+
+Pdf updates.
+Added new arc routine and point/path utility functions.
+Added new examples and updates to feynman.asy.
+
+------------------------------------------------------------------------
+r260 | rtprince | 2005-01-18 22:48:12 -0700 (Tue, 18 Jan 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/TODO
+
+*** empty log message ***
+
+------------------------------------------------------------------------
+r259 | rtprince | 2005-01-18 22:44:26 -0700 (Tue, 18 Jan 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/dec.cc
+ M /trunk/asymptote/exp.cc
+ M /trunk/asymptote/exp.h
+ M /trunk/asymptote/types.cc
+ M /trunk/asymptote/types.h
+
+Get rid of as::defaultExp, and store varinit* in signature instead.
+
+------------------------------------------------------------------------
+r258 | jcbowman | 2005-01-18 22:38:39 -0700 (Tue, 18 Jan 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/picture.cc
+ M /trunk/asymptote/settings.cc
+ M /trunk/asymptote/xasy
+
+Minor bbox fuzz and alignment adjustments; fixed xasy alignment.
+
+------------------------------------------------------------------------
+r257 | jcbowman | 2005-01-18 20:49:33 -0700 (Tue, 18 Jan 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/TODO
+ M /trunk/asymptote/camp.y
+ M /trunk/asymptote/dec.cc
+ M /trunk/asymptote/dec.h
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/exp.cc
+ M /trunk/asymptote/pen.h
+ M /trunk/asymptote/picture.cc
+ M /trunk/asymptote/types.cc
+ M /trunk/asymptote/types.h
+
+Implementation of explicit keyword.
+
+------------------------------------------------------------------------
+r256 | rtprince | 2005-01-18 20:16:10 -0700 (Tue, 18 Jan 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/Compile
+
+Oops.
+
+------------------------------------------------------------------------
+r255 | rtprince | 2005-01-18 20:14:34 -0700 (Tue, 18 Jan 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/Compile
+ M /trunk/asymptote/Makefile.in
+
+Fix makefile breakage.
+
+------------------------------------------------------------------------
+r254 | rtprince | 2005-01-18 20:07:13 -0700 (Tue, 18 Jan 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/Compile
+ M /trunk/asymptote/Makefile.in
+
+Don't rebuild asy if we don't need to.
+
+------------------------------------------------------------------------
+r253 | rtprince | 2005-01-18 18:33:16 -0700 (Tue, 18 Jan 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc
+ M /trunk/asymptote/doc/.cvsignore
+
+version.texi is autogenerated.
+
+------------------------------------------------------------------------
+r252 | rtprince | 2005-01-18 11:25:05 -0700 (Tue, 18 Jan 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/camp.l
+ M /trunk/asymptote/camp.y
+
+Make explicit a keyword to detect breakage.
+
+------------------------------------------------------------------------
+r251 | jcbowman | 2005-01-18 00:24:50 -0700 (Tue, 18 Jan 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/plain.asy
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/doc/lineargraph.asy
+ M /trunk/asymptote/settings.cc
+ M /trunk/asymptote/texfile.cc
+
+Inhibit output of null labels.
+
+------------------------------------------------------------------------
+r250 | jcbowman | 2005-01-17 17:30:20 -0700 (Mon, 17 Jan 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/Makefile
+ M /trunk/asymptote/examples/cosaddition.asy
+ M /trunk/asymptote/picture.cc
+
+Fixed antialiasing and gv -watch problems.
+
+------------------------------------------------------------------------
+r249 | jcbowman | 2005-01-17 15:11:34 -0700 (Mon, 17 Jan 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/configure.ac
+
+Incremented version to 0.59cvs.
+
+------------------------------------------------------------------------
+r248 | jcbowman | 2005-01-16 21:43:30 -0700 (Sun, 16 Jan 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/examples/circles.asy
+ M /trunk/asymptote/examples/geometry.asy
+
+Updated new examples.
+
+------------------------------------------------------------------------
+r247 | jcbowman | 2005-01-16 21:35:30 -0700 (Sun, 16 Jan 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+
+Fixed formatting.
+
+------------------------------------------------------------------------
+r246 | jcbowman | 2005-01-16 21:16:23 -0700 (Sun, 16 Jan 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/runtime.cc
+
+Fixed warning message about unused variable.
+
+------------------------------------------------------------------------
+r245 | jcbowman | 2005-01-16 20:54:49 -0700 (Sun, 16 Jan 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/TODO
+
+Added new entry.
+
+------------------------------------------------------------------------
+r244 | jcbowman | 2005-01-16 20:45:57 -0700 (Sun, 16 Jan 2005) | 5 lines
+Changed paths:
+ M /trunk/asymptote/base/plain.asy
+ M /trunk/asymptote/builtin.cc
+ M /trunk/asymptote/cast.cc
+ M /trunk/asymptote/doc/asymptote.sty
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/drawlabel.cc
+ M /trunk/asymptote/drawpath.cc
+ M /trunk/asymptote/fileio.h
+ M /trunk/asymptote/pen.h
+ M /trunk/asymptote/picture.cc
+ M /trunk/asymptote/picture.h
+ M /trunk/asymptote/psfile.cc
+ M /trunk/asymptote/psfile.h
+ M /trunk/asymptote/runtime.cc
+ M /trunk/asymptote/runtime.h
+ M /trunk/asymptote/settings.cc
+ M /trunk/asymptote/settings.h
+ M /trunk/asymptote/texfile.cc
+
+The default linetype, linewidth, fontsize, color, linecap, linejoin, and
+overwrite mode can now all be changed with the routine defaultpen(pen).
+Removed unused pen defaultpen() in favour of void defaultpen(), which
+resets all pen default attributes to their startup values.
+
+------------------------------------------------------------------------
+r243 | jcbowman | 2005-01-16 00:26:46 -0700 (Sun, 16 Jan 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/tree.asy
+
+Added missing == and != operators for struct tree.
+
+------------------------------------------------------------------------
+r242 | jcbowman | 2005-01-16 00:15:54 -0700 (Sun, 16 Jan 2005) | 3 lines
+Changed paths:
+ M /trunk/asymptote/base/plain.asy
+ M /trunk/asymptote/builtin.cc
+ M /trunk/asymptote/doc/asymptote.sty
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/doc/mosquito.asy
+ M /trunk/asymptote/examples/wheelanimation.asy
+ M /trunk/asymptote/main.cc
+ M /trunk/asymptote/runtime.cc
+ M /trunk/asymptote/runtime.h
+ M /trunk/asymptote/settings.cc
+ M /trunk/asymptote/settings.h
+
+Replaced defaultlinewidth and defaultfontsize commands with
+defaultpen(pen). Moved reset() into plain.asy.
+
+------------------------------------------------------------------------
+r241 | jcbowman | 2005-01-15 23:11:03 -0700 (Sat, 15 Jan 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/configure.ac
+ M /trunk/asymptote/fileio.cc
+ M /trunk/asymptote/fileio.h
+ M /trunk/asymptote/runtime.cc
+
+Added configure option to detect xdr/rpc header files.
+
+------------------------------------------------------------------------
+r240 | jcbowman | 2005-01-15 17:45:32 -0700 (Sat, 15 Jan 2005) | 6 lines
+Changed paths:
+ M /trunk/asymptote/base/graph.asy
+ M /trunk/asymptote/base/math.asy
+ M /trunk/asymptote/base/plain.asy
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/doc/datagraph.asy
+ M /trunk/asymptote/doc/latexusage.tex
+ M /trunk/asymptote/examples/Pythagoras.asy
+ A /trunk/asymptote/examples/circles.asy
+ A /trunk/asymptote/examples/geometry.asy
+
+Fixed 2d graph bugs 1102574 and 1102396 and related bugs.
+Added XEquals and YEquals axis types.
+Allow all axis types to optionally extend to dimensions of picture; updated
+documentation.
+Simplified routine for drawing perpendicular symbols in math.asy.
+
+------------------------------------------------------------------------
+r239 | rtprince | 2005-01-14 14:30:51 -0700 (Fri, 14 Jan 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/access.cc
+ M /trunk/asymptote/coder.cc
+ M /trunk/asymptote/coder.h
+ M /trunk/asymptote/dec.cc
+ M /trunk/asymptote/exp.cc
+ M /trunk/asymptote/genv.cc
+ M /trunk/asymptote/inst.cc
+ M /trunk/asymptote/inst.h
+ M /trunk/asymptote/newexp.cc
+ M /trunk/asymptote/stack.cc
+ M /trunk/asymptote/stm.cc
+
+Store operands with opcode, rather than in the following inst.
+
+------------------------------------------------------------------------
+r238 | rtprince | 2005-01-12 11:45:37 -0700 (Wed, 12 Jan 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/dec.h
+
+markTrans and markTransAsField are utility functions that don't need to be redefined.
+
+------------------------------------------------------------------------
+r237 | rtprince | 2005-01-12 11:36:53 -0700 (Wed, 12 Jan 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/absyn.cc
+ M /trunk/asymptote/absyn.h
+ M /trunk/asymptote/dec.h
+ M /trunk/asymptote/exp.cc
+ M /trunk/asymptote/exp.h
+ M /trunk/asymptote/name.cc
+ M /trunk/asymptote/name.h
+ M /trunk/asymptote/newexp.cc
+ M /trunk/asymptote/stm.cc
+ M /trunk/asymptote/stm.h
+
+Clean up header file dependencies.
+
+------------------------------------------------------------------------
+r236 | jcbowman | 2005-01-12 10:17:35 -0700 (Wed, 12 Jan 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/plain.asy
+ M /trunk/asymptote/doc/asymptote.texi
+
+Made currentpen static.
+
+------------------------------------------------------------------------
+r235 | jcbowman | 2005-01-11 21:42:27 -0700 (Tue, 11 Jan 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/Makefile.in
+
+Use $(MAKE) rather than make everywhere within Makefile.
+
+------------------------------------------------------------------------
+r234 | jcbowman | 2005-01-11 21:14:09 -0700 (Tue, 11 Jan 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/configure.ac
+
+Increment version to 0.58cvs.
+
+------------------------------------------------------------------------
+r233 | jcbowman | 2005-01-11 20:52:01 -0700 (Tue, 11 Jan 2005) | 3 lines
+Changed paths:
+ M /trunk/asymptote/base/feynman.asy
+ M /trunk/asymptote/base/graph.asy
+ M /trunk/asymptote/base/plain.asy
+ M /trunk/asymptote/builtin.cc
+ M /trunk/asymptote/doc/asymptote.texi
+ A /trunk/asymptote/examples/cosaddition.asy
+ A /trunk/asymptote/examples/delu.asy
+ D /trunk/asymptote/examples/exp.asy
+ A /trunk/asymptote/examples/fano.asy
+ A /trunk/asymptote/examples/phase.asy
+ A /trunk/asymptote/examples/polararea.asy
+ A /trunk/asymptote/examples/polarcircle.asy
+ A /trunk/asymptote/examples/sinxlex.asy
+ A /trunk/asymptote/examples/unitcircle.asy
+ A /trunk/asymptote/examples/wedge.asy
+
+Removed direction(path, real) and direction(path, int) in favour of
+dir(path, real t=1) and dir(path, int t=1). Added examples.
+
+------------------------------------------------------------------------
+r232 | jcbowman | 2005-01-11 16:29:22 -0700 (Tue, 11 Jan 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/plain.asy
+ M /trunk/asymptote/builtin.cc
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/doc/diatom.asy
+ M /trunk/asymptote/drawlabel.cc
+ M /trunk/asymptote/pen.h
+ M /trunk/asymptote/runtime.cc
+ M /trunk/asymptote/runtime.h
+ M /trunk/asymptote/settings.cc
+ M /trunk/asymptote/settings.h
+
+Made overwrite mode a pen attribute; updated documentation.
+
+------------------------------------------------------------------------
+r231 | rtprince | 2005-01-11 12:31:37 -0700 (Tue, 11 Jan 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/runtime.cc
+
+symbol::trans accepts a std::string not a char*.
+
+------------------------------------------------------------------------
+r230 | rtprince | 2005-01-11 12:30:26 -0700 (Tue, 11 Jan 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/settings.h
+
+Fix typo in comment.
+
+------------------------------------------------------------------------
+r229 | jcbowman | 2005-01-11 01:55:28 -0700 (Tue, 11 Jan 2005) | 3 lines
+Changed paths:
+ M /trunk/asymptote/builtin.cc
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/drawlabel.cc
+
+Fixed infinite loop bug in overwrite mode.
+Added synonym dir(path,int) for direction(path,int), etc.
+
+------------------------------------------------------------------------
+r228 | jcbowman | 2005-01-10 21:04:30 -0700 (Mon, 10 Jan 2005) | 7 lines
+Changed paths:
+ M /trunk/asymptote/base/graph.asy
+ M /trunk/asymptote/base/plain.asy
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/doc/logo.asy
+ M /trunk/asymptote/doc/westnile.asy
+ M /trunk/asymptote/pen.h
+ M /trunk/asymptote/psfile.h
+ M /trunk/asymptote/settings.cc
+ M /trunk/asymptote/settings.h
+ M /trunk/asymptote/texfile.cc
+ M /trunk/asymptote/texfile.h
+
+Fixed rgb to cmyk routine and added cmyk to rgb routine.
+Added -cmyk and -rgb command options.
+Made labelx and labely routines position labels consistently with axis
+routines by default.
+Generalized baseline routine and moved from texfile.cc into plain.asy.
+Adjusted logo for new labeling system.
+
+------------------------------------------------------------------------
+r227 | jcbowman | 2005-01-09 17:10:02 -0700 (Sun, 09 Jan 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/configure.ac
+
+Increment version to 0.57cvs.
+
+------------------------------------------------------------------------
+r226 | jcbowman | 2005-01-09 16:16:50 -0700 (Sun, 09 Jan 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/picture.cc
+
+Make PSViewer and PDFViewer search conform to documented behaviour.
+
+------------------------------------------------------------------------
+r225 | jcbowman | 2005-01-09 14:43:21 -0700 (Sun, 09 Jan 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/plain.asy
+ M /trunk/asymptote/builtin.cc
+ M /trunk/asymptote/doc/asymptote.texi
+ A /trunk/asymptote/doc/shade.asy
+ M /trunk/asymptote/drawfill.cc
+ M /trunk/asymptote/drawfill.h
+ M /trunk/asymptote/psfile.h
+ M /trunk/asymptote/runtime.cc
+ M /trunk/asymptote/settings.cc
+
+Implemented radial gradient shading; updated documentation.
+
+------------------------------------------------------------------------
+r224 | jcbowman | 2005-01-09 11:35:09 -0700 (Sun, 09 Jan 2005) | 6 lines
+Changed paths:
+ M /trunk/asymptote/base/plain.asy
+ M /trunk/asymptote/builtin.cc
+ M /trunk/asymptote/doc/asymptote.texi
+ A /trunk/asymptote/doc/mosquito.asy
+ A /trunk/asymptote/doc/mosquito.csv
+ A /trunk/asymptote/doc/secondaryaxis.asy
+ A /trunk/asymptote/doc/secondaryaxis.csv
+ A /trunk/asymptote/doc/westnile.asy
+ A /trunk/asymptote/doc/westnile.csv
+ M /trunk/asymptote/drawfill.cc
+ M /trunk/asymptote/pen.h
+ M /trunk/asymptote/runtime.cc
+ M /trunk/asymptote/runtime.h
+ M /trunk/asymptote/types.h
+
+Make patterns work with xasy.
+An explicit picture is now required in order to specify preamble to shipout.
+Added scientific diagram and graphs to documentation to illustrate
+the minipage function, secondary axes, and the drawabout function.
+The new real[[] colors(pen) function returns the color components of a pen.
+
+------------------------------------------------------------------------
+r223 | jcbowman | 2005-01-09 02:02:17 -0700 (Sun, 09 Jan 2005) | 4 lines
+Changed paths:
+ M /trunk/asymptote/base/plain.asy
+ M /trunk/asymptote/builtin.cc
+ M /trunk/asymptote/doc/asymptote.texi
+ A /trunk/asymptote/doc/hatch.asy
+ A /trunk/asymptote/doc/shadedtiling.asy
+ M /trunk/asymptote/drawelement.h
+ M /trunk/asymptote/drawfill.cc
+ M /trunk/asymptote/drawfill.h
+ M /trunk/asymptote/drawpath.cc
+ M /trunk/asymptote/drawverbatim.h
+ M /trunk/asymptote/pen.h
+ M /trunk/asymptote/picture.cc
+ M /trunk/asymptote/picture.h
+ M /trunk/asymptote/psfile.cc
+ M /trunk/asymptote/psfile.h
+ M /trunk/asymptote/runtime.cc
+ M /trunk/asymptote/runtime.h
+ M /trunk/asymptote/settings.cc
+ M /trunk/asymptote/settings.h
+ M /trunk/asymptote/texfile.cc
+
+Added tiling patterns and gradient shading.
+Added linecap and linejoin pen specifiers.
+Updated documentation with examples of new features.
+
+------------------------------------------------------------------------
+r222 | jcbowman | 2005-01-06 20:47:04 -0700 (Thu, 06 Jan 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/graph.asy
+ M /trunk/asymptote/base/plain.asy
+
+Minor interp and secondary axis updates.
+
+------------------------------------------------------------------------
+r221 | jcbowman | 2005-01-06 15:28:55 -0700 (Thu, 06 Jan 2005) | 3 lines
+Changed paths:
+ M /trunk/asymptote/base/graph.asy
+ M /trunk/asymptote/base/plain.asy
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/examples/equilchord.asy
+
+New postscript-coordinate shift option for label routines;
+pictures added to pictures now transform properly; updated documentation.
+
+------------------------------------------------------------------------
+r220 | jcbowman | 2005-01-06 03:20:46 -0700 (Thu, 06 Jan 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/graph.asy
+
+Added secondary axis facility; fixed scaling bug.
+
+------------------------------------------------------------------------
+r219 | jcbowman | 2005-01-06 03:19:12 -0700 (Thu, 06 Jan 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/runtime.h
+
+minor formatting.
+
+------------------------------------------------------------------------
+r218 | jcbowman | 2005-01-06 03:17:36 -0700 (Thu, 06 Jan 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/plain.asy
+ M /trunk/asymptote/doc/asymptote.texi
+
+Removed unused currentframe variable; updated documentation.
+
+------------------------------------------------------------------------
+r217 | jcbowman | 2005-01-05 16:19:22 -0700 (Wed, 05 Jan 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/fileio.cc
+ M /trunk/asymptote/runtime.h
+
+Further csv and linemode updates.
+
+------------------------------------------------------------------------
+r216 | jcbowman | 2005-01-05 09:21:16 -0700 (Wed, 05 Jan 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/fileio.cc
+
+Fixed cvs+line mode bugs.
+
+------------------------------------------------------------------------
+r215 | jcbowman | 2005-01-05 09:20:56 -0700 (Wed, 05 Jan 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/examples/lever.asy
+
+label positioning update
+
+------------------------------------------------------------------------
+r214 | jcbowman | 2005-01-05 09:20:26 -0700 (Wed, 05 Jan 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/exp.cc
+
+minor formatting.
+
+------------------------------------------------------------------------
+r213 | jcbowman | 2005-01-05 00:01:23 -0700 (Wed, 05 Jan 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+
+Updated documentation.
+
+------------------------------------------------------------------------
+r212 | jcbowman | 2005-01-04 23:38:08 -0700 (Tue, 04 Jan 2005) | 4 lines
+Changed paths:
+ M /trunk/asymptote/base/plain.asy
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/drawlabel.cc
+ M /trunk/asymptote/examples/venn.asy
+
+Fixed "label with arrow" routine. Removed outarrow in favour of drawabout.
+Updated documentation regarding new optional position argument of path
+labels (draw and drawabout).
+
+------------------------------------------------------------------------
+r211 | jcbowman | 2005-01-04 21:00:13 -0700 (Tue, 04 Jan 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/plain.asy
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/drawlabel.cc
+ M /trunk/asymptote/drawlabel.h
+
+Align labels before adding label bounding box fuzz.
+
+------------------------------------------------------------------------
+r210 | jcbowman | 2005-01-04 20:58:24 -0700 (Tue, 04 Jan 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/featpost3D.asy
+
+Use math italic axis labels.
+
+------------------------------------------------------------------------
+r209 | jcbowman | 2005-01-04 12:07:41 -0700 (Tue, 04 Jan 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/errors
+
+Updated.
+
+------------------------------------------------------------------------
+r208 | jcbowman | 2005-01-04 12:05:08 -0700 (Tue, 04 Jan 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/exp.cc
+ M /trunk/asymptote/types.h
+
+Added function name to "cannot call...with" error messages.
+
+------------------------------------------------------------------------
+r207 | jcbowman | 2005-01-04 00:34:48 -0700 (Tue, 04 Jan 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/graph.asy
+ M /trunk/asymptote/base/math.asy
+ M /trunk/asymptote/base/plain.asy
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/doc/latexusage.tex
+ M /trunk/asymptote/drawlabel.cc
+ M /trunk/asymptote/drawlabel.h
+ M /trunk/asymptote/examples/lever.asy
+ M /trunk/asymptote/examples/sqrtx01.asy
+
+Improved and tightened label bounding box calculation.
+
+------------------------------------------------------------------------
+r206 | jcbowman | 2005-01-04 00:32:19 -0700 (Tue, 04 Jan 2005) | 2 lines
+Changed paths:
+ M /trunk/asymptote/exp.cc
+
+Made "cannot call type...with" diagnostic easier to read.
+
+------------------------------------------------------------------------
+r205 | jcbowman | 2004-12-28 08:21:41 -0700 (Tue, 28 Dec 2004) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/graph.asy
+ M /trunk/asymptote/base/plain.asy
+ M /trunk/asymptote/examples/wheelanimation.asy
+
+label and arrow adjustments
+
+------------------------------------------------------------------------
+r204 | jcbowman | 2004-12-27 01:01:56 -0700 (Mon, 27 Dec 2004) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/plain.asy
+
+Added minipage and outarrow routines.
+
+------------------------------------------------------------------------
+r203 | jcbowman | 2004-12-26 18:55:48 -0700 (Sun, 26 Dec 2004) | 2 lines
+Changed paths:
+ M /trunk/asymptote/drawlabel.cc
+ M /trunk/asymptote/drawverbatim.h
+ M /trunk/asymptote/picture.cc
+ M /trunk/asymptote/pipestream.h
+ M /trunk/asymptote/runtime.cc
+ M /trunk/asymptote/texfile.h
+ M /trunk/asymptote/util.cc
+ M /trunk/asymptote/util.h
+
+Fixed TeX pipestream embedded newline & diagnostic problems.
+
+------------------------------------------------------------------------
+r202 | jcbowman | 2004-12-26 13:20:02 -0700 (Sun, 26 Dec 2004) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/plain.asy
+
+implement scaling of pic.userMin and pic.userMax.
+
+------------------------------------------------------------------------
+r201 | jcbowman | 2004-12-22 22:01:33 -0700 (Wed, 22 Dec 2004) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/plain.asy
+
+Added newpage() command.
+
+------------------------------------------------------------------------
+r200 | jcbowman | 2004-12-22 18:16:14 -0700 (Wed, 22 Dec 2004) | 2 lines
+Changed paths:
+ M /trunk/asymptote/drawlabel.cc
+ M /trunk/asymptote/drawlabel.h
+ M /trunk/asymptote/picture.cc
+ M /trunk/asymptote/texfile.cc
+ M /trunk/asymptote/texfile.h
+
+Improved and simplified label code.
+
+------------------------------------------------------------------------
+r199 | jcbowman | 2004-12-22 14:06:19 -0700 (Wed, 22 Dec 2004) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/plain.asy
+ M /trunk/asymptote/drawlabel.cc
+ M /trunk/asymptote/picture.cc
+
+More label updates.
+
+------------------------------------------------------------------------
+r198 | jcbowman | 2004-12-22 03:01:04 -0700 (Wed, 22 Dec 2004) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/plain.asy
+ M /trunk/asymptote/drawlabel.cc
+ M /trunk/asymptote/picture.cc
+
+Label updates.
+
+------------------------------------------------------------------------
+r197 | jcbowman | 2004-12-21 01:07:25 -0700 (Tue, 21 Dec 2004) | 2 lines
+Changed paths:
+ M /trunk/asymptote/drawlabel.cc
+ M /trunk/asymptote/picture.cc
+
+Improved label bounding boxes.
+
+------------------------------------------------------------------------
+r196 | jcbowman | 2004-12-19 21:00:22 -0700 (Sun, 19 Dec 2004) | 2 lines
+Changed paths:
+ M /trunk/asymptote/drawlabel.cc
+
+Account for depth in label alignment code.
+
+------------------------------------------------------------------------
+r195 | jcbowman | 2004-12-17 11:35:21 -0700 (Fri, 17 Dec 2004) | 2 lines
+Changed paths:
+ M /trunk/asymptote/picture.cc
+ M /trunk/asymptote/texfile.cc
+
+Fine tuning of label offset (dependent on pdf/-B).
+
+------------------------------------------------------------------------
+r194 | jcbowman | 2004-12-16 21:17:16 -0700 (Thu, 16 Dec 2004) | 2 lines
+Changed paths:
+ M /trunk/asymptote/configure.ac
+
+Increment version to 0.56cvs.
+
+------------------------------------------------------------------------
+r193 | jcbowman | 2004-12-16 16:52:04 -0700 (Thu, 16 Dec 2004) | 2 lines
+Changed paths:
+ M /trunk/asymptote/Makefile.in
+ M /trunk/asymptote/configure.ac
+
+Force use of bison (not yacc).
+
+------------------------------------------------------------------------
+r192 | jcbowman | 2004-12-16 16:32:16 -0700 (Thu, 16 Dec 2004) | 2 lines
+Changed paths:
+ M /trunk/asymptote/runtime.cc
+
+Fixed warning messages.
+
+------------------------------------------------------------------------
+r191 | jcbowman | 2004-12-16 16:26:09 -0700 (Thu, 16 Dec 2004) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+
+ispell updates
+
+------------------------------------------------------------------------
+r190 | jcbowman | 2004-12-16 16:21:08 -0700 (Thu, 16 Dec 2004) | 2 lines
+Changed paths:
+ M /trunk/asymptote/TODO
+ M /trunk/asymptote/doc/asymptote.texi
+
+Documentation updates.
+
+------------------------------------------------------------------------
+r189 | jcbowman | 2004-12-16 16:05:14 -0700 (Thu, 16 Dec 2004) | 2 lines
+Changed paths:
+ M /trunk/asymptote/picture.cc
+
+Improved latex diagnostics.
+
+------------------------------------------------------------------------
+r188 | jcbowman | 2004-12-16 12:14:58 -0700 (Thu, 16 Dec 2004) | 2 lines
+Changed paths:
+ A /trunk/asymptote/base/feynman.asy
+ M /trunk/asymptote/base/graph.asy
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/doc/datagraph.asy
+ M /trunk/asymptote/doc/lineargraph.asy
+
+Updated documentation.
+
+------------------------------------------------------------------------
+r187 | jcbowman | 2004-12-16 11:45:54 -0700 (Thu, 16 Dec 2004) | 2 lines
+Changed paths:
+ A /trunk/asymptote/examples/conicurv.asy
+ A /trunk/asymptote/examples/gluon.asy
+ A /trunk/asymptote/examples/near_earth.asy
+
+Contributed examples.
+
+------------------------------------------------------------------------
+r186 | jcbowman | 2004-12-16 09:11:08 -0700 (Thu, 16 Dec 2004) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/metapost.asy
+
+Added cuttings global variable.
+
+------------------------------------------------------------------------
+r185 | jcbowman | 2004-12-15 22:42:14 -0700 (Wed, 15 Dec 2004) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/featpost3D.asy
+ A /trunk/asymptote/base/metapost.asy
+ M /trunk/asymptote/base/plain.asy
+
+Moved metapost compatibility routines to separate file.
+
+------------------------------------------------------------------------
+r184 | jcbowman | 2004-12-15 21:52:04 -0700 (Wed, 15 Dec 2004) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/plain.asy
+ M /trunk/asymptote/doc/asymptote.texi
+
+Perhaps a more sensible alternative to Metapost cutbefore/cutafter/cuttings.
+
+------------------------------------------------------------------------
+r183 | jcbowman | 2004-12-15 09:31:40 -0700 (Wed, 15 Dec 2004) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/latexusage.tex
+
+updated coordinate
+
+------------------------------------------------------------------------
+r182 | jcbowman | 2004-12-15 09:30:10 -0700 (Wed, 15 Dec 2004) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/featpost3D.asy
+
+Added translator name.
+
+------------------------------------------------------------------------
+r181 | jcbowman | 2004-12-15 09:26:31 -0700 (Wed, 15 Dec 2004) | 3 lines
+Changed paths:
+ M /trunk/asymptote/base/plain.asy
+ M /trunk/asymptote/doc/asymptote.texi
+
+added before(path,path) and after(path,path); documented cutbefore and
+cutafter and changed them to work always according to these specificiations.
+
+------------------------------------------------------------------------
+r180 | jcbowman | 2004-12-14 17:39:21 -0700 (Tue, 14 Dec 2004) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.sty
+
+Fixed bug [ 1084667 ] asydef environment.
+
+------------------------------------------------------------------------
+r179 | jcbowman | 2004-12-14 17:24:27 -0700 (Tue, 14 Dec 2004) | 2 lines
+Changed paths:
+ M /trunk/asymptote/pen.h
+ M /trunk/asymptote/psfile.cc
+ M /trunk/asymptote/texfile.cc
+
+Fixed bug [ 1084641 ] problem with defaultfontsize.
+
+------------------------------------------------------------------------
+r178 | jcbowman | 2004-12-14 12:02:12 -0700 (Tue, 14 Dec 2004) | 3 lines
+Changed paths:
+ M /trunk/asymptote/runtime.cc
+
+in texPreamble: replaced newlines with spaces as they can break
+bidirectional TeX pipe.
+
+------------------------------------------------------------------------
+r177 | jcbowman | 2004-12-13 12:01:12 -0700 (Mon, 13 Dec 2004) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/graph.asy
+ M /trunk/asymptote/base/plain.asy
+
+Simplified axis capping.
+
+------------------------------------------------------------------------
+r176 | jcbowman | 2004-12-13 10:30:01 -0700 (Mon, 13 Dec 2004) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/graph.asy
+ M /trunk/asymptote/examples/equilchord.asy
+ M /trunk/asymptote/examples/lever.asy
+ M /trunk/asymptote/examples/wheelanimation.asy
+
+Fix override of axis label positioning.
+
+------------------------------------------------------------------------
+r175 | jcbowman | 2004-12-12 23:55:30 -0700 (Sun, 12 Dec 2004) | 2 lines
+Changed paths:
+ M /trunk/asymptote/path.cc
+
+Fixed bug 1084016: error in bounding box computation.
+
+------------------------------------------------------------------------
+r174 | jcbowman | 2004-12-12 17:05:09 -0700 (Sun, 12 Dec 2004) | 2 lines
+Changed paths:
+ A /trunk/asymptote/base/featpost3D.asy
+
+Partial port of featpost 3D package for MetaPost.
+
+------------------------------------------------------------------------
+r173 | jcbowman | 2004-12-12 17:04:06 -0700 (Sun, 12 Dec 2004) | 5 lines
+Changed paths:
+ M /trunk/asymptote/TODO
+ M /trunk/asymptote/base/math.asy
+ M /trunk/asymptote/base/plain.asy
+ M /trunk/asymptote/doc/asymptote.texi
+
+Added operator == and != for vector classs.
+Added interp routine for pairs, vectors, and pens.
+Added pen background=white, unfill, cutbefore, and cutafter.
+Documentation updates.
+
+------------------------------------------------------------------------
+r172 | jcbowman | 2004-12-12 16:59:33 -0700 (Sun, 12 Dec 2004) | 3 lines
+Changed paths:
+ M /trunk/asymptote/dec.cc
+
+Changed default structure operator == to alias (as with arrays) to allow
+user-defined == operators on structures. Also removed != in favour of !alias.
+
+------------------------------------------------------------------------
+r171 | jcbowman | 2004-12-11 13:59:39 -0700 (Sat, 11 Dec 2004) | 2 lines
+Changed paths:
+ M /trunk/asymptote/camp.l
+
+Handle invalid operators cleanly.
+
+------------------------------------------------------------------------
+r170 | jcbowman | 2004-12-10 17:32:52 -0700 (Fri, 10 Dec 2004) | 2 lines
+Changed paths:
+ M /trunk/asymptote/configure.ac
+
+Updated bug report address.
+
+------------------------------------------------------------------------
+r169 | jcbowman | 2004-12-10 16:10:39 -0700 (Fri, 10 Dec 2004) | 2 lines
+Changed paths:
+ M /trunk/asymptote/path.cc
+ M /trunk/asymptote/path.h
+
+Fixed nullpath bugs.
+
+------------------------------------------------------------------------
+r168 | jcbowman | 2004-12-10 16:10:21 -0700 (Fri, 10 Dec 2004) | 2 lines
+Changed paths:
+ M /trunk/asymptote/Makefile.in
+ M /trunk/asymptote/doc/asymptote.texi
+
+Installation updates
+
+------------------------------------------------------------------------
+r167 | jcbowman | 2004-12-10 11:17:20 -0700 (Fri, 10 Dec 2004) | 2 lines
+Changed paths:
+ M /trunk/asymptote/Makefile.in
+
+Make info and man directories if missing.
+
+------------------------------------------------------------------------
+r166 | jcbowman | 2004-12-10 10:57:18 -0700 (Fri, 10 Dec 2004) | 2 lines
+Changed paths:
+ M /trunk/asymptote/picture.cc
+
+Added missing include.
+
+------------------------------------------------------------------------
+r165 | jcbowman | 2004-12-10 10:55:11 -0700 (Fri, 10 Dec 2004) | 2 lines
+Changed paths:
+ M /trunk/asymptote/Makefile.in
+ M /trunk/asymptote/configure.ac
+ M /trunk/asymptote/doc/Makefile
+
+Simplified configuration.
+
+------------------------------------------------------------------------
+r164 | jcbowman | 2004-12-09 22:32:49 -0700 (Thu, 09 Dec 2004) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/plain.asy
+ M /trunk/asymptote/doc/asymptote.texi
+
+Documentation updates.
+
+------------------------------------------------------------------------
+r163 | hammera | 2004-12-09 11:41:11 -0700 (Thu, 09 Dec 2004) | 2 lines
+Changed paths:
+ M /trunk/asymptote/knotlist.cc
+
+Fixed tension atleast bug.
+
+------------------------------------------------------------------------
+r162 | jcbowman | 2004-12-05 11:32:56 -0700 (Sun, 05 Dec 2004) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/graph.asy
+
+Improved axis label sizing.
+
+------------------------------------------------------------------------
+r161 | jcbowman | 2004-12-05 11:31:11 -0700 (Sun, 05 Dec 2004) | 3 lines
+Changed paths:
+ M /trunk/asymptote/main.cc
+
+Remove signal(SIGCHLD, SIG_IGN): there are no remaining problems with
+zombies, and it causes other problems with gv.
+
+------------------------------------------------------------------------
+r160 | jcbowman | 2004-12-05 10:38:47 -0700 (Sun, 05 Dec 2004) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+
+Fixed typo.
+
+------------------------------------------------------------------------
+r159 | jcbowman | 2004-12-05 03:26:52 -0700 (Sun, 05 Dec 2004) | 2 lines
+Changed paths:
+ M /trunk/asymptote/configure.ac
+
+Increment version to 0.55cvs.
+
+------------------------------------------------------------------------
+r158 | jcbowman | 2004-12-05 02:19:43 -0700 (Sun, 05 Dec 2004) | 4 lines
+Changed paths:
+ M /trunk/asymptote/base/graph.asy
+ M /trunk/asymptote/base/plain.asy
+ M /trunk/asymptote/doc/asymptote.sty
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/doc/diatom.asy
+ M /trunk/asymptote/doc/latexusage.tex
+
+Fixed graph sizing routines; added legendsize routine (useful for
+compensating for space taken up by external legend); the default width in
+asymptote.sty is now the full line width.
+
+------------------------------------------------------------------------
+r157 | jcbowman | 2004-12-05 02:10:08 -0700 (Sun, 05 Dec 2004) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/Makefile
+
+Added missing mkdir.
+
+------------------------------------------------------------------------
+r156 | jcbowman | 2004-12-04 16:07:57 -0700 (Sat, 04 Dec 2004) | 6 lines
+Changed paths:
+ M /trunk/asymptote/Makefile.in
+ M /trunk/asymptote/doc/asy.1
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/picture.cc
+ M /trunk/asymptote/settings.cc
+ M /trunk/asymptote/settings.h
+
+Center EPS figures on page by default. Added support for a4 paper as well as
+letter.
+
+Default postscript offset is now 0,0.
+Option -B (-T) aligns to bottom (top) of page.
+
+------------------------------------------------------------------------
+r155 | jcbowman | 2004-12-04 14:15:09 -0700 (Sat, 04 Dec 2004) | 13 lines
+Changed paths:
+ M /trunk/asymptote/README
+ M /trunk/asymptote/doc/Makefile
+ A /trunk/asymptote/doc/asy.1
+ M /trunk/asymptote/doc/asymptote.texi
+ A /trunk/asymptote/doc/xasy.1x
+ M /trunk/asymptote/examples/lowint.asy
+ M /trunk/asymptote/examples/upint.asy
+ M /trunk/asymptote/picture.cc
+ M /trunk/asymptote/settings.cc
+
+Applied Hubert Chan's installation patch for Debian.
+
+Moved examples, asy.vim, and asy-mode.el to /usr/local/share/doc/asymptote/
+
+asymptote/asymptote.sty is now installed in /usr/share/texmf/tex/latex/
+(./configure --with-latex=PATH to override).
+
+Fixed typos; updated documentation and changed documentation license
+from GFDL to GPL in view of Debian position statement:
+http://people.debian.org/~srivasta/Position_Statement.xhtml
+
+Added man pages asy.1 and xasy.1x kindly provided by Hubert.
+
+------------------------------------------------------------------------
+r154 | jcbowman | 2004-12-04 13:42:17 -0700 (Sat, 04 Dec 2004) | 2 lines
+Changed paths:
+ M /trunk/asymptote/configure.ac
+
+Fixed -with-latex=PATH.
+
+------------------------------------------------------------------------
+r153 | jcbowman | 2004-12-04 13:03:09 -0700 (Sat, 04 Dec 2004) | 2 lines
+Changed paths:
+ M /trunk/asymptote/Makefile.in
+ M /trunk/asymptote/configure.ac
+
+Added --with-latex=PATH configuration option.
+
+------------------------------------------------------------------------
+r152 | jcbowman | 2004-12-03 23:15:57 -0700 (Fri, 03 Dec 2004) | 5 lines
+Changed paths:
+ M /trunk/asymptote/base/graph.asy
+ M /trunk/asymptote/base/plain.asy
+ M /trunk/asymptote/doc/diatom.asy
+ M /trunk/asymptote/picture.cc
+
+Implemented better estimate for graph axis space requirements for more
+accurate graph sizing.
+
+Added Portrait, Landscape, and Seascape shipout orientations.
+
+------------------------------------------------------------------------
+r151 | jcbowman | 2004-12-03 11:15:14 -0700 (Fri, 03 Dec 2004) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/picture.cc
+ M /trunk/asymptote/pipestream.h
+ M /trunk/asymptote/util.cc
+ M /trunk/asymptote/util.h
+
+Bounding box & diagnostic tweaks.
+
+------------------------------------------------------------------------
+r150 | jcbowman | 2004-12-03 07:52:52 -0700 (Fri, 03 Dec 2004) | 2 lines
+Changed paths:
+ M /trunk/asymptote/picture.cc
+ M /trunk/asymptote/util.h
+
+Added missing header to make cxx compiler happy.
+
+------------------------------------------------------------------------
+r149 | jcbowman | 2004-12-03 07:31:00 -0700 (Fri, 03 Dec 2004) | 9 lines
+Changed paths:
+ M /trunk/asymptote/bbox.h
+ M /trunk/asymptote/doc/asymptote.sty
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/doc/diatom.asy
+ M /trunk/asymptote/drawlabel.cc
+ M /trunk/asymptote/pair.h
+ M /trunk/asymptote/picture.cc
+ M /trunk/asymptote/picture.h
+ M /trunk/asymptote/pipestream.h
+ M /trunk/asymptote/psfile.cc
+ M /trunk/asymptote/psfile.h
+ M /trunk/asymptote/settings.cc
+ M /trunk/asymptote/settings.h
+
+Reworked dvips and gs pdfwrite interface: do a post-bbox correction rather than
+using dvips -E (which ignores postscript label rotation).
+
+Align figures to top-left corner (unless the new -b option is given, in
+which case the bottom-left corner is used), to allow for direct printing of
+the generated EPS files. User can override default offset of 18bp.
+
+Updated documentation.
+
+------------------------------------------------------------------------
+r148 | jcbowman | 2004-12-03 07:23:35 -0700 (Fri, 03 Dec 2004) | 2 lines
+Changed paths:
+ M /trunk/asymptote/examples/cardiod.asy
+
+Adjusted label alignment.
+
+------------------------------------------------------------------------
+r147 | jcbowman | 2004-12-02 11:54:48 -0700 (Thu, 02 Dec 2004) | 3 lines
+Changed paths:
+ M /trunk/asymptote/base/graph.asy
+
+Reinstate label bounding box determination; xequals and yequals routines
+will still work as expected if crop is called.
+
+------------------------------------------------------------------------
+r146 | jcbowman | 2004-12-02 02:00:42 -0700 (Thu, 02 Dec 2004) | 9 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/genv.cc
+ M /trunk/asymptote/main.cc
+ M /trunk/asymptote/picture.cc
+ M /trunk/asymptote/picture.h
+ M /trunk/asymptote/settings.cc
+ M /trunk/asymptote/settings.h
+ M /trunk/asymptote/util.cc
+ M /trunk/asymptote/util.h
+
+Use dvips -E (encapsulation; this works now that bbox coordinates are
+non-negative) instead of -T (pagesize) to fix compatibility problems in the
+final postscript output. Made corresponding adjustments to printer offset code.
+
+Added support and documentation for using Postscript viewers other than gv.
+
+Fixed filename extension detection so that filenames containing ./ and ../
+work correctly.
+
+------------------------------------------------------------------------
+r145 | jcbowman | 2004-12-02 01:54:00 -0700 (Thu, 02 Dec 2004) | 2 lines
+Changed paths:
+ M /trunk/asymptote/cast.cc
+
+Fixed typo.
+
+------------------------------------------------------------------------
+r144 | jcbowman | 2004-12-01 09:56:39 -0700 (Wed, 01 Dec 2004) | 2 lines
+Changed paths:
+ D /trunk/asymptote/bison.patch
+ D /trunk/asymptote/flex.patch
+ A /trunk/asymptote/patches
+ A /trunk/asymptote/patches/bison.patch
+ A /trunk/asymptote/patches/flex.patch
+ A /trunk/asymptote/patches/gv-3.5.8-all.patch
+
+Patches for bison, flex, and gv-3.5.8 now in patches directory.
+
+------------------------------------------------------------------------
+r143 | jcbowman | 2004-12-01 09:52:27 -0700 (Wed, 01 Dec 2004) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/plain.asy
+
+Arrow and bars should always be drawn with solid linetype.
+
+------------------------------------------------------------------------
+r142 | jcbowman | 2004-11-30 17:50:49 -0700 (Tue, 30 Nov 2004) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/graph.asy
+ M /trunk/asymptote/base/plain.asy
+
+Changed dots(pair[]) to dot(pair[]); added graph(pair(real),real,real).
+
+------------------------------------------------------------------------
+r141 | jcbowman | 2004-11-30 14:03:29 -0700 (Tue, 30 Nov 2004) | 2 lines
+Changed paths:
+ M /trunk/asymptote/BUGS
+
+Fixed typo.
+
+------------------------------------------------------------------------
+r140 | jcbowman | 2004-11-30 13:53:16 -0700 (Tue, 30 Nov 2004) | 3 lines
+Changed paths:
+ M /trunk/asymptote/BUGS
+ M /trunk/asymptote/base/graph.asy
+ M /trunk/asymptote/base/graph3d.asy
+ M /trunk/asymptote/base/math.asy
+ M /trunk/asymptote/base/plain.asy
+ M /trunk/asymptote/builtin.cc
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/examples/centroidfg.asy
+ M /trunk/asymptote/examples/lever.asy
+ M /trunk/asymptote/examples/triads.asy
+ M /trunk/asymptote/examples/wheelanimation.asy
+
+Simplified dot drawing function, distinguished it from Dot product, and
+updated documentation and examples.
+
+------------------------------------------------------------------------
+r139 | jcbowman | 2004-11-30 08:00:14 -0700 (Tue, 30 Nov 2004) | 2 lines
+Changed paths:
+ M /trunk/asymptote/runtime.cc
+
+Added array diagnostics.
+
+------------------------------------------------------------------------
+r138 | jcbowman | 2004-11-29 01:29:29 -0700 (Mon, 29 Nov 2004) | 2 lines
+Changed paths:
+ M /trunk/asymptote/BUGS
+
+Added qualifier.
+
+------------------------------------------------------------------------
+r137 | jcbowman | 2004-11-29 01:20:52 -0700 (Mon, 29 Nov 2004) | 4 lines
+Changed paths:
+ M /trunk/asymptote/BUGS
+ M /trunk/asymptote/configure.ac
+ M /trunk/asymptote/main.cc
+ M /trunk/asymptote/settings.cc
+ M /trunk/asymptote/settings.h
+
+Resolved infinite import recursion bug [24Nov04] by using libsigsegv to
+distinguish between stack overflows and real segmentation violations
+(due to C++ programming errors).
+
+------------------------------------------------------------------------
+r136 | jcbowman | 2004-11-28 16:22:15 -0700 (Sun, 28 Nov 2004) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/plain.asy
+ M /trunk/asymptote/doc/diatom.asy
+
+Deferred drawing should respect clipping bounds.
+
+------------------------------------------------------------------------
+r135 | jcbowman | 2004-11-28 15:01:11 -0700 (Sun, 28 Nov 2004) | 3 lines
+Changed paths:
+ M /trunk/asymptote/base/graph.asy
+
+Removed obsolete label bbox code from xequals and yequals to make them work
+correctly.
+
+------------------------------------------------------------------------
+r134 | jcbowman | 2004-11-27 21:55:25 -0700 (Sat, 27 Nov 2004) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/plain.asy
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/doc/latexusage.tex
+
+Updated documentation.
+
+------------------------------------------------------------------------
+r133 | jcbowman | 2004-11-27 21:08:47 -0700 (Sat, 27 Nov 2004) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/plain.asy
+ M /trunk/asymptote/examples/centroidfg.asy
+ M /trunk/asymptote/examples/integraltest.asy
+ M /trunk/asymptote/examples/triads.asy
+ M /trunk/asymptote/examples/wheelanimation.asy
+
+Improved dot(): if dotsize not specified, use linewidth(pen)*dotfactor.
+
+------------------------------------------------------------------------
+r132 | jcbowman | 2004-11-27 21:02:04 -0700 (Sat, 27 Nov 2004) | 2 lines
+Changed paths:
+ M /trunk/asymptote/cast.cc
+
+Implement implicit cast from real to pen linewidth.
+
+------------------------------------------------------------------------
+r131 | jcbowman | 2004-11-27 21:01:28 -0700 (Sat, 27 Nov 2004) | 2 lines
+Changed paths:
+ M /trunk/asymptote/builtin.cc
+ M /trunk/asymptote/drawlabel.cc
+ M /trunk/asymptote/pen.h
+ M /trunk/asymptote/psfile.cc
+ M /trunk/asymptote/psfile.h
+ M /trunk/asymptote/runtime.cc
+ M /trunk/asymptote/runtime.h
+ M /trunk/asymptote/texfile.cc
+
+Cleaned up pen code.
+
+------------------------------------------------------------------------
+r130 | jcbowman | 2004-11-27 09:13:32 -0700 (Sat, 27 Nov 2004) | 2 lines
+Changed paths:
+ M /trunk/asymptote/drawlayer.h
+ M /trunk/asymptote/drawverbatim.h
+
+tex() not layer() should force label processing.
+
+------------------------------------------------------------------------
+r129 | jcbowman | 2004-11-26 18:23:49 -0700 (Fri, 26 Nov 2004) | 2 lines
+Changed paths:
+ M /trunk/asymptote/configure.ac
+
+Increment version to 0.54.
+
+------------------------------------------------------------------------
+r128 | jcbowman | 2004-11-26 17:19:53 -0700 (Fri, 26 Nov 2004) | 2 lines
+Changed paths:
+ A /trunk/asymptote/base/graph3d.asy
+ M /trunk/asymptote/base/math.asy
+ M /trunk/asymptote/doc/asymptote.texi
+ A /trunk/asymptote/examples/planes.asy
+
+Added preliminary 3d graphics routines & documentation.
+
+------------------------------------------------------------------------
+r127 | jcbowman | 2004-11-26 16:37:42 -0700 (Fri, 26 Nov 2004) | 2 lines
+Changed paths:
+ M /trunk/asymptote/BUGS
+
+Added Bug 24Nov04.
+
+------------------------------------------------------------------------
+r126 | jcbowman | 2004-11-26 16:01:19 -0700 (Fri, 26 Nov 2004) | 2 lines
+Changed paths:
+ M /trunk/asymptote/psfile.h
+
+Fixed transform bug (yx->xy) reported by Jacques.
+
+------------------------------------------------------------------------
+r125 | jcbowman | 2004-11-26 12:44:02 -0700 (Fri, 26 Nov 2004) | 2 lines
+Changed paths:
+ A /trunk/asymptote/doc/Makefile
+ M /trunk/asymptote/doc/asymptote.texi
+
+Makefile for doc directory.
+
+------------------------------------------------------------------------
+r124 | jcbowman | 2004-11-26 11:58:25 -0700 (Fri, 26 Nov 2004) | 2 lines
+Changed paths:
+ M /trunk/asymptote/BUGS
+ M /trunk/asymptote/Makefile.in
+ M /trunk/asymptote/base/math.asy
+ M /trunk/asymptote/base/plain.asy
+ M /trunk/asymptote/doc/asymptote.texi
+
+Math and documentation updates.
+
+------------------------------------------------------------------------
+r123 | jcbowman | 2004-11-25 21:22:39 -0700 (Thu, 25 Nov 2004) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/math.asy
+
+Fixed intersect(vector,vector,vector,vector);
+
+------------------------------------------------------------------------
+r122 | jcbowman | 2004-11-25 12:00:37 -0700 (Thu, 25 Nov 2004) | 2 lines
+Changed paths:
+ D /trunk/asymptote/ChangeLog
+ M /trunk/asymptote/path.h
+
+Handle out of bounds indices properly in straight(path,int).
+
+------------------------------------------------------------------------
+r121 | jcbowman | 2004-11-25 09:31:25 -0700 (Thu, 25 Nov 2004) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/math.asy
+
+Fixed intersect(vector,vector,vector,vector).
+
+------------------------------------------------------------------------
+r120 | jcbowman | 2004-11-24 22:21:41 -0700 (Wed, 24 Nov 2004) | 2 lines
+Changed paths:
+ M /trunk/asymptote/env.h
+ M /trunk/asymptote/genv.cc
+
+Avoid duplicate import messages when verbose > 1.
+
+------------------------------------------------------------------------
+r119 | jcbowman | 2004-11-23 12:27:50 -0700 (Tue, 23 Nov 2004) | 2 lines
+Changed paths:
+ M /trunk/asymptote/drawlayer.h
+
+Make layer() work also when there are no labels.
+
+------------------------------------------------------------------------
+r118 | jcbowman | 2004-11-23 11:41:35 -0700 (Tue, 23 Nov 2004) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/graph.asy
+ M /trunk/asymptote/base/math.asy
+ M /trunk/asymptote/base/plain.asy
+ M /trunk/asymptote/builtin.cc
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/runtime.cc
+ M /trunk/asymptote/runtime.h
+ D /trunk/asymptote/treetest.asy
+
+Fixed bbox function; added dot product for pairs and vectors.
+
+------------------------------------------------------------------------
+r117 | jcbowman | 2004-11-23 09:33:58 -0700 (Tue, 23 Nov 2004) | 2 lines
+Changed paths:
+ M /trunk/asymptote/builtin.cc
+ M /trunk/asymptote/builtin.h
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/runtime.cc
+ M /trunk/asymptote/runtime.h
+
+Added missing xor boolean binary operator.
+
+------------------------------------------------------------------------
+r116 | jcbowman | 2004-11-23 09:31:20 -0700 (Tue, 23 Nov 2004) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/plain.asy
+
+add(picture, picture) now adjusts userMin and userMax.
+
+------------------------------------------------------------------------
+r115 | jcbowman | 2004-11-21 16:31:02 -0700 (Sun, 21 Nov 2004) | 2 lines
+Changed paths:
+ M /trunk/asymptote/fileio.cc
+ M /trunk/asymptote/fileio.h
+
+Ignore attempts to close stdin and stdout.
+
+------------------------------------------------------------------------
+r114 | jcbowman | 2004-11-21 16:05:42 -0700 (Sun, 21 Nov 2004) | 2 lines
+Changed paths:
+ M /trunk/asymptote/runtime.cc
+
+Fixed nullFile.
+
+------------------------------------------------------------------------
+r113 | jcbowman | 2004-11-21 11:19:31 -0700 (Sun, 21 Nov 2004) | 2 lines
+Changed paths:
+ M /trunk/asymptote/Makefile.in
+ M /trunk/asymptote/configure.ac
+ M /trunk/asymptote/settings.cc
+
+Simplified configuration; documented GNU_GETOPT_H.
+
+------------------------------------------------------------------------
+r112 | jcbowman | 2004-11-21 10:41:27 -0700 (Sun, 21 Nov 2004) | 2 lines
+Changed paths:
+ M /trunk/asymptote/arrayop.h
+ M /trunk/asymptote/fileio.cc
+ M /trunk/asymptote/fileio.h
+ M /trunk/asymptote/runtime.cc
+
+renamed camp::stdout to camp::Stdout to make FreeBSD happy.
+
+------------------------------------------------------------------------
+r111 | jcbowman | 2004-11-21 10:10:22 -0700 (Sun, 21 Nov 2004) | 2 lines
+Changed paths:
+ M /trunk/asymptote/README
+
+Added reference to mailing list.
+
+------------------------------------------------------------------------
+r110 | jcbowman | 2004-11-21 10:05:10 -0700 (Sun, 21 Nov 2004) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.sty
+
+Removed email addresses.
+
+------------------------------------------------------------------------
+r109 | jcbowman | 2004-11-21 09:52:23 -0700 (Sun, 21 Nov 2004) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+
+Fixed formatting.
+
+------------------------------------------------------------------------
+r108 | jcbowman | 2004-11-21 09:36:15 -0700 (Sun, 21 Nov 2004) | 2 lines
+Changed paths:
+ M /trunk/asymptote/Makefile.in
+
+updated distclean
+
+------------------------------------------------------------------------
+r107 | jcbowman | 2004-11-21 01:39:36 -0700 (Sun, 21 Nov 2004) | 2 lines
+Changed paths:
+ M /trunk/asymptote/arrayop.h
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/fileio.cc
+ M /trunk/asymptote/fileio.h
+ M /trunk/asymptote/runtime.cc
+
+Fixed memory leaks.
+
+------------------------------------------------------------------------
+r106 | jcbowman | 2004-11-21 01:03:42 -0700 (Sun, 21 Nov 2004) | 2 lines
+Changed paths:
+ M /trunk/asymptote/picture.cc
+
+Fixed memory leak.
+
+------------------------------------------------------------------------
+r105 | jcbowman | 2004-11-20 23:29:49 -0700 (Sat, 20 Nov 2004) | 3 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+
+Readline library should be reasonably up-to-date (Version 4.3 and 5.0
+have both been tested; asy won't even compile with very old versions).
+
+------------------------------------------------------------------------
+r104 | jcbowman | 2004-11-20 23:20:56 -0700 (Sat, 20 Nov 2004) | 2 lines
+Changed paths:
+ A /trunk/asymptote/doc/version.texi.in
+
+Template used to extract texinfo version from configure.ac.
+
+------------------------------------------------------------------------
+r103 | jcbowman | 2004-11-20 23:19:58 -0700 (Sat, 20 Nov 2004) | 2 lines
+Changed paths:
+ M /trunk/asymptote/Makefile.in
+ M /trunk/asymptote/configure.ac
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/settings.cc
+
+More FreeBSD tweaks.
+
+------------------------------------------------------------------------
+r102 | jcbowman | 2004-11-20 23:19:17 -0700 (Sat, 20 Nov 2004) | 2 lines
+Changed paths:
+ M /trunk/asymptote/arrayop.h
+ M /trunk/asymptote/runtime.cc
+
+Revert stdout optimization.
+
+------------------------------------------------------------------------
+r101 | jcbowman | 2004-11-20 20:22:59 -0700 (Sat, 20 Nov 2004) | 2 lines
+Changed paths:
+ M /trunk/asymptote/README
+
+Fixed typo.
+
+------------------------------------------------------------------------
+r100 | jcbowman | 2004-11-20 20:21:09 -0700 (Sat, 20 Nov 2004) | 2 lines
+Changed paths:
+ M /trunk/asymptote/Makefile.in
+
+make install-all now depends on all
+
+------------------------------------------------------------------------
+r99 | jcbowman | 2004-11-20 18:46:41 -0700 (Sat, 20 Nov 2004) | 2 lines
+Changed paths:
+ M /trunk/asymptote/Makefile.in
+ M /trunk/asymptote/camp.l
+ M /trunk/asymptote/camp.y
+ M /trunk/asymptote/configure.ac
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/fpu.h
+ M /trunk/asymptote/main.cc
+ M /trunk/asymptote/settings.cc
+
+Port to FreeBSD 4.10-RELEASE-p2 with gcc34.
+
+------------------------------------------------------------------------
+r98 | jcbowman | 2004-11-20 14:51:57 -0700 (Sat, 20 Nov 2004) | 2 lines
+Changed paths:
+ A /trunk/asymptote/bison.patch
+ A /trunk/asymptote/flex.patch
+
+Patches for clean compilation under CXX and other compilers.
+
+------------------------------------------------------------------------
+r97 | jcbowman | 2004-11-20 11:51:31 -0700 (Sat, 20 Nov 2004) | 2 lines
+Changed paths:
+ M /trunk/asymptote/fpu.h
+ M /trunk/asymptote/path.h
+
+include tweaks
+
+------------------------------------------------------------------------
+r96 | jcbowman | 2004-11-20 11:00:20 -0700 (Sat, 20 Nov 2004) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+
+Menu updates.
+
+------------------------------------------------------------------------
+r95 | jcbowman | 2004-11-20 10:36:52 -0700 (Sat, 20 Nov 2004) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+
+Fixed up discussion of static vs. dynamic
+
+------------------------------------------------------------------------
+r94 | jcbowman | 2004-11-19 21:53:36 -0700 (Fri, 19 Nov 2004) | 2 lines
+Changed paths:
+ M /trunk/asymptote/arrayop.h
+ M /trunk/asymptote/fileio.cc
+ M /trunk/asymptote/fileio.h
+ M /trunk/asymptote/runtime.cc
+ M /trunk/asymptote/runtime.h
+
+Check if file is closed before doing any reads or writes.
+
+------------------------------------------------------------------------
+r93 | jcbowman | 2004-11-19 21:53:29 -0700 (Fri, 19 Nov 2004) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+
+Added sentence about linetype-adjustment based on arclength of path.
+
+------------------------------------------------------------------------
+r92 | jcbowman | 2004-11-19 15:29:52 -0700 (Fri, 19 Nov 2004) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/plain.asy
+ M /trunk/asymptote/doc/asymptote.sty
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/doc/latexusage.tex
+
+Default width of figures included with asymptote.sty is now 0.9\linewidth.
+
+------------------------------------------------------------------------
+r91 | hammera | 2004-11-19 15:24:25 -0700 (Fri, 19 Nov 2004) | 2 lines
+Changed paths:
+ M /trunk/asymptote/TODO
+
+*** empty log message ***
+
+------------------------------------------------------------------------
+r90 | jcbowman | 2004-11-19 15:13:03 -0700 (Fri, 19 Nov 2004) | 2 lines
+Changed paths:
+ M /trunk/asymptote/BUGS
+
+Bug 2004-17-11 fixed.
+
+------------------------------------------------------------------------
+r89 | hammera | 2004-11-19 13:50:59 -0700 (Fri, 19 Nov 2004) | 2 lines
+Changed paths:
+ A /trunk/asymptote/coder.cc
+ A /trunk/asymptote/coder.h
+ A /trunk/asymptote/coenv.cc
+ A /trunk/asymptote/coenv.h
+
+New classes from the env -> env and coder split.
+
+------------------------------------------------------------------------
+r88 | hammera | 2004-11-19 13:49:45 -0700 (Fri, 19 Nov 2004) | 3 lines
+Changed paths:
+ M /trunk/asymptote/Makefile.in
+ M /trunk/asymptote/absyn.cc
+ M /trunk/asymptote/absyn.h
+ M /trunk/asymptote/access.cc
+ M /trunk/asymptote/access.h
+ M /trunk/asymptote/base/plain.asy
+ M /trunk/asymptote/base/simplex.asy
+ M /trunk/asymptote/builtin.cc
+ M /trunk/asymptote/dec.cc
+ M /trunk/asymptote/dec.h
+ M /trunk/asymptote/drawfill.cc
+ M /trunk/asymptote/env.cc
+ M /trunk/asymptote/env.h
+ M /trunk/asymptote/exp.cc
+ M /trunk/asymptote/exp.h
+ M /trunk/asymptote/fileio.cc
+ M /trunk/asymptote/genv.cc
+ M /trunk/asymptote/genv.h
+ M /trunk/asymptote/import.h
+ M /trunk/asymptote/importaccess.h
+ M /trunk/asymptote/name.cc
+ M /trunk/asymptote/name.h
+ M /trunk/asymptote/newexp.cc
+ M /trunk/asymptote/newexp.h
+ M /trunk/asymptote/pathlist.cc
+ M /trunk/asymptote/stm.cc
+ M /trunk/asymptote/stm.h
+
+Split the env class into env and coder, and added coenv.
+Added "self-importing".
+
+------------------------------------------------------------------------
+r87 | jcbowman | 2004-11-19 12:29:35 -0700 (Fri, 19 Nov 2004) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/graph.asy
+ M /trunk/asymptote/doc/asymptote.sty
+ M /trunk/asymptote/doc/asymptote.texi
+
+Figures included via asymptote.sty are now fully independent; updated documentation.
+
+------------------------------------------------------------------------
+r86 | jcbowman | 2004-11-19 08:18:14 -0700 (Fri, 19 Nov 2004) | 3 lines
+Changed paths:
+ M /trunk/asymptote/BUGS
+ M /trunk/asymptote/base/graph.asy
+ M /trunk/asymptote/base/math.asy
+ M /trunk/asymptote/base/plain.asy
+ M /trunk/asymptote/builtin.cc
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/runtime.cc
+ M /trunk/asymptote/runtime.h
+
+Remove dependency of graph.asy on math.asy;
+added builtin real abs(pair) and int sgn(real) functions.
+
+------------------------------------------------------------------------
+r85 | jcbowman | 2004-11-18 22:26:45 -0700 (Thu, 18 Nov 2004) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/plain.asy
+ M /trunk/asymptote/doc/asymptote.texi
+
+Renamed includegraphics to include.
+
+------------------------------------------------------------------------
+r84 | jcbowman | 2004-11-18 15:50:06 -0700 (Thu, 18 Nov 2004) | 2 lines
+Changed paths:
+ A /trunk/asymptote/BUGS
+
+Added BUGS file.
+
+------------------------------------------------------------------------
+r83 | jcbowman | 2004-11-18 13:09:11 -0700 (Thu, 18 Nov 2004) | 2 lines
+Changed paths:
+ A /trunk/asymptote/drawlayer.h
+
+Added layer function.
+
+------------------------------------------------------------------------
+r82 | jcbowman | 2004-11-18 13:05:11 -0700 (Thu, 18 Nov 2004) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/plain.asy
+ M /trunk/asymptote/builtin.cc
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/drawelement.h
+ M /trunk/asymptote/drawverbatim.h
+ M /trunk/asymptote/picture.cc
+ M /trunk/asymptote/picture.h
+ M /trunk/asymptote/runtime.cc
+ M /trunk/asymptote/runtime.h
+ M /trunk/asymptote/settings.cc
+ M /trunk/asymptote/texfile.cc
+ M /trunk/asymptote/texfile.h
+
+Added layer and includegraphics functions.
+
+------------------------------------------------------------------------
+r81 | jcbowman | 2004-11-18 13:04:01 -0700 (Thu, 18 Nov 2004) | 2 lines
+Changed paths:
+ M /trunk/asymptote/Makefile.in
+
+Added install-all target.
+
+------------------------------------------------------------------------
+r80 | jcbowman | 2004-11-17 21:16:20 -0700 (Wed, 17 Nov 2004) | 2 lines
+Changed paths:
+ M /trunk/asymptote/types.cc
+
+Fixed typo.
+
+------------------------------------------------------------------------
+r79 | jcbowman | 2004-11-17 10:54:37 -0700 (Wed, 17 Nov 2004) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/math.asy
+ M /trunk/asymptote/drawelement.h
+
+Minor optimizations.
+
+------------------------------------------------------------------------
+r78 | jcbowman | 2004-11-16 22:32:01 -0700 (Tue, 16 Nov 2004) | 2 lines
+Changed paths:
+ M /trunk/asymptote/camp.l
+ M /trunk/asymptote/camp.y
+ M /trunk/asymptote/dec.cc
+ M /trunk/asymptote/doc/asymptote.texi
+
+Removed unused dynamic keyword.
+
+------------------------------------------------------------------------
+r77 | jcbowman | 2004-11-16 15:25:06 -0700 (Tue, 16 Nov 2004) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/guide.cc
+ M /trunk/asymptote/path.cc
+
+Fixed bug: (path) (nullpath--(0,0)--(100,0)--cycle) was missing final node.
+
+------------------------------------------------------------------------
+r76 | jcbowman | 2004-11-15 11:10:37 -0700 (Mon, 15 Nov 2004) | 2 lines
+Changed paths:
+ M /trunk/asymptote/Makefile.in
+ M /trunk/asymptote/doc/asymptote.texi
+
+Switched from jpg to png images.
+
+------------------------------------------------------------------------
+r75 | jcbowman | 2004-11-14 23:23:59 -0700 (Sun, 14 Nov 2004) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/simplex.asy
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/genv.cc
+
+Make variables in file-level modules dynamic by default, like everywhere else.
+
+------------------------------------------------------------------------
+r74 | jcbowman | 2004-11-14 22:52:36 -0700 (Sun, 14 Nov 2004) | 2 lines
+Changed paths:
+ M /trunk/asymptote/Makefile.in
+
+Support old versions of install-info.
+
+------------------------------------------------------------------------
+r73 | hammera | 2004-11-14 19:17:32 -0700 (Sun, 14 Nov 2004) | 2 lines
+Changed paths:
+ M /trunk/asymptote/access.cc
+ M /trunk/asymptote/examples/dragon.asy
+
+Changed error message for static vs. dynamic errors.
+
+------------------------------------------------------------------------
+r72 | jcbowman | 2004-11-14 17:48:09 -0700 (Sun, 14 Nov 2004) | 3 lines
+Changed paths:
+ M /trunk/asymptote/base/plain.asy
+ M /trunk/asymptote/doc/asymptote.sty
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/examples/dragon.asy
+
+Moved Legend[] legend inside picture structure; shipout(frame) now adds
+gui() entries and legend; shipout always deconstructs its picture argument.
+
+------------------------------------------------------------------------
+r71 | jcbowman | 2004-11-14 17:45:13 -0700 (Sun, 14 Nov 2004) | 2 lines
+Changed paths:
+ M /trunk/asymptote/runtime.cc
+
+Fixed compiler warning message if HAVE_LIBFFTW3 is undefined.
+
+------------------------------------------------------------------------
+r70 | jcbowman | 2004-11-14 17:43:30 -0700 (Sun, 14 Nov 2004) | 2 lines
+Changed paths:
+ M /trunk/asymptote/stack.h
+
+removed unnecessary vm:: qualifier
+
+------------------------------------------------------------------------
+r69 | hammera | 2004-11-14 17:23:21 -0700 (Sun, 14 Nov 2004) | 2 lines
+Changed paths:
+ M /trunk/asymptote/cast.cc
+ M /trunk/asymptote/cast.h
+ M /trunk/asymptote/entry.cc
+ M /trunk/asymptote/table.h
+ M /trunk/asymptote/types.cc
+ M /trunk/asymptote/types.h
+
+Refactored the equivalent type function.
+
+------------------------------------------------------------------------
+r68 | jcbowman | 2004-11-14 17:12:55 -0700 (Sun, 14 Nov 2004) | 2 lines
+Changed paths:
+ M /trunk/asymptote/pipestream.h
+ M /trunk/asymptote/util.cc
+
+Added unistd.h include.
+
+------------------------------------------------------------------------
+r67 | jcbowman | 2004-11-12 18:55:36 -0700 (Fri, 12 Nov 2004) | 2 lines
+Changed paths:
+ M /trunk/asymptote/ChangeLog
+ M /trunk/asymptote/configure.ac
+ M /trunk/asymptote/doc/asymptote.texi
+
+Increment version.
+
+------------------------------------------------------------------------
+r66 | jcbowman | 2004-11-12 15:19:44 -0700 (Fri, 12 Nov 2004) | 2 lines
+Changed paths:
+ A /trunk/asymptote/ChangeLog
+
+release: Version 0.52
+
+------------------------------------------------------------------------
+r65 | jcbowman | 2004-11-12 14:59:54 -0700 (Fri, 12 Nov 2004) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/doc/latexusage.tex
+
+Made import graph local to each figure in latexusage.
+
+------------------------------------------------------------------------
+r64 | jcbowman | 2004-11-12 14:03:05 -0700 (Fri, 12 Nov 2004) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/diatom.asy
+
+added call to crop
+
+------------------------------------------------------------------------
+r63 | jcbowman | 2004-11-12 13:51:33 -0700 (Fri, 12 Nov 2004) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+
+Documentation updates
+
+------------------------------------------------------------------------
+r62 | jcbowman | 2004-11-12 11:54:34 -0700 (Fri, 12 Nov 2004) | 3 lines
+Changed paths:
+ M /trunk/asymptote/Makefile.in
+ M /trunk/asymptote/base/graph.asy
+ A /trunk/asymptote/base/latin1.asy
+ M /trunk/asymptote/camp.y
+ M /trunk/asymptote/doc/asymptote.texi
+
+Allow qualification of variables in imported modules with (quoted)
+nonalphanumeric names; added ISO 8859-1 support (latin1).
+
+------------------------------------------------------------------------
+r61 | jcbowman | 2004-11-12 00:19:36 -0700 (Fri, 12 Nov 2004) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/graph.asy
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/doc/loggraph.asy
+ M /trunk/asymptote/doc/parametricgraph.asy
+
+Improved xlimits, ylimits, limits routines. Added crop routine.
+
+------------------------------------------------------------------------
+r60 | jcbowman | 2004-11-11 23:18:59 -0700 (Thu, 11 Nov 2004) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/graph.asy
+ M /trunk/asymptote/base/plain.asy
+ M /trunk/asymptote/doc/asymptote.texi
+
+Fixed various graph scaling problems.
+
+------------------------------------------------------------------------
+r59 | jcbowman | 2004-11-10 10:49:27 -0700 (Wed, 10 Nov 2004) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+
+minor formatting changes
+
+------------------------------------------------------------------------
+r58 | jcbowman | 2004-11-10 10:32:05 -0700 (Wed, 10 Nov 2004) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/graph.asy
+ M /trunk/asymptote/base/plain.asy
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/doc/diatom.asy
+
+Encapsulated global graph scaling variables within picture; updated documentation.
+
+------------------------------------------------------------------------
+r57 | jcbowman | 2004-11-09 11:45:09 -0700 (Tue, 09 Nov 2004) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+
+fixed missing word on first page
+
+------------------------------------------------------------------------
+r56 | jcbowman | 2004-11-09 11:44:22 -0700 (Tue, 09 Nov 2004) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/plain.asy
+
+Added dots(pair); fixed division by zero in arrowhead for degenerate paths.
+
+------------------------------------------------------------------------
+r55 | jcbowman | 2004-11-09 00:55:45 -0700 (Tue, 09 Nov 2004) | 2 lines
+Changed paths:
+ M /trunk/asymptote/configure.ac
+ M /trunk/asymptote/doc/asymptote.texi
+
+Increment version.
+
+------------------------------------------------------------------------
+r54 | jcbowman | 2004-11-08 23:08:08 -0700 (Mon, 08 Nov 2004) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+
+Missing description
+
+------------------------------------------------------------------------
+r53 | jcbowman | 2004-11-08 22:54:35 -0700 (Mon, 08 Nov 2004) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+
+fixed missing @code
+
+------------------------------------------------------------------------
+r52 | jcbowman | 2004-11-08 22:34:47 -0700 (Mon, 08 Nov 2004) | 2 lines
+Changed paths:
+ D /trunk/asymptote/examples/logo.asy
+
+moved to doc/
+
+------------------------------------------------------------------------
+r51 | jcbowman | 2004-11-08 22:28:34 -0700 (Mon, 08 Nov 2004) | 2 lines
+Changed paths:
+ M /trunk/asymptote/Makefile.in
+
+Fixed problems with installation of base files from cvs.
+
+------------------------------------------------------------------------
+r50 | jcbowman | 2004-11-08 22:10:40 -0700 (Mon, 08 Nov 2004) | 2 lines
+Changed paths:
+ M /trunk/asymptote
+ M /trunk/asymptote/.cvsignore
+ M /trunk/asymptote/doc
+ A /trunk/asymptote/doc/.cvsignore
+ M /trunk/asymptote/examples
+ M /trunk/asymptote/examples/.cvsignore
+
+updated cvsignore entries
+
+------------------------------------------------------------------------
+r49 | jcbowman | 2004-11-08 21:50:37 -0700 (Mon, 08 Nov 2004) | 2 lines
+Changed paths:
+ M /trunk/asymptote/Makefile.in
+
+Added optimization flags.
+
+------------------------------------------------------------------------
+r48 | jcbowman | 2004-11-08 21:50:04 -0700 (Mon, 08 Nov 2004) | 2 lines
+Changed paths:
+ M /trunk/asymptote/Makefile.in
+ M /trunk/asymptote/doc/asymptote.texi
+
+Added optimization flags.
+
+------------------------------------------------------------------------
+r47 | jcbowman | 2004-11-08 21:37:03 -0700 (Mon, 08 Nov 2004) | 2 lines
+Changed paths:
+ M /trunk/asymptote/Makefile.in
+ D /trunk/asymptote/asy-mode.el
+ D /trunk/asymptote/asy.vim
+ A /trunk/asymptote/base/asy-mode.el
+ A /trunk/asymptote/base/asy.vim
+ M /trunk/asymptote/doc/asymptote.texi
+
+Added instructions for asy-mode.el and asy.vim.
+
+------------------------------------------------------------------------
+r46 | jcbowman | 2004-11-08 17:48:55 -0700 (Mon, 08 Nov 2004) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/unicode.asy
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/doc/diatom.asy
+ M /trunk/asymptote/doc/diatom.csv
+
+unicode updates
+
+------------------------------------------------------------------------
+r45 | jcbowman | 2004-11-08 12:18:05 -0700 (Mon, 08 Nov 2004) | 2 lines
+Changed paths:
+ M /trunk/asymptote/Makefile.in
+
+Corrected local value of ASYMPTOTE_DIR
+
+------------------------------------------------------------------------
+r44 | jcbowman | 2004-11-08 11:22:32 -0700 (Mon, 08 Nov 2004) | 2 lines
+Changed paths:
+ M /trunk/asymptote/runtime.cc
+
+Fixed warning messages.
+
+------------------------------------------------------------------------
+r43 | jcbowman | 2004-11-08 11:11:03 -0700 (Mon, 08 Nov 2004) | 2 lines
+Changed paths:
+ M /trunk/asymptote/configure.ac
+ M /trunk/asymptote/doc/asymptote.texi
+
+Update cvs version
+
+------------------------------------------------------------------------
+r42 | jcbowman | 2004-11-08 11:06:53 -0700 (Mon, 08 Nov 2004) | 2 lines
+Changed paths:
+ A /trunk/asymptote/doc/logo.asy
+
+Asymptote logo
+
+------------------------------------------------------------------------
+r41 | jcbowman | 2004-11-08 11:03:15 -0700 (Mon, 08 Nov 2004) | 2 lines
+Changed paths:
+ M /trunk/asymptote/README
+ M /trunk/asymptote/doc/asymptote.texi
+
+Updated README and URL.
+
+------------------------------------------------------------------------
+r40 | jcbowman | 2004-11-08 10:52:02 -0700 (Mon, 08 Nov 2004) | 2 lines
+Changed paths:
+ A /trunk/asymptote/doc/latexusage.tex
+
+Example of latex usage.
+
+------------------------------------------------------------------------
+r39 | jcbowman | 2004-11-08 10:39:13 -0700 (Mon, 08 Nov 2004) | 2 lines
+Changed paths:
+ A /trunk/asymptote/examples/progrid.asy
+
+displayed equation example
+
+------------------------------------------------------------------------
+r38 | jcbowman | 2004-11-08 10:35:58 -0700 (Mon, 08 Nov 2004) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+
+updates to localwords
+
+------------------------------------------------------------------------
+r37 | jcbowman | 2004-11-08 10:31:39 -0700 (Mon, 08 Nov 2004) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+
+typo fixed
+
+------------------------------------------------------------------------
+r36 | jcbowman | 2004-11-08 10:28:23 -0700 (Mon, 08 Nov 2004) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+
+Final documentation updates.
+
+------------------------------------------------------------------------
+r35 | jcbowman | 2004-11-08 10:23:09 -0700 (Mon, 08 Nov 2004) | 2 lines
+Changed paths:
+ M /trunk/asymptote/Makefile.in
+
+make install-man no longer does a make man
+
+------------------------------------------------------------------------
+r34 | jcbowman | 2004-11-08 10:21:30 -0700 (Mon, 08 Nov 2004) | 2 lines
+Changed paths:
+ M /trunk/asymptote/Makefile.in
+ M /trunk/asymptote/access.cc
+ D /trunk/asymptote/asymptote.sty
+ M /trunk/asymptote/dec.cc
+ A /trunk/asymptote/doc/asymptote.sty
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/doc/diatom.asy
+ A /trunk/asymptote/doc/diatom.csv
+ M /trunk/asymptote/errors
+ D /trunk/asymptote/examples/diatom.asy
+ D /trunk/asymptote/examples/diatom.csv
+ D /trunk/asymptote/examples/latexusage.tex
+ M /trunk/asymptote/exp.cc
+ M /trunk/asymptote/genv.cc
+ M /trunk/asymptote/name.cc
+ M /trunk/asymptote/newexp.cc
+ M /trunk/asymptote/record.h
+ M /trunk/asymptote/settings.cc
+ M /trunk/asymptote/types.cc
+ M /trunk/asymptote/wce
+
+Final tweaks before release.
+
+------------------------------------------------------------------------
+r33 | jcbowman | 2004-11-07 23:24:38 -0700 (Sun, 07 Nov 2004) | 2 lines
+Changed paths:
+ M /trunk/asymptote/Makefile.in
+ M /trunk/asymptote/base/plain.asy
+ M /trunk/asymptote/drawlabel.cc
+
+Updates to facilitate building info pages and figures.
+
+------------------------------------------------------------------------
+r32 | jcbowman | 2004-11-07 23:23:30 -0700 (Sun, 07 Nov 2004) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+ A /trunk/asymptote/doc/bezier.asy
+ A /trunk/asymptote/doc/bigsquare.asy
+ A /trunk/asymptote/doc/datagraph.asy
+ A /trunk/asymptote/doc/diagonal.asy
+ A /trunk/asymptote/doc/diatom.asy
+ A /trunk/asymptote/doc/exp.asy
+ A /trunk/asymptote/doc/generalaxis.asy
+ A /trunk/asymptote/doc/lineargraph.asy
+ A /trunk/asymptote/doc/linetype.asy
+ A /trunk/asymptote/doc/loggraph.asy
+ A /trunk/asymptote/doc/parametricgraph.asy
+ A /trunk/asymptote/doc/quartercircle.asy
+ A /trunk/asymptote/doc/square.asy
+
+Updated documentation.
+
+------------------------------------------------------------------------
+r31 | jcbowman | 2004-11-07 22:22:17 -0700 (Sun, 07 Nov 2004) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+
+Updated documentation
+
+------------------------------------------------------------------------
+r30 | jcbowman | 2004-11-07 22:05:05 -0700 (Sun, 07 Nov 2004) | 2 lines
+Changed paths:
+ M /trunk/asymptote/settings.cc
+
+Fixed interactive mode.
+
+------------------------------------------------------------------------
+r29 | jcbowman | 2004-11-07 16:02:25 -0700 (Sun, 07 Nov 2004) | 2 lines
+Changed paths:
+ A /trunk/asymptote/examples/diatom.asy
+ A /trunk/asymptote/examples/diatom.csv
+
+Example of multiple data graphs with secondary axis.
+
+------------------------------------------------------------------------
+r28 | jcbowman | 2004-11-07 15:32:44 -0700 (Sun, 07 Nov 2004) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+
+Fixed menus.
+
+------------------------------------------------------------------------
+r27 | jcbowman | 2004-11-07 15:31:19 -0700 (Sun, 07 Nov 2004) | 2 lines
+Changed paths:
+ M /trunk/asymptote/TODO
+ M /trunk/asymptote/asymptote.sty
+ M /trunk/asymptote/builtin.cc
+ M /trunk/asymptote/drawlabel.cc
+ M /trunk/asymptote/drawlabel.h
+ M /trunk/asymptote/main.cc
+ M /trunk/asymptote/runtime.cc
+ M /trunk/asymptote/runtime.h
+ M /trunk/asymptote/settings.cc
+ M /trunk/asymptote/settings.h
+
+Added a reset() function to restore settings to startup defaults.
+
+------------------------------------------------------------------------
+r26 | jcbowman | 2004-11-07 15:28:30 -0700 (Sun, 07 Nov 2004) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/simplex.asy
+
+Formatting of comments.
+
+------------------------------------------------------------------------
+r25 | jcbowman | 2004-11-07 15:27:32 -0700 (Sun, 07 Nov 2004) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+
+Documentation updates.
+
+------------------------------------------------------------------------
+r24 | jcbowman | 2004-11-07 00:08:29 -0700 (Sun, 07 Nov 2004) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/plain.asy
+ M /trunk/asymptote/builtin.cc
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/runtime.cc
+ M /trunk/asymptote/runtime.h
+
+Added missing functions; removed pt from plain.asy; updated documentation
+
+------------------------------------------------------------------------
+r23 | jcbowman | 2004-11-05 10:16:40 -0700 (Fri, 05 Nov 2004) | 2 lines
+Changed paths:
+ A /trunk/asymptote/LICENSE
+ M /trunk/asymptote/doc/asymptote.texi
+
+Added GNU public LICENSE.
+
+------------------------------------------------------------------------
+r22 | jcbowman | 2004-11-05 10:13:47 -0700 (Fri, 05 Nov 2004) | 2 lines
+Changed paths:
+ M /trunk/asymptote/base/plain.asy
+ M /trunk/asymptote/doc/asymptote.texi
+
+Documentation updates.
+
+------------------------------------------------------------------------
+r21 | jcbowman | 2004-11-04 23:37:35 -0700 (Thu, 04 Nov 2004) | 2 lines
+Changed paths:
+ M /trunk/asymptote/README
+ M /trunk/asymptote/base/plain.asy
+ M /trunk/asymptote/builtin.cc
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/fileio.h
+
+Updated documentation.
+
+------------------------------------------------------------------------
+r20 | jcbowman | 2004-11-03 23:45:40 -0700 (Wed, 03 Nov 2004) | 2 lines
+Changed paths:
+ M /trunk/asymptote/README
+ M /trunk/asymptote/doc/asymptote.texi
+ M /trunk/asymptote/runtime.cc
+
+Documentation updates.
+
+------------------------------------------------------------------------
+r19 | jcbowman | 2004-11-02 22:20:51 -0700 (Tue, 02 Nov 2004) | 2 lines
+Changed paths:
+ M /trunk/asymptote/runtime.cc
+
+Allow negative array indices in arrayIntArray as in arrayRead and arrayWrite.
+
+------------------------------------------------------------------------
+r18 | jcbowman | 2004-11-02 22:13:26 -0700 (Tue, 02 Nov 2004) | 3 lines
+Changed paths:
+ M /trunk/asymptote/runtime.cc
+
+Allow assignment to array indices [-len,-1];
+handle negative array indices in sequence routines.
+
+------------------------------------------------------------------------
+r17 | jcbowman | 2004-11-02 12:10:24 -0700 (Tue, 02 Nov 2004) | 2 lines
+Changed paths:
+ M /trunk/asymptote/pen.h
+
+Added missing pen transformation code.
+
+------------------------------------------------------------------------
+r16 | jcbowman | 2004-11-01 10:23:54 -0700 (Mon, 01 Nov 2004) | 2 lines
+Changed paths:
+ M /trunk/asymptote/doc/asymptote.texi
+ D /trunk/asymptote/test.asy
+
+minor updates
+
+------------------------------------------------------------------------
+r15 | jcbowman | 2004-10-31 22:27:35 -0700 (Sun, 31 Oct 2004) | 2 lines
+Changed paths:
+ M /trunk/asymptote/configure.ac
+ M /trunk/asymptote/doc/asymptote.texi
+
+Check for boost header files; updated documentation.
+
+------------------------------------------------------------------------
+r14 | jcbowman | 2004-10-28 23:04:37 -0600 (Thu, 28 Oct 2004) | 2 lines
+Changed paths:
+ M /trunk/asymptote/README
+ M /trunk/asymptote/doc/asymptote.texi
+
+Updated documentation.
+
+------------------------------------------------------------------------
+r13 | jcbowman | 2004-10-28 23:04:20 -0600 (Thu, 28 Oct 2004) | 2 lines
+Changed paths:
+ M /trunk/asymptote/picture.cc
+
+Make -O work when dvips isn't used.
+
+------------------------------------------------------------------------
+r12 | jcbowman | 2004-10-28 15:26:57 -0600 (Thu, 28 Oct 2004) | 2 lines
+Changed paths:
+ A /trunk/asymptote/examples/logo.asy
+
+Sean Healy's logo implemented in Asymptote.
+
+------------------------------------------------------------------------
+r11 | jcbowman | 2004-10-26 09:05:04 -0600 (Tue, 26 Oct 2004) | 2 lines
+Changed paths:
+ A /trunk/asymptote/doc
+ A /trunk/asymptote/doc/asymptote.texi
+
+Initial version.
+
+------------------------------------------------------------------------
+r10 | jcbowman | 2004-10-26 07:38:06 -0600 (Tue, 26 Oct 2004) | 2 lines
+Changed paths:
+ M /trunk/asymptote
+ D /trunk/asymptote/.asy_history
+ M /trunk/asymptote/.cvsignore
+
+Removed unwanted cvs files.
+
+------------------------------------------------------------------------
+r9 | jcbowman | 2004-10-26 07:31:01 -0600 (Tue, 26 Oct 2004) | 2 lines
+Changed paths:
+ M /trunk/asymptote/configure.ac
+
+Set version = 0.50.
+
+------------------------------------------------------------------------
+r8 | jcbowman | 2004-10-26 07:29:34 -0600 (Tue, 26 Oct 2004) | 2 lines
+Changed paths:
+ M /trunk/asymptote/runtime.cc
+
+Fixed warning message if HAVE_STRTIME == 0
+
+------------------------------------------------------------------------
+r3 | jcbowman | 2004-10-26 07:27:12 -0600 (Tue, 26 Oct 2004) | 2 lines
+Changed paths:
+ A /trunk/asymptote
+ A /trunk/asymptote/.asy_history
+ A /trunk/asymptote/.cvsignore
+ A /trunk/asymptote/Compile
+ A /trunk/asymptote/Makefile.in
+ A /trunk/asymptote/README
+ A /trunk/asymptote/TODO
+ A /trunk/asymptote/absyn.cc
+ A /trunk/asymptote/absyn.h
+ A /trunk/asymptote/access.cc
+ A /trunk/asymptote/access.h
+ A /trunk/asymptote/angle.h
+ A /trunk/asymptote/arrayop.h
+ A /trunk/asymptote/asy-mode.el
+ A /trunk/asymptote/asy.vim
+ A /trunk/asymptote/asymptote.sty
+ A /trunk/asymptote/autogen.sh
+ A /trunk/asymptote/base
+ A /trunk/asymptote/base/graph.asy
+ A /trunk/asymptote/base/math.asy
+ A /trunk/asymptote/base/plain.asy
+ A /trunk/asymptote/base/simplex.asy
+ A /trunk/asymptote/base/stats.asy
+ A /trunk/asymptote/base/tree.asy
+ A /trunk/asymptote/base/unicode.asy
+ A /trunk/asymptote/bbox.h
+ A /trunk/asymptote/builtin.cc
+ A /trunk/asymptote/builtin.h
+ A /trunk/asymptote/camp.l
+ A /trunk/asymptote/camp.y
+ A /trunk/asymptote/camperror.cc
+ A /trunk/asymptote/camperror.h
+ A /trunk/asymptote/cast.cc
+ A /trunk/asymptote/cast.h
+ A /trunk/asymptote/configure.ac
+ A /trunk/asymptote/dec.cc
+ A /trunk/asymptote/dec.h
+ A /trunk/asymptote/drawclipbegin.h
+ A /trunk/asymptote/drawclipend.h
+ A /trunk/asymptote/drawelement.h
+ A /trunk/asymptote/drawfill.cc
+ A /trunk/asymptote/drawfill.h
+ A /trunk/asymptote/drawlabel.cc
+ A /trunk/asymptote/drawlabel.h
+ A /trunk/asymptote/drawpath.cc
+ A /trunk/asymptote/drawpath.h
+ A /trunk/asymptote/drawverbatim.h
+ A /trunk/asymptote/entry.cc
+ A /trunk/asymptote/entry.h
+ A /trunk/asymptote/env.cc
+ A /trunk/asymptote/env.h
+ A /trunk/asymptote/errormsg.cc
+ A /trunk/asymptote/errormsg.h
+ A /trunk/asymptote/errors
+ A /trunk/asymptote/errortest.asy
+ A /trunk/asymptote/examples
+ A /trunk/asymptote/examples/.cvsignore
+ A /trunk/asymptote/examples/Pythagoras.asy
+ A /trunk/asymptote/examples/cardiod.asy
+ A /trunk/asymptote/examples/centroidfg.asy
+ A /trunk/asymptote/examples/cos2theta.asy
+ A /trunk/asymptote/examples/dragon.asy
+ A /trunk/asymptote/examples/equilchord.asy
+ A /trunk/asymptote/examples/exp.asy
+ A /trunk/asymptote/examples/fjortoft.asy
+ A /trunk/asymptote/examples/integraltest.asy
+ A /trunk/asymptote/examples/latexusage.tex
+ A /trunk/asymptote/examples/lever.asy
+ A /trunk/asymptote/examples/log.asy
+ A /trunk/asymptote/examples/lowint.asy
+ A /trunk/asymptote/examples/lowupint.asy
+ A /trunk/asymptote/examples/sacone.asy
+ A /trunk/asymptote/examples/sin1x.asy
+ A /trunk/asymptote/examples/spiral.asy
+ A /trunk/asymptote/examples/spring.asy
+ A /trunk/asymptote/examples/spring0.asy
+ A /trunk/asymptote/examples/spring2.asy
+ A /trunk/asymptote/examples/sqrtx01.asy
+ A /trunk/asymptote/examples/tanh.asy
+ A /trunk/asymptote/examples/triads.asy
+ A /trunk/asymptote/examples/upint.asy
+ A /trunk/asymptote/examples/venn.asy
+ A /trunk/asymptote/examples/wheelanimation.asy
+ A /trunk/asymptote/examples/workcone.asy
+ A /trunk/asymptote/examples/xsin1x.asy
+ A /trunk/asymptote/examples/yingyang.asy
+ A /trunk/asymptote/exp.cc
+ A /trunk/asymptote/exp.h
+ A /trunk/asymptote/fftw++.cc
+ A /trunk/asymptote/fftw++.h
+ A /trunk/asymptote/fileio.cc
+ A /trunk/asymptote/fileio.h
+ A /trunk/asymptote/fpu.h
+ A /trunk/asymptote/frame.h
+ A /trunk/asymptote/genv.cc
+ A /trunk/asymptote/genv.h
+ A /trunk/asymptote/guide.cc
+ A /trunk/asymptote/guide.h
+ A /trunk/asymptote/guideflags.h
+ A /trunk/asymptote/import.cc
+ A /trunk/asymptote/import.h
+ A /trunk/asymptote/importaccess.h
+ A /trunk/asymptote/inst.cc
+ A /trunk/asymptote/inst.h
+ A /trunk/asymptote/install-sh
+ A /trunk/asymptote/interact.cc
+ A /trunk/asymptote/interact.h
+ A /trunk/asymptote/knotlist.cc
+ A /trunk/asymptote/knotlist.h
+ A /trunk/asymptote/main.cc
+ A /trunk/asymptote/name.cc
+ A /trunk/asymptote/name.h
+ A /trunk/asymptote/newexp.cc
+ A /trunk/asymptote/newexp.h
+ A /trunk/asymptote/pair.h
+ A /trunk/asymptote/path.cc
+ A /trunk/asymptote/path.h
+ A /trunk/asymptote/pathlist.cc
+ A /trunk/asymptote/pathlist.h
+ A /trunk/asymptote/pen.h
+ A /trunk/asymptote/picture.cc
+ A /trunk/asymptote/picture.h
+ A /trunk/asymptote/pipestream.h
+ A /trunk/asymptote/pool.cc
+ A /trunk/asymptote/pool.h
+ A /trunk/asymptote/pow.h
+ A /trunk/asymptote/psfile.cc
+ A /trunk/asymptote/psfile.h
+ A /trunk/asymptote/record.cc
+ A /trunk/asymptote/record.h
+ A /trunk/asymptote/runtime.cc
+ A /trunk/asymptote/runtime.h
+ A /trunk/asymptote/settings.cc
+ A /trunk/asymptote/settings.h
+ A /trunk/asymptote/simpson.cc
+ A /trunk/asymptote/stack.cc
+ A /trunk/asymptote/stack.h
+ A /trunk/asymptote/stm.cc
+ A /trunk/asymptote/stm.h
+ A /trunk/asymptote/symbol.cc
+ A /trunk/asymptote/symbol.h
+ A /trunk/asymptote/table.h
+ A /trunk/asymptote/test.asy
+ A /trunk/asymptote/texfile.cc
+ A /trunk/asymptote/texfile.h
+ A /trunk/asymptote/transform.h
+ A /trunk/asymptote/treetest.asy
+ A /trunk/asymptote/types.cc
+ A /trunk/asymptote/types.h
+ A /trunk/asymptote/util.cc
+ A /trunk/asymptote/util.h
+ A /trunk/asymptote/wce
+ A /trunk/asymptote/xasy
+ A /trunk/asymptote/xstream.h
+
+Initial revision
+
+------------------------------------------------------------------------
diff --git a/Build/source/utils/asymptote/Compile b/Build/source/utils/asymptote/Compile
new file mode 100644
index 00000000000..e7a9e237a4d
--- /dev/null
+++ b/Build/source/utils/asymptote/Compile
@@ -0,0 +1,10 @@
+MAGIC=magic # Hide asy rule from Makefile.
+include Makefile
+
+asy: $(FILES:=.o)
+ $(CXX) $(OPTS) -o $(NAME) $(FILES:=.o) $(LIBS)
+
+msdos: $(FILES:=.o) asy.o
+ $(CXX) $(OPTS) -o $(NAME) $(FILES:=.o) asy.o $(LIBS)
+
+include $(FILES:=.d)
diff --git a/Build/source/utils/asymptote/Delaunay.cc b/Build/source/utils/asymptote/Delaunay.cc
new file mode 100644
index 00000000000..3e9e5507f21
--- /dev/null
+++ b/Build/source/utils/asymptote/Delaunay.cc
@@ -0,0 +1,212 @@
+// Robust version of Gilles Dumoulin's C++ port of Paul Bourke's
+// triangulation code available from
+// http://astronomy.swin.edu.au/~pbourke/papers/triangulate
+// Used with permission of Paul Bourke.
+// Segmentation fault and numerical robustness improvements by John C. Bowman
+
+#include <cassert>
+#include "Delaunay.h"
+#include "predicates.h"
+
+inline double max(double a, double b)
+{
+ return (a > b) ? a : b;
+}
+
+int XYZCompare(const void *v1, const void *v2)
+{
+ double x1=((XYZ*)v1)->p[0];
+ double x2=((XYZ*)v2)->p[0];
+ if(x1 < x2)
+ return(-1);
+ else if(x1 > x2)
+ return(1);
+ else
+ return(0);
+}
+
+inline double hypot2(double *x)
+{
+ return x[0]*x[0]+x[1]*x[1];
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// Triangulate():
+// Triangulation subroutine
+// Takes as input NV vertices in array pxyz
+// Returned is a list of ntri triangular faces in the array v
+// These triangles are arranged in a consistent clockwise order.
+// The triangle array v should be allocated to 4 * nv
+// The vertex array pxyz must be big enough to hold 3 additional points.
+// By default, the array pxyz is automatically presorted and postsorted.
+///////////////////////////////////////////////////////////////////////////////
+
+Int Triangulate(Int nv, XYZ pxyz[], ITRIANGLE v[], Int &ntri,
+ bool presort, bool postsort)
+{
+ Int emax = 200;
+
+ if(presort) qsort(pxyz,nv,sizeof(XYZ),XYZCompare);
+ else postsort=false;
+
+/* Allocate memory for the completeness list, flag for each triangle */
+ Int trimax = 4 * nv;
+ Int *complete = new Int[trimax];
+/* Allocate memory for the edge list */
+ IEDGE *edges = new IEDGE[emax];
+/*
+ Find the maximum and minimum vertex bounds.
+ This is to allow calculation of the bounding triangle
+*/
+ double xmin = pxyz[0].p[0];
+ double ymin = pxyz[0].p[1];
+ double xmax = xmin;
+ double ymax = ymin;
+ for(Int i = 1; i < nv; i++) {
+ XYZ *pxyzi=pxyz+i;
+ double x=pxyzi->p[0];
+ double y=pxyzi->p[1];
+ if (x < xmin) xmin = x;
+ if (x > xmax) xmax = x;
+ if (y < ymin) ymin = y;
+ if (y > ymax) ymax = y;
+ }
+ double dx = xmax - xmin;
+ double dy = ymax - ymin;
+/*
+ Set up the supertriangle.
+ This is a triangle which encompasses all the sample points.
+ The supertriangle coordinates are added to the end of the
+ vertex list. The supertriangle is the first triangle in
+ the triangle list.
+*/
+ static const double margin=0.01;
+ double xmargin=margin*dx;
+ double ymargin=margin*dy;
+ pxyz[nv+0].p[0] = xmin-xmargin;
+ pxyz[nv+0].p[1] = ymin-ymargin;
+ pxyz[nv+1].p[0] = xmin-xmargin;
+ pxyz[nv+1].p[1] = ymax+ymargin+dx;
+ pxyz[nv+2].p[0] = xmax+xmargin+dy;
+ pxyz[nv+2].p[1] = ymin-ymargin;
+ v->p1 = nv;
+ v->p2 = nv+1;
+ v->p3 = nv+2;
+ complete[0] = false;
+ ntri = 1;
+/*
+ Include each point one at a time into the existing mesh
+*/
+ for(Int i = 0; i < nv; i++) {
+ Int nedge = 0;
+ double *d=pxyz[i].p;
+/*
+ Set up the edge buffer.
+ If the point d lies inside the circumcircle then the
+ three edges of that triangle are added to the edge buffer
+ and that triangle is removed.
+*/
+ for(Int j = 0; j < ntri; j++) {
+ if(complete[j])
+ continue;
+ ITRIANGLE *vj=v+j;
+
+ double *a=pxyz[vj->p1].p;
+ double *b=pxyz[vj->p2].p;
+ double *c=pxyz[vj->p3].p;
+
+ if(incircle(a,b,c,d) <= 0.0) { // Point d is inside or on circumcircle
+/* Check that we haven't exceeded the edge list size */
+ if(nedge + 3 >= emax) {
+ emax += 100;
+ IEDGE *p_EdgeTemp = new IEDGE[emax];
+ for (Int i = 0; i < nedge; i++) {
+ p_EdgeTemp[i] = edges[i];
+ }
+ delete[] edges;
+ edges = p_EdgeTemp;
+ }
+ ITRIANGLE *vj=v+j;
+ Int p1=vj->p1;
+ Int p2=vj->p2;
+ Int p3=vj->p3;
+ edges[nedge].p1 = p1;
+ edges[nedge].p2 = p2;
+ edges[++nedge].p1 = p2;
+ edges[nedge].p2 = p3;
+ edges[++nedge].p1 = p3;
+ edges[nedge].p2 = p1;
+ ++nedge;
+ ntri--;
+ v[j] = v[ntri];
+ complete[j] = complete[ntri];
+ j--;
+ } else {
+ double A=hypot2(a);
+ double B=hypot2(b);
+ double C=hypot2(c);
+ double a0=orient2d(a,b,c);
+ // Is d[0] > xc+r for circumcircle abc of radius r about (xc,yc)?
+ if(d[0]*a0 < 0.5*orient2d(A,a[1],B,b[1],C,c[1]))
+ complete[j]=
+ incircle(a[0]*a0,a[1]*a0,b[0]*a0,b[1]*a0,c[0]*a0,c[1]*a0,
+ d[0]*a0,0.5*orient2d(a[0],A,b[0],B,c[0],C)) > 0.0;
+ }
+ }
+/*
+ Tag multiple edges
+ Note: if all triangles are specified anticlockwise then all
+ interior edges are opposite pointing in direction.
+*/
+ for(Int j = 0; j < nedge - 1; j++) {
+ for(Int k = j + 1; k < nedge; k++) {
+ if((edges[j].p1 == edges[k].p2) && (edges[j].p2 == edges[k].p1)) {
+ edges[j].p1 = -1;
+ edges[j].p2 = -1;
+ edges[k].p1 = -1;
+ edges[k].p2 = -1;
+ }
+ }
+ }
+/*
+ Form new triangles for the current point
+ Skipping over any tagged edges.
+ All edges are arranged in clockwise order.
+*/
+ for(Int j = 0; j < nedge; j++) {
+ if(edges[j].p1 < 0 || edges[j].p2 < 0)
+ continue;
+ v[ntri].p1 = edges[j].p1;
+ v[ntri].p2 = edges[j].p2;
+ v[ntri].p3 = i;
+ complete[ntri] = false;
+ ntri++;
+ assert(ntri < trimax);
+ }
+ }
+/*
+ Remove triangles with supertriangle vertices
+ These are triangles which have a vertex number greater than nv
+*/
+ for(Int i = 0; i < ntri; i++) {
+ ITRIANGLE *vi=v+i;
+ if(vi->p1 >= nv || vi->p2 >= nv || vi->p3 >= nv) {
+ ntri--;
+ *vi = v[ntri];
+ i--;
+ }
+ }
+ delete[] edges;
+ delete[] complete;
+
+ if(postsort) {
+ for(Int i = 0; i < ntri; i++) {
+ ITRIANGLE *vi=v+i;
+ vi->p1=pxyz[vi->p1].i;
+ vi->p2=pxyz[vi->p2].i;
+ vi->p3=pxyz[vi->p3].i;
+ }
+ }
+
+ return 0;
+}
diff --git a/Build/source/utils/asymptote/Delaunay.h b/Build/source/utils/asymptote/Delaunay.h
new file mode 100644
index 00000000000..bc68565ef84
--- /dev/null
+++ b/Build/source/utils/asymptote/Delaunay.h
@@ -0,0 +1,29 @@
+#ifndef DELAUNAY_H
+#define DELAUNAY_H
+
+#include <iostream>
+#include <cstdlib>
+#include <cmath>
+#include <cfloat>
+
+#include "common.h"
+
+struct ITRIANGLE{
+ Int p1, p2, p3;
+};
+
+struct IEDGE{
+ Int p1, p2;
+};
+
+struct XYZ{
+ double p[2]; // {x,y}
+ Int i;
+};
+
+Int Triangulate(Int nv, XYZ pxyz[], ITRIANGLE v[], Int &ntri,
+ bool presort=true, bool postsort=true);
+
+#endif
+
+
diff --git a/Build/source/utils/asymptote/GUI/CubicBezier.py b/Build/source/utils/asymptote/GUI/CubicBezier.py
new file mode 100755
index 00000000000..6455b700a79
--- /dev/null
+++ b/Build/source/utils/asymptote/GUI/CubicBezier.py
@@ -0,0 +1,101 @@
+#!/usr/bin/env python
+###########################################################################
+#
+# Convert a Bezier curve to a polyline
+#
+# Once Tk supports "RawCurves" this will not be needed.
+#
+#
+# Author: Orest Shardt
+# Created: June 29, 2007
+#
+###########################################################################
+import math
+
+def norm(vector):
+ """Return the norm of a vector"""
+ return math.sqrt(vector[0]**2+vector[1]**2)
+
+def splitLine(end0,end1,t):
+ """Split a line at the distance t, with t in (0,1)"""
+ return (end0[0]+t*(end1[0]-end0[0]),end0[1]+t*(end1[1]-end0[1]))
+
+def splitBezier(node0,control0,control1,node1,t):
+ """Find the nodes and control points for the segments of a Bezier curve split at t"""
+ a = splitLine(node0,control0,t)
+ b = splitLine(control0,control1,t)
+ c = splitLine(control1,node1,t)
+ d = splitLine(a,b,t)
+ e = splitLine(b,c,t)
+ f = splitLine(d,e,t)#this is the point on the curve at t
+ return ([node0,a,d,f],[f,e,c,node1])
+
+def BezierWidth(node0,control0,control1,node1):
+ """Compute the distance of the control points from the node-node axis"""
+ deltax = node1[0] - node0[0]
+ deltay = node1[1] - node0[1]
+ length = norm((deltax,deltay))
+ if length == 0:
+ y1 = control0[1]-node0[1]
+ y2 = control1[1]-node0[1]
+ else:
+ cosine = deltax/length
+ sine = deltay/length
+ y1 = cosine*(control0[1]-node0[1])-sine*(control0[0]-node0[0])
+ y2 = cosine*(control1[1]-node0[1])-sine*(control1[0]-node0[0])
+ if y1*y2 >= 0:
+ #same sign
+ return max(abs(y1),abs(y2))
+ else:
+ #opposite sign
+ return abs(y1)+abs(y2)
+
+#If the above algorithm fails, this one will work, but it is far from elegant
+#def computeIntermediates(steps,node0,control0,control1,node1):
+ #pointList = []
+ #for a in range(0,100,100/steps)+[100]:
+ #t = a/100.0
+ #t1 = 1-t
+ #x = node0[0]*t1**3+3*control0[0]*t*t1**2+3*control1[0]*t**2*t1+node1[0]*t**3
+ #y = node0[1]*t1**3+3*control0[1]*t*t1**2+3*control1[1]*t**2*t1+node1[1]*t**3
+ #pointList.append((x,y))
+ #return pointList
+#def makeBezier(steps,node0,control0,control1,node1):
+ #if len(node0)!=2 or len(control0)!=2 or len(control1)!=2 or len(node1)!=2:
+ #return -1
+ #else:
+ #return [node0]+computeIntermediates(steps,node0,control0,control1,node1)+[node1]
+
+def makeBezierIntermediates(node0,control0,control1,node1,epsilon):
+ """Find the points, excluding node0, to be used as the line segment endpoints"""
+ if(BezierWidth(node0,control0,control1,node1) <= epsilon):
+ return [node1]
+ else:
+ splitUp = splitBezier(node0,control0,control1,node1,0.5)
+ return makeBezierIntermediates(*splitUp[0]+[epsilon])+makeBezierIntermediates(*splitUp[1]+[epsilon])
+
+def makeBezier(node0,control0,control1,node1,epsilon=1):
+ """Return the vertices to be used in the polyline representation of a Bezier curve"""
+ return [node0]+makeBezierIntermediates(node0,control0,control1,node1,epsilon)
+
+if __name__ == '__main__':
+ pointList = makeBezier((-80,0),(-150,40),(150,120),(80,0),0.5)
+ from timeit import Timer
+ t = Timer('makeBezier((-80,0),(-40,-40),(40,120),(80,0),1)','from __main__ import makeBezier')
+ print pointList
+ print len(pointList)
+ iterations = 1000
+ time = t.timeit(iterations)
+ print "%d iterations took %f seconds (%f ms for each)."%(iterations,time,1000.0*time/iterations)
+ points = []
+ for point in pointList:
+ points.append(point[0])
+ points.append(-point[1])
+ from Tkinter import *
+ root = Tk()
+ canv = Canvas(root,scrollregion=(-100,-100,100,100))
+ canv.pack()
+ canv.create_line(points)
+ for point in pointList:
+ canv.create_oval(point[0],-point[1],point[0],-point[1],fill='red',outline='red')
+ root.mainloop()
diff --git a/Build/source/utils/asymptote/GUI/UndoRedoStack.py b/Build/source/utils/asymptote/GUI/UndoRedoStack.py
new file mode 100755
index 00000000000..f4a247a411d
--- /dev/null
+++ b/Build/source/utils/asymptote/GUI/UndoRedoStack.py
@@ -0,0 +1,117 @@
+#!/usr/bin/env python
+###########################################################################
+#
+# UndoRedoStack implements the usual undo/redo capabilities of a GUI
+#
+# Author: Orest Shardt
+# Created: July 23, 2007
+#
+###########################################################################
+
+class action:
+ def __init__(self,act,inv):
+ self.act = act
+ self.inv = inv
+ def undo(self):
+ #print "Undo:",self
+ self.inv()
+ def redo(self):
+ #print "Redo:",self
+ self.act()
+ def __str__(self):
+ return "A generic action"
+
+class beginActionGroup:
+ pass
+
+class endActionGroup:
+ pass
+
+class actionStack:
+ def __init__(self):
+ self.clear()
+
+ def add(self,action):
+ self.undoStack.append(action)
+ #print "Added",action
+ self.redoStack = []
+
+ def undo(self):
+ if len(self.undoStack) > 0:
+ op = self.undoStack.pop()
+ if op is beginActionGroup:
+ level = 1
+ self.redoStack.append(endActionGroup)
+ while level > 0:
+ op=self.undoStack.pop()
+ if op is endActionGroup:
+ level -= 1
+ self.redoStack.append(beginActionGroup)
+ elif op is beginActionGroup:
+ level += 1
+ self.redoStack.append(endActionGroup)
+ else:
+ op.undo()
+ self.redoStack.append(op)
+ elif op is endActionGroup:
+ raise Exception,"endActionGroup without previous beginActionGroup"
+ else:
+ self.redoStack.append(op)
+ op.undo()
+ #print "undid",op
+ else:
+ pass #print "nothing to undo"
+
+ def redo(self):
+ if len(self.redoStack) > 0:
+ op = self.redoStack.pop()
+ if op is beginActionGroup:
+ level = 1
+ self.undoStack.append(endActionGroup)
+ while level > 0:
+ op = self.redoStack.pop()
+ if op is endActionGroup:
+ level -= 1
+ self.undoStack.append(beginActionGroup)
+ elif op is beginActionGroup:
+ level += 1
+ self.undoStack.append(endActionGroup)
+ else:
+ op.redo()
+ self.undoStack.append(op)
+ elif op is endActionGroup:
+ raise Exception,"endActionGroup without previous beginActionGroup"
+ else:
+ self.undoStack.append(op)
+ op.redo()
+ #print "redid",op
+ else:
+ pass #print "nothing to redo"
+
+ def setCommitLevel(self):
+ self.commitLevel = len(self.undoStack)
+
+ def changesMade(self):
+ if len(self.undoStack) != self.commitLevel:
+ return True
+ else:
+ return False
+
+ def clear(self):
+ self.redoStack = []
+ self.undoStack = []
+ self.commitLevel = 0
+
+if __name__=='__main__':
+ import sys
+ def opq():
+ print "action1"
+ def unopq():
+ print "inverse1"
+ q = action(opq,unopq)
+ w = action(lambda:sys.stdout.write("action2\n"),lambda:sys.stdout.write("inverse2\n"))
+ e = action(lambda:sys.stdout.write("action3\n"),lambda:sys.stdout.write("inverse3\n"))
+ s = actionStack()
+ s.add(q)
+ s.add(w)
+ s.add(e)
diff --git a/Build/source/utils/asymptote/GUI/xasy.py b/Build/source/utils/asymptote/GUI/xasy.py
new file mode 100755
index 00000000000..ffca16a1e2d
--- /dev/null
+++ b/Build/source/utils/asymptote/GUI/xasy.py
@@ -0,0 +1,35 @@
+#!/usr/bin/env python
+###########################################################################
+#
+# xasy implements a graphical interface for Asymptote.
+#
+#
+# Author: Orest Shardt
+# Created: June 29, 2007
+#
+############################################################################
+
+import getopt,sys,signal
+from Tkinter import *
+import xasyMainWin
+
+signal.signal(signal.SIGINT,signal.SIG_IGN)
+
+root = Tk()
+mag = 1.0
+try:
+ opts,args = getopt.getopt(sys.argv[1:],"x:")
+ if(len(opts)>=1):
+ mag = float(opts[0][1])
+except:
+ print "Invalid arguments."
+ print "Usage: xasy.py [-x magnification] [filename]"
+ sys.exit(1)
+if(mag <= 0.0):
+ print "Magnification must be positive."
+ sys.exit(1)
+if(len(args)>=1):
+ app = xasyMainWin.xasyMainWin(root,args[0],mag)
+else:
+ app = xasyMainWin.xasyMainWin(root,magnification=mag)
+root.mainloop()
diff --git a/Build/source/utils/asymptote/GUI/xasy2asy.py b/Build/source/utils/asymptote/GUI/xasy2asy.py
new file mode 100755
index 00000000000..23bd5a67c38
--- /dev/null
+++ b/Build/source/utils/asymptote/GUI/xasy2asy.py
@@ -0,0 +1,785 @@
+#!/usr/bin/env python
+###########################################################################
+#
+# xasy2asy provides a Python interface to Asymptote
+#
+#
+# Author: Orest Shardt
+# Created: June 29, 2007
+#
+###########################################################################
+import sys,os,signal,threading
+from subprocess import *
+from string import *
+import xasyOptions
+import Queue
+from Tkinter import *
+from tempfile import mkdtemp
+
+# PIL support is now mandatory due to rotations
+try:
+ import ImageTk
+ import Image
+except:
+ pass
+
+import CubicBezier
+
+class asyProcessFailure(Exception):
+ """asy could not be invoked to execute a command because the process has failed."""
+ pass
+
+idCounter = 0;
+randString = 'wGd3I26kOcu4ZI4arZZMqoJufO2h1QE2D728f1Lai3aqeTQC9'
+
+quickAsyFailed = True
+global AsyTempDir
+
+console=None
+
+def startQuickAsy():
+ global quickAsy
+ global quickAsyFailed
+ global AsyTempDir
+ if quickAsyRunning():
+ return
+ try:
+ quickAsy.stdin.close()
+ quickAsy.wait()
+ except:
+ pass
+ try:
+ quickAsyFailed = False
+ if os.name == "nt":
+ AsyTempDir=mkdtemp(prefix="asy_", dir="./")
+ else:
+ AsyTempDir=mkdtemp(prefix="asy_")+os.sep
+ quickAsy = Popen([xasyOptions.options['asyPath']]+
+ split("-noV -multiline -interactive -o"+AsyTempDir),
+ stdin=PIPE,stdout=PIPE,stderr=STDOUT)
+ quickAsy.stdin.write("settings.xformat;\n")
+ if quickAsy.returncode != None:
+ quickAsyFailed = True
+ except:
+ quickAsyFailed = True
+
+def getAsyTempDir():
+ return AsyTempDir
+
+def quickAsyRunning():
+ if quickAsyFailed or quickAsy.returncode != None:
+ return False
+ else:
+ return True
+
+def asyExecute(command):
+ if not quickAsyRunning():
+ startQuickAsy()
+ syncQuickAsyOutput()
+ quickAsy.stdin.write(command)
+
+def closeConsole(event):
+ global console
+ console = None
+
+def consoleOutput(line):
+ global console
+ global ctl
+ if console == None:
+ ctl=Toplevel()
+ ctl.title("Asymptote Console")
+ ctl.bind("<Destroy>",closeConsole)
+ yscrollbar=Scrollbar(ctl)
+ yscrollbar.pack(side=RIGHT,fill=Y)
+ console=Text(ctl,yscrollcommand=yscrollbar.set)
+ console.pack()
+ yscrollbar.config(command=console.yview)
+ console.insert(END,line)
+ ctl.lift()
+
+def syncQuickAsyOutput(verbose=False,queue=None):
+ global idCounter
+ idStr = randString+"-id "+str(idCounter)
+ idCounter += 1
+ quickAsy.stdin.write("\nwrite(\""+idStr+"\");\n")
+ quickAsy.stdin.flush()
+ line = quickAsy.stdout.readline()
+ while not line.endswith(idStr+'\n'):
+ if verbose:
+ queue.put(("OUTPUT",line))
+ line = quickAsy.stdout.readline()
+ quickAsy.stdin.flush()
+
+class asyTransform:
+ """A python implementation of an asy transform"""
+ def __init__(self,initTuple,delete=False):
+ """Initialize the transform with a 6 entry tuple"""
+ if type(initTuple) == type((0,)) and len(initTuple) == 6:
+ self.t = initTuple
+ self.x,self.y,self.xx,self.xy,self.yx,self.yy = initTuple
+ self.deleted = delete
+ else:
+ raise Exception,"Illegal initializer for asyTransform"
+
+ def getCode(self):
+ """Obtain the asy code that represents this transform"""
+ if self.deleted:
+ return str(self.t) + ", false"
+ else:
+ return str(self.t)
+
+ def scale(self,s):
+ #return asyTransform((s*self.t[0],s*self.t[1],s*self.t[2],s*self.t[3],s*self.t[4],s*self.t[5]))
+ return asyTransform((0,0,s,0,0,s))*self
+
+ def __str__(self):
+ """Equivalent functionality to getCode(). It allows the expression str(asyTransform) to be meaningful."""
+ return self.getCode()
+
+ def __mul__(self,other):
+ """Define multiplication of transforms as composition."""
+ if type(other)==type((0,)):
+ if len(other) == 6:
+ return self*asyTransform(other)
+ elif len(other) == 2:
+ return ((self.t[0]+self.t[2]*other[0]+self.t[3]*other[1]),(self.t[1]+self.t[4]*other[0]+self.t[5]*other[1]))
+ else:
+ raise Exception, "Illegal multiplier of %s"%str(type(other))
+ elif isinstance(other,asyTransform):
+ result = asyTransform((0,0,0,0,0,0))
+ result.x = self.x+self.xx*other.x+self.xy*other.y
+ result.y = self.y+self.yx*other.x+self.yy*other.y
+ result.xx = self.xx*other.xx+self.xy*other.yx
+ result.xy = self.xx*other.xy+self.xy*other.yy
+ result.yx = self.yx*other.xx+self.yy*other.yx
+ result.yy = self.yx*other.xy+self.yy*other.yy
+ result.t = (result.x,result.y,result.xx,result.xy,result.yx,result.yy)
+ return result
+ else:
+ raise Exception, "Illegal multiplier of %s"%str(type(other))
+
+def identity():
+ return asyTransform((0,0,1,0,0,1))
+
+class asyObj:
+ """A base class for asy objects: an item represented by asymptote code."""
+ def __init__(self):
+ """Initialize the object"""
+ self.asyCode = ""
+
+ def updateCode(self,mag=1.0):
+ """Update the object's code: should be overriden."""
+ pass
+
+ def getCode(self):
+ """Return the code describing the object"""
+ self.updateCode()
+ return self.asyCode
+
+class asyPen(asyObj):
+ """A python wrapper for an asymptote pen"""
+ def __init__(self,color=(0,0,0),width=0.5,options=""):
+ """Initialize the pen"""
+ asyObj.__init__(self)
+ self.options=options
+ self.width=width
+ self.setColor(color)
+ self.updateCode()
+ if options != "":
+ self.computeColor()
+
+ def updateCode(self,mag=1.0):
+ """Generate the pen's code"""
+ self.asyCode = "rgb(%g,%g,%g)"%self.color+"+"+str(self.width)
+ if len(self.options) > 0:
+ self.asyCode += "+"+self.options
+
+ def setWidth(self,newWidth):
+ """Set the pen's width"""
+ self.width=newWidth
+ self.updateCode()
+
+ def setColor(self,color):
+ """Set the pen's color"""
+ if type(color) == type((1,)) and len(color) == 3:
+ self.color = color
+ else:
+ self.color = "(0,0,0)"
+ self.updateCode()
+
+ def computeColor(self):
+ """Find out the color of an arbitrary asymptote pen."""
+ syncQuickAsyOutput()
+ quickAsy.stdin.write("pen p="+self.getCode()+';\n')
+ quickAsy.stdin.write("write(\";\n\");write(colorspace(p));\n")
+ quickAsy.stdin.write("write(colors(p));\n")
+ quickAsy.stdin.flush()
+ testline = quickAsy.stdout.readline()
+ if testline.startswith("> -:"):
+ raise Exception,"Invalid pen options"
+ quickAsy.stdout.readline()
+ colorspace = quickAsy.stdout.readline()
+ if colorspace.find("cmyk") != -1:
+ lines = quickAsy.stdout.readline()+quickAsy.stdout.readline()+quickAsy.stdout.readline()+quickAsy.stdout.readline()
+ parts = lines.split()
+ c,m,y,k = eval(parts[2]),eval(parts[4]),eval(parts[6]),eval(parts[8])
+ k = 1-k
+ r,g,b = ((1-c)*k,(1-m)*k,(1-y)*k)
+ elif colorspace.find("rgb") != -1:
+ lines = quickAsy.stdout.readline()+quickAsy.stdout.readline()+quickAsy.stdout.readline()
+ parts = lines.split()
+ r,g,b = eval(parts[2]),eval(parts[4]),eval(parts[6])
+ elif colorspace.find("gray") != -1:
+ lines = quickAsy.stdout.readline()
+ parts = lines.split()
+ r = g = b = eval(parts[2])
+ self.color = (r,g,b)
+
+ def tkColor(self):
+ """Return the tk version of the pen's color"""
+ self.computeColor()
+ r,g,b = self.color
+ r,g,b = int(256*r),int(256*g),int(256*b)
+ if r == 256:
+ r = 255
+ if g == 256:
+ g = 255
+ if b == 256:
+ b = 255
+ r,g,b = map(hex,(r,g,b))
+ r,g,b = r[2:],g[2:],b[2:]
+ if len(r) < 2:
+ r += '0'
+ if len(g) < 2:
+ g += '0'
+ if len(b) < 2:
+ b += '0'
+ return'#'+r+g+b
+
+class asyPath(asyObj):
+ """A python wrapper for an asymptote path"""
+ def __init__(self):
+ """Initialize the path to be an empty path: a path with no nodes, control points, or links."""
+ asyObj.__init__(self)
+ self.nodeSet = []
+ self.linkSet = []
+ self.controlSet = []
+ self.computed = False
+
+ def initFromNodeList(self,nodeSet,linkSet):
+ """Initialize the path from a set of nodes and link types, "--", "..", or "::" """
+ if len(nodeSet)>0:
+ self.nodeSet = nodeSet[:]
+ self.linkSet = linkSet[:]
+ self.computed = False
+
+ def initFromControls(self,nodeSet,controlSet):
+ """Initialize the path from nodes and control points"""
+ self.controlSet = controlSet[:]
+ self.nodeSet = nodeSet[:]
+ self.computed = True
+
+ def makeNodeStr(self,node):
+ """Represent a node as a string"""
+ if node == 'cycle':
+ return node
+ else:
+ return "("+str(node[0])+","+str(node[1])+")"
+
+ def updateCode(self,mag=1.0):
+ """Generate the code describing the path"""
+ if not self.computed:
+ count = 0
+ #this string concatenation could be optimised
+ self.asyCode = self.makeNodeStr(self.nodeSet[0])
+ for node in self.nodeSet[1:]:
+ self.asyCode += self.linkSet[count]+self.makeNodeStr(node)
+ count += 1
+ else:
+ count = 0
+ #this string concatenation could be optimised
+ self.asyCode = self.makeNodeStr(self.nodeSet[0])
+ for node in self.nodeSet[1:]:
+ self.asyCode += "..controls"
+ self.asyCode += self.makeNodeStr(self.controlSet[count][0])
+ self.asyCode += "and"
+ self.asyCode += self.makeNodeStr(self.controlSet[count][1])
+ self.asyCode += ".." + self.makeNodeStr(node) + "\n"
+ count += 1
+
+ def getNode(self,index):
+ """Return the requested node"""
+ return self.nodeSet[index]
+
+ def getLink(self,index):
+ """Return the requested link"""
+ return self.linkSet[index]
+
+ def setNode(self,index,newNode):
+ """Set a node to a new position"""
+ self.nodeSet[index] = newNode
+
+ def moveNode(self,index,offset):
+ """Translate a node"""
+ if self.nodeSet[index] != "cycle":
+ self.nodeSet[index] = (self.nodeSet[index][0]+offset[0],self.nodeSet[1]+offset[1])
+
+ def setLink(self,index,ltype):
+ """Change the specified link"""
+ self.linkSet[index] = ltype
+
+ def addNode(self,point,ltype):
+ """Add a node to the end of a path"""
+ self.nodeSet.append(point)
+ if len(self.nodeSet) != 1:
+ self.linkSet.append(ltype)
+ if self.computed:
+ self.computeControls()
+
+ def insertNode(self,index,point,ltype=".."):
+ """Insert a node, and its corresponding link, at the given index"""
+ self.nodeSet.insert(index,point)
+ self.linkSet.insert(index,ltype)
+ if self.computed:
+ self.computeControls()
+
+ def setControl(self,index,position):
+ """Set a control point to a new position"""
+ self.controlSet[index] = position
+
+ def moveControl(self,index,offset):
+ """Translate a control point"""
+ self.controlSet[index] = (self.controlSet[index][0]+offset[0],self.controlSet[index][1]+offset[1])
+
+ def computeControls(self):
+ """Evaluate the code of the path to obtain its control points"""
+ syncQuickAsyOutput()
+ quickAsy.stdin.write("path p="+self.getCode()+';\n')
+ quickAsy.stdin.write("write(length(p));\n")
+ quickAsy.stdin.write("write(unstraighten(p));write(\"\");\n")
+ quickAsy.stdin.flush()
+ lengthStr = quickAsy.stdout.readline()
+ pathSegments = eval(lengthStr.split()[-1])
+ pathStrLines = []
+ for i in range(pathSegments+1):
+ pathStrLines.append(quickAsy.stdout.readline())
+ oneLiner = "".join(split(join(pathStrLines)))
+ oneLiner = oneLiner.replace(">","")
+ splitList = oneLiner.split("..")
+ nodes = [a for a in splitList if a.find("controls")==-1]
+ self.nodeSet = []
+ for a in nodes:
+ if a == 'cycle':
+ self.nodeSet.append(a)
+ else:
+ self.nodeSet.append(eval(a))
+ controls = [a.replace("controls","").split("and") for a in splitList if a.find("controls") != -1]
+ self.controlSet = [[eval(a[0]),eval(a[1])] for a in controls]
+ self.computed = True
+
+class asyLabel(asyObj):
+ """A python wrapper for an asy label"""
+ def __init__(self,text="",location=(0,0),pen=asyPen()):
+ """Initialize the label with the given test, location, and pen"""
+ asyObj.__init__(self)
+ self.text = text
+ self.location = location
+ self.pen = pen
+
+ def updateCode(self,mag=1.0):
+ """Generate the code describing the label"""
+ self.asyCode = "Label(\""+self.text+"\","+str((self.location[0],self.location[1]))+","+self.pen.getCode()+",align=SE)"
+
+ def setText(self,text):
+ """Set the label's text"""
+ self.text = text
+ self.updateCode()
+
+ def setPen(self,pen):
+ """Set the label's pen"""
+ self.pen = pen
+ self.updateCode()
+
+ def moveTo(self,newl):
+ """Translate the label's location"""
+ self.location = newl
+
+class asyImage:
+ """A structure containing an image and its format, bbox, and IDTag"""
+ def __init__(self,image,format,bbox):
+ self.image = image
+ self.format = format
+ self.bbox = bbox
+ self.IDTag = None
+
+class xasyItem:
+ """A base class for items in the xasy GUI"""
+ def __init__(self,canvas=None):
+ """Initialize the item to an empty item"""
+ self.transform = [identity()]
+ self.asyCode = ""
+ self.imageList = []
+ self.IDTag = None
+ self.asyfied = False
+ self.onCanvas = canvas
+
+ def updateCode(self,mag=1.0):
+ """Update the item's code: to be overriden"""
+ pass
+
+ def getCode(self):
+ """Return the code describing the item"""
+ self.updateCode()
+ return self.asyCode
+
+ def handleImageReception(self,file,format,bbox,count):
+ """Receive an image from an asy deconstruction. It replaces the default in asyProcess."""
+ image = Image.open(file)
+ self.imageList.append(asyImage(image,format,bbox))
+ if self.onCanvas != None:
+ self.imageList[-1].itk = ImageTk.PhotoImage(image)
+ self.imageList[-1].originalImage = image.copy()
+ self.imageList[-1].originalImage.theta = 0.0
+ self.imageList[-1].originalImage.bbox = bbox
+ if count >= len(self.transform) or self.transform[count].deleted == False:
+ self.imageList[-1].IDTag = self.onCanvas.create_image(bbox[0],-bbox[3],anchor=NW,tags=("image"),image=self.imageList[-1].itk)
+ self.onCanvas.update()
+
+ def asyfy(self,mag=1.0):
+ self.removeFromCanvas()
+ self.imageList = []
+ self.imageHandleQueue = Queue.Queue()
+ worker = threading.Thread(target=self.asyfyThread,args=(mag,))
+ worker.start()
+ item = self.imageHandleQueue.get()
+ if console != None:
+ console.delete(1.0,END)
+ while item != (None,) and item[0] != "ERROR":
+ if(item[0] == "OUTPUT"):
+ consoleOutput(item[1])
+ else:
+ self.handleImageReception(*item)
+ try:
+ os.remove(item[0])
+ except:
+ pass
+ item = self.imageHandleQueue.get()
+ #self.imageHandleQueue.task_done()
+ worker.join()
+
+ def asyfyThread(self,mag=1.0):
+ """Convert the item to a list of images by deconstructing this item's code"""
+ quickAsy.stdin.write("\nreset;\n")
+ quickAsy.stdin.write("initXasyMode();\n")
+ quickAsy.stdin.write("atexit(null);\n")
+ syncQuickAsyOutput()
+ global console
+ for line in self.getCode().splitlines():
+ quickAsy.stdin.write(line+"\n");
+ quickAsy.stdin.flush()
+ syncQuickAsyOutput(verbose=True,queue=self.imageHandleQueue);
+ quickAsy.stdin.write("deconstruct(%f);\n"%mag)
+ quickAsy.stdin.flush()
+ format = split(quickAsy.stdout.readline())[1]
+ maxargs = int(split(quickAsy.stdout.readline())[0])
+ boxes=[]
+ batch=0
+ n=0
+ text = quickAsy.stdout.readline()
+ template=AsyTempDir+"%d_%d.%s"
+ def render():
+ for i in range(len(boxes)):
+ l,b,r,t = [float(a) for a in split(boxes[i])]
+ name=template%(batch,i+1,format)
+ self.imageHandleQueue.put((name,format,(l,b,r,t),i))
+ while text != "Done\n" and text != "Error\n":
+ boxes.append(text)
+ text = quickAsy.stdout.readline()
+ n += 1
+ if n >= maxargs:
+ render()
+ boxes=[]
+ batch += 1
+ n=0
+ if text == "Error\n":
+ self.imageHandleQueue.put(("ERROR",quickAsy.stdout.readline()))
+ else:
+ render()
+ self.imageHandleQueue.put((None,))
+ self.asyfied = True
+
+ def drawOnCanvas(self,canvas,mag,forceAddition=False):
+ pass
+ def removeFromCanvas(self):
+ pass
+
+class xasyDrawnItem(xasyItem):
+ """A base class for GUI items was drawn by the user. It combines a path, a pen, and a transform."""
+ def __init__(self,path,pen = asyPen(),transform = identity()):
+ """Initialize the item with a path, pen, and transform"""
+ xasyItem.__init__(self)
+ self.path = path
+ self.pen = pen
+ self.transform = [transform]
+
+ def appendPoint(self,point,link=None):
+ """Append a point to the path. If the path is cyclic, add this point before the 'cycle' node."""
+ if self.path.nodeSet[-1] == 'cycle':
+ self.path.nodeSet[-1] = point
+ self.path.nodeSet.append('cycle')
+ else:
+ self.path.nodeSet.append(point)
+ self.path.computed = False
+ if len(self.path.nodeSet) > 1 and link != None:
+ self.path.linkSet.append(link)
+
+ def clearTransform(self):
+ """Reset the item's transform"""
+ self.transform = [identity()]
+
+ def removeLastPoint(self):
+ """Remove the last point in the path. If the path is cyclic, remove the node before the 'cycle' node."""
+ if self.path.nodeSet[-1] == 'cycle':
+ del self.path.nodeSet[-2]
+ else:
+ del self.path.nodeSet[-1]
+ del self.path.linkSet[-1]
+ self.path.computed = False
+
+ def setLastPoint(self,point):
+ """Modify the last point in the path. If the path is cyclic, modify the node before the 'cycle' node."""
+ if self.path.nodeSet[-1] == 'cycle':
+ self.path.nodeSet[-2] = point
+ else:
+ self.path.nodeSet[-1] = point
+ self.path.computed = False
+
+class xasyShape(xasyDrawnItem):
+ """An outlined shape drawn on the GUI"""
+ def __init__(self,path,pen=asyPen(),transform=identity()):
+ """Initialize the shape with a path, pen, and transform"""
+ xasyDrawnItem.__init__(self,path,pen,transform)
+
+ def updateCode(self,mag=1.0):
+ """Generate the code to describe this shape"""
+ self.asyCode = "xformStack.push("+self.transform[0].getCode()+");\n"
+ self.asyCode += "draw("+self.path.getCode()+","+self.pen.getCode()+");"
+
+ def removeFromCanvas(self,canvas):
+ """Remove the shape's depiction from a tk canvas"""
+ if self.IDTag != None:
+ canvas.delete(self.IDTag)
+
+ def drawOnCanvas(self,canvas,mag,asyFy=False,forceAddition=False):
+ """Add this shape to a tk canvas"""
+ if not asyFy:
+ if self.IDTag == None or forceAddition:
+ #add ourselves to the canvas
+ self.path.computeControls()
+ self.IDTag = canvas.create_line(0,0,0,0,tags=("drawn","xasyShape"),fill=self.pen.tkColor(),width=self.pen.width*mag)
+ self.drawOnCanvas(canvas,mag)
+ else:
+ self.path.computeControls()
+ pointSet = []
+ previousNode = self.path.nodeSet[0]
+ nodeCount = 0
+ if len(self.path.nodeSet) == 0:
+ pointSet = [0,0,0,0]
+ elif len(self.path.nodeSet) == 1:
+ if self.path.nodeSet[-1] != 'cycle':
+ p = self.transform[0]*(self.path.nodeSet[0][0],self.path.nodeSet[0][1])
+ pointSet = [p[0],-p[1],p[0],-p[1],p[0],-p[1]]
+ else:
+ pointSet = [0,0,0,0]
+ else:
+ for node in self.path.nodeSet[1:]:
+ if node == 'cycle':
+ node = self.path.nodeSet[0]
+ transform = self.transform[0].scale(mag)
+ points = CubicBezier.makeBezier(transform*previousNode,transform*self.path.controlSet[nodeCount][0],transform*self.path.controlSet[nodeCount][1],transform*node)
+ for point in points:
+ pointSet += [point[0],-point[1]]
+ nodeCount += 1
+ previousNode = node
+ canvas.coords(self.IDTag,*pointSet)
+ canvas.itemconfigure(self.IDTag,fill=self.pen.tkColor(),width=self.pen.width*mag)
+ else:
+ #first asyfy then add an image list
+ pass
+
+ def __str__(self):
+ """Create a string describing this shape"""
+ return "xasyShape code:%s"%("\n\t".join(self.getCode().splitlines()))
+
+class xasyFilledShape(xasyShape):
+ """A filled shape drawn on the GUI"""
+ def __init__(self,path,pen=asyPen(),transform=identity()):
+ """Initialize this shape with a path, pen, and transform"""
+ if path.nodeSet[-1] != 'cycle':
+ raise Exception,"Filled paths must be cyclic"
+ xasyShape.__init__(self,path,pen,transform)
+
+ def updateCode(self,mag=1.0):
+ """Generate the code describing this shape"""
+ self.asyCode = "xformStack.push("+self.transform[0].getCode()+");\n"
+ self.asyCode += "fill("+self.path.getCode()+","+self.pen.getCode()+");"
+
+ def removeFromCanvas(self,canvas):
+ """Remove this shape's depiction from a tk canvas"""
+ if self.IDTag != None:
+ canvas.delete(self.IDTag)
+
+ def drawOnCanvas(self,canvas,mag,asyFy=False,forceAddition=False):
+ """Add this shape to a tk canvas"""
+ if not asyFy:
+ if self.IDTag == None or forceAddition:
+ #add ourselves to the canvas
+ self.path.computeControls()
+ self.IDTag = canvas.create_polygon(0,0,0,0,0,0,tags=("drawn","xasyFilledShape"),fill=self.pen.tkColor(),outline=self.pen.tkColor(),width=1*mag)
+ self.drawOnCanvas(canvas,mag)
+ else:
+ self.path.computeControls()
+ pointSet = []
+ previousNode = self.path.nodeSet[0]
+ nodeCount = 0
+ if len(self.path.nodeSet) == 0:
+ pointSet = [0,0,0,0,0,0]
+ elif len(self.path.nodeSet) == 1:
+ if self.path.nodeSet[-1] != 'cycle':
+ p = self.transform[0]*(self.path.nodeSet[0][0],self.path.nodeSet[0][1])
+ pointSet = [p[0],-p[1],p[0],-p[1],p[0],-p[1]]
+ else:
+ pointSet = [0,0,0,0,0,0]
+ elif len(self.path.nodeSet) == 2:
+ if self.path.nodeSet[-1] != 'cycle':
+ p = self.transform[0].scale(mag)*(self.path.nodeSet[0][0],self.path.nodeSet[0][1])
+ p2 = self.transform[0].scale(mag)*(self.path.nodeSet[1][0],self.path.nodeSet[1][1])
+ pointSet = [p[0],-p[1],p2[0],-p2[1],p[0],-p[1]]
+ else:
+ pointSet = [0,0,0,0,0,0]
+ else:
+ for node in self.path.nodeSet[1:]:
+ if node == 'cycle':
+ node = self.path.nodeSet[0]
+ transform = self.transform[0].scale(mag)
+ points = CubicBezier.makeBezier(transform*previousNode,transform*self.path.controlSet[nodeCount][0],transform*self.path.controlSet[nodeCount][1],transform*node)
+ for point in points:
+ pointSet += [point[0],-point[1]]
+ nodeCount += 1
+ previousNode = node
+ canvas.coords(self.IDTag,*pointSet)
+ canvas.itemconfigure(self.IDTag,fill=self.pen.tkColor(),outline=self.pen.tkColor(),width=1*mag)
+ else:
+ #first asyfy then add an image list
+ pass
+
+ def __str__(self):
+ """Return a string describing this shape"""
+ return "xasyFilledShape code:%s"%("\n\t".join(self.getCode().splitlines()))
+
+class xasyText(xasyItem):
+ """Text created by the GUI"""
+ def __init__(self,text,location,pen=asyPen(),transform=identity()):
+ """Initialize this item with text, a location, pen, and transform"""
+ xasyItem.__init__(self)
+ self.label=asyLabel(text,location,pen)
+ self.transform = [transform]
+ self.onCanvas = None
+
+ def updateCode(self,mag=1.0):
+ """Generate the code describing this object"""
+ self.asyCode = "xformStack.push("+self.transform[0].getCode()+");\n"
+ self.asyCode += "label("+self.label.getCode()+");"
+
+ def removeFromCanvas(self):
+ """Removes the label's images from a tk canvas"""
+ if self.onCanvas == None:
+ return
+ for image in self.imageList:
+ if image.IDTag != None:
+ self.onCanvas.delete(image.IDTag)
+
+ def drawOnCanvas(self,canvas,mag,asyFy=True,forceAddition=False):
+ """Adds the label's images to a tk canvas"""
+ if self.onCanvas == None:
+ self.onCanvas = canvas
+ elif self.onCanvas != canvas:
+ raise Exception,"Error: item cannot be added to more than one canvas"
+ self.asyfy(mag)
+
+ def __str__(self):
+ return "xasyText code:%s"%("\n\t".join(self.getCode().splitlines()))
+
+class xasyScript(xasyItem):
+ """A set of images create from asymptote code. It is always deconstructed."""
+ def __init__(self,canvas,script="",transforms=[]):
+ """Initialize this script item"""
+ xasyItem.__init__(self,canvas)
+ self.transform = transforms[:]
+ self.script = script
+
+ def clearTransform(self):
+ """Reset the transforms for each of the deconstructed images"""
+ self.transform = [identity() for im in self.imageList]
+
+ def updateCode(self,mag=1.0):
+ """Generate the code describing this script"""
+ self.asyCode = "";
+ if len(self.transform) > 0:
+ self.asyCode = "xformStack.add("
+ isFirst = True
+ count = 0
+ for xform in self.transform:
+ if not isFirst:
+ self.asyCode+=",\n"
+ self.asyCode += "indexedTransform(%d,%s)"%(count,str(xform))
+ isFirst = False
+ count += 1
+ self.asyCode += ");\n"
+ self.asyCode += "startScript(); {\n"
+ self.asyCode += self.script.replace("\t"," ")
+ self.asyCode = self.asyCode.rstrip()
+ self.asyCode += "\n} endScript();\n"
+
+ def setScript(self,script):
+ """Sets the content of the script item."""
+ self.script = script
+ self.updateCode()
+
+ def removeFromCanvas(self):
+ """Removes the script's images from a tk canvas"""
+ if self.onCanvas == None:
+ return
+ for image in self.imageList:
+ if image.IDTag != None:
+ self.onCanvas.delete(image.IDTag)
+
+ def asyfy(self,mag):
+ """Generate the list of images described by this object and adjust the length of the transform list."""
+ xasyItem.asyfy(self,mag)
+ while len(self.imageList) > len(self.transform):
+ self.transform.append(identity())
+ while len(self.imageList) < len(self.transform):
+ self.transform.pop()
+ self.updateCode()
+
+ def drawOnCanvas(self,canvas,mag,asyFy=True,forceAddition=False):
+ """Adds the script's images to a tk canvas"""
+ if self.onCanvas == None:
+ self.onCanvas = canvas
+ elif self.onCanvas != canvas:
+ raise Exception,"Error: item cannot be added to more than one canvas"
+ self.asyfy(mag)
+
+ def __str__(self):
+ """Return a string describing this script"""
+ retVal = "xasyScript\n\tTransforms:\n"
+ for xform in self.transform:
+ retVal += "\t"+str(xform)+"\n"
+ retVal += "\tCode Ommitted"
+ return retVal
+
+if __name__=='__main__':
+ root = Tk()
+ t=xasyText("test",(0,0))
+ t.asyfy()
diff --git a/Build/source/utils/asymptote/GUI/xasyActions.py b/Build/source/utils/asymptote/GUI/xasyActions.py
new file mode 100755
index 00000000000..38aae1d5c7e
--- /dev/null
+++ b/Build/source/utils/asymptote/GUI/xasyActions.py
@@ -0,0 +1,387 @@
+#!/usr/bin/env python
+###########################################################################
+#
+# xasyActions implements the possible actions and their inverses
+# for the undo/redo stack in xasy
+#
+# Author: Orest Shardt
+# Created: July 23, 2007
+#
+###########################################################################
+import math
+import UndoRedoStack
+import xasy2asy
+from Tkinter import *
+
+class translationAction(UndoRedoStack.action):
+ def __init__(self,owner,itemList,indexList,translation):
+ self.translation = translation
+ self.owner = owner
+ self.itemList = itemList
+ self.indexList = indexList
+ UndoRedoStack.action.__init__(self,self.transF,self.unTransF)
+
+ def transF(self):
+ mag = self.owner.magnification
+ for i in range(len(self.itemList)):
+ for index in self.indexList[i]:
+ self.owner.translateSomething(-1,(self.translation[0]/mag,self.translation[1]/mag),self.itemList[i],index)
+ if index==None:
+ index = 0
+ try:
+ self.owner.mainCanvas.move(self.itemList[i].imageList[index].IDTag,self.translation[0]*mag,-self.translation[1]*mag)
+ except:
+ self.owner.mainCanvas.move(self.itemList[i].IDTag,self.translation[0]*mag,-self.translation[1]*mag)
+ self.owner.updateSelection()
+ self.owner.updateCanvasSize()
+
+ def unTransF(self):
+ mag = self.owner.magnification
+ for i in range(len(self.itemList)):
+ for index in self.indexList[i]:
+ self.owner.translateSomething(-1,(-self.translation[0]/mag,-self.translation[1]/mag),self.itemList[i],index)
+ try:
+ self.owner.mainCanvas.move(self.itemList[i].imageList[index].IDTag,-self.translation[0]*mag,self.translation[1]*mag)
+ except:
+ self.owner.mainCanvas.move(self.itemList[i].IDTag,-self.translation[0]*mag,self.translation[1]*mag)
+ self.owner.updateSelection()
+ self.owner.updateCanvasSize()
+
+ def __str__(self):
+ return "Translation of "+str(self.itemList)+str(self.indexList)+" by "+str(self.translation)
+
+class rotationAction(UndoRedoStack.action):
+ def __init__(self,owner,itemList,indexList,angle,origin):
+ self.owner = owner
+ self.itemList = itemList
+ self.indexList = indexList
+ self.angle = angle
+ self.origin = origin
+ UndoRedoStack.action.__init__(self,self.rotF,self.unRotF)
+
+ def rotF(self):
+ for i in range(len(self.itemList)):
+ for index in self.indexList[i]:
+ self.owner.rotateSomething(-1,self.angle,self.origin,self.itemList[i],index)
+ for item in self.itemList:
+ item.drawOnCanvas(self.owner.mainCanvas,self.owner.magnification)
+ self.owner.bindItemEvents(item)
+ self.owner.updateSelection()
+ self.owner.updateCanvasSize()
+
+ def unRotF(self):
+ for i in range(len(self.itemList)):
+ for index in self.indexList[i]:
+ self.owner.rotateSomething(-1,-self.angle,self.origin,self.itemList[i],index)
+ for item in self.itemList:
+ item.drawOnCanvas(self.owner.mainCanvas,self.owner.magnification)
+ self.owner.bindItemEvents(item)
+ self.owner.updateSelection()
+ self.owner.updateCanvasSize()
+
+ def __str__(self):
+ return "Rotation of "+str(self.itemList)+str(self.indexList)+" by "+"%.3f"%(self.angle*180.0/math.pi)+" about "+str(self.origin)
+
+class addLabelAction(UndoRedoStack.action):
+ def __init__(self,owner,label):
+ self.owner = owner
+ self.label = label
+ UndoRedoStack.action.__init__(self,self.addF,self.unAddF)
+
+ def addF(self):
+ self.owner.addItemToFile(self.label)
+ self.label.drawOnCanvas(self.owner.mainCanvas,self.owner.magnification)
+ self.owner.bindItemEvents(self.label)
+
+ def unAddF(self):
+ self.label.removeFromCanvas()
+ del self.owner.fileItems[-1]
+ self.owner.propList.delete(0)
+ self.owner.clearSelection()
+
+ def __str__(self):
+ return "Addition of a label"
+
+class deleteLabelAction(UndoRedoStack.action):
+ def __init__(self,owner,label,index):
+ self.owner = owner
+ self.label = label
+ self.index = index
+ UndoRedoStack.action.__init__(self,self.delF,self.unDelF)
+
+ def delF(self):
+ self.owner.fileItems[self.index].removeFromCanvas()
+ self.owner.propList.delete(len(self.owner.fileItems)-self.index-1)
+ del self.owner.fileItems[self.index]
+
+ def unDelF(self):
+ self.owner.fileItems.insert(self.index,self.label)
+ self.owner.fileItems[self.index].drawOnCanvas(self.owner.mainCanvas,self.owner.magnification)
+ self.owner.propList.insert(len(self.owner.fileItems)-self.index-1,self.owner.describeItem(self.label))
+ self.owner.bindItemEvents(self.label)
+
+ def __str__(self):
+ return "Deletion of a label"
+
+class editLabelTextAction(UndoRedoStack.action):
+ def __init__(self,owner,label,newText,oldText):
+ self.owner = owner
+ self.label = label
+ self.newText = newText
+ self.oldText = oldText
+ UndoRedoStack.action.__init__(self,self.modT,self.unModT)
+
+ def modT(self):
+ self.label.label.setText(self.newText)
+ self.label.drawOnCanvas(self.owner.mainCanvas,self.owner.magnification)
+ self.owner.bindItemEvents(self.label)
+
+ def unModT(self):
+ self.label.label.setText(self.oldText)
+ self.label.drawOnCanvas(self.owner.mainCanvas,self.owner.magnification)
+ self.owner.bindItemEvents(self.label)
+
+ def __str__(self):
+ return "Editing a label's text"
+
+class editLabelPenAction(UndoRedoStack.action):
+ def __init__(self,owner,oldPen,newPen,index):
+ self.owner = owner
+ self.newPen = newPen
+ self.oldPen = oldPen
+ self.index = index
+ UndoRedoStack.action.__init__(self,self.editF,self.unEditF)
+
+ def editF(self):
+ self.owner.fileItems[self.index].removeFromCanvas()
+ self.owner.fileItems[self.index].label.pen = self.newPen
+ self.owner.fileItems[self.index].drawOnCanvas(self.owner.mainCanvas,self.owner.magnification)
+ self.owner.bindItemEvents(self.owner.fileItems[self.index])
+
+ def unEditF(self):
+ self.owner.fileItems[self.index].removeFromCanvas()
+ self.owner.fileItems[self.index].label.pen = self.oldPen
+ self.owner.fileItems[self.index].drawOnCanvas(self.owner.mainCanvas,self.owner.magnification)
+ self.owner.bindItemEvents(self.owner.fileItems[self.index])
+
+ def __str__(self):
+ return "Changing a label's pen"
+
+class addScriptAction(UndoRedoStack.action):
+ def __init__(self,owner,script):
+ self.owner = owner
+ self.script = script
+ UndoRedoStack.action.__init__(self,self.addF,self.unAddF)
+
+ def addF(self):
+ self.owner.addItemToFile(self.script)
+ self.script.drawOnCanvas(self.owner.mainCanvas,self.owner.magnification)
+ self.owner.bindItemEvents(self.script)
+
+ def unAddF(self):
+ self.script.removeFromCanvas()
+ del self.owner.fileItems[-1]
+ self.owner.propList.delete(0)
+ self.owner.clearSelection()
+
+ def __str__(self):
+ return "Addition of a script"
+
+class deleteScriptAction(UndoRedoStack.action):
+ def __init__(self,owner,script,index):
+ self.owner = owner
+ self.script = script
+ self.index = index
+ UndoRedoStack.action.__init__(self,self.delF,self.unDelF)
+
+ def delF(self):
+ self.owner.fileItems[self.index].removeFromCanvas()
+ self.owner.propList.delete(len(self.owner.fileItems)-self.index-1)
+ del self.owner.fileItems[self.index]
+
+ def unDelF(self):
+ self.owner.fileItems.insert(self.index,self.script)
+ self.owner.fileItems[self.index].drawOnCanvas(self.owner.mainCanvas,self.owner.magnification)
+ self.owner.propList.insert(len(self.owner.fileItems)-self.index-1,self.owner.describeItem(self.script))
+ self.owner.bindItemEvents(self.script)
+
+ def __str__(self):
+ return "Deletion of a script"
+
+class deleteScriptItemAction(UndoRedoStack.action):
+ def __init__(self,owner,script,indices,oldTransforms):
+ self.owner = owner
+ self.script = script
+ self.indices = indices[:]
+ UndoRedoStack.action.__init__(self,self.delI,self.unDelI)
+ def delI(self):
+ for index in self.indices:
+ self.script.transform[index].deleted = True
+ self.owner.mainCanvas.delete(self.script.imageList[index].IDTag)
+
+ def unDelI(self):
+ for i in range(len(self.indices)):
+ index = self.indices[i]
+ self.script.transform[index].deleted = False
+ bbox = self.script.imageList[index].originalImage.bbox
+ self.script.imageList[index].IDTag = self.owner.mainCanvas.create_image(bbox[0],-bbox[3],anchor=NW,tags=("image"),image=self.script.imageList[index].itk)
+ self.owner.bindEvents(self.script.imageList[index].IDTag)
+ self.owner.resetStacking()
+
+ def __str__(self):
+ return "Deletion of item "+str(self.indices)+" in "+str(self.script)
+
+class editScriptAction(UndoRedoStack.action):
+ def __init__(self,owner,script,newText,oldText):
+ self.owner = owner
+ self.script = script
+ self.newText = newText
+ self.oldText = oldText
+ UndoRedoStack.action.__init__(self,self.modS,self.unModS)
+
+ def modS(self):
+ self.script.setScript(self.newText)
+ self.script.drawOnCanvas(self.owner.mainCanvas,self.owner.magnification)
+ self.owner.bindItemEvents(self.script)
+
+ def unModS(self):
+ self.script.setScript(self.oldText)
+ self.script.drawOnCanvas(self.owner.mainCanvas,self.owner.magnification)
+ self.owner.bindItemEvents(self.script)
+
+ def __str__(self):
+ return "Modification of a script"
+
+class clearItemTransformsAction(UndoRedoStack.action):
+ def __init__(self,owner,item,oldTransforms):
+ self.owner = owner
+ self.item = item
+ self.oldTransforms = oldTransforms
+ UndoRedoStack.action.__init__(self,self.clearF,self.unClearF)
+
+ def clearF(self):
+ for i in range(len(self.oldTransforms)):
+ self.item.transform[i] = xasy2asy.identity()
+ self.item.drawOnCanvas(self.owner.mainCanvas,self.owner.magnification)
+
+ def unClearF(self):
+ for i in range(len(self.oldTransforms)):
+ self.item.transform[i] = self.oldTransforms[i]
+ self.item.drawOnCanvas(self.owner.mainCanvas,self.owner.magnification)
+
+ def __str__(self):
+ return "Clear the transforms of "+str(self.item)+" from "+str(self.oldTransforms)
+
+class itemRaiseAction(UndoRedoStack.action):
+ def __init__(self,owner,items,oldPositions):
+ self.owner = owner
+ self.items = items[:]
+ self.oldPositions = oldPositions[:]
+ UndoRedoStack.action.__init__(self,self.raiseI,self.unRaiseI)
+
+ def raiseI(self):
+ for item in self.items:
+ self.owner.raiseSomething(item)
+
+ def unRaiseI(self):
+ length = len(self.owner.fileItems)
+ indices = self.oldPositions[:]
+ indices = [length-i-1 for i in indices]
+ indices.reverse()
+ for index in indices:
+ for i in range(index):
+ self.owner.raiseSomething(self.owner.fileItems[length-index-1])
+
+ def __str__(self):
+ return "Raise items "+str(self.items)+" from positions "+str(self.oldPositions)
+
+class itemLowerAction(UndoRedoStack.action):
+ def __init__(self,owner,items,oldPositions):
+ self.owner = owner
+ self.items = items[:]
+ self.oldPositions = oldPositions[:]
+ UndoRedoStack.action.__init__(self,self.lowerI,self.unLowerI)
+
+ def lowerI(self):
+ for item in self.items:
+ self.owner.lowerSomething(item)
+
+ def unLowerI(self):
+ indices = self.oldPositions[:]
+ indices.reverse()
+ for index in indices:
+ for i in range(index):
+ self.owner.lowerSomething(self.owner.fileItems[index])
+
+ def __str__(self):
+ return "Lower items "+str(self.items)+" from positions "+str(self.oldPositions)
+
+class addDrawnItemAction(UndoRedoStack.action):
+ def __init__(self,owner,item):
+ self.owner = owner
+ self.item = item
+ UndoRedoStack.action.__init__(self,self.drawF,self.unDrawF)
+
+ def drawF(self):
+ self.owner.addItemToFile(self.item)
+ self.item.drawOnCanvas(self.owner.mainCanvas,self.owner.magnification,forceAddition=True)
+ self.owner.bindItemEvents(self.item)
+
+ def unDrawF(self):
+ self.item.removeFromCanvas(self.owner.mainCanvas)
+ del self.owner.fileItems[-1]
+ self.owner.propList.delete(0)
+ self.owner.clearSelection()
+
+ def __str__(self):
+ return "Drawing of an item"
+
+class deleteDrawnItemAction(UndoRedoStack.action):
+ def __init__(self,owner,item,index):
+ self.owner = owner
+ self.item = item
+ self.index = index
+ UndoRedoStack.action.__init__(self,self.delF,self.unDelF)
+
+ def delF(self):
+ self.owner.fileItems[self.index].removeFromCanvas(self.owner.mainCanvas)
+ self.owner.propList.delete(len(self.owner.fileItems)-self.index-1)
+ del self.owner.fileItems[self.index]
+
+ def unDelF(self):
+ self.owner.fileItems.insert(self.index,self.item)
+ self.owner.fileItems[self.index].drawOnCanvas(self.owner.mainCanvas,self.owner.magnification,forceAddition=True)
+ self.owner.propList.insert(len(self.owner.fileItems)-self.index-1,self.owner.describeItem(self.item))
+ self.owner.bindItemEvents(self.item)
+
+ def __str__(self):
+ return "Deletion of a drawn item"
+
+class editDrawnItemAction(UndoRedoStack.action):
+ def __init__(self,owner,oldItem,newItem,index):
+ self.owner = owner
+ self.oldItem = oldItem
+ self.newItem = newItem
+ self.index = index
+ UndoRedoStack.action.__init__(self,self.editF,self.unEditF)
+
+ def editF(self):
+ self.owner.fileItems[self.index].removeFromCanvas(self.owner.mainCanvas)
+ self.owner.fileItems[self.index].path = self.newItem.path
+ self.owner.fileItems[self.index].pen = self.newItem.pen
+ self.owner.fileItems[self.index].transform = self.newItem.transform
+ self.owner.fileItems[self.index].IDTag = self.newItem.IDTag
+ self.owner.fileItems[self.index].drawOnCanvas(self.owner.mainCanvas,self.owner.magnification,forceAddition=True)
+ self.owner.bindItemEvents(self.owner.fileItems[self.index])
+
+ def unEditF(self):
+ self.owner.fileItems[self.index].removeFromCanvas(self.owner.mainCanvas)
+ self.owner.fileItems[self.index].path = self.oldItem.path
+ self.owner.fileItems[self.index].pen = self.oldItem.pen
+ self.owner.fileItems[self.index].transform = self.oldItem.transform
+ self.owner.fileItems[self.index].IDTag = self.oldItem.IDTag
+ self.owner.fileItems[self.index].drawOnCanvas(self.owner.mainCanvas,self.owner.magnification,forceAddition=True)
+ self.owner.bindItemEvents(self.owner.fileItems[self.index])
+
+ def __str__(self):
+ return "Modification of a drawn item"
diff --git a/Build/source/utils/asymptote/GUI/xasyBezierEditor.py b/Build/source/utils/asymptote/GUI/xasyBezierEditor.py
new file mode 100755
index 00000000000..998ee4c7c25
--- /dev/null
+++ b/Build/source/utils/asymptote/GUI/xasyBezierEditor.py
@@ -0,0 +1,208 @@
+#!/usr/bin/env python
+###########################################################################
+#
+# xasyBezierEditor implements the ability to graphically edit the location
+# of the nodes and control points of a bezier curve.
+#
+#
+# Author: Orest Shardt
+# Created: June 29, 2007
+#
+###########################################################################
+
+from Tkinter import *
+import math
+from CubicBezier import *
+import xasy2asy
+
+class node:
+ def __init__(self,precontrol,node,postcontrol,uid,isTied = True):
+ self.node = node
+ self.precontrol = precontrol
+ self.postcontrol = postcontrol
+ self.isTied = isTied
+ self.uid = uid
+ self.nodeID = self.precontrolID = self.prelineID = self.postcontrolID = self.postlineID = None
+
+ def shiftNode(self,delta):
+ self.node = (self.node[0]+delta[0],self.node[1]+delta[1])
+ if self.precontrol != None:
+ self.precontrol = (self.precontrol[0]+delta[0],self.precontrol[1]+delta[1])
+ if self.postcontrol != None:
+ self.postcontrol = (self.postcontrol[0]+delta[0],self.postcontrol[1]+delta[1])
+
+ def shiftPrecontrol(self,delta):
+ self.precontrol = (self.precontrol[0]+delta[0],self.precontrol[1]+delta[1])
+ if self.isTied and self.postcontrol != None:
+ self.rotatePostControl(self.precontrol)
+
+ def shiftPostcontrol(self,delta):
+ self.postcontrol = (self.postcontrol[0]+delta[0],self.postcontrol[1]+delta[1])
+ if self.isTied and self.precontrol != None:
+ self.rotatePrecontrol(self.postcontrol)
+
+ def rotatePrecontrol(self,after):
+ vx,vy = after[0]-self.node[0],after[1]-self.node[1]
+ l = norm((vx,vy))
+ if l == 0:
+ return
+ m = norm((self.precontrol[0]-self.node[0],self.precontrol[1]-self.node[1]))
+ vx = -m*vx/l
+ vy = -m*vy/l
+ self.precontrol = self.node[0]+vx,self.node[1]+vy
+
+ def rotatePostControl(self,after):
+ vx,vy = after[0]-self.node[0],after[1]-self.node[1]
+ l = norm((vx,vy))
+ if l == 0:
+ return
+ m = norm((self.postcontrol[0]-self.node[0],self.postcontrol[1]-self.node[1]))
+ vx = -m*vx/l
+ vy = -m*vy/l
+ self.postcontrol = self.node[0]+vx,self.node[1]+vy
+
+ def draw(self,canvas):
+ width = 3
+ if self.precontrol != None:
+ if self.prelineID == None:
+ self.prelineID = canvas.create_line(self.precontrol[0],-self.precontrol[1],self.node[0],-self.node[1],tags=("preline",self.uid))
+ else:
+ canvas.coords(self.prelineID,self.precontrol[0],-self.precontrol[1],self.node[0],-self.node[1])
+ if self.precontrolID == None:
+ self.precontrolID = canvas.create_oval(self.precontrol[0]-width,-self.precontrol[1]-width,self.precontrol[0]+width,-self.precontrol[1]+width,
+ fill="red",outline="black",tags=("precontrol",self.uid))
+ else:
+ canvas.coords(self.precontrolID,self.precontrol[0]-width,-self.precontrol[1]-width,self.precontrol[0]+width,-self.precontrol[1]+width)
+ if self.postcontrol != None:
+ if self.postlineID == None:
+ self.postlineID = canvas.create_line(self.postcontrol[0],-self.postcontrol[1],self.node[0],-self.node[1],tags=("postline",self.uid))
+ else:
+ canvas.coords(self.postlineID,self.postcontrol[0],-self.postcontrol[1],self.node[0],-self.node[1])
+ if self.postcontrolID == None:
+ self.postcontrolID = canvas.create_oval(self.postcontrol[0]-width,-self.postcontrol[1]-width,self.postcontrol[0]+width,-self.postcontrol[1]+width,
+ fill="red",outline="black",tags=("postcontrol",self.uid))
+ else:
+ canvas.coords(self.postcontrolID,self.postcontrol[0]-width,-self.postcontrol[1]-width,self.postcontrol[0]+width,-self.postcontrol[1]+width)
+ if self.isTied:
+ color = "blue"
+ else:
+ color = "green"
+ if self.nodeID == None:
+ self.nodeID = canvas.create_oval(self.node[0]-width,-self.node[1]-width,self.node[0]+width,-self.node[1]+width,
+ fill=color,outline="black",tags=("node",self.uid))
+ else:
+ canvas.coords(self.nodeID,self.node[0]-width,-self.node[1]-width,self.node[0]+width,-self.node[1]+width)
+ canvas.itemconfigure(self.nodeID,fill=color)
+
+class xasyBezierEditor:
+ def __init__(self,parent,shape,canvas):
+ self.parent = parent
+ self.shape = shape
+ self.transform = self.shape.transform[0]
+ self.path = self.shape.path
+ self.canvas = canvas
+ self.modified = False
+ self.path.computeControls()
+ isCyclic = self.path.nodeSet[-1] == 'cycle'
+ segments = len(self.path.controlSet)
+ self.nodeList = []
+ for i in range(segments):
+ if i == 0:
+ node0 = self.transform*self.path.nodeSet[i]
+ control = self.transform*self.path.controlSet[i][0]
+ self.nodeList.append(node(None,node0,control,len(self.nodeList)))
+ else:
+ node0 = self.transform*self.path.nodeSet[i]
+ precontrol = self.transform*self.path.controlSet[i-1][1]
+ postcontrol = self.transform*self.path.controlSet[i][0]
+ self.nodeList.append(node(precontrol,node0,postcontrol,len(self.nodeList)))
+ if not isCyclic:
+ node0 = self.transform*self.path.nodeSet[-1]
+ precontrol = self.transform*self.path.controlSet[-1][1]
+ self.nodeList.append(node(precontrol,node0,None,len(self.nodeList)))
+ else:
+ self.nodeList[0].precontrol = self.transform*self.path.controlSet[-1][1]
+ self.showControls()
+ self.bindNodeEvents()
+ self.bindControlEvents()
+
+ def showControls(self):
+ for n in self.nodeList:
+ n.draw(self.canvas)
+ self.bindNodeEvents()
+ self.bindControlEvents()
+ self.parent.updateCanvasSize()
+
+ def bindNodeEvents(self):
+ self.canvas.tag_bind("node","<B1-Motion>",self.nodeDrag)
+ self.canvas.tag_bind("node","<Button-1>",self.buttonDown)
+ self.canvas.tag_bind("node","<Double-Button-1>",self.toggleNode)
+
+ def unbindNodeEvents(self):
+ self.canvas.tag_unbind("node","<B1-Motion>")
+ self.canvas.tag_unbind("node","<Button-1>")
+ self.canvas.tag_unbind("node","<Double-Button-1>")
+
+ def bindControlEvents(self):
+ self.canvas.tag_bind("precontrol || postcontrol","<B1-Motion>",self.controlDrag)
+ self.canvas.tag_bind("precontrol || postcontrol","<Button-1>",self.buttonDown)
+
+ def unbindControlEvents(self):
+ self.canvas.tag_unbind("precontrol || postcontrol","<B1-Motion>")
+ self.canvas.tag_unbind("precontrol || postcontrol","<Button-1>")
+
+ def buttonDown(self,event):
+ self.parent.freeMouseDown = False
+ self.startx,self.starty = event.x,event.y
+
+ def toggleNode(self,event):
+ self.parent.freeMouseDown = False
+ tags = self.canvas.gettags(CURRENT)
+ obj = tags[0]
+ uid = int(tags[1])
+ self.nodeList[uid].isTied = not self.nodeList[uid].isTied
+ self.showControls()
+
+ def nodeDrag(self,event):
+ self.parent.freeMouseDown = False
+ deltax = event.x-self.startx
+ deltay = event.y-self.starty
+ tags = self.canvas.gettags(CURRENT)
+ obj = tags[0]
+ uid = int(tags[1])
+ self.nodeList[uid].shiftNode((deltax,-deltay))
+ self.startx,self.starty = event.x,event.y
+ self.applyChanges()
+ self.showControls()
+ self.shape.drawOnCanvas(self.canvas,self.parent.magnification)
+
+ def controlDrag(self,event):
+ self.parent.freeMouseDown = False
+ deltax = event.x-self.startx
+ deltay = event.y-self.starty
+ tags = self.canvas.gettags(CURRENT)
+ obj = tags[0]
+ uid = int(tags[1])
+ if obj == "precontrol":
+ self.nodeList[uid].shiftPrecontrol((deltax,-deltay))
+ elif obj == "postcontrol":
+ self.nodeList[uid].shiftPostcontrol((deltax,-deltay))
+ self.startx,self.starty = event.x,event.y
+ self.applyChanges()
+ self.showControls()
+ self.shape.drawOnCanvas(self.canvas,self.parent.magnification)
+
+ def applyChanges(self):
+ self.modified = True
+ self.shape.transform[0] = xasy2asy.asyTransform((0,0,1,0,0,1))
+ for i in range(len(self.nodeList)):
+ self.path.nodeSet[i] = self.nodeList[i].node
+ if self.nodeList[i].postcontrol != None:
+ self.path.controlSet[i][0] = self.nodeList[i].postcontrol
+ if self.nodeList[i].precontrol != None:
+ self.path.controlSet[i-1][1] = self.nodeList[i].precontrol
+
+ def endEdit(self):
+ self.unbindNodeEvents()
+ self.unbindControlEvents()
+ self.canvas.delete("node || precontrol || postcontrol || preline || postline")
diff --git a/Build/source/utils/asymptote/GUI/xasyCodeEditor.py b/Build/source/utils/asymptote/GUI/xasyCodeEditor.py
new file mode 100755
index 00000000000..93e06e447ee
--- /dev/null
+++ b/Build/source/utils/asymptote/GUI/xasyCodeEditor.py
@@ -0,0 +1,37 @@
+#!/usr/bin/env python
+###########################################################################
+#
+# xasyCodeEditor implements a simple text editor for Asymptote scripts in
+# xasy.
+#
+#
+# Author: Orest Shardt
+# Created: June 29, 2007
+#
+############################################################################
+
+from subprocess import call
+from tempfile import mkstemp
+from os import remove
+from os import fdopen
+from string import split
+import xasyOptions
+
+def getText(text=""):
+ """Launch the external editor"""
+ temp = mkstemp()
+ tempf = fdopen(temp[0],"r+w")
+ tempf.write(text)
+ tempf.flush()
+ try:
+ call(split(xasyOptions.options['externalEditor'])+[temp[1]])
+ except:
+ raise Exception('Error launching external editor.')
+ tempf.seek(0)
+ text = tempf.read()
+ remove(temp[1])
+ return text
+
+if __name__ == '__main__':
+ #run a test
+ print getText("Here is some text to edit")
diff --git a/Build/source/utils/asymptote/GUI/xasyColorPicker.py b/Build/source/utils/asymptote/GUI/xasyColorPicker.py
new file mode 100755
index 00000000000..7415be205c4
--- /dev/null
+++ b/Build/source/utils/asymptote/GUI/xasyColorPicker.py
@@ -0,0 +1,248 @@
+#!/usr/bin/env python
+###########################################################################
+#
+# xasyColorPicker implements a dialog that allows a user to choose a color
+# from those already defined in Asymptote or a custom RGB color.
+#
+#
+# Author: Orest Shardt
+# Created: June 29, 2007
+#
+############################################################################
+
+from Tkinter import *
+import tkColorChooser
+asyColors = { "black":(0,0,0),
+ "white":(1,1,1),
+ "gray":(0.5,0.5,0.5),
+ "red":(1,0,0),
+ "green":(0,1,0),
+ "blue":(0,0,1),
+ "cmyk":(1,1,1),
+ "Cyan":(0,1,1),
+ "Magenta":(1,0,1),
+ "Yellow":(1,1,0),
+ "Black":(0,0,0),
+ "cyan":(0,1,1),
+ "magenta":(1,0,1),
+ "yellow":(1,1,0),
+ "palered":(1,0.75,0.75),
+ "palegreen":(0.75,1,0.75),
+ "paleblue":(0.75,0.75,1),
+ "palecyan":(0.75,1,1),
+ "palemagenta":(1,0.75,1),
+ "paleyellow":(1,1,0.75),
+ "palegray":(0.95,0.95,0.95),
+ "lightred":(1,0.5,0.5),
+ "lightgreen":(0.5,1,0.5),
+ "lightblue":(0.5,0.5,1),
+ "lightcyan":(0.5,1,1),
+ "lightmagenta":(1,0.5,1),
+ "lightyellow":(1,1,0.5),
+ "lightgray":(0.9,0.9,0.9),
+ "mediumred":(1,0.25,0.25),
+ "mediumgreen":(0.25,1,0.25),
+ "mediumblue":(0.25,0.25,1),
+ "mediumcyan":(0.25,1,1),
+ "mediummagenta":(1,0.25,1),
+ "mediumyellow":(1,1,0.25),
+ "mediumgray":(0.75,0.75,0.75),
+ "heavyred":(0.75,0,0),
+ "heavygreen":(0,0.75,0),
+ "heavyblue":(0,0,0.75),
+ "heavycyan":(0,0.75,0.75),
+ "heavymagenta":(0.75,0,0.75),
+ "lightolive":(0.75,0.75,0),
+ "heavygray":(0.25,0.25,0.25),
+ "deepred":(0.5,0,0),
+ "deepgreen":(0,0.5,0),
+ "deepblue":(0,0,0.5),
+ "deepcyan":(0,0.5,0.5),
+ "deepmagenta":(0.5,0,0.5),
+ "olive":(0.5,0.5,0),
+ "deepgray":(0.1,0.1,0.1),
+ "darkred":(0.25,0,0),
+ "darkgreen":(0,0.25,0),
+ "darkblue":(0,0,0.25),
+ "darkcyan":(0,0.25,0.25),
+ "darkmagenta":(0.25,0,0.25),
+ "darkolive":(0.25,0.25,0),
+ "darkgray":(0.05,0.05,0.05),
+ "orange":(1,0.5,0),
+ "fuchsia":(1,0,0.5),
+ "chartreuse":(0.5,1,0),
+ "springgreen":(0,1,0.5),
+ "purple":(0.5,0,1),
+ "royalblue":(0,0.5,1)
+ }
+colorLayout = [['palered',
+ 'lightred',
+ 'mediumred',
+ 'red',
+ 'heavyred',
+ 'deepred',
+ 'darkred',
+ 'palegreen',
+ 'lightgreen',
+ 'mediumgreen',
+ 'green',
+ 'heavygreen',
+ 'deepgreen',
+ 'darkgreen',
+ 'paleblue',
+ 'lightblue',
+ 'mediumblue',
+ 'blue',
+ 'heavyblue',
+ 'deepblue',
+ 'darkblue'],
+ ['palecyan',
+ 'lightcyan',
+ 'heavycyan',
+ 'deepcyan',
+ 'darkcyan',
+ 'palemagenta',
+ 'lightmagenta',
+ 'mediummagenta',
+ 'magenta',
+ 'heavymagenta',
+ 'deepmagenta',
+ 'darkmagenta',
+ 'yellow',
+ 'lightyellow',
+ 'mediumyellow',
+ 'yellow',
+ 'lightolive',
+ 'olive',
+ 'darkolive',
+ 'palegray',
+ 'lightgray',
+ 'mediumgray',
+ 'gray',
+ 'heavygray',
+ 'deepgray',
+ 'darkgray'],
+ ['black',
+ 'white',
+ 'orange',
+ 'fuchsia',
+ 'chartreuse',
+ 'springgreen',
+ 'purple',
+ 'royalblue',
+ 'Cyan',
+ 'Magenta',
+ 'Yellow',
+ 'Black']]
+
+def makeRGBfromTkColor(tkColor):
+ """Convert a Tk color of the form #rrggbb to an asy rgb color"""
+ r = int('0x'+tkColor[1:3],16)
+ g = int('0x'+tkColor[3:5],16)
+ b = int('0x'+tkColor[5:7],16)
+ r /= 255.0
+ g /= 255.0
+ b /= 255.0
+ return (r,g,b)
+
+def RGBreal255((r,g,b)):
+ """Convert an RGB color from 0-1 to 0-255"""
+ a,b,c = (256*r,256*g,256*b)
+ if a == 256:
+ a = 255
+ if b == 256:
+ b = 255
+ if c == 256:
+ c = 255
+ return map(int,(a,b,c))
+
+def RGB255hex((r,g,b)):
+ """Make a color in the form #rrggbb in hex from r,g,b in 0-255"""
+ rs,gs,bs = map(hex,(r,g,b))
+ rs,gs,bs = rs[2:],gs[2:],bs[2:]
+ if len(rs) < 2:
+ rs += '0'
+ if len(gs) < 2:
+ gs += '0'
+ if len(bs) < 2:
+ bs += '0'
+ return '#'+rs+gs+bs
+
+class xasyColorDlg(Toplevel):
+ """A dialog for choosing an asymptote color. It displays the usual asy presets and allows custom rgb colors"""
+ def __init__(self,master=None,color=(0,0,0)):
+ Toplevel.__init__(self,master,width=500,height=500)
+ self.resizable(False,False)
+ self.parent = master
+ self.title("Color Picker")
+ self.transient(master)
+ self.focus_set()
+ self.wait_visibility()
+ self.grab_set()
+ self.color = self.oldColor = color
+ cwidth = 120
+ rheight = 20
+ self.pframe=Frame(self,bd=0)
+ self.pframe.rowconfigure(0,weight=1)
+ self.pframe.columnconfigure(0,weight=1)
+ Label(self.pframe,text="Color Presets").grid(row=0,column=0)
+ self.colScroll = Scrollbar(self.pframe,orient=VERTICAL)
+ self.colorList = Canvas(self.pframe, width=cwidth*len(colorLayout), scrollregion=(0,0,20+cwidth*len(colorLayout),20+rheight*max([len(i) for i in colorLayout])),yscrollcommand=self.colScroll.set,relief=FLAT)
+ self.colScroll.config(command=self.colorList.yview)
+ self.colScroll.grid(row=1,column=1,sticky=N+S)
+ self.colorList.grid(row=1,column=0,sticky=W)
+ ccount = 0
+ for column in colorLayout:
+ rcount = 0
+ for name in column:
+ self.colorList.create_rectangle(10+cwidth*ccount,10+rheight*rcount,cwidth*ccount+25,rheight*rcount+25,tags=(name,"preset"),fill=RGB255hex(RGBreal255(asyColors[name])))
+ self.colorList.create_text(cwidth*ccount+30,10+rheight*rcount,text=name,anchor=NW,tags=(name,"preset"),fill="black",activefill=RGB255hex(RGBreal255(asyColors[name])))
+ rcount += 1
+ ccount += 1
+ self.colorList.tag_bind("preset","<Button-1>",self.setColorEvt)
+ Button(self,text="Custom color...",command=self.getCustom).grid(row=2,column=0,sticky=W,padx=5,pady=5)
+ self.colDisp = Canvas(self,width=200,height=20,background=RGB255hex(RGBreal255(self.color)),relief=SUNKEN, bd=3)
+ self.colDisp.grid(row=2,column=1,columnspan=2)
+ self.rowconfigure(3,minsize=10)
+ self.columnconfigure(0,weight=1)
+ self.columnconfigure(1,weight=1)
+ self.columnconfigure(2,weight=1)
+ Button(self,text="OK",default=ACTIVE,command=self.destroy).grid(row=4,column=1,sticky=E+W,padx=5,pady=5)
+ Button(self,text="Cancel",command=self.cancel).grid(row=4,column=2,sticky=E+W,padx=5,pady=5)
+ self.pframe.grid(row=1,column=0,columnspan=3,padx=10,pady=10)
+ self.bind("<Return>",self.closeUp)
+ self.setColor(color)
+ def closeUp(self,event):
+ """Close the dialog forcibly"""
+ self.destroy()
+ def getCustom(self):
+ """Request a custom RGB color using a tkColorChooser"""
+ result=tkColorChooser.askcolor(initialcolor=RGB255hex(RGBreal255(self.color)),title="Custom Color",parent=self)
+ if result != (None,None):
+ self.setColor((result[0][0]/255.0,result[0][1]/255.0,result[0][2]/255.0))
+ def cancel(self):
+ """Respond to the user pressing cancel"""
+ self.color = self.oldColor
+ self.destroy()
+ def setColor(self,color):
+ """Save the color and update the color display"""
+ self.color = color
+ self.colDisp.configure(background=RGB255hex(RGBreal255(self.color)))
+ def setColorEvt(self,event):
+ """Respond to the user clicking a color from the palette"""
+ self.setColor(asyColors[self.colorList.gettags(CURRENT)[0]])
+ def getColor(self,initialColor=(0,0,0)):
+ """Use this method to prompt for a color. It returns the new color or the old color if the user cancelled the operation.
+
+ e.g:
+ print xasyColorDlg(Tk()).getColor((1,1,0))
+ """
+ self.setColor(initialColor)
+ self.oldColor = initialColor
+ self.wait_window(self)
+ return self.color
+
+if __name__ == '__main__':
+ root = Tk()
+ Button(root,text="Pick Color",command=lambda:xasyColorDlg(root).getColor()).pack()
+ root.mainloop()
diff --git a/Build/source/utils/asymptote/GUI/xasyExample.asy b/Build/source/utils/asymptote/GUI/xasyExample.asy
new file mode 100644
index 00000000000..c251d45acb4
--- /dev/null
+++ b/Build/source/utils/asymptote/GUI/xasyExample.asy
@@ -0,0 +1,63 @@
+initXasyMode();
+// This file was generated by xasy. It may be edited manually, however, a strict
+// syntax must be followed. It is advised that manually scripted items be added
+// in the form of a script either by using xasy or by mimicking the format of an
+// xasy-generated script item.
+// Please consult the documentation or the examples provided for details.
+xformStack.add(indexedTransform(0,(0, 0, 1, 0, 0, 1)),
+indexedTransform(1,(0, 0, 1, 0, 0, 1)),
+indexedTransform(2,(0, 0, 1, 0, 0, 1)),
+indexedTransform(3,(0, 0, 1, 0, 0, 1)),
+indexedTransform(4,(0, 0, 1, 0, 0, 1)),
+indexedTransform(5,(0, 0, 1, 0, 0, 1)),
+indexedTransform(6,(0, 0, 1, 0, 0, 1)),
+indexedTransform(7,(0, 0, 1, 0, 0, 1)),
+indexedTransform(8,(0, 0, 1, 0, 0, 1)),
+indexedTransform(9,(0, 0, 1, 0, 0, 1)),
+indexedTransform(10,(0, 0, 1, 0, 0, 1)),
+indexedTransform(11,(0, 0, 1, 0, 0, 1)),
+indexedTransform(12,(0, 0, 1, 0, 0, 1)));
+startScript(); {
+size(0,150);
+
+pen colour1=red;
+pen colour2=green;
+
+pair z0=(0,0);
+pair z1=(-1,0);
+pair z2=(1,0);
+real r=1.5;
+guide c1=circle(z1,r);
+guide c2=circle(z2,r);
+fill(c1,colour1);
+fill(c2,colour2);
+
+picture intersection;
+fill(intersection,c1,colour1+colour2);
+clip(intersection,c2);
+
+add(intersection);
+
+draw(c1);
+draw(c2);
+
+label("$A$",z1);
+label("$B$",z2);
+
+pair z=(0,-2);
+real m=3;
+margin BigMargin=Margin(0,m*dot(unit(z1-z),unit(z0-z)));
+
+draw(Label("$A\cap B$",0),conj(z)--z0,Arrow,BigMargin);
+draw(Label("$A\cup B$",0),z--z0,Arrow,BigMargin);
+draw(z--z1,Arrow,Margin(0,m));
+draw(z--z2,Arrow,Margin(0,m));
+} endScript();
+
+
+xformStack.push((-28.0, 7.0, 1, 0, 0, 1));
+label(Label("A Venn Diagram",(-79.0, 91.0),rgb(0,0,0)+0.5,align=SE));
+
+// This is the end of the file
+exitXasyMode();
+
diff --git a/Build/source/utils/asymptote/GUI/xasyFile.py b/Build/source/utils/asymptote/GUI/xasyFile.py
new file mode 100755
index 00000000000..890f1ad3eef
--- /dev/null
+++ b/Build/source/utils/asymptote/GUI/xasyFile.py
@@ -0,0 +1,315 @@
+#!/usr/bin/env python
+###########################################################################
+#
+# xasyFile implements the loading, parsing, and saving of an xasy file.
+#
+#
+# Author: Orest Shardt
+# Created: June 29, 2007
+#
+############################################################################
+
+from string import *
+from xasy2asy import *
+import re
+
+class xasyParseError(Exception):
+ """A parsing error"""
+ pass
+
+class xasyFileError(Exception):
+ """An i/o error or other error not related to parsing"""
+ pass
+
+def parseFile(inFile):
+ """Parse a file returning a list of xasyItems"""
+ lines = inFile.read()
+ lines = lines.splitlines()
+ #lines = [line for line in lines.splitlines() if not line.startswith("//")]
+ result = []
+ if lines[0] != "initXasyMode();":
+ raise xasyFileError,"Invalid file format: First line must be \"initXasyMode();\""
+ lines.pop(0)
+ lineCount = 2
+ lineNum = len(lines)
+ while lineNum > 0:
+ line = lines[0]
+ lines.pop(0)
+ if not line.isspace() and len(line)>0:
+ try:
+ #print "Line %d: %s"%(lineCount,line),
+ lineResult = parseLine(line.strip(),lines)
+ except:
+ raise xasyParseError,"Parsing error: line %d in %s\n%s"%(lineCount,inFile.name,line)
+
+ if lineResult != None:
+ result.append(lineResult)
+ #print "\tproduced: %s"%str(lineResult)
+ lineCount += lineNum-len(lines)
+ lineNum = len(lines)
+ return result
+
+transformPrefix = "xformStack"
+scriptPrefix = "startScript(); {"
+scriptSuffix = "} endScript();"
+def extractScript(lines):
+ """Find the code belonging to a script item"""
+ theScript = ""
+ line = lines.pop(0)
+ level = 1
+ while level > 0:
+ check = line.lstrip()
+ while check.endswith(scriptSuffix):
+ level -= 1
+ line = line[:len(line)-len(scriptSuffix)]
+ check = line.lstrip()
+ if check.startswith(scriptPrefix):
+ level += 1
+ theScript += line + "\n"
+ if level > 0:
+ line = lines.pop(0)
+
+ global pendingTransformsD
+ ts = pendingTransformsD[:]
+ pendingTransformsD = []
+ return xasyScript(None,script=theScript,transforms=ts[:])
+
+pendingTransforms = []
+pendingTransformsD = []
+def addTransform(index,t,active=1):
+ """Place a transform in the list of transforms, expanding the list as needed"""
+ while len(pendingTransformsD) < index+1:
+ pendingTransformsD.append(identity())
+ deleted = int(active==0)
+ pendingTransformsD[index]=asyTransform(t,deleted)
+
+def parseIndexedTransforms(args):
+ """Parse a list of indexedTransforms, adding them to the current list of transforms"""
+ global pendingTransformsD
+ pendingTransformsD = []
+ args = args.replace("indexedTransform","")
+ false = 0
+ tList = [eval(a) for a in ")?(".join(args.split("),(")).split("?")]
+ for a in tList:
+ addTransform(*a)
+
+def parseTransformExpression(line):
+ """Parse statements related to the xformStack
+
+ Syntax:
+ xformStack.push(transform)
+ e.g.: xformStack.push((0,0,1,0,0,1)); //the identity
+ xformStack.add(indexedTransform(index,transform)[,...])
+ e.g.: xformStack.add(indexedTransform(1,(0,0,1,0,0,1));
+ """
+ global pendingTransforms
+ stackCmd = line[len(transformPrefix)+1:line.find("(")]
+ if line[-2:] != ");":
+ raise xasyParseError,"Invalid syntax"
+ args = line[line.find("(")+1:-2]
+ if stackCmd == "push":
+ t = asyTransform(eval(args))
+ pendingTransforms.append(t)
+ elif stackCmd == "add":
+ parseIndexedTransforms(args)
+ else:
+ raise xasyParseError,"Invalid transform stack command."
+ return None
+
+def parseLabel(line):
+ """Parse an asy Label statement, returning an xasyText item"""
+ if not (line.startswith("Label(") and line.endswith(",align=SE)")):
+ raise xasyParseError,"Invalid syntax"
+ args = line[6:-1]
+ loc2 = args.rfind(",align=SE")
+ loc1 = args.rfind(",",0,loc2-1)
+ loc = args.rfind(",(",0,loc1-1)
+ if loc < 2:
+ raise xasyParseError,"Invalid syntax"
+ text = args[1:loc-1]
+ location = eval(args[loc+1:args.find("),",loc)+1])
+ pen = args[loc:loc2]
+ pen = pen[pen.find(",")+1:]
+ pen = pen[pen.find(",")+1:]
+ pen = pen[pen.find(",")+1:]
+ global pendingTransforms
+ return xasyText(text,location,parsePen(pen),pendingTransforms.pop())
+
+def parseLabelCommand(line):
+ """Parse a label command returning an xasyText object
+
+ Syntax:
+ label(Label(text,location,pen,align=SE));
+ e.g.: label(Label("Hello world!",(0,0),rgb(0,0,0)+0.5,align=SE));
+ """
+ if line[-2:] != ");":
+ raise xasyParseError,"Invalid syntax"
+ arguments = line[6:-2]
+ return parseLabel(arguments)
+
+def parseDrawCommand(line):
+ """Parse a draw command returning an xasyShape object
+
+ Syntax:
+ draw(path,pen);
+ e.g.: draw((0,0)..controls(0.33,0.33)and(0.66,0.66)..(1,1),rgb(1,0,1)+1.5);
+ """
+ if line[-2:] != ");":
+ raise xasyParseError,"Invalid syntax"
+ args = line[5:-2]
+ loc = args.rfind(",rgb")
+ path = args[:loc]
+ pen = args[loc+1:]
+ global pendingTransforms
+ return xasyShape(parsePathExpression(path),parsePen(pen),pendingTransforms.pop())
+
+def parseFillCommand(line):
+ """Parse a fill command returning an xasyFilledShape object
+
+ Syntax:
+ fill(cyclic path,pen);
+ e.g.: fill((0,0)..controls(0.33,0.33)and(0.66,0.66)..(1,1)..controls(0.66,0)and(0.33,0)..cycle,rgb(1,0,1)+1.5);
+ """
+ if line[-2:] != ");":
+ raise xasyParseError,"Invalid syntax"
+ args = line[5:-2]
+ loc = args.rfind(",rgb")
+ path = args[:loc]
+ pen = args[loc+1:]
+ global pendingTransforms
+ return xasyFilledShape(parsePathExpression(path),parsePen(pen),pendingTransforms.pop())
+
+def parsePen(pen):
+ """Parse a pen expression returning an asyPen
+
+ Syntax:
+ color+width[+options]
+ e.g.: rgb(0,0,0)+1.5+evenodd
+ e.g.: rgb(0,1,0)+1.23
+ """
+ try:
+ tokens = pen.split("+")
+ color = eval(tokens[0][3:])
+ width = float(tokens[1])
+ if len(tokens)>2:
+ options = "+".join(tokens[2:])
+ else:
+ options = ""
+ return asyPen(color,width,options)
+ except:
+ raise xasyParseError,"Invalid pen"
+
+def parsePathExpression(expr):
+ """Parse an asy path returning an asyPath()"""
+ result = asyPath()
+ expr = "".join(expr.split())
+ #print expr
+ if expr.find("controls") != -1:
+ #parse a path with control points
+ tokens = expr.split("..")
+ nodes = [a for a in tokens if not a.startswith("controls")]
+ for a in range(len(nodes)):
+ if nodes[a] != "cycle":
+ nodes[a] = eval(nodes[a])
+ controls = [map(eval,a.replace("controls","").split("and")) for a in tokens if a.startswith("controls")]
+ result.initFromControls(nodes, controls)
+ else:
+ #parse a path without control points
+ tokens = re.split(r"(::|--|\.\.)",expr)
+ linkSet = re.findall("::|--|\.\.",expr)
+ nodeSet = [a for a in tokens if not re.match(r"::|--|\.\.",a)]
+ #print nodeSet
+ for a in range(len(nodeSet)):
+ if nodeSet[a] != "cycle":
+ nodeSet[a] = eval(nodeSet[a])
+ #print nodeSet
+ result.initFromNodeList(nodeSet, linkSet)
+ return result
+
+def takeUntilSemicolon(line,lines):
+ """Read and concatenate lines until the collected lines end with a semicolon"""
+ data = line
+ while not data.endswith(";"):
+ newline = lines.pop(0)
+ data += newline
+ return data
+
+def parseLine(line,lines):
+ """Parse a line of the file"""
+ if len(line)==0 or line.isspace() or line.startswith("//"):
+ return None
+ elif line.startswith(scriptPrefix):
+ return extractScript(lines)
+ elif line.startswith(transformPrefix):
+ return parseTransformExpression(takeUntilSemicolon(line,lines))
+ elif line.startswith("label("):
+ return parseLabelCommand(takeUntilSemicolon(line,lines))
+ elif line.startswith("draw("):
+ return parseDrawCommand(takeUntilSemicolon(line,lines))
+ elif line.startswith("fill("):
+ return parseFillCommand(takeUntilSemicolon(line,lines))
+ elif line.startswith("exitXasyMode();"):
+ return None
+ raise Exception,"Could not parse the line"
+
+fileHeader = """initXasyMode();
+// This file was generated by xasy. It may be edited manually, however, a strict
+// syntax must be followed. It is advised that manually scripted items be added
+// in the form of a script either by using xasy or by mimicking the format of an
+// xasy-generated script item.
+// Please consult the documentation or the examples provided for details.
+"""
+
+fileFooter = """// This is the end of the file
+exitXasyMode();
+
+"""
+
+def saveFile(file,xasyItems):
+ """Write a list of xasyItems to a file"""
+ file.write(fileHeader)
+ for item in xasyItems:
+ file.write(item.getCode()+"\n\n")
+ file.write(fileFooter)
+
+if __name__ == '__main__':
+ root = Tk()
+ try:
+ name = raw_input("enter file name (\"../../xasyTest.asy\"):")
+ if name == '':
+ name = "../../xasyTest.asy"
+ f = open(name,"rt")
+ except:
+ print "Could not open file."
+ asy.quit()
+ sys.exit(1)
+
+ fileItems = []
+ try:
+ fileItems = parseFile(f)
+ res = map(str,fileItems)
+ print "----------------------------------"
+ print "Objects in %s"%f.name
+ print "----------------------------------"
+ for a in res:
+ print a
+ print "----------------------------------"
+ print "successful parse"
+ f.close()
+ except:
+ f.close()
+ print "parse failed"
+ raise
+
+ print "making a file"
+ f = open("testfile.asy","wt")
+ saveFile(f,fileItems)
+ f.close()
+ root.configure(width=500,height=500)
+ root.title("Results")
+ canv = Canvas(root,width=500,height=500)
+ canv.pack()
+ for i in fileItems[1].imageList:
+ canv.create_image(250+i.bbox[0],250-i.bbox[3],anchor = NW, image=i.image)
+ Button(root,image=i.image).pack(side=LEFT)
+ root.mainloop()
diff --git a/Build/source/utils/asymptote/GUI/xasyGUIIcons.py b/Build/source/utils/asymptote/GUI/xasyGUIIcons.py
new file mode 100755
index 00000000000..3afecfd349c
--- /dev/null
+++ b/Build/source/utils/asymptote/GUI/xasyGUIIcons.py
@@ -0,0 +1,92 @@
+#!/usr/bin/env python
+##################################################################
+# This file stores the icons used by the xasy GUI
+#
+# About images and base64
+#
+# Suppose you have image.gif and want to create a base64
+# string. This can be accomplished using:
+#
+# import base64
+# base64.encodestring(open("image.gif","rb").read())
+#
+# The resulting output, including the enclosing single quotes,
+# is the base64 encoding of the image and can be used in the
+# dictionary below.
+#
+#
+# Suppose you have a base64 string, b64str, and want to create
+# an image. This can be accomplished using:
+#
+# import base64
+# open("image.gif","w").write(base64.decodestring(b64str))
+#
+#
+# Author: Orest Shardt
+# Created: June 29, 2007
+#
+##################################################################
+import base64
+import os
+#toolbar icon image data in base64 eliminates need to worry about files
+#these are the base64 encodings of the content of the directory xasy3Imgs
+iconB64 = {
+'lower': 'R0lGODlhGAAYAPEBAAAAAP///8zMzAAAACH5BAEAAAIALAAAAAAYABgAAAItlI+py+0Po5yUgosz\nrrybK2giqADed6LHKCZm+p7xx2Zuqsqr95KcJpv9cJUCADs=\n',
+'rotate': 'R0lGODlhGAAYAPAAAAAAAAAAACH5BAEAAAEALAAAAAAYABgAAAI7jI8JkO231mux1mkistL1zX0Q\ng2Fi6aGmurKp+8KKrJB0Zt+nzOQw6XPZgqjczuQ7eohKEDKoUYWIgQIAOw==\n',
+'raise': 'R0lGODlhGAAYAPEBAAAAAP///8zMzAAAACH5BAEAAAIALAAAAAAYABgAAAIwlI+pywgND3ixzVvZ\nNDSn3nlKKH7fhaZmObKtk8Yh6dKlLcfC5vZ1jvIJh8SikVUAADs=\n',
+'fillPoly': 'R0lGODlhGAAYAPEAAAAAAIOBgwAAAAAAACH5BAEAAAIALAAAAAAYABgAAAJGlI+py+0PEYgNBDCp\nDPxqY3UcRoViRzrmKWbLyqIMHI9vHbsbfuoHjfOBcrlbT0ATIo+gldKpMD1lL8vUo5oqS9vS5wsp\nAAA7\n',
+'move': 'R0lGODlhGAAYAIABAAAAAP///yH5BAEAAAEALAAAAAAYABgAAAI4jI+py+0I3gNUNhqtwlVD7m3h\nkoVdUJ4MaKTYysVymbDoYcM4Tmv9eAO2cp6YEKUavY5BpvMZKgAAOw==\n',
+'drawBezi': 'R0lGODlhGAAYAPEBAAAAAP///6usrQAAACH5BAEAAAIALAAAAAAYABgAAAI6lI+py+0AnYRUKhox\nsFvUFDXdM4LWUaKnEaorhqSX1noPmMquWJukzpr0YitRcfE5oobFpPIJjUoZBQA7\n',
+'vertiMove': 'R0lGODlhGAAYAIABAAAAAP///yH5BAEAAAEALAAAAAAYABgAAAIsjI+py+0I3gNUNhqtwlVD7m3h\nko2QmZRooKKt+Y5xOFtc7dwrtrLd3gsKTQUAOw==\n',
+'horizMove': 'R0lGODlhGAAYAIABAAAAAP///yH5BAEAAAEALAAAAAAYABgAAAIljI+py+0Po5y02oshAGu/7Skg\n143mSYpgGTYt8mbyTNf2jedWAQA7\n',
+'fillEllip': 'R0lGODlhGAAYAPECAAAAAIOBg////6usrSH5BAEAAAMALAAAAAAYABgAAAJAnI+py+0PowS0gkmD\n3qE6wIXctYDi2SkmepLGyrYHHIcuXW93Lr+86BrgakHfrzjjIRGVFgVjWUqm1Kr1ijUUAAA7\n',
+'text': 'R0lGODlhGAAYAIABAAAAAP///yH5BAEAAAEALAAAAAAYABgAAAI+jI+py+0Po5x0AgSu1SZvHnhS\nBnpio5Ukt2Idm3bysYrnddLwy+czH0rhFDkbTigj6UzKl68CjUqn1Ko1UAAAOw==\n',
+'drawPoly': 'R0lGODlhGAAYAPAAAAAAAAAAACH5BAEAAAEALAAAAAAYABgAAAI4jI+py+0PEYhtgkmlzgFL/4DJ\nFULiVi4ns66smrUxrMj1fdqHR+60kfPdgCwLzbWTIU1LE+cJKQAAOw==\n',
+'drawLines': 'R0lGODlhGAAYAPEBAAAAAP///6usrQAAACH5BAEAAAIALAAAAAAYABgAAAI3lI+py+0AnYRAPmoZ\njvlwX3Vh8j2XUIIWNXoZS3ZoO8soSK+4fRuYnQPyFEHhcHecFV+ppDNRAAA7\n',
+'drawShape': 'R0lGODlhGAAYAPAAAAAAAAAAACH5BAEAAAEALAAAAAAYABgAAAI5jI+pywffIjQzIrCwdXnTplmh\nMoKmKIHVeZXp5cFcPH+0HbjbqKN17OoxgrTeKiOkPHjH3fIGjS4KADs=\n',
+'drawEllip': 'R0lGODlhGAAYAPEBAAAAAP///6usrQAAACH5BAEAAAIALAAAAAAYABgAAAIylI+py+0PowS0gklX\ndRd29XmgdIQh+Z1TSSJpyxpqZMLqzOB4sgsbmKFZgrCi8YhMNgoAOw==\n',
+'select': 'R0lGODlhGAAYAPIDAAAAAICAgMDAwP///6usrQAAAAAAAAAAACH5BAEAAAQALAAAAAAYABgAAANH\nSLrc/mvA6YCkGIiLIQhb54Gh2HwkZxKo4KoiSpam7L6rfdNZ4M+C3I+0Ush8wSLKCFIyPsnisyld\nAD7VabR6DWSt37BYmgAAOw==\n',
+'fillShape': 'R0lGODlhGAAYAPEAAAAAAIOBgwAAAAAAACH5BAEAAAIALAAAAAAYABgAAAJHlI+pywff4gsUxgSo\nrhflzXXCB4YXWQIiCqpnubnLw8KyU8Omket77wvcgD4ZUTcMIj3KlOLYejY1N8/R0qChaCIrtgsO\nRwoAOw==\n',
+'asy': 'R0lGODlhGAAYAIABAP8AAAAAACH5BAEKAAEALAIAAwAUABIAAAImjI+py+0AHINy0ZouNjBurmGd\nt40fFT4j2aydGqaBq8jvxH46UwAAOw==\n'
+}
+
+def createGIF(key):
+ """Create a gif file from the data in the iconB64 list of icons"""
+ if key not in iconB64.keys():
+ print "Error: %s not found in icon list."%key
+ print "Available icons:",iconB64.keys()
+ else:
+ print "Generating %s.gif"%key
+ open("%s.gif"%key,"w").write(base64.decodestring(iconB64[key]))
+
+def createGIFs():
+ """Create the files for all the icons in iconB64"""
+ for name in iconB64.keys():
+ createGIF(name)
+
+def createStrFromGif(gifFile):
+ """Create the base64 representation of a file"""
+ return base64.encodestring(gifFile.read())
+
+if __name__=='__main__':
+ print "Testing the xasyGUIIcons module."
+ print "Generating all the GIFs:"
+ createGIFs()
+ print "Checking consistency of all icons in iconB64"
+ allpassed = True
+ for icon in iconB64.keys():
+ print ("Checking %s"%icon),
+ if createStrFromGif(open("%s.gif"%icon,"rb")) == iconB64[icon]:
+ print "\tPassed."
+ else:
+ print "\tFailed."
+ allpassed= False
+ if allpassed:
+ print "All files succeeded."
+ s = raw_input("Delete generated files? (y/n)")
+ if s == "y":
+ for name in iconB64.keys():
+ print "Deleting %s.gif"%name,
+ os.unlink(name+".gif")
+ print "\tdone"
+ print "Done"
diff --git a/Build/source/utils/asymptote/GUI/xasyMainWin.py b/Build/source/utils/asymptote/GUI/xasyMainWin.py
new file mode 100755
index 00000000000..865e057accb
--- /dev/null
+++ b/Build/source/utils/asymptote/GUI/xasyMainWin.py
@@ -0,0 +1,1742 @@
+#!/usr/bin/env python
+###########################################################################
+#
+# xasyMainWin implements the functionality of the GUI. It depends on
+# xasy2asy for its interaction with Asymptote.
+#
+#
+# Author: Orest Shardt
+# Created: June 29, 2007
+#
+###########################################################################
+
+import os
+from string import *
+import subprocess
+import math
+import copy
+
+from Tkinter import *
+import tkMessageBox
+import tkFileDialog
+import tkSimpleDialog
+import threading
+import time
+
+from xasyVersion import xasyVersion
+import xasyCodeEditor
+from xasy2asy import *
+import xasyFile
+import xasyOptions
+import xasyOptionsDialog
+import CubicBezier
+from xasyBezierEditor import xasyBezierEditor
+from xasyGUIIcons import iconB64
+from xasyColorPicker import *
+
+from UndoRedoStack import *
+from xasyActions import *
+
+import string
+
+try:
+ import ImageTk
+ import Image
+ PILAvailable = True
+except:
+ PILAvailable = False
+
+class xasyMainWin:
+ def __init__(self,master,file=None,magnification=1.0):
+ self.opLock = threading.Lock()
+ self.parent = master
+ self.magnification = magnification
+ self.previousZoom = self.magnification
+ self.magList = [0.1,0.25,1.0/3,0.5,1,2,3,4,5,10]
+ self.bindGlobalEvents()
+ self.createWidgets()
+ self.resetGUI()
+ if sys.platform[:3] == "win":
+ site="http://effbot.org/downloads/PIL-1.1.6.win32-py2.5.exe"
+ if sys.version_info[0] != 2 or sys.version_info[1] != 5:
+ tkMessageBox.showerror("Failed Dependencies","Xasy requires Python 2.5 or 2.5.1. Please install http://www.python.org/ftp/python/2.5.1/python-2.5.1.msi")
+ self.parent.destroy()
+ sys.exit(1)
+ else:
+ site="http://effbot.org/downloads/Imaging-1.1.6.tar.gz after applying the patch http://asymptote.svn.sourceforge.net/viewvc/asymptote/trunk/asymptote/patches/TkAlpha-Imaging-1.1.6.patch"
+ if not PILAvailable:
+ tkMessageBox.showerror("Failed Dependencies","An error occurred loading the required PIL library. Please install "+site)
+ self.parent.destroy()
+ sys.exit(1)
+ if file != None:
+ self.loadFile(file)
+ self.parent.after(100,self.tickHandler)
+
+ def testOrAcquireLock(self):
+ val = self.opLock.acquire(False)
+ if val:
+ self.closeDisplayLock()
+ return val
+
+ def acquireLock(self):
+ self.closeDisplayLock()
+ self.opLock.acquire()
+
+ def releaseLock(self):
+ self.opLock.release()
+ self.openDisplayLock()
+
+ def tickHandler(self):
+ self.tickCount += 1
+ self.mainCanvas.itemconfigure("outlineBox",dashoffset=self.tickCount%9)
+ self.parent.after(100,self.tickHandler)
+
+ def closeDisplayLock(self):
+ self.status.config(text="Busy")
+ self.parent.update_idletasks()
+
+ def openDisplayLock(self):
+ self.status.config(text="Ready")
+
+ def bindGlobalEvents(self):
+ #global bindings
+ self.parent.bind_all("<Control-z>",lambda q:self.editUndoCmd())# z -> no shift
+ self.parent.bind_all("<Control-Z>",lambda q:self.editRedoCmd())# Z -> with shift
+ self.parent.bind_all("<Control-o>",lambda q:self.fileOpenCmd())
+ self.parent.bind_all("<Control-n>",lambda q:self.fileNewCmd())
+ self.parent.bind_all("<Control-s>",lambda q:self.fileSaveCmd())
+ self.parent.bind_all("<Control-q>",lambda q:self.fileExitCmd())
+ self.parent.bind_all("<F1>",lambda q:self.helpHelpCmd())
+
+ def unbindGlobalEvents(self):
+ #global bindings
+ self.parent.unbind("<Control-z>")
+ self.parent.unbind("<Control-Z>")
+ self.parent.unbind("<Control-o>")
+ self.parent.unbind("<Control-n>")
+ self.parent.unbind("<Control-s>")
+ self.parent.unbind("<Control-q>")
+ self.parent.unbind("<F1>")
+
+ def createWidgets(self):
+ #first some configuration
+ self.parent.geometry("800x600")
+ self.parent.title("Xasy")
+ self.parent.resizable(True,True)
+
+ #try to capture the closing of the window
+ #find a better way to do this since the widgets may
+ #already be destroyed when this is called
+ self.parent.protocol("WM_DELETE_WINDOW",self.canQuit)
+
+ #the main menu
+ self.mainMenu = Menu(self.parent)
+ self.parent.config(menu=self.mainMenu)
+
+ #the file menu
+ self.fileMenu = Menu(self.mainMenu,tearoff=0)
+ self.fileMenu.add_command(label="New",command=self.fileNewCmd,accelerator="Ctrl+N",underline=0)
+ self.fileMenu.add_command(label="Open",command=self.fileOpenCmd,accelerator="Ctrl+O",underline=0)
+ self.fileMenu.add_separator()
+ self.fileMenu.add_command(label="Save",command=self.fileSaveCmd,accelerator="Ctrl+S",underline=0)
+ self.fileMenu.add_command(label="Save As",command=self.fileSaveAsCmd,underline=5)
+ self.fileMenu.add_separator()
+
+ #an export menu
+ self.exportMenu = Menu(self.fileMenu,tearoff=0)
+ self.exportMenu.add_command(label="EPS...",command=self.exportEPS,underline=0)
+ self.exportMenu.add_command(label="PDF...",command=self.exportPDF,underline=0)
+ self.exportMenu.add_command(label="GIF...",command=self.exportGIF,underline=0)
+ self.exportMenu.add_command(label="PNG...",command=self.exportPNG,underline=1)
+ self.fileMenu.add_cascade(label="Export",menu=self.exportMenu,underline=1)
+ self.fileMenu.add_separator()
+
+ self.fileMenu.add_command(label="Quit",command=self.fileExitCmd,accelerator="Ctrl+Q",underline=0)
+
+ self.mainMenu.add_cascade(label="File",menu=self.fileMenu,underline=0)
+
+ #the edit menu
+ self.editMenu = Menu(self.mainMenu,tearoff=0)
+ self.editMenu.add_command(label="Undo",command=self.editUndoCmd,accelerator="Ctrl+Z",underline=0)
+ self.editMenu.add_command(label="Redo",command=self.editRedoCmd,accelerator="Shift+Ctrl+Z",underline=0)
+ self.mainMenu.add_cascade(label="Edit",menu=self.editMenu,underline=0)
+
+ #the tools menu
+ self.toolsMenu = Menu(self.mainMenu,tearoff=0)
+ self.mainMenu.add_cascade(label="Tools",menu=self.toolsMenu,underline=0)
+
+ #the options menu
+ self.optionsMenu = Menu(self.toolsMenu,tearoff=0)
+ self.toolsMenu.add_cascade(label="Options",menu=self.optionsMenu,underline=0)
+ self.optionsMenu.add_command(label="Edit...",command=self.editOptions,underline=0)
+ self.optionsMenu.add_command(label="Reset defaults",command=self.resetOptions,underline=6)
+
+ #the help menu
+ self.helpMenu = Menu(self.mainMenu,tearoff=0)
+ self.helpMenu.add_command(label="Help",command=self.helpHelpCmd,state=DISABLED,accelerator="F1",underline=0)
+ self.helpMenu.add_command(label="Asymptote Documentation",command=self.helpAsyDocCmd,underline=10)
+ self.helpMenu.add_separator()
+ self.helpMenu.add_command(label="About xasy",command=self.helpAboutCmd,underline=0)
+ self.mainMenu.add_cascade(label="Help",menu=self.helpMenu,underline=0)
+
+ #status bar
+ self.statusBar = Frame(self.parent,relief=FLAT)
+
+ self.magVal = DoubleVar()
+ self.magVal.set(round(100*self.magnification,1))
+ self.magVal.trace('w',self.zoomViewCmd)
+ zoomList = self.magList
+ if self.magnification not in zoomList:
+ zoomList.append(self.magnification)
+ zoomList.sort()
+ zoomList = [round(100*i,1) for i in zoomList]
+ self.zoomMenu = OptionMenu(self.statusBar,self.magVal,*zoomList)
+ self.zoomMenu.pack(side=RIGHT)
+ Label(self.statusBar,text="Zoom:",anchor=E,width=7).pack(side=RIGHT)
+
+ self.coords = Label(self.statusBar,text="(0,0)",relief=SUNKEN,anchor=W)
+ self.coords.pack(side=RIGHT,anchor=S)
+ self.status = Label(self.statusBar,text="Ready",relief=SUNKEN,anchor=W)
+ self.status.pack(side=RIGHT,fill=X,expand=1,anchor=SW)
+ self.statusBar.pack(side=BOTTOM,fill=X)
+
+ #toolbar for transformation, drawing, and adjustment commands
+ self.toolBar = Frame(self.parent,relief=FLAT,borderwidth=3)
+
+ #let's load some images
+ self.toolIcons = {}
+ for x in iconB64.keys():
+ self.toolIcons[x] = PhotoImage(data=iconB64[x])
+
+ self.transformLbl = Label(self.toolBar,text="",anchor=W)
+ self.transformLbl.grid(row=0,column=0,columnspan=2,sticky=W)
+ self.toolSelectButton = Button(self.toolBar,command=self.toolSelectCmd,image=self.toolIcons["select"])
+ self.toolSelectButton.grid(row=1,column=0,sticky=N+S+E+W)
+ self.toolMoveButton = Button(self.toolBar,command=self.toolMoveCmd,image=self.toolIcons["move"])
+ self.toolMoveButton.grid(row=2,column=0,sticky=N+S+E+W)
+ self.toolRotateButton = Button(self.toolBar,command=self.toolRotateCmd,image=self.toolIcons["rotate"])
+ self.toolRotateButton.grid(row=2,column=1,sticky=N+S+E+W)
+ self.toolVertiMoveButton = Button(self.toolBar,command=self.toolVertiMoveCmd,image=self.toolIcons["vertiMove"])
+ self.toolVertiMoveButton.grid(row=3,column=0,sticky=N+S+E+W)
+ self.toolHorizMoveButton = Button(self.toolBar,command=self.toolHorizMoveCmd,image=self.toolIcons["horizMove"])
+ self.toolHorizMoveButton.grid(row=3,column=1,sticky=N+S+E+W)
+
+ self.drawLbl = Label(self.toolBar,text="",anchor=W)
+ self.drawLbl.grid(row=4,column=0,columnspan=2,sticky=W)
+ self.toolDrawLinesButton = Button(self.toolBar,command=self.toolDrawLinesCmd,image=self.toolIcons["drawLines"])
+ self.toolDrawLinesButton.grid(row=5,column=0,sticky=N+S+E+W)
+ self.toolDrawBeziButton = Button(self.toolBar,command=self.toolDrawBeziCmd,image=self.toolIcons["drawBezi"])
+ self.toolDrawBeziButton.grid(row=5,column=1,sticky=N+S+E+W)
+ self.toolDrawPolyButton = Button(self.toolBar,command=self.toolDrawPolyCmd,image=self.toolIcons["drawPoly"])
+ self.toolDrawPolyButton.grid(row=6,column=0,sticky=N+S+E+W)
+ self.toolFillPolyButton = Button(self.toolBar,command=self.toolFillPolyCmd,image=self.toolIcons["fillPoly"])
+ self.toolFillPolyButton.grid(row=6,column=1,sticky=N+S+E+W)
+ self.toolDrawEllipButton = Button(self.toolBar,command=self.toolDrawEllipCmd,image=self.toolIcons["drawEllip"],state=DISABLED,relief=FLAT)
+ #self.toolDrawEllipButton.grid(row=7,column=0,sticky=N+S+E+W)
+ self.toolFillEllipButton = Button(self.toolBar,command=self.toolFillEllipCmd,image=self.toolIcons["fillEllip"],state=DISABLED,relief=FLAT)
+ #self.toolFillEllipButton.grid(row=7,column=1,sticky=N+S+E+W)
+ self.toolDrawShapeButton = Button(self.toolBar,command=self.toolDrawShapeCmd,image=self.toolIcons["drawShape"])
+ self.toolDrawShapeButton.grid(row=8,column=0,sticky=N+S+E+W)
+ self.toolFillShapeButton = Button(self.toolBar,command=self.toolFillShapeCmd,image=self.toolIcons["fillShape"])
+ self.toolFillShapeButton.grid(row=8,column=1,sticky=N+S+E+W)
+ self.toolTextButton = Button(self.toolBar,command=self.toolTextCmd,image=self.toolIcons["text"])
+ self.toolTextButton.grid(row=9,column=0,sticky=N+S+E+W)
+ self.toolAsyButton = Button(self.toolBar,command=self.toolAsyCmd,image=self.toolIcons["asy"])
+ self.toolAsyButton.grid(row=9,column=1,sticky=N+S+E+W)
+
+ self.adjLbl = Label(self.toolBar,text="",anchor=W)
+ self.adjLbl.grid(row=10,column=0,columnspan=2,sticky=W)
+ self.toolRaiseButton = Button(self.toolBar,command=self.toolRaiseCmd,image=self.toolIcons["raise"])
+ self.toolRaiseButton.grid(row=11,column=0,sticky=N+S+E+W)
+ self.toolLowerButton = Button(self.toolBar,command=self.toolLowerCmd,image=self.toolIcons["lower"])
+ self.toolLowerButton.grid(row=11,column=1,sticky=N+S+E+W)
+
+ self.toolBar.pack(side=LEFT,anchor=NW)
+
+ #documentation for the tool bar buttons
+ self.toolDocs = {
+ self.toolSelectButton : "Click an item to select it. Control-Click will select/deselect additional items. Use mouse scroller (or Up/Down keys) to raise/lower highlighted items.",
+ self.toolMoveButton : "Drag a selected item.",
+ self.toolHorizMoveButton : "Drag a selected item. Only horizontal translation will be applied.",
+ self.toolVertiMoveButton : "Drag a selected item. Only vertical translation will be applied.",
+ self.toolRotateButton : "Drag a selected item to rotate it.",
+ self.toolDrawLinesButton : "Click to draw line segments. Double click to place last point.",
+ self.toolDrawBeziButton : "Click to place points. Double click to place last point.",
+ self.toolDrawPolyButton : "Click to place vertices. Double click to place last point.",
+ self.toolFillPolyButton : "Click to place vertices. Double click to place last point.",
+ self.toolDrawEllipButton : "(UNIMPLEMENTED)Click to place center. Move mouse to achieve correct shape and double click.",
+ self.toolFillEllipButton : "(UNIMPLEMENTED)Click to place center. Move mouse to achieve correct shape and double click.",
+ self.toolDrawShapeButton : "Click to place points. Double click to place last point.",
+ self.toolFillShapeButton : "Click to place points. Double click to place last point.",
+ self.toolTextButton : "Click location of top left label position and enter text in dialog.",
+ self.toolRaiseButton : "Raise selected items to top.",
+ self.toolLowerButton : "Lower selected items to bottom.",
+ self.toolAsyButton : "Insert/Edit Asymptote code."
+ }
+
+ #Current pen settings
+ self.optionsBar = Frame(self.parent,height=100,relief=FLAT,borderwidth=3)
+ self.penDisp = Canvas(self.optionsBar,width=100,height=25,bg="white",relief=SUNKEN,borderwidth=3)
+ self.penDisp.grid(row=0,column=0,padx=3,pady=3)
+ self.penDisp.create_line(10,25,30,10,60,20,80,10,smooth=True,tags="penDisp")
+ self.penDisp.create_text(100,30,text="x1",tags="penMag",anchor=SE,font=("times","8"))
+ self.penColButton = Button(self.optionsBar,text="Color...",width=5,command=self.setPenColCmd,relief=FLAT)
+ self.penColButton.grid(row=0,column=1,padx=3,pady=3)
+ Label(self.optionsBar,text="Width",anchor=E).grid(row=0,column=2)
+ self.penWidthEntry = Entry(self.optionsBar,width=5)
+ self.penWidthEntry.bind("<KeyRelease>",self.penWidthChanged)
+ self.penWidthEntry.bind("<FocusOut>",self.applyPenWidthEvt)
+ self.penWidthEntry.bind("<Return>",self.applyPenWidthEvt)
+ self.penWidthEntry.grid(row=0,column=3)
+ Label(self.optionsBar,text="Options",anchor=E).grid(row=0,column=4)
+ self.penOptEntry = Entry(self.optionsBar)
+ self.penOptEntry.bind("<FocusOut>",self.applyPenOptEvt)
+ self.penOptEntry.bind("<Return>",self.applyPenOptEvt)
+ self.penOptEntry.grid(row=0,column=5)
+ self.optionsBar.pack(side=BOTTOM,anchor=NW)
+
+ #a paned window for the canvas and propert explorer
+ self.windowPane = PanedWindow(self.parent)
+
+ #a property explorer
+ self.propFrame = Frame(self.parent)
+ self.propFrame.rowconfigure(1,weight=1)
+ self.propFrame.columnconfigure(0,weight=1)
+ Label(self.propFrame,text="Item List").grid(row=0,column=0,columnspan=2)
+ self.itemScroll = Scrollbar(self.propFrame,orient=VERTICAL)
+ self.propList = Listbox(self.propFrame, yscrollcommand=self.itemScroll.set)
+ self.itemScroll.config(command=self.propList.yview)
+ self.itemScroll.grid(row=1,column=1,sticky=N+S)
+ self.propList.grid(row=1,column=0,sticky=N+S+E+W)
+ self.propList.bind("<Double-Button-1>",self.propSelect)
+ self.propList.bind("<Button-3>",self.itemPropMenuPopup)
+
+ #the canvas's frame
+ self.canvFrame = Frame(self.parent,relief=FLAT,borderwidth=0)
+ self.canvFrame.rowconfigure(0,weight=1)
+ self.canvFrame.columnconfigure(0,weight=1)
+ self.canvVScroll = Scrollbar(self.canvFrame,orient=VERTICAL)
+ self.canvHScroll = Scrollbar(self.canvFrame,orient=HORIZONTAL)
+ self.canvHScroll.grid(row=1,column=0,sticky=E+W)
+ self.canvVScroll.grid(row=0,column=1,sticky=N+S)
+
+ #add the frames to the window pane
+ self.windowPane.pack(side=RIGHT,fill=BOTH,expand=True)
+ self.windowPane.add(self.canvFrame)
+ self.windowPane.add(self.propFrame)
+ self.windowPane.paneconfigure(self.propFrame,minsize=50,sticky=N+S+E+W)
+ self.windowPane.bind("<Double-Button-1>",self.togglePaneEvt)
+
+ #the highly important canvas!
+ self.mainCanvas = Canvas(self.canvFrame,relief=SUNKEN,background="white",borderwidth=3,
+ highlightthickness=0,closeenough=1.0,yscrollcommand=self.canvVScroll.set,
+ xscrollcommand=self.canvHScroll.set)
+ self.mainCanvas.grid(row=0,column=0,sticky=N+S+E+W)
+
+ self.canvVScroll.config(command=self.mainCanvas.yview)
+ self.canvHScroll.config(command=self.mainCanvas.xview)
+
+ self.mainCanvas.bind("<Motion>",self.canvMotion)
+ self.mainCanvas.bind("<Button-1>",self.canvLeftDown)
+ self.mainCanvas.bind("<Double-Button-1>",self.endDraw)
+ self.mainCanvas.bind("<ButtonRelease-1>",self.canvLeftUp)
+ self.mainCanvas.bind("<B1-Motion>",self.canvDrag)
+
+ self.mainCanvas.bind("<Enter>",self.canvEnter)
+ self.mainCanvas.bind("<Leave>",self.canvLeave)
+ self.mainCanvas.bind("<Delete>",self.itemDelete)
+ #self.mainCanvas.bind("<Button-3>",self.canvRightDown)
+ #self.mainCanvas.bind("<ButtonRelease-3>",self.canvRightUp)
+ self.mainCanvas.bind("<Button-4>",self.itemRaise)
+ self.mainCanvas.bind("<Button-5>",self.itemLower)
+ self.mainCanvas.bind("<Up>",self.itemRaise)
+ self.mainCanvas.bind("<Down>",self.itemLower)
+ self.mainCanvas.bind("<Configure>",self.configEvt)
+
+ def foregroundPenColor(self,hex):
+ hex = hex[1:]
+ rgb = max(hex[0:2], hex[2:4], hex[4:6])
+ if(rgb >= "80"):
+ return "black"
+ else:
+ return "white"
+
+ def resetGUI(self):
+ #set up the main window
+ self.filename = None
+ self.fileToOpen = None
+ self.retitle()
+
+ #set up the paned window
+ self.paneVisible = True
+
+ #setup the pen entries
+ self.pendingPenWidthChange = None
+ self.pendingPenOptChange = None
+
+ #load one-time configs
+ xasyOptions.load()
+ self.tkPenColor = xasyOptions.options['defPenColor']
+ self.penColor = makeRGBfromTkColor(self.tkPenColor)
+ self.penColButton.config(activebackground=self.tkPenColor,
+ activeforeground=self.foregroundPenColor(self.tkPenColor))
+ self.penWidth = xasyOptions.options['defPenWidth']
+ self.penWidthEntry.select_range(0,END)
+ self.penWidthEntry.delete(0,END)
+ self.penWidthEntry.insert(END,str(self.penWidth))
+ self.penOptions = xasyOptions.options['defPenOptions']
+ self.penOptEntry.select_range(0,END)
+ self.penOptEntry.delete(0,END)
+ self.penOptEntry.insert(END,str(self.penOptions))
+ self.showCurrentPen()
+
+ #load modifiable configs
+ self.applyOptions()
+
+ #set up editing
+ self.editor = None
+
+ #set up drawing
+ self.pathInProgress = asyPath()
+ self.currentIDTag = -1
+ self.inDrawingMode = False
+ self.freeMouseDown = True
+ self.dragSelecting = False
+ self.itemsBeingRotated = []
+ self.inRotatingMode = False
+
+ #set up the toolbar
+ try:
+ self.updateSelectedButton(self.toolSelectButton)
+ except:
+ self.selectedButton = self.toolSelectButton
+ self.updateSelectedButton(self.toolSelectButton)
+
+ #set up the canvas
+ self.mainCanvas.delete(ALL)
+ self.mainCanvas.create_rectangle(0,0,0,0,tags="outlineBox",width=0,outline="#801111",dash=(3,6))
+ self.backColor = "white" #in future, load this from an options file. Or, should this really be an option?
+ self.mainCanvas.configure(background=self.backColor)
+
+ #set up the xasy item list
+ self.fileItems = []
+ self.propList.delete(0,END)
+ self.updateCanvasSize()
+
+ #setup timer
+ self.tickCount = 0
+
+ #setup undo/redo!
+ self.undoRedoStack = actionStack()
+ self.amDragging = False
+
+ def retitle(self):
+ if self.filename == None:
+ self.parent.title("Xasy - New File")
+ else:
+ name = os.path.abspath(self.filename)
+ name = os.path.basename(name)
+ self.parent.title("Xasy - %s"%name)
+
+ def applyOptions(self):
+ self.gridcolor = xasyOptions.options['gridColor']
+ self.tickcolor = xasyOptions.options['tickColor']
+ self.axiscolor = xasyOptions.options['axesColor']
+ self.gridVisible = xasyOptions.options['showGrid']
+ self.gridxspace = xasyOptions.options['gridX']
+ self.gridyspace = xasyOptions.options['gridY']
+ self.axesVisible = xasyOptions.options['showAxes']
+ self.axisxspace = xasyOptions.options['axisX']
+ self.axisyspace = xasyOptions.options['axisY']
+ self.updateCanvasSize()
+ #test the asyProcess
+ startQuickAsy()
+ if not quickAsyRunning():
+ if tkMessageBox.askyesno("Xasy Error","Asymptote could not be executed.\r\nTry to find Asymptote automatically?"):
+ xasyOptions.setAsyPathFromWindowsRegistry()
+ xasyOptions.save()
+ startQuickAsy()
+ while not quickAsyRunning():
+ if tkMessageBox.askyesno("Xasy Error","Asymptote could not be executed.\r\nEdit settings?"):
+ xasyOptionsDialog.xasyOptionsDlg(self.parent)
+ xasyOptions.save()
+ startQuickAsy()
+ else:
+ self.parent.destroy()
+ sys.exit(1)
+
+ def drawGrid(self):
+ self.mainCanvas.delete("grid")
+ if not self.gridVisible:
+ return
+ left,top,right,bottom = map(int,self.mainCanvas.cget("scrollregion").split())
+ gridyspace = int(self.magnification*self.gridyspace)
+ gridxspace = int(self.magnification*self.gridxspace)
+ if gridxspace >= 3 and gridyspace >= 3:
+ for i in range(0,right,gridxspace):
+ self.mainCanvas.create_line(i,top,i,bottom,tags=("grid","vertical"),fill=self.gridcolor)
+ for i in range(-gridxspace,left,-gridxspace):
+ self.mainCanvas.create_line(i,top,i,bottom,tags=("grid","vertical"),fill=self.gridcolor)
+ for i in range(-gridyspace,top,-gridyspace):
+ self.mainCanvas.create_line(left,i,right,i,tags=("grid","horizontal"),fill=self.gridcolor)
+ for i in range(0,bottom,gridyspace):
+ self.mainCanvas.create_line(left,i,right,i,tags=("grid","horizontal"),fill=self.gridcolor)
+ self.mainCanvas.tag_lower("grid")
+
+ def drawAxes(self):
+ self.mainCanvas.delete("axes")
+ if not self.axesVisible:
+ return
+ left,top,right,bottom = map(int,self.mainCanvas.cget("scrollregion").split())
+ self.mainCanvas.create_line(0,top,0,bottom,tags=("axes","yaxis"),fill=self.axiscolor)
+ self.mainCanvas.create_line(left,0,right,0,tags=("axes","xaxis"),fill=self.axiscolor)
+ axisxspace = int(self.magnification*self.axisxspace)
+ axisyspace = int(self.magnification*self.axisyspace)
+ if axisxspace >= 3 and axisyspace >= 3:
+ for i in range(axisxspace,right,axisxspace):
+ self.mainCanvas.create_line(i,-5,i,5,tags=("axes","xaxis-ticks"),fill=self.tickcolor)
+ for i in range(-axisxspace,left,-axisxspace):
+ self.mainCanvas.create_line(i,-5,i,5,tags=("axes","xaxis-ticks"),fill=self.tickcolor)
+ for i in range(-axisyspace,top,-axisyspace):
+ self.mainCanvas.create_line(-5,i,5,i,tags=("axes","yaxis-ticks"),fill=self.tickcolor)
+ for i in range(axisyspace,bottom,axisyspace):
+ self.mainCanvas.create_line(-5,i,5,i,tags=("axes","yaxis-ticks"),fill=self.tickcolor)
+ self.mainCanvas.tag_lower("axes")
+
+ def updateCanvasSize(self,left=-200,top=-200,right=200,bottom=200):
+ self.parent.update_idletasks()
+ bbox = self.mainCanvas.bbox("drawn || image || node || precontrol || postcontrol")
+ if bbox == None:
+ bbox = (0,0,0,0)
+ #(topleft, bottomright)
+ left = min(bbox[0],left)
+ top = min(bbox[1],top)
+ right = max(bbox[2],right)
+ bottom = max(bbox[3],bottom)
+ w,h = self.mainCanvas.winfo_width(),self.mainCanvas.winfo_height()
+ if right-left < w:
+ extraw = w-(right-left)
+ right += extraw/2
+ left -= extraw/2
+ if bottom-top < h:
+ extrah = h-(bottom-top)
+ bottom += extrah/2
+ top -= extrah/2
+ self.mainCanvas.config(scrollregion=(left,top,right,bottom))
+ #self.mainCanvas.xview(MOVETO,float(split(self.mainCanvas["scrollregion"])[0]))
+ #self.mainCanvas.yview(MOVETO,float(split(self.mainCanvas["scrollregion"])[1]))
+ #self.mainCanvas.xview(MOVETO,(left+right)/2)
+ #self.mainCanvas.yview(MOVETO,(top+bottom)/2)
+ self.drawAxes()
+ self.drawGrid()
+
+ def bindEvents(self,tagorID):
+ if tagorID == None:
+ return
+ self.mainCanvas.tag_bind(tagorID,"<Control-Button-1>",self.itemToggleSelect)
+ self.mainCanvas.tag_bind(tagorID,"<Button-1>",self.itemSelect)
+ self.mainCanvas.tag_bind(tagorID,"<ButtonRelease-1>",self.itemMouseUp)
+ self.mainCanvas.tag_bind(tagorID,"<Double-Button-1>",self.itemEditEvt)
+ self.mainCanvas.tag_bind(tagorID,"<B1-Motion>",self.itemDrag)
+ self.mainCanvas.tag_bind(tagorID,"<Delete>",self.itemDelete)
+ self.mainCanvas.tag_bind(tagorID,"<Enter>",self.itemHighlight)
+ self.mainCanvas.tag_bind(tagorID,"<Button-3>",self.itemCanvasMenuPopup)
+
+ def bindItemEvents(self,item):
+ if item == None:
+ return
+ if isinstance(item,xasyScript) or isinstance(item,xasyText):
+ for image in item.imageList:
+ self.bindEvents(image.IDTag)
+ else:
+ self.bindEvents(item.IDTag)
+
+ def canQuit(self,force=False):
+ #print "Quitting"
+ if not force and not self.testOrAcquireLock():
+ return
+ try:
+ self.releaseLock()
+ except:
+ pass
+ if self.undoRedoStack.changesMade():
+ result = tkMessageBox._show("xasy","File has been modified.\nSave changes?",icon=tkMessageBox.QUESTION,type=tkMessageBox.YESNOCANCEL)
+ if str(result) == tkMessageBox.CANCEL:
+ return
+ elif result == tkMessageBox.YES:
+ self.fileSaveCmd()
+ try:
+ os.rmdir(getAsyTempDir())
+ except:
+ pass
+ self.parent.destroy()
+
+ def openFile(self,name):
+ if(not self.testOrAcquireLock()):
+ return
+ self.releaseLock() #release the lock for loadFile
+ self.resetGUI()
+ self.loadFile(name)
+
+ def loadFile(self,name):
+ self.status.config(text="Loading "+name)
+ self.filename = os.path.abspath(name)
+ startQuickAsy()
+ self.retitle()
+ try:
+ try:
+ f = open(self.filename,'rt')
+ except:
+ if self.filename[-4:] == ".asy":
+ raise
+ else:
+ f = open(self.filename+".asy",'rt')
+ self.filename += ".asy"
+ self.retitle()
+ self.fileItems = xasyFile.parseFile(f)
+ f.close()
+ except IOError:
+ tkMessageBox.showerror("File Opening Failed.","File could not be opened.")
+ self.fileItems = []
+ except:
+ self.fileItems = []
+ self.autoMakeScript = True
+ if self.autoMakeScript or tkMessageBox.askyesno("Error Opening File", "File was not recognized as an xasy file.\nLoad as a script item?"):
+ try:
+ item = xasyScript(self.mainCanvas)
+ f.seek(0)
+ item.setScript(f.read())
+ self.addItemToFile(item)
+ except:
+ tkMessageBox.showerror("File Opening Failed.","Could not load as a script item.")
+ self.fileItems = []
+ self.populateCanvasWithItems()
+ self.populatePropertyList()
+ self.updateCanvasSize()
+
+ def populateCanvasWithItems(self):
+ if(not self.testOrAcquireLock()):
+ return
+ self.mainCanvas.delete("drawn || image")
+ self.itemCount = 0
+ for item in self.fileItems:
+ item.drawOnCanvas(self.mainCanvas,self.magnification,forceAddition=True)
+ self.bindItemEvents(item)
+ self.releaseLock()
+
+ def propListCountItem(self,item):
+ plist = self.propList.get(0,END)
+ count = 1
+ for text in plist:
+ if text.startswith(item):
+ count += 1
+ return count
+
+ def describeItem(self,item):
+ if isinstance(item,xasyScript):
+ return "Code Module "+str(self.propListCountItem("Code Module"))
+ elif isinstance(item,xasyText):
+ return "Text Label "+str(self.propListCountItem("Text Label"))
+ elif isinstance(item,xasyFilledShape):
+ return "Filled Shape "+str(self.propListCountItem("Filled Shape"))
+ elif isinstance(item,xasyShape):
+ return "Outline "+str(self.propListCountItem("Outline"))
+ else:
+ return "If this happened, the program is corrupt!"
+
+ def populatePropertyList(self):
+ self.propList.delete(0,END)
+ for item in self.fileItems:
+ self.propList.insert(0,self.describeItem(item))
+
+ def saveFile(self,name):
+ if(not self.testOrAcquireLock()):
+ return
+ f = open(name,"wt")
+ xasyFile.saveFile(f,self.fileItems)
+ f.close()
+ self.undoRedoStack.setCommitLevel()
+ self.retitle()
+ self.releaseLock()
+
+ #menu commands
+ def fileNewCmd(self):
+ if(not self.testOrAcquireLock()):
+ return
+ self.releaseLock()
+ #print "Create New File"
+ if self.undoRedoStack.changesMade():
+ result = tkMessageBox._show("xasy","File has been modified.\nSave changes?",icon=tkMessageBox.QUESTION,type=tkMessageBox.YESNOCANCEL)
+ if str(result) == tkMessageBox.CANCEL:
+ return
+ elif result == tkMessageBox.YES:
+ self.fileSaveCmd()
+ self.resetGUI()
+
+ def fileOpenCmd(self):
+ if(not self.testOrAcquireLock()):
+ return
+ self.releaseLock()
+ #print "Open a file"
+ if self.undoRedoStack.changesMade():
+ result = tkMessageBox._show("xasy","File has been modified.\nSave changes?",icon=tkMessageBox.QUESTION,type=tkMessageBox.YESNOCANCEL)
+ if str(result) == tkMessageBox.CANCEL:
+ return
+ elif result == tkMessageBox.YES:
+ self.fileSaveCmd()
+ filename=tkFileDialog.askopenfilename(filetypes=[("asy files","*.asy"),("All files","*")],title="Open File",parent=self.parent)
+ if type(filename) != type((0,)) and filename != None and filename != '':
+ self.filename = filename
+ self.openFile(self.filename)
+
+ def fileSaveCmd(self):
+ #print "Save current file"
+ if(not self.testOrAcquireLock()):
+ return
+ self.releaseLock()
+ if self.filename == None:
+ filename=tkFileDialog.asksaveasfilename(defaultextension=".asy",filetypes=[("asy files","*.asy")],initialfile="newDrawing.asy",parent=self.parent,title="Save File")
+ if type(filename) != type((0,)) and filename != None and filename != '':
+ self.filename = filename
+ if self.filename != None:
+ self.saveFile(self.filename)
+
+ def fileSaveAsCmd(self):
+ if(not self.testOrAcquireLock()):
+ return
+ self.releaseLock()
+ #print "Save current file as"
+ filename=tkFileDialog.asksaveasfilename(defaultextension=".asy",filetypes=[("asy files","*.asy")],initialfile="newDrawing.asy",parent=self.parent,title="Save File")
+ if type(filename) != type((0,)) and filename != None and filename != '':
+ self.filename = filename
+ self.saveFile(self.filename)
+
+ #export the file
+ def exportEPS(self):
+ self.exportFile(self.filename,"eps")
+
+ def exportPDF(self):
+ self.exportFile(self.filename,"pdf")
+
+ def exportGIF(self):
+ self.exportFile(self.filename,"gif")
+
+ def exportPNG(self):
+ self.exportFile(self.filename,"png")
+
+ def exportFile(self,inFile, outFormat):
+ if(not self.testOrAcquireLock()):
+ return
+ self.releaseLock()
+ if inFile == None:
+ if tkMessageBox.askyesno("xasy","File has not been saved.\nSave?"):
+ self.fileSaveAsCmd()
+ inFile = self.filename
+ else:
+ return
+ elif self.undoRedoStack.changesMade():
+ choice = tkMessageBox._show("xasy","File has been modified.\nOnly saved changes can be exported.\nDo you want to save changes?",icon=tkMessageBox.QUESTION,type=tkMessageBox.YESNOCANCEL)
+ choice = str(choice)
+ if choice != tkMessageBox.YES:
+ return
+ else:
+ self.fileSaveCmd()
+ name = os.path.splitext(os.path.basename(self.filename))[0]+'.'+outFormat
+ outfilename = tkFileDialog.asksaveasfilename(defaultextension = '.'+outFormat,filetypes=[(outFormat+" files","*."+outFormat)],initialfile=name,parent=self.parent,title="Choose output file")
+ if type(outfilename)==type((0,)) or not outfilename or outfilename == '':
+ return
+ fullname = os.path.abspath(outfilename)
+ outName = os.path.basename(outfilename)
+ dirname = os.path.dirname(fullname)
+ command = xasyOptions.options['asyPath']+" -f %s -o %s %s"%(outFormat,fullname,inFile)
+ saver = subprocess.Popen(split(command),stdin=PIPE,stdout=PIPE,stderr=PIPE)
+ saver.wait()
+ if saver.returncode != 0:
+ tkMessageBox.showerror("Export Error","Export Error:\n"+saver.stdout.read()+saver.stderr.read())
+ self.status.config(text="Error exporting file")
+ else:
+ self.status.config(text="File exported successfully")
+
+ def fileExitCmd(self):
+ #print "Exit xasy"
+ self.canQuit()
+
+ def editUndoCmd(self):
+ if not self.editor == None:
+ return
+ if(not self.testOrAcquireLock()):
+ return
+ self.undoOperation()
+ self.releaseLock()
+
+ def editRedoCmd(self):
+ if not self.editor == None:
+ return
+ if(not self.testOrAcquireLock()):
+ return
+ self.redoOperation()
+ self.releaseLock()
+
+ def helpHelpCmd(self):
+ print "Get help on xasy"
+
+ def helpAsyDocCmd(self):
+ #print "Open documentation about Asymptote"
+ asyExecute("\nhelp;\n")
+
+ def helpAboutCmd(self):
+ tkMessageBox.showinfo("About xasy","A graphical interface for Asymptote "+xasyVersion)
+
+ def updateSelectedButton(self,newB):
+ if(not self.testOrAcquireLock()):
+ return
+ self.releaseLock()
+ #disable switching modes during an incomplete drawing operation
+ if self.inDrawingMode:
+ return
+ self.selectedButton.config(relief = RAISED)
+ if newB == self.toolSelectButton or self.selectedButton == self.toolSelectButton:
+ self.mainCanvas.delete("highlightBox")
+ if self.editor != None:
+ self.editor.endEdit()
+ if self.editor.modified:
+ self.undoRedoStack.add(editDrawnItemAction(self,self.itemBeingEdited,copy.deepcopy(self.editor.shape),self.fileItems.index(self.editor.shape)))
+ if newB not in (self.toolSelectButton,self.toolMoveButton,self.toolHorizMoveButton,self.toolVertiMoveButton,self.toolRotateButton):
+ self.clearSelection()
+ self.selectedButton = newB
+ self.selectedButton.config(relief = SUNKEN)
+ self.status.config(text=self.toolDocs[newB])
+
+ #toolbar commands
+ def toolSelectCmd(self):
+ self.updateSelectedButton(self.toolSelectButton)
+ def toolMoveCmd(self):
+ self.updateSelectedButton(self.toolMoveButton)
+ def toolRotateCmd(self):
+ self.updateSelectedButton(self.toolRotateButton)
+ def toolVertiMoveCmd(self):
+ self.updateSelectedButton(self.toolVertiMoveButton)
+ def toolHorizMoveCmd(self):
+ self.updateSelectedButton(self.toolHorizMoveButton)
+ def toolDrawLinesCmd(self):
+ self.updateSelectedButton(self.toolDrawLinesButton)
+ def toolDrawBeziCmd(self):
+ self.updateSelectedButton(self.toolDrawBeziButton)
+ def toolDrawPolyCmd(self):
+ self.updateSelectedButton(self.toolDrawPolyButton)
+ def toolFillPolyCmd(self):
+ self.updateSelectedButton(self.toolFillPolyButton)
+ def toolDrawEllipCmd(self):
+ self.updateSelectedButton(self.toolDrawEllipButton)
+ def toolFillEllipCmd(self):
+ self.updateSelectedButton(self.toolFillEllipButton)
+ def toolDrawShapeCmd(self):
+ self.updateSelectedButton(self.toolDrawShapeButton)
+ def toolFillShapeCmd(self):
+ self.updateSelectedButton(self.toolFillShapeButton)
+ def toolTextCmd(self):
+ self.updateSelectedButton(self.toolTextButton)
+ def toolAsyCmd(self):
+ # ignore the command if we are too busy to process it
+ if not self.testOrAcquireLock():
+ return
+ self.updateSelectedButton(self.toolSelectButton)
+ self.clearSelection()
+ self.clearHighlight()
+ self.unbindGlobalEvents()
+ try:
+ self.getNewText("// enter your code here")
+ except Exception, e:
+ tkMessageBox.showerror('xasy Error',e.message)
+ else:
+ self.addItemToFile(xasyScript(self.mainCanvas))
+ text = self.newText
+ self.undoRedoStack.add(addScriptAction(self,self.fileItems[-1]))
+ self.fileItems[-1].setScript(text)
+ self.fileItems[-1].drawOnCanvas(self.mainCanvas,self.magnification)
+ self.bindItemEvents(self.fileItems[-1])
+ self.bindGlobalEvents()
+ self.releaseLock()
+ def toolRaiseCmd(self):
+ if(not self.testOrAcquireLock()):
+ return
+ self.releaseLock()
+ if not self.inDrawingMode and self.editor == None:
+ itemList = []
+ indexList = []
+ for ID in self.mainCanvas.find_withtag("selectedItem"):
+ item = self.findItem(ID)
+ if item not in itemList:
+ itemList.append(item)
+ indexList.append(self.fileItems.index(item))
+ self.raiseSomething(item)
+ self.undoRedoStack.add(itemRaiseAction(self,itemList,indexList))
+ def toolLowerCmd(self):
+ if(not self.testOrAcquireLock()):
+ return
+ self.releaseLock()
+ if not self.inDrawingMode and self.editor == None:
+ itemList = []
+ indexList = []
+ for ID in self.mainCanvas.find_withtag("selectedItem"):
+ item = self.findItem(ID)
+ if item not in itemList:
+ itemList.append(item)
+ indexList.append(self.fileItems.index(item))
+ self.lowerSomething(item)
+ self.undoRedoStack.add(itemLowerAction(self,itemList,indexList))
+ def itemRaise(self,event):
+ self.mainCanvas.tag_raise(CURRENT)
+ def itemLower(self,event):
+ self.mainCanvas.tag_lower(CURRENT)
+
+ #options bar commands
+ def setPenColCmd(self):
+ if not self.testOrAcquireLock():
+ return
+ old = self.penColor
+ self.penColor = xasyColorDlg(self.parent).getColor(self.penColor)
+ if self.penColor != old:
+ self.tkPenColor = RGB255hex(RGBreal255(self.penColor))
+ self.penColButton.config(activebackground=self.tkPenColor,
+ activeforeground=self.foregroundPenColor(self.tkPenColor))
+ self.showCurrentPen()
+ self.releaseLock()
+
+ def clearSelection(self):
+ self.hideSelectionBox()
+ self.mainCanvas.dtag("selectedItem","selectedItem")
+
+ def hideSelectionBox(self):
+ self.mainCanvas.itemconfigure("outlineBox",width=1,outline=self.backColor)
+ self.mainCanvas.tag_lower("outlineBox")
+ self.mainCanvas.coords("outlineBox",self.mainCanvas.bbox(ALL))
+
+ def showSelectionBox(self):
+ self.mainCanvas.itemconfigure("outlineBox",width=2,outline="#801111")
+ self.mainCanvas.tag_raise("outlineBox")
+
+ def setSelection(self,what):
+ self.mainCanvas.addtag_withtag("selectedItem",what)
+ self.updateSelection()
+ if self.selectedButton == self.toolSelectButton and len(self.mainCanvas.find_withtag("selectedItem")) > 0:
+ self.updateSelectedButton(self.toolMoveButton)
+
+ def unSelect(self,what):
+ self.mainCanvas.dtag(what,"selectedItem")
+ self.updateSelection()
+
+ def updateSelection(self):
+ self.clearHighlight()
+ theBbox = self.mainCanvas.bbox("selectedItem")
+ if theBbox != None:
+ theBbox = (theBbox[0]-2,theBbox[1]-2,theBbox[2]+2,theBbox[3]+2)
+ self.mainCanvas.coords("outlineBox",theBbox)
+ self.showSelectionBox()
+ else:
+ self.clearSelection()
+
+ #event handlers
+ def updateZoom(self):
+ self.zoomMenu.config(state=DISABLED)
+ self.magnification = self.magVal.get()/100.0
+ if self.magnification != self.previousZoom:
+ self.populateCanvasWithItems()
+ self.updateCanvasSize()
+ self.updateSelection()
+ self.drawAxes()
+ self.drawGrid()
+ self.previousZoom = self.magnification
+ self.zoomMenu.config(state=NORMAL)
+
+ def zoomViewCmd(self,*args):
+ magnification = self.magVal.get()/100.0
+ self.updateZoom();
+
+ def selectItem(self,item):
+ self.clearSelection()
+ if isinstance(item,xasyScript) or isinstance(item,xasyText):
+ for image in item.imageList:
+ self.setSelection(image.IDTag)
+ else:
+ self.setSelection(item.IDTag)
+
+ def propSelect(self,event):
+ items = map(int, self.propList.curselection())
+ if len(items)>0:
+ try:
+ self.selectItem(self.fileItems[len(self.fileItems)-items[0]-1])
+ except:
+ raise
+
+ def findItem(self,ID):
+ for item in self.fileItems:
+ if isinstance(item,xasyScript) or isinstance(item,xasyText):
+ for image in item.imageList:
+ if image.IDTag == ID:
+ return item
+ else:
+ if item.IDTag == ID:
+ return item
+ raise Exception,"Illegal operation: Item with matching ID could not be found."
+
+ def findItemImageIndex(self,item,ID):
+ count = 0
+ for image in item.imageList:
+ if image.IDTag == ID:
+ return count
+ else:
+ count += 1
+ raise Exception,"Illegal operation: Image with matching ID could not be found."
+ return None
+
+ def raiseSomething(self,item,force=False):
+ if self.fileItems[-1] != item or force:
+ index = len(self.fileItems)-self.fileItems.index(item)-1
+ text = self.propList.get(index)
+ self.propList.delete(index)
+ self.propList.insert(0,text)
+ for i in range(self.fileItems.index(item),len(self.fileItems)-1):
+ self.fileItems[i] = self.fileItems[i+1]
+ self.fileItems[-1] = item
+ if isinstance(item,xasyScript) or isinstance(item,xasyText):
+ for im in item.imageList:
+ if im.IDTag != None:
+ self.mainCanvas.tag_raise(im.IDTag)
+ else:
+ if item.IDTag != None:
+ self.mainCanvas.tag_raise(item.IDTag)
+
+ def lowerSomething(self,item):
+ if self.fileItems[0] != item:
+ index = len(self.fileItems)-self.fileItems.index(item)-1
+ text = self.propList.get(index)
+ self.propList.delete(index)
+ self.propList.insert(END,text)
+ indices = range(self.fileItems.index(item))
+ indices.reverse()
+ for i in indices:
+ self.fileItems[i+1] = self.fileItems[i]
+ self.fileItems[0] = item
+ if isinstance(item,xasyScript) or isinstance(item,xasyText):
+ item.imageList.reverse()
+ for im in item.imageList:
+ if im.IDTag != None:
+ self.mainCanvas.tag_lower(im.IDTag)
+ item.imageList.reverse()
+ else:
+ if item.IDTag != None:
+ self.mainCanvas.tag_lower(item.IDTag)
+ self.mainCanvas.tag_lower("axes || grid")
+
+ def translateSomething(self,ID,translation,specificItem=None,specificIndex=None):
+ transform = asyTransform((translation[0],translation[1],1,0,0,1))
+ if ID == -1:
+ item = specificItem
+ else:
+ item = self.findItem(ID)
+ if isinstance(item,xasyText) or isinstance(item,xasyScript):
+ if ID == -1:
+ index = specificIndex
+ else:
+ index = self.findItemImageIndex(item,ID)
+ try:
+ original = item.transform[index]
+ except:
+ original = identity()
+ item.transform[index] = transform*original
+ bbox = item.imageList[index].originalImage.bbox
+ item.imageList[index].originalImage.bbox = bbox[0]+translation[0],bbox[1]+translation[1],bbox[2]+translation[0],bbox[3]+translation[1]
+ else:
+ item.transform = [transform*item.transform[0]]
+
+ def makeRotationMatrix(self,theta,origin):
+ rotMat = (math.cos(theta),-math.sin(theta),math.sin(theta),math.cos(theta))
+ shift = asyTransform((0,0,1-rotMat[0],-rotMat[1],-rotMat[2],1-rotMat[3]))*origin
+ return asyTransform((shift[0],shift[1],rotMat[0],rotMat[1],rotMat[2],rotMat[3]))
+
+ def rotateSomething(self,ID,theta,origin,specificItem=None,specificIndex=None):
+ #print "Rotating by",theta*180.0/math.pi,"around",origin
+ rotMat = self.makeRotationMatrix(theta,(origin[0]/self.magnification,origin[1]/self.magnification))
+ #print rotMat
+ if ID == -1:
+ item = specificItem
+ else:
+ item = self.findItem(ID)
+ if isinstance(item,xasyText) or isinstance(item,xasyScript):
+ #transform the image
+ if ID == -1:
+ index = specificIndex
+ else:
+ index = self.findItemImageIndex(item,ID)
+ try:
+ original = item.transform[index]
+ except:
+ original = identity()
+ oldBbox = item.imageList[index].originalImage.bbox
+ oldBbox = (oldBbox[0],-oldBbox[1],oldBbox[2],-oldBbox[3])
+ item.transform[index] = rotMat*item.transform[index]
+ item.transform[index] = rotMat*original
+ item.imageList[index].originalImage.theta += theta
+ item.imageList[index].image = item.imageList[index].originalImage.rotate(item.imageList[index].originalImage.theta*180.0/math.pi,expand=True,resample=Image.BICUBIC)
+ item.imageList[index].itk = ImageTk.PhotoImage(item.imageList[index].image)
+ self.mainCanvas.itemconfigure(ID,image=item.imageList[index].itk)
+ #the image has been rotated in place
+ #now, compensate for any resizing and shift to the correct location
+ #
+ # p0 --- p1 p1
+ # | | ---> / \
+ # p2 --- p3 p0 p3
+ # \ /
+ # p2
+ #
+ rotMat2 = self.makeRotationMatrix(item.imageList[index].originalImage.theta,origin)
+ p0 = rotMat2*(oldBbox[0],-oldBbox[3])#switch to usual coordinates
+ p1 = rotMat2*(oldBbox[2],-oldBbox[3])
+ p2 = rotMat2*(oldBbox[0],-oldBbox[1])
+ p3 = rotMat2*(oldBbox[2],-oldBbox[1])
+ newTopLeft = (min(p0[0],p1[0],p2[0],p3[0]),-max(p0[1],p1[1],p2[1],p3[1]))#switch back to screen coords
+ shift = (newTopLeft[0]-oldBbox[0],newTopLeft[1]-oldBbox[3])
+ #print theta*180.0/math.pi,origin,oldBbox,newTopLeft,shift
+ #print item.imageList[index].originalImage.size
+ #print item.imageList[index].image.size
+ #print
+ self.mainCanvas.coords(ID,oldBbox[0]+shift[0],oldBbox[3]+shift[1])
+ else:
+ #transform each point of the object
+ xform = rotMat*item.transform[0]
+ item.transform = [identity()]
+ for i in range(len(item.path.nodeSet)):
+ if item.path.nodeSet[i] != 'cycle':
+ item.path.nodeSet[i] = xform*item.path.nodeSet[i]
+ for i in range(len(item.path.controlSet)):
+ item.path.controlSet[i][0] = xform*item.path.controlSet[i][0]
+ item.path.controlSet[i][1] = xform*item.path.controlSet[i][1]
+ item.drawOnCanvas(self.mainCanvas,self.magnification)
+
+ def deleteItem(self,item):
+ if isinstance(item,xasyScript) or isinstance(item,xasyText):
+ if isinstance(item,xasyScript):
+ self.undoRedoStack.add(deleteScriptAction(self,item,self.fileItems.index(item)))
+ else:
+ self.undoRedoStack.add(deleteLabelAction(self,item,self.fileItems.index(item)))
+ for image in item.imageList:
+ self.mainCanvas.delete(image.IDTag)
+ else:
+ if isinstance(item,xasyDrawnItem):
+ self.undoRedoStack.add(deleteDrawnItemAction(self,item,self.fileItems.index(item)))
+ self.mainCanvas.delete(item.IDTag)
+ self.fileItems.remove(item)
+ self.populatePropertyList()
+ self.clearSelection()
+
+ def deleteSomething(self,ID):
+ self.clearSelection()
+ self.clearHighlight()
+ if self.editor != None:
+ self.editor.endEdit()
+ if self.editor.modified:
+ self.undoRedoStack.add(editDrawnItemAction(self,self.itemBeingEdited,copy.deepcopy(self.editor.shape),self.fileItems.index(self.editor.shape)))
+ item = self.findItem(ID)
+ #save an event on the undoredo stack
+ if isinstance(item,xasyScript):
+ index = self.findItemImageIndex(item,ID)
+ item.transform[index].deleted = True
+ else:
+ if isinstance(item,xasyText):
+ self.undoRedoStack.add(deleteLabelAction(self,item,self.fileItems.index(item)))
+ elif isinstance(item,xasyDrawnItem):
+ self.undoRedoStack.add(deleteDrawnItemAction(self,item,self.fileItems.index(item)))
+ self.fileItems.remove(item)
+ self.mainCanvas.delete(ID)
+ self.populatePropertyList()
+
+ def scriptEditThread(self,oldText):
+ try:
+ self.newText = xasyCodeEditor.getText(oldText)
+ except:
+ self.newText = -1
+
+ def getNewText(self,oldText):
+ editThread = threading.Thread(target=self.scriptEditThread,args=(oldText,))
+ editThread.start()
+ while editThread.isAlive():
+ time.sleep(0.05)
+ self.parent.update()
+ editThread.join()
+ if type(self.newText)==type(-1):
+ self.newText = ''
+ raise Exception('Error launching external editor. Please check xasy options.')
+
+ def itemEdit(self,item):
+ # are we too busy?
+ if not self.testOrAcquireLock():
+ return
+ self.updateSelectedButton(self.toolSelectButton)
+ if isinstance(item,xasyScript):
+ self.unbindGlobalEvents()
+ oldText = item.script
+ try:
+ self.getNewText(oldText)
+ except Exception,e:
+ tkMessageBox.showerror('xasy Error',e.message)
+ else:
+ if self.newText != oldText:
+ self.undoRedoStack.add(editScriptAction(self,item,self.newText,oldText))
+ item.setScript(self.newText)
+ item.drawOnCanvas(self.mainCanvas,self.magnification)
+ self.bindItemEvents(item)
+ self.bindGlobalEvents()
+ elif isinstance(item,xasyText):
+ theText = tkSimpleDialog.askstring(title="Xasy - Text",prompt="Enter text to display:",initialvalue=item.label.text,parent=self.parent)
+ if theText != None and theText != "":
+ self.undoRedoStack.add(editLabelTextAction(self,item,theText,item.label.text))
+ item.label.text = theText
+ item.drawOnCanvas(self.mainCanvas,self.magnification)
+ self.bindItemEvents(item)
+ elif isinstance(item,xasyShape):
+ self.clearSelection()
+ self.clearHighlight()
+ self.itemBeingEdited = copy.deepcopy(item)
+ self.editor = xasyBezierEditor(self,item,self.mainCanvas)
+ self.updateSelection()
+ self.releaseLock()
+
+ def itemEditEvt(self,event):
+ if not self.inDrawingMode:
+ ID = self.mainCanvas.find_withtag(CURRENT)[0]
+ item = self.findItem(ID)
+ self.itemEdit(item)
+
+ def itemDrag(self,event):
+ x0,y0 = self.mainCanvas.canvasx(event.x),self.mainCanvas.canvasy(event.y)
+ x = x0/self.magnification
+ y = y0/self.magnification
+ if self.selectedButton not in [self.toolMoveButton,self.toolVertiMoveButton,self.toolHorizMoveButton]:
+ return
+ if "selectedItem" in self.mainCanvas.gettags(CURRENT):
+ self.amDragging = True
+ for ID in self.mainCanvas.find_withtag("selectedItem"):
+ transform = identity()
+ if self.selectedButton == self.toolMoveButton:
+ translation = (x0-self.dragStartx,-(y0-self.dragStarty))
+ elif self.selectedButton == self.toolVertiMoveButton:
+ translation = (0,-(y0-self.dragStarty))
+ elif self.selectedButton == self.toolHorizMoveButton:
+ translation = (x0-self.dragStartx,0)
+ self.translateSomething(ID,(translation[0]/self.magnification,translation[1]/self.magnification))
+ self.mainCanvas.move(ID,translation[0],-translation[1])
+ self.updateSelection()
+ self.updateCanvasSize()
+ self.distanceDragged = (self.distanceDragged[0]+translation[0],self.distanceDragged[1]-translation[1])
+ self.dragStartx,self.dragStarty = x0,y0
+
+ def itemMouseUp(self,event):
+ self.freeMouseDown = True
+ if self.amDragging:
+ IDList = self.mainCanvas.find_withtag("selectedItem")
+ itemList = []
+ indexList = []
+ for ID in IDList:
+ item = self.findItem(ID)
+ if item not in itemList:
+ itemList.append(item)
+ try:
+ indexList.append([self.findItemImageIndex(item,ID)])
+ except:
+ indexList.append([None])
+ else:
+ indexList[itemList.index(item)].append(self.findItemImageIndex(item,ID))
+ self.undoRedoStack.add(translationAction(self,itemList,indexList,(self.distanceDragged[0],-self.distanceDragged[1])))
+ self.amDragging = False
+
+ def itemSelect(self,event):
+ x0,y0 = self.mainCanvas.canvasx(event.x),self.mainCanvas.canvasy(event.y)
+ x = x0/self.magnification
+ y = y0/self.magnification
+ self.dragStartx,self.dragStarty = x0,y0
+ self.distanceDragged = (0,0)
+ if self.selectedButton in [self.toolSelectButton,self.toolMoveButton,self.toolVertiMoveButton,self.toolHorizMoveButton,self.toolRotateButton]:
+ self.freeMouseDown = False
+ if self.selectedButton == self.toolSelectButton or (len(self.mainCanvas.find_withtag("selectedItem"))<=1 and self.selectedButton in [self.toolMoveButton,self.toolVertiMoveButton,self.toolHorizMoveButton,self.toolRotateButton]):
+ self.clearSelection()
+ self.setSelection(CURRENT)
+
+ def itemToggleSelect(self,event):
+ #print "control click"
+ x0,y0 = self.mainCanvas.canvasx(event.x),self.mainCanvas.canvasy(event.y)
+ x = x0/self.magnification
+ y = y0/self.magnification
+ if self.selectedButton in [self.toolSelectButton,self.toolMoveButton,self.toolVertiMoveButton,self.toolHorizMoveButton,self.toolRotateButton]:
+ self.freeMouseDown = False
+ self.dragStartx,self.dragStarty = x0,y0
+ if "selectedItem" in self.mainCanvas.gettags(CURRENT):
+ self.unSelect(CURRENT)
+ else:
+ self.setSelection(CURRENT)
+
+ def itemDelete(self,event):
+ if(not self.testOrAcquireLock()):
+ return
+ itemList = []
+ self.undoRedoStack.add(endActionGroup)
+ for ID in self.mainCanvas.find_withtag("selectedItem"):
+ item = self.findItem(ID)
+ if isinstance(item,xasyScript):
+ index = self.findItemImageIndex(item,ID)
+ if item not in itemList:
+ itemList.append([item,[index],[item.transform[index]]])
+ else:
+ x = None
+ for i in itemList:
+ if i[0] == item:
+ x = i
+ x[1].append(index)
+ x[2].append(item.transform[index])
+ self.deleteSomething(ID)
+ for entry in itemList:
+ self.undoRedoStack.add(deleteScriptItemAction(self,entry[0],entry[1],entry[2]))
+ self.undoRedoStack.add(beginActionGroup)
+ self.clearSelection()
+ self.releaseLock()
+
+ def itemMotion(self,event):
+ pass
+
+ def itemHighlight(self,event):
+ if self.selectedButton in [self.toolSelectButton] and self.editor == None:
+ box = self.mainCanvas.bbox(CURRENT)
+ box = (box[0]-2,box[1]-2,box[2]+2,box[3]+2)
+ if len(self.mainCanvas.find_withtag("highlightBox"))==0:
+ self.mainCanvas.create_rectangle(box,tags="highlightBox",width=2,outline="red")
+ else:
+ self.mainCanvas.tag_raise("highlightBox")
+ self.mainCanvas.coords("highlightBox",*box)
+ self.mainCanvas.tag_bind("highlightBox","<Leave>",self.itemUnHighlight)
+
+ def itemUnHighlight(self,event):
+ self.clearHighlight()
+
+ def clearHighlight(self):
+ self.mainCanvas.delete("highlightBox")
+
+ def itemLeftDown(self,event):
+ pass
+
+ def itemLeftUp(self,event):
+ pass
+
+ def itemRightDown(self,event):
+ pass
+
+ def itemRightUp(self,event):
+ pass
+
+ def canvMotion(self,event):
+ self.coords.config(
+ text="(%.3f,%.3f)"%(self.mainCanvas.canvasx(event.x)/self.magnification,-self.mainCanvas.canvasy(event.y)/self.magnification)
+ )
+
+ def addItemToFile(self,item):
+ self.fileItems.append(item)
+ self.propList.insert(0,self.describeItem(item))
+ self.updateCanvasSize()
+
+ def startDraw(self,event):
+ # don't start if we can't finish
+ if not self.testOrAcquireLock() and not self.inDrawingMode:
+ return
+ x0,y0 = self.mainCanvas.canvasx(event.x),self.mainCanvas.canvasy(event.y)
+ x = x0/self.magnification
+ y = y0/self.magnification
+ #self.mainCanvas.create_oval(x,y,x,y,width=5)
+ if self.selectedButton == self.toolDrawEllipButton:
+ pass
+ elif self.selectedButton == self.toolFillEllipButton:
+ pass
+ elif self.selectedButton == self.toolTextButton:
+ theText = tkSimpleDialog.askstring(title="Xasy - Text",prompt="Enter text to display:",initialvalue="",parent=self.parent)
+ if theText != None and theText != "":
+ theItem = xasyText(theText,(x,-y),asyPen(self.penColor,self.penWidth,self.penOptions))
+ theItem.drawOnCanvas(self.mainCanvas,self.magnification)
+ self.bindItemEvents(theItem)
+ self.addItemToFile(theItem)
+ self.undoRedoStack.add(addLabelAction(self,theItem))
+ self.releaseLock()
+ self.updateSelectedButton(self.toolSelectButton)
+ elif self.selectedButton in [self.toolDrawLinesButton,self.toolDrawBeziButton,self.toolDrawPolyButton,self.toolDrawShapeButton,self.toolFillPolyButton,self.toolFillShapeButton]:
+ self.inDrawingMode = True
+ try:
+ if len(self.itemBeingDrawn.path.nodeSet) == 0:
+ raise Exception
+ else:
+ if self.selectedButton in [self.toolDrawLinesButton,self.toolDrawPolyButton,self.toolFillPolyButton]:
+ self.itemBeingDrawn.appendPoint((x,-y),'--')
+ else:#drawBezi,drawShape,fillShape
+ self.itemBeingDrawn.appendPoint((x,-y),'..')
+ except:
+ path = asyPath()
+ if self.selectedButton == self.toolDrawLinesButton:
+ path.initFromNodeList([(x,-y),(x,-y)],['--'])
+ elif self.selectedButton == self.toolDrawBeziButton:
+ path.initFromNodeList([(x,-y),(x,-y)],['..'])
+ elif self.selectedButton == self.toolDrawPolyButton or self.selectedButton == self.toolFillPolyButton:
+ path.initFromNodeList([(x,-y),(x,-y),'cycle'],['--','--'])
+ elif self.selectedButton == self.toolDrawShapeButton or self.selectedButton == self.toolFillShapeButton:
+ path.initFromNodeList([(x,-y),(x,-y),'cycle'],['..','..'])
+ if self.selectedButton in [self.toolDrawLinesButton,self.toolDrawBeziButton,self.toolDrawPolyButton,self.toolDrawShapeButton]:
+ self.itemBeingDrawn = xasyShape(path,pen=asyPen(self.penColor,self.penWidth,self.penOptions))
+ else:
+ if self.penOptions.find("fillrule") != -1 or self.penOptions.find("evenodd") != -1 or self.penOptions.find("zerowinding") != -1:
+ options = self.penOptions
+ else:
+ options = "evenodd"
+ self.itemBeingDrawn = xasyFilledShape(path,pen=asyPen(self.penColor,self.penWidth,options))
+ self.itemBeingDrawn.drawOnCanvas(self.mainCanvas,self.magnification)
+ self.bindItemEvents(self.itemBeingDrawn)
+ self.mainCanvas.bind("<Motion>",self.extendDraw)
+
+ def extendDraw(self,event):
+ x0,y0 = self.mainCanvas.canvasx(event.x),self.mainCanvas.canvasy(event.y)
+ x = x0/self.magnification
+ y = y0/self.magnification
+ tags = self.mainCanvas.gettags("itemBeingDrawn")
+ self.itemBeingDrawn.setLastPoint((x,-y))
+ self.itemBeingDrawn.drawOnCanvas(self.mainCanvas,self.magnification)
+ self.canvMotion(event)
+
+ def endDraw(self,event):
+ if not self.inDrawingMode or self.itemBeingDrawn == None:
+ return
+ x0,y0 = self.mainCanvas.canvasx(event.x),self.mainCanvas.canvasy(event.y)
+ x = x0/self.magnification
+ y = y0/self.magnification
+ #if self.selectedButton in [self.toolDrawLinesButton,self.toolDrawPolyButton,self.toolFillPolyButton]:
+ #self.itemBeingDrawn.appendPoint((x,-y),'--')
+ #else:
+ #self.itemBeingDrawn.appendPoint((x,-y),'..')
+
+ #only needed for certain key bindings when startDraw is triggered right before an endDraw
+ #e.g.: single click: startDraw, double click: endDraw
+ self.itemBeingDrawn.removeLastPoint()
+ self.itemBeingDrawn.setLastPoint((x,-y))
+ self.itemBeingDrawn.drawOnCanvas(self.mainCanvas,self.magnification)
+ self.addItemToFile(self.itemBeingDrawn)
+ self.undoRedoStack.add(addDrawnItemAction(self,self.itemBeingDrawn))
+ self.itemBeingDrawn = None
+ self.mainCanvas.dtag("itemBeingDrawn","itemBeingDrawn")
+ self.mainCanvas.bind("<Motion>",self.canvMotion)
+ self.inDrawingMode = False
+ self.releaseLock()
+
+ def canvLeftDown(self,event):
+ #print "Left Mouse Down"
+ self.selectDragStart = (self.mainCanvas.canvasx(event.x),self.mainCanvas.canvasy(event.y))
+ theBbox = self.mainCanvas.bbox("selectedItem")
+ if theBbox != None:
+ self.selectBboxMidpoint = (theBbox[0]+theBbox[2])/2.0,-(theBbox[1]+theBbox[3])/2.0
+ if self.freeMouseDown and self.editor != None:
+ self.editor.endEdit()
+ if self.editor.modified:
+ self.undoRedoStack.add(editDrawnItemAction(self,self.itemBeingEdited,copy.deepcopy(self.editor.shape),self.fileItems.index(self.editor.shape)))
+ self.editor = None
+ elif self.selectedButton in (self.toolSelectButton,self.toolMoveButton,self.toolVertiMoveButton,self.toolHorizMoveButton,self.toolRotateButton):
+ if self.freeMouseDown:
+ self.clearSelection()
+ self.dragSelecting = False
+ else:
+ self.startDraw(event)
+
+ def canvLeftUp(self,event):
+ #print "Left Mouse Up"
+ # if we're busy, ignore it
+ if not self.testOrAcquireLock():
+ return
+ self.freeMouseDown = True
+ if self.inRotatingMode:
+ for item in self.itemsBeingRotated:
+ item.drawOnCanvas(self.mainCanvas,self.magnification)
+ self.bindItemEvents(item)
+ self.updateSelection()
+ self.itemsBeingRotated = []
+ self.inRotatingMode = False
+ if self.dragSelecting:
+ self.hideSelectionBox()
+ self.dragSelecting = False
+ self.mainCanvas.addtag_enclosed("enclosed",self.selectDragStart[0],self.selectDragStart[1],self.mainCanvas.canvasx(event.x),self.mainCanvas.canvasy(event.y))
+ for item in self.mainCanvas.find_withtag("enclosed"):
+ tags = self.mainCanvas.gettags(item)
+ if "drawn" not in tags and "image" not in tags:
+ self.mainCanvas.dtag(item,"enclosed")
+ self.mainCanvas.addtag_withtag("selectedItem","enclosed")
+ self.mainCanvas.dtag("enclosed","enclosed")
+ if self.selectedButton == self.toolSelectButton and len(self.mainCanvas.find_withtag("selectedItem")) > 0:
+ self.updateSelectedButton(self.toolMoveButton)
+ self.updateSelection()
+ self.releaseLock()
+
+ def canvDrag(self,event):
+ x0,y0 = self.mainCanvas.canvasx(event.x),self.mainCanvas.canvasy(event.y)
+ x = x0/self.magnification
+ y = y0/self.magnification
+ if self.selectedButton == self.toolSelectButton and self.editor == None:
+ self.mainCanvas.coords("outlineBox",self.selectDragStart[0],self.selectDragStart[1],x0,y0)
+ self.showSelectionBox()
+ self.dragSelecting = True
+ elif self.selectedButton == self.toolRotateButton and self.editor == None:
+ bbox = self.mainCanvas.bbox("selectedItem")
+ if bbox != None:
+ p1 = self.selectDragStart[0]-self.selectBboxMidpoint[0],-self.selectDragStart[1]-self.selectBboxMidpoint[1]
+ mp1 = math.sqrt(p1[0]**2+p1[1]**2)
+ p2 = x0-self.selectBboxMidpoint[0],-y0-self.selectBboxMidpoint[1]
+ mp2 = math.sqrt(p2[0]**2+p2[1]**2)
+ if mp1 != 0:
+ t1 = math.acos(p1[0]/mp1)
+ if p1[1] < 0:
+ t1 *= -1
+ else:
+ t1 = 0
+ if mp2 != 0:
+ t2 = math.acos(p2[0]/mp2)
+ if p2[1] < 0:
+ t2 *= -1
+ else:
+ t2 = 0
+ theta = t2-t1
+ self.selectDragStart = x0,y0
+ self.itemsBeingRotated = []
+ for ID in self.mainCanvas.find_withtag("selectedItem"):
+ self.rotateSomething(ID,theta,self.selectBboxMidpoint)
+ item = self.findItem(ID)
+ if not item in self.itemsBeingRotated:
+ self.itemsBeingRotated.append(item)
+ self.updateSelection()
+ self.updateCanvasSize()
+ if not self.inRotatingMode:
+ self.currentRotationAngle = theta
+ IDList = self.mainCanvas.find_withtag("selectedItem")
+ itemList = []
+ indexList = []
+ for ID in IDList:
+ item = self.findItem(ID)
+ if item not in itemList:
+ itemList.append(item)
+ try:
+ indexList.append([self.findItemImageIndex(item,ID)])
+ except:
+ indexList.append([None])
+ else:
+ indexList[itemList.index(item)].append(self.findItemImageIndex(item,ID))
+ self.undoRedoStack.add(rotationAction(self,itemList,indexList,self.currentRotationAngle,self.selectBboxMidpoint))
+ self.inRotatingMode = True
+ else:
+ self.currentRotationAngle += theta
+ self.undoRedoStack.undoStack[-1].angle = self.currentRotationAngle
+
+ def canvEnter(self,event):
+ self.freeMouseDown = True
+ event.widget.focus_set()
+
+ def canvLeave(self,event):
+ self.freeMouseDown = False
+
+ def canvRightDown(self,event):
+ pass
+ #print "Right Mouse Down"
+
+ def canvRightUp(self,event):
+ pass
+ #print "Right Mouse Up"
+
+ def configEvt(self,event):
+ self.updateCanvasSize()
+ self.sizePane()
+
+ def sizePane(self):
+ width = self.windowPane.winfo_width()-10
+ cwidth = min(int(0.87*self.windowPane.winfo_width()),width-75)
+ if self.paneVisible:
+ self.windowPane.paneconfigure(self.canvFrame,minsize=cwidth)
+ else:
+ self.windowPane.paneconfigure(self.canvFrame,minsize=width)
+ self.windowPane.paneconfigure(self.propFrame,minsize=75)
+
+ def togglePaneEvt(self,event):
+ self.paneVisible = not self.paneVisible
+ self.sizePane()
+
+ def popupDelete(self):
+ self.deleteItem(self.itemPopupMenu.item)
+
+ def popupEdit(self):
+ self.itemEdit(self.itemPopupMenu.item)
+
+ def popupViewCode(self):
+ tkMessageBox.showinfo("Item Code",self.itemPopupMenu.item.getCode())
+
+ def popupClearTransform(self):
+ self.undoRedoStack.add(clearItemTransformsAction(self,self.itemPopupMenu.item,copy.deepcopy(self.itemPopupMenu.item.transform)))
+ if isinstance(self.itemPopupMenu.item,xasyScript) or isinstance(self.itemPopupMenu.item,xasyText):
+ for i in range(len(self.itemPopupMenu.item.transform)):
+ self.itemPopupMenu.item.transform[i] = identity()
+ else:
+ self.itemPopupMenu.item.transform = [identity()]
+ self.popupRedrawItem()
+
+ def popupRedrawItem(self):
+ if not self.testOrAcquireLock():
+ return
+ self.clearSelection()
+ self.clearHighlight()
+ self.itemPopupMenu.item.drawOnCanvas(self.mainCanvas,self.magnification)
+ self.bindItemEvents(self.itemPopupMenu.item)
+ self.updateCanvasSize()
+ self.releaseLock()
+
+ def hidePopupMenu(self):
+ try:
+ self.itemPopupMenu.unpost()
+ except:
+ pass
+
+ def itemMenuPopup(self,parent,item,x,y):
+ self.hidePopupMenu()
+ self.itemPopupMenu = Menu(parent,tearoff=False)
+ self.itemPopupMenu.add_command(label="Edit",command=self.popupEdit)
+ self.itemPopupMenu.add_command(label="Clear Transforms",command=self.popupClearTransform)
+ self.itemPopupMenu.add_command(label="Redraw",command=self.popupRedrawItem)
+ self.itemPopupMenu.add_command(label="View code",command=self.popupViewCode)
+ self.itemPopupMenu.add_separator()
+ self.itemPopupMenu.add_command(label="Delete",command=self.popupDelete)
+ self.itemPopupMenu.item = item
+ #self.itemPopupMenu.bind("<Leave>",lambda a:self.itemPopupMenu.unpost())
+ #self.itemPopupMenu.bind("<FocusOut>",lambda a:self.itemPopupMenu.unpost())
+ self.itemPopupMenu.post(x,y)
+
+ def itemPropMenuPopup(self,event):
+ try:
+ item = self.fileItems[len(self.fileItems)-int(self.propList.curselection()[0])-1]
+ self.itemMenuPopup(self.propList,item,event.x_root,event.y_root)
+ except:
+ pass
+
+ def itemCanvasMenuPopup(self,event):
+ if self.selectedButton in (self.toolSelectButton,self.toolMoveButton,self.toolVertiMoveButton,self.toolHorizMoveButton,self.toolRotateButton):
+ try:
+ item = self.findItem(self.mainCanvas.find_withtag(CURRENT)[0])
+ except:
+ item = None
+ if item != None:
+ self.itemMenuPopup(self.mainCanvas,item,event.x_root,event.y_root)
+
+ def editOptions(self):
+ if(not self.testOrAcquireLock()):
+ return
+ self.releaseLock()
+ xasyOptionsDialog.xasyOptionsDlg(self.parent)
+ self.applyOptions()
+
+ def resetOptions(self):
+ xasyOptions.setDefaults()
+ self.applyOptions()
+
+ def applyPenWidth(self):
+ self.pendingPenWidthChange = None
+ if self.validatePenWidth():
+ old = self.penWidth
+ self.penWidth = float(self.penWidthEntry.get())
+ if old != self.penWidth:
+ self.showCurrentPen()
+
+ def validatePenWidth(self):
+ text = self.penWidthEntry.get()
+ try:
+ width = float(text)
+ if width <= 0:
+ return False
+ else:
+ return True
+ except:
+ return False
+
+ def showCurrentPen(self):
+ mag = 1
+ width = self.penWidth
+ while width > 10:
+ width /= 2
+ mag *= 2
+ self.penDisp.itemconfigure("penDisp",width=width,fill=self.tkPenColor)
+ self.penDisp.itemconfigure("penMag",text="x%d"%mag)
+ #apply the new pen to any selected items
+ IDs = self.mainCanvas.find_withtag("selectedItem")
+ madeAChange = False
+ for ID in IDs:
+ item = self.findItem(ID)
+ if not isinstance(item,xasyScript):
+ if not madeAChange:
+ self.undoRedoStack.add(endActionGroup)
+ madeAChange = True
+ if isinstance(item,xasyText):
+ temp = item.label.pen
+ item.label.pen = asyPen(self.penColor,self.penWidth,self.penOptions)
+ item.drawOnCanvas(self.mainCanvas,self.magnification)
+ self.bindItemEvents(item)
+ self.setSelection(item.imageList[0].IDTag)
+ self.undoRedoStack.add(editLabelPenAction(self,temp,asyPen(self.penColor,self.penWidth,self.penOptions),self.fileItems.index(item)))
+ else:
+ temp = copy.deepcopy(item)
+ item.pen = asyPen(self.penColor,self.penWidth,self.penOptions)
+ item.drawOnCanvas(self.mainCanvas,self.magnification)
+ self.undoRedoStack.add(editDrawnItemAction(self,temp,copy.deepcopy(item),self.fileItems.index(item)))
+ if madeAChange:
+ self.undoRedoStack.add(beginActionGroup)
+
+ def applyPenWidthEvt(self,event):
+ if not self.testOrAcquireLock():
+ return
+ self.applyPenWidth()
+ self.releaseLock()
+
+ def penWidthChanged(self,event):
+ if self.pendingPenWidthChange is not None:
+ self.penWidthEntry.after_cancel(self.pendingPenWidthChange)
+ self.pendingPenWidthChange = self.penWidthEntry.after(1000,self.applyPenWidth)
+
+ def applyPenOptEvt(self,event):
+ if not self.testOrAcquireLock():
+ return
+ self.applyPenOpt()
+ self.releaseLock()
+
+ def validatePenOpt(self):
+ try:
+ penTest = asyPen(self.penColor,self.penWidth,self.penOptEntry.get())
+ return True
+ except:
+ self.penOptEntry.select_range(0,END)
+ self.penOptEntry.delete(0,END)
+ self.penOptEntry.insert(END,"Invalid Pen Options")
+ self.penOptEntry.after(5000,self.clearInvalidOptEntry)
+ self.penOptions = ""
+ return False
+
+ def clearInvalidOptEntry(self):
+ self.penOptEntry.select_range(0,END)
+ self.penOptEntry.delete(0,END)
+
+ def applyPenOpt(self):
+ if self.validatePenOpt():
+ old = self.penOptions
+ self.penOptions = self.penOptEntry.get()
+ if old != self.penOptions:
+ self.showCurrentPen()
+
+ def undoOperation(self):
+ self.undoRedoStack.undo()
+
+ def redoOperation(self):
+ self.undoRedoStack.redo()
+
+ def resetStacking(self):
+ for item in self.fileItems:
+ self.raiseSomething(item,force=True)
diff --git a/Build/source/utils/asymptote/GUI/xasyOptions.py b/Build/source/utils/asymptote/GUI/xasyOptions.py
new file mode 100755
index 00000000000..4406687cbf4
--- /dev/null
+++ b/Build/source/utils/asymptote/GUI/xasyOptions.py
@@ -0,0 +1,126 @@
+#!/usr/bin/env python
+###########################################################################
+#
+# xasyOptions provides a mechanism for storing and restoring a user's
+# preferences.
+#
+#
+# Author: Orest Shardt
+# Created: June 29, 2007
+#
+###########################################################################
+
+import pickle
+import sys,os
+import errno
+
+defaultOptions = {
+ 'asyPath':'asy',
+ 'showDebug':False,
+ 'showGrid':False,
+ 'gridX':10,
+ 'gridY':10,
+ 'gridColor':'#eeeeee',
+ 'showAxes':True,
+ 'axisX':10,
+ 'axisY':10,
+ 'axesColor':'#cccccc',
+ 'tickColor':'#eeeeee',
+ 'defPenOptions':'',
+ 'defPenColor':'#000000',
+ 'defPenWidth':1.0,
+ 'externalEditor':''
+ }
+
+if sys.platform[:3] == "win":
+ defaultOptions['externalEditor'] = "notepad.exe"
+else:
+ defaultOptions['externalEditor'] = "emacs"
+
+
+options = defaultOptions.copy()
+
+def settingsFileLocation():
+ folder = ""
+ try:
+ folder = os.path.expanduser("~/.asy/")
+ except:
+ pass
+ return os.path.normcase(os.path.join(folder,"xasy.conf"))
+
+def setAsyPathFromWindowsRegistry():
+ try:
+ import _winreg as registry
+ #test both registry locations
+ try:
+ key = registry.OpenKey(registry.HKEY_LOCAL_MACHINE,"Software\\Microsoft\\Windows\\CurrentVersion\\App Paths\\Asymptote")
+ options['asyPath'] = registry.QueryValueEx(key,"Path")[0]+"\\asy.exe"
+ registry.CloseKey(key)
+ except:
+ key = registry.OpenKey(registry.HKEY_LOCAL_MACHINE,"Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\Asymptote")
+ options['asyPath'] = registry.QueryValueEx(key,"InstallLocation")[0]+"\\asy.exe"
+ registry.CloseKey(key)
+ except:
+ #looks like asy is not installed or this isn't Windows
+ pass
+
+def setDefaults():
+ global options
+ options = defaultOptions.copy()
+ if sys.platform[:3] == 'win': #for windows, wince, win32, etc
+ setAsyPathFromWindowsRegistry()
+ save()
+
+def load():
+ global options
+ fileName = settingsFileLocation()
+ if not os.path.exists(fileName):
+ #make folder
+ thedir = os.path.dirname(fileName)
+ if not os.path.exists(thedir):
+ try:
+ os.makedirs(thedir)
+ except:
+ raise Exception,"Could not create configuration folder"
+ if not os.path.isdir(thedir):
+ raise Exception,"Configuration folder path does not point to a folder"
+ setDefaults()
+ try:
+ f = open(fileName,"rb")
+ newOptions = pickle.load(f)
+ for key in options.keys():
+ if type(newOptions[key]) != type(options[key]):
+ raise Exception,"Bad type for entry in xasy settings"
+ options = newOptions
+ except:
+ setDefaults()
+
+def save():
+ global options
+ fileName = settingsFileLocation()
+ try:
+ f = open(fileName,"wb")
+ pickle.dump(options,f)
+ f.close()
+ except:
+ raise Exception,"Error saving preferences"
+
+load()
+
+if __name__=='__main__':
+ print settingsFileLocation()
+ print "Current content"
+ load()
+ print "Setting defaults"
+ setDefaults()
+ save()
+ load()
+ options['showAxes'] = options['showGrid'] = False
+ save()
+ print "Set to False"
+ load()
+ options['showAxes'] = options['showGrid'] = True
+ save()
+ print "Set to True"
+ load()
+ print options
diff --git a/Build/source/utils/asymptote/GUI/xasyOptionsDialog.py b/Build/source/utils/asymptote/GUI/xasyOptionsDialog.py
new file mode 100755
index 00000000000..b93b2a7fed9
--- /dev/null
+++ b/Build/source/utils/asymptote/GUI/xasyOptionsDialog.py
@@ -0,0 +1,245 @@
+#!/usr/bin/env python
+###########################################################################
+#
+# xasyOptionsDialog implements a dialog window to allow users to edit
+# their preferences and specify program options
+#
+#
+# Author: Orest Shardt
+# Created: June 29, 2007
+#
+###########################################################################
+
+from Tkinter import *
+import xasyOptions
+import tkSimpleDialog
+import xasyColorPicker
+import tkMessageBox
+import tkFileDialog
+import tkColorChooser
+import os
+import subprocess
+import sys
+
+class xasyOptionsDlg(tkSimpleDialog.Dialog):
+ """A dialog to interact with users about their preferred settings"""
+ def __init__(self,master=None):
+ tkSimpleDialog.Dialog.__init__(self,master,"xasy Options")
+
+ def body(self,master):
+ optFrame = Frame(master)
+ optFrame.grid(row=0,column=0,sticky=N+S+E+W)
+
+ asyGrp = LabelFrame(optFrame,text="Asymptote",padx=5,pady=5)
+ asyGrp.grid(row=0,column=0,sticky=E+W)
+ asyGrp.rowconfigure(0,weight=1)
+ asyGrp.rowconfigure(1,weight=1)
+ asyGrp.columnconfigure(0,weight=1)
+ asyGrp.columnconfigure(0,weight=2)
+ Label(asyGrp,text="Command").grid(row=0,column=0,sticky=W)
+ self.ap = Entry(asyGrp)
+ self.ap.insert(END,xasyOptions.options['asyPath'])
+ self.ap.grid(row=0,column=1,sticky=E+W)
+ Button(asyGrp,text="...",command=self.findAsyPath).grid(row=0,column=2,sticky=E+W)
+ self.showDebug = BooleanVar()
+ self.showDebug.set(xasyOptions.options['showDebug'])
+ self.sd = Checkbutton(asyGrp,text="Show debugging info in console",var=self.showDebug)
+ self.sd.grid(row=1,column=0,columnspan=2,sticky=W)
+
+ editGrp = LabelFrame(optFrame,text="External Editor",padx=5,pady=5)
+ editGrp.grid(row=1,column=0,sticky=E+W)
+ editGrp.rowconfigure(0,weight=1)
+ editGrp.rowconfigure(1,weight=1)
+ editGrp.columnconfigure(0,weight=1)
+ editGrp.columnconfigure(0,weight=2)
+ Label(editGrp,text="Program").grid(row=0,column=0,sticky=W)
+ self.ee = Entry(editGrp)
+ self.ee.insert(END,xasyOptions.options['externalEditor'])
+ self.ee.grid(row=0,column=1,sticky=E+W)
+ Button(editGrp,text="...",command=self.findEEPath).grid(row=0,column=2,sticky=E+W)
+
+ penGrp = LabelFrame(optFrame,text="Default Pen",padx=5,pady=5)
+ penGrp.grid(row=2,column=0,sticky=E+W)
+ penGrp.rowconfigure(0,weight=1)
+ penGrp.rowconfigure(1,weight=1)
+ penGrp.rowconfigure(2,weight=1)
+ penGrp.columnconfigure(1,weight=1)
+ Label(penGrp,text="Color").grid(row=0,column=0,sticky=E)
+ self.pc = xasyOptions.options['defPenColor']
+ Button(penGrp,text="Change",command=self.changePenColor).grid(row=0,column=1,sticky=W)
+ Label(penGrp,text="Width").grid(row=1,column=0,sticky=E)
+ self.pw = Entry(penGrp)
+ self.pw.insert(END,str(xasyOptions.options['defPenWidth']))
+ self.pw.grid(row=1,column=1,sticky=E+W)
+ Label(penGrp,text="Options").grid(row=2,column=0,sticky=E)
+ self.po = Entry(penGrp)
+ self.po.insert(END,xasyOptions.options['defPenOptions'])
+ self.po.grid(row=2,column=1,sticky=E+W)
+
+ dispGrp = LabelFrame(optFrame,text="Display Options",padx=5,pady=5)
+ dispGrp.grid(row=3,column=0,sticky=E+W)
+ dispGrp.rowconfigure(0,weight=1)
+ dispGrp.rowconfigure(1,weight=1)
+ dispGrp.rowconfigure(2,weight=1)
+ dispGrp.rowconfigure(3,weight=1)
+ dispGrp.columnconfigure(0,weight=1)
+ dispGrp.columnconfigure(1,weight=1)
+ dispGrp.columnconfigure(2,weight=1)
+ self.showAxes = BooleanVar()
+ self.showAxes.set(xasyOptions.options['showAxes'])
+ self.sa = Checkbutton(dispGrp,text="Show Axes",var=self.showAxes)
+ self.sa.grid(row=0,column=0,sticky=W)
+ self.ac = xasyOptions.options['axesColor']
+ Button(dispGrp,text="Color...",command=self.changeAxesColor).grid(row=1,column=0)
+ Label(dispGrp,text="x").grid(row=0,column=1,padx=5,sticky=E)
+ self.axs = Entry(dispGrp,width=6)
+ self.axs.insert(END,xasyOptions.options['axisX'])
+ self.axs.grid(row=0,column=2,sticky=W+E)
+ Label(dispGrp,text="y").grid(row=1,column=1,padx=5,sticky=E)
+ self.ays = Entry(dispGrp,width=6)
+ self.ays.insert(END,xasyOptions.options['axisY'])
+ self.ays.grid(row=1,column=2,sticky=W+E)
+
+ self.showGrid = BooleanVar()
+ self.showGrid.set(xasyOptions.options['showGrid'])
+ self.sg = Checkbutton(dispGrp,text="Show Grid",var=self.showGrid)
+ self.sg.grid(row=4,column=0,sticky=W)
+ self.gc = xasyOptions.options['gridColor']
+ Button(dispGrp,text="Color...",command=self.changeGridColor).grid(row=3,column=0)
+ Label(dispGrp,text="x").grid(row=2,column=1,padx=5,sticky=E)
+ self.gxs = Entry(dispGrp,width=6)
+ self.gxs.insert(END,xasyOptions.options['gridX'])
+ self.gxs.grid(row=2,column=2,sticky=W+E)
+ Label(dispGrp,text="y").grid(row=3,column=1,padx=5,sticky=E)
+ self.gys = Entry(dispGrp,width=6)
+ self.gys.insert(END,xasyOptions.options['gridY'])
+ self.gys.grid(row=3,column=2,sticky=W+E)
+
+ def findEEPath(self):
+ if sys.platform[:3] == 'win': #for windows, wince, win32, etc
+ file=tkFileDialog.askopenfile(filetypes=[("Programs","*.exe"),("All files","*")],title="Choose External Editor",parent=self)
+ else:
+ file=tkFileDialog.askopenfile(filetypes=[("All files","*")],title="Choose External Editor",parent=self)
+ if file != None:
+ name = os.path.abspath(file.name)
+ file.close()
+ self.ee.delete(0,END)
+ self.ee.insert(END,name)
+ self.validate()
+
+ def findAsyPath(self):
+ if sys.platform[:3] == 'win': #for windows, wince, win32, etc
+ file=tkFileDialog.askopenfile(filetypes=[("Programs","*.exe"),("All files","*")],title="Find Asymptote Executable",parent=self)
+ else:
+ file=tkFileDialog.askopenfile(filetypes=[("All files","*")],title="Find Asymptote Executable",parent=self)
+ if file != None:
+ name = os.path.abspath(file.name)
+ file.close()
+ self.ap.delete(0,END)
+ self.ap.insert(END,name)
+ self.validate()
+
+ def getAColor(self,color):
+ result = xasyColorPicker.xasyColorDlg(self).getColor(xasyColorPicker.makeRGBfromTkColor(color))
+ return xasyColorPicker.RGB255hex(xasyColorPicker.RGBreal255(result))
+
+ def changeAxesColor(self):
+ self.ac = self.getAColor(self.ac)
+
+ def changeGridColor(self):
+ self.gc = self.getAColor(self.gc)
+
+ def changePenColor(self):
+ self.pc = self.getAColor(self.pc)
+
+ def apply(self):
+ xasyOptions.options['externalEditor'] = self.ee.get()
+ xasyOptions.options['asyPath'] = self.ap.get()
+ xasyOptions.options['showDebug'] = bool(self.showDebug.get())
+
+ xasyOptions.options['defPenColor'] = self.pc
+ xasyOptions.options['defPenWidth'] = float(self.pw.get())
+ xasyOptions.options['defPenOptions'] = self.po.get()
+
+ xasyOptions.options['showAxes'] = bool(self.showAxes.get())
+ xasyOptions.options['axesColor'] = self.ac
+ xasyOptions.options['tickColor'] = self.ac
+ xasyOptions.options['axisX'] = int(self.axs.get())
+ xasyOptions.options['axisY'] = int(self.ays.get())
+ xasyOptions.options['showGrid'] = bool(self.showGrid.get())
+ xasyOptions.options['gridColor'] = self.gc
+ xasyOptions.options['gridX'] = int(self.gxs.get())
+ xasyOptions.options['gridY'] = int(self.gys.get())
+ xasyOptions.save()
+
+ def validateAColor(self,color):
+ hexdigits = '0123456789abcdef'
+ if len(self.pc) != 7 or self.pc[0] != '#' or sum([1 for a in self.pc[1:] if a in hexdigits]) != 6:
+ return False
+ else:
+ return True
+
+ def validate(self):
+ """Validate the data entered into the dialog"""
+ #validate the path
+ pathOK = True
+ try:
+ test = subprocess.Popen([self.ap.get(),"-interactive"],stdin=subprocess.PIPE,stdout=subprocess.PIPE,stderr=subprocess.PIPE)
+ test.stdin.close()
+ test.wait()
+ idString = test.stdout.read()
+ except:
+ pathOK = False
+ if not pathOK or not idString.startswith("Welcome to Asymptote"):
+ tkMessageBox.showerror("xasy Options","Specified file does not exist or is not an Asymptote executable.\r\n"+self.ap.get(),parent=self)
+ return False
+
+ #validate the external editor
+ # how can I validate the editor?
+
+ #validate the color
+ hexdigits = '0123456789abcdef'
+ if not self.validateAColor(self.pc):
+ tkMessageBox.showerror("xasy Options","Invalid pen color.\r\n"+self.pc,parent=self)
+ return False
+ #validate the width
+ try:
+ test = float(self.pw.get())
+ except:
+ tkMessageBox.showerror("xasy Options","Pen width must be a number.",parent=self)
+ return False
+
+ #validate the options
+ #nothing to do
+
+ #validate the axis spacing
+ try:
+ test = int(self.axs.get())
+ test = int(self.ays.get())
+ except:
+ tkMessageBox.showerror("xasy Options","Axes' x- and y-spacing must be numbers.",parent=self)
+ return False
+
+ #validate the grid spacing
+ try:
+ test = int(self.gxs.get())
+ test = int(self.gys.get())
+ except:
+ tkMessageBox.showerror("xasy Options","Grid's x- and y-spacing must be numbers.",parent=self)
+ return False
+
+ if not self.validateAColor(self.ac):
+ tkMessageBox.showerror("xasy Options","Invalid axis color.\r\n"+self.ac,parent=self)
+ return False
+
+ if not self.validateAColor(self.gc):
+ tkMessageBox.showerror("xasy Options","Invalid grid color.\r\n"+self.gc,parent=self)
+ return False
+
+ return True
+
+if __name__ == '__main__':
+ root = Tk()
+ xasyOptions.load()
+ d = xasyOptionsDlg(root)
+ print d.result
diff --git a/Build/source/utils/asymptote/INSTALL b/Build/source/utils/asymptote/INSTALL
new file mode 100644
index 00000000000..581096dbb0d
--- /dev/null
+++ b/Build/source/utils/asymptote/INSTALL
@@ -0,0 +1,275 @@
+Compiling Asymptote from a Source Release
+=========================================
+
+To compile and install Asymptote version x.xx from a source release:
+
+gunzip asymptote-x.xx.src.tgz
+tar -xf asymptote-x.xx.src.tar
+cd asymptote-x.xx
+./configure
+make all
+make install
+
+The last command requires root privileges. To install without root privileges
+you should change the first line to
+
+./configure --prefix=$HOME/asymptote
+
+If you get errors from a broken pdftex installation, simply put
+http://asymptote.sourceforge.net/asymptote.pdf
+in the doc directory and repeat the commands make all and make install.
+
+For a list of configure options, type
+
+configure --help
+
+See also the generic configure instructions below.
+
+Compiling Asymptote from Subversion Developmental Source Code
+=============================================================
+
+To compile from Subversion developmental source code:
+
+svn co http://asymptote.svn.sourceforge.net/svnroot/asymptote/trunk/asymptote
+cd asymptote
+./autogen.sh
+./configure
+make all
+make install
+
+Optional packages:
+
+* Fast Fourier Transform library
+ http://www.fftw.org/
+
+ Version requirement >= 3.0
+
+* The GNU Scientific Library for numerical analysis:
+ http://www.gnu.org/software/gsl/
+
+*****************************************
+Generic Configure Instructions (advanced)
+*****************************************
+
+ The `configure' shell script attempts to guess correct values for
+various system-dependent variables used during compilation. It uses
+those values to create a `Makefile' in each directory of the package.
+It may also create one or more `.h' files containing system-dependent
+definitions. Finally, it creates a shell script `config.status' that
+you can run in the future to recreate the current configuration, and a
+file `config.log' containing compiler output (useful mainly for
+debugging `configure').
+
+ It can also use an optional file (typically called `config.cache'
+and enabled with `--cache-file=config.cache' or simply `-C') that saves
+the results of its tests to speed up reconfiguring. (Caching is
+disabled by default to prevent problems with accidental use of stale
+cache files.)
+
+ If you need to do unusual things to compile the package, please try
+to figure out how `configure' could check whether to do them, and mail
+diffs or instructions to the address given in the `README' so they can
+be considered for the next release. If you are using the cache, and at
+some point `config.cache' contains results you don't want to keep, you
+may remove or edit it.
+
+ The file `configure.ac' (or `configure.in') is used to create
+`configure' by a program called `autoconf'. You only need
+`configure.ac' if you want to change it or regenerate `configure' using
+a newer version of `autoconf'.
+
+The simplest way to compile this package is:
+
+ 1. `cd' to the directory containing the package's source code and type
+ `./configure' to configure the package for your system. If you're
+ using `csh' on an old version of System V, you might need to type
+ `sh ./configure' instead to prevent `csh' from trying to execute
+ `configure' itself.
+
+ Running `configure' takes awhile. While running, it prints some
+ messages telling which features it is checking for.
+
+ 2. Type `make' to compile the package.
+
+ 3. Optionally, type `make check' to run any self-tests that come with
+ the package.
+
+ 4. Type `make install' to install the programs and any data files and
+ documentation.
+
+ 5. You can remove the program binaries and object files from the
+ source code directory by typing `make clean'. To also remove the
+ files that `configure' created (so you can compile the package for
+ a different kind of computer), type `make distclean'. There is
+ also a `make maintainer-clean' target, but that is intended mainly
+ for the package's developers. If you use it, you may have to get
+ all sorts of other programs in order to regenerate files that came
+ with the distribution.
+
+Compilers and Options
+=====================
+
+Some systems require unusual options for compilation or linking that the
+`configure' script does not know about. Run `./configure --help' for
+details on some of the pertinent environment variables.
+
+ You can give `configure' initial values for configuration parameters
+by setting variables in the command line or in the environment. Here
+is an example:
+
+ ./configure CC=c89 CFLAGS=-O2 LIBS=-lposix
+
+ *Note Defining Variables::, for more details.
+
+Compiling For Multiple Architectures
+====================================
+
+You can compile the package for more than one kind of computer at the
+same time, by placing the object files for each architecture in their
+own directory. To do this, you must use a version of `make' that
+supports the `VPATH' variable, such as GNU `make'. `cd' to the
+directory where you want the object files and executables to go and run
+the `configure' script. `configure' automatically checks for the
+source code in the directory that `configure' is in and in `..'.
+
+ If you have to use a `make' that does not support the `VPATH'
+variable, you have to compile the package for one architecture at a
+time in the source code directory. After you have installed the
+package for one architecture, use `make distclean' before reconfiguring
+for another architecture.
+
+Installation Names
+==================
+
+By default, `make install' installs the package's commands under
+`/usr/local/bin', include files under `/usr/local/include', etc. You
+can specify an installation prefix other than `/usr/local' by giving
+`configure' the option `--prefix=PREFIX'.
+
+ You can specify separate installation prefixes for
+architecture-specific files and architecture-independent files. If you
+pass the option `--exec-prefix=PREFIX' to `configure', the package uses
+PREFIX as the prefix for installing programs and libraries.
+Documentation and other data files still use the regular prefix.
+
+ In addition, if you use an unusual directory layout you can give
+options like `--bindir=DIR' to specify different values for particular
+kinds of files. Run `configure --help' for a list of the directories
+you can set and what kinds of files go in them.
+
+ If the package supports it, you can cause programs to be installed
+with an extra prefix or suffix on their names by giving `configure' the
+option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'.
+
+Optional Features
+=================
+
+Some packages pay attention to `--enable-FEATURE' options to
+`configure', where FEATURE indicates an optional part of the package.
+They may also pay attention to `--with-PACKAGE' options, where PACKAGE
+is something like `gnu-as' or `x' (for the X Window System). The
+`README' should mention any `--enable-' and `--with-' options that the
+package recognizes.
+
+ For packages that use the X Window System, `configure' can usually
+find the X include and library files automatically, but if it doesn't,
+you can use the `configure' options `--x-includes=DIR' and
+`--x-libraries=DIR' to specify their locations.
+
+Specifying the System Type
+==========================
+
+There may be some features `configure' cannot figure out automatically,
+but needs to determine by the type of machine the package will run on.
+Usually, assuming the package is built to be run on the _same_
+architectures, `configure' can figure that out, but if it prints a
+message saying it cannot guess the machine type, give it the
+`--build=TYPE' option. TYPE can either be a short name for the system
+type, such as `sun4', or a canonical name which has the form:
+
+ CPU-COMPANY-SYSTEM
+
+where SYSTEM can have one of these forms:
+
+ OS KERNEL-OS
+
+ See the file `config.sub' for the possible values of each field. If
+`config.sub' isn't included in this package, then this package doesn't
+need to know the machine type.
+
+ If you are _building_ compiler tools for cross-compiling, you should
+use the option `--target=TYPE' to select the type of system they will
+produce code for.
+
+ If you want to _use_ a cross compiler, that generates code for a
+platform different from the build platform, you should specify the
+"host" platform (i.e., that on which the generated programs will
+eventually be run) with `--host=TYPE'.
+
+Sharing Defaults
+================
+
+If you want to set default values for `configure' scripts to share, you
+can create a site shell script called `config.site' that gives default
+values for variables like `CC', `cache_file', and `prefix'.
+`configure' looks for `PREFIX/share/config.site' if it exists, then
+`PREFIX/etc/config.site' if it exists. Or, you can set the
+`CONFIG_SITE' environment variable to the location of the site script.
+A warning: not all `configure' scripts look for a site script.
+
+Defining Variables
+==================
+
+Variables not defined in a site shell script can be set in the
+environment passed to `configure'. However, some packages may run
+configure again during the build, and the customized values of these
+variables may be lost. In order to avoid this problem, you should set
+them in the `configure' command line, using `VAR=value'. For example:
+
+ ./configure CC=/usr/local2/bin/gcc
+
+causes the specified `gcc' to be used as the C compiler (unless it is
+overridden in the site shell script). Here is a another example:
+
+ /bin/bash ./configure CONFIG_SHELL=/bin/bash
+
+Here the `CONFIG_SHELL=/bin/bash' operand causes subsequent
+configuration-related scripts to be executed by `/bin/bash'.
+
+`configure' Invocation
+======================
+
+`configure' recognizes the following options to control how it operates.
+
+`--help'
+`-h'
+ Print a summary of the options to `configure', and exit.
+
+`--version'
+`-V'
+ Print the version of Autoconf used to generate the `configure'
+ script, and exit.
+
+`--cache-file=FILE'
+ Enable the cache: use and save the results of the tests in FILE,
+ traditionally `config.cache'. FILE defaults to `/dev/null' to
+ disable caching.
+
+`--config-cache'
+`-C'
+ Alias for `--cache-file=config.cache'.
+
+`--quiet'
+`--silent'
+`-q'
+ Do not print messages saying which checks are being made. To
+ suppress all normal output, redirect it to `/dev/null' (any error
+ messages will still be shown).
+
+`--srcdir=DIR'
+ Look for the package's source code in directory DIR. Usually
+ `configure' can determine that directory automatically.
+
+`configure' also accepts some other options. Run
+`configure --help' for more details.
+
diff --git a/Build/source/utils/asymptote/LICENSE b/Build/source/utils/asymptote/LICENSE
new file mode 100644
index 00000000000..94a9ed024d3
--- /dev/null
+++ b/Build/source/utils/asymptote/LICENSE
@@ -0,0 +1,674 @@
+ GNU GENERAL PUBLIC LICENSE
+ Version 3, 29 June 2007
+
+ Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The GNU General Public License is a free, copyleft license for
+software and other kinds of works.
+
+ The licenses for most software and other practical works are designed
+to take away your freedom to share and change the works. By contrast,
+the GNU General Public License is intended to guarantee your freedom to
+share and change all versions of a program--to make sure it remains free
+software for all its users. We, the Free Software Foundation, use the
+GNU General Public License for most of our software; it applies also to
+any other work released this way by its authors. You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+them if you wish), that you receive source code or can get it if you
+want it, that you can change the software or use pieces of it in new
+free programs, and that you know you can do these things.
+
+ To protect your rights, we need to prevent others from denying you
+these rights or asking you to surrender the rights. Therefore, you have
+certain responsibilities if you distribute copies of the software, or if
+you modify it: responsibilities to respect the freedom of others.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must pass on to the recipients the same
+freedoms that you received. You must make sure that they, too, receive
+or can get the source code. And you must show them these terms so they
+know their rights.
+
+ Developers that use the GNU GPL protect your rights with two steps:
+(1) assert copyright on the software, and (2) offer you this License
+giving you legal permission to copy, distribute and/or modify it.
+
+ For the developers' and authors' protection, the GPL clearly explains
+that there is no warranty for this free software. For both users' and
+authors' sake, the GPL requires that modified versions be marked as
+changed, so that their problems will not be attributed erroneously to
+authors of previous versions.
+
+ Some devices are designed to deny users access to install or run
+modified versions of the software inside them, although the manufacturer
+can do so. This is fundamentally incompatible with the aim of
+protecting users' freedom to change the software. The systematic
+pattern of such abuse occurs in the area of products for individuals to
+use, which is precisely where it is most unacceptable. Therefore, we
+have designed this version of the GPL to prohibit the practice for those
+products. If such problems arise substantially in other domains, we
+stand ready to extend this provision to those domains in future versions
+of the GPL, as needed to protect the freedom of users.
+
+ Finally, every program is threatened constantly by software patents.
+States should not allow patents to restrict development and use of
+software on general-purpose computers, but in those that do, we wish to
+avoid the special danger that patents applied to a free program could
+make it effectively proprietary. To prevent this, the GPL assures that
+patents cannot be used to render the program non-free.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ TERMS AND CONDITIONS
+
+ 0. Definitions.
+
+ "This License" refers to version 3 of the GNU General Public License.
+
+ "Copyright" also means copyright-like laws that apply to other kinds of
+works, such as semiconductor masks.
+
+ "The Program" refers to any copyrightable work licensed under this
+License. Each licensee is addressed as "you". "Licensees" and
+"recipients" may be individuals or organizations.
+
+ To "modify" a work means to copy from or adapt all or part of the work
+in a fashion requiring copyright permission, other than the making of an
+exact copy. The resulting work is called a "modified version" of the
+earlier work or a work "based on" the earlier work.
+
+ A "covered work" means either the unmodified Program or a work based
+on the Program.
+
+ To "propagate" a work means to do anything with it that, without
+permission, would make you directly or secondarily liable for
+infringement under applicable copyright law, except executing it on a
+computer or modifying a private copy. Propagation includes copying,
+distribution (with or without modification), making available to the
+public, and in some countries other activities as well.
+
+ To "convey" a work means any kind of propagation that enables other
+parties to make or receive copies. Mere interaction with a user through
+a computer network, with no transfer of a copy, is not conveying.
+
+ An interactive user interface displays "Appropriate Legal Notices"
+to the extent that it includes a convenient and prominently visible
+feature that (1) displays an appropriate copyright notice, and (2)
+tells the user that there is no warranty for the work (except to the
+extent that warranties are provided), that licensees may convey the
+work under this License, and how to view a copy of this License. If
+the interface presents a list of user commands or options, such as a
+menu, a prominent item in the list meets this criterion.
+
+ 1. Source Code.
+
+ The "source code" for a work means the preferred form of the work
+for making modifications to it. "Object code" means any non-source
+form of a work.
+
+ A "Standard Interface" means an interface that either is an official
+standard defined by a recognized standards body, or, in the case of
+interfaces specified for a particular programming language, one that
+is widely used among developers working in that language.
+
+ The "System Libraries" of an executable work include anything, other
+than the work as a whole, that (a) is included in the normal form of
+packaging a Major Component, but which is not part of that Major
+Component, and (b) serves only to enable use of the work with that
+Major Component, or to implement a Standard Interface for which an
+implementation is available to the public in source code form. A
+"Major Component", in this context, means a major essential component
+(kernel, window system, and so on) of the specific operating system
+(if any) on which the executable work runs, or a compiler used to
+produce the work, or an object code interpreter used to run it.
+
+ The "Corresponding Source" for a work in object code form means all
+the source code needed to generate, install, and (for an executable
+work) run the object code and to modify the work, including scripts to
+control those activities. However, it does not include the work's
+System Libraries, or general-purpose tools or generally available free
+programs which are used unmodified in performing those activities but
+which are not part of the work. For example, Corresponding Source
+includes interface definition files associated with source files for
+the work, and the source code for shared libraries and dynamically
+linked subprograms that the work is specifically designed to require,
+such as by intimate data communication or control flow between those
+subprograms and other parts of the work.
+
+ The Corresponding Source need not include anything that users
+can regenerate automatically from other parts of the Corresponding
+Source.
+
+ The Corresponding Source for a work in source code form is that
+same work.
+
+ 2. Basic Permissions.
+
+ All rights granted under this License are granted for the term of
+copyright on the Program, and are irrevocable provided the stated
+conditions are met. This License explicitly affirms your unlimited
+permission to run the unmodified Program. The output from running a
+covered work is covered by this License only if the output, given its
+content, constitutes a covered work. This License acknowledges your
+rights of fair use or other equivalent, as provided by copyright law.
+
+ You may make, run and propagate covered works that you do not
+convey, without conditions so long as your license otherwise remains
+in force. You may convey covered works to others for the sole purpose
+of having them make modifications exclusively for you, or provide you
+with facilities for running those works, provided that you comply with
+the terms of this License in conveying all material for which you do
+not control copyright. Those thus making or running the covered works
+for you must do so exclusively on your behalf, under your direction
+and control, on terms that prohibit them from making any copies of
+your copyrighted material outside their relationship with you.
+
+ Conveying under any other circumstances is permitted solely under
+the conditions stated below. Sublicensing is not allowed; section 10
+makes it unnecessary.
+
+ 3. Protecting Users' Legal Rights From Anti-Circumvention Law.
+
+ No covered work shall be deemed part of an effective technological
+measure under any applicable law fulfilling obligations under article
+11 of the WIPO copyright treaty adopted on 20 December 1996, or
+similar laws prohibiting or restricting circumvention of such
+measures.
+
+ When you convey a covered work, you waive any legal power to forbid
+circumvention of technological measures to the extent such circumvention
+is effected by exercising rights under this License with respect to
+the covered work, and you disclaim any intention to limit operation or
+modification of the work as a means of enforcing, against the work's
+users, your or third parties' legal rights to forbid circumvention of
+technological measures.
+
+ 4. Conveying Verbatim Copies.
+
+ You may convey verbatim copies of the Program's source code as you
+receive it, in any medium, provided that you conspicuously and
+appropriately publish on each copy an appropriate copyright notice;
+keep intact all notices stating that this License and any
+non-permissive terms added in accord with section 7 apply to the code;
+keep intact all notices of the absence of any warranty; and give all
+recipients a copy of this License along with the Program.
+
+ You may charge any price or no price for each copy that you convey,
+and you may offer support or warranty protection for a fee.
+
+ 5. Conveying Modified Source Versions.
+
+ You may convey a work based on the Program, or the modifications to
+produce it from the Program, in the form of source code under the
+terms of section 4, provided that you also meet all of these conditions:
+
+ a) The work must carry prominent notices stating that you modified
+ it, and giving a relevant date.
+
+ b) The work must carry prominent notices stating that it is
+ released under this License and any conditions added under section
+ 7. This requirement modifies the requirement in section 4 to
+ "keep intact all notices".
+
+ c) You must license the entire work, as a whole, under this
+ License to anyone who comes into possession of a copy. This
+ License will therefore apply, along with any applicable section 7
+ additional terms, to the whole of the work, and all its parts,
+ regardless of how they are packaged. This License gives no
+ permission to license the work in any other way, but it does not
+ invalidate such permission if you have separately received it.
+
+ d) If the work has interactive user interfaces, each must display
+ Appropriate Legal Notices; however, if the Program has interactive
+ interfaces that do not display Appropriate Legal Notices, your
+ work need not make them do so.
+
+ A compilation of a covered work with other separate and independent
+works, which are not by their nature extensions of the covered work,
+and which are not combined with it such as to form a larger program,
+in or on a volume of a storage or distribution medium, is called an
+"aggregate" if the compilation and its resulting copyright are not
+used to limit the access or legal rights of the compilation's users
+beyond what the individual works permit. Inclusion of a covered work
+in an aggregate does not cause this License to apply to the other
+parts of the aggregate.
+
+ 6. Conveying Non-Source Forms.
+
+ You may convey a covered work in object code form under the terms
+of sections 4 and 5, provided that you also convey the
+machine-readable Corresponding Source under the terms of this License,
+in one of these ways:
+
+ a) Convey the object code in, or embodied in, a physical product
+ (including a physical distribution medium), accompanied by the
+ Corresponding Source fixed on a durable physical medium
+ customarily used for software interchange.
+
+ b) Convey the object code in, or embodied in, a physical product
+ (including a physical distribution medium), accompanied by a
+ written offer, valid for at least three years and valid for as
+ long as you offer spare parts or customer support for that product
+ model, to give anyone who possesses the object code either (1) a
+ copy of the Corresponding Source for all the software in the
+ product that is covered by this License, on a durable physical
+ medium customarily used for software interchange, for a price no
+ more than your reasonable cost of physically performing this
+ conveying of source, or (2) access to copy the
+ Corresponding Source from a network server at no charge.
+
+ c) Convey individual copies of the object code with a copy of the
+ written offer to provide the Corresponding Source. This
+ alternative is allowed only occasionally and noncommercially, and
+ only if you received the object code with such an offer, in accord
+ with subsection 6b.
+
+ d) Convey the object code by offering access from a designated
+ place (gratis or for a charge), and offer equivalent access to the
+ Corresponding Source in the same way through the same place at no
+ further charge. You need not require recipients to copy the
+ Corresponding Source along with the object code. If the place to
+ copy the object code is a network server, the Corresponding Source
+ may be on a different server (operated by you or a third party)
+ that supports equivalent copying facilities, provided you maintain
+ clear directions next to the object code saying where to find the
+ Corresponding Source. Regardless of what server hosts the
+ Corresponding Source, you remain obligated to ensure that it is
+ available for as long as needed to satisfy these requirements.
+
+ e) Convey the object code using peer-to-peer transmission, provided
+ you inform other peers where the object code and Corresponding
+ Source of the work are being offered to the general public at no
+ charge under subsection 6d.
+
+ A separable portion of the object code, whose source code is excluded
+from the Corresponding Source as a System Library, need not be
+included in conveying the object code work.
+
+ A "User Product" is either (1) a "consumer product", which means any
+tangible personal property which is normally used for personal, family,
+or household purposes, or (2) anything designed or sold for incorporation
+into a dwelling. In determining whether a product is a consumer product,
+doubtful cases shall be resolved in favor of coverage. For a particular
+product received by a particular user, "normally used" refers to a
+typical or common use of that class of product, regardless of the status
+of the particular user or of the way in which the particular user
+actually uses, or expects or is expected to use, the product. A product
+is a consumer product regardless of whether the product has substantial
+commercial, industrial or non-consumer uses, unless such uses represent
+the only significant mode of use of the product.
+
+ "Installation Information" for a User Product means any methods,
+procedures, authorization keys, or other information required to install
+and execute modified versions of a covered work in that User Product from
+a modified version of its Corresponding Source. The information must
+suffice to ensure that the continued functioning of the modified object
+code is in no case prevented or interfered with solely because
+modification has been made.
+
+ If you convey an object code work under this section in, or with, or
+specifically for use in, a User Product, and the conveying occurs as
+part of a transaction in which the right of possession and use of the
+User Product is transferred to the recipient in perpetuity or for a
+fixed term (regardless of how the transaction is characterized), the
+Corresponding Source conveyed under this section must be accompanied
+by the Installation Information. But this requirement does not apply
+if neither you nor any third party retains the ability to install
+modified object code on the User Product (for example, the work has
+been installed in ROM).
+
+ The requirement to provide Installation Information does not include a
+requirement to continue to provide support service, warranty, or updates
+for a work that has been modified or installed by the recipient, or for
+the User Product in which it has been modified or installed. Access to a
+network may be denied when the modification itself materially and
+adversely affects the operation of the network or violates the rules and
+protocols for communication across the network.
+
+ Corresponding Source conveyed, and Installation Information provided,
+in accord with this section must be in a format that is publicly
+documented (and with an implementation available to the public in
+source code form), and must require no special password or key for
+unpacking, reading or copying.
+
+ 7. Additional Terms.
+
+ "Additional permissions" are terms that supplement the terms of this
+License by making exceptions from one or more of its conditions.
+Additional permissions that are applicable to the entire Program shall
+be treated as though they were included in this License, to the extent
+that they are valid under applicable law. If additional permissions
+apply only to part of the Program, that part may be used separately
+under those permissions, but the entire Program remains governed by
+this License without regard to the additional permissions.
+
+ When you convey a copy of a covered work, you may at your option
+remove any additional permissions from that copy, or from any part of
+it. (Additional permissions may be written to require their own
+removal in certain cases when you modify the work.) You may place
+additional permissions on material, added by you to a covered work,
+for which you have or can give appropriate copyright permission.
+
+ Notwithstanding any other provision of this License, for material you
+add to a covered work, you may (if authorized by the copyright holders of
+that material) supplement the terms of this License with terms:
+
+ a) Disclaiming warranty or limiting liability differently from the
+ terms of sections 15 and 16 of this License; or
+
+ b) Requiring preservation of specified reasonable legal notices or
+ author attributions in that material or in the Appropriate Legal
+ Notices displayed by works containing it; or
+
+ c) Prohibiting misrepresentation of the origin of that material, or
+ requiring that modified versions of such material be marked in
+ reasonable ways as different from the original version; or
+
+ d) Limiting the use for publicity purposes of names of licensors or
+ authors of the material; or
+
+ e) Declining to grant rights under trademark law for use of some
+ trade names, trademarks, or service marks; or
+
+ f) Requiring indemnification of licensors and authors of that
+ material by anyone who conveys the material (or modified versions of
+ it) with contractual assumptions of liability to the recipient, for
+ any liability that these contractual assumptions directly impose on
+ those licensors and authors.
+
+ All other non-permissive additional terms are considered "further
+restrictions" within the meaning of section 10. If the Program as you
+received it, or any part of it, contains a notice stating that it is
+governed by this License along with a term that is a further
+restriction, you may remove that term. If a license document contains
+a further restriction but permits relicensing or conveying under this
+License, you may add to a covered work material governed by the terms
+of that license document, provided that the further restriction does
+not survive such relicensing or conveying.
+
+ If you add terms to a covered work in accord with this section, you
+must place, in the relevant source files, a statement of the
+additional terms that apply to those files, or a notice indicating
+where to find the applicable terms.
+
+ Additional terms, permissive or non-permissive, may be stated in the
+form of a separately written license, or stated as exceptions;
+the above requirements apply either way.
+
+ 8. Termination.
+
+ You may not propagate or modify a covered work except as expressly
+provided under this License. Any attempt otherwise to propagate or
+modify it is void, and will automatically terminate your rights under
+this License (including any patent licenses granted under the third
+paragraph of section 11).
+
+ However, if you cease all violation of this License, then your
+license from a particular copyright holder is reinstated (a)
+provisionally, unless and until the copyright holder explicitly and
+finally terminates your license, and (b) permanently, if the copyright
+holder fails to notify you of the violation by some reasonable means
+prior to 60 days after the cessation.
+
+ Moreover, your license from a particular copyright holder is
+reinstated permanently if the copyright holder notifies you of the
+violation by some reasonable means, this is the first time you have
+received notice of violation of this License (for any work) from that
+copyright holder, and you cure the violation prior to 30 days after
+your receipt of the notice.
+
+ Termination of your rights under this section does not terminate the
+licenses of parties who have received copies or rights from you under
+this License. If your rights have been terminated and not permanently
+reinstated, you do not qualify to receive new licenses for the same
+material under section 10.
+
+ 9. Acceptance Not Required for Having Copies.
+
+ You are not required to accept this License in order to receive or
+run a copy of the Program. Ancillary propagation of a covered work
+occurring solely as a consequence of using peer-to-peer transmission
+to receive a copy likewise does not require acceptance. However,
+nothing other than this License grants you permission to propagate or
+modify any covered work. These actions infringe copyright if you do
+not accept this License. Therefore, by modifying or propagating a
+covered work, you indicate your acceptance of this License to do so.
+
+ 10. Automatic Licensing of Downstream Recipients.
+
+ Each time you convey a covered work, the recipient automatically
+receives a license from the original licensors, to run, modify and
+propagate that work, subject to this License. You are not responsible
+for enforcing compliance by third parties with this License.
+
+ An "entity transaction" is a transaction transferring control of an
+organization, or substantially all assets of one, or subdividing an
+organization, or merging organizations. If propagation of a covered
+work results from an entity transaction, each party to that
+transaction who receives a copy of the work also receives whatever
+licenses to the work the party's predecessor in interest had or could
+give under the previous paragraph, plus a right to possession of the
+Corresponding Source of the work from the predecessor in interest, if
+the predecessor has it or can get it with reasonable efforts.
+
+ You may not impose any further restrictions on the exercise of the
+rights granted or affirmed under this License. For example, you may
+not impose a license fee, royalty, or other charge for exercise of
+rights granted under this License, and you may not initiate litigation
+(including a cross-claim or counterclaim in a lawsuit) alleging that
+any patent claim is infringed by making, using, selling, offering for
+sale, or importing the Program or any portion of it.
+
+ 11. Patents.
+
+ A "contributor" is a copyright holder who authorizes use under this
+License of the Program or a work on which the Program is based. The
+work thus licensed is called the contributor's "contributor version".
+
+ A contributor's "essential patent claims" are all patent claims
+owned or controlled by the contributor, whether already acquired or
+hereafter acquired, that would be infringed by some manner, permitted
+by this License, of making, using, or selling its contributor version,
+but do not include claims that would be infringed only as a
+consequence of further modification of the contributor version. For
+purposes of this definition, "control" includes the right to grant
+patent sublicenses in a manner consistent with the requirements of
+this License.
+
+ Each contributor grants you a non-exclusive, worldwide, royalty-free
+patent license under the contributor's essential patent claims, to
+make, use, sell, offer for sale, import and otherwise run, modify and
+propagate the contents of its contributor version.
+
+ In the following three paragraphs, a "patent license" is any express
+agreement or commitment, however denominated, not to enforce a patent
+(such as an express permission to practice a patent or covenant not to
+sue for patent infringement). To "grant" such a patent license to a
+party means to make such an agreement or commitment not to enforce a
+patent against the party.
+
+ If you convey a covered work, knowingly relying on a patent license,
+and the Corresponding Source of the work is not available for anyone
+to copy, free of charge and under the terms of this License, through a
+publicly available network server or other readily accessible means,
+then you must either (1) cause the Corresponding Source to be so
+available, or (2) arrange to deprive yourself of the benefit of the
+patent license for this particular work, or (3) arrange, in a manner
+consistent with the requirements of this License, to extend the patent
+license to downstream recipients. "Knowingly relying" means you have
+actual knowledge that, but for the patent license, your conveying the
+covered work in a country, or your recipient's use of the covered work
+in a country, would infringe one or more identifiable patents in that
+country that you have reason to believe are valid.
+
+ If, pursuant to or in connection with a single transaction or
+arrangement, you convey, or propagate by procuring conveyance of, a
+covered work, and grant a patent license to some of the parties
+receiving the covered work authorizing them to use, propagate, modify
+or convey a specific copy of the covered work, then the patent license
+you grant is automatically extended to all recipients of the covered
+work and works based on it.
+
+ A patent license is "discriminatory" if it does not include within
+the scope of its coverage, prohibits the exercise of, or is
+conditioned on the non-exercise of one or more of the rights that are
+specifically granted under this License. You may not convey a covered
+work if you are a party to an arrangement with a third party that is
+in the business of distributing software, under which you make payment
+to the third party based on the extent of your activity of conveying
+the work, and under which the third party grants, to any of the
+parties who would receive the covered work from you, a discriminatory
+patent license (a) in connection with copies of the covered work
+conveyed by you (or copies made from those copies), or (b) primarily
+for and in connection with specific products or compilations that
+contain the covered work, unless you entered into that arrangement,
+or that patent license was granted, prior to 28 March 2007.
+
+ Nothing in this License shall be construed as excluding or limiting
+any implied license or other defenses to infringement that may
+otherwise be available to you under applicable patent law.
+
+ 12. No Surrender of Others' Freedom.
+
+ If conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot convey a
+covered work so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you may
+not convey it at all. For example, if you agree to terms that obligate you
+to collect a royalty for further conveying from those to whom you convey
+the Program, the only way you could satisfy both those terms and this
+License would be to refrain entirely from conveying the Program.
+
+ 13. Use with the GNU Affero General Public License.
+
+ Notwithstanding any other provision of this License, you have
+permission to link or combine any covered work with a work licensed
+under version 3 of the GNU Affero General Public License into a single
+combined work, and to convey the resulting work. The terms of this
+License will continue to apply to the part which is the covered work,
+but the special requirements of the GNU Affero General Public License,
+section 13, concerning interaction through a network will apply to the
+combination as such.
+
+ 14. Revised Versions of this License.
+
+ The Free Software Foundation may publish revised and/or new versions of
+the GNU General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+ Each version is given a distinguishing version number. If the
+Program specifies that a certain numbered version of the GNU General
+Public License "or any later version" applies to it, you have the
+option of following the terms and conditions either of that numbered
+version or of any later version published by the Free Software
+Foundation. If the Program does not specify a version number of the
+GNU General Public License, you may choose any version ever published
+by the Free Software Foundation.
+
+ If the Program specifies that a proxy can decide which future
+versions of the GNU General Public License can be used, that proxy's
+public statement of acceptance of a version permanently authorizes you
+to choose that version for the Program.
+
+ Later license versions may give you additional or different
+permissions. However, no additional obligations are imposed on any
+author or copyright holder as a result of your choosing to follow a
+later version.
+
+ 15. Disclaimer of Warranty.
+
+ THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
+APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
+HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
+OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
+THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
+IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
+ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+ 16. Limitation of Liability.
+
+ IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
+THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
+GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
+USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
+DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
+PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
+EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGES.
+
+ 17. Interpretation of Sections 15 and 16.
+
+ If the disclaimer of warranty and limitation of liability provided
+above cannot be given local legal effect according to their terms,
+reviewing courts shall apply local law that most closely approximates
+an absolute waiver of all civil liability in connection with the
+Program, unless a warranty or assumption of liability accompanies a
+copy of the Program in return for a fee.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Programs
+
+ If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+ To do so, attach the following notices to the program. It is safest
+to attach them to the start of each source file to most effectively
+state the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+ <one line to give the program's name and a brief idea of what it does.>
+ Copyright (C) <year> <name of author>
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program 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 General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+Also add information on how to contact you by electronic and paper mail.
+
+ If the program does terminal interaction, make it output a short
+notice like this when it starts in an interactive mode:
+
+ <program> Copyright (C) <year> <name of author>
+ This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+ This is free software, and you are welcome to redistribute it
+ under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License. Of course, your program's commands
+might be different; for a GUI interface, you would use an "about box".
+
+ You should also get your employer (if you work as a programmer) or school,
+if any, to sign a "copyright disclaimer" for the program, if necessary.
+For more information on this, and how to apply and follow the GNU GPL, see
+<http://www.gnu.org/licenses/>.
+
+ The GNU General Public License does not permit incorporating your program
+into proprietary programs. If your program is a subroutine library, you
+may consider it more useful to permit linking proprietary applications with
+the library. If this is what you want to do, use the GNU Lesser General
+Public License instead of this License. But first, please read
+<http://www.gnu.org/philosophy/why-not-lgpl.html>.
diff --git a/Build/source/utils/asymptote/LICENSE.LESSER b/Build/source/utils/asymptote/LICENSE.LESSER
new file mode 100644
index 00000000000..fc8a5de7edf
--- /dev/null
+++ b/Build/source/utils/asymptote/LICENSE.LESSER
@@ -0,0 +1,165 @@
+ GNU LESSER GENERAL PUBLIC LICENSE
+ Version 3, 29 June 2007
+
+ Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+
+ This version of the GNU Lesser General Public License incorporates
+the terms and conditions of version 3 of the GNU General Public
+License, supplemented by the additional permissions listed below.
+
+ 0. Additional Definitions.
+
+ As used herein, "this License" refers to version 3 of the GNU Lesser
+General Public License, and the "GNU GPL" refers to version 3 of the GNU
+General Public License.
+
+ "The Library" refers to a covered work governed by this License,
+other than an Application or a Combined Work as defined below.
+
+ An "Application" is any work that makes use of an interface provided
+by the Library, but which is not otherwise based on the Library.
+Defining a subclass of a class defined by the Library is deemed a mode
+of using an interface provided by the Library.
+
+ A "Combined Work" is a work produced by combining or linking an
+Application with the Library. The particular version of the Library
+with which the Combined Work was made is also called the "Linked
+Version".
+
+ The "Minimal Corresponding Source" for a Combined Work means the
+Corresponding Source for the Combined Work, excluding any source code
+for portions of the Combined Work that, considered in isolation, are
+based on the Application, and not on the Linked Version.
+
+ The "Corresponding Application Code" for a Combined Work means the
+object code and/or source code for the Application, including any data
+and utility programs needed for reproducing the Combined Work from the
+Application, but excluding the System Libraries of the Combined Work.
+
+ 1. Exception to Section 3 of the GNU GPL.
+
+ You may convey a covered work under sections 3 and 4 of this License
+without being bound by section 3 of the GNU GPL.
+
+ 2. Conveying Modified Versions.
+
+ If you modify a copy of the Library, and, in your modifications, a
+facility refers to a function or data to be supplied by an Application
+that uses the facility (other than as an argument passed when the
+facility is invoked), then you may convey a copy of the modified
+version:
+
+ a) under this License, provided that you make a good faith effort to
+ ensure that, in the event an Application does not supply the
+ function or data, the facility still operates, and performs
+ whatever part of its purpose remains meaningful, or
+
+ b) under the GNU GPL, with none of the additional permissions of
+ this License applicable to that copy.
+
+ 3. Object Code Incorporating Material from Library Header Files.
+
+ The object code form of an Application may incorporate material from
+a header file that is part of the Library. You may convey such object
+code under terms of your choice, provided that, if the incorporated
+material is not limited to numerical parameters, data structure
+layouts and accessors, or small macros, inline functions and templates
+(ten or fewer lines in length), you do both of the following:
+
+ a) Give prominent notice with each copy of the object code that the
+ Library is used in it and that the Library and its use are
+ covered by this License.
+
+ b) Accompany the object code with a copy of the GNU GPL and this license
+ document.
+
+ 4. Combined Works.
+
+ You may convey a Combined Work under terms of your choice that,
+taken together, effectively do not restrict modification of the
+portions of the Library contained in the Combined Work and reverse
+engineering for debugging such modifications, if you also do each of
+the following:
+
+ a) Give prominent notice with each copy of the Combined Work that
+ the Library is used in it and that the Library and its use are
+ covered by this License.
+
+ b) Accompany the Combined Work with a copy of the GNU GPL and this license
+ document.
+
+ c) For a Combined Work that displays copyright notices during
+ execution, include the copyright notice for the Library among
+ these notices, as well as a reference directing the user to the
+ copies of the GNU GPL and this license document.
+
+ d) Do one of the following:
+
+ 0) Convey the Minimal Corresponding Source under the terms of this
+ License, and the Corresponding Application Code in a form
+ suitable for, and under terms that permit, the user to
+ recombine or relink the Application with a modified version of
+ the Linked Version to produce a modified Combined Work, in the
+ manner specified by section 6 of the GNU GPL for conveying
+ Corresponding Source.
+
+ 1) Use a suitable shared library mechanism for linking with the
+ Library. A suitable mechanism is one that (a) uses at run time
+ a copy of the Library already present on the user's computer
+ system, and (b) will operate properly with a modified version
+ of the Library that is interface-compatible with the Linked
+ Version.
+
+ e) Provide Installation Information, but only if you would otherwise
+ be required to provide such information under section 6 of the
+ GNU GPL, and only to the extent that such information is
+ necessary to install and execute a modified version of the
+ Combined Work produced by recombining or relinking the
+ Application with a modified version of the Linked Version. (If
+ you use option 4d0, the Installation Information must accompany
+ the Minimal Corresponding Source and Corresponding Application
+ Code. If you use option 4d1, you must provide the Installation
+ Information in the manner specified by section 6 of the GNU GPL
+ for conveying Corresponding Source.)
+
+ 5. Combined Libraries.
+
+ You may place library facilities that are a work based on the
+Library side by side in a single library together with other library
+facilities that are not Applications and are not covered by this
+License, and convey such a combined library under terms of your
+choice, if you do both of the following:
+
+ a) Accompany the combined library with a copy of the same work based
+ on the Library, uncombined with any other library facilities,
+ conveyed under the terms of this License.
+
+ b) Give prominent notice with the combined library that part of it
+ is a work based on the Library, and explaining where to find the
+ accompanying uncombined form of the same work.
+
+ 6. Revised Versions of the GNU Lesser General Public License.
+
+ The Free Software Foundation may publish revised and/or new versions
+of the GNU Lesser General Public License from time to time. Such new
+versions will be similar in spirit to the present version, but may
+differ in detail to address new problems or concerns.
+
+ Each version is given a distinguishing version number. If the
+Library as you received it specifies that a certain numbered version
+of the GNU Lesser General Public License "or any later version"
+applies to it, you have the option of following the terms and
+conditions either of that published version or of any later version
+published by the Free Software Foundation. If the Library as you
+received it does not specify a version number of the GNU Lesser
+General Public License, you may choose any version of the GNU Lesser
+General Public License ever published by the Free Software Foundation.
+
+ If the Library as you received it specifies that a proxy can decide
+whether future versions of the GNU Lesser General Public License shall
+apply, that proxy's public statement of acceptance of any version is
+permanent authorization for you to choose that version for the
+Library.
diff --git a/Build/source/utils/asymptote/Makefile.in b/Build/source/utils/asymptote/Makefile.in
new file mode 100644
index 00000000000..91613c1ff75
--- /dev/null
+++ b/Build/source/utils/asymptote/Makefile.in
@@ -0,0 +1,258 @@
+# @configure_input@
+
+ARCH = unix
+POLL = poll
+
+GC = @GCDIR@
+GCOPTIONS = @GCOPTIONS@
+GCLIB = @GCLIB@
+GCPPLIB = @GCPPLIB@
+GCLIBS = $(GCPPLIB) $(GCLIB)
+LFLAGS = @LDFLAGS@
+LIBS = $(LFLAGS) @LIBS@ $(GCLIBS)
+
+CAMP = camperror path drawpath drawlabel picture psfile texfile util settings \
+ guide flatguide knot drawfill path3 drawpath3 drawsurface
+
+PRC = prc/PRCbitStream prc/oPRCFile prc/PRCdouble prc/writePRC
+
+FILES = $(CAMP) runtime env genv main stm dec errormsg \
+ callable name symbol types entry exp newexp stack camp.tab lex.yy \
+ access absyn record interact fileio builtin fftw++ simpson coder coenv \
+ @getopt@ locate parser program application varinit fundec refaccess \
+ envcompleter process constructor array Delaunay predicates \
+ $(PRC) glrender tr arcball algebra3 quaternion svnrevision
+
+DIST = camp.tab.h camp.tab.cc lex.yy.cc runtime.h runtime.cc keywords.cc \
+ asy-keywords.el base/asy-keywords.el
+NAME = asy
+XNAME = x$(NAME)
+CLEAN = camp.output asy.list svnrevision.cc doc/version.texi GUI/xasyVersion.py $(XNAME)
+EXTRA = asy-mode.el asy-keywords.el asy-init.el asy.vim asymptote.py reload.js nopapersize.ps
+EXEXTRA = piicon.eps *.views *.dat
+DOCEXTRA = *.asy *.csv *.dat latexusage.tex externalprc.tex pixel.pdf
+KEYWORDS = base $(ASYMPTOTE_SITEDIR)
+LATEXFILES = asymptote.sty asycolors.sty
+ASY = ./asy -dir base -config "" -render=0
+
+DEFS = @DEFS@ @OPTIONS@
+CFLAGS = @CPPFLAGS@ @CFLAGS@
+OPTS = $(DEFS) $(CFLAGS)
+INCL = -I . @INCL@
+
+CXX = @CXX@ -Wall -ansi
+CC = @CC@ -Wall -ansi
+MAKEDEPEND = $(OPTS) -O0 -M -DDEPEND
+BISON = bison
+LEX = @LEX@
+
+prefix = @prefix@
+exec_prefix = @exec_prefix@
+datarootdir = @datarootdir@
+bindir = $(DESTDIR)@bindir@
+mandir = $(DESTDIR)@mandir@
+infodir = $(DESTDIR)@infodir@
+datadir = $(DESTDIR)@datadir@
+asydir = $(datadir)/asymptote
+GUIdir = $(asydir)/GUI
+docdir = $(DESTDIR)@docdir@
+exampledir = $(docdir)/examples
+animationsdir = $(exampledir)/animations
+latexdir = $(DESTDIR)@latexdir@
+INSTALL = @INSTALL@
+REVISION = "const char *SVN_REVISION="
+revision = `svn info 2>/dev/null | grep "Revision" | sed -e "s/Revision: \(.*\)/-r\1/"`
+last = `cat svnrevision.cc | sed -e 's/.*\"\(.*\)\";/\\1/'`
+
+export prefix docdir exampledir mandir infodir INSTALL MAKE DESTDIR TEXI2DVI
+
+asy: $(GCLIB) $(FILES:=.o) prc
+ if test "$(revision)" != "$(last)"; then \
+ echo $(REVISION)\"$(revision)\"\; > svnrevision.cc; \
+ $(CXX) $(OPTS) $(INCL) -o svnrevision.o -c svnrevision.cc; \
+ fi
+ echo string VERSION=\"@VERSION@$(revision)\"\; > base/version.asy
+ echo @set VERSION @VERSION@$(revision) > doc/version.texi
+ echo @set Datadir @datadir@ >> doc/version.texi
+ echo "#!/usr/bin/env python" > GUI/xasyVersion.py
+ echo xasyVersion = \"@VERSION@$(revision)\" >> GUI/xasyVersion.py
+ ln -sf GUI/xasy.py $(XNAME)
+ $(CXX) $(OPTS) -o $(NAME) $(FILES:=.o) $(LIBS)
+
+svnrevision.cc:
+ echo $(REVISION)\"\"\; > svnrevision.cc;
+
+msdos: $(GCLIB) $(FILES:=.o) prc asy.o
+ echo string VERSION=\"@VERSION@\"\; > base/version.asy
+ echo @set VERSION @VERSION@ > doc/version.texi
+ echo @set Datadir @datadir@ >> doc/version.texi
+ echo "#!/usr/bin/env python" > GUI/xasyVersion.py
+ echo xasyVersion = \"@VERSION@\" >> GUI/xasyVersion.py
+ $(CXX) $(OPTS) -o $(NAME) $(FILES:=.o) asy.o $(LIBS) -s -static
+
+asy.o: asy.rc asy.ico Makefile
+ cat asy.rc | sed -e "s/ASYMPTOTE_VERSION/@VERSION@$(revision)/" | \
+ windres -o asy.o
+
+all: asy man faq asy-keywords.el
+
+$(GCLIB): $(GC).tar.gz
+ gunzip -c $(GC).tar.gz > $(GC).tar
+ tar -xf $(GC).tar
+ rm -f $(GC).tar
+ if test "$(GC)" = "gc6.8"; then \
+ cd $(GC)/include; patch < ../../patches/gc6.8_AIX.patch; \
+ fi
+ if test "$(GC)" = "gc-7.0"; then \
+ cd $(GC)/include/private; patch < ../../../patches/gc-7.0nomem.patch;\
+ fi
+ cd $(GC); \
+ ./configure $(GCOPTIONS); \
+ $(MAKE) check
+
+$(GCPPLIB): $(GCLIB)
+
+html: asy
+ cd doc; $(MAKE) doc
+
+man: asy
+ cd doc; $(MAKE) man
+
+faq: asy
+ cd doc; $(MAKE) faq
+
+runtime.cc: runtime.pl runtime.in
+ ./runtime.pl
+
+camp.tab.cc: camp.y
+ $(BISON) -dvt -b camp camp.y && mv camp.tab.c camp.tab.cc
+
+camp.tab.h: camp.tab.cc
+
+lex.yy.cc: camp.l
+ $(LEX) -d -olex.yy.cc camp.l
+
+lex.yy.d: $(GCLIB) lex.yy.cc camp.tab.h
+
+keywords.cc: keywords.pl camp.l
+ ./keywords.pl
+
+envcompleter.d: keywords.cc
+
+asy.list: asy
+ $(ASY) -l > asy.list
+ ls $(addsuffix /*.asy,$(KEYWORDS)) | grep -v plain\* | grep -v three_\* | grep -v featpost3D | xargs $(ASY) -l >> asy.list
+ ./asy-list.pl asy.list @VERSION@
+
+asy-keywords.el: asy.list
+ ln -sf ../asy-keywords.el base/
+
+install: asy-keywords.el install-asy install-man
+
+install-all: asy-keywords.el install-asy install-doc
+
+install-asy: asy
+ ${INSTALL} -d $(bindir) $(asydir) $(GUIdir) $(exampledir) \
+ $(animationsdir)
+ -${INSTALL} -d $(latexdir)
+ ${INSTALL} -p -m 755 $(NAME) $(bindir)
+ ${INSTALL} -p -m 644 base/*.asy $(addprefix base/,$(EXTRA)) $(asydir)
+ ${INSTALL} -p -m 755 GUI/*.py $(GUIdir)
+ ln -sf @datadir@/asymptote/GUI/xasy.py $(bindir)/$(XNAME)
+ ${INSTALL} -p -m 644 examples/*.asy $(addprefix examples/,$(EXEXTRA)) \
+ doc/extra/*.asy $(addprefix doc/,$(DOCEXTRA)) $(exampledir)
+ ${INSTALL} -p -m 644 examples/animations/*.asy \
+ examples/animations/inlinemovie.tex \
+ examples/animations/inlinemovie3.tex $(animationsdir)
+ -${INSTALL} -p -m 644 $(addprefix doc/,$(LATEXFILES)) $(latexdir)
+ -if test -z "$(DESTDIR)"; then \
+ texhash; \
+ fi
+
+install-doc: html
+ cd doc; $(MAKE) install-all
+
+install-man: man
+ cd doc; $(MAKE) install
+
+uninstall: uninstall-all
+
+uninstall-all: uninstall-man uninstall-asy
+
+uninstall-asy:
+ -cd $(animationsdir); rm -f *.asy *.tex
+ -rmdir $(animationsdir)
+ -cd $(exampledir); rm -f $(EXEXTRA) $(DOCEXTRA)
+ -rmdir $(exampledir)
+ -rmdir $(docdir)
+ -cd $(GUIdir); rm -f *.py
+ -rmdir $(GUIdir)
+ -cd $(asydir); rm -f *.asy $(EXTRA)
+ -rmdir $(asydir)
+ -cd $(latexdir); rm -f $(LATEXFILES)
+ -rmdir $(latexdir)
+ -cd $(bindir); rm -f $(NAME) $(XNAME)
+
+uninstall-man:
+ cd doc; $(MAKE) uninstall
+
+prc-clean: FORCE
+ -rm -f prc/*.o prc/*.d
+
+clean: FORCE prc-clean
+ -rm -f asy *.o *.d *mon.out $(CLEAN)
+
+gc-clean: FORCE clean
+ -if test -d $(GC); then \
+ $(MAKE) -C $(GC) clean; \
+ fi
+
+cleaner: FORCE distclean
+distclean: FORCE clean
+ -if test -d $(GC); then \
+ rm -rf $(GC); \
+ fi
+ -rm -f Makefile config.h config.log config.status errors.temp
+ cd doc; $(MAKE) distclean
+ cd tests; $(MAKE) distclean
+
+cleanest: FORCE maintainer-clean
+maintainer-clean: FORCE distclean
+ -rm -f configure config.h.in $(DIST)
+ -rm -rf autom4te.cache
+
+check: asy FORCE
+ ./wce
+ $(MAKE) -C tests
+
+.SUFFIXES: .c .cc .o .d
+.cc.o:
+ $(CXX) $(OPTS) $(INCL) -o $@ -c $<
+.cc.d:
+ @echo Creating $@; \
+ rm -f $@; \
+ ${CXX} $(MAKEDEPEND) $(INCL) $(MDOPTS) $< > $@.$$$$ 2>/dev/null && \
+ sed 's,\($*\)\.o[ :]*,\1.o $@ : ,g' < $@.$$$$ > $@; \
+ rm -f $@.$$$$
+.c.d:
+ @echo Creating $@; \
+ rm -f $@; \
+ ${CC} $(MAKEDEPEND) $(INCL) $(MDOPTS) $< > $@.$$$$ 2>/dev/null && \
+ sed 's,\($*\)\.o[ :]*,\1.o $@ : ,g' < $@.$$$$ > $@; \
+ rm -f $@.$$$$
+
+ifeq (,$(findstring clean,${MAKECMDGOALS}))
+-include $(FILES:=.d)
+endif
+
+FORCE:
+
+configure: configure.ac
+ autoheader && autoconf
+
+Makefile: Makefile.in config.status
+ ./config.status
+
+config.status: configure
+ ./config.status --recheck
+
diff --git a/Build/source/utils/asymptote/README b/Build/source/utils/asymptote/README
new file mode 100644
index 00000000000..1dd3e3e3785
--- /dev/null
+++ b/Build/source/utils/asymptote/README
@@ -0,0 +1,41 @@
+ ASYMPTOTE
+ Copyright 2004-9 Andy Hammerlindl, John Bowman, and Tom Prince
+
+Asymptote is a powerful descriptive vector graphics language for technical
+drawings, inspired by MetaPost but with an improved C++-like
+syntax. Asymptote provides for figures the same high-quality level of
+typesetting that LaTeX does for scientific text.
+
+Installation instructions, documentation, binaries, and source code are
+available at:
+
+http://asymptote.sourceforge.net
+
+Bugs/Patches/Feature Requests can be submitted using the
+Bug/Patch/Feature Tracking Systems at
+http://sourceforge.net/projects/asymptote/.
+
+Questions and comments should be sent to the Asymptote Forum:
+
+http://sourceforge.net/forum/forum.php?forum_id=409349
+
+All files in the Asymptote project, unless explicitly noted otherwise,
+are released under version 3 (or later) of the GNU Lesser General Public
+License (see the files LICENSE.LESSER and LICENSE in the top-level source
+directory).
+
+This program 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 3 of the License, or
+(at your option) any later version.
+
+This program 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 program; if not, write to the Free Software
+Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+
diff --git a/Build/source/utils/asymptote/ReleaseNotes b/Build/source/utils/asymptote/ReleaseNotes
new file mode 100644
index 00000000000..a4cf39ffa94
--- /dev/null
+++ b/Build/source/utils/asymptote/ReleaseNotes
@@ -0,0 +1,1350 @@
+Release Notes for Version 1.72
+
+PostScript calculator function shading was implemented. Interactive camera
+parameters of the native OpenGL renderer can now be queried.
+The effective camera positions for oblique projections was fixed.
+Philippe Ivaldi's geometry_dev module was merged into geometry.asy;
+trembling_pi was added as trembling.asy. The GSL module was expanded.
+An extrude routine for labels was implemented. Rotated path
+label alignments were fixed. The alignment of 3D axis labels was fixed.
+The basealign pen now always typesets "ace" and "acg" at the same location.
+Arrow endpoint detection was fixed. A sysdir setting was added, along
+with an --enable-tetex-build configure option. The store argument of
+saveline is respected again. Left-justified trailingzero alignment was
+fixed; a signedtrailingzero specifier was added. Boolean conditions on
+linearly interpolated surfaces now suppress function evaluation.
+The adaptive algorithm used for rendering thick lines and tubes was
+improved. An ambiguity in the flowchart module was fixed.
+A patch is included to work around an MSWindows XP problem with 3Dgetview
+in the 2009/03/23 version of movie15.sty. A problem with spurious menu
+interaction zooming was fixed. The asy.bat MSWindows batch file now
+respects all command-line arguments.
+
+Release Notes for Version 1.70
+
+A labelpath3 module for typesetting curved labels in 3D, contributed by Jens
+Schwaiger, was added. PenMargin2 was defined for use with planar arrowhead
+types like DefaultHead2. A center=false parameter was added to projections
+to allow one to automatically center the target within the bounding volume.
+The ambiguity in the surface function was resolved. Problems with spaces in
+filenames were fixed.
+
+Release Notes for Version 1.69
+
+Internal patch degeneracies were removed by splitting. Bugs in the
+windingnumber and the intersection routines were fixed. The inside(path)
+routine was improved; a fillrule argument was added. The bezulate connect
+routine was improved. Bezulate is now automatically applied to path arrays:
+surfaces should be constructed directly, without first calling bezulate.
+A workaround for recent changes in the hyperref package was implemented.
+The divisor setting was replaced with purge(divisor=0). The calls to baseline
+in graph.asy were fixed. A miterlimit attribute was added to pens.
+Animation problems were fixed. Lighting problems with multiple exports and
+a quit deadlock were fixed. A new version of asymptote.sty (1.06) fixes
+an undefined \ASYbox.
+
+Release Notes for Version 1.68
+
+Support for 3D inline pdf movies was added. Camera adjustment was fixed;
+the filesurface.asy example illustrates automated camera and target
+computation. A deadlock in the export loop was fixed. A new version of
+asymptote.sty (1.05) fixes the definition of \ASYanimategraphics.
+The handling of intersection fuzz was improved. The baseline routine was
+generalized. New paragraphs are now allowed in minipage labels.
+Some minor errors in the documentation were fixed.
+
+Release Notes for Version 1.67
+
+Spurious annotation question marks in 3D PDF attachments were fixed;
+attached images are now printable. The asy environment defined in the new
+(1.04) version of asymptote.sty supports keyval options width, height,
+viewportwidth, viewportheight, and attach; the obsolete asyattach
+environment was removed. The default viewportwidth is the linewidth in
+inline mode and 0 in attached mode. Planar projected arrows were fixed.
+Automatic camera adjustment was improved. A minimum viewportsize can now be
+specified. The control points for cyclic segments produced by texpath were
+fixed. Overlap issues in planar surface patches were fixed. Surface
+constructors were simplified: the routine planar has been replaced by
+surface(path3) and in most cases there is no need to call bezulate directly.
+An Align constant was added. The parameter limits used in buildcycle were
+fixed. The intersection routines now respect the fuzz parameter.
+Segmentation faults involving null cyclic guides were fixed.
+Subpath now preserves the straight flag. Pictures containing graphs
+now transform correctly; unextended axes limits and tick selection were
+improved. Axial and radial shading respect now respect -gray. The animation
+prefix was fixed. An example of drawing a surface from irregular data was
+added. A work around was implemented for an intermittent hang on exit in
+the 3D native renderer. An auto3D option was added for controlling the
+poster option. The 2008/10/08 version of movie15.sty is now compulsory.
+The cd %USERPROFILE% command was removed from asy.bat.
+
+Release Notes for Version 1.66
+
+An alignment problem with the pdflatex tex engine was fixed.
+Problems in the animations module were fixed, including a broken
+ImageMagick layers optimization. Optional direction arguments
+were added for three-dimensional bars. The appearance and alignment of the
+planar arrowheads DefaultHead2, HookHead2, and TeXHead2 was improved; they
+now accept an optional normal argument and respect the filltype.
+A transverse/longitudinal confusion was fixed in the solids module.
+The camera adjustment routine was improved and is now controlled by the
+autoadjust=true option for perspective projections; the user is notified
+when the camera is moved. The obsolete featpost3D.asy module was
+removed. Midpoint interpolation was reinstated for drawing contours.
+The Asymptote license was upgraded to the GNU Lesser General Public License.
+
+Release Notes for Version 1.65
+
+The xelatex tex engine was implemented. Bugs in pdflatex output and the
+xelatex alignment were fixed.
+
+Release Notes for Version 1.64
+
+Support was added for XeLaTeX PDF specials. The target point is not forced
+to be part of the control volume for absolute projections. The directory is
+now stripped from the animation prefix; generated PDF animations are no longer
+automatically deleted. New parameters xsize and ysize of the asyinclude
+function of the slide module are illustrated in interactive 3D examples in
+intro.asy. A Protein Data Bank example was added to illustrate the
+generation of predefined views. The slidedemo example was fixed.
+The license of the PRC code and tools was upgraded from GPL to LGPL.
+
+Release Notes for Version 1.63
+
+Support was added for XeLaTeX (which requires a modified version of
+movie15.sty; note however that PDF specials are not yet implemented in
+dvipdfmx). The 2D contour routines were generalized to handle nonuiform
+lattices; interpolation artifacts are now avoided when the midpoint
+function values are unknown. The ncell parameter for 3D contours was
+replaced by nmesh. The complex gamma function was implemented. Interactive
+rendering of preview images is now properly synchronized. The bounding
+volume is now automatically expanded to include the target position.
+An interactive 3D surface of revolution example was added to slidedemo;
+rendered images are now automatically included when fitting non-PRC
+pictures. Duplicate beginclip/endclip functions in pstoedit.asy were
+removed and the pstoedit-3.45 patch was updated to fix compilation errors.
+Errors on EOF after reading 0 values are no longer reported. One-column
+legends are now handled correctly. Old-style constructors were replaced
+with operator init. An electromagnetic spectrum example was added.
+
+Release Notes for Version 1.62
+
+Outputting PDF format to other directories was fixed. An int hex(string)
+function that casts a hexidecimal string to an integer and a
+pen rgb(string) routine that returns a pen corresponding to a given
+6-character RGB hexidecimal string were added. In the dot routines, Label
+arguments were added and minor bugs were fixed. A parametric version of
+markuniform was added.
+
+Release Notes for Version 1.61
+
+A workaround was implemented for a dvips misconfiguration in TeXlive 2008
+that introduces unwanted %%BeginPaperSize commands into the EPS output.
+The -q option was reinstated; the asymptote.py Python module was fixed.
+The bezulate.asy module now enforces the same zerowinding fillrule as used by
+dvips. In solids.asy, a warning is issued if the silhouette routine is used
+in a fully 3d context. The freeglut extensions to support user-specified
+multisampling values were re-instated. A freeglut segmentation fault
+triggered by spurious window creation in the export loop was fixed. An
+aspect ratio problem was fixed. A string[] to int[] ecast was added. A
+Pentype function was added. The asydir() function was fixed under MSDOS.
+
+Release Notes for Version 1.60
+
+An optional bool3 condition was added to the graph functions, allowing one
+to skip points or segment a graph into distinct branches, based on a
+user-supplied test (see the example gamma.asy). A gettriple routine was
+added. The interp function first promotes its pen arguments to the highest
+colorspace. Export exceptions are now caught gracefully. Under UNIX,
+xasy can now be run from a write-protected directory again. A work around
+was implemented for the inability of the movie15.sty package to handle
+spaces in filenames. Stack overflow diagnostics were improved. A read from
+pipe failure under MSDOS was fixed.
+
+Release Notes for Version 1.59
+
+A missing filltype option for projected 2D arrowheads was added.
+The scaling of plain TeX fonts was fixed. Examples that mix 3D exporting and
+viewing now work properly. With the -nothreads option, the main process
+now waits for 3D exports to finish before proceeding. Conflicts in slide
+presentations were fixed; the asy(string) function assigns defaultfilename
+correctly. A bug in processing command-line options was fixed.
+
+Release Notes for Version 1.58
+
+Two-dimensional arrowheads are now drawn automatically for 2D projections.
+ArcArrow3 routines were added. Standard pen arithmetic is now used in all
+colorspaces, so that interp(pen,pen,real) and Gradient(pen[] p) now work as
+expected. A Wheel palette was added and is used in the example gamma3 to
+indicate the phase of the complex Gamma function. A silhouette routine for
+solids of revolution is illustrated in the examples spheresilhouette.asy
+and hyperboloidsilhouette.asy. Problems with 3D axis label alignments were
+fixed. The example scaledgraph illustrates how to factor out an axis
+scaling. Interactive mode is now exited on EOF, unless exitonEOF=false.
+Support for open function signatures was added. A conflict between
+asymptote.sty and the breqn package was fixed. PNG images for the manual
+are now built in a separate directory so that they don't take precedence
+over PDF files. A problem with xasy under MSDOS was fixed.
+
+Release Notes for Version 1.57
+
+The pdflatex texengine was fixed. The default MSDOS "start-in" directory is
+now %USERPROFILE%, for compatibility with the MSWindows Vista operating
+system. Temporary files are now generated in the directory specified by
+the -outname (-o) command-line option, so that write access to the current
+directory is no longer required. Various font size problems were fixed.
+The axis coverage calculation was improved. An object(Label, envelope, ...)
+constructor was added, along with support for object transformation and
+alignment. Clipping is now allowed across page boundaries;
+beginclip(picture, path[]) and endclip(picture) functions were implemented.
+
+Release Notes for Version 1.56
+
+A bounding box bug in the latex texengine was fixed.
+The font scaling is now rounded to the nearest integer. The wait=true
+argument of shipout was fixed. The documentation of grid3 was fixed;
+examples of using grid3 with scale(true) were added. The handling of the
+asydef environment within Emacs lasy-mode was fixed. An asyinclude function
+for embedding 3D PRC graphs in slides was implemented.
+
+Release Notes for Version 1.55
+
+A serious bug in drawing paths of length 0 that broke the dot(pair)
+routine was fixed. Problems in guide to path and path to guide conversions
+were fixed. A triple invert(pair) routine was added to invert a pair z
+onto the projection plane. The obsolete field of view factor was removed.
+
+Release Notes for Version 1.54
+
+The filltype of three-dimensional labels is now respected when render=0.
+Multiple file batch mode under MSWindows was fixed. The reverse(guide) and
+guide examination routines were fixed. A reverse(guide3) routine was added.
+Curved cyclic paths of size 1 were fixed. Fork is now used by default under
+MSWindows pending stable CYGWIN POSIX thread support; this can be overridden
+with settings.threads=true. The need to remove latexusage_.pre along with
+latexusage-* and latexusage.aux when switching between latex and pdflatex
+usage was documented.
+
+Release Notes for Version 1.53
+
+Forking problems under Windows 2000 were fixed and MS-DOS style path
+warnings were suppressed. Problems with PRC projection sizing and the
+rendering logic were fixed. The toolbar is now enabled by default within
+the asyattach environment. Two-dimensional transforms no longer prevent
+three-dimensional labels from being projected onto the initial viewing
+plane. Out-of-memory errors in the OpenGL renderer are caught again.
+The new tube module was documented and a trefoilknot example was added.
+
+Release Notes for Version 1.52
+
+Support for generating PRC output on bigendian machines was added.
+Multisampling was improved: by updating the freeglut library to svn version
+761, one can now specify an antialiasing pixel width with the parameter
+multisample, which is now an integer. The asymptote.sty and asycolors.sty
+files are now installed by default in $TEXMFLOCAL/tex/latex. The OpenGL
+renderer by default now uses POSIX threads instead of fork. A work around
+for the nonstandardized signature of gluNurbsCallback on various MacOS
+platforms was implemented. Planar vertex shading was fixed. A planar
+argument to surface was added. To work around rendering problems with some
+graphics cards, the window is now hidden only when iconify=true. A tube
+module was added. A setlocale segmentation fault was fixed. Now that we
+require a multithreaded version of the Boehm garbage collector, the
+installation instructions were updated for using the system version. An
+optional user=false argument was added to min(picture), max(picture), and
+size(picture). The dependency of asy-mode.el on the cc-mode.el source file
+was removed.
+
+Release Notes for Version 1.51
+
+A separate multisample setting is used to control screen antialiasing;
+multisampling is now only enabled when viewing. The problem of multiple
+glInit calls is fixed. A more conservative multisampling patch for freeglut
+is supplied. The OpenGL process is now always forked for better
+performance. The last freeglut extension was removed.
+
+Release Notes for Version 1.50
+
+Detection and support for the native glut library on MacOSX now allows
+Asymptote's adaptive OpenGL renderer to be used on all major platforms.
+The OpenGL renderer now supports antialiasing; a race condition and export
+problems were fixed. The new default value of maxtile=(0,0) denotes
+the screen dimensions. Lighting problems due to incorrect normal
+orientations were fixed. The up vector for embedded PRC output was fixed.
+A viewportmargin parameter was added to allow for a larger viewport.
+An iconify setting was added for UNIX systems that support rendering in an
+iconified state. An embed option (default true) was added to allow one to
+suppress the embedding of a rendered preview image. A new version of
+asymptote.sty (1.01) supports file attachments, which provide a better way
+of embedding 3D PRC files in a LaTeX document. The latexusage file prefix
+was renamed from latexusage_ to latexusage-. A numerical precision issue in
+the surface of revolution constructor was fixed. Support for
+three-dimensional dimension bars was added; PenMargin3 and DotMargin3 were
+fixed. The argument put=Above (put=Below) should now be replaced by
+above=true (above=false); this is a backwards incompatible change.
+
+Release Notes for Version 1.49
+
+Issues with surface normals that led to incorrect lighting were fixed.
+By default, the mean(pen[]) routine now returns an interpolated pen with the
+minimum opacity of all given pens. A patch reverse(patch) function was
+added. The settings.keep flag is now handled correctly in texpath and
+strokepath. A cornermean function for surfaces was added. Several
+examples that illustrate patch and vertex shading were updated.
+
+Release Notes for Version 1.48
+
+High-resolution OpenGL tiled rendering was implemented. Support for
+vertex-dependent colors was added. Centering of perspective projections
+was improved. Rendering artifacts in planar surfaces and thick lines were
+fixed. A Gradient palette that varies linearly over a specified range of
+pens was added. An improved surface constructor for convex
+three-dimensional paths was added; the planar constructor should now only
+be used for nonconvex paths. A DefaultHead2(filltype filltype=Fill)
+arrowhead was implemented, along with an optional filltype argument for
+HookHead2. New maxheight, hstretch, and vstretch parameters were added to
+legend(). A boolean user=true argument was added to the point(picture, pair)
+function; the framepoint routine was removed in favour of
+truepoint(picture, pair, user=false). A roundbox envelope routine was
+added. An antialias setting (default true) was added. A bug in xasy and an
+incorrect precontrol bug in write(path) was fixed. Compilation with
+standard glut for systems without freeglut is now supported.
+
+Release Notes for Version 1.47
+
+Support for simple obj files and patch-specific surfacepens and meshpens
+was added. Surface constructors for triangles were added. Three-dimensional
+margins were implemented. Flat 3D arrowhead types HookHead2 and TeXHead2
+were implemented. By default, 3D arrowheads are now always drawn with
+currentlight. A missing angle parameter in HookHead3 was added. Functions
+that construct a pen array from a given function and palette were added, as
+illustrated in the example elevation.asy. A bug in the cyclic path write
+functions was fixed. A strokepath(path g, pen p) function was implemented.
+A missing put argument in grid3 and a missing transform for projected 3D
+mesh lines were fixed. File prefix problems were fixed. Spurious "camera
+too close" errors were fixed. Tighter three-dimensional bounds are generated.
+
+Release Notes for Version 1.46
+
+Support was added for embedding 3D PRC files within LaTeX even when
+settings.render=0. An error is now signalled if the user tries to render an
+image without freeglut library support. The Klein bottle example was
+updated to use lightgray instead of the new default surface color (black).
+The sphere animation example was updated to work with the new skeleton
+structure in the solids module.
+
+Release Notes for Version 1.45
+
+Bugs in the solids of revolution and graph3 modules were fixed;
+longitudinal curves are split into front and back pieces. Min and max
+arguments were added to axes and axes3. Rendering artifacts are now
+avoided. When render=0, 2D and 3D objects are now sized consistently.
+The automatic camera adjustment was improved. Bugs in thick three-dimensional
+lines were fixed; thick lines are now drawn with fewer Bezier patches and
+3D Linetype offsets are supported. The appearance of unitcones and arrows
+was improved. New arrowhead3 types HookHead3 and TeXHead3 were added. The
+default surface color is now black. New surface and path constructors were
+added. Secure options can now be queried as read-only settings.
+
+Release Notes for Version 1.44
+
+Full interactive 3D support has been added to Asymptote, with the option of
+generating and embedding 3D PRC data in PDF files or rendering scenes
+directly with Asymptote's own fast OpenGL-based renderer. The implicit
+casts from 3D to 2D objects were removed (in favour of call explicit calls
+to project). A path[][] texpath(string s) routine was added to convert
+string into the paths that TeX would fill. Add boolean stroke parameter was
+added for shading (and clipping to) stroked paths. The Circle and Arc
+routines were fixed. Autoscaling of graph axes limits is now disabled by
+default. A path3 path3(path p, triple plane(pair)=XYplane) constructor was
+added; the path3 routines were moved to C++ code. Optimized and robust
+versions of the intersection, windingnumber, inside, and surface extrema
+routines were implemented. The lighting routines were replaced by the
+OpenGL model. Each Asymptote process once again uses a separate
+currentpen. A segmentation fault and an incorrect parameter in the
+Delaunay triangulation routine were fixed. This major overhaul of the
+three-dimensional graphics has necessitated a few backwards
+incompatibilities. The most significant change involves filldraw:
+
+filldraw(polygon(5),red);
+
+should be replaced by
+
+draw(surface(bezulate(polygon(5))),red);
+
+Also, the solids module has been improved so that
+
+revolution a=revolution(O--X+Z,Z);
+a.filldraw(red,blue);
+
+is now more sensibly written as
+
+revolution a=revolution(O--X+Z,Z);
+draw(surface(a),red);
+draw(a,blue);
+
+Release Notes for Version 1.43
+
+A new array(n, value) function returns an array consisting of n copies of
+value. Conditional drawing of surfaces meshes was implemented. Vector
+field support was improved. Graph tick selection without autoscaling
+was improved. By default, all 2D axes are drawn below existing objects.
+An interface for drawing contours on arbitrary nonoverlapping
+meshes was added. Optional support for Jonathan Shewchuk's more robust
+triangulation routines was added. The file precision setting can now be
+queried. A beep() function was added. The partialsum function now returns an
+array of the same length as its argument (backwards incompatible). Dash
+offset and font selection bugs were fixed. Modules to redefine LaTeX named
+fontsizes for 10pt and 11pt article documentclasses were added. Problems
+in asy-mode.el were fixed. A problem with label alignment was fixed.
+The international inch is now used instead of the U.S. survey inch.
+The code now compiles cleanly under gcc-4.3.0.
+
+Release Notes for Version 1.42
+
+A routine was added for projecting a Label onto a given plane;
+an ambiguity in the three-dimensional scale routine was resolved.
+An inside(path p, path q, pen fillrule=currentpen) routine was added to
+determine if one path is strictly within another. Optional arrows were
+added to the slopefield routines. The movie function now generates
+multipage PDF animations when format="pdf" and global=true; a fit argument
+was added to support an optional filled bounding box for each movie frame.
+Casts were added between the hsv structure and pens. Bad casts from TeX
+bidirectional pipe are now caught. In inline latex mode, TeX headers are
+now output only when needed. A bug in the cancellation of text addition in
+xasy was fixed. The sticky bit is no longer set when creating the ~/.asy
+directory. The documentation and FAQ were updated.
+The dot(real[] a, real[] b) routine now returns the dot product of the
+vectors a and b; this introduced a backwards incompatibility:
+dot(x,y) should now be replaced with dot(pairs(x,y)).
+
+Release Notes for Version 1.41
+
+Python-style array slices were added. The array virtual field A.keys
+returns the indices of initialized entries. The concat routine can now
+take an arbitrary number of arguments. The write functions now output
+nothing for uninitialized values instead of producing an error. A bounding
+path is stored in the object structure to allow connections to
+noncardinal boundary points. The buildcycle algorithm was improved.
+The expression dir(E) is a synonym for E. The visibility of unsplit solid
+slices is now properly resolved. A drawpen argument was added to FillDraw.
+The uniform(real a, real b, int n) function returns a uniform partition of
+[a,b] into n subintervals. Complex exp, log, sin, and cos functions were
+added. An interface to the internal adaptive simpson integration routine
+was added. History lines are now stored immediately after input (as well
+at exit, after stifling). Support for the HSV colorspace was added.
+The dependence of non-PDF animations on the animate.sty package was removed by
+renaming animate.asy to animation.asy (PDF animations still need to import
+animate.asy). Transparency groups are now respected by xasy.
+TeX diagnostics were improved. An obsolete function for drawing boxes on
+pictures was removed in favour of draw(Label,box).
+
+Release Notes for Version 1.40
+
+Hatch widths for PDF output were fixed by disabling dynamic line width
+adjustment. A nurb-related bug in solid shading was also fixed.
+
+Release Notes for Version 1.39
+
+In the animate module, a constructor bug was fixed and the temporary
+multipage pdf movie file is deleted by default.
+
+Release Notes for Version 1.38
+
+For perspective projection, nonuniform rational B-splines (NURBS) are now
+approximated by adding additional control points to Bezier curves.
+Inline PDF movies can be generated directly within LaTeX files (requires
+animate package, version 2007/11/30 or later). SimpleHead, HookHead, and
+TeXHead (Computer Modern) arrow styles were added. FillDraw is
+automatically reduced to Draw for noncyclic paths. Empty clipping bounding
+boxes were fixed. The xasy diagnostic Console should now work reliably on
+all platforms. Graph and interpolation array length diagnostics were
+improved. The axes routines now take optional xlabel, ylabel, and zlabel
+arguments defaulting to empty strings. The autoformat axes tick label
+routines now try to add an extra digit of precision. Pen arguments were
+added to the flowchart block routines. A path&cycle operator was added.
+The read1, read2, and read3 routines now affect only the current operation.
+A -c (command) option and exit() command were implemented. Ambiguous
+expressions are now resolved by interactiveWrite (with a warning). A patch
+is included for fixing problems with the Asymptote backend for pstoedit-3.45.
+
+Release Notes for Version 1.37
+
+The speed and useability of the graphical user interface has been greatly
+improved, including full transparency support under MSWindows.
+The intersections routine was fixed, and an optional fuzz parameter was
+added. A bug in the arrow routines was fixed. The 2D graph routines were
+improved when autoscaling is disabled, secondary axis bugs were fixed,
+and the automatic logarithmic axis coverage routine was re-enabled.
+Degenerate 3D reference vectors are now handled and the default 3D
+tick directions were improved. The array returned by intersections is now
+automatically sorted. A patch is applied to avoid out-of-memory
+segmentation faults with gc-7.0. A history(int n=1) function can be used to
+return the interactive history. Automatic semicolons are now added to the
+history. Locale bugs were fixed. A string[] split function was added.
+Installation, uninstallation, and diagnostics under MSWindows were
+improved. A marker dot routine was added. The output(s,update=true)
+function was fixed. Configure now uses a system version of Boehm GC if the
+recommended local version isn't present.
+
+Release Notes for Version 1.36
+
+Recently introduced bugs in the tex(), postscript(), gsave(), and grestore()
+commands were fixed.
+
+Release Notes for Version 1.35
+
+A hang in testing for the intersection of nearly identical paths in
+solids.asy was fixed. The numeric formatting of setdash arguments was fixed.
+
+Release Notes for Version 1.34
+
+An innovative graphical front end to Asymptote (xasy) has been developed.
+Clipping of labels is done within a picture environment to avoid unwanted
+page breaks. The default LaTeX font is now package-dependent. The syntax
+was generalized to allow expressions such as (x). Comments are now
+supported when reading strings in csv mode. Nesting capacity overflows
+in arctime were fixed. The autoscaling of graphs for close minimum and
+maximum values was improved, the default tick format is automatically
+adjusted to make tick labels unique, and a general trailingzero format
+string was added. Improved, robust versions of intersect and
+intersectionpoints were implemented (based on a new routine
+intersections). A permissions bug was fixed. A filltype argument was added
+to the dot routines. Printer stack use was optimized by pruning unneeded
+gsave/grestore commands. Temporary EPS files are now removed in inline PDF
+mode. A discussion of the 3D generalization of Hobby's algorithm used in
+Asymptote was added (intro.asy).
+
+Release Notes for Version 1.33
+
+Routines to find the 3D and projected 2D bounding boxes of Bezier surfaces
+were added to the surface module, along with the standard teapot example.
+Extended for loops were documented. The page numbering of slide
+presentations with stepping enabled was fixed. The int type is now a long
+long type (typically a 64-bit integer). Support for reading and writing
+64-bit integers in binary and XDR modes and large file support were added.
+Input files are now opened in input-only mode. Multiple invocations
+of labelpath now work. A projection bug in the grid3 module was fixed.
+The search path order was changed: directories specified by the dir
+configuration variable are now examined before the .asy subdirectory in the
+user's home directory. User configuration files are ignored during
+installation. Some bugs in asy-mode.el were fixed. Texput files are
+removed again. A memory allocation incompatibility in the workaround for
+old, broken readline libraries was fixed. The framepoint and truepoint
+routines now work even when an exact picture size estimate is unavailable;
+a picture scaling bug was fixed. Writing to a file specified with
+-o /dir/file.eps is allowed again. A quarticroots solver was added, the
+cubicroots solver was improved, and a complex quadraticroots solver was
+added. A workaround for broken texi2dvi installations was implemented.
+Memory leaks were fixed. The garbage collector was update to gc-7.0;
+upgrading to gv-3.6.3 is also recommended. A segmentation fault in
+complement was fixed.
+
+Release Notes for Version 1.32
+
+A recently introduced segmentation fault in subpath was fixed.
+The current directory can now be examined with cd() even if globalwrite is
+false. The cd path is now only written once in interactive mode.
+Further garbage collection improvements and leak fixes were made.
+
+Release Notes for Version 1.31
+
+Garbage collection was dramatically improved, resulting in reduced memory
+usage and increased speed. The options -compact and -divisor and the
+function purge() were added to give the user more control over garbage
+collection. The array virtual member function delete() with no arguments
+explicitly deletes all elements of the array.
+An interpolate(real[][] f, pen[] palette) function was added for
+constructing the pen array needed by the latticeshade routine.
+A nullpath frame and picture sizing bug was fixed.
+LaTeX diagnostics were improved. A facility that does not rely on
+garbage collection finalizers was implemented for closing open files
+at the end of each asy process.
+
+Release Notes for Version 1.30
+
+Constructors were added. Routines to allow access to guide
+components were added. The three-dimensional projection and contour
+routines were optimized. A tickmodifier NoZero and ticklabel format
+NoZeroFormat were added. A simplified gouraudshade interface was added.
+A linewidth bug was fixed. The array insert and delete routines were
+generalized. The new array virtual member "initialized" can be used to
+detect whether an element is initialized. All fonts are now automatically
+embedded in PDF files. Inline PDF animations now require version 2007/05/24
+or later of the animate.sty package. General root solving routines were added.
+The implicit initializer for files is null. Boolean arguments
+were added to the image and shading routines to allow one to disable
+data buffering. The functionality of the readline routine was split into
+the routines history, readline, and saveline. Many fixes were made to
+the Emacs asy-mode.el.
+
+Release Notes for Version 1.29
+
+Support for drawing surfaces described by the null space of real-valued
+functions of three variables was added. The dir command now works correctly
+for degenerate Bezier paths; an optional final argument can be used to
+examine incoming and outgoing tangent directions. Numerical overflow and
+precision issues were addressed. A piecewise monotonic spline type and
+example were added. Optional fillpen and legend entries were added to
+histogram. The "q" command quits in interactive mode only if there is no
+top-level variable of that name. Standard input of strings was
+fixed. Support for transparent PNG images in xasy was added. Animation
+support was upgraded to use the new animate.sty package rather than the
+interim pdfanim_temp.sty package.
+
+Release Notes for Version 1.28
+
+TeX error handling was improved. A dvipsOptions configuration variable was
+added. A recently introduced bug in the XDR routine xinput was fixed.
+Compilation under the upcoming GCC 4.3 release is now supported.
+Nonglobal PDF animations, where each frame is separately scaled and written
+to a file, were implemented. Reading from standard input now works correctly
+even in the absence of a working readline library. A build problem under
+Fedora Core 5 was fixed. Parallel builds are now supported.
+
+Release Notes for Version 1.27
+
+A Hermite spline graph interpolate type was added for smoothly joining
+sampled functions. The cycle3, tension3, and curl3 keywords were
+respectively renamed cycle, tension, and curl. Assignments no longer write
+the value at the prompt. A bug in longitudinal skeleton detection was
+fixed. The filloutside routine now works with paths that extend beyond the
+current boundary. The unit n-point cross function returns a cyclic path.
+The "append" argument of the output function was renamed to
+"update", which now allows both reads and writes to the data file.
+Negative arguments to seek mean relative to the end-of-file; a seekeof
+function was added. PDF animations can now be loaded from an external file.
+The TeX pipe handshaking was improved. TeXLive 2007 is now supported under
+MSWindows. A work around was implemented for a MikTeX bug in handling file
+names containing spaces.
+
+Release Notes for Version 1.26
+
+The correct surface normal is now used when calculating lighting; a Klein
+bottle example was added. The front/back detection of the transverse
+skeleton of solids of revolution is fixed. A better camera-independent
+reference value for resolving path3 orientation is used. A 3D midpoint
+routine was added. Tick values for broken axes can now be autogenerated;
+broken logarithmic axes are also supported. A 2D aligned axes example was
+added. A patch that fixes a redisplay bug in gv-3.6.2 is included.
+
+Release Notes for Version 1.25
+
+A new picture size routine, which maps specified user coordinates to a
+given final size, provides a convenient way of forcing the plotted
+subregion of a graph to have a fixed size. The correct surface
+normal is chosen when calculating lighting. The comment character can now be
+escaped when reading strings from data files (but is disabled when reading
+raw characters with getc). The new word file mode is useful for reading
+white space-delimited strings. PostScript output files are now explicitly
+designated as EPSF in the header line. The minimum width and height of
+flowchart blocks may now be controlled separately. Interpolation and knot
+theory modules were added. The usage of path vs. guide in the base files was
+standardized.
+
+Release Notes for Version 1.24
+
+Structures now have implicit initializers. PDF animations are supported in
+inline tex mode by communicating the texpreamble to LaTeX. The asypreamble
+environment was removed in favour of corresponding Asymptote commands in
+the asydef environment. Default y tick values were fixed. The binary space
+partition now works correctly for projections from infinity; an arbitrary
+target point can be specified for perspective projections. A 3D version of
+the intersectionpoints routine was added. Unconditional binary logical
+operators & and | and bitwise integer functions AND, OR, XOR, and NOT were
+defined; the array boolean operators && and || were renamed to & and |.
+The PostScript clipping code was fixed. The angle(rotate(x)) routine now
+always returns x (mod 360). User debugging errors are now cleared.
+The fontsize package was updated to use fix-cm.sty instead of type1cm.sty.
+The Microsoft Windows registry is checked for both GPL and AFPL Ghostscript.
+A workaround was implemented for a pdflatex vertical offset bug.
+Segmentation faults in the Delaunay triangulation and image codes were fixed.
+
+Release Notes for Version 1.23
+
+Microsoft Windows autoconfiguration has been implemented by querying the
+registry: Asymptote and the applications it depends on may now be installed in
+any location. The shipout command is allowed to write to other directories
+if and only if -global is true. An autoimport configuration setting was
+added. Importing the Gnu Scientific Library (gsl) now works on all
+platforms. A texpreamble environment to contain the LaTeX preamble for
+both LaTeX and Asymptote was added to asymptote.sty. A conflict with the
+French babel packages was fixed. Background picture sizing in the slide
+presentation package was fixed.
+
+Release Notes for Version 1.22
+
+Problems with loading LaTeX packages and slide presentations were fixed.
+Non-static variables in every loop iteration are now allocated anew.
+Formatting under locales with nonperiod decimal separators was fixed,
+along with logarithmic tick labels near the machine epsilon. Concatenation
+of nullpaths was fixed. New path markers were added and the perpendicular
+symbol in the geometry module was improved. The skeleton routines in the
+solids module were split to provide finer control. Routines to facilitate
+drawing 3d contours were added. Reading portable XDR binary data into
+arrays works again; functions for reading and writing also in native binary
+formats were added. The TeX preamble is no longer output in inline
+mode. The TeX pipe is now aware of a previously generated aux file. Memory
+leaks were fixed. An inline limit is now imposed on old compilers to speed
+up compilation. Setlocale warnings are disabled unless debugging is on. A
+colorspace command for extracting the colorspace of a pen was added. An
+Asymptote introductory slide presentation was added and a user-written
+Asymptote tutorial is now cited in the manual.
+
+Release Notes for Version 1.21
+
+Expressions entered at the interactive prompt are automatically evaluated
+and written to stdout. The routine intersectionpoints returns all
+intersection points of two paths. Bounding box computations of paths drawn
+with transformed pen nibs were fixed. Transparency and automatic
+colorspace promotion are supported when shading and drawing images.
+A grid3 module for drawing 3D grids and a binary tree module were added.
+Automatic tick computations were improved: the actual tick value is now
+passed to the ticklabel formatting routine, even for logarithmic axes.
+A tickmodifier routine gives users complete control over which of the
+auto-generated ticks actually get drawn. The contour drawing and filling
+routines were improved. A --where option makes --listvariables show where
+global functions and variables are declared. Emacs asy-mode was improved,
+including function source code lookup. An optional labelpath interface to
+the PSTricks pstextpath macro was implemented for drawing curved labels
+along paths. In inline latex usage, picture are no longer scaled by
+default (use \begin{asy}[\the\linewidth] to recover previous default of
+scaling to line width). A texcommand option was added to override the tex
+engine command name. The slide presentation module no longer forces
+pdflatex; bibliography support was added, figuremattpen was reimplemented,
+and the spurious vertical shifting of bullets was fixed. Compilation under
+AIX and IRIX systems is supported.
+
+Release Notes for Version 1.20
+
+Explicit yaxis label angles were fixed. Loading and including diagnostics
+under the -vv option were improved. The Emacs asy-mode now respects
+TeX-electric-sub-and-superscript. The texpath configuration variable and
+diagnostics were fixed under MSWindows. Low-resolution palettes now
+display correctly. A routine to fill cyclic contours was added, along with
+the example fillcontour.asy. A command-line option to change the current
+working directory was added. The FAQ was updated.
+
+Release Notes for Version 1.19
+
+Bezier surfaces were implemented, along with tensor and Coons patch
+shading. The cylinder function was changed to be consistent with the cone
+function. The intersect routine now returns an array of two reals.
+The unitsize, xunitsize, and yunitsize arguments of shipout have been
+replaced with a unitsize function. The seconds() function now works
+portably. Minor bugs in inside() were fixed; a winding number routine was
+added. The movie bounding box is set to the largest bounding box of all
+pictures. Portable high-quality embedded PDF movies are now supported, as
+well as portable external movies. An embedded U3D example was added.
+Alignment positioning transformation was fixed; a Rotate(pair) and a
+string(real x) routine was added. Flowchart routines and the labelbox and
+advection examples now work with pictures as well as frames.
+An add(picture pic=currentpicture, drawer d) wrapper was added; a picture
+rescaling bug was fixed. Tex error handling was improved. Optional bounds
+arguments were added to verbatim postscript and tex commands. Writing to
+only the local directory is allowed unless the -global (or -unsafe) option
+is specified. A final backslash continues a line on the interactive prompt;
+a new multiline option is convenient for cutting and pasting code in
+interactive mode. Clipping now sets the true size coordinates to 0. Memory
+usage was reduced. The documentation was updated, including a description
+of how to produce Debian binaries from RPM binaries.
+
+Release Notes for Version 1.18
+
+A pen caching problem and clipping bugs were fixed. Bugs in interactive
+mode and in linemode string reads were fixed. The picture.scale() routine
+now guards against division by zero. The drawing of surface meshes was fixed.
+The minbound and maxbound functions were implemented also for arrays.
+The labelx, labely, xtick, and ytick routines respect the current graph
+scaling. The asycolors.sty file was updated to remove the pstricks
+dependency. The slide package now works with both latex and pdflatex; the
+colordvi dependency was removed. A nativeformat() function returns "eps"
+or "pdf", depending on the current tex engine. The pdf() and latex()
+functions are now visible. The usepackage and minilatex modules check for
+latex mode. Static variable allocation is now discussed in the FAQ.
+An image histogram and contour example was added. The diatom example was
+modified to illustrate interaction of fixed-sized and scaled coordinates.
+
+Release Notes for Version 1.17
+
+A workaround for a garbage collection bus error under MacOS X was implemented.
+A uniform histogram routine was added to the stats module. New frequency
+binning routines were added. The argument order of the nonuniform frequency
+binning routines was interchanged for consistency (backwards incompatible).
+The FAQ was updated.
+
+Release Notes for Version 1.16
+
+Inline LaTeX mode was fixed. The legend routine was generalized to allow
+multiple entries per line; an example was added. The truepoint
+function was renamed framepoint. A function truepoint that works like point
+but accounts for fixed-sized objects was added.
+The picture.calculateTransform function now returns the actual transform used
+for fitting in the case where only an approximate picture size was
+available. A 2d frequency binning routine was added to the stats module.
+A memory leak was fixed.
+
+Release Notes for Version 1.15
+
+Graphics label bounds and incorrect path bounds in latticeshade were
+fixed. The LaTeX color package is now used for the latex and pdflatex engines,
+to keep them informed of the current color. A unitlength of 1pt is now
+enforced in inlinetex mode. In cases like 2D graphs where only an
+approximate picture size estimate is available, the transform is adjusted
+so that the fitted frame meets the size specification. The cube animation
+and binary space partition were fixed. The determinant of a singular
+matrix now returns 0 instead of an error. Temporary pdf files are removed.
+The gv patches were removed since these are included in the long-awaited
+gv-3.6.2 release. A workaround for a compilation problem under MacOS X
+10.3.9 was implemented. A DIN 15 CAD package and new examples were added.
+
+Release Notes for Version 1.14
+
+General affine transforms and clipping may be applied to TeX labels;
+bugs in label alignment transformation were fixed. The TeX engines latex,
+pdflatex, tex, and pdftex are supported. Separate xunitsize and
+yunitsize scalings are allowed. Graph axis bound communication was added
+to allow axes with ticks and unextended axes to be called on an empty
+picture. Path labels are drawn after the path (to support UnFill).
+Filltype definitions were standardized; a Draw filltype was added (for
+drawing a bounding box around a label). New filloutside routines were
+added. Images can be drawn for irregular mesh contours and two-dimensional
+pen arrays. Landscape slides automatically enable PDF autorotate option.
+A MetaPost buildcycle routine was added. Setlocale errors are ignored.
+The "Cannot write to venn_.tex" error under Windows XP was fixed. Very old
+readline libraries found on many MacOS X systems are detected. The editing
+mode asy-mode.el supports Emacs version 21. The option
+\usepackage[inline]{asymptote} is now supported under both latex and pdflatex.
+
+
+Release Notes for Version 1.13
+
+Image and contour transposition conventions for matrices were standardized;
+resolution arguments were removed from the matrix contour routines.
+The bounding box is now correctly calculated for square pen caps.
+A bug in drawline was fixed. An up argument was added to the projection
+routines to specify the camera orientation. The definition and
+documentation of cone was fixed; surface function signatures were
+consolidated. New 3d examples were added. Legends and markers are now
+allowed when drawing superpaths. Zero page alignment no longer suppresses
+labels; bounding box fuzz was removed. Intelligent interactive
+auto-completion was added. If scroll is negative, an entire page is
+scrolled. Support for Adobe Reader annotations was added.
+Write without data arguments now works like write with data arguments.
+A list function displays all global functions and variables in a module.
+The Emacs asy-mode.el was improved. A FAQ was added.
+
+Release Notes for Version 1.12
+
+PDF transparency was implemented. The documentation of Bezier curves was
+improved. Bounding box calculations now account for label scaling.
+A special case of the Step calculation in graph.asy was fixed. The function
+scroll(int) was changed to a setting; a quit (q) option was added to the
+scroll facility. To avoid an unwanted ghostscript window, gswin32c (rather
+than gswin32) is used by default for producing pdf files under MSDOS.
+
+Release Notes for Version 1.11
+
+The defaultformat string is used again for graph tick labelling commands
+instead of an empty format string. A workaround for the broken
+libsigsegv-2.3 library that caused a premature exit(1) was implemented.
+An extra blank line at the end of 3D array writes was removed; 3D array
+transpose and copy functions were added. The realmult routine was moved to
+runtime and documented. The example embeddedmovie of embedding movies
+within PDF files was added. Overflow diagnostic messages during mpeg merges
+are now suppressed. A twice setting was added to resolve LaTeX references.
+The settings module is now globally accessible. Duplicate trace messages
+were pruned. Debugger breakpoints can now be set using a matching substring
+instead of a line number. Conditional breakpoints are now supported.
+Runtime errors and interrupts no longer reset the interactive environment.
+
+Release Notes for Version 1.10
+
+Parametric surfaces were implemented and parametric graphs now respect
+picture scaling. Fill and FillDraw now work for markers and superpaths.
+A bug in reading strings from files was fixed. Support for MikTeX 2.5 and
+Autoconf > 2.59 was added. Asymptote and output filenames can now contain
+spaces. Interrupts are working again. A line-based debugger was implemented.
+
+Release Notes for Version 1.09
+
+The workaround for the gv-3.6.1 option handling bug now supports earlier
+versions of gv, including gv-3.5.8. By default, Ghostscript version 8.54 is
+used by the MSWindows version to produce PDF files.
+
+Release Notes for Version 1.08
+
+Resolution problems in the contour routines were fixed; null contour labels
+are now suppressed. Configuration problems were fixed; the malloc
+configuration checks were removed and the help command again knows the
+correct location of the manual. In the slides package, some stepping bugs
+were fixed, an institution field was added to the titlepage, and vbox
+support (say for aligned equations) was added. A colorless(pen) function
+that strips pen color attributes was added. A clean copy of the source
+files is now shipped.
+
+Release Notes for Version 1.07
+
+This release implements uniform and irregular mesh contour drawing
+algorithms: contours can be individually labelled or filled using a
+colour density palette. The flowchart interface and alignment were
+improved. A slope fields package was added. The arrow size limiting code
+was fixed. Some bugs in makepen were fixed. Image and shading functions
+now respect the -gray, -rgb, -cmyk, and -bw options. Date arithmetic routines
+were added. Several small bugs in the graph routines were fixed. Custom
+three-dimensional projections can now be easily constructed.
+
+The public keyword is now the default permission modifer. A new keyword,
+restricted, makes variables readable but not writeable outside the
+structure in which they are defined (previous this was the default behaviour).
+A user-transparent work around for the backwards-incompatible command-line
+options of gv-3.6.1 was implemented. Various configuration problems were
+addressed to better support the Asymptote rpm for the Fedora Core Extras
+project. A cputime() function was added.
+
+Release Notes for Version 1.06
+
+General flowchart routines and an example were added. Papersizes other than
+letter now work with -outformat pdf again. Performance was improved by
+avoiding unnecessary output flushing. An asycolors.sty package was added
+to make LaTeX aware of CMYK versions of predefined Asymptote colours.
+The default pdf viewer for MacOS is now "open". The -u option can now be
+specified multiple times on the command line. Optional x and y margin
+arguments were added to Fill. A reverse video option was added to
+slide.asy; titlepage and title by default call newslide, unless the
+currentpicture is empty. An argument was added to newslide to allow
+stepping to be turned off for that slide. The slidedemo example now
+generates any required eps files. A segmentation fault in eval was fixed.
+
+Release Notes for Version 1.05
+
+Shaded and skeletal representations of surfaces of rotation were
+implemented. New oblique projections were added and bugs in the 3D graph
+routines were fixed. An argument reversal in one of the add routines was
+fixed. A clipping margin was added to unfill. General determinants were
+added. Sin, Cos, Tan, aSin, aCos, and aTan, which use degrees, are now
+built-in functions. The dash adjustment algorithm was improved. The
+cubicroots solver now works again when R=0. Internal operations are now
+added for all variable declarations of new arrays and functions. Automatic
+viewing can easily be turned off under MSDOS. Nonstandard paper sizes
+are now correctly handled. The C locale is always used when producing
+postscript patterns. Configuration problems were fixed. The editor
+customization files asy.vim and asy-mode.el were moved to the Asymptote
+system directory. Stepping of slide presentations can now be enabled from
+the command line. Many new tests were implemented. The examples were moved
+to the examples subdirectory of the documentation directory.
+RPM files are now released.
+
+Release Notes for Version 1.04
+
+A convenient presentation slide package was developed. The misalignment of
+TeX and PostScript layers was fixed by giving includegraphics the exact
+bounding box. The overall bounding box was also fixed. The tension atleast
+command and the clipping of remote labels by unfill near the frame boundary
+were fixed. Permission checking for types was added. The new point-like
+truepoint function uses the actual current picture size. Locale support,
+the ', I, and F format specifiers, and custom pagewidth and pageheight
+settings were added. A Ticks specifier draws ticks on both sides of the path;
+format="%" also suppress tick labels for logarithmic axis.
+The linetype adjustment to the arclength was improved and can now be
+optionally disabled. Color names were systematized, including texcolors
+and x11colors. A general purpose user command-line option accepts arbitrary
+Asymptote code as a string. All duplicate path points in three.asy are now
+removed. A convenient fixedscaling picture sizing routine was added.
+Selected special functions from the GNU scientific library, DESTDIR support,
+and a Python module to access Asymptote commands were added.
+The legend skip is now based on the actual legend entry height, not the
+fontsize. A backwards incompatibility was introduced in attach, add, and
+legends (add and attach take arguments in the same order as label):
+
+attach(point(E),legend(20E),UnFill) -> attach(legend(),point(E),20E,UnFill).
+
+Release Notes for Version 1.03
+
+Support was added for compiling under gcc-4.1.0. A memory leak in
+interactive mode was fixed. A procedure for using CJK fonts was documented.
+The return type of the three-dimensional intersectionpoint routines was
+fixed. A function for inverting 2D points projected from 3D back onto a
+specified plane was added, along with a solid geometry package with
+routines to draw cylinders. New xaxis(triple,real), min(guide3[]), and
+max(guide3[]) convenience functions were added. A Degrees function like
+degrees(pair), except that it returns 0 for a (0,0) argument rather than
+generating an error, was added. Interactive mode (without command-line
+editing or history) now works even in the absence of the GNU readline
+library. An upper limit (100000) on the number of calls to intersectcubics
+per cubic segment was imposed on the intersection routines. The
+documentation was updated.
+
+Release Notes for Version 1.02
+
+Lighting was implemented for surfaces described by functions and matrices.
+A bug in the positioning of axis labels was fixed. The type of randMax was
+fixed. Configuration and diagnostics were improved; the "dir" setting in
+configuration files is respected. Under MSDOS, the configuration file is
+now %USERPROFILE%/.asy/config.asy; configuration settings now work as
+documented. On UNIX systems, installation can optionally be performed
+without root privileges. Errors thrown by the parser while reading the
+configuration file are now handled gracefully. The patches to pstoedit
+were removed since they are now included in pstoedit-3.44.
+
+Release Notes for Version 1.01
+
+A bug in the surface plot of a matrix was fixed. A workaround was
+implemented for the broken GNU readline/history library under MacOS.
+
+Release Notes for Version 1.00
+
+A pen bounds error was fixed. A bug in the linear equations solver was
+fixed. Images now transform properly and nonsquare images appear
+correctly. The legend argument of draw accepts a Label. An interface to
+the movie15 package for embedding movies, sounds, and 3D objects within a
+PDF file was added. A bug where nonsolid pen types were ignored was fixed.
+Missing xpart, ypart, and zpart functions were re-added. A segmentation
+fault in format was fixed. An interface to the GNU readline function was
+added to allow editing of input. A complement function was added. A bug in
+the 2D graph tick selection routines was fixed; xlimits and ylimits no
+longer crop data by default. For consistency, the "includegraphics"
+labeling function was renamed to "graphic".
+
+Release Notes for Version 0.99
+
+A bus error and compilation error under MacOS X were fixed. If -debug is
+set, execution continues after the first error. The "make check" code was
+fixed. The contributed MacOS X binary site is now mentioned in the
+documentation.
+
+Release Notes for Version 0.98
+
+Command-line options and configuration variables were reorganized into an
+Asymptote settings module, allowing default values to be set in
+~/.asy/config.asy (~/.asy/options is obsolete). Command-line options
+can be negated by prepending -no to the option name. Type-dependent
+function and record operators are now added to the parent record.
+Execution stops after the first error in a runnable. Two- and
+three-dimensional array min/max functions for all ordered builtin types
+were implemented. Comments are now allowed within 3d data blocks. The base
+file plain.asy was split into many subfiles. The currentpen nib is
+respected. Warning messages are suppressed when shipping out an empty
+picture. The tick computation was fixed when xaxis and yaxis are called
+with explicit limits. The -t option was removed as it is no longer needed
+for generating inline tex files. Machine constants are now implemented as
+variables rather than functions.
+
+Release Notes for Version 0.97
+
+An uninitialized pen transform bug was fixed. A workaround was added for a
+readline incompatibility under MacOS X 10.4.3. Incorrect and missing names
+for builtin function arguments were fixed. Duplicate functions were removed.
+
+Release Notes for Version 0.96
+
+A MetaPost-style makepen function allows the default pen nib to be changed
+to any polygonal (possibly nonconvex) cyclic path. A unitsize argument was
+added to the shipout command. Three-dimensional lighting effects were
+added and illustrated with the Gouraud shading of a sphere. The MidArrow
+attribute was fixed. Builtin functions now have named arguments. Brackets
+are now part of the quote syntax. The write command was generalized
+to allow writing a list of vectors as columns. Drawing to standard output
+now works even when there are no labels. The -noView command was replace
+by -nView or -no View. Several segmentation faults were fixed. Custom axis
+types were documented.
+
+Release Notes for Version 0.95
+
+A memory leak was fixed; garbage collection messages are now suppressed
+unless the -d option is given. In interactive mode, a reset keyword was
+implemented to restore the environment, except for the scroll setting.
+The interactive input command now does an automatic reset. A link was
+added to the GNU readline library documentation for customizing interactive
+key bindings. A hang in scroll mode on an end-of-file condition was
+fixed. To reduce LaTeX memory usage, the scalebox macro is used only where
+required. A legend problem was fixed. The documentation was updated.
+
+Release Notes for Version 0.94
+
+A label bug arising from a conflict between some versions of the LaTeX
+pstricks and graphicx packages was fixed. Embedded LaTeX files are always
+run in quiet (-noView) mode. Frame loading issues with imported types
+(for example, with the triangle SAS constructor in the geometry module) was
+fixed. The command import graph is now an abbreviation for access graph;
+unravel graph.
+
+Release Notes for Version 0.93
+
+The import scheme was completely redesigned, with new keywords access,
+unravel, from, and include. A true (rather than emulated) interactive mode
+and runtime imports have been implemented. The default pdf browser is now
+acroread; the pdf fuzz workaround for gv was removed. The tension3 and
+curl3 keywords were re-added; a surface graph routine for matrices was
+implemented. Problems with csv mode were fixed. The function defaultpen()
+was renamed to resetdefaultpen(). Integer division via quotient(int,int)
+is now consistent with the modulo (%) operator. Checks for integer
+overflow and erf, erfc, and gamma functions were added. More descriptive
+names latticeshade, axialshade, radialshade, and gouraudshade for the
+shading routines were chosen. Horizontal and vertical label scaling was
+implemented. Default command line style-parameters can now be stored in
+~/.asy/options. The interactive history file is now ~/.asy/history by
+default unless -localhistory is specified. Outputting to standard output
+via "-o -" is now allowed.
+
+
+Release Notes for Version 0.92
+
+Clipping now clips labels and all layers of a picture, not just the most
+recent one. A bug in precontrol and postcontrol was fixed. A ticklabel bug
+and precision errors at +/-1e-4 were fixed. An example of a "broken" x
+axis was added. A dot product now requires explicit pair arguments.
+The implicit cast from real to pen was removed. Straight flags are now
+preserved when using a path as part of a guide. An UnFill filltype was
+added for clipping underneath labels and legends. A struct marker was added
+to support arbitrary marker locations. Directories are no longer stripped
+from explicit output filenames.
+
+A function inside was implemented to test whether a point is inside a
+cyclic path. The routines inside, quadratic solver, and intersect in
+math.asy were replaced by internal C++ routines. A robust real cubic root
+solver was added. A floating point exception in complex powers when base is
+zero was fixed. Colinearity checks were added to the leastsquares routine.
+
+The interface to plane was changed to return a representation of the plane
+through point O with normal cross(u,v). The routine intersectionpoint was
+moved to plain.asy and a 3d version was added to three.asy. We now draw
+over existing TeX layers when doing 3d hidden surface removal. A 3d aspect
+ratio can now be specified. A gui() function and MSWindows support for xasy
+was added; this will require renaming "gui(" to "GUI(" in any existing .gui
+files. The dir argument of picture.fit() was moved to add(frame,pair)
+and attach(frame,pair):
+
+add(pic.fit(E)) -> add(pic.fit(),E).
+
+Release Notes for Version 0.91
+
+Fixed GUI transforms: grouping should not depend on deconstruct flag.
+
+Release Notes for Version 0.90
+
+Default function arguments are now evaluated in the scope where the
+function is defined, not in the scope of the caller. The depth handling
+of deferred TeX labels was fixed. The positioning of 3d axes labels was
+improved; an example showing tick and axis label rotation was added.
+A minimum value of fuzz in the intersect routines is enforced to prevent
+infinite loops. An error in the man page regarding the -t option was
+fixed. The write function was generalized to handle an arbitrary number of
+data values.
+
+Release Notes for Version 0.89
+
+The processing of GUI files was fixed. User-specified ticks now work also
+with logarithmic axes. The arguments of LeftTicks and RightTicks were
+standardized; it is now possible to include a general string(real) routine
+to typeset each label. Logarithmic axes ranges of less than a decade are no
+longer upscaled when autoscaling is disabled. All references to the
+mailing list were removed from the documentation since the forum is now
+used in its place. The temporary included PostScript file suffix was
+renamed from "ps" to "eps".
+
+Release Notes for Version 0.88
+
+The graph routines were overhauled to support both two- and three-
+dimensional axes, partitioning them uniformly in tick value space,
+not with respect to arclength. An empty format string is treated as
+defaultformat. A fuzz parameter was added to the intersect routines;
+these routines now work for points. Data file comments were implemented.
+The perpendicular routine now uses an alignment argument; scale(pair) was
+removed. An option was added to asymptote.sty to make all LaTeX symbols
+visible, along with a second optional string to Label for providing a size
+estimate for undefined labels. Numerous small bugs were fixed; the
+pstoedit patch was updated. The installation and instructions were
+improved. An environment variable for every external command was added.
+
+The argument order of the axes routines was standardized; a call like
+xaxis(min,max,"$x$",red,Bottom,LeftTicks);
+should now be written
+xaxis("$x$",Bottom,min,max,red,LeftTicks);
+
+Release Notes for Version 0.87
+
+This release implements general hidden surface removal using a binary space
+partition and adds three-dimensional versions of the standard path
+functions (arclength, subpath, intersect, etc.), along with circle and arc
+functions. Hidden surfaces in regular mesh surface plots now are properly
+handled from any camera location. The arclength rather than the length is
+used for determining default label position on paths; Relative(real) and
+Relative(pair) functions were added for labelling paths relative to the
+total arclength and local path direction. Structure constructors and
+operators == and != were implemented and documented. The permissions of
+static functions within structures was fixed. A pen argument to filltype
+Fill to specify an interior pen distinct from the boundary pen was added.
+For convenience, array push members now return the pushed element.
+A missing shift in Label.out(frame) was added. The feynman module was
+updated to include a new function texshipout; MidArrow was moved to
+plain.asy. The optional position arguments of BeginArrow and related
+functions were fixed. A numerically robust quadratic equation solver was
+added.
+
+Release Notes for Version 0.86
+
+Fixed make man problems.
+
+Release Notes for Version 0.85
+
+A fully three-dimensional, rotationally invariant, generalization of the
+two-dimensional MetaPost path construction algorithms has been
+implemented. A tridiagonal solver was added. Adobe's automatic rotation of
+PDF files was disabled. Cyclic indices are now allowed only on arrays
+having the virtual cyclic flag set to true. The bug fix in simplex was
+generalized. An online help option was added to interactive mode; exit is
+now a synonym for quit. Microsoft Windows resource fields and an icon were
+added. ASYMPTOTE_DIR can now be a list of directories.
+
+Since some files were moved in this release, Microsoft users may wish to
+first uninstall the previous release to avoid duplicate files.
+
+Release Notes for Version 0.84
+
+This release ports Asymptote to the Microsoft Windows operating system; an
+executable file is distributed. Label parameters are now in a structure
+called Label, to which strings are implicitly cast, and which can be
+rotated and shifted with a transform. Automatic sizing under picture
+transformation was fixed. A bug in the simplex method was fixed. Lattice
+and Gouraud shading were added. An array append method, virtual transform
+components, and transform 6-tuple notation were added. A pen and filltype
+were added to legend. The 2d graph and palette code were cleaned up.
+An extend option was added to draw ticks across the graph for producing a
+grid. Problems with nullguide3 were fixed, the arguments of 3d rotate were
+swapped, and 3d reflections were added. A spurious papersize comment
+inserted by newer versions of dvips was removed. Pstoedit support was updated.
+
+This release introduces a few minor backward incompatibilities. Here is a
+summary of the main changes:
+
+draw("text",(0,0)--(1,1),1.0) -> draw(Label("text",1.0),(0,0)--(1,1))
+label("text",90,(0,0)) -> label(rotate(90)*"text",(0,0))
+labeldot("text",(0,0)) -> dot("text",(0,0))
+labeldot((0,0)) -> dot(Label,(0,0))
+labelbox(2mm,2mm,"text",(0,0)) -> box(Label("text",(0,0)),2mm,2mm)
+xaxis("$x$",0.5) -> xaxis(Label("$x$",0.5))
+labelxtick(1) -> xtick(Label,1)
+
+Release Notes for Version 0.83
+
+This release extends Asymptote to three dimensions. A triple type (which
+replaces the old vector type in math.asy) and a guide3 type were added,
+along with the 3D projection routines in three.asy. Three-dimensional
+arrays can now be read in line mode, using blank lines as block
+delimiters. An array pop function was added. Math mode ($ delimiters) were
+moved to within the "defaultformat" string, to allow use of non-math mode
+fonts in tick labels (by overriding the default format). A pticklabel
+option for drawing tick labels with a different pen was added. Routines
+labelxtick and labelytick were added, and the tick size and shift in xtick
+were fixed. The autoscaling of unextended axes was fixed. The xline and
+yline routines were renamed to xequals and yequals, Dot was renamed to dot,
+Cross was renamed to cross, the function "Angle(pair)" was renamed to
+"degrees(pair)", and a "Degrees(pair)" function was added to math.asy. The
+Metapost --- operator and the replacement :: for the MetaPost ... operator
+were implemented. A segmentation fault involving controls points with
+direction specifiers and a bug in "string font(pen)" were fixed. Tensions
+in straight sections of paths are now handled as in MetaPost. The -l option
+was reimplemented.
+
+Release Notes for Version 0.82
+
+Initializers for structures and general cast operators can be specified.
+Functions can be called with named (keyword) arguments, in any order.
+Rest arguments are supported. Size and aspect ratio arguments, which may
+be specified with "size", were removed from "shipout". The tick routines
+were standardized; custom tick locations and arrows on axes were implemented.
+The default frame initializer nullframe was renamed to newframe. A segmentation
+fault in the file garbage collection code and an optimization-related bug
+in fill were fixed.
+
+Unlike in the C and C++ languages, an assignment in a function argument is
+now interpreted as an assignment to a parameter of the same name in the
+function signature, not within the local scope. The command-line option -d
+may be used to check Asymptote code for cases where a named function
+argument may be mistaken for a local assignment.
+
+Release Notes for Version 0.81
+
+A guide solver bug was fixed, allowing the construction of graphs with a single
+data point. Compilation under g++-4.0.0 is now supported.
+
+Release Notes for Version 0.80
+
+A segmentation fault on the alpha (cxx) and mac platforms was fixed.
+All members of the picture structure are now deep copied.
+The latest Boehm garbage collector (version 6.5) is used by default.
+
+Release Notes for Version 0.79
+
+Types are now cached to speed up parsing. All outstanding garbage collection
+issues were addressed. The autoscaling of scaled axes was fixed.
+Another example of a secondary axis was added to the documentation.
+A Pythagorean tree example illustrates picture transforms.
+
+Release Notes for Version 0.78
+
+A binary search routine was added for sorted arrays. The handling of NAN
+values was fixed. The "checkaxis" test in graph.asy was improved.
+A problem with implicit closing of files was fixed. Minor changes were made
+to support compilation under Cygwin. A workaround for the garbage
+collection warning about repeated allocation of very large
+blocks was introduced, along with other miscellaneous garbage collection
+updates. A configuration option was added to request use of a (slower,
+multi-theaded) system version of the Boehm garbage collector.
+
+Release Notes for Version 0.77
+
+Integer arguments are now converted to real values before dividing and a real
+quotient is returned. The "quotient(int, int)" function returns the integer
+part of that result. Garbage collection has been implemented to fix memory
+leaks. A knot solving bug was fixed. Pen "plabel" vs. "p" issues were
+addressed. The eval function was renamed to map and the new eval(string)
+function was documented. The concat function can be used to concatenate two
+arrays. Complex exponential and logarithmic functions were added. The new
+function reltime can be used to compute the label position argument for draw.
+A new geometry module includes a triangle structure and functions to draw
+interior arcs of triangles and perpendicular symbols.
+
+Release Notes for Version 0.76
+
+Installation has been simplified by removing the last remaining dependency
+on the boost header files. A "plabel" argument was added to "draw" to allow
+labels and legends to use a different pen than the curve itself. The pen
+arguments in the axes routines were rearranged to be consistent with
+"draw". TeX errors in interactive mode and the TeX preamble are now
+handled properly. New functions "getstring" and "getreal" can get and
+remember user parameters. Marker frame arrays, a "Mark(int)" function,
+and "node", "value", and "slope" path computation functions were added.
+Problems with implicit scaling were addressed. The "without side-effect"
+warning was removed. An option was added to list all loaded global
+functions. The documentation of structures was improved.
+
+Release Notes for Version 0.75
+
+This release fixes a number of bugs with the new parser controller,
+including a segmentation fault with the -p option, problems with
+interactive mode, and problems reading from standard input. The graph
+module now uses a better default value of axislabelmargin for positioning
+axis labels. The put argument of the axis routines was moved to the end of
+the argument list, for consistency with draw. Convenient xline and yline
+interfaces to the axis routines were added. The definition of the
+correlation coefficient in the least squares routine was fixed, and a fit
+function was added to the 'linefit' structure. A linear interpolation (with
+endpoint extrapolation) and a binary search routine were added to math.asy.
+
+Release Notes for Version 0.74
+
+This release fixes a segmentation fault in version 0.73 and also reduces
+the default number of colors in image palettes to work around
+PostScript/PDF limitations (that can cause the manual not to print).
+
+Release Notes for Version 0.73
+
+A more efficient type-safe union was used to speed up the virtual machine
+by roughly a factor of 5. New routines "ellipse" and "labelellipse"
+were added for drawing ovals around frames and labels. The function
+"bbox(frame)" was renamed "box(frame)". These routines now prepend to
+the frame for filling with a background color; they also return the boundary
+as a guide. A workaround was added for a bug in gcc version 3.3 to
+facilitate compilation under Darwin (MacOS). Many internal coding
+improvements were made.
diff --git a/Build/source/utils/asymptote/TODO b/Build/source/utils/asymptote/TODO
new file mode 100644
index 00000000000..ae06d7a8b94
--- /dev/null
+++ b/Build/source/utils/asymptote/TODO
@@ -0,0 +1,22 @@
+Andy: split runtime.in
+
+Andy: implement operator init(A a) copy constructors.
+
+Andy and John: (if possible) automatically turn expressions with array
+sub-expressions into iteration over the array(s)
+
+Andy: Change primNull to another name (null is not primitive).
+
+Andy: Decide if we should change vm::error to em in application.cc
+
+Andy: Add info to vm to aid debugging. (Locations are a start, but we can add
+variable names, type info, stack traces).
+
+John or Andy: Add unit test for AddOps.
+
+Andy: Fix: void f(int x=blah);
+
+Andy: Clean up processData and preRun
+
+Andy: Investigate adding unicode support for identifiers, using iswalpha, mbtowc
+etc.
diff --git a/Build/source/utils/asymptote/absyn.cc b/Build/source/utils/asymptote/absyn.cc
new file mode 100644
index 00000000000..8ff3148dc2a
--- /dev/null
+++ b/Build/source/utils/asymptote/absyn.cc
@@ -0,0 +1,30 @@
+/****
+ * absyn.cc
+ * Tom Prince 2004/05/12
+ *
+ * Utility functions for syntax trees.
+ *****/
+
+#include "absyn.h"
+#include "coenv.h"
+
+namespace absyntax {
+
+void absyn::markPos(trans::coenv& e)
+{
+ e.c.markPos(getPos());
+}
+
+absyn::~absyn()
+{}
+
+void prettyindent(ostream &out, Int indent)
+{
+ for (Int i = 0; i < indent; i++) out << " ";
+}
+void prettyname(ostream &out, string name, Int indent) {
+ prettyindent(out,indent);
+ out << name << "\n";
+}
+
+} // namespace absyntax
diff --git a/Build/source/utils/asymptote/absyn.h b/Build/source/utils/asymptote/absyn.h
new file mode 100644
index 00000000000..c8b85009ec4
--- /dev/null
+++ b/Build/source/utils/asymptote/absyn.h
@@ -0,0 +1,65 @@
+/****
+ * absyn.h
+ * Andy Hammerlindl 2002/07/14
+ *
+ * Defines the basic types of abstract syntax objects using forward
+ * class declarations.
+ *****/
+
+#ifndef ABSYN_H
+#define ABSYN_H
+
+#include "common.h"
+#include "errormsg.h" // For position
+
+// Forward declaration for markPos.
+namespace trans {
+class coenv;
+}
+
+namespace absyntax {
+
+class absyn : public gc {
+protected:
+ const position pos;
+
+ void markPos(trans::coenv& c);
+
+public:
+ absyn(position pos)
+ : pos(pos) {}
+
+ virtual ~absyn();
+
+ position getPos() const
+ {
+ return pos;
+ }
+
+ virtual void prettyprint(ostream &out, Int indent) = 0;
+private: // Non-copyable
+ void operator=(const absyn&);
+ absyn(const absyn&);
+};
+
+void prettyindent(ostream &out, Int indent);
+void prettyname(ostream &out, string name, Int indent);
+
+class name;
+class ty;
+class varinit;
+class exp;
+class runnable;
+class stm;
+class dec;
+class block;
+
+typedef block file;
+
+// This is the abstract syntax tree of a file, assigned to when running
+// yyparse.
+extern file *root;
+
+}
+
+#endif
diff --git a/Build/source/utils/asymptote/access.cc b/Build/source/utils/asymptote/access.cc
new file mode 100644
index 00000000000..60aee6fa659
--- /dev/null
+++ b/Build/source/utils/asymptote/access.cc
@@ -0,0 +1,133 @@
+/*****
+ * access.cc
+ * Andy Hammerlindl 2003/12/03
+ * Describes an "access," a representation of where a variable will be
+ * stored at runtime, so that read, write, and call instructions can be
+ * made.
+ *****/
+
+#include "access.h"
+#include "frame.h"
+#include "coder.h"
+#include "callable.h"
+
+using vm::item;
+
+namespace trans {
+
+/* access */
+access::~access()
+{}
+
+/* identAccess */
+void identAccess::encode(action act, position pos, coder& e)
+{
+ if (act != CALL) {
+ access::encode(act, pos, e);
+ }
+ // else - do nothing
+}
+
+
+/* bltinAccess */
+static void bltinError(position pos)
+{
+ em.error(pos);
+ em << "built-in functions cannot be modified";
+}
+
+void bltinAccess::encode(action act, position pos, coder &e)
+{
+ switch (act) {
+ case READ:
+ e.encode(inst::constpush,(item)(vm::callable*)new vm::bfunc(f));
+ break;
+ case WRITE:
+ bltinError(pos);
+ break;
+ case CALL:
+ e.encode(inst::builtin, f);
+ break;
+ }
+}
+
+void bltinAccess::encode(action act, position pos, coder &e, frame *)
+{
+ e.encode(inst::pop);
+ encode(act, pos, e);
+}
+
+
+/* frameAccess */
+void frameAccess::encode(action act, position pos, coder &e)
+{
+ if (act == READ) {
+ if (!e.encode(f)) {
+ em.compiler(pos);
+ em << "encoding frame out of context";
+ }
+ }
+ else
+ access::encode(act, pos, e);
+}
+
+void frameAccess::encode(action act, position pos, coder &e, frame *top)
+{
+ if (act == READ) {
+ if (!e.encode(f, top)) {
+ em.compiler(pos);
+ em << "encoding frame out of context";
+ }
+ }
+ else
+ access::encode(act, pos, e, top);
+}
+
+/* localAccess */
+void localAccess::encode(action act, position pos, coder &e)
+{
+ // Get the active frame of the virtual machine.
+ frame *active = e.getFrame();
+ if (level == active) {
+ e.encode(act == WRITE ? inst::varsave : inst::varpush,
+ offset);
+ if (act == CALL)
+ e.encode(inst::popcall);
+ }
+ else {
+ // Put the parent frame (in local variable 0) on the stack.
+ e.encode(inst::varpush,0);
+
+ // Encode the access from that frame.
+ this->encode(act, pos, e, active->getParent());
+ }
+}
+
+void localAccess::encode(action act, position pos, coder &e, frame *top)
+{
+ if (e.encode(level,top)) {
+ e.encode(act == WRITE ? inst::fieldsave : inst::fieldpush,
+ offset);
+ if (act == CALL)
+ e.encode(inst::popcall);
+ }
+ else {
+ // The local variable is being used when its frame is not active.
+ em.error(pos);
+ em << "static use of dynamic variable";
+ }
+}
+
+
+void qualifiedAccess::encode(action act, position pos, coder &e)
+{
+ qualifier->encode(READ, pos, e);
+ field->encode(act, pos, e, qualifierLevel);
+}
+
+void qualifiedAccess::encode(action act, position pos, coder &e, frame *top)
+{
+ qualifier->encode(READ, pos, e, top);
+ field->encode(act, pos, e, qualifierLevel);
+}
+} // namespace trans
diff --git a/Build/source/utils/asymptote/access.h b/Build/source/utils/asymptote/access.h
new file mode 100644
index 00000000000..440ca172aef
--- /dev/null
+++ b/Build/source/utils/asymptote/access.h
@@ -0,0 +1,119 @@
+/*****
+ * access.h
+ * Andy Hammerlindl 2003/12/03
+ *
+ * Describes an "access," a representation of where a variable will be
+ * stored at runtime, so that read, write, and call instructions can be
+ * made.
+ *****/
+
+#ifndef ACCESS_H
+#define ACCESS_H
+
+#include <cassert>
+
+#include "errormsg.h"
+#include "item.h"
+#include "vm.h"
+
+namespace trans {
+
+class frame;
+class coder;
+
+enum action {
+ READ,
+ WRITE,
+ CALL
+};
+
+// These serves as the base class for the accesses.
+class access : public gc {
+protected:
+ // Generic compiler access error - if the compiler functions properly,
+ // none of these should be reachable by the user.
+ void error(position pos)
+ {
+ em.compiler(pos);
+ em << "invalid use of access";
+ }
+
+public:
+ virtual ~access() = 0;
+
+ // Encode a read/write/call of the access when nothing is on the stack.
+ virtual void encode(action, position pos, coder &)
+ {
+ error(pos);
+ }
+ // Encode a read/write/call of the access when the frame "top" is on top
+ // of the stack.
+ virtual void encode(action, position pos, coder &, frame *)
+ {
+ error(pos);
+ }
+};
+
+// This class represents identity conversions in casting.
+class identAccess : public access
+{
+ virtual void encode(action act, position, coder&);
+};
+
+// Represents a function that is implemented by a built-in C++ function.
+class bltinAccess : public access {
+ vm::bltin f;
+
+public:
+ bltinAccess(vm::bltin f)
+ : f(f) {}
+
+ void encode(action act, position pos, coder &e);
+ void encode(action act, position pos, coder &e, frame *);
+};
+
+// An access that puts a frame on the top of the stack.
+class frameAccess : public access {
+ frame *f;
+
+public:
+ frameAccess(frame *f)
+ : f(f) {}
+
+ void encode(action act, position pos, coder &e);
+ void encode(action act, position pos, coder &e, frame *top);
+};
+
+// Represents the access of a local variable.
+class localAccess : public access {
+ Int offset;
+ frame *level;
+
+public:
+ localAccess(Int offset, frame *level)
+ : offset(offset), level(level) {}
+
+ void encode(action act, position pos, coder &e);
+ void encode(action act, position pos, coder &e, frame *top);
+};
+
+class qualifiedAccess : public access {
+ // The location and frame of the record.
+ access *qualifier;
+ frame *qualifierLevel;
+
+ // The location of the field relative to the record.
+ access *field;
+
+public:
+ qualifiedAccess(access *qualifier, frame *qualifierLevel, access *field)
+ : qualifier(qualifier), qualifierLevel(qualifierLevel), field(field) {}
+
+ void encode(action act, position pos, coder &e);
+ void encode(action act, position pos, coder &e, frame *top);
+};
+
+} // namespace trans
+
+#endif // ACCESS_H
+
diff --git a/Build/source/utils/asymptote/algebra3.cc b/Build/source/utils/asymptote/algebra3.cc
new file mode 100644
index 00000000000..7dafd2d5839
--- /dev/null
+++ b/Build/source/utils/asymptote/algebra3.cc
@@ -0,0 +1,1608 @@
+/*
+
+ algebra3.cpp, algebra3.h - C++ Vector and Matrix Algebra routines
+
+ 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
+
+*/
+
+/**************************************************************************
+
+ There are three vector classes and two matrix classes: vec2, vec3,
+ vec4, mat3, and mat4.
+
+ All the standard arithmetic operations are defined, with '*'
+ for dot product of two vectors and multiplication of two matrices,
+ and '^' for cross product of two vectors.
+
+ Additional functions include length(), normalize(), homogenize for
+ vectors, and print(), set(), apply() for all classes.
+
+ There is a function transpose() for matrices, but note that it
+ does not actually change the matrix,
+
+ When multiplied with a matrix, a vector is treated as a row vector
+ if it precedes the matrix (v*M), and as a column vector if it
+ follows the matrix (M*v).
+
+ Matrices are stored in row-major form.
+
+ A vector of one dimension (2d, 3d, or 4d) can be cast to a vector
+ of a higher or lower dimension. If casting to a higher dimension,
+ the new component is set by default to 1.0, unless a value is
+ specified:
+ vec3 a(1.0, 2.0, 3.0 );
+ vec4 b( a, 4.0 ); // now b == {1.0, 2.0, 3.0, 4.0};
+ When casting to a lower dimension, the vector is homogenized in
+ the lower dimension. E.g., if a 4d {X,Y,Z,W} is cast to 3d, the
+ resulting vector is {X/W, Y/W, Z/W}. It is up to the user to
+ insure the fourth component is not zero before casting.
+
+ There are also the following function for building matrices:
+ identity2D(), translation2D(), rotation2D(),
+ scaling2D(), identity3D(), translation3D(),
+ rotation3D(), rotation3Drad(), scaling3D(),
+ perspective3D()
+
+
+ ---------------------------------------------------------------------
+
+ Author: Jean-Francois DOUEg
+ Revised: Paul Rademacher
+ Version 3.2 - Feb 1998
+ Revised: Nigel Stewart (GLUI Code Cleaning)
+
+**************************************************************************/
+
+#include "algebra3.h"
+#include <cmath>
+
+#ifdef VEC_ERROR_FATAL
+#ifndef VEC_ERROR
+#define VEC_ERROR(E) { printf( "VERROR %s\n", E ); exit(1); }
+#endif
+#else
+#ifndef VEC_ERROR
+#define VEC_ERROR(E) { printf( "VERROR %s\n", E ); }
+#endif
+#endif
+
+/****************************************************************
+ * *
+ * vec2 Member functions *
+ * *
+ ****************************************************************/
+
+/******************** vec2 CONSTRUCTORS ********************/
+
+vec2::vec2()
+{
+ n[VX] = n[VY] = 0.0;
+}
+
+vec2::vec2(float x, float y)
+{
+ n[VX] = x;
+ n[VY] = y;
+}
+
+vec2::vec2(const vec2 &v)
+{
+ n[VX] = v.n[VX];
+ n[VY] = v.n[VY];
+}
+
+vec2::vec2(const vec3 &v) // it is up to caller to avoid divide-by-zero
+{
+ n[VX] = v.n[VX]/v.n[VZ];
+ n[VY] = v.n[VY]/v.n[VZ];
+}
+
+vec2::vec2(const vec3 &v, int dropAxis)
+{
+ switch (dropAxis)
+ {
+ case VX: n[VX] = v.n[VY]; n[VY] = v.n[VZ]; break;
+ case VY: n[VX] = v.n[VX]; n[VY] = v.n[VZ]; break;
+ default: n[VX] = v.n[VX]; n[VY] = v.n[VY]; break;
+ }
+}
+
+/******************** vec2 ASSIGNMENT OPERATORS ******************/
+
+vec2 & vec2::operator=(const vec2 &v)
+{
+ n[VX] = v.n[VX];
+ n[VY] = v.n[VY];
+ return *this;
+}
+
+vec2 & vec2::operator+=(const vec2 &v)
+{
+ n[VX] += v.n[VX];
+ n[VY] += v.n[VY];
+ return *this;
+}
+
+vec2 & vec2::operator-=(const vec2 &v)
+{
+ n[VX] -= v.n[VX];
+ n[VY] -= v.n[VY];
+ return *this;
+}
+
+vec2 &vec2::operator*=(float d)
+{
+ n[VX] *= d;
+ n[VY] *= d;
+ return *this;
+}
+
+vec2 &vec2::operator/=(float d)
+{
+ float d_inv = 1.0f/d;
+ n[VX] *= d_inv;
+ n[VY] *= d_inv;
+ return *this;
+}
+
+float &vec2::operator[](int i)
+{
+ if (i < VX || i > VY)
+ //VEC_ERROR("vec2 [] operator: illegal access; index = " << i << '\n')
+ VEC_ERROR("vec2 [] operator: illegal access" );
+ return n[i];
+}
+
+const float &vec2::operator[](int i) const
+{
+ if (i < VX || i > VY)
+ //VEC_ERROR("vec2 [] operator: illegal access; index = " << i << '\n')
+ VEC_ERROR("vec2 [] operator: illegal access" );
+
+ return n[i];
+}
+
+/******************** vec2 SPECIAL FUNCTIONS ********************/
+
+float vec2::length() const
+{
+ return (float) sqrt(length2());
+}
+
+float vec2::length2() const
+{
+ return n[VX]*n[VX] + n[VY]*n[VY];
+}
+
+vec2 &vec2::normalize() // it is up to caller to avoid divide-by-zero
+{
+ *this /= length();
+ return *this;
+}
+
+vec2 &vec2::apply(V_FCT_PTR fct)
+{
+ n[VX] = (*fct)(n[VX]);
+ n[VY] = (*fct)(n[VY]);
+ return *this;
+}
+
+void vec2::set( float x, float y )
+{
+ n[VX] = x; n[VY] = y;
+}
+
+/******************** vec2 FRIENDS *****************************/
+
+vec2 operator-(const vec2 &a)
+{
+ return vec2(-a.n[VX],-a.n[VY]);
+}
+
+vec2 operator+(const vec2 &a, const vec2& b)
+{
+ return vec2(a.n[VX]+b.n[VX], a.n[VY]+b.n[VY]);
+}
+
+vec2 operator-(const vec2 &a, const vec2& b)
+{
+ return vec2(a.n[VX]-b.n[VX], a.n[VY]-b.n[VY]);
+}
+
+vec2 operator*(const vec2 &a, float d)
+{
+ return vec2(d*a.n[VX], d*a.n[VY]);
+}
+
+vec2 operator*(float d, const vec2 &a)
+{
+ return a*d;
+}
+
+vec2 operator*(const mat3 &a, const vec2 &v)
+{
+ vec3 av;
+
+ av.n[VX] = a.v[0].n[VX]*v.n[VX] + a.v[0].n[VY]*v.n[VY] + a.v[0].n[VZ];
+ av.n[VY] = a.v[1].n[VX]*v.n[VX] + a.v[1].n[VY]*v.n[VY] + a.v[1].n[VZ];
+ av.n[VZ] = a.v[2].n[VX]*v.n[VX] + a.v[2].n[VY]*v.n[VY] + a.v[2].n[VZ];
+
+ return av;
+}
+
+vec2 operator*(const vec2 &v, const mat3 &a)
+{
+ return a.transpose() * v;
+}
+
+vec3 operator*(const mat3 &a, const vec3 &v)
+{
+ vec3 av;
+
+ av.n[VX] = a.v[0].n[VX]*v.n[VX] + a.v[0].n[VY]*v.n[VY] + a.v[0].n[VZ]*v.n[VZ];
+ av.n[VY] = a.v[1].n[VX]*v.n[VX] + a.v[1].n[VY]*v.n[VY] + a.v[1].n[VZ]*v.n[VZ];
+ av.n[VZ] = a.v[2].n[VX]*v.n[VX] + a.v[2].n[VY]*v.n[VY] + a.v[2].n[VZ]*v.n[VZ];
+
+ return av;
+}
+
+vec3 operator*(const vec3 &v, const mat3 &a)
+{
+ return a.transpose() * v;
+}
+
+float operator*(const vec2 &a, const vec2 &b)
+{
+ return a.n[VX]*b.n[VX] + a.n[VY]*b.n[VY];
+}
+
+vec2 operator/(const vec2 &a, float d)
+{
+ float d_inv = 1.0f/d;
+ return vec2(a.n[VX]*d_inv, a.n[VY]*d_inv);
+}
+
+vec3 operator^(const vec2 &a, const vec2 &b)
+{
+ return vec3(0.0, 0.0, a.n[VX] * b.n[VY] - b.n[VX] * a.n[VY]);
+}
+
+int operator==(const vec2 &a, const vec2 &b)
+{
+ return (a.n[VX] == b.n[VX]) && (a.n[VY] == b.n[VY]);
+}
+
+int operator!=(const vec2 &a, const vec2 &b)
+{
+ return !(a == b);
+}
+
+/*ostream& operator << (ostream& s, vec2& v)
+{ return s << "| " << v.n[VX] << ' ' << v.n[VY] << " |"; }
+*/
+
+/*istream& operator >> (istream& s, vec2& v) {
+ vec2 v_tmp;
+ char c = ' ';
+
+ while (isspace(c))
+ s >> c;
+ // The vectors can be formatted either as x y or | x y |
+ if (c == '|') {
+ s >> v_tmp[VX] >> v_tmp[VY];
+ while (s >> c && isspace(c)) ;
+ if (c != '|')
+ ;//s.set(_bad);
+ }
+ else {
+ s.putback(c);
+ s >> v_tmp[VX] >> v_tmp[VY];
+ }
+ if (s)
+ v = v_tmp;
+ return s;
+}
+*/
+
+void swap(vec2 &a, vec2 &b)
+{
+ vec2 tmp(a);
+ a = b;
+ b = tmp;
+}
+
+vec2 min_vec(const vec2 &a, const vec2 &b)
+{
+ return vec2(MIN(a.n[VX], b.n[VX]), MIN(a.n[VY], b.n[VY]));
+}
+
+vec2 max_vec(const vec2 &a, const vec2 &b)
+{
+ return vec2(MAX(a.n[VX], b.n[VX]), MAX(a.n[VY], b.n[VY]));
+}
+
+vec2 prod(const vec2 &a, const vec2 &b)
+{
+ return vec2(a.n[VX] * b.n[VX], a.n[VY] * b.n[VY]);
+}
+
+/****************************************************************
+ * *
+ * vec3 Member functions *
+ * *
+ ****************************************************************/
+
+// CONSTRUCTORS
+
+vec3::vec3()
+{
+ n[VX] = n[VY] = n[VZ] = 0.0;
+}
+
+vec3::vec3(float x, float y, float z)
+{
+ n[VX] = x;
+ n[VY] = y;
+ n[VZ] = z;
+}
+
+vec3::vec3(const vec3 &v)
+{
+ n[VX] = v.n[VX]; n[VY] = v.n[VY]; n[VZ] = v.n[VZ];
+}
+
+vec3::vec3(const vec2 &v)
+{
+ n[VX] = v.n[VX];
+ n[VY] = v.n[VY];
+ n[VZ] = 1.0;
+}
+
+vec3::vec3(const vec2 &v, float d)
+{
+ n[VX] = v.n[VX];
+ n[VY] = v.n[VY];
+ n[VZ] = d;
+}
+
+vec3::vec3(const vec4 &v) // it is up to caller to avoid divide-by-zero
+{
+ n[VX] = v.n[VX] / v.n[VW];
+ n[VY] = v.n[VY] / v.n[VW];
+ n[VZ] = v.n[VZ] / v.n[VW];
+}
+
+vec3::vec3(const vec4 &v, int dropAxis)
+{
+ switch (dropAxis)
+ {
+ case VX: n[VX] = v.n[VY]; n[VY] = v.n[VZ]; n[VZ] = v.n[VW]; break;
+ case VY: n[VX] = v.n[VX]; n[VY] = v.n[VZ]; n[VZ] = v.n[VW]; break;
+ case VZ: n[VX] = v.n[VX]; n[VY] = v.n[VY]; n[VZ] = v.n[VW]; break;
+ default: n[VX] = v.n[VX]; n[VY] = v.n[VY]; n[VZ] = v.n[VZ]; break;
+ }
+}
+
+
+// ASSIGNMENT OPERATORS
+
+vec3 &vec3::operator=(const vec3 &v)
+{
+ n[VX] = v.n[VX];
+ n[VY] = v.n[VY];
+ n[VZ] = v.n[VZ];
+ return *this;
+}
+
+vec3 &vec3::operator+=(const vec3 &v)
+{
+ n[VX] += v.n[VX];
+ n[VY] += v.n[VY];
+ n[VZ] += v.n[VZ];
+ return *this;
+}
+
+vec3 &vec3::operator-=(const vec3& v)
+{
+ n[VX] -= v.n[VX];
+ n[VY] -= v.n[VY];
+ n[VZ] -= v.n[VZ];
+ return *this;
+}
+
+vec3 &vec3::operator*=(float d)
+{
+ n[VX] *= d;
+ n[VY] *= d;
+ n[VZ] *= d;
+ return *this;
+}
+
+vec3 &vec3::operator/=(float d)
+{
+ float d_inv = 1.0f/d;
+ n[VX] *= d_inv;
+ n[VY] *= d_inv;
+ n[VZ] *= d_inv;
+ return *this;
+}
+
+float &vec3::operator[](int i)
+{
+ if (i < VX || i > VZ)
+ //VEC_ERROR("vec3 [] operator: illegal access; index = " << i << '\n')
+ VEC_ERROR("vec3 [] operator: illegal access" );
+
+ return n[i];
+}
+
+const float &vec3::operator[](int i) const
+{
+ if (i < VX || i > VZ)
+ //VEC_ERROR("vec3 [] operator: illegal access; index = " << i << '\n')
+ VEC_ERROR("vec3 [] operator: illegal access" );
+
+ return n[i];
+}
+
+// SPECIAL FUNCTIONS
+
+float vec3::length() const
+{
+ return (float) sqrt(length2());
+}
+
+float vec3::length2() const
+{
+ return n[VX]*n[VX] + n[VY]*n[VY] + n[VZ]*n[VZ];
+}
+
+vec3 &vec3::normalize() // it is up to caller to avoid divide-by-zero
+{
+ *this /= length();
+ return *this;
+}
+
+vec3 &vec3::homogenize(void) // it is up to caller to avoid divide-by-zero
+{
+ n[VX] /= n[VZ];
+ n[VY] /= n[VZ];
+ n[VZ] = 1.0;
+ return *this;
+}
+
+vec3 &vec3::apply(V_FCT_PTR fct)
+{
+ n[VX] = (*fct)(n[VX]);
+ n[VY] = (*fct)(n[VY]);
+ n[VZ] = (*fct)(n[VZ]);
+ return *this;
+}
+
+void vec3::set(float x, float y, float z) // set vector
+{
+ n[VX] = x;
+ n[VY] = y;
+ n[VZ] = z;
+}
+
+void vec3::print(FILE *file, const char *name) const // print vector to a file
+{
+ fprintf( file, "%s: <%f, %f, %f>\n", name, n[VX], n[VY], n[VZ] );
+}
+
+// FRIENDS
+
+vec3 operator-(const vec3 &a)
+{
+ return vec3(-a.n[VX],-a.n[VY],-a.n[VZ]);
+}
+
+vec3 operator+(const vec3 &a, const vec3 &b)
+{
+ return vec3(a.n[VX]+ b.n[VX], a.n[VY] + b.n[VY], a.n[VZ] + b.n[VZ]);
+}
+
+vec3 operator-(const vec3 &a, const vec3 &b)
+{
+ return vec3(a.n[VX]-b.n[VX], a.n[VY]-b.n[VY], a.n[VZ]-b.n[VZ]);
+}
+
+vec3 operator*(const vec3 &a, float d)
+{
+ return vec3(d*a.n[VX], d*a.n[VY], d*a.n[VZ]);
+}
+
+vec3 operator*(float d, const vec3 &a)
+{
+ return a*d;
+}
+
+vec3 operator*(const mat4 &a, const vec3 &v)
+{
+ return a*vec4(v);
+}
+
+vec3 operator*(const vec3 &v, mat4 &a)
+{
+ return a.transpose()*v;
+}
+
+float operator*(const vec3 &a, const vec3 &b)
+{
+ return a.n[VX]*b.n[VX] + a.n[VY]*b.n[VY] + a.n[VZ]*b.n[VZ];
+}
+
+vec3 operator/(const vec3 &a, float d)
+{
+ float d_inv = 1.0f/d;
+ return vec3(a.n[VX]*d_inv, a.n[VY]*d_inv, a.n[VZ]*d_inv);
+}
+
+vec3 operator^(const vec3 &a, const vec3 &b)
+{
+ return
+ vec3(a.n[VY]*b.n[VZ] - a.n[VZ]*b.n[VY],
+ a.n[VZ]*b.n[VX] - a.n[VX]*b.n[VZ],
+ a.n[VX]*b.n[VY] - a.n[VY]*b.n[VX]);
+}
+
+int operator==(const vec3 &a, const vec3 &b)
+{
+ return (a.n[VX] == b.n[VX]) && (a.n[VY] == b.n[VY]) && (a.n[VZ] == b.n[VZ]);
+}
+
+int operator!=(const vec3 &a, const vec3 &b)
+{
+ return !(a == b);
+}
+
+/*ostream& operator << (ostream& s, vec3& v)
+{ return s << "| " << v.n[VX] << ' ' << v.n[VY] << ' ' << v.n[VZ] << " |"; }
+
+istream& operator >> (istream& s, vec3& v) {
+ vec3 v_tmp;
+ char c = ' ';
+
+ while (isspace(c))
+ s >> c;
+ // The vectors can be formatted either as x y z or | x y z |
+ if (c == '|') {
+ s >> v_tmp[VX] >> v_tmp[VY] >> v_tmp[VZ];
+ while (s >> c && isspace(c)) ;
+ if (c != '|')
+ ;//s.set(_bad);
+ }
+ else {
+ s.putback(c);
+ s >> v_tmp[VX] >> v_tmp[VY] >> v_tmp[VZ];
+ }
+ if (s)
+ v = v_tmp;
+ return s;
+}
+*/
+
+void swap(vec3 &a, vec3 &b)
+{
+ vec3 tmp(a);
+ a = b;
+ b = tmp;
+}
+
+vec3 min_vec(const vec3 &a, const vec3 &b)
+{
+ return vec3(
+ MIN(a.n[VX], b.n[VX]),
+ MIN(a.n[VY], b.n[VY]),
+ MIN(a.n[VZ], b.n[VZ]));
+}
+
+vec3 max_vec(const vec3 &a, const vec3 &b)
+{
+ return vec3(
+ MAX(a.n[VX], b.n[VX]),
+ MAX(a.n[VY], b.n[VY]),
+ MAX(a.n[VZ], b.n[VZ]));
+}
+
+vec3 prod(const vec3 &a, const vec3 &b)
+{
+ return vec3(a.n[VX]*b.n[VX], a.n[VY]*b.n[VY], a.n[VZ]*b.n[VZ]);
+}
+
+/****************************************************************
+ * *
+ * vec4 Member functions *
+ * *
+ ****************************************************************/
+
+// CONSTRUCTORS
+
+vec4::vec4()
+{
+ n[VX] = n[VY] = n[VZ] = 0.0;
+ n[VW] = 1.0;
+}
+
+vec4::vec4(float x, float y, float z, float w)
+{
+ n[VX] = x;
+ n[VY] = y;
+ n[VZ] = z;
+ n[VW] = w;
+}
+
+vec4::vec4(const vec4 &v)
+{
+ n[VX] = v.n[VX];
+ n[VY] = v.n[VY];
+ n[VZ] = v.n[VZ];
+ n[VW] = v.n[VW];
+}
+
+vec4::vec4(const vec3 &v)
+{
+ n[VX] = v.n[VX];
+ n[VY] = v.n[VY];
+ n[VZ] = v.n[VZ];
+ n[VW] = 1.0;
+}
+
+vec4::vec4(const vec3 &v, float d)
+{
+ n[VX] = v.n[VX];
+ n[VY] = v.n[VY];
+ n[VZ] = v.n[VZ];
+ n[VW] = d;
+}
+
+// ASSIGNMENT OPERATORS
+
+vec4 &vec4::operator=(const vec4 &v)
+{
+ n[VX] = v.n[VX];
+ n[VY] = v.n[VY];
+ n[VZ] = v.n[VZ];
+ n[VW] = v.n[VW];
+ return *this;
+}
+
+vec4 &vec4::operator+=(const vec4 &v)
+{
+ n[VX] += v.n[VX];
+ n[VY] += v.n[VY];
+ n[VZ] += v.n[VZ];
+ n[VW] += v.n[VW];
+ return *this;
+}
+
+vec4 &vec4::operator-=(const vec4 &v)
+{
+ n[VX] -= v.n[VX];
+ n[VY] -= v.n[VY];
+ n[VZ] -= v.n[VZ];
+ n[VW] -= v.n[VW];
+ return *this;
+}
+
+vec4 &vec4::operator*=(float d)
+{
+ n[VX] *= d;
+ n[VY] *= d;
+ n[VZ] *= d;
+ n[VW] *= d;
+ return *this;
+}
+
+vec4 &vec4::operator/=(float d)
+{
+ float d_inv = 1.0f/d;
+ n[VX] *= d_inv;
+ n[VY] *= d_inv;
+ n[VZ] *= d_inv;
+ n[VW] *= d_inv;
+ return *this;
+}
+
+float &vec4::operator[](int i)
+{
+ if (i < VX || i > VW)
+ //VEC_ERROR("vec4 [] operator: illegal access; index = " << i << '\n')
+ VEC_ERROR("vec4 [] operator: illegal access" );
+
+ return n[i];
+}
+
+const float &vec4::operator[](int i) const
+{
+ if (i < VX || i > VW)
+ //VEC_ERROR("vec4 [] operator: illegal access; index = " << i << '\n')
+ VEC_ERROR("vec4 [] operator: illegal access" );
+
+ return n[i];
+}
+
+// SPECIAL FUNCTIONS
+
+float vec4::length() const
+{
+ return (float) sqrt(length2());
+}
+
+float vec4::length2() const
+{
+ return n[VX]*n[VX] + n[VY]*n[VY] + n[VZ]*n[VZ] + n[VW]*n[VW];
+}
+
+vec4 &vec4::normalize() // it is up to caller to avoid divide-by-zero
+{
+ *this /= length();
+ return *this;
+}
+
+vec4 &vec4::homogenize() // it is up to caller to avoid divide-by-zero
+{
+ n[VX] /= n[VW];
+ n[VY] /= n[VW];
+ n[VZ] /= n[VW];
+ n[VW] = 1.0;
+ return *this;
+}
+
+vec4 &vec4::apply(V_FCT_PTR fct)
+{
+ n[VX] = (*fct)(n[VX]);
+ n[VY] = (*fct)(n[VY]);
+ n[VZ] = (*fct)(n[VZ]);
+ n[VW] = (*fct)(n[VW]);
+ return *this;
+}
+
+void vec4::print(FILE *file, const char *name) const // print vector to a file
+{
+ fprintf( file, "%s: <%f, %f, %f, %f>\n", name, n[VX], n[VY], n[VZ], n[VW]);
+}
+
+void vec4::set(float x, float y, float z, float a)
+{
+ n[0] = x;
+ n[1] = y;
+ n[2] = z;
+ n[3] = a;
+}
+
+
+// FRIENDS
+
+vec4 operator-(const vec4 &a)
+{
+ return vec4(-a.n[VX],-a.n[VY],-a.n[VZ],-a.n[VW]);
+}
+
+vec4 operator+(const vec4 &a, const vec4 &b)
+{
+ return vec4(
+ a.n[VX] + b.n[VX],
+ a.n[VY] + b.n[VY],
+ a.n[VZ] + b.n[VZ],
+ a.n[VW] + b.n[VW]);
+}
+
+vec4 operator-(const vec4 &a, const vec4 &b)
+{
+ return vec4(
+ a.n[VX] - b.n[VX],
+ a.n[VY] - b.n[VY],
+ a.n[VZ] - b.n[VZ],
+ a.n[VW] - b.n[VW]);
+}
+
+vec4 operator*(const vec4 &a, float d)
+{
+ return vec4(d*a.n[VX], d*a.n[VY], d*a.n[VZ], d*a.n[VW]);
+}
+
+vec4 operator*(float d, const vec4 &a)
+{
+ return a*d;
+}
+
+vec4 operator*(const mat4 &a, const vec4 &v)
+{
+ #define ROWCOL(i) \
+ a.v[i].n[0]*v.n[VX] + \
+ a.v[i].n[1]*v.n[VY] + \
+ a.v[i].n[2]*v.n[VZ] + \
+ a.v[i].n[3]*v.n[VW]
+
+ return vec4(ROWCOL(0), ROWCOL(1), ROWCOL(2), ROWCOL(3));
+
+ #undef ROWCOL
+}
+
+vec4 operator*(const vec4 &v, const mat4 &a)
+{
+ return a.transpose()*v;
+}
+
+float operator*(const vec4 &a, const vec4 &b)
+{
+ return
+ a.n[VX]*b.n[VX] +
+ a.n[VY]*b.n[VY] +
+ a.n[VZ]*b.n[VZ] +
+ a.n[VW]*b.n[VW];
+}
+
+vec4 operator/(const vec4 &a, float d)
+{
+ float d_inv = 1.0f/d;
+ return vec4(
+ a.n[VX]*d_inv,
+ a.n[VY]*d_inv,
+ a.n[VZ]*d_inv,
+ a.n[VW]*d_inv);
+}
+
+int operator==(const vec4 &a, const vec4 &b)
+{
+ return
+ (a.n[VX] == b.n[VX]) &&
+ (a.n[VY] == b.n[VY]) &&
+ (a.n[VZ] == b.n[VZ]) &&
+ (a.n[VW] == b.n[VW]);
+}
+
+int operator!=(const vec4 &a, const vec4 &b)
+{
+ return !(a == b);
+}
+
+/*ostream& operator << (ostream& s, vec4& v)
+{ return s << "| " << v.n[VX] << ' ' << v.n[VY] << ' ' << v.n[VZ] << ' '
+ << v.n[VW] << " |"; }
+
+istream& operator >> (istream& s, vec4& v) {
+ vec4 v_tmp;
+ char c = ' ';
+
+ while (isspace(c))
+ s >> c;
+ // The vectors can be formatted either as x y z w or | x y z w |
+ if (c == '|') {
+ s >> v_tmp[VX] >> v_tmp[VY] >> v_tmp[VZ] >> v_tmp[VW];
+ while (s >> c && isspace(c)) ;
+ if (c != '|')
+ ;//s.set(_bad);
+ }
+ else {
+ s.putback(c);
+ s >> v_tmp[VX] >> v_tmp[VY] >> v_tmp[VZ] >> v_tmp[VW];
+ }
+ if (s)
+ v = v_tmp;
+ return s;
+}
+*/
+
+void swap(vec4 &a, vec4 &b)
+{
+ vec4 tmp(a);
+ a = b;
+ b = tmp;
+}
+
+vec4 min_vec(const vec4 &a, const vec4 &b)
+{
+ return vec4(
+ MIN(a.n[VX], b.n[VX]),
+ MIN(a.n[VY], b.n[VY]),
+ MIN(a.n[VZ], b.n[VZ]),
+ MIN(a.n[VW], b.n[VW]));
+}
+
+vec4 max_vec(const vec4 &a, const vec4 &b)
+{
+ return vec4(
+ MAX(a.n[VX], b.n[VX]),
+ MAX(a.n[VY], b.n[VY]),
+ MAX(a.n[VZ], b.n[VZ]),
+ MAX(a.n[VW], b.n[VW]));
+}
+
+vec4 prod(const vec4 &a, const vec4 &b)
+{
+ return vec4(
+ a.n[VX] * b.n[VX],
+ a.n[VY] * b.n[VY],
+ a.n[VZ] * b.n[VZ],
+ a.n[VW] * b.n[VW]);
+}
+
+/****************************************************************
+ * *
+ * mat3 member functions *
+ * *
+ ****************************************************************/
+
+// CONSTRUCTORS
+
+mat3::mat3()
+{
+ *this = identity2D();
+}
+
+mat3::mat3(const vec3 &v0, const vec3 &v1, const vec3 &v2)
+{
+ set(v0, v1, v2);
+}
+
+mat3::mat3(const mat3 &m)
+{
+ v[0] = m.v[0];
+ v[1] = m.v[1];
+ v[2] = m.v[2];
+}
+
+// ASSIGNMENT OPERATORS
+
+mat3 &mat3::operator=(const mat3 &m)
+{
+ v[0] = m.v[0];
+ v[1] = m.v[1];
+ v[2] = m.v[2];
+ return *this;
+}
+
+mat3 &mat3::operator+=(const mat3& m)
+{
+ v[0] += m.v[0];
+ v[1] += m.v[1];
+ v[2] += m.v[2];
+ return *this;
+}
+
+mat3 &mat3::operator-=(const mat3& m)
+{
+ v[0] -= m.v[0];
+ v[1] -= m.v[1];
+ v[2] -= m.v[2];
+ return *this;
+}
+
+mat3 &mat3::operator*=(float d)
+{
+ v[0] *= d;
+ v[1] *= d;
+ v[2] *= d;
+ return *this;
+}
+
+mat3 &mat3::operator/=(float d)
+{
+ v[0] /= d;
+ v[1] /= d;
+ v[2] /= d;
+ return *this;
+}
+
+vec3 &mat3::operator[](int i)
+{
+ if (i < VX || i > VZ)
+ //VEC_ERROR("mat3 [] operator: illegal access; index = " << i << '\n')
+ VEC_ERROR("mat3 [] operator: illegal access" );
+
+ return v[i];
+}
+
+const vec3 &mat3::operator[](int i) const
+{
+ if (i < VX || i > VZ)
+ //VEC_ERROR("mat3 [] operator: illegal access; index = " << i << '\n')
+ VEC_ERROR("mat3 [] operator: illegal access" );
+
+ return v[i];
+}
+
+void mat3::set(const vec3 &v0, const vec3 &v1, const vec3 &v2)
+{
+ v[0] = v0;
+ v[1] = v1;
+ v[2] = v2;
+}
+
+// SPECIAL FUNCTIONS
+
+mat3 mat3::transpose() const
+{
+ return mat3(
+ vec3(v[0][0], v[1][0], v[2][0]),
+ vec3(v[0][1], v[1][1], v[2][1]),
+ vec3(v[0][2], v[1][2], v[2][2]));
+}
+
+mat3 mat3::inverse() const // Gauss-Jordan elimination with partial pivoting
+{
+ mat3 a(*this); // As a evolves from original mat into identity
+ mat3 b(identity2D()); // b evolves from identity into inverse(a)
+ int i, j, i1;
+
+ // Loop over cols of a from left to right, eliminating above and below diag
+ for (j=0; j<3; j++) // Find largest pivot in column j among rows j..2
+ {
+ i1 = j; // Row with largest pivot candidate
+ for (i=j+1; i<3; i++)
+ if (fabs(a.v[i].n[j]) > fabs(a.v[i1].n[j]))
+ i1 = i;
+
+ // Swap rows i1 and j in a and b to put pivot on diagonal
+ swap(a.v[i1], a.v[j]);
+ swap(b.v[i1], b.v[j]);
+
+ // Scale row j to have a unit diagonal
+ if (a.v[j].n[j]==0.)
+ VEC_ERROR("mat3::inverse: singular matrix; can't invert\n");
+
+ b.v[j] /= a.v[j].n[j];
+ a.v[j] /= a.v[j].n[j];
+
+ // Eliminate off-diagonal elems in col j of a, doing identical ops to b
+ for (i=0; i<3; i++)
+ if (i!=j)
+ {
+ b.v[i] -= a.v[i].n[j]*b.v[j];
+ a.v[i] -= a.v[i].n[j]*a.v[j];
+ }
+ }
+
+ return b;
+}
+
+mat3 &mat3::apply(V_FCT_PTR fct)
+{
+ v[VX].apply(fct);
+ v[VY].apply(fct);
+ v[VZ].apply(fct);
+ return *this;
+}
+
+
+// FRIENDS
+
+mat3 operator-(const mat3 &a)
+{
+ return mat3(-a.v[0], -a.v[1], -a.v[2]);
+}
+
+mat3 operator+(const mat3 &a, const mat3 &b)
+{
+ return mat3(a.v[0]+b.v[0], a.v[1]+b.v[1], a.v[2]+b.v[2]);
+}
+
+mat3 operator-(const mat3 &a, const mat3 &b)
+{
+ return mat3(a.v[0]-b.v[0], a.v[1]-b.v[1], a.v[2]-b.v[2]);
+}
+
+mat3 operator*(const mat3 &a, const mat3 &b)
+{
+ #define ROWCOL(i, j) \
+ a.v[i].n[0]*b.v[0][j] + a.v[i].n[1]*b.v[1][j] + a.v[i].n[2]*b.v[2][j]
+
+ return mat3(
+ vec3(ROWCOL(0,0), ROWCOL(0,1), ROWCOL(0,2)),
+ vec3(ROWCOL(1,0), ROWCOL(1,1), ROWCOL(1,2)),
+ vec3(ROWCOL(2,0), ROWCOL(2,1), ROWCOL(2,2)));
+
+ #undef ROWCOL
+}
+
+mat3 operator*(const mat3 &a, float d)
+{
+ return mat3(a.v[0]*d, a.v[1]*d, a.v[2]*d);
+}
+
+mat3 operator*(float d, const mat3 &a)
+{
+ return a*d;
+}
+
+mat3 operator/(const mat3 &a, float d)
+{
+ return mat3(a.v[0]/d, a.v[1]/d, a.v[2]/d);
+}
+
+int operator==(const mat3 &a, const mat3 &b)
+{
+ return
+ (a.v[0] == b.v[0]) &&
+ (a.v[1] == b.v[1]) &&
+ (a.v[2] == b.v[2]);
+}
+
+int operator!=(const mat3 &a, const mat3 &b)
+{
+ return !(a == b);
+}
+
+/*ostream& operator << (ostream& s, mat3& m)
+{ return s << m.v[VX] << '\n' << m.v[VY] << '\n' << m.v[VZ]; }
+
+istream& operator >> (istream& s, mat3& m) {
+ mat3 m_tmp;
+
+ s >> m_tmp[VX] >> m_tmp[VY] >> m_tmp[VZ];
+ if (s)
+ m = m_tmp;
+ return s;
+}
+*/
+
+void swap(mat3 &a, mat3 &b)
+{
+ mat3 tmp(a);
+ a = b;
+ b = tmp;
+}
+
+void mat3::print(FILE *file, const char *name) const
+{
+ int i, j;
+
+ fprintf( stderr, "%s:\n", name );
+
+ for( i = 0; i < 3; i++ )
+ {
+ fprintf( stderr, " " );
+ for( j = 0; j < 3; j++ )
+ {
+ fprintf( stderr, "%f ", v[i][j] );
+ }
+ fprintf( stderr, "\n" );
+ }
+}
+
+
+
+/****************************************************************
+ * *
+ * mat4 member functions *
+ * *
+ ****************************************************************/
+
+// CONSTRUCTORS
+
+mat4::mat4()
+{
+ *this = identity3D();
+}
+
+mat4::mat4(const vec4& v0, const vec4& v1, const vec4& v2, const vec4& v3)
+{
+ v[0] = v0;
+ v[1] = v1;
+ v[2] = v2;
+ v[3] = v3;
+}
+
+mat4::mat4(const mat4 &m)
+{
+ v[0] = m.v[0];
+ v[1] = m.v[1];
+ v[2] = m.v[2];
+ v[3] = m.v[3];
+}
+
+mat4::mat4(
+ float a00, float a01, float a02, float a03,
+ float a10, float a11, float a12, float a13,
+ float a20, float a21, float a22, float a23,
+ float a30, float a31, float a32, float a33 )
+{
+ v[0][0] = a00; v[0][1] = a01; v[0][2] = a02; v[0][3] = a03;
+ v[1][0] = a10; v[1][1] = a11; v[1][2] = a12; v[1][3] = a13;
+ v[2][0] = a20; v[2][1] = a21; v[2][2] = a22; v[2][3] = a23;
+ v[3][0] = a30; v[3][1] = a31; v[3][2] = a32; v[3][3] = a33;
+}
+
+// ASSIGNMENT OPERATORS
+
+mat4 &mat4::operator=(const mat4 &m)
+{
+ v[0] = m.v[0];
+ v[1] = m.v[1];
+ v[2] = m.v[2];
+ v[3] = m.v[3];
+ return *this;
+}
+
+mat4 &mat4::operator+=(const mat4 &m)
+{
+ v[0] += m.v[0];
+ v[1] += m.v[1];
+ v[2] += m.v[2];
+ v[3] += m.v[3];
+ return *this;
+}
+
+mat4 &mat4::operator-=(const mat4 &m)
+{
+ v[0] -= m.v[0];
+ v[1] -= m.v[1];
+ v[2] -= m.v[2];
+ v[3] -= m.v[3];
+ return *this;
+}
+
+mat4 &mat4::operator*=(float d)
+{
+ v[0] *= d;
+ v[1] *= d;
+ v[2] *= d;
+ v[3] *= d;
+ return *this;
+}
+
+mat4 &mat4::operator/=(float d)
+{
+ v[0] /= d;
+ v[1] /= d;
+ v[2] /= d;
+ v[3] /= d;
+ return *this;
+}
+
+vec4 &mat4::operator[](int i)
+{
+ if (i < VX || i > VW)
+ //VEC_ERROR("mat4 [] operator: illegal access; index = " << i << '\n')
+ VEC_ERROR("mat4 [] operator: illegal access" );
+ return v[i];
+}
+
+const vec4 &mat4::operator[](int i) const
+{
+ if (i < VX || i > VW)
+ //VEC_ERROR("mat4 [] operator: illegal access; index = " << i << '\n')
+ VEC_ERROR("mat4 [] operator: illegal access" );
+ return v[i];
+}
+
+// SPECIAL FUNCTIONS;
+
+mat4 mat4::transpose() const
+{
+ return mat4(
+ vec4(v[0][0], v[1][0], v[2][0], v[3][0]),
+ vec4(v[0][1], v[1][1], v[2][1], v[3][1]),
+ vec4(v[0][2], v[1][2], v[2][2], v[3][2]),
+ vec4(v[0][3], v[1][3], v[2][3], v[3][3]));
+}
+
+mat4 mat4::inverse() const // Gauss-Jordan elimination with partial pivoting
+{
+ mat4 a(*this); // As a evolves from original mat into identity
+ mat4 b(identity3D()); // b evolves from identity into inverse(a)
+ int i, j, i1;
+
+ // Loop over cols of a from left to right, eliminating above and below diag
+ for (j=0; j<4; j++) // Find largest pivot in column j among rows j..3
+ {
+ i1 = j; // Row with largest pivot candidate
+ for (i=j+1; i<4; i++)
+ if (fabs(a.v[i].n[j]) > fabs(a.v[i1].n[j]))
+ i1 = i;
+
+ // Swap rows i1 and j in a and b to put pivot on diagonal
+ swap(a.v[i1], a.v[j]);
+ swap(b.v[i1], b.v[j]);
+
+ // Scale row j to have a unit diagonal
+ if (a.v[j].n[j]==0.)
+ VEC_ERROR("mat4::inverse: singular matrix; can't invert\n");
+
+ b.v[j] /= a.v[j].n[j];
+ a.v[j] /= a.v[j].n[j];
+
+ // Eliminate off-diagonal elems in col j of a, doing identical ops to b
+ for (i=0; i<4; i++)
+ if (i!=j)
+ {
+ b.v[i] -= a.v[i].n[j]*b.v[j];
+ a.v[i] -= a.v[i].n[j]*a.v[j];
+ }
+ }
+
+ return b;
+}
+
+mat4 &mat4::apply(V_FCT_PTR fct)
+{
+ v[VX].apply(fct);
+ v[VY].apply(fct);
+ v[VZ].apply(fct);
+ v[VW].apply(fct);
+ return *this;
+}
+
+void mat4::print(FILE *file, const char *name) const
+{
+ int i, j;
+
+ fprintf( stderr, "%s:\n", name );
+
+ for( i = 0; i < 4; i++ )
+ {
+ fprintf( stderr, " " );
+ for( j = 0; j < 4; j++ )
+ {
+ fprintf( stderr, "%f ", v[i][j] );
+ }
+ fprintf( stderr, "\n" );
+ }
+}
+
+void mat4::swap_rows(int i, int j)
+{
+ vec4 t;
+
+ t = v[i];
+ v[i] = v[j];
+ v[j] = t;
+}
+
+void mat4::swap_cols(int i, int j)
+{
+ float t;
+ int k;
+
+ for (k=0; k<4; k++)
+ {
+ t = v[k][i];
+ v[k][i] = v[k][j];
+ v[k][j] = t;
+ }
+}
+
+
+// FRIENDS
+
+mat4 operator-(const mat4 &a)
+{
+ return mat4(-a.v[0],-a.v[1],-a.v[2],-a.v[3]);
+}
+
+mat4 operator+(const mat4 &a, const mat4 &b)
+{
+ return mat4(
+ a.v[0] + b.v[0],
+ a.v[1] + b.v[1],
+ a.v[2] + b.v[2],
+ a.v[3] + b.v[3]);
+}
+
+mat4 operator-(const mat4 &a, const mat4 &b)
+{
+ return mat4(
+ a.v[0] - b.v[0],
+ a.v[1] - b.v[1],
+ a.v[2] - b.v[2],
+ a.v[3] - b.v[3]);
+}
+
+mat4 operator*(const mat4 &a, const mat4 &b)
+{
+ #define ROWCOL(i, j) \
+ a.v[i].n[0]*b.v[0][j] + \
+ a.v[i].n[1]*b.v[1][j] + \
+ a.v[i].n[2]*b.v[2][j] + \
+ a.v[i].n[3]*b.v[3][j]
+
+ return mat4(
+ vec4(ROWCOL(0,0), ROWCOL(0,1), ROWCOL(0,2), ROWCOL(0,3)),
+ vec4(ROWCOL(1,0), ROWCOL(1,1), ROWCOL(1,2), ROWCOL(1,3)),
+ vec4(ROWCOL(2,0), ROWCOL(2,1), ROWCOL(2,2), ROWCOL(2,3)),
+ vec4(ROWCOL(3,0), ROWCOL(3,1), ROWCOL(3,2), ROWCOL(3,3))
+ );
+
+ #undef ROWCOL
+}
+
+mat4 operator*(const mat4 &a, float d)
+{
+ return mat4(a.v[0]*d, a.v[1]*d, a.v[2]*d, a.v[3]*d);
+}
+
+mat4 operator*(float d, const mat4 &a)
+{
+ return a*d;
+}
+
+mat4 operator/(const mat4 &a, float d)
+{
+ return mat4(a.v[0]/d, a.v[1]/d, a.v[2]/d, a.v[3]/d);
+}
+
+int operator==(const mat4 &a, const mat4 &b)
+{
+ return
+ (a.v[0] == b.v[0]) &&
+ (a.v[1] == b.v[1]) &&
+ (a.v[2] == b.v[2]) &&
+ (a.v[3] == b.v[3]);
+}
+
+int operator!=(const mat4 &a, const mat4 &b)
+{
+ return !(a == b);
+}
+
+/*ostream& operator << (ostream& s, mat4& m)
+{ return s << m.v[VX] << '\n' << m.v[VY] << '\n' << m.v[VZ] << '\n' << m.v[VW]; }
+
+istream& operator >> (istream& s, mat4& m)
+{
+ mat4 m_tmp;
+
+ s >> m_tmp[VX] >> m_tmp[VY] >> m_tmp[VZ] >> m_tmp[VW];
+ if (s)
+ m = m_tmp;
+ return s;
+}
+*/
+
+void swap(mat4 &a, mat4 &b)
+{
+ mat4 tmp(a);
+ a = b;
+ b = tmp;
+}
+
+/****************************************************************
+ * *
+ * 2D functions and 3D functions *
+ * *
+ ****************************************************************/
+
+mat3 identity2D()
+{
+ return mat3(
+ vec3(1.0, 0.0, 0.0),
+ vec3(0.0, 1.0, 0.0),
+ vec3(0.0, 0.0, 1.0));
+}
+
+mat3 translation2D(const vec2 &v)
+{
+ return mat3(
+ vec3(1.0, 0.0, v[VX]),
+ vec3(0.0, 1.0, v[VY]),
+ vec3(0.0, 0.0, 1.0));
+}
+
+mat3 rotation2D(const vec2 &Center, float angleDeg)
+{
+ float angleRad = (float) (angleDeg * M_PI / 180.0);
+ float c = (float) cos(angleRad);
+ float s = (float) sin(angleRad);
+
+ return mat3(
+ vec3(c, -s, Center[VX] * (1.0f-c) + Center[VY] * s),
+ vec3(s, c, Center[VY] * (1.0f-c) - Center[VX] * s),
+ vec3(0.0, 0.0, 1.0));
+}
+
+mat3 scaling2D(const vec2 &scaleVector)
+{
+ return mat3(
+ vec3(scaleVector[VX], 0.0, 0.0),
+ vec3(0.0, scaleVector[VY], 0.0),
+ vec3(0.0, 0.0, 1.0));
+}
+
+mat4 identity3D()
+{
+ return mat4(
+ vec4(1.0, 0.0, 0.0, 0.0),
+ vec4(0.0, 1.0, 0.0, 0.0),
+ vec4(0.0, 0.0, 1.0, 0.0),
+ vec4(0.0, 0.0, 0.0, 1.0));
+}
+
+mat4 translation3D(const vec3 &v)
+{
+ return mat4(
+ vec4(1.0, 0.0, 0.0, v[VX]),
+ vec4(0.0, 1.0, 0.0, v[VY]),
+ vec4(0.0, 0.0, 1.0, v[VZ]),
+ vec4(0.0, 0.0, 0.0, 1.0));
+}
+
+mat4 rotation3D(const vec3 &Axis, float angleDeg)
+{
+ float angleRad = (float) (angleDeg * M_PI / 180.0);
+ float c = (float) cos(angleRad);
+ float s = (float) sin(angleRad);
+ float t = 1.0f - c;
+
+ vec3 axis(Axis);
+ axis.normalize();
+
+ return mat4(
+ vec4(t * axis[VX] * axis[VX] + c,
+ t * axis[VX] * axis[VY] - s * axis[VZ],
+ t * axis[VX] * axis[VZ] + s * axis[VY],
+ 0.0),
+ vec4(t * axis[VX] * axis[VY] + s * axis[VZ],
+ t * axis[VY] * axis[VY] + c,
+ t * axis[VY] * axis[VZ] - s * axis[VX],
+ 0.0),
+ vec4(t * axis[VX] * axis[VZ] - s * axis[VY],
+ t * axis[VY] * axis[VZ] + s * axis[VX],
+ t * axis[VZ] * axis[VZ] + c,
+ 0.0),
+ vec4(0.0, 0.0, 0.0, 1.0));
+}
+
+mat4 rotation3Drad(const vec3 &Axis, float angleRad)
+{
+ float c = (float) cos(angleRad);
+ float s = (float) sin(angleRad);
+ float t = 1.0f - c;
+
+ vec3 axis(Axis);
+ axis.normalize();
+
+ return mat4(
+ vec4(t * axis[VX] * axis[VX] + c,
+ t * axis[VX] * axis[VY] - s * axis[VZ],
+ t * axis[VX] * axis[VZ] + s * axis[VY],
+ 0.0),
+ vec4(t * axis[VX] * axis[VY] + s * axis[VZ],
+ t * axis[VY] * axis[VY] + c,
+ t * axis[VY] * axis[VZ] - s * axis[VX],
+ 0.0),
+ vec4(t * axis[VX] * axis[VZ] - s * axis[VY],
+ t * axis[VY] * axis[VZ] + s * axis[VX],
+ t * axis[VZ] * axis[VZ] + c,
+ 0.0),
+ vec4(0.0, 0.0, 0.0, 1.0));
+}
+
+mat4 scaling3D(const vec3 &scaleVector)
+{
+ return mat4(
+ vec4(scaleVector[VX], 0.0, 0.0, 0.0),
+ vec4(0.0, scaleVector[VY], 0.0, 0.0),
+ vec4(0.0, 0.0, scaleVector[VZ], 0.0),
+ vec4(0.0, 0.0, 0.0, 1.0));
+}
+
+mat4 perspective3D(float d)
+{
+ return mat4(
+ vec4(1.0f, 0.0f, 0.0f, 0.0f),
+ vec4(0.0f, 1.0f, 0.0f, 0.0f),
+ vec4(0.0f, 0.0f, 1.0f, 0.0f),
+ vec4(0.0f, 0.0f, 1.0f/d, 0.0f));
+}
diff --git a/Build/source/utils/asymptote/algebra3.h b/Build/source/utils/asymptote/algebra3.h
new file mode 100644
index 00000000000..67b07737f3c
--- /dev/null
+++ b/Build/source/utils/asymptote/algebra3.h
@@ -0,0 +1,484 @@
+/*
+
+ algebra3.cc, algebra3.h - C++ Vector and Matrix Algebra routines
+
+ 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
+
+*/
+
+/**************************************************************************
+
+ There are three vector classes and two matrix classes: vec2, vec3,
+ vec4, mat3, and mat4.
+
+ All the standard arithmetic operations are defined, with '*'
+ for dot product of two vectors and multiplication of two matrices,
+ and '^' for cross product of two vectors.
+
+ Additional functions include length(), normalize(), homogenize for
+ vectors, and print(), set(), apply() for all classes.
+
+ There is a function transpose() for matrices, but note that it
+ does not actually change the matrix,
+
+ When multiplied with a matrix, a vector is treated as a row vector
+ if it precedes the matrix (v*M), and as a column vector if it
+ follows the matrix (M*v).
+
+ Matrices are stored in row-major form.
+
+ A vector of one dimension (2d, 3d, or 4d) can be cast to a vector
+ of a higher or lower dimension. If casting to a higher dimension,
+ the new component is set by default to 1.0, unless a value is
+ specified:
+ vec3 a(1.0, 2.0, 3.0 );
+ vec4 b( a, 4.0 ); // now b == {1.0, 2.0, 3.0, 4.0};
+ When casting to a lower dimension, the vector is homogenized in
+ the lower dimension. E.g., if a 4d {X,Y,Z,W} is cast to 3d, the
+ resulting vector is {X/W, Y/W, Z/W}. It is up to the user to
+ insure the fourth component is not zero before casting.
+
+ There are also the following function for building matrices:
+ identity2D(), translation2D(), rotation2D(),
+ scaling2D(), identity3D(), translation3D(),
+ rotation3D(), rotation3Drad(), scaling3D(),
+ perspective3D()
+
+ NOTE: When compiling for Windows, include this file first, to avoid
+ certain name conflicts
+
+ ---------------------------------------------------------------------
+
+ Author: Jean-Francois DOUEg
+ Revised: Paul Rademacher
+ Version 3.2 - Feb 1998
+ Revised: Nigel Stewart (GLUI Code Cleaning)
+
+**************************************************************************/
+
+#ifndef GLUI_ALGEBRA3_H
+#define GLUI_ALGEBRA3_H
+
+#include <cmath>
+#include <cstdio>
+#include <cstdlib>
+
+#ifndef MAX
+#define MAX(a,b) ((a)>(b) ? (a) : (b))
+#define MIN(a,b) ((a)<(b) ? (a) : (b))
+#endif
+
+#define DEG2RAD(x) ((x)/180.0*M_PI)
+#define RAD2DEG(x) ((x)/M_PI*180.0)
+#define FUDGE .00001
+
+// this line defines a new type: pointer to a function which returns a
+// float and takes as argument a float
+typedef float (*V_FCT_PTR)(float);
+
+class vec2;
+class vec3;
+class vec4;
+class mat3;
+class mat4;
+
+#ifndef M_PI
+#define M_PI 3.141592654
+#endif
+
+enum {VX, VY, VZ, VW}; // axes
+enum {PA, PB, PC, PD}; // planes
+enum {RED, GREEN, BLUE, ALPHA}; // colors
+enum {KA, KD, KS, ES}; // phong coefficients
+
+/****************************************************************
+ * *
+ * 2D Vector *
+ * *
+ ****************************************************************/
+
+class vec2
+{
+ friend class vec3;
+
+protected:
+
+ float n[2];
+
+public:
+
+ // Constructors
+
+ vec2();
+ vec2(float x, float y);
+ vec2(const vec2 &v); // copy constructor
+ vec2(const vec3 &v); // cast v3 to v2
+ vec2(const vec3 &v, int dropAxis); // cast v3 to v2
+
+ // Assignment operators
+
+ vec2 &operator = (const vec2 &v); // assignment of a vec2
+ vec2 &operator += (const vec2 &v); // incrementation by a vec2
+ vec2 &operator -= (const vec2 &v); // decrementation by a vec2
+ vec2 &operator *= (float d); // multiplication by a constant
+ vec2 &operator /= (float d); // division by a constant
+
+ // special functions
+
+ float length() const; // length of a vec2
+ float length2() const; // squared length of a vec2
+ vec2 &normalize(); // normalize a vec2
+ vec2 &apply(V_FCT_PTR fct); // apply a func. to each component
+ void set(float x, float y); // set vector
+
+ float &operator [] (int i); // indexing
+ const float &operator [] (int i) const; // indexing
+
+ // friends
+
+ friend vec2 operator - (const vec2 &v); // -v1
+ friend vec2 operator + (const vec2 &a, const vec2 &b); // v1 + v2
+ friend vec2 operator - (const vec2 &a, const vec2 &b); // v1 - v2
+ friend vec2 operator * (const vec2 &a, float d); // v1 * 3.0
+ friend vec2 operator * (float d, const vec2 &a); // 3.0 * v1
+ friend vec2 operator * (const mat3 &a, const vec2 &v); // M . v
+ friend vec2 operator * (const vec2 &v, const mat3 &a); // v . M
+ friend float operator * (const vec2 &a, const vec2 &b); // dot product
+ friend vec2 operator / (const vec2 &a, float d); // v1 / 3.0
+ friend vec3 operator ^ (const vec2 &a, const vec2 &b); // cross product
+ friend int operator == (const vec2 &a, const vec2 &b); // v1 == v2 ?
+ friend int operator != (const vec2 &a, const vec2 &b); // v1 != v2 ?
+ //friend ostream& operator << (ostream& s, vec2& v); // output to stream
+ //friend istream& operator >> (istream& s, vec2& v); // input from strm.
+ friend void swap(vec2 &a, vec2 &b); // swap v1 & v2
+ friend vec2 min_vec(const vec2 &a, const vec2 &b); // min(v1, v2)
+ friend vec2 max_vec(const vec2 &a, const vec2 &b); // max(v1, v2)
+ friend vec2 prod (const vec2 &a, const vec2 &b); // term by term *
+};
+
+/****************************************************************
+ * *
+ * 3D Vector *
+ * *
+ ****************************************************************/
+
+class vec3
+{
+ friend class vec2;
+ friend class vec4;
+ friend class mat3;
+
+protected:
+
+ float n[3];
+
+public:
+
+ // Constructors
+
+ vec3();
+ vec3(float x, float y, float z);
+ vec3(const vec3 &v); // copy constructor
+ vec3(const vec2 &v); // cast v2 to v3
+ vec3(const vec2 &v, float d); // cast v2 to v3
+ vec3(const vec4 &v); // cast v4 to v3
+ vec3(const vec4 &v, int dropAxis); // cast v4 to v3
+
+ // Assignment operators
+
+ vec3 &operator = (const vec3 &v); // assignment of a vec3
+ vec3 &operator += (const vec3 &v); // incrementation by a vec3
+ vec3 &operator -= (const vec3 &v); // decrementation by a vec3
+ vec3 &operator *= (float d); // multiplication by a constant
+ vec3 &operator /= (float d); // division by a constant
+
+ // special functions
+
+ float length() const; // length of a vec3
+ float length2() const; // squared length of a vec3
+ vec3& normalize(); // normalize a vec3
+ vec3& homogenize(); // homogenize (div by Z)
+ vec3& apply(V_FCT_PTR fct); // apply a func. to each component
+ void set(float x, float y, float z); // set vector
+
+ void print(FILE *file, const char *name) const; // print vector to a file
+
+
+ float &operator [] (int i); // indexing
+ const float &operator [] (int i) const; // indexing
+
+ // friends
+
+ friend vec3 operator - (const vec3 &v); // -v1
+ friend vec3 operator + (const vec3 &a, const vec3 &b); // v1 + v2
+ friend vec3 operator - (const vec3 &a, const vec3 &b); // v1 - v2
+ friend vec3 operator * (const vec3 &a, float d); // v1 * 3.0
+ friend vec3 operator * (float d, const vec3 &a); // 3.0 * v1
+ friend vec3 operator * (const mat4 &a, const vec3 &v); // M . v
+ friend vec3 operator * (const vec3 &v, const mat4 &a); // v . M
+ friend float operator * (const vec3 &a, const vec3 &b); // dot product
+ friend vec3 operator / (const vec3 &a, float d); // v1 / 3.0
+ friend vec3 operator ^ (const vec3 &a, const vec3 &b); // cross product
+ friend int operator == (const vec3 &a, const vec3 &b); // v1 == v2 ?
+ friend int operator != (const vec3 &a, const vec3 &b); // v1 != v2 ?
+ //friend ostream& operator << (ostream& s, vec3& v); // output to stream
+ //friend istream& operator >> (istream& s, vec3& v); // input from strm.
+ friend void swap(vec3 &a, vec3 &b); // swap v1 & v2
+ friend vec3 min_vec(const vec3 &a, const vec3 &b); // min(v1, v2)
+ friend vec3 max_vec(const vec3 &a, const vec3 &b); // max(v1, v2)
+ friend vec3 prod(const vec3 &a, const vec3 &b); // term by term *
+
+ // necessary friend declarations
+
+ friend vec2 operator * (const mat3 &a, const vec2 &v); // linear transform
+ friend vec3 operator * (const mat3 &a, const vec3 &v); // linear transform
+ friend mat3 operator * (const mat3 &a, const mat3 &b); // matrix 3 product
+};
+
+/****************************************************************
+ * *
+ * 4D Vector *
+ * *
+ ****************************************************************/
+
+class vec4
+{
+ friend class vec3;
+ friend class mat4;
+
+protected:
+
+ float n[4];
+
+public:
+
+ // Constructors
+
+ vec4();
+ vec4(float x, float y, float z, float w);
+ vec4(const vec4 &v); // copy constructor
+ vec4(const vec3 &v); // cast vec3 to vec4
+ vec4(const vec3 &v, float d); // cast vec3 to vec4
+
+ // Assignment operators
+
+ vec4 &operator = (const vec4 &v); // assignment of a vec4
+ vec4 &operator += (const vec4 &v); // incrementation by a vec4
+ vec4 &operator -= (const vec4 &v); // decrementation by a vec4
+ vec4 &operator *= (float d); // multiplication by a constant
+ vec4 &operator /= (float d); // division by a constant
+
+ // special functions
+
+ float length() const; // length of a vec4
+ float length2() const; // squared length of a vec4
+ vec4 &normalize(); // normalize a vec4
+ vec4 &apply(V_FCT_PTR fct); // apply a func. to each component
+ vec4 &homogenize();
+
+ void print(FILE *file, const char *name) const; // print vector to a file
+
+ void set(float x, float y, float z, float a);
+
+ float &operator [] (int i); // indexing
+ const float &operator [] (int i) const; // indexing
+
+ // friends
+
+ friend vec4 operator - (const vec4 &v); // -v1
+ friend vec4 operator + (const vec4 &a, const vec4 &b); // v1 + v2
+ friend vec4 operator - (const vec4 &a, const vec4 &b); // v1 - v2
+ friend vec4 operator * (const vec4 &a, float d); // v1 * 3.0
+ friend vec4 operator * (float d, const vec4 &a); // 3.0 * v1
+ friend vec4 operator * (const mat4 &a, const vec4 &v); // M . v
+ friend vec4 operator * (const vec4 &v, const mat4 &a); // v . M
+ friend float operator * (const vec4 &a, const vec4 &b); // dot product
+ friend vec4 operator / (const vec4 &a, float d); // v1 / 3.0
+ friend int operator == (const vec4 &a, const vec4 &b); // v1 == v2 ?
+ friend int operator != (const vec4 &a, const vec4 &b); // v1 != v2 ?
+ //friend ostream& operator << (ostream& s, vec4& v); // output to stream
+ //friend istream& operator >> (istream& s, vec4& v); // input from strm.
+ friend void swap(vec4 &a, vec4 &b); // swap v1 & v2
+ friend vec4 min_vec(const vec4 &a, const vec4 &b); // min(v1, v2)
+ friend vec4 max_vec(const vec4 &a, const vec4 &b); // max(v1, v2)
+ friend vec4 prod (const vec4 &a, const vec4 &b); // term by term *
+
+ // necessary friend declarations
+
+ friend vec3 operator * (const mat4 &a, const vec3 &v); // linear transform
+ friend mat4 operator * (const mat4 &a, const mat4 &b); // matrix 4 product
+};
+
+/****************************************************************
+ * *
+ * 3x3 Matrix *
+ * *
+ ****************************************************************/
+
+class mat3
+{
+protected:
+
+ vec3 v[3];
+
+public:
+
+ // Constructors
+
+ mat3();
+ mat3(const vec3 &v0, const vec3 &v1, const vec3 &v2);
+ mat3(const mat3 &m);
+
+ // Assignment operators
+
+ mat3 &operator = (const mat3 &m); // assignment of a mat3
+ mat3 &operator += (const mat3 &m); // incrementation by a mat3
+ mat3 &operator -= (const mat3 &m); // decrementation by a mat3
+ mat3 &operator *= (float d); // multiplication by a constant
+ mat3 &operator /= (float d); // division by a constant
+
+ // special functions
+
+ mat3 transpose() const; // transpose
+ mat3 inverse() const; // inverse
+ mat3 &apply(V_FCT_PTR fct); // apply a func. to each element
+
+ void print(FILE *file, const char *name ) const; // print matrix to a file
+
+ void set(const vec3 &v0, const vec3 &v1, const vec3 &v2);
+
+ vec3 &operator [] (int i); // indexing
+ const vec3 &operator [] (int i) const; // indexing
+
+ // friends
+
+ friend mat3 operator - (const mat3 &a); // -m1
+ friend mat3 operator + (const mat3 &a, const mat3 &b); // m1 + m2
+ friend mat3 operator - (const mat3 &a, const mat3 &b); // m1 - m2
+ friend mat3 operator * (const mat3 &a, const mat3 &b); // m1 * m2
+ friend mat3 operator * (const mat3 &a, float d); // m1 * 3.0
+ friend mat3 operator * (float d, const mat3 &a); // 3.0 * m1
+ friend mat3 operator / (const mat3 &a, float d); // m1 / 3.0
+ friend int operator == (const mat3 &a, const mat3 &b); // m1 == m2 ?
+ friend int operator != (const mat3 &a, const mat3 &b); // m1 != m2 ?
+ //friend ostream& operator << (ostream& s, mat3& m); // output to stream
+ //friend istream& operator >> (istream& s, mat3& m); // input from strm.
+ friend void swap(mat3 &a, mat3 &b); // swap m1 & m2
+
+ // necessary friend declarations
+
+ friend vec3 operator * (const mat3 &a, const vec3 &v); // linear transform
+ friend vec2 operator * (const mat3 &a, const vec2 &v); // linear transform
+};
+
+/****************************************************************
+ * *
+ * 4x4 Matrix *
+ * *
+ ****************************************************************/
+
+class mat4
+{
+protected:
+
+ vec4 v[4];
+
+public:
+
+ // Constructors
+
+ mat4();
+ mat4(const vec4 &v0, const vec4 &v1, const vec4 &v2, const vec4 &v3);
+ mat4(const mat4 &m);
+ mat4(float a00, float a01, float a02, float a03,
+ float a10, float a11, float a12, float a13,
+ float a20, float a21, float a22, float a23,
+ float a30, float a31, float a32, float a33 );
+
+
+ // Assignment operators
+
+ mat4 &operator = (const mat4 &m); // assignment of a mat4
+ mat4 &operator += (const mat4 &m); // incrementation by a mat4
+ mat4 &operator -= (const mat4 &m); // decrementation by a mat4
+ mat4 &operator *= (float d); // multiplication by a constant
+ mat4 &operator /= (float d); // division by a constant
+
+ // special functions
+
+ mat4 transpose() const; // transpose
+ mat4 inverse() const; // inverse
+ mat4 &apply(V_FCT_PTR fct); // apply a func. to each element
+
+ void print(FILE *file, const char *name) const; // print matrix to a file
+
+ vec4 &operator [] (int i); // indexing
+ const vec4 &operator [] (int i) const; // indexing
+
+ void swap_rows(int i, int j); // swap rows i and j
+ void swap_cols(int i, int j); // swap cols i and j
+
+ // friends
+
+ friend mat4 operator - (const mat4 &a); // -m1
+ friend mat4 operator + (const mat4 &a, const mat4 &b); // m1 + m2
+ friend mat4 operator - (const mat4 &a, const mat4 &b); // m1 - m2
+ friend mat4 operator * (const mat4 &a, const mat4 &b); // m1 * m2
+ friend mat4 operator * (const mat4 &a, float d); // m1 * 4.0
+ friend mat4 operator * (float d, const mat4 &a); // 4.0 * m1
+ friend mat4 operator / (const mat4 &a, float d); // m1 / 3.0
+ friend int operator == (const mat4 &a, const mat4 &b); // m1 == m2 ?
+ friend int operator != (const mat4 &a, const mat4 &b); // m1 != m2 ?
+ //friend ostream& operator << (ostream& s, mat4& m); // output to stream
+ //friend istream& operator >> (istream& s, mat4& m); // input from strm.
+ friend void swap(mat4 &a, mat4 &b); // swap m1 & m2
+
+ // necessary friend declarations
+
+ friend vec4 operator * (const mat4 &a, const vec4 &v); // linear transform
+ //friend vec4 operator * (const vec4& v, const mat4& a); // linear transform
+ friend vec3 operator * (const mat4 &a, const vec3 &v); // linear transform
+ friend vec3 operator * (const vec3 &v, const mat4 &a); // linear transform
+};
+
+/****************************************************************
+ * *
+ * 2D functions and 3D functions *
+ * *
+ ****************************************************************/
+
+mat3 identity2D (); // identity 2D
+mat3 translation2D(const vec2 &v); // translation 2D
+mat3 rotation2D (const vec2 &Center, float angleDeg); // rotation 2D
+mat3 scaling2D (const vec2 &scaleVector); // scaling 2D
+mat4 identity3D (); // identity 3D
+mat4 translation3D(const vec3 &v); // translation 3D
+mat4 rotation3D (const vec3 &Axis, float angleDeg); // rotation 3D
+mat4 rotation3Drad(const vec3 &Axis, float angleRad); // rotation 3D
+mat4 scaling3D (const vec3 &scaleVector); // scaling 3D
+mat4 perspective3D(float d); // perspective 3D
+
+vec3 operator * (const vec3 &v, const mat3 &a);
+vec2 operator * (const vec2 &v, const mat3 &a);
+vec3 operator * (const vec3 &v, const mat4 &a);
+vec4 operator * (const vec4 &v, const mat4 &a);
+
+#endif
diff --git a/Build/source/utils/asymptote/angle.h b/Build/source/utils/asymptote/angle.h
new file mode 100644
index 00000000000..0adaa4a3d31
--- /dev/null
+++ b/Build/source/utils/asymptote/angle.h
@@ -0,0 +1,41 @@
+/*****
+ * angle.h
+ * Andy Hammerlindl 2004/04/29
+ *
+ * For degree to radian conversion and visa versa.
+ *****/
+
+#ifndef ANGLE_H
+#define ANGLE_H
+
+#include <cmath>
+#include "camperror.h"
+
+namespace camp {
+
+const double PI=acos(-1.0);
+
+const double Cpiby180=PI/180.0;
+const double C180bypi=180.0/PI;
+
+inline double radians(double theta)
+{
+ return theta*Cpiby180;
+}
+
+inline double degrees(double theta)
+{
+ return theta*C180bypi;
+}
+
+// Wrapper for atan2 with sensible (lexical) argument order and (0,0) check
+inline double angle(double x, double y)
+{
+ if(x == 0.0 && y == 0.0)
+ reportError("taking angle of (0,0)");
+ return atan2(y,x);
+}
+
+} //namespace camp
+
+#endif
diff --git a/Build/source/utils/asymptote/application.cc b/Build/source/utils/asymptote/application.cc
new file mode 100644
index 00000000000..7a146036722
--- /dev/null
+++ b/Build/source/utils/asymptote/application.cc
@@ -0,0 +1,371 @@
+/*****
+ * application.cc
+ * Andy Hammerlindl 2005/05/20
+ *
+ * An application is a matching of arguments in a call expression to formal
+ * parameters of a function. Since the language allows default arguments,
+ * keyword arguments, rest arguments, and anything else we think of, this
+ * is not a simple mapping.
+ *****/
+
+#include "application.h"
+#include "exp.h"
+#include "coenv.h"
+#include "runtime.h"
+
+using namespace types;
+using absyntax::varinit;
+using absyntax::arrayinit;
+using absyntax::arglist;
+
+namespace trans {
+
+// Lower scores are better. Packed is added onto the other qualifiers so
+// we may score both exact and casted packed arguments.
+const score FAIL=0, EXACT=1, CAST=2;
+const score PACKED=2;
+
+bool castable(env &e, formal& target, formal& source) {
+ return target.Explicit ? equivalent(target.t,source.t)
+ : e.castable(target.t,source.t, symbol::castsym);
+}
+
+score castScore(env &e, formal& target, formal& source) {
+ return equivalent(target.t,source.t) ? EXACT :
+ (!target.Explicit &&
+ e.castable(target.t,source.t, symbol::castsym)) ? CAST : FAIL;
+}
+
+defaultArg::defaultArg(types::ty *t)
+ : arg(new absyntax::callExp(position(),
+ new absyntax::varEntryExp(position(),
+ new function(t),
+ run::pushDefault)),
+ t)
+{}
+
+void restArg::transMaker(coenv &e, Int size, bool rest) {
+ // Push the number of cells and call the array maker.
+ e.c.encode(inst::intpush, size);
+ e.c.encode(inst::builtin, rest ? run::newAppendedArray :
+ run::newInitializedArray);
+}
+
+void restArg::trans(coenv &e, temp_vector &temps)
+{
+ // Push the values on the stack.
+ for (mem::list<arg *>::iterator p = inits.begin(); p != inits.end(); ++p)
+ (*p)->trans(e, temps);
+
+ if (rest)
+ rest->trans(e, temps);
+
+ transMaker(e, (Int)inits.size(), (bool)rest);
+}
+
+class maximizer {
+ app_list l;
+
+ // Tests if x is as good (or better) an application as y.
+ bool asgood(application *x, application *y) {
+ // Matches to open signatures are always worse than matches to normal
+ // signatures.
+ if (x->sig->isOpen)
+ return y->sig->isOpen;
+ else if (y->sig->isOpen)
+ return true;
+
+ assert (x->scores.size() == y->scores.size());
+
+ // Test if each score in x is no higher than the corresponding score in
+ // y.
+ return std::equal(x->scores.begin(), x->scores.end(), y->scores.begin(),
+ std::less_equal<score>());
+ }
+
+ bool better(application *x, application *y) {
+ return asgood(x,y) && !asgood(y,x);
+ }
+
+ // Add an application that has already been determined to be maximal.
+ // Remove any other applications that are now not maximal because of its
+ // addition.
+ void addMaximal(application *x) {
+ app_list::iterator y=l.begin();
+ while (y!=l.end())
+ if (better(x,*y))
+ y=l.erase(y);
+ else
+ ++y;
+ l.push_front(x);
+ }
+
+ // Tests if x is maximal.
+ bool maximal(application *x) {
+ for (app_list::iterator y=l.begin(); y!=l.end(); ++y)
+ if (better(*y,x))
+ return false;
+ return true;
+ }
+
+public:
+ maximizer() {}
+
+ void add(application *x) {
+ if (maximal(x))
+ addMaximal(x);
+ }
+
+ app_list result() {
+ return l;
+ }
+};
+
+
+void application::initRest() {
+ types::formal& f=sig->getRest();
+ if (f.t) {
+ types::array *a=dynamic_cast<types::array *>(f.t);
+ if(!a)
+ vm::error("formal rest argument must be an array");
+
+ static symbol *null=0;
+ rf=types::formal(a->celltype, null, false, f.Explicit);
+ }
+
+ if (f.t || sig->isOpen) {
+ rest=new restArg();
+ }
+}
+
+//const Int REST=-1;
+const Int NOMATCH=-2;
+
+Int application::find(symbol *name) {
+ formal_vector &f=sig->formals;
+ for (size_t i=index; i<f.size(); ++i)
+ if (f[i].name==name && args[i]==0)
+ return (Int)i;
+ return NOMATCH;
+}
+
+bool application::matchDefault() {
+ if (index==args.size())
+ return false;
+ else {
+ formal &target=getTarget();
+ if (target.defval) {
+ args[index]=new defaultArg(target.t);
+ advanceIndex();
+ return true;
+ }
+ else
+ return false;
+ }
+}
+
+bool application::matchArgumentToRest(env &e, formal &source,
+ varinit *a, size_t evalIndex)
+{
+ if (rest) {
+ score s=castScore(e, rf, source);
+ if (s!=FAIL) {
+ rest->add(seq.addArg(a, rf.t, evalIndex));
+ scores.push_back(s+PACKED);
+ return true;
+ }
+ }
+ return false;
+}
+
+bool application::matchAtSpot(size_t spot, env &e, formal &source,
+ varinit *a, size_t evalIndex)
+{
+ formal &target=sig->getFormal(spot);
+ score s=castScore(e, target, source);
+ if (s!=FAIL) {
+ // The argument matches.
+ args[spot]=seq.addArg(a, target.t, evalIndex);
+ if (spot==index)
+ advanceIndex();
+ scores.push_back(s);
+ return true;
+ }
+ else
+ return false;
+}
+
+bool application::matchArgument(env &e, formal &source,
+ varinit *a, size_t evalIndex)
+{
+ assert(source.name==0);
+
+ if (index==args.size())
+ // Try to pack into the rest array.
+ return matchArgumentToRest(e, source, a, evalIndex);
+ else
+ // Match here, or failing that use a default and try to match at the next
+ // spot.
+ return matchAtSpot(index, e, source, a, evalIndex) ||
+ (matchDefault() && matchArgument(e, source, a, evalIndex));
+}
+
+bool application::matchNamedArgument(env &e, formal &source,
+ varinit *a, size_t evalIndex)
+{
+ assert(source.name!=0);
+
+ Int spot=find(source.name);
+ return spot!=NOMATCH && matchAtSpot(spot, e, source, a, evalIndex);
+}
+
+bool application::complete() {
+ if (index==args.size())
+ return true;
+ else if (matchDefault())
+ return complete();
+ else
+ return false;
+}
+
+bool application::matchRest(env &e, formal &source, varinit *a) {
+ // First make sure all non-rest arguments are matched (matching to defaults
+ // if necessary).
+ if (complete())
+ // Match rest to rest.
+ if (rest) {
+ formal &target=sig->getRest();
+ score s=castScore(e, target, source);
+ if (s!=FAIL) {
+ rest->addRest(new arg(a, target.t));
+ scores.push_back(s);
+ return true;
+ }
+ }
+ return false;
+}
+
+bool application::matchSignature(env &e, types::signature *source,
+ arglist &al) {
+ formal_vector &f=source->formals;
+
+ // First, match all of the named (non-rest) arguments.
+ for (size_t i=0; i<f.size(); ++i)
+ if (f[i].name)
+ if (!matchNamedArgument(e, f[i], al[i].val, i))
+ return false;
+
+ // Then, the unnamed.
+ for (size_t i=0; i<f.size(); ++i)
+ if (!f[i].name)
+ if (!matchArgument(e, f[i], al[i].val, i))
+ return false;
+
+ // Then, the rest argument.
+ if (source->hasRest())
+ if (!matchRest(e, source->getRest(), al.rest.val))
+ return false;
+
+ // Fill in any remaining arguments with their defaults.
+ return complete();
+}
+
+#if 0
+application *application::matchHelper(env &e,
+ application *app,
+ signature *source)
+{
+ return app->matchSignature(e, source) ? app : 0;
+}
+
+application *application::match(env &e, signature *target, signature *source) {
+ application *app=new application(target);
+ return matchHelper(e, app, source);
+}
+#endif
+
+bool application::matchOpen(env &e, signature *source, arglist &al) {
+ assert(rest);
+
+ // Pack all given parameters into the rest argument.
+ formal_vector &f=source->formals;
+ for (size_t i = 0; i < f.size(); ++i)
+ if (al[i].name)
+ // Named arguments are not handled by open signatures.
+ return false;
+ else
+ rest->add(seq.addArg(al[i].val, f[i].t, i));
+
+ if (source->hasRest())
+ rest->addRest(new arg(al.rest.val, source->getRest().t));
+
+ return true;
+}
+
+application *application::match(env &e, function *t, signature *source,
+ arglist &al) {
+ assert(t->kind==ty_function);
+ application *app=new application(t);
+
+ if (t->getSignature()->isOpen)
+ return app->matchOpen(e, source, al) ? app : 0;
+ else
+ return app->matchSignature(e, source, al) ? app : 0;
+}
+
+void application::transArgs(coenv &e) {
+ temp_vector temps;
+
+ for(arg_vector::iterator a=args.begin(); a != args.end(); ++a)
+ (*a)->trans(e,temps);
+
+ if (rest)
+ rest->trans(e,temps);
+}
+
+app_list multimatch(env &e,
+ types::overloaded *o,
+ types::signature *source,
+ arglist &al)
+{
+ assert(source);
+
+ app_list l;
+
+ for(ty_vector::iterator t=o->sub.begin(); t!=o->sub.end(); ++t) {
+ if ((*t)->kind==ty_function) {
+ application *a=application::match(e, (function *)(*t), source, al);
+ if (a)
+ l.push_back(a);
+ }
+ }
+
+ if (l.size() > 1) {
+ // Return the most specific candidates.
+ maximizer m;
+ for (app_list::iterator x=l.begin(); x!=l.end(); ++x) {
+ assert(*x);
+ m.add(*x);
+ }
+ return m.result();
+ }
+ else
+ return l;
+}
+
+#if 0
+app_list resolve(env &e,
+ types::ty *t,
+ types::signature *source)
+{
+ if (t->kind == ty_overloaded)
+ return multimatch(e, (overloaded *)t, source);
+ else {
+ overloaded o;
+ o.add(t);
+ return multimatch(e, &o, source);
+ }
+}
+#endif
+
+} // namespace trans
diff --git a/Build/source/utils/asymptote/application.h b/Build/source/utils/asymptote/application.h
new file mode 100644
index 00000000000..994f0bb1970
--- /dev/null
+++ b/Build/source/utils/asymptote/application.h
@@ -0,0 +1,285 @@
+/*****
+ * application.h
+ * Andy Hammerlindl 2005/05/20
+ *
+ * An application is a matching of arguments in a call expression to formal
+ * parameters of a function. Since the language allows default arguments,
+ * keyword arguments, rest arguments, and anything else we think of, this
+ * is not a simple mapping.
+ *****/
+
+#ifndef APPLICATION_H
+#define APPLICATION_H
+
+#include "common.h"
+#include "types.h"
+#include "coenv.h"
+#include "exp.h"
+
+using absyntax::arglist;
+using absyntax::varinit;
+using absyntax::arrayinit;
+using absyntax::tempExp;
+
+// This is mid-way between trans and absyntax.
+namespace trans {
+
+typedef Int score;
+
+typedef mem::vector<score> score_vector;
+
+// This is used during the translation of arguments to store temporary
+// expressions for arguments that need to be translated for side-effects at a
+// certain point but used later on. The invariant maintained is that if the
+// vector has n elements, then the side-effects for the first n arguments have
+// been translated. Null is pushed onto the vector to indicate that the
+// expression was evaluated directly onto the stack, without the use of a
+// temporary.
+typedef mem::vector<tempExp *> temp_vector;
+
+struct arg : public gc {
+ virtual ~arg() {}
+ varinit *v;
+ types::ty *t;
+
+ arg(varinit *v, types::ty *t)
+ : v(v), t(t) {}
+
+ virtual void trans(coenv &e, temp_vector &) {
+ // Open signatures can match overloaded variables, but there is no way to
+ // translate the result, so report an error.
+ if (t->kind == types::ty_overloaded) {
+ em.error(v->getPos());
+ em << "overloaded argument in function call";
+ }
+ else
+ v->transToType(e, t);
+ }
+};
+
+// Pushes a default argument token on the stack as a placeholder for the
+// argument.
+struct defaultArg : public arg {
+ defaultArg(types::ty *t);
+};
+
+// Handles translation of all the arguments matched to the rest formal.
+// NOTE: This code duplicates a lot of arrayinit.
+struct restArg : public gc {
+ mem::list<arg *> inits;
+
+ arg *rest;
+public:
+ restArg()
+ : rest(0) {}
+
+ virtual ~restArg()
+ {}
+
+ // Encodes the instructions to make an array from size elements on the stack.
+ static void transMaker(coenv &e, Int size, bool rest);
+
+ void trans(coenv &e, temp_vector &temps);
+
+ void add(arg *init) {
+ inits.push_back(init);
+ }
+
+ void addRest(arg *init) {
+ rest=init;
+ }
+};
+
+
+// This class generates sequenced args, args whose side-effects occur in order
+// according to their index, regardless of the order they are called. This is
+// used to ensure left-to-right order of evaluation of keyword arguments, even
+// if they are given out of the order specified in the declaration.
+class sequencer {
+ struct sequencedArg : public arg {
+ sequencer &parent;
+ size_t i;
+ sequencedArg(varinit *v, types::ty *t, sequencer &parent, size_t i)
+ : arg(v, t), parent(parent), i(i) {}
+
+ void trans(coenv &e, temp_vector &temps) {
+ parent.trans(e, i, temps);
+ }
+ };
+
+ typedef mem::vector<sequencedArg *> sa_vector;
+ sa_vector args;
+
+ // Makes a temporary for the next argument in the sequence.
+ void alias(coenv &e, temp_vector &temps) {
+ size_t n=temps.size();
+ assert(n < args.size());
+ sequencedArg *sa=args[n];
+ assert(sa);
+
+ temps.push_back(new tempExp(e, sa->v, sa->t));
+ }
+
+ // Get in a state to translate the i-th argument, aliasing any arguments that
+ // occur before it in the sequence.
+ void advance(coenv &e, size_t i, temp_vector &temps) {
+ while (temps.size() < i)
+ alias(e,temps);
+ }
+
+ void trans(coenv &e, size_t i, temp_vector &temps) {
+ if (i < temps.size()) {
+ // Already translated, use the alias.
+ assert(temps[i]);
+ temps[i]->trans(e);
+ }
+ else {
+ // Alias earlier args if necessary.
+ advance(e, i, temps);
+
+ // Translate using the base method.
+ args[i]->arg::trans(e,temps);
+
+ // Push null to indicate the argument has been translated.
+ temps.push_back(0);
+ }
+ }
+
+public:
+ arg *addArg(varinit *v, types::ty *t, size_t i) {
+ if (args.size() <= i)
+ args.resize(i+1);
+ return args[i]=new sequencedArg(v, t, *this, i);
+ }
+};
+
+
+class application : public gc {
+ types::signature *sig;
+ types::function *t;
+
+ // Sequencer to ensure given arguments are evaluated in the proper order.
+ // Use of this sequencer means that transArgs can only be called once.
+ sequencer seq;
+
+ typedef mem::vector<arg *> arg_vector;
+ arg_vector args;
+ restArg *rest;
+
+ // Target formal to match with arguments to be packed into the rest array.
+ types::formal rf;
+
+ // During the matching of arguments to an application, this stores the index
+ // of the first unmatched formal.
+ size_t index;
+
+ // To resolve which is the best application in case of multiple matches of
+ // overloaded functions, a score is kept for every source argument matched,
+ // and an application with higher-scoring matches is chosen.
+ score_vector scores;
+
+ void initRest();
+
+ application(types::signature *sig)
+ : sig(sig),
+ t(0),
+ args(sig->formals.size()),
+ rest(0),
+ rf(0),
+ index(0)
+ { assert(sig); initRest(); }
+
+ application(types::function *t)
+ : sig(t->getSignature()),
+ t(t),
+ args(sig->formals.size()),
+ rest(0),
+ rf(0),
+ index(0)
+ { assert(sig); initRest(); }
+
+ types::formal &getTarget() {
+ return sig->getFormal(index);
+ }
+
+ // Move the index forward one, then keep going until we're at an unmatched
+ // argument.
+ void advanceIndex() {
+ do {
+ ++index;
+ } while (index < args.size() && args[index]!=0);
+ }
+
+ // Finds the first unmatched formal of the given name, returning the index.
+ // The rest formal is not tested. This function returns FAIL if no formals
+ // match.
+ Int find(symbol *name);
+
+ // Match the formal at index to its default argument (if it has one).
+ bool matchDefault();
+
+ // Match the argument to the formal indexed by spot.
+ bool matchAtSpot(size_t spot, env &e, types::formal &source,
+ varinit *a, size_t evalIndex);
+
+ // Match the argument to be packed into the rest array, if possible.
+ bool matchArgumentToRest(env &e, types::formal& source,
+ varinit *a, size_t evalIndex);
+
+ // Matches the argument to a formal in the target signature (possibly causing
+ // other formals in the target to be matched to default values), and updates
+ // the matchpoint accordingly.
+ bool matchArgument(env &e, types::formal& source,
+ varinit *a, size_t evalIndex);
+
+ // Match an argument bound to a name, as in f(index=7).
+ bool matchNamedArgument(env &e, types::formal& source,
+ varinit *a, size_t evalIndex);
+
+ // After all source formals have been matched, checks if the match is
+ // complete (filling in final default values if necessary).
+ bool complete();
+
+ // Match a rest argument in the calling expression.
+ bool matchRest(env &e, types::formal& f, varinit *a);
+
+ // Match the argument represented in signature to the target signature. On
+ // success, all of the arguments in args will be properly set up.
+ bool matchSignature(env &e, types::signature *source, arglist &al);
+
+ // Match a signature which is open, meaning that any sequence of arguments is
+ // matched.
+ bool matchOpen(env &e, signature *source, arglist &al);
+
+ friend class maximizer;
+public:
+ // Attempt to build an application given the target signature and the source
+ // signature (representing the given arguments). Return 0 if they cannot be
+ // matched.
+ static application *match(env &e,
+ types::function *t,
+ types::signature *source,
+ arglist &al);
+
+ // Translate the arguments so they appear in order on the stack in
+ // preparation for a call.
+ void transArgs(coenv &e);
+
+ types::function *getType() {
+ return t;
+ }
+};
+
+typedef mem::list<application *> app_list;
+
+// Given an overloaded list of types, determines which type to call. If none
+// are applicable, returns an empty vector, if there is ambiguity, several will
+// be returned.
+app_list multimatch(env &e,
+ types::overloaded *o,
+ types::signature *source,
+ arglist &al);
+
+} // namespace trans
+
+#endif
diff --git a/Build/source/utils/asymptote/arcball.cc b/Build/source/utils/asymptote/arcball.cc
new file mode 100644
index 00000000000..358195597ae
--- /dev/null
+++ b/Build/source/utils/asymptote/arcball.cc
@@ -0,0 +1,237 @@
+/**********************************************************************
+
+ arcball.cc
+
+
+ --------------------------------------------------
+
+ GLUI User Interface Toolkit (LGPL)
+ Copyright (c) 1998 Paul Rademacher
+ Feb 1998, Paul Rademacher (rademach@cs.unc.edu)
+ Oct 2003, Nigel Stewart - GLUI Code Cleaning
+
+ 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
+
+**********************************************************************/
+
+#include "arcball.h"
+
+#include <cstdio>
+
+
+/**************************************** Arcball::Arcball() ****/
+/* Default (void) constructor for Arcball */
+
+Arcball::Arcball()
+{
+ rot_ptr = &rot;
+ init();
+}
+
+/**************************************** Arcball::Arcball() ****/
+/* Takes as argument a mat4 to use instead of the internal rot */
+
+Arcball::Arcball(mat4 *mtx)
+{
+ rot_ptr = mtx;
+}
+
+
+/**************************************** Arcball::Arcball() ****/
+/* A constructor that accepts the screen center and arcball radius*/
+
+Arcball::Arcball(const vec2 &_center, float _radius)
+{
+ rot_ptr = &rot;
+ init();
+ set_params(_center, _radius);
+}
+
+
+/************************************** Arcball::set_params() ****/
+
+void Arcball::set_params(const vec2 &_center, float _radius)
+{
+ center = _center;
+ radius = _radius;
+}
+
+/*************************************** Arcball::init() **********/
+
+void Arcball::init()
+{
+ center.set( 0.0, 0.0 );
+ radius = 1.0;
+ q_now = quat_identity();
+ *rot_ptr = identity3D();
+ q_increment = quat_identity();
+ rot_increment = identity3D();
+ is_mouse_down = false;
+ is_spinning = false;
+ damp_factor = 0.0;
+ zero_increment = true;
+}
+
+/*********************************** Arcball::mouse_to_sphere() ****/
+
+vec3 Arcball::mouse_to_sphere(const vec2 &p)
+{
+ float mag;
+ vec2 v2 = (p - center) / radius;
+ vec3 v3( v2[0], v2[1], 0.0 );
+
+ mag = v2*v2;
+
+ if ( mag > 1.0 )
+ v3.normalize();
+ else
+ v3[VZ] = (float) sqrt( 1.0 - mag );
+
+ /* Now we add constraints - X takes precedence over Y */
+ if ( constraint_x )
+ {
+ v3 = constrain_vector( v3, vec3( 1.0, 0.0, 0.0 ));
+ }
+ else if ( constraint_y )
+ {
+ v3 = constrain_vector( v3, vec3( 0.0, 1.0, 0.0 ));
+ }
+
+ return v3;
+}
+
+
+/************************************ Arcball::constrain_vector() ****/
+
+vec3 Arcball::constrain_vector(const vec3 &vector, const vec3 &axis)
+{
+ return (vector-(vector*axis)*axis).normalize();
+}
+
+/************************************ Arcball::mouse_down() **********/
+
+void Arcball::mouse_down(int x, int y)
+{
+ down_pt.set( (float)x, (float) y );
+ is_mouse_down = true;
+
+ q_increment = quat_identity();
+ rot_increment = identity3D();
+ zero_increment = true;
+}
+
+
+/************************************ Arcball::mouse_up() **********/
+
+void Arcball::mouse_up()
+{
+ q_now = q_drag * q_now;
+ is_mouse_down = false;
+}
+
+
+/********************************** Arcball::mouse_motion() **********/
+
+void Arcball::mouse_motion(int x, int y, int shift, int ctrl, int alt)
+{
+ /* Set the X constraint if CONTROL key is pressed, Y if ALT key */
+ set_constraints( ctrl != 0, alt != 0 );
+
+ vec2 new_pt( (float)x, (float) y );
+ vec3 v0 = mouse_to_sphere( down_pt );
+ vec3 v1 = mouse_to_sphere( new_pt );
+
+ vec3 cross = v0^v1;
+
+ q_drag.set( cross, v0 * v1 );
+
+ // *rot_ptr = (q_drag * q_now).to_mat4();
+ mat4 temp = q_drag.to_mat4();
+ *rot_ptr = *rot_ptr * temp;
+
+ down_pt = new_pt;
+
+ /* We keep a copy of the current incremental rotation (= q_drag) */
+ q_increment = q_drag;
+ rot_increment = q_increment.to_mat4();
+
+ set_constraints(false, false);
+
+ if ( q_increment.s < .999999 )
+ {
+ is_spinning = true;
+ zero_increment = false;
+ }
+ else
+ {
+ is_spinning = false;
+ zero_increment = true;
+ }
+}
+
+
+/********************************** Arcball::mouse_motion() **********/
+
+void Arcball::mouse_motion(int x, int y)
+{
+ mouse_motion(x, y, 0, 0, 0);
+}
+
+
+/***************************** Arcball::set_constraints() **********/
+
+void Arcball::set_constraints(bool _constraint_x, bool _constraint_y)
+{
+ constraint_x = _constraint_x;
+ constraint_y = _constraint_y;
+}
+
+/***************************** Arcball::idle() *********************/
+
+void Arcball::idle()
+{
+ if (is_mouse_down)
+ {
+ is_spinning = false;
+ zero_increment = true;
+ }
+
+ if (damp_factor < 1.0f)
+ q_increment.scale_angle(1.0f - damp_factor);
+
+ rot_increment = q_increment.to_mat4();
+
+ if (q_increment.s >= .999999f)
+ {
+ is_spinning = false;
+ zero_increment = true;
+ }
+}
+
+
+/************************ Arcball::set_damping() *********************/
+
+void Arcball::set_damping(float d)
+{
+ damp_factor = d;
+}
+
+
+
+
+
diff --git a/Build/source/utils/asymptote/arcball.h b/Build/source/utils/asymptote/arcball.h
new file mode 100644
index 00000000000..58bc3a8c6a5
--- /dev/null
+++ b/Build/source/utils/asymptote/arcball.h
@@ -0,0 +1,95 @@
+/**********************************************************************
+
+ arcball.h
+
+ GLUI User Interface Toolkit (LGPL)
+ Copyright (c) 1998 Paul Rademacher
+ Feb 1998, Paul Rademacher (rademach@cs.unc.edu)
+ Oct 2003, Nigel Stewart - GLUI Code Cleaning
+
+
+ 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
+
+ ---------------------------------------------------------------------
+
+ A C++ class that implements the Arcball, as described by Ken
+ Shoemake in Graphics Gems IV.
+ This class takes as input mouse events (mouse down, mouse drag,
+ mouse up), and creates the appropriate quaternions and 4x4 matrices
+ to represent the rotation given by the mouse.
+
+ This class is used as follows:
+ - initialize [either in the constructor or with set_params()], the
+ center position (x,y) of the arcball on the screen, and the radius
+ - on mouse down, call mouse_down(x,y) with the mouse position
+ - as the mouse is dragged, repeatedly call mouse_motion() with the
+ current x and y positions. One can optionally pass in the current
+ state of the SHIFT, ALT, and CONTROL keys (passing zero if keys
+ are not pressed, non-zero otherwise), which constrains
+ the rotation to certain axes (X for CONTROL, Y for ALT).
+ - when the mouse button is released, call mouse_up()
+
+ Axis constraints can also be explicitly set with the
+ set_constraints() function.
+
+ The current rotation is stored in the 4x4 float matrix 'rot'.
+ It is also stored in the quaternion 'q_now'.
+
+**********************************************************************/
+
+#ifndef GLUI_ARCBALL_H
+#define GLUI_ARCBALL_H
+
+#include "algebra3.h"
+#include "quaternion.h"
+
+class Arcball
+{
+public:
+ Arcball();
+ Arcball(mat4 *mtx);
+ Arcball(const vec2 &center, float radius);
+
+ void set_damping(float d);
+ void idle();
+ void mouse_down(int x, int y);
+ void mouse_up();
+ void mouse_motion(int x, int y, int shift, int ctrl, int alt);
+ void mouse_motion(int x, int y);
+ void set_constraints(bool constrain_x, bool constrain_y);
+ void set_params(const vec2 &center, float radius);
+ void init();
+
+ vec3 constrain_vector(const vec3 &vector, const vec3 &axis);
+ vec3 mouse_to_sphere(const vec2 &p);
+
+ //public:
+ int is_mouse_down; /* true for down, false for up */
+ int is_spinning;
+ quat q_now, q_down, q_drag, q_increment;
+ vec2 down_pt;
+ mat4 rot, rot_increment;
+ mat4 *rot_ptr;
+
+ bool constraint_x, constraint_y;
+ vec2 center;
+ float radius, damp_factor;
+ int zero_increment;
+};
+
+#endif
diff --git a/Build/source/utils/asymptote/array.cc b/Build/source/utils/asymptote/array.cc
new file mode 100644
index 00000000000..e0ee2145407
--- /dev/null
+++ b/Build/source/utils/asymptote/array.cc
@@ -0,0 +1,191 @@
+/*****
+ * array.cc
+ * Andy Hammerlindl 2008/01/26
+ *
+ * Array type used by virtual machine.
+ *****/
+
+#include "array.h"
+#include "mod.h"
+
+namespace vm {
+
+inline void checkBackSlice(Int left, Int right)
+{
+ if (right < left)
+ // There isn't a clear behaviour for slices of the form A[5:2], so we don't
+ // allow them. (Atleast, not until we can figure out what the behaviour
+ // should be.)
+ vm::error("slice ends before it begins");
+}
+
+inline size_t sliceIndex(Int in, size_t len) {
+ if (in < 0)
+ // The Python behaviour here would simply be
+ // in += len;
+ // but this is inconsistent with Asymptote issuing an error for A[-1] if A
+ // is a non-cyclic array, so we also issue an error here.
+ vm::error("invalid negative index in slice of non-cyclic array");
+ if (in < 0)
+ return 0;
+ size_t index = (size_t)in;
+ return index < len ? index : len;
+}
+
+array *array::slice(Int left, Int right)
+{
+ checkBackSlice(left, right);
+
+ if (left == right)
+ return new array();
+
+ size_t length=size();
+ if (length == 0)
+ return new array();
+
+ if (cycle) {
+ size_t resultLength = (size_t)(right - left);
+ array *result = new array(resultLength);
+
+ size_t i = (size_t)imod(left, length), ri = 0;
+ while (ri < resultLength) {
+ (*result)[ri] = (*this)[i];
+
+ ++ri;
+ ++i;
+ if (i >= length)
+ i -= length;
+ }
+
+ return result;
+ }
+ else { // Non-cyclic
+ size_t l = sliceIndex(left, length);
+ size_t r = sliceIndex(right, length);
+
+ size_t resultLength = r - l;
+ array *result = new array(resultLength);
+
+ std::copy(this->begin()+l, this->begin()+r, result->begin());
+
+ return result;
+ }
+}
+
+void array::setNonBridgingSlice(size_t l, size_t r, mem::vector<item> *a)
+{
+ assert(0 <= l);
+ assert(l <= r);
+
+ size_t asize=a->size();
+ if (asize == r-l) {
+ // In place
+ std::copy(a->begin(), a->end(), this->begin()+l);
+ }
+ else if (asize < r-l) {
+ // Shrinking
+ std::copy(a->begin(), a->end(), this->begin()+l);
+ this->erase(this->begin()+l+a->size(), this->begin()+r);
+ }
+ else {
+ // Expanding
+ // NOTE: As a speed optimization, we could check capacity() to see if the
+ // array can fit the new entries, and build the new array from scratch
+ // (using swap()) if a new allocation is necessary.
+ std::copy(a->begin(), a->begin()+r-l, this->begin()+l);
+ this->insert(this->begin()+r, a->begin()+r-l, a->end());
+ }
+}
+
+void array::setBridgingSlice(size_t l, size_t r, mem::vector<item> *a)
+{
+ size_t len=this->size();
+
+ assert(r<=l);
+ assert(r+len-l == a->size());
+
+ std::copy(a->begin(), a->begin()+(len-l), this->begin()+l);
+ std::copy(a->begin()+(len-l), a->end(), this->begin());
+}
+
+void array::setSlice(Int left, Int right, array *a)
+{
+ checkBackSlice(left, right);
+
+ // If we are slicing an array into itself, slice in a copy instead, to ensure
+ // the proper result.
+ mem::vector<item> *v = (a == this) ? new mem::vector<item>(*a) : a;
+
+ size_t length=size();
+ if (cycle) {
+ if (right == left) {
+ // Notice that assigning to the slice A[A.length:A.length] is the same as
+ // assigning to the slice A[0:0] for a cyclic array.
+ size_t l = (size_t)imod(left, length);
+ setNonBridgingSlice(l, l, v);
+ }
+ else {
+ if (left + (Int) length < right)
+ vm::error("assigning to cyclic slice with repeated entries");
+
+ size_t l = (size_t)imod(left, length);
+
+ // Set r to length instead of zero, so that slices that go to the end of
+ // the array are properly treated as non-bridging.
+ size_t r = (size_t)imod(right, length);
+ if (r == 0)
+ r = length;
+
+ if (l < r)
+ setNonBridgingSlice(l, r, v);
+ else {
+ if (r + length - l == v->size())
+ setBridgingSlice(l, r, v);
+ else
+ vm::error("assignment to cyclic slice is not well defined");
+ }
+ }
+ }
+ else {
+ size_t l=sliceIndex(left, length);
+ size_t r=sliceIndex(right, length);
+
+ setNonBridgingSlice(l, r, v);
+ }
+}
+
+item copyItemToDepth(item i, Int depth)
+{
+ assert(depth >= 0);
+ if (depth == 0 || !isarray(i))
+ return i;
+ else
+ return get<array *>(i)->copyToDepth(depth);
+}
+
+array *array::copyToDepth(Int depth)
+{
+ assert(depth >= 0);
+ if (depth == 0) {
+ return this;
+ }
+ else {
+ size_t n=this->size();
+ array *a=new array(n);
+ a->cycle = this->cycle;
+
+ for (size_t i=0; i<n; ++i)
+ (*a)[i]=copyItemToDepth((*this)[i], depth-1);
+
+ return a;
+ }
+}
+
+array::array(size_t n, item i, Int depth)
+ : mem::vector<item>(n), cycle(false)
+{
+ for (size_t k=0; k<n; ++k)
+ (*this)[k] = copyItemToDepth(i, depth);
+}
+
+} // namespace vm
diff --git a/Build/source/utils/asymptote/array.h b/Build/source/utils/asymptote/array.h
new file mode 100644
index 00000000000..0fab8f5f693
--- /dev/null
+++ b/Build/source/utils/asymptote/array.h
@@ -0,0 +1,112 @@
+/*****
+ * array.h
+ * Tom Prince 2005/06/18
+ *
+ * Array type used by virtual machine.
+ *****/
+
+#ifndef ARRAY_H
+#define ARRAY_H
+
+#include "vm.h"
+#include "common.h"
+#include "item.h"
+
+namespace vm {
+
+// Arrays are vectors with push and pop functions.
+class array : public mem::vector<item> {
+ bool cycle;
+
+ void setNonBridgingSlice(size_t l, size_t r, mem::vector<item> *a);
+ void setBridgingSlice(size_t l, size_t r, mem::vector<item> *a);
+public:
+ array() : cycle(false) {}
+
+ array(size_t n)
+ : mem::vector<item>(n), cycle(false)
+ {}
+
+ array(size_t n, item i, Int depth);
+
+ void push(item i)
+ {
+ push_back(i);
+ }
+
+ item pop()
+ {
+ item i=back();
+ pop_back();
+ return i;
+ }
+
+ template <typename T>
+ T read(size_t i) const
+ {
+ return get<T>((*this)[i]);
+ }
+
+ array *slice(Int left, Int right);
+ void setSlice(Int left, Int right, array *a);
+
+ void cyclic(bool b) {
+ cycle=b;
+ }
+
+ bool cyclic() const {
+ return cycle;
+ }
+
+ array *copyToDepth(Int depth);
+};
+
+template <typename T>
+inline T read(array *a, size_t i)
+{
+ return a->array::read<T>(i);
+}
+
+template <typename T>
+inline T read(const array &a, size_t i)
+{
+ return a.array::read<T>(i);
+}
+
+inline size_t checkArray(const vm::array *a)
+{
+ if(a == 0) vm::error("dereference of null array");
+ return a->size();
+}
+
+inline void checkEqual(size_t i, size_t j) {
+ if(i == j) return;
+ ostringstream buf;
+ buf << "operation attempted on arrays of different lengths: "
+ << i << " != " << j;
+ vm::error(buf);
+}
+
+inline size_t checkArrays(const vm::array *a, const vm::array *b)
+{
+ size_t asize=checkArray(a);
+ size_t bsize=checkArray(b);
+ checkEqual(asize,bsize);
+ return asize;
+}
+
+// Tests if an item is actually an array. This needs to be defined here,
+// after the array type is declared.
+inline bool isarray(const item& it)
+{
+ return *it.kind == typeid(array);
+}
+
+// Copies an item to a depth d. If d==0 or if the item is not array, then the
+// item is just returned without copying, otherwise, the array and its
+// subarrays are copied as deeply as possible up to a depth d.
+item copyItemToDepth(item i, Int depth);
+
+} // namespace vm
+
+#endif // ARRAY_H
diff --git a/Build/source/utils/asymptote/arrayop.h b/Build/source/utils/asymptote/arrayop.h
new file mode 100644
index 00000000000..eed2d9ed4ab
--- /dev/null
+++ b/Build/source/utils/asymptote/arrayop.h
@@ -0,0 +1,410 @@
+/*****
+ * arrayop
+ * John Bowman
+ *
+ * Array operations
+ *****/
+#ifndef ARRAYOP_H
+#define ARRAYOP_H
+
+#include <typeinfo>
+
+#include "util.h"
+#include "stack.h"
+#include "array.h"
+#include "types.h"
+#include "fileio.h"
+#include "callable.h"
+#include "mathop.h"
+
+namespace run {
+
+using vm::pop;
+using vm::read;
+using vm::array;
+using camp::tab;
+
+vm::array *copyArray(vm::array *a);
+vm::array *copyArray2(vm::array *a);
+
+template<class T, class U, template <class S> class op>
+void arrayOp(vm::stack *s)
+{
+ U b=pop<U>(s);
+ array *a=pop<array*>(s);
+ size_t size=checkArray(a);
+ array *c=new array(size);
+ for(size_t i=0; i < size; i++)
+ (*c)[i]=op<T>()(read<T>(a,i),b,i);
+ s->push(c);
+}
+
+template<class T, class U, template <class S> class op>
+void opArray(vm::stack *s)
+{
+ array *a=pop<array*>(s);
+ T b=pop<T>(s);
+ size_t size=checkArray(a);
+ array *c=new array(size);
+ for(size_t i=0; i < size; i++)
+ (*c)[i]=op<U>()(b,read<U>(a,i),i);
+ s->push(c);
+}
+
+template<class T, template <class S> class op>
+void arrayArrayOp(vm::stack *s)
+{
+ array *b=pop<array*>(s);
+ array *a=pop<array*>(s);
+ size_t size=checkArrays(a,b);
+ array *c=new array(size);
+ for(size_t i=0; i < size; i++)
+ (*c)[i]=op<T>()(read<T>(a,i),read<T>(b,i),i);
+ s->push(c);
+}
+
+template<class T>
+inline void arrayNegate(vm::stack *s)
+{
+ array *a=pop<array*>(s);
+ size_t size=checkArray(a);
+ array *c=new array(size);
+ for(size_t i=0; i < size; i++)
+ (*c)[i]=-read<T>(a,i);
+ s->push(c);
+}
+
+template<>
+inline void arrayNegate<Int>(vm::stack *s)
+{
+ array *a=pop<array*>(s);
+ size_t size=checkArray(a);
+ array *c=new array(size);
+ for(size_t i=0; i < size; i++)
+ (*c)[i]=Negate(read<Int>(a,i),i);
+ s->push(c);
+}
+
+template<class T>
+void sumArray(vm::stack *s)
+{
+ array *a=pop<array*>(s);
+ size_t size=checkArray(a);
+ T sum=0;
+ for(size_t i=0; i < size; i++)
+ sum += read<T>(a,i);
+ s->push(sum);
+}
+
+extern const char *arrayempty;
+
+template<class T, template <class S> class op>
+void binopArray(vm::stack *s)
+{
+ array *a=pop<array*>(s);
+ size_t size=checkArray(a);
+ if(size == 0) vm::error(arrayempty);
+ T m=read<T>(a,0);
+ for(size_t i=1; i < size; i++)
+ m=op<T>()(m,read<T>(a,i));
+ s->push(m);
+}
+
+template<class T, template <class S> class op>
+void binopArray2(vm::stack *s)
+{
+ array *a=pop<array*>(s);
+ size_t size=checkArray(a);
+ bool empty=true;
+ T m=0;
+ for(size_t i=0; i < size; i++) {
+ array *ai=read<array*>(a,i);
+ size_t aisize=checkArray(ai);
+ if(aisize) {
+ if(empty) {
+ m=read<T>(ai,0);
+ empty=false;
+ }
+ for(size_t j=0; j < aisize; j++)
+ m=op<T>()(m,read<T>(ai,j));
+ }
+ }
+ if(empty) vm::error(arrayempty);
+ s->push(m);
+}
+
+template<class T, template <class S> class op>
+void binopArray3(vm::stack *s)
+{
+ array *a=pop<array*>(s);
+ size_t size=checkArray(a);
+ bool empty=true;
+ T m=0;
+ for(size_t i=0; i < size; i++) {
+ array *ai=read<array*>(a,i);
+ size_t aisize=checkArray(ai);
+ for(size_t j=0; j < aisize; j++) {
+ array *aij=read<array*>(ai,j);
+ size_t aijsize=checkArray(aij);
+ if(aijsize) {
+ if(empty) {
+ m=read<T>(aij,0);
+ empty=false;
+ }
+ for(size_t k=0; k < aijsize; k++) {
+ m=op<T>()(m,read<T>(aij,k));
+ }
+ }
+ }
+ }
+ if(empty) vm::error(arrayempty);
+ s->push(m);
+}
+
+template<class T>
+struct compare {
+ bool operator() (const vm::item& a, const vm::item& b)
+ {
+ return vm::get<T>(a) < vm::get<T>(b);
+ }
+};
+
+template<class T>
+void sortArray(vm::stack *s)
+{
+ array *c=copyArray(pop<array*>(s));
+ sort(c->begin(),c->end(),compare<T>());
+ s->push(c);
+}
+
+template<class T>
+struct compare2 {
+ bool operator() (const vm::item& A, const vm::item& B)
+ {
+ array *a=vm::get<array*>(A);
+ array *b=vm::get<array*>(B);
+ size_t size=a->size();
+ if(size != b->size()) return false;
+
+ for(size_t j=0; j < size; j++) {
+ if(read<T>(a,j) < read<T>(b,j)) return true;
+ if(read<T>(a,j) > read<T>(b,j)) return false;
+ }
+ return false;
+ }
+};
+
+// Sort the rows of a 2-dimensional array by the first column, breaking
+// ties with successively higher columns.
+template<class T>
+void sortArray2(vm::stack *s)
+{
+ array *c=copyArray(pop<array*>(s));
+ stable_sort(c->begin(),c->end(),compare2<T>());
+ s->push(c);
+}
+
+// Search a sorted ordered array of n elements to find an interval containing
+// a given key. Returns n-1 if the key is greater than or equal to the last
+// element, -1 if the key is less than the first element, and otherwise the
+// index corresponding to the left-hand endpoint of the matching interval.
+template<class T>
+void searchArray(vm::stack *s)
+{
+ T key=pop<T>(s);
+ array *a=pop<array*>(s);
+ Int size=(Int) a->size();
+ if(size == 0) {s->push(0); return;}
+ if(key < read<T>(a,0)) {s->push(-1); return;}
+ Int u=size-1;
+ if(key >= read<T>(a,u)) {s->push(u); return;}
+ Int l=0;
+
+ while (l < u) {
+ Int i=(l+u)/2;
+ if(read<T>(a,i) <= key && key < read<T>(a,i+1)) {s->push(i); return;}
+ if(key < read<T>(a,i)) u=i;
+ else l=i+1;
+ }
+ s->push(0);
+}
+
+extern string emptystring;
+
+void writestring(vm::stack *s);
+
+template<class T>
+void write(vm::stack *s)
+{
+ array *a=pop<array*>(s);
+ vm::callable *suffix=pop<vm::callable *>(s,NULL);
+ T first=pop<T>(s);
+ string S=pop<string>(s,emptystring);
+ vm::item it=pop(s);
+ bool defaultfile=isdefault(it);
+ camp::file *f=defaultfile ? &camp::Stdout : vm::get<camp::file*>(it);
+
+ size_t size=checkArray(a);
+ if(!f->isOpen()) return;
+ if(S != "") f->write(S);
+ f->write(first);
+ for(size_t i=0; i < size; ++i) {
+ f->write(tab);
+ f->write(read<T>(a,i));
+ }
+ if(f->text()) {
+ if(suffix) {
+ s->push(f);
+ suffix->call(s);
+ } else if(defaultfile) {
+ try {
+ f->writeline();
+ } catch (quit&) {
+ }
+ }
+ }
+}
+
+template<class T>
+void writeArray(vm::stack *s)
+{
+ array *A=pop<array*>(s);
+ array *a=pop<array*>(s);
+ string S=pop<string>(s,emptystring);
+ vm::item it=pop(s);
+ bool defaultfile=isdefault(it);
+ camp::file *f=defaultfile ? &camp::Stdout : vm::get<camp::file*>(it);
+
+ size_t asize=checkArray(a);
+ size_t Asize=checkArray(A);
+ if(f->Standard()) interact::lines=0;
+ else if(!f->isOpen()) return;
+ try {
+ if(S != "") {f->write(S); f->writeline();}
+
+ size_t i=0;
+ bool cont=true;
+ while(cont) {
+ cont=false;
+ bool first=true;
+ if(i < asize) {
+ vm::item& I=(*a)[i];
+ if(defaultfile) cout << i << ":\t";
+ if(!I.empty())
+ f->write(vm::get<T>(I));
+ cont=true;
+ first=false;
+ }
+ unsigned count=0;
+ for(size_t j=0; j < Asize; ++j) {
+ array *Aj=read<array*>(A,j);
+ size_t Ajsize=checkArray(Aj);
+ if(i < Ajsize) {
+ if(f->text()) {
+ if(first && defaultfile) cout << i << ":\t";
+ for(unsigned k=0; k <= count; ++k)
+ f->write(tab);
+ count=0;
+ }
+ vm::item& I=(*Aj)[i];
+ if(!I.empty())
+ f->write(vm::get<T>(I));
+ cont=true;
+ first=false;
+ } else count++;
+ }
+ ++i;
+ if(cont && f->text()) f->writeline();
+ }
+ } catch (quit&) {
+ }
+ f->flush();
+}
+
+template<class T>
+void writeArray2(vm::stack *s)
+{
+ array *a=pop<array*>(s);
+ camp::file *f=pop<camp::file*>(s,&camp::Stdout);
+
+ size_t size=checkArray(a);
+ if(f->Standard()) interact::lines=0;
+ else if(!f->isOpen()) return;
+
+ try {
+ for(size_t i=0; i < size; i++) {
+ vm::item& I=(*a)[i];
+ if(!I.empty()) {
+ array *ai=vm::get<array*>(I);
+ size_t aisize=checkArray(ai);
+ for(size_t j=0; j < aisize; j++) {
+ if(j > 0 && f->text()) f->write(tab);
+ vm::item& I=(*ai)[j];
+ if(!I.empty())
+ f->write(vm::get<T>(I));
+ }
+ }
+ if(f->text()) f->writeline();
+ }
+ } catch (quit&) {
+ }
+ f->flush();
+}
+
+template<class T>
+void writeArray3(vm::stack *s)
+{
+ array *a=pop<array*>(s);
+ camp::file *f=pop<camp::file*>(s,&camp::Stdout);
+
+ size_t size=checkArray(a);
+ if(f->Standard()) interact::lines=0;
+ else if(!f->isOpen()) return;
+
+ try {
+ for(size_t i=0; i < size;) {
+ vm::item& I=(*a)[i];
+ if(!I.empty()) {
+ array *ai=vm::get<array*>(I);
+ size_t aisize=checkArray(ai);
+ for(size_t j=0; j < aisize; j++) {
+ vm::item& I=(*ai)[j];
+ if(!I.empty()) {
+ array *aij=vm::get<array*>(I);
+ size_t aijsize=checkArray(aij);
+ for(size_t k=0; k < aijsize; k++) {
+ if(k > 0 && f->text()) f->write(tab);
+ vm::item& I=(*aij)[k];
+ if(!I.empty())
+ f->write(vm::get<T>(I));
+ }
+ }
+ if(f->text()) f->writeline();
+ }
+ }
+ ++i;
+ if(i < size && f->text()) f->writeline();
+ }
+ } catch (quit&) {
+ }
+ f->flush();
+}
+
+template <class T, class S, T (*func)(S)>
+void arrayFunc(vm::stack *s)
+{
+ array *a=pop<array*>(s);
+ size_t size=checkArray(a);
+ array *c=new array(size);
+ for(size_t i=0; i < size; i++)
+ (*c)[i]=func(read<S>(a,i));
+ s->push(c);
+}
+
+vm::array *Identity(Int n);
+camp::triple operator *(const vm::array& a, const camp::triple& v);
+camp::triple multshiftless(const vm::array& t, const camp::triple& v);
+
+} // namespace run
+
+#endif // ARRAYOP_H
diff --git a/Build/source/utils/asymptote/asy-keywords.el b/Build/source/utils/asymptote/asy-keywords.el
new file mode 100644
index 00000000000..0b848035b6e
--- /dev/null
+++ b/Build/source/utils/asymptote/asy-keywords.el
@@ -0,0 +1,17 @@
+;;
+;; This file is automatically generated by asy-list.pl.
+;; Changes will be overwritten.
+;;
+(defvar asy-keywords-version "1.72")
+
+(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 ))
+
+(defvar asy-type-name '(
+Braid Label Legend Rmf TreeNode abscissa arc arrowhead binarytree binarytreeNode block bool bool3 bounds bqe circle conic coord coordsys cputime ellipse file filltype frame grid3 guide horner hsv hyperbola indexedTransform int inversion key line linefit marginT marker mass object pair parabola path path3 pen picture point position projection real revolution scaleT scientific segment side slice 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 Automatic AvantGarde BBox BWRainbow BWRainbow2 Bar Bars BeginArcArrow BeginArrow BeginBar BeginDotMargin BeginMargin BeginPenMargin Blank Bookman Bottom BottomTop Bounds Break Broken BrokenLog Ceil Circle CircleBarIntervalMarker Cos Courier CrossIntervalMarker DefaultFormat DefaultLogFormat Degrees Dir DotMargin DotMargins Dotted Draw Drawline Embed EndArcArrow EndArrow EndBar EndDotMargin EndMargin EndPenMargin Fill FillDraw Floor Format Full Gaussian Gaussrand Gaussrandpair Gradient Grayscale Helvetica Hermite HookHead InOutTicks InTicks J Label Landscape Left LeftRight LeftTicks Legend Linear Link Log LogFormat Margin Margins Mark MidArcArrow MidArrow NOT NewCenturySchoolBook NoBox NoMargin NoModifier NoTicks NoTicks3 NoZero NoZeroFormat None OR OmitFormat OmitTick OutTicks Ox Oy Palatino PaletteTicks Pen PenMargin PenMargins Pentype Portrait RadialShade Rainbow Range Relative Right RightTicks Rotate Round 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 Z ZX ZXgrid ZYgrid ZapfChancery ZapfDingbats _cputime _draw _eval _image _labelpath _strokepath _texpath aCos aSin aTan abort abs accel acos acosh acot acsc add addArrow addMargins addSaveFunction addnode addnodes addpenarc addpenline addseg adjust alias align all altitude angabscissa angle 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 asec asin asinh ask assert asy asycode asydir asyfigure asyfilecode asyinclude asywrite atan atan2 atanh atbreakpoint atexit atime attach attract atupdate autoformat autoscale autoscale3 axes axes3 axialshade axis axiscoverage azimuth babel background bangles bar barmarksize barsize basealign baseline bbox beep beginclip begingroup beginpoint between bevel bezier bezierP bezierPP bezierPPP bezulate bibliography bibliographystyle binarytree binarytreeNode binomial binput bins bisector bisectorpoint bispline blend boutput box bqe breakpoint breakpoints brick buildRestoreDefaults buildRestoreThunk buildcycle bulletcolor canonical canonicalcartesiansystem cartesiansystem case1 case2 case3 cbrt cd ceil center centerToFocus centroid cevian change2 changecoordsys checkSegment checkconditionlength checker checklengths checkposition 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 cos cosh cot countIntersections cputime crop cropcode cross crossframe crosshatch crossmarksize csc csv cubicroots curabscissa curlSpecifier curpoint currentarrow currentexitfunction currentmomarrow currentpolarconicroutine curve cut cutafter cutbefore cyclic cylinder debugger deconstruct defaultdir defaultformat defaultpen defaultspline defined degenerate degrees delete deletepreamble determinant diagonal diamond diffdiv dimension dir dirSpecifier dirtime display distance divisors do_overpaint dot dotframe dotsize downcase draw drawAll drawDoubleLine drawFermion drawGhost drawGluon drawMomArrow drawPhoton drawScalar drawVertex drawVertexBox drawVertexBoxO drawVertexBoxX drawVertexO drawVertexOX drawVertexTriangle drawVertexTriangleO drawVertexX drawarrow drawarrow2 drawline drawtick duplicate elle ellipse ellipsenodesnumber embed embed3 empty enclose endScript endclip endgroup endl endpoint endpoints eof eol equation equations erase erf erfc error errorbar errorbars euler eval excenter excircle exit exitXasyMode exitfunction exp expi expm1 exradius extend extension extouch fabs factorial fermat fft fhorner figure file filecode fill filldraw filloutside fillrule filltype find finite firstcut firstframe fit fixedscaling floor flush fmdefaults fmod focusToCenter font fontcommand fontsize foot format frac frequency fromCenter fromFocus fspline functionshade gamma generate_random_backtrace generateticks gergonne getc getint getpair getreal getstring gettriple gluon gouraudshade graph graphic gray grestore grid grid3 gsave halfbox hatch hdiffdiv hermite hex histogram history hline hprojection hsv hyperbola hyperbolanodesnumber hyperlink hypot identity image incenter incentral incircle increasing incrementposition indexedTransform initXasyMode initdefaults input inradius insert inside interactive interior interp interpolate intersect intersection intersectionpoint intersectionpoints intersections intouch inverse inversion invisible is3D isDuplicate isogonal isogonalconjugate isotomic isotomicconjugate isparabola italic item key kurtosis kurtosisexcess label labelaxis labelmargin labelpath labels labeltick labelx labelx3 labely labely3 labelz labelz3 lastcut latex latitude latticeshade layer layout ldexp leastsquares legend legenditem length lift limits line linear linecap linejoin linemargin lineskip linetype linewidth link list locale locate locatefile location log log10 log1p logaxiscoverage longitude lookup magnetize makeNode makedraw makepen map margin markangle markangleradius markanglespace markarc marker markinterval marknodes markrightangle markuniform mass masscenter massformat math max max3 maxbound maxcoords maxratio maxtimes mean medial median midpoint min min3 minbound minipage minratio mintimes miterlimit momArrowPath momarrowsize monotonic nativeformat natural needshipout newl newpage newslide newton newtree nextframe nextnormal nextpage nib nodabscissa none normalvideo notaknot numberpage nurb object offset onpath opacity opposite orientation orig_circlenodesnumber orig_circlenodesnumber1 orig_draw orig_ellipsenodesnumber orig_ellipsenodesnumber1 orig_hyperbolanodesnumber orig_parabolanodesnumber origin orthic orthocentercenter outformat outline outprefix output overwrite pack pairs palette parabola parabolanodesnumber parallel partialsum path path3 pattern pause pdf pedal periodic perp perpendicular perpendicularmark phantom photon piecewisestraight point polar polarconicroutine polargraph polygon postcontrol postscript pow10 ppoint prc prc0 precision precontrol prepend print_random_addresses project projection purge pwhermite quadrant quadraticroots quantize quarticroots quotient radialshade radians radicalcenter radicalline radius rand randompath rd read1 read2 read3 readline realmult realquarticroots rectangle rectangular rectify reflect relabscissa relative relativedistance reldir relpoint reltime remainder remark removeDuplicates rename replace report rescale rescale2 resetdefaultpen restore restoredefaults reverse reversevideo rf rfind rgb rgba rgbint rmf rms rotate rotateO rotation round roundbox roundedpath roundrectangle samecoordsys sameside sample save savedefaults saveline scale scale3 scaleO scaleT scaleless scientific search searchtree sec secondaryX secondaryY seconds section sector seek seekeof segment sequence setpens sgn sgnd sharpangle sharpdegrees shift shiftless shipout shipout3 show side simeq simpson sin single sinh size size3 skewness skip slant sleep slope slopefield solve sort sourceline sphere split sqrt square srand standardizecoordsys startScript startTrembling stdev step stickframe stickmarksize stickmarkspace stop straight straightness string stripdirectory stripextension stripfile 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 thick thin tick tickMax tickMax3 tickMin tickMin3 ticklabelshift ticklocate tildeframe tildemarksize tile tiling time times title titlepage topbox transform transformation transpose tremble trembleFuzz tremble_circlenodesnumber tremble_circlenodesnumber1 tremble_draw tremble_ellipsenodesnumber tremble_ellipsenodesnumber1 tremble_hyperbolanodesnumber tremble_marknodes tremble_markuniform tremble_parabolanodesnumber triangle triangleAbc triangleabc triangulate tricoef tridiagonal trilinear trim trueMagnetize truepoint tube uncycle unfill uniform unit unitrand unitsize unityroot unstraighten upcase updatefunction upscale uptodate usepackage usersetting usleep value variance variancebiased vbox vector vectorfield verbatim view vline vprojection windingnumber word write xaxis xaxis3 xaxis3At xaxisAt xequals xinput xlimits xoutput xpart xscale xscaleO xtick xtick3 xtrans yaxis yaxis3 yaxis3At yaxisAt yequals ylimits ypart yscale yscaleO ytick ytick3 ytrans zaxis3 zaxis3At zero zero3 zlimits zpart ztick ztick3 ztrans ))
+
+(defvar asy-variable-name '(
+AliceBlue Align Allow AntiqueWhite Apricot Aqua Aquamarine Aspect Azure BeginPoint Beige Bisque Bittersweet Black BlanchedAlmond Blue BlueGreen BlueViolet Both Break BrickRed Brown BurlyWood BurntOrange CCW CW CadetBlue CarnationPink Center Centered Cerulean Chartreuse Chocolate Coral CornflowerBlue Cornsilk Crimson Crop Cyan Dandelion DarkBlue DarkCyan DarkGoldenrod DarkGray DarkGreen DarkKhaki DarkMagenta DarkOliveGreen DarkOrange DarkOrchid DarkRed DarkSalmon DarkSeaGreen DarkSlateBlue DarkSlateGray DarkTurquoise DarkViolet DeepPink DeepSkyBlue DefaultHead DimGray DodgerBlue Dotted Draw E ENE EPS ESE Emerald EndPoint Fill FillDraw FireBrick FloralWhite ForestGreen Fuchsia Gainsboro GhostWhite Gold Goldenrod Gray Green GreenYellow Honeydew HookHead Horizontal HotPink I IgnoreAspect IndianRed Indigo Ivory JOIN_IN JOIN_OUT JungleGreen Khaki Label Lavender LavenderBlush LawnGreen 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 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 NW NavajoWhite Navy NavyBlue NoAlign NoCrop NoFill NoSide OldLace Olive OliveDrab OliveGreen Orange OrangeRed Orchid Ox Oy PaleGoldenrod PaleGreen PaleTurquoise PaleVioletRed PapayaWhip Peach PeachPuff Periwinkle Peru PineGreen Pink Plum PowderBlue ProcessBlue Purple RawSienna Red RedOrange RedViolet Rhodamine RightJustified RightSide RosyBrown RoyalBlue RoyalPurple RubineRed S SE SSE SSW SW SaddleBrown Salmon SandyBrown SeaGreen Seashell Sepia Sienna Silver SimpleHead SkyBlue SlateBlue SlateGray Snow SpringGreen SteelBlue Suppress SuppressQuiet Tan TeXHead Teal TealBlue Thistle Ticksize Tomato Turquoise UnFill VERSION Value Vertical Violet VioletRed W WNW WSW Wheat White WhiteSmoke WildStrawberry XYAlign YAlign Yellow YellowGreen YellowOrange addpenarc addpenline align allowstepping angularsystem animationdelay appendsuffix arcarrowangle arcarrowfactor arrow2sizelimit arrowangle arrowbarb arrowdir arrowfactor arrowhookfactor arrowlength arrowsizelimit arrowtexfactor authorpen axis axiscoverage axislabelfactor background backgroundcolor backgroundpen barfactor barmarksizefactor basealign baselinetemplate beveljoin bigvertexpen bigvertexsize black blue bm bottom bp brown bullet byfoci byvertices camerafactor chartreuse circlemarkradiusfactor circlenodesnumberfactor circleprecision circlescale cm codefile codepen codeskip colorPen coloredNodes coloredSegments conditionlength conicnodesfactor count cputimeformat crossmarksizefactor currentcoordsys 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 default defaultS defaultbackpen defaultcoordsys defaultfilename defaultformat defaultmassformat defaultpen diagnostics differentlengths dot dotfactor dotframe dotted doublelinepen doublelinespacing down ellipsenodesnumberfactor eps epsgeo epsilon evenodd extendcap fermionpen figureborder figuremattpen firstnode firststep foregroundcolor fuchsia fuzz gapfactor ghostpen gluonamplitude gluonpen gluonratio gray green grey hatchepsilon havepagenumber heavyblue heavycyan heavygray heavygreen heavygrey heavymagenta heavyred hline hwratio hyperbolanodesnumberfactor identity4 ignore inXasyMode inch inches includegraphicscommand incommensurate inf infinity institutionpen intMax intMin invert invisible itempen itemskip itemstep labelmargin landscape lastnode left legendhskip legendlinelength legendmargin legendmarkersize legendmaxrelativewidth legendvskip lightblue lightcyan lightgray lightgreen lightgrey lightmagenta lightolive lightred lightyellow linemargin longdashdotted longdashed magenta magneticPoints magneticRadius mantissaBits markangleradius markangleradiusfactor markanglespace markanglespacefactor 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 newbulletcolor ngraph nil nmesh nobasealign nodeMarginDefault nodesystem nomarker nopoint noprimary nullpath nullpen numarray 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 plus preamblenodes pt purple r3 r4a r4b randMax realDigits realEpsilon realMax realMin red relativesystem reverse right roundcap roundjoin royalblue salmon saveFunctions scalarpen sequencereal settings shipped signedtrailingzero solid springgreen sqrtEpsilon squarecap squarepen startposition stdin stdout stepfraction steppagenumberpen stepping stickframe stickmarksizefactor stickmarkspacefactor textpen ticksize tildeframe tildemarksizefactor tinv titlealign titlepagepen titlepageposition titlepen titleskip top trailingzero treeLevelStep treeMinNodeWidth treeNodeStep trembleAngle trembleFrequency trembleRandom tremblingMode undefined unitcircle unitsquare up urlpen urlskip version vertexpen vertexsize viewportsize vline white wye xformStack yellow ylabelwidth zerotickfuzz zerowinding ))
diff --git a/Build/source/utils/asymptote/asy-list.pl b/Build/source/utils/asymptote/asy-list.pl
new file mode 100755
index 00000000000..4206adc4805
--- /dev/null
+++ b/Build/source/utils/asymptote/asy-list.pl
@@ -0,0 +1,106 @@
+#!/usr/bin/env perl
+#####
+# asy-list.pl
+#
+# Build asy-keywords.el from list of asy global functions and variables
+#
+#####
+
+open(keywords, "> asy-keywords.el") ||
+ die("Couldn't open asy-keywords.el for writing.");
+
+print keywords <<END;
+;;
+;; This file is automatically generated by asy-list.pl.
+;; Changes will be overwritten.
+;;
+(defvar asy-keywords-version "$ARGV[1]")
+
+END
+
+sub add {
+ print keywords $_[0]." ";
+}
+
+sub openlist {
+ open(asylist, $ARGV[0]) || die("Couldn't open $ARGV[0]");
+}
+
+print keywords <<END;
+(defvar asy-keyword-name '(
+END
+
+open(camp, "camp.l") || die("Couldn't open camp.l");
+
+# Search for the %% separator, after which the definitions start.
+while (<camp>) {
+ if (/^%%\s*$/) {
+ last; # Break out of the loop.
+ }
+}
+
+while (<camp>) {
+ if (/^%%\s*$/) {
+ last; # A second %% indicates the end of definitions.
+ }
+ if (/^(\w+)\s*\{/) {
+ add($1);
+ }
+}
+
+openlist();
+
+while (<asylist>) {
+ if (/^(\w*)[^ ]* (\w*)\(.*/) {
+ push @types, $1;
+ push @functions, $2;
+ }
+ if (/^([^ ]*) (\w*);/) {
+ push @variables, $2;
+ }
+}
+
+@saw{@types} = ();
+@types = sort keys %saw;
+undef %saw;
+
+@saw{@functions} = ();
+@functions = sort keys %saw;
+undef %saw;
+
+@saw{@variables} = ();
+@variables = sort keys %saw;
+undef %saw;
+
+print keywords <<END;
+))
+
+(defvar asy-type-name '(
+END
+
+foreach(@types) {
+ print keywords $_ . " ";
+}
+
+print keywords <<END;
+))
+
+(defvar asy-function-name '(
+END
+
+foreach(@functions) {
+ print keywords $_ . " ";
+}
+
+print keywords <<END;
+))
+
+(defvar asy-variable-name '(
+END
+
+foreach(@variables) {
+ print keywords $_ . " ";
+}
+
+print keywords "))\n";
+
diff --git a/Build/source/utils/asymptote/asy.ico b/Build/source/utils/asymptote/asy.ico
new file mode 100644
index 00000000000..f9c89bc2be7
--- /dev/null
+++ b/Build/source/utils/asymptote/asy.ico
Binary files differ
diff --git a/Build/source/utils/asymptote/asy.rc b/Build/source/utils/asymptote/asy.rc
new file mode 100644
index 00000000000..62b2e91dd3a
--- /dev/null
+++ b/Build/source/utils/asymptote/asy.rc
@@ -0,0 +1,26 @@
+asy ICON PRELOAD "asy.ico"
+
+1 VERSIONINFO
+ FILEOS 0x40004
+ FILETYPE 0x1
+ FILESUBTYPE 0x0
+
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "040904b0"
+ BEGIN
+ VALUE "FileDescription", "Vector Graphics Language\0"
+ VALUE "OriginalFilename", "asy.exe\0"
+ VALUE "LegalCopyright", "Copyright \251 2005 Andy Hammerlindl, John Bowman, Tom Prince\0"
+ VALUE "CompanyName", "Andy Hammerlindl, John Bowman, Tom Prince\0"
+ VALUE "ProductName", "Asymptote\0"
+ VALUE "ProductVersion", "ASYMPTOTE_VERSION\0"
+ VALUE "GPL Copyleft", "Released under the GNU General Public License version 2\0"
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x409, 0x04b0
+ END
+END
diff --git a/Build/source/utils/asymptote/asymptote.nsi b/Build/source/utils/asymptote/asymptote.nsi
new file mode 100644
index 00000000000..173e8b1d6c4
--- /dev/null
+++ b/Build/source/utils/asymptote/asymptote.nsi
@@ -0,0 +1,180 @@
+!define PRODUCT_NAME "Asymptote"
+!include AsymptoteInstallInfo.nsi
+!define PRODUCT_WEB_SITE "http://asymptote.sourceforge.net/"
+!define PRODUCT_DIR_REGKEY "Software\Microsoft\Windows\CurrentVersion\App Paths\Asymptote"
+!define PRODUCT_FILE_TYPE_REGKEY1 "Software\Classes\.asy"
+!define PRODUCT_FILE_TYPE_REGKEY2 "Software\Classes\ASYFile\shell\open\command"
+!define PRODUCT_UNINST_KEY "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PRODUCT_NAME}"
+!define PRODUCT_UNINST_ROOT_KEY "HKLM"
+!define PRODUCT_STARTMENU_REGVAL "NSIS:StartMenuDir"
+
+SetCompressor lzma
+XPStyle On
+
+; MUI 1.67 compatible ------
+!include "MUI.nsh"
+!include "LogicLib.nsh"
+
+; MUI Settings
+!define MUI_ABORTWARNING
+!define MUI_ICON "asy.ico"
+!define MUI_UNICON "asy.ico"
+
+; Welcome page
+!insertmacro MUI_PAGE_WELCOME
+; License page
+!insertmacro MUI_PAGE_LICENSE "LICENSE"
+;Components page
+; don't bother with this until there are other components to install
+; e.g.: possibility to automatically detect presence of, download, and install python, miktex, ImageMagick, etc
+;!insertmacro MUI_PAGE_COMPONENTS
+; Directory page
+!insertmacro MUI_PAGE_DIRECTORY
+; Start menu page
+var ICONS_GROUP
+!define MUI_STARTMENUPAGE_NODISABLE
+!define MUI_STARTMENUPAGE_DEFAULTFOLDER "Asymptote"
+!define MUI_STARTMENUPAGE_REGISTRY_ROOT "${PRODUCT_UNINST_ROOT_KEY}"
+!define MUI_STARTMENUPAGE_REGISTRY_KEY "${PRODUCT_UNINST_KEY}"
+!define MUI_STARTMENUPAGE_REGISTRY_VALUENAME "${PRODUCT_STARTMENU_REGVAL}"
+!insertmacro MUI_PAGE_STARTMENU Application $ICONS_GROUP
+; Instfiles page
+!insertmacro MUI_PAGE_INSTFILES
+; Finish page
+;!define MUI_FINISHPAGE_RUN "$INSTDIR\asy.bat"
+;!define MUI_FINISHPAGE_SHOWREADME "$INSTDIR\asymptote.pdf"
+!define MUI_FINISHPAGE_LINK ${PRODUCT_WEB_SITE}
+!define MUI_FINISHPAGE_LINK_LOCATION ${PRODUCT_WEB_SITE}
+!insertmacro MUI_PAGE_FINISH
+
+; Uninstaller pages
+!insertmacro MUI_UNPAGE_WELCOME
+!insertmacro MUI_UNPAGE_CONFIRM
+!insertmacro MUI_UNPAGE_INSTFILES
+!insertmacro MUI_UNPAGE_FINISH
+
+; Language files
+!insertmacro MUI_LANGUAGE "English"
+
+; Reserve files
+!insertmacro MUI_RESERVEFILE_INSTALLOPTIONS
+
+; MUI end ------
+
+Name "${PRODUCT_NAME} ${PRODUCT_VERSION}"
+OutFile "asymptote-${PRODUCT_VERSION}-setup.exe"
+InstallDir "$PROGRAMFILES\Asymptote"
+InstallDirRegKey HKLM "${PRODUCT_DIR_REGKEY}" ""
+ShowInstDetails show
+ShowUnInstDetails show
+
+Section "Asymptote" SEC01
+ SetOutPath "$INSTDIR"
+ SetOverwrite try
+ File /r build-${PRODUCT_VERSION}\*
+
+ CreateDirectory "$INSTDIR\..\etc"
+ FileOpen $0 $INSTDIR\..\etc\fstab w
+ FileClose $0
+
+ FileOpen $0 $INSTDIR\asy.bat w
+
+ FileWrite $0 "@ECHO OFF"
+ FileWriteByte $0 "13"
+ FileWriteByte $0 "10"
+
+ FileWrite $0 "set CYGWIN=nodosfilewarning"
+ FileWriteByte $0 "13"
+ FileWriteByte $0 "10"
+
+ FileWrite $0 '"$INSTDIR\asy.exe" %*'
+ FileWriteByte $0 "13"
+ FileWriteByte $0 "10"
+
+ FileWrite $0 "if %errorlevel% == 0 exit"
+ FileWriteByte $0 "13"
+ FileWriteByte $0 "10"
+
+ FileWrite $0 "echo."
+ FileWriteByte $0 "13"
+ FileWriteByte $0 "10"
+
+ FileWrite $0 "PAUSE"
+ FileWriteByte $0 "13"
+ FileWriteByte $0 "10"
+
+ FileClose $0
+
+; Shortcuts
+ !insertmacro MUI_STARTMENU_WRITE_BEGIN Application
+ CreateDirectory "$SMPROGRAMS\$ICONS_GROUP"
+ SetOutPath "%USERPROFILE%"
+ CreateShortCut "$SMPROGRAMS\$ICONS_GROUP\Asymptote.lnk" "$INSTDIR\asy.bat" "" "$INSTDIR\asy.ico"
+ CreateShortCut "$DESKTOP\Asymptote.lnk" "$INSTDIR\asy.bat" "" "$INSTDIR\asy.ico"
+ CreateShortCut "$DESKTOP\Xasy.lnk" "$INSTDIR\xasy.py"
+ CreateShortCut "$SMPROGRAMS\$ICONS_GROUP\Xasy.lnk" "$INSTDIR\xasy.py"
+ SetOutPath "$INSTDIR"
+ !insertmacro MUI_STARTMENU_WRITE_END
+SectionEnd
+
+Section "Tester"
+
+SectionEnd
+
+Section -AdditionalIcons
+ !insertmacro MUI_STARTMENU_WRITE_BEGIN Application
+ WriteIniStr "$INSTDIR\${PRODUCT_NAME}.url" "InternetShortcut" "URL" "${PRODUCT_WEB_SITE}"
+ CreateShortCut "$SMPROGRAMS\$ICONS_GROUP\Website.lnk" "$INSTDIR\${PRODUCT_NAME}.url"
+ CreateShortCut "$SMPROGRAMS\$ICONS_GROUP\Uninstall.lnk" "$INSTDIR\uninst.exe"
+ !insertmacro MUI_STARTMENU_WRITE_END
+SectionEnd
+
+Section -Post
+ WriteUninstaller "$INSTDIR\uninst.exe"
+ ;create registry keys with information needed to run asymptote
+ WriteRegStr HKLM "${PRODUCT_DIR_REGKEY}" "" "$INSTDIR\asy.exe"
+ WriteRegStr HKLM "${PRODUCT_DIR_REGKEY}" "Path" "$INSTDIR"
+ WriteRegStr HKLM "${PRODUCT_FILE_TYPE_REGKEY1}" "" "ASYFile"
+ WriteRegStr HKLM "${PRODUCT_FILE_TYPE_REGKEY2}" "" '"$INSTDIR\asy.bat" "%1"'
+ ReadRegStr $0 HKLM "SYSTEM\CurrentControlSet\Control\Session Manager\Environment" "CYGWIN"
+ ${If} $0 == ""
+ WriteRegExpandStr HKLM "SYSTEM\CurrentControlSet\Control\Session Manager\Environment" "CYGWIN" "nodosfilewarning"
+ SendMessage ${HWND_BROADCAST} ${WM_WININICHANGE} 0 "STR:Environment" /TIMEOUT=5000
+ ${Endif}
+
+ WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "DisplayName" "$(^Name)"
+ WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "UninstallString" "$INSTDIR\uninst.exe"
+ WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "DisplayIcon" "$INSTDIR\asy.exe"
+ WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "DisplayVersion" "${PRODUCT_VERSION}"
+ WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "URLInfoAbout" "${PRODUCT_WEB_SITE}"
+SectionEnd
+
+
+Function un.onUninstSuccess
+ HideWindow
+ MessageBox MB_ICONINFORMATION|MB_OK "$(^Name) was successfully removed from your computer."
+FunctionEnd
+
+Section Uninstall
+ !insertmacro MUI_STARTMENU_GETFOLDER "Application" $ICONS_GROUP
+ Delete "$INSTDIR\${PRODUCT_NAME}.url"
+ Delete "$INSTDIR\uninst.exe"
+ !include AsymptoteUninstallList.nsi
+ Delete "$INSTDIR\asy.bat"
+ RMDir "$INSTDIR"
+
+ Delete "$SMPROGRAMS\$ICONS_GROUP\Uninstall.lnk"
+ Delete "$SMPROGRAMS\$ICONS_GROUP\Website.lnk"
+ Delete "$DESKTOP\Asymptote.lnk"
+ Delete "$DESKTOP\Xasy.lnk"
+ Delete "$SMPROGRAMS\$ICONS_GROUP\Asymptote.lnk"
+ Delete "$SMPROGRAMS\$ICONS_GROUP\Xasy.lnk"
+ RMDir "$SMPROGRAMS\$ICONS_GROUP"
+
+
+ DeleteRegKey ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}"
+ DeleteRegKey HKLM "${PRODUCT_DIR_REGKEY}"
+ DeleteRegKey HKLM "${PRODUCT_FILE_TYPE_REGKEY1}"
+ DeleteRegKey HKLM "${PRODUCT_FILE_TYPE_REGKEY2}"
+ SetAutoClose true
+SectionEnd
diff --git a/Build/source/utils/asymptote/asymptote.spec b/Build/source/utils/asymptote/asymptote.spec
new file mode 100644
index 00000000000..c8138f9e553
--- /dev/null
+++ b/Build/source/utils/asymptote/asymptote.spec
@@ -0,0 +1,106 @@
+%{!?_texmf: %define _texmf %(eval "echo `kpsewhich -expand-var '$TEXMFLOCAL'`")}
+
+Name: asymptote
+Version: 1.72
+Release: 1%{?dist}
+Summary: Descriptive vector graphics language
+
+Group: Applications/Publishing
+License: GPL
+URL: http://asymptote.sourceforge.net/
+Source: http://downloads.sourceforge.net/sourceforge/asymptote/asymptote-%{version}.src.tgz
+BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
+
+BuildRequires: ncurses-devel
+BuildRequires: readline-devel
+BuildRequires: fftw-devel >= 3.0
+BuildRequires: gc-devel >= 6.7
+BuildRequires: gsl-devel
+BuildRequires: tetex-latex
+BuildRequires: ghostscript
+BuildRequires: texinfo >= 4.7
+BuildRequires: ImageMagick
+
+Requires: tetex-latex
+Requires: tkinter
+Requires: freeglut-devel >= 2.4.0
+Requires(post): /usr/bin/texhash /sbin/install-info
+Requires(postun): /usr/bin/texhash /sbin/install-info
+
+%define texpkgdir %{_texmf}/tex/latex/%{name}
+
+%description
+Asymptote is a powerful descriptive vector graphics language for technical
+drawings, inspired by MetaPost but with an improved C++-like syntax.
+Asymptote provides for figures the same high-quality level of typesetting
+that LaTeX does for scientific text.
+
+
+%prep
+%setup -q
+%{__sed} -i 's|^#!/usr/bin/env python$|#!%{__python}|' GUI/xasy.py
+
+
+%build
+CFLAGS="`echo $RPM_OPT_FLAGS | sed s/-O2/-O3/`" \
+%configure --with-latex=%{_texmf}/tex/latex/
+make %{?_smp_mflags}
+
+
+%install
+rm -rf $RPM_BUILD_ROOT
+make install-all DESTDIR=$RPM_BUILD_ROOT
+
+%{__install} -p -m 644 BUGS ChangeLog LICENSE README ReleaseNotes TODO \
+ $RPM_BUILD_ROOT%{_defaultdocdir}/%{name}/
+
+
+%clean
+rm -rf $RPM_BUILD_ROOT
+
+
+%post
+texhash >/dev/null 2>&1 || :
+/sbin/install-info %{_infodir}/%{name}.info.gz %{_infodir}/dir 2>/dev/null || :
+
+%postun
+texhash >/dev/null 2>&1 || :
+if [ $1 = 0 ]; then
+ /sbin/install-info --remove %{_infodir}/%{name}.info.gz %{_infodir}/dir 2>/dev/null || :
+fi
+
+
+%files
+%defattr(-,root,root,-)
+%doc %{_defaultdocdir}/%{name}/
+%{_bindir}/*
+%{_datadir}/%{name}/
+%{texpkgdir}/
+%{_mandir}/man1/*.1*
+%{_infodir}/*.info*
+
+
+%changelog
+* Thu Apr 19 2007 John Bowman <> - 1.26-1
+- Update source tar ball name.
+
+* Fri May 30 2006 John Bowman <> - 1.07-1
+- Use make install-all to also install info pages.
+
+* Fri May 26 2006 Jose Pedro Oliveira <jpo at di.uminho.pt> - 1.07-1
+- Update to 1.07.
+
+* Sun May 21 2006 John Bowman <> - 1.06-1
+- Update to 1.06.
+
+* Mon May 8 2006 John Bowman <> - 1.05-1
+- Update to 1.05.
+
+* Sun May 7 2006 Jose Pedro Oliveira <jpo at di.uminho.pt> - 1.04-1
+- Update to 1.04.
+
+* Fri Mar 31 2006 Jose Pedro Oliveira <jpo at di.uminho.pt> - 1.03-1
+- Update to 1.03.
+
+* Thu Mar 23 2006 Jose Pedro Oliveira <jpo at di.uminho.pt> - 1.02-1
+- First build.
diff --git a/Build/source/utils/asymptote/autogen.sh b/Build/source/utils/asymptote/autogen.sh
new file mode 100755
index 00000000000..5ec2b3585b6
--- /dev/null
+++ b/Build/source/utils/asymptote/autogen.sh
@@ -0,0 +1,3 @@
+#!/bin/sh
+
+autoheader && autoconf
diff --git a/Build/source/utils/asymptote/base/CAD.asy b/Build/source/utils/asymptote/base/CAD.asy
new file mode 100644
index 00000000000..7c333318f5c
--- /dev/null
+++ b/Build/source/utils/asymptote/base/CAD.asy
@@ -0,0 +1,367 @@
+struct sCAD
+{
+ int nLineGroup = 0; // 0-3
+
+ pen
+ // A
+ pA,
+ pVisibleEdge, // Sichtbare Kanten
+ pVisibleContour, // Sichtbarer Umriss
+ pUsableWindingLength, // Nitzbare Gewindelänge
+ pSystemLine, // Systemlinie (Stahlbau)
+ pDiagramCurve, // Kurve in Diagrammen
+ pSurfaceStructure, // Oberflächenstrukturen
+ // B
+ pB,
+ pLightEdge, // Lichtkante
+ pMeasureLine, // Maßlinie
+ pMeasureHelpLine, // Maßhilfslinie
+ pMeasureLineBound, // Maßlinienbegrenzung
+ pReferenceLine, // Hinweislinie
+ pHatch, // Schraffur
+ pWindingGround, // Gewindegrund
+ pDiagonalCross, // Diagonalkreuz
+ pBendLine, // Biegelinie
+ pProjectionLine, // Projektionslinie
+ pGrid, // Rasterlinien
+ // C
+ pC,
+ pFreehand, // Begrenzung abgebrochener oder unterbrochener
+ // Schnitte, wenn die Begrenzung
+ // keine Mittellinie ist
+ // E
+ pE,
+ pSurfaceTreatmentAllowed, // Bereich zulässiger Oberflächenbehandlung
+ // F
+ pF,
+ pInvisibleEdge, // unsichtbare Kante
+ pInvisibleContour, // unsichtbarer Umriss
+ // G
+ pG,
+ pMiddleLine, // Mittellinie
+ pSymmetryLine, // Symmetrielinie
+ pPartialCircle, // Teilkreis
+ pCircularHole, // Lochkreis
+ pDivisionPlane, // Teilungsebene
+ pTransferLine, // Trajektorien (Übertragunslinien)
+ // J
+ pJ,
+ pCuttingPlane, // Schnittebene
+ pSurfaceTreatmentRequested, // Bereich geforderter Behandlungen
+ // K
+ pK,
+ pContourBeforeDeformation, // Umrisse vor Verformung
+ pAdjacentPartContour, // Umrisse angrenzender Teile
+ pEndShapeRawMaterial, // Fertigformen in Rohteilen
+ pContourEligibleType, // Umrisse wahlweiser Ausführungen
+ pPartInFrontOfCuttingPlane; // Teile vor der Schnittebene
+
+
+
+ static sCAD Create(int nLineGroup = 1)
+ {
+ sCAD cad = new sCAD;
+ if ( nLineGroup < 0 )
+ nLineGroup = 0;
+ if ( nLineGroup > 3 )
+ nLineGroup = 3;
+ cad.nLineGroup = nLineGroup;
+
+ restricted real[] dblFullWidth = {0.35mm, 0.5mm, 0.7mm, 1.0mm};
+ restricted real[] dblHalfWidth = {0.18mm, 0.25mm, 0.35mm, 0.5mm};
+
+ pen pFullWidth = linewidth(dblFullWidth[nLineGroup]);
+ pen pHalfWidth = linewidth(dblHalfWidth[nLineGroup]);
+
+ // Linienarten:
+ // A
+ cad.pA =
+ cad.pVisibleEdge =
+ cad.pVisibleContour =
+ cad.pUsableWindingLength =
+ cad.pSystemLine =
+ cad.pDiagramCurve =
+ cad.pSurfaceStructure =
+ pFullWidth + solid;
+ // B
+ cad.pB =
+ cad.pLightEdge =
+ cad.pMeasureLine =
+ cad.pMeasureHelpLine =
+ cad.pMeasureLineBound =
+ cad.pReferenceLine =
+ cad.pHatch =
+ cad.pWindingGround =
+ cad.pDiagonalCross =
+ cad.pBendLine =
+ cad.pProjectionLine =
+ cad.pGrid =
+ pHalfWidth + solid;
+ // C
+ cad.pC =
+ cad.pFreehand =
+ pHalfWidth + solid;
+ // D
+ // Missing, as I have no idea how to implement this...
+ // E
+ cad.pE =
+ cad.pSurfaceTreatmentAllowed =
+ pFullWidth + linetype("10 2.5");
+ // F
+ cad.pF =
+ cad.pInvisibleEdge =
+ cad.pInvisibleContour =
+ pHalfWidth + linetype("20 5");
+ // G
+ cad.pG =
+ cad.pMiddleLine =
+ cad.pSymmetryLine =
+ cad.pPartialCircle =
+ cad.pCircularHole =
+ cad.pDivisionPlane =
+ cad.pTransferLine =
+ pHalfWidth + linetype("40 5 5 5");
+ // H
+ // see J
+ // I
+ // This letter is not used in DIN 15
+ // J
+ cad.pJ =
+ cad.pCuttingPlane =
+ cad.pSurfaceTreatmentRequested =
+ pFullWidth + linetype("20 2.5 2.5 2.5");
+ // K
+ cad.pK =
+ cad.pContourBeforeDeformation =
+ cad.pAdjacentPartContour =
+ cad.pEndShapeRawMaterial =
+ cad.pContourEligibleType =
+ cad.pPartInFrontOfCuttingPlane =
+ pHalfWidth + linetype("40 5 5 5 5 5");
+
+ return cad;
+ } // end of Create
+
+
+
+ real GetMeasurementBoundSize(bool bSmallBound = false)
+ {
+ if ( bSmallBound )
+ return 1.5 * linewidth(pVisibleEdge) / 2;
+ else
+ return 5 * linewidth(pVisibleEdge);
+ }
+
+
+
+ path GetMeasurementBound(bool bSmallBound = false)
+ {
+ if ( bSmallBound )
+ return scale(GetMeasurementBoundSize(bSmallBound = bSmallBound)) *
+ unitcircle;
+ else
+ return (0,0) --
+ (-cos(radians(7.5)), -sin(radians(7.5))) *
+ GetMeasurementBoundSize(bSmallBound = bSmallBound) --
+ (-cos(radians(7.5)), sin(radians(7.5))) *
+ GetMeasurementBoundSize(bSmallBound = bSmallBound) --
+ cycle;
+ }
+
+
+
+ void MeasureLine(picture pic = currentpicture,
+ Label L,
+ pair pFrom,
+ pair pTo,
+ real dblLeft = 0,
+ real dblRight = 0,
+ real dblRelPosition = 0.5,
+ bool bSmallBound = false)
+ {
+ if ( dblLeft < 0 )
+ dblLeft = 0;
+ if ( dblRight < 0 )
+ dblRight = 0;
+ if ( (dblLeft > 0) && (dblRight == 0) )
+ dblRight = dblLeft;
+ if ( (dblLeft == 0) && (dblRight > 0) )
+ dblLeft = dblRight;
+ pair pDiff = pTo - pFrom;
+ real dblLength = length(pDiff);
+ pair pBegin = pFrom - dblLeft * unit(pDiff);
+ pair pEnd = pTo + dblRight * unit(pDiff);
+ if ( bSmallBound )
+ {
+ draw(
+ pic = pic,
+ g = pBegin--pEnd,
+ p = pMeasureLine);
+ }
+ else
+ {
+ real dblBoundSize = GetMeasurementBoundSize(bSmallBound = bSmallBound);
+ if ( dblLeft == 0 )
+ draw(
+ pic = pic,
+ g = (pFrom + dblBoundSize/2 * unit(pDiff))
+ -- (pTo - dblBoundSize/2 * unit(pDiff)),
+ p = pMeasureLine);
+ else
+ draw(
+ pic = pic,
+ g = pBegin -- (pFrom - dblBoundSize/2 * unit(pDiff))
+ ^^ pFrom -- pTo
+ ^^ (pTo + dblBoundSize/2 * unit(pDiff)) -- pEnd,
+ p = pMeasureLine);
+ }
+ path gArrow = GetMeasurementBound(bSmallBound = bSmallBound);
+ picture picL;
+ label(picL, L);
+ pair pLabelSize = 1.2 * (max(picL) - min(picL));
+ if ( dblLeft == 0 )
+ {
+ fill(
+ pic = pic,
+ g = shift(pFrom) * rotate(degrees(-pDiff)) * gArrow,
+ p = pVisibleEdge);
+ fill(
+ pic = pic,
+ g = shift(pTo) * rotate(degrees(pDiff)) * gArrow,
+ p = pVisibleEdge);
+ if ( dblRelPosition < 0 )
+ dblRelPosition = 0;
+ if ( dblRelPosition > 1 )
+ dblRelPosition = 1;
+ label(
+ pic = pic,
+ L = rotate(degrees(pDiff)) * L,
+ position =
+ pFrom
+ + dblRelPosition * pDiff
+ + unit(rotate(90)*pDiff) * pLabelSize.y / 2);
+ }
+ else
+ {
+ fill(
+ pic = pic,
+ g = shift(pFrom) * rotate(degrees(pDiff)) * gArrow,
+ p = pVisibleEdge);
+ fill(
+ pic = pic,
+ g = shift(pTo) * rotate(degrees(-pDiff)) * gArrow,
+ p = pVisibleEdge);
+ if ( (dblRelPosition >= 0) && (dblRelPosition <= 1) )
+ label(
+ pic = pic,
+ L = rotate(degrees(pDiff)) * L,
+ position =
+ pFrom
+ + dblRelPosition * pDiff
+ + unit(rotate(90)*pDiff) * pLabelSize.y / 2);
+ else
+ {
+ // draw label outside
+ if ( dblRelPosition < 0 )
+ label(
+ pic = pic,
+ L = rotate(degrees(pDiff)) * L,
+ position =
+ pBegin
+ + pLabelSize.x / 2 * unit(pDiff)
+ + unit(rotate(90)*pDiff) * pLabelSize.y / 2);
+ else
+ // dblRelPosition > 1
+ label(
+ pic = pic,
+ L = rotate(degrees(pDiff)) * L,
+ position =
+ pEnd
+ - pLabelSize.x / 2 * unit(pDiff)
+ + unit(rotate(90)*pDiff) * pLabelSize.y / 2);
+ }
+ }
+ } // end of MeasureLine
+
+
+
+ void MeasureParallel(picture pic = currentpicture,
+ Label L,
+ pair pFrom,
+ pair pTo,
+ real dblDistance,
+ // Variables from MeasureLine
+ real dblLeft = 0,
+ real dblRight = 0,
+ real dblRelPosition = 0.5,
+ bool bSmallBound = false)
+ {
+ pair pDiff = pTo - pFrom;
+ pair pPerpendicularDiff = unit(rotate(90) * pDiff);
+ real dblDistancePlus;
+ if ( dblDistance >= 0 )
+ dblDistancePlus = dblDistance + 1mm;
+ else
+ dblDistancePlus = dblDistance - 1mm;
+ draw(
+ pic = pic,
+ g = pFrom--(pFrom + dblDistancePlus*pPerpendicularDiff),
+ p = pMeasureHelpLine
+ );
+ draw(
+ pic = pic,
+ g = pTo--(pTo + dblDistancePlus*pPerpendicularDiff),
+ p = pMeasureHelpLine
+ );
+ MeasureLine(
+ pic = pic,
+ L = L,
+ pFrom = pFrom + dblDistance * pPerpendicularDiff,
+ pTo = pTo + dblDistance * pPerpendicularDiff,
+ dblLeft = dblLeft,
+ dblRight = dblRight,
+ dblRelPosition = dblRelPosition,
+ bSmallBound = bSmallBound);
+ } // end of MeasureParallel
+
+
+
+ path MakeFreehand(pair pFrom, pair pTo,
+ real dblRelDivisionLength = 12.5,
+ real dblRelDistortion = 2.5,
+ bool bIncludeTo = true)
+ {
+ pair pDiff = pTo - pFrom;
+ pair pPerpendicular = dblRelDistortion * linewidth(pFreehand) *
+ unit(rotate(90) * pDiff);
+
+ int nNumOfSubDivisions=ceil(length(pDiff) /
+ (dblRelDivisionLength * linewidth(pFreehand)));
+
+ restricted real[] dblDistortion = {1, -.5, .75, -.25, .25, -1, .5, -.75,
+ .25, -.25};
+ int nDistortion = 0;
+
+ guide g;
+ g = pFrom;
+ for ( int i = 1 ; i < nNumOfSubDivisions ; ++i )
+ {
+ g = g ..
+ (pFrom
+ + pDiff * i / (real)nNumOfSubDivisions
+ + pPerpendicular * dblDistortion[nDistortion]);
+ nDistortion += 1;
+ if ( nDistortion > 9 )
+ nDistortion = 0;
+ }
+
+ if ( bIncludeTo )
+ g = g .. pTo;
+
+ return g;
+ } // end of MakeFreehand
+
+
+
+} // end of CAD
+
diff --git a/Build/source/utils/asymptote/base/animate.asy b/Build/source/utils/asymptote/base/animate.asy
new file mode 100644
index 00000000000..586e71041b6
--- /dev/null
+++ b/Build/source/utils/asymptote/base/animate.asy
@@ -0,0 +1,3 @@
+usepackage("animate");
+import animation;
+
diff --git a/Build/source/utils/asymptote/base/animation.asy b/Build/source/utils/asymptote/base/animation.asy
new file mode 100644
index 00000000000..2b7519c700a
--- /dev/null
+++ b/Build/source/utils/asymptote/base/animation.asy
@@ -0,0 +1,179 @@
+/*****
+ * animation.asy
+ * Andy Hammerlindl and John Bowman 2005/11/06
+ *
+ * Produce GIF, inline PDF, or other animations.
+ *****/
+
+// animation delay is in milliseconds
+real animationdelay=50;
+
+typedef frame fit(string prefix="",picture);
+
+frame NoBox(string prefix="", picture pic) {
+ return pic.fit(prefix);
+}
+
+fit BBox(string prefix="", real xmargin=0, real ymargin=xmargin,
+ pen p=currentpen, filltype filltype=NoFill) {
+ return new frame(string prefix, picture pic) {
+ return bbox(prefix,pic,xmargin,ymargin,p,filltype);
+ };
+}
+
+struct animation {
+ picture[] pictures;
+ string[] files;
+ int index;
+
+ string prefix;
+ bool global; // If true, use a global scaling for all frames; this requires
+ // extra memory since the actual shipout is deferred until all frames have
+ // been generated.
+
+ void operator init(string prefix="", bool global=true) {
+ prefix=replace((prefix == "") ? outprefix() : stripdirectory(prefix),
+ " ","_");
+ this.prefix=prefix;
+ this.global=global;
+ }
+
+ string basename(string prefix=prefix) {
+ return "_"+stripextension(prefix);
+ }
+
+ string name(string prefix, int index) {
+ return stripextension(prefix)+"+"+string(index);
+ }
+
+ private string nextname() {
+ string name=name(prefix,index);
+ ++index;
+ return name;
+ }
+
+ void shipout(string name=nextname(), frame f) {
+ string format=nativeformat();
+ plain.shipout(name,f,format=format,view=false);
+ files.push(name+"."+format);
+ shipped=false;
+ }
+
+ void add(picture pic=currentpicture, fit fit=NoBox) {
+ if(global) {
+ pictures.push(pic.copy());
+ } else this.shipout(nextname(),fit(prefix,pic));
+ }
+
+ void purge(bool keep=settings.keep) {
+ if(!keep) {
+ for(int i=0; i < files.length; ++i)
+ delete(files[i]);
+ }
+ }
+
+ int merge(int loops=0, real delay=animationdelay, string format="gif",
+ string options="", bool keep=settings.keep) {
+ string args="-loop " +(string) loops+" -delay "+(string)(delay/10)+
+ " -alpha Off -dispose Background "+options;
+ for(int i=0; i < files.length; ++i)
+ args += " " +files[i];
+ int rc=convert(args,prefix+"."+format,format=format);
+ this.purge(keep);
+ if(rc == 0) animate(file=prefix+"."+format,format=format);
+ else abort("merge failed");
+ return rc;
+ }
+
+ // Export all frames with the same scaling.
+ void export(string prefix=prefix, fit fit=NoBox,
+ bool multipage=false, bool view=false) {
+ if(pictures.length == 0) return;
+ rescale(pictures);
+ frame multi;
+ bool inlinetex=settings.inlinetex;
+ if(multipage)
+ settings.inlinetex=false;
+ for(int i=0; i < pictures.length; ++i) {
+ if(multipage) {
+ add(multi,fit(prefix,pictures[i]));
+ newpage(multi);
+ } else {
+ if(pictures[i].empty3() || settings.render <= 0) {
+ real render=settings.render;
+ settings.render=0;
+ this.shipout(name(prefix,i),fit(prefix,pictures[i]));
+ settings.render=render;
+ } else { // Render 3D frames
+ files.push(name(prefix,i)+"."+nativeformat());
+ fit(prefix,pictures[i]);
+ }
+ }
+ }
+ if(multipage) {
+ plain.shipout(prefix,multi,view=view);
+ settings.inlinetex=inlinetex;
+ }
+ shipped=true;
+ }
+
+ string load(int frames, real delay=animationdelay, string options="",
+ bool multipage=false) {
+ string s="\animategraphics["+options+"]{"+format("%.18f",1000/delay,"C")+
+ "}{"+basename();
+ if(!multipage) s += "+";
+ s += "}{0}{"+string(frames-1)+"}";
+ return s;
+ }
+
+ string pdf(fit fit=NoBox, real delay=animationdelay, string options="",
+ bool keep=settings.keep, bool multipage=true) {
+ if(settings.inlinetex) multipage=true;
+ if(settings.tex != "pdflatex")
+ abort("inline pdf animations require -tex pdflatex");
+ if(settings.outformat != "") settings.outformat="pdf";
+
+ string filename=basename();
+ string pdfname=filename+".pdf";
+ bool single=global && multipage;
+
+ if(global)
+ export(filename,fit,multipage=multipage);
+
+ shipped=false;
+
+ if(!keep && !settings.inlinetex) {
+ exitfcn currentexitfunction=atexit();
+ void exitfunction() {
+ if(currentexitfunction != null) currentexitfunction();
+ this.purge();
+ if(single)
+ delete(pdfname);
+ }
+ atexit(exitfunction);
+ }
+
+ if(!single)
+ delete(pdfname);
+
+ return load(pictures.length,delay,options,multipage);
+ }
+
+ int movie(fit fit=NoBox, int loops=0, real delay=animationdelay,
+ string format=settings.outformat == "" ? "gif" : settings.outformat,
+ string options="", bool keep=settings.keep) {
+ if(global && format == "pdf") {
+ export(fit,multipage=true,view=true);
+ return 0;
+ }
+
+ if(global)
+ export(fit);
+ return merge(loops,delay,format,options,keep);
+ }
+}
+
+animation operator init() {
+ animation a=animation();
+ return a;
+}
diff --git a/Build/source/utils/asymptote/base/annotate.asy b/Build/source/utils/asymptote/base/annotate.asy
new file mode 100644
index 00000000000..aba9309cb65
--- /dev/null
+++ b/Build/source/utils/asymptote/base/annotate.asy
@@ -0,0 +1,16 @@
+void annotate(picture pic=currentpicture, string title, string text,
+ pair position)
+{
+ pic.add(new void(frame f, transform t) {
+ position=t*position;
+ label(f,"\special{!/pdfmark where
+ {pop} {userdict /pdfmark /cleartomark load put} ifelse
+ [/Rect["+(string) position.x+" 0 0 "+(string) position.y+"]
+ /Subtype /Text
+ /Name /Comment
+ /Title ("+title+")
+ /Contents ("+text+")
+ /ANN pdfmark}");
+ },true);
+ draw(pic,position,invisible);
+}
diff --git a/Build/source/utils/asymptote/base/asy-init.el b/Build/source/utils/asymptote/base/asy-init.el
new file mode 100644
index 00000000000..0e3f178a228
--- /dev/null
+++ b/Build/source/utils/asymptote/base/asy-init.el
@@ -0,0 +1,4 @@
+(autoload 'asy-mode "asy-mode.el" "Asymptote major mode." t)
+(autoload 'lasy-mode "asy-mode.el" "hybrid Asymptote/Latex major mode." t)
+(autoload 'asy-insinuate-latex "asy-mode.el" "Asymptote insinuate LaTeX." t)
+(add-to-list 'auto-mode-alist '("\\.asy$" . asy-mode))
diff --git a/Build/source/utils/asymptote/base/asy-keywords.el b/Build/source/utils/asymptote/base/asy-keywords.el
new file mode 120000
index 00000000000..2e932b592e0
--- /dev/null
+++ b/Build/source/utils/asymptote/base/asy-keywords.el
@@ -0,0 +1 @@
+../asy-keywords.el \ No newline at end of file
diff --git a/Build/source/utils/asymptote/base/asy-mode.el b/Build/source/utils/asymptote/base/asy-mode.el
new file mode 100644
index 00000000000..ac31d8555eb
--- /dev/null
+++ b/Build/source/utils/asymptote/base/asy-mode.el
@@ -0,0 +1,1545 @@
+;;; asy-mode.el
+
+;; Copyright (C) 2006-8
+;; Author: Philippe IVALDI 20 August 2006
+;; Modified by: John Bowman
+;; Last modification: 05 December 2008 (P. Ivaldi)
+;;
+;; This program 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 3 of the License, or
+;; (at your option) any later version.
+;;
+;; This program 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 program ; if not, write to the Free Software
+;; Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+;; Emacs mode for editing Asymptote source code.
+
+;; INSTALLATION:
+;; Place this file (asy-mode.el) and asy-keywords.el in your Emacs load path.
+;; Then choose ONE of the following installation methods:
+
+;; * Method 1:
+;; Copy and uncomment the following lines to your .emacs initialization file:
+;;(autoload 'asy-mode "asy-mode.el" "Asymptote major mode." t)
+;;(autoload 'lasy-mode "asy-mode.el" "hybrid Asymptote/Latex major mode." t)
+;;(autoload 'asy-insinuate-latex "asy-mode.el" "Asymptote insinuate LaTeX." t)
+;;(add-to-list 'auto-mode-alist '("\\.asy$" . asy-mode))
+
+;; * Method 2:
+;; Copy and uncomment the following line to your .emacs initialization file:
+;;(require 'asy-mode)
+
+;; Notes:
+;;
+;; For full functionality the two-mode-mode package should also be installed
+;; (http://www.dedasys.com/freesoftware/files/two-mode-mode.el).
+;;
+;; See also paragraph II of the documentation below to automate asy-insinuate-latex.
+
+(defvar asy-mode-version "1.5")
+
+;;;###autoload
+(define-derived-mode asy-mode objc-mode "Asymptote"
+ "Emacs mode for editing Asymptote source code.
+For full functionality the `two-mode-mode' package should also be installed
+(http://www.dedasys.com/freesoftware/files/two-mode-mode.el).
+
+I. This package provides two modes:
+1- asy-mode:
+All the files with the extension '.asy' are edited in this mode, which provides the following features:
+* Syntax color highlighting;
+* Compiling and viewing current buffer with the key binding C-c C-c;
+* Moving cursor to the error by pressing the key F4.
+* Showing the available function prototypes for the command at the cursor with the key binding C-c ?
+* Compiling and viewing a TeX document linked with the current buffer (usually a document that includes the output picture).
+To link a Tex document try 'M-x asy-set-master-tex' follow by C-Return (see descriptions further of the key binding C-Return, C-S-Return, M-Return, M-S-Return etc within 2- lasy-mode)
+
+2- lasy-mode
+Editing a TeX file that contains Asymptote code is facilitated with the hybrid mode 'lasy-mode'.
+Toggle lasy-mode with M-x lasy-mode.
+In this hybrid mode the major mode is LaTeX when the cursor is in LaTeX code and becomes asy-mode when the cursor is between '\\begin{asy}' and '\\end{asy}'.
+All the features of asy-mode are provided and the key binding C-c C-c of asy-mode compiles and views only the code of the picture where the cursor is.
+Note that some keys binding are added to the LaTeX-mode-map in lasy-mode if the value of the variable lasy-extra-key is t (the default)
+.
+* C-return: compile (if the buffer/file is modified) and view the PostScript output with sequence [latex->[asy->latex]->dvips]->PSviewer
+* M-return: same with pdf output and with the sequence [pdflatex->[asy->pdflatex]]->PDFviewer
+* C-M-return: same with pdf output and with the sequence [latex->[asy->latex]->dvips->ps2pdf]->PSviewer
+* Add the Shift key to the sequence of keys to compile even if the file is not modified.
+
+II. To add a menu bar in current 'latex-mode' buffer and activate hot keys, use 'M-x asy-insinuate-latex <RET>'.
+You can automate this feature for all the 'latex-mode' buffers by inserting the five following lines in your .emacs initialization file:
+ (eval-after-load \"latex\"
+ '(progn
+ ;; Add here your personal features for 'latex-mode':
+ (asy-insinuate-latex t) ;; Asymptote globally insinuates Latex.
+ ))
+
+You can access this help within Emacs by the key binding C-h f asy-mode <RET>
+
+BUGS:
+This package has been tested in:
+* Linux Debian Etch
+- GNU Emacs 22.0.50.1
+- GNU Emacs 21.4.1 (only basic errors management and basic font-lock features within lasy-mode are supported)
+* WindowsXP
+- GNU Emacs 22.0.990.1 (i386-mingw-nt5.1.2600)
+
+This package seems to work with XEmacs 21.4 but not all the features are available (in particular syntax highlighting).
+
+Report bugs to http://asymptote.sourceforge.net
+
+Some variables can be customized: M-x customize-group <RET> asymptote <RET>."
+
+ (setq c++-font-lock-extra-types (cons "true" c++-font-lock-extra-types)))
+
+(require 'font-lock)
+(require 'cc-mode)
+(require 'cl) ;; Common Lisp extensions for Emacs
+(require 'compile)
+(require 'wid-edit)
+
+;;;###autoload
+(add-to-list 'auto-mode-alist '("\\.asy$" . asy-mode))
+
+(defvar running-xemacs-p (featurep 'xemacs))
+(defvar running-unix-p (not (string-match "windows-nt\\|ms-dos" (symbol-name system-type))))
+
+(when running-xemacs-p
+ (defalias 'turn-on-font-lock-if-enabled 'ignore)
+ (defalias 'line-number-at-pos 'line-number)
+ (defvar temporary-file-directory (temp-directory))
+ (defun replace-regexp-in-string (regexp rep string)
+ (replace-in-string string regexp rep))
+ )
+
+(when (or (< emacs-major-version 22) running-xemacs-p)
+ ;; Add regexp for parsing the compilation errors of asy
+ (add-to-list 'compilation-error-regexp-alist
+ '("\\(.*?.asy\\): \\(.*?\\)\\.\\(.*?\\):" 1 2 3)))
+
+(when (< emacs-major-version 22)
+ (defun line-number-at-pos (&optional pos)
+ "Return (narrowed) buffer line number at position POS.
+If POS is nil, use current buffer location.
+Counting starts at (point-min), so the value refers
+to the contents of the accessible portion of the buffer."
+ (let ((opoint (or pos (point))) start)
+ (save-excursion
+ (goto-char (point-min))
+ (setq start (point))
+ (goto-char opoint)
+ (forward-line 0)
+ (1+ (count-lines start (point)))))))
+
+(defcustom lasy-extra-key t
+ "* If on, the folowing binding keys are added in lasy-mode :
+ (define-key lasy-mode-map (kbd \"<C-return>\") 'lasy-view-ps)
+ (define-key lasy-mode-map (kbd \"<C-S-return>\") 'asy-master-tex-view-ps-f)
+ (define-key lasy-mode-map (kbd \"<M-return>\") 'lasy-view-pdf-via-pdflatex)
+ (define-key lasy-mode-map (kbd \"<M-S-return>\") 'asy-master-tex-view-pdflatex-f)
+ (define-key lasy-mode-map (kbd \"<C-M-return>\") 'lasy-view-pdf-via-ps2pdf)
+ (define-key lasy-mode-map (kbd \"<C-M-S-return>\") 'asy-master-tex-view-ps2pdf-f)
+
+If you also want this feature in pure latex-mode, you can set this variable to `nil' and add these lines in your .emacs:
+
+(require 'asy-mode)
+(eval-after-load \"latex\"
+ '(progn
+ (define-key LaTeX-mode-map (kbd \"<C-return>\") 'lasy-view-ps)
+ (define-key LaTeX-mode-map (kbd \"<C-S-return>\") 'asy-master-tex-view-ps-f)
+ (define-key LaTeX-mode-map (kbd \"<M-return>\") 'lasy-view-pdf-via-pdflatex)
+ (define-key LaTeX-mode-map (kbd \"<M-S-return>\") 'asy-master-tex-view-pdflatex-f)
+ (define-key LaTeX-mode-map (kbd \"<C-M-return>\") 'lasy-view-pdf-via-ps2pdf)
+ (define-key LaTeX-mode-map (kbd \"<C-M-S-return>\") 'asy-master-tex-view-ps2pdf-f)))"
+ :type 'boolean
+ :group 'asymptote)
+
+(defcustom asy-compilation-buffer 'none
+ " 'visible means keep compilation buffer visible ;
+ 'available means keep compilation buffer available in other buffer but not visible;
+ 'none means delete compilation buffer automatically after a *successful* compilation.
+ 'never means don't open any window or buffer attached to the compilation process.
+If the value is 'never':
+* Emacs is suspended until the child program returns;
+* the management of errors is poorer than with other value;
+* the compilation doesn't modify your current window configuration."
+ :type '(choice (const visible) (const available) (const none) (const never))
+ :group 'asymptote)
+
+(defcustom lasy-ask-about-temp-compilation-buffer t
+ "* If t, ask before visiting a temporary buffer of compilation."
+ :type 'boolean
+ :group 'asymptote)
+
+(defcustom lasy-compilation-inline-auto-detection nil
+ "* If t, lasy-mode detects automatically if the option 'inline' is passed to asymptote.sty.
+In case of 'inline' option, the compilation of a figure separately of the document is processed by rebuilding the preamble and compiling it as a file '.tex' containing only this picture.
+ If nil (the default), the compilation of a figure separately of the document is processed by building a file '.asy', without the features of the LaTeX preamble."
+ :type 'boolean
+ :group 'asymptote)
+
+(defcustom asy-command-location ""
+ "* If not in the path, you can put here the name of the directory containing Asy's binary files.
+this variable must end in /."
+ :type 'directory
+ :group 'asymptote)
+
+(defcustom asy-command "asy -V"
+ "* Command invoked to compile a Asymptote file.
+You can define the location of this command with the variable `asy-command-location'."
+ :type 'string
+ :group 'asymptote)
+
+(defcustom lasy-command "asy"
+ "* Command invoked to compile a Asymptote file generated compiling a .tex file.
+You can define the location of this command with the variable `asy-command-location'."
+ :type 'string
+ :group 'asymptote)
+
+(defcustom lasy-latex-command "latex -halt-on-error"
+ "* Command invoked to compile a .tex file with LaTeX."
+ :type 'string
+ :group 'asymptote)
+
+(defcustom lasy-pdflatex-command "pdflatex -halt-on-error"
+ "* Command invoked to compile a .tex file with pdflaTex."
+ :type 'string
+ :group 'asymptote)
+
+(defcustom lasy-dvips-pre-pdf-command "dvips -Ppdf"
+ "* Command invoked to convert a .dvi file to a temporary .ps file in order to
+generate a final .pdf file."
+ :type 'string
+ :group 'asymptote)
+
+(defcustom lasy-dvips-command "dvips -q"
+ "* Command invoked to convert a .dvi file to a final .ps file."
+ :type 'string
+ :group 'asymptote)
+
+(defcustom lasy-ps2pdf-command "ps2pdf14"
+ "* Command invoked to convert a .dvi file to .ps file."
+ :type 'string
+ :group 'asymptote)
+
+(defcustom asy-temp-dir temporary-file-directory
+ "*The name of a directory for Asy's temporary files.
+Such files are generated by functions like
+`asy-compile' when lasy-mode is enable."
+ :type 'directory
+ :group 'asymptote)
+
+(defcustom ps-view-command (if running-unix-p "gv" "")
+ "Command to view a PostScript file generated by compiling a tex file within lasy-mode.
+This variable is not used when running the Windows OS.
+See `asy-open-file'."
+ :type 'string
+ :group 'asymptote)
+
+(defcustom pdf-view-command
+ (if running-unix-p
+ "xpdf" "")
+ "Command to view a pdf file generated by compiling a tex file within lasy-mode.
+This variable is not used when running the Windows OS.
+See `asy-open-file'."
+ :type 'string
+ :group 'asymptote)
+
+(defvar asy-TeX-master-file nil
+ "TeX file associate with current asymptote code.
+This variable must be modified only using the function 'asy-set-master-tex by M-x asy-set-master-tex <RET>.")
+(make-variable-buffer-local 'asy-TeX-master-file)
+
+(defvar lasy-compile-tex nil
+ "* Internal use. t if LaTeX compilation come from latex-mode.")
+
+(when (fboundp 'font-lock-add-keywords)
+ (if (< max-specpdl-size 2000) (setq max-specpdl-size 2000))
+ (defun asy-add-function-keywords (function-keywords face-name)
+ (let* ((keyword-list (mapcar #'(lambda (x)
+ (symbol-name x))
+ function-keywords))
+ (keyword-regexp (concat "\\<\\("
+ (regexp-opt keyword-list)
+ "\\)(")))
+ (font-lock-add-keywords 'asy-mode
+ `((,keyword-regexp 1 ',face-name)))))
+
+ (defun asy-add-variable-keywords (function-keywords face-name)
+ (let* ((keyword-list (mapcar #'(lambda (x)
+ (symbol-name x))
+ function-keywords))
+ (keyword-regexp (concat "\\<[0-9]*\\("
+ (regexp-opt keyword-list)
+ "\\)\\(?:[^(a-zA-Z]\\|\\'\\)")))
+ (font-lock-add-keywords 'asy-mode
+ `((,keyword-regexp 1 ',face-name)))))
+
+ ;; External definitions of keywords:
+ ;; asy-function-name and asy-variable-name
+ (if (locate-library "asy-keywords.el")
+ (load "asy-keywords.el")
+ (progn
+ ;; Use dummy keyword definitions if asy-keywords.el is not found:
+ (defvar asy-keyword-name nil)
+ (defvar asy-type-name nil)
+ (defvar asy-function-name nil)
+ (defvar asy-variable-name nil)))
+
+ (defcustom asy-extra-type-name '()
+ "Extra user type names highlighted with 'font-lock-type-face"
+ :type '(repeat symbol)
+ :group 'asymptote)
+
+ (defcustom asy-extra-function-name
+ '()
+ "Extra user function names highlighted with 'font-lock-function-name-face"
+ :type '(repeat symbol)
+ :group 'asymptote)
+
+ (defcustom asy-extra-variable-name '()
+ "Extra user variable names highlighted with 'font-lock-constant-face"
+ :type '(repeat symbol)
+ :group 'asymptote)
+
+ (asy-add-variable-keywords
+ asy-keyword-name
+ 'font-lock-builtin-face)
+
+ (asy-add-variable-keywords
+ (nconc asy-type-name asy-extra-type-name)
+ 'font-lock-type-face)
+
+ (asy-add-function-keywords
+ (nconc asy-function-name asy-extra-function-name)
+ 'font-lock-function-name-face)
+
+ (asy-add-variable-keywords
+ (nconc asy-variable-name asy-extra-variable-name)
+ 'font-lock-constant-face)
+
+ (defface asy-environment-face
+ `((t
+ (:underline t :inverse-video t)))
+ "Face used to highlighting the keywords '\\begin{asy}' and '\\end{asy}' within lasy-mode."
+ :group 'asymptote)
+
+ (font-lock-add-keywords
+ 'asy-mode
+ '(("\\\\begin{asy}.*" . 'asy-environment-face)
+ ("\\\\end{asy}" . 'asy-environment-face)))
+
+ (defface asy-link-face ;; widget-field-face
+ `((t
+ (:underline t)))
+ "Face used to highlighting the links."
+ :group 'asymptote)
+
+ (font-lock-add-keywords
+ 'asy-mode
+ '(("\\[.*?\\.asy\\]" . 'asy-link-face)))
+ )
+
+(setq buffers-menu-max-size nil)
+(setq mode-name "Asymptote")
+
+(if running-xemacs-p
+ (defvar asy-menu
+ '("Asy"
+ ["Toggle lasy-mode" lasy-mode :active (and (featurep 'two-mode-mode) two-mode-bool)]
+ ["Compile/View" asy-compile t]
+ ["Go to error" asy-goto-error t]
+ ["Describe command" asy-show-function-at-point t]"--"
+ ("Master TeX file"
+ ["Set/Change value" (asy-set-master-tex) :active (not (and (boundp two-mode-bool) two-mode-bool))]
+ ["Erase value" (asy-unset-master-tex) :active (not (and (boundp two-mode-bool) two-mode-bool))]
+ ("Compile OR View"
+ ["PS" asy-master-tex-view-ps :active t]
+ ["PDF (pdflatex)" asy-master-tex-view-pdflatex :active t]
+ ["PDF (ps2pdf)" asy-master-tex-view-ps2pdf :active t])
+ ("Compile AND View"
+ ["PS" asy-master-tex-view-ps-f :active t]
+ ["PDF (pdflatex)" asy-master-tex-view-pdflatex-f :active t]
+ ["PDF (ps2pdf)" asy-master-tex-view-ps2pdf-f :active t]))
+ ["Asymptote insinuates globally LaTeX" asy-insinuate-latex-globally :active (not asy-insinuate-latex-globally-p)]"--"
+ ("Debugger Buffer"
+ ["Visible" (setq asy-compilation-buffer 'visible) :style radio :selected (eq asy-compilation-buffer 'visible) :active t]
+ ["Available" (setq asy-compilation-buffer 'available) :style radio :selected (eq asy-compilation-buffer 'available) :active t]
+ ["None" (setq asy-compilation-buffer 'none) :style radio :selected (eq asy-compilation-buffer 'none) :active t]
+ ["Never" (setq asy-compilation-buffer 'never) :style radio :selected (eq asy-compilation-buffer 'never) :active t])
+ ("Compilation Options" :included (and (featurep 'two-mode-mode) two-mode-bool)
+ ["Enable Automatic Detection of Option" (setq lasy-compilation-inline-auto-detection t) :style radio :selected lasy-compilation-inline-auto-detection :active t]
+ ["Disable Automatic Detection of Option" (setq lasy-compilation-inline-auto-detection nil) :style radio :selected (not lasy-compilation-inline-auto-detection) :active t])
+ ["Customize" (customize-group "asymptote") :active t]
+ ["Help" (describe-function 'asy-mode) :active t]
+ ))
+ (defvar asy-menu
+ '("Asy"
+ ["Toggle Lasy-Mode" lasy-mode :visible (and (featurep 'two-mode-mode) two-mode-bool)]
+ ["Compile/View" asy-compile t]
+ ["Go to Error" asy-goto-error t]
+ ["Describe Command" asy-show-function-at-point t]"--"
+ ("Master TeX File"
+ ["Set/Change Value" (asy-set-master-tex) :active (not (and (boundp two-mode-bool) two-mode-bool)) :key-sequence nil]
+ ["Erase Value" (asy-unset-master-tex) :active (not (and (boundp two-mode-bool) two-mode-bool)) :key-sequence nil]
+ ("Compile or View"
+ ["PS" asy-master-tex-view-ps :active t]
+ ["PDF (pdflatex)" asy-master-tex-view-pdflatex :active t]
+ ["PDF (ps2pdf)" asy-master-tex-view-ps2pdf :active t])
+ ("Compile and View"
+ ["PS" asy-master-tex-view-ps-f :active t]
+ ["PDF (pdflatex)" asy-master-tex-view-pdflatex-f :active t]
+ ["PDF (ps2pdf)" asy-master-tex-view-ps2pdf-f :active t]))
+ ["Asymptote Insinuates Globally LaTeX" asy-insinuate-latex-globally :active (not asy-insinuate-latex-globally-p)]"--"
+ ("Debugger Buffer"
+ ["Visible" (setq asy-compilation-buffer 'visible) :style radio :selected (eq asy-compilation-buffer 'visible) :active t :key-sequence nil]
+ ["Available" (setq asy-compilation-buffer 'available) :style radio :selected (eq asy-compilation-buffer 'available) :active t :key-sequence nil]
+ ["None" (setq asy-compilation-buffer 'none) :style radio :selected (eq asy-compilation-buffer 'none) :active t :key-sequence nil]
+ ["Never" (setq asy-compilation-buffer 'never) :style radio :selected (eq asy-compilation-buffer 'never) :active t :key-sequence nil])
+ ("Compilation Options" :visible (and (featurep 'two-mode-mode) two-mode-bool)
+ ["Enable Automatic Detection of Option" (setq lasy-compilation-inline-auto-detection t) :style radio :selected lasy-compilation-inline-auto-detection :active t :key-sequence nil]
+ ["Disable Automatic Detection of Option" (setq lasy-compilation-inline-auto-detection nil) :style radio :selected (not lasy-compilation-inline-auto-detection) :active t :key-sequence nil])
+ ["Customize" (customize-group "asymptote") :active t :key-sequence nil]
+ ["Help" (describe-function 'asy-mode) :active t :key-sequence nil]
+ )))
+(easy-menu-define asy-mode-menu asy-mode-map "Asymptote Mode Commands" asy-menu)
+;; On the hook for XEmacs only.
+(if running-xemacs-p
+ (add-hook 'asy-mode-hook
+ (lambda ()
+ (and (eq major-mode 'asy-mode)
+ (easy-menu-add asy-mode-menu asy-mode-map)))))
+
+(defun asy-protect-file-name(Filename)
+ (concat "\"" Filename "\""))
+
+(defun asy-get-temp-file-name(&optional noext)
+ "Get a temp file name for printing."
+ (if running-xemacs-p
+ (concat (make-temp-name asy-temp-dir) (if noext "" ".asy"))
+ (concat (make-temp-file
+ (expand-file-name "asy" asy-temp-dir)) (if noext "" ".asy"))))
+
+(defun asy-log-filename()
+ (concat buffer-file-name ".log"))
+
+(defun asy-compile()
+ "Compile Asymptote code."
+ (interactive)
+ (if (and (boundp two-mode-bool) two-mode-bool)
+ (lasy-compile) ;; compile asy code in a TeX file.
+ (progn ;; compile asy code in a asy file.
+ (let*
+ ((buffer-base-name (file-name-sans-extension (file-name-nondirectory buffer-file-name)))
+ (asy-compile-command
+ (concat asy-command-location asy-command
+ (if (eq asy-compilation-buffer 'never)
+ " " " -wait ")
+ (asy-protect-file-name buffer-base-name))))
+ (if (buffer-modified-p) (save-buffer))
+ (message "%s" asy-compile-command)
+ (asy-internal-compile asy-compile-command t t)))))
+
+(defun asy-error-message(&optional P)
+ (let ((asy-last-error
+ (asy-log-field-string
+ (asy-log-filename) 0)))
+ (if (and asy-last-error (not (string= asy-last-error "")))
+ (message (concat asy-last-error (if P "\nPress F4 to go to error" "")))
+ (when (and (boundp two-mode-bool) two-mode-bool lasy-run-tex (not (zerop asy-last-compilation-code)))
+ (message "The LaTeX code may be incorrect.")))))
+
+(defun asy-log-field-string(Filename Field)
+ "Return field of first line of file filename.
+Fields are defined as 'field1: field2.field3:field4' . Field=0 <-> all fields"
+ (let ((view-inhibit-help-message t))
+ (with-temp-buffer
+ (progn
+ (insert-file Filename)
+ (beginning-of-buffer)
+ (if (re-search-forward "^\\(.*?\\): \\(.*?\\)\\.\\(.*?\\):\\(.*\\)$" (point-max) t)
+ (match-string Field) nil)))))
+
+(defun asy-next-error(arg reset)
+ (if (> emacs-major-version 21)
+ (next-error arg reset)
+ (next-error arg)))
+
+(defun lasy-ask-visit-tem-compilation-buffer()
+ "* Ask before visiting a temporary compilation buffer depending the value of `lasy-ask-about-temp-compilation-buffer'."
+ (if lasy-ask-about-temp-compilation-buffer
+ (y-or-n-p "Visit temporary buffer of compilation ? ") t))
+
+(defun lasy-place-cursor-to-error(Filename li co)
+ (save-excursion
+ (with-temp-buffer
+ (insert-file-contents
+ (if running-unix-p Filename
+ (replace-regexp-in-string
+ "//" ":/"
+ (replace-regexp-in-string "/cygdrive/" "" Filename)))) ;; Not right,
+;;;maybe take a look at the code of compilation-find-file
+ (beginning-of-buffer)
+ (next-line (1- (string-to-number li)))
+ (setq line-err
+ (buffer-substring-no-properties
+ (progn (beginning-of-line) (point))
+ (progn (end-of-line) (point))))))
+ (beginning-of-buffer)
+ (search-forward line-err)
+ (beginning-of-line)
+ (forward-char (1- (string-to-number co))))
+
+(defun asy-goto-error(&optional arg reset)
+ "Go to point of last error within asy/lasy-mode."
+ (interactive "P")
+ (if (or (eq asy-compilation-buffer 'never)
+ (and (boundp two-mode-bool) two-mode-bool))
+ (let* ((log-file (asy-log-filename))
+ (li_ (asy-log-field-string log-file 2))
+ (co_ (asy-log-field-string log-file 3)))
+ (if (and (boundp two-mode-bool) two-mode-bool) ;; Within Lasy-mode
+ (progn ;; lasy-mode need the compilation of file.tex
+ ;; the error can be in Tex commands or in Asymptote commands
+ (if (eq asy-compilation-buffer 'never) ;; Find error in the log file.
+ (if li_ ;; Asy error found in the log-file
+ (progn
+ (lasy-place-cursor-to-error
+ (asy-log-field-string log-file 1) li_ co_)
+ (asy-error-message))
+ (message "There is an error in your LaTeX code..."))
+ (if (or running-xemacs-p (< emacs-major-version 22))
+ (when (lasy-ask-visit-tem-compilation-buffer)
+ (next-error arg))
+ (let ((msg)) ;; Find error in the compilation buffer
+ (save-excursion
+ (set-buffer (next-error-find-buffer))
+ (when reset
+ (setq compilation-current-error nil))
+ (let* ((columns compilation-error-screen-columns)
+ (last 1)
+ (loc (compilation-next-error (or arg 1) nil
+ (or compilation-current-error
+ compilation-messages-start
+ (point-min))))
+ (end-loc (nth 2 loc))
+ (marker (point-marker)))
+ (setq compilation-current-error (point-marker)
+ overlay-arrow-position
+ (if (bolp)
+ compilation-current-error
+ (copy-marker (line-beginning-position)))
+ loc (car loc)))
+ (if (re-search-forward "^\\(.*?\\): \\(.*?\\)\\.\\(.*?\\):\\(.*\\)$" (point-max) t)
+ (progn
+ (setq msg (match-string 0)
+ log-file (match-string 1)
+ li_ (match-string 2)
+ co_ (match-string 3)))
+ (error "Not other errors.")))
+ (lasy-place-cursor-to-error log-file li_ co_)
+ (message msg)))))
+ (if li_ ;;Pure asy-mode and compilation with shell-command
+ (progn
+ (goto-line (string-to-number li_))
+ (forward-char (1- (string-to-number co_)))
+ (asy-error-message))
+ (progn (message "No error.")))))
+ (asy-next-error arg reset)))
+
+(defun asy-grep (Regexp)
+ "Internal function used by asymptote."
+ (let ((Strout "")
+ (case-fold-search-asy case-fold-search))
+ (progn
+ (beginning-of-buffer)
+ (setq case-fold-search nil)
+ (while (re-search-forward Regexp (point-max) t)
+ (setq Strout (concat Strout (match-string 0) "\n\n")))
+ (setq case-fold-search case-fold-search-asy)
+ (if (string= Strout "") "No match.\n" Strout))))
+
+(defun asy-widget-open-file-at-pos (widget &optional event)
+ ""
+ (kill-buffer (current-buffer))
+ (find-file (widget-get widget :follow-link))
+ (goto-line (string-to-number (widget-get widget :value))))
+
+(defun asy-show-function-at-point()
+ "Show the Asymptote definitions of the command at point."
+ (interactive)
+ (save-excursion
+ (let ((cWord (current-word))
+ (cWindow (selected-window)))
+ (switch-to-buffer-other-window "*asy-help*")
+ (fundamental-mode)
+ (setq default-directory "/")
+ (if (> emacs-major-version 21)
+ (call-process-shell-command
+ (concat asy-command-location "asy -l --where") nil t nil)
+ (insert (shell-command-to-string "asy -l --where")))
+ (let ((rHelp (asy-grep (concat "^.*\\b" cWord "(\\(.\\)*?$")))
+ (tag)(file)(line))
+ (erase-buffer)
+ (insert rHelp)
+ (beginning-of-buffer)
+ (while (re-search-forward "\\(.*\\): \\([0-9]*\\)\\.\\([0-9]*\\)" (point-max) t)
+ (setq file (match-string 1)
+ line (match-string 2)
+ tag (file-name-nondirectory file))
+ (widget-create `(file-link
+ :tag ,tag
+ :follow-link ,file
+ :value ,line
+ :action asy-widget-open-file-at-pos
+ ))))
+ (beginning-of-buffer)
+ (while (re-search-forward "\\(.*: [0-9]*\\.[0-9]*\\)" (point-max) t)
+ (replace-match ""))
+ (asy-mode)
+ (use-local-map widget-keymap)
+ (widget-setup)
+ (goto-char (point-min))
+ (select-window cWindow))))
+
+(add-hook 'asy-mode-hook
+ (lambda ()
+ (c-set-style "gnu");
+ (c-set-offset (quote topmost-intro-cont) 0 nil)
+ (make-local-variable 'c-label-minimum-indentation)
+ (setq c-label-minimum-indentation 0)
+ (when (fboundp 'flyspell-mode) (flyspell-mode -1))
+ (turn-on-font-lock)
+ (column-number-mode t)
+ ))
+
+
+;;;###autoload (defun lasy-mode ())
+;;; ************************************
+;;; asy-mode mixed with LaTeX-mode: lasy
+;;; ************************************
+(if (locate-library "two-mode-mode")
+ (progn
+
+ (defvar lasy-fontify-asy-p nil
+ "Variable to communicate with `font-lock-unfontify-region'.
+Internal use, don't set in any fashion.")
+ (setq lasy-fontify-asy-p nil)
+
+ (eval-after-load "two-mode-mode"
+ '(progn
+ ;; Redefine `two-mode-mode-update-mode' to use regexp.
+ (defun two-mode-mode-update-mode ()
+ "Redefined in `asy-mode.el' to use regexp"
+ (when (and two-mode-bool two-mode-update)
+ (setq two-mode-update 0)
+ (let ((mode-list second-modes)
+ (flag 0))
+ (while mode-list
+ (let ((mode (car mode-list))
+ (lm -1)
+ (rm -1))
+ (save-excursion
+ (if (search-backward-regexp (cadr mode) nil t)
+ (setq lm (point))
+ (setq lm -1)))
+ (save-excursion
+ (if (search-backward-regexp (car (cddr mode)) nil t)
+ (setq rm (point))
+ (setq rm -1)))
+ (if (and (not (and (= lm -1) (= rm -1))) (>= lm rm))
+ (progn
+ (setq flag 1)
+ (setq mode-list '())
+ (two-mode-change-mode (car mode) (car (cdr (cddr mode)))))))
+ (setq mode-list (cdr mode-list)))
+ (if (= flag 0)
+ (two-mode-change-mode (car default-mode) (cadr default-mode))))))
+
+ (defun two-mode-change-mode (to-mode func)
+ "Redefined in asy-mode.
+Change the variable `lasy-fontify-asy-p' according to the value of func and
+the current mode."
+ (if (string= to-mode mode-name)
+ t
+ (progn
+ (setq lasy-fontify-asy-p (eq func 'asy-mode))
+ (funcall func)
+ (hack-local-variables)
+ (two-mode-mode-setup)
+ (if two-mode-switch-hook
+ (run-hooks 'two-mode-switch-hook))
+ (if (eq font-lock-mode t)
+ (font-lock-fontify-buffer))
+ (turn-on-font-lock-if-enabled))))
+ ))
+
+
+ (require 'two-mode-mode)
+
+ (defun lasy-mode ()
+ "Treat, in some cases, the current buffer as a literal Asymptote program."
+ (interactive)
+ (set (make-local-variable 'asy-insinuate-latex-p) asy-insinuate-latex-p)
+ (make-local-variable 'lasy-fontify-asy-p)
+ (when (< emacs-major-version 22)
+ (make-local-variable 'font-lock-keywords-only))
+ (setq default-mode '("LaTeX" latex-mode)
+ second-modes '(("Asymptote"
+ "^\\\\begin{asy}.*$"
+ "^\\\\end{asy}"
+ asy-mode)))
+ (if two-mode-bool
+ (progn
+ (latex-mode)
+ (asy-insinuate-latex))
+ (progn
+ (two-mode-mode)
+ )))
+
+ (when (not running-xemacs-p)
+ (defadvice TeX-command-master (around asy-choose-compile act)
+ "Hack to circumvent the preempt of 'C-c C-c' by AucTeX within `lasy-mode'."
+ (if (string-match "asymptote" (downcase mode-name))
+ (asy-compile)
+ ad-do-it)))
+
+ (add-hook 'two-mode-switch-hook
+ (lambda ()
+ (if (eq major-mode 'latex-mode)
+ (progn ;; Switch to latex-mode
+ ;; Disable LaTeX-math-Mode within lasy-mode (because of incompatibility)
+ (when LaTeX-math-mode (LaTeX-math-mode -1))
+ (asy-insinuate-latex)
+ (when (< emacs-major-version 22)
+ (setq font-lock-keywords-only nil)))
+ (progn ;; Switch to asy-mode
+ (when (< emacs-major-version 22)
+ (setq font-lock-keywords-only t))
+ ))))
+
+ ;; Solve a problem restoring a TeX file via desktop.el previously in lasy-mode.
+ (if (boundp 'desktop-buffer-mode-handlers)
+ (progn
+ (defun asy-restore-desktop-buffer (desktop-b-f-name d-b-n d-b-m)
+ (find-file desktop-b-f-name))
+ (add-to-list 'desktop-buffer-mode-handlers
+ '(asy-mode . asy-restore-desktop-buffer))))
+
+ ;; Functions and 'advises' to restrict 'font-lock-unfontify-region'
+ ;; and 'font-lock-fontify-syntactically-region' within lasy-mode
+ ;; Special thanks to Olivier Ramaré for his help.
+ (when (and (fboundp 'font-lock-add-keywords) (> emacs-major-version 21))
+ (defun lasy-mode-at-pos (pos &optional interior strictly)
+ "If point at POS is in an asy environment return the list (start end)."
+ (save-excursion
+ (save-match-data
+ (goto-char pos)
+ (let* ((basy
+ (progn
+ (unless strictly (end-of-line))
+ (when (re-search-backward "^\\\\begin{asy}" (point-min) t)
+ (when interior (next-line))
+ (point))))
+ (easy
+ (and basy
+ (progn
+ (when (re-search-forward "^\\\\end{asy}" (point-max) t)
+ (when interior (previous-line)(beginning-of-line))
+ (point))))))
+ (and basy easy
+ (> pos (- basy (if interior 12 0)))
+ (< pos (+ easy (if interior 10 0)))
+ (list basy easy))))))
+
+ (defun lasy-region (start end &optional interior)
+ "If the region 'start to end' contains the beginning or
+the end of an asy environment return the list of points where
+the asy environment starts and ends."
+ (let* ((beg (min start end))
+ (lim (max start end)))
+ (or (lasy-mode-at-pos beg interior)
+ (save-match-data
+ (save-excursion
+ (goto-char beg)
+ (and (re-search-forward "^\\\\begin{asy}" lim t)
+ (lasy-mode-at-pos (point) interior)))))))
+
+ (defun lasy-tags (start end)
+ "Return associated list of points where the tags starts and ends
+restricted to the region (start end).
+\"b\" associated with (start-beginTag end-beginTag),
+\"e\" associated with (start-endTag end-endTag)."
+ (let*
+ ((beg (min start end))
+ (lim (max start end))
+ out)
+ (save-excursion
+ (goto-char beg)(beginning-of-line)
+ (while
+ (when (re-search-forward "^\\\\begin{asy}.*" lim t)
+ (push (list
+ (progn (beginning-of-line)(point))
+ (progn (end-of-line)(point))) out)))
+ (goto-char beg)(beginning-of-line)
+ (while
+ (when (re-search-forward "^\\\\end{asy}" lim t)
+ (push (list
+ (progn (beginning-of-line)(point))
+ (progn (end-of-line)(point))) out)))
+ out)))
+
+ (defun lasy-restrict-region (start end &optional interior)
+ "If the region 'start to end' contains the beginning or
+the end of an asy environment, returns the list of points wich
+restricts the region to the asy environment.
+Else, return (start end)."
+ (let*
+ ((beg (min start end))
+ (lim (max start end))
+ (be (if (lasy-mode-at-pos beg)
+ beg
+ (or (save-excursion
+ (goto-char beg)
+ (when (re-search-forward "^\\\\begin{asy}.*" lim t)
+ (unless interior (beginning-of-line))
+ (point)))
+ beg)))
+ (en (or (save-excursion
+ (goto-char be)
+ (when (re-search-forward "^\\\\end{asy}" lim t)
+ (when interior (beginning-of-line))
+ (point)))
+ lim)))
+ (list be en)))
+
+ (defun lasy-parse-region (start end)
+ "Return a list ((a (start1 end1)) (b (start2 end2)) [...]).
+where a, b, ... are nil or t; t means the region from 'startX' through 'endX' (are points)
+is in a asy environnement."
+ (let (regasy out rr brr err tags)
+ (save-excursion
+ (goto-char start)
+ (while (< (point) end)
+ (setq regasy (lasy-region (point) end))
+ (if regasy
+ (progn
+ (setq rr (lasy-mode-at-pos (point)))
+ (setq brr (and rr (nth 0 rr))
+ err (and rr (nth 1 rr)))
+ (if rr
+ (progn
+ (push (list t (list (max 1 (1- (point))) (min end err))) out)
+ (goto-char (min end err)))
+ (progn
+ (push (list nil (list (point) (nth 0 regasy))) out)
+ (goto-char (1+ (nth 0 regasy))))))
+ (progn
+ (push (list nil (list (min (1+ (point)) end) end)) out)
+ (goto-char end)))
+ ))
+ ;; Put start and end of tag in latex fontification.
+ (setq tags (lasy-tags start end))
+ (dolist (tag tags) (push (list nil tag) out))
+ (reverse out)))
+
+ (defadvice font-lock-unfontify-region
+ (around asy-font-lock-unfontify-region (beg end))
+ (if two-mode-bool
+ (let ((rstate (lasy-parse-region beg end))
+ curr reg asy-fontify latex-fontify)
+ (while (setq curr (pop rstate))
+ (setq reg (nth 1 curr))
+ (setq asy-fontify (and (nth 0 curr) lasy-fontify-asy-p)
+ latex-fontify (and (not (nth 0 curr))
+ (not lasy-fontify-asy-p)))
+ (when (or asy-fontify latex-fontify)
+ (setq beg (nth 0 reg)
+ end (nth 1 reg))
+ (save-excursion
+ (save-restriction
+ (narrow-to-region beg end)
+ ad-do-it
+ (widen))))))
+ ad-do-it))
+
+ (ad-activate 'font-lock-unfontify-region)
+ ;; (ad-deactivate 'font-lock-unfontify-region)
+
+ (defadvice font-lock-fontify-syntactically-region
+ (around asy-font-lock-fontify-syntactically-region
+ (start end &optional loudly))
+ (if (and two-mode-bool (eq major-mode 'asy-mode))
+ (let*((reg (lasy-restrict-region start end)))
+ (save-restriction
+ (setq start (nth 0 reg) end (nth 1 reg))
+ (narrow-to-region start end)
+ (condition-case nil
+ ad-do-it
+ (error nil))
+ (widen)
+ ))
+ ad-do-it))
+
+ (ad-activate 'font-lock-fontify-syntactically-region)
+ ;; (ad-deactivate 'font-lock-fontify-syntactically-region)
+
+ (defadvice font-lock-default-fontify-region
+ (around asy-font-lock-default-fontify-region
+ (beg end loudly))
+ (if two-mode-bool
+ (let ((rstate (lasy-parse-region beg end))
+ asy-fontify latex-fontify curr reg)
+ (while (setq curr (pop rstate))
+ (setq reg (nth 1 curr))
+ (setq asy-fontify (and (nth 0 curr) lasy-fontify-asy-p)
+ latex-fontify (and (not (nth 0 curr))
+ (not lasy-fontify-asy-p)))
+ (when (or asy-fontify latex-fontify)
+ (setq beg (nth 0 reg)
+ end (nth 1 reg))
+ (save-excursion
+ (save-restriction
+ (narrow-to-region beg end)
+ (condition-case nil
+ ad-do-it
+ (error nil))
+ (widen)
+ )))))
+ ad-do-it))
+
+ (ad-activate 'font-lock-default-fontify-region)
+ ;; (ad-deactivate 'font-lock-default-fontify-region)
+
+ ))
+ (progn
+ (defvar two-mode-bool nil)
+ (defun lasy-mode ()
+ (message "You must install the package two-mode-mode.el."))))
+
+(setq asy-latex-menu-item
+ '(["Toggle lasy-mode" lasy-mode :active (featurep 'two-mode-mode)]
+ ["View asy picture near cursor" lasy-compile :active t]"--"
+ ("Compile OR View"
+ ["PS" lasy-view-ps :active t]
+ ["PDF (pdflatex)" lasy-view-pdf-via-pdflatex :active t]
+ ["PDF (ps2pdf)" lasy-view-pdf-via-ps2pdf :active t])
+ ("Compile AND View"
+ ["PS" asy-master-tex-view-ps-f :active t]
+ ["PDF (pdflatex)" asy-master-tex-view-pdflatex-f :active t]
+ ["PDF (ps2pdf)" asy-master-tex-view-ps2pdf-f :active t])"--"
+ ["Asymptote insinuates globally LaTeX" asy-insinuate-latex-globally :active (not asy-insinuate-latex-globally-p)]
+ ("Disable Asymptote insinuate Latex"
+ ["locally" asy-no-insinuate-locally :active t]
+ ["globally" asy-no-insinuate-globally :active t])
+ ("Debugger Buffer"
+ ["Visible" (setq asy-compilation-buffer 'visible) :style radio :selected (eq asy-compilation-buffer 'visible) :active t]
+ ["Available" (setq asy-compilation-buffer 'available) :style radio :selected (eq asy-compilation-buffer 'available) :active t]
+ ["None" (setq asy-compilation-buffer 'none) :style radio :selected (eq asy-compilation-buffer 'none) :active t]
+ ["Never" (setq asy-compilation-buffer 'never) :style radio :selected (eq asy-compilation-buffer 'never) :active t])
+ ))
+(if running-xemacs-p
+ (setq asy-latex-menu-item (nconc '("Asymptote") asy-latex-menu-item))
+ (setq asy-latex-menu-item (nconc '("Asymptote" :visible asy-insinuate-latex-p) asy-latex-menu-item)))
+
+(defun asy-insinuate-latex-maybe ()
+ "This function is added to `LaTeX-mode-hook' to define the environment 'asy'
+and, eventually, set its indentation.
+For internal use only."
+ (when (or asy-insinuate-latex-globally-p
+ (save-excursion
+ (beginning-of-buffer)
+ (save-match-data
+ (search-forward "\\begin{asy}" nil t))))
+ (asy-insinuate-latex))
+ (LaTeX-add-environments
+ '("asy" (lambda (env &rest ignore)
+ (unless asy-insinuate-latex-p (asy-insinuate-latex))
+ (LaTeX-insert-environment env)))))
+
+;; (add-hook 'after-init-hook
+;; (lambda ()
+(eval-after-load "latex"
+ '(progn
+ (add-hook 'LaTeX-mode-hook 'asy-insinuate-latex-maybe)
+ (setq lasy-mode-map (copy-keymap LaTeX-mode-map))
+ (setq LaTeX-mode-map-backup (copy-keymap LaTeX-mode-map))
+ (when lasy-extra-key
+ (define-key lasy-mode-map (kbd "<C-return>")
+ (lambda ()
+ (interactive)
+ (lasy-view-ps nil nil t)))
+ (define-key lasy-mode-map (kbd "<C-S-return>")
+ (lambda ()
+ (interactive)
+ (lasy-view-ps t nil t)))
+ (define-key lasy-mode-map (kbd "<M-return>")
+ (lambda ()
+ (interactive)
+ (lasy-view-pdf-via-pdflatex nil nil t)))
+ (define-key lasy-mode-map (kbd "<M-S-return>")
+ (lambda ()
+ (interactive)
+ (lasy-view-pdf-via-pdflatex t nil t)))
+ (define-key lasy-mode-map (kbd "<C-M-return>")
+ (lambda ()
+ (interactive)
+ (lasy-view-pdf-via-ps2pdf nil nil t)))
+ (define-key lasy-mode-map (kbd "<C-M-S-return>")
+ (lambda ()
+ (interactive)
+ (lasy-view-pdf-via-ps2pdf t nil t)))
+ (define-key lasy-mode-map (kbd "<f4>") 'asy-goto-error))
+
+ (easy-menu-define asy-latex-mode-menu lasy-mode-map "Asymptote insinuates LaTeX" asy-latex-menu-item)
+ ))
+;; ))
+
+(defvar asy-insinuate-latex-p nil
+ "Not nil when current buffer is insinuated by Asymptote.
+May be a local variable.
+For internal use.")
+
+(defvar asy-insinuate-latex-globally-p nil
+ "Not nil when all latex-mode buffers is insinuated by Asymptote.
+For internal use.")
+
+(defun asy-set-latex-asy-indentation ()
+ "Set the indentation of environnment 'asy' like the environnment 'verbatim' is."
+ ;; Regexp matching environments with indentation at col 0 for begin/end.
+ (set (make-local-variable 'LaTeX-verbatim-regexp)
+ (concat (default-value 'LaTeX-verbatim-regexp) "\\|asy"))
+ ;; Alist of environments with special indentation.
+ (make-local-variable 'LaTeX-indent-environment-list)
+ (add-to-list 'LaTeX-indent-environment-list
+ '("asy" current-indentation)))
+
+(defun asy-unset-latex-asy-indentation ()
+ "Unset the indentation of environnment 'asy' like the environnment 'verbatim' is."
+ (set (make-local-variable 'LaTeX-verbatim-regexp)
+ (default-value 'LaTeX-verbatim-regexp))
+ (set (make-local-variable 'LaTeX-indent-environment-list)
+ (default-value 'LaTeX-indent-environment-list)))
+
+(defun asy-no-insinuate-locally ()
+ (interactive)
+ (set (make-local-variable 'asy-insinuate-latex-p) nil)
+ (setq asy-insinuate-latex-globally-p nil)
+ (asy-unset-latex-asy-indentation)
+ (if running-xemacs-p
+ (easy-menu-remove-item nil nil "Asymptote")
+ (menu-bar-update-buffers))
+ (if (and (boundp 'two-mode-bool) two-mode-bool)
+ (lasy-mode))
+ (use-local-map LaTeX-mode-map-backup))
+
+
+(defun asy-no-insinuate-globally ()
+ (interactive)
+ (if running-xemacs-p
+ (easy-menu-remove-item nil nil "Asymptote")
+ (easy-menu-remove-item LaTeX-mode-map nil "Asymptote"))
+ (kill-local-variable asy-insinuate-latex-p)
+ (setq-default asy-insinuate-latex-p nil)
+ (setq asy-insinuate-latex-globally-p nil)
+ (if (not running-xemacs-p)
+ (menu-bar-update-buffers))
+ (setq LaTeX-mode-map (copy-keymap LaTeX-mode-map-backup))
+ ;;Disable lasy-mode in all latex-mode buffers.
+ (when (featurep 'two-mode-mode)
+ (mapc (lambda (buffer)
+ (with-current-buffer buffer
+ (when (and (buffer-file-name) (string= (file-name-extension (buffer-file-name)) "tex"))
+ (asy-unset-latex-asy-indentation)
+ (latex-mode)
+ (setq asy-insinuate-latex-p nil))))
+ (buffer-list))))
+
+;;;###autoload
+(defun asy-insinuate-latex (&optional global)
+ "Add a menu bar in current 'latex-mode' buffer and activate asy keys bindings.
+If the optional parameter (only for internal use) 'global' is 't' then all the FUTURE 'latex-mode' buffers are insinuated.
+To insinuate all (current and future) 'latex-mode' buffers, use 'asy-insinuate-latex-globally' instead.
+You can automate this feature for all the 'latex-mode' buffers by inserting the five following lines in your .emacs initialization file:
+ (eval-after-load \"latex\"
+ '(progn
+ ;; Add here your personal features for 'latex-mode':
+ (asy-insinuate-latex t) ;; Asymptote insinuates globally Latex.
+ ))"
+ (interactive)
+ (if (and (not asy-insinuate-latex-globally-p) (or global (string= major-mode "latex-mode")))
+ (progn
+ (asy-set-latex-asy-indentation)
+ (if global
+ (progn
+ (setq asy-insinuate-latex-p t)
+ (setq asy-insinuate-latex-globally-p t)
+ (setq LaTeX-mode-map (copy-keymap lasy-mode-map))
+ (if running-xemacs-p
+ (add-hook 'LaTeX-mode-hook
+ (lambda ()
+ (if asy-insinuate-latex-globally-p
+ (easy-menu-add asy-latex-mode-menu lasy-mode-map))))))
+ (progn
+ (use-local-map lasy-mode-map)
+ (easy-menu-add asy-latex-mode-menu lasy-mode-map)
+ (set (make-local-variable 'asy-insinuate-latex-p) t)))
+ )))
+
+(defun asy-insinuate-latex-globally ()
+ "Insinuates all (current and future) 'latex-mode' buffers.
+See `asy-insinuate-latex'."
+ (interactive)
+ (asy-insinuate-latex t)
+ (if running-xemacs-p
+ (add-hook 'LaTeX-mode-hook
+ (lambda ()
+ (if asy-insinuate-latex-globally-p
+ (easy-menu-add asy-latex-mode-menu lasy-mode-map)))))
+ (mapc (lambda (buffer)
+ (with-current-buffer buffer
+ (when (and
+ (buffer-file-name)
+ (string= (file-name-extension (buffer-file-name)) "tex"))
+ (setq asy-insinuate-latex-p t)
+ (use-local-map LaTeX-mode-map)
+ (use-local-map lasy-mode-map)
+ (asy-set-latex-asy-indentation)
+ (easy-menu-add asy-latex-mode-menu lasy-mode-map))))
+ (buffer-list)))
+
+(defun lasy-inline-p()
+ "Return nil if the option 'inline' is not used or if `lasy-compilation-inline-auto-detection' value is nil."
+ (if lasy-compilation-inline-auto-detection
+ (save-excursion
+ (re-search-backward "^[^%]* *\\\\usepackage\\[ *inline *\\]{ *asymptote *}" 0 t))
+ nil))
+
+(defvar lasy-run-tex nil)
+(defun lasy-asydef()
+ "Return the content between the tags \begin{asydef} and \end{asydef}."
+ (save-excursion
+ (if (re-search-backward "\\\\begin{asydef}" 0 t)
+ (buffer-substring
+ (progn (next-line)(beginning-of-line)(point))
+ (progn (re-search-forward "\\\\end{asydef}")
+ (previous-line)(end-of-line)
+ (point)))
+ "")))
+
+(defun lasy-compile-tex()
+ "Compile region between \\begin{asy}[text with backslash] and \\end{asy} passing by a reconstructed file .tex."
+ (interactive)
+ (setq lasy-run-tex t)
+ (save-excursion
+ (let* ((Filename (asy-get-temp-file-name t))
+ (FilenameTex (concat Filename ".tex"))
+ (asydef (lasy-asydef)))
+ (save-excursion
+ (beginning-of-buffer)
+ (write-region (point)
+ (progn
+ (re-search-forward "\\\\begin{document}.*\n")
+ (point)) FilenameTex)
+ (write-region (concat "\\begin{asydef}\n" asydef "\n\\end{asydef}\n") 0 FilenameTex t))
+ (re-search-backward "\\\\begin{asy}")
+ (write-region (point) (progn
+ (re-search-forward "\\\\end{asy}")
+ (point)) FilenameTex t)
+ (with-temp-file FilenameTex
+ (insert-file FilenameTex)
+ (end-of-buffer)
+ (insert "\n\\end{document}"))
+ (let ((default-directory asy-temp-dir))
+ (lasy-view-ps t Filename)))))
+
+(defun lasy-compile()
+ "Compile region between \\begin{asy} and \\end{asy}."
+ (interactive)
+ (if (or (lasy-inline-p) (progn ;; find \begin{asy}[any backslash]
+ (save-excursion
+ (re-search-forward "\\\\end{asy}" (point-max) t)
+ (re-search-backward "\\\\begin{asy}.*\\(\\[.*\\\\.*\\]\\)" 0 t))
+ (match-string 1)))
+ (progn
+ (lasy-compile-tex)) ;; a temporary TeX file must be reconstructed.
+ (progn
+ (setq lasy-run-tex nil)
+ (save-excursion
+ (let ((Filename (asy-get-temp-file-name))
+ (asydef (lasy-asydef)))
+ (write-region (match-string 0) 0 Filename)
+ (re-search-backward "\\\\begin{asy}")
+ (write-region (point) (progn
+ (re-search-forward "\\\\end{asy}")
+ (point)) Filename)
+ (with-temp-file Filename
+ (insert-file-contents Filename)
+ (beginning-of-buffer)
+ (if (re-search-forward "\\\\begin{asy}\\[\\(.*\\)\\]" (point-max) t)
+ (let ((sz (match-string 1)))
+ (replace-match "")
+ (insert (concat asydef "\nsize(" sz ");")))
+ (when (re-search-forward "\\\\begin{asy}" (point-max) t)
+ (replace-match "")
+ (insert asydef)))
+ (while (re-search-forward "\\\\end{asy}" (point-max) t)
+ (replace-match "")))
+ (let* ((asy-compile-command
+ (concat asy-command-location
+ asy-command
+ (if (eq asy-compilation-buffer 'never)
+ " " " -wait ")
+ (asy-protect-file-name Filename))))
+ (asy-internal-compile
+ asy-compile-command t
+ (not (eq asy-compilation-buffer 'never)))))))))
+
+(defun asy-set-master-tex ()
+ "Set the local variable 'asy-TeX-master-file.
+This variable is used by 'asy-master-tex-view-ps"
+ (interactive)
+ (set (make-local-variable 'asy-TeX-master-file)
+ (file-name-sans-extension
+ (file-relative-name
+ (expand-file-name
+ (read-file-name "TeX document: ")))))
+ (if (string= (concat default-directory asy-TeX-master-file)
+ (file-name-sans-extension buffer-file-name))
+ (prog1
+ (set (make-local-variable 'asy-TeX-master-file) nil)
+ (error "You should never give the same name to the TeX file and the Asymptote file"))
+ (save-excursion
+ (end-of-buffer)
+ (if (re-search-backward "asy-TeX-master-file\\(.\\)*$" 0 t)
+ (replace-match (concat "asy-TeX-master-file: \"" asy-TeX-master-file "\""))
+ (insert (concat "
+/// Local Variables:
+/// asy-TeX-master-file: \"" asy-TeX-master-file "\"
+/// End:")) t))))
+
+(defun asy-unset-master-tex ()
+ "Set the local variable 'asy-TeX-master-file to 'nil.
+This variable is used by 'asy-master-tex-view-ps"
+ (interactive)
+ (set (make-local-variable 'asy-TeX-master-file) nil)
+ (save-excursion
+ (end-of-buffer)
+ (if (re-search-backward "^.*asy-TeX-master-file:.*\n" 0 t)
+ (replace-match ""))))
+
+(defun asy-master-tex-error ()
+ "Asy-mode internal use..."
+ (if (y-or-n-p "You try to compile the TeX document that contains this picture.
+You must set the local variable asy-TeX-master-file.
+Do you want set this variable now ?")
+ (asy-set-master-tex) nil))
+
+(defun asy-master-tex-view (Func-view &optional Force fromtex)
+ "Compile the LaTeX document that contains the picture of the current Asymptote code with the function Func-view.
+Func-view can be one of 'lasy-view-ps, 'lasy-view-pdf-via-pdflatex, 'lasy-view-pdf-via-ps2pdf."
+ (interactive)
+ (if (or
+ (and (boundp two-mode-bool) two-mode-bool)
+ (string-match "latex" (downcase mode-name)))
+ (progn ;; Current mode is lasy-mode or latex-mode not asy-mode
+ (funcall Func-view Force nil fromtex))
+ (if asy-TeX-master-file
+ (if (string= asy-TeX-master-file
+ (file-name-sans-extension buffer-file-name))
+ (error "You should never give the same name to the TeX file and the Asymptote file")
+ (funcall Func-view Force asy-TeX-master-file fromtex))
+ (if (asy-master-tex-error)
+ (funcall Func-view Force asy-TeX-master-file fromtex)))))
+
+(defvar asy-last-compilation-code nil
+ "Code returned by the last compilation with `compile'.")
+
+(defvar asy-compilation-auto-close nil
+ "Variable to communicate with `asy-compilation-finish-function'.
+Do not set this variable in any fashion.")
+
+(defun asy-compilation-finish-function (buf msg)
+ "Function to automatically close the compilation buffer '*asy-compilation*'
+when no error or warning occurs."
+ (when (string-match "*asy-compilation*" (buffer-name buf))
+ (when (and asy-compilation-auto-close
+ (eq asy-compilation-buffer 'none))
+ (setq asy-compilation-auto-close nil)
+ (if (not (string-match "exited abnormally" msg))
+ (progn
+ (save-excursion
+ (set-buffer buf)
+ (beginning-of-buffer)
+ (if (not (search-forward-regexp "[wW]arning" nil t))
+ (when (not (eq asy-compilation-buffer 'visible))
+ ;;no errors/Warning, make the compilation window go away
+ (run-at-time 0.5 nil (lambda (buf_)
+ (delete-windows-on buf_)
+ (kill-buffer buf_)) buf)
+ (message (replace-regexp-in-string "\n" "" msg)))
+ (message "Compilation warnings..."))))))))
+
+(if running-xemacs-p
+ (setq compilation-finish-function 'asy-compilation-finish-function)
+ (add-to-list 'compilation-finish-functions
+ 'asy-compilation-finish-function))
+
+(defun asy-compilation-wait(&optional pass auto-close)
+ "Wait for process in *asy-compilation* exits.
+If pass is 't' don't wait.
+If auto-close is 't' close the window if the process exit with success."
+ (setq asy-compilation-auto-close auto-close)
+ (let* ((buff (get-buffer "*asy-compilation*"))
+ (comp-proc (get-buffer-process buff)))
+ (while (and comp-proc
+ (not (eq (process-status comp-proc) 'exit))
+ (not pass))
+ (setq comp-proc (get-buffer-process buff))
+ (sit-for 1)
+ (message "Waiting process...") ;; need message in Windows system
+ )
+ (message "") ;; Erase previous message.
+ (if (and (not pass) comp-proc)
+ (setq asy-last-compilation-code (process-exit-status comp-proc))
+ (setq asy-last-compilation-code 0))
+ (when (and (eq asy-compilation-buffer 'available)
+ (zerop asy-last-compilation-code))
+ (delete-windows-on buff))))
+
+
+(defun asy-internal-shell (command &optional pass)
+ "Execute 'command' in a inferior shell discarding output and
+redirecting stderr in the file given by the command `asy-log-filename'.
+`asy-internal-shell' waits for PROGRAM to terminate and returns a numeric exit status.
+The variable `asy-last-compilation-code' is always set to the exit status.
+The optional argument pass, for compatibility, is not used."
+ (let* ((log-file (asy-log-filename))
+ (discard (if pass 0 nil))
+ (status
+ (progn
+ (let ((view-inhibit-help-message t))(write-region "" 0 log-file nil))
+ (message "%s" command)
+ (call-process shell-file-name nil (list nil log-file) nil shell-command-switch command))))
+ (setq asy-last-compilation-code (if status status 0))
+ (if status status nil)))
+
+;; (defun asy-internal-shell (command &optional pass)
+;; "Execute 'command' in a inferior shell discarding output and
+;; redirecting stderr in the file given by the command `asy-log-filename'.
+;; pass non-nil means `asy-internal-shell' returns immediately with nil value.
+;; Otherwise it waits for PROGRAM to terminate and returns a numeric exit status.
+;; The variable `asy-last-compilation-code' is always set to the exit status or 0 if the
+;; process returns immediately."
+;; (let* ((log-file (asy-log-filename))
+;; (discard (if pass 0 nil))
+;; (status
+;; (progn
+;; (let ((inhibit-redisplay t))(write-region "" 0 log-file nil))
+;; (message "%s" command)
+;; (call-process shell-file-name nil (list discard log-file) nil shell-command-switch command))))
+;; (setq asy-last-compilation-code (if status status 0))
+;; (when pass (sit-for 1))
+;; (if status status nil)))
+
+(defun asy-internal-compile (command &optional pass auto-close stderr)
+ "Execute command.
+pass non-nil means don't wait the end of the process.
+auto-close non-nil means automatically close the compilation buffer.
+stderr non-nil means redirect the standard output error to the file
+returned by `asy-log-filename'.
+In this case command is running in an inferior shell without any output and
+the parameter auto-close is not used (see `asy-internal-shell')."
+ (setq asy-last-compilation-code -1)
+ (let* ((compilation-buffer-name "*asy-compilation*")
+ (compilation-buffer-name-function (lambda (mj) compilation-buffer-name)))
+ (if (or stderr (eq asy-compilation-buffer 'never))
+ (progn
+ (asy-internal-shell command pass)
+ (asy-error-message t))
+ (progn
+ (let ((comp-proc (get-buffer-process compilation-buffer-name)))
+ (if comp-proc
+ (condition-case ()
+ (progn
+ (interrupt-process comp-proc)
+ (sit-for 1)
+ (delete-process comp-proc)
+ (when (and asy-compilation-auto-close
+ (eq asy-compilation-buffer 'none)
+ (not (eq asy-compilation-buffer 'visible)))
+ (sit-for 0.6)))
+ (error ""))
+ ))
+ (let ((view-inhibit-help-message t))
+ (write-region "" 0 (asy-log-filename) nil))
+ (compile command))
+ (asy-compilation-wait pass auto-close))))
+
+(defun asy-open-file(Filename)
+ "Open the ps or pdf file Filename.
+In unix-like system the variables `ps-view-command' and `pdf-view-command' are used.
+In Windows the associated system file type is used instead."
+ (let ((command
+ (if running-unix-p
+ (let ((ext (file-name-extension Filename)))
+ (cond
+ ((string= ext "ps") ps-view-command)
+ ((string= ext "pdf") pdf-view-command)
+ (t (error "Extension Not Supported."))))
+ (asy-protect-file-name (file-name-nondirectory Filename))))
+ )
+ (if running-unix-p
+ (start-process "" nil command Filename)
+ (call-process-shell-command command nil 0))))
+
+(defun lasy-view-ps (&optional Force Filename fromtex)
+ "Compile a LaTeX document embedding Asymptote code with latex->asy->latex->dvips and/or view the PostScript output.
+If optional argument Force is t then force compilation."
+ (interactive)
+ (setq lasy-run-tex t)
+ (setq lasy-compile-tex fromtex)
+ (if (buffer-modified-p) (save-buffer))
+ (let*
+ ((b-b-n (if Filename Filename (file-name-sans-extension buffer-file-name)))
+ (b-b-n-tex (asy-protect-file-name (concat b-b-n ".tex")))
+ (b-b-n-ps (asy-protect-file-name (concat b-b-n ".ps")))
+ (b-b-n-dvi (asy-protect-file-name (concat b-b-n ".dvi")))
+ (b-b-n-asy (asy-protect-file-name (concat b-b-n ".asy")))
+ (stderr (eq asy-compilation-buffer 'never)))
+ (if (or (file-newer-than-file-p
+ (concat b-b-n ".tex")
+ (concat b-b-n ".ps"))
+ Force)
+ (progn
+ (asy-internal-compile (concat lasy-latex-command " " b-b-n-tex))
+ (when (and (zerop asy-last-compilation-code) (file-readable-p (concat b-b-n ".asy")))
+ (asy-internal-compile (concat asy-command-location lasy-command " " b-b-n-asy) nil nil stderr)
+ (when (zerop asy-last-compilation-code)
+ (asy-internal-compile (concat lasy-latex-command " " b-b-n-tex))))
+ (when (zerop asy-last-compilation-code)
+ (asy-internal-compile (concat lasy-dvips-command " " b-b-n-dvi " -o " b-b-n-ps) nil t)
+ (when (zerop asy-last-compilation-code)
+ (asy-open-file (concat b-b-n ".ps")))))
+ (asy-open-file (concat b-b-n ".ps")))))
+
+(defun lasy-view-pdf-via-pdflatex (&optional Force Filename fromtex)
+ "Compile a LaTeX document embedding Asymptote code with pdflatex->asy->pdflatex and/or view the PDF output.
+If optional argument Force is t then force compilation."
+ (interactive)
+ (setq lasy-run-tex t)
+ (setq lasy-compile-tex fromtex)
+ (if (buffer-modified-p) (save-buffer))
+ (when (eq asy-compilation-buffer 'never) (write-region "" 0 (asy-log-filename) nil))
+ (let*
+ ((b-b-n (if Filename Filename (file-name-sans-extension buffer-file-name)))
+ (b-b-n-tex (asy-protect-file-name (concat b-b-n ".tex")))
+ (b-b-n-pdf (asy-protect-file-name (concat b-b-n ".pdf")))
+ (b-b-n-asy (asy-protect-file-name (concat b-b-n ".asy")))
+ ;; (stderr (or (eq asy-compilation-buffer 'never) lasy-compile-tex)))
+ (stderr (eq asy-compilation-buffer 'never)))
+ (if (or (file-newer-than-file-p
+ (concat b-b-n ".tex")
+ (concat b-b-n ".pdf"))
+ Force)
+ (progn
+ (asy-internal-compile (concat lasy-pdflatex-command " " b-b-n-tex))
+ (when (and (zerop asy-last-compilation-code) (file-readable-p (concat b-b-n ".asy")))
+ (asy-internal-compile (concat asy-command-location lasy-command " " b-b-n-asy) nil nil stderr)
+ (when (zerop asy-last-compilation-code)
+ (asy-internal-compile (concat lasy-pdflatex-command " " b-b-n-tex) t)))
+ (when (zerop asy-last-compilation-code)
+ (asy-open-file (concat b-b-n ".pdf"))))
+ (asy-open-file (concat b-b-n ".pdf")))))
+
+(defun lasy-view-pdf-via-ps2pdf (&optional Force Filename fromtex)
+ "Compile a LaTeX document embedding Asymptote code with latex->asy->latex->dvips->ps2pdf14 and/or view the PDF output.
+If optional argument Force is t then force compilation."
+ (interactive)
+ (setq lasy-run-tex t)
+ (setq lasy-compile-tex fromtex)
+ (if (buffer-modified-p) (save-buffer))
+ (when (eq asy-compilation-buffer 'never) (write-region "" 0 (asy-log-filename) nil))
+ (let*
+ ((b-b-n (if Filename Filename (file-name-sans-extension buffer-file-name)))
+ (b-b-n-tex (asy-protect-file-name (concat b-b-n ".tex")))
+ (b-b-n-ps (asy-protect-file-name (concat b-b-n ".ps")))
+ (b-b-n-dvi (asy-protect-file-name (concat b-b-n ".dvi")))
+ (b-b-n-pdf (asy-protect-file-name (concat b-b-n ".pdf")))
+ (b-b-n-asy (asy-protect-file-name (concat b-b-n ".asy")))
+ ;; (stderr (or (eq asy-compilation-buffer 'never) lasy-compile-tex)))
+ (stderr (eq asy-compilation-buffer 'never)))
+ (if (or (file-newer-than-file-p
+ (concat b-b-n ".tex")
+ (concat b-b-n ".pdf"))
+ Force)
+ (progn
+ (asy-internal-compile (concat lasy-latex-command " " b-b-n-tex))
+ (when (and (zerop asy-last-compilation-code) (file-readable-p (concat b-b-n ".asy")))
+ (asy-internal-compile (concat asy-command-location lasy-command " " b-b-n-asy) nil nil stderr)
+ (when (zerop asy-last-compilation-code)
+ (asy-internal-compile (concat lasy-latex-command " " b-b-n-tex))))
+ (when (zerop asy-last-compilation-code)
+ (asy-internal-compile (concat lasy-dvips-pre-pdf-command " " b-b-n-dvi " -o " b-b-n-ps))
+ (when (zerop asy-last-compilation-code)
+ (asy-internal-compile (concat lasy-ps2pdf-command " " b-b-n-ps " " b-b-n-pdf) t)
+ (when (zerop asy-last-compilation-code)
+ (asy-open-file (concat b-b-n ".pdf"))))))
+ (asy-open-file (concat b-b-n ".pdf")))))
+
+;; Goto error of last compilation
+(define-key asy-mode-map (kbd "<f4>") 'asy-goto-error)
+
+;; Save and compile the file with option -V
+(define-key asy-mode-map (kbd "C-c C-c") 'asy-compile)
+
+;; Show the definitions of command at point
+(define-key asy-mode-map (kbd "C-c ?") 'asy-show-function-at-point)
+
+;; new line and indent
+(define-key asy-mode-map (kbd "RET") 'newline-and-indent)
+
+(defun asy-master-tex-view-ps ()
+ "Look at `asy-master-tex-view'"
+ (interactive)
+ (asy-master-tex-view 'lasy-view-ps nil t))
+(define-key asy-mode-map (kbd "<C-return>") 'asy-master-tex-view-ps)
+
+(defun asy-master-tex-view-ps-f ()
+ "Look at `asy-master-tex-view'"
+ (interactive)
+ (asy-master-tex-view 'lasy-view-ps t t))
+(define-key asy-mode-map (kbd "<C-S-return>") 'asy-master-tex-view-ps-f)
+
+(defun asy-master-tex-view-pdflatex ()
+ "Look at `asy-master-tex-view'"
+ (interactive)
+ (asy-master-tex-view 'lasy-view-pdf-via-pdflatex nil t))
+(define-key asy-mode-map (kbd "<M-return>") 'asy-master-tex-view-pdflatex)
+
+(defun asy-master-tex-view-pdflatex-f ()
+ "Look at `asy-master-tex-view'"
+ (interactive)
+ (asy-master-tex-view 'lasy-view-pdf-via-pdflatex t t))
+(define-key asy-mode-map (kbd "<M-S-return>") 'asy-master-tex-view-pdflatex-f)
+
+(defun asy-master-tex-view-ps2pdf ()
+ "Look at `asy-master-tex-view'"
+ (interactive)
+ (asy-master-tex-view 'lasy-view-pdf-via-ps2pdf nil t))
+(define-key asy-mode-map (kbd "<C-M-return>") 'asy-master-tex-view-ps2pdf)
+
+(defun asy-master-tex-view-ps2pdf-f ()
+ "Look at `asy-master-tex-view'"
+ (interactive)
+ (asy-master-tex-view 'lasy-view-pdf-via-ps2pdf t t))
+(define-key asy-mode-map (kbd "<C-M-S-return>") 'asy-master-tex-view-ps2pdf-f)
+
+(provide `asy-mode)
diff --git a/Build/source/utils/asymptote/base/asy.vim b/Build/source/utils/asymptote/base/asy.vim
new file mode 100644
index 00000000000..4cb897f1316
--- /dev/null
+++ b/Build/source/utils/asymptote/base/asy.vim
@@ -0,0 +1,202 @@
+" Vim syntax file
+" Language: Asymptote
+" Maintainer: Andy Hammerlindl
+" Last Change: 2005 Aug 23
+
+" Hacked together from Bram Moolenaar's C syntax file, and Claudio Fleiner's
+" Java syntax file.
+
+" For version 5.x: Clear all syntax items
+" For version 6.x: Quit when a syntax file was already loaded
+if version < 600
+ syntax clear
+elseif exists("b:current_syntax")
+ finish
+endif
+
+" A bunch of useful C keywords
+syn keyword asyStatement break return continue unravel
+syn keyword asyConditional if else
+syn keyword asyRepeat while for do
+syn keyword asyExternal access from import include
+syn keyword asyOperator new operator
+
+syn keyword asyTodo contained TODO FIXME XXX
+
+" asyCommentGroup allows adding matches for special things in comments
+syn cluster asyCommentGroup contains=asyTodo
+
+" String and Character constants
+" Highlight special characters (those proceding a double backslash) differently
+syn match asySpecial display contained "\\\\."
+" Highlight line continuation slashes
+syn match asySpecial display contained "\\$"
+syn region asyString start=+"+ skip=+\\\\\|\\"+ end=+"+ contains=asySpecial
+ " asyCppString: same as asyString, but ends at end of line
+if 0
+syn region asyCppString start=+"+ skip=+\\\\\|\\"\|\\$+ excludenl end=+"+ end='$' contains=asySpecial
+endif
+
+"when wanted, highlight trailing white space
+if exists("asy_space_errors")
+ if !exists("asy_no_trail_space_error")
+ syn match asySpaceError display excludenl "\s\+$"
+ endif
+ if !exists("asy_no_tab_space_error")
+ syn match asySpaceError display " \+\t"me=e-1
+ endif
+endif
+
+"catch errors caused by wrong parenthesis and brackets
+syn cluster asyParenGroup contains=asyParenError,asyIncluded,asySpecial,asyCommentSkip,asyCommentString,asyComment2String,@asyCommentGroup,asyCommentStartError,asyUserCont,asyUserLabel,asyBitField,asyCommentSkip,asyOctalZero,asyCppOut,asyCppOut2,asyCppSkip,asyFormat,asyNumber,asyFloat,asyOctal,asyOctalError,asyNumbersCom
+if exists("asy_no_bracket_error")
+ syn region asyParen transparent start='(' end=')' contains=ALLBUT,@asyParenGroup,asyCppParen,asyCppString
+ " asyCppParen: same as asyParen but ends at end-of-line; used in asyDefine
+ syn region asyCppParen transparent start='(' skip='\\$' excludenl end=')' end='$' contained contains=ALLBUT,@asyParenGroup,asyParen,asyString
+ syn match asyParenError display ")"
+ syn match asyErrInParen display contained "[{}]"
+else
+ syn region asyParen transparent start='(' end=')' contains=ALLBUT,@asyParenGroup,asyCppParen,asyErrInBracket,asyCppBracket,asyCppString
+ " asyCppParen: same as asyParen but ends at end-of-line; used in asyDefine
+ syn region asyCppParen transparent start='(' skip='\\$' excludenl end=')' end='$' contained contains=ALLBUT,@asyParenGroup,asyErrInBracket,asyParen,asyBracket,asyString
+if 0
+ syn match asyParenError display "[\])]"
+ syn match asyErrInParen display contained "[\]]"
+endif
+ syn region asyBracket transparent start='\[' end=']' contains=ALLBUT,@asyParenGroup,asyErrInParen,asyCppParen,asyCppBracket,asyCppString
+ " asyCppBracket: same as asyParen but ends at end-of-line; used in asyDefine
+ syn region asyCppBracket transparent start='\[' skip='\\$' excludenl end=']' end='$' contained contains=ALLBUT,@asyParenGroup,asyErrInParen,asyParen,asyBracket,asyString
+ syn match asyErrInBracket display contained "[);]"
+endif
+
+"integer number, or floating point number without a dot and with "f".
+syn case ignore
+syn match asyNumbers display transparent "\<\d\|\.\d" contains=asyNumber,asyFloat
+syn match asyNumber display contained "\d\+"
+"floating point number, with dot, optional exponent
+syn match asyFloat display contained "\d\+\.\d*\(e[-+]\=\d\+\)\="
+"floating point number, starting with a dot, optional exponent
+syn match asyFloat display contained "\.\d\+\(e[-+]\=\d\+\)\="
+"floating point number, without dot, with exponent
+syn match asyFloat display contained "\d\+e[-+]\=\d\+"
+syn case match
+
+if exists("asy_comment_strings")
+ " A comment can contain asyString, asyCharacter and asyNumber.
+ " But a "*/" inside a asyString in a asyComment DOES end the comment! So we
+ " need to use a special type of asyString: asyCommentString, which also ends on
+ " "*/", and sees a "*" at the start of the line as comment again.
+ " Unfortunately this doesn't very well work for // type of comments :-(
+ syntax match asyCommentSkip contained "^\s*\*\($\|\s\+\)"
+ syntax region asyCommentString contained start=+L\="+ skip=+\\\\\|\\"+ end=+"+ end=+\*/+me=s-1 contains=asySpecial,asyCommentSkip
+ syntax region asyComment2String contained start=+L\="+ skip=+\\\\\|\\"+ end=+"+ end="$" contains=asySpecial
+ syntax region asyCommentL start="//" skip="\\$" end="$" keepend contains=@asyCommentGroup,asyComment2String,asyCharacter,asyNumbersCom,asySpaceError
+ syntax region asyComment matchgroup=asyCommentStart start="/\*" matchgroup=NONE end="\*/" contains=@asyCommentGroup,asyCommentStartError,asyCommentString,asyCharacter,asyNumbersCom,asySpaceError
+else
+ syn region asyCommentL start="//" skip="\\$" end="$" keepend contains=@asyCommentGroup,asySpaceError
+ syn region asyComment matchgroup=asyCommentStart start="/\*" matchgroup=NONE end="\*/" contains=@asyCommentGroup,asyCommentStartError,asySpaceError
+endif
+" keep a // comment separately, it terminates a preproc. conditional
+syntax match asyCommentError display "\*/"
+syntax match asyCommentStartError display "/\*"me=e-1 contained
+
+syn keyword asyType void bool int real string
+syn keyword asyType pair triple transform guide path pen frame
+syn keyword asyType picture
+
+syn keyword asyStructure struct typedef
+syn keyword asyStorageClass static public readable private explicit
+
+syn keyword asyPathSpec and cycle controls tension atleast curl
+
+syn keyword asyConstant true false
+syn keyword asyConstant null nullframe nullpath
+
+if exists("asy_syn_plain")
+ syn keyword asyConstant currentpicture currentpen currentprojection
+ syn keyword asyConstant inch inches cm mm bp pt up down right left
+ syn keyword asyConstant E NE N NW W SW S SE
+ syn keyword asyConstant ENE NNE NNW WNW WSW SSW SSE ESE
+ syn keyword asyConstant I pi twopi
+ syn keyword asyConstant solid dotted dashed dashdotted
+ syn keyword asyConstant longdashed longdashdotted
+ syn keyword asyConstant squarecap roundcap extendcap
+ syn keyword asyConstant miterjoin roundjoin beveljoin
+ syn keyword asyConstant zerowinding evenodd
+ syn keyword asyConstant invisible black gray grey white
+ syn keyword asyConstant lightgray lightgrey
+ syn keyword asyConstant red green blue
+ syn keyword asyConstant cmyk Cyan Magenta Yellow Black
+ syn keyword asyConstant yellow magenta cyan
+ syn keyword asyConstant brown darkgreen darkblue
+ syn keyword asyConstant orange purple royalblue olive
+ syn keyword asyConstant chartreuse fuchsia salmon lightblue springgreen
+ syn keyword asyConstant pink
+endif
+
+syn sync ccomment asyComment minlines=15
+
+" Define the default highlighting.
+" For version 5.7 and earlier: only when not done already
+" For version 5.8 and later: only when an item doesn't have highlighting yet
+if version >= 508 || !exists("did_asy_syn_inits")
+ if version < 508
+ let did_asy_syn_inits = 1
+ command -nargs=+ HiLink hi link <args>
+ else
+ command -nargs=+ HiLink hi def link <args>
+ endif
+
+ HiLink asyFormat asySpecial
+ HiLink asyCppString asyString
+ HiLink asyCommentL asyComment
+ HiLink asyCommentStart asyComment
+ HiLink asyLabel Label
+ HiLink asyUserLabel Label
+ HiLink asyConditional Conditional
+ HiLink asyRepeat Repeat
+ HiLink asyCharacter Character
+ HiLink asySpecialCharacter asySpecial
+ HiLink asyNumber Number
+ HiLink asyOctal Number
+ HiLink asyOctalZero PreProc " link this to Error if you want
+ HiLink asyFloat Float
+ HiLink asyOctalError asyError
+ HiLink asyParenError asyError
+ HiLink asyErrInParen asyError
+ HiLink asyErrInBracket asyError
+ HiLink asyCommentError asyError
+ HiLink asyCommentStartError asyError
+ HiLink asySpaceError asyError
+ HiLink asySpecialError asyError
+ HiLink asyOperator Operator
+ HiLink asyStructure Structure
+ HiLink asyStorageClass StorageClass
+ HiLink asyExternal Include
+ HiLink asyPreProc PreProc
+ HiLink asyDefine Macro
+ HiLink asyIncluded asyString
+ HiLink asyError Error
+ HiLink asyStatement Statement
+ HiLink asyPreCondit PreCondit
+ HiLink asyType Type
+ HiLink asyConstant Constant
+ HiLink asyCommentString asyString
+ HiLink asyComment2String asyString
+ HiLink asyCommentSkip asyComment
+ HiLink asyString String
+ HiLink asyComment Comment
+ HiLink asySpecial SpecialChar
+ HiLink asyTodo Todo
+ HiLink asyCppSkip asyCppOut
+ HiLink asyCppOut2 asyCppOut
+ HiLink asyCppOut Comment
+ HiLink asyPathSpec Statement
+
+
+ delcommand HiLink
+endif
+
+let b:current_syntax = "c"
+
+" vim: ts=8
diff --git a/Build/source/utils/asymptote/base/asymptote.py b/Build/source/utils/asymptote/base/asymptote.py
new file mode 100755
index 00000000000..721c464d36b
--- /dev/null
+++ b/Build/source/utils/asymptote/base/asymptote.py
@@ -0,0 +1,48 @@
+# Python module to feed Asymptote with commands
+# (modified from gnuplot.py)
+from subprocess import *
+class asy:
+ def __init__(self):
+ self.session = Popen(['asy','-quiet','-interactive'],stdin=PIPE)
+ self.help()
+ def send(self, cmd):
+ self.session.stdin.write(cmd+'\n')
+ self.session.stdin.flush()
+ def size(self, size):
+ self.send("size(%d);" % size)
+ def draw(self, str):
+ self.send("draw(%s);" % str)
+ def fill(self, str):
+ self.send("fill(%s);" % str)
+ def clip(self, str):
+ self.send("clip(%s);" % str)
+ def label(self, str):
+ self.send("label(%s);" % str)
+ def shipout(self, str):
+ self.send("shipout(\"%s\");" % str)
+ def erase(self):
+ self.send("erase();")
+ def help(self):
+ print "Asymptote session is open. Available methods are:"
+ print " help(), size(int), draw(str), fill(str), clip(str), label(str), shipout(str), send(str), erase()"
+ def __del__(self):
+ print "closing Asymptote session..."
+ self.send('quit');
+ self.session.stdin.close();
+ self.session.wait()
+
+
+
+
+
+if __name__=="__main__":
+ g = asy()
+ g.size(200)
+ g.draw("unitcircle")
+ g.send("draw(unitsquare)")
+ g.fill("unitsquare, blue")
+ g.clip("unitcircle")
+ g.label("\"$O$\", (0,0), SW")
+ raw_input("press ENTER to continue")
+ g.erase()
+ del g
diff --git a/Build/source/utils/asymptote/base/babel.asy b/Build/source/utils/asymptote/base/babel.asy
new file mode 100644
index 00000000000..e93dec2a5cb
--- /dev/null
+++ b/Build/source/utils/asymptote/base/babel.asy
@@ -0,0 +1,4 @@
+void babel(string s)
+{
+ usepackage("babel",s);
+}
diff --git a/Build/source/utils/asymptote/base/bezulate.asy b/Build/source/utils/asymptote/base/bezulate.asy
new file mode 100644
index 00000000000..c47f3144912
--- /dev/null
+++ b/Build/source/utils/asymptote/base/bezulate.asy
@@ -0,0 +1,258 @@
+// Bezier triangulation routines written by Orest Shardt, 2008.
+
+private real fuzz = sqrtEpsilon;
+
+int countIntersections(path[] p, pair start, pair end)
+{
+ int intersects=0;
+ for(path q : p)
+ intersects += intersections(q,start--end,fuzz).length;
+ return intersects;
+}
+
+path[][] containmentTree(path[] paths)
+{
+ path[][] result;
+ for(int i=0; i < paths.length; ++i) {
+ bool classified=false;
+ // check if current curve contains or is contained in a group of curves
+ for(int j=0; !classified && j < result.length; ++j)
+ {
+ int test = inside(paths[i],result[j][0],zerowinding);
+ if(test == 1) // current curve contains group's toplevel curve
+ {
+ // replace toplevel curve with current curve
+ result[j].insert(0,paths[i]);
+ classified = true;
+ }
+ else if(test == -1) // current curve contained in group's toplevel curve
+ {
+ result[j].push(paths[i]);
+ classified = true;
+ }
+ }
+ // create a new group if this curve does not belong to another group
+ if(!classified)
+ result.push(new path[] {paths[i]});
+ }
+
+ // sort group so that later paths in the array are contained in previous paths
+ bool comparepaths(path i, path j) {return inside(i,j,zerowinding)==1;}
+ for(int i=0; i < result.length; ++i)
+ result[i] = sort(result[i],comparepaths);
+
+ return result;
+}
+
+bool isDuplicate(pair a, pair b, real relSize)
+{
+ return abs(a-b) <= sqrtEpsilon*relSize;
+}
+
+path removeDuplicates(path p)
+{
+ real relSize = abs(max(p)-min(p));
+ bool cyclic=cyclic(p);
+ for(int i=0; i < length(p); ++i) {
+ if(isDuplicate(point(p,i),point(p,i+1),relSize)) {
+ p=subpath(p,0,i)&subpath(p,i+1,length(p));
+ --i;
+ }
+ }
+ return cyclic ? p&cycle : p;
+}
+
+path section(path p, real t1, real t2, bool loop=false)
+{
+ if(t2 < t1 || loop && t1 == t2)
+ t2 += length(p);
+ return subpath(p,t1,t2);
+}
+
+path uncycle(path p, real t)
+{
+ return subpath(p,t,t+length(p));
+}
+
+// returns outer paths
+void connect(path[] paths, path[] result, path[] patch)
+{
+ path[][] tree=containmentTree(paths);
+ for(path[] group : tree) {
+ path outer = group[0];
+ group.delete(0);
+ path[][] innerTree = containmentTree(group);
+ path[] remainingCurves;
+ path[] inners;
+ for(path[] innerGroup:innerTree)
+ {
+ inners.push(innerGroup[0]);
+ if(innerGroup.length>1)
+ remainingCurves.append(innerGroup[1:]);
+ }
+ connect(remainingCurves,result,patch);
+ real d=2*abs(max(outer)-min(outer));
+ while(inners.length > 0) {
+ int curveIndex = 0;
+ real starttime = 0; // starttime is time on inners[curveIndex]
+ pair direction=I*dir(inners[curveIndex],starttime);
+ pair start=point(inners[curveIndex],starttime);
+
+ // find first intersection of line segment with outer curve
+ path line = start--start+d*direction;
+ real[][] ints=intersections(line,outer,fuzz);
+ assert(ints.length != 0);
+ real endtime=ints[0][1]; // endtime is time on outer
+ pair end = point(outer,endtime);
+ line = start--end;
+ path rline = reverse(line);
+
+ // find first intersection of rline segment with any inner curve
+ real earliestTime=1;
+ for(int j=0; j < inners.length; ++j) {
+ real[][] ints=intersections(rline,inners[j],fuzz);
+ if(ints.length > 0 && ints[0][0] < earliestTime) {
+ earliestTime=ints[0][0]; // time on rline
+ starttime=ints[0][1]; // time on inner curve
+ curveIndex=j;
+ }
+ }
+ start=point(inners[curveIndex],starttime);
+ line = start--end;
+
+ real timeoffset=2;
+ bool found=false;
+ path portion;
+ path[] allCurves = {outer};
+ allCurves.append(inners);
+
+ while(!found && timeoffset > fuzz) {
+ timeoffset /= 2;
+ if(countIntersections(allCurves,start,
+ point(outer,endtime+timeoffset)) == 2)
+ {
+ portion = subpath(outer,endtime,endtime+timeoffset)--start--cycle;
+ found=true;
+ // check if an inner curve is inside the portion
+ for(int k = 0; found && k < inners.length; ++k)
+ {
+ if(k!=curveIndex &&
+ inside(portion,point(inners[k],0),zerowinding))
+ found = false;
+ }
+ }
+ }
+
+ if(!found)timeoffset=-2;
+ while(!found && timeoffset < -fuzz) {
+ timeoffset /= 2;
+ if(countIntersections(allCurves,start,
+ point(outer,endtime+timeoffset))==2)
+ {
+ portion = subpath(outer,endtime+timeoffset,endtime)--start--cycle;
+ found = true;
+ // check if an inner curve is inside the portion
+ for(int k = 0; found && k < inners.length; ++k)
+ {
+ if(k!=curveIndex &&
+ inside(portion,point(inners[k],0),zerowinding))
+ found = false;
+ }
+ }
+ }
+ assert(found);
+ endtime=min(endtime,endtime+timeoffset);
+ timeoffset=abs(timeoffset);
+
+ // depends on the curves having opposite orientations
+ path remainder=section(outer,endtime+timeoffset,endtime)
+ --uncycle(inners[curveIndex],
+ starttime)--cycle;
+ inners.delete(curveIndex);
+ outer = remainder;
+ patch.append(portion);
+ }
+ result.append(outer);
+ }
+}
+
+int countIntersections(path g, pair p, pair q)
+{
+ int ints=0;
+ int l=length(g);
+ for(int i=1; i <= l; ++i)
+ ints += intersections(subpath(g,i-1,i),p--q,fuzz).length;
+ return ints;
+}
+
+bool checkSegment(path g, pair p, pair q)
+{
+ pair mid=0.5*(p+q);
+ return countIntersections(g,p,q) == 4 && inside(g,mid,zerowinding) &&
+ intersections(g,mid).length == 0;
+}
+
+path subdivide(path p)
+{
+ path q;
+ int l=length(p);
+ for(int i=0; i < l; ++i)
+ q=q&subpath(p,i,i+0.5)&subpath(p,i+0.5,i+1);
+ return cyclic(p) ? q&cycle : q;
+}
+
+path[] bezulate(path[] p)
+{
+ if(p.length == 1 && length(p[0]) <= 4) return p;
+ path[] patch;
+ path[] result;
+ connect(p,result,patch);
+ for(int i=0; i < result.length; ++i) {
+ path p=result[i];
+ int refinements=0;
+ if(size(p) <= 1) return p;
+ if(!cyclic(p))
+ abort("path must be cyclic and nonselfintersecting.");
+ p=removeDuplicates(p);
+ if(length(p) > 4) {
+ static real SIZE_STEPS=10;
+ static real factor=1.05/SIZE_STEPS;
+ for(int k=1; k <= SIZE_STEPS; ++k) {
+ real L=factor*k*abs(max(p)-min(p));
+ for(int i=0; length(p) > 4 && i < length(p); ++i) {
+ bool found=false;
+ pair start=point(p,i);
+ //look for quadrilaterals and triangles with one line, 4 | 3 curves
+ for(int desiredSides=4; !found && desiredSides >= 3;
+ --desiredSides) {
+ if(desiredSides == 3 && length(p) <= 3)
+ break;
+ pair end;
+ int endi=i+desiredSides-1;
+ end=point(p,endi);
+ found=checkSegment(p,start,end) && abs(end-start) < L;
+ if(found) {
+ path p1=subpath(p,endi,i+length(p))--cycle;
+ patch.append(subpath(p,i,endi)--cycle);
+ p=removeDuplicates(p1);
+ i=-1; // increment will make i be 0
+ }
+ }
+ if(!found && k == SIZE_STEPS && length(p) > 4 && i == length(p)-1) {
+ // avoid infinite recursion
+ ++refinements;
+ if(refinements > mantissaBits) {
+ write("warning: too many subdivisions");
+ } else {
+ p=subdivide(p);
+ i=-1;
+ }
+ }
+ }
+ }
+ }
+ if(length(p) <= 4)
+ patch.append(p);
+ }
+ return patch;
+}
diff --git a/Build/source/utils/asymptote/base/binarytree.asy b/Build/source/utils/asymptote/base/binarytree.asy
new file mode 100644
index 00000000000..7bbd1de2148
--- /dev/null
+++ b/Build/source/utils/asymptote/base/binarytree.asy
@@ -0,0 +1,326 @@
+/* **********************************************************************
+ * binarytree: An Asymptote module to draw binary trees *
+ * *
+ * Copyright (C) 2006 *
+ * Tobias Langner tobias[at]langner[dot]nightlabs[dot]de *
+ * *
+ * Modified by John Bowman *
+ * *
+ ************************************************************************
+ * *
+ * 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 3 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., *
+ * 51 Franklin St, Fifth Floor, *
+ * Boston, MA 02110-1301 USA *
+ * *
+ * Or get it online: *
+ * http://www.gnu.org/copyleft/lesser.html *
+ * *
+ ***********************************************************************/
+
+/**
+ * default values
+ */
+real minDistDefault=0.2cm;
+real nodeMarginDefault=0.1cm;
+
+/**
+ * structure to represent nodes in a binary tree
+ */
+struct binarytreeNode {
+ int key;
+ binarytreeNode left;
+ binarytreeNode right;
+ binarytreeNode parent;
+
+ /**
+ * sets the left child of this node
+ */
+ void setLeft(binarytreeNode left) {
+ this.left=left;
+ this.left.parent=this;
+ }
+
+ /**
+ * sets the right child of this node
+ */
+ void setRight(binarytreeNode right) {
+ this.right=right;
+ this.right.parent=this;
+ }
+
+ /**
+ * returns a boolean indicating whether this node is the root
+ */
+ bool isRoot() {
+ return parent == null;
+ }
+
+ /**
+ * Returns the level of the subtree rooted at this node.
+ */
+ int getLevel() {
+ if(isRoot())
+ return 1;
+ else
+ return parent.getLevel()+1;
+ }
+
+ /**
+ * sets the children of this binarytreeNode
+ */
+ void setChildren(binarytreeNode left, binarytreeNode right) {
+ setLeft(left);
+ setRight(right);
+ }
+
+ /**
+ * creates a new binarytreeNode with key <key>
+ */
+ static binarytreeNode binarytreeNode(int key) {
+ binarytreeNode toReturn=new binarytreeNode;
+ toReturn.key=key;
+ return toReturn;
+ }
+
+ /**
+ * returns the height of the subtree rooted at this node.
+ */
+ int getHeight() {
+ if(left == null && right == null)
+ return 1;
+ if(left == null)
+ return right.getHeight()+1;
+ if(right == null)
+ return left.getHeight()+1;
+
+ return max(left.getHeight(),right.getHeight())+1;
+ }
+}
+
+binarytreeNode operator init() {return null;}
+
+/**
+ * "constructor" for binarytreeNode
+ */
+binarytreeNode binarytreeNode(int key)=binarytreeNode.binarytreeNode;
+
+
+/**
+ * draws the tree rooted at the given <node> at the given position <pos>, with
+ * <height>: the height of the containing tree,
+ * <minDist>: the minimal horizontal distance of two nodes at the lowest level,
+ * <levelDist> the vertical distance between two levels,
+ * <nodeDiameter>: the diameter of one node.
+ */
+object draw(picture pic=currentpicture, binarytreeNode node, pair pos,
+ int height, real minDist, real levelDist, real nodeDiameter,
+ pen p=currentpen) {
+ Label label=Label(math((string) node.key),pos);
+
+ binarytreeNode left=node.left;
+ binarytreeNode right=node.right;
+
+ /**
+ * returns the distance for two nodes at the given <level> when the
+ * containing tree has height <height>
+ * and the minimal distance between two nodes is <minDist>.
+ */
+ real getDistance(int level, int height, real minDist) {
+ return(nodeDiameter+minDist)*2^(height-level);
+ }
+
+ real dist=getDistance(node.getLevel(),height,minDist)/2;
+
+ /**
+ * draws the connection between the two nodes at the given positions
+ * by calculating the connection points
+ * and then drawing the corresponding arrow.
+ */
+ void deferredDrawNodeConnection(pair parentPos, pair childPos) {
+ pic.add(new void(frame f, transform t) {
+ pair start,end;
+ // calculate connection path
+ transform T=shift(nodeDiameter/2*unit(t*childPos-t*parentPos));
+ path arr=(T*t*parentPos)--(inverse(T)*t*childPos);
+ draw(f,arr,p,Arrow(5));
+ });
+ pic.addPoint(parentPos);
+ pic.addPoint(childPos);
+ }
+
+ if(left != null) {
+ pair childPos=pos-(0,levelDist)-(dist/2,0);
+ draw(pic,left,childPos,height,minDist,levelDist,nodeDiameter,p);
+ deferredDrawNodeConnection(pos,childPos);
+ }
+
+ if(right != null) {
+ pair childPos=pos-(0,levelDist)+(dist/2,0);
+ draw(pic,right,childPos,height,minDist,levelDist,nodeDiameter,p);
+ deferredDrawNodeConnection(pos,childPos);
+ }
+
+ picture obj;
+ draw(obj,circle((0,0),nodeDiameter/2),p);
+ label(obj,label,(0,0),p);
+
+ add(pic,obj,pos);
+
+ return label;
+}
+
+struct key {
+ int n;
+ bool active;
+}
+
+key key(int n, bool active=true) {key k; k.n=n; k.active=active; return k;}
+
+key operator cast(int n) {return key(n);}
+int operator cast(key k) {return k.n;}
+int[] operator cast(key[] k) {
+ int[] I;
+ for(int i=0; i < k.length; ++i)
+ I[i]=k[i].n;
+ return I;
+}
+
+key nil=key(0,false);
+
+/**
+ * structure to represent a binary tree.
+ */
+struct binarytree {
+ binarytreeNode root;
+ int[] keys;
+
+ /**
+ * adds the given < key > to the tree by searching for its place and inserting it there.
+ */
+ void addKey(int key) {
+ binarytreeNode newNode=binarytreeNode(key);
+
+ if(root == null) {
+ root=newNode;
+ keys.push(key);
+ return;
+ }
+
+ binarytreeNode n=root;
+ while(n != null) {
+ if(key < n.key) {
+ if(n.left != null)
+ n=n.left;
+ else {
+ n.setLeft(newNode);
+ keys.push(key);
+ return;
+ }
+ } else if(key > n.key) {
+ if(n.right != null)
+ n=n.right;
+ else {
+ n.setRight(newNode);
+ keys.push(key);
+ return;
+ }
+ }
+ }
+ }
+
+ /**
+ * returns the height of the tree
+ */
+ int getHeight() {
+ if(root == null)
+ return 0;
+ else
+ return root.getHeight();
+ }
+
+ /**
+ * adds all given keys to the tree sequentially
+ */
+ void addSearchKeys(int[] keys) {
+ for(int i=0; i < keys.length; ++i) {
+ int key=keys[i];
+ // Ignore duplicate keys
+ if(find(this.keys == key) == -1)
+ addKey(key);
+ }
+ }
+
+ binarytreeNode build(key[] keys, int[] ind) {
+ if(ind[0] >= keys.length) return null;
+ key k=keys[ind[0]];
+ ++ind[0];
+ if(!k.active) return null;
+ binarytreeNode bt=binarytreeNode(k);
+ binarytreeNode left=build(keys,ind);
+ binarytreeNode right=build(keys,ind);
+ bt.left=left; bt.right=right;
+ if(left != null) left.parent=bt;
+ if(right != null) right.parent=bt;
+ return bt;
+ }
+
+ void addKeys(key[] keys) {
+ int[] ind={0};
+ root=build(keys,ind);
+ this.keys=keys;
+ }
+
+
+ /**
+ * returns all key in the tree
+ */
+ int[] getKeys() {
+ return keys;
+ }
+}
+
+binarytree searchtree(...int[] keys)
+{
+ binarytree bt;
+ bt.addSearchKeys(keys);
+ return bt;
+}
+
+binarytree binarytree(...key[] keys)
+{
+ binarytree bt;
+ bt.addKeys(keys);
+ return bt;
+}
+
+/**
+ * draws the given binary tree.
+ */
+void draw(picture pic=currentpicture, binarytree tree,
+ real minDist=minDistDefault, real nodeMargin=nodeMarginDefault,
+ pen p=currentpen)
+{
+ int[] keys=tree.getKeys();
+
+ // calculate the node diameter so that all keys fit into it
+ frame f;
+ for(int i=0; i < keys.length; ++i)
+ label(f,math(string(keys[i])),p);
+
+ real nodeDiameter=abs(max(f)-min(f))+2*nodeMargin;
+ real levelDist=nodeDiameter*1.8;
+
+ draw(pic,tree.root,(0,0),tree.getHeight(),minDist,levelDist,nodeDiameter,p);
+}
diff --git a/Build/source/utils/asymptote/base/bsp.asy b/Build/source/utils/asymptote/base/bsp.asy
new file mode 100644
index 00000000000..a744da522cc
--- /dev/null
+++ b/Build/source/utils/asymptote/base/bsp.asy
@@ -0,0 +1,207 @@
+private import math;
+import three;
+
+real epsilon=10*realEpsilon;
+
+// Routines for hidden surface removal (via binary space partition):
+// Structure face is derived from picture.
+struct face {
+ picture pic;
+ transform t;
+ frame fit;
+ triple normal,point;
+ triple min,max;
+ void operator init(path3 p) {
+ this.normal=normal(p);
+ if(this.normal == O) abort("path is linear");
+ this.point=point(p,0);
+ min=min(p);
+ max=max(p);
+ }
+ face copy() {
+ face f=new face;
+ f.pic=pic.copy();
+ f.t=t;
+ f.normal=normal;
+ f.point=point;
+ f.min=min;
+ f.max=max;
+ add(f.fit,fit);
+ return f;
+ }
+}
+
+picture operator cast(face f) {return f.pic;}
+face operator cast(path3 p) {return face(p);}
+
+struct line {
+ triple point;
+ triple dir;
+}
+
+private line intersection(face a, face b)
+{
+ line L;
+ L.point=intersectionpoint(a.normal,a.point,b.normal,b.point);
+ L.dir=unit(cross(a.normal,b.normal));
+ return L;
+}
+
+struct half {
+ pair[] left,right;
+
+ // Sort the points in the pair array z according to whether they lie on the
+ // left or right side of the line L in the direction dir passing through P.
+ // Points exactly on L are considered to be on the right side.
+ // Also push any points of intersection of L with the path operator --(... z)
+ // onto each of the arrays left and right.
+ void operator init(pair dir, pair P ... pair[] z) {
+ pair lastz;
+ pair invdir=dir != 0 ? 1/dir : 0;
+ bool left,last;
+ for(int i=0; i < z.length; ++i) {
+ left=(invdir*z[i]).y > (invdir*P).y;
+ if(i > 0 && last != left) {
+ pair w=extension(P,P+dir,lastz,z[i]);
+ this.left.push(w);
+ this.right.push(w);
+ }
+ if(left) this.left.push(z[i]);
+ else this.right.push(z[i]);
+ last=left;
+ lastz=z[i];
+ }
+ }
+}
+
+struct splitface {
+ face back,front;
+}
+
+// Return the pieces obtained by splitting face a by face cut.
+splitface split(face a, face cut, projection P)
+{
+ splitface S;
+
+ void nointersection() {
+ if(abs(dot(a.point-P.camera,a.normal)) >=
+ abs(dot(cut.point-P.camera,cut.normal))) {
+ S.back=a;
+ S.front=null;
+ } else {
+ S.back=null;
+ S.front=a;
+ }
+ }
+
+ if(P.infinity) {
+ P=P.copy();
+ static real factor=1/sqrtEpsilon;
+ P.camera *= factor*max(abs(a.min),abs(a.max),
+ abs(cut.min),abs(cut.max));
+ }
+
+ if((abs(a.normal-cut.normal) < epsilon ||
+ abs(a.normal+cut.normal) < epsilon)) {
+ nointersection();
+ return S;
+ }
+
+ line L=intersection(a,cut);
+
+ if(dot(P.camera-L.point,P.camera-P.target) < 0) {
+ nointersection();
+ return S;
+ }
+
+ pair point=a.t*project(L.point,P);
+ pair dir=a.t*project(L.point+L.dir,P)-point;
+ pair invdir=dir != 0 ? 1/dir : 0;
+ triple apoint=L.point+cross(L.dir,a.normal);
+ bool left=(invdir*(a.t*project(apoint,P))).y >= (invdir*point).y;
+
+ real t=intersect(apoint,P.camera,cut.normal,cut.point);
+ bool rightfront=left ^ (t <= 0 || t >= 1);
+
+ face back=a, front=a.copy();
+ pair max=max(a.fit);
+ pair min=min(a.fit);
+ half h=half(dir,point,max,(min.x,max.y),min,(max.x,min.y),max);
+ if(h.right.length == 0) {
+ if(rightfront) front=null;
+ else back=null;
+ } else if(h.left.length == 0) {
+ if(rightfront) back=null;
+ else front=null;
+ }
+ if(front != null)
+ clip(front.fit,operator --(... rightfront ? h.right : h.left)--cycle,
+ zerowinding);
+ if(back != null)
+ clip(back.fit,operator --(... rightfront ? h.left : h.right)--cycle,
+ zerowinding);
+ S.back=back;
+ S.front=front;
+ return S;
+}
+
+// A binary space partition
+struct bsp
+{
+ bsp back;
+ bsp front;
+ face node;
+
+ // Construct the bsp.
+ void operator init(face[] faces, projection P) {
+ if(faces.length != 0) {
+ this.node=faces.pop();
+ face[] front,back;
+ for(int i=0; i < faces.length; ++i) {
+ splitface split=split(faces[i],this.node,P);
+ if(split.front != null) front.push(split.front);
+ if(split.back != null) back.push(split.back);
+ }
+ this.front=bsp(front,P);
+ this.back=bsp(back,P);
+ }
+ }
+
+ // Draw from back to front.
+ void add(frame f) {
+ if(back != null) back.add(f);
+ add(f,node.fit,group=true);
+ if(labels(node.fit)) layer(f); // Draw over any existing TeX layers.
+ if(front != null) front.add(f);
+ }
+}
+
+void add(picture pic=currentpicture, face[] faces,
+ projection P=currentprojection)
+{
+ int n=faces.length;
+ face[] Faces=new face[n];
+ for(int i=0; i < n; ++i)
+ Faces[i]=faces[i].copy();
+
+ pic.nodes.push(new void (frame f, transform t, transform T,
+ pair m, pair M) {
+ // Fit all of the pictures so we know their exact sizes.
+ face[] faces=new face[n];
+ for(int i=0; i < n; ++i) {
+ faces[i]=Faces[i].copy();
+ face F=faces[i];
+ F.t=t*T*F.pic.T;
+ F.fit=F.pic.fit(t,T*F.pic.T,m,M);
+ }
+
+ bsp bsp=bsp(faces,P);
+ if(bsp != null) bsp.add(f);
+ });
+
+ for(int i=0; i < n; ++i) {
+ picture F=Faces[i].pic;
+ pic.userBox(F.userMin,F.userMax);
+ pic.append(pic.bounds.point,pic.bounds.min,pic.bounds.max,F.T,F.bounds);
+ }
+}
diff --git a/Build/source/utils/asymptote/base/contour.asy b/Build/source/utils/asymptote/base/contour.asy
new file mode 100644
index 00000000000..fbb4cd1c71a
--- /dev/null
+++ b/Build/source/utils/asymptote/base/contour.asy
@@ -0,0 +1,682 @@
+// Contour routines written by Radoslav Marinov and John Bowman.
+
+import graph_settings;
+
+real eps=10000*realEpsilon;
+
+// 1
+// 6 +-------------------+ 5
+// | \ / |
+// | \ / |
+// | \ / |
+// | \ / |
+// 2 | X | 0
+// | / \ |
+// | / \ |
+// | / \ |
+// | / \ |
+// 7 +-------------------+ 4 or 8
+// 3
+
+private struct segment
+{
+ bool active;
+ pair a,b; // Endpoints; a is always an edge point if one exists.
+ int c; // Contour value.
+ int edge; // -1: interior, 0 to 3: edge,
+ // 4-8: single-vertex edge, 9: double-vertex edge.
+}
+
+// Case 1: line passes through two vertices of a triangle
+private segment case1(pair p0, pair p1, int edge)
+{
+ // Will cause a duplicate guide; luckily case1 is rare
+ segment rtrn;
+ rtrn.active=true;
+ rtrn.a=p0;
+ rtrn.b=p1;
+ rtrn.edge=edge;
+ return rtrn;
+}
+
+// Case 2: line passes through a vertex and a side of a triangle
+// (the first vertex passed and the side between the other two)
+private segment case2(pair p0, pair p1, pair p2,
+ real v0, real v1, real v2, int edge)
+{
+ segment rtrn;
+ pair val=interp(p1,p2,abs(v1/(v2-v1)));
+ rtrn.active=true;
+ if(edge < 4) {
+ rtrn.a=val;
+ rtrn.b=p0;
+ } else {
+ rtrn.a=p0;
+ rtrn.b=val;
+ }
+ rtrn.edge=edge;
+ return rtrn;
+}
+
+// Case 3: line passes through two sides of a triangle
+// (through the sides formed by the first & second, and second & third
+// vertices)
+private segment case3(pair p0, pair p1, pair p2,
+ real v0, real v1, real v2, int edge=-1)
+{
+ segment rtrn;
+ rtrn.active=true;
+ rtrn.a=interp(p1,p0,abs(v1/(v0-v1)));
+ rtrn.b=interp(p1,p2,abs(v1/(v2-v1)));
+ rtrn.edge=edge;
+ return rtrn;
+}
+
+// Check if a line passes through a triangle, and draw the required line.
+private segment checktriangle(pair p0, pair p1, pair p2,
+ real v0, real v1, real v2, int edge=-1)
+{
+ // default null return
+ static segment dflt;
+
+ real eps=eps*max(abs(v0),abs(v1),abs(v2));
+
+ if(v0 < -eps) {
+ if(v1 < -eps) {
+ if(v2 < -eps) return dflt; // nothing to do
+ else if(v2 <= eps) return dflt; // nothing to do
+ else return case3(p0,p2,p1,v0,v2,v1);
+ } else if(v1 <= eps) {
+ if(v2 < -eps) return dflt; // nothing to do
+ else if(v2 <= eps) return case1(p1,p2,5+edge);
+ else return case2(p1,p0,p2,v1,v0,v2,5+edge);
+ } else {
+ if(v2 < -eps) return case3(p0,p1,p2,v0,v1,v2,edge);
+ else if(v2 <= eps)
+ return case2(p2,p0,p1,v2,v0,v1,edge);
+ else return case3(p1,p0,p2,v1,v0,v2,edge);
+ }
+ } else if(v0 <= eps) {
+ if(v1 < -eps) {
+ if(v2 < -eps) return dflt; // nothing to do
+ else if(v2 <= eps) return case1(p0,p2,4+edge);
+ else return case2(p0,p1,p2,v0,v1,v2,4+edge);
+ } else if(v1 <= eps) {
+ if(v2 < -eps) return case1(p0,p1,9);
+ else if(v2 <= eps) return dflt; // use finer partitioning.
+ else return case1(p0,p1,9);
+ } else {
+ if(v2 < -eps) return case2(p0,p1,p2,v0,v1,v2,4+edge);
+ else if(v2 <= eps) return case1(p0,p2,4+edge);
+ else return dflt; // nothing to do
+ }
+ } else {
+ if(v1 < -eps) {
+ if(v2 < -eps) return case3(p1,p0,p2,v1,v0,v2,edge);
+ else if(v2 <= eps)
+ return case2(p2,p0,p1,v2,v0,v1,edge);
+ else return case3(p0,p1,p2,v0,v1,v2,edge);
+ } else if(v1 <= eps) {
+ if(v2 < -eps) return case2(p1,p0,p2,v1,v0,v2,5+edge);
+ else if(v2 <= eps) return case1(p1,p2,5+edge);
+ else return dflt; // nothing to do
+ } else {
+ if(v2 < -eps) return case3(p0,p2,p1,v0,v2,v1);
+ else if(v2 <= eps) return dflt; // nothing to do
+ else return dflt; // nothing to do
+ }
+ }
+}
+
+// Collect connecting path segments.
+private void collect(pair[][][] points, real[] c)
+{
+ // use to reverse an array, omitting the first point
+ int[] reverseF(int n) {return sequence(new int(int x){return n-1-x;},n-1);}
+ // use to reverse an array, omitting the last point
+ int[] reverseL(int n) {return sequence(new int(int x){return n-2-x;},n-1);}
+
+ for(int cnt=0; cnt < c.length; ++cnt) {
+ pair[][] gdscnt=points[cnt];
+ for(int i=0; i < gdscnt.length; ++i) {
+ pair[] gig=gdscnt[i];
+ int Li=gig.length;
+ for(int j=i+1; j < gdscnt.length; ++j) {
+ pair[] gjg=gdscnt[j];
+ int Lj=gjg.length;
+ if(abs(gig[0]-gjg[0]) < eps) {
+ gdscnt[j]=gjg[reverseF(Lj)];
+ gdscnt[j].append(gig);
+ gdscnt.delete(i);
+ --i;
+ break;
+ } else if(abs(gig[0]-gjg[Lj-1]) < eps) {
+ gig.delete(0);
+ gdscnt[j].append(gig);
+ gdscnt.delete(i);
+ --i;
+ break;
+ } else if(abs(gig[Li-1]-gjg[0]) < eps) {
+ gjg.delete(0);
+ gig.append(gjg);
+ gdscnt[j]=gig;
+ gdscnt.delete(i);
+ --i;
+ break;
+ } else if(abs(gig[Li-1]-gjg[Lj-1]) < eps) {
+ gig.append(gjg[reverseL(Lj)]);
+ gdscnt[j]=gig;
+ gdscnt.delete(i);
+ --i;
+ break;
+ }
+ }
+ }
+ }
+}
+
+// Join path segments.
+private guide[][] connect(pair[][][] points, real[] c, interpolate join)
+{
+ // set up return value
+ guide[][] result=new guide[c.length][];
+ for(int cnt=0; cnt < c.length; ++cnt) {
+ pair[][] pointscnt=points[cnt];
+ guide[] resultcnt=result[cnt]=new guide[pointscnt.length];
+ for(int i=0; i < pointscnt.length; ++i) {
+ pair[] pts=pointscnt[i];
+ guide gd;
+ if(pts.length > 0) {
+ if(pts.length > 1 && abs(pts[0]-pts[pts.length-1]) < eps) {
+ guide[] g=sequence(new guide(int i) {
+ return pts[i];
+ },pts.length-1);
+ g.push(cycle);
+ gd=join(...g);
+ } else
+ gd=join(...sequence(new guide(int i) {
+ return pts[i];
+ },pts.length));
+ }
+ resultcnt[i]=gd;
+ }
+ }
+ return result;
+}
+
+
+// Return contour guides for a 2D data array.
+// z: two-dimensional array of nonoverlapping mesh points
+// f: two-dimensional array of corresponding f(z) data values
+// midpoint: optional array containing values of f at cell midpoints
+// c: array of contour values
+// join: interpolation operator (e.g. operator -- or operator ..)
+guide[][] contour(pair[][] z, real[][] f,
+ real[][] midpoint=new real[][], real[] c,
+ interpolate join=operator --)
+{
+ int nx=z.length-1;
+ if(nx == 0)
+ abort("array z must have length >= 2");
+ int ny=z[0].length-1;
+ if(ny == 0)
+ abort("array z[0] must have length >= 2");
+
+ c=sort(c);
+ bool midpoints=midpoint.length > 0;
+
+ segment segments[][][]=new segment[nx][ny][];
+
+ // go over region a rectangle at a time
+ for(int i=0; i < nx; ++i) {
+ pair[] zi=z[i];
+ pair[] zp=z[i+1];
+ real[] fi=f[i];
+ real[] fp=f[i+1];
+ real[] midpointi;
+ if(midpoints) midpointi=midpoint[i];
+ segment[][] segmentsi=segments[i];
+ for(int j=0; j < ny; ++j) {
+ segment[] segmentsij=segmentsi[j];
+
+ // define points
+ pair bleft=zi[j];
+ pair bright=zp[j];
+ pair tleft=zi[j+1];
+ pair tright=zp[j+1];
+ pair middle=0.25*(bleft+bright+tleft+tright);
+
+ real f00=fi[j];
+ real f01=fi[j+1];
+ real f10=fp[j];
+ real f11=fp[j+1];
+ real fmm=midpoints ? midpoint[i][j] : 0.25*(f00+f01+f10+f11);
+
+ // optimization: we make sure we don't work with empty rectangles
+ int checkcell(int cnt) {
+ real C=c[cnt];
+ real vertdat0=f00-C; // bottom-left vertex
+ real vertdat1=f10-C; // bottom-right vertex
+ real vertdat2=f01-C; // top-left vertex
+ real vertdat3=f11-C; // top-right vertex
+
+ // optimization: we make sure we don't work with empty rectangles
+ int countm=0;
+ int countz=0;
+ int countp=0;
+
+ void check(real vertdat) {
+ if(vertdat < -eps) ++countm;
+ else {
+ if(vertdat <= eps) ++countz;
+ else ++countp;
+ }
+ }
+
+ check(vertdat0);
+ check(vertdat1);
+ check(vertdat2);
+ check(vertdat3);
+
+ if(countm == 4) return 1; // nothing to do
+ if(countp == 4) return -1; // nothing to do
+ if((countm == 3 || countp == 3) && countz == 1) return 0;
+
+ // go through the triangles
+
+ void addseg(segment seg) {
+ if(seg.active) {
+ seg.c=cnt;
+ segmentsij.push(seg);
+ }
+ }
+ real vertdat4=fmm-C;
+ addseg(checktriangle(bright,tright,middle,
+ vertdat1,vertdat3,vertdat4,0));
+ addseg(checktriangle(tright,tleft,middle,
+ vertdat3,vertdat2,vertdat4,1));
+ addseg(checktriangle(tleft,bleft,middle,
+ vertdat2,vertdat0,vertdat4,2));
+ addseg(checktriangle(bleft,bright,middle,
+ vertdat0,vertdat1,vertdat4,3));
+ return 0;
+ }
+
+ void process(int l, int u) {
+ if(l >= u) return;
+ int i=quotient(l+u,2);
+ int sign=checkcell(i);
+ if(sign == -1) process(i+1,u);
+ else if(sign == 1) process(l,i);
+ else {
+ process(l,i);
+ process(i+1,u);
+ }
+ }
+
+ process(0,c.length);
+ }
+ }
+
+ // set up return value
+ pair[][][] points=new pair[c.length][][];
+
+ for(int i=0; i < nx; ++i) {
+ segment[][] segmentsi=segments[i];
+ for(int j=0; j < ny; ++j) {
+ segment[] segmentsij=segmentsi[j];
+ for(int k=0; k < segmentsij.length; ++k) {
+ segment C=segmentsij[k];
+
+ if(!C.active) continue;
+
+ pair[] g=new pair[] {C.a,C.b};
+ segmentsij[k].active=false;
+
+ int forward(int I, int J, bool first=true) {
+ if(I >= 0 && I < nx && J >= 0 && J < ny) {
+ segment[] segmentsIJ=segments[I][J];
+ for(int l=0; l < segmentsIJ.length; ++l) {
+ segment D=segmentsIJ[l];
+ if(!D.active) continue;
+ if(abs(D.a-g[g.length-1]) < eps) {
+ g.push(D.b);
+ segmentsIJ[l].active=false;
+ if(D.edge >= 0 && !first) return D.edge;
+ first=false;
+ l=-1;
+ } else if(abs(D.b-g[g.length-1]) < eps) {
+ g.push(D.a);
+ segmentsIJ[l].active=false;
+ if(D.edge >= 0 && !first) return D.edge;
+ first=false;
+ l=-1;
+ }
+ }
+ }
+ return -1;
+ }
+
+ int backward(int I, int J, bool first=true) {
+ if(I >= 0 && I < nx && J >= 0 && J < ny) {
+ segment[] segmentsIJ=segments[I][J];
+ for(int l=0; l < segmentsIJ.length; ++l) {
+ segment D=segmentsIJ[l];
+ if(!D.active) continue;
+ if(abs(D.a-g[0]) < eps) {
+ g.insert(0,D.b);
+ segmentsIJ[l].active=false;
+ if(D.edge >= 0 && !first) return D.edge;
+ first=false;
+ l=-1;
+ } else if(abs(D.b-g[0]) < eps) {
+ g.insert(0,D.a);
+ segmentsIJ[l].active=false;
+ if(D.edge >= 0 && !first) return D.edge;
+ first=false;
+ l=-1;
+ }
+ }
+ }
+ return -1;
+ }
+
+ void follow(int f(int, int, bool first=true), int edge) {
+ int I=i;
+ int J=j;
+ while(true) {
+ static int ix[]={1,0,-1,0};
+ static int iy[]={0,1,0,-1};
+ if(edge >= 0 && edge < 4) {
+ I += ix[edge];
+ J += iy[edge];
+ edge=f(I,J);
+ } else {
+ if(edge == -1) break;
+ if(edge < 9) {
+ int edge0=(edge-5) % 4;
+ int edge1=(edge-4) % 4;
+ int ix0=ix[edge0];
+ int iy0=iy[edge0];
+ I += ix0;
+ J += iy0;
+ // Search all 3 corner cells
+ if((edge=f(I,J)) == -1) {
+ I += ix[edge1];
+ J += iy[edge1];
+ if((edge=f(I,J)) == -1) {
+ I -= ix0;
+ J -= iy0;
+ edge=f(I,J);
+ }
+ }
+ } else {
+ // Double-vertex edge: search all 8 surrounding cells
+ void search() {
+ for(int i=-1; i <= 1; ++i) {
+ for(int j=-1; j <= 1; ++j) {
+ if((edge=f(I+i,J+j,false)) >= 0) {
+ I += i;
+ J += j;
+ return;
+ }
+ }
+ }
+ }
+ search();
+ }
+ }
+ }
+ }
+
+ // Follow contour in cell
+ int edge=forward(i,j,first=false);
+
+ // Follow contour forward outside of cell
+ follow(forward,edge);
+
+ // Follow contour backward outside of cell
+ follow(backward,C.edge);
+
+ points[C.c].push(g);
+ }
+ }
+ }
+
+ collect(points,c); // Required to join remaining case1 cycles.
+
+ return connect(points,c,join);
+}
+
+// Return contour guides for a 2D data array on a uniform lattice
+// f: two-dimensional array of real data values
+// midpoint: optional array containing data values at cell midpoints
+// a,b: diagonally opposite vertices of rectangular domain
+// c: array of contour values
+// join: interpolation operator (e.g. operator -- or operator ..)
+guide[][] contour(real[][] f, real[][] midpoint=new real[][],
+ pair a, pair b, real[] c,
+ interpolate join=operator --)
+{
+ int nx=f.length-1;
+ if(nx == 0)
+ abort("array f must have length >= 2");
+ int ny=f[0].length-1;
+ if(ny == 0)
+ abort("array f[0] must have length >= 2");
+
+ pair[][] z=new pair[nx+1][ny+1];
+ for(int i=0; i <= nx; ++i) {
+ pair[] zi=z[i];
+ real xi=interp(a.x,b.x,i/nx);
+ for(int j=0; j <= ny; ++j) {
+ zi[j]=(xi,interp(a.y,b.y,j/ny));
+ }
+ }
+ return contour(z,f,midpoint,c,join);
+}
+
+// return contour guides for a real-valued function
+// f: real-valued function of two real variables
+// a,b: diagonally opposite vertices of rectangular domain
+// c: array of contour values
+// nx,ny: number of subdivisions in x and y directions (determines accuracy)
+// join: interpolation operator (e.g. operator -- or operator ..)
+guide[][] contour(real f(real, real), pair a, pair b,
+ real[] c, int nx=ngraph, int ny=nx,
+ interpolate join=operator --)
+{
+ // evaluate function at points and midpoints
+ real[][] dat=new real[nx+1][ny+1];
+ real[][] midpoint=new real[nx+1][ny+1];
+
+ for(int i=0; i <= nx; ++i) {
+ real x=interp(a.x,b.x,i/nx);
+ real x2=interp(a.x,b.x,(i+0.5)/nx);
+ real[] dati=dat[i];
+ real[] midpointi=midpoint[i];
+ for(int j=0; j <= ny; ++j) {
+ dati[j]=f(x,interp(a.y,b.y,j/ny));
+ midpointi[j]=f(x2,interp(a.y,b.y,(j+0.5)/ny));
+ }
+ }
+
+ return contour(dat,midpoint,a,b,c,join);
+}
+
+void draw(picture pic=currentpicture, Label[] L=new Label[],
+ guide[][] g, pen[] p)
+{
+ begingroup(pic);
+ for(int cnt=0; cnt < g.length; ++cnt) {
+ guide[] gcnt=g[cnt];
+ pen pcnt=p[cnt];
+ for(int i=0; i < gcnt.length; ++i)
+ draw(pic,gcnt[i],pcnt);
+ if(L.length > 0) {
+ Label Lcnt=L[cnt];
+ for(int i=0; i < gcnt.length; ++i) {
+ if(Lcnt.s != "" && size(gcnt[i]) > 1)
+ label(pic,Lcnt,gcnt[i],pcnt);
+ }
+ }
+ }
+ endgroup(pic);
+}
+
+void draw(picture pic=currentpicture, Label[] L=new Label[],
+ guide[][] g, pen p=currentpen)
+{
+ draw(pic,L,g,sequence(new pen(int) {return p;},g.length));
+}
+
+// Extend palette by the colors below and above at each end.
+pen[] extend(pen[] palette, pen below, pen above) {
+ pen[] p=copy(palette);
+ p.insert(0,below);
+ p.push(above);
+ return p;
+}
+
+// Compute the interior palette for a sequence of cyclic contours
+// corresponding to palette.
+pen[][] interior(picture pic=currentpicture, guide[][] g, pen[] palette)
+{
+ if(palette.length != g.length+1)
+ abort("Palette array must have length one more than guide array");
+ pen[][] fillpalette=new pen[g.length][];
+ for(int i=0; i < g.length; ++i) {
+ guide[] gi=g[i];
+ guide[] gp;
+ if(i+1 < g.length) gp=g[i+1];
+ guide[] gm;
+ if(i > 0) gm=g[i-1];
+
+ pen[] fillpalettei=new pen[gi.length];
+ for(int j=0; j < gi.length; ++j) {
+ path P=gi[j];
+ if(cyclic(P)) {
+ int index=i+1;
+ bool nextinside;
+ for(int k=0; k < gp.length; ++k) {
+ path next=gp[k];
+ if(cyclic(next)) {
+ if(inside(P,point(next,0)))
+ nextinside=true;
+ else if(inside(next,point(P,0)))
+ index=i;
+ }
+ }
+ if(!nextinside) {
+ // Check to see if previous contour is inside
+ for(int k=0; k < gm.length; ++k) {
+ path prev=gm[k];
+ if(cyclic(prev)) {
+ if(inside(P,point(prev,0)))
+ index=i;
+ }
+ }
+ }
+ fillpalettei[j]=palette[index];
+ }
+ fillpalette[i]=fillpalettei;
+ }
+ }
+ return fillpalette;
+}
+
+// Fill the interior of cyclic contours with palette
+void fill(picture pic=currentpicture, guide[][] g, pen[][] palette)
+{
+ for(int i=0; i < g.length; ++i) {
+ guide[] gi=g[i];
+ guide[] gp;
+ if(i+1 < g.length) gp=g[i+1];
+ guide[] gm;
+ if(i > 0) gm=g[i-1];
+
+ for(int j=0; j < gi.length; ++j) {
+ path P=gi[j];
+ path[] S=P;
+ if(cyclic(P)) {
+ for(int k=0; k < gp.length; ++k) {
+ path next=gp[k];
+ if(cyclic(next) && inside(P,point(next,0)))
+ S=S^^next;
+ }
+ for(int k=0; k < gm.length; ++k) {
+ path next=gm[k];
+ if(cyclic(next) && inside(P,point(next,0)))
+ S=S^^next;
+ }
+ fill(pic,S,palette[i][j]+evenodd);
+ }
+ }
+ }
+}
+
+// routines for irregularly spaced points:
+
+// check existing guides and adds new segment to them if possible,
+// or otherwise store segment as a new guide
+private void addseg(pair[][] gds, segment seg)
+{
+ if(!seg.active) return;
+ // search for a path to extend
+ for(int i=0; i < gds.length; ++i) {
+ pair[] gd=gds[i];
+ if(abs(gd[0]-seg.b) < eps) {
+ gd.insert(0,seg.a);
+ return;
+ } else if(abs(gd[gd.length-1]-seg.b) < eps) {
+ gd.push(seg.a);
+ return;
+ } else if(abs(gd[0]-seg.a) < eps) {
+ gd.insert(0,seg.b);
+ return;
+ } else if(abs(gd[gd.length-1]-seg.a) < eps) {
+ gd.push(seg.b);
+ return;
+ }
+ }
+
+ // in case nothing is found
+ pair[] segm;
+ segm=new pair[] {seg.a,seg.b};
+ gds.push(segm);
+
+ return;
+}
+
+guide[][] contour(real f(pair), pair a, pair b,
+ real[] c, int nx=ngraph, int ny=nx,
+ interpolate join=operator --)
+{
+ return contour(new real(real x, real y) {return f((x,y));},a,b,c,nx,ny,join);
+}
+
+guide[][] contour(pair[] z, real[] f, real[] c, interpolate join=operator --)
+{
+ if(z.length != f.length)
+ abort("z and f arrays have different lengths");
+
+ int[][] trn=triangulate(z);
+
+ // array to store guides found so far
+ pair[][][] points=new pair[c.length][][];
+
+ for(int cnt=0; cnt < c.length; ++cnt) {
+ pair[][] pointscnt=points[cnt];
+ real C=c[cnt];
+ for(int i=0; i < trn.length; ++i) {
+ int[] trni=trn[i];
+ int i0=trni[0], i1=trni[1], i2=trni[2];
+ addseg(pointscnt,checktriangle(z[i0],z[i1],z[i2],
+ f[i0]-C,f[i1]-C,f[i2]-C));
+ }
+ }
+
+ collect(points,c);
+
+ return connect(points,c,join);
+}
diff --git a/Build/source/utils/asymptote/base/contour3.asy b/Build/source/utils/asymptote/base/contour3.asy
new file mode 100644
index 00000000000..e9d8d928991
--- /dev/null
+++ b/Build/source/utils/asymptote/base/contour3.asy
@@ -0,0 +1,481 @@
+import graph_settings;
+import three;
+
+real eps=10000*realEpsilon;
+
+private struct weighted
+{
+ triple normal;
+ real ratio;
+ int kpa0,kpa1,kpa2;
+ int kpb0,kpb1,kpb2;
+ triple v;
+}
+
+private struct bucket
+{
+ triple v;
+ triple val;
+ int count;
+}
+
+struct vertex
+{
+ triple v;
+ triple normal;
+}
+
+// A group of 3 or 4 points.
+private struct object
+{
+ bool active;
+ weighted[] pts;
+}
+
+// Return contour vertices for a 3D data array.
+// z: three-dimensional array of nonoverlapping mesh points
+// f: three-dimensional arrays of real data values
+// midpoint: optional array containing estimate of f at midpoint values
+vertex[][] contour3(triple[][][] v, real[][][] f,
+ real[][][] midpoint=new real[][][],
+ projection P=currentprojection)
+{
+ int nx=v.length-1;
+ if(nx == 0)
+ abort("array v must have length >= 2");
+ int ny=v[0].length-1;
+ if(ny == 0)
+ abort("array v[0] must have length >= 2");
+ int nz=v[0][0].length-1;
+ if(nz == 0)
+ abort("array v[0][0] must have length >= 2");
+
+ bool midpoints=midpoint.length > 0;
+
+ bucket[][][][] kps=new bucket[2nx+1][2ny+1][2nz+1][];
+ for(int i=0; i < 2nx+1; ++i)
+ for(int j=0; j < 2ny+1; ++j)
+ for(int k=0; k < 2nz+1; ++k)
+ kps[i][j][k]=new bucket[];
+
+ object[] objects;
+
+ // go over region a rectangle at a time
+ for(int i=0; i < nx; ++i) {
+ triple[][] vi=v[i];
+ triple[][] vp=v[i+1];
+ real[][] fi=f[i];
+ real[][] fp=f[i+1];
+ int i2=2i;
+ int i2p1=i2+1;
+ int i2p2=i2+2;
+ for(int j=0; j < ny; ++j) {
+ triple[] vij=vi[j];
+ triple[] vpj=vp[j];
+ triple[] vip=vi[j+1];
+ triple[] vpp=vp[j+1];
+ real[] fij=fi[j];
+ real[] fpj=fp[j];
+ real[] fip=fi[j+1];
+ real[] fpp=fp[j+1];
+ int j2=2j;
+ int j2p1=j2+1;
+ int j2p2=j2+2;
+
+ for(int k=0; k < nz; ++k) {
+ // vertex values
+ real vdat0=fij[k];
+ real vdat1=fij[k+1];
+ real vdat2=fip[k];
+ real vdat3=fip[k+1];
+ real vdat4=fpj[k];
+ real vdat5=fpj[k+1];
+ real vdat6=fpp[k];
+ real vdat7=fpp[k+1];
+
+ // define points
+ triple p000=vij[k];
+ triple p001=vij[k+1];
+ triple p010=vip[k];
+ triple p011=vip[k+1];
+ triple p100=vpj[k];
+ triple p101=vpj[k+1];
+ triple p110=vpp[k];
+ triple p111=vpp[k+1];
+ triple m0=0.25*(p000+p010+p110+p100);
+ triple m1=0.25*(p010+p110+p111+p011);
+ triple m2=0.25*(p110+p100+p101+p111);
+ triple m3=0.25*(p100+p000+p001+p101);
+ triple m4=0.25*(p000+p010+p011+p001);
+ triple m5=0.25*(p001+p011+p111+p101);
+ triple mc=0.5*(m0+m5);
+
+ // optimization: we make sure we don't work with empty rectangles
+ int countm=0;
+ int countz=0;
+ int countp=0;
+
+ void check(real vdat) {
+ if(vdat < -eps) ++countm;
+ else {
+ if(vdat <= eps) ++countz;
+ else ++countp;
+ }
+ }
+
+ check(vdat0);
+ check(vdat1);
+ check(vdat2);
+ check(vdat3);
+ check(vdat4);
+ check(vdat5);
+ check(vdat6);
+ check(vdat7);
+
+ if(countm == 8 || countp == 8 ||
+ ((countm == 7 || countp == 7) && countz == 1)) continue;
+
+ int k2=2k;
+ int k2p1=k2+1;
+ int k2p2=k2+2;
+
+ // Evaluate midpoints of cube sides.
+ // Then evaluate midpoint of cube.
+ real vdat8=midpoints ? midpoint[i2p1][j2p1][k2] :
+ 0.25*(vdat0+vdat2+vdat6+vdat4);
+ real vdat9=midpoints ? midpoint[i2p1][j2p2][k2p1] :
+ 0.25*(vdat2+vdat6+vdat7+vdat3);
+ real vdat10=midpoints ? midpoint[i2p2][j2p1][k2p1] :
+ 0.25*(vdat7+vdat6+vdat4+vdat5);
+ real vdat11=midpoints ? midpoint[i2p1][j2][k2p1] :
+ 0.25*(vdat0+vdat4+vdat5+vdat1);
+ real vdat12=midpoints ? midpoint[i2][j2p1][k2p1] :
+ 0.25*(vdat0+vdat2+vdat3+vdat1);
+ real vdat13=midpoints ? midpoint[i2p1][j2p1][k2p2] :
+ 0.25*(vdat1+vdat3+vdat7+vdat5);
+ real vdat14=midpoints ? midpoint[i2p1][j2p1][k2p1] :
+ 0.125*(vdat0+vdat1+vdat2+vdat3+vdat4+vdat5+vdat6+vdat7);
+
+ // Go through the 24 pyramids, 4 for each side.
+
+ void addval(int kp0, int kp1, int kp2, triple add, triple v) {
+ bucket[] cur=kps[kp0][kp1][kp2];
+ for(int q=0; q < cur.length; ++q) {
+ if(length(cur[q].v-v) < eps) {
+ cur[q].val += add;
+ ++cur[q].count;
+ return;
+ }
+ }
+ bucket newbuck;
+ newbuck.v=v;
+ newbuck.val=add;
+ newbuck.count=1;
+ cur.push(newbuck);
+ }
+
+ void accrue(weighted w) {
+ triple val1=w.normal*w.ratio;
+ triple val2=w.normal*(1-w.ratio);
+ addval(w.kpa0,w.kpa1,w.kpa2,val1,w.v);
+ addval(w.kpb0,w.kpb1,w.kpb2,val2,w.v);
+ }
+
+ triple dir=P.vector();
+
+ void addnormals(weighted[] pts) {
+ triple vec2=pts[1].v-pts[0].v;
+ triple vec1=pts[0].v-pts[2].v;
+ triple vec0=-vec2-vec1;
+ vec2=unit(vec2);
+ vec1=unit(vec1);
+ vec0=unit(vec0);
+ triple normal=cross(vec2,vec1);
+ normal *= sgn(dot(normal,dir));
+ real angle0=acos(-dot(vec1,vec2));
+ real angle1=acos(-dot(vec2,vec0));
+ pts[0].normal=normal*angle0;
+ pts[1].normal=normal*angle1;
+ pts[2].normal=normal*(pi-angle0-angle1);
+ }
+
+ void addobj(object obj) {
+ if(!obj.active) return;
+
+ if(obj.pts.length == 4) {
+ weighted[] points=obj.pts;
+ object obj1;
+ object obj2;
+ obj1.active=true;
+ obj2.active=true;
+ obj1.pts=new weighted[] {points[0],points[1],points[2]};
+ obj2.pts=new weighted[] {points[1],points[2],points[3]};
+ addobj(obj1);
+ addobj(obj2);
+ } else {
+ addnormals(obj.pts);
+ for(int q=0; q < obj.pts.length; ++q)
+ accrue(obj.pts[q]);
+ objects.push(obj);
+ }
+ }
+
+ weighted setupweighted(triple va, triple vb, real da, real db,
+ int[] kpa, int[] kpb) {
+ weighted w;
+ real ratio=abs(da/(db-da));
+ w.v=interp(va,vb,ratio);
+ w.ratio=ratio;
+ w.kpa0=i2+kpa[0];
+ w.kpa1=j2+kpa[1];
+ w.kpa2=k2+kpa[2];
+ w.kpb0=i2+kpb[0];
+ w.kpb1=j2+kpb[1];
+ w.kpb2=k2+kpb[2];
+
+ return w;
+ }
+
+ weighted setupweighted(triple v, int[] kp) {
+ weighted w;
+ w.v=v;
+ w.ratio=0.5;
+ w.kpa0=w.kpb0=i2+kp[0];
+ w.kpa1=w.kpb1=j2+kp[1];
+ w.kpa2=w.kpb2=k2+kp[2];
+
+ return w;
+ }
+
+ // Checks if a pyramid contains a contour object.
+ object checkpyr(triple v0, triple v1, triple v2, triple v3,
+ real d0, real d1, real d2, real d3,
+ int[] c0, int[] c1, int[] c2, int[] c3) {
+ object obj;
+ real a0=abs(d0);
+ real a1=abs(d1);
+ real a2=abs(d2);
+ real a3=abs(d3);
+
+ bool b0=a0 < eps;
+ bool b1=a1 < eps;
+ bool b2=a2 < eps;
+ bool b3=a3 < eps;
+
+ weighted[] pts;
+
+ if(b0) pts.push(setupweighted(v0,c0));
+ if(b1) pts.push(setupweighted(v1,c1));
+ if(b2) pts.push(setupweighted(v2,c2));
+ if(b3) pts.push(setupweighted(v3,c3));
+
+ if(!b0 && !b1 && abs(d0+d1)+eps < a0+a1)
+ pts.push(setupweighted(v0,v1,d0,d1,c0,c1));
+ if(!b0 && !b2 && abs(d0+d2)+eps < a0+a2)
+ pts.push(setupweighted(v0,v2,d0,d2,c0,c2));
+ if(!b0 && !b3 && abs(d0+d3)+eps < a0+a3)
+ pts.push(setupweighted(v0,v3,d0,d3,c0,c3));
+ if(!b1 && !b2 && abs(d1+d2)+eps < a1+a2)
+ pts.push(setupweighted(v1,v2,d1,d2,c1,c2));
+ if(!b1 && !b3 && abs(d1+d3)+eps < a1+a3)
+ pts.push(setupweighted(v1,v3,d1,d3,c1,c3));
+ if(!b2 && !b3 && abs(d2+d3)+eps < a2+a3)
+ pts.push(setupweighted(v2,v3,d2,d3,c2,c3));
+
+ int s=pts.length;
+ //There are three or four points.
+ if(s > 2) {
+ obj.active=true;
+ obj.pts=pts;
+ } else obj.active=false;
+
+ return obj;
+ }
+
+ void check4pyr(triple v0, triple v1, triple v2, triple v3,
+ triple v4, triple v5,
+ real d0, real d1, real d2, real d3, real d4, real d5,
+ int[] c0, int[] c1, int[] c2, int[] c3, int[] c4,
+ int[] c5) {
+ addobj(checkpyr(v5,v4,v0,v1,d5,d4,d0,d1,c5,c4,c0,c1));
+ addobj(checkpyr(v5,v4,v1,v2,d5,d4,d1,d2,c5,c4,c1,c2));
+ addobj(checkpyr(v5,v4,v2,v3,d5,d4,d2,d3,c5,c4,c2,c3));
+ addobj(checkpyr(v5,v4,v3,v0,d5,d4,d3,d0,c5,c4,c3,c0));
+ }
+
+ static int[] pp000={0,0,0};
+ static int[] pp001={0,0,2};
+ static int[] pp010={0,2,0};
+ static int[] pp011={0,2,2};
+ static int[] pp100={2,0,0};
+ static int[] pp101={2,0,2};
+ static int[] pp110={2,2,0};
+ static int[] pp111={2,2,2};
+ static int[] pm0={1,1,0};
+ static int[] pm1={1,2,1};
+ static int[] pm2={2,1,1};
+ static int[] pm3={1,0,1};
+ static int[] pm4={0,1,1};
+ static int[] pm5={1,1,2};
+ static int[] pmc={1,1,1};
+
+ check4pyr(p000,p010,p110,p100,mc,m0,
+ vdat0,vdat2,vdat6,vdat4,vdat14,vdat8,
+ pp000,pp010,pp110,pp100,pmc,pm0);
+ check4pyr(p010,p110,p111,p011,mc,m1,
+ vdat2,vdat6,vdat7,vdat3,vdat14,vdat9,
+ pp010,pp110,pp111,pp011,pmc,pm1);
+ check4pyr(p110,p100,p101,p111,mc,m2,
+ vdat6,vdat4,vdat5,vdat7,vdat14,vdat10,
+ pp110,pp100,pp101,pp111,pmc,pm2);
+ check4pyr(p100,p000,p001,p101,mc,m3,
+ vdat4,vdat0,vdat1,vdat5,vdat14,vdat11,
+ pp100,pp000,pp001,pp101,pmc,pm3);
+ check4pyr(p000,p010,p011,p001,mc,m4,
+ vdat0,vdat2,vdat3,vdat1,vdat14,vdat12,
+ pp000,pp010,pp011,pp001,pmc,pm4);
+ check4pyr(p001,p011,p111,p101,mc,m5,
+ vdat1,vdat3,vdat7,vdat5,vdat14,vdat13,
+ pp001,pp011,pp111,pp101,pmc,pm5);
+ }
+ }
+ }
+
+ vertex preparevertex(weighted w) {
+ vertex ret;
+ triple normal=O;
+ bool first=true;
+ bucket[] kp1=kps[w.kpa0][w.kpa1][w.kpa2];
+ bucket[] kp2=kps[w.kpb0][w.kpb1][w.kpb2];
+ bool notfound1=true;
+ bool notfound2=true;
+ int count=0;
+ int stop=max(kp1.length,kp2.length);
+ for(int r=0; r < stop; ++r) {
+ if(notfound1) {
+ if(length(w.v-kp1[r].v) < eps) {
+ if(first) {
+ ret.v=kp1[r].v;
+ first=false;
+ }
+ normal += kp1[r].val;
+ count += kp1[r].count;
+ notfound1=false;
+ }
+ }
+ if(notfound2) {
+ if(length(w.v-kp2[r].v) < eps) {
+ if(first) {
+ ret.v=kp2[r].v;
+ first=false;
+ }
+ normal += kp2[r].val;
+ count += kp2[r].count;
+ notfound2=false;
+ }
+ }
+ }
+ ret.normal=normal*2/count;
+ return ret;
+ }
+
+ // Prepare return value.
+ vertex[][] g;
+
+ for(int q=0; q < objects.length; ++q) {
+ object p=objects[q];
+ g.push(new vertex[] {preparevertex(p.pts[0]),preparevertex(p.pts[1]),
+ preparevertex(p.pts[2])});
+ }
+ return g;
+}
+
+// Return contour vertices for a 3D data array on a uniform lattice.
+// f: three-dimensional arrays of real data values
+// midpoint: optional array containing estimate of f at midpoint values
+// a,b: diagonally opposite points of rectangular parellelpiped domain
+vertex[][] contour3(real[][][] f, real[][][] midpoint=new real[][][],
+ triple a, triple b, projection P=currentprojection)
+
+{
+ int nx=f.length-1;
+ if(nx == 0)
+ abort("array f must have length >= 2");
+ int ny=f[0].length-1;
+ if(ny == 0)
+ abort("array f[0] must have length >= 2");
+ int nz=f[0][0].length-1;
+ if(nz == 0)
+ abort("array f[0][0] must have length >= 2");
+
+ triple[][][] v=new triple[nx+1][ny+1][nz+1];
+ for(int i=0; i <= nx; ++i) {
+ real xi=interp(a.x,b.x,i/nx);
+ triple[][] vi=v[i];
+ for(int j=0; j <= ny; ++j) {
+ triple[] vij=v[i][j];
+ real yj=interp(a.y,b.y,j/ny);
+ for(int k=0; k <= nz; ++k) {
+ vij[k]=(xi,yj,interp(a.z,b.z,k/nz));
+ }
+ }
+ }
+ return contour3(v,f,midpoint,P);
+}
+
+// Return contour vertices for a 3D data array, using a pyramid mesh
+// f: real-valued function of three real variables
+// a,b: diagonally opposite points of rectangular parellelpiped domain
+// nx,ny,nz number of subdivisions in x, y, and z directions
+vertex[][] contour3(real f(real, real, real), triple a, triple b,
+ int nx=nmesh, int ny=nx, int nz=nx,
+ projection P=currentprojection)
+{
+ // evaluate function at points and midpoints
+ real[][][] dat=new real[nx+1][ny+1][nz+1];
+ real[][][] midpoint=new real[2nx+2][2ny+2][2nz+1];
+
+ for(int i=0; i <= nx; ++i) {
+ real x=interp(a.x,b.x,i/nx);
+ real x2=interp(a.x,b.x,(i+0.5)/nx);
+ real[][] dati=dat[i];
+ real[][] midpointi2=midpoint[2i];
+ real[][] midpointi2p1=midpoint[2i+1];
+ for(int j=0; j <= ny; ++j) {
+ real y=interp(a.y,b.y,j/ny);
+ real y2=interp(a.y,b.y,(j+0.5)/ny);
+ real datij[]=dati[j];
+ real[] midpointi2p1j2=midpointi2p1[2j];
+ real[] midpointi2p1j2p1=midpointi2p1[2j+1];
+ real[] midpointi2j2p1=midpointi2[2j+1];
+ for(int k=0; k <= nz; ++k) {
+ real z=interp(a.z,b.z,k/nz);
+ real z2=interp(a.z,b.z,(k+0.5)/nz);
+ datij[k]=f(x,y,z);
+ if(i == nx || j == ny || k == nz) continue;
+ int k2p1=2k+1;
+ midpointi2p1j2p1[2k]=f(x2,y2,z);
+ midpointi2p1j2p1[k2p1]=f(x2,y2,z2);
+ midpointi2p1j2[k2p1]=f(x2,y,z2);
+ midpointi2j2p1[k2p1]=f(x,y2,z2);
+ if(i == 0) midpoint[2nx][2j+1][k2p1]=f(b.x,y2,z2);
+ if(j == 0) midpointi2p1[2ny][k2p1]=f(x2,b.y,z2);
+ if(k == 0) midpointi2p1j2p1[2nz]=f(x2,y2,b.z);
+ }
+ }
+ }
+ return contour3(dat,midpoint,a,b,P);
+}
+
+// Construct contour surface for a 3D data array, using a pyramid mesh.
+surface surface(vertex[][] g)
+{
+ surface s=surface(g.length);
+ for(int i=0; i < g.length; ++i) {
+ vertex[] cur=g[i];
+ s.s[i]=patch(new triple[] {cur[0].v,cur[0].v,cur[1].v,cur[2].v},
+ normals=new triple[] {cur[0].normal,cur[0].normal,
+ cur[1].normal,cur[2].normal});
+ }
+ return s;
+}
diff --git a/Build/source/utils/asymptote/base/drawtree.asy b/Build/source/utils/asymptote/base/drawtree.asy
new file mode 100644
index 00000000000..832dfc658a1
--- /dev/null
+++ b/Build/source/utils/asymptote/base/drawtree.asy
@@ -0,0 +1,101 @@
+// A simple tree drawing module contributed by adarovsky
+// See example treetest.asy
+
+real treeNodeStep = 0.5cm;
+real treeLevelStep = 1cm;
+real treeMinNodeWidth = 2cm;
+
+struct TreeNode {
+ TreeNode parent;
+ TreeNode[] children;
+
+ frame content;
+
+ pair pos;
+ real adjust;
+}
+
+void add( TreeNode child, TreeNode parent )
+{
+ child.parent = parent;
+ parent.children.push( child );
+}
+
+TreeNode makeNode( TreeNode parent = null, frame f )
+{
+ TreeNode child = new TreeNode;
+ child.content = f;
+ if( parent != null ) {
+ add( child, parent );
+ }
+ return child;
+}
+
+TreeNode makeNode( TreeNode parent = null, Label label )
+{
+ frame f;
+ box( f, label);
+ return makeNode( parent, f );
+}
+
+
+real layout( int level, TreeNode node )
+{
+ if( node.children.length > 0 ) {
+ real width[] = new real[node.children.length];
+ real curWidth = 0;
+
+ for( int i = 0; i < node.children.length; ++i ) {
+ width[i] = layout( level+1, node.children[i] );
+
+ node.children[i].pos = (curWidth + width[i]/2,
+ -level*treeLevelStep);
+ curWidth += width[i] + treeNodeStep;
+ }
+
+ real midPoint = ( sum( width )+treeNodeStep*(width.length-1)) / 2;
+ for( int i = 0; i < node.children.length; ++i ) {
+ node.children[i].adjust = - midPoint;
+ }
+
+ return max( (max(node.content)-min(node.content)).x,
+ sum(width)+treeNodeStep*(width.length-1) );
+ }
+ else {
+ return max( treeMinNodeWidth, (max(node.content)-min(node.content)).x );
+ }
+}
+
+void drawAll( TreeNode node, frame f )
+{
+ pair pos;
+ if( node.parent != null )
+ pos = (node.parent.pos.x+node.adjust, 0);
+ else
+ pos = (node.adjust, 0);
+ node.pos += pos;
+
+ node.content = shift(node.pos)*node.content;
+ add( f, node.content );
+
+
+ if( node.parent != null ) {
+ path p = point(node.content, N)--point(node.parent.content,S);
+ draw( f, p, currentpen );
+ }
+
+ for( int i = 0; i < node.children.length; ++i )
+ drawAll( node.children[i], f );
+}
+
+void draw( TreeNode root, pair pos )
+{
+ frame f;
+
+ root.pos = (0,0);
+ layout( 1, root );
+
+ drawAll( root, f );
+
+ add(f,pos);
+}
diff --git a/Build/source/utils/asymptote/base/embed.asy b/Build/source/utils/asymptote/base/embed.asy
new file mode 100644
index 00000000000..3fe3d38720c
--- /dev/null
+++ b/Build/source/utils/asymptote/base/embed.asy
@@ -0,0 +1,34 @@
+texpreamble("
+\ifx\pdfhorigin\undefined%
+\usepackage[3D,dvipdfmx]{movie15}
+\else%
+\usepackage[3D]{movie15}
+\fi%
+");
+usepackage("hyperref","setpagesize=false,unicode");
+
+// See http://www.ctan.org/tex-archive/macros/latex/contrib/movie15/README
+// for documentation of the options.
+
+// Embed object in pdf file
+string embed(string name, string options="", real width=0, real height=0)
+{
+ if(options != "") options="["+options+"]{";
+ if(width != 0) options += (string) (width/pt)+"pt";
+ options += "}{";
+ if(height != 0) options += (string) (height/pt)+"pt";
+ return "\includemovie"+options+"}{"+name+"}";
+}
+
+string hyperlink(string url, string text)
+{
+ return "\href{"+url+"}{"+text+"}";
+}
+
+string link(string label, string text, string options="")
+{
+ // Run LaTeX twice to resolve references.
+ settings.twice=true;
+ if(options != "") options="["+options+"]";
+ return "\movieref"+options+"{"+label+"}{"+text+"}";
+}
diff --git a/Build/source/utils/asymptote/base/external.asy b/Build/source/utils/asymptote/base/external.asy
new file mode 100644
index 00000000000..5573561fc36
--- /dev/null
+++ b/Build/source/utils/asymptote/base/external.asy
@@ -0,0 +1,36 @@
+usepackage("hyperref","setpagesize=false,unicode");
+
+// Embed object to be run in an external window. An image file name can be
+// specified; if not given one will be automatically generated.
+string embed(string name, string options="", real width=0, real height=0,
+ string image="")
+{
+ string options; // Ignore movie15 options.
+ if(image == "") {
+ image=stripdirectory(stripextension(name))+"."+nativeformat();
+ convert(name+"[0]",image,nativeformat());
+
+ if(!settings.keep) {
+ exitfcn currentexitfunction=atexit();
+ void exitfunction() {
+ if(currentexitfunction != null) currentexitfunction();
+ delete(image);
+ }
+ atexit(exitfunction);
+ }
+ }
+ if(width != 0) options += ", width="+(string) (width*pt)+"pt";
+ if(height != 0) options +=", height="+(string) (height*pt)+"pt";
+ return "\href{run:"+name+"}{"+graphic(image,options)+"}";
+}
+
+string hyperlink(string url, string text)
+{
+ return "\href{"+url+"}{"+text+"}";
+}
+
+string link(string url, string text, string options="")
+{
+ return hyperlink("run:"+url,text);
+}
+
diff --git a/Build/source/utils/asymptote/base/feynman.asy b/Build/source/utils/asymptote/base/feynman.asy
new file mode 100644
index 00000000000..4360ee9f524
--- /dev/null
+++ b/Build/source/utils/asymptote/base/feynman.asy
@@ -0,0 +1,622 @@
+/*****************************************************************************
+ * feynman.asy -- An Asymptote library for drawing Feynman diagrams. *
+ * *
+ * by: Martin Wiebusch <martin.wiebusch@gmx.net> *
+ * last change: 2007/04/13 *
+ *****************************************************************************/
+
+
+/* default parameters ********************************************************/
+
+// default ratio of width (distance between two loops) to amplitude for a gluon
+// line. The gluon function uses this ratio, if the width parameter is
+// negative.
+real gluonratio;
+
+// default ratio of width (distance between two crests) to amplitude for a
+// photon line. The photon function uses this ratio, if the width parameter is
+// negative.
+real photonratio;
+
+// default gluon amplitude
+real gluonamplitude;
+
+// default photon amplitude
+real photonamplitude;
+
+// default pen for drawing the background. Usually white.
+pen backgroundpen;
+
+// default pen for drawing gluon lines
+pen gluonpen;
+
+// default pen for drawing photon lines
+pen photonpen;
+
+// default pen for drawing fermion lines
+pen fermionpen;
+
+// default pen for drawing scalar lines
+pen scalarpen;
+
+// default pen for drawing ghost lines
+pen ghostpen;
+
+// default pen for drawing double lines
+pen doublelinepen;
+
+// default pen for drawing vertices
+pen vertexpen;
+
+// default pen for drawing big vertices (drawVertexOX and drawVertexBoxX)
+pen bigvertexpen;
+
+// inner spacing of a double line
+real doublelinespacing;
+
+// default arrow for propagators
+arrowbar currentarrow;
+
+// if true, each of the drawSomething commands blots out the background
+// (with pen backgroundpen) before drawing.
+bool overpaint;
+
+// margin around lines. If one line is drawn over anoter, a white margin
+// of size linemargin is kept around the top one.
+real linemargin;
+
+// at vertices, where many lines join, the last line drawn should not blot
+// out the others. By not erasing the background near the ends of lines,
+// this is prevented for lines with an angle greater than minvertexangle to
+// each other. Note, that small values for minvertexangle mean that the
+// background is only erased behind a small segment of every line. Setting
+// minvertexangle = 0 effectively disables background erasing for lines.
+real minvertexangle;
+
+// size (radius) of vertices
+real vertexsize;
+
+// size (radius) of big vertices (drawVertexOX and drawVertexBoxX)
+real bigvertexsize;
+
+/* defaults for momentum arrows **********************************************/
+
+// (momentum arrows are small arrows parallel to particle lines indicating the
+// direction of momentum)
+
+// default size of the arrowhead of momentum arrows
+arrowbar currentmomarrow;
+
+// default length of momentum arrows
+real momarrowlength;
+
+// default pen for momentum arrows
+pen momarrowpen;
+
+// default offset between momentum arrow and related particle line
+real momarrowoffset;
+
+// default margin for momentum arrows
+real momarrowmargin;
+
+// factor for determining the size of momentum arrowheads. After changing it,
+// you still have to update currentmomarrow manually.
+real momarrowfactor;
+
+// size function for momentum arrowheads
+real momarrowsize(pen p=momarrowpen) { return momarrowfactor*linewidth(p); }
+
+
+/* defaults for texshipout ***************************************************/
+
+// tex command for including graphics. It takes one argument, which is the
+// name of the graphics (eps or pdf) file.
+string includegraphicscommand;
+
+// Determines whether the suffix (.eps or .pdf) should be appended to the stem
+// of the file name in the \includegraphics command.
+bool appendsuffix;
+
+
+/* helper functions **********************************************************/
+
+// internal function for overpainting
+private void do_overpaint(picture pic, path p, pen bgpen,
+ real halfwidth, real vertexangle)
+{
+ real tanvertexangle = tan(vertexangle*pi/180);
+ if(tanvertexangle != 0) {
+ real t1 = arctime(p, halfwidth/tanvertexangle+halfwidth);
+ real t2 = arctime(p, arclength(p)-halfwidth/tanvertexangle-halfwidth);
+ draw(pic, subpath(p, t1, t2),
+ bgpen+linewidth(2*halfwidth));
+ }
+}
+
+// returns the path of a gluon line along path p, with amplitude amp and width
+// width (distance between two loops). If width is negative, the width is
+// set to amp*gluonratio
+path gluon(path p, real amp = gluonamplitude, real width=-1)
+{
+ if(width < 0) width = abs(gluonratio*amp);
+
+ real pathlen = arclength(p);
+ int ncurls = floor(pathlen/width);
+ real firstlen = (pathlen - width*(ncurls-1))/2;
+ real firstt = arctime(p, firstlen);
+ pair firstv = dir(p, firstt);
+ guide g = point(p, 0)..{firstv}( point(p, firstt)
+ +amp*unit(rotate(90)*firstv));
+
+ real t1;
+ pair v1;
+ real t2;
+ pair v2;
+ pathlen -= firstlen;
+ for(real len = firstlen+width/2; len < pathlen; len += width) {
+ t1 = arctime(p, len);
+ v1 = dir(p, t1);
+ t2 = arctime(p, len + width/2);
+ v2 = dir(p, t2);
+
+ g=g..{-v1}(point(p, t1)+amp*unit(rotate(-90)*v1))
+ ..{+v2}(point(p, t2)+amp*unit(rotate(+90)*v2));
+ }
+ g = g..point(p, size(p));
+ return g;
+}
+
+// returns the path of a photon line along path p, with amplitude amp and width
+// width (distance between two crests). If width is negative, the width is
+// set to amp*photonratio
+path photon(path p, real amp = photonamplitude, real width=-1)
+{
+ if(width < 0)
+ width = abs(photonratio*amp)/2;
+ else
+ width = width/2;
+
+ real pathlen = arclength(p);
+ int ncurls = floor(pathlen/width);
+ real firstlen = (pathlen - width*ncurls)/2;
+ real firstt = arctime(p, firstlen+width);
+ guide g = point(p, 0){unit(point(p, firstt)-point(p, 0))};
+
+ real t;
+ pair v;
+ pathlen -= firstlen;
+ for(real len = firstlen+width; len < pathlen; len += width) {
+ t = arctime(p, len);
+ v = dir(p, t);
+
+ g=g..{v}(point(p, t)+amp*unit(rotate(90)*v));
+ amp = -amp;
+ }
+ g = g..{unit(point(p, size(p))-point(p, t))}point(p, size(p));
+ return g;
+}
+
+// returns the path of a momentum arrow along path p, with length length,
+// an offset offset from the path p and at position position. position will
+// usually be one of the predefined pairs left or right. Making adjust
+// nonzero shifts the momentum arrow along the path.
+path momArrowPath(path p,
+ align align,
+ position pos,
+ real offset = momarrowoffset,
+ real length = momarrowlength)
+{
+ real pathlen = arclength(p);
+
+ real t1, t2;
+ if(pos.relative) {
+ t1 = arctime(p, (pathlen-length)*pos.position.x);
+ t2 = arctime(p, (pathlen-length)*pos.position.x+length);
+ } else {
+ t1 = arctime(p, (pathlen-length)/2 + pos.position.x);
+ t2 = arctime(p, (pathlen+length)/2+ pos.position.x);
+ }
+
+ pair v1 = dir(p, t1);
+ pair v2 = dir(p, t2);
+
+ pair p1, p2;
+ if(align.relative) {
+ p1 = point(p, t1) + offset*abs(align.dir)
+ *unit(rotate(degrees(align.dir)-90)*v1);
+ p2 = point(p, t2) + offset*abs(align.dir)
+ *unit(rotate(degrees(align.dir)-90)*v2);
+ } else {
+ p1 = point(p, t1) + offset*align.dir;
+ p2 = point(p, t2) + offset*align.dir;
+ }
+
+ return p1{v1}..{v2}p2;
+}
+
+
+
+
+/* drawing functions *********************************************************/
+
+// draw a gluon line on picture pic, along path p, with amplitude amp, width
+// width (distance between loops) and with pen fgpen. If erasebg is true,
+// bgpen is used to erase the background behind the line and at a margin
+// margin around it. The background is not erased at a certain distance to
+// the endpoints, which is determined by vertexangle (see comments to the
+// default parameter minvertexangle). For negative values of width, the width
+// is set to gluonratio*amp.
+void drawGluon(picture pic = currentpicture,
+ path p,
+ real amp = gluonamplitude,
+ real width = -1,
+ pen fgpen = gluonpen,
+ bool erasebg = overpaint,
+ pen bgpen = backgroundpen,
+ real vertexangle = minvertexangle,
+ real margin = linemargin)
+{
+ if(width < 0) width = abs(2*amp);
+
+ if(erasebg) do_overpaint(pic, p, bgpen, amp+margin, vertexangle);
+ draw(pic, gluon(p, amp, width), fgpen);
+}
+
+// draw a photon line on picture pic, along path p, with amplitude amp, width
+// width (distance between loops) and with pen fgpen. If erasebg is true,
+// bgpen is used to erase the background behind the line and at a margin
+// margin around it. The background is not erased at a certain distance to
+// the endpoints, which is determined by vertexangle (see comments to the
+// default parameter minvertexangle). For negative values of width, the width
+// is set to photonratio*amp.
+void drawPhoton(picture pic = currentpicture,
+ path p,
+ real amp = photonamplitude,
+ real width = -1,
+ pen fgpen = currentpen,
+ bool erasebg = overpaint,
+ pen bgpen = backgroundpen,
+ real vertexangle = minvertexangle,
+ real margin = linemargin)
+{
+ if(width < 0) width = abs(4*amp);
+
+ if(erasebg) do_overpaint(pic, p, bgpen, amp+margin, vertexangle);
+ draw(pic, photon(p, amp, width), fgpen);
+}
+
+// draw a fermion line on picture pic, along path p with pen fgpen and an
+// arrowhead arrow. If erasebg is true, bgpen is used to erase the background
+// at a margin margin around the line. The background is not erased at a
+// certain distance to the endpoints, which is determined by vertexangle
+// (see comments to the default parameter minvertexangle).
+void drawFermion(picture pic = currentpicture,
+ path p,
+ pen fgpen = currentpen,
+ arrowbar arrow = currentarrow,
+ bool erasebg = overpaint,
+ pen bgpen = backgroundpen,
+ real vertexangle = minvertexangle,
+ real margin = linemargin)
+{
+ if(erasebg) do_overpaint(pic, p, bgpen,
+ linewidth(fgpen)+margin, vertexangle);
+ draw(pic, p, fgpen, arrow);
+}
+
+// draw a scalar line on picture pic, along path p with pen fgpen and an
+// arrowhead arrow. If erasebg is true, bgpen is used to erase the background
+// at a margin margin around the line. The background is not erased at a
+// certain distance to the endpoints, which is determined by vertexangle
+// (see comments to the default parameter minvertexangle).
+void drawScalar(picture pic = currentpicture,
+ path p,
+ pen fgpen = scalarpen,
+ arrowbar arrow = currentarrow,
+ bool erasebg = overpaint,
+ pen bgpen = backgroundpen,
+ real vertexangle = minvertexangle,
+ real margin = linemargin)
+{
+ if(erasebg) do_overpaint(pic, p, bgpen,
+ linewidth(fgpen)+margin, vertexangle);
+ draw(pic, p, fgpen, arrow);
+}
+
+// draw a ghost line on picture pic, along path p with pen fgpen and an
+// arrowhead arrow. If erasebg is true, bgpen is used to erase the background
+// at a margin margin around the line. The background is not erased at a
+// certain distance to the endpoints, which is determined by vertexangle
+// (see comments to the default parameter minvertexangle).
+void drawGhost(picture pic = currentpicture,
+ path p,
+ pen fgpen = ghostpen,
+ arrowbar arrow = currentarrow,
+ bool erasebg = overpaint,
+ pen bgpen = backgroundpen,
+ real vertexangle = minvertexangle,
+ real margin = linemargin)
+{
+ if(erasebg) do_overpaint(pic, p, bgpen,
+ linewidth(fgpen)+margin, vertexangle);
+ draw(pic, p, fgpen, arrow);
+}
+
+// draw a double line on picture pic, along path p with pen fgpen, an inner
+// spacing of dlspacint and an arrowhead arrow. If erasebg is true, bgpen is
+// used to erase the background at a margin margin around the line. The
+// background is not erased at a certain distance to the endpoints, which is
+// determined by vertexangle (see comments to the default parameter
+// minvertexangle).
+void drawDoubleLine(picture pic = currentpicture,
+ path p,
+ pen fgpen = doublelinepen,
+ real dlspacing = doublelinespacing,
+ arrowbar arrow = currentarrow,
+ bool erasebg = overpaint,
+ pen bgpen = backgroundpen,
+ real vertexangle = minvertexangle,
+ real margin = linemargin)
+{
+ if(erasebg) do_overpaint(pic, p, bgpen,
+ linewidth(fgpen)+margin, vertexangle);
+
+ real htw = linewidth(fgpen)+dlspacing/2;
+ draw(pic, p, fgpen+2*htw);
+ draw(pic, p, bgpen+(linewidth(dlspacing)));
+ path rect = (-htw,-htw)--(-htw,htw)--(0,htw)--(0,-htw)--cycle;
+ fill(shift(point(p,0))*rotate(degrees(dir(p,0)))*rect, bgpen);
+ fill(shift(point(p,size(p)))*scale(-1)*rotate(degrees(dir(p,size(p))))*
+ rect,bgpen);
+ draw(pic, p, invisible, arrow);
+}
+
+// draw a vertex dot on picture pic, at position xy with radius r and pen
+// fgpen
+void drawVertex(picture pic = currentpicture,
+ pair xy,
+ real r = vertexsize,
+ pen fgpen = vertexpen)
+{
+ fill(pic, circle(xy, r), fgpen);
+}
+
+// draw an empty vertex dot on picture pic, at position xy with radius r
+// and pen fgpen. If erasebg is true, the background is erased in the inside
+// of the circle.
+void drawVertexO(picture pic = currentpicture,
+ pair xy,
+ real r = vertexsize,
+ pen fgpen = vertexpen,
+ bool erasebg = overpaint,
+ pen bgpen = backgroundpen)
+{
+ if(erasebg)
+ filldraw(pic, circle(xy, r), bgpen, fgpen);
+ else
+ draw(pic, circle(xy, r), fgpen);
+}
+
+// draw a vertex triangle on picture pic, at position xy with radius r and pen
+// fgpen
+void drawVertexTriangle(picture pic = currentpicture,
+ pair xy,
+ real r = vertexsize,
+ pen fgpen = vertexpen)
+{
+ real cospi6 = cos(pi/6);
+ real sinpi6 = sin(pi/6);
+ path triangle = (cospi6,-sinpi6)--(0,1)--(-cospi6,-sinpi6)--cycle;
+ fill(pic, shift(xy)*scale(r)*triangle, fgpen);
+}
+
+// draw an empty vertex triangle on picture pic, at position xy with size r
+// and pen fgpen. If erasebg is true, the background is erased in the inside
+// of the triangle.
+void drawVertexTriangleO(picture pic = currentpicture,
+ pair xy,
+ real r = vertexsize,
+ pen fgpen = vertexpen,
+ bool erasebg = overpaint,
+ pen bgpen = backgroundpen)
+{
+ real cospi6 = cos(pi/6);
+ real sinpi6 = sin(pi/6);
+ path triangle = (cospi6,-sinpi6)--(0,1)--(-cospi6,-sinpi6)--cycle;
+
+ if(erasebg)
+ filldraw(pic, shift(xy)*scale(r)*triangle, bgpen, fgpen);
+ else
+ draw(pic, shift(xy)*scale(r)*triangle, fgpen);
+}
+
+// draw a vertex box on picture pic, at position xy with radius r and pen
+// fgpen
+void drawVertexBox(picture pic = currentpicture,
+ pair xy,
+ real r = vertexsize,
+ pen fgpen = vertexpen)
+{
+ path box = (1,1)--(-1,1)--(-1,-1)--(1,-1)--cycle;
+ fill(pic, shift(xy)*scale(r)*box, fgpen);
+}
+
+// draw an empty vertex box on picture pic, at position xy with size r
+// and pen fgpen. If erasebg is true, the background is erased in the inside
+// of the box.
+void drawVertexBoxO(picture pic = currentpicture,
+ pair xy,
+ real r = vertexsize,
+ pen fgpen = vertexpen,
+ bool erasebg = overpaint,
+ pen bgpen = backgroundpen)
+{
+ path box = (1,1)--(-1,1)--(-1,-1)--(1,-1)--cycle;
+ if(erasebg)
+ filldraw(pic, shift(xy)*scale(r)*box, bgpen, fgpen);
+ else
+ draw(pic, shift(xy)*scale(r)*box, fgpen);
+}
+
+// draw an X on picture pic, at position xy with size r and pen
+// fgpen
+void drawVertexX(picture pic = currentpicture,
+ pair xy,
+ real r = vertexsize,
+ pen fgpen = vertexpen)
+{
+ draw(pic, shift(xy)*scale(r)*((-1,-1)--(1,1)), fgpen);
+ draw(pic, shift(xy)*scale(r)*((1,-1)--(-1,1)), fgpen);
+}
+
+// draw a circle with an X in the middle on picture pic, at position xy with
+// size r and pen fgpen. If erasebg is true, the background is erased in the
+// inside of the circle.
+void drawVertexOX(picture pic = currentpicture,
+ pair xy,
+ real r = bigvertexsize,
+ pen fgpen = vertexpen,
+ bool erasebg = overpaint,
+ pen bgpen = backgroundpen)
+{
+ if(erasebg)
+ filldraw(pic, circle(xy, r), bgpen, fgpen);
+ else
+ draw(pic, circle(xy, r), fgpen);
+ draw(pic, shift(xy)*scale(r)*(NW--SE), fgpen);
+ draw(pic, shift(xy)*scale(r)*(SW--NE), fgpen);
+}
+
+// draw a box with an X in the middle on picture pic, at position xy with
+// size r and pen fgpen. If erasebg is true, the background is erased in the
+// inside of the box.
+void drawVertexBoxX(picture pic = currentpicture,
+ pair xy,
+ real r = bigvertexsize,
+ pen fgpen = vertexpen,
+ bool erasebg = overpaint,
+ pen bgpen = backgroundpen)
+{
+ path box = (1,1)--(-1,1)--(-1,-1)--(1,-1)--cycle;
+ box = shift(xy)*scale(r)*box;
+ if(erasebg)
+ filldraw(pic, box, bgpen, fgpen);
+ else
+ draw(pic, box, fgpen);
+ draw(pic, shift(xy)*scale(r)*((-1,-1)--(1,1)), fgpen);
+ draw(pic, shift(xy)*scale(r)*((1,-1)--(-1,1)), fgpen);
+}
+
+// draw a momentum arrow on picture pic, along path p, at position position
+// (use one of the predefined pairs left or right), with an offset offset
+// from the path, a length length, a pen fgpen and an arrowhead arrow. Making
+// adjust nonzero shifts the momentum arrow along the path. If erasebg is true,
+// the background is erased inside a margin margin around the momentum arrow.
+// Make sure that offset and margin are chosen in such a way that the momentum
+// arrow does not overdraw the particle line.
+void drawMomArrow(picture pic = currentpicture,
+ path p,
+ align align,
+ position pos = MidPoint,
+ real offset = momarrowoffset,
+ real length = momarrowlength,
+ pen fgpen = momarrowpen,
+ arrowbar arrow = currentmomarrow,
+ bool erasebg = overpaint,
+ pen bgpen = backgroundpen,
+ real margin = momarrowmargin)
+{
+ path momarrow = momArrowPath(p, align, pos, offset, length);
+ if(erasebg) do_overpaint(pic, momarrow, bgpen,
+ linewidth(fgpen)+margin, 90);
+ draw(pic, momarrow, fgpen, arrow);
+}
+
+
+/* initialisation ************************************************************/
+
+// The function fmdefaults() tries to guess reasonable values for the
+// default parameters above by looking at the default parameters of plain.asy
+// (essentially, currentpen, arrowfactor and dotfactor). After customising the
+// default parameters of plain.asy, you may call fmdefaults to adjust the
+// parameters of feynman.asy.
+void fmdefaults()
+{
+ real arrowsize=arrowsize(currentpen);
+ real linewidth=linewidth(currentpen);
+
+ gluonratio = 2;
+ photonratio = 4;
+ gluonamplitude = arrowsize/3;
+ photonamplitude = arrowsize/4;
+
+ backgroundpen = white;
+ gluonpen = currentpen;
+ photonpen = currentpen;
+ fermionpen = currentpen;
+ scalarpen = dashed+linewidth;
+ ghostpen = dotted+linewidth;
+ doublelinepen = currentpen;
+ vertexpen = currentpen;
+ bigvertexpen = currentpen;
+ currentarrow = MidArrow;
+
+ doublelinespacing = 2*linewidth;
+ linemargin = 0.5*arrowsize;
+ minvertexangle = 30;
+ overpaint = true;
+ vertexsize = 0.5*dotfactor*linewidth;
+ bigvertexsize = 0.4*arrowsize;
+
+ momarrowfactor = 1.5*arrowfactor;
+ momarrowlength = 2.5*arrowsize;
+ momarrowpen = currentpen+0.5*linewidth;
+ momarrowoffset = 0.8*arrowsize;
+ momarrowmargin = 0.25*arrowsize;
+ currentmomarrow = EndArrow(momarrowsize());
+
+ includegraphicscommand = "\includegraphics";
+ appendsuffix = false;
+}
+
+// We call fmdefaults once, when the module is loaded.
+fmdefaults();
+
+
+/* shipout *******************************************************************/
+
+bool YAlign = false;
+bool XYAlign = true;
+
+// texshipout("filename", pic) creates two files: filename.eps holding the
+// picture pic and filename.tex holding some LaTeX code that includes the
+// picture from filename.eps and shifts it vertically in such a way that the
+// point (0,0) lies on the baseline.
+void texshipout(string stem,
+ picture pic = currentpicture,
+ bool xalign = YAlign)
+{
+ file tf = output(stem + ".tex");
+ pair min=pic.min();
+ real depth = min.y;
+ real xoffset = min.x;
+ if(xalign) {
+ write(tf, "\makebox[0pt][l]{\kern");
+ write(tf, xoffset);
+ write(tf, "bp\relax");
+ }
+ write(tf, "\raisebox{");
+ write(tf, depth);
+ write(tf, "bp}{"+includegraphicscommand+"{");
+ write(tf, stem);
+ string suffix="."+nativeformat();
+ if(appendsuffix)
+ write(tf, suffix);
+ write(tf, "}}");
+ if(xalign)
+ write(tf, "}");
+ close(tf);
+ shipout(stem+suffix, pic);
+}
+
+
diff --git a/Build/source/utils/asymptote/base/flowchart.asy b/Build/source/utils/asymptote/base/flowchart.asy
new file mode 100644
index 00000000000..5fe96ae8508
--- /dev/null
+++ b/Build/source/utils/asymptote/base/flowchart.asy
@@ -0,0 +1,356 @@
+// Flowchart routines written by Jacques Pienaar, Steve Melenchuk, John Bowman.
+
+private import math;
+
+struct flowdir {}
+
+restricted flowdir Horizontal;
+restricted flowdir Vertical;
+
+real minblockwidth=0;
+real minblockheight=0;
+real mincirclediameter=0;
+
+struct block {
+ // The absolute center of the block in user coordinates.
+ pair center;
+
+ // The relative center of the block.
+ pair f_center;
+
+ // The size of the block
+ pair size;
+
+ // Returns the relative position along the boundary of the block.
+ pair f_position(real x);
+
+ pair shift(transform t=identity()) {
+ return t*center-f_center;
+ }
+
+ // Returns the absolute position along the boundary of the block.
+ pair position(real x, transform t=identity()) {
+ return shift(t)+f_position(x);
+ }
+
+ // These eight variables return the appropriate location on the block
+ // in relative coordinates, where the lower left corner of the block is (0,0).
+ pair f_top;
+ pair f_left;
+ pair f_right;
+ pair f_bottom;
+ pair f_topleft;
+ pair f_topright;
+ pair f_bottomleft;
+ pair f_bottomright;
+
+ // These eight functions return the appropriate location on the block
+ // in absolute coordinates.
+ pair top(transform t=identity()) {
+ return shift(t)+f_top;
+ }
+ pair bottom(transform t=identity()) {
+ return shift(t)+f_bottom;
+ }
+ pair left(transform t=identity()) {
+ return shift(t)+f_left;
+ }
+ pair right(transform t=identity()) {
+ return shift(t)+f_right;
+ }
+ pair topleft(transform t=identity()) {
+ return shift(t)+f_topleft;
+ }
+ pair topright(transform t=identity()) {
+ return shift(t)+f_topright;
+ }
+ pair bottomleft(transform t=identity()) {
+ return shift(t)+f_bottomleft;
+ }
+ pair bottomright(transform t=identity()) {
+ return shift(t)+f_bottomright;
+ }
+
+ // Return a frame representing the block.
+ frame draw(pen p=currentpen);
+};
+
+// Construct a rectangular block with header and body objects.
+block rectangle(object header, object body, pair center=(0,0),
+ pen headerpen=mediumgray, pen bodypen=invisible,
+ pen drawpen=currentpen,
+ real dx=3, real minheaderwidth=minblockwidth,
+ real minheaderheight=minblockwidth,
+ real minbodywidth=minblockheight,
+ real minbodyheight=minblockheight)
+{
+ frame fbody=body.f;
+ frame fheader=header.f;
+ pair mheader=min(fheader);
+ pair Mheader=max(fheader);
+ pair mbody=min(fbody);
+ pair Mbody=max(fbody);
+ pair bound0=Mheader-mheader;
+ pair bound1=Mbody-mbody;
+ real width=max(bound0.x,bound1.x);
+ pair z0=maxbound((width+2dx,bound0.y+2dx),(minbodywidth,minbodyheight));
+ pair z1=maxbound((width+2dx,bound1.y+2dx),(minheaderwidth,minheaderheight));
+ path shape=(0,0)--(0,z1.y)--(0,z0.y+z1.y)--(z0.x,z0.y+z1.y)--z1--(z0.x,0)--
+ cycle;
+
+ block block;
+ block.draw=new frame(pen p) {
+ frame block;
+ filldraw(block,shift(0,z1.y)*box((0,0),z0),headerpen,drawpen);
+ add(block,shift(-0.5*(Mheader+mheader))*fheader,(0,z1.y)+0.5z0);
+ filldraw(block,box((0,0),z1),bodypen,drawpen);
+ add(block,shift(-0.5*(Mbody+mbody))*fbody,0.5z1);
+ return block;
+ };
+ block.f_position=new pair(real x) {
+ return point(shape,x);
+ };
+ block.f_center=interp(point(shape,0),point(shape,3),0.5);
+ block.f_bottomleft=point(shape,0);
+ block.f_bottom=point(shape,5.5);
+ block.f_bottomright=point(shape,5);
+ block.f_right=point(shape,4.5);
+ block.f_topright=point(shape,3);
+ block.f_top=point(shape,2.5);
+ block.f_topleft=point(shape,2);
+ block.f_left=point(shape,0.5);
+ block.center=center;
+ block.size=point(shape,3);
+ return block;
+}
+
+// As above, but without the header.
+block rectangle(object body, pair center=(0,0),
+ pen fillpen=invisible, pen drawpen=currentpen,
+ real dx=3, real minwidth=minblockwidth,
+ real minheight=minblockheight)
+{
+ frame f=body.f;
+ pair m=min(f);
+ pair M=max(f);
+ pair z=maxbound(M-m+dx*(2,2),(minwidth,minheight));
+ path shape=box((0,0),z);
+
+ block block;
+ block.draw=new frame(pen p) {
+ frame block;
+ filldraw(block,shape,fillpen,drawpen);
+ add(block,shift(-0.5*(M+m))*f,0.5z);
+ return block;
+ };
+ block.f_position=new pair(real x) {
+ return point(shape,x);
+ };
+ block.f_center=0.5*z;
+ block.center=center;
+ block.size=z;
+ block.f_bottomleft=point(shape,0);
+ block.f_bottom=point(shape,0.5);
+ block.f_bottomright=point(shape,1);
+ block.f_right=point(shape,1.5);
+ block.f_topright=point(shape,2);
+ block.f_top=point(shape,2.5);
+ block.f_topleft=point(shape,3);
+ block.f_left=point(shape,3.5);
+ return block;
+}
+
+block diamond(object body, pair center=(0,0),
+ pen fillpen=invisible, pen drawpen=currentpen,
+ real ds=5, real dw=1,
+ real height=20, real minwidth=minblockwidth,
+ real minheight=minblockheight)
+{
+ frame f=body.f;
+ pair m=min(f);
+ pair M=max(f);
+ pair bound=maxbound(M-m,(minwidth,minheight));
+
+ real e=ds;
+ real a=0.5bound.x-dw;
+ real b=0.5bound.y;
+ real c=b+height;
+
+ real arg=a^2+b^2+c^2-2b*c-e^2;
+ real denom=e^2-a^2;
+ real slope=arg >= 0 && denom != 0 ? (a*(c-b)-e*sqrt(arg))/denom : 1.0;
+ real d=abs(c/slope);
+
+ path shape=(2d,c)--(d,2c)--(0,c)--(d,0)--cycle;
+
+ block block;
+ block.draw=new frame(pen p) {
+ frame block;
+ filldraw(block,shape,fillpen,drawpen);
+ add(block,shift(-0.5*(M+m))*f,(d,c));
+ return block;
+ };
+ block.f_position=new pair(real x) {
+ return point(shape,x);
+ };
+ block.f_center=(point(shape,1).x,point(shape,0).y);
+ block.center=center;
+ block.size=(point(shape,0).x,point(shape,1).y);
+ block.f_bottomleft=point(shape,2.5);
+ block.f_bottom=point(shape,3);
+ block.f_bottomright=point(shape,3.5);
+ block.f_right=point(shape,0);
+ block.f_topright=point(shape,0.5);
+ block.f_top=point(shape,1);
+ block.f_topleft=point(shape,1.5);
+ block.f_left=point(shape,2);
+ return block;
+}
+
+block circle(object body, pair center=(0,0), pen fillpen=invisible,
+ pen drawpen=currentpen, real dr=3,
+ real mindiameter=mincirclediameter)
+{
+ frame f=body.f;
+ pair m=min(f);
+ pair M=max(f);
+ real r=max(0.5length(M-m)+dr,0.5mindiameter);
+
+ path shape=(0,r)..(r,2r)..(2r,r)..(r,0)..cycle;
+
+ block block;
+ block.draw=new frame(pen p) {
+ frame block;
+ filldraw(block,shape,fillpen,drawpen);
+ add(block,shift(-0.5*(M+m))*f,(r,r));
+ return block;
+ };
+ block.f_position=new pair(real x) {
+ return point(shape,x);
+ };
+ block.f_center=(r,r);
+ block.center=center;
+ block.size=(2r,2r);
+ block.f_left=point(shape,0);
+ block.f_topleft=point(shape,0.5);
+ block.f_top=point(shape,1);
+ block.f_topright=point(shape,1.5);
+ block.f_right=point(shape,2);
+ block.f_bottomright=point(shape,2.5);
+ block.f_bottom=point(shape,3);
+ block.f_bottomleft=point(shape,3.5);
+ return block;
+}
+
+block roundrectangle(object body, pair center=(0,0),
+ pen fillpen=invisible, pen drawpen=currentpen,
+ real ds=5, real dw=0, real minwidth=minblockwidth,
+ real minheight=minblockheight)
+{
+ frame f=body.f;
+ pair m=min(f);
+ pair M=max(f);
+ pair bound=maxbound(M-m,(minwidth,minheight));
+
+ real a=bound.x;
+ real b=bound.y;
+
+ path shape=(0,ds+dw)--(0,ds+b-dw){up}..{right}
+ (ds+dw,2ds+b)--(ds+a-dw,2ds+b){right}..{down}
+ (2ds+a,ds+b-dw)--(2ds+a,ds+dw){down}..{left}
+ (ds+a-dw,0)--(ds+dw,0){left}..{up}cycle;
+
+ block block;
+ block.draw=new frame(pen p) {
+ frame block;
+ filldraw(block,shape,fillpen,drawpen);
+ add(block,shift(-0.5*(M+m))*f,(ds,ds)+0.5bound);
+ return block;
+ };
+ block.f_position=new pair(real x) {
+ return point(shape,x);
+ };
+ block.f_center=(ds+0.5a,ds+0.5b);
+ block.center=center;
+ block.size=(2ds+a,2ds+b);
+ block.f_bottomleft=point(shape,7.5);
+ block.f_bottom=point(shape,6.5);
+ block.f_bottomright=point(shape,5.5);
+ block.f_right=point(shape,4.5);
+ block.f_topright=point(shape,3.5);
+ block.f_top=point(shape,2.5);
+ block.f_topleft=point(shape,1.5);
+ block.f_left=point(shape,0.5);
+ return block;
+}
+
+block bevel(object body, pair center=(0,0), pen fillpen=invisible,
+ pen drawpen=currentpen, real dh=5, real dw=5,
+ real minwidth=minblockwidth, real minheight=minblockheight)
+{
+ frame f=body.f;
+ pair m=min(f);
+ pair M=max(f);
+ pair bound=maxbound(M-m,(minwidth,minheight));
+
+ real a=bound.x;
+ real b=0.5bound.y;
+
+ path shape=(2dw+a,b+dh)--(dw+a,2b+2dh)--(dw,2b+2dh)--(0,b+dh)--(dw,0)--
+ (dw+a,0)--cycle;
+ block block;
+ block.draw=new frame(pen p) {
+ frame block;
+ filldraw(block,shape,fillpen,drawpen);
+ add(block,shift(-0.5*(M+m))*f,(0.5bound+(dw,dh)));
+ return block;
+ };
+ block.f_position=new pair(real x) {
+ return point(shape,x);
+ };
+ block.f_center=(dw+0.5a,dh+b);
+ block.center=center;
+ block.size=(2dw+a,2dh+2b);
+ block.f_bottomleft=point(shape,4);
+ block.f_bottom=point(shape,4.5);
+ block.f_bottomright=point(shape,5);
+ block.f_right=point(shape,0);
+ block.f_topright=point(shape,1);
+ block.f_top=point(shape,1.5);
+ block.f_topleft=point(shape,2);
+ block.f_left=point(shape,3);
+ return block;
+}
+
+path path(pair point[] ... flowdir dir[])
+{
+ path line=point[0];
+ pair current, prev=point[0];
+ for(int i=1; i < point.length; ++i) {
+ if(dir[i-1] == Horizontal)
+ current=(point[i].x,point[i-1].y);
+ else
+ current=(point[i-1].x,point[i].y);
+
+ if(current != prev) {
+ line=line--current;
+ prev=current;
+ }
+
+ current=point[i];
+ if(current != prev) {
+ line=line--current;
+ prev=current;
+ }
+ }
+ return line;
+}
+
+void draw(picture pic=currentpicture, block block, pen p=currentpen)
+{
+ pic.add(new void (frame f, transform t) {
+ add(f,shift(block.shift(t))*block.draw(p));
+ },true);
+ pic.addBox(block.center,block.center,
+ -0.5*block.size+min(p),0.5*block.size+max(p));
+}
diff --git a/Build/source/utils/asymptote/base/fontsize.asy b/Build/source/utils/asymptote/base/fontsize.asy
new file mode 100644
index 00000000000..0c0c6a0dcca
--- /dev/null
+++ b/Build/source/utils/asymptote/base/fontsize.asy
@@ -0,0 +1 @@
+usepackage("fix-cm");
diff --git a/Build/source/utils/asymptote/base/geometry.asy b/Build/source/utils/asymptote/base/geometry.asy
new file mode 100644
index 00000000000..a4860557e1f
--- /dev/null
+++ b/Build/source/utils/asymptote/base/geometry.asy
@@ -0,0 +1,7150 @@
+// Copyright (c) 2007, Philippe Ivaldi.
+// Version: : geometry.asy,v 0.1 2007/09/01 Philippe Ivaldi Exp $
+
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 3 of the License, or (at
+// your option) any later version.
+
+// This program 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
+// General Public License for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+// 02110-1301, USA.
+
+// COMMENTARY:
+// An Asymptote geometry module.
+
+// THANKS:
+// Special thanks to Olivier Guibé for his help in mathematical issues.
+
+// BUGS:
+
+// CODE:
+
+import math;
+import markers;
+// *=======================================================*
+// *........................HEADER.........................*
+/*<asyxml><variable type="real" signature="epsgeo"><code></asyxml>*/
+real epsgeo=10*sqrt(realEpsilon);/*<asyxml></code><documentation>Variable used in the approximate calculations.</documentation></variable></asyxml>*/
+
+/*<asyxml><function type="void" signature="addMargins(picture,real,real,real,real)"><code></asyxml>*/
+void addMargins(picture pic=currentpicture,
+ real lmargin=0, real bmargin=0,
+ real rmargin=lmargin, real tmargin=bmargin,
+ bool rigid=true, bool allObject=true)
+{/*<asyxml></code><documentation>Add margins to 'pic' with respect to
+ the current bounding box of 'pic'.
+ If 'rigid' is false, margins are added iff an infinite curve will
+ be prolonged on the margin.
+ If 'allObject' is false, fixed-size objects (such as labels and
+ arrowheads) will be ignored.</documentation></function></asyxml>*/
+ pair m=allObject ? truepoint(pic,SW) : point(pic,SW);
+ pair M=allObject ? truepoint(pic,NE) : point(pic,NE);
+ if(rigid) {
+ draw(m-inverse(pic.calculateTransform())*(lmargin,bmargin),invisible);
+ draw(M+inverse(pic.calculateTransform())*(rmargin,tmargin),invisible);
+ } else pic.addBox(m,M,-(lmargin,bmargin),(rmargin,tmargin));
+}
+
+real approximate(real t)
+{
+ real ot=t;
+ if(abs(t-ceil(t)) < epsgeo) ot=ceil(t);
+ else if(abs(t-floor(t)) < epsgeo) ot=floor(t);
+ return ot;
+}
+
+real[] approximate(real[] T)
+{
+ return map(approximate,T);
+}
+
+/*<asyxml><function type="real" signature="binomial(real,real)"><code></asyxml>*/
+real binomial(real n, real k)
+{/*<asyxml></code><documentation>Return n!/((n-k)!*k!)</documentation></function></asyxml>*/
+ return gamma(n+1)/(gamma(n-k+1)*gamma(k+1));
+}
+
+/*<asyxml><function type="real" signature="rf(real,real,real)"><code></asyxml>*/
+real rf(real x, real y, real z)
+{/*<asyxml></code><documentation>Computes Carlson's elliptic integral of the first kind.
+ x, y, and z must be non negative, and at most one can be zero.</documentation></function></asyxml>*/
+ real ERRTOL=0.0025,
+ TINY=1.5e-38,
+ BIG=3e37,
+ THIRD=1/3,
+ C1=1/24,
+ C2=0.1,
+ C3=3/44,
+ C4=1/14;
+ real alamb,ave,delx,dely,delz,e2,e3,sqrtx,sqrty,sqrtz,xt,yt,zt;
+ if(min(x,y,z) < 0 || min(x+y,x+z,y+z) < TINY ||
+ max(x,y,z) > BIG) abort("rf: invalid arguments.");
+ xt=x;
+ yt=y;
+ zt=z;
+ do {
+ sqrtx=sqrt(xt);
+ sqrty=sqrt(yt);
+ sqrtz=sqrt(zt);
+ alamb=sqrtx*(sqrty+sqrtz)+sqrty*sqrtz;
+ xt=0.25*(xt+alamb);
+ yt=0.25*(yt+alamb);
+ zt=0.25*(zt+alamb);
+ ave=THIRD*(xt+yt+zt);
+ delx=(ave-xt)/ave;
+ dely=(ave-yt)/ave;
+ delz=(ave-zt)/ave;
+ } while(max(fabs(delx),fabs(dely),fabs(delz)) > ERRTOL);
+ e2=delx*dely-delz*delz;
+ e3=delx*dely*delz;
+ return (1.0+(C1*e2-C2-C3*e3)*e2+C4*e3)/sqrt(ave);
+}
+
+/*<asyxml><function type="real" signature="rd(real,real,real)"><code></asyxml>*/
+real rd(real x, real y, real z)
+{/*<asyxml></code><documentation>Computes Carlson's elliptic integral of the second kind.
+ x and y must be positive, and at most one can be zero.
+ z must be non negative.</documentation></function></asyxml>*/
+ real ERRTOL=0.0015,
+ TINY=1e-25,
+ BIG=4.5*10.0^21,
+ C1=(3/14),
+ C2=(1/6),
+ C3=(9/22),
+ C4=(3/26),
+ C5=(0.25*C3),
+ C6=(1.5*C4);
+ real alamb,ave,delx,dely,delz,ea,eb,ec,ed,ee,fac,sqrtx,sqrty,
+ sqrtz,sum,xt,yt,zt;
+ if (min(x,y) < 0 || min(x+y,z) < TINY || max(x,y,z) > BIG)
+ abort("rd: invalid arguments");
+ xt=x;
+ yt=y;
+ zt=z;
+ sum=0;
+ fac=1;
+ do {
+ sqrtx=sqrt(xt);
+ sqrty=sqrt(yt);
+ sqrtz=sqrt(zt);
+ alamb=sqrtx*(sqrty+sqrtz)+sqrty*sqrtz;
+ sum += fac/(sqrtz*(zt+alamb));
+ fac=0.25*fac;
+ xt=0.25*(xt+alamb);
+ yt=0.25*(yt+alamb);
+ zt=0.25*(zt+alamb);
+ ave=0.2*(xt+yt+3.0*zt);
+ delx=(ave-xt)/ave;
+ dely=(ave-yt)/ave;
+ delz=(ave-zt)/ave;
+ } while (max(fabs(delx),fabs(dely),fabs(delz)) > ERRTOL);
+ ea=delx*dely;
+ eb=delz*delz;
+ ec=ea-eb;
+ ed=ea-6*eb;
+ ee=ed+ec+ec;
+ return 3*sum+fac*(1.0+ed*(-C1+C5*ed-C6*delz*ee)
+ +delz*(C2*ee+delz*(-C3*ec+delz*C4*ea)))/(ave*sqrt(ave));
+}
+
+/*<asyxml><function type="real" signature="elle(real,real)"><code></asyxml>*/
+real elle(real phi, real k)
+{/*<asyxml></code><documentation>Legendre elliptic integral of the 2nd kind,
+ evaluated using Carlson's functions RD and RF.
+ The argument ranges are -infinity < phi < +infinity, 0 <= k*sin(phi) <= 1.</documentation></function></asyxml>*/
+ real result;
+ if (phi >= 0 && phi <= pi/2) {
+ real cc,q,s;
+ s=sin(phi);
+ cc=cos(phi)^2;
+ q=(1-s*k)*(1+s*k);
+ result=s*(rf(cc,q,1)-(s*k)^2*rd(cc,q,1)/3);
+ } else
+ if (phi <= pi && phi >= 0) {
+ result=2*elle(pi/2,k)-elle(pi-phi,k);
+ } else
+ if (phi <= 3*pi/2 && phi >= 0) {
+ result=2*elle(pi/2,k)+elle(phi-pi,k);
+ } else
+ if (phi <= 2*pi && phi >= 0) {
+ result=4*elle(pi/2,k)-elle(2*pi-phi,k);
+ } else
+ if (phi >= 0) {
+ int nb=floor(0.5*phi/pi);
+ result=nb*elle(2*pi,k)+elle(phi%(2*pi),k);
+ } else result=-elle(-phi,k);
+ return result;
+}
+
+/*<asyxml><function type="pair[]" signature="intersectionpoints(pair,pair,real,real,real,real,real,real)"><code></asyxml>*/
+pair[] intersectionpoints(pair A, pair B,
+ real a, real b, real c, real d, real f, real g)
+{/*<asyxml></code><documentation>Intersection points with the line (AB) and the quadric curve
+ a*x^2+b*x*y+c*y^2+d*x+f*y+g=0 given in the default coordinate system</documentation></function></asyxml>*/
+ pair[] op;
+ real ap=B.y-A.y,
+ bpp=A.x-B.x,
+ cp=A.y*B.x-A.x*B.y;
+ real sol[];
+ if (abs(ap) > epsgeo) {
+ real aa=ap*c+a*bpp^2/ap-b*bpp,
+ bb=ap*f-bpp*d+2*a*bpp*cp/ap-b*cp,
+ cc=ap*g-cp*d+a*cp^2/ap;
+ sol=quadraticroots(aa,bb,cc);
+ for (int i=0; i<sol.length; ++i) {
+ op.push((-bpp*sol[i]/ap-cp/ap,sol[i]));
+ }
+ } else {
+ real aa=a*bpp,
+ bb=d*bpp-b*cp,
+ cc=g*bpp-cp*f+c*cp^2/bpp;
+ sol=quadraticroots(aa,bb,cc);
+ for (int i=0; i<sol.length; ++i) {
+ op.push((sol[i],-cp/bpp));
+ }
+ }
+ return op;
+}
+
+/*<asyxml><function type="pair[]" signature="intersectionpoints(pair,pair,real[])"><code></asyxml>*/
+pair[] intersectionpoints(pair A, pair B, real[] equation)
+{/*<asyxml></code><documentation>Return the intersection points of the line AB with
+ the conic whose an equation is
+ equation[0]*x^2+equation[1]*x*y+equation[2]*y^2+equation[3]*x+equation[4]*y+equation[5]=0</documentation></function></asyxml>*/
+ if(equation.length != 6) abort("intersectionpoints: bad length of array for a conic equation.");
+ return intersectionpoints(A, B, equation[0], equation[1], equation[2],
+ equation[3], equation[4], equation[5]);
+}
+// *........................HEADER.........................*
+// *=======================================================*
+
+// *=======================================================*
+// *......................COORDINATES......................*
+// Copyright (c) 2007, Philippe Ivaldi.
+// Version: $Id: coordinates.asy,v 0.0 2007/02/03 16:06:23 Philippe Ivaldi Exp$
+// Last modified: Wed Aug 15 15:53:01 CEST 2007
+
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 3 of the License, or
+// any later version.
+
+// This program 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
+// General Public License for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+// 02110-1301, USA.
+
+real EPS=sqrt(realEpsilon);
+
+/*<asyxml><typedef type="convert" return="pair" params="pair"><code></asyxml>*/
+typedef pair convert(pair);/*<asyxml></code><documentation>Function type to convert pair in an other coordinate system.</documentation></typedef></asyxml>*/
+/*<asyxml><typedef type="abs" return="real" params="pair"><code></asyxml>*/
+typedef real abs(pair);/*<asyxml></code><documentation>Function type to calculate modulus of pair.</documentation></typedef></asyxml>*/
+/*<asyxml><typedef type="dot" return="real" params="pair,pair"><code></asyxml>*/
+typedef real dot(pair,pair);/*<asyxml></code><documentation>Function type to calculate dot product.</documentation></typedef></asyxml>*/
+/*<asyxml><typedef type="polar" return="pair" params="real,real"><code></asyxml>*/
+typedef pair polar(real,real);/*<asyxml></code><documentation>Function type to calculate the coordinates from the polar coordinates.</documentation></typedef></asyxml>*/
+
+/*<asyxml><struct signature="coordsys"><code></asyxml>*/
+struct coordsys
+{/*<asyxml></code><documentation>This structure represents a coordinate system in the plane.</documentation></asyxml>*/
+ /*<asyxml><method type="pair" signature="relativetodefault(pair)"><code></asyxml>*/
+ restricted convert relativetodefault=new pair(pair m){return m;};/*<asyxml></code><documentation>Convert a pair given relatively to this coordinate system to
+ the pair relatively to the default coordinate system.</documentation></method></asyxml>*/
+ /*<asyxml><method type="pair" signature="defaulttorelativet(pair)"><code></asyxml>*/
+ restricted convert defaulttorelative=new pair(pair m){return m;};/*<asyxml></code><documentation>Convert a pair given relatively to the default coordinate system to
+ the pair relatively to this coordinate system.</documentation></method></asyxml>*/
+ /*<asyxml><method type="real" signature="dot(pair,pair)"><code></asyxml>*/
+ restricted dot dot=new real(pair m, pair n){return dot(m,n);};/*<asyxml></code><documentation>Return the dot product of this coordinate system.</documentation></method></asyxml>*/
+ /*<asyxml><method type="real" signature="abs(pair)"><code></asyxml>*/
+ restricted abs abs=new real(pair m){return abs(m);};/*<asyxml></code><documentation>Return the modulus of a pair in this coordinate system.</documentation></method></asyxml>*/
+ /*<asyxml><method type="pair" signature="polar(real,real)"><code></asyxml>*/
+ restricted polar polar=new pair(real r, real a){return (r*cos(a),r*sin(a));};/*<asyxml></code><documentation>Polar coordinates routine of this coordinate system.</documentation></method></asyxml>*/
+ /*<asyxml><property type="pair" signature="O, i, j"><code></asyxml>*/
+ restricted pair O=(0,0), i=(1,0), j=(0,1);/*<asyxml></code><documentation>Origin and units vector.</documentation></property></asyxml>*/
+ /*<asyxml><method type="void" signature="init(convert,convert,polar,dot)"><code></asyxml>*/
+ void init(convert rtd, convert dtr,
+ polar polar, dot dot)
+ {/*<asyxml></code><documentation>The default constructor of the coordinate system.</documentation></method></asyxml>*/
+ this.relativetodefault=rtd;
+ this.defaulttorelative=dtr;
+ this.polar=polar;
+ this.dot=dot;
+ this.abs=new real(pair m){return sqrt(dot(m,m));};;
+ this.O=rtd((0,0));
+ this.i=rtd((1,0))-O;
+ this.j=rtd((0,1))-O;
+ }
+}/*<asyxml></struct></asyxml>*/
+
+/*<asyxml><operator type="bool" signature="==(coordsys,coordsys)"><code></asyxml>*/
+bool operator ==(coordsys c1, coordsys c2)
+{/*<asyxml></code><documentation>Return true iff the coordinate system have the same origin and units vector.</documentation></operator></asyxml>*/
+ return c1.O == c2.O && c1.i == c2.i && c1.j == c2.j;
+}
+
+/*<asyxml><function type="coordsys" signature="cartesiansystem(pair,pair,pair)"><code></asyxml>*/
+coordsys cartesiansystem(pair O=(0,0), pair i, pair j)
+{/*<asyxml></code><documentation>Return the Cartesian coordinate system (O, i, j).</documentation></function></asyxml>*/
+ coordsys R;
+ real[][] P={{0,0},{0,0}};
+ real[][] iP;
+ P[0][0]=i.x;
+ P[0][1]=j.x;
+ P[1][0]=i.y;
+ P[1][1]=j.y;
+ iP=inverse(P);
+ real ni=abs(i);
+ real nj=abs(j);
+ real ij=angle(j)-angle(i);
+
+ pair rtd(pair m)
+ {
+ return O+(P[0][0]*m.x+P[0][1]*m.y,P[1][0]*m.x+P[1][1]*m.y);
+ }
+
+ pair dtr(pair m)
+ {
+ m-=O;
+ return (iP[0][0]*m.x+iP[0][1]*m.y,iP[1][0]*m.x+iP[1][1]*m.y);
+ }
+
+ pair polar(real r, real a)
+ {
+ real ca=sin(ij-a)/(ni*sin(ij));
+ real sa=sin(a)/(nj*sin(ij));
+ return r*(ca,sa);
+ }
+
+ real tdot(pair m, pair n)
+ {
+ return m.x*n.x*ni^2+m.y*n.y*nj^2+(m.x*n.y+n.x*m.y)*dot(i,j);
+ }
+
+ R.init(rtd,dtr,polar,tdot);
+ return R;
+}
+
+
+/*<asyxml><function type="void" signature="show(picture,Label,Label,Label,coordsys,pen,pen,pen,pen,pen)"><code></asyxml>*/
+void show(picture pic=currentpicture, Label lo="$O$",
+ Label li="$\vec{\imath}$",
+ Label lj="$\vec{\jmath}$",
+ coordsys R,
+ pen dotpen=currentpen, pen xpen=currentpen, pen ypen=xpen,
+ pen ipen=red,
+ pen jpen=ipen,
+ arrowbar arrow=Arrow)
+{/*<asyxml></code><documentation>Draw the components (O, i, j, x-axis, y-axis) of 'R'.</documentation></function></asyxml>*/
+ unravel R;
+ dot(pic,O,dotpen);
+ drawline(pic,O,O+i,xpen);
+ drawline(pic,O,O+j,ypen);
+ draw(pic,li,O--(O+i),ipen,arrow);
+ Label lj=lj.copy();
+ lj.align(lj.align,unit(I*j));
+ draw(pic,lj,O--(O+j),jpen,arrow);
+ draw(pic,lj,O--(O+j),jpen,arrow);
+ Label lo=lo.copy();
+ lo.align(lo.align,-2*dir(O--O+i,O--O+j));
+ lo.p(dotpen);
+ label(pic,lo,O);
+}
+
+/*<asyxml><operator type="pair" signature="/(pair,coordsys)"><code></asyxml>*/
+pair operator /(pair p, coordsys R)
+{/*<asyxml></code><documentation>Return the xy-coordinates of 'p' relatively to
+ the coordinate system 'R'.
+ For example, if R=cartesiansystem((1,2),(1,0),(0,1)), (0,0)/R is (-1,-2).</documentation></operator></asyxml>*/
+ return R.defaulttorelative(p);
+}
+
+/*<asyxml><operator type="pair" signature="*(coordsys,pair)"><code></asyxml>*/
+pair operator *(coordsys R, pair p)
+{/*<asyxml></code><documentation>Return the coordinates of 'p' given in the
+ xy-coordinates 'R'.
+ For example, if R=cartesiansystem((1,2),(1,0),(0,1)), R*(0,0) is (1,2).</documentation></operator></asyxml>*/
+ return R.relativetodefault(p);
+}
+
+/*<asyxml><operator type="path" signature="*(coordsys,path)"><code></asyxml>*/
+path operator *(coordsys R, path g)
+{/*<asyxml></code><documentation>Return the reconstructed path applying R*pair to each node, pre and post control point of 'g'.</documentation></operator></asyxml>*/
+ guide og=point(g,0);
+ real l=length(g);
+ for(int i=1; i <= l; ++i)
+ {
+ pair P=R*point(g,i);
+ pair post=R*postcontrol(g,i-1);
+ pair pre=R*precontrol(g,i);
+ if(i == l && (cyclic(g)))
+ og=og..controls post and pre..cycle;
+ else
+ og=og..controls post and pre..P;
+ }
+ return og;
+}
+
+/*<asyxml><operator type="coordsys" signature="*(transform,coordsys)"><code></asyxml>*/
+coordsys operator *(transform t, coordsys R)
+{/*<asyxml></code><documentation>Provide transform*coordsys.
+ Note that shiftless(t) is applied to R.i and R.j.</documentation></operator></asyxml>*/
+ coordsys oc;
+ oc=cartesiansystem(t*R.O,shiftless(t)*R.i,shiftless(t)*R.j);
+ return oc;
+}
+
+/*<asyxml><constant type="coordsys" signature="defaultcoordsys"><code></asyxml>*/
+restricted coordsys defaultcoordsys=cartesiansystem(0,(1,0),(0,1));/*<asyxml></code><documentation>One can always refer to the default coordinate system using this constant.</documentation></constant></asyxml>*/
+/*<asyxml><variable type="coordsys" signature="currentcoordsys"><code></asyxml>*/
+coordsys currentcoordsys=defaultcoordsys;/*<asyxml></code><documentation>The coordinate system used by default.</documentation></variable></asyxml>*/
+
+/*<asyxml><struct signature="point"><code></asyxml>*/
+struct point
+{/*<asyxml></code><documentation>This structure replaces the pair to embed its coordinate system.
+ For example, if 'P=point(cartesiansystem((1,2),i,j), (0,0))',
+ P is equal to the pair (1,2).</documentation></asyxml>*/
+ /*<asyxml><property type="coordsys" signature="coordsys"><code></asyxml>*/
+ coordsys coordsys;/*<asyxml></code><documentation>The coordinate system of this point.</documentation></property><property type="pair" signature="coordinates"><code></asyxml>*/
+ restricted pair coordinates;/*<asyxml></code><documentation>The coordinates of this point relatively to the coordinate system 'coordsys'.</documentation></property><property type="real" signature="x,y"><code></asyxml>*/
+ restricted real x, y;/*<asyxml></code><documentation>The xpart and the ypart of 'coordinates'.</documentation></property></asyxml>*/
+ /*<asyxml><method type="" signature="init(coordsys,pair)"><code><property type="real" signature="m"><code></asyxml>*/
+ real m=1;/*<asyxml></code><documentation>Used to cast mass<->point.</documentation></property></asyxml>*/
+ void init(coordsys R, pair coordinates, real mass)
+ {/*<asyxml></code><documentation>The constructor.</documentation></method></asyxml>*/
+ this.coordsys=R;
+ this.coordinates=coordinates;
+ this.x=coordinates.x;
+ this.y=coordinates.y;
+ this.m=mass;
+ }
+}/*<asyxml></struct></asyxml>*/
+
+/*<asyxml><function type="point" signature="point(coordsys,pair,real)"><code></asyxml>*/
+point point(coordsys R, pair p, real m=1)
+{/*<asyxml></code><documentation>Return the point which has the coodinates 'p' in the
+ coordinate system 'R' and the mass 'm'.</documentation></function></asyxml>*/
+ point op;
+ op.init(R, p, m);
+ return op;
+}
+
+/*<asyxml><function type="point" signature="point(explicit pair,real)"><code></asyxml>*/
+point point(explicit pair p, real m)
+{/*<asyxml></code><documentation>Return the point which has the coodinates 'p' in the current
+ coordinate system and the mass 'm'.</documentation></function></asyxml>*/
+ point op;
+ op.init(currentcoordsys, p, m);
+ return op;
+}
+point point(explicit pair p, int m)
+{// Handle ambiguity
+ return point(p,(real)m);
+}
+
+/*<asyxml><function type="point" signature="point(coordsys,explicit point,real)"><code></asyxml>*/
+point point(coordsys R, explicit point M, real m=M.m)
+{/*<asyxml></code><documentation>Return the point of 'R' which has the coordinates of 'M' and the mass 'm'.
+ Do not confuse this routine with the further routine 'changecoordsys'.</documentation></function></asyxml>*/
+ point op;
+ op.init(R, M.coordinates, M.m);
+ return op;
+}
+
+/*<asyxml><function type="point" signature="changecoordsys(coordsys,point)"><code></asyxml>*/
+point changecoordsys(coordsys R, point M)
+{/*<asyxml></code><documentation>Return the point 'M' in the coordinate system 'coordsys'.
+ In other words, the returned point marks the same plot as 'M' does.</documentation></function></asyxml>*/
+ point op;
+ coordsys mco=M.coordsys;
+ op.init(R, R.defaulttorelative(mco.relativetodefault(M.coordinates)), M.m);
+ return op;
+}
+
+/*<asyxml><function type="pair" signature="pair coordinates(point)"><code></asyxml>*/
+pair coordinates(point M)
+{/*<asyxml></code><documentation>Return the coordinates of 'M' in its coordinate system.</documentation></function></asyxml>*/
+ return M.coordinates;
+}
+
+/*<asyxml><function type="bool" signature="bool samecoordsys(bool...point[])"><code></asyxml>*/
+bool samecoordsys(bool warn=true ... point[] M)
+{/*<asyxml></code><documentation>Return true iff all the points have the same coordinate system.
+ If 'warn' is true and the coordinate systems are different, a warning is sent.</documentation></function></asyxml>*/
+ bool ret=true;
+ coordsys t=M[0].coordsys;
+ for (int i=1; i < M.length; ++i) {
+ ret=(t == M[i].coordsys);
+ if(!ret) break;
+ t=M[i].coordsys;
+ }
+ if(warn && !ret)
+ write("Warning, the coordinate system of two objects are not the same.
+The operation will be done relatively to the default coordinate system.");
+ return ret;
+}
+
+/*<asyxml><function type="point[]" signature="standardizecoordsys(coordsys,bool...point[])"><code></asyxml>*/
+point[] standardizecoordsys(coordsys R=currentcoordsys,
+ bool warn=true ... point[] M)
+{/*<asyxml></code><documentation>Return the points with the same coordinate system 'R'.
+ If 'warn' is true and the coordinate systems are different, a warning is sent.</documentation></function></asyxml>*/
+ point[] op=new point[];
+ op=M;
+ if(!samecoordsys(warn ... M))
+ for (int i=1; i < M.length; ++i)
+ op[i]=changecoordsys(R,M[i]);
+ return op;
+}
+
+/*<asyxml><operator type="pair" signature="cast(point)"><code></asyxml>*/
+pair operator cast(point P)
+{/*<asyxml></code><documentation>Cast point to pair.</documentation></operator></asyxml>*/
+ return P.coordsys.relativetodefault(P.coordinates);
+}
+
+/*<asyxml><operator type="pair[]" signature="cast(point[])"><code></asyxml>*/
+pair[] operator cast(point[] P)
+{/*<asyxml></code><documentation>Cast point[] to pair[].</documentation></operator></asyxml>*/
+ pair[] op;
+ for (int i=0; i<P.length; ++i) {
+ op.push((pair)P[i]);
+ }
+ return op;
+}
+
+/*<asyxml><operator type="point" signature="cast(pair)"><code></asyxml>*/
+point operator cast(pair p)
+{/*<asyxml></code><documentation>Cast pair to point relatively to the current coordinate
+ system 'currentcoordsys'.</documentation></operator></asyxml>*/
+ return point(currentcoordsys,p);
+}
+
+/*<asyxml><operator type="point[]" signature="cast(pair[])"><code></asyxml>*/
+point[] operator cast(pair[] p)
+{/*<asyxml></code><documentation>Cast pair[] to point[] relatively to the current coordinate
+ system 'currentcoordsys'.</documentation></operator></asyxml>*/
+ pair[] op;
+ for (int i=0; i<p.length; ++i) {
+ op.push((point)p[i]);
+ }
+ return op;
+}
+
+/*<asyxml><function type="pair" signature="locate(point)"><code></asyxml>*/
+pair locate(point P)
+{/*<asyxml></code><documentation>Return the coordinates of 'P' in the default coordinate system.</documentation></function></asyxml>*/
+ return P.coordsys*P.coordinates;
+}
+
+/*<asyxml><function type="point" signature="locate(pair)"><code></asyxml>*/
+point locate(pair p)
+{/*<asyxml></code><documentation>Return the point in the current coordinate system 'currentcoordsys'.</documentation></function></asyxml>*/
+ return p; //automatic casting 'pair to point'.
+}
+
+/*<asyxml><operator type="point" signature="*(real, explicit point)"><code></asyxml>*/
+point operator *(real x, explicit point P)
+{/*<asyxml></code><documentation>Multiply the coordinates (not the mass) of 'P' by 'x'.</documentation></operator></asyxml>*/
+ return point(P.coordsys,x*P.coordinates,P.m);
+}
+
+/*<asyxml><operator type="point" signature="/(explicit point, real)"><code></asyxml>*/
+point operator /(explicit point P, real x)
+{/*<asyxml></code><documentation>Divide the coordinates (not the mass) of 'P' by 'x'.</documentation></operator></asyxml>*/
+ return point(P.coordsys,P.coordinates/x,P.m);
+}
+
+/*<asyxml><operator type="point" signature="/(real,explicit point)"><code></asyxml>*/
+point operator /(real x, explicit point P)
+{/*<asyxml></code><documentation></documentation></operator></asyxml>*/
+ return point(P.coordsys,x/P.coordinates,P.m);
+}
+
+/*<asyxml><operator type="point" signature="-(explicit point)"><code></asyxml>*/
+point operator -(explicit point P)
+{/*<asyxml></code><documentation>-P. The mass is inchanged.</documentation></operator></asyxml>*/
+ return point(P.coordsys,-P.coordinates, P.m);
+}
+
+/*<asyxml><operator type="point" signature="+(explicit point,explicit point)"><code></asyxml>*/
+point operator +(explicit point P1, explicit point P2)
+{/*<asyxml></code><documentation>Provide 'point+point'.
+ If the two points haven't the same coordinate system, a warning is sent and the
+ returned point has the default coordinate system 'defaultcoordsys'.
+ The masses are added.</documentation></operator></asyxml>*/
+ point[] P=standardizecoordsys(P1,P2);
+ coordsys R=P[0].coordsys;
+ return point(R,P[0].coordinates+P[1].coordinates, P1.m+P2.m);
+}
+
+/*<asyxml><operator type="point" signature="+(explicit point,explicit pair)"><code></asyxml>*/
+point operator +(explicit point P1, explicit pair p2)
+{/*<asyxml></code><documentation>Provide 'point+pair'.
+ The pair 'p2' is supposed to be coordinates relatively to the coordinates system of 'P1'.
+ The mass is not changed.</documentation></operator></asyxml>*/
+ coordsys R=currentcoordsys;
+ return point(R,P1.coordinates+point(R,p2).coordinates, P1.m);
+}
+point operator +(explicit pair p1, explicit point p2)
+{
+ return p2+p1;
+}
+
+/*<asyxml><operator type="point" signature="-(explicit point,explicit point)"><code></asyxml>*/
+point operator -(explicit point P1, explicit point P2)
+{/*<asyxml></code><documentation>Provide 'point-point'.</documentation></operator></asyxml>*/
+ return P1+(-P2);
+}
+
+/*<asyxml><operator type="point" signature="-(explicit point,explicit pair)"><code></asyxml>*/
+point operator -(explicit point P1, explicit pair p2)
+{/*<asyxml></code><documentation>Provide 'point-pair'.
+ The pair 'p2' is supposed to be coordinates relatively to the coordinates system of 'P1'.</documentation></operator></asyxml>*/
+ return P1+(-p2);
+}
+point operator -(explicit pair p1, explicit point P2)
+{
+ return p1+(-P2);
+}
+
+/*<asyxml><operator type="point" signature="*(transform,explicit point)"><code></asyxml>*/
+point operator *(transform t, explicit point P)
+{/*<asyxml></code><documentation>Provide 'transform*point'.
+ Note that the transforms scale, xscale, yscale and rotate are carried out relatively
+ the default coordinate system 'defaultcoordsys' which is not desired for point
+ defined in an other coordinate system.
+ On can use scale(real,point), xscale(real,point), yscale(real,point), rotate(real,point),
+ scaleO(real), xscaleO(real), yscaleO(real) and rotateO(real) (described further)
+ to change the coordinate system of reference.</documentation></operator></asyxml>*/
+ coordsys R=P.coordsys;
+ return point(R,(t*locate(P))/R, P.m);
+}
+
+/*<asyxml><operator type="point" signature="*(explicit point,explicit point)"><code></asyxml>*/
+point operator *(explicit point P1, explicit point P2)
+{/*<asyxml></code><documentation>Provide 'point*point'.
+ The resulted mass is the mass of P2</documentation></operator></asyxml>*/
+ point[] P=standardizecoordsys(P1,P2);
+ coordsys R=P[0].coordsys;
+ return point(R,P[0].coordinates*P[1].coordinates, P2.m);
+}
+
+/*<asyxml><operator type="point" signature="*(explicit point,explicit pair)"><code></asyxml>*/
+point operator *(explicit point P1, explicit pair p2)
+{/*<asyxml></code><documentation>Provide 'point*pair'.
+ The pair 'p2' is supposed to be the coordinates of
+ the point in the coordinates system of 'P1'.
+ 'pair*point' is also defined.</documentation></operator></asyxml>*/
+ point P=point(P1.coordsys,p2, P1.m);
+ return P1*P;
+}
+point operator *(explicit pair p1, explicit point p2)
+{
+ return p2*p1;
+}
+
+/*<asyxml><operator type="bool" signature="==(explicit point, explicit point)"><code></asyxml>*/
+bool operator ==(explicit point M, explicit point N)
+{/*<asyxml></code><documentation>Provide the test 'M == N' wish returns true iff MN < EPS</documentation></operator></asyxml>*/
+ return abs(locate(M)-locate(N)) < EPS;
+}
+
+/*<asyxml><operator type="bool" signature="!=(explicit point, explicit point)"><code></asyxml>*/
+bool operator !=(explicit point M, explicit point N)
+{/*<asyxml></code><documentation>Provide the test 'M != N' wish return true iff MN >= EPS</documentation></operator></asyxml>*/
+ return !(M == N);
+}
+
+/*<asyxml><operator type="guide" signature="cast(point)"><code></asyxml>*/
+guide operator cast(point p)
+{/*<asyxml></code><documentation>Cast point to guide.</documentation></operator></asyxml>*/
+ return locate(p);
+}
+
+/*<asyxml><operator type="path" signature="cast(point)"><code></asyxml>*/
+path operator cast(point p)
+{/*<asyxml></code><documentation>Cast point to path.</documentation></operator></asyxml>*/
+ return locate(p);
+}
+
+/*<asyxml><function type="void" signature="dot(picture,Label,explicit point,align,string,pen)"><code></asyxml>*/
+void dot(picture pic=currentpicture, Label L, explicit point Z,
+ align align=NoAlign,
+ string format=defaultformat, pen p=currentpen)
+{/*<asyxml></code><documentation></documentation></function></asyxml>*/
+ Label L=L.copy();
+ L.position(locate(Z));
+ if(L.s == "") {
+ if(format == "") format=defaultformat;
+ L.s="("+format(format,Z.x)+","+format(format,Z.y)+")";
+ }
+ L.align(align,E);
+ L.p(p);
+ dot(pic,locate(Z),p);
+ add(pic,L);
+}
+
+/*<asyxml><function type="real" signature="abs(coordsys,pair)"><code></asyxml>*/
+real abs(coordsys R, pair m)
+{/*<asyxml></code><documentation>Return the modulus |m| in the coordinate system 'R'.</documentation></function></asyxml>*/
+ return R.abs(m);
+}
+
+/*<asyxml><function type="real" signature="abs(explicit point)"><code></asyxml>*/
+real abs(explicit point M)
+{/*<asyxml></code><documentation>Return the modulus |M| in its coordinate system.</documentation></function></asyxml>*/
+ return M.coordsys.abs(M.coordinates);
+}
+
+/*<asyxml><function type="real" signature="length(explicit point)"><code></asyxml>*/
+real length(explicit point M)
+{/*<asyxml></code><documentation>Return the modulus |M| in its coordinate system (same as 'abs').</documentation></function></asyxml>*/
+ return M.coordsys.abs(M.coordinates);
+}
+
+/*<asyxml><function type="point" signature="conj(explicit point)"><code></asyxml>*/
+point conj(explicit point M)
+{/*<asyxml></code><documentation>Conjugate.</documentation></function></asyxml>*/
+ return point(M.coordsys,conj(M.coordinates), M.m);
+}
+
+/*<asyxml><function type="real" signature="degrees(explicit point,coordsys,bool)"><code></asyxml>*/
+real degrees(explicit point M, coordsys R=M.coordsys, bool warn=true)
+{/*<asyxml></code><documentation>Return the angle of M (in degrees) relatively to 'R'.</documentation></function></asyxml>*/
+ return (degrees(locate(M)-R.O, warn) - degrees(R.i))%360;
+}
+
+/*<asyxml><function type="real" signature="angle(explicit point,coordsys,bool)"><code></asyxml>*/
+real angle(explicit point M, coordsys R=M.coordsys, bool warn=true)
+{/*<asyxml></code><documentation>Return the angle of M (in radians) relatively to 'R'.</documentation></function></asyxml>*/
+ return radians(degrees(M,R,warn));
+}
+
+/*<asyxml><function type="bool" signature="finite(explicit point)"><code></asyxml>*/
+bool finite(explicit point p)
+{/*<asyxml></code><documentation>Avoid to compute 'finite((pair)(infinite_point))'.</documentation></function></asyxml>*/
+ return finite(p.coordinates);
+}
+
+/*<asyxml><function type="real" signature="dot(point,point)"><code></asyxml>*/
+real dot(point A, point B)
+{/*<asyxml></code><documentation>Return the dot product in the coordinate system of 'A'.</documentation></function></asyxml>*/
+ point[] P=standardizecoordsys(A.coordsys,A,B);
+ return P[0].coordsys.dot(P[0].coordinates,P[1].coordinates);
+}
+
+/*<asyxml><function type="real" signature="dot(point,explicit pair)"><code></asyxml>*/
+real dot(point A, explicit pair B)
+{/*<asyxml></code><documentation>Return the dot product in the default coordinate system.
+ dot(explicit pair,point) is also defined.</documentation></function></asyxml>*/
+ return dot(locate(A),B);
+}
+real dot(explicit pair A, point B)
+{
+ return dot(A,locate(B));
+}
+
+/*<asyxml><function type="transforms" signature="rotateO(real)"><code></asyxml>*/
+transform rotateO(real a)
+{/*<asyxml></code><documentation>Rotation around the origin of the current coordinate system.</documentation></function></asyxml>*/
+ return rotate(a,currentcoordsys.O);
+};
+
+/*<asyxml><function type="transform" signature="projection(point,point)"><code></asyxml>*/
+transform projection(point A, point B)
+{/*<asyxml></code><documentation>Return the orthogonal projection on the line (AB).</documentation></function></asyxml>*/
+ pair dir=unit(locate(A)-locate(B));
+ pair a=locate(A);
+ real cof=dir.x*a.x+dir.y*a.y;
+ real tx=a.x-dir.x*cof;
+ real txx=dir.x^2;
+ real txy=dir.x*dir.y;
+ real ty=a.y-dir.y*cof;
+ real tyx=txy;
+ real tyy=dir.y^2;
+ transform t=(tx,ty,txx,txy,tyx,tyy);
+ return t;
+}
+
+/*<asyxml><function type="transform" signature="projection(point,point,point,point,bool)"><code></asyxml>*/
+transform projection(point A, point B, point C, point D, bool safe=false)
+{/*<asyxml></code><documentation>Return the (CD) parallel projection on (AB).
+ If 'safe=true' and (AB)//(CD) return the identity.
+ If 'safe=false' and (AB)//(CD) return an infinity scaling.</documentation></function></asyxml>*/
+ pair a=locate(A);
+ pair u=unit(locate(B)-locate(A));
+ pair v=unit(locate(D)-locate(C));
+ real c=u.x*a.y-u.y*a.x;
+ real d=(conj(u)*v).y;
+ if (abs(d) < epsgeo) {
+ return safe ? identity() : scale(infinity);
+ }
+ real tx=c*v.x/d;
+ real ty=c*v.y/d;
+ real txx=u.x*v.y/d;
+ real txy=-u.x*v.x/d;
+ real tyx=u.y*v.y/d;
+ real tyy=-u.y*v.x/d;
+ transform t=(tx,ty,txx,txy,tyx,tyy);
+ return t;
+}
+
+/*<asyxml><function type="transform" signature="scale(real,point)"><code></asyxml>*/
+transform scale(real k, point M)
+{/*<asyxml></code><documentation>Homothety.</documentation></function></asyxml>*/
+ pair P=locate(M);
+ return shift(P)*scale(k)*shift(-P);
+}
+
+/*<asyxml><function type="transform" signature="xscale(real,point)"><code></asyxml>*/
+transform xscale(real k, point M)
+{/*<asyxml></code><documentation>xscale from 'M' relatively to the x-axis of the coordinate system of 'M'.</documentation></function></asyxml>*/
+ pair P=locate(M);
+ real a=degrees(M.coordsys.i);
+ return (shift(P)*rotate(a))*xscale(k)*(rotate(-a)*shift(-P));
+}
+
+/*<asyxml><function type="transform" signature="yscale(real,point)"><code></asyxml>*/
+transform yscale(real k, point M)
+{/*<asyxml></code><documentation>yscale from 'M' relatively to the y-axis of the coordinate system of 'M'.</documentation></function></asyxml>*/
+ pair P=locate(M);
+ real a=degrees(M.coordsys.j)-90;
+ return (shift(P)*rotate(a))*yscale(k)*(rotate(-a)*shift(-P));
+}
+
+/*<asyxml><function type="transform" signature="scale(real,point,point,point,point,bool)"><code></asyxml>*/
+transform scale(real k, point A, point B, point C, point D, bool safe=false)
+{/*<asyxml></code><documentation><url href="http://fr.wikipedia.org/wiki/Affinit%C3%A9_%28math%C3%A9matiques%29"/>
+ (help me for English translation...)
+ If 'safe=true' and (AB)//(CD) return the identity.
+ If 'safe=false' and (AB)//(CD) return a infinity scaling.</documentation></function></asyxml>*/
+ pair a=locate(A);
+ pair u=unit(locate(B)-locate(A));
+ pair v=unit(locate(D)-locate(C));
+ real c=u.x*a.y-u.y*a.x;
+ real d=(conj(u)*v).y;
+ real d=(conj(u)*v).y;
+ if (abs(d) < epsgeo) {
+ return safe ? identity() : scale(infinity);
+ }
+ real tx=(1-k)*c*v.x/d;
+ real ty=(1-k)*c*v.y/d;
+ real txx=(1-k)*u.x*v.y/d+k;
+ real txy=(k-1)*u.x*v.x/d;
+ real tyx=(1-k)*u.y*v.y/d;
+ real tyy=(k-1)*u.y*v.x/d+k;
+ transform t=(tx,ty,txx,txy,tyx,tyy);
+ return t;
+}
+
+/*<asyxml><function type="transform" signature="scaleO(real)"><code></asyxml>*/
+transform scaleO(real x)
+{/*<asyxml></code><documentation>Homothety from the origin of the current coordinate system.</documentation></function></asyxml>*/
+ return scale(x,(0,0));
+}
+
+/*<asyxml><function type="transform" signature="xscaleO(real)"><code></asyxml>*/
+transform xscaleO(real x)
+{/*<asyxml></code><documentation>xscale from the origin and relatively to the current coordinate system.</documentation></function></asyxml>*/
+ return scale(x,(0,0),(0,1),(0,0),(1,0));
+}
+
+/*<asyxml><function type="transform" signature="yscaleO(real)"><code></asyxml>*/
+transform yscaleO(real x)
+{/*<asyxml></code><documentation>yscale from the origin and relatively to the current coordinate system.</documentation></function></asyxml>*/
+ return scale(x,(0,0),(1,0),(0,0),(0,1));
+}
+
+/*<asyxml><struct signature="vector"><code></asyxml>*/
+struct vector
+{/*<asyxml></code><documentation>Like a point but casting to pair, adding etc does not take account
+ of the origin of the coordinate system.</documentation><property type="point" signature="v"><code></asyxml>*/
+ point v;/*<asyxml></code><documentation>Coordinates as a point (embed coordinate system and pair).</documentation></property></asyxml>*/
+}/*<asyxml></struct></asyxml>*/
+
+/*<asyxml><operator type="point" signature="cast(vector)"><code></asyxml>*/
+point operator cast(vector v)
+{/*<asyxml></code><documentation>Cast vector 'v' to point 'M' so that OM=v.</documentation></operator></asyxml>*/
+ return v.v;
+}
+
+/*<asyxml><operator type="vector" signature="cast(pair)"><code></asyxml>*/
+vector operator cast(pair v)
+{/*<asyxml></code><documentation>Cast pair to vector relatively to the current coordinate
+ system 'currentcoordsys'.</documentation></operator></asyxml>*/
+ vector ov;
+ ov.v=point(currentcoordsys,v);
+ return ov;
+}
+
+/*<asyxml><operator type="vector" signature="cast(explicit point)"><code></asyxml>*/
+vector operator cast(explicit point v)
+{/*<asyxml></code><documentation>A point can be interpreted like a vector using the code
+ '(vector)a_point'.</documentation></operator></asyxml>*/
+ vector ov;
+ ov.v=v;
+ return ov;
+}
+
+/*<asyxml><operator type="pair" signature="cast(explicit vector)"><code></asyxml>*/
+pair operator cast(explicit vector v)
+{/*<asyxml></code><documentation>Cast vector to pair (the coordinates of 'v' in the default coordinate system).</documentation></operator></asyxml>*/
+ return locate(v.v)-v.v.coordsys.O;
+}
+
+/*<asyxml><operator type="align" signature="cast(vector)"><code></asyxml>*/
+align operator cast(vector v)
+{/*<asyxml></code><documentation>Cast vector to align.</documentation></operator></asyxml>*/
+ return (pair)v;
+}
+
+/*<asyxml><function type="vector" signature="vector(coordsys,pair)"><code></asyxml>*/
+vector vector(coordsys R=currentcoordsys, pair v)
+{/*<asyxml></code><documentation>Return the vector of 'R' which has the coordinates 'v'.</documentation></function></asyxml>*/
+ vector ov;
+ ov.v=point(R,v);
+ return ov;
+}
+
+/*<asyxml><function type="vector" signature="vector(point)"><code></asyxml>*/
+vector vector(point M)
+{/*<asyxml></code><documentation>Return the vector OM, where O is the origin of the coordinate system of 'M'.
+ Useful to write 'vector(P-M);' instead of '(vector)(P-M)'.</documentation></function></asyxml>*/
+ return M;
+}
+
+/*<asyxml><function type="point" signature="point(explicit vector)"><code></asyxml>*/
+point point(explicit vector u)
+{/*<asyxml></code><documentation>Return the point M so that OM=u, where O is the origin of the coordinate system of 'u'.</documentation></function></asyxml>*/
+ return u.v;
+}
+
+/*<asyxml><function type="pair" signature="locate(explicit vector)"><code></asyxml>*/
+pair locate(explicit vector v)
+{/*<asyxml></code><documentation>Return the coordinates of 'v' in the default coordinate system (like casting vector to pair).</documentation></function></asyxml>*/
+ return (pair)v;
+}
+
+/*<asyxml><function type="void" signature="show(Label,pen,arrowbar)"><code></asyxml>*/
+void show(Label L, vector v, pen p=currentpen, arrowbar arrow=Arrow)
+{/*<asyxml></code><documentation>Draw the vector v (from the origin of its coordinate system).</documentation></function></asyxml>*/
+ coordsys R=v.v.coordsys;
+ draw(L, R.O--v.v, p, arrow);
+}
+
+/*<asyxml><function type="vector" signature="changecoordsys(coordsys,vector)"><code></asyxml>*/
+vector changecoordsys(coordsys R, vector v)
+{/*<asyxml></code><documentation>Return the vector 'v' relatively to coordinate system 'R'.</documentation></function></asyxml>*/
+ vector ov;
+ ov.v=point(R,(locate(v)+R.O)/R);
+ return ov;
+}
+
+/*<asyxml><operator type="vector" signature="*(real,explicit vector)"><code></asyxml>*/
+vector operator *(real x, explicit vector v)
+{/*<asyxml></code><documentation>Provide real*vector.</documentation></operator></asyxml>*/
+ return x*v.v;
+}
+
+/*<asyxml><operator type="vector" signature="/(explicit vector,real)"><code></asyxml>*/
+vector operator /(explicit vector v, real x)
+{/*<asyxml></code><documentation>Provide vector/real</documentation></operator></asyxml>*/
+ return v.v/x;
+}
+
+/*<asyxml><operator type="vector" signature="*(transform t,explicit vector)"><code></asyxml>*/
+vector operator *(transform t, explicit vector v)
+{/*<asyxml></code><documentation>Provide transform*vector.</documentation></operator></asyxml>*/
+ return t*v.v;
+}
+
+/*<asyxml><operator type="vector" signature="*(explicit point,explicit vector)"><code></asyxml>*/
+vector operator *(explicit point M, explicit vector v)
+{/*<asyxml></code><documentation>Provide point*vector</documentation></operator></asyxml>*/
+ return M*v.v;
+}
+
+/*<asyxml><operator type="point" signature="+(explicit point,explicit vector)"><code></asyxml>*/
+point operator +(point M, explicit vector v)
+{/*<asyxml></code><documentation>Return 'M' shifted by 'v'.</documentation></operator></asyxml>*/
+ return shift(locate(v))*M;
+}
+
+/*<asyxml><operator type="point" signature="-(explicit point, explicit vector)"><code></asyxml>*/
+point operator -(point M, explicit vector v)
+{/*<asyxml></code><documentation>Return 'M' shifted by '-v'.</documentation></operator></asyxml>*/
+ return shift(-locate(v))*M;
+}
+
+/*<asyxml><operator type="vector" signature="-(explicit vector)"><code></asyxml>*/
+vector operator -(explicit vector v)
+{/*<asyxml></code><documentation>Provide -v.</documentation></operator></asyxml>*/
+ return -v.v;
+}
+
+/*<asyxml><operator type="point" signature="+(explicit pair,explicit vector)"><code></asyxml>*/
+point operator +(explicit pair m, explicit vector v)
+{/*<asyxml></code><documentation>The pair 'm' is supposed to be the coordinates of
+ a point in the current coordinates system 'currentcoordsys'.
+ Return this point shifted by the vector 'v'.</documentation></operator></asyxml>*/
+ return locate(m)+v;
+}
+
+/*<asyxml><operator type="point" signature="-(explicit pair,explicit vector)"><code></asyxml>*/
+point operator -(explicit pair m, explicit vector v)
+{/*<asyxml></code><documentation>The pair 'm' is supposed to be the coordinates of
+ a point in the current coordinates system 'currentcoordsys'.
+ Return this point shifted by the vector '-v'.</documentation></operator></asyxml>*/
+ return m+(-v);
+}
+
+/*<asyxml><operator type="vector" signature="+(explicit vector, explicit vector)"><code></asyxml>*/
+vector operator +(explicit vector v1, explicit vector v2)
+{/*<asyxml></code><documentation>Provide vector+vector.
+ If the two vector haven't the same coordinate system, the returned
+ vector is relative to the default coordinate system (without warning).</documentation></operator></asyxml>*/
+ coordsys R=v1.v.coordsys;
+ if(samecoordsys(false,v1,v2)){R=defaultcoordsys;}
+ return vector(R,(locate(v1)+locate(v2))/R);
+}
+
+/*<asyxml><operator type="vector" signature="-(explicit vector, explicit vector)"><code></asyxml>*/
+vector operator -(explicit vector v1, explicit vector v2)
+{/*<asyxml></code><documentation>Provide vector-vector.
+ If the two vector haven't the same coordinate system, the returned
+ vector is relative to the default coordinate system (without warning).</documentation></operator></asyxml>*/
+ return v1+(-v2);
+}
+
+/*<asyxml><operator type="bool" signature="==(explicit vector, explicit vector)"><code></asyxml>*/
+bool operator ==(explicit vector u, explicit vector v)
+{/*<asyxml></code><documentation>Return true iff |u-v|<EPS.</documentation></operator></asyxml>*/
+ return abs(u-v) < EPS;
+}
+
+/*<asyxml><function type="bool" signature="collinear(vector,vector)"><code></asyxml>*/
+bool collinear(vector u, vector v)
+{/*<asyxml></code><documentation>Return 'true' iff the vectors 'u' and 'v' are collinear.</documentation></function></asyxml>*/
+ return abs(ypart((conj((pair)u)*(pair)v))) < EPS;
+}
+
+/*<asyxml><function type="vector" signature="unit(point)"><code></asyxml>*/
+vector unit(point M)
+{/*<asyxml></code><documentation>Return the unit vector according to the modulus of its coordinate system.</documentation></function></asyxml>*/
+ return M/abs(M);
+}
+
+/*<asyxml><function type="vector" signature="unit(vector)"><code></asyxml>*/
+vector unit(vector u)
+{/*<asyxml></code><documentation>Return the unit vector according to the modulus of its coordinate system.</documentation></function></asyxml>*/
+ return u.v/abs(u.v);
+}
+
+/*<asyxml><function type="real" signature="degrees(vector,coordsys,bool)"><code></asyxml>*/
+real degrees(vector v,
+ coordsys R=v.v.coordsys,
+ bool warn=true)
+{/*<asyxml></code><documentation>Return the angle of 'v' (in degrees) relatively to 'R'.</documentation></function></asyxml>*/
+ return (degrees(locate(v),warn)-degrees(R.i))%360;
+}
+
+/*<asyxml><function type="real" signature="angle(vector,coordsys,bool)"><code></asyxml>*/
+real angle(explicit vector v,
+ coordsys R=v.v.coordsys,
+ bool warn=true)
+{/*<asyxml></code><documentation>Return the angle of 'v' (in radians) relatively to 'R'.</documentation></function></asyxml>*/
+ return radians(degrees(v,R,warn));
+}
+
+/*<asyxml><function type="vector" signature="conj(explicit vector)"><code></asyxml>*/
+vector conj(explicit vector u)
+{/*<asyxml></code><documentation>Conjugate.</documentation></function></asyxml>*/
+ return conj(u.v);
+}
+
+/*<asyxml><function type="transform" signature="rotate(explicit vector)"><code></asyxml>*/
+transform rotate(explicit vector dir)
+{/*<asyxml></code><documentation>A rotation in the direction 'dir' limited to [-90,90]
+This is useful for rotating text along a line in the direction dir.
+rotate(explicit point dir) is also defined.
+</documentation></function></asyxml>*/
+ return rotate(locate(dir));
+}
+transform rotate(explicit point dir){return rotate(locate(vector(dir)));}
+// *......................COORDINATES......................*
+// *=======================================================*
+
+// *=======================================================*
+// *.........................BASES.........................*
+/*<asyxml><variable type="point" signature="origin"><code></asyxml>*/
+point origin=point(defaultcoordsys,(0,0));/*<asyxml></code><documentation>The origin of the current coordinate system.</documentation></variable></asyxml>*/
+
+/*<asyxml><function type="point" signature="origin(coordsys)"><code></asyxml>*/
+point origin(coordsys R=currentcoordsys)
+{/*<asyxml></code><documentation>Return the origin of the coordinate system 'R'.</documentation></function></asyxml>*/
+ return point(R,(0,0)); //use automatic casting;
+}
+
+/*<asyxml><variable type="real" signature="linemargin"><code></asyxml>*/
+real linemargin=0;/*<asyxml></code><documentation>Margin used to draw lines.</documentation></variable></asyxml>*/
+/*<asyxml><function type="real" signature="linemargin()"><code></asyxml>*/
+real linemargin()
+{/*<asyxml></code><documentation>Return the margin used to draw lines.</documentation></function></asyxml>*/
+ return linemargin;
+}
+
+/*<asyxml><variable type="pen" signature="addpenline"><code></asyxml>*/
+pen addpenline=squarecap;/*<asyxml></code><documentation>Add this property to the drawing pen of "finish" lines.</documentation></variable></asyxml>*/
+pen addpenline(pen p) {
+ return addpenline+p;
+}
+
+/*<asyxml><variable type="pen" signature="addpenarc"><code></asyxml>*/
+pen addpenarc=squarecap;/*<asyxml></code><documentation>Add this property to the drawing pen of arcs.</documentation></variable></asyxml>*/
+pen addpenarc(pen p) {return addpenarc+p;}
+
+/*<asyxml><variable type="string" signature="defaultmassformat"><code></asyxml>*/
+string defaultmassformat="$\left(%L;%.4g\right)$";/*<asyxml></code><documentation>Format used to construct the default label of masses.</documentation></variable></asyxml>*/
+
+/*<asyxml><function type="int" signature="sgnd(real)"><code></asyxml>*/
+int sgnd(real x)
+{/*<asyxml></code><documentation>Return the -1 if x < 0, 1 if x >= 0.</documentation></function></asyxml>*/
+ return (x == 0) ? 1 : sgn(x);
+}
+int sgnd(int x)
+{
+ return (x == 0) ? 1 : sgn(x);
+}
+
+/*<asyxml><function type="bool" signature="defined(pair)"><code></asyxml>*/
+bool defined(point P)
+{/*<asyxml></code><documentation>Return true iff the coordinates of 'P' are finite.</documentation></function></asyxml>*/
+ return finite(P.coordinates);
+}
+
+/*<asyxml><function type="bool" signature="onpath(picture,path,point,pen)"><code></asyxml>*/
+bool onpath(picture pic=currentpicture, path g, point M, pen p=currentpen)
+{/*<asyxml></code><documentation>Return true iff 'M' is on the path drawn with the pen 'p' in 'pic'.</documentation></function></asyxml>*/
+ transform t=inverse(pic.calculateTransform());
+ return intersect(g, shift(locate(M))*scale(linewidth(p)/2)*t*unitcircle).length > 0;
+}
+
+/*<asyxml><function type="bool" signature="sameside(point,point,point)"><code></asyxml>*/
+bool sameside(point M, point N, point O)
+{/*<asyxml></code><documentation>Return 'true' iff 'M' and 'N' are same side of the point 'O'.</documentation></function></asyxml>*/
+ pair m=M, n=N, o=O;
+ return dot(m-o,n-o) >= -epsgeo;
+}
+
+/*<asyxml><function type="bool" signature="between(point,point,point)"><code></asyxml>*/
+bool between(point M, point O, point N)
+{/*<asyxml></code><documentation>Return 'true' iff 'O' is between 'M' and 'N'.</documentation></function></asyxml>*/
+ return (!sameside(N,M,O) || M == O || N == O);
+}
+
+
+typedef path pathModifier(path);
+pathModifier NoModifier=new path(path g){return g;};
+
+private void Drawline(picture pic=currentpicture, Label L="",pair P, bool dirP=true, pair Q, bool dirQ=true,
+ align align=NoAlign, pen p=currentpen,
+ arrowbar arrow=None,
+ Label legend="", marker marker=nomarker,
+ pathModifier pathModifier=NoModifier)
+{/* Add the two parameters 'dirP' and 'dirQ' to the native routine
+ 'drawline' of the module 'maths'.
+ Segment [PQ] will be prolonged in direction of P if 'dirP=true', in
+ direction of Q if 'dirQ=true'.
+ If 'dirP=dirQ=true', the behavior is that of the native 'drawline'.
+ Add all the other parameters of 'Draw'.*/
+ pic.add(new void (frame f, transform t, transform, pair m, pair M) {
+ picture opic;
+ // Reduce the bounds by the size of the pen.
+ m -= min(p)-(linemargin(),linemargin()); M -= max(p)+(linemargin(),linemargin());
+
+ // Calculate the points and direction vector in the transformed space.
+ pair z=t*P;
+ pair q=t*Q;
+ pair v=t*Q-z;
+ // path g;
+ pair ptp,ptq;
+ real cp = dirP ? 1:0;
+ real cq = dirQ ? 1:0;
+ // Handle horizontal and vertical lines.
+ if(v.x == 0) {
+ if(m.x <= z.x && z.x <= M.x)
+ if (dot(v,(z.x,m.y)) < 0) {
+ ptp=(z.x,z.y+cp*(m.y-z.y));
+ ptq=(z.x,q.y+cq*(M.y-q.y));
+ } else {
+ ptp=(z.x,q.y+cq*(m.y-q.y));
+ ptq=(z.x,z.y+cp*(M.y-z.y));
+ }
+ } else if(v.y == 0) {
+ if (dot(v,(m.x,z.y)) < 0) {
+ ptp=(z.x+cp*(m.x-z.x),z.y);
+ ptq=(q.x+cq*(M.x-q.x),z.y);
+ } else {
+ ptp=(q.x+cq*(m.x-q.x),z.y);
+ ptq=(z.x+cp*(M.x-z.x),z.y);
+ }
+ } else {
+ // Calculate the maximum and minimum t values allowed for the
+ // parametric equation z + t*v
+ real mx=(m.x-z.x)/v.x, Mx=(M.x-z.x)/v.x;
+ real my=(m.y-z.y)/v.y, My=(M.y-z.y)/v.y;
+ real tmin=max(v.x > 0 ? mx : Mx, v.y > 0 ? my : My);
+ real tmax=min(v.x > 0 ? Mx : mx, v.y > 0 ? My : my);
+ pair pmin=z+tmin*v;
+ pair pmax=z+tmax*v;
+ if(tmin <= tmax) {
+ ptp=z+cp*tmin*v;
+ ptq=z+(cq == 0 ? v:tmax*v);
+ }
+ }
+ path g=ptp--ptq;
+ if (length(g)>0)
+ {
+ if(L.s != "") {
+ Label lL=L.copy();
+ if(L.defaultposition) lL.position(Relative(.9));
+ lL.p(p);
+ lL.out(opic,g);
+ }
+ g=pathModifier(g);
+ if(linetype(p) == ""){
+ pair m=midpoint(g);
+ pen tp;
+ tp=dirP ? p : addpenline(p);
+ draw(opic,pathModifier(m--ptp),tp);
+ tp=dirQ ? p : addpenline(p);
+ draw(opic,pathModifier(m--ptq),tp);
+ } else {
+ draw(opic,g,p);
+ }
+ marker.markroutine(opic,marker.f,g);
+ arrow(opic,g,p,NoMargin);
+ add(f,opic.fit());
+ }
+ });
+}
+
+/*<asyxml><function type="void" signature="clipdraw(picture,Label,path,align,pen,arrowbar,arrowbar,real,real,Label,marker)"><code></asyxml>*/
+void clipdraw(picture pic=currentpicture, Label L="", path g,
+ align align=NoAlign, pen p=currentpen,
+ arrowbar arrow=None, arrowbar bar=None,
+ real xmargin=0, real ymargin=xmargin,
+ Label legend="", marker marker=nomarker)
+{/*<asyxml></code><documentation>Draw the path 'g' on 'pic' clipped to the bounding box of 'pic'.</documentation></function></asyxml>*/
+ if(L.s != "") {
+ picture tmp;
+ label(tmp,L,g,p);
+ add(pic,tmp);
+ }
+ pic.add(new void (frame f, transform t, transform, pair m, pair M) {
+ // Reduce the bounds by the size of the pen and the margins.
+ m += min(p)+(xmargin,ymargin); M -= max(p)+(xmargin,ymargin);
+ path bound=box(m,M);
+ picture tmp;
+ draw(tmp,"",t*g,align,p,arrow,bar,NoMargin,legend,marker);
+ clip(tmp,bound);
+ add(f,tmp.fit());
+ });
+}
+
+/*<asyxml><function type="void" signature="distance(picture pic,Label,point,point,bool,real,pen,pen,arrow)"><code></asyxml>*/
+void distance(picture pic=currentpicture, Label L="", point A, point B,
+ bool rotated=true, real offset=3mm,
+ pen p=currentpen, pen joinpen=invisible,
+ arrowbar arrow=Arrows(NoFill))
+{/*<asyxml></code><documentation>Draw arrow between A and B (from FAQ).</documentation></function></asyxml>*/
+ pair A=A, B=B;
+ path g=A--B;
+ transform Tp=shift(-offset*unit(B-A)*I);
+ pic.add(new void(frame f, transform t) {
+ picture opic;
+ path G=Tp*t*g;
+ transform id=identity();
+ transform T=rotated ? rotate(B-A) : id;
+ Label L=L.copy();
+ L.align(L.align,Center);
+ if(abs(ypart((conj(A-B)*L.align.dir))) < epsgeo && L.filltype == NoFill)
+ L.filltype=UnFill(1);
+ draw(opic,T*L,G,p,arrow,Bars,PenMargins);
+ pair Ap=t*A, Bp=t*B;
+ draw(opic,(Ap--Tp*Ap)^^(Bp--Tp*Bp), joinpen);
+ add(f,opic.fit());
+ }, true);
+ pic.addBox(min(g),max(g),Tp*min(p),Tp*max(p));
+}
+
+/*<asyxml><variable type="real" signature="perpfactor"><code></asyxml>*/
+real perpfactor=1;/*<asyxml></code><documentation>Factor for drawing perpendicular symbol.</documentation></variable></asyxml>*/
+/*<asyxml><function type="void" signature="perpendicularmark(picture,point,explicit pair,explicit pair,real,pen,margin,filltype)"><code></asyxml>*/
+void perpendicularmark(picture pic=currentpicture, point z,
+ explicit pair align,
+ explicit pair dir=E, real size=0,
+ pen p=currentpen,
+ margin margin=NoMargin,
+ filltype filltype=NoFill)
+{/*<asyxml></code><documentation>Draw a perpendicular symbol at z aligned in the direction align
+ relative to the path z--z+dir.
+ dir(45+n*90), where n in N*, are common values for 'align'.</documentation></function></asyxml>*/
+ p=squarecap+p;
+ if(size == 0) size=perpfactor*3mm+sqrt(1+linewidth(p))-1;
+ frame apic;
+ pair d1=size*align*unit(dir)*dir(-45);
+ pair d2=I*d1;
+ path g=d1--d1+d2--d2;
+ g=margin(g,p).g;
+ draw(apic,g,p);
+ if(filltype != NoFill) filltype.fill(apic,(relpoint(g,0)-relpoint(g,0.5)+
+ relpoint(g,1))--g--cycle,p+solid);
+ add(pic,apic,locate(z));
+}
+
+/*<asyxml><function type="void" signature="perpendicularmark(picture,point,vector,vector,real,pen,margin,filltype)"><code></asyxml>*/
+void perpendicularmark(picture pic=currentpicture, point z,
+ vector align,
+ vector dir=E, real size=0,
+ pen p=currentpen,
+ margin margin=NoMargin,
+ filltype filltype=NoFill)
+{/*<asyxml></code><documentation>Draw a perpendicular symbol at z aligned in the direction align
+ relative to the path z--z+dir.
+ dir(45+n*90), where n in N, are common values for 'align'.</documentation></function></asyxml>*/
+ perpendicularmark(pic, z, (pair)align, (pair)dir, size,
+ p, margin, filltype);
+}
+
+/*<asyxml><function type="void" signature="perpendicularmark(picture,point,explicit pair,path,real,pen,margin,filltype)"><code></asyxml>*/
+void perpendicularmark(picture pic=currentpicture, point z, explicit pair align, path g,
+ real size=0, pen p=currentpen,
+ margin margin=NoMargin,
+ filltype filltype=NoFill)
+{/*<asyxml></code><documentation>Draw a perpendicular symbol at z aligned in the direction align
+ relative to the path z--z+dir(g,0).
+ dir(45+n*90), where n in N, are common values for 'align'.</documentation></function></asyxml>*/
+ perpendicularmark(pic,z,align,dir(g,0),size,p,margin,filltype);
+}
+
+/*<asyxml><function type="void" signature="perpendicularmark(picture,point,vector,path,real,pen,margin,filltype)"><code></asyxml>*/
+void perpendicularmark(picture pic=currentpicture, point z, vector align, path g,
+ real size=0, pen p=currentpen,
+ margin margin=NoMargin,
+ filltype filltype=NoFill)
+{/*<asyxml></code><documentation>Draw a perpendicular symbol at z aligned in the direction align
+ relative to the path z--z+dir(g,0).
+ dir(45+n*90), where n in N, are common values for 'align'.</documentation></function></asyxml>*/
+ perpendicularmark(pic,z,(pair)align,dir(g,0),size,p,margin,filltype);
+}
+
+/*<asyxml><function type="void" signature="markrightangle(picture,point,point,point,real,pen,margin,filltype)"><code></asyxml>*/
+void markrightangle(picture pic=currentpicture, point A, point O,
+ point B, real size=0, pen p=currentpen,
+ margin margin=NoMargin,
+ filltype filltype=NoFill)
+{/*<asyxml></code><documentation>Mark the angle AOB with a perpendicular symbol.</documentation></function></asyxml>*/
+ pair Ap=A, Bp=B, Op=O;
+ pair dir=Ap-Op;
+ real a1=degrees(dir);
+ pair align=rotate(-a1)*unit(dir(Op--Ap,Op--Bp));
+ if (margin == NoMargin)
+ margin=TrueMargin(linewidth(currentpen)/2,linewidth(currentpen)/2);
+ perpendicularmark(pic=pic, z=O, align=align,
+ dir=dir, size=size, p=p,
+ margin=margin, filltype=filltype);
+}
+
+/*<asyxml><function type="bool" signature="simeq(point,point,real)"><code></asyxml>*/
+bool simeq(point A, point B, real fuzz=epsgeo)
+{/*<asyxml></code><documentation>Return true iff abs(A-B) < fuzz.
+ This routine is used internally to know if two points are equal, in particular by the operator == in 'point == point'.</documentation></function></asyxml>*/
+ return (abs(A-B) < fuzz);
+}
+bool simeq(point a, real b, real fuzz=epsgeo)
+{
+ coordsys R=a.coordsys;
+ return (abs(a-point(R,((pair)b)/R)) < fuzz);
+}
+
+/*<asyxml><function type="pair" signature="attract(pair,path,real)"><code></asyxml>*/
+pair attract(pair m, path g, real fuzz=0)
+{/*<asyxml></code><documentation>Return the nearest point (A PAIR) of 'm' which is on the path g.
+ 'fuzz' is the argument 'fuzz' of 'intersect'.</documentation></function></asyxml>*/
+ if(intersect(m,g,fuzz).length > 0) return m;
+ pair p;
+ real step=1, r=0;
+ real[] t;
+ static real eps=sqrt(realEpsilon);
+ do {// Find a radius for intersection
+ r+=step;
+ t=intersect(shift(m)*scale(r)*unitcircle,g);
+ } while(t.length <= 0);
+ p=point(g,t[1]);
+ real rm=0, rM=r;
+ while(rM-rm > eps) {
+ r=(rm+rM)/2;
+ t=intersect(shift(m)*scale(r)*unitcircle,g,fuzz);
+ if(t.length <= 0) {
+ rm=r;
+ } else {
+ rM=r;
+ p=point(g,t[1]);
+ }
+ }
+ return p;
+}
+
+/*<asyxml><function type="point" signature="attract(point,path,real)"><code></asyxml>*/
+point attract(point M, path g, real fuzz=0)
+{/*<asyxml></code><documentation>Return the nearest point (A POINT) of 'M' which is on the path g.
+ 'fuzz' is the argument 'fuzz' of 'intersect'.</documentation></function></asyxml>*/
+ return point(M.coordsys, attract(locate(M),g)/M.coordsys);
+}
+
+/*<asyxml><function type="real[]" signature="intersect(path,explicit pair)"><code></asyxml>*/
+real[] intersect(path g, explicit pair p, real fuzz=0)
+{/*<asyxml></code><documentation></documentation></function></asyxml>*/
+ fuzz=fuzz <= 0 ? sqrt(realEpsilon) : fuzz;
+ real[] or;
+ real r=realEpsilon;
+ do{
+ or=intersect(g,shift(p)*scale(r)*unitcircle,fuzz);
+ r *= 2;
+ } while(or.length == 0);
+ return or;
+}
+
+/*<asyxml><function type="real[]" signature="intersect(path,explicit point)"><code></asyxml>*/
+real[] intersect(path g, explicit point P, real fuzz=epsgeo)
+{/*<asyxml></code><documentation></documentation></function></asyxml>*/
+ return intersect(g,locate(P),fuzz);
+}
+// *.........................BASES.........................*
+// *=======================================================*
+
+// *=======================================================*
+// *.........................LINES.........................*
+/*<asyxml><struct signature="line"><code></asyxml>*/
+struct line
+{/*<asyxml></code><documentation>This structure provides the objects line, semi-line and segment oriented from A to B.
+ All the calculus with this structure will be as exact as Asymptote can do.
+ For a full precision, you must not cast 'line' to 'path' excepted for drawing routines.</documentation></asyxml>*/
+ /*<asyxml><property type="point" signature="A,B"><code></asyxml>*/
+ restricted point A,B;/*<asyxml></code><documentation>Two line's points with same coordinate system.</documentation></property><property type="bool" signature="extendA,extendB"><code></asyxml>*/
+ bool extendA,extendB;/*<asyxml></code><documentation>If true, extend 'l' in direction of A (resp. B).</documentation></property><property type="vector" signature="u,v"><code></asyxml>*/
+ restricted vector u,v;/*<asyxml></code><documentation>u=unit(AB)=direction vector, v=normal vector.</documentation></property><property type="real" signature="a,b,c"><code></asyxml>*/
+ restricted real a,b,c;/*<asyxml></code><documentation>Coefficients of the equation ax+by+c=0 in the coordinate system of 'A'.</documentation></property><property type="real" signature="slope,origin"><code></asyxml>*/
+ restricted real slope,origin;/*<asyxml></code><documentation>Slope and ordinate at the origin.</documentation></property></asyxml>*/
+ /*<asyxml><method type="line" signature="copy()"><code></asyxml>*/
+ line copy()
+ {/*<asyxml></code><documentation>Copy a line in a new instance.</documentation></method></asyxml>*/
+ line l=new line;
+ l.A=A;
+ l.B=B;
+ l.a=a;
+ l.b=b;
+ l.c=c;
+ l.slope=slope;
+ l.origin=origin;
+ l.u=u;
+ l.v=v;
+ l.extendA=extendA;
+ l.extendB=extendB;
+ return l;
+ }
+
+ /*<asyxml><method type="void" signature="init(point,bool,point,bool)"><code></asyxml>*/
+ void init(point A, bool extendA=true, point B, bool extendB=true)
+ {/*<asyxml></code><documentation>Initialize line.
+ If 'extendA' is true, the "line" is infinite in the direction of A.</documentation></method></asyxml>*/
+ point[] P=standardizecoordsys(A,B);
+ this.A=P[0];
+ this.B=P[1];
+ this.a=B.y-A.y;
+ this.b=A.x-B.x;
+ this.c=A.y*B.x-A.x*B.y;
+ this.slope= (this.b == 0) ? infinity : -this.a/this.b;
+ this.origin=(this.b == 0) ? (this.c==0) ? 0:infinity : -this.c/this.b;
+ this.u=unit(P[1]-P[0]);
+ // int tmp=sgnd(this.slope);
+ // this.u=(dot((pair)this.u,N) >= 0) ? tmp*this.u : -tmp*this.u;
+ this.v=rotate(90,point(P[0].coordsys,(0,0)))*this.u;
+ this.extendA=extendA;
+ this.extendB=extendB;
+ }
+}/*<asyxml></struct></asyxml>*/
+
+/*<asyxml><function type="line" signature="line(point,bool,point,bool)"><code></asyxml>*/
+line line(point A, bool extendA=true, point B, bool extendB=true)
+{/*<asyxml></code><documentation>Return the line passing through 'A' and 'B'.
+ If 'extendA' is true, the "line" is infinite in the direction of A.
+ A "line" can be half-line or segment.</documentation></function></asyxml>*/
+ if (A == B) abort("line: the points must be distinct.");
+ line l;
+ l.init(A,extendA,B,extendB);
+ return l;
+}
+
+/*<asyxml><struct signature="segment"><code></asyxml>*/
+struct segment
+{/*<asyxml></code><documentation><look href="struct line"/>.</documentation></asyxml>*/
+ restricted point A,B;// Extremity.
+ restricted vector u,v;// u=direction vector, v=normal vector.
+ restricted real a,b,c;// Coefficients of the équation ax+by+c=0
+ restricted real slope,origin;
+ segment copy()
+ {
+ segment s=new segment;
+ s.A=A;
+ s.B=B;
+ s.a=a;
+ s.b=b;
+ s.c=c;
+ s.slope=slope;
+ s.origin=origin;
+ s.u=u;
+ s.v=v;
+ return s;
+ }
+
+ void init(point A, point B)
+ {
+ line l;
+ l.init(A,B);
+ this.A=l.A; this.B=l.B;
+ this.a=l.a; this.b=l.b; this.c=l.c;
+ this.slope=l.slope; this.origin=l.origin;
+ this.u=l.u; this.v=l.v;
+ }
+}/*<asyxml></struct></asyxml>*/
+
+/*<asyxml><function type="segment" signature="segment(point,point)"><code></asyxml>*/
+segment segment(point A, point B)
+{/*<asyxml></code><documentation>Return the segment whose the extremities are A and B.</documentation></function></asyxml>*/
+ segment s;
+ s.init(A,B);
+ return s;
+}
+
+/*<asyxml><function type="real" signature="length(segment)"><code></asyxml>*/
+real length(segment s)
+{/*<asyxml></code><documentation>Return the length of 's'.</documentation></function></asyxml>*/
+ return abs(s.A-s.B);
+}
+
+/*<asyxml><operator type="line" signature="cast(segment)"><code></asyxml>*/
+line operator cast(segment s)
+{/*<asyxml></code><documentation>A segment is casted to a "finite line".</documentation></operator></asyxml>*/
+ return line(s.A,false,s.B,false);
+}
+
+/*<asyxml><operator type="segment" signature="cast(line)"><code></asyxml>*/
+segment operator cast(line l)
+{/*<asyxml></code><documentation>Cast line 'l' to segment [l.A l.B].</documentation></operator></asyxml>*/
+ return segment(l.A,l.B);
+}
+
+/*<asyxml><operator type="line" signature="*(transform,line)"><code></asyxml>*/
+line operator *(transform t, line l)
+{/*<asyxml></code><documentation>Provide transform*line</documentation></operator></asyxml>*/
+ return line(t*l.A,l.extendA,t*l.B,l.extendB);
+}
+/*<asyxml><operator type="line" signature="/(line,real)"><code></asyxml>*/
+line operator /(line l, real x)
+{/*<asyxml></code><documentation>Provide l/x.
+ Return the line passing through l.A/x and l.B/x.</documentation></operator></asyxml>*/
+ return line(l.A/x,l.extendA,l.B/x,l.extendB);
+}
+line operator /(line l, int x){return line(l.A/x,l.B/x);}
+/*<asyxml><operator type="line" signature="*(real,line)"><code></asyxml>*/
+line operator *(real x, line l)
+{/*<asyxml></code><documentation>Provide x*l.
+ Return the line passing through x*l.A and x*l.B.</documentation></operator></asyxml>*/
+ return line(x*l.A,l.extendA,x*l.B,l.extendB);
+}
+line operator *(int x, line l){return line(x*l.A,l.extendA,x*l.B,l.extendB);}
+
+/*<asyxml><operator type="line" signature="*(point,line)"><code></asyxml>*/
+line operator *(point M, line l)
+{/*<asyxml></code><documentation>Provide point*line.
+ Return the line passing through unit(M)*l.A and unit(M)*l.B.</documentation></operator></asyxml>*/
+ return line(unit(M)*l.A,l.extendA,unit(M)*l.B,l.extendB);
+}
+/*<asyxml><operator type="line" signature="+(line,point)"><code></asyxml>*/
+line operator +(line l, vector u)
+{/*<asyxml></code><documentation>Provide line+vector (and so line+point).
+ Return the line 'l' shifted by 'u'.</documentation></operator></asyxml>*/
+ return line(l.A+u,l.extendA,l.B+u,l.extendB);
+}
+/*<asyxml><operator type="line" signature="-(line,vector)"><code></asyxml>*/
+line operator -(line l, vector u)
+{/*<asyxml></code><documentation>Provide line - vector (and so line - point).
+ Return the line 'l' shifted by '-u'.</documentation></operator></asyxml>*/
+ return line(l.A-u,l.extendA,l.B-u,l.extendB);
+}
+
+/*<asyxml><operator type="line[]" signature="^^(line,line)"><code></asyxml>*/
+line[] operator ^^(line l1, line l2)
+{/*<asyxml></code><documentation>Provide line^^line.
+ Return the line array {l1,l2}.</documentation></operator></asyxml>*/
+ line[] ol;
+ ol.push(l1); ol.push(l2);
+ return ol;
+}
+
+/*<asyxml><operator type="line[]" signature="^^(line,line[])"><code></asyxml>*/
+line[] operator ^^(line l1, line[] l2)
+{/*<asyxml></code><documentation>Provide line^^line[].
+ Return the line array {l1, l2[0], l2[1]...}.
+ line[]^^line is also defined.</documentation></operator></asyxml>*/
+ line[] ol;
+ ol.push(l1);
+ for (int i=0; i<l2.length; ++i) {
+ ol.push(l2[i]);
+ }
+ return ol;
+}
+line[] operator ^^(line[] l2, line l1)
+{
+ line[] ol=l2;
+ ol.push(l1);
+ return ol;
+}
+
+/*<asyxml><operator type="line[]" signature="^^(line,line[])"><code></asyxml>*/
+line[] operator ^^(line l1[], line[] l2)
+{/*<asyxml></code><documentation>Provide line[]^^line[].
+ Return the line array {l1[0], l1[1],..., l2[0], l2[1],...}.</documentation></operator></asyxml>*/
+ line[] ol=l1;
+ for (int i=0; i<l2.length; ++i) {
+ ol.push(l2[i]);
+ }
+ return ol;
+}
+
+/*<asyxml><function type="bool" signature="sameside(point,point,line)"><code></asyxml>*/
+bool sameside(point M, point P, line l)
+{/*<asyxml></code><documentation>Return 'true' iff 'M' and 'N' are same side of the line (or on the line) 'l'.</documentation></function></asyxml>*/
+ pair A=l.A, B=l.B, m=M, p=P;
+ pair mil=(A+B)/2;
+ pair mA=rotate(90,mil)*A;
+ pair mB=rotate(-90,mil)*A;
+ return (abs(m-mA) <= abs(m-mB)) == (abs(p-mA) <= abs(p-mB));
+ // transform proj=projection(l.A,l.B);
+ // point Mp=proj*M;
+ // point Pp=proj*P;
+ // dot(Mp);dot(Pp);
+ // return dot(locate(Mp-M),locate(Pp-P)) >= 0;
+}
+
+/*<asyxml><function type="line" signature="line(segment)"><code></asyxml>*/
+line line(segment s)
+{/*<asyxml></code><documentation>Return the line passing through 's.A'
+ and 's.B'.</documentation></function></asyxml>*/
+ return line(s.A,s.B);
+}
+/*<asyxml><function type="segment" signature="segment(line)"><code></asyxml>*/
+segment segment(line l)
+{/*<asyxml></code><documentation>Return the segment whose extremities
+ are 'l.A' and 'l.B'.</documentation></function></asyxml>*/
+ return segment(l.A,l.B);
+}
+
+/*<asyxml><function type="point" signature="midpoint(segment)"><code></asyxml>*/
+point midpoint(segment s)
+{/*<asyxml></code><documentation>Return the midpoint of 's'.</documentation></function></asyxml>*/
+ return 0.5*(s.A+s.B);
+}
+
+/*<asyxml><function type="void" signature="write(line)"><code></asyxml>*/
+void write(explicit line l)
+{/*<asyxml></code><documentation>Write some informations about 'l'.</documentation></function></asyxml>*/
+ write("A="+(string)((pair)l.A));
+ write("Extend A="+(l.extendA ? "true" : "false"));
+ write("B="+(string)((pair)l.B));
+ write("Extend B="+(l.extendB ? "true" : "false"));
+ write("u="+(string)((pair)l.u));
+ write("v="+(string)((pair)l.v));
+ write("a="+(string) l.a);
+ write("b="+(string) l.b);
+ write("c="+(string) l.c);
+ write("slope="+(string) l.slope);
+ write("origin="+(string) l.origin);
+}
+
+/*<asyxml><function type="void" signature="write(explicit segment)"><code></asyxml>*/
+void write(explicit segment s)
+{/*<asyxml></code><documentation>Write some informations about 's'.</documentation></function></asyxml>*/
+ write("A="+(string)((pair)s.A));
+ write("B="+(string)((pair)s.B));
+ write("u="+(string)((pair)s.u));
+ write("v="+(string)((pair)s.v));
+ write("a="+(string) s.a);
+ write("b="+(string) s.b);
+ write("c="+(string) s.c);
+ write("slope="+(string) s.slope);
+ write("origin="+(string) s.origin);
+}
+
+/*<asyxml><operator type="bool" signature="==(line,line)"><code></asyxml>*/
+bool operator ==(line l1, line l2)
+{/*<asyxml></code><documentation>Provide the test 'line == line'.</documentation></operator></asyxml>*/
+ return (collinear(l1.u,l2.u) &&
+ abs(ypart((locate(l1.A)-locate(l1.B))/(locate(l1.A)-locate(l2.B)))) < epsgeo &&
+ l1.extendA == l2.extendA && l1.extendB == l2.extendB);
+}
+
+/*<asyxml><operator type="bool" signature="!=(line,line)"><code></asyxml>*/
+bool operator !=(line l1, line l2)
+{/*<asyxml></code><documentation>Provide the test 'line != line'.</documentation></operator></asyxml>*/
+ return !(l1 == l2);
+}
+
+/*<asyxml><operator type="bool" signature="@(point,line)"><code></asyxml>*/
+bool operator @(point m, line l)
+{/*<asyxml></code><documentation>Provide the test 'point @ line'.
+ Return true iff 'm' is on the 'l'.</documentation></operator></asyxml>*/
+ point M=changecoordsys(l.A.coordsys,m);
+ if (abs(l.a*M.x+l.b*M.y+l.c) >= epsgeo) return false;
+ if (l.extendA && l.extendB) return true;
+ if (!l.extendA && !l.extendB) return between(l.A,M,l.B);
+ if (l.extendA) return sameside(M,l.A,l.B);
+ return sameside(M,l.B,l.A);
+}
+
+/*<asyxml><function type="coordsys" signature="coordsys(line)"><code></asyxml>*/
+coordsys coordsys(line l)
+{/*<asyxml></code><documentation>Return the coordinate system in which 'l' is defined.</documentation></function></asyxml>*/
+ return l.A.coordsys;
+}
+
+/*<asyxml><function type="line" signature="reverse(line)"><code></asyxml>*/
+line reverse(line l)
+{/*<asyxml></code><documentation>Permute the points 'A' and 'B' of 'l' and so its orientation.</documentation></function></asyxml>*/
+ return line(l.B,l.extendB,l.A,l.extendA);
+}
+
+/*<asyxml><function type="line" signature="extend(line)"><code></asyxml>*/
+line extend(line l)
+{/*<asyxml></code><documentation>Return the infinite line passing through 'l.A' and 'l.B'.</documentation></function></asyxml>*/
+ line ol=l.copy();
+ ol.extendA=true;
+ ol.extendB=true;
+ return ol;
+}
+
+/*<asyxml><function type="line" signature="complementary(explicit line)"><code></asyxml>*/
+line complementary(explicit line l)
+{/*<asyxml></code><documentation>Return the complementary of a half-line with respect of
+ the full line 'l'.</documentation></function></asyxml>*/
+ if (l.extendA && l.extendB)
+ abort("complementary: the parameter is not a half-line.");
+ point origin=l.extendA ? l.B : l.A;
+ point ptdir=l.extendA ?
+ rotate(180,l.B)*l.A : rotate(180,l.A)*l.B;
+ return line(origin,false,ptdir);
+}
+
+/*<asyxml><function type="line[]" signature="complementary(explicit segment)"><code></asyxml>*/
+line[] complementary(explicit segment s)
+{/*<asyxml></code><documentation>Return the two half-lines of origin 's.A' and 's.B' respectively.</documentation></function></asyxml>*/
+ line[] ol=new line[2];
+ ol[0]=complementary(line(s.A,false,s.B));
+ ol[1]=complementary(line(s.A,s.B,false));
+ return ol;
+}
+
+/*<asyxml><function type="line" signature="Ox(coordsys)"><code></asyxml>*/
+line Ox(coordsys R=currentcoordsys)
+{/*<asyxml></code><documentation>Return the x-axis of 'R'.</documentation></function></asyxml>*/
+ return line(point(R,(0,0)), point(R,E));
+}
+/*<asyxml><constant type="line" signature="Ox"><code></asyxml>*/
+restricted line Ox=Ox();/*<asyxml></code><documentation>the x-axis of
+ the default coordinate system.</documentation></constant></asyxml>*/
+
+/*<asyxml><function type="line" signature="Oy(coordsys)"><code></asyxml>*/
+line Oy(coordsys R=currentcoordsys)
+{/*<asyxml></code><documentation>Return the y-axis of 'R'.</documentation></function></asyxml>*/
+ return line(point(R,(0,0)), point(R,N));
+}
+/*<asyxml><constant type="line" signature="Oy"><code></asyxml>*/
+restricted line Oy=Oy();/*<asyxml></code><documentation>the y-axis of
+ the default coordinate system.</documentation></constant></asyxml>*/
+
+/*<asyxml><function type="line" signature="line(real,point)"><code></asyxml>*/
+line line(real a, point A=point(currentcoordsys,(0,0)))
+{/*<asyxml></code><documentation>Return the line passing through 'A' with an
+ angle (in the coordinate system of A) 'a' in degrees.
+ line(point,real) is also defined.</documentation></function></asyxml>*/
+ return line(A, A+point(A.coordsys,A.coordsys.polar(1,radians(a))));
+}
+line line(point A=point(currentcoordsys,(0,0)),real a)
+{
+ return line(a,A);
+}
+line line(int a, point A=point(currentcoordsys,(0,0)))
+{
+ return line((real)a, A);
+}
+
+/*<asyxml><function type="line" signature="line(coordsys,real,real)"><code></asyxml>*/
+line line(coordsys R=currentcoordsys, real slope, real origin)
+{/*<asyxml></code><documentation>Return the line defined by slope and y-intercept relative to 'R'.</documentation></function></asyxml>*/
+ if (slope == infinity || slope == -infinity)
+ abort("The slope is infinite. Please, use the routine 'vline'.");
+ return line(point(R,(0,origin)), point(R,(1,origin+slope)));
+}
+
+/*<asyxml><function type="line" signature="line(coordsys,real,real,real)"><code></asyxml>*/
+line line(coordsys R=currentcoordsys, real a, real b, real c)
+{/*<asyxml></code><documentation>Retrun the line defined by equation relative to 'R'.</documentation></function></asyxml>*/
+ if (a == 0 && b == 0) abort("line: inconsistent equation...");
+ pair M;
+ M=(a == 0) ? (0,-c/b) : (-c/a,0);
+ return line(point(R,M), point(R,M+(-b,a)));
+}
+
+/*<asyxml><function type="line" signature="vline(coordsys)"><code></asyxml>*/
+line vline(coordsys R=currentcoordsys)
+{/*<asyxml></code><documentation>Return a vertical line in 'R' passing through the origin of 'R'.</documentation></function></asyxml>*/
+ point P=point(R,(0,0));
+ point PP=point(R,(R.O+N)/R);
+ return line(P,PP);
+}
+/*<asyxml><constant type="line" signature="vline"><code></asyxml>*/
+restricted line vline=vline();/*<asyxml></code><documentation>The vertical line in the current coordinate system passing
+ through the origin of this system.</documentation></constant></asyxml>*/
+
+/*<asyxml><function type="line" signature="hline(coordsys)"><code></asyxml>*/
+line hline(coordsys R=currentcoordsys)
+{/*<asyxml></code><documentation>Return a horizontal line in 'R' passing through the origin of 'R'.</documentation></function></asyxml>*/
+ point P=point(R,(0,0));
+ point PP=point(R,(R.O+E)/R);
+ return line(P,PP);
+}
+/*<asyxml><constant type="line" signature="hline"><code></asyxml>*/
+line hline=hline();/*<asyxml></code><documentation>The horizontal line in the current coordinate system passing
+ through the origin of this system.</documentation></constant></asyxml>*/
+
+/*<asyxml><function type="line" signature="changecoordsys(coordsys,line)"><code></asyxml>*/
+line changecoordsys(coordsys R, line l)
+{/*<asyxml></code><documentation>Return the line 'l' in the coordinate system 'R'.</documentation></function></asyxml>*/
+ point A=changecoordsys(R,l.A);
+ point B=changecoordsys(R,l.B);
+ return line(A,B);
+}
+
+/*<asyxml><function type="transform" signature="scale(real,line,line,bool)"><code></asyxml>*/
+transform scale(real k, line l1, line l2, bool safe=false)
+{/*<asyxml></code><documentation>Return the dilatation with respect to
+ 'l1' in the direction of 'l2'.</documentation></function></asyxml>*/
+ return scale(k,l1.A,l1.B,l2.A,l2.B,safe);
+}
+
+/*<asyxml><function type="transform" signature="reflect(line)"><code></asyxml>*/
+transform reflect(line l)
+{/*<asyxml></code><documentation>Return the reflect about the line 'l'.</documentation></function></asyxml>*/
+ return reflect((pair)l.A,(pair)l.B);
+}
+
+/*<asyxml><function type="transform" signature="reflect(line,line)"><code></asyxml>*/
+transform reflect(line l1, line l2, bool safe=false)
+{/*<asyxml></code><documentation>Return the reflect about the line
+ 'l1' in the direction of 'l2'.</documentation></function></asyxml>*/
+ return scale(-1.0,l1,l2,safe);
+}
+
+
+/*<asyxml><function type="point[]" signature="intersectionpoints(line,path)"><code></asyxml>*/
+point[] intersectionpoints(line l, path g)
+{/*<asyxml></code><documentation>Return all points of intersection of the line 'l' with the path 'g'.</documentation></function></asyxml>*/
+ // TODO utiliser la version 1.44 de intersections(path g, pair p, pair q)
+ // real [] t=intersections(g,l.A,l.B);
+ // coordsys R=coordsys(l);
+ // return sequence(new point(int n){return point(R,point(g,t[n])/R);}, t.length);
+ real [] t;
+ pair[] op;
+ pair A=l.A;
+ pair B=l.B;
+ real dy=B.y-A.y,
+ dx=A.x-B.x,
+ lg=length(g);
+ for (int i=0; i<lg; ++i)
+ {
+ pair z0=point(g,i),
+ z1=point(g,i+1),
+ c0=postcontrol(g,i),
+ c1=precontrol(g,i+1),
+ t3=z1-z0-3*c1+3*c0,
+ t2=3*z0+3*c1-6*c0,
+ t1=3*c0-3z0;
+ real a=dy*t3.x+dx*t3.y,
+ b=dy*t2.x+dx*t2.y,
+ c=dy*t1.x+dx*t1.y,
+ d=dy*z0.x+dx*z0.y+A.y*B.x-A.x*B.y;
+ t=cubicroots(a,b,c,d);
+ for (int j=0; j<t.length; ++j)
+ if (t[j]>=0 && (t[j]<1 || (t[j]==1 && i==lg-1 && !cyclic(g)))) op.push(point(g,i+t[j]));
+ }
+ point[] opp;
+ for (int i=0; i<op.length; ++i)
+ opp.push(point(coordsys(l),op[i]/coordsys(l)));
+ return opp;
+}
+
+/*<asyxml><function type="point" signature="intersectionpoint(line,line)"><code></asyxml>*/
+point intersectionpoint(line l1, line l2)
+{/*<asyxml></code><documentation>Return the point of intersection of line 'l1' with 'l2'.
+ If 'l1' and 'l2' have an infinity or none point of intersection,
+ this routine return (infinity,infinity).</documentation></function></asyxml>*/
+ point[] P=standardizecoordsys(l1.A,l1.B,l2.A,l2.B);
+ coordsys R=P[0].coordsys;
+ pair p=extension(P[0],P[1],P[2],P[3]);
+ if(finite(p)){
+ point p=point(R,p/R);
+ if (p @ l1 && p @ l2) return p;
+ }
+ return point(R,(infinity,infinity));
+}
+
+/*<asyxml><function type="line" signature="parallel(point,line)"><code></asyxml>*/
+line parallel(point M, line l)
+{/*<asyxml></code><documentation>Return the line parallel to 'l' passing through 'M'.</documentation></function></asyxml>*/
+ point A,B;
+ if (M.coordsys != coordsys(l))
+ {
+ A=changecoordsys(M.coordsys,l.A);
+ B=changecoordsys(M.coordsys,l.B);
+ } else {A=l.A;B=l.B;}
+ return line(M,M-A+B);
+}
+
+/*<asyxml><function type="line" signature="parallel(point,explicit vector)"><code></asyxml>*/
+line parallel(point M, explicit vector dir)
+{/*<asyxml></code><documentation>Return the line of direction 'dir' and passing through 'M'.</documentation></function></asyxml>*/
+ return line(M,M+locate(dir));
+}
+
+/*<asyxml><function type="line" signature="parallel(point,explicit pair)"><code></asyxml>*/
+line parallel(point M, explicit pair dir)
+{/*<asyxml></code><documentation>Return the line of direction 'dir' and passing through 'M'.</documentation></function></asyxml>*/
+ return line(M,M+vector(currentcoordsys,dir));
+}
+
+/*<asyxml><function type="bool" signature="parallel(line,line)"><code></asyxml>*/
+bool parallel(line l1, line l2, bool strictly=false)
+{/*<asyxml></code><documentation>Return 'true' if 'l1' and 'l2' are (strictly ?) parallel.</documentation></function></asyxml>*/
+ bool coll=collinear(l1.u,l2.u);
+ return strictly ? coll && (l1 != l2) : coll;
+}
+
+/*<asyxml><function type="bool" signature="concurrent(...line[])"><code></asyxml>*/
+bool concurrent(... line[] l)
+{/*<asyxml></code><documentation>Returns true if all the lines 'l' are concurrent.</documentation></function></asyxml>*/
+ if (l.length < 3) abort("'concurrent' needs at least for three lines ...");
+ pair point=intersectionpoint(l[0],l[1]);
+ bool conc;
+ for (int i=2; i < l.length; ++i) {
+ pair pt=intersectionpoint(l[i-1],l[i]);
+ conc=simeq(pt, point);
+ if (!conc) break;
+ }
+ return conc;
+}
+
+/*<asyxml><function type="transform" signature="projection(line)"><code></asyxml>*/
+transform projection(line l)
+{/*<asyxml></code><documentation>Return the orthogonal projection on 'l'.</documentation></function></asyxml>*/
+ return projection(l.A,l.B);
+}
+
+/*<asyxml><function type="transform" signature="projection(line,line,bool)"><code></asyxml>*/
+transform projection(line l1, line l2, bool safe=false)
+{/*<asyxml></code><documentation>Return the projection on (AB) in parallel of (CD).
+ If 'safe=true' and (l1)//(l2) return the identity.
+ If 'safe=false' and (l1)//(l2) return a infinity scaling.</documentation></function></asyxml>*/
+ return projection(l1.A,l1.B,l2.A,l2.B,safe);
+}
+
+/*<asyxml><function type="transform" signature="vprojection(line,bool)"><code></asyxml>*/
+transform vprojection(line l, bool safe=false)
+{/*<asyxml></code><documentation>Return the projection on 'l' in parallel of N--S.
+ If 'safe' is 'true' the projected point keeps the same place if 'l'
+ is vertical.</documentation></function></asyxml>*/
+ coordsys R=defaultcoordsys;
+ return projection(l, line(point(R,N),point(R,S)), safe);
+}
+
+/*<asyxml><function type="transform" signature="hprojection(line,bool)"><code></asyxml>*/
+transform hprojection(line l, bool safe=false)
+{/*<asyxml></code><documentation>Return the projection on 'l' in parallel of E--W.
+ If 'safe' is 'true' the projected point keeps the same place if 'l'
+ is horizontal.</documentation></function></asyxml>*/
+ coordsys R=defaultcoordsys;
+ return projection(l, line(point(R,E),point(R,W)), safe);
+}
+
+/*<asyxml><function type="line" signature="perpendicular(point,line)"><code></asyxml>*/
+line perpendicular(point M, line l)
+{/*<asyxml></code><documentation>Return the perpendicular line of 'l' passing through 'M'.</documentation></function></asyxml>*/
+ point Mp=projection(l)*M;
+ point A=Mp == l.A ? l.B : l.A;
+ return line(Mp, rotate(90,Mp)*A);
+}
+
+/*<asyxml><function type="line" signature="perpendicular(point,explicit vector)"><code></asyxml>*/
+line perpendicular(point M, explicit vector normal)
+{/*<asyxml></code><documentation>Return the line passing through 'M'
+ whose normal is \param{normal}.</documentation></function></asyxml>*/
+ return perpendicular(M,line(M,M+locate(normal)));
+}
+
+/*<asyxml><function type="line" signature="perpendicular(point,explicit pair)"><code></asyxml>*/
+line perpendicular(point M, explicit pair normal)
+{/*<asyxml></code><documentation>Return the line passing through 'M'
+ whose normal is \param{normal} (given in the currentcoordsys).</documentation></function></asyxml>*/
+ return perpendicular(M,line(M,M+vector(currentcoordsys,normal)));
+}
+
+/*<asyxml><function type="bool" signature="perpendicular(line,line)"><code></asyxml>*/
+bool perpendicular(line l1, line l2)
+{/*<asyxml></code><documentation>Return 'true' if 'l1' and 'l2' are perpendicular.</documentation></function></asyxml>*/
+ return abs(dot(locate(l1.u),locate(l2.u))) < epsgeo ;
+}
+
+/*<asyxml><function type="real" signature="angle(line,coordsys)"><code></asyxml>*/
+real angle(line l, coordsys R=coordsys(l))
+{/*<asyxml></code><documentation>Return the angle of the oriented line 'l',
+ in radian, in the interval ]-pi,pi] and relatively to 'R'.</documentation></function></asyxml>*/
+ return angle(l.u, R, false);
+}
+
+/*<asyxml><function type="real" signature="degrees(line,coordsys,bool)"><code></asyxml>*/
+real degrees(line l, coordsys R=coordsys(l))
+{/*<asyxml></code><documentation>Returns the angle of the oriented line 'l' in degrees,
+ in the interval [0,360[ and relatively to 'R'.</documentation></function></asyxml>*/
+ return degrees(angle(l, R));
+}
+
+/*<asyxml><function type="real" signature="sharpangle(line,line)"><code></asyxml>*/
+real sharpangle(line l1, line l2)
+{/*<asyxml></code><documentation>Return the measure in radians of the sharp angle formed by 'l1' and 'l2'.</documentation></function></asyxml>*/
+ vector u1=l1.u;
+ vector u2=(dot(l1.u,l2.u) < 0) ? -l2.u : l2.u;
+ real a12=angle(locate(u2))-angle(locate(u1));
+ a12=a12%(sgnd(a12)*pi);
+ if (a12 <= -pi/2) a12 += pi; else if (a12 > pi/2) a12 -= pi;
+ return a12;
+}
+
+/*<asyxml><function type="real" signature="angle(line,line)"><code></asyxml>*/
+real angle(line l1, line l2)
+{/*<asyxml></code><documentation>Return the measure in radians of oriented angle (l1.u,l2.u).</documentation></function></asyxml>*/
+ return angle(locate(l2.u))-angle(locate(l1.u));
+}
+
+/*<asyxml><function type="real" signature="degrees(line,line)"><code></asyxml>*/
+real degrees(line l1, line l2)
+{/*<asyxml></code><documentation>Return the measure in degrees of the
+ angle formed by the oriented lines 'l1' and 'l2'.</documentation></function></asyxml>*/
+ return degrees(angle(l1,l2));
+}
+
+/*<asyxml><function type="real" signature="sharpdegrees(line,line)"><code></asyxml>*/
+real sharpdegrees(line l1, line l2)
+{/*<asyxml></code><documentation>Return the measure in degrees of the sharp angle formed by 'l1' and 'l2'.</documentation></function></asyxml>*/
+ return degrees(sharpangle(l1,l2));
+}
+
+/*<asyxml><function type="line" signature="bisector(line,line,real,bool)"><code></asyxml>*/
+line bisector(line l1, line l2, real angle=0, bool sharp=true)
+{/*<asyxml></code><documentation>Return the bisector of the angle formed by 'l1' and 'l2'
+ rotated by the angle 'angle' (in degrees) around intersection point of 'l1' with 'l2'.
+ If 'sharp' is true (the default), this routine returns the bisector of the sharp angle.
+ Note that the returned line inherit of coordinate system of 'l1'.</documentation></function></asyxml>*/
+ line ol;
+ if (l1 == l2) return l1;
+ point A=intersectionpoint(l1,l2);
+ if (finite(A)) {
+ if(sharp) ol=rotate(sharpdegrees(l1,l2)/2+angle,A)*l1;
+ else {
+ coordsys R=coordsys(l1);
+ pair a=A, b=A+l1.u, c=A+l2.u;
+ pair pp=extension(a, a+dir(a--b,a--c), b, b+dir(b--a,b--c));
+ return rotate(angle,A)*line(A,point(R,pp/R));
+ }
+ } else {
+ ol=l1;
+ }
+ return ol;
+}
+
+/*<asyxml><function type="line" signature="sector(int,int,line,line,real,bool)"><code></asyxml>*/
+line sector(int n=2, int p=1, line l1, line l2, real angle=0, bool sharp=true)
+{/*<asyxml></code><documentation>Return the p-th nth-sector of the angle
+ formed by the oriented line 'l1' and 'l2'
+ rotated by the angle 'angle' (in degrees) around the intersection point of 'l1' with 'l2'.
+ If 'sharp' is true (the default), this routine returns the bisector of the sharp angle.
+ Note that the returned line inherit of coordinate system of 'l1'.</documentation></function></asyxml>*/
+ line ol;
+ if (l1 == l2) return l1;
+ point A=intersectionpoint(l1,l2);
+ if (finite(A)) {
+ if(sharp) ol=rotate(p*sharpdegrees(l1,l2)/n+angle,A)*l1;
+ else {
+ ol=rotate(p*degrees(l1,l2)/n+angle,A)*l1;
+ }
+ } else {
+ ol=l1;
+ }
+ return ol;
+}
+
+/*<asyxml><function type="line" signature="bisector(point,point,point,point,real)"><code></asyxml>*/
+line bisector(point A, point B, point C, point D, real angle=0, bool sharp=true)
+{/*<asyxml></code><documentation>Return the bisector of the angle formed by the lines (AB) and (CD).
+ <look href="#bisector(line,line,real,bool)"/>.</documentation></function></asyxml>*/
+ point[] P=standardizecoordsys(A,B,C,D);
+ return bisector(line(P[0],P[1]),line(P[2],P[3]),angle,sharp);
+}
+
+/*<asyxml><function type="line" signature="bisector(segment,real)"><code></asyxml>*/
+line bisector(segment s, real angle=0)
+{/*<asyxml></code><documentation>Return the bisector of the segment line 's' rotated by 'angle' (in degrees) around the
+ midpoint of 's'.</documentation></function></asyxml>*/
+ coordsys R=coordsys(s);
+ point m=midpoint(s);
+ vector dir=rotateO(90)*unit(s.A-m);
+ return rotate(angle,m)*line(m+dir,m-dir);
+}
+
+/*<asyxml><function type="line" signature="bisector(point,point,real)"><code></asyxml>*/
+line bisector(point A, point B, real angle=0)
+{/*<asyxml></code><documentation>Return the bisector of the segment line [AB] rotated by 'angle' (in degrees) around the
+ midpoint of [AB].</documentation></function></asyxml>*/
+ point[] P=standardizecoordsys(A,B);
+ return bisector(segment(P[0],P[1]),angle);
+}
+
+/*<asyxml><function type="real" signature="distance(point,line)"><code></asyxml>*/
+real distance(point M, line l)
+{/*<asyxml></code><documentation>Return the distance from 'M' to 'l'.
+ distance(line,point) is also defined.</documentation></function></asyxml>*/
+ point A=changecoordsys(defaultcoordsys,l.A);
+ point B=changecoordsys(defaultcoordsys,l.B);
+ line ll=line(A,B);
+ pair m=locate(M);
+ return abs(ll.a*m.x+ll.b*m.y+ll.c)/sqrt(ll.a^2+ll.b^2);
+}
+
+real distance(line l, point M)
+{
+ return distance(M,l);
+}
+
+/*<asyxml><function type="void" signature="draw(picture,Label,line,bool,bool,align,pen,arrowbar,Label,marker)"><code></asyxml>*/
+void draw(picture pic=currentpicture, Label L="",
+ line l, bool dirA=l.extendA, bool dirB=l.extendB,
+ align align=NoAlign, pen p=currentpen,
+ arrowbar arrow=None,
+ Label legend="", marker marker=nomarker,
+ pathModifier pathModifier=NoModifier)
+{/*<asyxml></code><documentation>Draw the line 'l' without altering the size of picture pic.
+ The boolean parameters control the infinite section.
+ The global variable 'linemargin' (default value is 0) allows to modify
+ the bounding box in which the line must be drawn.</documentation></function></asyxml>*/
+ if(!(dirA || dirB)) draw(l.A--l.B, invisible);// l is a segment.
+ Drawline(pic, L, l.A, dirP=dirA, l.B, dirQ=dirB,
+ align, p, arrow,
+ legend, marker, pathModifier);
+}
+
+/*<asyxml><function type="void" signature="draw(picture,Label[],line[],align,pen[],arrowbar,Label,marker)"><code></asyxml>*/
+void draw(picture pic=currentpicture,Label[] L=new Label[], line[] l,
+ align align=NoAlign, pen[] p=new pen[],
+ arrowbar arrow=None,
+ Label[] legend=new Label[], marker marker=nomarker,
+ pathModifier pathModifier=NoModifier)
+{/*<asyxml></code><documentation>Draw each lines with the corresponding pen.</documentation></function></asyxml>*/
+ for (int i=0; i < l.length; ++i) {
+ draw(pic, L.length>0 ? L[i] : "", l[i],
+ align, p=p.length>0 ? p[i] : currentpen,
+ arrow, legend.length>0 ? legend[i] : "", marker,
+ pathModifier);
+ }
+}
+
+/*<asyxml><function type="void" signature="draw(picture,Label[],line[],align,pen,arrowbar,Label,marker)"><code></asyxml>*/
+void draw(picture pic=currentpicture,Label[] L=new Label[], line[] l,
+ align align=NoAlign, pen p,
+ arrowbar arrow=None,
+ Label[] legend=new Label[], marker marker=nomarker,
+ pathModifier pathModifier=NoModifier)
+{/*<asyxml></code><documentation>Draw each lines with the same pen 'p'.</documentation></function></asyxml>*/
+ pen[] tp=sequence(new pen(int i){return p;},l.length);
+ draw(pic, L, l, align, tp, arrow, legend, marker, pathModifier);
+}
+
+/*<asyxml><function type="void" signature="show(picture,line,pen)"><code></asyxml>*/
+void show(picture pic=currentpicture, line l, pen p=red)
+{/*<asyxml></code><documentation>Draw some informations of 'l'.</documentation></function></asyxml>*/
+ dot("$A$",(pair)l.A,align=-locate(l.v),p);
+ dot("$B$",(pair)l.B,align=-locate(l.v),p);
+ draw(l,dotted);
+ draw("$\vec{u}$",locate(l.A)--locate(l.A+l.u),p,Arrow);
+ draw("$\vec{v}$",locate(l.A)--locate(l.A+l.v),p,Arrow);
+}
+
+/*<asyxml><function type="point[]" signature="sameside(point,line,line)"><code></asyxml>*/
+point[] sameside(point M, line l1, line l2)
+{/*<asyxml></code><documentation>Return two points on 'l1' and 'l2' respectively.
+ The first point is from the same side of M relatively to 'l2',
+ the second point is from the same side of M relatively to 'l1'.</documentation></function></asyxml>*/
+ point[] op;
+ coordsys R1=coordsys(l1);
+ coordsys R2=coordsys(l2);
+ if (parallel(l1,l2)) {
+ op.push(projection(l1)*M);
+ op.push(projection(l2)*M);
+ } else {
+ point O=intersectionpoint(l1,l2);
+ if (M @ l2) op.push((sameside(M,O+l1.u,l2)) ? O+l1.u : rotate(180,O)*(O+l1.u));
+ else op.push(projection(l1,l2)*M);
+ if (M @ l1) op.push((sameside(M,O+l2.u,l1)) ? O+l2.u : rotate(180,O)*(O+l2.u));
+ else {op.push(projection(l2,l1)*M);}
+ }
+ return op;
+}
+
+// /*<asyxml><function type="void" signature="markangle(picture,Label,int,real,real,line,line,explicit pair,arrowbar,pen,filltype,margin,marker)"><code></asyxml>*/
+// void markangle(picture pic=currentpicture,
+// Label L="", int n=1, real radius=0, real space=0,
+// line l1, line l2, explicit pair align=dir(1),
+// arrowbar arrow=None, pen p=currentpen,
+// filltype filltype=NoFill,
+// margin margin=NoMargin, marker marker=nomarker)
+// {/*<asyxml></code><documentation>Mark the angle (l1,l2) aligned in the direction 'align' relative to 'l1'.
+// Commune values for 'align' are dir(real).</documentation></function></asyxml>*/
+// if (parallel(l1,l2,true)) return;
+// real al=degrees(l1,defaultcoordsys);
+// pair O,A,B;
+// if (radius == 0) radius=markangleradius(p);
+// real d=degrees(locate(l1.u));
+// align=rotate(d)*align;
+// if (l1 == l2) {
+// O=midpoint(segment(l1.A,l1.B));
+// A=l1.A;B=l1.B;
+// if (sameside(rotate(sgn(angle(B-A))*45,O)*A,O+align,l1)) {radius=-radius;}
+// } else {
+// O=intersectionpoint(extend(l1),extend(l2));
+// pair R=O+align;
+// point [] ss=sameside(point(coordsys(l1),R/coordsys(l1)),l1,l2);
+// A=ss[0];
+// B=ss[1];
+// }
+// markangle(pic=pic,L=L,n=n,radius=radius,space=space,
+// O=O,A=A,B=B,
+// arrow=arrow,p=p,filltype=filltype,
+// margin=margin,marker=marker);
+// }
+
+// /*<asyxml><function type="void" signature="markangle(picture,Label,int,real,real,line,line,explicit vector,arrowbar,pen,filltype,margin,marker)"><code></asyxml>*/
+// void markangle(picture pic=currentpicture,
+// Label L="", int n=1, real radius=0, real space=0,
+// line l1, line l2,explicit vector align,
+// arrowbar arrow=None, pen p=currentpen,
+// filltype filltype=NoFill,
+// margin margin=NoMargin, marker marker=nomarker)
+// {/*<asyxml></code><documentation>Mark the angle (l1,l2) in the direction 'dir' given relatively to 'l1'.</documentation></function></asyxml>*/
+// markangle(pic, L, n, radius, space, l1, l2, (pair)align, arrow,
+// p, filltype, margin, marker);
+// }
+
+/*<asyxml><function type="void" signature="markangle(picture,Label,int,real,real,line,line,arrowbar,pen,filltype,margin,marker)"><code></asyxml>*/
+void markangle(picture pic=currentpicture,
+ Label L="", int n=1, real radius=0, real space=0,
+ line l1, line l2,
+ arrowbar arrow=None, pen p=currentpen,
+ filltype filltype=NoFill,
+ margin margin=NoMargin, marker marker=nomarker)
+{/*<asyxml></code><documentation>Mark the oriented angle (l1,l2).</documentation></function></asyxml>*/
+ if (parallel(l1,l2,true)) return;
+ real al=degrees(l1,defaultcoordsys);
+ pair O,A,B;
+ if (radius == 0) radius=markangleradius(p);
+ real d=degrees(locate(l1.u));
+ if (l1 == l2) {
+ O=midpoint(segment(l1.A,l1.B));
+ } else {
+ O=intersectionpoint(extend(l1),extend(l2));
+ }
+ A=O+locate(l1.u);
+ B=O+locate(l2.u);
+ markangle(pic=pic,L=L,n=n,radius=radius,space=space,
+ O=O,A=A,B=B,
+ arrow=arrow,p=p,filltype=filltype,
+ margin=margin,marker=marker);
+}
+
+/*<asyxml><function type="void" signature="perpendicularmark(picture,line,line,real,pen,int,margin,filltype)"><code></asyxml>*/
+void perpendicularmark(picture pic=currentpicture, line l1, line l2,
+ real size=0, pen p=currentpen, int quarter=1,
+ margin margin=NoMargin, filltype filltype=NoFill)
+{/*<asyxml></code><documentation>Draw a right angle at the intersection point of lines and
+ aligned in the 'quarter' nth quarter of circle formed by 'l1.u' and
+ 'l2.u'.</documentation></function></asyxml>*/
+ point P=intersectionpoint(l1,l2);
+ pair align=rotate(90*(quarter-1))*dir(45);
+ perpendicularmark(P,align,locate(l1.u),size,p,margin,filltype);
+}
+// *.........................LINES.........................*
+// *=======================================================*
+
+// *=======================================================*
+// *........................CONICS.........................*
+/*<asyxml><struct signature="bqe"><code></asyxml>*/
+struct bqe
+{/*<asyxml></code><documentation>Bivariate Quadratic Equation.</documentation></asyxml>*/
+ /*<asyxml><property type="real[]" signature="a"><code></asyxml>*/
+ real[] a;/*<asyxml></code><documentation>a[0]*x^2 + a[1]*x*y + a[2]*y^2 + a[3]*x + a[4]*y + a[5]=0</documentation></property><property type="coordsys" signature="coordsys"><code></asyxml>*/
+ coordsys coordsys;/*<asyxml></code></property></asyxml>*/
+}/*<asyxml></struct></asyxml>*/
+
+/*<asyxml><function type="bqe" signature="bqe(coordsys,real,real,real,real,real,real)"><code></asyxml>*/
+bqe bqe(coordsys R=currentcoordsys,
+ real a, real b, real c, real d, real e, real f)
+{/*<asyxml></code><documentation>Return the bivariate quadratic equation
+ a[0]*x^2 + a[1]*x*y + a[2]*y^2 + a[3]*x + a[4]*y + a[5]=0
+ relatively to the coordinate system R.</documentation></function></asyxml>*/
+ bqe obqe;
+ obqe.coordsys=R;
+ obqe.a=new real[] {a,b,c,d,e,f};
+ return obqe;
+}
+
+/*<asyxml><function type="bqe" signature="changecoordsys(coordsys,bqe)"><code></asyxml>*/
+bqe changecoordsys(coordsys R, bqe bqe)
+{/*<asyxml></code><documentation>Returns the bivariate quadratic equation relatively to 'R'.</documentation></function></asyxml>*/
+ pair i=coordinates(changecoordsys(R,vector(defaultcoordsys,
+ bqe.coordsys.i)));
+ pair j=coordinates(changecoordsys(R,vector(defaultcoordsys,
+ bqe.coordsys.j)));
+ pair O=coordinates(changecoordsys(R,point(defaultcoordsys,
+ bqe.coordsys.O)));
+ real a=bqe.a[0], b=bqe.a[1], c=bqe.a[2], d=bqe.a[3], f=bqe.a[4], g=bqe.a[5];
+ real ux=i.x, uy=i.y;
+ real vx=j.x, vy=j.y;
+ real ox=O.x, oy=O.y;
+ real D=ux*vy-uy*vx;
+ real ap=(a*vy^2-b*uy*vy+c*uy^2)/D^2;
+ real bpp=(-2*a*vx*vy+b*ux*vy+b*uy*vx-2*c*ux*uy)/D^2;
+ real cp=(a*vx^2-b*ux*vx+c*ux^2)/D^2;
+ real dp=(-2a*ox*vy^2+2a*oy*vx*vy+2b*ox*uy*vy-
+ b*oy*ux*vy-b*oy*uy*vx-2c*ox*uy^2+2c*oy*uy*ux)/D^2+
+ (d*vy-f*uy)/D;
+ real fp=(2a*ox*vx*vy-b*ox*ux*vy-2a*oy*vx^2-
+ b*ox*uy*vx+2*b*oy*ux*vx+2c*ox*ux*uy-2c*oy*ux^2)/D^2+
+ (f*ux-d*vx)/D;
+ g=(a*ox^2*vy^2-2a*ox*oy*vx*vy-b*ox^2*uy*vy+b*ox*oy*ux*vy+
+ a*oy^2*vx^2+b*ox*oy*uy*vx-b*oy^2*ux*vx+c*ox^2*uy^2-
+ 2*c*ox*oy*ux*uy+c*oy^2*ux^2)/D^2+
+ (d*oy*vx+f*ox*uy-d*ox*vy-f*oy*ux)/D+g;
+ bqe obqe;
+ obqe.a=approximate(new real[] {ap,bpp,cp,dp,fp,g});
+ obqe.coordsys=R;
+ return obqe;
+}
+
+/*<asyxml><function type="bqe" signature="bqe(point,point,point,point,point)"><code></asyxml>*/
+bqe bqe(point M1, point M2, point M3, point M4, point M5)
+{/*<asyxml></code><documentation>Return the bqe of conic passing through the five points (if possible).</documentation></function></asyxml>*/
+ coordsys R;
+ pair[] pts;
+ if (samecoordsys(M1,M2,M3,M4,M5)) {
+ R=M1.coordsys;
+ pts= new pair[] {M1.coordinates,M2.coordinates,M3.coordinates,M4.coordinates,M5.coordinates};
+ } else {
+ R=defaultcoordsys;
+ pts= new pair[] {M1,M2,M3,M4,M5};
+ }
+ real[][] M;
+ real[] x;
+ bqe bqe;
+ bqe.coordsys=R;
+ for (int i=0; i < 5; ++i) {// Try a=-1
+ M[i]=new real[] {pts[i].x*pts[i].y, pts[i].y^2, pts[i].x, pts[i].y, 1};
+ x[i]=pts[i].x^2;
+ }
+ if(abs(determinant(M)) < 1e-5) {// Try c=-1
+ for (int i=0; i < 5; ++i) {
+ M[i]=new real[] {pts[i].x^2, pts[i].x*pts[i].y, pts[i].x, pts[i].y, 1};
+ x[i]=pts[i].y^2;
+ }
+ real[] coef=solve(M,x);
+ bqe.a=new real[] {coef[0],coef[1],-1,coef[2],coef[3],coef[4]};
+ } else {
+ real[] coef=solve(M,x);
+ bqe.a=new real[] {-1,coef[0],coef[1],coef[2],coef[3],coef[4]};
+ }
+ bqe.a=approximate(bqe.a);
+ return bqe;
+}
+
+/*<asyxml><function type="bool" signature="samecoordsys(bool...bqe[])"><code></asyxml>*/
+bool samecoordsys(bool warn=true ... bqe[] bqes)
+{/*<asyxml></code><documentation>Return true if all the bivariate quadratic equations have the same coordinate system.</documentation></function></asyxml>*/
+ bool ret=true;
+ coordsys t=bqes[0].coordsys;
+ for (int i=1; i < bqes.length; ++i) {
+ ret=(t == bqes[i].coordsys);
+ if(!ret) break;
+ t=bqes[i].coordsys;
+ }
+ if(warn && !ret)
+ write("Warning, the coordinate system of two bivariate quadratic equations are not the same.
+The operation will be done relatively to the default coordinate system.");
+ return ret;
+}
+
+/*<asyxml><function type="real[]" signature="realquarticroots(real,real,real,real,real)"><code></asyxml>*/
+real[] realquarticroots(real a, real b, real c, real d, real e)
+{/*<asyxml></code><documentation>Return the real roots of the quartic equation ax^4 + b^x3 + cx^2 + dx = 0.</documentation></function></asyxml>*/
+ static real Fuzz=sqrt(realEpsilon);
+ pair[] zroots=quarticroots(a, b, c, d, e);
+ real[] roots;
+ real p(real x){return a*x^4+b*x^3+c*x^2+d*x+e;}
+ real prime(real x){return 4*a*x^3+3*b*x^2+2*c*x+d;}
+ real x;
+ bool search=true;
+ int n;
+ void addroot(real x)
+ {
+ bool exist=false;
+ for (int i=0; i < roots.length; ++i) {
+ if(abs(roots[i]-x) < 1e-5) {exist=true; break;}
+ }
+ if(!exist) roots.push(x);
+ }
+ for(int i=0; i < zroots.length; ++i) {
+ if(zroots[i].y == 0 || abs(p(zroots[i].x)) < Fuzz) addroot(zroots[i].x);
+ else {
+ if(abs(zroots[i].y) < 1e-3) {
+ x=zroots[i].x;
+ search=true;
+ n=200;
+ while(search) {
+ real tx=abs(p(x)) < Fuzz ? x : newton(iterations=n, p, prime, x);
+ if(tx < realMax) {
+ if(abs(p(tx)) < Fuzz) {
+ addroot(tx);
+ search=false;
+ } else if(n < 200) n *=2;
+ else {
+ search=false;
+ }
+ } else search=false; //It's not a real root.
+ }
+ }
+ }
+ }
+ return roots;
+}
+
+/*<asyxml><function type="point[]" signature="intersectionpoints(bqe,bqe)"><code></asyxml>*/
+point[] intersectionpoints(bqe bqe1, bqe bqe2)
+{/*<asyxml></code><documentation>Return the interscetion of the two conic sections whose equations are 'bqe1' and 'bqe2'.</documentation></function></asyxml>*/
+ coordsys R=bqe1.coordsys;
+ bqe lbqe1,lbqe2;
+ real[] a, b;
+ if(R != bqe2.coordsys) {
+ R=currentcoordsys;
+ a=changecoordsys(R, bqe1).a;
+ b=changecoordsys(R, bqe2).a;
+ } else {
+ a=bqe1.a;
+ b=bqe2.a;
+ }
+ static real e=100*sqrt(realEpsilon);
+ real[] x,y,c;
+ point[] P;
+ if(abs(a[0]-b[0]) > e || abs(a[1]-b[1]) > e || abs(a[2]-b[2]) > e) {
+ c=new real[] {-2*a[0]*a[2]*b[0]*b[2]+a[0]*a[2]*b[1]^2-a[0]*a[1]*b[2]*b[1]+a[1]^2*b[0]*b[2]-
+ a[2]*a[1]*b[0]*b[1]+a[0]^2*b[2]^2+a[2]^2*b[0]^2,
+ -a[2]*a[1]*b[0]*b[4]-a[2]*a[4]*b[0]*b[1]-a[1]*a[3]*b[2]*b[1]+2*a[0]*a[2]*b[1]*b[4]-
+ a[0]*a[1]*b[2]*b[4]+a[1]^2*b[2]*b[3]-2*a[2]*a[3]*b[0]*b[2]-2*a[0]*a[2]*b[2]*b[3]+
+ a[2]*a[3]*b[1]^2-a[2]*a[1]*b[1]*b[3]+2*a[1]*a[4]*b[0]*b[2]+2*a[2]^2*b[0]*b[3]-
+ a[0]*a[4]*b[2]*b[1]+2*a[0]*a[3]*b[2]^2,
+ -a[3]*a[4]*b[2]*b[1]+a[2]*a[5]*b[1]^2-a[1]*a[5]*b[2]*b[1]-a[1]*a[3]*b[2]*b[4]+
+ a[1]^2*b[2]*b[5]-2*a[2]*a[3]*b[2]*b[3]+2*a[2]^2*b[0]*b[5]+2*a[0]*a[5]*b[2]^2+a[3]^2*b[2]^2-
+ 2*a[2]*a[5]*b[0]*b[2]+2*a[1]*a[4]*b[2]*b[3]-a[2]*a[4]*b[1]*b[3]-2*a[0]*a[2]*b[2]*b[5]+
+ a[2]^2*b[3]^2+2*a[2]*a[3]*b[1]*b[4]-a[2]*a[4]*b[0]*b[4]+a[4]^2*b[0]*b[2]-a[2]*a[1]*b[3]*b[4]-
+ a[2]*a[1]*b[1]*b[5]-a[0]*a[4]*b[2]*b[4]+a[0]*a[2]*b[4]^2,
+ -a[4]*a[5]*b[2]*b[1]+a[2]*a[3]*b[4]^2+2*a[3]*a[5]*b[2]^2-a[2]*a[1]*b[4]*b[5]-
+ a[2]*a[4]*b[3]*b[4]+2*a[2]^2*b[3]*b[5]-2*a[2]*a[3]*b[2]*b[5]-a[3]*a[4]*b[2]*b[4]-
+ 2*a[2]*a[5]*b[2]*b[3]-a[2]*a[4]*b[1]*b[5]+2*a[1]*a[4]*b[2]*b[5]-a[1]*a[5]*b[2]*b[4]+
+ a[4]^2*b[2]*b[3]+2*a[2]*a[5]*b[1]*b[4],
+ -2*a[2]*a[5]*b[2]*b[5]+a[4]^2*b[2]*b[5]+a[5]^2*b[2]^2-a[4]*a[5]*b[2]*b[4]+a[2]*a[5]*b[4]^2+
+ a[2]^2*b[5]^2-a[2]*a[4]*b[4]*b[5]};
+ x=realquarticroots(c[0],c[1],c[2],c[3],c[4]);
+ } else {
+ if(abs(b[4]-a[4]) > e){
+ real D=(b[4]-a[4])^2;
+ c=new real[] {(a[0]*b[4]^2+(-a[1]*b[3]-2*a[0]*a[4]+a[1]*a[3])*b[4]+a[2]*b[3]^2+
+ (a[1]*a[4]-2*a[2]*a[3])*b[3]+a[0]*a[4]^2-a[1]*a[3]*a[4]+a[2]*a[3]^2)/D,
+ -((a[1]*b[4]-2*a[2]*b[3]-a[1]*a[4]+2*a[2]*a[3])*b[5]-a[3]*b[4]^2+(a[4]*b[3]-a[1]*a[5]+a[3]*a[4])*b[4]+(2*a[2]*a[5]-a[4]^2)*b[3]+(a[1]*a[4]-2*a[2]*a[3])*a[5])/D,
+ a[2]*(a[5]-b[5])^2/D+a[4]*(a[5]-b[5])/(b[4]-a[4])+a[5]};
+ x=quadraticroots(c[0],c[1],c[2]);
+ } else {
+ if(abs(a[3]-b[3]) > e) {
+ real D=b[3]-a[3];
+ c=new real[] {a[2], (-a[1]*b[5] + a[4]*b[3] + a[1]*a[5] - a[3]*a[4])/D,
+ a[0]*(a[5]-b[5])^2/D^2+a[3]*(a[5]-b[5])/D+a[5]};
+ y=quadraticroots(c[0],c[1],c[2]);
+ for (int i=0; i < y.length; ++i) {
+ c=new real[] {a[0], a[1]*y[i]+a[3], a[2]*y[i]^2+a[4]*y[i]+a[5]};
+ x=quadraticroots(c[0],c[1],c[2]);
+ for (int j=0; j < x.length; ++j) {
+ if(abs(b[0]*x[j]^2+b[1]*x[j]*y[i]+b[2]*y[i]^2+b[3]*x[j]+b[4]*y[i]+b[5]) < 1e-5)
+ P.push(point(R, (x[j],y[i])));
+ }
+ }
+ return P;
+ } else {
+ if(abs(a[5]-b[5]) < e) abort("intersectionpoints: intersection of identical conics.");
+ }
+ }
+ }
+ for (int i=0; i < x.length; ++i) {
+ c=new real[] {a[2], a[1]*x[i]+a[4], a[0]*x[i]^2+a[3]*x[i]+a[5]};
+ y=quadraticroots(c[0],c[1],c[2]);
+ for (int j=0; j < y.length; ++j) {
+ if(abs(b[0]*x[i]^2+b[1]*x[i]*y[j]+b[2]*y[j]^2+b[3]*x[i]+b[4]*y[j]+b[5]) < 1e-5)
+ P.push(point(R, (x[i],y[j])));
+ }
+ }
+ return P;
+}
+
+/*<asyxml><struct signature="conic"><code></asyxml>*/
+struct conic
+{/*<asyxml></code><documentation></documentation><property type="real" signature="e, p, h"><code></asyxml>*/
+ real e, p, h;/*<asyxml></code><documentation>BE CAREFUL: h=distance(F,D) and p=h*e (http://en.wikipedia.org/wiki/Ellipse)
+ While http://mathworld.wolfram.com/ takes p=distance(F,D).</documentation></property><property type="point" signature="F"><code></asyxml>*/
+ point F;/*<asyxml></code><documentation>Focus.</documentation></property><property type="line" signature="D"><code></asyxml>*/
+ line D;/*<asyxml></code><documentation>Directrix.</documentation></property><property type="line" signature="l"><code></asyxml>*/
+ line[] l;/*<asyxml></code><documentation>Case of degenerated conic (not yet implemented !).</documentation></property></asyxml>*/
+}/*<asyxml></struct></asyxml>*/
+
+bool degenerate(conic c)
+{
+ return !finite(c.p) || !finite(c.h);
+}
+
+/*ANCconic conic(point,line,real)ANC*/
+conic conic(point F, line l, real e)
+{/*DOC
+ The conic section define by the eccentricity 'e', the focus 'F'
+ and the directrix 'l'.
+ Note that an eccentricity equal to 0 defines a circle centered at F,
+ with a radius equal at the distance from 'F' to 'l'.
+ If the coordinate system of 'F' and 'l' are not identical, the conic is
+ attached to 'defaultcoordsys'.
+ DOC*/
+ if(e < 0) abort("conic: 'e' can't be negative.");
+ conic oc;
+ point[] P=standardizecoordsys(F,l.A,l.B);
+ line ll;
+ ll=line(P[1],P[2]);
+ oc.e=e < epsgeo ? 0 : e; // Handle case of circle.
+ oc.F=P[0];
+ oc.D=ll;
+ oc.h=distance(P[0],ll);
+ oc.p=abs(e) < epsgeo ? oc.h : e*oc.h;
+ return oc;
+}
+
+/*<asyxml><struct signature="circle"><code></asyxml>*/
+struct circle
+{/*<asyxml></code><documentation>All the calculus with this structure will be as exact as Asymptote can do.
+ For a full precision, you must not cast 'circle' to 'path' excepted for drawing routines.</documentation></asyxml>*/
+ /*<asyxml><property type="point" signature="C"><code></asyxml>*/
+ point C;/*<asyxml></code><documentation>Center</documentation></property><property><code></asyxml>*/
+ real r;/*<asyxml></code><documentation>Radius</documentation></property><property><code></asyxml>*/
+ line l;/*<asyxml></code><documentation>If the radius is infinite, this line is used instead of circle.</documentation></property></asyxml>*/
+}/*<asyxml></struct></asyxml>*/
+
+bool degenerate(circle c)
+{
+ return !finite(c.r);
+}
+
+line line(circle c){
+ if(finite(c.r)) abort("Circle can not be casted to line here.");
+ return c.l;
+}
+
+/*<asyxml><struct signature="ellipse"><code></asyxml>*/
+struct ellipse
+{/*<asyxml></code><documentation>Look at <html><a href="http://mathworld.wolfram.com/Ellipse.html">http://mathworld.wolfram.com/Ellipse.html</a></html></documentation></asyxml>*/
+ /*<asyxml><property type="point" signature="F1,F2,C"><code></asyxml>*/
+ restricted point F1, F2, C;/*<asyxml></code><documentation>Foci and center.</documentation></property><property type="real" signature="a, b, c, e, p"><code></asyxml>*/
+ restricted real a, b, c, e, p;/*<asyxml></code></property><property type="real" signature="angle"><code></asyxml>*/
+ restricted real angle;/*<asyxml></code><documentation>Value is degrees(F1-F2).</documentation></property><property type="line" signature="D1, D2"><code></asyxml>*/
+ restricted line D1, D2;/*<asyxml></code><documentation>Directrices.</documentation></property><property type="line" signature="l"><code></asyxml>*/
+ line l;/*<asyxml></code><documentation>If one axis is infinite, this line is used instead of ellipse.</documentation></property></asyxml>*/
+ /*<asyxml><method type="void" signature="init(point,point,real)"><code></asyxml>*/
+ void init(point f1, point f2, real a)
+ {/*<asyxml></code><documentation>Ellipse given by foci and semimajor axis</documentation></method></asyxml>*/
+ point[] P=standardizecoordsys(f1,f2);
+ this.F1=P[0];
+ this.F2=P[1];
+ this.angle=abs(P[1]-P[0]) < 10*epsgeo ? 0 : degrees(P[1]-P[0]);
+ this.C=(P[0]+P[1])/2;
+ this.a=a;
+ if(!finite(a)) {
+ this.l=line(P[0],P[1]);
+ this.b=infinity;
+ this.e=0;
+ this.c=0;
+ } else {
+ this.c=abs(C-P[0]);
+ this.b=this.c < epsgeo ? a : sqrt(a^2-c^2); // Handle case of circle.
+ this.e=this.c < epsgeo ? 0 : this.c/a; // Handle case of circle.
+ if(this.e >= 1) abort("ellipse.init: wrong parameter: e >= 1.");
+ this.p=a*(1-this.e^2);
+ if (this.c != 0) {// directrix is not set for a circle.
+ point A=this.C+(a^2/this.c)*unit(P[0]-this.C);
+ this.D1=line(A,A+rotateO(90)*unit(A-this.C));
+ this.D2=reverse(rotate(180,C)*D1);
+ }
+ }
+ }
+}/*<asyxml></struct></asyxml>*/
+
+bool degenerate(ellipse el)
+{
+ return (!finite(el.a) || !finite(el.b));
+}
+
+/*<asyxml><struct signature="parabola"><code></asyxml>*/
+struct parabola
+{/*<asyxml></code><documentation>Look at <html><a href="http://mathworld.wolfram.com/Parabola.html">http://mathworld.wolfram.com/Parabola.html</a></html></documentation><property type="point" signature="F, V"><code></asyxml>*/
+ restricted point F, V;/*<asyxml></code><documentation>Focus and vertex</documentation></property><property type="real" signature="a, p, e=1"><code></asyxml>*/
+ restricted real a, p, e=1;/*<asyxml></code></property><property type="real" signature="angle"><code></asyxml>*/
+ restricted real angle;/*<asyxml></code><documentation>Angle, in degrees, of the line (FV).</documentation></property><property type="line" signature="D"><code></asyxml>*/
+ restricted line D;/*<asyxml></code><documentation>Directrix</documentation></property><property type="pair" signature="bmin, bmax"><code></asyxml>*/
+ pair bmin, bmax;/*<asyxml></code><documentation>The (left,bottom) and (right,top) coordinates of region bounding box for drawing the parabola.
+ If unset the current picture bounding box is used instead.</documentation></property></asyxml>*/
+
+ /*<asyxml><method type="void" signature="init(point,line)"><code></asyxml>*/
+ void init(point F, line directrix)
+ {/*<asyxml></code><documentation>Parabola given by focus and directrix.</documentation></method></asyxml>*/
+ point[] P=standardizecoordsys(F,directrix.A,directrix.B);
+ line l=line(P[1],P[2]);
+ this.F=P[0];
+ this.D=l;
+ this.a=distance(P[0],l)/2;
+ this.p=2*a;
+ this.V=0.5*(F+projection(D)*P[0]);
+ this.angle=degrees(F-V);
+ }
+}/*<asyxml></struct></asyxml>*/
+
+/*<asyxml><struct signature="hyperbola"><code></asyxml>*/
+struct hyperbola
+{/*<asyxml></code><documentation><html>Look at <a href="http://mathworld.wolfram.com/Hyperbola.html">http://mathworld.wolfram.com/Hyperbola.html</a></html></documentation><property type="point" signature="F1, F2"><code></asyxml>*/
+ restricted point F1, F2;/*<asyxml></code><documentation>Foci.</documentation></property><property type="point" signature="C, V1, V2"><code></asyxml>*/
+ restricted point C, V1, V2;/*<asyxml></code><documentation>Center and vertices.</documentation></property><property type="real" signature="a, b, c, e, p"><code></asyxml>*/
+ restricted real a, b, c, e, p;/*<asyxml></code><documentation></documentation></property><property type="real" signature="angle"><code></asyxml>*/
+ restricted real angle;/*<asyxml></code><documentation>Angle, in degrees, of the line (F1F2).</documentation></property><property type="line" signature="D1, D2, A1, A2"><code></asyxml>*/
+ restricted line D1, D2, A1, A2;/*<asyxml></code><documentation>Directrices and asymptotes.</documentation></property><property type="pair" signature="bmin, bmax"><code></asyxml>*/
+ pair bmin, bmax; /*<asyxml></code><documentation>The (left,bottom) and (right,top) coordinates of region bounding box for drawing the hyperbola.
+ If unset the current picture bounding box is used instead.</documentation></property></asyxml>*/
+
+ /*<asyxml><method type="void" signature="init(point,point,real)"><code></asyxml>*/
+ void init(point f1, point f2, real a)
+ {/*<asyxml></code><documentation>Hyperbola given by foci and semimajor axis.</documentation></method></asyxml>*/
+ point[] P=standardizecoordsys(f1,f2);
+ this.F1=P[0];
+ this.F2=P[1];
+ this.angle=degrees(F2-F1);
+ this.a=a;
+ this.C=(P[0]+P[1])/2;
+ this.c=abs(C-P[0]);
+ this.e=this.c/a;
+ if(this.e <= 1) abort("hyperbola.init: wrong parameter: e <= 1.");
+ this.b=a*sqrt(this.e^2-1);
+ this.p=a*(this.e^2-1);
+ point A=this.C+(a^2/this.c)*unit(P[0]-this.C);
+ this.D1=line(A,A+rotateO(90)*unit(A-this.C));
+ this.D2=reverse(rotate(180,C)*D1);
+ this.V1=C+a*unit(F1-C);
+ this.V2=C+a*unit(F2-C);
+ this.A1=line(C,V1+b*unit(rotateO(-90)*(C-V1)));
+ this.A2=line(C,V1+b*unit(rotateO(90)*(C-V1)));
+ }
+}/*<asyxml></struct></asyxml>*/
+
+/*<asyxml><variable type="int" signature="conicnodesfactor"><code></asyxml>*/
+int conicnodesfactor=1;/*<asyxml></code><documentation>Factor for the node number of all conics.</documentation></variable></asyxml>*/
+
+/*<asyxml><variable type="int" signature="circlenodesnumberfactor"><code></asyxml>*/
+int circlenodesnumberfactor=100;/*<asyxml></code><documentation>Factor for the node number of circles.</documentation></variable></asyxml>*/
+/*<asyxml><function type="int" signature="circlenodesnumber(real)"><code></asyxml>*/
+int circlenodesnumber(real r)
+{/*<asyxml></code><documentation>Return the number of nodes for drawing a circle of radius 'r'.</documentation></function></asyxml>*/
+ if (circlenodesnumberfactor < 100) write("Warning: variable 'circlenodesnumberfactor' maybe too small.");
+ int oi=ceil(circlenodesnumberfactor*abs(r)^0.1);
+ oi=45*floor(oi/45);
+ return oi == 0 ? 4 : conicnodesfactor*oi;
+}
+
+/*<asyxml><function type="int" signature="circlenodesnumber(real,real,real)"><code></asyxml>*/
+int circlenodesnumber(real r, real angle1, real angle2)
+{/*<asyxml></code><documentation>Return the number of nodes to draw a circle arc.</documentation></function></asyxml>*/
+ return (r > 0) ?
+ ceil(circlenodesnumber(r)*abs(angle1-angle2)/360) :
+ ceil(circlenodesnumber(r)*abs((1-abs(angle1-angle2)/360)));
+}
+
+/*<asyxml><variable type="int" signature="ellispenodesnumberfactor"><code></asyxml>*/
+int ellipsenodesnumberfactor=250;/*<asyxml></code><documentation>Factor for the node number of ellispe (non-circle).</documentation></variable></asyxml>*/
+/*<asyxml><function type="int" signature="ellipsenodesnumber(real,real)"><code></asyxml>*/
+int ellipsenodesnumber(real a, real b)
+{/*<asyxml></code><documentation>Return the number of nodes to draw a ellipse of axis 'a' and 'b'.</documentation></function></asyxml>*/
+ if (ellipsenodesnumberfactor < 250) write("Warning: variable 'ellipsenodesnumberfactor' maybe too small.");
+ int tmp=circlenodesnumberfactor;
+ circlenodesnumberfactor=ellipsenodesnumberfactor;
+ int oi=circlenodesnumber(max(abs(a),abs(b))/min(abs(a),abs(b)));
+ circlenodesnumberfactor=tmp;
+ return conicnodesfactor*oi;
+}
+
+/*<asyxml><function type="int" signature="ellipsenodesnumber(real,real,real)"><code></asyxml>*/
+int ellipsenodesnumber(real a, real b, real angle1, real angle2, bool dir)
+{/*<asyxml></code><documentation>Return the number of nodes to draw an ellipse arc.</documentation></function></asyxml>*/
+ real d;
+ real da=angle2-angle1;
+ if(dir) {
+ d=angle1 < angle2 ? da : 360+da;
+ } else {
+ d=angle1 < angle2 ? -360+da : da;
+ }
+ int n=floor(ellipsenodesnumber(a,b)*abs(d)/360);
+ return n < 5 ? 5 : n;
+}
+
+/*<asyxml><variable type="int" signature="parabolanodesnumberfactor"><code></asyxml>*/
+int parabolanodesnumberfactor=100;/*<asyxml></code><documentation>Factor for the number of nodes of parabolas.</documentation></variable></asyxml>*/
+/*<asyxml><function type="int" signature="parabolanodesnumber(parabola,real,real)"><code></asyxml>*/
+int parabolanodesnumber(parabola p, real angle1, real angle2)
+{/*<asyxml></code><documentation>Return the number of nodes for drawing a parabola.</documentation></function></asyxml>*/
+ return conicnodesfactor*floor(0.01*parabolanodesnumberfactor*abs(angle1-angle2));
+}
+
+/*<asyxml><variable type="int" signature="hyperbolanodesnumberfactor"><code></asyxml>*/
+int hyperbolanodesnumberfactor=100;/*<asyxml></code><documentation>Factor for the number of nodes of hyperbolas.</documentation></variable></asyxml>*/
+/*<asyxml><function type="int" signature="hyperbolanodesnumber(hyperbola,real,real)"><code></asyxml>*/
+int hyperbolanodesnumber(hyperbola h, real angle1, real angle2)
+{/*<asyxml></code><documentation>Return the number of nodes for drawing an hyperbola.</documentation></function></asyxml>*/
+ return conicnodesfactor*floor(0.01*hyperbolanodesnumberfactor*abs(angle1-angle2)/h.e);
+}
+
+/*<asyxml><operator type="conic" signature="+(conic,explicit point)"><code></asyxml>*/
+conic operator +(conic c, explicit point M)
+{/*<asyxml></code><documentation></documentation></operator></asyxml>*/
+ return conic(c.F+M,c.D+M,c.e);
+}
+/*<asyxml><operator type="conic" signature="-(conic,explicit point)"><code></asyxml>*/
+conic operator -(conic c, explicit point M)
+{/*<asyxml></code><documentation></documentation></operator></asyxml>*/
+ return conic(c.F-M,c.D-M,c.e);
+}
+/*<asyxml><operator type="conic" signature="+(conic,explicit pair)"><code></asyxml>*/
+conic operator +(conic c, explicit pair m)
+{/*<asyxml></code><documentation></documentation></operator></asyxml>*/
+ point M=point(c.F.coordsys,m);
+ return conic(c.F+M,c.D+M,c.e);
+}
+/*<asyxml><operator type="conic" signature="-(conic,explicit pair)"><code></asyxml>*/
+conic operator -(conic c, explicit pair m)
+{/*<asyxml></code><documentation></documentation></operator></asyxml>*/
+ point M=point(c.F.coordsys,m);
+ return conic(c.F-M,c.D-M,c.e);
+}
+/*<asyxml><operator type="conic" signature="+(conic,vector)"><code></asyxml>*/
+conic operator +(conic c, vector v)
+{/*<asyxml></code><documentation></documentation></operator></asyxml>*/
+ return conic(c.F+v,c.D+v,c.e);
+}
+/*<asyxml><operator type="conic" signature="-(conic,vector)"><code></asyxml>*/
+conic operator -(conic c, vector v)
+{/*<asyxml></code><documentation></documentation></operator></asyxml>*/
+ return conic(c.F-v,c.D-v,c.e);
+}
+
+/*<asyxml><function type="coordsys" signature="coordsys(conic)"><code></asyxml>*/
+coordsys coordsys(conic co)
+{/*<asyxml></code><documentation>Return the coordinate system of 'co'.</documentation></function></asyxml>*/
+ return co.F.coordsys;
+}
+
+/*<asyxml><function type="conic" signature="changecoordsys(coordsys,conic)"><code></asyxml>*/
+conic changecoordsys(coordsys R, conic co)
+{/*<asyxml></code><documentation>Change the coordinate system of 'co' to 'R'</documentation></function></asyxml>*/
+ line l=changecoordsys(R,co.D);
+ point F=changecoordsys(R,co.F);
+ return conic(F,l,co.e);
+}
+
+/*<asyxml><typedef type="polarconicroutine" return="path" params="conic,real,real,int,bool"><code></asyxml>*/
+typedef path polarconicroutine(conic co, real angle1, real angle2, int n, bool direction);/*<asyxml></code><documentation>Routine type used to draw conics from 'angle1' to 'angle2'</documentation></typedef></asyxml>*/
+
+/*<asyxml><function type="path" signature="arcfromfocus(conic,real,real,int,bool)"><code></asyxml>*/
+path arcfromfocus(conic co, real angle1, real angle2, int n=400, bool direction=CCW)
+{/*<asyxml></code><documentation>Return the path of the conic section 'co' from angle1 to angle2 in degrees,
+ drawing in the given direction, with n nodes.</documentation></function></asyxml>*/
+ guide op;
+ if (n < 1) return op;
+ if (angle1 > angle2) {
+ path g=arcfromfocus(co,angle2,angle1,n,!direction);
+ return g == nullpath ? g : reverse(g);
+ }
+ point O=projection(co.D)*co.F;
+ pair i=unit(locate(co.F)-locate(O));
+ pair j=rotate(90)*i;
+ coordsys Rp=cartesiansystem(co.F,i,j);
+ real a1=direction ? radians(angle1) : radians(angle2);
+ real a2=direction ? radians(angle2) : radians(angle1)+2*pi;
+ real step=n == 1 ? 0 : (a2-a1)/(n-1);
+ real a,r;
+ for (int i=0; i < n; ++i) {
+ a=a1+i*step;
+ if(co.e >= 1) {
+ r=1-co.e*cos(a);
+ if(r > epsgeo) {
+ r=co.p/r;
+ op=op--Rp*Rp.polar(r,a);
+ }
+ } else {
+ r=co.p/(1-co.e*cos(a));
+ op=op..Rp*Rp.polar(r,a);
+ }
+ }
+ if(co.e < 1 && abs(abs(a2-a1)-2*pi) < epsgeo) op=(path)op..cycle;
+
+ return (direction ? op : op == nullpath ? op :reverse(op));
+}
+
+/*<asyxml><variable type="polarconicroutine" signature="currentpolarconicroutine"><code></asyxml>*/
+polarconicroutine currentpolarconicroutine=arcfromfocus;/*<asyxml></code><documentation>Default routine used to cast conic section to path.</documentation></variable></asyxml>*/
+
+/*<asyxml><function type="point" signature="angpoint(conic,real)"><code></asyxml>*/
+point angpoint(conic co, real angle)
+{/*<asyxml></code><documentation>Return the point of 'co' whose the angular (in degrees)
+ coordinate is 'angle' (mesured from the focus of 'co', relatively
+ to its 'natural coordinate system').</documentation></function></asyxml>*/
+ coordsys R=coordsys(co);
+ return point(R,point(arcfromfocus(co,angle,angle,1,CCW),0)/R);
+}
+
+/*<asyxml><operator type="bool" signature="@(point,conic)"><code></asyxml>*/
+bool operator @(point M, conic co)
+{/*<asyxml></code><documentation>Return true iff 'M' on 'co'.</documentation></operator></asyxml>*/
+ if(co.e == 0) return abs(abs(co.F-M)-co.p) < 10*epsgeo;
+ return abs(co.e*distance(M,co.D)-abs(co.F-M)) < 10*epsgeo;
+}
+
+/*<asyxml><function type="coordsys" signature="coordsys(ellipse)"><code></asyxml>*/
+coordsys coordsys(ellipse el)
+{/*<asyxml></code><documentation>Return the coordinate system of 'el'.</documentation></function></asyxml>*/
+ return el.F1.coordsys;
+}
+
+/*<asyxml><function type="coordsys" signature="canonicalcartesiansystem(ellipse)"><code></asyxml>*/
+coordsys canonicalcartesiansystem(ellipse el)
+{/*<asyxml></code><documentation>Return the canonical cartesian system of the ellipse 'el'.</documentation></function></asyxml>*/
+ if(degenerate(el)) return cartesiansystem(el.l.A,el.l.u,el.l.v);
+ pair O=locate(el.C);
+ pair i=el.e == 0 ? el.C.coordsys.i : unit(locate(el.F1)-O);
+ pair j=rotate(90)*i;
+ return cartesiansystem(O,i,j);
+}
+
+/*<asyxml><function type="coordsys" signature="canonicalcartesiansystem(parabola)"><code></asyxml>*/
+coordsys canonicalcartesiansystem(parabola p)
+{/*<asyxml></code><documentation>Return the canonical cartesian system of a parabola,
+ so that Origin = vertex of 'p' and directrix: x=-a.</documentation></function></asyxml>*/
+ point A=projection(p.D)*p.F;
+ pair O=locate((A+p.F)/2);
+ pair i=unit(locate(p.F)-O);
+ pair j=rotate(90)*i;
+ return cartesiansystem(O,i,j);
+}
+
+/*<asyxml><function type="coordsys" signature="canonicalcartesiansystem(hyperbola)"><code></asyxml>*/
+coordsys canonicalcartesiansystem(hyperbola h)
+{/*<asyxml></code><documentation>Return the canonical cartesian system of an hyperbola.</documentation></function></asyxml>*/
+ pair O=locate(h.C);
+ pair i=unit(locate(h.F2)-O);
+ pair j=rotate(90)*i;
+ return cartesiansystem(O,i,j);
+}
+
+/*<asyxml><function type="ellipse" signature="ellipse(point,point,real)"><code></asyxml>*/
+ellipse ellipse(point F1, point F2, real a)
+{/*<asyxml></code><documentation>Return the ellipse whose the foci are 'F1' and 'F2'
+ and the semimajor axis is 'a'.</documentation></function></asyxml>*/
+ ellipse oe;
+ oe.init(F1,F2,a);
+ return oe;
+}
+
+/*<asyxml><constant type="bool" signature="byfoci, byvertices"><code></asyxml>*/
+restricted bool byfoci=true, byvertices=false;/*<asyxml></code><documentation>Constants useful for the routine 'hyperbola(point P1, point P2, real ae, bool byfoci=byfoci)'</documentation></constant></asyxml>*/
+
+/*<asyxml><function type="hyperbola" signature="hyperbola(point,point,real,bool)"><code></asyxml>*/
+hyperbola hyperbola(point P1, point P2, real ae, bool byfoci=byfoci)
+{/*<asyxml></code><documentation>if 'byfoci=true':
+ return the hyperbola whose the foci are 'P1' and 'P2'
+ and the semimajor axis is 'ae'.
+ else return the hyperbola whose vertexes are 'P1' and 'P2' with eccentricity 'ae'.</documentation></function></asyxml>*/
+ hyperbola oh;
+ point[] P=standardizecoordsys(P1,P2);
+ if(byfoci) {
+ oh.init(P[0],P[1],ae);
+ } else {
+ real a=abs(P[0]-P[1])/2;
+ vector V=unit(P[0]-P[1]);
+ point F1=P[0]+a*(ae-1)*V;
+ point F2=P[1]-a*(ae-1)*V;
+ oh.init(F1,F2,a);
+ }
+ return oh;
+}
+
+/*<asyxml><function type="ellipse" signature="ellipse(point,point,point)"><code></asyxml>*/
+ellipse ellipse(point F1, point F2, point M)
+{/*<asyxml></code><documentation>Return the ellipse passing through 'M' whose the foci are 'F1' and 'F2'.</documentation></function></asyxml>*/
+ point P[]=standardizecoordsys(false,F1,F2,M);
+ real a=abs(F1-M)+abs(F2-M);
+ return ellipse(F1,F2,finite(a) ? a/2 : a);
+}
+
+/*<asyxml><function type="ellipse" signature="ellipse(point,real,real,real)"><code></asyxml>*/
+ellipse ellipse(point C, real a, real b, real angle=0)
+{/*<asyxml></code><documentation>Return the ellipse centered at 'C' with semimajor axis 'a' along C--C+dir(angle),
+ semiminor axis 'b' along the perpendicular.</documentation></function></asyxml>*/
+ ellipse oe;
+ coordsys R=C.coordsys;
+ angle+=degrees(R.i);
+ if(a < b) {angle += 90; real tmp=a; a=b; b=tmp;}
+ if(finite(a) && finite(b)) {
+ real c=sqrt(abs(a^2-b^2));
+ point f1, f2;
+ if(abs(a-b) < epsgeo) {
+ f1=C; f2=C;
+ } else {
+ f1=point(R,(locate(C)+rotate(angle)*(-c,0))/R);
+ f2=point(R,(locate(C)+rotate(angle)*(c,0))/R);
+ }
+ oe.init(f1,f2,a);
+ } else {
+ if(finite(b) || !finite(a)) oe.init(C,C+R.polar(1,angle),infinity);
+ else oe.init(C,C+R.polar(1,90+angle),infinity);
+ }
+ return oe;
+}
+
+/*<asyxml><function type="ellipse" signature="ellipse(explicit pair,real,real)"><code></asyxml>*/
+ellipse ellipse(explicit pair C, real a, real b)=
+ new ellipse(explicit pair C, real a, real b)
+{/*<asyxml></code><documentation>Overwrite the default routine.</documentation></function></asyxml>*/
+ return ellipse((point)C,a,b,0);
+};
+
+/*<asyxml><function type="ellipse" signature="ellipse(bqe)"><code></asyxml>*/
+ellipse ellipse(bqe bqe)
+{/*<asyxml></code><documentation>Return the ellipse a[0]*x^2 + a[1]*xy + a[2]*y^2 + a[3]*x + a[4]*y + a[5]=0
+ given in the coordinate system of 'bqe' with a[i]=bque.a[i].
+ <url href="http://mathworld.wolfram.com/QuadraticCurve.html"/>
+ <url href="http://mathworld.wolfram.com/Ellipse.html"/>.</documentation></function></asyxml>*/
+ bqe lbqe=changecoordsys(defaultcoordsys,bqe);
+ real a=lbqe.a[0], b=lbqe.a[1]/2, c=lbqe.a[2], d=lbqe.a[3]/2, f=lbqe.a[4]/2, g=lbqe.a[5];
+ coordsys R=bqe.coordsys;
+ string message="ellipse: the given equation is not an equation of an ellipse.";
+ real u=b^2*g + d^2*c + f^2*a;
+ real delta=a*c*g + b*f*d + d*b*f - u;
+ if(abs(delta) < epsgeo) abort(message);
+ real j=b^2-a*c;
+ real i=a+c;
+ real dd=j*(sgnd(c-a)*sqrt((a-c)^2+4*(b^2))-c-a);
+ real ddd=j*(-sgnd(c-a)*sqrt((a-c)^2+4*(b^2))-c-a);
+
+ if(abs(ddd) < epsgeo || abs(dd) < epsgeo ||
+ j >= -epsgeo || delta/sgnd(i) > 0) abort(message);
+
+ real x=(c*d-b*f)/j, y=(a*f-b*d)/j;
+ // real dir=abs(b) < epsgeo ? 0 : pi/2-0.5*acot(0.5*(c-a)/b);
+ real dir=abs(b) < epsgeo ? 0 : 0.5*acot(0.5*(c-a)/b);
+ if(dir*(c-a)*b < 0) dir=dir < 0 ? dir+pi/2 : dir-pi/2;
+ real cd=cos(dir), sd=sin(dir);
+ real t=a*cd^2-2*b*cd*sd+c*sd^2;
+ real tt=a*sd^2+2*b*cd*sd+c*cd^2;
+ real gg=-g+((d*cd-f*sd)^2)/t+((d*sd+f*cd)^2)/tt;
+ t=t/gg; tt=tt/gg;
+ // The equation of the ellipse is t*(x-center.x)^2+tt*(y-center.y)^2=1;
+ real aa, bb;
+ aa=sqrt(2*(u-2*b*d*f-a*c*g)/dd);
+ bb=sqrt(2*(u-2*b*d*f-a*c*g)/ddd);
+ a=t > tt ? max(aa,bb) : min(aa,bb);
+ b=t > tt ? min(aa,bb) : max(aa,bb);
+ return ellipse(point(R,(x,y)/R),
+ a,b,degrees(pi/2-dir-angle(R.i)));
+}
+
+/*<asyxml><function type="ellipse" signature="ellipse(point,point,point,point,point)"><code></asyxml>*/
+ellipse ellipse(point M1, point M2, point M3, point M4, point M5)
+{/*<asyxml></code><documentation>Return the ellipse passing through the five points (if possible)</documentation></function></asyxml>*/
+ return ellipse(bqe(M1,M2,M3,M4,M5));
+}
+
+/*<asyxml><function type="bool" signature="inside(ellipse,point)"><code></asyxml>*/
+bool inside(ellipse el, point M)
+{/*<asyxml></code><documentation>Return 'true' iff 'M' is inside 'el'.</documentation></function></asyxml>*/
+ return abs(el.F1-M)+abs(el.F2-M)-2*el.a < -epsgeo;
+}
+
+/*<asyxml><function type="bool" signature="inside(parabola,point)"><code></asyxml>*/
+bool inside(parabola p, point M)
+{/*<asyxml></code><documentation>Return 'true' if 'M' is inside 'p'.</documentation></function></asyxml>*/
+ return distance(p.D,M) - abs(p.F-M) > epsgeo;
+}
+
+/*<asyxml><function type="parabola" signature="parabola(point,line)"><code></asyxml>*/
+parabola parabola(point F, line l)
+{/*<asyxml></code><documentation>Return the parabola whose focus is 'F' and directrix is 'l'.</documentation></function></asyxml>*/
+ parabola op;
+ op.init(F,l);
+ return op;
+}
+
+/*<asyxml><function type="parabola" signature="parabola(point,point)"><code></asyxml>*/
+parabola parabola(point F, point vertex)
+{/*<asyxml></code><documentation>Return the parabola whose focus is 'F' and vertex is 'vertex'.</documentation></function></asyxml>*/
+ parabola op;
+ point[] P=standardizecoordsys(F,vertex);
+ point A=rotate(180,P[1])*P[0];
+ point B=A+rotateO(90)*unit(P[1]-A);
+ op.init(P[0],line(A,B));
+ return op;
+}
+
+/*<asyxml><function type="parabola" signature="parabola(point,real,real)"><code></asyxml>*/
+parabola parabola(point F, real a, real angle)
+{/*<asyxml></code><documentation>Return the parabola whose focus is F, latus rectum is 4a and
+ the angle of the axis of symmetry (in the coordinate system of F) is 'angle'.</documentation></function></asyxml>*/
+ parabola op;
+ coordsys R=F.coordsys;
+ point A=F-point(R,R.polar(2a,radians(angle)));
+ point B=A+point(R,R.polar(1,radians(90+angle)));
+ op.init(F,line(A,B));
+ return op;
+}
+
+/*<asyxml><function type="bool" signature="isparabola(bqe)"><code></asyxml>*/
+bool isparabola(bqe bqe)
+{/*<asyxml></code><documentation>Return true iff 'bqe' is the equation of a parabola.</documentation></function></asyxml>*/
+ bqe lbqe=changecoordsys(defaultcoordsys,bqe);
+ real a=lbqe.a[0], b=lbqe.a[1]/2, c=lbqe.a[2], d=lbqe.a[3]/2, f=lbqe.a[4]/2, g=lbqe.a[5];
+ real delta=a*c*g + b*f*d + d*b*f - (b^2*g + d^2*c + f^2*a);
+ return (abs(delta) > epsgeo && abs(b^2-a*c) < epsgeo);
+}
+
+/*<asyxml><function type="parabola" signature="parabola(bqe)"><code></asyxml>*/
+parabola parabola(bqe bqe)
+{/*<asyxml></code><documentation>Return the parabola a[0]x^2+a[1]xy+a[2]y^2+a[3]x+a[4]y+a[5]]=0 (a[n] means bqe.a[n]).
+ <url href="http://mathworld.wolfram.com/QuadraticCurve.html"/>
+ <url href="http://mathworld.wolfram.com/Parabola.html"/></documentation></function></asyxml>*/
+ bqe lbqe=changecoordsys(defaultcoordsys,bqe);
+ real a=lbqe.a[0], b=lbqe.a[1]/2, c=lbqe.a[2], d=lbqe.a[3]/2, f=lbqe.a[4]/2, g=lbqe.a[5];
+ string message="parabola: the given equation is not an equation of a parabola.";
+ real delta=a*c*g + b*f*d + d*b*f - (b^2*g + d^2*c + f^2*a);
+ if(abs(delta) < 10*epsgeo || abs(b^2-a*c) > 10*epsgeo) abort(message);
+ real dir=abs(b) < epsgeo ? 0 : 0.5*acot(0.5*(c-a)/b);
+ if(dir*(c-a)*b < 0) dir=dir < 0 ? dir+pi/2 : dir-pi/2;
+ real cd=cos(dir), sd=sin(dir);
+ real ap=a*cd^2-2*b*cd*sd+c*sd^2;
+ real cp=a*sd^2+2*b*cd*sd+c*cd^2;
+ real dp=d*cd-f*sd;
+ real fp=d*sd+f*cd;
+ real gp=g;
+ parabola op;
+ coordsys R=bqe.coordsys;
+ // The equation of the parabola is ap*x'^2+cp*y'^2+2dp*x'+2fp*y'+gp=0
+ if (abs(ap) < epsgeo) {/* directrix parallel to the rotated(dir) y-axis
+ equation: (y-vertex.y)^2=4*a*(x-vertex)
+ */
+ pair pvertex=rotate(degrees(-dir))*(0.5(-gp+fp^2/cp)/dp,-fp/cp);
+ real a=-0.5*dp/cp;
+ point vertex=point(R,pvertex/R);
+ point focus=point(R,(pvertex+a*expi(-dir))/R);
+ op=parabola(focus,vertex);
+
+ } else {/* directrix parallel to the rotated(dir) x-axis
+ equation: (x-vertex)^2=4*a*(y-vertex.y)
+ */
+ pair pvertex=rotate(degrees(-dir))*(-dp/ap,0.5*(-gp+dp^2/ap)/fp);
+ real a=-0.5*fp/ap;
+ point vertex=point(R,pvertex/R);
+ point focus=point(R,(pvertex+a*expi(pi/2-dir))/R);
+ op=parabola(focus,vertex);
+ }
+ return op;
+}
+
+/*<asyxml><function type="parabola" signature="parabola(point,point,point,line)"><code></asyxml>*/
+parabola parabola(point M1, point M2, point M3, line l)
+{/*<asyxml></code><documentation>Return the parabola passing through the three points with its directix
+ parallel to the line 'l'.</documentation></function></asyxml>*/
+ coordsys R;
+ pair[] pts;
+ if (samecoordsys(M1,M2,M3)) {
+ R=M1.coordsys;
+ } else {
+ R=defaultcoordsys;
+ }
+ real gle=degrees(l);
+ coordsys Rp=cartesiansystem(R.O,rotate(gle)*R.i,rotate(gle)*R.j);
+ pts=new pair[] {coordinates(changecoordsys(Rp,M1)),
+ coordinates(changecoordsys(Rp,M2)),
+ coordinates(changecoordsys(Rp,M3))};
+ real[][] M;
+ real[] x;
+ for (int i=0; i < 3; ++i) {
+ M[i]=new real[] {pts[i].x,pts[i].y,1};
+ x[i]=-pts[i].x^2;
+ }
+ real[] coef=solve(M,x);
+ return parabola(changecoordsys(R,bqe(Rp,1,0,0,coef[0],coef[1],coef[2])));
+}
+
+/*<asyxml><function type="parabola" signature="parabola(point,point,point,point,point)"><code></asyxml>*/
+parabola parabola(point M1, point M2, point M3, point M4, point M5)
+{/*<asyxml></code><documentation>Return the parabola passing through the five points.</documentation></function></asyxml>*/
+ return parabola(bqe(M1,M2,M3,M4,M5));
+}
+
+/*<asyxml><function type="hyperbola" signature="hyperbola(point,real,real,real)"><code></asyxml>*/
+hyperbola hyperbola(point C, real a, real b, real angle=0)
+{/*<asyxml></code><documentation>Return the hyperbola centered at 'C' with semimajor axis 'a' along C--C+dir(angle),
+ semiminor axis 'b' along the perpendicular.</documentation></function></asyxml>*/
+ hyperbola oh;
+ coordsys R=C.coordsys;
+ angle+=degrees(R.i);
+ real c=sqrt(a^2+b^2);
+ point f1=point(R,(locate(C)+rotate(angle)*(-c,0))/R);
+ point f2=point(R,(locate(C)+rotate(angle)*(c,0))/R);
+ oh.init(f1,f2,a);
+ return oh;
+}
+
+/*<asyxml><function type="hyperbola" signature="hyperbola(bqe)"><code></asyxml>*/
+hyperbola hyperbola(bqe bqe)
+{/*<asyxml></code><documentation>Return the hyperbola a[0]x^2+a[1]xy+a[2]y^2+a[3]x+a[4]y+a[5]]=0 (a[n] means bqe.a[n]).
+ <url href="http://mathworld.wolfram.com/QuadraticCurve.html"/>
+ <url href="http://mathworld.wolfram.com/Hyperbola.html"/></documentation></function></asyxml>*/
+ bqe lbqe=changecoordsys(defaultcoordsys,bqe);
+ real a=lbqe.a[0], b=lbqe.a[1]/2, c=lbqe.a[2], d=lbqe.a[3]/2, f=lbqe.a[4]/2, g=lbqe.a[5];
+ string message="hyperbola: the given equation is not an equation of a hyperbola.";
+ real delta=a*c*g + b*f*d + d*b*f - (b^2*g + d^2*c + f^2*a);
+ if(abs(delta) < 10*epsgeo || abs(b^2-a*c) < 0) abort(message);
+ real dir=abs(b) < epsgeo ? 0 : 0.5*acot(0.5*(c-a)/b);
+ real cd=cos(dir), sd=sin(dir);
+ real ap=a*cd^2-2*b*cd*sd+c*sd^2;
+ real cp=a*sd^2+2*b*cd*sd+c*cd^2;
+ real dp=d*cd-f*sd;
+ real fp=d*sd+f*cd;
+ real gp=-g+dp^2/ap+fp^2/cp;
+ hyperbola op;
+ coordsys R=bqe.coordsys;
+ real j=b^2-a*c;
+ point C=point(R,((c*d-b*f)/j,(a*f-b*d)/j)/R);
+ real aa=gp/ap, bb=gp/cp;
+ real a=sqrt(abs(aa)), b=sqrt(abs(bb));
+ if(aa < 0) {dir -= pi/2; aa=a; a=b; b=aa;}
+ return hyperbola(C,a,b,degrees(-dir-angle(R.i)));
+}
+
+/*<asyxml><function type="hyperbola" signature="hyperbola(point,point,point,point,point)"><code></asyxml>*/
+hyperbola hyperbola(point M1, point M2, point M3, point M4, point M5)
+{/*<asyxml></code><documentation>Return the hyperbola passing through the five points (if possible).</documentation></function></asyxml>*/
+ return hyperbola(bqe(M1,M2,M3,M4,M5));
+}
+
+/*<asyxml><function type="hyperbola" signature="conj(hyperbola)"><code></asyxml>*/
+hyperbola conj(hyperbola h)
+{/*<asyxml></code><documentation>Conjugate.</documentation></function></asyxml>*/
+ return hyperbola(h.C, h.b, h.a, 90+h.angle);
+}
+
+/*<asyxml><function type="circle" signature="circle(explicit point,real)"><code></asyxml>*/
+circle circle(explicit point C, real r)
+{/*<asyxml></code><documentation>Circle given by center and radius.</documentation></function></asyxml>*/
+ circle oc=new circle;
+ oc.C=C;
+ oc.r=r;
+ if(!finite(r)) oc.l=line(C,C+vector(C.coordsys,(1,0)));
+ return oc;
+}
+circle circle(explicit point C, int r)
+{
+ return circle(C,(real) r);
+}
+
+/*<asyxml><function type="circle" signature="circle(pair,real)"><code></asyxml>*/
+circle circle(pair c, real r)=new circle(pair c, real r)
+{/*<asyxml></code><documentation>Overwrite 'circle(pair,real)'</documentation></function></asyxml>*/
+ return circle(locate(c),r);
+};
+
+/*<asyxml><function type="circle" signature="circle(point,point)"><code></asyxml>*/
+circle circle(point A, point B)
+{/*<asyxml></code><documentation>Return the circle of diameter AB.</documentation></function></asyxml>*/
+ real r;
+ circle oc;
+ real a=abs(A), b=abs(B);
+ if(finite(a) && finite(b)) {
+ oc=circle((A+B)/2,abs(A-B)/2);
+ } else {
+ oc.r=infinity;
+ if(finite(abs(A))) oc.l=line(A,A+unit(B));
+ else {
+ if(finite(abs(B))) oc.l=line(B,B+unit(A));
+ else if(finite(abs(A-B)/2)) oc=circle((A+B)/2,abs(A-B)/2); else
+ oc.l=line(A,B);
+ }
+ }
+ return oc;
+}
+
+/*<asyxml><function type="circle" signature="circle(segment)"><code></asyxml>*/
+circle circle(segment s)
+{/*<asyxml></code><documentation>Return the circle of diameter 's'.</documentation></function></asyxml>*/
+ return circle(s.A,s.B);
+}
+
+/*<asyxml><function type="point" signature="circumcenter(point,point,point)"><code></asyxml>*/
+point circumcenter(point A, point B, point C)
+{/*<asyxml></code><documentation>Return the circumcenter of triangle ABC.</documentation></function></asyxml>*/
+ point[] P=standardizecoordsys(A,B,C);
+ coordsys R=P[0].coordsys;
+ pair a=A, b=B, c=C;
+ pair mAB=(a+b)/2;
+ pair mAC=(a+c)/2;
+ pair pp=extension(mAB, rotate(90,mAB)*a, mAC, rotate(90,mAC)*c);
+ return point(R,pp/R);
+}
+
+/*<asyxml><function type="circle" signature="circle(point,point,point)"><code></asyxml>*/
+circle circle(point A, point B, point C)
+{/*<asyxml></code><documentation>Return the circumcircle of the triangle ABC.</documentation></function></asyxml>*/
+ if(collinear(A-B,A-C)) {
+ circle oc;
+ oc.r=infinity;
+ oc.C=(A+B+C)/3;
+ oc.l=line(oc.C, oc.C == A ? B : A);
+ return oc;
+ }
+ point c=circumcenter(A, B, C);
+ return circle(c,abs(c-A));
+}
+
+/*<asyxml><function type="circle" signature="circumcircle(point,point,point)"><code></asyxml>*/
+circle circumcircle(point A, point B, point C)
+{/*<asyxml></code><documentation>Return the circumcircle of the triangle ABC.</documentation></function></asyxml>*/
+ return circle(A,B,C);
+}
+
+/*<asyxml><operator type="circle" signature="*(real,explicit circle)"><code></asyxml>*/
+circle operator *(real x, explicit circle c)
+{/*<asyxml></code><documentation>Multiply the radius of 'c'.</documentation></operator></asyxml>*/
+ return finite(c.r) ? circle(c.C,x*c.r) : c;
+}
+circle operator *(int x, explicit circle c)
+{
+ return finite(c.r) ? circle(c.C,x*c.r) : c;
+}
+/*<asyxml><operator type="circle" signature="/(explicit circle,real)"><code></asyxml>*/
+circle operator /(explicit circle c, real x)
+{/*<asyxml></code><documentation>Divide the radius of 'c'</documentation></operator></asyxml>*/
+ return finite(c.r) ? circle(c.C,c.r/x) : c;
+}
+circle operator /(explicit circle c,int x)
+{
+ return finite(c.r) ? circle(c.C,c.r/x) : c;
+}
+/*<asyxml><operator type="circle" signature="+(explicit circle,explicit point)"><code></asyxml>*/
+circle operator +(explicit circle c, explicit point M)
+{/*<asyxml></code><documentation>Translation of 'c'.</documentation></operator></asyxml>*/
+ return circle(c.C+M,c.r);
+}
+/*<asyxml><operator type="circle" signature="-(explicit circle,explicit point)"><code></asyxml>*/
+circle operator -(explicit circle c, explicit point M)
+{/*<asyxml></code><documentation>Translation of 'c'.</documentation></operator></asyxml>*/
+ return circle(c.C-M,c.r);
+}
+/*<asyxml><operator type="circle" signature="+(explicit circle,pair)"><code></asyxml>*/
+circle operator +(explicit circle c, pair m)
+{/*<asyxml></code><documentation>Translation of 'c'.
+ 'm' represent coordinates in the coordinate system where 'c' is defined.</documentation></operator></asyxml>*/
+ return circle(c.C+m,c.r);
+}
+/*<asyxml><operator type="circle" signature="-(explicit circle,pair)"><code></asyxml>*/
+circle operator -(explicit circle c, pair m)
+{/*<asyxml></code><documentation>Translation of 'c'.
+ 'm' represent coordinates in the coordinate system where 'c' is defined.</documentation></operator></asyxml>*/
+ return circle(c.C-m,c.r);
+}
+/*<asyxml><operator type="circle" signature="+(explicit circle,vector)"><code></asyxml>*/
+circle operator +(explicit circle c, vector m)
+{/*<asyxml></code><documentation>Translation of 'c'.</documentation></operator></asyxml>*/
+ return circle(c.C+m,c.r);
+}
+/*<asyxml><operator type="circle" signature="-(explicit circle,vector)"><code></asyxml>*/
+circle operator -(explicit circle c, vector m)
+{/*<asyxml></code><documentation>Translation of 'c'.</documentation></operator></asyxml>*/
+ return circle(c.C-m,c.r);
+}
+/*<asyxml><operator type="real" signature="^(point,explicit circle)"><code></asyxml>*/
+real operator ^(point M, explicit circle c)
+{/*<asyxml></code><documentation>The power of 'M' with respect to the circle 'c'</documentation></operator></asyxml>*/
+ return xpart((abs(locate(M)-locate(c.C)),c.r)^2);
+}
+/*<asyxml><operator type="bool" signature="@(point,explicit circle)"><code></asyxml>*/
+bool operator @(point M, explicit circle c)
+{/*<asyxml></code><documentation>Return true iff 'M' is on the circle 'c'.</documentation></operator></asyxml>*/
+ return finite(c.r) ?
+ abs(abs(locate(M)-locate(c.C))-abs(c.r)) <= 10*epsgeo :
+ M @ c.l;
+}
+
+/*<asyxml><operator type="ellipse" signature="cast(circle)"><code></asyxml>*/
+ellipse operator cast(circle c)
+{/*<asyxml></code><documentation></documentation></operator></asyxml>*/
+ return finite(c.r) ? ellipse(c.C,c.r,c.r,0) : ellipse(c.l.A,c.l.B,infinity);
+}
+
+/*<asyxml><operator type="circle" signature="cast(ellipse)"><code></asyxml>*/
+circle operator cast(ellipse el)
+{/*<asyxml></code><documentation></documentation></operator></asyxml>*/
+ circle oc;
+ bool infb=(!finite(el.a) || !finite(el.b));
+ if(!infb && abs(el.a-el.b) > epsgeo)
+ abort("Can not cast ellipse with different axis values to circle");
+ oc=circle(el.C,infb ? infinity : el.a);
+ oc.l=el.l.copy();
+ return oc;
+}
+
+/*<asyxml><operator type="ellipse" signature="cast(conic)"><code></asyxml>*/
+ellipse operator cast(conic co)
+{/*<asyxml></code><documentation>Cast a conic to an ellipse (can be a circle).</documentation></operator></asyxml>*/
+ if(degenerate(co) && co.e < 1) return ellipse(co.l[0].A, co.l[0].B,infinity);
+ ellipse oe;
+ if(co.e < 1) {
+ real a=co.p/(1-co.e^2);
+ real c=co.e*a;
+ vector v=co.D.v;
+ if(!sameside(co.D.A+v,co.F,co.D)) v=-v;
+ point f2=co.F+2*c*v;
+ f2=changecoordsys(co.F.coordsys,f2);
+ oe=a == 0 ? ellipse(co.F,co.p,co.p,0) : ellipse(co.F,f2,a);
+ } else
+ abort("casting: The conic section is not an ellipse.");
+ return oe;
+}
+
+/*<asyxml><operator type="parabola" signature="cast(conic)"><code></asyxml>*/
+parabola operator cast(conic co)
+{/*<asyxml></code><documentation>Cast a conic to a parabola.</documentation></operator></asyxml>*/
+ parabola op;
+ if(abs(co.e-1) > epsgeo) abort("casting: The conic section is not a parabola.");
+ op.init(co.F,co.D);
+ return op;
+}
+
+/*<asyxml><operator type="conic" signature="cast(parabola)"><code></asyxml>*/
+conic operator cast(parabola p)
+{/*<asyxml></code><documentation>Cast a parabola to a conic section.</documentation></operator></asyxml>*/
+ return conic(p.F,p.D,1);
+}
+
+/*<asyxml><operator type="hyperbola" signature="cast(conic)"><code></asyxml>*/
+hyperbola operator cast(conic co)
+{/*<asyxml></code><documentation>Cast a conic section to an hyperbola.</documentation></operator></asyxml>*/
+ hyperbola oh;
+ if(co.e > 1) {
+ real a=co.p/(co.e^2-1);
+ real c=co.e*a;
+ vector v=co.D.v;
+ if(sameside(co.D.A+v,co.F,co.D)) v=-v;
+ point f2=co.F+2*c*v;
+ f2=changecoordsys(co.F.coordsys,f2);
+ oh=hyperbola(co.F,f2,a);
+ } else
+ abort("casting: The conic section is not an hyperbola.");
+ return oh;
+}
+
+/*<asyxml><operator type="conic" signature="cast(hyperbola)"><code></asyxml>*/
+conic operator cast(hyperbola h)
+{/*<asyxml></code><documentation>Hyperbola to conic section.</documentation></operator></asyxml>*/
+ return conic(h.F1,h.D1,h.e);
+}
+
+/*<asyxml><operator type="conic" signature="cast(ellipse)"><code></asyxml>*/
+conic operator cast(ellipse el)
+{/*<asyxml></code><documentation>Ellipse to conic section.</documentation></operator></asyxml>*/
+ conic oc;
+ if(abs(el.c) > epsgeo) {
+ real x=el.a^2/el.c;
+ point O=(el.F1+el.F2)/2;
+ point A=O+x*unit(el.F1-el.F2);
+ oc=conic(el.F1,perpendicular(A,line(el.F1,el.F2)),el.e);
+ } else {//The ellipse is a circle
+ coordsys R=coordsys(el);
+ point M=el.F1+point(R,R.polar(el.a,0));
+ line l=line(rotate(90,M)*el.F1,M);
+ oc=conic(el.F1,l,0);
+ }
+ if(degenerate(el)) {
+ oc.p=infinity;
+ oc.h=infinity;
+ oc.l=new line[]{el.l};
+ }
+ return oc;
+}
+
+/*<asyxml><operator type="conic" signature="cast(circle)"><code></asyxml>*/
+conic operator cast(circle c)
+{/*<asyxml></code><documentation>Circle to conic section.</documentation></operator></asyxml>*/
+ return (conic)((ellipse)c);
+}
+
+/*<asyxml><operator type="circle" signature="cast(conic)"><code></asyxml>*/
+circle operator cast(conic c)
+{/*<asyxml></code><documentation>Conic section to circle.</documentation></operator></asyxml>*/
+ ellipse el=(ellipse)c;
+ circle oc;
+ if(abs(el.a-el.b) < epsgeo) {
+ oc=circle(el.C,el.a);
+ if(degenerate(c)) oc.l=c.l[0];
+ }
+ else abort("Can not cast this conic to a circle");
+ return oc;
+}
+
+/*<asyxml><operator type="ellipse" signature="*(transform,ellipse)"><code></asyxml>*/
+ellipse operator *(transform t, ellipse el)
+{/*<asyxml></code><documentation>Provide transform*ellipse.</documentation></operator></asyxml>*/
+ if(!degenerate(el)) {
+ point[] ep;
+ for (int i=0; i<360; i+=72) {
+ ep.push(t*angpoint(el,i));
+ }
+ ellipse oe=ellipse(ep[0],ep[1],ep[2],ep[3],ep[4]);
+ if(angpoint(oe,0) != ep[0]) return ellipse(oe.F2,oe.F1,oe.a);
+ return oe;
+ }
+ return ellipse(t*el.l.A,t*el.l.B,infinity);
+}
+
+/*<asyxml><operator type="parabola" signature="*(transform,parabola)"><code></asyxml>*/
+parabola operator *(transform t, parabola p)
+{/*<asyxml></code><documentation>Provide transform*parabola.</documentation></operator></asyxml>*/
+ point[] P;
+ P.push(t*angpoint(p,45));
+ P.push(t*angpoint(p,-45));
+ P.push(t*angpoint(p,180));
+ return parabola(P[0],P[1],P[2],t*p.D);
+}
+
+/*<asyxml><operator type="ellipse" signature="*(transform,circle)"><code></asyxml>*/
+ellipse operator *(transform t, circle c)
+{/*<asyxml></code><documentation>Provide transform*circle.
+ For example, 'circle C=scale(2)*circle' and 'ellipse E=xscale(2)*circle' are valid
+ but 'circle C=xscale(2)*circle' is invalid.</documentation></operator></asyxml>*/
+ return t*((ellipse)c);
+}
+
+/*<asyxml><operator type="hyperbola" signature="*(transform,hyperbola)"><code></asyxml>*/
+hyperbola operator *(transform t, hyperbola h)
+{/*<asyxml></code><documentation>Provide transform*hyperbola.</documentation></operator></asyxml>*/
+ point[] ep;
+ for (int i=90; i<=270; i+=45) {
+ ep.push(t*angpoint(h,i));
+ }
+ hyperbola oe=hyperbola(ep[0],ep[1],ep[2],ep[3],ep[4]);
+ if(angpoint(oe,90) != ep[0]) return hyperbola(oe.F2,oe.F1,oe.a);
+ return oe;
+}
+
+/*<asyxml><operator type="conic" signature="*(transform,conic)"><code></asyxml>*/
+conic operator *(transform t, conic co)
+{/*<asyxml></code><documentation>Provide transform*conic.</documentation></operator></asyxml>*/
+ if(co.e < 1) return (t*((ellipse)co));
+ if(co.e == 1) return (t*((parabola)co));
+ return (t*((hyperbola)co));
+}
+
+/*<asyxml><operator type="ellipse" signature="*(real,ellipse)"><code></asyxml>*/
+ellipse operator *(real x, ellipse el)
+{/*<asyxml></code><documentation>Identical but more efficient (rapid) than 'scale(x,el.C)*el'.</documentation></operator></asyxml>*/
+ return degenerate(el) ? el : ellipse(el.C,x*el.a,x*el.b,el.angle);
+}
+
+/*<asyxml><operator type="ellipse" signature="/(ellipse,real)"><code></asyxml>*/
+ellipse operator /(ellipse el, real x)
+{/*<asyxml></code><documentation>Identical but more efficient (rapid) than 'scale(1/x,el.C)*el'.</documentation></operator></asyxml>*/
+ return degenerate(el) ? el : ellipse(el.C,el.a/x,el.b/x,el.angle);
+}
+
+/*<asyxml><function type="path" signature="arcfromcenter(ellipse,real,real,int,bool)"><code></asyxml>*/
+path arcfromcenter(ellipse el, real angle1, real angle2,
+ bool direction=CCW,
+ int n=ellipsenodesnumber(el.a,el.b,angle1,angle2,direction))
+{/*<asyxml></code><documentation>Return the path of the ellipse 'el' from angle1 to angle2 in degrees,
+ drawing in the given direction, with n nodes.
+ The angles are mesured relatively to the axis (C,x-axis) where C is
+ the center of the ellipse.</documentation></function></asyxml>*/
+ if(degenerate(el)) abort("arcfromcenter: can not convert degenerated ellipse to path.");
+ guide op;
+ coordsys Rp=coordsys(el);
+ if (n < 1) return op;
+ if (angle1 > angle2)
+ return reverse(arcfromcenter(el,angle2,angle1,!direction,n));
+ real a1=direction ? radians(angle1) : radians(angle2);
+ real a2=direction ? radians(angle2) : radians(angle1)+2*pi;
+ real step=(a2-a1)/(n != 1 ? n-1 : 1);
+ real a,r;
+ real da=radians(el.angle);
+ for (int i=0; i < n; ++i) {
+ a=a1+i*step;
+ r=el.b/sqrt(1-(el.e*cos(a))^2);
+ op=op..Rp*Rp.polar(r,a+da);
+ }
+ return shift(el.C.x*Rp.i+el.C.y*Rp.j)*(direction ? op : reverse(op));
+}
+
+/*<asyxml><function type="path" signature="arcfromcenter(hyperbola,real,real,int,bool)"><code></asyxml>*/
+path arcfromcenter(hyperbola h, real angle1, real angle2,
+ int n=hyperbolanodesnumber(h,angle1,angle2),
+ bool direction=CCW)
+{/*<asyxml></code><documentation>Return the path of the hyperbola 'h' from angle1 to angle2 in degrees,
+ drawing in the given direction, with n nodes.
+ The angles are mesured relatively to the axis (C,x-axis) where C is
+ the center of the hyperbola.</documentation></function></asyxml>*/
+ guide op;
+ coordsys Rp=coordsys(h);
+ if (n < 1) return op;
+ if (angle1 > angle2) {
+ path g=reverse(arcfromcenter(h,angle2,angle1,n,!direction));
+ return g == nullpath ? g : reverse(g);
+ }
+ real a1=direction ? radians(angle1) : radians(angle2);
+ real a2=direction ? radians(angle2) : radians(angle1)+2*pi;
+ real step=(a2-a1)/(n != 1 ? n-1 : 1);
+ real a,r;
+ typedef guide interpolate(... guide[]);
+ interpolate join=operator ..;
+ real da=radians(h.angle);
+ for (int i=0; i < n; ++i) {
+ a=a1+i*step;
+ r=(h.b*cos(a))^2-(h.a*sin(a))^2;
+ if(r > epsgeo) {
+ r=sqrt(h.a^2*h.b^2/r);
+ op=join(op,Rp*Rp.polar(r,a+da));
+ join=operator ..;
+ } else join=operator --;
+ }
+ return shift(h.C.x*Rp.i+h.C.y*Rp.j)*
+ (direction ? op : op == nullpath ? op : reverse(op));
+}
+
+/*<asyxml><function type="path" signature="arcfromcenter(explicit conic,real,real,int,bool)"><code></asyxml>*/
+path arcfromcenter(explicit conic co, real angle1, real angle2,
+ int n, bool direction=CCW)
+{/*<asyxml></code><documentation>Use arcfromcenter(ellipse,...) or arcfromcenter(hyperbola,...) depending of
+ the eccentricity of 'co'.</documentation></function></asyxml>*/
+ path g;
+ if(co.e < 1)
+ g=arcfromcenter((ellipse)co,angle1,
+ angle2,direction,n);
+ else if(co.e > 1)
+ g=arcfromcenter((hyperbola)co,angle1,
+ angle2,n,direction);
+ else abort("arcfromcenter: does not exist for a parabola.");
+ return g;
+}
+
+/*<asyxml><constant type="polarconicroutine" signature="fromCenter"><code></asyxml>*/
+restricted polarconicroutine fromCenter=arcfromcenter;/*<asyxml></code><documentation></documentation></constant></asyxml>*/
+/*<asyxml><constant type="polarconicroutine" signature="fromFocus"><code></asyxml>*/
+restricted polarconicroutine fromFocus=arcfromfocus;/*<asyxml></code><documentation></documentation></constant></asyxml>*/
+
+/*<asyxml><function type="bqe" signature="equation(ellipse)"><code></asyxml>*/
+bqe equation(ellipse el)
+{/*<asyxml></code><documentation>Return the coefficients of the equation of the ellipse in its coordinate system:
+ bqe.a[0]*x^2 + bqe.a[1]*x*y + bqe.a[2]*y^2 + bqe.a[3]*x + bqe.a[4]*y + bqe.a[5]=0.
+ One can change the coordinate system of 'bqe' using the routine 'changecoordsys'.</documentation></function></asyxml>*/
+ pair[] pts;
+ for (int i=0; i<360; i+=72)
+ pts.push(locate(angpoint(el,i)));
+
+ real[][] M;
+ real[] x;
+ for (int i=0; i < 5; ++i) {
+ M[i]=new real[] {pts[i].x*pts[i].y,pts[i].y^2,pts[i].x,pts[i].y,1};
+ x[i]=-pts[i].x^2;
+ }
+ real[] coef=solve(M,x);
+ bqe bqe=changecoordsys(coordsys(el),
+ bqe(defaultcoordsys,
+ 1,coef[0],coef[1],coef[2],coef[3],coef[4]));
+ bqe.a=approximate(bqe.a);
+ return bqe;
+}
+
+/*<asyxml><function type="bqe" signature="equation(parabola)"><code></asyxml>*/
+bqe equation(parabola p)
+{/*<asyxml></code><documentation>Return the coefficients of the equation of the parabola in its coordinate system.
+ bqe.a[0]*x^2 + bqe.a[1]*x*y + bqe.a[2]*y^2 + bqe.a[3]*x + bqe.a[4]*y + bqe.a[5]=0
+ One can change the coordinate system of 'bqe' using the routine 'changecoordsys'.</documentation></function></asyxml>*/
+ coordsys R=canonicalcartesiansystem(p);
+ parabola tp=changecoordsys(R,p);
+ point A=projection(tp.D)*point(R,(0,0));
+ real a=abs(A);
+ return changecoordsys(coordsys(p),
+ bqe(R,0,0,1,-4*a,0,0));
+}
+
+/*<asyxml><function type="bqe" signature="equation(hyperbola)"><code></asyxml>*/
+bqe equation(hyperbola h)
+{/*<asyxml></code><documentation>Return the coefficients of the equation of the hyperbola in its coordinate system.
+ bqe.a[0]*x^2 + bqe.a[1]*x*y + bqe.a[2]*y^2 + bqe.a[3]*x + bqe.a[4]*y + bqe.a[5]=0
+ One can change the coordinate system of 'bqe' using the routine 'changecoordsys'.</documentation></function></asyxml>*/
+ coordsys R=canonicalcartesiansystem(h);
+ return changecoordsys(coordsys(h),
+ bqe(R,1/h.a^2,0,-1/h.b^2,0,0,-1));
+}
+
+/*<asyxml><operator type="path" signature="cast(ellipse)"><code></asyxml>*/
+path operator cast(ellipse el)
+{/*<asyxml></code><documentation>Cast ellipse to path.</documentation></operator></asyxml>*/
+ if(degenerate(el))
+ abort("Casting degenerated ellipse to path is not possible.");
+ int n=el.e == 0 ? circlenodesnumber(el.a) : ellipsenodesnumber(el.a,el.b);
+ return arcfromcenter(el,0.0,360,CCW,n)&cycle;
+}
+
+/*<asyxml><operator type="path" signature="cast(circle)"><code></asyxml>*/
+path operator cast(circle c)
+{/*<asyxml></code><documentation>Cast circle to path.</documentation></operator></asyxml>*/
+ return (path)((ellipse)c);
+}
+
+/*<asyxml><function type="real[]" signature="bangles(picture,parabola)"><code></asyxml>*/
+real[] bangles(picture pic=currentpicture, parabola p)
+{/*<asyxml></code><documentation>Return the array {ma, Ma} where 'ma' and 'Ma' are respectively
+ the smaller and the larger angles for which the parabola 'p' is included
+ in the bounding box of the picture 'pic'.</documentation></function></asyxml>*/
+ pair bmin,bmax;
+ pair[] b;
+ if (p.bmin == p.bmax) {
+ bmin=pic.userMin();
+ bmax=pic.userMax();
+ } else {
+ bmin=p.bmin;bmax=p.bmax;
+ }
+ if(bmin.x == bmax.x || bmin.y == bmax.y || !finite(abs(bmin)) || !finite(abs(bmax)))
+ return new real[] {0,0};
+ b[0]=bmin;
+ b[1]=(bmax.x,bmin.y);
+ b[2]=bmax;
+ b[3]=(bmin.x,bmax.y);
+ real[] eq=changecoordsys(defaultcoordsys,equation(p)).a;
+ pair[] inter;
+ for (int i=0; i < 4; ++i) {
+ pair[] tmp=intersectionpoints(b[i],b[(i+1)%4],eq);
+ for (int j=0; j < tmp.length; ++j) {
+ if(dot(b[i]-tmp[j],b[(i+1)%4]-tmp[j]) <= epsgeo)
+ inter.push(tmp[j]);
+ }
+ }
+ pair F=p.F, V=p.V;
+ real d=degrees(F-V);
+ real[] a=sequence(new real(int n){
+ return (360-d+degrees(inter[n]-F))%360;
+ }, inter.length);
+ real ma=a.length != 0 ? min(a) : 0, Ma= a.length != 0 ? max(a) : 0;
+ return new real[] {ma,Ma};
+}
+
+/*<asyxml><function type="real[][]" signature="bangles(picture,hyperbola)"><code></asyxml>*/
+real[][] bangles(picture pic=currentpicture, hyperbola h)
+{/*<asyxml></code><documentation>Return the array {{ma1, Ma1}, {ma2, Ma2}} where 'maX' and 'MaX' are respectively
+ the smaller and the bigger angles (from h.FX) for which the hyperbola 'h' is included
+ in the bounding box of the picture 'pic'.</documentation></function></asyxml>*/
+ pair bmin,bmax;
+ pair[] b;
+ if (h.bmin == h.bmax) {
+ bmin=pic.userMin();
+ bmax=pic.userMax();
+ } else {
+ bmin=h.bmin;bmax=h.bmax;
+ }
+ if(bmin.x == bmax.x || bmin.y == bmax.y || !finite(abs(bmin)) || !finite(abs(bmax)))
+ return new real[][] {{0,0}, {0,0}};
+ b[0]=bmin;
+ b[1]=(bmax.x,bmin.y);
+ b[2]=bmax;
+ b[3]=(bmin.x,bmax.y);
+ real[] eq=changecoordsys(defaultcoordsys,equation(h)).a;
+ pair[] inter0,inter1;
+ pair C=locate(h.C);
+ pair F1=h.F1;
+ for (int i=0; i < 4; ++i) {
+ pair[] tmp=intersectionpoints(b[i],b[(i+1)%4],eq);
+ for (int j=0; j < tmp.length; ++j) {
+ if(dot(b[i]-tmp[j],b[(i+1)%4]-tmp[j]) <= epsgeo) {
+ if(dot(F1-C,tmp[j]-C) > 0) inter0.push(tmp[j]);
+ else inter1.push(tmp[j]);
+ }
+ }
+ }
+ real d=degrees(F1-C);
+ real[] ma, Ma;
+ pair[][] inter=new pair[][] {inter0, inter1};
+ for (int i=0; i < 2; ++i) {
+ real[] a=sequence(new real(int n){
+ return (360-d+degrees(inter[i][n]-F1))%360;
+ },inter[i].length);
+ ma[i]=a.length != 0 ? min(a) : 0;
+ Ma[i]= a.length != 0 ? max(a) : 0;
+ }
+ return new real[][] {{ma[0],Ma[0]}, {ma[1],Ma[1]}};
+}
+
+/*<asyxml><operator type="path" signature="cast(parabola)"><code></asyxml>*/
+path operator cast(parabola p)
+{/*<asyxml></code><documentation>Cast parabola to path.
+ If possible, the returned path is restricted to the actual bounding box
+ of the current picture if the variables 'p.bmin' and 'p.bmax' are not set else
+ the bounding box of box(p.bmin, p.bmax) is used instead.</documentation></operator></asyxml>*/
+ real[] bangles=bangles(p);
+ int n=parabolanodesnumber(p,bangles[0],bangles[1]);
+ return arcfromfocus(p,bangles[0],bangles[1],n,CCW);
+}
+
+
+/*<asyxml><function type="void" signature="draw(picture,Label,circle,align,pen,arrowbar,arrowbar,margin,Label,marker)"><code></asyxml>*/
+void draw(picture pic=currentpicture, Label L="",circle c,
+ align align=NoAlign, pen p=currentpen,
+ arrowbar arrow=None, arrowbar bar=None,
+ margin margin=NoMargin, Label legend="", marker marker=nomarker)
+{/*<asyxml></code><documentation></documentation></function></asyxml>*/
+ if(degenerate(c)) draw(pic,L,c.l,align,p,arrow,legend,marker);
+ else draw(pic,L,(path)c,align,p,arrow,bar,margin,legend,marker);
+}
+
+/*<asyxml><function type="void" signature="draw(picture,Label,ellipse,align,pen,arrowbar,arrowbar,margin,Label,marker)"><code></asyxml>*/
+void draw(picture pic=currentpicture, Label L="",ellipse el,
+ align align=NoAlign, pen p=currentpen,
+ arrowbar arrow=None, arrowbar bar=None,
+ margin margin=NoMargin, Label legend="", marker marker=nomarker)
+{/*<asyxml></code><documentation></documentation>Draw the ellipse 'el' if it is not degenerated else draw 'el.l'.</function></asyxml>*/
+ if(degenerate(el)) draw(pic,L,el.l,align,p,arrow,legend,marker);
+ else draw(pic,L,(path)el,align,p,arrow,bar,margin,legend,marker);
+}
+
+/*<asyxml><function type="void" signature="draw(picture,Label,parabola,align,pen,arrowbar,arrowbar,margin,Label,marker)"><code></asyxml>*/
+void draw(picture pic=currentpicture, Label L="",parabola parabola,
+ align align=NoAlign, pen p=currentpen,
+ arrowbar arrow=None, arrowbar bar=None,
+ margin margin=NoMargin, Label legend="", marker marker=nomarker)
+{/*<asyxml></code><documentation>Draw the parabola 'p' on 'pic' without (if possible) altering the
+ size of picture pic.</documentation></function></asyxml>*/
+ pic.add(new void (frame f, transform t, transform, pair m, pair M) {
+ // Reduce the bounds by the size of the pen and the margins.
+ m -= min(p); M -= max(p);
+ parabola.bmin=inverse(t)*m; parabola.bmax=inverse(t)*M;
+ picture tmp;
+ draw(tmp,L,t*(path) parabola,align,p,arrow,bar,NoMargin,legend,marker);
+ add(f,tmp.fit());
+ });
+ if(pic.userMin.x != pic.userMax.x & pic.userMin.y != pic.userMax.y &
+ !finite(abs(pic.userMin)) & !finite(abs(pic.userMax)))
+ pic.addBox(truepoint(SW), truepoint(NE));
+}
+
+/*<asyxml><operator type="path" signature="cast(hyperbola)"><code></asyxml>*/
+path operator cast(hyperbola h)
+{/*<asyxml></code><documentation>Cast hyperbola to path.
+ If possible, the returned path is restricted to the actual bounding box
+ of the current picture unless the variables 'h.bmin' and 'h.bmax'
+ are set; in this case the bounding box of box(h.bmin, h.bmax) is used instead.
+ Only the branch on the side of 'h.F1' is considered.</documentation></operator></asyxml>*/
+ real[][] bangles=bangles(h);
+ int n=hyperbolanodesnumber(h,bangles[0][0],bangles[0][1]);
+ return arcfromfocus(h,bangles[0][0],bangles[0][1],n,CCW);
+}
+
+/*<asyxml><function type="void" signature="draw(picture,Label,hyperbola,align,pen,arrowbar,arrowbar,margin,Label,marker)"><code></asyxml>*/
+void draw(picture pic=currentpicture, Label L="", hyperbola h,
+ align align=NoAlign, pen p=currentpen,
+ arrowbar arrow=None, arrowbar bar=None,
+ margin margin=NoMargin, Label legend="", marker marker=nomarker)
+{/*<asyxml></code><documentation>Draw the hyperbola 'h' on 'pic' without (if possible) altering the
+ size of the picture pic.</documentation></function></asyxml>*/
+ pic.add(new void (frame f, transform t, transform, pair m, pair M) {
+ // Reduce the bounds by the size of the pen and the margins.
+ m -= min(p); M -= max(p);
+ h.bmin=inverse(t)*m; h.bmax=inverse(t)*M;
+ picture tmp;
+ draw(tmp,L,t*(path) h,align,p,arrow,bar,NoMargin,legend,marker);
+ hyperbola ht=hyperbola(h.F2,h.F1,h.a);
+ ht.bmin=inverse(t)*m; ht.bmax=inverse(t)*M;
+ draw(tmp,"",t*(path) ht,align,p,arrow,bar,NoMargin,marker);
+ add(f,tmp.fit());
+ });
+ if(pic.userMin.x != pic.userMax.x & pic.userMin.y != pic.userMax.y &
+ !finite(abs(pic.userMin)) & !finite(abs(pic.userMax)))
+ pic.addBox(truepoint(SW), truepoint(NE));
+}
+
+/*<asyxml><function type="void" signature="draw(picture,Label,explicit conic,align,pen,arrowbar,arrowbar,margin,Label,marker)"><code></asyxml>*/
+void draw(picture pic=currentpicture, Label L="", explicit conic co,
+ align align=NoAlign, pen p=currentpen,
+ arrowbar arrow=None, arrowbar bar=None,
+ margin margin=NoMargin, Label legend="", marker marker=nomarker)
+{/*<asyxml></code><documentation>Use one of the routine 'draw(ellipse,...)',
+ 'draw(parabola,...)' or 'draw(hyperbola,...)' depending of the value of eccentricity of 'co'.</documentation></function></asyxml>*/
+ if(co.e == 0)
+ draw(pic,L,(circle)co,align,p,arrow,bar,margin,legend,marker);
+ else
+ if(co.e < 1) draw(pic,L,(ellipse)co,align,p,arrow,bar,margin,legend,marker);
+ else
+ if(co.e == 1) draw(pic,L,(parabola)co,align,p,arrow,bar,margin,legend,marker);
+ else
+ if(co.e > 1) draw(pic,L,(hyperbola)co,align,p,arrow,bar,margin,legend,marker);
+ else abort("draw: unknown conic.");
+}
+
+/*<asyxml><function type="int" signature="conicnodesnumber(conic,real,real)"><code></asyxml>*/
+int conicnodesnumber(conic co, real angle1, real angle2, bool dir=CCW)
+{/*<asyxml></code><documentation>Return the number of node to draw a conic arc.</documentation></function></asyxml>*/
+ int oi;
+ if(co.e == 0) {
+ circle c=(circle)co;
+ oi=circlenodesnumber(c.r,angle1,angle2);
+ } else if(co.e < 1) {
+ ellipse el=(ellipse)co;
+ oi=ellipsenodesnumber(el.a,el.b,angle1,angle2,dir);
+ } else if(co.e == 1) {
+ parabola p=(parabola)co;
+ oi=parabolanodesnumber(p, angle1, angle2);
+ } else {
+ hyperbola h=(hyperbola)co;
+ oi=hyperbolanodesnumber(h, angle1, angle2);
+ }
+ return oi;
+}
+
+/*<asyxml><operator type="path" signature="cast(conic)"><code></asyxml>*/
+path operator cast(conic co)
+{/*<asyxml></code><documentation>Cast conic section to path.</documentation></operator></asyxml>*/
+ if(co.e < 1) return (path)((ellipse)co);
+ if(co.e == 1) return (path)((parabola)co);
+ return (path)((hyperbola)co);
+}
+
+/*<asyxml><function type="bqe" signature="equation(explicit conic)"><code></asyxml>*/
+bqe equation(explicit conic co)
+{/*<asyxml></code><documentation>Return the coefficients of the equation of conic section in its coordinate system:
+ bqe.a[0]*x^2 + bqe.a[1]*x*y + bqe.a[2]*y^2 + bqe.a[3]*x + bqe.a[4]*y + bqe.a[5]=0.
+ One can change the coordinate system of 'bqe' using the routine 'changecoordsys'.</documentation></function></asyxml>*/
+ bqe obqe;
+ if(co.e == 0)
+ obqe=equation((circle)co);
+ else
+ if(co.e < 1) obqe=equation((ellipse)co);
+ else
+ if(co.e == 1) obqe=equation((parabola)co);
+ else
+ if(co.e > 1) obqe=equation((hyperbola)co);
+ else abort("draw: unknown conic.");
+ return obqe;
+}
+
+/*<asyxml><function type="string" signature="conictype(bqe)"><code></asyxml>*/
+string conictype(bqe bqe)
+{/*<asyxml></code><documentation>Returned values are "ellipse" or "parabola" or "hyperbola"
+ depending of the conic section represented by 'bqe'.</documentation></function></asyxml>*/
+ bqe lbqe=changecoordsys(defaultcoordsys,bqe);
+ string os="degenerated";
+ real a=lbqe.a[0], b=lbqe.a[1]/2, c=lbqe.a[2], d=lbqe.a[3]/2, f=lbqe.a[4]/2, g=lbqe.a[5];
+ real delta=a*c*g + b*f*d + d*b*f - (b^2*g + d^2*c + f^2*a);
+ if(abs(delta) < 10*epsgeo) return os;
+ real J=a*c-b^2;
+ real I=a+c;
+ if(J > epsgeo) {
+ if(delta/I < -epsgeo);
+ os="ellipse";
+ } else {
+ if(abs(J) < epsgeo) os="parabola"; else os="hyperbola";
+ }
+ return os;
+}
+
+/*<asyxml><function type="conic" signature="conic(point,point,point,point,point)"><code></asyxml>*/
+conic conic(point M1, point M2, point M3, point M4, point M5)
+{/*<asyxml></code><documentation>Return the conic passing through 'M1', 'M2', 'M3', 'M4' and 'M5' if the conic is not degenerated.</documentation></function></asyxml>*/
+ bqe bqe=bqe(M1,M2,M3,M4,M5);
+ string ct=conictype(bqe);
+ if(ct == "degenerated") abort("conic: degenerated conic passing through five points.");
+ if(ct == "ellipse") return ellipse(bqe);
+ if(ct == "parabola") return parabola(bqe);
+ return hyperbola(bqe);
+}
+
+/*<asyxml><function type="coordsys" signature="canonicalcartesiansystem(hyperbola)"><code></asyxml>*/
+coordsys canonicalcartesiansystem(explicit conic co)
+{/*<asyxml></code><documentation>Return the canonical cartesian system of the conic 'co'.</documentation></function></asyxml>*/
+ if(co.e < 1) return canonicalcartesiansystem((ellipse)co);
+ else if(co.e == 1) return canonicalcartesiansystem((parabola)co);
+ return canonicalcartesiansystem((hyperbola)co);
+}
+
+/*<asyxml><function type="bqe" signature="canonical(bqe)"><code></asyxml>*/
+bqe canonical(bqe bqe)
+{/*<asyxml></code><documentation>Return the bivariate quadratic equation relative to the
+ canonical coordinate system of the conic section represented by 'bqe'.</documentation></function></asyxml>*/
+ string type=conictype(bqe);
+ if(type == "") abort("canonical: the equation can not be performed.");
+ bqe obqe;
+ if(type == "ellipse") {
+ ellipse el=ellipse(bqe);
+ obqe=changecoordsys(canonicalcartesiansystem(el),equation(el));
+ } else {
+ if(type == "parabola") {
+ parabola p=parabola(bqe);
+ obqe=changecoordsys(canonicalcartesiansystem(p),equation(p));
+ } else {
+ hyperbola h=hyperbola(bqe);
+ obqe=changecoordsys(canonicalcartesiansystem(h),equation(h));
+ }
+ }
+ return obqe;
+}
+
+/*<asyxml><function type="conic" signature="conic(bqe)"><code></asyxml>*/
+conic conic(bqe bqe)
+{/*<asyxml></code><documentation>Return the conic section represented by the bivariate quartic equation 'bqe'.</documentation></function></asyxml>*/
+ string type=conictype(bqe);
+ if(type == "") abort("canonical: the equation can not be performed.");
+ conic oc;
+ if(type == "ellipse") {
+ oc=ellipse(bqe);
+ } else {
+ if(type == "parabola") oc=parabola(bqe); else oc=hyperbola(bqe);
+ }
+ return oc;
+}
+
+/*<asyxml><function type="real" signature="arclength(circle)"><code></asyxml>*/
+real arclength(circle c)
+{/*<asyxml></code><documentation></documentation></function></asyxml>*/
+ return c.r*2*pi;
+}
+
+/*<asyxml><function type="real" signature="focusToCenter(ellipse,real)"><code></asyxml>*/
+real focusToCenter(ellipse el, real a)
+{/*<asyxml></code><documentation>Return the angle relatively to the center of 'el' for the angle 'a'
+ given relatively to the focus of 'el'.</documentation></function></asyxml>*/
+ pair p=point(fromFocus(el,a,a,1,CCW),0);
+ pair c=locate(el.C);
+ real d=degrees(p-c)-el.angle;
+ d=abs(d) < epsgeo ? 0 : d; // Avoid -1e-15
+ return d%(sgnd(a)*360);
+}
+
+/*<asyxml><function type="real" signature="centerToFocus(ellipse,real)"><code></asyxml>*/
+real centerToFocus(ellipse el, real a)
+{/*<asyxml></code><documentation>Return the angle relatively to the focus of 'el' for the angle 'a'
+ given relatively to the center of 'el'.</documentation></function></asyxml>*/
+ pair P=point(fromCenter(el,a,a,1,CCW),0);
+ pair F1=locate(el.F1);
+ pair F2=locate(el.F2);
+ real d=degrees(P-F1)-degrees(F2-F1);
+ d=abs(d) < epsgeo ? 0 : d; // Avoid -1e-15
+ return d%(sgnd(a)*360);
+}
+
+/*<asyxml><function type="real" signature="arclength(ellipse)"><code></asyxml>*/
+real arclength(ellipse el)
+{/*<asyxml></code><documentation></documentation></function></asyxml>*/
+ return degenerate(el) ? infinity : 4*el.a*elle(pi/2,el.e);
+}
+
+/*<asyxml><function type="real" signature="arclength(ellipse,real,real,bool,polarconicroutine)"><code></asyxml>*/
+real arclength(ellipse el, real angle1, real angle2,
+ bool direction=CCW,
+ polarconicroutine polarconicroutine=currentpolarconicroutine)
+{/*<asyxml></code><documentation>Return the length of the arc of the ellipse between 'angle1'
+ and 'angle2'.
+ 'angle1' and 'angle2' must be in the interval ]-360;+oo[ if polarconicroutine=fromFocus,
+ ]-oo;+oo[ if polarconicroutine=fromCenter.</documentation></function></asyxml>*/
+ if(degenerate(el)) return infinity;
+ if(angle1 > angle2) return arclength(el,angle2,angle1,!direction,polarconicroutine);
+ // path g;int n=1000;
+ // if(el.e == 0) g=arcfromcenter(el,angle1,angle2,n,direction);
+ // if(el.e != 1) g=polarconicroutine(el,angle1,angle2,n,direction);
+ // write("with path=",arclength(g));
+ if(polarconicroutine == fromFocus) {
+ // dot(point(fromFocus(el,angle1,angle1,1,CCW),0),2mm+blue);
+ // dot(point(fromFocus(el,angle2,angle2,1,CCW),0),2mm+blue);
+ // write("fromfocus1=",angle1);
+ // write("fromfocus2=",angle2);
+ real gle1=focusToCenter(el,angle1);
+ real gle2=focusToCenter(el,angle2);
+ if((gle1-gle2)*(angle1-angle2) > 0) {
+ angle1=gle1; angle2=gle2;
+ } else {
+ angle1=gle2; angle2=gle1;
+ }
+ // dot(point(fromCenter(el,angle1,angle1,1,CCW),0),1mm+red);
+ // dot(point(fromCenter(el,angle2,angle2,1,CCW),0),1mm+red);
+ // write("fromcenter1=",angle1);
+ // write("fromcenter2=",angle2);
+ }
+ if(angle1 < 0 || angle2 < 0) return arclength(el,180+angle1,180+angle2,direction,fromCenter);
+ real a1=direction ? angle1 : angle2;
+ real a2=direction ? angle2 : angle1+360;
+ real elleq=el.a*elle(pi/2,el.e);
+ real S(real a)
+ {//Return the arclength from 0 to the angle 'a' (in degrees)
+ // given form the center of the ellipse.
+ real gle=atan(el.a*Tan(a)/el.b)+
+ pi*(((a%90 == 0 && a != 0) ? floor(a/90)-1 : floor(a/90)) -
+ ((a%180 == 0) ? 0 : floor(a/180)) -
+ (a%360 == 0 ? floor(a/(360)) : 0));
+ /* // Uncomment to visualize the used branches
+ unitsize(2cm,1cm);
+ import graph;
+
+ real xmin=0, xmax=3pi;
+
+ xlimits( xmin,xmax);
+ ylimits( 0,10);
+ yaxis( "y" ,LeftRight(),RightTicks(pTick=.8red,ptick=lightgrey,extend=true));
+ xaxis( "x-value",BottomTop(),Ticks(Label("$%.2f$",red),Step=pi/2,step=pi/4,pTick=.8red,ptick=lightgrey,extend=true));
+
+ real p2=pi/2;
+ real f(real t)
+ {
+ return atan(0.6*tan(t))+
+ pi*((t%p2 == 0 && t != 0) ? floor(t/p2)-1 : floor(t/p2)) -
+ ((t%pi == 0) ? 0 : pi*floor(t/pi)) - (t%(2pi) == 0 ? pi*floor(t/(2*pi)) : 0);
+ }
+
+ draw(graph(f,xmin,xmax,100));
+ write(degrees(f(pi/2)));
+ write(degrees(f(pi)));
+ write(degrees(f(3pi/2)));
+ write(degrees(f(2pi)));
+ draw(graph(new real(real t){return t;},xmin,xmax,3));
+ */
+ return elleq-el.a*elle(pi/2-gle,el.e);
+ }
+ return S(a2)-S(a1);
+}
+
+/*<asyxml><function type="real" signature="arclength(parabola,real)"><code></asyxml>*/
+real arclength(parabola p, real angle)
+{/*<asyxml></code><documentation>Return the arclength from 180 to 'angle' given from focus in the
+ canonical coordinate system of 'p'.</documentation></function></asyxml>*/
+ real a=p.a; /* In canonicalcartesiansystem(p) the equation of p
+ is x=y^2/(4a) */
+ // integrate(sqrt(1+(x/(2*a))^2),x);
+ real S(real t){return 0.5*t*sqrt(1+t^2/(4*a^2))+a*asinh(t/(2*a));}
+ real R(real gle){return 2*a/(1-Cos(gle));}
+ real t=Sin(angle)*R(angle);
+ return S(t);
+}
+
+/*<asyxml><function type="real" signature="arclength(parabola,real,real)"><code></asyxml>*/
+real arclength(parabola p, real angle1, real angle2)
+{/*<asyxml></code><documentation>Return the arclength from 'angle1' to 'angle2' given from
+ focus in the canonical coordinate system of 'p'</documentation></function></asyxml>*/
+ return arclength(p,angle1)-arclength(p,angle2);
+}
+
+/*<asyxml><function type="real" signature="arclength(parabola p)"><code></asyxml>*/
+real arclength(parabola p)
+{/*<asyxml></code><documentation>Return the length of the arc of the parabola bounded to the bounding
+ box of the current picture.</documentation></function></asyxml>*/
+ real[] b=bangles(p);
+ return arclength(p,b[0],b[1]);
+}
+// *........................CONICS.........................*
+// *=======================================================*
+
+// *=======================================================*
+// *.......................ABSCISSA........................*
+/*<asyxml><struct signature="abscissa"><code></asyxml>*/
+struct abscissa
+{/*<asyxml></code><documentation>Provide abscissa structure on a curve used in the routine-like 'point(object,abscissa)'
+ where object can be 'line', 'segment', 'ellipse', 'circle', 'conic'...</documentation><property type="real" signature="x"><code></asyxml>*/
+ real x;/*<asyxml></code><documentation>The abscissa value.</documentation></property><property type="int" signature="system"><code></asyxml>*/
+ int system;/*<asyxml></code><documentation>0=relativesystem; 1=curvilinearsystem; 2=angularsystem; 3=nodesystem</documentation></property><property type="polarconicroutine" signature="polarconicroutine"><code></asyxml>*/
+ polarconicroutine polarconicroutine=fromCenter;/*<asyxml></code><documentation>The routine used with angular system and two foci conic section.
+ Possible values are 'formCenter' and 'formFocus'.</documentation></property></asyxml>*/
+ /*<asyxml><method type="abscissa" signature="copy()"><code></asyxml>*/
+ abscissa copy()
+ {/*<asyxml></code><documentation>Return a copy of this abscissa.</documentation></method></asyxml>*/
+ abscissa oa=new abscissa;
+ oa.x=this.x;
+ oa.system=this.system;
+ oa.polarconicroutine=this.polarconicroutine;
+ return oa;
+ }
+}/*<asyxml></struct></asyxml>*/
+
+/*<asyxml><constant type="int" signature="relativesystem, curvilinearsystem, angularsystem, nodesystem"><code></asyxml>*/
+restricted int relativesystem=0, curvilinearsystem=1, angularsystem=2, nodesystem=3;/*<asyxml></code><documentation>Constant used to set the abscissa system.</documentation></constant></asyxml>*/
+
+/*<asyxml><operator type="abscissa" signature="cast(explicit position)"><code></asyxml>*/
+abscissa operator cast(explicit position position)
+{/*<asyxml></code><documentation>Cast position to abscissa.
+ If 'position' is relative, the abscissa is relative else it's a curvilinear abscissa.</documentation></operator></asyxml>*/
+ abscissa oarcc;
+ oarcc.x=position.position.x;
+ oarcc.system=position.relative ? relativesystem : curvilinearsystem;
+ return oarcc;
+}
+
+/*<asyxml><operator type="abscissa" signature="+(real,explicit abscissa)"><code></asyxml>*/
+abscissa operator +(real x, explicit abscissa a)
+{/*<asyxml></code><documentation>Provide 'real+abscissa'.
+ Return abscissa b so that b.x=a.x+x.
+ +(explicit abscissa,real), -(real,explicit abscissa) and -(explicit abscissa,real) are also defined.</documentation></operator></asyxml>*/
+ abscissa oa=a.copy();
+ oa.x=a.x+x;
+ return oa;
+}
+abscissa operator +(explicit abscissa a, real x)
+{
+ return x+a;
+}
+abscissa operator +(int x, explicit abscissa a)
+{
+ return ((real)x)+a;
+}
+abscissa operator +(explicit abscissa a, int x)
+{
+ return ((real)x)+a;
+}
+
+/*<asyxml><operator type="abscissa" signature="-(explicit abscissa a)"><code></asyxml>*/
+abscissa operator -(explicit abscissa a)
+{/*<asyxml></code><documentation>Return the abscissa b so that b.x=-a.x.</documentation></operator></asyxml>*/
+ abscissa oa;
+ oa.system=a.system;
+ oa.x=-a.x;
+ return oa;
+}
+
+abscissa operator -(real x, explicit abscissa a)
+{
+ abscissa oa;
+ oa.system=a.system;
+ oa.x=x-a.x;
+ return oa;
+}
+abscissa operator -(explicit abscissa a, real x)
+{
+ abscissa oa;
+ oa.system=a.system;
+ oa.x=a.x-x;
+ return oa;
+}
+abscissa operator -(int x, explicit abscissa a)
+{
+ return ((real)x)-a;
+}
+abscissa operator -(explicit abscissa a, int x)
+{
+ return a-((real)x);
+}
+
+/*<asyxml><operator type="abscissa" signature="*(real,abscissa)"><code></asyxml>*/
+abscissa operator *(real x, explicit abscissa a)
+{/*<asyxml></code><documentation>Provide 'real*abscissa'.
+ Return abscissa b so that b.x=x*a.x.
+ *(explicit abscissa,real), /(real,explicit abscissa) and /(explicit abscissa,real) are also defined.</documentation></operator></asyxml>*/
+ abscissa oa;
+ oa.system=a.system;
+ oa.x=a.x*x;
+ return oa;
+}
+abscissa operator *(explicit abscissa a, real x)
+{
+ return x*a;
+}
+
+abscissa operator *(int x, explicit abscissa a)
+{
+ return ((real)x)*a;
+}
+abscissa operator *(explicit abscissa a, int x)
+{
+ return ((real)x)*a;
+}
+
+abscissa operator /(real x, explicit abscissa a)
+{
+ abscissa oa;
+ oa.system=a.system;
+ oa.x=x/a.x;
+ return oa;
+}
+abscissa operator /(explicit abscissa a, real x)
+{
+ abscissa oa;
+ oa.system=a.system;
+ oa.x=a.x/x;
+ return oa;
+}
+
+abscissa operator /(int x, explicit abscissa a)
+{
+ return ((real)x)/a;
+}
+abscissa operator /(explicit abscissa a, int x)
+{
+ return a/((real)x);
+}
+
+/*<asyxml><function type="abscissa" signature="relabscissa(real)"><code></asyxml>*/
+abscissa relabscissa(real x)
+{/*<asyxml></code><documentation>Return a relative abscissa.</documentation></function></asyxml>*/
+ return (abscissa)(Relative(x));
+}
+abscissa relabscissa(int x)
+{
+ return (abscissa)(Relative(x));
+}
+
+/*<asyxml><function type="abscissa" signature="curabscissa(real)"><code></asyxml>*/
+abscissa curabscissa(real x)
+{/*<asyxml></code><documentation>Return a curvilinear abscissa.</documentation></function></asyxml>*/
+ return (abscissa)((position)x);
+}
+abscissa curabscissa(int x)
+{
+ return (abscissa)((position)x);
+}
+
+/*<asyxml><function type="abscissa" signature="angabscissa(real,polarconicroutine)"><code></asyxml>*/
+abscissa angabscissa(real x, polarconicroutine polarconicroutine=currentpolarconicroutine)
+{/*<asyxml></code><documentation>Return a angular abscissa.</documentation></function></asyxml>*/
+ abscissa oarcc;
+ oarcc.x=x;
+ oarcc.polarconicroutine=polarconicroutine;
+ oarcc.system=angularsystem;
+ return oarcc;
+}
+abscissa angabscissa(int x, polarconicroutine polarconicroutine=currentpolarconicroutine)
+{
+ return angabscissa((real)x, polarconicroutine);
+}
+
+/*<asyxml><function type="abscissa" signature="nodabscissa(real)"><code></asyxml>*/
+abscissa nodabscissa(real x)
+{/*<asyxml></code><documentation>Return an abscissa as time on the path.</documentation></function></asyxml>*/
+ abscissa oarcc;
+ oarcc.x=x;
+ oarcc.system=nodesystem;
+ return oarcc;
+}
+abscissa nodabscissa(int x)
+{
+ return nodabscissa((real)x);
+}
+
+/*<asyxml><operator type="abscissa" signature="cast(real)"><code></asyxml>*/
+abscissa operator cast(real x)
+{/*<asyxml></code><documentation>Cast real to abscissa, precisely 'nodabscissa'.</documentation></operator></asyxml>*/
+ return nodabscissa(x);
+}
+abscissa operator cast(int x)
+{
+ return nodabscissa((real)x);
+}
+
+/*<asyxml><function type="point" signature="point(circle,abscissa)"><code></asyxml>*/
+point point(circle c, abscissa l)
+{/*<asyxml></code><documentation>Return the point of 'c' which has the abscissa 'l.x'
+ according to the abscissa system 'l.system'.</documentation></function></asyxml>*/
+ coordsys R=c.C.coordsys;
+ if (l.system == nodesystem)
+ return point(R,point((path)c,l.x)/R);
+ if (l.system == relativesystem)
+ return c.C+point(R,R.polar(c.r,2*pi*l.x));
+ if (l.system == curvilinearsystem)
+ return c.C+point(R,R.polar(c.r,l.x/c.r));
+ if (l.system == angularsystem)
+ return c.C+point(R,R.polar(c.r,radians(l.x)));
+ abort("point: bad abscissa system.");
+ return (0,0);
+}
+
+/*<asyxml><function type="point" signature="point(ellipse,abscissa)"><code></asyxml>*/
+point point(ellipse el, abscissa l)
+{/*<asyxml></code><documentation>Return the point of 'el' which has the abscissa 'l.x'
+ according to the abscissa system 'l.system'.</documentation></function></asyxml>*/
+ if(el.e == 0) return point((circle)el, l);
+ coordsys R=coordsys(el);
+ if (l.system == nodesystem)
+ return point(R,point((path)el,l.x)/R);
+ if (l.system == relativesystem) {
+ return point(el,curabscissa((l.x%1)*arclength(el)));
+ }
+ if (l.system == curvilinearsystem) {
+ real a1=0, a2=360, cx=0;
+ real aout=a1;
+ real x=abs(l.x)%arclength(el);
+ while (abs(cx-x) > epsgeo) {
+ aout=(a1+a2)/2;
+ cx=arclength(el,0,aout,CCW,fromCenter); //fromCenter is speeder
+ if(cx > x) a2=(a1+a2)/2; else a1=(a1+a2)/2;
+ }
+ path pel=fromCenter(el,sgn(l.x)*aout,sgn(l.x)*aout,1,CCW);
+ return point(R,point(pel,0)/R);
+ }
+ if (l.system == angularsystem) {
+ return point(R,point(l.polarconicroutine(el,l.x,l.x,1,CCW),0)/R);
+ }
+ abort("point: bad abscissa system.");
+ return (0,0);
+}
+
+/*<asyxml><function type="point" signature="point(parabola,abscissa)"><code></asyxml>*/
+point point(parabola p, abscissa l)
+{/*<asyxml></code><documentation>Return the point of 'p' which has the abscissa 'l.x'
+ according to the abscissa system 'l.system'.</documentation></function></asyxml>*/
+ coordsys R=coordsys(p);
+ if (l.system == nodesystem)
+ return point(R,point((path)p,l.x)/R);
+ if (l.system == relativesystem) {
+ real[] b=bangles(p);
+ real al=sgn(l.x) > 0 ? arclength(p,180,b[1]) : arclength(p,180,b[0]);
+ return point(p,curabscissa(abs(l.x)*al));
+ }
+ if (l.system == curvilinearsystem) {
+ real a1=1e-3,a2=360-1e-3, cx=infinity;
+ while (abs(cx-l.x) > epsgeo) {
+ cx=arclength(p,180,(a1+a2)/2);
+ if(cx > l.x) a2=(a1+a2)/2; else a1=(a1+a2)/2;
+ }
+ path pp=fromFocus(p,a1,a1,1,CCW);
+ return point(R,point(pp,0)/R);
+ }
+ if (l.system == angularsystem) {
+ return point(R,point(fromFocus(p, l.x, l.x, 1, CCW), 0)/R);
+ }
+ abort("point: bad abscissa system.");
+ return (0,0);
+}
+
+/*<asyxml><function type="point" signature="point(hyperbola,abscissa)"><code></asyxml>*/
+point point(hyperbola h, abscissa l)
+{/*<asyxml></code><documentation>Return the point of 'h' which has the abscissa 'l.x'
+ according to the abscissa system 'l.system'.</documentation></function></asyxml>*/
+ coordsys R=coordsys(h);
+ if (l.system == nodesystem)
+ return point(R,point((path)h,l.x)/R);
+ if (l.system == relativesystem) {
+ abort("point(hyperbola,relativeSystem) is not implemented...
+Try relpoint((path)your_hyperbola,x);");
+ }
+ if (l.system == curvilinearsystem) {
+ abort("point(hyperbola,curvilinearSystem) is not implemented...");
+ }
+ if (l.system == angularsystem) {
+ return point(R,point(l.polarconicroutine(h,l.x,l.x,1,CCW),0)/R);
+ }
+ abort("point: bad abscissa system.");
+ return (0,0);
+}
+
+/*<asyxml><function type="abscissa" signature="point(conic,point)"><code></asyxml>*/
+point point(explicit conic co, abscissa l)
+{/*<asyxml></code><documentation>Return the curvilinear abscissa of 'M' on the conic 'co'.</documentation></function></asyxml>*/
+ if(co.e == 0) return point((circle)co, l);
+ if(co.e < 1) return point((ellipse)co, l);
+ if(co.e == 1) return point((parabola)co, l);
+ return point((hyperbola)co, l);
+}
+
+
+/*<asyxml><function type="point" signature="point(line,abscissa)"><code></asyxml>*/
+point point(line l, abscissa x)
+{/*<asyxml></code><documentation>Return the point of 'l' which has the abscissa 'l.x' according to the abscissa system 'l.system'.
+ Note that the origin is l.A, and point(l, relabscissa(x)) returns l.A + x.x*vector(l.B-l.A).</documentation></function></asyxml>*/
+ coordsys R=l.A.coordsys;
+ if (x.system == nodesystem)
+ return l.A+(x.x < 0 ? 0 : x.x > 1 ? 1 : x.x)*vector(l.B-l.A);
+ if (x.system == relativesystem)
+ return l.A+x.x*vector(l.B-l.A);
+ if (x.system == curvilinearsystem)
+ return l.A+x.x*l.u;
+ if (x.system == angularsystem)
+ abort("point: what the meaning of angular abscissa on line ?.");
+ abort("point: bad abscissa system.");
+ return (0,0);
+}
+
+/*<asyxml><function type="point" signature="point(line,real)"><code></asyxml>*/
+point point(line l, explicit real x)
+{/*<asyxml></code><documentation>Return the point between node l.A and l.B (x <= 0 means l.A, x >=1 means l.B).</documentation></function></asyxml>*/
+ return point(l,nodabscissa(x));
+}
+point point(line l, explicit int x)
+{
+ return point(l,nodabscissa(x));
+}
+
+/*<asyxml><function type="circle" signature="point(explicit circle,explicit real)"><code></asyxml>*/
+point point(explicit circle c, explicit real x)
+{/*<asyxml></code><documentation>Return the point between node floor(x) and floor(x)+1.</documentation></function></asyxml>*/
+ return point(c,nodabscissa(x));
+}
+point point(explicit circle c, explicit int x)
+{
+ return point(c,nodabscissa(x));
+}
+
+/*<asyxml><function type="point" signature="point(explicit ellipse,explicit real)"><code></asyxml>*/
+point point(explicit ellipse el, explicit real x)
+{/*<asyxml></code><documentation>Return the point between node floor(x) and floor(x)+1.</documentation></function></asyxml>*/
+ return point(el,nodabscissa(x));
+}
+point point(explicit ellipse el, explicit int x)
+{
+ return point(el,nodabscissa(x));
+}
+
+/*<asyxml><function type="point" signature="point(explicit parabola,explicit real)"><code></asyxml>*/
+point point(explicit parabola p, explicit real x)
+{/*<asyxml></code><documentation>Return the point between node floor(x) and floor(x)+1.</documentation></function></asyxml>*/
+ return point(p,nodabscissa(x));
+}
+point point(explicit parabola p, explicit int x)
+{
+ return point(p,nodabscissa(x));
+}
+
+/*<asyxml><function type="point" signature="point(explicit hyperbola,explicit real)"><code></asyxml>*/
+point point(explicit hyperbola h, explicit real x)
+{/*<asyxml></code><documentation>Return the point between node floor(x) and floor(x)+1.</documentation></function></asyxml>*/
+ return point(h,nodabscissa(x));
+}
+point point(explicit hyperbola h, explicit int x)
+{
+ return point(h,nodabscissa(x));
+}
+
+/*<asyxml><function type="point" signature="point(explicit conic,explicit real)"><code></asyxml>*/
+point point(explicit conic co, explicit real x)
+{/*<asyxml></code><documentation>Return the point between node floor(x) and floor(x)+1.</documentation></function></asyxml>*/
+ point op;
+ if(co.e == 0) op=point((circle)co,nodabscissa(x));
+ else if(co.e < 1) op=point((ellipse)co,nodabscissa(x));
+ else if(co.e == 1) op=point((parabola)co,nodabscissa(x));
+ else op=point((hyperbola)co,nodabscissa(x));
+ return op;
+}
+point point(explicit conic co,explicit int x)
+{
+ return point(co,(real)x);
+}
+
+/*<asyxml><function type="point" signature="relpoint(line,real)"><code></asyxml>*/
+point relpoint(line l, real x)
+{/*<asyxml></code><documentation>Return the relative point of 'l' (0 means l.A,
+ 1 means l.B, x means l.A+x*vector(l.B-l.A) ).</documentation></function></asyxml>*/
+ return point(l, Relative(x));
+}
+
+/*<asyxml><function type="point" signature="relpoint(explicit circle,real)"><code></asyxml>*/
+point relpoint(explicit circle c, real x)
+{/*<asyxml></code><documentation>Return the relative point of 'c' (0 means origin, 1 means end).
+ Origin is c.center+c.r*(1,0).</documentation></function></asyxml>*/
+ return point(c, Relative(x));
+}
+
+/*<asyxml><function type="point" signature="relpoint(explicit ellipse,real)"><code></asyxml>*/
+point relpoint(explicit ellipse el, real x)
+{/*<asyxml></code><documentation>Return the relative point of 'el' (0 means origin, 1 means end).</documentation></function></asyxml>*/
+ return point(el,Relative(x));
+}
+
+/*<asyxml><function type="point" signature="relpoint(explicit parabola,real)"><code></asyxml>*/
+point relpoint(explicit parabola p, real x)
+{/*<asyxml></code><documentation>Return the relative point of the path of the parabola
+ bounded by the bounding box of the current picture.
+ 0 means origin, 1 means end, where the origin is the vertex of 'p'.</documentation></function></asyxml>*/
+ return point(p,Relative(x));
+}
+
+/*<asyxml><function type="point" signature="relpoint(explicit hyperbola,real)"><code></asyxml>*/
+point relpoint(explicit hyperbola h, real x)
+{/*<asyxml></code><documentation>Not yet implemented... <look href="point(hyperbola,abscissa)"/></documentation></function></asyxml>*/
+ return point(h,Relative(x));
+}
+
+/*<asyxml><function type="point" signature="relpoint(explicit conic,explicit real)"><code></asyxml>*/
+point relpoint(explicit conic co, explicit real x)
+{/*<asyxml></code><documentation>Return the relative point of 'co' (0 means origin, 1 means end).</documentation></function></asyxml>*/
+ point op;
+ if(co.e == 0) op=point((circle)co,Relative(x));
+ else if(co.e < 1) op=point((ellipse)co,Relative(x));
+ else if(co.e == 1) op=point((parabola)co,Relative(x));
+ else op=point((hyperbola)co,Relative(x));
+ return op;
+}
+point relpoint(explicit conic co, explicit int x)
+{
+ return relpoint(co,(real)x);
+}
+
+/*<asyxml><function type="point" signature="angpoint(explicit circle,real)"><code></asyxml>*/
+point angpoint(explicit circle c, real x)
+{/*<asyxml></code><documentation>Return the point of 'c' in the direction 'x' measured in degrees.</documentation></function></asyxml>*/
+ return point(c,angabscissa(x));
+}
+
+/*<asyxml><function type="point" signature="angpoint(explicit ellipse,real,polarconicroutine)"><code></asyxml>*/
+point angpoint(explicit ellipse el, real x,
+ polarconicroutine polarconicroutine=currentpolarconicroutine)
+{/*<asyxml></code><documentation>Return the point of 'el' in the direction 'x'
+ measured in degrees according to 'polarconicroutine'.</documentation></function></asyxml>*/
+ return el.e == 0 ? angpoint((circle) el, x) : point(el,angabscissa(x,polarconicroutine));
+}
+
+/*<asyxml><function type="point" signature="angpoint(explicit parabola,real)"><code></asyxml>*/
+point angpoint(explicit parabola p, real x)
+{/*<asyxml></code><documentation>Return the point of 'p' in the direction 'x' measured in degrees.</documentation></function></asyxml>*/
+ return point(p,angabscissa(x));
+}
+
+/*<asyxml><function type="point" signature="angpoint(explicit hyperbola,real,polarconicroutine)"><code></asyxml>*/
+point angpoint(explicit hyperbola h, real x,
+ polarconicroutine polarconicroutine=currentpolarconicroutine)
+{/*<asyxml></code><documentation>Return the point of 'h' in the direction 'x'
+ measured in degrees according to 'polarconicroutine'.</documentation></function></asyxml>*/
+ return point(h,angabscissa(x,polarconicroutine));
+}
+
+/*<asyxml><function type="point" signature="curpoint(line,real)"><code></asyxml>*/
+point curpoint(line l, real x)
+{/*<asyxml></code><documentation>Return the point of 'l' which has the curvilinear abscissa 'x'.
+ Origin is l.A.</documentation></function></asyxml>*/
+ return point(l, curabscissa(x));
+}
+
+/*<asyxml><function type="point" signature="curpoint(explicit circle,real)"><code></asyxml>*/
+point curpoint(explicit circle c, real x)
+{/*<asyxml></code><documentation>Return the point of 'c' which has the curvilinear abscissa 'x'.
+ Origin is c.center+c.r*(1,0).</documentation></function></asyxml>*/
+ return point(c, curabscissa(x));
+}
+
+/*<asyxml><function type="point" signature="curpoint(explicit ellipse,real)"><code></asyxml>*/
+point curpoint(explicit ellipse el, real x)
+{/*<asyxml></code><documentation>Return the point of 'el' which has the curvilinear abscissa 'el'.</documentation></function></asyxml>*/
+ return point(el,curabscissa(x));
+}
+
+/*<asyxml><function type="point" signature="curpoint(explicit parabola,real)"><code></asyxml>*/
+point curpoint(explicit parabola p, real x)
+{/*<asyxml></code><documentation>Return the point of 'p' which has the curvilinear abscissa 'x'.
+ Origin is the vertex of 'p'.</documentation></function></asyxml>*/
+ return point(p,curabscissa(x));
+}
+
+/*<asyxml><function type="point" signature="curpoint(conic,real)"><code></asyxml>*/
+point curpoint(conic co, real x)
+{/*<asyxml></code><documentation>Return the point of 'co' which has the curvilinear abscissa 'x'.</documentation></function></asyxml>*/
+ point op;
+ if(co.e == 0) op=point((circle)co,curabscissa(x));
+ else if(co.e < 1) op=point((ellipse)co,curabscissa(x));
+ else if(co.e == 1) op=point((parabola)co,curabscissa(x));
+ else op=point((hyperbola)co,curabscissa(x));
+ return op;
+}
+
+/*<asyxml><function type="abscissa" signature="angabscissa(circle,point)"><code></asyxml>*/
+abscissa angabscissa(circle c, point M)
+{/*<asyxml></code><documentation>Return the angular abscissa of 'M' on the circle 'c'.</documentation></function></asyxml>*/
+ if(!(M @ c)) abort("angabscissa: the point is not on the circle.");
+ abscissa oa;
+ oa.system=angularsystem;
+ oa.x=degrees(M-c.C);
+ if(oa.x < 0) oa.x+=360;
+ return oa;
+}
+
+/*<asyxml><function type="abscissa" signature="angabscissa(ellipse,point,polarconicroutine)"><code></asyxml>*/
+abscissa angabscissa(ellipse el, point M,
+ polarconicroutine polarconicroutine=currentpolarconicroutine)
+{/*<asyxml></code><documentation>Return the angular abscissa of 'M' on the ellipse 'el' according to 'polarconicroutine'.</documentation></function></asyxml>*/
+ if(!(M @ el)) abort("angabscissa: the point is not on the ellipse.");
+ abscissa oa;
+ oa.system=angularsystem;
+ oa.polarconicroutine=polarconicroutine;
+ oa.x=polarconicroutine == fromCenter ? degrees(M-el.C) : degrees(M-el.F1);
+ oa.x -= el.angle;
+ if(oa.x < 0) oa.x += 360;
+ return oa;
+}
+
+/*<asyxml><function type="abscissa" signature="angabscissa(hyperbola,point,polarconicroutine)"><code></asyxml>*/
+abscissa angabscissa(hyperbola h, point M,
+ polarconicroutine polarconicroutine=currentpolarconicroutine)
+{/*<asyxml></code><documentation>Return the angular abscissa of 'M' on the hyperbola 'h' according to 'polarconicroutine'.</documentation></function></asyxml>*/
+ if(!(M @ h)) abort("angabscissa: the point is not on the hyperbola.");
+ abscissa oa;
+ oa.system=angularsystem;
+ oa.polarconicroutine=polarconicroutine;
+ oa.x=polarconicroutine == fromCenter ? degrees(M-h.C) : degrees(M-h.F1)+180;
+ oa.x -= h.angle;
+ if(oa.x < 0) oa.x += 360;
+ return oa;
+}
+
+/*<asyxml><function type="abscissa" signature="angabscissa(parabola,point)"><code></asyxml>*/
+abscissa angabscissa(parabola p, point M)
+{/*<asyxml></code><documentation>Return the angular abscissa of 'M' on the parabola 'p'.</documentation></function></asyxml>*/
+ if(!(M @ p)) abort("angabscissa: the point is not on the parabola.");
+ abscissa oa;
+ oa.system=angularsystem;
+ oa.polarconicroutine=fromFocus;// Not used
+ oa.x=degrees(M-p.F);
+ oa.x -= p.angle;
+ if(oa.x < 0) oa.x += 360;
+ return oa;
+}
+
+/*<asyxml><function type="abscissa" signature="angabscissa(conic,point)"><code></asyxml>*/
+abscissa angabscissa(explicit conic co, point M)
+{/*<asyxml></code><documentation>Return the angular abscissa of 'M' on the conic 'co'.</documentation></function></asyxml>*/
+ if(co.e == 0) return angabscissa((circle)co,M);
+ if(co.e < 1) return angabscissa((ellipse)co,M);
+ if(co.e == 1) return angabscissa((parabola)co,M);
+ return angabscissa((hyperbola)co,M);
+}
+
+/*<asyxml><function type="abscissa" signature="curabscissa(line,point)"><code></asyxml>*/
+abscissa curabscissa(line l, point M)
+{/*<asyxml></code><documentation>Return the curvilinear abscissa of 'M' on the line 'l'.</documentation></function></asyxml>*/
+ if(!(M @ extend(l))) abort("curabscissa: the point is not on the line.");
+ abscissa oa;
+ oa.system=curvilinearsystem;
+ oa.x=sgn(dot(M-l.A, l.B-l.A))*abs(M-l.A);
+ return oa;
+}
+
+/*<asyxml><function type="abscissa" signature="curabscissa(circle,point)"><code></asyxml>*/
+abscissa curabscissa(circle c, point M)
+{/*<asyxml></code><documentation>Return the curvilinear abscissa of 'M' on the circle 'c'.</documentation></function></asyxml>*/
+ if(!(M @ c)) abort("curabscissa: the point is not on the circle.");
+ abscissa oa;
+ oa.system=curvilinearsystem;
+ oa.x=pi*angabscissa(c,M).x*c.r/180;
+ return oa;
+}
+
+/*<asyxml><function type="abscissa" signature="curabscissa(ellipse,point)"><code></asyxml>*/
+abscissa curabscissa(ellipse el, point M)
+{/*<asyxml></code><documentation>Return the curvilinear abscissa of 'M' on the ellipse 'el'.</documentation></function></asyxml>*/
+ if(!(M @ el)) abort("curabscissa: the point is not on the ellipse.");
+ abscissa oa;
+ oa.system=curvilinearsystem;
+ real a=angabscissa(el,M,fromCenter).x;
+ oa.x=arclength(el,0,a,fromCenter);
+ oa.polarconicroutine=fromCenter;
+ return oa;
+}
+
+/*<asyxml><function type="abscissa" signature="curabscissa(parabola,point)"><code></asyxml>*/
+abscissa curabscissa(parabola p, point M)
+{/*<asyxml></code><documentation>Return the curvilinear abscissa of 'M' on the parabola 'p'.</documentation></function></asyxml>*/
+ if(!(M @ p)) abort("curabscissa: the point is not on the parabola.");
+ abscissa oa;
+ oa.system=curvilinearsystem;
+ real a=angabscissa(p,M).x;
+ oa.x=arclength(p,180,a);
+ oa.polarconicroutine=fromFocus; // Not used.
+ return oa;
+}
+
+/*<asyxml><function type="abscissa" signature="curabscissa(conic,point)"><code></asyxml>*/
+abscissa curabscissa(conic co, point M)
+{/*<asyxml></code><documentation>Return the curvilinear abscissa of 'M' on the conic 'co'.</documentation></function></asyxml>*/
+ if(co.e > 1) abort("curabscissa: not implemented for this hyperbola.");
+ if(co.e == 0) return curabscissa((circle)co,M);
+ if(co.e < 1) return curabscissa((ellipse)co,M);
+ return curabscissa((parabola)co,M);
+}
+
+/*<asyxml><function type="abscissa" signature="nodabscissa(line,point)"><code></asyxml>*/
+abscissa nodabscissa(line l, point M)
+{/*<asyxml></code><documentation>Return the node abscissa of 'M' on the line 'l'.</documentation></function></asyxml>*/
+ if(!(M @ (segment)l)) abort("nodabscissa: the point is not on the segment.");
+ abscissa oa;
+ oa.system=nodesystem;
+ oa.x=abs(M-l.A)/abs(l.A-l.B);
+ return oa;
+}
+
+/*<asyxml><function type="abscissa" signature="nodabscissa(circle,point)"><code></asyxml>*/
+abscissa nodabscissa(circle c, point M)
+{/*<asyxml></code><documentation>Return the node abscissa of 'M' on the circle 'c'.</documentation></function></asyxml>*/
+ if(!(M @ c)) abort("nodabscissa: the point is not on the circle.");
+ abscissa oa;
+ oa.system=nodesystem;
+ oa.x=intersect((path)c,locate(M))[0];
+ return oa;
+}
+
+/*<asyxml><function type="abscissa" signature="nodabscissa(ellipse,point)"><code></asyxml>*/
+abscissa nodabscissa(ellipse el, point M)
+{/*<asyxml></code><documentation>Return the node abscissa of 'M' on the ellipse 'el'.</documentation></function></asyxml>*/
+ if(!(M @ el)) abort("nodabscissa: the point is not on the ellipse.");
+ abscissa oa;
+ oa.system=nodesystem;
+ oa.x=intersect((path)el,M)[0];
+ return oa;
+}
+
+/*<asyxml><function type="abscissa" signature="nodabscissa(parabola,point)"><code></asyxml>*/
+abscissa nodabscissa(parabola p, point M)
+{/*<asyxml></code><documentation>Return the node abscissa OF 'M' on the parabola 'p'.</documentation></function></asyxml>*/
+ if(!(M @ p)) abort("nodabscissa: the point is not on the parabola.");
+ abscissa oa;
+ oa.system=nodesystem;
+ path pg=p;
+ real[] t=intersect(pg,M,1e-5);
+ if(t.length == 0) abort("nodabscissa: the point is not on the path of the parabola.");
+ oa.x=t[0];
+ return oa;
+}
+
+/*<asyxml><function type="abscissa" signature="nodabscissa(conic,point)"><code></asyxml>*/
+abscissa nodabscissa(conic co, point M)
+{/*<asyxml></code><documentation>Return the node abscissa of 'M' on the conic 'co'.</documentation></function></asyxml>*/
+ if(co.e > 1) abort("nodabscissa: not implemented for hyperbola.");
+ if(co.e == 0) return nodabscissa((circle)co,M);
+ if(co.e < 1) return nodabscissa((ellipse)co,M);
+ return nodabscissa((parabola)co,M);
+}
+
+
+/*<asyxml><function type="abscissa" signature="relabscissa(line,point)"><code></asyxml>*/
+abscissa relabscissa(line l, point M)
+{/*<asyxml></code><documentation>Return the relative abscissa of 'M' on the line 'l'.</documentation></function></asyxml>*/
+ if(!(M @ extend(l))) abort("relabscissa: the point is not on the line.");
+ abscissa oa;
+ oa.system=relativesystem;
+ oa.x=sgn(dot(M-l.A, l.B-l.A))*abs(M-l.A)/abs(l.A-l.B);
+ return oa;
+}
+
+/*<asyxml><function type="abscissa" signature="relabscissa(circle,point)"><code></asyxml>*/
+abscissa relabscissa(circle c, point M)
+{/*<asyxml></code><documentation>Return the relative abscissa of 'M' on the circle 'c'.</documentation></function></asyxml>*/
+ if(!(M @ c)) abort("relabscissa: the point is not on the circle.");
+ abscissa oa;
+ oa.system=relativesystem;
+ oa.x=angabscissa(c,M).x/360;
+ return oa;
+}
+
+/*<asyxml><function type="abscissa" signature="relabscissa(ellipse,point)"><code></asyxml>*/
+abscissa relabscissa(ellipse el, point M)
+{/*<asyxml></code><documentation>Return the relative abscissa of 'M' on the ellipse 'el'.</documentation></function></asyxml>*/
+ if(!(M @ el)) abort("relabscissa: the point is not on the ellipse.");
+ abscissa oa;
+ oa.system=relativesystem;
+ oa.x=curabscissa(el,M).x/arclength(el);
+ oa.polarconicroutine=fromFocus;
+ return oa;
+}
+
+/*<asyxml><function type="abscissa" signature="relabscissa(conic,point)"><code></asyxml>*/
+abscissa relabscissa(conic co, point M)
+{/*<asyxml></code><documentation>Return the relative abscissa of 'M'
+ on the conic 'co'.</documentation></function></asyxml>*/
+ write("PASS");
+ if(co.e > 1) abort("relabscissa: not implemented for hyperbola and parabola.");
+ if(co.e == 1) return relabscissa((parabola)co,M);
+ if(co.e == 0) return relabscissa((circle)co,M);
+ return relabscissa((ellipse)co,M);
+}
+// *.......................ABSCISSA........................*
+// *=======================================================*
+
+// *=======================================================*
+// *.........................ARCS..........................*
+/*<asyxml><struct signature="arc"><code></asyxml>*/
+struct arc {
+ /*<asyxml></code><documentation>Implement oriented ellipse (included circle) arcs.
+ All the calculus with this structure will be as exact as Asymptote can do.
+ For a full precision, you must not cast 'arc' to 'path' excepted for drawing routines.
+ </documentation><property type="ellipse" signature="el"><code></asyxml>*/
+ ellipse el;/*<asyxml></code><documentation>The support of the arc.</documentation></property><property type="real" signature="angle0"><code></asyxml>*/
+ restricted real angle0=0;/*<asyxml></code><documentation>Internal use: rotating a circle does not modify the origin point, this variable stocks the eventual angle rotation. This value is not used for ellipses which are not circles.</documentation></property><property type="real" signature="angle1,angle2"><code></asyxml>*/
+ restricted real angle1, angle2;/*<asyxml></code><documentation>Values (in degrees) in ]-360,360[.</documentation></property><property type="bool" signature="direction"><code></asyxml>*/
+ bool direction=CCW;/*<asyxml></code><documentation>The arc will be drawn from 'angle1' to 'angle2' rotating in the direction 'direction'.</documentation></property><property type="polarconicroutine" signature="polarconicroutine"><code></asyxml>*/
+ polarconicroutine polarconicroutine=currentpolarconicroutine;/*<asyxml></code><documentation>The routine to which the angles refer.
+ If 'el' is a circle 'fromCenter' is always used.</documentation></property></asyxml>*/
+
+ /*<asyxml><method type="void" signature="setangles(real,real,real)"><code></asyxml>*/
+ void setangles(real a0, real a1, real a2)
+ {/*<asyxml></code><documentation>Set the angles.</documentation></method></asyxml>*/
+ this.angle0=a0%(sgnd(a0)*360);
+ this.angle1=a1%(sgnd(a1)*360);
+ this.angle2=a2%(sgnd(2)*360);
+ }
+
+ /*<asyxml><method type="void" signature="init(ellipse,real,real,real,polarconicroutine,bool)"><code></asyxml>*/
+ void init(ellipse el, real angle0=0, real angle1, real angle2,
+ polarconicroutine polarconicroutine,
+ bool direction=CCW)
+ {/*<asyxml></code><documentation>Constructor.</documentation></method></asyxml>*/
+ if(abs(angle1-angle2) > 360) abort("arc: |angle1-angle2| > 360.");
+ this.el=el;
+ this.setangles(angle0, angle1, angle2);
+ this.polarconicroutine=polarconicroutine;
+ this.direction=direction;
+ }
+
+ /*<asyxml><method type="arc" signature="copy()"><code></asyxml>*/
+ arc copy()
+ {/*<asyxml></code><documentation>Copy the arc.</documentation></method></asyxml>*/
+ arc oa=new arc;
+ oa.el=this.el;
+ oa.direction=this.direction;
+ oa.polarconicroutine=this.polarconicroutine;
+ oa.angle1=this.angle1;
+ oa.angle2=this.angle2;
+ oa.angle0=this.angle0;
+ return oa;
+ }
+}/*<asyxml></struct></asyxml>*/
+
+/*<asyxml><function type="polarconicroutine" signature="polarconicroutine(ellipse)"><code></asyxml>*/
+polarconicroutine polarconicroutine(conic co)
+{/*<asyxml></code><documentation>Return the default routine used to draw a conic.</documentation></function></asyxml>*/
+ if(co.e == 0) return fromCenter;
+ if(co.e == 1) return fromFocus;
+ return currentpolarconicroutine;
+}
+
+/*<asyxml><function type="arc" signature="arc(ellipse,real,real,polarconicroutine,bool)"><code></asyxml>*/
+arc arc(ellipse el, real angle1, real angle2,
+ polarconicroutine polarconicroutine=polarconicroutine(el),
+ bool direction=CCW)
+{/*<asyxml></code><documentation>Return the ellipse arc from 'angle1' to 'angle2' with respect to 'polarconicroutine' and rotating in the direction 'direction'.</documentation></function></asyxml>*/
+ arc oa;
+ oa.init(el,0,angle1,angle2,polarconicroutine,direction);
+ return oa;
+}
+
+/*<asyxml><function type="arc" signature="complementary(arc)"><code></asyxml>*/
+arc complementary(arc a)
+{/*<asyxml></code><documentation>Return the complementary of 'a'.</documentation></function></asyxml>*/
+ arc oa;
+ oa.init(a.el,a.angle0,a.angle2,a.angle1,a.polarconicroutine,a.direction);
+ return oa;
+}
+
+/*<asyxml><function type="arc" signature="reverse(arc)"><code></asyxml>*/
+arc reverse(arc a)
+{/*<asyxml></code><documentation>Return arc 'a' oriented in reverse direction.</documentation></function></asyxml>*/
+ arc oa;
+ oa.init(a.el,a.angle0,a.angle2,a.angle1,a.polarconicroutine,!a.direction);
+ return oa;
+}
+
+/*<asyxml><function type="real" signature="degrees(arc)"><code></asyxml>*/
+real degrees(arc a)
+{/*<asyxml></code><documentation>Return the measure in degrees of the oriented arc 'a'.</documentation></function></asyxml>*/
+ real or;
+ real da=a.angle2-a.angle1;
+ if(a.direction) {
+ or=a.angle1 < a.angle2 ? da : 360+da;
+ } else {
+ or=a.angle1 < a.angle2 ? -360+da : da;
+ }
+ return or;
+}
+
+/*<asyxml><function type="real" signature="angle(a)"><code></asyxml>*/
+real angle(arc a)
+{/*<asyxml></code><documentation>Return the measure in radians of the oriented arc 'a'.</documentation></function></asyxml>*/
+ return radians(degrees(a));
+}
+
+/*<asyxml><function type="int" signature="arcnodesnumber(explicit arc)"><code></asyxml>*/
+int arcnodesnumber(explicit arc a)
+{/*<asyxml></code><documentation>Return the number of nodes to draw the arc 'a'.</documentation></function></asyxml>*/
+ return ellipsenodesnumber(a.el.a,a.el.b,a.angle1,a.angle2,a.direction);
+}
+
+private path arctopath(arc a, int n)
+{
+ if(a.el.e == 0) return arcfromcenter(a.el,a.angle0+a.angle1,a.angle0+a.angle2,a.direction,n);
+ if(a.el.e != 1) return a.polarconicroutine(a.el,a.angle1,a.angle2,n,a.direction);
+ return arcfromfocus(a.el,a.angle1,a.angle2,n,a.direction);
+}
+
+/*<asyxml><function type="point" signature="angpoint(arc,real)"><code></asyxml>*/
+point angpoint(arc a, real angle)
+{/*<asyxml></code><documentation>Return the point given by its angular position (in degrees) relative to the arc 'a'.
+ If 'angle > degrees(a)' or 'angle < 0' the returned point is on the extended arc.</documentation></function></asyxml>*/
+ pair p;
+ if(a.el.e == 0) {
+ real gle=a.angle0+a.angle1+(a.direction ? angle : -angle);
+ p=point(arcfromcenter(a.el,gle,gle,CCW,1),0);
+ }
+ else {
+ real gle=a.angle1+(a.direction ? angle : -angle);
+ p=point(a.polarconicroutine(a.el,gle,gle,1,CCW),0);
+ }
+ return point(coordsys(a.el),p/coordsys(a.el));
+}
+
+/*<asyxml><operator type="path" signature="cast(explicit arc)"><code></asyxml>*/
+path operator cast(explicit arc a)
+{/*<asyxml></code><documentation>Cast arc to path.</documentation></operator></asyxml>*/
+ return arctopath(a,arcnodesnumber(a));
+}
+
+/*<asyxml><operator type="guide" signature="cast(explicit arc)"><code></asyxml>*/
+guide operator cast(explicit arc a)
+{/*<asyxml></code><documentation>Cast arc to guide.</documentation></operator></asyxml>*/
+ return arctopath(a,arcnodesnumber(a));
+}
+
+/*<asyxml><operator type="arc" signature="*(transform,explicit arc)"><code></asyxml>*/
+arc operator *(transform t, explicit arc a)
+{/*<asyxml></code><documentation>Provide transform*arc.</documentation></operator></asyxml>*/
+ pair[] P, PP;
+ path g=arctopath(a,3);
+ real a0, a1=a.angle1, a2=a.angle2, ap1, ap2;
+ bool dir=a.direction;
+ P[0]=t*point(g,0);
+ P[1]=t*point(g,2);
+ ellipse el=t*a.el;
+ arc oa;
+ a0=(a.angle0+angle(shiftless(t)))%360;
+ pair C;
+ if(a.polarconicroutine == fromCenter) C=el.C; else C=el.F1;
+ real d=abs(locate(el.F2-el.F1)) > epsgeo ?
+ degrees(locate(el.F2-el.F1)) : a0+degrees(el.C.coordsys.i);
+ ap1=(degrees(P[0]-C,false)-d)%360;
+ ap2=(degrees(P[1]-C,false)-d)%360;
+ oa.init(el,a0,ap1,ap2,a.polarconicroutine,dir);
+ g=arctopath(oa,3);
+ PP[0]=point(g,0);
+ PP[1]=point(g,2);
+ if((a1-a2)*(ap1-ap2) < 0) {// Handle reflection.
+ dir=!a.direction;
+ oa.init(el,a0,ap1,ap2,a.polarconicroutine,dir);
+ }
+ return oa;
+}
+
+/*<asyxml><operator type="arc" signature="*(real,explicit arc)"><code></asyxml>*/
+arc operator *(real x, explicit arc a)
+{/*<asyxml></code><documentation>Provide real*arc.
+ Return the arc subtracting and adding '(x-1)*degrees(a)/2' to 'a.angle1' and 'a.angle2' respectively.</documentation></operator></asyxml>*/
+ real a1, a2, gle;
+ gle=(x-1)*degrees(a)/2;
+ a1=a.angle1-gle;
+ a2=a.angle2+gle;
+ arc oa;
+ oa.init(a.el,a.angle0,a1,a2,a.polarconicroutine,a.direction);
+ return oa;
+}
+arc operator *(int x, explicit arc a){return (real)x*a;}
+/*<asyxml><operator type="arc" signature="/(real,explicit arc)"><code></asyxml>*/
+arc operator /(explicit arc a, real x)
+{/*<asyxml></code><documentation>Provide arc/real.
+ Return the arc subtracting and adding '(1/x-1)*degrees(a)/2' to 'a.angle1' and 'a.angle2' respectively.</documentation></operator></asyxml>*/
+ return (1/x)*a;
+}
+/*<asyxml><operator type="arc" signature="+(explicit arc,point)"><code></asyxml>*/
+arc operator +(explicit arc a, point M)
+{/*<asyxml></code><documentation>Provide arc+point.
+ Return shifted arc.
+ 'operator +(explicit arc,point)', 'operator +(explicit arc,vector)' and 'operator -(explicit arc,vector)' are also defined.</documentation></operator></asyxml>*/
+ return shift(M)*a;
+}
+arc operator -(explicit arc a, point M){return a+(-M);}
+arc operator +(explicit arc a, vector v){return shift(locate(v))*a;}
+arc operator -(explicit arc a, vector v){return a+(-v);}
+
+
+/*<asyxml><operator type="bool" signature="@(point,arc)"><code></asyxml>*/
+bool operator @(point M, arc a)
+{/*<asyxml></code><documentation>Return true iff 'M' is on the arc 'a'.</documentation></operator></asyxml>*/
+ if (!(M @ a.el)) return false;
+ coordsys R=defaultcoordsys;
+ path ap=arctopath(a,3);
+ line l=line(point(R,point(ap,0)),point(R,point(ap,2)));
+ return sameside(M, point(R,point(ap,1)), l);
+}
+
+/*<asyxml><function type="void" signature="draw(picture,Label,arc,align,pen,arrowbar,arrowbar,margin,Label,marker)"><code></asyxml>*/
+void draw(picture pic=currentpicture, Label L="", arc a,
+ align align=NoAlign, pen p=currentpen,
+ arrowbar arrow=None, arrowbar bar=None, margin margin=NoMargin,
+ Label legend="", marker marker=nomarker)
+{/*<asyxml></code><documentation>Draw 'arc' adding the pen returned by 'addpenarc(p)' to the pen 'p'.
+ <look href="#addpenarc"/></documentation></function></asyxml>*/
+ draw(pic,L,(path)a,align,addpenarc(p),arrow,bar,margin,legend,marker);
+}
+
+/*<asyxml><function type="real" signature="arclength(arc)"><code></asyxml>*/
+real arclength(arc a)
+{/*<asyxml></code><documentation>The arc length of 'a'.</documentation></function></asyxml>*/
+ return arclength(a.el, a.angle1, a.angle2, a.direction, a.polarconicroutine);
+}
+
+private point ppoint(arc a, real x)
+{// Return the point of the arc proportionally to its length.
+ point oP;
+ if(a.el.e == 0) { // Case of circle.
+ oP=angpoint(a,x*abs(degrees(a)));
+ } else { // Ellipse and not circle.
+ if(!a.direction) {
+ transform t=reflect(line(a.el.F1,a.el.F2));
+ return t*ppoint(t*a,x);
+ }
+
+ real angle1=a.angle1, angle2=a.angle2;
+ if(a.polarconicroutine == fromFocus) {
+ // dot(point(fromFocus(a.el,angle1,angle1,1,CCW),0),2mm+blue);
+ // dot(point(fromFocus(a.el,angle2,angle2,1,CCW),0),2mm+blue);
+ // write("fromfocus1=",angle1);
+ // write("fromfocus2=",angle2);
+ real gle1=focusToCenter(a.el,angle1);
+ real gle2=focusToCenter(a.el,angle2);
+ if((gle1-gle2)*(angle1-angle2) > 0) {
+ angle1=gle1; angle2=gle2;
+ } else {
+ angle1=gle2; angle2=gle1;
+ }
+ // write("fromcenter1=",angle1);
+ // write("fromcenter2=",angle2);
+ // dot(point(fromCenter(a.el,angle1,angle1,1,CCW),0),1mm+red);
+ // dot(point(fromCenter(a.el,angle2,angle2,1,CCW),0),1mm+red);
+ }
+
+ if(angle1 > angle2) {
+ arc ta=a.copy();
+ ta.polarconicroutine=fromCenter;
+ ta.setangles(a0=a.angle0,a1=angle1-360,a2=angle2);
+ return ppoint(ta,x);
+ }
+ ellipse co=a.el;
+ real gle, a1, a2, cx=0;
+ bool direction;
+ if(x >= 0) {
+ a1=angle1;
+ a2=a1+360;
+ direction=CCW;
+ } else {
+ a1=angle1-360;
+ a2=a1-360;
+ direction=CW;
+ }
+ gle=a1;
+ real L=arclength(co,angle1,angle2,a.direction,fromCenter);
+ real tx=L*abs(x)%arclength(co);
+ real aout=a1;
+ while(abs(cx-tx) > epsgeo) {
+ aout=(a1+a2)/2;
+ cx=abs(arclength(co,gle,aout,direction,fromCenter));
+ if(cx > tx) a2=(a1+a2)/2 ; else a1=(a1+a2)/2;
+ }
+ pair p=point(arcfromcenter(co,aout,aout,CCW,1), 0);
+ oP=point(coordsys(co), p/coordsys(co));
+ }
+ return oP;
+}
+
+/*<asyxml><function type="point" signature="point(arc,abscissa)"><code></asyxml>*/
+point point(arc a, abscissa l)
+{/*<asyxml></code><documentation>Return the point of 'a' which has the abscissa 'l.x'
+ according to the abscissa system 'l.system'.
+ Note that 'a.polarconicroutine' is used instead of 'l.polarconicroutine'.
+ <look href="#struct abscissa"/></documentation></function></asyxml>*/
+ real posx;
+ arc ta=a.copy();
+ ellipse co=a.el;
+ if (l.system == relativesystem) {
+ posx=l.x;
+ } else
+ if (l.system == curvilinearsystem) {
+ real tl;
+ if(co.e == 0) {
+ tl=curabscissa(a.el,angpoint(a.el,a.angle0+a.angle1)).x;
+ return curpoint(a.el,tl + (a.direction ? l.x : -l.x));
+ } else {
+ tl=curabscissa(a.el,angpoint(a.el,a.angle1,a.polarconicroutine)).x;
+ return curpoint(a.el,tl + (a.direction ? l.x : -l.x));
+ }
+ } else
+ if (l.system == nodesystem) {
+ coordsys R=coordsys(co);
+ return point(R,point((path)a,l.x)/R);
+ } else
+ if (l.system == angularsystem) {
+ return angpoint(a,l.x);
+ } else abort("point: bad abscissa system.");
+ return ppoint(ta, posx);
+}
+
+
+/*<asyxml><function type="point" signature="point(arc,real)"><code></asyxml>*/
+point point(arc a,real x)
+{/*<asyxml></code><documentation>Return the point between node floor(t) and floor(t)+1.</documentation></function></asyxml>*/
+ return point(a, nodabscissa(x));
+}
+pair point(explicit arc a, int x)
+{
+ return point(a, nodabscissa(x));
+}
+
+/*<asyxml><function type="point" signature="relpoint(arc,real)"><code></asyxml>*/
+point relpoint(arc a, real x)
+{/*<asyxml></code><documentation>Return the relative point of 'a'.
+ If x > 1 or x < 0, the returned point is on the extended arc.</documentation></function></asyxml>*/
+ return point(a, relabscissa(x));
+}
+
+/*<asyxml><function type="point" signature="curpoint(arc,real)"><code></asyxml>*/
+point curpoint(arc a, real x)
+{/*<asyxml></code><documentation>Return the point of 'a' which has the curvilinear abscissa 'x'.
+ If x < 0 or x > arclength(a), the returned point is on the extended arc.</documentation></function></asyxml>*/
+ return point(a, curabscissa(x));
+}
+
+/*<asyxml><function type="abscissa" signature="angabscissa(arc,point)"><code></asyxml>*/
+abscissa angabscissa(arc a, point M)
+{/*<asyxml></code><documentation>Return the angular abscissa of 'M' according to the arc 'a'.</documentation></function></asyxml>*/
+ if(!(M @ a.el))
+ abort("angabscissa: the point is not on the extended arc.");
+ abscissa oa;
+ oa.system=angularsystem;
+ oa.polarconicroutine=a.polarconicroutine;
+ real am=angabscissa(a.el,M,a.polarconicroutine).x;
+ oa.x=(am-a.angle1-(a.el.e == 0 ? a.angle0 : 0))%360;
+ oa.x=a.direction ? oa.x : 360-oa.x;
+ return oa;
+}
+
+/*<asyxml><function type="abscissa" signature="curabscissa(arc,point)"><code></asyxml>*/
+abscissa curabscissa(arc a, point M)
+{/*<asyxml></code><documentation>Return the curvilinear abscissa according to the arc 'a'.</documentation></function></asyxml>*/
+ ellipse el=a.el;
+ if(!(M @ el))
+ abort("angabscissa: the point is not on the extended arc.");
+ abscissa oa;
+ oa.system=curvilinearsystem;
+ real xm=curabscissa(el,M).x;
+ real a0=el.e == 0 ? a.angle0 : 0;
+ real am=curabscissa(el,angpoint(el,a.angle1+a0,a.polarconicroutine)).x;
+ real l=arclength(el);
+ oa.x=(xm-am)%l;
+ oa.x=a.direction ? oa.x : l-oa.x;
+ return oa;
+}
+
+/*<asyxml><function type="abscissa" signature="nodabscissa(arc,point)"><code></asyxml>*/
+abscissa nodabscissa(arc a, point M)
+{/*<asyxml></code><documentation>Return the node abscissa according to the arc 'a'.</documentation></function></asyxml>*/
+ if(!(M @ a))
+ abort("nodabscissa: the point is not on the arc.");
+ abscissa oa;
+ oa.system=nodesystem;
+ oa.x=intersect((path)a,M)[0];
+ return oa;
+}
+
+/*<asyxml><function type="abscissa" signature="relabscissa(arc,point)"><code></asyxml>*/
+abscissa relabscissa(arc a, point M)
+{/*<asyxml></code><documentation>Return the relative abscissa according to the arc 'a'.</documentation></function></asyxml>*/
+ ellipse el=a.el;
+ if(!( M @ el))
+ abort("relabscissa: the point is not on the prolonged arc.");
+ abscissa oa;
+ oa.system=relativesystem;
+ oa.x=curabscissa(a,M).x/arclength(a);
+ return oa;
+}
+
+/*<asyxml><function type="void" signature="markarc(picture,Label,int,real,real,arc,arrowbar,pen,pen,margin,marker)"><code></asyxml>*/
+void markarc(picture pic=currentpicture,
+ Label L="",
+ int n=1, real radius=0, real space=0,
+ arc a,
+ pen sectorpen=currentpen,
+ pen markpen=sectorpen,
+ margin margin=NoMargin,
+ arrowbar arrow=None,
+ marker marker=nomarker)
+{/*<asyxml></code><documentation></documentation></function></asyxml>*/
+ real Da=degrees(a);
+ pair p1=point(a,0);
+ pair p2=relpoint(a,1);
+ pair c=a.polarconicroutine == fromCenter ? locate(a.el.C) : locate(a.el.F1);
+ if(radius == 0) radius=markangleradius(markpen);
+ if(abs(Da) > 180) radius=-radius;
+ radius=(a.direction ? 1 : -1)*sgnd(Da)*radius;
+ draw(c--p1^^c--p2,sectorpen);
+ markangle(pic=pic,L=L,n=n,radius=radius,space=space,
+ A=p1,O=c,B=p2,
+ arrow=arrow,p=markpen,margin=margin,
+ marker=marker);
+}
+// *.........................ARCS..........................*
+// *=======================================================*
+
+// *=======================================================*
+// *........................MASSES.........................*
+/*<asyxml><struct signature="mass"><code></asyxml>*/
+struct mass {/*<asyxml></code><documentation></documentation><property type="point" signature="M"><code></asyxml>*/
+ point M;/*<asyxml></code><documentation></documentation></property><property type="real" signature="m"><code></asyxml>*/
+ real m;/*<asyxml></code><documentation></documentation></property></asyxml>*/
+}/*<asyxml></struct></asyxml>*/
+
+/*<asyxml><function type="mass" signature="mass(point,real)"><code></asyxml>*/
+mass mass(point M, real m)
+{/*<asyxml></code><documentation>Constructor of mass point.</documentation></function></asyxml>*/
+ mass om;
+ om.M=M;
+ om.m=m;
+ return om;
+}
+
+/*<asyxml><operator type="point" signature="cast(mass)"><code></asyxml>*/
+point operator cast(mass m)
+{/*<asyxml></code><documentation>Cast mass point to point.</documentation></operator></asyxml>*/
+ point op;
+ op=m.M;
+ op.m=m.m;
+ return op;
+}
+/*<asyxml><function type="point" signature="point(explicit mass)"><code></asyxml>*/
+point point(explicit mass m){return m;}/*<asyxml></code><documentation>Cast
+ 'm' to point</documentation></function></asyxml>*/
+
+/*<asyxml><operator type="mass" signature="cast(point)"><code></asyxml>*/
+mass operator cast(point M)
+{/*<asyxml></code><documentation>Cast point to mass point.</documentation></operator></asyxml>*/
+ mass om;
+ om.M=M;
+ om.m=M.m;
+ return om;
+}
+/*<asyxml><function type="mass" signature="mass(explicit point)"><code></asyxml>*/
+mass mass(explicit point P)
+{/*<asyxml></code><documentation>Cast 'P' to mass.</documentation></function></asyxml>*/
+ return mass(P,P.m);
+}
+
+/*<asyxml><operator type="point[]" signature="cast(mass[])"><code></asyxml>*/
+point[] operator cast(mass[] m)
+{/*<asyxml></code><documentation>Cast mass[] to point[].</documentation></operator></asyxml>*/
+ point[] op;
+ for(mass am : m) op.push(point(am));
+ return op;
+}
+
+/*<asyxml><operator type="mass[]" signature="cast(point[])"><code></asyxml>*/
+mass[] operator cast(point[] P)
+{/*<asyxml></code><documentation>Cast point[] to mass[].</documentation></operator></asyxml>*/
+ mass[] om;
+ for(point op : P) om.push(mass(op));
+ return om;
+}
+
+/*<asyxml><function type="mass" signature="mass(coordsys,explicit pair,real)"><code></asyxml>*/
+mass mass(coordsys R, explicit pair p, real m)
+{/*<asyxml></code><documentation>Return the mass which has coordinates
+ 'p' with respect to 'R' and weight 'm'.</documentation></function></asyxml>*/
+ return point(R,p,m);// Using casting.
+}
+
+/*<asyxml><operator type="mass" signature="cast(pair)"><code></asyxml>*/
+mass operator cast(pair m){return mass((point)m,1);}/*<asyxml></code><documentation>Cast pair to mass point.</documentation></operator></asyxml>*/
+/*<asyxml><operator type="path" signature="cast(mass)"><code></asyxml>*/
+path operator cast(mass M){return M.M;}/*<asyxml></code><documentation>Cast mass point to path.</documentation></operator></asyxml>*/
+/*<asyxml><operator type="guide" signature="cast(mass)"><code></asyxml>*/
+guide operator cast(mass M){return M.M;}/*<asyxml></code><documentation>Cast mass to guide.</documentation></operator></asyxml>*/
+
+/*<asyxml><operator type="mass" signature="+(mass,mass)"><code></asyxml>*/
+mass operator +(mass M1, mass M2)
+{/*<asyxml></code><documentation>Provide mass+mass.
+ mass-mass is also defined.</documentation></operator></asyxml>*/
+ return mass(M1.M+M2.M,M1.m+M2.m);
+}
+mass operator -(mass M1, mass M2)
+{
+ return mass(M1.M-M2.M,M1.m-M2.m);
+}
+
+/*<asyxml><operator type="mass" signature="*(real,mass)"><code></asyxml>*/
+mass operator *(real x, explicit mass M)
+{/*<asyxml></code><documentation>Provide real*mass.
+ The resulted mass is the mass of 'M' multiplied by 'x' .
+ mass/real, mass+real and mass-real are also defined.</documentation></operator></asyxml>*/
+ return mass(M.M,x*M.m);
+}
+mass operator *(int x, explicit mass M){return mass(M.M,x*M.m);}
+mass operator /(explicit mass M,real x){return mass(M.M,M.m/x);}
+mass operator /(explicit mass M,int x){return mass(M.M,M.m/x);}
+mass operator +(explicit mass M,real x){return mass(M.M,M.m+x);}
+mass operator +(explicit mass M,int x){return mass(M.M,M.m+x);}
+mass operator -(explicit mass M,real x){return mass(M.M,M.m-x);}
+mass operator -(explicit mass M,int x){return mass(M.M,M.m-x);}
+/*<asyxml><operator type="mass" signature="*(transform,mass)"><code></asyxml>*/
+mass operator *(transform t, mass M)
+{/*<asyxml></code><documentation>Provide transform*mass.</documentation></operator></asyxml>*/
+ return mass(t*M.M,M.m);
+}
+
+/*<asyxml><function type="mass" signature="masscenter(... mass[])"><code></asyxml>*/
+mass masscenter(... mass[] M)
+{/*<asyxml></code><documentation>Return the center of the masses 'M'.</documentation></function></asyxml>*/
+ point[] P;
+ for (int i=0; i < M.length; ++i)
+ P.push(M[i].M);
+ P=standardizecoordsys(currentcoordsys,true ... P);
+ real m=M[0].m;
+ point oM=M[0].m*P[0];
+ for (int i=1; i < M.length; ++i) {
+ oM+=M[i].m*P[i];
+ m+=M[i].m;
+ }
+ if (m == 0) abort("masscenter: the sum of masses is null.");
+ return mass(oM/m,m);
+}
+
+/*<asyxml><function type="string" signature="massformat(string,string,mass)"><code></asyxml>*/
+string massformat(string format=defaultmassformat,
+ string s, mass M)
+{/*<asyxml></code><documentation>Return the string formated by 'format' with the mass value.
+ In the parameter 'format', %L will be replaced by 's'.
+ <look href="#defaultmassformat"/>.</documentation></function></asyxml>*/
+ return format == "" ? s :
+ format(replace(format,"%L",replace(s,"$","")),M.m);
+}
+
+/*<asyxml><function type="void" signature="label(picture, Label,explicit mass,align,string,pen,filltype)"><code></asyxml>*/
+void label(picture pic=currentpicture, Label L, explicit mass M,
+ align align=NoAlign, string format=defaultmassformat,
+ pen p=nullpen, filltype filltype=NoFill)
+{/*<asyxml></code><documentation>Draw label returned by massformat(format,L,M) at coordinates of M.
+ <look href="#massformat(string,string,mass)"/>.</documentation></function></asyxml>*/
+ Label lL=L.copy();
+ lL.s=massformat(format,lL.s,M);
+ Label L=Label(lL,M.M,align,p,filltype);
+ add(pic,L);
+}
+
+/*<asyxml><function type="void" signature="dot(picture,Label,explicit mass,align,string,pen)"><code></asyxml>*/
+void dot(picture pic=currentpicture, Label L, explicit mass M, align align=NoAlign,
+ string format=defaultmassformat, pen p=currentpen)
+{/*<asyxml></code><documentation>Draw a dot with label 'L' as
+ label(picture, Label,explicit mass,align,string,pen,filltype) does.
+ <look href="#label(picture, Label,mass,align,string,pen,filltype)"/>.</documentation></function></asyxml>*/
+ Label lL=L.copy();
+ lL.s=massformat(format,lL.s,M);
+ lL.position(locate(M.M));
+ lL.align(align,E);
+ lL.p(p);
+ dot(pic,M.M,p);
+ add(pic,lL);
+}
+// *........................MASSES.........................*
+// *=======================================================*
+
+// *=======================================================*
+// *.......................TRIANGLES.......................*
+/*<asyxml><function type="point" signature="orthocentercenter(point,point,point)"><code></asyxml>*/
+point orthocentercenter(point A, point B, point C)
+{/*<asyxml></code><documentation>Return the orthocenter of the triangle ABC.</documentation></function></asyxml>*/
+ point[] P=standardizecoordsys(A,B,C);
+ coordsys R=P[0].coordsys;
+ pair pp=extension(A, projection(P[1],P[2])*P[0], B, projection(P[0],P[2])*P[1]);
+ return point(R,pp/R);
+}
+
+/*<asyxml><function type="point" signature="centroid(point,point,point)"><code></asyxml>*/
+point centroid(point A, point B, point C)
+{/*<asyxml></code><documentation>Return the centroid of the triangle ABC.</documentation></function></asyxml>*/
+ return (A+B+C)/3;
+}
+
+/*<asyxml><function type="point" signature="incenter(point,point,point)"><code></asyxml>*/
+point incenter(point A, point B, point C)
+{/*<asyxml></code><documentation>Return the center of the incircle of the triangle ABC.</documentation></function></asyxml>*/
+ point[] P=standardizecoordsys(A,B,C);
+ coordsys R=P[0].coordsys;
+ pair a=A, b=B, c=C;
+ pair pp=extension(a, a+dir(a--b,a--c), b, b+dir(b--a,b--c));
+ return point(R,pp/R);
+}
+
+/*<asyxml><function type="real" signature="inradius(point,point,point)"><code></asyxml>*/
+real inradius(point A, point B, point C)
+{/*<asyxml></code><documentation>Return the radius of the incircle of the triangle ABC.</documentation></function></asyxml>*/
+ point IC=incenter(A,B,C);
+ return abs(IC-projection(A,B)*IC);
+}
+
+/*<asyxml><function type="circle" signature="incircle(point,point,point)"><code></asyxml>*/
+circle incircle(point A, point B, point C)
+{/*<asyxml></code><documentation>Return the incircle of the triangle ABC.</documentation></function></asyxml>*/
+ point IC=incenter(A, B, C);
+ return circle(IC,abs(IC-projection(A,B)*IC));
+}
+
+/*<asyxml><function type="point" signature="excenter(point,point,point)"><code></asyxml>*/
+point excenter(point A, point B, point C)
+{/*<asyxml></code><documentation>Return the center of the excircle of the triangle tangent with (AB).</documentation></function></asyxml>*/
+ point[] P=standardizecoordsys(A,B,C);
+ coordsys R=P[0].coordsys;
+ pair a=A, b=B, c=C;
+ pair pp=extension(a, a+rotate(90)*dir(a--b,a--c), b, b+rotate(90)*dir(b--a,b--c));
+ return point(R,pp/R);
+}
+
+/*<asyxml><function type="real" signature="exradius(point,point,point)"><code></asyxml>*/
+real exradius(point A, point B, point C)
+{/*<asyxml></code><documentation>Return the radius of the excircle of the triangle ABC with (AB).</documentation></function></asyxml>*/
+ point EC=excenter(A,B,C);
+ return abs(EC-projection(A,B)*EC);
+}
+
+/*<asyxml><function type="circle" signature="excircle(point,point,point)"><code></asyxml>*/
+circle excircle(point A, point B, point C)
+{/*<asyxml></code><documentation>Return the excircle of the triangle ABC tangent with (AB).</documentation></function></asyxml>*/
+ point center=excenter(A,B,C);
+ real radius=abs(center-projection(B,C)*center);
+ return circle(center,radius);
+}
+
+private int[] numarray={1,2,3};
+numarray.cyclic(true);
+
+/*<asyxml><struct signature="triangle"><code></asyxml>*/
+struct triangle {/*<asyxml></code><documentation></documentation></asyxml>*/
+
+ /*<asyxml><struct signature="vertex"><code></asyxml>*/
+ struct vertex {/*<asyxml></code><documentation>Structure used to communicate the vertex of a triangle.</documentation><property type="int" signature="n"><code></asyxml>*/
+ int n;/*<asyxml></code><documentation>1 means VA, 2 means VB, 3 means VC, 4 means VA etc...</documentation></property><property type="triangle" signature="triangle"><code></asyxml>*/
+ triangle t;/*<asyxml></code><documentation>The triangle to which the vertex refers.</documentation></property></asyxml>*/
+ }/*<asyxml></struct></asyxml>*/
+
+ /*<asyxml><property type="point" signature="A, B, C"><code></asyxml>*/
+ restricted point A, B, C;/*<asyxml></code><documentation>The vertices of the triangle (as point).</documentation></property><property type="vertex" signature="VA, VB, VC"><code></asyxml>*/
+ restricted vertex VA, VB, VC;/*<asyxml></code><documentation>The vertices of the triangle (as vertex).
+ Note that the vertex structure contains the triangle to wish it refers.</documentation></property></asyxml>*/
+ VA.n=1;VB.n=2;VC.n=3;
+
+ /*<asyxml><method type="vertex" signature="vertex(int)"><code></asyxml>*/
+ vertex vertex(int n)
+ {/*<asyxml></code><documentation>Return numbered vertex.
+ 'n' is 1 means VA, 2 means VB, 3 means VC, 4 means VA etc...</documentation></method></asyxml>*/
+ n = numarray[n-1];
+ if(n == 1) return VA;
+ else if(n == 2) return VB;
+ return VC;
+ }
+
+ /*<asyxml><method type="point" signature="point(int)"><code></asyxml>*/
+ point point(int n)
+ {/*<asyxml></code><documentation>Return numbered point.
+ n is 1 means A, 2 means B, 3 means C, 4 means A etc...</documentation></method></asyxml>*/
+ n = numarray[n-1];
+ if(n == 1) return A;
+ else if(n == 2) return B;
+ return C;
+ }
+
+ /*<asyxml><method type="void" signature="init(point,point,point)"><code></asyxml>*/
+ void init(point A, point B, point C)
+ {/*<asyxml></code><documentation>Constructor.</documentation></method></asyxml>*/
+ point[] P=standardizecoordsys(A,B,C);
+ this.A=P[0];
+ this.B=P[1];
+ this.C=P[2];
+ VA.t=this; VB.t=this; VC.t=this;
+ }
+
+ /*<asyxml><method type="void" signature="operator init(point,point,point)"><code></asyxml>*/
+ void operator init(point A, point B, point C)
+ {/*<asyxml></code><documentation>For backward compatibility.
+ Provide the routine 'triangle(point A, point B, point C)'.</documentation></method></asyxml>*/
+ this.init(A,B,C);
+ }
+
+ /*<asyxml><method type="void" signature="init(real,real,real,real,point)"><code></asyxml>*/
+ void operator init(real b, real alpha, real c, real angle=0, point A=(0,0))
+ {/*<asyxml></code><documentation>For backward compatibility.
+ Provide the routine 'triangle(real b, real alpha, real c, real angle=0, point A=(0,0))
+ which returns the triangle ABC rotated by 'angle' (in degrees) and where b=AC, degrees(A)=alpha, AB=c.</documentation></method></asyxml>*/
+ coordsys R=A.coordsys;
+ this.init(A,A+R.polar(c,radians(angle)),A+R.polar(b,radians(angle+alpha)));
+ }
+
+ /*<asyxml><method type="real" signature="a(),b(),c()"><code></asyxml>*/
+ real a()
+ {/*<asyxml></code><documentation>Return the length BC.
+ b() and c() are also defined and return the length AC and AB respectively.</documentation></method></asyxml>*/
+ return length(C-B);
+ }
+ real b() {return length(A-C);}
+ real c() {return length(B-A);}
+
+ private real det(pair a, pair b) {return a.x*b.y-a.y*b.x;}
+
+ /*<asyxml><method type="real" signature="area()"><code></asyxml>*/
+ real area()
+ {/*<asyxml></code><documentation></documentation></method></asyxml>*/
+ pair a=locate(A), b=locate(B), c=locate(C);
+ return 0.5*abs(det(a,b)+det(b,c)+det(c,a));
+ }
+
+ /*<asyxml><method type="real" signature="alpha(),beta(),gamma()"><code></asyxml>*/
+ real alpha()
+ {/*<asyxml></code><documentation>Return the measure (in degrees) of the angle A.
+ beta() and gamma() are also defined and return the measure of the angles B and C respectively.</documentation></method></asyxml>*/
+ return degrees(acos((b()^2+c()^2-a()^2)/(2b()*c())));
+ }
+ real beta() {return degrees(acos((c()^2+a()^2-b()^2)/(2c()*a())));}
+ real gamma() {return degrees(acos((a()^2+b()^2-c()^2)/(2a()*b())));}
+
+ /*<asyxml><method type="path" signature="Path()"><code></asyxml>*/
+ path Path()
+ {/*<asyxml></code><documentation>The path of the triangle.</documentation></method></asyxml>*/
+ return A--C--B--cycle;
+ }
+
+ /*<asyxml><struct signature="side"><code></asyxml>*/
+ struct side
+ {/*<asyxml></code><documentation>Structure used to communicate the side of a triangle.</documentation><property type="int" signature="n"><code></asyxml>*/
+ int n;/*<asyxml></code><documentation>1 or 0 means [AB], -1 means [BA], 2 means [BC], -2 means [CB] etc.</documentation></property><property type="triangle" signature="triangle"><code></asyxml>*/
+ triangle t;/*<asyxml></code><documentation>The triangle to which the side refers.</documentation></property></asyxml>*/
+ }/*<asyxml></struct></asyxml>*/
+
+ /*<asyxml><property type="side" signature="AB"><code></asyxml>*/
+ side AB;/*<asyxml></code><documentation>For the routines using the structure 'side', triangle.AB means 'side AB'.
+ BA, AC, CA etc are also defined.</documentation></property></asyxml>*/
+ AB.n=1; AB.t=this;
+ side BA; BA.n=-1; BA.t=this;
+ side BC; BC.n=2; BC.t=this;
+ side CB; CB.n=-2; CB.t=this;
+ side CA; CA.n=3; CA.t=this;
+ side AC; AC.n=-3; AC.t=this;
+
+ /*<asyxml><method type="side" signature="side(int)"><code></asyxml>*/
+ side side(int n)
+ {/*<asyxml></code><documentation>Return numbered side.
+ n is 1 means AB, -1 means BA, 2 means BC, -2 means CB, etc.</documentation></method></asyxml>*/
+ if(n == 0) abort('Invalid side number.');
+ int an=numarray[abs(n)-1];
+ if(an == 1) return n > 0 ? AB : BA;
+ else if(an == 2) return n > 0 ? BC : CB;
+ return n > 0 ? CA : AC;
+ }
+
+ /*<asyxml><method type="line" signature="line(int)"><code></asyxml>*/
+ line line(int n)
+ {/*<asyxml></code><documentation>Return the numbered line.</documentation></method></asyxml>*/
+ if(n == 0) abort('Invalid line number.');
+ int an=numarray[abs(n)-1];
+ if(an == 1) return n > 0 ? line(A,B) : line(B,A);
+ else if(an == 2) return n > 0 ? line(B,C) : line(C,B);
+ return n > 0 ? line(C,A) : line(A,C);
+ }
+
+}/*<asyxml></struct></asyxml>*/
+
+from triangle unravel side; // The structure 'side' is now available outside the triangle structure.
+from triangle unravel vertex; // The structure 'vertex' is now available outside the triangle structure.
+
+triangle[] operator ^^(triangle[] t1, triangle t2)
+{
+ triangle[] T;
+ for (int i=0; i < t1.length; ++i) T.push(t1[i]);
+ T.push(t2);
+ return T;
+}
+
+triangle[] operator ^^(... triangle[] t)
+{
+ triangle[] T;
+ for (int i=0; i < t.length; ++i) {
+ T.push(t[i]);
+ }
+ return T;
+}
+
+/*<asyxml><operator type="line" signature="cast(side)"><code></asyxml>*/
+line operator cast(side side)
+{/*<asyxml></code><documentation>Cast side to (infinite) line.
+ Most routine with line parameters works with side parameters.
+ One can use the code 'segment(a_side)' to obtain a line segment.</documentation></operator></asyxml>*/
+ triangle t=side.t;
+ return t.line(side.n);
+}
+
+/*<asyxml><function type="line" signature="line(explicit side)"><code></asyxml>*/
+line line(explicit side side)
+{/*<asyxml></code><documentation>Return 'side' as line.</documentation></function></asyxml>*/
+ return (line)side;
+}
+
+/*<asyxml><function type="segment" signature="segment(explicit side)"><code></asyxml>*/
+segment segment(explicit side side)
+{/*<asyxml></code><documentation>Return 'side' as segment.</documentation></function></asyxml>*/
+ return (segment)(line)side;
+}
+
+/*<asyxml><operator type="point" signature="cast(vertex)"><code></asyxml>*/
+point operator cast(vertex V)
+{/*<asyxml></code><documentation>Cast vertex to point.
+ Most routine with point parameters works with vertex parameters.</documentation></operator></asyxml>*/
+ return V.t.point(V.n);
+}
+
+/*<asyxml><function type="point" signature="point(explicit vertex)"><code></asyxml>*/
+point point(explicit vertex V)
+{/*<asyxml></code><documentation>Return the point corresponding to the vertex 'V'.</documentation></function></asyxml>*/
+ return (point)V;
+}
+
+/*<asyxml><function type="side" signature="opposite(vertex)"><code></asyxml>*/
+side opposite(vertex V)
+{/*<asyxml></code><documentation>Return the opposite side of vertex 'V'.</documentation></function></asyxml>*/
+ return V.t.side(numarray[abs(V.n)]);
+}
+
+/*<asyxml><function type="vertex" signature="opposite(side)"><code></asyxml>*/
+vertex opposite(side side)
+{/*<asyxml></code><documentation>Return the opposite vertex of side 'side'.</documentation></function></asyxml>*/
+ return side.t.vertex(numarray[abs(side.n)+1]);
+}
+
+/*<asyxml><function type="point" signature="midpoint(side)"><code></asyxml>*/
+point midpoint(side side)
+{/*<asyxml></code><documentation></documentation></function></asyxml>*/
+ return midpoint(segment(side));
+}
+
+/*<asyxml><operator type="triangle" signature="*(transform,triangle)"><code></asyxml>*/
+triangle operator *(transform T, triangle t)
+{/*<asyxml></code><documentation>Provide transform*triangle.</documentation></operator></asyxml>*/
+ return triangle(T*t.A,T*t.B,T*t.C);
+}
+
+/*<asyxml><function type="triangle" signature="triangleAbc(real,real,real,real,point)"><code></asyxml>*/
+triangle triangleAbc(real alpha, real b, real c, real angle=0, point A=(0,0))
+{/*<asyxml></code><documentation>Return the triangle ABC rotated by 'angle' with BAC=alpha, AC=b and AB=c.</documentation></function></asyxml>*/
+ triangle T;
+ coordsys R=A.coordsys;
+ T.init(A,A+R.polar(c,radians(angle)),A+R.polar(b,radians(angle+alpha)));
+ return T;
+}
+
+/*<asyxml><function type="triangle" signature="triangleabc(real,real,real,real,point)"><code></asyxml>*/
+triangle triangleabc(real a, real b, real c, real angle=0, point A=(0,0))
+{/*<asyxml></code><documentation>Return the triangle ABC rotated by 'angle' with BC=a, AC=b and AB=c.</documentation></function></asyxml>*/
+ triangle T;
+ coordsys R=A.coordsys;
+ T.init(A,A+R.polar(c,radians(angle)),A+R.polar(b,radians(angle)+acos((b^2+c^2-a^2)/(2*b*c))));
+ return T;
+}
+
+/*<asyxml><function type="triangle" signature="triangle(line,line,line)"><code></asyxml>*/
+triangle triangle(line l1, line l2, line l3)
+{/*<asyxml></code><documentation>Return the triangle defined by three line.</documentation></function></asyxml>*/
+ point P1,P2,P3;
+ P1=intersectionpoint(l1,l2);
+ P2=intersectionpoint(l1,l3);
+ P3=intersectionpoint(l2,l3);
+ if(!(defined(P1) && defined(P2) && defined(P3))) abort("triangle: two lines are parallel.");
+ return triangle(P1,P2,P3);
+}
+
+/*<asyxml><function type="point" signature="foot(vertex)"><code></asyxml>*/
+point foot(vertex V)
+{/*<asyxml></code><documentation>Return the endpoint of the altitude from V.</documentation></function></asyxml>*/
+ return projection((line)opposite(V))*((point)V);
+}
+
+/*<asyxml><function type="point" signature="foot(side)"><code></asyxml>*/
+point foot(side side)
+{/*<asyxml></code><documentation>Return the endpoint of the altitude on 'side'.</documentation></function></asyxml>*/
+ return projection((line)side)*point(opposite(side));
+}
+
+/*<asyxml><function type="line" signature="altitude(vertex)"><code></asyxml>*/
+line altitude(vertex V)
+{/*<asyxml></code><documentation>Return the altitude passing through 'V'.</documentation></function></asyxml>*/
+ return line(point(V),foot(V));
+}
+
+/*<asyxml><function type="line" signature="altitude(vertex)"><code></asyxml>*/
+line altitude(side side)
+{/*<asyxml></code><documentation>Return the altitude cutting 'side'.</documentation></function></asyxml>*/
+ return altitude(opposite(side));
+}
+
+/*<asyxml><function type="point" signature="orthocentercenter(triangle)"><code></asyxml>*/
+point orthocentercenter(triangle t)
+{/*<asyxml></code><documentation>Return the orthocenter of the triangle t.</documentation></function></asyxml>*/
+ return orthocentercenter(t.A,t.B,t.C);
+}
+
+/*<asyxml><function type="point" signature="centroid(triangle)"><code></asyxml>*/
+point centroid(triangle t)
+{/*<asyxml></code><documentation>Return the centroid of the triangle 't'.</documentation></function></asyxml>*/
+ return (t.A+t.B+t.C)/3;
+}
+
+/*<asyxml><function type="point" signature="circumcenter(triangle)"><code></asyxml>*/
+point circumcenter(triangle t)
+{/*<asyxml></code><documentation>Return the circumcenter of the triangle 't'.</documentation></function></asyxml>*/
+ return circumcenter(t.A,t.B,t.C);
+}
+
+/*<asyxml><function type="circle" signature="circle(triangle)"><code></asyxml>*/
+circle circle(triangle t)
+{/*<asyxml></code><documentation>Return the circumcircle of the triangle 't'.</documentation></function></asyxml>*/
+ return circle(t.A,t.B,t.C);
+}
+
+/*<asyxml><function type="circle" signature="circumcircle(triangle)"><code></asyxml>*/
+circle circumcircle(triangle t)
+{/*<asyxml></code><documentation>Return the circumcircle of the triangle 't'.</documentation></function></asyxml>*/
+ return circle(t.A,t.B,t.C);
+}
+
+/*<asyxml><function type="point" signature="incenter(triangle)"><code></asyxml>*/
+point incenter(triangle t)
+{/*<asyxml></code><documentation>Return the center of the incircle of the triangle 't'.</documentation></function></asyxml>*/
+ return incenter(t.A,t.B,t.C);
+}
+
+/*<asyxml><function type="real" signature="inradius(triangle)"><code></asyxml>*/
+real inradius(triangle t)
+{/*<asyxml></code><documentation>Return the radius of the incircle of the triangle 't'.</documentation></function></asyxml>*/
+ return inradius(t.A,t.B,t.C);
+}
+
+/*<asyxml><function type="circle" signature="incircle(triangle)"><code></asyxml>*/
+circle incircle(triangle t)
+{/*<asyxml></code><documentation>Return the the incircle of the triangle 't'.</documentation></function></asyxml>*/
+ return incircle(t.A,t.B,t.C);
+}
+
+/*<asyxml><function type="point" signature="excenter(side,triangle)"><code></asyxml>*/
+point excenter(side side)
+{/*<asyxml></code><documentation>Return the center of the excircle tangent with the side 'side' of its triangle.
+ side=0 means AB, 1 means AC, other means BC.
+ One must use the predefined sides t.AB, t.AC where 't' is a triangle....</documentation></function></asyxml>*/
+ point op;
+ triangle t=side.t;
+ int n=numarray[abs(side.n)-1];
+ if(n == 1) op=excenter(t.A,t.B,t.C);
+ else if(n == 2) op=excenter(t.B,t.C,t.A);
+ else op=excenter(t.C,t.A,t.B);
+ return op;
+}
+
+/*<asyxml><function type="real" signature="exradius(side,triangle)"><code></asyxml>*/
+real exradius(side side)
+{/*<asyxml></code><documentation>Return radius of the excircle tangent with the side 'side' of its triangle.
+ side=0 means AB, 1 means BC, other means CA.
+ One must use the predefined sides t.AB, t.AC where 't' is a triangle....</documentation></function></asyxml>*/
+ real or;
+ triangle t=side.t;
+ int n=numarray[abs(side.n)-1];
+ if(n == 1) or=exradius(t.A,t.B,t.C);
+ else if(n == 2) or=exradius(t.B,t.C,t.A);
+ else or=exradius(t.A,t.C,t.B);
+ return or;
+}
+
+/*<asyxml><function type="circle" signature="excircle(side,triangle)"><code></asyxml>*/
+circle excircle(side side)
+{/*<asyxml></code><documentation>Return the excircle tangent with the side 'side' of its triangle.
+ side=0 means AB, 1 means AC, other means BC.
+ One must use the predefined sides t.AB, t.AC where 't' is a triangle....</documentation></function></asyxml>*/
+ circle oc;
+ int n=numarray[abs(side.n)-1];
+ triangle t=side.t;
+ if(n == 1) oc=excircle(t.A,t.B,t.C);
+ else if(n == 2) oc=excircle(t.B,t.C,t.A);
+ else oc=excircle(t.A,t.C,t.B);
+ return oc;
+}
+
+/*<asyxml><struct signature="trilinear"><code></asyxml>*/
+struct trilinear
+{/*<asyxml></code><documentation>Trilinear coordinates 'a:b:c' relative to triangle 't'.
+ <url href="http://mathworld.wolfram.com/TrilinearCoordinates.html"/></documentation><property type="real" signature="a,b,c"><code></asyxml>*/
+ real a,b,c;/*<asyxml></code><documentation>The trilinear coordinates.</documentation></property><property type="triangle" signature="t"><code></asyxml>*/
+ triangle t;/*<asyxml></code><documentation>The reference triangle.</documentation></property></asyxml>*/
+}/*<asyxml></struct></asyxml>*/
+
+/*<asyxml><function type="trilinear" signature="trilinear(triangle,real,real,real)"><code></asyxml>*/
+trilinear trilinear(triangle t, real a, real b, real c)
+{/*<asyxml></code><documentation>Return the trilinear coordinates relative to 't'.
+ <url href="http://mathworld.wolfram.com/TrilinearCoordinates.html"/></documentation></function></asyxml>*/
+ trilinear ot;
+ ot.a=a; ot.b=b; ot.c=c;
+ ot.t=t;
+ return ot;
+}
+
+/*<asyxml><function type="trilinear" signature="trilinear(triangle,point)"><code></asyxml>*/
+trilinear trilinear(triangle t, point M)
+{/*<asyxml></code><documentation>Return the trilinear coordinates of 'M' relative to 't'.
+ <url href="http://mathworld.wolfram.com/TrilinearCoordinates.html"/></documentation></function></asyxml>*/
+ trilinear ot;
+ pair m=locate(M);
+ int sameside(pair A, pair B, pair m, pair p)
+ {// Return 1 if 'm' and 'p' are same side of line (AB) else return -1.
+ pair mil=(A+B)/2;
+ pair mA=rotate(90,mil)*A;
+ pair mB=rotate(-90,mil)*A;
+ return (abs(m-mA) <= abs(m-mB)) == (abs(p-mA) <= abs(p-mB)) ? 1 : -1;
+ }
+ real det(pair a, pair b) {return a.x*b.y-a.y*b.x;}
+ real area(pair a, pair b, pair c){return 0.5*abs(det(a,b)+det(b,c)+det(c,a));}
+ pair A=t.A, B=t.B, C=t.C;
+ real t1=area(B,C,m), t2=area(C,A,m), t3=area(A,B,m);
+ ot.a=sameside(B,C,A,m)*t1/t.a();
+ ot.b=sameside(A,C,B,m)*t2/t.b();
+ ot.c=sameside(A,B,C,m)*t3/t.c();
+ ot.t=t;
+ return ot;
+}
+
+/*<asyxml><function type="void" signature="write(trilinear)"><code></asyxml>*/
+void write(trilinear tri)
+{/*<asyxml></code><documentation></documentation></function></asyxml>*/
+ write(format("%f : ", tri.a)+format("%f : ", tri.b)+format("%f",tri.c));
+}
+
+/*<asyxml><function type="point" signature="trilinear(triangle,real,real,real)"><code></asyxml>*/
+point point(trilinear tri)
+{/*<asyxml></code><documentation>Return the trilinear coordinates relative to 't'.
+ <url href="http://mathworld.wolfram.com/TrilinearCoordinates.html"/></documentation></function></asyxml>*/
+ triangle t=tri.t;
+ return masscenter(0.5*t.a()*mass(t.A,tri.a),
+ 0.5*t.b()*mass(t.B,tri.b),
+ 0.5*t.c()*mass(t.C,tri.c));
+}
+
+/*<asyxml><function type="int[]" signature="tricoef(side)"><code></asyxml>*/
+int[] tricoef(side side)
+{/*<asyxml></code><documentation>Return an array of integer (values are 0 or 1) which represents 'side'.
+ For example, side=t.BC will be represented by {0,1,1}.</documentation></function></asyxml>*/
+ int[] oi;
+ int n=numarray[abs(side.n)-1];
+ oi.push((n == 1 || n == 3) ? 1 : 0);
+ oi.push((n == 1 || n == 2) ? 1 : 0);
+ oi.push((n == 2 || n == 3) ? 1 : 0);
+ return oi;
+}
+
+/*<asyxml><operator type="point" signature="cast(trilinear)"><code></asyxml>*/
+point operator cast(trilinear tri)
+{/*<asyxml></code><documentation>Cast trilinear to point.
+ One may use the routine 'point(trilinear)' to force the casting.</documentation></operator></asyxml>*/
+ return point(tri);
+}
+
+/*<asyxml><typedef type="centerfunction" return="real" params="real,real,real"><code></asyxml>*/
+typedef real centerfunction(real,real,real);/*<asyxml></code><documentation><url href="http://mathworld.wolfram.com/TriangleCenterFunction.html"/></documentation></typedef></asyxml>*/
+
+/*<asyxml><function type="trilinear" signature="trilinear(triangle,centerfunction,real,real,real)"><code></asyxml>*/
+trilinear trilinear(triangle t, centerfunction f, real a=t.a(), real b=t.b(), real c=t.c())
+{/*<asyxml></code><documentation><url href="http://mathworld.wolfram.com/TriangleCenterFunction.html"/></documentation></function></asyxml>*/
+ return trilinear(t,f(a,b,c),f(b,c,a),f(c,a,b));
+}
+
+/*<asyxml><function type="point" signature="symmedian(triangle)"><code></asyxml>*/
+point symmedian(triangle t)
+{/*<asyxml></code><documentation>Return the symmedian point of 't'.</documentation></function></asyxml>*/
+ point A,B,C;
+ real a=t.a(), b=t.b(), c=t.c();
+ A=trilinear(t, 0, b, c);
+ B=trilinear(t, a, 0, c);
+ return intersectionpoint(line(t.A,A),line(t.B,B));
+}
+
+/*<asyxml><function type="point" signature="symmedian(side)"><code></asyxml>*/
+point symmedian(side side)
+{/*<asyxml></code><documentation>The symmedian point on the side 'side'.</documentation></function></asyxml>*/
+ triangle t=side.t;
+ int n=numarray[abs(side.n)-1];
+ if(n == 1) return trilinear(t, t.a(), t.b(), 0);
+ if(n == 2) return trilinear(t, 0, t.b(), t.c());
+ return trilinear(t, t.a(), 0, t.c());
+}
+
+/*<asyxml><function type="line" signature="symmedian(vertex)"><code></asyxml>*/
+line symmedian(vertex V)
+{/*<asyxml></code><documentation>Return the symmedian passing through 'V'.</documentation></function></asyxml>*/
+ return line(point(V),symmedian(V.t));
+}
+
+/*<asyxml><function type="triangle" signature="cevian(triangle,point)"><code></asyxml>*/
+triangle cevian(triangle t, point P)
+{/*<asyxml></code><documentation>Return the Cevian triangle with respect of 'P'
+ <url href="http://mathworld.wolfram.com/CevianTriangle.html"/>.</documentation></function></asyxml>*/
+ trilinear tri=trilinear(t,locate(P));
+ point A=point(trilinear(t,0,tri.b,tri.c));
+ point B=point(trilinear(t,tri.a,0,tri.c));
+ point C=point(trilinear(t,tri.a,tri.b,0));
+ return triangle(A,B,C);
+}
+
+/*<asyxml><function type="point" signature="cevian(side,point)"><code></asyxml>*/
+point cevian(side side, point P)
+{/*<asyxml></code><documentation>Return the Cevian point on 'side' with respect of 'P'.</documentation></function></asyxml>*/
+ triangle t=side.t;
+ trilinear tri=trilinear(t,locate(P));
+ int[] s=tricoef(side);
+ return point(trilinear(t,s[0]*tri.a, s[1]*tri.b, s[2]*tri.c));
+}
+
+/*<asyxml><function type="line" signature="cevian(vertex,point)"><code></asyxml>*/
+line cevian(vertex V, point P)
+{/*<asyxml></code><documentation>Return line passing through 'V' and its Cevian image with respect of 'P'.</documentation></function></asyxml>*/
+ return line(point(V), cevian(opposite(V), P));
+}
+
+/*<asyxml><function type="point" signature="gergonne(triangle)"><code></asyxml>*/
+point gergonne(triangle t)
+{/*<asyxml></code><documentation>Return the Gergonne point of 't'.</documentation></function></asyxml>*/
+ real f(real a, real b, real c){return 1/(a*(b+c-a));}
+ return point(trilinear(t,f));
+}
+
+/*<asyxml><function type="point[]" signature="fermat(triangle)"><code></asyxml>*/
+point[] fermat(triangle t)
+{/*<asyxml></code><documentation>Return the Fermat points of 't'.</documentation></function></asyxml>*/
+ point[] P;
+ real A=t.alpha(), B=t.beta(), C=t.gamma();
+ P.push(point(trilinear(t,1/Sin(A+60), 1/Sin(B+60), 1/Sin(C+60))));
+ P.push(point(trilinear(t,1/Sin(A-60), 1/Sin(B-60), 1/Sin(C-60))));
+ return P;
+}
+
+/*<asyxml><function type="point" signature="isotomicconjugate(triangle,point)"><code></asyxml>*/
+point isotomicconjugate(triangle t, point M)
+{/*<asyxml></code><documentation><url href="http://mathworld.wolfram.com/IsotomicConjugate.html"/></documentation></function></asyxml>*/
+ if(!inside(t.Path(),locate(M))) abort("isotomic: the point must be inside the triangle.");
+ trilinear tr=trilinear(t,M);
+ return point(trilinear(t,1/(t.a()^2*tr.a),1/(t.b()^2*tr.b),1/(t.c()^2*tr.c)));
+}
+
+/*<asyxml><function type="line" signature="isotomic(vertex,point)"><code></asyxml>*/
+line isotomic(vertex V, point M)
+{/*<asyxml></code><documentation><url href="http://mathworld.wolfram.com/IsotomicConjugate.html"/>.</documentation></function></asyxml>*/
+ side op=opposite(V);
+ return line(V,rotate(180,midpoint(op))*cevian(op,M));
+}
+
+/*<asyxml><function type="point" signature="isotomic(side,point)"><code></asyxml>*/
+point isotomic(side side, point M)
+{/*<asyxml></code><documentation><url href="http://mathworld.wolfram.com/IsotomicConjugate.html"/></documentation></function></asyxml>*/
+ return intersectionpoint(isotomic(opposite(side),M), side);
+}
+
+/*<asyxml><function type="triangle" signature="isotomic(triangle,point)"><code></asyxml>*/
+triangle isotomic(triangle t, point M)
+{/*<asyxml></code><documentation><url href="http://mathworld.wolfram.com/IsotomicConjugate.html"/></documentation></function></asyxml>*/
+ return triangle(isotomic(t.BC,M),isotomic(t.CA,M),isotomic(t.AB,M));
+}
+
+/*<asyxml><function type="point" signature="isogonalconjugate(triangle,point)"><code></asyxml>*/
+point isogonalconjugate(triangle t, point M)
+{/*<asyxml></code><documentation><url href="http://mathworld.wolfram.com/IsogonalConjugate.html"/></documentation></function></asyxml>*/
+ trilinear tr=trilinear(t,M);
+ return point(trilinear(t,1/tr.a,1/tr.b,1/tr.c));
+}
+
+/*<asyxml><function type="point" signature="isogonal(side,point)"><code></asyxml>*/
+point isogonal(side side, point M)
+{/*<asyxml></code><documentation><url href="http://mathworld.wolfram.com/IsogonalConjugate.html"/></documentation></function></asyxml>*/
+ return cevian(side,isogonalconjugate(side.t,M));
+}
+
+/*<asyxml><function type="line" signature="isogonal(vertex,point)"><code></asyxml>*/
+line isogonal(vertex V, point M)
+{/*<asyxml></code><documentation><url href="http://mathworld.wolfram.com/IsogonalConjugate.html"/></documentation></function></asyxml>*/
+ return line(V,isogonal(opposite(V),M));
+}
+
+/*<asyxml><function type="triangle" signature="isogonal(triangle,point)"><code></asyxml>*/
+triangle isogonal(triangle t, point M)
+{/*<asyxml></code><documentation><url href="http://mathworld.wolfram.com/IsogonalConjugate.html"/></documentation></function></asyxml>*/
+ return triangle(isogonal(t.BC,M),isogonal(t.CA,M),isogonal(t.AB,M));
+}
+
+/*<asyxml><function type="triangle" signature="pedal(triangle,point)"><code></asyxml>*/
+triangle pedal(triangle t, point M)
+{/*<asyxml></code><documentation>Return the pedal triangle of 'M' in 't'.
+ <url href="http://mathworld.wolfram.com/PedalTriangle.html"/></documentation></function></asyxml>*/
+ return triangle(projection(t.BC)*M,projection(t.AC)*M,projection(t.AB)*M);
+}
+
+/*<asyxml><function type="triangle" signature="pedal(triangle,point)"><code></asyxml>*/
+line pedal(side side, point M)
+{/*<asyxml></code><documentation>Return the pedal line of 'M' cutting 'side'.
+ <url href="http://mathworld.wolfram.com/PedalTriangle.html"/></documentation></function></asyxml>*/
+ return line(M, projection(side)*M);
+}
+
+/*<asyxml><function type="triangle" signature="antipedal(triangle,point)"><code></asyxml>*/
+triangle antipedal(triangle t, point M)
+{/*<asyxml></code><documentation><url href="http://mathworld.wolfram.com/AntipedalTriangle.html"/></documentation></function></asyxml>*/
+ trilinear Tm=trilinear(t,M);
+ real a=Tm.a, b=Tm.b, c=Tm.c;
+ real CA=Cos(t.alpha()), CB=Cos(t.beta()), CC=Cos(t.gamma());
+ point A=trilinear(t,-(b+a*CC)*(c+a*CB),(c+a*CB)*(a+b*CC),(b+a*CC)*(a+c*CB));
+ point B=trilinear(t,(c+b*CA)*(b+a*CC),-(c+b*CA)*(a+b*CC),(a+b*CC)*(b+c*CA));
+ point C=trilinear(t,(b+c*CA)*(c+a*CB),(a+c*CB)*(c+b*CA),-(a+c*CB)*(b+c*CA));
+ return triangle(A,B,C);
+}
+
+/*<asyxml><function type="triangle" signature="extouch(triangle)"><code></asyxml>*/
+triangle extouch(triangle t)
+{/*<asyxml></code><documentation>Return the extouch triangle of the triangle 't'.
+ The extouch triangle of 't' is the triangle formed by the points
+ of tangency of a triangle 't' with its excircles.</documentation></function></asyxml>*/
+ point A,B,C;
+ real a=t.a(), b=t.b(), c=t.c();
+ A=trilinear(t, 0, (a-b+c)/b, (a+b-c)/c);
+ B=trilinear(t, (-a+b+c)/a, 0, (a+b-c)/c);
+ C=trilinear(t, (-a+b+c)/a, (a-b+c)/b, 0);
+ return triangle(A,B,C);
+}
+
+/*<asyxml><function type="triangle" signature="extouch(triangle)"><code></asyxml>*/
+triangle incentral(triangle t)
+{/*<asyxml></code><documentation>Return the incentral triangle of the triangle 't'.
+ It is the triangle whose vertices are determined by the intersections of the
+ reference triangle's angle bisectors with the respective opposite sides.</documentation></function></asyxml>*/
+ point A,B,C;
+ // real a=t.a(), b=t.b(), c=t.c();
+ A=trilinear(t, 0, 1, 1);
+ B=trilinear(t, 1, 0, 1);
+ C=trilinear(t, 1, 1, 0);
+ return triangle(A,B,C);
+}
+
+/*<asyxml><function type="triangle" signature="extouch(side)"><code></asyxml>*/
+triangle extouch(side side)
+{/*<asyxml></code><documentation>Return the triangle formed by the points of tangency of the triangle referenced by 'side' with its excircles.
+ One vertex of the returned triangle is on the segment 'side'.</documentation></function></asyxml>*/
+ triangle t=side.t;
+ transform p1=projection((line)t.AB);
+ transform p2=projection((line)t.AC);
+ transform p3=projection((line)t.BC);
+ point EP=excenter(side);
+ return triangle(p3*EP,p2*EP,p1*EP);
+}
+
+/*<asyxml><function type="point" signature="bisectorpoint(side)"><code></asyxml>*/
+point bisectorpoint(side side)
+{/*<asyxml></code><documentation>The intersection point of the angle bisector from the
+ opposite point of 'side' with the side 'side'.</documentation></function></asyxml>*/
+ triangle t=side.t;
+ int n=numarray[abs(side.n)-1];
+ if(n == 1) return trilinear(t, 1, 1, 0);
+ if(n == 2) return trilinear(t, 0, 1, 1);
+ return trilinear(t, 1, 0, 1);
+}
+
+/*<asyxml><function type="line" signature="bisector(vertex,real)"><code></asyxml>*/
+line bisector(vertex V, real angle=0)
+{/*<asyxml></code><documentation>Return the interior bisector passing through 'V' rotated by angle (in degrees)
+ around 'V'.</documentation></function></asyxml>*/
+ return rotate(angle,point(V))*line(point(V),incenter(V.t));
+}
+
+/*<asyxml><function type="line" signature="bisector(side)"><code></asyxml>*/
+line bisector(side side)
+{/*<asyxml></code><documentation>Return the bisector of the line segment 'side'.</documentation></function></asyxml>*/
+ return bisector(segment(side));
+}
+
+/*<asyxml><function type="point" signature="intouch(side)"><code></asyxml>*/
+point intouch(side side)
+{/*<asyxml></code><documentation>The point of tangency on the side 'side' of its incircle.</documentation></function></asyxml>*/
+ triangle t=side.t;
+ real a=t.a(), b=t.b(), c=t.c();
+ int n=numarray[abs(side.n)-1];
+ if(n == 1) return trilinear(t, b*c/(-a+b+c),a*c/(a-b+c), 0);
+ if(n == 2) return trilinear(t, 0, a*c/(a-b+c), a*b/(a+b-c));
+ return trilinear(t, b*c/(-a+b+c), 0, a*b/(a+b-c));
+}
+
+/*<asyxml><function type="triangle" signature="intouch(triangle)"><code></asyxml>*/
+triangle intouch(triangle t)
+{/*<asyxml></code><documentation>Return the intouch triangle of the triangle 't'.
+ The intouch triangle of 't' is the triangle formed by the points
+ of tangency of a triangle 't' with its incircles.</documentation></function></asyxml>*/
+ point A,B,C;
+ real a=t.a(), b=t.b(), c=t.c();
+ A=trilinear(t, 0, a*c/(a-b+c), a*b/(a+b-c));
+ B=trilinear(t, b*c/(-a+b+c), 0, a*b/(a+b-c));
+ C=trilinear(t, b*c/(-a+b+c), a*c/(a-b+c), 0);
+ return triangle(A,B,C);
+}
+
+/*<asyxml><function type="triangle" signature="tangential(triangle)"><code></asyxml>*/
+triangle tangential(triangle t)
+{/*<asyxml></code><documentation>Return the tangential triangle of the triangle 't'.
+ The tangential triangle of 't' is the triangle formed by the lines
+ tangent to the circumcircle of the given triangle 't' at its vertices.</documentation></function></asyxml>*/
+ point A,B,C;
+ real a=t.a(), b=t.b(), c=t.c();
+ A=trilinear(t, -a, b, c);
+ B=trilinear(t, a, -b, c);
+ C=trilinear(t, a, b, -c);
+ return triangle(A,B,C);
+}
+
+/*<asyxml><function type="triangle" signature="medial(triangle t)"><code></asyxml>*/
+triangle medial(triangle t)
+{/*<asyxml></code><documentation>Return the triangle whose vertices are midpoints of the sides of 't'.</documentation></function></asyxml>*/
+ return triangle(midpoint(t.BC),midpoint(t.AC),midpoint(t.AB));
+}
+
+/*<asyxml><function type="line" signature="median(vertex)"><code></asyxml>*/
+line median(vertex V)
+{/*<asyxml></code><documentation>Return median from 'V'.</documentation></function></asyxml>*/
+ return line(point(V),midpoint(segment(opposite(V))));
+}
+
+/*<asyxml><function type="line" signature="median(side)"><code></asyxml>*/
+line median(side side)
+{/*<asyxml></code><documentation>Return median from the opposite vertex of 'side'.</documentation></function></asyxml>*/
+ return median(opposite(side));
+}
+
+/*<asyxml><function type="triangle" signature="orthic(triangle)"><code></asyxml>*/
+triangle orthic(triangle t)
+{/*<asyxml></code><documentation>Return the triangle whose vertices are endpoints of the altitudes from each of the vertices of 't'.</documentation></function></asyxml>*/
+ return triangle(foot(t.BC),foot(t.AC),foot(t.AB));
+}
+
+/*<asyxml><function type="triangle" signature="symmedial(triangle)"><code></asyxml>*/
+triangle symmedial(triangle t)
+{/*<asyxml></code><documentation>Return the symmedial triangle of 't'.</documentation></function></asyxml>*/
+ point A,B,C;
+ real a=t.a(), b=t.b(), c=t.c();
+ A=trilinear(t, 0, b, c);
+ B=trilinear(t, a, 0, c);
+ C=trilinear(t, a, b, 0);
+ return triangle(A,B,C);
+}
+
+/*<asyxml><function type="triangle" signature="anticomplementary(triangle)"><code></asyxml>*/
+triangle anticomplementary(triangle t)
+{/*<asyxml></code><documentation>Return the triangle which has the given triangle 't' as its medial triangle.</documentation></function></asyxml>*/
+ real a=t.a(), b=t.b(), c=t.c();
+ real ab=a*b, bc=b*c, ca=c*a;
+ point A=trilinear(t, -bc, ca, ab);
+ point B=trilinear(t, bc, -ca, ab);
+ point C=trilinear(t, bc, ca, -ab);
+ return triangle(A,B,C);
+}
+
+/*<asyxml><function type="point[]" signature="intersectionpoints(triangle,line,bool)"><code></asyxml>*/
+point[] intersectionpoints(triangle t, line l, bool extended=false)
+{/*<asyxml></code><documentation>Return the intersection points.
+ If 'extended' is true, the sides are lines else the sides are segments.
+ intersectionpoints(line,triangle,bool) is also defined.</documentation></function></asyxml>*/
+ point[] OP;
+ void addpoint(point P)
+ {
+ if(defined(P)) {
+ bool exist=false;
+ for (int i=0; i < OP.length; ++i) {
+ if(P == OP[i]) {exist=true; break;}
+ }
+ if(!exist) OP.push(P);
+ }
+ }
+ if(extended) {
+ for (int i=0; i < 3; ++i) {
+ addpoint(intersectionpoint(t.line(i),l));
+ }
+ } else {
+ for (int i=0; i < 3; ++i) {
+ addpoint(intersectionpoint((segment)t.line(i),l));
+ }
+ }
+ return OP;
+}
+
+point[] intersectionpoints(line l, triangle t, bool extended=false)
+{
+ return intersectionpoints(t, l, extended);
+}
+
+/*<asyxml><function type="vector" signature="dir(vertex)"><code></asyxml>*/
+vector dir(vertex V)
+{/*<asyxml></code><documentation>The direction (towards the outside of the triangle) of the interior angle bisector of 'V'.</documentation></function></asyxml>*/
+ triangle t=V.t;
+ if(V.n == 1) return vector(defaultcoordsys,(-dir(t.A--t.B,t.A--t.C)));
+ if(V.n == 2) return vector(defaultcoordsys,(-dir(t.B--t.A,t.B--t.C)));
+ return vector(defaultcoordsys,(-dir(t.C--t.A,t.C--t.B)));
+}
+
+/*<asyxml><function type="void" signature="lvoid label(picture,Label,vertex,pair,real,pen,filltype)"><code></asyxml>*/
+void label(picture pic=currentpicture, Label L, vertex V,
+ pair align=dir(V),
+ real alignFactor=1,
+ pen p=nullpen, filltype filltype=NoFill)
+{/*<asyxml></code><documentation>Draw 'L' on picture 'pic' at vertex 'V' aligned by 'alignFactor*align'.</documentation></function></asyxml>*/
+ label(pic,L,locate(point(V)),alignFactor*align,p,filltype);
+}
+
+/*<asyxml><function type="void" signature="label(picture,Label,Label,Label,triangle,real,real,pen,filltype)"><code></asyxml>*/
+void label(picture pic=currentpicture, Label LA="$A$",
+ Label LB="$B$", Label LC="$C$",
+ triangle t,
+ real alignAngle=0,
+ real alignFactor=1,
+ pen p=nullpen, filltype filltype=NoFill)
+{/*<asyxml></code><documentation>Draw labels LA, LB and LC aligned in the rotated (by 'alignAngle' in degrees) direction
+ (towards the outside of the triangle) of the interior angle bisector of vertices.
+ One can individually modify the alignment by setting the Label parameter 'align'.</documentation></function></asyxml>*/
+ Label lla=LA.copy();
+ lla.align(lla.align,rotate(alignAngle)*locate(dir(t.VA)));
+ label(pic,LA,t.VA,align=lla.align.dir,alignFactor=alignFactor,p,filltype);
+ Label llb=LB.copy();
+ llb.align(llb.align,rotate(alignAngle)*locate(dir(t.VB)));
+ label(pic,llb,t.VB,align=llb.align.dir,alignFactor=alignFactor,p,filltype);
+ Label llc=LC.copy();
+ llc.align(llc.align,rotate(alignAngle)*locate(dir(t.VC)));
+ label(pic,llc,t.VC,align=llc.align.dir,alignFactor=alignFactor,p,filltype);
+}
+
+/*<asyxml><function type="void" signature="show(picture,Label,Label,Label,Label,Label,Label,triangle,pen,filltype)"><code></asyxml>*/
+void show(picture pic=currentpicture,
+ Label LA="$A$", Label LB="$B$", Label LC="$C$",
+ Label La="$a$", Label Lb="$b$", Label Lc="$c$",
+ triangle t, pen p=currentpen, filltype filltype=NoFill)
+{/*<asyxml></code><documentation>Draw triangle and labels of sides and vertices.</documentation></function></asyxml>*/
+ pair a=locate(t.A), b=locate(t.B), c=locate(t.C);
+ draw(pic,a--b--c--cycle,p);
+ label(pic,LA,a,-dir(a--b,a--c),p,filltype);
+ label(pic,LB,b,-dir(b--a,b--c),p,filltype);
+ label(pic,LC,c,-dir(c--a,c--b),p,filltype);
+ pair aligna=I*unit(c-b), alignb=I*unit(c-a), alignc=I*unit(b-a);
+ pair mAB=locate(midpoint(t.AB)), mAC=locate(midpoint(t.AC)), mBC=locate(midpoint(t.BC));
+ draw(pic,La,b--c, align=rotate(dot(a-mBC,aligna) > 0 ? 180 :0)*aligna,p);
+ draw(pic,Lb,a--c, align=rotate(dot(b-mAC,alignb) > 0 ? 180 :0)*alignb,p);
+ draw(pic,Lc,a--b, align=rotate(dot(c-mAB,alignc) > 0 ? 180 :0)*alignc,p);
+}
+
+/*<asyxml><function type="void" signature="draw(picture,triangle,pen,marker)"><code></asyxml>*/
+void draw(picture pic=currentpicture, triangle t, pen p=currentpen, marker marker=nomarker)
+{/*<asyxml></code><documentation>Draw sides of the triangle 't' on picture 'pic' using pen 'p'.</documentation></function></asyxml>*/
+ draw(pic,t.Path(),p,marker);
+}
+
+/*<asyxml><function type="void" signature="draw(picture,triangle[],pen,marker)"><code></asyxml>*/
+void draw(picture pic=currentpicture, triangle[] t, pen p=currentpen, marker marker=nomarker)
+{/*<asyxml></code><documentation>Draw sides of the triangles 't' on picture 'pic' using pen 'p'.</documentation></function></asyxml>*/
+ for(int i=0; i < t.length; ++i) draw(pic,t[i],p,marker);
+}
+
+/*<asyxml><function type="void" signature="drawline(picture,triangle,pen)"><code></asyxml>*/
+void drawline(picture pic=currentpicture, triangle t, pen p=currentpen)
+{/*<asyxml></code><documentation>Draw lines of the triangle 't' on picture 'pic' using pen 'p'.</documentation></function></asyxml>*/
+ draw(t,p);
+ draw(pic,line(t.A,t.B),p);
+ draw(pic,line(t.A,t.C),p);
+ draw(pic,line(t.B,t.C),p);
+}
+
+/*<asyxml><function type="void" signature="dot(picture,triangle,pen)"><code></asyxml>*/
+void dot(picture pic=currentpicture, triangle t, pen p=currentpen)
+{/*<asyxml></code><documentation>Draw a dot at each vertex of 't'.</documentation></function></asyxml>*/
+ dot(pic, t.A^^t.B^^t.C, p);
+}
+// *.......................TRIANGLES.......................*
+// *=======================================================*
+
+// *=======================================================*
+// *.......................INVERSIONS......................*
+/*<asyxml><function type="point" signature="inverse(real k,point,point)"><code></asyxml>*/
+point inverse(real k, point A, point M)
+{/*<asyxml></code><documentation>Return the inverse point of 'M' with respect to point A and inversion radius 'k'.</documentation></function></asyxml>*/
+ return A+k/conj(M-A);
+}
+
+/*<asyxml><function type="point" signature="radicalcenter(circle,circle)"><code></asyxml>*/
+point radicalcenter(circle c1, circle c2)
+{/*<asyxml></code><documentation><url href="http://fr.wikipedia.org/wiki/Puissance_d'un_point_par_rapport_%C3%A0_un_cercle"/></documentation></function></asyxml>*/
+ point[] P=standardizecoordsys(c1.C,c2.C);
+ real k=c1.r^2-c2.r^2;
+ pair C1=locate(c1.C);
+ pair C2=locate(c2.C);
+ pair oop=C2-C1;
+ pair K=(abs(oop) == 0) ?
+ (infinity,infinity) :
+ midpoint(C1--C2)+0.5*k*oop/dot(oop,oop);
+ return point(P[0].coordsys,K/P[0].coordsys);
+}
+
+/*<asyxml><function type="line" signature="radicalline(circle,circle)"><code></asyxml>*/
+line radicalline(circle c1, circle c2)
+{/*<asyxml></code><documentation><url href="http://fr.wikipedia.org/wiki/Puissance_d'un_point_par_rapport_%C3%A0_un_cercle"/></documentation></function></asyxml>*/
+ if (c1.C == c2.C) abort("radicalline: the centers must be distinct");
+ return perpendicular(radicalcenter(c1,c2),line(c1.C,c2.C));
+}
+
+/*<asyxml><function type="point" signature="radicalcenter(circle,circle,circle)"><code></asyxml>*/
+point radicalcenter(circle c1, circle c2, circle c3)
+{/*<asyxml></code><documentation><url href="http://fr.wikipedia.org/wiki/Puissance_d'un_point_par_rapport_%C3%A0_un_cercle"/></documentation></function></asyxml>*/
+ return intersectionpoint(radicalline(c1,c2),radicalline(c1,c3));
+}
+
+/*<asyxml><struct signature="inversion"><code></asyxml>*/
+struct inversion
+{/*<asyxml></code><documentation>http://mathworld.wolfram.com/Inversion.html</documentation></asyxml>*/
+ point C;
+ real k;
+}/*<asyxml></struct></asyxml>*/
+
+/*<asyxml><function type="inversion" signature="inversion(real,point)"><code></asyxml>*/
+inversion inversion(real k, point C)
+{/*<asyxml></code><documentation>Return the inversion with respect to 'C' having inversion radius 'k'.</documentation></function></asyxml>*/
+ inversion oi;
+ oi.k=k;
+ oi.C=C;
+ return oi;
+}
+/*<asyxml><function type="inversion" signature="inversion(real,point)"><code></asyxml>*/
+inversion inversion(point C, real k)
+{/*<asyxml></code><documentation>Return the inversion with respect to 'C' having inversion radius 'k'.</documentation></function></asyxml>*/
+ return inversion(k,C);
+}
+
+/*<asyxml><function type="inversion" signature="inversion(circle,circle)"><code></asyxml>*/
+inversion inversion(circle c1, circle c2, real sgn=1)
+{/*<asyxml></code><documentation>Return the inversion which transforms 'c1' to
+ . 'c2' and positive inversion radius if 'sgn > 0';
+ . 'c2' and negative inversion radius if 'sgn < 0';
+ . 'c1' and 'c2' to 'c2' if 'sgn = 0'.</documentation></function></asyxml>*/
+ if(sgn == 0) {
+ point O=radicalcenter(c1,c2);
+ return inversion(O^c1, O);
+ }
+ real a=abs(c1.r/c2.r);
+ if(sgn > 0) {
+ point O=c1.C+a/abs(1-a)*(c2.C-c1.C);
+ return inversion(a*abs(abs(O-c2.C)^2-c2.r^2),O);
+ }
+ point O=c1.C+a/abs(1+a)*(c2.C-c1.C);
+ return inversion(-a*abs(abs(O-c2.C)^2-c2.r^2),O);
+}
+
+/*<asyxml><function type="inversion" signature="inversion(circle,circle,circle)"><code></asyxml>*/
+inversion inversion(circle c1, circle c2, circle c3)
+{/*<asyxml></code><documentation>Return the inversion which transform 'c1' to 'c1', 'c2' to 'c2' and 'c3' to 'c3'.</documentation></function></asyxml>*/
+ point Rc=radicalcenter(c1,c2,c3);
+ return inversion(Rc, Rc^c1);
+}
+
+circle operator cast(inversion i){return circle(i.C, sgn(i.k)*sqrt(abs(i.k)));}
+/*<asyxml><function type="circle" signature="circle(inversion)"><code></asyxml>*/
+circle circle(inversion i)
+{/*<asyxml></code><documentation>Return the inversion circle of 'i'.</documentation></function></asyxml>*/
+ return i;
+}
+
+inversion operator cast(circle c)
+{
+ return inversion(sgn(c.r)*c.r^2, c.C);
+}
+/*<asyxml><function type="inversion" signature="inversion(circle)"><code></asyxml>*/
+inversion inversion(circle c)
+{/*<asyxml></code><documentation>Return the inversion represented by the circle of 'c'.</documentation></function></asyxml>*/
+ return c;
+}
+
+/*<asyxml><operator type="point" signature="*(inversion, point)"><code></asyxml>*/
+point operator *(inversion i, point P)
+{/*<asyxml></code><documentation>Provide inversion*point.</documentation></operator></asyxml>*/
+ return inverse(i.k,i.C,P);
+}
+
+/*<asyxml><function type="circle" signature="inverse(real,point,line)"><code></asyxml>*/
+circle inverse(real k, point A, line l)
+{/*<asyxml></code><documentation>Return the inverse circle of 'l' with
+ respect to point 'A' and inversion radius 'k'.</documentation></function></asyxml>*/
+ if(A @ l) {
+ write("Warning: the inversion of the line is not a circle.");
+ write("The returned circle has an infinite radius, cirlce.l have been set.");
+ circle C=circle(A, infinity);
+ C.l=l;
+ return C;
+ }
+ point Ap=inverse(k,A,l.A), Bp=inverse(k,A,l.B);
+ return circle(A,Ap,Bp);
+}
+
+/*<asyxml><operator type="circle" signature="*(inversion,line)"><code></asyxml>*/
+circle operator *(inversion i, line l)
+{/*<asyxml></code><documentation>Provide inversion*line for lines that don't pass through the inversion center.</documentation></operator></asyxml>*/
+ return inverse(i.k,i.C,l);
+}
+
+/*<asyxml><function type="circle" signature="inverse(real,point,circle)"><code></asyxml>*/
+circle inverse(real k, point A, circle c)
+{/*<asyxml></code><documentation>Return the inverse circle of 'c' with
+ respect to point A and inversion radius 'k'.</documentation></function></asyxml>*/
+ if(degenerate(c)) return inverse(k,A,c.l);
+ if(A @ c) {
+ write("Warning: the inversion of the circle is not a circle.");
+ write("The returned circle has an infinite radius, cirlce.l have been set.");
+ point M=rotate(180,c.C)*A, Mp=rotate(90,c.C)*A;
+ circle oc=circle(A,infinity);
+ oc.l=line(inverse(k,A,M),inverse(k,A,Mp));
+ return oc;
+ }
+ point[] P=standardizecoordsys(A,c.C);
+ real s=k/((P[1].x-P[0].x)^2+(P[1].y-P[0].y)^2-c.r^2);
+ return circle(P[0]+s*(P[1]-P[0]),abs(s)*c.r);
+}
+
+/*<asyxml><operator type="circle" signature="*(inversion,circle)"><code></asyxml>*/
+circle operator *(inversion i, circle c)
+{/*<asyxml></code><documentation>Provide inversion*circle.</documentation></operator></asyxml>*/
+ return inverse(i.k,i.C,c);
+}
+// *.......................INVERSIONS......................*
+// *=======================================================*
+
+/*<asyxml><function type="point[]" signature="intersectionpoints(line,circle)"><code></asyxml>*/
+point[] intersectionpoints(line l, circle c)
+{/*<asyxml></code><documentation>Note that the line 'l' may be a segment by casting.
+ intersectionpoints(circle,line) is also defined.</documentation></function></asyxml>*/
+ if(degenerate(c)) return new point[]{intersectionpoint(l,c.l)};
+ point[] op;
+ coordsys R=samecoordsys(l.A,c.C) ?
+ l.A.coordsys : defaultcoordsys;
+ coordsys Rp=defaultcoordsys;
+ circle cc=circle(changecoordsys(Rp,c.C),c.r);
+ point proj=projection(l)*c.C;
+ if(proj @ cc) { // The line is a tangente of the circle.
+ if(proj @ l) op.push(proj);// line may be a segement...
+ } else {
+ coordsys Rc=cartesiansystem(c.C,(1,0),(0,1));
+ line ll=changecoordsys(Rc,l);
+ pair[] P=intersectionpoints(ll.A.coordinates, ll.B.coordinates,
+ 1, 0, 1, 0, 0, -c.r^2);
+ for (int i=0; i<P.length; ++i) {
+ point inter=changecoordsys(R,point(Rc,P[i]));
+ if(inter @ l) op.push(inter);
+ }
+ }
+ return op;
+}
+
+point[] intersectionpoints(circle c, line l)
+{
+ return intersectionpoints(l,c);
+}
+
+/*<asyxml><function type="point[]" signature="intersectionpoints(line,ellipse)"><code></asyxml>*/
+point[] intersectionpoints(line l, ellipse el)
+{/*<asyxml></code><documentation>Note that the line 'l' may be a segment by casting.
+ intersectionpoints(ellipse,line) is also defined.</documentation></function></asyxml>*/
+ if(el.e == 0) return intersectionpoints(l,(circle)el);
+ if(degenerate(el)) return new point[]{intersectionpoint(l,el.l)};
+ point[] op;
+ coordsys R=samecoordsys(l.A,el.C) ? l.A.coordsys : defaultcoordsys;
+ coordsys Rp=defaultcoordsys;
+ line ll=changecoordsys(Rp,l);
+ ellipse ell=changecoordsys(Rp,el);
+ circle C=circle(ell.C,ell.a);
+ point[] Ip=intersectionpoints(ll,C);
+ if (Ip.length > 0 &&
+ (perpendicular(ll,line(ell.F1,Ip[0])) ||
+ perpendicular(ll,line(ell.F2,Ip[0])))) {
+ // http://www.mathcurve.com/courbes2d/ellipse/ellipse.shtml
+ // Définition tangentielle par antipodaire de cercle.
+ // 'l' is a tangent of 'el'
+ transform t=scale(el.a/el.b,el.F1,el.F2,el.C,rotate(90,el.C)*el.F1);
+ point inter=inverse(t)*intersectionpoints(C,t*ll)[0];
+ if(inter @ l) op.push(inter);
+ } else {
+ coordsys Rc=canonicalcartesiansystem(el);
+ line ll=changecoordsys(Rc,l);
+ pair[] P=intersectionpoints(ll.A.coordinates, ll.B.coordinates,
+ 1/el.a^2, 0, 1/el.b^2, 0, 0, -1);
+ for (int i=0; i<P.length; ++i) {
+ point inter=changecoordsys(R,point(Rc,P[i]));
+ if(inter @ l) op.push(inter);
+ }
+ }
+ return op;
+}
+
+point[] intersectionpoints(ellipse el, line l)
+{
+ return intersectionpoints(l,el);
+}
+
+/*<asyxml><function type="point[]" signature="intersectionpoints(line,parabola)"><code></asyxml>*/
+point[] intersectionpoints(line l, parabola p)
+{/*<asyxml></code><documentation>Note that the line 'l' may be a segment by casting.
+ intersectionpoints(parabola,line) is also defined.</documentation></function></asyxml>*/
+ point[] op;
+ coordsys R=coordsys(p);
+ bool tgt=false;
+ line ll=changecoordsys(R,l),
+ lv=parallel(p.V,p.D);
+ point M=intersectionpoint(lv,ll), tgtp;
+ if(finite(M)) {// Test if 'l' is tangent to 'p'
+ line l1=bisector(line(M,p.F));
+ line l2=rotate(90,M)*lv;
+ point P=intersectionpoint(l1,l2);
+ tgtp=rotate(180,P)*p.F;
+ tgt=(tgtp @ l);
+ }
+ if(tgt) {
+ if(tgtp @ l) op.push(tgtp);
+ } else {
+ real[] eq=changecoordsys(defaultcoordsys,equation(p)).a;
+ pair[] tp=intersectionpoints(locate(l.A),locate(l.B),eq);
+ point inter;
+ for (int i=0; i < tp.length; ++i) {
+ inter=point(R,tp[i]/R);
+ if(inter @ l) op.push(inter);
+ }
+ }
+ return op;
+}
+
+point[] intersectionpoints(parabola p, line l)
+{
+ return intersectionpoints(l,p);
+}
+
+/*<asyxml><function type="point[]" signature="intersectionpoints(line,hyperbola)"><code></asyxml>*/
+point[] intersectionpoints(line l, hyperbola h)
+{/*<asyxml></code><documentation>Note that the line 'l' may be a segment by casting.
+ intersectionpoints(hyperbola,line) is also defined.</documentation></function></asyxml>*/
+ point[] op;
+ coordsys R=coordsys(h);
+ point A=intersectionpoint(l,h.A1), B=intersectionpoint(l,h.A2);
+ point M=midpoint(segment(A,B));
+ bool tgt=M @ h;
+ if(tgt) {
+ if(M @ l) op.push(M);
+ } else {
+ real[] eq=changecoordsys(defaultcoordsys,equation(h)).a;
+ pair[] tp=intersectionpoints(locate(l.A),locate(l.B),eq);
+ point inter;
+ for (int i=0; i < tp.length; ++i) {
+ inter=point(R,tp[i]/R);
+ if(inter @ l) op.push(inter);
+ }
+ }
+ return op;
+}
+
+point[] intersectionpoints(hyperbola h, line l)
+{
+ return intersectionpoints(l,h);
+}
+
+/*<asyxml><function type="point[]" signature="intersectionpoints(line,conic)"><code></asyxml>*/
+point[] intersectionpoints(line l, conic co)
+{/*<asyxml></code><documentation>Note that the line 'l' may be a segment by casting.
+ intersectionpoints(conic,line) is also defined.</documentation></function></asyxml>*/
+ point[] op;
+ if(co.e < 1) op=intersectionpoints((ellipse)co,l);
+ else
+ if(co.e == 1) op=intersectionpoints((parabola)co,l);
+ else op=intersectionpoints((hyperbola)co,l);
+ return op;
+}
+
+point[] intersectionpoints(conic co, line l)
+{
+ return intersectionpoints(l,co);
+}
+
+/*<asyxml><function type="point[]" signature="intersectionpoints(conic,conic)"><code></asyxml>*/
+point[] intersectionpoints(conic co1, conic co2)
+{/*<asyxml></code><documentation>Return the intersection points of the two conics.</documentation></function></asyxml>*/
+ if(degenerate(co1)) return intersectionpoints(co1.l[0],co2);
+ if(degenerate(co2)) return intersectionpoints(co1,co2.l[0]);
+ return intersectionpoints(equation(co1), equation(co2));
+}
+
+/*<asyxml><function type="point[]" signature="intersectionpoints(triangle,conic,bool)"><code></asyxml>*/
+point[] intersectionpoints(triangle t, conic co, bool extended=false)
+{/*<asyxml></code><documentation>Return the intersection points.
+ If 'extended' is true, the sides are lines else the sides are segments.
+ intersectionpoints(conic,triangle,bool) is also defined.</documentation></function></asyxml>*/
+ if(degenerate(co)) return intersectionpoints(t,co.l[0],extended);
+ point[] OP;
+ void addpoint(point P[])
+ {
+ for (int i=0; i < P.length; ++i) {
+ if(defined(P[i])) {
+ bool exist=false;
+ for (int j=0; j < OP.length; ++j) {
+ if(P[i] == OP[j]) {exist=true; break;}
+ }
+ if(!exist) OP.push(P[i]);
+ }}}
+ if(extended) {
+ for (int i=0; i < 3; ++i) {
+ addpoint(intersectionpoints(t.line(i),co));
+ }
+ } else {
+ for (int i=0; i < 3; ++i) {
+ addpoint(intersectionpoints((segment)t.line(i),co));
+ }
+ }
+ return OP;
+}
+
+point[] intersectionpoints(conic co, triangle t, bool extended=false)
+{
+ return intersectionpoints(t,co,extended);
+}
+
+/*<asyxml><function type="point[]" signature="intersectionpoints(ellipse,ellipse)"><code></asyxml>*/
+point[] intersectionpoints(ellipse a, ellipse b)
+{/*<asyxml></code><documentation></documentation></function></asyxml>*/
+ // if(degenerate(a)) return intersectionpoints(a.l,b);
+ // if(degenerate(b)) return intersectionpoints(a,b.l);;
+ return intersectionpoints((conic)a,(conic)b);
+}
+/*<asyxml><function type="point[]" signature="intersectionpoints(ellipse,circle)"><code></asyxml>*/
+point[] intersectionpoints(ellipse a, circle b)
+{/*<asyxml></code><documentation></documentation></function></asyxml>*/
+ // if(degenerate(a)) return intersectionpoints(a.l,b);
+ // if(degenerate(b)) return intersectionpoints(a,b.l);;
+ return intersectionpoints((conic)a,(conic)b);
+}
+/*<asyxml><function type="point[]" signature="intersectionpoints(circle,ellipse)"><code></asyxml>*/
+point[] intersectionpoints(circle a, ellipse b)
+{/*<asyxml></code><documentation></documentation></function></asyxml>*/
+ return intersectionpoints(b,a);
+}
+/*<asyxml><function type="point[]" signature="intersectionpoints(ellipse,parabola)"><code></asyxml>*/
+point[] intersectionpoints(ellipse a, parabola b)
+{/*<asyxml></code><documentation></documentation></function></asyxml>*/
+ // if(degenerate(a)) return intersectionpoints(a.l,b);
+ return intersectionpoints((conic)a,(conic)b);
+}
+/*<asyxml><function type="point[]" signature="intersectionpoints(parabola,ellipse)"><code></asyxml>*/
+point[] intersectionpoints(parabola a, ellipse b)
+{/*<asyxml></code><documentation></documentation></function></asyxml>*/
+ return intersectionpoints(b,a);
+}
+/*<asyxml><function type="point[]" signature="intersectionpoints(ellipse,hyperbola)"><code></asyxml>*/
+point[] intersectionpoints(ellipse a, hyperbola b)
+{/*<asyxml></code><documentation></documentation></function></asyxml>*/
+ // if(degenerate(a)) return intersectionpoints(a.l,b);
+ return intersectionpoints((conic)a,(conic)b);
+}
+/*<asyxml><function type="point[]" signature="intersectionpoints(hyperbola,ellipse)"><code></asyxml>*/
+point[] intersectionpoints(hyperbola a, ellipse b)
+{/*<asyxml></code><documentation></documentation></function></asyxml>*/
+ return intersectionpoints(b,a);
+}
+
+/*<asyxml><function type="point[]" signature="intersectionpoints(circle,parabola)"><code></asyxml>*/
+point[] intersectionpoints(circle a, parabola b)
+{/*<asyxml></code><documentation></documentation></function></asyxml>*/
+ return intersectionpoints((conic)a,(conic)b);
+}
+/*<asyxml><function type="point[]" signature="intersectionpoints(parabola,circle)"><code></asyxml>*/
+point[] intersectionpoints(parabola a, circle b)
+{/*<asyxml></code><documentation></documentation></function></asyxml>*/
+ return intersectionpoints((conic)a,(conic)b);
+}
+/*<asyxml><function type="point[]" signature="intersectionpoints(circle,hyperbola)"><code></asyxml>*/
+point[] intersectionpoints(circle a, hyperbola b)
+{/*<asyxml></code><documentation></documentation></function></asyxml>*/
+ return intersectionpoints((conic)a,(conic)b);
+}
+/*<asyxml><function type="point[]" signature="intersectionpoints(hyperbola,circle)"><code></asyxml>*/
+point[] intersectionpoints(hyperbola a, circle b)
+{/*<asyxml></code><documentation></documentation></function></asyxml>*/
+ return intersectionpoints((conic)a,(conic)b);
+}
+
+/*<asyxml><function type="point[]" signature="intersectionpoints(parabola,parabola)"><code></asyxml>*/
+point[] intersectionpoints(parabola a, parabola b)
+{/*<asyxml></code><documentation></documentation></function></asyxml>*/
+ return intersectionpoints((conic)a,(conic)b);
+}
+/*<asyxml><function type="point[]" signature="intersectionpoints(parabola,hyperbola)"><code></asyxml>*/
+point[] intersectionpoints(parabola a, hyperbola b)
+{/*<asyxml></code><documentation></documentation></function></asyxml>*/
+ return intersectionpoints((conic)a,(conic)b);
+}
+/*<asyxml><function type="point[]" signature="intersectionpoints(hyperbola,parabola)"><code></asyxml>*/
+point[] intersectionpoints(hyperbola a, parabola b)
+{/*<asyxml></code><documentation></documentation></function></asyxml>*/
+ return intersectionpoints((conic)a,(conic)b);
+}
+/*<asyxml><function type="point[]" signature="intersectionpoints(hyperbola,hyperbola)"><code></asyxml>*/
+point[] intersectionpoints(hyperbola a, hyperbola b)
+{/*<asyxml></code><documentation></documentation></function></asyxml>*/
+ return intersectionpoints((conic)a,(conic)b);
+}
+
+/*<asyxml><function type="point[]" signature="intersectionpoints(circle,circle)"><code></asyxml>*/
+point[] intersectionpoints(circle c1, circle c2)
+{/*<asyxml></code><documentation></documentation></function></asyxml>*/
+ if(degenerate(c1))
+ return degenerate(c2) ?
+ new point[]{intersectionpoint(c1.l,c2.l)} : intersectionpoints(c1.l,c2);
+ if(degenerate(c2)) return intersectionpoints(c1,c2.l);
+ return (c1.C == c2.C) ?
+ new point[] :
+ intersectionpoints(radicalline(c1,c2),c1);
+}
+
+/*<asyxml><function type="line" signature="tangent(circle,abscissa)"><code></asyxml>*/
+line tangent(circle c, abscissa x)
+{/*<asyxml></code><documentation>Return the tangent of 'c' at 'point(c,x)'.</documentation></function></asyxml>*/
+ if(c.r == 0) abort("tangent: a circle with a radius equals zero has no tangent.");
+ point M=point(c,x);
+ return line(rotate(90,M)*c.C,M);
+}
+
+/*<asyxml><function type="line[]" signature="tangents(circle,point)"><code></asyxml>*/
+line[] tangents(circle c, point M)
+{/*<asyxml></code><documentation>Return the tangents of 'c' passing through 'M'.</documentation></function></asyxml>*/
+ line[] ol;
+ if(inside(c,M)) return ol;
+ if(M @ c) {
+ ol.push(tangent(c,relabscissa(c,M)));
+ } else {
+ circle cc=circle(c.C,M);
+ point[] inter=intersectionpoints(c,cc);
+ for (int i=0; i<inter.length; ++i)
+ ol.push(tangents(c,inter[i])[0]);
+ }
+ return ol;
+}
+
+/*<asyxml><function type="point" signature="point(circle,point)"><code></asyxml>*/
+point point(circle c, point M)
+{/*<asyxml></code><documentation>Return the intersection point of 'c'
+ with the half-line '[c.C M)'.</documentation></function></asyxml>*/
+ return intersectionpoints(c, line(c.C,false,M))[0];
+}
+
+/*<asyxml><function type="line" signature="tangent(circle,point)"><code></asyxml>*/
+line tangent(circle c, point M)
+{/*<asyxml></code><documentation>Return the tangent of 'c' at the
+ intersection point of the half-line'[c.C M)'.</documentation></function></asyxml>*/
+ return tangents(c,point(c,M))[0];
+}
+
+/*<asyxml><function type="point" signature="point(circle,explicit vector)"><code></asyxml>*/
+point point(circle c, explicit vector v)
+{/*<asyxml></code><documentation>Return the intersection point of 'c'
+ with the half-line '[c.C v)'.</documentation></function></asyxml>*/
+ return point(c,c.C+v);
+}
+
+/*<asyxml><function type="line" signature="tangent(circle,explicit vector)"><code></asyxml>*/
+line tangent(circle c, explicit vector v)
+{/*<asyxml></code><documentation>Return the tangent of 'c' at the
+ point M so that vec(c.C M) is collinear to 'v' with the same sense.</documentation></function></asyxml>*/
+ line ol=tangent(c,c.C+v);
+ return dot(ol.v,v) > 0 ? ol : reverse(ol);
+}
+
+/*<asyxml><function type="line" signature="tangent(ellipse,abscissa)"><code></asyxml>*/
+line tangent(ellipse el, abscissa x)
+{/*<asyxml></code><documentation>Return the tangent of 'el' at 'point(el,x)'.</documentation></function></asyxml>*/
+ point M=point(el,x);
+ line l1=line(el.F1,M);
+ line l2=line(el.F2,M);
+ line ol=(l1 == l2) ? perpendicular(M,l1) : bisector(l1,l2,90,false);
+ return ol;
+}
+
+/*<asyxml><function type="line[]" signature="tangents(ellipse,point)"><code></asyxml>*/
+line[] tangents(ellipse el, point M)
+{/*<asyxml></code><documentation>Return the tangents of 'el' passing through 'M'.</documentation></function></asyxml>*/
+ line[] ol;
+ if(inside(el,M)) return ol;
+ if(M @ el) {
+ ol.push(tangent(el,relabscissa(el,M)));
+ } else {
+ point Mp=samecoordsys(M,el.F2) ?
+ M : changecoordsys(el.F2.coordsys,M);
+ circle c=circle(Mp,abs(el.F1-Mp));
+ circle cc=circle(el.F2,2*el.a);
+ point[] inter=intersectionpoints(c,cc);
+ for (int i=0; i<inter.length; ++i) {
+ line tl=line(inter[i],el.F2,false);
+ point[] P=intersectionpoints(tl,el);
+ ol.push(line(Mp,P[0]));
+ }
+ }
+ return ol;
+}
+
+/*<asyxml><function type="line" signature="tangent(parabola,abscissa)"><code></asyxml>*/
+line tangent(parabola p, abscissa x)
+{/*<asyxml></code><documentation>Return the tangent of 'p' at 'point(p,x)' (use the Wells method).</documentation></function></asyxml>*/
+ line lt=rotate(90,p.V)*line(p.V,p.F);
+ point P=point(p,x);
+ if(P == p.V) return lt;
+ point M=midpoint(segment(P,p.F));
+ line l=rotate(90,M)*line(P,p.F);
+ return line(P,projection(lt)*M);
+}
+
+/*<asyxml><function type="line[]" signature="tangents(parabola,point)"><code></asyxml>*/
+line[] tangents(parabola p, point M)
+{/*<asyxml></code><documentation>Return the tangent of 'p' at 'M' (use the Wells method).</documentation></function></asyxml>*/
+ line[] ol;
+ if(inside(p,M)) return ol;
+ if(M @ p) {
+ ol.push(tangent(p,angabscissa(p,M)));
+ }
+ else {
+ point Mt=changecoordsys(coordsys(p),M);
+ circle c=circle(Mt,p.F);
+ line l=rotate(90,p.V)*line(p.V,p.F);
+ point[] R=intersectionpoints(l,c);
+ for (int i=0; i < R.length; ++i) {
+ ol.push(line(Mt,R[i]));
+ }
+ // An other method: http://www.du.edu/~jcalvert/math/parabola.htm
+ // point[] R=intersectionpoints(p.directrix,c);
+ // for (int i=0; i < R.length; ++i) {
+ // ol.push(bisector(segment(p.F,R[i])));
+ // }
+ }
+ return ol;
+}
+
+/*<asyxml><function type="line" signature="tangent(hyperbola,abscissa)"><code></asyxml>*/
+line tangent(hyperbola h, abscissa x)
+{/*<asyxml></code><documentation>Return the tangent of 'h' at 'point(p,x)'.</documentation></function></asyxml>*/
+ point M=point(h,x);
+ line ol=bisector(line(M,h.F1),line(M,h.F2));
+ if(sameside(h.F1,h.F2,ol) || ol == line(h.F1,h.F2)) ol=rotate(90,M)*ol;
+ return ol;
+}
+
+/*<asyxml><function type="line[]" signature="tangents(hyperbola,point)"><code></asyxml>*/
+line[] tangents(hyperbola h, point M)
+{/*<asyxml></code><documentation>Return the tangent of 'h' at 'M'.</documentation></function></asyxml>*/
+ line[] ol;
+ if(M @ h) {
+ ol.push(tangent(h,angabscissa(h,M,fromCenter)));
+ } else {
+ coordsys cano=canonicalcartesiansystem(h);
+ bqe bqe=changecoordsys(cano,equation(h));
+ real a=abs(1/(bqe.a[5]*bqe.a[0])), b=abs(1/(bqe.a[5]*bqe.a[2]));
+ point Mp=changecoordsys(cano,M);
+ real x0=Mp.x, y0=Mp.y;
+ if(abs(x0) > epsgeo) {
+ real c0=a*y0^2/(b*x0)^2-1/b,
+ c1=2*a*y0/(b*x0^2), c2=a/x0^2-1;
+ real[] sol=quadraticroots(c0,c1,c2);
+ for (real y:sol) {
+ point tmp=changecoordsys(coordsys(h), point(cano,(a*(1+y*y0/b)/x0,y)));
+ ol.push(line(M,tmp));
+ }
+ } else if(abs(y0) > epsgeo) {
+ real y=-b/y0, x=sqrt(a*(1+b/y0^2));
+ ol.push(line(M,changecoordsys(coordsys(h),point(cano,(x,y)))));
+ ol.push(line(M,changecoordsys(coordsys(h),point(cano,(-x,y)))));
+ }}
+ return ol;
+}
+
+/*<asyxml><function type="point[]" signature="intersectionpoints(conic,arc)"><code></asyxml>*/
+point[] intersectionpoints(conic co, arc a)
+{/*<asyxml></code><documentation>intersectionpoints(arc,circle) is also defined.</documentation></function></asyxml>*/
+ point[] op;
+ point[] tp=intersectionpoints(co,(conic)a.el);
+ for (int i=0; i<tp.length; ++i)
+ if(tp[i] @ a) op.push(tp[i]);
+ return op;
+}
+
+point[] intersectionpoints(arc a, conic co)
+{
+ return intersectionpoints(co,a);
+}
+
+/*<asyxml><function type="point[]" signature="intersectionpoints(arc,arc)"><code></asyxml>*/
+point[] intersectionpoints(arc a1, arc a2)
+{/*<asyxml></code><documentation></documentation></function></asyxml>*/
+ point[] op;
+ point[] tp=intersectionpoints(a1.el,a2.el);
+ for (int i=0; i<tp.length; ++i)
+ if(tp[i] @ a1 && tp[i] @ a2) op.push(tp[i]);
+ return op;
+}
+
+
+/*<asyxml><function type="point[]" signature="intersectionpoints(line,arc)"><code></asyxml>*/
+point[] intersectionpoints(line l, arc a)
+{/*<asyxml></code><documentation>intersectionpoints(arc,line) is also defined.</documentation></function></asyxml>*/
+ point[] op;
+ point[] tp=intersectionpoints(a.el,l);
+ for (int i=0; i<tp.length; ++i)
+ if(tp[i] @ a && tp[i] @ l) op.push(tp[i]);
+ return op;
+}
+
+point[] intersectionpoints(arc a, line l)
+{
+ return intersectionpoints(l,a);
+}
+
+/*<asyxml><function type="point" signature="arcsubtendedcenter(point,point,real)"><code></asyxml>*/
+point arcsubtendedcenter(point A, point B, real angle)
+{/*<asyxml></code><documentation>Return the center of the arc retuned
+ by the 'arcsubtended' routine.</documentation></function></asyxml>*/
+ point OM;
+ point[] P=standardizecoordsys(A,B);
+ angle=angle%(sgnd(angle)*180);
+ line bis=bisector(P[0],P[1]);
+ line AB=line(P[0],P[1]);
+ return intersectionpoint(bis,rotate(90-angle,A)*AB);
+}
+
+/*<asyxml><function type="arc" signature="arcsubtended(point,point,real)"><code></asyxml>*/
+arc arcsubtended(point A, point B, real angle)
+{/*<asyxml></code><documentation>Return the arc circle from which the segment AB is saw with
+ the angle 'angle'.
+ If the point 'M' is on this arc, the oriented angle (MA,MB) is
+ equal to 'angle'.</documentation></function></asyxml>*/
+ point[] P=standardizecoordsys(A,B);
+ line AB=line(P[0],P[1]);
+ angle=angle%(sgnd(angle)*180);
+ point C=arcsubtendedcenter(P[0],P[1],angle);
+ real BC=degrees(B-C)%360;
+ real AC=degrees(A-C)%360;
+ return arc(circle(C,abs(B-C)),BC,AC, angle > 0 ? CCW : CW);
+}
+
+/*<asyxml><function type="arc" signature="arccircle(point,point,point)"><code></asyxml>*/
+arc arccircle(point A, point M, point B)
+{/*<asyxml></code><documentation>Return the CCW arc circle 'AB' passing through 'M'.</documentation></function></asyxml>*/
+ circle tc=circle(A,M,B);
+ real a=degrees(A-tc.C);
+ real b=degrees(B-tc.C);
+ arc oa=arc(tc,a,b);
+ if(!(M @ oa)) oa.direction=!oa.direction;
+ return oa;
+}
+
+/*<asyxml><function type="arc" signature="arc(ellipse,abscissa,abscissa,bool)"><code></asyxml>*/
+arc arc(ellipse el, explicit abscissa x1, explicit abscissa x2, bool direction=CCW)
+{/*<asyxml></code><documentation>Return the arc from 'point(c,x1)' to 'point(c,x2)' in the direction 'direction'.</documentation></function></asyxml>*/
+ real a=degrees(point(el,x1)-el.C);
+ real b=degrees(point(el,x2)-el.C);
+ arc oa=arc(el,a,b,fromCenter,direction);
+ return oa;
+}
+
+/*<asyxml><function type="arc" signature="arc(ellipse,point,point,bool)"><code></asyxml>*/
+arc arc(ellipse el, point M, point N, bool direction=CCW)
+{/*<asyxml></code><documentation>Return the arc from 'M' to 'N' in the direction 'direction'.
+ The points 'M' and 'N' must belong to the ellipse 'el'.</documentation></function></asyxml>*/
+ return arc(el, relabscissa(el,M), relabscissa(el,N), direction);
+}
+
+/*<asyxml><function type="arc" signature="arccircle(point,point,real,bool)"><code></asyxml>*/
+arc arccircle(point A, point B, real angle, bool direction=CCW)
+{/*<asyxml></code><documentation>Return the arc circle centered on A
+ from B to rotate(angle,A)*B in the direction 'direction'.</documentation></function></asyxml>*/
+ point M=rotate(angle,A)*B;
+ return arc(circle(A,abs(A-B)),B,M,direction);
+}
+
+
+/*<asyxml><function type="arc" signature="arc(explicit arc,abscissa,abscissa)"><code></asyxml>*/
+arc arc(explicit arc a, abscissa x1, abscissa x2)
+{/*<asyxml></code><documentation>Return the arc from 'point(a,x1)' to 'point(a,x2)' traversed in the direction of the arc direction.</documentation></function></asyxml>*/
+ real a1=angabscissa(a.el, point(a,x1), a.polarconicroutine).x;
+ real a2=angabscissa(a.el, point(a,x2), a.polarconicroutine).x;
+ return arc(a.el, a1, a2, a.polarconicroutine, a.direction);
+}
+
+/*<asyxml><function type="arc" signature="arc(explicit arc,point,point)"><code></asyxml>*/
+arc arc(explicit arc a, point M, point N)
+{/*<asyxml></code><documentation>Return the arc from 'M' to 'N'.
+ The points 'M' and 'N' must belong to the arc 'a'.</documentation></function></asyxml>*/
+ return arc(a, relabscissa(a,M), relabscissa(a,N));
+}
+
+/*<asyxml><function type="arc" signature="inverse(real,point,segment)"><code></asyxml>*/
+arc inverse(real k, point A, segment s)
+{/*<asyxml></code><documentation>Return the inverse arc circle of 's'
+ with respect to point A and inversion radius 'k'.</documentation></function></asyxml>*/
+ point Ap=inverse(k,A,s.A), Bp=inverse(k,A,s.B),
+ M=inverse(k,A,midpoint(s));
+ return arccircle(Ap,M,Bp);
+}
+
+/*<asyxml><operator type="arc" signature="*(inversion,segment)"><code></asyxml>*/
+arc operator *(inversion i, segment s)
+{/*<asyxml></code><documentation>Provide
+ inversion*segment.</documentation></operator></asyxml>*/
+ return inverse(i.k,i.C,s);
+}
+
+/*<asyxml><operator type="path" signature="*(inversion,triangle)"><code></asyxml>*/
+path operator *(inversion i, triangle t)
+{/*<asyxml></code><documentation>Provide inversion*triangle.</documentation></operator></asyxml>*/
+ return (path)(i*segment(t.AB))--
+ (path)(i*segment(t.BC))--
+ (path)(i*segment(t.CA))--cycle;
+}
+
+/*<asyxml><function type="path" signature="compassmark(pair,pair,real,real)"><code></asyxml>*/
+path compassmark(pair O, pair A, real position, real angle=10)
+{/*<asyxml></code><documentation>Return an arc centered on O with the angle 'angle' so that the position
+ of 'A' on this arc makes an angle 'position*angle'.</documentation></function></asyxml>*/
+ real a=degrees(A-O);
+ real pa=(a-position*angle)%360,
+ pb=(a-(position-1)*angle)%360;
+ real t1=intersect(unitcircle,(0,0)--2*dir(pa))[0];
+ real t2=intersect(unitcircle,(0,0)--2*dir(pb))[0];
+ int n=length(unitcircle);
+ if(t1 >= t2) t1 -= n;
+ return shift(O)*scale(abs(O-A))*subpath(unitcircle,t1,t2);
+}
+
+/*<asyxml><function type="line" signature="tangent(explicit arc,abscissa)"><code></asyxml>*/
+line tangent(explicit arc a, abscissa x)
+{/*<asyxml></code><documentation>Return the tangent of 'a' at 'point(a,x)'.</documentation></function></asyxml>*/
+ abscissa ag=angabscissa(a,point(a,x));
+ return tangent(a.el,ag+a.angle1+(a.el.e == 0 ? a.angle0 : 0));
+}
+
+/*<asyxml><function type="line" signature="tangent(explicit arc,point)"><code></asyxml>*/
+line tangent(explicit arc a, point M)
+{/*<asyxml></code><documentation>Return the tangent of 'a' at 'M'.
+ The points 'M' must belong to the arc 'a'.</documentation></function></asyxml>*/
+ return tangent(a, angabscissa(a,M));
+}
+
+// *=======================================================*
+// *.......Routines for compatibility with original geometry module........*
+
+path square(pair z1, pair z2)
+{
+ pair v=z2-z1;
+ pair z3=z2+I*v;
+ pair z4=z3-v;
+ return z1--z2--z3--z4--cycle;
+}
+
+// Draw a perpendicular symbol at z aligned in the direction align
+// relative to the path z--z+dir.
+void perpendicular(picture pic=currentpicture, pair z, pair align,
+ pair dir=E, real size=0, pen p=currentpen,
+ margin margin=NoMargin, filltype filltype=NoFill)
+{
+ perpendicularmark(pic,(point) z,align,dir,size,p,margin,filltype);
+}
+
+
+// Draw a perpendicular symbol at z aligned in the direction align
+// relative to the path z--z+dir(g,0)
+void perpendicular(picture pic=currentpicture, pair z, pair align, path g,
+ real size=0, pen p=currentpen, margin margin=NoMargin,
+ filltype filltype=NoFill)
+{
+ perpendicularmark(pic,(point) z,align,dir(g,0),size,p,margin,filltype);
+}
+
+// Return an interior arc BAC of triangle ABC, given a radius r > 0.
+// If r < 0, return the corresponding exterior arc of radius |r|.
+path arc(explicit pair B, explicit pair A, explicit pair C,
+ real r=arrowfactor)
+{
+ return arc(A,r,degrees(B-A),degrees(C-A));
+}
+
+// *.......End of compatibility routines........*
+// *=======================================================*
+
+// *........................FOOTER.........................*
+// *=======================================================*
diff --git a/Build/source/utils/asymptote/base/graph.asy b/Build/source/utils/asymptote/base/graph.asy
new file mode 100644
index 00000000000..a778dd89261
--- /dev/null
+++ b/Build/source/utils/asymptote/base/graph.asy
@@ -0,0 +1,2203 @@
+private import math;
+
+import splinetype;
+import graph_settings;
+
+scaleT Linear;
+
+scaleT Log=scaleT(log10,pow10,logarithmic=true);
+scaleT Logarithmic=Log;
+
+string baselinetemplate="$10^4$";
+
+// A linear scale, with optional autoscaling of minimum and maximum values,
+// scaling factor s and intercept.
+scaleT Linear(bool automin=false, bool automax=automin, real s=1,
+ real intercept=0)
+{
+ real sinv=1/s;
+ scalefcn T,Tinv;
+ if(s == 1 && intercept == 0)
+ T=Tinv=identity;
+ else {
+ T=new real(real x) {return (x-intercept)*s;};
+ Tinv=new real(real x) {return x*sinv+intercept;};
+ }
+ return scaleT(T,Tinv,logarithmic=false,automin,automax);
+}
+
+// A logarithmic scale, with optional autoscaling of minimum and maximum
+// values.
+scaleT Log(bool automin=false, bool automax=automin)
+{
+ return scaleT(Log.T,Log.Tinv,logarithmic=true,automin,automax);
+}
+
+// A "broken" linear axis omitting the segment [a,b].
+scaleT Broken(real a, real b, bool automin=false, bool automax=automin)
+{
+ real skip=b-a;
+ real T(real x) {
+ if(x <= a) return x;
+ if(x <= b) return a;
+ return x-skip;
+ }
+ real Tinv(real x) {
+ if(x <= a) return x;
+ return x+skip;
+ }
+ return scaleT(T,Tinv,logarithmic=false,automin,automax);
+}
+
+// A "broken" logarithmic axis omitting the segment [a,b], where a and b are
+// automatically rounded to the nearest integral power of the base.
+scaleT BrokenLog(real a, real b, bool automin=false, bool automax=automin)
+{
+ real A=round(Log.T(a));
+ real B=round(Log.T(b));
+ a=Log.Tinv(A);
+ b=Log.Tinv(B);
+ real skip=B-A;
+ real T(real x) {
+ if(x <= a) return Log.T(x);
+ if(x <= b) return A;
+ return Log.T(x)-skip;
+ }
+ real Tinv(real x) {
+ real X=Log.Tinv(x);
+ if(X <= a) return X;
+ return Log.Tinv(x+skip);
+ }
+ return scaleT(T,Tinv,logarithmic=true,automin,automax);
+}
+
+Label Break=Label("$\approx$",UnFill(0.2mm));
+
+void scale(picture pic=currentpicture, scaleT x, scaleT y=x, scaleT z=y)
+{
+ pic.scale.x.scale=x;
+ pic.scale.y.scale=y;
+ pic.scale.z.scale=z;
+ pic.scale.x.automin=x.automin;
+ pic.scale.y.automin=y.automin;
+ pic.scale.z.automin=z.automin;
+ pic.scale.x.automax=x.automax;
+ pic.scale.y.automax=y.automax;
+ pic.scale.z.automax=z.automax;
+}
+
+void scale(picture pic=currentpicture, bool xautoscale=false,
+ bool yautoscale=xautoscale, bool zautoscale=yautoscale)
+{
+ scale(pic,Linear(xautoscale,xautoscale),Linear(yautoscale,yautoscale),
+ Linear(zautoscale,zautoscale));
+}
+
+struct scientific
+{
+ int sign;
+ real mantissa;
+ int exponent;
+ int ceil() {return sign*ceil(mantissa);}
+ real scale(real x, real exp) {
+ static real max=0.1*realMax;
+ static real limit=-log10(max);
+ return x*(exp > limit ? 10^-exp : max);
+ }
+ real ceil(real x, real exp) {return ceil(sign*scale(abs(x),exp));}
+ real floor(real x, real exp) {return floor(sign*scale(abs(x),exp));}
+}
+
+// Convert x to scientific notation
+scientific scientific(real x)
+{
+ scientific s;
+ s.sign=sgn(x);
+ x=abs(x);
+ if(x == 0) {s.mantissa=0; s.exponent=-intMax; return s;}
+ real logx=log10(x);
+ s.exponent=floor(logx);
+ s.mantissa=s.scale(x,s.exponent);
+ return s;
+}
+
+// Autoscale limits and tick divisor.
+struct bounds {
+ real min;
+ real max;
+
+ // Possible tick intervals:
+ int[] divisor;
+
+ void operator init(real min, real max, int[] divisor=new int[]) {
+ this.min=min;
+ this.max=max;
+ this.divisor=divisor;
+ }
+}
+
+// Compute tick divisors.
+int[] divisors(int a, int b)
+{
+ int[] dlist;
+ int n=b-a;
+ dlist[0]=1;
+ if(n == 1) {dlist[1]=10; dlist[2]=100; return dlist;}
+ if(n == 2) {dlist[1]=2; return dlist;}
+ int sqrtn=floor(sqrt(n));
+ int i=0;
+ for(int d=2; d <= sqrtn; ++d)
+ if(n % d == 0 && (a*b >= 0 || b % (n/d) == 0)) dlist[++i]=d;
+ for(int d=sqrtn; d >= 1; --d)
+ if(n % d == 0 && (a*b >= 0 || b % d == 0)) dlist[++i]=quotient(n,d);
+ return dlist;
+}
+
+real upscale(real b, real a)
+{
+ if(b <= 5) b=5;
+ else if (b > 10 && a >= 0 && b <= 12) b=12;
+ else if (b > 10 && (a >= 0 || 15 % -a == 0) && b <= 15) b=15;
+ else b=ceil(b/10)*10;
+ return b;
+}
+
+// Compute autoscale limits and tick divisor.
+bounds autoscale(real Min, real Max, scaleT scale=Linear)
+{
+ bounds m;
+ if(scale.logarithmic) {
+ m.min=floor(Min);
+ m.max=ceil(Max);
+ return m;
+ }
+ if(!(finite(Min) && finite(Max)))
+ abort("autoscale requires finite limits");
+ Min=scale.Tinv(Min);
+ Max=scale.Tinv(Max);
+ m.min=Min;
+ m.max=Max;
+ if(Min > Max) {real temp=Min; Min=Max; Max=temp;}
+ if(Min == Max) {
+ if(Min == 0) {m.max=1; return m;}
+ if(Min > 0) {Min=0; Max *= 2;}
+ else {Min *= 2; Max=0;}
+ }
+
+ int sign;
+ if(Min < 0 && Max <= 0) {real temp=-Min; Min=-Max; Max=temp; sign=-1;}
+ else sign=1;
+ scientific sa=scientific(Min);
+ scientific sb=scientific(Max);
+ int exp=max(sa.exponent,sb.exponent);
+ real a=sa.floor(Min,exp);
+ real b=sb.ceil(Max,exp);
+
+ void zoom() {
+ --exp;
+ a=sa.floor(Min,exp);
+ b=sb.ceil(Max,exp);
+ }
+
+ if(sb.mantissa <= 1.5)
+ zoom();
+
+ while((b-a)*10.0^exp > 10*(Max-Min))
+ zoom();
+
+ real bsave=b;
+ if(b-a > (a >= 0 ? 8 : 6)) {
+ b=upscale(b,a);
+ if(a >= 0) {
+ if(a <= 5) a=0; else a=floor(a/10)*10;
+ } else a=-upscale(-a,-1);
+ }
+
+ // Redo b in case the value of a has changed
+ if(bsave-a > (a >= 0 ? 8 : 6))
+ b=upscale(bsave,a);
+
+ if(sign == -1) {real temp=-a; a=-b; b=temp;}
+ real Scale=10.0^exp;
+ m.min=scale.T(a*Scale);
+ m.max=scale.T(b*Scale);
+ if(m.min > m.max) {real temp=m.min; m.min=m.max; m.max=temp;}
+ m.divisor=divisors(round(a),round(b));
+ return m;
+}
+
+typedef string ticklabel(real);
+
+ticklabel Format(string s=defaultformat)
+{
+ return new string(real x) {return format(s,x);};
+}
+
+ticklabel OmitFormat(string s=defaultformat ... real[] x)
+{
+ return new string(real v) {
+ int i=find(x == v);
+ return i < 0 ? format(s,v) : "";
+ };
+}
+
+string trailingzero="$%#$";
+string signedtrailingzero="$%+#$";
+
+ticklabel DefaultFormat=Format();
+ticklabel NoZeroFormat=OmitFormat(0);
+
+// Format tick values as integral powers of base; otherwise with DefaultFormat.
+ticklabel DefaultLogFormat(int base) {
+ return new string(real x) {
+ string exponent=format("%.4f",log(x)/log(base));
+ return find(exponent,".") == -1 ?
+ "$"+(string) base+"^{"+exponent+"}$" : format(x);
+ };
+}
+
+// Format all tick values as powers of base.
+ticklabel LogFormat(int base) {
+ return new string(real x) {
+ return format("$"+(string) base+"^{%g}$",log(x)/log(base));
+ };
+}
+
+ticklabel LogFormat=LogFormat(10);
+ticklabel DefaultLogFormat=DefaultLogFormat(10);
+
+// The default direction specifier.
+pair zero(real) {return 0;}
+
+struct ticklocate {
+ real a,b; // Tick values at point(g,0), point(g,length(g)).
+ autoscaleT S; // Autoscaling transformation.
+ pair dir(real t); // Absolute 2D tick direction.
+ triple dir3(real t); // Absolute 3D tick direction.
+ real time(real v); // Returns the time corresponding to the value v.
+ ticklocate copy() {
+ ticklocate T=new ticklocate;
+ T.a=a;
+ T.b=b;
+ T.S=S.copy();
+ T.dir=dir;
+ T.dir3=dir3;
+ T.time=time;
+ return T;
+ }
+}
+
+autoscaleT defaultS;
+
+typedef real valuetime(real);
+
+valuetime linear(scalefcn S=identity, real Min, real Max)
+{
+ real factor=Max == Min ? 0.0 : 1.0/(Max-Min);
+ return new real(real v) {return (S(v)-Min)*factor;};
+}
+
+ticklocate ticklocate(real a, real b, autoscaleT S=defaultS,
+ real tickmin=-infinity, real tickmax=infinity,
+ real time(real)=null, pair dir(real)=zero)
+{
+ if((valuetime) time == null) time=linear(S.T(),a,b);
+ ticklocate locate;
+ locate.a=a;
+ locate.b=b;
+ locate.S=S.copy();
+ if(finite(tickmin)) locate.S.tickMin=tickmin;
+ if(finite(tickmax)) locate.S.tickMax=tickmax;
+ locate.time=time;
+ locate.dir=dir;
+ return locate;
+}
+
+private struct locateT {
+ real t; // tick location time
+ pair Z; // tick location in frame coordinates
+ pair pathdir; // path direction in frame coordinates
+ pair dir; // tick direction in frame coordinates
+
+ void dir(transform T, path g, ticklocate locate, real t) {
+ pathdir=unit(shiftless(T)*dir(g,t));
+ pair Dir=locate.dir(t);
+ dir=Dir == 0 ? -I*pathdir : unit(Dir);
+ }
+ // Locate the desired position of a tick along a path.
+ void calc(transform T, path g, ticklocate locate, real val) {
+ t=locate.time(val);
+ Z=T*point(g,t);
+ dir(T,g,locate,t);
+ }
+}
+
+pair ticklabelshift(pair align, pen p=currentpen)
+{
+ return 0.25*unit(align)*labelmargin(p);
+}
+
+void drawtick(frame f, transform T, path g, path g2, ticklocate locate,
+ real val, real Size, int sign, pen p, bool extend)
+{
+ locateT locate1,locate2;
+ locate1.calc(T,g,locate,val);
+ if(extend && size(g2) > 0) {
+ locate2.calc(T,g2,locate,val);
+ draw(f,locate1.Z--locate2.Z,p);
+ } else
+ if(sign == 0)
+ draw(f,locate1.Z-Size*locate1.dir--locate1.Z+Size*locate1.dir,p);
+ else
+ draw(f,locate1.Z--locate1.Z+Size*sign*locate1.dir,p);
+}
+
+real zerotickfuzz=10*epsilon;
+
+// Label a tick on a frame.
+pair labeltick(frame d, transform T, path g, ticklocate locate, real val,
+ pair side, int sign, real Size, ticklabel ticklabel,
+ Label F, real norm=0)
+{
+ locateT locate1;
+ locate1.calc(T,g,locate,val);
+ pair align=side*locate1.dir;
+ pair perp=I*locate1.pathdir;
+
+ // Adjust tick label alignment
+ pair adjust=unit(align+0.75perp*sgn(dot(align,perp)));
+ // Project align onto adjusted direction.
+ align=adjust*dot(align,adjust);
+ pair shift=dot(align,-sign*locate1.dir) <= 0 ? align*Size :
+ ticklabelshift(align,F.p);
+
+ real label;
+ if(locate.S.scale.logarithmic)
+ label=locate.S.scale.Tinv(val);
+ else {
+ label=val;
+ if(abs(label) < zerotickfuzz*norm) label=0;
+ // Fix epsilon errors at +/-1e-4
+ // default format changes to scientific notation here
+ if(abs(abs(label)-1e-4) < epsilon) label=sgn(label)*1e-4;
+ }
+
+ string s=ticklabel(label);
+ if(s != "")
+ label(d,F.T*baseline(s,baselinetemplate),locate1.Z+shift,align,F.p,
+ F.filltype);
+ return locate1.pathdir;
+}
+
+// Add axis label L to frame f.
+void labelaxis(frame f, transform T, Label L, path g,
+ ticklocate locate=null, int sign=1, bool ticklabels=false)
+{
+ Label L0=L.copy();
+ real t=L0.relative(g);
+ pair z=point(g,t);
+ pair dir=dir(g,t);
+ pair perp=I*dir;
+ if(locate != null) {
+ locateT locate1;
+ locate1.dir(T,g,locate,t);
+ L0.align(L0.align,unit(-sgn(dot(sign*locate1.dir,perp))*perp));
+ }
+ pair align=L0.align.dir;
+ if(L0.align.relative) align *= -perp;
+ pair alignperp=dot(align,perp)*perp;
+ pair offset;
+ if(ticklabels) {
+ if(piecewisestraight(g)) {
+ real angle=degrees(dir,warn=false);
+ transform S=rotate(-angle,z);
+ frame F=S*f;
+ pair Align=rotate(-angle)*alignperp;
+ offset=unit(alignperp-sign*locate.dir(t))*
+ abs((Align.y >= 0 ? max(F).y : (Align.y < 0 ? min(F).y : 0))-z.y);
+ }
+ z += offset;
+ }
+
+ L0.align(align);
+ L0.position(z);
+ frame d;
+ add(d,L0);
+ pair width=0.5*size(d);
+ int n=length(g);
+ real t=L.relative();
+ pair s=realmult(width,dir(g,t));
+ if(t <= 0) {
+ if(L.align.default) s *= -axislabelfactor;
+ d=shift(s)*d;
+ } else if(t >= n) {
+ if(L.align.default) s *= -axislabelfactor;
+ d=shift(-s)*d;
+ } else if(offset == 0 && L.align.default) {
+ pair s=realmult(width,I*dir(g,t));
+ s=axislabelfactor*s;
+ d=shift(s)*d;
+ }
+ add(f,d);
+}
+
+// Check the tick coverage of a linear axis.
+bool axiscoverage(int N, transform T, path g, ticklocate locate, real Step,
+ pair side, int sign, real Size, Label F, ticklabel ticklabel,
+ real norm, real limit)
+{
+ real coverage=0;
+ bool loop=cyclic(g);
+ real a=locate.S.Tinv(locate.a);
+ real b=locate.S.Tinv(locate.b);
+ real tickmin=finite(locate.S.tickMin) ? locate.S.Tinv(locate.S.tickMin) : a;
+ if(Size > 0) {
+ int count=0;
+ if(loop) count=N+1;
+ else {
+ for(int i=0; i <= N; ++i) {
+ real val=tickmin+i*Step;
+ if(val >= a && val <= b)
+ ++count;
+ }
+ }
+ if(count > 0) limit /= count;
+ for(int i=0; i <= N; ++i) {
+ real val=tickmin+i*Step;
+ if(loop || (val >= a && val <= b)) {
+ frame d;
+ pair dir=labeltick(d,T,g,locate,val,side,sign,Size,ticklabel,F,norm);
+ if(abs(dot(size(d),dir)) > limit) return false;
+ }
+ }
+ }
+ return true;
+}
+
+// Check the tick coverage of a logarithmic axis.
+bool logaxiscoverage(int N, transform T, path g, ticklocate locate, pair side,
+ int sign, real Size, Label F, ticklabel ticklabel,
+ real limit, int first, int last)
+{
+ bool loop=cyclic(g);
+ real coverage=0;
+ real a=locate.a;
+ real b=locate.b;
+ int count=0;
+ for(int i=first-1; i <= last+1; i += N) {
+ if(loop || i >= a && i <= b)
+ ++count;
+ }
+ if(count > 0) limit /= count;
+ for(int i=first-1; i <= last+1; i += N) {
+ if(loop || i >= a && i <= b) {
+ frame d;
+ pair dir=labeltick(d,T,g,locate,i,side,sign,Size,ticklabel,F);
+ if(abs(dot(size(d),dir)) > limit) return false;
+ }
+ }
+ return true;
+}
+
+struct tickvalues {
+ real[] major;
+ real[] minor;
+ int N; // For logarithmic axes: number of decades between tick labels.
+}
+
+// Determine a format that distinguishes adjacent pairs of ticks, optionally
+// adding trailing zeros.
+string autoformat(string format="", real norm ... real[] a)
+{
+ bool trailingzero=(format == trailingzero);
+ bool signedtrailingzero=(format == signedtrailingzero);
+ if(!trailingzero && !signedtrailingzero && format != "") return format;
+
+ real[] A=sort(a);
+ real[] a=abs(A);
+
+ bool signchange=(A.length > 1 && A[0] < 0 && A[A.length-1] >= 0);
+
+ for(int i=0; i < A.length-1; ++i)
+ if(a[i] < zerotickfuzz*norm) A[i]=a[i]=0;
+
+ int n=0;
+
+ bool Fixed=find(a >= 1e4-epsilon | (a > 0 & a <= 1e-4-epsilon)) < 0;
+ string Format=defaultformat(4,fixed=Fixed);
+
+ if(Fixed && n < 4) {
+ for(int i=0; i < A.length-1; ++i) {
+ real a=A[i];
+ while(format(defaultformat(n,fixed=Fixed),a) != format(Format,a))
+ ++n;
+ }
+ }
+
+ string trailing=trailingzero ? (signchange ? "# " : "#") :
+ signedtrailingzero ? "#+" : "";
+
+ string format=defaultformat(n,trailing,Fixed);
+
+ for(int i=0; i < A.length-1; ++i) {
+ real a=A[i];
+ real b=A[i+1];
+ // Check if an extra digit of precision should be added.
+ string fixedformat="%#."+string(n+1)+"f";
+ string A=format(fixedformat,a);
+ string B=format(fixedformat,b);
+ if(substr(A,length(A)-1,1) != "0" || substr(B,length(B)-1,1) != "0") {
+ a *= 0.1;
+ b *= 0.1;
+ }
+ if(a != b) {
+ while(format(format,a) == format(format,b))
+ format=defaultformat(++n,trailing,Fixed);
+ }
+ }
+
+ if(n == 0) return defaultformat;
+ return format;
+}
+
+// Automatic tick generation routine.
+tickvalues generateticks(int sign, Label F="", ticklabel ticklabel=null,
+ int N, int n=0, real Step=0, real step=0,
+ real Size=0, real size=0,
+ transform T, pair side, path g, real limit,
+ pen p, ticklocate locate, int[] divisor,
+ bool opposite)
+{
+ tickvalues tickvalues;
+ sign=opposite ? -sign : sign;
+ if(Size == 0) Size=Ticksize;
+ if(size == 0) size=ticksize;
+ F=F.copy();
+ F.p(p);
+
+ if(F.align.dir != 0) side=F.align.dir;
+ else if(side == 0) side=((sign == 1) ? left : right);
+
+ bool ticklabels=false;
+ path G=T*g;
+
+ if(!locate.S.scale.logarithmic) {
+ real a=locate.S.Tinv(locate.a);
+ real b=locate.S.Tinv(locate.b);
+ real norm=max(abs(a),abs(b));
+ string format=autoformat(F.s,norm,a,b);
+ if(F.s == "%") F.s="";
+ if(ticklabel == null) ticklabel=Format(format);
+
+ if(a > b) {real temp=a; a=b; b=temp;}
+
+ if(b-a < 100.0*epsilon*norm) b=a;
+
+ real tickmin=finite(locate.S.tickMin) && (Step == 0 || locate.S.automin) ?
+ locate.S.Tinv(locate.S.tickMin) : a;
+ real tickmax=finite(locate.S.tickMax) && (Step == 0 || locate.S.automax) ?
+ locate.S.Tinv(locate.S.tickMax) : b;
+ if(tickmin > tickmax) {real temp=tickmin; tickmin=tickmax; tickmax=temp;}
+
+ real inStep=Step;
+
+ bool calcStep=true;
+ real len=tickmax-tickmin;
+ if(Step == 0 && N == 0) {
+ N=1;
+ if(divisor.length > 0) {
+ bool autoscale=locate.S.automin && locate.S.automax;
+ real h=0.5*(b-a);
+ for(int d=divisor.length-1; d >= 0; --d) {
+ int N0=divisor[d];
+ Step=len/N0;
+ int N1=N0;
+ int m=2;
+ while(Step > h) {
+ N0=m*N1;
+ Step=len/N0;
+ m *= 2;
+ }
+ if(axiscoverage(N0,T,g,locate,Step,side,sign,Size,F,ticklabel,norm,
+ limit)) {
+ N=N0;
+ if(N0 == 1 && !autoscale && d < divisor.length-1) {
+ // Try using 2 ticks (otherwise 1);
+ int div=divisor[d+1];
+ Step=quotient(div,2)*len/div;
+ calcStep=false;
+ if(axiscoverage(2,T,g,locate,Step,side,sign,Size,F,ticklabel,
+ norm,limit)) N=2;
+ else Step=len;
+ }
+ // Found a good divisor; now compute subtick divisor
+ if(n == 0) {
+ if(step != 0) n=ceil(Step/step);
+ else {
+ n=quotient(divisor[divisor.length-1],N);
+ if(N == 1) n=(a*b >= 0) ? 2 : 1;
+ if(n == 1) n=2;
+ }
+ }
+ break;
+ }
+ }
+ }
+ }
+
+ if(inStep != 0 && !locate.S.automin) {
+ tickmin=floor(tickmin/Step)*Step;
+ len=tickmax-tickmin;
+ }
+
+ if(calcStep) {
+ if(N == 0) N=(int) (len/Step);
+ else Step=len/N;
+ }
+
+ if(n == 0) {
+ if(step != 0) n=ceil(Step/step);
+ } else step=Step/n;
+
+ b += epsilon*norm;
+
+ if(Size > 0) {
+ for(int i=0; i <= N; ++i) {
+ real val=tickmin+i*Step;
+ if(val >= a && val <= b)
+ tickvalues.major.push(val);
+ if(size > 0 && step > 0) {
+ real iStep=i*Step;
+ real jstop=(len-iStep)/step;
+ for(int j=1; j < n && j <= jstop; ++j) {
+ real val=tickmin+iStep+j*step;
+ if(val >= a && val <= b)
+ tickvalues.minor.push(val);
+ }
+ }
+ }
+ }
+
+ } else { // Logarithmic
+ string format=F.s;
+ if(F.s == "%") F.s="";
+
+ int base=round(locate.S.scale.Tinv(1));
+
+ if(ticklabel == null)
+ ticklabel=format == "%" ? Format("") : DefaultLogFormat(base);
+ real a=locate.S.postscale.Tinv(locate.a);
+ real b=locate.S.postscale.Tinv(locate.b);
+ if(a > b) {real temp=a; a=b; b=temp;}
+
+ int first=floor(a-epsilon);
+ int last=ceil(b+epsilon);
+
+ if(N == 0) {
+ N=1;
+ while(N <= last-first) {
+ if(logaxiscoverage(N,T,g,locate,side,sign,Size,F,ticklabel,limit,
+ first,last)) break;
+ ++N;
+ }
+ }
+
+ if(N <= 2 && n == 0) n=base;
+ tickvalues.N=N;
+
+ if(N > 0) {
+ for(int i=first-1; i <= last+1; ++i) {
+ if(i >= a && i <= b)
+ tickvalues.major.push(locate.S.scale.Tinv(i));
+ if(n > 0) {
+ for(int j=2; j < n; ++j) {
+ real val=(i+1+locate.S.scale.T(j/n));
+ if(val >= a && val <= b)
+ tickvalues.minor.push(locate.S.scale.Tinv(val));
+ }
+ }
+ }
+ }
+ }
+ return tickvalues;
+}
+
+// Signature of routines that draw labelled paths with ticks and tick labels.
+typedef void ticks(frame, transform, Label, pair, path, path, pen,
+ arrowbar, margin, ticklocate, int[], bool opposite=false);
+
+// Tick construction routine for a user-specified array of tick values.
+ticks Ticks(int sign, Label F="", ticklabel ticklabel=null,
+ bool beginlabel=true, bool endlabel=true,
+ real[] Ticks=new real[], real[] ticks=new real[], int N=1,
+ bool begin=true, bool end=true,
+ real Size=0, real size=0, bool extend=false,
+ pen pTick=nullpen, pen ptick=nullpen)
+{
+ return new void(frame f, transform t, Label L, pair side, path g, path g2,
+ pen p, arrowbar arrow, margin margin, ticklocate locate,
+ int[] divisor, bool opposite) {
+ // Use local copy of context variables:
+ int sign=opposite ? -sign : sign;
+ pen pTick=pTick;
+ pen ptick=ptick;
+ ticklabel ticklabel=ticklabel;
+
+ real Size=Size;
+ real size=size;
+ if(Size == 0) Size=Ticksize;
+ if(size == 0) size=ticksize;
+
+ Label L=L.copy();
+ Label F=F.copy();
+ L.p(p);
+ F.p(p);
+ if(pTick == nullpen) pTick=p;
+ if(ptick == nullpen) ptick=pTick;
+
+ if(F.align.dir != 0) side=F.align.dir;
+ else if(side == 0) side=F.T*((sign == 1) ? left : right);
+
+ bool ticklabels=false;
+ path G=t*g;
+ path G2=t*g2;
+
+ scalefcn T;
+
+ real a,b;
+ if(locate.S.scale.logarithmic) {
+ a=locate.S.postscale.Tinv(locate.a);
+ b=locate.S.postscale.Tinv(locate.b);
+ T=locate.S.scale.T;
+ } else {
+ a=locate.S.Tinv(locate.a);
+ b=locate.S.Tinv(locate.b);
+ T=identity;
+ }
+
+ if(a > b) {real temp=a; a=b; b=temp;}
+
+ real norm=max(abs(a),abs(b));
+
+ string format=autoformat(F.s,norm...Ticks);
+ if(F.s == "%") F.s="";
+ if(ticklabel == null) {
+ if(locate.S.scale.logarithmic) {
+ int base=round(locate.S.scale.Tinv(1));
+ ticklabel=format == "%" ? Format("") : DefaultLogFormat(base);
+ } else ticklabel=Format(format);
+ }
+
+ begingroup(f);
+ if(opposite) draw(f,G,p);
+ else draw(f,margin(G,p).g,p,arrow);
+ for(int i=(begin ? 0 : 1); i < (end ? Ticks.length : Ticks.length-1); ++i) {
+ real val=T(Ticks[i]);
+ if(val >= a && val <= b)
+ drawtick(f,t,g,g2,locate,val,Size,sign,pTick,extend);
+ }
+ for(int i=0; i < ticks.length; ++i) {
+ real val=T(ticks[i]);
+ if(val >= a && val <= b)
+ drawtick(f,t,g,g2,locate,val,size,sign,ptick,extend);
+ }
+ endgroup(f);
+
+ if(N == 0) N=1;
+ if(Size > 0 && !opposite) {
+ for(int i=(beginlabel ? 0 : 1);
+ i < (endlabel ? Ticks.length : Ticks.length-1); i += N) {
+ real val=T(Ticks[i]);
+ if(val >= a && val <= b) {
+ ticklabels=true;
+ labeltick(f,t,g,locate,val,side,sign,Size,ticklabel,F,norm);
+ }
+ }
+ }
+ if(L.s != "" && !opposite)
+ labelaxis(f,t,L,G,locate,sign,ticklabels);
+ };
+}
+
+// Optional routine to allow modification of auto-generated tick values.
+typedef tickvalues tickmodifier(tickvalues);
+tickvalues None(tickvalues v) {return v;}
+
+tickmodifier OmitTick(... real[] x) {
+ return new tickvalues(tickvalues v) {
+ if(v.major.length == 0) return v;
+ real norm=max(abs(v.major));
+ for(int i=0; i < x.length; ++i) {
+ int j=find(abs(v.major-x[i]) < zerotickfuzz*norm);
+ if(j >= 0) v.major.delete(j);
+ }
+ return v;
+ };
+}
+
+tickmodifier NoZero=OmitTick(0);
+
+// Tickmodifier that removes all major ticks in the interval [a,b].
+tickmodifier Break(real a, real b) {
+ return new tickvalues(tickvalues v) {
+ real[] V=v.major;
+ real[] major;
+ for(int i=0; i < V.length; ++i)
+ if(V[i] < a-epsilon || V[i] > b+epsilon) major.push(V[i]);
+ v.major=major;
+ return v;
+ };
+}
+
+// Automatic tick construction routine.
+ticks Ticks(int sign, Label F="", ticklabel ticklabel=null,
+ bool beginlabel=true, bool endlabel=true,
+ int N, int n=0, real Step=0, real step=0,
+ bool begin=true, bool end=true, tickmodifier modify=None,
+ real Size=0, real size=0, bool extend=false,
+ pen pTick=nullpen, pen ptick=nullpen)
+{
+ return new void(frame f, transform T, Label L, pair side, path g, path g2,
+ pen p, arrowbar arrow, margin margin, ticklocate locate,
+ int[] divisor, bool opposite) {
+ real limit=Step == 0 ? axiscoverage*arclength(T*g) : 0;
+ tickvalues values=modify(generateticks(sign,F,ticklabel,N,n,Step,step,
+ Size,size,T,side,g,
+ limit,p,locate,divisor,opposite));
+
+ Ticks(sign,F,ticklabel,beginlabel,endlabel,values.major,values.minor,
+ values.N,begin,end,Size,size,extend,pTick,ptick)
+ (f,T,L,side,g,g2,p,arrow,margin,locate,divisor,opposite);
+ };
+}
+
+ticks NoTicks()
+{
+ return new void(frame f, transform T, Label L, pair, path g, path, pen p,
+ arrowbar arrow, margin margin, ticklocate,
+ int[], bool opposite) {
+ path G=T*g;
+ if(opposite) draw(f,G,p);
+ else {
+ draw(f,margin(G,p).g,p,arrow);
+ if(L.s != "") {
+ Label L=L.copy();
+ L.p(p);
+ labelaxis(f,T,L,G);
+ }
+ }
+ };
+}
+
+ticks LeftTicks(Label format="", ticklabel ticklabel=null,
+ bool beginlabel=true, bool endlabel=true,
+ int N=0, int n=0, real Step=0, real step=0,
+ bool begin=true, bool end=true, tickmodifier modify=None,
+ real Size=0, real size=0, bool extend=false,
+ pen pTick=nullpen, pen ptick=nullpen)
+{
+ return Ticks(-1,format,ticklabel,beginlabel,endlabel,N,n,Step,step,
+ begin,end,modify,Size,size,extend,pTick,ptick);
+}
+
+ticks RightTicks(Label format="", ticklabel ticklabel=null,
+ bool beginlabel=true, bool endlabel=true,
+ int N=0, int n=0, real Step=0, real step=0,
+ bool begin=true, bool end=true, tickmodifier modify=None,
+ real Size=0, real size=0, bool extend=false,
+ pen pTick=nullpen, pen ptick=nullpen)
+{
+ return Ticks(1,format,ticklabel,beginlabel,endlabel,N,n,Step,step,
+ begin,end,modify,Size,size,extend,pTick,ptick);
+}
+
+ticks Ticks(Label format="", ticklabel ticklabel=null,
+ bool beginlabel=true, bool endlabel=true,
+ int N=0, int n=0, real Step=0, real step=0,
+ bool begin=true, bool end=true, tickmodifier modify=None,
+ real Size=0, real size=0, bool extend=false,
+ pen pTick=nullpen, pen ptick=nullpen)
+{
+ return Ticks(0,format,ticklabel,beginlabel,endlabel,N,n,Step,step,
+ begin,end,modify,Size,size,extend,pTick,ptick);
+}
+
+ticks LeftTicks(Label format="", ticklabel ticklabel=null,
+ bool beginlabel=true, bool endlabel=true,
+ real[] Ticks, real[] ticks=new real[],
+ real Size=0, real size=0, bool extend=false,
+ pen pTick=nullpen, pen ptick=nullpen)
+{
+ return Ticks(-1,format,ticklabel,beginlabel,endlabel,
+ Ticks,ticks,Size,size,extend,pTick,ptick);
+}
+
+ticks RightTicks(Label format="", ticklabel ticklabel=null,
+ bool beginlabel=true, bool endlabel=true,
+ real[] Ticks, real[] ticks=new real[],
+ real Size=0, real size=0, bool extend=false,
+ pen pTick=nullpen, pen ptick=nullpen)
+{
+ return Ticks(1,format,ticklabel,beginlabel,endlabel,
+ Ticks,ticks,Size,size,extend,pTick,ptick);
+}
+
+ticks Ticks(Label format="", ticklabel ticklabel=null,
+ bool beginlabel=true, bool endlabel=true,
+ real[] Ticks, real[] ticks=new real[],
+ real Size=0, real size=0, bool extend=false,
+ pen pTick=nullpen, pen ptick=nullpen)
+{
+ return Ticks(0,format,ticklabel,beginlabel,endlabel,
+ Ticks,ticks,Size,size,extend,pTick,ptick);
+}
+
+ticks NoTicks=NoTicks(),
+LeftTicks=LeftTicks(),
+RightTicks=RightTicks(),
+Ticks=Ticks();
+
+pair tickMin(picture pic)
+{
+ return minbound(pic.userMin(),(pic.scale.x.tickMin,pic.scale.y.tickMin));
+}
+
+pair tickMax(picture pic)
+{
+ return maxbound(pic.userMax(),(pic.scale.x.tickMax,pic.scale.y.tickMax));
+}
+
+int Min=-1;
+int Value=0;
+int Max=1;
+int Both=2;
+
+// Structure used to communicate axis and autoscale settings to tick routines.
+struct axisT {
+ int type; // -1 = min, 0 = given value, 1 = max, 2 = min/max
+ int type2; // for 3D axis
+ real value;
+ real value2;
+ pair side; // 2D tick label direction relative to path (left or right)
+ real position; // label position along axis
+ align align; // default axis label alignment and 3D tick label direction
+ int[] xdivisor;
+ int[] ydivisor;
+ int[] zdivisor;
+ bool extend; // extend axis to graph boundary?
+};
+
+axisT axis;
+typedef void axis(picture, axisT);
+
+axis Bottom(bool extend=false)
+{
+ return new void(picture pic, axisT axis) {
+ axis.type=Min;
+ axis.position=0.5;
+ axis.side=right;
+ axis.align=S;
+ axis.extend=extend;
+ };
+}
+
+axis Top(bool extend=false)
+{
+ return new void(picture pic, axisT axis) {
+ axis.type=Max;
+ axis.position=0.5;
+ axis.side=left;
+ axis.align=N;
+ axis.extend=extend;
+ };
+}
+
+axis BottomTop(bool extend=false)
+{
+ return new void(picture pic, axisT axis) {
+ axis.type=Both;
+ axis.position=0.5;
+ axis.side=right;
+ axis.align=S;
+ axis.extend=extend;
+ };
+}
+
+axis Left(bool extend=false)
+{
+ return new void(picture pic, axisT axis) {
+ axis.type=Min;
+ axis.position=0.5;
+ axis.side=left;
+ axis.align=W;
+ axis.extend=extend;
+ };
+}
+
+axis Right(bool extend=false)
+{
+ return new void(picture pic, axisT axis) {
+ axis.type=Max;
+ axis.position=0.5;
+ axis.side=right;
+ axis.align=E;
+ axis.extend=extend;
+ };
+}
+
+axis LeftRight(bool extend=false)
+{
+ return new void(picture pic, axisT axis) {
+ axis.type=Both;
+ axis.position=0.5;
+ axis.side=left;
+ axis.align=W;
+ axis.extend=extend;
+ };
+}
+
+axis XEquals(real x, bool extend=true)
+{
+ return new void(picture pic, axisT axis) {
+ axis.type=Value;
+ axis.value=pic.scale.x.T(x);
+ axis.position=1;
+ axis.side=left;
+ axis.align=W;
+ axis.extend=extend;
+ };
+}
+
+axis YEquals(real y, bool extend=true)
+{
+ return new void(picture pic, axisT axis) {
+ axis.type=Value;
+ axis.value=pic.scale.y.T(y);
+ axis.position=1;
+ axis.side=right;
+ axis.align=S;
+ axis.extend=extend;
+ };
+}
+
+axis XZero(bool extend=true)
+{
+ return new void(picture pic, axisT axis) {
+ axis.type=Value;
+ axis.value=pic.scale.x.T(pic.scale.x.scale.logarithmic ? 1 : 0);
+ axis.position=1;
+ axis.side=left;
+ axis.align=W;
+ axis.extend=extend;
+ };
+}
+
+axis YZero(bool extend=true)
+{
+ return new void(picture pic, axisT axis) {
+ axis.type=Value;
+ axis.value=pic.scale.y.T(pic.scale.y.scale.logarithmic ? 1 : 0);
+ axis.position=1;
+ axis.side=right;
+ axis.align=S;
+ axis.extend=extend;
+ };
+}
+
+axis Bottom=Bottom(),
+Top=Top(),
+BottomTop=BottomTop(),
+Left=Left(),
+Right=Right(),
+LeftRight=LeftRight(),
+XZero=XZero(),
+YZero=YZero();
+
+// Draw a general axis.
+void axis(picture pic=currentpicture, Label L="", path g, path g2=nullpath,
+ pen p=currentpen, ticks ticks, ticklocate locate,
+ arrowbar arrow=None, margin margin=NoMargin,
+ int[] divisor=new int[], bool above=false, bool opposite=false)
+{
+ Label L=L.copy();
+ real t=reltime(g,0.5);
+ if(L.defaultposition) L.position(t);
+ divisor=copy(divisor);
+ locate=locate.copy();
+ pic.add(new void (frame f, transform t, transform T, pair lb, pair rt) {
+ frame d;
+ ticks(d,t,L,0,g,g2,p,arrow,margin,locate,divisor,opposite);
+ (above ? add : prepend)(f,t*T*inverse(t)*d);
+ });
+
+ pic.addPath(g,p);
+
+ if(L.s != "") {
+ frame f;
+ Label L0=L.copy();
+ L0.position(0);
+ add(f,L0);
+ pair pos=point(g,L.relative()*length(g));
+ pic.addBox(pos,pos,min(f),max(f));
+ }
+}
+
+real xtrans(transform t, real x)
+{
+ return (t*(x,0)).x;
+}
+
+real ytrans(transform t, real y)
+{
+ return (t*(0,y)).y;
+}
+
+// An internal routine to draw an x axis at a particular y value.
+void xaxisAt(picture pic=currentpicture, Label L="", axis axis,
+ real xmin=-infinity, real xmax=infinity, pen p=currentpen,
+ ticks ticks=NoTicks, arrowbar arrow=None, margin margin=NoMargin,
+ bool above=true, bool opposite=false)
+{
+ real y=axis.value;
+ real y2;
+ Label L=L.copy();
+ int[] divisor=copy(axis.xdivisor);
+ pair side=axis.side;
+ int type=axis.type;
+
+ pic.add(new void (frame f, transform t, transform T, pair lb, pair rt) {
+ transform tinv=inverse(t);
+ pair a=xmin == -infinity ? tinv*(lb.x-min(p).x,ytrans(t,y)) : (xmin,y);
+ pair b=xmax == infinity ? tinv*(rt.x-max(p).x,ytrans(t,y)) : (xmax,y);
+ pair a2=xmin == -infinity ? tinv*(lb.x-min(p).x,ytrans(t,y2)) : (xmin,y2);
+ pair b2=xmax == infinity ? tinv*(rt.x-max(p).x,ytrans(t,y2)) : (xmax,y2);
+
+ if(xmin == -infinity || xmax == infinity) {
+ bounds mx=autoscale(a.x,b.x,pic.scale.x.scale);
+ pic.scale.x.tickMin=mx.min;
+ pic.scale.x.tickMax=mx.max;
+ divisor=mx.divisor;
+ }
+
+ real fuzz=epsilon*max(abs(a.x),abs(b.x));
+ a -= (fuzz,0);
+ b += (fuzz,0);
+
+ frame d;
+ ticks(d,t,L,side,a--b,finite(y2) ? a2--b2 : nullpath,p,arrow,margin,
+ ticklocate(a.x,b.x,pic.scale.x),divisor,opposite);
+ (above ? add : prepend)(f,t*T*tinv*d);
+ });
+
+ void bounds() {
+ if(type == Min)
+ y=pic.scale.y.automin() ? tickMin(pic).y : pic.userMin.y;
+ else if(type == Max)
+ y=pic.scale.y.automax() ? tickMax(pic).y : pic.userMax.y;
+ else if(type == Both) {
+ y2=pic.scale.y.automax() ? tickMax(pic).y : pic.userMax.y;
+ y=opposite ? y2 :
+ (pic.scale.y.automin() ? tickMin(pic).y : pic.userMin.y);
+ }
+
+ real Xmin=finite(xmin) ? xmin : pic.userMin.x;
+ real Xmax=finite(xmax) ? xmax : pic.userMax.x;
+
+ pair a=(Xmin,y);
+ pair b=(Xmax,y);
+ pair a2=(Xmin,y2);
+ pair b2=(Xmax,y2);
+
+ if(finite(a)) {
+ pic.addPoint(a,min(p));
+ pic.addPoint(a,max(p));
+ }
+
+ if(finite(b)) {
+ pic.addPoint(b,min(p));
+ pic.addPoint(b,max(p));
+ }
+
+ if(finite(a) && finite(b)) {
+ frame d;
+ ticks(d,pic.scaling(warn=false),L,side,
+ (a.x,0)--(b.x,0),(a2.x,0)--(b2.x,0),p,arrow,margin,
+ ticklocate(a.x,b.x,pic.scale.x),divisor,opposite);
+ frame f;
+ if(L.s != "") {
+ Label L0=L.copy();
+ L0.position(0);
+ add(f,L0);
+ }
+ pair pos=a+L.relative()*(b-a);
+ pic.addBox(pos,pos,(min(f).x,min(d).y),(max(f).x,max(d).y));
+ }
+ }
+
+ // Process any queued y axis bound calculation requests.
+ for(int i=0; i < pic.scale.y.bound.length; ++i)
+ pic.scale.y.bound[i]();
+
+ pic.scale.y.bound.delete();
+
+ bounds();
+
+ // Request another x bounds calculation before final picture scaling.
+ pic.scale.x.bound.push(bounds);
+}
+
+// An internal routine to draw a y axis at a particular x value.
+void yaxisAt(picture pic=currentpicture, Label L="", axis axis,
+ real ymin=-infinity, real ymax=infinity, pen p=currentpen,
+ ticks ticks=NoTicks, arrowbar arrow=None, margin margin=NoMargin,
+ bool above=true, bool opposite=false)
+{
+ real x=axis.value;
+ real x2;
+ Label L=L.copy();
+ int[] divisor=copy(axis.ydivisor);
+ pair side=axis.side;
+ int type=axis.type;
+
+ pic.add(new void (frame f, transform t, transform T, pair lb, pair rt) {
+ transform tinv=inverse(t);
+ pair a=ymin == -infinity ? tinv*(xtrans(t,x),lb.y-min(p).y) : (x,ymin);
+ pair b=ymax == infinity ? tinv*(xtrans(t,x),rt.y-max(p).y) : (x,ymax);
+ pair a2=ymin == -infinity ? tinv*(xtrans(t,x2),lb.y-min(p).y) : (x2,ymin);
+ pair b2=ymax == infinity ? tinv*(xtrans(t,x2),rt.y-max(p).y) : (x2,ymax);
+
+ if(ymin == -infinity || ymax == infinity) {
+ bounds my=autoscale(a.y,b.y,pic.scale.y.scale);
+ pic.scale.y.tickMin=my.min;
+ pic.scale.y.tickMax=my.max;
+ divisor=my.divisor;
+ }
+
+ real fuzz=epsilon*max(abs(a.y),abs(b.y));
+ a -= (0,fuzz);
+ b += (0,fuzz);
+
+ frame d;
+ ticks(d,t,L,side,a--b,finite(x2) ? a2--b2 : nullpath,p,arrow,margin,
+ ticklocate(a.y,b.y,pic.scale.y),divisor,opposite);
+ (above ? add : prepend)(f,t*T*tinv*d);
+ });
+
+ void bounds() {
+ if(type == Min)
+ x=pic.scale.x.automin() ? tickMin(pic).x : pic.userMin.x;
+ else if(type == Max)
+ x=pic.scale.x.automax() ? tickMax(pic).x : pic.userMax.x;
+ else if(type == Both) {
+ x2=pic.scale.x.automax() ? tickMax(pic).x : pic.userMax.x;
+ x=opposite ? x2 :
+ (pic.scale.x.automin() ? tickMin(pic).x : pic.userMin.x);
+ }
+
+ real Ymin=finite(ymin) ? ymin : pic.userMin.y;
+ real Ymax=finite(ymax) ? ymax : pic.userMax.y;
+
+ pair a=(x,Ymin);
+ pair b=(x,Ymax);
+ pair a2=(x2,Ymin);
+ pair b2=(x2,Ymax);
+
+ if(finite(a)) {
+ pic.addPoint(a,min(p));
+ pic.addPoint(a,max(p));
+ }
+
+ if(finite(b)) {
+ pic.addPoint(b,min(p));
+ pic.addPoint(b,max(p));
+ }
+
+ if(finite(a) && finite(b)) {
+ frame d;
+ ticks(d,pic.scaling(warn=false),L,side,
+ (0,a.y)--(0,b.y),(0,a2.y)--(0,b2.y),p,arrow,margin,
+ ticklocate(a.y,b.y,pic.scale.y),divisor,opposite);
+ frame f;
+ if(L.s != "") {
+ Label L0=L.copy();
+ L0.position(0);
+ add(f,L0);
+ }
+ pair pos=a+L.relative()*(b-a);
+ pic.addBox(pos,pos,(min(d).x,min(f).y),(max(d).x,max(f).y));
+ }
+ }
+
+ // Process any queued x axis bound calculation requests.
+ for(int i=0; i < pic.scale.x.bound.length; ++i)
+ pic.scale.x.bound[i]();
+
+ pic.scale.x.bound.delete();
+
+ bounds();
+
+ // Request another y bounds calculation before final picture scaling.
+ pic.scale.y.bound.push(bounds);
+}
+
+// Set the x limits of a picture.
+void xlimits(picture pic=currentpicture, real min=-infinity, real max=infinity,
+ bool crop=NoCrop)
+{
+ if(min > max) return;
+
+ pic.scale.x.automin=min <= -infinity;
+ pic.scale.x.automax=max >= infinity;
+
+ bounds mx;
+ if(pic.scale.x.automin() || pic.scale.x.automax())
+ mx=autoscale(pic.userMin.x,pic.userMax.x,pic.scale.x.scale);
+
+ if(pic.scale.x.automin) {
+ if(pic.scale.x.automin()) pic.userMinx(mx.min);
+ } else pic.userMinx(pic.scale.x.T(min));
+
+ if(pic.scale.x.automax) {
+ if(pic.scale.x.automax()) pic.userMaxx(mx.max);
+ } else pic.userMaxx(pic.scale.x.T(max));
+
+ if(crop) {
+ pair userMin=pic.userMin();
+ pair userMax=pic.userMax();
+ pic.bounds.xclip(userMin.x,userMax.x);
+ pic.clip(new void (frame f, transform t, transform T, pair, pair) {
+ frame Tinvf=T == identity() ? f : t*inverse(T)*inverse(t)*f;
+ clip(f,T*box(((t*userMin).x,(min(Tinvf)).y),
+ ((t*userMax).x,(max(Tinvf)).y)));
+ });
+ }
+}
+
+// Set the y limits of a picture.
+void ylimits(picture pic=currentpicture, real min=-infinity, real max=infinity,
+ bool crop=NoCrop)
+{
+ if(min > max) return;
+
+ pic.scale.y.automin=min <= -infinity;
+ pic.scale.y.automax=max >= infinity;
+
+ bounds my;
+ if(pic.scale.y.automin() || pic.scale.y.automax())
+ my=autoscale(pic.userMin.y,pic.userMax.y,pic.scale.y.scale);
+
+ if(pic.scale.y.automin) {
+ if(pic.scale.y.automin()) pic.userMiny(my.min);
+ } else pic.userMiny(pic.scale.y.T(min));
+
+ if(pic.scale.y.automax) {
+ if(pic.scale.y.automax()) pic.userMaxy(my.max);
+ } else pic.userMaxy(pic.scale.y.T(max));
+
+ if(crop) {
+ pair userMin=pic.userMin();
+ pair userMax=pic.userMax();
+ pic.bounds.yclip(userMin.y,userMax.y);
+ pic.clip(new void (frame f, transform t, transform T, pair, pair) {
+ frame Tinvf=T == identity() ? f : t*inverse(T)*inverse(t)*f;
+ clip(f,T*box(((min(Tinvf)).x,(t*userMin).y),
+ ((max(Tinvf)).x,(t*userMax).y)));
+ });
+ }
+}
+
+// Crop a picture to the current user-space picture limits.
+void crop(picture pic=currentpicture)
+{
+ xlimits(pic,false);
+ ylimits(pic,false);
+ if(pic.userSetx && pic.userSety)
+ clip(pic,box(pic.userMin(),pic.userMax()));
+}
+
+// Restrict the x and y limits to box(min,max).
+void limits(picture pic=currentpicture, pair min, pair max, bool crop=NoCrop)
+{
+ xlimits(pic,min.x,max.x);
+ ylimits(pic,min.y,max.y);
+ if(crop && pic.userSetx && pic.userSety)
+ clip(pic,box(pic.userMin(),pic.userMax()));
+}
+
+// Internal routine to autoscale the user limits of a picture.
+void autoscale(picture pic=currentpicture, axis axis)
+{
+ if(!pic.scale.set) {
+ bounds mx,my;
+ pic.scale.set=true;
+
+ if(pic.userSetx) {
+ mx=autoscale(pic.userMin.x,pic.userMax.x,pic.scale.x.scale);
+ if(pic.scale.x.scale.logarithmic &&
+ floor(pic.userMin.x) == floor(pic.userMax.x)) {
+ if(pic.scale.x.automin())
+ pic.userMinx(floor(pic.userMin.x));
+ if(pic.scale.x.automax())
+ pic.userMaxx(ceil(pic.userMax.x));
+ }
+ } else {mx.min=mx.max=0; pic.scale.set=false;}
+
+ if(pic.userSety) {
+ my=autoscale(pic.userMin.y,pic.userMax.y,pic.scale.y.scale);
+ if(pic.scale.y.scale.logarithmic &&
+ floor(pic.userMin.y) == floor(pic.userMax.y)) {
+ if(pic.scale.y.automin())
+ pic.userMiny(floor(pic.userMin.y));
+ if(pic.scale.y.automax())
+ pic.userMaxy(ceil(pic.userMax.y));
+ }
+ } else {my.min=my.max=0; pic.scale.set=false;}
+
+ pic.scale.x.tickMin=mx.min;
+ pic.scale.x.tickMax=mx.max;
+ pic.scale.y.tickMin=my.min;
+ pic.scale.y.tickMax=my.max;
+ axis.xdivisor=mx.divisor;
+ axis.ydivisor=my.divisor;
+ }
+}
+
+// Draw an x axis.
+void xaxis(picture pic=currentpicture, Label L="", axis axis=YZero,
+ real xmin=-infinity, real xmax=infinity, pen p=currentpen,
+ ticks ticks=NoTicks, arrowbar arrow=None, margin margin=NoMargin,
+ bool above=false)
+{
+ if(xmin > xmax) return;
+
+ if(pic.scale.x.automin && xmin > -infinity) pic.scale.x.automin=false;
+ if(pic.scale.x.automax && xmax < infinity) pic.scale.x.automax=false;
+
+ if(!pic.scale.set) {
+ axis(pic,axis);
+ autoscale(pic,axis);
+ }
+
+ Label L=L.copy();
+ bool newticks=false;
+
+ if(xmin != -infinity) {
+ xmin=pic.scale.x.T(xmin);
+ newticks=true;
+ }
+
+ if(xmax != infinity) {
+ xmax=pic.scale.x.T(xmax);
+ newticks=true;
+ }
+
+ if(newticks && pic.userSetx && ticks != NoTicks) {
+ if(xmin == -infinity) xmin=pic.userMin.x;
+ if(xmax == infinity) xmax=pic.userMax.x;
+ bounds mx=autoscale(xmin,xmax,pic.scale.x.scale);
+ pic.scale.x.tickMin=mx.min;
+ pic.scale.x.tickMax=mx.max;
+ axis.xdivisor=mx.divisor;
+ }
+
+ axis(pic,axis);
+
+ if(xmin == -infinity && !axis.extend) {
+ if(pic.scale.set)
+ xmin=pic.scale.x.automin() ? pic.scale.x.tickMin :
+ max(pic.scale.x.tickMin,pic.userMin.x);
+ else xmin=pic.userMin.x;
+ }
+
+ if(xmax == infinity && !axis.extend) {
+ if(pic.scale.set)
+ xmax=pic.scale.x.automax() ? pic.scale.x.tickMax :
+ min(pic.scale.x.tickMax,pic.userMax.x);
+ else xmax=pic.userMax.x;
+ }
+
+ if(L.defaultposition) L.position(axis.position);
+ L.align(L.align,axis.align);
+
+ xaxisAt(pic,L,axis,xmin,xmax,p,ticks,arrow,margin,above);
+ if(axis.type == Both)
+ xaxisAt(pic,L,axis,xmin,xmax,p,ticks,arrow,margin,above,true);
+}
+
+// Draw a y axis.
+void yaxis(picture pic=currentpicture, Label L="", axis axis=XZero,
+ real ymin=-infinity, real ymax=infinity, pen p=currentpen,
+ ticks ticks=NoTicks, arrowbar arrow=None, margin margin=NoMargin,
+ bool above=false)
+{
+ if(ymin > ymax) return;
+
+ if(pic.scale.y.automin && ymin > -infinity) pic.scale.y.automin=false;
+ if(pic.scale.y.automax && ymax < infinity) pic.scale.y.automax=false;
+
+ if(!pic.scale.set) {
+ axis(pic,axis);
+ autoscale(pic,axis);
+ }
+
+ Label L=L.copy();
+ bool newticks=false;
+
+ if(ymin != -infinity) {
+ ymin=pic.scale.y.T(ymin);
+ newticks=true;
+ }
+
+ if(ymax != infinity) {
+ ymax=pic.scale.y.T(ymax);
+ newticks=true;
+ }
+
+ if(newticks && pic.userSety && ticks != NoTicks) {
+ if(ymin == -infinity) ymin=pic.userMin.y;
+ if(ymax == infinity) ymax=pic.userMax.y;
+ bounds my=autoscale(ymin,ymax,pic.scale.y.scale);
+ pic.scale.y.tickMin=my.min;
+ pic.scale.y.tickMax=my.max;
+ axis.ydivisor=my.divisor;
+ }
+
+ axis(pic,axis);
+
+ if(ymin == -infinity && !axis.extend) {
+ if(pic.scale.set)
+ ymin=pic.scale.y.automin() ? pic.scale.y.tickMin :
+ max(pic.scale.y.tickMin,pic.userMin.y);
+ else ymin=pic.userMin.y;
+ }
+
+
+ if(ymax == infinity && !axis.extend) {
+ if(pic.scale.set)
+ ymax=pic.scale.y.automax() ? pic.scale.y.tickMax :
+ min(pic.scale.y.tickMax,pic.userMax.y);
+ else ymax=pic.userMax.y;
+ }
+
+ if(L.defaultposition) L.position(axis.position);
+ L.align(L.align,axis.align);
+
+ if(L.defaulttransform) {
+ frame f;
+ add(f,Label(L.s,(0,0),L.p));
+ if(length(max(f)-min(f)) > ylabelwidth*fontsize(L.p))
+ L.transform(rotate(90));
+ }
+
+ yaxisAt(pic,L,axis,ymin,ymax,p,ticks,arrow,margin,above);
+ if(axis.type == Both)
+ yaxisAt(pic,L,axis,ymin,ymax,p,ticks,arrow,margin,above,true);
+}
+
+// Draw x and y axes.
+void axes(picture pic=currentpicture, Label xlabel="", Label ylabel="",
+ pair min=(-infinity,-infinity), pair max=(infinity,infinity),
+ pen p=currentpen, arrowbar arrow=None, margin margin=NoMargin,
+ bool above=false)
+{
+ xaxis(pic,xlabel,min.x,max.x,p,arrow,margin,above);
+ yaxis(pic,ylabel,min.y,max.y,p,arrow,margin,above);
+}
+
+// Draw a yaxis at x.
+void xequals(picture pic=currentpicture, Label L="", real x,
+ bool extend=false, real ymin=-infinity, real ymax=infinity,
+ pen p=currentpen, ticks ticks=NoTicks,
+ arrowbar arrow=None, margin margin=NoMargin, bool above=true)
+{
+ yaxis(pic,L,XEquals(x,extend),ymin,ymax,p,ticks,arrow,margin,above);
+}
+
+// Draw an xaxis at y.
+void yequals(picture pic=currentpicture, Label L="", real y,
+ bool extend=false, real xmin=-infinity, real xmax=infinity,
+ pen p=currentpen, ticks ticks=NoTicks,
+ arrowbar arrow=None, margin margin=NoMargin, bool above=true)
+{
+ xaxis(pic,L,YEquals(y,extend),xmin,xmax,p,ticks,arrow,margin,above);
+}
+
+pair Scale(picture pic=currentpicture, pair z)
+{
+ return (pic.scale.x.T(z.x),pic.scale.y.T(z.y));
+}
+
+real ScaleX(picture pic=currentpicture, real x)
+{
+ return pic.scale.x.T(x);
+}
+
+real ScaleY(picture pic=currentpicture, real y)
+{
+ return pic.scale.y.T(y);
+}
+
+// Draw a tick of length size at pair z in direction dir using pen p.
+void tick(picture pic=currentpicture, pair z, pair dir, real size=Ticksize,
+ pen p=currentpen)
+{
+ pic.add(new void (frame f, transform t) {
+ pair tz=t*z;
+ draw(f,tz--tz+unit(dir)*size,p);
+ });
+ pic.addPoint(z,p);
+ pic.addPoint(z,unit(dir)*size,p);
+}
+
+void xtick(picture pic=currentpicture, explicit pair z, pair dir=N,
+ real size=Ticksize, pen p=currentpen)
+{
+ tick(pic,Scale(pic,z),dir,size,p);
+}
+
+void xtick(picture pic=currentpicture, real x, pair dir=N,
+ real size=Ticksize, pen p=currentpen)
+{
+ xtick(pic,(x,pic.scale.y.scale.logarithmic ? 1 : 0),dir,size,p);
+}
+
+void ytick(picture pic=currentpicture, explicit pair z, pair dir=E,
+ real size=Ticksize, pen p=currentpen)
+{
+ xtick(pic,z,dir,size,p);
+}
+
+void ytick(picture pic=currentpicture, real y, pair dir=E,
+ real size=Ticksize, pen p=currentpen)
+{
+ xtick(pic,(pic.scale.x.scale.logarithmic ? 1 : 0,y),dir,size,p);
+}
+
+void tick(picture pic=currentpicture, Label L, real value, explicit pair z,
+ pair dir, string format="", real size=Ticksize, pen p=currentpen)
+{
+ Label L=L.copy();
+ L.position(z);
+ L.align(L.align,-dir);
+ if(shift(L.T)*0 == 0)
+ L.T=shift(dot(dir,L.align.dir) > 0 ? dir*size :
+ ticklabelshift(L.align.dir,p))*L.T;
+ L.p(p);
+ if(L.s == "") L.s=format(format == "" ? defaultformat : format,value);
+ L.s=baseline(L.s,baselinetemplate);
+ add(pic,L);
+ xtick(pic,z,dir,size,p);
+}
+
+void xtick(picture pic=currentpicture, Label L, explicit pair z, pair dir=N,
+ string format="", real size=Ticksize, pen p=currentpen)
+{
+ tick(pic,L,z.x,z,dir,format,size,p);
+}
+
+void xtick(picture pic=currentpicture, Label L, real x, pair dir=N,
+ string format="", real size=Ticksize, pen p=currentpen)
+{
+ xtick(pic,L,(x,pic.scale.y.scale.logarithmic ? 1 : 0),dir,size,p);
+}
+
+void ytick(picture pic=currentpicture, Label L, explicit pair z, pair dir=E,
+ string format="", real size=Ticksize, pen p=currentpen)
+{
+ tick(pic,L,z.y,z,dir,format,size,p);
+}
+
+void ytick(picture pic=currentpicture, Label L, real y, pair dir=E,
+ string format="", real size=Ticksize, pen p=currentpen)
+{
+ ytick(pic,L,(pic.scale.x.scale.logarithmic ? 1 : 0,y),dir,format,size,p);
+}
+
+private void label(picture pic, Label L, pair z, real x, align align,
+ string format, pen p)
+{
+ Label L=L.copy();
+ L.position(z);
+ L.align(align);
+ L.p(p);
+ if(shift(L.T)*0 == 0)
+ L.T=shift(ticklabelshift(L.align.dir,L.p))*L.T;
+ if(L.s == "") L.s=format(format == "" ? defaultformat : format,x);
+ L.s=baseline(L.s,baselinetemplate);
+ add(pic,L);
+}
+
+// Put a label on the x axis.
+void labelx(picture pic=currentpicture, Label L="", explicit pair z,
+ align align=S, string format="", pen p=nullpen)
+{
+ label(pic,L,Scale(pic,z),z.x,align,format,p);
+}
+
+void labelx(picture pic=currentpicture, Label L="", real x,
+ align align=S, string format="", pen p=nullpen)
+{
+ labelx(pic,L,(x,pic.scale.y.scale.logarithmic ? 1 : 0),align,format,p);
+}
+
+void labelx(picture pic=currentpicture, Label L,
+ string format="", explicit pen p=currentpen)
+{
+ labelx(pic,L,L.position.position,format,p);
+}
+
+// Put a label on the y axis.
+void labely(picture pic=currentpicture, Label L="", explicit pair z,
+ align align=W, string format="", pen p=nullpen)
+{
+ label(pic,L,Scale(pic,z),z.y,align,format,p);
+}
+
+void labely(picture pic=currentpicture, Label L="", real y,
+ align align=W, string format="", pen p=nullpen)
+{
+ labely(pic,L,(pic.scale.x.scale.logarithmic ? 1 : 0,y),align,format,p);
+}
+
+void labely(picture pic=currentpicture, Label L,
+ string format="", explicit pen p=nullpen)
+{
+ labely(pic,L,L.position.position,format,p);
+}
+
+private string noprimary="Primary axis must be drawn before secondary axis";
+
+// Construct a secondary X axis
+picture secondaryX(picture primary=currentpicture, void f(picture))
+{
+ if(!primary.scale.set) abort(noprimary);
+ picture pic;
+ if(primary.userMax.x == primary.userMin.x) return pic;
+ f(pic);
+ if(!pic.userSetx) return pic;
+ bounds a=autoscale(pic.userMin.x,pic.userMax.x,pic.scale.x.scale);
+ real bmin=pic.scale.x.automin() ? a.min : pic.userMin.x;
+ real bmax=pic.scale.x.automax() ? a.max : pic.userMax.x;
+
+ real denom=bmax-bmin;
+ if(denom != 0) {
+ pic.erase();
+ real m=(primary.userMax.x-primary.userMin.x)/denom;
+ pic.scale.x.postscale=Linear(m,bmin-primary.userMin.x/m);
+ pic.scale.set=true;
+ pic.scale.x.tickMin=pic.scale.x.postscale.T(a.min);
+ pic.scale.x.tickMax=pic.scale.x.postscale.T(a.max);
+ pic.scale.y.tickMin=primary.userMin.y;
+ pic.scale.y.tickMax=primary.userMax.y;
+ axis.xdivisor=a.divisor;
+ f(pic);
+ }
+ pic.userCopy(primary);
+ return pic;
+}
+
+// Construct a secondary Y axis
+picture secondaryY(picture primary=currentpicture, void f(picture))
+{
+ if(!primary.scale.set) abort(noprimary);
+ picture pic;
+ if(primary.userMax.y == primary.userMin.y) return pic;
+ f(pic);
+ if(!pic.userSety) return pic;
+ bounds a=autoscale(pic.userMin.y,pic.userMax.y,pic.scale.y.scale);
+ real bmin=pic.scale.y.automin() ? a.min : pic.userMin.y;
+ real bmax=pic.scale.y.automax() ? a.max : pic.userMax.y;
+
+ real denom=bmax-bmin;
+ if(denom != 0) {
+ pic.erase();
+ real m=(primary.userMax.y-primary.userMin.y)/denom;
+ pic.scale.y.postscale=Linear(m,bmin-primary.userMin.y/m);
+ pic.scale.set=true;
+ pic.scale.x.tickMin=primary.userMin.x;
+ pic.scale.x.tickMax=primary.userMax.x;
+ pic.scale.y.tickMin=pic.scale.y.postscale.T(a.min);
+ pic.scale.y.tickMax=pic.scale.y.postscale.T(a.max);
+ axis.ydivisor=a.divisor;
+ f(pic);
+ }
+ pic.userCopy(primary);
+ return pic;
+}
+
+typedef guide graph(pair f(real), real, real, int);
+typedef guide[] multigraph(pair f(real), real, real, int);
+
+graph graph(interpolate join)
+{
+ return new guide(pair f(real), real a, real b, int n) {
+ real width=b-a;
+ return n == 0 ? join(f(a)) :
+ join(...sequence(new guide(int i) {return f(a+(i/n)*width);},n+1));
+ };
+}
+
+multigraph graph(interpolate join, bool3 cond(real))
+{
+ return new guide[](pair f(real), real a, real b, int n) {
+ real width=b-a;
+ if(n == 0) return new guide[] {join(cond(a) ? f(a) : nullpath)};
+ guide[] G;
+ guide[] g;
+ for(int i=0; i < n+1; ++i) {
+ real t=a+(i/n)*width;
+ bool3 b=cond(t);
+ if(b)
+ g.push(f(t));
+ else {
+ if(g.length > 0) {
+ G.push(join(...g));
+ g=new guide[] {};
+ }
+ if(b == default)
+ g.push(f(t));
+ }
+ }
+ if(g.length > 0)
+ G.push(join(...g));
+ return G;
+ };
+}
+
+guide Straight(... guide[])=operator --;
+guide Spline(... guide[])=operator ..;
+
+interpolate Hermite(splinetype splinetype)
+{
+ return new guide(... guide[] a) {
+ int n=a.length;
+ if(n == 0) return nullpath;
+ real[] x,y;
+ guide G;
+ for(int i=0; i < n; ++i) {
+ guide g=a[i];
+ int m=size(g);
+ if(m == 0) continue;
+ pair z=point(g,0);
+ x.push(z.x);
+ y.push(z.y);
+ if(m > 1) {
+ G=G..hermite(x,y,splinetype) & g;
+ pair z=point(g,m);
+ x=new real[] {z.x};
+ y=new real[] {z.y};
+ }
+ }
+ return G & hermite(x,y,splinetype);
+ };
+}
+
+interpolate Hermite=Hermite(defaultspline);
+
+guide graph(picture pic=currentpicture, real f(real), real a, real b,
+ int n=ngraph, real T(real)=identity, interpolate join=operator --)
+{
+ if(T == identity)
+ return graph(join)(new pair(real x) {
+ return (x,pic.scale.y.T(f(pic.scale.x.Tinv(x))));},
+ pic.scale.x.T(a),pic.scale.x.T(b),n);
+ else
+ return graph(join)(new pair(real x) {
+ return Scale(pic,(T(x),f(T(x))));},
+ a,b,n);
+}
+
+guide[] graph(picture pic=currentpicture, real f(real), real a, real b,
+ int n=ngraph, real T(real)=identity,
+ bool3 cond(real), interpolate join=operator --)
+{
+ if(T == identity)
+ return graph(join,cond)(new pair(real x) {
+ return (x,pic.scale.y.T(f(pic.scale.x.Tinv(x))));},
+ pic.scale.x.T(a),pic.scale.x.T(b),n);
+ else
+ return graph(join,cond)(new pair(real x) {
+ return Scale(pic,(T(x),f(T(x))));},
+ a,b,n);
+}
+
+guide graph(picture pic=currentpicture, real x(real), real y(real), real a,
+ real b, int n=ngraph, real T(real)=identity,
+ interpolate join=operator --)
+{
+ if(T == identity)
+ return graph(join)(new pair(real t) {return Scale(pic,(x(t),y(t)));},a,b,n);
+ else
+ return graph(join)(new pair(real t) {
+ return Scale(pic,(x(T(t)),y(T(t))));
+ },a,b,n);
+}
+
+guide[] graph(picture pic=currentpicture, real x(real), real y(real), real a,
+ real b, int n=ngraph, real T(real)=identity, bool3 cond(real),
+ interpolate join=operator --)
+{
+ if(T == identity)
+ return graph(join,cond)(new pair(real t) {return Scale(pic,(x(t),y(t)));},
+ a,b,n);
+ else
+ return graph(join,cond)(new pair(real t) {
+ return Scale(pic,(x(T(t)),y(T(t))));},
+ a,b,n);
+}
+
+guide graph(picture pic=currentpicture, pair z(real), real a, real b,
+ int n=ngraph, real T(real)=identity, interpolate join=operator --)
+{
+ if(T == identity)
+ return graph(join)(new pair(real t) {return Scale(pic,z(t));},a,b,n);
+ else
+ return graph(join)(new pair(real t) {
+ return Scale(pic,z(T(t)));
+ },a,b,n);
+}
+
+guide[] graph(picture pic=currentpicture, pair z(real), real a, real b,
+ int n=ngraph, real T(real)=identity, bool3 cond(real),
+ interpolate join=operator --)
+{
+ if(T == identity)
+ return graph(join,cond)(new pair(real t) {return Scale(pic,z(t));},a,b,n);
+ else
+ return graph(join,cond)(new pair(real t) {
+ return Scale(pic,z(T(t)));
+ },a,b,n);
+}
+
+string differentlengths="attempt to graph arrays of different lengths";
+string conditionlength="condition array has different length than data";
+
+void checklengths(int x, int y, string text=differentlengths)
+{
+ if(x != y)
+ abort(text+": "+string(x)+" != "+string(y));
+}
+
+void checkconditionlength(int x, int y)
+{
+ checklengths(x,y,conditionlength);
+}
+
+guide graph(picture pic=currentpicture, pair[] z, interpolate join=operator --)
+{
+ int i=0;
+ return graph(join)(new pair(real) {
+ pair w=Scale(pic,z[i]);
+ ++i;
+ return w;
+ },0,0,z.length-1);
+}
+
+guide[] graph(picture pic=currentpicture, pair[] z, bool3[] cond,
+ interpolate join=operator --)
+{
+ int n=z.length;
+ int i=0;
+ pair w;
+ checkconditionlength(cond.length,n);
+ bool3 condition(real) {
+ bool3 b=cond[i];
+ if(b != false) w=Scale(pic,z[i]);
+ ++i;
+ return b;
+ }
+ return graph(join,condition)(new pair(real) {return w;},0,0,n-1);
+}
+
+guide graph(picture pic=currentpicture, real[] x, real[] y,
+ interpolate join=operator --)
+{
+ int n=x.length;
+ checklengths(n,y.length);
+ int i=0;
+ return graph(join)(new pair(real) {
+ pair w=Scale(pic,(x[i],y[i]));
+ ++i;
+ return w;
+ },0,0,n-1);
+}
+
+guide[] graph(picture pic=currentpicture, real[] x, real[] y, bool3[] cond,
+ interpolate join=operator --)
+{
+ int n=x.length;
+ checklengths(n,y.length);
+ int i=0;
+ pair w;
+ checkconditionlength(cond.length,n);
+ bool3 condition(real) {
+ bool3 b=cond[i];
+ if(b != false) w=Scale(pic,(x[i],y[i]));
+ ++i;
+ return b;
+ }
+ return graph(join,condition)(new pair(real) {return w;},0,0,n-1);
+}
+
+// Connect points in z into segments corresponding to consecutive true elements
+// of b using interpolation operator join.
+path[] segment(pair[] z, bool[] cond, interpolate join=operator --)
+{
+ checkconditionlength(cond.length,z.length);
+ int[][] segment=segment(cond);
+ return sequence(new path(int i) {return join(...z[segment[i]]);},
+ segment.length);
+}
+
+pair polar(real r, real theta)
+{
+ return r*expi(theta);
+}
+
+guide polargraph(picture pic=currentpicture, real r(real), real a, real b,
+ int n=ngraph, interpolate join=operator --)
+{
+ return graph(join)(new pair(real theta) {
+ return Scale(pic,polar(r(theta),theta));
+ },a,b,n);
+}
+
+void errorbar(picture pic, pair z, pair dp, pair dm, pen p=currentpen,
+ real size=0)
+{
+ real dmx=-abs(dm.x);
+ real dmy=-abs(dm.y);
+ real dpx=abs(dp.x);
+ real dpy=abs(dp.y);
+ if(dmx != dpx) draw(pic,Scale(pic,z+(dmx,0))--Scale(pic,z+(dpx,0)),p,
+ Bars(size));
+ if(dmy != dpy) draw(pic,Scale(pic,z+(0,dmy))--Scale(pic,z+(0,dpy)),p,
+ Bars(size));
+}
+
+void errorbars(picture pic=currentpicture, pair[] z, pair[] dp, pair[] dm={},
+ bool[] cond={}, pen p=currentpen, real size=0)
+{
+ if(dm.length == 0) dm=dp;
+ int n=z.length;
+ checklengths(n,dm.length);
+ checklengths(n,dp.length);
+ bool all=cond.length == 0;
+ if(!all)
+ checkconditionlength(cond.length,n);
+ for(int i=0; i < n; ++i) {
+ if(all || cond[i])
+ errorbar(pic,z[i],dp[i],dm[i],p,size);
+ }
+}
+
+void errorbars(picture pic=currentpicture, real[] x, real[] y,
+ real[] dpx, real[] dpy, real[] dmx={}, real[] dmy={},
+ bool[] cond={}, pen p=currentpen, real size=0)
+{
+ if(dmx.length == 0) dmx=dpx;
+ if(dmy.length == 0) dmy=dpy;
+ int n=x.length;
+ checklengths(n,y.length);
+ checklengths(n,dpx.length);
+ checklengths(n,dpy.length);
+ checklengths(n,dmx.length);
+ checklengths(n,dmy.length);
+ bool all=cond.length == 0;
+ if(!all)
+ checkconditionlength(cond.length,n);
+ for(int i=0; i < n; ++i) {
+ if(all || cond[i])
+ errorbar(pic,(x[i],y[i]),(dpx[i],dpy[i]),(dmx[i],dmy[i]),p,size);
+ }
+}
+
+void errorbars(picture pic=currentpicture, real[] x, real[] y,
+ real[] dpy, bool[] cond={}, pen p=currentpen, real size=0)
+{
+ errorbars(pic,x,y,0*x,dpy,cond,p,size);
+}
+
+// Return a vector field on path g, specifying the vector as a function of the
+// relative position along path g in [0,1].
+picture vectorfield(path vector(real), path g, int n, bool truesize=false,
+ pen p=currentpen, arrowbar arrow=Arrow,
+ margin margin=PenMargin)
+{
+ picture pic;
+ for(int i=0; i < n; ++i) {
+ real x=(n == 1) ? 0.5 : i/(n-1);
+ if(truesize)
+ draw(relpoint(g,x),pic,vector(x),p,arrow);
+ else
+ draw(pic,shift(relpoint(g,x))*vector(x),p,arrow,margin);
+ }
+ return pic;
+}
+
+picture vectorfield(path vector(pair), pair a, pair b,
+ int nx=nmesh, int ny=nx,
+ bool autoscale=true, bool truesize=false,
+ pen p=currentpen, arrowbar arrow=Arrow,
+ margin margin=PenMargin)
+{
+ picture pic;
+ real dx=1/nx;
+ real dy=1/ny;
+ real scale;
+ if(autoscale) {
+ real size(pair z) {
+ path g=vector(z);
+ return abs(point(g,size(g)-1)-point(g,0));
+ }
+ real max=size((0,0));
+ for(int i=0; i <= nx; ++i) {
+ real x=interp(a.x,b.x,i*dx);
+ for(int j=0; j <= ny; ++j)
+ max=max(max,size((x,interp(a.y,b.y,j*dy))));
+ }
+ pair lambda=b-a;
+ scale=min(lambda.x/nx,lambda.y/ny)/max;
+ } else scale=1;
+ for(int i=0; i <= nx; ++i) {
+ real x=interp(a.x,b.x,i*dx);
+ for(int j=0; j <= ny; ++j) {
+ real y=interp(a.y,b.y,j*dy);
+ pair z=(x,y);
+ if(truesize)
+ draw(z,pic,vector(z),p,arrow);
+ else
+ draw(pic,shift(z)*scale(scale)*vector(z),p,arrow,margin);
+ }
+ }
+ return pic;
+}
+
+// True arc
+path Arc(pair c, real r, real angle1, real angle2, bool direction,
+ int n=nCircle)
+{
+ angle1=radians(angle1);
+ angle2=radians(angle2);
+ if(angle1 >= angle2 && direction) angle1 -= 2pi;
+ if(angle2 >= angle1 && !direction) angle2 -= 2pi;
+ return shift(c)*polargraph(new real(real t){return r;},angle1,angle2,n,
+ operator ..);
+}
+
+path Arc(pair c, real r, real angle1, real angle2, int n=nCircle)
+{
+ return Arc(c,r,angle1,angle2,angle2 >= angle1 ? CCW : CW,n);
+}
+
+path Arc(pair c, explicit pair z1, explicit pair z2, bool direction=CCW,
+ int n=nCircle)
+{
+ return Arc(c,abs(z1-c),degrees(z1-c),degrees(z2-c),direction,n);
+}
+
+// True circle
+path Circle(pair c, real r, int n=nCircle)
+{
+ return Arc(c,r,0,360,n)&cycle;
+}
diff --git a/Build/source/utils/asymptote/base/graph3.asy b/Build/source/utils/asymptote/base/graph3.asy
new file mode 100644
index 00000000000..43bf62d26ca
--- /dev/null
+++ b/Build/source/utils/asymptote/base/graph3.asy
@@ -0,0 +1,1926 @@
+// Three-dimensional graphing routines
+
+private import math;
+import graph;
+import three;
+
+triple zero3(real) {return O;}
+
+typedef triple direction3(real);
+direction3 Dir(triple dir) {return new triple(real) {return dir;};}
+
+ticklocate ticklocate(real a, real b, autoscaleT S=defaultS,
+ real tickmin=-infinity, real tickmax=infinity,
+ real time(real)=null, direction3 dir)
+{
+ if((valuetime) time == null) time=linear(S.T(),a,b);
+ ticklocate locate;
+ locate.a=a;
+ locate.b=b;
+ locate.S=S.copy();
+ if(finite(tickmin)) locate.S.tickMin=tickmin;
+ if(finite(tickmax)) locate.S.tickMax=tickmax;
+ locate.time=time;
+ locate.dir=zero;
+ locate.dir3=dir;
+ return locate;
+}
+
+private struct locateT {
+ real t; // tick location time
+ triple V; // tick location in frame coordinates
+ triple pathdir; // path direction in frame coordinates
+ triple dir; // tick direction in frame coordinates
+
+ void dir(transform3 T, path3 g, ticklocate locate, real t) {
+ pathdir=unit(shiftless(T)*dir(g,t));
+ triple Dir=locate.dir3(t);
+ dir=unit(Dir);
+ }
+ // Locate the desired position of a tick along a path.
+ void calc(transform3 T, path3 g, ticklocate locate, real val) {
+ t=locate.time(val);
+ V=T*point(g,t);
+ dir(T,g,locate,t);
+ }
+}
+
+void drawtick(picture pic, transform3 T, path3 g, path3 g2,
+ ticklocate locate, real val, real Size, int sign, pen p,
+ bool extend)
+{
+ locateT locate1,locate2;
+ locate1.calc(T,g,locate,val);
+ path3 G;
+ if(extend && size(g2) > 0) {
+ locate2.calc(T,g2,locate,val);
+ G=locate1.V--locate2.V;
+ } else
+ G=(sign == 0) ?
+ locate1.V-Size*locate1.dir--locate1.V+Size*locate1.dir :
+ locate1.V--locate1.V+Size*sign*locate1.dir;
+ draw(pic,G,p);
+}
+
+triple ticklabelshift(triple align, pen p=currentpen)
+{
+ return 0.25*unit(align)*labelmargin(p);
+}
+
+// Signature of routines that draw labelled paths with ticks and tick labels.
+typedef void ticks3(picture, transform3, Label, path3, path3, pen,
+ arrowbar3, margin3, ticklocate, int[], bool opposite=false,
+ bool primary=true);
+
+// Label a tick on a frame.
+void labeltick(picture pic, transform3 T, path3 g,
+ ticklocate locate, real val, int sign, real Size,
+ ticklabel ticklabel, Label F, real norm=0)
+{
+ locateT locate1;
+ locate1.calc(T,g,locate,val);
+ triple align=F.align.dir3;
+ if(align == O) align=sign*locate1.dir;
+
+ triple shift=align*labelmargin(F.p);
+ if(dot(align,sign*locate1.dir) >= 0)
+ shift=sign*(Size)*locate1.dir;
+
+ real label;
+ if(locate.S.scale.logarithmic)
+ label=locate.S.scale.Tinv(val);
+ else {
+ label=val;
+ if(abs(label) < zerotickfuzz*norm) label=0;
+ // Fix epsilon errors at +/-1e-4
+ // default format changes to scientific notation here
+ if(abs(abs(label)-1e-4) < epsilon) label=sgn(label)*1e-4;
+ }
+
+ string s=ticklabel(label);
+ triple v=locate1.V+shift;
+ if(s != "")
+ label(pic,F.defaulttransform3 ? baseline(s,baselinetemplate) : F.T3*s,v,
+ align,F.p);
+}
+
+// Add axis label L to frame f.
+void labelaxis(picture pic, transform3 T, Label L, path3 g,
+ ticklocate locate=null, int sign=1, bool ticklabels=false)
+{
+ triple m=pic.min(identity4);
+ triple M=pic.max(identity4);
+ triple align=L.align.dir3;
+ Label L=L.copy();
+
+ pic.add(new void(frame f, transform3 T, picture pic2, projection P) {
+ path3 g=T*g;
+ real t=relative(L,g);
+ triple v=point(g,t);
+ picture F;
+ if(L.align.dir3 == O)
+ align=unit(invert(L.align.dir,v,P))*abs(L.align.dir);
+
+ if(ticklabels && locate != null && piecewisestraight(g)) {
+ locateT locate1;
+ locate1.dir(T,g,locate,t);
+ triple pathdir=locate1.pathdir;
+
+ triple perp=cross(pathdir,P.vector());
+ if(align == O)
+ align=unit(sgn(dot(sign*locate1.dir,perp))*perp);
+ path[] g=project(box(T*m,T*M),P);
+ pair z=project(v,P);
+ pair Ppathdir=project(v+pathdir,P)-z;
+ pair Perp=unit(I*Ppathdir);
+ real angle=degrees(Ppathdir,warn=false);
+ transform S=rotate(-angle,z);
+ path[] G=S*g;
+ pair Palign=project(v+align,P)-z;
+ pair Align=rotate(-angle)*dot(Palign,Perp)*Perp;
+ pair offset=unit(Palign)*
+ abs((Align.y >= 0 ? max(G).y : (Align.y < 0 ? min(G).y : 0))-z.y);
+ triple normal=cross(pathdir,align);
+ if(normal != O) v=invert(z+offset,normal,v,P);
+ }
+
+ label(F,L,v);
+ add(f,F.fit3(identity4,pic2,P));
+ },exact=false);
+
+ path3[] G=path3(texpath(L));
+ G=L.align.is3D ? align(G,O,align,L.p) : L.T3*G;
+ triple v=point(g,relative(L,g));
+ pic.addBox(v,v,min(G),max(G));
+}
+
+// Tick construction routine for a user-specified array of tick values.
+ticks3 Ticks3(int sign, Label F="", ticklabel ticklabel=null,
+ bool beginlabel=true, bool endlabel=true,
+ real[] Ticks=new real[], real[] ticks=new real[], int N=1,
+ bool begin=true, bool end=true,
+ real Size=0, real size=0, bool extend=false,
+ pen pTick=nullpen, pen ptick=nullpen)
+{
+ return new void(picture pic, transform3 t, Label L, path3 g, path3 g2, pen p,
+ arrowbar3 arrow, margin3 margin, ticklocate locate,
+ int[] divisor, bool opposite, bool primary) {
+ // Use local copy of context variables:
+ int Sign=opposite ? -1 : 1;
+ int sign=Sign*sign;
+ pen pTick=pTick;
+ pen ptick=ptick;
+ ticklabel ticklabel=ticklabel;
+
+ real Size=Size;
+ real size=size;
+ if(Size == 0) Size=Ticksize;
+ if(size == 0) size=ticksize;
+
+ Label L=L.copy();
+ Label F=F.copy();
+ L.p(p);
+ F.p(p);
+ if(pTick == nullpen) pTick=p;
+ if(ptick == nullpen) ptick=pTick;
+
+ bool ticklabels=false;
+ path3 G=t*g;
+ path3 G2=t*g2;
+
+ scalefcn T;
+
+ real a,b;
+ if(locate.S.scale.logarithmic) {
+ a=locate.S.postscale.Tinv(locate.a);
+ b=locate.S.postscale.Tinv(locate.b);
+ T=locate.S.scale.T;
+ } else {
+ a=locate.S.Tinv(locate.a);
+ b=locate.S.Tinv(locate.b);
+ T=identity;
+ }
+
+ if(a > b) {real temp=a; a=b; b=temp;}
+
+ real norm=max(abs(a),abs(b));
+
+ string format=autoformat(F.s,norm...Ticks);
+ if(F.s == "%") F.s="";
+ if(ticklabel == null) {
+ if(locate.S.scale.logarithmic) {
+ int base=round(locate.S.scale.Tinv(1));
+ ticklabel=format == "%" ? Format("") : DefaultLogFormat(base);
+ } else ticklabel=Format(format);
+ }
+
+ begingroup3(pic);
+ if(primary) draw(pic,margin(G,p).g,p,arrow);
+ else draw(pic,G,p);
+
+ for(int i=(begin ? 0 : 1); i < (end ? Ticks.length : Ticks.length-1); ++i) {
+ real val=T(Ticks[i]);
+ if(val >= a && val <= b)
+ drawtick(pic,t,g,g2,locate,val,Size,sign,pTick,extend);
+ }
+ for(int i=0; i < ticks.length; ++i) {
+ real val=T(ticks[i]);
+ if(val >= a && val <= b)
+ drawtick(pic,t,g,g2,locate,val,size,sign,ptick,extend);
+ }
+ endgroup3(pic);
+
+ if(N == 0) N=1;
+ if(Size > 0 && primary) {
+ for(int i=(beginlabel ? 0 : 1);
+ i < (endlabel ? Ticks.length : Ticks.length-1); i += N) {
+ real val=T(Ticks[i]);
+ if(val >= a && val <= b) {
+ ticklabels=true;
+ labeltick(pic,t,g,locate,val,Sign,Size,ticklabel,F,norm);
+ }
+ }
+ }
+ if(L.s != "" && primary)
+ labelaxis(pic,t,L,G,locate,Sign,ticklabels);
+ };
+}
+
+// Automatic tick construction routine.
+ticks3 Ticks3(int sign, Label F="", ticklabel ticklabel=null,
+ bool beginlabel=true, bool endlabel=true,
+ int N, int n=0, real Step=0, real step=0,
+ bool begin=true, bool end=true, tickmodifier modify=None,
+ real Size=0, real size=0, bool extend=false,
+ pen pTick=nullpen, pen ptick=nullpen)
+{
+ return new void(picture pic, transform3 T, Label L,
+ path3 g, path3 g2, pen p,
+ arrowbar3 arrow, margin3 margin=NoMargin3, ticklocate locate,
+ int[] divisor, bool opposite, bool primary) {
+ path3 G=T*g;
+ real limit=Step == 0 ? axiscoverage*arclength(G) : 0;
+ tickvalues values=modify(generateticks(sign,F,ticklabel,N,n,Step,step,
+ Size,size,identity(),1,
+ project(G,currentprojection),
+ limit,p,locate,divisor,
+ opposite));
+ Ticks3(sign,F,ticklabel,beginlabel,endlabel,values.major,values.minor,
+ values.N,begin,end,Size,size,extend,pTick,ptick)
+ (pic,T,L,g,g2,p,arrow,margin,locate,divisor,opposite,primary);
+ };
+}
+
+ticks3 NoTicks3()
+{
+ return new void(picture pic, transform3 T, Label L, path3 g,
+ path3, pen p, arrowbar3 arrow, margin3 margin,
+ ticklocate, int[], bool opposite, bool primary) {
+ path3 G=T*g;
+ if(primary) draw(pic,margin(G,p).g,p,arrow,margin);
+ else draw(pic,G,p);
+ if(L.s != "" && primary) {
+ Label L=L.copy();
+ L.p(p);
+ labelaxis(pic,T,L,G,opposite ? -1 : 1);
+ }
+ };
+}
+
+ticks3 InTicks(Label format="", ticklabel ticklabel=null,
+ bool beginlabel=true, bool endlabel=true,
+ int N=0, int n=0, real Step=0, real step=0,
+ bool begin=true, bool end=true, tickmodifier modify=None,
+ real Size=0, real size=0, bool extend=false,
+ pen pTick=nullpen, pen ptick=nullpen)
+{
+ return Ticks3(-1,format,ticklabel,beginlabel,endlabel,N,n,Step,step,
+ begin,end,modify,Size,size,extend,pTick,ptick);
+}
+
+ticks3 OutTicks(Label format="", ticklabel ticklabel=null,
+ bool beginlabel=true, bool endlabel=true,
+ int N=0, int n=0, real Step=0, real step=0,
+ bool begin=true, bool end=true, tickmodifier modify=None,
+ real Size=0, real size=0, bool extend=false,
+ pen pTick=nullpen, pen ptick=nullpen)
+{
+ return Ticks3(1,format,ticklabel,beginlabel,endlabel,N,n,Step,step,
+ begin,end,modify,Size,size,extend,pTick,ptick);
+}
+
+ticks3 InOutTicks(Label format="", ticklabel ticklabel=null,
+ bool beginlabel=true, bool endlabel=true,
+ int N=0, int n=0, real Step=0, real step=0,
+ bool begin=true, bool end=true, tickmodifier modify=None,
+ real Size=0, real size=0, bool extend=false,
+ pen pTick=nullpen, pen ptick=nullpen)
+{
+ return Ticks3(0,format,ticklabel,beginlabel,endlabel,N,n,Step,step,
+ begin,end,modify,Size,size,extend,pTick,ptick);
+}
+
+ticks3 InTicks(Label format="", ticklabel ticklabel=null,
+ bool beginlabel=true, bool endlabel=true,
+ real[] Ticks, real[] ticks=new real[],
+ real Size=0, real size=0, bool extend=false,
+ pen pTick=nullpen, pen ptick=nullpen)
+{
+ return Ticks3(-1,format,ticklabel,beginlabel,endlabel,
+ Ticks,ticks,Size,size,extend,pTick,ptick);
+}
+
+ticks3 OutTicks(Label format="", ticklabel ticklabel=null,
+ bool beginlabel=true, bool endlabel=true,
+ real[] Ticks, real[] ticks=new real[],
+ real Size=0, real size=0, bool extend=false,
+ pen pTick=nullpen, pen ptick=nullpen)
+{
+ return Ticks3(1,format,ticklabel,beginlabel,endlabel,
+ Ticks,ticks,Size,size,extend,pTick,ptick);
+}
+
+ticks3 InOutTicks(Label format="", ticklabel ticklabel=null,
+ bool beginlabel=true, bool endlabel=true,
+ real[] Ticks, real[] ticks=new real[],
+ real Size=0, real size=0, bool extend=false,
+ pen pTick=nullpen, pen ptick=nullpen)
+{
+ return Ticks3(0,format,ticklabel,beginlabel,endlabel,
+ Ticks,ticks,Size,size,extend,pTick,ptick);
+}
+
+ticks3 NoTicks3=NoTicks3(),
+InTicks=InTicks(),
+OutTicks=OutTicks(),
+InOutTicks=InOutTicks();
+
+triple tickMin3(picture pic)
+{
+ return minbound(pic.userMin,(pic.scale.x.tickMin,pic.scale.y.tickMin,
+ pic.scale.z.tickMin));
+}
+
+triple tickMax3(picture pic)
+{
+ return maxbound(pic.userMax,(pic.scale.x.tickMax,pic.scale.y.tickMax,
+ pic.scale.z.tickMax));
+}
+
+axis Bounds(int type=Both, int type2=Both, triple align=O, bool extend=false)
+{
+ return new void(picture pic, axisT axis) {
+ axis.type=type;
+ axis.type2=type2;
+ axis.position=0.5;
+ axis.align=align;
+ axis.extend=extend;
+ };
+}
+
+axis YZEquals(real y, real z, triple align=O, bool extend=false)
+{
+ return new void(picture pic, axisT axis) {
+ axis.type=Value;
+ axis.type2=Value;
+ axis.value=pic.scale.y.T(y);
+ axis.value2=pic.scale.z.T(z);
+ axis.position=1;
+ axis.align=align;
+ axis.extend=extend;
+ };
+}
+
+axis XZEquals(real x, real z, triple align=O, bool extend=false)
+{
+ return new void(picture pic, axisT axis) {
+ axis.type=Value;
+ axis.type2=Value;
+ axis.value=pic.scale.x.T(x);
+ axis.value2=pic.scale.z.T(z);
+ axis.position=1;
+ axis.align=align;
+ axis.extend=extend;
+ };
+}
+
+axis XYEquals(real x, real y, triple align=O, bool extend=false)
+{
+ return new void(picture pic, axisT axis) {
+ axis.type=Value;
+ axis.type2=Value;
+ axis.value=pic.scale.x.T(x);
+ axis.value2=pic.scale.y.T(y);
+ axis.position=1;
+ axis.align=align;
+ axis.extend=extend;
+ };
+}
+
+axis YZZero(triple align=O, bool extend=false)
+{
+ return new void(picture pic, axisT axis) {
+ axis.type=Value;
+ axis.type2=Value;
+ axis.value=pic.scale.y.T(pic.scale.y.scale.logarithmic ? 1 : 0);
+ axis.value2=pic.scale.z.T(pic.scale.z.scale.logarithmic ? 1 : 0);
+ axis.position=1;
+ axis.align=align;
+ axis.extend=extend;
+ };
+}
+
+axis XZZero(triple align=O, bool extend=false)
+{
+ return new void(picture pic, axisT axis) {
+ axis.type=Value;
+ axis.type2=Value;
+ axis.value=pic.scale.x.T(pic.scale.x.scale.logarithmic ? 1 : 0);
+ axis.value2=pic.scale.z.T(pic.scale.z.scale.logarithmic ? 1 : 0);
+ axis.position=1;
+ axis.align=align;
+ axis.extend=extend;
+ };
+}
+
+axis XYZero(triple align=O, bool extend=false)
+{
+ return new void(picture pic, axisT axis) {
+ axis.type=Value;
+ axis.type2=Value;
+ axis.value=pic.scale.x.T(pic.scale.x.scale.logarithmic ? 1 : 0);
+ axis.value2=pic.scale.y.T(pic.scale.y.scale.logarithmic ? 1 : 0);
+ axis.position=1;
+ axis.align=align;
+ axis.extend=extend;
+ };
+}
+
+axis
+Bounds=Bounds(),
+YZZero=YZZero(),
+XZZero=XZZero(),
+XYZero=XYZero();
+
+// Draw a general three-dimensional axis.
+void axis(picture pic=currentpicture, Label L="", path3 g, path3 g2=nullpath3,
+ pen p=currentpen, ticks3 ticks, ticklocate locate,
+ arrowbar3 arrow=None, margin3 margin=NoMargin3,
+ int[] divisor=new int[], bool above=false, bool opposite=false)
+{
+ Label L=L.copy();
+ real t=reltime(g,0.5);
+ if(L.defaultposition) L.position(t);
+ divisor=copy(divisor);
+ locate=locate.copy();
+
+ pic.add(new void (picture f, transform3 t, transform3 T, triple, triple) {
+ picture d;
+ ticks(d,t,L,g,g2,p,arrow,margin,locate,divisor,opposite,true);
+ add(f,t*T*inverse(t)*d);
+ },above=above);
+
+ addPath(pic,g,p);
+
+ if(L.s != "") {
+ frame f;
+ Label L0=L.copy();
+ L0.position(0);
+ add(f,L0);
+ triple pos=point(g,L.relative()*length(g));
+ pic.addBox(pos,pos,min3(f),max3(f));
+ }
+}
+
+real xtrans(transform3 t, real x)
+{
+ return (t*(x,0,0)).x;
+}
+
+real ytrans(transform3 t, real y)
+{
+ return (t*(0,y,0)).y;
+}
+
+real ztrans(transform3 t, real z)
+{
+ return (t*(0,0,z)).z;
+}
+
+private triple defaultdir(triple X, triple Y, triple Z, bool opposite=false,
+ projection P) {
+ triple u=cross(P.vector(),Z);
+ return abs(dot(u,X)) > abs(dot(u,Y)) ? -X : (opposite ? Y : -Y);
+}
+
+// An internal routine to draw an x axis at a particular y value.
+void xaxis3At(picture pic=currentpicture, Label L="", axis axis,
+ real xmin=-infinity, real xmax=infinity, pen p=currentpen,
+ ticks3 ticks=NoTicks3,
+ arrowbar3 arrow=None, margin3 margin=NoMargin3, bool above=true,
+ bool opposite=false, bool opposite2=false, bool primary=true)
+{
+ int type=axis.type;
+ int type2=axis.type2;
+ triple dir=axis.align.dir3 == O ?
+ defaultdir(Y,Z,X,opposite^opposite2,currentprojection) : axis.align.dir3;
+ Label L=L.copy();
+ if(L.align.dir3 == O && L.align.dir == 0) L.align(opposite ? -dir : dir);
+
+ real y=axis.value;
+ real z=axis.value2;
+ real y2,z2;
+ int[] divisor=copy(axis.xdivisor);
+
+ pic.add(new void(picture f, transform3 t, transform3 T, triple lb,
+ triple rt) {
+ transform3 tinv=inverse(t);
+ triple a=xmin == -infinity ? tinv*(lb.x-min3(p).x,ytrans(t,y),
+ ztrans(t,z)) : (xmin,y,z);
+ triple b=xmax == infinity ? tinv*(rt.x-max3(p).x,ytrans(t,y),
+ ztrans(t,z)) : (xmax,y,z);
+ triple a2=xmin == -infinity ? tinv*(lb.x-min3(p).x,ytrans(t,y2),
+ ztrans(t,z2)) : (xmin,y2,z2);
+ triple b2=xmax == infinity ? tinv*(rt.x-max3(p).x,ytrans(t,y2),
+ ztrans(t,z2)) : (xmax,y2,z2);
+
+ if(xmin == -infinity || xmax == infinity) {
+ bounds mx=autoscale(a.x,b.x,pic.scale.x.scale);
+ pic.scale.x.tickMin=mx.min;
+ pic.scale.x.tickMax=mx.max;
+ divisor=mx.divisor;
+ }
+
+ triple fuzz=X*epsilon*max(abs(a.x),abs(b.x));
+ a -= fuzz;
+ b += fuzz;
+
+ picture d;
+ ticks(d,t,L,a--b,finite(y2) ? a2--b2 : nullpath3,p,arrow,margin,
+ ticklocate(a.x,b.x,pic.scale.x,Dir(dir)),divisor,
+ opposite,primary);
+ add(f,t*T*tinv*d);
+ },above=above);
+
+ void bounds() {
+ if(type == Min)
+ y=pic.scale.y.automin() ? tickMin3(pic).y : pic.userMin.y;
+ else if(type == Max)
+ y=pic.scale.y.automax() ? tickMax3(pic).y : pic.userMax.y;
+ else if(type == Both) {
+ y2=pic.scale.y.automax() ? tickMax3(pic).y : pic.userMax.y;
+ y=opposite ? y2 :
+ (pic.scale.y.automin() ? tickMin3(pic).y : pic.userMin.y);
+ }
+
+ if(type2 == Min)
+ z=pic.scale.z.automin() ? tickMin3(pic).z : pic.userMin.z;
+ else if(type2 == Max)
+ z=pic.scale.z.automax() ? tickMax3(pic).z : pic.userMax.z;
+ else if(type2 == Both) {
+ z2=pic.scale.z.automax() ? tickMax3(pic).z : pic.userMax.z;
+ z=opposite2 ? z2 :
+ (pic.scale.z.automin() ? tickMin3(pic).z : pic.userMin.z);
+ }
+
+ real Xmin=finite(xmin) ? xmin : pic.userMin.x;
+ real Xmax=finite(xmax) ? xmax : pic.userMax.x;
+
+ triple a=(Xmin,y,z);
+ triple b=(Xmax,y,z);
+ triple a2=(Xmin,y2,z2);
+ triple b2=(Xmax,y2,z2);
+
+ if(finite(a)) {
+ pic.addPoint(a,min3(p));
+ pic.addPoint(a,max3(p));
+ }
+
+ if(finite(b)) {
+ pic.addPoint(b,min3(p));
+ pic.addPoint(b,max3(p));
+ }
+
+ if(finite(a) && finite(b)) {
+ picture d;
+ ticks(d,pic.scaling3(warn=false),L,
+ (a.x,0,0)--(b.x,0,0),(a2.x,0,0)--(b2.x,0,0),p,arrow,margin,
+ ticklocate(a.x,b.x,pic.scale.x,Dir(dir)),divisor,
+ opposite,primary);
+ frame f;
+ if(L.s != "") {
+ Label L0=L.copy();
+ L0.position(0);
+ add(f,L0);
+ }
+ triple pos=a+L.relative()*(b-a);
+ triple m=min3(d);
+ triple M=max3(d);
+ pic.addBox(pos,pos,(min3(f).x,m.y,m.z),(max3(f).x,m.y,m.z));
+ }
+ }
+
+ // Process any queued y and z axes bound calculation requests.
+ for(int i=0; i < pic.scale.y.bound.length; ++i)
+ pic.scale.y.bound[i]();
+ for(int i=0; i < pic.scale.z.bound.length; ++i)
+ pic.scale.z.bound[i]();
+
+ pic.scale.y.bound.delete();
+ pic.scale.z.bound.delete();
+
+ bounds();
+
+ // Request another x bounds calculation before final picture scaling.
+ pic.scale.x.bound.push(bounds);
+}
+
+// An internal routine to draw an x axis at a particular y value.
+void yaxis3At(picture pic=currentpicture, Label L="", axis axis,
+ real ymin=-infinity, real ymax=infinity, pen p=currentpen,
+ ticks3 ticks=NoTicks3,
+ arrowbar3 arrow=None, margin3 margin=NoMargin3, bool above=true,
+ bool opposite=false, bool opposite2=false, bool primary=true)
+{
+ int type=axis.type;
+ int type2=axis.type2;
+ triple dir=axis.align.dir3 == O ?
+ defaultdir(X,Z,Y,opposite^opposite2,currentprojection) : axis.align.dir3;
+ Label L=L.copy();
+ if(L.align.dir3 == O && L.align.dir == 0) L.align(opposite ? -dir : dir);
+
+ real x=axis.value;
+ real z=axis.value2;
+ real x2,z2;
+ int[] divisor=copy(axis.ydivisor);
+
+ pic.add(new void(picture f, transform3 t, transform3 T, triple lb,
+ triple rt) {
+ transform3 tinv=inverse(t);
+ triple a=ymin == -infinity ? tinv*(xtrans(t,x),lb.y-min3(p).y,
+ ztrans(t,z)) : (x,ymin,z);
+ triple b=ymax == infinity ? tinv*(xtrans(t,x),rt.y-max3(p).y,
+ ztrans(t,z)) : (x,ymax,z);
+ triple a2=ymin == -infinity ? tinv*(xtrans(t,x2),lb.y-min3(p).y,
+ ztrans(t,z2)) : (x2,ymin,z2);
+ triple b2=ymax == infinity ? tinv*(xtrans(t,x2),rt.y-max3(p).y,
+ ztrans(t,z2)) : (x2,ymax,z2);
+
+ if(ymin == -infinity || ymax == infinity) {
+ bounds my=autoscale(a.y,b.y,pic.scale.y.scale);
+ pic.scale.y.tickMin=my.min;
+ pic.scale.y.tickMax=my.max;
+ divisor=my.divisor;
+ }
+
+ triple fuzz=Y*epsilon*max(abs(a.y),abs(b.y));
+ a -= fuzz;
+ b += fuzz;
+
+ picture d;
+ ticks(d,t,L,a--b,finite(x2) ? a2--b2 : nullpath3,p,arrow,margin,
+ ticklocate(a.y,b.y,pic.scale.y,Dir(dir)),divisor,
+ opposite,primary);
+ add(f,t*T*tinv*d);
+ },above=above);
+
+ void bounds() {
+ if(type == Min)
+ x=pic.scale.x.automin() ? tickMin3(pic).x : pic.userMin.x;
+ else if(type == Max)
+ x=pic.scale.x.automax() ? tickMax3(pic).x : pic.userMax.x;
+ else if(type == Both) {
+ x2=pic.scale.x.automax() ? tickMax3(pic).x : pic.userMax.x;
+ x=opposite ? x2 :
+ (pic.scale.x.automin() ? tickMin3(pic).x : pic.userMin.x);
+ }
+
+ if(type2 == Min)
+ z=pic.scale.z.automin() ? tickMin3(pic).z : pic.userMin.z;
+ else if(type2 == Max)
+ z=pic.scale.z.automax() ? tickMax3(pic).z : pic.userMax.z;
+ else if(type2 == Both) {
+ z2=pic.scale.z.automax() ? tickMax3(pic).z : pic.userMax.z;
+ z=opposite2 ? z2 :
+ (pic.scale.z.automin() ? tickMin3(pic).z : pic.userMin.z);
+ }
+
+ real Ymin=finite(ymin) ? ymin : pic.userMin.y;
+ real Ymax=finite(ymax) ? ymax : pic.userMax.y;
+
+ triple a=(x,Ymin,z);
+ triple b=(x,Ymax,z);
+ triple a2=(x2,Ymin,z2);
+ triple b2=(x2,Ymax,z2);
+
+ if(finite(a)) {
+ pic.addPoint(a,min3(p));
+ pic.addPoint(a,max3(p));
+ }
+
+ if(finite(b)) {
+ pic.addPoint(b,min3(p));
+ pic.addPoint(b,max3(p));
+ }
+
+ if(finite(a) && finite(b)) {
+ picture d;
+ ticks(d,pic.scaling3(warn=false),L,
+ (0,a.y,0)--(0,b.y,0),(0,a2.y,0)--(0,a2.y,0),p,arrow,margin,
+ ticklocate(a.y,b.y,pic.scale.y,Dir(dir)),divisor,
+ opposite,primary);
+ frame f;
+ if(L.s != "") {
+ Label L0=L.copy();
+ L0.position(0);
+ add(f,L0);
+ }
+ triple pos=a+L.relative()*(b-a);
+ triple m=min3(d);
+ triple M=max3(d);
+ pic.addBox(pos,pos,(m.x,min3(f).y,m.z),(m.x,max3(f).y,m.z));
+ }
+ }
+
+ // Process any queued x and z axis bound calculation requests.
+ for(int i=0; i < pic.scale.x.bound.length; ++i)
+ pic.scale.x.bound[i]();
+ for(int i=0; i < pic.scale.z.bound.length; ++i)
+ pic.scale.z.bound[i]();
+
+ pic.scale.x.bound.delete();
+ pic.scale.z.bound.delete();
+
+ bounds();
+
+ // Request another y bounds calculation before final picture scaling.
+ pic.scale.y.bound.push(bounds);
+}
+
+// An internal routine to draw an x axis at a particular y value.
+void zaxis3At(picture pic=currentpicture, Label L="", axis axis,
+ real zmin=-infinity, real zmax=infinity, pen p=currentpen,
+ ticks3 ticks=NoTicks3,
+ arrowbar3 arrow=None, margin3 margin=NoMargin3, bool above=true,
+ bool opposite=false, bool opposite2=false, bool primary=true)
+{
+ int type=axis.type;
+ int type2=axis.type2;
+ triple dir=axis.align.dir3 == O ?
+ defaultdir(X,Y,Z,opposite^opposite2,currentprojection) : axis.align.dir3;
+ Label L=L.copy();
+ if(L.align.dir3 == O && L.align.dir == 0) L.align(opposite ? -dir : dir);
+
+ real x=axis.value;
+ real y=axis.value2;
+ real x2,y2;
+ int[] divisor=copy(axis.zdivisor);
+
+ pic.add(new void(picture f, transform3 t, transform3 T, triple lb,
+ triple rt) {
+ transform3 tinv=inverse(t);
+ triple a=zmin == -infinity ? tinv*(xtrans(t,x),ytrans(t,y),
+ lb.z-min3(p).z) : (x,y,zmin);
+ triple b=zmax == infinity ? tinv*(xtrans(t,x),ytrans(t,y),
+ rt.z-max3(p).z) : (x,y,zmax);
+ triple a2=zmin == -infinity ? tinv*(xtrans(t,x2),ytrans(t,y2),
+ lb.z-min3(p).z) : (x2,y2,zmin);
+ triple b2=zmax == infinity ? tinv*(xtrans(t,x2),ytrans(t,y2),
+ rt.z-max3(p).z) : (x2,y2,zmax);
+
+ if(zmin == -infinity || zmax == infinity) {
+ bounds mz=autoscale(a.z,b.z,pic.scale.z.scale);
+ pic.scale.z.tickMin=mz.min;
+ pic.scale.z.tickMax=mz.max;
+ divisor=mz.divisor;
+ }
+
+ triple fuzz=Z*epsilon*max(abs(a.z),abs(b.z));
+ a -= fuzz;
+ b += fuzz;
+
+ picture d;
+ ticks(d,t,L,a--b,finite(x2) ? a2--b2 : nullpath3,p,arrow,margin,
+ ticklocate(a.z,b.z,pic.scale.z,Dir(dir)),divisor,
+ opposite,primary);
+ add(f,t*T*tinv*d);
+ },above=above);
+
+ void bounds() {
+ if(type == Min)
+ x=pic.scale.x.automin() ? tickMin3(pic).x : pic.userMin.x;
+ else if(type == Max)
+ x=pic.scale.x.automax() ? tickMax3(pic).x : pic.userMax.x;
+ else if(type == Both) {
+ x2=pic.scale.x.automax() ? tickMax3(pic).x : pic.userMax.x;
+ x=opposite ? x2 :
+ (pic.scale.x.automin() ? tickMin3(pic).x : pic.userMin.x);
+ }
+
+ if(type2 == Min)
+ y=pic.scale.y.automin() ? tickMin3(pic).y : pic.userMin.y;
+ else if(type2 == Max)
+ y=pic.scale.y.automax() ? tickMax3(pic).y : pic.userMax.y;
+ else if(type2 == Both) {
+ y2=pic.scale.y.automax() ? tickMax3(pic).y : pic.userMax.y;
+ y=opposite2 ? y2 :
+ (pic.scale.y.automin() ? tickMin3(pic).y : pic.userMin.y);
+ }
+
+ real Zmin=finite(zmin) ? zmin : pic.userMin.z;
+ real Zmax=finite(zmax) ? zmax : pic.userMax.z;
+
+ triple a=(x,y,Zmin);
+ triple b=(x,y,Zmax);
+ triple a2=(x2,y2,Zmin);
+ triple b2=(x2,y2,Zmax);
+
+ if(finite(a)) {
+ pic.addPoint(a,min3(p));
+ pic.addPoint(a,max3(p));
+ }
+
+ if(finite(b)) {
+ pic.addPoint(b,min3(p));
+ pic.addPoint(b,max3(p));
+ }
+
+ if(finite(a) && finite(b)) {
+ picture d;
+ ticks(d,pic.scaling3(warn=false),L,
+ (0,0,a.z)--(0,0,b.z),(0,0,a2.z)--(0,0,a2.z),p,arrow,margin,
+ ticklocate(a.z,b.z,pic.scale.z,Dir(dir)),divisor,
+ opposite,primary);
+ frame f;
+ if(L.s != "") {
+ Label L0=L.copy();
+ L0.position(0);
+ add(f,L0);
+ }
+ triple pos=a+L.relative()*(b-a);
+ triple m=min3(d);
+ triple M=max3(d);
+ pic.addBox(pos,pos,(m.x,m.y,min3(f).z),(m.x,m.y,max3(f).z));
+ }
+ }
+
+ // Process any queued x and y axes bound calculation requests.
+ for(int i=0; i < pic.scale.x.bound.length; ++i)
+ pic.scale.x.bound[i]();
+ for(int i=0; i < pic.scale.y.bound.length; ++i)
+ pic.scale.y.bound[i]();
+
+ pic.scale.x.bound.delete();
+ pic.scale.y.bound.delete();
+
+ bounds();
+
+ // Request another z bounds calculation before final picture scaling.
+ pic.scale.z.bound.push(bounds);
+}
+
+// Internal routine to autoscale the user limits of a picture.
+void autoscale3(picture pic=currentpicture, axis axis)
+{
+ bool set=pic.scale.set;
+ autoscale(pic,axis);
+
+ if(!set) {
+ bounds mz;
+ if(pic.userSetz) {
+ mz=autoscale(pic.userMin.z,pic.userMax.z,pic.scale.z.scale);
+ if(pic.scale.z.scale.logarithmic &&
+ floor(pic.userMin.z) == floor(pic.userMax.z)) {
+ if(pic.scale.z.automin())
+ pic.userMinz(floor(pic.userMin.z));
+ if(pic.scale.z.automax())
+ pic.userMaxz(ceil(pic.userMax.z));
+ }
+ } else {mz.min=mz.max=0; pic.scale.set=false;}
+
+ pic.scale.z.tickMin=mz.min;
+ pic.scale.z.tickMax=mz.max;
+ axis.zdivisor=mz.divisor;
+ }
+}
+
+// Draw an x axis in three dimensions.
+void xaxis3(picture pic=currentpicture, Label L="", axis axis=YZZero,
+ real xmin=-infinity, real xmax=infinity, pen p=currentpen,
+ ticks3 ticks=NoTicks3,
+ arrowbar3 arrow=None, margin3 margin=NoMargin3, bool above=false)
+{
+ if(xmin > xmax) return;
+
+ if(pic.scale.x.automin && xmin > -infinity) pic.scale.x.automin=false;
+ if(pic.scale.x.automax && xmax < infinity) pic.scale.x.automax=false;
+
+ if(!pic.scale.set) {
+ axis(pic,axis);
+ autoscale3(pic,axis);
+ }
+
+ bool newticks=false;
+
+ if(xmin != -infinity) {
+ xmin=pic.scale.x.T(xmin);
+ newticks=true;
+ }
+
+ if(xmax != infinity) {
+ xmax=pic.scale.x.T(xmax);
+ newticks=true;
+ }
+
+ if(newticks && pic.userSetx && ticks != NoTicks3) {
+ if(xmin == -infinity) xmin=pic.userMin.x;
+ if(xmax == infinity) xmax=pic.userMax.x;
+ bounds mx=autoscale(xmin,xmax,pic.scale.x.scale);
+ pic.scale.x.tickMin=mx.min;
+ pic.scale.x.tickMax=mx.max;
+ axis.xdivisor=mx.divisor;
+ }
+
+ axis(pic,axis);
+
+ if(xmin == -infinity && !axis.extend) {
+ if(pic.scale.set)
+ xmin=pic.scale.x.automin() ? pic.scale.x.tickMin :
+ max(pic.scale.x.tickMin,pic.userMin.x);
+ else xmin=pic.userMin.x;
+ }
+
+ if(xmax == infinity && !axis.extend) {
+ if(pic.scale.set)
+ xmax=pic.scale.x.automax() ? pic.scale.x.tickMax :
+ min(pic.scale.x.tickMax,pic.userMax.x);
+ else xmax=pic.userMax.x;
+ }
+
+ if(L.defaultposition) {
+ L=L.copy();
+ L.position(axis.position);
+ }
+
+ bool back=false;
+ if(axis.type == Both) {
+ triple v=currentprojection.vector();
+ back=dot((0,pic.userMax.y-pic.userMin.y,0),v)*sgn(v.z) > 0;
+ }
+
+ xaxis3At(pic,L,axis,xmin,xmax,p,ticks,arrow,margin,above,false,false,!back);
+ if(axis.type == Both)
+ xaxis3At(pic,L,axis,xmin,xmax,p,ticks,arrow,margin,above,true,false,back);
+ if(axis.type2 == Both) {
+ xaxis3At(pic,L,axis,xmin,xmax,p,ticks,arrow,margin,above,false,true,false);
+ if(axis.type == Both)
+ xaxis3At(pic,L,axis,xmin,xmax,p,ticks,arrow,margin,above,true,true,false);
+ }
+}
+
+// Draw a y axis in three dimensions.
+void yaxis3(picture pic=currentpicture, Label L="", axis axis=XZZero,
+ real ymin=-infinity, real ymax=infinity, pen p=currentpen,
+ ticks3 ticks=NoTicks3,
+ arrowbar3 arrow=None, margin3 margin=NoMargin3, bool above=false)
+{
+ if(ymin > ymax) return;
+
+ if(pic.scale.y.automin && ymin > -infinity) pic.scale.y.automin=false;
+ if(pic.scale.y.automax && ymax < infinity) pic.scale.y.automax=false;
+
+ if(!pic.scale.set) {
+ axis(pic,axis);
+ autoscale3(pic,axis);
+ }
+
+ bool newticks=false;
+
+ if(ymin != -infinity) {
+ ymin=pic.scale.y.T(ymin);
+ newticks=true;
+ }
+
+ if(ymax != infinity) {
+ ymax=pic.scale.y.T(ymax);
+ newticks=true;
+ }
+
+ if(newticks && pic.userSety && ticks != NoTicks3) {
+ if(ymin == -infinity) ymin=pic.userMin.y;
+ if(ymax == infinity) ymax=pic.userMax.y;
+ bounds my=autoscale(ymin,ymax,pic.scale.y.scale);
+ pic.scale.y.tickMin=my.min;
+ pic.scale.y.tickMax=my.max;
+ axis.ydivisor=my.divisor;
+ }
+
+ axis(pic,axis);
+
+ if(ymin == -infinity && !axis.extend) {
+ if(pic.scale.set)
+ ymin=pic.scale.y.automin() ? pic.scale.y.tickMin :
+ max(pic.scale.y.tickMin,pic.userMin.y);
+ else ymin=pic.userMin.y;
+ }
+
+
+ if(ymax == infinity && !axis.extend) {
+ if(pic.scale.set)
+ ymax=pic.scale.y.automax() ? pic.scale.y.tickMax :
+ min(pic.scale.y.tickMax,pic.userMax.y);
+ else ymax=pic.userMax.y;
+ }
+
+ if(L.defaultposition) {
+ L=L.copy();
+ L.position(axis.position);
+ }
+
+ bool back=false;
+ if(axis.type == Both) {
+ triple v=currentprojection.vector();
+ back=dot((pic.userMax.x-pic.userMin.x,0,0),v)*sgn(v.z) > 0;
+ }
+
+ yaxis3At(pic,L,axis,ymin,ymax,p,ticks,arrow,margin,above,false,false,!back);
+
+ if(axis.type == Both)
+ yaxis3At(pic,L,axis,ymin,ymax,p,ticks,arrow,margin,above,true,false,back);
+ if(axis.type2 == Both) {
+ yaxis3At(pic,L,axis,ymin,ymax,p,ticks,arrow,margin,above,false,true,false);
+ if(axis.type == Both)
+ yaxis3At(pic,L,axis,ymin,ymax,p,ticks,arrow,margin,above,true,true,false);
+ }
+}
+// Draw a z axis in three dimensions.
+void zaxis3(picture pic=currentpicture, Label L="", axis axis=XYZero,
+ real zmin=-infinity, real zmax=infinity, pen p=currentpen,
+ ticks3 ticks=NoTicks3,
+ arrowbar3 arrow=None, margin3 margin=NoMargin3, bool above=false)
+{
+ if(zmin > zmax) return;
+
+ if(pic.scale.z.automin && zmin > -infinity) pic.scale.z.automin=false;
+ if(pic.scale.z.automax && zmax < infinity) pic.scale.z.automax=false;
+
+ if(!pic.scale.set) {
+ axis(pic,axis);
+ autoscale3(pic,axis);
+ }
+
+ bool newticks=false;
+
+ if(zmin != -infinity) {
+ zmin=pic.scale.z.T(zmin);
+ newticks=true;
+ }
+
+ if(zmax != infinity) {
+ zmax=pic.scale.z.T(zmax);
+ newticks=true;
+ }
+
+ if(newticks && pic.userSetz && ticks != NoTicks3) {
+ if(zmin == -infinity) zmin=pic.userMin.z;
+ if(zmax == infinity) zmax=pic.userMax.z;
+ bounds mz=autoscale(zmin,zmax,pic.scale.z.scale);
+ pic.scale.z.tickMin=mz.min;
+ pic.scale.z.tickMax=mz.max;
+ axis.zdivisor=mz.divisor;
+ }
+
+ axis(pic,axis);
+
+ if(zmin == -infinity && !axis.extend) {
+ if(pic.scale.set)
+ zmin=pic.scale.z.automin() ? pic.scale.z.tickMin :
+ max(pic.scale.z.tickMin,pic.userMin.z);
+ else zmin=pic.userMin.z;
+ }
+
+ if(zmax == infinity && !axis.extend) {
+ if(pic.scale.set)
+ zmax=pic.scale.z.automax() ? pic.scale.z.tickMax :
+ min(pic.scale.z.tickMax,pic.userMax.z);
+ else zmax=pic.userMax.z;
+ }
+
+ if(L.defaultposition) {
+ L=L.copy();
+ L.position(axis.position);
+ }
+
+ bool back=false;
+ if(axis.type == Both) {
+ triple v=currentprojection.vector();
+ back=dot((pic.userMax.x-pic.userMin.x,0,0),v)*sgn(v.y) > 0;
+ }
+
+ zaxis3At(pic,L,axis,zmin,zmax,p,ticks,arrow,margin,above,false,false,!back);
+ if(axis.type == Both)
+ zaxis3At(pic,L,axis,zmin,zmax,p,ticks,arrow,margin,above,true,false,back);
+ if(axis.type2 == Both) {
+ zaxis3At(pic,L,axis,zmin,zmax,p,ticks,arrow,margin,above,false,true,false);
+ if(axis.type == Both)
+ zaxis3At(pic,L,axis,zmin,zmax,p,ticks,arrow,margin,above,true,true,false);
+ }
+}
+
+// Set the z limits of a picture.
+void zlimits(picture pic=currentpicture, real min=-infinity, real max=infinity,
+ bool crop=NoCrop)
+{
+ if(min > max) return;
+
+ pic.scale.z.automin=min <= -infinity;
+ pic.scale.z.automax=max >= infinity;
+
+ bounds mz;
+ if(pic.scale.z.automin() || pic.scale.z.automax())
+ mz=autoscale(pic.userMin.z,pic.userMax.z,pic.scale.z.scale);
+
+ if(pic.scale.z.automin) {
+ if(pic.scale.z.automin()) pic.userMinz(mz.min);
+ } else pic.userMinz(pic.scale.z.T(min));
+
+ if(pic.scale.z.automax) {
+ if(pic.scale.z.automax()) pic.userMaxz(mz.max);
+ } else pic.userMaxz(pic.scale.z.T(max));
+}
+
+// Restrict the x, y, and z limits to box(min,max).
+void limits(picture pic=currentpicture, triple min, triple max)
+{
+ xlimits(pic,min.x,max.x);
+ ylimits(pic,min.y,max.y);
+ zlimits(pic,min.z,max.z);
+}
+
+// Draw x, y and z axes.
+void axes3(picture pic=currentpicture,
+ Label xlabel="", Label ylabel="", Label zlabel="",
+ triple min=(-infinity,-infinity,-infinity),
+ triple max=(infinity,infinity,infinity),
+ pen p=currentpen, arrowbar3 arrow=None, margin3 margin=NoMargin3)
+{
+ xaxis3(pic,xlabel,min.x,max.x,p,arrow,margin);
+ yaxis3(pic,ylabel,min.y,max.y,p,arrow,margin);
+ zaxis3(pic,zlabel,min.z,max.z,p,arrow,margin);
+}
+
+triple Scale(picture pic=currentpicture, triple v)
+{
+ return (pic.scale.x.T(v.x),pic.scale.y.T(v.y),pic.scale.z.T(v.z));
+}
+
+real ScaleZ(picture pic=currentpicture, real z)
+{
+ return pic.scale.z.T(z);
+}
+
+// Draw a tick of length size at triple v in direction dir using pen p.
+void tick(picture pic=currentpicture, triple v, triple dir, real size=Ticksize,
+ pen p=currentpen)
+{
+ pic.add(new void (picture f, transform3 t) {
+ triple tv=t*v;
+ draw(f,tv--tv+unit(dir)*size,p);
+ });
+ pic.addPoint(v,p);
+ pic.addPoint(v,unit(dir)*size,p);
+}
+
+void xtick(picture pic=currentpicture, triple v, triple dir=Y,
+ real size=Ticksize, pen p=currentpen)
+{
+ tick(pic,Scale(pic,v),dir,size,p);
+}
+
+void xtick3(picture pic=currentpicture, real x, triple dir=Y,
+ real size=Ticksize, pen p=currentpen)
+{
+ xtick(pic,(x,pic.scale.y.scale.logarithmic ? 1 : 0,
+ pic.scale.z.scale.logarithmic ? 1 : 0),dir,size,p);
+}
+
+void ytick(picture pic=currentpicture, triple v, triple dir=X,
+ real size=Ticksize, pen p=currentpen)
+{
+ xtick(pic,v,dir,size,p);
+}
+
+void ytick(picture pic=currentpicture, real y, triple dir=X,
+ real size=Ticksize, pen p=currentpen)
+{
+ xtick(pic,(pic.scale.x.scale.logarithmic ? 1 : 0,y,
+ pic.scale.z.scale.logarithmic ? 1 : 0),dir,size,p);
+}
+
+void ztick(picture pic=currentpicture, triple v, triple dir=X,
+ real size=Ticksize, pen p=currentpen)
+{
+ xtick(pic,v,dir,size,p);
+}
+
+void ztick(picture pic=currentpicture, real z, triple dir=X,
+ real size=Ticksize, pen p=currentpen)
+{
+ xtick(pic,(pic.scale.x.scale.logarithmic ? 1 : 0,
+ pic.scale.y.scale.logarithmic ? 1 : 0,z),dir,size,p);
+}
+
+void tick(picture pic=currentpicture, Label L, real value, triple v,
+ triple dir, string format="", real size=Ticksize, pen p=currentpen)
+{
+ Label L=L.copy();
+ L.align(L.align,-dir);
+ if(shift(L.T3)*O == O) {
+ L.T3=shift(dot(dir,L.align.dir3) > 0 ? dir*size :
+ ticklabelshift(L.align.dir3,p))*L.T3;
+ }
+ L.p(p);
+ if(L.s == "") L.s=format(format == "" ? defaultformat : format,value);
+ L.s=baseline(L.s,baselinetemplate);
+ label(pic,L,v);
+ xtick(pic,v,dir,size,p);
+}
+
+void xtick(picture pic=currentpicture, Label L, triple v, triple dir=Y,
+ string format="", real size=Ticksize, pen p=currentpen)
+{
+ tick(pic,L,v.x,v,dir,format,size,p);
+}
+
+void xtick3(picture pic=currentpicture, Label L, real x, triple dir=Y,
+ string format="", real size=Ticksize, pen p=currentpen)
+{
+ xtick(pic,L,(x,pic.scale.y.scale.logarithmic ? 1 : 0,
+ pic.scale.z.scale.logarithmic ? 1 : 0),dir,size,p);
+}
+
+void ytick(picture pic=currentpicture, Label L, triple v, triple dir=X,
+ string format="", real size=Ticksize, pen p=currentpen)
+{
+ tick(pic,L,v.y,v,dir,format,size,p);
+}
+
+void ytick3(picture pic=currentpicture, Label L, real y, triple dir=X,
+ string format="", real size=Ticksize, pen p=currentpen)
+{
+ ytick(pic,L,(pic.scale.x.scale.logarithmic ? 1 : 0,y,
+ pic.scale.z.scale.logarithmic ? 1 : 0),dir,format,size,p);
+}
+
+void ztick(picture pic=currentpicture, Label L, triple v, triple dir=X,
+ string format="", real size=Ticksize, pen p=currentpen)
+{
+ tick(pic,L,v.z,v,dir,format,size,p);
+}
+
+void ztick3(picture pic=currentpicture, Label L, real z, triple dir=X,
+ string format="", real size=Ticksize, pen p=currentpen)
+{
+ ztick(pic,L,(pic.scale.x.scale.logarithmic ? 1 : 0,
+ pic.scale.z.scale.logarithmic ? 1 : 0,z),dir,format,size,p);
+}
+
+private void label(picture pic, Label L, triple v, real x, align align,
+ string format, pen p)
+{
+ Label L=L.copy();
+ L.align(align);
+ L.p(p);
+ if(shift(L.T3)*O == O)
+ L.T3=shift(ticklabelshift(L.align.dir3,L.p))*L.T3;
+ if(L.s == "") L.s=format(format == "" ? defaultformat : format,x);
+ L.s=baseline(L.s,baselinetemplate);
+ label(pic,L,v);
+}
+
+void labelx(picture pic=currentpicture, Label L="", triple v,
+ align align=-Y, string format="", pen p=nullpen)
+{
+ label(pic,L,Scale(pic,v),v.x,align,format,p);
+}
+
+void labelx3(picture pic=currentpicture, Label L="", real x,
+ align align=-Y, string format="", pen p=nullpen)
+{
+ labelx(pic,L,(x,pic.scale.y.scale.logarithmic ? 1 : 0,
+ pic.scale.z.scale.logarithmic ? 1 : 0),align,format,p);
+}
+
+void labely(picture pic=currentpicture, Label L="", triple v,
+ align align=-X, string format="", pen p=nullpen)
+{
+ label(pic,L,Scale(pic,v),v.y,align,format,p);
+}
+
+void labely3(picture pic=currentpicture, Label L="", real y,
+ align align=-X, string format="", pen p=nullpen)
+{
+ labely(pic,L,(pic.scale.x.scale.logarithmic ? 1 : 0,y,
+ pic.scale.z.scale.logarithmic ? 1 : 0),align,format,p);
+}
+
+void labelz(picture pic=currentpicture, Label L="", triple v,
+ align align=-X, string format="", pen p=nullpen)
+{
+ label(pic,L,Scale(pic,v),v.z,align,format,p);
+}
+
+void labelz3(picture pic=currentpicture, Label L="", real z,
+ align align=-X, string format="", pen p=nullpen)
+{
+ labelz(pic,L,(pic.scale.x.scale.logarithmic ? 1 : 0,
+ pic.scale.y.scale.logarithmic ? 1 : 0,z),align,format,p);
+}
+
+typedef guide3 graph(triple F(real), real, real, int);
+typedef guide3[] multigraph(triple F(real), real, real, int);
+
+graph graph(interpolate3 join)
+{
+ return new guide3(triple f(real), real a, real b, int n) {
+ real width=b-a;
+ return n == 0 ? join(f(a)) :
+ join(...sequence(new guide3(int i) {return f(a+(i/n)*width);},n+1));
+ };
+}
+
+multigraph graph(interpolate3 join, bool3 cond(real))
+{
+ return new guide3[](triple f(real), real a, real b, int n) {
+ real width=b-a;
+ if(n == 0) return new guide3[] {join(cond(a) ? f(a) : nullpath3)};
+ guide3[] G;
+ guide3[] g;
+ for(int i=0; i < n+1; ++i) {
+ real t=a+(i/n)*width;
+ bool3 b=cond(t);
+ if(b)
+ g.push(f(t));
+ else {
+ if(g.length > 0) {
+ G.push(join(...g));
+ g=new guide3[] {};
+ }
+ if(b == default)
+ g.push(f(t));
+ }
+ }
+ if(g.length > 0)
+ G.push(join(...g));
+ return G;
+ };
+}
+
+guide3 Straight(... guide3[])=operator --;
+guide3 Spline(... guide3[])=operator ..;
+
+guide3 graph(picture pic=currentpicture, real x(real), real y(real),
+ real z(real), real a, real b, int n=ngraph,
+ interpolate3 join=operator --)
+{
+ return graph(join)(new triple(real t) {return Scale(pic,(x(t),y(t),z(t)));},
+ a,b,n);
+}
+
+guide3[] graph(picture pic=currentpicture, real x(real), real y(real),
+ real z(real), real a, real b, int n=ngraph,
+ bool3 cond(real), interpolate3 join=operator --)
+{
+ return graph(join,cond)(new triple(real t) {
+ return Scale(pic,(x(t),y(t),z(t)));
+ },a,b,n);
+}
+
+guide3 graph(picture pic=currentpicture, triple v(real), real a, real b,
+ int n=ngraph, interpolate3 join=operator --)
+{
+ return graph(join)(new triple(real t) {return Scale(pic,v(t));},a,b,n);
+}
+
+guide3[] graph(picture pic=currentpicture, triple v(real), real a, real b,
+ int n=ngraph, bool3 cond(real), interpolate3 join=operator --)
+{
+ return graph(join,cond)(new triple(real t) {
+ return Scale(pic,v(t));
+ },a,b,n);
+}
+
+guide3 graph(picture pic=currentpicture, triple[] v,
+ interpolate3 join=operator --)
+{
+ int i=0;
+ return graph(join)(new triple(real) {
+ triple w=Scale(pic,v[i]);
+ ++i;
+ return w;
+ },0,0,v.length-1);
+}
+
+guide3[] graph(picture pic=currentpicture, triple[] v, bool3[] cond,
+ interpolate3 join=operator --)
+{
+ int n=v.length;
+ int i=0;
+ triple w;
+ checkconditionlength(cond.length,n);
+ bool3 condition(real) {
+ bool b=cond[i];
+ if(b) w=Scale(pic,v[i]);
+ ++i;
+ return b;
+ }
+ return graph(join,condition)(new triple(real) {return w;},0,0,n-1);
+}
+
+guide3 graph(picture pic=currentpicture, real[] x, real[] y, real[] z,
+ interpolate3 join=operator --)
+{
+ int n=x.length;
+ checklengths(n,y.length);
+ checklengths(n,z.length);
+ int i=0;
+ return graph(join)(new triple(real) {
+ triple w=Scale(pic,(x[i],y[i],z[i]));
+ ++i;
+ return w;
+ },0,0,n-1);
+}
+
+guide3[] graph(picture pic=currentpicture, real[] x, real[] y, real[] z,
+ bool3[] cond, interpolate3 join=operator --)
+{
+ int n=x.length;
+ checklengths(n,y.length);
+ checklengths(n,z.length);
+ int i=0;
+ triple w;
+ checkconditionlength(cond.length,n);
+ bool3 condition(real) {
+ bool3 b=cond[i];
+ if(b != false) w=Scale(pic,(x[i],y[i],z[i]));
+ ++i;
+ return b;
+ }
+ return graph(join,condition)(new triple(real) {return w;},0,0,n-1);
+}
+
+// The graph of a function along a path.
+guide3 graph(triple F(path, real), path p, int n=1,
+ interpolate3 join=operator --)
+{
+ guide3 g=join(...sequence(new guide3(int i) {
+ return F(p,i/n);
+ },n*length(p)));
+ return cyclic(p) ? join(g,cycle) : join(g,F(p,length(p)));
+}
+
+guide3 graph(triple F(pair), path p, int n=1, interpolate3 join=operator --)
+{
+ return graph(new triple(path p, real position)
+ {return F(point(p,position));},p,n,join);
+}
+
+guide3 graph(picture pic=currentpicture, real f(pair), path p, int n=1,
+ interpolate3 join=operator --)
+{
+ return graph(new triple(pair z) {return Scale(pic,(z.x,z.y,f(z)));},p,n,
+ join);
+}
+
+guide3 graph(real f(pair), path p, int n=1, real T(pair),
+ interpolate3 join=operator --)
+{
+ return graph(new triple(pair z) {pair w=T(z); return (w.x,w.y,f(w));},p,n,
+ join);
+}
+
+// Connect points in v into segments corresponding to consecutive true elements
+// of b using interpolation operator join.
+path3[] segment(triple[] v, bool[] cond, interpolate3 join=operator --)
+{
+ checkconditionlength(cond.length,v.length);
+ int[][] segment=segment(cond);
+ return sequence(new path3(int i) {return join(...v[segment[i]]);},
+ segment.length);
+}
+
+// return the surface described by a matrix f
+surface surface(triple[][] f, bool[][] cond={})
+{
+ if(!rectangular(f)) abort("matrix is not rectangular");
+
+ int nx=f.length-1;
+ int ny=nx > 0 ? f[0].length-1 : 0;
+
+ bool all=cond.length == 0;
+
+ int count;
+ if(all)
+ count=nx*ny;
+ else {
+ count=0;
+ for(int i=0; i < nx; ++i) {
+ bool[] condi=cond[i];
+ bool[] condp=cond[i+1];
+ for(int j=0; j < ny; ++j)
+ if(condi[j] && condi[j+1] && condp[j] && condp[j+1]) ++count;
+ }
+ }
+
+ surface s=surface(count);
+ int k=-1;
+ for(int i=0; i < nx; ++i) {
+ bool[] condi,condp;
+ if(!all) {
+ condi=cond[i];
+ condp=cond[i+1];
+ }
+ triple[] fi=f[i];
+ triple[] fp=f[i+1];
+ for(int j=0; j < ny; ++j) {
+ if(all || (condi[j] && condi[j+1] && condp[j] && condp[j+1]))
+ s.s[++k]=patch(new triple[] {fi[j],fp[j],fp[j+1],fi[j+1]});
+ }
+ }
+ return s;
+}
+
+private surface bispline(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];
+ for(int j=0; j < m; ++j)
+ if(condi[j]) ++count;
+ }
+ }
+
+ surface g=surface(count);
+ int k=-1;
+ for(int i=0; i < n; ++i) {
+ bool[] condi=all ? null : cond[i];
+ real xi=x[i];
+ real[] zi=z[i];
+ real[] zp=z[i+1];
+ real[] ri=r[i];
+ real[] rp=r[i+1];
+ real[] pi=p[i];
+ real[] pp=p[i+1];
+ real[] qi=q[i];
+ real[] qp=q[i+1];
+ real xp=x[i+1];
+ real hx=(xp-xi)/3;
+ for(int j=0; j < m; ++j) {
+ real yj=y[j];
+ real yp=y[j+1];
+ if(all || condi[j]) {
+ triple[][] P={
+ {O,O,O,O},
+ {O,O,O,O},
+ {O,O,O,O},
+ {O,O,O,O}};
+ real hy=(yp-yj)/3;
+ real hxy=hx*hy;
+ // first x and y directions
+ for(int k=0 ; k < 4 ; ++k) {
+ P[k][0] += xi*X;
+ P[0][k] += yj*Y;
+ P[k][1] += (xp+2*xi)/3*X;
+ P[1][k] += (yp+2*yj)/3*Y;
+ P[k][2] += (2*xp+xi)/3*X;
+ P[2][k] += (2*yp+yj)/3*Y;
+ P[k][3] += xp*X;
+ P[3][k] += yp*Y;
+ }
+ // now z, first the value
+ P[0][0] += zi[j]*Z;
+ P[0][3] += zp[j]*Z;
+ P[3][0] += zi[j+1]*Z;
+ P[3][3] += zp[j+1]*Z;
+ // 2nd, first derivative
+ P[0][1] += (P[0][0].z+hx*pi[j])*Z;
+ P[3][1] += (P[3][0].z+hx*pi[j+1])*Z;
+ P[0][2] += (P[0][3].z-hx*pp[j])*Z;
+ P[3][2] += (P[3][3].z-hx*pp[j+1])*Z;
+ P[1][0] += (P[0][0].z+hy*qi[j])*Z;
+ P[1][3] += (P[0][3].z+hy*qp[j])*Z;
+ P[2][0] += (P[3][0].z-hy*qi[j+1])*Z;
+ P[2][3] += (P[3][3].z-hy*qp[j+1])*Z;
+ // 3nd, second derivative
+ P[1][1] += (P[1][0].z+P[0][1].z-P[0][0].z+hxy*ri[j])*Z;
+ P[2][1] += (P[2][0].z+P[3][1].z-P[3][0].z-hxy*ri[j+1])*Z;
+ P[1][2] += (P[0][2].z+P[1][3].z-P[0][3].z-hxy*rp[j])*Z;
+ P[2][2] += (P[3][2].z+P[2][3].z-P[3][3].z+hxy*rp[j+1])*Z;
+ g.s[++k]=patch(P);
+ }
+ }
+ }
+ return g;
+}
+
+// return the surface described by a real matrix f, interpolated with
+// splinetype.
+surface surface(real[][] f, real[] x, real[] y,
+ splinetype splinetype=null, bool[][] cond={})
+{
+ if(splinetype == null)
+ splinetype=(x[0] == x[x.length-1] && y[0] == y[y.length-1]) ?
+ 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]=splinetype(x,ft[j]);
+ real[][] q=new real[n][];
+ for(int i=0; i < n ; ++i)
+ q[i]=splinetype(y,f[i]);
+ real[][] qt=transpose(q);
+ real[] d1=splinetype(x,qt[0]);
+ real[] d2=splinetype(x,qt[m-1]);
+ real[][] r=new real[n][];
+ for(int i=0; i < n ; ++i)
+ r[i]=clamped(d1[i],d2[i])(y,f[i]);
+ return bispline(f,transpose(tp),q,r,x,y,cond);
+}
+
+// return the surface described by a real matrix f, interpolated with
+// splinetype.
+surface surface(real[][] f, pair a, pair b, splinetype splinetype,
+ bool[][] cond={})
+{
+ if(!rectangular(f)) abort("matrix is not rectangular");
+
+ int nx=f.length-1;
+ int ny=nx > 0 ? f[0].length-1 : 0;
+
+ if(nx == 0 || ny == 0) return nullsurface;
+
+ real[] x=uniform(a.x,b.x,nx);
+ real[] y=uniform(a.y,b.y,ny);
+ return surface(f,x,y,splinetype,cond);
+}
+
+// return the surface described by a real matrix f, interpolated linearly.
+surface surface(real[][] f, pair a, pair b, bool[][] cond={})
+{
+ if(!rectangular(f)) abort("matrix is not rectangular");
+
+ int nx=f.length-1;
+ int ny=nx > 0 ? f[0].length-1 : 0;
+
+ if(nx == 0 || ny == 0) return nullsurface;
+
+ bool all=cond.length == 0;
+
+ triple[][] v=new triple[nx+1][ny+1];
+ for(int i=0; i <= nx; ++i) {
+ real x=interp(a.x,b.x,i/nx);
+ bool[] condi=all ? null : cond[i];
+ triple[] vi=v[i];
+ real[] fi=f[i];
+ for(int j=0; j <= ny; ++j)
+ if(all || condi[j])
+ vi[j]=(x,interp(a.y,b.y,j/ny),fi[j]);
+ }
+ return surface(v,cond);
+}
+
+// return the surface described by a parametric function f over box(a,b),
+// interpolated linearly.
+surface surface(triple f(pair z), pair a, pair b, int nu=nmesh, int nv=nu,
+ bool cond(pair z)=null)
+{
+ if(nu <= 0 || nv <= 0) return nullsurface;
+
+ bool[][] active;
+ bool all=cond == null;
+ if(!all) active=new bool[nu+1][nv+1];
+
+ real du=1/nu;
+ real dv=1/nv;
+ pair Idv=(0,dv);
+ pair dz=(du,dv);
+
+ triple[][] v=new triple[nu+1][nv+1];
+
+ for(int i=0; i <= nu; ++i) {
+ real x=interp(a.x,b.x,i*du);
+ bool[] activei=all ? null : active[i];
+ triple[] vi=v[i];
+ for(int j=0; j <= nv; ++j) {
+ pair z=(x,interp(a.y,b.y,j*dv));
+ if(all || (activei[j]=cond(z))) vi[j]=f(z);
+ }
+ }
+ return surface(v,active);
+}
+
+// return the surface described by a real function f over box(a,b),
+// interpolated linearly.
+surface surface(real f(pair z), pair a, pair b, int nx=nmesh, int ny=nx,
+ bool cond(pair z)=null)
+{
+ return surface(new triple(pair z) {return (z.x,z.y,f(z));},a,b,nx,ny,cond);
+}
+
+// return the surface described by a real function f over box(a,b),
+// interpolated with splinetype.
+surface surface(real f(pair z), pair a, pair b, int nx=nmesh, int ny=nx,
+ splinetype splinetype, bool cond(pair z)=null)
+{
+ bool[][] active;
+ bool all=cond == null;
+ if(!all) active=new bool[nx+1][ny+1];
+
+ real dx=1/nx;
+ real dy=1/ny;
+ pair Idy=(0,dy);
+ pair dz=(dx,dy);
+
+ real[][] F=new real[nx+1][ny+1];
+ real[] x=uniform(a.x,b.x,nx);
+ real[] y=uniform(a.y,b.y,ny);
+ for(int i=0; i <= nx; ++i) {
+ bool[] activei=all ? null : active[i];
+ real[] Fi=F[i];
+ real x=x[i];
+ for(int j=0; j <= ny; ++j) {
+ pair z=(x,y[j]);
+ Fi[j]=f(z);
+ if(!all) activei[j]=cond(z);
+ }
+ }
+ return surface(F,x,y,splinetype,active);
+}
+
+guide3[][] lift(real f(real x, real y), guide[][] g,
+ interpolate3 join=operator --)
+{
+ guide3[][] G=new guide3[g.length][];
+ for(int cnt=0; cnt < g.length; ++cnt) {
+ guide[] gcnt=g[cnt];
+ guide3[] Gcnt=new guide3[gcnt.length];
+ for(int i=0; i < gcnt.length; ++i) {
+ guide gcnti=gcnt[i];
+ guide3 Gcnti=join(...sequence(new guide3(int j) {
+ pair z=point(gcnti,j);
+ return (z.x,z.y,f(z.x,z.y));
+ },size(gcnti)));
+ if(cyclic(gcnti)) Gcnti=Gcnti..cycle;
+ Gcnt[i]=Gcnti;
+ }
+ G[cnt]=Gcnt;
+ }
+ return G;
+}
+
+guide3[][] lift(real f(pair z), guide[][] g, interpolate3 join=operator --)
+{
+ return lift(new real(real x, real y) {return f((x,y));},g,join);
+}
+
+void draw(picture pic=currentpicture, Label[] L=new Label[],
+ guide3[][] g, pen[] p)
+{
+ pen thin=is3D() ? thin() : defaultpen;
+ begingroup3(pic);
+ for(int cnt=0; cnt < g.length; ++cnt) {
+ guide3[] gcnt=g[cnt];
+ pen pcnt=thin+p[cnt];
+ for(int i=0; i < gcnt.length; ++i)
+ draw(pic,gcnt[i],pcnt);
+ if(L.length > 0) {
+ Label Lcnt=L[cnt];
+ for(int i=0; i < gcnt.length; ++i) {
+ if(Lcnt.s != "" && size(gcnt[i]) > 1)
+ label(pic,Lcnt,gcnt[i],pcnt);
+ }
+ }
+ }
+ endgroup3(pic);
+}
+
+void draw(picture pic=currentpicture, Label[] L=new Label[],
+ guide3[][] g, pen p=currentpen)
+{
+ draw(pic,L,g,sequence(new pen(int) {return p;},g.length));
+}
+
+picture vectorfield(path3 vector(pair z), triple f(pair z),
+ pair a, pair b, int nx=nmesh, int ny=nx,
+ bool autoscale=true, pen p=currentpen,
+ arrowbar3 arrow=Arrow3, margin3 margin=PenMargin3)
+{
+ picture pic;
+ real dx=1/nx;
+ real dy=1/ny;
+ real scale;
+ if(autoscale) {
+ real size(pair z) {
+ path3 g=vector(z);
+ return abs(point(g,size(g)-1)-point(g,0));
+ }
+ real max=size((0,0));
+ for(int i=0; i <= nx; ++i) {
+ real x=interp(a.x,b.x,i*dx);
+ for(int j=0; j <= ny; ++j)
+ max=max(max,size((x,interp(a.y,b.y,j*dy))));
+ }
+ pair lambda=(abs(f((b.x,a.y))-f(a)),abs(f((a.x,b.y))-f(a)));
+ scale=min(lambda.x/nx,lambda.y/ny)/max;
+ } else scale=1;
+ for(int i=0; i <= nx; ++i) {
+ real x=interp(a.x,b.x,i*dx);
+ for(int j=0; j <= ny; ++j) {
+ real y=interp(a.y,b.y,j*dy);
+ pair z=(x,y);
+ draw(pic,shift(f(z))*scale3(scale)*vector(z),p,arrow,margin);
+ }
+ }
+ return pic;
+}
+
+triple polar(real r, real theta, real phi)
+{
+ return r*expi(theta,phi);
+}
+
+guide3 polargraph(real r(real,real), real theta(real), real phi(real),
+ int n=ngraph, interpolate3 join=operator --)
+{
+ return graph(join)(new triple(real t) {
+ return polar(r(theta(t),phi(t)),theta(t),phi(t));
+ },0,1,n);
+}
+
+// True arc
+path3 Arc(triple c, triple v1, triple v2, triple normal=O, bool direction=CCW,
+ int n=nCircle)
+{
+ v1 -= c;
+ real r=abs(v1);
+ v1=unit(v1);
+ v2=unit(v2-c);
+
+ if(normal == O) {
+ normal=cross(v1,v2);
+ if(normal == O) abort("explicit normal required for these endpoints");
+ }
+
+ transform3 T=align(unit(normal));
+ transform3 Tinv=transpose(T);
+ v1=Tinv*v1;
+ v2=Tinv*v2;
+
+ real fuzz=sqrtEpsilon*max(abs(v1),abs(v2));
+ if(abs(v1.z) > fuzz || abs(v2.z) > fuzz)
+ abort("invalid normal vector");
+
+ real phi1=radians(longitude(v1,warn=false));
+ real phi2=radians(longitude(v2,warn=false));
+ if(phi1 >= phi2 && direction) phi1 -= 2pi;
+ if(phi2 >= phi1 && !direction) phi2 -= 2pi;
+
+ real piby2=pi/2;
+ return shift(c)*T*polargraph(new real(real theta, real phi) {return r;},
+ new real(real t) {return piby2;},
+ new real(real t) {return interp(phi1,phi2,t);},
+ n,operator ..);
+}
+
+path3 Arc(triple c, real r, real theta1, real phi1, real theta2, real phi2,
+ triple normal=O, bool direction, int n=nCircle)
+{
+ return Arc(c,c+r*dir(theta1,phi1),c+r*dir(theta2,phi2),normal,direction,n);
+}
+
+path3 Arc(triple c, real r, real theta1, real phi1, real theta2, real phi2,
+ triple normal=O, int n=nCircle)
+{
+ return Arc(c,r,theta1,phi1,theta2,phi2,normal,
+ theta2 > theta1 || (theta2 == theta1 && phi2 >= phi1) ? CCW : CW,
+ n);
+}
+
+// True circle
+path3 Circle(triple c, real r, triple normal=Z, int n=nCircle)
+{
+ return Arc(c,r,90,0,90,360,normal,n)&cycle;
+}
diff --git a/Build/source/utils/asymptote/base/graph_settings.asy b/Build/source/utils/asymptote/base/graph_settings.asy
new file mode 100644
index 00000000000..f5d04d0797b
--- /dev/null
+++ b/Build/source/utils/asymptote/base/graph_settings.asy
@@ -0,0 +1,18 @@
+// Number of function samples.
+int ngraph=100;
+int nCircle=400;
+
+// Number of mesh intervals.
+int nmesh=10;
+
+real ticksize=1mm;
+real Ticksize=2*ticksize;
+real ylabelwidth=2.0;
+real axislabelfactor=1.5;
+real axiscoverage=0.8;
+
+real epsilon=10*realEpsilon;
+
+restricted bool Crop=true;
+restricted bool NoCrop=false;
+
diff --git a/Build/source/utils/asymptote/base/grid3.asy b/Build/source/utils/asymptote/base/grid3.asy
new file mode 100644
index 00000000000..dcb220e0746
--- /dev/null
+++ b/Build/source/utils/asymptote/base/grid3.asy
@@ -0,0 +1,399 @@
+// grid3.asy
+// Author: Philippe Ivaldi (Grids in 3D)
+// Created: 10 janvier 2007
+
+import graph3;
+
+struct grid3 {
+ path3 axea,axeb;
+ bounds bds;
+ triple dir;
+ valuetime vt;
+ ticklocate locate;
+ void create(picture pic, path3 axea, path3 axeb, path3 axelevel,
+ real min, real max, position pos, autoscaleT t) {
+ real position=pos.position.x;
+ triple level;
+ if(pos.relative) {
+ position=reltime(axelevel,position);
+ level=point(axelevel,position)-point(axelevel,0);
+ } else {
+ triple v=unit(point(axelevel,1)-point(axelevel,0));
+ triple zerolevel=dot(-point(axelevel,0),v)*v;
+ level=zerolevel+position*v;
+ }
+ this.axea=shift(level)*axea;
+ this.axeb=shift(level)*axeb;
+ bds=autoscale(min,max,t.scale);
+ locate=ticklocate(min,max,t,bds.min,bds.max,
+ Dir(point(axeb,0)-point(axea,0)));
+ }
+};
+
+typedef grid3 grid3routine(picture pic);
+
+triple X(picture pic) {return (pic.userMax.x,pic.userMin.y,pic.userMin.z);}
+triple XY(picture pic) {return (pic.userMax.x,pic.userMax.y,pic.userMin.z);}
+triple Y(picture pic) {return (pic.userMin.x,pic.userMax.y,pic.userMin.z);}
+triple YZ(picture pic) {return (pic.userMin.x,pic.userMax.y,pic.userMax.z);}
+triple Z(picture pic) {return (pic.userMin.x,pic.userMin.y,pic.userMax.z);}
+triple ZX(picture pic) {return (pic.userMax.x,pic.userMin.y,pic.userMax.z);}
+
+grid3routine XYgrid(position pos=Relative(0)) {
+ return new grid3(picture pic) {
+ grid3 og;
+ og.create(pic,pic.userMin--X(pic),Y(pic)--XY(pic),pic.userMin--Z(pic),
+ pic.userMin.x,pic.userMax.x,pos,pic.scale.x);
+ return og;
+ };
+};
+grid3routine XYgrid=XYgrid();
+
+grid3routine YXgrid(position pos=Relative(0)) {
+ return new grid3(picture pic) {
+ grid3 og;
+ og.create(pic,pic.userMin--Y(pic),X(pic)--XY(pic),pic.userMin--Z(pic),
+ pic.userMin.y,pic.userMax.y,pos,pic.scale.y);
+ return og;
+ };
+};
+grid3routine YXgrid=YXgrid();
+
+
+grid3routine XZgrid(position pos=Relative(0)) {
+ return new grid3(picture pic) {
+ grid3 og;
+ og.create(pic,pic.userMin--X(pic),Z(pic)--ZX(pic),pic.userMin--Y(pic),
+ pic.userMin.x,pic.userMax.x,pos,pic.scale.x);
+ return og;
+ };
+};
+grid3routine XZgrid=XZgrid();
+
+grid3routine ZXgrid(position pos=Relative(0)) {
+ return new grid3(picture pic) {
+ grid3 og;
+ og.create(pic,pic.userMin--Z(pic),X(pic)--ZX(pic),pic.userMin--Y(pic),
+ pic.userMin.z,pic.userMax.z,pos,pic.scale.z);
+ return og;
+ };
+};
+grid3routine ZXgrid=ZXgrid();
+
+grid3routine YZgrid(position pos=Relative(0)) {
+ return new grid3(picture pic) {
+ grid3 og;
+ og.create(pic,pic.userMin--Y(pic),Z(pic)--YZ(pic),pic.userMin--X(pic),
+ pic.userMin.y,pic.userMax.y,pos,pic.scale.y);
+ return og;
+ };
+};
+grid3routine YZgrid=YZgrid();
+
+grid3routine ZYgrid(position pos=Relative(0)) {
+ return new grid3(picture pic) {
+ grid3 og;
+ og.create(pic,pic.userMin--Z(pic),Y(pic)--YZ(pic),pic.userMin--X(pic),
+ pic.userMin.z,pic.userMax.z,pos,pic.scale.z);
+ return og;
+ };
+};
+grid3routine ZYgrid=ZYgrid();
+
+typedef grid3routine grid3routines[] ;
+
+grid3routines XYXgrid(position pos=Relative(0)) {
+ grid3routines ogs=new grid3routine[] {XYgrid(pos),YXgrid(pos)};
+ return ogs;
+};
+grid3routines XYXgrid=XYXgrid();
+grid3routines YXYgrid(position pos=Relative(0)) {return XYXgrid(pos);};
+grid3routines YXYgrid=XYXgrid();
+
+grid3routines ZXZgrid(position pos=Relative(0)) {
+ grid3routines ogs=new grid3routine[] {ZXgrid(pos),XZgrid(pos)};
+ return ogs;
+};
+grid3routines ZXZgrid=ZXZgrid();
+grid3routines XZXgrid(position pos=Relative(0)) {return ZXZgrid(pos);};
+grid3routines XZXgrid=XZXgrid();
+
+grid3routines ZYZgrid(position pos=Relative(0)) {
+ grid3routines ogs=new grid3routine[] {ZYgrid(pos),YZgrid(pos)};
+ return ogs;
+};
+grid3routines ZYZgrid=ZYZgrid();
+grid3routines YZYgrid(position pos=Relative(0)) {return ZYZgrid(pos);};
+grid3routines YZYgrid=YZYgrid();
+
+grid3routines XY_XZgrid(position posa=Relative(0), position posb=Relative(0)) {
+ grid3routines ogs=new grid3routine[] {XYgrid(posa),XZgrid(posb)};
+ return ogs;
+};
+grid3routines XY_XZgrid=XY_XZgrid();
+
+grid3routines YX_YZgrid(position posa=Relative(0), position posb=Relative(0)) {
+ grid3routines ogs=new grid3routine[] {YXgrid(posa),YZgrid(posb)};
+ return ogs;
+};
+grid3routines YX_YZgrid=YX_YZgrid();
+
+grid3routines ZX_ZYgrid(position posa=Relative(0), position posb=Relative(0)) {
+ grid3routines ogs=new grid3routine[] {ZXgrid(posa),ZYgrid(posb)};
+ return ogs;
+};
+grid3routines ZX_ZYgrid=ZX_ZYgrid();
+
+typedef grid3routines[] grid3routinetype;
+
+grid3routinetype XYZgrid(position pos=Relative(0))
+{
+ grid3routinetype ogs=new grid3routines[] {YZYgrid(pos),XYXgrid(pos),
+ XZXgrid(pos)};
+ return ogs;
+}
+grid3routinetype XYZgrid=XYZgrid();
+
+grid3routines operator cast(grid3routine gridroutine) {
+ grid3routines og=new grid3routine[] {gridroutine};
+ return og;
+}
+
+grid3routinetype operator cast(grid3routines gridroutine) {
+ grid3routinetype og=new grid3routines[] {gridroutine};
+ return og;
+}
+
+grid3routinetype operator cast(grid3routine gridroutine) {
+ grid3routinetype og=(grid3routinetype)(grid3routines) gridroutine;
+ return og;
+}
+
+void grid3(picture pic=currentpicture,
+ grid3routinetype gridroutine=XYZgrid,
+ int N=0, int n=0, real Step=0, real step=0,
+ bool begin=true, bool end=true,
+ pen pGrid=grey, pen pgrid=lightgrey,
+ bool above=false)
+{
+ for(int j=0; j < gridroutine.length; ++j) {
+ grid3routines gridroutinej=gridroutine[j];
+ for(int i=0; i < gridroutinej.length; ++i) {
+ grid3 gt=gridroutinej[i](pic);
+ pic.add(new void(picture f, transform3 t, transform3 T, triple, triple) {
+ picture d;
+ ticks3 ticks=Ticks3(1,F="%",ticklabel=null,
+ beginlabel=false,endlabel=false,
+ N=N,n=n,Step=Step,step=step,
+ begin=begin,end=end,
+ Size=0,size=0,extend=true,
+ pTick=pGrid,ptick=pgrid);
+ ticks(d,t,"",gt.axea,gt.axeb,nullpen,None,NoMargin3,gt.locate,
+ gt.bds.divisor,opposite=true,primary=false);
+ add(f,t*T*inverse(t)*d);
+ },above=above);
+ addPath(pic,gt.axea,pGrid);
+ addPath(pic,gt.axeb,pGrid);
+ }
+ }
+}
+
+void grid3(picture pic=currentpicture,
+ grid3routinetype gridroutine,
+ int N=0, int n=0, real Step=0, real step=0,
+ bool begin=true, bool end=true,
+ pen[] pGrid, pen[] pgrid,
+ bool above=false)
+{
+ if(pGrid.length != gridroutine.length || pgrid.length != gridroutine.length)
+ abort("pen array has different length than grid");
+ for(int i=0; i < gridroutine.length; ++i) {
+ grid3(pic=pic,gridroutine=gridroutine[i],
+ N=N,n=n,Step=Step,step=step,
+ begin=begin,end=end,
+ pGrid=pGrid[i],pgrid=pgrid[i],
+ above=above);
+ }
+}
+
+position top=Relative(1);
+position bottom=Relative(0);
+position middle=Relative(0.5);
+
+// Structure used to communicate ticks and axis settings to grid3 routines.
+struct ticksgridT {
+ ticks3 ticks;
+ // Other arguments of grid3 are define by ticks and axis settings
+ void grid3(picture, bool);
+};
+
+typedef ticksgridT ticksgrid();
+
+
+ticksgrid InOutTicks(Label F="", ticklabel ticklabel=null,
+ bool beginlabel=true, bool endlabel=true,
+ int N=0, int n=0, real Step=0, real step=0,
+ bool begin=true, bool end=true,
+ real Size=0, real size=0,
+ pen pTick=nullpen, pen ptick=nullpen,
+ grid3routinetype gridroutine,
+ pen pGrid=grey, pen pgrid=lightgrey)
+{
+ return new ticksgridT()
+ {
+ ticksgridT otg;
+ otg.ticks=Ticks3(0,F,ticklabel,beginlabel,endlabel,
+ N,n,Step,step,begin,end,
+ Size,size,false,pTick,ptick);
+ otg.grid3=new void(picture pic, bool above) {
+ grid3(pic,gridroutine,N,n,Step,step,begin,end,pGrid,pgrid,above);
+ };
+ return otg;
+ };
+}
+
+ticksgrid InTicks(Label F="", ticklabel ticklabel=null,
+ bool beginlabel=true, bool endlabel=true,
+ int N=0, int n=0, real Step=0, real step=0,
+ bool begin=true, bool end=true,
+ real Size=0, real size=0,
+ pen pTick=nullpen, pen ptick=nullpen,
+ grid3routinetype gridroutine,
+ pen pGrid=grey, pen pgrid=lightgrey)
+{
+ return new ticksgridT()
+ {
+ ticksgridT otg;
+ otg.ticks=Ticks3(-1,F,ticklabel,beginlabel,endlabel,N,n,Step,step,
+ begin,end,Size,size,false,pTick,ptick);
+ otg.grid3=new void(picture pic, bool above) {
+ grid3(pic,gridroutine,N,n,Step,step,begin,end,pGrid,pgrid,above);
+ };
+ return otg;
+ };
+}
+
+ticksgrid OutTicks(Label F="", ticklabel ticklabel=null,
+ bool beginlabel=true, bool endlabel=true,
+ int N=0, int n=0, real Step=0, real step=0,
+ bool begin=true, bool end=true,
+ real Size=0, real size=0,
+ pen pTick=nullpen, pen ptick=nullpen,
+ grid3routinetype gridroutine,
+ pen pGrid=grey, pen pgrid=lightgrey)
+{
+ return new ticksgridT()
+ {
+ ticksgridT otg;
+ otg.ticks=Ticks3(1,F,ticklabel,beginlabel,endlabel,N,n,Step,step,
+ begin,end,Size,size,false,pTick,ptick);
+ otg.grid3=new void(picture pic, bool above) {
+ grid3(pic,gridroutine,N,n,Step,step,begin,end,pGrid,pgrid,above);
+ };
+ return otg;
+ };
+}
+
+void xaxis3(picture pic=currentpicture, Label L="", axis axis=YZZero,
+ pen p=currentpen, ticksgrid ticks,
+ arrowbar3 arrow=None, bool above=false)
+{
+ xaxis3(pic,L,axis,p,ticks().ticks,arrow,above);
+ ticks().grid3(pic,above);
+}
+
+void yaxis3(picture pic=currentpicture, Label L="", axis axis=XZZero,
+ pen p=currentpen, ticksgrid ticks,
+ arrowbar3 arrow=None, bool above=false)
+{
+ yaxis3(pic,L,axis,p,ticks().ticks,arrow,above);
+ ticks().grid3(pic,above);
+}
+
+void zaxis3(picture pic=currentpicture, Label L="", axis axis=XYZero,
+ pen p=currentpen, ticksgrid ticks,
+ arrowbar3 arrow=None, bool above=false)
+{
+ zaxis3(pic,L,axis,p,ticks().ticks,arrow,above);
+ ticks().grid3(pic,above);
+}
+
+/* Example:
+
+ import grid3;
+
+ size(8cm,0);
+ currentprojection=orthographic(0.5,1,0.5);
+
+ defaultpen(overwrite(SuppressQuiet));
+
+ scale(Linear, Linear, Log);
+
+ grid3(pic=currentpicture, // picture
+ gridroutine=XYZgrid(// grid3routine
+ // or grid3routine[] (alias grid3routines)
+ // or grid3routines[]:
+ // The routine(s) to draw the grid(s):
+ // *XYgrid: draw grid from X in direction of Y
+ // *YXgrid: draw grid from Y in direction of X, ...
+ // *An array of previous values XYgrid, YXgrid, ...
+ // *XYXgrid: draw XYgrid and YXgrid grids
+ // *YXYgrid: draw XYgrid and YXgrid grids
+ // *ZXZgrid: draw ZXgrid and XZgrid grids
+ // *YX_YZgrid: draw YXgrid and YZgrid grids
+ // *XY_XZgrid: draw XYgrid and XZgrid grids
+ // *YX_YZgrid: draw YXgrid and YZgrid grids
+ // *An array of previous values XYXgrid,...
+ // *XYZgrid: draw XYXgrid, ZYZgrid, XZXgrid grids.
+ pos=Relative(0)),
+ // the position of the grid relative to the axis
+ // perpendicular to the grid; a real number
+ // specifies a coordinate relative to this axis.
+ // Aliases: top=Relative(1), middle=Relative(0.5)
+ // and bottom=Relative(0).
+
+ // These arguments are similar to those of InOutTicks():
+ N=0, // int
+ n=0, // int
+ Step=0, // real
+ step=0, // real
+ begin=true, // bool
+ end=true, // bool
+ pGrid=grey, // pen
+ pgrid=lightgrey, // pen
+ above=false // bool
+ );
+
+ xaxis3(Label("$x$",position=EndPoint,align=S),OutTicks());
+ yaxis3(Label("$y$",position=EndPoint,align=S),OutTicks());
+ zaxis3(Label("$z$",position=EndPoint,align=(0,0.5)+W),OutTicks());
+*/
+
+/* Other examples:
+
+ int N=10, n=2;
+ xaxis3(Label("$x$",position=EndPoint,align=S),OutTicks());
+ yaxis3(Label("$y$",position=EndPoint,align=S),OutTicks(N=N,n=n));
+ zaxis3(Label("$z$",position=EndPoint,align=(0,0.5)+W),OutTicks());
+ grid3(N=N,n=n);
+
+ xaxis3(Label("$x$",position=EndPoint,align=S),OutTicks());
+ yaxis3(Label("$y$",position=EndPoint,align=S),OutTicks());
+ zaxis3(Label("$z$",position=EndPoint,align=(0,0.5)+W),OutTicks());
+ grid3(new grid3routines[] {XYXgrid(top),XZXgrid(0)});
+
+ xaxis3(Label("$x$",position=EndPoint,align=S),OutTicks());
+ yaxis3(Label("$y$",position=EndPoint,align=S),OutTicks());
+ zaxis3(Label("$z$",position=EndPoint,align=(0,0.5)+W),OutTicks());
+ grid3(new grid3routines[] {XYXgrid(-0.5),XYXgrid(1.5)},
+ pGrid=new pen[] {red,blue},
+ pgrid=new pen[] {0.5red,0.5blue});
+
+ // Axes with grids:
+
+ xaxis3(Label("$x$",position=EndPoint,align=S),
+ OutTicks(Step=0.5,gridroutine=XYgrid));
+ yaxis3(Label("$y$",position=EndPoint,align=S),
+ InOutTicks(Label("",align=0.5X),N=8,n=2,gridroutine=YX_YZgrid));
+ zaxis3("$z$",OutTicks(ZYgrid));
+*/
diff --git a/Build/source/utils/asymptote/base/interpolate.asy b/Build/source/utils/asymptote/base/interpolate.asy
new file mode 100644
index 00000000000..a6b820bc7d5
--- /dev/null
+++ b/Build/source/utils/asymptote/base/interpolate.asy
@@ -0,0 +1,140 @@
+// Lagrange and Hermite interpolation in Asymptote
+// Author: Olivier Guibé
+// Acknowledgements: Philippe Ivaldi
+
+// diffdiv(x,y) computes Newton's Divided Difference for
+// Lagrange interpolation with distinct values {x_0,..,x_n} in the array x
+// and values y_0,...,y_n in the array y,
+
+// hdiffdiv(x,y,dyp) computes Newton's Divided Difference for
+// Hermite interpolation where dyp={dy_0,...,dy_n}.
+//
+// fhorner(x,coeff) uses Horner's rule to compute the polynomial
+// a_0+a_1(x-x_0)+a_2(x-x_0)(x-x_1)+...+a_n(x-x_0)..(x-x_{n-1}),
+// where coeff={a_0,a_1,...,a_n}.
+
+// fspline does standard cubic spline interpolation of a function f
+// on the interval [a,b].
+// The points a=x_1 < x_2 < .. < x_n=b form the array x;
+// the points y_1=f(x_1),....,y_n=f(x_n) form the array y
+// We use the Hermite form for the spline.
+
+// The syntax is:
+// s=fspline(x,y); default not_a_knot condition
+// s=fspline(x,y,natural); natural spline
+// s=fspline(x,y,periodic); periodic spline
+// s=fspline(x,y,clamped(1,1)); clamped spline
+// s=fspline(x,y,monotonic); piecewise monotonic spline
+
+// Here s is a real function that is constant on (-infinity,a] and [b,infinity).
+
+private import math;
+import splinetype;
+
+typedef real fhorner(real);
+
+struct horner {
+ // x={x0,..,xn}(not necessarily distinct)
+ // a={a0,..,an} corresponds to the polyonmial
+ // a_0+a_1(x-x_0)+a_2(x-x_0)(x-x_1)+...+a_n(x-x_0)..(x-x_{n-1}),
+ real[] x;
+ real[] a;
+}
+
+// Evaluate p(x)=d0+(x-x0)(d1+(x-x1)+...+(d(n-1)+(x-x(n-1))*dn)))
+// via Horner's rule: n-1 multiplications, 2n-2 additions.
+fhorner fhorner(horner sh)
+{
+ int n=sh.x.length;
+ checklengths(n,sh.a.length);
+ return new real(real x) {
+ real s=sh.a[n-1];
+ for(int k=n-2; k >= 0; --k)
+ s=sh.a[k]+(x-sh.x[k])*s;
+ return s;
+ };
+}
+
+// Newton's Divided Difference method: n(n-1)/2 divisions, n(n-1) additions.
+horner diffdiv(real[] x, real[] y)
+{
+ int n=x.length;
+ horner s;
+ checklengths(n,y.length);
+ for(int i=0; i < n; ++i)
+ s.a[i]=y[i];
+ for(int k=0; k < n-1; ++k) {
+ for(int i=n-1; i > k; --i) {
+ s.a[i]=(s.a[i]-s.a[i-1])/(x[i]-x[i-k-1]);
+ }
+ }
+ s.x=x;
+ return s;
+}
+
+// Newton's Divided Difference for simple Hermite interpolation,
+// where one specifies both p(x_i) and p'(x_i).
+horner hdiffdiv(real[] x, real[] y, real[] dy)
+{
+ int n=x.length;
+ horner s;
+ checklengths(n,y.length);
+ checklengths(n,dy.length);
+ for(int i=0; i < n; ++i) {
+ s.a[2*i]=y[i];
+ s.a[2*i+1]=dy[i];
+ s.x[2*i]=x[i];
+ s.x[2*i+1]=x[i];
+ }
+
+ for(int i=n-1; i > 0; --i)
+ s.a[2*i]=(s.a[2*i]-s.a[2*i-2])/(x[i]-x[i-1]);
+
+ int stop=2*n-1;
+ for(int k=1; k < stop; ++k) {
+ for(int i=stop; i > k; --i) {
+ s.a[i]=(s.a[i]-s.a[i-1])/(s.x[i]-s.x[i-k-1]);
+ }
+ }
+ return s;
+}
+
+typedef real realfunction(real);
+
+// piecewise Hermite interpolation:
+// return the piecewise polynomial p(x), where on [x_i,x_i+1], deg(p) <= 3,
+// p(x_i)=y_i, p(x_{i+1})=y_i+1, p'(x_i)=dy_i, and p'(x_{i+1})=dy_i+1.
+// Outside [x_1,x_n] the returned function is constant: y_1 on (infinity,x_1]
+// and y_n on [x_n,infinity).
+realfunction pwhermite(real[] x, real[] y, real[] dy)
+{
+ int n=x.length;
+ checklengths(n,y.length);
+ checklengths(n,dy.length);
+ if(n < 2) abort(morepoints);
+ if(!increasing(x,strict=true)) abort("array x is not strictly increasing");
+ return new real(real t) {
+ int i=search(x,t);
+ if(i == n-1) {
+ i=n-2;
+ t=x[n-1];
+ } else if(i == -1) {
+ i=0;
+ t=x[0];
+ }
+ real h=x[i+1]-x[i];
+ real delta=(y[i+1]-y[i])/h;
+ real e=(3*delta-2*dy[i]-dy[i+1])/h;
+ real f=(dy[i]-2*delta+dy[i+1])/h^2;
+ real s=t-x[i];
+ return y[i]+s*(dy[i]+s*(e+s*f));
+ };
+}
+
+realfunction fspline(real[] x, real[] y, splinetype splinetype=notaknot)
+{
+ real[] dy=splinetype(x,y);
+ return new real(real t) {
+ return pwhermite(x,y,dy)(t);
+ };
+}
diff --git a/Build/source/utils/asymptote/base/labelpath.asy b/Build/source/utils/asymptote/base/labelpath.asy
new file mode 100644
index 00000000000..fe597a1608d
--- /dev/null
+++ b/Build/source/utils/asymptote/base/labelpath.asy
@@ -0,0 +1,28 @@
+usepackage("pstricks");
+usepackage("pst-text");
+
+string LeftJustified="l";
+string RightJustified="r";
+string Centered="c";
+
+void labelpath(frame f, Label L, path g, string justify=Centered,
+ pen p=currentpen)
+{
+ if(latex() && !pdf()) {
+ _labelpath(f,L.s,L.size,g,justify,(L.T.x,L.T.y+0.5linewidth(p)),p);
+ return;
+ }
+ write("warning: labelpath requires -tex latex");
+}
+
+void labelpath(picture pic=currentpicture, Label L, path g,
+ string justify=Centered, pen p=currentpen)
+{
+ pic.add(new void(frame f, transform t) {
+ labelpath(f,L,t*g,justify,p);
+ });
+ frame f;
+ label(f,Label(L.s,L.size));
+ real w=size(f).y+L.T.y+0.5linewidth(p);
+ pic.addBox(min(g),max(g),-w,w);
+}
diff --git a/Build/source/utils/asymptote/base/labelpath3.asy b/Build/source/utils/asymptote/base/labelpath3.asy
new file mode 100644
index 00000000000..acfa64d528f
--- /dev/null
+++ b/Build/source/utils/asymptote/base/labelpath3.asy
@@ -0,0 +1,86 @@
+// Fit a label to a path3.
+// Author: Jens Schwaiger
+
+import three;
+size(7.5cm,0);
+real eps=100*realEpsilon;
+currentprojection=perspective(20,18,8);
+currentlight=light(8,10,2);
+//texpreamble("\textwidth=50cm"); // Avoid line breaking in long texts
+
+triple nextnormal(triple p, triple q)
+{
+ triple nw=p-(dot(p,q)*q);
+ return abs(nw) < 0.0001 ? p : unit(nw);
+}
+
+triple[] firstframe(path3 p, triple optional=O)
+{
+ triple[] start=new triple[3];
+ start[0]=dir(p,reltime(p,0));
+ start[1]=(abs(cross(start[0],optional)) < eps) ? perp(start[0]) :
+ unit(cross(start[0],optional));
+ start[2]=cross(start[0],start[1]);
+ return start;
+}
+
+// Modification of the bishop frame construction contained in
+// space_tube.asy(from Philippe Ivaldi's modules).
+// For noncyclic path3s only
+triple[] nextframe(path3 p, real reltimestart, triple[] start, real
+ reltimeend, int subdiv=20)
+{
+ triple[][] bf=new triple[subdiv+1][3];
+ real lg=reltimeend-reltimestart;
+ if(lg <= 0) return start;
+ bf[0]=start;
+ for(int i=1; i < subdiv+1; i=i+1) {
+ bf[i][0]=dir(p,reltime(p,reltimestart+(i/subdiv)*lg));
+ };
+ for(int i=1; i < subdiv+1; i=i+1) {
+ bf[i][1]=nextnormal(bf[i-1][1],bf[i][0]);
+ bf[i][2]=cross(bf[i][0],bf[i][1]);
+ };
+ return bf[subdiv];
+}
+
+surface labelpath(string txt, path3 p, real angle=90, triple optional=O)
+{
+ real Cos=Cos(angle);
+ real Sin=Sin(angle);
+ path[] text=shift(-labelmargin(currentpen)*NE)*
+ texpath(Label(txt,(0,0),NE,basealign));
+ text=scale(1/(max(text).x-min(text).x))*text;
+ path[][] decompose=containmentTree(text);
+
+ real[][] xpos=new real[decompose.length][2];
+ surface sf;
+ for(int i=0; i < decompose.length; ++i) {// Identify positions along x-axis
+ xpos[i][1]=i;
+ real pos0=0.5(max(decompose[i]).x+min(decompose[i]).x);
+ xpos[i][0]=pos0;
+ };
+ xpos=sort(xpos); // sort by distance from 0;
+ triple[] pos=new triple[decompose.length];
+ real lg=arclength(p);
+ //create frames;
+ triple[] first=firstframe(p,optional);
+ triple[] t0=first;
+ real tm0=0;
+ triple[][] bfr=new triple[decompose.length][3];
+ for(int j=0; j < decompose.length; ++j) {
+ bfr[j]=nextframe(p,tm0,t0,xpos[j][0]);
+ tm0=xpos[j][0]; t0=bfr[j];};
+ transform3[] mt=new transform3[bfr.length];
+ for(int j=0; j < bfr.length; ++j) {
+ triple f2=Cos*bfr[j][1]+Sin*bfr[j][2];
+ triple f3=Sin*bfr[j][1]+Cos*bfr[j][2];
+ mt[j]=shift(relpoint(p,xpos[j][0]))*transform3(bfr[j][0],f2,f3);
+ };
+ for(int j=0; j < bfr.length; ++j) {
+ path[] dc=decompose[(int) xpos[j][1]];
+ pair pos0=(0.5(max(dc).x+min(dc).x),0);
+ sf.append(mt[j]*surface(scale(lg)*shift(-pos0)*dc));
+ };
+ return sf;
+}
diff --git a/Build/source/utils/asymptote/base/latin1.asy b/Build/source/utils/asymptote/base/latin1.asy
new file mode 100644
index 00000000000..3d76925be24
--- /dev/null
+++ b/Build/source/utils/asymptote/base/latin1.asy
@@ -0,0 +1,2 @@
+usepackage("fontenc","T1");
+usepackage("inputenc","latin1");
diff --git a/Build/source/utils/asymptote/base/markers.asy b/Build/source/utils/asymptote/base/markers.asy
new file mode 100644
index 00000000000..3fef6eb2d6c
--- /dev/null
+++ b/Build/source/utils/asymptote/base/markers.asy
@@ -0,0 +1,217 @@
+// Mark routines and markers written by Philippe Ivaldi.
+
+marker operator * (transform T, marker m)
+{
+ marker M=new marker;
+ M.f=T*m.f;
+ M.above=m.above;
+ M.markroutine=m.markroutine;
+ return M;
+}
+
+// Add n frames f midway (in arclength) between n+1 uniformly spaced marks.
+markroutine markinterval(int n=1, frame f, bool rotated=false)
+{
+ return new void(picture pic=currentpicture, frame mark, path g) {
+ markuniform(n+1,rotated)(pic,mark,g);
+ markuniform(centered=true,n,rotated)(pic,f,g);
+ };
+}
+
+// Return a frame containing n copies of the path g shifted by space
+// drawn with pen p.
+frame duplicate(path g, int n=1, pair space=0, pen p=currentpen)
+{
+ if(space == 0) space=dotsize(p);
+ frame f;
+ int pos=0;
+ int sign=1;
+ int m=(n+1) % 2;
+ for(int i=1; i <= n; ++i) {
+ draw(f,shift(space*(pos-0.5*m))*g,p);
+ pos += i*sign;
+ sign *= -1;
+ }
+ return f;
+}
+
+real tildemarksizefactor=5;
+real tildemarksize(pen p=currentpen)
+{
+ static real golden=(1+sqrt(5))/2;
+ return (1mm+tildemarksizefactor*sqrt(linewidth(p)))/golden;
+}
+frame tildeframe(int n=1, real size=0, pair space=0,
+ real angle=0, pair offset=0, pen p=currentpen)
+{
+ size=(size == 0) ? tildemarksize(p) : size;
+ space=(space == 0) ? 1.5*size : space;
+ path g=yscale(1.25)*((-1.5,-0.5)..(-0.75,0.5)..(0,0)..(0.75,-0.5)..(1.5,0.5));
+ return duplicate(shift(offset)*rotate(angle)*scale(size)*g,n,space,p);
+}
+
+frame tildeframe=tildeframe();
+
+real stickmarkspacefactor=4;
+real stickmarksizefactor=10;
+real stickmarksize(pen p=currentpen)
+{
+ return 1mm+stickmarksizefactor*sqrt(linewidth(p));
+}
+real stickmarkspace(pen p=currentpen)
+{
+ return stickmarkspacefactor*sqrt(linewidth(p));
+}
+frame stickframe(int n=1, real size=0, pair space=0, real angle=0,
+ pair offset=0, pen p=currentpen)
+{
+ if(size == 0) size=stickmarksize(p);
+ if(space == 0) space=stickmarkspace(p);
+ return duplicate(shift(offset)*rotate(angle)*scale(0.5*size)*(N--S),n,
+ space,p);
+}
+
+frame stickframe=stickframe();
+
+real circlemarkradiusfactor=stickmarksizefactor/2;
+real circlemarkradius(pen p=currentpen)
+{
+ static real golden=(1+sqrt(5))/2;
+ return (1mm+circlemarkradiusfactor*sqrt(linewidth(p)))/golden;
+}
+real barmarksizefactor=stickmarksizefactor;
+real barmarksize(pen p=currentpen)
+{
+ return 1mm+barmarksizefactor*sqrt(linewidth(p));
+}
+frame circlebarframe(int n=1, real barsize=0,
+ real radius=0,real angle=0,
+ pair offset=0, pen p=currentpen,
+ filltype filltype=NoFill, bool above=false)
+{
+ if(barsize == 0) barsize=barmarksize(p);
+ if(radius == 0) radius=circlemarkradius(p);
+ frame opic;
+ path g=circle(offset,radius);
+ frame f=stickframe(n,barsize,space=2*radius/(n+1),angle,offset,p);
+ if(above) {
+ add(opic,f);
+ filltype.fill(opic,g,p);
+ } else {
+ filltype.fill(opic,g,p);
+ add(opic,f);
+ }
+ return opic;
+}
+
+real crossmarksizefactor=5;
+real crossmarksize(pen p=currentpen)
+{
+ return 1mm+crossmarksizefactor*sqrt(linewidth(p));
+}
+frame crossframe(int n=3, real size=0, pair space=0,
+ real angle=0, pair offset=0, pen p=currentpen)
+{
+ if(size == 0) size=crossmarksize(p);
+ frame opic;
+ draw(opic,shift(offset)*rotate(angle)*scale(size)*cross(n),p);
+ return opic;
+}
+
+real markanglespacefactor=4;
+real markangleradiusfactor=8;
+real markangleradius(pen p=currentpen)
+{
+ return 8mm+markangleradiusfactor*sqrt(linewidth(p));
+}
+real markangleradius=markangleradius();
+real markanglespace(pen p=currentpen)
+{
+ return markanglespacefactor*sqrt(linewidth(p));
+}
+real markanglespace=markanglespace();
+// Mark the oriented angle AOB counterclockwise with optional Label, arrows, and markers.
+// With radius < 0, AOB-2pi is marked clockwise.
+void markangle(picture pic=currentpicture, Label L="",
+ int n=1, real radius=0, real space=0,
+ pair A, pair O, pair B, arrowbar arrow=None,
+ pen p=currentpen, filltype filltype=NoFill,
+ margin margin=NoMargin, marker marker=nomarker)
+{
+ if(space == 0) space=markanglespace(p);
+ if(radius == 0) radius=markangleradius(p);
+ picture lpic,phantom;
+ frame ff;
+ path lpth;
+ p=squarecap+p;
+ pair OB=unit(B-O), OA=unit(A-O);
+ real xoa=degrees(OA,false);
+ real gle=degrees(acos(dot(OA,OB)));
+ if((conj(OA)*OB).y < 0) gle *= -1;
+ bool ccw=radius > 0;
+ if(!ccw) radius=-radius;
+ bool drawarrow = !arrow(phantom,arc((0,0),radius,xoa,xoa+gle,ccw),p,margin);
+ if(drawarrow && margin == NoMargin) margin=TrueMargin(0,0.5linewidth(p));
+ if(filltype != NoFill) {
+ lpth=margin(arc((0,0),radius+(n-1)*space,xoa,xoa+gle,ccw),p).g;
+ pair p0=relpoint(lpth,0), p1=relpoint(lpth,1);
+ pair ac=p0-p0-A+O, bd=p1-p1-B+O, det=(conj(ac)*bd).y;
+ pair op=(det == 0) ? O : p0+(conj(p1-p0)*bd).y*ac/det;
+ filltype.fill(ff,op--lpth--relpoint(lpth,1)--cycle,p);
+ add(lpic,ff);
+ }
+ for(int i=0; i < n; ++i) {
+ lpth=margin(arc((0,0),radius+i*space,xoa,xoa+gle,ccw),p).g;
+ draw(lpic,lpth,p=p,arrow=arrow,margin=NoMargin,marker=marker);
+ }
+ Label lL=L.copy();
+ real position=lL.position.position.x;
+ if(lL.defaultposition) {lL.position.relative=true; position=0.5;}
+ if(lL.position.relative) position=reltime(lpth,position);
+ if(lL.align.default) {
+ lL.align.relative=true;
+ lL.align.dir=unit(point(lpth,position));
+ }
+ label(lpic,lL,point(lpth,position),align=NoAlign, p=p);
+ add(pic,lpic,O);
+}
+
+marker StickIntervalMarker(int i=2, int n=1, real size=0, real space=0,
+ real angle=0, pair offset=0, bool rotated=true,
+ pen p=currentpen, frame uniform=newframe,
+ bool above=true)
+{
+ return marker(uniform,markinterval(i,stickframe(n,size,space,angle,offset,p),
+ rotated),above);
+}
+
+
+marker CrossIntervalMarker(int i=2, int n=3, real size=0, real space=0,
+ real angle=0, pair offset=0, bool rotated=true,
+ pen p=currentpen, frame uniform=newframe,
+ bool above=true)
+{
+ return marker(uniform,markinterval(i,crossframe(n,size,space,angle,offset,p),
+ rotated=rotated),above);
+}
+
+marker CircleBarIntervalMarker(int i=2, int n=1, real barsize=0, real radius=0,
+ real angle=0, pair offset=0, bool rotated=true,
+ pen p=currentpen, filltype filltype=NoFill,
+ bool circleabove=false, frame uniform=newframe,
+ bool above=true)
+{
+ return marker(uniform,markinterval(i,circlebarframe(n,barsize,radius,angle,
+ offset,p,filltype,
+ circleabove),
+ rotated),above);
+}
+
+marker TildeIntervalMarker(int i=2, int n=1, real size=0, real space=0,
+ real angle=0, pair offset=0, bool rotated=true,
+ pen p=currentpen, frame uniform=newframe,
+ bool above=true)
+{
+ return marker(uniform,markinterval(i,tildeframe(n,size,space,angle,offset,p),
+ rotated),above);
+}
diff --git a/Build/source/utils/asymptote/base/math.asy b/Build/source/utils/asymptote/base/math.asy
new file mode 100644
index 00000000000..f204f746349
--- /dev/null
+++ b/Build/source/utils/asymptote/base/math.asy
@@ -0,0 +1,392 @@
+// Asymptote mathematics routines
+
+int quadrant(real degrees)
+{
+ return floor(degrees/90) % 4;
+}
+
+// Roots of unity.
+pair unityroot(int n, int k=1)
+{
+ return expi(2pi*k/n);
+}
+
+real csc(real x) {return 1/sin(x);}
+real sec(real x) {return 1/cos(x);}
+real cot(real x) {return tan(pi/2-x);}
+
+real acsc(real x) {return asin(1/x);}
+real asec(real x) {return acos(1/x);}
+real acot(real x) {return pi/2-atan(x);}
+
+real frac(real x) {return x-(int)x;}
+
+pair exp(explicit pair z) {return exp(z.x)*expi(z.y);}
+pair log(explicit pair z) {return log(abs(z))+I*angle(z);}
+
+// Return an Nx by Ny unit square lattice with lower-left corner at (0,0).
+picture grid(int Nx, int Ny, pen p=currentpen)
+{
+ picture pic;
+ for(int i=0; i <= Nx; ++i) draw(pic,(i,0)--(i,Ny),p);
+ for(int j=0; j <= Ny; ++j) draw(pic,(0,j)--(Nx,j),p);
+ return pic;
+}
+
+bool polygon(path p)
+{
+ return cyclic(p) && piecewisestraight(p);
+}
+
+// Return the intersection time of the extension of the line segment PQ
+// with the plane perpendicular to n and passing through Z.
+real intersect(triple P, triple Q, triple n, triple Z)
+{
+ real d=n.x*Z.x+n.y*Z.y+n.z*Z.z;
+ real denom=n.x*(Q.x-P.x)+n.y*(Q.y-P.y)+n.z*(Q.z-P.z);
+ return denom == 0 ? infinity : (d-n.x*P.x-n.y*P.y-n.z*P.z)/denom;
+}
+
+// Return any point on the intersection of the two planes with normals
+// n0 and n1 passing through points P0 and P1, respectively.
+// If the planes are parallel return (infinity,infinity,infinity).
+triple intersectionpoint(triple n0, triple P0, triple n1, triple P1)
+{
+ real Dx=n0.y*n1.z-n1.y*n0.z;
+ real Dy=n0.z*n1.x-n1.z*n0.x;
+ real Dz=n0.x*n1.y-n1.x*n0.y;
+ if(abs(Dx) > abs(Dy) && abs(Dx) > abs(Dz)) {
+ Dx=1/Dx;
+ real d0=n0.y*P0.y+n0.z*P0.z;
+ real d1=n1.y*P1.y+n1.z*P1.z+n1.x*(P1.x-P0.x);
+ real y=(d0*n1.z-d1*n0.z)*Dx;
+ real z=(d1*n0.y-d0*n1.y)*Dx;
+ return (P0.x,y,z);
+ } else if(abs(Dy) > abs(Dz)) {
+ Dy=1/Dy;
+ real d0=n0.z*P0.z+n0.x*P0.x;
+ real d1=n1.z*P1.z+n1.x*P1.x+n1.y*(P1.y-P0.y);
+ real z=(d0*n1.x-d1*n0.x)*Dy;
+ real x=(d1*n0.z-d0*n1.z)*Dy;
+ return (x,P0.y,z);
+ } else {
+ if(Dz == 0) return (infinity,infinity,infinity);
+ Dz=1/Dz;
+ real d0=n0.x*P0.x+n0.y*P0.y;
+ real d1=n1.x*P1.x+n1.y*P1.y+n1.z*(P1.z-P0.z);
+ real x=(d0*n1.y-d1*n0.y)*Dz;
+ real y=(d1*n0.x-d0*n1.x)*Dz;
+ return (x,y,P0.z);
+ }
+}
+
+// Given a real array A, return its partial sums.
+real[] partialsum(real[] A)
+{
+ real[] B=new real[A.length];
+ real sum=0;
+ for(int i=0; i < A.length; ++i) {
+ sum += A[i];
+ B[i]=sum;
+ }
+ return B;
+}
+
+// Given a real array A, return its partial dx-weighted sums.
+real[] partialsum(real[] A, real[] dx)
+{
+ real[] B=new real[A.length];
+ real sum=0;
+ for(int i=0; i < A.length; ++i) {
+ sum += A[i]*dx[i];
+ B[i]=sum;
+ }
+ return B;
+}
+
+// If strict=false, return whether i > j implies x[i] >= x[j]
+// If strict=true, return whether i > j implies x[i] > x[j]
+bool increasing(real[] x, bool strict=false)
+{
+ real[] xp=copy(x);
+ xp.delete(0);
+ xp.push(0);
+ bool[] b=strict ? (xp > x) : (xp >= x);
+ b[x.length-1]=true;
+ return all(b);
+}
+
+// Return the indices of consecutive true-element segments of bool[] b.
+int[][] segment(bool[] b)
+{
+ int[][] segment;
+ bool[] n=copy(b);
+ n.delete(0);
+ n.push(!b[b.length-1]);
+ int[] edge=(b != n) ? sequence(1,b.length) : null;
+ edge.insert(0,0);
+ int stop=edge[0];
+ for(int i=0; i < edge.length-1;) {
+ int start=stop;
+ stop=edge[++i];
+ if(b[start])
+ segment.push(sequence(start,stop-1));
+ }
+ return segment;
+}
+
+real[] zero(int n)
+{
+ return sequence(new real(int) {return 0;},n);
+}
+
+real[][] zero(int n, int m)
+{
+ real[][] M=new real[n][];
+ for(int i=0; i < n; ++i)
+ M[i]=sequence(new real(int) {return 0;},m);
+ return M;
+}
+
+real[][] operator + (real[][] a, real[][] b)
+{
+ int n=a.length;
+ real[][] m=new real[n][];
+ for(int i=0; i < n; ++i)
+ m[i]=a[i]+b[i];
+ return m;
+}
+
+real[][] operator - (real[][] a, real[][] b)
+{
+ int n=a.length;
+ real[][] m=new real[n][];
+ for(int i=0; i < n; ++i)
+ m[i]=a[i]-b[i];
+ return m;
+}
+
+private string incommensurate=
+ "Multiplication of incommensurate matrices is undefined";
+
+real[] operator * (real[] b, real[][] a)
+{
+ int nb=b.length;
+ if(nb != a.length)
+ abort(incommensurate);
+ int na0=a[0].length;
+ real[] m=new real[na0];
+ for(int j=0; j < na0; ++j) {
+ real sum;
+ for(int k=0; k < nb; ++k)
+ sum += b[k]*a[k][j];
+ m[j]=sum;
+ }
+ return m;
+}
+
+real[][] operator * (real[][] a, real b)
+{
+ int n=a.length;
+ real[][] m=new real[n][];
+ for(int i=0; i < n; ++i)
+ m[i]=a[i]*b;
+ return m;
+}
+
+real[][] operator * (real b, real[][] a)
+{
+ return a*b;
+}
+
+real[][] operator / (real[][] a, real b)
+{
+ return a*(1/b);
+}
+
+bool square(real[][] m)
+{
+ int n=m.length;
+ for(int i=0; i < n; ++i)
+ if(m[i].length != n) return false;
+ return true;
+}
+
+bool rectangular(real[][] m)
+{
+ int n=m.length;
+ if(n > 0) {
+ int m0=m[0].length;
+ for(int i=1; i < n; ++i)
+ if(m[i].length != m0) return false;
+ }
+ return true;
+}
+
+bool rectangular(pair[][] m)
+{
+ int n=m.length;
+ if(n > 0) {
+ int m0=m[0].length;
+ for(int i=1; i < n; ++i)
+ if(m[i].length != m0) return false;
+ }
+ return true;
+}
+
+bool rectangular(triple[][] m)
+{
+ int n=m.length;
+ if(n > 0) {
+ int m0=m[0].length;
+ for(int i=1; i < n; ++i)
+ if(m[i].length != m0) return false;
+ }
+ return true;
+}
+
+// draw the (infinite) line going through P and Q, without altering the
+// size of picture pic.
+void drawline(picture pic=currentpicture, pair P, pair Q, pen p=currentpen)
+{
+ pic.add(new void (frame f, transform t, transform, pair m, pair M) {
+ // Reduce the bounds by the size of the pen.
+ m -= min(p); M -= max(p);
+
+ // Calculate the points and direction vector in the transformed space.
+ pair z=t*P;
+ pair v=t*Q-z;
+
+ // Handle horizontal and vertical lines.
+ if(v.x == 0) {
+ if(m.x <= z.x && z.x <= M.x)
+ draw(f,(z.x,m.y)--(z.x,M.y),p);
+ } else if(v.y == 0) {
+ if(m.y <= z.y && z.y <= M.y)
+ draw(f,(m.x,z.y)--(M.x,z.y),p);
+ } else {
+ // Calculate the maximum and minimum t values allowed for the
+ // parametric equation z + t*v
+ real mx=(m.x-z.x)/v.x, Mx=(M.x-z.x)/v.x;
+ real my=(m.y-z.y)/v.y, My=(M.y-z.y)/v.y;
+ real tmin=max(v.x > 0 ? mx : Mx, v.y > 0 ? my : My);
+ real tmax=min(v.x > 0 ? Mx : mx, v.y > 0 ? My : my);
+ if(tmin <= tmax)
+ draw(f,z+tmin*v--z+tmax*v,p);
+ }
+ },true);
+}
+
+real interpolate(real[] x, real[] y, real x0, int i)
+{
+ int n=x.length;
+ if(n == 0) abort("Zero data points in interpolate");
+ if(n == 1) return y[0];
+ if(i < 0) {
+ real dx=x[1]-x[0];
+ return y[0]+(y[1]-y[0])/dx*(x0-x[0]);
+ }
+ if(i >= n-1) {
+ real dx=x[n-1]-x[n-2];
+ return y[n-1]+(y[n-1]-y[n-2])/dx*(x0-x[n-1]);
+ }
+
+ real D=x[i+1]-x[i];
+ real B=(x0-x[i])/D;
+ real A=1.0-B;
+ return A*y[i]+B*y[i+1];
+}
+
+// Linearly interpolate data points (x,y) to (x0,y0), where the elements of
+// real[] x are listed in ascending order and return y0. Values outside the
+// available data range are linearly extrapolated using the first derivative
+// at the nearest endpoint.
+real interpolate(real[] x, real[] y, real x0)
+{
+ return interpolate(x,y,x0,search(x,x0));
+}
+
+private string nopoint="point not found";
+
+// Return the nth intersection time of path g with the vertical line through x.
+real time(path g, real x, int n=0)
+{
+ real[] t=times(g,x);
+ if(t.length <= n) abort(nopoint);
+ return t[n];
+}
+
+// Return the nth intersection time of path g with the horizontal line through
+// (0,z.y).
+real time(path g, explicit pair z, int n=0)
+{
+ real[] t=times(g,z);
+ if(t.length <= n) abort(nopoint);
+ return t[n];
+}
+
+// Return the nth y value of g at x.
+real value(path g, real x, int n=0)
+{
+ return point(g,time(g,x,n)).y;
+}
+
+// Return the nth x value of g at y=z.y.
+real value(path g, explicit pair z, int n=0)
+{
+ return point(g,time(g,(0,z.y),n)).x;
+}
+
+// Return the nth slope of g at x.
+real slope(path g, real x, int n=0)
+{
+ pair a=dir(g,time(g,x,n));
+ return a.y/a.x;
+}
+
+// Return the nth slope of g at y=z.y.
+real slope(path g, explicit pair z, int n=0)
+{
+ pair a=dir(g,time(g,(0,z.y),n));
+ return a.y/a.x;
+}
+
+// A quartic complex root solver based on these references:
+// http://planetmath.org/encyclopedia/GaloisTheoreticDerivationOfTheQuarticFormula.html
+// Neumark, S., Solution of Cubic and Quartic Equations, Pergamon Press
+// Oxford (1965).
+pair[] quarticroots(real a, real b, real c, real d, real e)
+{
+ real Fuzz=100000*realEpsilon;
+
+ // Remove roots at numerical infinity.
+ if(abs(a) <= Fuzz*(abs(b)+Fuzz*(abs(c)+Fuzz*(abs(d)+Fuzz*abs(e)))))
+ return cubicroots(b,c,d,e);
+
+ // Detect roots at numerical zero.
+ if(abs(e) <= Fuzz*(abs(d)+Fuzz*(abs(c)+Fuzz*(abs(b)+Fuzz*abs(a)))))
+ return cubicroots(a,b,c,d);
+
+ real ainv=1/a;
+ b *= ainv;
+ c *= ainv;
+ d *= ainv;
+ e *= ainv;
+
+ pair[] roots;
+ real[] T=cubicroots(1,-2c,c^2+b*d-4e,d^2+b^2*e-b*c*d);
+ if(T.length == 0) return roots;
+
+ real t0=T[0];
+ pair[] sum=quadraticroots((1,0),(b,0),(t0,0));
+ pair[] product=quadraticroots((1,0),(t0-c,0),(e,0));
+
+ if(abs(sum[0]*product[0]+sum[1]*product[1]+d) <
+ abs(sum[0]*product[1]+sum[1]*product[0]+d))
+ product=reverse(product);
+
+ for(int i=0; i < 2; ++i)
+ roots.append(quadraticroots((1,0),-sum[i],product[i]));
+
+ return roots;
+}
diff --git a/Build/source/utils/asymptote/base/metapost.asy b/Build/source/utils/asymptote/base/metapost.asy
new file mode 100644
index 00000000000..525ffe755e1
--- /dev/null
+++ b/Build/source/utils/asymptote/base/metapost.asy
@@ -0,0 +1,19 @@
+// MetaPost compatibility routines
+
+path cuttings;
+
+path cutbefore(path p, path q)
+{
+ slice s=firstcut(p,q);
+ cuttings=s.before;
+ return s.after;
+}
+
+path cutafter(path p, path q)
+{
+ slice s=lastcut(p,q);
+ cuttings=s.after;
+ return s.before;
+}
+
+
diff --git a/Build/source/utils/asymptote/base/nopapersize.ps b/Build/source/utils/asymptote/base/nopapersize.ps
new file mode 100644
index 00000000000..67e31404744
--- /dev/null
+++ b/Build/source/utils/asymptote/base/nopapersize.ps
@@ -0,0 +1,3 @@
+@ a4size 0in 0in
+
+@ letterSize 0in 0in
diff --git a/Build/source/utils/asymptote/base/obj.asy b/Build/source/utils/asymptote/base/obj.asy
new file mode 100644
index 00000000000..02f839b594d
--- /dev/null
+++ b/Build/source/utils/asymptote/base/obj.asy
@@ -0,0 +1,104 @@
+// A module for reading simple obj files with groups.
+// Authors: Jens Schwaiger and John Bowman
+//
+// Here simple means that :
+//
+// 1) all vertex statements should come before the face statements;
+//
+// 2) face informations with respect to texture and/or normal vectors are
+// ignored;
+//
+// 3) face statements only contain positive numbers(no relative positions).
+//
+// The reading process only takes into account lines starting with "v" or
+// "f" or "g"(group).
+
+import three;
+
+struct obj {
+ surface s;
+ material[] surfacepen;
+ pen[] meshpen;
+
+ path3[][] read(string datafile, bool verbose=false) {
+ file in=word(line(input(datafile)));
+ triple[] vert;
+ path3[][] g;
+ g[0]=new path3[] ;
+ string[] G;
+ void Vertex(real x,real y ,real z) {vert.push((x,y,z));}
+ void Face(int[] vertnr, int groupnr) {
+ guide3 gh;
+ for(int i=0; i < vertnr.length; ++i)
+ gh=gh--vert[vertnr[i]-1];
+ gh=gh--cycle;
+ g[groupnr].push(gh);
+ }
+ if(verbose) write("Reading data from "+datafile+".");
+ int groupnr;
+ while(true) {
+ string[] str=in;
+ if(str.length == 0) break;
+ str=sequence(new string(int i) {return split(str[i],"/")[0];},str.length);
+ if(str[0] == "g" && str.length > 1) {
+ int tst=find(G == str[1]);
+ if(tst == -1) {
+ G.push(str[1]);
+ groupnr=G.length-1;
+ g[groupnr]=new path3[] ;
+ }
+ if(tst > -1) groupnr=tst;
+ }
+ if(str[0] == "v") Vertex((real) str[1],(real) str[2],(real) str[3]);
+ if(str[0] == "f") {
+ int[] vertnr;
+ for(int i=1; i < str.length; ++i) vertnr[i-1]=(int) str[i];
+ Face(vertnr,groupnr);
+ }
+ if(eof(in)) break;
+ }
+ close(in);
+ if(verbose) {
+ write("Number of groups: ",(string) G.length);
+ write("Groups and their names");
+ write(G);
+ write("Reading done.");
+ write("Number of faces contained in the groups: ");
+ for(int j=0; j < g.length; ++j)
+ write(G[j],": ",(string) g[j].length);
+ }
+ return g;
+ }
+
+ void operator init(path3[][] g, material[] surfacepen, pen[] meshpen) {
+ for(int i=0; i < g.length; ++i) {
+ path3[] gi=g[i];
+ for(int j=0; j < gi.length; ++j) {
+ // Treat all faces as planar to avoid subdivision cracks.
+ surface sij=surface(gi[j],planar=true);
+ s.append(sij);
+ this.surfacepen.append(array(sij.s.length,surfacepen[i]));
+ this.meshpen.append(array(sij.s.length,meshpen[i]));
+ }
+ }
+ }
+
+ void operator init(string datafile, bool verbose=false,
+ material[] surfacepen, pen[] meshpen=nullpens) {
+ operator init(read(datafile,verbose),surfacepen,meshpen);
+ }
+
+ void operator init(string datafile, bool verbose=false,
+ material surfacepen, pen meshpen=nullpen) {
+ material[] surfacepen={surfacepen};
+ pen[] meshpen={meshpen};
+ surfacepen.cyclic(true);
+ meshpen.cyclic(true);
+ operator init(read(datafile,verbose),surfacepen,meshpen);
+ }
+}
+
+void draw(picture pic=currentpicture, obj o, light light=currentlight)
+{
+ draw(pic,o.s,o.surfacepen,o.meshpen,light);
+}
diff --git a/Build/source/utils/asymptote/base/ode.asy b/Build/source/utils/asymptote/base/ode.asy
new file mode 100644
index 00000000000..5135dd9443f
--- /dev/null
+++ b/Build/source/utils/asymptote/base/ode.asy
@@ -0,0 +1,15 @@
+real euler(real y, real f(real x, real y), real a, real b=a, int n=0,
+ real h=0, bool dynamic=false, real tolmin=0, real tolmax=0)
+{
+ if(h == 0) {
+ if(b == a) return y;
+ if(n == 0) abort("Either n or h must be specified");
+ else h=(b-a)/n;
+ }
+ real x=a;
+ for(int i=0; i < n; ++i) {
+ y += h*f(x,y);
+ x += h;
+ }
+ return y;
+}
diff --git a/Build/source/utils/asymptote/base/palette.asy b/Build/source/utils/asymptote/base/palette.asy
new file mode 100644
index 00000000000..e9d3fb921db
--- /dev/null
+++ b/Build/source/utils/asymptote/base/palette.asy
@@ -0,0 +1,473 @@
+private import graph;
+
+typedef bounds range(picture pic, real min, real max);
+
+range Range(bool automin=false, real min=-infinity,
+ bool automax=false, real max=infinity)
+{
+ return new bounds(picture pic, real dmin, real dmax) {
+ // autoscale routine finds reasonable limits
+ bounds mz=autoscale(pic.scale.z.T(dmin),
+ pic.scale.z.T(dmax),
+ pic.scale.z.scale);
+ // If automin/max, use autoscale result, else
+ // if min/max is finite, use specified value, else
+ // use minimum/maximum data value
+ real pmin=automin ? pic.scale.z.Tinv(mz.min) : (finite(min) ? min : dmin);
+ real pmax=automax ? pic.scale.z.Tinv(mz.max) : (finite(max) ? max : dmax);
+ return bounds(pmin,pmax);
+ };
+}
+
+range Automatic=Range(true,true);
+range Full=Range();
+
+void image(frame f, real[][] data, pair initial, pair final, pen[] palette,
+ bool transpose=(initial.x < final.x && initial.y < final.y),
+ transform t=identity(), bool copy=true, bool antialias=false)
+{
+ _image(f,transpose ? transpose(data) : copy ? copy(data) : data,
+ initial,final,palette,t,copy=false,antialias=antialias);
+}
+
+void image(frame f, pen[][] data, pair initial, pair final,
+ bool transpose=(initial.x < final.x && initial.y < final.y),
+ transform t=identity(), bool copy=true, bool antialias=false)
+{
+ _image(f,transpose ? transpose(data) : copy ? copy(data) : data,
+ initial,final,t,copy=false,antialias=antialias);
+}
+
+// Reduce color palette to approximate range of data relative to "display"
+// range => errors of 1/palette.length in resulting color space.
+pen[] adjust(picture pic, real min, real max, real rmin, real rmax,
+ pen[] palette)
+{
+ real dmin=pic.scale.z.T(min);
+ real dmax=pic.scale.z.T(max);
+ int minindex=floor((dmin-rmin)/(rmax-rmin)*palette.length);
+ if(minindex < 0) minindex=0;
+ int maxindex=floor((dmax-rmin)/(rmax-rmin)*palette.length);
+ if(maxindex > palette.length) maxindex=palette.length;
+ if(minindex > 0 || maxindex < palette.length) {
+ pen[] newpalette;
+ for(int i=minindex; i < maxindex; ++i)
+ newpalette.push(palette[i]);
+ return newpalette;
+ }
+ return palette;
+}
+
+private real[] sequencereal;
+
+bounds image(picture pic=currentpicture, real[][] f, range range=Full,
+ pair initial, pair final, pen[] palette,
+ bool transpose=(initial.x < final.x && initial.y < final.y),
+ bool copy=true, bool antialias=false)
+{
+ if(transpose) f=transpose(f);
+ else if(copy) f=copy(f);
+ if(copy) palette=copy(palette);
+
+ real m=min(f);
+ real M=max(f);
+ bounds bounds=range(pic,m,M);
+ real rmin=pic.scale.z.T(bounds.min);
+ real rmax=pic.scale.z.T(bounds.max);
+ palette=adjust(pic,m,M,rmin,rmax,palette);
+
+ // Crop data to allowed range and scale
+ if(range != Full || pic.scale.z.scale.T != identity ||
+ pic.scale.z.postscale.T != identity) {
+ scalefcn T=pic.scale.z.T;
+ real m=bounds.min;
+ real M=bounds.max;
+ for(int i=0; i < f.length; ++i)
+ f[i]=map(new real(real x) {return T(min(max(x,m),M));},f[i]);
+ }
+
+ initial=Scale(pic,initial);
+ final=Scale(pic,final);
+
+ pic.add(new void(frame F, transform t) {
+ _image(F,f,initial,final,palette,t,copy=false,antialias=antialias);
+ },true);
+ pic.addBox(initial,final);
+ return bounds; // Return bounds used for color space
+}
+
+bounds image(picture pic=currentpicture, real f(real,real),
+ range range=Full, pair initial, pair final,
+ int nx=ngraph, int ny=nx, pen[] palette, bool antialias=false)
+{
+ // Generate data, taking scaling into account
+ real xmin=pic.scale.x.T(initial.x);
+ real xmax=pic.scale.x.T(final.x);
+ real ymin=pic.scale.y.T(initial.y);
+ real ymax=pic.scale.y.T(final.y);
+ real[][] data=new real[ny][nx];
+ for(int j=0; j < ny; ++j) {
+ real y=pic.scale.y.Tinv(interp(ymin,ymax,(j+0.5)/nx));
+ scalefcn Tinv=pic.scale.x.Tinv;
+ // Take center point of each bin
+ data[j]=sequence(new real(int i) {
+ return f(Tinv(interp(xmin,xmax,(i+0.5)/ny)),y);
+ },nx);
+ }
+ return image(pic,data,range,initial,final,palette,transpose=false,
+ copy=false,antialias=antialias);
+}
+
+void image(picture pic=currentpicture, pen[][] data, pair initial, pair final,
+ bool transpose=(initial.x < final.x && initial.y < final.y),
+ bool copy=true, bool antialias=false)
+{
+ if(transpose) data=transpose(data);
+ else if(copy) data=copy(data);
+
+ initial=Scale(pic,initial);
+ final=Scale(pic,final);
+
+ pic.add(new void(frame F, transform t) {
+ _image(F,data,initial,final,t,copy=false,antialias=antialias);
+ },true);
+ pic.addBox(initial,final);
+}
+
+bounds image(picture pic=currentpicture, pair[] z, real[] f,
+ range range=Full, pen[] palette)
+{
+ if(z.length != f.length)
+ abort("z and f arrays have different lengths");
+
+ real m=min(f);
+ real M=max(f);
+ bounds bounds=range(pic,m,M);
+ real rmin=pic.scale.z.T(bounds.min);
+ real rmax=pic.scale.z.T(bounds.max);
+
+ palette=adjust(pic,m,M,rmin,rmax,palette);
+
+ // Crop data to allowed range and scale
+ if(range != Full || pic.scale.z.scale.T != identity ||
+ pic.scale.z.postscale.T != identity) {
+ scalefcn T=pic.scale.z.T;
+ real m=bounds.min;
+ real M=bounds.max;
+ f=map(new real(real x) {return T(min(max(x,m),M));},f);
+ }
+
+ int[] edges={0,0,1};
+ int N=palette.length-1;
+
+ int[][] trn=triangulate(z);
+ real step=rmax == rmin ? 0.0 : N/(rmax-rmin);
+ for(int i=0; i < trn.length; ++i) {
+ int[] trni=trn[i];
+ int i0=trni[0], i1=trni[1], i2=trni[2];
+ pen color(int i) {return palette[round((f[i]-rmin)*step)];}
+ gouraudshade(pic,z[i0]--z[i1]--z[i2]--cycle,
+ new pen[] {color(i0),color(i1),color(i2)},edges);
+ }
+ return bounds; // Return bounds used for color space
+}
+
+bounds image(picture pic=currentpicture, real[] x, real[] y, real[] f,
+ range range=Full, pen[] palette)
+{
+ int n=x.length;
+ if(n != y.length)
+ abort("x and y arrays have different lengths");
+
+ pair[] z=sequence(new pair(int i) {return (x[i],y[i]);},n);
+ return image(pic,z,f,range,palette);
+}
+
+// Construct a pen[] array from f using the specified palette.
+pen[] palette(real[] f, pen[] palette)
+{
+ real Min=min(f);
+ real Max=max(f);
+ if(palette.length == 0) return new pen[];
+ real step=Max == Min ? 0.0 : (palette.length-1)/(Max-Min);
+ return sequence(new pen(int i) {return palette[round((f[i]-Min)*step)];},
+ f.length);
+}
+
+// Construct a pen[][] array from f using the specified palette.
+pen[][] palette(real[][] f, pen[] palette)
+{
+ real Min=min(f);
+ real Max=max(f);
+ int n=f.length;
+ int m=n > 0 ? f[0].length : 0;
+ pen[][] p=new pen[n][m];
+ real step=(Max == Min) ? 0.0 : (palette.length-1)/(Max-Min);
+ for(int i=0; i < n; ++i) {
+ real[] fi=f[i];
+ p[i]=sequence(new pen(int j) {return palette[round((fi[j]-Min)*step)];},m);
+ }
+ return p;
+}
+
+typedef ticks paletteticks(int sign=-1);
+
+paletteticks PaletteTicks(Label format="", ticklabel ticklabel=null,
+ bool beginlabel=true, bool endlabel=true,
+ int N=0, int n=0, real Step=0, real step=0,
+ pen pTick=nullpen, pen ptick=nullpen)
+{
+ return new ticks(int sign=-1) {
+ format.align(sign > 0 ? RightSide : LeftSide);
+ return Ticks(sign,format,ticklabel,beginlabel,endlabel,N,n,Step,step,
+ true,true,extend=true,pTick,ptick);
+ };
+}
+
+paletteticks PaletteTicks=PaletteTicks();
+
+void palette(picture pic=currentpicture, Label L="", bounds bounds,
+ pair initial, pair final, axis axis=Right, pen[] palette,
+ pen p=currentpen, paletteticks ticks=PaletteTicks,
+ bool copy=true, bool antialias=false)
+{
+ real initialz=pic.scale.z.T(bounds.min);
+ real finalz=pic.scale.z.T(bounds.max);
+ bounds mz=autoscale(initialz,finalz,pic.scale.z.scale);
+
+ axisT axis;
+ axis(pic,axis);
+ real angle=degrees(axis.align.dir);
+
+ initial=Scale(pic,initial);
+ final=Scale(pic,final);
+
+ pair lambda=final-initial;
+ bool vertical=(floor((angle+45)/90) % 2 == 0);
+ pair perp,par;
+
+ if(vertical) {perp=E; par=N;} else {perp=N; par=E;}
+
+ path g=(final-dot(lambda,par)*par)--final;
+ path g2=initial--final-dot(lambda,perp)*perp;
+
+ if(sgn(dot(lambda,perp)*dot(axis.align.dir,perp)) == -1) {
+ path tmp=g;
+ g=g2;
+ g2=tmp;
+ }
+
+ if(copy) palette=copy(palette);
+ Label L=L.copy();
+ if(L.defaultposition) L.position(0.5);
+ L.align(axis.align);
+ L.p(p);
+ if(vertical && L.defaulttransform) {
+ frame f;
+ add(f,Label(L.s,(0,0),L.p));
+ if(length(max(f)-min(f)) > ylabelwidth*fontsize(L.p))
+ L.transform(rotate(90));
+ }
+ real[][] pdata={sequence(palette.length)};
+ if(vertical) pdata=transpose(pdata);
+
+ pic.add(new void(frame f, transform t) {
+ _image(f,pdata,initial,final,palette,t,copy=false,antialias=antialias);
+ },true);
+
+ ticklocate locate=ticklocate(initialz,finalz,pic.scale.z,mz.min,mz.max);
+ axis(pic,L,g,g2,p,ticks(sgn(axis.side.x*dot(lambda,par))),locate,mz.divisor,
+ true);
+
+ pic.add(new void(frame f, transform t) {
+ pair Z0=t*initial;
+ pair Z1=t*final;
+ draw(f,Z0--(Z0.x,Z1.y)--Z1--(Z1.x,Z0.y)--cycle,p);
+ },true);
+
+ pic.addBox(initial,final);
+}
+
+// A grayscale palette
+pen[] Grayscale(int NColors=256)
+{
+ real ninv=1.0/(NColors-1.0);
+ return sequence(new pen(int i) {return gray(i*ninv);},NColors);
+}
+
+// A color wheel palette
+pen[] Wheel(int NColors=32766)
+{
+ if(settings.gray) return Grayscale(NColors);
+
+ int nintervals=6;
+ int n=quotient(NColors,nintervals);
+
+ pen[] Palette;
+ if(n == 0) return Palette;
+
+ Palette=new pen[n*nintervals];
+ real ninv=1.0/n;
+
+ for(int i=0; i < n; ++i) {
+ real ininv=i*ninv;
+ real ininv1=1.0-ininv;
+ Palette[i]=rgb(1.0,0.0,ininv);
+ Palette[n+i]=rgb(ininv1,0.0,1.0);
+ Palette[2n+i]=rgb(0.0,ininv,1.0);
+ Palette[3n+i]=rgb(0.0,1.0,ininv1);
+ Palette[4n+i]=rgb(ininv,1.0,0.0);
+ Palette[5n+i]=rgb(1.0,ininv1,0.0);
+ }
+ return Palette;
+}
+
+// A rainbow palette
+pen[] Rainbow(int NColors=32766)
+{
+ if(settings.gray) return Grayscale(NColors);
+
+ int offset=1;
+ int nintervals=5;
+ int n=quotient(NColors-1,nintervals);
+
+ pen[] Palette;
+ if(n == 0) return Palette;
+
+ Palette=new pen[n*nintervals+offset];
+ real ninv=1.0/n;
+
+ for(int i=0; i < n; ++i) {
+ real ininv=i*ninv;
+ real ininv1=1.0-ininv;
+ Palette[i]=rgb(ininv1,0.0,1.0);
+ Palette[n+i]=rgb(0.0,ininv,1.0);
+ Palette[2n+i]=rgb(0.0,1.0,ininv1);
+ Palette[3n+i]=rgb(ininv,1.0,0.0);
+ Palette[4n+i]=rgb(1.0,ininv1,0.0);
+ }
+ Palette[4n+n]=rgb(1.0,0.0,0.0);
+
+ return Palette;
+}
+
+private pen[] BWRainbow(int NColors, bool two)
+{
+ if(settings.gray) return Grayscale(NColors);
+
+ int offset=1;
+ int nintervals=6;
+ int divisor=3;
+
+ if(two) nintervals += 6;
+
+ int num=NColors-offset;
+ int n=quotient(num,nintervals*divisor)*divisor;
+ NColors=n*nintervals+offset;
+
+ pen[] Palette;
+ if(n == 0) return Palette;
+
+ Palette=new pen[NColors];
+ real ninv=1.0/n;
+
+ int k=0;
+
+ if(two) {
+ for(int i=0; i < n; ++i) {
+ real ininv=i*ninv;
+ real ininv1=1.0-ininv;
+ Palette[i]=rgb(ininv1,0.0,1.0);
+ Palette[n+i]=rgb(0.0,ininv,1.0);
+ Palette[2n+i]=rgb(0.0,1.0,ininv1);
+ Palette[3n+i]=rgb(ininv,1.0,0.0);
+ Palette[4n+i]=rgb(1.0,ininv1,0.0);
+ Palette[5n+i]=rgb(1.0,0.0,ininv);
+ }
+ k += 6n;
+ }
+
+ if(two)
+ for(int i=0; i < n; ++i)
+ Palette[k+i]=rgb(1.0-i*ninv,0.0,1.0);
+ else {
+ int n3=quotient(n,3);
+ int n23=2*n3;
+ real third=n3*ninv;
+ real twothirds=n23*ninv;
+ for(int i=0; i < n3; ++i) {
+ real ininv=i*ninv;
+ Palette[k+i]=rgb(ininv,0.0,ininv);
+ Palette[k+n3+i]=rgb(third,0.0,third+ininv);
+ Palette[k+n23+i]=rgb(third-ininv,0.0,twothirds+ininv);
+ }
+ }
+ k += n;
+
+ for(int i=0; i < n; ++i) {
+ real ininv=i*ninv;
+ real ininv1=1.0-ininv;
+ Palette[k+i]=rgb(0.0,ininv,1.0);
+ Palette[k+n+i]=rgb(0.0,1.0,ininv1);
+ Palette[k+2n+i]=rgb(ininv,1.0,0.0);
+ Palette[k+3n+i]=rgb(1.0,ininv1,0.0);
+ Palette[k+4n+i]=rgb(1.0,ininv,ininv);
+ }
+ Palette[k+5n]=rgb(1.0,1.0,1.0);
+
+ return Palette;
+}
+
+// Quantize palette to exactly n values
+pen[] quantize(pen[] Palette, int n)
+{
+ if(Palette.length == 0) abort("cannot quantize empty palette");
+ if(n <= 1) abort("palette must contain at least two pens");
+ real step=(Palette.length-1)/(n-1);
+ return sequence(new pen(int i) {
+ return Palette[round(i*step)];
+ },n);
+}
+
+// A rainbow palette tapering off to black/white at the spectrum ends,
+pen[] BWRainbow(int NColors=32761)
+{
+ return BWRainbow(NColors,false);
+}
+
+// A double rainbow palette tapering off to black/white at the spectrum ends,
+// with a linearly scaled intensity.
+pen[] BWRainbow2(int NColors=32761)
+{
+ pen[] Palette=BWRainbow(NColors,true);
+ int n=Palette.length;
+ real ninv=1.0/n;
+ for(int i=0; i < n; ++i)
+ Palette[i]=i*ninv*Palette[i];
+ return Palette;
+}
+
+//A palette varying linearly over the specified array of pens, using
+// NColors in each interpolation interval.
+pen[] Gradient(int NColors=256 ... pen[] p)
+{
+ pen[] P;
+ if(p.length < 2) abort("at least 2 colors must be specified");
+ real step=NColors > 1 ? (1/(NColors-1)) : 1;
+ for(int i=0; i < p.length-1; ++i) {
+ pen begin=p[i];
+ pen end=p[i+1];
+ P.append(sequence(new pen(int j) {
+ return interp(begin,end,j*step);
+ },NColors));
+ }
+ return P;
+}
+
+pen[] cmyk(pen[] Palette)
+{
+ int n=Palette.length;
+ for(int i=0; i < n; ++i)
+ Palette[i]=cmyk(Palette[i]);
+ return Palette;
+}
diff --git a/Build/source/utils/asymptote/base/patterns.asy b/Build/source/utils/asymptote/base/patterns.asy
new file mode 100644
index 00000000000..56fa3bf4a24
--- /dev/null
+++ b/Build/source/utils/asymptote/base/patterns.asy
@@ -0,0 +1,102 @@
+// Create a tiling named name from picture pic
+// with optional left-bottom margin lb and right-top margin rt.
+frame tiling(string name, picture pic, pair lb=0, pair rt=0)
+{
+ frame tiling;
+ frame f=pic.fit(identity());
+ pair pmin=min(f)-lb;
+ pair pmax=max(f)+rt;
+ string s="%.6f";
+ postscript(tiling,"<< /PaintType 1 /PatternType 1 /TilingType 1
+/BBox ["+format(s,pmin.x,"C")+" "+format(s,pmin.y,"C")+" "+
+ format(s,pmax.x,"C")+" "+format(s,pmax.y,"C")+"]
+/XStep "+format(s,pmax.x-pmin.x,"C")+"
+/YStep "+format(s,pmax.y-pmin.y,"C")+"
+/PaintProc {pop");
+ add(tiling,f);
+ postscript(tiling,"} >>
+ matrix makepattern
+/"+name+" exch def");
+ return tiling;
+}
+
+// Add to frame preamble a tiling name constructed from picture pic
+// with optional left-bottom margin lb and right-top margin rt.
+void add(string name, picture pic, pair lb=0, pair rt=0)
+{
+ add(currentpatterns,tiling(name,pic,lb,rt));
+}
+
+picture tile(real Hx=5mm, real Hy=0, pen p=currentpen,
+ filltype filltype=NoFill)
+{
+ picture tiling;
+ if(Hy == 0) Hy=Hx;
+ path tile=box((0,0),(Hx,Hy));
+ tiling.add(new void (frame f, transform t) {
+ filltype.fill(f,t*tile,p);
+ });
+ clip(tiling,tile);
+ return tiling;
+}
+
+picture checker(real Hx=5mm, real Hy=0, pen p=currentpen)
+{
+ picture tiling;
+ if(Hy == 0) Hy=Hx;
+ path tile=box((0,0),(Hx,Hy));
+ fill(tiling,tile,p);
+ fill(tiling,shift(Hx,Hy)*tile,p);
+ clip(tiling,box((0,0),(2Hx,2Hy)));
+ return tiling;
+}
+
+picture brick(real Hx=5mm, real Hy=0, pen p=currentpen)
+{
+ picture tiling;
+ if(Hy == 0) Hy=Hx/2;
+ path tile=box((0,0),(Hx,Hy));
+ draw(tiling,tile,p);
+ draw(tiling,(Hx/2,Hy)--(Hx/2,2Hy),p);
+ draw(tiling,(0,2Hy)--(Hx,2Hy),p);
+ clip(tiling,box((0,0),(Hx,2Hy)));
+ return tiling;
+}
+
+real hatchepsilon=1e-4;
+picture hatch(real H=5mm, pair dir=NE, pen p=currentpen)
+{
+ picture tiling;
+ real theta=angle(dir);
+ real s=sin(theta);
+ real c=cos(theta);
+ if(abs(s) <= hatchepsilon) {
+ path g=(0,0)--(H,0);
+ draw(tiling,g,p);
+ draw(tiling,shift(0,H)*g,p);
+ clip(tiling,scale(H)*unitsquare);
+ } else if(abs(c) <= hatchepsilon) {
+ path g=(0,0)--(0,H);
+ draw(tiling,g,p);
+ draw(tiling,shift(H,0)*g,p);
+ clip(tiling,scale(H)*unitsquare);
+ } else {
+ real h=H/s;
+ real y=H/c;
+ path g=(0,0)--(h,y);
+ draw(tiling,g,p);
+ draw(tiling,shift(-h/2,y/2)*g,p);
+ draw(tiling,shift(h/2,-y/2)*g,p);
+ clip(tiling,box((0,0),(h,y)));
+ }
+ return tiling;
+}
+
+picture crosshatch(real H=5mm, pen p=currentpen)
+{
+ picture tiling;
+ add(tiling,hatch(H,p));
+ add(tiling,shift(H*sqrt(2))*rotate(90)*hatch(H,p));
+ return tiling;
+}
+
diff --git a/Build/source/utils/asymptote/base/plain.asy b/Build/source/utils/asymptote/base/plain.asy
new file mode 100644
index 00000000000..a918a6bdc09
--- /dev/null
+++ b/Build/source/utils/asymptote/base/plain.asy
@@ -0,0 +1,270 @@
+/*****
+ * plain.asy
+ * Andy Hammerlindl and John Bowman 2004/08/19
+ *
+ * A package for general purpose drawing, with automatic sizing of pictures.
+ *
+ *****/
+
+access settings;
+
+if(settings.command != "") {
+ string s=settings.command;
+ settings.command="";
+ settings.multipleView=settings.batchView=settings.interactiveView;
+ _eval(s+";",false,true);
+ exit();
+}
+
+include plain_constants;
+
+access version;
+if(version.VERSION != VERSION) {
+ write(stdout,"warning: using possibly incompatible version "+
+ version.VERSION+" of plain.asy"+'\n');
+}
+
+include plain_pens;
+include plain_paths;
+include plain_filldraw;
+include plain_margins;
+include plain_picture;
+include plain_Label;
+include plain_shipout;
+include plain_arcs;
+include plain_boxes;
+include plain_strings;
+include plain_markers;
+include plain_arrows;
+include plain_debugger;
+
+typedef void exitfcn();
+
+bool needshipout() {
+ return !shipped && !currentpicture.empty();
+}
+
+void updatefunction()
+{
+ if(!currentpicture.uptodate) shipout();
+}
+
+void exitfunction()
+{
+ if(needshipout()) shipout();
+}
+
+atupdate(updatefunction);
+atexit(exitfunction);
+
+// A restore thunk is a function, that when called, restores the graphics state
+// to what it was when the restore thunk was created.
+typedef void restoreThunk();
+typedef restoreThunk saveFunction();
+saveFunction[] saveFunctions={};
+
+// When save is called, this will be redefined to do the corresponding restore.
+void restore()
+{
+ write("warning: restore called with no matching save");
+}
+
+void addSaveFunction(saveFunction s)
+{
+ saveFunctions.push(s);
+}
+
+restoreThunk buildRestoreThunk()
+{
+ // Call the save functions in reverse order, storing their restore thunks.
+ restoreThunk[] thunks={};
+ for (int i=saveFunctions.length-1; i >= 0; --i)
+ thunks.push(saveFunctions[i]());
+
+ return new void() {
+ // Call the restore thunks in an order matching the saves.
+ for (int i=thunks.length-1; i >= 0; --i)
+ thunks[i]();
+ };
+}
+
+// Add the default save function.
+addSaveFunction(new restoreThunk () {
+ pen defaultpen=defaultpen();
+ pen p=currentpen;
+ picture pic=currentpicture.copy();
+ restoreThunk r=restore;
+ return new void() {
+ defaultpen(defaultpen);
+ currentpen=p;
+ currentpicture=pic;
+ currentpicture.uptodate=false;
+ restore=r;
+ };
+ });
+
+// Save the current state, so that restore will put things back in that state.
+restoreThunk save()
+{
+ return restore=buildRestoreThunk();
+}
+
+void restoredefaults()
+{
+ write("warning: restoredefaults called with no matching savedefaults");
+}
+
+restoreThunk buildRestoreDefaults()
+{
+ pen defaultpen=defaultpen();
+ exitfcn atupdate=atupdate();
+ exitfcn atexit=atexit();
+ restoreThunk r=restoredefaults;
+ return new void() {
+ defaultpen(defaultpen);
+ atupdate(atupdate);
+ atexit(atexit);
+ restoredefaults=r;
+ };
+}
+
+// Save the current state, so that restore will put things back in that state.
+restoreThunk savedefaults()
+{
+ return restoredefaults=buildRestoreDefaults();
+}
+
+void initdefaults()
+{
+ savedefaults();
+ resetdefaultpen();
+ atupdate(null);
+ atexit(null);
+}
+
+// Return the sequence n,...m
+int[] sequence(int n, int m)
+{
+ return sequence(new int(int x){return x;},m-n+1)+n;
+}
+
+int[] reverse(int n) {return sequence(new int(int x){return n-1-x;},n);}
+bool[] reverse(bool[] a) {return a[reverse(a.length)];}
+int[] reverse(int[] a) {return a[reverse(a.length)];}
+real[] reverse(real[] a) {return a[reverse(a.length)];}
+pair[] reverse(pair[] a) {return a[reverse(a.length)];}
+triple[] reverse(triple[] a) {return a[reverse(a.length)];}
+string[] reverse(string[] a) {return a[reverse(a.length)];}
+
+// Return a uniform partition dividing [a,b] into n subintervals.
+real[] uniform(real a, real b, int n)
+{
+ if(n <= 0) return new real[];
+ return a+(b-a)/n*sequence(n+1);
+}
+
+void eval(string s, bool embedded=false)
+{
+ if(!embedded) initdefaults();
+ _eval(s+";",embedded);
+ if(!embedded) restoredefaults();
+}
+
+void eval(code s, bool embedded=false)
+{
+ if(!embedded) initdefaults();
+ _eval(s,embedded);
+ if(!embedded) restoredefaults();
+}
+
+// Evaluate user command line option.
+void usersetting()
+{
+ eval(settings.user,true);
+}
+
+// Conditionally process each file name in array s in a new environment.
+void asy(string format, bool overwrite=false ... string[] s)
+{
+ for(int i=0; i < s.length; ++i) {
+ string f=s[i];
+ int n=rfind(f,".asy");
+ if(n != -1) f=erase(f,n,-1);
+ if(overwrite || error(input(f+"."+format,check=false))) {
+ string outformat=settings.outformat;
+ bool interactiveView=settings.interactiveView;
+ bool batchView=settings.batchView;
+ settings.outformat=format;
+ settings.interactiveView=false;
+ settings.batchView=false;
+ eval("defaultfilename=\""+f+"\"; import \""+f+
+ "\" as dummy; exitfunction()");
+ settings.outformat=outformat;
+ settings.interactiveView=interactiveView;
+ settings.batchView=batchView;
+ }
+ }
+}
+
+void beep() {
+ write('\7',flush);
+}
+
+struct processtime {
+ real user;
+ real system;
+}
+
+struct cputime {
+ processtime parent;
+ processtime child;
+ processtime change;
+}
+
+cputime cputime()
+{
+ static processtime last;
+ real [] a=_cputime();
+ cputime cputime;
+ cputime.parent.user=a[0];
+ cputime.parent.system=a[1];
+ cputime.child.user=a[2];
+ cputime.child.system=a[3];
+ real user=a[0]+a[2];
+ real system=a[1]+a[3];
+ cputime.change.user=user-last.user;
+ cputime.change.system=system-last.system;
+ last.user=user;
+ last.system=system;
+ return cputime;
+}
+
+string cputimeformat="%#.2f";
+
+void write(file file, string s="", cputime c, string format=cputimeformat,
+ suffix suffix=none)
+{
+ write(file,s,
+ format(format,c.change.user)+"u "+
+ format(format,c.change.system)+"s "+
+ format(format,c.parent.user+c.child.user)+"U "+
+ format(format,c.parent.system+c.child.system)+"S ",suffix);
+}
+
+void write(string s="", cputime c, string format=cputimeformat,
+ suffix suffix=endl)
+{
+ write(stdout,s,c,format,suffix);
+}
+
+if(settings.autoimport != "") {
+ string s=settings.autoimport;
+ settings.autoimport="";
+ eval("import \""+s+"\" as dummy",true);
+ shipped=false;
+ atupdate(updatefunction);
+ atexit(exitfunction);
+ settings.autoimport=s;
+}
+
+cputime();
diff --git a/Build/source/utils/asymptote/base/plain_Label.asy b/Build/source/utils/asymptote/base/plain_Label.asy
new file mode 100644
index 00000000000..72f924224d4
--- /dev/null
+++ b/Build/source/utils/asymptote/base/plain_Label.asy
@@ -0,0 +1,601 @@
+// A rotation in the direction dir limited to [-90,90]
+// This is useful for rotating text along a line in the direction dir.
+transform rotate(explicit pair dir)
+{
+ real angle=degrees(dir);
+ if(angle > 90 && angle < 270) angle -= 180;
+ return rotate(angle);
+}
+
+real angle(transform t)
+{
+ pair z=(2t.xx*t.yy,t.yx*t.yy-t.xx*t.xy);
+ if(t.xx < 0) z=-z;
+ return degrees(z,warn=false);
+}
+
+transform rotation(transform t)
+{
+ return rotate(angle(t));
+}
+
+transform scaleless(transform t)
+{
+ real a=t.xx, b=t.xy, c=t.yx, d=t.yy;
+ real arg=(a-d)^2+4b*c;
+ pair delta=arg >= 0 ? sqrt(arg) : I*sqrt(-arg);
+ real trace=a+d;
+ pair l1=0.5(trace+delta);
+ pair l2=0.5(trace-delta);
+
+ if(abs(delta) < sqrtEpsilon*max(abs(l1),abs(l2))) {
+ real s=abs(0.5trace);
+ return (s != 0) ? scale(1/s)*t : t;
+ }
+
+ if(abs(l1-d) < abs(l2-d)) {pair temp=l1; l1=l2; l2=temp;}
+
+ pair dot(pair[] u, pair[] v) {return conj(u[0])*v[0]+conj(u[1])*v[1];}
+
+ pair[] unit(pair[] u) {
+ real norm2=abs(u[0])^2+abs(u[1])^2;
+ return norm2 != 0 ? u/sqrt(norm2) : u;
+ }
+
+ pair[] u={l1-d,b};
+ pair[] v={c,l2-a};
+ u=unit(u);
+ pair d=dot(u,u);
+ if(d != 0) v -= dot(u,v)/d*u;
+ v=unit(v);
+
+ pair[][] U={{u[0],v[0]},{u[1],v[1]}};
+ pair[][] A={{a,b},{c,d}};
+
+ pair[][] operator *(pair[][] a, pair[][] b) {
+ pair[][] c=new pair[2][2];
+ for(int i=0; i < 2; ++i) {
+ for(int j=0; j < 2; ++j) {
+ c[i][j]=a[i][0]*b[0][j]+a[i][1]*b[1][j];
+ }
+ }
+ return c;
+ }
+
+ pair[][] conj(pair[][] a) {
+ pair[][] c=new pair[2][2];
+ for(int i=0; i < 2; ++i) {
+ for(int j=0; j < 2; ++j) {
+ c[i][j]=conj(a[j][i]);
+ }
+ }
+ return c;
+ }
+
+ A=conj(U)*A*U;
+
+ real D=abs(A[0][0]);
+ if(D != 0) A[0][0] /= D;
+ D=abs(A[1][1]);
+ if(D != 0) A[1][1] /= D;
+
+ A=U*A*conj(U);
+ return (0,0,A[0][0].x,A[0][1].x,A[1][0].x,A[1][1].x);
+}
+
+struct align {
+ pair dir;
+ triple dir3;
+ bool relative=false;
+ bool default=true;
+ bool is3D=false;
+ void init(pair dir=0, bool relative=false, bool default=false) {
+ this.dir=dir;
+ this.relative=relative;
+ this.default=default;
+ is3D=false;
+ }
+ void init(triple dir=(0,0,0), bool relative=false, bool default=false) {
+ this.dir3=dir;
+ this.relative=relative;
+ this.default=default;
+ is3D=true;
+ }
+ align copy() {
+ align align=new align;
+ align.init(dir,relative,default);
+ align.dir3=dir3;
+ align.is3D=is3D;
+ return align;
+ }
+ void align(align align) {
+ if(!align.default) {
+ bool is3D=align.is3D;
+ init(align.dir,align.relative);
+ dir3=align.dir3;
+ this.is3D=is3D;
+ }
+ }
+ void align(align align, align default) {
+ align(align);
+ if(this.default) {
+ init(default.dir,default.relative,default.default);
+ dir3=default.dir3;
+ is3D=default.is3D;
+ }
+ }
+ void write(file file=stdout, suffix suffix=endl) {
+ if(!default) {
+ if(relative) {
+ write(file,"Relative(");
+ if(is3D)
+ write(file,dir3);
+ else
+ write(file,dir);
+ write(file,")",suffix);
+ } else {
+ if(is3D)
+ write(file,dir3,suffix);
+ else
+ write(file,dir,suffix);
+ }
+ }
+ }
+ bool Center() {
+ return relative && (is3D ? dir3 == (0,0,0) : dir == 0);
+ }
+}
+
+struct side {
+ pair align;
+}
+
+side Relative(explicit pair align)
+{
+ side s;
+ s.align=align;
+ return s;
+}
+
+restricted side NoSide;
+restricted side LeftSide=Relative(W);
+restricted side Center=Relative((0,0));
+restricted side RightSide=Relative(E);
+
+side operator * (real x, side s)
+{
+ side S;
+ S.align=x*s.align;
+ return S;
+}
+
+align operator cast(pair dir) {align A; A.init(dir,false); return A;}
+align operator cast(triple dir) {align A; A.init(dir,false); return A;}
+align operator cast(side side) {align A; A.init(side.align,true); return A;}
+align NoAlign;
+
+void write(file file=stdout, align align, suffix suffix=endl)
+{
+ align.write(file,suffix);
+}
+
+struct position {
+ pair position;
+ bool relative;
+}
+
+position Relative(real position)
+{
+ position p;
+ p.position=position;
+ p.relative=true;
+ return p;
+}
+
+restricted position BeginPoint=Relative(0);
+restricted position MidPoint=Relative(0.5);
+restricted position EndPoint=Relative(1);
+
+position operator cast(pair x) {position P; P.position=x; return P;}
+position operator cast(real x) {return (pair) x;}
+position operator cast(int x) {return (pair) x;}
+
+pair operator cast(position P) {return P.position;}
+
+typedef transform embed(transform);
+transform Shift(transform t) {return identity();}
+transform Rotate(transform t) {return rotation(t);}
+transform Slant(transform t) {return scaleless(t);}
+transform Scale(transform t) {return t;}
+
+embed Rotate(pair z) {
+ return new transform(transform t) {return rotate(degrees(shiftless(t)*z));};
+}
+
+struct Label {
+ string s,size;
+ position position;
+ bool defaultposition=true;
+ align align;
+ pen p=nullpen;
+ transform T;
+ transform3 T3=identity(4);
+ bool defaulttransform=true;
+ bool defaulttransform3=true;
+ embed embed=Rotate; // Shift, Rotate, Slant, or Scale with embedded picture
+ filltype filltype=NoFill;
+
+ void init(string s="", string size="", position position=0,
+ bool defaultposition=true, align align=NoAlign, pen p=nullpen,
+ transform T=identity(), transform3 T3=identity4,
+ bool defaulttransform=true, bool defaulttransform3=true,
+ embed embed=Rotate, filltype filltype=NoFill) {
+ this.s=s;
+ this.size=size;
+ this.position=position;
+ this.defaultposition=defaultposition;
+ this.align=align.copy();
+ this.p=p;
+ this.T=T;
+ this.T3=copy(T3);
+ this.defaulttransform=defaulttransform;
+ this.defaulttransform3=defaulttransform3;
+ this.embed=embed;
+ this.filltype=filltype;
+ }
+
+ void initalign(string s="", string size="", align align, pen p=nullpen,
+ embed embed=Rotate, filltype filltype=NoFill) {
+ init(s,size,align,p,embed,filltype);
+ }
+
+ void transform(transform T) {
+ this.T=T;
+ defaulttransform=false;
+ }
+
+ void transform3(transform3 T) {
+ this.T3=copy(T);
+ defaulttransform3=false;
+ }
+
+ Label copy(transform3 T3=this.T3) {
+ Label L=new Label;
+ L.init(s,size,position,defaultposition,align,p,T,T3,defaulttransform,
+ defaulttransform3,embed,filltype);
+ return L;
+ }
+
+ void position(position pos) {
+ this.position=pos;
+ defaultposition=false;
+ }
+
+ void align(align a) {
+ align.align(a);
+ }
+ void align(align a, align default) {
+ align.align(a,default);
+ }
+
+ void p(pen p0) {
+ if(this.p == nullpen) this.p=p0;
+ }
+
+ void filltype(filltype filltype0) {
+ if(this.filltype == NoFill) this.filltype=filltype0;
+ }
+
+ void label(frame f, transform t=identity(), pair position, pair align) {
+ pen p0=p == nullpen ? currentpen : p;
+ align=length(align)*unit(scaleless(shiftless(t))*align);
+ label(f,s,size,embed(t)*shiftless(T),
+ t*position+align*labelmargin(p0)+shift(T)*0,align,p0);
+ }
+
+ void out(frame f, transform t=identity(), pair position=position.position,
+ pair align=align.dir) {
+ if(filltype == NoFill)
+ label(f,t,position,align);
+ else {
+ frame d;
+ label(d,t,position,align);
+ add(f,d,filltype);
+ }
+ }
+
+ void label(picture pic=currentpicture, pair position, pair align) {
+ if(s == "") return;
+ pic.add(new void (frame f, transform t) {
+ out(f,t,position,align);
+ },true);
+ frame f;
+ // Create a picture with label at the origin to extract its bbox truesize.
+ label(f,(0,0),align);
+ pic.addBox(position,position,min(f),max(f));
+ }
+
+ void out(picture pic=currentpicture) {
+ label(pic,position.position,align.dir);
+ }
+
+ void out(picture pic=currentpicture, path g) {
+ bool relative=position.relative;
+ real position=position.position.x;
+ pair Align=align.dir;
+ bool alignrelative=align.relative;
+ if(defaultposition) {relative=true; position=0.5;}
+ if(relative) position=reltime(g,position);
+ if(align.default) {
+ alignrelative=true;
+ Align=position <= sqrtEpsilon ? S :
+ position >= length(g)-sqrtEpsilon ? N : E;
+ }
+
+ pic.add(new void (frame f, transform t) {
+ out(f,t,point(g,position),
+ alignrelative ? -Align*dir(t*g,position)*I : Align);
+ },true);
+ }
+
+ void write(file file=stdout, suffix suffix=endl) {
+ write(file,"\""+s+"\"");
+ if(!defaultposition) write(file,", position=",position.position);
+ if(!align.default) write(file,", align=");
+ write(file,align);
+ if(p != nullpen) write(file,", pen=",p);
+ if(!defaulttransform)
+ write(file,", transform=",T);
+ if(!defaulttransform3)
+ write(file,T3);
+ write(file,"",suffix);
+ }
+
+ real relative() {
+ return defaultposition ? 0.5 : position.position.x;
+ };
+
+ real relative(path g) {
+ return position.relative ? reltime(g,relative()) : relative();
+ };
+}
+
+Label Label;
+
+void add(frame f, transform t=identity(), Label L)
+{
+ L.out(f,t);
+}
+
+void add(picture pic=currentpicture, Label L)
+{
+ L.out(pic);
+}
+
+Label operator * (transform t, Label L)
+{
+ Label tL=L.copy();
+ tL.align.dir=L.align.dir;
+ tL.transform(t*L.T);
+ return tL;
+}
+
+Label operator * (transform3 t, Label L)
+{
+ Label tL=L.copy(t*L.T3);
+ tL.align.dir=L.align.dir;
+ tL.defaulttransform3=false;
+ return tL;
+}
+
+Label Label(string s, string size="", explicit position position,
+ align align=NoAlign, pen p=nullpen, embed embed=Rotate,
+ filltype filltype=NoFill)
+{
+ Label L;
+ L.init(s,size,position,false,align,p,embed,filltype);
+ return L;
+}
+
+Label Label(string s, string size="", pair position, align align=NoAlign,
+ pen p=nullpen, embed embed=Rotate, filltype filltype=NoFill)
+{
+ return Label(s,size,(position) position,align,p,embed,filltype);
+}
+
+Label Label(explicit pair position, align align=NoAlign, pen p=nullpen,
+ embed embed=Rotate, filltype filltype=NoFill)
+{
+ return Label((string) position,position,align,p,embed,filltype);
+}
+
+Label Label(string s="", string size="", align align=NoAlign, pen p=nullpen,
+ embed embed=Rotate, filltype filltype=NoFill)
+{
+ Label L;
+ L.initalign(s,size,align,p,embed,filltype);
+ return L;
+}
+
+Label Label(Label L, align align=NoAlign, pen p=nullpen, embed embed=L.embed,
+ filltype filltype=NoFill)
+{
+ Label L=L.copy();
+ L.align(align);
+ L.p(p);
+ L.embed=embed;
+ L.filltype(filltype);
+ return L;
+}
+
+Label Label(Label L, explicit position position, align align=NoAlign,
+ pen p=nullpen, embed embed=L.embed, filltype filltype=NoFill)
+{
+ Label L=Label(L,align,p,embed,filltype);
+ L.position(position);
+ return L;
+}
+
+Label Label(Label L, pair position, align align=NoAlign,
+ pen p=nullpen, embed embed=L.embed, filltype filltype=NoFill)
+{
+ return Label(L,(position) position,align,p,embed,filltype);
+}
+
+void write(file file=stdout, Label L, suffix suffix=endl)
+{
+ L.write(file,suffix);
+}
+
+void label(frame f, Label L, pair position, align align=NoAlign,
+ pen p=currentpen, filltype filltype=NoFill)
+{
+ add(f,Label(L,position,align,p,filltype));
+}
+
+void label(frame f, Label L, align align=NoAlign,
+ pen p=currentpen, filltype filltype=NoFill)
+{
+ add(f,Label(L,L.position,align,p,filltype));
+}
+
+void label(picture pic=currentpicture, Label L, pair position,
+ align align=NoAlign, pen p=nullpen, filltype filltype=NoFill)
+{
+ Label L=Label(L,position,align,p,filltype);
+ add(pic,L);
+}
+
+void label(picture pic=currentpicture, Label L, align align=NoAlign,
+ pen p=nullpen, filltype filltype=NoFill)
+{
+ label(pic,L,L.position,align,p,filltype);
+}
+
+void label(picture pic=currentpicture, Label L, explicit path g,
+ align align=NoAlign, pen p=nullpen, filltype filltype=NoFill)
+{
+ Label L=Label(L,align,p,filltype);
+ L.out(pic,g);
+}
+
+void label(picture pic=currentpicture, Label L, explicit guide g,
+ align align=NoAlign, pen p=nullpen, filltype filltype=NoFill)
+{
+ label(pic,L,(path) g,align,p,filltype);
+}
+
+Label operator cast(string s) {return Label(s);}
+
+// A structure that a string, Label, or frame can be cast to.
+struct object {
+ frame f;
+ Label L=Label;
+ path g; // Bounding path
+
+ void operator init(frame f) {
+ this.f=f;
+ g=box(min(f),max(f));
+ }
+
+ void operator init(Label L) {
+ this.L=L.copy();
+ if(L != Label) L.out(f);
+ g=box(min(f),max(f));
+ }
+}
+
+object operator cast(frame f) {
+ return object(f);
+}
+
+object operator cast(Label L)
+{
+ return object(L);
+}
+
+object operator cast(string s)
+{
+ return object(s);
+}
+
+Label operator cast(object F)
+{
+ return F.L;
+}
+
+frame operator cast(object F)
+{
+ return F.f;
+}
+
+object operator * (transform t, explicit object F)
+{
+ object f;
+ f.f=t*F.f;
+ f.L=t*F.L;
+ f.g=t*F.g;
+ return f;
+}
+
+// Returns a copy of object F aligned in the direction align
+object align(object F, pair align)
+{
+ return shift(F.f,align)*F;
+}
+
+void add(picture dest=currentpicture, object F, pair position=0,
+ bool group=true, filltype filltype=NoFill, bool above=true)
+{
+ add(dest,F.f,position,group,filltype,above);
+}
+
+// Pack a list of objects into a frame.
+frame pack(pair align=2S ... object inset[])
+{
+ frame F;
+ int n=inset.length;
+ pair z;
+ for (int i=0; i < n; ++i) {
+ add(F,inset[i].f,z);
+ z += align+realmult(unit(align),size(inset[i].f));
+ }
+ return F;
+}
+
+path[] texpath(Label L)
+{
+ static string[] stringcache;
+ static pen[] pencache;
+ static path[][] pathcache;
+ path[] g;
+
+ string s=L.s;
+ pen p=L.p;
+ int k=0;
+ int i;
+ while((i=find(stringcache == s,++k)) >= 0) {
+ if(pencache[i] == p) {
+ g=pathcache[i];
+ break;
+ }
+ }
+
+ if(i == -1) {
+ g=_texpath(s,p);
+ stringcache.push(s);
+ pencache.push(p);
+ pathcache.push(g);
+ }
+
+ pair a;
+ if(g.length == 0) return g;
+ pair m=min(g);
+ pair M=max(g);
+ pair dir=rectify(inverse(L.T)*-L.align.dir);
+ if(basealign(p) == 1)
+ dir -= (0,(1-dir.y)*m.y/(M.y-m.y));
+ a=m+realmult(dir,M-m);
+
+ return shift(L.position+L.align.dir*labelmargin(p))*L.T*shift(-a)*g;
+}
diff --git a/Build/source/utils/asymptote/base/plain_arcs.asy b/Build/source/utils/asymptote/base/plain_arcs.asy
new file mode 100644
index 00000000000..01e750f42cd
--- /dev/null
+++ b/Build/source/utils/asymptote/base/plain_arcs.asy
@@ -0,0 +1,43 @@
+bool CCW=true;
+bool CW=false;
+
+path circle(pair c, real r)
+{
+ return shift(c)*scale(r)*unitcircle;
+}
+
+path ellipse(pair c, real a, real b)
+{
+ return shift(c)*scale(a,b)*unitcircle;
+}
+
+// return an arc centered at c from pair z1 to z2 (assuming |z2-c|=|z1-c|),
+// drawing in the given direction.
+path arc(pair c, explicit pair z1, explicit pair z2, bool direction=CCW)
+{
+ z1 -= c;
+ real r=abs(z1);
+ z1=unit(z1);
+ z2=unit(z2-c);
+
+ real t1=intersect(unitcircle,(0,0)--2*z1)[0];
+ real t2=intersect(unitcircle,(0,0)--2*z2)[0];
+ static int n=length(unitcircle);
+ if(t1 >= t2 && direction) t1 -= n;
+ if(t2 >= t1 && !direction) t2 -= n;
+ return shift(c)*scale(r)*subpath(unitcircle,t1,t2);
+}
+
+// return an arc centered at c with radius r from angle1 to angle2 in degrees,
+// drawing in the given direction.
+path arc(pair c, real r, real angle1, real angle2, bool direction)
+{
+ return arc(c,c+r*dir(angle1),c+r*dir(angle2),direction);
+}
+
+// return an arc centered at c with radius r > 0 from angle1 to angle2 in
+// degrees, drawing counterclockwise if angle2 >= angle1 (otherwise clockwise).
+path arc(pair c, real r, real angle1, real angle2)
+{
+ return arc(c,r,angle1,angle2,angle2 >= angle1 ? CCW : CW);
+}
diff --git a/Build/source/utils/asymptote/base/plain_arrows.asy b/Build/source/utils/asymptote/base/plain_arrows.asy
new file mode 100644
index 00000000000..0ef8c2b2d5c
--- /dev/null
+++ b/Build/source/utils/asymptote/base/plain_arrows.asy
@@ -0,0 +1,569 @@
+real arrowlength=0.75cm;
+real arrowfactor=15;
+real arrowangle=15;
+real arcarrowfactor=0.5*arrowfactor;
+real arcarrowangle=2*arrowangle;
+real arrowsizelimit=0.5;
+real arrow2sizelimit=1/3;
+real arrowdir=5;
+real arrowbarb=3;
+real arrowhookfactor=1.5;
+real arrowtexfactor=1;
+
+real barfactor=arrowfactor;
+
+real arrowsize(pen p=currentpen)
+{
+ return arrowfactor*linewidth(p);
+}
+
+real arcarrowsize(pen p=currentpen)
+{
+ return arcarrowfactor*linewidth(p);
+}
+
+real barsize(pen p=currentpen)
+{
+ return barfactor*linewidth(p);
+}
+
+struct arrowhead
+{
+ path head(path g, position position=EndPoint, pen p=currentpen,
+ real size=0, real angle=arrowangle);
+ real size(pen p)=arrowsize;
+ real arcsize(pen p)=arcarrowsize;
+ filltype defaultfilltype(pen) {return FillDraw;}
+}
+
+real[] arrowbasepoints(path base, path left, path right)
+{
+ real[][] Tl=transpose(intersections(left,base));
+ real[][] Tr=transpose(intersections(right,base));
+ return new real[] {Tl.length > 0 ? Tl[0][0] : 1,
+ Tr.length > 0 ? Tr[0][0] : 1};
+}
+
+path arrowbase(path r, pair y, real t, real size)
+{
+ pair perp=2*size*I*dir(r,t);
+ return size == 0 ? y : y+perp--y-perp;
+}
+
+arrowhead DefaultHead;
+DefaultHead.head=new path(path g, position position=EndPoint, pen p=currentpen,
+ real size=0, real angle=arrowangle) {
+ if(size == 0) size=DefaultHead.size(p);
+ bool relative=position.relative;
+ real position=position.position.x;
+ if(relative) position=reltime(g,position);
+ path r=subpath(g,position,0);
+ pair x=point(r,0);
+ real t=arctime(r,size);
+ pair y=point(r,t);
+ path base=arrowbase(r,y,t,size);
+ path left=rotate(-angle,x)*r;
+ path right=rotate(angle,x)*r;
+ real[] T=arrowbasepoints(base,left,right);
+ pair denom=point(right,T[1])-y;
+ real factor=denom != 0 ? length((point(left,T[0])-y)/denom) : 1;
+ path left=rotate(-angle,x)*r;
+ path right=rotate(angle*factor,x)*r;
+ real[] T=arrowbasepoints(base,left,right);
+ return subpath(left,0,T[0])--subpath(right,T[1],0)&cycle;
+};
+
+arrowhead SimpleHead;
+SimpleHead.head=new path(path g, position position=EndPoint, pen p=currentpen,
+ real size=0, real angle=arrowangle) {
+ if(size == 0) size=SimpleHead.size(p);
+ bool relative=position.relative;
+ real position=position.position.x;
+ if(relative) position=reltime(g,position);
+ path r=subpath(g,position,0);
+ pair x=point(r,0);
+ real t=arctime(r,size);
+ pair y=point(r,t);
+ path base=arrowbase(r,y,t,size);
+ path left=rotate(-angle,x)*r;
+ path right=rotate(angle,x)*r;
+ real[] T=arrowbasepoints(base,left,right);
+ pair denom=point(right,T[1])-y;
+ real factor=denom != 0 ? length((point(left,T[0])-y)/denom) : 1;
+ path left=rotate(-angle,x)*r;
+ path right=rotate(angle*factor,x)*r;
+ real[] T=arrowbasepoints(base,left,right);
+ return subpath(left,T[0],0)--subpath(right,T[1],0);
+};
+
+arrowhead HookHead(real dir=arrowdir, real barb=arrowbarb)
+{
+ arrowhead a;
+ a.head=new path(path g, position position=EndPoint, pen p=currentpen,
+ real size=0, real angle=arrowangle)
+ {
+ if(size == 0) size=a.size(p);
+ angle=min(angle*arrowhookfactor,45);
+ bool relative=position.relative;
+ real position=position.position.x;
+ if(relative) position=reltime(g,position);
+ path r=subpath(g,position,0);
+ pair x=point(r,0);
+ real t=arctime(r,size);
+ pair y=point(r,t);
+ path base=arrowbase(r,y,t,size);
+ path left=rotate(-angle,x)*r;
+ path right=rotate(angle,x)*r;
+ real[] T=arrowbasepoints(base,left,right);
+ pair denom=point(right,T[1])-y;
+ real factor=denom != 0 ? length((point(left,T[0])-y)/denom) : 1;
+ path left=rotate(-angle,x)*r;
+ path right=rotate(angle*factor,x)*r;
+ real[] T=arrowbasepoints(base,left,right);
+ left=subpath(left,0,T[0]);
+ right=subpath(right,T[1],0);
+ pair pl0=point(left,0), pl1=relpoint(left,1);
+ pair pr0=relpoint(right,0), pr1=relpoint(right,1);
+ pair M=(pl1+pr0)/2;
+ pair v=barb*unit(M-pl0);
+ pl1=pl1+v; pr0=pr0+v;
+ left=pl0{dir(-dir+degrees(M-pl0,false))}..pl1--M;
+ right=M--pr0..pr1{dir(dir+degrees(pr1-M,false))};
+ return left--right&cycle;
+ };
+ return a;
+}
+arrowhead HookHead=HookHead();
+
+arrowhead TeXHead;
+TeXHead.size=new real(pen p)
+{
+ static real hcoef=2.1; // 84/40=abs(base-hint)/base_height
+ return hcoef*arrowtexfactor*linewidth(p);
+};
+TeXHead.arcsize=TeXHead.size;
+
+TeXHead.head=new path(path g, position position=EndPoint, pen p=currentpen,
+ real size=0, real angle=arrowangle) {
+ static real wcoef=1/84; // 1/abs(base-hint)
+ static path texhead=scale(wcoef)*
+ ((0,20) .. controls (-75,75) and (-108,158) ..
+ (-108,166) .. controls (-108,175) and (-100,178) ..
+ (-93,178) .. controls (-82,178) and (-80,173) ..
+ (-77,168) .. controls (-62,134) and (-30,61) ..
+ (70,14) .. controls (82,8) and (84,7) ..
+ (84,0) .. controls (84,-7) and (82,-8) ..
+ (70,-14) .. controls (-30,-61) and (-62,-134) ..
+ (-77,-168) .. controls (-80,-173) and (-82,-178) ..
+ (-93,-178) .. controls (-100,-178) and (-108,-175)..
+ (-108,-166).. controls (-108,-158) and (-75,-75) ..
+ (0,-20)--cycle);
+ if(size == 0) size=TeXHead.size(p);
+ path gp=scale(size)*texhead;
+ bool relative=position.relative;
+ real position=position.position.x;
+ if(relative) position=reltime(g,position);
+ path r=subpath(g,position,0);
+ pair y=point(r,arctime(r,size));
+ return shift(y)*rotate(degrees(-dir(r,arctime(r,0.5*size))))*gp;
+};
+TeXHead.defaultfilltype=new filltype(pen p) {return Fill(p);};
+
+private real position(position position, real size, path g, bool center)
+{
+ bool relative=position.relative;
+ real position=position.position.x;
+ if(relative) {
+ position *= arclength(g);
+ if(center) position += 0.5*size;
+ position=arctime(g,position);
+ } else if(center)
+ position=arctime(g,arclength(subpath(g,0,position))+0.5*size);
+ return position;
+}
+
+void drawarrow(frame f, arrowhead arrowhead=DefaultHead,
+ path g, pen p=currentpen, real size=0,
+ real angle=arrowangle,
+ filltype filltype=null,
+ position position=EndPoint, bool forwards=true,
+ margin margin=NoMargin, bool center=false)
+{
+ if(size == 0) size=arrowhead.size(p);
+ if(filltype == null) filltype=arrowhead.defaultfilltype(p);
+ size=min(arrowsizelimit*arclength(g),size);
+ real position=position(position,size,g,center);
+
+ g=margin(g,p).g;
+ int L=length(g);
+ if(!forwards) {
+ g=reverse(g);
+ position=L-position;
+ }
+ path r=subpath(g,position,0);
+ size=min(arrowsizelimit*arclength(r),size);
+ path head=arrowhead.head(g,position,p,size,angle);
+ bool endpoint=position > L-sqrtEpsilon;
+ if(cyclic(head) && (filltype == NoFill || endpoint)) {
+ if(position > 0)
+ draw(f,subpath(r,arctime(r,size),length(r)),p);
+ if(!endpoint)
+ draw(f,subpath(g,position,L),p);
+ } else draw(f,g,p);
+ filltype.fill(f,head,p+solid);
+}
+
+void drawarrow2(frame f, arrowhead arrowhead=DefaultHead,
+ path g, pen p=currentpen, real size=0,
+ real angle=arrowangle, filltype filltype=null,
+ margin margin=NoMargin)
+{
+ if(size == 0) size=arrowhead.size(p);
+ if(filltype == null) filltype=arrowhead.defaultfilltype(p);
+ g=margin(g,p).g;
+ size=min(arrow2sizelimit*arclength(g),size);
+
+ path r=reverse(g);
+ int L=length(g);
+ path head=arrowhead.head(g,L,p,size,angle);
+ path tail=arrowhead.head(r,L,p,size,angle);
+ if(cyclic(head))
+ draw(f,subpath(r,arctime(r,size),L-arctime(g,size)),p);
+ else draw(f,g,p);
+ filltype.fill(f,head,p+solid);
+ filltype.fill(f,tail,p+solid);
+}
+
+// Add to picture an estimate of the bounding box contribution of arrowhead
+// using the local slope at endpoint and ignoring margin.
+void addArrow(picture pic, arrowhead arrowhead, path g, pen p, real size,
+ real angle, filltype filltype, real position)
+{
+ if(filltype == null) filltype=arrowhead.defaultfilltype(p);
+ pair z=point(g,position);
+ path g=z-(size+linewidth(p))*dir(g,position)--z;
+ frame f;
+ filltype.fill(f,arrowhead.head(g,position,p,size,angle),p);
+ pic.addBox(z,z,min(f)-z,max(f)-z);
+}
+
+picture arrow(arrowhead arrowhead=DefaultHead,
+ path g, pen p=currentpen, real size=0,
+ real angle=arrowangle, filltype filltype=null,
+ position position=EndPoint, bool forwards=true,
+ margin margin=NoMargin, bool center=false)
+{
+ if(size == 0) size=arrowhead.size(p);
+ picture pic;
+ pic.add(new void(frame f, transform t) {
+ drawarrow(f,arrowhead,t*g,p,size,angle,filltype,position,forwards,margin,
+ center);
+ });
+
+ pic.addPath(g,p);
+
+ real position=position(position,size,g,center);
+ path G;
+ if(!forwards) {
+ G=reverse(g);
+ position=length(g)-position;
+ } else G=g;
+ addArrow(pic,arrowhead,G,p,size,angle,filltype,position);
+
+ return pic;
+}
+
+picture arrow2(arrowhead arrowhead=DefaultHead,
+ path g, pen p=currentpen, real size=0,
+ real angle=arrowangle, filltype filltype=null,
+ margin margin=NoMargin)
+{
+ if(size == 0) size=arrowhead.size(p);
+ picture pic;
+ pic.add(new void(frame f, transform t) {
+ drawarrow2(f,arrowhead,t*g,p,size,angle,filltype,margin);
+ });
+
+ pic.addPath(g,p);
+
+ int L=length(g);
+ addArrow(pic,arrowhead,g,p,size,angle,filltype,L);
+ addArrow(pic,arrowhead,reverse(g),p,size,angle,filltype,L);
+
+ return pic;
+}
+
+void bar(picture pic, pair a, pair d, pen p=currentpen)
+{
+ picture opic;
+ Draw(opic,-0.5d--0.5d,p+solid);
+ add(pic,opic,a);
+}
+
+picture bar(pair a, pair d, pen p=currentpen)
+{
+ picture pic;
+ bar(pic,a,d,p);
+ return pic;
+}
+
+typedef bool arrowbar(picture, path, pen, margin);
+
+bool Blank(picture, path, pen, margin)
+{
+ return false;
+}
+
+bool None(picture, path, pen, margin)
+{
+ return true;
+}
+
+arrowbar BeginArrow(arrowhead arrowhead=DefaultHead,
+ real size=0, real angle=arrowangle,
+ filltype filltype=null, position position=BeginPoint)
+{
+ return new bool(picture pic, path g, pen p, margin margin) {
+ add(pic,arrow(arrowhead,g,p,size,angle,filltype,position,forwards=false,
+ margin));
+ return false;
+ };
+}
+
+arrowbar Arrow(arrowhead arrowhead=DefaultHead,
+ real size=0, real angle=arrowangle,
+ filltype filltype=null, position position=EndPoint)
+{
+ return new bool(picture pic, path g, pen p, margin margin) {
+ add(pic,arrow(arrowhead,g,p,size,angle,filltype,position,margin));
+ return false;
+ };
+}
+
+arrowbar EndArrow(arrowhead arrowhead=DefaultHead,
+ real size=0, real angle=arrowangle,
+ filltype filltype=null, position position=EndPoint)=Arrow;
+
+arrowbar MidArrow(arrowhead arrowhead=DefaultHead,
+ real size=0, real angle=arrowangle, filltype filltype=null)
+{
+ return new bool(picture pic, path g, pen p, margin margin) {
+ add(pic,arrow(arrowhead,g,p,size,angle,filltype,MidPoint,margin,
+ center=true));
+ return false;
+ };
+}
+
+arrowbar Arrows(arrowhead arrowhead=DefaultHead,
+ real size=0, real angle=arrowangle,
+ filltype filltype=null)
+{
+ return new bool(picture pic, path g, pen p, margin margin) {
+ add(pic,arrow2(arrowhead,g,p,size,angle,filltype,margin));
+ return false;
+ };
+}
+
+arrowbar BeginArcArrow(arrowhead arrowhead=DefaultHead,
+ real size=0, real angle=arcarrowangle,
+ filltype filltype=null, position position=BeginPoint)
+{
+ return new bool(picture pic, path g, pen p, margin margin) {
+ real size=size == 0 ? arrowhead.arcsize(p) : size;
+ add(pic,arrow(arrowhead,g,p,size,angle,filltype,position,
+ forwards=false,margin));
+ return false;
+ };
+}
+
+arrowbar ArcArrow(arrowhead arrowhead=DefaultHead,
+ real size=0, real angle=arcarrowangle,
+ filltype filltype=null, position position=EndPoint)
+{
+ return new bool(picture pic, path g, pen p, margin margin) {
+ real size=size == 0 ? arrowhead.arcsize(p) : size;
+ add(pic,arrow(arrowhead,g,p,size,angle,filltype,position,margin));
+ return false;
+ };
+}
+
+arrowbar EndArcArrow(arrowhead arrowhead=DefaultHead,
+ real size=0, real angle=arcarrowangle,
+ filltype filltype=null,
+ position position=EndPoint)=ArcArrow;
+
+arrowbar MidArcArrow(arrowhead arrowhead=DefaultHead,
+ real size=0, real angle=arcarrowangle,
+ filltype filltype=null)
+{
+ return new bool(picture pic, path g, pen p, margin margin) {
+ real size=size == 0 ? arrowhead.arcsize(p) : size;
+ add(pic,arrow(arrowhead,g,p,size,angle,filltype,MidPoint,margin,
+ center=true));
+ return false;
+ };
+}
+
+arrowbar ArcArrows(arrowhead arrowhead=DefaultHead,
+ real size=0, real angle=arcarrowangle,
+ filltype filltype=null)
+{
+ return new bool(picture pic, path g, pen p, margin margin) {
+ real size=size == 0 ? arrowhead.arcsize(p) : size;
+ add(pic,arrow2(arrowhead,g,p,size,angle,filltype,margin));
+ return false;
+ };
+}
+
+arrowbar BeginBar(real size=0)
+{
+ return new bool(picture pic, path g, pen p, margin margin) {
+ real size=size == 0 ? barsize(p) : size;
+ bar(pic,point(g,0),size*dir(g,0)*I,p);
+ return true;
+ };
+}
+
+arrowbar Bar(real size=0)
+{
+ return new bool(picture pic, path g, pen p, margin margin) {
+ int L=length(g);
+ real size=size == 0 ? barsize(p) : size;
+ bar(pic,point(g,L),size*dir(g,L)*I,p);
+ return true;
+ };
+}
+
+arrowbar EndBar(real size=0)=Bar;
+
+arrowbar Bars(real size=0)
+{
+ return new bool(picture pic, path g, pen p, margin margin) {
+ real size=size == 0 ? barsize(p) : size;
+ BeginBar(size)(pic,g,p,margin);
+ EndBar(size)(pic,g,p,margin);
+ return true;
+ };
+}
+
+arrowbar BeginArrow=BeginArrow(),
+MidArrow=MidArrow(),
+Arrow=Arrow(),
+EndArrow=Arrow(),
+Arrows=Arrows(),
+BeginArcArrow=BeginArcArrow(),
+MidArcArrow=MidArcArrow(),
+ArcArrow=ArcArrow(),
+EndArcArrow=ArcArrow(),
+ArcArrows=ArcArrows(),
+BeginBar=BeginBar(),
+Bar=Bar(),
+EndBar=Bar(),
+Bars=Bars();
+
+void draw(frame f, path g, pen p=currentpen, arrowbar arrow)
+{
+ picture pic;
+ if(arrow(pic,g,p,NoMargin))
+ draw(f,g,p);
+ add(f,pic.fit());
+}
+
+void draw(picture pic=currentpicture, Label L="", path g, align align=NoAlign,
+ pen p=currentpen, arrowbar arrow=None, arrowbar bar=None,
+ margin margin=NoMargin, Label legend="", marker marker=nomarker)
+{
+ Label L=L.copy();
+ L.align(align);
+ if(marker != nomarker && !marker.above) marker.mark(pic,g);
+ bool drawpath=arrow(pic,g,p,margin);
+ if(bar(pic,g,p,margin) && drawpath) _draw(pic,g,p,margin);
+ if(L.s != "") {
+ L.p(p);
+ L.out(pic,g);
+ }
+ if(legend.s != "") {
+ legend.p(p);
+ pic.legend.push(Legend(legend.s,legend.p,p,marker.f,marker.above));
+ }
+ if(marker != nomarker && marker.above) marker.mark(pic,g);
+}
+
+// Draw a fixed-size line about the user-coordinate 'origin'.
+void draw(pair origin, picture pic=currentpicture, Label L="", path g,
+ align align=NoAlign, pen p=currentpen, arrowbar arrow=None,
+ arrowbar bar=None, margin margin=NoMargin, Label legend="",
+ marker marker=nomarker)
+{
+ picture opic;
+ draw(opic,L,g,align,p,arrow,bar,margin,legend,marker);
+ add(pic,opic,origin);
+}
+
+void draw(picture pic=currentpicture, explicit path[] g, pen p=currentpen,
+ Label legend="", marker marker=nomarker)
+{
+ for(int i=0; i < g.length-1; ++i)
+ draw(pic,g[i],p,marker);
+ if(g.length > 0) draw(pic,g[g.length-1],p,legend,marker);
+}
+
+void draw(picture pic=currentpicture, guide[] g, pen p=currentpen,
+ Label legend="", marker marker=nomarker)
+{
+ draw(pic,(path[]) g,p,legend,marker);
+}
+
+void draw(pair origin, picture pic=currentpicture, explicit path[] g,
+ pen p=currentpen, Label legend="", marker marker=nomarker)
+{
+ picture opic;
+ draw(opic,g,p,legend,marker);
+ add(pic,opic,origin);
+}
+
+void draw(pair origin, picture pic=currentpicture, guide[] g, pen p=currentpen,
+ Label legend="", marker marker=nomarker)
+{
+ draw(origin,pic,(path[]) g,p,legend,marker);
+}
+
+// Align an arrow pointing to b from the direction dir. The arrow is
+// 'length' PostScript units long.
+void arrow(picture pic=currentpicture, Label L="", pair b, pair dir,
+ real length=arrowlength, align align=NoAlign,
+ pen p=currentpen, arrowbar arrow=Arrow, margin margin=EndMargin)
+{
+ Label L=L.copy();
+ if(L.defaultposition) L.position(0);
+ L.align(L.align,dir);
+ L.p(p);
+ marginT margin=margin(b--b,p); // Extract margin.begin and margin.end
+ pair a=(margin.begin+length+margin.end)*unit(dir);
+ draw(b,pic,L,a--(0,0),align,p,arrow,margin);
+}
+
+// Force an array of 2D pictures to be as least as large as picture all.
+void rescale2(picture[] pictures, picture all)
+{
+ if(!all.empty2()) {
+ transform t=inverse(all.calculateTransform()*pictures[0].T);
+ pair m=t*min(all);
+ pair M=t*max(all);
+ for(int i=0; i < pictures.length; ++i) {
+ draw(pictures[i],m,nullpen);
+ draw(pictures[i],M,nullpen);
+ }
+ }
+}
+
+// Force an array of pictures to have a uniform scaling.
+void rescale(picture[] pictures)
+{
+ if(pictures.length == 0) return;
+ picture all;
+ size(all,pictures[0]);
+ for(picture pic : pictures)
+ add(all,pic);
+ rescale2(pictures,all);
+}
diff --git a/Build/source/utils/asymptote/base/plain_boxes.asy b/Build/source/utils/asymptote/base/plain_boxes.asy
new file mode 100644
index 00000000000..6ec7f23c985
--- /dev/null
+++ b/Build/source/utils/asymptote/base/plain_boxes.asy
@@ -0,0 +1,136 @@
+// Draw and/or fill a box on frame dest using the dimensions of frame src.
+path box(frame dest, frame src=dest, real xmargin=0, real ymargin=xmargin,
+ pen p=currentpen, filltype filltype=NoFill, bool above=true)
+{
+ pair z=(xmargin,ymargin);
+ int sign=filltype == NoFill ? 1 : -1;
+ path g=box(min(src)+0.5*sign*min(p)-z,max(src)+0.5*sign*max(p)+z);
+ frame F;
+ if(above == false) {
+ filltype.fill(F,g,p);
+ prepend(dest,F);
+ } else filltype.fill(dest,g,p);
+ return g;
+}
+
+path roundbox(frame dest, frame src=dest, real xmargin=0, real ymargin=xmargin,
+ pen p=currentpen, filltype filltype=NoFill, bool above=true)
+{
+ pair m=min(src);
+ pair M=max(src);
+ pair bound=M-m;
+ int sign=filltype == NoFill ? 1 : -1;
+ real a=bound.x+2*xmargin;
+ real b=bound.y+2*ymargin;
+ real ds=0;
+ real dw=min(a,b)*0.3;
+ path g=shift(m-(xmargin,ymargin))*((0,dw)--(0,b-dw){up}..{right}
+ (dw,b)--(a-dw,b){right}..{down}
+ (a,b-dw)--(a,dw){down}..{left}
+ (a-dw,0)--(dw,0){left}..{up}cycle);
+
+ frame F;
+ if(above == false) {
+ filltype.fill(F,g,p);
+ prepend(dest,F);
+ } else filltype.fill(dest,g,p);
+ return g;
+}
+
+path ellipse(frame dest, frame src=dest, real xmargin=0, real ymargin=xmargin,
+ pen p=currentpen, filltype filltype=NoFill, bool above=true)
+{
+ pair m=min(src);
+ pair M=max(src);
+ pair D=M-m;
+ static real factor=0.5*sqrt(2);
+ int sign=filltype == NoFill ? 1 : -1;
+ path g=ellipse(0.5*(M+m),factor*D.x+0.5*sign*max(p).x+xmargin,
+ factor*D.y+0.5*sign*max(p).y+ymargin);
+ frame F;
+ if(above == false) {
+ filltype.fill(F,g,p);
+ prepend(dest,F);
+ } else filltype.fill(dest,g,p);
+ return g;
+}
+
+path box(frame f, Label L, real xmargin=0, real ymargin=xmargin,
+ pen p=currentpen, filltype filltype=NoFill, bool above=true)
+{
+ add(f,L);
+ return box(f,xmargin,ymargin,p,filltype,above);
+}
+
+path roundbox(frame f, Label L, real xmargin=0, real ymargin=xmargin,
+ pen p=currentpen, filltype filltype=NoFill, bool above=true)
+{
+ add(f,L);
+ return roundbox(f,xmargin,ymargin,p,filltype,above);
+}
+
+path ellipse(frame f, Label L, real xmargin=0, real ymargin=xmargin,
+ pen p=currentpen, filltype filltype=NoFill, bool above=true)
+{
+ add(f,L);
+ return ellipse(f,xmargin,ymargin,p,filltype,above);
+}
+
+typedef path envelope(frame dest, frame src=dest, real xmargin=0,
+ real ymargin=xmargin, pen p=currentpen,
+ filltype filltype=NoFill, bool above=true);
+
+object object(Label L, envelope e, real xmargin=0, real ymargin=xmargin,
+ pen p=currentpen, filltype filltype=NoFill, bool above=true)
+{
+ object F;
+ F.L=L.copy();
+ Label L0=L.copy();
+ L0.position(0);
+ L0.p(p);
+ add(F.f,L0);
+ F.g=e(F.f,xmargin,ymargin,p,filltype);
+ return F;
+}
+
+object draw(picture pic=currentpicture, Label L, envelope e,
+ real xmargin=0, real ymargin=xmargin, pen p=currentpen,
+ filltype filltype=NoFill, bool above=true)
+{
+ object F=object(L,e,xmargin,ymargin,p,filltype,above);
+ pic.add(new void (frame f, transform t) {
+ frame d;
+ add(d,t,F.L);
+ e(f,d,xmargin,ymargin,p,filltype,above);
+ add(f,d);
+ },true);
+ pic.addBox(L.position,L.position,min(F.f),max(F.f));
+ return F;
+}
+
+object draw(picture pic=currentpicture, Label L, envelope e, pair position,
+ real xmargin=0, real ymargin=xmargin, pen p=currentpen,
+ filltype filltype=NoFill, bool above=true)
+{
+ return draw(pic,Label(L,position),e,xmargin,ymargin,p,filltype,above);
+}
+
+pair point(object F, pair dir, transform t=identity())
+{
+ pair m=min(F.g);
+ pair M=max(F.g);
+ pair c=0.5*(m+M);
+ pair z=t*F.L.position;
+ real[] T=intersect(F.g,c--2*(m+realmult(rectify(dir),M-m))-c);
+ if(T.length == 0) return z;
+ return z+point(F.g,T[0]);
+}
+
+frame bbox(string prefix="", picture pic=currentpicture,
+ real xmargin=0, real ymargin=xmargin,
+ pen p=currentpen, filltype filltype=NoFill)
+{
+ frame f=pic.fit(prefix,max(pic.xsize-2*xmargin,0),max(pic.ysize-2*ymargin,0));
+ box(f,xmargin,ymargin,p,filltype,false);
+ return f;
+}
diff --git a/Build/source/utils/asymptote/base/plain_constants.asy b/Build/source/utils/asymptote/base/plain_constants.asy
new file mode 100644
index 00000000000..c1d8c086f71
--- /dev/null
+++ b/Build/source/utils/asymptote/base/plain_constants.asy
@@ -0,0 +1,157 @@
+restricted int undefined=intMax+((intMax % 2)-1);
+
+restricted real inches=72;
+restricted real inch=inches;
+restricted real cm=inches/2.54;
+restricted real mm=0.1cm;
+restricted real bp=1; // A PostScript point.
+restricted real pt=72.0/72.27; // A TeX pt; smaller than a PostScript bp.
+restricted pair I=(0,1);
+
+restricted pair up=(0,1);
+restricted pair down=(0,-1);
+restricted pair right=(1,0);
+restricted pair left=(-1,0);
+
+restricted pair E=(1,0);
+restricted pair N=(0,1);
+restricted pair W=(-1,0);
+restricted pair S=(0,-1);
+
+restricted pair NE=unit(N+E);
+restricted pair NW=unit(N+W);
+restricted pair SW=unit(S+W);
+restricted pair SE=unit(S+E);
+
+restricted pair ENE=unit(E+NE);
+restricted pair NNE=unit(N+NE);
+restricted pair NNW=unit(N+NW);
+restricted pair WNW=unit(W+NW);
+restricted pair WSW=unit(W+SW);
+restricted pair SSW=unit(S+SW);
+restricted pair SSE=unit(S+SE);
+restricted pair ESE=unit(E+SE);
+
+restricted real sqrtEpsilon=sqrt(realEpsilon);
+restricted pair Align=sqrtEpsilon*NE;
+restricted int mantissaBits=ceil(-log(realEpsilon)/log(2))+1;
+
+int min(... int[] a) {return min(a);}
+int max(... int[] a) {return max(a);}
+
+real min(... real[] a) {return min(a);}
+real max(... real[] a) {return max(a);}
+
+bool finite(real x)
+{
+ return abs(x) < infinity;
+}
+
+bool finite(pair z)
+{
+ return abs(z.x) < infinity && abs(z.y) < infinity;
+}
+
+bool finite(triple v)
+{
+ return abs(v.x) < infinity && abs(v.y) < infinity && abs(v.z) < infinity;
+}
+
+restricted file stdin=input("");
+restricted file stdout=output("");
+
+void none(file file) {}
+void endl(file file) {write(file,'\n',flush);}
+void newl(file file) {write(file,'\n');}
+void tab(file file) {write(file,'\t');}
+void comma(file file) {write(file,',');}
+typedef void suffix(file);
+
+void write(suffix suffix=endl) {suffix(stdout);}
+void write(file file, suffix suffix=none) {suffix(file);}
+
+path box(pair a, pair b)
+{
+ return a--(b.x,a.y)--b--(a.x,b.y)--cycle;
+}
+
+restricted path unitsquare=box((0,0),(1,1));
+
+restricted path unitcircle=E..N..W..S..cycle;
+restricted real circleprecision=0.0006;
+
+restricted transform invert=reflect((0,0),(1,0));
+
+restricted pen defaultpen;
+
+// A type that takes on one of the values true, false, or default.
+struct bool3 {
+ bool value;
+ bool set;
+}
+
+void write(file file, string s="", bool3 b, suffix suffix=none)
+{
+ if(b.set) write(b.value);
+ else write("default");
+}
+
+void write(string s="", bool3 b, suffix suffix=endl)
+{
+ write(stdout,s,b,suffix);
+}
+
+restricted bool3 default;
+
+bool operator cast(bool3 b)
+{
+ return b.set && b.value;
+}
+
+bool3 operator cast(bool b)
+{
+ bool3 B;
+ B.value=b;
+ B.set=true;
+ return B;
+}
+
+bool operator == (bool3 a, bool3 b)
+{
+ return a.set == b.set && (!a.set || (a.value == b.value));
+}
+
+bool operator != (bool3 a, bool3 b)
+{
+ return a.set != b.set || (a.set && (a.value != b.value));
+}
+
+bool operator == (bool3 a, bool b)
+{
+ return a.set && a.value == b;
+}
+
+bool operator != (bool3 a, bool b)
+{
+ return !a.set || a.value != b;
+}
+
+bool operator == (bool a, bool3 b)
+{
+ return b.set && b.value == a;
+}
+
+bool operator != (bool a, bool3 b)
+{
+ return !b.set || b.value != a;
+}
+
+bool[] operator cast(bool3[] b)
+{
+ return sequence(new bool(int i) {return b[i];},b.length);
+}
+
+bool3[] operator cast(bool[] b)
+{
+ return sequence(new bool3(int i) {return b[i];},b.length);
+}
diff --git a/Build/source/utils/asymptote/base/plain_debugger.asy b/Build/source/utils/asymptote/base/plain_debugger.asy
new file mode 100644
index 00000000000..8568ee0bd8d
--- /dev/null
+++ b/Build/source/utils/asymptote/base/plain_debugger.asy
@@ -0,0 +1,86 @@
+int debuggerlines=5;
+
+int sourceline(string file, string text)
+{
+ string file=locatefile(file);
+ string[] source=input(file);
+ for(int line=0; line < source.length; ++line)
+ if(find(source[line],text) >= 0) return line+1;
+ write("no matching line in "+file+": \""+text+"\"");
+ return 0;
+}
+
+void stop(string file, string text, code s=quote{})
+{
+ int line=sourceline(file,text);
+ if(line > 0) stop(file,line,s);
+}
+
+void clear(string file, string text)
+{
+ int line=sourceline(file,text);
+ if(line > 0) clear(file,line);
+}
+
+// Enable debugging.
+bool debugging=true;
+
+// Variables used by conditional expressions:
+// e.g. stop("test",2,quote{ignore=(++count <= 10);});
+
+bool ignore;
+int count=0;
+
+string debugger(string file, int line, int column, code s=quote{})
+{
+ int verbose=settings.verbose;
+ settings.verbose=0;
+ _eval(s,true);
+ if(ignore) {
+ ignore=false;
+ settings.verbose=verbose;
+ return "c";
+ }
+ static string s;
+ if(debugging) {
+ static string lastfile;
+ static string[] source;
+ bool help=false;
+ while(true) {
+ if(file != lastfile && file != "-") {source=input(file); lastfile=file;}
+ write();
+ for(int i=max(line-debuggerlines,0); i < min(line,source.length); ++i)
+ write(source[i]);
+ for(int i=0; i < column-1; ++i)
+ write(" ",none);
+ write("^"+(verbose == 5 ? " trace" : ""));
+
+ if(help) {
+ write("c:continue f:file h:help i:inst n:next r:return s:step t:trace q:quit x:exit");
+ help=false;
+ }
+
+ string Prompt=file+": "+(string) line+"."+(string) column;
+ Prompt += "? [%s] ";
+ s=getstring(name="debug",default="h",prompt=Prompt,store=false);
+ if(s == "h" || s == "?") {help=true; continue;}
+ if(s == "c" || s == "s" || s == "n" || s == "i" || s == "f" || s == "r")
+ break;
+ if(s == "q") {debugging=false; abort();} // quit
+ if(s == "x") {debugging=false; return "";} // exit
+ if(s == "t") { // trace
+ if(verbose == 0) {
+ verbose=5;
+ } else {
+ verbose=0;
+ }
+ continue;
+ }
+ _eval(s+";",true);
+ }
+ }
+ settings.verbose=verbose;
+ return s;
+}
+
+atbreakpoint(debugger);
diff --git a/Build/source/utils/asymptote/base/plain_filldraw.asy b/Build/source/utils/asymptote/base/plain_filldraw.asy
new file mode 100644
index 00000000000..b9cd191e075
--- /dev/null
+++ b/Build/source/utils/asymptote/base/plain_filldraw.asy
@@ -0,0 +1,234 @@
+// Draw path g on frame f with user-constructed pen p.
+void makedraw(frame f, path g, pen p, int depth=mantissaBits)
+{
+ if(depth == 0) return;
+ --depth;
+
+ path n=nib(p);
+ for(int i=0; i < size(g); ++i)
+ fill(f,shift(point(g,i))*n,p);
+
+ static real epsilon=1000*realEpsilon;
+ int L=length(g);
+ real stop=L-epsilon;
+ int N=length(n);
+ pair first=point(n,0);
+ pair n0=first;
+
+ for(int i=0; i < N; ++i) {
+ pair n1=point(n,i+1);
+ pair dir=unit(n1-n0);
+ real t=dirtime(g,-dir);
+ if(straight(g,(int) t)) t=ceil(t);
+ if(t > epsilon && t < stop) {
+ makedraw(f,subpath(g,0,t),p,depth);
+ makedraw(f,subpath(g,t,L),p,depth);
+ return;
+ }
+ real t=dirtime(g,dir);
+ if(straight(g,(int) t)) t=ceil(t);
+ if(t > epsilon && t < stop) {
+ makedraw(f,subpath(g,0,t),p,depth);
+ makedraw(f,subpath(g,t,L),p,depth);
+ return;
+ }
+ n0=n1;
+ }
+
+ n0=first;
+ for(int i=0; i < N; ++i) {
+ pair n1=point(n,i+1);
+ fill(f,shift(n0)*g--shift(n1)*reverse(g)--cycle,p);
+ n0=n1;
+ }
+}
+
+void draw(frame f, path g, pen p=currentpen)
+{
+ if(size(nib(p)) == 0) _draw(f,g,p);
+ else {
+ begingroup(f);
+ makedraw(f,g,p);
+ endgroup(f);
+ }
+}
+
+void draw(frame f, explicit path[] g, pen p=currentpen)
+{
+ for(int i=0; i < g.length; ++i) draw(f,g[i],p);
+}
+
+void draw(frame f, guide[] g, pen p=currentpen)
+{
+ for(int i=0; i < g.length; ++i) draw(f,g[i],p);
+}
+
+void filldraw(frame f, path[] g, pen fillpen=currentpen,
+ pen drawpen=currentpen)
+{
+ begingroup(f);
+ fill(f,g,fillpen);
+ draw(f,g,drawpen);
+ endgroup(f);
+}
+
+path[] complement(frame f, path[] g)
+{
+ static pair margin=(0.5,0.5);
+ return box(minbound(min(f),min(g))-margin,maxbound(max(f),max(g))+margin)^^g;
+}
+
+void unfill(frame f, path[] g, bool copy=true)
+{
+ clip(f,complement(f,g),evenodd,copy);
+}
+
+void filloutside(frame f, path[] g, pen p=currentpen, bool copy=true)
+{
+ fill(f,complement(f,g),p+evenodd,copy);
+}
+
+struct filltype
+{
+ typedef void fill2(frame f, path[] g, pen fillpen);
+ fill2 fill2;
+ pen fillpen;
+ pen drawpen;
+
+ int type;
+ static int Fill=1;
+ static int FillDraw=2;
+ static int Draw=3;
+ static int NoFill=4;
+ static int UnFill=5;
+
+ void operator init(int type=0, pen fillpen=nullpen, pen drawpen=nullpen,
+ fill2 fill2) {
+ this.type=type;
+ this.fillpen=fillpen;
+ this.drawpen=drawpen;
+ this.fill2=fill2;
+ }
+ void fill(frame f, path[] g, pen p) {fill2(f,g,p);}
+}
+
+path[] margin(path[] g, real xmargin, real ymargin)
+{
+ if(xmargin != 0 || ymargin != 0) {
+ pair M=max(g);
+ pair m=min(g);
+ real width=M.x-m.x;
+ real height=M.y-m.y;
+ real xfactor=width > 0 ? (width+2xmargin)/width : 1;
+ real yfactor=height > 0 ? (height+2ymargin)/height : 1;
+ g=scale(xfactor,yfactor)*g;
+ g=shift(0.5*(M+m)-0.5*(max(g)+min(g)))*g;
+ }
+ return g;
+}
+
+filltype Fill(real xmargin=0, real ymargin=xmargin, pen p=nullpen)
+{
+ return filltype(filltype.Fill,p,new void(frame f, path[] g, pen fillpen) {
+ if(p != nullpen) fillpen=p;
+ if(fillpen == nullpen) fillpen=currentpen;
+ fill(f,margin(g,xmargin,ymargin),fillpen);
+ });
+}
+
+filltype FillDraw(real xmargin=0, real ymargin=xmargin,
+ pen fillpen=nullpen, pen drawpen=nullpen)
+{
+ return filltype(filltype.FillDraw,fillpen,drawpen,
+ new void(frame f, path[] g, pen Drawpen) {
+ if(drawpen != nullpen) Drawpen=drawpen;
+ pen Fillpen=fillpen == nullpen ? Drawpen : fillpen;
+ if(Fillpen == nullpen) Fillpen=currentpen;
+ if(Drawpen == nullpen) Drawpen=Fillpen;
+ if(cyclic(g[0]))
+ filldraw(f,margin(g,xmargin,ymargin),Fillpen,Drawpen);
+ else
+ draw(f,margin(g,xmargin,ymargin),Drawpen);
+ });
+}
+
+filltype Draw(real xmargin=0, real ymargin=xmargin, pen p=nullpen)
+{
+ return filltype(filltype.Draw,drawpen=p,
+ new void(frame f, path[] g, pen drawpen) {
+ pen drawpen=p == nullpen ? drawpen : p;
+ if(drawpen == nullpen) drawpen=currentpen;
+ draw(f,margin(g,xmargin,ymargin),drawpen);
+ });
+}
+
+filltype NoFill=filltype(filltype.NoFill,new void(frame f, path[] g, pen p) {
+ draw(f,g,p);
+ });
+
+
+filltype UnFill(real xmargin=0, real ymargin=xmargin)
+{
+ return filltype(filltype.UnFill,new void(frame f, path[] g, pen) {
+ unfill(f,margin(g,xmargin,ymargin));
+ });
+}
+
+filltype FillDraw=FillDraw(), Fill=Fill(), Draw=Draw(), UnFill=UnFill();
+
+// Fill varying radially from penc at the center of the bounding box to
+// penr at the edge.
+filltype RadialShade(pen penc, pen penr)
+{
+ return filltype(new void(frame f, path[] g, pen) {
+ pair c=(min(g)+max(g))/2;
+ radialshade(f,g,penc,c,0,penr,c,abs(max(g)-min(g))/2);
+ });
+}
+
+// Fill the region in frame dest underneath frame src and return the
+// boundary of src.
+path fill(frame dest, frame src, filltype filltype=NoFill,
+ real xmargin=0, real ymargin=xmargin)
+{
+ pair z=(xmargin,ymargin);
+ path g=box(min(src)-z,max(src)+z);
+ filltype.fill(dest,g,nullpen);
+ return g;
+}
+
+// Add frame dest to frame src with optional grouping and background fill.
+void add(frame dest, frame src, bool group, filltype filltype=NoFill,
+ bool above=true)
+{
+ if(above) {
+ if(filltype != NoFill) fill(dest,src,filltype);
+ if(group) begingroup(dest);
+ add(dest,src);
+ if(group) endgroup(dest);
+ } else {
+ if(group) {
+ frame f;
+ endgroup(f);
+ prepend(dest,f);
+ }
+ prepend(dest,src);
+ if(group) {
+ frame f;
+ begingroup(f);
+ prepend(dest,f);
+ }
+ if(filltype != NoFill) {
+ frame f;
+ fill(f,src,filltype);
+ prepend(dest,f);
+ }
+ }
+}
+
+void add(frame dest, frame src, filltype filltype,
+ bool above=filltype.type != filltype.UnFill)
+{
+ if(filltype != NoFill) fill(dest,src,filltype);
+ (above ? add : prepend)(dest,src);
+}
diff --git a/Build/source/utils/asymptote/base/plain_margins.asy b/Build/source/utils/asymptote/base/plain_margins.asy
new file mode 100644
index 00000000000..c4522754481
--- /dev/null
+++ b/Build/source/utils/asymptote/base/plain_margins.asy
@@ -0,0 +1,99 @@
+struct marginT {
+ path g;
+ real begin,end;
+};
+
+typedef marginT margin(path, pen);
+
+path trim(path g, real begin, real end) {
+ real a=arctime(g,begin);
+ real b=arctime(g,arclength(g)-end);
+ return a <= b ? subpath(g,a,b) : point(g,a);
+}
+
+margin operator +(margin ma, margin mb)
+{
+ return new marginT(path g, pen p) {
+ marginT margin;
+ real ba=ma(g,p).begin < 0 ? 0 : ma(g,p).begin;
+ real bb=mb(g,p).begin < 0 ? 0 : mb(g,p).begin;
+ real ea=ma(g,p).end < 0 ? 0 : ma(g,p).end;
+ real eb=mb(g,p).end < 0 ? 0 : mb(g,p).end;
+ margin.begin=ba+bb;
+ margin.end=ea+eb;
+ margin.g=trim(g,margin.begin,margin.end);
+ return margin;
+ };
+}
+
+margin NoMargin()
+{
+ return new marginT(path g, pen) {
+ marginT margin;
+ margin.begin=margin.end=0;
+ margin.g=g;
+ return margin;
+ };
+}
+
+margin Margin(real begin, real end)
+{
+ return new marginT(path g, pen p) {
+ marginT margin;
+ real factor=labelmargin(p);
+ margin.begin=begin*factor;
+ margin.end=end*factor;
+ margin.g=trim(g,margin.begin,margin.end);
+ return margin;
+ };
+}
+
+margin PenMargin(real begin, real end)
+{
+ return new marginT(path g, pen p) {
+ marginT margin;
+ real factor=linewidth(p);
+ margin.begin=(begin+0.5)*factor;
+ margin.end=(end+0.5)*factor;
+ margin.g=trim(g,margin.begin,margin.end);
+ return margin;
+ };
+}
+
+margin DotMargin(real begin, real end)
+{
+ return new marginT(path g, pen p) {
+ marginT margin;
+ real margindot(real x) {return x > 0 ? dotfactor*x : x;}
+ real factor=linewidth(p);
+ margin.begin=(margindot(begin)+0.5)*factor;
+ margin.end=(margindot(end)+0.5)*factor;
+ margin.g=trim(g,margin.begin,margin.end);
+ return margin;
+ };
+}
+
+margin TrueMargin(real begin, real end)
+{
+ return new marginT(path g, pen p) {
+ marginT margin;
+ margin.begin=begin;
+ margin.end=end;
+ margin.g=trim(g,begin,end);
+ return margin;
+ };
+}
+
+margin NoMargin=NoMargin(),
+ BeginMargin=Margin(1,0),
+ Margin=Margin(0,1),
+ EndMargin=Margin,
+ Margins=Margin(1,1),
+ BeginPenMargin=PenMargin(0.5,-0.5),
+ PenMargin=PenMargin(-0.5,0.5),
+ EndPenMargin=PenMargin,
+ PenMargins=PenMargin(0.5,0.5),
+ BeginDotMargin=DotMargin(0.5,-0.5),
+ DotMargin=DotMargin(-0.5,0.5),
+ EndDotMargin=DotMargin,
+ DotMargins=DotMargin(0.5,0.5);
diff --git a/Build/source/utils/asymptote/base/plain_markers.asy b/Build/source/utils/asymptote/base/plain_markers.asy
new file mode 100644
index 00000000000..67b218f716d
--- /dev/null
+++ b/Build/source/utils/asymptote/base/plain_markers.asy
@@ -0,0 +1,377 @@
+real legendlinelength=50;
+real legendhskip=1.2;
+real legendvskip=legendhskip;
+real legendmargin=10;
+real legendmaxrelativewidth=1;
+
+// Return a unit polygon with n sides.
+path polygon(int n)
+{
+ guide g;
+ for(int i=0; i < n; ++i) g=g--expi(2pi*(i+0.5)/n-0.5*pi);
+ return g--cycle;
+}
+
+// Return a unit n-point cyclic cross, with optional inner radius r and
+// end rounding.
+path cross(int n, bool round=true, real r=0)
+{
+ assert(n > 1);
+ real r=min(r,1);
+ real theta=pi/n;
+ real s=sin(theta);
+ real c=cos(theta);
+ pair z=(c,s);
+ transform mirror=reflect(0,z);
+ pair p1=(r,0);
+ path elementary;
+ if(round) {
+ pair e1=p1+z*max(1-r*(s+c),0);
+ elementary=p1--e1..(c,s)..mirror*e1--mirror*p1;
+ } else {
+ pair p2=p1+z*(max(sqrt(1-(r*s)^2)-r*c),0);
+ elementary=p1--p2--mirror*p2--mirror*p1;
+ }
+
+ guide g;
+ real step=360/n;
+ for(int i=0; i < n; ++i)
+ g=g--rotate(i*step-90)*elementary;
+
+ return g--cycle;
+}
+
+path[] plus=(-1,0)--(1,0)^^(0,-1)--(0,1);
+
+typedef void markroutine(picture pic=currentpicture, frame f, path g);
+
+// On picture pic, add frame f about every node of path g.
+void marknodes(picture pic=currentpicture, frame f, path g) {
+ for(int i=0; i < size(g); ++i)
+ add(pic,f,point(g,i));
+}
+
+// On picture pic, add n copies of frame f to path g, evenly spaced in
+// arclength.
+// If rotated=true, the frame will be rotated by the angle of the tangent
+// to the path at the points where the frame will be added.
+// If centered is true, center the frames within n evenly spaced arclength
+// intervals.
+markroutine markuniform(bool centered=false, int n, bool rotated=false) {
+ return new void(picture pic=currentpicture, frame f, path g) {
+ if(n <= 0) return;
+ void add(real x) {
+ real t=reltime(g,x);
+ add(pic,rotated ? rotate(degrees(dir(g,t)))*f : f,point(g,t));
+ }
+ if(centered) {
+ real width=1/n;
+ for(int i=0; i < n; ++i) add((i+0.5)*width);
+ } else {
+ if(n == 1) add(0.5);
+ else {
+ real width=1/(n-1);
+ for(int i=0; i < n; ++i)
+ add(i*width);
+ }
+ }
+ };
+}
+
+// On picture pic, add frame f at points z(t) for n evenly spaced values of
+// t in [a,b].
+markroutine markuniform(pair z(real t), real a, real b, int n)
+{
+ return new void(picture pic=currentpicture, frame f, path) {
+ real width=b-a;
+ for(int i=0; i <= n; ++i) {
+ add(pic,f,z(a+i/n*width));
+ }
+ };
+}
+
+struct marker {
+ frame f;
+ bool above=true;
+ markroutine markroutine=marknodes;
+ void mark(picture pic=currentpicture, path g) {
+ markroutine(pic,f,g);
+ };
+}
+
+marker marker(frame f=newframe, markroutine markroutine=marknodes,
+ bool above=true)
+{
+ marker m=new marker;
+ m.f=f;
+ m.above=above;
+ m.markroutine=markroutine;
+ return m;
+}
+
+marker marker(path[] g, markroutine markroutine=marknodes, pen p=currentpen,
+ filltype filltype=NoFill, bool above=true)
+{
+ frame f;
+ filltype.fill(f,g,p);
+ return marker(f,markroutine,above);
+}
+
+marker nomarker;
+
+real circlescale=0.85;
+
+marker[] Mark={
+ marker(scale(circlescale)*unitcircle),
+ marker(polygon(3)),marker(polygon(4)),
+ marker(polygon(5)),marker(invert*polygon(3)),
+ marker(cross(4)),marker(cross(6))
+};
+
+marker[] MarkFill={
+ marker(scale(circlescale)*unitcircle,Fill),marker(polygon(3),Fill),
+ marker(polygon(4),Fill),marker(polygon(5),Fill),
+ marker(invert*polygon(3),Fill)
+};
+
+marker Mark(int n)
+{
+ n=n % (Mark.length+MarkFill.length);
+ if(n < Mark.length) return Mark[n];
+ else return MarkFill[n-Mark.length];
+}
+
+picture legenditem(Legend legenditem, real linelength)
+{
+ picture pic;
+ pair z1=(0,0);
+ pair z2=z1+(linelength,0);
+ if(!legenditem.above && !empty(legenditem.mark))
+ marknodes(pic,legenditem.mark,interp(z1,z2,0.5));
+ if(linelength > 0)
+ Draw(pic,z1--z2,legenditem.p);
+ if(legenditem.above && !empty(legenditem.mark))
+ marknodes(pic,legenditem.mark,interp(z1,z2,0.5));
+ if(legenditem.plabel != invisible)
+ label(pic,legenditem.label,z2,E,legenditem.plabel);
+ else
+ label(pic,legenditem.label,z2,E,currentpen);
+ return pic;
+}
+
+picture legend(Legend[] Legend, int perline=1, real linelength,
+ real hskip, real vskip, real maxwidth=0, real maxheight=0,
+ bool hstretch=false, bool vstretch=false)
+{
+ if(maxwidth <= 0) hstretch=false;
+ if(maxheight <= 0) vstretch=false;
+ if(Legend.length <= 1) vstretch=hstretch=false;
+
+ picture inset;
+ size(inset,0,0,IgnoreAspect);
+
+ if(Legend.length == 0)
+ return inset;
+
+ // Check for legend entries with lines:
+ bool bLineEntriesAvailable=false;
+ for(int i=0; i < Legend.length; ++i) {
+ if(Legend[i].p != invisible) {
+ bLineEntriesAvailable=true;
+ break;
+ }
+ }
+
+ real markersize=0;
+ for(int i=0; i < Legend.length; ++i)
+ markersize=max(markersize,size(Legend[i].mark).x);
+
+ // If no legend has a line, set the line length to zero
+ if(!bLineEntriesAvailable)
+ linelength=0;
+
+ linelength=max(linelength,markersize*(linelength == 0 ? 1 : 2));
+
+ // Get the maximum dimensions per legend entry;
+ // calculate line length for a one-line legend
+ real heightPerEntry=0;
+ real widthPerEntry=0;
+ real totalwidth=0;
+ for(int i=0; i < Legend.length; ++i) {
+ picture pic=legenditem(Legend[i],linelength);
+ pair lambda=size(pic);
+ heightPerEntry=max(heightPerEntry,lambda.y);
+ widthPerEntry=max(widthPerEntry,lambda.x);
+ if(Legend[i].p != invisible)
+ totalwidth += lambda.x;
+ else {
+ // Legend entries without leading line need less space in one-line legends
+ picture pic=legenditem(Legend[i],0);
+ totalwidth += size(pic).x;
+ }
+ }
+ // Does everything fit into one line?
+ if(((perline < 1) || (perline >= Legend.length)) &&
+ (maxwidth >= totalwidth+(totalwidth/Legend.length)*
+ (Legend.length-1)*(hskip-1))) {
+ // One-line legend
+ real currPosX=0;
+ real itemDistance;
+ if(hstretch)
+ itemDistance=(maxwidth-totalwidth)/(Legend.length-1);
+ else
+ itemDistance=(totalwidth/Legend.length)*(hskip-1);
+ for(int i=0; i < Legend.length; ++i) {
+ picture pic=legenditem(Legend[i],
+ Legend[i].p == invisible ? 0 : linelength);
+ add(inset,pic,(currPosX,0));
+ currPosX += size(pic).x+itemDistance;
+ }
+ } else {
+ // multiline legend
+ if(maxwidth > 0) {
+ int maxperline=floor(maxwidth/(widthPerEntry*hskip));
+ if((perline < 1) || (perline > maxperline))
+ perline=maxperline;
+ }
+ if(perline < 1) // This means: maxwidth < widthPerEntry
+ perline=1;
+
+ if(perline <= 1) hstretch=false;
+ if(hstretch) hskip=(maxwidth/widthPerEntry-perline)/(perline-1)+1;
+ if(vstretch) {
+ int rows=ceil(Legend.length/perline);
+ vskip=(maxheight/heightPerEntry-rows)/(rows-1)+1;
+ }
+
+ if(hstretch && (perline == 1)) {
+ Draw(inset,(0,0)--(maxwidth,0),invisible());
+ for(int i=0; i < Legend.length; ++i)
+ add(inset,legenditem(Legend[i],linelength),
+ (0.5*(maxwidth-widthPerEntry),
+ -quotient(i,perline)*heightPerEntry*vskip));
+ } else
+ for(int i=0; i < Legend.length; ++i)
+ add(inset,legenditem(Legend[i],linelength),
+ ((i%perline)*widthPerEntry*hskip,
+ -quotient(i,perline)*heightPerEntry*vskip));
+ }
+
+ return inset;
+}
+
+frame legend(picture pic=currentpicture, int perline=1,
+ real xmargin=legendmargin, real ymargin=xmargin,
+ real linelength=legendlinelength,
+ real hskip=legendhskip, real vskip=legendvskip,
+ real maxwidth=perline == 0 ?
+ legendmaxrelativewidth*size(pic).x : 0, real maxheight=0,
+ bool hstretch=false, bool vstretch=false, pen p=currentpen)
+{
+ frame F;
+ if(pic.legend.length == 0) return F;
+ F=legend(pic.legend,perline,linelength,hskip,vskip,
+ max(maxwidth-2xmargin,0),
+ max(maxheight-2ymargin,0),
+ hstretch,vstretch).fit();
+ box(F,xmargin,ymargin,p);
+ return F;
+}
+
+pair[] pairs(real[] x, real[] y)
+{
+ if(x.length != y.length) abort("arrays have different lengths");
+ return sequence(new pair(int i) {return (x[i],y[i]);},x.length);
+}
+
+void dot(frame f, pair z, pen p=currentpen, filltype filltype=Fill)
+{
+ if(filltype == Fill)
+ draw(f,z,dotsize(p)+p);
+ else {
+ transform t=shift(z);
+ path g=t*scale(0.5*(dotsize(p)-linewidth(p)))*unitcircle;
+ begingroup(f);
+ filltype.fill(f,g,p);
+ draw(f,g,p);
+ endgroup(f);
+ }
+}
+
+void dot(picture pic=currentpicture, pair z, pen p=currentpen,
+ filltype filltype=Fill)
+{
+ pic.add(new void(frame f, transform t) {
+ dot(f,t*z,p,filltype);
+ },true);
+ pic.addPoint(z,dotsize(p)+p);
+}
+
+void dot(picture pic=currentpicture, Label L, pair z, align align=NoAlign,
+ string format=defaultformat, pen p=currentpen, filltype filltype=Fill)
+{
+ Label L=L.copy();
+ L.position(z);
+ if(L.s == "") {
+ if(format == "") format=defaultformat;
+ L.s="("+format(format,z.x)+","+format(format,z.y)+")";
+ }
+ L.align(align,E);
+ L.p(p);
+ dot(pic,z,p,filltype);
+ add(pic,L);
+}
+
+void dot(picture pic=currentpicture, Label[] L=new Label[], pair[] z,
+ align align=NoAlign, string format=defaultformat, pen p=currentpen,
+ filltype filltype=Fill)
+{
+ int stop=min(L.length,z.length);
+ for(int i=0; i < stop; ++i)
+ dot(pic,L[i],z[i],align,format,p,filltype);
+ for(int i=stop; i < z.length; ++i)
+ dot(pic,z[i],p,filltype);
+}
+
+void dot(picture pic=currentpicture, Label[] L=new Label[],
+ explicit path g, align align=RightSide, string format=defaultformat,
+ pen p=currentpen, filltype filltype=Fill)
+{
+ int n=size(g);
+ int stop=min(L.length,n);
+ for(int i=0; i < stop; ++i)
+ dot(pic,L[i],point(g,i),-sgn(align.dir.x)*I*dir(g,i),format,p,filltype);
+ for(int i=stop; i < n; ++i)
+ dot(pic,point(g,i),p,filltype);
+}
+
+void dot(picture pic=currentpicture, path[] g, pen p=currentpen,
+ filltype filltype=Fill)
+{
+ for(int i=0; i < g.length; ++i)
+ dot(pic,g[i],p,filltype);
+}
+
+void dot(picture pic=currentpicture, Label L, pen p=currentpen,
+ filltype filltype=Fill)
+{
+ dot(pic,L,L.position,p,filltype);
+}
+
+// A dot in a frame.
+frame dotframe(pen p=currentpen, filltype filltype=Fill)
+{
+ frame f;
+ dot(f,(0,0),p,filltype);
+ return f;
+}
+
+frame dotframe=dotframe();
+
+marker dot(pen p=currentpen, filltype filltype=Fill)
+{
+ return marker(dotframe(p,filltype));
+}
+
+marker dot=dot();
+
diff --git a/Build/source/utils/asymptote/base/plain_paths.asy b/Build/source/utils/asymptote/base/plain_paths.asy
new file mode 100644
index 00000000000..486f3f0cc7b
--- /dev/null
+++ b/Build/source/utils/asymptote/base/plain_paths.asy
@@ -0,0 +1,380 @@
+path nullpath;
+
+typedef guide interpolate(... guide[]);
+
+// These numbers identify the side of a specifier in an operator spec or
+// operator curl expression:
+// a{out} .. {in}b
+restricted int JOIN_OUT=0;
+restricted int JOIN_IN=1;
+
+// Define a.. tension t ..b to be equivalent to
+// a.. tension t and t ..b
+// and likewise with controls.
+tensionSpecifier operator tension(real t, bool atLeast)
+{
+ return operator tension(t,t,atLeast);
+}
+guide operator controls(pair z)
+{
+ return operator controls(z,z);
+}
+
+guide[] operator cast(pair[] z)
+{
+ return sequence(new guide(int i) {return z[i];},z.length);
+}
+
+path[] operator cast(pair[] z)
+{
+ return sequence(new path(int i) {return z[i];},z.length);
+}
+
+path[] operator cast(guide[] g)
+{
+ return sequence(new path(int i) {return g[i];},g.length);
+}
+
+guide[] operator cast(path[] g)
+{
+ return sequence(new guide(int i) {return g[i];},g.length);
+}
+
+path[] operator cast(path p)
+{
+ return new path[] {p};
+}
+
+path[] operator cast(guide g)
+{
+ return new path[] {(path) g};
+}
+
+path[] operator ^^ (path p, path q)
+{
+ return new path[] {p,q};
+}
+
+path[] operator ^^ (path p, explicit path[] q)
+{
+ return concat(new path[] {p},q);
+}
+
+path[] operator ^^ (explicit path[] p, path q)
+{
+ return concat(p,new path[] {q});
+}
+
+path[] operator ^^ (explicit path[] p, explicit path[] q)
+{
+ return concat(p,q);
+}
+
+path[] operator * (transform t, explicit path[] p)
+{
+ return sequence(new path(int i) {return t*p[i];},p.length);
+}
+
+pair[] operator * (transform t, pair[] z)
+{
+ return sequence(new pair(int i) {return t*z[i];},z.length);
+}
+
+void write(file file, string s="", explicit path[] x, suffix suffix=none)
+{
+ write(file,s);
+ if(x.length > 0) write(file,x[0]);
+ for(int i=1; i < x.length; ++i) {
+ write(file,endl);
+ write(file," ^^");
+ write(file,x[i]);
+ }
+ write(file,suffix);
+}
+
+void write(file file, string s="", explicit guide[] x, suffix suffix=none)
+{
+ write(file,s,(path[]) x,suffix);
+}
+
+void write(string s="", explicit path[] x, suffix suffix=endl)
+{
+ write(stdout,s,x,suffix);
+}
+
+void write(string s="", explicit guide[] x, suffix suffix=endl)
+{
+ write(stdout,s,(path[]) x,suffix);
+}
+
+private string nopoints="nullpath has no points";
+
+pair min(explicit path[] p)
+{
+ if(p.length == 0) abort(nopoints);
+ pair minp=min(p[0]);
+ for(int i=1; i < p.length; ++i)
+ minp=minbound(minp,min(p[i]));
+ return minp;
+}
+
+pair max(explicit path[] p)
+{
+ if(p.length == 0) abort(nopoints);
+ pair maxp=max(p[0]);
+ for(int i=1; i < p.length; ++i)
+ maxp=maxbound(maxp,max(p[i]));
+ return maxp;
+}
+
+guide operator ::(... guide[] a)
+{
+ if(a.length == 0) return nullpath;
+ guide g=a[0];
+ for(int i=1; i < a.length; ++i)
+ g=g..operator tension(1,true)..a[i];
+ return g;
+}
+
+guide operator ---(... guide[] a)
+{
+ if(a.length == 0) return nullpath;
+ guide g=a[0];
+ for(int i=1; i < a.length; ++i)
+ g=g..operator tension(infinity,true)..a[i];
+ return g;
+}
+
+// return an arbitrary intersection point of paths p and q
+pair intersectionpoint(path p, path q, real fuzz=-1)
+{
+ real[] t=intersect(p,q,fuzz);
+ if(t.length == 0) abort("paths do not intersect");
+ return point(p,t[0]);
+}
+
+// return an array containing all intersection points of the paths p and q
+pair[] intersectionpoints(path p, path q, real fuzz=-1)
+{
+ real[][] t=intersections(p,q,fuzz);
+ return sequence(new pair(int i) {return point(p,t[i][0]);},t.length);
+}
+
+pair[] intersectionpoints(explicit path[] p, explicit path[] q, real fuzz=-1)
+{
+ pair[] z;
+ for(int i=0; i < p.length; ++i)
+ for(int j=0; j < q.length; ++j)
+ z.append(intersectionpoints(p[i],q[j],fuzz));
+ return z;
+}
+
+struct slice {
+ path before,after;
+}
+
+slice cut(path p, path knife, int n)
+{
+ slice s;
+ real[][] T=intersections(p,knife);
+ if(T.length == 0) {s.before=p; s.after=nullpath; return s;}
+ T.cyclic(true);
+ real t=T[n][0];
+ s.before=subpath(p,0,t);
+ s.after=subpath(p,t,length(p));
+ return s;
+}
+
+slice firstcut(path p, path knife)
+{
+ return cut(p,knife,0);
+}
+
+slice lastcut(path p, path knife)
+{
+ return cut(p,knife,-1);
+}
+
+pair dir(path p)
+{
+ return dir(p,length(p));
+}
+
+pair dir(path p, path h)
+{
+ return 0.5*(dir(p)+dir(h));
+}
+
+// return the point on path p at arclength L
+pair arcpoint(path p, real L)
+{
+ return point(p,arctime(p,L));
+}
+
+// return the direction on path p at arclength L
+pair arcdir(path p, real L)
+{
+ return dir(p,arctime(p,L));
+}
+
+// return the time on path p at the relative fraction l of its arclength
+real reltime(path p, real l)
+{
+ return arctime(p,l*arclength(p));
+}
+
+// return the point on path p at the relative fraction l of its arclength
+pair relpoint(path p, real l)
+{
+ return point(p,reltime(p,l));
+}
+
+// return the direction of path p at the relative fraction l of its arclength
+pair reldir(path p, real l)
+{
+ return dir(p,reltime(p,l));
+}
+
+// return the initial point of path p
+pair beginpoint(path p)
+{
+ return point(p,0);
+}
+
+// return the point on path p at half of its arclength
+pair midpoint(path p)
+{
+ return relpoint(p,0.5);
+}
+
+// return the final point of path p
+pair endpoint(path p)
+{
+ return point(p,length(p));
+}
+
+path operator &(path p, cycleToken tok)
+{
+ int n=length(p);
+ if(n < 0) return nullpath;
+ if(n == 0) return p--cycle;
+ if(cyclic(p)) return p;
+ return straight(p,n-1) ? subpath(p,0,n-1)--cycle :
+ subpath(p,0,n-1)..controls postcontrol(p,n-1) and precontrol(p,n)..cycle;
+}
+
+// return a cyclic path enclosing a region bounded by a list of two or more
+// consecutively intersecting paths
+path buildcycle(... path[] p)
+{
+ int n=p.length;
+ if(n < 2) return nullpath;
+ real[] ta=new real[n];
+ real[] tb=new real[n];
+ if(n == 2) {
+ real[][] t=intersections(p[0],p[1]);
+ if(t.length < 2)
+ return nullpath;
+ int k=t.length-1;
+ ta[0]=t[0][0]; tb[0]=t[k][0];
+ ta[1]=t[k][1]; tb[1]=t[0][1];
+ } else {
+ int j=n-1;
+ for(int i=0; i < n; ++i) {
+ real[][] t=intersections(p[i],p[j]);
+ if(t.length == 0)
+ return nullpath;
+ ta[i]=t[0][0]; tb[j]=t[0][1];
+ j=i;
+ }
+ }
+
+ pair c;
+ for(int i=0; i < n ; ++i)
+ c += point(p[i],ta[i]);
+ c /= n;
+
+ path G;
+ for(int i=0; i < n ; ++i) {
+ real Ta=ta[i];
+ real Tb=tb[i];
+ if(cyclic(p[i])) {
+ int L=length(p[i]);
+ real t=Tb-L;
+ if(abs(c-point(p[i],0.5(Ta+t))) <
+ abs(c-point(p[i],0.5(Ta+Tb)))) Tb=t;
+ while(Tb < Ta) Tb += L;
+ }
+ G=G&subpath(p[i],Ta,Tb);
+ }
+ return G&cycle;
+}
+
+// return 1 if p strictly contains q,
+// -1 if q strictly contains p,
+// 0 otherwise.
+int inside(path p, path q, pen fillrule=currentpen)
+{
+ if(intersect(p,q).length > 0) return 0;
+ if(cyclic(p) && inside(p,point(q,0),fillrule)) return 1;
+ if(cyclic(q) && inside(q,point(p,0),fillrule)) return -1;
+ return 0;
+}
+
+// Return an arbitrary point strictly inside a cyclic path p according to
+// the specified fill rule.
+pair inside(path p, pen fillrule=currentpen)
+{
+ if(!cyclic(p)) abort("path is not cyclic");
+ int n=length(p);
+ for(int i=0; i < n; ++i) {
+ pair z=point(p,i);
+ real[] T=intersections(p,z,z+I*dir(p,i));
+ // Check midpoints of line segments formed between the
+ // corresponding intersection points and z.
+ for(int j=0; j < T.length; ++j) {
+ if(T[j] != i) {
+ pair w=point(p,T[j]);
+ pair m=0.5*(z+w);
+ if(inside(windingnumber(p,m),fillrule)) return m;
+ }
+ }
+ }
+ abort("cannot find an interior point");
+ return 0;
+}
+
+// Return all intersection times of path g with the vertical line through (x,0).
+real[] times(path p, real x)
+{
+ return intersections(p,(x,0),(x,1));
+}
+
+// Return all intersection times of path g with the horizontal line through
+// (0,z.y).
+real[] times(path p, explicit pair z)
+{
+ return intersections(p,(0,z.y),(1,z.y));
+}
+
+path randompath(int n, bool cumulate=true, interpolate join=operator ..)
+{
+ guide g;
+ pair w;
+ for(int i=0; i <= n; ++i) {
+ pair z=(unitrand()-0.5,unitrand()-0.5);
+ if(cumulate) w += z;
+ else w=z;
+ g=join(g,w);
+ }
+ return g;
+}
+
+path[] strokepath(path g, pen p=currentpen)
+{
+ path[] G=_strokepath(g,p);
+ if(G.length == 0) return G;
+ pair center(path g) {return 0.5*(min(g)+max(g));}
+ pair center(path[] g) {return 0.5*(min(g)+max(g));}
+ return shift(center(g)-center(G))*G;
+}
diff --git a/Build/source/utils/asymptote/base/plain_pens.asy b/Build/source/utils/asymptote/base/plain_pens.asy
new file mode 100644
index 00000000000..88fc112f684
--- /dev/null
+++ b/Build/source/utils/asymptote/base/plain_pens.asy
@@ -0,0 +1,341 @@
+real labelmargin=0.3;
+real dotfactor=6;
+
+pen solid=linetype("");
+pen dotted=linetype("0 4");
+pen dashed=linetype("8 8");
+pen longdashed=linetype("24 8");
+pen dashdotted=linetype("8 8 0 8");
+pen longdashdotted=linetype("24 8 0 8");
+
+void defaultpen(real w) {defaultpen(linewidth(w));}
+pen operator +(pen p, real w) {return p+linewidth(w);}
+pen operator +(real w, pen p) {return linewidth(w)+p;}
+
+pen Dotted=dotted+1.0;
+pen Dotted(pen p=currentpen) {return dotted+2*linewidth(p);}
+
+restricted pen squarecap=linecap(0);
+restricted pen roundcap=linecap(1);
+restricted pen extendcap=linecap(2);
+
+restricted pen miterjoin=linejoin(0);
+restricted pen roundjoin=linejoin(1);
+restricted pen beveljoin=linejoin(2);
+
+restricted pen zerowinding=fillrule(0);
+restricted pen evenodd=fillrule(1);
+bool inside(int windingnumber, pen fillrule) {
+ return windingnumber != undefined &&
+ (fillrule(fillrule) == 1 ? windingnumber % 2 == 1 : windingnumber != 0);
+}
+
+restricted pen nobasealign=basealign(0);
+restricted pen basealign=basealign(1);
+
+pen invisible=invisible();
+pen thin() {return settings.thin ? linewidth(0) : defaultpen;}
+pen thick(pen p=currentpen) {return linewidth(linewidth(p));}
+pen nullpen=linewidth(0)+invisible;
+
+pen black=gray(0);
+pen white=gray(1);
+pen gray=gray(0.5);
+
+pen red=rgb(1,0,0);
+pen green=rgb(0,1,0);
+pen blue=rgb(0,0,1);
+
+pen Cyan=cmyk(1,0,0,0);
+pen Magenta=cmyk(0,1,0,0);
+pen Yellow=cmyk(0,0,1,0);
+pen Black=cmyk(0,0,0,1);
+
+pen cyan=rgb(0,1,1);
+pen magenta=rgb(1,0,1);
+pen yellow=rgb(1,1,0);
+
+pen palered=rgb(1,0.75,0.75);
+pen palegreen=rgb(0.75,1,0.75);
+pen paleblue=rgb(0.75,0.75,1);
+pen palecyan=rgb(0.75,1,1);
+pen palemagenta=rgb(1,0.75,1);
+pen paleyellow=rgb(1,1,0.75);
+pen palegray=gray(0.95);
+
+pen lightred=rgb(1,0.5,0.5);
+pen lightgreen=rgb(0.5,1,0.5);
+pen lightblue=rgb(0.5,0.5,1);
+pen lightcyan=rgb(0.5,1,1);
+pen lightmagenta=rgb(1,0.5,1);
+pen lightyellow=rgb(1,1,0.5);
+pen lightgray=gray(0.9);
+
+pen mediumred=rgb(1,0.25,0.25);
+pen mediumgreen=rgb(0.25,1,0.25);
+pen mediumblue=rgb(0.25,0.25,1);
+pen mediumcyan=rgb(0.25,1,1);
+pen mediummagenta=rgb(1,0.25,1);
+pen mediumyellow=rgb(1,1,0.25);
+pen mediumgray=gray(0.75);
+
+pen heavyred=rgb(0.75,0,0);
+pen heavygreen=rgb(0,0.75,0);
+pen heavyblue=rgb(0,0,0.75);
+pen heavycyan=rgb(0,0.75,0.75);
+pen heavymagenta=rgb(0.75,0,0.75);
+pen lightolive=rgb(0.75,0.75,0);
+pen heavygray=gray(0.25);
+
+pen deepred=rgb(0.5,0,0);
+pen deepgreen=rgb(0,0.5,0);
+pen deepblue=rgb(0,0,0.5);
+pen deepcyan=rgb(0,0.5,0.5);
+pen deepmagenta=rgb(0.5,0,0.5);
+pen olive=rgb(0.5,0.5,0);
+pen deepgray=gray(0.1);
+
+pen darkred=rgb(0.25,0,0);
+pen darkgreen=rgb(0,0.25,0);
+pen darkblue=rgb(0,0,0.25);
+pen darkcyan=rgb(0,0.25,0.25);
+pen darkmagenta=rgb(0.25,0,0.25);
+pen darkolive=rgb(0.25,0.25,0);
+pen darkgray=gray(0.05);
+
+pen orange=rgb(1,0.5,0);
+pen fuchsia=rgb(1,0,0.5);
+
+pen chartreuse=rgb(0.5,1,0);
+pen springgreen=rgb(0,1,0.5);
+
+pen purple=rgb(0.5,0,1);
+pen royalblue=rgb(0,0.5,1);
+
+// Synonyms:
+
+pen salmon=lightred;
+pen brown=deepred;
+pen darkbrown=darkred;
+pen pink=palemagenta;
+pen palegrey=palegray;
+pen lightgrey=lightgray;
+pen mediumgrey=mediumgray;
+pen grey=gray;
+pen heavygrey=gray;
+pen deepgrey=deepgray;
+pen darkgrey=darkgray;
+
+// Options for handling label overwriting
+restricted int Allow=0;
+restricted int Suppress=1;
+restricted int SuppressQuiet=2;
+restricted int Move=3;
+restricted int MoveQuiet=4;
+
+pen[] colorPen={red,blue,green,magenta,cyan,orange,purple,brown,
+ deepblue,deepgreen,chartreuse,fuchsia,lightred,
+ lightblue,black,pink,yellow,gray};
+
+colorPen.cyclic(true);
+
+pen[] monoPen={solid,dashed,dotted,longdashed,dashdotted,
+ longdashdotted};
+monoPen.cyclic(true);
+
+pen Pen(int n)
+{
+ return (settings.gray || settings.bw) ? monoPen[n] : colorPen[n];
+}
+
+pen Pentype(int n)
+{
+ return (settings.gray || settings.bw) ? monoPen[n] : monoPen[n]+colorPen[n];
+}
+
+real dotsize(pen p=currentpen)
+{
+ return dotfactor*linewidth(p);
+}
+
+pen fontsize(real size)
+{
+ return fontsize(size,1.2*size);
+}
+
+real labelmargin(pen p=currentpen)
+{
+ return labelmargin*fontsize(p);
+}
+
+void write(file file=stdout, string s="", pen[] p)
+{
+ for(int i=0; i < p.length; ++i)
+ write(file,s,p[i],endl);
+}
+
+pen font(string name)
+{
+ return fontcommand("\font\ASYfont="+name+"\ASYfont");
+}
+
+pen font(string name, real size)
+{
+ return fontsize(size)+font(name+" at "+(string) size+"pt");
+}
+
+pen font(string encoding, string family, string series="m", string shape="n")
+{
+ return fontcommand("\usefont{"+encoding+"}{"+family+"}{"+series+"}{"+shape+
+ "}");
+}
+
+pen AvantGarde(string series="m", string shape="n")
+{
+ return font("OT1","pag",series,shape);
+}
+pen Bookman(string series="m", string shape="n")
+{
+ return font("OT1","pbk",series,shape);
+}
+pen Courier(string series="m", string shape="n")
+{
+ return font("OT1","pcr",series,shape);
+}
+pen Helvetica(string series="m", string shape="n")
+{
+ return font("OT1","phv",series,shape);
+}
+pen NewCenturySchoolBook(string series="m", string shape="n")
+{
+ return font("OT1","pnc",series,shape);
+}
+pen Palatino(string series="m", string shape="n")
+{
+ return font("OT1","ppl",series,shape);
+}
+pen TimesRoman(string series="m", string shape="n")
+{
+ return font("OT1","ptm",series,shape);
+}
+pen ZapfChancery(string series="m", string shape="n")
+{
+ return font("OT1","pzc",series,shape);
+}
+pen Symbol(string series="m", string shape="n")
+{
+ return font("OT1","psy",series,shape);
+}
+pen ZapfDingbats(string series="m", string shape="n")
+{
+ return font("OT1","pzd",series,shape);
+}
+
+pen squarepen=makepen(shift(-0.5,-0.5)*unitsquare);
+
+struct hsv {
+ real h;
+ real v;
+ real s;
+ void operator init(real h, real s, real v) {
+ this.h=h;
+ this.s=s;
+ this.v=v;
+ }
+ void operator init(pen p) {
+ real[] c=colors(rgb(p));
+ real r=c[0];
+ real g=c[1];
+ real b=c[2];
+ real M=max(r,g,b);
+ real m=min(r,g,b);
+ if(M == m) this.h=0;
+ else {
+ real denom=1/(M-m);
+ if(M == r) {
+ this.h=60*(g-b)*denom;
+ if(g < b) h += 360;
+ } else if(M == g) {
+ this.h=60*(b-r)*denom+120;
+ } else
+ this.h=60*(r-g)*denom+240;
+ }
+ this.s=M == 0 ? 0 : 1-m/M;
+ this.v=M;
+ }
+ // return an rgb pen corresponding to h in [0,360) and s and v in [0,1].
+ pen rgb() {
+ real H=(h % 360)/60;
+ int i=floor(H) % 6;
+ real f=H-i;
+ real[] V={v,v*(1-s),v*(1-(i % 2 == 0 ? 1-f : f)*s)};
+ int[] a={0,2,1,1,2,0};
+ int[] b={2,0,0,2,1,1};
+ int[] c={1,1,2,0,0,2};
+ return rgb(V[a[i]],V[b[i]],V[c[i]]);
+ }
+}
+
+pen operator cast(hsv hsv)
+{
+ return hsv.rgb();
+}
+
+hsv operator cast(pen p)
+{
+ return hsv(p);
+}
+
+real[] rgba(pen p)
+{
+ real[] a=colors(rgb(p));
+ a.push(opacity(p));
+ return a;
+}
+
+pen rgba(real[] a)
+{
+ return rgb(a[0],a[1],a[2])+opacity(a[3]);
+}
+
+// Return a pen corresponding to a given 6-character RGB hexidecimal string.
+pen rgb(string s)
+{
+ real value(string s, int i) {return hex(substr(s,2i,2))/255;}
+ return rgb(value(s,0),value(s,1),value(s,2));
+}
+
+pen[] operator +(pen[] a, pen b)
+{
+ return sequence(new pen(int i) {return a[i]+b;},a.length);
+}
+
+pen[] operator +(pen a, pen[] b)
+{
+ return sequence(new pen(int i) {return a+b[i];},b.length);
+}
+
+// Interpolate an array of pens in rgb space using by default their minimum
+// opacity.
+pen mean(pen[] p, real opacity(real[])=min)
+{
+ if(p.length == 0) return nullpen;
+ real[] a=rgba(p[0]);
+ real[] t=new real[p.length];
+ t[0]=a[3];
+ for(int i=1; i < p.length; ++i) {
+ real[] b=rgba(p[i]);
+ a += b;
+ t[i]=b[3];
+ }
+ a /= p.length;
+ return rgb(a[0],a[1],a[2])+opacity(opacity(t));
+}
+
+pen[] mean(pen[][] palette, real opacity(real[])=min)
+{
+ return sequence(new pen(int i) {return mean(palette[i],opacity);},
+ palette.length);
+}
+
+
diff --git a/Build/source/utils/asymptote/base/plain_picture.asy b/Build/source/utils/asymptote/base/plain_picture.asy
new file mode 100644
index 00000000000..4d894dc6dea
--- /dev/null
+++ b/Build/source/utils/asymptote/base/plain_picture.asy
@@ -0,0 +1,1892 @@
+real camerafactor=2; // Factor used for camera adjustment.
+pair viewportsize=0; // Horizontal and vertical viewport limits.
+
+restricted bool Aspect=true;
+restricted bool IgnoreAspect=false;
+
+pair size(frame f)
+{
+ return max(f)-min(f);
+}
+
+typedef real[][] transform3;
+restricted transform3 identity4=identity(4);
+
+// A uniform 3D scaling.
+transform3 scale3(real s)
+{
+ transform3 t=identity(4);
+ t[0][0]=t[1][1]=t[2][2]=s;
+ return t;
+}
+
+// Simultaneous 3D scalings in the x, y, and z directions.
+transform3 scale(real x, real y, real z)
+{
+ transform3 t=identity(4);
+ t[0][0]=x;
+ t[1][1]=y;
+ t[2][2]=z;
+ return t;
+}
+
+transform3 shiftless(transform3 t)
+{
+ transform3 T=copy(t);
+ T[0][3]=T[1][3]=T[2][3]=0;
+ return T;
+}
+
+// A coordinate in "flex space." A linear combination of user and true-size
+// coordinates.
+struct coord {
+ real user,truesize;
+ bool finite=true;
+
+ // Build a coord.
+ static coord build(real user, real truesize) {
+ coord c=new coord;
+ c.user=user;
+ c.truesize=truesize;
+ return c;
+ }
+
+ // Deep copy of coordinate. Users may add coords to the picture, but then
+ // modify the struct. To prevent this from yielding unexpected results, deep
+ // copying is used.
+ coord copy() {
+ return build(user, truesize);
+ }
+
+ void clip(real min, real max) {
+ user=min(max(user,min),max);
+ truesize=0;
+ }
+}
+
+struct coords2 {
+ coord[] x,y;
+ void erase() {
+ x.delete();
+ y.delete();
+ }
+ // Only a shallow copy of the individual elements of x and y
+ // is needed since, once entered, they are never modified.
+ coords2 copy() {
+ coords2 c=new coords2;
+ c.x=copy(x);
+ c.y=copy(y);
+ return c;
+ }
+ void append(coords2 c) {
+ x.append(c.x);
+ y.append(c.y);
+ }
+ void push(pair user, pair truesize) {
+ x.push(coord.build(user.x,truesize.x));
+ y.push(coord.build(user.y,truesize.y));
+ }
+ void push(coord cx, coord cy) {
+ x.push(cx);
+ y.push(cy);
+ }
+ void push(transform t, coords2 c1, coords2 c2) {
+ for(int i=0; i < c1.x.length; ++i) {
+ coord cx=c1.x[i], cy=c2.y[i];
+ pair tinf=shiftless(t)*((finite(cx.user) ? 0 : 1),
+ (finite(cy.user) ? 0 : 1));
+ pair z=t*(cx.user,cy.user);
+ pair w=(cx.truesize,cy.truesize);
+ w=length(w)*unit(shiftless(t)*w);
+ coord Cx,Cy;
+ Cx.user=(tinf.x == 0 ? z.x : infinity);
+ Cy.user=(tinf.y == 0 ? z.y : infinity);
+ Cx.truesize=w.x;
+ Cy.truesize=w.y;
+ push(Cx,Cy);
+ }
+ }
+ void xclip(real min, real max) {
+ for(int i=0; i < x.length; ++i)
+ x[i].clip(min,max);
+ }
+ void yclip(real min, real max) {
+ for(int i=0; i < y.length; ++i)
+ y[i].clip(min,max);
+ }
+}
+
+struct coords3 {
+ coord[] x,y,z;
+ void erase() {
+ x.delete();
+ y.delete();
+ z.delete();
+ }
+ // Only a shallow copy of the individual elements of x and y
+ // is needed since, once entered, they are never modified.
+ coords3 copy() {
+ coords3 c=new coords3;
+ c.x=copy(x);
+ c.y=copy(y);
+ c.z=copy(z);
+ return c;
+ }
+ void append(coords3 c) {
+ x.append(c.x);
+ y.append(c.y);
+ z.append(c.z);
+ }
+ void push(triple user, triple truesize) {
+ x.push(coord.build(user.x,truesize.x));
+ y.push(coord.build(user.y,truesize.y));
+ z.push(coord.build(user.z,truesize.z));
+ }
+ void push(coord cx, coord cy, coord cz) {
+ x.push(cx);
+ y.push(cy);
+ z.push(cz);
+ }
+ void push(transform3 t, coords3 c1, coords3 c2, coords3 c3) {
+ for(int i=0; i < c1.x.length; ++i) {
+ coord cx=c1.x[i], cy=c2.y[i], cz=c3.z[i];
+ triple tinf=shiftless(t)*((finite(cx.user) ? 0 : 1),
+ (finite(cy.user) ? 0 : 1),
+ (finite(cz.user) ? 0 : 1));
+ triple z=t*(cx.user,cy.user,cz.user);
+ triple w=(cx.truesize,cy.truesize,cz.truesize);
+ w=length(w)*unit(shiftless(t)*w);
+ coord Cx,Cy,Cz;
+ Cx.user=(tinf.x == 0 ? z.x : infinity);
+ Cy.user=(tinf.y == 0 ? z.y : infinity);
+ Cz.user=(tinf.z == 0 ? z.z : infinity);
+ Cx.truesize=w.x;
+ Cy.truesize=w.y;
+ Cz.truesize=w.z;
+ push(Cx,Cy,Cz);
+ }
+ }
+}
+
+bool operator <= (coord a, coord b)
+{
+ return a.user <= b.user && a.truesize <= b.truesize;
+}
+
+bool operator >= (coord a, coord b)
+{
+ return a.user >= b.user && a.truesize >= b.truesize;
+}
+
+// Find the maximal elements of the input array, using the partial ordering
+// given.
+coord[] maxcoords(coord[] in, bool operator <= (coord,coord))
+{
+ // As operator <= is defined in the parameter list, it has a special
+ // meaning in the body of the function.
+
+ coord best;
+ coord[] c;
+
+ int n=in.length;
+
+ // Find the first finite restriction.
+ int first=0;
+ for(first=0; first < n; ++first)
+ if(finite(in[first].user)) break;
+
+ if(first == n)
+ return c;
+ else {
+ // Add the first coord without checking restrictions (as there are none).
+ best=in[first];
+ c.push(best);
+ }
+
+ static int NONE=-1;
+
+ int dominator(coord x)
+ {
+ // This assumes it has already been checked against the best.
+ for(int i=1; i < c.length; ++i)
+ if(x <= c[i])
+ return i;
+ return NONE;
+ }
+
+ void promote(int i)
+ {
+ // Swap with the top
+ coord x=c[i];
+ c[i]=best;
+ best=c[0]=x;
+ }
+
+ void addmaximal(coord x)
+ {
+ coord[] newc;
+
+ // Check if it beats any others.
+ for(int i=0; i < c.length; ++i) {
+ coord y=c[i];
+ if(!(y <= x))
+ newc.push(y);
+ }
+ newc.push(x);
+ c=newc;
+ best=c[0];
+ }
+
+ void add(coord x)
+ {
+ if(x <= best || !finite(x.user))
+ return;
+ else {
+ int i=dominator(x);
+ if(i == NONE)
+ addmaximal(x);
+ else
+ promote(i);
+ }
+ }
+
+ for(int i=1; i < n; ++i)
+ add(in[i]);
+
+ return c;
+}
+
+typedef real scalefcn(real x);
+
+struct scaleT {
+ scalefcn T,Tinv;
+ bool logarithmic;
+ bool automin,automax;
+ void operator init(scalefcn T, scalefcn Tinv, bool logarithmic=false,
+ bool automin=false, bool automax=false) {
+ this.T=T;
+ this.Tinv=Tinv;
+ this.logarithmic=logarithmic;
+ this.automin=automin;
+ this.automax=automax;
+ }
+ scaleT copy() {
+ scaleT dest=scaleT(T,Tinv,logarithmic,automin,automax);
+ return dest;
+ }
+};
+
+scaleT operator init()
+{
+ scaleT S=scaleT(identity,identity);
+ return S;
+}
+
+typedef void boundRoutine();
+
+struct autoscaleT {
+ scaleT scale;
+ scaleT postscale;
+ real tickMin=-infinity, tickMax=infinity;
+ boundRoutine[] bound; // Optional routines to recompute the bounding box.
+ bool automin=false, automax=false;
+ bool automin() {return automin && scale.automin;}
+ bool automax() {return automax && scale.automax;}
+
+ real T(real x) {return postscale.T(scale.T(x));}
+ scalefcn T() {return scale.logarithmic ? postscale.T : T;}
+ real Tinv(real x) {return scale.Tinv(postscale.Tinv(x));}
+
+ autoscaleT copy() {
+ autoscaleT dest=new autoscaleT;
+ dest.scale=scale.copy();
+ dest.postscale=postscale.copy();
+ dest.tickMin=tickMin;
+ dest.tickMax=tickMax;
+ dest.bound=copy(bound);
+ dest.automin=(bool) automin;
+ dest.automax=(bool) automax;
+ return dest;
+ }
+}
+
+struct ScaleT {
+ bool set;
+ autoscaleT x;
+ autoscaleT y;
+ autoscaleT z;
+
+ ScaleT copy() {
+ ScaleT dest=new ScaleT;
+ dest.set=set;
+ dest.x=x.copy();
+ dest.y=y.copy();
+ dest.z=z.copy();
+ return dest;
+ }
+};
+
+struct Legend {
+ string label;
+ pen plabel;
+ pen p;
+ frame mark;
+ bool above;
+ void operator init(string label, pen plabel=currentpen, pen p=nullpen,
+ frame mark=newframe, bool above=true) {
+ this.label=label;
+ this.plabel=plabel;
+ this.p=(p == nullpen) ? plabel : p;
+ this.mark=mark;
+ this.above=above;
+ }
+}
+
+pair rectify(pair dir)
+{
+ real scale=max(abs(dir.x),abs(dir.y));
+ if(scale != 0) dir *= 0.5/scale;
+ dir += (0.5,0.5);
+ return dir;
+}
+
+pair point(frame f, pair dir)
+{
+ pair m=min(f);
+ pair M=max(f);
+ return m+realmult(rectify(dir),M-m);
+}
+
+path[] align(path[] g, transform t=identity(), pair position,
+ pair align, pen p=currentpen)
+{
+ pair m=min(g);
+ pair M=max(g);
+ pair dir=rectify(inverse(t)*-align);
+ if(basealign(p) == 1)
+ dir -= (0,m.y/(M.y-m.y));
+ pair a=m+realmult(dir,M-m);
+ return shift(position+align*labelmargin(p))*t*shift(-a)*g;
+}
+
+// Returns a transform for aligning frame f in the direction align
+transform shift(frame f, pair align)
+{
+ return shift(align-point(f,-align));
+}
+
+// Returns a copy of frame f aligned in the direction align
+frame align(frame f, pair align)
+{
+ return shift(f,align)*f;
+}
+
+struct transformation {
+ transform3 modelview; // For orientation and positioning
+ transform3 projection; // For 3D to 2D projection
+ bool infinity;
+ bool oblique;
+ void operator init(transform3 modelview, bool oblique=false) {
+ this.modelview=modelview;
+ this.projection=identity4;
+ infinity=true;
+ this.oblique=oblique;
+ }
+ void operator init(transform3 modelview, transform3 projection) {
+ this.modelview=modelview;
+ this.projection=projection;
+ infinity=false;
+ oblique=false;
+ }
+ transform3 compute() {
+ return projection*modelview;
+ }
+}
+
+struct projection {
+ transform3 t; // projection*modelview (cached)
+ bool infinity;
+ bool oblique;
+ bool absolute=false;
+ triple camera;
+ triple up;
+ triple target;
+ bool showtarget=true; // Expand bounding volume to include target?
+ typedef transformation projector(triple camera, triple up, triple target);
+ projector projector;
+ bool autoadjust=true; // Adjust camera to lie outside bounding volume?
+ bool center=false; // Center target within bounding volume?
+ real angle; // Lens angle (currently only used by PRC viewpoint).
+ int ninterpolate; // Used for projecting nurbs to 2D Bezier curves.
+
+ void calculate() {
+ transformation T=projector(camera,up,target);
+ t=T.compute();
+ infinity=T.infinity;
+ oblique=T.oblique;
+ ninterpolate=infinity ? 1 : 16;
+ }
+
+ transformation transformation() {
+ return projector(camera,up,target);
+ }
+
+ transform3 modelview() {return transformation().modelview;}
+
+ triple vector() {
+ return camera-target;
+ }
+
+ void operator init(triple camera, triple up=(0,0,1), triple target=(0,0,0),
+ bool showtarget=true, bool autoadjust=true,
+ bool center=false, projector projector) {
+ this.camera=camera;
+ this.up=up;
+ this.target=target;
+ this.showtarget=showtarget;
+ this.autoadjust=autoadjust;
+ this.center=center;
+ this.projector=projector;
+ calculate();
+ }
+
+ projection copy() {
+ projection P=new projection;
+ P.t=t;
+ P.infinity=infinity;
+ P.absolute=absolute;
+ P.oblique=oblique;
+ P.camera=camera;
+ P.up=up;
+ P.target=target;
+ P.showtarget=showtarget;
+ P.autoadjust=autoadjust;
+ P.center=center;
+ P.projector=projector;
+ P.angle=angle;
+ P.ninterpolate=ninterpolate;
+ return P;
+ }
+
+ // Return the maximum distance of box(m,M) from target.
+ real distance(triple m, triple M) {
+ triple[] c={m,(m.x,m.y,M.z),(m.x,M.y,m.z),(m.x,M.y,M.z),
+ (M.x,m.y,m.z),(M.x,m.y,M.z),(M.x,M.y,m.z),M};
+ return max(abs(c-target));
+ }
+
+ // Move the camera so that the box(m,M) rotated about target will always
+ // lie in front of the clipping plane.
+ bool adjust(triple m, triple M) {
+ triple v=camera-target;
+ real d=distance(m,M);
+ static real lambda=camerafactor*(1-sqrtEpsilon);
+ if(lambda*d >= abs(v)) {
+ camera=target+camerafactor*d*unit(v);
+ calculate();
+ return true;
+ }
+ return false;
+ }
+}
+
+projection currentprojection;
+
+triple min3(pen p)
+{
+ return linewidth(p)*(-0.5,-0.5,-0.5);
+}
+
+triple max3(pen p)
+{
+ return linewidth(p)*(0.5,0.5,0.5);
+}
+
+// A function that draws an object to frame pic, given that the transform
+// from user coordinates to true-size coordinates is t.
+typedef void drawer(frame f, transform t);
+
+// A generalization of drawer that includes the final frame's bounds.
+typedef void drawerBound(frame f, transform t, transform T, pair lb, pair rt);
+
+struct picture {
+ // Three-dimensional version of drawer and drawerBound:
+ typedef void drawer3(frame f, transform3 t, picture pic, projection P);
+ typedef void drawerBound3(frame f, transform3 t, transform3 T,
+ picture pic, projection P, triple lb, triple rt);
+
+ // The functions to do the deferred drawing.
+ drawerBound[] nodes;
+ drawerBound3[] nodes3;
+
+ bool uptodate=true;
+
+ // The coordinates in flex space to be used in sizing the picture.
+ struct bounds {
+ coords2 point,min,max;
+ bool exact=true; // An accurate picture bounds is provided by the user.
+ void erase() {
+ point.erase();
+ min.erase();
+ max.erase();
+ }
+ bounds copy() {
+ bounds b=new bounds;
+ b.point=point.copy();
+ b.min=min.copy();
+ b.max=max.copy();
+ b.exact=exact;
+ return b;
+ }
+ void xclip(real Min, real Max) {
+ point.xclip(Min,Max);
+ min.xclip(Min,Max);
+ max.xclip(Min,Max);
+ }
+ void yclip(real Min, real Max) {
+ point.yclip(Min,Max);
+ min.yclip(Min,Max);
+ max.yclip(Min,Max);
+ }
+ void clip(triple Min, triple Max) {
+ xclip(Min.x,Max.x);
+ yclip(Min.y,Max.y);
+ }
+ }
+
+ struct bounds3 {
+ coords3 point,min,max;
+ bool exact=true; // An accurate picture bounds is provided by the user.
+ void erase() {
+ point.erase();
+ min.erase();
+ max.erase();
+ }
+ bounds3 copy() {
+ bounds3 b=new bounds3;
+ b.point=point.copy();
+ b.min=min.copy();
+ b.max=max.copy();
+ b.exact=exact;
+ return b;
+ }
+ }
+
+ bounds bounds;
+ bounds3 bounds3;
+
+ // Transform to be applied to this picture.
+ transform T;
+ transform3 T3;
+
+ // Cached user-space bounding box
+ triple userMin,userMax;
+ bool userSetx,userSety,userSetz;
+
+ ScaleT scale; // Needed by graph
+ Legend[] legend;
+
+ pair[] clipmax; // Used by beginclip/endclip
+ pair[] clipmin;
+
+ // The maximum sizes in the x, y, and z directions; zero means no restriction.
+ real xsize=0, ysize=0;
+
+ real xsize3=0, ysize3=0, zsize3=0;
+
+ // Fixed unitsizes in the x y, and z directions; zero means use
+ // xsize, ysize, and zsize.
+ real xunitsize=0, yunitsize=0, zunitsize=0;
+
+ // If true, the x and y directions must be scaled by the same amount.
+ bool keepAspect=true;
+
+ // A fixed scaling transform.
+ bool fixed;
+ transform fixedscaling;
+
+ void init() {
+ userMin=userMax=(0,0,0);
+ userSetx=userSety=userSetz=false;
+ T3=identity(4);
+ }
+ init();
+
+ // Erase the current picture, retaining any size specification.
+ void erase() {
+ nodes.delete();
+ nodes3.delete();
+ bounds.erase();
+ bounds3.erase();
+ T=identity();
+ scale=new ScaleT;
+ legend.delete();
+ init();
+ }
+
+ bool empty2() {
+ return nodes.length == 0;
+ }
+
+ bool empty3() {
+ return nodes3.length == 0;
+ }
+
+ bool empty() {
+ return empty2() && empty3();
+ }
+
+ pair userMin() {return (userMin.x,userMin.y);}
+ pair userMax() {return (userMax.x,userMax.y);}
+
+ void userMinx(real x) {
+ userMin=(x,userMin.y,userMin.z);
+ userSetx=true;
+ }
+
+ void userMiny(real y) {
+ userMin=(userMin.x,y,userMin.z);
+ userSety=true;
+ }
+
+ void userMinz(real z) {
+ userMin=(userMin.x,userMin.y,z);
+ userSetz=true;
+ }
+
+ void userMaxx(real x) {
+ userMax=(x,userMax.y,userMax.z);
+ userSetx=true;
+ }
+
+ void userMaxy(real y) {
+ userMax=(userMax.x,y,userMax.z);
+ userSety=true;
+ }
+
+ void userMaxz(real z) {
+ userMax=(userMax.x,userMax.y,z);
+ userSetz=true;
+ }
+
+ void userCorners(pair c00, pair c01, pair c10, pair c11) {
+ userMin=(min(c00.x,c01.x,c10.x,c11.x),min(c00.y,c01.y,c10.y,c11.y),
+ userMin.z);
+ userMax=(max(c00.x,c01.x,c10.x,c11.x),max(c00.y,c01.y,c10.y,c11.y),
+ userMax.z);
+ }
+
+ void userCorners(triple c000, triple c001, triple c010, triple c011,
+ triple c100, triple c101, triple c110, triple c111) {
+ userMin=(min(c000.x,c001.x,c010.x,c011.x,c100.x,c101.x,c110.x,c111.x),
+ min(c000.y,c001.y,c010.y,c011.y,c100.y,c101.y,c110.y,c111.y),
+ min(c000.z,c001.z,c010.z,c011.z,c100.z,c101.z,c110.z,c111.z));
+ userMax=(max(c000.x,c001.x,c010.x,c011.x,c100.x,c101.x,c110.x,c111.x),
+ max(c000.y,c001.y,c010.y,c011.y,c100.y,c101.y,c110.y,c111.y),
+ max(c000.z,c001.z,c010.z,c011.z,c100.z,c101.z,c110.z,c111.z));
+ }
+
+ void userCopy(picture pic) {
+ userMin=(triple) pic.userMin;
+ userMax=(triple) pic.userMax;
+ userSetx=pic.userSetx;
+ userSety=pic.userSety;
+ userSetz=pic.userSetz;
+ }
+
+ typedef real binop(real, real);
+
+ // Cache the current user-space bounding box x coodinates
+ void userBoxX(real min, real max, binop m=min, binop M=max) {
+ if(userSetx) {
+ userMin=(m(userMin.x,min),userMin.y,userMin.z);
+ userMax=(M(userMax.x,max),userMax.y,userMax.z);
+ } else {
+ userMin=(min,userMin.y,userMin.z);
+ userMax=(max,userMax.y,userMax.z);
+ userSetx=true;
+ }
+ }
+
+ // Cache the current user-space bounding box y coodinates
+ void userBoxY(real min, real max, binop m=min, binop M=max) {
+ if(userSety) {
+ userMin=(userMin.x,m(userMin.y,min),userMin.z);
+ userMax=(userMax.x,M(userMax.y,max),userMax.z);
+ } else {
+ userMin=(userMin.x,min,userMin.z);
+ userMax=(userMax.x,max,userMax.z);
+ userSety=true;
+ }
+ }
+
+ // Cache the current user-space bounding box z coodinates
+ void userBoxZ(real min, real max, binop m=min, binop M=max) {
+ if(userSetz) {
+ userMin=(userMin.x,userMin.y,m(userMin.z,min));
+ userMax=(userMax.x,userMax.y,M(userMax.z,max));
+ } else {
+ userMin=(userMin.x,userMin.y,min);
+ userMax=(userMax.x,userMax.y,max);
+ userSetz=true;
+ }
+ }
+
+ // Cache the current user-space bounding box
+ void userBox(pair min, pair max) {
+ userBoxX(min.x,max.x);
+ userBoxY(min.y,max.y);
+ }
+
+ // Cache the current user-space bounding box
+ void userBox(triple min, triple max) {
+ userBoxX(min.x,max.x);
+ userBoxY(min.y,max.y);
+ userBoxZ(min.z,max.z);
+ }
+
+ // Clip the current user-space bounding box
+ void userClip(pair min, pair max) {
+ userBoxX(min.x,max.x,max,min);
+ userBoxY(min.y,max.y,max,min);
+ }
+
+ void add(drawerBound d, bool exact=false) {
+ uptodate=false;
+ if(!exact) bounds.exact=false;
+ nodes.push(d);
+ }
+
+ void add(drawer d, bool exact=false, bool above=true) {
+ uptodate=false;
+ if(!exact) bounds.exact=false;
+ nodes.push(new void(frame f, transform t, transform T, pair, pair) {
+ d(f,t*T);
+ });
+ }
+
+ void add(drawerBound3 d, bool exact=false, bool above=true) {
+ uptodate=false;
+ if(!exact) bounds.exact=false;
+ if(above)
+ nodes3.push(d);
+ else
+ nodes3.insert(0,d);
+ }
+
+ void add(drawer3 d, bool exact=false, bool above=true) {
+ add(new void(frame f, transform3 t, transform3 T, picture pic,
+ projection P, triple, triple) {
+ d(f,t*T,pic,P);
+ },exact,above);
+ }
+
+ void clip(drawer d, bool exact=false) {
+ bounds.clip(userMin,userMax);
+ this.add(d,exact);
+ }
+
+ void clip(drawerBound d, bool exact=false) {
+ bounds.clip(userMin,userMax);
+ this.add(d,exact);
+ }
+
+ // Add a point to the sizing.
+ void addPoint(pair user, pair truesize=0) {
+ bounds.point.push(user,truesize);
+ userBox(user,user);
+ }
+
+ // Add a point to the sizing, accounting also for the size of the pen.
+ void addPoint(pair user, pair truesize=0, pen p) {
+ addPoint(user,truesize+min(p));
+ addPoint(user,truesize+max(p));
+ }
+
+ void addPoint(triple user, triple truesize=(0,0,0)) {
+ bounds3.point.push(user,truesize);
+ userBox(user,user);
+ }
+
+ void addPoint(triple user, triple truesize=(0,0,0), pen p) {
+ addPoint(user,truesize+min3(p));
+ addPoint(user,truesize+max3(p));
+ }
+
+ // Add a box to the sizing.
+ void addBox(pair userMin, pair userMax, pair trueMin=0, pair trueMax=0) {
+ bounds.min.push(userMin,trueMin);
+ bounds.max.push(userMax,trueMax);
+ userBox(userMin,userMax);
+ }
+
+ void addBox(triple userMin, triple userMax, triple trueMin=(0,0,0),
+ triple trueMax=(0,0,0)) {
+ bounds3.min.push(userMin,trueMin);
+ bounds3.max.push(userMax,trueMax);
+ userBox(userMin,userMax);
+ }
+
+ // Add a (user space) path to the sizing.
+ void addPath(path g) {
+ if(size(g) > 0)
+ addBox(min(g),max(g));
+ }
+ void addPath(path[] g) {
+ for(int i=0; i < g.length; ++i)
+ addPath(g[i]);
+ }
+
+ // Add a path to the sizing with the additional padding of a pen.
+ void addPath(path g, pen p) {
+ if(size(g) > 0)
+ addBox(min(g),max(g),min(p),max(p));
+ }
+
+ void size(real x, real y=x, bool keepAspect=this.keepAspect) {
+ if(!empty()) uptodate=false;
+ xsize=x;
+ ysize=y;
+ this.keepAspect=keepAspect;
+ }
+
+ void size3(real x, real y=x, real z=y, bool keepAspect=this.keepAspect) {
+ if(!empty3()) uptodate=false;
+ xsize3=x;
+ ysize3=y;
+ zsize3=z;
+ this.keepAspect=keepAspect;
+ }
+
+ void unitsize(real x, real y=x, real z=y) {
+ uptodate=false;
+ xunitsize=x;
+ yunitsize=y;
+ zunitsize=z;
+ }
+
+ // The scaling in one dimension: x --> a*x + b
+ struct scaling {
+ real a,b;
+ static scaling build(real a, real b) {
+ scaling s=new scaling;
+ s.a=a; s.b=b;
+ return s;
+ }
+ real scale(real x) {
+ return a*x+b;
+ }
+ real scale(coord c) {
+ return scale(c.user) + c.truesize;
+ }
+ }
+
+ // Calculate the minimum point in scaling the coords.
+ real min(real m, scaling s, coord[] c) {
+ for(int i=0; i < c.length; ++i)
+ if(finite(c[i].user) && s.scale(c[i]) < m)
+ m=s.scale(c[i]);
+ return m;
+ }
+
+ // Calculate the maximum point in scaling the coords.
+ real max(real M, scaling s, coord[] c) {
+ for(int i=0; i < c.length; ++i)
+ if(finite(c[i].user) && s.scale(c[i]) > M)
+ M=s.scale(c[i]);
+ return M;
+ }
+
+ // Calculate the min for the final frame, given the coordinate transform.
+ pair min(transform t) {
+ if(bounds.min.x.length == 0 && bounds.point.x.length == 0 &&
+ bounds.max.x.length == 0) return 0;
+ pair a=t*(1,1)-t*(0,0), b=t*(0,0);
+ scaling xs=scaling.build(a.x,b.x);
+ scaling ys=scaling.build(a.y,b.y);
+ return (min(min(min(infinity,xs,bounds.point.x),xs,bounds.min.x),
+ xs,bounds.max.x),
+ min(min(min(infinity,ys,bounds.point.y),ys,bounds.min.y),
+ ys,bounds.max.y));
+ }
+
+ // Calculate the max for the final frame, given the coordinate transform.
+ pair max(transform t) {
+ if(bounds.min.x.length == 0 && bounds.point.x.length == 0 &&
+ bounds.max.x.length == 0) return 0;
+ pair a=t*(1,1)-t*(0,0), b=t*(0,0);
+ scaling xs=scaling.build(a.x,b.x);
+ scaling ys=scaling.build(a.y,b.y);
+ return (max(max(max(-infinity,xs,bounds.point.x),xs,bounds.min.x),
+ xs,bounds.max.x),
+ max(max(max(-infinity,ys,bounds.point.y),ys,bounds.min.y),
+ ys,bounds.max.y));
+ }
+
+ // Calculate the min for the final frame, given the coordinate transform.
+ triple min(transform3 t) {
+ if(bounds3.min.x.length == 0 && bounds3.point.x.length == 0 &&
+ bounds3.max.x.length == 0) return (0,0,0);
+ triple a=t*(1,1,1)-t*(0,0,0), b=t*(0,0,0);
+ scaling xs=scaling.build(a.x,b.x);
+ scaling ys=scaling.build(a.y,b.y);
+ scaling zs=scaling.build(a.z,b.z);
+ return (min(min(min(infinity,xs,bounds3.point.x),xs,bounds3.min.x),
+ xs,bounds3.max.x),
+ min(min(min(infinity,ys,bounds3.point.y),ys,bounds3.min.y),
+ ys,bounds3.max.y),
+ min(min(min(infinity,zs,bounds3.point.z),zs,bounds3.min.z),
+ zs,bounds3.max.z));
+ }
+
+ // Calculate the max for the final frame, given the coordinate transform.
+ triple max(transform3 t) {
+ if(bounds3.min.x.length == 0 && bounds3.point.x.length == 0 &&
+ bounds3.max.x.length == 0) return (0,0,0);
+ triple a=t*(1,1,1)-t*(0,0,0), b=t*(0,0,0);
+ scaling xs=scaling.build(a.x,b.x);
+ scaling ys=scaling.build(a.y,b.y);
+ scaling zs=scaling.build(a.z,b.z);
+ return (max(max(max(-infinity,xs,bounds3.point.x),xs,bounds3.min.x),
+ xs,bounds3.max.x),
+ max(max(max(-infinity,ys,bounds3.point.y),ys,bounds3.min.y),
+ ys,bounds3.max.y),
+ max(max(max(-infinity,zs,bounds3.point.z),zs,bounds3.min.z),
+ zs,bounds3.max.z));
+ }
+
+ // Calculate the sizing constants for the given array and maximum size.
+ real calculateScaling(string dir, coord[] coords, real size,
+ bool warn=true) {
+ access simplex;
+ simplex.problem p=new simplex.problem;
+
+ void addMinCoord(coord c) {
+ // (a*user + b) + truesize >= 0:
+ p.addRestriction(c.user,1,c.truesize);
+ }
+ void addMaxCoord(coord c) {
+ // (a*user + b) + truesize <= size:
+ p.addRestriction(-c.user,-1,size-c.truesize);
+ }
+
+ coord[] m=maxcoords(coords,operator >=);
+ coord[] M=maxcoords(coords,operator <=);
+
+ for(int i=0; i < m.length; ++i)
+ addMinCoord(m[i]);
+ for(int i=0; i < M.length; ++i)
+ addMaxCoord(M[i]);
+
+ int status=p.optimize();
+ if(status == simplex.problem.OPTIMAL) {
+ return scaling.build(p.a(),p.b()).a;
+ } else if(status == simplex.problem.UNBOUNDED) {
+ if(warn) write("warning: "+dir+" scaling in picture unbounded");
+ return 0;
+ } else {
+ if(!warn) return 1;
+ bool userzero=true;
+ for(int i=0; i < coords.length; ++i) {
+ if(coords[i].user != 0) userzero=false;
+ if(!finite(coords[i].user) || !finite(coords[i].truesize))
+ abort("unbounded picture");
+ }
+ if(userzero) return 1;
+ write("warning: cannot fit picture to "+dir+"size "+(string) size
+ +"...enlarging...");
+ return calculateScaling(dir,coords,sqrt(2)*size,warn);
+ }
+ }
+
+ void append(coords2 point, coords2 min, coords2 max, transform t,
+ bounds bounds)
+ {
+ // Add the coord info to this picture.
+ if(t == identity()) {
+ point.append(bounds.point);
+ min.append(bounds.min);
+ max.append(bounds.max);
+ } else {
+ point.push(t,bounds.point,bounds.point);
+ // Add in all 4 corner points, to properly size rectangular pictures.
+ point.push(t,bounds.min,bounds.min);
+ point.push(t,bounds.min,bounds.max);
+ point.push(t,bounds.max,bounds.min);
+ point.push(t,bounds.max,bounds.max);
+ }
+ }
+
+ void append(coords3 point, coords3 min, coords3 max, transform3 t,
+ bounds3 bounds)
+ {
+ // Add the coord info to this picture.
+ if(t == identity4) {
+ point.append(bounds.point);
+ min.append(bounds.min);
+ max.append(bounds.max);
+ } else {
+ point.push(t,bounds.point,bounds.point,bounds.point);
+ // Add in all 8 corner points, to properly size cuboid pictures.
+ point.push(t,bounds.min,bounds.min,bounds.min);
+ point.push(t,bounds.min,bounds.min,bounds.max);
+ point.push(t,bounds.min,bounds.max,bounds.min);
+ point.push(t,bounds.min,bounds.max,bounds.max);
+ point.push(t,bounds.max,bounds.min,bounds.min);
+ point.push(t,bounds.max,bounds.min,bounds.max);
+ point.push(t,bounds.max,bounds.max,bounds.min);
+ point.push(t,bounds.max,bounds.max,bounds.max);
+ }
+ }
+
+ // Returns the transform for turning user-space pairs into true-space pairs.
+ transform scaling(real xsize, real ysize, bool keepAspect=true,
+ bool warn=true) {
+ if(xsize == 0 && xunitsize == 0 && ysize == 0 && yunitsize == 0)
+ return identity();
+
+ coords2 Coords;
+
+ append(Coords,Coords,Coords,T,bounds);
+
+ real sx;
+ if(xunitsize == 0) {
+ if(xsize != 0) sx=calculateScaling("x",Coords.x,xsize,warn);
+ } else sx=xunitsize;
+
+ real sy;
+ if(yunitsize == 0) {
+ if(ysize != 0) sy=calculateScaling("y",Coords.y,ysize,warn);
+ } else sy=yunitsize;
+
+ if(sx == 0) {
+ sx=sy;
+ if(sx == 0)
+ return identity();
+ } else if(sy == 0) sy=sx;
+
+
+ if(keepAspect && (xunitsize == 0 || yunitsize == 0))
+ return scale(min(sx,sy));
+ else
+ return scale(sx,sy);
+ }
+
+ transform scaling(bool warn=true) {
+ return scaling(xsize,ysize,keepAspect,warn);
+ }
+
+ // Returns the transform for turning user-space pairs into true-space triples.
+ transform3 scaling(real xsize, real ysize, real zsize, bool keepAspect=true,
+ bool warn=true) {
+ if(xsize == 0 && xunitsize == 0 && ysize == 0 && yunitsize == 0
+ && zsize == 0 && zunitsize == 0)
+ return identity(4);
+
+ coords3 Coords;
+
+ append(Coords,Coords,Coords,T3,bounds3);
+
+ real sx;
+ if(xunitsize == 0) {
+ if(xsize != 0) sx=calculateScaling("x",Coords.x,xsize,warn);
+ } else sx=xunitsize;
+
+ real sy;
+ if(yunitsize == 0) {
+ if(ysize != 0) sy=calculateScaling("y",Coords.y,ysize,warn);
+ } else sy=yunitsize;
+
+ real sz;
+ if(zunitsize == 0) {
+ if(zsize != 0) sz=calculateScaling("z",Coords.z,zsize,warn);
+ } else sz=zunitsize;
+
+ if(sx == 0) {
+ sx=max(sy,sz);
+ if(sx == 0)
+ return identity(4);
+ }
+ if(sy == 0) sy=max(sz,sx);
+ if(sz == 0) sz=max(sx,sy);
+
+ if(keepAspect && (xunitsize == 0 || yunitsize == 0 || zunitsize == 0))
+ return scale3(min(sx,sy,sz));
+ else
+ return scale(sx,sy,sz);
+ }
+
+ transform3 scaling3(bool warn=true) {
+ return scaling(xsize3,ysize3,zsize3,keepAspect,warn);
+ }
+
+ frame fit(transform t, transform T0=T, pair m, pair M) {
+ frame f;
+ for(int i=0; i < nodes.length; ++i)
+ nodes[i](f,t,T0,m,M);
+ return f;
+ }
+
+ frame fit3(transform3 t, transform3 T0=T3, picture pic, projection P,
+ triple m, triple M) {
+ frame f;
+ for(int i=0; i < nodes3.length; ++i)
+ nodes3[i](f,t,T0,pic,P,m,M);
+ return f;
+ }
+
+ // Returns a rigid version of the picture using t to transform user coords
+ // into truesize coords.
+ frame fit(transform t) {
+ return fit(t,min(t),max(t));
+ }
+
+ frame fit3(transform3 t, picture pic, projection P) {
+ return fit3(t,pic,P,min(t),max(t));
+ }
+
+ void add(void d(picture, transform), bool exact=false) {
+ add(new void(frame f, transform t) {
+ picture opic=new picture;
+ d(opic,t);
+ add(f,opic.fit(identity()));
+ },exact);
+ }
+
+ void add(void d(picture, transform3), bool exact=false, bool above=true) {
+ add(new void(frame f, transform3 t, picture pic2, projection P) {
+ picture opic=new picture;
+ d(opic,t);
+ add(f,opic.fit3(identity4,pic2,P));
+ },exact,above);
+ }
+
+ void add(void d(picture, transform3, transform3, triple, triple),
+ bool exact=false, bool above=true) {
+ add(new void(frame f, transform3 t, transform3 T, picture pic2,
+ projection P, triple lb, triple rt) {
+ picture opic=new picture;
+ d(opic,t,T,lb,rt);
+ add(f,opic.fit3(identity4,pic2,P));
+ },exact,above);
+ }
+
+ frame scaled() {
+ frame f=fit(fixedscaling);
+ pair d=size(f);
+ static real epsilon=100*realEpsilon;
+ if(d.x > xsize*(1+epsilon))
+ write("warning: frame exceeds xlimit: "+(string) d.x+" > "+
+ (string) xsize);
+ if(d.y > ysize*(1+epsilon))
+ write("warning: frame exceeds ylimit: "+(string) d.y+" > "+
+ (string) ysize);
+ return f;
+ }
+
+ // Calculate additional scaling required if only an approximate picture
+ // size estimate is available.
+ transform scale(frame f, real xsize=this.xsize, real ysize=this.ysize,
+ bool keepaspect=this.keepAspect) {
+ if(bounds.exact) return identity();
+ pair m=min(f);
+ pair M=max(f);
+ real width=M.x-m.x;
+ real height=M.y-m.y;
+ real xgrow=xsize == 0 || width == 0 ? 1 : xsize/width;
+ real ygrow=ysize == 0 || height == 0 ? 1 : ysize/height;
+ if(keepAspect) {
+ real[] grow;
+ if(xsize > 0) grow.push(xgrow);
+ if(ysize > 0) grow.push(ygrow);
+ return scale(grow.length == 0 ? 1 : min(grow));
+ } else return scale(xgrow,ygrow);
+
+ }
+
+ // Calculate additional scaling required if only an approximate thisture
+ // size estimate is available.
+ transform3 scale3(frame f, real xsize3=this.xsize3,
+ real ysize3=this.ysize3, real zsize3=this.zsize3,
+ bool keepaspect=this.keepAspect) {
+ if(bounds3.exact) return identity(4);
+ triple m=min3(f);
+ triple M=max3(f);
+ real width=M.x-m.x;
+ real height=M.y-m.y;
+ real depth=M.z-m.z;
+ real xgrow=xsize3 == 0 || width == 0 ? 1 : xsize3/width;
+ real ygrow=ysize3 == 0 || height == 0 ? 1 : ysize3/height;
+ real zgrow=zsize3 == 0 || depth == 0 ? 1 : zsize3/depth;
+ if(keepAspect) {
+ real[] grow;
+ if(xsize3 > 0) grow.push(xgrow);
+ if(ysize3 > 0) grow.push(ygrow);
+ if(zsize3 > 0) grow.push(zgrow);
+ return scale3(grow.length == 0 ? 1 : min(grow));
+ } else return scale(xgrow,ygrow,zgrow);
+ }
+
+ // Return the transform that would be used to fit the picture to a frame
+ transform calculateTransform(real xsize, real ysize, bool keepAspect=true,
+ bool warn=true) {
+ transform t=scaling(xsize,ysize,keepAspect,warn);
+ return scale(fit(t),xsize,ysize,keepAspect)*t;
+ }
+
+ transform calculateTransform(bool warn=true) {
+ if(fixed) return fixedscaling;
+ return calculateTransform(xsize,ysize,keepAspect,warn);
+ }
+
+ transform3 calculateTransform3(real xsize=xsize3, real ysize=ysize3,
+ real zsize=zsize3,
+ bool keepAspect=true, bool warn=true,
+ projection P=currentprojection) {
+ transform3 t=scaling(xsize,ysize,zsize,keepAspect,warn);
+ return scale3(fit3(t,null,P),keepAspect)*t;
+ }
+
+ pair min(real xsize=this.xsize, real ysize=this.ysize,
+ bool keepAspect=this.keepAspect, bool warn=true) {
+ return min(calculateTransform(xsize,ysize,keepAspect,warn));
+ }
+
+ pair max(real xsize=this.xsize, real ysize=this.ysize,
+ bool keepAspect=this.keepAspect, bool warn=true) {
+ return max(calculateTransform(xsize,ysize,keepAspect,warn));
+ }
+
+ triple min3(real xsize=this.xsize3, real ysize=this.ysize3,
+ real zsize=this.zsize3, bool keepAspect=this.keepAspect,
+ bool warn=true, projection P) {
+ return min(calculateTransform3(xsize,ysize,zsize,keepAspect,warn,P));
+ }
+
+ triple max3(real xsize=this.xsize3, real ysize=this.ysize3,
+ real zsize=this.zsize3, bool keepAspect=this.keepAspect,
+ bool warn=true, projection P) {
+ return max(calculateTransform3(xsize,ysize,zsize,keepAspect,warn,P));
+ }
+
+ // Returns the 2D picture fit to the requested size.
+ frame fit2(real xsize=this.xsize, real ysize=this.ysize,
+ bool keepAspect=this.keepAspect) {
+ if(fixed) return scaled();
+ if(empty2()) return newframe;
+ transform t=scaling(xsize,ysize,keepAspect);
+ frame f=fit(t);
+ transform s=scale(f,xsize,ysize,keepAspect);
+ if(s == identity()) return f;
+ return fit(s*t);
+ }
+
+ static frame fitter(string,picture,string,real,real,bool,bool,string,string,
+ projection);
+ frame fit(string prefix="", string format="",
+ real xsize=this.xsize, real ysize=this.ysize,
+ bool keepAspect=this.keepAspect, bool view=false,
+ string options="", string script="",
+ projection P=currentprojection) {
+ return fitter == null ? fit2(xsize,ysize,keepAspect) :
+ fitter(prefix,this,format,xsize,ysize,keepAspect,view,options,script,P);
+ }
+
+ // In case only an approximate picture size estimate is available, return the
+ // fitted frame slightly scaled (including labels and true size distances)
+ // so that it precisely meets the given size specification.
+ frame scale(real xsize=this.xsize, real ysize=this.ysize,
+ bool keepAspect=this.keepAspect) {
+ frame f=fit(xsize,ysize,keepAspect);
+ transform s=scale(f,xsize,ysize,keepAspect);
+ if(s == identity()) return f;
+ return s*f;
+ }
+
+ // Copies the drawing information, but not the sizing information into a new
+ // picture. Fitting this picture will not scale as the original picture would.
+ picture drawcopy() {
+ picture dest=new picture;
+ dest.nodes=copy(nodes);
+ dest.nodes3=copy(nodes3);
+ dest.T=T;
+ dest.T3=T3;
+ dest.userCopy(this);
+ dest.scale=scale.copy();
+ dest.legend=copy(legend);
+
+ return dest;
+ }
+
+ // A deep copy of this picture. Modifying the copied picture will not affect
+ // the original.
+ picture copy() {
+ picture dest=drawcopy();
+
+ dest.uptodate=uptodate;
+ dest.bounds=bounds.copy();
+ dest.bounds3=bounds3.copy();
+
+ dest.xsize=xsize; dest.ysize=ysize;
+ dest.xsize3=xsize; dest.ysize3=ysize3; dest.zsize3=zsize3;
+ dest.keepAspect=keepAspect;
+ dest.xunitsize=xunitsize; dest.yunitsize=yunitsize;
+ dest.zunitsize=zunitsize;
+ dest.fixed=fixed; dest.fixedscaling=fixedscaling;
+
+ return dest;
+ }
+
+ // Add a picture to this picture, such that the user coordinates will be
+ // scaled identically when fitted
+ void add(picture src, bool group=true, filltype filltype=NoFill,
+ bool above=true) {
+ // Copy the picture. Only the drawing function closures are needed, so we
+ // only copy them. This needs to be a deep copy, as src could later have
+ // objects added to it that should not be included in this picture.
+
+ if(src == this) abort("cannot add picture to itself");
+
+ uptodate=false;
+
+ picture srcCopy=src.drawcopy();
+ // Draw by drawing the copied picture.
+ if(srcCopy.nodes.length > 0)
+ nodes.push(new void(frame f, transform t, transform T, pair m, pair M) {
+ add(f,srcCopy.fit(t,T*srcCopy.T,m,M),group,filltype,above);
+ });
+
+ if(srcCopy.nodes3.length > 0) {
+ nodes3.push(new void(frame f, transform3 t, transform3 T3, picture pic,
+ projection P, triple m, triple M) {
+ add(f,srcCopy.fit3(t,T3*srcCopy.T3,pic,P,m,M),group,above);
+ });
+ }
+
+ legend.append(src.legend);
+
+ if(src.userSetx) userBoxX(src.userMin.x,src.userMax.x);
+ if(src.userSety) userBoxY(src.userMin.y,src.userMax.y);
+ if(src.userSetz) userBoxZ(src.userMin.z,src.userMax.z);
+
+ append(bounds.point,bounds.min,bounds.max,srcCopy.T,src.bounds);
+ append(bounds3.point,bounds3.min,bounds3.max,srcCopy.T3,src.bounds3);
+
+ if(!src.bounds.exact) bounds.exact=false;
+ if(!src.bounds3.exact) bounds3.exact=false;
+ }
+}
+
+picture operator * (transform t, picture orig)
+{
+ picture pic=orig.copy();
+ pic.T=t*pic.T;
+ pic.userCorners(t*(pic.userMin.x,pic.userMin.y),
+ t*(pic.userMin.x,pic.userMax.y),
+ t*(pic.userMax.x,pic.userMin.y),
+ t*(pic.userMax.x,pic.userMax.y));
+ pic.bounds.exact=false;
+ return pic;
+}
+
+picture operator * (transform3 t, picture orig)
+{
+ picture pic=orig.copy();
+ pic.T3=t*pic.T3;
+ pic.userCorners(t*pic.userMin,
+ t*(pic.userMin.x,pic.userMin.y,pic.userMax.z),
+ t*(pic.userMin.x,pic.userMax.y,pic.userMin.z),
+ t*(pic.userMin.x,pic.userMax.y,pic.userMax.z),
+ t*(pic.userMax.x,pic.userMin.y,pic.userMin.z),
+ t*(pic.userMax.x,pic.userMin.y,pic.userMax.z),
+ t*(pic.userMax.x,pic.userMax.y,pic.userMin.z),
+ t*pic.userMax);
+ pic.bounds3.exact=false;
+ return pic;
+}
+
+picture currentpicture;
+
+void size(picture pic=currentpicture, real x, real y=x,
+ bool keepAspect=pic.keepAspect)
+{
+ pic.size(x,y,keepAspect);
+}
+
+void size3(picture pic=currentpicture, real x, real y=x, real z=y,
+ bool keepAspect=pic.keepAspect)
+{
+ pic.size3(x,y,z,keepAspect);
+}
+
+void unitsize(picture pic=currentpicture, real x, real y=x, real z=y)
+{
+ pic.unitsize(x,y,z);
+}
+
+void size(picture pic=currentpicture, real xsize, real ysize,
+ pair min, pair max)
+{
+ pair size=max-min;
+ pic.unitsize(size.x != 0 ? xsize/size.x : 0,
+ size.y != 0 ? ysize/size.y : 0);
+}
+
+void size(picture dest, picture src)
+{
+ dest.size(src.xsize,src.ysize,src.keepAspect);
+ dest.size3(src.xsize3,src.ysize3,src.zsize3,src.keepAspect);
+ dest.unitsize(src.xunitsize,src.yunitsize,src.zunitsize);
+}
+
+pair min(picture pic, bool user=false)
+{
+ transform t=pic.calculateTransform();
+ pair z=pic.min(t);
+ return user ? inverse(t)*z : z;
+}
+
+pair max(picture pic, bool user=false)
+{
+ transform t=pic.calculateTransform();
+ pair z=pic.max(t);
+ return user ? inverse(t)*z : z;
+}
+
+pair size(picture pic, bool user=false)
+{
+ transform t=pic.calculateTransform();
+ pair M=pic.max(t);
+ pair m=pic.min(t);
+ if(!user) return M-m;
+ t=inverse(t);
+ return t*M-t*m;
+}
+
+pair point(picture pic=currentpicture, pair dir, bool user=true)
+{
+ pair z=pic.userMin()+realmult(rectify(dir),pic.userMax()-pic.userMin());
+ return user ? z : pic.calculateTransform()*z;
+}
+
+pair truepoint(picture pic=currentpicture, pair dir, bool user=true)
+{
+ transform t=pic.calculateTransform();
+ pair m=pic.min(t);
+ pair M=pic.max(t);
+ pair z=m+realmult(rectify(dir),M-m);
+ return user ? inverse(t)*z : z;
+}
+
+// Transform coordinate in [0,1]x[0,1] to current user coordinates.
+pair relative(picture pic=currentpicture, pair z)
+{
+ return pic.userMin()+realmult(z,pic.userMax()-pic.userMin());
+}
+
+void add(picture pic=currentpicture, drawer d, bool exact=false)
+{
+ pic.add(d,exact);
+}
+
+void add(picture pic=currentpicture, void d(picture,transform),
+ bool exact=false)
+{
+ pic.add(d,exact);
+}
+
+void begingroup(picture pic=currentpicture)
+{
+ pic.add(new void(frame f, transform) {
+ begingroup(f);
+ },true);
+}
+
+void endgroup(picture pic=currentpicture)
+{
+ pic.add(new void(frame f, transform) {
+ endgroup(f);
+ },true);
+}
+
+void Draw(picture pic=currentpicture, path g, pen p=currentpen)
+{
+ pic.add(new void(frame f, transform t) {
+ draw(f,t*g,p);
+ },true);
+ pic.addPath(g,p);
+}
+
+void _draw(picture pic=currentpicture, path g, pen p=currentpen,
+ margin margin=NoMargin)
+{
+ pic.add(new void(frame f, transform t) {
+ draw(f,margin(t*g,p).g,p);
+ },true);
+ pic.addPath(g,p);
+}
+
+void Draw(picture pic=currentpicture, explicit path[] g, pen p=currentpen)
+{
+ for(int i=0; i < g.length; ++i) Draw(pic,g[i],p);
+}
+
+void fill(picture pic=currentpicture, path[] g, pen p=currentpen,
+ bool copy=true)
+{
+ if(copy)
+ g=copy(g);
+ pic.add(new void(frame f, transform t) {
+ fill(f,t*g,p,false);
+ },true);
+ pic.addPath(g);
+}
+
+void latticeshade(picture pic=currentpicture, path[] g, bool stroke=false,
+ pen fillrule=currentpen, pen[][] p, bool copy=true)
+{
+ if(copy) {
+ g=copy(g);
+ p=copy(p);
+ }
+ pic.add(new void(frame f, transform t) {
+ latticeshade(f,t*g,stroke,fillrule,p,false);
+ },true);
+ pic.addPath(g);
+}
+
+void axialshade(picture pic=currentpicture, path[] g, bool stroke=false,
+ pen pena, pair a, pen penb, pair b, bool copy=true)
+{
+ if(copy)
+ g=copy(g);
+ pic.add(new void(frame f, transform t) {
+ axialshade(f,t*g,stroke,pena,t*a,penb,t*b,false);
+ },true);
+ pic.addPath(g);
+}
+
+void radialshade(picture pic=currentpicture, path[] g, bool stroke=false,
+ pen pena, pair a, real ra, pen penb, pair b, real rb,
+ bool copy=true)
+{
+ if(copy)
+ g=copy(g);
+ pic.add(new void(frame f, transform t) {
+ pair A=t*a, B=t*b;
+ real RA=abs(t*(a+ra)-A);
+ real RB=abs(t*(b+rb)-B);
+ radialshade(f,t*g,stroke,pena,A,RA,penb,B,RB,false);
+ },true);
+ pic.addPath(g);
+}
+
+void gouraudshade(picture pic=currentpicture, path[] g, bool stroke=false,
+ pen fillrule=currentpen, pen[] p, pair[] z, int[] edges,
+ bool copy=true)
+{
+ if(copy) {
+ g=copy(g);
+ p=copy(p);
+ z=copy(z);
+ edges=copy(edges);
+ }
+ pic.add(new void(frame f, transform t) {
+ gouraudshade(f,t*g,stroke,fillrule,p,t*z,edges,false);
+ },true);
+ pic.addPath(g);
+}
+
+void gouraudshade(picture pic=currentpicture, path[] g, bool stroke=false,
+ pen fillrule=currentpen, pen[] p, int[] edges, bool copy=true)
+{
+ if(copy) {
+ g=copy(g);
+ p=copy(p);
+ edges=copy(edges);
+ }
+ pic.add(new void(frame f, transform t) {
+ gouraudshade(f,t*g,stroke,fillrule,p,edges,false);
+ },true);
+ pic.addPath(g);
+}
+
+void tensorshade(picture pic=currentpicture, path[] g, bool stroke=false,
+ pen fillrule=currentpen, pen[][] p, path[] b=g,
+ pair[][] z=new pair[][], bool copy=true)
+{
+ if(copy) {
+ g=copy(g);
+ p=copy(p);
+ b=copy(b);
+ z=copy(z);
+ }
+ pic.add(new void(frame f, transform t) {
+ pair[][] Z=new pair[z.length][];
+ for(int i=0; i < z.length; ++i)
+ Z[i]=t*z[i];
+ tensorshade(f,t*g,stroke,fillrule,p,t*b,Z,false);
+ },true);
+ pic.addPath(g);
+}
+
+void tensorshade(frame f, path[] g, bool stroke=false,
+ pen fillrule=currentpen, pen[] p,
+ path b=g.length > 0 ? g[0] : nullpath)
+{
+ tensorshade(f,g,stroke,fillrule,new pen[][] {p},b);
+}
+
+void tensorshade(frame f, path[] g, bool stroke=false,
+ pen fillrule=currentpen, pen[] p,
+ path b=g.length > 0 ? g[0] : nullpath, pair[] z)
+{
+ tensorshade(f,g,stroke,fillrule,new pen[][] {p},b,new pair[][] {z});
+}
+
+void tensorshade(picture pic=currentpicture, path[] g, bool stroke=false,
+ pen fillrule=currentpen, pen[] p,
+ path b=g.length > 0 ? g[0] : nullpath)
+{
+ tensorshade(pic,g,stroke,fillrule,new pen[][] {p},b);
+}
+
+void tensorshade(picture pic=currentpicture, path[] g, bool stroke=false,
+ pen fillrule=currentpen, pen[] p,
+ path b=g.length > 0 ? g[0] : nullpath, pair[] z)
+{
+ tensorshade(pic,g,stroke,fillrule,new pen[][] {p},b,new pair[][] {z});
+}
+
+// Smoothly shade the regions between consecutive paths of a sequence using a
+// given array of pens:
+void draw(picture pic=currentpicture, path[] g, pen[] p)
+{
+ path[] G;
+ pen[][] P;
+ string differentlengths="arrays have different lengths";
+ if(g.length != p.length) abort(differentlengths);
+ for(int i=0; i < g.length-1; ++i) {
+ path g0=g[i];
+ path g1=g[i+1];
+ if(length(g0) != length(g1)) abort(differentlengths);
+ for(int j=0; j < length(g0); ++j) {
+ G.push(subpath(g0,j,j+1)--reverse(subpath(g1,j,j+1))--cycle);
+ P.push(new pen[] {p[i],p[i],p[i+1],p[i+1]});
+ }
+ }
+ tensorshade(pic,G,P);
+}
+
+void functionshade(picture pic=currentpicture, path[] g, bool stroke=false,
+ pen fillrule=currentpen, string shader, bool copy=true)
+{
+ if(copy)
+ g=copy(g);
+ pic.add(new void(frame f, transform t) {
+ functionshade(f,t*g,stroke,fillrule,shader);
+ },true);
+ pic.addPath(g);
+}
+
+void filldraw(picture pic=currentpicture, path[] g, pen fillpen=currentpen,
+ pen drawpen=currentpen)
+{
+ begingroup(pic);
+ fill(pic,g,fillpen);
+ Draw(pic,g,drawpen);
+ endgroup(pic);
+}
+
+void clip(picture pic=currentpicture, path[] g, bool stroke=false,
+ pen fillrule=currentpen, bool copy=true)
+{
+ if(copy)
+ g=copy(g);
+ pic.userClip(min(g),max(g));
+ pic.clip(new void(frame f, transform t) {
+ clip(f,t*g,stroke,fillrule,false);
+ },true);
+}
+
+void beginclip(picture pic=currentpicture, path[] g, bool stroke=false,
+ pen fillrule=currentpen, bool copy=true)
+{
+ if(copy)
+ g=copy(g);
+
+ pic.clipmin.push(min(g));
+ pic.clipmax.push(max(g));
+
+ pic.add(new void(frame f, transform t) {
+ beginclip(f,t*g,stroke,fillrule,false);
+ },true);
+}
+
+void endclip(picture pic=currentpicture)
+{
+ if(pic.clipmin.length > 0 && pic.clipmax.length > 0)
+ pic.userClip(pic.clipmin.pop(),pic.clipmax.pop());
+ pic.clip(new void(frame f, transform) {
+ endclip(f);
+ },true);
+}
+
+void unfill(picture pic=currentpicture, path[] g, bool copy=true)
+{
+ if(copy)
+ g=copy(g);
+ pic.add(new void(frame f, transform t) {
+ unfill(f,t*g,false);
+ },true);
+}
+
+void filloutside(picture pic=currentpicture, path[] g, pen p=currentpen,
+ bool copy=true)
+{
+ if(copy)
+ g=copy(g);
+ pic.add(new void(frame f, transform t) {
+ filloutside(f,t*g,p,false);
+ },true);
+ pic.addPath(g);
+}
+
+// Use a fixed scaling to map user coordinates in box(min,max) to the
+// desired picture size.
+transform fixedscaling(picture pic=currentpicture, pair min, pair max,
+ pen p=nullpen, bool warn=false)
+{
+ Draw(pic,min,p+invisible);
+ Draw(pic,max,p+invisible);
+ pic.fixed=true;
+ return pic.fixedscaling=pic.calculateTransform(pic.xsize,pic.ysize,
+ pic.keepAspect);
+}
+
+// Add frame src about position to frame dest with optional grouping.
+void add(frame dest, frame src, pair position, bool group=false,
+ filltype filltype=NoFill, bool above=true)
+{
+ add(dest,shift(position)*src,group,filltype,above);
+}
+
+// Add frame src about position to picture dest with optional grouping.
+void add(picture dest=currentpicture, frame src, pair position=0,
+ bool group=true, filltype filltype=NoFill, bool above=true)
+{
+ if(is3D(src)) {
+ dest.add(new void(frame f, transform3, picture, projection) {
+ add(f,src); // always add about 3D origin (ignore position)
+ },true);
+ dest.addBox((0,0,0),(0,0,0),min3(src),max3(src));
+ } else {
+ dest.add(new void(frame f, transform t) {
+ add(f,shift(t*position)*src,group,filltype,above);
+ },true);
+ dest.addBox(position,position,min(src),max(src));
+ }
+}
+
+// Like add(picture,frame,pair) but extend picture to accommodate frame.
+void attach(picture dest=currentpicture, frame src, pair position=0,
+ bool group=true, filltype filltype=NoFill, bool above=true)
+{
+ transform t=dest.calculateTransform();
+ add(dest,src,position,group,filltype,above);
+ pair s=size(dest.fit(t));
+ size(dest,dest.xsize != 0 ? s.x : 0,dest.ysize != 0 ? s.y : 0);
+}
+
+// Like add(picture,frame,pair) but align frame in direction align.
+void add(picture dest=currentpicture, frame src, pair position, pair align,
+ bool group=true, filltype filltype=NoFill, bool above=true)
+{
+ add(dest,align(src,align),position,group,filltype,above);
+}
+
+// Like attach(picture,frame,pair) but extend picture to accommodate frame;
+void attach(picture dest=currentpicture, frame src, pair position,
+ pair align, bool group=true, filltype filltype=NoFill,
+ bool above=true)
+{
+ attach(dest,align(src,align),position,group,filltype,above);
+}
+
+// Add a picture to another such that user coordinates in both will be scaled
+// identically in the shipout.
+void add(picture dest, picture src, bool group=true, filltype filltype=NoFill,
+ bool above=true)
+{
+ dest.add(src,group,filltype,above);
+}
+
+void add(picture src, bool group=true, filltype filltype=NoFill,
+ bool above=true)
+{
+ currentpicture.add(src,group,filltype,above);
+}
+
+// Fit the picture src using the identity transformation (so user
+// coordinates and truesize coordinates agree) and add it about the point
+// position to picture dest.
+void add(picture dest, picture src, pair position, bool group=true,
+ filltype filltype=NoFill, bool above=true)
+{
+ add(dest,src.fit(identity()),position,group,filltype,above);
+}
+
+void add(picture src, pair position, bool group=true, filltype filltype=NoFill,
+ bool above=true)
+{
+ add(currentpicture,src,position,group,filltype,above);
+}
+
+// Fill a region about the user-coordinate 'origin'.
+void fill(pair origin, picture pic=currentpicture, path[] g, pen p=currentpen)
+{
+ picture opic;
+ fill(opic,g,p);
+ add(pic,opic,origin);
+}
+
+void postscript(picture pic=currentpicture, string s)
+{
+ pic.add(new void(frame f, transform) {
+ postscript(f,s);
+ },true);
+}
+
+void tex(picture pic=currentpicture, string s)
+{
+ pic.add(new void(frame f, transform) {
+ tex(f,s);
+ },true);
+}
+
+void postscript(picture pic=currentpicture, string s, pair min, pair max)
+{
+ pic.add(new void(frame f, transform t) {
+ postscript(f,s,t*min,t*max);
+ },true);
+}
+
+void tex(picture pic=currentpicture, string s, pair min, pair max)
+{
+ pic.add(new void(frame f, transform t) {
+ tex(f,s,t*min,t*max);
+ },true);
+}
+
+void layer(picture pic=currentpicture)
+{
+ pic.add(new void(frame f, transform) {
+ layer(f);
+ },true);
+}
+
+void erase(picture pic=currentpicture)
+{
+ pic.uptodate=false;
+ pic.erase();
+}
diff --git a/Build/source/utils/asymptote/base/plain_shipout.asy b/Build/source/utils/asymptote/base/plain_shipout.asy
new file mode 100644
index 00000000000..22aeef7121f
--- /dev/null
+++ b/Build/source/utils/asymptote/base/plain_shipout.asy
@@ -0,0 +1,113 @@
+// Default file prefix used for inline LaTeX mode
+string defaultfilename;
+
+string outprefix(string prefix=defaultfilename) {
+ string s=prefix != "" ? prefix :
+ (settings.outname == "" && interactive()) ? "out" : settings.outname;
+ return stripextension(s);
+}
+
+string outformat(string format="")
+{
+ if(format == "") format=settings.outformat;
+ if(format == "") format=nativeformat();
+ return format;
+}
+
+
+bool shipped; // Was a picture or frame already shipped out?
+
+frame currentpatterns;
+
+frame Portrait(frame f) {return f;};
+frame Landscape(frame f) {return rotate(90)*f;};
+frame UpsideDown(frame f) {return rotate(180)*f;};
+frame Seascape(frame f) {return rotate(-90)*f;};
+typedef frame orientation(frame);
+orientation orientation=Portrait;
+
+// Forward references to functions defined in module three.
+object embed3(string, frame, string, string, string, projection);
+string Embed(string name, string options="", real width=0, real height=0);
+string Link(string label, string text, string options="");
+
+bool prc0(string format="")
+{
+ return settings.prc && (outformat(format) == "pdf" || settings.inlineimage);
+}
+
+bool prc(string format="") {
+ return prc0(format) && Embed != null;
+}
+
+bool is3D(string format="")
+{
+ return prc(format) || settings.render != 0;
+}
+
+frame enclose(string prefix=defaultfilename, object F, string format="")
+{
+ if(prc(format)) {
+ frame f;
+ label(f,F.L);
+ return f;
+ } return F.f;
+}
+
+include plain_xasy;
+
+void shipout(string prefix=defaultfilename, frame f,
+ string format="", bool wait=false, bool view=true,
+ string options="", string script="",
+ projection P=currentprojection)
+{
+ if(is3D(f)) {
+ f=enclose(prefix,embed3(prefix,f,format,options,script,P));
+ if(settings.render != 0 && !prc(format)) {
+ shipped=true;
+ return;
+ }
+ }
+
+ if(inXasyMode) {
+ erase();
+ add(f,group=false);
+ return;
+ }
+
+ // Applications like LaTeX cannot handle large PostScript coordinates.
+ pair m=min(f);
+ int limit=2000;
+ if(abs(m.x) > limit || abs(m.y) > limit) f=shift(-m)*f;
+
+ shipout(prefix,f,currentpatterns,format,wait,view,xformStack.pop0);
+ shipped=true;
+}
+
+void shipout(string prefix=defaultfilename, picture pic=currentpicture,
+ orientation orientation=orientation,
+ string format="", bool wait=false, bool view=true,
+ string options="", string script="",
+ projection P=currentprojection)
+{
+ if(!uptodate()) {
+ bool inlinetex=settings.inlinetex;
+ bool prc=prc(format);
+ if(prc && !pic.empty3())
+ settings.inlinetex=settings.inlineimage;
+ frame f=pic.fit(prefix,format,view=view,options,script,P);
+ if(!pic.empty2() || settings.render == 0 || prc)
+ shipout(prefix,orientation(f),format,wait,view);
+ settings.inlinetex=inlinetex;
+ }
+
+ pic.uptodate=true;
+ shipped=true;
+}
+
+void newpage(picture pic=currentpicture)
+{
+ pic.add(new void(frame f, transform) {
+ newpage(f);
+ },true);
+}
diff --git a/Build/source/utils/asymptote/base/plain_strings.asy b/Build/source/utils/asymptote/base/plain_strings.asy
new file mode 100644
index 00000000000..2df4743171f
--- /dev/null
+++ b/Build/source/utils/asymptote/base/plain_strings.asy
@@ -0,0 +1,183 @@
+string defaultformat(int n, string trailingzero="", bool fixed=false,
+ bool signed=true)
+{
+ return "$%"+trailingzero+"."+string(n)+(fixed ? "f" : "g")+"$";
+}
+
+string defaultformat=defaultformat(4);
+
+string ask(string prompt)
+{
+ write(stdout,prompt);
+ return stdin;
+}
+
+string getstring(string name="", string default="", string prompt="",
+ bool store=true)
+{
+ string[] history=history(name,1);
+ if(history.length > 0) default=history[0];
+ if(prompt == "") prompt=name+"? [%s] ";
+ prompt=replace(prompt,new string[][] {{"%s",default}});
+ string s=readline(prompt,name);
+ if(s == "") s=default;
+ else saveline(name,s,store);
+ return s;
+}
+
+int getint(string name="", int default=0, string prompt="", bool store=true)
+{
+ return (int) getstring(name,(string) default,prompt,store);
+}
+
+real getreal(string name="", real default=0, string prompt="", bool store=true)
+{
+ return (real) getstring(name,(string) default,prompt,store);
+}
+
+pair getpair(string name="", pair default=0, string prompt="", bool store=true)
+{
+ return (pair) getstring(name,(string) default,prompt,store);
+}
+
+triple gettriple(string name="", triple default=(0,0,0), string prompt="",
+ bool store=true)
+{
+ return (triple) getstring(name,(string) default,prompt,store);
+}
+
+// returns a string with all occurrences of string 'before' in string 's'
+// changed to string 'after'.
+string replace(string s, string before, string after)
+{
+ return replace(s,new string[][] {{before,after}});
+}
+
+// Like texify but don't convert embedded TeX commands: \${}
+string TeXify(string s)
+{
+ static string[][] t={{"&","\&"},{"%","\%"},{"_","\_"},{"#","\#"},{"<","$<$"},
+ {">","$>$"},{"|","$|$"},{"^","$\hat{\ }$"},
+ {"~","$\tilde{\ }$"},{" ","\phantom{ }"}};
+ return replace(s,t);
+}
+
+private string[][] trans1={{'\\',"\backslash "},
+ {"$","\$"},{"{","\{"},{"}","\}"}};
+private string[][] trans2={{"\backslash ","$\backslash$"}};
+
+// Convert string to TeX
+string texify(string s)
+{
+ return TeXify(replace(replace(s,trans1),trans2));
+}
+
+// Convert string to TeX, preserving newlines
+string verbatim(string s)
+{
+ bool space=substr(s,0,1) == '\n';
+ static string[][] t={{'\n',"\\"}};
+ t.append(trans1);
+ s=TeXify(replace(replace(s,t),trans2));
+ return space ? "\ "+s : s;
+}
+
+// Split a string into an array of substrings delimited by delimiter
+string[] split(string s, string delimiter)
+{
+ string[] S;
+ int last=0;
+ int i;
+ int N=length(delimiter);
+ while((i=find(s,delimiter,last)) >= 0) {
+ if(i >= last)
+ S.push(substr(s,last,i-last));
+ last=i+N;
+ }
+ int n=length(s);
+ if(n >= last)
+ S.push(substr(s,last,n-last));
+ return S;
+}
+
+int[] operator ecast(string[] a)
+{
+ return sequence(new int(int i) {return (int) a[i];},a.length);
+}
+
+real[] operator ecast(string[] a)
+{
+ return sequence(new real(int i) {return (real) a[i];},a.length);
+}
+
+// Read contents of file as a string.
+string file(string s)
+{
+ file f=input(s);
+ string s;
+ while(!eof(f)) {
+ s += f+'\n';
+ }
+ return s;
+}
+
+string italic(string s)
+{
+ return s != "" ? "{\it "+s+"}" : s;
+}
+
+string baseline(string s, string template="\strut")
+{
+ return s != "" ? "\vphantom{"+template+"}"+s : s;
+}
+
+string math(string s)
+{
+ return s != "" ? "$"+s+"$" : s;
+}
+
+string graphic(string name, string options="")
+{
+ if(options != "") options="["+options+"]";
+ return "\includegraphics"+options+"{"+name+"}";
+}
+
+string minipage(string s, real width=100bp)
+{
+ if(latex())
+ return "\begin{minipage}{"+(string) (width*pt)+"pt}"+s+"\end{minipage}";
+ write("warning: minipage requires -tex latex or -tex pdflatex");
+ return "";
+}
+
+void usepackage(string s, string options="")
+{
+ if(latex()) {
+ string usepackage="\usepackage";
+ if(options != "") usepackage += "["+options+"]";
+ texpreamble(usepackage+"{"+s+"}");
+ return;
+ }
+ write("warning: usepackage requires -tex latex or -tex pdflatex");
+}
+
+void pause(string w="Hit enter to continue")
+{
+ write(w);
+ w=stdin;
+}
+
+string math(real x)
+{
+ return math((string) x);
+}
+
+string format(real x)
+{
+ return format(defaultformat,x);
+}
+
+string phantom(string s)
+{
+ return "\phantom{"+s+"}";
+}
diff --git a/Build/source/utils/asymptote/base/plain_xasy.asy b/Build/source/utils/asymptote/base/plain_xasy.asy
new file mode 100644
index 00000000000..162cbfb35ad
--- /dev/null
+++ b/Build/source/utils/asymptote/base/plain_xasy.asy
@@ -0,0 +1,128 @@
+restricted bool inXasyMode=false;
+bool diagnostics=false;
+void report(string text)
+{
+ if(diagnostics)
+ write(text);
+}
+void report(transform t)
+{
+ if(diagnostics)
+ write(t);
+}
+void report(int i)
+{
+ if(diagnostics)
+ write(i);
+}
+void initXasyMode()
+{
+ size(0,0);
+ inXasyMode=true;
+}
+
+void exitXasyMode()
+{
+ inXasyMode=false;
+}
+private picture[] tempStore;
+private picture newPic;
+void startScript()
+{
+ tempStore.push(currentpicture.copy());
+ newPic=new picture;
+ currentpicture=newPic;
+}
+
+void endScript()
+{
+ if(tempStore.length < 1) {
+ abort("endScript() without matching beginScript()");
+ } else {
+ currentpicture=tempStore.pop();
+ add(currentpicture,newPic.fit(),group=false);
+ }
+ shipped=false;
+}
+
+struct indexedTransform {
+ int index;
+ transform t;
+ bool active;
+ void operator init(int index, transform t, bool active=true) {
+ this.index=index;
+ this.t=t;
+ this.active=active;
+ }
+}
+
+struct framedTransformStack {
+ struct transact {
+ transform t;
+ bool active;
+ void operator init(transform t, bool active=true) {
+ this.t=t;
+ this.active=active;
+ }
+ void operator init(indexedTransform i){
+ this.t=i.t;
+ this.active=i.active;
+ }
+ void operator init() {
+ this.t=identity();
+ this.active=true;
+ }
+ }
+ private transact[] stack;
+ private int[] frames;
+ private int stackBase=0;
+ transform pop() {
+ if(stack.length == 0)
+ return identity();
+ else {
+ transform popped=stack[0].t;
+ stack.delete(0);
+ report("Popped");
+ report(popped);
+ return popped;
+ }
+ }
+
+ transform pop0() {
+ if(stack.length == 0)
+ return identity();
+ else {
+ static transform zerotransform=(0,0,0,0,0,0);
+ transform popped=stack[0].active ? stack[0].t : zerotransform;
+ stack.delete(0);
+ report("Popped");
+ report(popped);
+ return popped;
+ }
+ }
+
+ void push(transform t, bool Active=true) {
+ report("Pushed");
+ report(t);
+ stack.push(transact(t,Active));
+ }
+
+ void add(... indexedTransform[] tList) {
+ transact[] toPush;
+ for(int a=0; a < tList.length; ++a)
+ toPush[tList[a].index]=transact(tList[a]);
+ for(int a=0; a < toPush.length; ++a)
+ if(!toPush.initialized(a))
+ toPush[a]=transact();
+ report("Added");
+ report(toPush.length);
+ stack.append(toPush);
+ }
+}
+
+framedTransformStack xformStack;
+
+void deconstruct(picture pic=currentpicture, real magnification=1)
+{
+ deconstruct(pic.fit(),currentpatterns,magnification,xformStack.pop);
+}
diff --git a/Build/source/utils/asymptote/base/pstoedit.asy b/Build/source/utils/asymptote/base/pstoedit.asy
new file mode 100644
index 00000000000..7baccd3ed69
--- /dev/null
+++ b/Build/source/utils/asymptote/base/pstoedit.asy
@@ -0,0 +1,18 @@
+pen textpen=basealign;
+pair align=Align;
+
+// Compatibility routines for the pstoedit (version 3.43 or later) backend.
+void gsave(picture pic=currentpicture)
+{
+ pic.add(new void (frame f, transform) {
+ gsave(f);
+ },true);
+}
+
+void grestore(picture pic=currentpicture)
+{
+ pic.add(new void (frame f, transform) {
+ grestore(f);
+ },true);
+}
+
diff --git a/Build/source/utils/asymptote/base/reload.js b/Build/source/utils/asymptote/base/reload.js
new file mode 100644
index 00000000000..a6526803056
--- /dev/null
+++ b/Build/source/utils/asymptote/base/reload.js
@@ -0,0 +1,23 @@
+// Load/reload the document associated with a given path.
+
+// UNIX: Copy to ~/.adobe/Acrobat/x.x/JavaScripts/
+// To avoid random window placement we recommend specifying an acroread
+// geometry option, for example: -geometry +0+0
+
+// MSWindows: Copy to %APPDATA%/Adobe/Acrobat/x.x/JavaScripts/
+
+// Note: x.x represents the appropriate Acrobat Reader version number.
+
+reload = app.trustedFunction(function(path) {
+ app.beginPriv();
+ n=app.activeDocs.length;
+ for(i=app.activeDocs.length-1; i >= 0; --i) {
+ Doc=app.activeDocs[i];
+ if(Doc.path == path && Doc != this) {
+ Doc.closeDoc();
+ break;
+ }
+ }
+ app.openDoc(path);
+ app.endPriv();
+ });
diff --git a/Build/source/utils/asymptote/base/roundedpath.asy b/Build/source/utils/asymptote/base/roundedpath.asy
new file mode 100644
index 00000000000..1a426f91dcb
--- /dev/null
+++ b/Build/source/utils/asymptote/base/roundedpath.asy
@@ -0,0 +1,84 @@
+// a function to round sharp edges of open and cyclic paths
+// written by stefan knorr
+
+path roundedpath(path A, real R, real S = 1)
+// create rounded path from path A with radius R and scale S = 1
+{
+ path RoundPath; // returned path
+ path LocalPath; // local straight subpath
+ path LocalCirc; // local edge circle for intersection
+ real LocalTime; // local intersectiontime between . and ..
+ pair LocalPair; // local point to be added to 'RoundPath'
+
+ int len=length(A); // length of given path 'A'
+ bool PathClosed=cyclic(A); // true, if given path 'A' is cyclic
+
+ // initialisation: define first Point of 'RoundPath' as
+ if (PathClosed) // ? is 'A' cyclic
+ RoundPath=scale(S)*point(point(A,0)--point(A,1), 0.5); // centerpoint of first straight subpath of 'A'
+ else
+ RoundPath=scale(S)*point(A,0); // first point of 'A'
+
+ // doing everything between start and end
+ // create round paths subpath by subpath for every i-th edge
+ for(int i=1; i < len; ++i)
+ {
+ // straight subpath towards i-th edge
+ LocalPath=point(A,i-1)---point(A,i);
+ // circle with radius 'R' around i-th edge
+ LocalCirc=circle(point(A,i),R);
+ // calculate intersection time between straight subpath and circle
+ real[] t=intersect(LocalPath, LocalCirc);
+ if(t.length > 0) {
+ LocalTime=t[0];
+ // define intersectionpoint between both paths
+ LocalPair=point(subpath(LocalPath, 0, LocalTime), 1);
+ // add straight subpath towards i-th curvature to 'RoundPath'
+ RoundPath=RoundPath--scale(S)*LocalPair;
+ }
+
+ // straight subpath from i-th edge to (i+1)-th edge
+ LocalPath=point(A,i)---point(A,i+1);
+ // calculate intersection-time between straight subpath and circle
+ real[] t=intersect(LocalPath, LocalCirc);
+ if(t.length > 0) {
+ LocalTime=t[0];
+ // define intersectionpoint between both paths
+ LocalPair=point(subpath(LocalPath, 0, LocalTime), 1);
+ // add curvature near i-th edge to 'RoundPath'
+ RoundPath=RoundPath..scale(S)*LocalPair;
+ }
+ }
+
+ // final steps to have a correct termination
+ if(PathClosed) { // Is 'A' cyclic?
+ // straight subpath towards 0-th edge
+ LocalPath=point(A,len-1)---point(A,0);
+ // circle with radius 'R' around 0-th edge
+ LocalCirc=circle(point(A,0),R);
+ // calculate intersection-time between straight subpath and circle
+ real[] t=intersect(LocalPath, LocalCirc);
+ if(t.length > 0) {
+ LocalTime=t[0];
+ // define intersectionpoint between both paths
+ LocalPair=point(subpath(LocalPath, 0, LocalTime), 1);
+ // add straight subpath towards 0-th curvature to 'RoundPath'
+ RoundPath=RoundPath--scale(S)*LocalPair;
+ }
+
+
+ // straight subpath from 0-th edge to 1st edge
+ LocalPath=point(A,0)---point(A,1);
+ // calculate intersection-time between straight subpath and circle
+ real[] t=intersect(LocalPath, LocalCirc);
+ if(t.length > 0) {
+ LocalTime=t[0];
+ // define intersectionpoint between both paths
+ LocalPair=point(subpath(LocalPath, 0, LocalTime), 1);
+ // add curvature near 0-th edge to 'RoundPath' and close path
+ RoundPath=RoundPath..scale(S)*LocalPair--cycle;
+ }
+ } else
+ RoundPath=RoundPath--scale(S)*point(A,len);
+ return RoundPath;
+}
diff --git a/Build/source/utils/asymptote/base/simplex.asy b/Build/source/utils/asymptote/base/simplex.asy
new file mode 100644
index 00000000000..bd9f69c9324
--- /dev/null
+++ b/Build/source/utils/asymptote/base/simplex.asy
@@ -0,0 +1,272 @@
+/*****
+ * simplex.asy
+ * Andy Hammerlindl 2004/07/27
+ *
+ * Solves the two-variable linear programming problem using the simplex method.
+ * This problem is specialized in that the second variable, "b", does not have
+ * a non-negativity condition, and the first variable, "a", is the quantity
+ * being maximized.
+ * Correct execution of the algorithm also assumes that the coefficient of "b"
+ * will be +1 or -1 in every added restriction, and that the problem can be
+ * initialized to a valid state by pivoting b with one of the slack
+ * variables. This assumption may in fact be incorrect.
+ *****/
+
+private real infinity=sqrt(0.25*realMax);
+
+struct problem {
+ typedef int var;
+ static var VAR_A = 0;
+ static var VAR_B = 1;
+
+ static int OPTIMAL = -1;
+ static var UNBOUNDED = -2;
+ static int INVALID = -3;
+
+ struct row {
+ real c, t[];
+ }
+
+ // The variables of the rows.
+ // Initialized for the two variable problem.
+ var[] v = {VAR_A, VAR_B};
+
+ // The rows of equalities.
+ row rowA() {
+ row r = new row;
+ r.c = 0;
+ r.t = new real[] {1, 0};
+ return r;
+ }
+ row rowB() {
+ row r = new row;
+ r.c = 0;
+ r.t = new real[] {0, 1};
+ return r;
+ }
+ row[] rows = {rowA(), rowB()};
+
+ // The number of original variables.
+ int n = rows.length;
+
+ // Pivot the variable v[col] with vp.
+ void pivot(int col, var vp)
+ {
+ var vc=v[col];
+
+ // Recalculate rows v[col] and vp for the pivot-swap.
+ row rvc = rows[vc], rvp = rows[vp];
+ real factor=1/rvp.t[col]; // NOTE: Handle rvp.t[col] == 0 case.
+ rvc.c=-rvp.c*factor;
+ rvp.c=0;
+ rvc.t=-rvp.t*factor;
+ rvp.t *= 0;
+ rvc.t[col]=factor;
+ rvp.t[col]=1;
+
+ var a=min(vc,vp);
+ var b=max(vc,vp);
+
+ // Recalculate the rows other than the two used for the above pivot.
+ for (var i = 0; i < a; ++i) {
+ row r=rows[i];
+ real m = r.t[col];
+ r.c += m*rvc.c;
+ r.t += m*rvc.t;
+ r.t[col]=m*factor;
+ }
+ for (var i = a+1; i < b; ++i) {
+ row r=rows[i];
+ real m = r.t[col];
+ r.c += m*rvc.c;
+ r.t += m*rvc.t;
+ r.t[col]=m*factor;
+ }
+ for (var i = b+1; i < rows.length; ++i) {
+ row r=rows[i];
+ real m = r.t[col];
+ r.c += m*rvc.c;
+ r.t += m*rvc.t;
+ r.t[col]=m*factor;
+ }
+
+ // Relabel the vars.
+ v[col] = vp;
+ }
+
+ // As b does not have a non-negativity condition, it must initially be
+ // pivoted out for a variable that does. This selects the initial
+ // variable to pivot with b. It also assumes that there is a valid
+ // solution with a == 0 to the linear programming problem, and if so, it
+ // picks a pivot to get to that state. In our case, a == 0 corresponds to
+ // a picture with the user coordinates shrunk down to zero, and if that
+ // doesn't fit, nothing will.
+ var initVar()
+ {
+ real min=infinity, max=-infinity;
+ var argmin=0, argmax=0;
+
+ for (var i = 2; i < rows.length; ++i) {
+ row r=rows[i];
+ if (r.t[VAR_B] > 0) {
+ real val=r.c/r.t[VAR_B];
+ if (val < min) {
+ min=val;
+ argmin=i;
+ }
+ } else if (r.t[VAR_B] < 0) {
+ real val=r.c/r.t[VAR_B];
+ if (val > max) {
+ max=val;
+ argmax=i;
+ }
+ }
+ }
+
+ // If b has a minimal value, choose a pivot that will give b its minimal
+ // value. Otherwise, if b has maximal value, choose a pivot to give b its
+ // maximal value.
+ return argmin != 0 ? argmin :
+ argmax != 0 ? argmax :
+ UNBOUNDED;
+ }
+
+ // Initialize the linear program problem by moving into an acceptable state
+ // this assumes that b is unrestrained and is the second variable.
+ // NOTE: Works in limited cases, may be bug-ridden.
+ void init()
+ {
+ // Find the lowest constant term in the equations.
+ var lowest = 0;
+ for (var i = 2; i < rows.length; ++i) {
+ if (rows[i].c < rows[lowest].c)
+ lowest = i;
+ }
+
+ // Pivot if necessary.
+ if (lowest != 0)
+ pivot(VAR_B, lowest);
+ }
+
+ // Selects a column to pivot on. Returns OPTIMAL if the current state is
+ // optimal. Assumes we are optimizing the first row.
+ int selectColumn()
+ {
+ int i=find(rows[0].t > 0,1);
+ return (i >= 0) ? i : OPTIMAL;
+ }
+
+ // Select the new variable associated with a pivot on the column given.
+ // Returns UNBOUNDED if the space is unbounded.
+ var selectVar(int col)
+ {
+ // We assume that the first two vars (a and b) once swapped out, won't be
+ // swapped back in. This finds the variable which gives the tightest
+ // non-negativity condition restricting our optimization. This turns
+ // out to be the max of c/t[col]. Note that as c is positive, and
+ // t[col] is negative, all c/t[col] will be negative, so we are finding
+ // the smallest in magnitude.
+ var vp=UNBOUNDED;
+ real max=-infinity;
+ for (int i = 2; i < rows.length; ++i) {
+ row r=rows[i];
+ if(r.c < max*r.t[col]) {
+ max=r.c/r.t[col]; vp=i;
+ }
+ }
+
+ return vp;
+ }
+
+ // Checks that the rows are in a valid state.
+ bool valid()
+ {
+ // Checks that constants are valid.
+ bool validConstants() {
+ for (int i = 0; i < rows.length; ++i)
+ if (rows[i].c < 0)
+ return false;
+ return true;
+ }
+
+ // Check a variable to see if its row is simple.
+ // NOTE: Simple rows could be optimized out, since they are not really
+ // used.
+ bool validVar(int col) {
+
+ var vc = v[col];
+ row rvc = rows[vc];
+
+ if (rvc.c != 0)
+ return false;
+ for (int i = 0; i < n; ++i)
+ if (rvc.t[i] != (i == col ? 1 : 0))
+ return false;
+
+ return true;
+ }
+
+ if (!validConstants()) {
+ return false;
+ }
+ for (int i = 0; i < n; ++i)
+ if (!validVar(i)) {
+ return false;
+ }
+
+ return true;
+ }
+
+
+ // Perform the algorithm to find the optimal solution. Returns OPTIMAL,
+ // UNBOUNDED, or INVALID (if no solution is possible).
+ int optimize()
+ {
+ // Put into a valid state to begin and pivot b out.
+ var iv=initVar();
+ if (iv == UNBOUNDED)
+ return iv;
+ pivot(VAR_B, iv);
+
+ if (!valid())
+ return INVALID;
+
+ while(true) {
+ int col = selectColumn();
+
+ if (col == OPTIMAL)
+ return col;
+ var vp = selectVar(col);
+
+ if (vp == UNBOUNDED)
+ return vp;
+
+ pivot(col, vp);
+ }
+
+ // Shouldn't reach here.
+ return INVALID;
+ }
+
+ // Add a restriction to the problem:
+ // t1*a + t2*b + c >= 0
+ void addRestriction(real t1, real t2, real c)
+ {
+ row r = new row;
+ r.c = c;
+ r.t = new real[] {t1, t2};
+ rows.push(r);
+ }
+
+ // Return the value of a computed.
+ real a()
+ {
+ return rows[VAR_A].c;
+ }
+
+ // Return the value of b computed.
+ real b()
+ {
+ return rows[VAR_B].c;
+ }
+}
diff --git a/Build/source/utils/asymptote/base/size10.asy b/Build/source/utils/asymptote/base/size10.asy
new file mode 100644
index 00000000000..3bbd31227a9
--- /dev/null
+++ b/Build/source/utils/asymptote/base/size10.asy
@@ -0,0 +1,12 @@
+texpreamble("\makeatletter%
+\renewcommand\normalsize{\@setfontsize\normalsize\@xpt\@xiipt}%
+\renewcommand\small{\@setfontsize\small\@ixpt{11}}%
+\renewcommand\footnotesize{\@setfontsize\footnotesize\@viiipt{9.5}}%
+\renewcommand\scriptsize{\@setfontsize\scriptsize\@viipt\@viiipt}%
+\renewcommand\tiny{\@setfontsize\tiny\@vpt\@vipt}%
+\renewcommand\large{\@setfontsize\large\@xiipt{14}}%
+\renewcommand\Large{\@setfontsize\Large\@xivpt{18}}%
+\renewcommand\LARGE{\@setfontsize\LARGE\@xviipt{22}}%
+\renewcommand\huge{\@setfontsize\huge\@xxpt{25}}%
+\renewcommand\Huge{\@setfontsize\Huge\@xxvpt{30}}%
+\makeatother");
diff --git a/Build/source/utils/asymptote/base/size11.asy b/Build/source/utils/asymptote/base/size11.asy
new file mode 100644
index 00000000000..93712288152
--- /dev/null
+++ b/Build/source/utils/asymptote/base/size11.asy
@@ -0,0 +1,12 @@
+texpreamble("\makeatletter%
+\renewcommand\normalsize{\@setfontsize\normalsize\@xipt{13.6}}%
+\renewcommand\small{\@setfontsize\small\@xpt\@xiipt}%
+\renewcommand\footnotesize{\@setfontsize\footnotesize\@ixpt{11}}%
+\renewcommand\scriptsize{\@setfontsize\scriptsize\@viiipt{9.5}}
+\renewcommand\tiny{\@setfontsize\tiny\@vipt\@viipt}
+\renewcommand\large{\@setfontsize\large\@xiipt{14}}
+\renewcommand\Large{\@setfontsize\Large\@xivpt{18}}
+\renewcommand\LARGE{\@setfontsize\LARGE\@xviipt{22}}
+\renewcommand\huge{\@setfontsize\huge\@xxpt{25}}
+\renewcommand\Huge{\@setfontsize\Huge\@xxvpt{30}}
+\makeatother");
diff --git a/Build/source/utils/asymptote/base/slide.asy b/Build/source/utils/asymptote/base/slide.asy
new file mode 100644
index 00000000000..5b3596d02e6
--- /dev/null
+++ b/Build/source/utils/asymptote/base/slide.asy
@@ -0,0 +1,574 @@
+import fontsize;
+usepackage("asycolors");
+
+bool reverse=false; // Set to true to enable reverse video.
+bool stepping=false; // Set to true to enable stepping.
+bool itemstep=true; // Set to false to disable stepping on each item.
+
+settings.toolbar=false; // Disable 3D toolbar by default.
+if(settings.render < 0) settings.render=4;
+
+bool allowstepping=false; // Allow stepping for current slide.
+
+real pagemargin=0.5cm;
+real pagewidth=-2pagemargin;
+real pageheight=-2pagemargin;
+
+bool landscape=orientation == Landscape || orientation == Seascape;
+
+if(landscape) {
+ orientation=Portrait;
+ real temp=settings.paperwidth;
+ settings.paperwidth=settings.paperheight;
+ settings.paperheight=temp;
+ pagewidth += settings.paperwidth;
+ pageheight += settings.paperheight;
+} else {
+ pagewidth += settings.paperwidth;
+ pageheight += settings.paperheight;
+}
+
+size(pagewidth,pageheight,IgnoreAspect);
+picture background;
+
+real minipagemargin=1inch;
+real minipagewidth=pagewidth-2minipagemargin;
+
+transform tinv=inverse(fixedscaling((-1,-1),(1,1),currentpen));
+
+pen itempen=fontsize(24pt);
+pen codepen=fontsize(20pt);
+pen titlepagepen=fontsize(36pt);
+pen authorpen=fontsize(24pt);
+pen institutionpen=authorpen;
+pen datepen=fontsize(18pt);
+pen urlpen=datepen;
+
+real itemskip=0.5;
+real codeskip=0.25;
+pair dateskip=(0,0.1);
+pair urlskip=(0,0.2);
+
+pair titlealign=3S;
+pen titlepen=fontsize(32pt);
+real titleskip=0.5;
+
+string oldbulletcolor;
+string newbulletcolor="red";
+string bullet="{\bulletcolor\textbullet}";
+
+pair pagenumberposition=S+E;
+pair pagenumberalign=4NW;
+pen pagenumberpen=fontsize(12);
+pen steppagenumberpen=colorless(pagenumberpen);
+
+real figureborder=0.25cm;
+pen figuremattpen;
+
+pen backgroundcolor;
+pen foregroundcolor;
+
+pair titlepageposition=(-0.8,0.4);
+pair startposition=(-0.8,0.9);
+pair currentposition=startposition;
+
+string bulletcolor(string color)
+{
+ return "\def\bulletcolor{"+'\\'+"color{"+color+"}}%";
+}
+
+int[] firstnode=new int[] {currentpicture.nodes.length};
+int[] lastnode;
+bool firststep=true;
+
+int page=0;
+bool havepagenumber=true;
+
+int preamblenodes=2;
+
+bool empty()
+{
+ return currentpicture.nodes.length <= preamblenodes;
+}
+
+void background()
+{
+ if(!background.empty()) {
+ add(background);
+ layer();
+ preamblenodes += 2;
+ }
+}
+
+void color(string name, string color)
+{
+ texpreamble("\def"+'\\'+name+"#1{{\color{"+color+"}#1}}%");
+}
+
+string texcolor(pen p)
+{
+ real[] colors=colors(p);
+ string s;
+ if(colors.length > 0) {
+ s="{"+colorspace(p)+"}{";
+ for(int i=0; i < colors.length-1; ++i)
+ s += format("%.6f",colors[i],"C")+",";
+ s += format("%.6f",colors[colors.length-1],"C")+"}";
+ }
+ return s;
+}
+
+void setpens(pen red=red, pen blue=blue, pen steppen=red)
+{
+ itempen=colorless(itempen);
+ codepen=colorless(codepen);
+ pagenumberpen=colorless(pagenumberpen);
+ steppagenumberpen=colorless(steppagenumberpen)+steppen;
+ titlepagepen=colorless(titlepagepen)+red;
+ authorpen=colorless(authorpen)+blue;
+ institutionpen=colorless(institutionpen)+blue;
+ datepen=colorless(datepen);
+ urlpen=colorless(urlpen);
+}
+
+void reversevideo()
+{
+ backgroundcolor=black;
+ foregroundcolor=white;
+ fill(background,box((-1,-1),(1,1)),backgroundcolor);
+ setpens(mediumred,paleblue,mediumblue);
+ // Work around pdflatex bug, in which white is mapped to black!
+ figuremattpen=pdf() ? cmyk(0,0,0,1/255) : white;
+ color("Red","mediumred");
+ color("Green","green");
+ color("Blue","paleblue");
+ color("Foreground","white");
+ color("Background","black");
+ oldbulletcolor="white";
+ defaultpen(itempen+foregroundcolor);
+}
+
+void normalvideo() {
+ backgroundcolor=invisible;
+ foregroundcolor=black;
+ background=new picture;
+ size(background,currentpicture);
+ setpens();
+ figuremattpen=invisible;
+ color("Red","red");
+ color("Green","heavygreen");
+ color("Blue","blue");
+ color("Foreground","black");
+ color("Background","white");
+ oldbulletcolor="black";
+ defaultpen(itempen+foregroundcolor);
+}
+
+normalvideo();
+
+texpreamble(bulletcolor(newbulletcolor));
+texpreamble("\hyphenpenalty=10000\tolerance=1000");
+
+// Evaluate user command line option.
+void usersetting()
+{
+ plain.usersetting();
+ if(reverse) { // Black background
+ reversevideo();
+ } else { // White background
+ normalvideo();
+ }
+}
+
+void numberpage(pen p=pagenumberpen)
+{
+ if(havepagenumber) {
+ label((string) page,pagenumberposition,pagenumberalign,p);
+ }
+}
+
+void nextpage(pen p=pagenumberpen)
+{
+ if(!empty()) {
+ numberpage(p);
+ newpage();
+ }
+ background();
+ firststep=true;
+}
+
+void newslide(bool stepping=true)
+{
+ allowstepping=stepping;
+ nextpage();
+ ++page;
+ havepagenumber=true;
+ currentposition=startposition;
+ firstnode=new int[] {currentpicture.nodes.length};
+ lastnode.delete();
+}
+
+bool checkposition()
+{
+ if(abs(currentposition.x) > 1 || abs(currentposition.y) > 1) {
+ newslide();
+ return false;
+ }
+ return true;
+}
+
+void step()
+{
+ if(!stepping || !allowstepping) return;
+ if(!checkposition()) return;
+ lastnode.push(currentpicture.nodes.length-1);
+ nextpage(steppagenumberpen);
+ for(int i=0; i < firstnode.length; ++i) {
+ for(int j=firstnode[i]; j <= lastnode[i]; ++j) {
+ tex(bulletcolor(oldbulletcolor));
+ currentpicture.add(currentpicture.nodes[j]);
+ }
+ }
+ firstnode.push(currentpicture.nodes.length-1);
+ tex(bulletcolor(newbulletcolor));
+}
+
+void incrementposition(pair z)
+{
+ currentposition += z;
+}
+
+void title(string s, pair position=N, pair align=titlealign,
+ pen p=titlepen, bool newslide=true)
+{
+ if(newslide) newslide();
+ checkposition();
+ frame f;
+ if(s != "") label(f,minipage("\center "+s,minipagewidth),(0,0),align,p);
+ add(f,position,labelmargin(p)*align);
+ currentposition=(currentposition.x,position.y+
+ (tinv*(min(f)-titleskip*I*lineskip(p)*pt)).y);
+}
+
+void outline(string s="Outline", pair position=N, pair align=titlealign,
+ pen p=titlepen)
+{
+ newslide(stepping=false);
+ title(s,position,align,p,newslide=false);
+}
+
+void remark(bool center=false, string s, pair align=0, pen p=itempen,
+ real indent=0, bool minipage=true, real skip=itemskip,
+ filltype filltype=NoFill, bool step=false)
+{
+ checkposition();
+ if(minipage) s=minipage(s,minipagewidth);
+
+ pair offset;
+ if(center) {
+ if(align == 0) align=S;
+ offset=(0,currentposition.y);
+ } else {
+ if(align == 0) align=SE;
+ offset=currentposition;
+ }
+
+ frame f;
+ label(f,s,(indent,0),align,p,filltype);
+ pair m=tinv*min(f);
+ pair M=tinv*min(f);
+
+ if(abs(offset.x+M.x) > 1)
+ write("warning: slide too wide on page "+(string) page+':\n'+(string) s);
+
+ if(abs(offset.y+M.y) > 1) {
+ void toohigh() {
+ write("warning: slide too high on page "+(string) page+':\n'+(string) s);
+ }
+ if(M.y-m.y < 2) {
+ newslide(); offset=(offset.x,currentposition.y);
+ if(offset.y+M.y > 1 || offset.y+m.y < -1) toohigh();
+ } else toohigh();
+ }
+
+ if(step) {
+ if(!firststep) step();
+ firststep=false;
+ }
+
+ add(f,offset);
+ incrementposition((0,(tinv*(min(f)-skip*I*lineskip(p)*pt)).y));
+}
+
+void center(string s, pen p=itempen)
+{
+ remark("\center "+s,p);
+}
+
+void equation(string s, pen p=itempen)
+{
+ remark(center=true,"\vbox{$$"+s+"$$}",p,minipage=false,skip=0);
+}
+
+void vbox(string s, pen p=itempen)
+{
+ remark(center=true,"\vbox{"+s+"}",p,minipage=false,skip=0);
+}
+
+void equations(string s, pen p=itempen)
+{
+ vbox("\begin{eqnarray*}"+s+"\end{eqnarray*}",p);
+}
+
+void skip(real n=1)
+{
+ incrementposition((0,(tinv*(-n*itemskip*I*lineskip(itempen)*pt)).y));
+}
+
+void display(frame[] f, real margin=0, pair align=S, pen p=itempen,
+ pen figuremattpen=figuremattpen)
+{
+ if(f.length == 0) return;
+ real[] width=new real[f.length];
+ real sum;
+ for(int i=0; i < f.length; ++i) {
+ width[i]=size(f[i]).x;
+ sum += width[i];
+ }
+ if(sum > pagewidth)
+ write("warning: slide too wide on page "+(string) page);
+ else margin=(pagewidth-sum)/(f.length+1);
+ real pos;
+ frame F;
+ for(int i=0; i < f.length; ++i) {
+ real w=0.5*(margin+width[i]);
+ pos += w;
+ add(F,f[i],(pos,0),Fill(figureborder,figuremattpen));
+ pos += w;
+ }
+ add(F,(0,currentposition.y),align);
+ real a=0.5(unit(align).y-1);
+ incrementposition((0,(tinv*(a*(max(F)-min(F))-itemskip*I*lineskip(p)*pt)).y));
+}
+
+void display(frame f, real margin=0, pair align=S, pen p=itempen,
+ pen figuremattpen=figuremattpen)
+{
+ display(new frame[] {f},margin,align,p,figuremattpen);
+}
+
+void display(string[] s, real margin=0, string[] captions=new string[],
+ string caption="", pair align=S, pen p=itempen,
+ pen figuremattpen=figuremattpen)
+{
+ frame[] f=new frame[s.length];
+ frame F;
+ for(int i=0; i < s.length; ++i) {
+ f[i]=newframe;
+ label(f[i],s[i]);
+ add(F,f[i],(0,0));
+ }
+ real y=point(F,S).y;
+ int stop=min(s.length,captions.length);
+ for(int i=0; i < stop; ++i) {
+ if(captions[i] != "")
+ label(f[i],captions[i],point(f[i],S).x+I*y,S);
+ }
+ display(f,margin,align,p,figuremattpen);
+ if(caption != "") center(caption,p);
+}
+
+void display(string s, string caption="", pair align=S, pen p=itempen,
+ pen figuremattpen=figuremattpen)
+{
+ display(new string[] {s},caption,align,p,figuremattpen);
+}
+
+void figure(string[] s, string options="", real margin=0,
+ string[] captions=new string[], string caption="",
+ pair align=S, pen p=itempen, pen figuremattpen=figuremattpen)
+{
+ string[] S;
+ for(int i=0; i < s.length; ++i) {
+ S[i]=graphic(s[i],options);
+ }
+
+ display(S,margin,captions,caption,align,itempen,figuremattpen);
+}
+
+void figure(string s, string options="", string caption="", pair align=S,
+ pen p=itempen, pen figuremattpen=figuremattpen)
+{
+ figure(new string[] {s},options,caption,align,p,figuremattpen);
+}
+
+string[] codefile;
+
+void asyinclude(string s, real xsize=0, real ysize=xsize)
+{
+ picture currentpictureSave=currentpicture;
+ currentpicture=new picture;
+ _eval("include \""+s+"\";",true);
+ s=stripdirectory(settings.outname+"_"+s);
+ codefile.push(s);
+ frame f=(xsize > 0 || ysize > 0) ?
+ currentpicture.fit(xsize,ysize) : currentpicture.fit();
+ currentpicture=currentpictureSave;
+ display(f);
+}
+
+string cropcode(string s)
+{
+ while(substr(s,0,1) == '\n') s=substr(s,1,length(s));
+ while(substr(s,length(s)-1,1) == '\n') s=substr(s,0,length(s)-1);
+ return s;
+}
+
+void code(bool center=false, string s, pen p=codepen,
+ real indent=0, real skip=codeskip,
+ filltype filltype=NoFill)
+{
+ remark(center,"{\tt "+verbatim(cropcode(s))+"}",p,indent,skip,filltype);
+}
+
+void filecode(bool center=false, string s, pen p=codepen, real indent=0,
+ real skip=codeskip, filltype filltype=NoFill)
+{
+ code(center,file(s),p,indent,skip,filltype);
+}
+
+void asyfigure(string s, string options="", string caption="", pair align=S,
+ pen p=codepen, pen figuremattpen=figuremattpen,
+ filltype filltype=NoFill, bool newslide=false)
+{
+ string a=s+".asy";
+ asy(nativeformat(),s);
+ s += "."+nativeformat();
+ if(newslide && !empty()) {
+ newslide();
+ currentposition=(currentposition.x,0);
+ align=0;
+ }
+ figure(s,options,caption,align,p,figuremattpen);
+}
+
+string asywrite(string s, string preamble="")
+{
+ static int count=0;
+ string name=settings.outname+"_slide"+(string) count;
+ ++count;
+ file temp=output(name+".asy");
+ write(temp,preamble);
+ write(temp,s);
+ close(temp);
+ codefile.push(name);
+ return name;
+}
+
+void asycode(bool center=false, string s, string options="",
+ string caption="", string preamble="",
+ pair align=S, pen p=codepen, pen figuremattpen=figuremattpen,
+ real indent=0, real skip=codeskip,
+ filltype filltype=NoFill, bool newslide=false)
+{
+ code(center,s,p,indent,skip,filltype);
+ asyfigure(asywrite(s,preamble),options,caption,align,p,figuremattpen,filltype,
+ newslide);
+}
+
+void asyfilecode(bool center=false, string s, string options="",
+ string caption="",
+ pair align=S, pen p=codepen, pen figuremattpen=figuremattpen,
+ real indent=0, real skip=codeskip,
+ filltype filltype=NoFill, bool newslide=false)
+{
+ filecode(center,s+".asy",p,indent,skip,filltype);
+ asyfigure(s,options,caption,align,p,figuremattpen,filltype,newslide);
+}
+
+void item(string s, pen p=itempen, bool step=itemstep)
+{
+ frame b;
+ label(b,bullet,(0,0),p);
+ real bulletwidth=max(b).x-min(b).x;
+ remark(bullet+"\hangindent"+(string) bulletwidth+"pt$\,$"+s,p,
+ -bulletwidth*pt,step=step);
+}
+
+void subitem(string s, pen p=itempen)
+{
+ remark("\quad -- "+s,p);
+}
+
+void titlepage(string title, string author, string institution="",
+ string date="", string url="", bool newslide=false)
+{
+ newslide();
+ currentposition=titlepageposition;
+ center(title,titlepagepen);
+ center(author,authorpen);
+ if(institution != "") center(institution,institutionpen);
+ currentposition -= dateskip;
+ if(date != "") center(date,datepen);
+ currentposition -= urlskip;
+ if(url != "") center("{\tt "+url+"}",urlpen);
+}
+
+// Resolve optional bibtex citations:
+void bibliographystyle(string name)
+{
+ settings.twice=true;
+ settings.keepaux=true;
+ delete(outprefix()+"_.aux");
+ texpreamble("\bibliographystyle{"+name+"}");
+}
+
+void bibliography(string name)
+{
+ numberpage();
+ havepagenumber=false;
+ string s=texcolor(backgroundcolor);
+ if(s != "") tex("\definecolor{Background}"+s+"\pagecolor{Background}%");
+ label("",itempen);
+ tex("\eject\def\refname{\fontsize{"+string(fontsize(titlepen))+"}{"+
+ string(lineskip(titlepen))+"}\selectfont References}%");
+ real hmargin,vmargin;
+ if(pdf()) {
+ hmargin=1;
+ vmargin=0;
+ } else {
+ hmargin=1.5;
+ vmargin=1;
+ }
+ string s;
+ if(landscape) {
+ s="{\centering\textheight="+string(pageheight-1inch)+"bp\textwidth="+
+ string(pagewidth-1.5inches)+"bp"+
+ "\vsize=\textheight\hsize=\textwidth\linewidth=\hsize"+
+ "\topmargin="+string(vmargin)+"in\oddsidemargin="+string(hmargin)+"in";
+ } else
+ s="{\centering\textheight="+string(pageheight-0.5inches)+"bp\textwidth="+
+ string(pagewidth-0.5inches)+
+ "bp\hsize=\textwidth\linewidth=\textwidth\vsize=\textheight"+
+ "\topmargin=0.5in\oddsidemargin=1in";
+ s += "\evensidemargin=\oddsidemargin\bibliography{"+name+"}\eject}";
+ tex(s);
+}
+
+exitfcn currentexitfunction=atexit();
+
+void exitfunction()
+{
+ numberpage();
+ if(currentexitfunction != null) currentexitfunction();
+ if(!settings.keep)
+ for(int i=0; i < codefile.length; ++i) {
+ string name=codefile[i];
+ delete(name+"."+nativeformat());
+ delete(name+"_.aux");
+ delete(name+".asy");
+ }
+ codefile=new string[];
+}
+
+atexit(exitfunction);
diff --git a/Build/source/utils/asymptote/base/slopefield.asy b/Build/source/utils/asymptote/base/slopefield.asy
new file mode 100644
index 00000000000..bdbb0252670
--- /dev/null
+++ b/Build/source/utils/asymptote/base/slopefield.asy
@@ -0,0 +1,87 @@
+import graph_settings;
+real stepfraction=0.05;
+
+picture slopefield(real f(real,real), pair a, pair b,
+ int nx=nmesh, int ny=nx,
+ real tickfactor=0.5, pen p=currentpen, arrowbar arrow=None)
+{
+ picture pic;
+ real dx=(b.x-a.x)/nx;
+ real dy=(b.y-a.y)/ny;
+ real step=0.5*tickfactor*min(dx,dy);
+
+ for(int i=0; i <= nx; ++i) {
+ real x=a.x+i*dx;
+ for(int j=0; j <= ny; ++j) {
+ pair cp=(x,a.y+j*dy);
+ real slope=f(cp.x,cp.y);
+ real mp=step/sqrt(1+slope^2);
+ draw(pic,(cp.x-mp,cp.y-mp*slope)--(cp.x+mp,cp.y+mp*slope),p,arrow);
+ }
+ }
+ clip(pic,box(a,b));
+ return pic;
+}
+
+picture slopefield(real f(real), pair a, pair b,
+ int nx=nmesh, int ny=nx, pen p=currentpen,
+ arrowbar arrow=None)
+{
+ return slopefield(new real(real x, real y) {return f(x);},a,b,nx,ny,p,arrow);
+}
+
+path curve(pair c, real f(real,real), pair a, pair b)
+{
+ real step=stepfraction*(b.x-a.x);
+ real halfstep=0.5*step;
+ real sixthstep=step/6;
+
+ path follow(real sign) {
+ pair cp=c;
+ guide g=cp;
+ real dx,dy;
+ real factor=1;
+ do {
+ real slope;
+ pair S(pair z) {
+ slope=f(z.x,z.y);
+ return factor*sign/sqrt(1+slope^2)*(1,slope);
+ }
+ pair S3;
+ pair advance() {
+ pair S0=S(cp);
+ pair S1=S(cp+halfstep*S0);
+ pair S2=S(cp+halfstep*S1);
+ S3=S(cp+step*S2);
+ pair cp0=cp+sixthstep*(S0+2S1+2S2+S3);
+ dx=min(cp0.x-a.x,b.x-cp0.x);
+ dy=min(cp0.y-a.y,b.y-cp0.y);
+ return cp0;
+ }
+ pair cp0=advance();
+ if(dx < 0) {
+ factor=(step+dx)/step;
+ cp0=advance();
+ g=g..{S3}cp0{S3};
+ break;
+ }
+ if(dy < 0) {
+ factor=(step+dy)/step;
+ cp0=advance();
+ g=g..{S3}cp0{S3};
+ break;
+ }
+ cp=cp0;
+ g=g..{S3}cp{S3};
+ } while (dx > 0 && dy > 0);
+ return g;
+ }
+
+ return reverse(follow(-1))&follow(1);
+}
+
+path curve(pair c, real f(real), pair a, pair b)
+{
+ return curve(c,new real(real x, real y){return f(x);},a,b);
+}
+
diff --git a/Build/source/utils/asymptote/base/solids.asy b/Build/source/utils/asymptote/base/solids.asy
new file mode 100644
index 00000000000..0b2ffa2a508
--- /dev/null
+++ b/Build/source/utils/asymptote/base/solids.asy
@@ -0,0 +1,395 @@
+import three;
+import graph3;
+
+pen defaultbackpen=linetype("4 4",4,scale=false);
+
+// A solid geometry package.
+
+// Try to find a bounding tangent line between two paths.
+real[] tangent(path p, path q, bool side)
+{
+ static real fuzz=1.0e-5;
+
+ if((cyclic(p) && inside(p,point(q,0)) ||
+ cyclic(q) && inside(q,point(p,0))) &&
+ intersect(p,q,fuzz).length == 0) return new real[];
+
+ for(int i=0; i < 100; ++i) {
+ real ta=side ? mintimes(p)[1] : maxtimes(p)[1];
+ real tb=side ? mintimes(q)[1] : maxtimes(q)[1];
+ pair a=point(p,ta);
+ pair b=point(q,tb);
+ real angle=angle(b-a,warn=false);
+ if(abs(angle) <= sqrtEpsilon || abs(abs(0.5*angle)-pi) <= sqrtEpsilon)
+ return new real[] {ta,tb};
+ transform t=rotate(-degrees(angle));
+ p=t*p;
+ q=t*q;
+ }
+ return new real[];
+}
+
+path line(path p, path q, real[] t)
+{
+ return point(p,t[0])--point(q,t[1]);
+}
+
+// Return the projection of a generalized cylinder of height h constructed
+// from area base in the XY plane and aligned with axis.
+path[] cylinder(path3 base, real h, triple axis=Z,
+ projection P=currentprojection)
+{
+ base=rotate(-colatitude(axis),cross(axis,Z))*base;
+ path3 top=shift(h*axis)*base;
+ path Base=project(base,P);
+ path Top=project(top,P);
+ real[] t1=tangent(Base,Top,true);
+ real[] t2=tangent(Base,Top,false);
+ path p=subpath(Base,t1[0]/P.ninterpolate,t2[0]/P.ninterpolate);
+ path q=subpath(Base,t2[0]/P.ninterpolate,t1[0]/P.ninterpolate);
+ return Base^^Top^^line(Base,Top,t1)^^line(Base,Top,t2);
+}
+
+// The three-dimensional "wireframe" used to visualize a volume of revolution
+struct skeleton {
+ struct curve {
+ path3[] front;
+ path3[] back;
+ }
+ // transverse skeleton (perpendicular to axis of revolution)
+ curve transverse;
+ // longitudinal skeleton (parallel to axis of revolution)
+ curve longitudinal;
+}
+
+// A surface of revolution generated by rotating a planar path3 g
+// from angle1 to angle2 about c--c+axis.
+struct revolution {
+ triple c;
+ path3 g;
+ triple axis;
+ real angle1,angle2;
+ triple M;
+ triple m;
+
+ static real epsilon=10*sqrtEpsilon;
+
+ void operator init(triple c=O, path3 g, triple axis=Z, real angle1=0,
+ real angle2=360) {
+ this.c=c;
+ this.g=g;
+ this.axis=unit(axis);
+ this.angle1=angle1;
+ this.angle2=angle2;
+ M=max(g);
+ m=min(g);
+ }
+
+ // Return the surface of rotation obtain by rotating the path3 (x,0,f(x))
+ // sampled n times between x=a and x=b about an axis lying in the XZ plane.
+ void operator init(triple c=O, real f(real x), real a, real b, int n=ngraph,
+ interpolate3 join=operator --, triple axis=Z,
+ real angle1=0, real angle2=360) {
+ operator init(c,graph(new triple(real x) {return (x,0,f(x));},a,b,n,
+ join),axis,angle1,angle2);
+ }
+
+ revolution copy() {
+ return revolution(c,g,axis,angle1,angle2);
+ }
+
+ triple vertex(int i, real j) {
+ triple v=point(g,i);
+ triple center=c+dot(v-c,axis)*axis;
+ triple perp=v-center;
+ triple normal=cross(axis,perp);
+ return center+Cos(j)*perp+Sin(j)*normal;
+ }
+
+ // Construct the surface of rotation generated by rotating g
+ // from angle1 to angle2 sampled n times about the line c--c+axis.
+ // An optional surface pen color(int i, real j) may be specified
+ // to override the color at vertex(i,j).
+ surface surface(int n=nslice, pen color(int i, real j)=null) {
+ return surface(c,g,axis,n,angle1,angle2,color);
+ }
+
+ path3 slice(real position, int n=nCircle) {
+ triple v=point(g,position);
+ triple center=c+dot(v-c,axis)*axis;
+ triple perp=v-center;
+ if(abs(perp) <= epsilon*max(abs(m),abs(M))) return center;
+ triple v1=center+rotate(angle1,axis)*perp;
+ triple v2=center+rotate(angle2,axis)*perp;
+ path3 p=Arc(center,v1,v2,axis,n);
+ return (angle2-angle1) % 360 == 0 ? p&cycle : p;
+ }
+
+ triple camera(projection P) {
+ triple camera=P.camera;
+ if(P.infinity) {
+ real s=abs(M-m)+abs(m-P.target);
+ camera=P.target+camerafactor*s*unit(P.vector());
+ }
+ return camera;
+ }
+
+ // add transverse slice to skeleton s;
+ // must be recomputed if camera is adjusted
+ void transverse(skeleton s, real t, int n=nslice,
+ projection P=currentprojection) {
+ skeleton.curve s=s.transverse;
+ path3 S=slice(t,n);
+ triple camera=camera(P);
+ int L=length(g);
+ real midtime=0.5*L;
+ real sign=sgn(dot(axis,camera-P.target))*sgn(dot(axis,dir(g,midtime)));
+ if(dot(M-m,axis) == 0 || (t <= epsilon && sign < 0) ||
+ (t >= L-epsilon && sign > 0))
+ s.front.push(S);
+ else {
+ path3 Sp=slice(t+epsilon,n);
+ path3 Sm=slice(t-epsilon,n);
+ path sp=project(Sp,P);
+ path sm=project(Sm,P);
+ real[] t1=tangent(sp,sm,true);
+ real[] t2=tangent(sp,sm,false);
+ if(t1.length > 1 && t2.length > 1) {
+ real t1=t1[0]/P.ninterpolate;
+ real t2=t2[0]/P.ninterpolate;
+ int len=length(S);
+ if(t2 < t1) {
+ real temp=t1;
+ t1=t2;
+ t2=temp;
+ }
+ path3 p1=subpath(S,t1,t2);
+ path3 p2=subpath(S,t2,len);
+ path3 P2=subpath(S,0,t1);
+ if(abs(midpoint(p1)-camera) <= abs(midpoint(p2)-camera)) {
+ s.front.push(p1);
+ if(cyclic(S))
+ s.back.push(p2 & P2);
+ else {
+ s.back.push(p2);
+ s.back.push(P2);
+ }
+ } else {
+ if(cyclic(S))
+ s.front.push(p2 & P2);
+ else {
+ s.front.push(p2);
+ s.front.push(P2);
+ }
+ s.back.push(p1);
+ }
+ } else {
+ if((t <= midtime && sign < 0) || (t >= midtime && sign > 0))
+ s.front.push(S);
+ else
+ s.back.push(S);
+ }
+ }
+ }
+
+ // add m evenly spaced transverse slices to skeleton s
+ void transverse(skeleton s, int m=0, int n=nslice,
+ projection P=currentprojection) {
+ if(m == 0) {
+ int N=size(g);
+ for(int i=0; i < N; ++i)
+ transverse(s,(real) i,n,P);
+ } else if(m == 1)
+ transverse(s,reltime(g,0.5),n,P);
+ else {
+ real factor=1/(m-1);
+ for(int i=0; i < m; ++i)
+ transverse(s,reltime(g,i*factor),n,P);
+ }
+ }
+
+ // return approximate silhouette based on m evenly spaced transverse slices;
+ // must be recomputed if camera is adjusted
+ path3[] silhouette(int m=64, projection P=currentprojection) {
+ if(is3D())
+ write("warning: silhouette routine is intended only for 2d projections");
+ path3 G,H;
+ int N=size(g);
+ int M=(m == 0) ? N : m;
+ real factor=m == 1 ? 0 : 1/(m-1);
+ int n=nslice;
+
+ real tfirst=-1;
+ real tlast;
+ for(int i=0; i < M; ++i) {
+ real t=(m == 0) ? i : reltime(g,i*factor);
+ path3 S=slice(t,n);
+ triple camera=camera(P);
+ path3 Sp=slice(t+epsilon,n);
+ path3 Sm=slice(t-epsilon,n);
+ path sp=project(Sp,P);
+ path sm=project(Sm,P);
+ real[] t1=tangent(sp,sm,true);
+ real[] t2=tangent(sp,sm,false);
+ if(t1.length > 1 && t2.length > 1) {
+ real t1=t1[0]/P.ninterpolate;
+ real t2=t2[0]/P.ninterpolate;
+ if(t1 != t2) {
+ G=G..point(S,t1);
+ H=point(S,t2)..H;
+ if(tfirst < 0) tfirst=t;
+ tlast=t;
+ }
+ }
+ }
+ int L=length(g);
+ real midtime=0.5*L;
+ triple camera=camera(P);
+ real sign=sgn(dot(axis,camera-P.target))*sgn(dot(axis,dir(g,midtime)));
+
+ skeleton sfirst;
+ transverse(sfirst,tfirst,n,P);
+ triple delta=this.M-this.m;
+ path3 cap;
+ if(dot(delta,axis) == 0 || (tfirst <= epsilon && sign < 0)) {
+ cap=sfirst.transverse.front[0];
+ } else {
+ if(sign > 0) {
+ if(sfirst.transverse.front.length > 0)
+ G=reverse(sfirst.transverse.front[0])..G;
+ } else {
+ if(sfirst.transverse.back.length > 0)
+ G=sfirst.transverse.back[0]..G;
+ }
+ }
+
+ skeleton slast;
+ transverse(slast,tlast,n,P);
+ if(dot(delta,axis) == 0 || (tlast >= L-epsilon && sign > 0)) {
+ cap=slast.transverse.front[0];
+ } else {
+ if(sign > 0) {
+ if(slast.transverse.back.length > 0)
+ H=reverse(slast.transverse.back[0])..H;
+ } else {
+ if(slast.transverse.front.length > 0)
+ H=slast.transverse.front[0]..H;
+ }
+ }
+
+ return size(cap) == 0 ? G^^H : G^^H^^cap;
+ }
+
+ // add longitudinal curves to skeleton;
+ // must be recomputed if camera is adjusted
+ void longitudinal(skeleton s, int n=nslice, projection P=currentprojection) {
+ real t, d=0;
+ // Find a point on g of maximal distance from the axis.
+ int N=size(g);
+ for(int i=0; i < N; ++i) {
+ triple v=point(g,i);
+ triple center=c+dot(v-c,axis)*axis;
+ real r=abs(v-center);
+ if(r > d) {
+ t=i;
+ d=r;
+ }
+ }
+ path3 S=slice(t,n);
+ path3 Sm=slice(t+epsilon,n);
+ path3 Sp=slice(t-epsilon,n);
+ path sp=project(Sp,P);
+ path sm=project(Sm,P);
+ real[] t1=tangent(sp,sm,true);
+ real[] t2=tangent(sp,sm,false);
+ transform3 T=transpose(align(axis));
+ real Longitude(triple v) {return longitude(T*(v-c),warn=false);}
+ real ref=Longitude(point(g,t));
+ real angle(real t) {return Longitude(point(S,t/P.ninterpolate))-ref;}
+ triple camera=camera(P);
+ void push(real[] T) {
+ if(T.length > 1) {
+ path3 p=rotate(angle(T[0]),c,c+axis)*g;
+ path3 p1=subpath(p,0,t);
+ path3 p2=subpath(p,t,length(p));
+ if(length(p1) > 0 &&
+ abs(midpoint(p1)-camera) <= abs(midpoint(p2)-camera)) {
+ s.longitudinal.front.push(p1);
+ s.longitudinal.back.push(p2);
+ } else {
+ s.longitudinal.back.push(p1);
+ s.longitudinal.front.push(p2);
+ }
+ }
+ }
+ push(t1);
+ push(t2);
+ }
+
+ skeleton skeleton(int m=0, int n=nslice, projection P=currentprojection) {
+ skeleton s;
+ transverse(s,m,n,P);
+ longitudinal(s,n,P);
+ return s;
+ }
+}
+
+surface surface(revolution r, int n=nslice, pen color(int i, real j)=null)
+{
+ return r.surface(n,color);
+}
+
+// Draw on picture pic the skeleton of the surface of revolution r.
+// Draw the front portion of each of the m transverse slices with pen p and
+// the back portion with pen backpen. Rotational arcs are based on
+// n-point approximations to the unit circle.
+void draw(picture pic=currentpicture, revolution r, int m=0, int n=nslice,
+ pen frontpen=currentpen, pen backpen=frontpen,
+ pen longitudinalpen=frontpen, pen longitudinalbackpen=backpen,
+ light light=currentlight, projection P=currentprojection)
+{
+ pen thin=is3D() ? thin() : defaultpen;
+ skeleton s=r.skeleton(m,n,P);
+ begingroup3(pic);
+ if(frontpen != nullpen) {
+ draw(pic,s.transverse.back,thin+defaultbackpen+backpen,light);
+ draw(pic,s.transverse.front,thin+frontpen,light);
+ }
+ if(longitudinalpen != nullpen) {
+ draw(pic,s.longitudinal.back,thin+defaultbackpen+longitudinalbackpen,light);
+ draw(pic,s.longitudinal.front,thin+longitudinalpen,light);
+ }
+ endgroup3(pic);
+}
+
+revolution operator * (transform3 t, revolution r)
+{
+ triple trc=t*r.c;
+ return revolution(trc,t*r.g,t*(r.c+r.axis)-trc,r.angle1,r.angle2);
+}
+
+// Return a right circular cylinder of height h in the direction of axis
+// based on a circle centered at c with radius r.
+revolution cylinder(triple c=O, real r, real h, triple axis=Z)
+{
+ triple C=c+r*perp(axis);
+ axis=h*unit(axis);
+ return revolution(c,C--C+axis,axis);
+}
+
+// Return a right circular cone of height h in the direction of axis
+// based on a circle centered at c with radius r. The parameter n
+// controls the accuracy near the degenerate point at the apex.
+revolution cone(triple c=O, real r, real h, triple axis=Z, int n=nslice)
+{
+ axis=unit(axis);
+ return revolution(c,approach(c+r*perp(axis)--c+h*axis,n),axis);
+}
+
+// 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.
+revolution sphere(triple c=O, real r, int n=nslice)
+{
+ return revolution(c,Arc(c,r,180,0,0,0,Y,n),Z);
+}
diff --git a/Build/source/utils/asymptote/base/splinetype.asy b/Build/source/utils/asymptote/base/splinetype.asy
new file mode 100644
index 00000000000..366f91ac370
--- /dev/null
+++ b/Build/source/utils/asymptote/base/splinetype.asy
@@ -0,0 +1,238 @@
+typedef real[] splinetype(real[], real[]);
+
+restricted real[] defaultspline(real[] x, real[] y);
+restricted real[] Spline(real[] x, real[] y);
+
+string morepoints="interpolation requires at least 2 points";
+string differentlengths="arrays have different lengths";
+void checklengths(int x, int y, string text=differentlengths)
+{
+ if(x != y)
+ abort(text+": "+string(x)+" != "+string(y));
+}
+
+// Standard cubic spline interpolation with not-a-knot condition:
+// s'''(x_2^-)=s'''(x_2^+) et s'''(x_(n_2)^-)=s'''(x_(n-2)^+)
+// if n=2, linear interpolation is returned
+// if n=3, an interpolation polynomial of degree <= 2 is returned:
+// p(x_1)=y_1, p(x_2)=y_2, p(x_3)=y_3
+real[] notaknot(real[] x, real[] y)
+{
+ int n=x.length;
+ checklengths(n,y.length);
+ real[] d;
+ if(n > 3) {
+ real[] a=new real[n];
+ real[] b=new real[n];
+ real[] c=new real[n];
+ real[] g=new real[n];
+ b[0]=x[2]-x[1];
+ c[0]=x[2]-x[0];
+ a[0]=0;
+ g[0]=((x[1]-x[0])^2*(y[2]-y[1])/b[0]+b[0]*(2*b[0]+3*(x[1]-x[0]))*
+ (y[1]-y[0])/(x[1]-x[0]))/c[0];
+ for(int i=1; i < n-1; ++i) {
+ a[i]=x[i+1]-x[i];
+ c[i]=x[i]-x[i-1];
+ b[i]=2*(a[i]+c[i]);
+ g[i]=3*(c[i]*(y[i+1]-y[i])/a[i]+a[i]*(y[i]-y[i-1])/c[i]);
+ }
+ c[n-1]=0;
+ b[n-1]=x[n-2]-x[n-3];
+ a[n-1]=x[n-1]-x[n-3];
+ g[n-1]=((x[n-1]-x[n-2])^2*(y[n-2]-y[n-3])/b[n-1]+
+ b[n-1]*(2*b[n-1]+3(x[n-1]-x[n-2]))*
+ (y[n-1]-y[n-2])/(x[n-1]-x[n-2]))/a[n-1];
+ d=tridiagonal(a,b,c,g);
+ } else if(n == 2) {
+ real val=(y[1]-y[0])/(x[1]-x[0]);
+ d=new real[] {val,val};
+ } else if(n == 3) {
+ real a=(y[1]-y[0])/(x[1]-x[0]);
+ real b=(y[2]-y[1])/(x[2]-x[1]);
+ real c=(b-a)/(x[2]-x[0]);
+ d=new real[] {a+c*(x[0]-x[1]),a+c*(x[1]-x[0]),a+c*(2*x[2]-x[0]-x[1])};
+ } else abort(morepoints);
+ return d;
+}
+
+// Standard cubic spline interpolation with periodic condition
+// s'(a)=s'(b), s''(a)=s''(b), assuming that f(a)=f(b)
+// if n=2, linear interpolation is returned
+real[] periodic(real[] x, real[] y)
+{
+ int n=x.length;
+ checklengths(n,y.length);
+ if(y[n-1] != y[0]) abort("function values are not periodic");
+ real[] d;
+ if(n > 2) {
+ real[] a=new real[n-1];
+ real[] b=new real[n-1];
+ real[] c=new real[n-1];
+ real[] g=new real[n-1];
+ c[0]=x[n-1]-x[n-2];
+ a[0]=x[1]-x[0];
+ b[0]=2*(a[0]+c[0]);
+ g[0]=3*c[0]*(y[1]-y[0])/a[0]+3*a[0]*(y[n-1]-y[n-2])/c[0];
+ for(int i=1; i < n-1; ++i) {
+ a[i]=x[i+1]-x[i];
+ c[i]=x[i]-x[i-1];
+ b[i]=2*(a[i]+c[i]);
+ g[i]=3*(c[i]*(y[i+1]-y[i])/a[i]+a[i]*(y[i]-y[i-1])/c[i]);
+ }
+ d=tridiagonal(a,b,c,g);
+ d.push(d[0]);
+ } else if(n == 2) {
+ d=new real[] {0,0};
+ } else abort(morepoints);
+ return d;
+}
+
+// Standard cubic spline interpolation with the natural condition
+// s''(a)=s''(b)=0.
+// if n=2, linear interpolation is returned
+// Don't use the natural type unless the underlying function
+// has zero second end points derivatives.
+real[] natural(real[] x, real[] y)
+{
+ int n=x.length;
+ checklengths(n,y.length);
+ real[] d;
+ if(n > 2) {
+ real[] a=new real[n];
+ real[] b=new real[n];
+ real[] c=new real[n];
+ real[] g=new real[n];
+ b[0]=2*(x[1]-x[0]);
+ c[0]=x[1]-x[0];
+ a[0]=0;
+ g[0]=3*(y[1]-y[0]);
+ for(int i=1; i < n-1; ++i) {
+ a[i]=x[i+1]-x[i];
+ c[i]=x[i]-x[i-1];
+ b[i]=2*(a[i]+c[i]);
+ g[i]=3*(c[i]*(y[i+1]-y[i])/a[i]+a[i]*(y[i]-y[i-1])/c[i]);
+ }
+ c[n-1]=0;
+ a[n-1]=x[n-1]-x[n-2];
+ b[n-1]=2*a[n-1];
+ g[n-1]=3*(y[n-1]-y[n-2]);
+ d=tridiagonal(a,b,c,g);
+ } else if(n == 2) {
+ real val=(y[1]-y[0])/(x[1]-x[0]);
+ d=new real[] {val,val};
+ } else abort(morepoints);
+ return d;
+}
+
+// Standard cubic spline interpolation with clamped conditions f'(a), f'(b)
+splinetype clamped(real slopea, real slopeb)
+{
+ return new real[] (real[] x, real[] y) {
+ int n=x.length;
+ checklengths(n,y.length);
+ real[] d;
+ if(n > 2) {
+ real[] a=new real[n];
+ real[] b=new real[n];
+ real[] c=new real[n];
+ real[] g=new real[n];
+ b[0]=x[1]-x[0];
+ g[0]=b[0]*slopea;
+ c[0]=0;
+ a[0]=0;
+ for(int i=1; i < n-1; ++i) {
+ a[i]=x[i+1]-x[i];
+ c[i]=x[i]-x[i-1];
+ b[i]=2*(a[i]+c[i]);
+ g[i]=3*(c[i]*(y[i+1]-y[i])/a[i]+a[i]*(y[i]-y[i-1])/c[i]);
+ }
+ c[n-1]=0;
+ a[n-1]=0;
+ b[n-1]=x[n-1]-x[n-2];
+ g[n-1]=b[n-1]*slopeb;
+ d=tridiagonal(a,b,c,g);
+ } else if(n == 2) {
+ d=new real[] {slopea,slopeb};
+ } else abort(morepoints);
+ return d;
+ };
+}
+
+// Piecewise Cubic Hermite Interpolating Polynomial (PCHIP)
+// Modified MATLAB code
+// [1] Fritsch, F. N. and R. E. Carlson,
+// "Monotone Piecewise Cubic Interpolation,"
+// SIAM J. Numerical Analysis, Vol. 17, 1980, pp.238-246.
+// [2] Kahaner, David, Cleve Moler, Stephen Nash,
+// Numerical Methods and Software, Prentice Hall, 1988.
+real[] monotonic(real[] x, real[] y)
+{
+ int n=x.length;
+ checklengths(n,y.length);
+ real[] d=new real[n];
+ if(n > 2) {
+ real[] h=new real[n-1];
+ real[] del=new real[n-1];
+ for(int i=0; i < n-1; ++i) {
+ h[i]=x[i+1]-x[i];
+ del[i]=(y[i+1]-y[i])/h[i];
+ }
+ int j=0;
+ int k[]=new int[];
+ for(int i=0; i < n-2; ++i)
+ if((sgn(del[i])*sgn(del[i+1])) > 0) {k[j]=i; j=j+1;}
+
+ real[] hs=new real[j];
+ for(int i=0; i < j; ++i) hs[i]=h[k[i]]+h[k[i]+1];
+ real w1[]=new real[j];
+ real w2[]=new real[j];
+ real dmax[]=new real[j];
+ real dmin[]=new real[j];
+ for(int i=0; i < j; ++i) {
+ w1[i]=(h[k[i]]+hs[i])/(3*hs[i]);
+ w2[i]=(h[k[i]+1]+hs[i])/(3*hs[i]);
+ dmax[i]=max(abs(del[k[i]]),abs(del[k[i]+1]));
+ dmin[i]=min(abs(del[k[i]]),abs(del[k[i]+1]));
+ }
+ for(int i=0; i < n; ++i) d[i]=0;
+ for(int i=0; i < j; ++i)
+ d[k[i]+1]=dmin[i]/(w1[i]*(del[k[i]]/dmax[i])+w2[i]*(del[k[i]+1]/dmax[i]));
+ d[0]=((2*h[0]+h[1])*del[0]-h[0]*del[1])/(h[0]+h[1]);
+ if(sgn(d[0]) != sgn(del[0])) {d[0]=0;}
+ else if((sgn(del[0]) != sgn(del[1])) && (abs(d[0]) > abs(3*del[0])))
+ d[0]=3*del[0];
+
+ d[n-1]=((2*h[n-2]+h[n-3])*del[n-2]-h[n-2]*del[n-2])/(h[n-2]+h[n-3]);
+ if(sgn(d[n-1]) != sgn(del[n-2])) {d[n-1]=0;}
+ else if((sgn(del[n-2]) != sgn(del[n-3])) &&
+ (abs(d[n-1]) > abs(3*del[n-2])))
+ d[n-1]=3*del[n-2];
+ } else if(n == 2) {
+ d[0]=d[1]=(y[1]-y[0])/(x[1]-x[0]);
+ } else abort(morepoints);
+ return d;
+}
+
+// Return standard cubic spline interpolation as a guide
+guide hermite(real[] x, real[] y, splinetype splinetype=null)
+{
+ int n=x.length;
+ if(n == 0) return nullpath;
+
+ guide g=(x[0],y[0]);
+ if(n == 1) return g;
+ if(n == 2) return g--(x[1],y[1]);
+
+ if(splinetype == null)
+ splinetype=(x[0] == x[x.length-1] && y[0] == y[y.length-1]) ?
+ periodic : notaknot;
+
+ real[] dy=splinetype(x,y);
+ for(int i=1; i < n; ++i) {
+ pair z=(x[i],y[i]);
+ real dx=x[i]-x[i-1];
+ g=g..controls((x[i-1],y[i-1])+dx*(1,dy[i-1])/3) and (z-dx*(1,dy[i])/3)..z;
+ }
+ return g;
+}
diff --git a/Build/source/utils/asymptote/base/stats.asy b/Build/source/utils/asymptote/base/stats.asy
new file mode 100644
index 00000000000..be9efdfa429
--- /dev/null
+++ b/Build/source/utils/asymptote/base/stats.asy
@@ -0,0 +1,292 @@
+private import graph;
+
+real legendmarkersize=2mm;
+
+real mean(real A[])
+{
+ return sum(A)/A.length;
+}
+
+// unbiased estimate
+real variance(real A[])
+{
+ return sum((A-mean(A))^2)/(A.length-1);
+}
+
+real variancebiased(real A[])
+{
+ return sum((A-mean(A))^2)/A.length;
+}
+
+// unbiased estimate
+real stdev(real A[])
+{
+ return sqrt(variance(A));
+}
+
+real rms(real A[])
+{
+ return sqrt(sum(A^2)/A.length);
+}
+
+real skewness(real A[])
+{
+ real[] diff=A-mean(A);
+ return sum(diff^3)/sqrt(sum(diff^2)^3/A.length);
+}
+
+real kurtosis(real A[])
+{
+ real[] diff=A-mean(A);
+ return sum(diff^4)/sum(diff^2)^2*A.length;
+}
+
+real kurtosisexcess(real A[])
+{
+ return kurtosis(A)-3;
+}
+
+real Gaussian(real x, real sigma)
+{
+ static real sqrt2pi=sqrt(2pi);
+ return exp(-0.5*(x/sigma)^2)/(sigma*sqrt2pi);
+}
+
+real Gaussian(real x)
+{
+ static real invsqrt2pi=1/sqrt(2pi);
+ return exp(-0.5*x^2)*invsqrt2pi;
+}
+
+// Return frequency count of data in [bins[i],bins[i+1]) for i=0,...,n-1.
+int[] frequency(real[] data, real[] bins)
+{
+ int n=bins.length-1;
+ int[] freq=new int[n];
+ for(int i=0; i < n; ++i)
+ freq[i]=sum(bins[i] <= data & data < bins[i+1]);
+ return freq;
+}
+
+// Return frequency count in n uniform bins from a to b
+// (faster than the above more general algorithm).
+int[] frequency(real[] data, real a, real b, int n)
+{
+ int[] freq=sequence(new int(int x) {return 0;},n);
+ real h=n/(b-a);
+ for(int i=0; i < data.length; ++i) {
+ int I=Floor((data[i]-a)*h);
+ if(I >= 0 && I < n)
+ ++freq[I];
+ }
+ return freq;
+}
+
+// Return frequency count in [xbins[i],xbins[i+1]) and [ybins[j],ybins[j+1]).
+int[][] frequency(real[] x, real[] y, real[] xbins, real[] ybins)
+{
+ int n=xbins.length-1;
+ int m=ybins.length-1;
+ int[][] freq=new int[n][m];
+ bool[][] inybin=new bool[m][y.length];
+ for(int j=0; j < m; ++j)
+ inybin[j]=ybins[j] <= y & y < ybins[j+1];
+ for(int i=0; i < n; ++i) {
+ bool[] inxbini=xbins[i] <= x & x < xbins[i+1];
+ int[] freqi=freq[i];
+ for(int j=0; j < m; ++j)
+ freqi[j]=sum(inxbini & inybin[j]);
+ }
+ return freq;
+}
+
+// Return frequency count in nx by ny uniform bins in box(a,b).
+int[][] frequency(real[] x, real[] y, pair a, pair b, int nx, int ny=nx)
+{
+ int[][] freq=new int[nx][];
+ for(int i=0; i < nx; ++i)
+ freq[i]=sequence(new int(int x) {return 0;},ny);
+ real hx=nx/(b.x-a.x);
+ real hy=ny/(b.y-a.y);
+ real ax=a.x;
+ real ay=a.y;
+ for(int i=0; i < x.length; ++i) {
+ int I=Floor((x[i]-ax)*hx);
+ int J=Floor((y[i]-ay)*hy);
+ if(I >= 0 && I <= nx && J >= 0 && J <= ny)
+ ++freq[I][J];
+ }
+ return freq;
+}
+
+int[][] frequency(pair[] z, pair a, pair b, int nx, int ny=nx)
+{
+ int[][] freq=new int[nx][];
+ for(int i=0; i < nx; ++i)
+ freq[i]=sequence(new int(int x) {return 0;},ny);
+ real hx=nx/(b.x-a.x);
+ real hy=ny/(b.y-a.y);
+ real ax=a.x;
+ real ay=a.y;
+ for(int i=0; i < z.length; ++i) {
+ int I=Floor((z[i].x-ax)*hx);
+ int J=Floor((z[i].y-ay)*hy);
+ if(I >= 0 && I < nx && J >= 0 && J < ny)
+ ++freq[I][J];
+ }
+ return freq;
+}
+
+path halfbox(pair a, pair b)
+{
+ return a--(a.x,b.y)--b;
+}
+
+path topbox(pair a, pair b)
+{
+ return a--(a.x,b.y)--b--(b.x,a.y);
+}
+
+// Draw a histogram for bin boundaries bin[n+1] of frequency data in count[n].
+void histogram(picture pic=currentpicture, real[] bins, real[] count,
+ real low=-infinity,
+ pen fillpen=nullpen, pen drawpen=nullpen, bool bars=false,
+ Label legend="", real markersize=legendmarkersize)
+{
+ if((fillpen == nullpen || bars == true) && drawpen == nullpen)
+ drawpen=currentpen;
+ bool[] valid=count > 0;
+ real m=min(valid ? count : null);
+ real M=max(valid ? count : null);
+ bounds my=autoscale(pic.scale.y.scale.T(m),pic.scale.y.T(M),
+ pic.scale.y.scale);
+ if(low == -infinity) low=pic.scale.y.scale.Tinv(my.min);
+ real last=low;
+ int n=count.length;
+ begingroup(pic);
+ for(int i=0; i < n; ++i) {
+ if(valid[i]) {
+ real c=count[i];
+ pair b=Scale(pic,(bins[i+1],c));
+ pair a=Scale(pic,(bins[i],low));
+ if(fillpen != nullpen) {
+ fill(pic,box(a,b),fillpen);
+ if(!bars) draw(pic,b--(b.x,a.y),fillpen);
+ }
+ if(!bars)
+ draw(pic,halfbox(Scale(pic,(bins[i],last)),b),drawpen);
+ else draw(pic,topbox(a,b),drawpen);
+ last=c;
+ } else {
+ if(!bars && last != low) {
+ draw(pic,Scale(pic,(bins[i],last))--Scale(pic,(bins[i],low)),drawpen);
+ last=low;
+ }
+ }
+ }
+ if(!bars && last != low)
+ draw(pic,Scale(pic,(bins[n],last))--Scale(pic,(bins[n],low)),drawpen);
+ endgroup(pic);
+
+ if(legend.s != "") {
+ marker m=marker(scale(markersize)*shift((-0.5,-0.5))*unitsquare,
+ drawpen,fillpen == nullpen ? Draw :
+ (drawpen == nullpen ? Fill(fillpen) : FillDraw(fillpen)));
+ legend.p(drawpen);
+ pic.legend.push(Legend(legend.s,legend.p,invisible,m.f));
+ }
+}
+
+// Draw a histogram for data in n uniform bins between a and b
+// (optionally normalized).
+void histogram(picture pic=currentpicture, real[] data, real a, real b, int n,
+ bool normalize=false, real low=-infinity,
+ pen fillpen=nullpen, pen drawpen=nullpen, bool bars=false,
+ Label legend="", real markersize=legendmarkersize)
+{
+ real dx=(b-a)/n;
+ real[] freq=frequency(data,a,b,n);
+ if(normalize) freq /= dx*sum(freq);
+ histogram(pic,a+sequence(n+1)*dx,freq,low,fillpen,drawpen,bars,legend,
+ markersize);
+}
+
+// Method of Shimazaki and Shinomoto for selecting the optimal number of bins.
+// Shimazaki H. and Shinomoto S., A method for selecting the bin size of a
+// time histogram, Neural Computation (2007), Vol. 19(6), 1503-1527.
+// cf. http://www.ton.scphys.kyoto-u.ac.jp/~hideaki/res/histogram.html
+int bins(real[] data, int max=100)
+{
+ real m=min(data);
+ real M=max(data)*(1+epsilon);
+ real n=data.length;
+ int bins=1;
+ real minC=2n-n^2; // Cost function for N=1.
+ for(int N=2; N <= max; ++N) {
+ real C=N*(2n-sum(frequency(data,m,M,N)^2));
+ if(C < minC) {
+ minC=C;
+ bins=N;
+ }
+ }
+
+ return bins;
+}
+
+// return a pair of central Gaussian random numbers with unit variance
+pair Gaussrandpair()
+{
+ real r2,v1,v2;
+ do {
+ v1=2.0*unitrand()-1.0;
+ v2=2.0*unitrand()-1.0;
+ r2=v1*v1+v2*v2;
+ } while(r2 >= 1.0 || r2 == 0.0);
+ return (v1,v2)*sqrt(-log(r2)/r2);
+}
+
+// return a central Gaussian random number with unit variance
+real Gaussrand()
+{
+ static real sqrt2=sqrt(2.0);
+ static pair z;
+ static bool cached=true;
+ cached=!cached;
+ if(cached) return sqrt2*z.y;
+ z=Gaussrandpair();
+ return sqrt2*z.x;
+}
+
+struct linefit {
+ real m,b; // slope, intercept
+ real dm,db; // standard error in slope, intercept
+ real r; // correlation coefficient
+ real fit(real x) {
+ return m*x+b;
+ }
+}
+
+// Do a least-squares fit of data in real arrays x and y to the line y=m*x+b
+linefit leastsquares(real[] x, real[] y)
+{
+ linefit L;
+ int n=x.length;
+ if(n == 1) abort("Least squares fit requires at least 2 data points");
+ real sx=sum(x);
+ real sy=sum(y);
+ real sxx=n*sum(x^2)-sx^2;
+ real sxy=n*sum(x*y)-sx*sy;
+ L.m=sxy/sxx;
+ L.b=(sy-L.m*sx)/n;
+ if(n > 2) {
+ real syy=n*sum(y^2)-sy^2;
+ if(sxx == 0 || syy == 0) return L;
+ L.r=sxy/sqrt(sxx*syy);
+ real arg=syy-sxy^2/sxx;
+ if(arg <= 0) return L;
+ real s=sqrt(arg/(n-2));
+ L.dm=s*sqrt(1/sxx);
+ L.db=s*sqrt(1+sx^2/sxx)/n;
+ }
+ return L;
+}
diff --git a/Build/source/utils/asymptote/base/syzygy.asy b/Build/source/utils/asymptote/base/syzygy.asy
new file mode 100644
index 00000000000..dce87805c9d
--- /dev/null
+++ b/Build/source/utils/asymptote/base/syzygy.asy
@@ -0,0 +1,936 @@
+/***** syzygy.asy {{{1
+ * Andy Hammerlindl 2006/12/02
+ *
+ * Automates the drawing of braids, relations, and syzygies, along with the
+ * corresponding equations.
+ *
+ * See
+ * http://katlas.math.toronto.edu/drorbn/index.php?title=06-1350/Syzygies_in_Asymptote
+ * For more information.
+ *****/
+struct Component { // {{{1
+ // The number of strings coming in or out of the component.
+ int in;
+ int out;
+
+ // Which 'out' string each 'in' string is connected to. For deriving
+ // equations.
+ int[] connections;
+
+ string symbol; // For pullback notation.
+ string lsym; // For linear equations.
+ string codename; // For Mathematica code.
+
+ guide[] draw(picture pic, guide[] ins);
+}
+
+// Utility functions {{{1
+pair[] endpoints(guide[] a) {
+ pair[] z;
+ for (int i=0; i<a.length; ++i)
+ z.push(endpoint(a[i]));
+ return z;
+}
+
+pair min(pair[] z) {
+ pair m=(infinity, infinity);
+ for (int i=0; i<z.length; ++i) {
+ if (z[i].x < m.x)
+ m=(z[i].x,m.y);
+ if (z[i].y < m.y)
+ m=(m.x,z[i].y);
+ }
+ return m;
+}
+
+pair max(pair[] z) {
+ pair M=(-infinity, -infinity);
+ for (int i=0; i<z.length; ++i) {
+ if (z[i].x > M.x)
+ M=(z[i].x,M.y);
+ if (z[i].y > M.y)
+ M=(M.x,z[i].y);
+ }
+ return M;
+}
+
+// Component Definitions {{{1
+real hwratio=1.4;
+real gapfactor=6;
+
+Component bp=new Component;
+bp.in=2; bp.out=2;
+bp.connections=new int[] {1,0};
+bp.symbol="B^+"; bp.lsym="b^+"; bp.codename="bp";
+bp.draw=new guide[] (picture pic, guide[] ins) {
+ pair[] z=endpoints(ins);
+ pair m=min(z), M=max(z);
+ real w=M.x-m.x, h=hwratio*w;
+ pair centre=(0.5(m.x+M.x),M.y+h/2);
+
+ /*
+ return new guide[] {ins[1]..centre{NW}..z[0]+h*N,
+ ins[0]..centre{NE}..z[1]+h*N};
+ */
+
+ real offset=gapfactor*linewidth(currentpen);
+ draw(pic, ins[1]..(centre-offset*NW){NW});
+ return new guide[] {(centre+offset*NW){NW}..z[0]+h*N,
+ ins[0]..centre{NE}..z[1]+h*N};
+};
+
+Component bm=new Component;
+bm.in=2; bm.out=2;
+bm.connections=new int[] {1,0};
+bm.symbol="B^-"; bm.lsym="b^-"; bm.codename="bm";
+bm.draw=new guide[] (picture pic, guide[] ins) {
+ pair[] z=endpoints(ins);
+ pair m=min(z), M=max(z);
+ real w=M.x-m.x, h=hwratio*w;
+ pair centre=(0.5(m.x+M.x),M.y+h/2);
+
+ /*
+ return new guide[] {ins[1]..centre{NW}..z[0]+h*N,
+ ins[0]..centre{NE}..z[1]+h*N};
+ */
+
+ real offset=gapfactor*linewidth(currentpen);
+ draw(pic, ins[0]..(centre-offset*NE){NE});
+ return new guide[] {ins[1]..centre{NW}..z[0]+h*N,
+ (centre+offset*NE){NE}..z[1]+h*N};
+};
+
+Component phi=new Component;
+phi.in=2; phi.out=1;
+phi.connections=new int[] {0,0};
+phi.symbol="\Phi"; phi.lsym="\phi"; phi.codename="phi";
+phi.draw=new guide[] (picture pic, guide[] ins) {
+ pair[] z=endpoints(ins);
+ pair m=min(z), M=max(z);
+ real w=M.x-m.x, h=hwratio*w;
+ pair centre=(0.5(m.x+M.x),M.y+h/2);
+
+
+ //real offset=4*linewidth(currentpen);
+ draw(pic, ins[0]..centre{NE});
+ draw(pic, ins[1]..centre{NW});
+ draw(pic, centre,linewidth(5*linewidth(currentpen)));
+ dot(pic, centre);
+ return new guide[] {centre..centre+0.5h*N};
+};
+
+Component wye=new Component;
+wye.in=1; wye.out=2;
+wye.connections=null; // TODO: Fix this!
+wye.symbol="Y"; wye.lsym="y"; wye.codename="wye";
+wye.draw=new guide[] (picture pic, guide[] ins) {
+ pair z=endpoint(ins[0]);
+ real w=10, h=hwratio*w; // The 10 is a guess here, and may produce badness.
+ pair centre=(z.x,z.y+h/2);
+
+
+ draw(pic, ins[0]..centre);
+ draw(pic, centre,linewidth(5*linewidth(currentpen)));
+ return new guide[] {centre{NW}..centre+(-0.5w,0.5h),
+ centre{NE}..centre+(0.5w,0.5h)};
+};
+
+
+struct Braid { // {{{1
+ // Members {{{2
+ // Number of lines initially.
+ int n;
+
+ struct Placement {
+ Component c;
+ int place;
+
+ Placement copy() {
+ Placement p=new Placement;
+ p.c=this.c; p.place=this.place;
+ return p;
+ }
+ }
+ Placement[] places;
+
+ void add(Component c, int place) {
+ Placement p=new Placement;
+ p.c=c; p.place=place;
+ places.push(p);
+ }
+
+ void add(Braid sub, int place) {
+ for (int i=0; i<sub.places.length; ++i)
+ add(sub.places[i].c,sub.places[i].place+place);
+ }
+
+ // Drawing {{{2
+ guide[] drawStep(picture pic, Placement p, guide[] ins) {
+ int i=0,j=0;
+
+ // Draw the component.
+ Component c=p.c;
+ //write("drawing "+c.symbol+" at place "+(string)p.place);
+ guide[] couts=c.draw(pic, ins[sequence(c.in)+p.place]);
+
+ pair M=max(endpoints(couts));
+
+ // Extend lines not in the component.
+ guide[] outs;
+ pair[] z=endpoints(ins);
+ while (i<p.place) {
+ outs.push(ins[i]..(z[i].x,M.y));
+ ++i;
+ }
+
+ outs.append(couts);
+ i+=c.in;
+
+ while (i<ins.length) {
+ outs.push(ins[i]..(z[i].x,M.y));
+ ++i;
+ }
+
+ return outs;
+ }
+
+ void drawEnd(picture pic, guide[] ins, real minheight=0) {
+ pair[] z=endpoints(ins);
+ for (int i=0; i<ins.length; ++i) {
+ draw(pic, z[i].y >= minheight ? ins[i] : ins[i]..(z[i].x,minheight));
+ }
+ }
+
+ void draw(picture pic, guide[] ins, real minheight=0) {
+ int steps=places.length;
+
+ guide[] nodes=ins;
+ for (int i=0; i<steps; ++i) {
+ Placement p=places[i];
+ nodes=drawStep(pic, places[i], nodes);
+ }
+
+ drawEnd(pic, nodes, minheight);
+ }
+
+ void draw(picture pic=currentpicture, real spacing=15,
+ real minheight=2hwratio*spacing) {
+ pair[] ins;
+ for (int i=0; i<n; ++i)
+ ins.push((spacing*i,0));
+
+ draw(pic, ins, minheight);
+ }
+
+ // Utilities {{{2
+ int in() {
+ return n;
+ }
+ int out() {
+ int steps=places.length;
+ int num=n; // The number of nodes at this step.
+
+ for (int i=0; i<steps; ++i) {
+ Placement p=places[i];
+ int nextNum=num-p.c.in+p.c.out;
+ num=nextNum;
+ }
+ return num;
+ }
+
+ // Deep copy of a braid.
+ Braid copy() {
+ Braid b=new Braid;
+ b.n=this.n;
+ for (int i=0; i<this.places.length; ++i)
+ b.add(this.places[i].c,this.places[i].place);
+ return b;
+ }
+
+ // Matching {{{2
+ // Tests if a component p can be swapped with a component q which is assumed
+ // to be directly above it.
+ static bool swapable(Placement p, Placement q) {
+ return p.place + p.c.out <= q.place || // p is left of q or
+ q.place + q.c.in <= p.place; // q is left of p
+ }
+
+ // Creates a new braid with a transposition of two components.
+ Braid swap(int i, int j) {
+ if (i>j)
+ return swap(j,i);
+ else {
+ assert(j==i+1); assert(swapable(places[i],places[j]));
+
+ Placement p=places[i].copy();
+ Placement q=places[j].copy();
+ /*write("swap:");
+ write("p originally at " + (string)p.place);
+ write("q originally at " + (string)q.place);
+ write("p.c.in: " + (string)p.c.in + " p.c.out: " + (string)p.c.out);
+ write("q.c.in: " + (string)q.c.in + " q.c.out: " + (string)q.c.out);*/
+ if (q.place + q.c.in <= p.place)
+ // q is left of p - adjust for q renumbering strings.
+ p.place+=q.c.out-q.c.in;
+ else if (p.place + p.c.out <= q.place)
+ // q is right of p - adjust for p renumbering strings.
+ q.place+=p.c.in-p.c.out;
+ else
+ // q is directly on top of p
+ assert(false, "swapable");
+
+ /*write("q now at " + (string)q.place);
+ write("p now at " + (string)p.place);*/
+
+ Braid b=this.copy();
+ b.places[i]=q;
+ b.places[j]=p;
+ return b;
+ }
+ }
+
+ // Tests if the component at index 'start' can be moved to index 'end'
+ // without interfering with other components.
+ bool moveable(int start, int end) {
+ assert(start<places.length); assert(end<places.length);
+ if (start==end)
+ return true;
+ else if (end<start)
+ return moveable(end,start);
+ else {
+ assert(start<end);
+ Placement p=places[start].copy();
+ for (int step=start; step<end; ++step) {
+ Placement q=places[step+1];
+ if (q.place + q.c.in <= p.place)
+ // q is left of p - adjust for q renumbering strings.
+ p.place+=q.c.out-q.c.in;
+ else if (p.place + p.c.out <= q.place)
+ // q is right of p - nothing to do.
+ continue;
+ else
+ // q is directly on top of p
+ return false;
+ }
+ return true;
+ }
+ }
+
+ bool matchComponent(Braid sub, int subindex, int place, int step) {
+ int i=subindex;
+ return sub.places[i].c == this.places[step].c &&
+ sub.places[i].place + place == this.places[step].place;
+ }
+
+ // Returns true if a sub-braid occurs within the one at the specified
+ // coordinates with no component occuring anywhere inbetween.
+ bool exactMatch(Braid sub, int place, int step) {
+ for (int i=0; i<sub.places.length; ++i) {
+ if (!matchComponent(sub, i, place, i+step)) {
+ write("match failed at iteration: ", i);
+ return false;
+ }
+ }
+ return true;
+ }
+
+ /*
+ bool findSubsequence(Braid sub, int place, int size, int[] acc) {
+ // If we've matched all the components, we've won.
+ if (acc.length >= sub.places.length)
+ return true;
+
+ // The next component to match.
+ Placement p=sub.places[acc.length];
+
+ // Start looking immediately after the last match.
+ for (int step=acc[acc.length-1]+1; step<this.places.length; ++step) {
+ Placement q=this.places[step];
+ */
+
+ bool tryMatch(Braid sub, int place, int size, int[] acc) {
+ // If we've matched all the components, we've won.
+ if (acc.length >= sub.places.length)
+ return true;
+
+ // The next component to match.
+ Placement p=sub.places[acc.length];
+
+ // Start looking immediately after the last match.
+ for (int step=acc[acc.length-1]+1; step<this.places.length; ++step) {
+ Placement q=this.places[step];
+ // Check if the next component is in the set of strings used by the
+ // subbraid.
+ if (q.place + q.c.in > place && q.place < place + size) {
+ // It's in the window, so it must match the next component in the
+ // subbraid.
+ if (p.c==q.c && p.place+place==q.place) {
+ // A match - go on to the next component.
+ acc.push(step);
+ return tryMatch(sub, place, size, acc); // TODO: Adjust place/size.
+ }
+ else
+ return false;
+ }
+
+ // TODO: Adjust place and size.
+ }
+
+ // We've run out of components to match.
+ return false;
+ }
+
+
+ // This attempts to find a subbraid within the braid. It allows other
+ // components to be interspersed with the components of the subbraid so long
+ // as they don't occur on the same string as the ones the subbraid lies on.
+ // Returns null on failure.
+ int[] match(Braid sub, int place) {
+ for (int i=0; i<=this.places.length-sub.places.length; ++i) {
+ // Find where the first component of the subbraid matches and try to
+ // match the rest of the braid starting from there.
+ if (matchComponent(sub, 0, place, i)) {
+ int[] result;
+ result.push(i);
+ if (tryMatch(sub,place,sub.n,result))
+ return result;
+ }
+ }
+ return null;
+ }
+
+ // Equations {{{2
+ // Returns the string that 'place' moves to when going through the section
+ // with Placement p.
+ static int advancePast(Placement p, int place) {
+ // If it's to the left of the component, it is unaffected.
+ return place<p.place ? place :
+ // If it's to the right of the component, adjust the numbering due
+ // to the change of the number of strings in the component.
+ p.place+p.c.in <= place ? place - p.c.in + p.c.out :
+ // If it's in the component, ask the component to do the work.
+ p.place + p.c.connections[place-p.place];
+ }
+
+ // Adjust the place (at step 0) to the step given, to find which string it is
+ // on in that part of the diagram.
+ int advanceToStep(int step, int place) {
+ assert(place>=0 && place<n);
+ assert(step>=0 && step<places.length);
+
+ for (int i=0; i<step; ++i)
+ place=advancePast(places[i], place);
+
+ return place;
+ }
+
+ int pullbackWindowPlace(int step, int place,
+ int w_place, int w_size) {
+ place=advanceToStep(step,place);
+ return place < w_place ? 1 : // The shielding.
+ w_place + w_size <= place ? 0 : // The string doesn't touch it.
+ place-w_place+2;
+ }
+
+ int pullbackPlace(int step, int place) {
+ // Move to the right step.
+ //write("advance: ", step, place, advanceToStep(step,place));
+ //place=advanceToStep(step,place);
+ Placement p=places[step];
+ return pullbackWindowPlace(step,place, p.place, p.c.in);
+ /*return place < p.place ? 1 : // The shielding.
+ p.place + p.c.in <= place ? 0 : // The string doesn't touch it.
+ place-p.place+2;*/
+ }
+
+ int[] pullbackWindow(int step, int w_place, int w_size) {
+ int[] a={1};
+ for (int place=0; place<n; ++place)
+ a.push(pullbackWindowPlace(step, place, w_place, w_size));
+ return a;
+ }
+
+ int[] pullback(int step) {
+ Placement p=places[step];
+ return pullbackWindow(step, p.place, p.c.in);
+ /*int[] a={1};
+ for (int place=0; place<n; ++place)
+ a.push(pullbackPlace(step, place));
+ return a;*/
+ }
+
+ string stepToFormula(int step) {
+ // Determine the pullbacks.
+ string s="(1";
+ for (int place=0; place<n; ++place)
+ //write("pullback: ", step, place, pullbackString(step,place));
+ s+=(string)pullbackPlace(step, place);
+ s+=")^\star "+places[step].c.symbol;
+ return s;
+ }
+
+ // Write it as a formula with pullback notation.
+ string toFormula() {
+ if (places.length==0)
+ return "1";
+ else {
+ string s;
+ for (int step=0; step<places.length; ++step) {
+ if (step>0)
+ s+=" ";
+ s+=stepToFormula(step);
+ }
+ return s;
+ }
+ }
+
+ string windowToLinear(int step, int w_place, int w_size) {
+ int[] a=pullbackWindow(step, w_place, w_size);
+ string s="(";
+ for (int arg=1; arg<=w_size+1; ++arg) {
+ if (arg>1)
+ s+=",";
+ bool first=true;
+ for (int var=0; var<a.length; ++var) {
+ if (a[var]==arg) {
+ if (first)
+ first=false;
+ else
+ s+="+";
+ s+="x_"+(string)(var+1);
+ }
+ }
+ }
+ return s+")";
+ }
+
+ string windowToCode(int step, int w_place, int w_size) {
+ int[] a=pullbackWindow(step, w_place, w_size);
+ string s="[";
+ for (int arg=1; arg<=w_size+1; ++arg) {
+ if (arg>1)
+ s+=", ";
+ bool first=true;
+ for (int var=0; var<a.length; ++var) {
+ if (a[var]==arg) {
+ if (first)
+ first=false;
+ else
+ s+=" + ";
+ s+="x"+(string)(var+1);
+ }
+ }
+ }
+ return s+"]";
+ }
+
+ string stepToLinear(int step) {
+ //int[] a=pullback(step);
+ Placement p=places[step];
+ return p.c.lsym+windowToLinear(step, p.place, p.c.in);
+
+ /*string s=p.c.lsym+"(";
+ for (int arg=1; arg<=p.c.in+1; ++arg) {
+ if (arg>1)
+ s+=",";
+ bool first=true;
+ for (int var=0; var<a.length; ++var) {
+ if (a[var]==arg) {
+ if (first)
+ first=false;
+ else
+ s+="+";
+ s+="x_"+(string)(var+1);
+ }
+ }
+ }
+ return s+")";*/
+ }
+
+ string stepToCode(int step) {
+ Placement p=places[step];
+ return p.c.codename+windowToCode(step, p.place, p.c.in);
+ }
+
+ string toLinear(bool subtract=false) {
+ if (places.length==0)
+ return subtract ? "0" : ""; // or "1" ?
+ else {
+ string s = subtract ? " - " : "";
+ for (int step=0; step<places.length; ++step) {
+ if (step>0)
+ s+= subtract ? " - " : " + ";
+ s+=stepToLinear(step);
+ }
+ return s;
+ }
+ }
+
+ string toCode(bool subtract=false) {
+ if (places.length==0)
+ return subtract ? "0" : ""; // or "1" ?
+ else {
+ string s = subtract ? " - " : "";
+ for (int step=0; step<places.length; ++step) {
+ if (step>0)
+ s+= subtract ? " - " : " + ";
+ s+=stepToCode(step);
+ }
+ return s;
+ }
+ }
+}
+
+struct Relation { // {{{1
+ Braid lhs, rhs;
+
+ string lsym, codename;
+ bool inverted=false;
+
+ string toFormula() {
+ return lhs.toFormula() + " = " + rhs.toFormula();
+ }
+
+ string linearName() {
+ assert(lhs.n==rhs.n);
+ assert(lsym!="");
+
+ string s=(inverted ? "-" : "") + lsym+"(";
+ for (int i=1; i<=lhs.n+1; ++i) {
+ if (i>1)
+ s+=",";
+ s+="x_"+(string)i;
+ }
+ return s+")";
+ }
+
+ string fullCodeName() {
+ assert(lhs.n==rhs.n);
+ assert(codename!="");
+
+ string s=(inverted ? "minus" : "") + codename+"[";
+ for (int i=1; i<=lhs.n+1; ++i) {
+ if (i>1)
+ s+=", ";
+ s+="x"+(string)i+"_";
+ }
+ return s+"]";
+ }
+
+ string toLinear() {
+ return linearName() + " = " + lhs.toLinear() + rhs.toLinear(true);
+ }
+
+ string toCode() {
+ return fullCodeName() + " :> " + lhs.toCode() + rhs.toCode(true);
+ }
+
+ void draw(picture pic=currentpicture) {
+ picture left; lhs.draw(left);
+ frame l=left.fit();
+ picture right; rhs.draw(right);
+ frame r=right.fit();
+
+ real xpad=30;
+
+ add(pic, l);
+ label(pic, "=", (max(l).x + 0.5xpad, 0.25(max(l).y+max(r).y)));
+ add(pic, r, (max(l).x+xpad,0));
+ }
+}
+
+Relation operator- (Relation r) {
+ Relation opposite;
+ opposite.lhs=r.rhs;
+ opposite.rhs=r.lhs;
+ opposite.lsym=r.lsym;
+ opposite.codename=r.codename;
+ opposite.inverted=!r.inverted;
+ return opposite;
+}
+
+
+Braid apply(Relation r, Braid b, int step, int place) {
+ bool valid=b.exactMatch(r.lhs,place,step);
+ if (valid) {
+ Braid result=new Braid;
+ result.n=b.n;
+ for (int i=0; i<step; ++i)
+ result.places.push(b.places[i]);
+ result.add(r.rhs,place);
+ for (int i=step+r.lhs.places.length; i<b.places.length; ++i)
+ result.places.push(b.places[i]);
+ return result;
+ }
+ else {
+ write("Invalid match!");
+ return null;
+ }
+}
+
+// Tableau {{{1
+frame[] fit(picture[] pics) {
+ frame[] f;
+ for (int i=0; i<pics.length; ++i) {
+ frame ff=pics[i].fit();
+ //label(ff, (string)i, (10,10));
+ //f.push(pics[i].fit());
+ f.push(ff);
+ }
+ return f;
+}
+
+// Draw a number of frames in a nice circular arrangement.
+picture tableau(frame[] cards, bool number=false) {
+ int n=cards.length;
+
+ // Calculate the max height and width of the frames (assuming min(f)=(0,0)).
+ pair M=(0,0);
+ for (int i=0; i<n; ++i) {
+ pair z=max(cards[i]);
+ if (z.x > M.x)
+ M=(z.x,M.y);
+ if (z.y > M.y)
+ M=(M.x,z.y);
+ }
+
+ picture pic;
+ real xpad=2.0, ypad=1.3;
+ void place(int index, real row, real column) {
+ pair z=((M.x*xpad)*column,(M.y*ypad)*row);
+ add(pic, cards[index], z);
+ if (number) {
+ label(pic,(string)index, z+(0.5M.x,0), S);
+ }
+ }
+
+ // Handle small collections.
+ if (n<=4) {
+ for (int i=0; i<n; ++i)
+ place(i,0,i);
+ }
+ else {
+ int rows=quotient(n-1,2), columns=3;
+
+ // Add the top middle card.
+ place(0,rows-1,1);
+
+ // place cards down the right side.
+ for (int i=1; i<rows; ++i)
+ place(i, rows-i,2);
+
+ // place cards at the bottom.
+ if (n%2==0) {
+ place(rows,0,2);
+ place(rows+1,0,1);
+ place(rows+2,0,0);
+ }
+ else {
+ place(rows,0,1.5);
+ place(rows+1,0,0.5);
+ }
+
+ // place cards up the left side.
+ for (int i=1; i<rows; ++i)
+ place(i+n-rows,i,0);
+ }
+
+ return pic;
+}
+
+struct Syzygy { // {{{1
+ // Setup {{{2
+ Braid initial=null;
+ bool cyclic=true;
+ bool showall=false;
+ bool number=false; // Number the diagrams when drawn.
+
+ string lsym, codename;
+
+ bool watched=false;
+ bool uptodate=true;
+
+ struct Move {
+ Braid action(Braid);
+ Relation rel;
+ int place, step;
+ }
+
+ Move[] moves;
+
+ void apply(Relation r, int step, int place) {
+ Move m=new Move;
+ m.rel=r;
+ m.place=place; m.step=step;
+ m.action=new Braid (Braid b) {
+ return apply(r, b, step, place);
+ };
+ moves.push(m);
+
+ uptodate = false;
+ }
+
+ void swap(int i, int j) {
+ Move m=new Move;
+ m.rel=null;
+ m.action=new Braid (Braid b) {
+ return b.swap(i, j);
+ };
+ moves.push(m);
+
+ uptodate = false;
+ }
+
+ // Drawing {{{2
+ picture[] drawMoves() {
+ picture[] pics;
+
+ assert(initial!=null, "must set initial braid");
+ Braid b=initial;
+
+ picture pic;
+ b.draw(pic);
+ pics.push(pic);
+
+ for (int i=0; i<moves.length; ++i) {
+ b=moves[i].action(b);
+ if (showall || moves[i].rel != null) {
+ picture pic;
+ b.draw(pic);
+ pics.push(pic);
+ }
+ }
+
+ // Remove the last picture.
+ if (this.cyclic)
+ pics.pop();
+
+ return pics;
+ }
+
+ void draw(picture pic=currentpicture) {
+ pic.add(tableau(fit(drawMoves()), this.number));
+ }
+
+ void updatefunction() {
+ if (!uptodate) {
+ picture pic; this.draw(pic);
+ shipout(pic);
+ uptodate = true;
+ }
+ }
+
+ void oldupdatefunction() = null;
+
+ void watch() {
+ if (!watched) {
+ watched = true;
+ oldupdatefunction = atupdate();
+ atupdate(this.updatefunction);
+ uptodate = false;
+ }
+ }
+
+ void unwatch() {
+ assert(watched == true);
+ atupdate(oldupdatefunction);
+ uptodate = false;
+ }
+
+ // Writing {{{2
+ string linearName() {
+ assert(lsym!="");
+
+ string s=lsym+"(";
+ for (int i=1; i<=initial.n+1; ++i) {
+ if (i>1)
+ s+=",";
+ s+="x_"+(string)i;
+ }
+ return s+")";
+ }
+
+ string fullCodeName() {
+ assert(codename!="");
+
+ string s=codename+"[";
+ for (int i=1; i<=initial.n+1; ++i) {
+ if (i>1)
+ s+=", ";
+ s+="x"+(string)i+"_";
+ }
+ return s+"]";
+ }
+
+ string toLinear() {
+ string s=linearName()+" = ";
+
+ Braid b=initial;
+ bool first=true;
+ for (int i=0; i<moves.length; ++i) {
+ Move m=moves[i];
+ if (m.rel != null) {
+ if (first) {
+ first=false;
+ if (m.rel.inverted)
+ s+=" - ";
+ }
+ else
+ s+=m.rel.inverted ? " - " : " + ";
+ s+=m.rel.lsym+b.windowToLinear(m.step, m.place, m.rel.lhs.n);
+ }
+ b=m.action(b);
+ }
+
+ return s;
+ }
+
+ string toCode() {
+ string s=fullCodeName()+" :> ";
+
+ Braid b=initial;
+ bool first=true;
+ for (int i=0; i<moves.length; ++i) {
+ Move m=moves[i];
+ if (m.rel != null) {
+ if (first) {
+ first=false;
+ if (m.rel.inverted)
+ s+=" - ";
+ }
+ else
+ s+=m.rel.inverted ? " - " : " + ";
+ s+=m.rel.codename+b.windowToCode(m.step, m.place, m.rel.lhs.n);
+ }
+ b=m.action(b);
+ }
+
+ return s;
+ }
+
+}
+
+// Relation definitions {{{1
+// If you define more relations that you think would be useful, please email
+// them to me, and I'll add them to the script. --Andy.
+Relation r3;
+r3.lhs.n=3;
+r3.lsym="\rho_3"; r3.codename="rho3";
+r3.lhs.add(bp,0); r3.lhs.add(bp,1); r3.lhs.add(bp,0);
+r3.rhs.n=3;
+r3.rhs.add(bp,1); r3.rhs.add(bp,0); r3.rhs.add(bp,1);
+
+Relation r4a;
+r4a.lhs.n=3;
+r4a.lsym="\rho_{4a}"; r4a.codename="rho4a";
+r4a.lhs.add(bp,0); r4a.lhs.add(bp,1); r4a.lhs.add(phi,0);
+r4a.rhs.n=3;
+r4a.rhs.add(phi,1); r4a.rhs.add(bp,0);
+
+Relation r4b;
+r4b.lhs.n=3;
+r4b.lsym="\rho_{4b}"; r4b.codename="rho4b";
+r4b.lhs.add(bp,1); r4b.lhs.add(bp,0); r4b.lhs.add(phi,1);
+r4b.rhs.n=3;
+r4b.rhs.add(phi,0); r4b.rhs.add(bp,0);
+
diff --git a/Build/source/utils/asymptote/base/texcolors.asy b/Build/source/utils/asymptote/base/texcolors.asy
new file mode 100644
index 00000000000..90d9606cb70
--- /dev/null
+++ b/Build/source/utils/asymptote/base/texcolors.asy
@@ -0,0 +1,68 @@
+pen GreenYellow=cmyk(0.15,0,0.69,0);
+pen Yellow=cmyk(0,0,1,0);
+pen Goldenrod=cmyk(0,0.10,0.84,0);
+pen Dandelion=cmyk(0,0.29,0.84,0);
+pen Apricot=cmyk(0,0.32,0.52,0);
+pen Peach=cmyk(0,0.50,0.70,0);
+pen Melon=cmyk(0,0.46,0.50,0);
+pen YellowOrange=cmyk(0,0.42,1,0);
+pen Orange=cmyk(0,0.61,0.87,0);
+pen BurntOrange=cmyk(0,0.51,1,0);
+pen Bittersweet=cmyk(0,0.75,1,0.24);
+pen RedOrange=cmyk(0,0.77,0.87,0);
+pen Mahogany=cmyk(0,0.85,0.87,0.35);
+pen Maroon=cmyk(0,0.87,0.68,0.32);
+pen BrickRed=cmyk(0,0.89,0.94,0.28);
+pen Red=cmyk(0,1,1,0);
+pen OrangeRed=cmyk(0,1,0.50,0);
+pen RubineRed=cmyk(0,1,0.13,0);
+pen WildStrawberry=cmyk(0,0.96,0.39,0);
+pen Salmon=cmyk(0,0.53,0.38,0);
+pen CarnationPink=cmyk(0,0.63,0,0);
+pen Magenta=cmyk(0,1,0,0);
+pen VioletRed=cmyk(0,0.81,0,0);
+pen Rhodamine=cmyk(0,0.82,0,0);
+pen Mulberry=cmyk(0.34,0.90,0,0.02);
+pen RedViolet=cmyk(0.07,0.90,0,0.34);
+pen Fuchsia=cmyk(0.47,0.91,0,0.08);
+pen Lavender=cmyk(0,0.48,0,0);
+pen Thistle=cmyk(0.12,0.59,0,0);
+pen Orchid=cmyk(0.32,0.64,0,0);
+pen DarkOrchid=cmyk(0.40,0.80,0.20,0);
+pen Purple=cmyk(0.45,0.86,0,0);
+pen Plum=cmyk(0.50,1,0,0);
+pen Violet=cmyk(0.79,0.88,0,0);
+pen RoyalPurple=cmyk(0.75,0.90,0,0);
+pen BlueViolet=cmyk(0.86,0.91,0,0.04);
+pen Periwinkle=cmyk(0.57,0.55,0,0);
+pen CadetBlue=cmyk(0.62,0.57,0.23,0);
+pen CornflowerBlue=cmyk(0.65,0.13,0,0);
+pen MidnightBlue=cmyk(0.98,0.13,0,0.43);
+pen NavyBlue=cmyk(0.94,0.54,0,0);
+pen RoyalBlue=cmyk(1,0.50,0,0);
+pen Blue=cmyk(1,1,0,0);
+pen Cerulean=cmyk(0.94,0.11,0,0);
+pen Cyan=cmyk(1,0,0,0);
+pen ProcessBlue=cmyk(0.96,0,0,0);
+pen SkyBlue=cmyk(0.62,0,0.12,0);
+pen Turquoise=cmyk(0.85,0,0.20,0);
+pen TealBlue=cmyk(0.86,0,0.34,0.02);
+pen Aquamarine=cmyk(0.82,0,0.30,0);
+pen BlueGreen=cmyk(0.85,0,0.33,0);
+pen Emerald=cmyk(1,0,0.50,0);
+pen JungleGreen=cmyk(0.99,0,0.52,0);
+pen SeaGreen=cmyk(0.69,0,0.50,0);
+pen Green=cmyk(1,0,1,0);
+pen ForestGreen=cmyk(0.91,0,0.88,0.12);
+pen PineGreen=cmyk(0.92,0,0.59,0.25);
+pen LimeGreen=cmyk(0.50,0,1,0);
+pen YellowGreen=cmyk(0.44,0,0.74,0);
+pen SpringGreen=cmyk(0.26,0,0.76,0);
+pen OliveGreen=cmyk(0.64,0,0.95,0.40);
+pen RawSienna=cmyk(0,0.72,1,0.45);
+pen Sepia=cmyk(0,0.83,1,0.70);
+pen Brown=cmyk(0,0.81,1,0.60);
+pen Tan=cmyk(0.14,0.42,0.56,0);
+pen Gray=cmyk(0,0,0,0.50);
+pen Black=cmyk(0,0,0,1);
+pen White=cmyk(0,0,0,0);
diff --git a/Build/source/utils/asymptote/base/three.asy b/Build/source/utils/asymptote/base/three.asy
new file mode 100644
index 00000000000..2ba6b73abe1
--- /dev/null
+++ b/Build/source/utils/asymptote/base/three.asy
@@ -0,0 +1,2614 @@
+private import math;
+
+if(inXasyMode) settings.render=0;
+
+if(prc0()) {
+ access embed;
+ Embed=embed.embed;
+ Link=embed.link;
+}
+
+real defaultshininess=0.25;
+real defaultgranularity=0;
+real linegranularity=0.01;
+real tubegranularity=0.003;
+real dotgranularity=0.0001;
+pair viewportmargin=0; // Horizontal and vertical viewport margins.
+real viewportfactor=1.02; // Factor used to expand orthographic viewport.
+real anglefactor=1.02; // Factor used to expand perspective viewport.
+real angleprecision=1e-3; // Precision for centering perspective projections.
+
+string defaultembed3Doptions;
+string defaultembed3Dscript;
+
+triple O=(0,0,0);
+triple X=(1,0,0), Y=(0,1,0), Z=(0,0,1);
+
+// A translation in 3D space.
+transform3 shift(triple v)
+{
+ transform3 t=identity(4);
+ t[0][3]=v.x;
+ t[1][3]=v.y;
+ t[2][3]=v.z;
+ return t;
+}
+
+// Avoid two parentheses.
+transform3 shift(real x, real y, real z)
+{
+ return shift((x,y,z));
+}
+
+transform3 shift(transform3 t)
+{
+ transform3 T=identity(4);
+ T[0][3]=t[0][3];
+ T[1][3]=t[1][3];
+ T[2][3]=t[2][3];
+ return T;
+}
+
+// A 3D scaling in the x direction.
+transform3 xscale3(real x)
+{
+ transform3 t=identity(4);
+ t[0][0]=x;
+ return t;
+}
+
+// A 3D scaling in the y direction.
+transform3 yscale3(real y)
+{
+ transform3 t=identity(4);
+ t[1][1]=y;
+ return t;
+}
+
+// A 3D scaling in the z direction.
+transform3 zscale3(real z)
+{
+ transform3 t=identity(4);
+ t[2][2]=z;
+ return t;
+}
+
+// A 3D scaling by s in the v direction.
+transform3 scale(triple v, real s)
+{
+ v=unit(v);
+ s -= 1;
+ return new real[][] {
+ {1+s*v.x^2, s*v.x*v.y, s*v.x*v.z, 0},
+ {s*v.x*v.y, 1+s*v.y^2, s*v.y*v.z, 0},
+ {s*v.x*v.z, s*v.y*v.z, 1+s*v.z^2, 0},
+ {0, 0, 0, 1}};
+}
+
+// A transformation representing rotation by an angle in degrees about
+// an axis v through the origin (in the right-handed direction).
+transform3 rotate(real angle, triple v)
+{
+ if(v == O) abort("cannot rotate about the zero vector");
+ v=unit(v);
+ real x=v.x, y=v.y, z=v.z;
+ real s=Sin(angle), c=Cos(angle), t=1-c;
+
+ return new real[][] {
+ {t*x^2+c, t*x*y-s*z, t*x*z+s*y, 0},
+ {t*x*y+s*z, t*y^2+c, t*y*z-s*x, 0},
+ {t*x*z-s*y, t*y*z+s*x, t*z^2+c, 0},
+ {0, 0, 0, 1}};
+}
+
+// A transformation representing rotation by an angle in degrees about
+// the line u--v (in the right-handed direction).
+transform3 rotate(real angle, triple u, triple v)
+{
+ return shift(u)*rotate(angle,v-u)*shift(-u);
+}
+
+// Reflects about the plane through u, v, and w.
+transform3 reflect(triple u, triple v, triple w)
+{
+ triple n=unit(cross(v-u,w-u));
+ if(n == O)
+ abort("points determining reflection plane cannot be colinear");
+
+ return new real[][] {
+ {1-2*n.x^2, -2*n.x*n.y, -2*n.x*n.z, u.x},
+ {-2*n.x*n.y, 1-2*n.y^2, -2*n.y*n.z, u.y},
+ {-2*n.x*n.z, -2*n.y*n.z, 1-2*n.z^2, u.z},
+ {0, 0, 0, 1}
+ }*shift(-u);
+}
+
+bool operator != (real[][] a, real[][] b) {
+ return !(a == b);
+}
+
+// Project u onto v.
+triple project(triple u, triple v)
+{
+ v=unit(v);
+ return dot(u,v)*v;
+}
+
+// Return a unit vector perpendicular to a given unit vector v.
+triple perp(triple v)
+{
+ triple u=cross(v,Y);
+ return (abs(u) > sqrtEpsilon) ? unit(u) : unit(cross(v,Z));
+}
+
+// Return the transformation corresponding to moving the camera from the target
+// (looking in the negative z direction) to the point 'eye' (looking at target),
+// orienting the camera so that direction 'up' points upwards.
+// Since, in actuality, we are transforming the points instead of the camera,
+// we calculate the inverse matrix.
+// Based on the gluLookAt implementation in the OpenGL manual.
+transform3 look(triple eye, triple up=Z, triple target=O)
+{
+ triple f=unit(target-eye);
+ if(f == O)
+ f=-Z; // The eye is already at the origin: look down.
+
+ triple s=cross(f,up);
+
+ // If the eye is pointing either directly up or down, there is no
+ // preferred "up" direction. Pick one arbitrarily.
+ s=s != O ? unit(s) : perp(f);
+
+ triple u=cross(s,f);
+
+ transform3 M={{ s.x, s.y, s.z, 0},
+ { u.x, u.y, u.z, 0},
+ {-f.x, -f.y, -f.z, 0},
+ { 0, 0, 0, 1}};
+
+ return M*shift(-eye);
+}
+
+// Return a matrix to do perspective distortion based on a triple v.
+transform3 distort(triple v)
+{
+ transform3 t=identity(4);
+ real d=length(v);
+ if(d == 0) return t;
+ t[3][2]=-1/d;
+ t[3][3]=0;
+ return t;
+}
+
+projection operator * (transform3 t, projection P)
+{
+ projection P=P.copy();
+ if(!P.absolute) {
+ P.camera=t*P.camera;
+ P.target=t*P.target;
+ P.calculate();
+ }
+ return P;
+}
+
+// With this, save() and restore() in plain also save and restore the
+// currentprojection.
+addSaveFunction(new restoreThunk() {
+ projection P=currentprojection.copy();
+ return new void() {
+ currentprojection=P;
+ };
+ });
+
+pair project(triple v, projection P=currentprojection)
+{
+ return project(v,P.t);
+}
+
+pair dir(triple v, triple dir, projection P)
+{
+ return unit(project(v+0.5dir,P)-project(v-0.5*dir,P));
+}
+
+// Uses the homogenous coordinate to perform perspective distortion.
+// When combined with a projection to the XY plane, this effectively maps
+// points in three space to a plane through target and
+// perpendicular to the vector camera-target.
+projection perspective(triple camera, triple up=Z, triple target=O,
+ bool showtarget=true, bool autoadjust=true,
+ bool center=false)
+{
+ if(camera == target)
+ abort("camera cannot be at target");
+ return projection(camera,up,target,showtarget,autoadjust,center,
+ new transformation(triple camera, triple up, triple target)
+ {return transformation(look(camera,up,target),
+ distort(camera-target));});
+}
+
+projection perspective(real x, real y, real z, triple up=Z, triple target=O,
+ bool showtarget=true, bool autoadjust=true,
+ bool center=false)
+{
+ return perspective((x,y,z),up,target,showtarget,autoadjust,center);
+}
+
+projection orthographic(triple camera, triple up=Z, triple target=O,
+ bool showtarget=true, bool autoadjust=true,
+ bool center=false)
+{
+ return projection(camera,up,target,showtarget,autoadjust,center,
+ new transformation(triple camera, triple up,
+ triple target) {
+ return transformation(look(camera,up,target));});
+}
+
+projection orthographic(real x, real y, real z, triple up=Z,
+ triple target=O, bool showtarget=true,
+ bool autoadjust=true, bool center=false)
+{
+ return orthographic((x,y,z),up,target,showtarget,autoadjust,center);
+}
+
+projection oblique(real angle=45)
+{
+ transform3 t=identity(4);
+ real c2=Cos(angle)^2;
+ real s2=1-c2;
+ t[0][2]=-c2;
+ t[1][2]=-s2;
+ t[2][2]=1;
+ return projection((c2,s2,1),up=Y,
+ new transformation(triple,triple,triple) {
+ return transformation(t,oblique=true);});
+}
+
+projection obliqueZ(real angle=45) {return oblique(angle);}
+
+projection obliqueX(real angle=45)
+{
+ transform3 t=identity(4);
+ real c2=Cos(angle)^2;
+ real s2=1-c2;
+ t[0][0]=-c2;
+ t[1][0]=-s2;
+ t[1][1]=0;
+ t[0][1]=1;
+ t[1][2]=1;
+ t[2][2]=0;
+ t[2][0]=1;
+ return projection((1,c2,s2),
+ new transformation(triple,triple,triple) {
+ return transformation(t,oblique=true);});
+}
+
+projection obliqueY(real angle=45)
+{
+ transform3 t=identity(4);
+ real c2=Cos(angle)^2;
+ real s2=1-c2;
+ t[0][1]=c2;
+ t[1][1]=s2;
+ t[1][2]=1;
+ t[2][1]=-1;
+ t[2][2]=0;
+ return projection((c2,-1,s2),
+ new transformation(triple,triple,triple) {
+ return transformation(t,oblique=true);});
+}
+
+projection oblique=oblique();
+projection obliqueX=obliqueX(), obliqueY=obliqueY(), obliqueZ=obliqueZ();
+
+currentprojection=perspective(5,4,2);
+
+// Map pair z to a triple by inverting the projection P onto the
+// plane perpendicular to normal and passing through point.
+triple invert(pair z, triple normal, triple point,
+ projection P=currentprojection)
+{
+ transform3 t=P.t;
+ real[][] A={{t[0][0]-z.x*t[3][0],t[0][1]-z.x*t[3][1],t[0][2]-z.x*t[3][2]},
+ {t[1][0]-z.y*t[3][0],t[1][1]-z.y*t[3][1],t[1][2]-z.y*t[3][2]},
+ {normal.x,normal.y,normal.z}};
+ real[] b={z.x*t[3][3]-t[0][3],z.y*t[3][3]-t[1][3],dot(normal,point)};
+ real[] x=solve(A,b,warn=false);
+ return x.length > 0 ? (x[0],x[1],x[2]) : P.camera;
+}
+
+// Map pair to a triple on the projection plane.
+triple invert(pair z, projection P=currentprojection)
+{
+ return invert(z,P.vector(),P.target,P);
+}
+
+// Map pair dir to a triple direction at point v on the projection plane.
+triple invert(pair dir, triple v, projection P=currentprojection)
+{
+ return invert(project(v,P)+dir,P.vector(),v,P)-v;
+}
+
+pair xypart(triple v)
+{
+ return (v.x,v.y);
+}
+
+struct control {
+ triple post,pre;
+ bool active=false;
+ bool straight=true;
+ void operator init(triple post, triple pre, bool straight=false) {
+ this.post=post;
+ this.pre=pre;
+ active=true;
+ this.straight=straight;
+ }
+}
+
+control nocontrol;
+
+control operator * (transform3 t, control c)
+{
+ control C;
+ C.post=t*c.post;
+ C.pre=t*c.pre;
+ C.active=c.active;
+ C.straight=c.straight;
+ return C;
+}
+
+void write(file file, control c)
+{
+ write(file,".. controls ");
+ write(file,c.post);
+ write(file," and ");
+ write(file,c.pre);
+}
+
+struct Tension {
+ real out,in;
+ bool atLeast;
+ bool active;
+ void operator init(real out=1, real in=1, bool atLeast=false,
+ bool active=true) {
+ real check(real val) {
+ if(val < 0.75) abort("tension cannot be less than 3/4");
+ return val;
+ }
+ this.out=check(out);
+ this.in=check(in);
+ this.atLeast=atLeast;
+ this.active=active;
+ }
+}
+
+Tension operator init()
+{
+ return Tension();
+}
+
+Tension noTension;
+noTension.active=false;
+
+void write(file file, Tension t)
+{
+ write(file,"..tension ");
+ if(t.atLeast) write(file,"atleast ");
+ write(file,t.out);
+ write(file," and ");
+ write(file,t.in);
+}
+
+struct dir {
+ triple dir;
+ real gamma=1; // endpoint curl
+ bool Curl; // curl specified
+ bool active() {
+ return dir != O || Curl;
+ }
+ void init(triple v) {
+ this.dir=v;
+ }
+ void init(real gamma) {
+ if(gamma < 0) abort("curl cannot be less than 0");
+ this.gamma=gamma;
+ this.Curl=true;
+ }
+ void init(dir d) {
+ dir=d.dir;
+ gamma=d.gamma;
+ Curl=d.Curl;
+ }
+ void default(triple v) {
+ if(!active()) init(v);
+ }
+ void default(dir d) {
+ if(!active()) init(d);
+ }
+ dir copy() {
+ dir d=new dir;
+ d.init(this);
+ return d;
+ }
+}
+
+void write(file file, dir d)
+{
+ if(d.dir != O) {
+ write(file,"{"); write(file,unit(d.dir)); write(file,"}");
+ } else if(d.Curl) {
+ write(file,"{curl "); write(file,d.gamma); write(file,"}");
+ }
+}
+
+dir operator * (transform3 t, dir d)
+{
+ dir D=d.copy();
+ D.init(unit(shiftless(t)*d.dir));
+ return D;
+}
+
+void checkEmpty(int n) {
+ if(n == 0)
+ abort("nullpath3 has no points");
+}
+
+int adjustedIndex(int i, int n, bool cycles)
+{
+ checkEmpty(n);
+ if(cycles)
+ return i % n;
+ else if(i < 0)
+ return 0;
+ else if(i >= n)
+ return n-1;
+ else
+ return i;
+}
+
+struct flatguide3 {
+ triple[] nodes;
+ bool[] cyclic; // true if node is really a cycle
+ control[] control; // control points for segment starting at node
+ Tension[] Tension; // Tension parameters for segment starting at node
+ dir[] in,out; // in and out directions for segment starting at node
+
+ bool cyclic() {int n=cyclic.length; return n > 0 ? cyclic[n-1] : false;}
+ bool precyclic() {int i=find(cyclic); return i >= 0 && i < cyclic.length-1;}
+
+ int size() {
+ return cyclic() ? nodes.length-1 : nodes.length;
+ }
+
+ void node(triple v, bool b=false) {
+ nodes.push(v);
+ control.push(nocontrol);
+ Tension.push(noTension);
+ in.push(new dir);
+ out.push(new dir);
+ cyclic.push(b);
+ }
+
+ void control(triple post, triple pre) {
+ if(control.length > 0) {
+ control c=control(post,pre,false);
+ control[control.length-1]=c;
+ }
+ }
+
+ void Tension(real out, real in, bool atLeast) {
+ if(Tension.length > 0)
+ Tension[Tension.length-1]=Tension(out,in,atLeast,true);
+ }
+
+ void in(triple v) {
+ if(in.length > 0) {
+ in[in.length-1].init(v);
+ }
+ }
+
+ void out(triple v) {
+ if(out.length > 0) {
+ out[out.length-1].init(v);
+ }
+ }
+
+ void in(real gamma) {
+ if(in.length > 0) {
+ in[in.length-1].init(gamma);
+ }
+ }
+
+ void out(real gamma) {
+ if(out.length > 0) {
+ out[out.length-1].init(gamma);
+ }
+ }
+
+ void cycleToken() {
+ if(nodes.length > 0)
+ node(nodes[0],true);
+ }
+
+ // Return true if outgoing direction at node i is known.
+ bool solved(int i) {
+ return out[i].active() || control[i].active;
+ }
+}
+
+void write(file file, string s="", explicit flatguide3 x, suffix suffix=none)
+{
+ write(file,s);
+ if(x.size() == 0) write(file,"<nullpath3>");
+ else for(int i=0; i < x.nodes.length; ++i) {
+ if(i > 0) write(file,endl);
+ if(x.cyclic[i]) write(file,"cycle");
+ else write(file,x.nodes[i]);
+ if(i < x.nodes.length-1) {
+ // Explicit control points trump other specifiers
+ if(x.control[i].active)
+ write(file,x.control[i]);
+ else {
+ write(file,x.out[i]);
+ if(x.Tension[i].active) write(file,x.Tension[i]);
+ }
+ write(file,"..");
+ if(!x.control[i].active) write(file,x.in[i]);
+ }
+ }
+ write(file,suffix);
+}
+
+void write(string s="", flatguide3 x, suffix suffix=endl)
+{
+ write(stdout,s,x,suffix);
+}
+
+// A guide3 is most easily represented as something that modifies a flatguide3.
+typedef void guide3(flatguide3);
+
+restricted void nullpath3(flatguide3) {};
+
+guide3 operator init() {return nullpath3;}
+
+guide3 operator cast(triple v)
+{
+ return new void(flatguide3 f) {
+ f.node(v);
+ };
+}
+
+guide3 operator cast(cycleToken) {
+ return new void(flatguide3 f) {
+ f.cycleToken();
+ };
+}
+
+guide3 operator controls(triple post, triple pre)
+{
+ return new void(flatguide3 f) {
+ f.control(post,pre);
+ };
+};
+
+guide3 operator controls(triple v)
+{
+ return operator controls(v,v);
+}
+
+guide3 operator cast(tensionSpecifier t)
+{
+ return new void(flatguide3 f) {
+ f.Tension(t.out, t.in, t.atLeast);
+ };
+}
+
+guide3 operator cast(curlSpecifier spec)
+{
+ return new void(flatguide3 f) {
+ if(spec.side == JOIN_OUT) f.out(spec.value);
+ else if(spec.side == JOIN_IN) f.in(spec.value);
+ else
+ abort("invalid curl specifier");
+ };
+}
+
+guide3 operator spec(triple v, int side)
+{
+ return new void(flatguide3 f) {
+ if(side == JOIN_OUT) f.out(v);
+ else if(side == JOIN_IN) f.in(v);
+ else
+ abort("invalid direction specifier");
+ };
+}
+
+guide3 operator -- (... guide3[] g)
+{
+ return new void(flatguide3 f) {
+ if(g.length > 0) {
+ for(int i=0; i < g.length-1; ++i) {
+ g[i](f);
+ f.out(1);
+ f.in(1);
+ }
+ g[g.length-1](f);
+ }
+ };
+}
+
+guide3 operator .. (... guide3[] g)
+{
+ return new void(flatguide3 f) {
+ for(int i=0; i < g.length; ++i)
+ g[i](f);
+ };
+}
+
+guide3 operator ::(... guide3[] a)
+{
+ if(a.length == 0) return nullpath3;
+ guide3 g=a[0];
+ for(int i=1; i < a.length; ++i)
+ g=g.. tension atleast 1 ..a[i];
+ return g;
+}
+
+guide3 operator ---(... guide3[] a)
+{
+ if(a.length == 0) return nullpath3;
+ guide3 g=a[0];
+ for(int i=1; i < a.length; ++i)
+ g=g.. tension atleast infinity ..a[i];
+ return g;
+}
+
+flatguide3 operator cast(guide3 g)
+{
+ flatguide3 f;
+ g(f);
+ return f;
+}
+
+flatguide3[] operator cast(guide3[] g)
+{
+ flatguide3[] p=new flatguide3[g.length];
+ for(int i=0; i < g.length; ++i) {
+ flatguide3 f;
+ g[i](f);
+ p[i]=f;
+ }
+ return p;
+}
+
+// A version of asin that tolerates numerical imprecision
+real asin1(real x)
+{
+ return asin(min(max(x,-1),1));
+}
+
+// A version of acos that tolerates numerical imprecision
+real acos1(real x)
+{
+ return acos(min(max(x,-1),1));
+}
+
+struct Controls {
+ triple c0,c1;
+
+ // 3D extension of John Hobby's control point formula
+ // (cf. The MetaFont Book, page 131),
+ // as described in John C. Bowman and A. Hammerlindl,
+ // TUGBOAT: The Communications of th TeX Users Group 29:2 (2008).
+
+ void operator init(triple v0, triple v1, triple d0, triple d1, real tout,
+ real tin, bool atLeast) {
+ triple v=v1-v0;
+ triple u=unit(v);
+ real L=length(v);
+ d0=unit(d0);
+ d1=unit(d1);
+ real theta=acos1(dot(d0,u));
+ real phi=acos1(dot(d1,u));
+ if(dot(cross(d0,v),cross(v,d1)) < 0) phi=-phi;
+ c0=v0+d0*L*relativedistance(theta,phi,tout,atLeast);
+ c1=v1-d1*L*relativedistance(phi,theta,tin,atLeast);
+ }
+}
+
+private triple cross(triple d0, triple d1, triple reference)
+{
+ triple normal=cross(d0,d1);
+ return normal == O ? reference : normal;
+}
+
+private triple dir(real theta, triple d0, triple d1, triple reference)
+{
+ triple normal=cross(d0,d1,reference);
+ if(normal == O) return d1;
+ return rotate(degrees(theta),dot(normal,reference) >= 0 ? normal : -normal)*
+ d1;
+}
+
+private real angle(triple d0, triple d1, triple reference)
+{
+ real theta=acos1(dot(unit(d0),unit(d1)));
+ return dot(cross(d0,d1,reference),reference) >= 0 ? theta : -theta;
+}
+
+// 3D extension of John Hobby's angle formula (The MetaFont Book, page 131).
+// Notational differences: here psi[i] is the turning angle at z[i+1],
+// beta[i] is the tension for segment i, and in[i] is the incoming
+// direction for segment i (where segment i begins at node i).
+
+real[] theta(triple[] v, real[] alpha, real[] beta,
+ triple dir0, triple dirn, real g0, real gn, triple reference)
+{
+ real[] a,b,c,f,l,psi;
+ int n=alpha.length;
+ bool cyclic=v.cyclicflag;
+ for(int i=0; i < n; ++i)
+ l[i]=1/length(v[i+1]-v[i]);
+ int i0,in;
+ if(cyclic) {i0=0; in=n;}
+ else {i0=1; in=n-1;}
+ for(int i=0; i < in; ++i)
+ psi[i]=angle(v[i+1]-v[i],v[i+2]-v[i+1],reference);
+ if(cyclic) {
+ l.cyclic(true);
+ psi.cyclic(true);
+ } else {
+ psi[n-1]=0;
+ if(dir0 == O) {
+ real a0=alpha[0];
+ real b0=beta[0];
+ real chi=g0*(b0/a0)^2;
+ a[0]=0;
+ b[0]=3a0-a0/b0+chi;
+ real C=chi*(3a0-1)+a0/b0;
+ c[0]=C;
+ f[0]=-C*psi[0];
+ } else {
+ a[0]=c[0]=0;
+ b[0]=1;
+ f[0]=angle(v[1]-v[0],dir0,reference);
+ }
+ if(dirn == O) {
+ real an=alpha[n-1];
+ real bn=beta[n-1];
+ real chi=gn*(an/bn)^2;
+ a[n]=chi*(3bn-1)+bn/an;
+ b[n]=3bn-bn/an+chi;
+ c[n]=f[n]=0;
+ } else {
+ a[n]=c[n]=0;
+ b[n]=1;
+ f[n]=angle(v[n]-v[n-1],dirn,reference);
+ }
+ }
+
+ for(int i=i0; i < n; ++i) {
+ real in=beta[i-1]^2*l[i-1];
+ real A=in/alpha[i-1];
+ a[i]=A;
+ real B=3*in-A;
+ real out=alpha[i]^2*l[i];
+ real C=out/beta[i];
+ b[i]=B+3*out-C;
+ c[i]=C;
+ f[i]=-B*psi[i-1]-C*psi[i];
+ }
+
+ return tridiagonal(a,b,c,f);
+}
+
+triple reference(triple[] v, int n, triple d0, triple d1)
+{
+ triple[] V=sequence(new triple(int i) {
+ return cross(v[i+1]-v[i],v[i+2]-v[i+1]);
+ },n-1);
+ if(n > 0) {
+ V.push(cross(d0,v[1]-v[0]));
+ V.push(cross(v[n]-v[n-1],d1));
+ }
+
+ triple max=V[0];
+ real M=abs(max);
+ for(int i=1; i < V.length; ++i) {
+ triple vi=V[i];
+ real a=abs(vi);
+ if(a > M) {
+ M=a;
+ max=vi;
+ }
+ }
+
+ triple reference;
+ for(int i=0; i < V.length; ++i) {
+ triple u=unit(V[i]);
+ reference += dot(u,max) < 0 ? -u : u;
+ }
+
+ return reference;
+}
+
+// Fill in missing directions for n cyclic nodes.
+void aim(flatguide3 g, int N)
+{
+ bool cyclic=true;
+ int start=0, end=0;
+
+ // If the cycle contains one or more direction specifiers, break the loop.
+ for(int k=0; k < N; ++k)
+ if(g.solved(k)) {cyclic=false; end=k; break;}
+ for(int k=N-1; k >= 0; --k)
+ if(g.solved(k)) {cyclic=false; start=k; break;}
+ while(start < N && g.control[start].active) ++start;
+
+ int n=N-(start-end);
+ if(n <= 1 || (cyclic && n <= 2)) return;
+
+ triple[] v=new triple[cyclic ? n : n+1];
+ real[] alpha=new real[n];
+ real[] beta=new real[n];
+ for(int k=0; k < n; ++k) {
+ int K=(start+k) % N;
+ v[k]=g.nodes[K];
+ alpha[k]=g.Tension[K].out;
+ beta[k]=g.Tension[K].in;
+ }
+ if(cyclic) {
+ v.cyclic(true);
+ alpha.cyclic(true);
+ beta.cyclic(true);
+ } else v[n]=g.nodes[(start+n) % N];
+ int final=(end-1) % N;
+
+ triple d0=g.out[start].dir;
+ triple d1=g.in[final].dir;
+
+ triple reference=reference(v,n,d0,d1);
+
+ real[] theta=theta(v,alpha,beta,d0,d1,g.out[start].gamma,g.in[final].gamma,
+ reference);
+
+ v.cyclic(true);
+ theta.cyclic(true);
+
+ for(int k=1; k < (cyclic ? n+1 : n); ++k) {
+ triple w=dir(theta[k],v[k]-v[k-1],v[k+1]-v[k],reference);
+ g.in[(start+k-1) % N].init(w);
+ g.out[(start+k) % N].init(w);
+ }
+
+ if(g.out[start].dir == O)
+ g.out[start].init(dir(theta[0],v[0]-g.nodes[(start-1) % N],v[1]-v[0],
+ reference));
+ if(g.in[final].dir == O)
+ g.in[final].init(dir(theta[n],v[n-1]-v[n-2],v[n]-v[n-1],reference));
+}
+
+// Fill in missing directions for the sequence of nodes i...n.
+void aim(flatguide3 g, int i, int n)
+{
+ int j=n-i;
+ if(j > 1 || g.out[i].dir != O || g.in[i].dir != O) {
+ triple[] v=new triple[j+1];
+ real[] alpha=new real[j];
+ real[] beta=new real[j];
+ for(int k=0; k < j; ++k) {
+ v[k]=g.nodes[i+k];
+ alpha[k]=g.Tension[i+k].out;
+ beta[k]=g.Tension[i+k].in;
+ }
+ v[j]=g.nodes[n];
+
+ triple d0=g.out[i].dir;
+ triple d1=g.in[n-1].dir;
+
+ triple reference=reference(v,j,d0,d1);
+
+ real[] theta=theta(v,alpha,beta,d0,d1,g.out[i].gamma,g.in[n-1].gamma,
+ reference);
+
+ for(int k=1; k < j; ++k) {
+ triple w=dir(theta[k],v[k]-v[k-1],v[k+1]-v[k],reference);
+ g.in[i+k-1].init(w);
+ g.out[i+k].init(w);
+ }
+ if(g.out[i].dir == O) {
+ triple w=dir(theta[0],g.in[i].dir,v[1]-v[0],reference);
+ if(i > 0) g.in[i-1].init(w);
+ g.out[i].init(w);
+ }
+ if(g.in[n-1].dir == O) {
+ triple w=dir(theta[j],g.out[n-1].dir,v[j]-v[j-1],reference);
+ g.in[n-1].init(w);
+ g.out[n].init(w);
+ }
+ }
+}
+
+private real Fuzz=10*realEpsilon;
+
+triple XYplane(pair z) {return (z.x,z.y,0);}
+triple YZplane(pair z) {return (0,z.x,z.y);}
+triple ZXplane(pair z) {return (z.y,0,z.x);}
+
+bool cyclic(guide3 g) {flatguide3 f; g(f); return f.cyclic();}
+int size(guide3 g) {flatguide3 f; g(f); return f.size();}
+int length(guide3 g) {flatguide3 f; g(f); return f.nodes.length-1;}
+
+path3 path3(triple v)
+{
+ triple[] point={v};
+ return path3(point,point,point,new bool[] {false},false);
+}
+
+path3 path3(path p, triple plane(pair)=XYplane)
+{
+ int n=size(p);
+ return path3(sequence(new triple(int i) {return plane(precontrol(p,i));},n),
+ sequence(new triple(int i) {return plane(point(p,i));},n),
+ sequence(new triple(int i) {return plane(postcontrol(p,i));},n),
+ sequence(new bool(int i) {return straight(p,i);},n),
+ cyclic(p));
+}
+
+path3[] path3(explicit path[] g, triple plane(pair)=XYplane)
+{
+ return sequence(new path3(int i) {return path3(g[i],plane);},g.length);
+}
+
+// Construct a path from a path3 by applying P to each control point.
+path path(path3 p, pair P(triple)=xypart)
+{
+ int n=length(p);
+ if(n < 0) return nullpath;
+ guide g=P(point(p,0));
+ if(n == 0) return g;
+ for(int i=1; i < n; ++i)
+ g=straight(p,i-1) ? g--P(point(p,i)) :
+ g..controls P(postcontrol(p,i-1)) and P(precontrol(p,i))..P(point(p,i));
+
+ if(straight(p,n-1))
+ return cyclic(p) ? g--cycle : g--P(point(p,n));
+
+ pair post=P(postcontrol(p,n-1));
+ pair pre=P(precontrol(p,n));
+ return cyclic(p) ? g..controls post and pre..cycle :
+ g..controls post and pre..P(point(p,n));
+}
+
+void write(file file, string s="", explicit path3 x, suffix suffix=none)
+{
+ write(file,s);
+ int n=length(x);
+ if(n < 0) write("<nullpath3>");
+ else {
+ for(int i=0; i < n; ++i) {
+ write(file,point(x,i));
+ if(i < length(x)) {
+ if(straight(x,i)) write(file,"--");
+ else {
+ write(file,".. controls ");
+ write(file,postcontrol(x,i));
+ write(file," and ");
+ write(file,precontrol(x,i+1),newl);
+ write(file," ..");
+ }
+ }
+ }
+ if(cyclic(x))
+ write(file,"cycle",suffix);
+ else
+ write(file,point(x,n),suffix);
+ }
+}
+
+void write(string s="", explicit path3 x, suffix suffix=endl)
+{
+ write(stdout,s,x,suffix);
+}
+
+void write(file file, string s="", explicit path3[] x, suffix suffix=none)
+{
+ write(file,s);
+ if(x.length > 0) write(file,x[0]);
+ for(int i=1; i < x.length; ++i) {
+ write(file,endl);
+ write(file," ^^");
+ write(file,x[i]);
+ }
+ write(file,suffix);
+}
+
+void write(string s="", explicit path3[] x, suffix suffix=endl)
+{
+ write(stdout,s,x,suffix);
+}
+
+path3 solve(flatguide3 g)
+{
+ int n=g.nodes.length-1;
+
+ // If duplicate points occur consecutively, add dummy controls (if absent).
+ for(int i=0; i < n; ++i) {
+ if(g.nodes[i] == g.nodes[i+1] && !g.control[i].active)
+ g.control[i]=control(g.nodes[i],g.nodes[i],straight=true);
+ }
+
+ // Fill in empty direction specifiers inherited from explicit control points.
+ for(int i=0; i < n; ++i) {
+ if(g.control[i].active) {
+ g.out[i].init(g.control[i].post-g.nodes[i]);
+ g.in[i].init(g.nodes[i+1]-g.control[i].pre);
+ }
+ }
+
+ // Propagate directions across nodes.
+ for(int i=0; i < n; ++i) {
+ int next=g.cyclic[i+1] ? 0 : i+1;
+ if(g.out[next].active())
+ g.in[i].default(g.out[next]);
+ if(g.in[i].active()) {
+ g.out[next].default(g.in[i]);
+ g.out[i+1].default(g.in[i]);
+ }
+ }
+
+ // Compute missing 3D directions.
+ // First, resolve cycles
+ int i=find(g.cyclic);
+ if(i > 0) {
+ aim(g,i);
+ // All other cycles can now be reduced to sequences.
+ triple v=g.out[0].dir;
+ for(int j=i; j <= n; ++j) {
+ if(g.cyclic[j]) {
+ g.in[j-1].default(v);
+ g.out[j].default(v);
+ if(g.nodes[j-1] == g.nodes[j] && !g.control[j-1].active)
+ g.control[j-1]=control(g.nodes[j-1],g.nodes[j-1]);
+ }
+ }
+ }
+
+ // Next, resolve sequences.
+ int i=0;
+ int start=0;
+ while(i < n) {
+ // Look for a missing outgoing direction.
+ while(i <= n && g.solved(i)) {start=i; ++i;}
+ if(i > n) break;
+ // Look for the end of the sequence.
+ while(i < n && !g.solved(i)) ++i;
+
+ while(start < i && g.control[start].active) ++start;
+
+ if(start < i)
+ aim(g,start,i);
+ }
+
+ // Compute missing 3D control points.
+ for(int i=0; i < n; ++i) {
+ int next=g.cyclic[i+1] ? 0 : i+1;
+ if(!g.control[i].active) {
+ control c;
+ if((g.out[i].Curl && g.in[i].Curl) ||
+ (g.out[i].dir == O && g.in[i].dir == O)) {
+ // fill in straight control points for path3 functions
+ triple delta=(g.nodes[i+1]-g.nodes[i])/3;
+ c=control(g.nodes[i]+delta,g.nodes[i+1]-delta,straight=true);
+ } else {
+ Controls C=Controls(g.nodes[i],g.nodes[next],g.out[i].dir,g.in[i].dir,
+ g.Tension[i].out,g.Tension[i].in,
+ g.Tension[i].atLeast);
+ c=control(C.c0,C.c1);
+ }
+ g.control[i]=c;
+ }
+ }
+
+ // Convert to Knuth's format (control points stored with nodes)
+ int n=g.nodes.length;
+ bool cyclic;
+ if(n > 0) {
+ cyclic=g.cyclic[n-1];
+ if(cyclic) --n;
+ }
+ triple[] pre=new triple[n];
+ triple[] point=new triple[n];
+ triple[] post=new triple[n];
+ bool[] straight=new bool[n];
+ if(n > 0) {
+ for(int i=0; i < n-1; ++i) {
+ point[i]=g.nodes[i];
+ post[i]=g.control[i].post;
+ pre[i+1]=g.control[i].pre;
+ straight[i]=g.control[i].straight;
+ }
+ point[n-1]=g.nodes[n-1];
+ if(cyclic) {
+ pre[0]=g.control[n-1].pre;
+ post[n-1]=g.control[n-1].post;
+ straight[n-1]=g.control[n-1].straight;
+ } else {
+ pre[0]=point[0];
+ post[n-1]=point[n-1];
+ straight[n-1]=false;
+ }
+ }
+
+ return path3(pre,point,post,straight,cyclic);
+}
+
+path nurb(path3 p, projection P, int ninterpolate=P.ninterpolate)
+{
+ triple f=P.camera;
+ triple u=unit(P.vector());
+ transform3 t=P.t;
+
+ path nurb(triple v0, triple v1, triple v2, triple v3) {
+ return nurb(project(v0,t),project(v1,t),project(v2,t),project(v3,t),
+ dot(u,f-v0),dot(u,f-v1),dot(u,f-v2),dot(u,f-v3),ninterpolate);
+ }
+
+ path g;
+
+ if(straight(p,0))
+ g=project(point(p,0),t);
+
+ int last=length(p);
+ for(int i=0; i < last; ++i) {
+ if(straight(p,i))
+ g=g--project(point(p,i+1),t);
+ else
+ g=g&nurb(point(p,i),postcontrol(p,i),precontrol(p,i+1),point(p,i+1));
+ }
+
+ int n=length(g);
+ if(cyclic(p)) g=g&cycle;
+
+ return g;
+}
+
+path project(path3 p, projection P=currentprojection,
+ int ninterpolate=P.ninterpolate)
+{
+ guide g;
+
+ int last=length(p);
+ if(last < 0) return g;
+
+ transform3 t=P.t;
+
+ if(ninterpolate == 1 || piecewisestraight(p)) {
+ g=project(point(p,0),t);
+ // Construct the path.
+ int stop=cyclic(p) ? last-1 : last;
+ for(int i=0; i < stop; ++i) {
+ if(straight(p,i))
+ g=g--project(point(p,i+1),t);
+ else {
+ g=g..controls project(postcontrol(p,i),t) and
+ project(precontrol(p,i+1),t)..project(point(p,i+1),t);
+ }
+ }
+ } else return nurb(p,P);
+
+ if(cyclic(p))
+ g=straight(p,last-1) ? g--cycle :
+ g..controls project(postcontrol(p,last-1),t) and
+ project(precontrol(p,last),t)..cycle;
+ return g;
+}
+
+pair[] project(triple[] v, projection P=currentprojection)
+{
+ return sequence(new pair(int i) {return project(v[i],P.t);},v.length);
+}
+
+path[] project(explicit path3[] g, projection P=currentprojection)
+{
+ return sequence(new path(int i) {return project(g[i],P);},g.length);
+}
+
+guide3 operator cast(path3 p)
+{
+ int last=length(p);
+
+ bool cyclic=cyclic(p);
+ int stop=cyclic ? last-1 : last;
+ return new void(flatguide3 f) {
+ if(last >= 0) {
+ f.node(point(p,0));
+ for(int i=0; i < stop; ++i) {
+ if(straight(p,i)) {
+ f.out(1);
+ f.in(1);
+ } else
+ f.control(postcontrol(p,i),precontrol(p,i+1));
+ f.node(point(p,i+1));
+ }
+ if(cyclic) {
+ if(straight(p,stop)) {
+ f.out(1);
+ f.in(1);
+ } else
+ f.control(postcontrol(p,stop),precontrol(p,last));
+ f.cycleToken();
+ }
+ }
+ };
+}
+
+// Return a unit normal vector to a planar path p (or O if the path is
+// nonplanar).
+triple normal(path3 p)
+{
+ triple normal;
+ real fuzz=sqrtEpsilon*abs(max(p)-min(p));
+ real absnormal;
+ real theta;
+
+ bool Cross(triple a, triple b) {
+ if(abs(a) >= fuzz && abs(b) >= fuzz) {
+ triple n=cross(unit(a),unit(b));
+ real absn=abs(n);
+ n=unit(n);
+ if(absnormal > 0 && absn > sqrtEpsilon &&
+ abs(normal-n) > sqrtEpsilon && abs(normal+n) > sqrtEpsilon)
+ return true;
+ else {
+ int sign=dot(n,normal) >= 0 ? 1 : -1;
+ theta += sign*asin1(absn);
+ if(absn > absnormal) {
+ absnormal=absn;
+ normal=n;
+ theta=sign*theta;
+ }
+ }
+ }
+ return false;
+ }
+
+ int L=length(p);
+ if(L <= 0) return O;
+
+ triple zi=point(p,0);
+ triple v0=zi-precontrol(p,0);
+ for(int i=0; i < L; ++i) {
+ triple c0=postcontrol(p,i);
+ triple c1=precontrol(p,i+1);
+ triple zp=point(p,i+1);
+ triple v1=c0-zi;
+ triple v2=c1-c0;
+ triple v3=zp-c1;
+ if(Cross(v0,v1) || Cross(v1,v2) || Cross(v2,v3)) return O;
+ v0=v3;
+ zi=zp;
+ }
+ return theta >= 0 ? normal : -normal;
+}
+
+// Return a unit normal vector to a polygon with vertices in p.
+triple normal(triple[] p)
+{
+ triple normal;
+ real fuzz=sqrtEpsilon*abs(maxbound(p)-minbound(p));
+ real absnormal;
+ real theta;
+
+ bool Cross(triple a, triple b) {
+ if(abs(a) >= fuzz && abs(b) >= fuzz) {
+ triple n=cross(unit(a),unit(b));
+ real absn=abs(n);
+ n=unit(n);
+ if(absnormal > 0 && absn > sqrtEpsilon &&
+ abs(normal-n) > sqrtEpsilon && abs(normal+n) > sqrtEpsilon)
+ return true;
+ else {
+ int sign=dot(n,normal) >= 0 ? 1 : -1;
+ theta += sign*asin1(absn);
+ if(absn > absnormal) {
+ absnormal=absn;
+ normal=n;
+ theta=sign*theta;
+ }
+ }
+ }
+ return false;
+ }
+
+ if(p.length <= 0) return O;
+
+ triple zi=p[0];
+ triple v0=zi-p[p.length-1];
+ for(int i=0; i < p.length-1; ++i) {
+ triple zp=p[i+1];
+ triple v1=zp-zi;
+ if(Cross(v0,v1)) return O;
+ v0=v1;
+ zi=zp;
+ }
+ return theta >= 0 ? normal : -normal;
+}
+
+// Transforms that map XY plane to YX, YZ, ZY, ZX, and XZ planes.
+restricted transform3 XY=identity4;
+restricted transform3 YX=rotate(-90,O,Z);
+restricted transform3 YZ=rotate(90,O,Z)*rotate(90,O,X);
+restricted transform3 ZY=rotate(-90,O,X)*YZ;
+restricted transform3 ZX=rotate(-90,O,Z)*rotate(-90,O,Y);
+restricted transform3 XZ=rotate(-90,O,Y)*ZX;
+
+private transform3 flip(transform3 t, triple X, triple Y, triple Z,
+ projection P)
+{
+ static transform3 flip(triple v) {
+ static real s(real x) {return x > 0 ? -1 : 1;}
+ return scale(s(v.x),s(v.y),s(v.z));
+ }
+
+ triple u=unit(P.vector());
+ triple up=unit(perp(P.up,u));
+ bool upright=dot(Z,u) >= 0;
+ if(dot(Y,up) < 0) {
+ t=flip(Y)*t;
+ upright=!upright;
+ }
+ return upright ? t : flip(X)*t;
+}
+
+restricted transform3 XY(projection P=currentprojection)
+{
+ return flip(XY,X,Y,Z,P);
+}
+
+restricted transform3 YX(projection P=currentprojection)
+{
+ return flip(YX,Y,X,Z,P);
+}
+
+restricted transform3 YZ(projection P=currentprojection)
+{
+ return flip(YZ,Y,Z,X,P);
+}
+
+restricted transform3 ZY(projection P=currentprojection)
+{
+ return flip(ZY,Z,Y,X,P);
+}
+
+restricted transform3 ZX(projection P=currentprojection)
+{
+ return flip(ZX,Z,X,Y,P);
+}
+
+restricted transform3 XZ(projection P=currentprojection)
+{
+ return flip(XZ,X,Z,Y,P);
+}
+
+// Transform3 that projects in direction dir onto plane with normal n
+// through point O.
+transform3 planeproject(triple n, triple O=O, triple dir=n)
+{
+ real a=n.x, b=n.y, c=n.z;
+ real u=dir.x, v=dir.y, w=dir.z;
+ real delta=1.0/(a*u+b*v+c*w);
+ real d=-(a*O.x+b*O.y+c*O.z)*delta;
+ return new real[][] {
+ {(b*v+c*w)*delta,-b*u*delta,-c*u*delta,-d*u},
+ {-a*v*delta,(a*u+c*w)*delta,-c*v*delta,-d*v},
+ {-a*w*delta,-b*w*delta,(a*u+b*v)*delta,-d*w},
+ {0,0,0,1}
+ };
+}
+
+// Transform3 that projects in direction dir onto plane defined by p.
+transform3 planeproject(path3 p, triple dir=O)
+{
+ triple n=normal(p);
+ return planeproject(n,point(p,0),dir == O ? n : dir);
+}
+
+// Transform for projecting onto plane through point O with normal cross(u,v).
+transform transform(triple u, triple v, triple O=O,
+ projection P=currentprojection)
+{
+ transform3 t=P.t;
+ static real[] O={0,0,0,1};
+ real[] tO=t*O;
+ real tO3=tO[3];
+ real factor=1/tO3^2;
+ real[] x=(tO3*t[0]-tO[0]*t[3])*factor;
+ real[] y=(tO3*t[1]-tO[1]*t[3])*factor;
+ triple x=(x[0],x[1],x[2]);
+ triple y=(y[0],y[1],y[2]);
+ u=unit(u);
+ v=unit(v);
+ return (0,0,dot(u,x),dot(v,x),dot(u,y),dot(v,y));
+}
+
+// Project Label onto plane through point O with normal cross(u,v).
+Label project(Label L, triple u, triple v, triple O=O,
+ projection P=currentprojection) {
+ Label L=L.copy();
+ L.position=project(O,P.t);
+ L.transform(transform(u,v,O,P));
+ return L;
+}
+
+path3 operator cast(guide3 g) {return solve(g);}
+path3 operator cast(triple v) {return path3(v);}
+
+guide3[] operator cast(triple[] v)
+{
+ return sequence(new guide3(int i) {return v[i];},v.length);
+}
+
+path3[] operator cast(triple[] v)
+{
+ return sequence(new path3(int i) {return v[i];},v.length);
+}
+
+path3[] operator cast(guide3[] g)
+{
+ return sequence(new path3(int i) {return solve(g[i]);},g.length);
+}
+
+guide3[] operator cast(path3[] g)
+{
+ return sequence(new guide3(int i) {return g[i];},g.length);
+}
+
+void write(file file, string s="", explicit guide3[] x, suffix suffix=none)
+{
+ write(file,s,(path3[]) x,suffix);
+}
+
+void write(string s="", explicit guide3[] x, suffix suffix=endl)
+{
+ write(stdout,s,(path3[]) x,suffix);
+}
+
+triple point(explicit guide3 g, int t) {
+ flatguide3 f;
+ g(f);
+ int n=f.size();
+ return f.nodes[adjustedIndex(t,n,f.cyclic())];
+}
+
+triple[] dirSpecifier(guide3 g, int t)
+{
+ flatguide3 f;
+ g(f);
+ int n=f.size();
+ checkEmpty(n);
+ if(f.cyclic()) t=t % n;
+ else if(t < 0 || t >= n-1) return new triple[];
+ return new triple[] {f.out[t].dir,f.in[t].dir};
+}
+
+triple[] controlSpecifier(guide3 g, int t) {
+ flatguide3 f;
+ g(f);
+ int n=f.size();
+ checkEmpty(n);
+ if(f.cyclic()) t=t % n;
+ else if(t < 0 || t >= n-1) return new triple[];
+ control c=f.control[t];
+ if(c.active) return new triple[] {c.post,c.pre};
+ else return new triple[];
+}
+
+tensionSpecifier tensionSpecifier(guide3 g, int t)
+{
+ flatguide3 f;
+ g(f);
+ int n=f.size();
+ checkEmpty(n);
+ if(f.cyclic()) t=t % n;
+ else if(t < 0 || t >= n-1) return operator tension(1,1,false);
+ Tension T=f.Tension[t];
+ return operator tension(T.out,T.in,T.atLeast);
+}
+
+real[] curlSpecifier(guide3 g, int t)
+{
+ flatguide3 f;
+ g(f);
+ int n=f.size();
+ checkEmpty(n);
+ if(f.cyclic()) t=t % n;
+ else if(t < 0 || t >= n-1) return new real[];
+ return new real[] {f.out[t].gamma,f.in[t].gamma};
+}
+
+guide3 reverse(guide3 g)
+{
+ flatguide3 f;
+ bool cyclic=cyclic(g);
+ g(f);
+
+ if(f.precyclic())
+ return reverse(solve(g));
+
+ int n=f.size();
+ checkEmpty(n);
+ guide3 G;
+ if(n >= 0) {
+ int start=cyclic ? n : n-1;
+ for(int i=start; i > 0; --i) {
+ G=G..f.nodes[i];
+ control c=f.control[i-1];
+ if(c.active)
+ G=G..operator controls(c.pre,c.post);
+ else {
+ dir in=f.in[i-1];
+ triple d=in.dir;
+ if(d != O) G=G..operator spec(-d,JOIN_OUT);
+ else if(in.Curl) G=G..operator curl(in.gamma,JOIN_OUT);
+ dir out=f.out[i-1];
+ triple d=out.dir;
+ if(d != O) G=G..operator spec(-d,JOIN_IN);
+ else if(out.Curl) G=G..operator curl(out.gamma,JOIN_IN);
+ }
+ }
+ if(cyclic) G=G..cycle;
+ else G=G..f.nodes[0];
+ }
+ return G;
+}
+
+triple intersectionpoint(path3 p, path3 q, real fuzz=-1)
+{
+ real[] t=intersect(p,q,fuzz);
+ if(t.length == 0) abort("paths do not intersect");
+ return point(p,t[0]);
+}
+
+// return an array containing all intersection points of p and q
+triple[] intersectionpoints(path3 p, path3 q, real fuzz=-1)
+{
+ real[][] t=intersections(p,q,fuzz);
+ return sequence(new triple(int i) {return point(p,t[i][0]);},t.length);
+}
+
+triple[] intersectionpoints(explicit path3[] p, explicit path3[] q,
+ real fuzz=-1)
+{
+ triple[] v;
+ for(int i=0; i < p.length; ++i)
+ for(int j=0; j < q.length; ++j)
+ v.append(intersectionpoints(p[i],q[j],fuzz));
+ return v;
+}
+
+path3 operator &(path3 p, cycleToken tok)
+{
+ int n=length(p);
+ if(n < 0) return nullpath3;
+ triple a=point(p,0);
+ triple b=point(p,n);
+ return subpath(p,0,n-1)..controls postcontrol(p,n-1) and precontrol(p,n)..
+ cycle;
+}
+
+// return the point on path3 p at arclength L
+triple arcpoint(path3 p, real L)
+{
+ return point(p,arctime(p,L));
+}
+
+// return the point on path3 p at arclength L
+triple arcpoint(path3 p, real L)
+{
+ return point(p,arctime(p,L));
+}
+
+// return the direction on path3 p at arclength L
+triple arcdir(path3 p, real L)
+{
+ return dir(p,arctime(p,L));
+}
+
+// return the time on path3 p at the relative fraction l of its arclength
+real reltime(path3 p, real l)
+{
+ return arctime(p,l*arclength(p));
+}
+
+// return the point on path3 p at the relative fraction l of its arclength
+triple relpoint(path3 p, real l)
+{
+ return point(p,reltime(p,l));
+}
+
+// return the direction of path3 p at the relative fraction l of its arclength
+triple reldir(path3 p, real l)
+{
+ return dir(p,reltime(p,l));
+}
+
+// return the point on path3 p at half of its arclength
+triple midpoint(path3 p)
+{
+ return relpoint(p,0.5);
+}
+
+real relative(Label L, path3 g)
+{
+ return L.position.relative ? reltime(g,L.relative()) : L.relative();
+}
+
+// return the linear transformation that maps X,Y,Z to u,v,w.
+transform3 transform3(triple u, triple v, triple w=cross(u,v))
+{
+ return new real[][] {
+ {u.x,v.x,w.x,0},
+ {u.y,v.y,w.y,0},
+ {u.z,v.z,w.z,0},
+ {0,0,0,1}
+ };
+}
+
+// return the rotation that maps Z to a unit vector u about cross(u,Z),
+transform3 align(triple u)
+{
+ real a=u.x;
+ real b=u.y;
+ real c=u.z;
+ real d=a^2+b^2;
+
+ if(d != 0) {
+ d=sqrt(d);
+ real e=1/d;
+ return new real[][] {
+ {-b*e,-a*c*e,a,0},
+ {a*e,-b*c*e,b,0},
+ {0,d,c,0},
+ {0,0,0,1}};
+ }
+ return c >= 0 ? identity(4) : diagonal(1,-1,-1,1);
+}
+
+// return a rotation that maps X,Y to the projection plane.
+transform3 transform3(projection P)
+{
+ triple v=unit(P.oblique ? P.camera : P.vector());
+ triple u=unit(perp(P.up,v));
+ if(u == O) u=cross(perp(v),v);
+ return transform3(cross(u,v),u);
+}
+
+triple[] triples(real[] x, real[] y, real[] z)
+{
+ if(x.length != y.length || x.length != z.length)
+ abort("arrays have different lengths");
+ return sequence(new triple(int i) {return (x[i],y[i],z[i]);},x.length);
+}
+
+path3[] operator cast(path3 p)
+{
+ return new path3[] {p};
+}
+
+path3[] operator cast(guide3 g)
+{
+ return new path3[] {(path3) g};
+}
+
+path3[] operator ^^ (path3 p, path3 q)
+{
+ return new path3[] {p,q};
+}
+
+path3[] operator ^^ (path3 p, explicit path3[] q)
+{
+ return concat(new path3[] {p},q);
+}
+
+path3[] operator ^^ (explicit path3[] p, path3 q)
+{
+ return concat(p,new path3[] {q});
+}
+
+path3[] operator ^^ (explicit path3[] p, explicit path3[] q)
+{
+ return concat(p,q);
+}
+
+path3[] operator * (transform3 t, explicit path3[] p)
+{
+ return sequence(new path3(int i) {return t*p[i];},p.length);
+}
+
+triple[] operator * (transform3 t, triple[] v)
+{
+ return sequence(new triple(int i) {return t*v[i];},v.length);
+}
+
+triple min(explicit path3[] p)
+{
+ checkEmpty(p.length);
+ triple minp=min(p[0]);
+ for(int i=1; i < p.length; ++i)
+ minp=minbound(minp,min(p[i]));
+ return minp;
+}
+
+triple max(explicit path3[] p)
+{
+ checkEmpty(p.length);
+ triple maxp=max(p[0]);
+ for(int i=1; i < p.length; ++i)
+ maxp=maxbound(maxp,max(p[i]));
+ return maxp;
+}
+
+typedef guide3 interpolate3(... guide3[]);
+
+path3 randompath3(int n, bool cumulate=true, interpolate3 join=operator ..)
+{
+ guide3 g;
+ triple w;
+ for(int i=0; i <= n; ++i) {
+ triple z=(unitrand()-0.5,unitrand()-0.5,unitrand()-0.5);
+ if(cumulate) w += z;
+ else w=z;
+ g=join(g,w);
+ }
+ return g;
+}
+
+path3[] box(triple v1, triple v2)
+{
+ return
+ (v1.x,v1.y,v1.z)--
+ (v1.x,v1.y,v2.z)--
+ (v1.x,v2.y,v2.z)--
+ (v1.x,v2.y,v1.z)--
+ (v1.x,v1.y,v1.z)--
+ (v2.x,v1.y,v1.z)--
+ (v2.x,v1.y,v2.z)--
+ (v2.x,v2.y,v2.z)--
+ (v2.x,v2.y,v1.z)--
+ (v2.x,v1.y,v1.z)^^
+ (v2.x,v2.y,v1.z)--
+ (v1.x,v2.y,v1.z)^^
+ (v1.x,v2.y,v2.z)--
+ (v2.x,v2.y,v2.z)^^
+ (v2.x,v1.y,v2.z)--
+ (v1.x,v1.y,v2.z);
+}
+
+restricted path3[] unitbox=box(O,(1,1,1));
+restricted path3 unitcircle3=X..Y..-X..-Y..cycle;
+restricted path3 unitsquare3=O--X--X+Y--Y--cycle;
+
+path3 circle(triple c, real r, triple normal=Z)
+{
+ path3 p=scale3(r)*unitcircle3;
+ if(normal != Z)
+ p=align(unit(normal))*p;
+ return shift(c)*p;
+}
+
+// return an arc centered at c from triple v1 to v2 (assuming |v2-c|=|v1-c|),
+// drawing in the given direction.
+// The normal must be explicitly specified if c and the endpoints are colinear.
+path3 arc(triple c, triple v1, triple v2, triple normal=O, bool direction=CCW)
+{
+ v1 -= c;
+ real r=abs(v1);
+ v1=unit(v1);
+ v2=unit(v2-c);
+
+ if(normal == O) {
+ normal=cross(v1,v2);
+ if(normal == O) abort("explicit normal required for these endpoints");
+ }
+
+ transform3 T=align(unit(normal));
+ transform3 Tinv=transpose(T);
+ v1=Tinv*v1;
+ v2=Tinv*v2;
+
+ string invalidnormal="invalid normal vector";
+ real fuzz=sqrtEpsilon*max(abs(v1),abs(v2));
+ if(abs(v1.z) > fuzz || abs(v2.z) > fuzz)
+ abort(invalidnormal);
+
+ real[] t1=intersect(unitcircle3,O--2*(v1.x,v1.y,0));
+ real[] t2=intersect(unitcircle3,O--2*(v2.x,v2.y,0));
+
+ if(t1.length == 0 || t2.length == 0)
+ abort(invalidnormal);
+
+ real t1=t1[0];
+ real t2=t2[0];
+ int n=length(unitcircle3);
+ if(t1 >= t2 && direction) t1 -= n;
+ if(t2 >= t1 && !direction) t2 -= n;
+
+ return shift(c)*scale3(r)*T*subpath(unitcircle3,t1,t2);
+}
+
+// return an arc centered at c with radius r from c+r*dir(theta1,phi1) to
+// c+r*dir(theta2,phi2) in degrees, drawing in the given direction
+// relative to the normal vector cross(dir(theta1,phi1),dir(theta2,phi2)).
+// The normal must be explicitly specified if c and the endpoints are colinear.
+path3 arc(triple c, real r, real theta1, real phi1, real theta2, real phi2,
+ triple normal=O, bool direction)
+{
+ return arc(c,c+r*dir(theta1,phi1),c+r*dir(theta2,phi2),normal,direction);
+}
+
+// return an arc centered at c with radius r from c+r*dir(theta1,phi1) to
+// c+r*dir(theta2,phi2) in degrees, drawing drawing counterclockwise
+// relative to the normal vector cross(dir(theta1,phi1),dir(theta2,phi2))
+// iff theta2 > theta1 or (theta2 == theta1 and phi2 >= phi1).
+// The normal must be explicitly specified if c and the endpoints are colinear.
+path3 arc(triple c, real r, real theta1, real phi1, real theta2, real phi2,
+ triple normal=O)
+{
+ return arc(c,r,theta1,phi1,theta2,phi2,normal,
+ theta2 > theta1 || (theta2 == theta1 && phi2 >= phi1) ? CCW : CW);
+}
+
+private real epsilon=1000*realEpsilon;
+
+// Return a representation of the plane through point O with normal cross(u,v).
+path3 plane(triple u, triple v, triple O=O)
+{
+ return O--O+u--O+u+v--O+v--cycle;
+}
+
+triple size3(frame f)
+{
+ return max3(f)-min3(f);
+}
+
+// PRC/OpenGL support
+
+include three_light;
+
+void draw(frame f, path3 g, material p=currentpen, light light=nolight,
+ projection P=currentprojection);
+
+void begingroup3(picture pic=currentpicture)
+{
+ pic.add(new void(frame f, transform3, picture opic, projection) {
+ if(opic != null)
+ begingroup(opic);
+ },true);
+}
+
+void endgroup3(picture pic=currentpicture)
+{
+ pic.add(new void(frame f, transform3, picture opic, projection) {
+ if(opic != null)
+ endgroup(opic);
+ },true);
+}
+
+void addPath(picture pic, path3 g, pen p)
+{
+ if(size(g) > 0)
+ pic.addBox(min(g),max(g),min3(p),max3(p));
+}
+
+include three_surface;
+include three_margins;
+
+void draw(picture pic=currentpicture, Label L="", path3 g,
+ align align=NoAlign, material p=currentpen, margin3 margin=NoMargin3,
+ light light=nolight)
+{
+ pen q=(pen) p;
+ pic.add(new void(frame f, transform3 t, picture pic, projection P) {
+ path3 G=margin(t*g,q).g;
+ if(is3D()) {
+ draw(f,G,p,light,null);
+ if(pic != null && size(G) > 0) {
+ pic.addPoint(min(G,P.t));
+ pic.addPoint(max(G,P.t));
+ }
+ }
+ if(pic != null)
+ draw(pic,project(G,P),q);
+ },true);
+ Label L=L.copy();
+ L.align(align);
+ if(L.s != "") {
+ L.p(q);
+ label(pic,L,g);
+ }
+ addPath(pic,g,q);
+}
+
+include three_arrows;
+
+draw=new void(frame f, path3 g, material p=currentpen,
+ light light=nolight, projection P=currentprojection) {
+ pen q=(pen) p;
+ if(is3D()) {
+ p=material(p,(p.granularity >= 0) ? p.granularity : linegranularity);
+ void drawthick(path3 g) {
+ if(settings.thick) {
+ real width=linewidth(q);
+ if(width > 0) {
+ surface s=tube(g,width);
+ int L=length(g);
+ if(L >= 0) {
+ if(!cyclic(g)) {
+ real r=0.5*width;
+ real linecap=linecap(q);
+ transform3 scale3r=scale3(r);
+ surface cap;
+ triple dirL=dir(g,L);
+ triple dir0=dir(g,0);
+ if(linecap == 0)
+ cap=scale(r,r,1)*unitdisk;
+ else if(linecap == 1)
+ cap=scale3r*((dir0 == O || dirL == O) ?
+ unitsphere : unithemisphere);
+ else if(linecap == 2) {
+ cap=scale3r*unitcylinder;
+ cap.append(scale3r*shift(Z)*unitdisk);
+ }
+ s.append(shift(point(g,0))*align(-dir0)*cap);
+ s.append(shift(point(g,L))*align(dirL)*cap);
+ }
+ if(opacity(q) == 1) _draw(f,g,q);
+ }
+ for(int i=0; i < s.s.length; ++i)
+ draw3D(f,s.s[i],p,light);
+ } else _draw(f,g,q);
+ } else _draw(f,g,q);
+ }
+ string type=linetype(adjust(q,arclength(g),cyclic(g)));
+ if(length(type) == 0) drawthick(g);
+ else {
+ real[] dash=(real[]) split(type," ");
+ if(sum(dash) > 0) {
+ dash.cyclic(true);
+ real offset=offset(q);
+ real L=arclength(g);
+ int i=0;
+ real l=offset;
+ while(l <= L) {
+ real t1=arctime(g,l);
+ l += dash[i];
+ real t2=arctime(g,min(l,L));
+ drawthick(subpath(g,t1,t2));
+ ++i;
+ l += dash[i];
+ ++i;
+ }
+ }
+ }
+ } else draw(f,project(g,P),q);
+};
+
+void draw(frame f, explicit path3[] g, material p=currentpen,
+ light light=nolight, projection P=currentprojection)
+{
+ for(int i=0; i < g.length; ++i) draw(f,g[i],p,light,P);
+}
+
+void draw(picture pic=currentpicture, explicit path3[] g,
+ material p=currentpen, margin3 margin=NoMargin3, light light=nolight)
+{
+ for(int i=0; i < g.length; ++i) draw(pic,g[i],p,margin,light);
+}
+
+void draw(picture pic=currentpicture, Label L="", path3 g,
+ align align=NoAlign, material p=currentpen, arrowbar3 arrow,
+ arrowbar3 bar=None, margin3 margin=NoMargin3, light light=nolight,
+ light arrowheadlight=currentlight)
+{
+ begingroup3(pic);
+ bool drawpath=arrow(pic,g,p,margin,light,arrowheadlight);
+ if(bar(pic,g,p,margin,light,arrowheadlight) && drawpath)
+ draw(pic,L,g,align,p,margin,light);
+ endgroup3(pic);
+ label(pic,L,g,align,(pen) p);
+}
+
+void draw(frame f, path3 g, material p=currentpen, arrowbar3 arrow,
+ light light=nolight, light arrowheadlight=currentlight,
+ projection P=currentprojection)
+{
+ picture pic;
+ if(arrow(pic,g,p,NoMargin3,light,arrowheadlight))
+ draw(f,g,p,light,P);
+ add(f,pic.fit());
+}
+
+void add(picture pic=currentpicture, void d(picture,transform3),
+ bool exact=false)
+{
+ pic.add(d,exact);
+}
+
+// Fit the picture src using the identity transformation (so user
+// coordinates and truesize coordinates agree) and add it about the point
+// position to picture dest.
+void add(picture dest, picture src, triple position, bool group=true,
+ bool above=true)
+{
+ dest.add(new void(picture f, transform3 t) {
+ f.add(shift(t*position)*src,group,above);
+ });
+}
+
+void add(picture src, triple position, bool group=true, bool above=true)
+{
+ add(currentpicture,src,position,group,above);
+}
+
+// Align an arrow pointing to b from the direction dir. The arrow is
+// 'length' PostScript units long.
+void arrow(picture pic=currentpicture, Label L="", triple b, triple dir,
+ real length=arrowlength, align align=NoAlign,
+ pen p=currentpen, arrowbar3 arrow=Arrow3, margin3 margin=EndMargin3,
+ light light=nolight, light arrowheadlight=currentlight)
+{
+ Label L=L.copy();
+ if(L.defaultposition) L.position(0);
+ L.align(L.align,dir);
+ L.p(p);
+ picture opic;
+ marginT3 margin=margin(b--b,p); // Extract margin.begin and margin.end
+ triple a=(margin.begin+length+margin.end)*unit(dir);
+ draw(opic,L,a--O,align,p,arrow,margin,light,arrowheadlight);
+ add(pic,opic,b);
+}
+
+void arrow(picture pic=currentpicture, Label L="", triple b, pair dir,
+ real length=arrowlength, align align=NoAlign,
+ pen p=currentpen, arrowbar3 arrow=Arrow3, margin3 margin=EndMargin3,
+ light light=nolight, light arrowheadlight=currentlight,
+ projection P=currentprojection)
+{
+ arrow(pic,L,b,invert(dir,b,P),length,align,p,arrow,margin,light,
+ arrowheadlight);
+}
+
+triple min3(picture pic, projection P=currentprojection)
+{
+ return pic.min3(P);
+}
+
+triple max3(picture pic, projection P=currentprojection)
+{
+ return pic.max3(P);
+}
+
+triple size3(picture pic, bool user=false, projection P=currentprojection)
+{
+ transform3 t=pic.calculateTransform3(P);
+ triple M=pic.max(t);
+ triple m=pic.min(t);
+ if(!user) return M-m;
+ t=inverse(t);
+ return t*M-t*m;
+}
+
+triple point(frame f, triple dir)
+{
+ triple m=min3(f);
+ triple M=max3(f);
+ return m+realmult(rectify(dir),M-m);
+}
+
+triple point(picture pic=currentpicture, triple dir, bool user=true,
+ projection P=currentprojection)
+{
+ triple v=pic.userMin+realmult(rectify(dir),pic.userMax-pic.userMin);
+ return user ? v : pic.calculateTransform3(P)*v;
+}
+
+triple truepoint(picture pic=currentpicture, triple dir, bool user=true,
+ projection P=currentprojection)
+{
+ transform3 t=pic.calculateTransform3(P);
+ triple m=pic.min(t);
+ triple M=pic.max(t);
+ triple v=m+realmult(rectify(dir),M-m);
+ return user ? inverse(t)*v : v;
+}
+
+void add(picture dest=currentpicture, object src, pair position=0, pair align=0,
+ bool group=true, filltype filltype=NoFill, bool above=true)
+{
+ if(prc())
+ label(dest,src,position,align);
+ else if(settings.render == 0)
+ plain.add(dest,src,position,align,group,filltype,above);
+}
+
+string cameralink(string label, string text="View Parameters")
+{
+ if(!prc() || Link == null) return "";
+ return Link(label,text,"3Dgetview");
+}
+
+private struct viewpoint {
+ triple target,camera,up;
+ real angle;
+ void operator init(string s) {
+ s=replace(s,new string[][] {{" ",","},{"}{",","},{"{",""},{"}",""},});
+ string[] S=split(s,",");
+ target=((real) S[0],(real) S[1],(real) S[2])*cm;
+ camera=target+(real) S[6]*((real) S[3],(real) S[4],(real) S[5])*cm;
+ triple u=unit(target-camera);
+ triple w=unit(Z-u.z*u);
+ up=rotate((real) S[7],O,u)*w;
+ angle=S[8] == "" ? 30 : (real) S[8];
+ }
+}
+
+projection perspective(string s)
+{
+ viewpoint v=viewpoint(s);
+ projection P=perspective(v.camera,v.up,v.target);
+ P.angle=v.angle;
+ P.absolute=true;
+ return P;
+}
+
+private string format(real x)
+{
+ // Work around movie15.sty division by zero bug;
+ // e.g. u=unit((1e-10,1e-10,0.9));
+ if(abs(x) < 1e-9) x=0;
+ assert(abs(x) < 1e18,"Number too large: "+string(x));
+ return format("%.18f",x,"C");
+}
+
+private string format(triple v, string sep=" ")
+{
+ return format(v.x)+sep+format(v.y)+sep+format(v.z);
+}
+
+private string format(pen p)
+{
+ real[] c=colors(rgb(p));
+ return format((c[0],c[1],c[2]));
+}
+
+private string[] file3;
+
+private string projection(bool infinity, real viewplanesize)
+{
+ return "activeCamera=scene.cameras.getByIndex(0);
+function asyProjection() {"+
+ (infinity ? "activeCamera.projectionType=activeCamera.TYPE_ORTHOGRAPHIC;" :
+ "activeCamera.projectionType=activeCamera.TYPE_PERSPECTIVE;")+"
+activeCamera.viewPlaneSize="+string(viewplanesize)+";
+activeCamera.binding=activeCamera.BINDING_VERTICAL;
+}
+
+asyProjection();
+
+handler=new CameraEventHandler();
+runtime.addEventHandler(handler);
+handler.onEvent=function(event)
+{
+ asyProjection();
+ scene.update();
+}";
+}
+
+string lightscript(light light) {
+ string script="for(var i=scene.lights.count-1; i >= 0; i--)
+ scene.lights.removeByIndex(i);"+'\n\n';
+ for(int i=0; i < light.position.length; ++i) {
+ string Li="L"+string(i);
+ real[] diffuse=light.diffuse[i];
+ script += Li+"=scene.createLight();"+'\n'+
+ Li+".direction.set("+format(-light.position[i],",")+");"+'\n'+
+ Li+".color.set("+format((diffuse[0],diffuse[1],diffuse[2]),",")+");"+'\n';
+ }
+ // Work around initialization bug in Adobe Reader 8.0:
+ return script +"
+scene.lightScheme=scene.LIGHT_MODE_HEADLAMP;
+scene.lightScheme=scene.LIGHT_MODE_FILE;
+";
+}
+
+void writeJavaScript(string name, string preamble, string script)
+{
+ file out=output(name);
+ write(out,preamble);
+ if(script != "") {
+ file in=input(script);
+ while(true) {
+ string line=in;
+ if(eof(in)) break;
+ write(out,line,endl);
+ }
+ }
+ close(out);
+ if(settings.verbose > 1) write("Wrote "+name);
+ if(!settings.inlinetex)
+ file3.push(name);
+}
+
+pair viewportmargin(projection P, real width, real height)
+{
+ pair viewportmargin=viewportmargin;
+ real xmargin=viewportmargin.x;
+ real ymargin=viewportmargin.y;
+ if(xmargin <= 0) xmargin=max(0.5*(viewportsize.x-width),0);
+ if(ymargin <= 0) ymargin=max(0.5*(viewportsize.y-height),0);
+ viewportmargin=(xmargin,ymargin);
+ if(P.infinity) return viewportmargin;
+ return (max(viewportmargin.x,viewportmargin.y),viewportmargin.y);
+}
+
+string embed3D(string label="", string text=label, string prefix,
+ frame f, string format="",
+ real width=0, real height=0, real angle=30,
+ string options="", string script="",
+ pen background=white, light light=currentlight,
+ projection P=currentprojection)
+{
+ if(!prc(format) || Embed == null) return "";
+
+ if(width == 0) width=settings.paperwidth;
+ if(height == 0) height=settings.paperheight;
+
+ if(script == "") script=defaultembed3Dscript;
+
+ // Adobe Reader doesn't appear to support user-specified viewport lights.
+ string lightscript=light.on() && !light.viewport ? lightscript(light) : "";
+
+ triple lambda=max3(f)-min3(f);
+ pair viewportmargin=viewportmargin(P,lambda.x,lambda.y);
+ real viewplanesize=(viewportfactor*lambda.y+2*viewportmargin.y)/cm;
+ string name=prefix+".js";
+ writeJavaScript(name,lightscript+projection(P.infinity,viewplanesize),script);
+
+ shipout3(prefix,f);
+
+ prefix += ".prc";
+ if(!settings.inlinetex)
+ file3.push(prefix);
+
+ triple v=P.vector()/cm;
+ triple u=unit(v);
+ triple w=Z-u.z*u;
+ real roll;
+ if(abs(w) > sqrtEpsilon) {
+ w=unit(w);
+ triple up=unit(perp(P.up,u));
+ roll=degrees(acos1(dot(up,w)))*sgn(dot(cross(up,w),u));
+ } else roll=0;
+
+ string options3=light.viewport ? "3Dlights=Headlamp" : "3Dlights=File";
+ if(defaultembed3Doptions != "") options3 += ","+defaultembed3Doptions;
+ if((settings.render < 0 || !settings.embed) && settings.auto3D)
+ options3 += ",poster";
+ options3 += ",text="+text+",label="+label+
+ ",toolbar="+(settings.toolbar ? "true" : "false")+
+ ",3Daac="+format(P.absolute ? P.angle : angle)+
+ ",3Dc2c="+format(u)+
+ ",3Dcoo="+format(P.target/cm)+
+ ",3Droll="+format(roll)+
+ ",3Droo="+format(abs(v))+
+ ",3Dbg="+format(background);
+ if(options != "") options3 += ","+options;
+ if(name != "") options3 += ",3Djscript="+stripdirectory(name);
+
+ return Embed(stripdirectory(prefix),options3,width+2*viewportmargin.x,
+ height+2*viewportmargin.y);
+}
+
+object embed(string label="", string text=label,
+ string prefix=defaultfilename,
+ frame f, string format="",
+ real width=0, real height=0, real angle=30,
+ string options="", string script="",
+ pen background=white, light light=currentlight,
+ projection P=currentprojection)
+{
+ object F;
+
+ if(is3D(format))
+ F.L=embed3D(label,text,prefix,f,format,width,height,angle,options,script,
+ background,light,P);
+ else
+ F.f=f;
+ return F;
+}
+
+object embed(string label="", string text=label,
+ string prefix=defaultfilename,
+ picture pic, string format="",
+ real xsize=pic.xsize, real ysize=pic.ysize,
+ bool keepAspect=pic.keepAspect, bool view=true, string options="",
+ string script="", real angle=0, pen background=white,
+ light light=currentlight, projection P=currentprojection)
+{
+ object F;
+ real xsize3=pic.xsize3, ysize3=pic.ysize3, zsize3=pic.zsize3;
+ bool warn=true;
+ transform3 modelview;
+
+ if(xsize3 == 0 && ysize3 == 0 && zsize3 == 0) {
+ xsize3=ysize3=zsize3=max(xsize,ysize);
+ warn=false;
+ }
+
+ projection P=P.copy();
+
+ if(!P.autoadjust && !P.absolute && P.showtarget)
+ draw(pic,P.target,nullpen);
+
+ transform3 t=pic.scaling(xsize3,ysize3,zsize3,keepAspect,warn);
+ bool adjusted=false;
+ transform3 tinv=inverse(t);
+ triple m=pic.min(t);
+ triple M=pic.max(t);
+
+ if(!P.absolute) {
+ P=t*P;
+ if(P.autoadjust || P.center) {
+ bool recalculate=false;
+ if(P.center || P.target.x < m.x ||
+ P.target.y < m.y ||
+ P.target.z < m.z ||
+ P.target.x > M.x ||
+ P.target.y > M.y ||
+ P.target.z > M.z) {
+ P.target=0.5*(m+M);
+ recalculate=true;
+ if(!P.center) write("adjusting target to ",tinv*P.target);
+ }
+ if(recalculate) P.calculate();
+ }
+ if(P.autoadjust || P.infinity)
+ adjusted=adjusted | P.adjust(m,M);
+ }
+
+ picture pic2;
+
+ frame f=pic.fit3(t,pic.bounds3.exact ? pic2 : null,P);
+
+ if(!pic.bounds3.exact) {
+ transform3 s=pic.scale3(f,xsize3,ysize3,zsize3,keepAspect);
+ t=s*t;
+ tinv=inverse(t);
+ P=s*P;
+ f=pic.fit3(t,pic2,P);
+ }
+
+ bool is3D=is3D(format);
+ bool scale=xsize != 0 || ysize != 0;
+
+ if(is3D || scale) {
+ pic2.bounds.exact=true;
+ transform s=pic2.scaling(xsize,ysize,keepAspect);
+ pair m2=pic2.min(s);
+ pair M2=pic2.max(s);
+ pair lambda=M2-m2;
+ real width=lambda.x;
+ real height=lambda.y;
+
+ pair viewportmargin=viewportmargin(P,width,height);
+ projection Q;
+ if(!P.absolute) {
+ if(scale) {
+ pair v=(s.xx,s.yy);
+ transform3 T=P.t;
+ pair x=project(X,T);
+ pair y=project(Y,T);
+ pair z=project(Z,T);
+ real f(pair a, pair b) {
+ return b == 0 ? (0.5*(a.x+a.y)) : (b.x^2*a.x+b.y^2*a.y)/(b.x^2+b.y^2);
+ }
+ pic2.erase();
+ t=xscale3(f(v,x))*yscale3(f(v,y))*zscale3(f(v,z))*t;
+ f=pic.fit3(t,is3D ? null : pic2,P);
+ }
+
+ if(P.autoadjust || P.infinity)
+ adjusted=adjusted | P.adjust(min3(f),max3(f));
+
+ if(adjusted && !P.infinity)
+ write("adjusting camera to ",tinv*P.camera);
+
+ modelview=P.modelview();
+ f=modelview*f;
+ P=modelview*P;
+ Q=P.copy();
+ light=modelview*light;
+
+ if(P.infinity) {
+ triple m=min3(f);
+ triple M=max3(f);
+ triple s=(-0.5(m.x+M.x),-0.5*(m.y+M.y),0);
+ f=shift(s)*f; // Eye will be at (0,0,0).
+ } else {
+ // Choose the angle to be just large enough to view the entire image:
+ int maxiterations=100;
+ if(is3D && angle == 0 && !P.infinity) {
+ real h=-0.5*P.target.z;
+ pair r,R;
+ real diff=realMax;
+ pair s;
+ int i;
+ do {
+ r=minratio(f);
+ R=maxratio(f);
+ pair lasts=s;
+ s=r+R;
+ transform3 t=shift(h*s.x,h*s.y,0);
+ f=t*f;
+ P=t*P;
+ diff=abs(s-lasts);
+ ++i;
+ } while (diff > angleprecision && i < maxiterations);
+
+ real aspect=width > 0 ? height/width : 1;
+ angle=anglefactor*max(aTan(-r.x*aspect)+aTan(R.x*aspect),
+ aTan(-r.y)+aTan(R.y));
+ if(viewportmargin.y != 0)
+ angle=2*aTan(Tan(0.5*angle)-viewportmargin.y/P.target.z);
+ }
+ }
+ }
+
+ if(prefix == "") prefix=outprefix();
+ bool prc=prc(format);
+ bool preview=settings.render > 0;
+ if(prc) {
+ // The movie15.sty package cannot handle spaces or dots in filenames.
+ prefix=replace(prefix,new string[][]{{" ","_"},{".","_"}});
+ if(settings.embed || nativeformat() == "pdf")
+ prefix += "+"+(string) file3.length;
+ } else
+ preview=false;
+ if(preview || (!prc && settings.render != 0)) {
+ frame f=f;
+ triple m,M;
+ real zcenter;
+ if(P.absolute) {
+ modelview=P.modelview();
+ f=modelview*f;
+ P=modelview*P;
+ angle=P.angle;
+ m=min3(f);
+ M=max3(f);
+ real r=0.5*abs(M-m);
+ zcenter=0.5*(M.z+m.z);
+ M=(M.x,M.y,zcenter+r);
+ m=(m.x,m.y,zcenter-r);
+ } else {
+ m=min3(f);
+ M=max3(f);
+ zcenter=P.target.z;
+ real d=P.distance(m,M);
+ M=(M.x,M.y,zcenter+d);
+ m=(m.x,m.y,zcenter-d);
+ }
+
+ real factor=viewportfactor-1.0;
+ triple margin=(factor*abs(M.x-m.x),factor*abs(M.y-m.y),0);
+ if(P.infinity)
+ margin += (0,viewportmargin.y,0);
+ M += margin;
+ m -= margin;
+ if(!P.infinity && M.z >= 0) abort("camera too close");
+
+ shipout3(prefix,f,preview ? nativeformat() : format,
+ width+2*viewportmargin.x,height+2*viewportmargin.y,
+ P.infinity ? 0 : angle,m,M,
+ tinv*inverse(modelview)*shift(0,0,zcenter),
+ P.absolute ? (modelview*light).position : light.position,
+ light.diffuse,light.ambient,light.specular,
+ light.viewport,view && !preview);
+ if(!preview) return F;
+ }
+
+ string image;
+ if(preview && settings.embed) {
+ image=prefix;
+ if(settings.inlinetex) image += "_0";
+ image += "."+nativeformat();
+ if(!settings.inlinetex) file3.push(image);
+ image=graphic(image);
+ }
+ if(prc) F.L=embed3D(label,text=image,prefix,f,format,
+ width,height,angle,options,script,background,light,
+ P.absolute ? P : Q);
+ }
+
+ if(!is3D) {
+ transform T=pic2.scaling(xsize,ysize,keepAspect);
+ F.f=pic.fit(scale(t[0][0])*T);
+ add(F.f,pic2.fit(T));
+ }
+
+ return F;
+}
+
+embed3=new object(string prefix, frame f, string format, string options,
+ string script, projection P) {
+ return embed(prefix=prefix,f,format,options,script,P);
+};
+
+currentpicture.fitter=new frame(string prefix, picture pic, string format,
+ real xsize, real ysize,
+ bool keepAspect, bool view,
+ string options, string script, projection P) {
+ frame f;
+ bool empty3=pic.empty3();
+ if(is3D(format) || empty3) add(f,pic.fit2(xsize,ysize,keepAspect));
+ if(!empty3) {
+ bool prc=prc(format);
+ if(!prc && settings.render != 0 && !view) {
+ static int previewcount=0;
+ bool keep=prefix != "";
+ prefix=outprefix(prefix)+"+"+(string) previewcount;
+ ++previewcount;
+ format=nativeformat();
+ if(!keep) file3.push(prefix+"."+format);
+ }
+ object F=embed(prefix=prefix,pic,format,xsize,ysize,keepAspect,view,
+ options,script,P);
+ if(prc)
+ label(f,F.L);
+ else {
+ if(settings.render == 0)
+ add(f,F.f);
+ else if(!view)
+ label(f,graphic(prefix));
+ }
+ }
+ return f;
+};
+
+// Force an array of 3D pictures to be as least as large as picture all.
+void rescale3(picture[] pictures, picture all, projection P=currentprojection)
+{
+ if(!all.empty3()) {
+ transform3 t=inverse(all.calculateTransform3(P)*pictures[0].T3);
+ triple m=t*min3(all);
+ triple M=t*max3(all);
+ for(int i=0; i < pictures.length; ++i) {
+ draw(pictures[i],m,nullpen);
+ draw(pictures[i],M,nullpen);
+ }
+ }
+}
+
+// Force an array of pictures to have a uniform scaling using currenprojection.
+rescale=new void(picture[] pictures) {
+ if(pictures.length == 0) return;
+ picture all;
+ size(all,pictures[0]);
+ for(picture pic : pictures)
+ add(all,pic);
+ rescale2(pictures,all);
+ rescale3(pictures,all);
+};
+
+exitfcn currentexitfunction=atexit();
+
+void exitfunction()
+{
+ if(currentexitfunction != null) currentexitfunction();
+ if(!settings.keep)
+ for(int i=0; i < file3.length; ++i)
+ delete(file3[i]);
+ file3=new string[];
+}
+
+atexit(exitfunction);
diff --git a/Build/source/utils/asymptote/base/three_arrows.asy b/Build/source/utils/asymptote/base/three_arrows.asy
new file mode 100644
index 00000000000..78ee56d9f04
--- /dev/null
+++ b/Build/source/utils/asymptote/base/three_arrows.asy
@@ -0,0 +1,789 @@
+// A transformation that bends points along a path
+transform3 bend(path3 g, real t)
+{
+ triple dir=dir(g,t);
+ triple a=point(g,0), b=postcontrol(g,0);
+ triple c=precontrol(g,1), d=point(g,1);
+ triple dir1=b-a;
+ triple dir2=c-b;
+ triple dir3=d-c;
+
+ triple u = unit(cross(dir1,dir3));
+ real eps=1000*realEpsilon;
+ if(abs(u) < eps) {
+ u = unit(cross(dir1,dir2));
+ if(abs(u) < eps) {
+ u = unit(cross(dir2,dir3));
+ if(abs(u) < eps)
+ // linear segment: use any direction perpendicular to initial direction
+ u = perp(dir1);
+ }
+ }
+ u = unit(perp(u,dir));
+
+ triple w=cross(dir,u);
+ triple q=point(g,t);
+ return new real[][] {
+ {u.x,w.x,dir.x,q.x},
+ {u.y,w.y,dir.y,q.y},
+ {u.z,w.z,dir.z,q.z},
+ {0,0,0,1}
+ };
+}
+
+// bend a point along a path; assumes that p.z is in [0,scale]
+triple bend(triple p, path3 g, real scale)
+{
+ return bend(g,arctime(g,arclength(g)+p.z-scale))*(p.x,p.y,0);
+}
+
+void bend(surface s, path3 g, real L)
+{
+ for(patch p : s.s) {
+ for(int i=0; i < 4; ++i) {
+ for(int j=0; j < 4; ++j) {
+ p.P[i][j]=bend(p.P[i][j],g,L);
+ }
+ }
+ }
+}
+
+void render(path3 s, void f(path3, real))
+{
+ static int maxdepth=ceil(-log(realEpsilon)/log(2))+1;
+ 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);
+ real R=infinity;
+ int nintervals=3;
+ real fuzz=sqrtEpsilon*max(abs(z0),abs(z1));
+ if(S > 0) {
+ --depth;
+ for(int i=0; i <= nintervals; ++i) {
+ R=min(R,radius(z0,c0,c1,z1,i/nintervals));
+ if(S > max(tubegranularity*R,fuzz)) {
+ 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));
+}
+
+surface tube(path3 g, real width)
+{
+ surface tube;
+ real r=0.5*width;
+
+ transform3 t=scale3(r);
+
+ int n=length(g);
+ for(int i=0; i < n; ++i) {
+ real S=straightness(g,i);
+ if(S < sqrtEpsilon*r) {
+ triple v=point(g,i);
+ triple u=point(g,i+1)-v;
+ tube.append(shift(v)*align(unit(u))*scale(r,r,abs(u))*unitcylinder);
+ } else {
+ render(subpath(g,i,i+1),new void(path3 q, real) {
+ real L=arclength(q);
+ surface segment=scale(r,r,L)*unitcylinder;
+ bend(segment,q,L);
+ tube.s.append(segment.s);
+ });
+ }
+
+ if((cyclic(g) || i > 0) && abs(dir(g,i,1)-dir(g,i,-1)) > sqrtEpsilon)
+ tube.append(shift(point(g,i))*t*align(dir(g,i,-1))*unithemisphere);
+ }
+ return tube;
+}
+
+// Refine a noncyclic path3 g so that it approaches its endpoint in
+// geometrically spaced steps.
+path3 approach(path3 g, int n, real radix=3)
+{
+ guide3 G;
+ real L=length(g);
+ real tlast=0;
+ real r=1/radix;
+ for(int i=1; i < n; ++i) {
+ real t=L*(1-r^i);
+ G=G&subpath(g,tlast,t);
+ tlast=t;
+ }
+ return G&subpath(g,tlast,L);
+}
+
+struct arrowhead3
+{
+ arrowhead arrowhead2=DefaultHead;
+ real size(pen p)=arrowsize;
+ real arcsize(pen p)=arcarrowsize;
+ real gap=1;
+ bool splitpath=true;
+
+ surface head(path3 g, position position=EndPoint,
+ pen p=currentpen, real size=0, real angle=arrowangle,
+ filltype filltype=null, bool forwards=true,
+ projection P=currentprojection);
+
+ static surface surface(path3 g, position position, real size,
+ path[] h, pen p, filltype filltype,
+ triple normal, projection P) {
+ bool relative=position.relative;
+ real position=position.position.x;
+ if(relative) position=reltime(g,position);
+ path3 r=subpath(g,position,0);
+ path3 s=subpath(r,arctime(r,size),0);
+ if(filltype == null) filltype=FillDraw(p);
+ bool draw=filltype.type != filltype.Fill;
+ triple v=point(s,length(s));
+ triple N=normal == O ? P.vector() : normal;
+ triple w=unit(v-point(s,0));
+ transform3 t=transform3(w,unit(cross(w,N)));
+ path3[] H=t*path3(h);
+ surface s;
+ real width=linewidth(p);
+ if(filltype != NoFill && filltype.type != filltype.UnFill &&
+ filltype.type != filltype.Draw) {
+ triple n=0.5*width*unit(t*Z);
+ s=surface(shift(n)*H,planar=true);
+ s.append(surface(shift(-n)*H,planar=true));
+ if(!draw)
+ for(path g : h)
+ s.append(shift(-n)*t*extrude(g,width*Z));
+ }
+ if(draw)
+ for(path3 g : H)
+ s.append(tube(g,width));
+ return shift(v)*s;
+ }
+
+ static path project(path3 g, bool forwards, projection P) {
+ path h=project(forwards ? g : reverse(g),P);
+ return shift(-point(h,length(h)))*h;
+ }
+
+ static path[] align(path H, path h) {
+ static real fuzz=1000*realEpsilon;
+ real[][] t=intersections(H,h,fuzz*max(abs(max(h)),abs(min(h))));
+ return rotate(-degrees(point(H,t[0][0])-point(H,t[1][0]),warn=false))*H;
+ }
+}
+
+arrowhead3 DefaultHead3;
+DefaultHead3.head=new surface(path3 g, position position=EndPoint,
+ pen p=currentpen, real size=0,
+ real angle=arrowangle, filltype filltype=null,
+ bool forwards=true,
+ projection P=currentprojection)
+{
+ if(size == 0) size=DefaultHead3.size(p);
+ bool relative=position.relative;
+ real position=position.position.x;
+ if(relative) position=reltime(g,position);
+
+ path3 r=subpath(g,position,0);
+ path3 s=subpath(r,arctime(r,size),0);
+ int n=length(s);
+ bool straight1=n == 1 && straight(g,0);
+ real aspect=Tan(angle);
+ real width=size*aspect;
+ surface head;
+ if(straight1) {
+ triple v=point(s,0);
+ triple u=point(s,1)-v;
+ return shift(v)*align(unit(u))*scale(width,width,size)*unitsolidcone;
+ } else {
+ real remainL=size;
+ bool first=true;
+ for(int i=0; i < n; ++i) {
+ render(subpath(s,i,i+1),new void(path3 q, real) {
+ 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]=(k*p.P[i][j].x,k*p.P[i][j].y,p.P[i][j].z);
+ p.P[i][j]=bend(p.P[i][j],q,l);
+ }
+ }
+ }
+ head.append(segment);
+ remainL -= l;
+ });
+ }
+ }
+ return head;
+};
+
+arrowhead3 HookHead3(real dir=arrowdir, real barb=arrowbarb)
+{
+ arrowhead3 a;
+ a.head=new surface(path3 g, position position=EndPoint,
+ pen p=currentpen, real size=0, real angle=arrowangle,
+ filltype filltype=null, bool forwards=true,
+ projection P=currentprojection) {
+ if(size == 0) size=a.size(p);
+
+ angle=min(angle*arrowhookfactor,45);
+ bool relative=position.relative;
+ real position=position.position.x;
+ if(relative) position=reltime(g,position);
+
+ path3 r=subpath(g,position,0);
+ path3 s=subpath(r,arctime(r,size),0);
+ bool straight1=length(s) == 1 && straight(g,0);
+ path3 H=path3(HookHead(dir,barb).head((0,0)--(0,size),p,size,angle),
+ YZplane);
+ surface head=surface(O,reverse(approach(subpath(H,1,0),7,1.5))&
+ approach(subpath(H,1,2),4,2),Z);
+
+ if(straight1) {
+ triple v=point(s,0);
+ triple u=point(s,1)-v;
+ return shift(v)*align(unit(u))*head;
+ } else {
+ bend(head,s,size);
+ return head;
+ }
+ };
+ a.arrowhead2=HookHead;
+ a.gap=0.7;
+ return a;
+}
+arrowhead3 HookHead3=HookHead3();
+
+arrowhead3 TeXHead3;
+TeXHead3.size=TeXHead.size;
+TeXHead3.arcsize=TeXHead.size;
+TeXHead3.arrowhead2=TeXHead;
+TeXHead3.head=new surface(path3 g, position position=EndPoint,
+ pen p=currentpen, real size=0, real angle=arrowangle,
+ filltype filltype=null, bool forwards=true,
+ projection P=currentprojection)
+{
+ real texsize=TeXHead3.size(p);
+ if(size == 0) size=texsize;
+ bool relative=position.relative;
+ real position=position.position.x;
+ if(relative) position=reltime(g,position);
+
+ path3 r=subpath(g,position,0);
+ path3 s=subpath(r,arctime(r,size),0);
+ bool straight1=length(s) == 1 && straight(g,0);
+
+ surface head=surface(O,approach(subpath(path3(TeXHead.head((0,0)--(0,1),p,
+ size),
+ YZplane),5,0),8,1.5),Z);
+ if(straight1) {
+ triple v=point(s,0);
+ triple u=point(s,1)-v;
+ return shift(v)*align(unit(u))*head;
+ } else {
+ path3 s=subpath(r,arctime(r,size/texsize*arrowsize(p)),0);
+ bend(head,s,size);
+ return head;
+ }
+};
+
+real[] arrowbasepoints(path3 base, path3 left, path3 right)
+{
+ real[][] Tl=transpose(intersections(left,base));
+ real[][] Tr=transpose(intersections(right,base));
+ return new real[] {Tl.length > 0 ? Tl[0][0] : 1,
+ Tr.length > 0 ? Tr[0][0] : 1};
+}
+
+path3 arrowbase(path3 r, triple y, real t, real size)
+{
+ triple perp=2*size*perp(dir(r,t));
+ return size == 0 ? y : y+perp--y-perp;
+}
+
+arrowhead3 DefaultHead2(triple normal=O) {
+ arrowhead3 a;
+ a.head=new surface(path3 g, position position=EndPoint,
+ pen p=currentpen, real size=0,
+ real angle=arrowangle,
+ filltype filltype=null, bool forwards=true,
+ projection P=currentprojection) {
+ if(size == 0) size=a.size(p);
+ path h=a.project(g,forwards,P);
+ path[] H=a.align(DefaultHead.head(h,p,size,angle),h);
+ H=forwards ? yscale(-1)*H : H;
+ return a.surface(g,position,size,H,p,filltype,normal,P);
+ };
+ a.gap=1.01;
+ return a;
+}
+arrowhead3 DefaultHead2=DefaultHead2();
+
+arrowhead3 HookHead2(real dir=arrowdir, real barb=arrowbarb, triple normal=O)
+{
+ arrowhead3 a;
+ a.head=new surface(path3 g, position position=EndPoint,
+ pen p=currentpen, real size=0, real angle=arrowangle,
+ filltype filltype=null, bool forwards=true,
+ projection P=currentprojection) {
+ if(size == 0) size=a.size(p);
+ angle=min(angle*arrowhookfactor,45);
+ path h=a.project(g,forwards,P);
+ path[] H=a.align(HookHead.head(h,p,size,angle),h);
+ H=forwards ? yscale(-1)*H : H;
+ return a.surface(g,position,size,H,p,filltype,normal,P);
+ };
+ a.arrowhead2=HookHead;
+ a.gap=1.01;
+ return a;
+}
+arrowhead3 HookHead2=HookHead2();
+
+arrowhead3 TeXHead2(triple normal=O) {
+ arrowhead3 a;
+ a.head=new surface(path3 g, position position=EndPoint,
+ pen p=currentpen, real size=0,
+ real angle=arrowangle, filltype filltype=null,
+ bool forwards=true, projection P=currentprojection) {
+ if(size == 0) size=a.size(p);
+ path h=a.project(g,forwards,P);
+ h=rotate(-degrees(dir(h,length(h)),warn=false))*h;
+ path[] H=TeXHead.head(h,p,size,angle);
+ H=forwards ? yscale(-1)*H : H;
+ return a.surface(g,position,size,H,p,
+ filltype == null ? TeXHead.defaultfilltype(p) : filltype,
+ normal,P);
+ };
+ a.arrowhead2=TeXHead;
+ a.size=TeXHead.size;
+ a.gap=0.83;
+ a.splitpath=false;
+ return a;
+}
+arrowhead3 TeXHead2=TeXHead2();
+
+private real position(position position, real size, path3 g, bool center)
+{
+ bool relative=position.relative;
+ real position=position.position.x;
+ if(relative) {
+ position *= arclength(g);
+ if(center) position += 0.5*size;
+ position=arctime(g,position);
+ } else if(center)
+ position=arctime(g,arclength(subpath(g,0,position))+0.5*size);
+ return position;
+}
+
+void drawarrow(picture pic, arrowhead3 arrowhead=DefaultHead3,
+ path3 g, material p=currentpen, material arrowheadpen=nullpen,
+ real size=0, real angle=arrowangle, position position=EndPoint,
+ filltype filltype=null, bool forwards=true,
+ margin3 margin=NoMargin3, bool center=false, light light=nolight,
+ light arrowheadlight=currentlight,
+ projection P=currentprojection)
+{
+ pen q=(pen) p;
+ if(filltype != null) {
+ if(arrowheadpen == nullpen && filltype != null)
+ arrowheadpen=filltype.fillpen;
+ if(arrowheadpen == nullpen && filltype != null)
+ arrowheadpen=filltype.drawpen;
+ }
+ if(arrowheadpen == nullpen) arrowheadpen=p;
+ if(size == 0) size=arrowhead.size(q);
+ size=min(arrowsizelimit*arclength(g),size);
+ real position=position(position,size,g,center);
+
+ g=margin(g,q).g;
+ int L=length(g);
+ if(!forwards) {
+ g=reverse(g);
+ position=L-position;
+ }
+ path3 r=subpath(g,position,0);
+ size=min(arrowsizelimit*arclength(r),size);
+ surface head=arrowhead.head(g,position,q,size,angle,filltype,forwards,P);
+ bool endpoint=position > L-sqrtEpsilon;
+ if(arrowhead.splitpath || endpoint) {
+ if(position > 0) {
+ real Size=size*arrowhead.gap;
+ draw(pic,subpath(r,arctime(r,Size),length(r)),p,light);
+ }
+ if(!endpoint)
+ draw(pic,subpath(g,position,L),p,light);
+ } else draw(pic,g,p,light);
+ draw(pic,head,arrowheadpen,arrowheadlight);
+}
+
+void drawarrow2(picture pic, arrowhead3 arrowhead=DefaultHead3,
+ path3 g, material p=currentpen, material arrowheadpen=nullpen,
+ real size=0, real angle=arrowangle, filltype filltype=null,
+ margin3 margin=NoMargin3, light light=nolight,
+ light arrowheadlight=currentlight,
+ projection P=currentprojection)
+{
+ pen q=(pen) p;
+ if(filltype != null) {
+ if(arrowheadpen == nullpen && filltype != null)
+ arrowheadpen=filltype.fillpen;
+ if(arrowheadpen == nullpen && filltype != null)
+ arrowheadpen=filltype.drawpen;
+ }
+ if(arrowheadpen == nullpen) arrowheadpen=p;
+ if(size == 0) size=arrowhead.size(q);
+ g=margin(g,q).g;
+ size=min(arrow2sizelimit*arclength(g),size);
+
+ path3 r=reverse(g);
+ int L=length(g);
+ real Size=size*arrowhead.gap;
+ draw(pic,subpath(r,arctime(r,Size),L-arctime(g,Size)),p,light);
+ draw(pic,arrowhead.head(g,L,q,size,angle,filltype,forwards=true,P),
+ arrowheadpen,arrowheadlight);
+ draw(pic,arrowhead.head(r,L,q,size,angle,filltype,forwards=false,P),
+ arrowheadpen,arrowheadlight);
+}
+
+// Add to picture an estimate of the bounding box contribution of arrowhead
+// using the local slope at endpoint.
+void addArrow(picture pic, arrowhead3 arrowhead, path3 g, pen p, real size,
+ real angle, filltype filltype, real position)
+{
+ triple v=point(g,position);
+ path3 g=v-(size+linewidth(p))*dir(g,position)--v;
+ surface s=arrowhead.head(g,position,p,size,angle);
+ if(s.s.length > 0) {
+ pic.addPoint(v,min(s)-v);
+ pic.addPoint(v,max(s)-v);
+ } else pic.addPoint(v);
+}
+
+picture arrow(arrowhead3 arrowhead=DefaultHead3,
+ path3 g, material p=currentpen, material arrowheadpen=p,
+ real size=0, real angle=arrowangle,
+ filltype filltype=null, position position=EndPoint,
+ bool forwards=true, margin3 margin=NoMargin3,
+ bool center=false, light light=nolight,
+ light arrowheadlight=currentlight)
+{
+ pen q=(pen) p;
+ if(size == 0) size=arrowhead.size(q);
+ picture pic;
+ if(is3D())
+ pic.add(new void(frame f, transform3 t, picture pic2, projection P) {
+ picture opic;
+ drawarrow(opic,arrowhead,t*g,p,arrowheadpen,size,angle,position,
+ filltype,forwards,margin,center,light,arrowheadlight,P);
+ add(f,opic.fit3(identity4,pic2,P));
+ });
+
+ addPath(pic,g,q);
+
+ real position=position(position,size,g,center);
+ path3 G;
+ if(!forwards) {
+ G=reverse(g);
+ position=length(g)-position;
+ } else G=g;
+ addArrow(pic,arrowhead,G,q,size,angle,filltype,position);
+
+ return pic;
+}
+
+picture arrow2(arrowhead3 arrowhead=DefaultHead3,
+ path3 g, material p=currentpen, material arrowheadpen=p,
+ real size=0, real angle=arrowangle, filltype filltype=null,
+ margin3 margin=NoMargin3, light light=nolight,
+ light arrowheadlight=currentlight)
+{
+ pen q=(pen) p;
+ if(size == 0) size=arrowhead.size(q);
+ picture pic;
+
+ if(is3D())
+ pic.add(new void(frame f, transform3 t, picture pic2, projection P) {
+ picture opic;
+ drawarrow2(opic,arrowhead,t*g,p,arrowheadpen,size,angle,filltype,
+ margin,light,arrowheadlight,P);
+ add(f,opic.fit3(identity4,pic2,P));
+ });
+
+ addPath(pic,g,q);
+
+ int L=length(g);
+ addArrow(pic,arrowhead,g,q,size,angle,filltype,L);
+ addArrow(pic,arrowhead,reverse(g),q,size,angle,filltype,L);
+
+ return pic;
+}
+
+void add(picture pic, arrowhead3 arrowhead, real size, real angle,
+ filltype filltype, position position, material arrowheadpen,
+ path3 g, material p, bool forwards=true, margin3 margin,
+ bool center=false, light light, light arrowheadlight)
+{
+ add(pic,arrow(arrowhead,g,p,arrowheadpen,size,angle,filltype,position,
+ forwards,margin,center,light,arrowheadlight));
+ if(!is3D()) {
+ pic.add(new void(frame f, transform3 t, picture pic, projection P) {
+ if(pic != null) {
+ pen q=(pen) p;
+ path3 G=t*g;
+ marginT3 m=margin(G,q);
+ add(pic,arrow(arrowhead.arrowhead2,project(G,P),q,size,angle,
+ filltype == null ?
+ arrowhead.arrowhead2.defaultfilltype
+ ((pen) arrowheadpen) : filltype,position,
+ forwards,TrueMargin(m.begin,m.end),center));
+ }
+ },true);
+ }
+}
+
+void add2(picture pic, arrowhead3 arrowhead, real size, real angle,
+ filltype filltype, material arrowheadpen, path3 g, material p,
+ margin3 margin, light light, light arrowheadlight)
+{
+ add(pic,arrow2(arrowhead,g,p,arrowheadpen,size,angle,filltype,margin,light,
+ arrowheadlight));
+ if(!is3D()) {
+ pic.add(new void(frame f, transform3 t, picture pic, projection P) {
+ if(pic != null) {
+ pen q=(pen) p;
+ path3 G=t*g;
+ marginT3 m=margin(G,q);
+ add(pic,arrow2(arrowhead.arrowhead2,project(G,P),q,size,angle,
+ filltype == null ?
+ arrowhead.arrowhead2.defaultfilltype
+ ((pen) arrowheadpen) : filltype,
+ TrueMargin(m.begin,m.end)));
+ }
+ },true);
+ }
+}
+
+void bar(picture pic, triple a, triple d, triple perp=O,
+ material p=currentpen, light light=nolight)
+{
+ d *= 0.5;
+ perp *= 0.5;
+ pic.add(new void(frame f, transform3 t, picture pic2, projection P) {
+ picture opic;
+ triple A=t*a;
+ triple v=d == O ? abs(perp)*unit(cross(P.vector(),perp)) : d;
+ draw(opic,A-v--A+v,p,light);
+ add(f,opic.fit3(identity4,pic2,P));
+ });
+ triple v=d == O ? cross(currentprojection.vector(),perp) : d;
+ pen q=(pen) p;
+ triple m=min3(q);
+ triple M=max3(q);
+ pic.addPoint(a,-v-m);
+ pic.addPoint(a,-v+m);
+ pic.addPoint(a,v-M);
+ pic.addPoint(a,v+M);
+}
+
+picture bar(triple a, triple dir, triple perp=O, material p=currentpen)
+{
+ picture pic;
+ bar(pic,a,dir,perp,p);
+ return pic;
+}
+
+typedef bool arrowbar3(picture, path3, material, margin3, light, light);
+
+bool Blank(picture, path3, material, margin3, light, light)
+{
+ return false;
+}
+
+bool None(picture, path3, material, margin3, light, light)
+{
+ return true;
+}
+
+arrowbar3 BeginArrow3(arrowhead3 arrowhead=DefaultHead3,
+ real size=0, real angle=arrowangle,
+ filltype filltype=null, position position=BeginPoint,
+ material arrowheadpen=nullpen)
+{
+ return new bool(picture pic, path3 g, material p, margin3 margin,
+ light light, light arrowheadlight) {
+ add(pic,arrowhead,size,angle,filltype,position,arrowheadpen,g,p,
+ forwards=false,margin,light,arrowheadlight);
+ return false;
+ };
+}
+
+arrowbar3 Arrow3(arrowhead3 arrowhead=DefaultHead3,
+ real size=0, real angle=arrowangle,
+ filltype filltype=null, position position=EndPoint,
+ material arrowheadpen=nullpen)
+{
+ return new bool(picture pic, path3 g, material p, margin3 margin,
+ light light, light arrowheadlight) {
+ add(pic,arrowhead,size,angle,filltype,position,arrowheadpen,g,p,margin,
+ light,arrowheadlight);
+ return false;
+ };
+}
+
+arrowbar3 EndArrow3(arrowhead3 arrowhead=DefaultHead3,
+ real size=0, real angle=arrowangle,
+ filltype filltype=null, position position=EndPoint,
+ material arrowheadpen=nullpen)=Arrow3;
+
+arrowbar3 MidArrow3(arrowhead3 arrowhead=DefaultHead3,
+ real size=0, real angle=arrowangle,
+ filltype filltype=null, material arrowheadpen=nullpen)
+{
+ return new bool(picture pic, path3 g, material p, margin3 margin,
+ light light, light arrowheadlight) {
+ add(pic,arrowhead,size,angle,filltype,MidPoint,
+ arrowheadpen,g,p,margin,center=true,light,arrowheadlight);
+ return false;
+ };
+}
+
+arrowbar3 Arrows3(arrowhead3 arrowhead=DefaultHead3,
+ real size=0, real angle=arrowangle,
+ filltype filltype=null, material arrowheadpen=nullpen)
+{
+ return new bool(picture pic, path3 g, material p, margin3 margin,
+ light light, light arrowheadlight) {
+ add2(pic,arrowhead,size,angle,filltype,arrowheadpen,g,p,margin,light,
+ arrowheadlight);
+ return false;
+ };
+}
+
+arrowbar3 BeginArcArrow3(arrowhead3 arrowhead=DefaultHead3,
+ real size=0, real angle=arcarrowangle,
+ filltype filltype=null, position position=BeginPoint,
+ material arrowheadpen=nullpen)
+{
+ return new bool(picture pic, path3 g, material p, margin3 margin,
+ light light, light arrowheadlight) {
+ real size=size == 0 ? arrowhead.arcsize((pen) p) : size;
+ add(pic,arrowhead,size,angle,filltype,position,arrowheadpen,g,p,
+ forwards=false,margin,light,arrowheadlight);
+ return false;
+ };
+}
+
+arrowbar3 ArcArrow3(arrowhead3 arrowhead=DefaultHead3,
+ real size=0, real angle=arcarrowangle,
+ filltype filltype=null, position position=EndPoint,
+ material arrowheadpen=nullpen)
+{
+ return new bool(picture pic, path3 g, material p, margin3 margin,
+ light light, light arrowheadlight) {
+ real size=size == 0 ? arrowhead.arcsize((pen) p) : size;
+ add(pic,arrowhead,size,angle,filltype,position,arrowheadpen,g,p,margin,
+ light,arrowheadlight);
+ return false;
+ };
+}
+
+arrowbar3 EndArcArrow3(arrowhead3 arrowhead=DefaultHead3,
+ real size=0, real angle=arcarrowangle,
+ filltype filltype=null,
+ position position=EndPoint,
+ material arrowheadpen=nullpen)=ArcArrow3;
+
+
+arrowbar3 MidArcArrow3(arrowhead3 arrowhead=DefaultHead3,
+ real size=0, real angle=arcarrowangle,
+ filltype filltype=null, material arrowheadpen=nullpen)
+{
+ return new bool(picture pic, path3 g, material p, margin3 margin,
+ light light, light arrowheadlight) {
+ real size=size == 0 ? arrowhead.arcsize((pen) p) : size;
+ add(pic,arrowhead,size,angle,filltype,MidPoint,arrowheadpen,g,p,margin,
+ center=true,light,arrowheadlight);
+ return false;
+ };
+}
+
+arrowbar3 ArcArrows3(arrowhead3 arrowhead=DefaultHead3,
+ real size=0, real angle=arcarrowangle,
+ filltype filltype=null, material arrowheadpen=nullpen)
+{
+ return new bool(picture pic, path3 g, material p, margin3 margin,
+ light light, light arrowheadlight) {
+ real size=size == 0 ? arrowhead.arcsize((pen) p) : size;
+ add2(pic,arrowhead,size,angle,filltype,arrowheadpen,g,p,margin,light,
+ arrowheadlight);
+ return false;
+ };
+}
+
+arrowbar3 BeginBar3(real size=0, triple dir=O)
+{
+ return new bool(picture pic, path3 g, material p, margin3 margin, light light,
+ light) {
+ real size=size == 0 ? barsize((pen) p) : size;
+ bar(pic,point(g,0),size*unit(dir),size*dir(g,0),p,light);
+ return true;
+ };
+}
+
+arrowbar3 Bar3(real size=0, triple dir=O)
+{
+ return new bool(picture pic, path3 g, material p, margin3 margin, light light,
+ light) {
+ int L=length(g);
+ real size=size == 0 ? barsize((pen) p) : size;
+ bar(pic,point(g,L),size*unit(dir),size*dir(g,L),p,light);
+ return true;
+ };
+}
+
+arrowbar3 EndBar3(real size=0, triple dir=O)=Bar3;
+
+arrowbar3 Bars3(real size=0, triple dir=O)
+{
+ return new bool(picture pic, path3 g, material p, margin3 margin, light light,
+ light) {
+ real size=size == 0 ? barsize((pen) p) : size;
+ BeginBar3(size,dir)(pic,g,p,margin,light,nolight);
+ EndBar3(size,dir)(pic,g,p,margin,light,nolight);
+ return true;
+ };
+}
+
+arrowbar3 BeginArrow3=BeginArrow3(),
+MidArrow3=MidArrow3(),
+Arrow3=Arrow3(),
+EndArrow3=Arrow3(),
+Arrows3=Arrows3(),
+BeginArcArrow3=BeginArcArrow3(),
+MidArcArrow3=MidArcArrow3(),
+ArcArrow3=ArcArrow3(),
+EndArcArrow3=ArcArrow3(),
+ArcArrows3=ArcArrows3(),
+BeginBar3=BeginBar3(),
+Bar3=Bar3(),
+EndBar3=Bar3(),
+Bars3=Bars3();
diff --git a/Build/source/utils/asymptote/base/three_light.asy b/Build/source/utils/asymptote/base/three_light.asy
new file mode 100644
index 00000000000..388c344895a
--- /dev/null
+++ b/Build/source/utils/asymptote/base/three_light.asy
@@ -0,0 +1,167 @@
+struct material {
+ pen[] p; // diffusepen,ambientpen,emissivepen,specularpen
+ real opacity;
+ real shininess;
+ real granularity;
+ void operator init(pen diffusepen=black, pen ambientpen=black,
+ pen emissivepen=black, pen specularpen=mediumgray,
+ real opacity=opacity(diffusepen),
+ real shininess=defaultshininess,
+ real granularity=-1) {
+ p=new pen[] {diffusepen,ambientpen,emissivepen,specularpen};
+ this.opacity=opacity;
+ this.shininess=shininess;
+ this.granularity=granularity;
+ }
+ void operator init(material m, real granularity=m.granularity) {
+ p=copy(m.p);
+ opacity=m.opacity;
+ shininess=m.shininess;
+ this.granularity=granularity;
+ }
+ pen diffuse() {return p[0];}
+ pen ambient() {return p[1];}
+ pen emissive() {return p[2];}
+ pen specular() {return p[3];}
+ void diffuse(pen q) {p[0]=q;}
+ void ambient(pen q) {p[1]=q;}
+ void emissive(pen q) {p[2]=q;}
+ void specular(pen q) {p[3]=q;}
+}
+
+void write(file file, string s="", material x, suffix suffix=none)
+{
+ write(file,s);
+ write(file,"{");
+ write(file,"diffuse=",x.diffuse());
+ write(file,", ambient=",x.ambient());
+ write(file,", emissive=",x.emissive());
+ write(file,", specular=",x.specular());
+ write(file,", opacity=",x.opacity);
+ write(file,", shininess=",x.shininess);
+ write(file,", granularity=",x.granularity);
+ write(file,"}",suffix);
+}
+
+void write(string s="", material x, suffix suffix=endl)
+{
+ write(stdout,s,x,suffix);
+}
+
+bool operator == (material m, material n)
+{
+ return all(m.p == n.p) && m.opacity == n.opacity &&
+ m.shininess == n.shininess && m.granularity == n.granularity;
+}
+
+material operator cast(pen p)
+{
+ return material(p);
+}
+
+material[] operator cast(pen[] p)
+{
+ return sequence(new material(int i) {return p[i];},p.length);
+}
+
+pen operator ecast(material m)
+{
+ return m.p.length > 0 ? m.diffuse() : nullpen;
+}
+
+material emissive(material m, real granularity=m.granularity)
+{
+ return material(black+opacity(m.opacity),black,m.diffuse(),black,m.opacity,1,
+ granularity);
+}
+
+struct light {
+ real[][] diffuse;
+ real[][] ambient;
+ real[][] specular;
+ real specularfactor;
+ bool viewport; // Are the lights specified (and fixed) in the viewport frame?
+ triple[] position; // Only directional lights are implemented.
+
+ transform3 T=identity(4); // Transform to apply to normal vectors.
+
+ bool on() {return position.length > 0;}
+
+ void operator init(pen[] diffuse=array(position.length,white),
+ pen[] ambient=array(position.length,black),
+ pen[] specular=diffuse, real specularfactor=1,
+ bool viewport=true, triple[] position) {
+ this.position=new triple[position.length];
+ this.diffuse=new real[position.length][];
+ this.ambient=new real[position.length][];
+ this.specular=new real[position.length][];
+ for(int i=0; i < position.length; ++i) {
+ this.position[i]=unit(position[i]);
+ this.diffuse[i]=rgba(diffuse[i]);
+ this.ambient[i]=rgba(ambient[i]);
+ this.specular[i]=rgba(specular[i]);
+ }
+ this.specularfactor=specularfactor;
+ this.viewport=viewport;
+ }
+
+ void operator init(pen diffuse=white, pen ambient=black, pen specular=diffuse,
+ real specularfactor=1,
+ bool viewport=true...triple[] position) {
+ int n=position.length;
+ operator init(array(n,diffuse),array(n,ambient),array(n,specular),
+ specularfactor,viewport,position);
+ }
+
+ void operator init(pen diffuse=white, pen ambient=black, pen specular=diffuse,
+ bool viewport=true, real x, real y, real z) {
+ operator init(diffuse,ambient,specular,viewport,(x,y,z));
+ }
+
+ void operator init(explicit light light) {
+ diffuse=copy(light.diffuse);
+ ambient=copy(light.ambient);
+ specular=copy(light.specular);
+ specularfactor=light.specularfactor;
+ viewport=light.viewport;
+ position=copy(light.position);
+ }
+
+ pen color(triple normal, material m, transform3 T=T) {
+ if(invisible((pen) m)) return invisible;
+ if(position.length == 0) return m.diffuse();
+ normal=unit(T*normal);
+ if(settings.twosided) normal *= sgn(normal.z);
+ real s=m.shininess*128;
+ real[] Diffuse=rgba(m.diffuse());
+ real[] Ambient=rgba(m.ambient());
+ real[] Specular=rgba(m.specular());
+ real[] p=rgba(m.emissive());
+ for(int i=0; i < position.length; ++i) {
+ triple L=viewport ? position[i] : T*position[i];
+ real Ldotn=max(dot(normal,L),0);
+ p += ambient[i]*Ambient+Ldotn*diffuse[i]*Diffuse;
+// Apply specularfactor to partially compensate non-pixel-based rendering.
+ if(Ldotn > 0) // Phong-Blinn model of specular reflection
+ p += dot(normal,unit(L+Z))^s*specularfactor*specular[i]*Specular;
+ }
+ return rgb(p[0],p[1],p[2])+opacity(opacity(m.diffuse()));
+ }
+}
+
+light operator * (transform3 t, light light)
+{
+ light light=light(light);
+ if(!light.viewport) light.position=shiftless(t)*light.position;
+ return light;
+}
+
+light operator cast(triple v) {return light(v);}
+
+light currentlight=light(ambient=rgb(0.1,0.1,0.1),specularfactor=3,
+ (0.25,-0.25,1));
+
+light adobe=light(gray(0.4),specularfactor=3,viewport=false,
+ (0.5,-0.5,-0.25),(0.5,0.5,0.25),
+ (0.5,-0.5,0.2),(-0.5,0.5,-0.2));
+light nolight;
diff --git a/Build/source/utils/asymptote/base/three_margins.asy b/Build/source/utils/asymptote/base/three_margins.asy
new file mode 100644
index 00000000000..b6f286ee4ff
--- /dev/null
+++ b/Build/source/utils/asymptote/base/three_margins.asy
@@ -0,0 +1,104 @@
+struct marginT3 {
+ path3 g;
+ real begin,end;
+};
+
+typedef marginT3 margin3(path3, pen);
+
+path3 trim(path3 g, real begin, real end) {
+ real a=arctime(g,begin);
+ real b=arctime(g,arclength(g)-end);
+ return a <= b ? subpath(g,a,b) : point(g,a);
+}
+
+margin3 operator +(margin3 ma, margin3 mb)
+{
+ return new marginT3(path3 g, pen p) {
+ marginT3 margin;
+ real ba=ma(g,p).begin < 0 ? 0 : ma(g,p).begin;
+ real bb=mb(g,p).begin < 0 ? 0 : mb(g,p).begin;
+ real ea=ma(g,p).end < 0 ? 0 : ma(g,p).end;
+ real eb=mb(g,p).end < 0 ? 0 : mb(g,p).end;
+ margin.begin=ba+bb;
+ margin.end=ea+eb;
+ margin.g=trim(g,margin.begin,margin.end);
+ return margin;
+ };
+}
+
+margin3 NoMargin3()
+{
+ return new marginT3(path3 g, pen) {
+ marginT3 margin;
+ margin.begin=margin.end=0;
+ margin.g=g;
+ return margin;
+ };
+}
+
+margin3 Margin3(real begin, real end)
+{
+ return new marginT3(path3 g, pen p) {
+ marginT3 margin;
+ real factor=labelmargin(p);
+ real w=0.5*linewidth(p);
+ margin.begin=begin*factor-w;
+ margin.end=end*factor-w;
+ margin.g=trim(g,margin.begin,margin.end);
+ return margin;
+ };
+}
+
+margin3 PenMargin3(real begin, real end)
+{
+ return new marginT3(path3 g, pen p) {
+ marginT3 margin;
+ real factor=linewidth(p);
+ margin.begin=begin*factor;
+ margin.end=end*factor;
+ margin.g=trim(g,margin.begin,margin.end);
+ return margin;
+ };
+}
+
+margin3 DotMargin3(real begin, real end)
+{
+ return new marginT3(path3 g, pen p) {
+ marginT3 margin;
+ real margindot(real x) {return x > 0 ? dotfactor*x : x;}
+ real factor=linewidth(p);
+ margin.begin=margindot(begin)*factor;
+ margin.end=margindot(end)*factor;
+ margin.g=trim(g,margin.begin,margin.end);
+ return margin;
+ };
+}
+
+margin3 TrueMargin3(real begin, real end)
+{
+ return new marginT3(path3 g, pen p) {
+ marginT3 margin;
+ margin.begin=begin;
+ margin.end=end;
+ margin.g=trim(g,begin,end);
+ return margin;
+ };
+}
+
+margin3 NoMargin3=NoMargin3(),
+ BeginMargin3=Margin3(1,0),
+ Margin3=Margin3(0,1),
+ EndMargin3=Margin3,
+ Margins3=Margin3(1,1),
+ BeginPenMargin3=PenMargin3(0.5,-0.5),
+ BeginPenMargin2=PenMargin3(1.0,-0.5),
+ PenMargin3=PenMargin3(-0.5,0.5),
+ PenMargin2=PenMargin3(-0.5,1.0),
+ EndPenMargin3=PenMargin3,
+ EndPenMargin2=PenMargin2,
+ PenMargins3=PenMargin3(0.5,0.5),
+ PenMargins2=PenMargin3(1.0,1.0),
+ BeginDotMargin3=DotMargin3(0.5,-0.5),
+ DotMargin3=DotMargin3(-0.5,0.5),
+ EndDotMargin3=DotMargin3,
+ DotMargins3=DotMargin3(0.5,0.5);
diff --git a/Build/source/utils/asymptote/base/three_surface.asy b/Build/source/utils/asymptote/base/three_surface.asy
new file mode 100644
index 00000000000..6e540c416ff
--- /dev/null
+++ b/Build/source/utils/asymptote/base/three_surface.asy
@@ -0,0 +1,1343 @@
+import bezulate;
+
+int nslice=12;
+real camerafactor=1.2;
+
+private real Fuzz=10.0*realEpsilon;
+private real nineth=1/9;
+
+struct patch {
+ triple[][] P=new triple[4][4];
+ triple[] normals; // Optionally specify 4 normal vectors at the corners.
+ pen[] colors; // Optionally specify 4 corner colors.
+ bool straight; // Patch is based on a piecewise straight external path.
+ bool3 planar; // Patch is planar.
+
+ path3 external() {
+ return
+ P[0][0]..controls P[0][1] and P[0][2]..
+ P[0][3]..controls P[1][3] and P[2][3]..
+ P[3][3]..controls P[3][2] and P[3][1]..
+ P[3][0]..controls P[2][0] and P[1][0]..cycle;
+ }
+
+ triple[] internal() {
+ return new triple[] {P[1][1],P[1][2],P[2][2],P[2][1]};
+ }
+
+ triple cornermean() {
+ return 0.25*(P[0][0]+P[0][3]+P[3][3]+P[3][0]);
+ }
+
+ triple[] corners() {return new triple[] {P[0][0],P[0][3],P[3][3],P[3][0]};}
+
+ real[] map(real f(triple)) {
+ return new real[] {f(P[0][0]),f(P[0][3]),f(P[3][3]),f(P[3][0])};
+ }
+
+ triple[] controlpoints() {
+ return new triple[] {
+ P[0][0],P[0][1],P[0][2],P[0][3],
+ P[1][0],P[1][1],P[1][2],P[1][3],
+ P[2][0],P[2][1],P[2][2],P[2][3],
+ P[3][0],P[3][1],P[3][2],P[3][3]};
+ }
+
+ triple Bu(int j, real u) {return bezier(P[0][j],P[1][j],P[2][j],P[3][j],u);}
+ 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) {
+ return straight ? Bu(0,u)--Bu(3,u) :
+ Bu(0,u)..controls Bu(1,u) and Bu(2,u)..Bu(3,u);
+ }
+
+ triple Bv(int i, real v) {return bezier(P[i][0],P[i][1],P[i][2],P[i][3],v);}
+ 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) {
+ return straight ? Bv(0,v)--Bv(3,v) :
+ Bv(0,v)..controls Bv(1,v) and Bv(2,v)..Bv(3,v);
+ }
+
+ triple point(real u, real v) {
+ 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(BvPP(0,v),BvPP(1,v),BvPP(2,v),BvPP(3,v),u),
+ bezier(BuP(0,u),BuP(1,u),BuP(2,u),BuP(3,u),v))+
+ cross(bezier(BvP(0,v),BvP(1,v),BvP(2,v),BvP(3,v),u),
+ bezier(BuPP(0,u),BuPP(1,u),BuPP(2,u),BuPP(3,u),v)));
+ return abs(n) > epsilon ? n :
+ 0.25*cross(bezier(BvPP(0,v),BvPP(1,v),BvPP(2,v),BvPP(3,v),u),
+ bezier(BuPP(0,u),BuPP(1,u),BuPP(2,u),BuPP(3,u),v))+
+ 1/6*(cross(bezier(BvPPP(0),BvPPP(1),BvPPP(2),BvPPP(3),u),
+ bezier(BuP(0,u),BuP(1,u),BuP(2,u),BuP(3,u),v))+
+ cross(bezier(BvP(0,v),BvP(1,v),BvP(2,v),BvP(3,v),u),
+ bezier(BuPPP(0),BuPPP(1),BuPPP(2),BuPPP(3),v)))+
+ 1/12*(cross(bezier(BvPPP(0),BvPPP(1),BvPPP(2),BvPPP(3),u),
+ bezier(BuPP(0,u),BuPP(1,u),BuPP(2,u),BuPP(3,u),v))+
+ cross(bezier(BvPP(0,v),BvPP(1,v),BvPP(2,v),BvPP(3,v),u),
+ bezier(BuPPP(0),BuPPP(1),BuPPP(2),BuPPP(3),v)))+
+ 1/36*cross(bezier(BvPPP(0),BvPPP(1),BvPPP(2),BvPPP(3),u),
+ bezier(BuPPP(0),BuPPP(1),BuPPP(2),BuPPP(3),v));
+ }
+
+ static real fuzz=1000*realEpsilon;
+
+ triple normal(real u, real v) {
+ triple n=cross(bezier(BvP(0,v),BvP(1,v),BvP(2,v),BvP(3,v),u),
+ bezier(BuP(0,u),BuP(1,u),BuP(2,u),BuP(3,u),v));
+ real epsilon=fuzz*change2(P);
+ return (abs(n) > epsilon) ? n : normal0(u,v,epsilon);
+ }
+
+ triple normal00() {
+ triple n=9*cross(P[0][1]-P[0][0],P[1][0]-P[0][0]);
+ real epsilon=fuzz*change2(P);
+ return abs(n) > epsilon ? n : normal0(0,0,epsilon);
+ }
+
+ triple normal01() {
+ triple n=9*cross(P[0][3]-P[0][2],P[1][3]-P[0][3]);
+ real epsilon=fuzz*change2(P);
+ return abs(n) > epsilon ? n : normal0(0,1,epsilon);
+ }
+
+ triple normal11() {
+ triple n=9*cross(P[3][3]-P[3][2],P[3][3]-P[2][3]);
+ real epsilon=fuzz*change2(P);
+ return abs(n) > epsilon ? n : normal0(1,1,epsilon);
+ }
+
+ triple normal10() {
+ triple n=9*cross(P[3][1]-P[3][0],P[3][0]-P[2][0]);
+ real epsilon=fuzz*change2(P);
+ return abs(n) > epsilon ? n : normal0(1,0,epsilon);
+ }
+
+ pen[] colors(material m, light light=currentlight) {
+ bool nocolors=colors.length == 0;
+ if(normals.length > 0)
+ return new pen[] {light.color(normals[0],nocolors ? m : colors[0]),
+ light.color(normals[1],nocolors ? m : colors[1]),
+ light.color(normals[2],nocolors ? m : colors[2]),
+ light.color(normals[3],nocolors ? m : colors[3])};
+ if(planar) {
+ triple normal=normal(0.5,0.5);
+ return new pen[] {light.color(normal,nocolors ? m : colors[0]),
+ light.color(normal,nocolors ? m : colors[1]),
+ light.color(normal,nocolors ? m : colors[2]),
+ light.color(normal,nocolors ? m : colors[3])};
+ }
+ return new pen[] {light.color(normal00(),nocolors ? m : colors[0]),
+ light.color(normal01(),nocolors ? m : colors[1]),
+ light.color(normal11(),nocolors ? m : colors[2]),
+ light.color(normal10(),nocolors ? m : colors[3])};
+ }
+
+ triple bound(real m(real[], real), triple b) {
+ real x=m(new real[] {P[0][0].x,P[0][1].x,P[0][2].x,P[0][3].x,
+ P[1][0].x,P[1][1].x,P[1][2].x,P[1][3].x,
+ P[2][0].x,P[2][1].x,P[2][2].x,P[2][3].x,
+ P[3][0].x,P[3][1].x,P[3][2].x,P[3][3].x},b.x);
+ real y=m(new real[] {P[0][0].y,P[0][1].y,P[0][2].y,P[0][3].y,
+ P[1][0].y,P[1][1].y,P[1][2].y,P[1][3].y,
+ P[2][0].y,P[2][1].y,P[2][2].y,P[2][3].y,
+ P[3][0].y,P[3][1].y,P[3][2].y,P[3][3].y},b.y);
+ real z=m(new real[] {P[0][0].z,P[0][1].z,P[0][2].z,P[0][3].z,
+ P[1][0].z,P[1][1].z,P[1][2].z,P[1][3].z,
+ P[2][0].z,P[2][1].z,P[2][2].z,P[2][3].z,
+ P[3][0].z,P[3][1].z,P[3][2].z,P[3][3].z},b.z);
+ return (x,y,z);
+ }
+
+ triple min3,max3;
+ bool havemin3,havemax3;
+
+ void init() {
+ havemin3=false;
+ havemax3=false;
+ }
+
+ triple min(triple bound=P[0][0]) {
+ if(havemin3) return minbound(min3,bound);
+ havemin3=true;
+ return min3=bound(minbound,bound);
+ }
+
+ triple max(triple bound=P[0][0]) {
+ if(havemax3) return maxbound(max3,bound);
+ havemax3=true;
+ return max3=bound(maxbound,bound);
+ }
+
+ triple center() {
+ return 0.5*(this.min()+this.max());
+ }
+
+ pair min(projection P, pair bound=project(this.P[0][0],P.t)) {
+ return minbound(controlpoints(),P.t,bound);
+ }
+
+ pair max(projection P, pair bound=project(this.P[0][0],P.t)) {
+ return maxbound(controlpoints(),P.t,bound);
+ }
+
+ void operator init(triple[][] P, triple[] normals=new triple[],
+ pen[] colors=new pen[], bool straight=false,
+ bool3 planar=default) {
+ init();
+ this.P=copy(P);
+ if(normals.length != 0)
+ this.normals=copy(normals);
+ if(colors.length != 0)
+ this.colors=copy(colors);
+ this.planar=planar;
+ this.straight=straight;
+ }
+
+ void operator init(pair[][] P, triple plane(pair)=XYplane,
+ bool straight=false) {
+ triple[][] Q=new triple[4][];
+ for(int i=0; i < 4; ++i) {
+ pair[] Pi=P[i];
+ Q[i]=sequence(new triple(int j) {return plane(Pi[j]);},4);
+ }
+ operator init(Q,straight);
+ planar=true;
+ }
+
+ void operator init(patch s) {
+ operator init(s.P,s.normals,s.colors,s.straight);
+ }
+
+ // A constructor for a convex cyclic path3 of length <= 4 with optional
+ // arrays of 4 internal points, corner normals, and pens.
+ void operator init(path3 external, triple[] internal=new triple[],
+ triple[] normals=new triple[], pen[] colors=new pen[],
+ bool3 planar=default) {
+ init();
+
+ if(internal.length == 0 && planar == default)
+ this.planar=normal(external) != O;
+ else this.planar=planar;
+
+ int L=length(external);
+ if(L > 4 || !cyclic(external))
+ abort("cyclic path3 of length <= 4 expected");
+ if(L == 1) {
+ external=external--cycle--cycle--cycle;
+ if(colors.length > 0) colors.append(array(3,colors[0]));
+ if(normals.length > 0) normals.append(array(3,normals[0]));
+ } else if(L == 2) {
+ external=external--cycle--cycle;
+ if(colors.length > 0) colors.append(array(2,colors[0]));
+ if(normals.length > 0) normals.append(array(2,normals[0]));
+ } else if(L == 3) {
+ external=external--cycle;
+ if(colors.length > 0) colors.push(colors[0]);
+ if(normals.length > 0) normals.push(normals[0]);
+ }
+ if(normals.length != 0)
+ this.normals=copy(normals);
+ if(colors.length != 0)
+ this.colors=copy(colors);
+
+ if(internal.length == 0) {
+ straight=piecewisestraight(external);
+ internal=new triple[4];
+ for(int j=0; j < 4; ++j)
+ internal[j]=nineth*(-4*point(external,j)
+ +6*(precontrol(external,j)+postcontrol(external,j))
+ -2*(point(external,j-1)+point(external,j+1))
+ +3*(precontrol(external,j-1)+
+ postcontrol(external,j+1))
+ -point(external,j+2));
+ } else straight=false;
+
+ P=new triple[][] {
+ {point(external,0),postcontrol(external,0),precontrol(external,1),
+ point(external,1)},
+ {precontrol(external,0),internal[0],internal[1],postcontrol(external,1)},
+ {postcontrol(external,3),internal[3],internal[2],precontrol(external,2)},
+ {point(external,3),precontrol(external,3),postcontrol(external,2),
+ point(external,2)}
+ };
+ }
+
+ // A constructor for a convex quadrilateral.
+ void operator init(triple[] external, triple[] internal=new triple[],
+ triple[] normals=new triple[], pen[] colors=new pen[],
+ bool3 planar=default) {
+ init();
+
+ if(internal.length == 0 && planar == default)
+ this.planar=normal(external) != O;
+ else this.planar=planar;
+
+ if(normals.length != 0)
+ this.normals=copy(normals);
+ if(colors.length != 0)
+ this.colors=copy(colors);
+
+ if(internal.length == 0) {
+ internal=new triple[4];
+ for(int j=0; j < 4; ++j)
+ internal[j]=nineth*(4*external[j]+2*external[(j+1)%4]+
+ external[(j+2)%4]+2*external[(j+3)%4]);
+ }
+
+ straight=true;
+
+ triple delta[]=new triple[4];
+ for(int j=0; j < 4; ++j)
+ delta[j]=(external[(j+1)% 4]-external[j])/3;
+
+ P=new triple[][] {
+ {external[0],external[0]+delta[0],external[1]-delta[0],external[1]},
+ {external[0]-delta[3],internal[0],internal[1],external[1]+delta[1]},
+ {external[3]+delta[3],internal[3],internal[2],external[2]-delta[1]},
+ {external[3],external[3]-delta[2],external[2]+delta[2],external[2]}
+ };
+ }
+}
+
+patch operator * (transform3 t, patch s)
+{
+ patch S;
+ for(int i=0; i < 4; ++i) {
+ triple[] si=s.P[i];
+ triple[] Si=S.P[i];
+ for(int j=0; j < 4; ++j)
+ Si[j]=t*si[j];
+ }
+
+ transform3 t0=shiftless(t);
+ for(int i=0; i < s.normals.length; ++i)
+ S.normals[i]=t0*s.normals[i];
+
+ S.colors=copy(s.colors);
+ S.planar=s.planar;
+ S.straight=s.straight;
+ return S;
+}
+
+patch reverse(patch s)
+{
+ patch S;
+ S.P=transpose(s.P);
+ if(s.normals.length > 0)
+ S.normals=
+ new triple[] {s.normals[0],s.normals[3],s.normals[2],s.normals[1]};
+ if(s.colors.length > 0)
+ S.colors=new pen[] {s.colors[0],s.colors[3],s.colors[2],s.colors[1]};
+ S.planar=s.planar;
+ S.straight=s.straight;
+ return S;
+}
+
+struct surface {
+ patch[] s;
+
+ bool empty() {
+ return s.length == 0;
+ }
+
+ void operator init(int n) {
+ s=new patch[n];
+ }
+
+ void operator init(... patch[] s) {
+ this.s=s;
+ }
+
+ void operator init(surface s) {
+ this.s=new patch[s.s.length];
+ for(int i=0; i < s.s.length; ++i)
+ this.s[i]=patch(s.s[i]);
+ }
+
+ void operator init(triple[][][] P, triple[][] normals=new triple[][],
+ pen[][] colors=new pen[][], bool3 planar=default) {
+ s=sequence(new patch(int i) {
+ return patch(P[i],normals.length == 0 ? new triple[] : normals[i],
+ colors.length == 0 ? new pen[] : colors[i],planar);
+ },P.length);
+ }
+
+ void colors(pen[][] palette) {
+ for(int i=0; i < s.length; ++i) {
+ pen[] palettei=palette[i];
+ s[i].colors=new pen[] {palettei[0],palettei[1],palettei[2],palettei[3]};
+ }
+ }
+
+ triple[][] corners() {
+ triple[][] a=new triple[s.length][];
+ for(int i=0; i < s.length; ++i)
+ a[i]=s[i].corners();
+ return a;
+ }
+
+ real[][] map(real f(triple)) {
+ real[][] a=new real[s.length][];
+ for(int i=0; i < s.length; ++i)
+ a[i]=s[i].map(f);
+ return a;
+ }
+
+ triple[] cornermean() {
+ return sequence(new triple(int i) {return s[i].cornermean();},s.length);
+ }
+
+ // A constructor for a possibly nonconvex cyclic path in a given plane.
+ void operator init (path p, triple plane(pair)=XYplane,
+ bool checkboundary=true) {
+ if(!cyclic(p))
+ abort("cyclic path expected");
+
+ int L=length(p);
+
+ if(L > 4) {
+ for(path g : bezulate(p))
+ s.append(surface(g,plane,checkboundary).s);
+ return;
+ }
+
+ pair[][] P(path p) {
+ if(L == 1)
+ p=p--cycle--cycle--cycle;
+ else if(L == 2)
+ p=p--cycle--cycle;
+ else if(L == 3)
+ p=p--cycle;
+
+ pair[] internal=new pair[4];
+ for(int j=0; j < 4; ++j) {
+ internal[j]=nineth*(-4*point(p,j)
+ +6*(precontrol(p,j)+postcontrol(p,j))
+ -2*(point(p,j-1)+point(p,j+1))
+ +3*(precontrol(p,j-1)+postcontrol(p,j+1))
+ -point(p,j+2));
+ }
+
+ return new pair[][] {
+ {point(p,0),postcontrol(p,0),precontrol(p,1),point(p,1)},
+ {precontrol(p,0),internal[0],internal[1],postcontrol(p,1)},
+ {postcontrol(p,3),internal[3],internal[2],precontrol(p,2)},
+ {point(p,3),precontrol(p,3),postcontrol(p,2),point(p,2)}
+ };
+ }
+
+ bool straight=piecewisestraight(p);
+ if(L <= 3 && straight) {
+ s=new patch[] {patch(P(p),plane,straight)};
+ return;
+ }
+
+ // Split p along the angle bisector at t.
+ bool split(path p, real t) {
+ pair dir=dir(p,t);
+ if(dir != 0) {
+ path g=subpath(p,t,t+length(p));
+ int L=length(g);
+ pair z=point(g,0);
+ real[] T=intersections(g,z,z+I*dir);
+ for(int i=0; i < T.length; ++i) {
+ real cut=T[i];
+ if(cut > sqrtEpsilon && cut < L-sqrtEpsilon) {
+ pair w=point(g,cut);
+ if(!inside(p,0.5*(z+w),zerowinding)) continue;
+ pair delta=sqrtEpsilon*(w-z);
+ if(intersections(g,z-delta--w+delta).length != 2) continue;
+ s=surface(subpath(g,0,cut)--cycle,plane,checkboundary).s;
+ s.append(surface(subpath(g,cut,L)--cycle,plane,checkboundary).s);
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
+ // Ensure that all interior angles are less than 180 degrees.
+ real fuzz=1e-4;
+ int sign=sgn(windingnumber(p,inside(p,zerowinding)));
+ for(int i=0; i < L; ++i) {
+ if(sign*(conj(dir(p,i,-1))*dir(p,i,1)).y < -fuzz) {
+ if(split(p,i)) return;
+ }
+ }
+
+ pair[][] P=P(p);
+
+ if(straight) {
+ s=new patch[] {patch(P,plane,straight)};
+ return;
+ }
+
+ // Check for degeneracy.
+ pair[][] U=new pair[3][4];
+ pair[][] V=new pair[4][3];
+
+ for(int i=0; i < 3; ++i) {
+ for(int j=0; j < 4; ++j)
+ U[i][j]=P[i+1][j]-P[i][j];
+ }
+
+ for(int i=0; i < 4; ++i) {
+ for(int j=0; j < 3; ++j)
+ V[i][j]=P[i][j+1]-P[i][j];
+ }
+
+ int[] choose2={1,2,1};
+ int[] choose3={1,3,3,1};
+
+ real T[][]=new real[6][6];
+ for(int p=0; p < 6; ++p) {
+ int kstart=max(p-2,0);
+ int kstop=min(p,3);
+ real[] Tp=T[p];
+ for(int q=0; q < 6; ++q) {
+ real Tpq;
+ int jstop=min(q,3);
+ int jstart=max(q-2,0);
+ for(int k=kstart; k <= kstop; ++k) {
+ int choose3k=choose3[k];
+ for(int j=jstart; j <= jstop; ++j) {
+ int i=p-k;
+ int l=q-j;
+ Tpq += (conj(U[i][j])*V[k][l]).y*
+ choose2[i]*choose3k*choose3[j]*choose2[l];
+ }
+ }
+ Tp[q]=Tpq;
+ }
+ }
+
+ bool3 aligned=default;
+ bool degenerate=false;
+
+ for(int p=0; p < 6; ++p) {
+ for(int q=0; q < 6; ++q) {
+ if(aligned == default) {
+ if(T[p][q] < -sqrtEpsilon) aligned=true;
+ if(T[p][q] > sqrtEpsilon) aligned=false;
+ } else {
+ if((T[p][q] < -sqrtEpsilon && aligned == false) ||
+ (T[p][q] > sqrtEpsilon && aligned == true)) degenerate=true;
+ }
+ }
+ }
+
+ if(!degenerate) {
+ if(aligned == (sign >= 0))
+ s=new patch[] {patch(P,plane)};
+ return;
+ }
+
+ if(checkboundary) {
+ // Polynomial coefficients of (B_i'' B_j + B_i' B_j')/3.
+ static real[][][] fpv0={
+ {{5, -20, 30, -20, 5},
+ {-3, 24, -54, 48, -15},
+ {0, -6, 27, -36, 15},
+ {0, 0, -3, 8, -5}},
+ {{-7, 36, -66, 52, -15},
+ {3, -36, 108, -120, 45},
+ {0, 6, -45, 84, -45},
+ {0, 0, 3, -16, 15}},
+ {{2, -18, 45, -44, 15},
+ {0, 12, -63, 96, -45},
+ {0, 0, 18, -60, 45},
+ {0, 0, 0, 8, -15}},
+ {{0, 2, -9, 12, -5},
+ {0, 0, 9, -24, 15},
+ {0, 0, 0, 12, -15},
+ {0, 0, 0, 0, 5}}
+ };
+
+ // Compute one-ninth of the derivative of the Jacobian along the boundary.
+ real[][] c=array(4,array(5,0.0));
+ for(int i=0; i < 4; ++i) {
+ real[][] fpv0i=fpv0[i];
+ for(int j=0; j < 4; ++j) {
+ real[] w=fpv0i[j];
+ c[0] += w*(conj(P[0][j]-P[1][j])*P[0][i]).y; // u=0
+ c[1] += w*(conj(P[i][3])*(P[j][3]-P[j][2])).y; // v=1
+ c[2] += w*(conj(P[3][j]-P[2][j])*P[3][i]).y; // u=1
+ c[3] += w*(conj(P[i][0])*(P[j][1]-P[j][0])).y; // v=0
+ }
+ }
+
+ pair BuP(int j, real u) {
+ return bezierP(P[0][j],P[1][j],P[2][j],P[3][j],u);
+ }
+ pair BvP(int i, real v) {
+ return bezierP(P[i][0],P[i][1],P[i][2],P[i][3],v);
+ }
+ real normal(real u, real v) {
+ return (conj(bezier(BvP(0,v),BvP(1,v),BvP(2,v),BvP(3,v),u))*
+ bezier(BuP(0,u),BuP(1,u),BuP(2,u),BuP(3,u),v)).y;
+ }
+
+ // Use Rolle's theorem to check for degeneracy on the boundary.
+ real M=0;
+ real cut;
+ for(int i=0; i < 4; ++i) {
+ if(!straight(p,i)) {
+ real[] ci=c[i];
+ pair[] R=quarticroots(ci[4],ci[3],ci[2],ci[1],ci[0]);
+ for(pair r : R) {
+ if(fabs(r.y) < sqrtEpsilon) {
+ real t=r.x;
+ if(0 <= t && t <= 1) {
+ real[] U={0,t,1,t};
+ real[] V={t,1,t,0};
+ real[] T={t,t,1-t,1-t};
+ real N=sign*normal(U[i],V[i]);
+ if(N < M) {
+ M=N; cut=i+T[i];
+ }
+ }
+ }
+ }
+ }
+ }
+
+ // Split at the worst boundary degeneracy.
+ if(M < 0 && split(p,cut)) return;
+ }
+
+ // Split arbitrarily to resolve any remaining (internal) degeneracy.
+ checkboundary=false;
+ for(int i=0; i < L; ++i)
+ if(!straight(p,i) && split(p,i+0.5)) return;
+
+ while(true)
+ for(int i=0; i < L; ++i)
+ if(!straight(p,i) && split(p,i+unitrand())) return;
+ }
+
+ void operator init(explicit path[] g, triple plane(pair)=XYplane) {
+ for(path p : bezulate(g))
+ s.append(surface(p,plane).s);
+ }
+
+ // A general surface constructor for both planar and nonplanar 3D paths.
+ void construct(path3 external, triple[] internal=new triple[],
+ triple[] normals=new triple[], pen[] colors=new pen[],
+ bool3 planar=default) {
+ int L=length(external);
+ if(!cyclic(external)) abort("cyclic path expected");
+
+ if(L <= 3 && piecewisestraight(external)) {
+ s.push(patch(external,internal,normals,colors,planar=true));
+ return;
+ }
+
+ // Construct a surface from a possibly nonconvex planar cyclic path3.
+ if(planar != false && internal.length == 0 && normals.length == 0 &&
+ colors.length == 0) {
+ triple n=normal(external);
+ if(n != O) {
+ transform3 T=align(n);
+ external=transpose(T)*external;
+ T *= shift(0,0,point(external,0).z);
+ for(patch p : surface(path(external)).s)
+ s.push(T*p);
+ return;
+ }
+ }
+
+ if(L <= 4 || internal.length > 0) {
+ s.push(patch(external,internal,normals,colors,planar));
+ return;
+ }
+
+ // Path is not planar; split into patches.
+ real factor=1/L;
+ pen[] p;
+ triple[] n;
+ bool nocolors=colors.length == 0;
+ bool nonormals=normals.length == 0;
+ triple center;
+ for(int i=0; i < L; ++i)
+ center += point(external,i);
+ center *= factor;
+ if(!nocolors)
+ p=new pen[] {mean(colors)};
+ if(!nonormals)
+ n=new triple[] {factor*sum(normals)};
+ // Use triangles for nonplanar surfaces.
+ int step=normal(external) == O ? 1 : 2;
+ int i=0;
+ int end;
+ while((end=i+step) < L) {
+ s.push(patch(subpath(external,i,end)--center--cycle,
+ nonormals ? n : concat(normals[i:end+1],n),
+ nocolors ? p : concat(colors[i:end+1],p),planar));
+ i=end;
+ }
+ s.push(patch(subpath(external,i,L)--center--cycle,
+ nonormals ? n : concat(normals[i:],normals[0:1],n),
+ nocolors ? p : concat(colors[i:],colors[0:1],p),planar));
+ }
+
+ void operator init(path3 external, triple[] internal=new triple[],
+ triple[] normals=new triple[], pen[] colors=new pen[],
+ bool3 planar=default) {
+ s=new patch[];
+ construct(external,internal,normals,colors,planar);
+ }
+
+ void operator init(explicit path3[] external,
+ triple[][] internal=new triple[][],
+ triple[][] normals=new triple[][],
+ pen[][] colors=new pen[][], bool3 planar=default) {
+ s=new patch[];
+ for(int i=0; i < external.length; ++i)
+ construct(external[i],
+ internal.length == 0 ? new triple[] : internal[i],
+ normals.length == 0 ? new triple[] : normals[i],
+ colors.length == 0 ? new pen[] : colors[i],planar);
+ }
+
+ void push(path3 external, triple[] internal=new triple[],
+ triple[] normals=new triple[] ,pen[] colors=new pen[],
+ bool3 planar=default) {
+ s.push(patch(external,internal,normals,colors,planar));
+ }
+
+ // Construct the surface of rotation generated by rotating g
+ // from angle1 to angle2 sampled n times about the line c--c+axis.
+ // An optional surface pen color(int i, real j) may be specified
+ // to override the color at vertex(i,j).
+ void operator init(triple c, path3 g, triple axis, int n=nslice,
+ real angle1=0, real angle2= 360,
+ pen color(int i, real j)=null) {
+ axis=unit(axis);
+ real w=(angle2-angle1)/n;
+ int L=length(g);
+ s=new patch[L*n];
+ int m=-1;
+ transform3[] T=new transform3[n+1];
+ transform3 t=rotate(w,c,c+axis);
+ T[0]=rotate(angle1,c,c+axis);
+ for(int k=1; k <= n; ++k)
+ T[k]=T[k-1]*t;
+
+ for(int i=0; i < L; ++i) {
+ path3 h=subpath(g,i,i+1);
+ path3 r=reverse(h);
+ triple max=max(h);
+ triple min=min(h);
+ triple perp=perp(max-c,axis);
+ real fuzz=epsilon*max(abs(max),abs(min));
+ if(abs(perp) < fuzz)
+ perp=perp(min-c,axis);
+ perp=unit(perp);
+ triple normal=cross(axis,perp);
+ triple dir(real j) {return Cos(j)*normal-Sin(j)*perp;}
+ real j=angle1;
+ transform3 Tk=T[0];
+ triple dirj=dir(j);
+ for(int k=0; k < n; ++k, j += w) {
+ transform3 Tp=T[k+1];
+ triple dirp=dir(j+w);
+ path3 G=Tk*h{dirj}..{dirp}Tp*r{-dirp}..{-dirj}cycle;
+ Tk=Tp;
+ dirj=dirp;
+ s[++m]=color == null ? patch(G) :
+ patch(G,new pen[] {color(i,j),color(i+1,j),color(i+1,j+w),
+ color(i,j+w)});
+ }
+ }
+ }
+
+ void push(patch s) {
+ this.s.push(s);
+ }
+
+ void append(surface s) {
+ this.s.append(s.s);
+ }
+
+ void operator init(... surface[] s) {
+ for(surface S : s)
+ this.s.append(S.s);
+ }
+}
+
+surface operator * (transform3 t, surface s)
+{
+ surface S;
+ S.s=new patch[s.s.length];
+ for(int i=0; i < s.s.length; ++i)
+ S.s[i]=t*s.s[i];
+ return S;
+}
+
+private string nullsurface="null surface";
+
+triple min(surface s)
+{
+ if(s.s.length == 0)
+ abort(nullsurface);
+ triple bound=s.s[0].min();
+ for(int i=1; i < s.s.length; ++i)
+ bound=s.s[i].min(bound);
+ return bound;
+}
+
+triple max(surface s)
+{
+ if(s.s.length == 0)
+ abort(nullsurface);
+ triple bound=s.s[0].max();
+ for(int i=1; i < s.s.length; ++i)
+ bound=s.s[i].max(bound);
+ return bound;
+}
+
+pair min(surface s, projection P)
+{
+ if(s.s.length == 0)
+ abort(nullsurface);
+ pair bound=s.s[0].min(P);
+ for(int i=1; i < s.s.length; ++i)
+ bound=s.s[i].min(P,bound);
+ return bound;
+}
+
+pair max(surface s, projection P)
+{
+ if(s.s.length == 0)
+ abort(nullsurface);
+ pair bound=s.s[0].max(P);
+ for(int i=1; i < s.s.length; ++i)
+ bound=s.s[i].max(P,bound);
+ return bound;
+}
+
+private triple[] split(triple z0, triple c0, triple c1, triple z1, real t=0.5)
+{
+ triple m0=interp(z0,c0,t);
+ triple m1=interp(c0,c1,t);
+ triple m2=interp(c1,z1,t);
+ triple m3=interp(m0,m1,t);
+ triple m4=interp(m1,m2,t);
+ triple m5=interp(m3,m4,t);
+
+ return new triple[] {m0,m3,m5,m4,m2};
+}
+
+// Return the control points for a subpatch of P on [u,1] x [v,1].
+triple[][] subpatchbegin(triple[][] P, real u, real v)
+{
+ triple[] P0=P[0];
+ triple[] P1=P[1];
+ triple[] P2=P[2];
+ triple[] P3=P[3];
+
+ triple[] c0=split(P0[0],P0[1],P0[2],P0[3],v);
+ triple[] c1=split(P1[0],P1[1],P1[2],P1[3],v);
+ triple[] c2=split(P2[0],P2[1],P2[2],P2[3],v);
+ triple[] c3=split(P3[0],P3[1],P3[2],P3[3],v);
+
+ u=1.0-u;
+
+ triple[] c7=split(c3[2],c2[2],c1[2],c0[2],u);
+ triple[] c8=split(c3[3],c2[3],c1[3],c0[3],u);
+ triple[] c9=split(c3[4],c2[4],c1[4],c0[4],u);
+ triple[] c10=split(P3[3],P2[3],P1[3],P0[3],u);
+
+ return new triple[][] {{c7[2],c8[2],c9[2],c10[2]},
+ {c7[1],c8[1],c9[1],c10[1]},
+ {c7[0],c8[0],c9[0],c10[0]},
+ {c3[2],c3[3],c3[4],P3[3]}};
+}
+
+// Return the control points for a subpatch of P on [0,u] x [0,v].
+triple[][] subpatchend(triple[][] P, real u, real v)
+{
+ triple[] P0=P[0];
+ triple[] P1=P[1];
+ triple[] P2=P[2];
+ triple[] P3=P[3];
+
+ triple[] c0=split(P0[0],P0[1],P0[2],P0[3],v);
+ triple[] c1=split(P1[0],P1[1],P1[2],P1[3],v);
+ triple[] c2=split(P2[0],P2[1],P2[2],P2[3],v);
+ triple[] c3=split(P3[0],P3[1],P3[2],P3[3],v);
+
+ u=1.0-u;
+
+ triple[] c4=split(P3[0],P2[0],P1[0],P0[0],u);
+ triple[] c5=split(c3[0],c2[0],c1[0],c0[0],u);
+ triple[] c6=split(c3[1],c2[1],c1[1],c0[1],u);
+ triple[] c7=split(c3[2],c2[2],c1[2],c0[2],u);
+
+ return new triple[][] {
+ {P0[0],c0[0],c0[1],c0[2]},
+ {c4[4],c5[4],c6[4],c7[4]},
+ {c4[3],c5[3],c6[3],c7[3]},
+ {c4[2],c5[2],c6[2],c7[2]}};
+}
+
+patch subpatch(patch s, real ua, real va, real ub, real vb)
+{
+ assert(ua >= 0 && va >= 0 && ub <= 1 && vb <= 1 && ua < ub && va < vb);
+ return patch(subpatchbegin(subpatchend(s.P,ub,vb),ua/ub,va/vb),
+ s.straight,s.planar);
+}
+
+triple point(patch s, real u, real v)
+{
+ return s.point(u,v);
+}
+
+void draw3D(frame f, patch s, material m, light light=currentlight)
+{
+ if(s.colors.length > 0)
+ m=mean(s.colors);
+ bool lighton=light.on();
+ if(!lighton && !invisible((pen) m))
+ m=emissive(m);
+ real granularity=m.granularity >= 0 ? m.granularity : defaultgranularity;
+ draw(f,s.P,s.straight,m.p,m.opacity,m.shininess,granularity,
+ s.planar ? s.normal(0.5,0.5) : O,lighton,s.colors);
+}
+
+void tensorshade(transform t=identity(), frame f, patch s,
+ material m, light light=currentlight, projection P)
+{
+ tensorshade(f,box(t*s.min(P),t*s.max(P)),m.diffuse(),
+ s.colors(m,light),t*project(s.external(),P,1),
+ t*project(s.internal(),P));
+}
+
+restricted pen[] nullpens={nullpen};
+nullpens.cyclic(true);
+
+void draw(transform t=identity(), frame f, surface s, int nu=1, int nv=1,
+ material[] surfacepen, pen[] meshpen=nullpens,
+ light light=currentlight, light meshlight=light,
+ projection P=currentprojection)
+{
+ if(is3D()) {
+ for(int i=0; i < s.s.length; ++i)
+ draw3D(f,s.s[i],surfacepen[i],light);
+ pen modifiers=thin()+squarecap;
+ for(int k=0; k < s.s.length; ++k) {
+ pen meshpen=meshpen[k];
+ if(!invisible(meshpen)) {
+ meshpen=modifiers+meshpen;
+ real step=nu == 0 ? 0 : 1/nu;
+ for(int i=0; i <= nu; ++i)
+ draw(f,s.s[k].uequals(i*step),meshpen,meshlight);
+ step=nv == 0 ? 0 : 1/nv;
+ for(int j=0; j <= nv; ++j)
+ draw(f,s.s[k].vequals(j*step),meshpen,meshlight);
+ }
+ }
+ } else {
+ begingroup(f);
+ // 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[] {abs(camera-s.s[i].cornermean()),i};
+
+ depth=sort(depth);
+
+ light.T=shiftless(P.modelview());
+
+ // Draw from farthest to nearest
+ while(depth.length > 0) {
+ real[] a=depth.pop();
+ int i=round(a[1]);
+ tensorshade(t,f,s.s[i],surfacepen[i],light,P);
+ pen meshpen=meshpen[i];
+ if(!invisible(meshpen))
+ draw(f,t*project(s.s[i].external(),P),meshpen);
+ }
+ endgroup(f);
+ }
+}
+
+void draw(transform t=identity(), frame f, surface s, int nu=1, int nv=1,
+ material surfacepen=currentpen, pen meshpen=nullpen,
+ light light=currentlight, light meshlight=light,
+ projection P=currentprojection)
+{
+ material[] surfacepen={surfacepen};
+ pen[] meshpen={meshpen};
+ surfacepen.cyclic(true);
+ meshpen.cyclic(true);
+ draw(t,f,s,nu,nv,surfacepen,meshpen,light,meshlight,P);
+}
+
+void draw(picture pic=currentpicture, surface s, int nu=1, int nv=1,
+ material[] surfacepen, pen[] meshpen=nullpens,
+ light light=currentlight, light meshlight=light)
+{
+ if(s.empty()) return;
+
+ pic.add(new void(frame f, transform3 t, picture pic, projection P) {
+ surface S=t*s;
+ if(is3D()) {
+ draw(f,S,nu,nv,surfacepen,meshpen,light,meshlight);
+ } else if(pic != null)
+ pic.add(new void(frame f, transform T) {
+ draw(T,f,S,nu,nv,surfacepen,meshpen,light,meshlight,P);
+ },true);
+ if(pic != null) {
+ pic.addPoint(min(S,P));
+ pic.addPoint(max(S,P));
+ }
+ },true);
+ pic.addPoint(min(s));
+ pic.addPoint(max(s));
+
+ pen modifiers;
+ if(is3D()) modifiers=thin()+squarecap;
+ for(int k=0; k < s.s.length; ++k) {
+ pen meshpen=meshpen[k];
+ if(!invisible(meshpen)) {
+ meshpen=modifiers+meshpen;
+ real step=nu == 0 ? 0 : 1/nu;
+ for(int i=0; i <= nu; ++i)
+ addPath(pic,s.s[k].uequals(i*step),meshpen);
+ step=nv == 0 ? 0 : 1/nv;
+ for(int j=0; j <= nv; ++j)
+ addPath(pic,s.s[k].vequals(j*step),meshpen);
+ }
+ }
+}
+
+void draw(picture pic=currentpicture, surface s, int nu=1, int nv=1,
+ material surfacepen=currentpen, pen meshpen=nullpen,
+ light light=currentlight, light meshlight=light)
+{
+ material[] surfacepen={surfacepen};
+ pen[] meshpen={meshpen};
+ surfacepen.cyclic(true);
+ meshpen.cyclic(true);
+ draw(pic,s,nu,nv,surfacepen,meshpen,light,meshlight);
+}
+
+void draw(picture pic=currentpicture, surface s, int nu=1, int nv=1,
+ material[] surfacepen, pen meshpen,
+ light light=currentlight, light meshlight=light)
+{
+ pen[] meshpen={meshpen};
+ meshpen.cyclic(true);
+ draw(pic,s,nu,nv,surfacepen,meshpen,light,meshlight);
+}
+
+surface extrude(path p, triple axis=Z)
+{
+ static patch[] allocate;
+ path3 G=path3(p);
+ path3 G2=shift(axis)*G;
+ return surface(...sequence(new patch(int i) {
+ return patch(subpath(G,i,i+1)--subpath(G2,i+1,i)--cycle);
+ },length(G)));
+}
+
+surface extrude(explicit path[] p, triple axis=Z)
+{
+ surface s;
+ for(path g:p)
+ s.append(extrude(g,axis));
+ return s;
+}
+
+triple rectify(triple dir)
+{
+ real scale=max(abs(dir.x),abs(dir.y),abs(dir.z));
+ if(scale != 0) dir *= 0.5/scale;
+ dir += (0.5,0.5,0.5);
+ return dir;
+}
+
+path3[] align(path3[] g, transform3 t=identity4, triple position,
+ triple align, pen p=currentpen)
+{
+ if(determinant(t) == 0) return g;
+ triple m=min(g);
+ triple dir=rectify(inverse(t)*-align);
+ triple a=m+realmult(dir,max(g)-m);
+ return shift(position+align*labelmargin(p))*t*shift(-a)*g;
+}
+
+surface align(surface s, transform3 t=identity4, triple position,
+ triple align, pen p=currentpen)
+{
+ if(determinant(t) == 0) return s;
+ triple m=min(s);
+ triple dir=rectify(inverse(t)*-align);
+ triple a=m+realmult(dir,max(s)-m);
+ return shift(position+align*labelmargin(p))*t*shift(-a)*s;
+}
+
+surface surface(Label L, triple position=O)
+{
+ surface s=surface(texpath(L));
+ return L.align.is3D ? align(s,L.T3,position,L.align.dir3,L.p) :
+ shift(position)*L.T3*s;
+}
+
+path[] path(Label L, pair z=0, projection P)
+{
+ path[] g=texpath(L);
+ if(L.defaulttransform3) {
+ return L.align.is3D ? align(g,z,project(L.align.dir3,P)-project(O,P),L.p) :
+ shift(z)*g;
+ } else {
+ path3[] G=path3(g);
+ return L.align.is3D ? shift(z)*project(align(G,L.T3,O,L.align.dir3,L.p),P) :
+ shift(z)*project(L.T3*G,P);
+ }
+}
+
+void label(frame f, Label L, triple position, align align=NoAlign,
+ pen p=currentpen, light light=nolight,
+ projection P=currentprojection)
+{
+ Label L=L.copy();
+ L.align(align);
+ L.p(p);
+ if(L.defaulttransform3)
+ L.T3=transform3(P);
+ if(is3D()) {
+ for(patch S : surface(L,position).s)
+ draw3D(f,S,L.p,light);
+ } else {
+ if(L.filltype == NoFill)
+ fill(f,path(L,project(position,P.t),P),
+ light.color(L.T3*Z,L.p,shiftless(P.modelview())));
+ else {
+ frame d;
+ fill(d,path(L,project(position,P.t),P),
+ light.color(L.T3*Z,L.p,shiftless(P.modelview())));
+ add(f,d,L.filltype);
+ }
+ }
+}
+
+void label(picture pic=currentpicture, Label L, triple position,
+ align align=NoAlign, pen p=currentpen, light light=nolight)
+{
+ Label L=L.copy();
+ L.align(align);
+ L.p(p);
+ L.position(0);
+ path[] g=texpath(L);
+ if(g.length == 0 || (g.length == 1 && size(g[0]) == 0)) return;
+ pic.add(new void(frame f, transform3 t, picture pic, projection P) {
+ triple v=t*position;
+ if(L.defaulttransform3)
+ L.T3=transform3(P);
+ if(is3D())
+ for(patch S : surface(L,v).s)
+ draw3D(f,S,L.p,light);
+ if(pic != null) {
+ if(L.filltype == NoFill)
+ fill(project(v,P.t),pic,path(L,P),
+ light.color(L.T3*Z,L.p,shiftless(P.modelview())));
+ else {
+ picture d;
+ fill(project(v,P.t),d,path(L,P),
+ light.color(L.T3*Z,L.p,shiftless(P.modelview())));
+ add(pic,d,L.filltype);
+ }
+ }
+ },!L.defaulttransform3);
+
+ if(L.defaulttransform3)
+ L.T3=transform3(currentprojection);
+ path3[] G=path3(g);
+ G=L.align.is3D ? align(G,L.T3,O,L.align.dir3,L.p) : L.T3*G;
+ pic.addBox(position,position,min(G),max(G));
+}
+
+void label(picture pic=currentpicture, Label L, path3 g, align align=NoAlign,
+ pen p=currentpen)
+{
+ Label L=Label(L,align,p);
+ bool relative=L.position.relative;
+ real position=L.position.position.x;
+ pair Align=L.align.dir;
+ bool alignrelative=L.align.relative;
+ if(L.defaultposition) {relative=true; position=0.5;}
+ if(relative) position=reltime(g,position);
+ if(L.align.default) {
+ alignrelative=true;
+ Align=position <= 0 ? S : position >= length(g) ? N : E;
+ }
+ label(pic,L,point(g,position),
+ alignrelative && determinant(currentprojection.t) != 0 ?
+ -Align*project(dir(g,position),currentprojection.t)*I : L.align);
+}
+
+surface extrude(Label L, triple axis=Z)
+{
+ Label L=L.copy();
+ path[] g=texpath(L);
+ surface S=extrude(g,axis);
+ surface s=surface(g);
+ S.append(s);
+ S.append(shift(axis)*s);
+ return S;
+}
+
+restricted surface nullsurface;
+
+private real a=4/3*(sqrt(2)-1);
+private transform3 t=rotate(90,O,Z);
+private transform3 t2=t*t;
+private transform3 t3=t2*t;
+private transform3 i=xscale3(-1)*zscale3(-1);
+
+restricted patch octant1=patch(X{Z}..{-X}Z..Z{Y}..{-Z}Y{X}..{-Y}cycle,
+ new triple[] {(1,a,a),(a,a^2,1),(a^2,a,1),
+ (a,1,a)});
+
+restricted surface unithemisphere=surface(octant1,t*octant1,t2*octant1,
+ t3*octant1);
+restricted surface unitsphere=surface(octant1,t*octant1,t2*octant1,t3*octant1,
+ i*octant1,i*t*octant1,i*t2*octant1,
+ i*t3*octant1);
+
+restricted patch unitfrustum(real t1, real t2)
+{
+ real s1=interp(t1,t2,1/3);
+ real s2=interp(t1,t2,2/3);
+ return patch(interp(Z,X,t2)--interp(Z,X,t1){Y}..{-X}interp(Z,Y,t1)--
+ interp(Z,Y,t2){X}..{-Y}cycle,
+ new triple[] {(s2,s2*a,1-s2),(s1,s1*a,1-s1),(s1*a,s1,1-s1),
+ (s2*a,s2,1-s2)});
+}
+
+// Return a unitcone constructed from n frusta (the final one being degenerate)
+surface unitcone(int n=6)
+{
+ 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]=t*s;
+ unitcone.s[2n+i]=t2*s;
+ unitcone.s[3n+i]=t3*s;
+ }
+ return unitcone;
+}
+
+restricted surface unitcone=unitcone();
+restricted surface unitsolidcone=surface(patch(unitcircle3)...unitcone.s);
+
+private patch unitcylinder1=patch(X--X+Z{Y}..{-X}Y+Z--Y{X}..{-Y}cycle);
+
+restricted surface unitcylinder=surface(unitcylinder1,t*unitcylinder1,
+ t2*unitcylinder1,t3*unitcylinder1);
+
+private patch unitplane=patch(new triple[] {O,X,X+Y,Y});
+restricted surface unitcube=surface(reverse(unitplane),
+ rotate(90,O,X)*unitplane,
+ rotate(-90,O,Y)*unitplane,
+ shift(Z)*unitplane,
+ rotate(90,X,X+Y)*unitplane,
+ rotate(-90,Y,X+Y)*unitplane);
+restricted surface unitplane=surface(unitplane);
+restricted surface unitdisk=surface(unitcircle3);
+
+void dot(frame f, triple v, material p=currentpen,
+ light light=nolight, projection P=currentprojection)
+{
+ pen q=(pen) p;
+ if(is3D()) {
+ material m=material(p,p.granularity >= 0 ? p.granularity : dotgranularity);
+ for(patch s : unitsphere.s)
+ draw3D(f,shift(v)*scale3(0.5*linewidth(dotsize(q)+q))*s,m,light);
+ } else dot(f,project(v,P.t),q);
+}
+
+void dot(frame f, path3 g, material p=currentpen,
+ projection P=currentprojection)
+{
+ for(int i=0; i <= length(g); ++i) dot(f,point(g,i),p,P);
+}
+
+void dot(frame f, path3[] g, material p=currentpen,
+ projection P=currentprojection)
+{
+ for(int i=0; i < g.length; ++i) dot(f,g[i],p,P);
+}
+
+void dot(picture pic=currentpicture, triple v, material p=currentpen,
+ light light=nolight)
+{
+ pen q=(pen) p;
+ real size=0.5*linewidth(dotsize(q)+q);
+ pic.add(new void(frame f, transform3 t, picture pic, projection P) {
+ if(is3D()) {
+ material m=material(p,p.granularity >= 0 ? p.granularity :
+ dotgranularity);
+ for(patch s : unitsphere.s)
+ draw3D(f,shift(t*v)*scale3(size)*s,m,light);
+ }
+ if(pic != null)
+ dot(pic,project(t*v,P.t),q);
+ },true);
+ triple R=size*(1,1,1);
+ pic.addBox(v,v,-R,R);
+}
+
+void dot(picture pic=currentpicture, triple[] v, material p=currentpen)
+{
+ for(int i=0; i < v.length; ++i) dot(pic,v[i],p);
+}
+
+void dot(picture pic=currentpicture, explicit path3 g, material p=currentpen)
+{
+ for(int i=0; i <= length(g); ++i) dot(pic,point(g,i),p);
+}
+
+void dot(picture pic=currentpicture, path3[] g, material p=currentpen)
+{
+ for(int i=0; i < g.length; ++i) dot(pic,g[i],p);
+}
+
+void dot(picture pic=currentpicture, Label L, triple v, align align=NoAlign,
+ string format=defaultformat, material p=currentpen)
+{
+ Label L=L.copy();
+ if(L.s == "") {
+ if(format == "") format=defaultformat;
+ L.s="("+format(format,v.x)+","+format(format,v.y)+","+
+ format(format,v.z)+")";
+ }
+ L.align(align,E);
+ L.p((pen) p);
+ dot(pic,v,p);
+ label(pic,L,v);
+}
diff --git a/Build/source/utils/asymptote/base/tree.asy b/Build/source/utils/asymptote/base/tree.asy
new file mode 100644
index 00000000000..0f3559112c3
--- /dev/null
+++ b/Build/source/utils/asymptote/base/tree.asy
@@ -0,0 +1,86 @@
+/*****
+ * treedef.asy
+ * Andy Hammerlindl 2003/10/25
+ *
+ * Implements a dynamic binary search tree.
+ *****/
+
+struct tree
+{
+ tree left = null;
+ tree right = null;
+ int key = 0;
+ int value = 0;
+}
+
+tree newtree()
+{
+ return null;
+}
+
+tree add(tree t, int key, int value)
+{
+ if (t == null) {
+ tree tt;
+ tt.key = key; tt.value = value;
+ return tt;
+ }
+ else if (key == t.key) {
+ return t;
+ }
+ else if (key < t.key) {
+ tree tt;
+ tt.left = add(t.left, key, value);
+ tt.key = t.key;
+ tt.value = t.value;
+ tt.right = t.right;
+ return tt;
+ }
+ else {
+ tree tt;
+ tt.left = t.left;
+ tt.key = t.key;
+ tt.value = t.value;
+ tt.right = add(t.right, key, value);
+ return tt;
+ }
+}
+
+bool contains(tree t, int key)
+{
+ if (t == null)
+ return false;
+ else if (key == t.key)
+ return true;
+ else if (key < t.key)
+ return contains(t.left, key);
+ else
+ return contains(t.right, key);
+}
+
+int lookup(tree t, int key)
+{
+ if (t == null)
+ return 0;
+ else if (key == t.key)
+ return t.value;
+ else if (key < t.key)
+ return lookup(t.left, key);
+ else
+ return lookup(t.right, key);
+}
+
+void write(file out=stdout, tree t)
+{
+ if (t != null) {
+ if(t.left != null) {
+ write(out,t.left);
+ }
+ write(out,t.key);
+ write(out,"->");
+ write(out,t.value,endl);
+ if (t.right != null) {
+ write(out,t.right);
+ }
+ }
+}
diff --git a/Build/source/utils/asymptote/base/trembling.asy b/Build/source/utils/asymptote/base/trembling.asy
new file mode 100644
index 00000000000..6b94317b1c4
--- /dev/null
+++ b/Build/source/utils/asymptote/base/trembling.asy
@@ -0,0 +1,369 @@
+// Copyright (c) 2008, Philippe Ivaldi.
+// trembling.asy: handwriting package for the software Asymptote.
+// Last modified: Mon Jul 7 23:35:36 CEST 2008
+
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or (at
+// your option) any later version.
+
+// This program 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
+// General Public License for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+// 02110-1301, USA.
+
+// COMMENTARY:
+
+// THANKS:
+
+// BUGS:
+// magnetic points are experimental...
+
+// CODE:
+
+import geometry;
+import stats;
+
+/*<asyxml><variable type="pair[]" signature="magneticPoints"><code></asyxml>*/
+pair[] magneticPoints;
+/*<asyxml></code><documentation>Array of magnetic points.
+ When a point is magnetized, a trembled path will pass though P if the original path passes through P.
+ When trembling is enabled with the routine 'startTrembling' all the drawn points is added to this array.
+ For convenience, one can magnetize an arbitrary number of points with the routine 'magnetize'.<look href="#magnetize(...point[])"><look href="#startTrembling(real,real,real,real,bool">
+ </documentation></variable></asyxml>*/
+real magneticRadius=1; // unit is bp in postscript coordinates.
+real trembleFuzz(){return min(1e-3,magneticRadius/10);}
+// real trembleFuzz(){return min(1e-1,1);}
+
+pair[] single(pair[] P)
+{
+ pair[] op;
+ bool allow;
+ for (int i=0; i < P.length-1; ++i) {
+ allow=true;
+ for (int j=i+1; j < P.length; ++j) {
+ if(abs(P[i]-P[j]) < magneticRadius) {
+ allow=false;
+ break;
+ }
+ }
+ if(allow) op.push(P[i]);
+ }
+ if(P.length > 0) op.push(P[P.length-1]);
+ return op;
+}
+
+/*<asyxml><function type="pair" signature="attract(pair,path,real)"><code></asyxml>*/
+real atime(pair m, path g, real fuzz=trembleFuzz())
+{/*<asyxml></code><documentation>Return the time of the nearest point of 'm' which is on the path g.
+ 'fuzz' is the argument 'fuzz' of 'intersect'.</documentation></function></asyxml>*/
+ if(length(g) == 0) return 0.0;
+ real[] t=intersect(m,g,fuzz);
+ if(t.length > 0) return t[1];
+ real ot;
+ static real eps=sqrt(realEpsilon);
+ real abmax=abs(max(g)-m), abmin=abs(min(g)-m);
+ real initr=abs(m-midpoint(g));
+ real maxR=2*max(abmax,abmin), step=eps, r=initr;
+ real shx=1e-4;
+ transform T=shift(m);
+ path ig;
+ // do {
+ // do {// Find a radius for intersection
+ // r += step;
+ // ig=T*scale(r)*unitcircle;
+ // if(ig == g) {
+ // T *= shift(shx,0);
+ // ig=T*scale(r)*unitcircle;
+ // }
+ // t=intersect(ig,g);
+ // } while(t.length <= 0 && r <= maxR && inside(g,ig) != 1);//
+ // if(t.length <= 0) { // degenerated case
+ // r=initr;
+ // T *= shift(shx,0);
+ // write("warning: atime needs numerical adjustment.");
+ // }
+ // } while(t.length <= 0);
+ if(t.length > 0) ot=t[1];
+ real rm=0, rM=r;
+ while(rM-rm > eps) {
+ r=(rm+rM)/2;
+ t=intersect(T*scale(r)*unitcircle,g,fuzz);
+ if(t.length <= 0) {
+ rm=r;
+ } else {
+ rM=r;
+ ot=t[1];
+ }
+ }
+ return ot;
+}
+
+/*<asyxml><function type="void" signature="magnetize(...pair[])"><code></asyxml>*/
+void magnetize(...pair[] P)
+{/*<asyxml></code><documentation>Magnetize the points P.
+ When a point is magnetized, a trembled path will pass though P if the original path passes through P.</documentation></function></asyxml>*/
+ if(magneticRadius <= 0) return;
+ currentpicture.uptodate=false;
+ currentpicture.nodes.insert(0,
+ new void(frame f, transform t, transform T, pair lb, pair rt)
+ {
+ for (pair PT:P) {
+ magneticPoints.push(t*PT);
+ }
+ });
+}
+
+/*<asyxml><function type="void" signature="magnetize(...triangle[])"><code></asyxml>*/
+void magnetize(...triangle[] t)
+{/*<asyxml></code><documentation>Magnetize the vertices of the triangles t.<look href="#magnetize(...pair[])"/></documentation></function></asyxml>*/
+ for(int i=0; i < t.length; ++i)
+ magnetize(...new point[] {t[i].A, t[i].B, t[i].C});
+}
+
+void trueMagnetize(pair p)
+{
+ if(magneticRadius <= 0) return;
+ magneticPoints.push(p);
+}
+
+/*<asyxml><function type="path" signature="addnode(path,real)"><code></asyxml>*/
+path addnode(path g, real t)
+{/*<asyxml></code><documentation>Add a node to 'g' at point(g,t).</documentation></function></asyxml>*/
+ real l=length(g);
+ real rt=t%1;
+ if (l==0 || (t > l && !cyclic(g)) || rt == 0) return g;
+ if(cyclic(g)) t=t%l;
+ int t0=floor(t);
+ int t1=t0+1;
+ pair z0=point(g,t0), z1=point(g,t1),
+ c0=postcontrol(g,t0), c1=precontrol(g,t1),
+ m0=(1-rt)*z0+rt*c0, m1=(1-rt)*c0+rt*c1,
+ m2=(1-rt)*c1+rt*z1, m3=(1-rt)*m0+rt*m1,
+ m4=(1-rt)*m1+rt*m2;
+ guide og=subpath(g,0,t0);
+ og=og..controls m0 and m3..point(g,t);
+ if(cyclic(g))
+ if(t1 < l) {
+ og=og..controls m4 and m2..subpath(g,t1,l)&cycle;
+ } else og=og..controls m4 and m2..cycle;
+ else og=og..controls m4 and m2..subpath(g,t1,l);
+ return og;
+}
+
+path addnodes(path g, real fuzz=trembleFuzz() ...pair[] P)
+{
+ pair[] P=single(P);
+ if(length(g) == 0 || P.length == 0 || magneticRadius <= 0) return g;
+ path og=g;
+ for(pair tp:P) {
+ real t=atime(tp,og,fuzz);
+ real d=abs(tp-point(og,t));
+ if(d < magneticRadius) og=addnode(og,t);
+ }
+ return og;
+}
+
+/*<asyxml><function type="path" signature="addnodes(path,int)"><code></asyxml>*/
+path addnodes(path g, int n)
+{/*<asyxml></code><documentation>Add 'n' nodes between each node of 'g'.</documentation></function></asyxml>*/
+ real l=length(g);
+ if(n == 0 || l == 0) return g;
+ path og=g;
+ int np=0;
+ for (int i=0; i < l; ++i) {
+ real step=1/(n+1);
+ for (int j=0; j < n; ++j) {
+ og=addnode(og,i*(n+1)+j+step);
+ step=1/(n-j);
+ }
+ }
+ return og;
+}
+
+
+
+/*<asyxml><variable type="real" signature="trembleAngle"><code></asyxml>*/
+real trembleAngle=4, trembleFrequency=0.5, trembleRandom=2;/*<asyxml></code><documentation>Variables used by the routine 'tremble'.</documentation></variable></asyxml>*/
+
+/*<asyxml><function type="path" signature="tremble(path,real,real,real,real)"><code></asyxml>*/
+path tremble(path g,
+ real angle=trembleAngle,
+ real frequency=trembleFrequency,
+ real random=trembleRandom,
+ real fuzz=trembleFuzz())
+{/*<asyxml></code><documentation>Return g as it was handwriting.
+ The postcontrols and precontrols of the nodes of g will be rotated
+ by an angle proportional to 'angle' (in degrees).
+ If frequency < 1, floor(1/frequency) nodes will be added to g to increase the
+ control points.
+ If frequency >= 1, one point for floor(frequency) will be used to deform the path.
+ 'random' controls the randomized coefficient which will be multiplied 'angle'.
+ random is 0 means don't use randomized coefficient;
+ More 'random' is hight more the coefficient is hight and the trembling seems randomized.</documentation></function></asyxml>*/
+ if(length(g) == 0) return g;
+ path tg=g;
+ frequency=abs(frequency);
+ int f=abs(floor(1/frequency)-1);
+ tg=addnodes(tg,f);
+ int frequency=floor(frequency);
+ int tf=(frequency == 0) ? 1 : frequency;
+ int l=length(tg);
+ guide og=point(tg,0);
+ random=abs(random);
+ int rsgn(real x){
+ int d2=floor(100*x)-10*floor(10*x);
+ if(d2 == 0) return 1;
+ return 2%d2 == 0 ? 1 : -1;
+ }
+ real randf()
+ {
+ real or;
+ if(random != 0)
+ if(1%tf != 0) or=0; else {
+ real ur=unitrand();
+ or=rsgn(ur)*angle*(1+ur^(1/random));
+ }
+ else or=rsgn(unitrand())*1.5*angle;
+ return or;
+ }
+
+ real first=randf(), a=first;
+ real gle;
+ for(int i=1; i <= l; ++i)
+ {
+ pair P=point(tg,i);
+ // gle=(i == l && (cyclic(tg))) ? first : a;
+ // pair post=rotate(gle,point(tg,i-1))*postcontrol(tg,i-1);
+ // pair pre=rotate(gle,P)*precontrol(tg,i);
+ a=randf();
+ pair post=rotate(a,point(tg,i-1))*postcontrol(tg,i-1);
+ pair pre=rotate((a+randf())/2,P)*precontrol(tg,i);
+ if(i == l && (cyclic(tg)))
+ og=og..controls post and pre..cycle;
+ else
+ og=og..controls post and pre..P;
+ }
+ return og;
+}
+
+typedef path pathModifier(path);
+pathModifier NoModifier=new path(path g){return g;};
+pathModifier tremble(real angle=trembleAngle,
+ real frequency=trembleFrequency,
+ real random=trembleRandom,
+ real fuzz=trembleFuzz())
+{
+ return new path(path g){return tremble(g,angle,frequency,random,fuzz);};
+}
+
+void orig_draw(frame f, path g, pen p=currentpen)=draw;
+void tremble_draw(frame f, path g, pen p=currentpen){}
+
+void tremble_marknodes(picture pic=currentpicture, frame f, path g) {}
+void tremble_markuniform(bool centered=false, int n, bool rotated=false) {}
+
+int tremble_circlenodesnumber(real r){return 5;}
+int orig_circlenodesnumber(real r)=circlenodesnumber;
+
+int tremble_circlenodesnumber1(real r, real angle1, real angle2){return 4;}
+int orig_circlenodesnumber1(real r, real angle1, real angle2)=circlenodesnumber;
+
+int tremble_ellipsenodesnumber(real a, real b){return 50;}
+int orig_ellipsenodesnumber(real a, real b)=ellipsenodesnumber;
+
+int tremble_ellipsenodesnumber1(real a, real b, real angle1, real angle2, bool dir){return 20;}
+int orig_ellipsenodesnumber1(real a, real b, real angle1, real angle2, bool dir)=ellipsenodesnumber;
+
+int tremble_parabolanodesnumber(parabola p, real angle1, real angle2){return 20;}
+int orig_parabolanodesnumber(parabola p, real angle1, real angle2)=parabolanodesnumber;
+
+int tremble_hyperbolanodesnumber(hyperbola h, real angle1, real angle2){return 20;}
+int orig_hyperbolanodesnumber(hyperbola h, real angle1, real angle2)=hyperbolanodesnumber;
+
+restricted bool tremblingMode=false;
+/*<asyxml><function type="void" signature="startTrembling(real,real,real,real,bool"><code></asyxml>*/
+void startTrembling(real angle=trembleAngle,
+ real frequency=trembleFrequency,
+ real random=trembleRandom,
+ real fuzz=trembleFuzz(),
+ bool magnetizePoints=true)
+{/*<asyxml></code><documentation>Calling this routine all drawn paths will be trembled with the givens parameters.<look href="#tremble(path,real,real,real,real)"/>
+ If 'magnetizePoints' is true, most dotted points are automatically magnetized.<look href="magnetize(...pair[])"/></documentation></function></asyxml>*/
+ if(!tremblingMode) {
+ tremblingMode=true;
+ tremble_draw=new void(frame f, path g, pen p=currentpen)
+ {
+ if(length(g) == 0 && magnetizePoints) {
+ trueMagnetize(point(g,0));
+ }
+ g=addnodes(g,fuzz*abs(max(g)-min(g)) ...magneticPoints);
+ orig_draw(f,tremble(g,angle,frequency,random,fuzz),p);
+ };
+
+ plain.draw=tremble_draw;
+
+ if(magnetizePoints) {
+ marknodes=new void(picture pic=currentpicture, frame f, path g)
+ {
+ for(int i=0; i <= length(g); ++i) {
+ add(pic,f,point(g,i));
+ magnetize(point(g,i));
+ }
+ };
+ dot=dot();
+
+ markuniform=new markroutine(bool centered=false, int n, bool rotated=false)
+ {
+ return new void(picture pic=currentpicture, frame f, path g) {
+ if(n <= 0) return;
+ void add(real x) {
+ real t=reltime(g,x);
+ add(pic,rotated ? rotate(degrees(dir(g,t)))*f : f,point(g,t));
+ magnetize(point(g,t));
+ }
+ if(centered) {
+ real width=1/n;
+ for(int i=0; i < n; ++i) add((i+0.5)*width);
+ } else {
+ if(n == 1) add(0.5);
+ else {
+ real width=1/(n-1);
+ for(int i=0; i < n; ++i)
+ add(i*width);
+ }
+ }
+ };
+ };
+ }
+
+ circlenodesnumber=tremble_circlenodesnumber;
+ circlenodesnumber=tremble_circlenodesnumber1;
+
+ ellipsenodesnumber=tremble_ellipsenodesnumber;
+ ellipsenodesnumber=tremble_ellipsenodesnumber1;
+
+ parabolanodesnumber=tremble_parabolanodesnumber;
+ hyperbolanodesnumber=tremble_hyperbolanodesnumber;
+ }
+}
+
+// void stopTrembling()
+// {
+// if(tremblingMode) {
+// tremblingMode=false;
+// plain.draw=orig_draw;
+// // draw=orig_draw1;
+// circlenodesnumber=orig_circlenodesnumber;
+// circlenodesnumber=orig_circlenodesnumber1;
+// ellipsenodesnumber=orig_ellipsenodesnumber;
+// ellipsenodesnumber=orig_ellipsenodesnumber1;
+// parabolanodesnumber=orig_parabolanodesnumber;
+// hyperbolanodesnumber=orig_hyperbolanodesnumber;
+// }
+// }
diff --git a/Build/source/utils/asymptote/base/tube.asy b/Build/source/utils/asymptote/base/tube.asy
new file mode 100644
index 00000000000..f62d3897adf
--- /dev/null
+++ b/Build/source/utils/asymptote/base/tube.asy
@@ -0,0 +1,210 @@
+// Author: Philippe Ivaldi
+// Based on this paper:
+// http://www.cs.hku.hk/research/techreps/document/TR-2007-07.pdf
+// Note: the additional rotation for a cyclic smooth spine curve is not
+// yet properly determined.
+// TODO: Implement variational principles for RMF with boundary conditions:
+// minimum total angular speed OR minimum total squared angular speed
+
+import three;
+
+// A 3D version of roundedpath(path, real).
+path3 roundedpath(path3 A, real r)
+{
+ // Author of this routine: Jens Schwaiger
+ guide3 rounded;
+ triple before, after, indir, outdir;
+ int len=length(A);
+ bool guideclosed=cyclic(A);
+ if(len < 2) {return A;};
+ if(guideclosed) {rounded=point(point(A,0)--point(A,1),r);}
+ else {rounded=point(A,0);}
+ for(int i=1; i < len; i=i+1) {
+ before=point(point(A,i)--point(A,i-1),r);
+ after=point(point(A,i)--point(A,i+1),r);
+ indir=dir(point(A,i-1)--point(A,i),1);
+ outdir=dir(point(A,i)--point(A,i+1),1);
+ rounded=rounded--before{indir}..{outdir}after;
+ }
+ if(guideclosed) {
+ before=point(point(A,0)--point(A,len-1),r);
+ indir=dir(point(A,len-1)--point(A,0),1);
+ outdir=dir(point(A,0)--point(A,1),1);
+ rounded=rounded--before{indir}..{outdir}cycle;
+ } else rounded=rounded--point(A,len);
+
+ return rounded;
+}
+
+real[] sample(path3 g, real r, real relstep=0)
+{
+ 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);});
+ }
+ t.push(n);
+ } else {
+ int nb=ceil(1/relstep);
+ relstep=n/nb;
+ for(int i=0; i <= nb; ++i)
+ t.push(i*relstep);
+ }
+ return t;
+}
+
+struct Rmf
+{
+ triple p,r,t; // s=cross(t,r);
+ real reltime;
+ void operator init(triple p, triple r, triple t, real reltime)
+ {
+ this.p=p;
+ this.r=r;
+ this.t=t;
+ this.reltime=reltime;
+ }
+}
+
+real degrees(Rmf a, Rmf b)
+{
+ real d=degrees(acos1(dot(a.r,b.r)));
+ real dt=dot(cross(a.r,b.r),a.t);
+ d=dt > 0 ? d : 360-d;
+ return d%360;
+}
+
+private Rmf[] rmf(path3 g, Rmf U0=Rmf(O,O,O,0), real[] t)
+{
+ if(U0.t == O) {
+ triple d=dir(g,0);
+ U0=Rmf(point(g,0),perp(d),d,0);
+ }
+ int l=length(g);
+ Rmf[] R={U0};
+ triple rp,v1,v2,tp,ti,p;
+ real c;
+
+ for(int i=0; i < t.length-1; ++i) {
+ p=point(g,t[i+1]);
+ v1=p-R[i].p;
+ c=dot(v1,v1);
+ if(c != 0) {
+ rp=R[i].r-2*dot(v1,R[i].r)*v1/c;
+ ti=R[i].t;
+ tp=ti-2*dot(v1,ti)*v1/c;
+ ti=dir(g,t[i+1]);
+ v2=ti-tp;
+ rp=rp-2*dot(v2,rp)*v2/dot(v2,v2);
+ R.push(Rmf(p,unit(rp),unit(ti),t[i+1]/l));
+ } else {
+ write("Warning: path3 has duplicated point in Rmf.");
+ R.push(R[R.length-1]);
+ }
+ }
+ return R;
+}
+
+restricted int coloredNodes=1;
+restricted int coloredSegments=2;
+
+struct coloredpath
+{
+ path p;
+ pen[] pens(real);
+ bool usepens=false;
+ int colortype=coloredSegments;
+
+ void operator init(path p, pen[] pens=new pen[] {currentpen},
+ int colortype=coloredSegments)
+ {
+ this.p=p;
+ this.pens=new pen[] (real t) {return pens;};
+ this.usepens=true;
+ this.colortype=colortype;
+ }
+
+ void operator init(path p, pen[] pens(real), int colortype=coloredSegments)
+ {
+ this.p=p;
+ this.pens=pens;
+ this.usepens=true;
+ this.colortype=colortype;
+ }
+
+ void operator init(path p, pen pen(real))
+ {
+ this.p=p;
+ this.pens=new pen[] (real t) {return new pen[] {pen(t)};};
+ this.usepens=true;
+ this.colortype=coloredSegments;
+ }
+}
+
+coloredpath operator cast(path p)
+{
+ coloredpath cp=coloredpath(p);
+ cp.usepens=false;
+ return cp;
+}
+
+coloredpath operator cast(guide p)
+{
+ return coloredpath(p);
+}
+
+private surface surface(Rmf[] R, coloredpath cp,transform T(real)=
+ new transform(real t) {return identity();},
+ bool cyclic)
+{
+ path g=cp.p;
+ int l=length(g);
+ bool[] planar;
+ for(int i=0; i < l; ++i)
+ planar[i]=straight(g,i);
+
+ surface s;
+ path3 sec=path3(T(R[0].reltime)*g);
+ real adjust=0;
+ if(cyclic) adjust=-degrees(R[0],R[R.length-1])/(R.length-1);
+ path3 sec1=shift(R[0].p)*transform3(R[0].r,cross(R[0].t,R[0].r),R[0].t)*sec,
+ sec2;
+
+ for(int i=1; i < R.length; ++i) {
+ sec=path3(T(R[i].reltime)*g);
+ sec2=shift(R[i].p)*transform3(R[i].r,cross(R[i].t,R[i].r),R[i].t)*
+ rotate(i*adjust,Z)*sec;
+ for(int j=0; j < l; ++j) {
+ surface st=surface(subpath(sec1,j,j+1)--subpath(sec2,j+1,j)--cycle,
+ planar=planar[j]);
+ if(cp.usepens) {
+ pen[] tp1=cp.pens(R[i-1].reltime), tp2=cp.pens(R[i].reltime);
+ tp1.cyclic(true); tp2.cyclic(true);
+ if(cp.colortype == coloredSegments) {
+ st.colors(new pen[][] {{tp1[j],tp1[j],tp2[j],tp2[j]}});
+ } else {
+ st.colors(new pen[][] {{tp1[j],tp1[j+1],tp2[j+1],tp2[j]}});
+ }
+ }
+ s.append(st);
+ }
+ sec1=sec2;
+ }
+ return s;
+}
+
+surface tube(path3 g, coloredpath section,
+ transform T(real)=new transform(real t) {return identity();},
+ real corner=1, real relstep=0)
+{
+ pair M=max(section.p), m=min(section.p);
+ real[] t=sample(g,max(M.x-m.x,M.y-m.y)/max(realEpsilon,abs(corner)),
+ min(abs(relstep),1));
+ t.cyclic(cyclic(g));
+ return surface(rmf(g,t),section,T,cyclic(g));
+}
diff --git a/Build/source/utils/asymptote/base/unicode.asy b/Build/source/utils/asymptote/base/unicode.asy
new file mode 100644
index 00000000000..33571e8341a
--- /dev/null
+++ b/Build/source/utils/asymptote/base/unicode.asy
@@ -0,0 +1,2 @@
+usepackage("ucs");
+usepackage("inputenc","utf8x");
diff --git a/Build/source/utils/asymptote/base/version.asy b/Build/source/utils/asymptote/base/version.asy
new file mode 100644
index 00000000000..e8dcc965de5
--- /dev/null
+++ b/Build/source/utils/asymptote/base/version.asy
@@ -0,0 +1 @@
+string VERSION="1.72";
diff --git a/Build/source/utils/asymptote/base/x11colors.asy b/Build/source/utils/asymptote/base/x11colors.asy
new file mode 100644
index 00000000000..77e0401f06e
--- /dev/null
+++ b/Build/source/utils/asymptote/base/x11colors.asy
@@ -0,0 +1,145 @@
+pen rgbint(int r, int g, int b)
+{
+ return rgb(r/255,g/255,b/255);
+}
+
+pen AliceBlue=rgbint(240,248,255);
+pen AntiqueWhite=rgbint(250,235,215);
+pen Aqua=rgbint(0,255,255);
+pen Aquamarine=rgbint(127,255,212);
+pen Azure=rgbint(240,255,255);
+pen Beige=rgbint(245,245,220);
+pen Bisque=rgbint(255,228,196);
+pen Black=rgbint(0,0,0);
+pen BlanchedAlmond=rgbint(255,235,205);
+pen Blue=rgbint(0,0,255);
+pen BlueViolet=rgbint(138,43,226);
+pen Brown=rgbint(165,42,42);
+pen BurlyWood=rgbint(222,184,135);
+pen CadetBlue=rgbint(95,158,160);
+pen Chartreuse=rgbint(127,255,0);
+pen Chocolate=rgbint(210,105,30);
+pen Coral=rgbint(255,127,80);
+pen CornflowerBlue=rgbint(100,149,237);
+pen Cornsilk=rgbint(255,248,220);
+pen Crimson=rgbint(220,20,60);
+pen Cyan=rgbint(0,255,255);
+pen DarkBlue=rgbint(0,0,139);
+pen DarkCyan=rgbint(0,139,139);
+pen DarkGoldenrod=rgbint(184,134,11);
+pen DarkGray=rgbint(169,169,169);
+pen DarkGreen=rgbint(0,100,0);
+pen DarkKhaki=rgbint(189,183,107);
+pen DarkMagenta=rgbint(139,0,139);
+pen DarkOliveGreen=rgbint(85,107,47);
+pen DarkOrange=rgbint(255,140,0);
+pen DarkOrchid=rgbint(153,50,204);
+pen DarkRed=rgbint(139,0,0);
+pen DarkSalmon=rgbint(233,150,122);
+pen DarkSeaGreen=rgbint(143,188,143);
+pen DarkSlateBlue=rgbint(72,61,139);
+pen DarkSlateGray=rgbint(47,79,79);
+pen DarkTurquoise=rgbint(0,206,209);
+pen DarkViolet=rgbint(148,0,211);
+pen DeepPink=rgbint(255,20,147);
+pen DeepSkyBlue=rgbint(0,191,255);
+pen DimGray=rgbint(105,105,105);
+pen DodgerBlue=rgbint(30,144,255);
+pen FireBrick=rgbint(178,34,34);
+pen FloralWhite=rgbint(255,250,240);
+pen ForestGreen=rgbint(34,139,34);
+pen Fuchsia=rgbint(255,0,255);
+pen Gainsboro=rgbint(220,220,220);
+pen GhostWhite=rgbint(248,248,255);
+pen Gold=rgbint(255,215,0);
+pen Goldenrod=rgbint(218,165,32);
+pen Gray=rgbint(128,128,128);
+pen Green=rgbint(0,128,0);
+pen GreenYellow=rgbint(173,255,47);
+pen Honeydew=rgbint(240,255,240);
+pen HotPink=rgbint(255,105,180);
+pen IndianRed=rgbint(205,92,92);
+pen Indigo=rgbint(75,0,130);
+pen Ivory=rgbint(255,255,240);
+pen Khaki=rgbint(240,230,140);
+pen Lavender=rgbint(230,230,250);
+pen LavenderBlush=rgbint(255,240,245);
+pen LawnGreen=rgbint(124,252,0);
+pen LemonChiffon=rgbint(255,250,205);
+pen LightBlue=rgbint(173,216,230);
+pen LightCoral=rgbint(240,128,128);
+pen LightCyan=rgbint(224,255,255);
+pen LightGoldenrodYellow=rgbint(250,250,210);
+pen LightGreen=rgbint(144,238,144);
+pen LightGrey=rgbint(211,211,211);
+pen LightPink=rgbint(255,182,193);
+pen LightSalmon=rgbint(255,160,122);
+pen LightSeaGreen=rgbint(32,178,170);
+pen LightSkyBlue=rgbint(135,206,250);
+pen LightSlateGray=rgbint(119,136,153);
+pen LightSteelBlue=rgbint(176,196,222);
+pen LightYellow=rgbint(255,255,224);
+pen Lime=rgbint(0,255,0);
+pen LimeGreen=rgbint(50,205,50);
+pen Linen=rgbint(250,240,230);
+pen Magenta=rgbint(255,0,255);
+pen Maroon=rgbint(128,0,0);
+pen MediumAquamarine=rgbint(102,205,170);
+pen MediumBlue=rgbint(0,0,205);
+pen MediumOrchid=rgbint(186,85,211);
+pen MediumPurple=rgbint(147,112,219);
+pen MediumSeaGreen=rgbint(60,179,113);
+pen MediumSlateBlue=rgbint(123,104,238);
+pen MediumSpringGreen=rgbint(0,250,154);
+pen MediumTurquoise=rgbint(72,209,204);
+pen MediumVioletRed=rgbint(199,21,133);
+pen MidnightBlue=rgbint(25,25,112);
+pen MintCream=rgbint(245,255,250);
+pen MistyRose=rgbint(255,228,225);
+pen Moccasin=rgbint(255,228,181);
+pen NavajoWhite=rgbint(255,222,173);
+pen Navy=rgbint(0,0,128);
+pen OldLace=rgbint(253,245,230);
+pen Olive=rgbint(128,128,0);
+pen OliveDrab=rgbint(107,142,35);
+pen Orange=rgbint(255,165,0);
+pen OrangeRed=rgbint(255,69,0);
+pen Orchid=rgbint(218,112,214);
+pen PaleGoldenrod=rgbint(238,232,170);
+pen PaleGreen=rgbint(152,251,152);
+pen PaleTurquoise=rgbint(175,238,238);
+pen PaleVioletRed=rgbint(219,112,147);
+pen PapayaWhip=rgbint(255,239,213);
+pen PeachPuff=rgbint(255,218,185);
+pen Peru=rgbint(205,133,63);
+pen Pink=rgbint(255,192,203);
+pen Plum=rgbint(221,160,221);
+pen PowderBlue=rgbint(176,224,230);
+pen Purple=rgbint(128,0,128);
+pen Red=rgbint(255,0,0);
+pen RosyBrown=rgbint(188,143,143);
+pen RoyalBlue=rgbint(65,105,225);
+pen SaddleBrown=rgbint(139,69,19);
+pen Salmon=rgbint(250,128,114);
+pen SandyBrown=rgbint(244,164,96);
+pen SeaGreen=rgbint(46,139,87);
+pen Seashell=rgbint(255,245,238);
+pen Sienna=rgbint(160,82,45);
+pen Silver=rgbint(192,192,192);
+pen SkyBlue=rgbint(135,206,235);
+pen SlateBlue=rgbint(106,90,205);
+pen SlateGray=rgbint(112,128,144);
+pen Snow=rgbint(255,250,250);
+pen SpringGreen=rgbint(0,255,127);
+pen SteelBlue=rgbint(70,130,180);
+pen Tan=rgbint(210,180,140);
+pen Teal=rgbint(0,128,128);
+pen Thistle=rgbint(216,191,216);
+pen Tomato=rgbint(255,99,71);
+pen Turquoise=rgbint(64,224,208);
+pen Violet=rgbint(238,130,238);
+pen Wheat=rgbint(245,222,179);
+pen White=rgbint(255,255,255);
+pen WhiteSmoke=rgbint(245,245,245);
+pen Yellow=rgbint(255,255,0);
+pen YellowGreen=rgbint(154,205,50);
diff --git a/Build/source/utils/asymptote/bbox.h b/Build/source/utils/asymptote/bbox.h
new file mode 100644
index 00000000000..a4c8c92e0b1
--- /dev/null
+++ b/Build/source/utils/asymptote/bbox.h
@@ -0,0 +1,229 @@
+/*****
+ * bbox.h
+ * Andy Hammerlindl 2002/06/06
+ *
+ * Stores a rectangle that encloses a drawing object.
+ *****/
+
+#ifndef BBOX_H
+#define BBOX_H
+
+#include "pair.h"
+
+namespace camp {
+
+template<class T>
+inline T min(T a, T b)
+{
+ return (a < b) ? a : b;
+}
+
+template<class T>
+inline T max(T a, T b)
+{
+ return (a > b) ? a : b;
+}
+
+// The box that encloses a path
+struct bbox {
+ bool empty;
+ double left;
+ double bottom;
+ double right;
+ double top;
+
+ // Start bbox about the origin
+ bbox()
+ : empty(true), left(0.0), bottom(0.0), right(0.0), top(0.0)
+ {
+ }
+
+ bbox(double left, double bottom, double right, double top)
+ : empty(false), left(left), bottom(bottom), right(right), top(top)
+ {
+ }
+
+ // Start a bbox with a point
+ bbox(const pair& z)
+ : empty(false), left(z.getx()), bottom(z.gety()),
+ right(z.getx()), top(z.gety())
+ {
+ }
+
+ bool nonempty() const {
+ return !empty;
+ }
+
+ // Add a point to a bbox
+ bbox add(const pair& z)
+ {
+ double x = z.getx(), y = z.gety();
+
+ if (empty) {
+ left = right = x;
+ top = bottom = y;
+ empty = false;
+ }
+ else {
+ if (x < left)
+ left = x;
+ else if (x > right)
+ right = x;
+ if (y < bottom)
+ bottom = y;
+ else if (y > top)
+ top = y;
+ }
+
+ return *this;
+ }
+
+ // Add a point to a nonempty bbox
+ void addnonempty(const pair& z)
+ {
+ double x = z.getx(), y = z.gety();
+ if (x < left)
+ left = x;
+ else if (x > right)
+ right = x;
+ if (y < bottom)
+ bottom = y;
+ else if (y > top)
+ top = y;
+ }
+
+ // Add a point to a nonempty bbox, updating bounding times
+ void addnonempty(const pair& z, bbox& times, double t)
+ {
+ double x = z.getx(), y = z.gety();
+
+ if (x < left) {
+ left = x;
+ times.left = t;
+ }
+ else if (x > right) {
+ right = x;
+ times.right = t;
+ }
+ if (y < bottom) {
+ bottom = y;
+ times.bottom = t;
+ }
+ else if (y > top) {
+ top = y;
+ times.top = t;
+ }
+ }
+
+ bbox operator+= (const pair& z)
+ {
+ add(z);
+ return *this;
+ }
+
+ bbox operator*= (double x)
+ {
+ left *= x;
+ right *= x;
+ top *= x;
+ bottom *=x;
+ return *this;
+ }
+
+ // Add two bounding boxes
+ friend bbox operator+ (const bbox& b1, const bbox& b2)
+ {
+ if (b1.empty)
+ return b2;
+ else if (b2.empty)
+ return b1;
+ else
+ return bbox(min(b1.left, b2.left),
+ max(b1.right, b2.right),
+ min(b1.bottom, b2.bottom),
+ max(b1.top, b2.top));
+ }
+
+ // Add one bounding box to another
+ void add(const bbox& b)
+ {
+ if (this->empty)
+ *this = b;
+ else if (!b.empty) {
+ left = min(left, b.left);
+ right = max(right, b.right);
+ bottom = min(bottom, b.bottom);
+ top = max(top, b.top);
+ }
+ }
+
+ bbox operator+= (const bbox& b)
+ {
+ add(b);
+ return *this;
+ }
+
+ void clip(const bbox& b) {
+ if(this->empty) return;
+ left = max(left, b.left);
+ right = min(right, b.right);
+ bottom = max(bottom, b.bottom);
+ top = min(top, b.top);
+ if(left > right || bottom > top)
+ *this=bbox();
+ }
+
+ void shift(const pair& p) {
+ left += p.getx();
+ right += p.getx();
+ bottom += p.gety();
+ top += p.gety();
+ }
+
+ pair Min() const {
+ return pair(left,bottom);
+ }
+
+ pair Max() const {
+ return pair(right,top);
+ }
+
+ double diameter() {
+ return (Max()-Min()).length();
+ }
+
+ bbox LowRes() const
+ {
+ return bbox(floor(left),floor(bottom),ceil(right),ceil(top));
+ }
+
+ friend ostream& operator<< (ostream& out, const bbox& b)
+ {
+ out << b.left << " " << b.bottom << " " << b.right << " " << b.top;
+ return out;
+ }
+};
+
+// Add results of both bounding boxes, say for a path and a pen.
+inline bbox pad(bbox b1, bbox b2)
+{
+ if (b1.empty)
+ return b2;
+ else if (b2.empty)
+ return b1;
+ else {
+ bbox b;
+ b.empty = false;
+ b.left = b1.left + b2.left;
+ b.right = b1.right + b2.right;
+ b.top = b1.top + b2.top;
+ b.bottom = b1.bottom + b2.bottom;
+ return b;
+ }
+}
+
+} // namespace camp
+
+GC_DECLARE_PTRFREE(camp::bbox);
+
+#endif
diff --git a/Build/source/utils/asymptote/bbox3.h b/Build/source/utils/asymptote/bbox3.h
new file mode 100644
index 00000000000..5659f24b6ee
--- /dev/null
+++ b/Build/source/utils/asymptote/bbox3.h
@@ -0,0 +1,153 @@
+/*****
+ * bbox3.h
+ * Andy Hammerlindl 2002/06/06
+ *
+ * Stores a rectangle that encloses a drawing object.
+ *****/
+
+#ifndef BBOX3_H
+#define BBOX3_H
+
+#include "triple.h"
+
+namespace camp {
+
+// The box that encloses a path
+struct bbox3 {
+ bool empty;
+ double left;
+ double bottom;
+ double lower;
+ double right;
+ double top;
+ double upper;
+
+ // Start bbox3 about the origin
+ bbox3()
+ : empty(true), left(0.0), bottom(0.0), lower(0.0),
+ right(0.0), top(0.0), upper(0.0)
+ {
+ }
+
+ bbox3(double left, double bottom, double lower,
+ double right, double top, double upper)
+ : empty(false), left(left), bottom(bottom), lower(lower),
+ right(right), top(top), upper(upper)
+ {
+ }
+
+ // Start a bbox3 with a point
+ bbox3(double x, double y, double z)
+ : empty(false), left(x), bottom(y), lower(z), right(x), top(y), upper(z)
+ {
+ }
+
+ // Start a bbox3 with a point
+ bbox3(const triple& v)
+ : empty(false), left(v.getx()), bottom(v.gety()), lower(v.getz()),
+ right(v.getx()), top(v.gety()), upper(v.getz())
+ {
+ }
+
+ // Add a point to a bbox3
+ void add(const triple& v)
+ {
+ double x = v.getx(), y = v.gety(), z = v.getz();
+
+ if (empty) {
+ left = right = x;
+ top = bottom = y;
+ lower = upper = z;
+ empty = false;
+ }
+ else {
+ if(x < left)
+ left = x;
+ else if(x > right)
+ right = x;
+ if(y < bottom)
+ bottom = y;
+ else if(y > top)
+ top = y;
+ if(z < lower)
+ lower = z;
+ else if(z > upper)
+ upper = z;
+ }
+ }
+
+ // Add a point to a nonempty bbox3
+ void addnonempty(double x, double y, double z)
+ {
+ if(x < left)
+ left = x;
+ else if(x > right)
+ right = x;
+ if(y < bottom)
+ bottom = y;
+ else if(y > top)
+ top = y;
+ if(z < lower)
+ lower = z;
+ else if(z > upper)
+ upper = z;
+ }
+
+ // Add a point to a nonempty bbox3
+ void addnonempty(const triple& v)
+ {
+ addnonempty(v.getx(),v.gety(),v.getz());
+ }
+
+ // Add a point to a nonempty bbox, updating bounding times
+ void addnonempty(const triple& v, bbox3& times, double t)
+ {
+ double x = v.getx(), y = v.gety(), z = v.getz();
+
+ if(x < left) {
+ left = x;
+ times.left = t;
+ }
+ else if(x > right) {
+ right = x;
+ times.right = t;
+ }
+ if(y < bottom) {
+ bottom = y;
+ times.bottom = t;
+ }
+ else if(y > top) {
+ top = y;
+ times.top = t;
+ }
+ if(z < lower) {
+ lower = z;
+ times.lower=t;
+ }
+ else if(z > upper) {
+ upper = z;
+ times.upper=t;
+ }
+ }
+
+ bbox3 operator+= (const triple& v)
+ {
+ add(v);
+ return *this;
+ }
+
+ triple Min() const {
+ return triple(left,bottom,lower);
+ }
+
+ triple Max() const {
+ return triple(right,top,upper);
+ }
+
+};
+
+} // namespace camp
+
+GC_DECLARE_PTRFREE(camp::bbox3);
+
+#endif
diff --git a/Build/source/utils/asymptote/builtin.cc b/Build/source/utils/asymptote/builtin.cc
new file mode 100644
index 00000000000..5b4ed77b38d
--- /dev/null
+++ b/Build/source/utils/asymptote/builtin.cc
@@ -0,0 +1,1411 @@
+/*****
+ * builtin.cc
+ * Tom Prince 2004/08/25
+ *
+ * Initialize builtins.
+ *****/
+
+#include <cmath>
+
+#include "builtin.h"
+#include "entry.h"
+#include "runtime.h"
+#include "types.h"
+
+#include "castop.h"
+#include "mathop.h"
+#include "arrayop.h"
+#include "vm.h"
+
+#include "coder.h"
+#include "exp.h"
+#include "refaccess.h"
+#include "settings.h"
+
+#ifdef HAVE_LIBGSL
+#include <gsl/gsl_math.h>
+#include <gsl/gsl_sf.h>
+#include <gsl/gsl_errno.h>
+#endif
+
+using namespace types;
+using namespace camp;
+using namespace vm;
+
+namespace trans {
+using camp::transform;
+using camp::pair;
+using vm::bltin;
+using run::divide;
+using run::less;
+using run::greater;
+using run::plus;
+using run::minus;
+
+
+using namespace run;
+
+void gen_base_venv(venv &ve);
+
+void addType(tenv &te, const char *name, ty *t)
+{
+ te.enter(symbol::trans(name), new tyEntry(t,0,0,position()));
+}
+
+// The base environments for built-in types and functions
+void base_tenv(tenv &te)
+{
+#define PRIMITIVE(name,Name,asyName) addType(te, #asyName, prim##Name());
+#include <primitives.h>
+#undef PRIMITIVE
+}
+
+const formal noformal(0);
+
+void addFunc(venv &ve, access *a, ty *result, symbol *id,
+ formal f1=noformal, formal f2=noformal, formal f3=noformal,
+ formal f4=noformal, formal f5=noformal, formal f6=noformal,
+ formal f7=noformal, formal f8=noformal, formal f9=noformal,
+ formal fA=noformal, formal fB=noformal, formal fC=noformal,
+ formal fD=noformal, formal fE=noformal, formal fF=noformal)
+{
+ function *fun = new function(result);
+
+ if (f1.t) fun->add(f1);
+ if (f2.t) fun->add(f2);
+ if (f3.t) fun->add(f3);
+ if (f4.t) fun->add(f4);
+ if (f5.t) fun->add(f5);
+ if (f6.t) fun->add(f6);
+ if (f7.t) fun->add(f7);
+ if (f8.t) fun->add(f8);
+ if (f9.t) fun->add(f9);
+ if (fA.t) fun->add(fA);
+ if (fB.t) fun->add(fB);
+ if (fC.t) fun->add(fC);
+ if (fD.t) fun->add(fD);
+ if (fE.t) fun->add(fE);
+ if (fF.t) fun->add(fF);
+
+ // NOTE: If the function is a field, we should encode the defining record in
+ // the entry
+ varEntry *ent = new varEntry(fun, a, 0, position());
+
+ ve.enter(id, ent);
+}
+
+// Add a function with one or more default arguments.
+void addFunc(venv &ve, bltin f, ty *result, const char *name,
+ formal f1, formal f2, formal f3, formal f4, formal f5, formal f6,
+ formal f7, formal f8, formal f9, formal fA, formal fB,
+ formal fC, formal fD, formal fE, formal fF)
+{
+ access *a = new bltinAccess(f);
+ addFunc(ve,a,result,symbol::trans(name),f1,f2,f3,f4,f5,f6,f7,f8,f9,
+ fA,fB,fC,fD,fE,fF);
+}
+
+void addFunc(venv &ve, access *a, ty *result, const char *name, formal f1)
+{
+ addFunc(ve,a,result,symbol::trans(name),f1);
+}
+
+void addOpenFunc(venv &ve, bltin f, ty *result, const char *name)
+{
+ function *fun = new function(result, signature::OPEN);
+
+ access *a= new bltinAccess(f);
+
+ varEntry *ent = new varEntry(fun, a, 0, position());
+
+ ve.enter(symbol::trans(name), ent);
+}
+
+
+// Add a rest function with zero or more default/explicit arguments.
+void addRestFunc(venv &ve, bltin f, ty *result, const char *name, formal frest,
+ formal f1=noformal, formal f2=noformal, formal f3=noformal,
+ formal f4=noformal, formal f5=noformal, formal f6=noformal,
+ formal f7=noformal, formal f8=noformal, formal f9=noformal)
+{
+ access *a = new bltinAccess(f);
+ function *fun = new function(result);
+
+ if (f1.t) fun->add(f1);
+ if (f2.t) fun->add(f2);
+ if (f3.t) fun->add(f3);
+ if (f4.t) fun->add(f4);
+ if (f5.t) fun->add(f5);
+ if (f6.t) fun->add(f6);
+ if (f7.t) fun->add(f7);
+ if (f8.t) fun->add(f8);
+ if (f9.t) fun->add(f9);
+
+ if (frest.t) fun->addRest(frest);
+
+ varEntry *ent = new varEntry(fun, a, 0, position());
+
+ ve.enter(symbol::trans(name), ent);
+}
+
+void addRealFunc0(venv &ve, bltin fcn, const char *name)
+{
+ addFunc(ve, fcn, primReal(), name);
+}
+
+template<double (*fcn)(double)>
+void addRealFunc(venv &ve, const char* name)
+{
+ addFunc(ve, realReal<fcn>, primReal(), name, formal(primReal(),"x"));
+ addFunc(ve, arrayFunc<double,double,fcn>, realArray(), name,
+ formal(realArray(),"a"));
+}
+
+#define addRealFunc(fcn) addRealFunc<fcn>(ve, #fcn);
+
+void addRealFunc2(venv &ve, bltin fcn, const char *name)
+{
+ addFunc(ve,fcn,primReal(),name,formal(primReal(),"a"),
+ formal(primReal(),"b"));
+}
+
+template <double (*func)(double, int)>
+void realRealInt(vm::stack *s) {
+ Int n = pop<Int>(s);
+ double x = pop<double>(s);
+ s->push(func(x, intcast(n)));
+}
+
+template<double (*fcn)(double, int)>
+void addRealIntFunc(venv& ve, const char* name, const char* arg1,
+ const char* arg2) {
+ addFunc(ve, realRealInt<fcn>, primReal(), name, formal(primReal(), arg1),
+ formal(primInt(), arg2));
+}
+
+#ifdef HAVE_LIBGSL
+bool GSLerror=false;
+
+types::dummyRecord *GSLModule;
+
+types::record *getGSLModule()
+{
+ return GSLModule;
+}
+
+inline void checkGSLerror()
+{
+ if(GSLerror) {
+ GSLerror=false;
+ throw handled_error();
+ }
+}
+
+template <double (*func)(double)>
+void realRealGSL(vm::stack *s)
+{
+ double x=pop<double>(s);
+ s->push(func(x));
+ checkGSLerror();
+}
+
+template <double (*func)(double, gsl_mode_t)>
+void realRealDOUBLE(vm::stack *s)
+{
+ double x=pop<double>(s);
+ s->push(func(x,GSL_PREC_DOUBLE));
+ checkGSLerror();
+}
+
+template <double (*func)(double, double, gsl_mode_t)>
+void realRealRealDOUBLE(vm::stack *s)
+{
+ double y=pop<double>(s);
+ double x=pop<double>(s);
+ s->push(func(x,y,GSL_PREC_DOUBLE));
+ checkGSLerror();
+}
+
+template <double (*func)(unsigned)>
+void realIntGSL(vm::stack *s)
+{
+ s->push(func(unsignedcast(pop<Int>(s))));
+ checkGSLerror();
+}
+
+template <double (*func)(int, double)>
+void realIntRealGSL(vm::stack *s)
+{
+ double x=pop<double>(s);
+
+ s->push(func(intcast(pop<Int>(s)),x));
+ checkGSLerror();
+}
+
+template <double (*func)(double, double)>
+void realRealRealGSL(vm::stack *s)
+{
+ double x=pop<double>(s);
+ double n=pop<double>(s);
+ s->push(func(n,x));
+ checkGSLerror();
+}
+
+template <int (*func)(double, double, double)>
+void intRealRealRealGSL(vm::stack *s)
+{
+ double x=pop<double>(s);
+ double n=pop<double>(s);
+ double a=pop<double>(s);
+ s->push(func(a,n,x));
+ checkGSLerror();
+}
+
+template <double (*func)(double, double, double)>
+void realRealRealRealGSL(vm::stack *s)
+{
+ double x=pop<double>(s);
+ double n=pop<double>(s);
+ double a=pop<double>(s);
+ s->push(func(a,n,x));
+ checkGSLerror();
+}
+
+template <double (*func)(double, unsigned)>
+void realRealIntGSL(vm::stack *s)
+{
+ Int n=pop<Int>(s);
+ double x=pop<double>(s);
+ s->push(func(x,unsignedcast(n)));
+ checkGSLerror();
+}
+
+// Add a GSL special function from the GNU GSL library
+template<double (*fcn)(double)>
+void addGSLRealFunc(const char* name, const char* arg1="x")
+{
+ addFunc(GSLModule->e.ve, realRealGSL<fcn>, primReal(), name,
+ formal(primReal(),arg1));
+}
+
+// Add a GSL_PREC_DOUBLE GSL special function.
+template<double (*fcn)(double, gsl_mode_t)>
+void addGSLDOUBLEFunc(const char* name, const char* arg1="x")
+{
+ addFunc(GSLModule->e.ve, realRealDOUBLE<fcn>, primReal(), name,
+ formal(primReal(),arg1));
+}
+
+template<double (*fcn)(double, double, gsl_mode_t)>
+void addGSLDOUBLE2Func(const char* name, const char* arg1="phi",
+ const char* arg2="k")
+{
+ addFunc(GSLModule->e.ve, realRealRealDOUBLE<fcn>, primReal(), name,
+ formal(primReal(),arg1), formal(primReal(),arg2));
+}
+
+template <double (*func)(double, double, double, gsl_mode_t)>
+void realRealRealRealDOUBLE(vm::stack *s)
+{
+ double z=pop<double>(s);
+ double y=pop<double>(s);
+ double x=pop<double>(s);
+ s->push(func(x,y,z,GSL_PREC_DOUBLE));
+ checkGSLerror();
+}
+
+template<double (*fcn)(double, double, double, gsl_mode_t)>
+void addGSLDOUBLE3Func(const char* name, const char* arg1, const char* arg2,
+ const char* arg3)
+{
+ addFunc(GSLModule->e.ve, realRealRealRealDOUBLE<fcn>, primReal(), name,
+ formal(primReal(),arg1), formal(primReal(),arg2),
+ formal(primReal(), arg3));
+}
+
+template <double (*func)(double, double, double, double, gsl_mode_t)>
+void realRealRealRealRealDOUBLE(vm::stack *s)
+{
+ double z=pop<double>(s);
+ double y=pop<double>(s);
+ double x=pop<double>(s);
+ double w=pop<double>(s);
+ s->push(func(w,x,y,z,GSL_PREC_DOUBLE));
+ checkGSLerror();
+}
+
+template<double (*fcn)(double, double, double, double, gsl_mode_t)>
+void addGSLDOUBLE4Func(const char* name, const char* arg1, const char* arg2,
+ const char* arg3, const char* arg4)
+{
+ addFunc(GSLModule->e.ve, realRealRealRealRealDOUBLE<fcn>, primReal(), name,
+ formal(primReal(),arg1), formal(primReal(),arg2),
+ formal(primReal(), arg3), formal(primReal(), arg4));
+}
+
+template<double (*fcn)(unsigned)>
+void addGSLIntFunc(const char* name)
+{
+ addFunc(GSLModule->e.ve, realIntGSL<fcn>, primReal(), name,
+ formal(primInt(),"s"));
+}
+
+template <double (*func)(int)>
+void realSignedGSL(vm::stack *s)
+{
+ Int a = pop<Int>(s);
+ s->push(func(intcast(a)));
+ checkGSLerror();
+}
+
+template<double (*fcn)(int)>
+void addGSLSignedFunc(const char* name, const char* arg1)
+{
+ addFunc(GSLModule->e.ve, realSignedGSL<fcn>, primReal(), name,
+ formal(primInt(),arg1));
+}
+
+template<double (*fcn)(int, double)>
+void addGSLIntRealFunc(const char* name, const char *arg1="n",
+ const char* arg2="x")
+{
+ addFunc(GSLModule->e.ve, realIntRealGSL<fcn>, primReal(), name,
+ formal(primInt(),arg1), formal(primReal(),arg2));
+}
+
+template<double (*fcn)(double, double)>
+void addGSLRealRealFunc(const char* name, const char* arg1="nu",
+ const char* arg2="x")
+{
+ addFunc(GSLModule->e.ve, realRealRealGSL<fcn>, primReal(), name,
+ formal(primReal(),arg1), formal(primReal(),arg2));
+}
+
+template<double (*fcn)(double, double, double)>
+void addGSLRealRealRealFunc(const char* name, const char* arg1,
+ const char* arg2, const char* arg3)
+{
+ addFunc(GSLModule->e.ve, realRealRealRealGSL<fcn>, primReal(), name,
+ formal(primReal(),arg1), formal(primReal(),arg2),
+ formal(primReal(), arg3));
+}
+
+template<int (*fcn)(double, double, double)>
+void addGSLRealRealRealFuncInt(const char* name, const char* arg1,
+ const char* arg2, const char* arg3)
+{
+ addFunc(GSLModule->e.ve, intRealRealRealGSL<fcn>, primInt(), name,
+ formal(primReal(),arg1), formal(primReal(),arg2),
+ formal(primReal(), arg3));
+}
+
+template<double (*fcn)(double, unsigned)>
+void addGSLRealIntFunc(const char* name, const char* arg1="nu",
+ const char* arg2="s")
+{
+ addFunc(GSLModule->e.ve, realRealIntGSL<fcn>, primReal(), name,
+ formal(primReal(),arg1), formal(primInt(),arg2));
+}
+
+template<double (*func)(double, int)>
+void realRealSignedGSL(vm::stack *s)
+{
+ Int b = pop<Int>(s);
+ double a = pop<double>(s);
+ s->push(func(a, intcast(b)));
+ checkGSLerror();
+}
+
+template<double (*fcn)(double, int)>
+void addGSLRealSignedFunc(const char* name, const char* arg1, const char* arg2)
+{
+ addFunc(GSLModule->e.ve, realRealSignedGSL<fcn>, primReal(), name,
+ formal(primReal(),arg1), formal(primInt(),arg2));
+}
+
+template<double (*func)(unsigned int, unsigned int)>
+void realUnsignedUnsignedGSL(vm::stack *s)
+{
+ Int b = pop<Int>(s);
+ Int a = pop<Int>(s);
+ s->push(func(unsignedcast(a), unsignedcast(b)));
+ checkGSLerror();
+}
+
+template<double (*fcn)(unsigned int, unsigned int)>
+void addGSLUnsignedUnsignedFunc(const char* name, const char* arg1,
+ const char* arg2)
+{
+ addFunc(GSLModule->e.ve, realUnsignedUnsignedGSL<fcn>, primReal(), name,
+ formal(primInt(), arg1), formal(primInt(), arg2));
+}
+
+template<double (*func)(int, double, double)>
+void realIntRealRealGSL(vm::stack *s)
+{
+ double c = pop<double>(s);
+ double b = pop<double>(s);
+ Int a = pop<Int>(s);
+ s->push(func(intcast(a), b, c));
+ checkGSLerror();
+}
+
+template<double (*fcn)(int, double, double)>
+void addGSLIntRealRealFunc(const char* name, const char* arg1,
+ const char* arg2, const char* arg3)
+{
+ addFunc(GSLModule->e.ve, realIntRealRealGSL<fcn>, primReal(), name,
+ formal(primInt(), arg1), formal(primReal(), arg2),
+ formal(primReal(), arg3));
+}
+
+template<double (*func)(int, int, double)>
+void realIntIntRealGSL(vm::stack *s)
+{
+ double c = pop<double>(s);
+ Int b = pop<Int>(s);
+ Int a = pop<Int>(s);
+ s->push(func(intcast(a), intcast(b), c));
+ checkGSLerror();
+}
+
+template<double (*fcn)(int, int, double)>
+void addGSLIntIntRealFunc(const char* name, const char* arg1, const char* arg2,
+ const char* arg3)
+{
+ addFunc(GSLModule->e.ve, realIntIntRealGSL<fcn>, primReal(), name,
+ formal(primInt(), arg1), formal(primInt(), arg2),
+ formal(primReal(), arg3));
+}
+
+template<double (*func)(int, int, double, double)>
+void realIntIntRealRealGSL(vm::stack *s)
+{
+ double d = pop<double>(s);
+ double c = pop<double>(s);
+ Int b = pop<Int>(s);
+ Int a = pop<Int>(s);
+ s->push(func(intcast(a), intcast(b), c, d));
+ checkGSLerror();
+}
+
+template<double (*fcn)(int, int, double, double)>
+void addGSLIntIntRealRealFunc(const char* name, const char* arg1,
+ const char* arg2, const char* arg3,
+ const char* arg4)
+{
+ addFunc(GSLModule->e.ve, realIntIntRealRealGSL<fcn>, primReal(), name,
+ formal(primInt(), arg1), formal(primInt(), arg2),
+ formal(primReal(), arg3), formal(primReal(), arg4));
+}
+
+template<double (*func)(double, double, double, double)>
+void realRealRealRealRealGSL(vm::stack *s)
+{
+ double d = pop<double>(s);
+ double c = pop<double>(s);
+ double b = pop<double>(s);
+ double a = pop<double>(s);
+ s->push(func(a, b, c, d));
+ checkGSLerror();
+}
+
+template<double (*fcn)(double, double, double, double)>
+void addGSLRealRealRealRealFunc(const char* name, const char* arg1,
+ const char* arg2, const char* arg3,
+ const char* arg4)
+{
+ addFunc(GSLModule->e.ve, realRealRealRealRealGSL<fcn>, primReal(), name,
+ formal(primReal(), arg1), formal(primReal(), arg2),
+ formal(primReal(), arg3), formal(primReal(), arg4));
+}
+
+template<double (*func)(int, int, int, int, int, int)>
+void realIntIntIntIntIntIntGSL(vm::stack *s)
+{
+ Int f = pop<Int>(s);
+ Int e = pop<Int>(s);
+ Int d = pop<Int>(s);
+ Int c = pop<Int>(s);
+ Int b = pop<Int>(s);
+ Int a = pop<Int>(s);
+ s->push(func(intcast(a), intcast(b), intcast(c), intcast(d), intcast(e),
+ intcast(f)));
+ checkGSLerror();
+}
+
+template<double (*fcn)(int, int, int, int, int, int)>
+void addGSLIntIntIntIntIntIntFunc(const char* name, const char* arg1,
+ const char* arg2, const char* arg3,
+ const char* arg4, const char* arg5,
+ const char* arg6)
+{
+ addFunc(GSLModule->e.ve, realIntIntIntIntIntIntGSL<fcn>, primReal(), name,
+ formal(primInt(), arg1), formal(primInt(), arg2),
+ formal(primInt(), arg3), formal(primInt(), arg4),
+ formal(primInt(), arg5), formal(primInt(), arg6));
+}
+
+template<double (*func)(int, int, int, int, int, int, int, int, int)>
+void realIntIntIntIntIntIntIntIntIntGSL(vm::stack *s)
+{
+ Int i = pop<Int>(s);
+ Int h = pop<Int>(s);
+ Int g = pop<Int>(s);
+ Int f = pop<Int>(s);
+ Int e = pop<Int>(s);
+ Int d = pop<Int>(s);
+ Int c = pop<Int>(s);
+ Int b = pop<Int>(s);
+ Int a = pop<Int>(s);
+ s->push(func(intcast(a), intcast(b), intcast(c), intcast(d), intcast(e),
+ intcast(f), intcast(g), intcast(h), intcast(i)));
+ checkGSLerror();
+}
+
+template<double (*fcn)(int, int, int, int, int, int, int, int, int)>
+void addGSLIntIntIntIntIntIntIntIntIntFunc(const char* name, const char* arg1,
+ const char* arg2, const char* arg3,
+ const char* arg4, const char* arg5,
+ const char* arg6, const char* arg7,
+ const char* arg8, const char* arg9)
+{
+ addFunc(GSLModule->e.ve, realIntIntIntIntIntIntIntIntIntGSL<fcn>, primReal(),
+ name, formal(primInt(), arg1), formal(primInt(), arg2),
+ formal(primInt(), arg3), formal(primInt(), arg4),
+ formal(primInt(), arg5), formal(primInt(), arg6),
+ formal(primInt(), arg7), formal(primInt(), arg8),
+ formal(primInt(), arg9));
+}
+
+// Handle GSL errors gracefully.
+void GSLerrorhandler(const char *reason, const char *, int, int)
+{
+ if(!GSLerror) {
+ vm::errornothrow(reason);
+ GSLerror=true;
+ }
+}
+#endif
+
+void addInitializer(venv &ve, ty *t, access *a)
+{
+ addFunc(ve, a, t, symbol::initsym);
+}
+
+void addInitializer(venv &ve, ty *t, bltin f)
+{
+ access *a = new bltinAccess(f);
+ addInitializer(ve, t, a);
+}
+
+// Specifies that source may be cast to target, but only if an explicit
+// cast expression is used.
+void addExplicitCast(venv &ve, ty *target, ty *source, access *a) {
+ addFunc(ve, a, target, symbol::ecastsym, source);
+}
+
+// Specifies that source may be implicitly cast to target by the
+// function or instruction stores at a.
+void addCast(venv &ve, ty *target, ty *source, access *a) {
+ //addExplicitCast(target,source,a);
+ addFunc(ve, a, target, symbol::castsym, source);
+}
+
+void addExplicitCast(venv &ve, ty *target, ty *source, bltin f) {
+ addExplicitCast(ve, target, source, new bltinAccess(f));
+}
+
+void addCast(venv &ve, ty *target, ty *source, bltin f) {
+ addCast(ve, target, source, new bltinAccess(f));
+}
+
+template<class T>
+void addVariable(venv &ve, T *ref, ty *t, const char *name,
+ record *module=settings::getSettingsModule()) {
+ access *a = new refAccess<T>(ref);
+ varEntry *ent = new varEntry(t, a, PUBLIC, module, 0, position());
+ ve.enter(symbol::trans(name), ent);
+}
+
+template<class T>
+void addVariable(venv &ve, T value, ty *t, const char *name,
+ record *module=settings::getSettingsModule(),
+ permission perm=PUBLIC) {
+ item* ref=new item;
+ *ref=value;
+ access *a = new itemRefAccess(ref);
+ varEntry *ent = new varEntry(t, a, perm, module, 0, position());
+ ve.enter(symbol::trans(name), ent);
+}
+
+template<class T>
+void addConstant(venv &ve, T value, ty *t, const char *name,
+ record *module=settings::getSettingsModule()) {
+ addVariable(ve,value,t,name,module,RESTRICTED);
+}
+
+// The identity access, i.e. no instructions are encoded for a cast or
+// operation, and no functions are called.
+identAccess id;
+
+function *IntRealFunction()
+{
+ return new function(primInt(),primReal());
+}
+
+function *realPairFunction()
+{
+ return new function(primReal(),primPair());
+}
+
+function *voidFileFunction()
+{
+ return new function(primVoid(),primFile());
+}
+
+void addInitializers(venv &ve)
+{
+ addInitializer(ve, primBoolean(), boolFalse);
+ addInitializer(ve, primInt(), IntZero);
+ addInitializer(ve, primReal(), realZero);
+
+ addInitializer(ve, primString(), emptyString);
+ addInitializer(ve, primPair(), pairZero);
+ addInitializer(ve, primTriple(), tripleZero);
+ addInitializer(ve, primTransform(), transformIdentity);
+ addInitializer(ve, primGuide(), nullGuide);
+ addInitializer(ve, primPath(), nullPath);
+ addInitializer(ve, primPath3(), nullPath3);
+ addInitializer(ve, primPen(), newPen);
+ addInitializer(ve, primPicture(), newPicture);
+ addInitializer(ve, primFile(), nullFile);
+}
+
+void addCasts(venv &ve)
+{
+ addExplicitCast(ve, primString(), primInt(), stringCast<Int>);
+ addExplicitCast(ve, primString(), primReal(), stringCast<double>);
+ addExplicitCast(ve, primString(), primPair(), stringCast<pair>);
+ addExplicitCast(ve, primString(), primTriple(), stringCast<triple>);
+ addExplicitCast(ve, primInt(), primString(), castString<Int>);
+ addExplicitCast(ve, primReal(), primString(), castString<double>);
+ addExplicitCast(ve, primPair(), primString(), castString<pair>);
+ addExplicitCast(ve, primTriple(), primString(), castString<triple>);
+
+ addExplicitCast(ve, primInt(), primReal(), castDoubleInt);
+
+ addCast(ve, primReal(), primInt(), cast<Int,double>);
+ addCast(ve, primPair(), primInt(), cast<Int,pair>);
+ addCast(ve, primPair(), primReal(), cast<double,pair>);
+
+ addCast(ve, primPath(), primPair(), cast<pair,path>);
+ addCast(ve, primGuide(), primPair(), pairToGuide);
+ addCast(ve, primGuide(), primPath(), pathToGuide);
+ addCast(ve, primPath(), primGuide(), guideToPath);
+
+ addCast(ve, primFile(), primNull(), nullFile);
+
+ // Vectorized casts.
+ addExplicitCast(ve, IntArray(), realArray(), arrayToArray<double,Int>);
+
+ addCast(ve, realArray(), IntArray(), arrayToArray<Int,double>);
+ addCast(ve, pairArray(), IntArray(), arrayToArray<Int,pair>);
+ addCast(ve, pairArray(), realArray(), arrayToArray<double,pair>);
+}
+
+void addGuideOperators(venv &ve)
+{
+ // The guide operators .. and -- take an array of guides, and turn them
+ // into a single guide.
+ addRestFunc(ve, dotsGuide, primGuide(), "..", guideArray());
+ addRestFunc(ve, dashesGuide, primGuide(), "--", guideArray());
+}
+
+/* Avoid typing the same type three times. */
+void addSimpleOperator(venv &ve, bltin f, ty *t, const char *name)
+{
+ addFunc(ve,f,t,name,formal(t,"a"),formal(t,"b"));
+}
+void addBooleanOperator(venv &ve, bltin f, ty *t, const char *name)
+{
+ addFunc(ve,f,primBoolean(),name,formal(t,"a"),formal(t,"b"));
+}
+
+template<class T, template <class S> class op>
+void addOps(venv &ve, ty *t1, const char *name, ty *t2)
+{
+ addSimpleOperator(ve,binaryOp<T,op>,t1,name);
+ addFunc(ve,opArray<T,T,op>,t2,name,formal(t1,"a"),formal(t2,"b"));
+ addFunc(ve,arrayOp<T,T,op>,t2,name,formal(t2,"a"),formal(t1,"b"));
+ addSimpleOperator(ve,arrayArrayOp<T,op>,t2,name);
+}
+
+template<class T, template <class S> class op>
+void addBooleanOps(venv &ve, ty *t1, const char *name, ty *t2)
+{
+ addBooleanOperator(ve,binaryOp<T,op>,t1,name);
+ addFunc(ve,opArray<T,T,op>,boolArray(),name,formal(t1,"a"),formal(t2,"b"));
+ addFunc(ve,arrayOp<T,T,op>,boolArray(),name,formal(t2,"a"),formal(t1,"b"));
+ addFunc(ve,arrayArrayOp<T,op>,boolArray(),name,formal(t2,"a"),
+ formal(t2,"b"));
+}
+
+void addWrite(venv &ve, bltin f, ty *t1, ty *t2)
+{
+ addRestFunc(ve,f,primVoid(),"write",t2,
+ formal(primFile(),"file",true),formal(primString(),"s",true),
+ formal(t1,"x"),formal(voidFileFunction(),"suffix",true));
+}
+
+template<class T>
+void addUnorderedOps(venv &ve, ty *t1, ty *t2, ty *t3, ty *t4)
+{
+ addBooleanOps<T,equals>(ve,t1,"==",t2);
+ addBooleanOps<T,notequals>(ve,t1,"!=",t2);
+
+ addCast(ve,t1,primFile(),read<T>);
+ addCast(ve,t2,primFile(),readArray<T>);
+ addCast(ve,t3,primFile(),readArray<T>);
+ addCast(ve,t4,primFile(),readArray<T>);
+
+ addWrite(ve,write<T>,t1,t2);
+ addRestFunc(ve,writeArray<T>,primVoid(),"write",t3,
+ formal(primFile(),"file",true),formal(primString(),"s",true),
+ formal(t2,"a",false,true));
+ addFunc(ve,writeArray2<T>,primVoid(),"write",
+ formal(primFile(),"file",true),t3);
+ addFunc(ve,writeArray3<T>,primVoid(),"write",
+ formal(primFile(),"file",true),t4);
+}
+
+inline double abs(pair z) {
+ return z.length();
+}
+
+inline double abs(triple v) {
+ return v.length();
+}
+
+template<class T, template <class S> class op>
+void addBinOps(venv &ve, ty *t1, ty *t2, ty *t3, ty *t4, const char *name)
+{
+ addFunc(ve,binopArray<T,op>,t1,name,formal(t2,"a"));
+ addFunc(ve,binopArray2<T,op>,t1,name,formal(t3,"a"));
+ addFunc(ve,binopArray3<T,op>,t1,name,formal(t4,"a"));
+}
+
+template<class T>
+void addOrderedOps(venv &ve, ty *t1, ty *t2, ty *t3, ty *t4)
+{
+ addBooleanOps<T,less>(ve,t1,"<",t2);
+ addBooleanOps<T,lessequals>(ve,t1,"<=",t2);
+ addBooleanOps<T,greaterequals>(ve,t1,">=",t2);
+ addBooleanOps<T,greater>(ve,t1,">",t2);
+
+ addOps<T,run::min>(ve,t1,"min",t2);
+ addOps<T,run::max>(ve,t1,"max",t2);
+ addBinOps<T,run::min>(ve,t1,t2,t3,t4,"min");
+ addBinOps<T,run::max>(ve,t1,t2,t3,t4,"max");
+
+ addFunc(ve,sortArray<T>,t2,"sort",formal(t2,"a"));
+ addFunc(ve,sortArray2<T>,t3,"sort",formal(t3,"a"));
+
+ addFunc(ve,searchArray<T>,primInt(),"search",formal(t2,"a"),
+ formal(t1,"key"));
+}
+
+template<class T>
+void addBasicOps(venv &ve, ty *t1, ty *t2, ty *t3, ty *t4, bool integer=false,
+ bool Explicit=false)
+{
+ addOps<T,plus>(ve,t1,"+",t2);
+ addOps<T,minus>(ve,t1,"-",t2);
+
+ addFunc(ve,&id,t1,"+",formal(t1,"a"));
+ addFunc(ve,&id,t2,"+",formal(t2,"a"));
+ addFunc(ve,Negate<T>,t1,"-",formal(t1,"a"));
+ addFunc(ve,arrayNegate<T>,t2,"-",formal(t2,"a"));
+ if(!integer) addFunc(ve,interp<T>,t1,"interp",formal(t1,"a",false,Explicit),
+ formal(t1,"b",false,Explicit),
+ formal(primReal(),"t"));
+
+ addFunc(ve,sumArray<T>,t1,"sum",formal(t2,"a"));
+ addUnorderedOps<T>(ve,t1,t2,t3,t4);
+}
+
+template<class T>
+void addOps(venv &ve, ty *t1, ty *t2, ty *t3, ty *t4, bool integer=false,
+ bool Explicit=false)
+{
+ addBasicOps<T>(ve,t1,t2,t3,t4,integer,Explicit);
+ addOps<T,times>(ve,t1,"*",t2);
+ if(!integer) addOps<T,run::divide>(ve,t1,"/",t2);
+ addOps<T,power>(ve,t1,"^",t2);
+}
+
+
+// Adds standard functions for a newly added array type.
+void addArrayOps(venv &ve, types::array *t)
+{
+ ty *ct = t->celltype;
+
+ addFunc(ve, run::arrayAlias,
+ primBoolean(), "alias", formal(t, "a"), formal(t, "b"));
+
+ addFunc(ve, run::newDuplicateArray,
+ t, "array", formal(primInt(), "n"),
+ formal(ct, "value"),
+ formal(primInt(), "depth", /*optional=*/ true));
+
+ switch (t->depth()) {
+ case 1:
+ addFunc(ve, run::arrayCopy, t, "copy", formal(t, "a"));
+ addRestFunc(ve, run::arrayConcat, t, "concat", new types::array(t));
+ addFunc(ve, run::arraySequence,
+ t, "sequence", formal(new function(ct, primInt()), "f"),
+ formal(primInt(), "n"));
+ addFunc(ve, run::arrayFunction,
+ t, "map", formal(new function(ct, ct), "f"), formal(t, "a"));
+ addFunc(ve, run::arraySort,
+ t, "sort", formal(t, "a"),
+ formal(new function(primBoolean(), ct, ct), "f"));
+ break;
+ case 2:
+ addFunc(ve, run::array2Copy, t, "copy", formal(t, "a"));
+ addFunc(ve, run::array2Transpose, t, "transpose", formal(t, "a"));
+ break;
+ case 3:
+ addFunc(ve, run::array3Copy, t, "copy", formal(t, "a"));
+ addFunc(ve, run::array3Transpose, t, "transpose", formal(t, "a"),
+ formal(IntArray(),"perm"));
+ break;
+ default:
+ break;
+ }
+}
+
+void addRecordOps(venv &ve, record *r)
+{
+ addFunc(ve, run::boolMemEq, primBoolean(), "alias", types::formal(r, "a"),
+ types::formal(r, "b"));
+ addFunc(ve, run::boolMemEq, primBoolean(), "==", types::formal(r, "a"),
+ types::formal(r, "b"));
+ addFunc(ve, run::boolMemNeq, primBoolean(), "!=", types::formal(r, "a"),
+ types::formal(r, "b"));
+}
+
+void addFunctionOps(venv &ve, function *f)
+{
+ addFunc(ve, run::boolFuncEq, primBoolean(), "==", types::formal(f, "a"),
+ types::formal(f, "b"));
+ addFunc(ve, run::boolFuncNeq, primBoolean(), "!=", types::formal(f, "a"),
+ types::formal(f, "b"));
+}
+
+void addOperators(venv &ve)
+{
+ addSimpleOperator(ve,binaryOp<string,plus>,primString(),"+");
+
+ addBooleanOps<bool,And>(ve,primBoolean(),"&",boolArray());
+ addBooleanOps<bool,Or>(ve,primBoolean(),"|",boolArray());
+ addBooleanOps<bool,Xor>(ve,primBoolean(),"^",boolArray());
+
+ addUnorderedOps<bool>(ve,primBoolean(),boolArray(),boolArray2(),
+ boolArray3());
+ addOps<Int>(ve,primInt(),IntArray(),IntArray2(),IntArray3(),true);
+ addOps<double>(ve,primReal(),realArray(),realArray2(),realArray3());
+ addOps<pair>(ve,primPair(),pairArray(),pairArray2(),pairArray3(),false,true);
+ addBasicOps<triple>(ve,primTriple(),tripleArray(),tripleArray2(),
+ tripleArray3());
+ addFunc(ve,opArray<double,triple,times>,tripleArray(),"*",
+ formal(primReal(),"a"),formal(tripleArray(),"b"));
+ addFunc(ve,arrayOp<triple,double,timesR>,tripleArray(),"*",
+ formal(tripleArray(),"a"),formal(primReal(),"b"));
+ addFunc(ve,arrayOp<triple,double,divide>,tripleArray(),"/",
+ formal(tripleArray(),"a"),formal(primReal(),"b"));
+
+ addUnorderedOps<string>(ve,primString(),stringArray(),stringArray2(),
+ stringArray3());
+
+ addSimpleOperator(ve,binaryOp<pair,minbound>,primPair(),"minbound");
+ addSimpleOperator(ve,binaryOp<pair,maxbound>,primPair(),"maxbound");
+ addSimpleOperator(ve,binaryOp<triple,minbound>,primTriple(),"minbound");
+ addSimpleOperator(ve,binaryOp<triple,maxbound>,primTriple(),"maxbound");
+ addBinOps<pair,minbound>(ve,primPair(),pairArray(),pairArray2(),pairArray3(),
+ "minbound");
+ addBinOps<pair,maxbound>(ve,primPair(),pairArray(),pairArray2(),pairArray3(),
+ "maxbound");
+ addBinOps<triple,minbound>(ve,primTriple(),tripleArray(),tripleArray2(),
+ tripleArray3(),"minbound");
+ addBinOps<triple,maxbound>(ve,primTriple(),tripleArray(),tripleArray2(),
+ tripleArray3(),"maxbound");
+
+ addFunc(ve,arrayFunc<double,pair,abs>,realArray(),"abs",
+ formal(pairArray(),"a"));
+ addFunc(ve,arrayFunc<double,triple,abs>,realArray(),"abs",
+ formal(tripleArray(),"a"));
+
+ addFunc(ve,binaryOp<Int,divide>,primReal(),"/",
+ formal(primInt(),"a"),formal(primInt(),"b"));
+ addFunc(ve,arrayOp<Int,Int,divide>,realArray(),"/",
+ formal(IntArray(),"a"),formal(primInt(),"b"));
+ addFunc(ve,opArray<Int,Int,divide>,realArray(),"/",
+ formal(primInt(),"a"),formal(IntArray(),"b"));
+ addFunc(ve,arrayArrayOp<Int,divide>,realArray(),"/",
+ formal(IntArray(),"a"),formal(IntArray(),"b"));
+
+ addOrderedOps<Int>(ve,primInt(),IntArray(),IntArray2(),IntArray3());
+ addOrderedOps<double>(ve,primReal(),realArray(),realArray2(),realArray3());
+ addOrderedOps<string>(ve,primString(),stringArray(),stringArray2(),
+ stringArray3());
+
+ addOps<Int,mod>(ve,primInt(),"%",IntArray());
+ addOps<double,mod>(ve,primReal(),"%",realArray());
+
+ addRestFunc(ve,run::diagonal,realArray2(),"diagonal",realArray());
+}
+
+dummyRecord *createDummyRecord(venv &ve, const char *name)
+{
+ dummyRecord *r=new dummyRecord(name);
+ addConstant(ve, new vm::frame(0), r, name);
+ addRecordOps(ve, r);
+ return r;
+}
+
+double identity(double x) {return x;}
+double pow10(double x) {return run::pow(10.0,x);}
+
+// An example of an open function.
+#ifdef OPENFUNCEXAMPLE
+void openFunc(stack *Stack)
+{
+ vm::array *a=vm::pop<vm::array *>(Stack);
+ size_t numArgs=checkArray(a);
+ for (size_t k=0; k<numArgs; ++k)
+ cout << k << ": " << (*a)[k];
+
+ Stack->push<Int>((Int)numArgs);
+}
+#endif
+
+// NOTE: We should move all of these into a "builtin" module.
+void base_venv(venv &ve)
+{
+ addInitializers(ve);
+ addCasts(ve);
+ addOperators(ve);
+ addGuideOperators(ve);
+
+ addRealFunc(sin);
+ addRealFunc(cos);
+ addRealFunc(tan);
+ addRealFunc(asin);
+ addRealFunc(acos);
+ addRealFunc(atan);
+ addRealFunc(exp);
+ addRealFunc(log);
+ addRealFunc(log10);
+ addRealFunc(sinh);
+ addRealFunc(cosh);
+ addRealFunc(tanh);
+ addRealFunc(asinh);
+ addRealFunc(acosh);
+ addRealFunc(atanh);
+ addRealFunc(sqrt);
+ addRealFunc(cbrt);
+ addRealFunc(fabs);
+ addRealFunc<fabs>(ve,"abs");
+ addRealFunc(expm1);
+ addRealFunc(log1p);
+ addRealIntFunc<ldexp>(ve, "ldexp", "x", "e");
+
+ addRealFunc(pow10);
+ addRealFunc(identity);
+
+#ifdef HAVE_LIBGSL
+ GSLModule=new types::dummyRecord(symbol::trans("gsl"));
+ gsl_set_error_handler(GSLerrorhandler);
+
+ // Common functions
+ addGSLRealRealFunc<gsl_hypot>("hypot","x","y");
+// addGSLRealRealRealFunc<gsl_hypot3>("hypot","x","y","z");
+ addGSLRealRealRealFuncInt<gsl_fcmp>("fcmp","x","y","epsilon");
+
+ // Airy functions
+ addGSLDOUBLEFunc<gsl_sf_airy_Ai>("Ai");
+ addGSLDOUBLEFunc<gsl_sf_airy_Bi>("Bi");
+ addGSLDOUBLEFunc<gsl_sf_airy_Ai_scaled>("Ai_scaled");
+ addGSLDOUBLEFunc<gsl_sf_airy_Bi_scaled>("Bi_scaled");
+ addGSLDOUBLEFunc<gsl_sf_airy_Ai_deriv>("Ai_deriv");
+ addGSLDOUBLEFunc<gsl_sf_airy_Bi_deriv>("Bi_deriv");
+ addGSLDOUBLEFunc<gsl_sf_airy_Ai_deriv_scaled>("Ai_deriv_scaled");
+ addGSLDOUBLEFunc<gsl_sf_airy_Bi_deriv_scaled>("Bi_deriv_scaled");
+ addGSLIntFunc<gsl_sf_airy_zero_Ai>("zero_Ai");
+ addGSLIntFunc<gsl_sf_airy_zero_Bi>("zero_Bi");
+ addGSLIntFunc<gsl_sf_airy_zero_Ai_deriv>("zero_Ai_deriv");
+ addGSLIntFunc<gsl_sf_airy_zero_Bi_deriv>("zero_Bi_deriv");
+
+ // Bessel functions
+ addGSLRealFunc<gsl_sf_bessel_J0>("J0");
+ addGSLRealFunc<gsl_sf_bessel_J1>("J1");
+ addGSLIntRealFunc<gsl_sf_bessel_Jn>("Jn");
+ addGSLRealFunc<gsl_sf_bessel_Y0>("Y0");
+ addGSLRealFunc<gsl_sf_bessel_Y1>("Y1");
+ addGSLIntRealFunc<gsl_sf_bessel_Yn>("Yn");
+ addGSLRealFunc<gsl_sf_bessel_I0>("I0");
+ addGSLRealFunc<gsl_sf_bessel_I1>("I1");
+ addGSLIntRealFunc<gsl_sf_bessel_In>("I");
+ addGSLRealFunc<gsl_sf_bessel_I0_scaled>("I0_scaled");
+ addGSLRealFunc<gsl_sf_bessel_I1_scaled>("I1_scaled");
+ addGSLIntRealFunc<gsl_sf_bessel_In_scaled>("I_scaled");
+ addGSLRealFunc<gsl_sf_bessel_K0>("K0");
+ addGSLRealFunc<gsl_sf_bessel_K1>("K1");
+ addGSLIntRealFunc<gsl_sf_bessel_Kn>("K");
+ addGSLRealFunc<gsl_sf_bessel_K0_scaled>("K0_scaled");
+ addGSLRealFunc<gsl_sf_bessel_K1_scaled>("K1_scaled");
+ addGSLIntRealFunc<gsl_sf_bessel_Kn_scaled>("K_scaled");
+ addGSLRealFunc<gsl_sf_bessel_j0>("j0");
+ addGSLRealFunc<gsl_sf_bessel_j1>("j1");
+ addGSLRealFunc<gsl_sf_bessel_j2>("j2");
+ addGSLIntRealFunc<gsl_sf_bessel_jl>("j","l");
+ addGSLRealFunc<gsl_sf_bessel_y0>("y0");
+ addGSLRealFunc<gsl_sf_bessel_y1>("y1");
+ addGSLRealFunc<gsl_sf_bessel_y2>("y2");
+ addGSLIntRealFunc<gsl_sf_bessel_yl>("y","l");
+ addGSLRealFunc<gsl_sf_bessel_i0_scaled>("i0_scaled");
+ addGSLRealFunc<gsl_sf_bessel_i1_scaled>("i1_scaled");
+ addGSLRealFunc<gsl_sf_bessel_i2_scaled>("i2_scaled");
+ addGSLIntRealFunc<gsl_sf_bessel_il_scaled>("i_scaled","l");
+ addGSLRealFunc<gsl_sf_bessel_k0_scaled>("k0_scaled");
+ addGSLRealFunc<gsl_sf_bessel_k1_scaled>("k1_scaled");
+ addGSLRealFunc<gsl_sf_bessel_k2_scaled>("k2_scaled");
+ addGSLIntRealFunc<gsl_sf_bessel_kl_scaled>("k_scaled","l");
+ addGSLRealRealFunc<gsl_sf_bessel_Jnu>("J");
+ addGSLRealRealFunc<gsl_sf_bessel_Ynu>("Y");
+ addGSLRealRealFunc<gsl_sf_bessel_Inu>("I");
+ addGSLRealRealFunc<gsl_sf_bessel_Inu_scaled>("I_scaled");
+ addGSLRealRealFunc<gsl_sf_bessel_Knu>("K");
+ addGSLRealRealFunc<gsl_sf_bessel_lnKnu>("lnK");
+ addGSLRealRealFunc<gsl_sf_bessel_Knu_scaled>("K_scaled");
+ addGSLIntFunc<gsl_sf_bessel_zero_J0>("zero_J0");
+ addGSLIntFunc<gsl_sf_bessel_zero_J1>("zero_J1");
+ addGSLRealIntFunc<gsl_sf_bessel_zero_Jnu>("zero_J");
+
+ // Clausen functions
+ addGSLRealFunc<gsl_sf_clausen>("clausen");
+
+ // Coulomb functions
+ addGSLRealRealFunc<gsl_sf_hydrogenicR_1>("hydrogenicR_1","Z","r");
+ addGSLIntIntRealRealFunc<gsl_sf_hydrogenicR>("hydrogenicR","n","l","Z",
+ "r");
+ // Missing: F_L(eta,x), G_L(eta,x), C_L(eta)
+
+ // Coupling coefficients
+ addGSLIntIntIntIntIntIntFunc<gsl_sf_coupling_3j>("coupling_3j","two_ja",
+ "two_jb","two_jc","two_ma",
+ "two_mb","two_mc");
+ addGSLIntIntIntIntIntIntFunc<gsl_sf_coupling_6j>("coupling_6j","two_ja",
+ "two_jb","two_jc","two_jd",
+ "two_je","two_jf");
+ addGSLIntIntIntIntIntIntIntIntIntFunc<gsl_sf_coupling_9j>("coupling_9j",
+ "two_ja","two_jb",
+ "two_jc","two_jd",
+ "two_je","two_jf",
+ "two_jg","two_jh",
+ "two_ji");
+ // Dawson function
+ addGSLRealFunc<gsl_sf_dawson>("dawson");
+
+ // Debye functions
+ addGSLRealFunc<gsl_sf_debye_1>("debye_1");
+ addGSLRealFunc<gsl_sf_debye_2>("debye_2");
+ addGSLRealFunc<gsl_sf_debye_3>("debye_3");
+ addGSLRealFunc<gsl_sf_debye_4>("debye_4");
+ addGSLRealFunc<gsl_sf_debye_5>("debye_5");
+ addGSLRealFunc<gsl_sf_debye_6>("debye_6");
+
+ // Dilogarithm
+ addGSLRealFunc<gsl_sf_dilog>("dilog");
+ // Missing: complex dilogarithm
+
+ // Elementary operations
+ // we don't support errors at the moment
+
+ // Elliptic integrals
+ addGSLDOUBLEFunc<gsl_sf_ellint_Kcomp>("K","k");
+ addGSLDOUBLEFunc<gsl_sf_ellint_Ecomp>("E","k");
+ addGSLDOUBLE2Func<gsl_sf_ellint_Pcomp>("P","k","n");
+ addGSLDOUBLE2Func<gsl_sf_ellint_F>("F");
+ addGSLDOUBLE2Func<gsl_sf_ellint_E>("E");
+ addGSLDOUBLE3Func<gsl_sf_ellint_P>("P","phi","k","n");
+ addGSLDOUBLE3Func<gsl_sf_ellint_D>("D","phi","k","n");
+ addGSLDOUBLE2Func<gsl_sf_ellint_RC>("RC","x","y");
+ addGSLDOUBLE3Func<gsl_sf_ellint_RD>("RD","x","y","z");
+ addGSLDOUBLE3Func<gsl_sf_ellint_RF>("RF","x","y","z");
+ addGSLDOUBLE4Func<gsl_sf_ellint_RJ>("RJ","x","y","z","p");
+
+ // Elliptic functions (Jacobi)
+ // to be implemented
+
+ // Error functions
+ addGSLRealFunc<gsl_sf_erf>("erf");
+ addGSLRealFunc<gsl_sf_erfc>("erfc");
+ addGSLRealFunc<gsl_sf_log_erfc>("log_erfc");
+ addGSLRealFunc<gsl_sf_erf_Z>("erf_Z");
+ addGSLRealFunc<gsl_sf_erf_Q>("erf_Q");
+ addGSLRealFunc<gsl_sf_hazard>("hazard");
+
+ // Exponential functions
+ addGSLRealRealFunc<gsl_sf_exp_mult>("exp_mult","x","y");
+// addGSLRealFunc<gsl_sf_expm1>("expm1");
+ addGSLRealFunc<gsl_sf_exprel>("exprel");
+ addGSLRealFunc<gsl_sf_exprel_2>("exprel_2");
+ addGSLIntRealFunc<gsl_sf_exprel_n>("exprel","n","x");
+
+ // Exponential integrals
+ addGSLRealFunc<gsl_sf_expint_E1>("E1");
+ addGSLRealFunc<gsl_sf_expint_E2>("E2");
+// addGSLIntRealFunc<gsl_sf_expint_En>("En","n","x");
+ addGSLRealFunc<gsl_sf_expint_Ei>("Ei");
+ addGSLRealFunc<gsl_sf_Shi>("Shi");
+ addGSLRealFunc<gsl_sf_Chi>("Chi");
+ addGSLRealFunc<gsl_sf_expint_3>("Ei3");
+ addGSLRealFunc<gsl_sf_Si>("Si");
+ addGSLRealFunc<gsl_sf_Ci>("Ci");
+ addGSLRealFunc<gsl_sf_atanint>("atanint");
+
+ // Fermi--Dirac function
+ addGSLRealFunc<gsl_sf_fermi_dirac_m1>("FermiDiracM1");
+ addGSLRealFunc<gsl_sf_fermi_dirac_0>("FermiDirac0");
+ addGSLRealFunc<gsl_sf_fermi_dirac_1>("FermiDirac1");
+ addGSLRealFunc<gsl_sf_fermi_dirac_2>("FermiDirac2");
+ addGSLIntRealFunc<gsl_sf_fermi_dirac_int>("FermiDirac","j","x");
+ addGSLRealFunc<gsl_sf_fermi_dirac_mhalf>("FermiDiracMHalf");
+ addGSLRealFunc<gsl_sf_fermi_dirac_half>("FermiDiracHalf");
+ addGSLRealFunc<gsl_sf_fermi_dirac_3half>("FermiDirac3Half");
+ addGSLRealRealFunc<gsl_sf_fermi_dirac_inc_0>("FermiDiracInc0","x","b");
+
+ // Gamma and beta functions
+ addGSLRealFunc<gsl_sf_gamma>("gamma");
+ addGSLRealFunc<gsl_sf_lngamma>("lngamma");
+ addGSLRealFunc<gsl_sf_gammastar>("gammastar");
+ addGSLRealFunc<gsl_sf_gammainv>("gammainv");
+ addGSLIntFunc<gsl_sf_fact>("fact");
+ addGSLIntFunc<gsl_sf_doublefact>("doublefact");
+ addGSLIntFunc<gsl_sf_lnfact>("lnfact");
+ addGSLIntFunc<gsl_sf_lndoublefact>("lndoublefact");
+ addGSLUnsignedUnsignedFunc<gsl_sf_choose>("choose","n","m");
+ addGSLUnsignedUnsignedFunc<gsl_sf_lnchoose>("lnchoose","n","m");
+ addGSLIntRealFunc<gsl_sf_taylorcoeff>("taylorcoeff","n","x");
+ addGSLRealRealFunc<gsl_sf_poch>("poch","a","x");
+ addGSLRealRealFunc<gsl_sf_lnpoch>("lnpoch","a","x");
+ addGSLRealRealFunc<gsl_sf_pochrel>("pochrel","a","x");
+ addGSLRealRealFunc<gsl_sf_gamma_inc>("gamma","a","x");
+ addGSLRealRealFunc<gsl_sf_gamma_inc_Q>("gamma_Q","a","x");
+ addGSLRealRealFunc<gsl_sf_gamma_inc_P>("gamma_P","a","x");
+ addGSLRealRealFunc<gsl_sf_beta>("beta","a","b");
+ addGSLRealRealFunc<gsl_sf_lnbeta>("lnbeta","a","b");
+ addGSLRealRealRealFunc<gsl_sf_beta_inc>("beta","a","b","x");
+
+ // Gegenbauer functions
+ addGSLRealRealFunc<gsl_sf_gegenpoly_1>("gegenpoly_1","lambda","x");
+ addGSLRealRealFunc<gsl_sf_gegenpoly_2>("gegenpoly_2","lambda","x");
+ addGSLRealRealFunc<gsl_sf_gegenpoly_3>("gegenpoly_3","lambda","x");
+ addGSLIntRealRealFunc<gsl_sf_gegenpoly_n>("gegenpoly","n","lambda","x");
+
+ // Hypergeometric functions
+ addGSLRealRealFunc<gsl_sf_hyperg_0F1>("hy0F1","c","x");
+ addGSLIntIntRealFunc<gsl_sf_hyperg_1F1_int>("hy1F1","m","n","x");
+ addGSLRealRealRealFunc<gsl_sf_hyperg_1F1>("hy1F1","a","b","x");
+ addGSLIntIntRealFunc<gsl_sf_hyperg_U_int>("U","m","n","x");
+ addGSLRealRealRealFunc<gsl_sf_hyperg_U>("U","a","b","x");
+ addGSLRealRealRealRealFunc<gsl_sf_hyperg_2F1>("hy2F1","a","b","c","x");
+ addGSLRealRealRealRealFunc<gsl_sf_hyperg_2F1_conj>("hy2F1_conj","aR","aI","c",
+ "x");
+ addGSLRealRealRealRealFunc<gsl_sf_hyperg_2F1_renorm>("hy2F1_renorm","a","b",
+ "c","x");
+ addGSLRealRealRealRealFunc<gsl_sf_hyperg_2F1_conj_renorm>("hy2F1_conj_renorm",
+ "aR","aI","c","x");
+ addGSLRealRealRealFunc<gsl_sf_hyperg_2F0>("hy2F0","a","b","x");
+
+ // Laguerre functions
+ addGSLRealRealFunc<gsl_sf_laguerre_1>("L1","a","x");
+ addGSLRealRealFunc<gsl_sf_laguerre_2>("L2","a","x");
+ addGSLRealRealFunc<gsl_sf_laguerre_3>("L3","a","x");
+ addGSLIntRealRealFunc<gsl_sf_laguerre_n>("L","n","a","x");
+
+ // Lambert W functions
+ addGSLRealFunc<gsl_sf_lambert_W0>("W0");
+ addGSLRealFunc<gsl_sf_lambert_Wm1>("Wm1");
+
+ // Legendre functions and spherical harmonics
+ addGSLRealFunc<gsl_sf_legendre_P1>("P1");
+ addGSLRealFunc<gsl_sf_legendre_P2>("P2");
+ addGSLRealFunc<gsl_sf_legendre_P3>("P3");
+ addGSLIntRealFunc<gsl_sf_legendre_Pl>("Pl","l");
+ addGSLRealFunc<gsl_sf_legendre_Q0>("Q0");
+ addGSLRealFunc<gsl_sf_legendre_Q1>("Q1");
+ addGSLIntRealFunc<gsl_sf_legendre_Ql>("Ql","l");
+ addGSLIntIntRealFunc<gsl_sf_legendre_Plm>("Plm","l","m","x");
+ addGSLIntIntRealFunc<gsl_sf_legendre_sphPlm>("sphPlm","l","m","x");
+ addGSLRealRealFunc<gsl_sf_conicalP_half>("conicalP_half","lambda","x");
+ addGSLRealRealFunc<gsl_sf_conicalP_mhalf>("conicalP_mhalf","lambda","x");
+ addGSLRealRealFunc<gsl_sf_conicalP_0>("conicalP_0","lambda","x");
+ addGSLRealRealFunc<gsl_sf_conicalP_1>("conicalP_1","lambda","x");
+ addGSLIntRealRealFunc<gsl_sf_conicalP_sph_reg>("conicalP_sph_reg","l",
+ "lambda","x");
+ addGSLIntRealRealFunc<gsl_sf_conicalP_cyl_reg>("conicalP_cyl_reg","m",
+ "lambda","x");
+ addGSLRealRealFunc<gsl_sf_legendre_H3d_0>("H3d0","lambda","eta");
+ addGSLRealRealFunc<gsl_sf_legendre_H3d_1>("H3d1","lambda","eta");
+ addGSLIntRealRealFunc<gsl_sf_legendre_H3d>("H3d","l","lambda","eta");
+
+ // Logarithm and related functions
+ addGSLRealFunc<gsl_sf_log_abs>("logabs");
+// addGSLRealFunc<gsl_sf_log_1plusx>("log1p");
+ addGSLRealFunc<gsl_sf_log_1plusx_mx>("log1pm");
+
+ // Matthieu functions
+ // to be implemented
+
+ // Power function
+ addGSLRealSignedFunc<gsl_sf_pow_int>("pow","x","n");
+
+ // Psi (digamma) function
+ addGSLSignedFunc<gsl_sf_psi_int>("psi","n");
+ addGSLRealFunc<gsl_sf_psi>("psi");
+ addGSLRealFunc<gsl_sf_psi_1piy>("psi_1piy","y");
+ addGSLSignedFunc<gsl_sf_psi_1_int>("psi1","n");
+ addGSLRealFunc<gsl_sf_psi_1>("psi1","x");
+ addGSLIntRealFunc<gsl_sf_psi_n>("psi","n","x");
+
+ // Synchrotron functions
+ addGSLRealFunc<gsl_sf_synchrotron_1>("synchrotron_1");
+ addGSLRealFunc<gsl_sf_synchrotron_2>("synchrotron_2");
+
+ // Transport functions
+ addGSLRealFunc<gsl_sf_transport_2>("transport_2");
+ addGSLRealFunc<gsl_sf_transport_3>("transport_3");
+ addGSLRealFunc<gsl_sf_transport_4>("transport_4");
+ addGSLRealFunc<gsl_sf_transport_5>("transport_5");
+
+ // Trigonometric functions
+ addGSLRealFunc<gsl_sf_sinc>("sinc");
+ addGSLRealFunc<gsl_sf_lnsinh>("lnsinh");
+ addGSLRealFunc<gsl_sf_lncosh>("lncosh");
+
+ // Zeta functions
+ addGSLSignedFunc<gsl_sf_zeta_int>("zeta","n");
+ addGSLRealFunc<gsl_sf_zeta>("zeta","s");
+ addGSLSignedFunc<gsl_sf_zetam1_int>("zetam1","n");
+ addGSLRealFunc<gsl_sf_zetam1>("zetam1","s");
+ addGSLRealRealFunc<gsl_sf_hzeta>("hzeta","s","q");
+ addGSLSignedFunc<gsl_sf_eta_int>("eta","n");
+ addGSLRealFunc<gsl_sf_eta>("eta","s");
+#endif
+
+#ifdef STRUCTEXAMPLE
+ dummyRecord *fun=createDummyRecord(ve, "test");
+ addFunc(fun->e.ve,realReal<sin>,primReal(),"f",formal(primReal(),"x"));
+ addVariable<Int>(fun->e.ve,1,primInt(),"x");
+#endif
+
+ addFunc(ve,writestring,primVoid(),"write",
+ formal(primFile(),"file",true),
+ formal(primString(),"s"),
+ formal(voidFileFunction(),"suffix",true));
+
+ addWrite(ve,write<transform>,primTransform(),transformArray());
+ addWrite(ve,write<guide *>,primGuide(),guideArray());
+ addWrite(ve,write<pen>,primPen(),penArray());
+ addFunc(ve,arrayArrayOp<pen,equals>,boolArray(),"==",
+ formal(penArray(),"a"),formal(penArray(),"b"));
+ addFunc(ve,arrayArrayOp<pen,notequals>,boolArray(),"!=",
+ formal(penArray(),"a"),formal(penArray(),"b"));
+
+ addFunc(ve,arrayFunction,realArray(),"map",
+ formal(realPairFunction(),"f"),
+ formal(pairArray(),"a"));
+ addFunc(ve,arrayFunction,IntArray(),"map",
+ formal(IntRealFunction(),"f"),
+ formal(realArray(),"a"));
+
+#ifdef HAVE_LIBFFTW3
+ addFunc(ve,pairArrayFFT,pairArray(),"fft",formal(pairArray(),"a"),
+ formal(primInt(),"sign",true));
+#endif
+
+ addConstant<Int>(ve, Int_MAX, primInt(), "intMax");
+ addConstant<Int>(ve, Int_MIN, primInt(), "intMin");
+ addConstant<double>(ve, HUGE_VAL, primReal(), "inf");
+ addConstant<double>(ve, run::infinity, primReal(), "infinity");
+ addConstant<double>(ve, DBL_MAX, primReal(), "realMax");
+ addConstant<double>(ve, DBL_MIN, primReal(), "realMin");
+ addConstant<double>(ve, DBL_EPSILON, primReal(), "realEpsilon");
+ addConstant<Int>(ve, DBL_DIG, primInt(), "realDigits");
+ addConstant<Int>(ve, RAND_MAX, primInt(), "randMax");
+ addConstant<double>(ve, PI, primReal(), "pi");
+ addConstant<string>(ve, string(settings::VERSION)+string(SVN_REVISION),
+ primString(),"VERSION");
+
+ addVariable<pen>(ve, &processData().currentpen, primPen(), "currentpen");
+
+#ifdef OPENFUNCEXAMPLE
+ addOpenFunc(ve, openFunc, primInt(), "openFunc");
+#endif
+
+ gen_base_venv(ve);
+}
+
+void base_menv(menv&)
+{
+}
+
+} //namespace trans
+
+namespace run {
+
+double infinity=cbrt(DBL_MAX); // Reduced for tension atleast infinity
+
+void arrayDeleteHelper(vm::stack *Stack)
+{
+ array *a=pop<array *>(Stack);
+ item itj=pop(Stack);
+ item iti=pop(Stack);
+ if(isdefault(iti)) {
+ (*a).clear();
+ return;
+ }
+ Int i=get<Int>(iti);
+ Int j=isdefault(itj) ? i : get<Int>(itj);
+
+ size_t asize=checkArray(a);
+ if(a->cyclic() && asize > 0) {
+ if(j-i+1 >= (Int) asize) {
+ (*a).clear();
+ return;
+ }
+ i=imod(i,asize);
+ j=imod(j,asize);
+ if(j >= i)
+ (*a).erase((*a).begin()+i,(*a).begin()+j+1);
+ else {
+ (*a).erase((*a).begin()+i,(*a).end());
+ (*a).erase((*a).begin(),(*a).begin()+j+1);
+ }
+ return;
+ }
+
+ if(i < 0 || i >= (Int) asize || i > j || j >= (Int) asize) {
+ ostringstream buf;
+ buf << "delete called on array of length " << (Int) asize
+ << " with out-of-bounds index range [" << i << "," << j << "]";
+ error(buf);
+ }
+
+ (*a).erase((*a).begin()+i,(*a).begin()+j+1);
+}
+
+}
diff --git a/Build/source/utils/asymptote/builtin.h b/Build/source/utils/asymptote/builtin.h
new file mode 100644
index 00000000000..0e54a5fb473
--- /dev/null
+++ b/Build/source/utils/asymptote/builtin.h
@@ -0,0 +1,52 @@
+/*****
+ * builtin.h
+ * Tom Prince 2004/08/25
+ *
+ * Initialize builtins.
+ *****/
+#ifndef BUILTIN_H
+#define BUILTIN_H
+
+#include "vm.h"
+#include "types.h"
+
+namespace trans {
+
+class tenv;
+class venv;
+class menv;
+
+// The base environments for built-in types and functions
+void base_tenv(tenv &);
+void base_venv(venv &);
+void base_menv(menv &);
+
+extern const types::formal noformal;
+
+// Add a function with one or more default arguments.
+void addFunc(venv &ve, vm::bltin f, types::ty *result, const char *name,
+ types::formal f1=noformal, types::formal f2=noformal,
+ types::formal f3=noformal, types::formal f4=noformal,
+ types::formal f5=noformal, types::formal f6=noformal,
+ types::formal f7=noformal, types::formal f8=noformal,
+ types::formal f9=noformal, types::formal fA=noformal,
+ types::formal fB=noformal, types::formal fC=noformal,
+ types::formal fD=noformal, types::formal fE=noformal,
+ types::formal fF=noformal);
+
+// Adds standard functions for a newly added types.
+void addArrayOps(venv &ve, types::array *t);
+void addRecordOps(venv &ve, types::record *r);
+void addFunctionOps(venv &ve, types::function *f);
+
+types::record *getGSLModule();
+
+} //namespace trans
+
+namespace run {
+extern double infinity;
+
+void arrayDeleteHelper(vm::stack *Stack);
+}
+
+#endif //BUILTIN_H
diff --git a/Build/source/utils/asymptote/callable.cc b/Build/source/utils/asymptote/callable.cc
new file mode 100644
index 00000000000..ba3fe33152c
--- /dev/null
+++ b/Build/source/utils/asymptote/callable.cc
@@ -0,0 +1,52 @@
+/*****
+ * callable.cc
+ * Tom Prince 2005/06/19
+ *
+ * Runtime representation of functions.
+ *****/
+
+#include "stack.h"
+#include "callable.h"
+
+namespace vm {
+
+callable::~callable()
+{}
+
+void func::call(stack *s)
+{
+ s->run(this);
+}
+
+bool func::compare(callable* F)
+{
+ if (func* f=dynamic_cast<func*>(F))
+ return (body == f->body) && (closure == f->closure);
+ else return false;
+}
+
+bool bfunc::compare(callable* F)
+{
+ if (bfunc* f=dynamic_cast<bfunc*>(F))
+ return (func == f->func);
+ else return false;
+}
+
+void thunk::call(stack *s)
+{
+ s->push(arg);
+ func->call(s);
+}
+
+nullfunc nullfunc::func;
+void nullfunc::call(stack *)
+{
+ error("dereference of null function");
+}
+
+bool nullfunc::compare(callable* f)
+{
+ return f == &func;
+}
+
+} // namespace vm
diff --git a/Build/source/utils/asymptote/callable.h b/Build/source/utils/asymptote/callable.h
new file mode 100644
index 00000000000..4274218f8fd
--- /dev/null
+++ b/Build/source/utils/asymptote/callable.h
@@ -0,0 +1,74 @@
+/*****
+ * callable.h
+ * Tom Prince 2005/06/19
+ *
+ * Runtime representation of functions.
+ *****/
+
+#ifndef CALLABLE_H
+#define CALLABLE_H
+
+#include "common.h"
+#include "item.h"
+
+namespace vm {
+
+class stack;
+typedef void (*bltin)(stack *s);
+
+struct callable : public gc
+{
+ virtual void call(stack *) = 0;
+ virtual ~callable();
+ virtual bool compare(callable*) { return false; }
+};
+
+class nullfunc : public callable
+{
+private:
+ nullfunc() {}
+ static nullfunc func;
+public:
+ virtual void call (stack*);
+ virtual bool compare(callable*);
+ static callable* instance() { return &func; }
+};
+
+// How a function reference to a non-builtin function is stored.
+struct func : public callable {
+ lambda *body;
+ frame *closure;
+ func () : body(), closure() {}
+ virtual void call (stack*);
+ virtual bool compare(callable*);
+};
+
+class bfunc : public callable
+{
+public:
+ bfunc(bltin b) : func(b) {}
+ virtual void call (stack *s) { func(s); }
+ virtual bool compare(callable*);
+private:
+ bltin func;
+};
+
+class thunk : public callable
+{
+public:
+ thunk(callable *f, item i) : func(f), arg(i) {}
+ virtual void call (stack*);
+private:
+ callable *func;
+ item arg;
+};
+
+} // namespace vm
+
+GC_DECLARE_PTRFREE(vm::nullfunc);
+
+// I believe this is safe, as pointers to C++ functions do not point to
+// the heap.
+GC_DECLARE_PTRFREE(vm::bfunc);
+
+#endif // CALLABLE_H
diff --git a/Build/source/utils/asymptote/camp.l b/Build/source/utils/asymptote/camp.l
new file mode 100644
index 00000000000..f6b53c40f85
--- /dev/null
+++ b/Build/source/utils/asymptote/camp.l
@@ -0,0 +1,406 @@
+%{
+/*****
+ * camp.l
+ * Andy Hammerlindl 2002/06/14
+ *
+ * The lexical analyzer of the Asymptote language.
+ *****/
+
+#include <iostream>
+#include <fstream>
+#include <sstream>
+
+#include "util.h"
+#include "modifier.h"
+#include "exp.h"
+#include "stm.h"
+#include "fundec.h"
+#include "errormsg.h"
+#include "interact.h"
+#include "lexical.h"
+
+using namespace absyntax;
+using mem::string;
+
+#include "camp.tab.h"
+
+#define YY_NO_UNPUT
+
+fileinfo* fi;
+Int tokPos;
+Int charPos;
+//int commentDepth = 0;
+
+bool eof;
+string eofMessage;
+
+extern errorstream em;
+
+extern "C" int yywrap(void)
+{
+ charPos=1;
+ return 1;
+}
+
+typedef size_t (*input_f) (char* bif, size_t max_size);
+
+input_f yy_input = NULL;
+
+void setlexer(input_f input, string filename)
+{
+ YY_FLUSH_BUFFER;
+ yywrap();
+ fi = new fileinfo(filename);
+ yy_input = input;
+ tokPos = charPos = 1;
+
+ eof=false;
+ eofMessage="<no eof>";
+}
+
+#define YY_INPUT(buf,result,max_size) {result=yy_input(buf,max_size);}
+
+position lexerPos()
+{
+ position p;
+ p.init(fi, tokPos);
+ return p;
+}
+
+namespace {
+position here()
+
+{
+ return lexerPos();
+}
+
+void adjust()
+{
+ tokPos = charPos;
+ charPos += yyleng;
+ yylval.pos = here();
+}
+
+void makesymbol(bool op=true, string text = yytext)
+{
+ adjust();
+ yylval.ps.pos=here();
+ yylval.ps.sym=op ? symbol::opTrans(text) : symbol::literalTrans(text);
+}
+
+void makeselfsymbol(bool op=true, string text = yytext)
+{
+ /* Copy all but the last digit, which should be an =. */
+ assert(text[text.length()-1] == '=');
+ text.erase(text.length()-1);
+ makesymbol(op,text);
+}
+
+void makemod(trans::modifier mod) {
+ yylval.mod.pos=here();
+ yylval.mod.val=mod;
+}
+
+void makeperm(trans::permission perm) {
+ yylval.perm.pos=here();
+ yylval.perm.val=perm;
+}
+
+void newline()
+{
+ fi->newline();
+ charPos = tokPos = 1;
+}
+
+void error(void)
+{
+ em.error(here());
+}
+
+}
+
+
+// Used by the lexer rules to flag an unexpected end of input. The message is
+// the error message that should be reported, and may differ if, say the input
+// ends in the middle of a string or comment.
+void setEOF(string message) {
+ eof=true;
+ eofMessage=message;
+}
+
+// Called by code outside of the lexer to see if a parse error was caused by
+// running out of input.
+bool lexerEOF()
+{
+ return eof;
+}
+
+// Called by code outside of the lexer when it wants to report the unexpected
+// eof as an error (instead of looking for more input).
+void reportEOF() {
+ assert(eof);
+ error();
+ em << eofMessage;
+ em.sync();
+}
+
+string stringbuild;
+
+namespace {
+void append(char c)
+{
+ stringbuild.push_back(c);
+ yylval.pos = here();
+}
+
+void getstring(void)
+{
+ // NOTE: Replace here() with a position at the start of the string.
+ makesymbol(false,stringbuild);
+ string().swap(stringbuild);
+}
+}
+
+%}
+
+%x lexcomment
+%x texstring
+%x cstring
+%x lexformat
+%x opname
+
+LETTER [_A-Za-z]
+ESC \\
+ENDL \\?(\r\n|\n|\r)
+EXTRAOPS <<|>>|$|$$|@|@@|~
+
+%%
+
+<lexcomment>{
+\/\* {adjust(); /*commentDepth++;*/}
+\*\/ {adjust(); /*commentDepth--;*/
+ /*if (commentDepth == 0)*/ BEGIN INITIAL; }
+\r\n|\n|\r {adjust(); newline(); continue; }
+<<EOF>> {adjust();
+ setEOF("comment not terminated");
+ BEGIN INITIAL;
+ return GARBAGE;
+ }
+. {adjust(); continue; }
+}
+
+<texstring>{
+\"/([ \t]|{ENDL})*[\"\'] {adjust(); BEGIN INITIAL;}
+\" {adjust();
+ BEGIN INITIAL;
+ getstring();
+ return STRING; }
+<<EOF>> {adjust();
+ setEOF("string not terminated");
+ BEGIN INITIAL;
+ getstring();
+ return GARBAGE;
+ }
+{ENDL} {adjust(); newline(); append('\n'); continue; }
+{ESC}{ESC} {adjust(); append('\\'); append('\\'); continue; }
+{ESC}\" {adjust(); append('\"'); continue; }
+. {adjust(); append(*yytext); }
+}
+
+<cstring>{
+\'/([ \t]|{ENDL})*[\"\'] {adjust(); BEGIN INITIAL;}
+\' {adjust();
+ BEGIN INITIAL;
+ getstring();
+ return STRING; }
+<<EOF>> {adjust();
+ setEOF("string not terminated");
+ BEGIN INITIAL;
+ getstring();
+ return GARBAGE;
+ }
+{ENDL} {adjust(); newline(); append('\n'); continue; }
+{ESC}(\'|\"|\?|\\) {adjust(); append(yytext[1]); continue; }
+{ESC}a {adjust(); append('\a'); continue; }
+{ESC}b {adjust(); append('\b'); continue; }
+{ESC}f {adjust(); append('\f'); continue; }
+{ESC}n {adjust(); append('\n'); continue; }
+{ESC}r {adjust(); append('\r'); continue; }
+{ESC}t {adjust(); append('\t'); continue; }
+{ESC}v {adjust(); append('\v'); continue; }
+{ESC}[0-7] {adjust();
+ char x=(char)(yytext[1]-'0');
+ append(x);
+ continue;
+ }
+{ESC}[0-7][0-7] {adjust();
+ char x=(char)((yytext[1]-'0')*8+yytext[2]-'0');
+ append(x);
+ continue;
+ }
+{ESC}[0-3][0-7][0-7] {adjust();
+ char x=(char)((yytext[1]-'0')*64+(yytext[2]-'0')*8
+ +yytext[3]-'0');
+ append(x);
+ continue;
+ }
+{ESC}x[0-9,A-F] {adjust();
+ char x=(char) (yytext[2] <= '9' ? yytext[2]-'0' :
+ 10+yytext[2]-'A');
+ append(x);
+ continue;
+ }
+{ESC}x[0-9,A-F][0-9,A-F] {adjust();
+ char x=(char) ((yytext[2] <= '9' ? yytext[2]-'0' :
+ 10+yytext[2]-'A')*16
+ +(yytext[3] <= '9' ? yytext[3]-'0' :
+ 10+yytext[3]-'A'));
+ append(x);
+ continue;
+ }
+. {adjust(); append(*yytext); }
+}
+
+[ \t] {adjust(); continue;}
+{ENDL} {adjust(); newline(); continue;}
+\/\/[^\n]* {adjust(); continue;}
+"," {adjust(); return ','; }
+":" {adjust(); return ':'; }
+";" {adjust(); return ';'; }
+"(" {adjust(); return '('; }
+")" {adjust(); return ')'; }
+"[" {adjust(); return '['; }
+"]" {adjust(); return ']'; }
+"{" {adjust(); return '{'; }
+"}" {adjust(); return '}'; }
+"." {adjust(); return '.'; }
+"..." {adjust(); return ELLIPSIS; }
+"+" {makesymbol(); return '+'; }
+"-" {makesymbol(); return '-'; }
+"*" {makesymbol(); return '*'; }
+"/" {makesymbol(); return '/'; }
+"%" {makesymbol(); return '%'; }
+"^" {makesymbol(); return '^'; }
+"**" {makesymbol(true,"^"); return '^'; }
+"?" {adjust(); return '?'; }
+"=" {adjust(); return ASSIGN; }
+"==" {makesymbol(); return EQ; }
+"!=" {makesymbol(); return NEQ; }
+"<" {makesymbol(); return LT; }
+"<=" {makesymbol(); return LE; }
+">" {makesymbol(); return GT; }
+">=" {makesymbol(); return GE; }
+"&&" {makesymbol(); return CAND; }
+"||" {makesymbol(); return COR; }
+"!" {makesymbol(); return LOGNOT; }
+"^^" {makesymbol(); return CARETS; }
+"::" {makesymbol(); return COLONS; }
+"++" {makesymbol(); return INCR; }
+".." {makesymbol(); return DOTS; }
+"--" {makesymbol(); return DASHES; }
+"---" {makesymbol(); return LONGDASH; }
+"&" {makesymbol(); return AMPERSAND; }
+"|" {makesymbol(); return BAR; }
+{EXTRAOPS} {makesymbol(); return OPERATOR; }
+
+"+=" {makeselfsymbol(); return ADD; }
+"-=" {makeselfsymbol(); return SUBTRACT; }
+"*=" {makeselfsymbol(); return TIMES; }
+"/=" {makeselfsymbol(); return DIVIDE; }
+"%=" {makeselfsymbol(); return MOD; }
+"^=" {makeselfsymbol(); return EXPONENT; }
+
+and {adjust(); return AND; }
+controls {makesymbol(); return CONTROLS; }
+tension {makesymbol(); return TENSION; }
+atleast {makesymbol(); return ATLEAST; }
+curl {makesymbol(); return CURL; }
+
+if {adjust(); return IF; }
+else {adjust(); return ELSE; }
+while {adjust(); return WHILE; }
+for {adjust(); return FOR; }
+do {adjust(); return DO; }
+return {adjust(); return RETURN_; }
+break {adjust(); return BREAK; }
+continue {adjust(); return CONTINUE; }
+struct {adjust(); return STRUCT; }
+typedef {adjust(); return TYPEDEF; }
+new {adjust(); return NEW; }
+access {adjust(); return ACCESS; }
+import {adjust(); return IMPORT; }
+unravel {adjust(); return UNRAVEL; }
+from {adjust(); return FROM; }
+include {adjust(); return INCLUDE; }
+quote {adjust(); return QUOTE; }
+static {adjust(); makemod(trans::EXPLICIT_STATIC);
+ return MODIFIER; }
+public {adjust(); makeperm(trans::PUBLIC); return PERM; }
+private {adjust(); makeperm(trans::PRIVATE); return PERM; }
+restricted {adjust(); makeperm(trans::RESTRICTED); return PERM; }
+this {adjust(); return THIS; }
+explicit {adjust(); return EXPLICIT; }
+
+
+[0-9]+ try {
+ adjust(); yylval.e= new intExp(here(), lexical::cast<Int>(yytext));
+ } catch (lexical::bad_cast&) {
+ error();
+ em << "invalid integer";
+ yylval.e= new intExp(here(), 0);
+ } return LIT;
+([0-9]*\.[0-9]+)|([0-9]+\.[0-9]*)|([0-9]*\.*[0-9]+e[-+]*[0-9]+)|([0-9]+\.[0-9]*e[-+]*[0-9]+) try {
+ adjust(); yylval.e= new realExp(here(), lexical::cast<double>(yytext));
+ } catch (lexical::bad_cast&) {
+ error();
+ em << "invalid real";
+ yylval.e= new realExp(here(), 0);
+ } return LIT;
+true {
+ adjust(); yylval.e= new booleanExp(here(), true); return LIT; }
+false {
+ adjust(); yylval.e= new booleanExp(here(), false); return LIT; }
+null {
+ adjust(); yylval.e= new nullExp(here()); return LIT; }
+cycle {
+ adjust(); yylval.e= new cycleExp(here()); return LIT; }
+newframe {
+ adjust(); yylval.e= new newPictureExp(here()); return LIT; }
+
+operator {adjust(); BEGIN opname; }
+<opname>{
+[ \t\r] {adjust(); continue;}
+{ENDL} {adjust(); newline(); continue;}
+<<EOF>> {adjust();
+ setEOF("missing operator name");
+ BEGIN INITIAL;
+ return GARBAGE;
+ }
+"**" { makesymbol(true, "^");
+ BEGIN INITIAL;
+ return ID;
+ }
+[-+*/%^!<>]|==|!=|<=|>=|&|\||\^\^|\.\.|::|--|---|\+\+|{EXTRAOPS} {
+ makesymbol();
+ BEGIN INITIAL;
+ return ID;}
+{LETTER}({LETTER}|[0-9])* {
+ makesymbol(true);
+ BEGIN INITIAL;
+ return ID; }
+. {}
+}
+
+{LETTER}({LETTER}|[0-9])* {
+ makesymbol(false);
+ return ID; }
+
+\/\* {adjust(); /*commentDepth = 1;*/ BEGIN lexcomment; }
+\" {adjust(); BEGIN texstring; }
+\' {adjust(); BEGIN cstring; }
+
+<<EOF>> { setEOF("unexpected end of input"); yyterminate(); }
+
+. {
+ adjust(); error(); em <<"invalid token '" << yytext << "'"; }
+
diff --git a/Build/source/utils/asymptote/camp.tab.cc b/Build/source/utils/asymptote/camp.tab.cc
new file mode 100644
index 00000000000..52b5558ce1e
--- /dev/null
+++ b/Build/source/utils/asymptote/camp.tab.cc
@@ -0,0 +1,3516 @@
+/* A Bison parser, made by GNU Bison 2.3. */
+
+/* Skeleton implementation for Bison's Yacc-like parsers in C
+
+ Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006
+ Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ This program 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 General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA. */
+
+/* As a special exception, you may create a larger work that contains
+ part or all of the Bison parser skeleton and distribute that work
+ under terms of your choice, so long as that work isn't itself a
+ parser generator using the skeleton or a modified version thereof
+ as a parser skeleton. Alternatively, if you modify or redistribute
+ the parser skeleton itself, you may (at your option) remove this
+ special exception, which will cause the skeleton and the resulting
+ Bison output files to be licensed under the GNU General Public
+ License without this special exception.
+
+ This special exception was added by the Free Software Foundation in
+ version 2.2 of Bison. */
+
+/* C LALR(1) parser skeleton written by Richard Stallman, by
+ simplifying the original so-called "semantic" parser. */
+
+/* All symbols defined below should begin with yy or YY, to avoid
+ infringing on user name space. This should be done even for local
+ variables, as they might otherwise be expanded by user macros.
+ There are some unavoidable exceptions within include files to
+ define necessary library symbols; they are noted "INFRINGES ON
+ USER NAME SPACE" below. */
+
+/* Identify Bison output. */
+#define YYBISON 1
+
+/* Bison version. */
+#define YYBISON_VERSION "2.3"
+
+/* Skeleton name. */
+#define YYSKELETON_NAME "yacc.c"
+
+/* Pure parsers. */
+#define YYPURE 0
+
+/* Using locations. */
+#define YYLSP_NEEDED 0
+
+
+
+/* Tokens. */
+#ifndef YYTOKENTYPE
+# define YYTOKENTYPE
+ /* Put the tokens into the symbol table, so that GDB and other debuggers
+ know about them. */
+ enum yytokentype {
+ ID = 258,
+ ADD = 259,
+ SUBTRACT = 260,
+ TIMES = 261,
+ DIVIDE = 262,
+ MOD = 263,
+ EXPONENT = 264,
+ DOTS = 265,
+ COLONS = 266,
+ DASHES = 267,
+ INCR = 268,
+ LONGDASH = 269,
+ CONTROLS = 270,
+ TENSION = 271,
+ ATLEAST = 272,
+ CURL = 273,
+ COR = 274,
+ CAND = 275,
+ BAR = 276,
+ AMPERSAND = 277,
+ EQ = 278,
+ NEQ = 279,
+ LT = 280,
+ LE = 281,
+ GT = 282,
+ GE = 283,
+ CARETS = 284,
+ LOGNOT = 285,
+ OPERATOR = 286,
+ STRING = 287,
+ LOOSE = 288,
+ ASSIGN = 289,
+ DIRTAG = 290,
+ JOIN_PREC = 291,
+ AND = 292,
+ ELLIPSIS = 293,
+ ACCESS = 294,
+ UNRAVEL = 295,
+ IMPORT = 296,
+ INCLUDE = 297,
+ FROM = 298,
+ QUOTE = 299,
+ STRUCT = 300,
+ TYPEDEF = 301,
+ NEW = 302,
+ IF = 303,
+ ELSE = 304,
+ WHILE = 305,
+ DO = 306,
+ FOR = 307,
+ BREAK = 308,
+ CONTINUE = 309,
+ RETURN_ = 310,
+ THIS = 311,
+ EXPLICIT = 312,
+ GARBAGE = 313,
+ LIT = 314,
+ PERM = 315,
+ MODIFIER = 316,
+ UNARY = 317,
+ EXP_IN_PARENS_RULE = 318
+ };
+#endif
+/* Tokens. */
+#define ID 258
+#define ADD 259
+#define SUBTRACT 260
+#define TIMES 261
+#define DIVIDE 262
+#define MOD 263
+#define EXPONENT 264
+#define DOTS 265
+#define COLONS 266
+#define DASHES 267
+#define INCR 268
+#define LONGDASH 269
+#define CONTROLS 270
+#define TENSION 271
+#define ATLEAST 272
+#define CURL 273
+#define COR 274
+#define CAND 275
+#define BAR 276
+#define AMPERSAND 277
+#define EQ 278
+#define NEQ 279
+#define LT 280
+#define LE 281
+#define GT 282
+#define GE 283
+#define CARETS 284
+#define LOGNOT 285
+#define OPERATOR 286
+#define STRING 287
+#define LOOSE 288
+#define ASSIGN 289
+#define DIRTAG 290
+#define JOIN_PREC 291
+#define AND 292
+#define ELLIPSIS 293
+#define ACCESS 294
+#define UNRAVEL 295
+#define IMPORT 296
+#define INCLUDE 297
+#define FROM 298
+#define QUOTE 299
+#define STRUCT 300
+#define TYPEDEF 301
+#define NEW 302
+#define IF 303
+#define ELSE 304
+#define WHILE 305
+#define DO 306
+#define FOR 307
+#define BREAK 308
+#define CONTINUE 309
+#define RETURN_ 310
+#define THIS 311
+#define EXPLICIT 312
+#define GARBAGE 313
+#define LIT 314
+#define PERM 315
+#define MODIFIER 316
+#define UNARY 317
+#define EXP_IN_PARENS_RULE 318
+
+
+
+
+/* Copy the first part of user declarations. */
+#line 1 "camp.y"
+
+/*****
+ * camp.y
+ * Andy Hammerlindl 08/12/2002
+ *
+ * The grammar of the camp language.
+ *****/
+
+#include "errormsg.h"
+#include "exp.h"
+#include "newexp.h"
+#include "dec.h"
+#include "fundec.h"
+#include "stm.h"
+#include "modifier.h"
+
+// Avoid error messages with unpatched bison-1.875:
+#ifndef __attribute__
+#define __attribute__(x)
+#endif
+
+// Used when a position needs to be determined and no token is
+// available. Defined in camp.l.
+position lexerPos();
+
+bool lexerEOF();
+
+int yylex(void); /* function prototype */
+
+void yyerror(const char *s)
+{
+ if (!lexerEOF()) {
+ em.error(lexerPos());
+ em << s;
+ em.cont();
+ }
+}
+
+namespace absyntax { file *root; }
+
+using namespace absyntax;
+using sym::symbol;
+using mem::string;
+
+
+/* Enabling traces. */
+#ifndef YYDEBUG
+# define YYDEBUG 1
+#endif
+
+/* Enabling verbose error messages. */
+#ifdef YYERROR_VERBOSE
+# undef YYERROR_VERBOSE
+# define YYERROR_VERBOSE 1
+#else
+# define YYERROR_VERBOSE 0
+#endif
+
+/* Enabling the token table. */
+#ifndef YYTOKEN_TABLE
+# define YYTOKEN_TABLE 0
+#endif
+
+#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
+typedef union YYSTYPE
+#line 46 "camp.y"
+{
+ position pos;
+ bool boo;
+ struct {
+ position pos;
+ sym::symbol *sym;
+ } ps;
+ absyntax::name *n;
+ absyntax::varinit *vi;
+ absyntax::arrayinit *ai;
+ absyntax::exp *e;
+ absyntax::specExp *se;
+ absyntax::joinExp *j;
+ absyntax::explist *elist;
+ absyntax::argument arg;
+ absyntax::arglist *alist;
+ absyntax::slice *slice;
+ absyntax::dimensions *dim;
+ absyntax::ty *t;
+ absyntax::decid *di;
+ absyntax::decidlist *dil;
+ absyntax::decidstart *dis;
+ absyntax::runnable *run;
+ struct {
+ position pos;
+ trans::permission val;
+ } perm;
+ struct {
+ position pos;
+ trans::modifier val;
+ } mod;
+ absyntax::modifierList *ml;
+ //absyntax::program *prog;
+ absyntax::vardec *vd;
+ //absyntax::vardecs *vds;
+ absyntax::dec *d;
+ absyntax::idpair *ip;
+ absyntax::idpairlist *ipl;
+ absyntax::stm *s;
+ absyntax::block *b;
+ absyntax::stmExpList *sel;
+ //absyntax::funheader *fh;
+ absyntax::formal *fl;
+ absyntax::formals *fls;
+}
+/* Line 187 of yacc.c. */
+#line 313 "camp.tab.c"
+ YYSTYPE;
+# define yystype YYSTYPE /* obsolescent; will be withdrawn */
+# define YYSTYPE_IS_DECLARED 1
+# define YYSTYPE_IS_TRIVIAL 1
+#endif
+
+
+
+/* Copy the second part of user declarations. */
+
+
+/* Line 216 of yacc.c. */
+#line 326 "camp.tab.c"
+
+#ifdef short
+# undef short
+#endif
+
+#ifdef YYTYPE_UINT8
+typedef YYTYPE_UINT8 yytype_uint8;
+#else
+typedef unsigned char yytype_uint8;
+#endif
+
+#ifdef YYTYPE_INT8
+typedef YYTYPE_INT8 yytype_int8;
+#elif (defined __STDC__ || defined __C99__FUNC__ \
+ || defined __cplusplus || defined _MSC_VER)
+typedef signed char yytype_int8;
+#else
+typedef short int yytype_int8;
+#endif
+
+#ifdef YYTYPE_UINT16
+typedef YYTYPE_UINT16 yytype_uint16;
+#else
+typedef unsigned short int yytype_uint16;
+#endif
+
+#ifdef YYTYPE_INT16
+typedef YYTYPE_INT16 yytype_int16;
+#else
+typedef short int yytype_int16;
+#endif
+
+#ifndef YYSIZE_T
+# ifdef __SIZE_TYPE__
+# define YYSIZE_T __SIZE_TYPE__
+# elif defined size_t
+# define YYSIZE_T size_t
+# elif ! defined YYSIZE_T && (defined __STDC__ || defined __C99__FUNC__ \
+ || defined __cplusplus || defined _MSC_VER)
+# include <stddef.h> /* INFRINGES ON USER NAME SPACE */
+# define YYSIZE_T size_t
+# else
+# define YYSIZE_T unsigned int
+# endif
+#endif
+
+#define YYSIZE_MAXIMUM ((YYSIZE_T) -1)
+
+#ifndef YY_
+# if YYENABLE_NLS
+# if ENABLE_NLS
+# include <libintl.h> /* INFRINGES ON USER NAME SPACE */
+# define YY_(msgid) dgettext ("bison-runtime", msgid)
+# endif
+# endif
+# ifndef YY_
+# define YY_(msgid) msgid
+# endif
+#endif
+
+/* Suppress unused-variable warnings by "using" E. */
+#if ! defined lint || defined __GNUC__
+# define YYUSE(e) ((void) (e))
+#else
+# define YYUSE(e) /* empty */
+#endif
+
+/* Identity function, used to suppress warnings about constant conditions. */
+#ifndef lint
+# define YYID(n) (n)
+#else
+#if (defined __STDC__ || defined __C99__FUNC__ \
+ || defined __cplusplus || defined _MSC_VER)
+static int
+YYID (int i)
+#else
+static int
+YYID (i)
+ int i;
+#endif
+{
+ return i;
+}
+#endif
+
+#if ! defined yyoverflow || YYERROR_VERBOSE
+
+/* The parser invokes alloca or malloc; define the necessary symbols. */
+
+# ifdef YYSTACK_USE_ALLOCA
+# if YYSTACK_USE_ALLOCA
+# ifdef __GNUC__
+# define YYSTACK_ALLOC __builtin_alloca
+# elif defined __BUILTIN_VA_ARG_INCR
+# include <alloca.h> /* INFRINGES ON USER NAME SPACE */
+# elif defined _AIX
+# define YYSTACK_ALLOC __alloca
+# elif defined _MSC_VER
+# include <malloc.h> /* INFRINGES ON USER NAME SPACE */
+# define alloca _alloca
+# else
+# define YYSTACK_ALLOC alloca
+# if ! defined _ALLOCA_H && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \
+ || defined __cplusplus || defined _MSC_VER)
+# include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
+# ifndef _STDLIB_H
+# define _STDLIB_H 1
+# endif
+# endif
+# endif
+# endif
+# endif
+
+# ifdef YYSTACK_ALLOC
+ /* Pacify GCC's `empty if-body' warning. */
+# define YYSTACK_FREE(Ptr) do { /* empty */; } while (YYID (0))
+# ifndef YYSTACK_ALLOC_MAXIMUM
+ /* The OS might guarantee only one guard page at the bottom of the stack,
+ and a page size can be as small as 4096 bytes. So we cannot safely
+ invoke alloca (N) if N exceeds 4096. Use a slightly smaller number
+ to allow for a few compiler-allocated temporary stack slots. */
+# define YYSTACK_ALLOC_MAXIMUM 4032 /* reasonable circa 2006 */
+# endif
+# else
+# define YYSTACK_ALLOC YYMALLOC
+# define YYSTACK_FREE YYFREE
+# ifndef YYSTACK_ALLOC_MAXIMUM
+# define YYSTACK_ALLOC_MAXIMUM YYSIZE_MAXIMUM
+# endif
+# if (defined __cplusplus && ! defined _STDLIB_H \
+ && ! ((defined YYMALLOC || defined malloc) \
+ && (defined YYFREE || defined free)))
+# include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
+# ifndef _STDLIB_H
+# define _STDLIB_H 1
+# endif
+# endif
+# ifndef YYMALLOC
+# define YYMALLOC malloc
+# if ! defined malloc && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \
+ || defined __cplusplus || defined _MSC_VER)
+void *malloc (YYSIZE_T); /* INFRINGES ON USER NAME SPACE */
+# endif
+# endif
+# ifndef YYFREE
+# define YYFREE free
+# if ! defined free && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \
+ || defined __cplusplus || defined _MSC_VER)
+void free (void *); /* INFRINGES ON USER NAME SPACE */
+# endif
+# endif
+# endif
+#endif /* ! defined yyoverflow || YYERROR_VERBOSE */
+
+
+#if (! defined yyoverflow \
+ && (! defined __cplusplus \
+ || (defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL)))
+
+/* A type that is properly aligned for any stack member. */
+union yyalloc
+{
+ yytype_int16 yyss;
+ YYSTYPE yyvs;
+ };
+
+/* The size of the maximum gap between one aligned stack and the next. */
+# define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1)
+
+/* The size of an array large to enough to hold all stacks, each with
+ N elements. */
+# define YYSTACK_BYTES(N) \
+ ((N) * (sizeof (yytype_int16) + sizeof (YYSTYPE)) \
+ + YYSTACK_GAP_MAXIMUM)
+
+/* Copy COUNT objects from FROM to TO. The source and destination do
+ not overlap. */
+# ifndef YYCOPY
+# if defined __GNUC__ && 1 < __GNUC__
+# define YYCOPY(To, From, Count) \
+ __builtin_memcpy (To, From, (Count) * sizeof (*(From)))
+# else
+# define YYCOPY(To, From, Count) \
+ do \
+ { \
+ YYSIZE_T yyi; \
+ for (yyi = 0; yyi < (Count); yyi++) \
+ (To)[yyi] = (From)[yyi]; \
+ } \
+ while (YYID (0))
+# endif
+# endif
+
+/* Relocate STACK from its old location to the new one. The
+ local variables YYSIZE and YYSTACKSIZE give the old and new number of
+ elements in the stack, and YYPTR gives the new location of the
+ stack. Advance YYPTR to a properly aligned location for the next
+ stack. */
+# define YYSTACK_RELOCATE(Stack) \
+ do \
+ { \
+ YYSIZE_T yynewbytes; \
+ YYCOPY (&yyptr->Stack, Stack, yysize); \
+ Stack = &yyptr->Stack; \
+ yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \
+ yyptr += yynewbytes / sizeof (*yyptr); \
+ } \
+ while (YYID (0))
+
+#endif
+
+/* YYFINAL -- State number of the termination state. */
+#define YYFINAL 3
+/* YYLAST -- Last index in YYTABLE. */
+#define YYLAST 2252
+
+/* YYNTOKENS -- Number of terminals. */
+#define YYNTOKENS 81
+/* YYNNTS -- Number of nonterminals. */
+#define YYNNTS 51
+/* YYNRULES -- Number of rules. */
+#define YYNRULES 203
+/* YYNRULES -- Number of states. */
+#define YYNSTATES 388
+
+/* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */
+#define YYUNDEFTOK 2
+#define YYMAXUTOK 318
+
+#define YYTRANSLATE(YYX) \
+ ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK)
+
+/* YYTRANSLATE[YYLEX] -- Bison symbol number corresponding to YYLEX. */
+static const yytype_uint8 yytranslate[] =
+{
+ 0, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 34, 2, 2,
+ 48, 49, 32, 29, 51, 31, 50, 33, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 42, 54,
+ 2, 2, 2, 40, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 52, 2, 53, 35, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 45, 2, 47, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 1, 2, 3, 4,
+ 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
+ 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
+ 25, 26, 27, 28, 30, 36, 37, 38, 39, 41,
+ 43, 44, 46, 55, 56, 57, 58, 59, 60, 61,
+ 62, 63, 64, 65, 66, 67, 68, 69, 70, 71,
+ 72, 73, 74, 75, 76, 77, 78, 79, 80
+};
+
+#if YYDEBUG
+/* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in
+ YYRHS. */
+static const yytype_uint16 yyprhs[] =
+{
+ 0, 0, 3, 5, 6, 9, 10, 13, 15, 19,
+ 21, 23, 26, 29, 31, 33, 36, 39, 41, 43,
+ 45, 49, 55, 61, 65, 71, 77, 81, 85, 89,
+ 91, 95, 97, 101, 103, 105, 107, 111, 113, 117,
+ 120, 123, 125, 128, 130, 133, 137, 141, 146, 148,
+ 152, 154, 158, 160, 163, 167, 172, 174, 176, 180,
+ 183, 188, 192, 198, 200, 202, 205, 207, 211, 213,
+ 217, 220, 222, 226, 228, 229, 232, 236, 242, 248,
+ 255, 259, 262, 264, 267, 270, 274, 278, 283, 288,
+ 293, 298, 302, 307, 311, 316, 320, 324, 326, 328,
+ 332, 334, 338, 341, 343, 347, 349, 351, 353, 355,
+ 358, 363, 369, 372, 375, 378, 382, 386, 390, 394,
+ 398, 402, 406, 410, 414, 418, 422, 426, 430, 434,
+ 438, 442, 446, 450, 454, 457, 461, 466, 470, 475,
+ 481, 488, 495, 503, 509, 513, 519, 527, 541, 545,
+ 548, 551, 554, 557, 561, 565, 569, 573, 577, 581,
+ 586, 588, 590, 593, 596, 600, 605, 609, 615, 623,
+ 625, 629, 633, 635, 637, 640, 645, 649, 655, 658,
+ 663, 665, 667, 670, 676, 684, 690, 698, 708, 717,
+ 720, 723, 726, 730, 732, 734, 735, 737, 739, 740,
+ 742, 743, 745, 747
+};
+
+/* YYRHS -- A `-1'-separated list of the rules' RHS. */
+static const yytype_int16 yyrhs[] =
+{
+ 82, 0, -1, 83, -1, -1, 83, 86, -1, -1,
+ 84, 86, -1, 3, -1, 85, 50, 3, -1, 88,
+ -1, 125, -1, 87, 88, -1, 87, 125, -1, 78,
+ -1, 77, -1, 87, 78, -1, 87, 77, -1, 94,
+ -1, 112, -1, 113, -1, 56, 93, 54, -1, 60,
+ 85, 57, 90, 54, -1, 60, 85, 57, 32, 54,
+ -1, 57, 85, 54, -1, 60, 91, 56, 90, 54,
+ -1, 60, 91, 56, 32, 54, -1, 58, 92, 54,
+ -1, 59, 3, 54, -1, 59, 38, 54, -1, 3,
+ -1, 3, 3, 3, -1, 89, -1, 90, 51, 89,
+ -1, 38, -1, 3, -1, 3, -1, 91, 3, 3,
+ -1, 92, -1, 93, 51, 92, -1, 95, 54, -1,
+ 96, 100, -1, 97, -1, 85, 98, -1, 85, -1,
+ 52, 53, -1, 98, 52, 53, -1, 52, 119, 53,
+ -1, 99, 52, 119, 53, -1, 101, -1, 100, 51,
+ 101, -1, 102, -1, 102, 41, 103, -1, 3, -1,
+ 3, 98, -1, 3, 48, 49, -1, 3, 48, 108,
+ 49, -1, 119, -1, 105, -1, 45, 84, 47, -1,
+ 45, 47, -1, 45, 55, 103, 47, -1, 45, 106,
+ 47, -1, 45, 106, 55, 103, 47, -1, 51, -1,
+ 107, -1, 107, 51, -1, 103, -1, 107, 51, 103,
+ -1, 109, -1, 109, 55, 111, -1, 55, 111, -1,
+ 111, -1, 109, 51, 111, -1, 74, -1, -1, 110,
+ 96, -1, 110, 96, 102, -1, 110, 96, 102, 41,
+ 103, -1, 96, 3, 48, 49, 127, -1, 96, 3,
+ 48, 108, 49, 127, -1, 62, 3, 104, -1, 63,
+ 94, -1, 42, -1, 119, 42, -1, 42, 119, -1,
+ 119, 42, 119, -1, 115, 50, 3, -1, 85, 52,
+ 119, 53, -1, 115, 52, 119, 53, -1, 85, 52,
+ 114, 53, -1, 115, 52, 114, 53, -1, 85, 48,
+ 49, -1, 85, 48, 117, 49, -1, 115, 48, 49,
+ -1, 115, 48, 117, 49, -1, 48, 119, 49, -1,
+ 48, 85, 49, -1, 73, -1, 119, -1, 3, 41,
+ 119, -1, 118, -1, 118, 55, 116, -1, 55, 116,
+ -1, 116, -1, 118, 51, 116, -1, 85, -1, 115,
+ -1, 76, -1, 38, -1, 76, 119, -1, 48, 85,
+ 49, 119, -1, 48, 85, 98, 49, 119, -1, 29,
+ 119, -1, 31, 119, -1, 36, 119, -1, 119, 29,
+ 119, -1, 119, 31, 119, -1, 119, 32, 119, -1,
+ 119, 33, 119, -1, 119, 34, 119, -1, 119, 35,
+ 119, -1, 119, 25, 119, -1, 119, 26, 119, -1,
+ 119, 27, 119, -1, 119, 28, 119, -1, 119, 23,
+ 119, -1, 119, 24, 119, -1, 119, 20, 119, -1,
+ 119, 19, 119, -1, 119, 30, 119, -1, 119, 22,
+ 119, -1, 119, 21, 119, -1, 119, 37, 119, -1,
+ 119, 13, 119, -1, 64, 97, -1, 64, 97, 99,
+ -1, 64, 97, 99, 98, -1, 64, 97, 98, -1,
+ 64, 97, 98, 105, -1, 64, 97, 48, 49, 127,
+ -1, 64, 97, 98, 48, 49, 127, -1, 64, 97,
+ 48, 108, 49, 127, -1, 64, 97, 98, 48, 108,
+ 49, 127, -1, 119, 40, 119, 42, 119, -1, 119,
+ 41, 119, -1, 48, 119, 51, 119, 49, -1, 48,
+ 119, 51, 119, 51, 119, 49, -1, 48, 119, 51,
+ 119, 51, 119, 51, 119, 51, 119, 51, 119, 49,
+ -1, 119, 120, 119, -1, 119, 121, -1, 13, 119,
+ -1, 12, 119, -1, 119, 13, -1, 119, 4, 119,
+ -1, 119, 5, 119, -1, 119, 6, 119, -1, 119,
+ 7, 119, -1, 119, 8, 119, -1, 119, 9, 119,
+ -1, 61, 45, 83, 47, -1, 12, -1, 122, -1,
+ 121, 122, -1, 122, 121, -1, 121, 122, 121, -1,
+ 45, 18, 119, 47, -1, 45, 119, 47, -1, 45,
+ 119, 51, 119, 47, -1, 45, 119, 51, 119, 51,
+ 119, 47, -1, 10, -1, 10, 123, 10, -1, 10,
+ 124, 10, -1, 11, -1, 14, -1, 16, 119, -1,
+ 16, 119, 46, 119, -1, 16, 17, 119, -1, 16,
+ 17, 119, 46, 119, -1, 15, 119, -1, 15, 119,
+ 46, 119, -1, 54, -1, 127, -1, 126, 54, -1,
+ 65, 48, 119, 49, 125, -1, 65, 48, 119, 49,
+ 125, 66, 125, -1, 67, 48, 119, 49, 125, -1,
+ 68, 125, 67, 48, 119, 49, 54, -1, 69, 48,
+ 128, 54, 129, 54, 130, 49, 125, -1, 69, 48,
+ 96, 3, 42, 119, 49, 125, -1, 70, 54, -1,
+ 71, 54, -1, 72, 54, -1, 72, 119, 54, -1,
+ 119, -1, 104, -1, -1, 131, -1, 95, -1, -1,
+ 119, -1, -1, 131, -1, 126, -1, 131, 51, 126,
+ -1
+};
+
+/* YYRLINE[YYN] -- source line where rule number YYN was defined. */
+static const yytype_uint16 yyrline[] =
+{
+ 0, 177, 177, 181, 182, 187, 188, 193, 194, 198,
+ 199, 200, 202, 207, 208, 209, 211, 216, 217, 218,
+ 219, 221, 223, 225, 226, 228, 230, 232, 233, 238,
+ 240, 244, 245, 250, 251, 255, 257, 261, 262, 267,
+ 271, 275, 276, 280, 284, 285, 289, 290, 295, 296,
+ 301, 302, 307, 308, 309, 311, 316, 317, 321, 326,
+ 327, 329, 331, 336, 337, 338, 342, 344, 349, 350,
+ 352, 356, 357, 362, 363, 367, 369, 371, 376, 378,
+ 383, 384, 388, 389, 390, 391, 395, 396, 398, 399,
+ 401, 402, 405, 409, 410, 412, 414, 416, 420, 421,
+ 425, 426, 428, 432, 433, 439, 440, 441, 442, 444,
+ 445, 447, 449, 451, 453, 454, 455, 456, 457, 458,
+ 459, 460, 461, 462, 463, 464, 465, 466, 467, 468,
+ 469, 470, 471, 472, 473, 475, 477, 479, 481, 483,
+ 485, 490, 492, 497, 499, 501, 503, 505, 507, 509,
+ 515, 517, 520, 522, 523, 525, 526, 527, 528, 530,
+ 537, 538, 540, 543, 546, 552, 553, 554, 557, 563,
+ 564, 566, 568, 569, 573, 575, 578, 581, 587, 588,
+ 593, 594, 595, 596, 598, 600, 602, 604, 606, 608,
+ 609, 610, 611, 615, 619, 623, 624, 625, 629, 630,
+ 634, 635, 639, 640
+};
+#endif
+
+#if YYDEBUG || YYERROR_VERBOSE || YYTOKEN_TABLE
+/* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM.
+ First, the terminals, then, starting at YYNTOKENS, nonterminals. */
+static const char *const yytname[] =
+{
+ "$end", "error", "$undefined", "ID", "ADD", "SUBTRACT", "TIMES",
+ "DIVIDE", "MOD", "EXPONENT", "DOTS", "COLONS", "DASHES", "INCR",
+ "LONGDASH", "CONTROLS", "TENSION", "ATLEAST", "CURL", "COR", "CAND",
+ "BAR", "AMPERSAND", "EQ", "NEQ", "LT", "LE", "GT", "GE", "'+'", "CARETS",
+ "'-'", "'*'", "'/'", "'%'", "'^'", "LOGNOT", "OPERATOR", "STRING",
+ "LOOSE", "'?'", "ASSIGN", "':'", "DIRTAG", "JOIN_PREC", "'{'", "AND",
+ "'}'", "'('", "')'", "'.'", "','", "'['", "']'", "';'", "ELLIPSIS",
+ "ACCESS", "UNRAVEL", "IMPORT", "INCLUDE", "FROM", "QUOTE", "STRUCT",
+ "TYPEDEF", "NEW", "IF", "ELSE", "WHILE", "DO", "FOR", "BREAK",
+ "CONTINUE", "RETURN_", "THIS", "EXPLICIT", "GARBAGE", "LIT", "PERM",
+ "MODIFIER", "UNARY", "EXP_IN_PARENS_RULE", "$accept", "file",
+ "fileblock", "bareblock", "name", "runnable", "modifiers", "dec",
+ "idpair", "idpairlist", "strid", "stridpair", "stridpairlist", "vardec",
+ "barevardec", "type", "celltype", "dims", "dimexps", "decidlist",
+ "decid", "decidstart", "varinit", "block", "arrayinit", "basearrayinit",
+ "varinits", "formals", "baseformals", "explicitornot", "formal",
+ "fundec", "typedec", "slice", "value", "argument", "arglist",
+ "basearglist", "exp", "join", "dir", "basicjoin", "tension", "controls",
+ "stm", "stmexp", "blockstm", "forinit", "fortest", "forupdate",
+ "stmexplist", 0
+};
+#endif
+
+# ifdef YYPRINT
+/* YYTOKNUM[YYLEX-NUM] -- Internal token number corresponding to
+ token YYLEX-NUM. */
+static const yytype_uint16 yytoknum[] =
+{
+ 0, 256, 257, 258, 259, 260, 261, 262, 263, 264,
+ 265, 266, 267, 268, 269, 270, 271, 272, 273, 274,
+ 275, 276, 277, 278, 279, 280, 281, 282, 283, 43,
+ 284, 45, 42, 47, 37, 94, 285, 286, 287, 288,
+ 63, 289, 58, 290, 291, 123, 292, 125, 40, 41,
+ 46, 44, 91, 93, 59, 293, 294, 295, 296, 297,
+ 298, 299, 300, 301, 302, 303, 304, 305, 306, 307,
+ 308, 309, 310, 311, 312, 313, 314, 315, 316, 317,
+ 318
+};
+# endif
+
+/* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */
+static const yytype_uint8 yyr1[] =
+{
+ 0, 81, 82, 83, 83, 84, 84, 85, 85, 86,
+ 86, 86, 86, 87, 87, 87, 87, 88, 88, 88,
+ 88, 88, 88, 88, 88, 88, 88, 88, 88, 89,
+ 89, 90, 90, 91, 91, 92, 92, 93, 93, 94,
+ 95, 96, 96, 97, 98, 98, 99, 99, 100, 100,
+ 101, 101, 102, 102, 102, 102, 103, 103, 104, 105,
+ 105, 105, 105, 106, 106, 106, 107, 107, 108, 108,
+ 108, 109, 109, 110, 110, 111, 111, 111, 112, 112,
+ 113, 113, 114, 114, 114, 114, 115, 115, 115, 115,
+ 115, 115, 115, 115, 115, 115, 115, 115, 116, 116,
+ 117, 117, 117, 118, 118, 119, 119, 119, 119, 119,
+ 119, 119, 119, 119, 119, 119, 119, 119, 119, 119,
+ 119, 119, 119, 119, 119, 119, 119, 119, 119, 119,
+ 119, 119, 119, 119, 119, 119, 119, 119, 119, 119,
+ 119, 119, 119, 119, 119, 119, 119, 119, 119, 119,
+ 119, 119, 119, 119, 119, 119, 119, 119, 119, 119,
+ 120, 120, 120, 120, 120, 121, 121, 121, 121, 122,
+ 122, 122, 122, 122, 123, 123, 123, 123, 124, 124,
+ 125, 125, 125, 125, 125, 125, 125, 125, 125, 125,
+ 125, 125, 125, 126, 127, 128, 128, 128, 129, 129,
+ 130, 130, 131, 131
+};
+
+/* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */
+static const yytype_uint8 yyr2[] =
+{
+ 0, 2, 1, 0, 2, 0, 2, 1, 3, 1,
+ 1, 2, 2, 1, 1, 2, 2, 1, 1, 1,
+ 3, 5, 5, 3, 5, 5, 3, 3, 3, 1,
+ 3, 1, 3, 1, 1, 1, 3, 1, 3, 2,
+ 2, 1, 2, 1, 2, 3, 3, 4, 1, 3,
+ 1, 3, 1, 2, 3, 4, 1, 1, 3, 2,
+ 4, 3, 5, 1, 1, 2, 1, 3, 1, 3,
+ 2, 1, 3, 1, 0, 2, 3, 5, 5, 6,
+ 3, 2, 1, 2, 2, 3, 3, 4, 4, 4,
+ 4, 3, 4, 3, 4, 3, 3, 1, 1, 3,
+ 1, 3, 2, 1, 3, 1, 1, 1, 1, 2,
+ 4, 5, 2, 2, 2, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 2, 3, 4, 3, 4, 5,
+ 6, 6, 7, 5, 3, 5, 7, 13, 3, 2,
+ 2, 2, 2, 3, 3, 3, 3, 3, 3, 4,
+ 1, 1, 2, 2, 3, 4, 3, 5, 7, 1,
+ 3, 3, 1, 1, 2, 4, 3, 5, 2, 4,
+ 1, 1, 2, 5, 7, 5, 7, 9, 8, 2,
+ 2, 2, 3, 1, 1, 0, 1, 1, 0, 1,
+ 0, 1, 1, 3
+};
+
+/* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state
+ STATE-NUM when YYTABLE doesn't specify something else to do. Zero
+ means the default is an error. */
+static const yytype_uint8 yydefact[] =
+{
+ 3, 0, 2, 1, 7, 0, 0, 0, 0, 0,
+ 108, 5, 0, 180, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 97, 107, 14, 13, 105, 4, 0, 9, 17, 0,
+ 0, 41, 194, 18, 19, 106, 193, 10, 0, 181,
+ 105, 151, 150, 112, 113, 114, 0, 105, 0, 35,
+ 33, 0, 37, 0, 0, 0, 0, 0, 7, 0,
+ 0, 3, 0, 43, 81, 0, 43, 134, 0, 0,
+ 0, 195, 189, 190, 191, 0, 109, 0, 0, 0,
+ 42, 16, 15, 11, 12, 39, 52, 40, 48, 50,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 169,
+ 172, 160, 152, 173, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 149, 161, 182, 0,
+ 58, 6, 96, 0, 95, 0, 0, 0, 20, 23,
+ 26, 27, 28, 0, 0, 0, 80, 0, 52, 74,
+ 0, 137, 135, 0, 0, 0, 197, 0, 202, 0,
+ 196, 192, 7, 91, 0, 103, 0, 100, 98, 8,
+ 82, 44, 0, 0, 0, 74, 53, 0, 0, 93,
+ 0, 86, 0, 0, 153, 154, 155, 156, 157, 158,
+ 0, 0, 0, 0, 133, 128, 127, 131, 130, 125,
+ 126, 121, 122, 123, 124, 115, 129, 116, 117, 118,
+ 119, 120, 132, 0, 144, 0, 0, 148, 162, 163,
+ 110, 0, 0, 36, 38, 29, 0, 31, 0, 0,
+ 0, 159, 74, 0, 74, 73, 0, 68, 0, 71,
+ 0, 0, 74, 138, 0, 136, 0, 0, 0, 52,
+ 198, 0, 0, 102, 92, 0, 0, 84, 89, 83,
+ 87, 45, 54, 0, 49, 51, 57, 56, 94, 90,
+ 88, 178, 0, 174, 170, 171, 0, 0, 166, 0,
+ 164, 111, 145, 0, 0, 22, 0, 21, 25, 24,
+ 54, 0, 139, 70, 0, 74, 74, 75, 46, 59,
+ 63, 0, 66, 0, 64, 0, 0, 0, 183, 185,
+ 0, 0, 199, 0, 203, 99, 104, 101, 85, 78,
+ 55, 0, 176, 0, 143, 165, 0, 0, 30, 32,
+ 55, 141, 72, 69, 76, 0, 61, 0, 65, 140,
+ 0, 47, 0, 0, 0, 200, 79, 179, 0, 175,
+ 167, 0, 146, 0, 0, 60, 0, 67, 142, 184,
+ 186, 0, 0, 201, 177, 0, 0, 77, 62, 188,
+ 0, 168, 0, 187, 0, 0, 0, 147
+};
+
+/* YYDEFGOTO[NTERM-NUM]. */
+static const yytype_int16 yydefgoto[] =
+{
+ -1, 1, 2, 56, 50, 35, 36, 37, 237, 238,
+ 61, 62, 63, 38, 39, 40, 41, 186, 162, 97,
+ 98, 99, 275, 42, 276, 313, 314, 246, 247, 248,
+ 249, 43, 44, 182, 45, 175, 176, 177, 46, 135,
+ 136, 137, 202, 203, 47, 48, 49, 169, 323, 372,
+ 170
+};
+
+/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing
+ STATE-NUM. */
+#define YYPACT_NINF -230
+static const yytype_int16 yypact[] =
+{
+ -230, 40, 476, -230, -230, 780, 780, 780, 780, 780,
+ -230, -230, 780, -230, 6, 60, 6, 18, 20, 27,
+ 76, 60, 60, 46, 83, 202, 96, 91, 113, 647,
+ -230, 17, -230, -230, 35, -230, 547, -230, -230, 140,
+ 176, -230, -230, -230, -230, 111, 1972, -230, 148, -230,
+ 118, 152, 152, 152, 152, -230, 334, 108, 1147, 204,
+ -230, 205, -230, 92, 38, 155, 156, 157, 162, -8,
+ 163, -230, 167, 19, -230, 210, 171, 124, 780, 780,
+ 160, 780, -230, -230, -230, 896, 152, 168, 219, 291,
+ 172, -230, -230, -230, -230, -230, 125, 174, -230, 187,
+ 626, 227, 693, 780, 780, 780, 780, 780, 780, 14,
+ -230, -230, 17, -230, 780, 780, 780, 780, 780, 780,
+ 780, 780, 780, 780, 780, 780, 780, 780, 780, 780,
+ 780, 780, 780, 780, 701, 780, -230, 189, -230, 693,
+ -230, -230, 17, 37, -230, 780, 236, 6, -230, -230,
+ -230, -230, -230, 15, 16, 405, -230, 190, 126, -22,
+ 715, 90, 193, 1483, 1529, 194, -230, 245, -230, 197,
+ 201, -230, 213, -230, 823, -230, 216, 133, 1972, -230,
+ 780, -230, 206, 947, 209, -14, 172, 210, 758, -230,
+ 230, -230, 215, 997, 1972, 1972, 1972, 1972, 1972, 1972,
+ 780, 769, 266, 272, 119, 2086, 2114, 2142, 2170, 2198,
+ 2198, 2207, 2207, 2207, 2207, 158, 413, 158, 152, 152,
+ 152, 152, 279, 1930, 1972, 780, 1195, 119, 189, -230,
+ -230, 780, 1243, -230, -230, 280, 231, -230, 147, 232,
+ 149, -230, -12, 167, 221, -230, 238, 134, 60, -230,
+ 1047, 618, -10, -230, 715, 172, 202, 202, 780, 9,
+ 780, 780, 780, -230, -230, 823, 823, 1972, -230, 780,
+ -230, -230, 167, 247, -230, -230, -230, 1972, -230, -230,
+ -230, 1801, 780, 1844, -230, -230, 780, 1713, -230, 780,
+ -230, -230, -230, 780, 294, -230, 295, -230, -230, -230,
+ -230, 250, -230, -230, 167, 221, 221, 210, -230, -230,
+ -230, 758, -230, 12, 249, 167, 252, 1097, 239, -230,
+ 1575, 780, 1972, 248, -230, 1972, -230, -230, 1972, -230,
+ 167, 780, 1887, 780, 2050, -230, 1291, 1339, -230, -230,
+ -230, -230, -230, -230, 274, 260, -230, 758, 758, -230,
+ 167, -230, 202, 263, 1621, 780, -230, 2014, 780, 2014,
+ -230, 780, -230, 780, 758, -230, 271, -230, -230, -230,
+ -230, 202, 270, 201, 2014, 1757, 1387, -230, -230, -230,
+ 202, -230, 780, -230, 1435, 780, 1667, -230
+};
+
+/* YYPGOTO[NTERM-NUM]. */
+static const yytype_int16 yypgoto[] =
+{
+ -230, -230, 254, -230, 10, 265, -230, 287, 34, 177,
+ 316, -6, -230, 314, 255, -13, 318, -23, -230, -230,
+ 151, 41, -215, 269, 184, -230, -230, -172, -230, -230,
+ -229, -230, -230, 259, -230, -160, 257, -230, -5, -230,
+ -120, 214, -230, -230, -20, -75, -168, -230, -230, -230,
+ -1
+};
+
+/* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If
+ positive, shift that token. If negative, reduce the rule which
+ number is the opposite. If zero, do what YYDEFACT says.
+ If YYTABLE_NINF, syntax error. */
+#define YYTABLE_NINF -44
+static const yytype_int16 yytable[] =
+{
+ 51, 52, 53, 54, 55, 80, 168, 58, 75, 59,
+ 65, 90, 34, 273, 263, 303, 94, 229, 235, 235,
+ 4, 66, 57, 68, 85, 64, 86, 243, 69, 200,
+ 201, 73, 76, 244, 143, 272, 312, 300, -43, 315,
+ 3, 244, 88, 244, 60, 244, 34, 236, 239, 153,
+ 90, 321, 245, 9, 161, 10, 67, 242, 60, 346,
+ 245, 157, 245, 4, 245, 12, 34, 347, 167, 88,
+ 301, 157, 71, 163, 164, 302, 342, 343, 19, 72,
+ 316, 22, 178, 87, 183, 88, 231, 89, 88, 184,
+ 30, 34, 149, 31, 78, 178, 345, 193, 194, 195,
+ 196, 197, 198, 199, 329, 326, 327, 204, 290, 205,
+ 206, 207, 208, 209, 210, 211, 212, 213, 214, 215,
+ 216, 217, 218, 219, 220, 221, 222, 223, 224, 226,
+ 227, 79, 366, 367, 183, 251, 341, 230, 252, 255,
+ 232, 234, 184, 147, 81, 82, 148, 349, 124, 377,
+ 126, 127, 128, 129, 130, 250, 87, 142, 88, 100,
+ 89, 101, 356, 102, 134, 34, 87, 83, 88, 178,
+ 139, 172, 159, 185, 242, 267, 160, 157, 157, 96,
+ 5, 6, 368, 277, 265, 305, 324, 130, 266, 306,
+ 127, 128, 129, 130, 95, 281, 283, 7, 296, 8,
+ 296, 297, 138, 299, 9, 4, 10, -34, 146, 150,
+ 151, 152, 11, 158, 5, 6, 12, 173, -34, 154,
+ 287, 88, 179, 174, 184, 187, 291, 165, 188, 19,
+ 191, 7, 22, 8, 134, 307, 318, 319, 9, 233,
+ 10, 30, 258, 181, 31, 254, 277, 11, 259, 317,
+ 12, 260, 261, 320, 262, 322, 13, 325, 73, 268,
+ 178, 178, 271, 19, 328, 264, 22, 23, 279, 24,
+ 25, 26, 27, 28, 29, 30, 284, 332, 31, 278,
+ 168, 334, 285, 294, 336, 295, 298, 304, 337, 109,
+ 110, 111, 112, 113, 4, 245, 330, 338, 235, 340,
+ 348, 350, 355, 5, 6, 352, 277, 365, 124, 125,
+ 126, 127, 128, 129, 130, 364, 354, 370, 378, 380,
+ 7, 141, 8, 93, 134, 155, 357, 9, 359, 10,
+ 339, 240, 369, 180, 70, 74, 166, 4, 274, 12,
+ 77, 156, 277, 277, 181, 253, 5, 6, 344, 0,
+ 228, 379, 19, 374, 373, 22, 375, 190, 376, 277,
+ 383, 192, 0, 7, 30, 8, 0, 31, 0, 0,
+ 9, 0, 10, 0, 0, 0, 0, 384, 0, 11,
+ 386, 140, 12, 0, 0, 0, 0, 0, 13, 0,
+ 14, 15, 16, 17, 18, 19, 20, 21, 22, 23,
+ 0, 24, 25, 26, 27, 28, 29, 30, 4, 0,
+ 31, 32, 33, 0, 0, 0, 0, 5, 6, 0,
+ 0, 0, 0, 109, 110, 111, 112, 113, 0, 0,
+ 0, 0, 0, 0, 7, 0, 8, 0, 0, 0,
+ 0, 9, 124, 10, 126, 127, 128, 129, 130, 0,
+ 11, 0, 241, 12, 0, 0, 0, 0, 134, 13,
+ 0, 14, 15, 16, 17, 18, 19, 20, 21, 22,
+ 23, 0, 24, 25, 26, 27, 28, 29, 30, 4,
+ 0, 31, 32, 33, 0, 0, 0, 0, 5, 6,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 7, 0, 8, 0, 0,
+ 0, 0, 9, 0, 10, 0, 0, 0, 0, 0,
+ 0, 11, 0, 0, 12, 0, 0, 0, 0, 0,
+ 13, 0, 14, 15, 16, 17, 18, 19, 20, 21,
+ 22, 23, 0, 24, 25, 26, 27, 28, 29, 30,
+ 4, 0, 31, 32, 33, 0, 0, 0, 0, 5,
+ 6, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 7, 0, 8, 0,
+ 0, 0, 0, 9, 0, 10, 0, 0, 0, 0,
+ 0, 0, 11, 0, 0, 12, 0, 0, 0, 0,
+ 0, 13, 0, 14, 15, 16, 17, 18, 19, 20,
+ 21, 22, 23, 0, 24, 25, 26, 27, 28, 29,
+ 30, 4, 0, 31, 91, 92, 0, 0, 0, 172,
+ 5, 6, 0, 0, 0, 0, 0, 0, 5, 6,
+ 0, 0, 0, 0, 0, 0, 0, 7, 0, 8,
+ 4, 0, 0, 0, 9, 7, 10, 8, 0, 5,
+ 6, 0, 9, 251, 10, 309, 12, 0, 0, 310,
+ 0, 0, 0, 311, 12, 189, 7, 0, 8, 19,
+ 0, 174, 22, 9, 0, 10, 0, 19, 0, 0,
+ 22, 30, 0, 0, 31, 12, 4, 0, 0, 30,
+ 0, 84, 31, 0, 4, 5, 6, 0, 19, 0,
+ 0, 22, 0, 5, 6, 0, 0, 0, 4, 225,
+ 30, 0, 7, 31, 8, 0, 0, 5, 6, 9,
+ 7, 10, 8, 0, 0, 180, 0, 9, 0, 10,
+ 0, 12, 0, 0, 7, 0, 8, 0, 0, 12,
+ 0, 9, 0, 10, 19, 0, 0, 22, 0, 0,
+ 0, 4, 19, 12, 0, 22, 30, 0, 181, 31,
+ 5, 6, 4, 0, 30, 0, 19, 31, 0, 22,
+ 0, 5, 6, 4, 0, 0, 282, 7, 30, 8,
+ 0, 31, 5, 6, 9, 0, 10, 0, 7, 0,
+ 8, 0, 0, 251, 0, 9, 12, 10, 0, 7,
+ 0, 8, 0, 0, 0, 0, 9, 12, 10, 19,
+ 0, 0, 22, 0, 0, 0, 172, 0, 12, 0,
+ 19, 30, 0, 22, 31, 5, 6, 0, 0, 0,
+ 0, 19, 30, 0, 22, 31, 0, 0, 0, 0,
+ 0, 0, 7, 30, 8, 0, 31, 0, 0, 9,
+ 0, 10, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 12, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 19, 0, 0, 22, 0, 0,
+ 0, 0, 0, 0, 0, 0, 30, 0, 0, 31,
+ 103, 104, 105, 106, 107, 108, 109, 110, 111, 112,
+ 113, 0, 0, 0, 0, 114, 115, 116, 117, 118,
+ 119, 120, 121, 122, 123, 124, 125, 126, 127, 128,
+ 129, 130, 0, 131, 0, 0, 132, 133, 0, 0,
+ 0, 134, 0, 0, 0, 0, 0, 0, 0, 0,
+ 171, 103, 104, 105, 106, 107, 108, 109, 110, 111,
+ 112, 113, 0, 0, 0, 0, 114, 115, 116, 117,
+ 118, 119, 120, 121, 122, 123, 124, 125, 126, 127,
+ 128, 129, 130, 0, 131, 0, 0, 132, 133, 269,
+ 0, 0, 134, 0, 0, 0, 0, 0, 0, 0,
+ 270, 103, 104, 105, 106, 107, 108, 109, 110, 111,
+ 112, 113, 0, 0, 0, 0, 114, 115, 116, 117,
+ 118, 119, 120, 121, 122, 123, 124, 125, 126, 127,
+ 128, 129, 130, 0, 131, 0, 0, 132, 133, 269,
+ 0, 0, 134, 0, 0, 0, 0, 0, 0, 0,
+ 280, 103, 104, 105, 106, 107, 108, 109, 110, 111,
+ 112, 113, 0, 0, 0, 0, 114, 115, 116, 117,
+ 118, 119, 120, 121, 122, 123, 124, 125, 126, 127,
+ 128, 129, 130, 0, 131, 0, 0, 132, 133, 0,
+ 0, 0, 134, 0, 0, 0, 0, 0, 0, 0,
+ 308, 103, 104, 105, 106, 107, 108, 109, 110, 111,
+ 112, 113, 0, 0, 0, 0, 114, 115, 116, 117,
+ 118, 119, 120, 121, 122, 123, 124, 125, 126, 127,
+ 128, 129, 130, 0, 131, 0, 0, 132, 133, 0,
+ 0, 0, 134, 0, 0, 0, 0, 0, 0, 0,
+ 351, 103, 104, 105, 106, 107, 108, 109, 110, 111,
+ 112, 113, 0, 0, 0, 0, 114, 115, 116, 117,
+ 118, 119, 120, 121, 122, 123, 124, 125, 126, 127,
+ 128, 129, 130, 0, 131, 0, 0, 132, 133, 0,
+ 0, 0, 134, 0, 0, 0, 144, 0, 145, 103,
+ 104, 105, 106, 107, 108, 109, 110, 111, 112, 113,
+ 0, 0, 0, 0, 114, 115, 116, 117, 118, 119,
+ 120, 121, 122, 123, 124, 125, 126, 127, 128, 129,
+ 130, 0, 131, 0, 0, 132, 133, 0, 0, 0,
+ 134, 0, 288, 0, 0, 0, 289, 103, 104, 105,
+ 106, 107, 108, 109, 110, 111, 112, 113, 0, 0,
+ 0, 0, 114, 115, 116, 117, 118, 119, 120, 121,
+ 122, 123, 124, 125, 126, 127, 128, 129, 130, 0,
+ 131, 0, 0, 132, 133, 0, 0, 0, 134, 0,
+ 0, 0, 292, 0, 293, 103, 104, 105, 106, 107,
+ 108, 109, 110, 111, 112, 113, 0, 0, 0, 0,
+ 114, 115, 116, 117, 118, 119, 120, 121, 122, 123,
+ 124, 125, 126, 127, 128, 129, 130, 0, 131, 0,
+ 0, 132, 133, 0, 0, 0, 134, 0, 360, 0,
+ 0, 0, 361, 103, 104, 105, 106, 107, 108, 109,
+ 110, 111, 112, 113, 0, 0, 0, 0, 114, 115,
+ 116, 117, 118, 119, 120, 121, 122, 123, 124, 125,
+ 126, 127, 128, 129, 130, 0, 131, 0, 0, 132,
+ 133, 0, 0, 0, 134, 0, 0, 0, 362, 0,
+ 363, 103, 104, 105, 106, 107, 108, 109, 110, 111,
+ 112, 113, 0, 0, 0, 0, 114, 115, 116, 117,
+ 118, 119, 120, 121, 122, 123, 124, 125, 126, 127,
+ 128, 129, 130, 0, 131, 0, 0, 132, 133, 0,
+ 0, 0, 134, 0, 0, 0, 0, 0, 382, 103,
+ 104, 105, 106, 107, 108, 109, 110, 111, 112, 113,
+ 0, 0, 0, 0, 114, 115, 116, 117, 118, 119,
+ 120, 121, 122, 123, 124, 125, 126, 127, 128, 129,
+ 130, 0, 131, 0, 0, 132, 133, 0, 0, 0,
+ 134, 0, 0, 0, 0, 0, 385, 103, 104, 105,
+ 106, 107, 108, 109, 110, 111, 112, 113, 0, 0,
+ 0, 0, 114, 115, 116, 117, 118, 119, 120, 121,
+ 122, 123, 124, 125, 126, 127, 128, 129, 130, 0,
+ 131, 0, 0, 132, 133, 0, 0, 0, 134, 0,
+ 0, 0, 256, 103, 104, 105, 106, 107, 108, 109,
+ 110, 111, 112, 113, 0, 0, 0, 0, 114, 115,
+ 116, 117, 118, 119, 120, 121, 122, 123, 124, 125,
+ 126, 127, 128, 129, 130, 0, 131, 0, 0, 132,
+ 133, 0, 0, 0, 134, 0, 0, 0, 257, 103,
+ 104, 105, 106, 107, 108, 109, 110, 111, 112, 113,
+ 0, 0, 0, 0, 114, 115, 116, 117, 118, 119,
+ 120, 121, 122, 123, 124, 125, 126, 127, 128, 129,
+ 130, 0, 131, 0, 0, 132, 133, 0, 0, 0,
+ 134, 0, 0, 0, 353, 103, 104, 105, 106, 107,
+ 108, 109, 110, 111, 112, 113, 0, 0, 0, 0,
+ 114, 115, 116, 117, 118, 119, 120, 121, 122, 123,
+ 124, 125, 126, 127, 128, 129, 130, 0, 131, 0,
+ 0, 132, 133, 0, 0, 0, 134, 0, 0, 0,
+ 371, 103, 104, 105, 106, 107, 108, 109, 110, 111,
+ 112, 113, 0, 0, 0, 0, 114, 115, 116, 117,
+ 118, 119, 120, 121, 122, 123, 124, 125, 126, 127,
+ 128, 129, 130, 0, 131, 0, 0, 132, 133, 0,
+ 0, 0, 134, 0, 0, 0, 387, 103, 104, 105,
+ 106, 107, 108, 109, 110, 111, 112, 113, 0, 0,
+ 0, 0, 114, 115, 116, 117, 118, 119, 120, 121,
+ 122, 123, 124, 125, 126, 127, 128, 129, 130, 0,
+ 131, 0, 0, 132, 133, 0, 0, 0, 134, 0,
+ 335, 103, 104, 105, 106, 107, 108, 109, 110, 111,
+ 112, 113, 0, 0, 0, 0, 114, 115, 116, 117,
+ 118, 119, 120, 121, 122, 123, 124, 125, 126, 127,
+ 128, 129, 130, 0, 131, 0, 0, 132, 133, 0,
+ 0, 0, 134, 0, 381, 103, 104, 105, 106, 107,
+ 108, 0, 110, 111, 112, 113, 0, 0, 0, 0,
+ 114, 115, 116, 117, 118, 119, 120, 121, 122, 123,
+ 124, 125, 126, 127, 128, 129, 130, 0, 131, 0,
+ 0, 132, 133, 0, 0, 0, 134, 331, 103, 104,
+ 105, 106, 107, 108, 0, 110, 111, 112, 113, 0,
+ 0, 0, 0, 114, 115, 116, 117, 118, 119, 120,
+ 121, 122, 123, 124, 125, 126, 127, 128, 129, 130,
+ 0, 131, 0, 0, 132, 133, 0, 0, 0, 134,
+ 333, 103, 104, 105, 106, 107, 108, 0, 110, 111,
+ 112, 113, 0, 0, 0, 0, 114, 115, 116, 117,
+ 118, 119, 120, 121, 122, 123, 124, 125, 126, 127,
+ 128, 129, 130, 0, 131, 0, 0, 132, 133, 0,
+ 0, 0, 134, 358, 103, 104, 105, 106, 107, 108,
+ 109, 110, 111, 112, 113, 0, 0, 0, 0, 114,
+ 115, 116, 117, 118, 119, 120, 121, 122, 123, 124,
+ 125, 126, 127, 128, 129, 130, 0, 131, 0, 0,
+ 132, 133, 286, 0, 0, 134, 103, 104, 105, 106,
+ 107, 108, 109, 110, 111, 112, 113, 0, 0, 0,
+ 0, 114, 115, 116, 117, 118, 119, 120, 121, 122,
+ 123, 124, 125, 126, 127, 128, 129, 130, 0, 131,
+ 0, 0, 132, 133, 0, 0, 0, 134, 103, 104,
+ 105, 106, 107, 108, 0, 110, 111, 112, 113, 0,
+ 0, 0, 0, 114, 115, 116, 117, 118, 119, 120,
+ 121, 122, 123, 124, 125, 126, 127, 128, 129, 130,
+ 0, 131, 0, 0, 132, 133, 0, 0, 0, 134,
+ 109, 110, 111, 112, 113, 0, 0, 0, 0, 114,
+ 115, 116, 117, 118, 119, 120, 121, 122, 123, 124,
+ 125, 126, 127, 128, 129, 130, 0, 131, 0, 0,
+ 132, 0, 0, 0, 0, 134, 109, 110, 111, 112,
+ 113, 0, 0, 0, 0, 0, 115, 116, 117, 118,
+ 119, 120, 121, 122, 123, 124, 125, 126, 127, 128,
+ 129, 130, 0, 131, 109, 110, 111, 112, 113, 0,
+ 0, 134, 0, 0, 0, 116, 117, 118, 119, 120,
+ 121, 122, 123, 124, 125, 126, 127, 128, 129, 130,
+ 0, 131, 109, 110, 111, 112, 113, 0, 0, 134,
+ 0, 0, 0, 0, 117, 118, 119, 120, 121, 122,
+ 123, 124, 125, 126, 127, 128, 129, 130, 0, 131,
+ 109, 110, 111, 112, 113, 0, 0, 134, 0, 0,
+ 0, 0, 0, 118, 119, 120, 121, 122, 123, 124,
+ 125, 126, 127, 128, 129, 130, 0, 131, 109, 110,
+ 111, 112, 113, 0, 0, 134, 0, 109, 110, 111,
+ 112, 113, 0, 120, 121, 122, 123, 124, 125, 126,
+ 127, 128, 129, 130, 0, 131, 124, 125, 126, 127,
+ 128, 129, 130, 134, 131, 0, 0, 0, 0, 0,
+ 0, 0, 134
+};
+
+static const yytype_int16 yycheck[] =
+{
+ 5, 6, 7, 8, 9, 25, 81, 12, 21, 3,
+ 16, 34, 2, 185, 174, 244, 36, 137, 3, 3,
+ 3, 3, 12, 3, 29, 15, 31, 49, 18, 15,
+ 16, 21, 22, 55, 57, 49, 251, 49, 3, 49,
+ 0, 55, 50, 55, 38, 55, 36, 32, 32, 57,
+ 73, 42, 74, 36, 77, 38, 38, 48, 38, 47,
+ 74, 52, 74, 3, 74, 48, 56, 55, 81, 50,
+ 242, 52, 45, 78, 79, 243, 305, 306, 61, 3,
+ 252, 64, 87, 48, 89, 50, 49, 52, 50, 52,
+ 73, 81, 54, 76, 48, 100, 311, 102, 103, 104,
+ 105, 106, 107, 108, 272, 265, 266, 112, 228, 114,
+ 115, 116, 117, 118, 119, 120, 121, 122, 123, 124,
+ 125, 126, 127, 128, 129, 130, 131, 132, 133, 134,
+ 135, 48, 347, 348, 139, 45, 304, 142, 48, 162,
+ 145, 147, 52, 51, 48, 54, 54, 315, 29, 364,
+ 31, 32, 33, 34, 35, 160, 48, 49, 50, 48,
+ 52, 50, 330, 52, 45, 155, 48, 54, 50, 174,
+ 52, 3, 48, 48, 48, 180, 52, 52, 52, 3,
+ 12, 13, 350, 188, 51, 51, 261, 35, 55, 55,
+ 32, 33, 34, 35, 54, 200, 201, 29, 51, 31,
+ 51, 54, 54, 54, 36, 3, 38, 3, 3, 54,
+ 54, 54, 45, 3, 12, 13, 48, 49, 56, 56,
+ 225, 50, 3, 55, 52, 51, 231, 67, 41, 61,
+ 3, 29, 64, 31, 45, 248, 256, 257, 36, 3,
+ 38, 73, 48, 53, 76, 52, 251, 45, 3, 254,
+ 48, 54, 51, 258, 41, 260, 54, 262, 248, 53,
+ 265, 266, 53, 61, 269, 49, 64, 65, 53, 67,
+ 68, 69, 70, 71, 72, 73, 10, 282, 76, 49,
+ 355, 286, 10, 3, 289, 54, 54, 49, 293, 10,
+ 11, 12, 13, 14, 3, 74, 49, 3, 3, 49,
+ 51, 49, 54, 12, 13, 66, 311, 47, 29, 30,
+ 31, 32, 33, 34, 35, 41, 321, 54, 47, 49,
+ 29, 56, 31, 36, 45, 71, 331, 36, 333, 38,
+ 296, 154, 352, 42, 18, 21, 81, 3, 187, 48,
+ 22, 72, 347, 348, 53, 161, 12, 13, 307, -1,
+ 136, 371, 61, 358, 355, 64, 361, 100, 363, 364,
+ 380, 102, -1, 29, 73, 31, -1, 76, -1, -1,
+ 36, -1, 38, -1, -1, -1, -1, 382, -1, 45,
+ 385, 47, 48, -1, -1, -1, -1, -1, 54, -1,
+ 56, 57, 58, 59, 60, 61, 62, 63, 64, 65,
+ -1, 67, 68, 69, 70, 71, 72, 73, 3, -1,
+ 76, 77, 78, -1, -1, -1, -1, 12, 13, -1,
+ -1, -1, -1, 10, 11, 12, 13, 14, -1, -1,
+ -1, -1, -1, -1, 29, -1, 31, -1, -1, -1,
+ -1, 36, 29, 38, 31, 32, 33, 34, 35, -1,
+ 45, -1, 47, 48, -1, -1, -1, -1, 45, 54,
+ -1, 56, 57, 58, 59, 60, 61, 62, 63, 64,
+ 65, -1, 67, 68, 69, 70, 71, 72, 73, 3,
+ -1, 76, 77, 78, -1, -1, -1, -1, 12, 13,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, 29, -1, 31, -1, -1,
+ -1, -1, 36, -1, 38, -1, -1, -1, -1, -1,
+ -1, 45, -1, -1, 48, -1, -1, -1, -1, -1,
+ 54, -1, 56, 57, 58, 59, 60, 61, 62, 63,
+ 64, 65, -1, 67, 68, 69, 70, 71, 72, 73,
+ 3, -1, 76, 77, 78, -1, -1, -1, -1, 12,
+ 13, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, 29, -1, 31, -1,
+ -1, -1, -1, 36, -1, 38, -1, -1, -1, -1,
+ -1, -1, 45, -1, -1, 48, -1, -1, -1, -1,
+ -1, 54, -1, 56, 57, 58, 59, 60, 61, 62,
+ 63, 64, 65, -1, 67, 68, 69, 70, 71, 72,
+ 73, 3, -1, 76, 77, 78, -1, -1, -1, 3,
+ 12, 13, -1, -1, -1, -1, -1, -1, 12, 13,
+ -1, -1, -1, -1, -1, -1, -1, 29, -1, 31,
+ 3, -1, -1, -1, 36, 29, 38, 31, -1, 12,
+ 13, -1, 36, 45, 38, 47, 48, -1, -1, 51,
+ -1, -1, -1, 55, 48, 49, 29, -1, 31, 61,
+ -1, 55, 64, 36, -1, 38, -1, 61, -1, -1,
+ 64, 73, -1, -1, 76, 48, 3, -1, -1, 73,
+ -1, 54, 76, -1, 3, 12, 13, -1, 61, -1,
+ -1, 64, -1, 12, 13, -1, -1, -1, 3, 18,
+ 73, -1, 29, 76, 31, -1, -1, 12, 13, 36,
+ 29, 38, 31, -1, -1, 42, -1, 36, -1, 38,
+ -1, 48, -1, -1, 29, -1, 31, -1, -1, 48,
+ -1, 36, -1, 38, 61, -1, -1, 64, -1, -1,
+ -1, 3, 61, 48, -1, 64, 73, -1, 53, 76,
+ 12, 13, 3, -1, 73, -1, 61, 76, -1, 64,
+ -1, 12, 13, 3, -1, -1, 17, 29, 73, 31,
+ -1, 76, 12, 13, 36, -1, 38, -1, 29, -1,
+ 31, -1, -1, 45, -1, 36, 48, 38, -1, 29,
+ -1, 31, -1, -1, -1, -1, 36, 48, 38, 61,
+ -1, -1, 64, -1, -1, -1, 3, -1, 48, -1,
+ 61, 73, -1, 64, 76, 12, 13, -1, -1, -1,
+ -1, 61, 73, -1, 64, 76, -1, -1, -1, -1,
+ -1, -1, 29, 73, 31, -1, 76, -1, -1, 36,
+ -1, 38, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, 48, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, 61, -1, -1, 64, -1, -1,
+ -1, -1, -1, -1, -1, -1, 73, -1, -1, 76,
+ 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,
+ 14, -1, -1, -1, -1, 19, 20, 21, 22, 23,
+ 24, 25, 26, 27, 28, 29, 30, 31, 32, 33,
+ 34, 35, -1, 37, -1, -1, 40, 41, -1, -1,
+ -1, 45, -1, -1, -1, -1, -1, -1, -1, -1,
+ 54, 4, 5, 6, 7, 8, 9, 10, 11, 12,
+ 13, 14, -1, -1, -1, -1, 19, 20, 21, 22,
+ 23, 24, 25, 26, 27, 28, 29, 30, 31, 32,
+ 33, 34, 35, -1, 37, -1, -1, 40, 41, 42,
+ -1, -1, 45, -1, -1, -1, -1, -1, -1, -1,
+ 53, 4, 5, 6, 7, 8, 9, 10, 11, 12,
+ 13, 14, -1, -1, -1, -1, 19, 20, 21, 22,
+ 23, 24, 25, 26, 27, 28, 29, 30, 31, 32,
+ 33, 34, 35, -1, 37, -1, -1, 40, 41, 42,
+ -1, -1, 45, -1, -1, -1, -1, -1, -1, -1,
+ 53, 4, 5, 6, 7, 8, 9, 10, 11, 12,
+ 13, 14, -1, -1, -1, -1, 19, 20, 21, 22,
+ 23, 24, 25, 26, 27, 28, 29, 30, 31, 32,
+ 33, 34, 35, -1, 37, -1, -1, 40, 41, -1,
+ -1, -1, 45, -1, -1, -1, -1, -1, -1, -1,
+ 53, 4, 5, 6, 7, 8, 9, 10, 11, 12,
+ 13, 14, -1, -1, -1, -1, 19, 20, 21, 22,
+ 23, 24, 25, 26, 27, 28, 29, 30, 31, 32,
+ 33, 34, 35, -1, 37, -1, -1, 40, 41, -1,
+ -1, -1, 45, -1, -1, -1, -1, -1, -1, -1,
+ 53, 4, 5, 6, 7, 8, 9, 10, 11, 12,
+ 13, 14, -1, -1, -1, -1, 19, 20, 21, 22,
+ 23, 24, 25, 26, 27, 28, 29, 30, 31, 32,
+ 33, 34, 35, -1, 37, -1, -1, 40, 41, -1,
+ -1, -1, 45, -1, -1, -1, 49, -1, 51, 4,
+ 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
+ -1, -1, -1, -1, 19, 20, 21, 22, 23, 24,
+ 25, 26, 27, 28, 29, 30, 31, 32, 33, 34,
+ 35, -1, 37, -1, -1, 40, 41, -1, -1, -1,
+ 45, -1, 47, -1, -1, -1, 51, 4, 5, 6,
+ 7, 8, 9, 10, 11, 12, 13, 14, -1, -1,
+ -1, -1, 19, 20, 21, 22, 23, 24, 25, 26,
+ 27, 28, 29, 30, 31, 32, 33, 34, 35, -1,
+ 37, -1, -1, 40, 41, -1, -1, -1, 45, -1,
+ -1, -1, 49, -1, 51, 4, 5, 6, 7, 8,
+ 9, 10, 11, 12, 13, 14, -1, -1, -1, -1,
+ 19, 20, 21, 22, 23, 24, 25, 26, 27, 28,
+ 29, 30, 31, 32, 33, 34, 35, -1, 37, -1,
+ -1, 40, 41, -1, -1, -1, 45, -1, 47, -1,
+ -1, -1, 51, 4, 5, 6, 7, 8, 9, 10,
+ 11, 12, 13, 14, -1, -1, -1, -1, 19, 20,
+ 21, 22, 23, 24, 25, 26, 27, 28, 29, 30,
+ 31, 32, 33, 34, 35, -1, 37, -1, -1, 40,
+ 41, -1, -1, -1, 45, -1, -1, -1, 49, -1,
+ 51, 4, 5, 6, 7, 8, 9, 10, 11, 12,
+ 13, 14, -1, -1, -1, -1, 19, 20, 21, 22,
+ 23, 24, 25, 26, 27, 28, 29, 30, 31, 32,
+ 33, 34, 35, -1, 37, -1, -1, 40, 41, -1,
+ -1, -1, 45, -1, -1, -1, -1, -1, 51, 4,
+ 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
+ -1, -1, -1, -1, 19, 20, 21, 22, 23, 24,
+ 25, 26, 27, 28, 29, 30, 31, 32, 33, 34,
+ 35, -1, 37, -1, -1, 40, 41, -1, -1, -1,
+ 45, -1, -1, -1, -1, -1, 51, 4, 5, 6,
+ 7, 8, 9, 10, 11, 12, 13, 14, -1, -1,
+ -1, -1, 19, 20, 21, 22, 23, 24, 25, 26,
+ 27, 28, 29, 30, 31, 32, 33, 34, 35, -1,
+ 37, -1, -1, 40, 41, -1, -1, -1, 45, -1,
+ -1, -1, 49, 4, 5, 6, 7, 8, 9, 10,
+ 11, 12, 13, 14, -1, -1, -1, -1, 19, 20,
+ 21, 22, 23, 24, 25, 26, 27, 28, 29, 30,
+ 31, 32, 33, 34, 35, -1, 37, -1, -1, 40,
+ 41, -1, -1, -1, 45, -1, -1, -1, 49, 4,
+ 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
+ -1, -1, -1, -1, 19, 20, 21, 22, 23, 24,
+ 25, 26, 27, 28, 29, 30, 31, 32, 33, 34,
+ 35, -1, 37, -1, -1, 40, 41, -1, -1, -1,
+ 45, -1, -1, -1, 49, 4, 5, 6, 7, 8,
+ 9, 10, 11, 12, 13, 14, -1, -1, -1, -1,
+ 19, 20, 21, 22, 23, 24, 25, 26, 27, 28,
+ 29, 30, 31, 32, 33, 34, 35, -1, 37, -1,
+ -1, 40, 41, -1, -1, -1, 45, -1, -1, -1,
+ 49, 4, 5, 6, 7, 8, 9, 10, 11, 12,
+ 13, 14, -1, -1, -1, -1, 19, 20, 21, 22,
+ 23, 24, 25, 26, 27, 28, 29, 30, 31, 32,
+ 33, 34, 35, -1, 37, -1, -1, 40, 41, -1,
+ -1, -1, 45, -1, -1, -1, 49, 4, 5, 6,
+ 7, 8, 9, 10, 11, 12, 13, 14, -1, -1,
+ -1, -1, 19, 20, 21, 22, 23, 24, 25, 26,
+ 27, 28, 29, 30, 31, 32, 33, 34, 35, -1,
+ 37, -1, -1, 40, 41, -1, -1, -1, 45, -1,
+ 47, 4, 5, 6, 7, 8, 9, 10, 11, 12,
+ 13, 14, -1, -1, -1, -1, 19, 20, 21, 22,
+ 23, 24, 25, 26, 27, 28, 29, 30, 31, 32,
+ 33, 34, 35, -1, 37, -1, -1, 40, 41, -1,
+ -1, -1, 45, -1, 47, 4, 5, 6, 7, 8,
+ 9, -1, 11, 12, 13, 14, -1, -1, -1, -1,
+ 19, 20, 21, 22, 23, 24, 25, 26, 27, 28,
+ 29, 30, 31, 32, 33, 34, 35, -1, 37, -1,
+ -1, 40, 41, -1, -1, -1, 45, 46, 4, 5,
+ 6, 7, 8, 9, -1, 11, 12, 13, 14, -1,
+ -1, -1, -1, 19, 20, 21, 22, 23, 24, 25,
+ 26, 27, 28, 29, 30, 31, 32, 33, 34, 35,
+ -1, 37, -1, -1, 40, 41, -1, -1, -1, 45,
+ 46, 4, 5, 6, 7, 8, 9, -1, 11, 12,
+ 13, 14, -1, -1, -1, -1, 19, 20, 21, 22,
+ 23, 24, 25, 26, 27, 28, 29, 30, 31, 32,
+ 33, 34, 35, -1, 37, -1, -1, 40, 41, -1,
+ -1, -1, 45, 46, 4, 5, 6, 7, 8, 9,
+ 10, 11, 12, 13, 14, -1, -1, -1, -1, 19,
+ 20, 21, 22, 23, 24, 25, 26, 27, 28, 29,
+ 30, 31, 32, 33, 34, 35, -1, 37, -1, -1,
+ 40, 41, 42, -1, -1, 45, 4, 5, 6, 7,
+ 8, 9, 10, 11, 12, 13, 14, -1, -1, -1,
+ -1, 19, 20, 21, 22, 23, 24, 25, 26, 27,
+ 28, 29, 30, 31, 32, 33, 34, 35, -1, 37,
+ -1, -1, 40, 41, -1, -1, -1, 45, 4, 5,
+ 6, 7, 8, 9, -1, 11, 12, 13, 14, -1,
+ -1, -1, -1, 19, 20, 21, 22, 23, 24, 25,
+ 26, 27, 28, 29, 30, 31, 32, 33, 34, 35,
+ -1, 37, -1, -1, 40, 41, -1, -1, -1, 45,
+ 10, 11, 12, 13, 14, -1, -1, -1, -1, 19,
+ 20, 21, 22, 23, 24, 25, 26, 27, 28, 29,
+ 30, 31, 32, 33, 34, 35, -1, 37, -1, -1,
+ 40, -1, -1, -1, -1, 45, 10, 11, 12, 13,
+ 14, -1, -1, -1, -1, -1, 20, 21, 22, 23,
+ 24, 25, 26, 27, 28, 29, 30, 31, 32, 33,
+ 34, 35, -1, 37, 10, 11, 12, 13, 14, -1,
+ -1, 45, -1, -1, -1, 21, 22, 23, 24, 25,
+ 26, 27, 28, 29, 30, 31, 32, 33, 34, 35,
+ -1, 37, 10, 11, 12, 13, 14, -1, -1, 45,
+ -1, -1, -1, -1, 22, 23, 24, 25, 26, 27,
+ 28, 29, 30, 31, 32, 33, 34, 35, -1, 37,
+ 10, 11, 12, 13, 14, -1, -1, 45, -1, -1,
+ -1, -1, -1, 23, 24, 25, 26, 27, 28, 29,
+ 30, 31, 32, 33, 34, 35, -1, 37, 10, 11,
+ 12, 13, 14, -1, -1, 45, -1, 10, 11, 12,
+ 13, 14, -1, 25, 26, 27, 28, 29, 30, 31,
+ 32, 33, 34, 35, -1, 37, 29, 30, 31, 32,
+ 33, 34, 35, 45, 37, -1, -1, -1, -1, -1,
+ -1, -1, 45
+};
+
+/* YYSTOS[STATE-NUM] -- The (internal number of the) accessing
+ symbol of state STATE-NUM. */
+static const yytype_uint8 yystos[] =
+{
+ 0, 82, 83, 0, 3, 12, 13, 29, 31, 36,
+ 38, 45, 48, 54, 56, 57, 58, 59, 60, 61,
+ 62, 63, 64, 65, 67, 68, 69, 70, 71, 72,
+ 73, 76, 77, 78, 85, 86, 87, 88, 94, 95,
+ 96, 97, 104, 112, 113, 115, 119, 125, 126, 127,
+ 85, 119, 119, 119, 119, 119, 84, 85, 119, 3,
+ 38, 91, 92, 93, 85, 92, 3, 38, 3, 85,
+ 91, 45, 3, 85, 94, 96, 85, 97, 48, 48,
+ 125, 48, 54, 54, 54, 119, 119, 48, 50, 52,
+ 98, 77, 78, 88, 125, 54, 3, 100, 101, 102,
+ 48, 50, 52, 4, 5, 6, 7, 8, 9, 10,
+ 11, 12, 13, 14, 19, 20, 21, 22, 23, 24,
+ 25, 26, 27, 28, 29, 30, 31, 32, 33, 34,
+ 35, 37, 40, 41, 45, 120, 121, 122, 54, 52,
+ 47, 86, 49, 98, 49, 51, 3, 51, 54, 54,
+ 54, 54, 54, 57, 56, 83, 104, 52, 3, 48,
+ 52, 98, 99, 119, 119, 67, 95, 96, 126, 128,
+ 131, 54, 3, 49, 55, 116, 117, 118, 119, 3,
+ 42, 53, 114, 119, 52, 48, 98, 51, 41, 49,
+ 117, 3, 114, 119, 119, 119, 119, 119, 119, 119,
+ 15, 16, 123, 124, 119, 119, 119, 119, 119, 119,
+ 119, 119, 119, 119, 119, 119, 119, 119, 119, 119,
+ 119, 119, 119, 119, 119, 18, 119, 119, 122, 121,
+ 119, 49, 119, 3, 92, 3, 32, 89, 90, 32,
+ 90, 47, 48, 49, 55, 74, 108, 109, 110, 111,
+ 119, 45, 48, 105, 52, 98, 49, 49, 48, 3,
+ 54, 51, 41, 116, 49, 51, 55, 119, 53, 42,
+ 53, 53, 49, 108, 101, 103, 105, 119, 49, 53,
+ 53, 119, 17, 119, 10, 10, 42, 119, 47, 51,
+ 121, 119, 49, 51, 3, 54, 51, 54, 54, 54,
+ 49, 108, 127, 111, 49, 51, 55, 96, 53, 47,
+ 51, 55, 103, 106, 107, 49, 108, 119, 125, 125,
+ 119, 42, 119, 129, 126, 119, 116, 116, 119, 127,
+ 49, 46, 119, 46, 119, 47, 119, 119, 3, 89,
+ 49, 127, 111, 111, 102, 103, 47, 55, 51, 127,
+ 49, 53, 66, 49, 119, 54, 127, 119, 46, 119,
+ 47, 51, 49, 51, 41, 47, 103, 103, 127, 125,
+ 54, 49, 130, 131, 119, 119, 119, 103, 47, 125,
+ 49, 47, 51, 125, 119, 51, 119, 49
+};
+
+#define yyerrok (yyerrstatus = 0)
+#define yyclearin (yychar = YYEMPTY)
+#define YYEMPTY (-2)
+#define YYEOF 0
+
+#define YYACCEPT goto yyacceptlab
+#define YYABORT goto yyabortlab
+#define YYERROR goto yyerrorlab
+
+
+/* Like YYERROR except do call yyerror. This remains here temporarily
+ to ease the transition to the new meaning of YYERROR, for GCC.
+ Once GCC version 2 has supplanted version 1, this can go. */
+
+#define YYFAIL goto yyerrlab
+
+#define YYRECOVERING() (!!yyerrstatus)
+
+#define YYBACKUP(Token, Value) \
+do \
+ if (yychar == YYEMPTY && yylen == 1) \
+ { \
+ yychar = (Token); \
+ yylval = (Value); \
+ yytoken = YYTRANSLATE (yychar); \
+ YYPOPSTACK (1); \
+ goto yybackup; \
+ } \
+ else \
+ { \
+ yyerror (YY_("syntax error: cannot back up")); \
+ YYERROR; \
+ } \
+while (YYID (0))
+
+
+#define YYTERROR 1
+#define YYERRCODE 256
+
+
+/* YYLLOC_DEFAULT -- Set CURRENT to span from RHS[1] to RHS[N].
+ If N is 0, then set CURRENT to the empty location which ends
+ the previous symbol: RHS[0] (always defined). */
+
+#define YYRHSLOC(Rhs, K) ((Rhs)[K])
+#ifndef YYLLOC_DEFAULT
+# define YYLLOC_DEFAULT(Current, Rhs, N) \
+ do \
+ if (YYID (N)) \
+ { \
+ (Current).first_line = YYRHSLOC (Rhs, 1).first_line; \
+ (Current).first_column = YYRHSLOC (Rhs, 1).first_column; \
+ (Current).last_line = YYRHSLOC (Rhs, N).last_line; \
+ (Current).last_column = YYRHSLOC (Rhs, N).last_column; \
+ } \
+ else \
+ { \
+ (Current).first_line = (Current).last_line = \
+ YYRHSLOC (Rhs, 0).last_line; \
+ (Current).first_column = (Current).last_column = \
+ YYRHSLOC (Rhs, 0).last_column; \
+ } \
+ while (YYID (0))
+#endif
+
+
+/* YY_LOCATION_PRINT -- Print the location on the stream.
+ This macro was not mandated originally: define only if we know
+ we won't break user code: when these are the locations we know. */
+
+#ifndef YY_LOCATION_PRINT
+# if YYLTYPE_IS_TRIVIAL
+# define YY_LOCATION_PRINT(File, Loc) \
+ fprintf (File, "%d.%d-%d.%d", \
+ (Loc).first_line, (Loc).first_column, \
+ (Loc).last_line, (Loc).last_column)
+# else
+# define YY_LOCATION_PRINT(File, Loc) ((void) 0)
+# endif
+#endif
+
+
+/* YYLEX -- calling `yylex' with the right arguments. */
+
+#ifdef YYLEX_PARAM
+# define YYLEX yylex (YYLEX_PARAM)
+#else
+# define YYLEX yylex ()
+#endif
+
+/* Enable debugging if requested. */
+#if YYDEBUG
+
+# ifndef YYFPRINTF
+# include <stdio.h> /* INFRINGES ON USER NAME SPACE */
+# define YYFPRINTF fprintf
+# endif
+
+# define YYDPRINTF(Args) \
+do { \
+ if (yydebug) \
+ YYFPRINTF Args; \
+} while (YYID (0))
+
+# define YY_SYMBOL_PRINT(Title, Type, Value, Location) \
+do { \
+ if (yydebug) \
+ { \
+ YYFPRINTF (stderr, "%s ", Title); \
+ yy_symbol_print (stderr, \
+ Type, Value); \
+ YYFPRINTF (stderr, "\n"); \
+ } \
+} while (YYID (0))
+
+
+/*--------------------------------.
+| Print this symbol on YYOUTPUT. |
+`--------------------------------*/
+
+/*ARGSUSED*/
+#if (defined __STDC__ || defined __C99__FUNC__ \
+ || defined __cplusplus || defined _MSC_VER)
+static void
+yy_symbol_value_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep)
+#else
+static void
+yy_symbol_value_print (yyoutput, yytype, yyvaluep)
+ FILE *yyoutput;
+ int yytype;
+ YYSTYPE const * const yyvaluep;
+#endif
+{
+ if (!yyvaluep)
+ return;
+# ifdef YYPRINT
+ if (yytype < YYNTOKENS)
+ YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep);
+# else
+ YYUSE (yyoutput);
+# endif
+ switch (yytype)
+ {
+ default:
+ break;
+ }
+}
+
+
+/*--------------------------------.
+| Print this symbol on YYOUTPUT. |
+`--------------------------------*/
+
+#if (defined __STDC__ || defined __C99__FUNC__ \
+ || defined __cplusplus || defined _MSC_VER)
+static void
+yy_symbol_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep)
+#else
+static void
+yy_symbol_print (yyoutput, yytype, yyvaluep)
+ FILE *yyoutput;
+ int yytype;
+ YYSTYPE const * const yyvaluep;
+#endif
+{
+ if (yytype < YYNTOKENS)
+ YYFPRINTF (yyoutput, "token %s (", yytname[yytype]);
+ else
+ YYFPRINTF (yyoutput, "nterm %s (", yytname[yytype]);
+
+ yy_symbol_value_print (yyoutput, yytype, yyvaluep);
+ YYFPRINTF (yyoutput, ")");
+}
+
+/*------------------------------------------------------------------.
+| yy_stack_print -- Print the state stack from its BOTTOM up to its |
+| TOP (included). |
+`------------------------------------------------------------------*/
+
+#if (defined __STDC__ || defined __C99__FUNC__ \
+ || defined __cplusplus || defined _MSC_VER)
+static void
+yy_stack_print (yytype_int16 *bottom, yytype_int16 *top)
+#else
+static void
+yy_stack_print (bottom, top)
+ yytype_int16 *bottom;
+ yytype_int16 *top;
+#endif
+{
+ YYFPRINTF (stderr, "Stack now");
+ for (; bottom <= top; ++bottom)
+ YYFPRINTF (stderr, " %d", *bottom);
+ YYFPRINTF (stderr, "\n");
+}
+
+# define YY_STACK_PRINT(Bottom, Top) \
+do { \
+ if (yydebug) \
+ yy_stack_print ((Bottom), (Top)); \
+} while (YYID (0))
+
+
+/*------------------------------------------------.
+| Report that the YYRULE is going to be reduced. |
+`------------------------------------------------*/
+
+#if (defined __STDC__ || defined __C99__FUNC__ \
+ || defined __cplusplus || defined _MSC_VER)
+static void
+yy_reduce_print (YYSTYPE *yyvsp, int yyrule)
+#else
+static void
+yy_reduce_print (yyvsp, yyrule)
+ YYSTYPE *yyvsp;
+ int yyrule;
+#endif
+{
+ int yynrhs = yyr2[yyrule];
+ int yyi;
+ unsigned long int yylno = yyrline[yyrule];
+ YYFPRINTF (stderr, "Reducing stack by rule %d (line %lu):\n",
+ yyrule - 1, yylno);
+ /* The symbols being reduced. */
+ for (yyi = 0; yyi < yynrhs; yyi++)
+ {
+ fprintf (stderr, " $%d = ", yyi + 1);
+ yy_symbol_print (stderr, yyrhs[yyprhs[yyrule] + yyi],
+ &(yyvsp[(yyi + 1) - (yynrhs)])
+ );
+ fprintf (stderr, "\n");
+ }
+}
+
+# define YY_REDUCE_PRINT(Rule) \
+do { \
+ if (yydebug) \
+ yy_reduce_print (yyvsp, Rule); \
+} while (YYID (0))
+
+/* Nonzero means print parse trace. It is left uninitialized so that
+ multiple parsers can coexist. */
+int yydebug;
+#else /* !YYDEBUG */
+# define YYDPRINTF(Args)
+# define YY_SYMBOL_PRINT(Title, Type, Value, Location)
+# define YY_STACK_PRINT(Bottom, Top)
+# define YY_REDUCE_PRINT(Rule)
+#endif /* !YYDEBUG */
+
+
+/* YYINITDEPTH -- initial size of the parser's stacks. */
+#ifndef YYINITDEPTH
+# define YYINITDEPTH 200
+#endif
+
+/* YYMAXDEPTH -- maximum size the stacks can grow to (effective only
+ if the built-in stack extension method is used).
+
+ Do not make this value too large; the results are undefined if
+ YYSTACK_ALLOC_MAXIMUM < YYSTACK_BYTES (YYMAXDEPTH)
+ evaluated with infinite-precision integer arithmetic. */
+
+#ifndef YYMAXDEPTH
+# define YYMAXDEPTH 10000
+#endif
+
+
+
+#if YYERROR_VERBOSE
+
+# ifndef yystrlen
+# if defined __GLIBC__ && defined _STRING_H
+# define yystrlen strlen
+# else
+/* Return the length of YYSTR. */
+#if (defined __STDC__ || defined __C99__FUNC__ \
+ || defined __cplusplus || defined _MSC_VER)
+static YYSIZE_T
+yystrlen (const char *yystr)
+#else
+static YYSIZE_T
+yystrlen (yystr)
+ const char *yystr;
+#endif
+{
+ YYSIZE_T yylen;
+ for (yylen = 0; yystr[yylen]; yylen++)
+ continue;
+ return yylen;
+}
+# endif
+# endif
+
+# ifndef yystpcpy
+# if defined __GLIBC__ && defined _STRING_H && defined _GNU_SOURCE
+# define yystpcpy stpcpy
+# else
+/* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in
+ YYDEST. */
+#if (defined __STDC__ || defined __C99__FUNC__ \
+ || defined __cplusplus || defined _MSC_VER)
+static char *
+yystpcpy (char *yydest, const char *yysrc)
+#else
+static char *
+yystpcpy (yydest, yysrc)
+ char *yydest;
+ const char *yysrc;
+#endif
+{
+ char *yyd = yydest;
+ const char *yys = yysrc;
+
+ while ((*yyd++ = *yys++) != '\0')
+ continue;
+
+ return yyd - 1;
+}
+# endif
+# endif
+
+# ifndef yytnamerr
+/* Copy to YYRES the contents of YYSTR after stripping away unnecessary
+ quotes and backslashes, so that it's suitable for yyerror. The
+ heuristic is that double-quoting is unnecessary unless the string
+ contains an apostrophe, a comma, or backslash (other than
+ backslash-backslash). YYSTR is taken from yytname. If YYRES is
+ null, do not copy; instead, return the length of what the result
+ would have been. */
+static YYSIZE_T
+yytnamerr (char *yyres, const char *yystr)
+{
+ if (*yystr == '"')
+ {
+ YYSIZE_T yyn = 0;
+ char const *yyp = yystr;
+
+ for (;;)
+ switch (*++yyp)
+ {
+ case '\'':
+ case ',':
+ goto do_not_strip_quotes;
+
+ case '\\':
+ if (*++yyp != '\\')
+ goto do_not_strip_quotes;
+ /* Fall through. */
+ default:
+ if (yyres)
+ yyres[yyn] = *yyp;
+ yyn++;
+ break;
+
+ case '"':
+ if (yyres)
+ yyres[yyn] = '\0';
+ return yyn;
+ }
+ do_not_strip_quotes: ;
+ }
+
+ if (! yyres)
+ return yystrlen (yystr);
+
+ return yystpcpy (yyres, yystr) - yyres;
+}
+# endif
+
+/* Copy into YYRESULT an error message about the unexpected token
+ YYCHAR while in state YYSTATE. Return the number of bytes copied,
+ including the terminating null byte. If YYRESULT is null, do not
+ copy anything; just return the number of bytes that would be
+ copied. As a special case, return 0 if an ordinary "syntax error"
+ message will do. Return YYSIZE_MAXIMUM if overflow occurs during
+ size calculation. */
+static YYSIZE_T
+yysyntax_error (char *yyresult, int yystate, int yychar)
+{
+ int yyn = yypact[yystate];
+
+ if (! (YYPACT_NINF < yyn && yyn <= YYLAST))
+ return 0;
+ else
+ {
+ int yytype = YYTRANSLATE (yychar);
+ YYSIZE_T yysize0 = yytnamerr (0, yytname[yytype]);
+ YYSIZE_T yysize = yysize0;
+ YYSIZE_T yysize1;
+ int yysize_overflow = 0;
+ enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 };
+ char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM];
+ int yyx;
+
+# if 0
+ /* This is so xgettext sees the translatable formats that are
+ constructed on the fly. */
+ YY_("syntax error, unexpected %s");
+ YY_("syntax error, unexpected %s, expecting %s");
+ YY_("syntax error, unexpected %s, expecting %s or %s");
+ YY_("syntax error, unexpected %s, expecting %s or %s or %s");
+ YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s");
+# endif
+ char *yyfmt;
+ char const *yyf;
+ static char const yyunexpected[] = "syntax error, unexpected %s";
+ static char const yyexpecting[] = ", expecting %s";
+ static char const yyor[] = " or %s";
+ char yyformat[sizeof yyunexpected
+ + sizeof yyexpecting - 1
+ + ((YYERROR_VERBOSE_ARGS_MAXIMUM - 2)
+ * (sizeof yyor - 1))];
+ char const *yyprefix = yyexpecting;
+
+ /* Start YYX at -YYN if negative to avoid negative indexes in
+ YYCHECK. */
+ int yyxbegin = yyn < 0 ? -yyn : 0;
+
+ /* Stay within bounds of both yycheck and yytname. */
+ int yychecklim = YYLAST - yyn + 1;
+ int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS;
+ int yycount = 1;
+
+ yyarg[0] = yytname[yytype];
+ yyfmt = yystpcpy (yyformat, yyunexpected);
+
+ for (yyx = yyxbegin; yyx < yyxend; ++yyx)
+ if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR)
+ {
+ if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM)
+ {
+ yycount = 1;
+ yysize = yysize0;
+ yyformat[sizeof yyunexpected - 1] = '\0';
+ break;
+ }
+ yyarg[yycount++] = yytname[yyx];
+ yysize1 = yysize + yytnamerr (0, yytname[yyx]);
+ yysize_overflow |= (yysize1 < yysize);
+ yysize = yysize1;
+ yyfmt = yystpcpy (yyfmt, yyprefix);
+ yyprefix = yyor;
+ }
+
+ yyf = YY_(yyformat);
+ yysize1 = yysize + yystrlen (yyf);
+ yysize_overflow |= (yysize1 < yysize);
+ yysize = yysize1;
+
+ if (yysize_overflow)
+ return YYSIZE_MAXIMUM;
+
+ if (yyresult)
+ {
+ /* Avoid sprintf, as that infringes on the user's name space.
+ Don't have undefined behavior even if the translation
+ produced a string with the wrong number of "%s"s. */
+ char *yyp = yyresult;
+ int yyi = 0;
+ while ((*yyp = *yyf) != '\0')
+ {
+ if (*yyp == '%' && yyf[1] == 's' && yyi < yycount)
+ {
+ yyp += yytnamerr (yyp, yyarg[yyi++]);
+ yyf += 2;
+ }
+ else
+ {
+ yyp++;
+ yyf++;
+ }
+ }
+ }
+ return yysize;
+ }
+}
+#endif /* YYERROR_VERBOSE */
+
+
+/*-----------------------------------------------.
+| Release the memory associated to this symbol. |
+`-----------------------------------------------*/
+
+/*ARGSUSED*/
+#if (defined __STDC__ || defined __C99__FUNC__ \
+ || defined __cplusplus || defined _MSC_VER)
+static void
+yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep)
+#else
+static void
+yydestruct (yymsg, yytype, yyvaluep)
+ const char *yymsg;
+ int yytype;
+ YYSTYPE *yyvaluep;
+#endif
+{
+ YYUSE (yyvaluep);
+
+ if (!yymsg)
+ yymsg = "Deleting";
+ YY_SYMBOL_PRINT (yymsg, yytype, yyvaluep, yylocationp);
+
+ switch (yytype)
+ {
+
+ default:
+ break;
+ }
+}
+
+
+/* Prevent warnings from -Wmissing-prototypes. */
+
+#ifdef YYPARSE_PARAM
+#if defined __STDC__ || defined __cplusplus
+int yyparse (void *YYPARSE_PARAM);
+#else
+int yyparse ();
+#endif
+#else /* ! YYPARSE_PARAM */
+#if defined __STDC__ || defined __cplusplus
+int yyparse (void);
+#else
+int yyparse ();
+#endif
+#endif /* ! YYPARSE_PARAM */
+
+
+
+/* The look-ahead symbol. */
+int yychar;
+
+/* The semantic value of the look-ahead symbol. */
+YYSTYPE yylval;
+
+/* Number of syntax errors so far. */
+int yynerrs;
+
+
+
+/*----------.
+| yyparse. |
+`----------*/
+
+#ifdef YYPARSE_PARAM
+#if (defined __STDC__ || defined __C99__FUNC__ \
+ || defined __cplusplus || defined _MSC_VER)
+int
+yyparse (void *YYPARSE_PARAM)
+#else
+int
+yyparse (YYPARSE_PARAM)
+ void *YYPARSE_PARAM;
+#endif
+#else /* ! YYPARSE_PARAM */
+#if (defined __STDC__ || defined __C99__FUNC__ \
+ || defined __cplusplus || defined _MSC_VER)
+int
+yyparse (void)
+#else
+int
+yyparse ()
+
+#endif
+#endif
+{
+
+ int yystate;
+ int yyn;
+ int yyresult;
+ /* Number of tokens to shift before error messages enabled. */
+ int yyerrstatus;
+ /* Look-ahead token as an internal (translated) token number. */
+ int yytoken = 0;
+#if YYERROR_VERBOSE
+ /* Buffer for error messages, and its allocated size. */
+ char yymsgbuf[128];
+ char *yymsg = yymsgbuf;
+ YYSIZE_T yymsg_alloc = sizeof yymsgbuf;
+#endif
+
+ /* Three stacks and their tools:
+ `yyss': related to states,
+ `yyvs': related to semantic values,
+ `yyls': related to locations.
+
+ Refer to the stacks thru separate pointers, to allow yyoverflow
+ to reallocate them elsewhere. */
+
+ /* The state stack. */
+ yytype_int16 yyssa[YYINITDEPTH];
+ yytype_int16 *yyss = yyssa;
+ yytype_int16 *yyssp;
+
+ /* The semantic value stack. */
+ YYSTYPE yyvsa[YYINITDEPTH];
+ YYSTYPE *yyvs = yyvsa;
+ YYSTYPE *yyvsp;
+
+
+
+#define YYPOPSTACK(N) (yyvsp -= (N), yyssp -= (N))
+
+ YYSIZE_T yystacksize = YYINITDEPTH;
+
+ /* The variables used to return semantic value and location from the
+ action routines. */
+ YYSTYPE yyval;
+
+
+ /* The number of symbols on the RHS of the reduced rule.
+ Keep to zero when no symbol should be popped. */
+ int yylen = 0;
+
+ YYDPRINTF ((stderr, "Starting parse\n"));
+
+ yystate = 0;
+ yyerrstatus = 0;
+ yynerrs = 0;
+ yychar = YYEMPTY; /* Cause a token to be read. */
+
+ /* Initialize stack pointers.
+ Waste one element of value and location stack
+ so that they stay on the same level as the state stack.
+ The wasted elements are never initialized. */
+
+ yyssp = yyss;
+ yyvsp = yyvs;
+
+ goto yysetstate;
+
+/*------------------------------------------------------------.
+| yynewstate -- Push a new state, which is found in yystate. |
+`------------------------------------------------------------*/
+ yynewstate:
+ /* In all cases, when you get here, the value and location stacks
+ have just been pushed. So pushing a state here evens the stacks. */
+ yyssp++;
+
+ yysetstate:
+ *yyssp = yystate;
+
+ if (yyss + yystacksize - 1 <= yyssp)
+ {
+ /* Get the current used size of the three stacks, in elements. */
+ YYSIZE_T yysize = yyssp - yyss + 1;
+
+#ifdef yyoverflow
+ {
+ /* Give user a chance to reallocate the stack. Use copies of
+ these so that the &'s don't force the real ones into
+ memory. */
+ YYSTYPE *yyvs1 = yyvs;
+ yytype_int16 *yyss1 = yyss;
+
+
+ /* Each stack pointer address is followed by the size of the
+ data in use in that stack, in bytes. This used to be a
+ conditional around just the two extra args, but that might
+ be undefined if yyoverflow is a macro. */
+ yyoverflow (YY_("memory exhausted"),
+ &yyss1, yysize * sizeof (*yyssp),
+ &yyvs1, yysize * sizeof (*yyvsp),
+
+ &yystacksize);
+
+ yyss = yyss1;
+ yyvs = yyvs1;
+ }
+#else /* no yyoverflow */
+# ifndef YYSTACK_RELOCATE
+ goto yyexhaustedlab;
+# else
+ /* Extend the stack our own way. */
+ if (YYMAXDEPTH <= yystacksize)
+ goto yyexhaustedlab;
+ yystacksize *= 2;
+ if (YYMAXDEPTH < yystacksize)
+ yystacksize = YYMAXDEPTH;
+
+ {
+ yytype_int16 *yyss1 = yyss;
+ union yyalloc *yyptr =
+ (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize));
+ if (! yyptr)
+ goto yyexhaustedlab;
+ YYSTACK_RELOCATE (yyss);
+ YYSTACK_RELOCATE (yyvs);
+
+# undef YYSTACK_RELOCATE
+ if (yyss1 != yyssa)
+ YYSTACK_FREE (yyss1);
+ }
+# endif
+#endif /* no yyoverflow */
+
+ yyssp = yyss + yysize - 1;
+ yyvsp = yyvs + yysize - 1;
+
+
+ YYDPRINTF ((stderr, "Stack size increased to %lu\n",
+ (unsigned long int) yystacksize));
+
+ if (yyss + yystacksize - 1 <= yyssp)
+ YYABORT;
+ }
+
+ YYDPRINTF ((stderr, "Entering state %d\n", yystate));
+
+ goto yybackup;
+
+/*-----------.
+| yybackup. |
+`-----------*/
+yybackup:
+
+ /* Do appropriate processing given the current state. Read a
+ look-ahead token if we need one and don't already have one. */
+
+ /* First try to decide what to do without reference to look-ahead token. */
+ yyn = yypact[yystate];
+ if (yyn == YYPACT_NINF)
+ goto yydefault;
+
+ /* Not known => get a look-ahead token if don't already have one. */
+
+ /* YYCHAR is either YYEMPTY or YYEOF or a valid look-ahead symbol. */
+ if (yychar == YYEMPTY)
+ {
+ YYDPRINTF ((stderr, "Reading a token: "));
+ yychar = YYLEX;
+ }
+
+ if (yychar <= YYEOF)
+ {
+ yychar = yytoken = YYEOF;
+ YYDPRINTF ((stderr, "Now at end of input.\n"));
+ }
+ else
+ {
+ yytoken = YYTRANSLATE (yychar);
+ YY_SYMBOL_PRINT ("Next token is", yytoken, &yylval, &yylloc);
+ }
+
+ /* If the proper action on seeing token YYTOKEN is to reduce or to
+ detect an error, take that action. */
+ yyn += yytoken;
+ if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken)
+ goto yydefault;
+ yyn = yytable[yyn];
+ if (yyn <= 0)
+ {
+ if (yyn == 0 || yyn == YYTABLE_NINF)
+ goto yyerrlab;
+ yyn = -yyn;
+ goto yyreduce;
+ }
+
+ if (yyn == YYFINAL)
+ YYACCEPT;
+
+ /* Count tokens shifted since error; after three, turn off error
+ status. */
+ if (yyerrstatus)
+ yyerrstatus--;
+
+ /* Shift the look-ahead token. */
+ YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc);
+
+ /* Discard the shifted token unless it is eof. */
+ if (yychar != YYEOF)
+ yychar = YYEMPTY;
+
+ yystate = yyn;
+ *++yyvsp = yylval;
+
+ goto yynewstate;
+
+
+/*-----------------------------------------------------------.
+| yydefault -- do the default action for the current state. |
+`-----------------------------------------------------------*/
+yydefault:
+ yyn = yydefact[yystate];
+ if (yyn == 0)
+ goto yyerrlab;
+ goto yyreduce;
+
+
+/*-----------------------------.
+| yyreduce -- Do a reduction. |
+`-----------------------------*/
+yyreduce:
+ /* yyn is the number of a rule to reduce with. */
+ yylen = yyr2[yyn];
+
+ /* If YYLEN is nonzero, implement the default value of the action:
+ `$$ = $1'.
+
+ Otherwise, the following line sets YYVAL to garbage.
+ This behavior is undocumented and Bison
+ users should not rely upon it. Assigning to YYVAL
+ unconditionally makes the parser a bit smaller, and it avoids a
+ GCC warning that YYVAL may be used uninitialized. */
+ yyval = yyvsp[1-yylen];
+
+
+ YY_REDUCE_PRINT (yyn);
+ switch (yyn)
+ {
+ case 2:
+#line 177 "camp.y"
+ { absyntax::root = (yyvsp[(1) - (1)].b); ;}
+ break;
+
+ case 3:
+#line 181 "camp.y"
+ { (yyval.b) = new file(lexerPos(), false); ;}
+ break;
+
+ case 4:
+#line 183 "camp.y"
+ { (yyval.b) = (yyvsp[(1) - (2)].b); (yyval.b)->add((yyvsp[(2) - (2)].run)); ;}
+ break;
+
+ case 5:
+#line 187 "camp.y"
+ { (yyval.b) = new block(lexerPos(), true); ;}
+ break;
+
+ case 6:
+#line 189 "camp.y"
+ { (yyval.b) = (yyvsp[(1) - (2)].b); (yyval.b)->add((yyvsp[(2) - (2)].run)); ;}
+ break;
+
+ case 7:
+#line 193 "camp.y"
+ { (yyval.n) = new simpleName((yyvsp[(1) - (1)].ps).pos, (yyvsp[(1) - (1)].ps).sym); ;}
+ break;
+
+ case 8:
+#line 194 "camp.y"
+ { (yyval.n) = new qualifiedName((yyvsp[(2) - (3)].pos), (yyvsp[(1) - (3)].n), (yyvsp[(3) - (3)].ps).sym); ;}
+ break;
+
+ case 9:
+#line 198 "camp.y"
+ { (yyval.run) = (yyvsp[(1) - (1)].d); ;}
+ break;
+
+ case 10:
+#line 199 "camp.y"
+ { (yyval.run) = (yyvsp[(1) - (1)].s); ;}
+ break;
+
+ case 11:
+#line 201 "camp.y"
+ { (yyval.run) = new modifiedRunnable((yyvsp[(1) - (2)].ml)->getPos(), (yyvsp[(1) - (2)].ml), (yyvsp[(2) - (2)].d)); ;}
+ break;
+
+ case 12:
+#line 203 "camp.y"
+ { (yyval.run) = new modifiedRunnable((yyvsp[(1) - (2)].ml)->getPos(), (yyvsp[(1) - (2)].ml), (yyvsp[(2) - (2)].s)); ;}
+ break;
+
+ case 13:
+#line 207 "camp.y"
+ { (yyval.ml) = new modifierList((yyvsp[(1) - (1)].mod).pos); (yyval.ml)->add((yyvsp[(1) - (1)].mod).val); ;}
+ break;
+
+ case 14:
+#line 208 "camp.y"
+ { (yyval.ml) = new modifierList((yyvsp[(1) - (1)].perm).pos); (yyval.ml)->add((yyvsp[(1) - (1)].perm).val); ;}
+ break;
+
+ case 15:
+#line 210 "camp.y"
+ { (yyval.ml) = (yyvsp[(1) - (2)].ml); (yyval.ml)->add((yyvsp[(2) - (2)].mod).val); ;}
+ break;
+
+ case 16:
+#line 212 "camp.y"
+ { (yyval.ml) = (yyvsp[(1) - (2)].ml); (yyval.ml)->add((yyvsp[(2) - (2)].perm).val); ;}
+ break;
+
+ case 17:
+#line 216 "camp.y"
+ { (yyval.d) = (yyvsp[(1) - (1)].vd); ;}
+ break;
+
+ case 18:
+#line 217 "camp.y"
+ { (yyval.d) = (yyvsp[(1) - (1)].d); ;}
+ break;
+
+ case 19:
+#line 218 "camp.y"
+ { (yyval.d) = (yyvsp[(1) - (1)].d); ;}
+ break;
+
+ case 20:
+#line 220 "camp.y"
+ { (yyval.d) = new accessdec((yyvsp[(1) - (3)].pos), (yyvsp[(2) - (3)].ipl)); ;}
+ break;
+
+ case 21:
+#line 222 "camp.y"
+ { (yyval.d) = new unraveldec((yyvsp[(1) - (5)].pos), (yyvsp[(2) - (5)].n), (yyvsp[(4) - (5)].ipl)); ;}
+ break;
+
+ case 22:
+#line 224 "camp.y"
+ { (yyval.d) = new unraveldec((yyvsp[(1) - (5)].pos), (yyvsp[(2) - (5)].n), WILDCARD); ;}
+ break;
+
+ case 23:
+#line 225 "camp.y"
+ { (yyval.d) = new unraveldec((yyvsp[(1) - (3)].pos), (yyvsp[(2) - (3)].n), WILDCARD); ;}
+ break;
+
+ case 24:
+#line 227 "camp.y"
+ { (yyval.d) = new fromaccessdec((yyvsp[(1) - (5)].pos), (yyvsp[(2) - (5)].ps).sym, (yyvsp[(4) - (5)].ipl)); ;}
+ break;
+
+ case 25:
+#line 229 "camp.y"
+ { (yyval.d) = new fromaccessdec((yyvsp[(1) - (5)].pos), (yyvsp[(2) - (5)].ps).sym, WILDCARD); ;}
+ break;
+
+ case 26:
+#line 231 "camp.y"
+ { (yyval.d) = new importdec((yyvsp[(1) - (3)].pos), (yyvsp[(2) - (3)].ip)); ;}
+ break;
+
+ case 27:
+#line 232 "camp.y"
+ { (yyval.d) = new includedec((yyvsp[(1) - (3)].pos), (yyvsp[(2) - (3)].ps).sym); ;}
+ break;
+
+ case 28:
+#line 234 "camp.y"
+ { (yyval.d) = new includedec((yyvsp[(1) - (3)].pos), (string)*(yyvsp[(2) - (3)].ps).sym); ;}
+ break;
+
+ case 29:
+#line 238 "camp.y"
+ { (yyval.ip) = new idpair((yyvsp[(1) - (1)].ps).pos, (yyvsp[(1) - (1)].ps).sym); ;}
+ break;
+
+ case 30:
+#line 240 "camp.y"
+ { (yyval.ip) = new idpair((yyvsp[(1) - (3)].ps).pos, (yyvsp[(1) - (3)].ps).sym, (yyvsp[(2) - (3)].ps).sym , (yyvsp[(3) - (3)].ps).sym); ;}
+ break;
+
+ case 31:
+#line 244 "camp.y"
+ { (yyval.ipl) = new idpairlist(); (yyval.ipl)->add((yyvsp[(1) - (1)].ip)); ;}
+ break;
+
+ case 32:
+#line 246 "camp.y"
+ { (yyval.ipl) = (yyvsp[(1) - (3)].ipl); (yyval.ipl)->add((yyvsp[(3) - (3)].ip)); ;}
+ break;
+
+ case 33:
+#line 250 "camp.y"
+ { (yyval.ps) = (yyvsp[(1) - (1)].ps); ;}
+ break;
+
+ case 34:
+#line 251 "camp.y"
+ { (yyval.ps) = (yyvsp[(1) - (1)].ps); ;}
+ break;
+
+ case 35:
+#line 255 "camp.y"
+ { (yyval.ip) = new idpair((yyvsp[(1) - (1)].ps).pos, (yyvsp[(1) - (1)].ps).sym); ;}
+ break;
+
+ case 36:
+#line 257 "camp.y"
+ { (yyval.ip) = new idpair((yyvsp[(1) - (3)].ps).pos, (yyvsp[(1) - (3)].ps).sym, (yyvsp[(2) - (3)].ps).sym , (yyvsp[(3) - (3)].ps).sym); ;}
+ break;
+
+ case 37:
+#line 261 "camp.y"
+ { (yyval.ipl) = new idpairlist(); (yyval.ipl)->add((yyvsp[(1) - (1)].ip)); ;}
+ break;
+
+ case 38:
+#line 263 "camp.y"
+ { (yyval.ipl) = (yyvsp[(1) - (3)].ipl); (yyval.ipl)->add((yyvsp[(3) - (3)].ip)); ;}
+ break;
+
+ case 39:
+#line 267 "camp.y"
+ { (yyval.vd) = (yyvsp[(1) - (2)].vd); ;}
+ break;
+
+ case 40:
+#line 271 "camp.y"
+ { (yyval.vd) = new vardec((yyvsp[(1) - (2)].t)->getPos(), (yyvsp[(1) - (2)].t), (yyvsp[(2) - (2)].dil)); ;}
+ break;
+
+ case 41:
+#line 275 "camp.y"
+ { (yyval.t) = (yyvsp[(1) - (1)].t); ;}
+ break;
+
+ case 42:
+#line 276 "camp.y"
+ { (yyval.t) = new arrayTy((yyvsp[(1) - (2)].n), (yyvsp[(2) - (2)].dim)); ;}
+ break;
+
+ case 43:
+#line 280 "camp.y"
+ { (yyval.t) = new nameTy((yyvsp[(1) - (1)].n)); ;}
+ break;
+
+ case 44:
+#line 284 "camp.y"
+ { (yyval.dim) = new dimensions((yyvsp[(1) - (2)].pos)); ;}
+ break;
+
+ case 45:
+#line 285 "camp.y"
+ { (yyval.dim) = (yyvsp[(1) - (3)].dim); (yyval.dim)->increase(); ;}
+ break;
+
+ case 46:
+#line 289 "camp.y"
+ { (yyval.elist) = new explist((yyvsp[(1) - (3)].pos)); (yyval.elist)->add((yyvsp[(2) - (3)].e)); ;}
+ break;
+
+ case 47:
+#line 291 "camp.y"
+ { (yyval.elist) = (yyvsp[(1) - (4)].elist); (yyval.elist)->add((yyvsp[(3) - (4)].e)); ;}
+ break;
+
+ case 48:
+#line 295 "camp.y"
+ { (yyval.dil) = new decidlist((yyvsp[(1) - (1)].di)->getPos()); (yyval.dil)->add((yyvsp[(1) - (1)].di)); ;}
+ break;
+
+ case 49:
+#line 297 "camp.y"
+ { (yyval.dil) = (yyvsp[(1) - (3)].dil); (yyval.dil)->add((yyvsp[(3) - (3)].di)); ;}
+ break;
+
+ case 50:
+#line 301 "camp.y"
+ { (yyval.di) = new decid((yyvsp[(1) - (1)].dis)->getPos(), (yyvsp[(1) - (1)].dis)); ;}
+ break;
+
+ case 51:
+#line 303 "camp.y"
+ { (yyval.di) = new decid((yyvsp[(1) - (3)].dis)->getPos(), (yyvsp[(1) - (3)].dis), (yyvsp[(3) - (3)].vi)); ;}
+ break;
+
+ case 52:
+#line 307 "camp.y"
+ { (yyval.dis) = new decidstart((yyvsp[(1) - (1)].ps).pos, (yyvsp[(1) - (1)].ps).sym); ;}
+ break;
+
+ case 53:
+#line 308 "camp.y"
+ { (yyval.dis) = new decidstart((yyvsp[(1) - (2)].ps).pos, (yyvsp[(1) - (2)].ps).sym, (yyvsp[(2) - (2)].dim)); ;}
+ break;
+
+ case 54:
+#line 309 "camp.y"
+ { (yyval.dis) = new fundecidstart((yyvsp[(1) - (3)].ps).pos, (yyvsp[(1) - (3)].ps).sym, 0,
+ new formals((yyvsp[(2) - (3)].pos))); ;}
+ break;
+
+ case 55:
+#line 312 "camp.y"
+ { (yyval.dis) = new fundecidstart((yyvsp[(1) - (4)].ps).pos, (yyvsp[(1) - (4)].ps).sym, 0, (yyvsp[(3) - (4)].fls)); ;}
+ break;
+
+ case 56:
+#line 316 "camp.y"
+ { (yyval.vi) = (yyvsp[(1) - (1)].e); ;}
+ break;
+
+ case 57:
+#line 317 "camp.y"
+ { (yyval.vi) = (yyvsp[(1) - (1)].ai); ;}
+ break;
+
+ case 58:
+#line 322 "camp.y"
+ { (yyval.b) = (yyvsp[(2) - (3)].b); ;}
+ break;
+
+ case 59:
+#line 326 "camp.y"
+ { (yyval.ai) = new arrayinit((yyvsp[(1) - (2)].pos)); ;}
+ break;
+
+ case 60:
+#line 328 "camp.y"
+ { (yyval.ai) = new arrayinit((yyvsp[(1) - (4)].pos)); (yyval.ai)->addRest((yyvsp[(3) - (4)].vi)); ;}
+ break;
+
+ case 61:
+#line 330 "camp.y"
+ { (yyval.ai) = (yyvsp[(2) - (3)].ai); ;}
+ break;
+
+ case 62:
+#line 332 "camp.y"
+ { (yyval.ai) = (yyvsp[(2) - (5)].ai); (yyval.ai)->addRest((yyvsp[(4) - (5)].vi)); ;}
+ break;
+
+ case 63:
+#line 336 "camp.y"
+ { (yyval.ai) = new arrayinit((yyvsp[(1) - (1)].pos)); ;}
+ break;
+
+ case 64:
+#line 337 "camp.y"
+ { (yyval.ai) = (yyvsp[(1) - (1)].ai); ;}
+ break;
+
+ case 65:
+#line 338 "camp.y"
+ { (yyval.ai) = (yyvsp[(1) - (2)].ai); ;}
+ break;
+
+ case 66:
+#line 342 "camp.y"
+ { (yyval.ai) = new arrayinit((yyvsp[(1) - (1)].vi)->getPos());
+ (yyval.ai)->add((yyvsp[(1) - (1)].vi));;}
+ break;
+
+ case 67:
+#line 345 "camp.y"
+ { (yyval.ai) = (yyvsp[(1) - (3)].ai); (yyval.ai)->add((yyvsp[(3) - (3)].vi)); ;}
+ break;
+
+ case 68:
+#line 349 "camp.y"
+ { (yyval.fls) = (yyvsp[(1) - (1)].fls); ;}
+ break;
+
+ case 69:
+#line 351 "camp.y"
+ { (yyval.fls) = (yyvsp[(1) - (3)].fls); (yyval.fls)->addRest((yyvsp[(3) - (3)].fl)); ;}
+ break;
+
+ case 70:
+#line 352 "camp.y"
+ { (yyval.fls) = new formals((yyvsp[(1) - (2)].pos)); (yyval.fls)->addRest((yyvsp[(2) - (2)].fl)); ;}
+ break;
+
+ case 71:
+#line 356 "camp.y"
+ { (yyval.fls) = new formals((yyvsp[(1) - (1)].fl)->getPos()); (yyval.fls)->add((yyvsp[(1) - (1)].fl)); ;}
+ break;
+
+ case 72:
+#line 358 "camp.y"
+ { (yyval.fls) = (yyvsp[(1) - (3)].fls); (yyval.fls)->add((yyvsp[(3) - (3)].fl)); ;}
+ break;
+
+ case 73:
+#line 362 "camp.y"
+ { (yyval.boo) = true; ;}
+ break;
+
+ case 74:
+#line 363 "camp.y"
+ { (yyval.boo) = false; ;}
+ break;
+
+ case 75:
+#line 368 "camp.y"
+ { (yyval.fl) = new formal((yyvsp[(2) - (2)].t)->getPos(), (yyvsp[(2) - (2)].t), 0, 0, (yyvsp[(1) - (2)].boo)); ;}
+ break;
+
+ case 76:
+#line 370 "camp.y"
+ { (yyval.fl) = new formal((yyvsp[(2) - (3)].t)->getPos(), (yyvsp[(2) - (3)].t), (yyvsp[(3) - (3)].dis), 0, (yyvsp[(1) - (3)].boo)); ;}
+ break;
+
+ case 77:
+#line 372 "camp.y"
+ { (yyval.fl) = new formal((yyvsp[(2) - (5)].t)->getPos(), (yyvsp[(2) - (5)].t), (yyvsp[(3) - (5)].dis), (yyvsp[(5) - (5)].vi), (yyvsp[(1) - (5)].boo)); ;}
+ break;
+
+ case 78:
+#line 377 "camp.y"
+ { (yyval.d) = new fundec((yyvsp[(3) - (5)].pos), (yyvsp[(1) - (5)].t), (yyvsp[(2) - (5)].ps).sym, new formals((yyvsp[(3) - (5)].pos)), (yyvsp[(5) - (5)].s)); ;}
+ break;
+
+ case 79:
+#line 379 "camp.y"
+ { (yyval.d) = new fundec((yyvsp[(3) - (6)].pos), (yyvsp[(1) - (6)].t), (yyvsp[(2) - (6)].ps).sym, (yyvsp[(4) - (6)].fls), (yyvsp[(6) - (6)].s)); ;}
+ break;
+
+ case 80:
+#line 383 "camp.y"
+ { (yyval.d) = new recorddec((yyvsp[(1) - (3)].pos), (yyvsp[(2) - (3)].ps).sym, (yyvsp[(3) - (3)].b)); ;}
+ break;
+
+ case 81:
+#line 384 "camp.y"
+ { (yyval.d) = new typedec((yyvsp[(1) - (2)].pos), (yyvsp[(2) - (2)].vd)); ;}
+ break;
+
+ case 82:
+#line 388 "camp.y"
+ { (yyval.slice) = new slice((yyvsp[(1) - (1)].pos), 0, 0); ;}
+ break;
+
+ case 83:
+#line 389 "camp.y"
+ { (yyval.slice) = new slice((yyvsp[(2) - (2)].pos), (yyvsp[(1) - (2)].e), 0); ;}
+ break;
+
+ case 84:
+#line 390 "camp.y"
+ { (yyval.slice) = new slice((yyvsp[(1) - (2)].pos), 0, (yyvsp[(2) - (2)].e)); ;}
+ break;
+
+ case 85:
+#line 391 "camp.y"
+ { (yyval.slice) = new slice((yyvsp[(2) - (3)].pos), (yyvsp[(1) - (3)].e), (yyvsp[(3) - (3)].e)); ;}
+ break;
+
+ case 86:
+#line 395 "camp.y"
+ { (yyval.e) = new fieldExp((yyvsp[(2) - (3)].pos), (yyvsp[(1) - (3)].e), (yyvsp[(3) - (3)].ps).sym); ;}
+ break;
+
+ case 87:
+#line 396 "camp.y"
+ { (yyval.e) = new subscriptExp((yyvsp[(2) - (4)].pos),
+ new nameExp((yyvsp[(1) - (4)].n)->getPos(), (yyvsp[(1) - (4)].n)), (yyvsp[(3) - (4)].e)); ;}
+ break;
+
+ case 88:
+#line 398 "camp.y"
+ { (yyval.e) = new subscriptExp((yyvsp[(2) - (4)].pos), (yyvsp[(1) - (4)].e), (yyvsp[(3) - (4)].e)); ;}
+ break;
+
+ case 89:
+#line 399 "camp.y"
+ { (yyval.e) = new sliceExp((yyvsp[(2) - (4)].pos),
+ new nameExp((yyvsp[(1) - (4)].n)->getPos(), (yyvsp[(1) - (4)].n)), (yyvsp[(3) - (4)].slice)); ;}
+ break;
+
+ case 90:
+#line 401 "camp.y"
+ { (yyval.e) = new sliceExp((yyvsp[(2) - (4)].pos), (yyvsp[(1) - (4)].e), (yyvsp[(3) - (4)].slice)); ;}
+ break;
+
+ case 91:
+#line 402 "camp.y"
+ { (yyval.e) = new callExp((yyvsp[(2) - (3)].pos),
+ new nameExp((yyvsp[(1) - (3)].n)->getPos(), (yyvsp[(1) - (3)].n)),
+ new arglist()); ;}
+ break;
+
+ case 92:
+#line 406 "camp.y"
+ { (yyval.e) = new callExp((yyvsp[(2) - (4)].pos),
+ new nameExp((yyvsp[(1) - (4)].n)->getPos(), (yyvsp[(1) - (4)].n)),
+ (yyvsp[(3) - (4)].alist)); ;}
+ break;
+
+ case 93:
+#line 409 "camp.y"
+ { (yyval.e) = new callExp((yyvsp[(2) - (3)].pos), (yyvsp[(1) - (3)].e), new arglist()); ;}
+ break;
+
+ case 94:
+#line 411 "camp.y"
+ { (yyval.e) = new callExp((yyvsp[(2) - (4)].pos), (yyvsp[(1) - (4)].e), (yyvsp[(3) - (4)].alist)); ;}
+ break;
+
+ case 95:
+#line 413 "camp.y"
+ { (yyval.e) = (yyvsp[(2) - (3)].e); ;}
+ break;
+
+ case 96:
+#line 415 "camp.y"
+ { (yyval.e) = new nameExp((yyvsp[(2) - (3)].n)->getPos(), (yyvsp[(2) - (3)].n)); ;}
+ break;
+
+ case 97:
+#line 416 "camp.y"
+ { (yyval.e) = new thisExp((yyvsp[(1) - (1)].pos)); ;}
+ break;
+
+ case 98:
+#line 420 "camp.y"
+ { (yyval.arg).name=0; (yyval.arg).val=(yyvsp[(1) - (1)].e); ;}
+ break;
+
+ case 99:
+#line 421 "camp.y"
+ { (yyval.arg).name=(yyvsp[(1) - (3)].ps).sym; (yyval.arg).val=(yyvsp[(3) - (3)].e); ;}
+ break;
+
+ case 100:
+#line 425 "camp.y"
+ { (yyval.alist) = (yyvsp[(1) - (1)].alist); ;}
+ break;
+
+ case 101:
+#line 427 "camp.y"
+ { (yyval.alist) = (yyvsp[(1) - (3)].alist); (yyval.alist)->rest = (yyvsp[(3) - (3)].arg); ;}
+ break;
+
+ case 102:
+#line 428 "camp.y"
+ { (yyval.alist) = new arglist(); (yyval.alist)->rest = (yyvsp[(2) - (2)].arg); ;}
+ break;
+
+ case 103:
+#line 432 "camp.y"
+ { (yyval.alist) = new arglist(); (yyval.alist)->add((yyvsp[(1) - (1)].arg)); ;}
+ break;
+
+ case 104:
+#line 434 "camp.y"
+ { (yyval.alist) = (yyvsp[(1) - (3)].alist); (yyval.alist)->add((yyvsp[(3) - (3)].arg)); ;}
+ break;
+
+ case 105:
+#line 439 "camp.y"
+ { (yyval.e) = new nameExp((yyvsp[(1) - (1)].n)->getPos(), (yyvsp[(1) - (1)].n)); ;}
+ break;
+
+ case 106:
+#line 440 "camp.y"
+ { (yyval.e) = (yyvsp[(1) - (1)].e); ;}
+ break;
+
+ case 107:
+#line 441 "camp.y"
+ { (yyval.e) = (yyvsp[(1) - (1)].e); ;}
+ break;
+
+ case 108:
+#line 442 "camp.y"
+ { (yyval.e) = new stringExp((yyvsp[(1) - (1)].ps).pos, *(yyvsp[(1) - (1)].ps).sym); ;}
+ break;
+
+ case 109:
+#line 444 "camp.y"
+ { (yyval.e) = new scaleExp((yyvsp[(1) - (2)].e)->getPos(), (yyvsp[(1) - (2)].e), (yyvsp[(2) - (2)].e)); ;}
+ break;
+
+ case 110:
+#line 446 "camp.y"
+ { (yyval.e) = new castExp((yyvsp[(2) - (4)].n)->getPos(), new nameTy((yyvsp[(2) - (4)].n)), (yyvsp[(4) - (4)].e)); ;}
+ break;
+
+ case 111:
+#line 448 "camp.y"
+ { (yyval.e) = new castExp((yyvsp[(2) - (5)].n)->getPos(), new arrayTy((yyvsp[(2) - (5)].n), (yyvsp[(3) - (5)].dim)), (yyvsp[(5) - (5)].e)); ;}
+ break;
+
+ case 112:
+#line 450 "camp.y"
+ { (yyval.e) = new unaryExp((yyvsp[(1) - (2)].ps).pos, (yyvsp[(2) - (2)].e), (yyvsp[(1) - (2)].ps).sym); ;}
+ break;
+
+ case 113:
+#line 452 "camp.y"
+ { (yyval.e) = new unaryExp((yyvsp[(1) - (2)].ps).pos, (yyvsp[(2) - (2)].e), (yyvsp[(1) - (2)].ps).sym); ;}
+ break;
+
+ case 114:
+#line 453 "camp.y"
+ { (yyval.e) = new unaryExp((yyvsp[(1) - (2)].ps).pos, (yyvsp[(2) - (2)].e), (yyvsp[(1) - (2)].ps).sym); ;}
+ break;
+
+ case 115:
+#line 454 "camp.y"
+ { (yyval.e) = new binaryExp((yyvsp[(2) - (3)].ps).pos, (yyvsp[(1) - (3)].e), (yyvsp[(2) - (3)].ps).sym, (yyvsp[(3) - (3)].e)); ;}
+ break;
+
+ case 116:
+#line 455 "camp.y"
+ { (yyval.e) = new binaryExp((yyvsp[(2) - (3)].ps).pos, (yyvsp[(1) - (3)].e), (yyvsp[(2) - (3)].ps).sym, (yyvsp[(3) - (3)].e)); ;}
+ break;
+
+ case 117:
+#line 456 "camp.y"
+ { (yyval.e) = new binaryExp((yyvsp[(2) - (3)].ps).pos, (yyvsp[(1) - (3)].e), (yyvsp[(2) - (3)].ps).sym, (yyvsp[(3) - (3)].e)); ;}
+ break;
+
+ case 118:
+#line 457 "camp.y"
+ { (yyval.e) = new binaryExp((yyvsp[(2) - (3)].ps).pos, (yyvsp[(1) - (3)].e), (yyvsp[(2) - (3)].ps).sym, (yyvsp[(3) - (3)].e)); ;}
+ break;
+
+ case 119:
+#line 458 "camp.y"
+ { (yyval.e) = new binaryExp((yyvsp[(2) - (3)].ps).pos, (yyvsp[(1) - (3)].e), (yyvsp[(2) - (3)].ps).sym, (yyvsp[(3) - (3)].e)); ;}
+ break;
+
+ case 120:
+#line 459 "camp.y"
+ { (yyval.e) = new binaryExp((yyvsp[(2) - (3)].ps).pos, (yyvsp[(1) - (3)].e), (yyvsp[(2) - (3)].ps).sym, (yyvsp[(3) - (3)].e)); ;}
+ break;
+
+ case 121:
+#line 460 "camp.y"
+ { (yyval.e) = new binaryExp((yyvsp[(2) - (3)].ps).pos, (yyvsp[(1) - (3)].e), (yyvsp[(2) - (3)].ps).sym, (yyvsp[(3) - (3)].e)); ;}
+ break;
+
+ case 122:
+#line 461 "camp.y"
+ { (yyval.e) = new binaryExp((yyvsp[(2) - (3)].ps).pos, (yyvsp[(1) - (3)].e), (yyvsp[(2) - (3)].ps).sym, (yyvsp[(3) - (3)].e)); ;}
+ break;
+
+ case 123:
+#line 462 "camp.y"
+ { (yyval.e) = new binaryExp((yyvsp[(2) - (3)].ps).pos, (yyvsp[(1) - (3)].e), (yyvsp[(2) - (3)].ps).sym, (yyvsp[(3) - (3)].e)); ;}
+ break;
+
+ case 124:
+#line 463 "camp.y"
+ { (yyval.e) = new binaryExp((yyvsp[(2) - (3)].ps).pos, (yyvsp[(1) - (3)].e), (yyvsp[(2) - (3)].ps).sym, (yyvsp[(3) - (3)].e)); ;}
+ break;
+
+ case 125:
+#line 464 "camp.y"
+ { (yyval.e) = new binaryExp((yyvsp[(2) - (3)].ps).pos, (yyvsp[(1) - (3)].e), (yyvsp[(2) - (3)].ps).sym, (yyvsp[(3) - (3)].e)); ;}
+ break;
+
+ case 126:
+#line 465 "camp.y"
+ { (yyval.e) = new binaryExp((yyvsp[(2) - (3)].ps).pos, (yyvsp[(1) - (3)].e), (yyvsp[(2) - (3)].ps).sym, (yyvsp[(3) - (3)].e)); ;}
+ break;
+
+ case 127:
+#line 466 "camp.y"
+ { (yyval.e) = new andExp((yyvsp[(2) - (3)].ps).pos, (yyvsp[(1) - (3)].e), (yyvsp[(2) - (3)].ps).sym, (yyvsp[(3) - (3)].e)); ;}
+ break;
+
+ case 128:
+#line 467 "camp.y"
+ { (yyval.e) = new orExp((yyvsp[(2) - (3)].ps).pos, (yyvsp[(1) - (3)].e), (yyvsp[(2) - (3)].ps).sym, (yyvsp[(3) - (3)].e)); ;}
+ break;
+
+ case 129:
+#line 468 "camp.y"
+ { (yyval.e) = new binaryExp((yyvsp[(2) - (3)].ps).pos, (yyvsp[(1) - (3)].e), (yyvsp[(2) - (3)].ps).sym, (yyvsp[(3) - (3)].e)); ;}
+ break;
+
+ case 130:
+#line 469 "camp.y"
+ { (yyval.e) = new binaryExp((yyvsp[(2) - (3)].ps).pos, (yyvsp[(1) - (3)].e), (yyvsp[(2) - (3)].ps).sym, (yyvsp[(3) - (3)].e)); ;}
+ break;
+
+ case 131:
+#line 470 "camp.y"
+ { (yyval.e) = new binaryExp((yyvsp[(2) - (3)].ps).pos, (yyvsp[(1) - (3)].e), (yyvsp[(2) - (3)].ps).sym, (yyvsp[(3) - (3)].e)); ;}
+ break;
+
+ case 132:
+#line 471 "camp.y"
+ { (yyval.e) = new binaryExp((yyvsp[(2) - (3)].ps).pos, (yyvsp[(1) - (3)].e), (yyvsp[(2) - (3)].ps).sym, (yyvsp[(3) - (3)].e)); ;}
+ break;
+
+ case 133:
+#line 472 "camp.y"
+ { (yyval.e) = new binaryExp((yyvsp[(2) - (3)].ps).pos, (yyvsp[(1) - (3)].e), (yyvsp[(2) - (3)].ps).sym, (yyvsp[(3) - (3)].e)); ;}
+ break;
+
+ case 134:
+#line 474 "camp.y"
+ { (yyval.e) = new newRecordExp((yyvsp[(1) - (2)].pos), (yyvsp[(2) - (2)].t)); ;}
+ break;
+
+ case 135:
+#line 476 "camp.y"
+ { (yyval.e) = new newArrayExp((yyvsp[(1) - (3)].pos), (yyvsp[(2) - (3)].t), (yyvsp[(3) - (3)].elist), 0, 0); ;}
+ break;
+
+ case 136:
+#line 478 "camp.y"
+ { (yyval.e) = new newArrayExp((yyvsp[(1) - (4)].pos), (yyvsp[(2) - (4)].t), (yyvsp[(3) - (4)].elist), (yyvsp[(4) - (4)].dim), 0); ;}
+ break;
+
+ case 137:
+#line 480 "camp.y"
+ { (yyval.e) = new newArrayExp((yyvsp[(1) - (3)].pos), (yyvsp[(2) - (3)].t), 0, (yyvsp[(3) - (3)].dim), 0); ;}
+ break;
+
+ case 138:
+#line 482 "camp.y"
+ { (yyval.e) = new newArrayExp((yyvsp[(1) - (4)].pos), (yyvsp[(2) - (4)].t), 0, (yyvsp[(3) - (4)].dim), (yyvsp[(4) - (4)].ai)); ;}
+ break;
+
+ case 139:
+#line 484 "camp.y"
+ { (yyval.e) = new newFunctionExp((yyvsp[(1) - (5)].pos), (yyvsp[(2) - (5)].t), new formals((yyvsp[(3) - (5)].pos)), (yyvsp[(5) - (5)].s)); ;}
+ break;
+
+ case 140:
+#line 486 "camp.y"
+ { (yyval.e) = new newFunctionExp((yyvsp[(1) - (6)].pos),
+ new arrayTy((yyvsp[(2) - (6)].t)->getPos(), (yyvsp[(2) - (6)].t), (yyvsp[(3) - (6)].dim)),
+ new formals((yyvsp[(4) - (6)].pos)),
+ (yyvsp[(6) - (6)].s)); ;}
+ break;
+
+ case 141:
+#line 491 "camp.y"
+ { (yyval.e) = new newFunctionExp((yyvsp[(1) - (6)].pos), (yyvsp[(2) - (6)].t), (yyvsp[(4) - (6)].fls), (yyvsp[(6) - (6)].s)); ;}
+ break;
+
+ case 142:
+#line 493 "camp.y"
+ { (yyval.e) = new newFunctionExp((yyvsp[(1) - (7)].pos),
+ new arrayTy((yyvsp[(2) - (7)].t)->getPos(), (yyvsp[(2) - (7)].t), (yyvsp[(3) - (7)].dim)),
+ (yyvsp[(5) - (7)].fls),
+ (yyvsp[(7) - (7)].s)); ;}
+ break;
+
+ case 143:
+#line 498 "camp.y"
+ { (yyval.e) = new conditionalExp((yyvsp[(2) - (5)].pos), (yyvsp[(1) - (5)].e), (yyvsp[(3) - (5)].e), (yyvsp[(5) - (5)].e)); ;}
+ break;
+
+ case 144:
+#line 499 "camp.y"
+ { (yyval.e) = new assignExp((yyvsp[(2) - (3)].pos), (yyvsp[(1) - (3)].e), (yyvsp[(3) - (3)].e)); ;}
+ break;
+
+ case 145:
+#line 502 "camp.y"
+ { (yyval.e) = new pairExp((yyvsp[(1) - (5)].pos), (yyvsp[(2) - (5)].e), (yyvsp[(4) - (5)].e)); ;}
+ break;
+
+ case 146:
+#line 504 "camp.y"
+ { (yyval.e) = new tripleExp((yyvsp[(1) - (7)].pos), (yyvsp[(2) - (7)].e), (yyvsp[(4) - (7)].e), (yyvsp[(6) - (7)].e)); ;}
+ break;
+
+ case 147:
+#line 506 "camp.y"
+ { (yyval.e) = new transformExp((yyvsp[(1) - (13)].pos), (yyvsp[(2) - (13)].e), (yyvsp[(4) - (13)].e), (yyvsp[(6) - (13)].e), (yyvsp[(8) - (13)].e), (yyvsp[(10) - (13)].e), (yyvsp[(12) - (13)].e)); ;}
+ break;
+
+ case 148:
+#line 508 "camp.y"
+ { (yyvsp[(2) - (3)].j)->pushFront((yyvsp[(1) - (3)].e)); (yyvsp[(2) - (3)].j)->pushBack((yyvsp[(3) - (3)].e)); (yyval.e) = (yyvsp[(2) - (3)].j); ;}
+ break;
+
+ case 149:
+#line 510 "camp.y"
+ { (yyvsp[(2) - (2)].se)->setSide(camp::OUT);
+ joinExp *jexp =
+ new joinExp((yyvsp[(2) - (2)].se)->getPos(), symbol::trans(".."));
+ (yyval.e)=jexp;
+ jexp->pushBack((yyvsp[(1) - (2)].e)); jexp->pushBack((yyvsp[(2) - (2)].se)); ;}
+ break;
+
+ case 150:
+#line 516 "camp.y"
+ { (yyval.e) = new prefixExp((yyvsp[(1) - (2)].ps).pos, (yyvsp[(2) - (2)].e), symbol::trans("+")); ;}
+ break;
+
+ case 151:
+#line 518 "camp.y"
+ { (yyval.e) = new prefixExp((yyvsp[(1) - (2)].ps).pos, (yyvsp[(2) - (2)].e), symbol::trans("-")); ;}
+ break;
+
+ case 152:
+#line 521 "camp.y"
+ { (yyval.e) = new postfixExp((yyvsp[(2) - (2)].ps).pos, (yyvsp[(1) - (2)].e), symbol::trans("+")); ;}
+ break;
+
+ case 153:
+#line 522 "camp.y"
+ { (yyval.e) = new selfExp((yyvsp[(2) - (3)].ps).pos, (yyvsp[(1) - (3)].e), (yyvsp[(2) - (3)].ps).sym, (yyvsp[(3) - (3)].e)); ;}
+ break;
+
+ case 154:
+#line 524 "camp.y"
+ { (yyval.e) = new selfExp((yyvsp[(2) - (3)].ps).pos, (yyvsp[(1) - (3)].e), (yyvsp[(2) - (3)].ps).sym, (yyvsp[(3) - (3)].e)); ;}
+ break;
+
+ case 155:
+#line 525 "camp.y"
+ { (yyval.e) = new selfExp((yyvsp[(2) - (3)].ps).pos, (yyvsp[(1) - (3)].e), (yyvsp[(2) - (3)].ps).sym, (yyvsp[(3) - (3)].e)); ;}
+ break;
+
+ case 156:
+#line 526 "camp.y"
+ { (yyval.e) = new selfExp((yyvsp[(2) - (3)].ps).pos, (yyvsp[(1) - (3)].e), (yyvsp[(2) - (3)].ps).sym, (yyvsp[(3) - (3)].e)); ;}
+ break;
+
+ case 157:
+#line 527 "camp.y"
+ { (yyval.e) = new selfExp((yyvsp[(2) - (3)].ps).pos, (yyvsp[(1) - (3)].e), (yyvsp[(2) - (3)].ps).sym, (yyvsp[(3) - (3)].e)); ;}
+ break;
+
+ case 158:
+#line 529 "camp.y"
+ { (yyval.e) = new selfExp((yyvsp[(2) - (3)].ps).pos, (yyvsp[(1) - (3)].e), (yyvsp[(2) - (3)].ps).sym, (yyvsp[(3) - (3)].e)); ;}
+ break;
+
+ case 159:
+#line 531 "camp.y"
+ { (yyval.e) = new quoteExp((yyvsp[(1) - (4)].pos), (yyvsp[(3) - (4)].b)); ;}
+ break;
+
+ case 160:
+#line 537 "camp.y"
+ { (yyval.j) = new joinExp((yyvsp[(1) - (1)].ps).pos,(yyvsp[(1) - (1)].ps).sym); ;}
+ break;
+
+ case 161:
+#line 539 "camp.y"
+ { (yyval.j) = (yyvsp[(1) - (1)].j); ;}
+ break;
+
+ case 162:
+#line 541 "camp.y"
+ { (yyvsp[(1) - (2)].se)->setSide(camp::OUT);
+ (yyval.j) = (yyvsp[(2) - (2)].j); (yyval.j)->pushFront((yyvsp[(1) - (2)].se)); ;}
+ break;
+
+ case 163:
+#line 544 "camp.y"
+ { (yyvsp[(2) - (2)].se)->setSide(camp::IN);
+ (yyval.j) = (yyvsp[(1) - (2)].j); (yyval.j)->pushBack((yyvsp[(2) - (2)].se)); ;}
+ break;
+
+ case 164:
+#line 547 "camp.y"
+ { (yyvsp[(1) - (3)].se)->setSide(camp::OUT); (yyvsp[(3) - (3)].se)->setSide(camp::IN);
+ (yyval.j) = (yyvsp[(2) - (3)].j); (yyval.j)->pushFront((yyvsp[(1) - (3)].se)); (yyval.j)->pushBack((yyvsp[(3) - (3)].se)); ;}
+ break;
+
+ case 165:
+#line 552 "camp.y"
+ { (yyval.se) = new specExp((yyvsp[(2) - (4)].ps).pos, (yyvsp[(2) - (4)].ps).sym, (yyvsp[(3) - (4)].e)); ;}
+ break;
+
+ case 166:
+#line 553 "camp.y"
+ { (yyval.se) = new specExp((yyvsp[(1) - (3)].pos), symbol::opTrans("spec"), (yyvsp[(2) - (3)].e)); ;}
+ break;
+
+ case 167:
+#line 555 "camp.y"
+ { (yyval.se) = new specExp((yyvsp[(1) - (5)].pos), symbol::opTrans("spec"),
+ new pairExp((yyvsp[(3) - (5)].pos), (yyvsp[(2) - (5)].e), (yyvsp[(4) - (5)].e))); ;}
+ break;
+
+ case 168:
+#line 558 "camp.y"
+ { (yyval.se) = new specExp((yyvsp[(1) - (7)].pos), symbol::opTrans("spec"),
+ new tripleExp((yyvsp[(3) - (7)].pos), (yyvsp[(2) - (7)].e), (yyvsp[(4) - (7)].e), (yyvsp[(6) - (7)].e))); ;}
+ break;
+
+ case 169:
+#line 563 "camp.y"
+ { (yyval.j) = new joinExp((yyvsp[(1) - (1)].ps).pos, (yyvsp[(1) - (1)].ps).sym); ;}
+ break;
+
+ case 170:
+#line 565 "camp.y"
+ { (yyval.j) = new joinExp((yyvsp[(1) - (3)].ps).pos, (yyvsp[(1) - (3)].ps).sym); (yyval.j)->pushBack((yyvsp[(2) - (3)].e)); ;}
+ break;
+
+ case 171:
+#line 567 "camp.y"
+ { (yyval.j) = new joinExp((yyvsp[(1) - (3)].ps).pos, (yyvsp[(1) - (3)].ps).sym); (yyval.j)->pushBack((yyvsp[(2) - (3)].e)); ;}
+ break;
+
+ case 172:
+#line 568 "camp.y"
+ { (yyval.j) = new joinExp((yyvsp[(1) - (1)].ps).pos, (yyvsp[(1) - (1)].ps).sym); ;}
+ break;
+
+ case 173:
+#line 569 "camp.y"
+ { (yyval.j) = new joinExp((yyvsp[(1) - (1)].ps).pos, (yyvsp[(1) - (1)].ps).sym); ;}
+ break;
+
+ case 174:
+#line 573 "camp.y"
+ { (yyval.e) = new binaryExp((yyvsp[(1) - (2)].ps).pos, (yyvsp[(2) - (2)].e), (yyvsp[(1) - (2)].ps).sym,
+ new booleanExp((yyvsp[(1) - (2)].ps).pos, false)); ;}
+ break;
+
+ case 175:
+#line 576 "camp.y"
+ { (yyval.e) = new ternaryExp((yyvsp[(1) - (4)].ps).pos, (yyvsp[(2) - (4)].e), (yyvsp[(1) - (4)].ps).sym, (yyvsp[(4) - (4)].e),
+ new booleanExp((yyvsp[(1) - (4)].ps).pos, false)); ;}
+ break;
+
+ case 176:
+#line 579 "camp.y"
+ { (yyval.e) = new binaryExp((yyvsp[(1) - (3)].ps).pos, (yyvsp[(3) - (3)].e), (yyvsp[(1) - (3)].ps).sym,
+ new booleanExp((yyvsp[(2) - (3)].ps).pos, true)); ;}
+ break;
+
+ case 177:
+#line 582 "camp.y"
+ { (yyval.e) = new ternaryExp((yyvsp[(1) - (5)].ps).pos, (yyvsp[(3) - (5)].e), (yyvsp[(1) - (5)].ps).sym, (yyvsp[(5) - (5)].e),
+ new booleanExp((yyvsp[(2) - (5)].ps).pos, true)); ;}
+ break;
+
+ case 178:
+#line 587 "camp.y"
+ { (yyval.e) = new unaryExp((yyvsp[(1) - (2)].ps).pos, (yyvsp[(2) - (2)].e), (yyvsp[(1) - (2)].ps).sym); ;}
+ break;
+
+ case 179:
+#line 589 "camp.y"
+ { (yyval.e) = new binaryExp((yyvsp[(1) - (4)].ps).pos, (yyvsp[(2) - (4)].e), (yyvsp[(1) - (4)].ps).sym, (yyvsp[(4) - (4)].e)); ;}
+ break;
+
+ case 180:
+#line 593 "camp.y"
+ { (yyval.s) = new emptyStm((yyvsp[(1) - (1)].pos)); ;}
+ break;
+
+ case 181:
+#line 594 "camp.y"
+ { (yyval.s) = (yyvsp[(1) - (1)].s); ;}
+ break;
+
+ case 182:
+#line 595 "camp.y"
+ { (yyval.s) = (yyvsp[(1) - (2)].s); ;}
+ break;
+
+ case 183:
+#line 597 "camp.y"
+ { (yyval.s) = new ifStm((yyvsp[(1) - (5)].pos), (yyvsp[(3) - (5)].e), (yyvsp[(5) - (5)].s)); ;}
+ break;
+
+ case 184:
+#line 599 "camp.y"
+ { (yyval.s) = new ifStm((yyvsp[(1) - (7)].pos), (yyvsp[(3) - (7)].e), (yyvsp[(5) - (7)].s), (yyvsp[(7) - (7)].s)); ;}
+ break;
+
+ case 185:
+#line 601 "camp.y"
+ { (yyval.s) = new whileStm((yyvsp[(1) - (5)].pos), (yyvsp[(3) - (5)].e), (yyvsp[(5) - (5)].s)); ;}
+ break;
+
+ case 186:
+#line 603 "camp.y"
+ { (yyval.s) = new doStm((yyvsp[(1) - (7)].pos), (yyvsp[(2) - (7)].s), (yyvsp[(5) - (7)].e)); ;}
+ break;
+
+ case 187:
+#line 605 "camp.y"
+ { (yyval.s) = new forStm((yyvsp[(1) - (9)].pos), (yyvsp[(3) - (9)].run), (yyvsp[(5) - (9)].e), (yyvsp[(7) - (9)].sel), (yyvsp[(9) - (9)].s)); ;}
+ break;
+
+ case 188:
+#line 607 "camp.y"
+ { (yyval.s) = new extendedForStm((yyvsp[(1) - (8)].pos), (yyvsp[(3) - (8)].t), (yyvsp[(4) - (8)].ps).sym, (yyvsp[(6) - (8)].e), (yyvsp[(8) - (8)].s)); ;}
+ break;
+
+ case 189:
+#line 608 "camp.y"
+ { (yyval.s) = new breakStm((yyvsp[(1) - (2)].pos)); ;}
+ break;
+
+ case 190:
+#line 609 "camp.y"
+ { (yyval.s) = new continueStm((yyvsp[(1) - (2)].pos)); ;}
+ break;
+
+ case 191:
+#line 610 "camp.y"
+ { (yyval.s) = new returnStm((yyvsp[(1) - (2)].pos)); ;}
+ break;
+
+ case 192:
+#line 611 "camp.y"
+ { (yyval.s) = new returnStm((yyvsp[(1) - (3)].pos), (yyvsp[(2) - (3)].e)); ;}
+ break;
+
+ case 193:
+#line 615 "camp.y"
+ { (yyval.s) = new expStm((yyvsp[(1) - (1)].e)->getPos(), (yyvsp[(1) - (1)].e)); ;}
+ break;
+
+ case 194:
+#line 619 "camp.y"
+ { (yyval.s) = new blockStm((yyvsp[(1) - (1)].b)->getPos(), (yyvsp[(1) - (1)].b)); ;}
+ break;
+
+ case 195:
+#line 623 "camp.y"
+ { (yyval.run) = 0; ;}
+ break;
+
+ case 196:
+#line 624 "camp.y"
+ { (yyval.run) = (yyvsp[(1) - (1)].sel); ;}
+ break;
+
+ case 197:
+#line 625 "camp.y"
+ { (yyval.run) = (yyvsp[(1) - (1)].vd); ;}
+ break;
+
+ case 198:
+#line 629 "camp.y"
+ { (yyval.e) = 0; ;}
+ break;
+
+ case 199:
+#line 630 "camp.y"
+ { (yyval.e) = (yyvsp[(1) - (1)].e); ;}
+ break;
+
+ case 200:
+#line 634 "camp.y"
+ { (yyval.sel) = 0; ;}
+ break;
+
+ case 201:
+#line 635 "camp.y"
+ { (yyval.sel) = (yyvsp[(1) - (1)].sel); ;}
+ break;
+
+ case 202:
+#line 639 "camp.y"
+ { (yyval.sel) = new stmExpList((yyvsp[(1) - (1)].s)->getPos()); (yyval.sel)->add((yyvsp[(1) - (1)].s)); ;}
+ break;
+
+ case 203:
+#line 641 "camp.y"
+ { (yyval.sel) = (yyvsp[(1) - (3)].sel); (yyval.sel)->add((yyvsp[(3) - (3)].s)); ;}
+ break;
+
+
+/* Line 1267 of yacc.c. */
+#line 3303 "camp.tab.c"
+ default: break;
+ }
+ YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc);
+
+ YYPOPSTACK (yylen);
+ yylen = 0;
+ YY_STACK_PRINT (yyss, yyssp);
+
+ *++yyvsp = yyval;
+
+
+ /* Now `shift' the result of the reduction. Determine what state
+ that goes to, based on the state we popped back to and the rule
+ number reduced by. */
+
+ yyn = yyr1[yyn];
+
+ yystate = yypgoto[yyn - YYNTOKENS] + *yyssp;
+ if (0 <= yystate && yystate <= YYLAST && yycheck[yystate] == *yyssp)
+ yystate = yytable[yystate];
+ else
+ yystate = yydefgoto[yyn - YYNTOKENS];
+
+ goto yynewstate;
+
+
+/*------------------------------------.
+| yyerrlab -- here on detecting error |
+`------------------------------------*/
+yyerrlab:
+ /* If not already recovering from an error, report this error. */
+ if (!yyerrstatus)
+ {
+ ++yynerrs;
+#if ! YYERROR_VERBOSE
+ yyerror (YY_("syntax error"));
+#else
+ {
+ YYSIZE_T yysize = yysyntax_error (0, yystate, yychar);
+ if (yymsg_alloc < yysize && yymsg_alloc < YYSTACK_ALLOC_MAXIMUM)
+ {
+ YYSIZE_T yyalloc = 2 * yysize;
+ if (! (yysize <= yyalloc && yyalloc <= YYSTACK_ALLOC_MAXIMUM))
+ yyalloc = YYSTACK_ALLOC_MAXIMUM;
+ if (yymsg != yymsgbuf)
+ YYSTACK_FREE (yymsg);
+ yymsg = (char *) YYSTACK_ALLOC (yyalloc);
+ if (yymsg)
+ yymsg_alloc = yyalloc;
+ else
+ {
+ yymsg = yymsgbuf;
+ yymsg_alloc = sizeof yymsgbuf;
+ }
+ }
+
+ if (0 < yysize && yysize <= yymsg_alloc)
+ {
+ (void) yysyntax_error (yymsg, yystate, yychar);
+ yyerror (yymsg);
+ }
+ else
+ {
+ yyerror (YY_("syntax error"));
+ if (yysize != 0)
+ goto yyexhaustedlab;
+ }
+ }
+#endif
+ }
+
+
+
+ if (yyerrstatus == 3)
+ {
+ /* If just tried and failed to reuse look-ahead token after an
+ error, discard it. */
+
+ if (yychar <= YYEOF)
+ {
+ /* Return failure if at end of input. */
+ if (yychar == YYEOF)
+ YYABORT;
+ }
+ else
+ {
+ yydestruct ("Error: discarding",
+ yytoken, &yylval);
+ yychar = YYEMPTY;
+ }
+ }
+
+ /* Else will try to reuse look-ahead token after shifting the error
+ token. */
+ goto yyerrlab1;
+
+
+/*---------------------------------------------------.
+| yyerrorlab -- error raised explicitly by YYERROR. |
+`---------------------------------------------------*/
+yyerrorlab:
+
+ /* Pacify compilers like GCC when the user code never invokes
+ YYERROR and the label yyerrorlab therefore never appears in user
+ code. */
+ if (/*CONSTCOND*/ 0)
+ goto yyerrorlab;
+
+ /* Do not reclaim the symbols of the rule which action triggered
+ this YYERROR. */
+ YYPOPSTACK (yylen);
+ yylen = 0;
+ YY_STACK_PRINT (yyss, yyssp);
+ yystate = *yyssp;
+ goto yyerrlab1;
+
+
+/*-------------------------------------------------------------.
+| yyerrlab1 -- common code for both syntax error and YYERROR. |
+`-------------------------------------------------------------*/
+yyerrlab1:
+ yyerrstatus = 3; /* Each real token shifted decrements this. */
+
+ for (;;)
+ {
+ yyn = yypact[yystate];
+ if (yyn != YYPACT_NINF)
+ {
+ yyn += YYTERROR;
+ if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR)
+ {
+ yyn = yytable[yyn];
+ if (0 < yyn)
+ break;
+ }
+ }
+
+ /* Pop the current state because it cannot handle the error token. */
+ if (yyssp == yyss)
+ YYABORT;
+
+
+ yydestruct ("Error: popping",
+ yystos[yystate], yyvsp);
+ YYPOPSTACK (1);
+ yystate = *yyssp;
+ YY_STACK_PRINT (yyss, yyssp);
+ }
+
+ if (yyn == YYFINAL)
+ YYACCEPT;
+
+ *++yyvsp = yylval;
+
+
+ /* Shift the error token. */
+ YY_SYMBOL_PRINT ("Shifting", yystos[yyn], yyvsp, yylsp);
+
+ yystate = yyn;
+ goto yynewstate;
+
+
+/*-------------------------------------.
+| yyacceptlab -- YYACCEPT comes here. |
+`-------------------------------------*/
+yyacceptlab:
+ yyresult = 0;
+ goto yyreturn;
+
+/*-----------------------------------.
+| yyabortlab -- YYABORT comes here. |
+`-----------------------------------*/
+yyabortlab:
+ yyresult = 1;
+ goto yyreturn;
+
+#ifndef yyoverflow
+/*-------------------------------------------------.
+| yyexhaustedlab -- memory exhaustion comes here. |
+`-------------------------------------------------*/
+yyexhaustedlab:
+ yyerror (YY_("memory exhausted"));
+ yyresult = 2;
+ /* Fall through. */
+#endif
+
+yyreturn:
+ if (yychar != YYEOF && yychar != YYEMPTY)
+ yydestruct ("Cleanup: discarding lookahead",
+ yytoken, &yylval);
+ /* Do not reclaim the symbols of the rule which action triggered
+ this YYABORT or YYACCEPT. */
+ YYPOPSTACK (yylen);
+ YY_STACK_PRINT (yyss, yyssp);
+ while (yyssp != yyss)
+ {
+ yydestruct ("Cleanup: popping",
+ yystos[*yyssp], yyvsp);
+ YYPOPSTACK (1);
+ }
+#ifndef yyoverflow
+ if (yyss != yyssa)
+ YYSTACK_FREE (yyss);
+#endif
+#if YYERROR_VERBOSE
+ if (yymsg != yymsgbuf)
+ YYSTACK_FREE (yymsg);
+#endif
+ /* Make sure YYID is used. */
+ return YYID (yyresult);
+}
+
+
+
diff --git a/Build/source/utils/asymptote/camp.tab.h b/Build/source/utils/asymptote/camp.tab.h
new file mode 100644
index 00000000000..a6a8b4464e9
--- /dev/null
+++ b/Build/source/utils/asymptote/camp.tab.h
@@ -0,0 +1,228 @@
+/* A Bison parser, made by GNU Bison 2.3. */
+
+/* Skeleton interface for Bison's Yacc-like parsers in C
+
+ Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006
+ Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ This program 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 General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA. */
+
+/* As a special exception, you may create a larger work that contains
+ part or all of the Bison parser skeleton and distribute that work
+ under terms of your choice, so long as that work isn't itself a
+ parser generator using the skeleton or a modified version thereof
+ as a parser skeleton. Alternatively, if you modify or redistribute
+ the parser skeleton itself, you may (at your option) remove this
+ special exception, which will cause the skeleton and the resulting
+ Bison output files to be licensed under the GNU General Public
+ License without this special exception.
+
+ This special exception was added by the Free Software Foundation in
+ version 2.2 of Bison. */
+
+/* Tokens. */
+#ifndef YYTOKENTYPE
+# define YYTOKENTYPE
+ /* Put the tokens into the symbol table, so that GDB and other debuggers
+ know about them. */
+ enum yytokentype {
+ ID = 258,
+ ADD = 259,
+ SUBTRACT = 260,
+ TIMES = 261,
+ DIVIDE = 262,
+ MOD = 263,
+ EXPONENT = 264,
+ DOTS = 265,
+ COLONS = 266,
+ DASHES = 267,
+ INCR = 268,
+ LONGDASH = 269,
+ CONTROLS = 270,
+ TENSION = 271,
+ ATLEAST = 272,
+ CURL = 273,
+ COR = 274,
+ CAND = 275,
+ BAR = 276,
+ AMPERSAND = 277,
+ EQ = 278,
+ NEQ = 279,
+ LT = 280,
+ LE = 281,
+ GT = 282,
+ GE = 283,
+ CARETS = 284,
+ LOGNOT = 285,
+ OPERATOR = 286,
+ STRING = 287,
+ LOOSE = 288,
+ ASSIGN = 289,
+ DIRTAG = 290,
+ JOIN_PREC = 291,
+ AND = 292,
+ ELLIPSIS = 293,
+ ACCESS = 294,
+ UNRAVEL = 295,
+ IMPORT = 296,
+ INCLUDE = 297,
+ FROM = 298,
+ QUOTE = 299,
+ STRUCT = 300,
+ TYPEDEF = 301,
+ NEW = 302,
+ IF = 303,
+ ELSE = 304,
+ WHILE = 305,
+ DO = 306,
+ FOR = 307,
+ BREAK = 308,
+ CONTINUE = 309,
+ RETURN_ = 310,
+ THIS = 311,
+ EXPLICIT = 312,
+ GARBAGE = 313,
+ LIT = 314,
+ PERM = 315,
+ MODIFIER = 316,
+ UNARY = 317,
+ EXP_IN_PARENS_RULE = 318
+ };
+#endif
+/* Tokens. */
+#define ID 258
+#define ADD 259
+#define SUBTRACT 260
+#define TIMES 261
+#define DIVIDE 262
+#define MOD 263
+#define EXPONENT 264
+#define DOTS 265
+#define COLONS 266
+#define DASHES 267
+#define INCR 268
+#define LONGDASH 269
+#define CONTROLS 270
+#define TENSION 271
+#define ATLEAST 272
+#define CURL 273
+#define COR 274
+#define CAND 275
+#define BAR 276
+#define AMPERSAND 277
+#define EQ 278
+#define NEQ 279
+#define LT 280
+#define LE 281
+#define GT 282
+#define GE 283
+#define CARETS 284
+#define LOGNOT 285
+#define OPERATOR 286
+#define STRING 287
+#define LOOSE 288
+#define ASSIGN 289
+#define DIRTAG 290
+#define JOIN_PREC 291
+#define AND 292
+#define ELLIPSIS 293
+#define ACCESS 294
+#define UNRAVEL 295
+#define IMPORT 296
+#define INCLUDE 297
+#define FROM 298
+#define QUOTE 299
+#define STRUCT 300
+#define TYPEDEF 301
+#define NEW 302
+#define IF 303
+#define ELSE 304
+#define WHILE 305
+#define DO 306
+#define FOR 307
+#define BREAK 308
+#define CONTINUE 309
+#define RETURN_ 310
+#define THIS 311
+#define EXPLICIT 312
+#define GARBAGE 313
+#define LIT 314
+#define PERM 315
+#define MODIFIER 316
+#define UNARY 317
+#define EXP_IN_PARENS_RULE 318
+
+
+
+
+#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
+typedef union YYSTYPE
+#line 46 "camp.y"
+{
+ position pos;
+ bool boo;
+ struct {
+ position pos;
+ sym::symbol *sym;
+ } ps;
+ absyntax::name *n;
+ absyntax::varinit *vi;
+ absyntax::arrayinit *ai;
+ absyntax::exp *e;
+ absyntax::specExp *se;
+ absyntax::joinExp *j;
+ absyntax::explist *elist;
+ absyntax::argument arg;
+ absyntax::arglist *alist;
+ absyntax::slice *slice;
+ absyntax::dimensions *dim;
+ absyntax::ty *t;
+ absyntax::decid *di;
+ absyntax::decidlist *dil;
+ absyntax::decidstart *dis;
+ absyntax::runnable *run;
+ struct {
+ position pos;
+ trans::permission val;
+ } perm;
+ struct {
+ position pos;
+ trans::modifier val;
+ } mod;
+ absyntax::modifierList *ml;
+ //absyntax::program *prog;
+ absyntax::vardec *vd;
+ //absyntax::vardecs *vds;
+ absyntax::dec *d;
+ absyntax::idpair *ip;
+ absyntax::idpairlist *ipl;
+ absyntax::stm *s;
+ absyntax::block *b;
+ absyntax::stmExpList *sel;
+ //absyntax::funheader *fh;
+ absyntax::formal *fl;
+ absyntax::formals *fls;
+}
+/* Line 1489 of yacc.c. */
+#line 221 "camp.tab.h"
+ YYSTYPE;
+# define yystype YYSTYPE /* obsolescent; will be withdrawn */
+# define YYSTYPE_IS_DECLARED 1
+# define YYSTYPE_IS_TRIVIAL 1
+#endif
+
+extern YYSTYPE yylval;
+
diff --git a/Build/source/utils/asymptote/camp.y b/Build/source/utils/asymptote/camp.y
new file mode 100644
index 00000000000..f257812b068
--- /dev/null
+++ b/Build/source/utils/asymptote/camp.y
@@ -0,0 +1,642 @@
+%{
+/*****
+ * camp.y
+ * Andy Hammerlindl 08/12/2002
+ *
+ * The grammar of the camp language.
+ *****/
+
+#include "errormsg.h"
+#include "exp.h"
+#include "newexp.h"
+#include "dec.h"
+#include "fundec.h"
+#include "stm.h"
+#include "modifier.h"
+
+// Avoid error messages with unpatched bison-1.875:
+#ifndef __attribute__
+#define __attribute__(x)
+#endif
+
+// Used when a position needs to be determined and no token is
+// available. Defined in camp.l.
+position lexerPos();
+
+bool lexerEOF();
+
+int yylex(void); /* function prototype */
+
+void yyerror(const char *s)
+{
+ if (!lexerEOF()) {
+ em.error(lexerPos());
+ em << s;
+ em.cont();
+ }
+}
+
+namespace absyntax { file *root; }
+
+using namespace absyntax;
+using sym::symbol;
+using mem::string;
+%}
+
+%union {
+ position pos;
+ bool boo;
+ struct {
+ position pos;
+ sym::symbol *sym;
+ } ps;
+ absyntax::name *n;
+ absyntax::varinit *vi;
+ absyntax::arrayinit *ai;
+ absyntax::exp *e;
+ absyntax::specExp *se;
+ absyntax::joinExp *j;
+ absyntax::explist *elist;
+ absyntax::argument arg;
+ absyntax::arglist *alist;
+ absyntax::slice *slice;
+ absyntax::dimensions *dim;
+ absyntax::ty *t;
+ absyntax::decid *di;
+ absyntax::decidlist *dil;
+ absyntax::decidstart *dis;
+ absyntax::runnable *run;
+ struct {
+ position pos;
+ trans::permission val;
+ } perm;
+ struct {
+ position pos;
+ trans::modifier val;
+ } mod;
+ absyntax::modifierList *ml;
+ //absyntax::program *prog;
+ absyntax::vardec *vd;
+ //absyntax::vardecs *vds;
+ absyntax::dec *d;
+ absyntax::idpair *ip;
+ absyntax::idpairlist *ipl;
+ absyntax::stm *s;
+ absyntax::block *b;
+ absyntax::stmExpList *sel;
+ //absyntax::funheader *fh;
+ absyntax::formal *fl;
+ absyntax::formals *fls;
+}
+
+%token <ps> ID ADD SUBTRACT TIMES DIVIDE MOD EXPONENT
+ DOTS COLONS DASHES INCR LONGDASH
+ CONTROLS TENSION ATLEAST CURL
+ COR CAND BAR AMPERSAND EQ NEQ LT LE GT GE CARETS
+ '+' '-' '*' '/' '%' '^' LOGNOT OPERATOR
+ STRING
+%token <pos> LOOSE ASSIGN '?' ':'
+ DIRTAG JOIN_PREC AND
+ '{' '}' '(' ')' '.' ',' '[' ']' ';' ELLIPSIS
+ ACCESS UNRAVEL IMPORT INCLUDE FROM QUOTE STRUCT TYPEDEF NEW
+ IF ELSE WHILE DO FOR BREAK CONTINUE RETURN_
+ THIS EXPLICIT
+ GARBAGE
+%token <e> LIT
+%token <perm> PERM
+%token <mod> MODIFIER
+
+%right ASSIGN ADD SUBTRACT TIMES DIVIDE MOD EXPONENT
+%right '?' ':'
+%left COR
+%left CAND
+%left BAR
+%left AMPERSAND
+%left EQ NEQ
+%left LT LE GT GE
+%left OPERATOR
+
+%left CARETS
+%left JOIN_PREC DOTS COLONS DASHES INCR LONGDASH
+%left DIRTAG CONTROLS TENSION ATLEAST AND
+%left CURL '{' '}'
+
+%left '+' '-'
+%left '*' '/' '%' LIT
+%left UNARY
+%right '^'
+%left LOGNOT
+%left EXP_IN_PARENS_RULE
+%left '(' ')'
+
+%type <b> fileblock bareblock block
+%type <n> name
+%type <run> runnable
+%type <ml> modifiers
+%type <d> dec fundec typedec
+%type <ps> strid
+%type <ip> idpair stridpair
+%type <ipl> idpairlist stridpairlist
+%type <vd> vardec barevardec
+%type <t> type celltype
+%type <dim> dims
+%type <dil> decidlist
+%type <di> decid
+%type <dis> decidstart
+%type <vi> varinit
+%type <ai> arrayinit basearrayinit varinits
+%type <fl> formal
+%type <fls> formals baseformals
+%type <e> value exp fortest
+%type <arg> argument
+%type <slice> slice
+%type <j> join basicjoin
+%type <e> tension controls
+%type <se> dir
+%type <elist> dimexps
+%type <alist> arglist basearglist
+%type <s> stm stmexp blockstm
+%type <run> forinit
+%type <sel> forupdate stmexplist
+%type <boo> explicitornot
+
+/* There are four shift/reduce conflicts:
+ * the dangling ELSE in IF (exp) IF (exp) stm ELSE stm
+ * new ID
+ * the argument id=exp is taken as an argument instead of an assignExp
+ * explicit cast
+ */
+%expect 4
+
+/* Enable grammar debugging. */
+/*%debug*/
+
+%%
+
+file:
+ fileblock { absyntax::root = $1; }
+;
+
+fileblock:
+ /* empty */ { $$ = new file(lexerPos(), false); }
+| fileblock runnable
+ { $$ = $1; $$->add($2); }
+;
+
+bareblock:
+ /* empty */ { $$ = new block(lexerPos(), true); }
+| bareblock runnable
+ { $$ = $1; $$->add($2); }
+;
+
+name:
+ ID { $$ = new simpleName($1.pos, $1.sym); }
+| name '.' ID { $$ = new qualifiedName($2, $1, $3.sym); }
+;
+
+runnable:
+ dec { $$ = $1; }
+| stm { $$ = $1; }
+| modifiers dec
+ { $$ = new modifiedRunnable($1->getPos(), $1, $2); }
+| modifiers stm
+ { $$ = new modifiedRunnable($1->getPos(), $1, $2); }
+;
+
+modifiers:
+ MODIFIER { $$ = new modifierList($1.pos); $$->add($1.val); }
+| PERM { $$ = new modifierList($1.pos); $$->add($1.val); }
+| modifiers MODIFIER
+ { $$ = $1; $$->add($2.val); }
+| modifiers PERM
+ { $$ = $1; $$->add($2.val); }
+;
+
+dec:
+ vardec { $$ = $1; }
+| fundec { $$ = $1; }
+| typedec { $$ = $1; }
+| ACCESS stridpairlist ';'
+ { $$ = new accessdec($1, $2); }
+| FROM name UNRAVEL idpairlist ';'
+ { $$ = new unraveldec($1, $2, $4); }
+| FROM name UNRAVEL '*' ';'
+ { $$ = new unraveldec($1, $2, WILDCARD); }
+| UNRAVEL name ';' { $$ = new unraveldec($1, $2, WILDCARD); }
+| FROM strid ACCESS idpairlist ';'
+ { $$ = new fromaccessdec($1, $2.sym, $4); }
+| FROM strid ACCESS '*' ';'
+ { $$ = new fromaccessdec($1, $2.sym, WILDCARD); }
+| IMPORT stridpair ';'
+ { $$ = new importdec($1, $2); }
+| INCLUDE ID ';' { $$ = new includedec($1, $2.sym); }
+| INCLUDE STRING ';'
+ { $$ = new includedec($1, (string)*$2.sym); }
+;
+
+idpair:
+ ID { $$ = new idpair($1.pos, $1.sym); }
+/* ID 'as' ID */
+| ID ID ID { $$ = new idpair($1.pos, $1.sym, $2.sym , $3.sym); }
+;
+
+idpairlist:
+ idpair { $$ = new idpairlist(); $$->add($1); }
+| idpairlist ',' idpair
+ { $$ = $1; $$->add($3); }
+;
+
+strid:
+ STRING { $$ = $1; }
+| ID { $$ = $1; }
+;
+
+stridpair:
+ ID { $$ = new idpair($1.pos, $1.sym); }
+/* strid 'as' ID */
+| strid ID ID { $$ = new idpair($1.pos, $1.sym, $2.sym , $3.sym); }
+;
+
+stridpairlist:
+ stridpair { $$ = new idpairlist(); $$->add($1); }
+| stridpairlist ',' stridpair
+ { $$ = $1; $$->add($3); }
+;
+
+vardec:
+ barevardec ';' { $$ = $1; }
+;
+
+barevardec:
+ type decidlist { $$ = new vardec($1->getPos(), $1, $2); }
+;
+
+type:
+ celltype { $$ = $1; }
+| name dims { $$ = new arrayTy($1, $2); }
+;
+
+celltype:
+ name { $$ = new nameTy($1); }
+;
+
+dims:
+ '[' ']' { $$ = new dimensions($1); }
+| dims '[' ']' { $$ = $1; $$->increase(); }
+;
+
+dimexps:
+ '[' exp ']' { $$ = new explist($1); $$->add($2); }
+| dimexps '[' exp ']'
+ { $$ = $1; $$->add($3); }
+;
+
+decidlist:
+ decid { $$ = new decidlist($1->getPos()); $$->add($1); }
+| decidlist ',' decid
+ { $$ = $1; $$->add($3); }
+;
+
+decid:
+ decidstart { $$ = new decid($1->getPos(), $1); }
+| decidstart ASSIGN varinit
+ { $$ = new decid($1->getPos(), $1, $3); }
+;
+
+decidstart:
+ ID { $$ = new decidstart($1.pos, $1.sym); }
+| ID dims { $$ = new decidstart($1.pos, $1.sym, $2); }
+| ID '(' ')' { $$ = new fundecidstart($1.pos, $1.sym, 0,
+ new formals($2)); }
+| ID '(' formals ')'
+ { $$ = new fundecidstart($1.pos, $1.sym, 0, $3); }
+;
+
+varinit:
+ exp { $$ = $1; }
+| arrayinit { $$ = $1; }
+;
+
+block:
+ '{' bareblock '}'
+ { $$ = $2; }
+;
+
+arrayinit:
+ '{' '}' { $$ = new arrayinit($1); }
+| '{' ELLIPSIS varinit '}'
+ { $$ = new arrayinit($1); $$->addRest($3); }
+| '{' basearrayinit '}'
+ { $$ = $2; }
+| '{' basearrayinit ELLIPSIS varinit '}'
+ { $$ = $2; $$->addRest($4); }
+;
+
+basearrayinit:
+ ',' { $$ = new arrayinit($1); }
+| varinits { $$ = $1; }
+| varinits ',' { $$ = $1; }
+;
+
+varinits:
+ varinit { $$ = new arrayinit($1->getPos());
+ $$->add($1);}
+| varinits ',' varinit
+ { $$ = $1; $$->add($3); }
+;
+
+formals:
+ baseformals { $$ = $1; }
+| baseformals ELLIPSIS formal
+ { $$ = $1; $$->addRest($3); }
+| ELLIPSIS formal { $$ = new formals($1); $$->addRest($2); }
+;
+
+baseformals:
+ formal { $$ = new formals($1->getPos()); $$->add($1); }
+| baseformals ',' formal
+ { $$ = $1; $$->add($3); }
+;
+
+explicitornot:
+ EXPLICIT { $$ = true; }
+| { $$ = false; }
+;
+
+formal:
+ explicitornot type
+ { $$ = new formal($2->getPos(), $2, 0, 0, $1); }
+| explicitornot type decidstart
+ { $$ = new formal($2->getPos(), $2, $3, 0, $1); }
+| explicitornot type decidstart ASSIGN varinit
+ { $$ = new formal($2->getPos(), $2, $3, $5, $1); }
+;
+
+fundec:
+ type ID '(' ')' blockstm
+ { $$ = new fundec($3, $1, $2.sym, new formals($3), $5); }
+| type ID '(' formals ')' blockstm
+ { $$ = new fundec($3, $1, $2.sym, $4, $6); }
+;
+
+typedec:
+ STRUCT ID block { $$ = new recorddec($1, $2.sym, $3); }
+| TYPEDEF vardec { $$ = new typedec($1, $2); }
+;
+
+slice:
+ ':' { $$ = new slice($1, 0, 0); }
+| exp ':' { $$ = new slice($2, $1, 0); }
+| ':' exp { $$ = new slice($1, 0, $2); }
+| exp ':' exp { $$ = new slice($2, $1, $3); }
+;
+
+value:
+ value '.' ID { $$ = new fieldExp($2, $1, $3.sym); }
+| name '[' exp ']' { $$ = new subscriptExp($2,
+ new nameExp($1->getPos(), $1), $3); }
+| value '[' exp ']'{ $$ = new subscriptExp($2, $1, $3); }
+| name '[' slice ']' { $$ = new sliceExp($2,
+ new nameExp($1->getPos(), $1), $3); }
+| value '[' slice ']'{ $$ = new sliceExp($2, $1, $3); }
+| name '(' ')' { $$ = new callExp($2,
+ new nameExp($1->getPos(), $1),
+ new arglist()); }
+| name '(' arglist ')'
+ { $$ = new callExp($2,
+ new nameExp($1->getPos(), $1),
+ $3); }
+| value '(' ')' { $$ = new callExp($2, $1, new arglist()); }
+| value '(' arglist ')'
+ { $$ = new callExp($2, $1, $3); }
+| '(' exp ')' %prec EXP_IN_PARENS_RULE
+ { $$ = $2; }
+| '(' name ')' %prec EXP_IN_PARENS_RULE
+ { $$ = new nameExp($2->getPos(), $2); }
+| THIS { $$ = new thisExp($1); }
+;
+
+argument:
+ exp { $$.name=0; $$.val=$1; }
+| ID ASSIGN exp { $$.name=$1.sym; $$.val=$3; }
+;
+
+arglist:
+ basearglist { $$ = $1; }
+| basearglist ELLIPSIS argument
+ { $$ = $1; $$->rest = $3; }
+| ELLIPSIS argument { $$ = new arglist(); $$->rest = $2; }
+;
+
+basearglist:
+ argument { $$ = new arglist(); $$->add($1); }
+| basearglist ',' argument
+ { $$ = $1; $$->add($3); }
+;
+
+
+exp:
+ name { $$ = new nameExp($1->getPos(), $1); }
+| value { $$ = $1; }
+| LIT { $$ = $1; }
+| STRING { $$ = new stringExp($1.pos, *$1.sym); }
+/* This is for scaling expressions such as 105cm */
+| LIT exp { $$ = new scaleExp($1->getPos(), $1, $2); }
+| '(' name ')' exp
+ { $$ = new castExp($2->getPos(), new nameTy($2), $4); }
+| '(' name dims ')' exp
+ { $$ = new castExp($2->getPos(), new arrayTy($2, $3), $5); }
+| '+' exp %prec UNARY
+ { $$ = new unaryExp($1.pos, $2, $1.sym); }
+| '-' exp %prec UNARY
+ { $$ = new unaryExp($1.pos, $2, $1.sym); }
+| LOGNOT exp { $$ = new unaryExp($1.pos, $2, $1.sym); }
+| exp '+' exp { $$ = new binaryExp($2.pos, $1, $2.sym, $3); }
+| exp '-' exp { $$ = new binaryExp($2.pos, $1, $2.sym, $3); }
+| exp '*' exp { $$ = new binaryExp($2.pos, $1, $2.sym, $3); }
+| exp '/' exp { $$ = new binaryExp($2.pos, $1, $2.sym, $3); }
+| exp '%' exp { $$ = new binaryExp($2.pos, $1, $2.sym, $3); }
+| exp '^' exp { $$ = new binaryExp($2.pos, $1, $2.sym, $3); }
+| exp LT exp { $$ = new binaryExp($2.pos, $1, $2.sym, $3); }
+| exp LE exp { $$ = new binaryExp($2.pos, $1, $2.sym, $3); }
+| exp GT exp { $$ = new binaryExp($2.pos, $1, $2.sym, $3); }
+| exp GE exp { $$ = new binaryExp($2.pos, $1, $2.sym, $3); }
+| exp EQ exp { $$ = new binaryExp($2.pos, $1, $2.sym, $3); }
+| exp NEQ exp { $$ = new binaryExp($2.pos, $1, $2.sym, $3); }
+| exp CAND exp { $$ = new andExp($2.pos, $1, $2.sym, $3); }
+| exp COR exp { $$ = new orExp($2.pos, $1, $2.sym, $3); }
+| exp CARETS exp { $$ = new binaryExp($2.pos, $1, $2.sym, $3); }
+| exp AMPERSAND exp{ $$ = new binaryExp($2.pos, $1, $2.sym, $3); }
+| exp BAR exp{ $$ = new binaryExp($2.pos, $1, $2.sym, $3); }
+| exp OPERATOR exp { $$ = new binaryExp($2.pos, $1, $2.sym, $3); }
+| exp INCR exp { $$ = new binaryExp($2.pos, $1, $2.sym, $3); }
+| NEW celltype
+ { $$ = new newRecordExp($1, $2); }
+| NEW celltype dimexps
+ { $$ = new newArrayExp($1, $2, $3, 0, 0); }
+| NEW celltype dimexps dims
+ { $$ = new newArrayExp($1, $2, $3, $4, 0); }
+| NEW celltype dims
+ { $$ = new newArrayExp($1, $2, 0, $3, 0); }
+| NEW celltype dims arrayinit
+ { $$ = new newArrayExp($1, $2, 0, $3, $4); }
+| NEW celltype '(' ')' blockstm
+ { $$ = new newFunctionExp($1, $2, new formals($3), $5); }
+| NEW celltype dims '(' ')' blockstm
+ { $$ = new newFunctionExp($1,
+ new arrayTy($2->getPos(), $2, $3),
+ new formals($4),
+ $6); }
+| NEW celltype '(' formals ')' blockstm
+ { $$ = new newFunctionExp($1, $2, $4, $6); }
+| NEW celltype dims '(' formals ')' blockstm
+ { $$ = new newFunctionExp($1,
+ new arrayTy($2->getPos(), $2, $3),
+ $5,
+ $7); }
+| exp '?' exp ':' exp
+ { $$ = new conditionalExp($2, $1, $3, $5); }
+| exp ASSIGN exp { $$ = new assignExp($2, $1, $3); }
+// Camp stuff
+| '(' exp ',' exp ')'
+ { $$ = new pairExp($1, $2, $4); }
+| '(' exp ',' exp ',' exp ')'
+ { $$ = new tripleExp($1, $2, $4, $6); }
+| '(' exp ',' exp ',' exp ',' exp ',' exp ',' exp ')'
+ { $$ = new transformExp($1, $2, $4, $6, $8, $10, $12); }
+| exp join exp %prec JOIN_PREC
+ { $2->pushFront($1); $2->pushBack($3); $$ = $2; }
+| exp dir %prec DIRTAG
+ { $2->setSide(camp::OUT);
+ joinExp *jexp =
+ new joinExp($2->getPos(), symbol::trans(".."));
+ $$=jexp;
+ jexp->pushBack($1); jexp->pushBack($2); }
+| INCR exp %prec UNARY
+ { $$ = new prefixExp($1.pos, $2, symbol::trans("+")); }
+| DASHES exp %prec UNARY
+ { $$ = new prefixExp($1.pos, $2, symbol::trans("-")); }
+/* Illegal - will be caught during translation. */
+| exp INCR %prec UNARY
+ { $$ = new postfixExp($2.pos, $1, symbol::trans("+")); }
+| exp ADD exp { $$ = new selfExp($2.pos, $1, $2.sym, $3); }
+| exp SUBTRACT exp
+ { $$ = new selfExp($2.pos, $1, $2.sym, $3); }
+| exp TIMES exp { $$ = new selfExp($2.pos, $1, $2.sym, $3); }
+| exp DIVIDE exp { $$ = new selfExp($2.pos, $1, $2.sym, $3); }
+| exp MOD exp { $$ = new selfExp($2.pos, $1, $2.sym, $3); }
+| exp EXPONENT exp
+ { $$ = new selfExp($2.pos, $1, $2.sym, $3); }
+| QUOTE '{' fileblock '}'
+ { $$ = new quoteExp($1, $3); }
+;
+
+// This verbose definition is because leaving empty as an expansion for dir
+// made a whack of reduce/reduce errors.
+join:
+ DASHES { $$ = new joinExp($1.pos,$1.sym); }
+| basicjoin %prec JOIN_PREC
+ { $$ = $1; }
+| dir basicjoin %prec JOIN_PREC
+ { $1->setSide(camp::OUT);
+ $$ = $2; $$->pushFront($1); }
+| basicjoin dir %prec JOIN_PREC
+ { $2->setSide(camp::IN);
+ $$ = $1; $$->pushBack($2); }
+| dir basicjoin dir %prec JOIN_PREC
+ { $1->setSide(camp::OUT); $3->setSide(camp::IN);
+ $$ = $2; $$->pushFront($1); $$->pushBack($3); }
+;
+
+dir:
+ '{' CURL exp '}' { $$ = new specExp($2.pos, $2.sym, $3); }
+| '{' exp '}' { $$ = new specExp($1, symbol::opTrans("spec"), $2); }
+| '{' exp ',' exp '}'
+ { $$ = new specExp($1, symbol::opTrans("spec"),
+ new pairExp($3, $2, $4)); }
+| '{' exp ',' exp ',' exp '}'
+ { $$ = new specExp($1, symbol::opTrans("spec"),
+ new tripleExp($3, $2, $4, $6)); }
+;
+
+basicjoin:
+ DOTS { $$ = new joinExp($1.pos, $1.sym); }
+| DOTS tension DOTS
+ { $$ = new joinExp($1.pos, $1.sym); $$->pushBack($2); }
+| DOTS controls DOTS
+ { $$ = new joinExp($1.pos, $1.sym); $$->pushBack($2); }
+| COLONS { $$ = new joinExp($1.pos, $1.sym); }
+| LONGDASH { $$ = new joinExp($1.pos, $1.sym); }
+;
+
+tension:
+ TENSION exp { $$ = new binaryExp($1.pos, $2, $1.sym,
+ new booleanExp($1.pos, false)); }
+| TENSION exp AND exp
+ { $$ = new ternaryExp($1.pos, $2, $1.sym, $4,
+ new booleanExp($1.pos, false)); }
+| TENSION ATLEAST exp
+ { $$ = new binaryExp($1.pos, $3, $1.sym,
+ new booleanExp($2.pos, true)); }
+| TENSION ATLEAST exp AND exp
+ { $$ = new ternaryExp($1.pos, $3, $1.sym, $5,
+ new booleanExp($2.pos, true)); }
+;
+
+controls:
+ CONTROLS exp { $$ = new unaryExp($1.pos, $2, $1.sym); }
+| CONTROLS exp AND exp
+ { $$ = new binaryExp($1.pos, $2, $1.sym, $4); }
+;
+
+stm:
+ ';' { $$ = new emptyStm($1); }
+| blockstm { $$ = $1; }
+| stmexp ';' { $$ = $1; }
+| IF '(' exp ')' stm
+ { $$ = new ifStm($1, $3, $5); }
+| IF '(' exp ')' stm ELSE stm
+ { $$ = new ifStm($1, $3, $5, $7); }
+| WHILE '(' exp ')' stm
+ { $$ = new whileStm($1, $3, $5); }
+| DO stm WHILE '(' exp ')' ';'
+ { $$ = new doStm($1, $2, $5); }
+| FOR '(' forinit ';' fortest ';' forupdate ')' stm
+ { $$ = new forStm($1, $3, $5, $7, $9); }
+| FOR '(' type ID ':' exp ')' stm
+ { $$ = new extendedForStm($1, $3, $4.sym, $6, $8); }
+| BREAK ';' { $$ = new breakStm($1); }
+| CONTINUE ';' { $$ = new continueStm($1); }
+| RETURN_ ';' { $$ = new returnStm($1); }
+| RETURN_ exp ';' { $$ = new returnStm($1, $2); }
+;
+
+stmexp:
+ exp { $$ = new expStm($1->getPos(), $1); }
+;
+
+blockstm:
+ block { $$ = new blockStm($1->getPos(), $1); }
+;
+
+forinit:
+ /* empty */ { $$ = 0; }
+| stmexplist { $$ = $1; }
+| barevardec { $$ = $1; }
+;
+
+fortest:
+ /* empty */ { $$ = 0; }
+| exp { $$ = $1; }
+;
+
+forupdate:
+ /* empty */ { $$ = 0; }
+| stmexplist { $$ = $1; }
+;
+
+stmexplist:
+ stmexp { $$ = new stmExpList($1->getPos()); $$->add($1); }
+| stmexplist ',' stmexp
+ { $$ = $1; $$->add($3); }
+;
diff --git a/Build/source/utils/asymptote/camperror.cc b/Build/source/utils/asymptote/camperror.cc
new file mode 100644
index 00000000000..d92ed7d20fd
--- /dev/null
+++ b/Build/source/utils/asymptote/camperror.cc
@@ -0,0 +1,66 @@
+/*****
+ * camperror.cc
+ * 2003/02/25 Andy Hammerlindl
+ *
+ * Provides a way for the classes in camp to report errors in
+ * computation elegantly. After running a method on a camp object that
+ * could encounter an error, the program should call camp::errors to see
+ * if any errors were encountered.
+ *****/
+
+#include <cassert>
+#include <sstream>
+
+#include "camperror.h"
+#include "vm.h"
+#include "errormsg.h"
+
+namespace camp {
+
+// Used internally to report an error in an operation.
+void reportError(const string& desc)
+{
+ em.runtime(vm::getPos());
+ em << desc;
+ em.sync();
+ try {
+ throw handled_error();
+ } catch(handled_error) {
+ }
+}
+
+// Used internally to report a warning in an operation.
+void reportWarning(const string& desc)
+{
+ em.warning(vm::getPos());
+ em << desc;
+ em.sync();
+}
+
+void reportFatal(const string& desc)
+{
+ em.fatal(vm::getPos());
+ em << desc;
+ em.sync();
+ try {
+ throw quit();
+ } catch(handled_error) {
+ }
+}
+
+void reportError(const ostringstream& desc)
+{
+ reportError(desc.str());
+}
+
+void reportWarning(const ostringstream& desc)
+{
+ reportWarning(desc.str());
+}
+
+void reportFatal(const ostringstream& desc)
+{
+ reportFatal(desc.str());
+}
+
+} // namespace camp
diff --git a/Build/source/utils/asymptote/camperror.h b/Build/source/utils/asymptote/camperror.h
new file mode 100644
index 00000000000..b6adaaf63fe
--- /dev/null
+++ b/Build/source/utils/asymptote/camperror.h
@@ -0,0 +1,34 @@
+/*****
+ * camperror.h
+ * 2003/02/25 Andy Hammerlindl
+ *
+ * Provides a way for the classes in camp to report errors in
+ * computation elegantly. After running a method on a camp object that
+ * could encounter an error, the program should call camp::errors to see
+ * if any errors were encountered.
+ *****/
+
+#ifndef CAMPERROR_H
+#define CAMPERROR_H
+
+#include <iostream>
+
+#include "common.h"
+
+namespace camp {
+
+// Used internally to report an error in an operation.
+void reportError(const string& desc);
+void reportError(const ostringstream& desc);
+
+void reportWarning(const string& desc);
+void reportWarning(const ostringstream& desc);
+
+void reportFatal(const string& desc);
+void reportFatal(const ostringstream& desc);
+
+inline std::ostream& newl(std::ostream& s) {s << '\n'; return s;}
+
+} // namespace camp
+
+#endif
diff --git a/Build/source/utils/asymptote/castop.h b/Build/source/utils/asymptote/castop.h
new file mode 100644
index 00000000000..714dfdb0bae
--- /dev/null
+++ b/Build/source/utils/asymptote/castop.h
@@ -0,0 +1,179 @@
+/*****
+ * castop.h
+ * Tom Prince 2005/3/18
+ *
+ * Defines some runtime functions used by the stack machine.
+ *
+ *****/
+
+#ifndef CASTOP_H
+#define CASTOP_H
+
+#include <cfloat>
+
+#include "common.h"
+#include "stack.h"
+#include "fileio.h"
+#include "lexical.h"
+#include "mathop.h"
+#include "array.h"
+
+namespace run {
+
+using vm::read;
+using vm::pop;
+
+template<class T, class S>
+void cast(vm::stack *s)
+{
+ s->push((S) pop<T>(s));
+}
+
+void castDoubleInt(vm::stack *s)
+{
+ double x=pop<double>(s);
+ s->push(Intcast(x));
+}
+
+template<class T>
+void stringCast(vm::stack *s)
+{
+ ostringstream buf;
+ buf.precision(DBL_DIG);
+ buf << pop<T>(s);
+ s->push(buf.str());
+}
+
+template<class T>
+void castString(vm::stack *s)
+{
+ string *S=pop<string*>(s);
+ if(S->empty()) {
+ T x=0;
+ s->push(x);
+ } else {
+ try {
+ s->push(lexical::cast<T>(*S));
+ } catch (lexical::bad_cast&) {
+ ostringstream buf;
+ buf << "invalid cast from string \"" << *S << "\"";
+ vm::error(buf);
+ }
+ }
+}
+
+template<class T, class S>
+void arrayToArray(vm::stack *s)
+{
+ vm::array *a = pop<vm::array*>(s);
+ checkArray(a);
+ size_t size=(size_t) a->size();
+ vm::array *c=new vm::array(size);
+ for(size_t i=0; i < size; i++)
+ (*c)[i]=(S) read<T>(a,i);
+ s->push(c);
+}
+
+template<class T>
+void read(vm::stack *s)
+{
+ camp::file *f = pop<camp::file*>(s);
+ T val=T();
+ if(f->isOpen()) {
+ f->read(val);
+ if(f->LineMode()) f->nexteol();
+ if(interact::interactive) f->purgeStandard(val);
+ }
+ s->push(val);
+}
+
+inline Int Limit(Int nx) {return nx == 0 ? Int_MAX : nx;}
+inline void reportEof(camp::file *f, Int count)
+{
+ if(count > 0) {
+ ostringstream buf;
+ buf << "EOF after reading " << count
+ << " values from file '" << f->filename() << "'.";
+ vm::error(buf);
+ }
+}
+
+template<class T>
+void readArray(vm::stack *s)
+{
+ camp::file *f = pop<camp::file*>(s);
+ vm::array *c=new vm::array(0);
+ if(f->isOpen()) {
+ Int nx=f->Nx();
+ if(nx == -2) {f->read(nx); f->Nx(-1); if(nx == 0) {s->push(c); return;}}
+ Int ny=f->Ny();
+ if(ny == -2) {f->read(ny); f->Ny(-1); if(ny == 0) {s->push(c); return;}}
+ Int nz=f->Nz();
+ if(nz == -2) {f->read(nz); f->Nz(-1); if(nz == 0) {s->push(c); return;}}
+ T v;
+ if(nx >= 0) {
+ for(Int i=0; i < Limit(nx); i++) {
+ if(ny >= 0) {
+ vm::array *ci=new vm::array(0);
+ for(Int j=0; j < Limit(ny); j++) {
+ if(nz >= 0) {
+ vm::array *cij=new vm::array(0);
+ bool break2=false;
+ for(Int k=0; k < Limit(nz); k++) {
+ f->read(v);
+ if(f->error()) {
+ if(nx && ny && nz) reportEof(f,(i*ny+j)*nz+k);
+ s->push(c);
+ return;
+ }
+ if(k == 0) {
+ if(j == 0) c->push(ci);
+ ci->push(cij);
+ }
+ cij->push(v);
+ if(f->LineMode() && f->nexteol()) {
+ if(f->nexteol()) break2=true;
+ break;
+ }
+ }
+ if(break2) break;
+ } else {
+ f->read(v);
+ if(f->error()) {
+ if(nx && ny) reportEof(f,i*ny+j);
+ s->push(c);
+ return;
+ }
+ if(j == 0) c->push(ci);
+ ci->push(v);
+ if(f->LineMode() && f->nexteol()) break;
+ }
+ }
+ } else {
+ f->read(v);
+ if(f->error()) {
+ if(nx) reportEof(f,i);
+ s->push(c);
+ return;
+ }
+ c->push(v);
+ if(f->LineMode() && f->nexteol()) break;
+ }
+ }
+ } else {
+ for(;;) {
+ f->read(v);
+ if(f->error()) break;
+ c->push(v);
+ if(f->LineMode() && f->nexteol()) break;
+ }
+ }
+ if(interact::interactive) f->purgeStandard(v);
+ }
+ s->push(c);
+}
+
+} // namespace run
+
+#endif // CASTOP_H
+
diff --git a/Build/source/utils/asymptote/coder.cc b/Build/source/utils/asymptote/coder.cc
new file mode 100644
index 00000000000..01d3ff3a58f
--- /dev/null
+++ b/Build/source/utils/asymptote/coder.cc
@@ -0,0 +1,278 @@
+/*****
+ * coder.cc
+ * Andy Hammerlindl 2004/11/06
+ *
+ * Handles encoding of syntax into programs. It's methods are called by
+ * abstract syntax objects during translation to construct the virtual machine
+ * code.
+ *****/
+
+#include <utility>
+
+#include "errormsg.h"
+#include "coder.h"
+#include "genv.h"
+#include "entry.h"
+
+using namespace sym;
+using namespace types;
+
+namespace trans {
+
+namespace {
+function *inittype();
+function *bootuptype();
+}
+
+// The dummy environment of the global environment.
+// Used purely for global variables and static code blocks of file
+// level modules.
+coder::coder(modifier sord)
+ : level(new frame(0, 0)),
+ recordLevel(0),
+ recordType(0),
+ isCodelet(false),
+ l(new vm::lambda),
+ funtype(bootuptype()),
+ parent(0),
+ sord(sord),
+ perm(DEFAULT_PERM),
+ program(new vm::program),
+ numLabels(0),
+ curPos(nullPos)
+{
+ sord_stack.push(sord);
+ encodeAllocInstruction();
+}
+
+// Defines a new function environment.
+coder::coder(function *t, coder *parent, modifier sord, bool reframe)
+ : level(reframe ? new frame(parent->getFrame(), t->sig.getNumFormals()) :
+ parent->getFrame()),
+ recordLevel(parent->recordLevel),
+ recordType(parent->recordType),
+ isCodelet(!reframe),
+ l(new vm::lambda),
+ funtype(t),
+ parent(parent),
+ sord(sord),
+ perm(DEFAULT_PERM),
+ program(new vm::program),
+ numLabels(0),
+ curPos(nullPos)
+{
+ sord_stack.push(sord);
+ encodeAllocInstruction();
+}
+
+// Start encoding the body of the record. The function being encoded
+// is the record's initializer.
+coder::coder(record *t, coder *parent, modifier sord)
+ : level(t->getLevel()),
+ recordLevel(t->getLevel()),
+ recordType(t),
+ isCodelet(false),
+ l(t->getInit()),
+ funtype(inittype()),
+ parent(parent),
+ sord(sord),
+ perm(DEFAULT_PERM),
+ program(new vm::program),
+ numLabels(0),
+ curPos(nullPos)
+{
+ sord_stack.push(sord);
+ encodeAllocInstruction();
+}
+
+coder coder::newFunction(function *t, modifier sord)
+{
+ return coder(t, this, sord);
+}
+
+coder coder::newCodelet()
+{
+ return coder(new function(primVoid()), this, DEFAULT_DYNAMIC, false);
+}
+
+record *coder::newRecord(symbol *id)
+{
+ frame *underlevel = getFrame();
+
+ frame *level = new frame(underlevel, 0);
+
+ record *r = new record(id, level);
+
+ return r;
+}
+
+coder coder::newRecordInit(record *r, modifier sord)
+{
+ return coder(r, this, sord);
+}
+
+
+bool coder::encode(frame *f)
+{
+ frame *toplevel = getFrame();
+
+ if (f == 0) {
+ encode(inst::constpush,(item)0);
+ }
+ else if (f == toplevel) {
+ encode(inst::pushclosure);
+ }
+ else {
+ encode(inst::varpush,0);
+
+ frame *level = toplevel->getParent();
+ while (level != f) {
+ if (level == 0)
+ // Frame request was in an improper scope.
+ return false;
+
+ encode(inst::fieldpush,0);
+
+ level = level->getParent();
+ }
+ }
+
+ return true;
+}
+
+bool coder::encode(frame *dest, frame *top)
+{
+ //cerr << "coder::encode()\n";
+
+ if (dest == 0) {
+ encode(inst::pop);
+ encode(inst::constpush,(item)0);
+ }
+ else {
+ frame *level = top;
+ while (level != dest) {
+ if (level == 0) {
+ // Frame request was in an improper scope.
+ //cerr << "failed\n";
+
+ return false;
+ }
+
+ encode(inst::fieldpush,0);
+
+ level = level->getParent();
+ }
+ }
+
+ //cerr << "succeeded\n";
+ return true;
+}
+
+Int coder::defLabel()
+{
+ if (isStatic())
+ return parent->defLabel();
+
+ return defLabel(numLabels++);
+}
+
+Int coder::defLabel(Int label)
+{
+ if (isStatic())
+ return parent->defLabel(label);
+
+ assert(label >= 0 && label < numLabels);
+
+ defs.insert(std::make_pair(label,program->end()));
+
+ std::multimap<Int,vm::program::label>::iterator p = uses.lower_bound(label);
+ while (p != uses.upper_bound(label)) {
+ p->second->ref = program->end();
+ ++p;
+ }
+
+ return label;
+}
+
+void coder::useLabel(inst::opcode op, Int label)
+{
+ if (isStatic())
+ return parent->useLabel(op,label);
+
+ std::map<Int,vm::program::label>::iterator p = defs.find(label);
+ if (p != defs.end()) {
+ encode(op,p->second);
+ } else {
+ // Not yet defined
+ uses.insert(std::make_pair(label,program->end()));
+ encode(op);
+ }
+}
+
+Int coder::fwdLabel()
+{
+ if (isStatic())
+ return parent->fwdLabel();
+
+ // Create a new label without specifying its position.
+ return numLabels++;
+}
+
+void coder::markPos(position pos)
+{
+ curPos = pos;
+}
+
+// When translating the function is finished, this ties up loose ends
+// and returns the lambda.
+vm::lambda *coder::close() {
+ // These steps must be done dynamically, not statically.
+ sord = EXPLICIT_DYNAMIC;
+ sord_stack.push(sord);
+
+ // Add a return for void types; may be redundant.
+ if (funtype->result->kind == types::ty_void)
+ encode(inst::ret);
+
+ l->code = program;
+
+ l->params = level->getNumFormals();
+
+ // Now that we know how many variables the function has, allocate space for
+ // all of them at the start of the function.
+ finishAlloc();
+
+ sord_stack.pop();
+ sord = sord_stack.top();
+
+ return l;
+}
+
+void coder::closeRecord()
+{
+ // Put record into finished state.
+ encode(inst::pushclosure);
+ close();
+}
+
+bool coder::isRecord()
+{
+ return (funtype==inittype());
+}
+
+namespace {
+function *inittype()
+{
+ static function t(types::primVoid());
+ return &t;
+}
+
+function *bootuptype()
+{
+ static function t(types::primVoid());
+ return &t;
+}
+} // private
+
+} // namespace trans
+
diff --git a/Build/source/utils/asymptote/coder.h b/Build/source/utils/asymptote/coder.h
new file mode 100644
index 00000000000..331ed3d9952
--- /dev/null
+++ b/Build/source/utils/asymptote/coder.h
@@ -0,0 +1,382 @@
+/*****
+ * coder.h
+ * Andy Hammerlindl 2004/11/06
+ *
+ * Handles encoding of syntax into programs. It's methods are called by
+ * abstract syntax objects during translation to construct the virtual machine
+ * code.
+ *****/
+
+#ifndef CODER_H
+#define CODER_H
+
+#include "errormsg.h"
+#include "entry.h"
+#include "types.h"
+#include "record.h"
+#include "frame.h"
+#include "program.h"
+#include "util.h"
+#include "modifier.h"
+
+namespace trans {
+
+using sym::symbol;
+using types::ty;
+using types::function;
+using types::record;
+
+using vm::bltin;
+using vm::inst;
+using vm::item;
+
+class coder {
+ // The frame of the function we are currently encoding. This keeps
+ // track of local variables, and parameters with respect to the stack.
+ frame *level;
+
+ // The frame of the enclosing record that the "this" expression yields. ie.
+ // the highest frame that is a record, not a function.
+ frame *recordLevel;
+
+ // The type of the enclosing record. Also needed for the "this" expression.
+ record *recordType;
+
+ // Are we translating a codelet?
+ bool isCodelet;
+
+ // The lambda being constructed. In some cases, this lambda is needed
+ // before full translation of the function, so it is stored,
+ // incomplete, here.
+ vm::lambda *l;
+
+ // The type of the function being translated.
+ const function *funtype;
+
+ // The enclosing environment. Null if this is a file-level module.
+ coder *parent;
+
+ // The mode of encoding, either static or dynamic. sord is used as an
+ // acronym for Static OR Dynamic.
+ // Once something is static, no amount of dynamic modifiers can change
+ // that, so once a stack is EXPLICIT_STATIC, additional modifiers will
+ // be pushed on as EXPLICIT_STATIC.
+ modifier sord;
+ std::stack<modifier> sord_stack;
+
+ // What permissions will be given to a new access.
+ // TODO: Ensure private fields don't show up calling lookup for a
+ // record.
+ permission perm;
+
+ // The function code as its being written. Code points to next place in
+ // array to write.
+ vm::program *program;
+
+ // Keeps track of labels and writes in memory addresses as they're defined.
+ // This way a label can be used before its address is known.
+ std::map<Int,vm::program::label> defs;
+ std::multimap<Int,vm::program::label> uses;
+ Int numLabels;
+
+ // The loop constructs allocate nested frames, in case variables in an
+ // iteration escape in a closure. This stack keeps track of where the
+ // variables are allocated, so the size of the frame can be encoded. At the
+ // start, it just holds the label of the first instruction of the lambda, as
+ // this is where space for the variables of the function is allocated.
+ std::stack<vm::program::label> allocs;
+
+ // Loops need to store labels to where break and continue statements
+ // should pass control to. Since loops can be nested, this needs to
+ // be stored as a stack.
+ std::stack<Int> breakLabels;
+ std::stack<Int> continueLabels;
+
+ // Current File Position
+ position curPos;
+
+public:
+ // Define a new function coder. If reframe is true, this gives the function
+ // its own frame, which is the usual (sensible) thing to do. It is set to
+ // false for a line-at-a-time codelet, where variables should be allocated in
+ // the lower frame.
+ coder(function *t, coder *parent, modifier sord = DEFAULT_DYNAMIC,
+ bool reframe=true);
+
+ // Start encoding the body of the record. The function being encoded
+ // is the record's initializer.
+ coder(record *t, coder *parent, modifier sord = DEFAULT_DYNAMIC);
+
+ coder(modifier sord = DEFAULT_DYNAMIC);
+
+ coder(const coder&);
+
+ /* Add a static or dynamic modifier. */
+ void pushModifier(modifier s)
+ {
+ /* Default setting should only be used in the constructor. */
+ assert(s != DEFAULT_STATIC && s != DEFAULT_DYNAMIC);
+
+ /* Non-default static overrules. */
+ if (sord != EXPLICIT_STATIC)
+ sord = s;
+
+ sord_stack.push(sord);
+ }
+
+ /* Tests if encoding mode is currently static. */
+ bool isStatic()
+ {
+ switch(sord) {
+ case DEFAULT_STATIC:
+ case EXPLICIT_STATIC:
+ return true;
+ case DEFAULT_DYNAMIC:
+ case EXPLICIT_DYNAMIC:
+ return false;
+ default:
+ assert(False);
+ return false;
+ }
+ }
+
+
+ /* Remove a modifier. */
+ void popModifier()
+ {
+ assert(!sord_stack.empty());
+ sord_stack.pop();
+
+ assert(!sord_stack.empty());
+ sord = sord_stack.top();
+ }
+
+ /* Set/get/clear permissions. */
+ void setPermission(permission p)
+ {
+ perm = p;
+ }
+ permission getPermission()
+ {
+ return perm;
+ }
+ void clearPermission()
+ {
+ perm = DEFAULT_PERM;
+ }
+
+
+ // Says what the return type of the function is.
+ ty *getReturnType() {
+ return funtype->result;
+ }
+
+ bool isRecord();
+
+ // Creates a new coder to handle the translation of a new function.
+ coder newFunction(function *t, modifier sord=DEFAULT_DYNAMIC);
+
+ // Creates a new record type.
+ record *newRecord(symbol *id);
+
+ // Create a coder for the initializer of the record.
+ coder newRecordInit(record *r, modifier sord=DEFAULT_DYNAMIC);
+
+ // Create a coder for translating a small piece of code. Used for
+ // line-at-a-time mode.
+ coder newCodelet();
+
+ frame *getFrame()
+ {
+ if (isStatic() && !isTopLevel()) {
+ assert(parent->getFrame());
+ return parent->getFrame();
+ }
+ else
+ return level;
+ }
+
+ // Tests if the function or record with the given frame is currently under
+ // translation (either by this coder or an ancestor).
+ bool inTranslation(frame *f) {
+ frame *level=this->level;
+ while (level) {
+ if (f==level)
+ return true;
+ level=level->getParent();
+ }
+ return parent && parent->inTranslation(f);
+ }
+
+ // Allocates space in the function or record frame for a new local variable.
+ access *allocLocal()
+ {
+ return getFrame()->allocLocal();
+ }
+
+ // Get the access in the frame for a specified formal parameter.
+ access *accessFormal(Int index)
+ {
+ // NOTE: This hasn't been extended to handle frames for loops, but is
+ // currently only called when starting to translate a function, where there
+ // can be no loops.
+ return level->accessFormal(index);
+ }
+
+ // Checks if we are at the top level, which is true for a file-level module or
+ // a codelet.
+ bool isTopLevel() {
+ return parent==0 || isCodelet;
+ }
+
+ // The encode functions add instructions and operands on to the code array.
+private:
+ void encode(inst i)
+ {
+ i.pos = curPos;
+ // Static code is put into the enclosing coder, unless we are translating a
+ // codelet.
+ if (isStatic() && !isTopLevel()) {
+ assert(parent);
+ parent->encode(i);
+ }
+ else {
+ program->encode(i);
+ }
+ }
+
+public:
+ void encode(inst::opcode op)
+ {
+ inst i; i.op = op; i.pos = nullPos;
+ encode(i);
+ }
+ void encode(inst::opcode op, item it)
+ {
+ inst i; i.op = op; i.pos = nullPos; i.ref = it;
+ encode(i);
+ }
+
+ // Puts the requested frame on the stack. If the frame is not that of
+ // this coder or its ancestors, false is returned.
+ bool encode(frame *f);
+
+ // Puts the frame corresponding to the expression "this" on the stack.
+ bool encodeThis()
+ {
+ assert(recordLevel);
+ return encode(recordLevel);
+ }
+
+ // An access that encodes the frame corresponding to "this".
+ access *thisLocation()
+ {
+ assert(recordLevel);
+ return new frameAccess(recordLevel);
+ }
+
+ // Returns the type of the enclosing record.
+ record *thisType()
+ {
+ return recordType;
+ }
+
+ // Puts the 'dest' frame on the stack, assuming the frame 'top' is on
+ // top of the stack. If 'dest' is not an ancestor frame of 'top',
+ // false is returned.
+ bool encode(frame *dest, frame *top);
+
+
+ // Assigns a handle to the current point in the list of stack
+ // instructions and returns that handle.
+ Int defLabel();
+
+ // Sets the handle given by label to the current point in the list of
+ // instructions.
+ Int defLabel(Int label);
+
+ // Encodes the address pointed to by the handle label into the
+ // sequence of instructions. This is useful for a jump instruction to
+ // jump to where a label was defined.
+ void useLabel(inst::opcode op, Int label);
+
+ // If an address has to be used for a jump instruction before it is
+ // actually encoded, a handle can be given to it by this function.
+ // When that handle's label is later defined, the proper address will
+ // be inserted into the code where the handle was used.
+ Int fwdLabel();
+
+ void pushBreak(Int label) {
+ breakLabels.push(label);
+ }
+ void pushContinue(Int label) {
+ continueLabels.push(label);
+ }
+ void popBreak() {
+ breakLabels.pop();
+ }
+ void popContinue() {
+ continueLabels.pop();
+ }
+ bool encodeBreak() {
+ if (breakLabels.empty())
+ return false;
+ else {
+ useLabel(inst::jmp,breakLabels.top());
+ return true;
+ }
+ }
+ bool encodeContinue() {
+ if (continueLabels.empty())
+ return false;
+ else {
+ useLabel(inst::jmp,continueLabels.top());
+ return true;
+ }
+ }
+
+private:
+ void encodeAllocInstruction() {
+ encode(inst::alloc, 0);
+ allocs.push(--program->end());
+ }
+
+ void finishAlloc() {
+ allocs.top()->ref = level->size();
+ allocs.pop();
+ }
+
+public:
+ void encodePushFrame() {
+ encode(inst::pushframe);
+ level = new frame(level, 0);
+
+ encodeAllocInstruction();
+ }
+
+ void encodePopFrame() {
+ finishAlloc();
+
+ encode(inst::popframe);
+ level = level->getParent();
+ }
+
+ // Adds an entry into the position list, linking the given point in the
+ // source code to the current position in the virtual machine code. This is
+ // used to print positions at runtime.
+ void markPos(position pos);
+
+ // When translation of the function is finished, this ties up loose ends
+ // and returns the lambda.
+ vm::lambda *close();
+
+ // Finishes translating the initializer of a record.
+ void closeRecord();
+
+private: // Non-copyable
+ void operator=(const coder&);
+};
+
+} // namespace trans
+
+#endif
diff --git a/Build/source/utils/asymptote/coenv.cc b/Build/source/utils/asymptote/coenv.cc
new file mode 100644
index 00000000000..e281b666962
--- /dev/null
+++ b/Build/source/utils/asymptote/coenv.cc
@@ -0,0 +1,47 @@
+/*****
+ * coenv.cc
+ * Andy Hammerlindl 2004/11/18
+ *
+ * Bundles the env and coder classes needed in translating the abstract syntax
+ * tree. It also also implements some functions that involve both the env and
+ * coder, such as implicitCast().
+ *****/
+
+#include "coenv.h"
+
+namespace trans {
+
+// Prints out error messages for the cast methods.
+static inline void castError(position pos, ty *target, ty *source)
+{
+ em.error(pos);
+ em << "cannot convert \'" << *source
+ << "\' to \'" << *target << "\'";
+}
+
+static inline bool accessCast(position pos, ty *target, ty *source,
+ access *a, coder& c)
+{
+ if (a) {
+ a->encode(CALL, pos, c);
+ return true;
+ }
+ else {
+ castError(pos, target, source);
+ return false;
+ }
+}
+
+bool coenv::implicitCast(position pos, ty *target, ty *source)
+{
+ return accessCast(pos, target, source,
+ e.lookupCast(target, source, symbol::castsym), c);
+}
+
+bool coenv::explicitCast(position pos, ty *target, ty *source)
+{
+ return accessCast(pos, target, source,
+ e.lookupCast(target, source, symbol::ecastsym), c);
+}
+
+}
diff --git a/Build/source/utils/asymptote/coenv.h b/Build/source/utils/asymptote/coenv.h
new file mode 100644
index 00000000000..b8d751570e9
--- /dev/null
+++ b/Build/source/utils/asymptote/coenv.h
@@ -0,0 +1,40 @@
+/*****
+ * coenv.h
+ * Andy Hammerlindl 2004/11/18
+ *
+ * Bundles the env and coder classes needed in translating the abstract syntax
+ * tree. It also also implements some functions that involve both the env and
+ * coder, such as implicitCast().
+ *****/
+
+#ifndef COENV_H
+#define COENV_H
+
+#include "env.h"
+#include "coder.h"
+
+namespace trans {
+
+class coenv {
+public:
+ coder &c;
+ env &e;
+
+ coenv(coder &c, env &e)
+ : c(c), e(e) {}
+
+ // This is used when an expression of type source needs to be an
+ // expression of type target.
+ // If it is allowed, the casting instructions (if any) will be added.
+ // Otherwise, an appropriate error message will be printed.
+ bool implicitCast(position pos, ty *target, ty *source);
+ bool explicitCast(position pos, ty *target, ty *source);
+
+ void add(protoenv &source, varEntry *qualifier) {
+ e.add(source, qualifier, c);
+ }
+};
+
+} // namespace trans
+
+#endif
diff --git a/Build/source/utils/asymptote/common.h b/Build/source/utils/asymptote/common.h
new file mode 100644
index 00000000000..f2796f5241d
--- /dev/null
+++ b/Build/source/utils/asymptote/common.h
@@ -0,0 +1,57 @@
+/****
+ * common.h
+ *
+ * Definitions common to all files.
+ *****/
+
+#ifndef COMMON_H
+#define COMMON_H
+
+#include <iostream>
+#include <climits>
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#if defined(HAVE_LIBGLU) && defined(HAVE_LIBGLUT)
+#define HAVE_LIBGL
+#endif
+
+#ifdef HAVE_LIBPTHREAD
+#include <pthread.h>
+#endif
+
+#include "memory.h"
+
+#if defined(HAVE_LONG_LONG) && defined(LONG_LONG_MAX) && defined(LONG_LONG_MIN)
+#define Int_MAX LONG_LONG_MAX
+#define Int_MIN LONG_LONG_MIN
+typedef long long Int;
+#else
+#undef HAVE_LONG_LONG
+#ifdef HAVE_LONG
+#define Int_MAX LONG_MAX
+#define Int_MIN LONG_MIN
+typedef long Int;
+#else
+#define Int_MAX INT_MAX
+#define Int_MIN INT_MIN
+#define Int int
+#endif
+#endif
+
+using std::cout;
+using std::cin;
+using std::cerr;
+using std::endl;
+using std::istream;
+using std::ostream;
+
+using mem::string;
+using mem::stringstream;
+using mem::istringstream;
+using mem::ostringstream;
+using mem::stringbuf;
+
+#endif
diff --git a/Build/source/utils/asymptote/config.h.in b/Build/source/utils/asymptote/config.h.in
new file mode 100644
index 00000000000..ef1b416889a
--- /dev/null
+++ b/Build/source/utils/asymptote/config.h.in
@@ -0,0 +1,221 @@
+/* config.h.in. Generated from configure.ac by autoheader. */
+
+/* Define if building universal (internal helper macro) */
+#undef AC_APPLE_UNIVERSAL_BUILD
+
+/* Directory for documentation */
+#undef ASYMPTOTE_DOCDIR
+
+/* System directory for global .asy files */
+#undef ASYMPTOTE_SYSDIR
+
+/* Define if gluNurbsCallback expects a variadic function. */
+#undef GLU_TESS_CALLBACK_TRIPLEDOT
+
+/* Define to 1 if you have the <curses.h> header file. */
+#undef HAVE_CURSES_H
+
+/* Define to 1 if you have the `dup2' function. */
+#undef HAVE_DUP2
+
+/* Define to 1 if you have the <fenv.h> header file. */
+#undef HAVE_FENV_H
+
+/* Define to 1 if you have the `floor' function. */
+#undef HAVE_FLOOR
+
+/* Define to 1 if you have the `fork' function. */
+#undef HAVE_FORK
+
+/* Define to 1 if you have the <fpu_control.h> header file. */
+#undef HAVE_FPU_CONTROL_H
+
+/* Define to 1 if fseeko (and presumably ftello) exists and is declared. */
+#undef HAVE_FSEEKO
+
+/* Define if getopt.h is the GNU version */
+#undef HAVE_GNU_GETOPT_H
+
+/* Define to 1 if you have the <inttypes.h> header file. */
+#undef HAVE_INTTYPES_H
+
+/* Define to 1 if you have the `curses' library (-lcurses). */
+#undef HAVE_LIBCURSES
+
+/* Define to 1 if you have the `fftw3' library (-lfftw3). */
+#undef HAVE_LIBFFTW3
+
+/* Define to 1 if you have the `GLU' library (-lGLU). */
+#undef HAVE_LIBGLU
+
+/* Define to 1 if you have the `glut' library (-lglut). */
+#undef HAVE_LIBGLUT
+
+/* Define to 1 if you have the 'gsl' library (-lgsl). */
+#undef HAVE_LIBGSL
+
+/* Define to 1 if you have the <libintl.h> header file. */
+#undef HAVE_LIBINTL_H
+
+/* Define to 1 if you have the `m' library (-lm). */
+#undef HAVE_LIBM
+
+/* Define to 1 if you have the `pthread' library (-lpthread). */
+#undef HAVE_LIBPTHREAD
+
+/* Define to 1 if you have the `readline' library (-lreadline). */
+#undef HAVE_LIBREADLINE
+
+/* Define to 1 if you have the `sigsegv' library (-lsigsegv). */
+#undef HAVE_LIBSIGSEGV
+
+/* Define to 1 if you have the `z' library (-lz). */
+#undef HAVE_LIBZ
+
+/* Define to 1 if the system has the type `long'. */
+#undef HAVE_LONG
+
+/* Define to 1 if the system has the type `long long'. */
+#undef HAVE_LONG_LONG
+
+/* Define to 1 if you have the <memory.h> header file. */
+#undef HAVE_MEMORY_H
+
+/* Define to 1 if you have the `memset' function. */
+#undef HAVE_MEMSET
+
+/* Define to 1 if you have the <ncurses/curses.h> header file. */
+#undef HAVE_NCURSES_CURSES_H
+
+/* Define to 1 if you have the <ncurses.h> header file. */
+#undef HAVE_NCURSES_H
+
+/* Define to 1 if you have the `pow' function. */
+#undef HAVE_POW
+
+/* Define to 1 if the system has the type `ptrdiff_t'. */
+#undef HAVE_PTRDIFF_T
+
+/* Define if you have a working <rpc/rpc.h> header file */
+#undef HAVE_RPC_RPC_H
+
+/* Define to 1 if you have the `sqrt' function. */
+#undef HAVE_SQRT
+
+/* Define to 1 if you have the <stddef.h> header file. */
+#undef HAVE_STDDEF_H
+
+/* Define to 1 if you have the <stdint.h> header file. */
+#undef HAVE_STDINT_H
+
+/* Define to 1 if you have the <stdlib.h> header file. */
+#undef HAVE_STDLIB_H
+
+/* Define to 1 if you have the `strchr' function. */
+#undef HAVE_STRCHR
+
+/* Define to 1 if you have the `strftime' function. */
+#undef HAVE_STRFTIME
+
+/* Define to 1 if you have the <strings.h> header file. */
+#undef HAVE_STRINGS_H
+
+/* Define to 1 if you have the <string.h> header file. */
+#undef HAVE_STRING_H
+
+/* Define to 1 if you have the `strptime' function. */
+#undef HAVE_STRPTIME
+
+/* Define if the function strptime is declared in <time.h> */
+#undef HAVE_STRPTIME_DECL
+
+/* Define to 1 if you have the <sys/stat.h> header file. */
+#undef HAVE_SYS_STAT_H
+
+/* Define to 1 if you have the <sys/types.h> header file. */
+#undef HAVE_SYS_TYPES_H
+
+/* Define to 1 if you have <sys/wait.h> that is POSIX.1 compatible. */
+#undef HAVE_SYS_WAIT_H
+
+/* Define to 1 if you have the `tgamma' function. */
+#undef HAVE_TGAMMA
+
+/* Define to 1 if you have the <unistd.h> header file. */
+#undef HAVE_UNISTD_H
+
+/* Define to 1 if you have the `vfork' function. */
+#undef HAVE_VFORK
+
+/* Define to 1 if you have the <vfork.h> header file. */
+#undef HAVE_VFORK_H
+
+/* Define to 1 if `fork' works. */
+#undef HAVE_WORKING_FORK
+
+/* Define to 1 if `vfork' works. */
+#undef HAVE_WORKING_VFORK
+
+/* Define to the address where bug reports for this package should be sent. */
+#undef PACKAGE_BUGREPORT
+
+/* Define to the full name of this package. */
+#undef PACKAGE_NAME
+
+/* Define to the full name and version of this package. */
+#undef PACKAGE_STRING
+
+/* Define to the one symbol short name of this package. */
+#undef PACKAGE_TARNAME
+
+/* Define to the version of this package. */
+#undef PACKAGE_VERSION
+
+/* Define as the return type of signal handlers (`int' or `void'). */
+#undef RETSIGTYPE
+
+/* Define to 1 if you have the ANSI C header files. */
+#undef STDC_HEADERS
+
+/* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most
+ significant byte first (like Motorola and SPARC, unlike Intel). */
+#if defined AC_APPLE_UNIVERSAL_BUILD
+# if defined __BIG_ENDIAN__
+# define WORDS_BIGENDIAN 1
+# endif
+#else
+# ifndef WORDS_BIGENDIAN
+# undef WORDS_BIGENDIAN
+# endif
+#endif
+
+/* Define if words are stored with the most significant byte first. */
+#undef WORDS_BIG_ENDIAN
+
+/* Define if words are stored with the least significant byte first. */
+#undef WORDS_LITTLE_ENDIAN
+
+/* Define to 1 if `lex' declares `yytext' as a `char *' by default, not a
+ `char[]'. */
+#undef YYTEXT_POINTER
+
+/* Define to 1 to make fseeko visible on some hosts (e.g. glibc 2.2). */
+#undef _LARGEFILE_SOURCE
+
+/* Define to empty if `const' does not conform to ANSI C. */
+#undef const
+
+/* Define to `__inline__' or `__inline' if that's what the C compiler
+ calls it, or to nothing if 'inline' is not supported under any name. */
+#ifndef __cplusplus
+#undef inline
+#endif
+
+/* Define to `int' if <sys/types.h> does not define. */
+#undef pid_t
+
+/* Define to `unsigned int' if <sys/types.h> does not define. */
+#undef size_t
+
+/* Define as `fork' if `vfork' does not work. */
+#undef vfork
diff --git a/Build/source/utils/asymptote/configure b/Build/source/utils/asymptote/configure
new file mode 100755
index 00000000000..bc5b3a38df7
--- /dev/null
+++ b/Build/source/utils/asymptote/configure
@@ -0,0 +1,12186 @@
+#! /bin/sh
+# Guess values for system-dependent variables and create Makefiles.
+# Generated by GNU Autoconf 2.63 for Asymptote 1.72.
+#
+# Report bugs to <http://sourceforge.net/projects/asymptote>.
+#
+# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001,
+# 2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
+# This configure script is free software; the Free Software Foundation
+# gives unlimited permission to copy, distribute and modify it.
+## --------------------- ##
+## M4sh Initialization. ##
+## --------------------- ##
+
+# Be more Bourne compatible
+DUALCASE=1; export DUALCASE # for MKS sh
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then
+ emulate sh
+ NULLCMD=:
+ # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which
+ # is contrary to our usage. Disable this feature.
+ alias -g '${1+"$@"}'='"$@"'
+ setopt NO_GLOB_SUBST
+else
+ case `(set -o) 2>/dev/null` in
+ *posix*) set -o posix ;;
+esac
+
+fi
+
+
+
+
+# PATH needs CR
+# Avoid depending upon Character Ranges.
+as_cr_letters='abcdefghijklmnopqrstuvwxyz'
+as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
+as_cr_Letters=$as_cr_letters$as_cr_LETTERS
+as_cr_digits='0123456789'
+as_cr_alnum=$as_cr_Letters$as_cr_digits
+
+as_nl='
+'
+export as_nl
+# Printing a long string crashes Solaris 7 /usr/bin/printf.
+as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'
+as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo
+as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo
+if (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then
+ as_echo='printf %s\n'
+ as_echo_n='printf %s'
+else
+ if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then
+ as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"'
+ as_echo_n='/usr/ucb/echo -n'
+ else
+ as_echo_body='eval expr "X$1" : "X\\(.*\\)"'
+ as_echo_n_body='eval
+ arg=$1;
+ case $arg in
+ *"$as_nl"*)
+ expr "X$arg" : "X\\(.*\\)$as_nl";
+ arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;;
+ esac;
+ expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl"
+ '
+ export as_echo_n_body
+ as_echo_n='sh -c $as_echo_n_body as_echo'
+ fi
+ export as_echo_body
+ as_echo='sh -c $as_echo_body as_echo'
+fi
+
+# The user is always right.
+if test "${PATH_SEPARATOR+set}" != set; then
+ PATH_SEPARATOR=:
+ (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && {
+ (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 ||
+ PATH_SEPARATOR=';'
+ }
+fi
+
+# Support unset when possible.
+if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then
+ as_unset=unset
+else
+ as_unset=false
+fi
+
+
+# IFS
+# We need space, tab and new line, in precisely that order. Quoting is
+# there to prevent editors from complaining about space-tab.
+# (If _AS_PATH_WALK were called with IFS unset, it would disable word
+# splitting by setting IFS to empty value.)
+IFS=" "" $as_nl"
+
+# Find who we are. Look in the path if we contain no directory separator.
+case $0 in
+ *[\\/]* ) as_myself=$0 ;;
+ *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
+done
+IFS=$as_save_IFS
+
+ ;;
+esac
+# We did not find ourselves, most probably we were run as `sh COMMAND'
+# in which case we are not to be found in the path.
+if test "x$as_myself" = x; then
+ as_myself=$0
+fi
+if test ! -f "$as_myself"; then
+ $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2
+ { (exit 1); exit 1; }
+fi
+
+# Work around bugs in pre-3.0 UWIN ksh.
+for as_var in ENV MAIL MAILPATH
+do ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var
+done
+PS1='$ '
+PS2='> '
+PS4='+ '
+
+# NLS nuisances.
+LC_ALL=C
+export LC_ALL
+LANGUAGE=C
+export LANGUAGE
+
+# Required to use basename.
+if expr a : '\(a\)' >/dev/null 2>&1 &&
+ test "X`expr 00001 : '.*\(...\)'`" = X001; then
+ as_expr=expr
+else
+ as_expr=false
+fi
+
+if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then
+ as_basename=basename
+else
+ as_basename=false
+fi
+
+
+# Name of the executable.
+as_me=`$as_basename -- "$0" ||
+$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
+ X"$0" : 'X\(//\)$' \| \
+ X"$0" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X/"$0" |
+ sed '/^.*\/\([^/][^/]*\)\/*$/{
+ s//\1/
+ q
+ }
+ /^X\/\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\/\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'`
+
+# CDPATH.
+$as_unset CDPATH
+
+
+if test "x$CONFIG_SHELL" = x; then
+ if (eval ":") 2>/dev/null; then
+ as_have_required=yes
+else
+ as_have_required=no
+fi
+
+ if test $as_have_required = yes && (eval ":
+(as_func_return () {
+ (exit \$1)
+}
+as_func_success () {
+ as_func_return 0
+}
+as_func_failure () {
+ as_func_return 1
+}
+as_func_ret_success () {
+ return 0
+}
+as_func_ret_failure () {
+ return 1
+}
+
+exitcode=0
+if as_func_success; then
+ :
+else
+ exitcode=1
+ echo as_func_success failed.
+fi
+
+if as_func_failure; then
+ exitcode=1
+ echo as_func_failure succeeded.
+fi
+
+if as_func_ret_success; then
+ :
+else
+ exitcode=1
+ echo as_func_ret_success failed.
+fi
+
+if as_func_ret_failure; then
+ exitcode=1
+ echo as_func_ret_failure succeeded.
+fi
+
+if ( set x; as_func_ret_success y && test x = \"\$1\" ); then
+ :
+else
+ exitcode=1
+ echo positional parameters were not saved.
+fi
+
+test \$exitcode = 0) || { (exit 1); exit 1; }
+
+(
+ as_lineno_1=\$LINENO
+ as_lineno_2=\$LINENO
+ test \"x\$as_lineno_1\" != \"x\$as_lineno_2\" &&
+ test \"x\`expr \$as_lineno_1 + 1\`\" = \"x\$as_lineno_2\") || { (exit 1); exit 1; }
+") 2> /dev/null; then
+ :
+else
+ as_candidate_shells=
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ case $as_dir in
+ /*)
+ for as_base in sh bash ksh sh5; do
+ as_candidate_shells="$as_candidate_shells $as_dir/$as_base"
+ done;;
+ esac
+done
+IFS=$as_save_IFS
+
+
+ for as_shell in $as_candidate_shells $SHELL; do
+ # Try only shells that exist, to save several forks.
+ if { test -f "$as_shell" || test -f "$as_shell.exe"; } &&
+ { ("$as_shell") 2> /dev/null <<\_ASEOF
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then
+ emulate sh
+ NULLCMD=:
+ # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which
+ # is contrary to our usage. Disable this feature.
+ alias -g '${1+"$@"}'='"$@"'
+ setopt NO_GLOB_SUBST
+else
+ case `(set -o) 2>/dev/null` in
+ *posix*) set -o posix ;;
+esac
+
+fi
+
+
+:
+_ASEOF
+}; then
+ CONFIG_SHELL=$as_shell
+ as_have_required=yes
+ if { "$as_shell" 2> /dev/null <<\_ASEOF
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then
+ emulate sh
+ NULLCMD=:
+ # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which
+ # is contrary to our usage. Disable this feature.
+ alias -g '${1+"$@"}'='"$@"'
+ setopt NO_GLOB_SUBST
+else
+ case `(set -o) 2>/dev/null` in
+ *posix*) set -o posix ;;
+esac
+
+fi
+
+
+:
+(as_func_return () {
+ (exit $1)
+}
+as_func_success () {
+ as_func_return 0
+}
+as_func_failure () {
+ as_func_return 1
+}
+as_func_ret_success () {
+ return 0
+}
+as_func_ret_failure () {
+ return 1
+}
+
+exitcode=0
+if as_func_success; then
+ :
+else
+ exitcode=1
+ echo as_func_success failed.
+fi
+
+if as_func_failure; then
+ exitcode=1
+ echo as_func_failure succeeded.
+fi
+
+if as_func_ret_success; then
+ :
+else
+ exitcode=1
+ echo as_func_ret_success failed.
+fi
+
+if as_func_ret_failure; then
+ exitcode=1
+ echo as_func_ret_failure succeeded.
+fi
+
+if ( set x; as_func_ret_success y && test x = "$1" ); then
+ :
+else
+ exitcode=1
+ echo positional parameters were not saved.
+fi
+
+test $exitcode = 0) || { (exit 1); exit 1; }
+
+(
+ as_lineno_1=$LINENO
+ as_lineno_2=$LINENO
+ test "x$as_lineno_1" != "x$as_lineno_2" &&
+ test "x`expr $as_lineno_1 + 1`" = "x$as_lineno_2") || { (exit 1); exit 1; }
+
+_ASEOF
+}; then
+ break
+fi
+
+fi
+
+ done
+
+ if test "x$CONFIG_SHELL" != x; then
+ for as_var in BASH_ENV ENV
+ do ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var
+ done
+ export CONFIG_SHELL
+ exec "$CONFIG_SHELL" "$as_myself" ${1+"$@"}
+fi
+
+
+ if test $as_have_required = no; then
+ echo This script requires a shell more modern than all the
+ echo shells that I found on your system. Please install a
+ echo modern shell, or manually run the script under such a
+ echo shell if you do have one.
+ { (exit 1); exit 1; }
+fi
+
+
+fi
+
+fi
+
+
+
+(eval "as_func_return () {
+ (exit \$1)
+}
+as_func_success () {
+ as_func_return 0
+}
+as_func_failure () {
+ as_func_return 1
+}
+as_func_ret_success () {
+ return 0
+}
+as_func_ret_failure () {
+ return 1
+}
+
+exitcode=0
+if as_func_success; then
+ :
+else
+ exitcode=1
+ echo as_func_success failed.
+fi
+
+if as_func_failure; then
+ exitcode=1
+ echo as_func_failure succeeded.
+fi
+
+if as_func_ret_success; then
+ :
+else
+ exitcode=1
+ echo as_func_ret_success failed.
+fi
+
+if as_func_ret_failure; then
+ exitcode=1
+ echo as_func_ret_failure succeeded.
+fi
+
+if ( set x; as_func_ret_success y && test x = \"\$1\" ); then
+ :
+else
+ exitcode=1
+ echo positional parameters were not saved.
+fi
+
+test \$exitcode = 0") || {
+ echo No shell found that supports shell functions.
+ echo Please tell bug-autoconf@gnu.org about your system,
+ echo including any error possibly output before this message.
+ echo This can help us improve future autoconf versions.
+ echo Configuration will now proceed without shell functions.
+}
+
+
+
+ as_lineno_1=$LINENO
+ as_lineno_2=$LINENO
+ test "x$as_lineno_1" != "x$as_lineno_2" &&
+ test "x`expr $as_lineno_1 + 1`" = "x$as_lineno_2" || {
+
+ # Create $as_me.lineno as a copy of $as_myself, but with $LINENO
+ # uniformly replaced by the line number. The first 'sed' inserts a
+ # line-number line after each line using $LINENO; the second 'sed'
+ # does the real work. The second script uses 'N' to pair each
+ # line-number line with the line containing $LINENO, and appends
+ # trailing '-' during substitution so that $LINENO is not a special
+ # case at line end.
+ # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the
+ # scripts with optimization help from Paolo Bonzini. Blame Lee
+ # E. McMahon (1931-1989) for sed's syntax. :-)
+ sed -n '
+ p
+ /[$]LINENO/=
+ ' <$as_myself |
+ sed '
+ s/[$]LINENO.*/&-/
+ t lineno
+ b
+ :lineno
+ N
+ :loop
+ s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/
+ t loop
+ s/-\n.*//
+ ' >$as_me.lineno &&
+ chmod +x "$as_me.lineno" ||
+ { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2
+ { (exit 1); exit 1; }; }
+
+ # Don't try to exec as it changes $[0], causing all sort of problems
+ # (the dirname of $[0] is not the place where we might find the
+ # original and so on. Autoconf is especially sensitive to this).
+ . "./$as_me.lineno"
+ # Exit status is that of the last command.
+ exit
+}
+
+
+if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then
+ as_dirname=dirname
+else
+ as_dirname=false
+fi
+
+ECHO_C= ECHO_N= ECHO_T=
+case `echo -n x` in
+-n*)
+ case `echo 'x\c'` in
+ *c*) ECHO_T=' ';; # ECHO_T is single tab character.
+ *) ECHO_C='\c';;
+ esac;;
+*)
+ ECHO_N='-n';;
+esac
+if expr a : '\(a\)' >/dev/null 2>&1 &&
+ test "X`expr 00001 : '.*\(...\)'`" = X001; then
+ as_expr=expr
+else
+ as_expr=false
+fi
+
+rm -f conf$$ conf$$.exe conf$$.file
+if test -d conf$$.dir; then
+ rm -f conf$$.dir/conf$$.file
+else
+ rm -f conf$$.dir
+ mkdir conf$$.dir 2>/dev/null
+fi
+if (echo >conf$$.file) 2>/dev/null; then
+ if ln -s conf$$.file conf$$ 2>/dev/null; then
+ as_ln_s='ln -s'
+ # ... but there are two gotchas:
+ # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail.
+ # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable.
+ # In both cases, we have to default to `cp -p'.
+ ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe ||
+ as_ln_s='cp -p'
+ elif ln conf$$.file conf$$ 2>/dev/null; then
+ as_ln_s=ln
+ else
+ as_ln_s='cp -p'
+ fi
+else
+ as_ln_s='cp -p'
+fi
+rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file
+rmdir conf$$.dir 2>/dev/null
+
+if mkdir -p . 2>/dev/null; then
+ as_mkdir_p=:
+else
+ test -d ./-p && rmdir ./-p
+ as_mkdir_p=false
+fi
+
+if test -x / >/dev/null 2>&1; then
+ as_test_x='test -x'
+else
+ if ls -dL / >/dev/null 2>&1; then
+ as_ls_L_option=L
+ else
+ as_ls_L_option=
+ fi
+ as_test_x='
+ eval sh -c '\''
+ if test -d "$1"; then
+ test -d "$1/.";
+ else
+ case $1 in
+ -*)set "./$1";;
+ esac;
+ case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in
+ ???[sx]*):;;*)false;;esac;fi
+ '\'' sh
+ '
+fi
+as_executable_p=$as_test_x
+
+# Sed expression to map a string onto a valid CPP name.
+as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"
+
+# Sed expression to map a string onto a valid variable name.
+as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'"
+
+
+
+exec 7<&0 </dev/null 6>&1
+
+# Name of the host.
+# hostname on some systems (SVR3.2, Linux) returns a bogus exit status,
+# so uname gets run too.
+ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q`
+
+#
+# Initializations.
+#
+ac_default_prefix=/usr/local
+ac_clean_files=
+ac_config_libobj_dir=.
+LIBOBJS=
+cross_compiling=no
+subdirs=
+MFLAGS=
+MAKEFLAGS=
+SHELL=${CONFIG_SHELL-/bin/sh}
+
+# Identity of this package.
+PACKAGE_NAME='Asymptote'
+PACKAGE_TARNAME='asymptote'
+PACKAGE_VERSION='1.72'
+PACKAGE_STRING='Asymptote 1.72'
+PACKAGE_BUGREPORT='http://sourceforge.net/projects/asymptote'
+
+# Factoring default headers for most tests.
+ac_includes_default="\
+#include <stdio.h>
+#ifdef HAVE_SYS_TYPES_H
+# include <sys/types.h>
+#endif
+#ifdef HAVE_SYS_STAT_H
+# include <sys/stat.h>
+#endif
+#ifdef STDC_HEADERS
+# include <stdlib.h>
+# include <stddef.h>
+#else
+# ifdef HAVE_STDLIB_H
+# include <stdlib.h>
+# endif
+#endif
+#ifdef HAVE_STRING_H
+# if !defined STDC_HEADERS && defined HAVE_MEMORY_H
+# include <memory.h>
+# endif
+# include <string.h>
+#endif
+#ifdef HAVE_STRINGS_H
+# include <strings.h>
+#endif
+#ifdef HAVE_INTTYPES_H
+# include <inttypes.h>
+#endif
+#ifdef HAVE_STDINT_H
+# include <stdint.h>
+#endif
+#ifdef HAVE_UNISTD_H
+# include <unistd.h>
+#endif"
+
+ac_unique_file="absyn.cc"
+ac_subst_vars='LTLIBOBJS
+LIBOBJS
+OPTIONS
+INCL
+GCPPLIB
+GCLIB
+GCOPTIONS
+GCDIR
+getopt
+CXXCPP
+YFLAGS
+YACC
+SET_MAKE
+INSTALL_DATA
+INSTALL_SCRIPT
+INSTALL_PROGRAM
+LEXLIB
+ac_ct_CXX
+CXXFLAGS
+CXX
+LEX_OUTPUT_ROOT
+LEX
+latexdir
+TEXI2DVI
+kpsewhich
+Datadir
+EGREP
+GREP
+CPP
+OBJEXT
+EXEEXT
+ac_ct_CC
+CPPFLAGS
+LDFLAGS
+CFLAGS
+CC
+VERSION
+target_alias
+host_alias
+build_alias
+LIBS
+ECHO_T
+ECHO_N
+ECHO_C
+DEFS
+mandir
+localedir
+libdir
+psdir
+pdfdir
+dvidir
+htmldir
+infodir
+docdir
+oldincludedir
+includedir
+localstatedir
+sharedstatedir
+sysconfdir
+datadir
+datarootdir
+libexecdir
+sbindir
+bindir
+program_transform_name
+prefix
+exec_prefix
+PACKAGE_BUGREPORT
+PACKAGE_STRING
+PACKAGE_VERSION
+PACKAGE_TARNAME
+PACKAGE_NAME
+PATH_SEPARATOR
+SHELL'
+ac_subst_files=''
+ac_user_opts='
+enable_option_checking
+with_latex
+with_docdir
+enable_tetex_build
+enable_gc
+enable_gc_debug
+enable_gc_full_debug
+'
+ ac_precious_vars='build_alias
+host_alias
+target_alias
+CC
+CFLAGS
+LDFLAGS
+LIBS
+CPPFLAGS
+CPP
+CXX
+CXXFLAGS
+CCC
+YACC
+YFLAGS
+CXXCPP'
+
+
+# Initialize some variables set by options.
+ac_init_help=
+ac_init_version=false
+ac_unrecognized_opts=
+ac_unrecognized_sep=
+# The variables have the same names as the options, with
+# dashes changed to underlines.
+cache_file=/dev/null
+exec_prefix=NONE
+no_create=
+no_recursion=
+prefix=NONE
+program_prefix=NONE
+program_suffix=NONE
+program_transform_name=s,x,x,
+silent=
+site=
+srcdir=
+verbose=
+x_includes=NONE
+x_libraries=NONE
+
+# Installation directory options.
+# These are left unexpanded so users can "make install exec_prefix=/foo"
+# and all the variables that are supposed to be based on exec_prefix
+# by default will actually change.
+# Use braces instead of parens because sh, perl, etc. also accept them.
+# (The list follows the same order as the GNU Coding Standards.)
+bindir='${exec_prefix}/bin'
+sbindir='${exec_prefix}/sbin'
+libexecdir='${exec_prefix}/libexec'
+datarootdir='${prefix}/share'
+datadir='${datarootdir}'
+sysconfdir='${prefix}/etc'
+sharedstatedir='${prefix}/com'
+localstatedir='${prefix}/var'
+includedir='${prefix}/include'
+oldincludedir='/usr/include'
+docdir='${datarootdir}/doc/${PACKAGE_TARNAME}'
+infodir='${datarootdir}/info'
+htmldir='${docdir}'
+dvidir='${docdir}'
+pdfdir='${docdir}'
+psdir='${docdir}'
+libdir='${exec_prefix}/lib'
+localedir='${datarootdir}/locale'
+mandir='${datarootdir}/man'
+
+ac_prev=
+ac_dashdash=
+for ac_option
+do
+ # If the previous option needs an argument, assign it.
+ if test -n "$ac_prev"; then
+ eval $ac_prev=\$ac_option
+ ac_prev=
+ continue
+ fi
+
+ case $ac_option in
+ *=*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;;
+ *) ac_optarg=yes ;;
+ esac
+
+ # Accept the important Cygnus configure options, so we can diagnose typos.
+
+ case $ac_dashdash$ac_option in
+ --)
+ ac_dashdash=yes ;;
+
+ -bindir | --bindir | --bindi | --bind | --bin | --bi)
+ ac_prev=bindir ;;
+ -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*)
+ bindir=$ac_optarg ;;
+
+ -build | --build | --buil | --bui | --bu)
+ ac_prev=build_alias ;;
+ -build=* | --build=* | --buil=* | --bui=* | --bu=*)
+ build_alias=$ac_optarg ;;
+
+ -cache-file | --cache-file | --cache-fil | --cache-fi \
+ | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c)
+ ac_prev=cache_file ;;
+ -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \
+ | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*)
+ cache_file=$ac_optarg ;;
+
+ --config-cache | -C)
+ cache_file=config.cache ;;
+
+ -datadir | --datadir | --datadi | --datad)
+ ac_prev=datadir ;;
+ -datadir=* | --datadir=* | --datadi=* | --datad=*)
+ datadir=$ac_optarg ;;
+
+ -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \
+ | --dataroo | --dataro | --datar)
+ ac_prev=datarootdir ;;
+ -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \
+ | --dataroot=* | --dataroo=* | --dataro=* | --datar=*)
+ datarootdir=$ac_optarg ;;
+
+ -disable-* | --disable-*)
+ ac_useropt=`expr "x$ac_option" : 'x-*disable-\(.*\)'`
+ # Reject names that are not valid shell variable names.
+ expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
+ { $as_echo "$as_me: error: invalid feature name: $ac_useropt" >&2
+ { (exit 1); exit 1; }; }
+ ac_useropt_orig=$ac_useropt
+ ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
+ case $ac_user_opts in
+ *"
+"enable_$ac_useropt"
+"*) ;;
+ *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--disable-$ac_useropt_orig"
+ ac_unrecognized_sep=', ';;
+ esac
+ eval enable_$ac_useropt=no ;;
+
+ -docdir | --docdir | --docdi | --doc | --do)
+ ac_prev=docdir ;;
+ -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*)
+ docdir=$ac_optarg ;;
+
+ -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv)
+ ac_prev=dvidir ;;
+ -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*)
+ dvidir=$ac_optarg ;;
+
+ -enable-* | --enable-*)
+ ac_useropt=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'`
+ # Reject names that are not valid shell variable names.
+ expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
+ { $as_echo "$as_me: error: invalid feature name: $ac_useropt" >&2
+ { (exit 1); exit 1; }; }
+ ac_useropt_orig=$ac_useropt
+ ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
+ case $ac_user_opts in
+ *"
+"enable_$ac_useropt"
+"*) ;;
+ *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--enable-$ac_useropt_orig"
+ ac_unrecognized_sep=', ';;
+ esac
+ eval enable_$ac_useropt=\$ac_optarg ;;
+
+ -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \
+ | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \
+ | --exec | --exe | --ex)
+ ac_prev=exec_prefix ;;
+ -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \
+ | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \
+ | --exec=* | --exe=* | --ex=*)
+ exec_prefix=$ac_optarg ;;
+
+ -gas | --gas | --ga | --g)
+ # Obsolete; use --with-gas.
+ with_gas=yes ;;
+
+ -help | --help | --hel | --he | -h)
+ ac_init_help=long ;;
+ -help=r* | --help=r* | --hel=r* | --he=r* | -hr*)
+ ac_init_help=recursive ;;
+ -help=s* | --help=s* | --hel=s* | --he=s* | -hs*)
+ ac_init_help=short ;;
+
+ -host | --host | --hos | --ho)
+ ac_prev=host_alias ;;
+ -host=* | --host=* | --hos=* | --ho=*)
+ host_alias=$ac_optarg ;;
+
+ -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht)
+ ac_prev=htmldir ;;
+ -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \
+ | --ht=*)
+ htmldir=$ac_optarg ;;
+
+ -includedir | --includedir | --includedi | --included | --include \
+ | --includ | --inclu | --incl | --inc)
+ ac_prev=includedir ;;
+ -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \
+ | --includ=* | --inclu=* | --incl=* | --inc=*)
+ includedir=$ac_optarg ;;
+
+ -infodir | --infodir | --infodi | --infod | --info | --inf)
+ ac_prev=infodir ;;
+ -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*)
+ infodir=$ac_optarg ;;
+
+ -libdir | --libdir | --libdi | --libd)
+ ac_prev=libdir ;;
+ -libdir=* | --libdir=* | --libdi=* | --libd=*)
+ libdir=$ac_optarg ;;
+
+ -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \
+ | --libexe | --libex | --libe)
+ ac_prev=libexecdir ;;
+ -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \
+ | --libexe=* | --libex=* | --libe=*)
+ libexecdir=$ac_optarg ;;
+
+ -localedir | --localedir | --localedi | --localed | --locale)
+ ac_prev=localedir ;;
+ -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*)
+ localedir=$ac_optarg ;;
+
+ -localstatedir | --localstatedir | --localstatedi | --localstated \
+ | --localstate | --localstat | --localsta | --localst | --locals)
+ ac_prev=localstatedir ;;
+ -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \
+ | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*)
+ localstatedir=$ac_optarg ;;
+
+ -mandir | --mandir | --mandi | --mand | --man | --ma | --m)
+ ac_prev=mandir ;;
+ -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*)
+ mandir=$ac_optarg ;;
+
+ -nfp | --nfp | --nf)
+ # Obsolete; use --without-fp.
+ with_fp=no ;;
+
+ -no-create | --no-create | --no-creat | --no-crea | --no-cre \
+ | --no-cr | --no-c | -n)
+ no_create=yes ;;
+
+ -no-recursion | --no-recursion | --no-recursio | --no-recursi \
+ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r)
+ no_recursion=yes ;;
+
+ -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \
+ | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \
+ | --oldin | --oldi | --old | --ol | --o)
+ ac_prev=oldincludedir ;;
+ -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \
+ | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \
+ | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*)
+ oldincludedir=$ac_optarg ;;
+
+ -prefix | --prefix | --prefi | --pref | --pre | --pr | --p)
+ ac_prev=prefix ;;
+ -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*)
+ prefix=$ac_optarg ;;
+
+ -program-prefix | --program-prefix | --program-prefi | --program-pref \
+ | --program-pre | --program-pr | --program-p)
+ ac_prev=program_prefix ;;
+ -program-prefix=* | --program-prefix=* | --program-prefi=* \
+ | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*)
+ program_prefix=$ac_optarg ;;
+
+ -program-suffix | --program-suffix | --program-suffi | --program-suff \
+ | --program-suf | --program-su | --program-s)
+ ac_prev=program_suffix ;;
+ -program-suffix=* | --program-suffix=* | --program-suffi=* \
+ | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*)
+ program_suffix=$ac_optarg ;;
+
+ -program-transform-name | --program-transform-name \
+ | --program-transform-nam | --program-transform-na \
+ | --program-transform-n | --program-transform- \
+ | --program-transform | --program-transfor \
+ | --program-transfo | --program-transf \
+ | --program-trans | --program-tran \
+ | --progr-tra | --program-tr | --program-t)
+ ac_prev=program_transform_name ;;
+ -program-transform-name=* | --program-transform-name=* \
+ | --program-transform-nam=* | --program-transform-na=* \
+ | --program-transform-n=* | --program-transform-=* \
+ | --program-transform=* | --program-transfor=* \
+ | --program-transfo=* | --program-transf=* \
+ | --program-trans=* | --program-tran=* \
+ | --progr-tra=* | --program-tr=* | --program-t=*)
+ program_transform_name=$ac_optarg ;;
+
+ -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd)
+ ac_prev=pdfdir ;;
+ -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*)
+ pdfdir=$ac_optarg ;;
+
+ -psdir | --psdir | --psdi | --psd | --ps)
+ ac_prev=psdir ;;
+ -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*)
+ psdir=$ac_optarg ;;
+
+ -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+ | -silent | --silent | --silen | --sile | --sil)
+ silent=yes ;;
+
+ -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)
+ ac_prev=sbindir ;;
+ -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \
+ | --sbi=* | --sb=*)
+ sbindir=$ac_optarg ;;
+
+ -sharedstatedir | --sharedstatedir | --sharedstatedi \
+ | --sharedstated | --sharedstate | --sharedstat | --sharedsta \
+ | --sharedst | --shareds | --shared | --share | --shar \
+ | --sha | --sh)
+ ac_prev=sharedstatedir ;;
+ -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \
+ | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \
+ | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \
+ | --sha=* | --sh=*)
+ sharedstatedir=$ac_optarg ;;
+
+ -site | --site | --sit)
+ ac_prev=site ;;
+ -site=* | --site=* | --sit=*)
+ site=$ac_optarg ;;
+
+ -srcdir | --srcdir | --srcdi | --srcd | --src | --sr)
+ ac_prev=srcdir ;;
+ -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*)
+ srcdir=$ac_optarg ;;
+
+ -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \
+ | --syscon | --sysco | --sysc | --sys | --sy)
+ ac_prev=sysconfdir ;;
+ -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \
+ | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*)
+ sysconfdir=$ac_optarg ;;
+
+ -target | --target | --targe | --targ | --tar | --ta | --t)
+ ac_prev=target_alias ;;
+ -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*)
+ target_alias=$ac_optarg ;;
+
+ -v | -verbose | --verbose | --verbos | --verbo | --verb)
+ verbose=yes ;;
+
+ -version | --version | --versio | --versi | --vers | -V)
+ ac_init_version=: ;;
+
+ -with-* | --with-*)
+ ac_useropt=`expr "x$ac_option" : 'x-*with-\([^=]*\)'`
+ # Reject names that are not valid shell variable names.
+ expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
+ { $as_echo "$as_me: error: invalid package name: $ac_useropt" >&2
+ { (exit 1); exit 1; }; }
+ ac_useropt_orig=$ac_useropt
+ ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
+ case $ac_user_opts in
+ *"
+"with_$ac_useropt"
+"*) ;;
+ *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--with-$ac_useropt_orig"
+ ac_unrecognized_sep=', ';;
+ esac
+ eval with_$ac_useropt=\$ac_optarg ;;
+
+ -without-* | --without-*)
+ ac_useropt=`expr "x$ac_option" : 'x-*without-\(.*\)'`
+ # Reject names that are not valid shell variable names.
+ expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
+ { $as_echo "$as_me: error: invalid package name: $ac_useropt" >&2
+ { (exit 1); exit 1; }; }
+ ac_useropt_orig=$ac_useropt
+ ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
+ case $ac_user_opts in
+ *"
+"with_$ac_useropt"
+"*) ;;
+ *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--without-$ac_useropt_orig"
+ ac_unrecognized_sep=', ';;
+ esac
+ eval with_$ac_useropt=no ;;
+
+ --x)
+ # Obsolete; use --with-x.
+ with_x=yes ;;
+
+ -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \
+ | --x-incl | --x-inc | --x-in | --x-i)
+ ac_prev=x_includes ;;
+ -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \
+ | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*)
+ x_includes=$ac_optarg ;;
+
+ -x-libraries | --x-libraries | --x-librarie | --x-librari \
+ | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l)
+ ac_prev=x_libraries ;;
+ -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \
+ | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*)
+ x_libraries=$ac_optarg ;;
+
+ -*) { $as_echo "$as_me: error: unrecognized option: $ac_option
+Try \`$0 --help' for more information." >&2
+ { (exit 1); exit 1; }; }
+ ;;
+
+ *=*)
+ ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='`
+ # Reject names that are not valid shell variable names.
+ expr "x$ac_envvar" : ".*[^_$as_cr_alnum]" >/dev/null &&
+ { $as_echo "$as_me: error: invalid variable name: $ac_envvar" >&2
+ { (exit 1); exit 1; }; }
+ eval $ac_envvar=\$ac_optarg
+ export $ac_envvar ;;
+
+ *)
+ # FIXME: should be removed in autoconf 3.0.
+ $as_echo "$as_me: WARNING: you should use --build, --host, --target" >&2
+ expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null &&
+ $as_echo "$as_me: WARNING: invalid host type: $ac_option" >&2
+ : ${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}
+ ;;
+
+ esac
+done
+
+if test -n "$ac_prev"; then
+ ac_option=--`echo $ac_prev | sed 's/_/-/g'`
+ { $as_echo "$as_me: error: missing argument to $ac_option" >&2
+ { (exit 1); exit 1; }; }
+fi
+
+if test -n "$ac_unrecognized_opts"; then
+ case $enable_option_checking in
+ no) ;;
+ fatal) { $as_echo "$as_me: error: unrecognized options: $ac_unrecognized_opts" >&2
+ { (exit 1); exit 1; }; } ;;
+ *) $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;;
+ esac
+fi
+
+# Check all directory arguments for consistency.
+for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \
+ datadir sysconfdir sharedstatedir localstatedir includedir \
+ oldincludedir docdir infodir htmldir dvidir pdfdir psdir \
+ libdir localedir mandir
+do
+ eval ac_val=\$$ac_var
+ # Remove trailing slashes.
+ case $ac_val in
+ */ )
+ ac_val=`expr "X$ac_val" : 'X\(.*[^/]\)' \| "X$ac_val" : 'X\(.*\)'`
+ eval $ac_var=\$ac_val;;
+ esac
+ # Be sure to have absolute directory names.
+ case $ac_val in
+ [\\/$]* | ?:[\\/]* ) continue;;
+ NONE | '' ) case $ac_var in *prefix ) continue;; esac;;
+ esac
+ { $as_echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2
+ { (exit 1); exit 1; }; }
+done
+
+# There might be people who depend on the old broken behavior: `$host'
+# used to hold the argument of --host etc.
+# FIXME: To remove some day.
+build=$build_alias
+host=$host_alias
+target=$target_alias
+
+# FIXME: To remove some day.
+if test "x$host_alias" != x; then
+ if test "x$build_alias" = x; then
+ cross_compiling=maybe
+ $as_echo "$as_me: WARNING: If you wanted to set the --build type, don't use --host.
+ If a cross compiler is detected then cross compile mode will be used." >&2
+ elif test "x$build_alias" != "x$host_alias"; then
+ cross_compiling=yes
+ fi
+fi
+
+ac_tool_prefix=
+test -n "$host_alias" && ac_tool_prefix=$host_alias-
+
+test "$silent" = yes && exec 6>/dev/null
+
+
+ac_pwd=`pwd` && test -n "$ac_pwd" &&
+ac_ls_di=`ls -di .` &&
+ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` ||
+ { $as_echo "$as_me: error: working directory cannot be determined" >&2
+ { (exit 1); exit 1; }; }
+test "X$ac_ls_di" = "X$ac_pwd_ls_di" ||
+ { $as_echo "$as_me: error: pwd does not report name of working directory" >&2
+ { (exit 1); exit 1; }; }
+
+
+# Find the source files, if location was not specified.
+if test -z "$srcdir"; then
+ ac_srcdir_defaulted=yes
+ # Try the directory containing this script, then the parent directory.
+ ac_confdir=`$as_dirname -- "$as_myself" ||
+$as_expr X"$as_myself" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$as_myself" : 'X\(//\)[^/]' \| \
+ X"$as_myself" : 'X\(//\)$' \| \
+ X"$as_myself" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$as_myself" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)[^/].*/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'`
+ srcdir=$ac_confdir
+ if test ! -r "$srcdir/$ac_unique_file"; then
+ srcdir=..
+ fi
+else
+ ac_srcdir_defaulted=no
+fi
+if test ! -r "$srcdir/$ac_unique_file"; then
+ test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .."
+ { $as_echo "$as_me: error: cannot find sources ($ac_unique_file) in $srcdir" >&2
+ { (exit 1); exit 1; }; }
+fi
+ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work"
+ac_abs_confdir=`(
+ cd "$srcdir" && test -r "./$ac_unique_file" || { $as_echo "$as_me: error: $ac_msg" >&2
+ { (exit 1); exit 1; }; }
+ pwd)`
+# When building in place, set srcdir=.
+if test "$ac_abs_confdir" = "$ac_pwd"; then
+ srcdir=.
+fi
+# Remove unnecessary trailing slashes from srcdir.
+# Double slashes in file names in object file debugging info
+# mess up M-x gdb in Emacs.
+case $srcdir in
+*/) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;;
+esac
+for ac_var in $ac_precious_vars; do
+ eval ac_env_${ac_var}_set=\${${ac_var}+set}
+ eval ac_env_${ac_var}_value=\$${ac_var}
+ eval ac_cv_env_${ac_var}_set=\${${ac_var}+set}
+ eval ac_cv_env_${ac_var}_value=\$${ac_var}
+done
+
+#
+# Report the --help message.
+#
+if test "$ac_init_help" = "long"; then
+ # 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 1.72 to adapt to many kinds of systems.
+
+Usage: $0 [OPTION]... [VAR=VALUE]...
+
+To assign environment variables (e.g., CC, CFLAGS...), specify them as
+VAR=VALUE. See below for descriptions of some of the useful variables.
+
+Defaults for the options are specified in brackets.
+
+Configuration:
+ -h, --help display this help and exit
+ --help=short display options specific to this package
+ --help=recursive display the short help of all the included packages
+ -V, --version display version information and exit
+ -q, --quiet, --silent do not print \`checking...' messages
+ --cache-file=FILE cache test results in FILE [disabled]
+ -C, --config-cache alias for \`--cache-file=config.cache'
+ -n, --no-create do not create output files
+ --srcdir=DIR find the sources in DIR [configure dir or \`..']
+
+Installation directories:
+ --prefix=PREFIX install architecture-independent files in PREFIX
+ [$ac_default_prefix]
+ --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX
+ [PREFIX]
+
+By default, \`make install' will install all the files in
+\`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify
+an installation prefix other than \`$ac_default_prefix' using \`--prefix',
+for instance \`--prefix=\$HOME'.
+
+For better control, use the options below.
+
+Fine tuning of the installation directories:
+ --bindir=DIR user executables [EPREFIX/bin]
+ --sbindir=DIR system admin executables [EPREFIX/sbin]
+ --libexecdir=DIR program executables [EPREFIX/libexec]
+ --sysconfdir=DIR read-only single-machine data [PREFIX/etc]
+ --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com]
+ --localstatedir=DIR modifiable single-machine data [PREFIX/var]
+ --libdir=DIR object code libraries [EPREFIX/lib]
+ --includedir=DIR C header files [PREFIX/include]
+ --oldincludedir=DIR C header files for non-gcc [/usr/include]
+ --datarootdir=DIR read-only arch.-independent data root [PREFIX/share]
+ --datadir=DIR read-only architecture-independent data [DATAROOTDIR]
+ --infodir=DIR info documentation [DATAROOTDIR/info]
+ --localedir=DIR locale-dependent data [DATAROOTDIR/locale]
+ --mandir=DIR man documentation [DATAROOTDIR/man]
+ --docdir=DIR documentation root [DATAROOTDIR/doc/asymptote]
+ --htmldir=DIR html documentation [DOCDIR]
+ --dvidir=DIR dvi documentation [DOCDIR]
+ --pdfdir=DIR pdf documentation [DOCDIR]
+ --psdir=DIR ps documentation [DOCDIR]
+_ACEOF
+
+ cat <<\_ACEOF
+_ACEOF
+fi
+
+if test -n "$ac_init_help"; then
+ case $ac_init_help in
+ short | recursive ) echo "Configuration of Asymptote 1.72:";;
+ esac
+ cat <<\_ACEOF
+
+Optional Features:
+ --disable-option-checking ignore unrecognized --enable/--with options
+ --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no)
+ --enable-FEATURE[=ARG] include FEATURE [ARG=yes]
+ --enable-tetex-build automatically determine settings.sysdir from kpsewhich
+ --enable-gc[=system] enable system Boehm garbage collector
+ [=VERSION] enable local VERSION of Boehm garbage collector
+ [=PREFIX] use Boehm garbage collector installed in PREFIX
+ --enable-gc-debug enable (slow) garbage collector debugging
+ --enable-gc-full-debug enable (very slow) garbage collector backtrace
+
+Optional Packages:
+ --with-PACKAGE[=ARG] use PACKAGE [ARG=yes]
+ --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no)
+ --with-latex=PATH specify path to LaTeX installation
+ --with-docdir=PATH alternate documentation installation directory
+
+Some influential environment variables:
+ CC C compiler command
+ CFLAGS C compiler flags
+ LDFLAGS linker flags, e.g. -L<lib dir> if you have libraries in a
+ nonstandard directory <lib dir>
+ LIBS libraries to pass to the linker, e.g. -l<library>
+ CPPFLAGS C/C++/Objective C preprocessor flags, e.g. -I<include dir> if
+ you have headers in a nonstandard directory <include dir>
+ CPP C preprocessor
+ CXX C++ compiler command
+ CXXFLAGS C++ compiler flags
+ YACC The `Yet Another C Compiler' implementation to use. Defaults to
+ the first program found out of: `bison -y', `byacc', `yacc'.
+ YFLAGS The list of arguments that will be passed by default to $YACC.
+ This script will default YFLAGS to the empty string to avoid a
+ default value of `-d' given by some make applications.
+ CXXCPP C++ preprocessor
+
+Use these variables to override the choices made by `configure' or to help
+it to find libraries and programs with nonstandard names/locations.
+
+Report bugs to <http://sourceforge.net/projects/asymptote>.
+_ACEOF
+ac_status=$?
+fi
+
+if test "$ac_init_help" = "recursive"; then
+ # If there are subdirs, report their specific --help.
+ for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue
+ test -d "$ac_dir" ||
+ { cd "$srcdir" && ac_pwd=`pwd` && srcdir=. && test -d "$ac_dir"; } ||
+ continue
+ ac_builddir=.
+
+case "$ac_dir" in
+.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;;
+*)
+ ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'`
+ # A ".." for each directory in $ac_dir_suffix.
+ ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'`
+ case $ac_top_builddir_sub in
+ "") ac_top_builddir_sub=. ac_top_build_prefix= ;;
+ *) ac_top_build_prefix=$ac_top_builddir_sub/ ;;
+ esac ;;
+esac
+ac_abs_top_builddir=$ac_pwd
+ac_abs_builddir=$ac_pwd$ac_dir_suffix
+# for backward compatibility:
+ac_top_builddir=$ac_top_build_prefix
+
+case $srcdir in
+ .) # We are building in place.
+ ac_srcdir=.
+ ac_top_srcdir=$ac_top_builddir_sub
+ ac_abs_top_srcdir=$ac_pwd ;;
+ [\\/]* | ?:[\\/]* ) # Absolute name.
+ ac_srcdir=$srcdir$ac_dir_suffix;
+ ac_top_srcdir=$srcdir
+ ac_abs_top_srcdir=$srcdir ;;
+ *) # Relative name.
+ ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix
+ ac_top_srcdir=$ac_top_build_prefix$srcdir
+ ac_abs_top_srcdir=$ac_pwd/$srcdir ;;
+esac
+ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix
+
+ cd "$ac_dir" || { ac_status=$?; continue; }
+ # Check for guested configure.
+ if test -f "$ac_srcdir/configure.gnu"; then
+ echo &&
+ $SHELL "$ac_srcdir/configure.gnu" --help=recursive
+ elif test -f "$ac_srcdir/configure"; then
+ echo &&
+ $SHELL "$ac_srcdir/configure" --help=recursive
+ else
+ $as_echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2
+ fi || ac_status=$?
+ cd "$ac_pwd" || { ac_status=$?; break; }
+ done
+fi
+
+test -n "$ac_init_help" && exit $ac_status
+if $ac_init_version; then
+ cat <<\_ACEOF
+Asymptote configure 1.72
+generated by GNU Autoconf 2.63
+
+Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001,
+2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
+This configure script is free software; the Free Software Foundation
+gives unlimited permission to copy, distribute and modify it.
+_ACEOF
+ exit
+fi
+cat >config.log <<_ACEOF
+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 1.72, which was
+generated by GNU Autoconf 2.63. Invocation command line was
+
+ $ $0 $@
+
+_ACEOF
+exec 5>>config.log
+{
+cat <<_ASUNAME
+## --------- ##
+## Platform. ##
+## --------- ##
+
+hostname = `(hostname || uname -n) 2>/dev/null | sed 1q`
+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 || echo unknown`
+/bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown`
+
+/bin/arch = `(/bin/arch) 2>/dev/null || echo unknown`
+/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown`
+/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown`
+/usr/bin/hostinfo = `(/usr/bin/hostinfo) 2>/dev/null || echo unknown`
+/bin/machine = `(/bin/machine) 2>/dev/null || echo unknown`
+/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown`
+/bin/universe = `(/bin/universe) 2>/dev/null || echo unknown`
+
+_ASUNAME
+
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ $as_echo "PATH: $as_dir"
+done
+IFS=$as_save_IFS
+
+} >&5
+
+cat >&5 <<_ACEOF
+
+
+## ----------- ##
+## Core tests. ##
+## ----------- ##
+
+_ACEOF
+
+
+# Keep a trace of the command line.
+# Strip out --no-create and --no-recursion so they do not pile up.
+# Strip out --silent because we don't want to record it for future runs.
+# Also quote any args containing shell meta-characters.
+# Make two passes to allow for proper duplicate-argument suppression.
+ac_configure_args=
+ac_configure_args0=
+ac_configure_args1=
+ac_must_keep_next=false
+for ac_pass in 1 2
+do
+ for ac_arg
+ do
+ case $ac_arg in
+ -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;;
+ -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+ | -silent | --silent | --silen | --sile | --sil)
+ continue ;;
+ *\'*)
+ ac_arg=`$as_echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;;
+ esac
+ case $ac_pass in
+ 1) ac_configure_args0="$ac_configure_args0 '$ac_arg'" ;;
+ 2)
+ ac_configure_args1="$ac_configure_args1 '$ac_arg'"
+ if test $ac_must_keep_next = true; then
+ ac_must_keep_next=false # Got value, back to normal.
+ else
+ case $ac_arg in
+ *=* | --config-cache | -C | -disable-* | --disable-* \
+ | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \
+ | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \
+ | -with-* | --with-* | -without-* | --without-* | --x)
+ case "$ac_configure_args0 " in
+ "$ac_configure_args1"*" '$ac_arg' "* ) continue ;;
+ esac
+ ;;
+ -* ) ac_must_keep_next=true ;;
+ esac
+ fi
+ ac_configure_args="$ac_configure_args '$ac_arg'"
+ ;;
+ esac
+ done
+done
+$as_unset ac_configure_args0 || test "${ac_configure_args0+set}" != set || { ac_configure_args0=; export ac_configure_args0; }
+$as_unset ac_configure_args1 || test "${ac_configure_args1+set}" != set || { ac_configure_args1=; export ac_configure_args1; }
+
+# When interrupted or exit'd, cleanup temporary files, and complete
+# config.log. We remove comments because anyway the quotes in there
+# would cause problems or look ugly.
+# WARNING: Use '\'' to represent an apostrophe within the trap.
+# WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug.
+trap 'exit_status=$?
+ # Save into config.log some information that might help in debugging.
+ {
+ echo
+
+ cat <<\_ASBOX
+## ---------------- ##
+## Cache variables. ##
+## ---------------- ##
+_ASBOX
+ echo
+ # The following way of writing the cache mishandles newlines in values,
+(
+ for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do
+ eval ac_val=\$$ac_var
+ case $ac_val in #(
+ *${as_nl}*)
+ case $ac_var in #(
+ *_cv_*) { $as_echo "$as_me:$LINENO: WARNING: cache variable $ac_var contains a newline" >&5
+$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;;
+ esac
+ case $ac_var in #(
+ _ | IFS | as_nl) ;; #(
+ BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #(
+ *) $as_unset $ac_var ;;
+ esac ;;
+ esac
+ done
+ (set) 2>&1 |
+ case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #(
+ *${as_nl}ac_space=\ *)
+ sed -n \
+ "s/'\''/'\''\\\\'\'''\''/g;
+ s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p"
+ ;; #(
+ *)
+ sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p"
+ ;;
+ esac |
+ sort
+)
+ echo
+
+ cat <<\_ASBOX
+## ----------------- ##
+## Output variables. ##
+## ----------------- ##
+_ASBOX
+ echo
+ for ac_var in $ac_subst_vars
+ do
+ eval ac_val=\$$ac_var
+ case $ac_val in
+ *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;;
+ esac
+ $as_echo "$ac_var='\''$ac_val'\''"
+ done | sort
+ echo
+
+ if test -n "$ac_subst_files"; then
+ cat <<\_ASBOX
+## ------------------- ##
+## File substitutions. ##
+## ------------------- ##
+_ASBOX
+ echo
+ for ac_var in $ac_subst_files
+ do
+ eval ac_val=\$$ac_var
+ case $ac_val in
+ *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;;
+ esac
+ $as_echo "$ac_var='\''$ac_val'\''"
+ done | sort
+ echo
+ fi
+
+ if test -s confdefs.h; then
+ cat <<\_ASBOX
+## ----------- ##
+## confdefs.h. ##
+## ----------- ##
+_ASBOX
+ echo
+ cat confdefs.h
+ echo
+ fi
+ test "$ac_signal" != 0 &&
+ $as_echo "$as_me: caught signal $ac_signal"
+ $as_echo "$as_me: exit $exit_status"
+ } >&5
+ rm -f core *.core core.conftest.* &&
+ rm -f -r conftest* confdefs* conf$$* $ac_clean_files &&
+ exit $exit_status
+' 0
+for ac_signal in 1 2 13 15; do
+ trap 'ac_signal='$ac_signal'; { (exit 1); exit 1; }' $ac_signal
+done
+ac_signal=0
+
+# confdefs.h avoids OS command line length limits that DEFS can exceed.
+rm -f -r conftest* confdefs.h
+
+# Predefined preprocessor variables.
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_NAME "$PACKAGE_NAME"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_TARNAME "$PACKAGE_TARNAME"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_VERSION "$PACKAGE_VERSION"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_STRING "$PACKAGE_STRING"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT"
+_ACEOF
+
+
+# Let the site file select an alternate cache file if it wants to.
+# Prefer an explicitly selected file to automatically selected ones.
+ac_site_file1=NONE
+ac_site_file2=NONE
+if test -n "$CONFIG_SITE"; then
+ ac_site_file1=$CONFIG_SITE
+elif test "x$prefix" != xNONE; then
+ ac_site_file1=$prefix/share/config.site
+ ac_site_file2=$prefix/etc/config.site
+else
+ ac_site_file1=$ac_default_prefix/share/config.site
+ ac_site_file2=$ac_default_prefix/etc/config.site
+fi
+for ac_site_file in "$ac_site_file1" "$ac_site_file2"
+do
+ test "x$ac_site_file" = xNONE && continue
+ if test -r "$ac_site_file"; then
+ { $as_echo "$as_me:$LINENO: loading site script $ac_site_file" >&5
+$as_echo "$as_me: loading site script $ac_site_file" >&6;}
+ sed 's/^/| /' "$ac_site_file" >&5
+ . "$ac_site_file"
+ fi
+done
+
+if test -r "$cache_file"; then
+ # Some versions of bash will fail to source /dev/null (special
+ # files actually), so we avoid doing that.
+ if test -f "$cache_file"; then
+ { $as_echo "$as_me:$LINENO: loading cache $cache_file" >&5
+$as_echo "$as_me: loading cache $cache_file" >&6;}
+ case $cache_file in
+ [\\/]* | ?:[\\/]* ) . "$cache_file";;
+ *) . "./$cache_file";;
+ esac
+ fi
+else
+ { $as_echo "$as_me:$LINENO: creating cache $cache_file" >&5
+$as_echo "$as_me: creating cache $cache_file" >&6;}
+ >$cache_file
+fi
+
+# Check that the precious variables saved in the cache have kept the same
+# value.
+ac_cache_corrupted=false
+for ac_var in $ac_precious_vars; do
+ eval ac_old_set=\$ac_cv_env_${ac_var}_set
+ eval ac_new_set=\$ac_env_${ac_var}_set
+ eval ac_old_val=\$ac_cv_env_${ac_var}_value
+ eval ac_new_val=\$ac_env_${ac_var}_value
+ case $ac_old_set,$ac_new_set in
+ set,)
+ { $as_echo "$as_me:$LINENO: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5
+$as_echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;}
+ ac_cache_corrupted=: ;;
+ ,set)
+ { $as_echo "$as_me:$LINENO: error: \`$ac_var' was not set in the previous run" >&5
+$as_echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;}
+ ac_cache_corrupted=: ;;
+ ,);;
+ *)
+ if test "x$ac_old_val" != "x$ac_new_val"; then
+ # differences in whitespace do not lead to failure.
+ ac_old_val_w=`echo x $ac_old_val`
+ ac_new_val_w=`echo x $ac_new_val`
+ if test "$ac_old_val_w" != "$ac_new_val_w"; then
+ { $as_echo "$as_me:$LINENO: error: \`$ac_var' has changed since the previous run:" >&5
+$as_echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;}
+ ac_cache_corrupted=:
+ else
+ { $as_echo "$as_me:$LINENO: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&5
+$as_echo "$as_me: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&2;}
+ eval $ac_var=\$ac_old_val
+ fi
+ { $as_echo "$as_me:$LINENO: former value: \`$ac_old_val'" >&5
+$as_echo "$as_me: former value: \`$ac_old_val'" >&2;}
+ { $as_echo "$as_me:$LINENO: current value: \`$ac_new_val'" >&5
+$as_echo "$as_me: current value: \`$ac_new_val'" >&2;}
+ fi;;
+ esac
+ # Pass precious variables to config.status.
+ if test "$ac_new_set" = set; then
+ case $ac_new_val in
+ *\'*) ac_arg=$ac_var=`$as_echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;;
+ *) ac_arg=$ac_var=$ac_new_val ;;
+ esac
+ case " $ac_configure_args " in
+ *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy.
+ *) ac_configure_args="$ac_configure_args '$ac_arg'" ;;
+ esac
+ fi
+done
+if $ac_cache_corrupted; then
+ { $as_echo "$as_me:$LINENO: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+ { $as_echo "$as_me:$LINENO: error: changes in the environment can compromise the build" >&5
+$as_echo "$as_me: error: changes in the environment can compromise the build" >&2;}
+ { { $as_echo "$as_me:$LINENO: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&5
+$as_echo "$as_me: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&2;}
+ { (exit 1); exit 1; }; }
+fi
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+VERSION=$PACKAGE_VERSION
+
+
+test "$CFLAGS" || CFLAGS="-g -O3"
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args.
+set dummy ${ac_tool_prefix}gcc; ac_word=$2
+{ $as_echo "$as_me:$LINENO: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_CC+set}" = set; then
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ ac_cv_prog_CC="${ac_tool_prefix}gcc"
+ $as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+IFS=$as_save_IFS
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+ { $as_echo "$as_me:$LINENO: result: $CC" >&5
+$as_echo "$CC" >&6; }
+else
+ { $as_echo "$as_me:$LINENO: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_CC"; then
+ ac_ct_CC=$CC
+ # Extract the first word of "gcc", so it can be a program name with args.
+set dummy gcc; ac_word=$2
+{ $as_echo "$as_me:$LINENO: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_ac_ct_CC+set}" = set; then
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_CC"; then
+ ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ ac_cv_prog_ac_ct_CC="gcc"
+ $as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_CC=$ac_cv_prog_ac_ct_CC
+if test -n "$ac_ct_CC"; then
+ { $as_echo "$as_me:$LINENO: result: $ac_ct_CC" >&5
+$as_echo "$ac_ct_CC" >&6; }
+else
+ { $as_echo "$as_me:$LINENO: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$ac_ct_CC" = x; then
+ CC=""
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:$LINENO: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ CC=$ac_ct_CC
+ fi
+else
+ CC="$ac_cv_prog_CC"
+fi
+
+if test -z "$CC"; then
+ if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args.
+set dummy ${ac_tool_prefix}cc; ac_word=$2
+{ $as_echo "$as_me:$LINENO: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_CC+set}" = set; then
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ ac_cv_prog_CC="${ac_tool_prefix}cc"
+ $as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+IFS=$as_save_IFS
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+ { $as_echo "$as_me:$LINENO: result: $CC" >&5
+$as_echo "$CC" >&6; }
+else
+ { $as_echo "$as_me:$LINENO: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ fi
+fi
+if test -z "$CC"; then
+ # Extract the first word of "cc", so it can be a program name with args.
+set dummy cc; ac_word=$2
+{ $as_echo "$as_me:$LINENO: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_CC+set}" = set; then
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+ ac_prog_rejected=no
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then
+ ac_prog_rejected=yes
+ continue
+ fi
+ ac_cv_prog_CC="cc"
+ $as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+IFS=$as_save_IFS
+
+if test $ac_prog_rejected = yes; then
+ # We found a bogon in the path, so make sure we never use it.
+ set dummy $ac_cv_prog_CC
+ shift
+ if test $# != 0; then
+ # We chose a different compiler from the bogus one.
+ # However, it has the same basename, so the bogon will be chosen
+ # first if we set CC to just the basename; use the full file name.
+ shift
+ ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@"
+ fi
+fi
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+ { $as_echo "$as_me:$LINENO: result: $CC" >&5
+$as_echo "$CC" >&6; }
+else
+ { $as_echo "$as_me:$LINENO: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$CC"; then
+ if test -n "$ac_tool_prefix"; then
+ for ac_prog in cl.exe
+ do
+ # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
+set dummy $ac_tool_prefix$ac_prog; ac_word=$2
+{ $as_echo "$as_me:$LINENO: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_CC+set}" = set; then
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ ac_cv_prog_CC="$ac_tool_prefix$ac_prog"
+ $as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+IFS=$as_save_IFS
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+ { $as_echo "$as_me:$LINENO: result: $CC" >&5
+$as_echo "$CC" >&6; }
+else
+ { $as_echo "$as_me:$LINENO: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ test -n "$CC" && break
+ done
+fi
+if test -z "$CC"; then
+ ac_ct_CC=$CC
+ for ac_prog in cl.exe
+do
+ # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ $as_echo "$as_me:$LINENO: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_ac_ct_CC+set}" = set; then
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_CC"; then
+ ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ ac_cv_prog_ac_ct_CC="$ac_prog"
+ $as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_CC=$ac_cv_prog_ac_ct_CC
+if test -n "$ac_ct_CC"; then
+ { $as_echo "$as_me:$LINENO: result: $ac_ct_CC" >&5
+$as_echo "$ac_ct_CC" >&6; }
+else
+ { $as_echo "$as_me:$LINENO: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ test -n "$ac_ct_CC" && break
+done
+
+ if test "x$ac_ct_CC" = x; then
+ CC=""
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:$LINENO: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ CC=$ac_ct_CC
+ fi
+fi
+
+fi
+
+
+test -z "$CC" && { { $as_echo "$as_me:$LINENO: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+{ { $as_echo "$as_me:$LINENO: error: no acceptable C compiler found in \$PATH
+See \`config.log' for more details." >&5
+$as_echo "$as_me: error: no acceptable C compiler found in \$PATH
+See \`config.log' for more details." >&2;}
+ { (exit 1); exit 1; }; }; }
+
+# Provide some information about the compiler.
+$as_echo "$as_me:$LINENO: checking for C compiler version" >&5
+set X $ac_compile
+ac_compiler=$2
+{ (ac_try="$ac_compiler --version >&5"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_compiler --version >&5") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }
+{ (ac_try="$ac_compiler -v >&5"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_compiler -v >&5") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }
+{ (ac_try="$ac_compiler -V >&5"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_compiler -V >&5") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }
+
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+ac_clean_files_save=$ac_clean_files
+ac_clean_files="$ac_clean_files a.out a.out.dSYM a.exe b.out"
+# Try to create an executable without -o first, disregard a.out.
+# It will help us diagnose broken compilers, and finding out an intuition
+# of exeext.
+{ $as_echo "$as_me:$LINENO: checking for C compiler default output file name" >&5
+$as_echo_n "checking for C compiler default output file name... " >&6; }
+ac_link_default=`$as_echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'`
+
+# The possible output files:
+ac_files="a.out conftest.exe conftest a.exe a_out.exe b.out conftest.*"
+
+ac_rmfiles=
+for ac_file in $ac_files
+do
+ case $ac_file in
+ *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;;
+ * ) ac_rmfiles="$ac_rmfiles $ac_file";;
+ esac
+done
+rm -f $ac_rmfiles
+
+if { (ac_try="$ac_link_default"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_link_default") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; then
+ # Autoconf-2.13 could set the ac_cv_exeext variable to `no'.
+# So ignore a value of `no', otherwise this would lead to `EXEEXT = no'
+# in a Makefile. We should not override ac_cv_exeext if it was cached,
+# so that the user can short-circuit this test for compilers unknown to
+# Autoconf.
+for ac_file in $ac_files ''
+do
+ test -f "$ac_file" || continue
+ case $ac_file in
+ *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj )
+ ;;
+ [ab].out )
+ # We found the default executable, but exeext='' is most
+ # certainly right.
+ break;;
+ *.* )
+ if test "${ac_cv_exeext+set}" = set && test "$ac_cv_exeext" != no;
+ then :; else
+ ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
+ fi
+ # We set ac_cv_exeext here because the later test for it is not
+ # safe: cross compilers may not add the suffix if given an `-o'
+ # argument, so we may need to know it at that point already.
+ # Even if this section looks crufty: it has the advantage of
+ # actually working.
+ break;;
+ * )
+ break;;
+ esac
+done
+test "$ac_cv_exeext" = no && ac_cv_exeext=
+
+else
+ ac_file=''
+fi
+
+{ $as_echo "$as_me:$LINENO: result: $ac_file" >&5
+$as_echo "$ac_file" >&6; }
+if test -z "$ac_file"; then
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+{ { $as_echo "$as_me:$LINENO: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+{ { $as_echo "$as_me:$LINENO: error: C compiler cannot create executables
+See \`config.log' for more details." >&5
+$as_echo "$as_me: error: C compiler cannot create executables
+See \`config.log' for more details." >&2;}
+ { (exit 77); exit 77; }; }; }
+fi
+
+ac_exeext=$ac_cv_exeext
+
+# Check that the compiler produces executables we can run. If not, either
+# the compiler is broken, or we cross compile.
+{ $as_echo "$as_me:$LINENO: checking whether the C compiler works" >&5
+$as_echo_n "checking whether the C compiler works... " >&6; }
+# FIXME: These cross compiler hacks should be removed for Autoconf 3.0
+# If not cross compiling, check that we can run a simple program.
+if test "$cross_compiling" != yes; then
+ if { ac_try='./$ac_file'
+ { (case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_try") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ cross_compiling=no
+ else
+ if test "$cross_compiling" = maybe; then
+ cross_compiling=yes
+ else
+ { { $as_echo "$as_me:$LINENO: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+{ { $as_echo "$as_me:$LINENO: error: cannot run C compiled programs.
+If you meant to cross compile, use \`--host'.
+See \`config.log' for more details." >&5
+$as_echo "$as_me: error: cannot run C compiled programs.
+If you meant to cross compile, use \`--host'.
+See \`config.log' for more details." >&2;}
+ { (exit 1); exit 1; }; }; }
+ fi
+ fi
+fi
+{ $as_echo "$as_me:$LINENO: result: yes" >&5
+$as_echo "yes" >&6; }
+
+rm -f -r a.out a.out.dSYM a.exe conftest$ac_cv_exeext b.out
+ac_clean_files=$ac_clean_files_save
+# Check that the compiler produces executables we can run. If not, either
+# the compiler is broken, or we cross compile.
+{ $as_echo "$as_me:$LINENO: checking whether we are cross compiling" >&5
+$as_echo_n "checking whether we are cross compiling... " >&6; }
+{ $as_echo "$as_me:$LINENO: result: $cross_compiling" >&5
+$as_echo "$cross_compiling" >&6; }
+
+{ $as_echo "$as_me:$LINENO: checking for suffix of executables" >&5
+$as_echo_n "checking for suffix of executables... " >&6; }
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_link") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; then
+ # If both `conftest.exe' and `conftest' are `present' (well, observable)
+# catch `conftest.exe'. For instance with Cygwin, `ls conftest' will
+# work properly (i.e., refer to `conftest.exe'), while it won't with
+# `rm'.
+for ac_file in conftest.exe conftest conftest.*; do
+ test -f "$ac_file" || continue
+ case $ac_file in
+ *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;;
+ *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
+ break;;
+ * ) break;;
+ esac
+done
+else
+ { { $as_echo "$as_me:$LINENO: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+{ { $as_echo "$as_me:$LINENO: error: cannot compute suffix of executables: cannot compile and link
+See \`config.log' for more details." >&5
+$as_echo "$as_me: error: cannot compute suffix of executables: cannot compile and link
+See \`config.log' for more details." >&2;}
+ { (exit 1); exit 1; }; }; }
+fi
+
+rm -f conftest$ac_cv_exeext
+{ $as_echo "$as_me:$LINENO: result: $ac_cv_exeext" >&5
+$as_echo "$ac_cv_exeext" >&6; }
+
+rm -f conftest.$ac_ext
+EXEEXT=$ac_cv_exeext
+ac_exeext=$EXEEXT
+{ $as_echo "$as_me:$LINENO: checking for suffix of object files" >&5
+$as_echo_n "checking for suffix of object files... " >&6; }
+if test "${ac_cv_objext+set}" = set; then
+ $as_echo_n "(cached) " >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.o conftest.obj
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_compile") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; then
+ for ac_file in conftest.o conftest.obj conftest.*; do
+ test -f "$ac_file" || continue;
+ case $ac_file in
+ *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM ) ;;
+ *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'`
+ break;;
+ esac
+done
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+{ { $as_echo "$as_me:$LINENO: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+{ { $as_echo "$as_me:$LINENO: error: cannot compute suffix of object files: cannot compile
+See \`config.log' for more details." >&5
+$as_echo "$as_me: error: cannot compute suffix of object files: cannot compile
+See \`config.log' for more details." >&2;}
+ { (exit 1); exit 1; }; }; }
+fi
+
+rm -f conftest.$ac_cv_objext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:$LINENO: result: $ac_cv_objext" >&5
+$as_echo "$ac_cv_objext" >&6; }
+OBJEXT=$ac_cv_objext
+ac_objext=$OBJEXT
+{ $as_echo "$as_me:$LINENO: checking whether we are using the GNU C compiler" >&5
+$as_echo_n "checking whether we are using the GNU C compiler... " >&6; }
+if test "${ac_cv_c_compiler_gnu+set}" = set; then
+ $as_echo_n "(cached) " >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+int
+main ()
+{
+#ifndef __GNUC__
+ choke me
+#endif
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_compile") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && {
+ test -z "$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest.$ac_objext; then
+ ac_compiler_gnu=yes
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_compiler_gnu=no
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ac_cv_c_compiler_gnu=$ac_compiler_gnu
+
+fi
+{ $as_echo "$as_me:$LINENO: result: $ac_cv_c_compiler_gnu" >&5
+$as_echo "$ac_cv_c_compiler_gnu" >&6; }
+if test $ac_compiler_gnu = yes; then
+ GCC=yes
+else
+ GCC=
+fi
+ac_test_CFLAGS=${CFLAGS+set}
+ac_save_CFLAGS=$CFLAGS
+{ $as_echo "$as_me:$LINENO: checking whether $CC accepts -g" >&5
+$as_echo_n "checking whether $CC accepts -g... " >&6; }
+if test "${ac_cv_prog_cc_g+set}" = set; then
+ $as_echo_n "(cached) " >&6
+else
+ ac_save_c_werror_flag=$ac_c_werror_flag
+ ac_c_werror_flag=yes
+ ac_cv_prog_cc_g=no
+ CFLAGS="-g"
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_compile") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && {
+ test -z "$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest.$ac_objext; then
+ ac_cv_prog_cc_g=yes
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ CFLAGS=""
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_compile") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && {
+ test -z "$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest.$ac_objext; then
+ :
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_c_werror_flag=$ac_save_c_werror_flag
+ CFLAGS="-g"
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_compile") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && {
+ test -z "$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest.$ac_objext; then
+ ac_cv_prog_cc_g=yes
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ ac_c_werror_flag=$ac_save_c_werror_flag
+fi
+{ $as_echo "$as_me:$LINENO: result: $ac_cv_prog_cc_g" >&5
+$as_echo "$ac_cv_prog_cc_g" >&6; }
+if test "$ac_test_CFLAGS" = set; then
+ CFLAGS=$ac_save_CFLAGS
+elif test $ac_cv_prog_cc_g = yes; then
+ if test "$GCC" = yes; then
+ CFLAGS="-g -O2"
+ else
+ CFLAGS="-g"
+ fi
+else
+ if test "$GCC" = yes; then
+ CFLAGS="-O2"
+ else
+ CFLAGS=
+ fi
+fi
+{ $as_echo "$as_me:$LINENO: checking for $CC option to accept ISO C89" >&5
+$as_echo_n "checking for $CC option to accept ISO C89... " >&6; }
+if test "${ac_cv_prog_cc_c89+set}" = set; then
+ $as_echo_n "(cached) " >&6
+else
+ ac_cv_prog_cc_c89=no
+ac_save_CC=$CC
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <stdarg.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+/* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */
+struct buf { int x; };
+FILE * (*rcsopen) (struct buf *, struct stat *, int);
+static char *e (p, i)
+ char **p;
+ int i;
+{
+ return p[i];
+}
+static char *f (char * (*g) (char **, int), char **p, ...)
+{
+ char *s;
+ va_list v;
+ va_start (v,p);
+ s = g (p, va_arg (v,int));
+ va_end (v);
+ return s;
+}
+
+/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has
+ function prototypes and stuff, but not '\xHH' hex character constants.
+ These don't provoke an error unfortunately, instead are silently treated
+ as 'x'. The following induces an error, until -std is added to get
+ proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an
+ array size at least. It's necessary to write '\x00'==0 to get something
+ that's true only with -std. */
+int osf4_cc_array ['\x00' == 0 ? 1 : -1];
+
+/* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters
+ inside strings and character constants. */
+#define FOO(x) 'x'
+int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1];
+
+int test (int i, double x);
+struct s1 {int (*f) (int a);};
+struct s2 {int (*f) (double a);};
+int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int);
+int argc;
+char **argv;
+int
+main ()
+{
+return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1];
+ ;
+ return 0;
+}
+_ACEOF
+for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \
+ -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__"
+do
+ CC="$ac_save_CC $ac_arg"
+ rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_compile") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && {
+ test -z "$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest.$ac_objext; then
+ ac_cv_prog_cc_c89=$ac_arg
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+
+fi
+
+rm -f core conftest.err conftest.$ac_objext
+ test "x$ac_cv_prog_cc_c89" != "xno" && break
+done
+rm -f conftest.$ac_ext
+CC=$ac_save_CC
+
+fi
+# AC_CACHE_VAL
+case "x$ac_cv_prog_cc_c89" in
+ x)
+ { $as_echo "$as_me:$LINENO: result: none needed" >&5
+$as_echo "none needed" >&6; } ;;
+ xno)
+ { $as_echo "$as_me:$LINENO: result: unsupported" >&5
+$as_echo "unsupported" >&6; } ;;
+ *)
+ CC="$CC $ac_cv_prog_cc_c89"
+ { $as_echo "$as_me:$LINENO: result: $ac_cv_prog_cc_c89" >&5
+$as_echo "$ac_cv_prog_cc_c89" >&6; } ;;
+esac
+
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+{ $as_echo "$as_me:$LINENO: checking how to run the C preprocessor" >&5
+$as_echo_n "checking how to run the C preprocessor... " >&6; }
+# On Suns, sometimes $CPP names a directory.
+if test -n "$CPP" && test -d "$CPP"; then
+ CPP=
+fi
+if test -z "$CPP"; then
+ if test "${ac_cv_prog_CPP+set}" = set; then
+ $as_echo_n "(cached) " >&6
+else
+ # Double quotes because CPP needs to be expanded
+ for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp"
+ do
+ ac_preproc_ok=false
+for ac_c_preproc_warn_flag in '' yes
+do
+ # Use a header file that comes with gcc, so configuring glibc
+ # with a fresh cross-compiler works.
+ # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ # <limits.h> exists even on freestanding compilers.
+ # On the NeXT, cc -E runs the code through the compiler's parser,
+ # not just through cpp. "Syntax error" is here to catch this case.
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+ Syntax error
+_ACEOF
+if { (ac_try="$ac_cpp conftest.$ac_ext"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } >/dev/null && {
+ test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ }; then
+ :
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ # Broken: fails on valid input.
+continue
+fi
+
+rm -f conftest.err conftest.$ac_ext
+
+ # OK, works on sane cases. Now check whether nonexistent headers
+ # can be detected and how.
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <ac_nonexistent.h>
+_ACEOF
+if { (ac_try="$ac_cpp conftest.$ac_ext"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } >/dev/null && {
+ test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ }; then
+ # Broken: success on invalid input.
+continue
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ # Passes both tests.
+ac_preproc_ok=:
+break
+fi
+
+rm -f conftest.err conftest.$ac_ext
+
+done
+# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
+rm -f conftest.err conftest.$ac_ext
+if $ac_preproc_ok; then
+ break
+fi
+
+ done
+ ac_cv_prog_CPP=$CPP
+
+fi
+ CPP=$ac_cv_prog_CPP
+else
+ ac_cv_prog_CPP=$CPP
+fi
+{ $as_echo "$as_me:$LINENO: result: $CPP" >&5
+$as_echo "$CPP" >&6; }
+ac_preproc_ok=false
+for ac_c_preproc_warn_flag in '' yes
+do
+ # Use a header file that comes with gcc, so configuring glibc
+ # with a fresh cross-compiler works.
+ # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ # <limits.h> exists even on freestanding compilers.
+ # On the NeXT, cc -E runs the code through the compiler's parser,
+ # not just through cpp. "Syntax error" is here to catch this case.
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+ Syntax error
+_ACEOF
+if { (ac_try="$ac_cpp conftest.$ac_ext"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } >/dev/null && {
+ test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ }; then
+ :
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ # Broken: fails on valid input.
+continue
+fi
+
+rm -f conftest.err conftest.$ac_ext
+
+ # OK, works on sane cases. Now check whether nonexistent headers
+ # can be detected and how.
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <ac_nonexistent.h>
+_ACEOF
+if { (ac_try="$ac_cpp conftest.$ac_ext"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } >/dev/null && {
+ test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ }; then
+ # Broken: success on invalid input.
+continue
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ # Passes both tests.
+ac_preproc_ok=:
+break
+fi
+
+rm -f conftest.err conftest.$ac_ext
+
+done
+# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
+rm -f conftest.err conftest.$ac_ext
+if $ac_preproc_ok; then
+ :
+else
+ { { $as_echo "$as_me:$LINENO: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+{ { $as_echo "$as_me:$LINENO: error: C preprocessor \"$CPP\" fails sanity check
+See \`config.log' for more details." >&5
+$as_echo "$as_me: error: C preprocessor \"$CPP\" fails sanity check
+See \`config.log' for more details." >&2;}
+ { (exit 1); exit 1; }; }; }
+fi
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+{ $as_echo "$as_me:$LINENO: checking for grep that handles long lines and -e" >&5
+$as_echo_n "checking for grep that handles long lines and -e... " >&6; }
+if test "${ac_cv_path_GREP+set}" = set; then
+ $as_echo_n "(cached) " >&6
+else
+ if test -z "$GREP"; then
+ ac_path_GREP_found=false
+ # Loop through the user's path and test for each of PROGNAME-LIST
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_prog in grep ggrep; do
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext"
+ { test -f "$ac_path_GREP" && $as_test_x "$ac_path_GREP"; } || continue
+# Check for GNU ac_path_GREP and select it if it is found.
+ # Check for GNU $ac_path_GREP
+case `"$ac_path_GREP" --version 2>&1` in
+*GNU*)
+ ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;;
+*)
+ ac_count=0
+ $as_echo_n 0123456789 >"conftest.in"
+ while :
+ do
+ cat "conftest.in" "conftest.in" >"conftest.tmp"
+ mv "conftest.tmp" "conftest.in"
+ cp "conftest.in" "conftest.nl"
+ $as_echo 'GREP' >> "conftest.nl"
+ "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break
+ diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break
+ ac_count=`expr $ac_count + 1`
+ if test $ac_count -gt ${ac_path_GREP_max-0}; then
+ # Best one so far, save it but keep looking for a better one
+ ac_cv_path_GREP="$ac_path_GREP"
+ ac_path_GREP_max=$ac_count
+ fi
+ # 10*(2^10) chars as input seems more than enough
+ test $ac_count -gt 10 && break
+ done
+ rm -f conftest.in conftest.tmp conftest.nl conftest.out;;
+esac
+
+ $ac_path_GREP_found && break 3
+ done
+ done
+done
+IFS=$as_save_IFS
+ if test -z "$ac_cv_path_GREP"; then
+ { { $as_echo "$as_me:$LINENO: error: no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&5
+$as_echo "$as_me: error: no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&2;}
+ { (exit 1); exit 1; }; }
+ fi
+else
+ ac_cv_path_GREP=$GREP
+fi
+
+fi
+{ $as_echo "$as_me:$LINENO: result: $ac_cv_path_GREP" >&5
+$as_echo "$ac_cv_path_GREP" >&6; }
+ GREP="$ac_cv_path_GREP"
+
+
+{ $as_echo "$as_me:$LINENO: checking for egrep" >&5
+$as_echo_n "checking for egrep... " >&6; }
+if test "${ac_cv_path_EGREP+set}" = set; then
+ $as_echo_n "(cached) " >&6
+else
+ if echo a | $GREP -E '(a|b)' >/dev/null 2>&1
+ then ac_cv_path_EGREP="$GREP -E"
+ else
+ if test -z "$EGREP"; then
+ ac_path_EGREP_found=false
+ # Loop through the user's path and test for each of PROGNAME-LIST
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_prog in egrep; do
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext"
+ { test -f "$ac_path_EGREP" && $as_test_x "$ac_path_EGREP"; } || continue
+# Check for GNU ac_path_EGREP and select it if it is found.
+ # Check for GNU $ac_path_EGREP
+case `"$ac_path_EGREP" --version 2>&1` in
+*GNU*)
+ ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;;
+*)
+ ac_count=0
+ $as_echo_n 0123456789 >"conftest.in"
+ while :
+ do
+ cat "conftest.in" "conftest.in" >"conftest.tmp"
+ mv "conftest.tmp" "conftest.in"
+ cp "conftest.in" "conftest.nl"
+ $as_echo 'EGREP' >> "conftest.nl"
+ "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break
+ diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break
+ ac_count=`expr $ac_count + 1`
+ if test $ac_count -gt ${ac_path_EGREP_max-0}; then
+ # Best one so far, save it but keep looking for a better one
+ ac_cv_path_EGREP="$ac_path_EGREP"
+ ac_path_EGREP_max=$ac_count
+ fi
+ # 10*(2^10) chars as input seems more than enough
+ test $ac_count -gt 10 && break
+ done
+ rm -f conftest.in conftest.tmp conftest.nl conftest.out;;
+esac
+
+ $ac_path_EGREP_found && break 3
+ done
+ done
+done
+IFS=$as_save_IFS
+ if test -z "$ac_cv_path_EGREP"; then
+ { { $as_echo "$as_me:$LINENO: error: no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&5
+$as_echo "$as_me: error: no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&2;}
+ { (exit 1); exit 1; }; }
+ fi
+else
+ ac_cv_path_EGREP=$EGREP
+fi
+
+ fi
+fi
+{ $as_echo "$as_me:$LINENO: result: $ac_cv_path_EGREP" >&5
+$as_echo "$ac_cv_path_EGREP" >&6; }
+ EGREP="$ac_cv_path_EGREP"
+
+
+{ $as_echo "$as_me:$LINENO: checking for ANSI C header files" >&5
+$as_echo_n "checking for ANSI C header files... " >&6; }
+if test "${ac_cv_header_stdc+set}" = set; then
+ $as_echo_n "(cached) " >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <float.h>
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_compile") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && {
+ test -z "$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest.$ac_objext; then
+ ac_cv_header_stdc=yes
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_cv_header_stdc=no
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+if test $ac_cv_header_stdc = yes; then
+ # SunOS 4.x string.h does not declare mem*, contrary to ANSI.
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <string.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ $EGREP "memchr" >/dev/null 2>&1; then
+ :
+else
+ ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+ # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI.
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <stdlib.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ $EGREP "free" >/dev/null 2>&1; then
+ :
+else
+ ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+ # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi.
+ if test "$cross_compiling" = yes; then
+ :
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <ctype.h>
+#include <stdlib.h>
+#if ((' ' & 0x0FF) == 0x020)
+# define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
+# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c))
+#else
+# define ISLOWER(c) \
+ (('a' <= (c) && (c) <= 'i') \
+ || ('j' <= (c) && (c) <= 'r') \
+ || ('s' <= (c) && (c) <= 'z'))
+# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c))
+#endif
+
+#define XOR(e, f) (((e) && !(f)) || (!(e) && (f)))
+int
+main ()
+{
+ int i;
+ for (i = 0; i < 256; i++)
+ if (XOR (islower (i), ISLOWER (i))
+ || toupper (i) != TOUPPER (i))
+ return 2;
+ return 0;
+}
+_ACEOF
+rm -f conftest$ac_exeext
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_link") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
+ { (case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_try") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ :
+else
+ $as_echo "$as_me: program exited with status $ac_status" >&5
+$as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+( exit $ac_status )
+ac_cv_header_stdc=no
+fi
+rm -rf conftest.dSYM
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
+fi
+
+
+fi
+fi
+{ $as_echo "$as_me:$LINENO: result: $ac_cv_header_stdc" >&5
+$as_echo "$ac_cv_header_stdc" >&6; }
+if test $ac_cv_header_stdc = yes; then
+
+cat >>confdefs.h <<\_ACEOF
+#define STDC_HEADERS 1
+_ACEOF
+
+fi
+
+# On IRIX 5.3, sys/types and inttypes.h are conflicting.
+
+
+
+
+
+
+
+
+
+for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \
+ inttypes.h stdint.h unistd.h
+do
+as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
+{ $as_echo "$as_me:$LINENO: checking for $ac_header" >&5
+$as_echo_n "checking for $ac_header... " >&6; }
+if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
+ $as_echo_n "(cached) " >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+$ac_includes_default
+
+#include <$ac_header>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_compile") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && {
+ test -z "$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest.$ac_objext; then
+ eval "$as_ac_Header=yes"
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ eval "$as_ac_Header=no"
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+ac_res=`eval 'as_val=${'$as_ac_Header'}
+ $as_echo "$as_val"'`
+ { $as_echo "$as_me:$LINENO: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+as_val=`eval 'as_val=${'$as_ac_Header'}
+ $as_echo "$as_val"'`
+ if test "x$as_val" = x""yes; then
+ cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+
+done
+
+
+
+ { $as_echo "$as_me:$LINENO: checking whether byte ordering is bigendian" >&5
+$as_echo_n "checking whether byte ordering is bigendian... " >&6; }
+if test "${ac_cv_c_bigendian+set}" = set; then
+ $as_echo_n "(cached) " >&6
+else
+ ac_cv_c_bigendian=unknown
+ # See if we're dealing with a universal compiler.
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#ifndef __APPLE_CC__
+ not a universal capable compiler
+ #endif
+ typedef int dummy;
+
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_compile") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && {
+ test -z "$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest.$ac_objext; then
+
+ # Check for potential -arch flags. It is not universal unless
+ # there are some -arch flags. Note that *ppc* also matches
+ # ppc64. This check is also rather less than ideal.
+ case "${CC} ${CFLAGS} ${CPPFLAGS} ${LDFLAGS}" in #(
+ *-arch*ppc*|*-arch*i386*|*-arch*x86_64*) ac_cv_c_bigendian=universal;;
+ esac
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ if test $ac_cv_c_bigendian = unknown; then
+ # See if sys/param.h defines the BYTE_ORDER macro.
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <sys/types.h>
+ #include <sys/param.h>
+
+int
+main ()
+{
+#if ! (defined BYTE_ORDER && defined BIG_ENDIAN \
+ && defined LITTLE_ENDIAN && BYTE_ORDER && BIG_ENDIAN \
+ && LITTLE_ENDIAN)
+ bogus endian macros
+ #endif
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_compile") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && {
+ test -z "$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest.$ac_objext; then
+ # It does; now see whether it defined to BIG_ENDIAN or not.
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <sys/types.h>
+ #include <sys/param.h>
+
+int
+main ()
+{
+#if BYTE_ORDER != BIG_ENDIAN
+ not big endian
+ #endif
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_compile") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && {
+ test -z "$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest.$ac_objext; then
+ ac_cv_c_bigendian=yes
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_cv_c_bigendian=no
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ fi
+ if test $ac_cv_c_bigendian = unknown; then
+ # See if <limits.h> defines _LITTLE_ENDIAN or _BIG_ENDIAN (e.g., Solaris).
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <limits.h>
+
+int
+main ()
+{
+#if ! (defined _LITTLE_ENDIAN || defined _BIG_ENDIAN)
+ bogus endian macros
+ #endif
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_compile") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && {
+ test -z "$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest.$ac_objext; then
+ # It does; now see whether it defined to _BIG_ENDIAN or not.
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <limits.h>
+
+int
+main ()
+{
+#ifndef _BIG_ENDIAN
+ not big endian
+ #endif
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_compile") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && {
+ test -z "$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest.$ac_objext; then
+ ac_cv_c_bigendian=yes
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_cv_c_bigendian=no
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ fi
+ if test $ac_cv_c_bigendian = unknown; then
+ # Compile a test program.
+ if test "$cross_compiling" = yes; then
+ # Try to guess by grepping values from an object file.
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+short int ascii_mm[] =
+ { 0x4249, 0x4765, 0x6E44, 0x6961, 0x6E53, 0x7953, 0 };
+ short int ascii_ii[] =
+ { 0x694C, 0x5454, 0x656C, 0x6E45, 0x6944, 0x6E61, 0 };
+ int use_ascii (int i) {
+ return ascii_mm[i] + ascii_ii[i];
+ }
+ short int ebcdic_ii[] =
+ { 0x89D3, 0xE3E3, 0x8593, 0x95C5, 0x89C4, 0x9581, 0 };
+ short int ebcdic_mm[] =
+ { 0xC2C9, 0xC785, 0x95C4, 0x8981, 0x95E2, 0xA8E2, 0 };
+ int use_ebcdic (int i) {
+ return ebcdic_mm[i] + ebcdic_ii[i];
+ }
+ extern int foo;
+
+int
+main ()
+{
+return use_ascii (foo) == use_ebcdic (foo);
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_compile") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && {
+ test -z "$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest.$ac_objext; then
+ if grep BIGenDianSyS conftest.$ac_objext >/dev/null; then
+ ac_cv_c_bigendian=yes
+ fi
+ if grep LiTTleEnDian conftest.$ac_objext >/dev/null ; then
+ if test "$ac_cv_c_bigendian" = unknown; then
+ ac_cv_c_bigendian=no
+ else
+ # finding both strings is unlikely to happen, but who knows?
+ ac_cv_c_bigendian=unknown
+ fi
+ fi
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+$ac_includes_default
+int
+main ()
+{
+
+ /* Are we little or big endian? From Harbison&Steele. */
+ union
+ {
+ long int l;
+ char c[sizeof (long int)];
+ } u;
+ u.l = 1;
+ return u.c[sizeof (long int) - 1] == 1;
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest$ac_exeext
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_link") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
+ { (case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_try") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_cv_c_bigendian=no
+else
+ $as_echo "$as_me: program exited with status $ac_status" >&5
+$as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+( exit $ac_status )
+ac_cv_c_bigendian=yes
+fi
+rm -rf conftest.dSYM
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
+fi
+
+
+ fi
+fi
+{ $as_echo "$as_me:$LINENO: result: $ac_cv_c_bigendian" >&5
+$as_echo "$ac_cv_c_bigendian" >&6; }
+ case $ac_cv_c_bigendian in #(
+ yes)
+
+cat >>confdefs.h <<\_ACEOF
+#define WORDS_BIG_ENDIAN 1
+_ACEOF
+;; #(
+ no)
+
+cat >>confdefs.h <<\_ACEOF
+#define WORDS_LITTLE_ENDIAN 1
+_ACEOF
+ ;; #(
+ universal)
+
+cat >>confdefs.h <<\_ACEOF
+#define AC_APPLE_UNIVERSAL_BUILD 1
+_ACEOF
+
+ ;; #(
+ *)
+ { { $as_echo "$as_me:$LINENO: error: unknown endianness
+ presetting ac_cv_c_bigendian=no (or yes) will help" >&5
+$as_echo "$as_me: error: unknown endianness
+ presetting ac_cv_c_bigendian=no (or yes) will help" >&2;}
+ { (exit 1); exit 1; }; } ;;
+ esac
+
+
+test "$prefix" = NONE && prefix=/usr/local
+Datadir=$datadir
+test "$Datadir" = '${datarootdir}' && Datadir=$datarootdir
+test "$Datadir" = '${prefix}/share' && Datadir=$prefix/share
+
+
+
+# Check whether --with-latex was given.
+if test "${with_latex+set}" = set; then
+ withval=$with_latex; if test "x$withval" != "x" ; then
+ latexdir=$withval
+ fi
+
+else
+
+# Extract the first word of "kpsewhich", so it can be a program name with args.
+set dummy kpsewhich; ac_word=$2
+{ $as_echo "$as_me:$LINENO: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_kpsewhich+set}" = set; then
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$kpsewhich"; then
+ ac_cv_prog_kpsewhich="$kpsewhich" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ ac_cv_prog_kpsewhich="true"
+ $as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+IFS=$as_save_IFS
+
+fi
+fi
+kpsewhich=$ac_cv_prog_kpsewhich
+if test -n "$kpsewhich"; then
+ { $as_echo "$as_me:$LINENO: result: $kpsewhich" >&5
+$as_echo "$kpsewhich" >&6; }
+else
+ { $as_echo "$as_me:$LINENO: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+if test "x$kpsewhich" = "xtrue"; then
+ latexdir=`kpsewhich -expand-var='$TEXMFLOCAL'/tex/latex`
+else
+ latexdir=$prefix/share/texmf/tex/latex
+ as_ac_File=`$as_echo "ac_cv_file_$latexdir/base/latex.ltx" | $as_tr_sh`
+{ $as_echo "$as_me:$LINENO: checking for $latexdir/base/latex.ltx" >&5
+$as_echo_n "checking for $latexdir/base/latex.ltx... " >&6; }
+if { as_var=$as_ac_File; eval "test \"\${$as_var+set}\" = set"; }; then
+ $as_echo_n "(cached) " >&6
+else
+ test "$cross_compiling" = yes &&
+ { { $as_echo "$as_me:$LINENO: error: cannot check for file existence when cross compiling" >&5
+$as_echo "$as_me: error: cannot check for file existence when cross compiling" >&2;}
+ { (exit 1); exit 1; }; }
+if test -r "$latexdir/base/latex.ltx"; then
+ eval "$as_ac_File=yes"
+else
+ eval "$as_ac_File=no"
+fi
+fi
+ac_res=`eval 'as_val=${'$as_ac_File'}
+ $as_echo "$as_val"'`
+ { $as_echo "$as_me:$LINENO: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+as_val=`eval 'as_val=${'$as_ac_File'}
+ $as_echo "$as_val"'`
+ if test "x$as_val" = x""yes; then
+ :
+else
+ latexdir=/usr/share/texmf/tex/latex
+ as_ac_File=`$as_echo "ac_cv_file_$latexdir/base/latex.ltx" | $as_tr_sh`
+{ $as_echo "$as_me:$LINENO: checking for $latexdir/base/latex.ltx" >&5
+$as_echo_n "checking for $latexdir/base/latex.ltx... " >&6; }
+if { as_var=$as_ac_File; eval "test \"\${$as_var+set}\" = set"; }; then
+ $as_echo_n "(cached) " >&6
+else
+ test "$cross_compiling" = yes &&
+ { { $as_echo "$as_me:$LINENO: error: cannot check for file existence when cross compiling" >&5
+$as_echo "$as_me: error: cannot check for file existence when cross compiling" >&2;}
+ { (exit 1); exit 1; }; }
+if test -r "$latexdir/base/latex.ltx"; then
+ eval "$as_ac_File=yes"
+else
+ eval "$as_ac_File=no"
+fi
+fi
+ac_res=`eval 'as_val=${'$as_ac_File'}
+ $as_echo "$as_val"'`
+ { $as_echo "$as_me:$LINENO: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+as_val=`eval 'as_val=${'$as_ac_File'}
+ $as_echo "$as_val"'`
+
+fi
+
+fi
+
+fi
+
+
+for ac_prog in texi2dvi texi2dvi4a2ps
+do
+ # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ $as_echo "$as_me:$LINENO: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_TEXI2DVI+set}" = set; then
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$TEXI2DVI"; then
+ ac_cv_prog_TEXI2DVI="$TEXI2DVI" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ ac_cv_prog_TEXI2DVI="$ac_prog"
+ $as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+IFS=$as_save_IFS
+
+fi
+fi
+TEXI2DVI=$ac_cv_prog_TEXI2DVI
+if test -n "$TEXI2DVI"; then
+ { $as_echo "$as_me:$LINENO: result: $TEXI2DVI" >&5
+$as_echo "$TEXI2DVI" >&6; }
+else
+ { $as_echo "$as_me:$LINENO: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ test -n "$TEXI2DVI" && break
+done
+
+
+
+latexdir=$latexdir/asymptote
+
+{ $as_echo "$as_me:$LINENO: Using $latexdir for LaTeX style file" >&5
+$as_echo "$as_me: Using $latexdir for LaTeX style file" >&6;}
+
+
+
+docdir=$Datadir/doc/asymptote
+
+
+# Check whether --with-docdir was given.
+if test "${with_docdir+set}" = set; then
+ withval=$with_docdir; if test "x$withval" != "x" ; then
+ docdir=$withval
+ fi
+
+fi
+
+
+
+sysdir=$Datadir/asymptote
+
+# Check whether --enable-tetex-build was given.
+if test "${enable_tetex_build+set}" = set; then
+ enableval=$enable_tetex_build; if test "x$enableval" = "xyes" ; then
+ sysdir=""
+ fi
+
+fi
+
+
+
+cat >>confdefs.h <<_ACEOF
+#define ASYMPTOTE_SYSDIR "$sysdir"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define ASYMPTOTE_DOCDIR "$docdir"
+_ACEOF
+
+
+
+
+ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+
+# Checks for programs.
+ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+if test -z "$CXX"; then
+ if test -n "$CCC"; then
+ CXX=$CCC
+ else
+ if test -n "$ac_tool_prefix"; then
+ for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC
+ do
+ # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
+set dummy $ac_tool_prefix$ac_prog; ac_word=$2
+{ $as_echo "$as_me:$LINENO: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_CXX+set}" = set; then
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$CXX"; then
+ ac_cv_prog_CXX="$CXX" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ ac_cv_prog_CXX="$ac_tool_prefix$ac_prog"
+ $as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+IFS=$as_save_IFS
+
+fi
+fi
+CXX=$ac_cv_prog_CXX
+if test -n "$CXX"; then
+ { $as_echo "$as_me:$LINENO: result: $CXX" >&5
+$as_echo "$CXX" >&6; }
+else
+ { $as_echo "$as_me:$LINENO: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ test -n "$CXX" && break
+ done
+fi
+if test -z "$CXX"; then
+ ac_ct_CXX=$CXX
+ for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC
+do
+ # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ $as_echo "$as_me:$LINENO: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_ac_ct_CXX+set}" = set; then
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_CXX"; then
+ ac_cv_prog_ac_ct_CXX="$ac_ct_CXX" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ ac_cv_prog_ac_ct_CXX="$ac_prog"
+ $as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_CXX=$ac_cv_prog_ac_ct_CXX
+if test -n "$ac_ct_CXX"; then
+ { $as_echo "$as_me:$LINENO: result: $ac_ct_CXX" >&5
+$as_echo "$ac_ct_CXX" >&6; }
+else
+ { $as_echo "$as_me:$LINENO: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ test -n "$ac_ct_CXX" && break
+done
+
+ if test "x$ac_ct_CXX" = x; then
+ CXX="g++"
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:$LINENO: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ CXX=$ac_ct_CXX
+ fi
+fi
+
+ fi
+fi
+# Provide some information about the compiler.
+$as_echo "$as_me:$LINENO: checking for C++ compiler version" >&5
+set X $ac_compile
+ac_compiler=$2
+{ (ac_try="$ac_compiler --version >&5"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_compiler --version >&5") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }
+{ (ac_try="$ac_compiler -v >&5"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_compiler -v >&5") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }
+{ (ac_try="$ac_compiler -V >&5"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_compiler -V >&5") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }
+
+{ $as_echo "$as_me:$LINENO: checking whether we are using the GNU C++ compiler" >&5
+$as_echo_n "checking whether we are using the GNU C++ compiler... " >&6; }
+if test "${ac_cv_cxx_compiler_gnu+set}" = set; then
+ $as_echo_n "(cached) " >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+int
+main ()
+{
+#ifndef __GNUC__
+ choke me
+#endif
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_compile") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && {
+ test -z "$ac_cxx_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest.$ac_objext; then
+ ac_compiler_gnu=yes
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_compiler_gnu=no
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ac_cv_cxx_compiler_gnu=$ac_compiler_gnu
+
+fi
+{ $as_echo "$as_me:$LINENO: result: $ac_cv_cxx_compiler_gnu" >&5
+$as_echo "$ac_cv_cxx_compiler_gnu" >&6; }
+if test $ac_compiler_gnu = yes; then
+ GXX=yes
+else
+ GXX=
+fi
+ac_test_CXXFLAGS=${CXXFLAGS+set}
+ac_save_CXXFLAGS=$CXXFLAGS
+{ $as_echo "$as_me:$LINENO: checking whether $CXX accepts -g" >&5
+$as_echo_n "checking whether $CXX accepts -g... " >&6; }
+if test "${ac_cv_prog_cxx_g+set}" = set; then
+ $as_echo_n "(cached) " >&6
+else
+ ac_save_cxx_werror_flag=$ac_cxx_werror_flag
+ ac_cxx_werror_flag=yes
+ ac_cv_prog_cxx_g=no
+ CXXFLAGS="-g"
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_compile") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && {
+ test -z "$ac_cxx_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest.$ac_objext; then
+ ac_cv_prog_cxx_g=yes
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ CXXFLAGS=""
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_compile") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && {
+ test -z "$ac_cxx_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest.$ac_objext; then
+ :
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_cxx_werror_flag=$ac_save_cxx_werror_flag
+ CXXFLAGS="-g"
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_compile") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && {
+ test -z "$ac_cxx_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest.$ac_objext; then
+ ac_cv_prog_cxx_g=yes
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ ac_cxx_werror_flag=$ac_save_cxx_werror_flag
+fi
+{ $as_echo "$as_me:$LINENO: result: $ac_cv_prog_cxx_g" >&5
+$as_echo "$ac_cv_prog_cxx_g" >&6; }
+if test "$ac_test_CXXFLAGS" = set; then
+ CXXFLAGS=$ac_save_CXXFLAGS
+elif test $ac_cv_prog_cxx_g = yes; then
+ if test "$GXX" = yes; then
+ CXXFLAGS="-g -O2"
+ else
+ CXXFLAGS="-g"
+ fi
+else
+ if test "$GXX" = yes; then
+ CXXFLAGS="-O2"
+ else
+ CXXFLAGS=
+ fi
+fi
+ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+
+for ac_prog in flex lex
+do
+ # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ $as_echo "$as_me:$LINENO: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_LEX+set}" = set; then
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$LEX"; then
+ ac_cv_prog_LEX="$LEX" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ ac_cv_prog_LEX="$ac_prog"
+ $as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+IFS=$as_save_IFS
+
+fi
+fi
+LEX=$ac_cv_prog_LEX
+if test -n "$LEX"; then
+ { $as_echo "$as_me:$LINENO: result: $LEX" >&5
+$as_echo "$LEX" >&6; }
+else
+ { $as_echo "$as_me:$LINENO: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ test -n "$LEX" && break
+done
+test -n "$LEX" || LEX=":"
+
+if test "x$LEX" != "x:"; then
+ cat >conftest.l <<_ACEOF
+%%
+a { ECHO; }
+b { REJECT; }
+c { yymore (); }
+d { yyless (1); }
+e { yyless (input () != 0); }
+f { unput (yytext[0]); }
+. { BEGIN INITIAL; }
+%%
+#ifdef YYTEXT_POINTER
+extern char *yytext;
+#endif
+int
+main (void)
+{
+ return ! yylex () + ! yywrap ();
+}
+_ACEOF
+{ (ac_try="$LEX conftest.l"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$LEX conftest.l") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }
+{ $as_echo "$as_me:$LINENO: checking lex output file root" >&5
+$as_echo_n "checking lex output file root... " >&6; }
+if test "${ac_cv_prog_lex_root+set}" = set; then
+ $as_echo_n "(cached) " >&6
+else
+
+if test -f lex.yy.c; then
+ ac_cv_prog_lex_root=lex.yy
+elif test -f lexyy.c; then
+ ac_cv_prog_lex_root=lexyy
+else
+ { { $as_echo "$as_me:$LINENO: error: cannot find output from $LEX; giving up" >&5
+$as_echo "$as_me: error: cannot find output from $LEX; giving up" >&2;}
+ { (exit 1); exit 1; }; }
+fi
+fi
+{ $as_echo "$as_me:$LINENO: result: $ac_cv_prog_lex_root" >&5
+$as_echo "$ac_cv_prog_lex_root" >&6; }
+LEX_OUTPUT_ROOT=$ac_cv_prog_lex_root
+
+if test -z "${LEXLIB+set}"; then
+ { $as_echo "$as_me:$LINENO: checking lex library" >&5
+$as_echo_n "checking lex library... " >&6; }
+if test "${ac_cv_lib_lex+set}" = set; then
+ $as_echo_n "(cached) " >&6
+else
+
+ ac_save_LIBS=$LIBS
+ ac_cv_lib_lex='none needed'
+ for ac_lib in '' -lfl -ll; do
+ LIBS="$ac_lib $ac_save_LIBS"
+ cat >conftest.$ac_ext <<_ACEOF
+`cat $LEX_OUTPUT_ROOT.c`
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_link") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && {
+ test -z "$ac_cxx_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest$ac_exeext && {
+ test "$cross_compiling" = yes ||
+ $as_test_x conftest$ac_exeext
+ }; then
+ ac_cv_lib_lex=$ac_lib
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+
+fi
+
+rm -rf conftest.dSYM
+rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
+ conftest$ac_exeext conftest.$ac_ext
+ test "$ac_cv_lib_lex" != 'none needed' && break
+ done
+ LIBS=$ac_save_LIBS
+
+fi
+{ $as_echo "$as_me:$LINENO: result: $ac_cv_lib_lex" >&5
+$as_echo "$ac_cv_lib_lex" >&6; }
+ test "$ac_cv_lib_lex" != 'none needed' && LEXLIB=$ac_cv_lib_lex
+fi
+
+
+{ $as_echo "$as_me:$LINENO: checking whether yytext is a pointer" >&5
+$as_echo_n "checking whether yytext is a pointer... " >&6; }
+if test "${ac_cv_prog_lex_yytext_pointer+set}" = set; then
+ $as_echo_n "(cached) " >&6
+else
+ # POSIX says lex can declare yytext either as a pointer or an array; the
+# default is implementation-dependent. Figure out which it is, since
+# not all implementations provide the %pointer and %array declarations.
+ac_cv_prog_lex_yytext_pointer=no
+ac_save_LIBS=$LIBS
+LIBS="$LEXLIB $ac_save_LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+#define YYTEXT_POINTER 1
+`cat $LEX_OUTPUT_ROOT.c`
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_link") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && {
+ test -z "$ac_cxx_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest$ac_exeext && {
+ test "$cross_compiling" = yes ||
+ $as_test_x conftest$ac_exeext
+ }; then
+ ac_cv_prog_lex_yytext_pointer=yes
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+
+fi
+
+rm -rf conftest.dSYM
+rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_save_LIBS
+
+fi
+{ $as_echo "$as_me:$LINENO: result: $ac_cv_prog_lex_yytext_pointer" >&5
+$as_echo "$ac_cv_prog_lex_yytext_pointer" >&6; }
+if test $ac_cv_prog_lex_yytext_pointer = yes; then
+
+cat >>confdefs.h <<\_ACEOF
+#define YYTEXT_POINTER 1
+_ACEOF
+
+fi
+rm -f conftest.l $LEX_OUTPUT_ROOT.c
+
+fi
+ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+if test -z "$CXX"; then
+ if test -n "$CCC"; then
+ CXX=$CCC
+ else
+ if test -n "$ac_tool_prefix"; then
+ for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC
+ do
+ # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
+set dummy $ac_tool_prefix$ac_prog; ac_word=$2
+{ $as_echo "$as_me:$LINENO: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_CXX+set}" = set; then
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$CXX"; then
+ ac_cv_prog_CXX="$CXX" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ ac_cv_prog_CXX="$ac_tool_prefix$ac_prog"
+ $as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+IFS=$as_save_IFS
+
+fi
+fi
+CXX=$ac_cv_prog_CXX
+if test -n "$CXX"; then
+ { $as_echo "$as_me:$LINENO: result: $CXX" >&5
+$as_echo "$CXX" >&6; }
+else
+ { $as_echo "$as_me:$LINENO: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ test -n "$CXX" && break
+ done
+fi
+if test -z "$CXX"; then
+ ac_ct_CXX=$CXX
+ for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC
+do
+ # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ $as_echo "$as_me:$LINENO: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_ac_ct_CXX+set}" = set; then
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_CXX"; then
+ ac_cv_prog_ac_ct_CXX="$ac_ct_CXX" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ ac_cv_prog_ac_ct_CXX="$ac_prog"
+ $as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_CXX=$ac_cv_prog_ac_ct_CXX
+if test -n "$ac_ct_CXX"; then
+ { $as_echo "$as_me:$LINENO: result: $ac_ct_CXX" >&5
+$as_echo "$ac_ct_CXX" >&6; }
+else
+ { $as_echo "$as_me:$LINENO: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ test -n "$ac_ct_CXX" && break
+done
+
+ if test "x$ac_ct_CXX" = x; then
+ CXX="g++"
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:$LINENO: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ CXX=$ac_ct_CXX
+ fi
+fi
+
+ fi
+fi
+# Provide some information about the compiler.
+$as_echo "$as_me:$LINENO: checking for C++ compiler version" >&5
+set X $ac_compile
+ac_compiler=$2
+{ (ac_try="$ac_compiler --version >&5"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_compiler --version >&5") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }
+{ (ac_try="$ac_compiler -v >&5"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_compiler -v >&5") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }
+{ (ac_try="$ac_compiler -V >&5"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_compiler -V >&5") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }
+
+{ $as_echo "$as_me:$LINENO: checking whether we are using the GNU C++ compiler" >&5
+$as_echo_n "checking whether we are using the GNU C++ compiler... " >&6; }
+if test "${ac_cv_cxx_compiler_gnu+set}" = set; then
+ $as_echo_n "(cached) " >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+int
+main ()
+{
+#ifndef __GNUC__
+ choke me
+#endif
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_compile") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && {
+ test -z "$ac_cxx_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest.$ac_objext; then
+ ac_compiler_gnu=yes
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_compiler_gnu=no
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ac_cv_cxx_compiler_gnu=$ac_compiler_gnu
+
+fi
+{ $as_echo "$as_me:$LINENO: result: $ac_cv_cxx_compiler_gnu" >&5
+$as_echo "$ac_cv_cxx_compiler_gnu" >&6; }
+if test $ac_compiler_gnu = yes; then
+ GXX=yes
+else
+ GXX=
+fi
+ac_test_CXXFLAGS=${CXXFLAGS+set}
+ac_save_CXXFLAGS=$CXXFLAGS
+{ $as_echo "$as_me:$LINENO: checking whether $CXX accepts -g" >&5
+$as_echo_n "checking whether $CXX accepts -g... " >&6; }
+if test "${ac_cv_prog_cxx_g+set}" = set; then
+ $as_echo_n "(cached) " >&6
+else
+ ac_save_cxx_werror_flag=$ac_cxx_werror_flag
+ ac_cxx_werror_flag=yes
+ ac_cv_prog_cxx_g=no
+ CXXFLAGS="-g"
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_compile") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && {
+ test -z "$ac_cxx_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest.$ac_objext; then
+ ac_cv_prog_cxx_g=yes
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ CXXFLAGS=""
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_compile") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && {
+ test -z "$ac_cxx_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest.$ac_objext; then
+ :
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_cxx_werror_flag=$ac_save_cxx_werror_flag
+ CXXFLAGS="-g"
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_compile") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && {
+ test -z "$ac_cxx_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest.$ac_objext; then
+ ac_cv_prog_cxx_g=yes
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ ac_cxx_werror_flag=$ac_save_cxx_werror_flag
+fi
+{ $as_echo "$as_me:$LINENO: result: $ac_cv_prog_cxx_g" >&5
+$as_echo "$ac_cv_prog_cxx_g" >&6; }
+if test "$ac_test_CXXFLAGS" = set; then
+ CXXFLAGS=$ac_save_CXXFLAGS
+elif test $ac_cv_prog_cxx_g = yes; then
+ if test "$GXX" = yes; then
+ CXXFLAGS="-g -O2"
+ else
+ CXXFLAGS="-g"
+ fi
+else
+ if test "$GXX" = yes; then
+ CXXFLAGS="-O2"
+ else
+ CXXFLAGS=
+ fi
+fi
+ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+ac_aux_dir=
+for ac_dir in "$srcdir" "$srcdir/.." "$srcdir/../.."; do
+ if test -f "$ac_dir/install-sh"; then
+ ac_aux_dir=$ac_dir
+ ac_install_sh="$ac_aux_dir/install-sh -c"
+ break
+ elif test -f "$ac_dir/install.sh"; then
+ ac_aux_dir=$ac_dir
+ ac_install_sh="$ac_aux_dir/install.sh -c"
+ break
+ elif test -f "$ac_dir/shtool"; then
+ ac_aux_dir=$ac_dir
+ ac_install_sh="$ac_aux_dir/shtool install -c"
+ break
+ fi
+done
+if test -z "$ac_aux_dir"; then
+ { { $as_echo "$as_me:$LINENO: error: cannot find install-sh or install.sh in \"$srcdir\" \"$srcdir/..\" \"$srcdir/../..\"" >&5
+$as_echo "$as_me: error: cannot find install-sh or install.sh in \"$srcdir\" \"$srcdir/..\" \"$srcdir/../..\"" >&2;}
+ { (exit 1); exit 1; }; }
+fi
+
+# These three variables are undocumented and unsupported,
+# and are intended to be withdrawn in a future Autoconf release.
+# They can cause serious problems if a builder's source tree is in a directory
+# whose full name contains unusual characters.
+ac_config_guess="$SHELL $ac_aux_dir/config.guess" # Please don't use this var.
+ac_config_sub="$SHELL $ac_aux_dir/config.sub" # Please don't use this var.
+ac_configure="$SHELL $ac_aux_dir/configure" # Please don't use this var.
+
+
+# Find a good install program. We prefer a C program (faster),
+# so one script is as good as another. But avoid the broken or
+# incompatible versions:
+# SysV /etc/install, /usr/sbin/install
+# SunOS /usr/etc/install
+# IRIX /sbin/install
+# AIX /bin/install
+# AmigaOS /C/install, which installs bootblocks on floppy discs
+# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag
+# AFS /usr/afsws/bin/install, which mishandles nonexistent args
+# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff"
+# OS/2's system install, which has a completely different semantic
+# ./install, which can be erroneously created by make from ./install.sh.
+# Reject install programs that cannot install multiple files.
+{ $as_echo "$as_me:$LINENO: checking for a BSD-compatible install" >&5
+$as_echo_n "checking for a BSD-compatible install... " >&6; }
+if test -z "$INSTALL"; then
+if test "${ac_cv_path_install+set}" = set; then
+ $as_echo_n "(cached) " >&6
+else
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ # Account for people who put trailing slashes in PATH elements.
+case $as_dir/ in
+ ./ | .// | /cC/* | \
+ /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \
+ ?:\\/os2\\/install\\/* | ?:\\/OS2\\/INSTALL\\/* | \
+ /usr/ucb/* ) ;;
+ *)
+ # OSF1 and SCO ODT 3.0 have their own names for install.
+ # Don't use installbsd from OSF since it installs stuff as root
+ # by default.
+ for ac_prog in ginstall scoinst install; do
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_prog$ac_exec_ext" && $as_test_x "$as_dir/$ac_prog$ac_exec_ext"; }; then
+ if test $ac_prog = install &&
+ grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then
+ # AIX install. It has an incompatible calling convention.
+ :
+ elif test $ac_prog = install &&
+ grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then
+ # program-specific install script used by HP pwplus--don't use.
+ :
+ else
+ rm -rf conftest.one conftest.two conftest.dir
+ echo one > conftest.one
+ echo two > conftest.two
+ mkdir conftest.dir
+ if "$as_dir/$ac_prog$ac_exec_ext" -c conftest.one conftest.two "`pwd`/conftest.dir" &&
+ test -s conftest.one && test -s conftest.two &&
+ test -s conftest.dir/conftest.one &&
+ test -s conftest.dir/conftest.two
+ then
+ ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c"
+ break 3
+ fi
+ fi
+ fi
+ done
+ done
+ ;;
+esac
+
+done
+IFS=$as_save_IFS
+
+rm -rf conftest.one conftest.two conftest.dir
+
+fi
+ if test "${ac_cv_path_install+set}" = set; then
+ INSTALL=$ac_cv_path_install
+ else
+ # As a last resort, use the slow shell script. Don't cache a
+ # value for INSTALL within a source directory, because that will
+ # break other packages using the cache if that directory is
+ # removed, or if the value is a relative name.
+ INSTALL=$ac_install_sh
+ fi
+fi
+{ $as_echo "$as_me:$LINENO: result: $INSTALL" >&5
+$as_echo "$INSTALL" >&6; }
+
+# Use test -z because SunOS4 sh mishandles braces in ${var-val}.
+# It thinks the first close brace ends the variable substitution.
+test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}'
+
+test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}'
+
+test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644'
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args.
+set dummy ${ac_tool_prefix}gcc; ac_word=$2
+{ $as_echo "$as_me:$LINENO: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_CC+set}" = set; then
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ ac_cv_prog_CC="${ac_tool_prefix}gcc"
+ $as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+IFS=$as_save_IFS
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+ { $as_echo "$as_me:$LINENO: result: $CC" >&5
+$as_echo "$CC" >&6; }
+else
+ { $as_echo "$as_me:$LINENO: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_CC"; then
+ ac_ct_CC=$CC
+ # Extract the first word of "gcc", so it can be a program name with args.
+set dummy gcc; ac_word=$2
+{ $as_echo "$as_me:$LINENO: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_ac_ct_CC+set}" = set; then
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_CC"; then
+ ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ ac_cv_prog_ac_ct_CC="gcc"
+ $as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_CC=$ac_cv_prog_ac_ct_CC
+if test -n "$ac_ct_CC"; then
+ { $as_echo "$as_me:$LINENO: result: $ac_ct_CC" >&5
+$as_echo "$ac_ct_CC" >&6; }
+else
+ { $as_echo "$as_me:$LINENO: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$ac_ct_CC" = x; then
+ CC=""
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:$LINENO: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ CC=$ac_ct_CC
+ fi
+else
+ CC="$ac_cv_prog_CC"
+fi
+
+if test -z "$CC"; then
+ if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args.
+set dummy ${ac_tool_prefix}cc; ac_word=$2
+{ $as_echo "$as_me:$LINENO: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_CC+set}" = set; then
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ ac_cv_prog_CC="${ac_tool_prefix}cc"
+ $as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+IFS=$as_save_IFS
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+ { $as_echo "$as_me:$LINENO: result: $CC" >&5
+$as_echo "$CC" >&6; }
+else
+ { $as_echo "$as_me:$LINENO: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ fi
+fi
+if test -z "$CC"; then
+ # Extract the first word of "cc", so it can be a program name with args.
+set dummy cc; ac_word=$2
+{ $as_echo "$as_me:$LINENO: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_CC+set}" = set; then
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+ ac_prog_rejected=no
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then
+ ac_prog_rejected=yes
+ continue
+ fi
+ ac_cv_prog_CC="cc"
+ $as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+IFS=$as_save_IFS
+
+if test $ac_prog_rejected = yes; then
+ # We found a bogon in the path, so make sure we never use it.
+ set dummy $ac_cv_prog_CC
+ shift
+ if test $# != 0; then
+ # We chose a different compiler from the bogus one.
+ # However, it has the same basename, so the bogon will be chosen
+ # first if we set CC to just the basename; use the full file name.
+ shift
+ ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@"
+ fi
+fi
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+ { $as_echo "$as_me:$LINENO: result: $CC" >&5
+$as_echo "$CC" >&6; }
+else
+ { $as_echo "$as_me:$LINENO: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$CC"; then
+ if test -n "$ac_tool_prefix"; then
+ for ac_prog in cl.exe
+ do
+ # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
+set dummy $ac_tool_prefix$ac_prog; ac_word=$2
+{ $as_echo "$as_me:$LINENO: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_CC+set}" = set; then
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ ac_cv_prog_CC="$ac_tool_prefix$ac_prog"
+ $as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+IFS=$as_save_IFS
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+ { $as_echo "$as_me:$LINENO: result: $CC" >&5
+$as_echo "$CC" >&6; }
+else
+ { $as_echo "$as_me:$LINENO: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ test -n "$CC" && break
+ done
+fi
+if test -z "$CC"; then
+ ac_ct_CC=$CC
+ for ac_prog in cl.exe
+do
+ # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ $as_echo "$as_me:$LINENO: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_ac_ct_CC+set}" = set; then
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_CC"; then
+ ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ ac_cv_prog_ac_ct_CC="$ac_prog"
+ $as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_CC=$ac_cv_prog_ac_ct_CC
+if test -n "$ac_ct_CC"; then
+ { $as_echo "$as_me:$LINENO: result: $ac_ct_CC" >&5
+$as_echo "$ac_ct_CC" >&6; }
+else
+ { $as_echo "$as_me:$LINENO: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ test -n "$ac_ct_CC" && break
+done
+
+ if test "x$ac_ct_CC" = x; then
+ CC=""
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:$LINENO: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ CC=$ac_ct_CC
+ fi
+fi
+
+fi
+
+
+test -z "$CC" && { { $as_echo "$as_me:$LINENO: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+{ { $as_echo "$as_me:$LINENO: error: no acceptable C compiler found in \$PATH
+See \`config.log' for more details." >&5
+$as_echo "$as_me: error: no acceptable C compiler found in \$PATH
+See \`config.log' for more details." >&2;}
+ { (exit 1); exit 1; }; }; }
+
+# Provide some information about the compiler.
+$as_echo "$as_me:$LINENO: checking for C compiler version" >&5
+set X $ac_compile
+ac_compiler=$2
+{ (ac_try="$ac_compiler --version >&5"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_compiler --version >&5") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }
+{ (ac_try="$ac_compiler -v >&5"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_compiler -v >&5") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }
+{ (ac_try="$ac_compiler -V >&5"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_compiler -V >&5") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }
+
+{ $as_echo "$as_me:$LINENO: checking whether we are using the GNU C compiler" >&5
+$as_echo_n "checking whether we are using the GNU C compiler... " >&6; }
+if test "${ac_cv_c_compiler_gnu+set}" = set; then
+ $as_echo_n "(cached) " >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+int
+main ()
+{
+#ifndef __GNUC__
+ choke me
+#endif
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_compile") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && {
+ test -z "$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest.$ac_objext; then
+ ac_compiler_gnu=yes
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_compiler_gnu=no
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ac_cv_c_compiler_gnu=$ac_compiler_gnu
+
+fi
+{ $as_echo "$as_me:$LINENO: result: $ac_cv_c_compiler_gnu" >&5
+$as_echo "$ac_cv_c_compiler_gnu" >&6; }
+if test $ac_compiler_gnu = yes; then
+ GCC=yes
+else
+ GCC=
+fi
+ac_test_CFLAGS=${CFLAGS+set}
+ac_save_CFLAGS=$CFLAGS
+{ $as_echo "$as_me:$LINENO: checking whether $CC accepts -g" >&5
+$as_echo_n "checking whether $CC accepts -g... " >&6; }
+if test "${ac_cv_prog_cc_g+set}" = set; then
+ $as_echo_n "(cached) " >&6
+else
+ ac_save_c_werror_flag=$ac_c_werror_flag
+ ac_c_werror_flag=yes
+ ac_cv_prog_cc_g=no
+ CFLAGS="-g"
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_compile") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && {
+ test -z "$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest.$ac_objext; then
+ ac_cv_prog_cc_g=yes
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ CFLAGS=""
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_compile") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && {
+ test -z "$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest.$ac_objext; then
+ :
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_c_werror_flag=$ac_save_c_werror_flag
+ CFLAGS="-g"
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_compile") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && {
+ test -z "$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest.$ac_objext; then
+ ac_cv_prog_cc_g=yes
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ ac_c_werror_flag=$ac_save_c_werror_flag
+fi
+{ $as_echo "$as_me:$LINENO: result: $ac_cv_prog_cc_g" >&5
+$as_echo "$ac_cv_prog_cc_g" >&6; }
+if test "$ac_test_CFLAGS" = set; then
+ CFLAGS=$ac_save_CFLAGS
+elif test $ac_cv_prog_cc_g = yes; then
+ if test "$GCC" = yes; then
+ CFLAGS="-g -O2"
+ else
+ CFLAGS="-g"
+ fi
+else
+ if test "$GCC" = yes; then
+ CFLAGS="-O2"
+ else
+ CFLAGS=
+ fi
+fi
+{ $as_echo "$as_me:$LINENO: checking for $CC option to accept ISO C89" >&5
+$as_echo_n "checking for $CC option to accept ISO C89... " >&6; }
+if test "${ac_cv_prog_cc_c89+set}" = set; then
+ $as_echo_n "(cached) " >&6
+else
+ ac_cv_prog_cc_c89=no
+ac_save_CC=$CC
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <stdarg.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+/* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */
+struct buf { int x; };
+FILE * (*rcsopen) (struct buf *, struct stat *, int);
+static char *e (p, i)
+ char **p;
+ int i;
+{
+ return p[i];
+}
+static char *f (char * (*g) (char **, int), char **p, ...)
+{
+ char *s;
+ va_list v;
+ va_start (v,p);
+ s = g (p, va_arg (v,int));
+ va_end (v);
+ return s;
+}
+
+/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has
+ function prototypes and stuff, but not '\xHH' hex character constants.
+ These don't provoke an error unfortunately, instead are silently treated
+ as 'x'. The following induces an error, until -std is added to get
+ proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an
+ array size at least. It's necessary to write '\x00'==0 to get something
+ that's true only with -std. */
+int osf4_cc_array ['\x00' == 0 ? 1 : -1];
+
+/* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters
+ inside strings and character constants. */
+#define FOO(x) 'x'
+int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1];
+
+int test (int i, double x);
+struct s1 {int (*f) (int a);};
+struct s2 {int (*f) (double a);};
+int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int);
+int argc;
+char **argv;
+int
+main ()
+{
+return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1];
+ ;
+ return 0;
+}
+_ACEOF
+for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \
+ -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__"
+do
+ CC="$ac_save_CC $ac_arg"
+ rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_compile") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && {
+ test -z "$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest.$ac_objext; then
+ ac_cv_prog_cc_c89=$ac_arg
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+
+fi
+
+rm -f core conftest.err conftest.$ac_objext
+ test "x$ac_cv_prog_cc_c89" != "xno" && break
+done
+rm -f conftest.$ac_ext
+CC=$ac_save_CC
+
+fi
+# AC_CACHE_VAL
+case "x$ac_cv_prog_cc_c89" in
+ x)
+ { $as_echo "$as_me:$LINENO: result: none needed" >&5
+$as_echo "none needed" >&6; } ;;
+ xno)
+ { $as_echo "$as_me:$LINENO: result: unsupported" >&5
+$as_echo "unsupported" >&6; } ;;
+ *)
+ CC="$CC $ac_cv_prog_cc_c89"
+ { $as_echo "$as_me:$LINENO: result: $ac_cv_prog_cc_c89" >&5
+$as_echo "$ac_cv_prog_cc_c89" >&6; } ;;
+esac
+
+
+ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+{ $as_echo "$as_me:$LINENO: checking whether ${MAKE-make} sets \$(MAKE)" >&5
+$as_echo_n "checking whether ${MAKE-make} sets \$(MAKE)... " >&6; }
+set x ${MAKE-make}
+ac_make=`$as_echo "$2" | sed 's/+/p/g; s/[^a-zA-Z0-9_]/_/g'`
+if { as_var=ac_cv_prog_make_${ac_make}_set; eval "test \"\${$as_var+set}\" = set"; }; then
+ $as_echo_n "(cached) " >&6
+else
+ cat >conftest.make <<\_ACEOF
+SHELL = /bin/sh
+all:
+ @echo '@@@%%%=$(MAKE)=@@@%%%'
+_ACEOF
+# GNU make sometimes prints "make[1]: Entering...", which would confuse us.
+case `${MAKE-make} -f conftest.make 2>/dev/null` in
+ *@@@%%%=?*=@@@%%%*)
+ eval ac_cv_prog_make_${ac_make}_set=yes;;
+ *)
+ eval ac_cv_prog_make_${ac_make}_set=no;;
+esac
+rm -f conftest.make
+fi
+if eval test \$ac_cv_prog_make_${ac_make}_set = yes; then
+ { $as_echo "$as_me:$LINENO: result: yes" >&5
+$as_echo "yes" >&6; }
+ SET_MAKE=
+else
+ { $as_echo "$as_me:$LINENO: result: no" >&5
+$as_echo "no" >&6; }
+ SET_MAKE="MAKE=${MAKE-make}"
+fi
+
+for ac_prog in 'bison -y' byacc
+do
+ # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ $as_echo "$as_me:$LINENO: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_YACC+set}" = set; then
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$YACC"; then
+ ac_cv_prog_YACC="$YACC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ ac_cv_prog_YACC="$ac_prog"
+ $as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+IFS=$as_save_IFS
+
+fi
+fi
+YACC=$ac_cv_prog_YACC
+if test -n "$YACC"; then
+ { $as_echo "$as_me:$LINENO: result: $YACC" >&5
+$as_echo "$YACC" >&6; }
+else
+ { $as_echo "$as_me:$LINENO: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ test -n "$YACC" && break
+done
+test -n "$YACC" || YACC="yacc"
+
+
+if test "$GXX" = yes ; then
+ ac_gcc_version=`echo __GNUC__ | $CC -E - | grep -v ^\#`
+ if test "$ac_gcc_version" -lt 4; then
+ CFLAGS=$CFLAGS" -finline-limit=400"
+ fi
+fi
+
+ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+{ $as_echo "$as_me:$LINENO: checking how to run the C++ preprocessor" >&5
+$as_echo_n "checking how to run the C++ preprocessor... " >&6; }
+if test -z "$CXXCPP"; then
+ if test "${ac_cv_prog_CXXCPP+set}" = set; then
+ $as_echo_n "(cached) " >&6
+else
+ # Double quotes because CXXCPP needs to be expanded
+ for CXXCPP in "$CXX -E" "/lib/cpp"
+ do
+ ac_preproc_ok=false
+for ac_cxx_preproc_warn_flag in '' yes
+do
+ # Use a header file that comes with gcc, so configuring glibc
+ # with a fresh cross-compiler works.
+ # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ # <limits.h> exists even on freestanding compilers.
+ # On the NeXT, cc -E runs the code through the compiler's parser,
+ # not just through cpp. "Syntax error" is here to catch this case.
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+ Syntax error
+_ACEOF
+if { (ac_try="$ac_cpp conftest.$ac_ext"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } >/dev/null && {
+ test -z "$ac_cxx_preproc_warn_flag$ac_cxx_werror_flag" ||
+ test ! -s conftest.err
+ }; then
+ :
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ # Broken: fails on valid input.
+continue
+fi
+
+rm -f conftest.err conftest.$ac_ext
+
+ # OK, works on sane cases. Now check whether nonexistent headers
+ # can be detected and how.
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <ac_nonexistent.h>
+_ACEOF
+if { (ac_try="$ac_cpp conftest.$ac_ext"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } >/dev/null && {
+ test -z "$ac_cxx_preproc_warn_flag$ac_cxx_werror_flag" ||
+ test ! -s conftest.err
+ }; then
+ # Broken: success on invalid input.
+continue
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ # Passes both tests.
+ac_preproc_ok=:
+break
+fi
+
+rm -f conftest.err conftest.$ac_ext
+
+done
+# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
+rm -f conftest.err conftest.$ac_ext
+if $ac_preproc_ok; then
+ break
+fi
+
+ done
+ ac_cv_prog_CXXCPP=$CXXCPP
+
+fi
+ CXXCPP=$ac_cv_prog_CXXCPP
+else
+ ac_cv_prog_CXXCPP=$CXXCPP
+fi
+{ $as_echo "$as_me:$LINENO: result: $CXXCPP" >&5
+$as_echo "$CXXCPP" >&6; }
+ac_preproc_ok=false
+for ac_cxx_preproc_warn_flag in '' yes
+do
+ # Use a header file that comes with gcc, so configuring glibc
+ # with a fresh cross-compiler works.
+ # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ # <limits.h> exists even on freestanding compilers.
+ # On the NeXT, cc -E runs the code through the compiler's parser,
+ # not just through cpp. "Syntax error" is here to catch this case.
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+ Syntax error
+_ACEOF
+if { (ac_try="$ac_cpp conftest.$ac_ext"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } >/dev/null && {
+ test -z "$ac_cxx_preproc_warn_flag$ac_cxx_werror_flag" ||
+ test ! -s conftest.err
+ }; then
+ :
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ # Broken: fails on valid input.
+continue
+fi
+
+rm -f conftest.err conftest.$ac_ext
+
+ # OK, works on sane cases. Now check whether nonexistent headers
+ # can be detected and how.
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <ac_nonexistent.h>
+_ACEOF
+if { (ac_try="$ac_cpp conftest.$ac_ext"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } >/dev/null && {
+ test -z "$ac_cxx_preproc_warn_flag$ac_cxx_werror_flag" ||
+ test ! -s conftest.err
+ }; then
+ # Broken: success on invalid input.
+continue
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ # Passes both tests.
+ac_preproc_ok=:
+break
+fi
+
+rm -f conftest.err conftest.$ac_ext
+
+done
+# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
+rm -f conftest.err conftest.$ac_ext
+if $ac_preproc_ok; then
+ :
+else
+ { { $as_echo "$as_me:$LINENO: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+{ { $as_echo "$as_me:$LINENO: error: C++ preprocessor \"$CXXCPP\" fails sanity check
+See \`config.log' for more details." >&5
+$as_echo "$as_me: error: C++ preprocessor \"$CXXCPP\" fails sanity check
+See \`config.log' for more details." >&2;}
+ { (exit 1); exit 1; }; }; }
+fi
+
+ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+
+if test "${ac_cv_header_fftw3_h+set}" = set; then
+ { $as_echo "$as_me:$LINENO: checking for fftw3.h" >&5
+$as_echo_n "checking for fftw3.h... " >&6; }
+if test "${ac_cv_header_fftw3_h+set}" = set; then
+ $as_echo_n "(cached) " >&6
+fi
+{ $as_echo "$as_me:$LINENO: result: $ac_cv_header_fftw3_h" >&5
+$as_echo "$ac_cv_header_fftw3_h" >&6; }
+else
+ # Is the header compilable?
+{ $as_echo "$as_me:$LINENO: checking fftw3.h usability" >&5
+$as_echo_n "checking fftw3.h usability... " >&6; }
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+$ac_includes_default
+#include <fftw3.h>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_compile") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && {
+ test -z "$ac_cxx_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest.$ac_objext; then
+ ac_header_compiler=yes
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_header_compiler=no
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+{ $as_echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
+$as_echo "$ac_header_compiler" >&6; }
+
+# Is the header present?
+{ $as_echo "$as_me:$LINENO: checking fftw3.h presence" >&5
+$as_echo_n "checking fftw3.h presence... " >&6; }
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <fftw3.h>
+_ACEOF
+if { (ac_try="$ac_cpp conftest.$ac_ext"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } >/dev/null && {
+ test -z "$ac_cxx_preproc_warn_flag$ac_cxx_werror_flag" ||
+ test ! -s conftest.err
+ }; then
+ ac_header_preproc=yes
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_header_preproc=no
+fi
+
+rm -f conftest.err conftest.$ac_ext
+{ $as_echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
+$as_echo "$ac_header_preproc" >&6; }
+
+# So? What about this header?
+case $ac_header_compiler:$ac_header_preproc:$ac_cxx_preproc_warn_flag in
+ yes:no: )
+ { $as_echo "$as_me:$LINENO: WARNING: fftw3.h: accepted by the compiler, rejected by the preprocessor!" >&5
+$as_echo "$as_me: WARNING: fftw3.h: accepted by the compiler, rejected by the preprocessor!" >&2;}
+ { $as_echo "$as_me:$LINENO: WARNING: fftw3.h: proceeding with the compiler's result" >&5
+$as_echo "$as_me: WARNING: fftw3.h: proceeding with the compiler's result" >&2;}
+ ac_header_preproc=yes
+ ;;
+ no:yes:* )
+ { $as_echo "$as_me:$LINENO: WARNING: fftw3.h: present but cannot be compiled" >&5
+$as_echo "$as_me: WARNING: fftw3.h: present but cannot be compiled" >&2;}
+ { $as_echo "$as_me:$LINENO: WARNING: fftw3.h: check for missing prerequisite headers?" >&5
+$as_echo "$as_me: WARNING: fftw3.h: check for missing prerequisite headers?" >&2;}
+ { $as_echo "$as_me:$LINENO: WARNING: fftw3.h: see the Autoconf documentation" >&5
+$as_echo "$as_me: WARNING: fftw3.h: see the Autoconf documentation" >&2;}
+ { $as_echo "$as_me:$LINENO: WARNING: fftw3.h: section \"Present But Cannot Be Compiled\"" >&5
+$as_echo "$as_me: WARNING: fftw3.h: section \"Present But Cannot Be Compiled\"" >&2;}
+ { $as_echo "$as_me:$LINENO: WARNING: fftw3.h: proceeding with the preprocessor's result" >&5
+$as_echo "$as_me: WARNING: fftw3.h: proceeding with the preprocessor's result" >&2;}
+ { $as_echo "$as_me:$LINENO: WARNING: fftw3.h: in the future, the compiler will take precedence" >&5
+$as_echo "$as_me: WARNING: fftw3.h: in the future, the compiler will take precedence" >&2;}
+ ( cat <<\_ASBOX
+## -------------------------------------------------------- ##
+## Report this to http://sourceforge.net/projects/asymptote ##
+## -------------------------------------------------------- ##
+_ASBOX
+ ) | sed "s/^/$as_me: WARNING: /" >&2
+ ;;
+esac
+{ $as_echo "$as_me:$LINENO: checking for fftw3.h" >&5
+$as_echo_n "checking for fftw3.h... " >&6; }
+if test "${ac_cv_header_fftw3_h+set}" = set; then
+ $as_echo_n "(cached) " >&6
+else
+ ac_cv_header_fftw3_h=$ac_header_preproc
+fi
+{ $as_echo "$as_me:$LINENO: result: $ac_cv_header_fftw3_h" >&5
+$as_echo "$ac_cv_header_fftw3_h" >&6; }
+
+fi
+if test "x$ac_cv_header_fftw3_h" = x""yes; then
+
+{ $as_echo "$as_me:$LINENO: checking for fftw_execute in -lfftw3" >&5
+$as_echo_n "checking for fftw_execute in -lfftw3... " >&6; }
+if test "${ac_cv_lib_fftw3_fftw_execute+set}" = set; then
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lfftw3 $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* 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 fftw_execute ();
+int
+main ()
+{
+return fftw_execute ();
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_link") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && {
+ test -z "$ac_cxx_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest$ac_exeext && {
+ test "$cross_compiling" = yes ||
+ $as_test_x conftest$ac_exeext
+ }; then
+ ac_cv_lib_fftw3_fftw_execute=yes
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_cv_lib_fftw3_fftw_execute=no
+fi
+
+rm -rf conftest.dSYM
+rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:$LINENO: result: $ac_cv_lib_fftw3_fftw_execute" >&5
+$as_echo "$ac_cv_lib_fftw3_fftw_execute" >&6; }
+if test "x$ac_cv_lib_fftw3_fftw_execute" = x""yes; then
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_LIBFFTW3 1
+_ACEOF
+
+ LIBS="-lfftw3 $LIBS"
+
+else
+ { $as_echo "$as_me:$LINENO: *** Could not find libfftw3: will compile without optional fast Fourier transforms. ***" >&5
+$as_echo "$as_me: *** Could not find libfftw3: will compile without optional fast Fourier transforms. ***" >&6;}
+fi
+
+else
+ { $as_echo "$as_me:$LINENO: *** Header file fftw3.h not found: will compile without optional fast Fourier transforms. ***" >&5
+$as_echo "$as_me: *** Header file fftw3.h not found: will compile without optional fast Fourier transforms. ***" >&6;}
+fi
+
+
+
+GCVERSION=gc-7.1
+
+as_ac_File=`$as_echo "ac_cv_file_$GCVERSION.tar.gz" | $as_tr_sh`
+{ $as_echo "$as_me:$LINENO: checking for $GCVERSION.tar.gz" >&5
+$as_echo_n "checking for $GCVERSION.tar.gz... " >&6; }
+if { as_var=$as_ac_File; eval "test \"\${$as_var+set}\" = set"; }; then
+ $as_echo_n "(cached) " >&6
+else
+ test "$cross_compiling" = yes &&
+ { { $as_echo "$as_me:$LINENO: error: cannot check for file existence when cross compiling" >&5
+$as_echo "$as_me: error: cannot check for file existence when cross compiling" >&2;}
+ { (exit 1); exit 1; }; }
+if test -r "$GCVERSION.tar.gz"; then
+ eval "$as_ac_File=yes"
+else
+ eval "$as_ac_File=no"
+fi
+fi
+ac_res=`eval 'as_val=${'$as_ac_File'}
+ $as_echo "$as_val"'`
+ { $as_echo "$as_me:$LINENO: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+as_val=`eval 'as_val=${'$as_ac_File'}
+ $as_echo "$as_val"'`
+ if test "x$as_val" = x""yes; then
+ ac_cv_use_gc=$GCVERSION
+else
+ GC_SYSTEM="$GCVERSION.tar.gz not found: using system Boehm garbage collector"
+ac_cv_use_gc="system"
+fi
+
+# Check whether --enable-gc was given.
+if test "${enable_gc+set}" = set; then
+ enableval=$enable_gc;
+ if test "x$enableval" != "xyes"; then
+ ac_cv_use_gc=$enableval
+ GC_SYSTEM=""
+ fi
+
+fi
+
+
+OPTIONS="-D_FILE_OFFSET_BITS=64 "
+GCLIB=
+GCPPLIB=
+GCNAME="Boehm Garbage Collector"
+GCOPTIONS=""
+if test "x$ac_cv_use_gc" != "xno" ; then
+ OPTIONS=$OPTIONS"-DUSEGC "
+ case $ac_cv_use_gc in
+ system|*[\\/]*)
+ if test "x$ac_cv_use_gc" = "xsystem" ; then
+ INCL="-I$prefix/include/gc -I/usr/include/gc"
+ LIBS=$LIBS"-L$prefix/lib "
+ else
+ INCL="-I$ac_cv_use_gc/include/gc"
+ LIBS=$LIBS"-L$ac_cv_use_gc/lib "
+ fi
+ CPPFLAGS_SAVE=$CPPFLAGS
+ CPPFLAGS=$CPPFLAGS" $INCL"
+ if test "${ac_cv_header_gc_h+set}" = set; then
+ { $as_echo "$as_me:$LINENO: checking for gc.h" >&5
+$as_echo_n "checking for gc.h... " >&6; }
+if test "${ac_cv_header_gc_h+set}" = set; then
+ $as_echo_n "(cached) " >&6
+fi
+{ $as_echo "$as_me:$LINENO: result: $ac_cv_header_gc_h" >&5
+$as_echo "$ac_cv_header_gc_h" >&6; }
+else
+ # Is the header compilable?
+{ $as_echo "$as_me:$LINENO: checking gc.h usability" >&5
+$as_echo_n "checking gc.h usability... " >&6; }
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+$ac_includes_default
+#include <gc.h>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_compile") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && {
+ test -z "$ac_cxx_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest.$ac_objext; then
+ ac_header_compiler=yes
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_header_compiler=no
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+{ $as_echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
+$as_echo "$ac_header_compiler" >&6; }
+
+# Is the header present?
+{ $as_echo "$as_me:$LINENO: checking gc.h presence" >&5
+$as_echo_n "checking gc.h presence... " >&6; }
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <gc.h>
+_ACEOF
+if { (ac_try="$ac_cpp conftest.$ac_ext"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } >/dev/null && {
+ test -z "$ac_cxx_preproc_warn_flag$ac_cxx_werror_flag" ||
+ test ! -s conftest.err
+ }; then
+ ac_header_preproc=yes
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_header_preproc=no
+fi
+
+rm -f conftest.err conftest.$ac_ext
+{ $as_echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
+$as_echo "$ac_header_preproc" >&6; }
+
+# So? What about this header?
+case $ac_header_compiler:$ac_header_preproc:$ac_cxx_preproc_warn_flag in
+ yes:no: )
+ { $as_echo "$as_me:$LINENO: WARNING: gc.h: accepted by the compiler, rejected by the preprocessor!" >&5
+$as_echo "$as_me: WARNING: gc.h: accepted by the compiler, rejected by the preprocessor!" >&2;}
+ { $as_echo "$as_me:$LINENO: WARNING: gc.h: proceeding with the compiler's result" >&5
+$as_echo "$as_me: WARNING: gc.h: proceeding with the compiler's result" >&2;}
+ ac_header_preproc=yes
+ ;;
+ no:yes:* )
+ { $as_echo "$as_me:$LINENO: WARNING: gc.h: present but cannot be compiled" >&5
+$as_echo "$as_me: WARNING: gc.h: present but cannot be compiled" >&2;}
+ { $as_echo "$as_me:$LINENO: WARNING: gc.h: check for missing prerequisite headers?" >&5
+$as_echo "$as_me: WARNING: gc.h: check for missing prerequisite headers?" >&2;}
+ { $as_echo "$as_me:$LINENO: WARNING: gc.h: see the Autoconf documentation" >&5
+$as_echo "$as_me: WARNING: gc.h: see the Autoconf documentation" >&2;}
+ { $as_echo "$as_me:$LINENO: WARNING: gc.h: section \"Present But Cannot Be Compiled\"" >&5
+$as_echo "$as_me: WARNING: gc.h: section \"Present But Cannot Be Compiled\"" >&2;}
+ { $as_echo "$as_me:$LINENO: WARNING: gc.h: proceeding with the preprocessor's result" >&5
+$as_echo "$as_me: WARNING: gc.h: proceeding with the preprocessor's result" >&2;}
+ { $as_echo "$as_me:$LINENO: WARNING: gc.h: in the future, the compiler will take precedence" >&5
+$as_echo "$as_me: WARNING: gc.h: in the future, the compiler will take precedence" >&2;}
+ ( cat <<\_ASBOX
+## -------------------------------------------------------- ##
+## Report this to http://sourceforge.net/projects/asymptote ##
+## -------------------------------------------------------- ##
+_ASBOX
+ ) | sed "s/^/$as_me: WARNING: /" >&2
+ ;;
+esac
+{ $as_echo "$as_me:$LINENO: checking for gc.h" >&5
+$as_echo_n "checking for gc.h... " >&6; }
+if test "${ac_cv_header_gc_h+set}" = set; then
+ $as_echo_n "(cached) " >&6
+else
+ ac_cv_header_gc_h=$ac_header_preproc
+fi
+{ $as_echo "$as_me:$LINENO: result: $ac_cv_header_gc_h" >&5
+$as_echo "$ac_cv_header_gc_h" >&6; }
+
+fi
+if test "x$ac_cv_header_gc_h" = x""yes; then
+ { $as_echo "$as_me:$LINENO: checking for GC_malloc in -lgc" >&5
+$as_echo_n "checking for GC_malloc in -lgc... " >&6; }
+if test "${ac_cv_lib_gc_GC_malloc+set}" = set; then
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lgc $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* 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 GC_malloc ();
+int
+main ()
+{
+return GC_malloc ();
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_link") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && {
+ test -z "$ac_cxx_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest$ac_exeext && {
+ test "$cross_compiling" = yes ||
+ $as_test_x conftest$ac_exeext
+ }; then
+ ac_cv_lib_gc_GC_malloc=yes
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_cv_lib_gc_GC_malloc=no
+fi
+
+rm -rf conftest.dSYM
+rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:$LINENO: result: $ac_cv_lib_gc_GC_malloc" >&5
+$as_echo "$ac_cv_lib_gc_GC_malloc" >&6; }
+if test "x$ac_cv_lib_gc_GC_malloc" = x""yes; then
+
+ LIBS=$LIBS"-lgc "
+ { $as_echo "$as_me:$LINENO: enabling system $GCNAME" >&5
+$as_echo "$as_me: enabling system $GCNAME" >&6;}
+else
+
+ GCDIR=$GCVERSION
+ GCLIB="\$(GC)/.libs/libgc.a"
+ { $as_echo "$as_me:$LINENO: $GCNAME library not found" >&5
+$as_echo "$as_me: $GCNAME library not found" >&6;}
+fi
+
+else
+ GCDIR=$GCVERSION
+ INCL="-I\$(GC)/include"
+ { $as_echo "$as_me:$LINENO: $GCNAME header file not found" >&5
+$as_echo "$as_me: $GCNAME header file not found" >&6;}
+fi
+
+
+ CPPFLAGS=$CPPFLAGS_SAVE
+ ;;
+ *)
+ GCDIR=$ac_cv_use_gc
+ GCOPTIONS="--disable-shared "
+ { $as_echo "$as_me:$LINENO: enabling local $GCNAME $GCDIR" >&5
+$as_echo "$as_me: enabling local $GCNAME $GCDIR" >&6;}
+ GCLIB="\$(GC)/.libs/libgc.a"
+ INCL="-I\$(GC)/include"
+ ;;
+ esac
+else
+ { $as_echo "$as_me:$LINENO: disabling the $GCNAME" >&5
+$as_echo "$as_me: disabling the $GCNAME" >&6;}
+fi
+
+# Check whether --enable-gc-debug was given.
+if test "${enable_gc_debug+set}" = set; then
+ enableval=$enable_gc_debug; if test "x$ac_cv_use_gc" != "xno" ; then
+ if test "x$enableval" = "xyes" ; then
+ OPTIONS=$OPTIONS"-DGC_DEBUG "
+ { $as_echo "$as_me:$LINENO: *** Enabling GC debugging: remember to make clean ***" >&5
+$as_echo "$as_me: *** Enabling GC debugging: remember to make clean ***" >&6;}
+ { $as_echo "$as_me:$LINENO: *** Set the environment variable GC_FIND_LEAK at runtime ***" >&5
+$as_echo "$as_me: *** Set the environment variable GC_FIND_LEAK at runtime ***" >&6;}
+ fi
+ fi
+
+fi
+
+
+# Check whether --enable-gc-full-debug was given.
+if test "${enable_gc_full_debug+set}" = set; then
+ enableval=$enable_gc_full_debug; if test "x$ac_cv_use_gc" != "xno" ; then
+ if test "x$enableval" = "xyes" ; then
+ OPTIONS=$OPTIONS"-DGC_DEBUG -DGC_BACKTRACE "
+ GCOPTIONS=$GCOPTIONS"--enable-gc-debug "
+ { $as_echo "$as_me:$LINENO: *** Enabling GC backtrace debugging; remember to make gc-clean ***" >&5
+$as_echo "$as_me: *** Enabling GC backtrace debugging; remember to make gc-clean ***" >&6;}
+ fi
+ fi
+
+fi
+
+
+{ $as_echo "$as_me:$LINENO: checking for getopt_long_only" >&5
+$as_echo_n "checking for getopt_long_only... " >&6; }
+if test "${ac_cv_func_getopt_long_only+set}" = set; then
+ $as_echo_n "(cached) " >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+/* Define getopt_long_only to an innocuous variant, in case <limits.h> declares getopt_long_only.
+ For example, HP-UX 11i <limits.h> declares gettimeofday. */
+#define getopt_long_only innocuous_getopt_long_only
+
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char getopt_long_only (); below.
+ Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ <limits.h> exists even on freestanding compilers. */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef getopt_long_only
+
+/* 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 getopt_long_only ();
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined __stub_getopt_long_only || defined __stub___getopt_long_only
+choke me
+#endif
+
+int
+main ()
+{
+return getopt_long_only ();
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_link") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && {
+ test -z "$ac_cxx_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest$ac_exeext && {
+ test "$cross_compiling" = yes ||
+ $as_test_x conftest$ac_exeext
+ }; then
+ ac_cv_func_getopt_long_only=yes
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_cv_func_getopt_long_only=no
+fi
+
+rm -rf conftest.dSYM
+rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
+ conftest$ac_exeext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:$LINENO: result: $ac_cv_func_getopt_long_only" >&5
+$as_echo "$ac_cv_func_getopt_long_only" >&6; }
+if test "x$ac_cv_func_getopt_long_only" = x""yes; then
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_GNU_GETOPT_H 1
+_ACEOF
+
+else
+ getopt="getopt getopt1"
+fi
+
+if test "${ac_cv_header_tr1_unordered_map+set}" = set; then
+ { $as_echo "$as_me:$LINENO: checking for tr1/unordered_map" >&5
+$as_echo_n "checking for tr1/unordered_map... " >&6; }
+if test "${ac_cv_header_tr1_unordered_map+set}" = set; then
+ $as_echo_n "(cached) " >&6
+fi
+{ $as_echo "$as_me:$LINENO: result: $ac_cv_header_tr1_unordered_map" >&5
+$as_echo "$ac_cv_header_tr1_unordered_map" >&6; }
+else
+ # Is the header compilable?
+{ $as_echo "$as_me:$LINENO: checking tr1/unordered_map usability" >&5
+$as_echo_n "checking tr1/unordered_map usability... " >&6; }
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+$ac_includes_default
+#include <tr1/unordered_map>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_compile") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && {
+ test -z "$ac_cxx_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest.$ac_objext; then
+ ac_header_compiler=yes
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_header_compiler=no
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+{ $as_echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
+$as_echo "$ac_header_compiler" >&6; }
+
+# Is the header present?
+{ $as_echo "$as_me:$LINENO: checking tr1/unordered_map presence" >&5
+$as_echo_n "checking tr1/unordered_map presence... " >&6; }
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <tr1/unordered_map>
+_ACEOF
+if { (ac_try="$ac_cpp conftest.$ac_ext"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } >/dev/null && {
+ test -z "$ac_cxx_preproc_warn_flag$ac_cxx_werror_flag" ||
+ test ! -s conftest.err
+ }; then
+ ac_header_preproc=yes
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_header_preproc=no
+fi
+
+rm -f conftest.err conftest.$ac_ext
+{ $as_echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
+$as_echo "$ac_header_preproc" >&6; }
+
+# So? What about this header?
+case $ac_header_compiler:$ac_header_preproc:$ac_cxx_preproc_warn_flag in
+ yes:no: )
+ { $as_echo "$as_me:$LINENO: WARNING: tr1/unordered_map: accepted by the compiler, rejected by the preprocessor!" >&5
+$as_echo "$as_me: WARNING: tr1/unordered_map: accepted by the compiler, rejected by the preprocessor!" >&2;}
+ { $as_echo "$as_me:$LINENO: WARNING: tr1/unordered_map: proceeding with the compiler's result" >&5
+$as_echo "$as_me: WARNING: tr1/unordered_map: proceeding with the compiler's result" >&2;}
+ ac_header_preproc=yes
+ ;;
+ no:yes:* )
+ { $as_echo "$as_me:$LINENO: WARNING: tr1/unordered_map: present but cannot be compiled" >&5
+$as_echo "$as_me: WARNING: tr1/unordered_map: present but cannot be compiled" >&2;}
+ { $as_echo "$as_me:$LINENO: WARNING: tr1/unordered_map: check for missing prerequisite headers?" >&5
+$as_echo "$as_me: WARNING: tr1/unordered_map: check for missing prerequisite headers?" >&2;}
+ { $as_echo "$as_me:$LINENO: WARNING: tr1/unordered_map: see the Autoconf documentation" >&5
+$as_echo "$as_me: WARNING: tr1/unordered_map: see the Autoconf documentation" >&2;}
+ { $as_echo "$as_me:$LINENO: WARNING: tr1/unordered_map: section \"Present But Cannot Be Compiled\"" >&5
+$as_echo "$as_me: WARNING: tr1/unordered_map: section \"Present But Cannot Be Compiled\"" >&2;}
+ { $as_echo "$as_me:$LINENO: WARNING: tr1/unordered_map: proceeding with the preprocessor's result" >&5
+$as_echo "$as_me: WARNING: tr1/unordered_map: proceeding with the preprocessor's result" >&2;}
+ { $as_echo "$as_me:$LINENO: WARNING: tr1/unordered_map: in the future, the compiler will take precedence" >&5
+$as_echo "$as_me: WARNING: tr1/unordered_map: in the future, the compiler will take precedence" >&2;}
+ ( cat <<\_ASBOX
+## -------------------------------------------------------- ##
+## Report this to http://sourceforge.net/projects/asymptote ##
+## -------------------------------------------------------- ##
+_ASBOX
+ ) | sed "s/^/$as_me: WARNING: /" >&2
+ ;;
+esac
+{ $as_echo "$as_me:$LINENO: checking for tr1/unordered_map" >&5
+$as_echo_n "checking for tr1/unordered_map... " >&6; }
+if test "${ac_cv_header_tr1_unordered_map+set}" = set; then
+ $as_echo_n "(cached) " >&6
+else
+ ac_cv_header_tr1_unordered_map=$ac_header_preproc
+fi
+{ $as_echo "$as_me:$LINENO: result: $ac_cv_header_tr1_unordered_map" >&5
+$as_echo "$ac_cv_header_tr1_unordered_map" >&6; }
+
+fi
+if test "x$ac_cv_header_tr1_unordered_map" = x""yes; then
+ :
+else
+ if test "${ac_cv_header_ext_hash_map+set}" = set; then
+ { $as_echo "$as_me:$LINENO: checking for ext/hash_map" >&5
+$as_echo_n "checking for ext/hash_map... " >&6; }
+if test "${ac_cv_header_ext_hash_map+set}" = set; then
+ $as_echo_n "(cached) " >&6
+fi
+{ $as_echo "$as_me:$LINENO: result: $ac_cv_header_ext_hash_map" >&5
+$as_echo "$ac_cv_header_ext_hash_map" >&6; }
+else
+ # Is the header compilable?
+{ $as_echo "$as_me:$LINENO: checking ext/hash_map usability" >&5
+$as_echo_n "checking ext/hash_map usability... " >&6; }
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+$ac_includes_default
+#include <ext/hash_map>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_compile") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && {
+ test -z "$ac_cxx_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest.$ac_objext; then
+ ac_header_compiler=yes
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_header_compiler=no
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+{ $as_echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
+$as_echo "$ac_header_compiler" >&6; }
+
+# Is the header present?
+{ $as_echo "$as_me:$LINENO: checking ext/hash_map presence" >&5
+$as_echo_n "checking ext/hash_map presence... " >&6; }
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <ext/hash_map>
+_ACEOF
+if { (ac_try="$ac_cpp conftest.$ac_ext"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } >/dev/null && {
+ test -z "$ac_cxx_preproc_warn_flag$ac_cxx_werror_flag" ||
+ test ! -s conftest.err
+ }; then
+ ac_header_preproc=yes
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_header_preproc=no
+fi
+
+rm -f conftest.err conftest.$ac_ext
+{ $as_echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
+$as_echo "$ac_header_preproc" >&6; }
+
+# So? What about this header?
+case $ac_header_compiler:$ac_header_preproc:$ac_cxx_preproc_warn_flag in
+ yes:no: )
+ { $as_echo "$as_me:$LINENO: WARNING: ext/hash_map: accepted by the compiler, rejected by the preprocessor!" >&5
+$as_echo "$as_me: WARNING: ext/hash_map: accepted by the compiler, rejected by the preprocessor!" >&2;}
+ { $as_echo "$as_me:$LINENO: WARNING: ext/hash_map: proceeding with the compiler's result" >&5
+$as_echo "$as_me: WARNING: ext/hash_map: proceeding with the compiler's result" >&2;}
+ ac_header_preproc=yes
+ ;;
+ no:yes:* )
+ { $as_echo "$as_me:$LINENO: WARNING: ext/hash_map: present but cannot be compiled" >&5
+$as_echo "$as_me: WARNING: ext/hash_map: present but cannot be compiled" >&2;}
+ { $as_echo "$as_me:$LINENO: WARNING: ext/hash_map: check for missing prerequisite headers?" >&5
+$as_echo "$as_me: WARNING: ext/hash_map: check for missing prerequisite headers?" >&2;}
+ { $as_echo "$as_me:$LINENO: WARNING: ext/hash_map: see the Autoconf documentation" >&5
+$as_echo "$as_me: WARNING: ext/hash_map: see the Autoconf documentation" >&2;}
+ { $as_echo "$as_me:$LINENO: WARNING: ext/hash_map: section \"Present But Cannot Be Compiled\"" >&5
+$as_echo "$as_me: WARNING: ext/hash_map: section \"Present But Cannot Be Compiled\"" >&2;}
+ { $as_echo "$as_me:$LINENO: WARNING: ext/hash_map: proceeding with the preprocessor's result" >&5
+$as_echo "$as_me: WARNING: ext/hash_map: proceeding with the preprocessor's result" >&2;}
+ { $as_echo "$as_me:$LINENO: WARNING: ext/hash_map: in the future, the compiler will take precedence" >&5
+$as_echo "$as_me: WARNING: ext/hash_map: in the future, the compiler will take precedence" >&2;}
+ ( cat <<\_ASBOX
+## -------------------------------------------------------- ##
+## Report this to http://sourceforge.net/projects/asymptote ##
+## -------------------------------------------------------- ##
+_ASBOX
+ ) | sed "s/^/$as_me: WARNING: /" >&2
+ ;;
+esac
+{ $as_echo "$as_me:$LINENO: checking for ext/hash_map" >&5
+$as_echo_n "checking for ext/hash_map... " >&6; }
+if test "${ac_cv_header_ext_hash_map+set}" = set; then
+ $as_echo_n "(cached) " >&6
+else
+ ac_cv_header_ext_hash_map=$ac_header_preproc
+fi
+{ $as_echo "$as_me:$LINENO: result: $ac_cv_header_ext_hash_map" >&5
+$as_echo "$ac_cv_header_ext_hash_map" >&6; }
+
+fi
+if test "x$ac_cv_header_ext_hash_map" = x""yes; then
+ :
+else
+ OPTIONS=$OPTIONS"-DNOHASH "
+fi
+
+
+fi
+
+
+
+
+
+
+
+
+
+
+
+# Checks for libraries.
+{ $as_echo "$as_me:$LINENO: checking for setupterm in -lncurses" >&5
+$as_echo_n "checking for setupterm in -lncurses... " >&6; }
+if test "${ac_cv_lib_ncurses_setupterm+set}" = set; then
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lncurses $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* 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 setupterm ();
+int
+main ()
+{
+return setupterm ();
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_link") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && {
+ test -z "$ac_cxx_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest$ac_exeext && {
+ test "$cross_compiling" = yes ||
+ $as_test_x conftest$ac_exeext
+ }; then
+ ac_cv_lib_ncurses_setupterm=yes
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_cv_lib_ncurses_setupterm=no
+fi
+
+rm -rf conftest.dSYM
+rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:$LINENO: result: $ac_cv_lib_ncurses_setupterm" >&5
+$as_echo "$ac_cv_lib_ncurses_setupterm" >&6; }
+if test "x$ac_cv_lib_ncurses_setupterm" = x""yes; then
+ cat >>confdefs.h <<\_ACEOF
+#define HAVE_LIBCURSES 1
+_ACEOF
+
+ LIBS=$LIBS"-lncurses "
+else
+
+{ $as_echo "$as_me:$LINENO: checking for setupterm in -lcurses" >&5
+$as_echo_n "checking for setupterm in -lcurses... " >&6; }
+if test "${ac_cv_lib_curses_setupterm+set}" = set; then
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lcurses $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* 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 setupterm ();
+int
+main ()
+{
+return setupterm ();
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_link") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && {
+ test -z "$ac_cxx_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest$ac_exeext && {
+ test "$cross_compiling" = yes ||
+ $as_test_x conftest$ac_exeext
+ }; then
+ ac_cv_lib_curses_setupterm=yes
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_cv_lib_curses_setupterm=no
+fi
+
+rm -rf conftest.dSYM
+rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:$LINENO: result: $ac_cv_lib_curses_setupterm" >&5
+$as_echo "$ac_cv_lib_curses_setupterm" >&6; }
+if test "x$ac_cv_lib_curses_setupterm" = x""yes; then
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_LIBCURSES 1
+_ACEOF
+
+ LIBS="-lcurses $LIBS"
+
+fi
+
+fi
+
+
+{ $as_echo "$as_me:$LINENO: checking for sqrt in -lm" >&5
+$as_echo_n "checking for sqrt in -lm... " >&6; }
+if test "${ac_cv_lib_m_sqrt+set}" = set; then
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lm $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* 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 sqrt ();
+int
+main ()
+{
+return sqrt ();
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_link") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && {
+ test -z "$ac_cxx_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest$ac_exeext && {
+ test "$cross_compiling" = yes ||
+ $as_test_x conftest$ac_exeext
+ }; then
+ ac_cv_lib_m_sqrt=yes
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_cv_lib_m_sqrt=no
+fi
+
+rm -rf conftest.dSYM
+rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:$LINENO: result: $ac_cv_lib_m_sqrt" >&5
+$as_echo "$ac_cv_lib_m_sqrt" >&6; }
+if test "x$ac_cv_lib_m_sqrt" = x""yes; then
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_LIBM 1
+_ACEOF
+
+ LIBS="-lm $LIBS"
+
+fi
+
+
+{ $as_echo "$as_me:$LINENO: checking for deflate in -lz" >&5
+$as_echo_n "checking for deflate in -lz... " >&6; }
+if test "${ac_cv_lib_z_deflate+set}" = set; then
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lz $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* 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 deflate ();
+int
+main ()
+{
+return deflate ();
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_link") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && {
+ test -z "$ac_cxx_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest$ac_exeext && {
+ test "$cross_compiling" = yes ||
+ $as_test_x conftest$ac_exeext
+ }; then
+ ac_cv_lib_z_deflate=yes
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_cv_lib_z_deflate=no
+fi
+
+rm -rf conftest.dSYM
+rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:$LINENO: result: $ac_cv_lib_z_deflate" >&5
+$as_echo "$ac_cv_lib_z_deflate" >&6; }
+if test "x$ac_cv_lib_z_deflate" = x""yes; then
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_LIBZ 1
+_ACEOF
+
+ LIBS="-lz $LIBS"
+
+fi
+
+
+{ $as_echo "$as_me:$LINENO: checking for pthread_create in -lpthread" >&5
+$as_echo_n "checking for pthread_create in -lpthread... " >&6; }
+if test "${ac_cv_lib_pthread_pthread_create+set}" = set; then
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lpthread $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* 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 pthread_create ();
+int
+main ()
+{
+return pthread_create ();
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_link") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && {
+ test -z "$ac_cxx_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest$ac_exeext && {
+ test "$cross_compiling" = yes ||
+ $as_test_x conftest$ac_exeext
+ }; then
+ ac_cv_lib_pthread_pthread_create=yes
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_cv_lib_pthread_pthread_create=no
+fi
+
+rm -rf conftest.dSYM
+rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:$LINENO: result: $ac_cv_lib_pthread_pthread_create" >&5
+$as_echo "$ac_cv_lib_pthread_pthread_create" >&6; }
+if test "x$ac_cv_lib_pthread_pthread_create" = x""yes; then
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_LIBPTHREAD 1
+_ACEOF
+
+ LIBS="-lpthread $LIBS"
+
+fi
+
+
+{ $as_echo "$as_me:$LINENO: checking for stackoverflow_install_handler in -lsigsegv" >&5
+$as_echo_n "checking for stackoverflow_install_handler in -lsigsegv... " >&6; }
+if test "${ac_cv_lib_sigsegv_stackoverflow_install_handler+set}" = set; then
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lsigsegv $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* 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 stackoverflow_install_handler ();
+int
+main ()
+{
+return stackoverflow_install_handler ();
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_link") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && {
+ test -z "$ac_cxx_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest$ac_exeext && {
+ test "$cross_compiling" = yes ||
+ $as_test_x conftest$ac_exeext
+ }; then
+ ac_cv_lib_sigsegv_stackoverflow_install_handler=yes
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_cv_lib_sigsegv_stackoverflow_install_handler=no
+fi
+
+rm -rf conftest.dSYM
+rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:$LINENO: result: $ac_cv_lib_sigsegv_stackoverflow_install_handler" >&5
+$as_echo "$ac_cv_lib_sigsegv_stackoverflow_install_handler" >&6; }
+if test "x$ac_cv_lib_sigsegv_stackoverflow_install_handler" = x""yes; then
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_LIBSIGSEGV 1
+_ACEOF
+
+ LIBS="-lsigsegv $LIBS"
+
+fi
+
+
+
+{ $as_echo "$as_me:$LINENO: checking for rl_completion_matches in -lreadline" >&5
+$as_echo_n "checking for rl_completion_matches in -lreadline... " >&6; }
+if test "${ac_cv_lib_readline_rl_completion_matches+set}" = set; then
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lreadline $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* 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 rl_completion_matches ();
+int
+main ()
+{
+return rl_completion_matches ();
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_link") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && {
+ test -z "$ac_cxx_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest$ac_exeext && {
+ test "$cross_compiling" = yes ||
+ $as_test_x conftest$ac_exeext
+ }; then
+ ac_cv_lib_readline_rl_completion_matches=yes
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_cv_lib_readline_rl_completion_matches=no
+fi
+
+rm -rf conftest.dSYM
+rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:$LINENO: result: $ac_cv_lib_readline_rl_completion_matches" >&5
+$as_echo "$ac_cv_lib_readline_rl_completion_matches" >&6; }
+if test "x$ac_cv_lib_readline_rl_completion_matches" = x""yes; then
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_LIBREADLINE 1
+_ACEOF
+
+ LIBS="-lreadline $LIBS"
+
+else
+ { $as_echo "$as_me:$LINENO: *** Could not find GNU readline 4.2 or later: will compile without readline support ***" >&5
+$as_echo "$as_me: *** Could not find GNU readline 4.2 or later: will compile without readline support ***" >&6;}
+fi
+
+
+# Checks for header files.
+{ $as_echo "$as_me:$LINENO: checking for sys/wait.h that is POSIX.1 compatible" >&5
+$as_echo_n "checking for sys/wait.h that is POSIX.1 compatible... " >&6; }
+if test "${ac_cv_header_sys_wait_h+set}" = set; then
+ $as_echo_n "(cached) " >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <sys/types.h>
+#include <sys/wait.h>
+#ifndef WEXITSTATUS
+# define WEXITSTATUS(stat_val) ((unsigned int) (stat_val) >> 8)
+#endif
+#ifndef WIFEXITED
+# define WIFEXITED(stat_val) (((stat_val) & 255) == 0)
+#endif
+
+int
+main ()
+{
+ int s;
+ wait (&s);
+ s = WIFEXITED (s) ? WEXITSTATUS (s) : 1;
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_compile") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && {
+ test -z "$ac_cxx_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest.$ac_objext; then
+ ac_cv_header_sys_wait_h=yes
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_cv_header_sys_wait_h=no
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:$LINENO: result: $ac_cv_header_sys_wait_h" >&5
+$as_echo "$ac_cv_header_sys_wait_h" >&6; }
+if test $ac_cv_header_sys_wait_h = yes; then
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_SYS_WAIT_H 1
+_ACEOF
+
+fi
+
+
+
+
+for ac_header in fenv.h stddef.h libintl.h
+do
+as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
+if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
+ { $as_echo "$as_me:$LINENO: checking for $ac_header" >&5
+$as_echo_n "checking for $ac_header... " >&6; }
+if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
+ $as_echo_n "(cached) " >&6
+fi
+ac_res=`eval 'as_val=${'$as_ac_Header'}
+ $as_echo "$as_val"'`
+ { $as_echo "$as_me:$LINENO: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+else
+ # Is the header compilable?
+{ $as_echo "$as_me:$LINENO: checking $ac_header usability" >&5
+$as_echo_n "checking $ac_header usability... " >&6; }
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+$ac_includes_default
+#include <$ac_header>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_compile") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && {
+ test -z "$ac_cxx_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest.$ac_objext; then
+ ac_header_compiler=yes
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_header_compiler=no
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+{ $as_echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
+$as_echo "$ac_header_compiler" >&6; }
+
+# Is the header present?
+{ $as_echo "$as_me:$LINENO: checking $ac_header presence" >&5
+$as_echo_n "checking $ac_header presence... " >&6; }
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <$ac_header>
+_ACEOF
+if { (ac_try="$ac_cpp conftest.$ac_ext"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } >/dev/null && {
+ test -z "$ac_cxx_preproc_warn_flag$ac_cxx_werror_flag" ||
+ test ! -s conftest.err
+ }; then
+ ac_header_preproc=yes
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_header_preproc=no
+fi
+
+rm -f conftest.err conftest.$ac_ext
+{ $as_echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
+$as_echo "$ac_header_preproc" >&6; }
+
+# So? What about this header?
+case $ac_header_compiler:$ac_header_preproc:$ac_cxx_preproc_warn_flag in
+ yes:no: )
+ { $as_echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5
+$as_echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;}
+ { $as_echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5
+$as_echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;}
+ ac_header_preproc=yes
+ ;;
+ no:yes:* )
+ { $as_echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5
+$as_echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;}
+ { $as_echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5
+$as_echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;}
+ { $as_echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5
+$as_echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;}
+ { $as_echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5
+$as_echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;}
+ { $as_echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5
+$as_echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;}
+ { $as_echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5
+$as_echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;}
+ ( cat <<\_ASBOX
+## -------------------------------------------------------- ##
+## Report this to http://sourceforge.net/projects/asymptote ##
+## -------------------------------------------------------- ##
+_ASBOX
+ ) | sed "s/^/$as_me: WARNING: /" >&2
+ ;;
+esac
+{ $as_echo "$as_me:$LINENO: checking for $ac_header" >&5
+$as_echo_n "checking for $ac_header... " >&6; }
+if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
+ $as_echo_n "(cached) " >&6
+else
+ eval "$as_ac_Header=\$ac_header_preproc"
+fi
+ac_res=`eval 'as_val=${'$as_ac_Header'}
+ $as_echo "$as_val"'`
+ { $as_echo "$as_me:$LINENO: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+
+fi
+as_val=`eval 'as_val=${'$as_ac_Header'}
+ $as_echo "$as_val"'`
+ if test "x$as_val" = x""yes; then
+ cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+
+done
+
+
+
+
+for ac_header in ncurses/curses.h ncurses.h curses.h
+do
+as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
+if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
+ { $as_echo "$as_me:$LINENO: checking for $ac_header" >&5
+$as_echo_n "checking for $ac_header... " >&6; }
+if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
+ $as_echo_n "(cached) " >&6
+fi
+ac_res=`eval 'as_val=${'$as_ac_Header'}
+ $as_echo "$as_val"'`
+ { $as_echo "$as_me:$LINENO: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+else
+ # Is the header compilable?
+{ $as_echo "$as_me:$LINENO: checking $ac_header usability" >&5
+$as_echo_n "checking $ac_header usability... " >&6; }
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+$ac_includes_default
+#include <$ac_header>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_compile") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && {
+ test -z "$ac_cxx_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest.$ac_objext; then
+ ac_header_compiler=yes
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_header_compiler=no
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+{ $as_echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
+$as_echo "$ac_header_compiler" >&6; }
+
+# Is the header present?
+{ $as_echo "$as_me:$LINENO: checking $ac_header presence" >&5
+$as_echo_n "checking $ac_header presence... " >&6; }
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <$ac_header>
+_ACEOF
+if { (ac_try="$ac_cpp conftest.$ac_ext"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } >/dev/null && {
+ test -z "$ac_cxx_preproc_warn_flag$ac_cxx_werror_flag" ||
+ test ! -s conftest.err
+ }; then
+ ac_header_preproc=yes
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_header_preproc=no
+fi
+
+rm -f conftest.err conftest.$ac_ext
+{ $as_echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
+$as_echo "$ac_header_preproc" >&6; }
+
+# So? What about this header?
+case $ac_header_compiler:$ac_header_preproc:$ac_cxx_preproc_warn_flag in
+ yes:no: )
+ { $as_echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5
+$as_echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;}
+ { $as_echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5
+$as_echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;}
+ ac_header_preproc=yes
+ ;;
+ no:yes:* )
+ { $as_echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5
+$as_echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;}
+ { $as_echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5
+$as_echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;}
+ { $as_echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5
+$as_echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;}
+ { $as_echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5
+$as_echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;}
+ { $as_echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5
+$as_echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;}
+ { $as_echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5
+$as_echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;}
+ ( cat <<\_ASBOX
+## -------------------------------------------------------- ##
+## Report this to http://sourceforge.net/projects/asymptote ##
+## -------------------------------------------------------- ##
+_ASBOX
+ ) | sed "s/^/$as_me: WARNING: /" >&2
+ ;;
+esac
+{ $as_echo "$as_me:$LINENO: checking for $ac_header" >&5
+$as_echo_n "checking for $ac_header... " >&6; }
+if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
+ $as_echo_n "(cached) " >&6
+else
+ eval "$as_ac_Header=\$ac_header_preproc"
+fi
+ac_res=`eval 'as_val=${'$as_ac_Header'}
+ $as_echo "$as_val"'`
+ { $as_echo "$as_me:$LINENO: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+
+fi
+as_val=`eval 'as_val=${'$as_ac_Header'}
+ $as_echo "$as_val"'`
+ if test "x$as_val" = x""yes; then
+ cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+ break
+fi
+
+done
+
+
+for ac_header in fpu_control.h
+do
+as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
+if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
+ { $as_echo "$as_me:$LINENO: checking for $ac_header" >&5
+$as_echo_n "checking for $ac_header... " >&6; }
+if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
+ $as_echo_n "(cached) " >&6
+fi
+ac_res=`eval 'as_val=${'$as_ac_Header'}
+ $as_echo "$as_val"'`
+ { $as_echo "$as_me:$LINENO: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+else
+ # Is the header compilable?
+{ $as_echo "$as_me:$LINENO: checking $ac_header usability" >&5
+$as_echo_n "checking $ac_header usability... " >&6; }
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+$ac_includes_default
+#include <$ac_header>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_compile") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && {
+ test -z "$ac_cxx_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest.$ac_objext; then
+ ac_header_compiler=yes
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_header_compiler=no
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+{ $as_echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
+$as_echo "$ac_header_compiler" >&6; }
+
+# Is the header present?
+{ $as_echo "$as_me:$LINENO: checking $ac_header presence" >&5
+$as_echo_n "checking $ac_header presence... " >&6; }
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <$ac_header>
+_ACEOF
+if { (ac_try="$ac_cpp conftest.$ac_ext"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } >/dev/null && {
+ test -z "$ac_cxx_preproc_warn_flag$ac_cxx_werror_flag" ||
+ test ! -s conftest.err
+ }; then
+ ac_header_preproc=yes
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_header_preproc=no
+fi
+
+rm -f conftest.err conftest.$ac_ext
+{ $as_echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
+$as_echo "$ac_header_preproc" >&6; }
+
+# So? What about this header?
+case $ac_header_compiler:$ac_header_preproc:$ac_cxx_preproc_warn_flag in
+ yes:no: )
+ { $as_echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5
+$as_echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;}
+ { $as_echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5
+$as_echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;}
+ ac_header_preproc=yes
+ ;;
+ no:yes:* )
+ { $as_echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5
+$as_echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;}
+ { $as_echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5
+$as_echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;}
+ { $as_echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5
+$as_echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;}
+ { $as_echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5
+$as_echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;}
+ { $as_echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5
+$as_echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;}
+ { $as_echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5
+$as_echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;}
+ ( cat <<\_ASBOX
+## -------------------------------------------------------- ##
+## Report this to http://sourceforge.net/projects/asymptote ##
+## -------------------------------------------------------- ##
+_ASBOX
+ ) | sed "s/^/$as_me: WARNING: /" >&2
+ ;;
+esac
+{ $as_echo "$as_me:$LINENO: checking for $ac_header" >&5
+$as_echo_n "checking for $ac_header... " >&6; }
+if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
+ $as_echo_n "(cached) " >&6
+else
+ eval "$as_ac_Header=\$ac_header_preproc"
+fi
+ac_res=`eval 'as_val=${'$as_ac_Header'}
+ $as_echo "$as_val"'`
+ { $as_echo "$as_me:$LINENO: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+
+fi
+as_val=`eval 'as_val=${'$as_ac_Header'}
+ $as_echo "$as_val"'`
+ if test "x$as_val" = x""yes; then
+ cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+
+done
+
+
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include "xstream.h"
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_compile") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && {
+ test -z "$ac_cxx_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest.$ac_objext; then
+ { $as_echo "$as_me:$LINENO: checking for library containing xdrstdio_create" >&5
+$as_echo_n "checking for library containing xdrstdio_create... " >&6; }
+if test "${ac_cv_search_xdrstdio_create+set}" = set; then
+ $as_echo_n "(cached) " >&6
+else
+ ac_func_search_save_LIBS=$LIBS
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* 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 xdrstdio_create ();
+int
+main ()
+{
+return xdrstdio_create ();
+ ;
+ return 0;
+}
+_ACEOF
+for ac_lib in '' nsl rpc; do
+ if test -z "$ac_lib"; then
+ ac_res="none required"
+ else
+ ac_res=-l$ac_lib
+ LIBS="-l$ac_lib $ac_func_search_save_LIBS"
+ fi
+ rm -f conftest.$ac_objext conftest$ac_exeext
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_link") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && {
+ test -z "$ac_cxx_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest$ac_exeext && {
+ test "$cross_compiling" = yes ||
+ $as_test_x conftest$ac_exeext
+ }; then
+ ac_cv_search_xdrstdio_create=$ac_res
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+
+fi
+
+rm -rf conftest.dSYM
+rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
+ conftest$ac_exeext
+ if test "${ac_cv_search_xdrstdio_create+set}" = set; then
+ break
+fi
+done
+if test "${ac_cv_search_xdrstdio_create+set}" = set; then
+ :
+else
+ ac_cv_search_xdrstdio_create=no
+fi
+rm conftest.$ac_ext
+LIBS=$ac_func_search_save_LIBS
+fi
+{ $as_echo "$as_me:$LINENO: result: $ac_cv_search_xdrstdio_create" >&5
+$as_echo "$ac_cv_search_xdrstdio_create" >&6; }
+ac_res=$ac_cv_search_xdrstdio_create
+if test "$ac_res" != no; then
+ test "$ac_res" = "none required" || LIBS="$ac_res $LIBS"
+
+fi
+
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_RPC_RPC_H 1
+_ACEOF
+
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ { $as_echo "$as_me:$LINENO: WARNING: *** Broken rpc headers; XDR support disabled ***" >&5
+$as_echo "$as_me: WARNING: *** Broken rpc headers; XDR support disabled ***" >&2;}
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+if test "${ac_cv_header_gsl_gsl_sf_h+set}" = set; then
+ { $as_echo "$as_me:$LINENO: checking for gsl/gsl_sf.h" >&5
+$as_echo_n "checking for gsl/gsl_sf.h... " >&6; }
+if test "${ac_cv_header_gsl_gsl_sf_h+set}" = set; then
+ $as_echo_n "(cached) " >&6
+fi
+{ $as_echo "$as_me:$LINENO: result: $ac_cv_header_gsl_gsl_sf_h" >&5
+$as_echo "$ac_cv_header_gsl_gsl_sf_h" >&6; }
+else
+ # Is the header compilable?
+{ $as_echo "$as_me:$LINENO: checking gsl/gsl_sf.h usability" >&5
+$as_echo_n "checking gsl/gsl_sf.h usability... " >&6; }
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+$ac_includes_default
+#include <gsl/gsl_sf.h>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_compile") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && {
+ test -z "$ac_cxx_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest.$ac_objext; then
+ ac_header_compiler=yes
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_header_compiler=no
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+{ $as_echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
+$as_echo "$ac_header_compiler" >&6; }
+
+# Is the header present?
+{ $as_echo "$as_me:$LINENO: checking gsl/gsl_sf.h presence" >&5
+$as_echo_n "checking gsl/gsl_sf.h presence... " >&6; }
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <gsl/gsl_sf.h>
+_ACEOF
+if { (ac_try="$ac_cpp conftest.$ac_ext"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } >/dev/null && {
+ test -z "$ac_cxx_preproc_warn_flag$ac_cxx_werror_flag" ||
+ test ! -s conftest.err
+ }; then
+ ac_header_preproc=yes
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_header_preproc=no
+fi
+
+rm -f conftest.err conftest.$ac_ext
+{ $as_echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
+$as_echo "$ac_header_preproc" >&6; }
+
+# So? What about this header?
+case $ac_header_compiler:$ac_header_preproc:$ac_cxx_preproc_warn_flag in
+ yes:no: )
+ { $as_echo "$as_me:$LINENO: WARNING: gsl/gsl_sf.h: accepted by the compiler, rejected by the preprocessor!" >&5
+$as_echo "$as_me: WARNING: gsl/gsl_sf.h: accepted by the compiler, rejected by the preprocessor!" >&2;}
+ { $as_echo "$as_me:$LINENO: WARNING: gsl/gsl_sf.h: proceeding with the compiler's result" >&5
+$as_echo "$as_me: WARNING: gsl/gsl_sf.h: proceeding with the compiler's result" >&2;}
+ ac_header_preproc=yes
+ ;;
+ no:yes:* )
+ { $as_echo "$as_me:$LINENO: WARNING: gsl/gsl_sf.h: present but cannot be compiled" >&5
+$as_echo "$as_me: WARNING: gsl/gsl_sf.h: present but cannot be compiled" >&2;}
+ { $as_echo "$as_me:$LINENO: WARNING: gsl/gsl_sf.h: check for missing prerequisite headers?" >&5
+$as_echo "$as_me: WARNING: gsl/gsl_sf.h: check for missing prerequisite headers?" >&2;}
+ { $as_echo "$as_me:$LINENO: WARNING: gsl/gsl_sf.h: see the Autoconf documentation" >&5
+$as_echo "$as_me: WARNING: gsl/gsl_sf.h: see the Autoconf documentation" >&2;}
+ { $as_echo "$as_me:$LINENO: WARNING: gsl/gsl_sf.h: section \"Present But Cannot Be Compiled\"" >&5
+$as_echo "$as_me: WARNING: gsl/gsl_sf.h: section \"Present But Cannot Be Compiled\"" >&2;}
+ { $as_echo "$as_me:$LINENO: WARNING: gsl/gsl_sf.h: proceeding with the preprocessor's result" >&5
+$as_echo "$as_me: WARNING: gsl/gsl_sf.h: proceeding with the preprocessor's result" >&2;}
+ { $as_echo "$as_me:$LINENO: WARNING: gsl/gsl_sf.h: in the future, the compiler will take precedence" >&5
+$as_echo "$as_me: WARNING: gsl/gsl_sf.h: in the future, the compiler will take precedence" >&2;}
+ ( cat <<\_ASBOX
+## -------------------------------------------------------- ##
+## Report this to http://sourceforge.net/projects/asymptote ##
+## -------------------------------------------------------- ##
+_ASBOX
+ ) | sed "s/^/$as_me: WARNING: /" >&2
+ ;;
+esac
+{ $as_echo "$as_me:$LINENO: checking for gsl/gsl_sf.h" >&5
+$as_echo_n "checking for gsl/gsl_sf.h... " >&6; }
+if test "${ac_cv_header_gsl_gsl_sf_h+set}" = set; then
+ $as_echo_n "(cached) " >&6
+else
+ ac_cv_header_gsl_gsl_sf_h=$ac_header_preproc
+fi
+{ $as_echo "$as_me:$LINENO: result: $ac_cv_header_gsl_gsl_sf_h" >&5
+$as_echo "$ac_cv_header_gsl_gsl_sf_h" >&6; }
+
+fi
+if test "x$ac_cv_header_gsl_gsl_sf_h" = x""yes; then
+ { $as_echo "$as_me:$LINENO: checking for gsl_sf_Si in -lgsl" >&5
+$as_echo_n "checking for gsl_sf_Si in -lgsl... " >&6; }
+if test "${ac_cv_lib_gsl_gsl_sf_Si+set}" = set; then
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lgsl -lgslcblas $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* 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 gsl_sf_Si ();
+int
+main ()
+{
+return gsl_sf_Si ();
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_link") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && {
+ test -z "$ac_cxx_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest$ac_exeext && {
+ test "$cross_compiling" = yes ||
+ $as_test_x conftest$ac_exeext
+ }; then
+ ac_cv_lib_gsl_gsl_sf_Si=yes
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_cv_lib_gsl_gsl_sf_Si=no
+fi
+
+rm -rf conftest.dSYM
+rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:$LINENO: result: $ac_cv_lib_gsl_gsl_sf_Si" >&5
+$as_echo "$ac_cv_lib_gsl_gsl_sf_Si" >&6; }
+if test "x$ac_cv_lib_gsl_gsl_sf_Si" = x""yes; then
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_LIBGSL 1
+_ACEOF
+ LIBS=$LIBS"-lgsl -lgslcblas "
+else
+ { $as_echo "$as_me:$LINENO: *** Could not find libgsl: will compile without optional special functions. ***" >&5
+$as_echo "$as_me: *** Could not find libgsl: will compile without optional special functions. ***" >&6;}
+fi
+
+else
+ { $as_echo "$as_me:$LINENO: *** Header file gsl_sf.h not found: will compile without optional special functions. ***" >&5
+$as_echo "$as_me: *** Header file gsl_sf.h not found: will compile without optional special functions. ***" >&6;}
+fi
+
+
+
+case "$OSTYPE" in
+ cygwin) if test "${ac_cv_header_GL_glut_h+set}" = set; then
+ { $as_echo "$as_me:$LINENO: checking for GL/glut.h" >&5
+$as_echo_n "checking for GL/glut.h... " >&6; }
+if test "${ac_cv_header_GL_glut_h+set}" = set; then
+ $as_echo_n "(cached) " >&6
+fi
+{ $as_echo "$as_me:$LINENO: result: $ac_cv_header_GL_glut_h" >&5
+$as_echo "$ac_cv_header_GL_glut_h" >&6; }
+else
+ # Is the header compilable?
+{ $as_echo "$as_me:$LINENO: checking GL/glut.h usability" >&5
+$as_echo_n "checking GL/glut.h usability... " >&6; }
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+$ac_includes_default
+#include <GL/glut.h>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_compile") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && {
+ test -z "$ac_cxx_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest.$ac_objext; then
+ ac_header_compiler=yes
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_header_compiler=no
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+{ $as_echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
+$as_echo "$ac_header_compiler" >&6; }
+
+# Is the header present?
+{ $as_echo "$as_me:$LINENO: checking GL/glut.h presence" >&5
+$as_echo_n "checking GL/glut.h presence... " >&6; }
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <GL/glut.h>
+_ACEOF
+if { (ac_try="$ac_cpp conftest.$ac_ext"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } >/dev/null && {
+ test -z "$ac_cxx_preproc_warn_flag$ac_cxx_werror_flag" ||
+ test ! -s conftest.err
+ }; then
+ ac_header_preproc=yes
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_header_preproc=no
+fi
+
+rm -f conftest.err conftest.$ac_ext
+{ $as_echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
+$as_echo "$ac_header_preproc" >&6; }
+
+# So? What about this header?
+case $ac_header_compiler:$ac_header_preproc:$ac_cxx_preproc_warn_flag in
+ yes:no: )
+ { $as_echo "$as_me:$LINENO: WARNING: GL/glut.h: accepted by the compiler, rejected by the preprocessor!" >&5
+$as_echo "$as_me: WARNING: GL/glut.h: accepted by the compiler, rejected by the preprocessor!" >&2;}
+ { $as_echo "$as_me:$LINENO: WARNING: GL/glut.h: proceeding with the compiler's result" >&5
+$as_echo "$as_me: WARNING: GL/glut.h: proceeding with the compiler's result" >&2;}
+ ac_header_preproc=yes
+ ;;
+ no:yes:* )
+ { $as_echo "$as_me:$LINENO: WARNING: GL/glut.h: present but cannot be compiled" >&5
+$as_echo "$as_me: WARNING: GL/glut.h: present but cannot be compiled" >&2;}
+ { $as_echo "$as_me:$LINENO: WARNING: GL/glut.h: check for missing prerequisite headers?" >&5
+$as_echo "$as_me: WARNING: GL/glut.h: check for missing prerequisite headers?" >&2;}
+ { $as_echo "$as_me:$LINENO: WARNING: GL/glut.h: see the Autoconf documentation" >&5
+$as_echo "$as_me: WARNING: GL/glut.h: see the Autoconf documentation" >&2;}
+ { $as_echo "$as_me:$LINENO: WARNING: GL/glut.h: section \"Present But Cannot Be Compiled\"" >&5
+$as_echo "$as_me: WARNING: GL/glut.h: section \"Present But Cannot Be Compiled\"" >&2;}
+ { $as_echo "$as_me:$LINENO: WARNING: GL/glut.h: proceeding with the preprocessor's result" >&5
+$as_echo "$as_me: WARNING: GL/glut.h: proceeding with the preprocessor's result" >&2;}
+ { $as_echo "$as_me:$LINENO: WARNING: GL/glut.h: in the future, the compiler will take precedence" >&5
+$as_echo "$as_me: WARNING: GL/glut.h: in the future, the compiler will take precedence" >&2;}
+ ( cat <<\_ASBOX
+## -------------------------------------------------------- ##
+## Report this to http://sourceforge.net/projects/asymptote ##
+## -------------------------------------------------------- ##
+_ASBOX
+ ) | sed "s/^/$as_me: WARNING: /" >&2
+ ;;
+esac
+{ $as_echo "$as_me:$LINENO: checking for GL/glut.h" >&5
+$as_echo_n "checking for GL/glut.h... " >&6; }
+if test "${ac_cv_header_GL_glut_h+set}" = set; then
+ $as_echo_n "(cached) " >&6
+else
+ ac_cv_header_GL_glut_h=$ac_header_preproc
+fi
+{ $as_echo "$as_me:$LINENO: result: $ac_cv_header_GL_glut_h" >&5
+$as_echo "$ac_cv_header_GL_glut_h" >&6; }
+
+fi
+if test "x$ac_cv_header_GL_glut_h" = x""yes; then
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_LIBGLUT 1
+_ACEOF
+
+ LIBS=$LIBS"-lfreeglut -lopengl32 "
+else
+ { $as_echo "$as_me:$LINENO: *** Could not find freeglut: will compile without OpenGL support ***" >&5
+$as_echo "$as_me: *** Could not find freeglut: will compile without OpenGL support ***" >&6;}
+fi
+
+
+ { $as_echo "$as_me:$LINENO: checking for gluNewNurbsRenderer in -lGLU" >&5
+$as_echo_n "checking for gluNewNurbsRenderer in -lGLU... " >&6; }
+if test "${ac_cv_lib_GLU_gluNewNurbsRenderer+set}" = set; then
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lGLU $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* 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 gluNewNurbsRenderer ();
+int
+main ()
+{
+return gluNewNurbsRenderer ();
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_link") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && {
+ test -z "$ac_cxx_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest$ac_exeext && {
+ test "$cross_compiling" = yes ||
+ $as_test_x conftest$ac_exeext
+ }; then
+ ac_cv_lib_GLU_gluNewNurbsRenderer=yes
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_cv_lib_GLU_gluNewNurbsRenderer=no
+fi
+
+rm -rf conftest.dSYM
+rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:$LINENO: result: $ac_cv_lib_GLU_gluNewNurbsRenderer" >&5
+$as_echo "$ac_cv_lib_GLU_gluNewNurbsRenderer" >&6; }
+if test "x$ac_cv_lib_GLU_gluNewNurbsRenderer" = x""yes; then
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_LIBGLU 1
+_ACEOF
+ LIBS=$LIBS"-lglu32 "
+else
+ { $as_echo "$as_me:$LINENO: *** Could not find libglu32: will compile without OpenGL support ***" >&5
+$as_echo "$as_me: *** Could not find libglu32: will compile without OpenGL support ***" >&6;}
+fi
+
+ ;;
+ darwin*) if test "${ac_cv_header_GLUT_glut_h+set}" = set; then
+ { $as_echo "$as_me:$LINENO: checking for GLUT/glut.h" >&5
+$as_echo_n "checking for GLUT/glut.h... " >&6; }
+if test "${ac_cv_header_GLUT_glut_h+set}" = set; then
+ $as_echo_n "(cached) " >&6
+fi
+{ $as_echo "$as_me:$LINENO: result: $ac_cv_header_GLUT_glut_h" >&5
+$as_echo "$ac_cv_header_GLUT_glut_h" >&6; }
+else
+ # Is the header compilable?
+{ $as_echo "$as_me:$LINENO: checking GLUT/glut.h usability" >&5
+$as_echo_n "checking GLUT/glut.h usability... " >&6; }
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+$ac_includes_default
+#include <GLUT/glut.h>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_compile") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && {
+ test -z "$ac_cxx_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest.$ac_objext; then
+ ac_header_compiler=yes
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_header_compiler=no
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+{ $as_echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
+$as_echo "$ac_header_compiler" >&6; }
+
+# Is the header present?
+{ $as_echo "$as_me:$LINENO: checking GLUT/glut.h presence" >&5
+$as_echo_n "checking GLUT/glut.h presence... " >&6; }
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <GLUT/glut.h>
+_ACEOF
+if { (ac_try="$ac_cpp conftest.$ac_ext"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } >/dev/null && {
+ test -z "$ac_cxx_preproc_warn_flag$ac_cxx_werror_flag" ||
+ test ! -s conftest.err
+ }; then
+ ac_header_preproc=yes
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_header_preproc=no
+fi
+
+rm -f conftest.err conftest.$ac_ext
+{ $as_echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
+$as_echo "$ac_header_preproc" >&6; }
+
+# So? What about this header?
+case $ac_header_compiler:$ac_header_preproc:$ac_cxx_preproc_warn_flag in
+ yes:no: )
+ { $as_echo "$as_me:$LINENO: WARNING: GLUT/glut.h: accepted by the compiler, rejected by the preprocessor!" >&5
+$as_echo "$as_me: WARNING: GLUT/glut.h: accepted by the compiler, rejected by the preprocessor!" >&2;}
+ { $as_echo "$as_me:$LINENO: WARNING: GLUT/glut.h: proceeding with the compiler's result" >&5
+$as_echo "$as_me: WARNING: GLUT/glut.h: proceeding with the compiler's result" >&2;}
+ ac_header_preproc=yes
+ ;;
+ no:yes:* )
+ { $as_echo "$as_me:$LINENO: WARNING: GLUT/glut.h: present but cannot be compiled" >&5
+$as_echo "$as_me: WARNING: GLUT/glut.h: present but cannot be compiled" >&2;}
+ { $as_echo "$as_me:$LINENO: WARNING: GLUT/glut.h: check for missing prerequisite headers?" >&5
+$as_echo "$as_me: WARNING: GLUT/glut.h: check for missing prerequisite headers?" >&2;}
+ { $as_echo "$as_me:$LINENO: WARNING: GLUT/glut.h: see the Autoconf documentation" >&5
+$as_echo "$as_me: WARNING: GLUT/glut.h: see the Autoconf documentation" >&2;}
+ { $as_echo "$as_me:$LINENO: WARNING: GLUT/glut.h: section \"Present But Cannot Be Compiled\"" >&5
+$as_echo "$as_me: WARNING: GLUT/glut.h: section \"Present But Cannot Be Compiled\"" >&2;}
+ { $as_echo "$as_me:$LINENO: WARNING: GLUT/glut.h: proceeding with the preprocessor's result" >&5
+$as_echo "$as_me: WARNING: GLUT/glut.h: proceeding with the preprocessor's result" >&2;}
+ { $as_echo "$as_me:$LINENO: WARNING: GLUT/glut.h: in the future, the compiler will take precedence" >&5
+$as_echo "$as_me: WARNING: GLUT/glut.h: in the future, the compiler will take precedence" >&2;}
+ ( cat <<\_ASBOX
+## -------------------------------------------------------- ##
+## Report this to http://sourceforge.net/projects/asymptote ##
+## -------------------------------------------------------- ##
+_ASBOX
+ ) | sed "s/^/$as_me: WARNING: /" >&2
+ ;;
+esac
+{ $as_echo "$as_me:$LINENO: checking for GLUT/glut.h" >&5
+$as_echo_n "checking for GLUT/glut.h... " >&6; }
+if test "${ac_cv_header_GLUT_glut_h+set}" = set; then
+ $as_echo_n "(cached) " >&6
+else
+ ac_cv_header_GLUT_glut_h=$ac_header_preproc
+fi
+{ $as_echo "$as_me:$LINENO: result: $ac_cv_header_GLUT_glut_h" >&5
+$as_echo "$ac_cv_header_GLUT_glut_h" >&6; }
+
+fi
+if test "x$ac_cv_header_GLUT_glut_h" = x""yes; then
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_LIBGLUT 1
+_ACEOF
+
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_LIBGLU 1
+_ACEOF
+
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+#include <OpenGL/gl.h>
+#include <OpenGL/glu.h>
+#ifndef GLU_TESS_CALLBACK_TRIPLEDOT
+typedef GLvoid (* _GLUfuncptr)(...);
+void f(void) {
+ gluNurbsCallback(gluNewNurbsRenderer(),GLU_NURBS_BEGIN,(_GLUfuncptr) glBegin);
+}
+#endif
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_compile") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && {
+ test -z "$ac_cxx_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest.$ac_objext; then
+
+cat >>confdefs.h <<\_ACEOF
+#define GLU_TESS_CALLBACK_TRIPLEDOT 1
+_ACEOF
+
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ LIBS=$LIBS"-framework GLUT -framework OpenGL -framework Cocoa"
+else
+ { $as_echo "$as_me:$LINENO: *** Could not find glut: will compile without OpenGL support ***" >&5
+$as_echo "$as_me: *** Could not find glut: will compile without OpenGL support ***" >&6;}
+fi
+
+
+ ;;
+ *)
+{ $as_echo "$as_me:$LINENO: checking for glutMainLoop in -lglut" >&5
+$as_echo_n "checking for glutMainLoop in -lglut... " >&6; }
+if test "${ac_cv_lib_glut_glutMainLoop+set}" = set; then
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lglut $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* 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 glutMainLoop ();
+int
+main ()
+{
+return glutMainLoop ();
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_link") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && {
+ test -z "$ac_cxx_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest$ac_exeext && {
+ test "$cross_compiling" = yes ||
+ $as_test_x conftest$ac_exeext
+ }; then
+ ac_cv_lib_glut_glutMainLoop=yes
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_cv_lib_glut_glutMainLoop=no
+fi
+
+rm -rf conftest.dSYM
+rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:$LINENO: result: $ac_cv_lib_glut_glutMainLoop" >&5
+$as_echo "$ac_cv_lib_glut_glutMainLoop" >&6; }
+if test "x$ac_cv_lib_glut_glutMainLoop" = x""yes; then
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_LIBGLUT 1
+_ACEOF
+
+ LIBS="-lglut $LIBS"
+
+else
+ { $as_echo "$as_me:$LINENO: *** Could not find libglut: will compile without OpenGL support ***" >&5
+$as_echo "$as_me: *** Could not find libglut: will compile without OpenGL support ***" >&6;}
+fi
+
+
+{ $as_echo "$as_me:$LINENO: checking for gluNewNurbsRenderer in -lGLU" >&5
+$as_echo_n "checking for gluNewNurbsRenderer in -lGLU... " >&6; }
+if test "${ac_cv_lib_GLU_gluNewNurbsRenderer+set}" = set; then
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lGLU $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* 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 gluNewNurbsRenderer ();
+int
+main ()
+{
+return gluNewNurbsRenderer ();
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_link") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && {
+ test -z "$ac_cxx_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest$ac_exeext && {
+ test "$cross_compiling" = yes ||
+ $as_test_x conftest$ac_exeext
+ }; then
+ ac_cv_lib_GLU_gluNewNurbsRenderer=yes
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_cv_lib_GLU_gluNewNurbsRenderer=no
+fi
+
+rm -rf conftest.dSYM
+rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:$LINENO: result: $ac_cv_lib_GLU_gluNewNurbsRenderer" >&5
+$as_echo "$ac_cv_lib_GLU_gluNewNurbsRenderer" >&6; }
+if test "x$ac_cv_lib_GLU_gluNewNurbsRenderer" = x""yes; then
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_LIBGLU 1
+_ACEOF
+
+ LIBS="-lGLU $LIBS"
+
+else
+ { $as_echo "$as_me:$LINENO: *** Could not find libGLU: will compile without OpenGL support ***" >&5
+$as_echo "$as_me: *** Could not find libGLU: will compile without OpenGL support ***" >&6;}
+fi
+
+esac
+
+
+# Checks for typedefs, structures, and compiler characteristics.
+{ $as_echo "$as_me:$LINENO: checking for pid_t" >&5
+$as_echo_n "checking for pid_t... " >&6; }
+if test "${ac_cv_type_pid_t+set}" = set; then
+ $as_echo_n "(cached) " >&6
+else
+ ac_cv_type_pid_t=no
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+$ac_includes_default
+int
+main ()
+{
+if (sizeof (pid_t))
+ return 0;
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_compile") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && {
+ test -z "$ac_cxx_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest.$ac_objext; then
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+$ac_includes_default
+int
+main ()
+{
+if (sizeof ((pid_t)))
+ return 0;
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_compile") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && {
+ test -z "$ac_cxx_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest.$ac_objext; then
+ :
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_cv_type_pid_t=yes
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:$LINENO: result: $ac_cv_type_pid_t" >&5
+$as_echo "$ac_cv_type_pid_t" >&6; }
+if test "x$ac_cv_type_pid_t" = x""yes; then
+ :
+else
+
+cat >>confdefs.h <<_ACEOF
+#define pid_t int
+_ACEOF
+
+fi
+
+{ $as_echo "$as_me:$LINENO: checking for size_t" >&5
+$as_echo_n "checking for size_t... " >&6; }
+if test "${ac_cv_type_size_t+set}" = set; then
+ $as_echo_n "(cached) " >&6
+else
+ ac_cv_type_size_t=no
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+$ac_includes_default
+int
+main ()
+{
+if (sizeof (size_t))
+ return 0;
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_compile") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && {
+ test -z "$ac_cxx_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest.$ac_objext; then
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+$ac_includes_default
+int
+main ()
+{
+if (sizeof ((size_t)))
+ return 0;
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_compile") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && {
+ test -z "$ac_cxx_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest.$ac_objext; then
+ :
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_cv_type_size_t=yes
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:$LINENO: result: $ac_cv_type_size_t" >&5
+$as_echo "$ac_cv_type_size_t" >&6; }
+if test "x$ac_cv_type_size_t" = x""yes; then
+ :
+else
+
+cat >>confdefs.h <<_ACEOF
+#define size_t unsigned int
+_ACEOF
+
+fi
+
+{ $as_echo "$as_me:$LINENO: checking for ptrdiff_t" >&5
+$as_echo_n "checking for ptrdiff_t... " >&6; }
+if test "${ac_cv_type_ptrdiff_t+set}" = set; then
+ $as_echo_n "(cached) " >&6
+else
+ ac_cv_type_ptrdiff_t=no
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+$ac_includes_default
+int
+main ()
+{
+if (sizeof (ptrdiff_t))
+ return 0;
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_compile") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && {
+ test -z "$ac_cxx_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest.$ac_objext; then
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+$ac_includes_default
+int
+main ()
+{
+if (sizeof ((ptrdiff_t)))
+ return 0;
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_compile") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && {
+ test -z "$ac_cxx_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest.$ac_objext; then
+ :
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_cv_type_ptrdiff_t=yes
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:$LINENO: result: $ac_cv_type_ptrdiff_t" >&5
+$as_echo "$ac_cv_type_ptrdiff_t" >&6; }
+if test "x$ac_cv_type_ptrdiff_t" = x""yes; then
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_PTRDIFF_T 1
+_ACEOF
+
+
+fi
+
+{ $as_echo "$as_me:$LINENO: checking for long long" >&5
+$as_echo_n "checking for long long... " >&6; }
+if test "${ac_cv_type_long_long+set}" = set; then
+ $as_echo_n "(cached) " >&6
+else
+ ac_cv_type_long_long=no
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+$ac_includes_default
+int
+main ()
+{
+if (sizeof (long long))
+ return 0;
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_compile") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && {
+ test -z "$ac_cxx_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest.$ac_objext; then
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+$ac_includes_default
+int
+main ()
+{
+if (sizeof ((long long)))
+ return 0;
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_compile") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && {
+ test -z "$ac_cxx_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest.$ac_objext; then
+ :
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_cv_type_long_long=yes
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:$LINENO: result: $ac_cv_type_long_long" >&5
+$as_echo "$ac_cv_type_long_long" >&6; }
+if test "x$ac_cv_type_long_long" = x""yes; then
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_LONG_LONG 1
+_ACEOF
+
+
+fi
+
+{ $as_echo "$as_me:$LINENO: checking for long" >&5
+$as_echo_n "checking for long... " >&6; }
+if test "${ac_cv_type_long+set}" = set; then
+ $as_echo_n "(cached) " >&6
+else
+ ac_cv_type_long=no
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+$ac_includes_default
+int
+main ()
+{
+if (sizeof (long))
+ return 0;
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_compile") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && {
+ test -z "$ac_cxx_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest.$ac_objext; then
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+$ac_includes_default
+int
+main ()
+{
+if (sizeof ((long)))
+ return 0;
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_compile") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && {
+ test -z "$ac_cxx_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest.$ac_objext; then
+ :
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_cv_type_long=yes
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:$LINENO: result: $ac_cv_type_long" >&5
+$as_echo "$ac_cv_type_long" >&6; }
+if test "x$ac_cv_type_long" = x""yes; then
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_LONG 1
+_ACEOF
+
+
+fi
+
+{ $as_echo "$as_me:$LINENO: checking for an ANSI C-conforming const" >&5
+$as_echo_n "checking for an ANSI C-conforming const... " >&6; }
+if test "${ac_cv_c_const+set}" = set; then
+ $as_echo_n "(cached) " >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+int
+main ()
+{
+/* FIXME: Include the comments suggested by Paul. */
+#ifndef __cplusplus
+ /* Ultrix mips cc rejects this. */
+ typedef int charset[2];
+ const charset cs;
+ /* SunOS 4.1.1 cc rejects this. */
+ char const *const *pcpcc;
+ char **ppc;
+ /* NEC SVR4.0.2 mips cc rejects this. */
+ struct point {int x, y;};
+ static struct point const zero = {0,0};
+ /* AIX XL C 1.02.0.0 rejects this.
+ It does not let you subtract one const X* pointer from another in
+ an arm of an if-expression whose if-part is not a constant
+ expression */
+ const char *g = "string";
+ pcpcc = &g + (g ? g-g : 0);
+ /* HPUX 7.0 cc rejects these. */
+ ++pcpcc;
+ ppc = (char**) pcpcc;
+ pcpcc = (char const *const *) ppc;
+ { /* SCO 3.2v4 cc rejects this. */
+ char *t;
+ char const *s = 0 ? (char *) 0 : (char const *) 0;
+
+ *t++ = 0;
+ if (s) return 0;
+ }
+ { /* Someone thinks the Sun supposedly-ANSI compiler will reject this. */
+ int x[] = {25, 17};
+ const int *foo = &x[0];
+ ++foo;
+ }
+ { /* Sun SC1.0 ANSI compiler rejects this -- but not the above. */
+ typedef const int *iptr;
+ iptr p = 0;
+ ++p;
+ }
+ { /* AIX XL C 1.02.0.0 rejects this saying
+ "k.c", line 2.27: 1506-025 (S) Operand must be a modifiable lvalue. */
+ struct s { int j; const int *ap[3]; };
+ struct s *b; b->j = 5;
+ }
+ { /* ULTRIX-32 V3.1 (Rev 9) vcc rejects this */
+ const int foo = 10;
+ if (!foo) return 0;
+ }
+ return !cs[0] && !zero.x;
+#endif
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_compile") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && {
+ test -z "$ac_cxx_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest.$ac_objext; then
+ ac_cv_c_const=yes
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_cv_c_const=no
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:$LINENO: result: $ac_cv_c_const" >&5
+$as_echo "$ac_cv_c_const" >&6; }
+if test $ac_cv_c_const = no; then
+
+cat >>confdefs.h <<\_ACEOF
+#define const /**/
+_ACEOF
+
+fi
+
+{ $as_echo "$as_me:$LINENO: checking for inline" >&5
+$as_echo_n "checking for inline... " >&6; }
+if test "${ac_cv_c_inline+set}" = set; then
+ $as_echo_n "(cached) " >&6
+else
+ ac_cv_c_inline=no
+for ac_kw in inline __inline__ __inline; do
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#ifndef __cplusplus
+typedef int foo_t;
+static $ac_kw foo_t static_foo () {return 0; }
+$ac_kw foo_t foo () {return 0; }
+#endif
+
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_compile") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && {
+ test -z "$ac_cxx_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest.$ac_objext; then
+ ac_cv_c_inline=$ac_kw
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ test "$ac_cv_c_inline" != no && break
+done
+
+fi
+{ $as_echo "$as_me:$LINENO: result: $ac_cv_c_inline" >&5
+$as_echo "$ac_cv_c_inline" >&6; }
+
+
+case $ac_cv_c_inline in
+ inline | yes) ;;
+ *)
+ case $ac_cv_c_inline in
+ no) ac_val=;;
+ *) ac_val=$ac_cv_c_inline;;
+ esac
+ cat >>confdefs.h <<_ACEOF
+#ifndef __cplusplus
+#define inline $ac_val
+#endif
+_ACEOF
+ ;;
+esac
+
+{ $as_echo "$as_me:$LINENO: checking return type of signal handlers" >&5
+$as_echo_n "checking return type of signal handlers... " >&6; }
+if test "${ac_cv_type_signal+set}" = set; then
+ $as_echo_n "(cached) " >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <sys/types.h>
+#include <signal.h>
+
+int
+main ()
+{
+return *(signal (0, 0)) (0) == 1;
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_compile") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && {
+ test -z "$ac_cxx_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest.$ac_objext; then
+ ac_cv_type_signal=int
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_cv_type_signal=void
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:$LINENO: result: $ac_cv_type_signal" >&5
+$as_echo "$ac_cv_type_signal" >&6; }
+
+cat >>confdefs.h <<_ACEOF
+#define RETSIGTYPE $ac_cv_type_signal
+_ACEOF
+
+
+
+
+
+# Checks for library functions.
+
+for ac_header in vfork.h
+do
+as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
+if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
+ { $as_echo "$as_me:$LINENO: checking for $ac_header" >&5
+$as_echo_n "checking for $ac_header... " >&6; }
+if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
+ $as_echo_n "(cached) " >&6
+fi
+ac_res=`eval 'as_val=${'$as_ac_Header'}
+ $as_echo "$as_val"'`
+ { $as_echo "$as_me:$LINENO: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+else
+ # Is the header compilable?
+{ $as_echo "$as_me:$LINENO: checking $ac_header usability" >&5
+$as_echo_n "checking $ac_header usability... " >&6; }
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+$ac_includes_default
+#include <$ac_header>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_compile") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && {
+ test -z "$ac_cxx_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest.$ac_objext; then
+ ac_header_compiler=yes
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_header_compiler=no
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+{ $as_echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
+$as_echo "$ac_header_compiler" >&6; }
+
+# Is the header present?
+{ $as_echo "$as_me:$LINENO: checking $ac_header presence" >&5
+$as_echo_n "checking $ac_header presence... " >&6; }
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <$ac_header>
+_ACEOF
+if { (ac_try="$ac_cpp conftest.$ac_ext"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } >/dev/null && {
+ test -z "$ac_cxx_preproc_warn_flag$ac_cxx_werror_flag" ||
+ test ! -s conftest.err
+ }; then
+ ac_header_preproc=yes
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_header_preproc=no
+fi
+
+rm -f conftest.err conftest.$ac_ext
+{ $as_echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
+$as_echo "$ac_header_preproc" >&6; }
+
+# So? What about this header?
+case $ac_header_compiler:$ac_header_preproc:$ac_cxx_preproc_warn_flag in
+ yes:no: )
+ { $as_echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5
+$as_echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;}
+ { $as_echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5
+$as_echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;}
+ ac_header_preproc=yes
+ ;;
+ no:yes:* )
+ { $as_echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5
+$as_echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;}
+ { $as_echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5
+$as_echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;}
+ { $as_echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5
+$as_echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;}
+ { $as_echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5
+$as_echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;}
+ { $as_echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5
+$as_echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;}
+ { $as_echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5
+$as_echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;}
+ ( cat <<\_ASBOX
+## -------------------------------------------------------- ##
+## Report this to http://sourceforge.net/projects/asymptote ##
+## -------------------------------------------------------- ##
+_ASBOX
+ ) | sed "s/^/$as_me: WARNING: /" >&2
+ ;;
+esac
+{ $as_echo "$as_me:$LINENO: checking for $ac_header" >&5
+$as_echo_n "checking for $ac_header... " >&6; }
+if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
+ $as_echo_n "(cached) " >&6
+else
+ eval "$as_ac_Header=\$ac_header_preproc"
+fi
+ac_res=`eval 'as_val=${'$as_ac_Header'}
+ $as_echo "$as_val"'`
+ { $as_echo "$as_me:$LINENO: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+
+fi
+as_val=`eval 'as_val=${'$as_ac_Header'}
+ $as_echo "$as_val"'`
+ if test "x$as_val" = x""yes; then
+ cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+
+done
+
+
+
+for ac_func in fork vfork
+do
+as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
+{ $as_echo "$as_me:$LINENO: checking for $ac_func" >&5
+$as_echo_n "checking for $ac_func... " >&6; }
+if { as_var=$as_ac_var; eval "test \"\${$as_var+set}\" = set"; }; then
+ $as_echo_n "(cached) " >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+/* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func.
+ For example, HP-UX 11i <limits.h> declares gettimeofday. */
+#define $ac_func innocuous_$ac_func
+
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func (); below.
+ Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ <limits.h> exists even on freestanding compilers. */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef $ac_func
+
+/* 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 $ac_func ();
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined __stub_$ac_func || defined __stub___$ac_func
+choke me
+#endif
+
+int
+main ()
+{
+return $ac_func ();
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_link") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && {
+ test -z "$ac_cxx_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest$ac_exeext && {
+ test "$cross_compiling" = yes ||
+ $as_test_x conftest$ac_exeext
+ }; then
+ eval "$as_ac_var=yes"
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ eval "$as_ac_var=no"
+fi
+
+rm -rf conftest.dSYM
+rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
+ conftest$ac_exeext conftest.$ac_ext
+fi
+ac_res=`eval 'as_val=${'$as_ac_var'}
+ $as_echo "$as_val"'`
+ { $as_echo "$as_me:$LINENO: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+as_val=`eval 'as_val=${'$as_ac_var'}
+ $as_echo "$as_val"'`
+ if test "x$as_val" = x""yes; then
+ cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+if test "x$ac_cv_func_fork" = xyes; then
+ { $as_echo "$as_me:$LINENO: checking for working fork" >&5
+$as_echo_n "checking for working fork... " >&6; }
+if test "${ac_cv_func_fork_works+set}" = set; then
+ $as_echo_n "(cached) " >&6
+else
+ if test "$cross_compiling" = yes; then
+ ac_cv_func_fork_works=cross
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+$ac_includes_default
+int
+main ()
+{
+
+ /* By Ruediger Kuhlmann. */
+ return fork () < 0;
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest$ac_exeext
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_link") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
+ { (case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_try") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_cv_func_fork_works=yes
+else
+ $as_echo "$as_me: program exited with status $ac_status" >&5
+$as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+( exit $ac_status )
+ac_cv_func_fork_works=no
+fi
+rm -rf conftest.dSYM
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
+fi
+
+
+fi
+{ $as_echo "$as_me:$LINENO: result: $ac_cv_func_fork_works" >&5
+$as_echo "$ac_cv_func_fork_works" >&6; }
+
+else
+ ac_cv_func_fork_works=$ac_cv_func_fork
+fi
+if test "x$ac_cv_func_fork_works" = xcross; then
+ case $host in
+ *-*-amigaos* | *-*-msdosdjgpp*)
+ # Override, as these systems have only a dummy fork() stub
+ ac_cv_func_fork_works=no
+ ;;
+ *)
+ ac_cv_func_fork_works=yes
+ ;;
+ esac
+ { $as_echo "$as_me:$LINENO: WARNING: result $ac_cv_func_fork_works guessed because of cross compilation" >&5
+$as_echo "$as_me: WARNING: result $ac_cv_func_fork_works guessed because of cross compilation" >&2;}
+fi
+ac_cv_func_vfork_works=$ac_cv_func_vfork
+if test "x$ac_cv_func_vfork" = xyes; then
+ { $as_echo "$as_me:$LINENO: checking for working vfork" >&5
+$as_echo_n "checking for working vfork... " >&6; }
+if test "${ac_cv_func_vfork_works+set}" = set; then
+ $as_echo_n "(cached) " >&6
+else
+ if test "$cross_compiling" = yes; then
+ ac_cv_func_vfork_works=cross
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+/* Thanks to Paul Eggert for this test. */
+$ac_includes_default
+#include <sys/wait.h>
+#ifdef HAVE_VFORK_H
+# include <vfork.h>
+#endif
+/* On some sparc systems, changes by the child to local and incoming
+ argument registers are propagated back to the parent. The compiler
+ is told about this with #include <vfork.h>, but some compilers
+ (e.g. gcc -O) don't grok <vfork.h>. Test for this by using a
+ static variable whose address is put into a register that is
+ clobbered by the vfork. */
+static void
+#ifdef __cplusplus
+sparc_address_test (int arg)
+# else
+sparc_address_test (arg) int arg;
+#endif
+{
+ static pid_t child;
+ if (!child) {
+ child = vfork ();
+ if (child < 0) {
+ perror ("vfork");
+ _exit(2);
+ }
+ if (!child) {
+ arg = getpid();
+ write(-1, "", 0);
+ _exit (arg);
+ }
+ }
+}
+
+int
+main ()
+{
+ pid_t parent = getpid ();
+ pid_t child;
+
+ sparc_address_test (0);
+
+ child = vfork ();
+
+ if (child == 0) {
+ /* Here is another test for sparc vfork register problems. This
+ test uses lots of local variables, at least as many local
+ variables as main has allocated so far including compiler
+ temporaries. 4 locals are enough for gcc 1.40.3 on a Solaris
+ 4.1.3 sparc, but we use 8 to be safe. A buggy compiler should
+ reuse the register of parent for one of the local variables,
+ since it will think that parent can't possibly be used any more
+ in this routine. Assigning to the local variable will thus
+ munge parent in the parent process. */
+ pid_t
+ p = getpid(), p1 = getpid(), p2 = getpid(), p3 = getpid(),
+ p4 = getpid(), p5 = getpid(), p6 = getpid(), p7 = getpid();
+ /* Convince the compiler that p..p7 are live; otherwise, it might
+ use the same hardware register for all 8 local variables. */
+ if (p != p1 || p != p2 || p != p3 || p != p4
+ || p != p5 || p != p6 || p != p7)
+ _exit(1);
+
+ /* On some systems (e.g. IRIX 3.3), vfork doesn't separate parent
+ from child file descriptors. If the child closes a descriptor
+ before it execs or exits, this munges the parent's descriptor
+ as well. Test for this by closing stdout in the child. */
+ _exit(close(fileno(stdout)) != 0);
+ } else {
+ int status;
+ struct stat st;
+
+ while (wait(&status) != child)
+ ;
+ return (
+ /* Was there some problem with vforking? */
+ child < 0
+
+ /* Did the child fail? (This shouldn't happen.) */
+ || status
+
+ /* Did the vfork/compiler bug occur? */
+ || parent != getpid()
+
+ /* Did the file descriptor bug occur? */
+ || fstat(fileno(stdout), &st) != 0
+ );
+ }
+}
+_ACEOF
+rm -f conftest$ac_exeext
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_link") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
+ { (case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_try") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_cv_func_vfork_works=yes
+else
+ $as_echo "$as_me: program exited with status $ac_status" >&5
+$as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+( exit $ac_status )
+ac_cv_func_vfork_works=no
+fi
+rm -rf conftest.dSYM
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
+fi
+
+
+fi
+{ $as_echo "$as_me:$LINENO: result: $ac_cv_func_vfork_works" >&5
+$as_echo "$ac_cv_func_vfork_works" >&6; }
+
+fi;
+if test "x$ac_cv_func_fork_works" = xcross; then
+ ac_cv_func_vfork_works=$ac_cv_func_vfork
+ { $as_echo "$as_me:$LINENO: WARNING: result $ac_cv_func_vfork_works guessed because of cross compilation" >&5
+$as_echo "$as_me: WARNING: result $ac_cv_func_vfork_works guessed because of cross compilation" >&2;}
+fi
+
+if test "x$ac_cv_func_vfork_works" = xyes; then
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_WORKING_VFORK 1
+_ACEOF
+
+else
+
+cat >>confdefs.h <<\_ACEOF
+#define vfork fork
+_ACEOF
+
+fi
+if test "x$ac_cv_func_fork_works" = xyes; then
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_WORKING_FORK 1
+_ACEOF
+
+fi
+
+
+
+
+
+
+
+
+for ac_func in dup2 floor memset pow sqrt strchr tgamma
+do
+as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
+{ $as_echo "$as_me:$LINENO: checking for $ac_func" >&5
+$as_echo_n "checking for $ac_func... " >&6; }
+if { as_var=$as_ac_var; eval "test \"\${$as_var+set}\" = set"; }; then
+ $as_echo_n "(cached) " >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+/* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func.
+ For example, HP-UX 11i <limits.h> declares gettimeofday. */
+#define $ac_func innocuous_$ac_func
+
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func (); below.
+ Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ <limits.h> exists even on freestanding compilers. */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef $ac_func
+
+/* 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 $ac_func ();
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined __stub_$ac_func || defined __stub___$ac_func
+choke me
+#endif
+
+int
+main ()
+{
+return $ac_func ();
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_link") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && {
+ test -z "$ac_cxx_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest$ac_exeext && {
+ test "$cross_compiling" = yes ||
+ $as_test_x conftest$ac_exeext
+ }; then
+ eval "$as_ac_var=yes"
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ eval "$as_ac_var=no"
+fi
+
+rm -rf conftest.dSYM
+rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
+ conftest$ac_exeext conftest.$ac_ext
+fi
+ac_res=`eval 'as_val=${'$as_ac_var'}
+ $as_echo "$as_val"'`
+ { $as_echo "$as_me:$LINENO: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+as_val=`eval 'as_val=${'$as_ac_var'}
+ $as_echo "$as_val"'`
+ if test "x$as_val" = x""yes; then
+ cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+
+for ac_func in strftime
+do
+as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
+{ $as_echo "$as_me:$LINENO: checking for $ac_func" >&5
+$as_echo_n "checking for $ac_func... " >&6; }
+if { as_var=$as_ac_var; eval "test \"\${$as_var+set}\" = set"; }; then
+ $as_echo_n "(cached) " >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+/* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func.
+ For example, HP-UX 11i <limits.h> declares gettimeofday. */
+#define $ac_func innocuous_$ac_func
+
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func (); below.
+ Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ <limits.h> exists even on freestanding compilers. */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef $ac_func
+
+/* 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 $ac_func ();
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined __stub_$ac_func || defined __stub___$ac_func
+choke me
+#endif
+
+int
+main ()
+{
+return $ac_func ();
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_link") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && {
+ test -z "$ac_cxx_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest$ac_exeext && {
+ test "$cross_compiling" = yes ||
+ $as_test_x conftest$ac_exeext
+ }; then
+ eval "$as_ac_var=yes"
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ eval "$as_ac_var=no"
+fi
+
+rm -rf conftest.dSYM
+rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
+ conftest$ac_exeext conftest.$ac_ext
+fi
+ac_res=`eval 'as_val=${'$as_ac_var'}
+ $as_echo "$as_val"'`
+ { $as_echo "$as_me:$LINENO: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+as_val=`eval 'as_val=${'$as_ac_var'}
+ $as_echo "$as_val"'`
+ if test "x$as_val" = x""yes; then
+ cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+else
+ # strftime is in -lintl on SCO UNIX.
+{ $as_echo "$as_me:$LINENO: checking for strftime in -lintl" >&5
+$as_echo_n "checking for strftime in -lintl... " >&6; }
+if test "${ac_cv_lib_intl_strftime+set}" = set; then
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lintl $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* 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 strftime ();
+int
+main ()
+{
+return strftime ();
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_link") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && {
+ test -z "$ac_cxx_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest$ac_exeext && {
+ test "$cross_compiling" = yes ||
+ $as_test_x conftest$ac_exeext
+ }; then
+ ac_cv_lib_intl_strftime=yes
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_cv_lib_intl_strftime=no
+fi
+
+rm -rf conftest.dSYM
+rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:$LINENO: result: $ac_cv_lib_intl_strftime" >&5
+$as_echo "$ac_cv_lib_intl_strftime" >&6; }
+if test "x$ac_cv_lib_intl_strftime" = x""yes; then
+ cat >>confdefs.h <<\_ACEOF
+#define HAVE_STRFTIME 1
+_ACEOF
+
+LIBS="-lintl $LIBS"
+fi
+
+fi
+done
+
+
+
+for ac_func in strptime
+do
+as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
+{ $as_echo "$as_me:$LINENO: checking for $ac_func" >&5
+$as_echo_n "checking for $ac_func... " >&6; }
+if { as_var=$as_ac_var; eval "test \"\${$as_var+set}\" = set"; }; then
+ $as_echo_n "(cached) " >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+/* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func.
+ For example, HP-UX 11i <limits.h> declares gettimeofday. */
+#define $ac_func innocuous_$ac_func
+
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func (); below.
+ Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ <limits.h> exists even on freestanding compilers. */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef $ac_func
+
+/* 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 $ac_func ();
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined __stub_$ac_func || defined __stub___$ac_func
+choke me
+#endif
+
+int
+main ()
+{
+return $ac_func ();
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_link") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && {
+ test -z "$ac_cxx_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest$ac_exeext && {
+ test "$cross_compiling" = yes ||
+ $as_test_x conftest$ac_exeext
+ }; then
+ eval "$as_ac_var=yes"
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ eval "$as_ac_var=no"
+fi
+
+rm -rf conftest.dSYM
+rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
+ conftest$ac_exeext conftest.$ac_ext
+fi
+ac_res=`eval 'as_val=${'$as_ac_var'}
+ $as_echo "$as_val"'`
+ { $as_echo "$as_me:$LINENO: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+as_val=`eval 'as_val=${'$as_ac_var'}
+ $as_echo "$as_val"'`
+ if test "x$as_val" = x""yes; then
+ cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+ { $as_echo "$as_me:$LINENO: checking for strptime declaration in time.h" >&5
+$as_echo_n "checking for strptime declaration in time.h... " >&6; }
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <time.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ $EGREP "strptime" >/dev/null 2>&1; then
+
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_STRPTIME_DECL /**/
+_ACEOF
+
+ { $as_echo "$as_me:$LINENO: result: yes" >&5
+$as_echo "yes" >&6; }
+else
+ { $as_echo "$as_me:$LINENO: result: no" >&5
+$as_echo "no" >&6; }
+
+fi
+rm -f conftest*
+
+
+{ $as_echo "$as_me:$LINENO: checking for error_at_line" >&5
+$as_echo_n "checking for error_at_line... " >&6; }
+if test "${ac_cv_lib_error_at_line+set}" = set; then
+ $as_echo_n "(cached) " >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <error.h>
+int
+main ()
+{
+error_at_line (0, 0, "", 0, "an error occurred");
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_link") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && {
+ test -z "$ac_cxx_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest$ac_exeext && {
+ test "$cross_compiling" = yes ||
+ $as_test_x conftest$ac_exeext
+ }; then
+ ac_cv_lib_error_at_line=yes
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_cv_lib_error_at_line=no
+fi
+
+rm -rf conftest.dSYM
+rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
+ conftest$ac_exeext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:$LINENO: result: $ac_cv_lib_error_at_line" >&5
+$as_echo "$ac_cv_lib_error_at_line" >&6; }
+if test $ac_cv_lib_error_at_line = no; then
+ case " $LIBOBJS " in
+ *" error.$ac_objext "* ) ;;
+ *) LIBOBJS="$LIBOBJS error.$ac_objext"
+ ;;
+esac
+
+fi
+
+{ $as_echo "$as_me:$LINENO: checking for _LARGEFILE_SOURCE value needed for large files" >&5
+$as_echo_n "checking for _LARGEFILE_SOURCE value needed for large files... " >&6; }
+if test "${ac_cv_sys_largefile_source+set}" = set; then
+ $as_echo_n "(cached) " >&6
+else
+ while :; do
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <sys/types.h> /* for off_t */
+ #include <stdio.h>
+int
+main ()
+{
+int (*fp) (FILE *, off_t, int) = fseeko;
+ return fseeko (stdin, 0, 0) && fp (stdin, 0, 0);
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_link") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && {
+ test -z "$ac_cxx_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest$ac_exeext && {
+ test "$cross_compiling" = yes ||
+ $as_test_x conftest$ac_exeext
+ }; then
+ ac_cv_sys_largefile_source=no; break
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+
+fi
+
+rm -rf conftest.dSYM
+rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
+ conftest$ac_exeext conftest.$ac_ext
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#define _LARGEFILE_SOURCE 1
+#include <sys/types.h> /* for off_t */
+ #include <stdio.h>
+int
+main ()
+{
+int (*fp) (FILE *, off_t, int) = fseeko;
+ return fseeko (stdin, 0, 0) && fp (stdin, 0, 0);
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_link") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && {
+ test -z "$ac_cxx_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest$ac_exeext && {
+ test "$cross_compiling" = yes ||
+ $as_test_x conftest$ac_exeext
+ }; then
+ ac_cv_sys_largefile_source=1; break
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+
+fi
+
+rm -rf conftest.dSYM
+rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
+ conftest$ac_exeext conftest.$ac_ext
+ ac_cv_sys_largefile_source=unknown
+ break
+done
+fi
+{ $as_echo "$as_me:$LINENO: result: $ac_cv_sys_largefile_source" >&5
+$as_echo "$ac_cv_sys_largefile_source" >&6; }
+case $ac_cv_sys_largefile_source in #(
+ no | unknown) ;;
+ *)
+cat >>confdefs.h <<_ACEOF
+#define _LARGEFILE_SOURCE $ac_cv_sys_largefile_source
+_ACEOF
+;;
+esac
+rm -rf conftest*
+
+# We used to try defining _XOPEN_SOURCE=500 too, to work around a bug
+# in glibc 2.1.3, but that breaks too many other things.
+# If you want fseeko and ftello with glibc, upgrade to a fixed glibc.
+if test $ac_cv_sys_largefile_source != unknown; then
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_FSEEKO 1
+_ACEOF
+
+fi
+
+
+ac_config_headers="$ac_config_headers config.h"
+
+
+ac_config_files="$ac_config_files Makefile doc/Makefile doc/png/Makefile"
+
+cat >confcache <<\_ACEOF
+# This file is a shell script that caches the results of configure
+# tests run on this system so they can be shared between configure
+# scripts and configure runs, see configure's option --config-cache.
+# It is not useful on other systems. If it contains results you don't
+# want to keep, you may remove or edit it.
+#
+# config.status only pays attention to the cache file if you give it
+# the --recheck option to rerun configure.
+#
+# `ac_cv_env_foo' variables (set or unset) will be overridden when
+# loading this file, other *unset* `ac_cv_foo' will be assigned the
+# following values.
+
+_ACEOF
+
+# The following way of writing the cache mishandles newlines in values,
+# but we know of no workaround that is simple, portable, and efficient.
+# So, we kill variables containing newlines.
+# Ultrix sh set writes to stderr and can't be redirected directly,
+# and sets the high bit in the cache file unless we assign to the vars.
+(
+ for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do
+ eval ac_val=\$$ac_var
+ case $ac_val in #(
+ *${as_nl}*)
+ case $ac_var in #(
+ *_cv_*) { $as_echo "$as_me:$LINENO: WARNING: cache variable $ac_var contains a newline" >&5
+$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;;
+ esac
+ case $ac_var in #(
+ _ | IFS | as_nl) ;; #(
+ BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #(
+ *) $as_unset $ac_var ;;
+ esac ;;
+ esac
+ done
+
+ (set) 2>&1 |
+ case $as_nl`(ac_space=' '; set) 2>&1` in #(
+ *${as_nl}ac_space=\ *)
+ # `set' does not quote correctly, so add quotes (double-quote
+ # substitution turns \\\\ into \\, and sed turns \\ into \).
+ sed -n \
+ "s/'/'\\\\''/g;
+ s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p"
+ ;; #(
+ *)
+ # `set' quotes correctly as required by POSIX, so do not add quotes.
+ sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p"
+ ;;
+ esac |
+ sort
+) |
+ sed '
+ /^ac_cv_env_/b end
+ t clear
+ :clear
+ s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/
+ t end
+ s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/
+ :end' >>confcache
+if diff "$cache_file" confcache >/dev/null 2>&1; then :; else
+ if test -w "$cache_file"; then
+ test "x$cache_file" != "x/dev/null" &&
+ { $as_echo "$as_me:$LINENO: updating cache $cache_file" >&5
+$as_echo "$as_me: updating cache $cache_file" >&6;}
+ cat confcache >$cache_file
+ else
+ { $as_echo "$as_me:$LINENO: not updating unwritable cache $cache_file" >&5
+$as_echo "$as_me: not updating unwritable cache $cache_file" >&6;}
+ fi
+fi
+rm -f confcache
+
+test "x$prefix" = xNONE && prefix=$ac_default_prefix
+# Let make expand exec_prefix.
+test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'
+
+DEFS=-DHAVE_CONFIG_H
+
+ac_libobjs=
+ac_ltlibobjs=
+for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue
+ # 1. Remove the extension, and $U if already installed.
+ ac_script='s/\$U\././;s/\.o$//;s/\.obj$//'
+ ac_i=`$as_echo "$ac_i" | sed "$ac_script"`
+ # 2. Prepend LIBOBJDIR. When used with automake>=1.10 LIBOBJDIR
+ # will be set to the directory where LIBOBJS objects are built.
+ ac_libobjs="$ac_libobjs \${LIBOBJDIR}$ac_i\$U.$ac_objext"
+ ac_ltlibobjs="$ac_ltlibobjs \${LIBOBJDIR}$ac_i"'$U.lo'
+done
+LIBOBJS=$ac_libobjs
+
+LTLIBOBJS=$ac_ltlibobjs
+
+
+
+
+: ${CONFIG_STATUS=./config.status}
+ac_write_fail=0
+ac_clean_files_save=$ac_clean_files
+ac_clean_files="$ac_clean_files $CONFIG_STATUS"
+{ $as_echo "$as_me:$LINENO: creating $CONFIG_STATUS" >&5
+$as_echo "$as_me: creating $CONFIG_STATUS" >&6;}
+cat >$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+#! $SHELL
+# Generated by $as_me.
+# Run this file to recreate the current configuration.
+# Compiler output produced by configure, useful for debugging
+# configure, is in config.log if it exists.
+
+debug=false
+ac_cs_recheck=false
+ac_cs_silent=false
+SHELL=\${CONFIG_SHELL-$SHELL}
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+## --------------------- ##
+## M4sh Initialization. ##
+## --------------------- ##
+
+# Be more Bourne compatible
+DUALCASE=1; export DUALCASE # for MKS sh
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then
+ emulate sh
+ NULLCMD=:
+ # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which
+ # is contrary to our usage. Disable this feature.
+ alias -g '${1+"$@"}'='"$@"'
+ setopt NO_GLOB_SUBST
+else
+ case `(set -o) 2>/dev/null` in
+ *posix*) set -o posix ;;
+esac
+
+fi
+
+
+
+
+# PATH needs CR
+# Avoid depending upon Character Ranges.
+as_cr_letters='abcdefghijklmnopqrstuvwxyz'
+as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
+as_cr_Letters=$as_cr_letters$as_cr_LETTERS
+as_cr_digits='0123456789'
+as_cr_alnum=$as_cr_Letters$as_cr_digits
+
+as_nl='
+'
+export as_nl
+# Printing a long string crashes Solaris 7 /usr/bin/printf.
+as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'
+as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo
+as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo
+if (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then
+ as_echo='printf %s\n'
+ as_echo_n='printf %s'
+else
+ if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then
+ as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"'
+ as_echo_n='/usr/ucb/echo -n'
+ else
+ as_echo_body='eval expr "X$1" : "X\\(.*\\)"'
+ as_echo_n_body='eval
+ arg=$1;
+ case $arg in
+ *"$as_nl"*)
+ expr "X$arg" : "X\\(.*\\)$as_nl";
+ arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;;
+ esac;
+ expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl"
+ '
+ export as_echo_n_body
+ as_echo_n='sh -c $as_echo_n_body as_echo'
+ fi
+ export as_echo_body
+ as_echo='sh -c $as_echo_body as_echo'
+fi
+
+# The user is always right.
+if test "${PATH_SEPARATOR+set}" != set; then
+ PATH_SEPARATOR=:
+ (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && {
+ (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 ||
+ PATH_SEPARATOR=';'
+ }
+fi
+
+# Support unset when possible.
+if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then
+ as_unset=unset
+else
+ as_unset=false
+fi
+
+
+# IFS
+# We need space, tab and new line, in precisely that order. Quoting is
+# there to prevent editors from complaining about space-tab.
+# (If _AS_PATH_WALK were called with IFS unset, it would disable word
+# splitting by setting IFS to empty value.)
+IFS=" "" $as_nl"
+
+# Find who we are. Look in the path if we contain no directory separator.
+case $0 in
+ *[\\/]* ) as_myself=$0 ;;
+ *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
+done
+IFS=$as_save_IFS
+
+ ;;
+esac
+# We did not find ourselves, most probably we were run as `sh COMMAND'
+# in which case we are not to be found in the path.
+if test "x$as_myself" = x; then
+ as_myself=$0
+fi
+if test ! -f "$as_myself"; then
+ $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2
+ { (exit 1); exit 1; }
+fi
+
+# Work around bugs in pre-3.0 UWIN ksh.
+for as_var in ENV MAIL MAILPATH
+do ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var
+done
+PS1='$ '
+PS2='> '
+PS4='+ '
+
+# NLS nuisances.
+LC_ALL=C
+export LC_ALL
+LANGUAGE=C
+export LANGUAGE
+
+# Required to use basename.
+if expr a : '\(a\)' >/dev/null 2>&1 &&
+ test "X`expr 00001 : '.*\(...\)'`" = X001; then
+ as_expr=expr
+else
+ as_expr=false
+fi
+
+if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then
+ as_basename=basename
+else
+ as_basename=false
+fi
+
+
+# Name of the executable.
+as_me=`$as_basename -- "$0" ||
+$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
+ X"$0" : 'X\(//\)$' \| \
+ X"$0" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X/"$0" |
+ sed '/^.*\/\([^/][^/]*\)\/*$/{
+ s//\1/
+ q
+ }
+ /^X\/\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\/\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'`
+
+# CDPATH.
+$as_unset CDPATH
+
+
+
+ as_lineno_1=$LINENO
+ as_lineno_2=$LINENO
+ test "x$as_lineno_1" != "x$as_lineno_2" &&
+ test "x`expr $as_lineno_1 + 1`" = "x$as_lineno_2" || {
+
+ # Create $as_me.lineno as a copy of $as_myself, but with $LINENO
+ # uniformly replaced by the line number. The first 'sed' inserts a
+ # line-number line after each line using $LINENO; the second 'sed'
+ # does the real work. The second script uses 'N' to pair each
+ # line-number line with the line containing $LINENO, and appends
+ # trailing '-' during substitution so that $LINENO is not a special
+ # case at line end.
+ # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the
+ # scripts with optimization help from Paolo Bonzini. Blame Lee
+ # E. McMahon (1931-1989) for sed's syntax. :-)
+ sed -n '
+ p
+ /[$]LINENO/=
+ ' <$as_myself |
+ sed '
+ s/[$]LINENO.*/&-/
+ t lineno
+ b
+ :lineno
+ N
+ :loop
+ s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/
+ t loop
+ s/-\n.*//
+ ' >$as_me.lineno &&
+ chmod +x "$as_me.lineno" ||
+ { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2
+ { (exit 1); exit 1; }; }
+
+ # Don't try to exec as it changes $[0], causing all sort of problems
+ # (the dirname of $[0] is not the place where we might find the
+ # original and so on. Autoconf is especially sensitive to this).
+ . "./$as_me.lineno"
+ # Exit status is that of the last command.
+ exit
+}
+
+
+if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then
+ as_dirname=dirname
+else
+ as_dirname=false
+fi
+
+ECHO_C= ECHO_N= ECHO_T=
+case `echo -n x` in
+-n*)
+ case `echo 'x\c'` in
+ *c*) ECHO_T=' ';; # ECHO_T is single tab character.
+ *) ECHO_C='\c';;
+ esac;;
+*)
+ ECHO_N='-n';;
+esac
+if expr a : '\(a\)' >/dev/null 2>&1 &&
+ test "X`expr 00001 : '.*\(...\)'`" = X001; then
+ as_expr=expr
+else
+ as_expr=false
+fi
+
+rm -f conf$$ conf$$.exe conf$$.file
+if test -d conf$$.dir; then
+ rm -f conf$$.dir/conf$$.file
+else
+ rm -f conf$$.dir
+ mkdir conf$$.dir 2>/dev/null
+fi
+if (echo >conf$$.file) 2>/dev/null; then
+ if ln -s conf$$.file conf$$ 2>/dev/null; then
+ as_ln_s='ln -s'
+ # ... but there are two gotchas:
+ # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail.
+ # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable.
+ # In both cases, we have to default to `cp -p'.
+ ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe ||
+ as_ln_s='cp -p'
+ elif ln conf$$.file conf$$ 2>/dev/null; then
+ as_ln_s=ln
+ else
+ as_ln_s='cp -p'
+ fi
+else
+ as_ln_s='cp -p'
+fi
+rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file
+rmdir conf$$.dir 2>/dev/null
+
+if mkdir -p . 2>/dev/null; then
+ as_mkdir_p=:
+else
+ test -d ./-p && rmdir ./-p
+ as_mkdir_p=false
+fi
+
+if test -x / >/dev/null 2>&1; then
+ as_test_x='test -x'
+else
+ if ls -dL / >/dev/null 2>&1; then
+ as_ls_L_option=L
+ else
+ as_ls_L_option=
+ fi
+ as_test_x='
+ eval sh -c '\''
+ if test -d "$1"; then
+ test -d "$1/.";
+ else
+ case $1 in
+ -*)set "./$1";;
+ esac;
+ case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in
+ ???[sx]*):;;*)false;;esac;fi
+ '\'' sh
+ '
+fi
+as_executable_p=$as_test_x
+
+# Sed expression to map a string onto a valid CPP name.
+as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"
+
+# Sed expression to map a string onto a valid variable name.
+as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'"
+
+
+exec 6>&1
+
+# Save the log message, to keep $[0] and so on meaningful, and to
+# 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 1.72, which was
+generated by GNU Autoconf 2.63. Invocation command line was
+
+ CONFIG_FILES = $CONFIG_FILES
+ CONFIG_HEADERS = $CONFIG_HEADERS
+ CONFIG_LINKS = $CONFIG_LINKS
+ CONFIG_COMMANDS = $CONFIG_COMMANDS
+ $ $0 $@
+
+on `(hostname || uname -n) 2>/dev/null | sed 1q`
+"
+
+_ACEOF
+
+case $ac_config_files in *"
+"*) set x $ac_config_files; shift; ac_config_files=$*;;
+esac
+
+case $ac_config_headers in *"
+"*) set x $ac_config_headers; shift; ac_config_headers=$*;;
+esac
+
+
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+# Files that config.status was made for.
+config_files="$ac_config_files"
+config_headers="$ac_config_headers"
+
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+ac_cs_usage="\
+\`$as_me' instantiates files from templates according to the
+current configuration.
+
+Usage: $0 [OPTION]... [FILE]...
+
+ -h, --help print this help, then exit
+ -V, --version print version number and configuration settings, then exit
+ -q, --quiet, --silent
+ do not print progress messages
+ -d, --debug don't remove temporary files
+ --recheck update $as_me by reconfiguring in the same conditions
+ --file=FILE[:TEMPLATE]
+ instantiate the configuration file FILE
+ --header=FILE[:TEMPLATE]
+ instantiate the configuration header FILE
+
+Configuration files:
+$config_files
+
+Configuration headers:
+$config_headers
+
+Report bugs to <bug-autoconf@gnu.org>."
+
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+ac_cs_version="\\
+Asymptote config.status 1.72
+configured by $0, generated by GNU Autoconf 2.63,
+ with options \\"`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`\\"
+
+Copyright (C) 2008 Free Software Foundation, Inc.
+This config.status script is free software; the Free Software Foundation
+gives unlimited permission to copy, distribute and modify it."
+
+ac_pwd='$ac_pwd'
+srcdir='$srcdir'
+INSTALL='$INSTALL'
+test -n "\$AWK" || AWK=awk
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+# The default lists apply if the user does not specify any file.
+ac_need_defaults=:
+while test $# != 0
+do
+ case $1 in
+ --*=*)
+ ac_option=`expr "X$1" : 'X\([^=]*\)='`
+ ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'`
+ ac_shift=:
+ ;;
+ *)
+ ac_option=$1
+ ac_optarg=$2
+ ac_shift=shift
+ ;;
+ esac
+
+ case $ac_option in
+ # Handling of the options.
+ -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)
+ ac_cs_recheck=: ;;
+ --version | --versio | --versi | --vers | --ver | --ve | --v | -V )
+ $as_echo "$ac_cs_version"; exit ;;
+ --debug | --debu | --deb | --de | --d | -d )
+ debug=: ;;
+ --file | --fil | --fi | --f )
+ $ac_shift
+ case $ac_optarg in
+ *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;;
+ esac
+ CONFIG_FILES="$CONFIG_FILES '$ac_optarg'"
+ ac_need_defaults=false;;
+ --header | --heade | --head | --hea )
+ $ac_shift
+ case $ac_optarg in
+ *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;;
+ esac
+ CONFIG_HEADERS="$CONFIG_HEADERS '$ac_optarg'"
+ ac_need_defaults=false;;
+ --he | --h)
+ # Conflict between --help and --header
+ { $as_echo "$as_me: error: ambiguous option: $1
+Try \`$0 --help' for more information." >&2
+ { (exit 1); exit 1; }; };;
+ --help | --hel | -h )
+ $as_echo "$ac_cs_usage"; exit ;;
+ -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+ | -silent | --silent | --silen | --sile | --sil | --si | --s)
+ ac_cs_silent=: ;;
+
+ # This is an error.
+ -*) { $as_echo "$as_me: error: unrecognized option: $1
+Try \`$0 --help' for more information." >&2
+ { (exit 1); exit 1; }; } ;;
+
+ *) ac_config_targets="$ac_config_targets $1"
+ ac_need_defaults=false ;;
+
+ esac
+ shift
+done
+
+ac_configure_extra_args=
+
+if $ac_cs_silent; then
+ exec 6>/dev/null
+ ac_configure_extra_args="$ac_configure_extra_args --silent"
+fi
+
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+if \$ac_cs_recheck; then
+ set X '$SHELL' '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion
+ shift
+ \$as_echo "running CONFIG_SHELL=$SHELL \$*" >&6
+ CONFIG_SHELL='$SHELL'
+ export CONFIG_SHELL
+ exec "\$@"
+fi
+
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+exec 5>>config.log
+{
+ echo
+ sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX
+## Running $as_me. ##
+_ASBOX
+ $as_echo "$ac_log"
+} >&5
+
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+
+# Handling of arguments.
+for ac_config_target in $ac_config_targets
+do
+ case $ac_config_target in
+ "config.h") CONFIG_HEADERS="$CONFIG_HEADERS config.h" ;;
+ "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;;
+ "doc/Makefile") CONFIG_FILES="$CONFIG_FILES doc/Makefile" ;;
+ "doc/png/Makefile") CONFIG_FILES="$CONFIG_FILES doc/png/Makefile" ;;
+
+ *) { { $as_echo "$as_me:$LINENO: error: invalid argument: $ac_config_target" >&5
+$as_echo "$as_me: error: invalid argument: $ac_config_target" >&2;}
+ { (exit 1); exit 1; }; };;
+ esac
+done
+
+
+# If the user did not use the arguments to specify the items to instantiate,
+# then the envvar interface is used. Set only those that are not.
+# We use the long form for the default assignment because of an extremely
+# bizarre bug on SunOS 4.1.3.
+if $ac_need_defaults; then
+ test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files
+ test "${CONFIG_HEADERS+set}" = set || CONFIG_HEADERS=$config_headers
+fi
+
+# Have a temporary directory for convenience. Make it in the build tree
+# simply because there is no reason against having it here, and in addition,
+# creating and moving files from /tmp can sometimes cause problems.
+# Hook for its removal unless debugging.
+# Note that there is a small window in which the directory will not be cleaned:
+# after its creation but before its name has been assigned to `$tmp'.
+$debug ||
+{
+ tmp=
+ trap 'exit_status=$?
+ { test -z "$tmp" || test ! -d "$tmp" || rm -fr "$tmp"; } && exit $exit_status
+' 0
+ trap '{ (exit 1); exit 1; }' 1 2 13 15
+}
+# Create a (secure) tmp directory for tmp files.
+
+{
+ tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` &&
+ test -n "$tmp" && test -d "$tmp"
+} ||
+{
+ tmp=./conf$$-$RANDOM
+ (umask 077 && mkdir "$tmp")
+} ||
+{
+ $as_echo "$as_me: cannot create a temporary directory in ." >&2
+ { (exit 1); exit 1; }
+}
+
+# Set up the scripts for CONFIG_FILES section.
+# No need to generate them if there are no CONFIG_FILES.
+# This happens for instance with `./config.status config.h'.
+if test -n "$CONFIG_FILES"; then
+
+
+ac_cr=' '
+ac_cs_awk_cr=`$AWK 'BEGIN { print "a\rb" }' </dev/null 2>/dev/null`
+if test "$ac_cs_awk_cr" = "a${ac_cr}b"; then
+ ac_cs_awk_cr='\\r'
+else
+ ac_cs_awk_cr=$ac_cr
+fi
+
+echo 'BEGIN {' >"$tmp/subs1.awk" &&
+_ACEOF
+
+
+{
+ echo "cat >conf$$subs.awk <<_ACEOF" &&
+ echo "$ac_subst_vars" | sed 's/.*/&!$&$ac_delim/' &&
+ echo "_ACEOF"
+} >conf$$subs.sh ||
+ { { $as_echo "$as_me:$LINENO: error: could not make $CONFIG_STATUS" >&5
+$as_echo "$as_me: error: could not make $CONFIG_STATUS" >&2;}
+ { (exit 1); exit 1; }; }
+ac_delim_num=`echo "$ac_subst_vars" | grep -c '$'`
+ac_delim='%!_!# '
+for ac_last_try in false false false false false :; do
+ . ./conf$$subs.sh ||
+ { { $as_echo "$as_me:$LINENO: error: could not make $CONFIG_STATUS" >&5
+$as_echo "$as_me: error: could not make $CONFIG_STATUS" >&2;}
+ { (exit 1); exit 1; }; }
+
+ ac_delim_n=`sed -n "s/.*$ac_delim\$/X/p" conf$$subs.awk | grep -c X`
+ if test $ac_delim_n = $ac_delim_num; then
+ break
+ elif $ac_last_try; then
+ { { $as_echo "$as_me:$LINENO: error: could not make $CONFIG_STATUS" >&5
+$as_echo "$as_me: error: could not make $CONFIG_STATUS" >&2;}
+ { (exit 1); exit 1; }; }
+ else
+ ac_delim="$ac_delim!$ac_delim _$ac_delim!! "
+ fi
+done
+rm -f conf$$subs.sh
+
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+cat >>"\$tmp/subs1.awk" <<\\_ACAWK &&
+_ACEOF
+sed -n '
+h
+s/^/S["/; s/!.*/"]=/
+p
+g
+s/^[^!]*!//
+:repl
+t repl
+s/'"$ac_delim"'$//
+t delim
+:nl
+h
+s/\(.\{148\}\).*/\1/
+t more1
+s/["\\]/\\&/g; s/^/"/; s/$/\\n"\\/
+p
+n
+b repl
+:more1
+s/["\\]/\\&/g; s/^/"/; s/$/"\\/
+p
+g
+s/.\{148\}//
+t nl
+:delim
+h
+s/\(.\{148\}\).*/\1/
+t more2
+s/["\\]/\\&/g; s/^/"/; s/$/"/
+p
+b
+:more2
+s/["\\]/\\&/g; s/^/"/; s/$/"\\/
+p
+g
+s/.\{148\}//
+t delim
+' <conf$$subs.awk | sed '
+/^[^""]/{
+ N
+ s/\n//
+}
+' >>$CONFIG_STATUS || ac_write_fail=1
+rm -f conf$$subs.awk
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+_ACAWK
+cat >>"\$tmp/subs1.awk" <<_ACAWK &&
+ for (key in S) S_is_set[key] = 1
+ FS = ""
+
+}
+{
+ line = $ 0
+ nfields = split(line, field, "@")
+ substed = 0
+ len = length(field[1])
+ for (i = 2; i < nfields; i++) {
+ key = field[i]
+ keylen = length(key)
+ if (S_is_set[key]) {
+ value = S[key]
+ line = substr(line, 1, len) "" value "" substr(line, len + keylen + 3)
+ len += length(value) + length(field[++i])
+ substed = 1
+ } else
+ len += 1 + keylen
+ }
+
+ print line
+}
+
+_ACAWK
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+if sed "s/$ac_cr//" < /dev/null > /dev/null 2>&1; then
+ sed "s/$ac_cr\$//; s/$ac_cr/$ac_cs_awk_cr/g"
+else
+ cat
+fi < "$tmp/subs1.awk" > "$tmp/subs.awk" \
+ || { { $as_echo "$as_me:$LINENO: error: could not setup config files machinery" >&5
+$as_echo "$as_me: error: could not setup config files machinery" >&2;}
+ { (exit 1); exit 1; }; }
+_ACEOF
+
+# VPATH may cause trouble with some makes, so we remove $(srcdir),
+# ${srcdir} and @srcdir@ from VPATH if srcdir is ".", strip leading and
+# trailing colons and then remove the whole line if VPATH becomes empty
+# (actually we leave an empty line to preserve line numbers).
+if test "x$srcdir" = x.; then
+ ac_vpsub='/^[ ]*VPATH[ ]*=/{
+s/:*\$(srcdir):*/:/
+s/:*\${srcdir}:*/:/
+s/:*@srcdir@:*/:/
+s/^\([^=]*=[ ]*\):*/\1/
+s/:*$//
+s/^[^=]*=[ ]*$//
+}'
+fi
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+fi # test -n "$CONFIG_FILES"
+
+# Set up the scripts for CONFIG_HEADERS section.
+# No need to generate them if there are no CONFIG_HEADERS.
+# This happens for instance with `./config.status Makefile'.
+if test -n "$CONFIG_HEADERS"; then
+cat >"$tmp/defines.awk" <<\_ACAWK ||
+BEGIN {
+_ACEOF
+
+# Transform confdefs.h into an awk script `defines.awk', embedded as
+# here-document in config.status, that substitutes the proper values into
+# config.h.in to produce config.h.
+
+# Create a delimiter string that does not exist in confdefs.h, to ease
+# handling of long lines.
+ac_delim='%!_!# '
+for ac_last_try in false false :; do
+ ac_t=`sed -n "/$ac_delim/p" confdefs.h`
+ if test -z "$ac_t"; then
+ break
+ elif $ac_last_try; then
+ { { $as_echo "$as_me:$LINENO: error: could not make $CONFIG_HEADERS" >&5
+$as_echo "$as_me: error: could not make $CONFIG_HEADERS" >&2;}
+ { (exit 1); exit 1; }; }
+ else
+ ac_delim="$ac_delim!$ac_delim _$ac_delim!! "
+ fi
+done
+
+# For the awk script, D is an array of macro values keyed by name,
+# likewise P contains macro parameters if any. Preserve backslash
+# newline sequences.
+
+ac_word_re=[_$as_cr_Letters][_$as_cr_alnum]*
+sed -n '
+s/.\{148\}/&'"$ac_delim"'/g
+t rset
+:rset
+s/^[ ]*#[ ]*define[ ][ ]*/ /
+t def
+d
+:def
+s/\\$//
+t bsnl
+s/["\\]/\\&/g
+s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\
+D["\1"]=" \3"/p
+s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2"/p
+d
+:bsnl
+s/["\\]/\\&/g
+s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\
+D["\1"]=" \3\\\\\\n"\\/p
+t cont
+s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2\\\\\\n"\\/p
+t cont
+d
+:cont
+n
+s/.\{148\}/&'"$ac_delim"'/g
+t clear
+:clear
+s/\\$//
+t bsnlc
+s/["\\]/\\&/g; s/^/"/; s/$/"/p
+d
+:bsnlc
+s/["\\]/\\&/g; s/^/"/; s/$/\\\\\\n"\\/p
+b cont
+' <confdefs.h | sed '
+s/'"$ac_delim"'/"\\\
+"/g' >>$CONFIG_STATUS || ac_write_fail=1
+
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+ for (key in D) D_is_set[key] = 1
+ FS = ""
+}
+/^[\t ]*#[\t ]*(define|undef)[\t ]+$ac_word_re([\t (]|\$)/ {
+ line = \$ 0
+ split(line, arg, " ")
+ if (arg[1] == "#") {
+ defundef = arg[2]
+ mac1 = arg[3]
+ } else {
+ defundef = substr(arg[1], 2)
+ mac1 = arg[2]
+ }
+ split(mac1, mac2, "(") #)
+ macro = mac2[1]
+ prefix = substr(line, 1, index(line, defundef) - 1)
+ if (D_is_set[macro]) {
+ # Preserve the white space surrounding the "#".
+ print prefix "define", macro P[macro] D[macro]
+ next
+ } else {
+ # Replace #undef with comments. This is necessary, for example,
+ # in the case of _POSIX_SOURCE, which is predefined and required
+ # on some systems where configure will not decide to define it.
+ if (defundef == "undef") {
+ print "/*", prefix defundef, macro, "*/"
+ next
+ }
+ }
+}
+{ print }
+_ACAWK
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+ { { $as_echo "$as_me:$LINENO: error: could not setup config headers machinery" >&5
+$as_echo "$as_me: error: could not setup config headers machinery" >&2;}
+ { (exit 1); exit 1; }; }
+fi # test -n "$CONFIG_HEADERS"
+
+
+eval set X " :F $CONFIG_FILES :H $CONFIG_HEADERS "
+shift
+for ac_tag
+do
+ case $ac_tag in
+ :[FHLC]) ac_mode=$ac_tag; continue;;
+ esac
+ case $ac_mode$ac_tag in
+ :[FHL]*:*);;
+ :L* | :C*:*) { { $as_echo "$as_me:$LINENO: error: invalid tag $ac_tag" >&5
+$as_echo "$as_me: error: invalid tag $ac_tag" >&2;}
+ { (exit 1); exit 1; }; };;
+ :[FH]-) ac_tag=-:-;;
+ :[FH]*) ac_tag=$ac_tag:$ac_tag.in;;
+ esac
+ ac_save_IFS=$IFS
+ IFS=:
+ set x $ac_tag
+ IFS=$ac_save_IFS
+ shift
+ ac_file=$1
+ shift
+
+ case $ac_mode in
+ :L) ac_source=$1;;
+ :[FH])
+ ac_file_inputs=
+ for ac_f
+ do
+ case $ac_f in
+ -) ac_f="$tmp/stdin";;
+ *) # Look for the file first in the build tree, then in the source tree
+ # (if the path is not absolute). The absolute path cannot be DOS-style,
+ # because $ac_f cannot contain `:'.
+ test -f "$ac_f" ||
+ case $ac_f in
+ [\\/$]*) false;;
+ *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";;
+ esac ||
+ { { $as_echo "$as_me:$LINENO: error: cannot find input file: $ac_f" >&5
+$as_echo "$as_me: error: cannot find input file: $ac_f" >&2;}
+ { (exit 1); exit 1; }; };;
+ esac
+ case $ac_f in *\'*) ac_f=`$as_echo "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac
+ ac_file_inputs="$ac_file_inputs '$ac_f'"
+ done
+
+ # Let's still pretend it is `configure' which instantiates (i.e., don't
+ # use $as_me), people would be surprised to read:
+ # /* config.h. Generated by config.status. */
+ configure_input='Generated from '`
+ $as_echo "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g'
+ `' by configure.'
+ if test x"$ac_file" != x-; then
+ configure_input="$ac_file. $configure_input"
+ { $as_echo "$as_me:$LINENO: creating $ac_file" >&5
+$as_echo "$as_me: creating $ac_file" >&6;}
+ fi
+ # Neutralize special characters interpreted by sed in replacement strings.
+ case $configure_input in #(
+ *\&* | *\|* | *\\* )
+ ac_sed_conf_input=`$as_echo "$configure_input" |
+ sed 's/[\\\\&|]/\\\\&/g'`;; #(
+ *) ac_sed_conf_input=$configure_input;;
+ esac
+
+ case $ac_tag in
+ *:-:* | *:-) cat >"$tmp/stdin" \
+ || { { $as_echo "$as_me:$LINENO: error: could not create $ac_file" >&5
+$as_echo "$as_me: error: could not create $ac_file" >&2;}
+ { (exit 1); exit 1; }; } ;;
+ esac
+ ;;
+ esac
+
+ ac_dir=`$as_dirname -- "$ac_file" ||
+$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$ac_file" : 'X\(//\)[^/]' \| \
+ X"$ac_file" : 'X\(//\)$' \| \
+ X"$ac_file" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$ac_file" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)[^/].*/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'`
+ { as_dir="$ac_dir"
+ case $as_dir in #(
+ -*) as_dir=./$as_dir;;
+ esac
+ test -d "$as_dir" || { $as_mkdir_p && mkdir -p "$as_dir"; } || {
+ as_dirs=
+ while :; do
+ case $as_dir in #(
+ *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'(
+ *) as_qdir=$as_dir;;
+ esac
+ as_dirs="'$as_qdir' $as_dirs"
+ as_dir=`$as_dirname -- "$as_dir" ||
+$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$as_dir" : 'X\(//\)[^/]' \| \
+ X"$as_dir" : 'X\(//\)$' \| \
+ X"$as_dir" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$as_dir" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)[^/].*/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'`
+ test -d "$as_dir" && break
+ done
+ test -z "$as_dirs" || eval "mkdir $as_dirs"
+ } || test -d "$as_dir" || { { $as_echo "$as_me:$LINENO: error: cannot create directory $as_dir" >&5
+$as_echo "$as_me: error: cannot create directory $as_dir" >&2;}
+ { (exit 1); exit 1; }; }; }
+ ac_builddir=.
+
+case "$ac_dir" in
+.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;;
+*)
+ ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'`
+ # A ".." for each directory in $ac_dir_suffix.
+ ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'`
+ case $ac_top_builddir_sub in
+ "") ac_top_builddir_sub=. ac_top_build_prefix= ;;
+ *) ac_top_build_prefix=$ac_top_builddir_sub/ ;;
+ esac ;;
+esac
+ac_abs_top_builddir=$ac_pwd
+ac_abs_builddir=$ac_pwd$ac_dir_suffix
+# for backward compatibility:
+ac_top_builddir=$ac_top_build_prefix
+
+case $srcdir in
+ .) # We are building in place.
+ ac_srcdir=.
+ ac_top_srcdir=$ac_top_builddir_sub
+ ac_abs_top_srcdir=$ac_pwd ;;
+ [\\/]* | ?:[\\/]* ) # Absolute name.
+ ac_srcdir=$srcdir$ac_dir_suffix;
+ ac_top_srcdir=$srcdir
+ ac_abs_top_srcdir=$srcdir ;;
+ *) # Relative name.
+ ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix
+ ac_top_srcdir=$ac_top_build_prefix$srcdir
+ ac_abs_top_srcdir=$ac_pwd/$srcdir ;;
+esac
+ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix
+
+
+ case $ac_mode in
+ :F)
+ #
+ # CONFIG_FILE
+ #
+
+ case $INSTALL in
+ [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;;
+ *) ac_INSTALL=$ac_top_build_prefix$INSTALL ;;
+ esac
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+# If the template does not know about datarootdir, expand it.
+# FIXME: This hack should be removed a few years after 2.60.
+ac_datarootdir_hack=; ac_datarootdir_seen=
+
+ac_sed_dataroot='
+/datarootdir/ {
+ p
+ q
+}
+/@datadir@/p
+/@docdir@/p
+/@infodir@/p
+/@localedir@/p
+/@mandir@/p
+'
+case `eval "sed -n \"\$ac_sed_dataroot\" $ac_file_inputs"` in
+*datarootdir*) ac_datarootdir_seen=yes;;
+*@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*)
+ { $as_echo "$as_me:$LINENO: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5
+$as_echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;}
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+ ac_datarootdir_hack='
+ s&@datadir@&$datadir&g
+ s&@docdir@&$docdir&g
+ s&@infodir@&$infodir&g
+ s&@localedir@&$localedir&g
+ s&@mandir@&$mandir&g
+ s&\\\${datarootdir}&$datarootdir&g' ;;
+esac
+_ACEOF
+
+# Neutralize VPATH when `$srcdir' = `.'.
+# Shell code in configure.ac might set extrasub.
+# FIXME: do we really want to maintain this feature?
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+ac_sed_extra="$ac_vpsub
+$extrasub
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+:t
+/@[a-zA-Z_][a-zA-Z_0-9]*@/!b
+s|@configure_input@|$ac_sed_conf_input|;t t
+s&@top_builddir@&$ac_top_builddir_sub&;t t
+s&@top_build_prefix@&$ac_top_build_prefix&;t t
+s&@srcdir@&$ac_srcdir&;t t
+s&@abs_srcdir@&$ac_abs_srcdir&;t t
+s&@top_srcdir@&$ac_top_srcdir&;t t
+s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t
+s&@builddir@&$ac_builddir&;t t
+s&@abs_builddir@&$ac_abs_builddir&;t t
+s&@abs_top_builddir@&$ac_abs_top_builddir&;t t
+s&@INSTALL@&$ac_INSTALL&;t t
+$ac_datarootdir_hack
+"
+eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$tmp/subs.awk" >$tmp/out \
+ || { { $as_echo "$as_me:$LINENO: error: could not create $ac_file" >&5
+$as_echo "$as_me: error: could not create $ac_file" >&2;}
+ { (exit 1); exit 1; }; }
+
+test -z "$ac_datarootdir_hack$ac_datarootdir_seen" &&
+ { ac_out=`sed -n '/\${datarootdir}/p' "$tmp/out"`; test -n "$ac_out"; } &&
+ { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' "$tmp/out"`; test -z "$ac_out"; } &&
+ { $as_echo "$as_me:$LINENO: WARNING: $ac_file contains a reference to the variable \`datarootdir'
+which seems to be undefined. Please make sure it is defined." >&5
+$as_echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir'
+which seems to be undefined. Please make sure it is defined." >&2;}
+
+ rm -f "$tmp/stdin"
+ case $ac_file in
+ -) cat "$tmp/out" && rm -f "$tmp/out";;
+ *) rm -f "$ac_file" && mv "$tmp/out" "$ac_file";;
+ esac \
+ || { { $as_echo "$as_me:$LINENO: error: could not create $ac_file" >&5
+$as_echo "$as_me: error: could not create $ac_file" >&2;}
+ { (exit 1); exit 1; }; }
+ ;;
+ :H)
+ #
+ # CONFIG_HEADER
+ #
+ if test x"$ac_file" != x-; then
+ {
+ $as_echo "/* $configure_input */" \
+ && eval '$AWK -f "$tmp/defines.awk"' "$ac_file_inputs"
+ } >"$tmp/config.h" \
+ || { { $as_echo "$as_me:$LINENO: error: could not create $ac_file" >&5
+$as_echo "$as_me: error: could not create $ac_file" >&2;}
+ { (exit 1); exit 1; }; }
+ if diff "$ac_file" "$tmp/config.h" >/dev/null 2>&1; then
+ { $as_echo "$as_me:$LINENO: $ac_file is unchanged" >&5
+$as_echo "$as_me: $ac_file is unchanged" >&6;}
+ else
+ rm -f "$ac_file"
+ mv "$tmp/config.h" "$ac_file" \
+ || { { $as_echo "$as_me:$LINENO: error: could not create $ac_file" >&5
+$as_echo "$as_me: error: could not create $ac_file" >&2;}
+ { (exit 1); exit 1; }; }
+ fi
+ else
+ $as_echo "/* $configure_input */" \
+ && eval '$AWK -f "$tmp/defines.awk"' "$ac_file_inputs" \
+ || { { $as_echo "$as_me:$LINENO: error: could not create -" >&5
+$as_echo "$as_me: error: could not create -" >&2;}
+ { (exit 1); exit 1; }; }
+ fi
+ ;;
+
+
+ esac
+
+done # for ac_tag
+
+
+{ (exit 0); exit 0; }
+_ACEOF
+chmod +x $CONFIG_STATUS
+ac_clean_files=$ac_clean_files_save
+
+test $ac_write_fail = 0 ||
+ { { $as_echo "$as_me:$LINENO: error: write failure creating $CONFIG_STATUS" >&5
+$as_echo "$as_me: error: write failure creating $CONFIG_STATUS" >&2;}
+ { (exit 1); exit 1; }; }
+
+
+# configure is writing to config.log, and then calls config.status.
+# config.status does its own redirection, appending to config.log.
+# Unfortunately, on DOS this fails, as config.log is still kept open
+# by configure, so config.status won't be able to write to it; its
+# output is simply discarded. So we exec the FD to /dev/null,
+# effectively closing config.log, so it can be properly (re)opened and
+# appended to by config.status. When coming back to configure, we
+# need to make the FD available again.
+if test "$no_create" != yes; then
+ ac_cs_success=:
+ ac_config_status_args=
+ test "$silent" = yes &&
+ ac_config_status_args="$ac_config_status_args --quiet"
+ exec 5>/dev/null
+ $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false
+ exec 5>>config.log
+ # Use ||, not &&, to avoid exiting from the if with $? = 1, which
+ # would make configure fail if this is the last instruction.
+ $ac_cs_success || { (exit 1); exit 1; }
+fi
+if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then
+ { $as_echo "$as_me:$LINENO: WARNING: unrecognized options: $ac_unrecognized_opts" >&5
+$as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;}
+fi
+
+
+if test "x$GCDIR" != "x" ; then
+ as_ac_File=`$as_echo "ac_cv_file_$GCDIR.tar.gz" | $as_tr_sh`
+{ $as_echo "$as_me:$LINENO: checking for $GCDIR.tar.gz" >&5
+$as_echo_n "checking for $GCDIR.tar.gz... " >&6; }
+if { as_var=$as_ac_File; eval "test \"\${$as_var+set}\" = set"; }; then
+ $as_echo_n "(cached) " >&6
+else
+ test "$cross_compiling" = yes &&
+ { { $as_echo "$as_me:$LINENO: error: cannot check for file existence when cross compiling" >&5
+$as_echo "$as_me: error: cannot check for file existence when cross compiling" >&2;}
+ { (exit 1); exit 1; }; }
+if test -r "$GCDIR.tar.gz"; then
+ eval "$as_ac_File=yes"
+else
+ eval "$as_ac_File=no"
+fi
+fi
+ac_res=`eval 'as_val=${'$as_ac_File'}
+ $as_echo "$as_val"'`
+ { $as_echo "$as_me:$LINENO: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+as_val=`eval 'as_val=${'$as_ac_File'}
+ $as_echo "$as_val"'`
+ if test "x$as_val" = x""yes; then
+ :
+else
+
+ echo
+ echo Please put the Boehm garbage collector tar.gz file in the current directory.
+ echo FOR EXAMPLE, USE THE COMMAND:
+ echo
+ echo wget http://www.hpl.hp.com/personal/Hans_Boehm/gc/gc_source/$GCDIR.tar.gz
+ exit 1
+
+fi
+
+fi
diff --git a/Build/source/utils/asymptote/configure.ac b/Build/source/utils/asymptote/configure.ac
new file mode 100644
index 00000000000..b2974bd984f
--- /dev/null
+++ b/Build/source/utils/asymptote/configure.ac
@@ -0,0 +1,297 @@
+# -*- Autoconf -*-
+# Run autoheader and autoconf to produce a header and configure script from
+# this file.
+
+AC_PREREQ(2)
+AC_INIT([Asymptote],[1.72],[http://sourceforge.net/projects/asymptote])
+VERSION=$PACKAGE_VERSION
+AC_SUBST(VERSION)
+
+test "$CFLAGS" || CFLAGS="-g -O3"
+
+AC_C_BIGENDIAN(AC_DEFINE(WORDS_BIG_ENDIAN, 1,
+ [Define if words are stored with the most significant byte first.]),AC_DEFINE(WORDS_LITTLE_ENDIAN, 1 ,
+ [Define if words are stored with the least significant byte first.]))
+
+test "$prefix" = NONE && prefix=/usr/local
+Datadir=$datadir
+test "$Datadir" = '${datarootdir}' && Datadir=$datarootdir
+test "$Datadir" = '${prefix}/share' && Datadir=$prefix/share
+AC_SUBST(Datadir)
+
+AC_ARG_WITH(latex,
+ [ --with-latex=PATH specify path to LaTeX installation ],
+ [if test "x$withval" != "x" ; then
+ latexdir=$withval
+ fi
+ ],[
+AC_CHECK_PROG(kpsewhich,kpsewhich,true)
+if test "x$kpsewhich" = "xtrue"; then
+ latexdir=`kpsewhich -expand-var='$TEXMFLOCAL'/tex/latex`
+else
+ latexdir=$prefix/share/texmf/tex/latex
+ AC_CHECK_FILE($latexdir/base/latex.ltx,,
+ [latexdir=/usr/share/texmf/tex/latex
+ AC_CHECK_FILE($latexdir/base/latex.ltx,,)])
+fi
+])
+
+AC_CHECK_PROGS(TEXI2DVI,[texi2dvi texi2dvi4a2ps])
+AC_SUBST(TEXI2DVI)
+
+latexdir=$latexdir/asymptote
+
+AC_MSG_NOTICE([Using $latexdir for LaTeX style file])
+
+AC_SUBST(latexdir)
+
+docdir=$Datadir/doc/asymptote
+
+AC_ARG_WITH(docdir,
+ [ --with-docdir=PATH alternate documentation installation directory],
+ [if test "x$withval" != "x" ; then
+ docdir=$withval
+ fi
+ ])
+AC_SUBST(docdir)
+
+sysdir=$Datadir/asymptote
+
+AC_ARG_ENABLE(tetex-build,
+[ --enable-tetex-build automatically determine settings.sysdir from kpsewhich],
+[ if test "x$enableval" = "xyes" ; then
+ sysdir=""
+ fi
+])
+
+AC_DEFINE_UNQUOTED(ASYMPTOTE_SYSDIR,"$sysdir",
+ [System directory for global .asy files])
+AC_DEFINE_UNQUOTED(ASYMPTOTE_DOCDIR,"$docdir",
+ [Directory for documentation])
+
+AC_CONFIG_SRCDIR([absyn.cc])
+
+AC_LANG([C++])
+
+# Checks for programs.
+AC_PROG_LEX
+AC_PROG_CXX
+AC_PROG_INSTALL
+AC_PROG_CC
+AC_PROG_MAKE_SET
+AC_PROG_YACC
+
+if test "$GXX" = yes ; then
+ ac_gcc_version=`echo __GNUC__ | $CC -E - | grep -v ^\#`
+ if test "$ac_gcc_version" -lt 4; then
+ CFLAGS=$CFLAGS" -finline-limit=400"
+ fi
+fi
+
+AC_CHECK_HEADER(fftw3.h,
+ AC_CHECK_LIB([fftw3], fftw_execute,,
+ AC_MSG_NOTICE([*** Could not find libfftw3: will compile without optional fast Fourier transforms. ***])),
+ AC_MSG_NOTICE([*** Header file fftw3.h not found: will compile without optional fast Fourier transforms. ***]))
+
+GCVERSION=gc-7.1
+
+AC_CHECK_FILE($GCVERSION.tar.gz,
+ac_cv_use_gc=$GCVERSION,
+[GC_SYSTEM="$GCVERSION.tar.gz not found: using system Boehm garbage collector"
+ac_cv_use_gc="system"])
+AC_ARG_ENABLE(gc,
+ [ --enable-gc[[=system]] enable system Boehm garbage collector]
+ [ [[=VERSION]] enable local VERSION of Boehm garbage collector]
+ [ [[=PREFIX]] use Boehm garbage collector installed in PREFIX],
+ [
+ if test "x$enableval" != "xyes"; then
+ ac_cv_use_gc=$enableval
+ GC_SYSTEM=""
+ fi
+ ])
+
+OPTIONS="-D_FILE_OFFSET_BITS=64 "
+GCLIB=
+GCPPLIB=
+GCNAME="Boehm Garbage Collector"
+GCOPTIONS=""
+if test "x$ac_cv_use_gc" != "xno" ; then
+ OPTIONS=$OPTIONS"-DUSEGC "
+ case $ac_cv_use_gc in
+ system|*[[\\/]]*)
+ if test "x$ac_cv_use_gc" = "xsystem" ; then
+ INCL="-I$prefix/include/gc -I/usr/include/gc"
+ LIBS=$LIBS"-L$prefix/lib "
+ else
+ INCL="-I$ac_cv_use_gc/include/gc"
+ LIBS=$LIBS"-L$ac_cv_use_gc/lib "
+ fi
+ CPPFLAGS_SAVE=$CPPFLAGS
+ CPPFLAGS=$CPPFLAGS" $INCL"
+ AC_CHECK_HEADER(gc.h,
+ AC_CHECK_LIB([gc],[GC_malloc],[
+ LIBS=$LIBS"-lgc "
+ AC_MSG_NOTICE([enabling system $GCNAME])],[
+ GCDIR=$GCVERSION
+ GCLIB="\$(GC)/.libs/libgc.a"
+ AC_MSG_NOTICE($GCNAME library not found)]),
+ GCDIR=$GCVERSION
+ INCL="-I\$(GC)/include"
+ AC_MSG_NOTICE($GCNAME header file not found))
+ CPPFLAGS=$CPPFLAGS_SAVE
+ ;;
+ *)
+ GCDIR=$ac_cv_use_gc
+ GCOPTIONS="--disable-shared "
+ AC_MSG_NOTICE([enabling local $GCNAME $GCDIR])
+ GCLIB="\$(GC)/.libs/libgc.a"
+ INCL="-I\$(GC)/include"
+ ;;
+ esac
+else
+ AC_MSG_NOTICE([disabling the $GCNAME])
+fi
+
+AC_ARG_ENABLE(gc-debug,
+[ --enable-gc-debug enable (slow) garbage collector debugging],
+[ if test "x$ac_cv_use_gc" != "xno" ; then
+ if test "x$enableval" = "xyes" ; then
+ OPTIONS=$OPTIONS"-DGC_DEBUG "
+ AC_MSG_NOTICE([*** Enabling GC debugging: remember to make clean ***])
+ AC_MSG_NOTICE([*** Set the environment variable GC_FIND_LEAK at runtime ***])
+ fi
+ fi
+])
+
+AC_ARG_ENABLE(gc-full-debug,
+[ --enable-gc-full-debug enable (very slow) garbage collector backtrace],
+[ if test "x$ac_cv_use_gc" != "xno" ; then
+ if test "x$enableval" = "xyes" ; then
+ OPTIONS=$OPTIONS"-DGC_DEBUG -DGC_BACKTRACE "
+ GCOPTIONS=$GCOPTIONS"--enable-gc-debug "
+ AC_MSG_NOTICE([*** Enabling GC backtrace debugging; remember to make gc-clean ***])
+ fi
+ fi
+])
+
+AC_CHECK_FUNC(getopt_long_only, AC_DEFINE(HAVE_GNU_GETOPT_H, 1,
+ [Define if getopt.h is the GNU version]),
+ getopt="getopt getopt1",)
+AC_CHECK_HEADER(tr1/unordered_map,,
+ [AC_CHECK_HEADER(ext/hash_map,,OPTIONS=$OPTIONS"-DNOHASH ")])
+
+AC_SUBST(getopt)
+AC_SUBST(GCDIR)
+AC_SUBST(GCOPTIONS)
+AC_SUBST(GCLIB)
+AC_SUBST(GCPPLIB)
+AC_SUBST(INCL)
+AC_SUBST(OPTIONS)
+
+# Checks for libraries.
+AC_CHECK_LIB([ncurses], [setupterm], [AC_DEFINE(HAVE_LIBCURSES)
+ LIBS=$LIBS"-lncurses "],
+ AC_CHECK_LIB([curses], [setupterm]))
+AC_CHECK_LIB([m], [sqrt])
+AC_CHECK_LIB([z], [deflate])
+AC_CHECK_LIB([pthread], [pthread_create])
+AC_CHECK_LIB([sigsegv], [stackoverflow_install_handler])
+
+AC_CHECK_LIB([readline], [rl_completion_matches],,
+AC_MSG_NOTICE(*** Could not find GNU readline 4.2 or later: will compile without readline support ***))
+
+# Checks for header files.
+AC_HEADER_SYS_WAIT
+AC_CHECK_HEADERS([fenv.h stddef.h libintl.h])
+AC_CHECK_HEADERS([ncurses/curses.h ncurses.h curses.h], [break])
+AC_CHECK_HEADERS(fpu_control.h)
+
+AC_COMPILE_IFELSE(AC_LANG_PROGRAM([#include "xstream.h"]),
+ [AC_SEARCH_LIBS([xdrstdio_create],[nsl rpc])
+ AC_DEFINE(HAVE_RPC_RPC_H, 1,
+ [Define if you have a working <rpc/rpc.h> header file])],
+ AC_MSG_WARN([*** Broken rpc headers; XDR support disabled ***]))
+
+AC_CHECK_HEADER(gsl/gsl_sf.h,
+ AC_CHECK_LIB([gsl], gsl_sf_Si, [AC_DEFINE(HAVE_LIBGSL, 1,
+ [Define to 1 if you have the 'gsl' library (-lgsl). ]) LIBS=$LIBS"-lgsl -lgslcblas "],
+ AC_MSG_NOTICE([*** Could not find libgsl: will compile without optional special functions. ***]),[-lgslcblas]),
+ AC_MSG_NOTICE([*** Header file gsl_sf.h not found: will compile without optional special functions. ***]))
+
+case "$OSTYPE" in
+ cygwin) AC_CHECK_HEADER(GL/glut.h,
+ [AC_DEFINE(HAVE_LIBGLUT, 1,
+ [Define if you have the `freeglut' library (-lfreeglut).])
+ LIBS=$LIBS"-lfreeglut -lopengl32 "],
+ AC_MSG_NOTICE([*** Could not find freeglut: will compile without OpenGL support ***]))
+ AC_CHECK_LIB([GLU], [gluNewNurbsRenderer],[AC_DEFINE(HAVE_LIBGLU, 1,
+ [Define to 1 if you have the 'glu32' library (-lglu32). ]) LIBS=$LIBS"-lglu32 "],
+ AC_MSG_NOTICE([*** Could not find libglu32: will compile without OpenGL support ***]))
+ ;;
+ darwin*) AC_CHECK_HEADER(GLUT/glut.h,
+ [AC_DEFINE(HAVE_LIBGLUT, 1,
+ [Define if you have the `glut' library (-lglut).])
+ AC_DEFINE(HAVE_LIBGLU, 1,
+ [Define to 1 if you have the 'GLU' library. ])
+AC_COMPILE_IFELSE(AC_LANG_PROGRAM([
+#include <OpenGL/gl.h>
+#include <OpenGL/glu.h>
+#ifndef GLU_TESS_CALLBACK_TRIPLEDOT
+typedef GLvoid (* _GLUfuncptr)(...);
+void f(void) {
+ gluNurbsCallback(gluNewNurbsRenderer(),GLU_NURBS_BEGIN,(_GLUfuncptr) glBegin);
+}
+#endif
+]),[AC_DEFINE(GLU_TESS_CALLBACK_TRIPLEDOT, 1, [Define if gluNurbsCallback expects a variadic function.])])
+ LIBS=$LIBS"-framework GLUT -framework OpenGL -framework Cocoa"],
+ AC_MSG_NOTICE([*** Could not find glut: will compile without OpenGL support ***]))
+ ;;
+ *) AC_CHECK_LIB([glut], [glutMainLoop],,
+ AC_MSG_NOTICE([*** Could not find libglut: will compile without OpenGL support ***]))
+ AC_CHECK_LIB([GLU], [gluNewNurbsRenderer],,
+ AC_MSG_NOTICE([*** Could not find libGLU: will compile without OpenGL support ***]))
+esac
+
+
+# Checks for typedefs, structures, and compiler characteristics.
+AC_TYPE_PID_T
+AC_TYPE_SIZE_T
+AC_CHECK_TYPES([ptrdiff_t])
+AC_CHECK_TYPES([long long])
+AC_CHECK_TYPES([long])
+AC_C_CONST
+AC_C_INLINE
+AC_TYPE_SIGNAL
+
+AC_DEFUN(AC_FUNC_STRPTIME, [
+ AC_CHECK_FUNCS(strptime)
+ AC_MSG_CHECKING(for strptime declaration in time.h)
+ AC_EGREP_HEADER(strptime, time.h, [
+ AC_DEFINE([HAVE_STRPTIME_DECL],,[Define if the function strptime is declared in <time.h>])
+ AC_MSG_RESULT(yes)], [AC_MSG_RESULT(no)
+ ])
+])
+
+# Checks for library functions.
+AC_FUNC_FORK
+AC_CHECK_FUNCS([dup2 floor memset pow sqrt strchr tgamma])
+AC_FUNC_STRFTIME
+AC_FUNC_STRPTIME
+AC_FUNC_ERROR_AT_LINE
+AC_FUNC_FSEEKO
+
+AC_CONFIG_HEADERS(config.h)
+
+AC_CONFIG_FILES([Makefile doc/Makefile doc/png/Makefile])
+AC_OUTPUT
+
+if test "x$GCDIR" != "x" ; then
+ AC_CHECK_FILE($GCDIR.tar.gz,,[
+ echo
+ echo Please put the Boehm garbage collector tar.gz file in the current directory.
+ echo FOR EXAMPLE, USE THE COMMAND:
+ echo
+ echo wget http://www.hpl.hp.com/personal/Hans_Boehm/gc/gc_source/$GCDIR.tar.gz
+ exit 1
+ ])
+fi
diff --git a/Build/source/utils/asymptote/constructor.cc b/Build/source/utils/asymptote/constructor.cc
new file mode 100644
index 00000000000..5915a614985
--- /dev/null
+++ b/Build/source/utils/asymptote/constructor.cc
@@ -0,0 +1,140 @@
+/*****
+ * constructor.cc
+ * Andy Hammerlindl 2007/05/12
+ *
+ * Using
+ *
+ * void operator init(<args>)
+ *
+ * as a field in the definition structure named Foo implicitly creates a
+ * function that could be explicitly defined with code similar to
+ *
+ * static Foo Foo(<args>) {
+ * Foo a=new Foo;
+ * a.operator init(<args>);
+ * return a;
+ * }
+ *
+ * This function is usable within further code in the structure definition and,
+ * after the end of the structure definition, is carried over into the enclosing
+ * scope so that it lasts as long as the type definition.
+ *****/
+
+#include "stack.h"
+#include "entry.h"
+#include "coenv.h"
+#include "dec.h"
+#include "newexp.h"
+
+namespace absyntax {
+
+using namespace trans;
+using namespace types;
+
+// Defined in dec.cc.
+varEntry *makeVarEntry(position pos, coenv &e, record *r, types::ty *t);
+
+bool definesImplicitConstructor(coenv &e, record *r, varEntry *v, symbol *id)
+{
+ if (id == symbol::initsym &&
+ r != 0 &&
+ v->getType()->kind == ty_function &&
+ e.c.isStatic() == false &&
+ e.c.isTopLevel() == false)
+ {
+ function *ft=dynamic_cast<function *>(v->getType());
+ if (ft->getResult()->kind == ty_void)
+ return true;
+ }
+
+ return false;
+}
+
+// Given the coenv of the body of the constructor, encode the neccessary
+// instructions to make a new initialized object.
+void transConstructorBody(position pos, coenv &e, record *r, varEntry *init)
+{
+ assert(r);
+ assert(init);
+
+ // Create a varEntry to hold the new object. Foo a;
+ varEntry *v=makeVarEntry(pos, e, 0 /* not a field */, r);
+
+ // Initialize the object. a=new Foo;
+ newRecordExp::transFromTyEntry(pos, e, new tyEntry(r, 0, 0, position()));
+ v->encode(WRITE, pos, e.c);
+ e.c.encode(inst::pop);
+
+ // Push the args onto the stack.
+ size_t numArgs=init->getSignature()->getNumFormals();
+ for (size_t i=0; i<numArgs; ++i) {
+ access *a=e.c.accessFormal((Int)i);
+ a->encode(READ, pos, e.c);
+ }
+
+ // Push the object on the stack.
+ v->encode(READ, pos, e.c);
+
+ // Call the 'operator init' field of the object.
+ init->encode(CALL, pos, e.c, v->getLevel());
+
+ // Push the object again.
+ v->encode(READ, pos, e.c);
+
+ // Return the initialized object.
+ e.c.encode(inst::ret);
+}
+
+varEntry *constructorFromInitializer(position pos, coenv &e, record *r,
+ varEntry *init)
+{
+ assert(r);
+
+ types::function *ft=new types::function(r, init->getSignature());
+
+ // Create a new function environment.
+ coder fc = e.c.newFunction(ft);
+ coenv fe(fc,e.e);
+
+ // Translate the function.
+ fe.e.beginScope();
+
+ transConstructorBody(pos, fe, r, init);
+
+ fe.e.endScope();
+
+ // Put an instance of the new function on the stack.
+ vm::lambda *l = fe.c.close();
+ e.c.encode(inst::pushclosure);
+ e.c.encode(inst::makefunc, l);
+
+ // Save it into a varEntry.
+ varEntry *v=makeVarEntry(pos, e, r, ft);
+ v->encode(WRITE, pos, e.c);
+ e.c.encode(inst::pop);
+
+ return v;
+}
+
+void addConstructorFromInitializer(position pos, coenv &e, record *r,
+ varEntry *init)
+{
+ assert(r);
+
+ // Constructors are declared statically.
+ e.c.pushModifier(EXPLICIT_STATIC);
+
+ varEntry *v=constructorFromInitializer(pos, e, r, init);
+
+ // Add the constructor function under the same name as the record.
+ addVar(e, r, v, r->getName());
+
+ // Add to the "post definition environment" of the record, so it will also be
+ // added to the enclosing scope when the record definition ends.
+ r->postdefenv.addVar(r->getName(), v);
+
+ e.c.popModifier();
+}
+
+} // namespace absyntax
+
diff --git a/Build/source/utils/asymptote/dec.cc b/Build/source/utils/asymptote/dec.cc
new file mode 100644
index 00000000000..7c7ed1edd59
--- /dev/null
+++ b/Build/source/utils/asymptote/dec.cc
@@ -0,0 +1,827 @@
+/*****
+ * dec.cc
+ * Andy Hammerlindl 2002/8/29
+ *
+ * Represents the abstract syntax tree for declarations in the language.
+ * Also included is an abstract syntax for types as they are most often
+ * used with declarations.
+ *****/
+
+#include "errormsg.h"
+#include "coenv.h"
+#include "dec.h"
+#include "fundec.h"
+#include "newexp.h"
+#include "stm.h"
+#include "exp.h"
+#include "modifier.h"
+#include "runtime.h"
+#include "parser.h"
+
+namespace absyntax {
+
+using namespace trans;
+using namespace types;
+
+using mem::list;
+
+trans::tyEntry *ty::transAsTyEntry(coenv &e, record *where)
+{
+ return new trans::tyEntry(trans(e, false), 0, where, getPos());
+}
+
+
+void nameTy::prettyprint(ostream &out, Int indent)
+{
+ prettyname(out, "nameTy",indent);
+
+ id->prettyprint(out, indent+1);
+}
+
+types::ty *nameTy::trans(coenv &e, bool tacit)
+{
+ return id->typeTrans(e, tacit);
+}
+
+trans::tyEntry *nameTy::transAsTyEntry(coenv &e, record *)
+{
+ return id->tyEntryTrans(e);
+}
+
+
+void dimensions::prettyprint(ostream &out, Int indent)
+{
+ prettyindent(out, indent);
+ out << "dimensions (" << depth << ")\n";
+}
+
+types::array *dimensions::truetype(types::ty *base)
+{
+ if (base->kind == ty_void) {
+ em.error(getPos());
+ em << "cannot declare array of type void";
+ }
+
+ assert(depth >= 1);
+ size_t d=depth;
+ types::array *a=new types::array(base); d--;
+ for (; d > 0; d--) {
+ a = new types::array(a);
+ }
+ return a;
+}
+
+
+void arrayTy::prettyprint(ostream &out, Int indent)
+{
+ prettyname(out, "arrayTy",indent);
+
+ cell->prettyprint(out, indent+1);
+ dims->prettyprint(out, indent+1);
+}
+
+// NOTE: Can this be merged with trans somehow?
+void arrayTy::addOps(coenv &e, record *r)
+{
+ types::array *t=dynamic_cast<types::array *>(trans(e, true));
+ e.e.addArrayOps(t);
+ if (r)
+ r->e.addArrayOps(t);
+}
+
+types::ty *arrayTy::trans(coenv &e, bool tacit)
+{
+ types::ty *ct = cell->trans(e, tacit);
+ assert(ct);
+
+ types::array *t = dims->truetype(ct);
+ assert(t);
+
+ return t;
+}
+
+tyEntryTy::tyEntryTy(position pos, types::ty *t)
+ : ty(pos), ent(new trans::tyEntry(t, 0, 0, position()))
+{
+}
+
+void tyEntryTy::prettyprint(ostream &out, Int indent)
+{
+ prettyindent(out,indent);
+ out << "tyEntryTy: " << *(ent->t) << "\n";
+}
+
+types::ty *tyEntryTy::trans(coenv &, bool) {
+ return ent->t;
+}
+
+
+vm::lambda *runnable::transAsCodelet(coenv &e)
+{
+ coder c=e.c.newCodelet();
+ coenv ce(c, e.e);
+ markTrans(ce);
+ return c.close();
+}
+
+
+void block::prettystms(ostream &out, Int indent)
+{
+ for (list<runnable *>::iterator p = stms.begin(); p != stms.end(); ++p)
+ (*p)->prettyprint(out, indent);
+}
+
+void block::prettyprint(ostream &out, Int indent)
+{
+ prettyname(out,"block",indent);
+ prettystms(out, indent+1);
+}
+
+void block::trans(coenv &e)
+{
+ if (scope) e.e.beginScope();
+ for (list<runnable *>::iterator p = stms.begin(); p != stms.end(); ++p) {
+ (*p)->markTrans(e);
+ }
+ if (scope) e.e.endScope();
+}
+
+void block::transAsField(coenv &e, record *r)
+{
+ if (scope) e.e.beginScope();
+ for (list<runnable *>::iterator p = stms.begin(); p != stms.end(); ++p) {
+ (*p)->markTransAsField(e, r);
+ }
+ if (scope) e.e.endScope();
+}
+
+void block::transAsRecordBody(coenv &e, record *r)
+{
+ transAsField(e, r);
+ e.c.closeRecord();
+}
+
+record *block::transAsFile(genv& ge, symbol *id)
+{
+ // Create the new module.
+ record *r = new record(id, new frame(0,0));
+
+ // Create coder and environment to translate the module.
+ // File-level modules have dynamic fields by default.
+ coder c(r, 0);
+ env e(ge);
+ coenv ce(c, e);
+
+ // Translate the abstract syntax.
+ if (settings::getSetting<bool>("autoplain")) {
+ autoplainRunnable()->transAsField(ce, r);
+ }
+ transAsRecordBody(ce, r);
+ em.sync();
+
+ return r;
+}
+
+bool block::returns() {
+ // Search for a returning runnable, starting at the end for efficiency.
+ for (list<runnable *>::reverse_iterator p=stms.rbegin();
+ p != stms.rend();
+ ++p)
+ if ((*p)->returns())
+ return true;
+ return false;
+}
+
+
+void dec::prettyprint(ostream &out, Int indent)
+{
+ prettyname(out, "dec", indent);
+}
+
+
+void modifierList::prettyprint(ostream &out, Int indent)
+{
+ prettyindent(out,indent);
+ out << "modifierList (";
+
+ for (list<modifier>::iterator p = mods.begin(); p != mods.end(); ++p) {
+ if (p != mods.begin())
+ out << ", ";
+ switch (*p) {
+ case EXPLICIT_STATIC:
+ out << "static";
+ break;
+#if 0
+ case EXPLICIT_DYNAMIC:
+ out << "dynamic";
+ break;
+#endif
+ default:
+ out << "invalid code";
+ }
+ }
+
+ for (list<permission>::iterator p = perms.begin(); p != perms.end(); ++p) {
+ if (p != perms.begin() || !mods.empty())
+ out << ", ";
+ switch (*p) {
+ case PUBLIC:
+ out << "public";
+ break;
+ case PRIVATE:
+ out << "private";
+ break;
+ default:
+ out << "invalid code";
+ }
+ }
+
+ out << ")\n";
+}
+
+bool modifierList::staticSet()
+{
+ return !mods.empty();
+}
+
+modifier modifierList::getModifier()
+{
+ if (mods.size() > 1) {
+ em.error(getPos());
+ em << "too many modifiers";
+ }
+
+ assert(staticSet());
+ return mods.front();
+}
+
+permission modifierList::getPermission()
+{
+ if (perms.size() > 1) {
+ em.error(getPos());
+ em << "too many modifiers";
+ }
+
+ return perms.empty() ? DEFAULT_PERM : perms.front();
+}
+
+
+void modifiedRunnable::prettyprint(ostream &out, Int indent)
+{
+ prettyname(out, "modifierRunnable",indent);
+
+ mods->prettyprint(out, indent+1);
+ body->prettyprint(out, indent+1);
+}
+
+void modifiedRunnable::transAsField(coenv &e, record *r)
+{
+ if (mods->staticSet()) {
+ if (e.c.isTopLevel()) {
+ em.warning(getPos());
+ em << "static modifier is meaningless at top level";
+ }
+ e.c.pushModifier(mods->getModifier());
+ }
+
+ permission p = mods->getPermission();
+#if 0 // This is innocuous
+ if (p != DEFAULT_PERM && (!r || !body->allowPermissions())) {
+ em.warning(pos);
+ em << "permission modifier is meaningless";
+ }
+#endif
+ e.c.setPermission(p);
+
+ body->transAsField(e,r);
+
+ e.c.clearPermission();
+ if (mods->staticSet())
+ e.c.popModifier();
+}
+
+
+void decidstart::prettyprint(ostream &out, Int indent)
+{
+ prettyindent(out, indent);
+ out << "decidstart '" << *id << "'\n";
+
+ if (dims)
+ dims->prettyprint(out, indent+1);
+}
+
+types::ty *decidstart::getType(types::ty *base, coenv &, bool)
+{
+ return dims ? dims->truetype(base) : base;
+}
+
+trans::tyEntry *decidstart::getTyEntry(trans::tyEntry *base, coenv &e,
+ record *where)
+{
+ return dims ? new trans::tyEntry(getType(base->t,e,false), 0,
+ where, getPos()) :
+ base;
+}
+
+void decidstart::addOps(types::ty *base, coenv &e, record *r)
+{
+ if (dims) {
+ e.e.addArrayOps(dims->truetype(base));
+ if (r)
+ r->e.addArrayOps(dims->truetype(base));
+ }
+}
+
+
+void fundecidstart::prettyprint(ostream &out, Int indent)
+{
+ prettyindent(out, indent);
+ out << "fundecidstart '" << *id << "'\n";
+
+ if (dims)
+ dims->prettyprint(out, indent+1);
+ if (params)
+ params->prettyprint(out, indent+1);
+}
+
+types::ty *fundecidstart::getType(types::ty *base, coenv &e, bool tacit)
+{
+ types::ty *result = decidstart::getType(base, e, tacit);
+
+ if (params) {
+ return params->getType(result, e, true, tacit);
+ }
+ else {
+ types::ty *t = new function(base);
+ return t;
+ }
+}
+
+trans::tyEntry *fundecidstart::getTyEntry(trans::tyEntry *base, coenv &e,
+ record *where)
+{
+ return new trans::tyEntry(getType(base->t,e,false), 0, where, getPos());
+}
+
+void fundecidstart::addOps(types::ty *base, coenv &e, record *r)
+{
+ decidstart::addOps(base, e, r);
+
+ params->addOps(e, r);
+
+ types::function *ft=dynamic_cast<types::function *>(getType(base, e, true));
+ assert(ft);
+
+ e.e.addFunctionOps(ft);
+ if (r)
+ r->e.addFunctionOps(ft);
+}
+
+
+void decid::prettyprint(ostream &out, Int indent)
+{
+ prettyname(out, "decid",indent);
+
+ start->prettyprint(out, indent+1);
+ if (init)
+ init->prettyprint(out, indent+1);
+}
+
+
+varEntry *makeVarEntryWhere(coenv &e, record *r, types::ty *t,
+ record *where, position pos)
+{
+ access *a = r ? r->allocField(e.c.isStatic()) :
+ e.c.allocLocal();
+
+ return r ? new varEntry(t, a, e.c.getPermission(), r, where, pos) :
+ new varEntry(t, a, where, pos);
+}
+
+varEntry *makeVarEntry(position pos, coenv &e, record *r, types::ty *t) {
+ return makeVarEntryWhere(e, r, t, r, pos);
+}
+
+
+// Defined in constructor.cc.
+bool definesImplicitConstructor(coenv &e, record *r, varEntry *v, symbol *id);
+void addConstructorFromInitializer(position pos, coenv &e, record *r,
+ varEntry *init);
+
+void addVar(coenv &e, record *r, varEntry *v, symbol *id)
+{
+ // Test for 'operator init' definitions that implicitly define constructors:
+ if (definesImplicitConstructor(e, r, v, id))
+ addConstructorFromInitializer(position(), e, r, v);
+
+ // Add to the record so it can be accessed when qualified; add to the
+ // environment so it can be accessed unqualified in the scope of the
+ // record definition.
+ if (r)
+ r->e.addVar(id, v);
+ e.e.addVar(id, v);
+}
+
+void initializeVar(position pos, coenv &e, varEntry *v, varinit *init)
+{
+ types::ty *t=v->getType();
+
+ if (init)
+ init->transToType(e, t);
+ else {
+ definit d(pos);
+ d.transToType(e, t);
+ }
+
+ v->getLocation()->encode(WRITE, pos, e.c);
+ e.c.encode(inst::pop);
+}
+
+void createVar(position pos, coenv &e, record *r,
+ symbol *id, types::ty *t, varinit *init)
+{
+ varEntry *v=makeVarEntry(pos, e, r, t);
+ addVar(e, r, v, id);
+ initializeVar(pos, e, v, init);
+}
+
+void createVarOutOfOrder(position pos, coenv &e, record *r,
+ symbol *id, types::ty *t, varinit *init)
+{
+ varEntry *v=makeVarEntry(pos, e, r, t);
+ initializeVar(pos, e, v, init);
+ addVar(e, r, v, id);
+}
+
+void addTypeWithPermission(coenv &e, record *r, tyEntry *base, symbol *id)
+{
+ // Only bother encoding permissions for private types.
+ tyEntry *ent = (r && e.c.getPermission()==PRIVATE) ?
+ new trans::tyEntry(base, PRIVATE, r) :
+ base;
+
+ if (r)
+ r->e.addType(id, ent);
+ e.e.addType(id, ent);
+}
+
+
+void decid::transAsField(coenv &e, record *r, types::ty *base)
+{
+ types::ty *t = start->getType(base, e);
+ assert(t);
+ if (t->kind == ty_void) {
+ em.error(getPos());
+ em << "cannot declare variable of type void";
+ }
+
+ start->addOps(base, e, r);
+
+ createVarOutOfOrder(getPos(), e, r, start->getName(), t, init);
+}
+
+void decid::transAsTypedefField(coenv &e, trans::tyEntry *base, record *r)
+{
+ trans::tyEntry *ent = start->getTyEntry(base, e, r);
+ assert(ent && ent->t);
+
+ if (init) {
+ em.error(getPos());
+ em << "type definition cannot have initializer";
+ }
+
+ start->addOps(base->t, e, r);
+
+ addTypeWithPermission(e, r, ent, start->getName());
+}
+
+
+void decidlist::prettyprint(ostream &out, Int indent)
+{
+ prettyname(out, "decidlist",indent);
+
+ for (list<decid *>::iterator p = decs.begin(); p != decs.end(); ++p)
+ (*p)->prettyprint(out, indent+1);
+}
+
+void decidlist::transAsField(coenv &e, record *r, types::ty *base)
+{
+ for (list<decid *>::iterator p = decs.begin(); p != decs.end(); ++p)
+ (*p)->transAsField(e, r, base);
+}
+
+void decidlist::transAsTypedefField(coenv &e, trans::tyEntry *base, record *r)
+{
+ for (list<decid *>::iterator p = decs.begin(); p != decs.end(); ++p)
+ (*p)->transAsTypedefField(e, base, r);
+}
+
+
+void vardec::prettyprint(ostream &out, Int indent)
+{
+ prettyname(out, "vardec",indent);
+
+ base->prettyprint(out, indent+1);
+ decs->prettyprint(out, indent+1);
+}
+
+void vardec::transAsTypedefField(coenv &e, record *r)
+{
+ base->addOps(e, r);
+ decs->transAsTypedefField(e, base->transAsTyEntry(e, r), r);
+}
+
+// Helper class for imports. This essentially evaluates to the run::loadModule
+// function. However, that function returns different types of records
+// depending on the filename given to it, so we cannot add it to the
+// environment. Instead, we explicitly tell it what types::record it is
+// returning for each use.
+class loadModuleExp : public exp {
+ record *imp;
+ function *ft;
+
+public:
+ loadModuleExp(position pos, record *imp)
+ : exp(pos), imp(imp), ft(new function(imp,primString())) {}
+
+ types::ty *trans(coenv &) {
+ em.compiler(getPos());
+ em << "trans called for loadModuleExp";
+ return primError();
+ }
+
+ void transCall(coenv &e, types::ty *t) {
+ assert(equivalent(t, ft));
+ e.c.encode(inst::builtin, run::loadModule);
+ }
+
+ types::ty *getType(coenv &) {
+ return ft;
+ }
+
+ exp *evaluate(coenv &, types::ty *) {
+ // Don't alias.
+ return this;
+ }
+};
+
+// Creates a local variable to hold the import and translate the accessing of
+// the import, but doesn't add the import to the environment.
+varEntry *accessModule(position pos, coenv &e, record *r, symbol *id)
+{
+ record *imp=e.e.getModule(id, (string)*id);
+ if (!imp) {
+ em.error(pos);
+ em << "could not load module '" << *id << "'";
+ em.sync();
+ return 0;
+ }
+ else {
+ // Create a varinit that evaluates to the module.
+ // This is effectively the expression "loadModule(filename)".
+ callExp init(pos, new loadModuleExp(pos, imp),
+ new stringExp(pos, *id));
+
+ // The varEntry should have whereDefined()==0 as it is not defined inside
+ // the record r.
+ varEntry *v=makeVarEntryWhere(e, r, imp, 0, pos);
+ initializeVar(pos, e, v, &init);
+ return v;
+ }
+}
+
+
+void idpair::prettyprint(ostream &out, Int indent)
+{
+ prettyindent(out, indent);
+ out << "idpair (" << "'" << *src << "' as " << *dest << ")\n";
+}
+
+void idpair::transAsAccess(coenv &e, record *r)
+{
+ checkValidity();
+
+ varEntry *v=accessModule(getPos(), e, r, src);
+ if (v)
+ addVar(e, r, v, dest);
+}
+
+void idpair::transAsUnravel(coenv &e, record *r,
+ protoenv &source, varEntry *qualifier)
+{
+ checkValidity();
+
+ if (r)
+ r->e.add(src, dest, source, qualifier, e.c);
+ if (!e.e.add(src, dest, source, qualifier, e.c)) {
+ em.error(getPos());
+ em << "no matching types or fields of name '" << *src << "'";
+ }
+}
+
+
+void idpairlist::prettyprint(ostream &out, Int indent)
+{
+ for (list<idpair *>::iterator p=base.begin();
+ p != base.end();
+ ++p)
+ (*p)->prettyprint(out, indent);
+}
+
+void idpairlist::transAsAccess(coenv &e, record *r)
+{
+ for (list<idpair *>::iterator p=base.begin();
+ p != base.end();
+ ++p)
+ (*p)->transAsAccess(e,r);
+}
+
+void idpairlist::transAsUnravel(coenv &e, record *r,
+ protoenv &source, varEntry *qualifier)
+{
+ for (list<idpair *>::iterator p=base.begin();
+ p != base.end();
+ ++p)
+ (*p)->transAsUnravel(e,r,source,qualifier);
+}
+
+idpairlist * const WILDCARD = 0;
+
+void accessdec::prettyprint(ostream &out, Int indent)
+{
+ prettyname(out, "accessdec", indent);
+ base->prettyprint(out, indent+1);
+}
+
+
+void fromdec::prettyprint(ostream &out, Int indent)
+{
+ prettyname(out, "fromdec", indent);
+ fields->prettyprint(out, indent+1);
+}
+
+void fromdec::transAsField(coenv &e, record *r)
+{
+ qualifier q=getQualifier(e,r);
+ if (q.t) {
+ if (fields==WILDCARD) {
+ if (r)
+ r->e.add(q.t->e, q.v, e.c);
+ e.e.add(q.t->e, q.v, e.c);
+ }
+ else
+ fields->transAsUnravel(e, r, q.t->e, q.v);
+ }
+}
+
+
+void unraveldec::prettyprint(ostream &out, Int indent)
+{
+ prettyname(out, "unraveldec", indent);
+ id->prettyprint(out, indent+1);
+ idpairlist *f=this->fields;
+ if(f) f->prettyprint(out, indent+1);
+}
+
+fromdec::qualifier unraveldec::getQualifier(coenv &e, record *)
+{
+ // getType is where errors in the qualifier are reported.
+ record *qt=dynamic_cast<record *>(id->getType(e, false));
+ if (!qt) {
+ em.error(getPos());
+ em << "qualifier is not a record";
+ }
+
+ return qualifier(qt,id->getVarEntry(e));
+}
+
+void fromaccessdec::prettyprint(ostream &out, Int indent)
+{
+ prettyindent(out, indent);
+ out << "fromaccessdec '" << *id << "'\n";
+ idpairlist *f=this->fields;
+ if(f) f->prettyprint(out, indent+1);
+}
+
+fromdec::qualifier fromaccessdec::getQualifier(coenv &e, record *r)
+{
+ varEntry *v=accessModule(getPos(), e, r, id);
+ if (v) {
+ record *qt=dynamic_cast<record *>(v->getType());
+ if (!qt) {
+ em.compiler(getPos());
+ em << "qualifier is not a record";
+ }
+ return qualifier(qt, v);
+ }
+ else
+ return qualifier(0,0);
+}
+
+void importdec::prettyprint(ostream &out, Int indent)
+{
+ prettyname(out, "importdec", indent);
+ base.prettyprint(out, indent+1);
+}
+
+void includedec::prettyprint(ostream &out, Int indent)
+{
+ prettyindent(out, indent);
+ out << "includedec ('" << filename << "')\n";
+}
+
+void includedec::loadFailed(coenv &)
+{
+ em.warning(getPos());
+ em << "could not parse file of name '" << filename << "'";
+ em.sync();
+}
+
+void includedec::transAsField(coenv &e, record *r)
+{
+ file *ast = parser::parseFile(filename,"Including");
+ em.sync();
+
+ // The runnables will be translated, one at a time, without any additional
+ // scoping.
+ ast->transAsField(e, r);
+}
+
+
+void typedec::prettyprint(ostream &out, Int indent)
+{
+ prettyname(out, "typedec",indent);
+
+ body->prettyprint(out, indent+1);
+}
+
+
+void recorddec::prettyprint(ostream &out, Int indent)
+{
+ prettyindent(out, indent);
+ out << "structdec '" << *id << "'\n";
+
+ body->prettyprint(out, indent+1);
+}
+
+void recorddec::transRecordInitializer(coenv &e, record *parent)
+{
+ position here=getPos();
+
+ // This is equivalent to the code
+ // A operator init() { return new A; };
+ // where A is the name of the record.
+ formals formals(here);
+ simpleName recordName(here, id);
+ nameTy result(here, &recordName);
+ newRecordExp exp(here, &result);
+ returnStm stm(here, &exp);
+ fundec init(here, &result, symbol::opTrans("init"), &formals, &stm);
+
+ init.transAsField(e, parent);
+}
+
+void recorddec::addPostRecordEnvironment(coenv &e, record *r, record *parent) {
+ if (parent)
+ parent->e.add(r->postdefenv, 0, e.c);
+ e.e.add(r->postdefenv, 0, e.c);
+}
+
+void recorddec::transAsField(coenv &e, record *parent)
+{
+ record *r = parent ? parent->newRecord(id, e.c.isStatic()) :
+ e.c.newRecord(id);
+
+ addTypeWithPermission(e, parent, new trans::tyEntry(r,0,parent,getPos()), id);
+ e.e.addRecordOps(r);
+ if (parent)
+ parent->e.addRecordOps(r);
+
+ // Start translating the initializer.
+ coder c=e.c.newRecordInit(r);
+ coenv re(c,e.e);
+
+ body->transAsRecordBody(re, r);
+
+ // After the record is translated, add a default initializer so that a
+ // variable of the type of the record is initialized to a new instance by
+ // default.
+ transRecordInitializer(e, parent);
+
+ // Add types and variables defined during the record that should be added to
+ // the enclosing environment. These are the implicit constructors defined by
+ // "operator init".
+ addPostRecordEnvironment(e, r, parent);
+}
+
+runnable *autoplainRunnable() {
+ // Abstract syntax for the code:
+ // private import plain;
+ position pos=position();
+ static importdec ap(pos, new idpair(pos, symbol::trans("plain")));
+ static modifiedRunnable mr(pos, trans::PRIVATE, &ap);
+
+ return &mr;
+}
+
+} // namespace absyntax
diff --git a/Build/source/utils/asymptote/dec.h b/Build/source/utils/asymptote/dec.h
new file mode 100644
index 00000000000..00198ff3353
--- /dev/null
+++ b/Build/source/utils/asymptote/dec.h
@@ -0,0 +1,633 @@
+/*****
+ * dec.h
+ * Andy Hammerlindl 2002/8/29
+ *
+ * Represents the abstract syntax tree for declatations in the language.
+ * Also included is abstract syntax for types as they are most often
+ * used with declarations.
+ *****/
+
+#ifndef DEC_H
+#define DEC_H
+
+#include "symbol.h"
+#include "absyn.h"
+#include "name.h"
+#include "varinit.h"
+#include "modifier.h"
+
+namespace trans {
+class coenv;
+class genv;
+class protoenv;
+class varEntry;
+class access;
+}
+
+namespace types {
+class ty;
+class formal;
+class signature;
+class function;
+}
+
+namespace vm {
+class lambda;
+}
+namespace absyntax {
+
+using trans::genv;
+using trans::coenv;
+using trans::protoenv;
+using trans::varEntry;
+using trans::access;
+using sym::symbol;
+
+class ty : public absyn {
+public:
+ ty(position pos)
+ : absyn(pos) {}
+
+ virtual void prettyprint(ostream &out, Int indent) = 0;
+
+ // If we introduced a new type, automatically add corresponding functions for
+ // that type.
+ virtual void addOps(coenv &, record *) {}
+
+ // Returns the internal representation of the type. This method can
+ // be called by exp::getType which does not report errors, so tacit is
+ // needed to silence errors in this case.
+ virtual types::ty *trans(coenv &e, bool tacit = false) = 0;
+
+ virtual trans::tyEntry *transAsTyEntry(coenv &e, record *where);
+};
+
+class nameTy : public ty {
+ name *id;
+
+public:
+ nameTy(position pos, name *id)
+ : ty(pos), id(id) {}
+
+ nameTy(name *id)
+ : ty(id->getPos()), id(id) {}
+
+ void prettyprint(ostream &out, Int indent);
+
+ types::ty *trans(coenv &e, bool tacit = false);
+ trans::tyEntry *transAsTyEntry(coenv &e, record *where);
+};
+
+class dimensions : public absyn {
+ size_t depth;
+public:
+ dimensions(position pos)
+ : absyn(pos), depth(1) {}
+
+ void prettyprint(ostream &out, Int indent);
+
+ void increase()
+ { depth++; }
+
+ size_t size() {
+ return depth;
+ }
+
+ types::array *truetype(types::ty *base);
+};
+
+class arrayTy : public ty {
+ ty *cell;
+ dimensions *dims;
+
+public:
+ arrayTy(position pos, ty *cell, dimensions *dims)
+ : ty(pos), cell(cell), dims(dims) {}
+
+ arrayTy(name *id, dimensions *dims)
+ : ty(dims->getPos()), cell(new nameTy(id)), dims(dims) {}
+
+ void prettyprint(ostream &out, Int indent);
+
+ void addOps(coenv &e, record *r);
+
+ types::ty *trans(coenv &e, bool tacit = false);
+};
+
+// Similar to varEntryExp, this helper class always translates to the same fixed
+// type.
+class tyEntryTy : public ty {
+ trans::tyEntry *ent;
+public:
+ tyEntryTy(position pos, trans::tyEntry *ent)
+ : ty(pos), ent(ent) {}
+
+ tyEntryTy(position pos, types::ty *t);
+
+ void prettyprint(ostream &out, Int indent);
+
+ types::ty *trans(coenv &e, bool tacit = false);
+ trans::tyEntry *transAsTyEntry(coenv &, record *) {
+ return ent;
+ }
+};
+
+// Runnable is anything that can be executed by the program, including
+// any declaration or statement.
+class runnable : public absyn {
+public:
+ runnable(position pos)
+ : absyn(pos) {}
+
+ virtual void prettyprint(ostream &out, Int indent) = 0;
+
+ void markTrans(coenv &e)
+ {
+ markPos(e);
+ trans(e);
+ }
+
+ /* Translates the stm or dec as if it were in a function definition. */
+ virtual void trans(coenv &e) {
+ transAsField(e, 0);
+ }
+
+ /* This can be overridden, to specify a special way of translating the code
+ * when it is run at the top of the interactive prompt.
+ */
+ virtual void interactiveTrans(coenv &e) {
+ trans(e);
+ }
+
+ void markTransAsField(coenv &e, record *r)
+ {
+ markPos(e);
+ transAsField(e,r);
+ }
+
+ /* Translate the runnable as in the lowest lexical scope of a record
+ * definition. If it is simply a statement, it will be added to the
+ * record's initializer. A declaration, however, will also have to
+ * add a new type or field to the record.
+ */
+ virtual void transAsField(coenv &e, record *) = 0;
+
+ virtual vm::lambda *transAsCodelet(coenv &e);
+
+ // For functions that return a value, we must guarantee that they end
+ // with a return statement. This checks for that condition.
+ virtual bool returns()
+ { return false; }
+
+ // Returns true if it is syntatically allowable to modify this
+ // runnable by a PUBLIC or PRIVATE modifier.
+ virtual bool allowPermissions()
+ { return false; }
+};
+
+class block : public runnable {
+public:
+ mem::list<runnable *> stms;
+
+ // If the runnables should be interpreted in their own scope.
+ bool scope;
+
+protected:
+ void prettystms(ostream &out, Int indent);
+
+public:
+ block(position pos, bool scope=true)
+ : runnable(pos), scope(scope) {}
+
+ // To ensure list deallocates properly.
+ virtual ~block() {}
+
+ void add(runnable *r) {
+ stms.push_back(r);
+ }
+
+ void prettyprint(ostream &out, Int indent);
+
+ void trans(coenv &e);
+
+ void transAsField(coenv &e, record *r);
+
+ void transAsRecordBody(coenv &e, record *r);
+
+ types::record *transAsFile(genv& ge, symbol *id);
+
+ // A block is guaranteed to return iff one of the runnables is guaranteed to
+ // return.
+ // This is conservative in that
+ //
+ // int f(int x)
+ // {
+ // if (x==1) return 0;
+ // if (x!=1) return 1;
+ // }
+ //
+ // is not guaranteed to return.
+ bool returns();
+};
+
+class modifierList : public absyn {
+ mem::list<trans::permission> perms;
+ mem::list<trans::modifier> mods;
+
+public:
+ modifierList(position pos)
+ : absyn(pos) {}
+
+ virtual ~modifierList()
+ {}
+
+ void prettyprint(ostream &out, Int indent);
+
+ void add(trans::permission p)
+ {
+ perms.push_back(p);
+ }
+
+ void add(trans::modifier m)
+ {
+ mods.push_back(m);
+ }
+
+ /* True if a static or dynamic modifier is present.
+ */
+ bool staticSet();
+
+ /* Says if the modifiers indicate static or dynamic. Prints error if
+ * there are duplicates.
+ */
+ trans::modifier getModifier();
+
+ /* Says if it is declared public, private, or read-only (default).
+ * Prints error if there are duplicates.
+ */
+ trans::permission getPermission();
+};
+
+// Modifiers of static or dynamic can change the way declarations and
+// statements are encoded.
+class modifiedRunnable : public runnable {
+ modifierList *mods;
+ runnable *body;
+
+public:
+ modifiedRunnable(position pos, modifierList *mods, runnable *body)
+ : runnable(pos), mods(mods), body(body) {}
+
+ modifiedRunnable(position pos, trans::permission perm, runnable *body)
+ : runnable(pos), mods(new modifierList(pos)), body(body) {
+ mods->add(perm);
+ }
+
+ void prettyprint(ostream &out, Int indent);
+
+ void transAsField(coenv &e, record *r);
+
+ bool returns()
+ { return body->returns(); }
+};
+
+
+class decidstart : public absyn {
+protected:
+ symbol *id;
+ dimensions *dims;
+
+public:
+ decidstart(position pos, symbol *id, dimensions *dims = 0)
+ : absyn(pos), id(id), dims(dims) {}
+
+ virtual void prettyprint(ostream &out, Int indent);
+
+ virtual types::ty *getType(types::ty *base, coenv &, bool = false);
+ virtual trans::tyEntry *getTyEntry(trans::tyEntry *base, coenv &e,
+ record *where);
+
+ // If a new type is formed by adding dimensions (or a function signature)
+ // after the id, this will add the standard functions for that new type.
+ virtual void addOps(types::ty *base, coenv &e, record *r);
+
+ virtual symbol *getName()
+ { return id; }
+};
+
+// Forward declaration.
+class formals;
+
+class fundecidstart : public decidstart {
+ formals *params;
+
+public:
+ fundecidstart(position pos,
+ symbol *id,
+ dimensions *dims = 0,
+ formals *params = 0)
+ : decidstart(pos, id, dims), params(params) {}
+
+ void prettyprint(ostream &out, Int indent);
+
+ types::ty *getType(types::ty *base, coenv &e, bool tacit = false);
+ trans::tyEntry *getTyEntry(trans::tyEntry *base, coenv &e, record *where);
+ void addOps(types::ty *base, coenv &e, record *r);
+};
+
+class decid : public absyn {
+ decidstart *start;
+ varinit *init;
+
+ // Returns the default initializer for the type.
+ access *defaultInit(coenv &e, types::ty *t);
+
+public:
+ decid(position pos, decidstart *start, varinit *init = 0)
+ : absyn(pos), start(start), init(init) {}
+
+ virtual void prettyprint(ostream &out, Int indent);
+
+ virtual void transAsField(coenv &e, record *r, types::ty *base);
+
+ // Translate, but add the names in as types rather than variables.
+ virtual void transAsTypedefField(coenv &e, trans::tyEntry *base, record *r);
+};
+
+class decidlist : public absyn {
+ mem::list<decid *> decs;
+
+public:
+ decidlist(position pos)
+ : absyn(pos) {}
+
+ virtual ~decidlist() {}
+
+ void add(decid *p) {
+ decs.push_back(p);
+ }
+
+ virtual void prettyprint(ostream &out, Int indent);
+
+ virtual void transAsField(coenv &e, record *r, types::ty *base);
+
+ // Translate, but add the names in as types rather than variables.
+ virtual void transAsTypedefField(coenv &e, trans::tyEntry *base, record *r);
+};
+
+class dec : public runnable {
+public:
+ dec(position pos)
+ : runnable(pos) {}
+
+ void prettyprint(ostream &out, Int indent);
+
+ // Declarations can be public or private.
+ bool allowPermissions()
+ { return true; }
+};
+
+void createVar(position pos, coenv &e, record *r,
+ symbol *id, types::ty *t, varinit *init);
+
+class vardec : public dec {
+ ty *base;
+ decidlist *decs;
+
+public:
+ vardec(position pos, ty *base, decidlist *decs)
+ : dec(pos), base(base), decs(decs) {}
+
+ vardec(position pos, ty *base, decid *di)
+ : dec(pos), base(base), decs(new decidlist(pos))
+ {
+ decs->add(di);
+ }
+ void prettyprint(ostream &out, Int indent);
+
+ void transAsField(coenv &e, record *r)
+ {
+ base->addOps(e, r);
+ decs->transAsField(e, r, base->trans(e));
+ }
+
+ // Translate, but add the names in as types rather than variables.
+ virtual void transAsTypedefField(coenv &e, record *r);
+};
+
+struct idpair : public absyn {
+ symbol *src; // The name of the module to access.
+ symbol *dest; // What to call it in the local environment.
+ bool valid; // If it parsed properly.
+
+ idpair(position pos, symbol *id)
+ : absyn(pos), src(id), dest(id), valid(true) {}
+
+ idpair(position pos, symbol *src, symbol *as, symbol *dest)
+ : absyn(pos), src(src), dest(dest), valid(as==symbol::trans("as")) {}
+
+ void checkValidity() {
+ if (!valid) {
+ em.error(getPos());
+ em << "expected 'as'";
+ }
+ }
+
+ void prettyprint(ostream &out, Int indent);
+
+ // Translates as: access src as dest;
+ void transAsAccess(coenv &e, record *r);
+
+ // Translates as: from _ unravel src as dest;
+ // where _ is the qualifier record with source as its fields and types.
+ void transAsUnravel(coenv &e, record *r,
+ protoenv &source, varEntry *qualifier);
+};
+
+struct idpairlist : public gc {
+ mem::list<idpair *> base;
+
+ void add(idpair *x) {
+ base.push_back(x);
+ }
+
+ void prettyprint(ostream &out, Int indent);
+
+ void transAsAccess(coenv &e, record *r);
+
+ void transAsUnravel(coenv &e, record *r,
+ protoenv &source, varEntry *qualifier);
+};
+
+extern idpairlist * const WILDCARD;
+
+
+class accessdec : public dec {
+ idpairlist *base;
+
+public:
+ accessdec(position pos, idpairlist *base)
+ : dec(pos), base(base) {}
+
+ void prettyprint(ostream &out, Int indent);
+
+ void transAsField(coenv &e, record *r) {
+ base->transAsAccess(e,r);
+ }
+};
+
+// Abstract base class for
+// from _ access _; (fromaccessdec)
+// and
+// from _ unravel _; (unraveldec)
+class fromdec : public dec {
+protected:
+ struct qualifier {
+ // The varEntry holds the location and the type of the highest framed
+ // structure that can be put on the stack. The record holds the actual type
+ // of the qualifier.
+ // For example:
+ // struct A {
+ // struct B {
+ // static int x;
+ // }
+ // }
+ // A a=new A;
+ // from a.B unravel x;
+ //
+ // Here, v->getType() will yield A and v->getLocation() will yield the
+ // location of the the variable a, but the record type t will be B.
+ record *t;
+ varEntry *v;
+
+ qualifier(record *t, varEntry *v)
+ : t(t), v(v) {}
+ };
+
+ // Return the qualifier from which the fields are taken. If t==0, it is
+ // assumed that an error occurred and was reported.
+ virtual qualifier getQualifier(coenv &e, record *r) = 0;
+ idpairlist *fields;
+
+public:
+ fromdec(position pos, idpairlist *fields)
+ : dec(pos), fields(fields) {}
+
+ void prettyprint(ostream &out, Int indent);
+
+ void transAsField(coenv &e, record *r);
+};
+
+// An unravel declaration dumps fields and types of a record into the local
+// scope.
+class unraveldec : public fromdec {
+ name *id;
+
+ qualifier getQualifier(coenv &e, record *);
+public:
+ unraveldec(position pos, name *id, idpairlist *fields)
+ : fromdec(pos, fields), id(id) {}
+
+ void prettyprint(ostream &out, Int indent);
+};
+
+// A fromaccess declaration dumps fields and types of a module into the local
+// scope. It does not add the module as a variable in the local scope.
+class fromaccessdec : public fromdec {
+ symbol *id;
+
+ qualifier getQualifier(coenv &e, record *r);
+public:
+ fromaccessdec(position pos, symbol *id, idpairlist *fields)
+ : fromdec(pos, fields), id(id) {}
+
+ void prettyprint(ostream &out, Int indent);
+};
+
+// An import declaration dumps fields and types of a module into the local
+// scope. It also adds the module as a variable in the local scope.
+class importdec : public dec {
+ block base;
+
+public:
+ importdec(position pos, idpair *id)
+ : dec(pos), base(pos, false) {
+ idpairlist *i=new idpairlist;
+ i->add(id);
+ base.add(new accessdec(pos, i));
+ base.add(new unraveldec(pos, new simpleName(pos, id->dest), WILDCARD));
+ }
+
+ void trans(coenv &e) {
+ base.trans(e);
+ }
+
+ void transAsField(coenv &e, record *r) {
+ base.transAsField(e, r);
+ }
+
+ void prettyprint(ostream &out, Int indent);
+};
+
+// Parses the file given, and translates the resulting runnables as if they
+// occurred at this place in the code.
+class includedec : public dec {
+ string filename;
+
+public:
+ includedec(position pos, string filename)
+ : dec(pos), filename(filename) {}
+ includedec(position pos, symbol *id)
+ : dec(pos), filename(*id) {}
+
+ void prettyprint(ostream &out, Int indent);
+ void loadFailed(coenv &e);
+
+ void transAsField(coenv &e, record *r);
+};
+
+// Types defined from others in typedef.
+class typedec : public dec {
+ vardec *body;
+
+public:
+ typedec(position pos, vardec *body)
+ : dec(pos), body(body) {}
+
+ void prettyprint(ostream &out, Int indent);
+
+ void transAsField(coenv &e, record *r) {
+ body->transAsTypedefField(e,r);
+ }
+};
+
+
+// A struct declaration.
+class recorddec : public dec {
+ symbol *id;
+ block *body;
+
+ void transRecordInitializer(coenv &e, record *parent);
+ void addPostRecordEnvironment(coenv &e, record *r, record *parent);
+
+public:
+ recorddec(position pos, symbol *id, block *body)
+ : dec(pos), id(id), body(body) {}
+
+ virtual ~recorddec()
+ {}
+
+ void prettyprint(ostream &out, Int indent);
+
+ void transAsField(coenv &e, record *parent);
+};
+
+// Returns a runnable that facilitates the autoplain feature.
+runnable *autoplainRunnable();
+
+void addVar(coenv &e, record *r, varEntry *v, symbol *id);
+
+} // namespace absyntax
+
+#endif
+
diff --git a/Build/source/utils/asymptote/doc/.cvsignore b/Build/source/utils/asymptote/doc/.cvsignore
new file mode 100644
index 00000000000..bd8d0a3caf6
--- /dev/null
+++ b/Build/source/utils/asymptote/doc/.cvsignore
@@ -0,0 +1,18 @@
+*.png
+*.jpg
+*.eps
+*.aux
+*.log
+*.dvi
+*.cp
+*.cps
+*.fn
+*.info
+*.ky
+*.pg
+*.toc
+*.tp
+*.vr
+asymptote
+latexusage.asy
+version.texi
diff --git a/Build/source/utils/asymptote/doc/Bode.asy b/Build/source/utils/asymptote/doc/Bode.asy
new file mode 100644
index 00000000000..a35540e9749
--- /dev/null
+++ b/Build/source/utils/asymptote/doc/Bode.asy
@@ -0,0 +1,27 @@
+import graph;
+texpreamble("\def\Arg{\mathop {\rm Arg}\nolimits}");
+
+size(10cm,5cm,IgnoreAspect);
+
+real ampl(real x) {return 2.5/(1+x^2);}
+real phas(real x) {return -atan(x)/pi;}
+
+scale(Log,Log);
+draw(graph(ampl,0.01,10));
+ylimits(0.001,100);
+
+xaxis("$\omega\tau_0$",BottomTop,LeftTicks);
+yaxis("$|G(\omega\tau_0)|$",Left,RightTicks);
+
+picture q=secondaryY(new void(picture pic) {
+ scale(pic,Log,Linear);
+ draw(pic,graph(pic,phas,0.01,10),red);
+ ylimits(pic,-1.0,1.5);
+ yaxis(pic,"$\Arg G/\pi$",Right,red,
+ LeftTicks("$% #.1f$",
+ begin=false,end=false));
+ yequals(pic,1,Dotted);
+ });
+label(q,"(1,0)",Scale(q,(1,0)),red);
+add(q);
+
diff --git a/Build/source/utils/asymptote/doc/CAD.tex b/Build/source/utils/asymptote/doc/CAD.tex
new file mode 100644
index 00000000000..270c528b85f
--- /dev/null
+++ b/Build/source/utils/asymptote/doc/CAD.tex
@@ -0,0 +1,256 @@
+\documentclass{ltxguide}
+\usepackage{graphicx}
+
+
+
+\begin{document}
+
+
+
+\title{Asymptote package CAD.asy\footnote{This document describes version 1.0.}}
+\author{Mark Henning, Germany\thanks{URL: http://www.markhenning.de}}
+\date{29 September 2006}
+\maketitle
+
+
+
+\tableofcontents
+
+
+
+\section{Introduction}
+
+The package {\tt CAD.asy} provides basic pen definitions and measurement functions for simple 2D CAD drawings according to DIN 15.
+
+
+
+\section{Important rules for using this package}
+
+If a function is declared like this:
+%
+\begin{verbatim}
+void foo(int nParam1, string strParam2)
+\end{verbatim}
+%
+You may call it \verb\foo(0, 'abc');\ or \verb\foo(nParam1=0, strParam2='abc');\. The definitions of the functions in this package may change in future version: the order of the parameters may be changed, new parameters may be inserted. Therefore it is \emph{strongly recommended} always calling the functions \verb\foo(nParam1=0, strParam2='abc');\.
+
+
+
+\section{Usage}
+
+To use the capabilities of the package, import it:
+%
+\begin{verbatim}
+import CAD;
+\end{verbatim}
+%
+All functions are encapsulated in the structure \verb\sCAD\. As the pen definitions may differ depending on the size of your drawing, you have to initialize the structure before drawing:
+
+\begin{verbatim}
+static sCAD Create(int nLineGroup = 1)
+\end{verbatim}
+%
+The parameter \verb\nLineGroup\ depends on the size of your drawing. It specifies the line group to define the pens and thus the width used for the lines. The parameter has to be within the range $[0;3]$. The larger the value, the thicker the lines. Code example:
+%
+\begin{quote}\begin{verbatim}
+sCAD cad = sCAD.Create();
+\end{verbatim}\end{quote}
+
+The created variable \verb\cad\ then provides the most important pens. Available pens are:
+%
+\begin{itemize}
+\item The pens of group A:
+ \begin{itemize}
+ \item\verb\pA\
+ \item\verb\pVisibleEdge\
+ \item\verb\pVisibleContour\
+ \item\verb\pUsableWindingLength\
+ \item\verb\pSystemLine\
+ \item\verb\pDiagramCurve\
+ \item\verb\pSurfaceStructure\
+ \end{itemize}
+\item The pens of group B:
+ \begin{itemize}
+ \item\verb\pB\
+ \item\verb\pLightEdge\
+ \item\verb\pMeasureLine\
+ \item\verb\pMeasureHelpLine\
+ \item\verb\pMeasureLineBound\
+ \item\verb\pReferenceLine\
+ \item\verb\pHatch\
+ \item\verb\pWindingGround\
+ \item\verb\pDiagonalCross\
+ \item\verb\pBendLine\
+ \item\verb\pProjectionLine\
+ \item\verb\pGrid\
+ \end{itemize}
+\item The pens of group C:
+ \begin{itemize}
+ \item\verb\pC\
+ \item\verb\pFreehand\
+ \end{itemize}
+\item The pens of group E:
+ \begin{itemize}
+ \item\verb\pE\
+ \item\verb\pSurfaceTreatmentAllowed\
+ \end{itemize}
+\item The pens of group F:
+ \begin{itemize}
+ \item\verb\pF\
+ \item\verb\pInvisibleEdge\
+ \item\verb\pInvisibleContour\
+ \end{itemize}
+\item The pens of group G:
+ \begin{itemize}
+ \item\verb\pG\
+ \item\verb\pMiddleLine\
+ \item\verb\pSymmetryLine\
+ \item\verb\pPartialCircle\
+ \item\verb\pCircularHole\
+ \item\verb\pDivisionPlane\
+ \item\verb\pTransferLine\
+ \end{itemize}
+\item The pens of group J:
+ \begin{itemize}
+ \item\verb\pJ\
+ \item\verb\pCuttingPlane\
+ \item\verb\pSurfaceTreatmentRequested\
+ \end{itemize}
+\item The pens of group K:
+ \begin{itemize}
+ \item\verb\pK\
+ \item\verb\pContourBeforeDeformation\
+ \item\verb\pAdjacentPartContour\
+ \item\verb\pEndShapeRawMaterial\
+ \item\verb\pContourEligibleType\
+ \item\verb\pPartInFrontOfCuttingPlane\
+ \end{itemize}
+\end{itemize}
+%
+All pens of one group are the same. So there is no difference between the pen \verb\pA\ and the pen \verb\pVisibleEdge\. You may use the short names or the descriptive ones. The list of groups is not complete. I had no idea how to implement the pens of group D. For me, group H seems to be obsolete, and there is no group I contained in DIN 15. In the case I did something wrong translating the German names into English, the source file also contains the original German names of each pen. Whenever a drawing function does not allow you to select the pen, the right pen is selected automatically.
+
+
+
+\begin{verbatim}
+void MeasureLine(picture pic = currentpicture,
+ Label L,
+ pair pFrom,
+ pair pTo,
+ real dblLeft = 0,
+ real dblRight = 0,
+ real dblRelPosition = 0.5,
+ bool bSmallBound = false)
+\end{verbatim}
+%
+This is the basic function to draw labeled straight measurement lines. \verb\pic\ denotes the picture the line has to be drawn into, \verb\L\ is the label of the line. The pairs \verb\pFrom\ and \verb\pTo\ are the start and the end point of the distance to measure, respectively. Note, that these two points do \emph{not} refer to the start and end point of the line, as it may be longer than the measured distance.
+
+The line is extended on its left side (= the part of the line 'before' the start point) by the distance \verb\dblLeft\. On its right side (= the part of the line 'behind' the end point) it is extended by the distance \verb\dblRight\. \verb\dblLeft\ and \verb\dblRight\ must be $\leq 0$. If only one of both values is zero, it is set to the value of the other one, because according to DIN 15 it is not allowed to draw a measurement line asymmetrically. The position of the arrows indicating begin and end of the distance depends on \verb\dblLeft\ and \verb\dblRight\. If both values are 0, the measurement arrows are drawn within the measurement distance. Otherwise they are drawn outside.
+
+The parameter \verb\dblRelPosition\ refers to the relative position of the label between the start and end point. This means: The value 0 positions the label at the start point, 0.5 refers to the center between the start and the end point. Finally, the value 1 will position the label at the end point. If \verb\dblLeft\ or \verb\dblRight\ are nonzero, you may position the label at the left side of the start point ($< 0$) or at the right side of the start point ($> 1$).
+
+Usually, there is enough space to draw the measurement arrows. If you wish to use small circles instead of the arrows, set \verb\bSmallBound\ to \verb\true\.
+
+
+
+\begin{verbatim}
+real GetMeasurementBoundSize(bool bSmallBound = false)
+\end{verbatim}
+%
+Returns the size of the arrow or the small bound circle used for measurement lines.
+
+
+
+\begin{verbatim}
+guide GetMeasurementBound(bool bSmallBound = false)
+\end{verbatim}
+%
+Returns the correctly scaled guide of the arrow or the small bound circle used for measurement lines.
+
+
+
+\begin{verbatim}
+void MeasureParallel(picture pic = currentpicture,
+ Label L,
+ pair pFrom,
+ pair pTo,
+ real dblDistance,
+ // Variables from MeasureLine
+ real dblLeft = 0,
+ real dblRight = 0,
+ real dblRelPosition = 0.5,
+ bool bSmallBound = false)
+\end{verbatim}
+%
+Usually, measurement lines are placed outside the drawing with reference lines to the measured distance. \verb\pFrom\ and \verb\pTo\ denote the points of the drawing marking the begin and the end of the distance to measure, and not the begin and the end of the measurement line as in the case of the function \verb\MeasureLine\. The measurement line is placed \verb\dblDistance\ away from the distance to measure. If you would be at \verb\pFrom\ and look into the direction \verb\pTo\, it is placed on the left for positive values of \verb\dblDistance\. For negative values, it is positioned on the right. For the meaning of the other parameters see the function \verb\MeasureLine\.
+
+
+
+\begin{verbatim}
+guide MakeFreehand(pair pFrom, pair pTo,
+ real dblRelDivisionLength = 12.5,
+ real dblRelDistortion = 2.5,
+ bool bIncludeTo = true)
+\end{verbatim}
+%
+To draw a line between two points, which is not straight, but more like a freehand line, use this function. The pairs \verb\pFrom\ and \verb\pTo\ denote start and end point, respectively. \verb\dblRelDivisionLength\ is the length of the parts, the line is subdivided into. \verb\dblRelDistortion\ is the amount of distortion. Both sizes are given relative to the width of a freehand line. If \verb\bIncludeTo\ is \verb\true\, the point \verb\pTo\ is added to the path. Otherwise it is not. This may be useful for converting a guide containing more than two points to a freehand line.
+
+
+
+\section{Example}
+
+\begin{figure}
+\includegraphics{CAD1}
+\caption{Example showing the measurement capabilities and a small freehand line.\label{fig:example1}}
+\end{figure}
+
+To produce figure \ref{fig:example1}, use this code:
+\begin{quote}
+\begin{verbatim}
+import CAD;
+
+sCAD cad = sCAD.Create();
+
+// Freehand line
+draw(g = cad.MakeFreehand(pFrom = (3, -1)*cm, (6, -1)*cm),
+ p = cad.pFreehand);
+
+// Standard measurement lines
+draw(g = box((0, 0)*cm, (1, 1)*cm), p = cad.pVisibleEdge);
+cad.MeasureParallel(L = "$\sqrt{2}$",
+ pFrom = (0, 1)*cm,
+ pTo = (1, 0)*cm,
+ dblDistance = -15mm);
+
+// Label inside, shifted to the right; arrows outside
+draw(g = box((2, 0)*cm, (3, 1)*cm), p = cad.pVisibleEdge);
+cad.MeasureParallel(L = "1",
+ pFrom = (2, 1)*cm,
+ pTo = (3, 1)*cm,
+ dblDistance = 5mm,
+ dblLeft = 5mm,
+ dblRelPosition = 0.75);
+
+// Label and arrows outside
+draw(g = box((5, 0)*cm, (5.5, 1)*cm), p = cad.pVisibleEdge);
+cad.MeasureParallel(L = "0.5",
+ pFrom = (5, 1)*cm,
+ pTo = (5.5, 1)*cm,
+ dblDistance = 5mm,
+ dblLeft = 10mm,
+ dblRelPosition = -1);
+
+// Small bounds, asymmetric measurement line
+draw(g = box((7, 0)*cm, (7.5, 1)*cm), p = cad.pVisibleEdge);
+cad.MeasureParallel(L = "0.5",
+ pFrom = (7, 1)*cm,
+ pTo = (7.5, 1)*cm,
+ dblDistance = 5mm,
+ dblLeft = 2*cad.GetMeasurementBoundSize(
+ bSmallBound = true),
+ dblRight = 10mm,
+ dblRelPosition = 2,
+ bSmallBound = true);
+\end{verbatim}
+\end{quote}
+
+\end{document}
diff --git a/Build/source/utils/asymptote/doc/CAD1.asy b/Build/source/utils/asymptote/doc/CAD1.asy
new file mode 100644
index 00000000000..4602e73b709
--- /dev/null
+++ b/Build/source/utils/asymptote/doc/CAD1.asy
@@ -0,0 +1,43 @@
+import CAD;
+
+sCAD cad=sCAD.Create();
+
+// Freehand line
+draw(g=cad.MakeFreehand(pFrom=(3,-1)*cm,(6,-1)*cm),
+ p=cad.pFreehand);
+
+// Standard measurement lines
+draw(g=box((0,0)*cm,(1,1)*cm),p=cad.pVisibleEdge);
+cad.MeasureParallel(L="$\sqrt{2}$",
+ pFrom=(0,1)*cm,
+ pTo=(1,0)*cm,
+ dblDistance=-15mm);
+
+// Label inside,shifted to the right; arrows outside
+draw(g=box((2,0)*cm,(3,1)*cm),p=cad.pVisibleEdge);
+cad.MeasureParallel(L="1",
+ pFrom=(2,1)*cm,
+ pTo=(3,1)*cm,
+ dblDistance=5mm,
+ dblLeft=5mm,
+ dblRelPosition=0.75);
+
+// Label and arrows outside
+draw(g=box((5,0)*cm,(5.5,1)*cm),p=cad.pVisibleEdge);
+cad.MeasureParallel(L="0.5",
+ pFrom=(5,1)*cm,
+ pTo=(5.5,1)*cm,
+ dblDistance=5mm,
+ dblLeft=10mm,
+ dblRelPosition=-1);
+
+// Small bounds,asymmetric measurement line
+draw(g=box((7,0)*cm,(7.5,1)*cm),p=cad.pVisibleEdge);
+cad.MeasureParallel(L="0.5",
+ pFrom=(7,1)*cm,
+ pTo=(7.5,1)*cm,
+ dblDistance=5mm,
+ dblLeft=2*cad.GetMeasurementBoundSize(bSmallBound=true),
+ dblRight=10mm,
+ dblRelPosition=2,
+ bSmallBound=true);
diff --git a/Build/source/utils/asymptote/doc/CDlabel.asy b/Build/source/utils/asymptote/doc/CDlabel.asy
new file mode 100644
index 00000000000..3dd59699e40
--- /dev/null
+++ b/Build/source/utils/asymptote/doc/CDlabel.asy
@@ -0,0 +1,14 @@
+size(11.7cm,11.7cm);
+asy(nativeformat(),"logo");
+fill(unitcircle^^(scale(2/11.7)*unitcircle),
+ evenodd+rgb(124/255,205/255,124/255));
+label(scale(1.1)*minipage(
+"\centering\scriptsize \textbf{\LARGE {\tt Asymptote}\\
+\smallskip
+\small The Vector Graphics Language}\\
+\smallskip
+\textsc{Andy Hammerlindl, John Bowman, and Tom Prince}
+http://asymptote.sourceforge.net\\
+",8cm),(0,0.6));
+label(graphic("logo."+nativeformat(),"height=7cm"),(0,-0.22));
+clip(unitcircle^^(scale(2/11.7)*unitcircle),evenodd);
diff --git a/Build/source/utils/asymptote/doc/FAQ/Makefile b/Build/source/utils/asymptote/doc/FAQ/Makefile
new file mode 100644
index 00000000000..c47394cbe7c
--- /dev/null
+++ b/Build/source/utils/asymptote/doc/FAQ/Makefile
@@ -0,0 +1,42 @@
+BFNNCONV = bfnnconv.pl m-ascii.pl m-html.pl m-info.pl m-lout.pl m-post.pl
+
+FAQ = asy-faq.html asy-faq.ascii asy-faq.info
+
+all: faq
+
+$(FAQ): $(BFNNCONV) asy-faq.bfnn
+ mkdir -p asy-faq.html
+ perl bfnnconv.pl asy-faq.bfnn
+ perl bfnnconv.pl asy-faq.bfnn
+
+faq: $(FAQ)
+
+clean: FORCE
+ -rm -f *~ core a.out *.lout *.ps *.info *.ascii *.xrefdb *.post
+ -rm -rf *.html
+
+install-all: install install-info
+
+install: faq
+ ${INSTALL} -d -m 755 $(docdir) $(docdir)/asy-faq.html
+ ${INSTALL} -p -m 644 asy-faq.ascii $(docdir)
+ ${INSTALL} -p -m 644 asy-faq.html/* $(docdir)/asy-faq.html
+
+install-info: faq
+ ${INSTALL} -d -m 755 $(infodir)
+ ${INSTALL} -p -m 644 asy-faq.info $(infodir)
+ -if test -z "$(DESTDIR)"; then \
+ install-info --infodir=$(infodir) asy-faq.info; \
+ fi
+
+uninstall: uninstall-all
+
+uninstall-all:
+ -cd $(docdir)/asy-faq.html; rm -rf *.html
+ -cd $(docdir); rmdir asy-faq.html; rm asy-faq.ascii
+ -install-info --remove --infodir=$(infodir) asy-faq.info
+ -rm -f $(infodir)/asy-faq.info
+
+distclean: FORCE clean
+
+FORCE:
diff --git a/Build/source/utils/asymptote/doc/FAQ/asy-faq.bfnn b/Build/source/utils/asymptote/doc/FAQ/asy-faq.bfnn
new file mode 100644
index 00000000000..a3095732cfd
--- /dev/null
+++ b/Build/source/utils/asymptote/doc/FAQ/asy-faq.bfnn
@@ -0,0 +1,1285 @@
+\comment This is the source for the Asymptote FAQ list, in
+\comment the Bizarre Format With No Name. It is turned into Lout
+\comment input, HTML, plain ASCII and an Info document by a Perl script.
+\comment
+\comment The format and scripts come from the Linux FAQ, by
+\comment Ian Jackson.
+\set brieftitle Asymptote FAQ
+\set author <A href="http://asymptote.sourceforge.net">Asymptote</A>
+\set title Asymptote Frequently Asked Questions
+\copyto ASCII
+ ASYMPTOTE FREQUENTLY ASKED QUESTIONS
+ `date '+%d %h %Y'`
+
+\endcopy
+\copyto INFO
+START-INFO-DIR-ENTRY
+* asymptote FAQ: (asy-faq). Asymptote Frequently Asked Questions.
+END-INFO-DIR-ENTRY
+
+
+File: $prefix.info, Node: Top, Next: Question 1.1, Up: (dir)
+
+ ASYMPTOTE FREQUENTLY ASKED QUESTIONS
+ `date '+%d %h %Y'`
+
+\endcopy
+
+This is the list of Frequently Asked Questions about Asymptote (asy).
+
+\section Index
+
+\index
+
+\comment ######################################################################
+
+\section About Asymptote
+
+\question 26jun:whatisasy What is Asymptote?
+
+Asymptote is a vector graphics language designed for
+technical graphics, inspired by MetaPost but with IEEE floating-point numerics,
+native three-dimensional graphics, Grayscale/RGB/CMYK colourspaces, and a
+C++-like syntax. Unlike MetaPost, it natively supports multiple-segment paths
+(and hence regions other than simply connected ones), tiling patterns, Gouraud
+ shading, tensor patch shading, and PostScript images.
+
+\question 22jun:whereisasy How do I obtain Asymptote?
+
+Binary releases are available for Linux, MacOS X, and Microsoft Windows
+platforms, in addition to full source code, from the website
+\docref{http://asymptote.sourceforge.net/\}. Many Linux distributions
+(such as RedHat and Debian) now include an Asymptote package (check your
+distribution's documentation for further information about this).
+
+\question 28jun:beforeasking Where can I ask questions about Asymptote?
+
+If you have a question, please try to find an answer in this FAQ, in the
+extensive Asymptote documentation at
+\docref{http://asymptote.sourceforge.net/doc/\}, or search the forum:
+\docref{http://sourceforge.net/forum/forum.php?forum_id=409349\}.
+
+\question 02sep:whyasy Why was the name Asymptote chosen?
+
+Well, it isn't the perfect graphics package, but we do think it is getting there
+asymptotically...
+
+\question 02sep:whycamp In the internal Asymptote source code, what does the name \courier{camp\} refer to?
+
+That was our original tentative name for this project, which stood for
+"C's Answer to MetaPost" (the language that inspired Asymptote).
+However, we eventually decided that the name \courier{Asymptote\} better
+emphasizes the mathematical and graphical nature of this language.
+
+\comment ######################################################################
+
+\section Questions about installation and setup
+
+\question 26jun:osx Is it possible to install Asymptote on Mac OS X?
+
+It is easy to compile Asymptote directly from the source code at
+\docref{http://sourceforge.net/project/showfiles.php?group_id=120000\}
+We recommend first upgrading to the latest GNU readline library, unless you
+don't care about interactive readline support (in which case configure will
+automatically detect and disable obsolete versions of the readline library).
+Marius Schamschula also maintains a binary package for various MacOS X
+platforms
+\docref{http://www.hmug.org/pub/MacOS_X/X/Applications/Publishing/asymptote\}.
+
+\question 26jun:osxbadCPU Why do I get the error \courier{Bad CPU type in executable\} on installing Asymptote from the MAC OS binary?
+
+This means either that you have a binary distribution for another MAC
+architecture, or (according to Marius Schamschula) that you may have a missing
+library. The simplest solution is to compile Asymptote directly from the
+official source:
+\docref{http://sourceforge.net/project/showfiles.php?group_id=120000\}.
+
+\question 04nov:brokenpdftex What do I do if I get the error: \courier{Error: pdfetex (file pdftex.cfg): cannot open config file...texinfo.tex appears to be broken\}?
+
+Simply put \docref{http://asymptote.sourceforge.net/asymptote.pdf\}
+in the directory \courier{doc\} and repeat the command \courier{make all\}.
+Or, if you don't want to build a local copy of the documentation, simply
+proceed with \courier{make install-asy\}.
+
+\question 04nov:brokentexinfo What do I do if I get the error: \courier{! Undefined control sequence. l.6 @copying\}?
+
+Either upgrade your \courier{texinfo\} package or follow one of the easy work arounds in \qref brokenpdftex.
+
+\question 27jun:latexintegration Is it possible to integrate Asymptote into LaTeX?
+
+Yes, see the example latexusage.tex. Dario Teixeira has also written a detailed
+guide on the topic. You can download it from
+\docref{http://dario.dse.nl/projects/asylatex/\}.
+
+Philippe Ivaldi has contributed an Asymptote mode for Emacs users
+\docref{http://asymptote.sourceforge.net/doc/Editing-modes.html\},
+which includes a \courier{lasy-mode\} that allows one to compile and view
+the output of one \\begin{asy}...\\end{asy} section at a time.
+
+\question 02sep:pdflatex Is it possible to integrate Asymptote into latex or pdflatex?
+
+Yes, as of version 1.14, Asymptote supports latex and pdflatex (both in
+EPS/PDF and inline mode), as illustrated by the example
+\courier{latexusage.tex\}:
+
+\verbatim
+pdflatex latexusage
+asy latexusage
+pdflatex latexusage
+\endverbatim
+
+\question 02sep:tkinterdepend Do I need the \courier{tkinter\} package to install an Asymptote rpm binary?
+
+No, you don't need \courier{tkinter\} unless you want to try out the GUI \courier{xasy\}. Try
+
+\verbatim
+rpm -Uvh --nodeps asymptote-x.xx-1.i386.rpm
+\endverbatim
+
+where \courier{x.xx\} represents the version number.
+
+\question 26jun:windir What does the path \courier{%USERPROFILE%\\.asy\\config.asy\} mean?
+
+That is the way that Microsoft Windows refers to the user profile directory.
+There's nothing really to understand here, just put your configuration
+commands in the file \courier{config.asy\} in a new folder \courier{%USERPROFILE%\\.asy\}.
+
+\question 25dec:escapechar Why do I get the error "string not terminated" when I try to set \courier{settings.dir="C:\\asymptote\\";\}?
+
+The backslash is an escape character here, so
+\courier{\\"\} is interpreted as a verbatim quotation mark, leaving the string
+without a terminating quotation mark. Fortunately, this is the
+only escaped character in double-quoted strings. A final backslash isn't
+needed here anyway, but should you really want one somewhere, you can say:
+\courier{settings.dir="C:\\asymptote"+'\\\\';\}.
+
+\question 27jun:winglobal How do I change environment variables in Microsoft Windows, for example, in order to change the default PostScript viewer?
+
+While it is easier to set the corresponding Asymptote configuration
+variable in your \courier{config.asy\} file, here is the procedure for changing
+Microsoft Windows environment variables:
+
+Click on the [Start] button
+
+* RIGHT-click on 'My Computer'
+
+* Choose 'Properties' from the popup menu
+
+* Click the 'Advanced' tab
+
+* Click the 'Environment Variables' button.
+
+\question 02sep:convert Under Microsoft Windows XP, why do I get an error like "Invalid Parameter - 432x432"?
+
+This means that ImageMagick wasn't properly installed and you are using the
+MSDOS convert program rather than the ImageMagick one. Or you may have
+installed ImageMagick but ran Asymptote from an existing MSDOS window.
+In that case, simply open a new window and try again. If that doesn't work,
+check that
+
+\verbatim
+convert --version
+\endverbatim
+
+returns something like
+
+\verbatim
+Version: ImageMagick 6.2.8 06/27/06 Q16 http://www.imagemagick.org
+\endverbatim
+
+\question 26jun:miktex Why does Asymptote freeze upon trying to draw a label with my MikTex installation under Microsoft Windows?
+
+Likely, this means that latex and dvips are not in your default path.
+Try adding the appropriate paths in your \courier{config.asy\} file,
+for example:
+
+\verbatim
+import settings;
+latex="C:\Program Files\MiKTeX 2.7\miktex\bin\latex.exe";
+dvips="C:\Program Files\MiKTeX 2.7\miktex\bin\dvips.exe";
+\endverbatim
+
+\comment #####################################################################
+
+\section Questions about paths
+
+\question 02sep:tensionsyntax Why do I get a syntax error message when I specify an integer value for the path tension?
+
+What is happening here is that
+
+\verbatim
+draw((0,0)..tension 2..(0,50)..(100,100));
+\endverbatim
+
+is read as
+
+\verbatim
+draw((0,0)..tension 2. .(0,50)..(100,100));
+\endverbatim
+
+So the first . after the two is treated as a decimal point.
+Just put a space after the integer tension value:
+
+\verbatim
+draw((0,0)..tension 2 ..(0,50)..(100,100));
+\endverbatim
+
+\question 27jun:dots Shouldn't dots always be the same size?
+
+From the documentation:
+
+"The dot command defined in the module plain draws a dot having a diameter
+equal to an explicit pen linewidth or the default linewidth magnified by
+dotfactor (6 by default)."
+
+Thus, when you use the default pen, the dot will have size 6*linewidth,
+but when you give a pen with an explicit width specified, you will
+have a dot of size linewidth. If you want the first case to behave like the
+second, you may set dotfactor=1.
+
+\comment #####################################################################
+
+\section Questions about labels
+
+\question 02sep:greek How do I get Greek letters like omega to show up in my labels?
+
+In (La)TeX, Greek letters can be obtained in math mode by prepending a
+backslash to the letter name. So for a omega symbol, use "$\\omega$". Everything
+between the dollar signs is considered to be a math formula. Uppercase Greek
+letters can be used by capitalizing the first letter of the name:
+
+\verbatim
+label("$\omega$",(0,0));
+label("$\Omega$",(20,0));
+\endverbatim
+
+\question 29jun:matlabels Can Asymptote use matrices as labels?
+
+Yes:
+\verbatim
+usepackage("amsmath");
+label("$\begin{matrix} 1 & 2 \\\ 1 & 1 \end{matrix}$",(0,0));
+\endverbatim
+
+\question 27jun:latexpackage How do I tell Asymptote to load a particular LaTeX package, like \courier{mathptmx\}?
+
+Put
+
+\verbatim
+usepackage("mathptmx");
+\endverbatim
+
+at the beginning of your file. Note: to enable the Adobe Times Roman font
+for text, you will also need to say:
+\verbatim
+defaultpen(TimesRoman());
+\endverbatim
+
+
+\question 28jun:internatfonts How can I use international fonts in Asymptote labels?
+
+See \docref{http://asymptote.sourceforge.net/doc/unicode.html\}.
+
+\question 10jul:Fourier How can I use Fourier fonts?
+
+\verbatim
+usepackage("fourier");
+defaultpen(font("T1","fut\textfamilyextension","m","n"));
+\endverbatim
+
+\question 26jun:decsep Is there any way to change the default appearance of the decimal separator, using a comma instead of a dot?
+
+Just set your locale appropriately:
+
+\verbatim
+locale("it_IT");
+usepackage("icomma");
+label(format(0.5));
+\endverbatim
+
+\question 02sep:rotatelabel How can I get a rotated label with the filled box rotated as well so that it fits the text?
+
+\verbatim
+frame f;
+label(f,"This is some text",white,Fill(blue));
+add(rotate(65)*f);
+\endverbatim
+
+
+\question 02sep:rotatelabel3D How can I rotate labels in a 3D figure?
+
+You need to first project the triple to a pair like this:
+
+\verbatim
+import three;
+size(100,100);
+
+draw(rotate(90,project(Z))*"A",O--X);
+\endverbatim
+
+\question 02sep:fixedsize How can I draw some squares and circles of a fixed size and put a label in the middle of them?
+
+Fixed-size objects should be drawn on a separate picture and then added to
+currentpicture. Here is one way (see also \docref{http://asymptote.sourceforge.net/gallery/subpictures.asy\} and \docref{http://asymptote.sourceforge.net/gallery/mosquito.asy\}):
+
+\verbatim
+real u=2cm;
+
+picture square;
+draw(square,scale(u)*shift(-0.5,-0.5)*unitsquare);
+
+picture circle;
+draw(circle,scale(0.5u)*unitcircle);
+
+void add(picture pic=currentpicture, Label L, picture object, pair z) {
+add(pic,object,z);
+label(pic,L,z);
+}
+
+add("square",square,(0,0));
+add("circle",circle,(5cm,0));
+\endverbatim
+
+\question 27jun:colorssaturation The binary operator * can be used to scale the color of a pen by a real number. Does this scaling factor have to be less than 1?
+
+The scaling factor can be greater than 1. But keep in mind that the rgb color
+components saturate at 1.
+
+Try
+\verbatim
+write(cyan); write(0.8*cyan); write(1.5*cyan);
+\endverbatim
+and you will quickly see what is going on.
+
+To get a lighter cyan you can say white+cyan,
+which yields rgb(0.5,1,1). If you want something even lighter specify the
+rgb colors directly,
+for example, rgb(0.9,1,1).
+
+Alternatively, work in cmyk colour space, which is nicer in that it handles
+saturation separately from hue:
+
+0.1*Cyan is light and 0.9*Cyan is dark.
+You can also say 0.1*cmyk(red).
+
+\question 05mar:commadecimalseparator Why is the space after the comma decimal separator in my locale so large?
+
+LaTeX is treating the comma as punctuation and not as a decimal separator.
+The solution is to load the \courier{icomma\} package near the beginning of your file:
+\verbatim
+usepackage("icomma");
+\endverbatim
+
+\question 11mar:hyperref How can I prevent \courier{texpreamble("\\usepackage[pdftex]{hyperref}")\} from changing the page size?
+
+\verbatim
+texpreamble("\usepackage[pdftex,setpagesize=false]{hyperref}");
+\endverbatim
+
+\comment #####################################################################
+
+\section Questions about arrows
+
+\question 02sep:doublearrows How do I draw two arrows at arbitrary positions along a path?
+
+Assuming that at least one of the arrowheads is to be filled, you can do this:
+
+\verbatim
+size(200);
+path g = (0,0)..(1,3)..(3,0);
+draw(g,Arrow(Relative(0.9)));
+add(arrow(g,invisible,FillDraw(black),Relative(0.5)));
+add(arrow(reverse(g),invisible,FillDraw(white,black),Relative(0.9)));
+\endverbatim
+
+If both of the arrowheads are to be drawn with filltype NoFill,
+one will need to create a specialized version of the arrow routine in
+\courier{plain_arrows.asy\}:
+
+\verbatim
+void arrow(frame f, arrowhead arrowhead=DefaultHead,
+ path g, pen p=currentpen, real size=0,
+ real angle=arrowangle, filltype filltype=arrowhead.defaultfilltype,
+ position position=EndPoint, bool forwards=true,
+ margin margin=NoMargin, bool center=false);
+\endverbatim
+
+\question 02sep:reversearrow How do I reverse the direction of an arrowhead?
+
+Simply reverse the direction of the path.
+
+\verbatim
+path g=((0,0)--(5cm,0));
+draw(reverse(g),Arrow(Relative(0.55)));
+\endverbatim
+
+\question 02sep:reversearrow How do I change the size of all arrows?
+
+To override the arrowsize you can give every Arrow drawing attribute a real
+size argument. If you want to do this globally, you can override the
+pen-dependent arrowsize function like this:
+
+\verbatim
+arrowsize=new real(pen p=currentpen) {return 2mm;};
+\endverbatim
+
+\question 26jun:arrowhead Can I create other arrowhead styles?
+
+Yes, you can build custom arrowheads like this (see the predefined
+arrowhead styles in \courier{plain_arrows.asy\} for further examples):
+
+\verbatim
+arrowhead DotHead;
+DotHead.head=new path(path g, position position=EndPoint, pen p=currentpen,
+ real size=0, real angle=arrowangle) {
+ if(size == 0) size=DotHead.size(p);
+ bool relative=position.relative;
+ real position=position.position.x;
+ if(relative) position=reltime(g,position);
+ path r=subpath(g,position,0);
+ pair x=point(r,0);
+ real t=arctime(r,size);
+ pair y=point(r,t);
+ return circle(0.5(x+y),0.5size);
+};
+
+size(100);
+draw((0,0)..(1,1)..(2,0),Arrow(DotHead));
+dot((2,0),red);
+\endverbatim
+
+If you submit your alternate arrowheads to the Forum or the Patch
+Tracking System, we'll consider including them in a future release.
+
+\comment #####################################################################
+
+\section Questions about 2D graphs
+
+\question 02sep:axisticks How can I draw x axis ticks on the right side, with the tick labels on the left side (relative to the axis path)?
+
+\verbatim
+import graph;
+
+size(250,200,IgnoreAspect);
+
+draw(graph(exp,-1,1),red);
+
+xaxis("$x$",RightTicks(Label(align=left)));
+yaxis("$y$",RightTicks);
+\endverbatim
+
+\question 02sep:axislabel How can I reposition the x axis label to three-quarters along the axis length?
+
+\verbatim
+import graph;
+
+size(250,200,IgnoreAspect);
+
+draw(graph(exp,-1,1),red);
+
+xaxis(Label("$x$",0.75),LeftTicks);
+yaxis("$y$",RightTicks);
+\endverbatim
+
+\question 02sep:axislabeldown How can I move the x axis label down 10bp?
+
+\verbatim
+import graph;
+size(250,200,IgnoreAspect);
+
+draw(graph(exp,-1,1),red);
+
+xaxis(shift(0,-10)*"$x$",LeftTicks);
+yaxis("$y$",RightTicks);
+\endverbatim
+
+\question 02sep:threeaxispens Can I use different pens for the axis, the axis label, and the tick labels?
+
+Yes:
+
+\verbatim
+import graph;
+size(300,200,IgnoreAspect);
+
+xlimits(-50,50);
+ylimits(0,100);
+
+xaxis(Label("$x$",MidPoint,red),Bottom,blue,LeftTicks(green));
+yaxis("$y$",Left,RightTicks);
+\endverbatim
+
+\question 02sep:axislabelfont How can I change the font type of the axes label?
+
+\verbatim
+import graph;
+size(300,200,IgnoreAspect);
+
+xlimits(-50,50);
+ylimits(0,100);
+
+xaxis("x",Bottom,Courier("m","n"),LeftTicks);
+yaxis("$y$",Left,RightTicks);
+\endverbatim
+
+\question 02sep:axisticklabelfont How can I change the font type of the tick labels on an axis?
+
+Tick labels are by default typeset in (TeX) math mode, so to use other
+fonts you need to override the default tick format:
+
+\verbatim
+import graph;
+size(300,200,IgnoreAspect);
+
+xlimits(-50,50);
+ylimits(0,100);
+
+xaxis("$x$",Bottom,LeftTicks("%.4g",Courier("m","n")+fontsize(12)));
+yaxis("$y$",Left,RightTicks);
+\endverbatim
+
+\question 26jun:overlappingticklabels How can I prevent axes tick labels from rendering on top of each other?
+
+Either:
+
+(i) give LeftTicks/RightTicks/Ticks the arguments beginlabel=false
+and/or endlabel=false;
+
+(ii) explicitly remove specific ticks and their labels (drawing them manually;
+see \docref{http://asymptote.svn.sourceforge.net/viewvc/asymptote/trunk/asymptote/base/graph.asy\} for the definition of NoZero):
+
+\verbatim
+import graph;
+
+size(10cm);
+
+real f(real x) {return x^2;}
+
+draw(graph(f,-2,2));
+
+xaxis(Ticks(NoZero));
+yaxis(Ticks(NoZero));
+
+label("$0$",(0,0),SW);
+\endverbatim
+
+(iii) explicitly remove specific tick labels and draw them manually
+(see \docref{http://asymptote.svn.sourceforge.net/viewvc/asymptote/trunk/asymptote/base/graph.asy\} for the definition of NoZeroFormat):
+
+\verbatim
+import graph;
+
+size(10cm);
+
+real f(real x) {return x^2;}
+
+draw(graph(f,-2,2));
+
+xaxis(Ticks(NoZeroFormat));
+yaxis(Ticks(NoZeroFormat));
+
+label("$0$",(0,0),SW);
+\endverbatim
+
+(iv) use the xasy GUI to move overlapping labels;
+
+(v) change the Label argument of LeftTicks, RightTicks, or Ticks to:
+
+\verbatim
+Label(currentpen+overwrite(Move))
+\endverbatim
+
+Solution (v) will move labels that might otherwise overwrite a previous
+label. Other possible overwrite arguments are Allow (allows overlapping
+labels; the default), Suppress (an overlapping label will not be written at
+all), SuppressQuiet, and MoveQuiet. The last two achieve the same result as
+the non-quiet types, but will not notify you which labels are overlapping. See:
+\docref{http://asymptote.sourceforge.net/doc/Pens.html\}.
+
+In the case of a user-specified tick array, you can change which labels get
+suppressed/moved by changing the order of array entries.
+
+\question 04nov:fixedsizegraphs How do I make the plot region of a graph, ignoring labels and legends, have a fixed size?
+
+Either:
+
+i) Specify an explicit unitsize, which overrides any call to \courier{size\}:
+\verbatim
+unitsize(x=1cm,y=2cm);
+\endverbatim
+
+ii) Explicitly tell Asymptote to map the plot region to a specific size:
+\verbatim
+import graph;
+real[] x={0,1,2,3};
+real[] y=x^2;
+draw(graph(x,y),red);
+xaxis("$x$",BottomTop,LeftTicks);
+yaxis("$y$",LeftRight,RightTicks);
+
+size(5cm,5cm,point(SW),point(NE));
+
+label("$f_\mathrm{T}$",point(N),2N);
+\endverbatim
+
+iii) Specify the points in user coordinates that should correspond to a
+given picture size:
+
+\verbatim
+import graph;
+
+size(250,200,IgnoreAspect);
+
+draw(graph(exp,-1,1),red);
+
+xaxis("$x$",BottomTop,LeftTicks);
+yaxis("$y$",LeftRight,RightTicks);
+
+fixedscaling((-1.5,-0.5),(1.5,3.5));
+\endverbatim
+
+In this example, the user coordinate \courier{(-1.5,-0.5)\} will end up
+being the lower left corner of the figure and \courier{(1.5,3.5)\} will be
+the upper right corner. You can use this option to ensure multiple figures
+have the same scaling and same resulting figure size (just ensure the two
+coordinates given to \courier{fixedscaling()\} leaves room for any labels).
+
+See also
+\docref{http://asymptote.sourceforge.net/doc/Frames-and-pictures.html\}.
+
+\question 26jun:graphlimits How can I plot a function f(x) within [0,1]x[0,2] without explicitly calculating the x values for which f(x) hits the boundary?
+
+Call \courier{limits\} with the \courier{Crop\} option before drawing the graph:
+\verbatim
+import graph;
+
+size(250,200,IgnoreAspect);
+
+draw(graph(exp,-1,1),red);
+
+limits((0,0),(1,2),Crop);
+
+xaxis("$x$",BottomTop,LeftTicks);
+yaxis("$y$",LeftRight,RightTicks);
+\endverbatim
+
+See also \docref{http://asymptote.sourceforge.net/doc/graph.html\}.
+
+\question 26jun:custompalettes Is it possible to define customized palettes?
+
+Yes, you may generate your own pen[] array. For example:
+
+\verbatim
+int NColors=32768;
+pen[] MyPalette=new pen[NColors];
+real step=1/(NColors-1.0);
+// Start at black: rgb(0,0,0)
+// End at yellow: rgb(1,1,0)
+for(int i=0; i < NColors; ++i) {
+ real rgval=i*step;
+ MyPalette[i]=rgb(rgval,rgval,0.0);
+}
+\endverbatim
+
+\question 26jun:factorial Is there an easy way to graph factorial functions nicely?
+
+The example below shows a continuous function and two methods for placing
+markers at integer values of x:
+
+\verbatim
+import graph;
+
+size(200,200,IgnoreAspect);
+
+real factorial(real t) {return gamma(t+1);}
+
+scale(Linear,Log);
+
+// Graph the factorial function.
+draw(graph(factorial,0,10));
+
+// Method 1: Draw nodes, but hide line
+pair F(int t) {return (t,factorial(t));}
+// Graph of factorial function from 0 to 10
+pair[] z=sequence(F,11);
+draw(graph(z),invisible,marker(scale(0.8mm)*unitcircle,blue,Fill));
+
+// Method 2: Nongraphing routines require explicit scaling:
+pair dotloc(int t) {return Scale(F(t));}
+pair[] dotlocs=sequence(dotloc,11);
+dot(dotlocs);
+
+xaxis("$x$",BottomTop,LeftTicks);
+yaxis("$y$",LeftRight,RightTicks);
+\endverbatim
+
+\question 26jun:length How do I indicate that a certain length should be exactly the size I prescribe with no rescaling, within a picture which has its own size?
+
+Here's an easy way to do this.
+
+\verbatim
+size(12cm,0);
+
+void distance(picture pic=currentpicture, pair A, pair B, Label L="", real n=0,
+ pen p=currentpen)
+{
+ real d=3mm;
+ path g=A--B;
+ transform T=shift(-n*d*unit(B-A)*I);
+ pic.add(new void(frame f, transform t) {
+ picture opic;
+ path G=T*t*g;
+ draw(opic,Label(L,Center,UnFill(1)),G,p,Arrows(NoFill),Bars,PenMargins);
+ add(f,opic.fit());
+ });
+ pic.addBox(min(g),max(g),T*min(p),T*max(p));
+}
+
+pair A=(0,0), B=(3,3);
+
+dot(A);
+dot(B);
+
+distance(A,B,"$\ell$",1);
+\endverbatim
+
+\question 26jun:log2 How can I make the y axis display base-2 logarithmic values?
+
+See the example \docref{http://asymptote.sourceforge.net/gallery/2D graphs/log2graph.asy\}.
+
+\question 27jun:align How can I align the x axes of two graphs on the same figure?
+
+An easy way to do this, if the axes to be aligned have the same scaling
+and size, is illustrated in the example \docref{http://asymptote.sourceforge.net/gallery/2D graphs/alignedaxis.asy\}.
+
+Here is a more general solution to the problem of aligning two arbitrary axes.
+One fits the second picture to a frame based on the horizontal scaling for
+the first picture:
+
+\verbatim
+import graph;
+
+real width=15cm;
+real aspect=0.3;
+
+picture pic1,pic2;
+
+size(pic1,width,aspect*width,IgnoreAspect);
+size(pic2,width,aspect*width,IgnoreAspect);
+
+scale(pic1,false);
+scale(pic2,false);
+
+real xmin1=6;
+real xmax1=9;
+real xmin2=8;
+real xmax2=16;
+
+real a1=1;
+real a2=0.001;
+
+real f1(real x) {return a1*sin(x/2*pi);}
+real f2(real x) {return a2*sin(x/4*pi);}
+
+draw(pic1,graph(pic1,f1,xmin1,xmax1));
+draw(pic2,graph(pic2,f2,xmin2,xmax2));
+
+xaxis(pic1,Bottom,LeftTicks());
+yaxis(pic1,"$f_1(x)$",Left,RightTicks);
+
+xaxis(pic2,"$x$",Bottom,LeftTicks(Step=4));
+yaxis(pic2,"$f_2(x)$",Left,RightTicks);
+
+yequals(pic1,0,Dotted);
+yequals(pic2,0,Dotted);
+
+pair min1=point(pic1,SW);
+pair max1=point(pic1,NE);
+
+pair min2=point(pic2,SW);
+pair max2=point(pic2,NE);
+
+real scale=(max1.x-min1.x)/(max2.x-min2.x);
+real shift=min1.x/scale-min2.x;
+
+transform t1=pic1.calculateTransform();
+transform t2=pic2.calculateTransform();
+transform T=xscale(scale*t1.xx)*yscale(t2.yy);
+
+add(pic1.fit());
+real height=truepoint(N,user=false).y-truepoint(S,user=false).y;
+add(shift(0,-height)*(shift(shift)*pic2).fit(T));
+\endverbatim
+
+\question 27jun:changeaxis How can I change the direction of the y-axis, such that negatives values are on the upper y-axis?
+
+Here is a simple example (see also the example \docref{http://asymptote.sourceforge.net/gallery/2D graphs/diatom.asy\} or the discussion
+of Linear(-1) in the documentation):
+
+\verbatim
+import graph;
+size(250,200,IgnoreAspect);
+
+scale(Linear,Linear(-1));
+
+draw(graph(log,0.1,10),red);
+
+xaxis("$x$",LeftTicks);
+yaxis("$y$",RightTicks);
+\endverbatim
+
+\question 27jun:functioncolor How can I fill a path with a function that defines the color of each location?
+
+General function shading is only supported by PDF, not PostScript, so this
+will have to wait until we produce PDF code directly.
+
+An approximate solution for now would be to superimpose a fine grid and
+specify colors to latticeshade depending on position as a single pen[][]
+lattice. Or use Gouraud shading.
+
+\question 27jun:nonexplicitfun Is there a way to draw a function that is not explicitly given, such as (y - 2)^2 = x - 1 ?
+
+Yes, use the parametric form
+
+\verbatim
+y=t
+x=(t-2)^2+1
+\endverbatim
+
+See the example \docref{http://asymptote.sourceforge.net/gallery/2D graphs/parametricgraph.asy\}.
+
+\question 27jun:scalesecondaryaxis Is it possible to reverse or stretch an axis?
+
+The real scaling argument to Linear is used to stretch (or reverse) the axis.
+To see the effect of axis stretching, be sure not to specify IgnoreAspect in
+the picture size command.
+
+A secondary axis has the same length as the primary axis, so stretching cannot
+have any effect. But one can still reverse the axis, with Linear(-1).
+
+\question 02sep:emptymarkers Why can't I use the UnFill option to draw graphs with empty markers?
+
+UnFill won't work here because it only affects the local frame the markers
+are initially drawn on, before being added to currentpicture.
+Here is a way of achieving the desired effect (assuming a white background):
+
+\verbatim
+import graph;
+size(10cm,0);
+pair[] z={(0,0),(0.5,0.5),(1,1)};
+path g=graph(z);
+
+draw(shift(0,.5)*g,marker(scale(5)*unitcircle,FillDraw(white)));
+
+xaxis(BottomTop,LeftTicks);
+yaxis(LeftRight,RightTicks);
+\endverbatim
+
+\question 02sep:paletterange How can I force several images to use the same palette range (e.g. the entire 0-255 grayscale range)?
+
+The palette color space corresponds to a range of values specified by the
+argument range, which can be \courier{Full\}, \courier{Automatic\} or an
+explicit range \courier{Range(pair min, pair max)\}. Here \courier{Full}
+specifies a range varying from the minimum to maximum values of the
+function over the sampling interval, while \courier{Automatic\} selects
+"nice" limits.
+
+\comment #####################################################################
+
+\section Questions about programming
+
+\question 27jun:comporint Is Asymptote an interpreter or a compiler?
+
+Asymptote compiles Asymptote commands into its own virtual machine code. It
+then runs this pseudocode on a virtual machine to produce PostScript code.
+
+\question 05sep:framepicture What is the difference between a frame and a picture?
+
+Frames are canvases for drawing in PostScript coordinates. While working
+with frames directly is occasionally necessary for constructing deferred
+drawing routines, pictures are usually more convenient to work with.
+See \qref unitsizes.
+
+\question 05sep:pathguide What is the difference between a path and a guide?
+
+A path is a cubic spline with fixed endpoint conditions.
+
+A guide is an unresolved cubic spline (list of cubic-spline nodes and
+control points). A guide is like a path except that the computation of the cubic
+spline is deferred until drawing time (when it is resolved into a path);
+this allows two guides with free endpoint conditions to be joined together
+smoothly.
+
+\question 27jun:picarray What is a convenient way to declare and initialize an array of pictures?
+
+You could write yourself a routine such as:
+\verbatim
+picture[] picture(int n) {
+ picture[] pic;
+ for(int i=0; i < n; ++i) {
+ pic[i]=new picture;
+ size(pic[i],19cm,0);
+ }
+ return pic;
+}
+
+picture[] pic=picture(6);
+\endverbatim
+
+\question 27jun:genarrays Is there a way to define functions that act on arrays in general (i.e. work for arrays of any type)?
+
+Generic types aren't yet implemented.
+
+But for now you can at least say
+\verbatim
+typedef string T;
+include F;
+
+typedef real T;
+include F;
+\endverbatim
+
+where \courier{F.asy\} contains some type-dependent code like
+\verbatim
+T[] operator $(T A, T B) {return new T[] {A,B};}
+\endverbatim
+
+\question 27jun:cirdep Is there any way to declare structures ahead of their definition, e.g. where struct A performs some operation on struct B, but B contains an A member?
+
+Asymptote does not support forward declaration of types. You can, however,
+nest structures, so that both types are visible for parts of the bodies of
+both structure definitions. For example:
+
+\verbatim
+struct B {
+ typedef void someroutine(B b);
+
+ static struct A {
+ someroutine routine;
+ void operator init(someroutine routine) {
+ this.routine=routine;
+ }
+ }
+
+ string test="Testing";
+}
+
+typedef B.A A;
+
+A a=B.A(new void(B b){write(b.test);});
+
+B b;
+a.routine(b);
+\endverbatim
+
+\question 04nov:static Where are static variables in for loops allocated?
+
+In the example
+
+\verbatim
+void f() {
+ for(int i=0; i < 3; ++i) {
+ static int n;
+ ++n;
+ write(n);
+ }
+}
+
+f(); // Writes 1, 2, 3
+\endverbatim
+
+the static qualifier means that \courier{n\} is allocated not just outside
+of the for loop, but also outside the function. This is clear if you call
+\courier{f\} multiple times; there is still only one instance of \courier{n\}.
+
+The "level" of a variable (where it is allocated) has nothing to do with
+the "scope" of a variable (how long it can be referred to by name).
+The curly braces enclosing a block affect only a variable's scope, not
+its level.
+
+Static modifiers are meaningless at the top level; they generate a warning
+and are simply ignored:
+
+\verbatim
+for(int i=0; i < 3; ++i) {
+ static int n;
+ ++n;
+ write(n);
+}
+// Writes warning about top-level static modifier and then 1, 1, 1
+\endverbatim
+
+Since version 1.22, non-static variables allocated in a loop body are allocated
+anew every iteration. This is only noticable in obscure cases where a variable
+in a loop is accessed in the closure of a function defined in the loop:
+
+\verbatim
+int f();
+
+for(int i=0; i < 10; ++i) {
+ int j=10*i;
+ if(i == 5)
+ f=new int() {return j;};
+}
+
+write(f()); // Writes 50
+\endverbatim
+
+Variables in the body of a loop last as long as that iteration of the loop,
+unless they are kept alive by a function closure as in the example above. In a
+function body, variables will last at least as long as the function call, though
+because of closures and garbage collection, they may last longer than that. If
+defined at the top level of a file or at the interactive prompt, they will last
+at least until the end of the file or prompt's run.
+
+\question 26jun:debug Is there a debugger for asy?
+
+Yes, Asymptote includes a line-based debugger:
+
+\docref{http://asymptote.sourceforge.net/doc/Debugger.html\}
+
+\question 27jun:patches Do you accept patches for Asymptote?
+
+Yes, in fact we would prefer that users submit patches for customized features
+(to \docref{http://sourceforge.net/tracker/?atid=685685&group_id=120000\})
+instead of relying on us to do all of the coding. Development will proceed
+faster that way.
+
+\comment #####################################################################
+
+\section Questions about differences between Asymptote and MetaPost
+
+\question 29jun:interp What is the equivalent of the MetaPost c[a,b] interpolation operator?
+
+\verbatim
+interp(a,b,c);
+\endverbatim
+
+\question 02sep:automaticscaling How does picture scaling differ in Asymptote and MetaPost?
+
+Asymptote includes an optional facility to do automatic scaling of pictures
+to achieve a given overall picture size, whereas Metapost only supports manual
+scaling. Asymptote defers drawing of objects drawn to pictures and
+distinguishes between true-size objects and objects that should scale with
+the picture size. The resulting linear programming problem is solved via
+the Simplex method.
+
+See the \docref{http://asymptote.sourceforge.net/gallery/dimension.asy\} example for an example of how deferred drawing is
+used to accomodate both user and true-size (PostScript) coordinates.
+
+\question 02sep:manualscaling How can I avoid automatic scaling of a picture?
+
+If you really like Metapost-style manual (hard-wired) scaling either:
+
+(i) use the default size(0,0) for the entire picture and do all of the
+scaling by hand, just like in MetaPost;
+
+(ii) draw to a separate picture pic and add(pic.fit());
+
+(iii) use frames.
+
+\question 23jun:mp3dots What is the equivalent of MetaPost ... command?
+
+The connector \courier{::\} is a macro for tension atleast 1:
+
+\verbatim
+size(100);
+pair z0=(0,0);
+pair z1=(1,0.25);
+pair z2=(2,0);
+draw(z0{up}::z1{right}::z2{down});
+\endverbatim
+
+\question 23jun:mppickup What is the equivalent of the MetaPost pickup command?
+
+Just say, for example:
+
+\verbatim
+currentpen=red;
+\endverbatim
+
+\question 29aug:whatever What is the equivalent of the MetaPost whatever command?
+
+Asymptote does not implicitly solve linear equations and therefore does not
+have the notion of a \courier{whatever\} unknown. Such a facility could
+certainly be added (perhaps using the notation \courier{?=\} since
+\courier{=\} means assignment).
+However, the most common uses of \courier{whatever\} in MetaPost are covered by
+functions like \courier{extension\} in \courier{math.asy\}:
+\verbatim
+pair extension(pair P, pair Q, pair p, pair q);
+\endverbatim
+this returns the intersection point of the extensions of the line segments
+\courier{PQ\} and \courier{pq\}. We find using routines like
+\courier{extension\} more explicit and less confusing to new users. But we
+could be persuaded to add something similar if someone can justify the
+need. In the meantime, one can always use the explicit built-in linear
+solver \courier{solve\} (see
+\docref{http://asymptote.sourceforge.net/doc/solve.html\}), which uses LU
+decomposition.
+
+\question 23jun:lray What is the equivalent for the MetaPost command for \courier{lray - horiz*v - verti*u = whatever*(LightSource - R)\}, a system of three linear equations for three unknowns: \courier{horiz, verti, whatever\}?
+
+Since \courier{horiz*v+verti*u\} spans a plane, you could use
+\verbatim
+real intersect(vector P, vector Q, vector n, vector Z);
+\endverbatim
+
+to find the intersection time for the line
+\courier{lray-whatever*(LightSource - R)\}
+and then extract the three desired values from there. (You'll still need to
+use the built-in explicit linear solver to solve a 2x2 system to get
+\courier{horiz\} and \courier{verti\}.)
+
+\question 27jun:unitsizes In MetaPost, it is possible to have a drawing remain the same size in different pictures by defining a unit \courier{u\} and explicitly multiply all the coordinates by \courier{u\}. Is there a better way to do this in Asymptote?
+
+Yes, Asymptote has a better way: you definitely don't want to manually scale
+all of your coordinates. To make the user coordinates represent multiples
+of exactly \courier{1cm\}:
+
+\verbatim
+unitsize(1cm);
+draw(unitsquare);
+\endverbatim
+
+One can also specify different x and y unit sizes:
+
+\verbatim
+unitsize(x=1cm,y=2cm);
+draw(unitsquare);
+\endverbatim
+
+Another way is to draw your fixed size object to a frame and add it to
+currentpicture like this:
+
+\verbatim
+path p=(0,0)--(1,0);
+frame object;
+draw(object,scale(100)*p);
+
+add(object);
+add(object,(0,-10));
+\endverbatim
+
+To understand the difference between frames and pictures, try this:
+
+\verbatim
+size(300,300);
+
+path p=(0,0)--(1,0);
+picture object;
+draw(object,scale(100)*p);
+
+add(object);
+add(object,(0,-10)); // Adds truesize object to currentpicture
+\endverbatim
+
+\question 28jun:tiles In MetaPost, one could produce tiling pictures by generating a picture, and then clipping the picture to a rectangle of fixed dimensions around the center of the picture. How is that done in Asymptote?
+
+If you are using currentpicture the way one would in MetaPost (drawing in
+raw PostScript coordinates), you can simply do something like:
+
+\verbatim
+fill((0,0)--(100,100)--(200,0)--cycle);
+
+pair center(picture pic=currentpicture) {return 0.5*(pic.min()+pic.max());}
+
+real height=100;
+real width=100;
+pair delta=0.5(width,height);
+pair c=center();
+clip(box(c-delta,c+delta));
+\endverbatim
+
+However, drawing in PostScript coordinates is often inconvenient. Here's the
+Asymptote way of doing the same thing, using deferred drawing:
+
+\verbatim
+size(200,100);
+fill((0,0)--(1,1)--(2,0)--cycle);
+
+void clip(picture pic=currentpicture, real width, real height)
+{
+ pic.clip(new void (frame f, transform) {
+ pair center=0.5(min(f)+max(f));
+ pair delta=0.5(width,height);
+ clip(f,box(center-delta,center+delta));
+ });
+}
+
+clip(100,100);
+\endverbatim
+
+See also the discussion of tilings in the documentation:
+\docref{http://asymptote.sourceforge.net/doc/Pens.html\}.
+
+\comment ######################################################################
+
+\section Questions about output
+
+\question 27jun:psviewer How can I disable automatic invocation of the PS viewer after an asy file is done processing?
+
+It's actually not on by default, unless you happen to be using Microsoft
+Windows (because that is what most Microsoft Windows users
+expect). Microsoft Windows users can turn this feature off with the
+command-line option -noV or by putting
+
+\verbatim
+import settings;
+interactiveView=false;
+batchView=false;
+\endverbatim
+
+in their \courier{config.asy\} file. See
+\docref{http://asymptote.sourceforge.net/doc/Options.html\}.
+
+\question 26jun:jpeg How do I output jpeg images?
+
+If you have the ImageMagick convert program installed, simply type
+
+\verbatim
+asy -f jpg test.asy
+\endverbatim
+
+\question 27jun:embedbitmaps Can I embed bitmaps (photos) into my drawings and position and scale them?
+
+Convert them to eps format and use the graphic(string) function just like a
+Label:
+
+\verbatim
+label(graphic("file"),(0,0));
+\endverbatim
+
+See the example \docref{http://asymptote.sourceforge.net/gallery/orthocenter.asy\} and
+\docref{http://asymptote.sourceforge.net/doc/label.html\}.
+
+\question 28jun:directpdf Does Asymptote support direct PDF output?
+
+Yes, PDF output can be produced by the -f pdf option or -tex pdflatex option.
+This supports transparency, annotations, embedded movies, and U3D/PRC content.
+
+\question 28jun:bigpictures How to I produce large pictures of high quality in raster format (e.g. png, giff etc).
+
+Try using some of the options to convert, mainly -geometry and -density. For example:
+\verbatim
+convert -geometry 1000x3000 example.eps example.png
+\endverbatim
+
+You can also change the default resolution of the image with:
+\verbatim
+convert -geometry 1000x3000 -density 300 -units PixelsPerInch example.eps example.png
+\endverbatim
+This does not change the number of pixels in the image, but just gives a hint
+as to how large each pixel should be displayed.
+
+If you include the -density option without the -geometry option, convert will
+keep the image size constant (so a 4cm x 3cm eps figure will generate a 4cm x
+3cm png
+image).
+
+\question 28jun:multipage Is it possible to produce multi-page documents with asymptote?
+
+Yes, simply call the newpage() function. This is used by the
+\courier{slide.asy\} package to produce high-quality slide presentations
+(easier to use than Prosper).
+
+\comment Here it ends!
diff --git a/Build/source/utils/asymptote/doc/FAQ/bfnnconv.pl b/Build/source/utils/asymptote/doc/FAQ/bfnnconv.pl
new file mode 100755
index 00000000000..e1c894d299c
--- /dev/null
+++ b/Build/source/utils/asymptote/doc/FAQ/bfnnconv.pl
@@ -0,0 +1,298 @@
+#!/usr/bin/perl --
+# Copyright (C) 1993-1995 Ian Jackson.
+
+# This file is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+
+# It 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 General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with GNU Emacs; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+# Boston, MA 02111-1307, USA.
+
+# (Note: I do not consider works produced using these BFNN processing
+# tools to be derivative works of the tools, so they are NOT covered
+# by the GPL. However, I would appreciate it if you credited me if
+# appropriate in any documents you format using BFNN.)
+
+@outputs=('ascii','info','html');
+
+while ($ARGV[0] =~ m/^\-/) {
+ $_= shift(@ARGV);
+ if (m/^-only/) {
+ @outputs= (shift(@ARGV));
+ } else {
+ warn "unknown option `$_' ignored";
+ }
+}
+
+$prefix= $ARGV[0];
+$prefix= 'stdin' unless length($prefix);
+$prefix =~ s/\.bfnn$//;
+
+if (open(O,"$prefix.xrefdb")) {
+ @xrefdb= <O>;
+ close(O);
+} else {
+ warn "no $prefix.xrefdb ($!)";
+}
+
+$section= -1;
+for $thisxr (@xrefdb) {
+ $_= $thisxr;
+ chop;
+ if (m/^Q (\w+) ((\d+)\.(\d+)) (.*)$/) {
+ $qrefn{$1}= $2;
+ $qreft{$1}= $5;
+ $qn2ref{$3,$4}= $1;
+ $maxsection= $3;
+ $maxquestion[$3]= $4;
+ } elsif (m/^S (\d+) /) {
+ $maxsection= $1;
+ $sn2title{$1}=$';
+ }
+}
+
+open(U,">$prefix.xrefdb-new");
+
+for $x (@outputs) { require("m-$x.pl"); }
+
+&call('init');
+
+while (<>) {
+ chop;
+ next if m/^\\comment\b/;
+ if (!m/\S/) {
+ &call('endpara');
+ next;
+ }
+ if (s/^\\section +//) {
+ $line= $_;
+ $section++; $question=0;
+ print U "S $section $line\n";
+ $|=1; print "S$section",' 'x10,"\r"; $|=0;
+ &call('endpara');
+ &call('startmajorheading',"$section",
+ "Section $section",
+ $section<$maxsection ? "Section ".($section+1) : '',
+ $section>1 ? 'Section '.($section-1) : 'Top');
+ &text($line);
+ &call('endmajorheading');
+ if ($section) {
+ &call('endpara');
+ &call('startindex');
+ for $thisxr (@xrefdb) {
+ $_= $thisxr;
+ chop;
+ if (m/^Q (\w+) (\d+)\.(\d+) (.*)$/) {
+ $ref= $1; $num1= $2; $num2= $3; $text= $4;
+ next unless $num1 == $section;
+ &call('startindexitem',$ref,"Q$num1.$num2","Question $num1.$num2");
+ &text($text);
+ &call('endindexitem');
+ }
+ }
+ &call('endindex');
+ }
+ } elsif (s/^\\question \d{2}[a-z]{3}((:\w+)?) +//) {
+ $line= $_;
+ $question++;
+ $qrefstring= $1;
+ $qrefstring= "q_${section}_$question" unless $qrefstring =~ s/^://;
+ print U "Q $qrefstring $section.$question $line\n";
+ $|=1; print "Q$section.$question",' 'x10,"\r"; $|=0;
+ &call('endpara');
+ &call('startminorheading',$qrefstring,
+ "Question $section.$question",
+ $question < $maxquestion[$section] ? "Question $section.".($question+1) :
+ $section < $maxsection ? "Question ".($section+1).".1" : '',
+ $question > 1 ? "Question $section.".($question-1) :
+ $section > 1 ? "Question ".($section-1).'.'.($maxquestion[$section-1]) :
+ 'Top',
+ "Section $section");
+ &text("Question $section.$question. $line");
+ &call('endminorheading');
+ } elsif (s/^\\only +//) {
+ @saveoutputs= @outputs;
+ @outputs=();
+ for $x (split(/\s+/,$_)) {
+ push(@outputs,$x) if grep($x eq $_, @saveoutputs);
+ }
+ } elsif (s/^\\endonly$//) {
+ @outputs= @saveoutputs;
+ } elsif (s/^\\copyto +//) {
+ $fh= $';
+ while(<>) {
+ last if m/^\\endcopy$/;
+ while (s/^([^\`]*)\`//) {
+ print $fh $1;
+ m/([^\\])\`/ || warn "`$_'";
+ $_= $';
+ $cmd= $`.$1;
+ $it= `$cmd`; chop $it;
+ print $fh $it;
+ }
+ print $fh $_;
+ }
+ } elsif (m/\\index$/) {
+ &call('startindex');
+ for $thisxr (@xrefdb) {
+ $_= $thisxr;
+ chop;
+ if (m/^Q (\w+) (\d+\.\d+) (.*)$/) {
+ $ref= $1; $num= $2; $text= $3;
+ &call('startindexitem',$ref,"Q$num","Question $num");
+ &text($text);
+ &call('endindexitem');
+ } elsif (m/^S (\d+) (.*)$/) {
+ $num= $1; $text= $2;
+ next unless $num;
+ &call('startindexmainitem',"s_$num",
+ "Section $num.","Section $num");
+ &text($text);
+ &call('endindexitem');
+ } else {
+ warn $_;
+ }
+ }
+ &call('endindex');
+ } elsif (m/^\\call-(\w+) +(\w+)\s*(.*)$/) {
+ $fn= $1.'_'.$2;
+ eval { &$fn($3); };
+ warn $@ if length($@);
+ } elsif (m/^\\call +(\w+)\s*(.*)$/) {
+ eval { &call($1,$2); };
+ warn $@ if length($@);
+ } elsif (s/^\\set +(\w+)\s*//) {
+ $svalue= $'; $svari= $1;
+ eval("\$user_$svari=\$svalue"); $@ && warn "setting $svalue failed: $@\n";
+ } elsif (m/^\\verbatim$/) {
+ &call('startverbatim');
+ while (<>) {
+ chop;
+ last if m/^\\endverbatim$/;
+ &call('verbatim',$_);
+ }
+ &call('endverbatim');
+ } else {
+ s/\.$/\. /;
+ &text($_." ");
+ }
+}
+
+print ' 'x25,"\r";
+&call('finish');
+rename("$prefix.xrefdb-new","$prefix.xrefdb") || warn "rename xrefdb: $!";
+exit 0;
+
+
+sub text {
+ local($in,$rhs,$word,$refn,$reft,$fn,$style);
+ $in= "$holdover$_[0]";
+ $holdover= '';
+ while ($in =~ m/\\/) {
+#print STDERR ">$`##$'\n";
+ $rhs=$';
+ &call('text',$`);
+ $_= $rhs;
+ if (m/^\w+ $/) {
+ $holdover= "\\$&";
+ $in= '';
+ } elsif (s/^fn\s+([^\s\\]*\w)//) {
+ $in= $_;
+ $word= $1;
+ &call('courier');
+ &call('text',$word);
+ &call('endcourier');
+ } elsif (s/^tab\s+(\d+)\s+//) {
+ $in= $_; &call('tab',$1);
+ } elsif (s/^nl\s+//) {
+ $in= $_; &call('newline');
+ } elsif (s/^qref\s+(\w+)//) {
+ $refn= $qrefn{$1};
+ $reft= $qreft{$1};
+ if (!length($refn)) {
+ warn "unknown question `$1'";
+ }
+ $in= "$`\\pageref:$1:$refn:$reft\\endpageref.$_";
+ } elsif (s/^pageref:(\w+):([^:\n]+)://) {
+ $in= $_;
+ &call('pageref',$1,$2);
+ } elsif (s/^endpageref\.//) {
+ $in= $_; &call('endpageref');
+ } elsif (s/^(\w+)\{//) {
+ $in= $_; $fn= $1;
+ eval { &call("$fn"); };
+ if (length($@)) { warn $@; $fn= 'x'; }
+ push(@styles,$fn);
+ } elsif (s/^\}//) {
+ $in= $_;
+ $fn= pop(@styles);
+ if ($fn ne 'x') { &call("end$fn"); }
+ } elsif (s/^\\//) {
+ $in= $_;
+ &call('text',"\\");
+ } elsif (s,^(\w+)\s+([-A-Za-z0-9.\@:/]*\w),,) {
+#print STDERR "**$&**$_\n";
+ $in= $_;
+ $style=$1; $word= $2;
+ &call($style);
+ &call('text',$word);
+ &call("end$style");
+ } else {
+ warn "unknown control `\\$_'";
+ $in= $_;
+ }
+ }
+ &call('text',$in);
+}
+
+
+sub call {
+ local ($fnbase, @callargs) = @_;
+ local ($coutput);
+ for $coutput (@outputs) {
+ if ($fnbase eq 'text' && eval("\@${coutput}_cmds")) {
+#print STDERR "special handling text (@callargs) for $coutput\n";
+ $evstrg= "\$${coutput}_args[\$#${coutput}_args].=\"\@callargs\"";
+ eval($evstrg);
+ length($@) && warn "call adding for $coutput (($evstrg)): $@";
+ } else {
+ $fntc= $coutput.'_'.$fnbase;
+ &$fntc(@callargs);
+ }
+ }
+}
+
+
+sub recurse {
+ local (@outputs) = $coutput;
+ local ($holdover);
+ &text($_[0]);
+}
+
+
+sub arg {
+#print STDERR "arg($_[0]) from $coutput\n";
+ $cmd= $_[0];
+ eval("push(\@${coutput}_cmds,\$cmd); push(\@${coutput}_args,'')");
+ length($@) && warn "arg setting up for $coutput: $@";
+}
+
+sub endarg {
+#print STDERR "endarg($_[0]) from $coutput\n";
+ $evstrg= "\$${coutput}_cmd= \$cmd= pop(\@${coutput}_cmds); ".
+ "\$${coutput}_arg= \$arg= pop(\@${coutput}_args); ";
+ eval($evstrg);
+ length($@) && warn "endarg extracting for $coutput (($evstrg)): $@";
+#print STDERR ">call $coutput $cmd $arg< (($evstrg))\n";
+ $evstrg= "&${coutput}_do_${cmd}(\$arg)";
+ eval($evstrg);
+ length($@) && warn "endarg running ${coutput}_do_${cmd} (($evstrg)): $@";
+}
diff --git a/Build/source/utils/asymptote/doc/FAQ/install-sh b/Build/source/utils/asymptote/doc/FAQ/install-sh
new file mode 120000
index 00000000000..fa87b11d55a
--- /dev/null
+++ b/Build/source/utils/asymptote/doc/FAQ/install-sh
@@ -0,0 +1 @@
+../../install-sh \ No newline at end of file
diff --git a/Build/source/utils/asymptote/doc/FAQ/m-ascii.pl b/Build/source/utils/asymptote/doc/FAQ/m-ascii.pl
new file mode 100644
index 00000000000..d05f8ed80d2
--- /dev/null
+++ b/Build/source/utils/asymptote/doc/FAQ/m-ascii.pl
@@ -0,0 +1,189 @@
+## ASCII output
+# Copyright (C) 1993-1995 Ian Jackson.
+
+# This file is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+
+# It 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 General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with GNU Emacs; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+# Boston, MA 02111-1307, USA.
+
+# (Note: I do not consider works produced using these BFNN processing
+# tools to be derivative works of the tools, so they are NOT covered
+# by the GPL. However, I would appreciate it if you credited me if
+# appropriate in any documents you format using BFNN.)
+
+sub ascii_init {
+ open(ASCII,">$prefix.ascii");
+}
+
+sub ascii_startmajorheading {
+ print ASCII '='x79,"\n\n";
+ $ascii_status= 'h';
+ &ascii_text($_[0] ? "Section $_[0]. " : '');
+}
+
+sub ascii_startminorheading {
+ print ASCII '-'x79,"\n\n";
+ $ascii_status= 'h';
+}
+
+sub ascii_italic { &ascii_text('*'); }
+sub ascii_enditalic { $ascii_para .= '*'; }
+
+sub ascii_email { &ascii_text('<'); } sub ascii_endemail { &ascii_text('>'); }
+
+sub ascii_ftpon { } sub ascii_endftpon { }
+sub ascii_ftpin { } sub ascii_endftpin { }
+sub ascii_docref { } sub ascii_enddocref { }
+sub ascii_courier { } sub ascii_endcourier { }
+sub ascii_newsgroup { } sub ascii_endnewsgroup { }
+sub ascii_ftpsilent { $ascii_ignore++; }
+sub ascii_endftpsilent { $ascii_ignore--; }
+
+sub ascii_text {
+ return if $ascii_ignore;
+ if ($ascii_status eq '') {
+ $ascii_status= 'p';
+ }
+ $ascii_para .= $_[0];
+}
+
+sub ascii_tab {
+ local ($n) = $_[0]-length($ascii_para);
+ $ascii_para .= ' 'x$n if $n>0;
+}
+
+sub ascii_newline {
+ return unless $ascii_status eq 'p';
+ &ascii_writepara;
+}
+
+sub ascii_writepara {
+ local ($thisline, $thisword, $rest);
+ for (;;) {
+ last unless $ascii_para =~ m/\S/;
+ $thisline= $ascii_indentstring;
+ for (;;) {
+ last unless $ascii_para =~ m/^(\s*\S+)/;
+ unless (length($1) + length($thisline) < 75 ||
+ length($thisline) == length($ascii_indentstring)) {
+ last;
+ }
+ $thisline .= $1;
+ $ascii_para= $';
+ }
+ $ascii_para =~ s/^\s*//;
+ print ASCII $thisline,"\n";
+ $ascii_indentstring= $ascii_nextindent;
+ last unless length($ascii_para);
+ }
+ $ascii_status= ''; $ascii_para= '';
+}
+
+sub ascii_endpara {
+ return unless $ascii_status eq 'p';
+ &ascii_writepara;
+ print ASCII "\n";
+}
+
+sub ascii_endheading {
+ $ascii_para =~ s/\s*$//;
+ print ASCII "$ascii_para\n\n";
+ $ascii_status= '';
+ $ascii_para= '';
+}
+
+sub ascii_endmajorheading { &ascii_endheading(@_); }
+sub ascii_endminorheading { &ascii_endheading(@_); }
+
+sub ascii_startverbatim {
+ $ascii_vstatus= $ascii_status;
+ &ascii_writepara;
+}
+
+sub ascii_verbatim {
+ print ASCII $_[0],"\n";
+}
+
+sub ascii_endverbatim {
+ $ascii_status= $ascii_vstatus;
+}
+
+sub ascii_finish {
+ close(ASCII);
+}
+
+sub ascii_startindex { $ascii_status= ''; }
+sub ascii_endindex { $ascii_status= 'p'; }
+
+sub ascii_endindexitem {
+ printf ASCII " %-11s %-.66s\n",$ascii_left,$ascii_para;
+ $ascii_status= 'p';
+ $ascii_para= '';
+}
+
+sub ascii_startindexitem {
+ $ascii_left= $_[1];
+}
+
+sub ascii_startindexmainitem {
+ $ascii_left= $_[1];
+ print ASCII "\n" if $ascii_status eq 'p';
+}
+
+sub ascii_startindent {
+ $ascii_istatus= $ascii_status;
+ &ascii_writepara;
+ $ascii_indentstring= " $ascii_indentstring";
+ $ascii_nextindent= " $ascii_nextindent";
+}
+
+sub ascii_endindent {
+ $ascii_indentstring =~ s/^ //;
+ $ascii_nextindent =~ s/^ //;
+ $ascii_status= $ascii_istatus;
+}
+
+sub ascii_startpackedlist { $ascii_plc=0; }
+sub ascii_endpackedlist { &ascii_newline if !$ascii_plc; }
+sub ascii_packeditem {
+ &ascii_newline if !$ascii_plc;
+ &ascii_tab($ascii_plc*40+5);
+ $ascii_plc= !$ascii_plc;
+}
+
+sub ascii_startlist {
+ &ascii_endpara;
+ $ascii_indentstring= " $ascii_indentstring";
+ $ascii_nextindent= " $ascii_nextindent";
+}
+
+sub ascii_endlist {
+ &ascii_endpara;
+ $ascii_indentstring =~ s/^ //;
+ $ascii_nextindent =~ s/^ //;
+}
+
+sub ascii_item {
+ &ascii_newline;
+ $ascii_indentstring =~ s/ $/* /;
+}
+
+sub ascii_pageref {
+ &ascii_text("Q$_[1] \`");
+}
+
+sub ascii_endpageref {
+ &ascii_text("'");
+}
+
+1;
diff --git a/Build/source/utils/asymptote/doc/FAQ/m-html.pl b/Build/source/utils/asymptote/doc/FAQ/m-html.pl
new file mode 100644
index 00000000000..75b8ccc38f7
--- /dev/null
+++ b/Build/source/utils/asymptote/doc/FAQ/m-html.pl
@@ -0,0 +1,341 @@
+## HTML output
+# Copyright (C) 1993-1995 Ian Jackson.
+# Modified by John Bowman 02Sep06: simply docref usage
+
+# This file is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+
+# It 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 General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with GNU Emacs; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+# Boston, MA 02111-1307, USA.
+
+# (Note: I do not consider works produced using these BFNN processing
+# tools to be derivative works of the tools, so they are NOT covered
+# by the GPL. However, I would appreciate it if you credited me if
+# appropriate in any documents you format using BFNN.)
+
+%saniarray= ('<','lt', '>','gt', '&','amp', '"','quot');
+
+sub html_init {
+ $html_prefix = './'.$prefix;
+ $html_prefix =~ s:^\.//:/:;
+ system('rm','-r',"$html_prefix.html");
+ system('mkdir',"$html_prefix.html");
+ open(HTML,">$html_prefix.html/index.html");
+ print HTML "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 3.2//EN\">\n";
+ print HTML "<html>\n";
+ $html_needpara= -1;
+ $html_end='';
+ chop($html_date=`date '+%d %B %Y'`);
+ chop($html_year=`date '+%Y'`);
+}
+
+sub html_startup {
+ print HTML <<END;
+<head><title>
+$user_title
+</title>
+<link rev="made" href="mailto:$user_authormail">
+<link rel="Contents" href="index.html">
+<link rel="Start" href="index.html">
+<META name="description"
+ content="Frequently asked questions and answers (FAQ) for Asymptote.">
+<link rel="Bookmark" title="Asymptote FAQ" href="index.html">
+<LINK rel="Bookmark" title="Asymptote Home Page"
+ href="http://asymptote.sourceforge.net">
+<LINK rel="Bookmark" title="Asymptote Manual"
+ href="http://asymptote.sourceforge.net/doc/">
+</head><body text="#000000" bgcolor="#FFFFFF"><h1>
+$user_title
+</h1>
+END
+ &html_readrefs($_[0]);
+ if (length($user_copyrightref)) {
+ local ($refn) = $qrefn{$user_copyrightref};
+ if (!length($refn)) {
+ warn "unknown question (copyright) `$user_copyrightref'";
+ }
+ $refn =~ m/(\d+)\.(\d+)/;
+ local ($s,$n) = ($1,$2);
+ $html_copyrighthref= ($s == $html_sectionn)?'':"section$s.html";
+ $html_copyrighthref.= "#$qn2ref{$s,$n}";
+ }
+}
+
+sub html_close {
+ print HTML $html_end,"<address>\n$user_author\n";
+ print HTML "- $html_date\n</address><br>\n";
+ print HTML "Extracted from $user_title,\n";
+ print HTML "<A href=\"$html_copyrighthref\">" if length($html_copyrighthref);
+ print HTML "Copyright &copy; $html_year $user_copyholder.";
+ print HTML "</A>" if length($html_copyrighthref);
+ print HTML "\n</body></html>\n";
+ close(HTML);
+}
+
+sub html_startmajorheading {
+ local ($ref, $this,$next,$back) = @_;
+ local ($nextt,$backt);
+ $this =~ s/^Section /section/; $html_sectionn= $ref;
+ $next =~ s/^Section /section/ && ($nextt= $sn2title{$'});
+ $back =~ s/^Section /section/ ? ($backt= $sn2title{$'}) : ($back='');
+ if ($html_sectionn) {
+ &html_close;
+ open(HTML,">$html_prefix.html/$this.html");
+ print HTML "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 3.2//EN\">\n";
+ print HTML "<html>\n";
+ $html_end= "<hr>\n";
+ $html_end.= "Next: <a href=\"$next.html\" rel=precedes>$nextt</a>.<br>\n"
+ if $next;
+ $html_end.= "Back: <a href=\"$back.html\" rev=precedes>$backt</a>.<br>\n"
+ if $back;
+ $html_end.= "<a href=\"index.html\" rev=subdocument>";
+ $html_end.= "Return to contents</a>.<p>\n";
+ print HTML <<END;
+<head><title>
+$user_brieftitle - Section $html_sectionn
+</title>
+<link rev="made" href="mailto:$user_authormail">
+<link rel="Contents" href="index.html">
+<link rel="Start" href="index.html">
+END
+ print HTML "<link rel=\"Next\" href=\"$next.html\">" if $next;
+ print HTML "<link rel=\"Previous\" href=\"$back.html\">" if $back;
+ print HTML <<END;
+<link rel="Bookmark" title="Asymptote FAQ" href="index.html">
+</head><body text="#000000" bgcolor="#FFFFFF"><h1>
+$user_brieftitle - Section $html_sectionn <br>
+END
+ $html_needpara= -1;
+ }
+ else {
+ print HTML "\n<h1>\n";
+ $html_needpara=-1;
+ }
+}
+
+sub html_endmajorheading {
+ print HTML "\n</h1>\n\n";
+ $html_needpara=-1;
+}
+
+sub html_startminorheading {
+ local ($ref, $this) = @_;
+ $html_needpara=0;
+ $this =~ m/^Question (\d+)\.(\d+)/;
+ local ($s,$n) = ($1,$2);
+ print HTML "\n<h2><A name=\"$qn2ref{$s,$n}\">\n";
+}
+
+sub html_endminorheading {
+ print HTML "\n</A></h2>\n\n";
+ $html_needpara=-1;
+}
+
+sub html_newsgroup { &arg('newsgroup'); }
+sub html_endnewsgroup { &endarg('newsgroup'); }
+sub html_do_newsgroup {
+ print HTML "<A href=\"news:$_[0]\"><code>$_[0]</code></A>";
+}
+
+sub html_email { &arg('email'); }
+sub html_endemail { &endarg('email'); }
+sub html_do_email {
+ print HTML "<A href=\"mailto:$_[0]\"><code>$_[0]</code></A>";
+}
+
+sub html_courier { print HTML "<code>" ; }
+sub html_endcourier { print HTML "</code>"; }
+sub html_italic { print HTML "<i>" ; }
+sub html_enditalic { print HTML "</i>" ; }
+
+sub html_docref { &arg('docref'); }
+sub html_enddocref { &endarg('docref'); }
+sub html_do_docref {
+ if (!defined($html_refval{$_[0]})) {
+# Modified by John Bowman 02Sep06: interpret the argument as an html reference
+# warn "undefined HTML reference $_[0]";
+# $html_refval{$n}='UNDEFINED';
+ print HTML "<A href=\"$_[0]\">";
+ } else {
+ print HTML "<A href=\"$html_refval{$_[0]}\">";
+ }
+ &recurse($_[0]);
+ print HTML "</A>";
+}
+
+sub html_readrefs {
+ local ($p);
+ open(HTMLREFS,"<$_[0]") || (warn("failed to open HTML refs $_[0]: $!"),return);
+ while(<HTMLREFS>) {
+ next if m/^\\\s/;
+ s/\s*\n$//;
+ if (s/^\\prefix\s*//) {
+ $p= $'; next;
+ } elsif (s/^\s*(\S.*\S)\s*\\\s*//) {
+ $_=$1; $v=$';
+ s/\\\\/\\/g;
+ $html_refval{$_}= $p.$v;
+ } else {
+ warn("cannot understand line in HTML refs >$_<");
+ }
+ }
+ close(HTMLREFS);
+}
+
+sub html_ftpsilent { &arg('ftpsilent'); }
+sub html_endftpsilent { &endarg('ftpsilent'); }
+sub html_do_ftpsilent {
+ if ($_[0] =~ m/:/) {
+ $html_ftpsite= $`;
+ $html_ftpdir= $'.'/';
+ } else {
+ $html_ftpsite= $_[0];
+ $html_ftpdir= '';
+ }
+}
+
+sub html_ftpon { &arg('ftpon'); }
+sub html_endftpon { &endarg('ftpon'); }
+sub html_do_ftpon {
+#print STDERR "ftpon($_[0])\n";
+ $html_ftpsite= $_[0]; $html_ftpdir= '';
+ print HTML "<code>";
+ &recurse($_[0]);
+ print HTML "</code>";
+}
+
+sub html_ftpin { &arg('ftpin'); }
+sub html_endftpin { &endarg('ftpin'); }
+sub html_do_ftpin {
+#print STDERR "ftpin($_[0])\n";
+ print HTML "<A href=\"ftp://$html_ftpsite$html_ftpdir$_[0]\"><code>";
+ &recurse($_[0]);
+ print HTML "</code></A>";
+}
+
+sub html_text {
+ print HTML "\n<p>\n" if $html_needpara > 0;
+ $html_needpara=0;
+ $html_stuff= &html_sanitise($_[0]);
+ while ($html_stuff =~ s/^(.{40,70}) //) {
+ print HTML "$1\n";
+ }
+ print HTML $html_stuff;
+}
+
+sub html_tab {
+ $htmltabignore++ || warn "html tab ignored";
+}
+
+sub html_newline { print HTML "<br>\n" ; }
+sub html_startverbatim { print HTML "<pre>\n" ; }
+sub html_verbatim { print HTML &html_sanitise($_[0]),"\n"; }
+sub html_endverbatim { print HTML "</pre>\n" ; $html_needpara= -1; }
+
+sub html_endpara {
+ $html_needpara || $html_needpara++;
+}
+
+sub html_finish {
+ &html_close;
+}
+
+sub html_startindex {
+ print HTML "<ul>\n";
+}
+
+sub html_endindex {
+ print HTML "</ul><hr>\n";
+}
+
+sub html_startindexitem {
+ local ($ref,$qval) = @_;
+ $qval =~ m/Q(\d+)\.(\d+)/;
+ local ($s,$n) = ($1,$2);
+ print HTML "<li><a href=\"";
+ print HTML ($s == $html_sectionn)?'':"section$s.html";
+ print HTML "#$qn2ref{$s,$n}\" rel=subdocument>Q$s.$n. ";
+ $html_indexunhead='';
+}
+
+sub html_startindexmainitem {
+ local ($ref,$s) = @_;
+ $s =~ m/\d+/; $s= $&;
+ print HTML "<br><br>" if ($s > 1);
+ print HTML "<li><b><font size=\"+2\"><a href=\"section$s.html\" rel=subdocument>Section $s. ";
+ $html_indexunhead='</font></b>';
+}
+
+sub html_endindexitem {
+ print HTML "</a>$html_indexunhead\n";
+}
+
+sub html_startlist {
+ print HTML "\n";
+ $html_itemend="<ul>";
+}
+
+sub html_endlist {
+ print HTML "$html_itemend\n</ul>\n";
+ $html_needpara=-1
+}
+
+sub html_item {
+ print HTML "$html_itemend\n<li>";
+ $html_itemend="";
+ $html_needpara=-1;
+}
+
+sub html_startpackedlist {
+ print HTML "\n";
+ $html_itemend="<dir>";
+}
+
+sub html_endpackedlist {
+ print HTML "$html_itemend\n</dir>\n";
+ $html_needpara=-1;
+}
+
+sub html_packeditem {
+ print HTML "$html_itemend\n<li>";
+ $html_itemend="";
+ $html_needpara=-1;
+}
+
+sub html_startindent { print HTML "<blockquote>\n"; }
+sub html_endindent { print HTML "</blockquote>\n"; }
+
+sub html_pageref {
+ local ($ref,$sq) = @_;
+ $sq =~ m/(\d+)\.(\d+)/;
+ local ($s,$n) = ($1,$2);
+ print HTML "<A href=\"";
+ print HTML ($s == $html_sectionn)?'':"section$s.html";
+ print HTML "#$qn2ref{$s,$n}\">Q$sq \`";
+}
+
+sub html_endpageref {
+ print HTML "'</A>";
+}
+
+sub html_sanitise {
+ local ($in) = @_;
+ local ($out);
+ while ($in =~ m/[<>&"]/) {
+ $out.= $`. '&'. $saniarray{$&}. ';';
+ $in=$';
+ }
+ $out.= $in;
+ $out;
+}
+
+1;
diff --git a/Build/source/utils/asymptote/doc/FAQ/m-info.pl b/Build/source/utils/asymptote/doc/FAQ/m-info.pl
new file mode 100644
index 00000000000..cfa2515ae11
--- /dev/null
+++ b/Build/source/utils/asymptote/doc/FAQ/m-info.pl
@@ -0,0 +1,226 @@
+## Info output
+# Copyright (C) 1993-1995 Ian Jackson.
+
+# This file is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+
+# It 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 General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with GNU Emacs; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+# Boston, MA 02111-1307, USA.
+
+# (Note: I do not consider works produced using these BFNN processing
+# tools to be derivative works of the tools, so they are NOT covered
+# by the GPL. However, I would appreciate it if you credited me if
+# appropriate in any documents you format using BFNN.)
+
+sub info_init {
+ open(INFO,">$prefix.info");
+ print INFO <<END;
+Info file: $prefix.info, -*-Text-*-
+produced by bfnnconv.pl from the Bizarre Format With No Name.
+
+END
+}
+
+sub info_heading {
+ # refstring Node Next Previous Up
+ print INFO "\nFile: $prefix.info, Node: $_[1]";
+ print INFO ", Next: $_[2]" if length($_[2]);
+ print INFO ", Previous: $_[3]" if length($_[3]);
+ print INFO ", Up: $_[4]" if length($_[4]);
+ print INFO "\n\n";
+ $info_status= '';
+}
+
+sub info_startmajorheading {
+ return if $_[0] eq '0';
+ &info_heading('s_'.$_[0],@_[1..$#_],'Top');
+}
+
+sub info_startminorheading {
+ &info_heading(@_);
+}
+
+sub info_italic { &info_text('*'); }
+sub info_enditalic { $info_para .= '*'; }
+
+sub info_email { &info_text('<'); } sub info_endemail { &info_text('>'); }
+
+sub info_ftpon { } sub info_endftpon { }
+sub info_ftpin { } sub info_endftpin { }
+sub info_docref { } sub info_enddocref { }
+sub info_courier { } sub info_endcourier { }
+sub info_newsgroup { } sub info_endnewsgroup { }
+sub info_ftpsilent { $info_ignore++; }
+sub info_endftpsilent { $info_ignore--; }
+
+sub info_text {
+ return if $info_ignore;
+ if ($info_status eq '') {
+ $info_status= 'p';
+ }
+ $info_para .= $_[0];
+}
+
+sub info_tab {
+ local ($n) = $_[0]-length($info_para);
+ $info_para .= ' 'x$n if $n>0;
+}
+
+sub info_newline {
+ return unless $info_status eq 'p';
+ print INFO &info_writepara;
+}
+
+sub info_writepara {
+ local ($thisline, $thisword, $rest, $output);
+ for (;;) {
+ last unless $info_para =~ m/\S/;
+ $thisline= $info_indentstring;
+ for (;;) {
+ last unless $info_para =~ m/^(\s*\S+)/;
+ unless (length($1) + length($thisline) < 75 ||
+ length($thisline) == length($info_indentstring)) {
+ last;
+ }
+ $thisline .= $1;
+ $info_para= $';
+ }
+ $info_para =~ s/^\s*//;
+ $output.= $thisline."\n";
+ $info_indentstring= $info_nextindent;
+ last unless length($info_para);
+ }
+ $info_status= ''; $info_para= '';
+ return $output;
+}
+
+sub info_endpara {
+ return unless $info_status eq 'p';
+ print INFO &info_writepara;
+ print INFO "\n";
+}
+
+sub info_endheading {
+ $info_para =~ s/\s*$//;
+ print INFO "$info_para\n\n";
+ $info_status= '';
+ $info_para= '';
+}
+
+sub info_endmajorheading { &info_endheading(@_); }
+sub info_endminorheading { &info_endheading(@_); }
+
+sub info_startverbatim {
+ print INFO &info_writepara;
+}
+
+sub info_verbatim {
+ print INFO $_[0],"\n";
+}
+
+sub info_endverbatim {
+ $info_status= $info_vstatus;
+}
+
+sub info_finish {
+ close(INFO);
+}
+
+sub info_startindex {
+ &info_endpara;
+ $info_moredetail= '';
+ $info_status= '';
+}
+
+sub info_endindex {
+ print INFO "$info_moredetail\n" if length($info_moredetail);
+}
+
+sub info_endindexitem {
+ $info_indentstring= sprintf("* %-17s ",$info_label.'::');
+ $info_nextindent= ' 'x20;
+ local ($txt);
+ $txt= &info_writepara;
+ if ($info_main) {
+ print INFO $label.$txt;
+ $txt =~ s/^.{20}//;
+ $info_moredetail.= $txt;
+ } else {
+ $info_moredetail.= $label.$txt;
+ }
+ $info_indentstring= $info_nextindent= '';
+ $info_status='p';
+}
+
+sub info_startindexitem {
+ print INFO "* Menu:\n" if $info_status eq '';
+ $info_status= '';
+ $info_label= $_[2];
+ $info_main= 0;
+}
+
+sub info_startindexmainitem {
+ print INFO "* Menu:\n" if $info_status eq '';
+ $info_label= $_[2];
+ $info_main= 1;
+ $info_moredetail .= "\n$_[2], ";
+ $info_status= '';
+}
+
+sub info_startindent {
+ $info_istatus= $info_status;
+ print INFO &info_writepara;
+ $info_indentstring= " $info_indentstring";
+ $info_nextindent= " $info_nextindent";
+}
+
+sub info_endindent {
+ $info_indentstring =~ s/^ //;
+ $info_nextindent =~ s/^ //;
+ $info_status= $info_istatus;
+}
+
+sub info_startpackedlist { $info_plc=0; }
+sub info_endpackedlist { &info_newline if !$info_plc; }
+sub info_packeditem {
+ &info_newline if !$info_plc;
+ &info_tab($info_plc*40+5);
+ $info_plc= !$info_plc;
+}
+
+sub info_startlist {
+ $info_istatus= $info_status;
+ print INFO &info_writepara;
+ $info_indentstring= " $info_indentstring";
+ $info_nextindent= " $info_nextindent";
+}
+
+sub info_endlist {
+ $info_indentstring =~ s/^ //;
+ $info_nextindent =~ s/^ //;
+ $info_status= $info_lstatus;
+}
+
+sub info_item {
+ &info_newline;
+ $info_indentstring =~ s/ $/* /;
+}
+
+sub info_pageref {
+ &info_text("*Note Question $_[1]:: \`");
+}
+
+sub info_endpageref {
+ &info_text("'");
+}
+
+1;
diff --git a/Build/source/utils/asymptote/doc/FAQ/m-lout.pl b/Build/source/utils/asymptote/doc/FAQ/m-lout.pl
new file mode 100644
index 00000000000..5c44852c750
--- /dev/null
+++ b/Build/source/utils/asymptote/doc/FAQ/m-lout.pl
@@ -0,0 +1,242 @@
+## Lout output
+# Copyright (C) 1993-1995 Ian Jackson.
+
+# This file is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+
+# It 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 General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with GNU Emacs; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+# Boston, MA 02111-1307, USA.
+
+# (Note: I do not consider works produced using these BFNN processing
+# tools to be derivative works of the tools, so they are NOT covered
+# by the GPL. However, I would appreciate it if you credited me if
+# appropriate in any documents you format using BFNN.)
+
+sub lout_init {
+ open(LOUT,">$prefix.lout");
+ chop($dprint= `date '+%d %B %Y'`);
+ $dprint =~ s/^0//;
+}
+
+sub lout_startup {
+ local ($lbs) = &lout_sanitise($user_brieftitle);
+ print LOUT <<END;
+\@SysInclude{ fontdefs }
+\@SysInclude{ langdefs }
+\@SysInclude{ dl }
+\@SysInclude{ docf }
+\@Use { \@DocumentLayout
+ \@OddTop { \@Null }
+ \@EvenTop { \@Null }
+ \@StartOddTop { \@Null }
+ \@StartEvenTop { \@Null }
+ \@OddFoot { { $lbs } \@Centre{ - \@PageNum - } \@Right{ $dprint } }
+ \@EvenFoot { { $lbs } \@Centre{ - \@PageNum - } \@Right{ $dprint } }
+ \@StartOddFoot { { $lbs } \@Centre{ - \@PageNum - } \@Right{ $dprint } }
+ \@StartEvenFoot { { $lbs } \@Centre{ - \@PageNum - } \@Right{ $dprint } }
+ \@ParaGap { 1.70vx }
+ \@InitialBreak { 1.0fx ragged hyphen }
+}
+\@Use { \@OrdinaryLayout }
+END
+ $lout_textstatus= 'p';
+}
+
+sub lout_pageref {
+ print LOUT "Q$_[1] (page {\@PageOf{$_[0]}}) ";
+ &lout_text("\`");
+}
+
+sub lout_endpageref {
+ &lout_text("'");
+}
+
+sub lout_finish {
+ print LOUT "\@End \@Text\n";
+ close(L);
+}
+
+sub lout_startmajorheading {
+ $lout_styles .= 'h';
+ print LOUT <<END
+\@CNP
+{
+ newpath 0 ysize 0.3 ft sub moveto
+ xsize 0 rlineto
+ 0 0.2 ft rlineto
+ xsize neg 0 rlineto
+ closepath fill
+} \@Graphic { //1.6f \@HAdjust \@Heading{
+END
+ ;
+ $endh= "}\n{\@PageMark s_$_[0]}\n/1.0fo\n";
+ &lout_text($_[0] ? "Section $_[0]. " : '');
+}
+
+sub lout_startminorheading {
+ $lout_styles .= 'h';
+ print LOUT "//0.2f \@CNP {\@PageMark $_[0]} \@Heading{\n";
+ $endh= '';
+}
+
+sub lout_endheading {
+ $lout_styles =~ s/.$//; print LOUT "}\n$endh";
+ $lout_status= 'p';
+}
+
+sub lout_endmajorheading { &lout_endheading(@_); }
+sub lout_endminorheading { &lout_endheading(@_); }
+
+sub lout_courier {
+ $lout_styles .= 'f';
+ print LOUT "{{0.7 1.0} \@Scale {Courier Bold} \@Font {";
+}
+
+sub lout_endcourier {
+ $lout_styles =~ s/.$//; print LOUT "}}";
+}
+
+sub lout_italic { $lout_styles .= 'f'; print LOUT "{Slope \@Font {"; }
+sub lout_enditalic { $lout_styles =~ s/.$//; print LOUT "}}"; }
+
+sub lout_startindent { $lout_styles .= 'i'; print LOUT "\@IndentedDisplay {\n"; }
+
+sub lout_endindent {
+ &lout_endpara;
+ $lout_styles =~ s/.$//; print LOUT "}\n\@LP\n";
+}
+
+sub lout_startpackedlist { $lout_plc=-1; }
+sub lout_endpackedlist { &lout_newline if !$lout_plc; }
+sub lout_packeditem {
+ &lout_newline if !$lout_plc;
+ &lout_tab(($lout_plc>0)*40+5);
+ $lout_plc= !$lout_plc;
+}
+
+sub lout_startlist {
+ &lout_endpara;
+ print LOUT "\@RawIndentedList style {\@Bullet} indent {0.5i} gap {1.1vx}\n";
+ $lout_styles .= 'l';
+ $lout_status= '';
+}
+
+sub lout_endlist {
+ &lout_endpara;
+ print LOUT "\@EndList\n\n";
+ $lout_styles =~ s/.$//;
+}
+
+sub lout_item {
+ &lout_endpara;
+ print LOUT "\@ListItem{";
+ $lout_styles.= 'I';
+}
+
+sub lout_startindex {
+ print LOUT "//0.0fe\n";
+}
+
+sub lout_endindex {
+ $lout_status='p';
+}
+
+sub lout_startindexmainitem {
+ $lout_marker= $_[0];
+ $lout_status= '';
+ print LOUT "//0.3vx Bold \@Font \@HAdjust { \@HContract { { $_[1] } |3cx {";
+ $lout_iiendheight= '1.00';
+ $lout_styles .= 'X';
+}
+
+sub lout_startindexitem {
+ $lout_marker= $_[0];
+ print LOUT "\@HAdjust { \@HContract { { $_[1] } |3cx {";
+ $lout_iiendheight= '0.95';
+ $lout_styles .= 'X';
+}
+
+sub lout_endindexitem {
+ print LOUT "} } |0c \@PageOf { $lout_marker } } //${lout_iiendheight}vx\n";
+ $lout_styles =~ s/.$//;
+}
+
+sub lout_email { &lout_courier; &lout_text('<'); }
+sub lout_endemail { &lout_text('>'); &lout_endcourier; }
+
+sub lout_ftpon { &lout_courier; } sub lout_endftpon { &lout_endcourier; }
+sub lout_ftpin { &lout_courier; } sub lout_endftpin { &lout_endcourier; }
+sub lout_docref { } sub lout_enddocref { }
+sub lout_ftpsilent { $lout_ignore++; }
+sub lout_endftpsilent { $lout_ignore--; }
+
+sub lout_newsgroup { &lout_courier; }
+sub lout_endnewsgroup { &lout_endcourier; }
+
+sub lout_text {
+ return if $lout_ignore;
+ $lout_status= 'p';
+ $_= &lout_sanitise($_[0]);
+ s/ $/\n/ unless $lout_styles =~ m/[fhX]/;
+ print LOUT $_;
+}
+
+sub lout_tab {
+ local ($size) = $_[0]*0.5;
+ print LOUT " |${size}ft ";
+}
+
+sub lout_newline {
+ print LOUT " //1.0vx\n";
+}
+
+sub lout_sanitise {
+ local ($in) = @_;
+ local ($out);
+ $in= ' '.$in.' ';
+ $out='';
+ while ($in =~ m/(\s)(\S*[\@\/|\\\"\^\&\{\}\#]\S*)(\s)/) {
+ $out .= $`.$1;
+ $in = $3.$';
+ $_= $2;
+ s/[\\\"]/\\$&/g;
+ $out .= '"'.$_.'"';
+ }
+ $out .= $in;
+ $out =~ s/^ //; $out =~ s/ $//;
+ $out;
+}
+
+sub lout_endpara {
+ return if $lout_status eq '';
+ if ($lout_styles eq '') {
+ print LOUT "\@LP\n\n";
+ } elsif ($lout_styles =~ s/I$//) {
+ print LOUT "}\n";
+ }
+ $lout_status= '';
+}
+
+sub lout_startverbatim {
+ print LOUT "//0.4f\n\@RawIndentedDisplay lines \@Break".
+ " { {0.7 1.0} \@Scale {Courier Bold} \@Font {\n";
+}
+
+sub lout_verbatim {
+ $_= $_[0];
+ s/^\s*//;
+ print LOUT &lout_sanitise($_),"\n";
+}
+
+sub lout_endverbatim { print LOUT "}\n}\n//0.4f\n"; }
+
+1;
diff --git a/Build/source/utils/asymptote/doc/FAQ/m-post.pl b/Build/source/utils/asymptote/doc/FAQ/m-post.pl
new file mode 100644
index 00000000000..e41c8d84fe4
--- /dev/null
+++ b/Build/source/utils/asymptote/doc/FAQ/m-post.pl
@@ -0,0 +1,189 @@
+## POST output
+# Copyright (C) 1993-1995 Ian Jackson.
+
+# This file is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+
+# It 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 General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with GNU Emacs; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+# Boston, MA 02111-1307, USA.
+
+# (Note: I do not consider works produced using these BFNN processing
+# tools to be derivative works of the tools, so they are NOT covered
+# by the GPL. However, I would appreciate it if you credited me if
+# appropriate in any documents you format using BFNN.)
+
+sub post_init {
+ open(POST,">$prefix.post");
+}
+
+sub post_startmajorheading {
+ print POST '='x79,"\n\n";
+ $post_status= 'h';
+ &post_text($_[0] ? "Section $_[0]. " : '');
+}
+
+sub post_startminorheading {
+ print POST '-'x77,"\n\n";
+ $post_status= 'h';
+}
+
+sub post_italic { &post_text('*'); }
+sub post_enditalic { $post_para .= '*'; }
+
+sub post_email { &post_text('<'); } sub post_endemail { &post_text('>'); }
+
+sub post_ftpon { } sub post_endftpon { }
+sub post_ftpin { } sub post_endftpin { }
+sub post_docref { } sub post_enddocref { }
+sub post_courier { } sub post_endcourier { }
+sub post_newsgroup { } sub post_endnewsgroup { }
+sub post_ftpsilent { $post_ignore++; }
+sub post_endftpsilent { $post_ignore--; }
+
+sub post_text {
+ return if $post_ignore;
+ if ($post_status eq '') {
+ $post_status= 'p';
+ }
+ $post_para .= $_[0];
+}
+
+sub post_tab {
+ local ($n) = $_[0]-length($post_para);
+ $post_para .= ' 'x$n if $n>0;
+}
+
+sub post_newline {
+ return unless $post_status eq 'p';
+ &post_writepara;
+}
+
+sub post_writepara {
+ local ($thisline, $thisword, $rest);
+ for (;;) {
+ last unless $post_para =~ m/\S/;
+ $thisline= $post_indentstring;
+ for (;;) {
+ last unless $post_para =~ m/^(\s*\S+)/;
+ unless (length($1) + length($thisline) < 75 ||
+ length($thisline) == length($post_indentstring)) {
+ last;
+ }
+ $thisline .= $1;
+ $post_para= $';
+ }
+ $post_para =~ s/^\s*//;
+ print POST $thisline,"\n";
+ $post_indentstring= $post_nextindent;
+ last unless length($post_para);
+ }
+ $post_status= ''; $post_para= '';
+}
+
+sub post_endpara {
+ return unless $post_status eq 'p';
+ &post_writepara;
+ print POST "\n";
+}
+
+sub post_endheading {
+ $post_para =~ s/\s*$//;
+ print POST "$post_para\n\n";
+ $post_status= '';
+ $post_para= '';
+}
+
+sub post_endmajorheading { &post_endheading(@_); }
+sub post_endminorheading { &post_endheading(@_); }
+
+sub post_startverbatim {
+ $post_vstatus= $post_status;
+ &post_writepara;
+}
+
+sub post_verbatim {
+ print POST $_[0],"\n";
+}
+
+sub post_endverbatim {
+ $post_status= $post_vstatus;
+}
+
+sub post_finish {
+ close(POST);
+}
+
+sub post_startindex { $post_status= ''; }
+sub post_endindex { $post_status= 'p'; }
+
+sub post_endindexitem {
+ printf POST " %-11s %-.66s\n",$post_left,$post_para;
+ $post_status= 'p';
+ $post_para= '';
+}
+
+sub post_startindexitem {
+ $post_left= $_[1];
+}
+
+sub post_startindexmainitem {
+ $post_left= $_[1];
+ print POST "\n" if $post_status eq 'p';
+}
+
+sub post_startindent {
+ $post_istatus= $post_status;
+ &post_writepara;
+ $post_indentstring= " $post_indentstring";
+ $post_nextindent= " $post_nextindent";
+}
+
+sub post_endindent {
+ $post_indentstring =~ s/^ //;
+ $post_nextindent =~ s/^ //;
+ $post_status= $post_istatus;
+}
+
+sub post_startpackedlist { $post_plc=0; }
+sub post_endpackedlist { &post_newline if !$post_plc; }
+sub post_packeditem {
+ &post_newline if !$post_plc;
+ &post_tab($post_plc*40+5);
+ $post_plc= !$post_plc;
+}
+
+sub post_startlist {
+ &post_endpara;
+ $post_indentstring= " $post_indentstring";
+ $post_nextindent= " $post_nextindent";
+}
+
+sub post_endlist {
+ &post_endpara;
+ $post_indentstring =~ s/^ //;
+ $post_nextindent =~ s/^ //;
+}
+
+sub post_item {
+ &post_newline;
+ $post_indentstring =~ s/ $/* /;
+}
+
+sub post_pageref {
+ &post_text("Q$_[1] \`");
+}
+
+sub post_endpageref {
+ &post_text("'");
+}
+
+1;
diff --git a/Build/source/utils/asymptote/doc/GaussianSurface.asy b/Build/source/utils/asymptote/doc/GaussianSurface.asy
new file mode 100644
index 00000000000..7b75a5133a7
--- /dev/null
+++ b/Build/source/utils/asymptote/doc/GaussianSurface.asy
@@ -0,0 +1,21 @@
+import graph3;
+
+size(200,0);
+
+currentprojection=perspective(10,8,4);
+
+real f(pair z) {return 0.5+exp(-abs(z)^2);}
+
+draw((-1,-1,0)--(1,-1,0)--(1,1,0)--(-1,1,0)--cycle);
+
+draw(arc(0.12Z,0.2,90,60,90,25),ArcArrow3);
+
+surface s=surface(f,(-1,-1),(1,1),nx=5,Spline);
+
+xaxis3(Label("$x$"),red,Arrow3);
+yaxis3(Label("$y$"),red,Arrow3);
+zaxis3(XYZero(extend=true),red,Arrow3);
+
+draw(s,lightgray,meshpen=black+thick(),nolight);
+
+label("$O$",O,-Z+Y,red);
diff --git a/Build/source/utils/asymptote/doc/HermiteSpline.asy b/Build/source/utils/asymptote/doc/HermiteSpline.asy
new file mode 100644
index 00000000000..7f4cbbebb24
--- /dev/null
+++ b/Build/source/utils/asymptote/doc/HermiteSpline.asy
@@ -0,0 +1,14 @@
+import graph;
+
+size(140mm,70mm,IgnoreAspect);
+scale(false);
+real[] x={1,3,4,5,6};
+real[] y={1,5,2,0,4};
+
+marker mark=marker(scale(1mm)*cross(6,false,r=0.35),red,Fill);
+
+draw(graph(x,y,Hermite),"Hermite Spline",mark);
+xaxis("$x$",Bottom,LeftTicks(x));
+yaxis("$y$",Left,LeftTicks);
+attach(legend(),point(NW),40S+30E,UnFill);
+
diff --git a/Build/source/utils/asymptote/doc/Hobbycontrol.asy b/Build/source/utils/asymptote/doc/Hobbycontrol.asy
new file mode 100644
index 00000000000..50662988e04
--- /dev/null
+++ b/Build/source/utils/asymptote/doc/Hobbycontrol.asy
@@ -0,0 +1,20 @@
+size(200);
+pair z0=(0,0);
+pair z1=(0.5,3);
+pair z2=(2,1);
+
+path g=z0..z1..z2;
+
+pair d0=dir(g,0);
+pair d1=dir(g,1);
+draw(Label("$\omega_0$",1),z0-d0..z0+d0,blue+dashed,Arrow);
+draw(Label("$\omega_1$",1),z1-d1..z1+1.5d1,blue+dashed,Arrow);
+draw(z0--interp(z0,z1,1.5),dashed);
+draw(subpath(g,0,1),blue);
+draw("$\theta$",arc(z0,0.4,degrees(z1-z0),degrees(d0)),red,Arrow,
+ EndPenMargin);
+draw("$\phi$",arc(z1,1.05,degrees(z1-z0),degrees(d1)),red,Arrow,
+ EndPenMargin);
+
+dot("$z_0$",z0,SW,red);
+dot("$z_1$",z1,SE,red);
diff --git a/Build/source/utils/asymptote/doc/Hobbydir.asy b/Build/source/utils/asymptote/doc/Hobbydir.asy
new file mode 100644
index 00000000000..01d8a2e0ed0
--- /dev/null
+++ b/Build/source/utils/asymptote/doc/Hobbydir.asy
@@ -0,0 +1,21 @@
+size(200);
+pair z0=(0,0);
+pair z1=(1,2);
+pair z2=(2,1);
+
+path g=z0..z1..z2;
+
+label("$\ell_k$",z0--z1);
+draw("$\ell_{k+1}$",z1--z2,dashed);
+draw(z0--interp(z0,z1,1.5),dashed);
+pair d1=dir(g,1);
+draw(z1-d1..z1+d1,blue+dashed);
+draw(g,blue);
+draw(Label("$\theta_k$",0.4),arc(z1,0.4,degrees(z2-z1),degrees(d1)),blue,Arrow,
+ EndPenMargin);
+draw("$\phi_k$",arc(z1,0.4,degrees(d1),degrees(z1-z0),CCW),Arrow,
+ EndPenMargin);
+
+dot("$z_{k-1}$",z0,red);
+dot("$z_k$",z1,NW,red);
+dot("$z_{k+1}$",z2,red);
diff --git a/Build/source/utils/asymptote/doc/Makefile.in b/Build/source/utils/asymptote/doc/Makefile.in
new file mode 100644
index 00000000000..f4141a02780
--- /dev/null
+++ b/Build/source/utils/asymptote/doc/Makefile.in
@@ -0,0 +1,96 @@
+MANFILES = asy.1 xasy.1x
+ASYFILES = $(wildcard *.asy) latexusage.asy
+SOURCE = asymptote.texi version.texi options
+ASY = ../asy -dir ../base -config "" -render=0
+DOCFILES = asymptote.pdf CAD.pdf
+
+docdir = $(DESTDIR)@docdir@
+infodir = $(DESTDIR)@infodir@
+datarootdir = @datarootdir@
+INSTALL = @INSTALL@
+TEXI2DVI = @TEXI2DVI@
+
+export docdir infodir INSTALL
+
+all: doc
+
+htmlinfo: latexusage.eps
+ cd png; $(MAKE) all
+
+man: $(DOCFILES) asy.1
+
+faq:
+ cd FAQ; $(MAKE) faq
+
+doc: asymptote.dvi htmlinfo man faq
+
+%.eps: %.asy
+ $(ASY) -f eps $<
+
+%.pdf: %.asy
+ $(ASY) -f pdf -noprc $<
+
+latexusage.dvi: latexusage.tex
+ rm -f latexusage-*
+ rm -f latexusage_.pre
+ rm -f latexusage.aux
+ latex latexusage
+ $(ASY) -noprc latexusage
+ latex latexusage
+
+latexusage.eps: latexusage.dvi
+ dvips -o latexusage.eps latexusage
+
+latexusage.pdf: latexusage.dvi
+ dvipdf latexusage
+
+options: ../settings.cc
+ $(ASY) -h 2>&1 | grep -iv Asymptote > options
+
+asy.1: options asy.1.begin asy.1.end
+ cat options | grep \^- | sed -e "s/-\(.*\) \([A-Z].*\)/.TP\n.B -\1\n\2\./" | sed -e "/^.B/ s/-/\\\\-/g" | cat asy.1.begin - asy.1.end > asy.1
+
+asymptote.dvi: $(SOURCE) $(ASYFILES:.asy=.eps)
+ ln -sf asymptote.texi asymptote_.texi
+ $(TEXI2DVI) asymptote_.texi
+ mv asymptote_.dvi asymptote.dvi
+
+asymptote.pdf: $(SOURCE) $(ASYFILES:.asy=.pdf)
+ $(TEXI2DVI) --pdf asymptote.texi
+
+CAD.pdf: CAD.tex CAD1.eps
+ latex CAD
+ latex CAD
+ latex CAD
+ dvipdf CAD
+
+clean: FORCE
+ -rm -f $(ASYFILES:.asy=.pdf) $(DOCFILES)
+ -rm -f *.eps latexusage.{asy,dvi,eps,log,aux,*.eps}
+ -rm -f {asymptote,asymptote_}.{aux,cp,cps,dvi,fn,info,ky,log,pg,pdf,toc,tp,vr}
+ -rm -f asymptote_.texi
+ -rm -f CAD.{aux,dvi,log,pdf,toc}
+ cd png; $(MAKE) clean
+
+install: man faq
+ cd FAQ; $(MAKE) install
+ ${INSTALL} -d -m 755 $(docdir) $(mandir)/man1
+ ${INSTALL} -p -m 644 $(DOCFILES) $(docdir)
+ ${INSTALL} -p -m 644 $(MANFILES) $(mandir)/man1
+
+install-all: doc install
+ cd FAQ; $(MAKE) install-info
+ cd png; $(MAKE) install
+
+uninstall: uninstall-all
+
+uninstall-all:
+ cd FAQ; $(MAKE) uninstall
+ cd png; $(MAKE) uninstall
+ -cd $(mandir)/man1; rm -f $(MANFILES)
+ -rm -f $(addprefix $(docdir)/,$(DOCFILES))
+
+distclean: FORCE clean
+ -rm -f version.texi Makefile
+ cd FAQ; make distclean
+FORCE:
diff --git a/Build/source/utils/asymptote/doc/asy.1 b/Build/source/utils/asymptote/doc/asy.1
new file mode 100644
index 00000000000..0e3cfed6d67
--- /dev/null
+++ b/Build/source/utils/asymptote/doc/asy.1
@@ -0,0 +1,250 @@
+.\" Hey, EMACS: -*- nroff -*-
+.TH ASY 1 "1 Dec 2004"
+.SH NAME
+asy \- Asymptote: a script-based vector graphics language
+.SH SYNOPSIS
+.B asy
+.RI [ options ]
+.RI [ file \ ...]
+.SH DESCRIPTION
+\fBAsymptote\fP is a powerful descriptive vector graphics language for
+technical drawings, inspired by MetaPost but with an improved C++-like syntax.
+Asymptote provides for figures the same high-quality level of typesetting that
+LaTeX does for scientific text.
+.SH OPTIONS
+If no arguments are given, Asymptote runs in interactive mode.
+.PP
+If "\-" is given as the file argument, Asymptote reads from standard input.
+.PP
+A summary of options is included below. The effect of most options
+can be negated by prepending
+.B no
+to the option name.
+Default values for most options may also be entered in the
+file
+.B .asy/config.asy
+in the user's home directory using the long form:
+.PP
+ import settings;
+ batchView=true;
+.PP
+For a complete
+description, see the Info files.
+.TP
+.B \-V,\-View
+View output; command-line only.
+.TP
+.B \-a,\-align C|B|T|Z
+Center, Bottom, Top, or Zero page alignment [Center].
+.TP
+.B \-antialias n
+Antialiasing width for rasterized output [2].
+.TP
+.B \-auto3D
+Automatically activate 3D scene [true].
+.TP
+.B \-autoimport string
+Module to automatically import.
+.TP
+.B \-autoplain
+Enable automatic importing of plain [true].
+.TP
+.B \-autorotate
+Enable automatic PDF page rotation [false].
+.TP
+.B \-batchMask
+Mask fpu exceptions in batch mode [false].
+.TP
+.B \-batchView
+View output in batch mode [false].
+.TP
+.B \-bw
+Convert all colors to black and white [false].
+.TP
+.B \-cd directory
+Set current directory; command-line only.
+.TP
+.B \-cmyk
+Convert rgb colors to cmyk [false].
+.TP
+.B \-c,\-command string
+Command to autoexecute.
+.TP
+.B \-compact
+Conserve memory at the expense of speed [false].
+.TP
+.B \-d,\-debug
+Enable debugging messages [false].
+.TP
+.B \-divisor n
+Garbage collect using purge(divisor=n) [2].
+.TP
+.B \-embed
+Embed rendered preview image [true].
+.TP
+.B \-exitonEOF
+Exit interactive mode on EOF [true].
+.TP
+.B \-fitscreen
+Fit rendered image to screen [true].
+.TP
+.B \-globalwrite
+Allow write to other directory [false].
+.TP
+.B \-gray
+Convert all colors to grayscale [false].
+.TP
+.B \-h,\-help
+Show summary of options; command-line only.
+.TP
+.B \-historylines n
+Retain n lines of history [1000].
+.TP
+.B \-iconify
+Iconify rendering window [false].
+.TP
+.B \-inlineimage
+Generate inline embedded image [false].
+.TP
+.B \-inlinetex
+Generate inline TeX code [false].
+.TP
+.B \-interactiveMask
+Mask fpu exceptions in interactive mode [true].
+.TP
+.B \-interactiveView
+View output in interactive mode [true].
+.TP
+.B \-interactiveWrite
+Write expressions entered at the prompt to stdout [true].
+.TP
+.B \-k,\-keep
+Keep intermediate files [false].
+.TP
+.B \-keepaux
+Keep intermediate LaTeX .aux files [false].
+.TP
+.B \-level n
+Postscript level [3].
+.TP
+.B \-l,\-listvariables
+List available global functions and variables [false].
+.TP
+.B \-localhistory
+Use a local interactive history file [false].
+.TP
+.B \-m,\-mask
+Mask fpu exceptions; command-line only.
+.TP
+.B \-maxtile pair
+Maximum rendering tile size [(0,0)].
+.TP
+.B \-maxviewport pair
+Maximum viewport size [(2048,2048)].
+.TP
+.B \-multiline
+Input code over multiple lines at the prompt [false].
+.TP
+.B \-multipleView
+View output from multiple batch-mode files [false].
+.TP
+.B \-multisample n
+Multisampling width for screen images [4].
+.TP
+.B \-O,\-offset pair
+PostScript offset [(0,0)].
+.TP
+.B \-f,\-outformat format
+Convert each output file to specified format.
+.TP
+.B \-o,\-outname name
+Alternative output directory/filename.
+.TP
+.B \-p,\-parseonly
+Parse file [false].
+.TP
+.B \-pdfreload
+Automatically reload document in pdfviewer [false].
+.TP
+.B \-pdfreloaddelay usec
+Delay before attempting initial pdf reload [750000].
+.TP
+.B \-position pair
+Initial 3D rendering screen position [(0,0)].
+.TP
+.B \-prc
+Embed 3D PRC graphics in PDF output [true].
+.TP
+.B \-prompt string
+Prompt [> ].
+.TP
+.B \-prompt2 string
+Continuation prompt for multiline input [..].
+.TP
+.B \-q,\-quiet
+Suppress welcome message [false].
+.TP
+.B \-render n
+Render 3D graphics using n pixels per bp (-1=auto) [-1].
+.TP
+.B \-rgb
+Convert cmyk colors to rgb [false].
+.TP
+.B \-safe
+Disable system call [true].
+.TP
+.B \-scroll n
+Scroll standard output n lines at a time [0].
+.TP
+.B \-tabcompletion
+Interactive prompt auto-completion [true].
+-tex engine latex|pdflatex|xelatex|tex|pdftex|none [latex]
+.TP
+.B \-thick
+Render thick 3D lines [true].
+.TP
+.B \-thin
+Render thin 3D lines [true].
+.TP
+.B \-threads
+Use POSIX threads for 3D rendering [true].
+.TP
+.B \-toolbar
+Show 3D toolbar in PDF output [true].
+.TP
+.B \-s,\-translate
+Show translated virtual machine code [false].
+.TP
+.B \-twice
+Run LaTeX twice (to resolve references) [false].
+.TP
+.B \-twosided
+Use two-sided 3D lighting model for rendering [true].
+.TP
+.B \-u,\-user string
+General purpose user string.
+.TP
+.B \-v,\-verbose
+Increase verbosity level [0].
+.TP
+.B \-version
+Show version; command-line only.
+.TP
+.B \-wait
+Wait for child processes to finish before exiting [false].
+.TP
+.B \-where
+Show where listed variables are declared [false].
+.TP
+.B \-xformat format
+GUI deconstruction format [png].
+
+.SH SEE ALSO
+Asymptote is documented fully in the asymptote Info page.
+The manual can also be accessed in interactive mode with the "help" command.
+
+.SH AUTHOR
+Asymptote was written by Andy Hammerlindl, John Bowman, and Tom Prince.
+.PP
+This manual page was written by Hubert Chan for the Debian project (but may
+be used by others).
diff --git a/Build/source/utils/asymptote/doc/asy.1.begin b/Build/source/utils/asymptote/doc/asy.1.begin
new file mode 100644
index 00000000000..1a2232968ee
--- /dev/null
+++ b/Build/source/utils/asymptote/doc/asy.1.begin
@@ -0,0 +1,32 @@
+.\" Hey, EMACS: -*- nroff -*-
+.TH ASY 1 "1 Dec 2004"
+.SH NAME
+asy \- Asymptote: a script-based vector graphics language
+.SH SYNOPSIS
+.B asy
+.RI [ options ]
+.RI [ file \ ...]
+.SH DESCRIPTION
+\fBAsymptote\fP is a powerful descriptive vector graphics language for
+technical drawings, inspired by MetaPost but with an improved C++-like syntax.
+Asymptote provides for figures the same high-quality level of typesetting that
+LaTeX does for scientific text.
+.SH OPTIONS
+If no arguments are given, Asymptote runs in interactive mode.
+.PP
+If "\-" is given as the file argument, Asymptote reads from standard input.
+.PP
+A summary of options is included below. The effect of most options
+can be negated by prepending
+.B no
+to the option name.
+Default values for most options may also be entered in the
+file
+.B .asy/config.asy
+in the user's home directory using the long form:
+.PP
+ import settings;
+ batchView=true;
+.PP
+For a complete
+description, see the Info files.
diff --git a/Build/source/utils/asymptote/doc/asy.1.end b/Build/source/utils/asymptote/doc/asy.1.end
new file mode 100644
index 00000000000..24586d9d403
--- /dev/null
+++ b/Build/source/utils/asymptote/doc/asy.1.end
@@ -0,0 +1,10 @@
+
+.SH SEE ALSO
+Asymptote is documented fully in the asymptote Info page.
+The manual can also be accessed in interactive mode with the "help" command.
+
+.SH AUTHOR
+Asymptote was written by Andy Hammerlindl, John Bowman, and Tom Prince.
+.PP
+This manual page was written by Hubert Chan for the Debian project (but may
+be used by others).
diff --git a/Build/source/utils/asymptote/doc/asycolors.sty b/Build/source/utils/asymptote/doc/asycolors.sty
new file mode 100644
index 00000000000..31031c730fd
--- /dev/null
+++ b/Build/source/utils/asymptote/doc/asycolors.sty
@@ -0,0 +1,72 @@
+\usepackage{color}
+\definecolor{cyan}{cmyk}{1,0,0,0}
+\definecolor{magenta}{cmyk}{0,1,0,0}
+\definecolor{yellow}{cmyk}{0,0,1,0}
+\definecolor{black}{cmyk}{0,0,0,1}
+
+\definecolor{white}{cmyk}{0,0,0,0}
+\definecolor{gray}{cmyk}{0,0,0,0.5}
+
+\definecolor{red}{cmyk}{0,1,1,0}
+\definecolor{green}{cmyk}{1,0,1,0}
+\definecolor{blue}{cmyk}{1,1,0,0}
+
+\definecolor{palered}{cmyk}{0,0.25,0.25,0}
+\definecolor{palegreen}{cmyk}{0.25,0,0.25,0}
+\definecolor{paleblue}{cmyk}{0.25,0.25,0,0}
+\definecolor{palecyan}{cmyk}{0.25,0,0,0}
+\definecolor{palemagenta}{cmyk}{0,0.25,0,0}
+\definecolor{paleyellow}{cmyk}{0,0,0.25,0}
+\definecolor{palegray}{cmyk}{0,0,0,0.05}
+\definecolor{lightred}{cmyk}{0,0.5,0.5,0}
+\definecolor{lightgreen}{cmyk}{0.5,0,0.5,0}
+\definecolor{lightblue}{cmyk}{0.5,0.5,0,0}
+\definecolor{lightcyan}{cmyk}{0.5,0,0,0}
+\definecolor{lightmagenta}{cmyk}{0,0.5,0,0}
+\definecolor{lightyellow}{cmyk}{0,0,0.5,0}
+\definecolor{lightgray}{cmyk}{0,0,0,0.1}
+\definecolor{mediumred}{cmyk}{0,0.75,0.75,0}
+\definecolor{mediumgreen}{cmyk}{0.75,0,0.75,0}
+\definecolor{mediumblue}{cmyk}{0.75,0.75,0,0}
+\definecolor{mediumcyan}{cmyk}{0.75,0,0,0}
+\definecolor{mediummagenta}{cmyk}{0,0.75,0,0}
+\definecolor{mediumyellow}{cmyk}{0,0,0.75,0}
+\definecolor{mediumgray}{cmyk}{0,0,0,0.25}
+\definecolor{heavyred}{cmyk}{0,1,1,0.25}
+\definecolor{heavygreen}{cmyk}{1,0,1,0.25}
+\definecolor{heavyblue}{cmyk}{1,1,0,0.25}
+\definecolor{heavycyan}{cmyk}{1,0,0,0.25}
+\definecolor{heavymagenta}{cmyk}{0,1,0,0.25}
+\definecolor{lightolive}{cmyk}{0,0,1,0.25}
+\definecolor{heavygray}{cmyk}{0,0,0,0.75}
+\definecolor{deepred}{cmyk}{0,1,1,0.5}
+\definecolor{deepgreen}{cmyk}{1,0,1,0.5}
+\definecolor{deepblue}{cmyk}{1,1,0,0.5}
+\definecolor{deepcyan}{cmyk}{1,0,0,0.5}
+\definecolor{deepmagenta}{cmyk}{0,1,0,0.5}
+\definecolor{olive}{cmyk}{0,0,1,0.5}
+\definecolor{deepgray}{cmyk}{0,0,0,0.9}
+\definecolor{darkred}{cmyk}{0,1,1,0.75}
+\definecolor{darkgreen}{cmyk}{1,0,1,0.75}
+\definecolor{darkblue}{cmyk}{1,1,0,0.75}
+\definecolor{darkcyan}{cmyk}{1,0,0,0.75}
+\definecolor{darkmagenta}{cmyk}{0,1,0,0.75}
+\definecolor{darkolive}{cmyk}{0,0,1,0.75}
+\definecolor{darkgray}{cmyk}{0,0,0,0.95}
+\definecolor{orange}{cmyk}{0,0.5,1,0}
+\definecolor{fuchsia}{cmyk}{0,1,0.5,0}
+\definecolor{chartreuse}{cmyk}{0.5,0,1,0}
+\definecolor{springgreen}{cmyk}{1,0,0.5,0}
+\definecolor{purple}{cmyk}{0.5,1,0,0}
+\definecolor{royalblue}{cmyk}{1,0.5,0,0}
+\definecolor{salmon}{cmyk}{0,0.5,0.5,0}
+\definecolor{brown}{cmyk}{0,1,1,0.5}
+\definecolor{darkbrown}{cmyk}{0,1,1,0.75}
+\definecolor{pink}{cmyk}{0,0.25,0,0}
+\definecolor{palegrey}{cmyk}{0,0,0,0.05}
+\definecolor{lightgrey}{cmyk}{0,0,0,0.1}
+\definecolor{mediumgrey}{cmyk}{0,0,0,0.25}
+\definecolor{grey}{cmyk}{0,0,0,0.5}
+\definecolor{heavygrey}{cmyk}{0,0,0,0.5}
+\definecolor{deepgrey}{cmyk}{0,0,0,0.9}
+\definecolor{darkgrey}{cmyk}{0,0,0,0.95}
diff --git a/Build/source/utils/asymptote/doc/asymptote.sty b/Build/source/utils/asymptote/doc/asymptote.sty
new file mode 100644
index 00000000000..487ddaaafac
--- /dev/null
+++ b/Build/source/utils/asymptote/doc/asymptote.sty
@@ -0,0 +1,271 @@
+%%% Asymptote style file for LaTeX
+%%% Contributed by Tom Prince 14 May 2003
+%%% Modified by John Bowman
+%%% Adapted from comment.sty (Under GPL v2)
+
+\ProvidesPackage{asymptote}[2009/03/29 v1.06 Asymptote style file for LaTeX]
+\RequirePackage{keyval}
+\RequirePackage{ifthen}
+\newif\ifASYinline
+\DeclareOption{inline}{\ASYinlinetrue}
+\ProcessOptions*
+
+% Work around jobname bug in MiKTeX 2.5 and 2.6:
+% Turn stars in file names (resulting from spaces, etc.) into minus signs
+\def\fixstar#1*#2\relax{\def\argtwo{#2}\ifx\argtwo\empty\gdef\Jobname{#1}\else
+\fixstar#1-#2\relax\fi}
+\expandafter\fixstar\jobname*\relax
+
+\RequirePackage{color,graphicx}
+
+\def\makeinnocent#1{\catcode`#1=12 }
+\def\csarg#1#2{\expandafter#1\csname#2\endcsname}
+\newwrite\AsyStream
+\newread\AsyTestStream
+\newread\AsyTestTeXStream
+\def\AsyFile{\jobname.asy}
+
+\openin\AsyTestStream=\jobname_.pre
+\ifeof\AsyTestStream
+\else
+\input \jobname_.pre
+\fi
+\closein\AsyTestStream%
+
+\immediate\openout\AsyStream=\AsyFile
+\immediate\write\AsyStream{if(!settings.multipleView)}%
+\immediate\write\AsyStream{ settings.batchView=false;}%
+
+\newif\ifASYattach
+\newif\ifASYtex
+
+\newif\ifASYPDF
+\ifx\pdfoutput\undefined
+\else
+\ifcase\pdfoutput
+\else
+\ASYPDFtrue
+\fi
+\fi
+\ifx\XeTeXversion\undefined
+\else
+\ASYPDFtrue
+\immediate\write\AsyStream{settings.texcommand="xelatex";}%
+\fi
+\ifASYPDF
+\immediate\write\AsyStream{settings.tex="pdflatex";}%
+\fi
+
+\ifASYinline
+\immediate\write\AsyStream{settings.inlinetex=true;}%
+\immediate\write\AsyStream{deletepreamble();}%
+\fi
+
+\newbox\ASYbox
+\newcounter{asy}
+
+\def\ProcessAsymptote#1% start it all off
+{\begingroup
+ \def\CurrentAsymptote{#1}%
+ \let\do\makeinnocent \dospecials
+ \makeinnocent\^^L% and whatever other special cases
+ \endlinechar`\^^M \catcode`\^^M=12 \xAsymptote}
+{\catcode`\^^M=12 \endlinechar=-1 %
+ \gdef\xAsymptote{%
+ \expandafter\ProcessAsymptoteLine}
+ \gdef\ProcessAsymptoteLine#1^^M{\def\test{#1}
+ \csarg\ifx{End\CurrentAsymptote Test}\test
+ \edef\next{\noexpand\EndOfAsymptote{\CurrentAsymptote}}%
+ \else \ThisAsymptote{#1}\let\next\ProcessAsymptoteLine
+ \fi \next}
+}
+
+\def\ASYstringmeaning#1{\expandafter\ASYgobblearrow\meaning#1}
+\def\ASYstringcsnoescape#1{\expandafter\ASYgobbleescape\string#1}
+{\escapechar-1
+ \expandafter\expandafter\expandafter\gdef
+ \expandafter\expandafter\expandafter\ASYgobblearrow
+ \expandafter\string\csname macro:->\endcsname{}
+}
+\def\ASYgobbleescape#1{\ifnum`\\=`#1 \else #1\fi}
+
+\def\WriteAsyLine#1{\def\ASYtmp{#1}%
+ \immediate\write\AsyStream{\ASYstringmeaning\ASYtmp}}
+
+\def\gedefappend#1#2{%
+ \toks@ = \expandafter{#1}%
+ \global\edef#1{\the\toks@ #2}%
+}%
+\def\globalASYdefs{}
+\def\WriteGlobalAsyLine#1{\def\ASYtmp{#1^^J}%
+\gedefappend\globalASYdefs{\ASYstringmeaning\ASYtmp}}
+
+\def\EndOfAsymptote#1{\endgroup\end{#1}%
+ \csname After#1Asymptote\endcsname}
+\def\AsymptoteEndDef#1{{\escapechar=-1\relax
+ \csarg\xdef{End#1Test}{\string\\end\string\{#1\string\}}%
+ }}
+
+\def\AfterasyAsymptote{%
+ \ifx\ASYwidth\empty
+ \ifx\ASYheight\empty
+ \else
+ \immediate\write\AsyStream{size(0,\ASYheight);}%
+ \fi
+ \else
+ \ifx\ASYheight\empty
+ \immediate\write\AsyStream{size(\ASYwidth,0);}%
+ \else
+ \immediate\write\AsyStream{size(\ASYwidth,\ASYheight);}%
+ \fi
+ \fi
+ \ASYtexfalse
+ \ifASYattach
+ \def\ASYdefaultviewportwidth{0}
+ \else
+ \def\ASYdefaultviewportwidth{\the\linewidth}
+ \ifASYinline
+ \ASYtextrue
+ \fi
+ \fi
+ \ifx\ASYviewportwidth\empty
+ \ifx\ASYviewportheight\empty
+ \else
+ \immediate\write\AsyStream{viewportsize=(0,\ASYviewportheight);}%
+ \fi
+ \else
+ \ifx\ASYviewportheight\empty
+ \immediate\write\AsyStream{viewportsize=(\ASYviewportwidth,0);}%
+ \else
+ \immediate\write%
+ \AsyStream{viewportsize=(\ASYviewportwidth,\ASYviewportheight);}%
+ \fi
+ \fi
+ \gdef\ASYwidth{}
+ \gdef\ASYheight{}
+ \gdef\ASYviewportwidth{\ASYdefaultviewportwidth}
+ \gdef\ASYviewportheight{}
+ \immediate\write\AsyStream{\@charrb);}%
+ \immediate\write\AsyStream{// End of Asymptote Figure \the\c@asy}%
+ \ifASYtex
+ \openin\AsyTestStream=\Jobname-\the\c@asy_.tex
+ \else
+ \ifASYPDF
+ \openin\AsyTestStream=\Jobname-\the\c@asy.pdf
+ \else
+ \openin\AsyTestStream=\Jobname-\the\c@asy.eps
+ \fi
+ \fi
+ \ifeof\AsyTestStream
+ \ifASYtex
+ \PackageWarning{asymptote}{file \Jobname-\the\c@asy_.tex does not exist}%
+ \else
+ \openin\AsyTestTeXStream=\Jobname-\the\c@asy_.tex
+ \ifeof\AsyTestTeXStream
+ \ifASYPDF
+ \PackageWarning{asymptote}{file \Jobname-\the\c@asy.pdf does not exist}%
+ \else
+ \PackageWarning{asymptote}{file \Jobname-\the\c@asy.eps does not exist}%
+ \fi
+ \else
+ \catcode`:=12
+ \input \Jobname-\the\c@asy_.tex%
+ \fi
+ \closein\AsyTestTeXStream%
+ \fi
+ \closein\AsyTestStream%
+ \else
+ \closein\AsyTestStream%
+ \ifASYtex
+ \catcode`:=12
+ \input \Jobname-\the\c@asy_.tex%
+ \else
+ \ifASYattach
+ \ifASYPDF
+ \openin\AsyTestStream=\Jobname-\the\c@asy-0.pdf
+ \fi
+ \ifeof\AsyTestStream
+ \setbox\ASYbox=\hbox{\includegraphics{\Jobname-\the\c@asy}}%
+ \else
+ \setbox\ASYbox=\hbox{\includegraphics{\Jobname-\the\c@asy-0}}%
+ \fi
+ \textattachfile{\Jobname-\the\c@asy.pdf}{\phantom{\copy\ASYbox}}%
+ \vskip-\ht\ASYbox%
+ \indent%
+ \box\ASYbox%
+ \closein\AsyTestStream%
+ \else
+ \includegraphics{\Jobname-\the\c@asy}%
+ \fi
+ \fi
+ \fi
+ \global\ASYattachfalse
+ \relax%
+ \endgroup}
+\gdef\ASYwidth{}%
+\define@key{ASYkeys}{width}{%
+ \gdef\ASYwidth{#1}%
+}
+\gdef\ASYheight{}%
+\define@key{ASYkeys}{height}{%
+ \gdef\ASYheight{#1}%
+}
+\gdef\ASYviewportwidth{\ASYdefaultviewportwidth}%
+\define@key{ASYkeys}{viewportwidth}{%
+ \gdef\ASYviewportwidth{#1}%
+}
+\gdef\ASYviewportheight{}%
+\define@key{ASYkeys}{viewportheight}{%
+ \gdef\ASYviewportheight{#1}%
+}
+\define@key{ASYkeys}{attach}[true]{%
+ \ifthenelse{\equal{#1}{true}}{\global\ASYattachtrue}{\global\ASYattachfalse}%
+}
+\newcommand\asy[1][]{%
+ \begingroup
+ \let\par\empty
+ \stepcounter{asy}%
+ \setkeys{ASYkeys}{#1}%
+ \immediate\write\AsyStream{}%
+ \immediate\write\AsyStream{// Beginning of Asymptote Figure \the\c@asy}%
+ \immediate\write\AsyStream{eval(quote\@charlb}%
+ \immediate\write\AsyStream{defaultfilename='\Jobname-\the\c@asy';}%
+ \immediate\write\AsyStream{if(settings.render < 0) settings.render=4;}%
+ \ifASYattach
+ \immediate\write\AsyStream{settings.inlineimage=false;}%
+ \immediate\write\AsyStream{settings.embed=false;}%
+ \immediate\write\AsyStream{settings.outformat='pdf';}%
+ \immediate\write\AsyStream{settings.toolbar=true;}%
+ \else
+ \immediate\write\AsyStream{settings.inlineimage=true;}%
+ \immediate\write\AsyStream{settings.embed=true;}%
+ \immediate\write\AsyStream{settings.outformat='';}%
+ \immediate\write\AsyStream{settings.toolbar=false;}%
+ \fi
+ \immediate\write\AsyStream{\globalASYdefs}%
+ \let\ThisAsymptote\WriteAsyLine%
+ \ProcessAsymptote{asy}%
+}
+\AsymptoteEndDef{asy}
+\def\asydef{%
+ \let\ThisAsymptote\WriteGlobalAsyLine%
+ \ProcessAsymptote{asydef}}
+\AsymptoteEndDef{asydef}
+\def\AfterasydefAsymptote{}
+
+\AtEndDocument{\immediate\closeout\AsyStream}
+
+\newcommand{\ASYanimategraphics}[5][]{%
+\openin\AsyTestStream=_#3.pdf
+\ifeof\AsyTestStream%
+\else%
+\animategraphics[{#1}]{#2}{_#3}{#4}{#5}%
+\fi%
+}
+
+\def\Asymptote{{\tt Asymptote}}
+
+%%% Local Variables:
+%%% mode: latex
+%%% TeX-master: "shared"
+%%% End:
diff --git a/Build/source/utils/asymptote/doc/asymptote.texi b/Build/source/utils/asymptote/doc/asymptote.texi
new file mode 100644
index 00000000000..46043c85867
--- /dev/null
+++ b/Build/source/utils/asymptote/doc/asymptote.texi
@@ -0,0 +1,9131 @@
+\input texinfo @c -*-texinfo-*-
+@setfilename asymptote.info
+@settitle Asymptote: the Vector Graphics Language
+@include version.texi
+@finalout
+
+@copying
+This file documents @code{Asymptote}, version @value{VERSION}.
+
+@url{http://asymptote.sourceforge.net}
+
+Copyright @copyright{} 2004-9 Andy Hammerlindl, John Bowman, and Tom Prince.
+
+@quotation
+Permission is granted to copy, distribute and/or modify this document
+under the terms of the @acronym{GNU} Lesser General Public License (see the
+file LICENSE in the top-level source directory).
+
+@end quotation
+@end copying
+
+@dircategory Languages
+@direntry
+* asymptote: (asymptote). Vector graphics language.
+@end direntry
+
+@titlepage
+@title Asymptote: the Vector Graphics Language
+@subtitle For version @value{VERSION}
+@sp 1
+@center @image{logo}
+
+@page
+@vskip 0pt plus 1filll
+@insertcopying
+
+@end titlepage
+
+@c So the toc is printed at the start.
+@contents
+
+@ifnottex
+@node Top
+@top Asymptote
+
+@insertcopying
+@end ifnottex
+
+@menu
+* Description:: What is @code{Asymptote}?
+* Installation:: Downloading and installing
+* Tutorial:: Getting started
+* Drawing commands:: Four primitive graphics commands
+* Programming:: The @code{Asymptote} vector graphics language
+* LaTeX usage:: Embedding @code{Asymptote} commands within @code{LaTeX}
+* Base modules:: Base modules shipped with @code{Asymptote}
+* Options:: Command-line options
+* Interactive mode:: Typing @code{Asymptote} commands interactively
+* GUI:: Graphical user interface
+* PostScript to Asymptote:: @code{Asymptote} backend to @code{pstoedit}
+* Help:: Where to get help and submit bug reports
+* Debugger:: Squish those bugs!
+* Credits:: Contributions and acknowledgments
+* Index:: General index
+
+@detailmenu
+ --- The Detailed Node Listing ---
+
+Installation
+
+* UNIX binary distributions:: Prebuilt @code{UNIX} binaries
+* MacOS X binary distributions:: Prebuilt @code{MacOS X} binaries
+* Microsoft Windows:: Prebuilt @code{Microsoft Windows} binary
+* Configuring:: Configuring @code{Asymptote} for your system
+* Search paths:: Where @code{Asymptote} looks for your files
+* Compiling from UNIX source:: Building @code{Asymptote} from scratch
+* Editing modes:: Convenient @code{emacs} and @code{vim} modes
+* Subversion::
+* Uninstall:: Goodbye, @code{Asymptote}!
+
+Drawing commands
+
+* draw:: Draw a path on a picture or frame
+* fill:: Fill a cyclic path on a picture or frame
+* clip:: Clip a picture or frame to a cyclic path
+* label:: Label a point on a picture
+
+Programming
+
+* Data types:: void, bool, int, real, pair, triple, string
+* Paths and guides::
+* Pens:: Colors, line types, line widths, font sizes
+* Transforms:: Affine transforms
+* Frames and pictures:: Canvases for immediate and deferred drawing
+* Files:: Reading and writing your data
+* Variable initializers:: Initialize your variables
+* Structures:: Organize your data
+* Operators:: Arithmetic and logical operators
+* Implicit scaling:: Avoiding those ugly *s
+* Functions:: Traditional and high-order functions
+* Arrays:: Dynamic vectors
+* Casts:: Implicit and explicit casts
+* Import:: Importing external @code{Asymptote} packages
+* Static:: Where to allocate your variable?
+
+Operators
+
+* Arithmetic & logical:: Basic mathematical operators
+* Self & prefix operators:: Increment and decrement
+* User-defined operators:: Overloading operators
+
+Functions
+
+* Default arguments:: Default values can appear anywhere
+* Named arguments:: Assigning function arguments by keyword
+* Rest arguments:: Functions with a variable number of arguments
+* Mathematical functions:: Standard libm functions
+
+
+Arrays
+
+* Slices:: Python-style array slices
+
+Base modules
+
+* plain:: Default @code{Asymptote} base file
+* simplex:: Linear programming: simplex method
+* math:: Extend @code{Asymptote}'s math capabilities
+* interpolate:: Interpolation routines
+* geometry:: Geometry routines
+* trembling:: Wavy lines
+* stats:: Statistics routines and histograms
+* patterns:: Custom fill and draw patterns
+* markers:: Custom path marker routines
+* tree:: Dynamic binary search tree
+* binarytree:: Binary tree drawing module
+* drawtree:: Tree drawing module
+* syzygy:: Syzygy and braid drawing module
+* feynman:: Feynman diagrams
+* roundedpath:: Round the sharp corners of paths
+* animation:: Embedded @acronym{PDF} and @acronym{MPEG} movies
+* embed:: Embedding movies, sounds, and 3D objects
+* slide:: Making presentations with @code{Asymptote}
+* MetaPost:: @code{MetaPost} compatibility routines
+* unicode:: Accept @code{unicode} (UTF-8) characters
+* latin1:: Accept @code{ISO 8859-1} characters
+* babel:: Interface to @code{LaTeX} @code{babel} package
+* labelpath:: Drawing curved labels
+* labelpath3:: Drawing curved labels in 3D
+* annotate:: Annotate your @acronym{PDF} files
+* CAD:: 2D CAD pen and measurement functions (DIN 15)
+* graph:: 2D linear & logarithmic graphs
+* palette:: Color density images and palettes
+* three:: 3D vector graphics
+* obj:: 3D obj files
+* graph3:: 3D linear & logarithmic graphs
+* grid3:: 3D grids
+* solids:: 3D solid geometry
+* tube:: 3D rotation minimizing tubes
+* flowchart:: Flowchart drawing routines
+* contour:: Contour lines
+* contour3:: Contour surfaces
+* slopefield:: Slope fields
+
+
+Graphical User Interface
+
+* GUI Installation:: Installing @code{xasy}
+* GUI Usage::
+
+@end detailmenu
+@end menu
+
+@node Description
+@chapter Description
+@cindex description
+
+@code{Asymptote} is a powerful descriptive vector graphics language that
+provides a mathematical coordinate-based framework for technical drawings.
+Labels and equations are typeset with @code{LaTeX}, for overall document
+consistency, yielding the same high-quality level of typesetting that
+@code{LaTeX} provides for scientific text. By default it produces
+@code{PostScript} output, but it can also generate any format that the
+@code{ImageMagick} package can produce.
+
+A major advantage of @code{Asymptote} over other graphics packages is
+that it is a high-level programming language, as opposed to just a graphics
+program: it can therefore exploit the best features of the script
+(command-driven) and graphical-user-interface (@acronym{GUI}) methods for
+producing figures. The rudimentary @acronym{GUI} @code{xasy} included with the
+package allows one to move script-generated objects
+around. To make @code{Asymptote} accessible to the average user, this
+@acronym{GUI} is currently being developed into a full-fledged interface
+that can generate objects directly. However, the script portion of the language
+is now ready for general use by users who are willing to learn a few
+simple @code{Asymptote} graphics commands (@pxref{Drawing commands}).
+
+@code{Asymptote} is mathematically oriented (e.g.@ one can
+use complex multiplication to rotate a vector) and uses
+@code{LaTeX} to do the
+typesetting of labels. This is an important feature for scientific
+applications. It was inspired by an earlier drawing program (with a weaker
+syntax and capabilities) called @code{MetaPost}.
+
+The @code{Asymptote} vector graphics language provides:
+
+@itemize @bullet
+@item a standard for typesetting mathematical figures, just
+as @TeX{}/@code{LaTeX} is the de-facto standard for typesetting equations.
+
+@item @code{LaTeX} typesetting of labels, for overall document consistency;
+
+@item a natural coordinate-based framework for technical drawings,
+inspired by @code{MetaPost}, with a much cleaner, powerful C++-like programming
+syntax;
+
+@item compilation of figures into virtual machine code for speed, without
+sacrificing portability;
+
+@item the power of a script-based language coupled to the convenience of
+a @acronym{GUI};
+
+@item customization using its own C++-like graphics programming language;
+
+@item sensible defaults for graphical features, with the ability to override;
+
+@item a high-level mathematically oriented interface to the
+@code{PostScript} language for vector graphics, including affine transforms
+and complex variables;
+
+@item functions that can create new (anonymous) functions;
+
+@item deferred drawing that uses the simplex method to solve overall size
+constraint issues between fixed-sized objects (labels and arrowheads) and
+objects that should scale with figure size;
+
+@end itemize
+
+Many of the features of @code{Asymptote} are written in the
+@code{Asymptote} language itself. While the stock version of
+@code{Asymptote} is designed for mathematics typesetting needs, one can
+write @code{Asymptote} modules that tailor it to specific
+applications. A scientific graphing module has already been written
+(@pxref{graph}). Examples of @code{Asymptote} code and output,
+including animations, are available at
+@quotation
+@url{http://asymptote.sourceforge.net/gallery/}.
+@end quotation
+@noindent
+Links to many external resources, including an excellent user-written
+@code{Asymptote} tutorial can be found at
+@quotation
+@url{http://asymptote.sourceforge.net/links.html}.
+@end quotation
+
+@node Installation
+@chapter Installation
+@cindex installation
+
+@menu
+* UNIX binary distributions:: Prebuilt @code{UNIX} binaries
+* MacOS X binary distributions:: Prebuilt @code{MacOS X} binaries
+* Microsoft Windows:: Prebuilt @code{Microsoft Windows} binary
+* Configuring:: Configuring @code{Asymptote} for your system
+* Search paths:: Where @code{Asymptote} looks for your files
+* Compiling from UNIX source:: Building @code{Asymptote} from scratch
+* Editing modes:: Convenient @code{emacs} and @code{vim} modes
+* Subversion::
+* Uninstall:: Goodbye, @code{Asymptote}!
+@end menu
+
+After following the instructions for your specific distribution,
+please see also @ref{Configuring}.
+
+@noindent
+We recommend subscribing to new release announcements at
+@quotation
+@url{http://freshmeat.net/projects/asy}
+@end quotation
+@noindent
+Users may also wish to monitor the @code{Asymptote} forum:
+@quotation
+@url{http://sourceforge.net/forum/monitor.php?forum_id=409349}
+@end quotation
+@noindent
+
+@node UNIX binary distributions
+@section UNIX binary distributions
+@cindex UNIX binary distributions
+
+@cindex @acronym{RPM}
+@cindex @code{tgz}
+We release both @code{tgz} and @acronym{RPM} binary distributions of
+@code{Asymptote}. The root user can install the @code{Linux i386} @code{tgz}
+distribution of version @code{x.xx} of @code{Asymptote} with the commands:
+@verbatim
+tar -C / -zxf asymptote-x.xx.i386.tgz
+texhash
+@end verbatim
+@noindent
+The @code{texhash} command, which installs LaTeX style files, is optional.
+The executable file will be @code{/usr/local/bin/asy}) and example code
+will be installed by default in @code{@value{Datadir}/doc/asymptote/examples}.
+
+@noindent
+@cindex Fedora
+Fedora users can easily install the most recent version of @code{Asymptote}
+with the command
+@verbatim
+yum --enablerepo=rawhide install asymptote
+@end verbatim
+
+@cindex Debian
+@noindent
+To install the latest version of @code{Asymptote} on a Debian-based distribution
+(e.g.@ Ubuntu, Mepis, Linspire) follow the instructions for compiling
+from @code{UNIX} source (@pxref{Compiling from UNIX source}).
+Alternatively, Debian users can install one of Hubert Chan's
+prebuilt @code{Asymptote} binaries from
+@quotation
+@url{http://ftp.debian.org/debian/pool/main/a/asymptote}
+@end quotation
+
+@node MacOS X binary distributions
+@section MacOS X binary distributions
+@cindex @code{MacOS X} binary distributions
+@code{MacOS X} users can either compile the @code{UNIX} source code
+(@pxref{Compiling from UNIX source})
+or install the contributed @code{Asymptote} binary available at
+
+@url{http://www.hmug.org/pub/MacOS_X/X/Applications/Publishing/asymptote/}
+
+@noindent
+Because these preconfigured binary distributions have
+strict architecture and library dependencies that many installations do
+not satisfy, we recommend installing @code{Asymptote} directly from the
+official source:
+
+@url{http://sourceforge.net/project/showfiles.php?group_id=120000}
+
+@noindent
+Note that many @code{MacOS X} (and FreeBSD) systems inexplicably ship
+with an extremely old @acronym{GNU} @code{readline} version (4.1,
+dated 21 March 2000). For full interactive functionality,
+@code{readline} version 4.2 or later (16 April 2001) is required.
+
+@node Microsoft Windows
+@section Microsoft Windows
+@cindex Microsoft Windows
+Users of the @code{Microsoft Windows} operating system can install the
+self-extracting @code{Asymptote} executable @code{asymptote-x.xx-setup.exe},
+where @code{x.xx} denotes the latest version.
+
+A working @TeX{} implementation (such as the one available at
+@url{http://www.miktex.org}) will be required to typeset labels.
+You will also need to install @code{GPL Ghostscript} from
+@url{http://sourceforge.net/projects/ghostscript/}.
+To view the default @code{PostScript} output, you can install the
+program @code{gsview} available from
+@url{http://www.cs.wisc.edu/~ghost/gsview/}.
+
+The @code{ImageMagick} package from
+
+@url{http://www.imagemagick.org/script/binary-releases.php}
+
+@noindent
+is required to support output formats other than @acronym{EPS} and
+@acronym{PDF} (@pxref{convert}).
+The @code{Python} interpreter from @url{http://www.python.org} is only required
+if you wish to try out the graphical user interface (@pxref{GUI}).
+
+@noindent
+Example code will be installed by default in the @code{examples}
+subdirectory of the installation directory (by default,
+@code{C:\Program Files\Asymptote}).
+
+@node Configuring
+@section Configuring
+@cindex configuring
+@cindex @code{-V}
+@cindex @code{psviewer}
+@cindex @code{pdfviewer}
+@cindex @code{gs}
+In interactive mode, or when given the @code{-V} option (the default
+when running @code{Asymptote} on a single file under @code{MSDOS}),
+@code{Asymptote} will automatically invoke the @code{PostScript}
+viewer @code{gv} (under @code{UNIX}) or @code{gsview} (under
+@code{MSDOS} to display graphical output. These defaults may be
+overridden with the configuration variable @code{psviewer}.
+The @code{PostScript} viewer should be capable of automatically
+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
+@url{http://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}.
+Users of @code{gsview} will need to enable @code{Options/Auto Redisplay}
+(however, under @code{MSDOS} it is still necessary to click on the
+@code{gsview} window; under @code{UNIX} one must manually redisplay by
+pressing the @code{r} key).
+
+@cindex @code{settings}
+@cindex configuration file
+Configuration variables are most easily set as @code{Asymptote}
+variables in the configuration file (by default, @code{.asy/config.asy} in the
+user's home directory or @code{%USERPROFILE%\.asy\config.asy} under
+@code{MSDOS}); @pxref{configuration file}. Here are the default values
+of several important configuration variables under @code{UNIX}:
+
+@cindex @code{python}
+@noindent
+@verbatim
+import settings;
+psviewer="gv";
+pdfviewer="acroread";
+gs="gs";
+python="";
+@end verbatim
+
+@noindent
+The (installation-dependent) default values of these configuration
+variables under @code{MSDOS} are determined automatically from the
+@code{Microsoft Windows} registry.
+
+For @acronym{PDF} format output, the @code{gs} setting specifies the
+location of the @code{PostScript}-to-@acronym{PDF} processor @code{Ghostscript},
+available from @url{http://sourceforge.net/projects/ghostscript/}.
+
+The setting @code{pdfviewer} specifies the location of the @acronym{PDF}
+viewer. On @code{UNIX} systems, to support automatic document
+reloading in @code{Adobe Reader}, we recommend copying the file
+@code{reload.js} from the @code{Asymptote} system directory (by default,
+@code{@value{Datadir}/asymptote} under @code{UNIX} to
+@code{~/.adobe/Acrobat/x.x/JavaScripts/},
+where @code{x.x} represents the appropriate @code{Adobe Reader}
+version number. The automatic document reload feature must then be
+explicitly enabled by putting
+@verbatim
+import settings;
+pdfreload=true;
+pdfreloadOptions="-tempFile";
+@end verbatim
+@noindent
+in the @code{Asymptote} configuration file. This reload feature is not
+useful under @code{MSDOS} since the document cannot be updated anyway on
+that operating system until it is first closed by @code{Adobe Reader}.
+
+The graphical user interface may also require setting the variable
+@code{python} if @code{Python} is installed in a nonstandard location.
+
+The configuration variable @code{dir} can be used to adjust the
+search path (@pxref{Search paths}).
+
+@cindex @code{papertype}
+@cindex @code{paperwidth}
+@cindex @code{paperheight}
+@cindex @code{letter}
+@cindex @code{a4}
+By default, @code{Asymptote} attempts to center the figure on the
+page, assuming that the paper type is @code{letter}. The default paper
+type may be changed to @code{a4} with the configuration variable
+@code{papertype}. Alignment to other paper sizes can be obtained by setting the
+configuration variables @code{paperwidth} and @code{paperheight}.
+
+@cindex @code{texpath}
+@cindex @code{texcommand}
+@cindex @code{texdvicommand}
+@cindex @code{dvips}
+@cindex @code{convert}
+@cindex @code{display}
+@cindex @code{animate}
+@cindex @code{xasy}
+@cindex @code{ImageMagick}
+The following configuration variables normally do not require adjustment:
+@verbatim
+texpath
+texcommand
+texdvicommand
+dvips
+convert
+display
+animate
+xasy
+@end verbatim
+@noindent
+The @code{texdvicommand} is used for @code{3D} label typesetting, which
+requires @code{dvips} output. An empty string indicates the default setting
+of @code{latex}/@code{tex}, depending on the setting of @code{texengine}.
+
+@cindex command-line options
+Configuration variables may also be set or overwritten with a
+command-line option:
+@verbatim
+asy -psviewer=gsview -V venn
+@end verbatim
+
+@cindex environment variables
+Alternatively, system environment versions of the above configuration
+variables may be set in the conventional way. The corresponding
+environment variable name is obtained by converting the configuration
+variable name to upper case and prepending @code{ASYMPTOTE_}:
+for example, to set the environment variable
+@verbatim
+ASYMPTOTE_PSVIEWER="C:\Program Files\Ghostgum\gsview\gsview32.exe";
+@end verbatim
+@noindent
+under @code{Microsoft Windows XP}:
+@enumerate
+@item Click on the @code{Start} button;
+@item Right-click on @code{My Computer};
+@item Choose @code{Properties} from the popup menu;
+@item Click the @code{Advanced} tab;
+@item Click the @code{Environment Variables} button.
+@end enumerate
+
+@node Search paths
+@section Search paths
+@cindex search paths
+
+In looking for @code{Asymptote} system
+files, @code{asy} will search the following paths, in the order listed:
+@enumerate
+@item
+The current directory;
+@item
+@cindex @code{dir}
+A list of one or more directories specified by the configuration
+variable @code{dir} (separated by @code{:} under UNIX and
+@code{;} under @code{MSDOS});
+@item
+@cindex @code{.asy}
+The directory @code{.asy} in the user's home directory
+(@code{%USERPROFILE%\.asy} under @code{MSDOS});
+@item
+The @code{Asymptote} system directory (by default,
+@code{@value{Datadir}/asymptote} under @code{UNIX} and
+@code{C:\Program Files\Asymptote} under @code{MSDOS}).
+@end enumerate
+
+@node Compiling from UNIX source
+@section Compiling from UNIX source
+@cindex Compiling from UNIX source
+
+To compile and install a @code{UNIX} executable from
+a source release
+@code{x.xx}, first execute the commands:
+@verbatim
+gunzip asymptote-x.xx.src.tgz
+tar -xf asymptote-x.xx.src.tar
+cd asymptote-x.xx
+@end verbatim
+By default the system version of the Boehm garbage collector will be
+used; if it is old we recommend first putting
+@url{http://www.hpl.hp.com/personal/Hans_Boehm/gc/gc_source/gc-7.1.tar.gz}
+in the @code{Asymptote} source directory.
+
+@cindex @code{freeglut}
+@cindex 3D rendering
+@cindex antialiasing
+@cindex multisampling
+@anchor{multisampling}
+@noindent
+If your graphics card supports multisampling, we recommend using SVN
+revision 761 (or later) of @code{freeglut} to support antialiasing in
+@code{Asymptote}'s adaptive @code{OpenGL} 3D renderer
+(@code{MacOS X} users can skip this step since @code{Asymptote} is configured
+to use the native glut library on that platform). Download
+@quotation
+@url{http://freeglut.svn.sourceforge.net/viewvc/freeglut/trunk/freeglut/freeglut.tar.gz}
+@end quotation
+@noindent
+and type (as the root user):
+@verbatim
+tar -zxf freeglut.tar.gz
+cd freeglut
+sh autogen.sh
+./configure --prefix=/usr
+make install
+cd ..
+@end verbatim
+@noindent
+Then compile @code{Asymptote} with the commands
+@verbatim
+./configure
+make all
+make install
+@end verbatim
+@noindent
+Be sure to use @acronym{GNU} @code{make} (on non-@acronym{GNU} systems
+this command may be called @code{gmake}).
+To build the documentation, you may need to install the
+@code{texinfo-tex} package. If you get errors from a broken @code{texinfo}
+or @code{pdftex} installation, simply put
+@quotation
+@url{http://asymptote.sourceforge.net/asymptote.pdf}
+@end quotation
+@noindent
+in the directory @code{doc} and repeat the command @code{make all}.
+
+@noindent
+For a (default) system-wide installation, the last command should be
+done as the root user. To install without root privileges, change the
+@code{./configure} command to
+@verbatim
+./configure --prefix=$HOME/asymptote
+@end verbatim
+One can disable use of the Boehm garbage collector by configuring
+with @code{./configure --disable-gc}. For a list of other configuration
+options, say @code{./configure --help}. For example, one can tell
+configure to look for header files and libraries in nonstandard locations:
+@verbatim
+./configure CFLAGS=-I/opt/usr/include LDFLAGS=-L/opt/usr/lib
+@end verbatim
+
+If you are compiling @code{Asymptote} with @code{gcc}, you will need a
+relatively recent version (e.g.@ 3.4.4 or later). For full interactive
+functionality, you will need version 4.2 or later of the @acronym{GNU}
+@code{readline} library.
+The file @code{gcc3.3.2curses.patch} in the @code{patches} directory can
+be used to patch the broken curses.h header file (or a local copy thereof
+in the current directory) on some @code{AIX} and @code{IRIX} systems.
+
+@cindex @code{FFTW}
+@cindex @code{GSL}
+The @code{FFTW} library is only required if you want @code{Asymptote}
+to be able to take Fourier transforms of data (say, to compute an
+audio power spectrum). The @code{GSL} library is only required if you
+require the special functions that it supports.
+
+If you don't want to install @code{Asymptote} system wide, just make
+sure the compiled binary @code{asy} and @acronym{GUI} script @code{xasy} are in
+your path and set the configuration variable @code{dir} to point
+to the directory @code{base} (in the top level directory of the
+@code{Asymptote} source code).
+
+@node Editing modes
+@section Editing modes
+@cindex Editing modes
+@cindex @code{emacs}
+@cindex @code{asy-mode}
+@cindex @code{lasy-mode}
+Users of @code{emacs} can edit @code{Asymptote} code with the mode
+@code{asy-mode}, after enabling it by putting the following lines in their
+@code{.emacs} initialization file, replacing @code{ASYDIR} with the
+location of the @code{Asymptote} system directory (by default,
+@code{@value{Datadir}/asymptote} or @code{C:\Program Files\Asymptote}
+under @code{MSDOS}):
+@verbatim
+(add-to-list 'load-path "ASYDIR")
+(autoload 'asy-mode "asy-mode.el" "Asymptote major mode." t)
+(autoload 'lasy-mode "asy-mode.el" "hybrid Asymptote/Latex major mode." t)
+(autoload 'asy-insinuate-latex "asy-mode.el" "Asymptote insinuate LaTeX." t)
+(add-to-list 'auto-mode-alist '("\\.asy$" . asy-mode))
+
+@end verbatim
+@noindent
+Particularly useful key bindings in this mode are @code{C-c C-c}, which compiles
+and displays the current buffer, and the key binding @code{C-c ?}, which
+shows the available function prototypes for the command at the cursor.
+For full functionality you should also install the Apache Software Foundation
+package @code{two-mode-mode}:
+@quotation
+@url{http://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
+LaTeX file containing embedded @code{Asymptote} code (@pxref{LaTeX usage}).
+This mode can be enabled within @code{latex-mode}
+with the key sequence @code{M-x lasy-mode <RET>}.
+On @code{UNIX} systems, additional keywords will be generated from
+all @code{asy} files in the space-separated list of directories
+specified by the environment variable @code{ASYMPTOTE_SITEDIR}.
+Further documentation of @code{asy-mode} is available within
+@code{emacs} by pressing the sequence keys @code{C-h f asy-mode <RET>}.
+
+@cindex @code{vim}
+@cindex @code{asy.vim}
+Fans of @code{vim} can customize @code{vim} for @code{Asymptote} with
+
+@noindent
+@code{cp @value{Datadir}/asymptote/asy.vim ~/.vim/syntax/asy.vim}
+
+@noindent
+and add the following to their @code{~/.vimrc} file:
+@verbatim
+augroup filetypedetect
+au BufNewFile,BufRead *.asy setf asy
+augroup END
+filetype plugin on
+@end verbatim
+
+If any of these directories or files don't exist, just create them.
+To set @code{vim} up to run the current asymptote script using @code{:make}
+just add to @code{~/.vim/ftplugin/asy.vim}:
+@verbatim
+setlocal makeprg=asy\ %
+setlocal errorformat=%f:\ %l.%c:\ %m
+
+@end verbatim
+
+@node Subversion
+@section Subversion (SVN)
+@cindex Subversion
+@cindex SVN
+
+The following commands are needed to install the latest development version of
+@code{Asymptote} using @acronym{Subversion}:
+@verbatim
+svn co http://asymptote.svn.sourceforge.net/svnroot/asymptote/trunk/asymptote
+cd asymptote
+./autogen.sh
+./configure
+make all
+make install
+@end verbatim
+
+@noindent
+To compile without optimization, use the command @code{make CFLAGS=-g}.
+
+@node Uninstall
+@section Uninstall
+@cindex Uninstall
+
+To uninstall an @code{Linux i386} binary distribution, use the commands
+@verbatim
+tar -zxvf asymptote-x.xx.i386.tgz | xargs --replace=% rm /%
+texhash
+@end verbatim
+
+@noindent
+To uninstall all @code{Asymptote} files installed from a source
+distribution, use the command
+@verbatim
+make uninstall
+@end verbatim
+
+@node Tutorial
+@chapter Tutorial
+@cindex tutorial
+@emph{An excellent user-written @code{Asymptote} tutorial is also available
+from}
+
+@url{http://www.artofproblemsolving.com/Wiki/index.php/Asymptote:_Basics}
+
+@noindent
+To draw a line from coordinate (0,0) to coordinate (100,100) using
+@code{Asymptote}'s interactive mode, type at the command prompt:
+@verbatim
+asy
+draw((0,0)--(100,100));
+@end verbatim
+@sp 1
+@center @image{diagonal}
+
+@cindex @code{bp}
+@cindex @code{pair}
+The units here are @code{PostScript} "big points"
+(1 @code{bp} = 1/72 @code{inch}); @code{--} means join with a linear segment.
+In @code{Asymptote} coordinates like @code{(0,0)} and
+@code{(1000,100)} are called @emph{pairs}.
+
+@cindex tab completion
+@cindex arrow keys
+At this point you can type in further draw commands, which will be added
+to the displayed figure, or type @code{quit} to exit interactive mode.
+You can use the arrow keys in interactive mode to edit previous lines
+(assuming that you have support for the @acronym{GNU} @code{readline} library
+enabled). The tab key will automatically complete unambiguous words;
+otherwise, hitting tab again will show the possible choices. Further
+commands specific to interactive mode are described in @ref{Interactive mode}.
+
+@cindex batch mode
+In batch mode, @code{Asymptote} reads commands directly from a
+file. To try this out, type
+@verbatiminclude diagonal.asy
+
+@noindent
+into a file, say test.asy. Then execute this file with the
+@code{MSDOS} or @code{UNIX} command
+@verbatim
+asy -V test
+@end verbatim
+@noindent
+@code{MSDOS} users can drag and drop the file onto the
+Desktop @code{asy} icon or make @code{Asymptote} the
+default application for files with the extension @code{asy}.
+
+@noindent
+@cindex @code{-V}
+The @code{-V} option opens up a @code{PostScript}
+viewer window so you can immediately view the encapsulated
+@code{PostScript} output. By default the output will be written to the
+file @code{test.eps}; the prefix of the output file may be changed with
+the @code{-o} command-line option.
+
+@cindex @code{cycle}
+One can draw a line with more than two points and create a cyclic path
+like this square:
+@verbatiminclude square.asy
+@sp 1
+@center @image{square}
+
+It is often inconvenient to work directly with @code{PostScript} coordinates.
+The next example draws a unit square scaled to width 101 bp and height
+101 bp. The output is identical to that of the previous example.
+@verbatim
+size(101,101);
+draw((0,0)--(1,0)--(1,1)--(0,1)--cycle);
+@end verbatim
+
+For convenience, the path @code{(0,0)--(1,0)--(1,1)--(0,1)--cycle}
+may be replaced with the predefined variable
+@code{unitsquare}, or equivalently, @code{box((0,0),(1,1))}.
+
+@cindex @code{inches}
+@cindex @code{cm}
+@cindex @code{mm}
+@cindex @code{pt}
+One can also specify the size in @code{pt} (1 @code{pt} = 1/72.27 @code{inch}),
+@code{cm}, @code{mm}, or @code{inches}.
+If 0 is given as a size argument, no restriction is made in that direction;
+the overall scaling will be determined by the other direction
+(@pxref{size}):
+@verbatiminclude bigsquare.asy
+@sp 1
+@center @image{bigsquare}
+
+@cindex user coordinates
+@cindex @code{unitsize}
+To make the user coordinates represent multiples of exactly @code{1cm}:
+@verbatim
+unitsize(1cm);
+draw(unitsquare);
+@end verbatim
+
+One can also specify different @math{x} and @math{y} unit sizes:
+@verbatim
+unitsize(1cm,2cm);
+draw(unitsquare);
+@end verbatim
+
+Adding labels is easy in @code{Asymptote}; one specifies the
+label as a double-quoted @code{LaTeX} string, a
+coordinate, and an optional alignment direction:
+@verbatiminclude labelsquare.asy
+@sp 1
+@center @image{labelsquare}
+
+@cindex compass directions
+@cindex @code{N}
+@cindex @code{E}
+@cindex @code{W}
+@cindex @code{S}
+@code{Asymptote} uses the standard compass directions @code{E=(1,0)},
+@code{N=(0,1)}, @code{NE=unit(N+E)}, and @code{ENE=unit(E+NE)}, etc.,
+which along with the directions @code{up}, @code{down}, @code{right},
+and @code{left} are defined as pairs in the @code{Asymptote} base
+module @code{plain}. A user who has a local variable named @code{E}
+may access the compass direction @code{E} by prefixing it with the name
+of the module where it is defined: @code{plain.E}.
+
+This example draws a path that approximates a quarter circle:
+@verbatiminclude quartercircle.asy
+@sp 1
+@center @image{quartercircle}
+
+In general, a path is specified as a list of pairs (or other paths)
+interconnected with
+@cindex @code{cycle}
+@cindex @code{--}
+@cindex @code{..}
+@code{--}, which denotes a straight line segment, or @code{..}, which
+denotes a cubic spline.
+@anchor{unitcircle}
+@cindex @code{unitcircle}
+Specifying a final node @code{cycle} creates a cyclic path that
+connects smoothly back to the initial node, as in this approximation
+(accurate to within 0.06%) of a unit circle:
+@verbatim
+path unitcircle=E..N..W..S..cycle;
+@end verbatim
+
+@anchor{Bezier}
+@cindex direction specifier
+Each interior node of a cubic spline may be given a
+direction prefix or suffix @code{@{dir@}}: the direction of the pair
+@code{dir} specifies the direction of the incoming or outgoing tangent,
+respectively, to the curve at that node. Exterior nodes may be
+given direction specifiers only on their interior side.
+
+A cubic spline between the node @math{z_0}, with postcontrol point
+@math{c_0}, and the node @math{z_1}, with precontrol point @math{c_1},
+is computed as the Bezier curve
+@sp 1
+@center @image{bezier,,,(1-t)^3*z_0+3t(1-t)^2*c_0+3t^2(1-t)*c_1+t^3*z_1 for 0 <=t <= 1.}
+
+As illustrated in the diagram below, the third-order midpoint (@math{m_5})
+constructed from two endpoints @math{z_0} and @math{z_1} and two control points
+@math{c_0} and @math{c_1}, is the point corresponding to @math{t=1/2} on
+the Bezier curve formed by the quadruple (@math{z_0}, @math{c_0},
+@math{c_1}, @math{z_1}). This allows one to recursively construct the
+desired curve, by using the newly extracted third-order midpoint as an
+endpoint and the respective second- and first-order midpoints as control
+points:
+@sp 1
+@center @image{bezier2}
+
+Here @math{m_0}, @math{m_1} and @math{m_2} are the first-order
+midpoints, @math{m_3} and @math{m_4} are the second-order midpoints, and
+@math{m_5} is the third-order midpoint.
+The curve is then constructed by recursively applying the algorithm to
+(@math{z_0}, @math{m_0}, @math{m_3}, @math{m_5}) and
+(@math{m_5}, @math{m_4}, @math{m_2}, @math{z_1}).
+
+In fact, an analogous property holds for points located at any
+fraction @math{t} in @math{[0,1]} of each segment, not just for
+midpoints (@math{t=1/2}).
+
+The Bezier curve constructed in this manner has the following properties:
+@itemize @bullet
+
+@item It is entirely contained in the convex hull of the given four points.
+
+@item It starts heading from the first endpoint to the first control point
+and finishes heading from the second control point to the second endpoint.
+
+@end itemize
+
+@cindex @code{controls}
+The user can specify explicit control points between two nodes like this:
+@verbatim
+draw((0,0)..controls (0,100) and (100,100)..(100,0));
+@end verbatim
+
+However, it is usually more convenient to just use the
+@code{..} operator, which tells @code{Asymptote} to choose its own
+control points using the algorithms described in Donald Knuth's
+monograph, The MetaFontbook, Chapter 14.
+The user can still customize the guide (or path) by specifying
+direction, tension, and curl values.
+
+The higher the tension, the straighter the curve is, and the more
+it approximates a straight line.
+@cindex @code{tension}
+@cindex @code{and}
+@cindex @code{atleast}
+One can change the spline tension from its default value of 1 to any
+real value greater than or equal to 0.75 (cf. John D. Hobby, Discrete and
+Computational Geometry 1, 1986):
+@verbatim
+draw((100,0)..tension 2 ..(100,100)..(0,100));
+draw((100,0)..tension 2 and 1 ..(100,100)..(0,100));
+draw((100,0)..tension atleast 1 ..(100,100)..(0,100));
+@end verbatim
+
+@cindex @code{curl}
+The curl parameter specifies the curvature at the endpoints of a path
+(0 means straight; the default value of 1 means approximately circular):
+@verbatim
+draw((100,0){curl 0}..(100,100)..{curl 0}(0,100));
+@end verbatim
+
+@cindex @code{MetaPost ...@ }
+@cindex @code{::}
+The @code{MetaPost ...} path connector, which requests, when possible, an
+inflection-free curve confined to a triangle defined by the
+endpoints and directions, is implemented in @code{Asymptote} as the
+convenient abbreviation @code{::} for @code{..tension atleast 1 ..}
+(the ellipsis @code{...} is used in @code{Asymptote} to indicate a
+variable number of arguments; @pxref{Rest arguments}). For example,
+compare
+@verbatiminclude dots.asy
+@sp 1
+@center @image{dots}
+@noindent
+with
+@verbatiminclude colons.asy
+@sp 1
+@center @image{colons}
+
+@cindex @code{---}
+@cindex @code{&}
+The @code{---} connector is an abbreviation for @code{..tension atleast
+infinity..} and the @code{&} connector concatenates two paths, after
+first stripping off the last node of the first path (which normally
+should coincide with the first node of the second path).
+
+@cindex @code{PostScript} subpath
+@cindex @code{^^}
+@cindex @code{path[]}
+@cindex superpath
+An @code{Asymptote} path, being connected, is equivalent to a
+@code{Postscript subpath}. The @code{^^} binary operator, which
+requests that the pen be moved (without drawing or affecting
+endpoint curvatures) from the final point of the left-hand path to the
+initial point of the right-hand path, may be used to group several
+@code{Asymptote} paths into a @code{path[]} array (equivalent to a
+@code{PostScript} path):
+@verbatiminclude superpath.asy
+@sp 1
+@center @image{superpath}
+
+@cindex evenodd
+The @code{PostScript} even-odd fill rule here specifies that only the
+region bounded between the two unit circles is filled (@pxref{fillrule}).
+In this example, the same effect can be achieved by using the default
+zero winding number fill rule, if one is careful to alternate the
+orientation of the paths:
+@verbatim
+filldraw(unitcircle^^reverse(g),yellow,black);
+@end verbatim
+
+@cindex @code{unitbox}
+The @code{^^} operator is used by the @code{box(triple, triple)} function in
+@code{three.asy} to construct the edges of a cube @code{unitbox}
+without retracing steps:
+@verbatiminclude cube.asy
+@sp 1
+@center @image{cube}
+
+See section @ref{graph} (or the online @code{Asymptote} gallery and
+external links posted at @url{http://asymptote.sourceforge.net}) for
+further examples, including two and three-dimensional scientific
+graphs. Additional examples have been posted by Philippe Ivaldi at
+@url{http://piprim.tuxfamily.org/asymptote/}.
+
+@node Drawing commands
+@chapter Drawing commands
+@cindex drawing commands
+
+All of @code{Asymptote}'s graphical capabilities are based on four primitive
+commands. The three @code{PostScript} drawing commands @code{draw},
+@code{fill}, and @code{clip} add objects to a picture in the order in
+which they are executed, with the most recently drawn object appearing on top.
+The labeling command @code{label} can be used to add text
+labels and external @acronym{EPS} images, which will appear on top of the
+@code{PostScript} objects (since this is normally what one wants), but
+again in the relative order in which they were executed. After drawing
+objects on a picture, the picture can be output with the
+@code{shipout} function (@pxref{shipout}).
+
+@cindex @code{layer}
+If you wish to draw @code{PostScript} objects on top of labels (or verbatim
+@code{tex} commands; @pxref{tex}), the @code{layer} command may be
+used to start a
+new @code{PostScript/LaTeX} layer:
+@verbatim
+void layer(picture pic=currentpicture);
+@end verbatim
+
+The @code{layer} function gives one full control over the order in which
+objects are drawn. Layers are drawn sequentially, with the most recent
+layer appearing on top. Within each layer, labels, images, and
+verbatim @code{tex} commands are always drawn after the
+@code{PostScript} objects in that layer.
+
+While some of these drawing commands take many options, they all have sensible
+default values (for example, the picture argument defaults to
+currentpicture).
+
+@cindex legend
+@cindex @code{draw}
+@cindex @code{arrow}
+@menu
+* draw:: Draw a path on a picture or frame
+* fill:: Fill a cyclic path on a picture or frame
+* clip:: Clip a picture or frame to a cyclic path
+* label:: Label a point on a picture
+@end menu
+
+@node draw
+@section draw
+@verbatim
+void draw(picture pic=currentpicture, Label L="", path g,
+ align align=NoAlign, pen p=currentpen,
+ arrowbar arrow=None, arrowbar bar=None, margin margin=NoMargin,
+ Label legend="", marker marker=nomarker);
+@end verbatim
+
+Draw the path @code{g} on the picture @code{pic} using pen @code{p}
+for drawing, with optional drawing attributes (Label @code{L},
+explicit label alignment @code{align},
+arrows and bars @code{arrow} and @code{bar}, margins @code{margin},
+legend, and markers @code{marker}). Only one parameter, the path, is
+required. For convenience, the arguments @code{arrow} and @code{bar} may be
+specified in either order. The argument @code{legend} is a Label to
+use in constructing an optional legend entry.
+
+@cindex @code{None}
+@cindex @code{BeginBar}
+@cindex @code{EndBar}
+@cindex @code{Bar}
+@cindex @code{Bars}
+@cindex @code{barsize}
+Bars are useful for indicating dimensions. The possible values of
+@code{bar} are @code{None}, @code{BeginBar}, @code{EndBar} (or
+equivalently @code{Bar}), and @code{Bars} (which draws a bar at both
+ends of the path). Each of these bar specifiers (except for
+@code{None}) will accept an optional real argument that denotes the
+length of the bar in @code{PostScript} coordinates. The default
+bar length is @code{barsize(pen)}.
+
+@anchor{arrows}
+@cindex @code{None}
+@cindex @code{Blank}
+@cindex @code{BeginArrow}
+@cindex @code{MidArrow}
+@cindex @code{EndArrow}
+@cindex @code{Arrow}
+@cindex @code{Arrows}
+@cindex @code{FillDraw}
+@cindex @code{Fill}
+@cindex @code{Draw}
+@cindex @code{NoFill}
+@cindex @code{UnFill}
+@cindex @code{BeginArcArrow}
+@cindex @code{MidArcArrow}
+@cindex @code{EndArcArrow}
+@cindex @code{ArcArrow}
+@cindex @code{ArcArrows}
+
+@cindex @code{DefaultHead}
+@cindex @code{SimpleHead}
+@cindex @code{HookHead}
+@cindex @code{TeXHead}
+The possible values of @code{arrow} are @code{None}, @code{Blank}
+(which draws no arrows or path), @code{BeginArrow}, @code{MidArrow},
+@code{EndArrow} (or equivalently @code{Arrow}),
+and @code{Arrows} (which draws an arrow at both ends of the path).
+All of the arrow specifiers except for @code{None} and @code{Blank}
+may be given the optional arguments arrowhead @code{arrowhead} (one of
+the predefined arrowhead styles @code{DefaultHead}, @code{SimpleHead},
+@code{HookHead}, @code{TeXHead}),
+real @code{size} (arrowhead size in @code{PostScript} coordinates),
+real @code{angle} (arrowhead angle
+in degrees), filltype @code{filltype} (one of @code{FillDraw}, @code{Fill},
+@code{NoFill}, @code{UnFill}, @code{Draw})
+and (except for @code{MidArrow} and @code{Arrows}) a
+relative real @code{position} along the path (an @code{arctime}) where
+the tip of the arrow should be placed. The default arrowhead size when drawn
+with a pen @code{p} is @code{arrowsize(p)}. There are also arrow versions with
+slightly modified default values of @code{size} and @code{angle} suitable for
+curved arrows: @code{BeginArcArrow}, @code{EndArcArrow} (or equivalently
+@code{ArcArrow}), @code{MidArcArrow}, and @code{ArcArrows}.
+
+@cindex @code{NoMargin}
+@cindex @code{BeginMargin}
+@cindex @code{EndMargin}
+@cindex @code{Margin}
+@cindex @code{Margins}
+@cindex @code{BeginPenMargin}
+@cindex @code{EndPenMargin}
+@cindex @code{PenMargin}
+@cindex @code{PenMargins}
+@cindex @code{BeginDotMargin}
+@cindex @code{EndDotMargin}
+@cindex @code{DotMargin}
+@cindex @code{DotMargins}
+@cindex @code{Margin}
+@cindex @code{TrueMargin}
+Margins can be used to shrink the visible portion of a path by
+@code{labelmargin(p)} to avoid overlap with other drawn objects.
+Typical values of @code{margin}
+are @code{NoMargin}, @code{BeginMargin}, @code{EndMargin} (or
+equivalently @code{Margin}), and @code{Margins} (which leaves a margin
+at both ends of the path). One may use @code{Margin(real begin, real end)}
+to specify the size of the beginning and ending margin, respectively,
+in multiples of the units @code{labelmargin(p)} used for aligning labels.
+Alternatively, @code{BeginPenMargin}, @code{EndPenMargin}
+(or equivalently @code{PenMargin}), @code{PenMargins},
+@code{PenMargin(real begin, real end)} specify a margin in units of
+the pen line width, taking account of the pen line width when drawing
+the path or arrow. For example, use @code{DotMargin}, an
+abbreviation for @code{PenMargin(-0.5*dotfactor,0.5*dotfactor)},
+to draw from the usual beginning point just up to the boundary of an
+end dot of width @code{dotfactor*linewidth(p)}. The qualifiers
+@code{BeginDotMargin}, @code{EndDotMargin}, and @code{DotMargins} work
+similarly. The qualifier @code{TrueMargin(real begin, real end)} allows one to
+specify a margin directly in @code{PostScript} units, independent of
+the pen line width.
+
+The use of arrows, bars, and margins is illustrated by the examples
+@code{Pythagoras.asy}, @code{sqrtx01.asy}, and @code{triads.asy}.
+
+The legend for a picture @code{pic} can be fit and aligned to a frame
+with the routine:
+@cindex @code{legend}
+@verbatim
+frame legend(picture pic=currentpicture, int perline=1,
+ real xmargin=legendmargin, real ymargin=xmargin,
+ real linelength=legendlinelength,
+ real hskip=legendhskip, real vskip=legendvskip,
+ real maxwidth=0, real maxheight=0,
+ bool hstretch=false, bool vstretch=false, pen p=currentpen);
+@end verbatim
+@noindent
+Here @code{xmargin} and @code{ymargin} specify the surrounding @math{x}
+and @math{y} margins, @code{perline} specifies the number of entries
+per line (default 1; 0 means choose this number automatically),
+@code{linelength} specifies the length of the path lines, @code{hskip}
+and @code{vskip} specify the line skip (as a multiple of the legend entry
+size), @code{maxwidth} and @code{maxheight} specify optional upper limits
+on the width and height of the resulting legend (0 means unlimited),
+@code{hstretch} and @code{vstretch} allow the legend to stretch
+horizontally or vertically, and @code{p} specifies the pen used to draw
+the bounding box. The legend frame can then be added and aligned about a
+point on a picture @code{dest} using @code{add} or @code{attach}
+(@pxref{add about}).
+
+@cindex @code{dot}
+To draw a dot, simply draw a path containing a single point.
+The @code{dot} command defined in the module @code{plain} draws a
+dot having a diameter equal to an explicit pen line width or the
+default line width magnified by @code{dotfactor} (6 by default),
+using the specified filltype (@pxref{filltype}):
+@verbatim
+void dot(picture pic=currentpicture, pair z, pen p=currentpen,
+ filltype filltype=Fill);
+void dot(picture pic=currentpicture, Label L, pair z, align align=NoAlign,
+ string format=defaultformat, pen p=currentpen, filltype filltype=Fill);
+void dot(picture pic=currentpicture, Label[] L=new Label[], pair[] z,
+ align align=NoAlign, string format=defaultformat, pen p=currentpen,
+ filltype filltype=Fill)
+void dot(picture pic=currentpicture, Label L, pen p=currentpen,
+ filltype filltype=Fill);
+@end verbatim
+
+@cindex @code{Label}
+If the variable @code{Label} is given as the @code{Label}
+argument to the second routine, the @code{format} argument will be
+used to format a string based on the dot location (here @code{defaultformat}
+is @code{"$%.4g$"}).
+The third routine draws a dot at every point of a pair array @code{z}.
+One can also draw a dot at every node of a path:
+@verbatim
+void dot(picture pic=currentpicture, Label[] L=new Label[],
+ path g, align align=RightSide, string format=defaultformat,
+ pen p=currentpen, filltype filltype=Fill);
+@end verbatim
+See @ref{pathmarkers} and @ref{markers} for more general
+methods for marking path nodes.
+
+To draw a fixed-sized object (in @code{PostScript} coordinates) about
+the user coordinate @code{origin}, use the routine
+@cindex @code{draw}
+@verbatim
+void draw(pair origin, picture pic=currentpicture, Label L="", path g,
+ align align=NoAlign, pen p=currentpen, arrowbar arrow=None,
+ arrowbar bar=None, margin margin=NoMargin, Label legend="",
+ marker marker=nomarker);
+@end verbatim
+
+@cindex @code{fill}
+@node fill
+@section fill
+@verbatim
+void fill(picture pic=currentpicture, path g, pen p=currentpen);
+@end verbatim
+
+Fill the interior region bounded by the cyclic path @code{g} on the picture
+@code{pic}, using the pen @code{p}.
+
+@cindex @code{filldraw}
+There is also a convenient @code{filldraw} command, which fills the path
+and then draws in the boundary. One can specify separate pens for each
+operation:
+@verbatim
+void filldraw(picture pic=currentpicture, path g, pen fillpen=currentpen,
+ pen drawpen=currentpen);
+@end verbatim
+
+@cindex @code{fill}
+This fixed-size version of @code{fill} allows one to fill an object
+described in @code{PostScript} coordinates about the user coordinate
+@code{origin}:
+@verbatim
+void fill(pair origin, picture pic=currentpicture, path g, pen p=currentpen);
+@end verbatim
+
+@noindent
+This is just a convenient abbreviation for the commands:
+@verbatim
+picture opic;
+fill(opic,g,p);
+add(pic,opic,origin);
+@end verbatim
+
+The routine
+@cindex @code{filloutside}
+@verbatim
+void filloutside(picture pic=currentpicture, path g, pen p=currentpen);
+@end verbatim
+@noindent
+fills the region exterior to the path @code{g}, out to the current
+boundary of picture @code{pic}.
+
+@anchor{gradient shading}
+@cindex gradient shading
+
+@cindex shading
+@cindex @code{latticeshade}
+Lattice gradient shading varying smoothly over a two-dimensional
+array of pens @code{p}, using fill rule @code{fillrule}, can be produced with
+@verbatim
+void latticeshade(picture pic=currentpicture, path g, bool stroke=false,
+ pen fillrule=currentpen, pen[][] p)
+@end verbatim
+@cindex @code{stroke}
+If @code{stroke=true}, the region filled is the same as the region that
+would be drawn by @code{draw(pic,g,fillrule+zerowinding)}; in this case the path
+@code{g} need not be cyclic.
+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
+@code{latticeshading.asy}.
+
+@cindex @code{axialshade}
+Axial gradient shading varying smoothly from @code{pena} to @code{penb} in the
+direction of the line segment @code{a--b} can be achieved with
+@verbatim
+void axialshade(picture pic=currentpicture, path g, bool stroke=false,
+ pen pena, pair a,
+ pen penb, pair b);
+@end verbatim
+
+@cindex @code{radialshade}
+Radial gradient shading varying smoothly from
+@code{pena} on the circle with center @code{a} and radius @code{ra} to
+@code{penb} on the circle with center @code{b} and radius @code{rb}
+is similar:
+@verbatim
+void radialshade(picture pic=currentpicture, path g, bool stroke=false,
+ pen pena, pair a, real ra,
+ pen penb, pair b, real rb);
+@end verbatim
+@noindent
+Illustrations of radial shading are provided in the example files
+@code{shade.asy}, @code{ring.asy}, and @code{shadestroke.asy}.
+
+@cindex @code{gouraudshade}
+Gouraud shading using fill rule @code{fillrule} and the vertex colors in the
+pen array @code{p} on a triangular lattice defined by the vertices
+@code{z} and edge flags @code{edges} is implemented with
+@verbatim
+void gouraudshade(picture pic=currentpicture, path g, bool stroke=false,
+ pen fillrule=currentpen, pen[] p, pair[] z,
+ int[] edges);
+void gouraudshade(picture pic=currentpicture, path g, bool stroke=false,
+ pen fillrule=currentpen, pen[] p, int[] edges);
+@end verbatim
+@noindent
+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
+@code{Gouraud.asy} and in the solid geometry module @code{solids.asy}.
+The edge flags used in Gouraud shading are documented here:
+@quotation
+@url{http://partners.adobe.com/public/developer/en/ps/sdk/TN5600.SmoothShading.pdf}.
+@end quotation
+
+@cindex Coons shading
+@cindex tensor product shading
+@cindex @code{tensorshade}
+Tensor product shading using fill rule @code{fillrule} on patches
+bounded by the @math{n} cyclic paths of length 4 in path array @code{b},
+using the vertex colors specified in the @math{n \times 4} pen array
+@code{p} and internal control points in the @math{n \times 4}
+array @code{z}, is implemented with
+@verbatim
+void tensorshade(picture pic=currentpicture, path g, bool stroke=false,
+ pen fillrule=currentpen, pen[][] p, path[] b=g,
+ pair[][] z=new pair[][]);
+@end verbatim
+@noindent
+If the array @code{z} is empty, Coons shading, in which the color
+control points are calculated automatically, is used.
+The pens in @code{p} must belong to the same color space.
+A simpler interface for the case of a single patch (@math{n=1}) is also
+available:
+@verbatim
+void tensorshade(picture pic=currentpicture, path g, bool stroke=false,
+ pen fillrule=currentpen, pen[] p, path b=g,
+ pair[] z=new pair[]);
+@end verbatim
+One can also smoothly shade the regions between consecutive paths of a
+sequence using a given array of pens:
+@verbatim
+void draw(picture pic=currentpicture, path[] g, pen[] p);
+@end verbatim
+@noindent
+Illustrations of tensor product and Coons shading are provided in the
+example files @code{tensor.asy}, @code{Coons.asy}, @code{BezierSurface.asy},
+and @code{rainbow.asy}.
+
+@cindex Function shading
+@cindex function shading
+@cindex @code{functionshade}
+More general shading possibilities are available with the @code{pdflatex},
+@code{xetex}, and @code{pdftex} @TeX{} engines: the routine
+@verbatim
+void functionshade(picture pic=currentpicture, path[] g, bool stroke=false,
+ pen fillrule=currentpen, string shader);
+@end verbatim
+@noindent
+shades on picture @code{pic} the interior of path @code{g} according
+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{functionshading.asy}.
+
+@cindex unfill
+The following routine uses @code{evenodd} clipping together with the
+@code{^^} operator to unfill a region:
+
+@verbatim
+void unfill(picture pic=currentpicture, path g);
+@end verbatim
+
+@cindex @code{clip}
+@cindex @code{stroke}
+@node clip
+@section clip
+@verbatim
+void clip(picture pic=currentpicture, path g, stroke=false,
+ pen fillrule=currentpen);
+@end verbatim
+
+Clip the current contents of picture @code{pic} to the region bounded
+by the path @code{g}, using fill rule @code{fillrule} (@pxref{fillrule}).
+If @code{stroke=true}, the clipped portion is the same as the region
+that would be drawn with @code{draw(pic,g,fillrule+zerowinding)}; in
+this case the path @code{g} need not be cyclic. For an illustration of
+picture clipping, see the first example in @ref{LaTeX usage}.
+
+@cindex @code{label}
+@node label
+@section label
+@verbatim
+void label(picture pic=currentpicture, Label L, pair position,
+ align align=NoAlign, pen p=nullpen, filltype filltype=NoFill)
+@end verbatim
+
+Draw Label @code{L} on picture @code{pic} using pen @code{p}. If
+@code{align} is @code{NoAlign}, the label will be centered at user
+coordinate @code{position}; otherwise it will be aligned in the
+direction of @code{align} and displaced from @code{position} by
+the @code{PostScript} offset @code{align*labelmargin(p)}.
+@cindex @code{Align}
+The constant @code{Align} can be used to align the
+bottom-left corner of the label at @code{position}.
+@cindex @code{nullpen}
+If @code{p} is @code{nullpen}, the pen specified within the
+Label, which defaults to @code{currentpen}, will be used.
+@anchor{Label}
+The Label @code{L} can either be a string or the structure obtained by calling
+one of the functions
+@verbatim
+Label Label(string s="", pair position, align align=NoAlign,
+ pen p=nullpen, embed embed=Rotate, filltype filltype=NoFill);
+Label Label(string s="", align align=NoAlign,
+ pen p=nullpen, embed embed=Rotate, filltype filltype=NoFill);
+Label Label(Label L, pair position, align align=NoAlign,
+ pen p=nullpen, embed embed=L.embed, filltype filltype=NoFill);
+Label Label(Label L, align align=NoAlign,
+ pen p=nullpen, embed embed=L.embed, filltype filltype=NoFill);
+@end verbatim
+The text of a Label can be scaled, slanted, rotated, or shifted by
+multiplying it on the left by an affine transform (@pxref{Transforms}).
+For example, @code{rotate(45)*xscale(2)*L} first scales @code{L} in the
+@math{x} direction and then rotates it counterclockwise by 45
+degrees. The final position of a Label can also be shifted by a
+@code{PostScript} coordinate translation: @code{shift(10,0)*L}.
+The @code{embed} argument determines how the Label should transform with the
+embedding picture:
+@table @code
+@item Shift
+@cindex @code{Shift}
+only shift with embedding picture;
+
+@item Rotate
+@cindex @code{Rotate}
+only shift and rotate with embedding picture (default);
+
+@item Rotate(pair z)
+@cindex @code{Rotate(pair z)}
+rotate with (picture-transformed) vector @code{z}.
+
+@item Slant
+@cindex @code{Slant}
+only shift, rotate, slant, and reflect with embedding picture;
+
+@item Scale
+@cindex @code{Scale}
+shift, rotate, slant, reflect, and scale with embedding picture.
+
+@end table
+
+To add a label to a path, use
+@verbatim
+void label(picture pic=currentpicture, Label L, path g, align align=NoAlign,
+ pen p=nullpen, filltype filltype=NoFill);
+@end verbatim
+@cindex @code{Relative}
+By default the label will be positioned at the midpoint of the path.
+An alternative label location (an @code{arctime} value between 0 and
+@code{length(g)} @pxref{arctime}) may be specified as real value for
+@code{position} in constructing the Label. The position
+@code{Relative(real)} specifies a location relative to the total
+arclength of the path. These convenient abbreviations are predefined:
+@cindex @code{BeginPoint}
+@cindex @code{MidPoint}
+@cindex @code{EndPoint}
+@verbatim
+position BeginPoint=Relative(0);
+position MidPoint=Relative(0.5);
+position EndPoint=Relative(1);
+@end verbatim
+
+@cindex @code{Relative}
+@cindex @code{LeftSide}
+@cindex @code{Center}
+@cindex @code{RightSide}
+Path labels are aligned in the direction @code{align}, which may
+be specified as an absolute compass direction (pair) or a direction
+@code{Relative(pair)} measured relative to a north axis
+in the local direction of the path. For convenience @code{LeftSide},
+@code{Center}, and @code{RightSide} are defined as @code{Relative(W)},
+@code{Relative((0,0))}, and @code{Relative(E)}, respectively.
+Multiplying @code{LeftSide}, @code{Center}, @code{RightSide} on the
+left by a real scaling factor will move the label further away from or
+closer to the path.
+
+A label with a fixed-size arrow of length @code{arrowlength} pointing
+to @code{b} from direction @code{dir} can be produced with the routine
+@cindex @code{arrow}
+@verbatim
+void arrow(picture pic=currentpicture, Label L="", pair b, pair dir,
+ real length=arrowlength, align align=NoAlign,
+ pen p=currentpen, arrowbar arrow=Arrow, margin margin=EndMargin);
+@end verbatim
+If no alignment is specified (either in the Label or as an explicit
+argument), the optional Label will be aligned in the direction @code{dir},
+using margin @code{margin}.
+
+@cindex including images
+@cindex @code{graphic}
+@cindex @acronym{EPS}
+The function @code{string graphic(string name, string options="")}
+returns a string that can be used to include an encapsulated
+@code{PostScript} (@acronym{EPS}) file. Here, @code{name} is the name
+of the file to include and @code{options} is a string containing a
+comma-separated list of optional bounding box (@code{bb=llx lly urx
+ury}), width (@code{width=value}), height (@code{height=value}),
+rotation (@code{angle=value}), scaling (@code{scale=factor}), clipping
+(@code{clip=bool}), and draft mode (@code{draft=bool}) parameters. The
+@code{layer()} function can be used to force future objects to be
+drawn on top of the included image:
+@verbatim
+label(graphic("file.eps","width=1cm"),(0,0),NE);
+layer();
+@end verbatim
+
+@cindex @code{baseline}
+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{Pythagoras.asy} for an example.
+
+One can prevent labels from overwriting one another with the
+@code{overwrite} pen attribute (@pxref{overwrite}).
+
+The structure @code{object} defined in @code{plain_Label.asy} allows Labels
+and frames to be treated in a uniform manner.
+A group of objects may be packed together into single frame with the routine
+@cindex @code{pack}
+@verbatim
+frame pack(pair align=2S ... object inset[]);
+@end verbatim
+@noindent
+To draw or fill a box (or ellipse or other path) around a Label and
+return the bounding object, use one of the routines
+@verbatim
+object draw(picture pic=currentpicture, Label L, envelope e,
+ real xmargin=0, real ymargin=xmargin, pen p=currentpen,
+ filltype filltype=NoFill, bool above=true);
+object draw(picture pic=currentpicture, Label L, envelope e, pair position,
+ real xmargin=0, real ymargin=xmargin, pen p=currentpen,
+ filltype filltype=NoFill, bool above=true);
+@end verbatim
+@noindent
+Here @code{envelope} is a boundary-drawing routine such as @code{box},
+@code{roundbox}, or @code{ellipse} defined in @code{plain_boxes.asy}
+(@pxref{envelope}).
+
+@cindex @code{texpath}
+The function @code{path[] texpath(Label L)} returns the path array that
+@TeX{} would fill to draw the Label @code{L}.
+
+@cindex @code{minipage}
+The @code{string minipage(string s, width=100pt)} function can be used
+to format string @code{s} into a paragraph of width @code{width}.
+This example uses @code{minipage}, @code{clip}, and @code{graphic} to
+produce a CD label:
+@sp 1
+@center @image{CDlabel}
+@verbatiminclude CDlabel.asy
+@node Programming
+@chapter Programming
+@cindex programming
+
+Here is a short introductory example to the @code{Asymptote} programming
+language that highlights the similarity of its control structures
+with those of C, C++, and Java:
+@cindex declaration
+@cindex assignment
+@cindex conditional
+@cindex loop
+@cindex @code{if}
+@cindex @code{else}
+@cindex @code{for}
+@verbatim
+// This is a comment.
+
+// Declaration: Declare x to be a real variable;
+real x;
+
+// Assignment: Assign the real variable x the value 1.
+x=1.0;
+
+// Conditional: Test if x equals 1 or not.
+if(x == 1.0) {
+ write("x equals 1.0");
+} else {
+ write("x is not equal to 1.0");
+}
+
+// Loop: iterate 10 times
+for(int i=0; i < 10; ++i) {
+ write(i);
+}
+
+@end verbatim
+
+@cindex @code{while}
+@cindex @code{do}
+@cindex @code{break}
+@cindex @code{continue}
+@code{Asymptote} supports @code{while}, @code{do}, @code{break}, and
+@code{continue} statements just as in C/C++. It also supports the Java-style
+shorthand for iterating over all elements of an array:
+
+@cindex array iteration
+@anchor{array iteration}
+@verbatim
+// Iterate over an array
+int[] array={1,1,2,3,5};
+for(int k : array) {
+ write(k);
+}
+@end verbatim
+@noindent
+In addition, it supports many features beyond the ones found in those languages.
+
+@menu
+* Data types:: void, bool, int, real, pair, triple, string
+* Paths and guides::
+* Pens:: Colors, line types, line widths, font sizes
+* Transforms:: Affine transforms
+* Frames and pictures:: Canvases for immediate and deferred drawing
+* Files:: Reading and writing your data
+* Variable initializers:: Initialize your variables
+* Structures:: Organize your data
+* Operators:: Arithmetic and logical operators
+* Implicit scaling:: Avoiding those ugly *s
+* Functions:: Traditional and high-order functions
+* Arrays:: Dynamic vectors
+* Casts:: Implicit and explicit casts
+* Import:: Importing external @code{Asymptote} packages
+* Static:: Where to allocate your variable?
+@end menu
+
+@node Data types
+@section Data types
+@cindex data types
+@code{Asymptote} supports the following data types (in addition to
+user-defined types):
+
+@table @code
+
+@item void
+@cindex @code{void}
+The void type is used only by functions that take or return no arguments.
+
+@item bool
+@cindex @code{bool}
+a boolean type that can only take on the values @code{true} or
+@code{false}. For example:
+@verbatim
+bool b=true;
+@end verbatim
+
+@noindent
+defines a boolean variable @code{b} and initializes it to the value
+@code{true}. If no initializer is given:
+@verbatim
+bool b;
+@end verbatim
+
+@noindent
+the value @code{false} is assumed.
+
+@item bool3
+@cindex @code{bool3}
+an extended boolean type that can take on the values
+@code{true}, @code{default}, or @code{false}. A bool3 type can be cast
+to or from a bool. The default initializer for bool3 is @code{default}.
+
+@item int
+@cindex @code{int}
+@cindex @code{intMin}
+@cindex @code{intMax}
+an integer type; if no initializer is given, the implicit value @code{0}
+is assumed. The minimum allowed value of an integer is @code{intMin} and the
+maximum value is @code{intMax}.
+
+@item real
+@cindex @code{real}
+@cindex @code{realMin}
+@cindex @code{realMax}
+@cindex @code{realEpsilon}
+@cindex @code{realDigits}
+a real number; this should be set to the highest-precision native
+floating-point type on the architecture. The implicit initializer for
+reals is @code{0.0}. Real numbers have precision
+@code{realEpsilon}, with @code{realDigits} significant digits.
+The smallest positive real number is @code{realMin} and the largest
+positive real number is @code{realMax}.
+
+@item pair
+@cindex @code{pair}
+complex number, that is, an ordered pair of real components @code{(x,y)}.
+The real and imaginary parts of a pair @code{z} can read as @code{z.x}
+and @code{z.y}. We say that @code{x} and @code{y} are virtual members of
+the data element pair; they cannot be directly modified, however.
+The implicit initializer for pairs is @code{(0.0,0.0)}.
+
+There are a number of ways to take the complex conjugate of a pair:
+@example
+pair z=(3,4);
+z=(z.x,-z.y);
+z=z.x-I*z.y;
+z=conj(z);
+@end example
+
+Here @code{I} is the pair @code{(0,1)}.
+A number of built-in functions are defined for pairs:
+
+@table @code
+@item pair conj(pair z)
+@cindex @code{conj}
+returns the conjugate of @code{z};
+
+@item real length(pair z)
+@cindex @code{length}
+@cindex @code{abs}
+returns the complex modulus @code{|z|} of its argument @code{z}.
+For example,
+@example
+pair z=(3,4);
+length(z);
+@end example
+returns the result 5. A synonym for @code{length(pair)} is @code{abs(pair)};
+
+@item real angle(pair z)
+@cindex @code{angle}
+returns the angle of @code{z} in radians in the interval
+[-@code{pi},@code{pi}];
+
+@item real degrees(pair z, bool warn=true)
+@cindex @code{degrees}
+returns the angle of @code{z} in degrees in the interval [0,360)
+or @code{0} if @code{warn} is @code{false} and @code{z.x=z.y=0} (rather than
+producing an error);
+
+@item pair unit(pair z)
+@cindex @code{unit}
+returns a unit vector in the direction of the pair @code{z};
+
+@item pair expi(real angle)
+@cindex @code{expi}
+returns a unit vector in the direction @code{angle} measured in radians;
+
+@item pair dir(real degrees)
+@cindex @code{dir}
+returns a unit vector in the direction @code{degrees} measured in degrees;
+
+@item real xpart(pair z)
+@cindex @code{xpart}
+returns @code{z.x};
+
+@item real ypart(pair z)
+@cindex @code{ypart}
+returns @code{z.y};
+
+@item pair realmult(pair z, pair w)
+@cindex @code{realmult}
+returns the element-by-element product @code{(z.x*w.x,z.y*w.y)};
+
+@item real dot(pair z, pair w)
+@cindex @code{dot}
+returns the dot product @code{z.x*w.x+z.y*w.y};
+
+@item pair minbound(pair z, pair w)
+@cindex @code{minbound}
+returns @code{(min(z.x,w.x),min(z.y,w.y))};
+
+@item pair maxbound(pair z, pair w)
+@cindex @code{maxbound}
+returns @code{(max(z.x,w.x),max(z.y,w.y))}.
+
+@end table
+
+@item triple
+@cindex @code{triple}
+an ordered triple of real components @code{(x,y,z)} used for
+three-dimensional drawings. The respective components of a triple
+@code{v} can read as @code{v.x}, @code{v.y}, and @code{v.z}.
+The implicit initializer for triples is @code{(0.0,0.0,0.0)}.
+
+Here are the built-in functions for triples:
+@table @code
+@item real length(triple v)
+@cindex @code{length}
+returns the length @code{|v|} of the vector @code{v}.
+A synonym for @code{length(triple)} is @code{abs(triple)};
+
+@item real polar(triple v)
+@cindex @code{polar}
+returns the colatitude of @code{v} measured from the @math{z} axis in radians;
+
+@item real azimuth(triple v)
+@cindex @code{azimuth}
+returns the longitude of @code{v} measured from the @math{x} axis in radians;
+
+@item real colatitude(triple v)
+@cindex @code{colatitude}
+returns the colatitude of @code{v} measured from the @math{z} axis in degrees;
+
+@item real latitude(triple v)
+@cindex @code{latitude}
+returns the latitude of @code{v} measured from the @math{xy} plane in degrees;
+
+@item real longitude(triple v, bool warn=true)
+@cindex @code{longitude}
+returns the longitude of @code{v} measured from the @math{x} axis in degrees;
+or @code{0} if @code{warn} is @code{false} and @code{v.x=v.y=0} (rather than
+producing an error);
+
+@item triple unit(triple v)
+@cindex @code{unit}
+returns a unit triple in the direction of the triple @code{v};
+
+@item triple expi(real polar, real azimuth)
+@cindex @code{expi}
+returns a unit triple in the direction @code{(polar,azimuth)}
+measured in radians;
+
+@item triple dir(real colatitude, real longitude)
+@cindex @code{dir}
+returns a unit triple in the direction @code{(colatitude,longitude)}
+measured in degrees;
+
+@item real xpart(triple v)
+@cindex @code{xpart}
+returns @code{v.x};
+
+@item real ypart(triple v)
+@cindex @code{ypart}
+returns @code{v.y};
+
+@item real zpart(triple v)
+@cindex @code{zpart}
+returns @code{v.z};
+
+@item real dot(triple u, triple v)
+@cindex @code{dot}
+returns the dot product @code{u.x*v.x+u.y*v.y+u.z*v.z};
+
+@item triple cross(triple u, triple v)
+@cindex @code{cross}
+returns the cross product
+
+@code{(u.y*v.z-u.z*v.y,u.z*v.x-u.x*v.z,u.x*v.y-v.x*u.y)};
+
+@item triple minbound(triple u, triple v)
+@cindex @code{minbound}
+returns @code{(min(u.x,v.x),min(u.y,v.y),min(u.z,v.z))};
+
+@item triple maxbound(triple u, triple v)
+@cindex @code{maxbound}
+returns @code{(max(u.x,v.x),max(u.y,v.y),max(u.z,v.z)}).
+
+@end table
+
+@item string
+@cindex @code{string}
+@cindex @TeX{} string
+a character string, implemented using the STL @code{string} class.
+
+Strings delimited by double quotes (@code{"}) are subject to the
+following mappings to allow the use of double quotes in @TeX{} (e.g.@ for
+using the @code{babel} package, @pxref{babel}):
+
+@itemize @bullet
+@item \" maps to "
+@item \\ maps to \\
+@end itemize
+
+@cindex @code{C} string
+Strings delimited by single quotes (@code{'}) have the same mappings as
+character strings in ANSI @code{C}:
+
+@itemize @bullet
+@item \' maps to '
+@item \" maps to "
+@item \? maps to ?
+@item \\ maps to backslash
+@item \a maps to alert
+@item \b maps to backspace
+@item \f maps to form feed
+@item \n maps to newline
+@item \r maps to carriage return
+@item \t maps to tab
+@item \v maps to vertical tab
+@item \0-\377 map to corresponding octal byte
+@item \x0-\xFF map to corresponding hexadecimal byte
+@end itemize
+
+The implicit initializer for strings is the empty string @code{""}.
+Strings may be concatenated with the @code{+} operator. In the following
+string functions, position @code{0} denotes the start of the string:
+@table @code
+
+@cindex @code{length}
+@item int length(string s)
+returns the length of the string @code{s};
+
+@cindex @code{find}
+@item int find(string s, string t, int pos=0)
+returns the position of the first occurrence of string @code{t} in string
+@code{s} at or after position @code{pos}, or -1 if @code{t} is not a
+substring of @code{s};
+
+@cindex @code{rfind}
+@item int rfind(string s, string t, int pos=-1)
+returns the position of the last occurrence of string @code{t} in string
+@code{s} at or before position @code{pos} (if @code{pos}=-1, at the end
+of the string @code{s}), or -1 if @code{t} is not a substring of @code{s};
+
+@cindex @code{insert}
+@item string insert(string s, int pos, string t)
+returns the string formed by inserting string @code{t} at position
+@code{pos} in @code{s};
+
+@cindex @code{erase}
+@item string erase(string s, int pos, int n)
+returns the string formed by erasing the string of length @code{n}
+(if @code{n}=-1, to the end of the string @code{s}) at
+position @code{pos} in @code{s};
+
+@cindex @code{substr}
+@item string substr(string s, int pos, int n=-1)
+returns the substring of @code{s} starting at position @code{pos}
+and of length @code{n} (if @code{n}=-1, until the end of the
+string @code{s});
+
+@cindex @code{reverse}
+@item string reverse(string s)
+returns the string formed by reversing string @code{s};
+
+@item string replace(string s, string before, string after)
+@cindex @code{replace}
+returns a string with all occurrences of the string @code{before} in the
+string @code{s} changed to the string @code{after};
+
+@item string replace(string s, string[][] table)
+returns a string constructed by translating in string @code{s} all
+occurrences of the string @code{before} in an array @code{table} of
+string pairs @{@code{before},@code{after}@} to the corresponding
+string @code{after};
+
+@cindex @code{split}
+@item string[] split(string s, string delimiter)
+returns an array of strings obtained by splitting @code{s} into substrings
+delimited by @code{delimiter};
+
+@anchor{format}
+@item string format(string s, int n)
+@cindex @code{format}
+returns a string containing @code{n} formatted according to the C-style
+format string @code{s} using the current locale;
+
+@item string format(string s, real x, string locale="")
+returns a string containing @code{x} formatted according to the C-style format
+string @code{s} using locale @code{locale} (or the current locale if an
+empty string is specified), following the behaviour of the C function
+@code{fprintf}), except that only one data field is allowed, trailing
+zeros are removed by default (unless @code{#} is specified), and @TeX{}
+is used to typeset scientific notation;
+
+@cindex @code{hex}
+@cindex @code{hexidecimal}
+@item int hex(string s);
+casts a hexidecimal string @code{s} to an integer.
+
+@cindex @code{string}
+@item string string(real x, int digits=realDigits)
+casts @code{x} to a string using precision @code{digits} and the C locale;
+
+@cindex @code{locale}
+@item string locale(string s="")
+sets the locale to the given string, if nonempty, and returns the
+current locale.
+
+@item string time(string format="%a %b %d %T %Z %Y")
+@cindex @code{time}
+@cindex @code{date}
+@cindex @code{strftime}
+returns the current time formatted by the ANSI C routine
+@code{strftime} according to the string @code{format} using the current
+locale. Thus
+@verbatim
+time();
+time("%a %b %d %H:%M:%S %Z %Y");
+@end verbatim
+
+@noindent
+are equivalent ways of returning the current time in the default
+format used by the @code{UNIX} @code{date} command;
+
+@cindex @code{seconds}
+@cindex @code{strptime}
+@item int seconds(string t="", string format="")
+returns the time measured in seconds after the Epoch (Thu Jan 01
+00:00:00 UTC 1970) as determined by the ANSI C routine @code{strptime}
+according to the string @code{format} using the current locale, or the
+current time if @code{t} is the empty string.
+Note that the @code{"%Z"} extension to the POSIX @code{strptime}
+specification is ignored by the current GNU C Library. If an error occurs, the
+value -1 is returned. Here are some examples:
+@verbatim
+seconds("Mar 02 11:12:36 AM PST 2007","%b %d %r PST %Y");
+seconds(time("%b %d %r %z %Y"),"%b %d %r %z %Y");
+seconds(time("%b %d %r %Z %Y"),"%b %d %r "+time("%Z")+" %Y");
+1+(seconds()-seconds("Jan 1","%b %d"))/(24*60*60);
+@end verbatim
+The last example returns today's ordinal date, measured from the
+beginning of the year.
+
+@cindex @code{time}
+@cindex @code{strftime}
+@item string time(int seconds, string format="%a %b %d %T %Z %Y")
+returns the time corresponding to @code{seconds} seconds after the Epoch
+(Thu Jan 01 00:00:00 UTC 1970) formatted by the ANSI C routine
+@code{strftime} according to the string @code{format} using the current
+locale. For example, to return the date corresponding to 24 hours ago:
+@verbatim
+time(seconds()-24*60*60);
+@end verbatim
+
+@cindex @code{abort}
+@item void abort(string s)
+aborts execution (with a non-zero return code in batch mode); if string
+@code{s} is nonempty, a diagnostic message constructed from the source
+file, line number, and @code{s} is printed;
+
+@cindex @code{exit}
+@item void exit()
+exits with a zero error return code in batch mode;
+
+@cindex @code{sleep}
+@item void sleep(int seconds)
+pauses for the given number of seconds;
+
+@cindex @code{usleep}
+@item void usleep(int microseconds)
+pauses for the given number of microseconds;
+
+@cindex @code{beep}
+@item void beep()
+produces a beep on the console;
+
+@end table
+
+@cindex @code{typedef}
+
+@end table
+
+As in C/C++, complicated types may be abbreviated with @code{typedef}
+(see the example in @ref{Functions}).
+
+@node Paths and guides
+@section Paths and guides
+
+@table @code
+
+@item path
+@cindex @code{path}
+a cubic spline resolved into a fixed path.
+The implicit initializer for paths is @code{nullpath}.
+
+@cindex @code{circle}
+@anchor{circle}
+For example, the routine @code{circle(pair c, real r)}, which returns a
+Bezier curve approximating a circle of radius @code{r} centered on @code{c},
+is based on @code{unitcircle} (@pxref{unitcircle}):
+@verbatim
+path circle(pair c, real r)
+{
+ return shift(c)*scale(r)*unitcircle;
+}
+@end verbatim
+If high accuracy is needed, a true circle may be produced with the
+routine @code{Circle} defined in the module @code{graph.asy}:
+@cindex @code{Circle}
+@verbatim
+import graph;
+path Circle(pair c, real r, int n=nCircle);
+@end verbatim
+
+A circular arc consistent with @code{circle} centered on
+@code{c} with radius @code{r} from @code{angle1} to @code{angle2}
+degrees, drawing counterclockwise if @code{angle2 >= angle1}, can be
+constructed with
+@cindex @code{arc}
+@verbatim
+path arc(pair c, real r, real angle1, real angle2);
+@end verbatim
+One may also specify the direction explicitly:
+@verbatim
+path arc(pair c, real r, real angle1, real angle2, bool direction);
+@end verbatim
+Here the direction can be specified as CCW (counter-clockwise) or CW
+(clockwise). For convenience, an arc centered at @code{c} from pair
+@code{z1} to @code{z2} (assuming @code{|z2-c|=|z1-c|}) in the may also
+be constructed with @verbatim
+path arc(pair c, explicit pair z1, explicit pair z2,
+ bool direction=CCW)
+@end verbatim
+
+If high accuracy is needed, true arcs may be produced with routines
+in the module @code{graph.asy} that produce Bezier curves with @code{n}
+control points:
+@cindex @code{Arc}
+@verbatim
+import graph;
+path Arc(pair c, real r, real angle1, real angle2, bool direction,
+ int n=nCircle);
+path Arc(pair c, real r, real angle1, real angle2, int n=nCircle);
+path Arc(pair c, explicit pair z1, explicit pair z2,
+ bool direction=CCW, int n=nCircle);
+@end verbatim
+
+An ellipse can be drawn with the routine
+@verbatim
+@cindex @code{ellipse}
+path ellipse(pair c, real a, real b)
+{
+ return shift(c)*scale(a,b)*unitcircle;
+}
+@end verbatim
+
+This example illustrates the use of all five guide connectors discussed
+in @ref{Tutorial}:
+@verbatiminclude join.asy
+@sp 1
+@center @image{join}
+
+Here are some useful functions for paths:
+
+@table @code
+
+@cindex @code{length}
+@item int length(path p);
+This is the number of (linear or cubic) segments in path @code{p}.
+If @code{p} is cyclic, this is the same as the number of nodes in @code{p}.
+
+@cindex @code{size}
+@item int size(path p);
+This is the number of nodes in the path @code{p}.
+If @code{p} is cyclic, this is the same as @code{length(p)}.
+
+@cindex @code{cyclic}
+@item bool cyclic(path p);
+returns @code{true} iff path @code{p} is cyclic.
+
+@cindex @code{straight}
+@item bool straight(path p, int i);
+returns @code{true} iff the segment of path @code{p} between node
+@code{i} and node @code{i+1} is straight.
+
+@cindex @code{piecewisestraight}
+@item bool piecewisestraight(path p)
+returns @code{true} iff the path @code{p} is piecewise straight.
+
+@cindex @code{point}
+@item pair point(path p, int t);
+If @code{p} is cyclic, return the coordinates of node @code{t} mod
+@code{length(p)}. Otherwise, return the coordinates of node @code{t},
+unless @code{t} < 0 (in which case @code{point(0)} is returned) or
+@code{t} > @code{length(p)} (in which case @code{point(length(p))}
+is returned).
+
+@item pair point(path p, real t);
+This returns the coordinates of the point between node @code{floor(t)}
+and @code{floor(t)+1} corresponding to the cubic spline parameter
+@code{t-floor(t)} (@pxref{Bezier}). If @code{t} lies outside the range
+[0,@code{length(p)}], it is first reduced modulo @code{length(p)}
+in the case where @code{p} is cyclic or else converted to the corresponding
+endpoint of @code{p}.
+
+@cindex @code{dir}
+@item pair dir(path p, int t, int sign=0, bool normalize=true);
+If @code{sign < 0}, return the direction (as a pair) of the incoming tangent
+to path @code{p} at node @code{t}; if @code{sign > 0}, return the
+direction of the outgoing tangent. If @code{sign=0}, the mean of these
+two directions is returned.
+
+@item pair dir(path p, real t, bool normalize=true);
+returns the direction of the tangent to path @code{p} at the point
+between node @code{floor(t)} and @code{floor(t)+1} corresponding to the
+cubic spline parameter @code{t-floor(t)} (@pxref{Bezier}).
+
+@cindex @code{accel}
+@item pair accel(path p, int t, int sign=0);
+If @code{sign < 0}, return the acceleration of the incoming path
+@code{p} at node @code{t}; if @code{sign > 0}, return the
+acceleration of the outgoing path. If @code{sign=0}, the mean of these
+two accelerations is returned.
+
+@cindex @code{accel}
+@item pair accel(path p, real t);
+returns the acceleration of the path @code{p} at the point @code{t}.
+
+@cindex @code{radius}
+@item pair radius(path p, real t);
+returns the radius of curvature of the path @code{p} at the point @code{t}.
+
+@cindex @code{precontrol}
+@item pair precontrol(path p, int t);
+returns the precontrol point of @code{p} at node @code{t}.
+
+@item pair precontrol(path p, real t);
+returns the effective precontrol point of @code{p} at parameter @code{t}.
+
+@cindex @code{postcontrol}
+@item pair postcontrol(path p, int t);
+returns the postcontrol point of @code{p} at node @code{t}.
+
+@item pair postcontrol(path p, real t);
+returns the effective postcontrol point of @code{p} at parameter @code{t}.
+
+@cindex @code{arclength}
+@item real arclength(path p);
+returns the length (in user coordinates) of the piecewise linear
+or cubic curve that path @code{p} represents.
+
+@anchor{arctime}
+@cindex @code{arctime}
+@item real arctime(path p, real L);
+returns the path "time", a real number between 0 and the length of
+the path in the sense of @code{point(path p, real t)}, at which the
+cumulative arclength (measured from the beginning of the path) equals @code{L}.
+
+@cindex @code{dirtime}
+@item real dirtime(path p, pair z);
+returns the first "time", a real number between 0 and the length of
+the path in the sense of @code{point(path, real)}, at which the tangent
+to the path has the direction of pair @code{z}, or -1 if this never happens.
+
+@cindex @code{reltime}
+@item real reltime(path p, real l);
+returns the time on path @code{p} at the relative fraction @code{l} of
+its arclength.
+
+@cindex @code{relpoint}
+@item pair relpoint(path p, real l);
+returns the point on path @code{p} at the relative fraction @code{l} of its
+arclength.
+
+@cindex @code{midpoint}
+@item pair midpoint(path p);
+returns the point on path @code{p} at half of its arclength.
+
+@cindex @code{reverse}
+@item path reverse(path p);
+returns a path running backwards along @code{p}.
+
+@cindex @code{subpath}
+@item path subpath(path p, int a, int b);
+returns the subpath of @code{p} running from node @code{a} to node @code{b}.
+If @code{a} < @code{b}, the direction of the subpath is reversed.
+
+@item path subpath(path p, real a, real b);
+returns the subpath of @code{p} running from path time @code{a} to path
+time @code{b}, in the sense of @code{point(path, real)}. If @code{a} <
+@code{b}, the direction of the subpath is reversed.
+
+@cindex @code{intersect}
+@item real[] intersect(path p, path q, real fuzz=-1);
+If @code{p} and @code{q} have at least one intersection point, return a
+real array of length 2 containing the times representing the respective
+path times along @code{p} and @code{q}, in the sense of
+@code{point(path, real)}, for one such intersection point (as chosen by
+the algorithm described on page 137 of @code{The MetaFontbook}).
+The computations are performed to the absolute error specified by @code{fuzz},
+or, if @code{fuzz < 0}, to machine precision. If the paths do not
+intersect, return a real array of length 0.
+
+@cindex @code{intersections}
+@item real[][] intersections(path p, path q, real fuzz=-1);
+Return all (unless there are infinitely many) intersection times of
+paths @code{p} and @code{q} as a sorted array of real arrays of length 2
+(@pxref{sort}). The computations are performed to the absolute error
+specified by @code{fuzz}, or, if @code{fuzz < 0}, to machine precision.
+
+@cindex @code{intersections}
+@item real[] intersections(path p, explicit pair a, explicit pair b,
+ real fuzz=-1);
+Return all (unless there are infinitely many) intersection times of path
+@code{p} with the (infinite) line through points @code{a} and @code{b}
+as a sorted array. The intersections returned are guaranteed to be
+correct to within the absolute error specified by @code{fuzz}, or, if
+@code{fuzz < 0}, to machine precision.
+
+@cindex @code{times}
+@item real[] times(path p, real x)
+returns all intersection times of path @code{p} with the vertical line
+through @code{(x,0)}.
+
+@cindex @code{times}
+@item real[] times(path p, explicit pair z)
+returns all intersection times of path @code{p} with the horizontal line
+through @code{(0,z.y)}.
+
+@cindex @code{mintimes}
+@item real[] mintimes(path p)
+returns an array of length 2 containing times at which path @code{p}
+reaches its minimal horizontal and vertical extents, respectively.
+
+@cindex @code{maxtimes}
+@item real[] maxtimes(path p)
+returns an array of length 2 containing the times at which path @code{p}
+reaches its maximal horizontal and vertical extents, respectively.
+
+@cindex @code{intersectionpoint}
+@item pair intersectionpoint(path p, path q, real fuzz=-1);
+returns the intersection point @code{point(p,intersect(p,q,fuzz)[0])}.
+
+@cindex @code{intersectionpoints}
+@item pair[] intersectionpoints(path p, path q, real fuzz=-1);
+returns an array containing all intersection points of the paths
+@code{p} and @code{q}.
+
+@anchor{extension}
+@cindex @code{whatever}
+@cindex @code{extension}
+@item pair extension(pair P, pair Q, pair p, pair q);
+returns the intersection point of the extensions of the line segments
+@code{P--Q} and @code{p--q}, or, if the lines are parallel,
+@code{(infinity,infinity)}.
+
+@cindex @code{cut}
+@cindex @code{slice}
+@item slice cut(path p, path knife, int n);
+returns the portions of path @code{p} before and after the @code{n}th
+intersection of @code{p} with path @code{knife} as a structure
+@code{slice} (if no intersection exist is found, the entire path is
+considered to be `before' the intersection):
+@verbatim
+struct slice {
+ path before,after;
+}
+@end verbatim
+The argument @code{n} is treated as modulo the number of intersections.
+
+@cindex @code{firstcut}
+@cindex @code{slice}
+@item slice firstcut(path p, path knife);
+equivalent to @code{cut(p,knife,0);}
+@cindex @code{MetaPost cutbefore}
+Note that @code{firstcut.after} plays the role of the @code{MetaPost
+cutbefore} command.
+
+@cindex @code{lastcut}
+@item slice lastcut(path p, path knife);
+equivalent to @code{cut(p,knife,-1);}
+@cindex @code{MetaPost cutafter}
+Note that @code{lastcut.before} plays the role of the
+@code{MetaPost cutafter} command.
+
+@cindex @code{buildcycle}
+@item path buildcycle(... path[] p);
+This returns the path surrounding a region bounded by a list of two or more
+consecutively intersecting paths, following the behaviour of the
+@code{MetaPost buildcycle} command.
+
+@cindex @code{min}
+@item pair min(path p);
+returns the pair (left,bottom) for the path bounding box of path @code{p}.
+
+@cindex @code{max}
+@item pair max(path p);
+returns the pair (right,top) for the path bounding box of path @code{p}.
+
+@cindex @code{windingnumber}
+@cindex @code{undefined}
+@item int windingnumber(path p, pair z);
+returns the winding number of the cyclic path @code{p} relative to the point
+@code{z}. The winding number is positive if the path encircles @code{z} in the
+counterclockwise direction. If @code{z} lies on @code{p} the constant
+@code{undefined} (defined to be the largest odd integer) is returned.
+
+@cindex @code{inside}
+@item bool inside(path p, pair z, pen fillrule=currentpen);
+returns @code{true} iff the point @code{z} is inside or on the edge of
+the region bounded by the cyclic path @code{p} according to the fill
+rule @code{fillrule} (@pxref{fillrule}).
+
+@cindex @code{inside}
+@item int inside(path p, path q, pen fillrule=currentpen);
+returns @code{1} if the cyclic path @code{p} strictly contains @code{q}
+according to the fill rule @code{fillrule} (@pxref{fillrule}), @code{-1}
+if the cyclic path @code{q} strictly contains @code{p}, and @code{0}
+otherwise.
+
+@cindex @code{inside}
+@item pair inside(path p, pen fillrule=currentpen);
+returns an arbitrary point strictly inside a cyclic path @code{p}
+according to the fill rule @code{fillrule} (@pxref{fillrule}).
+
+@cindex @code{strokepath}
+@item path[] strokepath(path g, pen p=currentpen);
+returns the path array that @code{PostScript} would fill in drawing path
+@code{g} with pen @code{p}.
+
+@end table
+
+@item guide
+@cindex @code{guide}
+an unresolved cubic spline (list of cubic-spline nodes and control points).
+The implicit initializer for a guide is @code{nullpath}; this is useful
+for building up a guide within a loop.
+
+A guide is similar to a path except that the computation of the cubic spline is
+deferred until drawing time (when it is resolved into a path); this allows
+two guides with free endpoint conditions to be joined together smoothly.
+The solid curve in the following example is built up incrementally as
+a guide, but only resolved at drawing time; the dashed curve is
+incrementally resolved at each iteration, before the entire set of nodes
+(shown in red) is known:
+
+@verbatiminclude mexicanhat.asy
+@sp 1
+@center @image{mexicanhat}
+
+We point out an efficiency distinction in the use of guides and paths:
+@verbatim
+guide g;
+for(int i=0; i < 10; ++i)
+ g=g--(i,i);
+path p=g;
+@end verbatim
+
+@noindent
+runs in linear time, whereas
+@verbatim
+path p;
+for(int i=0; i < 10; ++i)
+ p=p--(i,i);
+@end verbatim
+
+@noindent
+runs in quadratic time, as the entire path up to that point is copied at each
+step of the iteration.
+
+The following routines can be used to examine the individual elements of
+a guide without actually resolving the guide to a fixed path (except for
+internal cycles, which are resolved):
+
+@table @code
+
+@cindex @code{size}
+@item int size(guide g);
+Analogous to @code{size(path p)}.
+
+@cindex @code{length}
+@item int length(guide g);
+Analogous to @code{length(path p)}.
+
+@cindex @code{cyclic}
+@item bool cyclic(path p);
+Analogous to @code{cyclic(path p)}.
+
+@cindex @code{point}
+@item pair point(guide g, int t);
+Analogous to @code{point(path p, int t)}.
+
+@cindex @code{reverse}
+@item guide reverse(guide g);
+Analogous to @code{reverse(path p)}. If @code{g} is cyclic and
+also contains a secondary cycle, it is first solved to a
+path, then reversed. If @code{g} is not cyclic but contains an internal
+cycle, only the internal cycle is solved before reversal. If there are
+no internal cycles, the guide is reversed but not solved to a path.
+
+@cindex @code{dirSpecifier}
+@item pair[] dirSpecifier(guide g, int i);
+This returns a pair array of length 2 containing the outgoing (in
+element 0) and incoming (in element 1) direction specifiers (or
+@code{(0,0)} if none specified) for the segment of guide @code{g}
+between nodes @code{i} and @code{i+1}.
+
+@cindex @code{controlSpecifier}
+@item pair[] controlSpecifier(guide g, int i);
+If the segment of guide @code{g} between nodes @code{i} and @code{i+1}
+has explicit outgoing and incoming control points, they are returned as
+elements 0 and 1, respectively, of a two-element array. Otherwise, an
+empty array is returned.
+
+@cindex @code{tensionSpecifier}
+@item tensionSpecifier tensionSpecifier(guide g, int i);
+This returns the tension specifier for the segment of guide @code{g} between
+nodes @code{i} and @code{i+1}. The individual components of the
+@code{tensionSpecifier} type can be accessed as the virtual members
+@code{in}, @code{out}, and @code{atLeast}.
+
+@cindex @code{curlSpecifier}
+@item real[] curlSpecifier(guide g);
+This returns an array containing the initial curl specifier (in element 0)
+and final curl specifier (in element 1) for guide @code{g}.
+
+@end table
+
+As a technical detail we note that a direction specifier given to
+@code{nullpath} modifies the node on the other side: the guides
+@verbatim
+a..{up}nullpath..b;
+c..nullpath{up}..d;
+e..{up}nullpath{down}..f;
+@end verbatim
+are respectively equivalent to
+@verbatim
+a..nullpath..{up}b;
+c{up}..nullpath..d;
+e{down}..nullpath..{up}f;
+@end verbatim
+
+@end table
+
+@node Pens
+@section Pens
+
+@cindex @code{pen}
+@cindex @code{currentpen}
+@cindex @code{MetaPost pickup}
+In @code{Asymptote}, pens provide a context for the four basic drawing
+commands (@pxref{Drawing commands}). They are used to specify the
+following drawing attributes: color, line type, line width, line cap,
+line join, fill rule, text alignment, font, font size, pattern,
+overwrite mode, and calligraphic transforms on the pen nib. The
+default pen used by the drawing routines is called
+@code{currentpen}. This provides the same functionality as the
+@code{MetaPost} command @code{pickup}.
+The implicit initializer for pens is @code{defaultpen}.
+
+@cindex @code{+}
+@cindex @code{*}
+Pens may be added together with the nonassociative binary
+operator @code{+}. This will add the colors of the two pens.
+All other non-default attributes of the rightmost pen will
+override those of the leftmost pen. Thus, one can obtain a yellow
+dashed pen by saying @code{dashed+red+green} or @code{red+green+dashed}
+or @code{red+dashed+green}. The binary operator @code{*}
+can be used to scale the color of a pen by a real number, until it
+saturates with one or more color components equal to 1.
+
+@itemize @bullet
+
+@item Colors are specified using one of the following colorspaces:
+@cindex color
+@table @code
+@item pen gray(real g);
+@cindex @code{gray}
+@cindex grayscale
+This produces a grayscale color, where the intensity @code{g} lies in the
+interval [0,1], with 0.0 denoting black and 1.0 denoting white.
+
+@item pen rgb(real r, real g, real b);
+@cindex @code{rgb}
+This produces an @acronym{RGB} color, where each of the red, green,
+and blue intensities @code{r}, @code{g}, @code{b}, lies in the interval [0,1].
+
+@item pen cmyk(real c, real m, real y, real k);
+@cindex @code{cmyk}
+This produces a @acronym{CMYK} color, where each of the cyan, magenta,
+yellow, and black intensities @code{c}, @code{m}, @code{y}, @code{k},
+lies in the interval [0,1].
+
+@item pen invisible;
+@cindex @code{invisible}
+This special pen writes in invisible ink, but adjusts the bounding
+box as if something had been drawn (like the @code{\phantom}
+command in @TeX{}). The function @code{bool invisible(pen)} can be used
+to test whether a pen is invisible.
+
+@end table
+
+@cindex @code{defaultpen}
+The default color is @code{black}; this may be changed with the routine
+@code{defaultpen(pen)}. The function @code{colorspace(pen p)} returns
+the colorspace of pen @code{p} as a string (@code{"gray"}, @code{"rgb"},
+@code{"cmyk"}, or @code{""}).
+
+@cindex @code{colors}
+The function @code{real[] colors(pen)} returns the color components of a pen.
+The functions @code{pen gray(pen)}, @code{pen rgb(pen)}, and
+@code{pen cmyk(pen)} return new pens obtained by converting their
+arguments to the respective color spaces.
+@cindex @code{colorless}
+The function @code{colorless(pen=currentpen)} returns a copy of its argument
+with the color attributes stripped (to avoid color mixing).
+
+A 6-character RGB hexidecimal string can be converted to a pen with
+the routine
+@cindex @code{rgb}
+@cindex @code{hexidecimal}
+@verbatim
+pen rgb(string s);
+@end verbatim
+
+Various shades and mixtures of the grayscale primary colors
+@code{black} and @code{white}, @acronym{RGB} primary colors
+@code{red}, @code{green}, and @code{blue}, and
+@acronym{RGB} secondary colors @code{cyan}, @code{magenta}, and @code{yellow}
+are defined as named colors, along with the @acronym{CMYK} primary
+colors @code{Cyan}, @code{Magenta}, @code{Yellow}, and @code{Black}, in
+the module @code{plain}:
+@sp 1
+@center @image{colors}
+
+The standard 140 @acronym{RGB} @code{X11} colors can be imported with
+the command
+@verbatim
+import x11colors;
+@end verbatim
+and the standard 68 @acronym{CMYK} @TeX{} colors can be imported with
+the command
+@verbatim
+import texcolors;
+@end verbatim
+Note that there is some overlap between these two standards
+and the definitions of some colors (e.g.@ @code{Green}) actually disagree.
+
+@code{Asymptote} also comes with a @code{asycolors.sty} @code{LaTeX} package
+that defines to @code{LaTeX} @acronym{CMYK} versions of
+@code{Asymptote}'s predefined colors, so that they can be used
+directly within @code{LaTeX} strings. Normally, such colors are
+passed to @code{LaTeX} via a pen argument; however, to change the
+color of only a portion of a string, say for a slide presentation,
+(@pxref{slide}) it may be desirable to specify the color directly to
+@code{LaTeX}. This file can be passed to @code{LaTeX} with the
+@code{Asymptote} command
+@verbatim
+usepackage("asycolors");
+@end verbatim
+
+The structure @code{hsv} defined in @code{plain_pens.asy} may be used
+to convert between @acronym{HSV} and @acronym{RGB} spaces, where
+the hue @code{h} is an angle in @math{[0,360)} and the saturation
+@code{s} and value @code{v} lie in @code{[0,1]}:
+@verbatim
+pen p=hsv(180,0.5,0.75);
+write(p); // ([default], red=0.375, green=0.75, blue=0.75)
+hsv q=p;
+write(q.h,q.s,q.v); // 180 0.5 0.75
+@end verbatim
+
+@item Line types are specified with the function
+@code{pen linetype(string s, real offset=0, bool scale=true, bool adjust=true)},
+@cindex @code{solid}
+@cindex @code{dashed}
+@cindex @code{dotted}
+@cindex @code{longdashed}
+@cindex @code{dashdotted}
+@cindex @code{longdashdotted}
+where @code{s} is a string of integer or real numbers separated by spaces.
+The optional parameter @code{offset} specifies where in the pattern
+to begin. The first number specifies how far (if @code{scale} is
+@code{true}, in units of the pen line width; otherwise in
+@code{PostScript} units) to draw with the pen on, the second number
+specifies how far to draw with the pen off, and so on. If
+@code{adjust} is @code{true}, these spacings are automatically
+adjusted by @code{Asymptote} to fit the arclength of the path. Here
+are the predefined line types:
+@verbatim
+pen solid=linetype("");
+pen dotted=linetype("0 4");
+pen dashed=linetype("8 8");
+pen longdashed=linetype("24 8");
+pen dashdotted=linetype("8 8 0 8");
+pen longdashdotted=linetype("24 8 0 8");
+pen Dotted=dotted+1.0;
+pen Dotted(pen p=currentpen) {return dotted+2*linewidth(p);}
+@end verbatim
+@sp 1
+@center @image{linetype}
+
+@cindex @code{defaultpen}
+The default line type is @code{solid}; this may be changed with
+@code{defaultpen(pen)}.
+The line type of a pen is returned by @code{int linetype(pen p=currentpen)}.
+
+@cindex @code{linewidth}
+@cindex @code{defaultpen}
+@item The pen line width is specified in @code{PostScript} units with
+@code{pen linewidth(real)}. The default line width is 0.5 bp; this value
+may be changed with @code{defaultpen(pen)}. The line width of a pen
+is returned by @code{real linewidth(pen p=currentpen)}.
+For convenience, in the module @code{plain} we define
+@verbatim
+static void defaultpen(real w) {defaultpen(linewidth(w));}
+static pen operator +(pen p, real w) {return p+linewidth(w);}
+static pen operator +(real w, pen p) {return linewidth(w)+p;}
+@end verbatim
+so that one may set the line width like this:
+@verbatim
+defaultpen(2);
+pen p=red+0.5;
+@end verbatim
+
+@cindex @code{linecap}
+@cindex @code{squarecap}
+@cindex @code{roundcap}
+@cindex @code{extendcap}
+@cindex @code{defaultpen}
+@item A pen with a specific @code{PostScript} line cap is returned on
+calling @code{linecap} with an integer argument:
+@verbatim
+pen squarecap=linecap(0);
+pen roundcap=linecap(1);
+pen extendcap=linecap(2);
+@end verbatim
+
+@noindent
+The default line cap, @code{roundcap}, may be changed with
+@code{defaultpen(pen)}. The line cap of a pen is returned by
+@code{int linecap(pen p=currentpen)}.
+
+@cindex @code{linejoin}
+@cindex @code{miterjoin}
+@cindex @code{roundjoin}
+@cindex @code{beveljoin}
+@item A pen with a specific @code{PostScript} join style is returned on
+calling @code{linejoin} with an integer argument:
+@verbatim
+pen miterjoin=linejoin(0);
+pen roundjoin=linejoin(1);
+pen beveljoin=linejoin(2);
+@end verbatim
+
+@noindent
+The default join style, @code{roundjoin}, may be changed with
+@code{defaultpen(pen)}.The join style of a pen is returned by
+@code{int linejoin(pen p=currentpen)}.
+
+@cindex @code{miterlimit}
+@item A pen with a specific @code{PostScript} miter limit is returned by
+calling @code{miterlimit(real)}.
+The default miterlimit, @code{10.0}, may be changed with
+@code{defaultpen(pen)}. The miter limit of a pen is returned by
+@code{real miterlimit(pen p=currentpen)}.
+
+@cindex @code{fillrule}
+@cindex @code{zerowinding}
+@cindex @code{evenodd}
+@anchor{fillrule}
+@item A pen with a specific @code{PostScript} fill rule is returned on
+calling @code{fillrule} with an integer argument:
+@verbatim
+pen zerowinding=fillrule(0);
+pen evenodd=fillrule(1);
+@end verbatim
+
+@noindent
+The fill rule, which identifies the algorithm used to determine the
+insideness of a path or array of paths, only affects the @code{clip},
+@code{fill}, and @code{inside} functions. For the @code{zerowinding}
+fill rule, a point @code{z} is outside the region bounded by a path if
+the number of upward intersections of the path with the horizontal
+line @code{z--z+infinity} minus the number of downward intersections
+is zero. For the @code{evenodd} fill rule, @code{z} is considered to
+be outside the region if the total number of such intersections is even.
+The default fill rule, @code{zerowinding}, may be changed with
+@code{defaultpen(pen)}. The fill rule of a pen is returned by
+@code{int fillrule(pen p=currentpen)}.
+
+@cindex @code{nobasealign}
+@cindex @code{basealign}
+@anchor{basealign}
+@item A pen with a specific text alignment setting is returned on
+calling @code{basealign} with an integer argument:
+@verbatim
+pen nobasealign=basealign(0);
+pen basealign=basealign(1);
+@end verbatim
+
+@noindent
+The default setting, @code{nobasealign},which may be changed with
+@code{defaultpen(pen)}, causes the label alignment routines to use the
+full label bounding box for alignment. In contrast, @code{basealign}
+requests that the @TeX{} baseline be respected.
+The base align setting of a pen is returned by
+@code{int basealigin(pen p=currentpen)}.
+
+@cindex @code{fontsize}
+@cindex @code{lineskip}
+@cindex @code{defaultpen}
+@cindex @code{fix-cm}
+@item The font size is specified in @TeX{} points (1 pt = 1/72.27 inches) with
+the function @code{pen fontsize(real size, real lineskip=1.2*size)}.
+The default font size, 12pt, may be changed with @code{defaultpen(pen)}.
+Nonstandard font sizes may require inserting
+@verbatim
+import fontsize;
+@end verbatim
+at the beginning of the file (this requires the @code{fix-cm} package
+available from
+@quotation
+@url{http://www.ctan.org/tex-archive/help/Catalogue/entries/fix-cm}
+@end quotation
+and included in recent @code{LaTeX} distributions). The font size and line
+skip of a pen can be examined with the routines
+@code{real fontsize(pen p=currentpen)} and
+@code{real lineskip(pen p=currentpen)}, respectively.
+
+@cindex @code{font}
+@cindex @code{LaTeX fonts}
+@cindex @code{NFSS}
+@cindex @code{font command}
+@item A pen using a specific @code{LaTeX} @code{NFSS} font is returned
+by calling the function @code{pen font(string encoding, string family,
+string series="m", string shape="n")}. The default setting,
+@code{font("OT1","cmr","m","n")}, corresponds to 12pt Computer Modern Roman;
+this may be changed with @code{defaultpen(pen)}.
+The font setting of a pen is returned by
+@code{string font(pen p=currentpen)}.
+Support for standardized international characters is provided by the
+@code{unicode} package (@pxref{unicode}).
+
+@cindex @code{TeX fonts}
+Alternatively, one may select a fixed-size @TeX{} font (on which
+@code{fontsize} has no effect) like @code{"cmr12"} (12pt Computer Modern
+Roman) or @code{"pcrr"} (Courier) using the function @code{pen font(string
+name)}. An optional size argument can also be given to scale the font
+to the requested size: @code{pen font(string name, real size)}.
+
+@cindex @code{fontcommand}
+A nonstandard font command can be generated with
+@code{pen fontcommand(string)}.
+
+@cindex @code{PostScript fonts}
+A convenient interface to the following standard @code{PostScript}
+fonts is also provided:
+@verbatim
+pen AvantGarde(string series="m", string shape="n");
+pen Bookman(string series="m", string shape="n");
+pen Courier(string series="m", string shape="n");
+pen Helvetica(string series="m", string shape="n");
+pen NewCenturySchoolBook(string series="m", string shape="n");
+pen Palatino(string series="m", string shape="n");
+pen TimesRoman(string series="m", string shape="n");
+pen ZapfChancery(string series="m", string shape="n");
+pen Symbol(string series="m", string shape="n");
+pen ZapfDingbats(string series="m", string shape="n");
+@end verbatim
+
+@anchor{transparency}
+@cindex transparency
+@cindex @code{opacity}
+@item The transparency of a pen can be changed with the command:
+@verbatim
+pen opacity(real opacity=1, string blend="Compatible");
+@end verbatim
+The opacity can be varied from @code{0} (fully transparent) to the default
+value of @code{1} (opaque), and @code{blend} specifies one of the
+following foreground--background blending operations:
+@verbatim
+"Compatible","Normal","Multiply","Screen","Overlay","SoftLight",
+"HardLight","ColorDodge","ColorBurn","Darken","Lighten","Difference",
+"Exclusion","Hue","Saturation","Color","Luminosity",
+@end verbatim
+as described in
+
+@url{http://partners.adobe.com/public/developer/en/pdf/PDFReference16.pdf}.
+Since @code{PostScript} does not support transparency, this feature is
+only effective with the @code{-f pdf} output format option; other
+formats can be produced from the resulting @acronym{PDF} file with the
+@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
+@code{transparency.asy}.
+
+@cindex patterns
+@cindex tilings
+@item @code{PostScript} commands within a @code{picture} may be used
+to create a tiling pattern, identified by the string @code{name}, for
+@code{fill} and @code{draw} operations by adding it to the
+global @code{PostScript} frame @code{currentpatterns},
+with optional left-bottom margin @code{lb} and right-top margin @code{rt}.
+@verbatim
+import patterns;
+void add(string name, picture pic, pair lb=0, pair rt=0);
+@end verbatim
+
+To @code{fill} or @code{draw} using pattern @code{name}, use
+the pen @code{pattern("name")}. For example, rectangular tilings
+can be constructed using the routines
+@code{picture tile(real Hx=5mm, real Hy=0, pen p=currentpen,
+filltype filltype=NoFill)},
+@code{picture checker(real Hx=5mm, real Hy=0, pen p=currentpen)}, and
+@code{picture brick(real Hx=5mm, real Hy=0, pen p=currentpen)} defined in
+@code{patterns.asy}:
+@cindex grid
+@cindex tile
+@cindex checker
+@cindex brick
+@verbatiminclude tile.asy
+@sp 1
+@center @image{tile}
+
+@cindex hatch
+@cindex crosshatch
+Hatch patterns can be generated with the routines
+@code{picture hatch(real H=5mm, pair dir=NE, pen p=currentpen)},
+@code{picture crosshatch(real H=5mm, pen p=currentpen)}:
+@verbatiminclude hatch.asy
+@sp 1
+@center @image{hatch}
+
+You may need to turn off aliasing in your @code{PostScript} viewer for
+patterns to appear correctly. Custom patterns can easily be constructed,
+following the examples in @code{patterns.asy}. The tiled pattern can
+even incorporate shading (@pxref{gradient shading}), as illustrated
+in this example (not included in the manual because not all printers support
+@code{PostScript} 3):
+@verbatiminclude shadedtiling.asy
+
+@anchor{makepen}
+@cindex @code{makepen}
+@item One can specify a custom pen nib as an arbitrary polygonal path
+with @code{pen makepen(path)}; this path represents the mark to be
+drawn for paths containing a single point. This pen nib path can be
+recovered from a pen with @code{path nib(pen)}. Unlike in
+@code{MetaPost}, the path need not be convex:
+
+@verbatiminclude makepen.asy
+@sp 1
+@center @image{makepen}
+
+The value @code{nullpath} represents a circular pen nib (the default);
+an elliptical pen can be achieved simply by multiplying the pen by a
+transform: @code{yscale(2)*currentpen}.
+
+@anchor{overwrite}
+@cindex @code{overwrite}
+@item One can prevent labels from overwriting one another by using
+the pen attribute @code{overwrite}, which takes a single argument:
+
+@table @code
+@cindex @code{Allow}
+@cindex @code{defaultpen}
+@item Allow
+Allow labels to overwrite one another. This is the default behaviour (unless
+overridden with @code{defaultpen(pen)}.
+
+@cindex @code{Suppress}
+@item Suppress
+Suppress, with a warning, each label that would overwrite another label.
+
+@cindex @code{SuppressQuiet}
+@item SuppressQuiet
+Suppress, without warning, each label that would overwrite another label.
+
+@cindex @code{Move}
+@item Move
+Move a label that would overwrite another out of the way and issue a warning.
+As this adjustment is during the final output phase (in @code{PostScript}
+coordinates) it could result in a larger figure than requested.
+
+@cindex @code{MoveQuiet}
+@item MoveQuiet
+Move a label that would overwrite another out of the way, without warning.
+As this adjustment is during the final output phase (in @code{PostScript}
+coordinates) it could result in a larger figure than requested.
+
+@end table
+
+@end itemize
+
+@cindex @code{defaultpen}
+@cindex @code{resetdefaultpen}
+The routine @code{defaultpen()} returns the current default pen attributes.
+Calling the routine @code{resetdefaultpen()} resets all pen default
+attributes to their initial values.
+
+@node Transforms
+@section Transforms
+
+@cindex @code{transform}
+@code{Asymptote} makes extensive use of affine transforms. A pair
+@code{(x,y)} is transformed by the transform
+@code{t=(t.x,t.y,t.xx,t.xy,t.yx,t.yy)} to @code{(x',y')}, where
+@verbatim
+x' = t.x + t.xx * x + t.xy * y
+y' = t.y + t.yx * x + t.yy * y
+@end verbatim
+@noindent
+This is equivalent to the @code{PostScript} transformation
+@code{[t.xx t.yx t.xy t.yy t.x t.y]}.
+
+Transforms can be applied to pairs, guides, paths, pens, strings,
+transforms, frames, and pictures by multiplication (via the binary operator
+@code{*}) on the left (@pxref{circle} for an example).
+@cindex @code{inverse}
+Transforms can be composed with one another and inverted with the
+function @code{transform inverse(transform t)}; they can also be raised to any
+integer power with the @code{^} operator.
+
+The built-in transforms are:
+
+@table @code
+@item transform identity();
+@cindex @code{identity}
+the identity transform;
+@item transform shift(pair z);
+@cindex @code{shift}
+translates by the pair @code{z};
+@item transform shift(real x, real y);
+@cindex @code{shift}
+translates by the pair @code{(x,y)};
+@item transform xscale(real x);
+@cindex @code{xscale}
+scales by @code{x} in the @math{x} direction;
+@item transform yscale(real y);
+@cindex @code{yscale}
+scales by @code{y} in the @math{y} direction;
+@item transform scale(real s);
+@cindex @code{scale}
+scale by @code{s} in both @math{x} and @math{y} directions;
+@item transform scale(real x, real y);
+@cindex @code{scale}
+scale by @code{x} in the @math{x} direction and by @code{y} in the
+@math{y} direction;
+@item transform slant(real s);
+@cindex @code{slant}
+maps @code{(x,y)} --> @code{(x+s*y,y)};
+@item transform rotate(real angle, pair z=(0,0));
+rotates by @code{angle} in degrees about @code{z};
+@item transform reflect(pair a, pair b);
+@cindex @code{reflect}
+reflects about the line @code{a--b}.
+@end table
+
+@cindex @code{shift}
+@cindex @code{shiftless}
+The implicit initializer for transforms is @code{identity()}.
+The routines @code{shift(transform t)} and @code{shiftless(transform t)}
+return the transforms @code{(t.x,t.y,0,0,0,0)} and
+@code{(0,0,t.xx,t.xy,t.yx,t.yy)} respectively.
+
+
+@node Frames and pictures
+@section Frames and pictures
+
+@table @code
+
+@item frame
+@cindex @code{frame}
+@cindex @code{newframe}
+@cindex @code{empty}
+@cindex @code{erase}
+@cindex @code{min}
+@cindex @code{max}
+Frames are canvases for drawing in @code{PostScript} coordinates. While working
+with frames directly is occasionally necessary for constructing deferred
+drawing routines, pictures are usually more convenient to work with.
+The implicit initializer for frames is @code{newframe}. The function
+@code{bool empty(frame f)} returns @code{true} only if the frame @code{f}
+is empty. A frame may be erased with the @code{erase(frame)} routine.
+The functions @code{pair min(frame)} and @code{pair max(frame)}
+return the (left,bottom) and (right,top) coordinates of the frame
+bounding box, respectively. The contents of frame @code{src} may be
+appended to frame @code{dest} with the command
+@verbatim
+void add(frame dest, frame src);
+@end verbatim
+or prepended with
+@verbatim
+void prepend(frame dest, frame src);
+@end verbatim
+A frame obtained by aligning frame @code{f} in the direction
+@code{align}, in a manner analogous to the @code{align} argument of
+@code{label} (@pxref{label}), is returned by
+@verbatim
+frame align(frame f, pair align);
+@end verbatim
+
+@cindex @code{box}
+@cindex @code{ellipse}
+@anchor{envelope}
+@cindex @code{envelope}
+To draw or fill a box or ellipse around a label or frame and return the
+boundary as a path, use one of the predefined @code{envelope} routines
+@verbatim
+path box(frame f, Label L="", real xmargin=0,
+ real ymargin=xmargin, pen p=currentpen,
+ filltype filltype=NoFill, bool above=true);
+path roundbox(frame f, Label L="", real xmargin=0,
+ real ymargin=xmargin, pen p=currentpen,
+ filltype filltype=NoFill, bool above=true);
+path ellipse(frame f, Label L="", real xmargin=0,
+ real ymargin=xmargin, pen p=currentpen,
+ filltype filltype=NoFill, bool above=true);
+@end verbatim
+
+@item picture
+@cindex @code{picture}
+Pictures are high-level structures (@pxref{Structures}) defined in
+the module @code{plain} that provide canvases for drawing in user coordinates.
+The default picture is called @code{currentpicture}. A new picture
+can be created like this:
+@verbatim
+picture pic;
+@end verbatim
+@noindent
+Anonymous pictures can be made by the expression @code{new picture}.
+
+The @code{size} routine specifies the dimensions of the desired picture:
+
+@anchor{size}
+@cindex @code{size}
+@verbatim
+void size(picture pic=currentpicture, real x, real y=x,
+ bool keepAspect=Aspect);
+@end verbatim
+
+If the @code{x} and @code{y} sizes are both 0, user coordinates will be
+interpreted as @code{PostScript} coordinates. In this case, the transform
+mapping @code{pic} to the final output frame is @code{identity()}.
+
+If exactly one of @code{x} or @code{y} is 0, no size restriction
+is imposed in that direction; it will be scaled the same as the other
+direction.
+
+@cindex @code{Aspect}
+If @code{keepAspect} is set to @code{Aspect} or @code{true},
+the picture will be scaled with its aspect ratio preserved such that
+the final width is no more than @code{x} and the final height is
+no more than @code{y}.
+
+@cindex @code{IgnoreAspect}
+If @code{keepAspect} is set to @code{IgnoreAspect} or @code{false},
+the picture will be scaled in both directions so that the final width
+is @code{x} and the height is @code{y}.
+
+To make the user coordinates of picture @code{pic}
+represent multiples of @code{x} units in the @math{x} direction and
+@code{y} units in the @math{y} direction, use
+@anchor{unitsize}
+@cindex @code{unitsize}
+@verbatim
+void unitsize(picture pic=currentpicture, real x, real y=x);
+@end verbatim
+When nonzero, these @code{x} and @code{y} values override the
+corresponding size parameters of picture @code{pic}.
+
+The routine
+@cindex @code{size}
+@verbatim
+void size(picture pic=currentpicture, real xsize, real ysize,
+ pair min, pair max);
+@end verbatim
+forces the final picture scaling to map the user coordinates
+@code{box(min,max)} to a region of width @code{xsize} and height @code{ysize}
+(when these parameters are nonzero).
+
+Alternatively, calling the routine
+@cindex @code{fixedscaling}
+@verbatim
+transform fixedscaling(picture pic=currentpicture, pair min,
+ pair max, pen p=nullpen, bool warn=false);
+@end verbatim
+will cause picture @code{pic} to use a fixed scaling to map user
+coordinates in @code{box(min,max)} to the (already specified) picture size,
+taking account of the width of pen @code{p}. A warning will be issued if
+the final picture exceeds the specified size.
+
+A picture @code{pic} can be fit to a frame and output to a file
+@code{prefix}.@code{format} using image format @code{format}
+by calling the @code{shipout} function:
+@anchor{shipout}
+@cindex @code{shipout}
+@verbatim
+void shipout(string prefix=defaultfilename, picture pic,
+ orientation orientation=orientation,
+ string format="", bool wait=false, bool view=true);
+void shipout(string prefix=defaultfilename,
+ orientation orientation=orientation,
+ string format="", bool wait=false, bool view=true);
+@end verbatim
+@noindent
+The default output format, @code{PostScript}, may be changed
+with the @code{-f} or @code{-tex} command-line options.
+A @code{shipout()} command is added implicitly at file exit if no
+previous @code{shipout} commands have been executed.
+@cindex @code{orientation}
+@cindex @code{Portrait}
+@cindex @code{Landscape}
+@cindex @code{UpsideDown}
+The default page orientation is @code{Portrait}; this may be modified
+by changing the variable @code{orientation}. To output in landscape
+mode, simply set the variable @code{orientation=Landscape} or issue
+the command
+@verbatim
+shipout(Landscape);
+@end verbatim
+
+@cindex @code{Seascape}
+To rotate the page by @math{-90} degrees, use the orientation @code{Seascape}.
+@cindex @code{UpsideDown}
+The orientation @code{UpsideDown} rotates the page by 180 degrees.
+
+@cindex subpictures
+@cindex @code{fit}
+A picture @code{pic} can be explicitly fit to a frame by calling
+@verbatim
+frame pic.fit(real xsize=pic.xsize, real ysize=pic.ysize,
+ bool keepAspect=pic.keepAspect);
+@end verbatim
+The default size and aspect ratio settings are those given to the
+@code{size} command (which default to @code{0}, @code{0}, and
+@code{true}, respectively).
+@cindex @code{calculateTransform}
+The transformation that would currently be used to fit a picture
+@code{pic} to a frame is returned by the member function
+@code{pic.calculateTransform()}.
+
+In certain cases (e.g.@ 2D graphs) where only an approximate size
+estimate for @code{pic} is available, the picture fitting routine
+@verbatim
+frame pic.scale(real xsize=this.xsize, real ysize=this.ysize,
+ bool keepAspect=this.keepAspect);
+@end verbatim
+(which scales the resulting frame, including labels and fixed-size
+objects) will enforce perfect compliance with the requested size
+specification, but should not normally be required.
+
+@cindex @code{box}
+To draw a bounding box with margins around a picture, fit the
+picture to a frame using the function
+@verbatim
+frame bbox(picture pic=currentpicture, real xmargin=0,
+ real ymargin=xmargin, pen p=currentpen,
+ filltype filltype=NoFill);
+@end verbatim
+@anchor{filltype}
+Here @code{filltype} specifies one of the following fill types:
+@table @code
+@cindex @code{FillDraw}
+@item FillDraw
+Fill the interior and draw the boundary.
+
+@item FillDraw(real xmargin=0, real ymargin=xmargin, pen fillpen=nullpen,
+ @code{pen drawpen=nullpen);}
+@cindex @code{nullpen}
+If @code{fillpen} is @code{nullpen}, fill with the drawing pen;
+otherwise fill with pen @code{fillpen}.
+If @code{drawpen} is @code{nullpen}, draw the boundary with @code{fillpen};
+otherwise with @code{drawpen}. An optional margin of
+@code{xmargin} and @code{ymargin} can be specified.
+
+@cindex @code{Fill}
+@item Fill
+Fill the interior.
+
+@cindex @code{nullpen}
+@item Fill(real xmargin=0, real ymargin=xmargin, pen p=nullpen)
+If @code{p} is @code{nullpen}, fill with the drawing pen;
+otherwise fill with pen @code{p}. An optional margin of
+@code{xmargin} and @code{ymargin} can be specified.
+
+@cindex @code{NoFill}
+@item NoFill
+Do not fill.
+
+@item Draw
+Draw only the boundary.
+
+@cindex @code{Draw}
+@item Draw(real xmargin=0, real ymargin=xmargin, pen p=nullpen)
+If @code{p} is @code{nullpen}, draw the boundary with the drawing pen;
+otherwise draw with pen @code{p}. An optional margin of
+@code{xmargin} and @code{ymargin} can be specified.
+
+@cindex @code{UnFill}
+@item UnFill
+Clip the region.
+
+@cindex @code{UnFill}
+@item UnFill(real xmargin=0, real ymargin=xmargin)
+Clip the region and surrounding margins @code{xmargin} and @code{ymargin}.
+
+@cindex @code{RadialShade}
+@item RadialShade(pen penc, pen penr)
+Fill varying radially from @code{penc} at the center of the bounding
+box to @code{penr} at the edge.
+
+@end table
+
+@cindex bounding box
+@cindex background color
+For example, to draw a bounding box around a picture with a 0.25 cm
+margin and output the resulting frame, use the command:
+@verbatim
+shipout(bbox(0.25cm));
+@end verbatim
+A @code{picture} may be fit to a frame with the background color of
+pen @code{p} with the function @code{bbox(p,Fill)}.
+
+The functions
+@verbatim
+pair min(picture pic, user=false);
+pair max(picture pic, user=false);
+pair size(picture pic, user=false);
+@end verbatim
+calculate the @code{PostScript} bounds that picture @code{pic} would
+have if it were currently fit to a frame using its default size specification.
+If @code{user} is @code{false} the returned value is in
+@code{PostScript} coordinates, otherwise it is in user coordinates.
+
+The function
+@verbatim
+pair point(picture pic=currentpicture, pair dir, bool user=true);
+@end verbatim
+is a convenient way of determining the point on the bounding box of
+@code{pic} in the direction @code{dir} relative to its center, ignoring
+the contributions from fixed-size objects (such as labels and arrowheads).
+If @code{user} is @code{true} the returned value is in user coordinates,
+otherwise it is in @code{PostScript} coordinates.
+
+The function
+@verbatim
+pair truepoint(picture pic=currentpicture, pair dir, bool user=true);
+@end verbatim
+is identical to @code{point}, except that it also accounts for
+fixed-size objects, using the scaling transform that picture @code{pic}
+would have if currently fit to a frame using its default size
+specification. If @code{user} is @code{true} the returned value is in
+user coordinates, otherwise it is in @code{PostScript} coordinates.
+
+@anchor{add}
+Sometimes it is useful to draw objects on separate pictures and add one
+picture to another using the @code{add} function:
+@cindex @code{add}
+@verbatim
+void add(picture src, bool group=true,
+ filltype filltype=NoFill, bool above=true);
+void add(picture dest, picture src, bool group=true,
+ filltype filltype=NoFill, bool above=true);
+@end verbatim
+@noindent
+The first example adds @code{src} to @code{currentpicture}; the second
+one adds @code{src} to @code{dest}.
+The @code{group} option specifies whether or not the graphical user
+interface @code{xasy} should treat all of the elements of @code{src}
+as a single entity (@pxref{GUI}), @code{filltype} requests optional
+background filling or clipping, and @code{above} specifies
+whether to add @code{src} above or below existing objects.
+
+There are also routines to add a picture or frame @code{src} specified
+in postscript coordinates to another picture @code{dest} (or
+@code{currentpicture}) about the user coordinate
+@code{position}:
+@anchor{add about}
+@cindex @code{add}
+@cindex picture alignment
+@verbatim
+void add(picture src, pair position, bool group=true,
+ filltype filltype=NoFill, bool above=true);
+void add(picture dest, picture src, pair position,
+ bool group=true, filltype filltype=NoFill, bool above=true);
+void add(picture dest=currentpicture, frame src, pair position=0,
+ bool group=true, filltype filltype=NoFill, bool above=true);
+void add(picture dest=currentpicture, frame src, pair position,
+ pair align, bool group=true, filltype filltype=NoFill,
+ bool above=true);
+@end verbatim
+
+The optional @code{align} argument in the last three forms specifies a
+direction to use for aligning the frame, in a manner analogous to the
+@code{align} argument of @code{label} (@pxref{label}). However, one key
+difference is that when @code{align} is not specified, labels are
+centered, whereas frames and pictures are aligned so that their origin is
+at @code{position}. Illustrations of frame alignment can be found in
+the examples @ref{errorbars} and @ref{image}. If you want to align three
+or more subpictures, group them two at a time:
+
+@verbatiminclude subpictures.asy
+@sp 1
+@center @image{subpictures}
+
+Alternatively, one can use @code{attach} to automatically increase the
+size of picture @code{dest} to accommodate adding a frame @code{src}
+about the user coordinate @code{position}:
+@verbatim
+void attach(picture dest=currentpicture, frame src,
+ pair position=0, bool group=true,
+ filltype filltype=NoFill, bool above=true);
+void attach(picture dest=currentpicture, frame src,
+ pair position, pair align, bool group=true,
+ filltype filltype=NoFill, bool above=true);
+@end verbatim
+
+@cindex @code{erase}
+To erase the contents of a picture (but not the size specification), use
+the function
+@verbatim
+void erase(picture pic=currentpicture);
+@end verbatim
+
+@cindex @code{save}
+To save a snapshot of @code{currentpicture}, @code{currentpen}, and
+@code{currentprojection}, use the function @code{save()}.
+
+@cindex @code{restore}
+To restore a snapshot of @code{currentpicture}, @code{currentpen}, and
+@code{currentprojection}, use the function @code{restore()}.
+
+Many further examples of picture and frame operations are provided in
+the base module @code{plain}.
+
+@cindex verbatim
+@cindex @code{postscript}
+It is possible to insert verbatim @code{PostScript} commands in a picture with
+one of the routines
+@verbatim
+void postscript(picture pic=currentpicture, string s);
+void postscript(picture pic=currentpicture, string s, pair min,
+ pair max)
+@end verbatim
+Here @code{min} and @code{max} can be used to specify explicit bounds
+associated with the resulting @code{PostScript} code.
+
+@anchor{tex}
+@cindex @code{tex}
+Verbatim @TeX{} commands can be inserted in the intermediate
+@code{LaTeX} output file with one of the functions
+@verbatim
+void tex(picture pic=currentpicture, string s);
+void tex(picture pic=currentpicture, string s, pair min, pair max)
+@end verbatim
+Here @code{min} and @code{max} can be used to specify explicit bounds
+associated with the resulting @TeX{} code.
+
+To issue a global @TeX{} command (such as a @TeX{} macro definition) in the
+@TeX{} preamble (valid for the remainder of the top-level module) use:
+@cindex @code{texpreamble}
+@verbatim
+void texpreamble(string s);
+@end verbatim
+
+The @TeX{} environment can be reset to its initial state, clearing all
+macro definitions, with the function
+@cindex @code{texreset}
+@verbatim
+void texreset();
+@end verbatim
+
+@cindex @code{usepackage}
+The routine
+@verbatim
+void usepackage(string s, string options="");
+@end verbatim
+provides a convenient abbreviation for
+@verbatim
+texpreamble("\usepackage["+options+"]{"+s+"}");
+@end verbatim
+@noindent
+that can be used for importing @code{LaTeX} packages.
+
+@end table
+
+@node Files
+@section Files
+
+@cindex @code{file}
+@code{Asymptote} can read and write text files (including comma-separated
+value) files and portable @acronym{XDR} (External Data Representation)
+binary files.
+
+An input file must first be opened with
+@code{input(string name, bool check=true, string comment="#")};
+reading is then done by assignment:
+@cindex open
+@cindex @code{input}
+@cindex reading
+@verbatim
+file fin=input("test.txt");
+real a=fin;
+@end verbatim
+
+@cindex comment character
+@cindex @code{error}
+If the optional boolean argument @code{check} is @code{false}, no check will
+be made that the file exists. If the file does not exist or is not
+readable, the function @code{bool error(file)} will return @code{true}.
+The first character of the string @code{comment} specifies a
+comment character. If this character is encountered in a data file,
+the remainder of the line is ignored. When reading strings, a comment
+character followed immediately by another comment character is treated
+as a single literal comment character.
+
+@anchor{cd}
+@cindex @code{cd}
+@cindex directory
+If the @code{-globalwrite} (or @code{-nosafe}) option is enabled, one can
+change the current working directory to the contents of the string
+@code{s} with the function @code{string cd(string s)}, which returns the
+new working directory. If @code{string s} is empty, the path is reset to
+the value it had at program startup.
+
+@cindex @code{getc}
+When reading pairs, the enclosing parenthesis are optional.
+Strings are also read by assignment, by reading characters up to but not
+including a newline. In addition, @code{Asymptote} provides the function
+@code{string getc(file)} to read the next character (treating the
+comment character as an ordinary character) and return it as a string.
+
+@cindex @code{output}
+@cindex @code{update}
+@cindex append
+A file named @code{name} can be open for output with
+@verbatim
+file output(string name, bool update=false);
+@end verbatim
+@noindent
+If @code{update=false}, any existing data in the file will be erased
+and only write operations can be used on the file.
+If @code{update=true}, any existing data will be preserved, the position
+will be set to the end-of-file, and both reading and writing operations
+will be enabled. For security reasons, writing to files in directories
+other than the current directory is allowed only if the @code{-globalwrite}
+(or @code{-nosafe}) command-line option is specified.
+
+@cindex @code{stdin}
+@cindex @code{stdout}
+There are two special files: @code{stdin}, which reads from the keyboard,
+and @code{stdout}, which writes to the terminal. The implicit
+initializer for files is @code{null}.
+
+Data of a built-in type @code{T} can be written to an output file by
+calling one of the functions
+@cindex @code{write}
+@verbatim
+write(string s="", T x, suffix suffix=endl ... T[]);
+write(file file, string s="", T x, suffix suffix=none ... T[]);
+write(file file=stdout, string s="", explicit T[] x ... T[][]);
+write(file file=stdout, T[][]);
+write(file file=stdout, T[][][]);
+write(suffix suffix=endl);
+write(file file, suffix suffix=none);
+@end verbatim
+@cindex @code{none}
+@cindex @code{flush}
+@cindex @code{endl}
+@cindex @code{newl}
+@cindex @code{tab}
+@cindex @code{comma}
+If @code{file} is not specified, @code{stdout} is used and
+terminated by default with a newline. If specified, the optional
+identifying string @code{s} is written before the data @code{x}.
+An arbitrary number of data values may be listed when writing scalars
+or one-dimensional arrays. The @code{suffix} may be one of the following:
+@code{none} (do nothing), @code{flush} (output buffered data),
+@code{endl} (terminate with a newline and flush),
+@code{newl} (terminate with a newline),
+@code{tab} (terminate with a tab), or @code{comma} (terminate with a
+comma). Here are some simple examples of data output:
+@verbatim
+file fout=output("test.txt");
+write(fout,1); // Writes "1"
+write(fout); // Writes a new line
+write(fout,"List: ",1,2,3); // Writes "List: 1 2 3"
+@end verbatim
+@noindent
+
+@cindex binary format
+@cindex @code{xinput}
+@cindex @code{xoutput}
+@cindex @code{binput}
+@cindex @code{boutput}
+@cindex @code{single}
+@cindex @code{double}
+A file may also be opened with @code{xinput} or @code{xoutput}, instead of
+@code{input} or @code{output}, to read or write
+double precision (64-bit) real values and single precision (32-bit)
+integer values in Sun Microsystem's @acronym{XDR} (External
+Data Representation) portable binary format (available on all
+@code{UNIX} platforms).
+A file may also be opened with @code{binput} or @code{boutput} to read
+or write double precision values in the native (nonportable)
+machine binary format. The function @code{file single(file,0.0)} may
+be used to set a file to read single precision real @acronym{XDR} or binary
+values; calling @code{file single(file,0.0,false)} sets it back to read
+doubles again. The functions @code{file single(file,0)} and
+@code{file single(file,0,false)} can be used to change the default
+integer precision (single). The functions @code{file
+single(file)} and @code{file single(file,false)} may be used to set the
+precision for both real and integer values.
+
+@cindex @code{eof}
+@cindex @code{eol}
+@cindex @code{error}
+@cindex @code{flush}
+@cindex @code{clear}
+@cindex @code{precision}
+@cindex @code{seek}
+@cindex @code{tell}
+@cindex rewind
+@cindex @code{seekeof}
+One can test a file for end-of-file with the boolean function @code{eof(file)},
+end-of-line with @code{eol(file)}, and for I/O errors with @code{error(file)}.
+One can flush the output buffers with @code{flush(file)}, clear a
+previous I/O error with @code{clear(file)}, and close the file with
+@code{close(file)}. The function
+@code{int precision(file file=stdout, int digits=0)}
+sets the number of digits of output precision for @code{file} to @code{digits},
+provided @code{digits} is nonzero, and returns the previous
+precision setting. The function @code{int tell(file)} returns
+the current position in a file relative to the beginning.
+The routine @code{seek(file file, int pos)} can be used to
+change this position, where a negative value for the position @code{pos}
+is interpreted as relative to the end-of-file. For example, one can
+rewind a file @code{file} with the command @code{seek(file,0)}
+and position to the final character in the file with @code{seek(file,-1)}.
+The command @code{seekeof(file)} sets the position to the end of the file.
+
+@cindex @code{scroll}
+@anchor{scroll}
+Assigning @code{settings.scroll=n} for a positive integer @code{n}
+requests a pause after every @code{n} output lines to @code{stdout}.
+One may then press @code{Enter} to continue to the next @code{n} output lines,
+@code{s} followed by @code{Enter} to scroll without further interruption,
+or @code{q} followed by @code{Enter} to quit the current output
+operation. If @code{n} is negative, the output scrolls a page at a time
+(i.e. by one less than the current number of display lines). The default
+value, @code{settings.scroll=0}, specifies continuous scrolling.
+
+The routines
+@cindex @code{getstring}
+@cindex @code{getreal}
+@cindex @code{getpair}
+@cindex @code{gettriple}
+@verbatim
+string getstring(string name="", string default="", string prompt="",
+ bool store=true);
+int getint(string name="", int default=0, string prompt="",
+ bool store=true);
+real getreal(string name="", real default=0, string prompt="",
+ bool store=true);
+pair getpair(string name="", pair default=0, string prompt="",
+ bool store=true);
+triple gettriple(string name="", triple default=(0,0,0), string prompt="",
+ bool store=true);
+@end verbatim
+@noindent
+defined in the module @code{plain} may be used to prompt for a value from
+@code{stdin} using the @acronym{GNU} @code{readline} library.
+If @code{store=true}, the history of values for @code{name} is
+stored in the file @code{".asy_history_"+name} (@pxref{history}). The most
+recent value in the history will be used to provide a default value
+for subsequent runs. The default value (initially @code{default}) is
+displayed after @code{prompt}. These functions are based on the internal
+routines
+@cindex @code{readline}
+@cindex @code{saveline}
+@verbatim
+string readline(string prompt="", string name="", bool tabcompletion=false);
+void saveline(string name, string value, bool store=true);
+@end verbatim
+Here, @code{readline} prompts the user with the default value
+formatted according to @code{prompt}, while @code{saveline}
+is used to save the string @code{value} in a local history named
+@code{name}, optionally storing the local history in a file
+@code{".asy_history_"+name}.
+
+@cindex @code{history}
+The routine @code{history(string name, int n=1)} can be used to look up
+the @code{n} most recent values (or all values up to @code{historylines}
+if @code{n=0}) entered for string @code{name}.
+The routine @code{history(int n=0)} returns the interactive history.
+For example,
+@verbatim
+write(output("transcript.asy"),history());
+@end verbatim
+@noindent
+outputs the interactive history to the file @code{transcript.asy}.
+
+@cindex @code{delete}
+The function @code{int delete(string s)} deletes the file named by the
+string @code{s}. Unless the @code{-globalwrite} (or @code{-nosafe})
+option is enabled, the file must reside in the current directory.
+@cindex @code{rename}
+The function @code{int rename(string from, string to)} may be used to
+rename file @code{from} to file @code{to}.
+Unless the @code{-globalwrite} (or @code{-nosafe}) option is enabled,
+this operation is restricted to the current directory.
+@cindex @code{convert}
+@cindex @code{animate}
+The functions
+@verbatim
+int convert(string args="", string file="", string format="");
+int animate(string args="", string file="", string format="");
+@end verbatim
+@noindent
+call the @code{ImageMagick} commands @code{convert} and @code{animate},
+respectively, with the arguments @code{args} and the file name constructed
+from the strings @code{file} and @code{format}.
+@cindex @code{system}
+If the setting @code{safe} is false, then the function
+@code{int system(string s)} can be used to call the arbitrary system
+command @code{s}.
+
+@node Variable initializers
+@section Variable initializers
+@cindex variable initializers
+@cindex @code{operator init}
+@cindex initializers
+
+A variable can be assigned a value when it is declared, as in
+@code{int x=3;} where the variable @code{x} is assigned the value @code{3}.
+As well as literal constants such as @code{3}, arbitary expressions can be used
+as initializers, as in @code{real x=2*sin(pi/2);}.
+
+A variable is not added to the namespace until after the initializer is
+evaluated, so for example, in
+
+@verbatim
+int x=2;
+int x=5*x;
+@end verbatim
+@noindent
+the @code{x} in the initializer on the second line refers to the variable
+@code{x} declared on the first line. The second line, then, declares a variable
+@code{x} shadowing the original @code{x} and initializes it to the value
+@code{10}.
+
+Variables of most types can be declared without an explicit initializer and they
+will be initialized by the default initializer of that type:
+
+@itemize
+@item Variables of the numeric types @code{int}, @code{real}, and @code{pair}
+are all initialized to zero; variables of type @code{triple} are
+initialized to @code{O=(0,0,0)}.
+@item @code{boolean} variables are initialized to @code{false}.
+@item @code{string} variables are initialized to the empty string.
+@item @code{transform} variables are initialized to the identity transformation.
+@item @code{path} and @code{guide} variables are initialized to
+@code{nullpath}.
+@item @code{pen} variables are initialized to the default pen.
+@item @code{frame} and @code{picture} variables are initialized to empty
+frames and pictures, respectively.
+@item @code{file} variables are initialized to @code{null}.
+@end itemize
+
+The default initializers for user-defined array, structure, and function types
+are explained in their respective sections. Some types, such as
+@code{code}, do not have default initializers. When a variable of such
+a type is introduced, the user must initialize it by explicitly giving
+it a value.
+
+The default initializer for any type @code{T} can be redeclared by defining the
+function @code{T operator init()}. For instance, @code{int} variables are
+usually initialized to zero, but in
+
+@verbatim
+int operator init() {
+ return 3;
+}
+int y;
+@end verbatim
+
+@noindent
+the variable @code{y} is initialized to @code{3}. This example was given for
+illustrative purposes; redeclaring the initializers of built-in types is not
+recommended. Typically, @code{operator init} is used to define sensible
+defaults for user-defined types.
+
+@node Structures
+@section Structures
+@cindex @code{struct}
+@cindex structures
+@cindex @code{public}
+@cindex @code{restricted}
+@cindex @code{private}
+@cindex @code{this}
+@cindex @code{new}
+@cindex @code{null}
+
+Users may also define their own data types as structures, along with
+user-defined operators, much as in C++. By default, structure members
+are @code{public} (may be read and modified anywhere in the code), but may be
+optionally declared @code{restricted} (readable anywhere but writeable
+only inside the structure where they are defined) or @code{private}
+(readable and writable only inside the structure). In a structure definition,
+the keyword @code{this} can be used as an expression to refer to the enclosing
+structure. Any code at the
+top-level scope within the structure is executed on initialization.
+
+Variables hold references to structures. That is, in the example:
+
+@verbatim
+struct T {
+ int x;
+}
+
+T foo=new T;
+T bar=foo;
+bar.x=5;
+@end verbatim
+
+The variable @code{foo} holds a reference to an instance of the structure
+@code{T}. When @code{bar} is assigned the value of @code{foo}, it too
+now holds a reference to the same instance as @code{foo} does. The assignment
+@code{bar.x=5} changes the value of the field @code{x} in that instance, so
+that @code{foo.x} will also be equal to @code{5}.
+
+The expression @code{new T} creates a new instance of the structure @code{T} and
+returns a reference to that instance. In creating the new instance, any code in
+the body of the record definition is executed. For example:
+
+@verbatim
+int Tcount=0;
+struct T {
+ int x;
+ ++Tcount;
+}
+
+T foo=new T;
+@end verbatim
+
+Here, the expression @code{new T} will produce a new instance of the class, but
+will also cause @code{Tcount} to be incremented, so that it keeps track of the
+number of instances produced.
+
+The expression @code{null} can be cast to any structure type to yield a null
+reference, a reference that does not actually refer to any instance of the
+structure. Trying to use a field of a null reference will cause an error.
+
+@cindex alias
+@cindex @code{==}
+@cindex @code{!=}
+The function @code{bool alias(T,T)} checks to see if two structure references
+refer to the same instance of the structure (or both to @code{null}). For
+example, in the example code at the start of the section, @code{alias(foo,bar)}
+would return true, but @code{alias(foo,new T)} would return false, as @code{new
+T} creates a new instance of the structure @code{T}. The boolean operators
+@code{==} and @code{!=} are by default equivalent to @code{alias} and
+@code{!alias} respectively, but may be overwritten for a particular type
+(for example, to do a deep comparison).
+
+After the definition of a structure @code{T}, a variable of type @code{T} is
+initialized to a new instance (@code{new T}) by default. During the definition
+of the structure, however, variables of type @code{T} are initialized to
+@code{null} by default. This special behaviour is to avoid infinite
+recursion of creating new instances in code such as
+
+@verbatim
+struct tree {
+ int value;
+ tree left;
+ tree right;
+}
+@end verbatim
+
+Here is a simple example that illustrates the use of structures:
+
+@verbatim
+struct S {
+ real a=1;
+ real f(real a) {return a+this.a;}
+}
+
+S s; // Initializes s with new S;
+
+write(s.f(2)); // Outputs 3
+
+S operator + (S s1, S s2)
+{
+ S result;
+ result.a=s1.a+s2.a;
+ return result;
+}
+
+write((s+s).f(0)); // Outputs 2
+
+@end verbatim
+
+@cindex constructors
+It is often convenient to have functions that construct new instances of a
+structure. Say we have a @code{Person} structure:
+
+@verbatim
+struct Person {
+ string firstname;
+ string lastname;
+}
+
+Person joe=new Person;
+joe.firstname="Joe";
+joe.lastname="Jones";
+@end verbatim
+@noindent
+Creating a new Person is a chore; it takes three lines to create a new instance
+and to initialize its fields (that's still considerably less effort than
+creating a new person in real life, though).
+
+We can reduce the work by defining a constructor function
+@code{Person(string,string)}:
+
+@verbatim
+struct Person {
+ string firstname;
+ string lastname;
+
+ static Person Person(string firstname, string lastname) {
+ Person p=new Person;
+ p.firstname=firstname;
+ p.lastname=lastname;
+ return p;
+ }
+}
+
+Person joe=Person.Person("Joe", "Jones");
+@end verbatim
+
+While it is now easier than before to create a new instance, we still
+have to refer to the constructor by the qualified name
+@code{Person.Person}. If we add the line
+
+@verbatim
+from Person unravel Person;
+@end verbatim
+@noindent
+immediately after the structure definition, then the constructor can be used
+without qualification: @code{Person joe=Person("Joe", "Jones");}.
+
+The constructor is now easy to use, but it is quite a hassle to define. If you
+write a lot of constructors, you will find that you are repeating a lot of code
+in each of them. Fortunately, your friendly neighbourhood Asymptote
+developers have devised a way to automate much of the process.
+
+@cindex @code{operator init}
+If, in the body of a structure, Asymptote encounters the definition of
+a function of the form @code{void operator init(@var{args})}, it implicitly
+defines a constructor function of the arguments @code{@var{args}} that
+uses the @code{void operator init} function to initialize a
+new instance of the structure.
+That is, it essentially defines the following constructor (assuming the
+structure is called @code{Foo}):
+
+@example
+static Foo Foo(@var{args}) @{
+ Foo instance=new Foo;
+ instance.operator init(@var{args});
+ return instance;
+@}
+@end example
+
+This constructor is also implicitly copied to the enclosing scope after the end
+of the structure definition, so that it can used subsequently without qualifying
+it by the structure name. Our @code{Person} example can thus be implemented as:
+
+@verbatim
+struct Person {
+ string firstname;
+ string lastname;
+
+ void operator init(string firstname, string lastname) {
+ this.firstname=firstname;
+ this.lastname=lastname;
+ }
+}
+
+Person joe=Person("Joe", "Jones");
+@end verbatim
+
+The use of @code{operator init} to implicitly define constructors should not be
+confused with its use to define default values for variables
+(@pxref{Variable initializers}). Indeed, in the
+first case, the return type of the @code{operator init} must be @code{void}
+while in the second, it must be the (non-@code{void}) type of the variable.
+
+@cindex @code{cputime}
+The function @code{cputime()}
+returns a structure @code{cputime} with cumulative @acronym{CPU} times
+broken down into the fields @code{parent.user}, @code{parent.system},
+@code{child.user}, and @code{child.system}. For convenience, the
+incremental fields @code{change.user} and @code{change.system} indicate
+the change in the corresponding total parent and child @acronym{CPU}
+times since the last call to @code{cputime()}. The function
+@verbatim
+void write(file file=stdout, string s="", cputime c,
+ string format=cputimeformat, suffix suffix=none);
+@end verbatim
+@noindent
+displays the incremental user cputime followed by ``u'',
+the incremental system cputime followed by ``s'',
+the total user cputime followed by ``U'', and
+the total system cputime followed by ``S''.
+
+@cindex inheritance
+@cindex virtual functions
+Much like in C++, casting (@pxref{Casts}) provides for an elegant
+implementation of structure inheritance, including virtual functions:
+@verbatim
+struct parent {
+ real x=1;
+ void virtual(int) {write (0);}
+ void f() {virtual(1);}
+}
+
+void write(parent p) {write(p.x);}
+
+struct child {
+ parent parent;
+ real y=2;
+ void virtual(int x) {write (x);}
+ parent.virtual=virtual;
+ void f()=parent.f;
+}
+
+parent operator cast(child child) {return child.parent;}
+
+parent p;
+child c;
+
+write(c); // Outputs 1;
+
+p.f(); // Outputs 0;
+c.f(); // Outputs 1;
+
+write(c.parent.x); // Outputs 1;
+write(c.y); // Outputs 2;
+@end verbatim
+
+For further examples of structures, see @code{Legend} and @code{picture} in
+the @code{Asymptote} base module @code{plain}.
+
+@node Operators
+@section Operators
+@cindex operators
+
+@menu
+* Arithmetic & logical:: Basic mathematical operators
+* Self & prefix operators:: Increment and decrement
+* User-defined operators:: Overloading operators
+@end menu
+
+@node Arithmetic & logical
+@subsection Arithmetic & logical operators
+@cindex arithmetic operators
+@cindex binary operators
+@cindex boolean operators
+@cindex logical operators
+@cindex integer division
+@cindex @code{quotient}
+
+@code{Asymptote} uses the standard binary arithmetic operators.
+However, when one integer is divided by another, both arguments are
+converted to real values before dividing and a real quotient is
+returned (since this is usually what is intended). The function
+@code{int quotient(int x, int y)} returns the greatest integer less
+than or equal to @code{x/y}. In all other cases both operands are
+promoted to the same type, which will also be the type of the result:
+@table @code
+@cindex @code{+}
+@item +
+addition
+@cindex @code{-}
+@item -
+subtraction
+@cindex @code{*}
+@item *
+multiplication
+@cindex @code{/}
+@item /
+division
+@cindex @code{%}
+@item %
+modulo; the result always has the same sign as the divisor.
+In particular, this makes @code{q*quotient(p,q)+p%q == p} for all
+integers @code{p} and nonzero integers @code{q}.
+@cindex @code{^}
+@item ^
+@cindex @code{**}
+power; if the exponent (second argument) is an int, recursive
+multiplication is used; otherwise, logarithms and exponentials are used
+(@code{**} is a synonym for @code{^}).
+
+@end table
+
+The usual boolean operators are also defined:
+@table @code
+@cindex @code{==}
+@item ==
+equals
+@cindex @code{!=}
+@item !=
+not equals
+@cindex @code{<}
+@item <
+less than
+@cindex @code{<=}
+@item <=
+less than or equals
+@cindex @code{>=}
+@item >=
+greater than or equals
+@cindex @code{>}
+@item >
+greater than
+@cindex @code{&&}
+@item &&
+and (with conditional evaluation of right-hand argument)
+@cindex @code{&}
+@item &
+and
+@cindex @code{||}
+@item ||
+or (with conditional evaluation of right-hand argument)
+@cindex @code{|}
+@item |
+or
+@cindex @code{^}
+@item ^
+xor
+@cindex @code{!}
+@item !
+not
+@end table
+
+@code{Asymptote} also supports the C-like conditional syntax:
+@cindex @code{:}
+@cindex @code{?}
+@cindex conditional
+@verbatim
+bool positive=(pi >= 0) ? true : false;
+@end verbatim
+
+@cindex @code{interp}
+The function @code{T interp(T a, T b, real t)} returns @code{(1-t)*a+t*b}
+for nonintegral built-in arithmetic types @code{T}. If @code{a} and
+@code{b} are pens, they are first promoted to the same color space.
+
+@cindex @code{AND}
+@cindex @code{OR}
+@cindex @code{XOR}
+@cindex @code{NOT}
+@code{Asymptote} also defines bitwise functions @code{int AND(int,int)},
+@code{int OR(int,int)}, @code{int XOR(int,int)}, and @code{int NOT(int)}.
+
+@node Self & prefix operators
+@subsection Self & prefix operators
+@cindex self operators
+@cindex prefix operators
+@cindex @code{+=}
+@cindex @code{-=}
+@cindex @code{*=}
+@cindex @code{/=}
+@cindex @code{%=}
+@cindex @code{^=}
+@cindex @code{++}
+@cindex @code{--}
+
+As in C, each of the arithmetic operators @code{+}, @code{-}, @code{*},
+@code{/}, @code{%}, and @code{^} can be used as a self operator.
+The prefix operators @code{++} (increment by one) and @code{--} (decrement
+by one) are also defined.
+For example,
+@verbatim
+int i=1;
+i += 2;
+int j=++i;
+@end verbatim
+
+@noindent
+is equivalent to the code
+@verbatim
+int i=1;
+i=i+2;
+int j=i=i+1;
+@end verbatim
+
+@cindex postfix operators
+However, postfix operators like @code{i++} and @code{i--} are not defined
+(because of the inherent ambiguities that would arise with the @code{--}
+path-joining operator). In the rare instances where @code{i++}
+and @code{i--} are really needed, one can substitute the expressions
+@code{(++i-1)} and @code{(--i+1)}, respectively.
+
+@node User-defined operators
+@subsection User-defined operators
+@cindex user-defined operators
+@cindex @code{operator}
+The following symbols may be used with @code{operator} to define or redefine
+operators on structures and built-in types:
+@verbatim
+- + * / % ^ ! < > == != <= >= & | ^^ .. :: -- --- ++
+<< >> $ $$ @ @@
+@end verbatim
+@noindent
+The operators on the second line have precedence one higher than the
+boolean operators @code{<}, @code{>}, @code{<=}, and @code{>=}.
+
+Guide operators like @code{..} may be overloaded, say, to write
+a user function that produces a new guide from a given guide:
+@verbatim
+guide dots(... guide[] g)=operator ..;
+
+guide operator ..(... guide[] g) {
+ guide G;
+ if(g.length > 0) {
+ write(g[0]);
+ G=g[0];
+ }
+ for(int i=1; i < g.length; ++i) {
+ write(g[i]);
+ write();
+ G=dots(G,g[i]);
+ }
+ return G;
+}
+
+guide g=(0,0){up}..{SW}(100,100){NE}..{curl 3}(50,50)..(10,10);
+write("g=",g);
+@end verbatim
+
+@node Implicit scaling
+@section Implicit scaling
+@cindex implicit scaling
+
+If a numeric literal is in front of certain types of expressions, then the two
+are multiplied:
+@verbatim
+int x=2;
+real y=2.0;
+real cm=72/2.540005;
+
+write(3x);
+write(2.5x);
+write(3y);
+write(-1.602e-19 y);
+write(0.5(x,y));
+write(2x^2);
+write(3x+2y);
+write(3(x+2y));
+write(3sin(x));
+write(3(sin(x))^2);
+write(10cm);
+@end verbatim
+
+This produces the output
+@verbatim
+6
+5
+6
+-3.204e-19
+(1,1)
+8
+10
+18
+2.72789228047704
+2.48046543129542
+283.464008929116
+@end verbatim
+
+@node Functions
+@section Functions
+@cindex functions
+
+@code{Asymptote} functions are treated as variables with a signature
+(non-function variables have null signatures). Variables with the
+same name are allowed, so long as they have distinct signatures.
+
+Functions arguments are passed by value. To pass an argument by
+reference, simply enclose it in a structure (@pxref{Structures}).
+
+Here are some significant features of @code{Asymptote} functions:
+
+@enumerate
+@item Variables with signatures (functions) and without signatures
+(nonfunction variables) are distinct:
+@verbatim
+int x, x();
+x=5;
+x=new int() {return 17;};
+x=x(); // calls x() and puts the result, 17, in the scalar x
+@end verbatim
+
+@item Traditional function definitions are allowed:
+@verbatim
+int sqr(int x)
+{
+ return x*x;
+}
+sqr=null; // but the function is still just a variable.
+@end verbatim
+
+@item Casting can be used to resolve ambiguities:
+@verbatim
+int a, a(), b, b(); // Valid: creates four variables.
+a=b; // Invalid: assignment is ambiguous.
+a=(int) b; // Valid: resolves ambiguity.
+(int) (a=b); // Valid: resolves ambiguity.
+(int) a=b; // Invalid: cast expressions cannot be L-values.
+
+int c();
+c=a; // Valid: only one possible assignment.
+@end verbatim
+
+@item Anonymous (so-called "high-order") functions are also allowed:
+@cindex @code{typedef}
+@verbatim
+typedef int intop(int);
+intop adder(int m)
+{
+ return new int(int n) {return m+n;};
+}
+intop addby7=adder(7);
+write(addby7(1)); // Writes 8.
+@end verbatim
+
+@item
+@cindex overloading functions
+One may redefine a function @code{f}, even for calls to @code{f} in previously
+declared functions, by assigning another (anonymous or named)
+function to it. However, if @code{f} is overloaded by a
+new function definition, previous calls will still access the original
+version of @code{f}, as illustrated in this example:
+@verbatim
+void f() {
+ write("hi");
+}
+
+void g() {
+ f();
+}
+
+g(); // writes "hi"
+
+f=new void() {write("bye");};
+
+g(); // writes "bye"
+
+void f() {write("overloaded");};
+
+f(); // writes "overloaded"
+g(); // writes "bye"
+@end verbatim
+
+@cindex function declarations
+@item Anonymous functions can be used to redefine a function variable
+that has been declared (and implicitly initialized to the null function)
+but not yet explicitly defined:
+@verbatim
+void f(bool b);
+
+void g(bool b) {
+ if(b) f(b);
+ else write(b);
+}
+
+f=new void(bool b) {
+ write(b);
+ g(false);
+};
+
+g(true); // Writes true, then writes false.
+@end verbatim
+
+@end enumerate
+
+@code{Asymptote} is the only language we know of that treats functions
+as variables, but allows overloading by distinguishing variables
+based on their signatures.
+
+@cindex @code{libsigsegv}
+@anchor{stack overflow}
+@cindex recursion
+@cindex stack overflow
+Functions are allowed to call themselves recursively. As in C++, infinite
+nested recursion will generate a stack overflow (reported as a
+segmentation fault, unless a fully working version of the @acronym{GNU}
+library @code{libsigsegv} (e.g.@ 2.4 or later) is installed at
+configuration time).
+
+@menu
+* Default arguments:: Default values can appear anywhere
+* Named arguments:: Assigning function arguments by keyword
+* Rest arguments:: Functions with a variable number of arguments
+* Mathematical functions:: Standard libm functions
+
+@end menu
+
+@node Default arguments
+@subsection Default arguments
+@cindex default arguments
+@cindex arguments
+
+@code{Asymptote} supports a more flexible mechanism for default function
+arguments than C++: they may appear anywhere in the function prototype.
+Because certain data types are implicitly cast to more sophisticated
+types (@pxref{Casts}) one can often avoid ambiguities by ordering
+function arguments from the simplest to the most complicated.
+For example, given
+@verbatim
+real f(int a=1, real b=0) {return a+b;}
+@end verbatim
+@noindent
+then @code{f(1)} returns 1.0, but @code{f(1.0)} returns 2.0.
+
+The value of a default argument is determined by evaluating the
+given @code{Asymptote} expression in the scope where the called
+function is defined.
+
+@node Named arguments
+@subsection Named arguments
+@cindex keywords
+@cindex named arguments
+
+It is sometimes difficult to remember the order in which arguments
+appear in a function declaration. Named (keyword) arguments make calling
+functions with multiple arguments easier. Unlike in the C and C++
+languages, an assignment in a function argument is interpreted as an
+assignment to a parameter of the same name in the function signature,
+@emph{not within the local scope}. The command-line option @code{-d}
+may be used to check @code{Asymptote} code for cases where a
+named argument may be mistaken for a local assignment.
+
+When matching arguments to signatures, first all of the keywords are
+matched, then the arguments without names are matched against the
+unmatched formals as usual. For example,
+@verbatim
+int f(int x, int y) {
+ return 10x+y;
+}
+write(f(4,x=3));
+@end verbatim
+@noindent
+outputs 34, as @code{x} is already matched when we try to match the
+unnamed argument @code{4}, so it gets matched to the next item, @code{y}.
+
+For the rare occasions where it is desirable to assign a value to
+local variable within a function argument (generally @emph{not} a good
+programming practice), simply enclose the assignment in
+parentheses. For example, given the definition of @code{f} in the
+previous example,
+@verbatim
+int x;
+write(f(4,(x=3)));
+@end verbatim
+@noindent
+is equivalent to the statements
+@verbatim
+int x;
+x=3;
+write(f(4,3));
+@end verbatim
+@noindent
+and outputs 43.
+
+As a technical detail, we point out that, since variables of the same
+name but different signatures are allowed in the same scope, the code
+@verbatim
+int f(int x, int x()) {
+ return x+x();
+}
+int seven() {return 7;}
+@end verbatim
+@noindent
+is legal in @code{Asymptote}, with @code{f(2,seven)} returning 9.
+A named argument matches the first unmatched formal of the same name, so
+@code{f(x=2,x=seven)} is an equivalent call, but @code{f(x=seven,2)}
+is not, as the first argument is matched to the first formal, and
+@code{int ()} cannot be implicitly cast to @code{int}. Default
+arguments do not affect which formal a named argument is matched to,
+so if @code{f} were defined as
+@verbatim
+int f(int x=3, int x()) {
+ return x+x();
+}
+@end verbatim
+@noindent
+then @code{f(x=seven)} would be illegal, even though @code{f(seven)}
+obviously would be allowed.
+
+@node Rest arguments
+@subsection Rest arguments
+@cindex rest arguments
+
+Rest arguments allow one to write functions that take a variable
+number of arguments:
+@verbatim
+// This function sums its arguments.
+int sum(... int[] nums) {
+ int total=0;
+ for(int i=0; i < nums.length; ++i)
+ total += nums[i];
+ return total;
+}
+
+sum(1,2,3,4); // returns 10
+sum(); // returns 0
+
+// This function subtracts subsequent arguments from the first.
+int subtract(int start ... int[] subs) {
+ for(int i=0; i < subs.length; ++i)
+ start -= subs[i];
+ return start;
+}
+
+subtract(10,1,2); // returns 7
+subtract(10); // returns 10
+subtract(); // illegal
+@end verbatim
+
+@cindex packing
+Putting an argument into a rest array is called @emph{packing}.
+One can give an explicit list of arguments for the rest
+argument, so @code{subtract} could alternatively be implemented as
+@verbatim
+int subtract(int start ... int[] subs) {
+ return start - sum(... subs);
+}
+@end verbatim
+
+One can even combine normal arguments with rest arguments:
+@verbatim
+sum(1,2,3 ... new int[] {4,5,6}); // returns 21
+@end verbatim
+@noindent
+@cindex unpacking
+This builds a new six-element array that is passed to @code{sum} as
+@code{nums}. The opposite operation, @emph{unpacking}, is not allowed:
+@verbatim
+subtract(... new int[] {10, 1, 2});
+@end verbatim
+@noindent
+is illegal, as the start formal is not matched.
+
+If no arguments are packed, then a zero-length array (as opposed to
+@code{null}) is bound to the rest parameter. Note that default
+arguments are ignored for rest formals and the rest argument is not
+bound to a keyword.
+
+The overloading resolution in @code{Asymptote} is similar to the
+function matching rules used in C++. Every argument match is given a
+score. Exact matches score better than matches with casting, and
+matches with formals (regardless of casting) score better than packing
+an argument into the rest array. A candidate is maximal if all of the
+arguments score as well in it as with any other candidate. If there
+is one unique maximal candidate, it is chosen; otherwise, there is an
+ambiguity error.
+
+@verbatim
+int f(path g);
+int f(guide g);
+f((0,0)--(100,100)); // matches the second; the argument is a guide
+
+int g(int x, real y);
+int g(real x, int x);
+
+g(3,4); // ambiguous; the first candidate is better for the first argument,
+ // but the second candidate is better for the second argument
+
+int h(... int[] rest);
+int h(real x ... int[] rest);
+
+h(1,2); // the second definition matches, even though there is a cast,
+ // because casting is preferred over packing
+
+int i(int x ... int[] rest);
+int i(real x, real y ... int[] rest);
+
+i(3,4); // ambiguous; the first candidate is better for the first argument,
+ // but the second candidate is better for the second one
+@end verbatim
+
+@node Mathematical functions
+@subsection Mathematical functions
+@cindex mathematical functions
+@cindex functions
+@cindex @code{libm} routines
+
+@cindex @code{sin}
+@cindex @code{cos}
+@cindex @code{tan}
+@cindex @code{asin}
+@cindex @code{acos}
+@cindex @code{atan}
+@cindex @code{exp}
+@cindex @code{log}
+@cindex @code{pow10}
+@cindex @code{log10}
+@cindex @code{sinh}
+@cindex @code{cosh}
+@cindex @code{tanh}
+@cindex @code{asinh}
+@cindex @code{acosh}
+@cindex @code{atanh}
+@cindex @code{sqrt}
+@cindex @code{cbrt}
+@cindex @code{fabs}
+@cindex @code{expm1}
+@cindex @code{log1p}
+@cindex @code{identity}
+@cindex @code{J}
+@cindex @code{Y}
+@cindex @code{gamma}
+@cindex @code{erf}
+@cindex @code{erfc}
+@cindex @code{atan2}
+@cindex @code{hypot}
+@cindex @code{fmod}
+@cindex @code{remainder}
+@code{Asymptote} has built-in versions of the standard @code{libm} mathematical
+real(real) functions @code{sin}, @code{cos}, @code{tan}, @code{asin},
+@code{acos}, @code{atan}, @code{exp}, @code{log}, @code{pow10},
+@code{log10}, @code{sinh}, @code{cosh}, @code{tanh}, @code{asinh},
+@code{acosh}, @code{atanh}, @code{sqrt}, @code{cbrt}, @code{fabs}, @code{expm1},
+@code{log1p}, as well as the identity function @code{identity}.
+@code{Asymptote} also defines the order @code{n} Bessel functions of
+the first kind @code{J(int n, real)} and second kind
+@code{Y(int n, real)}, as well as the gamma function @code{gamma},
+the error function @code{erf}, and the complementary error function
+@code{erfc}. The standard real(real, real) functions @code{atan2},
+@code{hypot}, @code{fmod}, @code{remainder} are also included.
+
+@cindex @code{degrees}
+@cindex @code{radians}
+@cindex @code{Degrees}
+The functions @code{degrees(real radians)} and @code{radians(real degrees)}
+can be used to convert between radians and degrees. The function
+@code{Degrees(real radians)} returns the angle in degrees in the
+interval [0,360).
+@cindex @code{Sin}
+@cindex @code{Cos}
+@cindex @code{Tan}
+@cindex @code{aSin}
+@cindex @code{aCos}
+@cindex @code{aTan}
+For convenience, @code{Asymptote} defines variants @code{Sin},
+@code{Cos}, @code{Tan}, @code{aSin}, @code{aCos}, and @code{aTan} of
+the standard trigonometric functions that use degrees rather than radians.
+We also define complex versions of the @code{sqrt}, @code{sin}, @code{cos},
+@code{exp}, @code{log}, and @code{gamma} functions.
+
+@cindex @code{floor}
+@cindex @code{ceil}
+@cindex @code{round}
+@cindex @code{sgn}
+The functions @code{floor}, @code{ceil}, and @code{round} differ from
+their usual definitions in that they all return an int value rather than
+a real (since that is normally what one wants).
+The functions @code{Floor}, @code{Ceil}, and @code{Round} are
+respectively similar, except that if the result cannot be converted
+to a valid int, they return @code{intMax}
+for positive arguments and @code{intMin} for negative arguments,
+rather than generating an integer overflow.
+We also define a function @code{sgn}, which returns the sign of its
+real argument as an integer (-1, 0, or 1).
+
+@cindex @code{abs}
+There is an @code{abs(int)} function, as well as an @code{abs(real)}
+function (equivalent to @code{fabs(real)}), an @code{abs(pair)} function
+(equivalent to @code{length(pair)}).
+
+@cindex @code{srand}
+@cindex @code{rand}
+@cindex @code{randMax}
+@cindex @code{unitrand}
+@cindex @code{Gaussrand}
+@cindex @code{histogram}
+@cindex @code{factorial}
+@cindex @code{choose}
+Random numbers can be seeded with @code{srand(int)} and generated with
+the @code{int rand()} function, which returns a random integer between 0
+and the integer @code{randMax}. The @code{unitrand()} function returns
+a random number uniformly distributed in the interval [0,1].
+A Gaussian random number generator
+@code{Gaussrand} and a collection of statistics routines, including
+@code{histogram}, are provided in the base file @code{stats.asy}.
+The functions @code{factorial(int n)}, which returns @math{n!}, and
+@code{choose(int n, int k)}, which returns @math{n!/(k!(n-k)!)}, are
+also defined.
+
+@cindex @acronym{GNU} Scientific Library
+@cindex @code{gsl}
+@cindex Airy
+@cindex Bessel
+@cindex Legendre
+@cindex elliptic functions
+@cindex exponential integral
+@cindex trigonometric integrals
+@cindex Riemann zeta function
+@cindex @code{Ai}
+@cindex @code{Bi}
+@cindex @code{Ai_deriv}
+@cindex @code{Bi_deriv}
+@cindex @code{zero_Ai}
+@cindex @code{zero_Bi}
+@cindex @code{zero_Ai_deriv}
+@cindex @code{zero_Bi_deriv}
+@cindex @code{J}
+@cindex @code{Y}
+@cindex @code{I}
+@cindex @code{K}
+@cindex @code{i_scaled}
+@cindex @code{k_scaled}
+@cindex @code{zero_J}
+@cindex @code{F}
+@cindex @code{E}
+@cindex @code{P}
+@cindex @code{Ei}
+@cindex @code{Si}
+@cindex @code{Ci}
+@cindex @code{Pl}
+@cindex @code{zeta}
+When configured with the @acronym{GNU} Scientific Library (GSL), available from
+@url{http://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)},
+@code{zero_Ai(int)}, @code{zero_Bi(int)},
+@code{zero_Ai_deriv(int)}, @code{zero_Bi_deriv(int)}, the Bessel functions
+@code{I(int, real)}, @code{K(int, real)}, @code{j(int, real)},
+@code{y(int, real)}, @code{i_scaled(int, real)}, @code{k_scaled(int, real)},
+@code{J(real, real)}, @code{Y(real, real)}, @code{I(real, real)},
+@code{K(real, real)}, @code{zero_J(real, int)}, the elliptic functions
+@code{F(real, real)}, @code{E(real, real)}, and @code{P(real, real)},
+the exponential/trigonometric integrals @code{Ei}, @code{Si}, and @code{Ci},
+the Legendre polynomials @code{Pl(int, real)}, and the Riemann zeta
+function @code{zeta(real)}. For example, to compute the sine integral
+@code{Si} of 1.0:
+@verbatim
+import gsl;
+write(Si(1.0));
+@end verbatim
+
+@code{Asymptote} also provides a few general purpose numerical routines:
+
+@table @code
+
+@cindex @code{newton}
+@item @code{real newton(int iterations=100, real f(real), real fprime(real), real x, bool verbose=false);}
+Use Newton-Raphson iteration to solve for a root of a real-valued
+differentiable function @code{f}, given its derivative @code{fprime} and
+an initial guess @code{x}. Diagnostics for
+each iteration are printed if @code{verbose=true}.
+If the iteration fails after the maximum allowed number of loops
+(@code{iterations}), @code{realMax} is returned.
+
+@cindex @code{newton}
+@item @code{real newton(int iterations=100, real f(real), real fprime(real), real x1, real x2, bool verbose=false);}
+Use bracketed Newton-Raphson bisection to solve for a root of a real-valued
+differentiable function @code{f} within an interval
+[@code{x1},@code{x2}] (on which the endpoint values of @code{f} have
+opposite signs), given its derivative @code{fprime}. Diagnostics for
+each iteration are printed if @code{verbose=true}.
+If the iteration fails after the maximum allowed number of loops
+(@code{iterations}), @code{realMax} is returned.
+
+@cindex @code{simpson}
+@item @code{real simpson(real f(real), real a, real b, real acc=realEpsilon, real dxmax=b-a)}
+returns the integral of @code{f} from @code{a} to @code{b} using adaptive Simpson integration.
+
+@end table
+
+@node Arrays
+@section Arrays
+@cindex arrays
+
+@menu
+* Slices:: Python-style array slices
+@end menu
+
+Appending @code{[]} to a built-in or user-defined type yields an array.
+The array element @code{i} of an array @code{A} can be accessed as @code{A[i]}.
+By default, attempts to access or assign to an array element using a negative
+index generates an error. Reading an array element with an index
+beyond the length of the array also generates an error; however,
+assignment to an element beyond the length of the array causes the
+array to be resized to accommodate the new element.
+One can also index an array @code{A} with an integer array @code{B}:
+the array @code{A[B]} is formed by indexing array @code{A} with
+successive elements of array @code{B}.
+A convenient Java-style shorthand exists for iterating over all elements of an
+array; see @ref{array iteration}.
+
+The declaration
+@verbatim
+real[] A;
+@end verbatim
+
+@noindent
+initializes @code{A} to be an empty (zero-length) array. Empty arrays should be
+distinguished from null arrays. If we say
+@verbatim
+real[] A=null;
+@end verbatim
+
+@noindent
+then @code{A} cannot be dereferenced at all (null arrays have no length
+and cannot be read from or assigned to).
+
+Arrays can be explicitly initialized like this:
+@verbatim
+real[] A={0,1,2};
+@end verbatim
+
+Array assignment in @code{Asymptote} does a shallow copy: only
+the pointer is copied (if one copy if modified, the other will be too).
+The @code{copy} function listed below provides a deep copy of an array.
+
+@cindex @code{length}
+@cindex @code{cyclic}
+@cindex @code{cyclicflag}
+@cindex @code{keys}
+@cindex @code{push}
+@cindex @code{append}
+@cindex @code{pop}
+@cindex @code{insert}
+@cindex @code{delete}
+@cindex @code{initialized}
+Every array @code{A} of type @code{T[]} has the virtual members
+@itemize
+@item @code{int length},
+@item @code{void cyclic(bool b)},
+@item @code{bool cyclicflag},
+@item @code{int[] keys},
+@item @code{T push(T x)},
+@item @code{void append(T[] a)},
+@item @code{T pop()},
+@item @code{void insert(int i ... T[] x)},
+@item @code{void delete(int i, int j=i)},
+@item @code{void delete()}, and
+@item @code{bool initialized(int n)}.
+@end itemize
+
+The member @code{A.length} evaluates to the length of the array.
+Setting @code{A.cyclic(true)} signifies that array indices should be reduced
+modulo the current array length. Reading from or writing to a nonempty
+cyclic array never leads to out-of-bounds errors or array resizing. The member
+@code{A.cyclicflag} returns the current setting of the @code{cyclic} flag.
+
+The member @code{A.keys} evaluates to an array of integers containing the
+indices of initialized entries in the array in ascending order. Hence, for an
+array of length @code{n} with all entries initialized, @code{A.keys} evaluates
+to the array of integers from @code{0} to @code{n-1} inclusive. A new keys
+array is produced each time @code{A.keys} is evaluated.
+
+The functions @code{A.push} and @code{A.append} append their
+arguments onto the end of the array, while @code{A.insert(int i ... T[] x)}
+inserts @code{x} into the array at index @code{i}.
+For convenience @code{A.push} returns the pushed item.
+The function @code{A.pop()} pops and returns the last element,
+while @code{A.delete(int i, int j=i)} deletes elements with indices in
+the range [@code{i},@code{j}], shifting the position of all higher-indexed
+elements down. If no arguments are given, @code{A.delete()} provides a
+convenient way of deleting all elements of @code{A}. The routine
+@code{A.initialized(int n)} can be used to examine whether the element
+at index @code{n} is initialized. Like all @code{Asymptote} functions,
+@code{cyclic}, @code{push}, @code{append}, @code{pop}, @code{insert},
+@code{delete}, and @code{initialized} can be "pulled off" of the array
+and used on their own. For example,
+@verbatim
+int[] A={1};
+A.push(2); // A now contains {1,2}.
+A.append(A); // A now contains {1,2,1,2}.
+int f(int)=A.push;
+f(3); // A now contains {1,2,1,2,3}.
+int g()=A.pop;
+write(g()); // Outputs 3.
+A.delete(0); // A now contains {2,1,2}.
+A.delete(0,1); // A now contains {2}.
+A.insert(1,3); // A now contains {2,3}.
+A.insert(1 ... A); // A now contains {2,2,3,3}
+A.insert(2,4,5); // A now contains {2,2,4,5,3,3}.
+@end verbatim
+
+The @code{[]} suffix can also appear after the variable name; this
+is sometimes convenient for declaring a list of variables and arrays
+of the same type:
+@verbatim
+real a,A[];
+@end verbatim
+@noindent
+This declares @code{a} to be @code{real} and implicitly declares @code{A} to
+be of type @code{real[]}.
+
+In the following list of built-in array functions, @code{T} represents a
+generic type. Note that the internal functions @code{alias}, @code{array},
+@code{copy}, @code{concat}, @code{sequence}, @code{map}, and
+@code{transpose}, which depend on type @code{T[]}, are defined only after the
+first declaration of a variable of type @code{T[]}.
+
+@table @code
+
+@cindex @code{new}
+@item new T[]
+returns a new empty array of type @code{T[]};
+
+@cindex @code{new}
+@item new T[] @{list@}
+returns a new array of type @code{T[]} initialized with @code{list} (a comma
+delimited list of elements).
+
+@item new T[n]
+returns a new array of @code{n} elements of type @code{T[]}.
+These @code{n} array elements are not initialized unless they are arrays
+themselves (in which case they are each initialized to empty arrays).
+
+@cindex @code{array}
+@item T[] array(int n, T value, int depth=intMax)
+returns an array consisting of @code{n} copies of value. By default, if
+@code{value} is itself an array, a deep copy of that array is made for
+each entry in the new array. If @code{depth} is specified, this deep copying
+only recurses to the number of levels specified.
+
+@cindex @code{sequence}
+@item int[] sequence(int n)
+if @code{n >= 1} returns the array @code{@{0,1,...,n-1@}} (otherwise returns
+a null array);
+
+@item int[] sequence(int n, int m)
+if @code{m >= n} returns an array @code{@{n,n+1,...,m@}} (otherwise
+returns a null array);
+
+@item T[] sequence(T f(int), int n)
+if @code{n >= 1} returns the sequence @code{@{f_i :i=0,1,...n-1@}} given a
+function @code{T f(int)} and integer @code{int n} (otherwise returns a
+null array);
+
+@cindex @code{map}
+@item T[] map(T f(T), T[] a)
+returns the array obtained by applying the function @code{f} to each
+element of the array @code{a}. This is equivalent to
+@code{sequence(new T(int i) @{return f(a[i]);@},a.length)}.
+
+@cindex @code{reverse}
+@item int[] reverse(int n)
+if @code{n >= 1} returns the array @code{@{n-1,n-2,...,0@}} (otherwise
+returns a null array);
+
+@cindex @code{complement}
+@item int[] complement(int[] a, int n)
+returns the complement of the integer array @code{a} in
+@code{@{0,1,2,...,n-1@}}, so that @code{b[complement(a,b.length)]} yields the
+complement of @code{b[a]}.
+
+@cindex @code{uniform}
+@item real[] uniform(real a, real b, int n)
+if @code{n >= 1} returns a uniform partition of @code{[a,b]} into
+@code{n} subintervals (otherwise returns a null array);
+
+@cindex @code{find}
+@item int find(bool[], int n=1)
+returns the index of the @code{n}th @code{true} value or -1 if not found.
+If @code{n} is negative, search backwards from the end of the array for the
+@code{-n}th value;
+
+@cindex @code{search}
+@item int search(T[] a, T key)
+For built-in ordered types @code{T}, searches a sorted ordered array
+@code{a} of @code{n} elements to find an interval containing
+@code{key}, returning @code{-1} if @code{key} is less than the first
+element, @code{n-1} if @code{key} is greater than or equal to the last
+element, and otherwise the index corresponding to the left-hand
+(smaller) endpoint.
+
+@cindex @code{copy}
+@item T[] copy(T[] a)
+returns a deep copy of the array @code{a};
+
+@cindex @code{copy}
+@item T[][] copy(T[][] a)
+returns a deep copy of the array @code{a};
+
+@cindex @code{copy}
+@item T[][][] copy(T[][][] a)
+returns a deep copy of the array @code{a};
+
+@cindex @code{concat}
+@item T[] concat(... T[][] a)
+returns a new array formed by concatenating the arrays given as arguments;
+
+@cindex @code{alias}
+@item bool alias(T[] a, T[] b)
+returns @code{true} if the arrays @code{a} and @code{b} are identical;
+
+@cindex @code{sort}
+@item T[] sort(T[] a)
+For built-in ordered types @code{T}, returns a copy of @code{a} sorted in
+ascending order;
+
+@anchor{sort}
+@item T[][] sort(T[][] a)
+For built-in ordered types @code{T}, returns a copy of @code{a} with the rows
+sorted by the first column, breaking ties with successively higher
+columns. For example:
+@verbatim
+string[][] a={{"bob","9"},{"alice","5"},{"pete","7"},
+ {"alice","4"}};
+// Row sort (by column 0, using column 1 to break ties):
+write(sort(a));
+@end verbatim
+
+produces
+@verbatim
+alice 4
+alice 5
+bob 9
+pete 7
+@end verbatim
+
+@cindex @code{sort}
+@item T[] sort(T[] a, bool compare(T i, T j))
+returns a copy of @code{a} stably sorted in ascending order such that
+element @code{i} precedes element @code{j} if @code{compare(i,j)} is true.
+
+@cindex @code{transpose}
+@item T[][] transpose(T[][] a)
+returns the transpose of @code{a}.
+
+@cindex @code{transpose}
+@item T[][][] transpose(T[][][] a, int[] perm)
+returns the 3D transpose of @code{a} obtained by applying the permutation
+@code{perm} of @code{new int[]@{0,1,2@}} to the indices of each entry.
+
+@cindex @code{sum}
+@item T sum(T[] a)
+For arithmetic types @code{T}, returns the sum of @code{a}.
+In the case where @code{T} is @code{bool}, the number of true elements in
+@code{a} is returned.
+
+@cindex @code{min}
+@item T min(T[] a)
+@item T min(T[][] a)
+@item T min(T[][][] a)
+For built-in ordered types @code{T}, returns the minimum element of @code{a}.
+
+@cindex @code{max}
+@item T max(T[] a)
+@item T max(T[][] a)
+@item T max(T[][][] a)
+For built-in ordered types @code{T}, returns the maximum element of @code{a}.
+
+@cindex @code{min}
+@item T[] min(T[] a, T[] b)
+For built-in ordered types @code{T}, and arrays @code{a} and @code{b}
+of the same length, returns an array composed of the minimum of the
+corresponding elements of @code{a} and @code{b}.
+
+@cindex @code{max}
+@item T[] max(T[] a, T[] b)
+For built-in ordered types @code{T}, and arrays @code{a} and @code{b}
+of the same length, returns an array composed of the maximum of the
+corresponding elements of @code{a} and @code{b}.
+
+@cindex @code{pairs}
+@item pair[] pairs(real[] x, real[] y);
+For arrays @code{x} and @code{y} of the same length, returns the pair array
+@code{sequence(new pair(int i) @{return (x[i],y[i]);@},x.length)}.
+
+@cindex @code{fft}
+@item pair[] fft(pair[] a, int sign=1)
+returns the Fast Fourier Transform of @code{a} (if the optional
+@code{FFTW} package is installed), using the given @code{sign}. Here
+is a simple example:
+@verbatim
+int n=4;
+pair[] f=sequence(n);
+write(f);
+pair[] g=fft(f,-1);
+write();
+write(g);
+f=fft(g,1);
+write();
+write(f/n);
+@end verbatim
+
+@cindex @code{solve}
+@item real dot(real[] a, real[] b)
+returns the dot product of the vectors @code{a} and @code{b}.
+
+@anchor{tridiagonal}
+@cindex @code{tridiagonal}
+@item real[] tridiagonal(real[] a, real[] b, real[] c, real[] f);
+Solve the periodic tridiagonal problem @math{L@code{x}=@code{f}} and return the
+solution @code{x}, where @code{f}
+is an @math{n} vector and @math{L} is the @math{n \times n} matrix
+@verbatim
+[ b[0] c[0] a[0] ]
+[ a[1] b[1] c[1] ]
+[ a[2] b[2] c[2] ]
+[ ... ]
+[ c[n-1] a[n-1] b[n-1] ]
+@end verbatim
+For Dirichlet boundary conditions (denoted here by @code{u[-1]} and
+@code{u[n]}), replace @code{f[0]} by @code{f[0]-a[0]u[-1]} and
+@code{f[n-1]-c[n-1]u[n]}; then set @code{a[0]=c[n-1]=0}.
+
+@cindex @code{solve}
+@item real[] solve(real[][] a, real[] b, bool warn=true)
+Solve the linear equation @math{@code{a}x=@code{b}} by LU decomposition
+and return the solution @math{x}, where @code{a} is an
+@math{n \times n} matrix and @code{b} is an array of length @math{n}.
+For example:
+@verbatim
+import math;
+real[][] a={{1,-2,3,0},{4,-5,6,2},{-7,-8,10,5},{1,50,1,-2}};
+real[] b={7,19,33,3};
+real[] x=solve(a,b);
+write(a); write();
+write(b); write();
+write(x); write();
+write(a*x);
+@end verbatim
+If @code{a} is a singular matrix and @code{warn} is @code{false}, return an
+empty array.
+If the matrix @code{a} is tridiagonal, the routine @code{tridiagonal} provides
+a more efficient algorithm (@pxref{tridiagonal}).
+
+@anchor{solve}
+
+@cindex @code{solve}
+@item real[][] solve(real[][] a, real[][] b, bool warn=true)
+Solve the linear equation @math{@code{a}x=@code{b}} and return the
+solution @math{x}, where @code{a} is an @math{n \times n} matrix and
+@code{b} is an @math{n \times m} matrix. If @code{a} is a singular
+matrix and @code{warn} is @code{false}, return an empty matrix.
+
+@cindex @code{identity}
+@item real[][] identity(int n);
+returns the @math{n \times n} identity matrix.
+
+@cindex @code{diagonal}
+@item real[][] diagonal(... real[] a)
+returns the diagonal matrix with diagonal entries given by a.
+
+@cindex @code{inverse}
+@item real[][] inverse(real[][] a)
+returns the inverse of a square matrix @code{a}.
+
+@cindex @code{quadraticroots}
+@item @code{real[] quadraticroots(real a, real b, real c);}
+This numerically robust solver returns the real roots of the
+quadratic equation @math{ax^2+bx+c=0}, in ascending order. Multiple
+roots are listed separately.
+
+@cindex @code{quadraticroots}
+@item @code{pair[] quadraticroots(explicit pair a, explicit pair b, explicit pair c);}
+This numerically robust solver returns the two complex roots of the
+quadratic equation @math{ax^2+bx+c=0}.
+
+@cindex @code{cubicroots}
+@item @code{real[] cubicroots(real a, real b, real c, real d);}
+This numerically robust solver returns the real roots of the
+cubic equation @math{ax^3+bx^2+cx+d=0}. Multiple roots are listed separately.
+
+@end table
+
+@cindex vectorization
+@code{Asymptote} includes a full set of vectorized array instructions for
+arithmetic (including self) and logical operations. These
+element-by-element instructions are implemented in C++ code for speed. Given
+@verbatim
+real[] a={1,2};
+real[] b={3,2};
+@end verbatim
+@noindent
+then @code{a == b} and @code{a >= 2} both evaluate to the vector
+@code{@{false, true@}}.
+@cindex @code{all}
+To test whether all components of @code{a} and @code{b} agree,
+use the boolean function @code{all(a == b)}. One can also use conditionals like
+@code{(a >= 2) ? a : b}, which returns the array @code{@{3,2@}}, or
+@code{write((a >= 2) ? a : null}, which returns the array @code{@{2@}}.
+
+All of the standard built-in @code{libm} functions of signature
+@code{real(real)} also take a real array as an argument, effectively like an
+implicit call to @code{map}.
+
+As with other built-in types, arrays of the basic data types can be read
+in by assignment. In this example, the code
+@verbatim
+file fin=input("test.txt");
+real[] A=fin;
+@end verbatim
+
+@cindex @code{eof}
+@cindex @code{eol}
+@cindex @code{line}
+@cindex line mode
+@noindent
+reads real values into @code{A} until the end-of-file is reached (or an
+I/O error occurs). If line mode is set with @code{line(file)}, then
+reading will stop once the end of the line is reached instead
+(line mode may be cleared with @code{line(file,false)}):
+@verbatim
+file fin=input("test.txt");
+real[] A=line(fin);
+@end verbatim
+
+@cindex reading string arrays
+@cindex @code{word}
+@cindex white-space string delimiter mode
+Since string reads by default read up to the end of line anyway, line mode
+normally has no effect on string array reads.
+However, there is a white-space delimiter mode for reading strings, set with
+@code{word(file)} and cleared with @code{word(file,false)}, which causes
+string reads to respect white-space delimiters, instead of the default
+end-of-line delimiter:
+@verbatim
+file fin=word(line(input("test.txt")));
+real[] A=fin;
+@end verbatim
+
+@cindex @code{csv}
+@cindex comma-separated-value mode
+Another useful mode is comma-separated-value mode, set with @code{csv(file)}
+and cleared with @code{csv(file,false)}, which causes reads to respect
+comma delimiters:
+@verbatim
+file fin=csv(input("test.txt"));
+real[] A=fin;
+@end verbatim
+
+@cindex @code{dimension}
+To restrict the number of values read, use the @code{dimension(file,int)}
+function:
+@verbatim
+file fin=input("test.txt");
+real[] A=dimension(fin,10);
+@end verbatim
+
+This reads 10 values into A, unless end-of-file (or end-of-line in line mode)
+occurs first. Attempting to read beyond the end of the file will produce a
+runtime error message. Specifying a value of 0 for the integer limit is
+equivalent to the previous example of reading until end-of-file (or
+end-of-line in line mode) is encountered.
+
+Two- and three-dimensional arrays of the basic data types can be read
+in like this:
+@verbatim
+file fin=input("test.txt");
+real[][] A=dimension(fin,2,3);
+real[][][] B=dimension(fin,2,3,4);
+@end verbatim
+@noindent
+Again, an integer limit of zero means no restriction.
+
+@cindex @code{read1}
+@cindex @code{read2}
+@cindex @code{read3}
+Sometimes the array dimensions are stored with the data as integer
+fields at the beginning of an array. Such arrays can be read in with the
+functions @code{read1}, @code{read2}, and @code{read3}, respectively:
+@verbatim
+file fin=input("test.txt");
+real[] A=read1(fin);
+real[][] B=read2(fin);
+real[][][] C=read3(fin);
+@end verbatim
+
+@cindex @code{write}
+One, two, and three-dimensional arrays of the basic data types can be
+output with the functions @code{write(file,T[])},
+@code{write(file,T[][])}, @code{write(file,T[][][])}, respectively.
+
+@node Slices
+@subsection Slices
+@cindex slices
+
+Asymptote allows a section of an array to be addressed as a slice
+using a Python-like syntax. If @code{A} is an array, the expression
+@code{A[m:n]} returns a new array consisting of the elements of @code{A} with
+indices from @code{m} up to but not including @code{n}. For example,
+
+@verbatim
+int[] x={0,1,2,3,4,5,6,7,8,9};
+int[] y=x[2:6]; // y={2,3,4,5};
+int[] z=x[5:10]; // z={5,6,7,8,9};
+@end verbatim
+
+If the left index is omitted, it is taken be @code{0}. If the right index is
+omitted it is taken to be the length of the array. If both are omitted, the
+slice then goes from the start of the array to the end, producing a non-cyclic
+deep copy of the array. For example:
+
+@verbatim
+int[] x={0,1,2,3,4,5,6,7,8,9};
+int[] y=x[:4]; // y={0,1,2,3}
+int[] z=x[5:]; // z={5,6,7,8,9}
+int[] w=x[:]; // w={0,1,2,3,4,5,6,7,8,9}, distinct from array x.
+@end verbatim
+
+If A is a non-cyclic array, it is illegal to use negative values for either of
+the indices. If the indices exceed the length of the array, however, they are
+politely truncated to that length.
+
+For cyclic arrays, the slice @code{A[m:n]} still consists of the cells with
+indices in the set [@code{m},@code{n}), but now negative
+values and values beyond the length of the array are allowed. The indices
+simply wrap around. For example:
+
+@verbatim
+int[] x={0,1,2,3,4,5,6,7,8,9};
+x.cyclic(true);
+int[] y=x[8:15]; // y={8,9,0,1,2,3,4}.
+int[] z=x[-5:5]; // z={5,6,7,8,9,0,1,2,3,4}
+int[] w=x[-3:17]; // w={7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6}
+@end verbatim
+
+Notice that with cyclic arrays, it is possible to include the same element of
+the original array multiple times within a slice. Regardless of the original
+array, arrays produced by slices are always non-cyclic.
+
+If the left and right indices of a slice are the same, the result is an empty
+array. If the array being sliced is empty, the result is an empty array. Any
+slice with a left index greater than its right index will yield an error.
+
+Slices can also be assigned to, changing the value of the original array. If
+the array being assigned to the slice has a different length than the
+slice itself, elements will be inserted or removed from the array to
+accommodate it. For instance:
+
+@verbatim
+string[] toppings={"mayo", "salt", "ham", "lettuce"};
+toppings[0:2]=new string[] {"mustard", "pepper"};
+ // Now toppings={"mustard", "pepper", "ham", "lettuce"}
+toppings[2:3]=new string[] {"turkey", "bacon" };
+ // Now toppings={"mustard", "pepper", "turkey", "bacon", "lettuce"}
+toppings[0:3]=new string[] {"tomato"};
+ // Now toppings={"tomato", "bacon", "lettuce"}
+@end verbatim
+
+If an array is assigned to a slice of itself, a copy of the original array
+is assigned to the slice. That is, code such as @code{x[m:n]=x} is equivalent
+to @code{x[m:n]=copy(x)}. One can use the shorthand @code{x[m:m]=y} to insert
+the contents of the array @code{y} into the array @code{x} starting at the
+location just before @code{x[m]}.
+
+For a cyclic array, a slice is bridging if it addresses cells up to the end of
+the array and then continues on to address cells at the start of the array.
+For instance, if @code{A} is a cyclic array of length 10, @code{A[8:12]},
+@code{A[-3:1]}, and @code{A[5:25]} are bridging slices whereas @code{A[3:7]},
+@code{A[7:10]}, @code{A[-3:0]} and @code{A[103:107]} are not. Bridging slices
+can only be assigned to if the number of elements in the slice is exactly equal
+to the number of elements we are assigning to it. Otherwise, there is no clear
+way to decide which of the new entries should be @code{A[0]} and an error is
+reported. Non-bridging slices may be assigned an array of any length.
+
+For a cyclic array @code{A} an expression of the form
+@code{A[A.length:A.length]} is equivalent to the expression @code{A[0:0]} and
+so assigning to this slice will insert values at the start of the array.
+@code{A.append()} can be used to insert values at the end of the array.
+
+It is illegal to assign to a slice of a cyclic array that repeats any of the
+cells.
+
+@node Casts
+@section Casts
+@cindex casts
+@cindex implicit casts
+@cindex @code{explicit}
+
+@code{Asymptote} implicitly casts @code{int} to @code{real}, @code{int} to
+@code{pair}, @code{real} to @code{pair}, @code{pair} to @code{path},
+@code{pair} to @code{guide}, @code{path} to @code{guide}, @code{guide}
+to @code{path}, @code{real} to @code{pen},
+@code{pair[]} to @code{guide[]}, @code{pair[]} to @code{path[]},
+@code{path} to @code{path[]}, and @code{guide} to @code{path[]},
+along with various three-dimensional casts defined in @code{three.asy}.
+Implicit casts are automatically attempted on assignment and when
+trying to match function calls with possible function
+signatures. Implicit casting can be inhibited by declaring individual
+arguments @code{explicit} in the function signature, say to avoid an
+ambiguous function call in the following example, which outputs 0:
+
+@verbatim
+int f(pair a) {return 0;}
+int f(explicit real x) {return 1;}
+
+write(f(0));
+@end verbatim
+
+@cindex explicit casts
+Other conversions, say @code{real} to @code{int} or
+@code{real} to @code{string}, require an explicit cast:
+@verbatim
+int i=(int) 2.5;
+string s=(string) 2.5;
+
+real[] a={2.5,-3.5};
+int[] b=(int []) a;
+write(stdout,b); // Outputs 2,-3
+@end verbatim
+
+@cindex operator cast
+Casting to user-defined types is also possible using @code{operator cast}:
+@verbatim
+struct rpair {
+ real radius;
+ real angle;
+}
+
+pair operator cast(rpair x) {
+ return (x.radius*cos(x.angle),x.radius*sin(x.angle));
+}
+
+rpair x;
+x.radius=1;
+x.angle=pi/6;
+
+write(x); // Outputs (0.866025403784439,0.5)
+@end verbatim
+
+One must use care when defining new cast operators. Suppose that in some
+code one wants all integers to represent multiples of 100. To convert them
+to reals, one would first want to multiply them by 100. However, the
+straightforward implementation
+@verbatim
+real operator cast(int x) {return x*100;}
+@end verbatim
+is equivalent to an infinite recursion, since the result @code{x*100}
+needs itself to be cast from an integer to a real. Instead, we want to
+use the standard conversion of int to real:
+@verbatim
+real convert(int x) {return x*100;}
+real operator cast(int x)=convert;
+@end verbatim
+
+@cindex operator ecast
+Explicit casts are implemented similarly, with @code{operator ecast}.
+
+@node Import
+@section Import
+@cindex @code{access}
+While @code{Asymptote} provides many features by default,
+some applications require specialized features contained in
+external @code{Asymptote} modules. For instance, the lines
+@verbatim
+access graph;
+graph.axes();
+@end verbatim
+@noindent
+draw @math{x} and @math{y} axes on a two-dimensional graph. Here, the
+command looks up the module under the name @code{graph} in a global dictionary
+of modules and puts it in a new variable named @code{graph}.
+The module is a structure, and we can refer to its fields as we usually
+would with a structure.
+
+@cindex @code{from}
+Often, one wants to use module functions without having to specify
+the module name. The code
+@verbatim
+from graph access axes;
+@end verbatim
+@noindent
+adds the @code{axes} field of @code{graph} into the local name space,
+so that subsequently, one can just write @code{axes()}. If the given name
+is overloaded, all types and variables of that name are added. To add
+more than one name, just use a comma-separated list:
+
+@verbatim
+from graph access axes, xaxis, yaxis;
+@end verbatim
+@noindent
+Wild card notation can be used to add all non-private fields and types of a
+module to the local name space:
+
+@verbatim
+from graph access *;
+@end verbatim
+
+@cindex @code{unravel}
+Similarly, one can add the non-private fields and types of a structure
+to the local environment with the @code{unravel} keyword:
+
+@verbatim
+struct matrix {
+ real a,b,c,d;
+}
+
+real det(matrix m) {
+ unravel m;
+ return a*d-b*c;
+}
+@end verbatim
+Alternatively, one can unravel selective fields:
+@verbatim
+real det(matrix m) {
+ from m unravel a,b,c as C,d;
+ return a*d-b*C;
+}
+@end verbatim
+
+@cindex @code{import}
+The command
+@verbatim
+import graph;
+@end verbatim
+is a convenient abbreviation for the commands
+@verbatim
+access graph;
+unravel graph;
+@end verbatim
+That is, @code{import graph} first loads a module into a structure called
+@code{graph} and then adds its non-private fields and types to the
+local environment. This way, if a member variable (or function) is
+overwritten with a local variable (or function of the same signature),
+the original one can still be accessed by qualifying it with the
+module name.
+
+Wild card importing will work fine in most cases, but one does not usually know
+all of the internal types and variables of a module, which can also
+change as the module writer adds or changes features of the module.
+As such, it is prudent to add @code{import} commands at the start of an
+@code{Asymptote} file, so that imported names won't shadow locally
+defined functions. Still, imported names may shadow other imported
+names, depending on the order in which they were imported, and
+imported functions may cause overloading resolution problems if they
+have the same name as local functions defined later.
+
+@cindex @code{as}
+To rename modules or fields when adding them to the local environment, use
+@code{as}:
+
+@verbatim
+access graph as graph2d;
+from graph access xaxis as xline, yaxis as yline;
+@end verbatim
+
+The command
+@verbatim
+import graph as graph2d;
+@end verbatim
+is a convenient abbreviation for the commands
+@verbatim
+access graph as graph2d;
+unravel graph2d;
+@end verbatim
+
+Except for a few built-in modules, such as @code{settings}, all modules
+are implemented as @code{Asymptote} files. When looking up a module
+that has not yet been loaded, @code{Asymptote} searches the standard
+search paths (@pxref{Search paths}) for the matching file. The file
+corresponding to that name is read and the code within it is interpreted
+as the body of a structure defining the module.
+
+If the file name contains
+nonalphanumeric characters, enclose it with quotation marks:
+
+@noindent
+@code{access "@value{Datadir}/asymptote/graph.asy" as graph;}
+
+@noindent
+@code{from "@value{Datadir}/asymptote/graph.asy" access axes;}
+
+@noindent
+@code{import "@value{Datadir}/asymptote/graph.asy" as graph;}
+
+It is an error if modules import themselves (or each other in a cycle).
+The module name to be imported must be known at compile time.
+
+@cindex runtime imports
+@cindex @code{eval}
+However, you can import an @code{Asymptote} module determined by the
+string @code{s} at runtime like this:
+@verbatim
+eval("import "+s,true);
+@end verbatim
+
+@cindex @code{asy}
+To conditionally execute an array of asy files, use
+@verbatim
+void asy(string format, bool overwrite ... string[] s);
+@end verbatim
+The file will only be processed, using output format @code{format}, if
+overwrite is @code{true} or the output file is missing.
+
+One can evaluate an @code{Asymptote} expression (without any return
+value, however) contained in the string @code{s} with:
+@cindex @code{eval}
+@verbatim
+void eval(string s, bool embedded=false);
+@end verbatim
+It is not necessary to terminate the string @code{s} with a semicolon.
+If @code{embedded} is @code{true}, the string will be evaluated
+at the top level of the current environment.
+If @code{embedded} is @code{false} (the default), the string
+will be evaluated in an independent environment, sharing the same
+@code{settings} module (@pxref{settings}).
+
+@cindex @code{quote}
+One can evaluate arbitrary @code{Asymptote} code (which may
+contain unescaped quotation marks) with the command
+@verbatim
+void eval(code s, bool embedded=false);
+@end verbatim
+Here @code{code} is a special type used with @code{quote @{@}}
+to enclose @code{Asymptote code} like this:
+@verbatim
+real a=1;
+code s=quote {
+ write(a);
+};
+eval(s,true); // Outputs 1
+@end verbatim
+
+To include the contents of a file @code{graph} verbatim (as if the
+contents of the file were inserted at that point), use one of the forms:
+@verbatim
+include graph;
+@end verbatim
+
+@noindent
+@code{include "@value{Datadir}/asymptote/graph.asy";}
+
+To list all global functions and variables defined in a module named
+by the contents of the string @code{s}, use the function
+@verbatim
+void list(string s, bool imports=false);
+@end verbatim
+@noindent
+Imported global functions and variables are also listed if
+@code{imports} is @code{true}.
+
+@node Static
+@section Static
+@cindex @code{static}
+
+Static qualifiers allocate the memory address of a variable in a higher
+enclosing level.
+
+For a function body, the variable is allocated in the block where the
+function is defined; so in the code
+@verbatim
+struct s {
+ int count() {
+ static int c=0;
+ ++c;
+ return c;
+ }
+}
+@end verbatim
+
+@noindent
+there is one instance of the variable @code{c} for each
+object @code{s} (as opposed to each call of @code{count}).
+
+Similarly, in
+@verbatim
+int factorial(int n) {
+ int helper(int k) {
+ static int x=1;
+ x *= k;
+ return k == 1 ? x : helper(k-1);
+ }
+ return helper(n);
+}
+@end verbatim
+
+@noindent
+there is one instance of @code{x} for every call to
+@code{factorial} (and not for every call to @code{helper}), so this is
+a correct, but ugly, implementation of factorial.
+
+Similarly, a static variable declared within a structure is allocated in
+the block where the structure is defined. Thus,
+@verbatim
+struct A {
+ struct B {
+ static pair z;
+ }
+}
+@end verbatim
+
+@noindent
+creates one object @code{z} for each object of type @code{A} created.
+
+In this example,
+@verbatim
+int pow(int n, int k) {
+ struct A {
+ static int x=1;
+ void helper() {
+ x *= n;
+ }
+ }
+ for(int i=0; i < k; ++i) {
+ A a;
+ a.helper();
+ }
+ return A.x;
+}
+@end verbatim
+
+@noindent
+there is one instance of @code{x} for each call to @code{pow}, so this
+is an ugly implementation of exponentiation.
+
+Loop constructs allocate a new frame in every iteration. This is so that
+higher-order functions can refer to variables of a specific iteration of a
+loop:
+
+@verbatim
+void f();
+for(int i=0; i < 10; ++i) {
+ int x=i;
+ if(x==5) {
+ f=new void () { write(x); }
+ }
+}
+f();
+@end verbatim
+
+Here, every iteration of the loop has its own variable @code{x}, so @code{f()}
+will write @code{5}. If a variable in a loop is declared static, it will be
+allocated where the enclosing function or structure was defined (just as if it
+were declared static outside of the loop). For instance, in:
+
+@verbatim
+void f() {
+ static int x;
+ for(int i=0; i < 10; ++i) {
+ static int y;
+ }
+}
+@end verbatim
+@noindent
+both @code{x} and @code{y} will be allocated in the same place, which is
+also where @code{f} is also allocated.
+
+Statements may also be declared static, in which case they are run at the place
+where the enclosing function or structure is defined.
+Declarations or statements not enclosed in a function or structure definition
+are already at the top level, so static modifiers are meaningless. A warning is
+given in such a case.
+
+Since structures can have static fields, it is not always clear for a qualified
+name whether the qualifier is a variable or a type. For instance, in:
+
+@verbatim
+struct A {
+ static int x;
+}
+pair A;
+
+int y=A.x;
+@end verbatim
+@noindent
+does the @code{A} in @code{A.x} refer to the structure or to the pair variable.
+It is the convention in Asymptote that, if there is a non-function variable with
+the same name as the qualifier, the qualifier refers to that variable, and not
+to the type. This is regardless of what fields the variable actually possesses.
+
+@node LaTeX usage
+@chapter @code{LaTeX} usage
+@cindex @code{LaTeX} usage
+@cindex @code{asymptote.sty}
+
+@code{Asymptote} comes with a convenient @code{LaTeX} style file
+@code{asymptote.sty} that makes @code{LaTeX}
+@code{Asymptote}-aware. Entering @code{Asymptote} code
+directly into the @code{LaTeX} source file, at the point where it is
+needed, keeps figures organized and avoids the need to invent new file
+names for each figure. Simply add the line
+@code{\usepackage@{asymptote@}} at the beginning of your file
+and enclose your @code{Asymptote} code within a
+@code{\begin@{asy@}...\end@{asy@}} environment. As with the
+@code{LaTeX} @code{comment} environment, the @code{\end@{asy@}} command
+must appear on a line by itself, with no leading spaces or trailing
+commands/comments.
+
+The sample @code{LaTeX} file below, named @code{latexusage.tex}, can
+be run as follows:
+@verbatim
+latex latexusage
+asy latexusage
+latex latexusage
+@end verbatim
+
+@noindent
+or
+
+@verbatim
+pdflatex latexusage
+asy latexusage
+pdflatex latexusage
+@end verbatim
+
+To switch between using @code{latex} and @code{pdflatex} you may first
+need to remove the files @code{latexusage-*}, @code{latexusage_.pre}, and
+@code{latexusage.aux}.
+
+@cindex @code{width}
+@cindex @code{height}
+@cindex @code{viewportwidth}
+@cindex @code{viewportheight}
+@cindex @code{attach}
+One can specify @code{width}, @code{height},
+@code{viewportwidth}, @code{viewportheight}, and @code{attach}
+@code{keyval}-style options to the @code{asy} environment.
+The current version (1.06) of @code{asymptote.sty} supports the
+embedding of 3D @acronym{PRC} files, either inline or, using the
+@code{attach} option with the @code{attachfile2} (or older
+@code{attachfile}) @code{LaTeX} package,
+as annotated (but printable) attachments. For many applications, the
+annotated attachment method tends to be more convenient.
+The default value of @code{viewportwidth} is @code{\the\linewidth} for
+inline 3D figures and @code{0} for attachments.
+
+If the @code{inline} option is given to the
+@code{asymptote.sty} package, inline @code{LaTeX} code is generated instead of
+@acronym{EPS} or @acronym{PDF} files. This makes LaTeX symbols visible to the
+@code{\begin@{asy@}...\end@{asy@}} environment. In this mode,
+Asymptote correctly aligns LaTeX symbols defined outside of
+@code{\begin@{asy@}...\end@{asy@}}, but treats their size as zero; an
+optional second string can be given to @code{Label} to provide an
+estimate of the unknown label size.
+
+Note that if @code{latex} is used with the @code{inline} option,
+the labels might not show up in @acronym{DVI} viewers that cannot
+handle raw @code{PostScript} code. One can use @code{dvips}/@code{dvipdf} to
+produce @code{PostScript}/@acronym{PDF} output (we recommend using the
+modified version of @code{dvipdf} in the @code{Asymptote} patches
+directory, which accepts the @code{dvips -z} hyperdvi option).
+
+An excellent tutorial by Dario Teixeira on integrating @code{Asymptote} and
+@code{LaTeX} is available at @url{http://dario.dse.nl/projects/asylatex/}.
+
+Here now is @code{latexusage.tex}:
+@verbatiminclude latexusage.tex
+@page
+@image{latexusage,,25cm}
+
+@node Base modules
+@chapter Base modules
+@cindex base modules
+
+@code{Asymptote} currently ships with the following base modules:
+
+@menu
+* plain:: Default @code{Asymptote} base file
+* simplex:: Linear programming: simplex method
+* math:: Extend @code{Asymptote}'s math capabilities
+* interpolate:: Interpolation routines
+* geometry:: Geometry routines
+* trembling:: Wavy lines
+* stats:: Statistics routines and histograms
+* patterns:: Custom fill and draw patterns
+* markers:: Custom path marker routines
+* tree:: Dynamic binary search tree
+* binarytree:: Binary tree drawing module
+* drawtree:: Tree drawing module
+* syzygy:: Syzygy and braid drawing module
+* feynman:: Feynman diagrams
+* roundedpath:: Round the sharp corners of paths
+* animation:: Embedded @acronym{PDF} and @acronym{MPEG} movies
+* embed:: Embedding movies, sounds, and 3D objects
+* slide:: Making presentations with @code{Asymptote}
+* MetaPost:: @code{MetaPost} compatibility routines
+* unicode:: Accept @code{unicode} (UTF-8) characters
+* latin1:: Accept @code{ISO 8859-1} characters
+* babel:: Interface to @code{LaTeX} @code{babel} package
+* labelpath:: Drawing curved labels
+* labelpath3:: Drawing curved labels in 3D
+* annotate:: Annotate your @acronym{PDF} files
+* CAD:: 2D CAD pen and measurement functions (DIN 15)
+* graph:: 2D linear & logarithmic graphs
+* palette:: Color density images and palettes
+* three:: 3D vector graphics
+* obj:: 3D obj files
+* graph3:: 3D linear & logarithmic graphs
+* grid3:: 3D grids
+* solids:: 3D solid geometry
+* tube:: 3D rotation minimizing tubes
+* flowchart:: Flowchart drawing routines
+* contour:: Contour lines
+* contour3:: Contour surfaces
+* slopefield:: Slope fields
+
+@end menu
+
+@node plain
+@section @code{plain}
+@cindex @code{plain}
+
+This is the default @code{Asymptote} base file, which defines key parts of the
+drawing language (such as the @code{picture} structure).
+
+By default, an implicit @code{private import plain;} occurs before
+translating a file and before the first command given in interactive
+mode. This also applies when translating files for module definitions
+(except when translating @code{plain}, of course). This means that
+the types and functions defined in @code{plain} are accessible in
+almost all @code{Asymptote} code. Use the @code{-noautoplain} command-line
+option to disable this feature.
+
+@node simplex
+@section @code{simplex}
+@cindex @code{simplex}
+@cindex @code{deferred drawing}
+This package solves the two-variable linear programming problem using the
+simplex method. It is used by the module @code{plain} for automatic
+sizing of pictures.
+
+@node math
+@section @code{math}
+@cindex @code{math}
+This package extends @code{Asymptote}'s mathematical capabilities with
+intersection algorithms and matrix arithmetic:
+
+@table @code
+
+@cindex @code{drawline}
+@item void drawline(picture pic=currentpicture, pair P, pair Q, pen p=currentpen);
+draw the visible portion of the (infinite) line going through
+@code{P} and @code{Q}, without altering the size of picture @code{pic},
+using pen @code{p}.
+
+@cindex @code{intersect}
+@item real intersect(triple P, triple Q, triple n, triple Z);
+returns the intersection time of the extension of the line segment @code{PQ}
+with the plane perpendicular to @code{n} and passing through @code{Z}.
+
+@cindex @code{intersectionpoint}
+@item triple intersectionpoint(triple n0, triple P0, triple n1, triple P1);
+Return any point on the intersection of the two planes with normals
+@code{n0} and @code{n1} passing through points @code{P0} and @code{P1},
+respectively. If the planes are parallel, return
+@code{(infinity,infinity,infinity)}.
+
+@cindex @code{quarticroots}
+@item @code{pair[] quarticroots(real a, real b, real c, real d, real e);}
+returns the four complex roots of the quartic equation
+@math{ax^4+bx^3+cx^2+dx+e=0}.
+
+@end table
+
+@node interpolate
+@section @code{interpolate}
+@cindex @code{interpolate}
+This module implements Lagrange, Hermite, and standard cubic spline
+interpolation in @code{Asymptote}, as illustrated in the example
+@code{interpolate1.asy}.
+
+@node geometry
+@section @code{geometry}
+@cindex @code{geometry}
+@cindex @code{triangle}
+@cindex @code{perpendicular}
+This module, written by Philippe Ivaldi, provides an extensive set of
+geometry routines, including @code{perpendicular} symbols and a @code{triangle}
+structure. It is documented here:
+@url{http://piprim.tuxfamily.org/asymptote/geometry_en.pdf},
+including an extensive set of examples,
+@url{http://piprim.tuxfamily.org/asymptote/travaux/}, and an index:
+@quotation
+@url{http://piprim.tuxfamily.org/asymptote/travaux/modules/geometry_dev.asy.index.type.html}
+@end quotation
+
+@node trembling
+@section @code{trembling}
+@cindex @code{trembling}
+This module, written by Philippe Ivaldi and illustrated in the example
+@code{floatingdisk.asy}, allows one to draw wavy lines, as if drawn by
+hand. Further examples are posted at
+@url{http://piprim.tuxfamily.org/asymptote/modules}
+
+@node stats
+@section @code{stats}
+@cindex @code{stats}
+@cindex @code{leastsquares}
+This package implements a Gaussian random number generator
+and a collection of statistics routines, including @code{histogram}
+and @code{leastsquares}.
+
+@node patterns
+@section @code{patterns}
+@cindex @code{patterns}
+This package implements @code{Postscript} tiling patterns and includes
+several convenient pattern generation routines.
+
+@node markers
+@section @code{markers}
+@cindex @code{markers}
+This package implements specialized routines for marking paths and angles.
+The principal mark routine provided by this package is
+@verbatim
+markroutine markinterval(int n=1, frame f, bool rotated=false);
+@end verbatim
+@noindent
+which centers @code{n} copies of frame @code{f} within uniformly space
+intervals in arclength along the path, optionally rotated by the angle of the
+local tangent.
+
+The @code{marker} (@pxref{marker}) routine can be used to construct new
+markers from these predefined frames:
+
+@cindex @code{stickframe}
+@verbatim
+frame stickframe(int n=1, real size=0, pair space=0, real angle=0,
+ pair offset=0, pen p=currentpen);
+@end verbatim
+@cindex @code{circlebarframe}
+@verbatim
+frame circlebarframe(int n=1, real barsize=0,
+ real radius=0,real angle=0,
+ pair offset=0, pen p=currentpen,
+ filltype filltype=NoFill, bool above=false);
+@end verbatim
+@cindex @code{crossframe}
+@verbatim
+frame crossframe(int n=3, real size=0, pair space=0,
+ real angle=0, pair offset=0, pen p=currentpen);
+@end verbatim
+@cindex @code{tildeframe}
+@verbatim
+frame tildeframe(int n=1, real size=0, pair space=0,
+ real angle=0, pair offset=0, pen p=currentpen);
+@end verbatim
+
+For convenience, this module also constructs the markers
+@code{StickIntervalMarker}, @code{CrossIntervalMarker},
+@code{CircleBarIntervalMarker}, and @code{TildeIntervalMarker}
+from the above frames. The example @code{markers1.asy} illustrates the
+use of these markers:
+
+@sp 1
+@center @image{markers1}
+
+This package also provides a routine for marking an angle @math{AOB}:
+@cindex @code{markangle}
+@verbatim
+void markangle(picture pic=currentpicture, Label L="",
+ int n=1, real radius=0, real space=0,
+ pair A, pair O, pair B, arrowbar arrow=None,
+ pen p=currentpen, margin margin=NoMargin,
+ marker marker=nomarker);
+@end verbatim
+@noindent
+as illustrated in the example @code{markers2.asy}.
+
+@sp 1
+@center @image{markers2}
+
+@node tree
+@section @code{tree}
+@cindex @code{tree}
+This package implements an example of a dynamic binary search tree.
+
+@node binarytree
+@section @code{binarytree}
+@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{binarytreetest.asy}:
+@verbatiminclude binarytreetest.asy
+@sp 1
+@center @image{binarytreetest}
+
+@node drawtree
+@section @code{drawtree}
+@cindex @code{drawtree}
+This is a simple tree drawing module used by the example @code{treetest.asy}.
+
+@node syzygy
+@section @code{syzygy}
+@cindex @code{syzygy}
+This module automates the drawing of braids, relations, and syzygies,
+along with the corresponding equations, as illustrated in the example
+@code{knots.asy}.
+
+@node feynman
+@section @code{feynman}
+@cindex @code{feynman}
+This package, contributed by Martin Wiebusch, is useful for drawing
+Feynman diagrams, as illustrated by the examples @code{eetomumu.asy}
+and @code{fermi.asy}.
+
+@node roundedpath
+@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{roundpath.asy}.
+
+@node animation
+@section @code{animation}
+@cindex @code{animation}
+@cindex @code{merge}
+@cindex @code{convert}
+@cindex animation
+@cindex @code{ImageMagick}
+This module allows one to generate animations, as illustrated by the
+files @code{wheel.asy}, @code{wavelet.asy}, and @code{cube.asy} in
+the @code{animations} subdirectory of the examples directory. These
+animations use the @code{ImageMagick} @code{convert} program to
+@code{merge} multiple images into a @acronym{GIF} or @acronym{MPEG}
+movie.
+
+@cindex @code{animate}
+@anchor{animate}
+The related @code{animate} module, derived from the @code{animation}
+module, generates higher-quality portable clickable @acronym{PDF} movies, with
+optional controls. This requires installing the package
+@quotation
+@url{http://www.ctan.org/tex-archive/macros/latex/contrib/animate/animate.sty}
+@noindent
+@end quotation
+@noindent
+(version 2007/11/30 or later) in a new directory @code{animate} in the
+local @code{LaTeX} directory (for example, in
+@code{/usr/local/share/texmf/tex/latex/animate}). On @code{UNIX} systems,
+one must then execute the command @code{texhash}.
+
+The example @code{pdfmovie.asy} in the @code{animations}
+directory, along with the slide presentations @code{slidemovies.asy}
+and @code{intro.asy}, 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}).
+The member function
+@verbatim
+string pdf(fit fit=NoBox, real delay=animationdelay, string options="",
+ bool keep=settings.keep, bool multipage=true);
+@end verbatim
+@noindent
+of the @code{animate} structure accepts any of the @code{animate.sty} options,
+as described here:
+@quotation
+@url{http://www.ctan.org/tex-archive/macros/latex/contrib/animate/doc/animate.pdf}
+@end quotation
+
+@node embed
+@section @code{embed}
+@cindex @code{embed}
+This module provides an interface to the @code{LaTeX} package
+(included with @code{MikTeX})
+@quotation
+@url{http://www.ctan.org/tex-archive/macros/latex/contrib/movie15}
+@end quotation
+@noindent
+for embedding movies, sounds, and 3D objects into a @acronym{PDF} document.
+@noindent
+@cindex @code{XeLaTeX}
+However, @code{XeLaTeX} users need to rename the modified version
+@code{movie15_dvipdfmx.sty} from
+@quotation
+@url{http://asymptote.svn.sourceforge.net/viewvc/asymptote/trunk/asymptote/patches/}
+@end quotation
+to @code{movie15.sty} and place it in their @code{LaTeX} path.
+
+The latest version (2008/10/08) of the @code{movie15} package requires both
+@code{pdflatex} version 1.20 or later and the file
+@quotation
+@url{http://www.ctan.org/tex-archive/macros/latex/contrib/oberdiek/ifdraft.dtx}
+@end quotation
+@noindent
+which can be installed by placing it in a directory @code{ifdraft} in
+the local @code{LaTeX} directory
+(e.g.@ @code{/usr/local/share/texmf/tex/latex/ifdraft}) and executing in that
+directory the commands:
+@verbatim
+tex ifdraft.dtx
+texhash
+@end verbatim
+
+@cindex @code{external}
+An example of embedding @code{U3D} code is provided in the file
+@code{embeddedu3d.asy}.
+As of version 7.0.8, @code{Adobe Reader} supports the @code{U3D} format
+under Linux.
+
+Unfortunately, Adobe has not yet made available an embedded movie plugin
+for the Linux version of @code{Adobe Reader}. A portable method for
+embedding movie files, which should work on any platform and does not require
+the @code{movie15} or @code{ifdraft} packages, is provided by using the
+@code{external} module instead of @code{embed}. An example of these
+interfaces is provided in the file @code{embeddedmovie.asy} and
+@code{externalmovie.asy} in the @code{animations} subdirectory of the
+examples directory. For a higher quality 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
+(@pxref{animate}).
+
+@node slide
+@section @code{slide}
+@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{slidemovies.asy}). A simple example is provided in the file
+@code{slidedemo.asy}.
+
+@node MetaPost
+@section @code{MetaPost}
+@cindex @code{MetaPost}
+This package provides some useful routines to help @code{MetaPost} users
+migrate old @code{MetaPost} code to @code{Asymptote}. Further
+contributions here are welcome.
+
+@cindex @code{implicit linear solver}
+@cindex @code{MetaPost whatever}
+@cindex @code{extension}
+Unlike @code{MetaPost}, @code{Asymptote} does not implicitly solve
+linear equations and therefore does not have the notion of a
+@code{whatever} unknown. The routine @code{extension} (@pxref{extension})
+provides a useful replacement for a common use of @code{whatever}: finding the
+intersection point of the lines through @code{P}, @code{Q} and
+@code{p}, @code{q}. For less common occurrences of @code{whatever}, one
+can use the built-in explicit linear equation solver @code{solve} instead.
+
+@node unicode
+@section @code{unicode}
+@cindex @code{unicode}
+@cindex international characters
+Import this package at the beginning of the file to instruct
+@code{LaTeX} to accept @code{unicode} (UTF-8) standardized international
+characters.
+@noindent
+@cindex Cyrillic
+@cindex Russian
+To use Cyrillic fonts, you will need to change the font encoding:
+@verbatim
+import unicode;
+texpreamble("\usepackage{mathtext}\usepackage[russian]{babel}");
+defaultpen(font("T2A","cmr"));
+@end verbatim
+@noindent
+@cindex Chinese
+@cindex Japanese
+@cindex Korean
+@cindex CJK
+Support for Chinese, Japanese, and Korean fonts is provided by the
+CJK package:
+@quotation
+@url{http://www.ctan.org/tex-archive/languages/chinese/CJK/}
+@end quotation
+@noindent
+The following commands enable the CJK song family (within a label, you
+can also temporarily switch to another family, say kai, by prepending
+@code{"\CJKfamily@{kai@}"} to the label string):
+@verbatim
+texpreamble("\usepackage{CJK}
+\AtBeginDocument{\begin{CJK*}{GBK}{song}}
+\AtEndDocument{\clearpage\end{CJK*}}");
+@end verbatim
+
+@node latin1
+@section @code{latin1}
+@cindex @code{latin1}
+If you don't have @code{LaTeX} support for @code{unicode} installed,
+you can enable support for Western European languages (ISO 8859-1) by
+importing the module @code{latin1}. This module can be used as a
+template for providing support for other ISO 8859 alphabets.
+
+@node babel
+@section @code{babel}
+@cindex @code{babel}
+This module implements the @code{LaTeX} @code{babel} package in
+@code{Asymptote}. For example:
+@verbatim
+import babel;
+babel("german");
+@end verbatim
+
+@node labelpath
+@section @code{labelpath}
+@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
+@code{curvedlabel.asy}), using the command
+@verbatim
+void labelpath(picture pic=currentpicture, Label L, path g,
+ string justify=Centered, pen p=currentpen);
+@end verbatim
+@noindent
+Here @code{justify} is one of @code{LeftJustified}, @code{Centered}, or
+@code{RightJustified}. The @math{x} component of a shift transform
+applied to the Label is interpreted as a shift along the curve, whereas
+the @math{y} component is interpreted as a shift away from the curve.
+All other Label transforms are ignored. This package requires the
+@code{latex} tex engine and inherits the limitations of the
+@code{PSTricks} @code{\pstextpath} macro.
+
+@node labelpath3
+@section @code{labelpath3}
+@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{curvedlabel3.asy}.
+
+@node annotate
+@section @code{annotate}
+@cindex @code{annotate}
+This module supports @acronym{PDF} annotations for viewing with
+@code{Adobe Reader}, via the function
+@verbatim
+void annotate(picture pic=currentpicture, string title, string text,
+ pair position);
+@end verbatim
+@noindent
+Annotations are illustrated in the example file @code{annotation.asy}.
+Currently, annotations are only implemented for the @code{latex}
+(default) and @code{tex} @TeX{} engines.
+
+@node CAD
+@section @code{CAD}
+@cindex @code{CAD}
+This package, contributed by Mark Henning, provides basic pen
+definitions and measurement functions for simple 2D CAD drawings
+according to DIN 15. It is documented separately, in the file
+@code{CAD.pdf}.
+
+@node graph
+@section @code{graph}
+@cindex @code{graph}
+@cindex 2D graphs
+This package implements two-dimensional linear and logarithmic graphs,
+including automatic scale and tick selection (with the ability to
+override manually). A graph is a @code{guide} (that can be drawn with
+the draw command, with an optional legend) constructed with one of
+the following routines:
+
+@itemize
+@item
+@verbatim
+guide graph(picture pic=currentpicture, real f(real), real a, real b,
+ int n=ngraph, real T(real)=identity,
+ interpolate join=operator --);
+guide[] graph(picture pic=currentpicture, real f(real), real a, real b,
+ int n=ngraph, real T(real)=identity, bool3 cond(real),
+ interpolate join=operator --);
+@end verbatim
+
+Returns a graph using the scaling information for picture @code{pic}
+(@pxref{automatic scaling}) of the function @code{f} on the interval
+[@code{T}(@code{a}),@code{T}(@code{b})], sampling at @code{n} points
+evenly spaced in [@code{a},@code{b}], optionally restricted by the
+bool3 function @code{cond} on [@code{a},@code{b}]. If @code{cond} is:
+@itemize @bullet
+@item @code{true}, the point is added to the existing guide;
+@item @code{default}, the point is added to a new guide;
+@item @code{false}, the point is omitted and a new guide is begun.
+@end itemize
+Th points are connected using the interpolation specified by @code{join}:
+@itemize @bullet
+
+@cindex @code{operator --}
+@cindex @code{Straight}
+@item @code{operator --} (linear interpolation; the abbreviation
+@code{Straight} is also accepted);
+
+@cindex @code{operator ..}
+@cindex @code{Spline}
+@item @code{operator ..} (piecewise Bezier cubic spline interpolation;
+the abbreviation @code{Spline} is also accepted);
+
+@cindex @code{Hermite}
+@cindex @code{Hermite(splinetype splinetype}
+@item @code{Hermite} (standard cubic spline interpolation using boundary
+condition @code{notaknot}, @code{natural}, @code{periodic},
+@code{clamped(real slopea, real slopeb)}), or @code{monotonic}.
+The abbreviation @code{Hermite} is equivalent to
+@code{Hermite(notaknot)} for nonperiodic data and
+@code{Hermite(periodic)} for periodic data).
+
+@end itemize
+
+@item
+@verbatim
+guide graph(picture pic=currentpicture, real x(real), real y(real),
+ real a, real b, int n=ngraph, real T(real)=identity,
+ interpolate join=operator --);
+guide[] graph(picture pic=currentpicture, real x(real), real y(real),
+ real a, real b, int n=ngraph, real T(real)=identity,
+ bool3 cond(real), interpolate join=operator --);
+@end verbatim
+
+Returns a graph using the scaling information for picture @code{pic}
+of the parametrized function
+(@code{x}(@math{t}),@code{y}(@math{t})) for @math{t} in the interval
+[@code{T}(@code{a}),@code{T}(@code{b})], sampling at @code{n} points
+evenly spaced in [@code{a},@code{b}], optionally restricted by the
+bool3 function @code{cond} on [@code{a},@code{b}], using the given
+interpolation type.
+
+@item
+@verbatim
+guide graph(picture pic=currentpicture, pair z(real), real a, real b,
+ int n=ngraph, real T(real)=identity,
+ interpolate join=operator --);
+guide[] graph(picture pic=currentpicture, pair z(real), real a, real b,
+ int n=ngraph, real T(real)=identity, bool3 cond(real),
+ interpolate join=operator --);
+@end verbatim
+
+Returns a graph using the scaling information for picture @code{pic}
+of the parametrized function
+@code{z}(@math{t}) for @math{t} in the interval
+[@code{T}(@code{a}),@code{T}(@code{b})], sampling at @code{n} points
+evenly spaced in [@code{a},@code{b}], optionally restricted by the
+bool3 function @code{cond} on [@code{a},@code{b}], using the given
+interpolation type.
+
+@item
+@verbatim
+guide graph(picture pic=currentpicture, pair[] z,
+ interpolate join=operator --);
+guide[] graph(picture pic=currentpicture, pair[] z, bool3[] cond,
+ interpolate join=operator --);
+@end verbatim
+
+Returns a graph using the scaling information for picture @code{pic}
+of the elements of the array @code{z}, optionally restricted to
+those indices for which the elements of the boolean array @code{cond} are
+@code{true}, using the given interpolation type.
+
+@item
+@verbatim
+guide graph(picture pic=currentpicture, real[] x, real[] y,
+ interpolate join=operator --);
+guide[] graph(picture pic=currentpicture, real[] x, real[] y,
+ bool3[] cond, interpolate join=operator --);
+@end verbatim
+
+Returns a graph using the scaling information for picture @code{pic}
+of the elements of the arrays (@code{x},@code{y}), optionally
+restricted to those indices for which the elements of the boolean
+array @code{cond} are @code{true}, using the given interpolation type.
+
+@item
+@cindex @code{polargraph}
+@verbatim
+guide polargraph(picture pic=currentpicture, real f(real), real a,
+ real b, int n=ngraph, interpolate join=operator --);
+@end verbatim
+
+Returns a polar-coordinate graph using the scaling information for
+picture @code{pic} of the function @code{f} on the interval
+[@code{a},@code{b}], sampling at @code{n} evenly spaced points, with
+the given interpolation type.
+
+@end itemize
+
+@verbatim
+
+
+@end verbatim
+
+An axis can be drawn on a picture with one of the following commands:
+
+@itemize
+
+@item
+@verbatim
+void xaxis(picture pic=currentpicture, Label L="", axis axis=YZero,
+ real xmin=-infinity, real xmax=infinity, pen p=currentpen,
+ ticks ticks=NoTicks, arrowbar arrow=None, bool above=false);
+@end verbatim
+
+Draw an @math{x} axis on picture @code{pic} from @math{x}=@code{xmin} to
+@math{x}=@code{xmax} using pen @code{p}, optionally labelling it with
+Label @code{L}. The relative label location along the axis (a real number from
+[0,1]) defaults to 1 (@pxref{Label}), so that the label is drawn at the
+end of the axis. An infinite value of @code{xmin}
+or @code{xmax} specifies that the corresponding axis limit will be
+automatically determined from the picture limits.
+The optional @code{arrow} argument takes the same values as in the
+@code{draw} command (@pxref{arrows}). The axis is drawn before any
+existing objects in the current picture unless @code{above=true}.
+The axis placement is determined by one of the following @code{axis} types:
+
+@table @code
+
+@cindex @code{YZero}
+@item YZero(bool extend=true)
+Request an @math{x} axis at @math{y}=0 (or @math{y}=1 on a logarithmic axis)
+extending to the full dimensions of the picture, unless @code{extend}=false.
+
+@cindex @code{YEquals}
+@item YEquals(real Y, bool extend=true)
+Request an @math{x} axis at @math{y}=@code{Y} extending to the full
+dimensions of the picture, unless @code{extend}=false.
+
+@cindex @code{Bottom}
+@item Bottom(bool extend=false)
+Request a bottom axis.
+
+@cindex @code{Top}
+@item Top(bool extend=false)
+Request a top axis.
+
+@cindex @code{BottomTop}
+@item BottomTop(bool extend=false)
+Request a bottom and top axis.
+
+@end table
+
+@cindex custom axis types
+Custom axis types can be created by following the examples in @code{graph.asy}.
+One can easily override the default values for the standard axis types:
+@verbatim
+import graph;
+
+YZero=new axis(bool extend=true) {
+ return new void(picture pic, axisT axis) {
+ real y=pic.scale.x.scale.logarithmic ? 1 : 0;
+ axis.value=I*pic.scale.y.T(y);
+ axis.position=1;
+ axis.side=right;
+ axis.align=2.5E;
+ axis.value2=Infinity;
+ axis.extend=extend;
+ };
+};
+YZero=YZero();
+
+@end verbatim
+
+@anchor{ticks}
+@cindex @code{ticks}
+@cindex @code{NoTicks}
+@cindex @code{LeftTicks}
+@cindex @code{RightTicks}
+@cindex @code{Ticks}
+The default tick option is @code{NoTicks}.
+The options @code{LeftTicks}, @code{RightTicks}, or @code{Ticks} can be
+used to draw ticks on the left, right, or both sides of the path,
+relative to the direction in which the path is drawn.
+These tick routines accept a number of optional arguments:
+@verbatim
+ticks LeftTicks(Label format="", ticklabel ticklabel=null,
+ bool beginlabel=true, bool endlabel=true,
+ int N=0, int n=0, real Step=0, real step=0,
+ bool begin=true, bool end=true, tickmodifier modify=None,
+ real Size=0, real size=0, bool extend=false,
+ pen pTick=nullpen, pen ptick=nullpen);
+@end verbatim
+
+If any of these parameters are omitted, reasonable defaults will
+be chosen:
+@table @code
+@item Label format
+@cindex @code{defaultformat}
+@cindex @code{trailingzero}
+override the default tick label format (@code{defaultformat}, initially
+"$%.4g$"), rotation, pen, and alignment (for example, @code{LeftSide},
+@code{Center}, or @code{RightSide}) relative to the axis. To enable
+@code{LaTeX} math mode fonts, the format string should begin and
+end with @code{$} @pxref{format}. If the format string is @code{trailingzero},
+trailing zeros will be added to the tick labels; if the format string is
+@code{"%"}, the tick label will be suppressed;
+@item ticklabel
+is a function @code{string(real x)} returning the label (by default,
+format(format.s,x)) for each major tick value @code{x};
+@item bool beginlabel
+include the first label;
+@item bool endlabel
+include the last label;
+@item int N
+when automatic scaling is enabled (the default; @pxref{automatic scaling}),
+divide a linear axis evenly into this many intervals, separated by major ticks;
+for a logarithmic axis, this is the number of decades between labelled ticks;
+@item int n
+divide each interval into this many subintervals, separated by minor ticks;
+@item real Step
+the tick value spacing between major ticks
+(if @code{N}=@code{0});
+@item real step
+the tick value spacing between minor ticks (if @code{n}=@code{0});
+@item bool begin
+include the first major tick;
+@item bool end
+include the last major tick;
+@item tickmodifier modify;
+an optional function that takes and returns a @code{tickvalue} structure having
+real[] members @code{major} and @code{minor} consisting of the tick values
+(to allow modification of the automatically generated tick values);
+@item real Size
+the size of the major ticks (in @code{PostScript} coordinates);
+@item real size
+the size of the minor ticks (in @code{PostScript} coordinates);
+@item bool extend;
+extend the ticks between two axes (useful for drawing a grid on the graph);
+@item pen pTick
+an optional pen used to draw the major ticks;
+@item pen ptick
+an optional pen used to draw the minor ticks.
+
+@end table
+
+For convenience, the predefined tickmodifier @code{OmitTick(... real[] x)}
+tickmodifier can be used to remove specific auto-generated ticks and
+their labels. The @code{OmitFormat(string s=defaultformat ... real[] x)}
+ticklabel can be used to remove specific tick labels but not the
+corresponding ticks. The tickmodifier @code{NoZero} is an abbreviation for
+@code{OmitTick(0)} and the ticklabel @code{NoZeroFormat} is an
+abbrevation for @code{OmitFormat(0)}.
+
+@cindex custom tick locations
+@cindex @code{LeftTicks}
+@cindex @code{RightTicks}
+@cindex @code{Ticks}
+It is also possible to specify custom tick locations with
+@code{LeftTicks}, @code{RightTicks}, and @code{Ticks} by passing explicit real
+arrays @code{Ticks} and (optionally) @code{ticks} containing the
+locations of the major and minor ticks, respectively:
+@verbatim
+ticks LeftTicks(Label format="", ticklabel ticklabel=null,
+ bool beginlabel=true, bool endlabel=true,
+ real[] Ticks, real[] ticks=new real[],
+ real Size=0, real size=0, bool extend=false,
+ pen pTick=nullpen, pen ptick=nullpen)
+@end verbatim
+
+@item
+@verbatim
+void yaxis(picture pic=currentpicture, Label L="", axis axis=XZero,
+ real ymin=-infinity, real ymax=infinity, pen p=currentpen,
+ ticks ticks=NoTicks, arrowbar arrow=None, bool above=false);
+@end verbatim
+
+Draw a @math{y} axis on picture @code{pic} from @math{y}=@code{ymin} to
+@math{y}=@code{ymax} using pen @code{p}, optionally labelling it with
+Label @code{L}. The relative location of the label (a real number from
+[0,1]) defaults to 1 (@pxref{Label}). An infinite value of @code{ymin}
+or @code{ymax} specifies that the corresponding axis limit will be
+automatically determined from the picture limits.
+The optional @code{arrow} argument takes the same values as in the
+@code{draw} command (@pxref{arrows}). The axis is drawn before any
+existing objects in the current picture unless @code{above=true}.
+The tick type is specified by @code{ticks} and the axis placement is
+determined by one of the following @code{axis} types:
+
+@table @code
+
+@cindex @code{XZero}
+@item XZero(bool extend=true)
+Request a @math{y} axis at @math{x}=0 (or @math{x}=1 on a logarithmic axis)
+extending to the full dimensions of the picture, unless @code{extend}=false.
+
+@cindex @code{XEquals}
+@item XEquals(real X, bool extend=true)
+Request a @math{y} axis at @math{x}=@code{X} extending to the full
+dimensions of the picture, unless @code{extend}=false.
+
+@cindex @code{Left}
+@item Left(bool extend=false)
+Request a left axis.
+
+@cindex @code{Right}
+@item Right(bool extend=false)
+Request a right axis.
+
+@cindex @code{LeftRight}
+@item LeftRight(bool extend=false)
+Request a left and right axis.
+
+@end table
+
+@item
+@cindex @code{xequals}
+@cindex @code{yequals}
+For convenience, the functions
+@verbatim
+void xequals(picture pic=currentpicture, Label L="", real x,
+ bool extend=false, real ymin=-infinity, real ymax=infinity,
+ pen p=currentpen, ticks ticks=NoTicks, bool above=true,
+ arrowbar arrow=None);
+@end verbatim
+and
+@verbatim
+void yequals(picture pic=currentpicture, Label L="", real y,
+ bool extend=false, real xmin=-infinity, real xmax=infinity,
+ pen p=currentpen, ticks ticks=NoTicks, bool above=true,
+ arrowbar arrow=None);
+@end verbatim
+can be respectively used to call @code{yaxis} and
+@code{xaxis} with the appropriate axis types @code{XEquals(x,extend)} and
+@code{YEquals(y,extend)}. This is the recommended way of drawing vertical
+or horizontal lines and axes at arbitrary locations.
+
+@item
+@verbatim
+void axes(picture pic=currentpicture, Label xlabel="", Label ylabel="",
+ pair min=(-infinity,-infinity), pair max=(infinity,infinity),
+ pen p=currentpen, arrowbar arrow=None, bool above=false);
+@end verbatim
+This convenience routine draws both @math{x} and @math{y} axes
+on picture @code{pic} from @code{min} to @code{max},
+with optional labels @code{xlabel} and @code{ylabel}
+and any arrows specified by @code{arrow}. The axes are drawn on top of
+existing objects in the current picture only if @code{above=true}.
+
+@item
+@verbatim
+void axis(picture pic=currentpicture, Label L="", path g,
+ pen p=currentpen, ticks ticks, ticklocate locate,
+ arrowbar arrow=None, int[] divisor=new int[],
+ bool above=false, bool opposite=false);
+@end verbatim
+
+This routine can be used to draw on picture @code{pic} a general axis
+based on an arbitrary path @code{g}, using pen @code{p}.
+One can optionally label the axis with Label @code{L} and add an arrow
+@code{arrow}. The tick type is given by @code{ticks}.
+The optional integer array @code{divisor} specifies what tick divisors
+to try in the attempt to produce uncrowded tick labels. A @code{true}
+value for the flag @code{opposite} identifies an unlabelled secondary
+axis (typically drawn opposite a primary axis). The axis is drawn before
+any existing objects in the current picture unless @code{above=true}.
+The tick locator @code{ticklocate} is constructed by the routine
+@verbatim
+ticklocate ticklocate(real a, real b, autoscaleT S=defaultS,
+ real tickmin=-infinity, real tickmax=infinity,
+ real time(real)=null, pair dir(real)=zero);
+@end verbatim
+@noindent
+where @code{a} and @code{b} specify the respective tick values at
+@code{point(g,0)} and @code{point(g,length(g))}, @code{S} specifies
+the autoscaling transformation, the function @code{real time(real v)}
+returns the time corresponding to the value @code{v}, and
+@code{pair dir(real t)} returns the absolute tick direction as a
+function of @code{t} (zero means draw the tick perpendicular to the axis).
+
+@item These routines are useful for manually putting ticks and labels on axes
+(if the variable @code{Label} is given as the @code{Label}
+argument, the @code{format} argument will be used to format a string based on
+the tick location):
+@cindex xtick
+@cindex ytick
+@cindex labelx
+@cindex labely
+@cindex tick
+@cindex Label
+@verbatim
+void xtick(picture pic=currentpicture, Label L="", explicit pair z,
+ pair dir=N, string format="",
+ real size=Ticksize, pen p=currentpen);
+void xtick(picture pic=currentpicture, Label L="", real x,
+ pair dir=N, string format="",
+ real size=Ticksize, pen p=currentpen);
+void ytick(picture pic=currentpicture, Label L="", explicit pair z,
+ pair dir=E, string format="",
+ real size=Ticksize, pen p=currentpen);
+void ytick(picture pic=currentpicture, Label L="", real y,
+ pair dir=E, string format="",
+ real size=Ticksize, pen p=currentpen);
+void tick(picture pic=currentpicture, pair z,
+ pair dir, real size=Ticksize, pen p=currentpen);
+void labelx(picture pic=currentpicture, Label L="", explicit pair z,
+ align align=S, string format="", pen p=nullpen);
+void labelx(picture pic=currentpicture, Label L="", real x,
+ align align=S, string format="", pen p=nullpen);
+void labelx(picture pic=currentpicture, Label L,
+ string format="", explicit pen p=currentpen);
+void labely(picture pic=currentpicture, Label L="", explicit pair z,
+ align align=W, string format="", pen p=nullpen);
+void labely(picture pic=currentpicture, Label L="", real y,
+ align align=W, string format="", pen p=nullpen);
+void labely(picture pic=currentpicture, Label L,
+ string format="", explicit pen p=nullpen);
+@end verbatim
+@end itemize
+
+Here are some simple examples of two-dimensional graphs:
+
+@enumerate
+
+@cindex textbook graph
+@item This example draws a textbook-style graph of
+@math{y=} exp@math{(x)}, with the @math{y} axis starting at @math{y=0}:
+@verbatiminclude exp.asy
+@sp 1
+@center @image{exp}
+
+
+@item The next example draws a scientific-style graph with a legend.
+The position of the legend can be adjusted either explicitly or by using the
+graphical user interface @code{xasy} (@pxref{GUI}). If an
+@code{UnFill(real xmargin=0, real ymargin=xmargin)} or
+@code{Fill(pen)} option is specified to @code{add}, the legend will obscure
+any underlying objects. Here we illustrate how to clip the portion of
+the picture covered by a label:
+
+@cindex scientific graph
+@verbatiminclude lineargraph0.asy
+@sp 1
+@center @image{lineargraph0}
+
+@cindex @code{attach}
+To specify a fixed size for the graph proper, use @code{attach}:
+@verbatiminclude lineargraph.asy
+
+@cindex @code{legend}
+A legend can have multiple entries per line:
+@verbatiminclude legend.asy
+@sp 1
+@center @image{legend}
+
+@item This example draws a graph of one array versus another (both of
+the same size) using custom tick locations and a smaller font size for
+the tick labels on the @math{y} axis.
+@verbatiminclude datagraph.asy
+@sp 1
+@center @image{datagraph}
+
+@item This example shows how to graph columns of data read from a file.
+@verbatiminclude filegraph.asy
+@sp 1
+@center @image{filegraph}
+
+@cindex @code{polygon}
+@cindex @code{cross}
+@cindex @code{errorbars}
+@cindex @code{marker}
+@cindex @code{marknodes}
+@cindex @code{markuniform}
+@cindex @code{mark}
+@anchor{pathmarkers}
+@item The next example draws two graphs of an array of coordinate pairs,
+using frame alignment and data markers. In the left-hand graph, the
+markers, constructed with
+@verbatim
+marker marker(path g, markroutine markroutine=marknodes,
+ pen p=currentpen, filltype filltype=NoFill,
+ bool above=true);
+@end verbatim
+using the path @code{unitcircle} (@pxref{filltype}), are drawn
+below each node. Any frame can be converted to a marker, using
+@anchor{marker}
+@verbatim
+marker marker(frame f, markroutine markroutine=marknodes,
+ bool above=true);
+@end verbatim
+In the right-hand graph, the unit @math{n}-sided regular polygon
+@code{polygon(int n)} and the unit @math{n}-point cyclic cross
+@code{cross(int n, bool round=true, real r=0)} (where @code{r} is an
+optional ``inner'' radius) are used to build a custom marker frame.
+@anchor{markuniform}
+Here @code{markuniform(bool centered=false, int n, bool rotated=false)}
+adds this frame at @code{n} uniformly spaced points along the arclength
+of the path, optionally rotated by the angle of the local tangent to the path
+(if centered is true, the frames will be centered within @code{n} evenly
+spaced arclength intervals). Alternatively, one can use
+markroutine @code{marknodes} to request that the marks be placed at each
+Bezier node of the path, or
+markroutine @code{markuniform(pair z(real t), real a, real b, int n)}
+to place marks at points @code{z(t)} for n evenly spaced values of
+@code{t} in @code{[a,b]}.
+
+These markers are predefined:
+@verbatim
+marker[] Mark={
+ marker(scale(circlescale)*unitcircle),
+ marker(polygon(3)),marker(polygon(4)),
+ marker(polygon(5)),marker(invert*polygon(3)),
+ marker(cross(4)),marker(cross(6))
+};
+
+marker[] MarkFill={
+ marker(scale(circlescale)*unitcircle,Fill),marker(polygon(3),Fill),
+ marker(polygon(4),Fill),marker(polygon(5),Fill),
+ marker(invert*polygon(3),Fill)
+};
+@end verbatim
+
+The example also illustrates the @code{errorbar} routines:
+
+@verbatim
+void errorbars(picture pic=currentpicture, pair[] z, pair[] dp,
+ pair[] dm={}, bool[] cond={}, pen p=currentpen,
+ real size=0);
+
+void errorbars(picture pic=currentpicture, real[] x, real[] y,
+ real[] dpx, real[] dpy, real[] dmx={}, real[] dmy={},
+ bool[] cond={}, pen p=currentpen, real size=0);
+@end verbatim
+
+@noindent
+Here, the positive and negative extents of the error are given by the
+absolute values of the elements of the pair array @code{dp} and the
+optional pair array @code{dm}. If @code{dm} is not specified, the
+positive and negative extents of the error are assumed to be equal.
+@anchor{errorbars}
+@verbatiminclude errorbars.asy
+@sp 1
+@center @image{errorbars}
+
+@cindex custom mark routine
+@item A custom mark routine can be also be specified:
+@verbatiminclude graphmarkers.asy
+@sp 1
+@center @image{graphmarkers}
+
+@item This example shows how to label an axis with arbitrary strings.
+@verbatiminclude monthaxis.asy
+@sp 1
+@center @image{monthaxis}
+
+@item The next example draws a graph of a parametrized curve.
+@cindex parametrized curve
+@cindex cropping graphs
+@cindex @code{xlimits}
+@cindex @code{ylimits}
+@cindex @code{limits}
+@cindex @code{crop}
+The calls to
+@verbatim
+xlimits(picture pic=currentpicture, real min=-infinity,
+ real max=infinity, bool crop=NoCrop);
+@end verbatim
+@noindent
+and the analogous function @code{ylimits} can be uncommented
+to set the respective axes limits for picture @code{pic} to the
+specified @code{min} and @code{max} values. Alternatively, the function
+@verbatim
+void limits(picture pic=currentpicture, pair min, pair max, bool crop=NoCrop);
+@end verbatim
+can be used to limit the axes to the box having opposite vertices at
+the given pairs). Existing objects in picture @code{pic} will be cropped to lie
+within the given limits if @code{crop}=@code{Crop}. The function
+@code{crop(picture pic)} can be used to crop a graph to the current
+graph limits.
+@verbatiminclude parametricgraph.asy
+@sp 1
+@center @image{parametricgraph}
+
+@cindex scaled graph
+The next example illustrates how one can extract a common axis scaling
+factor.
+@verbatiminclude scaledgraph.asy
+@sp 1
+@center @image{scaledgraph}
+
+@anchor{automatic scaling}
+@cindex @code{scale}
+@cindex @code{Linear}
+@cindex @code{Log}
+@cindex automatic scaling
+Axis scaling can be requested and/or automatic selection of the
+axis limits can be inhibited with one of these @code{scale} routines:
+@verbatim
+void scale(picture pic=currentpicture, scaleT x, scaleT y);
+
+void scale(picture pic=currentpicture, bool xautoscale=true,
+ bool yautoscale=xautoscale, bool zautoscale=yautoscale);
+@end verbatim
+
+This sets the scalings for picture @code{pic}. The @code{graph} routines
+accept an optional @code{picture} argument for determining the appropriate
+scalings to use; if none is given, it uses those set for
+@code{currentpicture}.
+
+Two frequently used scaling routines
+@code{Linear} and @code{Log} are predefined in @code{graph}.
+
+All picture coordinates (including those in paths and those given
+to the @code{label} and @code{limits} functions) are always treated as linear
+(post-scaled) coordinates. Use
+@cindex @code{Scale}
+@verbatim
+pair Scale(picture pic=currentpicture, pair z);
+@end verbatim
+to convert a graph coordinate into a scaled picture coordinate.
+
+The @math{x} and @math{y} components can be individually scaled using
+the analogous routines
+@verbatim
+real ScaleX(picture pic=currentpicture, real x);
+real ScaleY(picture pic=currentpicture, real y);
+@end verbatim
+
+The predefined scaling routines can be given two optional boolean arguments:
+@code{automin=false} and @code{automax=automin}. These default to
+@code{false} but can be respectively set to @code{true} to enable
+automatic selection of "nice" axis minimum and maximum values. The
+@code{Linear} scaling can also take as optional final arguments a
+multiplicative scaling factor and intercept (e.g.@ for a depth axis,
+@code{Linear(-1)} requests axis reversal).
+
+@cindex logarithmic graph
+@cindex log-log graph
+For example, to draw a log/log graph of a function, use @code{scale(Log,Log)}:
+@verbatiminclude loggraph.asy
+@sp 1
+@center @image{loggraph}
+
+@cindex grid
+By extending the ticks, one can easily produce a logarithmic grid:
+@verbatiminclude loggrid.asy
+
+@sp 1
+@center @image{loggrid}
+
+One can also specify custom tick locations and formats for logarithmic axes:
+@verbatiminclude logticks.asy
+@sp 1
+@center @image{logticks}
+
+@cindex @code{log2} graph
+It is easy to draw logarithmic graphs with respect to other bases:
+@verbatiminclude log2graph.asy
+@sp 1
+@center @image{log2graph}
+
+@cindex broken axis
+Here is an example of "broken" linear @math{x} and logarithmic
+@math{y} axes that omit the segments [3,8] and [100,1000], respectively.
+In the case of a logarithmic axis, the break endpoints are automatically
+rounded to the nearest integral power of the base.
+@verbatiminclude brokenaxis.asy
+@sp 1
+@center @image{brokenaxis}
+
+@cindex secondary axis
+@cindex @code{secondaryX}
+@cindex @code{secondaryY}
+@item @code{Asymptote} can draw secondary axes with the routines
+@verbatim
+picture secondaryX(picture primary=currentpicture, void f(picture));
+picture secondaryY(picture primary=currentpicture, void f(picture));
+@end verbatim
+
+In this example, @code{secondaryY} is used to draw a secondary linear
+@math{y} axis against a primary logarithmic @math{y} axis:
+@verbatiminclude Bode.asy
+@sp 1
+@center @image{Bode}
+
+A secondary logarithmic @math{y} axis can be drawn like this:
+@verbatiminclude secondaryaxis.asy
+@sp 1
+@center @image{secondaryaxis}
+
+@item Here is a histogram example, which uses the @code{stats} module.
+@cindex @code{axis}
+@verbatiminclude histogram.asy
+@sp 1
+@center @image{histogram}
+
+@item Here is an example of reading column data in from a file and a
+least-squares fit, using the @code{stats} module.
+@cindex @code{leastsquares}
+@verbatiminclude leastsquares.asy
+@sp 1
+@center @image{leastsquares}
+
+@item Here is an example that illustrates the general @code{axis} routine.
+@cindex @code{axis}
+@verbatiminclude generalaxis.asy
+@sp 1
+@center @image{generalaxis}
+
+@item To draw a vector field of @code{n} arrows evenly spaced along the arclength of a path, use the routine
+@cindex @code{vectorfield}
+@verbatim
+picture vectorfield(path vector(real), path g, int n, bool truesize=false,
+ pen p=currentpen, arrowbar arrow=Arrow);
+@end verbatim
+as illustrated in this simple example of a flow field:
+@verbatiminclude flow.asy
+@sp 1
+@center @image{flow}
+
+@item To draw a vector field of @code{nx}@math{\times}@code{ny} arrows in @code{box(a,b)}, use the routine
+@cindex @code{vectorfield}
+@verbatim
+picture vectorfield(path vector(pair), pair a, pair b,
+ int nx=nmesh, int ny=nx,
+ bool autoscale=true, bool truesize=false,
+ pen p=currentpen, arrowbar arrow=Arrow);
+@end verbatim
+as illustrated in this example:
+@verbatiminclude vectorfield.asy
+@sp 1
+@center @image{vectorfield}
+
+@item The following scientific graphs, which illustrate many features of
+@code{Asymptote}'s graphics routines, were generated from the examples
+@code{diatom.asy} and @code{westnile.asy}, using the comma-separated
+data in @code{diatom.csv} and @code{westnile.csv}.
+@page
+
+@sp 1
+@center @image{diatom}
+@sp 1
+@center @image{westnile,,7.5cm}
+@end enumerate
+
+@page
+@node palette
+@section @code{palette}
+@anchor{images}
+@code{Asymptote} can also generate color density images
+and palettes. The following palettes are predefined in
+@code{palette.asy}:
+
+@table @code
+
+@cindex @code{Grayscale}
+@item pen[] Grayscale(int NColors=256)
+a grayscale palette;
+
+@cindex @code{Rainbow}
+@item pen[] Rainbow(int NColors=32766)
+a rainbow spectrum;
+
+@cindex @code{BWRainbow}
+@item pen[] BWRainbow(int NColors=32761)
+a rainbow spectrum tapering off to black/white at the ends;
+
+@cindex @code{BWRainbow2}
+@item pen[] BWRainbow2(int NColors=32761)
+a double rainbow palette tapering off to black/white at the ends, with
+a linearly scaled intensity.
+
+@cindex @code{Wheel}
+@item pen[] Wheel(int NColors=32766)
+a full color wheel palette;
+
+@cindex @code{Gradient}
+@item pen[] Gradient(int NColors=256 ... pen[] p)
+a palette varying linearly over the specified array of pens, using
+NColors in each interpolation interval;
+
+@end table
+
+The function @code{cmyk(pen[] Palette)} may be used to convert any
+of these palettes to the @acronym{CMYK} colorspace.
+
+A color density plot using palette @code{palette} can be generated from
+a function @code{f}(@math{x},@math{y}) and added to a picture @code{pic}:
+@cindex @code{image}
+@verbatim
+bounds image(picture pic=currentpicture, real f(real,real),
+ range range=Full, pair initial, pair final,
+ int nx=ngraph, int ny=nx, pen[] palette, bool antialias=false)
+@end verbatim
+The function @code{f} will be sampled at @code{nx} and @code{ny}
+evenly spaced points over a rectangle defined by the points
+@code{initial} and @code{final}, respecting the current graphical
+scaling of @code{pic}. The color space is scaled according to the
+@math{z} axis scaling (@pxref{automatic scaling}). A bounds structure
+for the function values is returned:
+@verbatim
+struct bounds {
+ real min;
+ real max;
+ // Possible tick intervals:
+ int[] divisor;
+}
+@end verbatim
+@noindent
+This information can be used for generating an optional palette bar.
+The palette color space corresponds to a range of values specified by
+the argument @code{range}, which can be @code{Full}, @code{Automatic},
+or an explicit range @code{Range(real min, real max)}.
+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{imagecontour.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[][]
+array @code{data}:
+@cindex @code{image}
+@verbatim
+bounds image(picture pic=currentpicture, real[][] f, range range=Full,
+ pair initial, pair final, pen[] palette,
+ bool transpose=(initial.x < final.x && initial.y < final.y),
+ bool copy=true, bool antialias=false);
+@end verbatim
+@noindent
+If the initial point is to the left and below the final point,
+by default the array indices are interpreted according to the
+Cartesian convention (first index: @math{x}, second index: @math{y})
+rather than the usual matrix convention (first index: @math{-y},
+second index: @math{x}).
+
+To construct an image from an array of irregularly spaced points
+and an array of values @code{f} at these points, use one of the routines
+@verbatim
+bounds image(picture pic=currentpicture, pair[] z, real[] f,
+ range range=Full, pen[] palette)
+bounds image(picture pic=currentpicture, real[] x, real[] y, real[] f,
+ range range=Full, pen[] palette)
+@end verbatim
+
+An optionally labelled palette bar may be generated with the routine
+@verbatim
+void palette(picture pic=currentpicture, Label L="", bounds bounds,
+ pair initial, pair final, axis axis=Right, pen[] palette,
+ pen p=currentpen, paletteticks ticks=PaletteTicks,
+ bool copy=true, bool antialias=false);
+@end verbatim
+The color space of @code{palette} is taken to be over bounds @code{bounds} with
+scaling given by the @math{z} scaling of @code{pic}.
+The palette orientation is specified by @code{axis}, which may be one of
+@code{Right}, @code{Left}, @code{Top}, or @code{Bottom}.
+The bar is drawn over the rectangle from @code{initial} to @code{final}.
+The argument @code{paletteticks} is a special tick type (@pxref{ticks})
+that takes the following arguments:
+@verbatim
+paletteticks PaletteTicks(Label format="", ticklabel ticklabel=null,
+ bool beginlabel=true, bool endlabel=true,
+ int N=0, int n=0, real Step=0, real step=0,
+ pen pTick=nullpen, pen ptick=nullpen);
+@end verbatim
+
+The image and palette bar can be fit to a frame and added and
+optionally aligned to a picture at the desired location:
+
+@anchor{image}
+@verbatiminclude image.asy
+@sp 1
+@center @image{image}
+
+Here is an example that uses logarithmic scaling of the function values:
+
+@anchor{logimage}
+@verbatiminclude logimage.asy
+@sp 1
+@center @image{logimage}
+
+One can also draw an image directly from a two-dimensional pen array:
+@verbatim
+void image(picture pic=currentpicture, pen[][] data,
+ pair initial, pair final,
+ bool transpose=(initial.x < final.x && initial.y < final.y),
+ bool copy=true, bool antialias=false);
+@end verbatim
+@noindent
+as illustrated in the following example:
+
+@anchor{penimage}
+@verbatiminclude penimage.asy
+@sp 1
+@center @image{penimage}
+
+For convenience, the module @code{palette} also defines functions
+that may be used to construct a pen array from a given function and palette:
+@verbatim
+pen[] palette(real[] f, pen[] palette);
+pen[][] palette(real[][] f, pen[] palette);
+@end verbatim
+
+@node three
+@section @code{three}
+@cindex @code{three}
+@cindex @code{guide3}
+@cindex @code{path3}
+@cindex @code{cycle}
+@cindex @code{curl}
+@cindex @code{tension}
+@cindex @code{controls}
+This module fully extends the notion of guides and paths in @code{Asymptote}
+to three dimensions. It introduces the new types guide3, path3, and surface.
+Guides in three dimensions are specified with the same syntax as in two
+dimensions except that triples @code{(x,y,z)} are used in place of pairs
+@code{(x,y)} for the nodes and direction specifiers. This
+generalization of John Hobby's spline algorithm is shape-invariant under
+three-dimensional rotation, scaling, and shifting, and reduces in the
+planar case to the two-dimensional algorithm used in @code{Asymptote},
+@code{MetaPost}, and @code{MetaFont} [cf.@ J. C. Bowman, Proceedings in
+Applied Mathematics and Mechanics, 7:1, 2010021-2010022 (2007)].
+
+For example, a unit circle in the @math{XY} plane may be filled and
+drawn like this:
+@verbatiminclude unitcircle3.asy
+@sp 1
+@center @image{unitcircle3}
+@noindent
+and then distorted into a saddle:
+@verbatiminclude saddle.asy
+@sp 1
+@center @image{saddle}
+@noindent
+
+Module @code{three} provides constructors for converting two-dimensional
+paths to three-dimensional ones, and vice-versa:
+@cindex @code{path3}
+@cindex @code{path}
+@verbatim
+path3 path3(path p, triple plane(pair)=XYplane);
+path path(path3 p, pair P(triple)=xypart);
+@end verbatim
+
+@cindex @code{surface}
+A Bezier surface, the natural two-dimensional generalization of Bezier
+curves, is defined in @code{three_surface.asy} as a structure
+containing an array of Bezier patches. Surfaces may drawn with one of
+the routines
+@verbatim
+void draw(picture pic=currentpicture, surface s, int nu=1, int nv=1,
+ material surfacepen=currentpen, pen meshpen=nullpen,
+ light light=currentlight, light meshlight=light);
+void draw(picture pic=currentpicture, surface s, int nu=1, int nv=1,
+ material[] surfacepen, pen meshpen,
+ light light=currentlight, light meshlight=light);
+void draw(picture pic=currentpicture, surface s, int nu=1, int nv=1,
+ material[] surfacepen, pen[] meshpen=nullpens,
+ light light=currentlight, light meshlight=light);
+@end verbatim
+The parameters @code{nu} and @code{nv} specify the number of subdivisions
+for drawing optional mesh lines for each Bezier patch.
+Here material is a structure defined in @code{three_light.asy}:
+@verbatim
+struct material {
+ pen[] p; // diffusepen,ambientpen,emissivepen,specularpen
+ real opacity;
+ real shininess;
+ real granularity;
+...
+}
+@end verbatim
+@noindent
+These material properties are used to implement @code{OpenGL}-style lighting,
+based on the Phong-Blinn specular model. Sample Bezier surfaces are
+contained in the example files @code{BezierSurface.asy}, @code{teapot.asy},
+and @code{parametricsurface.asy}.
+
+@cindex patch-dependent colors
+@cindex vertex-dependent colors
+The examples
+@code{elevation.asy} and @code{sphericalharmonic.asy}
+illustrate how to draw a surface with patch-dependent colors.
+The examples @code{vertexshading} and @code{smoothelevation} illustrate
+vertex-dependent colors, which is supported for both
+@code{Asymptote}'s native @code{OpenGL} renderer and two-dimensional
+projections. Since the @acronym{PRC} output format does not currently support
+vertex shading of Bezier surfaces, @acronym{PRC} patches are shaded
+with the mean of the four vertex colors.
+
+@cindex @code{surface}
+@cindex @code{planar}
+A surface can be constructed from a cyclic @code{path3} with the constructor
+@verbatim
+surface surface(path3 external, triple[] internal=new triple[],
+ triple[] normals=new triple[], pen[] colors=new pen[],
+ bool3 planar=default);
+@end verbatim
+@noindent
+and then filled:
+@verbatim
+draw(surface(path3(polygon(5))),red);
+draw(surface(unitcircle3),red);
+draw(surface(unitcircle3,new pen[] {red,green,blue,black}));
+@end verbatim
+@noindent
+The last example constructs a patch with vertex-specific colors.
+A three-dimensional planar surface in the plane @code{plane} can be
+constructed from a two-dimensional cyclic path @code{g} with the constructor
+@cindex @code{surface}
+@verbatim
+surface surface(path p, triple plane(pair)=XYplane);
+@end verbatim
+@noindent
+and then filled:
+@verbatim
+draw(surface((0,0)--E+2N--2E--E+N..0.2E..cycle),red);
+@end verbatim
+@noindent
+@cindex @code{bezulate}
+Planar Bezier surfaces patches are constructed using Orest Shardt's
+@code{bezulate} routine, which decomposes (possibly nonsimply
+connected) regions bounded by nonselfintersecting cyclic paths
+(according to the @code{zerowinding} fill rule) into subregions
+bounded by cyclic paths of length @code{4} or less.
+
+@cindex @code{thin}
+@cindex @code{thick}
+@cindex @code{tube}
+Arbitrary thick three-dimensional curves and line caps (which the
+@code{OpenGL} standard does not require implementations to provide) are
+constructed with the routine
+@verbatim
+surface tube(path3 g, real width);
+@end verbatim
+@noindent
+which returns a tube of diameter @code{width} centered on @code{g}.
+This can make files slow to render,
+especially with the @code{Adobe Reader} renderer. The setting
+@code{thick=false} can be used to disable this feature and force all
+lines to be drawn with @code{linewidth(0)} (one pixel wide, regardless
+of the resolution). By default mesh and contour lines in three-dimensions
+are always drawn thin, unless an explicit line width is given in the pen
+parameter or the setting @code{thin} is set to @code{false}. The pens
+@code{thin()} and @code{thick()} defined in plain_pens.asy can also be used
+to override these defaults for specific draw commands.
+
+@noindent
+There are four choices for viewing 3D @code{Asymptote} output:
+@enumerate
+@cindex @code{OpenGL}
+@cindex @code{render}
+@cindex @code{outformat}
+@cindex @code{multisample}
+@item Use the native @code{Asymptote} adaptive @code{OpenGL}-based
+renderer (with the command-line option @code{-V} and the default settings
+@code{outformat=""} and @code{render=-1}). If you encounter warnings
+from your graphics card driver, try specifying @code{-glOptions=-indirect}
+on the command line. On @code{UNIX} systems with graphics support for
+multisampling, we recommend installing the latest SVN (antialiased)
+version of the @code{freeglut} library
+(@pxref{multisampling}); the sample width can be
+controlled with the setting @code{multisample}. An initial screen
+position can be specified with the pair setting @code{position}, where
+negative values are interpreted as relative to the corresponding
+maximum screen dimension. The mouse bindings are:
+@cindex mouse bindings
+@itemize
+@item Left: rotate
+@item shift Left: zoom
+@item ctrl Left: shift
+@item Middle: menu
+@item Wheel: zoom
+@item Right: zoom
+@item Right double click: menu
+@item shift Right: rotate about the X axis
+@item ctrl Right: rotate about the Y axis
+@item alt Right: rotate about the Z axis
+@end itemize
+The keyboard shortcuts are:
+@cindex keyboard bindings:
+@itemize
+@item h: home
+@item f: toggle fitscreen
+@item x: spin about the X axis
+@item y: spin about the Y axis
+@item z: spin about the Z axis
+@item s: stop spinning
+@item m: rendering mode (solid/mesh/patch)
+@item e: export
+@item c: show camera parameters
+@item +: expand
+@item =: expand
+@item -: shrink
+@item _: shrink
+@item q: exit
+@item Ctrl-q: exit
+@end itemize
+
+@cindex @code{antialias}
+@cindex @code{maxviewport}
+@cindex @code{maxtile}
+@cindex @code{glOptions}
+@cindex @code{iconic}
+@item Render the scene to a specified rasterized format @code{outformat}
+at the resolution of @code{n} pixels per @code{bp}, as specified by the
+setting @code{render=n}. A negative value of @code{n} is interpreted
+as @code{|2n|} for @acronym{EPS} and @acronym{PDF} formats and
+@code{|n|} for other formats. The default value of @code{render} is -1.
+By default, the scene is internally rendered at twice the specified
+resolution; this can be disabled by setting @code{antialias=1}.
+High resolution rendering is done by tiling the image. If your
+graphics card allows it, the rendering can be made more efficient by
+increasing the maximum tile size @code{maxtile} beyond the screen
+dimensions (indicated by @code{maxtile=(0,0)}. The tile size is also
+limited by the setting @code{maxviewport}, which restricts the maximum
+width and height of the viewport. On @code{UNIX} systems some graphics
+drivers support batch mode (@code{-noV}) rendering in an
+iconified window; this can be enabled with the setting @code{iconify=true}.
+Other @code{UNIX} graphics drivers may require the command line setting
+@code{-glOptions=-indirect}.
+
+@cindex @code{prc}
+@cindex @code{views}
+@item Embed the 3D @acronym{PRC} format in a @acronym{PDF} file
+and view the resulting @acronym{PDF} file with
+version @code{8.0} or later of @code{Adobe Reader}.
+In addition to the default @code{settings.prc=true}, this requires
+@code{settings.outformat="pdf"}, which can be specified by the command
+line option @code{-f pdf}, put in the @code{Asymptote} configuration
+file (@pxref{configuration file}), or specified in the script before
+@code{three.asy} (or @code{graph3.asy}) is imported.
+Version 2008/10/08 or later of the @code{movie15} package is also
+required (@pxref{embed}). The example @code{pdb.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
+the file to be viewed with other @code{PDF} viewers. Alternatively, the
+file @code{externalprc.tex} illustrates how the resulting @acronym{PRC} and
+rendered image files can be extracted and processed in a separate
+@code{LaTeX} file. However, see @ref{LaTeX usage} for an easier way
+to embed three-dimensional @code{Asymptote} pictures within @code{LaTeX}.
+The open-source @acronym{PRC} specification is available from
+@url{http://livedocs.adobe.com/acrobat_sdk/9/Acrobat9_HTMLHelp/API_References/PRCReference/PRC_Format_Specification/}.
+
+@item Project the scene to a two-dimensional vector (@acronym{EPS} or
+@acronym{PDF}) format with @code{render=0}. Only limited hidden surface
+removal facilities are currently available with this approach
+(@pxref{PostScript3D}).
+
+@end enumerate
+
+@cindex @code{double deferred drawing}
+Automatic picture sizing in three dimensions is accomplished with double
+deferred drawing. The maximal desired dimensions of the scene in each of
+the three dimensions can optionally be specified with the routine
+@cindex @code{size3}
+@verbatim
+void size3(picture pic=currentpicture, real x, real y=x, real z=y,
+ bool keepAspect=pic.keepAspect);
+@end verbatim
+@noindent
+@cindex margins
+@cindex @code{viewportmargin}
+@cindex @code{viewportsize}
+The resulting simplex linear programming problem is then solved to
+produce a 3D version of a frame (actually implemented as a 3D picture).
+The result is then fit with another application of deferred drawing
+to the viewport dimensions corresponding to the usual two-dimensional
+picture @code{size} parameters. The global pair @code{viewportmargin}
+may be used to add horizontal and vertical margins to the viewport
+dimensions. Alternatively, a minimum @code{viewportsize} may be specified.
+
+@cindex @code{O}
+@cindex @code{X}
+@cindex @code{Y}
+@cindex @code{Z}
+@cindex @code{unitcircle}
+For convenience, the @code{three} module defines @code{O=(0,0,0)},
+@code{X=(1,0,0)}, @code{Y=(0,1,0)}, and @code{Z=(0,0,1)}, along with a
+unitcircle in the XY plane:
+@verbatim
+path3 unitcircle3=X..Y..-X..-Y..cycle;
+@end verbatim
+
+@cindex @code{circle}
+A general (approximate) circle can be drawn perpendicular to the direction
+@code{normal} with the routine
+@verbatim
+path3 circle(triple c, real r, triple normal=Z);
+@end verbatim
+
+@cindex @code{arc}
+A circular arc centered at @code{c} with radius @code{r} from
+@code{c+r*dir(theta1,phi1)} to @code{c+r*dir(theta2,phi2)},
+drawing counterclockwise relative to the normal vector
+@code{cross(dir(theta1,phi1),dir(theta2,phi2))} if @code{theta2 > theta1}
+or if @code{theta2 == theta1} and @code{phi2 >= phi1}, can be constructed with
+@verbatim
+path3 arc(triple c, real r, real theta1, real phi1, real theta2, real phi2,
+ triple normal=O);
+@end verbatim
+The normal must be explicitly specified if @code{c} and the endpoints
+are colinear. If @code{r} < 0, the complementary arc of radius
+@code{|r|} is constructed.
+For convenience, an arc centered at @code{c} from triple @code{v1} to
+@code{v2} (assuming @code{|v2-c|=|v1-c|}) in the direction CCW
+(counter-clockwise) or CW (clockwise) may also be constructed with
+@verbatim
+path3 arc(triple c, triple v1, triple v2, triple normal=O,
+ bool direction=CCW);
+@end verbatim
+@noindent
+When high accuracy is needed, the routines @code{Circle} and
+@code{Arc} defined in @code{graph3} may be used instead.
+See @ref{GaussianSurface} for an example of a three-dimensional circular arc.
+
+@cindex @code{plane}
+The representation @code{O--O+u--O+u+v--O+v--cycle}
+of the plane passing through point @code{O} with normal
+@code{cross(u,v)} is returned by
+@verbatim
+path3 plane(triple u, triple v, triple O=O);
+@end verbatim
+A three-dimensional box with opposite vertices at triples @code{v1}
+and @code{v2} may be drawn with the function
+@cindex @code{box}
+@verbatim
+path3[] box(triple v1, triple v2);
+@end verbatim
+@noindent
+For example, a unit box is predefined as
+@cindex @code{box}
+@cindex @code{unitbox}
+@verbatim
+path3[] unitbox=box(O,(1,1,1));
+@end verbatim
+@code{Asymptote} also provides optimized definitions for the
+three-dimensional paths @code{unitsquare3} and @code{unitcircle3},
+along with the surfaces @code{unitdisk}, @code{unitplane}, @code{unitcube},
+@code{unitcylinder}, @code{unitcone}, @code{unitsolidcone},
+@code{unitfrustum(real t1, real t2)}, @code{unitsphere}, and
+@code{unithemisphere}.
+
+@noindent
+These projections to two dimensions are predefined:
+@table @code
+@item oblique
+@item oblique(real angle);
+@cindex @code{oblique}
+@cindex @code{obliqueZ}
+The point @code{(x,y,z)} is projected to @code{(x-0.5z,y-0.5z)}.
+If an optional real argument is given, the
+negative @math{z} axis is drawn at this angle in degrees.
+The projection @code{obliqueZ} is a synonym for @code{oblique}.
+
+@item obliqueX
+@item obliqueX(real angle)
+@cindex @code{obliqueX}
+The point @code{(x,y,z)} is projected to @code{(y-0.5x,z-0.5x)}.
+If an optional real argument is given, the
+negative @math{x} axis is drawn at this angle in degrees.
+
+@item obliqueY
+@item obliqueY(real angle)
+@cindex @code{obliqueY}
+The point @code{(x,y,z)} is projected to @code{(x+0.5y,z+0.5y)}.
+If an optional real argument is given, the
+positive @math{y} axis is drawn at this angle in degrees.
+
+@cindex @code{orthographic}
+@cindex @code{up}
+@cindex @code{target}
+@cindex @code{showtarget}
+@cindex @code{autoadjust}
+@cindex @code{center}
+@item orthographic(triple camera, triple up=Z, triple target=O, @*@ @ @ @ @ @ @ @ @ @ @ @ @ bool showtarget=true, bool autoadjust=true, bool center=false)
+This projects from three to two dimensions using the view as seen at a point
+infinitely far away in the direction @code{unit(camera)}, orienting the camera
+so that, if possible, the vector @code{up} points upwards. Parallel
+lines are projected to parallel lines. The bounding volume is expanded
+to include @code{target} if @code{showtarget=true}. If @code{autoadjust=true},
+the camera will automatically be adjusted to lie outside the bounding volume
+for all possible interactive rotations about @code{target}.
+If @code{center=true}, the target will be adjusted to the center of the
+bounding volume.
+
+@item orthographic(real x, real y, real z, triple up=Z, triple target=O, @*@ @ @ @ @ @ @ @ @ @ @ @ @ bool showtarget=true, bool autoadjust=true, bool center=false)
+This is equivalent to
+@code{orthographic((x,y,z),up,target,showtarget,autoadjust,
+center)}.
+
+@item perspective(triple camera, triple up=Z, triple target=O, @*@ @ @ @ @ @ @ @ @ @ @ @ bool showtarget=true, bool autoadjust=true, bool center=false)
+@cindex @code{perspective}
+@cindex @code{NURBS}
+This projects from three to two dimensions, taking account of
+perspective, as seen from the location @code{camera} looking at @code{target},
+orienting the camera so that, if possible, the vector @code{up} points upwards.
+If @code{render=0}, projection of three-dimensional cubic Bezier splines
+is implemented by approximating a two-dimensional nonuniform rational B-spline
+(@acronym{NURBS}) with a two-dimensional Bezier curve containing
+additional nodes and control points. If @code{autoadjust=true},
+the camera will automatically be adjusted to lie outside the bounding volume
+for all possible interactive rotations about @code{target}.
+If @code{center=true}, the target will be adjusted to the center of the
+bounding volume.
+
+@item perspective(real x, real y, real z, triple up=Z, triple target=O, @*@ @ @ @ @ @ @ @ @ @ @ @ bool showtarget=true, bool autoadjust=true, bool center=false)
+This is equivalent to @code{perspective((x,y,z),up,target,showtarget,
+autoadjust,center)}.
+@end table
+
+@cindex @code{currentprojection}
+@noindent
+The default projection, @code{currentprojection}, is initially set to
+@code{perspective(5,4,2)}.
+
+A triple or path3 can be projected to a pair or path,
+with @code{project(triple, projection P=currentprojection)} or
+@code{project(path3, projection P=currentprojection)}.
+
+It is occasionally useful to be able to invert a projection, sending
+a pair @code{z} onto the plane perpendicular to @code{normal} and passing
+through @code{point}:
+@cindex @code{invert}
+@verbatim
+triple invert(pair z, triple normal, triple point,
+ projection P=currentprojection);
+@end verbatim
+@noindent
+A pair @code{z} on the projection plane can be inverted to a triple
+with the routine
+@verbatim
+triple invert(pair z, projection P=currentprojection);
+@end verbatim
+@noindent
+A pair direction @code{dir} on the projection plane can be inverted to
+a triple direction relative to a point @code{v} with the routine
+@verbatim
+triple invert(pair dir, triple v, projection P=currentprojection).
+@end verbatim
+
+@cindex @code{transform3}
+Three-dimensional objects may be transformed with one of the following
+built-in transform3 types:
+
+@table @code
+@item shift(triple v)
+@cindex @code{shift}
+translates by the triple @code{v};
+@item xscale3(real x)
+@cindex @code{xscale3}
+scales by @code{x} in the @math{x} direction;
+@item yscale3(real y)
+@cindex @code{yscale3}
+scales by @code{y} in the @math{y} direction;
+@item zscale3(real z)
+@cindex @code{zscale3}
+scales by @code{z} in the @math{z} direction;
+@item scale3(real s)
+@cindex @code{scale3}
+scales by @code{s} in the @math{x}, @math{y}, and @math{z} directions;
+@item scale(real x, real y, real z)
+@cindex @code{scale}
+scales by @code{x} in the @math{x} direction,
+by @code{y} in the @math{y} direction, and by @code{z} in the @math{z}
+direction;
+@item rotate(real angle, triple v)
+rotates by @code{angle} in degrees about an axis @code{v} through the origin;
+@item rotate(real angle, triple u, triple v)
+rotates by @code{angle} in degrees about the axis @code{u--v};
+@item reflect(triple u, triple v, triple w)
+reflects about the plane through @code{u}, @code{v}, and @code{w}.
+@end table
+
+@cindex @code{transform}
+Three-dimensional @TeX{} Labels, which are by default drawn as
+Bezier surfaces directly on the projection plane, can be transformed
+from the @code{XY} plane by any of the above transforms or mapped to a
+specified two-dimensional plane with the transform3 types @code{XY},
+@code{YZ}, @code{ZX}, @code{YX}, @code{ZY}, @code{ZX}. There are also
+modified versions of these transforms that take an optional argument
+@code{projection P=currentprojection} that rotate and/or flip the
+label so that it is more readable from the initial viewpoint.
+
+@cindex @code{planeproject}
+A transform3 that projects in the direction @code{dir} onto the plane
+with normal @code{n} through point @code{O} is returned by
+@verbatim
+transform3 planeproject(triple n, triple O=O, triple dir=n);
+@end verbatim
+@noindent
+One can use
+@cindex @code{normal}
+@verbatim
+triple normal(path3 p);
+@end verbatim
+@noindent
+to find the unit normal vector to a planar three-dimensional path @code{p}.
+As illustrated in the example @code{planeproject.asy}, a transform3
+that projects in the direction @code{dir} onto the plane defined by a
+planar path @code{p} is returned by
+@verbatim
+transform3 planeproject(path3 p, triple dir=normal(p));
+@end verbatim
+
+The functions
+@cindex @code{extrude}
+@verbatim
+surface extrude(path p, triple axis=Z);
+surface extrude(Label L, triple axis=Z);
+@end verbatim
+@noindent
+return the surface obtained by extruding path @code{p} or
+Label @code{L} along @code{axis}.
+
+@cindex @code{length}
+@cindex @code{size}
+@cindex @code{point}
+@cindex @code{dir}
+@cindex @code{accel}
+@cindex @code{radius}
+@cindex @code{precontrol}
+@cindex @code{postcontrol}
+@cindex @code{arclength}
+@cindex @code{arctime}
+@cindex @code{reverse}
+@cindex @code{subpath}
+@cindex @code{intersect}
+@cindex @code{intersections}
+@cindex @code{intersectionpoint}
+@cindex @code{intersectionpoints}
+@cindex @code{min}
+@cindex @code{max}
+@cindex @code{cyclic}
+@cindex @code{straight}
+Three-dimensional versions of the path functions @code{length},
+@code{size}, @code{point}, @code{dir}, @code{accel}, @code{radius},
+@code{precontrol}, @code{postcontrol},
+@code{arclength}, @code{arctime}, @code{reverse}, @code{subpath},
+@code{intersect}, @code{intersections}, @code{intersectionpoint},
+@code{intersectionpoints}, @code{min}, @code{max}, @code{cyclic}, and
+@code{straight} are also defined.
+
+Here is an example showing all five guide3 connectors:
+@verbatiminclude join3.asy
+@sp 1
+@center @image{join3}
+
+@cindex @code{BeginBar3}
+@cindex @code{EndBar3}
+@cindex @code{Bar3}
+@cindex @code{Bars3}
+@cindex @code{BeginArrow3}
+@cindex @code{MidArrow3}
+@cindex @code{EndArrow3}
+@cindex @code{Arrow3}
+@cindex @code{Arrows3}
+@cindex @code{BeginArcArrow3}
+@cindex @code{MidArcArrow3}
+@cindex @code{EndArcArrow3}
+@cindex @code{ArcArrow3}
+@cindex @code{ArcArrows3}
+@cindex @code{DefaultHead3}
+@cindex @code{HookHead3}
+@cindex @code{TeXHead3}
+Three-dimensional versions of bars or arrows can be drawn with one of
+the specifiers @code{None}, @code{Blank},
+@code{BeginBar3}, @code{EndBar3} (or equivalently @code{Bar3}), @code{Bars3},
+@code{BeginArrow3}, @code{MidArrow3},
+@code{EndArrow3} (or equivalently @code{Arrow3}), @code{Arrows3},
+@code{BeginArcArrow3}, @code{EndArcArrow3} (or equivalently
+@code{ArcArrow3}), @code{MidArcArrow3}, and @code{ArcArrows3}.
+Three-dimensional bars accept the optional arguments @code{(real size=0,
+triple dir=O)}. If @code{size=O}, the default bar length is used; if
+@code{dir=O}, the bar is drawn perpendicular to the path
+and the initial viewing direction. The predefined three-dimensional
+arrowhead styles are @code{DefaultHead3}, @code{HookHead3}, @code{TeXHead3}.
+Versions of the two-dimensional arrowheads lifted to three-dimensional
+space and aligned according to the initial viewpoint (or an optionally
+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
+@code{arrows3.asy}.
+
+@cindex @code{NoMargin3}
+@cindex @code{BeginMargin3}
+@cindex @code{EndMargin3}
+@cindex @code{Margin3}
+@cindex @code{Margins3}
+@cindex @code{BeginPenMargin2}
+@cindex @code{EndPenMargin2}
+@cindex @code{PenMargin2}
+@cindex @code{PenMargins2}
+@cindex @code{BeginPenMargin3}
+@cindex @code{EndPenMargin3}
+@cindex @code{PenMargin3}
+@cindex @code{PenMargins3}
+@cindex @code{BeginDotMargin3}
+@cindex @code{EndDotMargin3}
+@cindex @code{DotMargin3}
+@cindex @code{DotMargins3}
+@cindex @code{Margin3}
+@cindex @code{TrueMargin3}
+Module @code{three} also defines the three-dimensional margins
+@code{NoMargin3}, @code{BeginMargin3}, @code{EndMargin3},
+@code{Margin3}, @code{Margins3},
+@code{BeginPenMargin2}, @code{EndPenMargin2}, @code{PenMargin2},
+@code{PenMargins2},
+@code{BeginPenMargin3}, @code{EndPenMargin3}, @code{PenMargin3},
+@code{PenMargins3},
+@code{BeginDotMargin3}, @code{EndDotMargin3}, @code{DotMargin3},
+@code{DotMargins3}, @code{Margin3}, and @code{TrueMargin3}.
+
+Further three-dimensional examples are provided in the files
+@code{near_earth.asy}, @code{conicurv.asy}, and (in the @code{animations}
+subdirectory) @code{cube.asy}.
+
+@anchor{PostScript3D}
+Limited support for projected vector graphics (effectively three-dimensional
+nonrendered @code{PostScript}) is available with the setting
+@code{render=0}. This currently only works for piecewise planar
+surfaces, such as those produced by the parametric @code{surface}
+routines in the @code{graph3} module. Surfaces produced by the
+@code{solids} package will also be properly rendered if the parameter
+@code{nslices} is sufficiently large.
+
+@cindex hidden surface removal
+@cindex @code{face}
+In the module @code{bsp}, hidden surface removal of planar pictures is
+implemented using a binary space partition and picture clipping.
+A planar path is first converted to a structure @code{face} derived from
+@code{picture}. A @code{face} may be given to a two-dimensional drawing
+routine in place of any @code{picture} argument. An array of such faces
+may then be drawn, removing hidden surfaces:
+@verbatim
+void add(picture pic=currentpicture, face[] faces,
+ projection P=currentprojection);
+@end verbatim
+Labels may be projected to two dimensions, using projection @code{P},
+onto the plane passing through point @code{O} with normal
+@code{cross(u,v)} by multiplying it on the left by the transform
+@verbatim
+transform transform(triple u, triple v, triple O=O,
+ projection P=currentprojection);
+@end verbatim
+
+Here is an example that shows how a binary space partition may be used to draw a
+two-dimensional vector graphics projection of three orthogonal
+intersecting planes:
+@verbatiminclude planes.asy
+@sp 1
+@center @image{planes}
+
+@node obj
+@section @code{obj}
+@cindex @code{obj}
+This module allows one to construct surfaces from simple obj files,
+as illustrated in the example files @code{galleon.asy} and
+@code{triceratops.asy}.
+
+@node graph3
+@section @code{graph3}
+@cindex @code{graph3}
+@cindex 3D graphs
+This module implements three-dimensional versions of the
+functions in @code{graph.asy}.
+@cindex @code{xaxis}
+@cindex @code{yaxis}
+@cindex @code{zaxis}
+@noindent
+To draw an @math{x} axis in three dimensions, use the routine
+@verbatim
+void xaxis3(picture pic=currentpicture, Label L="", axis axis=YZZero,
+ real xmin=-infinity, real xmax=infinity, pen p=currentpen,
+ ticks3 ticks=NoTicks3, arrowbar3 arrow=None, bool above=false);
+@end verbatim
+@noindent
+Analogous routines @code{yaxis} and @code{zaxis} can be used to draw
+@math{y} and @math{z} axes in three dimensions.
+There is also a routine for drawing all three axis:
+@verbatim
+void axes3(picture pic=currentpicture,
+ Label xlabel="", Label ylabel="", Label zlabel="",
+ triple min=(-infinity,-infinity,-infinity),
+ triple max=(infinity,infinity,infinity),
+ pen p=currentpen, arrowbar3 arrow=None);
+@end verbatim
+
+@cindex @code{YZEquals}
+@cindex @code{XZEquals}
+@cindex @code{XYEquals}
+@cindex @code{YZZero}
+@cindex @code{XZZero}
+@cindex @code{XYZero}
+@cindex @code{Bounds}
+@noindent
+The predefined three-dimensional axis types are
+@verbatim
+axis YZEquals(real y, real z, triple align=O, bool extend=false);
+axis XZEquals(real x, real z, triple align=O, bool extend=false);
+axis XYEquals(real x, real y, triple align=O, bool extend=false);
+axis YZZero(triple align=O, bool extend=false);
+axis XZZero(triple align=O, bool extend=false);
+axis XYZero(triple align=O, bool extend=false);
+axis Bounds(int type=Both, int type2=Both, triple align=O, bool extend=false);
+@end verbatim
+@noindent
+The optional @code{align} parameter to these routines can be used to
+specify the default axis and tick label alignments. The @code{Bounds}
+axis accepts two type parameters, each of which must be one of
+@code{Min}, @code{Max}, or @code{Both}. These parameters specify which
+of the four possible three-dimensional bounding box edges should be drawn.
+
+@cindex @code{NoTicks3}
+@cindex @code{InTicks}
+@cindex @code{OutTicks}
+@cindex @code{InOutTicks}
+The three-dimensional tick options are @code{NoTicks3}, @code{InTicks},
+@code{OutTicks}, and @code{InOutTicks}. These specify the tick
+directions for the @code{Bounds} axis type; other axis types inherit
+the direction that would be used for the @code{Bounds(Min,Min)} axis.
+
+Here is an example of a helix and bounding box axes with ticks
+and axis labels, using orthographic projection:
+@verbatiminclude helix.asy
+@sp 1
+@center @image{helix}
+
+The next example illustrates three-dimensional @math{x}, @math{y}, and
+@math{z} axes, without autoscaling of the axis limits:
+@cindex @code{axis}
+@verbatiminclude axis3.asy
+@sp 1
+@center @image{axis3}
+
+One can also place ticks along a general three-dimensional axis:
+@cindex @code{axis}
+@verbatiminclude generalaxis3.asy
+@sp 1
+@center @image{generalaxis3}
+
+Surface plots of matrices and functions over the region
+@code{box(a,b)} in the @math{XY} plane are also implemented:
+@verbatim
+surface surface(real[][] f, pair a, pair b, bool[][] cond={});
+surface surface(real[][] f, pair a, pair b, splinetype splinetype,
+ bool[][] cond={});
+surface surface(real[][] f, real[] x, real[] y,
+ splinetype splinetype=null, bool[][] cond={})
+surface surface(triple[][] f, bool[][] cond={});
+surface surface(real f(pair z), pair a, pair b, int nx=nmesh, int ny=nx,
+ bool cond(pair z)=null);
+surface surface(real f(pair z), pair a, pair b, int nx=nmesh, int ny=nx,
+ splinetype splinetype, bool cond(pair z)=null);
+surface surface(triple f(pair z), pair a, pair b, int nu=nmesh, int nv=nu,
+ bool cond(pair z)=null);
+@end verbatim
+@noindent
+The final version draws a parametric surface for a function
+@math{f(u,v)} over the parameter space @code{box(a,b)},
+as illustrated in the example @code{parametricsurface.asy}.
+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
+@code{parametricsurface.asy} and @code{sinc.asy}.
+Lighting can be disabled by setting @code{light=nolight}, as in this example
+of a Gaussian surface:
+@anchor{GaussianSurface}
+@verbatiminclude GaussianSurface.asy
+@sp 1
+@center @image{GaussianSurface}
+@noindent
+A mesh can be drawn without surface filling by specifying @code{nullpen}
+for the surfacepen.
+
+@node grid3
+@section @code{grid3}
+@cindex @code{grid3}
+@cindex 3D grids
+
+This module, contributed by Philippe Ivaldi, can be used for drawing
+3D grids. Here is an example (further examples can be found in
+@code{grid3.asy} and at @url{http://piprim.tuxfamily.org/asymptote/grid3/}):
+@verbatiminclude grid3xyz.asy
+@sp 1
+@center @image{grid3xyz}
+
+@node solids
+@section @code{solids}
+@cindex @code{solids}
+This solid geometry package defines a structure @code{revolution} that
+can be used to fill and draw surfaces of revolution. The following example
+uses it to display the outline of a circular cylinder of radius 1
+with axis @code{O--1.5unit(Y+Z)} with perspective projection:
+@verbatiminclude cylinderskeleton.asy
+@sp 1
+@center @image{cylinderskeleton}
+
+Further illustrations are provided in the example files @code{cylinder.asy},
+@code{cones.asy}, @code{hyperboloid.asy}, and @code{torus.asy}.
+
+The structure @code{skeleton} contains the three-dimensional wireframe
+used to visualize a volume of revolution:
+@verbatim
+struct skeleton {
+ struct curve {
+ path3[] front;
+ path3[] back;
+ }
+ // transverse skeleton (perpendicular to axis of revolution)
+ curve transverse;
+ // longitudinal skeleton (parallel to axis of revolution)
+ curve longitudinal;
+}
+@end verbatim
+
+@node tube
+@section @code{tube}
+@cindex @code{tube}
+This package extends the routine @code{tube} defined in @code{three_arrows.asy}
+to arbitrary cross sections, colors, and spine transformations.
+The routine
+@verbatim
+surface tube(path3 g, coloredpath section,
+ transform T(real)=new transform(real t) {return identity();},
+ real corner=1, real relstep=0);
+@end verbatim
+@noindent
+draws a tube along @code{g} with cross section @code{section}, after
+applying the transformation @code{T(t)} at @code{relpoint(g,t)}.
+The parameter @code{corner} controls the number of elementary tubes at
+the angular points of @code{g}. A nonzero value of @code{relstep}
+specifies a fixed relative time step (in the sense of
+@code{relpoint(g,t)}) to use in constructing elementary tubes along @code{g}.
+The type @code{coloredpath} is a generalization of @code{path} to
+which a @code{path} can be cast:
+@cindex @code{coloredpath}
+@verbatim
+struct coloredpath
+{
+ path p;
+ pen[] pens(real);
+ int colortype=coloredSegments;
+}
+@end verbatim
+@noindent
+@cindex @code{coloredSegments}
+@cindex @code{coloredNodes}
+Here @code{p} defines the cross section and
+the method @code{pens(real t)} returns an array of pens (interpreted
+as a cyclic array) used for shading the tube patches at
+@code{relpoint(g,t)}. If @code{colortype=coloredSegments}, the tube patches
+are filled as if each segment of the section was colored with the pen
+returned by @code{pens(t)}, whereas if @code{colortype=coloredNodes}, the
+tube components are vertex shaded as if the nodes of the section were colored.
+
+A @code{coloredpath} can be constructed with one of the routines:
+@verbatim
+coloredpath coloredpath(path p, pen[] pens(real),
+ int colortype=coloredSegments);
+coloredpath coloredpath(path p, pen[] pens=new pen[] {currentpen},
+ int colortype=coloredSegments);
+coloredpath coloredpath(path p, pen pen(real));
+@end verbatim
+@noindent
+In the second case, the pens are independent of the relative time.
+In the third case, the array of pens contains only one pen, which
+depends of the relative time.
+
+The casting of @code{path} to @code{coloredpath} allows the
+use of a @code{path} instead of a @code{coloredpath}; in this case the
+shading behaviour is the default shading behavior for a surface.
+
+An example of @code{tube} is provided in the file
+@code{trefoilknot.asy}. Further examples can be found at
+@url{http://piprim.tuxfamily.org/asymptote/tube/}.
+
+@node flowchart
+@section @code{flowchart}
+@cindex @code{flowchart}
+This package provides routines for drawing flowcharts. The primary
+structure is a @code{block}, which represents a single block on the
+flowchart. The following eight functions return a position on the appropriate
+edge of the block, given picture transform @code{t}:
+
+@verbatim
+pair block.top(transform t=identity());
+pair block.left(transform t=identity());
+pair block.right(transform t=identity());
+pair block.bottom(transform t=identity());
+pair block.topleft(transform t=identity());
+pair block.topright(transform t=identity());
+pair block.bottomleft(transform t=identity());
+pair block.bottomright(transform t=identity());
+@end verbatim
+@cindex @code{block.top}
+@cindex @code{block.left}
+@cindex @code{block.right}
+@cindex @code{block.bottom}
+@cindex @code{block.topleft}
+@cindex @code{block.topright}
+@cindex @code{block.bottomleft}
+@cindex @code{block.bottomright}
+
+@noindent
+To obtain an arbitrary position along the boundary of the block in user
+coordinates, use:
+@verbatim
+pair block.position(real x, transform t=identity());
+@end verbatim
+@cindex @code{block.position}
+
+@noindent
+@cindex @code{block.center}
+The center of the block in user coordinates is stored in
+@code{block.center} and the block size in @code{PostScript} coordinates
+is given by @code{block.size}.
+
+@noindent
+A frame containing the block is returned by
+@verbatim
+frame block.draw(pen p=currentpen);
+@end verbatim
+@cindex @code{block.draw}
+
+The following block generation routines accept a Label, string, or
+frame for their object argument:
+
+@table @dfn
+@item rectangular block with an optional header (and padding @code{dx} around header and body):
+@cindex @code{rectangle}
+@verbatim
+block rectangle(object header, object body, pair center=(0,0),
+ pen headerpen=mediumgray, pen bodypen=invisible,
+ pen drawpen=currentpen,
+ real dx=3, real minheaderwidth=minblockwidth,
+ real minheaderheight=minblockwidth,
+ real minbodywidth=minblockheight,
+ real minbodyheight=minblockheight);
+block rectangle(object body, pair center=(0,0),
+ pen fillpen=invisible, pen drawpen=currentpen,
+ real dx=3, real minwidth=minblockwidth,
+ real minheight=minblockheight);
+@end verbatim
+
+@item diamond-shaped flowchart block:
+@cindex @code{diamond}
+@verbatim
+block diamond(object body, pair center=(0,0),
+ pen fillpen=invisible, pen drawpen=currentpen,
+ real ds=5, real dw=1,
+ real height=20, real minwidth=minblockwidth,
+ real minheight=minblockheight);
+@end verbatim
+
+@item circular flowchart block:
+@cindex @code{circle}
+@verbatim
+block circle(object body, pair center=(0,0), pen fillpen=invisible,
+ pen drawpen=currentpen, real dr=3,
+ real mindiameter=mincirclediameter);
+@end verbatim
+
+@item rectangular flowchart block with rounded corners:
+@cindex @code{roundrectangle}
+@verbatim
+block roundrectangle(object body, pair center=(0,0),
+ pen fillpen=invisible, pen drawpen=currentpen,
+ real ds=5, real dw=0, real minwidth=minblockwidth,
+ real minheight=minblockheight);
+@end verbatim
+
+@item rectangular flowchart block with beveled edges:
+@cindex @code{bevel}
+@verbatim
+block bevel(object body, pair center=(0,0), pen fillpen=invisible,
+ pen drawpen=currentpen, real dh=5, real dw=5,
+ real minwidth=minblockwidth, real minheight=minblockheight);
+@end verbatim
+
+@end table
+
+To draw paths joining the pairs in @code{point} with right-angled lines,
+use the routine:
+@cindex @code{path}
+@cindex @code{Horizontal}
+@cindex @code{Vertical}
+@verbatim
+path path(pair point[] ... flowdir dir[]);
+@end verbatim
+@noindent
+The entries in @code{dir} identify whether successive
+segments between the pairs specified by @code{point} should be drawn
+in the @code{Horizontal} or @code{Vertical} direction.
+
+Here is a simple flowchart example:
+
+@verbatiminclude flowchartdemo.asy
+@sp 1
+@center @image{flowchartdemo}
+
+@node contour
+@section @code{contour}
+@cindex @code{contour}
+This package draws contour lines.
+To construct contours corresponding to the values in an array @code{c}
+for a function @code{f} on @code{box(a,b)}, use
+@verbatim
+guide[][] contour(real f(real, real), pair a, pair b,
+ real[] c, int nx=ngraph, int ny=nx,
+ interpolate join=operator --);
+@end verbatim
+@noindent
+The integers @code{nx} and @code{ny} define the resolution.
+The default resolution, @code{ngraph x ngraph} (here @code{ngraph}
+defaults to @code{100}), can be increased for greater accuracy. The
+default interpolation operator is @code{operator --} (linear). Spline
+interpolation (@code{operator ..}) may produce smoother
+contours but it can also lead to overshooting.
+
+To construct contours for an array of data values on a uniform
+two-dimensional lattice on @code{box(a,b)}, use
+@verbatim
+guide[][] contour(real[][] f, real[][] midpoint=new real[][],
+ pair a, pair b, real[] c,
+ interpolate join=operator --);
+@end verbatim
+
+To construct contours for an array of data values on a nonoverlapping
+regular mesh specified by the two-dimensional array @code{z}, optionally
+specifying the values of @code{f} at the mesh midpoints, use
+@verbatim
+guide[][] contour(pair[][] z, real[][] f,
+ real[][] midpoint=new real[][], real[] c,
+ interpolate join=operator --);
+
+@end verbatim
+@noindent
+To construct contours for an array of values @code{f} specified at
+irregularly positioned points @code{z}, use the routine
+@verbatim
+guide[][] contour(pair[] z, real[] f, real[] c,
+ interpolate join=operator --);
+@end verbatim
+@noindent
+The contours themselves can be drawn with one of the routines
+@verbatim
+void draw(picture pic=currentpicture, Label[] L=new Label[],
+ guide[][] g, pen p=currentpen)
+
+void draw(picture pic=currentpicture, Label[] L=new Label[],
+ guide[][] g, pen[] p)
+@end verbatim
+
+The following simple example draws the contour at value @code{1}
+for the function @math{z=x^2+y^2}, which is a unit circle:
+@verbatiminclude onecontour.asy
+@sp 1
+@center @image{onecontour}
+
+The next example draws and labels multiple contours for the function
+@math{z=x^2-y^2} with the resolution @code{100 x 100}, using a dashed
+pen for negative contours and a solid pen for positive (and zero) contours:
+@verbatiminclude multicontour.asy
+@sp 1
+@center @image{multicontour}
+
+The next example illustrates how contour lines can be drawn on color
+density images:
+@verbatiminclude imagecontour.asy
+@sp 1
+@center @image{imagecontour}
+
+Finally, here is an example that illustrates the construction of contours
+from irregularly spaced data:
+@verbatiminclude irregularcontour.asy
+@sp 1
+@center @image{irregularcontour}
+
+In the above example, the contours of irregularly spaced data are constructed by
+first creating a triangular mesh from an array @code{z} of pairs:
+
+@cindex @code{triangulate}
+@verbatim
+int[][] triangulate(pair[] z);
+@end verbatim
+
+@verbatiminclude triangulate.asy
+@sp 1
+@center @image{triangulate}
+
+The example @code{Gouraudcontour} 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
+Jonathan Shewchuk.
+
+@node contour3
+@section @code{contour3}
+@cindex @code{contour3}
+This package draws surfaces described as the null space of real-valued
+functions of @math{(x,y,z)} or real[][][] matrices.
+Its usage is illustrated in the example file @code{magnetic.asy}.
+
+@node slopefield
+@section @code{slopefield}
+@cindex @code{slopefield}
+To draw a slope field for the differential equation @math{dy/dx=f(x,y)} (or
+@math{dy/dx=f(x)}), use:
+@verbatim
+picture slopefield(real f(real,real), pair a, pair b,
+ int nx=nmesh, int ny=nx,
+ real tickfactor=0.5, pen p=currentpen,
+ arrowbar arrow=None);
+@end verbatim
+@noindent
+Here, the points @code{a} and @code{b} are the lower left and upper
+right corners of the rectangle in which the slope field is to be drawn,
+@code{nx} and @code{ny} are the respective number of ticks in the
+@math{x} and @math{y} directions, @code{tickfactor} is the fraction of
+the minimum cell dimension to use for drawing ticks, and @code{p} is
+the pen to use for drawing the slope fields.
+The return value is a picture that can be added to
+@code{currentpicture} via the @code{add(picture)} command.
+
+The function
+@cindex @code{curve}
+@verbatim
+path curve(pair c, real f(real,real), pair a, pair b);
+@end verbatim
+@noindent
+takes a point (@code{c}) and a slope field-defining function @code{f}
+and returns, as a path, the curve passing through that point. The points
+@code{a} and @code{b} represent the rectangular boundaries over which
+the curve is interpolated.
+
+Both @code{slopefield} and @code{curve} alternatively accept a function
+@code{real f(real)} that depends on @math{x} only, as seen in this example:
+
+@verbatiminclude slopefield1.asy
+@sp 1
+@center @image{slopefield1}
+
+@node Options
+@chapter Options
+@cindex options
+@cindex command-line options
+Type @code{asy -h} to see the full list of command-line options
+supported by @code{Asymptote}:
+@verbatiminclude options
+
+All boolean options can be negated by prepending @code{no} to the option name.
+
+If no arguments are given, @code{Asymptote} runs in interactive mode
+(@pxref{Interactive mode}). In this case, the default output file
+is @code{out.eps}.
+
+If @code{-} is given as the file argument, @code{Asymptote} reads from
+standard input.
+
+If multiple files are specified, they are treated as separate
+@code{Asymptote} runs.
+
+@cindex @code{autoimport}
+If the string @code{autoimport} is nonempty, a module with this name is
+automatically imported for each run as the final step in loading module
+@code{plain}.
+
+@anchor{configuration file}
+@cindex @code{ASYMPTOTE_CONFIG}
+@cindex @code{config}
+@cindex @code{settings}
+@anchor{settings}
+Default option values may be entered as @code{Asymptote} code in a
+configuration file named @code{config.asy} (or the file specified by
+the environment variable @code{ASYMPTOTE_CONFIG} or @code{-config} option).
+@code{Asymptote} will look for this file in its usual search path.
+Typically the configuration file is placed in the
+@code{.asy} directory in the user's home directory
+(@code{%USERPROFILE%\.asy} under @code{MSDOS}).
+Configuration variables are accessed using the long form of the option names:
+@verbatim
+import settings;
+outformat="pdf";
+batchView=false;
+interactiveView=true;
+batchMask=false;
+interactiveMask=true;
+@end verbatim
+Command-line options override these defaults. Most configuration
+variables may also be changed at runtime.
+@cindex @code{dvipsOptions}
+@cindex @code{convertOptions}
+@cindex @code{gsOptions}
+@cindex @code{psviewerOptions}
+@cindex @code{pdfviewerOptions}
+@cindex @code{glOptions}
+The advanced configuration variables @code{dvipsOptions}, @code{convertOptions},
+@code{gsOptions}, @code{psviewerOptions}, @code{pdfviewerOptions}, and
+@code{glOptions} allow specialized options to be passed as a string to
+the respective applications or libraries.
+
+If you insert
+@verbatim
+import plain;
+settings.autoplain=true;
+@end verbatim
+@noindent
+at the beginning of the configuration file, it can contain arbitrary
+@code{Asymptote} code.
+
+@cindex @code{convert}
+@cindex @code{output}
+@cindex @code{format}
+@cindex @code{ImageMagick}
+@cindex @code{render}
+@cindex @code{antialias}
+@cindex @code{size}
+@anchor{convert}
+The default output format is @acronym{EPS} for the (default)
+@code{latex} tex engine and @acronym{PDF} for the @code{pdflatex} and
+@code{xelatex} tex engines.
+Alternative output formats may be produced using the @code{-f} option
+(or @code{outformat} setting). The optional setting @code{-render n} requests
+an output resolution of @code{n} pixels per @code{bp}. Antialiasing is
+controlled by the parameter @code{antialias}, which by default
+specifies a sampling width of 2 pixels.
+@code{Asymptote} can produce any output format supported
+by the @code{ImageMagick} @code{convert} program (version 6.3.5 or
+later recommended; an @code{Invalid Parameter} error message indicates
+that the @code{MSDOS} utility @code{convert} is being used instead of
+the one that comes with @code{ImageMagick}).
+To give specific options to @code{convert}, use the
+@code{convertOptions} setting or call convert manually. This example
+emulates how @code{Asymptote} produces antialiased @code{tiff} output at
+one pixel per @code{bp}:
+@verbatim
+asy -o - venn | convert -alpha Off -density 144x144 -geometry 50%x eps:- venn.tiff
+@end verbatim
+
+@cindex @code{nosafe}
+@cindex @code{safe}
+@cindex @code{system}
+If the option @code{-nosafe} is given, @code{Asymptote} runs
+in unsafe mode. This enables the @code{int system(string s)} call, allowing one
+to execute arbitrary shell commands. The default mode, @code{-safe},
+disables this call.
+
+@cindex offset
+@cindex @code{align}
+A @code{PostScript} offset may be specified as a pair (in @code{bp}
+units) with the @code{-O} option:
+@verbatim
+asy -O 0,0 file
+@end verbatim
+@noindent
+The default offset is zero. The default value of the page alignment
+setting @code{align} is @code{Center}.
+
+@cindex @code{-c}
+The @code{-c} (@code{command}) option may be used to execute arbitrary
+@code{Asymptote} code on the command line as a string. It is not
+necessary to terminate the string with a semicolon. Multiple @code{-c}
+options are executed in the order they are given. For example
+@verbatim
+asy -c 2+2 -c "sin(1)" -c "size(100); draw(unitsquare)"
+@end verbatim
+@noindent
+produces the output
+@verbatim
+4
+0.841470984807897
+@end verbatim
+@noindent
+and draws a unitsquare of size @code{100}.
+
+@cindex @code{-u}
+The @code{-u} (@code{user}) option may be used to specify arbitrary
+@code{Asymptote} settings on the command line as a string. It is not
+necessary to terminate the string with a semicolon. Multiple @code{-u}
+options are executed in the order they are given. Command-line code like
+@code{-u x=sqrt(2)} can be executed within a module like this:
+@verbatim
+real x;
+usersetting();
+write(x);
+@end verbatim
+
+@cindex @code{-l}
+When the @code{-l} (@code{listvariables}) option is used with file
+arguments, only global functions and variables defined in the specified
+file(s) are listed.
+
+Additional debugging output is produced with each additional @code{-v} option:
+@table @code
+@item -v
+Display top-level module and final output file names.
+@item -vv
+Also display imported and included module names and final @code{LaTeX} and
+@code{dvips} processing information.
+@item -vvv
+Also output @code{LaTeX} bidirectional pipe diagnostics.
+@item -vvvv
+Also output knot guide solver diagnostics.
+@item -vvvvv
+Also output @code{Asymptote} traceback diagnostics.
+@end table
+
+@node Interactive mode
+@chapter Interactive mode
+@cindex interactive mode
+Interactive mode is entered by executing the command @code{asy} with
+no file arguments. When the @code{-multiline} option is disabled (the default),
+each line must be a complete @code{Asymptote} statement (unless
+explicitly continued by a final backslash character @code{\});
+it is not necessary to terminate input lines with a semicolon.
+If one assigns @code{settings.multiline=true}, interactive code can be
+entered over multiple lines; in this mode, the automatic termination of
+interactive input lines by a semicolon is inhibited. Multiline mode is useful
+for cutting and pasting @code{Asymptote} code directly into the
+interactive input buffer.
+
+Interactive mode can be conveniently used as a calculator: expressions
+entered at the interactive prompt (for which a corresponding @code{write}
+function exists) are automatically evaluated and written to @code{stdout}.
+
+The following special commands are supported only in interactive mode
+and must be entered immediately after the prompt:
+
+@table @code
+@cindex @code{help}
+@item help
+view the manual;
+@item reset
+reset the @code{Asymptote} environment to its initial state, except for
+changes to the settings module (@pxref{settings}), the current directory
+(@pxref{cd}), and breakpoints (@pxref{Debugger});
+@cindex @code{input}
+@item input FILE
+does an interactive reset, followed by the command
+@code{include FILE}. If the file name @code{FILE} contains
+nonalphanumeric characters, enclose it with quotation marks.
+A trailing semi-colon followed by optional @code{Asymptote} commands may
+be entered on the same line.
+@cindex @code{quit}
+@cindex @code{exit}
+@anchor{history}
+@item quit
+exit interactive mode (@code{exit} is a synonym; the abbreviation
+@code{q} is also accepted unless there exists a top-level variable named
+@code{q}).
+@cindex @code{historylines}
+A history of the most recent 1000 (this number can be changed with the
+@code{historylines} configuration variable) previous commands will be retained
+in the file @code{.asy/history} in the user's home directory (unless
+the command-line option @code{-localhistory} was specified, in which case
+the history will be stored in the file @code{.asy_history} in the
+current directory).
+
+@end table
+
+Typing @code{ctrl-C} interrupts the execution of @code{Asymptote} code
+and returns control to the interactive prompt.
+
+Interactive mode is implemented with the @acronym{GNU} @code{readline} library,
+with command history and auto-completion. To customize the key bindings, see:
+@url{http://cnswww.cns.cwru.edu/php/chet/readline/readline.html}
+
+@cindex @code{Python} usage
+The file @code{asymptote.py} in the @code{Asymptote} system directory
+provides an alternative way of entering @code{Asymptote} commands
+interactively, coupled with the full power of @code{Python}. Copy this
+file to your @code{Python path} and then execute from within
+@code{Python} the commands
+@verbatim
+from asymptote import *
+g=asy()
+g.size(200)
+g.draw("unitcircle")
+g.send("draw(unitsquare)")
+g.fill("unitsquare, blue")
+g.clip("unitcircle")
+g.label("\"$O$\", (0,0), SW")
+@end verbatim
+
+@node GUI
+@chapter Graphical User Interface
+@cindex graphical user interface
+@cindex @acronym{GUI}
+@cindex mouse
+@cindex wheel mouse
+@cindex @code{Button-1}
+@cindex @code{Button-2}
+@cindex @code{xasy}
+
+In the event that adjustments to the final figure are required, the
+preliminary Graphical User Interface (@acronym{GUI}) @code{xasy} included with
+@code{Asymptote} allows you to move graphical objects and draw new ones.
+The modified figure can then be saved as a normal @code{Asymptote} file.
+
+@menu
+* GUI Installation:: Installing @code{xasy}
+* GUI Usage::
+@end menu
+
+@node GUI Installation
+@section GUI Installation
+@cindex GUI installation
+
+As @code{xasy} is written in the interactive scripting language
+@code{Python/TK}, it requires @code{Python}
+(@url{http://www.python.org}), the Python Imaging Library
+(@url{http://www.pythonware.com/products/pil/}), and the @code{tkinter}
+package (included with s@code{Python} under @code{Microsoft Windows}) be
+installed. @code{Fedora Linux} users can either install
+@code{tkinter} with the commands
+@verbatim
+yum install tkinter
+yum install tk-devel
+@end verbatim
+@noindent
+or manually install the @code{tkinter}, @code{tix}, @code{tk},
+and @code{tk-devel} packages.
+
+Pictures are deconstructed into the @acronym{PNG} image format, which
+supports full alpha channel transparency. Under @code{Microsoft
+Windows}, this requires @code{Python 2.5 (or 2.5.1)} and the
+@code{Python Imaging Library}:
+@quotation
+@url{http://www.python.org/ftp/python/2.5.1/python-2.5.1.msi}
+@end quotation
+@quotation
+@url{http://effbot.org/downloads/PIL-1.1.6.win32-py2.5.exe}.
+@end quotation
+@noindent
+On @code{UNIX} systems, place
+@url{http://effbot.org/downloads/Imaging-1.1.6.tar.gz} in the
+@code{Asymptote} source directory, and type (as the root user):
+@verbatim
+tar -zxf Imaging-1.1.6.tar.gz
+cd Imaging-1.1.6
+patch -p1 < ../patches/TkAlpha-Imaging-1.1.6.patch
+python setup.py install
+@end verbatim
+
+Alternatively, @code{xasy} can deconstruct pictures into the @acronym{GIF}
+image format (not recommended as this is very slow), using white as the
+transparent color. This requires the lines
+@verbatim
+import settings;
+xformat="gif";
+@end verbatim
+@noindent
+in the @code{Asymptote} configuration file (@pxref{configuration file}),
+along with the @code{ImageMagick} (@pxref{convert}) program.
+
+@node GUI Usage
+@section GUI Usage
+@cindex GUI usage
+@cindex @code{deconstruct}
+
+A wheel mouse is convenient for raising and lowering objects within
+@code{xasy}, to expose the object to be moved. If a wheel mouse is not
+available, mouse @code{Button-2} can be used to repeatedly lower an
+object instead. When run from the command line, @code{xasy} accepts
+a command line option @code{-x n}, which sets the initial magnification
+to @code{n}.
+
+Deconstruction of compound objects (such as arrows) can be prevented
+by enclosing them within the commands
+@verbatim
+void begingroup(picture pic=currentpicture);
+void endgroup(picture pic=currentpicture);
+@end verbatim
+By default, the elements of a picture or frame will be grouped
+together on adding them to a picture. However, the elements of a frame
+added to another frame are not grouped together by default: their
+elements will be individually deconstructed (@pxref{add}).
+
+@node PostScript to Asymptote
+@chapter @code{PostScript} to @code{Asymptote}
+@cindex @code{pstoedit}
+The excellent @code{PostScript} editor @code{pstoedit} (version 3.45 or later;
+available from @url{http://pstoedit.net}) 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.
+
+For full functionality, the patch @code{pstoedit-3.45asy.patch}
+in the @code{patches} directory should be applied. On @code{UNIX} systems, as
+the root user, place
+@quotation
+@url{http://prdownloads.sourceforge.net/pstoedit/pstoedit-3.45.tar.gz}
+@end quotation
+@noindent
+in the @code{Asymptote} source directory, and type:
+
+@verbatim
+tar -zxf pstoedit-3.45.tar.gz
+cd pstoedit-3.45
+patch -p1 < ../patches/pstoedit-3.45asy.patch
+autoconf
+./configure --prefix=/usr
+make install
+@end verbatim
+
+@noindent
+Then try:
+
+@noindent
+@code{asy -V @value{Datadir}/doc/asymptote/examples/venn.asy}
+@noindent
+@verbatim
+pstoedit -f asy venn.eps test.asy
+asy -V test
+@end verbatim
+
+@noindent
+If the line widths aren't quite correct, try giving @code{pstoedit} the
+@code{-dis} option.
+If the fonts aren't typeset correctly, try giving @code{pstoedit} the
+@code{-dt} option.
+
+@node Help
+@chapter Help
+@cindex help
+@cindex forum
+
+A list of frequently asked questions (@acronym{FAQ}) is maintained at
+@quotation
+@url{http://asymptote.sourceforge.net/FAQ}
+@end quotation
+@noindent
+Questions on installing and using @code{Asymptote} that are not
+addressed in the @acronym{FAQ} should be sent to the
+@code{Asymptote} forum:
+@quotation
+@url{http://sourceforge.net/forum/forum.php?forum_id=409349}
+@end quotation
+@noindent
+Including an example that illustrates what you are trying to do will help
+you get useful feedback.
+@code{LaTeX} problems can often be diagnosed with the @code{-vv} or
+@code{-vvv} command-line options.
+Contributions in the form of patches or @code{Asymptote} modules can be
+posted here:
+@quotation
+@url{http://sourceforge.net/tracker/?atid=685685&group_id=120000}
+@end quotation
+@noindent
+To receive announcements of upcoming releases, please subscribe to
+@code{Asymptote} at
+@quotation
+@url{http://freshmeat.net/projects/asy}
+@end quotation
+@cindex bug reports
+@noindent
+If you find a bug in @code{Asymptote}, please check (if possible)
+whether the bug is still present in the latest @acronym{Subversion}
+developmental code (@pxref{Subversion}) before submitting a bug
+report. New bugs can be submitted using the Bug Tracking System at
+@quotation
+@url{http://sourceforge.net/projects/asymptote}
+@end quotation
+@noindent
+To see if the bug has already been fixed,
+check bugs with Status @code{Closed} and recent lines in
+@quotation
+@url{http://asymptote.sourceforge.net/ChangeLog}
+@end quotation
+@noindent
+
+@cindex stack overflow
+@cindex segmentation fault
+@cindex @code{libsigsegv}
+@code{Asymptote} can be configured with the optional @acronym{GNU} library
+@code{libsigsegv}, available from
+@url{http://libsigsegv.sourceforge.net}, 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
+faults along with your bug report).
+
+@node Debugger
+@chapter Debugger
+@cindex debugger
+Asymptote now includes a line-based (as opposed to code-based)
+debugger that can assist the user in following flow control. To set a
+break point in file @code{file} at line @code{line}, use the command
+
+@cindex @code{stop}
+@verbatim
+void stop(string file, int line, code s=quote{});
+@end verbatim
+@noindent
+The optional argument @code{s} may be used to conditionally set the variable
+@code{ignore} in @code{plain_debugger.asy} to @code{true}. For example, the
+first 10 instances of this breakpoint will be ignored (the
+variable @code{int count=0} is defined in @code{plain_debugger.asy}):
+@verbatim
+stop("test",2,quote{ignore=(++count <= 10);});
+@end verbatim
+
+To set a break point in file @code{file} at the first line containing
+the string @code{text}, use
+
+@verbatim
+void stop(string file, string text, code s=quote{});
+@end verbatim
+@noindent
+To list all breakpoints, use:
+@cindex @code{breakpoints}
+@verbatim
+void breakpoints();
+@end verbatim
+@noindent
+To clear a breakpoint, use:
+@cindex @code{clear}
+@verbatim
+void clear(string file, int line);
+@end verbatim
+@noindent
+To clear all breakpoints, use:
+@verbatim
+void clear();
+@end verbatim
+
+The following commands may be entered at the debugging prompt:
+
+@table @code
+@cindex @code{help}
+@item @code{h}
+help;
+@cindex @code{continue}
+@item @code{c}
+continue execution;
+
+@cindex @code{inst}
+@item @code{i}
+step to the next instruction;
+
+@cindex @code{step}
+@item @code{s}
+step to the next executable line;
+
+@cindex @code{next}
+@item @code{n}
+step to the next executable line in the current file;
+
+@cindex @code{file}
+@item @code{f}
+step to the next file;
+
+@cindex @code{return}
+@item @code{r}
+return to the file associated with the most recent breakpoint;
+
+@cindex @code{trace}
+@item @code{t}
+toggle tracing (@code{-vvvvv}) mode;
+
+@cindex @code{quit}
+@item @code{q}
+quit debugging and end execution;
+
+@cindex @code{exit}
+@item @code{x}
+exit the debugger and run to completion.
+
+@end table
+@noindent
+Arbitrary @code{Asymptote} code may also be entered at the debugging prompt;
+however, since the debugger is implemented with @code{eval}, currently
+only top-level (global) variables can be displayed or modified.
+
+The debugging prompt may be entered manually with the call
+@verbatim
+void breakpoint(code s=quote{});
+@end verbatim
+
+@node Credits
+@chapter Acknowledgments
+@cindex acknowledgments
+
+Financial support for the development of @code{Asymptote} was generously
+provided by the Natural Sciences and Engineering Research Council of
+Canada, the Pacific Institute for Mathematical Sciences, and the
+University of Alberta Faculty of Science.
+
+We also would like to acknowledge the previous work of John D. Hobby,
+author of the program @code{MetaPost} that inspired the development of
+@code{Asymptote}, and Donald E. Knuth, author of @TeX{} and
+@code{MetaFont} (on which @code{MetaPost} is based).
+
+The authors of @code{Asymptote} are Andy Hammerlindl, John Bowman, and
+Tom Prince. Sean Healy designed the @code{Asymptote} logo. Other
+contributors include Radoslav Marinov, Orest Shardt, Chris Savage,
+Philippe Ivaldi, Olivier Guib@'e, Jacques Pienaar, Mark Henning, Steve
+Melenchuk, Martin Wiebusch, and Stefan Knorr.
+
+@node Index
+@unnumbered Index
+
+@printindex cp
+
+@bye
+
+@c LocalWords: randMax Gaussrand asy cindex indices resized LaTeX TK latin au
+@c LocalWords: latexusage tex bbox PostScript subdirectory gcc emacs ASYDIR
+@c LocalWords: documentclass usepackage subpath shipout sqrt xN Mx bw AcroRd
+@c LocalWords: xscale xaxis yaxis BeginBar GIF postprocessing fpu de rpair xy
+@c LocalWords: nomask noplain ImageMagick defaultfontsize defaultlinewidth cd
+@c LocalWords: startup natively xasy tkinter VxN yingyang currentpicture toc
+@c LocalWords: MetaPost MetaFont Hammerlindl Healy texinfo autoload setq setf
+@c LocalWords: printindex setfilename settitle dircategory direntry titlepage
+@c LocalWords: vskip filll insertcopying ifnottex detailmenu alist augroup PQ
+@c LocalWords: bool behaviour facto zxf login Debian dev filetypedetect SVN
+@c LocalWords: FFTW bp readline gv eps args Boehm gc evenoddoverlap png joe
+@c LocalWords: boolean initializer expi dir xpart ypart STL substring rfind
+@c LocalWords: pos substr strftime typedef pxref unitcircle yscale Bezier iff
+@c LocalWords: postcontrol precontrol atleast nullpath arclength arctime rgb
+@c LocalWords: dirtime currentpen colorspaces grayscale cmyk defaultpen x cx
+@c LocalWords: linetype longdashed dashdotted longdashdotted linewidth y XP
+@c LocalWords: fontsize defaultfilename keepAspect IgnoreAspect ise flushleft
+@c LocalWords: src dest XDR txt getc fout stdin stdout endl xinput eof js prc
+@c LocalWords: xoutput Microsystem's eol exponentials postfix sayhi th Ubuntu
+@c LocalWords: sqr intop addby libm asin acos atan sinh tanh asinh acosh cbrt
+@c LocalWords: atanh fabs hypot fmod ceil srand dereferenced alice pete sqrtx
+@c LocalWords: eval fft csv runtime nonalphanumeric labely LeftTicks NoTicks
+@c LocalWords: RightTicks BottomTop LeftRight Ticksize UTF BufNewFile BufRead
+@c LocalWords: ticksize subintervals xlimits filetype plugin setlocal makeprg
+@c LocalWords: ylimits uncommented automin automax cp uninstall reals ecast
+@c LocalWords: scaleT unicode RightSide yx yy NoAlign legendmargin opic CCW
+@c LocalWords: arrowbar LeftSide EndBar BeginArrow lly feynman isi showtarget
+@c LocalWords: EndArrow BeginArcArrow EndArcArrow ArcArrow ArcArrows NoFill
+@c LocalWords: filldraw fillpen drawpen errorformat bigsquare bezier darkblue
+@c LocalWords: quartercircle darkgreen lightblue urx ury texpreamble sgn texi
+@c LocalWords: lineargraph datagraph vertices parametricgraph uncomment ggv
+@c LocalWords: loggraph generalaxis texhash arrowsize arrowangle arrowlength
+@c LocalWords: SuppressQuiet MoveQuiet LIBREADLINE config MacOS prebuilt svn
+@c LocalWords: ghostview gsview SIGHUP PDF acroread xpdf cutbefore strptime
+@c LocalWords: libsigsegv intersectionpoint dotfactor vv firstcut pq logticks
+@c LocalWords: Unisys dvips vvv vvvv vvvvv traceback lastcut cutafter infodir
+@c LocalWords: zxvf xargs cond polargraph xmin xmax plabel YZero labelling ln
+@c LocalWords: ymin ymax XZero xequals tickmin tickmax unlabelled se pq pena
+@c LocalWords: yequals Nobre Barbarosie Schwaiger nearearth conicurv Wiebusch
+@c LocalWords: unfill posterSize ngraph interpolatetype ctrl dt pic getint Ai
+@c LocalWords: NNE jxf linecap linejoin unitsquare shadedtiling ei nomarker
+@c LocalWords: westnile minipage ra penb paletteticks drawline nV FillDraw uv
+@c LocalWords: susceptibleM flushright secondaryX secondaryY secondaryaxis tt
+@c LocalWords: titlelabel columnlabel rb xtick ytick labelx XEquals YEquals
+@c LocalWords: treetest eetomumu fermi backend pstoedit drawtree xFF MSDOS gz
+@c LocalWords: vimrc CFLAGS verbatiminclude online noindent bezier superpath
+@c LocalWords: evenodd squarecap roundcap extendcap miterjoin roundjoin NFSS
+@c LocalWords: beveljoin fillrule zerowinding insideness lineskip cmr pcrr Hx
+@c LocalWords: AvantGarde Bookman Helvetica NewCenturySchoolBook minbound pdf
+@c LocalWords: Palatino TimesRoman ZapfChancery ZapfDingbats german basealign
+@c LocalWords: nondeconstructed backends usr venn labelsquare nobasealign dp
+@c LocalWords: NoMargin BeginMargin EndMargin BeginPenMargin EndPenMargin dm
+@c LocalWords: PenMargin PenMargins TrueMargin labelmargin errorbars errorbar
+@c LocalWords: dpx dpy dmx dmy barsize arrowsize BeginDotMargin DotMargin acc
+@c LocalWords: EndDotMargin DotMargins NColors BWRainbow colorspace labelled
+@c LocalWords: PaletteTicks defaultformat leastsquares bjam fprintf endgroup
+@c LocalWords: begingroup xmargin ymargin pbox box ellipse wget exe Gouraud
+@c LocalWords: multithreaded newframe init emph nums concat xline yline zpart
+@c LocalWords: colatitude zscale cosh nullpen MetaFontbook cyclicflag FreeBSD
+@c LocalWords: nodeps Ghostgum beginlabel endlabel pTick ptick loggrid SAS dy
+@c LocalWords: currentprojection latticeshading subpictures colinear unitcube
+@c LocalWords: Autoscaling solveQuadratic MidArrow MidArcArrow Prebuilt url
+@c LocalWords: pdftex comment getstring getstringprefix getreal defaultS hsv
+@c LocalWords: ticklocate autoscaleT autoscaling vectorfield autolimits dvi
+@c LocalWords: zlimits inline dvipdf hyperdvi autoconf gui zerowindingoverlap
+@c LocalWords: prepended intMax quadraticroots cubicroots filltype prepend dx
+@c LocalWords: ticklabel popup UnFill markroutine marknodes markuniform erf
+@c LocalWords: intersectpoint cyrillic mathtext russian brokenaxis Datadir ds
+@c LocalWords: resetdefaultpen latticeshade axialshade radialshade erfc det
+@c LocalWords: gouraudshade unescaped nmesh surfacepen getpair MikTeX dw YZ
+@c LocalWords: meshpen localhistory axisT roundedpath unitsize aSin accel pre
+@c LocalWords: fontcommand makepen aCos aTan Knorr roundpath BeginPoint nView
+@c LocalWords: MidPoint EndPoint nmask antialiasing autoplain batchMask libgc
+@c LocalWords: batchView clearGUI ignoreGUI interactiveMask interactiveView
+@c LocalWords: listvariables outformat parseonly prepending psviewer nCircle
+@c LocalWords: pdfviewer papertype tabcompletion noautoplain plugins Teixeira
+@c LocalWords: embeddedmovie historylines RadialShade penc penr CJK tgz GPL
+@c LocalWords: legendlinelength legendskip USERPROFILE LDFLAGS currentlight
+@c LocalWords: subsampled sinc kai AtBeginDocument GBK clearpage lasy texpath
+@c LocalWords: AtEndDocument zaxis maxbound truepoint paperwidth paperheight
+@c LocalWords: GSL deriv texcolors fixedscaling UpsideDown texreset slidedemo
+@c LocalWords: subitem newslide realMin realMax realEpsilon realDigits gsl dh
+@c LocalWords: obliqueX asycolors monthaxis xautoscale yautoscale zautoscale
+@c LocalWords: obliqueZ obliqueY cylinderskeleton block llcorner dr py nx CPU
+@c LocalWords: loc topleft topright bottomleft bottomright flowrectangle UTC
+@c LocalWords: chartblock flowdiamond flowcircle xlabel BezierSurface el xyz
+@c LocalWords: flowroundrectangle flowbevel flowpath drawflow blocks ny cpu
+@c LocalWords: multipleView usersetting mediumgray flowchartdemo ylabel nv xf
+@c LocalWords: zlabel slopefields cputime roundrectangle slopefield libgccpp
+@c LocalWords: tickfactor USERNAME writeable imagecontour logimage Dumoulin's
+@c LocalWords: NoCrop parametricsurface realmult SoftLight HardLight interp
+@c LocalWords: ColorDodge ColorBurn Ivaldi buildcycle autorotate mexicanhat
+@c LocalWords: Gouraudcontour pdflatex preconfigured perline linelength hskip
+@c LocalWords: penimage filloutside legendhskip legendvskip maxwidth CDlabel
+@c LocalWords: tensorshade MPEG framepoint nonfunction Radoslav Marinov Mepis
+@c LocalWords: Pienaar Melenchuk finalout Linspire Dpkg sudo dpkg dtx Tcount
+@c LocalWords: windingnumber clickable pdfmovie dfn du animationdelay fprime
+@c LocalWords: slidemovies ifdraft embeddedu externalmovie headerpen bodypen
+@c LocalWords: GaussianSurface multiline binarytree tridiagonal portably AIX
+@c LocalWords: binarytreetest Henning subsample breakpoint locator wireframe
+@c LocalWords: labelpath intersectionpoints PSTricks pstextpath curvedlabel
+@c LocalWords: LeftJustified RightJustified tickmodifier gunzip gmake IRIX dv
+@c LocalWords: texcommand RET SITEDIR filegraph pathmarkers POSIX binput AOB
+@c LocalWords: boutput nonportable markinterval stickframe circlebarframe tix
+@c LocalWords: crossframe tildeframe markangle StickIntervalMarker gswin expm
+@c LocalWords: CrossIntervalMarker CircleBarIntervalMarker Ghostscript syzygy
+@c LocalWords: TildeIntervalMarker autoimport calculateTransform bitwise tk
+@c LocalWords: headersize bodysize minheaderwidth minheaderheight minwidth ZX
+@c LocalWords: minbodywidth minbodyheight minheight mindiameter reltime PNG
+@c LocalWords: relpoint Syzygy syzygies seekeof splinetype notaknot slopea ZY
+@c LocalWords: slopeb nonperiodic circlescale MarkFill ScaleX ScaleY xformat
+@c LocalWords: onecontour multicontour irregularcontour dvipsOptions saveline
+@c LocalWords: dirSpecifier controlSpecifier tensionSpecifier atleastflag bsp
+@c LocalWords: curlSpecifier cputimeformat initializers arbitary redeclaring
+@c LocalWords: firstname lastname multdiagonal Raphson OmitTick OmitFormat sp
+@c LocalWords: NoZero NoZeroFormat abbrevation gsOptions namespace redeclared
+@c LocalWords: atLeast intMin globalwrite quarticroots deconsruct substrings
+@c LocalWords: usleep currentpatterns trailingzero Orest Shardt DefaultHead
+@c LocalWords: SimpleHead HookHead TeXHead multipage NURBS inlinemovie dxmax
+@c LocalWords: simpson NoBox truesize autoscale shadestroke recurses mintimes
+@c LocalWords: nonoverlapping texdvicommand texengine maxtimes maxheight pdb
+@c LocalWords: piecewisestraight unitrand graphmarkers antialias nolight newl
+@c LocalWords: Delaunay Shewchuk convertOptions APPDATA pdfreload tempFile
+@c LocalWords: pdfreloadOptions deferred OpenGL Phong Blinn renderer unitbox
+@c LocalWords: bezulate Shardt's rasterized viewport unitdisk unitplane devel
+@c LocalWords: unitcylinder unitcone solidcone unitfrustum unitsphere nslices
+@c LocalWords: DPostScript YZZero freeglut externalprc nonrendered nosafe
+@c LocalWords: unithemisphere versa XYplane xypart unitsolidcone YZEquals
+@c LocalWords: XZEquals XYEquals XZZero XYZero InTicks OutTicks InOutTicks
+@c LocalWords: fitscreen planeproject strokepath meshlight nullpens arrowdir
+@c LocalWords: diffusepen ambientpen emissivepen specularpen arrowbarb keyval
+@c LocalWords: hstretch vstretch roundbox nonconvex miterlimit basealigin
+@c LocalWords: maxviewport maxtile antialiased sphericalharmonic attachfile
+@c LocalWords: vertexshading smoothelevation glOptions iconified iconify
+@c LocalWords: psviewerOptions pdfviewerOptions viewportmargin asyattach
+@c LocalWords: multisampling autogen multisample coloredpath relstep flowdir
+@c LocalWords: colortype coloredSegments coloredNodes trefoilknot scaledgraph
+@c LocalWords: minblockwidth minblockheight mincirclediameter nonassociative
+@c LocalWords: nonintegral gettriple enablerepo hexidecimal XeLaTeX xelatex
+@c LocalWords: dvipdfmx autoadjust viewportsize viewportwidth viewportheight
+@c LocalWords: subregions nonsimply functionshade xetex shader floatingdisk
+@c LocalWords: functionshading nonselfintersecting
diff --git a/Build/source/utils/asymptote/doc/axis3.asy b/Build/source/utils/asymptote/doc/axis3.asy
new file mode 100644
index 00000000000..90cbdc6ad09
--- /dev/null
+++ b/Build/source/utils/asymptote/doc/axis3.asy
@@ -0,0 +1,12 @@
+import graph3;
+
+size(0,200);
+size3(200,IgnoreAspect);
+
+currentprojection=perspective(5,2,2);
+
+scale(Linear,Linear,Log);
+
+xaxis3("$x$",0,1,red,OutTicks(2,2));
+yaxis3("$y$",0,1,red,OutTicks(2,2));
+zaxis3("$z$",1,30,red,OutTicks(beginlabel=false));
diff --git a/Build/source/utils/asymptote/doc/bezier.asy b/Build/source/utils/asymptote/doc/bezier.asy
new file mode 100644
index 00000000000..1c168042c05
--- /dev/null
+++ b/Build/source/utils/asymptote/doc/bezier.asy
@@ -0,0 +1 @@
+label("$(1-t)^3z_0+3t(1-t)^2c_0+3t^2(1-t)c_1+t^3z_1\qquad 0\le t\le 1$.",(0,0));
diff --git a/Build/source/utils/asymptote/doc/bezier2.asy b/Build/source/utils/asymptote/doc/bezier2.asy
new file mode 100644
index 00000000000..745fb649dd1
--- /dev/null
+++ b/Build/source/utils/asymptote/doc/bezier2.asy
@@ -0,0 +1,21 @@
+import beziercurve;
+
+pair midpoint(pair a, pair b) {return interp(a,b,0.5);}
+
+pair m0=midpoint(z0,c0);
+pair m1=midpoint(c0,c1);
+pair m2=midpoint(c1,z1);
+
+draw(m0--m1--m2,dashed);
+dot("$m_0$",m0,NW,red);
+dot("$m_1$",m1,N,red);
+dot("$m_2$",m2,red);
+
+pair m3=midpoint(m0,m1);
+pair m4=midpoint(m1,m2);
+pair m5=midpoint(m3,m4);
+
+draw(m3--m4,dashed);
+dot("$m_3$",m3,NW,red);
+dot("$m_4$",m4,NE,red);
+dot("$m_5$",m5,N,red);
diff --git a/Build/source/utils/asymptote/doc/beziercurve.asy b/Build/source/utils/asymptote/doc/beziercurve.asy
new file mode 100644
index 00000000000..338109bbd6e
--- /dev/null
+++ b/Build/source/utils/asymptote/doc/beziercurve.asy
@@ -0,0 +1,12 @@
+size(400);
+pair z0=(0,0);
+pair c0=(1,1);
+pair c1=(2,1);
+pair z1=(3,0);
+draw(z0..controls c0 and c1 .. z1,blue);
+
+draw(z0--c0--c1--z1,dashed);
+dot("$z_0$",z0,W,red);
+dot("$c_0$",c0,NW,red);
+dot("$c_1$",c1,NE,red);
+dot("$z_1$",z1,red);
diff --git a/Build/source/utils/asymptote/doc/bigsquare.asy b/Build/source/utils/asymptote/doc/bigsquare.asy
new file mode 100644
index 00000000000..b917dfc42cc
--- /dev/null
+++ b/Build/source/utils/asymptote/doc/bigsquare.asy
@@ -0,0 +1,2 @@
+size(0,3cm);
+draw(unitsquare);
diff --git a/Build/source/utils/asymptote/doc/binarytreetest.asy b/Build/source/utils/asymptote/doc/binarytreetest.asy
new file mode 100644
index 00000000000..0078bb749e0
--- /dev/null
+++ b/Build/source/utils/asymptote/doc/binarytreetest.asy
@@ -0,0 +1,13 @@
+import binarytree;
+
+picture pic,pic2;
+
+binarytree bt=binarytree(1,2,4,nil,5,nil,nil,0,nil,nil,3,6,nil,nil,7);
+draw(pic,bt);
+
+binarytree st=searchtree(10,5,2,1,3,4,7,6,8,9,15,13,12,11,14,17,16,18,19);
+draw(pic2,st,blue);
+
+add(pic.fit(),(0,0),10N);
+add(pic2.fit(),(0,0),10S);
+
diff --git a/Build/source/utils/asymptote/doc/brokenaxis.asy b/Build/source/utils/asymptote/doc/brokenaxis.asy
new file mode 100644
index 00000000000..9de9fa414d3
--- /dev/null
+++ b/Build/source/utils/asymptote/doc/brokenaxis.asy
@@ -0,0 +1,25 @@
+import graph;
+
+size(200,150,IgnoreAspect);
+
+// Break the x axis at 3; restart at 8:
+real a=3, b=8;
+
+// Break the y axis at 100; restart at 1000:
+real c=100, d=1000;
+
+scale(Broken(a,b),BrokenLog(c,d));
+
+real[] x={1,2,4,6,10};
+real[] y=x^4;
+
+draw(graph(x,y),red,MarkFill[0]);
+
+xaxis("$x$",BottomTop,LeftTicks(Break(a,b)));
+yaxis("$y$",LeftRight,RightTicks(Break(c,d)));
+
+label(rotate(90)*Break,(a,point(S).y));
+label(rotate(90)*Break,(a,point(N).y));
+label(Break,(point(W).x,ScaleY(c)));
+label(Break,(point(E).x,ScaleY(c)));
+
diff --git a/Build/source/utils/asymptote/doc/colons.asy b/Build/source/utils/asymptote/doc/colons.asy
new file mode 100644
index 00000000000..3cdb6b42962
--- /dev/null
+++ b/Build/source/utils/asymptote/doc/colons.asy
@@ -0,0 +1 @@
+draw((0,0){up}::(100,25){right}::(200,0){down});
diff --git a/Build/source/utils/asymptote/doc/colors.asy b/Build/source/utils/asymptote/doc/colors.asy
new file mode 100644
index 00000000000..ea576379deb
--- /dev/null
+++ b/Build/source/utils/asymptote/doc/colors.asy
@@ -0,0 +1,116 @@
+int i=0;
+int j=0;
+
+bool components=false;
+
+pen p;
+
+void col(bool fill=false ... string[] s) {
+ for(int n=0; n < s.length; ++n) {
+ j -= 10;
+ string s=s[n];
+ eval("p="+s+";",true);
+ if(components) {
+ real[] a=colors(p);
+ for(int i=0; i < a.length; ++i)
+ s += " "+(string) a[i];
+ }
+ if(fill) label(s,(i+10,j),E,p,Fill(gray));
+ else label(s,(i+10,j),E,p);
+ fill(box((i,j-5),(i+10,j+5)),p);
+ }
+}
+
+col("palered");
+col("lightred");
+col("mediumred");
+col("red");
+col("heavyred");
+col("brown");
+col("darkbrown");
+j -= 10;
+
+col("palegreen");
+col("lightgreen");
+col("mediumgreen");
+col("green");
+col("heavygreen");
+col("deepgreen");
+col("darkgreen");
+j -= 10;
+
+col("paleblue");
+col("lightblue");
+col("mediumblue");
+col("blue");
+col("heavyblue");
+col("deepblue");
+col("darkblue");
+j -= 10;
+
+i += 150;
+j=0;
+
+col("palecyan");
+col("lightcyan");
+col("mediumcyan");
+col("cyan");
+col("heavycyan");
+col("deepcyan");
+col("darkcyan");
+j -= 10;
+
+col("pink");
+col("lightmagenta");
+col("mediummagenta");
+col("magenta");
+col("heavymagenta");
+col("deepmagenta");
+col("darkmagenta");
+j -= 10;
+
+col("paleyellow");
+col("lightyellow");
+col("mediumyellow");
+col("yellow");
+col("lightolive");
+col("olive");
+col("darkolive");
+j -= 10;
+
+col("palegray");
+col("lightgray");
+col("mediumgray");
+col("gray");
+col("heavygray");
+col("deepgray");
+col("darkgray");
+j -= 10;
+
+i += 150;
+j=0;
+
+col("black");
+col("white",fill=true);
+j -= 10;
+
+col("orange");
+col("fuchsia");
+j -= 10;
+col("chartreuse");
+col("springgreen");
+j -= 10;
+col("purple");
+col("royalblue");
+j -= 10;
+
+col("Cyan");
+col("Magenta");
+col("Yellow");
+col("Black");
+
+j -= 10;
+
+col("cmyk(red)");
+col("cmyk(blue)");
+col("cmyk(green)");
diff --git a/Build/source/utils/asymptote/doc/cube.asy b/Build/source/utils/asymptote/doc/cube.asy
new file mode 100644
index 00000000000..436e1e2729f
--- /dev/null
+++ b/Build/source/utils/asymptote/doc/cube.asy
@@ -0,0 +1,16 @@
+import three;
+dotgranularity=0; // Render dots as spheres.
+
+currentprojection=orthographic(5,4,2,center=true);
+
+size(5cm);
+size3(3cm,5cm,8cm);
+
+draw(unitbox);
+
+dot(unitbox,red);
+
+label("$O$",(0,0,0),NW);
+label("(1,0,0)",(1,0,0),S);
+label("(0,1,0)",(0,1,0),E);
+label("(0,0,1)",(0,0,1),Z);
diff --git a/Build/source/utils/asymptote/doc/cylinderskeleton.asy b/Build/source/utils/asymptote/doc/cylinderskeleton.asy
new file mode 100644
index 00000000000..7dcd1c81190
--- /dev/null
+++ b/Build/source/utils/asymptote/doc/cylinderskeleton.asy
@@ -0,0 +1,6 @@
+import solids;
+
+size(0,100);
+
+revolution r=cylinder(O,1,1.5,Y+Z);
+draw(r,heavygreen);
diff --git a/Build/source/utils/asymptote/doc/datagraph.asy b/Build/source/utils/asymptote/doc/datagraph.asy
new file mode 100644
index 00000000000..299b1594a0f
--- /dev/null
+++ b/Build/source/utils/asymptote/doc/datagraph.asy
@@ -0,0 +1,12 @@
+import graph;
+
+size(200,150,IgnoreAspect);
+
+real[] x={0,1,2,3};
+real[] y=x^2;
+
+draw(graph(x,y),red);
+
+xaxis("$x$",BottomTop,LeftTicks);
+yaxis("$y$",LeftRight,
+ RightTicks(Label(fontsize(8)),new real[]{0,4,9}));
diff --git a/Build/source/utils/asymptote/doc/diagonal.asy b/Build/source/utils/asymptote/doc/diagonal.asy
new file mode 100644
index 00000000000..32f3fc04be0
--- /dev/null
+++ b/Build/source/utils/asymptote/doc/diagonal.asy
@@ -0,0 +1 @@
+draw((0,0)--(100,100));
diff --git a/Build/source/utils/asymptote/doc/diatom.asy b/Build/source/utils/asymptote/doc/diatom.asy
new file mode 100644
index 00000000000..905b432c90d
--- /dev/null
+++ b/Build/source/utils/asymptote/doc/diatom.asy
@@ -0,0 +1,129 @@
+import graph;
+
+size(15cm,12cm,IgnoreAspect);
+
+real minpercent=20;
+real ignorebelow=0;
+string data="diatom.csv";
+string[] group;
+int[] begin,end;
+
+defaultpen(fontsize(8)+overwrite(MoveQuiet));
+
+file in=line(csv(input(data)));
+
+string depthlabel=in;
+string yearlabel=in;
+string[] taxa=in;
+group=in;
+begin=in;
+real[] depth;
+int[] year;
+real[][] percentage;
+
+while(true) {
+ real d=in;
+ if(eof(in)) break;
+ depth.push(d);
+ year.push(in);
+ percentage.push(in);
+}
+
+percentage=transpose(percentage);
+real depthmin=-min(depth);
+real depthmax=-max(depth);
+
+int n=percentage.length;
+
+int final;
+for(int taxon=0; taxon < n; ++taxon) {
+ real[] P=percentage[taxon];
+ if(max(P) < ignorebelow) continue;
+ final=taxon;
+}
+
+real angle=45;
+real L=3cm;
+pair Ldir=L*dir(angle);
+real ymax=-infinity;
+real margin=labelmargin();
+
+real location=0;
+
+for(int i=0; i < begin.length-1; ++i) end[i]=begin[i+1]-1;
+end[begin.length-1]=n-1;
+
+typedef void drawfcn(frame f);
+drawfcn[] draw=new drawfcn[begin.length];
+
+pair z0;
+
+for(int taxon=0; taxon < n; ++taxon) {
+ real[] P=percentage[taxon];
+ real maxP=max(P);
+ if(maxP < ignorebelow) continue;
+ picture pic;
+ real x=1;
+ if(maxP < minpercent) x=minpercent/maxP;
+ if(maxP > 100) x=50/maxP;
+ scale(pic,Linear(true,x),Linear(-1));
+ filldraw(pic,(0,depthmin)--graph(pic,P,depth)--(0,depthmax)--cycle,
+ gray(0.9));
+ xaxis(pic,Bottom,LeftTicks("$%.3g$",beginlabel=false,0,2),above=true);
+ xaxis(pic,Top,above=true);
+
+ frame label;
+ label(label,rotate(angle)*TeXify(taxa[taxon]),(0,0),N);
+
+ pair z=point(pic,N);
+ pair v=max(label);
+ int taxon=taxon;
+ pic.add(new void(frame f, transform t) {
+ pair z1=t*z+v;
+ ymax=max(ymax,z1.y+margin);
+ });
+
+ for(int i=0; i < begin.length; ++i) {
+ pair z=point(pic,N);
+ pair v=max(label);
+ if(taxon == begin[i]) {
+ pic.add(new void(frame f, transform t) {
+ pair Z=t*z+v;
+ z0=Z;
+ pair w0=Z+Ldir;
+ });
+ } else if(taxon == end[i]) {
+ int i=i;
+ pair align=2N;
+ pic.add(new void(frame, transform t) {
+ pair z0=z0;
+ pair z1=t*z+v;
+ pair w1=z1+Ldir;
+ draw[i]=new void(frame f) {
+ path g=z0--(z0.x+(ymax-z0.y)/Tan(angle),ymax)--
+ (z1.x+(ymax-z1.y)/Tan(angle),ymax)--z1;
+ draw(f,g);
+ label(f,group[i],point(g,1.5),align);
+ };
+ });
+ }
+ }
+
+ add(pic,label,point(pic,N));
+
+ if(taxon == 0) yaxis(pic,depthlabel,Left,RightTicks(0,10),above=true);
+ if(taxon == final) yaxis(pic,Right,LeftTicks("%",0,10),above=true);
+
+ add(shift(location,0)*pic);
+ location += pic.userMax.x;
+}
+
+add(new void(frame f, transform) {
+ for(int i=0; i < draw.length; ++i)
+ draw[i](f);
+ });
+
+for(int i=0; i < year.length; ++i)
+ if(year[i] != 0) label((string) year[i],(location,-depth[i]),E);
+
+label("\%",(0.5*location,point(S).y),5*S);
diff --git a/Build/source/utils/asymptote/doc/diatom.csv b/Build/source/utils/asymptote/doc/diatom.csv
new file mode 100644
index 00000000000..d05c3f4bc9a
--- /dev/null
+++ b/Build/source/utils/asymptote/doc/diatom.csv
@@ -0,0 +1,28 @@
+"sediment depth (cm)","year","Achnanthes minutissima Kuetzing","Anomoeoneis vitrea (Grunow) Ross","Asterionella formosa Hassall","Tabellaria flocculosa (Roth) Kuetzing","Fragilaria cf. tenera","Chaetoceros muelleri/elmorei cysts","Aulacoseira spp. ","Fragilaria capucina var. vaucheriae (Kuetzing)","Fragilaria crotonensis Kitton"
+"A","B","C"
+0,4,6
+0,2000,11.6959064327485,9.55165692007797,49.6101364522417,1.364522417154,0,0.974658869395711,0,2.14424951267057,4.09356725146199
+10,1998,20.2676864244742,11.2810707456979,34.7992351816444,2.39005736137667,0,0.191204588910134,0.573613766730402,0.382409177820268,7.55258126195029
+20,1996,21.1282051282051,33.6410256410256,24,2.35897435897436,0.615384615384615,0,0.205128205128205,0.615384615384615,2.56410256410256
+30,1994,25.7620452310718,21.0422812192724,31.3667649950836,2.16322517207473,0.393313667649951,0.393313667649951,0.196656833824975,1.76991150442478,3.73647984267453
+40,1992,21.0422812192724,16.5191740412979,42.9695181907571,0.589970501474926,0,0.983284169124877,0.589970501474926,0.393313667649951,1.96656833824975
+50,1990,23.1067961165049,24.0776699029126,29.126213592233,1.35922330097087,0,0.970873786407767,0.388349514563107,0.58252427184466,3.30097087378641
+60,1988,35.0738916256158,33.3004926108374,4.33497536945813,1.37931034482759,0.591133004926108,1.97044334975369,1.18226600985222,0.985221674876847,2.75862068965517
+70,1986,42.2090729783037,33.7278106508876,2.26824457593688,1.38067061143984,0.788954635108481,1.18343195266272,0.591715976331361,1.38067061143984,3.25443786982249
+90,1984,34.5098039215686,41.9607843137255,0.196078431372549,2.15686274509804,0.588235294117647,2.74509803921569,0.588235294117647,2.15686274509804,0
+95,1982,38.0487804878049,45.4634146341463,0.487804878048781,0.975609756097561,0.975609756097561,0,0.390243902439024,0.390243902439024,0
+110,1980,40.1860465116279,41.4883720930233,1.30232558139535,0.837209302325581,0,0.930232558139535,0.372093023255814,0.372093023255814,1.3953488372093
+130,1978,39.6501457725948,42.1768707482993,0.291545189504373,0.194363459669582,2.72108843537415,1.55490767735666,0,1.36054421768707,0.777453838678329
+150,1972,32.6298701298701,31.4935064935065,1.86688311688312,1.78571428571429,0.162337662337662,13.961038961039,0.162337662337662,1.94805194805195,1.86688311688312
+170,1970,30.7692307692308,47.534516765286,0.986193293885602,3.35305719921105,0.19723865877712,1.38067061143984,0,1.18343195266272,0.591715976331361
+190,1965,40.5268490374873,37.8926038500507,1.82370820668693,2.63424518743668,0,1.21580547112462,0.405268490374873,1.21580547112462,1.01317122593718
+260,1961,40.4494382022472,26.0299625468165,0.468164794007491,1.31086142322097,0.561797752808989,8.05243445692884,0,3.74531835205992,0.374531835205993
+280,1950,44.946025515211,11.9725220804711,0.294406280667321,0.785083415112856,16.48675171737,1.96270853778214,0.392541707556428,2.35525024533857,0
+290,1942,41.2818096135721,8.29406220546654,0.188501413760603,0.282752120640905,28.6522148916117,0.942507068803016,0.377002827521206,4.33553251649387,0
+300,1940,18.0995475113122,12.3076923076923,0,0.180995475113122,40.3619909502262,5.61085972850679,0,2.35294117647059,0
+310,1920,28.6844708209693,11.2759643916914,0.593471810089021,3.26409495548961,13.0563798219585,13.2542037586548,0.19782393669634,9.89119683481701,0.989119683481701
+320,1915,6.17977528089888,1.31086142322097,4.30711610486891,6.74157303370787,32.7715355805243,34.4569288389513,1.31086142322097,2.62172284644195,0
+330,1910,4.03846153846154,0.769230769230769,14.5192307692308,36.4423076923077,5,0.769230769230769,11.1538461538462,0,2.11538461538462
+340,1888,7.37148399612027,1.1639185257032,9.40834141610087,31.8137730358875,1.1639185257032,0.969932104752667,14.3549951503395,0.193986420950533,0.969932104752667
+400,1763,2.69749518304432,0.192678227360308,24.8554913294798,26.7822736030829,0.385356454720617,2.69749518304432,20.0385356454721,0,1.54142581888247
+450,1726,2.37859266600595,0.396432111000991,9.71258671952428,28.5431119920714,0.198216055500496,0.594648166501487,30.5252725470763,0,0.792864222001982
diff --git a/Build/source/utils/asymptote/doc/dots.asy b/Build/source/utils/asymptote/doc/dots.asy
new file mode 100644
index 00000000000..49acfce341f
--- /dev/null
+++ b/Build/source/utils/asymptote/doc/dots.asy
@@ -0,0 +1 @@
+draw((0,0){up}..(100,25){right}..(200,0){down});
diff --git a/Build/source/utils/asymptote/doc/eetomumu.asy b/Build/source/utils/asymptote/doc/eetomumu.asy
new file mode 100644
index 00000000000..309547d1455
--- /dev/null
+++ b/Build/source/utils/asymptote/doc/eetomumu.asy
@@ -0,0 +1,60 @@
+import feynman;
+
+
+// set default line width to 0.8bp
+currentpen = linewidth(0.8);
+
+// scale all other defaults of the feynman module appropriately
+fmdefaults();
+
+// define vertex and external points
+
+real L = 50;
+
+pair zl = (-0.75*L,0);
+pair zr = (+0.75*L,0);
+
+pair xu = zl + L*dir(+120);
+pair xl = zl + L*dir(-120);
+
+pair yu = zr + L*dir(+60);
+pair yl = zr + L*dir(-60);
+
+
+// draw propagators and vertices
+
+drawFermion(xu--zl);
+drawFermion(zl--xl);
+
+drawPhoton(zl--zr);
+
+drawFermion(yu--zr);
+drawFermion(zr--yl);
+
+drawVertex(zl);
+drawVertex(zr);
+
+
+// draw momentum arrows and momentum labels
+
+drawMomArrow(xl--zl, Relative(left));
+label(Label("$k'$",2RightSide), xl--zl);
+
+label(Label("$k$",2LeftSide), xu--zl);
+
+drawMomArrow(zl--zr, Relative(left));
+label(Label("$q$",2RightSide), zl--zr);
+
+drawMomArrow(zr--yu, Relative(right));
+label(Label("$p'$",2LeftSide), zr--yu);
+
+label(Label("$p$",2RightSide), zr--yl);
+
+
+// draw particle labels
+
+label("$e^-$", xu, left);
+label("$e^+$", xl, left);
+
+label("$\mu^+$", yu, right);
+label("$\mu^-$", yl, right);
diff --git a/Build/source/utils/asymptote/doc/elliptic.asy b/Build/source/utils/asymptote/doc/elliptic.asy
new file mode 100644
index 00000000000..728508f0110
--- /dev/null
+++ b/Build/source/utils/asymptote/doc/elliptic.asy
@@ -0,0 +1,115 @@
+struct curve {
+ real a=0;
+ real b=8;
+
+ real y2(real x) {
+ return x^3+a*x+b;
+ }
+
+ real disc() {
+ return -16*(4*a*a*a+27*b*b);
+ }
+
+ real lowx () {
+ return sqrt(-a/3);
+ }
+
+ int comps() {
+ if (a < 0) {
+ real x=sqrt(-a/3);
+ return y2(x) < 0 ? 2 : 1;
+ }
+ return 1;
+ }
+
+ void locus(picture pic=currentpicture, real m, real M, int n=100,
+ pen p=currentpen) {
+ path flip(path p, bool close) {
+ path pp=reverse(yscale(-1)*p)..p;
+ return close ? pp..cycle : pp;
+ }
+ path section(real m, real M, int n) {
+ guide g;
+ real width=(M-m)/n;
+ for(int i=0; i <= n; ++i) {
+ real x=m+width*i;
+ real yy=y2(x);
+ if (yy > 0)
+ g=g..(x,sqrt(yy));
+ }
+ return g;
+ }
+
+ if (comps() == 1) {
+ draw(pic,flip(section(m,M,n),false),p);
+ }
+ else {
+ real x=lowx(); // The minimum on x^3+ax+b
+ if (m < x)
+ draw(pic,flip(section(m,min(x,M),n),true),p);
+ if (x < M)
+ draw(pic,flip(section(max(x,m),M,n),false),p);
+ }
+ }
+
+ pair neg(pair P) {
+ return finite(P.y) ? yscale(-1)*P : P;
+ }
+
+ pair add(pair P, pair Q) {
+ if (P.x == Q.x && P.x != Q.x)
+ return (0,infinity);
+ else {
+ real lambda=P == Q ? (3*P.x^2+a)/(2*P.y) : (Q.y-P.y)/(Q.x-P.x);
+ real Rx=lambda^2-P.x-Q.x;
+ return (Rx,(P.x-Rx)*lambda-P.y);
+ }
+ }
+}
+
+import graph;
+import math;
+
+size(0,200);
+
+curve c; c.a=-1; c.b=4;
+
+pair oncurve(real x)
+{
+ return (x,sqrt(c.y2(x)));
+}
+
+picture output;
+
+axes();
+c.locus(-4,3,.3red+.7blue);
+
+pair P=oncurve(-1),Q=oncurve(1.2);
+pair PP=c.add(P,P),sum=c.add(P,Q);
+
+save();
+
+drawline(P,Q,dashed);
+drawline(c.neg(sum),sum,dashed);
+dot("$P$", P, NW);
+dot("$Q$", Q, SSE);
+dot(c.neg(sum));
+dot("$P+Q$", sum, 2SW);
+
+add(output,currentpicture.fit(),(-0.5cm,0),W);
+
+restore();
+
+save();
+
+drawline(P,c.neg(PP),dashed);
+drawline(c.neg(PP),PP,dashed);
+dot("$P$", P, NW);
+dot(c.neg(PP));
+dot("$2P$", PP, SW);
+
+add(output,currentpicture.fit(),(0.5cm,0),E);
+
+shipout(output);
+
+restore();
diff --git a/Build/source/utils/asymptote/doc/errorbars.asy b/Build/source/utils/asymptote/doc/errorbars.asy
new file mode 100644
index 00000000000..a8707b24972
--- /dev/null
+++ b/Build/source/utils/asymptote/doc/errorbars.asy
@@ -0,0 +1,42 @@
+import graph;
+
+picture pic;
+real xsize=200, ysize=140;
+size(pic,xsize,ysize,IgnoreAspect);
+
+pair[] f={(5,5),(50,20),(90,90)};
+pair[] df={(0,0),(5,7),(0,5)};
+
+errorbars(pic,f,df,red);
+draw(pic,graph(pic,f),"legend",
+ marker(scale(0.8mm)*unitcircle,red,FillDraw(blue),above=false));
+
+scale(pic,true);
+
+xaxis(pic,"$x$",BottomTop,LeftTicks);
+yaxis(pic,"$y$",LeftRight,RightTicks);
+add(pic,legend(pic),point(pic,NW),20SE,UnFill);
+
+picture pic2;
+size(pic2,xsize,ysize,IgnoreAspect);
+
+frame mark;
+filldraw(mark,scale(0.8mm)*polygon(6),green,green);
+draw(mark,scale(0.8mm)*cross(6),blue);
+
+draw(pic2,graph(pic2,f),marker(mark,markuniform(5)));
+
+scale(pic2,true);
+
+xaxis(pic2,"$x$",BottomTop,LeftTicks);
+yaxis(pic2,"$y$",LeftRight,RightTicks);
+
+yequals(pic2,55.0,red+Dotted);
+xequals(pic2,70.0,red+Dotted);
+
+// Fit pic to W of origin:
+add(pic.fit(),(0,0),W);
+
+// Fit pic2 to E of (5mm,0):
+add(pic2.fit(),(5mm,0),E);
+
diff --git a/Build/source/utils/asymptote/doc/exp.asy b/Build/source/utils/asymptote/doc/exp.asy
new file mode 100644
index 00000000000..2c4eed90d4e
--- /dev/null
+++ b/Build/source/utils/asymptote/doc/exp.asy
@@ -0,0 +1,14 @@
+import graph;
+size(150,0);
+
+real f(real x) {return exp(x);}
+pair F(real x) {return (x,f(x));}
+
+xaxis("$x$");
+yaxis("$y$",0);
+
+draw(graph(f,-4,2,operator ..),red);
+
+labely(1,E);
+label("$e^x$",F(1),SE);
+
diff --git a/Build/source/utils/asymptote/doc/external-proposal.html b/Build/source/utils/asymptote/doc/external-proposal.html
new file mode 100644
index 00000000000..3dcc97d95bd
--- /dev/null
+++ b/Build/source/utils/asymptote/doc/external-proposal.html
@@ -0,0 +1,415 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
+"http://www.w3.org/TR/xhtml1-strict.dtd">
+<html>
+ <head>
+ <meta http-equiv='Content-Type' content='text/html; charset=UTF-8' />
+ <title>Asymptote Proposal - External Modules</title>
+ <style><!--
+ --></style>
+ </head>
+ <body>
+ <h1>Asymptote Proposal &mdash External Modules</h1>
+ <h2>Overview</h2>
+ <p>External modules allow users to extend Asymptote by calling functions
+ written in another programming language.</p>
+ <p>Users do this by writing a .asyc file, which contains a mix of
+ Asymptote code and code from another language, say C++. Then, a program
+ is run which produces a .asy file and a C++ source file. The C++ file is
+ compiled to produce a shared library file. Then, the .asy file can be
+ imported in Asymptote to use the externally defined features.</p>
+ <p>This spec is describes a proposed feature that has not yet been
+ implemented. It is incomplete, and does not address all of the issues
+ involved in implementing the feature.</p>
+ <h2>Example</h2>
+ <p>Let&#8217;s look at a simple example that shows off the main features.
+ Asymptote currently doesn&#8217;t offer a way to read the contents of a
+ directory. This would be useful if, say, we wanted to make a series of
+ graphs for every .csv file in a directory.</p>
+ <pre>
+/*****
+ * dir.asyc
+ * Andy Hammerlindl 2007/09/11
+ *
+ * An example for the proposed external module support in Asymptote. This reads
+ * the contents of a directory via the POSIX commands.
+ *
+ * Example usage in asymptote:
+ * access dir;
+ * dir.entry[] entries= dir.open('.');
+ * for (dir.entry e : entries)
+ * write(e.name);
+ *****/
+
+// Verbatim code will appear in the c++ or asy file (as specified) interleaved
+// in the same order as it appears here.
+verbatim c++ {
+ #include &lt;sys/types.h&gt;
+ #include &lt;dirent.h&gt;
+ #include &lt;errno.h&gt;
+
+ // asy.h is included by default (needed for hidden code, anyway).
+ // Asymptote-specific types, such as array below, are in the asy namespace.
+ using namespace asy;
+}
+
+// Define a new opaque type in asy which is internally represented by struct
+// dirent *. This is too messy to expose to users of the module, so define
+// everything as private.
+private asytype const struct dirent *entry_t;
+
+private int entry_d_ino(entry_t e) {
+ return (Int)e-&gt;d_ino;
+}
+
+private int entry_d_off(entry_t e) {
+ return (Int)e-&gt;d_off;
+}
+
+private int entry_d_reclen(entry_t e) {
+ return (Int)e-&gt;reclen;
+}
+
+private string entry_d_type(entry_t e) {
+ return string( /*length*/ 1, e-&gt;d_type);
+}
+
+private string entry_d_name(entry_t e) {
+ return string(e-&gt;d_name);
+}
+
+// Define an asy structure to expose the information. These steps are annoying,
+// but straightforward, and not too hard to plow through.
+verbatim asy {
+ struct entry {
+ restricted int ino;
+ restricted int off;
+ restricted int reclen;
+ restricted int type;
+ restricted string name;
+
+ void operator init(entry_t e) {
+ ino=entry_d_ino(e);
+ off=entry_d_off(e);
+ reclen=entry_d_reclen(e);
+ type=entry_d_type(e);
+ name=entry_d_name(e);
+ }
+ }
+}
+
+
+// Given the name of a directory, return an array of entries. Return 0
+// (a null array) on error.
+private entry_t[] base_read(string name)
+{
+ DIR *dir=opendir(name.c_str());
+
+ // TODO: Add standard style of error reporting.
+ if (dir == NULL)
+ return 0;
+
+ // Create the array structure.
+ // array is derived from gc, so will be automatically memory-managed.
+ array *a=new array();
+
+ struct dirent *entry;
+ while (entry=readdir(dir))
+ a-&gt;push&lt;struct dirent *&gt;(entry);
+
+ // The loop has exited, either by error, or after reading the entire
+ // directory. Check before closedir(), in case that call resets errno.
+ if (errno != 0) {
+ closedir(dir);
+ return 0;
+ }
+
+ closedir(dir);
+ return a;
+}
+
+verbatim asy {
+ private entry[] cleanEntries(entry_t[] raw_entries) {
+ if (raw_entries) {
+ entry[] entries;
+ for (entry_t e : raw_entries)
+ entries.push(entry(e));
+ return entries;
+ }
+ return null;
+ }
+
+ entry[] read(string name) {
+ return cleanEntries(base_read(name));
+ }
+}
+
+</pre>
+ <h2>Type Mappings</h2>
+ <p>Types in Asymptote do not directly relate to types in C++, but there
+ is a partial mapping between them. The header file
+ <code>asymptote.h</code> provides typedefs for the primitive asymptote
+ types. For instance <code>string</code> in Asymptote maps to the C++
+ class <code>asy::string</code> which is a variant of
+ <code>std::string</code> and <code>real</code> to <code>asy::real</code>
+ which is a basic floating point type (probably <code>double</code>).
+ Because <code>int</code> is a reserved word in C++, the Asymptote type
+ <code>int</code> is mapped to <code>asy::Int</code> which is one of the
+ basic signed numeric types in C++ (currently 64 bit).
+ <code>asy::pair</code> is a class that implements complex numbers. In
+ the first version of the external module implementation, these will be
+ the only primitive types with mappings, but eventually all of them will
+ be added.</p>
+
+ <p>All Asymptote arrays, regardless of the cell type, are mapped to
+ <code>asy::array *</code> where <code>asy::array</code> is a C++ class.
+ The cells of the array are of the type <code>asy::item</code> which can
+ hold any Asymptote data type. Items can be constructed from any C++
+ type. Once constructed, the value of an item can be retrieved by the
+ function <code>template&lt;typename T&gt; T get(const item&amp;)</code>.
+ Calling <code>get</code> on an item using the wrong type generates a
+ runtime error. </p>
+<pre>
+// Examples of using item.
+item x((asy::Int)2);
+item y(3.4);
+item z=new array;
+item w=(asy::real)3.4;
+
+cout &lt;&lt; get&lt;asy::Int&gt;(x);
+cout &lt;&lt; get&lt;double&gt;(y);
+
+x=y; // x now stores a double.
+cout &lt;&lt; get&lt;double&gt;(x);
+
+cout &lt;&lt; get&lt;asy::real&gt;(w);
+</pre>
+
+ <p>The <code>asy::array</code> class implements, at a minimum, the
+ methods:</p>
+ <ul>
+ <li><code>size_t size()</code>
+ which returns the number of elements,</li>
+ <li><code>template &lt;typename T&gt; T read(size_t i) const</code>
+ which returns the i-th element, interpreted as being of type t.</li>
+ <li><code>template &lt;typename T&gt; void push(item i)</code>
+ adds the item to the end of the array.</li>
+ </ul>
+ <p>It allows access to elements of the array as items by
+ <code>operator[]</code>. We may specify that <code>asy::array</code>
+ be a model of the Random Access Container in the C++ Standard Template
+ Library. It is currently implemented as a subclass of an STL
+ vector.</p>
+<pre>
+// Example of a C++ function that doubles the entries in an array of integers.
+using namespace asy;
+
+void doubler(array *a) {
+ assert(a);
+ size_t length=a-&gt;size();
+ for (size_t i=0; i&lt;length; ++i) {
+ Int x=a-&gt;read&lt;Int&gt;(i); // This is shorthand for get&lt;Int&gt;((*a)[i]).
+ a[i]=2*x; // The type of 2*x is also Int, so this will enter
+ // the item as the proper type.
+ }
+}
+</pre>
+ <p>Users can map new Asymptote types to their own custom C++ types using
+ Opaque Type Declarations, explained below.</p>
+
+ <h2>Syntactic Features</h2>
+ <p>A .asyc file is neither an asy file with some C++ in it, nor a C++
+ with some asy code in it. It can only contain a small number of
+ specific constructs:</p>
+ <ul>
+ <li>Comments</li>
+ <li>Function Definitions</li>
+ <li>Verbatim Code Block</li>
+ <li>Opaque Type Declaration</li>
+ </ul>
+ <!-- Move to after constructs -->
+ <p>Each component may produce code for either the .asy file, the .cc
+ file, or both. The pieces of code produced by each construct appears in
+ the output file in the same order as the constructs in the .asyc. For
+ example, if a function definition occurs before a verbatim Asymptote
+ code block, we can be sure that the function is defined and can be used
+ in that block. Similarly, if a verbatim C++ block occurs before a
+ function definition, then the body of the function can use features
+ declared in the verbatim section.</p>
+
+ <h3>Comments</h3>
+ <p>C++/Asymptote style comments using <code>/* */</code> or
+ <code>//</code> are allowed at the top level. These do not affect the
+ definition of the module, but the implementation may copy them into the
+ .asy and .cc to help explain the resulting code.</p>
+
+ <h3>Verbatim Code Blocks</h3>
+ <p>Verbatim code, ie. code to be copied directly into the either
+ the output .asy or .cc file can be specified in the .asyc file by
+ enclosing it in a verbatim code block. This starts with the special
+ identifier <code>verbatim</code> followed by either <code>c++</code>
+ or <code>asy</code> to specify into which file the code will be copied,
+ and then a block of code in braces. When the .asyc file is parsed,
+ the parser keeps track of matching open and close braces inside the
+ verbatim code block, so that the brace at the start of the block can
+ be matched with the one at the end. This matching process will ignore
+ braces occuring in comments and string and character literals.</p>
+ <h4>Open issue</h4>
+ <p>It may prove to be impractical to walk through the code, matching
+ braces. Also, this plan precludes having a verbatim block with an
+ unbalanced number of braces which might be useful, say to start a
+ namespace at the beginning of the C++ file, and end it at the end of the
+ file. As such, it may be useful to have another technique. A really
+ simple idea (with obvious drawbacks) would be to use the first closing
+ braces that occur at the same indentation level as the verbatim keyword
+ (assuming that the code block itself will be indented). Other
+ alternatives are to use more complicated tokens such as <code>%{</code>
+ and <code>%}</code>, or the shell style <code>&lt;&lt;EOF</code>.</p>
+
+ <h3>Function Definitions</h3>
+ <p>A function definition given at the top level of the file (and not
+ inside a verbatim block) looks much like a function definition in
+ Asymptote or C++, but is actually a mix of both. The header of the
+ function is given in Asymptote code, and defines how the function will
+ look in the resulting Asymptote module. The body, on the other hand, is
+ given in C++, and defines how the function is implemented in C++. As a
+ simple example, consider:
+ <pre>real sum(real x, real y=0.0) {
+ return x+y;
+}</pre>
+ <h4>Header</h4>
+ <p> The header of the definition gives
+ the name, permission, return type, and parameters of the function.
+ Because the function is defined for use in Asymptote, all of the types
+ are given as Asymptote types.</p>
+ <h5>Permissions</h5>
+ <p>As in pure Asymptote, the function can optionally be given a
+ <code>private</code>, <code>restricted</code> or <code>public</code>
+ permission. If not specified, the permission is <code>public</code> by
+ default. This is the permission that the function will have when it is
+ part of the Asymptote module. The example of <code>sum</code> above
+ specifies no permission, so it is public.</p>
+ <p>Just as public methods such as <code>plain.draw</code> can be
+ re-assigned by scripts that import the <code>plain</code> module, the
+ current plan is to allow Asymptote code to modify public members of any
+ module, including ones defined using native code. This is in contrast
+ to builtin functions bindings, which cannot be modified.</p>
+ <h5>Return Type</h5>
+ <p>This gives the Asymptote return type of the function. This cannot be
+ an arbitrary Asymptote type, but must one which maps to a C++ type as
+ explained in the type mapping section above. Our example of <code>sum</code> gives
+ <code>real</code> as a return type, which maps to the C++ type
+ <code>asy::real</code>.</p>
+ <h5>Function Name</h5>
+ <p>This gives the name of the function as it will appear in the
+ Asymptote module. In our example, the Asymptote name is
+ <code>sum</code>. The name can be any Asymptote identifier, including
+ operator names, such as <code>operator +</code>.</p>
+ <p>It is important to note that the Asymptote name has no relation to
+ the C++ name of the function, which may be something strange, such as
+ <code>_asy_func_modulename162</code>. Also, the actual signature and
+ return type of the C++ function may bear no relation to the Asymptote
+ signature. That said, the C++ name of the function may be defined by
+ giving the function name as <code>asyname:cname</code>. Then it can be
+ referred to by other C++ code. The function will be defined with C
+ calling convention, so that its name is not mangled.</p>
+ <h5>Formal Parameters</h5>
+ <p>The function header takes a list of formal parameters. Just as in
+ pure Asymptote code, these can include <code>explicit</code>
+ keywords, type declarations with array and functional types, and rest
+ parameters. Just as with the return type of the function, the type of
+ each of the parameters must map to a C++ type.</p>
+ <p>Parameters may be given an optional Asymptote name and an optional
+ C++ name. These may be declared in one of six ways as in the following
+ examples:</p>
+ <pre>void f(int)
+void f(int name)
+void f(int :)
+void f(int asyname:)
+void f(int :cname)
+void f(int asyname:cname)
+</pre>
+ <p>If the parameter just contains a type, with no identifier,
+ then it has no Asymptote name and no C++ name. If it contains a single
+ name (with no colon), then that name is both the Asymptote and the C++
+ name. If it contains a colon in the place of an identifier, with an
+ optional name in front of the colon and an optional name behind the
+ colon, than the name in front (if given) is the Asymptote name, and the
+ name behind (if given) is the C++ name.</p>
+ <p>The Asymptote name can be any Asymptote identifier, including
+ operator names, but the C++ name must be a valid C++ identifier. For
+ instance <code>void f(int operator +)</code> is not allowed, as the
+ parameter would not have a valid C++ name. The examples
+ <code>void f(int operator +:)</code> and
+ <code>void f(int operator +:addop)</code> are allowed.</p>
+ <p>When called by Asymptote code, named arguments are only matched to
+ the Asymptote names, so for example a function defined by
+ <code>void f(int :x, string x:y)</code> could be called by
+ <code>f(x="hi mom", 4)</code>, but one defined by
+ <code>void f(int x, string x:y)</code> could not.</p>
+ <p>Each formal parameter may take a piece of code as a default value.
+ Because the function is implemented in C++, this code must be given as
+ C++ code. More akin to Asymptote than C++, default arguments may occur
+ for any non-rest parameters, not just those at the end of the list, and
+ may refer to earlier parameters in the list. Earlier parameters are
+ refered to by their C++ names. Example:
+<pre>void drawbox(pair center, real width, real height=2*width, pen p)</pre>
+ Default arguments are parsed by finding the next comma that is not part
+ of a comment, string literal, or character constant, and is not nested
+ inside parentheses. The C++ code between the equals-sign and the comma
+ is taken as the expression for the default argument.</p>
+ <h4>Body</h4>
+ <p>The body of the function is written as C++ code. When the .asyc
+ file is processed, this C++ code is copied verbatim into an actual C++
+ function providing the implementation. However, the actual body of the
+ resultant C++ function may contain code other than the body provided by
+ the user. This auxillary code could include instruction to retrieve the
+ arguments of the function from their representation in the Asymptote
+ virtual machine and bind them to local variables with their C++ names.
+ It could also include initialization and finalization code for the
+ function.</p>
+ <p>In writing code for the function body, one can be assured that all
+ function arguments with C++ names have been bound and are therefore
+ usable in the code. Since all parameters must have Asymptote types that
+ map to C++ types, the types of the paramaters in the body have the type
+ resulting from that mapping.</p>
+ <p>The <code>return</code> keyword can be used to return the result of
+ the function (or without an expression, if the return type was declared
+ as void). The Asymptote return type must map to a C++ type, and the
+ expression given in the return statement will be implicitly cast to that
+ type.</p>
+ <p>Since the implementation will likely not use an actual return
+ statement to return the value of the function back to the Asymptote
+ virtual machine, the interpreter of the .asyc file may walk through the
+ code converting return expressions into a special format in the actual
+ implementation of the function.<p>
+
+ <h3>Opaque Type Declarations</h3>
+ <p>There are a number of mappings between Asymptote and C++ types
+ builtin to the facility. For instance <code>int</code> maps to
+ <code>asy::Int</code> and <code>real</code> to <code>asy::real</code>.
+ Users, however, may want to reference other C++ objects in Asymptote
+ code. This done though opaque type declarations.</p>
+
+ <p>An opaque type declaration is given by an optional permission
+ modifier, the keyword <code>asytype</code>, a C++ type, and an Asymptote
+ identifier; in that order.</p>
+<pre>
+// Examples
+asytype char char;
+public asytype const std::list&lt;asy::Int&gt; *intList;
+private asytype const struct dirert *entry_t;
+</pre>
+ <p>This declaration mapping the Asymptote identifier to the C++ type
+ within the module. The permission of the Asymptote type is given by the
+ permission modifier (or public if the modifier is omitted). The type is
+ opaque, in that none of its internal structure is revealed in the
+ Asymptote code. Like any other type, however, objects of this new type
+ can be returned from functions, given as an arguments to functions, and
+ stored in variables, structures and arrays.</p>
+ <p>In many cases, such as the directory listing example at the start, it
+ will be practical to declare the type as private, and use an Asymptote
+ structure as a wrapper hiding the C++ implementation.</p>
+ </body>
+</html>
+
+
diff --git a/Build/source/utils/asymptote/doc/externalprc.tex b/Build/source/utils/asymptote/doc/externalprc.tex
new file mode 100644
index 00000000000..96643d7cebf
--- /dev/null
+++ b/Build/source/utils/asymptote/doc/externalprc.tex
@@ -0,0 +1,12 @@
+% Generate inline PRC images for latex with
+% asy -inlineimage teapot -render=4
+%
+% Generate inline PRC images for pdflatex with
+% asy -inlineimage teapot -render=4 -tex pdflatex
+%
+\documentclass[12pt]{article}
+\input teapot_.pre
+\RequirePackage{color,graphicx}
+\begin{document}
+\input teapot_.tex
+\end{document}
diff --git a/Build/source/utils/asymptote/doc/extra/intro.asy b/Build/source/utils/asymptote/doc/extra/intro.asy
new file mode 100644
index 00000000000..f19f51b286d
--- /dev/null
+++ b/Build/source/utils/asymptote/doc/extra/intro.asy
@@ -0,0 +1,909 @@
+// Introduction to Asymptote
+
+orientation=Landscape;
+
+settings.tex="pdflatex";
+
+import slide;
+import three;
+import animate;
+
+usersetting();
+
+viewportsize=pagewidth-2pagemargin;
+
+// To generate bibliographic references:
+// asy -k goysr
+// bibtex goysr_
+bibliographystyle("alpha");
+
+itempen=fontsize(22pt);
+
+titlepage("Asymptote: The Vector Graphics Language",
+ "Andy Hammerlindl and John Bowman",
+ "University of Toronto and University of Alberta","August 16, 2007",
+ "http://asymptote.sf.net");
+
+title("History");
+item("\TeX\ and METAFONT (Knuth, 1979)");
+item("MetaPost (Hobby, 1989): 2D Bezier Control Point Selection");
+item("Asymptote (Hammerlindl, Bowman, Prince, 2004): 2D \& 3D Graphics");
+
+title("Statistics (as of April, 2007)");
+item("Runs on Windows, Mac OS X, Linux, etc.");
+item("1800 downloads a month from {\tt asymptote.sourceforge.net}.");
+item("33\ 000 lines of C++ code.");
+item("18\ 000 lines of Asymptote code.");
+
+title("Vector Graphics");
+item("Raster graphics assign colors to a grid of pixels.");
+figure("pixel.pdf");
+item("Vector graphics are graphics which still maintain their look when
+ inspected at arbitrarily small scales.");
+asyfigure(asywrite("
+picture pic;
+
+path zoombox(real h) {
+ return box((-h,-h/2),(min(10,h),min(10,h)/2));
+}
+
+frame zoom(real h, real next=0) {
+ frame f;
+ draw(f, (0,-100){W}..{E}(0,0), Arrow);
+ clip(f, zoombox(h));
+ if(next > 0)
+ draw(f, zoombox(next));
+
+ return scale(100/h)*f;
+}
+
+add(zoom(100), (0,0));
+add(zoom(10), (200,0));
+add(zoom(1), (400,0));
+"));
+
+title("Cartesian Coordinates");
+asyfilecode("diagonal");
+item("units are {\tt PostScript} {\it big points\/} (1 {\tt bp} =
+1/72 {\tt inch})");
+item("{\tt --} means join the points with a linear segment to create
+a {\it path}");
+
+item("cyclic path:");
+
+asyfilecode("square");
+
+
+title("Scaling to a Given Size");
+
+item("{\tt PostScript} units are often inconvenient.");
+
+item("Instead, scale user coordinates to a specified final size:");
+
+code("
+size(101,101);
+draw((0,0)--(1,0)--(1,1)--(0,1)--cycle);
+");
+asyfigure("square");
+
+item("One can also specify the size in {\tt cm}:");
+
+asyfilecode("bigsquare");
+
+
+title("Labels");
+
+item("Adding and aligning \LaTeX\ labels is easy:");
+
+asyfilecode("labelsquare","height=6cm");
+
+
+title("2D Bezier Splines");
+
+item("Using {\tt ..} instead of {\tt --} specifies a {\it Bezier cubic
+spline}:");
+
+code("
+draw(z0 .. controls c0 and c1 .. z1,blue);
+");
+asyfigure("beziercurve","height=7cm");
+
+equation("(1-t)^3 z_0+3t(1-t)^2 c_0+3t^2(1-t) c_1+t^3 z_1, \qquad t\in [0,1].");
+
+title("Smooth Paths");
+
+item("Asymptote can choose control points for you, using the algorithms of
+Hobby and Knuth \cite{Hobby86,Knuth86b}:");
+
+string bean="
+pair[] z={(0,0), (0,1), (2,1), (2,0), (1,0)};
+";
+
+asycode(preamble="size(130,0);",bean+"
+draw(z[0]..z[1]..z[2]..z[3]..z[4]..cycle,
+ grey+linewidth(5));
+dot(z,linewidth(7));
+");
+
+item("First, linear equations involving the curvature are solved to find the
+ direction through each knot. Then, control points along those directions
+ are chosen:");
+
+asyfigure(asywrite(preamble="size(130,0);",bean+"
+path p=z[0]..z[1]..z[2]..z[3]..z[4]..cycle;
+
+dot(z);
+draw(p,lightgrey+linewidth(5));
+dot(z);
+
+picture output;
+save();
+for (int i=0; i<length(p); ++i) {
+ pair z=point(p,i), dir=dir(p,i);
+ draw((z-0.3dir)--(z+0.3dir), Arrow);
+}
+add(output, currentpicture.fit(), (-0.5inch, 0), W);
+restore();
+
+save();
+guide g;
+for (int i=0; i<length(p); ++i) {
+ dot(precontrol(p,i));
+ dot(postcontrol(p,i));
+ g=g--precontrol(p,i)--point(p,i)--postcontrol(p,i);
+}
+draw(g--cycle,dashed);
+add(output, currentpicture.fit(), (+0.5inch, 0), E);
+restore();
+
+shipout(output);
+"));
+
+title("Filling");
+item("Use {\tt fill} to fill the inside of a path:");
+asycode(preamble="size(0,200);","
+path star;
+for (int i=0; i<5; ++i)
+ star=star--dir(90+144i);
+star=star--cycle;
+fill(shift(-1,0)*star,orange+zerowinding);
+draw(shift(-1,0)*star,linewidth(3));
+fill(shift(1,0)*star,blue+evenodd);
+draw(shift(1,0)*star,linewidth(3));
+");
+
+title("Filling");
+item("Use a list of paths to fill a region with holes:");
+asycode(preamble="size(0,300);","
+path[] p={scale(2)*unitcircle, reverse(unitcircle)};
+fill(p,green+zerowinding);
+");
+
+title("Clipping");
+item("Pictures can be clipped to lie inside a path:");
+asycode(preamble="
+size(0,200);
+guide star;
+for (int i=0; i<5; ++i)
+ star=star--dir(90+144i);
+star=star--cycle;","
+fill(star,orange+zerowinding);
+clip(scale(0.7)*unitcircle);
+draw(scale(0.7)*unitcircle);
+");
+item("All of Asymptote's graphical capabilities are based on four primitive
+ commands: {\tt draw}, {\tt fill}, {\tt clip}, and {\tt label}.");
+
+title("Affine Transforms");
+
+item("Affine transformations: shifts, rotations, reflections, and scalings.");
+code("
+transform t=rotate(90);
+write(t*(1,0)); // Writes (0,1).
+");
+
+item("Pairs, paths, pens, strings, and whole pictures can be transformed.");
+code("
+fill(P,blue);
+fill(shift(2,0)*reflect((0,0),(0,1))*P, red);
+fill(shift(4,0)*rotate(30)*P, yellow);
+fill(shift(6,0)*yscale(0.7)*xscale(2)*P, green);
+");
+asyfigure(asywrite("
+size(500,0);
+real bw=0.15;
+real sw=0.2;
+real r=0.15;
+
+path outside=(0,0)--(0,1)--
+ (bw+sw,1)..(bw+sw+r+bw,1-(r+bw))..(bw+sw,1-2(r+bw))--
+ (bw,1-2(r+bw))--(bw,0)--cycle;
+path inside=(bw,1-bw-2r)--(bw,1-bw)--
+ (bw+sw,1-bw)..(bw+sw+r,1-bw-r)..(bw+sw,1-bw-2r)--cycle;
+//fill(new path[] {outside, reverse(inside)},yellow);
+
+path[] P={outside, reverse(inside)};
+
+fill(P,blue);
+fill(shift(2,0)*reflect((0,0),(0,1))*P, red);
+fill(shift(4,0)*rotate(30)*P, yellow);
+fill(shift(6,0)*yscale(0.7)*xscale(2)*P, green);
+"));
+
+title("C++/Java-like Programming Syntax");
+
+code("// Declaration: Declare x to be real:
+real x;
+
+// Assignment: Assign x the value 1.
+x=1.0;
+
+// Conditional: Test if x equals 1 or not.
+if(x == 1.0) {
+ write(\"x equals 1.0\");
+} else {
+ write(\"x is not equal to 1.0\");
+}
+
+// Loop: iterate 10 times
+for(int i=0; i < 10; ++i) {
+ write(i);
+}");
+
+title("Helpful Math Notation");
+
+item("Integer division returns a {\tt real}. Use {\tt quotient} for an integer
+ result:");
+code("3/4==0.75 quotient(3,4)==0");
+
+item("Caret for real and integer exponentiation:");
+code("2^3 2.7^3 2.7^3.2");
+
+item("Many expressions can be implicitly scaled by a numeric constant:");
+code("2pi 10cm 2x^2 3sin(x) 2(a+b)");
+
+item("Pairs are complex numbers:");
+code("(0,1)*(0,1)==(-1,0)");
+
+title("Function Calls");
+
+item("Functions can take default arguments in any position. Arguments are
+ matched to the first possible location:");
+string unitsize="unitsize(0.65cm);";
+string preamble="void drawEllipse(real xsize=1, real ysize=xsize, pen p=blue) {
+ draw(xscale(xsize)*yscale(ysize)*unitcircle, p);
+}
+";
+
+asycode(preamble=unitsize,preamble+"
+drawEllipse(2);
+drawEllipse(red);
+");
+
+item("Arguments can be given by name:");
+asycode(preamble=unitsize+preamble,"
+drawEllipse(xsize=2, ysize=1);
+drawEllipse(ysize=2, xsize=3, green);
+");
+
+title("Rest Arguments");
+item("Rest arguments allow one to write a function that takes an arbitrary
+ number of arguments:");
+code("
+int sum(... int[] nums) {
+ int total=0;
+ for (int i=0; i < nums.length; ++i)
+ total += nums[i];
+ return total;
+}
+
+sum(1,2,3,4); // returns 10
+sum(); // returns 0
+sum(1,2,3 ... new int[] {4,5,6}); // returns 21
+
+int subtract(int start ... int[] subs) {
+ return start - sum(... subs);
+}
+");
+
+title("Higher-Order Functions");
+
+item("Functions are first-class values. They can be passed to other
+ functions:");
+code("real f(real x) {
+ return x*sin(10x);
+}
+draw(graph(f,-3,3,300),red);");
+asyfigure(asywrite("
+import graph;
+size(300,0);
+real f(real x) {
+ return x*sin(10x);
+}
+draw(graph(f,-3,3,300),red);
+"));
+
+title("Higher-Order Functions");
+item("Functions can return functions:");
+equation("f_n(x)=n\sin\left(\frac{x}{n}\right).");
+skip();
+string preamble="
+import graph;
+size(300,0);
+";
+string graphfunc2="
+typedef real func(real);
+func f(int n) {
+ real fn(real x) {
+ return n*sin(x/n);
+ }
+ return fn;
+}
+
+func f1=f(1);
+real y=f1(pi);
+
+for (int i=1; i<=5; ++i)
+ draw(graph(f(i),-10,10),red);
+";
+code(graphfunc2);
+string name=asywrite(graphfunc2,preamble=preamble);
+asy(nativeformat(),name+".asy");
+label(graphic(name+"."+nativeformat()),(0.5,0),
+ Fill(figureborder,figuremattpen));
+
+title("Anonymous Functions");
+
+item("Create new functions with {\tt new}:");
+code("
+path p=graph(new real (real x) { return x*sin(10x); },-3,3,red);
+
+func f(int n) {
+ return new real (real x) { return n*sin(x/n); };
+}");
+
+item("Function definitions are just syntactic sugar for assigning function
+objects to variables.");
+code("
+real square(real x) {
+ return x^2;
+}
+");
+
+remark("is equivalent to");
+code("
+real square(real x);
+square=new real (real x) {
+ return x^2;
+};
+");
+
+title("Structures");
+
+item("As in other languages, structures group together data.");
+code("
+struct Person {
+ string firstname, lastname;
+ int age;
+}
+Person bob=new Person;
+bob.firstname=\"Bob\";
+bob.lastname=\"Chesterton\";
+bob.age=24;
+");
+
+item("Any code in the structure body will be executed every time a new structure
+ is allocated...");
+code("
+struct Person {
+ write(\"Making a person.\");
+ string firstname, lastname;
+ int age=18;
+}
+Person eve=new Person; // Writes \"Making a person.\"
+write(eve.age); // Writes 18.
+");
+
+title("Object-Oriented Programming");
+item("Functions are defined for each instance of a structure.");
+code("
+struct Quadratic {
+ real a,b,c;
+ real discriminant() {
+ return b^2-4*a*c;
+ }
+ real eval(real x) {
+ return a*x^2 + b*x + c;
+ }
+}
+");
+
+item("This allows us to construct ``methods'' which are just normal functions
+ declared in the environment of a particular object:");
+code("
+Quadratic poly=new Quadratic;
+poly.a=-1; poly.b=1; poly.c=2;
+
+real f(real x)=poly.eval;
+real y=f(2);
+draw(graph(poly.eval, -5, 5));
+");
+
+title("Specialization");
+
+item("Can create specialized objects just by redefining methods:");
+code("
+struct Shape {
+ void draw();
+ real area();
+}
+
+Shape rectangle(real w, real h) {
+ Shape s=new Shape;
+ s.draw = new void () {
+ fill((0,0)--(w,0)--(w,h)--(0,h)--cycle); };
+ s.area = new real () { return w*h; };
+ return s;
+}
+
+Shape circle(real radius) {
+ Shape s=new Shape;
+ s.draw = new void () { fill(scale(radius)*unitcircle); };
+ s.area = new real () { return pi*radius^2; }
+ return s;
+}
+");
+
+title("Overloading");
+item("Consider the code:");
+code("
+int x1=2;
+int x2() {
+ return 7;
+}
+int x3(int y) {
+ return 2y;
+}
+
+write(x1+x2()); // Writes 9.
+write(x3(x1)+x2()); // Writes 11.
+");
+
+title("Overloading");
+item("{\tt x1}, {\tt x2}, and {\tt x3} are never used in the same context, so
+ they can all be renamed {\tt x} without ambiguity:");
+code("
+int x=2;
+int x() {
+ return 7;
+}
+int x(int y) {
+ return 2y;
+}
+
+write(x+x()); // Writes 9.
+write(x(x)+x()); // Writes 11.
+");
+
+item("Function definitions are just variable definitions, but variables are
+ distinguished by their signatures to allow overloading.");
+
+title("Operators");
+item("Operators are just syntactic sugar for functions, and can be addressed or
+ defined as functions with the {\tt operator} keyword.");
+code("
+int add(int x, int y)=operator +;
+write(add(2,3)); // Writes 5.
+
+// Don't try this at home.
+int operator +(int x, int y) {
+ return add(2x,y);
+}
+write(2+3); // Writes 7.
+");
+item("This allows operators to be defined for new types.");
+
+title("Operators");
+item("Operators for constructing paths are also functions:");
+code("a.. controls b and c .. d--e");
+remark("is equivalent to");
+code(
+ "operator --(operator ..(a, operator controls(b,c), d), e)");
+item("This allowed us to redefine all of the path operators for 3D paths.");
+asyfigure("helix","height=10cm");
+
+title("Packages");
+
+item("Function and structure definitions can be grouped into packages:");
+code("
+// powers.asy
+real square(real x) { return x^2; }
+real cube(real x) { return x^3; }
+");
+remark("and imported:");
+code("
+import powers;
+real eight=cube(2.0);
+draw(graph(powers.square, -1, 1));
+");
+
+title("Packages");
+
+item("There are packages for Feynman diagrams,");
+asyfigure("eetomumu","height=6cm");
+remark("data structures,");
+asyfigure(asywrite("
+import binarytree;
+
+binarytree bt=binarytree(1,2,4,nil,5,nil,nil,0,nil,nil,3,6,nil,nil,7);
+draw(bt);
+"),"height=6cm");
+newslide();
+remark("algebraic knot theory:");
+asyfigure("knots");
+equations("\Phi\Phi(x_1,x_2,x_3,x_4,x_5)
+ = &\rho_{4b}(x_1+x_4,x_2,x_3,x_5) + \rho_{4b}(x_1,x_2,x_3,x_4) \\
+ + &\rho_{4a}(x_1,x_2+x_3,x_4,x_5) - \rho_{4b}(x_1,x_2,x_3,x_4+x_5) \\
+ - &\rho_{4a}(x_1+x_2,x_3,x_4,x_5) - \rho_{4a}(x_1,x_2,x_4,x_5).");
+
+title("Textbook Graph");
+asy(nativeformat(),"exp");
+filecode("exp.asy");
+label(graphic("exp."+nativeformat(),"height=10cm"),(0.5,0),
+ Fill(figureborder,figuremattpen));
+
+title("Scientific Graph");
+asyfilecode("lineargraph","height=13cm",newslide=true);
+
+title("Data Graph");
+asyfilecode("datagraph","height=13cm",newslide=true);
+
+title("Imported Data Graph");
+asyfilecode("filegraph","height=15cm",newslide=true);
+
+title("Logarithmic Graph");
+asyfilecode("loggraph","height=15cm",newslide=true);
+
+title("Secondary Axis");
+asyfigure("secondaryaxis","height=15cm");
+
+title("Images");
+asyfigure("imagecontour","height=17cm");
+
+title("Multiple Graphs");
+asyfigure("diatom","height=17cm");
+
+title("Hobby's 2D Direction Algorithm");
+item("A tridiagonal system of linear equations is solved to determine any unspecified directions $\theta_k$ and $\phi_k$ through each knot $z_k$:");
+
+equation("\frac{\theta_{k-1}-2\phi_k}{\ell_k}=
+\frac{\phi_{k+1}-2\theta_k}{\ell_{k+1}}.");
+
+asyfigure("Hobbydir","height=9cm");
+
+item("The resulting shape may be adjusted by modifying optional {\it tension\/} parameters and {\it curl\/} boundary conditions.");
+
+//involving the curvature
+
+title("Hobby's 2D Control Point Algorithm");
+item("Having prescribed outgoing and incoming path directions $e^{i\theta}$
+at node~$z_0$ and $e^{i\phi}$ at node $z_1$ relative to the
+vector $z_1-z_0$, the control points are determined as:");
+
+equations("u&=&z_0+e^{i\theta}(z_1-z_0)f(\theta,-\phi),\nonumber\\
+v&=&z_1-e^{i\phi}(z_1-z_0)f(-\phi,\theta),");
+
+remark("where the relative distance function $f(\theta,\phi)$ is given by Hobby [1986].");
+
+asyfigure("Hobbycontrol","height=9cm");
+
+title("Bezier Curves in 3D");
+
+item("Apply an affine transformation");
+
+equation("x'_i=A_{ij} x_j+C_i");
+
+remark("to a Bezier curve:");
+
+equation("x(t)=\sum_{k=0}^3 B_k(t) P_k, \qquad t\in [0,1].");
+
+item("The resulting curve is also a Bezier curve:");
+
+equations("x'_i(t)&=&\sum_{k=0}^3 B_k(t) A_{ij}(P_k)_j+C_i\nonumber\\
+&=&\sum_{k=0}^3 B_k(t) P'_k,");
+
+remark("where $P'_k$ is the transformed $k^{\rm th}$ control point, noting
+$\displaystyle\sum_{k=0}^3 B_k(t)=1.$");
+
+title("3D Generalization of Hobby's algorithm");
+
+item("Must reduce to 2D algorithm in planar case.");
+
+item("Determine directions by applying Hobby's algorithm in the plane containing $z_{k-1}$, $z_k$, $z_{k+1}$.");
+
+// Reformulate Hobby's equations in terms of the angle $\psi_k=$
+item("The only ambiguity that can arise is the overall sign of the angles, which relates to viewing each 2D plane from opposing normal directions.");
+
+item("A reference vector based on the mean unit normal of successive segments can be used to resolve such ambiguities.");
+
+title("3D Control Point Algorithm");
+
+item("Hobby's control point algorithm can be generalized to 3D by expressing it in terms of the absolute directions $\omega_0$ and $\omega_1$:");
+
+equation("u=z_0+\omega_0\left|z_1-z_0\right|f(\theta,-\phi),");
+equation("v=z_1-\omega_1\left|z_1-z_0\right|f(-\phi,\theta),");
+
+asyfigure("Hobbycontrol");
+
+remark("interpreting $\theta$ and $\phi$ as the angle between the corresponding path direction vector and $z_1-z_0$.");
+
+item("In this case there is an unambiguous reference vector for determining the relative sign of the angles $\phi$ and $\theta$.");
+
+viewportmargin=(0,0.5cm);
+defaultpen(1.0);
+title("Interactive 3D Saddle");
+item("A unit circle in the $X$--$Y$ plane may be filled and drawn with:
+(1,0,0)..(0,1,0)..(-1,0,0)..(0,-1,0)..cycle");
+asyinclude("unitcircle3",8cm);
+remark("and then distorted into a saddle:\\ (1,0,0)..(0,1,1)..(-1,0,0)..(0,-1,1)..cycle");
+asyinclude("saddle",8cm);
+
+viewportmargin=(0,2cm);
+title("Smooth 3D surfaces");
+asyinclude("GaussianSurface",15cm);
+defaultpen(0.5);
+
+title("Slide Presentations");
+item("Asymptote has a package for preparing slides.");
+item("It even supports embedded high-resolution PDF movies.");
+
+code('
+title("Slide Presentations");
+item("Asymptote has a package for preparing slides.");
+item("It even supports embedded high-resolution PDF movies.");
+');
+remark("\quad\ldots");
+
+import graph;
+
+pen p=linewidth(1);
+pen dotpen=linewidth(5);
+
+pair wheelpoint(real t) {return (t+cos(t),-sin(t));}
+
+guide wheel(guide g=nullpath, real a, real b, int n)
+{
+ real width=(b-a)/n;
+ for(int i=0; i <= n; ++i) {
+ real t=a+width*i;
+ g=g--wheelpoint(t);
+ }
+ return g;
+}
+
+real t1=0;
+real t2=t1+2*pi;
+
+picture base;
+draw(base,circle((0,0),1),p);
+draw(base,wheel(t1,t2,100),p+linetype("0 2"));
+yequals(base,Label("$y=-1$",1.0),-1,extend=true,p+linetype("4 4"));
+xaxis(base,Label("$x$",align=3SW),0,p);
+yaxis(base,"$y$",0,1.3,p);
+pair z1=wheelpoint(t1);
+pair z2=wheelpoint(t2);
+dot(base,z1,dotpen);
+dot(base,z2,dotpen);
+
+animation a;
+
+int n=25;
+real dt=(t2-t1)/n;
+for(int i=0; i <= n; ++i) {
+ picture pic;
+ size(pic,24cm);
+ real t=t1+dt*i;
+ add(pic,base);
+ draw(pic,circle((t,0),1),p+red);
+ dot(pic,wheelpoint(t),dotpen);
+ a.add(pic);
+}
+
+display(a.pdf(delay=150,"controls"));
+
+title("Automatic Sizing");
+item("Figures can be specified in user coordinates, then
+ automatically scaled to the desired final size.");
+asyfigure(asywrite("
+import graph;
+
+size(0,100);
+
+frame cardsize(real w=0, real h=0, bool keepAspect=Aspect) {
+ picture pic;
+ pic.size(w,h,keepAspect);
+
+ real f(real t) {return 1+cos(t);}
+
+ guide g=polargraph(f,0,2pi,operator ..)--cycle;
+ filldraw(pic,g,pink);
+
+ xaxis(pic,\"$x$\");
+ yaxis(pic,\"$y$\");
+
+ dot(pic,\"$(a,0)$\",(1,0),N);
+ dot(pic,\"$(2a,0)$\",(2,0),N+E);
+
+ frame f=pic.fit();
+ label(f,\"{\tt size(\"+string(w)+\",\"+string(h)+\");}\",point(f,S),align=S);
+ return f;
+}
+
+add(cardsize(0,50), (0,0));
+add(cardsize(0,100), (230,0));
+add(cardsize(0,200), (540,0));
+"));
+
+title("Deferred Drawing");
+item("We can't draw a graphical object until we know the scaling
+ factors for the user coordinates.");
+item("Instead, store a function that when given the scaling information, draws
+ the scaled object.");
+code("
+void draw(picture pic=currentpicture, path g, pen p=currentpen) {
+ pic.add(new void(frame f, transform t) {
+ draw(f,t*g,p);
+ });
+ pic.addPoint(min(g),min(p));
+ pic.addPoint(max(g),max(p));
+}
+");
+
+title("Coordinates");
+item("Store bounding box information as the sum of user and true-size
+ coordinates:");
+asyfigure(asywrite("
+size(0,150);
+
+path q=(0,0){dir(70)}..{dir(70)}(100,50);
+pen p=rotate(30)*yscale(0.7)*(lightblue+linewidth(20));
+draw(q,p);
+draw((90,10),p);
+
+currentpicture.add(new void(frame f, transform t) {
+ draw(f,box(min(t*q)+min(p),max(t*q)+max(p)), dashed);
+ });
+
+draw(box(min(q),max(q)));
+
+frame f;
+draw(f,box(min(p),max(p)));
+
+add(f,min(q));
+add(f,max(q));
+
+draw(q);
+"));
+
+code("pic.addPoint(min(g),min(p));
+pic.addPoint(max(g),max(p));");
+item("Filling ignores the pen width:");
+code("pic.addPoint(min(g),(0,0));
+pic.addPoint(max(g),(0,0));");
+item("Communicate with \LaTeX\ to determine label sizes:");
+
+asyfigure(asywrite("
+size(0,100);
+
+pen p=fontsize(30pt);
+frame f;
+label(f, \"$E=mc^2$\", p);
+draw(f, box(min(f),max(f)));
+shipout(f);
+"));
+
+title("Sizing");
+
+item("When scaling the final figure to a given size $S$, we first need to
+ determine a scaling factor $a>0$ and a shift $b$ so that all of the
+ coordinates when transformed will lie in the interval $[0,S]$. That is, if
+ $u$ and $t$ are the user and truesize components:");
+equation("0\le au+t+b \le S.");
+
+item("We are maximizing the variable $a$ subject to a number of inequalities.
+ This is a linear programming problem that can be solved by the simplex
+ method.");
+
+title("Sizing");
+item("Every addition of a coordinate $(t,u)$ adds two restrictions");
+equation("au+t+b\ge 0,");
+equation("au+t+b\le S,");
+remark("and each drawing component adds two coordinates.");
+item("A figure could easily produce thousands of restrictions, making the
+ simplex method impractical.");
+
+item("Most of these restrictions are redundant, however. For instance, with
+ concentric circles, only the largest circle needs to be accounted for.");
+asyfigure(asywrite("
+import palette;
+size(160,0);
+pen[] p=Rainbow(NColors=11);
+for (int i=1; i<10; ++i) {
+ draw(scale(i)*unitcircle, p[i]+linewidth(2));
+}
+"));
+
+title("Redundant Restrictions");
+item("In general, if $u\le u'$ and $t\le t'$ then");
+equation("au+t+b\le au'+t'+b");
+remark("for all choices of $a>0$ and $b$, so");
+equation("0\le au+t+b\le au'+t'+b\le S.");
+item("This defines a partial ordering on coordinates. When sizing a picture,
+ the program first computes which coordinates are maximal (or minimal) and
+ only sends effective constraints to the simplex algorithm.");
+item("In practice, the linear programming problem will have less than a dozen
+ restraints.");
+item("All picture sizing is implemented in Asymptote code.");
+
+title("Infinite Lines");
+item("Deferred drawing allows us to draw infinite lines.");
+code("drawline(P, Q);");
+
+asyfigure("elliptic","height=12cm");
+
+title("A Final Example: Quilting");
+asyfigure(asywrite("
+import math;
+
+int n=8, skip=3;
+
+pair r(int k) { return unityroot(n,k); }
+
+pen col=blue, col2=purple;
+
+guide square=box((1,1),(-1,-1));
+
+guide step(int mult)
+{
+ guide g;
+ for (int k=0; k<n; ++k)
+ g=g--r(mult*k);
+ g=g--cycle;
+ return g;
+}
+
+guide oct=step(1), star=step(skip);
+
+guide wedge(pair z, pair v, real r, real a)
+{
+ pair w=expi(a/2.0);
+ v=unit(v)*r;
+ return shift(z)*((0,0)--v*w--v*conj(w)--cycle);
+}
+
+filldraw(square, col);
+filldraw(oct, yellow);
+
+// The interior angle of the points of the star.
+real intang=pi*(1-((real)2skip)/((real)n));
+
+for (int k=0; k<n; ++k) {
+ pair z=midpoint(r(k)--r(k+1));
+ guide g=wedge(z,-z,1,intang);
+ filldraw(g,col2);
+}
+
+fill(star,yellow);
+filldraw(star,evenodd+col);
+
+size(5inch,0);
+"));
+
+bibliography("refs");
+
+viewportsize=viewportmargin=0;
+title("\mbox{Asymptote: 2D \& 3D Vector Graphics Language}");
+asyinclude("../examples/logo3");
+skip();
+center("\tt http://asymptote.sf.net");
+center("(freely available under the GNU public license)");
diff --git a/Build/source/utils/asymptote/doc/extra/intro_.bbl b/Build/source/utils/asymptote/doc/extra/intro_.bbl
new file mode 100644
index 00000000000..b3e55e47eee
--- /dev/null
+++ b/Build/source/utils/asymptote/doc/extra/intro_.bbl
@@ -0,0 +1,13 @@
+\begin{thebibliography}{Knu86}
+
+\bibitem[Hob86]{Hobby86}
+John~D. Hobby.
+\newblock Smooth, easy to compute interpolating splines.
+\newblock {\em Discrete Comput. Geom.}, 1:123--140, 1986.
+
+\bibitem[Knu86]{Knuth86b}
+Donald~E. Knuth.
+\newblock {\em The METAFONTbook}.
+\newblock Addison-Wesley, Reading, Massachusetts, 1986.
+
+\end{thebibliography}
diff --git a/Build/source/utils/asymptote/doc/filegraph.asy b/Build/source/utils/asymptote/doc/filegraph.asy
new file mode 100644
index 00000000000..c56dd0234f3
--- /dev/null
+++ b/Build/source/utils/asymptote/doc/filegraph.asy
@@ -0,0 +1,15 @@
+import graph;
+
+size(200,150,IgnoreAspect);
+
+file in=line(input("filegraph.dat"));
+real[][] a=dimension(in,0,0);
+a=transpose(a);
+
+real[] x=a[0];
+real[] y=a[1];
+
+draw(graph(x,y),red);
+
+xaxis("$x$",BottomTop,LeftTicks);
+yaxis("$y$",LeftRight,RightTicks);
diff --git a/Build/source/utils/asymptote/doc/filegraph.dat b/Build/source/utils/asymptote/doc/filegraph.dat
new file mode 100644
index 00000000000..f69ffe330de
--- /dev/null
+++ b/Build/source/utils/asymptote/doc/filegraph.dat
@@ -0,0 +1,4 @@
+# x y
+ 50 0
+100 0.5
+125 2
diff --git a/Build/source/utils/asymptote/doc/flow.asy b/Build/source/utils/asymptote/doc/flow.asy
new file mode 100644
index 00000000000..aba6c5aa055
--- /dev/null
+++ b/Build/source/utils/asymptote/doc/flow.asy
@@ -0,0 +1,31 @@
+import graph;
+defaultpen(1.0);
+
+size(0,150,IgnoreAspect);
+
+real arrowsize=4mm;
+real arrowlength=2arrowsize;
+
+typedef path vector(real);
+
+// Return a vector interpolated linearly between a and b.
+vector vector(pair a, pair b) {
+ return new path(real x) {
+ return (0,0)--arrowlength*interp(a,b,x);
+ };
+}
+
+real f(real x) {return 1/x;}
+
+real epsilon=0.5;
+path g=graph(f,epsilon,1/epsilon);
+
+int n=3;
+draw(g);
+xaxis("$x$");
+yaxis("$y$");
+
+add(vectorfield(vector(W,W),g,n,true));
+add(vectorfield(vector(NE,NW),(0,0)--(point(E).x,0),n,true));
+add(vectorfield(vector(NE,NE),(0,0)--(0,point(N).y),n,true));
+
diff --git a/Build/source/utils/asymptote/doc/flowchartdemo.asy b/Build/source/utils/asymptote/doc/flowchartdemo.asy
new file mode 100644
index 00000000000..74940d92f34
--- /dev/null
+++ b/Build/source/utils/asymptote/doc/flowchartdemo.asy
@@ -0,0 +1,30 @@
+size(0,300);
+
+import flowchart;
+
+block block1=rectangle(Label("Example",magenta),
+ pack(Label("Start:",heavygreen),"",Label("$A:=0$",blue),
+ "$B:=1$"),(-0.5,3),palegreen,paleblue,red);
+block block2=diamond(Label("Choice?",blue),(0,2),palegreen,red);
+block block3=roundrectangle("Do something",(-1,1));
+block block4=bevel("Don't do something",(1,1));
+block block5=circle("End",(0,0));
+
+draw(block1);
+draw(block2);
+draw(block3);
+draw(block4);
+draw(block5);
+
+add(new void(picture pic, transform t) {
+ draw(pic,path(new pair[]{block1.right(t),block2.top(t)},Horizontal),
+ Arrow,PenMargin);
+ draw(pic,Label("Yes",0.5),path(new pair[]{block2.left(t),block3.top(t)},
+ Horizontal),Arrow,PenMargin);
+ draw(pic,Label("No",0.5,N),path(new pair[]{block2.right(t),block4.top(t)},
+ Horizontal),Arrow,PenMargin);
+ draw(pic,path(new pair[]{block3.bottom(t),block5.left(t)},Vertical),
+ Arrow,PenMargin);
+ draw(pic,path(new pair[]{block4.bottom(t),block5.right(t)},Vertical),
+ Arrow,PenMargin);
+ });
diff --git a/Build/source/utils/asymptote/doc/generalaxis.asy b/Build/source/utils/asymptote/doc/generalaxis.asy
new file mode 100644
index 00000000000..dfe1000838e
--- /dev/null
+++ b/Build/source/utils/asymptote/doc/generalaxis.asy
@@ -0,0 +1,11 @@
+import graph;
+size(0,100);
+
+path g=ellipse((0,0),1,2);
+
+scale(true);
+
+axis(Label("C",align=10W),g,LeftTicks(endlabel=false,8,end=false),
+ ticklocate(0,360,new real(real v) {
+ path h=(0,0)--max(abs(max(g)),abs(min(g)))*dir(v);
+ return intersect(g,h)[0];}));
diff --git a/Build/source/utils/asymptote/doc/generalaxis3.asy b/Build/source/utils/asymptote/doc/generalaxis3.asy
new file mode 100644
index 00000000000..68a01c8ce28
--- /dev/null
+++ b/Build/source/utils/asymptote/doc/generalaxis3.asy
@@ -0,0 +1,13 @@
+import graph3;
+
+size(0,100);
+
+path3 g=yscale3(2)*unitcircle3;
+currentprojection=perspective(10,10,10);
+
+axis(Label("C",position=0,align=15X),g,InTicks(endlabel=false,8,end=false),
+ ticklocate(0,360,new real(real v) {
+ path3 h=O--max(abs(max(g)),abs(min(g)))*dir(90,v);
+ return intersect(g,h)[0];},
+ new triple(real t) {return cross(dir(g,t),Z);}));
+
diff --git a/Build/source/utils/asymptote/doc/graphmarkers.asy b/Build/source/utils/asymptote/doc/graphmarkers.asy
new file mode 100644
index 00000000000..f40f00d9ff6
--- /dev/null
+++ b/Build/source/utils/asymptote/doc/graphmarkers.asy
@@ -0,0 +1,37 @@
+import graph;
+
+size(200,100,IgnoreAspect);
+
+markroutine marks() {
+ return new void(picture pic=currentpicture, frame f, path g) {
+ path p=scale(1mm)*unitcircle;
+ for(int i=0; i <= length(g); ++i) {
+ pair z=point(g,i);
+ frame f;
+ if(i % 4 == 0) {
+ fill(f,p);
+ add(pic,f,z);
+ } else {
+ if(z.y > 50) {
+ pic.add(new void(frame F, transform t) {
+ path q=shift(t*z)*p;
+ unfill(F,q);
+ draw(F,q);
+ });
+ } else {
+ draw(f,p);
+ add(pic,f,z);
+ }
+ }
+ }
+ };
+}
+
+pair[] f={(5,5),(40,20),(55,51),(90,30)};
+
+draw(graph(f),marker(marks()));
+
+scale(true);
+
+xaxis("$x$",BottomTop,LeftTicks);
+yaxis("$y$",LeftRight,RightTicks);
diff --git a/Build/source/utils/asymptote/doc/grid3xyz.asy b/Build/source/utils/asymptote/doc/grid3xyz.asy
new file mode 100644
index 00000000000..888b9202eee
--- /dev/null
+++ b/Build/source/utils/asymptote/doc/grid3xyz.asy
@@ -0,0 +1,17 @@
+import grid3;
+
+size(8cm,0,IgnoreAspect);
+currentprojection=orthographic(0.5,1,0.5);
+
+scale(Linear, Linear, Log);
+
+limits((-2,-2,1),(0,2,100));
+
+grid3(XYZgrid);
+
+xaxis3(Label("$x$",position=EndPoint,align=S),Bounds(Min,Min),
+ OutTicks());
+yaxis3(Label("$y$",position=EndPoint,align=S),Bounds(Min,Min),OutTicks());
+zaxis3(Label("$z$",position=EndPoint,align=(-1,0.5)),Bounds(Min,Min),
+ OutTicks(beginlabel=false));
+
diff --git a/Build/source/utils/asymptote/doc/hatch.asy b/Build/source/utils/asymptote/doc/hatch.asy
new file mode 100644
index 00000000000..126b5bec13a
--- /dev/null
+++ b/Build/source/utils/asymptote/doc/hatch.asy
@@ -0,0 +1,11 @@
+size(0,100);
+import patterns;
+
+add("hatch",hatch());
+add("hatchback",hatch(NW));
+add("crosshatch",crosshatch(3mm));
+
+real s=1.25;
+filldraw(unitsquare,pattern("hatch"));
+filldraw(shift(s,0)*unitsquare,pattern("hatchback"));
+filldraw(shift(2s,0)*unitsquare,pattern("crosshatch"));
diff --git a/Build/source/utils/asymptote/doc/helix.asy b/Build/source/utils/asymptote/doc/helix.asy
new file mode 100644
index 00000000000..768add3481a
--- /dev/null
+++ b/Build/source/utils/asymptote/doc/helix.asy
@@ -0,0 +1,20 @@
+import graph3;
+
+size(0,200);
+size3(200,IgnoreAspect);
+
+currentprojection=orthographic(4,6,3);
+
+real x(real t) {return cos(2pi*t);}
+real y(real t) {return sin(2pi*t);}
+real z(real t) {return t;}
+
+path3 p=graph(x,y,z,0,2.7,operator ..);
+
+draw(p,Arrow3);
+
+scale(true);
+
+xaxis3(XZ()*"$x$",Bounds(),red,InTicks(Label,2,2));
+yaxis3(YZ()*"$y$",Bounds(),red,InTicks(beginlabel=false,Label,2,2));
+zaxis3(XZ()*"$z$",Bounds(),red,InTicks);
diff --git a/Build/source/utils/asymptote/doc/histogram.asy b/Build/source/utils/asymptote/doc/histogram.asy
new file mode 100644
index 00000000000..ec00d6638d1
--- /dev/null
+++ b/Build/source/utils/asymptote/doc/histogram.asy
@@ -0,0 +1,19 @@
+import graph;
+import stats;
+
+size(400,200,IgnoreAspect);
+
+int n=10000;
+real[] a=new real[n];
+for(int i=0; i < n; ++i) a[i]=Gaussrand();
+
+draw(graph(Gaussian,min(a),max(a)),blue);
+
+// Optionally calculate "optimal" number of bins a la Shimazaki and Shinomoto.
+int N=bins(a);
+
+histogram(a,min(a),max(a),N,normalize=true,low=0,lightred,black,bars=false);
+
+xaxis("$x$",BottomTop,LeftTicks);
+yaxis("$dP/dx$",LeftRight,RightTicks(trailingzero));
+
diff --git a/Build/source/utils/asymptote/doc/icon.asy b/Build/source/utils/asymptote/doc/icon.asy
new file mode 100644
index 00000000000..1701fe0f32e
--- /dev/null
+++ b/Build/source/utils/asymptote/doc/icon.asy
@@ -0,0 +1,22 @@
+import graph;
+
+size(30,30,IgnoreAspect);
+
+real f(real t) {return t < 0 ? -1/t : -0.5/t;}
+
+picture logo(pair s=0, pen q)
+{
+ picture pic;
+ pen p=linewidth(3)+q;
+ real a=-0.5;
+ real b=1;
+ real eps=0.1;
+ draw(pic,shift((eps,-f(a)))*graph(f,a,-eps),p);
+ real c=0.5*a;
+ pair z=(0,f(c)-f(a));
+ draw(pic,z+c+eps--z,p);
+ yaxis(pic,p);
+ return shift(s)*pic;
+}
+
+add(logo(red));
diff --git a/Build/source/utils/asymptote/doc/image.asy b/Build/source/utils/asymptote/doc/image.asy
new file mode 100644
index 00000000000..3270c06e31e
--- /dev/null
+++ b/Build/source/utils/asymptote/doc/image.asy
@@ -0,0 +1,22 @@
+size(12cm,12cm);
+
+import graph;
+import palette;
+
+int n=256;
+real ninv=2pi/n;
+real[][] v=new real[n][n];
+
+for(int i=0; i < n; ++i)
+ for(int j=0; j < n; ++j)
+ v[i][j]=sin(i*ninv)*cos(j*ninv);
+
+pen[] Palette=BWRainbow();
+
+picture bar;
+
+bounds range=image(v,(0,0),(1,1),Palette);
+palette(bar,"$A$",range,(0,0),(0.5cm,8cm),Right,Palette,
+ PaletteTicks("$%+#.1f$"));
+add(bar.fit(),point(E),30E);
+
diff --git a/Build/source/utils/asymptote/doc/imagecontour.asy b/Build/source/utils/asymptote/doc/imagecontour.asy
new file mode 100644
index 00000000000..25fdb3f6ed4
--- /dev/null
+++ b/Build/source/utils/asymptote/doc/imagecontour.asy
@@ -0,0 +1,40 @@
+import graph;
+import palette;
+import contour;
+
+size(10cm,10cm,IgnoreAspect);
+
+pair a=(0,0);
+pair b=(2pi,2pi);
+
+real f(real x, real y) {return cos(x)*sin(y);}
+
+int N=200;
+int Divs=10;
+int divs=2;
+
+defaultpen(1bp);
+pen Tickpen=black;
+pen tickpen=gray+0.5*linewidth(currentpen);
+pen[] Palette=BWRainbow();
+
+scale(false);
+
+bounds range=image(f,Automatic,a,b,N,Palette);
+
+// Major contours
+
+real[] Cvals=uniform(range.min,range.max,Divs);
+draw(contour(f,a,b,Cvals,N,operator --),Tickpen);
+
+// Minor contours
+real[] cvals;
+for(int i=0; i < Cvals.length-1; ++i)
+ cvals.append(uniform(Cvals[i],Cvals[i+1],divs)[1:divs]);
+draw(contour(f,a,b,cvals,N,operator --),tickpen);
+
+xaxis("$x$",BottomTop,LeftTicks,above=true);
+yaxis("$y$",LeftRight,RightTicks,above=true);
+
+palette("$f(x,y)$",range,point(NW)+(0,0.5),point(NE)+(0,1),Top,Palette,
+ PaletteTicks(N=Divs,n=divs,Tickpen,tickpen));
diff --git a/Build/source/utils/asymptote/doc/install-sh b/Build/source/utils/asymptote/doc/install-sh
new file mode 120000
index 00000000000..255ee584656
--- /dev/null
+++ b/Build/source/utils/asymptote/doc/install-sh
@@ -0,0 +1 @@
+../install-sh \ No newline at end of file
diff --git a/Build/source/utils/asymptote/doc/irregularcontour.asy b/Build/source/utils/asymptote/doc/irregularcontour.asy
new file mode 100644
index 00000000000..b72ddd0e08b
--- /dev/null
+++ b/Build/source/utils/asymptote/doc/irregularcontour.asy
@@ -0,0 +1,19 @@
+import contour;
+
+size(200);
+
+int n=100;
+
+pair[] points=new pair[n];
+real[] values=new real[n];
+
+real f(real a, real b) {return a^2+b^2;}
+
+real r() {return 1.1*(rand()/randMax*2-1);}
+
+for(int i=0; i < n; ++i) {
+ points[i]=(r(),r());
+ values[i]=f(points[i].x,points[i].y);
+}
+
+draw(contour(points,values,new real[]{0.25,0.5,1},operator ..),blue);
diff --git a/Build/source/utils/asymptote/doc/join.asy b/Build/source/utils/asymptote/doc/join.asy
new file mode 100644
index 00000000000..75fa14f36ca
--- /dev/null
+++ b/Build/source/utils/asymptote/doc/join.asy
@@ -0,0 +1,15 @@
+size(300,0);
+pair[] z=new pair[10];
+
+z[0]=(0,100); z[1]=(50,0); z[2]=(180,0);
+
+for(int n=3; n <= 9; ++n)
+ z[n]=z[n-3]+(200,0);
+
+path p=z[0]..z[1]---z[2]::{up}z[3]
+&z[3]..z[4]--z[5]::{up}z[6]
+&z[6]::z[7]---z[8]..{up}z[9];
+
+draw(p,grey+linewidth(4mm));
+
+dot(z);
diff --git a/Build/source/utils/asymptote/doc/join3.asy b/Build/source/utils/asymptote/doc/join3.asy
new file mode 100644
index 00000000000..62d5faaaee6
--- /dev/null
+++ b/Build/source/utils/asymptote/doc/join3.asy
@@ -0,0 +1,24 @@
+import graph3;
+
+size(200);
+
+currentprojection=orthographic(500,-500,500);
+
+triple[] z=new triple[10];
+
+z[0]=(0,100,0); z[1]=(50,0,0); z[2]=(180,0,0);
+
+for(int n=3; n <= 9; ++n)
+ z[n]=z[n-3]+(200,0,0);
+
+path3 p=z[0]..z[1]---z[2]::{Y}z[3]
+&z[3]..z[4]--z[5]::{Y}z[6]
+&z[6]::z[7]---z[8]..{Y}z[9];
+
+draw(p,grey+linewidth(4mm)+opacity(0.5));
+
+xaxis3(Label(XY()*"$x$",align=-3Y),red,above=true);
+yaxis3(Label(XY()*"$y$",align=-3X),red,above=true);
+
+dot(z);
+
diff --git a/Build/source/utils/asymptote/doc/knots.asy b/Build/source/utils/asymptote/doc/knots.asy
new file mode 100644
index 00000000000..48881459d05
--- /dev/null
+++ b/Build/source/utils/asymptote/doc/knots.asy
@@ -0,0 +1,27 @@
+import syzygy;
+
+Braid initial;
+initial.n = 4;
+initial.add(bp,1);
+initial.add(bp,0);
+initial.add(bp,2);
+initial.add(bp,1);
+initial.add(phi,2);
+initial.add(phi,0);
+
+Syzygy pp;
+pp.lsym="\Phi\Phi"; pp.codename="PhiAroundPhi";
+
+pp.number=true;
+pp.initial=initial;
+pp.apply(r4b,2,1);
+pp.apply(r4b,0,0);
+pp.apply(r4a,1,0);
+pp.swap(0,1);
+pp.apply(-r4b,1,0);
+pp.apply(-r4a,0,1);
+pp.apply(-r4a,2,0);
+pp.swap(4,5);
+
+pp.draw();
+
diff --git a/Build/source/utils/asymptote/doc/labelsquare.asy b/Build/source/utils/asymptote/doc/labelsquare.asy
new file mode 100644
index 00000000000..193314ae4d4
--- /dev/null
+++ b/Build/source/utils/asymptote/doc/labelsquare.asy
@@ -0,0 +1,6 @@
+size(0,3cm);
+draw(unitsquare);
+label("$A$",(0,0),SW);
+label("$B$",(1,0),SE);
+label("$C$",(1,1),NE);
+label("$D$",(0,1),NW);
diff --git a/Build/source/utils/asymptote/doc/latexusage.tex b/Build/source/utils/asymptote/doc/latexusage.tex
new file mode 100644
index 00000000000..5c10c4f83d9
--- /dev/null
+++ b/Build/source/utils/asymptote/doc/latexusage.tex
@@ -0,0 +1,112 @@
+\documentclass[12pt]{article}
+
+% Use this form to include EPS (latex) or PDF (pdflatex) files:
+\usepackage{asymptote}
+
+% Use this form with latex or pdflatex to include inline LaTeX code:
+%\usepackage[inline]{asymptote}
+
+% Enable this line to support PDF hyperlinks:
+%\usepackage[setpagesize=false]{hyperref}
+
+% Enable this line for PDF attachments with asy environment option attach=true:
+%\usepackage[dvips]{attachfile2}
+
+\begin{document}
+
+\begin{asydef}
+// Global Asymptote definitions can be put here.
+usepackage("bm");
+texpreamble("\def\V#1{\bm{#1}}");
+// One can globally override the default toolbar settings here:
+// settings.toolbar=true;
+\end{asydef}
+
+Here is a venn diagram produced with Asymptote, drawn to width 4cm:
+
+\def\A{A}
+\def\B{\V{B}}
+
+%\begin{figure}
+\begin{center}
+\begin{asy}
+size(4cm,0);
+pen colour1=red;
+pen colour2=green;
+
+pair z0=(0,0);
+pair z1=(-1,0);
+pair z2=(1,0);
+real r=1.5;
+path c1=circle(z1,r);
+path c2=circle(z2,r);
+fill(c1,colour1);
+fill(c2,colour2);
+
+picture intersection=new picture;
+fill(intersection,c1,colour1+colour2);
+clip(intersection,c2);
+
+add(intersection);
+
+draw(c1);
+draw(c2);
+
+//draw("$\A$",box,z1); // Requires [inline] package option.
+//draw(Label("$\B$","$B$"),box,z2); // Requires [inline] package option.
+draw("$A$",box,z1);
+draw("$\V{B}$",box,z2);
+
+pair z=(0,-2);
+real m=3;
+margin BigMargin=Margin(0,m*dot(unit(z1-z),unit(z0-z)));
+
+draw(Label("$A\cap B$",0),conj(z)--z0,Arrow,BigMargin);
+draw(Label("$A\cup B$",0),z--z0,Arrow,BigMargin);
+draw(z--z1,Arrow,Margin(0,m));
+draw(z--z2,Arrow,Margin(0,m));
+
+shipout(bbox(0.25cm));
+\end{asy}
+%\caption{Venn diagram}\label{venn}
+\end{center}
+%\end{figure}
+
+Each graph is drawn in its own environment. One can specify the width
+and height to \LaTeX\ explicitly. This 3D example can be viewed
+interactively either with Adobe Reader or Asymptote's fast OpenGL-based
+renderer. It is often desirable to embed such files as annotated attachments;
+this requires the optional \verb+\usepackage{attachfile2}+ package and
+the \verb+{attach=true}+ option:
+\begin{center}
+\begin{asy}[height=4cm,attach=false]
+import three;
+draw(unitcube,blue);
+label("$V-E+F=2$",(0,1,0.5),3Y,blue+fontsize(17));
+\end{asy}
+\end{center}
+
+One can also scale the figure to the full line width:
+\begin{center}
+\begin{asy}[width=\the\linewidth]
+pair z0=(0,0);
+pair z1=(2,0);
+pair z2=(5,0);
+pair zf=z1+0.75*(z2-z1);
+
+draw(z1--z2);
+dot(z1,red+0.15cm);
+dot(z2,darkgreen+0.3cm);
+label("$m$",z1,1.2N,red);
+label("$M$",z2,1.5N,darkgreen);
+label("$\hat{\ }$",zf,0.2*S,fontsize(24)+blue);
+
+pair s=-0.2*I;
+draw("$x$",z0+s--z1+s,N,red,Arrows,Bars,PenMargins);
+s=-0.5*I;
+draw("$\bar{x}$",z0+s--zf+s,blue,Arrows,Bars,PenMargins);
+s=-0.95*I;
+draw("$X$",z0+s--z2+s,darkgreen,Arrows,Bars,PenMargins);
+\end{asy}
+\end{center}
+\end{document}
diff --git a/Build/source/utils/asymptote/doc/leastsquares.asy b/Build/source/utils/asymptote/doc/leastsquares.asy
new file mode 100644
index 00000000000..c2f3e027aae
--- /dev/null
+++ b/Build/source/utils/asymptote/doc/leastsquares.asy
@@ -0,0 +1,55 @@
+size(400,200,IgnoreAspect);
+
+import graph;
+import stats;
+
+file fin=line(input("leastsquares.dat"));
+
+real[][] a=dimension(fin,0,0);
+a=transpose(a);
+
+real[] t=a[0], rho=a[1];
+
+// Read in parameters from the keyboard:
+//real first=getreal("first");
+//real step=getreal("step");
+//real last=getreal("last");
+
+real first=100;
+real step=50;
+real last=700;
+
+// Remove negative or zero values of rho:
+t=rho > 0 ? t : null;
+rho=rho > 0 ? rho : null;
+
+scale(Log(true),Linear(true));
+
+int n=step > 0 ? ceil((last-first)/step) : 0;
+
+real[] T,xi,dxi;
+
+for(int i=0; i <= n; ++i) {
+ real first=first+i*step;
+ real[] logrho=(t >= first & t <= last) ? log(rho) : null;
+ real[] logt=(t >= first & t <= last) ? -log(t) : null;
+
+ if(logt.length < 2) break;
+
+ // Fit to the line logt=L.m*logrho+L.b:
+ linefit L=leastsquares(logt,logrho);
+
+ T.push(first);
+ xi.push(L.m);
+ dxi.push(L.dm);
+}
+
+draw(graph(T,xi),blue);
+errorbars(T,xi,dxi,red);
+
+crop();
+
+ylimits(0);
+
+xaxis("$T$",BottomTop,LeftTicks);
+yaxis("$\xi$",LeftRight,RightTicks);
diff --git a/Build/source/utils/asymptote/doc/leastsquares.dat b/Build/source/utils/asymptote/doc/leastsquares.dat
new file mode 100644
index 00000000000..a4d63d6e100
--- /dev/null
+++ b/Build/source/utils/asymptote/doc/leastsquares.dat
@@ -0,0 +1,882 @@
+1 3825
+2 4057
+3 4217
+4 4278
+5 4353
+6 4483
+7 4410
+8 4462
+9 4626
+10 4511
+11 4531
+12 4450
+13 4354
+14 4402
+15 4489
+16 4441
+17 4366
+18 4443
+19 4442
+20 4335
+21 4292
+22 4458
+23 4444
+24 4426
+25 4310
+26 4264
+27 4263
+28 4252
+29 4330
+30 4304
+31 4242
+32 4272
+33 4284
+34 4198
+35 4242
+36 4096
+37 4142
+38 4248
+39 4186
+40 4210
+41 4125
+42 4134
+43 4098
+44 4129
+45 3960
+46 4012
+47 4079
+48 4038
+49 4024
+50 3949
+51 3996
+52 3970
+53 4031
+54 3895
+55 3806
+56 3825
+57 3850
+58 3742
+59 3678
+60 3589
+61 3648
+62 3476
+63 3490
+64 3353
+65 3270
+66 3134
+67 3018
+68 2922
+69 2801
+70 2691
+71 2528
+72 2460
+73 2254
+74 2105
+75 2009
+76 1854
+77 1677
+78 1562
+79 1501
+80 1399
+81 1244
+82 1160
+83 1080
+84 963
+85 879
+86 797
+87 745
+88 701
+89 634
+90 554
+91 532
+92 549
+93 521
+94 466
+95 460
+96 435
+97 412
+98 376
+99 367
+100 350
+101 360
+102 321
+103 302
+104 291
+105 273
+106 261
+107 255
+108 231
+109 245
+110 252
+111 236
+112 227
+113 207
+114 196
+115 199
+116 211
+117 232
+118 220
+119 214
+120 229
+121 213
+122 208
+123 196
+124 218
+125 196
+126 192
+127 178
+128 177
+129 178
+130 179
+131 170
+132 173
+133 170
+134 150
+135 144
+136 149
+137 145
+138 145
+139 139
+140 147
+141 140
+142 128
+143 133
+144 156
+145 136
+146 164
+147 152
+148 140
+149 141
+150 112
+151 108
+152 110
+153 133
+154 118
+155 113
+156 113
+157 108
+158 88
+159 109
+160 97
+161 99
+162 94
+163 97
+164 104
+165 105
+166 118
+167 108
+168 130
+169 126
+170 114
+171 112
+172 107
+173 96
+174 96
+175 102
+176 85
+177 89
+178 93
+179 96
+180 101
+181 82
+182 97
+183 96
+184 94
+185 97
+186 85
+187 79
+188 72
+189 75
+190 63
+191 65
+192 62
+193 54
+194 53
+195 49
+196 55
+197 48
+198 53
+199 46
+200 50
+201 48
+202 50
+203 51
+204 50
+205 49
+206 46
+207 47
+208 44
+209 42
+210 47
+211 45
+212 44
+213 46
+214 43
+215 40
+216 42
+217 41
+218 40
+219 43
+220 41
+221 42
+222 43
+223 40
+224 42
+225 39
+226 41
+227 42
+228 44
+229 40
+230 40
+231 35
+232 38
+233 37
+234 36
+235 34
+236 34
+237 34
+238 36
+239 36
+240 36
+241 37
+242 37
+243 37
+244 36
+245 36
+246 45
+247 43
+248 43
+249 43
+250 49
+251 58
+252 48
+253 50
+254 56
+255 51
+256 50
+257 55
+258 64
+259 55
+260 49
+261 36
+262 36
+263 40
+264 49
+265 37
+266 35
+267 35
+268 33
+269 33
+270 39
+271 35
+272 34
+273 36
+274 32
+275 37
+276 31
+277 31
+278 32
+279 30
+280 32
+281 29
+282 31
+283 30
+284 30
+285 28
+286 27
+287 26
+288 24
+289 25
+290 28
+291 30
+292 29
+293 27
+294 27
+295 27
+296 26
+297 26
+298 28
+299 27
+300 24
+301 22
+302 27
+303 26
+304 25
+305 25
+306 25
+307 26
+308 28
+309 26
+310 25
+311 24
+312 26
+313 25
+314 23
+315 25
+316 24
+317 23
+318 23
+319 24
+320 23
+321 24
+322 22
+323 24
+324 24
+325 24
+326 23
+327 25
+328 24
+329 22
+330 22
+331 23
+332 23
+333 23
+334 21
+335 19
+336 20
+337 22
+338 26
+339 25
+340 24
+341 22
+342 22
+343 23
+344 23
+345 23
+346 20
+347 21
+348 20
+349 21
+350 25
+351 22
+352 22
+353 21
+354 24
+355 24
+356 22
+357 23
+358 26
+359 24
+360 23
+361 22
+362 26
+363 30
+364 27
+365 25
+366 26
+367 26
+368 25
+369 24
+370 24
+371 22
+372 21
+373 20
+374 20
+375 19
+376 20
+377 21
+378 20
+379 20
+380 19
+381 19
+382 19
+383 19
+384 20
+385 20
+386 19
+387 20
+388 20
+389 20
+390 17
+391 18
+392 16
+393 18
+394 32
+395 31
+396 47
+397 57
+398 64
+399 34
+400 42
+401 40
+402 41
+403 35
+404 26
+405 25
+406 25
+407 36
+408 42
+409 55
+410 75
+411 94
+412 87
+413 97
+414 95
+415 101
+416 70
+417 66
+418 66
+419 73
+420 77
+421 89
+422 79
+423 63
+424 66
+425 71
+426 70
+427 49
+428 46
+429 46
+430 43
+431 49
+432 48
+433 44
+434 36
+435 33
+436 28
+437 29
+438 32
+439 31
+440 29
+441 28
+442 29
+443 31
+444 31
+445 33
+446 33
+447 39
+448 44
+449 37
+450 58
+451 64
+452 38
+453 31
+454 36
+455 33
+456 29
+457 34
+458 28
+459 27
+460 23
+461 31
+462 26
+463 21
+464 23
+465 26
+466 21
+467 21
+468 24
+469 24
+470 24
+471 24
+472 26
+473 23
+474 26
+475 20
+476 21
+477 25
+478 21
+479 22
+480 22
+481 23
+482 22
+483 23
+484 22
+485 20
+486 22
+487 20
+488 22
+489 20
+490 24
+491 20
+492 22
+493 19
+494 19
+495 20
+496 19
+497 18
+498 18
+499 17
+500 16
+501 16
+502 17
+503 17
+504 16
+505 17
+506 16
+507 16
+508 16
+509 17
+510 18
+511 17
+512 16
+513 17
+514 16
+515 16
+516 16
+517 17
+518 16
+519 16
+520 16
+521 16
+522 16
+523 16
+524 16
+525 16
+526 16
+527 17
+528 17
+529 18
+530 17
+531 16
+532 15
+533 15
+534 15
+535 15
+536 16
+537 17
+538 16
+539 18
+540 17
+541 17
+542 15
+543 15
+544 15
+545 16
+546 15
+547 15
+548 15
+549 15
+550 15
+551 14
+552 14
+553 14
+554 14
+555 14
+556 14
+557 14
+558 15
+559 14
+560 16
+561 15
+562 16
+563 17
+564 15
+565 14
+566 17
+567 18
+568 17
+569 16
+570 17
+571 14
+572 15
+573 15
+574 15
+575 14
+576 15
+577 14
+578 14
+579 13
+580 13
+581 13
+582 13
+583 13
+584 12
+585 12
+586 13
+587 12
+588 12
+589 12
+590 13
+591 15
+592 16
+593 14
+594 13
+595 14
+596 13
+597 13
+598 13
+599 13
+600 14
+601 13
+602 13
+603 13
+604 14
+605 15
+606 15
+607 15
+608 15
+609 15
+610 15
+611 15
+612 15
+613 15
+614 15
+615 15
+616 14
+617 14
+618 14
+619 14
+620 14
+621 14
+622 14
+623 15
+624 15
+625 15
+626 14
+627 15
+628 14
+629 14
+630 14
+631 14
+632 14
+633 14
+634 13
+635 13
+636 13
+637 13
+638 13
+639 13
+640 13
+641 13
+642 13
+643 13
+644 13
+645 13
+646 13
+647 13
+648 13
+649 13
+650 13
+651 13
+652 13
+653 13
+654 13
+655 13
+656 13
+657 13
+658 13
+659 13
+660 13
+661 13
+662 13
+663 13
+664 13
+665 13
+666 13
+667 13
+668 13
+669 13
+670 13
+671 13
+672 13
+673 13
+674 13
+675 13
+676 13
+677 13
+678 13
+679 12
+680 12
+681 13
+682 13
+683 13
+684 13
+685 12
+686 12
+687 13
+688 13
+689 13
+690 13
+691 13
+692 13
+693 13
+694 13
+695 13
+696 13
+697 13
+698 13
+699 13
+700 13
+701 13
+702 13
+703 13
+704 13
+705 13
+706 13
+707 13
+708 13
+709 13
+710 13
+711 13
+712 13
+713 13
+714 13
+715 13
+716 13
+717 13
+718 13
+719 13
+720 13
+721 13
+722 13
+723 13
+724 13
+725 13
+726 13
+727 13
+728 13
+729 13
+730 13
+731 13
+732 13
+733 13
+734 13
+735 13
+736 13
+737 13
+738 13
+739 13
+740 13
+741 13
+742 13
+743 13
+744 13
+745 13
+746 13
+747 13
+748 13
+749 13
+750 13
+751 13
+752 13
+753 13
+754 13
+755 12
+756 12
+757 12
+758 12
+759 11
+760 12
+761 11
+762 12
+763 11
+764 12
+765 12
+766 12
+767 12
+768 14
+769 14
+770 14
+771 14
+772 12
+773 12
+774 12
+775 13
+776 13
+777 13
+778 12
+779 13
+780 13
+781 13
+782 13
+783 13
+784 13
+785 12
+786 11
+787 11
+788 11
+789 12
+790 13
+791 13
+792 13
+793 12
+794 13
+795 13
+796 13
+797 13
+798 13
+799 12
+800 12
+801 12
+802 12
+803 12
+804 12
+805 11
+806 11
+807 11
+808 12
+809 13
+810 13
+811 12
+812 12
+813 12
+814 12
+815 12
+816 12
+817 12
+818 12
+819 12
+820 13
+821 13
+822 13
+823 13
+824 12
+825 13
+826 12
+827 13
+828 13
+829 13
+830 13
+831 12
+832 12
+833 12
+834 13
+835 13
+836 12
+837 9
+838 9
+839 10
+840 10
+841 11
+842 11
+843 11
+844 12
+845 12
+846 11
+847 12
+848 12
+849 12
+850 12
+851 12
+852 12
+853 12
+854 12
+855 12
+856 11
+857 10
+858 11
+859 12
+860 11
+861 11
+862 11
+863 10
+864 10
+865 10
+866 11
+867 10
+868 10
+869 10
+870 11
+871 11
+872 12
+873 12
+874 12
+875 12
+876 12
+877 12
+878 12
+879 12
+880 12
+881 0
+882 0
diff --git a/Build/source/utils/asymptote/doc/legend.asy b/Build/source/utils/asymptote/doc/legend.asy
new file mode 100644
index 00000000000..09a31868ae4
--- /dev/null
+++ b/Build/source/utils/asymptote/doc/legend.asy
@@ -0,0 +1,15 @@
+import graph;
+size(8cm,6cm,IgnoreAspect);
+
+typedef real realfcn(real);
+realfcn F(real p) {
+ return new real(real x) {return sin(p*x);};
+};
+
+for(int i=1; i < 5; ++i)
+ draw(graph(F(i*pi),0,1),Pen(i),
+ "$\sin("+(i == 1 ? "" : (string) i)+"\pi x)$");
+xaxis("$x$",BottomTop,LeftTicks);
+yaxis("$y$",LeftRight,RightTicks(trailingzero));
+
+attach(legend(2),(point(S).x,truepoint(S).y),10S,UnFill);
diff --git a/Build/source/utils/asymptote/doc/lineargraph.asy b/Build/source/utils/asymptote/doc/lineargraph.asy
new file mode 100644
index 00000000000..c352311ee72
--- /dev/null
+++ b/Build/source/utils/asymptote/doc/lineargraph.asy
@@ -0,0 +1,16 @@
+import graph;
+
+size(250,200,IgnoreAspect);
+
+real Sin(real t) {return sin(2pi*t);}
+real Cos(real t) {return cos(2pi*t);}
+
+draw(graph(Sin,0,1),red,"$\sin(2\pi x)$");
+draw(graph(Cos,0,1),blue,"$\cos(2\pi x)$");
+
+xaxis("$x$",BottomTop,LeftTicks);
+yaxis("$y$",LeftRight,RightTicks(trailingzero));
+
+label("LABEL",point(0),UnFill(1mm));
+
+attach(legend(),truepoint(E),20E,UnFill);
diff --git a/Build/source/utils/asymptote/doc/lineargraph0.asy b/Build/source/utils/asymptote/doc/lineargraph0.asy
new file mode 100644
index 00000000000..fc344181d51
--- /dev/null
+++ b/Build/source/utils/asymptote/doc/lineargraph0.asy
@@ -0,0 +1,16 @@
+import graph;
+
+size(400,200,IgnoreAspect);
+
+real Sin(real t) {return sin(2pi*t);}
+real Cos(real t) {return cos(2pi*t);}
+
+draw(graph(Sin,0,1),red,"$\sin(2\pi x)$");
+draw(graph(Cos,0,1),blue,"$\cos(2\pi x)$");
+
+xaxis("$x$",BottomTop,LeftTicks);
+yaxis("$y$",LeftRight,RightTicks(trailingzero));
+
+label("LABEL",point(0),UnFill(1mm));
+
+add(legend(),point(E),20E,UnFill);
diff --git a/Build/source/utils/asymptote/doc/linetype.asy b/Build/source/utils/asymptote/doc/linetype.asy
new file mode 100644
index 00000000000..dc4762c2478
--- /dev/null
+++ b/Build/source/utils/asymptote/doc/linetype.asy
@@ -0,0 +1,13 @@
+void testline(real y) {
+ draw((0,y)--(100,y),currentpen+solid);
+ draw((0,y-10)--(100,y-10),currentpen+dotted);
+ draw((0,y-20)--(100,y-20),currentpen+dashed);
+ draw((0,y-30)--(100,y-30),currentpen+longdashed);
+ draw((0,y-40)--(100,y-40),currentpen+dashdotted);
+ draw((0,y-50)--(100,y-50),currentpen+longdashdotted);
+ draw((0,y-60)--(100,y-60),currentpen+Dotted);
+}
+
+currentpen=linewidth(0.5);
+testline(100);
+
diff --git a/Build/source/utils/asymptote/doc/log2graph.asy b/Build/source/utils/asymptote/doc/log2graph.asy
new file mode 100644
index 00000000000..238f4126274
--- /dev/null
+++ b/Build/source/utils/asymptote/doc/log2graph.asy
@@ -0,0 +1,17 @@
+import graph;
+size(200,IgnoreAspect);
+
+// Base-2 logarithmic scale on y-axis:
+
+real log2(real x) {static real log2=log(2); return log(x)/log2;}
+real pow2(real x) {return 2^x;}
+
+scaleT yscale=scaleT(log2,pow2,logarithmic=true);
+scale(Linear,yscale);
+
+real f(real x) {return 1+x^2;}
+
+draw(graph(f,-4,4));
+
+yaxis("$y$",ymin=1,ymax=f(5),RightTicks(Label(Fill(white))),EndArrow);
+xaxis("$x$",xmin=-5,xmax=5,LeftTicks,EndArrow);
diff --git a/Build/source/utils/asymptote/doc/loggraph.asy b/Build/source/utils/asymptote/doc/loggraph.asy
new file mode 100644
index 00000000000..9dee2ffbbff
--- /dev/null
+++ b/Build/source/utils/asymptote/doc/loggraph.asy
@@ -0,0 +1,18 @@
+import graph;
+
+size(200,200,IgnoreAspect);
+
+real f(real t) {return 1/t;}
+
+scale(Log,Log);
+
+draw(graph(f,0.1,10));
+
+//xlimits(1,10);
+//ylimits(0.1,1);
+
+dot(Label("(3,5)",align=S),Scale((3,5)));
+
+xaxis("$x$",BottomTop,LeftTicks);
+yaxis("$y$",LeftRight,RightTicks);
+
diff --git a/Build/source/utils/asymptote/doc/loggrid.asy b/Build/source/utils/asymptote/doc/loggrid.asy
new file mode 100644
index 00000000000..bb48a1e4ca8
--- /dev/null
+++ b/Build/source/utils/asymptote/doc/loggrid.asy
@@ -0,0 +1,13 @@
+import graph;
+size(200,200,IgnoreAspect);
+
+real f(real t) {return 1/t;}
+
+scale(Log,Log);
+draw(graph(f,0.1,10),red);
+pen thin=linewidth(0.5*linewidth());
+xaxis("$x$",BottomTop,LeftTicks(begin=false,end=false,extend=true,
+ ptick=thin));
+yaxis("$y$",LeftRight,RightTicks(begin=false,end=false,extend=true,
+ ptick=thin));
+
diff --git a/Build/source/utils/asymptote/doc/logimage.asy b/Build/source/utils/asymptote/doc/logimage.asy
new file mode 100644
index 00000000000..65d6bb53111
--- /dev/null
+++ b/Build/source/utils/asymptote/doc/logimage.asy
@@ -0,0 +1,22 @@
+import graph;
+import palette;
+
+size(10cm,10cm,IgnoreAspect);
+
+real f(real x, real y) {
+ return 0.9*pow10(2*sin(x/5+2*y^0.25)) + 0.1*(1+cos(10*log(y)));
+}
+
+scale(Linear,Log,Log);
+
+pen[] Palette=BWRainbow();
+
+bounds range=image(f,Automatic,(0,1),(100,100),nx=200,Palette);
+
+xaxis("$x$",BottomTop,LeftTicks,above=true);
+yaxis("$y$",LeftRight,RightTicks,above=true);
+
+palette("$f(x,y)$",range,(0,200),(100,250),Top,Palette,
+ PaletteTicks(ptick=linewidth(0.5*linewidth())));
+
+
diff --git a/Build/source/utils/asymptote/doc/logo.asy b/Build/source/utils/asymptote/doc/logo.asy
new file mode 100644
index 00000000000..3cd20a573f4
--- /dev/null
+++ b/Build/source/utils/asymptote/doc/logo.asy
@@ -0,0 +1,28 @@
+size(140,80,IgnoreAspect);
+
+picture logo(pair s=0, pen q)
+{
+ picture pic;
+ pen p=linewidth(2)+fontsize(24)+q;
+ real a=-0.4;
+ real b=0.95;
+ real y1=-5;
+ real y2=-3y1/2;
+ path A=(a,0){dir(10)}::{dir(89.5)}(0,y2);
+ draw(pic,A,p);
+ draw(pic,(0,y1){dir(88.3)}::{dir(20)}(b,0),p);
+ real c=0.5*a;
+ pair z=(0,2.5);
+ label(pic,"{\it symptote}",z,0.25*E+0.169S,p);
+ pair w=(0,1.7);
+ draw(pic,intersectionpoint(A,w-1--w)--w,p);
+ draw(pic,(0,y1)--(0,y2),p);
+ draw(pic,(a,0)--(b,0),p);
+ return shift(s)*pic;
+}
+
+pair z=(-0.015,0.08);
+for(int x=0; x < 10; ++x)
+ add(logo(0.1*x*z,gray(0.04*x)));
+
+add(logo(red));
diff --git a/Build/source/utils/asymptote/doc/logticks.asy b/Build/source/utils/asymptote/doc/logticks.asy
new file mode 100644
index 00000000000..bdd14411692
--- /dev/null
+++ b/Build/source/utils/asymptote/doc/logticks.asy
@@ -0,0 +1,11 @@
+import graph;
+
+size(300,175,IgnoreAspect);
+scale(Log,Log);
+draw(graph(identity,5,20));
+xlimits(5,20);
+ylimits(1,100);
+xaxis("$M/M_\odot$",BottomTop,LeftTicks(DefaultFormat,
+ new real[] {6,10,12,14,16,18}));
+yaxis("$\nu_{\rm upp}$ [Hz]",LeftRight,RightTicks(DefaultFormat));
+
diff --git a/Build/source/utils/asymptote/doc/makepen.asy b/Build/source/utils/asymptote/doc/makepen.asy
new file mode 100644
index 00000000000..7c7868a0901
--- /dev/null
+++ b/Build/source/utils/asymptote/doc/makepen.asy
@@ -0,0 +1,9 @@
+size(200);
+pen convex=makepen(scale(10)*polygon(8))+grey;
+draw((1,0.4),convex);
+draw((0,0)---(1,1)..(2,0)--cycle,convex);
+
+pen nonconvex=scale(10)*
+ makepen((0,0)--(0.25,-1)--(0.5,0.25)--(1,0)--(0.5,1.25)--cycle)+red;
+draw((0.5,-1.5),nonconvex);
+draw((0,-1.5)..(1,-0.5)..(2,-1.5),nonconvex);
diff --git a/Build/source/utils/asymptote/doc/markers1.asy b/Build/source/utils/asymptote/doc/markers1.asy
new file mode 100644
index 00000000000..a3af424616d
--- /dev/null
+++ b/Build/source/utils/asymptote/doc/markers1.asy
@@ -0,0 +1,102 @@
+size(12cm,0);
+import markers;
+
+pair A=(0,0), B=(1,0), C=(2,0), D=(3,0);
+path p=A--B--C--D;
+transform T=shift(-4,-1);
+transform t=shift(4,0);
+
+//line 1 **********
+draw(p,marker(markinterval(3,dotframe,true)));
+label("$1$",point(p,0),3W);
+
+//line 2 **********
+p=t*p;
+draw(p,marker(stickframe,markuniform(4)));
+label("$2$",point(p,0),3W);
+
+//line 3 **********
+p=T*p;
+draw(p,marker(stickframe(red),markinterval(3,dotframe(blue),true)));
+label("$3$",point(p,0),3W);
+
+//line 4 **********
+p=t*p;
+draw(p,StickIntervalMarker(3,2,blue,dotframe(red)));
+label("$4$",point(p,0),3W);
+
+//line 5 **********
+p=T*p;
+pen pn=linewidth(4bp);
+draw(p,pn,StickIntervalMarker(3,3,angle=25,pn,dotframe(red+pn)));
+label("$5$",point(p,0),3W);
+
+//line 6 **********
+p=t*p;
+draw(p,StickIntervalMarker(3,5,angle=25,size=4mm,space=2mm,offset=I*2mm,
+ scale(2)*dotframe(red)));
+label("$6$",point(p,0),3W);
+
+//line 7 **********
+p=T*p;
+draw(p,StickIntervalMarker(n=3,angle=45,size=10mm,space=3mm,dotframe));
+label("$7$",point(p,0),3W);
+
+//line 8 **********
+p=t*p;
+draw(p,CircleBarIntervalMarker(n=2,dotframe));
+label("$8$",point(p,0),3W);
+
+//line 9 **********
+p=T*p;
+draw(p,CircleBarIntervalMarker(n=3,angle=30,barsize=8mm,radius=2mm,
+ FillDraw(.8red),
+ dotframe));
+label("$9$",point(p,0),3W);
+
+//line 10 **********
+p=t*p;
+draw(p,CircleBarIntervalMarker(n=3,angle=30,barsize=8mm,radius=2mm,
+ FillDraw(.8red),circleabove=true,dotframe));
+label("$10$",point(p,0),3W);
+
+//line 11 **********
+p=T*p;
+draw(p,CircleBarIntervalMarker(n=3,angle=30,barsize=8mm,radius=2mm,
+ FillDraw(.8red),circleabove=true,dotframe,
+ above=false));
+label("$11$",point(p,0),3W);
+
+//line 12 **********
+p=t*p;
+draw(p,TildeIntervalMarker(i=3,dotframe));
+label("$12$",point(p,0),3W);
+
+//line 13 **********
+p=T*p;
+draw(p,TildeIntervalMarker(i=3,n=2,angle=-20,dotframe));
+label("$13$",point(p,0),3W);
+
+//line 14 **********
+p=t*p;
+draw(p,CrossIntervalMarker(3,3,dotframe));
+label("$14$",point(p,0),3W);
+
+//line 15 **********
+p=shift(.25S)*T*p;
+path cle=shift(relpoint(p,.5))*scale(abs(A-D)/4)*unitcircle;
+draw(cle,StickIntervalMarker(5,3,dotframe(6bp+red)));
+label("$15$",point(p,0),3W);
+
+//line 16 **********
+cle=t*cle;
+p=t*p;
+frame a;
+label(a,"$a$",(0,-2labelmargin()));
+draw(cle,marker(dotframe(6bp+red),markinterval(5,a,true)));
+label("$16$",point(p,0),3W);
+
+// line 17 **********
+p=T*shift(relpoint(p,.5)+.65S)*scale(.5)*shift(-relpoint(p,.5))*rotate(45,relpoint(p,.5))*p;
+draw(p,TildeIntervalMarker(size=5mm,rotated=false,dotframe));
+label("$17$",point(p,0),3W);
diff --git a/Build/source/utils/asymptote/doc/markers2.asy b/Build/source/utils/asymptote/doc/markers2.asy
new file mode 100644
index 00000000000..b9c8ac21894
--- /dev/null
+++ b/Build/source/utils/asymptote/doc/markers2.asy
@@ -0,0 +1,34 @@
+size(10cm,0);
+import markers;
+import geometry;
+import math;
+
+pair A=0, B=(1,0), C=(0.7,1), D=(-0.5,0), F=rotate(-90)*(C-B)/2+B;
+
+draw(A--B);
+draw(A--C);
+pen p=linewidth(1mm);
+draw(B--C,p);
+draw(A--D);
+draw(B--F,p);
+label("$A$",A,SW);
+label("$B$",B,S);
+label("$C$",C,N);
+dot(Label("$D$",D,S));
+dot(Label("$F$",F,N+NW));
+
+markangle(A,C,B);
+
+markangle(scale(1.5)*"$\theta$",radius=40,C,B,A,ArcArrow(2mm),1mm+red);
+markangle(scale(1.5)*"$-\theta$",radius=-70,A,B,C,ArcArrow,green);
+
+markangle(Label("$\gamma$",Relative(0.25)),n=2,radius=-30,A,C,B,p=0.7blue+2);
+
+markangle(n=3,B,A,C,marker(markinterval(stickframe(n=2),true)));
+
+pen RedPen=0.7red+1bp;
+markangle(C,A,D,RedPen,marker(markinterval(2,stickframe(3,4mm,RedPen),true)));
+drawline(A,A+dir(A--D,A--C),dotted);
+
+perpendicular(B,NE,F-B,size=10mm,1mm+red,
+ TrueMargin(linewidth(p)/2,linewidth(p)/2),Fill(yellow));
diff --git a/Build/source/utils/asymptote/doc/mexicanhat.asy b/Build/source/utils/asymptote/doc/mexicanhat.asy
new file mode 100644
index 00000000000..d55b127ae5c
--- /dev/null
+++ b/Build/source/utils/asymptote/doc/mexicanhat.asy
@@ -0,0 +1,22 @@
+size(200);
+
+real mexican(real x) {return (1-8x^2)*exp(-(4x^2));}
+
+int n=30;
+real a=1.5;
+real width=2a/n;
+
+guide hat;
+path solved;
+
+for(int i=0; i < n; ++i) {
+ real t=-a+i*width;
+ pair z=(t,mexican(t));
+ hat=hat..z;
+ solved=solved..z;
+}
+
+draw(hat);
+dot(hat,red);
+draw(solved,dashed);
+
diff --git a/Build/source/utils/asymptote/doc/monthaxis.asy b/Build/source/utils/asymptote/doc/monthaxis.asy
new file mode 100644
index 00000000000..d2c8bf3298f
--- /dev/null
+++ b/Build/source/utils/asymptote/doc/monthaxis.asy
@@ -0,0 +1,17 @@
+import graph;
+
+size(400,150,IgnoreAspect);
+
+real[] x=sequence(12);
+real[] y=sin(2pi*x/12);
+
+scale(false);
+
+string[] month={"Jan","Feb","Mar","Apr","May","Jun",
+ "Jul","Aug","Sep","Oct","Nov","Dec"};
+
+draw(graph(x,y),red,MarkFill[0]);
+
+xaxis(BottomTop,LeftTicks(new string(real x) {
+ return month[round(x % 12)];}));
+yaxis("$y$",LeftRight,RightTicks(4));
diff --git a/Build/source/utils/asymptote/doc/multicontour.asy b/Build/source/utils/asymptote/doc/multicontour.asy
new file mode 100644
index 00000000000..5e4ea0c06f6
--- /dev/null
+++ b/Build/source/utils/asymptote/doc/multicontour.asy
@@ -0,0 +1,19 @@
+import contour;
+
+size(200);
+
+real f(real x, real y) {return x^2-y^2;}
+int n=10;
+real[] c=new real[n];
+for(int i=0; i < n; ++i) c[i]=(i-n/2)/n;
+
+pen[] p=sequence(new pen(int i) {
+ return (c[i] >= 0 ? solid : dashed)+fontsize(6);
+ },c.length);
+
+Label[] Labels=sequence(new Label(int i) {
+ return Label(c[i] != 0 ? (string) c[i] : "",Relative(unitrand()),(0,0),
+ UnFill(1bp));
+ },c.length);
+
+draw(Labels,contour(f,(-1,-1),(1,1),c),p);
diff --git a/Build/source/utils/asymptote/doc/onecontour.asy b/Build/source/utils/asymptote/doc/onecontour.asy
new file mode 100644
index 00000000000..0d7f247fd39
--- /dev/null
+++ b/Build/source/utils/asymptote/doc/onecontour.asy
@@ -0,0 +1,5 @@
+import contour;
+size(75);
+
+real f(real a, real b) {return a^2+b^2;}
+draw(contour(f,(-1,-1),(1,1),new real[] {1}));
diff --git a/Build/source/utils/asymptote/doc/options b/Build/source/utils/asymptote/doc/options
new file mode 100644
index 00000000000..48d821dfa40
--- /dev/null
+++ b/Build/source/utils/asymptote/doc/options
@@ -0,0 +1,75 @@
+Usage: ../asy [options] [file ...]
+
+Options (negate by replacing - with -no):
+
+-V,-View View output; command-line only
+-a,-align C|B|T|Z Center, Bottom, Top, or Zero page alignment [Center]
+-antialias n Antialiasing width for rasterized output [2]
+-auto3D Automatically activate 3D scene [true]
+-autoimport string Module to automatically import
+-autoplain Enable automatic importing of plain [true]
+-autorotate Enable automatic PDF page rotation [false]
+-batchMask Mask fpu exceptions in batch mode [false]
+-batchView View output in batch mode [false]
+-bw Convert all colors to black and white [false]
+-cd directory Set current directory; command-line only
+-cmyk Convert rgb colors to cmyk [false]
+-c,-command string Command to autoexecute
+-compact Conserve memory at the expense of speed [false]
+-d,-debug Enable debugging messages [false]
+-divisor n Garbage collect using purge(divisor=n) [2]
+-embed Embed rendered preview image [true]
+-exitonEOF Exit interactive mode on EOF [true]
+-fitscreen Fit rendered image to screen [true]
+-globalwrite Allow write to other directory [false]
+-gray Convert all colors to grayscale [false]
+-h,-help Show summary of options; command-line only
+-historylines n Retain n lines of history [1000]
+-iconify Iconify rendering window [false]
+-inlineimage Generate inline embedded image [false]
+-inlinetex Generate inline TeX code [false]
+-interactiveMask Mask fpu exceptions in interactive mode [true]
+-interactiveView View output in interactive mode [true]
+-interactiveWrite Write expressions entered at the prompt to stdout [true]
+-k,-keep Keep intermediate files [false]
+-keepaux Keep intermediate LaTeX .aux files [false]
+-level n Postscript level [3]
+-l,-listvariables List available global functions and variables [false]
+-localhistory Use a local interactive history file [false]
+-m,-mask Mask fpu exceptions; command-line only
+-maxtile pair Maximum rendering tile size [(0,0)]
+-maxviewport pair Maximum viewport size [(2048,2048)]
+-multiline Input code over multiple lines at the prompt [false]
+-multipleView View output from multiple batch-mode files [false]
+-multisample n Multisampling width for screen images [4]
+-O,-offset pair PostScript offset [(0,0)]
+-f,-outformat format Convert each output file to specified format
+-o,-outname name Alternative output directory/filename
+-p,-parseonly Parse file [false]
+-pdfreload Automatically reload document in pdfviewer [false]
+-pdfreloaddelay usec Delay before attempting initial pdf reload [750000]
+-position pair Initial 3D rendering screen position [(0,0)]
+-prc Embed 3D PRC graphics in PDF output [true]
+-prompt string Prompt [> ]
+-prompt2 string Continuation prompt for multiline input [..]
+-q,-quiet Suppress welcome message [false]
+-render n Render 3D graphics using n pixels per bp (-1=auto) [-1]
+-rgb Convert cmyk colors to rgb [false]
+-safe Disable system call [true]
+-scroll n Scroll standard output n lines at a time [0]
+-tabcompletion Interactive prompt auto-completion [true]
+-tex engine latex|pdflatex|xelatex|tex|pdftex|none [latex]
+-thick Render thick 3D lines [true]
+-thin Render thin 3D lines [true]
+-threads Use POSIX threads for 3D rendering [true]
+-toolbar Show 3D toolbar in PDF output [true]
+-s,-translate Show translated virtual machine code [false]
+-twice Run LaTeX twice (to resolve references) [false]
+-twosided Use two-sided 3D lighting model for rendering [true]
+-u,-user string General purpose user string
+-v,-verbose Increase verbosity level [0]
+-version Show version; command-line only
+-wait Wait for child processes to finish before exiting [false]
+-where Show where listed variables are declared [false]
+-xformat format GUI deconstruction format [png]
+
diff --git a/Build/source/utils/asymptote/doc/parametricgraph.asy b/Build/source/utils/asymptote/doc/parametricgraph.asy
new file mode 100644
index 00000000000..a5688a6f9dd
--- /dev/null
+++ b/Build/source/utils/asymptote/doc/parametricgraph.asy
@@ -0,0 +1,16 @@
+import graph;
+
+size(0,200);
+
+real x(real t) {return cos(2pi*t);}
+real y(real t) {return sin(2pi*t);}
+
+draw(graph(x,y,0,1));
+
+//xlimits(0,1,Crop);
+//ylimits(-1,0,Crop);
+
+xaxis("$x$",BottomTop,LeftTicks);
+yaxis("$y$",LeftRight,RightTicks(trailingzero));
+
+
diff --git a/Build/source/utils/asymptote/doc/penimage.asy b/Build/source/utils/asymptote/doc/penimage.asy
new file mode 100644
index 00000000000..2aef9f9ebe2
--- /dev/null
+++ b/Build/source/utils/asymptote/doc/penimage.asy
@@ -0,0 +1,14 @@
+size(200);
+
+import palette;
+
+int n=256;
+real ninv=2pi/n;
+pen[][] v=new pen[n][n];
+
+for(int i=0; i < n; ++i)
+ for(int j=0; j < n; ++j)
+ v[i][j]=rgb(0.5*(1+sin(i*ninv)),0.5*(1+cos(j*ninv)),0);
+
+image(v,(0,0),(1,1));
+
diff --git a/Build/source/utils/asymptote/doc/pixel.pdf b/Build/source/utils/asymptote/doc/pixel.pdf
new file mode 100644
index 00000000000..de3d0820da2
--- /dev/null
+++ b/Build/source/utils/asymptote/doc/pixel.pdf
Binary files differ
diff --git a/Build/source/utils/asymptote/doc/planes.asy b/Build/source/utils/asymptote/doc/planes.asy
new file mode 100644
index 00000000000..da859200f03
--- /dev/null
+++ b/Build/source/utils/asymptote/doc/planes.asy
@@ -0,0 +1,19 @@
+size(6cm,0);
+import bsp;
+
+real u=2.5;
+real v=1;
+
+currentprojection=oblique;
+
+path3 y=plane((2u,0,0),(0,2v,0),(-u,-v,0));
+path3 l=rotate(90,Z)*rotate(90,Y)*y;
+path3 g=rotate(90,X)*rotate(90,Y)*y;
+
+face[] faces;
+filldraw(faces.push(y),project(y),yellow);
+filldraw(faces.push(l),project(l),lightgrey);
+filldraw(faces.push(g),project(g),green);
+
+add(faces);
+
diff --git a/Build/source/utils/asymptote/doc/png/Makefile b/Build/source/utils/asymptote/doc/png/Makefile
new file mode 100644
index 00000000000..dba4da51890
--- /dev/null
+++ b/Build/source/utils/asymptote/doc/png/Makefile
@@ -0,0 +1,46 @@
+ASYFILES = $(notdir $(wildcard ../*.asy)) latexusage.asy
+SOURCE = ../asymptote.texi ../version.texi ../options
+ASY = ../asy -dir ../base -config "" -render=0
+
+docdir = $(DESTDIR)/usr/local/share/doc/asymptote
+infodir = $(DESTDIR)${datarootdir}/info
+datarootdir = ${prefix}/share
+INSTALL = /usr/bin/ginstall -c
+
+all: html info
+
+%.png: ../%.asy
+ cd ..; $(ASY) -f png -o png/ $(notdir $<)
+
+latexusage.png: ../latexusage.eps
+ convert -alpha Off -density 144x144 +antialias -geometry 50%x \
+ ../latexusage.eps latexusage.png
+
+index.html: $(SOURCE) $(ASYFILES:.asy=.png)
+ makeinfo --html ../asymptote -o .
+
+asymptote.info: $(SOURCE) $(ASYFILES:.asy=.png)
+ makeinfo ../asymptote
+
+html: index.html
+
+info: asymptote.info
+
+clean: FORCE
+ -rm -f *.png *.html asymptote.info* texput.aux texput.log
+
+distclean:
+ -rm -f Makefile
+
+install:
+ ${INSTALL} -d -m 755 $(infodir)
+ ${INSTALL} -p -m 644 asymptote.info $(infodir)
+ -${INSTALL} -p -m 644 asymptote.info-* $(infodir)
+ -if test -z "$(DESTDIR)"; then \
+ install-info --infodir=$(infodir) asymptote.info; \
+ fi
+
+uninstall:
+ -install-info --remove --infodir=$(infodir) asymptote.info
+ -rm -f $(infodir)/asymptote.info $(infodir)/asymptote.info-*
+FORCE:
diff --git a/Build/source/utils/asymptote/doc/png/Makefile.in b/Build/source/utils/asymptote/doc/png/Makefile.in
new file mode 100644
index 00000000000..d49c9813578
--- /dev/null
+++ b/Build/source/utils/asymptote/doc/png/Makefile.in
@@ -0,0 +1,46 @@
+ASYFILES = $(notdir $(wildcard ../*.asy)) latexusage.asy
+SOURCE = ../asymptote.texi ../version.texi ../options
+ASY = ../asy -dir ../base -config "" -render=0
+
+docdir = $(DESTDIR)@docdir@
+infodir = $(DESTDIR)@infodir@
+datarootdir = @datarootdir@
+INSTALL = @INSTALL@
+
+all: html info
+
+%.png: ../%.asy
+ cd ..; $(ASY) -f png -o png/ $(notdir $<)
+
+latexusage.png: ../latexusage.eps
+ convert -alpha Off -density 144x144 +antialias -geometry 50%x \
+ ../latexusage.eps latexusage.png
+
+index.html: $(SOURCE) $(ASYFILES:.asy=.png)
+ makeinfo --html ../asymptote -o .
+
+asymptote.info: $(SOURCE) $(ASYFILES:.asy=.png)
+ makeinfo ../asymptote
+
+html: index.html
+
+info: asymptote.info
+
+clean: FORCE
+ -rm -f *.png *.html asymptote.info* texput.aux texput.log
+
+distclean:
+ -rm -f Makefile
+
+install:
+ ${INSTALL} -d -m 755 $(infodir)
+ ${INSTALL} -p -m 644 asymptote.info $(infodir)
+ -${INSTALL} -p -m 644 asymptote.info-* $(infodir)
+ -if test -z "$(DESTDIR)"; then \
+ install-info --infodir=$(infodir) asymptote.info; \
+ fi
+
+uninstall:
+ -install-info --remove --infodir=$(infodir) asymptote.info
+ -rm -f $(infodir)/asymptote.info $(infodir)/asymptote.info-*
+FORCE:
diff --git a/Build/source/utils/asymptote/doc/quartercircle.asy b/Build/source/utils/asymptote/doc/quartercircle.asy
new file mode 100644
index 00000000000..5c584a10e9e
--- /dev/null
+++ b/Build/source/utils/asymptote/doc/quartercircle.asy
@@ -0,0 +1,2 @@
+size(100,0);
+draw((1,0){up}..{left}(0,1));
diff --git a/Build/source/utils/asymptote/doc/reloadpdf.tex b/Build/source/utils/asymptote/doc/reloadpdf.tex
new file mode 100644
index 00000000000..f203af1699b
--- /dev/null
+++ b/Build/source/utils/asymptote/doc/reloadpdf.tex
@@ -0,0 +1,11 @@
+% Tex file for generating the reloadpdf.pdf utility to force Adobe Reader
+% to reload all currently loaded documents. Usage:
+%
+% pdflatex reloadpdf
+% acroread reloadpdf.pdf
+%
+\documentclass{article}
+\begin{document}
+\ \pdfannot width 0pt height 0pt { /AA << /PO << /S /JavaScript /JS
+ (try{reload();} catch(e) {} closeDoc(this);) >> >> }
+\end{document}
diff --git a/Build/source/utils/asymptote/doc/saddle.asy b/Build/source/utils/asymptote/doc/saddle.asy
new file mode 100644
index 00000000000..0180bf125a6
--- /dev/null
+++ b/Build/source/utils/asymptote/doc/saddle.asy
@@ -0,0 +1,7 @@
+import three;
+
+size(100,0);
+path3 g=(1,0,0)..(0,1,1)..(-1,0,0)..(0,-1,1)..cycle;
+draw(g);
+draw(((-1,-1,0)--(1,-1,0)--(1,1,0)--(-1,1,0)--cycle));
+dot(g,red);
diff --git a/Build/source/utils/asymptote/doc/scaledgraph.asy b/Build/source/utils/asymptote/doc/scaledgraph.asy
new file mode 100644
index 00000000000..408c10cc582
--- /dev/null
+++ b/Build/source/utils/asymptote/doc/scaledgraph.asy
@@ -0,0 +1,15 @@
+import graph;
+
+axiscoverage=0.9;
+size(200,IgnoreAspect);
+
+real[] x={-1e-11,1e-11};
+real[] y={0,1e6};
+
+real xscale=round(log10(max(x)));
+real yscale=round(log10(max(y)))-1;
+
+draw(graph(x*10^(-xscale),y*10^(-yscale)),red);
+
+xaxis("$x/10^{"+(string) xscale+"}$",BottomTop,LeftTicks);
+yaxis("$y/10^{"+(string) yscale+"}$",LeftRight,RightTicks(trailingzero));
diff --git a/Build/source/utils/asymptote/doc/secondaryaxis.asy b/Build/source/utils/asymptote/doc/secondaryaxis.asy
new file mode 100644
index 00000000000..527675f2f51
--- /dev/null
+++ b/Build/source/utils/asymptote/doc/secondaryaxis.asy
@@ -0,0 +1,32 @@
+import graph;
+
+size(9cm,6cm,IgnoreAspect);
+string data="secondaryaxis.csv";
+
+file in=line(csv(input(data)));
+
+string[] titlelabel=in;
+string[] columnlabel=in;
+
+real[][] a=dimension(in,0,0);
+a=transpose(a);
+real[] t=a[0], susceptible=a[1], infectious=a[2], dead=a[3], larvae=a[4];
+real[] susceptibleM=a[5], exposed=a[6],infectiousM=a[7];
+
+scale(true);
+
+draw(graph(t,susceptible,t >= 10 & t <= 15));
+draw(graph(t,dead,t >= 10 & t <= 15),dashed);
+
+xaxis("Time ($\tau$)",BottomTop,LeftTicks);
+yaxis(Left,RightTicks);
+
+picture secondary=secondaryY(new void(picture pic) {
+ scale(pic,Linear(true),Log(true));
+ draw(pic,graph(pic,t,infectious,t >= 10 & t <= 15),red);
+ yaxis(pic,Right,red,LeftTicks(begin=false,end=false));
+ });
+
+add(secondary);
+label(shift(5mm*N)*"Proportion of crows",point(NW),E);
+
diff --git a/Build/source/utils/asymptote/doc/secondaryaxis.csv b/Build/source/utils/asymptote/doc/secondaryaxis.csv
new file mode 100644
index 00000000000..082d45a0e71
--- /dev/null
+++ b/Build/source/utils/asymptote/doc/secondaryaxis.csv
@@ -0,0 +1,1003 @@
+,"Proportion of crows",,,"Mosquitoes per crow",,,
+Time,Susceptible,Infectious,Dead,Larvae,Susceptible,Exposed,Infectious
+0,1,0,0,,30,0.000,0.001
+0.1,1.000,0.000,0.000,12.794,30.000,0.000,0.001
+0.2,1.000,0.000,0.000,12.794,30.000,0.000,0.001
+0.3,1.000,0.000,0.000,12.795,30.000,0.000,0.001
+0.4,1.000,0.000,0.000,12.795,30.000,0.000,0.001
+0.5,1.000,0.000,0.000,12.795,30.000,0.000,0.001
+0.6,1.000,0.000,0.000,12.795,30.000,0.000,0.001
+0.7,1.000,0.000,0.000,12.795,30.000,0.000,0.001
+0.8,0.999,0.000,0.000,12.795,30.000,0.000,0.001
+0.9,0.999,0.000,0.000,12.795,29.999,0.001,0.001
+1,0.999,0.000,0.000,12.795,29.999,0.001,0.001
+1.1,0.999,0.000,0.000,12.795,29.999,0.001,0.001
+1.2,0.999,0.000,0.000,12.795,29.999,0.001,0.001
+1.3,0.999,0.000,0.000,12.795,29.999,0.001,0.001
+1.4,0.999,0.000,0.001,12.795,29.999,0.001,0.001
+1.5,0.999,0.001,0.001,12.795,29.999,0.001,0.001
+1.6,0.999,0.001,0.001,12.795,29.999,0.001,0.001
+1.7,0.999,0.001,0.001,12.795,29.998,0.001,0.001
+1.8,0.999,0.001,0.001,12.795,29.998,0.001,0.001
+1.9,0.998,0.001,0.001,12.795,29.998,0.001,0.002
+2,0.998,0.001,0.001,12.795,29.998,0.001,0.002
+2.1,0.998,0.001,0.001,12.795,29.998,0.002,0.002
+2.2,0.998,0.001,0.001,12.795,29.998,0.002,0.002
+2.3,0.998,0.001,0.001,12.795,29.997,0.002,0.002
+2.4,0.998,0.001,0.001,12.795,29.997,0.002,0.002
+2.5,0.998,0.001,0.002,12.795,29.997,0.002,0.002
+2.6,0.997,0.001,0.002,12.795,29.997,0.002,0.002
+2.7,0.997,0.001,0.002,12.795,29.996,0.002,0.003
+2.8,0.997,0.001,0.002,12.795,29.996,0.002,0.003
+2.9,0.997,0.001,0.002,12.795,29.996,0.002,0.003
+3,0.997,0.001,0.002,12.795,29.995,0.003,0.003
+3.1,0.996,0.001,0.002,12.795,29.995,0.003,0.003
+3.2,0.996,0.001,0.003,12.795,29.995,0.003,0.003
+3.3,0.996,0.001,0.003,12.795,29.994,0.003,0.004
+3.4,0.996,0.001,0.003,12.795,29.994,0.003,0.004
+3.5,0.995,0.002,0.003,12.795,29.994,0.003,0.004
+3.6,0.995,0.002,0.003,12.795,29.993,0.004,0.004
+3.7,0.995,0.002,0.004,12.795,29.993,0.004,0.004
+3.8,0.994,0.002,0.004,12.795,29.992,0.004,0.005
+3.9,0.994,0.002,0.004,12.795,29.992,0.004,0.005
+4,0.994,0.002,0.004,12.795,29.991,0.005,0.005
+4.1,0.993,0.002,0.005,12.795,29.991,0.005,0.006
+4.2,0.993,0.002,0.005,12.795,29.990,0.005,0.006
+4.3,0.992,0.002,0.005,12.795,29.989,0.005,0.006
+4.4,0.992,0.003,0.006,12.795,29.989,0.006,0.007
+4.5,0.991,0.003,0.006,12.795,29.988,0.006,0.007
+4.6,0.991,0.003,0.006,12.795,29.987,0.006,0.008
+4.7,0.990,0.003,0.007,12.795,29.986,0.007,0.008
+4.8,0.990,0.003,0.007,12.795,29.985,0.007,0.008
+4.9,0.989,0.003,0.008,12.795,29.984,0.008,0.009
+5,0.988,0.004,0.008,12.795,29.984,0.008,0.009
+5.1,0.988,0.004,0.009,12.795,29.982,0.008,0.010
+5.2,0.987,0.004,0.009,12.795,29.981,0.009,0.011
+5.3,0.986,0.004,0.010,12.795,29.980,0.010,0.011
+5.4,0.985,0.005,0.010,12.795,29.979,0.010,0.012
+5.5,0.984,0.005,0.011,12.795,29.978,0.011,0.013
+5.6,0.983,0.005,0.012,12.795,29.976,0.011,0.013
+5.7,0.982,0.005,0.012,12.795,29.975,0.012,0.014
+5.8,0.981,0.006,0.013,12.795,29.973,0.013,0.015
+5.9,0.980,0.006,0.014,12.795,29.972,0.013,0.016
+6,0.979,0.006,0.015,12.795,29.970,0.014,0.017
+6.1,0.978,0.007,0.016,12.795,29.968,0.015,0.018
+6.2,0.976,0.007,0.016,12.795,29.966,0.016,0.019
+6.3,0.975,0.008,0.017,12.795,29.964,0.017,0.020
+6.4,0.973,0.008,0.019,12.795,29.962,0.018,0.021
+6.5,0.972,0.008,0.020,12.795,29.960,0.019,0.022
+6.6,0.970,0.009,0.021,12.795,29.957,0.020,0.024
+6.7,0.968,0.009,0.022,12.795,29.955,0.021,0.025
+6.8,0.967,0.010,0.023,12.795,29.952,0.022,0.026
+6.9,0.965,0.011,0.025,12.795,29.949,0.024,0.028
+7,0.963,0.011,0.026,12.795,29.946,0.025,0.030
+7.1,0.960,0.012,0.028,12.795,29.943,0.026,0.031
+7.2,0.958,0.013,0.029,12.795,29.940,0.028,0.033
+7.3,0.956,0.013,0.031,12.795,29.936,0.029,0.035
+7.4,0.953,0.014,0.033,12.795,29.933,0.031,0.037
+7.5,0.950,0.015,0.035,12.795,29.929,0.033,0.039
+7.6,0.947,0.016,0.037,12.795,29.925,0.035,0.042
+7.7,0.944,0.016,0.039,12.795,29.920,0.037,0.044
+7.8,0.941,0.017,0.041,12.795,29.916,0.039,0.046
+7.9,0.938,0.018,0.044,12.795,29.911,0.041,0.049
+8,0.934,0.019,0.046,12.795,29.906,0.043,0.052
+8.1,0.931,0.020,0.049,12.795,29.900,0.046,0.055
+8.2,0.927,0.021,0.052,12.795,29.895,0.048,0.058
+8.3,0.923,0.023,0.055,12.795,29.889,0.051,0.061
+8.4,0.918,0.024,0.058,12.795,29.883,0.054,0.065
+8.5,0.914,0.025,0.061,12.795,29.876,0.056,0.069
+8.6,0.909,0.026,0.065,12.795,29.869,0.059,0.072
+8.7,0.904,0.028,0.068,12.795,29.862,0.063,0.076
+8.8,0.899,0.029,0.072,12.795,29.854,0.066,0.081
+8.9,0.893,0.031,0.076,12.795,29.846,0.070,0.085
+9,0.887,0.032,0.080,12.795,29.838,0.073,0.090
+9.1,0.881,0.034,0.085,12.795,29.829,0.077,0.095
+9.2,0.875,0.036,0.090,12.795,29.820,0.081,0.100
+9.3,0.868,0.037,0.095,12.795,29.810,0.085,0.106
+9.4,0.861,0.039,0.100,12.795,29.800,0.090,0.112
+9.5,0.854,0.041,0.105,12.795,29.789,0.094,0.118
+9.6,0.846,0.043,0.111,12.795,29.778,0.099,0.124
+9.7,0.838,0.045,0.117,12.795,29.766,0.104,0.131
+9.8,0.830,0.047,0.123,12.795,29.754,0.109,0.138
+9.9,0.821,0.049,0.130,12.795,29.742,0.114,0.145
+10,0.812,0.052,0.136,12.795,29.729,0.120,0.153
+10.1,0.802,0.054,0.144,12.795,29.715,0.126,0.161
+10.2,0.793,0.056,0.151,12.795,29.701,0.132,0.169
+10.3,0.782,0.059,0.159,12.795,29.686,0.138,0.178
+10.4,0.772,0.061,0.167,12.795,29.670,0.144,0.187
+10.5,0.761,0.064,0.175,12.795,29.654,0.150,0.196
+10.6,0.750,0.066,0.184,12.795,29.638,0.157,0.206
+10.7,0.738,0.069,0.193,12.795,29.621,0.164,0.216
+10.8,0.726,0.072,0.203,12.795,29.603,0.171,0.227
+10.9,0.713,0.074,0.212,12.795,29.585,0.178,0.238
+11,0.700,0.077,0.223,12.795,29.566,0.185,0.250
+11.1,0.687,0.080,0.233,12.795,29.547,0.193,0.261
+11.2,0.674,0.082,0.244,12.795,29.527,0.200,0.274
+11.3,0.660,0.085,0.255,12.795,29.507,0.208,0.286
+11.4,0.645,0.088,0.267,12.795,29.486,0.215,0.300
+11.5,0.631,0.090,0.279,12.795,29.465,0.223,0.313
+11.6,0.616,0.093,0.291,12.795,29.443,0.231,0.327
+11.7,0.601,0.095,0.304,12.795,29.421,0.238,0.341
+11.8,0.585,0.098,0.317,12.795,29.399,0.246,0.356
+11.9,0.570,0.100,0.330,12.795,29.376,0.254,0.371
+12,0.554,0.102,0.344,12.795,29.353,0.261,0.386
+12.1,0.538,0.104,0.358,12.795,29.330,0.269,0.402
+12.2,0.521,0.106,0.372,12.795,29.307,0.276,0.418
+12.3,0.505,0.108,0.387,12.795,29.283,0.283,0.434
+12.4,0.489,0.110,0.401,12.795,29.260,0.290,0.451
+12.5,0.472,0.112,0.416,12.795,29.236,0.297,0.468
+12.6,0.456,0.113,0.432,12.795,29.213,0.303,0.485
+12.7,0.439,0.114,0.447,12.795,29.190,0.309,0.502
+12.8,0.423,0.115,0.462,12.795,29.167,0.315,0.519
+12.9,0.406,0.116,0.478,12.795,29.144,0.320,0.536
+13,0.390,0.116,0.494,12.795,29.122,0.325,0.554
+13.1,0.374,0.117,0.509,12.795,29.100,0.329,0.571
+13.2,0.358,0.117,0.525,12.795,29.079,0.333,0.588
+13.3,0.343,0.117,0.541,12.795,29.059,0.337,0.606
+13.4,0.327,0.116,0.557,12.795,29.039,0.340,0.623
+13.5,0.312,0.116,0.572,12.795,29.020,0.342,0.639
+13.6,0.297,0.115,0.588,12.795,29.001,0.344,0.656
+13.7,0.283,0.114,0.603,12.795,28.984,0.345,0.672
+13.8,0.269,0.113,0.618,12.795,28.967,0.346,0.688
+13.9,0.255,0.111,0.634,12.795,28.952,0.346,0.704
+14,0.242,0.109,0.648,12.795,28.937,0.345,0.719
+14.1,0.229,0.108,0.663,12.795,28.924,0.344,0.733
+14.2,0.217,0.106,0.677,12.795,28.912,0.342,0.747
+14.3,0.205,0.103,0.692,12.795,28.900,0.340,0.761
+14.4,0.194,0.101,0.705,12.795,28.891,0.337,0.774
+14.5,0.183,0.099,0.719,12.795,28.882,0.333,0.786
+14.6,0.172,0.096,0.732,12.795,28.874,0.329,0.797
+14.7,0.162,0.093,0.745,12.795,28.868,0.325,0.808
+14.8,0.153,0.090,0.757,12.795,28.863,0.320,0.818
+14.9,0.143,0.087,0.769,12.795,28.860,0.314,0.827
+15,0.135,0.084,0.781,12.795,28.857,0.308,0.836
+15.1,0.127,0.081,0.792,12.795,28.856,0.302,0.843
+15.2,0.119,0.078,0.803,12.795,28.856,0.295,0.850
+15.3,0.112,0.075,0.813,12.795,28.857,0.288,0.856
+15.4,0.105,0.072,0.823,12.795,28.859,0.281,0.861
+15.5,0.098,0.069,0.833,12.795,28.863,0.273,0.865
+15.6,0.092,0.066,0.842,12.795,28.867,0.266,0.868
+15.7,0.086,0.063,0.850,12.795,28.873,0.258,0.870
+15.8,0.081,0.060,0.859,12.795,28.879,0.250,0.872
+15.9,0.076,0.058,0.867,12.795,28.887,0.242,0.873
+16,0.071,0.055,0.874,12.795,28.895,0.233,0.873
+16.1,0.066,0.052,0.882,12.795,28.904,0.225,0.872
+16.2,0.062,0.049,0.888,12.795,28.914,0.217,0.870
+16.3,0.058,0.047,0.895,12.795,28.925,0.209,0.867
+16.4,0.055,0.044,0.901,12.795,28.936,0.201,0.864
+16.5,0.051,0.042,0.907,12.795,28.948,0.192,0.860
+16.6,0.048,0.040,0.912,12.795,28.961,0.185,0.856
+16.7,0.045,0.037,0.918,12.795,28.974,0.177,0.850
+16.8,0.042,0.035,0.922,12.795,28.988,0.169,0.844
+16.9,0.040,0.033,0.927,12.795,29.002,0.161,0.838
+17,0.037,0.031,0.931,12.795,29.016,0.154,0.831
+17.1,0.035,0.029,0.936,12.795,29.031,0.147,0.823
+17.2,0.033,0.028,0.939,12.795,29.046,0.140,0.815
+17.3,0.031,0.026,0.943,12.795,29.061,0.133,0.807
+17.4,0.029,0.024,0.946,12.795,29.077,0.126,0.798
+17.5,0.028,0.023,0.950,12.795,29.093,0.120,0.788
+17.6,0.026,0.021,0.953,12.795,29.108,0.114,0.779
+17.7,0.025,0.020,0.955,12.795,29.124,0.108,0.769
+17.8,0.023,0.019,0.958,12.795,29.141,0.102,0.758
+17.9,0.022,0.018,0.960,12.795,29.157,0.097,0.748
+18,0.021,0.017,0.963,12.795,29.173,0.092,0.737
+18.1,0.020,0.015,0.965,12.795,29.189,0.087,0.726
+18.2,0.019,0.014,0.967,12.795,29.205,0.082,0.714
+18.3,0.018,0.014,0.969,12.795,29.221,0.077,0.703
+18.4,0.017,0.013,0.971,12.795,29.237,0.073,0.691
+18.5,0.016,0.012,0.972,12.795,29.253,0.069,0.680
+18.6,0.015,0.011,0.974,12.795,29.268,0.065,0.668
+18.7,0.014,0.010,0.975,12.795,29.284,0.061,0.656
+18.8,0.014,0.010,0.977,12.795,29.299,0.057,0.644
+18.9,0.013,0.009,0.978,12.795,29.315,0.054,0.632
+19,0.012,0.008,0.979,12.795,29.330,0.051,0.620
+19.1,0.012,0.008,0.980,12.795,29.345,0.048,0.609
+19.2,0.011,0.007,0.981,12.795,29.359,0.045,0.597
+19.3,0.011,0.007,0.982,12.795,29.374,0.042,0.585
+19.4,0.010,0.007,0.983,12.795,29.388,0.040,0.573
+19.5,0.010,0.006,0.984,12.795,29.402,0.037,0.562
+19.6,0.010,0.006,0.985,12.795,29.416,0.035,0.550
+19.7,0.009,0.005,0.985,12.795,29.430,0.033,0.538
+19.8,0.009,0.005,0.986,12.795,29.443,0.031,0.527
+19.9,0.009,0.005,0.987,12.795,29.456,0.029,0.516
+20,0.008,0.004,0.987,12.795,29.469,0.027,0.505
+20.1,0.008,0.004,0.988,12.795,29.482,0.026,0.494
+20.2,0.008,0.004,0.989,12.795,29.494,0.024,0.483
+20.3,0.007,0.004,0.989,12.795,29.506,0.023,0.472
+20.4,0.007,0.003,0.990,12.795,29.518,0.021,0.461
+20.5,0.007,0.003,0.990,12.795,29.530,0.020,0.451
+20.6,0.007,0.003,0.990,12.795,29.541,0.019,0.441
+20.7,0.006,0.003,0.991,12.795,29.553,0.018,0.431
+20.8,0.006,0.003,0.991,12.795,29.564,0.017,0.421
+20.9,0.006,0.002,0.991,12.795,29.575,0.016,0.411
+21,0.006,0.002,0.992,12.795,29.585,0.015,0.401
+21.1,0.006,0.002,0.992,12.795,29.595,0.014,0.392
+21.2,0.006,0.002,0.992,12.795,29.605,0.013,0.383
+21.3,0.005,0.002,0.993,12.795,29.615,0.012,0.374
+21.4,0.005,0.002,0.993,12.795,29.625,0.011,0.365
+21.5,0.005,0.002,0.993,12.795,29.634,0.011,0.356
+21.6,0.005,0.002,0.993,12.795,29.644,0.010,0.347
+21.7,0.005,0.002,0.994,12.795,29.653,0.009,0.339
+21.8,0.005,0.001,0.994,12.795,29.661,0.009,0.331
+21.9,0.005,0.001,0.994,12.795,29.670,0.008,0.323
+22,0.004,0.001,0.994,12.795,29.678,0.008,0.315
+22.1,0.004,0.001,0.994,12.795,29.687,0.007,0.307
+22.2,0.004,0.001,0.995,12.795,29.695,0.007,0.299
+22.3,0.004,0.001,0.995,12.795,29.702,0.007,0.292
+22.4,0.004,0.001,0.995,12.795,29.710,0.006,0.285
+22.5,0.004,0.001,0.995,12.795,29.718,0.006,0.278
+22.6,0.004,0.001,0.995,12.795,29.725,0.006,0.271
+22.7,0.004,0.001,0.995,12.795,29.732,0.005,0.264
+22.8,0.004,0.001,0.995,12.795,29.739,0.005,0.257
+22.9,0.004,0.001,0.995,12.795,29.746,0.005,0.251
+23,0.004,0.001,0.996,12.795,29.752,0.004,0.244
+23.1,0.004,0.001,0.996,12.795,29.758,0.004,0.238
+23.2,0.004,0.001,0.996,12.795,29.765,0.004,0.232
+23.3,0.003,0.001,0.996,12.795,29.771,0.004,0.226
+23.4,0.003,0.001,0.996,12.795,29.777,0.004,0.221
+23.5,0.003,0.001,0.996,12.795,29.783,0.003,0.215
+23.6,0.003,0.001,0.996,12.795,29.788,0.003,0.210
+23.7,0.003,0.001,0.996,12.795,29.794,0.003,0.204
+23.8,0.003,0.001,0.996,12.795,29.799,0.003,0.199
+23.9,0.003,0.001,0.996,12.795,29.804,0.003,0.194
+24,0.003,0.000,0.996,12.795,29.809,0.003,0.189
+24.1,0.003,0.000,0.996,12.795,29.814,0.002,0.184
+24.2,0.003,0.000,0.997,12.795,29.819,0.002,0.179
+24.3,0.003,0.000,0.997,12.795,29.824,0.002,0.175
+24.4,0.003,0.000,0.997,12.795,29.829,0.002,0.170
+24.5,0.003,0.000,0.997,12.795,29.833,0.002,0.166
+24.6,0.003,0.000,0.997,12.795,29.838,0.002,0.162
+24.7,0.003,0.000,0.997,12.795,29.842,0.002,0.157
+24.8,0.003,0.000,0.997,12.795,29.846,0.002,0.153
+24.9,0.003,0.000,0.997,12.795,29.850,0.002,0.149
+25,0.003,0.000,0.997,12.795,29.854,0.002,0.145
+25.1,0.003,0.000,0.997,12.795,29.858,0.002,0.142
+25.2,0.003,0.000,0.997,12.795,29.862,0.001,0.138
+25.3,0.003,0.000,0.997,12.795,29.865,0.001,0.134
+25.4,0.003,0.000,0.997,12.795,29.869,0.001,0.131
+25.5,0.003,0.000,0.997,12.795,29.872,0.001,0.128
+25.6,0.003,0.000,0.997,12.795,29.876,0.001,0.124
+25.7,0.003,0.000,0.997,12.795,29.879,0.001,0.121
+25.8,0.003,0.000,0.997,12.795,29.882,0.001,0.118
+25.9,0.003,0.000,0.997,12.795,29.885,0.001,0.115
+26,0.002,0.000,0.997,12.795,29.888,0.001,0.112
+26.1,0.002,0.000,0.997,12.795,29.891,0.001,0.109
+26.2,0.002,0.000,0.997,12.795,29.894,0.001,0.106
+26.3,0.002,0.000,0.997,12.795,29.897,0.001,0.103
+26.4,0.002,0.000,0.997,12.795,29.900,0.001,0.101
+26.5,0.002,0.000,0.997,12.795,29.902,0.001,0.098
+26.6,0.002,0.000,0.997,12.795,29.905,0.001,0.095
+26.7,0.002,0.000,0.997,12.795,29.907,0.001,0.093
+26.8,0.002,0.000,0.997,12.795,29.910,0.001,0.090
+26.9,0.002,0.000,0.998,12.795,29.912,0.001,0.088
+27,0.002,0.000,0.998,12.795,29.915,0.001,0.086
+27.1,0.002,0.000,0.998,12.795,29.917,0.001,0.083
+27.2,0.002,0.000,0.998,12.795,29.919,0.001,0.081
+27.3,0.002,0.000,0.998,12.795,29.921,0.001,0.079
+27.4,0.002,0.000,0.998,12.795,29.923,0.001,0.077
+27.5,0.002,0.000,0.998,12.795,29.925,0.001,0.075
+27.6,0.002,0.000,0.998,12.795,29.927,0.001,0.073
+27.7,0.002,0.000,0.998,12.795,29.929,0.001,0.071
+27.8,0.002,0.000,0.998,12.795,29.931,0.001,0.069
+27.9,0.002,0.000,0.998,12.795,29.933,0.000,0.067
+28,0.002,0.000,0.998,12.795,29.935,0.000,0.066
+28.1,0.002,0.000,0.998,12.795,29.937,0.000,0.064
+28.2,0.002,0.000,0.998,12.795,29.938,0.000,0.062
+28.3,0.002,0.000,0.998,12.795,29.940,0.000,0.061
+28.4,0.002,0.000,0.998,12.795,29.942,0.000,0.059
+28.5,0.002,0.000,0.998,12.795,29.943,0.000,0.057
+28.6,0.002,0.000,0.998,12.795,29.945,0.000,0.056
+28.7,0.002,0.000,0.998,12.795,29.946,0.000,0.054
+28.8,0.002,0.000,0.998,12.795,29.948,0.000,0.053
+28.9,0.002,0.000,0.998,12.795,29.949,0.000,0.052
+29,0.002,0.000,0.998,12.795,29.950,0.000,0.050
+29.1,0.002,0.000,0.998,12.795,29.952,0.000,0.049
+29.2,0.002,0.000,0.998,12.795,29.953,0.000,0.048
+29.3,0.002,0.000,0.998,12.795,29.954,0.000,0.046
+29.4,0.002,0.000,0.998,12.795,29.955,0.000,0.045
+29.5,0.002,0.000,0.998,12.795,29.957,0.000,0.044
+29.6,0.002,0.000,0.998,12.795,29.958,0.000,0.043
+29.7,0.002,0.000,0.998,12.795,29.959,0.000,0.042
+29.8,0.002,0.000,0.998,12.795,29.960,0.000,0.041
+29.9,0.002,0.000,0.998,12.795,29.961,0.000,0.040
+30,0.002,0.000,0.998,12.795,29.962,0.000,0.039
+30.1,0.002,0.000,0.998,12.795,29.963,0.000,0.037
+30.2,0.002,0.000,0.998,12.795,29.964,0.000,0.037
+30.3,0.002,0.000,0.998,12.795,29.965,0.000,0.036
+30.4,0.002,0.000,0.998,12.795,29.966,0.000,0.035
+30.5,0.002,0.000,0.998,12.795,29.967,0.000,0.034
+30.6,0.002,0.000,0.998,12.795,29.968,0.000,0.033
+30.7,0.002,0.000,0.998,12.795,29.969,0.000,0.032
+30.8,0.002,0.000,0.998,12.795,29.970,0.000,0.031
+30.9,0.002,0.000,0.998,12.795,29.971,0.000,0.030
+31,0.002,0.000,0.998,12.795,29.971,0.000,0.029
+31.1,0.002,0.000,0.998,12.795,29.972,0.000,0.029
+31.2,0.002,0.000,0.998,12.795,29.973,0.000,0.028
+31.3,0.002,0.000,0.998,12.795,29.974,0.000,0.027
+31.4,0.002,0.000,0.998,12.795,29.974,0.000,0.026
+31.5,0.002,0.000,0.998,12.795,29.975,0.000,0.026
+31.6,0.002,0.000,0.998,12.795,29.976,0.000,0.025
+31.7,0.002,0.000,0.998,12.795,29.976,0.000,0.024
+31.8,0.002,0.000,0.998,12.795,29.977,0.000,0.024
+31.9,0.002,0.000,0.998,12.795,29.978,0.000,0.023
+32,0.002,0.000,0.998,12.795,29.978,0.000,0.023
+32.1,0.002,0.000,0.998,12.795,29.979,0.000,0.022
+32.2,0.002,0.000,0.998,12.795,29.979,0.000,0.021
+32.3,0.002,0.000,0.998,12.795,29.980,0.000,0.021
+32.4,0.002,0.000,0.998,12.795,29.981,0.000,0.020
+32.5,0.002,0.000,0.998,12.795,29.981,0.000,0.020
+32.6,0.002,0.000,0.998,12.795,29.982,0.000,0.019
+32.7,0.002,0.000,0.998,12.795,29.982,0.000,0.019
+32.8,0.002,0.000,0.998,12.795,29.983,0.000,0.018
+32.9,0.002,0.000,0.998,12.795,29.983,0.000,0.018
+33,0.002,0.000,0.998,12.795,29.984,0.000,0.017
+33.1,0.002,0.000,0.998,12.795,29.984,0.000,0.017
+33.2,0.002,0.000,0.998,12.795,29.985,0.000,0.016
+33.3,0.002,0.000,0.998,12.795,29.985,0.000,0.016
+33.4,0.002,0.000,0.998,12.795,29.985,0.000,0.015
+33.5,0.002,0.000,0.998,12.795,29.986,0.000,0.015
+33.6,0.002,0.000,0.998,12.795,29.986,0.000,0.015
+33.7,0.002,0.000,0.998,12.795,29.987,0.000,0.014
+33.8,0.002,0.000,0.998,12.795,29.987,0.000,0.014
+33.9,0.002,0.000,0.998,12.795,29.987,0.000,0.014
+34,0.002,0.000,0.998,12.795,29.988,0.000,0.013
+34.1,0.002,0.000,0.998,12.795,29.988,0.000,0.013
+34.2,0.002,0.000,0.998,12.795,29.988,0.000,0.012
+34.3,0.002,0.000,0.998,12.795,29.989,0.000,0.012
+34.4,0.002,0.000,0.998,12.795,29.989,0.000,0.012
+34.5,0.002,0.000,0.998,12.795,29.989,0.000,0.012
+34.6,0.002,0.000,0.998,12.795,29.990,0.000,0.011
+34.7,0.002,0.000,0.998,12.795,29.990,0.000,0.011
+34.8,0.002,0.000,0.998,12.795,29.990,0.000,0.011
+34.9,0.002,0.000,0.998,12.795,29.991,0.000,0.010
+35,0.002,0.000,0.998,12.795,29.991,0.000,0.010
+35.1,0.002,0.000,0.998,12.795,29.991,0.000,0.010
+35.2,0.002,0.000,0.998,12.795,29.991,0.000,0.010
+35.3,0.002,0.000,0.998,12.795,29.992,0.000,0.009
+35.4,0.002,0.000,0.998,12.795,29.992,0.000,0.009
+35.5,0.002,0.000,0.998,12.795,29.992,0.000,0.009
+35.6,0.002,0.000,0.998,12.795,29.992,0.000,0.009
+35.7,0.002,0.000,0.998,12.795,29.993,0.000,0.008
+35.8,0.002,0.000,0.998,12.795,29.993,0.000,0.008
+35.9,0.002,0.000,0.998,12.795,29.993,0.000,0.008
+36,0.002,0.000,0.998,12.795,29.993,0.000,0.008
+36.1,0.002,0.000,0.998,12.795,29.993,0.000,0.008
+36.2,0.002,0.000,0.998,12.795,29.994,0.000,0.007
+36.3,0.002,0.000,0.998,12.795,29.994,0.000,0.007
+36.4,0.002,0.000,0.998,12.795,29.994,0.000,0.007
+36.5,0.002,0.000,0.998,12.795,29.994,0.000,0.007
+36.6,0.002,0.000,0.998,12.795,29.994,0.000,0.007
+36.7,0.002,0.000,0.998,12.795,29.995,0.000,0.006
+36.8,0.002,0.000,0.998,12.795,29.995,0.000,0.006
+36.9,0.002,0.000,0.998,12.795,29.995,0.000,0.006
+37,0.002,0.000,0.998,12.795,29.995,0.000,0.006
+37.1,0.002,0.000,0.998,12.795,29.995,0.000,0.006
+37.2,0.002,0.000,0.998,12.795,29.995,0.000,0.006
+37.3,0.002,0.000,0.998,12.795,29.996,0.000,0.005
+37.4,0.002,0.000,0.998,12.795,29.996,0.000,0.005
+37.5,0.002,0.000,0.998,12.795,29.996,0.000,0.005
+37.6,0.002,0.000,0.998,12.795,29.996,0.000,0.005
+37.7,0.002,0.000,0.998,12.795,29.996,0.000,0.005
+37.8,0.002,0.000,0.998,12.795,29.996,0.000,0.005
+37.9,0.002,0.000,0.998,12.795,29.996,0.000,0.005
+38,0.002,0.000,0.998,12.795,29.996,0.000,0.005
+38.1,0.002,0.000,0.998,12.795,29.997,0.000,0.004
+38.2,0.002,0.000,0.998,12.795,29.997,0.000,0.004
+38.3,0.002,0.000,0.998,12.795,29.997,0.000,0.004
+38.4,0.002,0.000,0.998,12.795,29.997,0.000,0.004
+38.5,0.002,0.000,0.998,12.795,29.997,0.000,0.004
+38.6,0.002,0.000,0.998,12.795,29.997,0.000,0.004
+38.7,0.002,0.000,0.998,12.795,29.997,0.000,0.004
+38.8,0.002,0.000,0.998,12.795,29.997,0.000,0.004
+38.9,0.002,0.000,0.998,12.795,29.997,0.000,0.004
+39,0.002,0.000,0.998,12.795,29.998,0.000,0.003
+39.1,0.002,0.000,0.998,12.795,29.998,0.000,0.003
+39.2,0.002,0.000,0.998,12.795,29.998,0.000,0.003
+39.3,0.002,0.000,0.998,12.795,29.998,0.000,0.003
+39.4,0.002,0.000,0.998,12.795,29.998,0.000,0.003
+39.5,0.002,0.000,0.998,12.795,29.998,0.000,0.003
+39.6,0.002,0.000,0.998,12.795,29.998,0.000,0.003
+39.7,0.002,0.000,0.998,12.795,29.998,0.000,0.003
+39.8,0.002,0.000,0.998,12.795,29.998,0.000,0.003
+39.9,0.002,0.000,0.998,12.795,29.998,0.000,0.003
+40,0.002,0.000,0.998,12.795,29.998,0.000,0.003
+40.1,0.002,0.000,0.998,12.795,29.998,0.000,0.003
+40.2,0.002,0.000,0.998,12.795,29.998,0.000,0.002
+40.3,0.002,0.000,0.998,12.795,29.999,0.000,0.002
+40.4,0.002,0.000,0.998,12.795,29.999,0.000,0.002
+40.5,0.002,0.000,0.998,12.795,29.999,0.000,0.002
+40.6,0.002,0.000,0.998,12.795,29.999,0.000,0.002
+40.7,0.002,0.000,0.998,12.795,29.999,0.000,0.002
+40.8,0.002,0.000,0.998,12.795,29.999,0.000,0.002
+40.9,0.002,0.000,0.998,12.795,29.999,0.000,0.002
+41,0.002,0.000,0.998,12.795,29.999,0.000,0.002
+41.1,0.002,0.000,0.998,12.795,29.999,0.000,0.002
+41.2,0.002,0.000,0.998,12.795,29.999,0.000,0.002
+41.3,0.002,0.000,0.998,12.795,29.999,0.000,0.002
+41.4,0.002,0.000,0.998,12.795,29.999,0.000,0.002
+41.5,0.002,0.000,0.998,12.795,29.999,0.000,0.002
+41.6,0.002,0.000,0.998,12.795,29.999,0.000,0.002
+41.7,0.002,0.000,0.998,12.795,29.999,0.000,0.002
+41.8,0.002,0.000,0.998,12.795,29.999,0.000,0.002
+41.9,0.002,0.000,0.998,12.795,29.999,0.000,0.002
+42,0.002,0.000,0.998,12.795,29.999,0.000,0.002
+42.1,0.002,0.000,0.998,12.795,29.999,0.000,0.001
+42.2,0.002,0.000,0.998,12.795,30.000,0.000,0.001
+42.3,0.002,0.000,0.998,12.795,30.000,0.000,0.001
+42.4,0.002,0.000,0.998,12.795,30.000,0.000,0.001
+42.5,0.002,0.000,0.998,12.795,30.000,0.000,0.001
+42.6,0.002,0.000,0.998,12.795,30.000,0.000,0.001
+42.7,0.002,0.000,0.998,12.795,30.000,0.000,0.001
+42.8,0.002,0.000,0.998,12.795,30.000,0.000,0.001
+42.9,0.002,0.000,0.998,12.795,30.000,0.000,0.001
+43,0.002,0.000,0.998,12.795,30.000,0.000,0.001
+43.1,0.002,0.000,0.998,12.795,30.000,0.000,0.001
+43.2,0.002,0.000,0.998,12.795,30.000,0.000,0.001
+43.3,0.002,0.000,0.998,12.795,30.000,0.000,0.001
+43.4,0.002,0.000,0.998,12.795,30.000,0.000,0.001
+43.5,0.002,0.000,0.998,12.795,30.000,0.000,0.001
+43.6,0.002,0.000,0.998,12.795,30.000,0.000,0.001
+43.7,0.002,0.000,0.998,12.795,30.000,0.000,0.001
+43.8,0.002,0.000,0.998,12.795,30.000,0.000,0.001
+43.9,0.002,0.000,0.998,12.795,30.000,0.000,0.001
+44,0.002,0.000,0.998,12.795,30.000,0.000,0.001
+44.1,0.002,0.000,0.998,12.795,30.000,0.000,0.001
+44.2,0.002,0.000,0.998,12.795,30.000,0.000,0.001
+44.3,0.002,0.000,0.998,12.795,30.000,0.000,0.001
+44.4,0.002,0.000,0.998,12.795,30.000,0.000,0.001
+44.5,0.002,0.000,0.998,12.795,30.000,0.000,0.001
+44.6,0.002,0.000,0.998,12.795,30.000,0.000,0.001
+44.7,0.002,0.000,0.998,12.795,30.000,0.000,0.001
+44.8,0.002,0.000,0.998,12.795,30.000,0.000,0.001
+44.9,0.002,0.000,0.998,12.795,30.000,0.000,0.001
+45,0.002,0.000,0.998,12.795,30.000,0.000,0.001
+45.1,0.002,0.000,0.998,12.795,30.000,0.000,0.001
+45.2,0.002,0.000,0.998,12.795,30.000,0.000,0.001
+45.3,0.002,0.000,0.998,12.795,30.000,0.000,0.001
+45.4,0.002,0.000,0.998,12.795,30.000,0.000,0.001
+45.5,0.002,0.000,0.998,12.795,30.000,0.000,0.001
+45.6,0.002,0.000,0.998,12.795,30.000,0.000,0.001
+45.7,0.002,0.000,0.998,12.795,30.000,0.000,0.001
+45.8,0.002,0.000,0.998,12.795,30.000,0.000,0.001
+45.9,0.002,0.000,0.998,12.795,30.000,0.000,0.001
+46,0.002,0.000,0.998,12.795,30.000,0.000,0.001
+46.1,0.002,0.000,0.998,12.795,30.000,0.000,0.001
+46.2,0.002,0.000,0.998,12.795,30.000,0.000,0.000
+46.3,0.002,0.000,0.998,12.795,30.000,0.000,0.000
+46.4,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+46.5,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+46.6,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+46.7,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+46.8,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+46.9,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+47,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+47.1,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+47.2,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+47.3,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+47.4,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+47.5,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+47.6,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+47.7,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+47.8,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+47.9,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+48,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+48.1,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+48.2,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+48.3,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+48.4,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+48.5,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+48.6,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+48.7,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+48.8,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+48.9,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+49,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+49.1,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+49.2,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+49.3,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+49.4,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+49.5,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+49.6,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+49.7,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+49.8,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+49.9,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+50,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+50.1,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+50.2,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+50.3,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+50.4,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+50.5,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+50.6,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+50.7,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+50.8,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+50.9,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+51,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+51.1,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+51.2,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+51.3,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+51.4,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+51.5,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+51.6,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+51.7,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+51.8,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+51.9,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+52,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+52.1,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+52.2,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+52.3,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+52.4,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+52.5,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+52.6,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+52.7,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+52.8,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+52.9,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+53,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+53.1,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+53.2,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+53.3,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+53.4,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+53.5,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+53.6,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+53.7,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+53.8,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+53.9,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+54,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+54.1,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+54.2,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+54.3,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+54.4,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+54.5,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+54.6,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+54.7,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+54.8,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+54.9,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+55,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+55.1,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+55.2,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+55.3,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+55.4,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+55.5,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+55.6,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+55.7,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+55.8,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+55.9,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+56,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+56.1,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+56.2,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+56.3,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+56.4,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+56.5,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+56.6,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+56.7,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+56.8,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+56.9,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+57,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+57.1,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+57.2,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+57.3,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+57.4,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+57.5,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+57.6,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+57.7,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+57.8,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+57.9,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+58,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+58.1,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+58.2,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+58.3,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+58.4,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+58.5,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+58.6,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+58.7,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+58.8,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+58.9,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+59,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+59.1,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+59.2,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+59.3,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+59.4,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+59.5,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+59.6,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+59.7,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+59.8,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+59.9,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+60,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+60.1,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+60.2,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+60.3,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+60.4,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+60.5,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+60.6,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+60.7,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+60.8,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+60.9,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+61,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+61.1,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+61.2,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+61.3,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+61.4,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+61.5,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+61.6,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+61.7,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+61.8,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+61.9,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+62,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+62.1,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+62.2,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+62.3,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+62.4,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+62.5,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+62.6,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+62.7,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+62.8,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+62.9,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+63,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+63.1,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+63.2,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+63.3,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+63.4,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+63.5,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+63.6,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+63.7,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+63.8,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+63.9,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+64,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+64.1,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+64.2,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+64.3,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+64.4,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+64.5,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+64.6,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+64.7,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+64.8,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+64.9,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+65,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+65.1,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+65.2,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+65.3,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+65.4,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+65.5,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+65.6,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+65.7,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+65.8,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+65.9,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+66,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+66.1,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+66.2,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+66.3,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+66.4,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+66.5,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+66.6,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+66.7,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+66.8,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+66.9,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+67,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+67.1,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+67.2,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+67.3,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+67.4,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+67.5,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+67.6,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+67.7,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+67.8,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+67.9,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+68,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+68.1,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+68.2,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+68.3,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+68.4,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+68.5,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+68.6,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+68.7,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+68.8,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+68.9,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+69,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+69.1,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+69.2,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+69.3,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+69.4,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+69.5,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+69.6,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+69.7,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+69.8,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+69.9,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+70,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+70.1,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+70.2,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+70.3,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+70.4,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+70.5,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+70.6,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+70.7,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+70.8,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+70.9,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+71,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+71.1,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+71.2,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+71.3,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+71.4,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+71.5,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+71.6,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+71.7,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+71.8,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+71.9,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+72,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+72.1,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+72.2,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+72.3,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+72.4,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+72.5,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+72.6,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+72.7,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+72.8,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+72.9,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+73,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+73.1,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+73.2,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+73.3,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+73.4,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+73.5,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+73.6,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+73.7,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+73.8,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+73.9,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+74,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+74.1,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+74.2,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+74.3,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+74.4,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+74.5,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+74.6,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+74.7,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+74.8,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+74.9,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+75,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+75.1,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+75.2,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+75.3,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+75.4,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+75.5,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+75.6,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+75.7,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+75.8,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+75.9,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+76,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+76.1,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+76.2,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+76.3,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+76.4,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+76.5,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+76.6,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+76.7,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+76.8,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+76.9,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+77,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+77.1,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+77.2,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+77.3,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+77.4,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+77.5,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+77.6,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+77.7,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+77.8,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+77.9,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+78,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+78.1,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+78.2,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+78.3,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+78.4,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+78.5,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+78.6,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+78.7,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+78.8,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+78.9,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+79,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+79.1,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+79.2,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+79.3,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+79.4,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+79.5,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+79.6,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+79.7,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+79.8,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+79.9,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+80,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+80.1,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+80.2,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+80.3,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+80.4,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+80.5,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+80.6,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+80.7,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+80.8,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+80.9,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+81,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+81.1,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+81.2,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+81.3,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+81.4,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+81.5,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+81.6,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+81.7,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+81.8,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+81.9,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+82,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+82.1,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+82.2,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+82.3,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+82.4,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+82.5,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+82.6,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+82.7,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+82.8,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+82.9,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+83,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+83.1,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+83.2,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+83.3,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+83.4,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+83.5,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+83.6,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+83.7,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+83.8,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+83.9,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+84,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+84.1,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+84.2,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+84.3,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+84.4,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+84.5,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+84.6,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+84.7,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+84.8,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+84.9,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+85,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+85.1,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+85.2,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+85.3,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+85.4,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+85.5,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+85.6,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+85.7,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+85.8,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+85.9,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+86,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+86.1,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+86.2,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+86.3,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+86.4,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+86.5,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+86.6,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+86.7,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+86.8,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+86.9,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+87,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+87.1,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+87.2,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+87.3,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+87.4,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+87.5,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+87.6,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+87.7,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+87.8,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+87.9,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+88,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+88.1,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+88.2,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+88.3,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+88.4,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+88.5,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+88.6,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+88.7,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+88.8,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+88.9,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+89,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+89.1,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+89.2,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+89.3,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+89.4,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+89.5,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+89.6,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+89.7,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+89.8,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+89.9,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+90,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+90.1,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+90.2,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+90.3,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+90.4,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+90.5,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+90.6,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+90.7,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+90.8,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+90.9,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+91,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+91.1,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+91.2,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+91.3,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+91.4,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+91.5,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+91.6,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+91.7,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+91.8,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+91.9,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+92,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+92.1,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+92.2,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+92.3,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+92.4,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+92.5,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+92.6,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+92.7,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+92.8,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+92.9,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+93,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+93.1,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+93.2,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+93.3,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+93.4,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+93.5,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+93.6,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+93.7,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+93.8,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+93.9,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+94,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+94.1,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+94.2,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+94.3,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+94.4,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+94.5,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+94.6,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+94.7,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+94.8,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+94.9,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+95,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+95.1,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+95.2,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+95.3,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+95.4,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+95.5,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+95.6,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+95.7,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+95.8,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+95.9,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+96,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+96.1,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+96.2,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+96.3,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+96.4,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+96.5,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+96.6,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+96.7,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+96.8,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+96.9,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+97,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+97.1,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+97.2,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+97.3,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+97.4,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+97.5,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+97.6,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+97.7,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+97.8,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+97.9,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+98,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+98.1,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+98.2,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+98.3,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+98.4,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+98.5,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+98.6,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+98.7,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+98.8,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+98.9,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+99,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+99.1,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+99.2,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+99.3,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+99.4,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+99.5,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+99.6,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+99.7,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+99.8,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+99.9,0.002,0.000,0.998,12.795,30.001,0.000,0.000
+100,0.002,0.000,0.998,12.795,30.001,0.000,0.000
diff --git a/Build/source/utils/asymptote/doc/shadedtiling.asy b/Build/source/utils/asymptote/doc/shadedtiling.asy
new file mode 100644
index 00000000000..4d3b8ae894b
--- /dev/null
+++ b/Build/source/utils/asymptote/doc/shadedtiling.asy
@@ -0,0 +1,12 @@
+size(0,100);
+import patterns;
+
+real d=4mm;
+picture tiling;
+path square=scale(d)*unitsquare;
+axialshade(tiling,square,white,(0,0),black,(d,d));
+fill(tiling,shift(d,d)*square,blue);
+add("shadedtiling",tiling);
+
+filldraw(unitcircle,pattern("shadedtiling"));
+
diff --git a/Build/source/utils/asymptote/doc/slopefield1.asy b/Build/source/utils/asymptote/doc/slopefield1.asy
new file mode 100644
index 00000000000..fd60de4f632
--- /dev/null
+++ b/Build/source/utils/asymptote/doc/slopefield1.asy
@@ -0,0 +1,9 @@
+import slopefield;
+
+size(200);
+
+real func(real x) {return 2x;}
+add(slopefield(func,(-3,-3),(3,3),20,Arrow));
+draw(curve((0,0),func,(-3,-3),(3,3)),red);
+
+
diff --git a/Build/source/utils/asymptote/doc/square.asy b/Build/source/utils/asymptote/doc/square.asy
new file mode 100644
index 00000000000..f3f34a4c628
--- /dev/null
+++ b/Build/source/utils/asymptote/doc/square.asy
@@ -0,0 +1 @@
+draw((0,0)--(100,0)--(100,100)--(0,100)--cycle);
diff --git a/Build/source/utils/asymptote/doc/subpictures.asy b/Build/source/utils/asymptote/doc/subpictures.asy
new file mode 100644
index 00000000000..1ace23f5678
--- /dev/null
+++ b/Build/source/utils/asymptote/doc/subpictures.asy
@@ -0,0 +1,20 @@
+picture pic1;
+real size=50;
+size(pic1,size);
+fill(pic1,(0,0)--(50,100)--(100,0)--cycle,red);
+
+picture pic2;
+size(pic2,size);
+fill(pic2,unitcircle,green);
+
+picture pic3;
+size(pic3,size);
+fill(pic3,unitsquare,blue);
+
+picture pic;
+add(pic,pic1.fit(),(0,0),N);
+add(pic,pic2.fit(),(0,0),10S);
+
+add(pic.fit(),(0,0),N);
+add(pic3.fit(),(0,0),10S);
+
diff --git a/Build/source/utils/asymptote/doc/superpath.asy b/Build/source/utils/asymptote/doc/superpath.asy
new file mode 100644
index 00000000000..ec2787a9ce0
--- /dev/null
+++ b/Build/source/utils/asymptote/doc/superpath.asy
@@ -0,0 +1,5 @@
+size(0,100);
+path unitcircle=E..N..W..S..cycle;
+path g=scale(2)*unitcircle;
+filldraw(unitcircle^^g,evenodd+yellow,black);
+
diff --git a/Build/source/utils/asymptote/doc/tile.asy b/Build/source/utils/asymptote/doc/tile.asy
new file mode 100644
index 00000000000..fe9cbc523c7
--- /dev/null
+++ b/Build/source/utils/asymptote/doc/tile.asy
@@ -0,0 +1,13 @@
+size(0,90);
+import patterns;
+
+add("tile",tile());
+add("filledtilewithmargin",tile(6mm,4mm,red,Fill),(1mm,1mm),(1mm,1mm));
+add("checker",checker());
+add("brick",brick());
+
+real s=2.5;
+filldraw(unitcircle,pattern("tile"));
+filldraw(shift(s,0)*unitcircle,pattern("filledtilewithmargin"));
+filldraw(shift(2s,0)*unitcircle,pattern("checker"));
+filldraw(shift(3s,0)*unitcircle,pattern("brick"));
diff --git a/Build/source/utils/asymptote/doc/triangulate.asy b/Build/source/utils/asymptote/doc/triangulate.asy
new file mode 100644
index 00000000000..56ad347b53d
--- /dev/null
+++ b/Build/source/utils/asymptote/doc/triangulate.asy
@@ -0,0 +1,19 @@
+size(200);
+int np=100;
+pair[] points;
+
+real r() {return 1.2*(rand()/randMax*2-1);}
+
+for(int i=0; i < np; ++i)
+ points.push((r(),r()));
+
+int[][] trn=triangulate(points);
+
+for(int i=0; i < trn.length; ++i) {
+ draw(points[trn[i][0]]--points[trn[i][1]]);
+ draw(points[trn[i][1]]--points[trn[i][2]]);
+ draw(points[trn[i][2]]--points[trn[i][0]]);
+}
+
+for(int i=0; i < np; ++i)
+ dot(points[i],red);
diff --git a/Build/source/utils/asymptote/doc/unitcircle3.asy b/Build/source/utils/asymptote/doc/unitcircle3.asy
new file mode 100644
index 00000000000..be282011dca
--- /dev/null
+++ b/Build/source/utils/asymptote/doc/unitcircle3.asy
@@ -0,0 +1,9 @@
+import three;
+
+size(100);
+
+path3 g=(1,0,0)..(0,1,0)..(-1,0,0)..(0,-1,0)..cycle;
+draw(g);
+draw(O--Z,red+dashed,Arrow3);
+draw(((-1,-1,0)--(1,-1,0)--(1,1,0)--(-1,1,0)--cycle));
+dot(g,red);
diff --git a/Build/source/utils/asymptote/doc/vectorfield.asy b/Build/source/utils/asymptote/doc/vectorfield.asy
new file mode 100644
index 00000000000..12de66e49c5
--- /dev/null
+++ b/Build/source/utils/asymptote/doc/vectorfield.asy
@@ -0,0 +1,9 @@
+import graph;
+size(100);
+
+pair a=(0,0);
+pair b=(2pi,2pi);
+
+path vector(pair z) {return (0,0)--(sin(z.x),cos(z.y));}
+
+add(vectorfield(vector,a,b));
diff --git a/Build/source/utils/asymptote/doc/westnile.asy b/Build/source/utils/asymptote/doc/westnile.asy
new file mode 100644
index 00000000000..eaef31e1e87
--- /dev/null
+++ b/Build/source/utils/asymptote/doc/westnile.asy
@@ -0,0 +1,64 @@
+import graph;
+
+size(9cm,8cm,IgnoreAspect);
+string data="westnile.csv";
+
+file in=line(csv(input(data)));
+
+string[] columnlabel=in;
+
+real[][] A=dimension(in,0,0);
+A=transpose(A);
+real[] number=A[0], survival=A[1];
+
+path g=graph(number,survival);
+draw(g);
+
+scale(true);
+
+xaxis("Initial no.\ of mosquitoes per bird ($S_{M_0}/N_{B_0}$)",
+ Bottom,LeftTicks);
+xaxis(Top);
+yaxis("Susceptible bird survival",Left,RightTicks(trailingzero));
+yaxis(Right);
+
+real a=number[0];
+real b=number[number.length-1];
+
+real S1=0.475;
+path h1=(a,S1)--(b,S1);
+real M1=interp(a,b,intersect(h1,g)[0]);
+
+real S2=0.9;
+path h2=(a,S2)--(b,S2);
+real M2=interp(a,b,intersect(h2,g)[0]);
+
+labelx("$M_1$",M1);
+labelx("$M_2$",M2);
+
+draw((a,S2)--(M2,S2)--(M2,0),Dotted);
+draw((a,S1)--(M1,S1)--(M1,0),dashed);
+
+pen p=fontsize(10);
+
+real y3=0.043;
+path reduction=(M1,y3)--(M2,y3);
+draw(reduction,Arrow,TrueMargin(0,0.5*(linewidth(Dotted)+linewidth())));
+
+arrow(shift(-20,5)*Label(minipage("\flushleft{\begin{itemize}\item[1.]
+Estimate proportion of birds surviving at end of season\end{itemize}}",100),
+ align=NNE),
+ (M1,S1),NNE,1cm,p,Arrow(NoFill));
+
+arrow(shift(-24,5)*Label(minipage("\flushleft{\begin{itemize}\item[2.]
+Read off initial mosquito abundance\end{itemize}}",80),align=NNE),
+ (M1,0),NE,2cm,p,Arrow(NoFill));
+
+arrow(shift(20,0)*Label(minipage("\flushleft{\begin{itemize}\item[3.]
+Determine desired bird survival for next season\end{itemize}}",90),align=SW),
+ (M2,S2),SW,arrowlength,p,Arrow(NoFill));
+
+arrow(shift(8,-15)*Label(minipage("\flushleft{\begin{itemize}\item[4.]
+Calculate required proportional reduction in mosquitoes\end{itemize}}",90),
+ align=NW),
+ point(reduction,0.5),NW,1.5cm,p,Arrow(NoFill));
diff --git a/Build/source/utils/asymptote/doc/westnile.csv b/Build/source/utils/asymptote/doc/westnile.csv
new file mode 100644
index 00000000000..cfc8493ed22
--- /dev/null
+++ b/Build/source/utils/asymptote/doc/westnile.csv
@@ -0,0 +1,402 @@
+sm0,0.001(T14)
+0.0,0.9973
+0.1,0.9973
+0.2,0.9972
+0.3,0.9972
+0.4,0.9971
+0.5,0.9971
+0.6,0.9970
+0.7,0.9970
+0.8,0.9969
+0.9,0.9968
+1.0,0.9968
+1.1,0.9967
+1.2,0.9966
+1.3,0.9966
+1.4,0.9965
+1.5,0.9964
+1.6,0.9963
+1.7,0.9963
+1.8,0.9962
+1.9,0.9961
+2.0,0.9960
+2.1,0.9959
+2.2,0.9958
+2.3,0.9957
+2.4,0.9957
+2.5,0.9956
+2.6,0.9955
+2.7,0.9954
+2.8,0.9952
+2.9,0.9951
+3.0,0.9950
+3.1,0.9949
+3.2,0.9948
+3.3,0.9947
+3.4,0.9945
+3.5,0.9944
+3.6,0.9943
+3.7,0.9941
+3.8,0.9940
+3.9,0.9939
+4.0,0.9937
+4.1,0.9936
+4.2,0.9934
+4.3,0.9932
+4.4,0.9931
+4.5,0.9929
+4.6,0.9927
+4.7,0.9926
+4.8,0.9924
+4.9,0.9922
+5.0,0.9920
+5.1,0.9918
+5.2,0.9916
+5.3,0.9914
+5.4,0.9912
+5.5,0.9909
+5.6,0.9907
+5.7,0.9905
+5.8,0.9902
+5.9,0.9900
+6.0,0.9897
+6.1,0.9895
+6.2,0.9892
+6.3,0.9889
+6.4,0.9887
+6.5,0.9884
+6.6,0.9881
+6.7,0.9878
+6.8,0.9875
+6.9,0.9872
+7.0,0.9868
+7.1,0.9865
+7.2,0.9861
+7.3,0.9858
+7.4,0.9854
+7.5,0.9851
+7.6,0.9847
+7.7,0.9843
+7.8,0.9839
+7.9,0.9835
+8.0,0.9831
+8.1,0.9826
+8.2,0.9822
+8.3,0.9818
+8.4,0.9813
+8.5,0.9808
+8.6,0.9803
+8.7,0.9798
+8.8,0.9793
+8.9,0.9788
+9.0,0.9783
+9.1,0.9777
+9.2,0.9772
+9.3,0.9766
+9.4,0.9760
+9.5,0.9754
+9.6,0.9748
+9.7,0.9742
+9.8,0.9735
+9.9,0.9729
+10.0,0.9722
+10.1,0.9715
+10.2,0.9708
+10.3,0.9701
+10.4,0.9694
+10.5,0.9686
+10.6,0.9679
+10.7,0.9671
+10.8,0.9663
+10.9,0.9654
+11.0,0.9646
+11.1,0.9637
+11.2,0.9629
+11.3,0.9620
+11.4,0.9611
+11.5,0.9601
+11.6,0.9592
+11.7,0.9582
+11.8,0.9572
+11.9,0.9562
+12.0,0.9551
+12.1,0.9541
+12.2,0.9530
+12.3,0.9519
+12.4,0.9507
+12.5,0.9496
+12.6,0.9484
+12.7,0.9472
+12.8,0.9460
+12.9,0.9447
+13.0,0.9434
+13.1,0.9421
+13.2,0.9408
+13.3,0.9394
+13.4,0.9380
+13.5,0.9366
+13.6,0.9352
+13.7,0.9337
+13.8,0.9322
+13.9,0.9307
+14.0,0.9291
+14.1,0.9275
+14.2,0.9259
+14.3,0.9243
+14.4,0.9226
+14.5,0.9209
+14.6,0.9191
+14.7,0.9174
+14.8,0.9156
+14.9,0.9137
+15.0,0.9118
+15.1,0.9099
+15.2,0.9080
+15.3,0.9060
+15.4,0.9041
+15.5,0.9020
+15.6,0.8999
+15.7,0.8978
+15.8,0.8956
+15.9,0.8934
+16.0,0.8912
+16.1,0.8889
+16.2,0.8866
+16.3,0.8843
+16.4,0.8819
+16.5,0.8795
+16.6,0.8770
+16.7,0.8745
+16.8,0.8720
+16.9,0.8694
+17.0,0.8668
+17.1,0.8641
+17.2,0.8614
+17.3,0.8587
+17.4,0.8559
+17.5,0.8531
+17.6,0.8502
+17.7,0.8473
+17.8,0.8444
+17.9,0.8414
+18.0,0.8383
+18.1,0.8353
+18.2,0.8323
+18.3,0.8291
+18.4,0.8259
+18.5,0.8227
+18.6,0.8194
+18.7,0.8160
+18.8,0.8127
+18.9,0.8092
+19.0,0.8058
+19.1,0.8022
+19.2,0.7987
+19.3,0.7951
+19.4,0.7914
+19.5,0.7878
+19.6,0.7840
+19.7,0.7803
+19.8,0.7764
+19.9,0.7726
+20.0,0.7687
+20.1,0.7647
+20.2,0.7607
+20.3,0.7567
+20.4,0.7526
+20.5,0.7485
+20.6,0.7443
+20.7,0.7401
+20.8,0.7359
+20.9,0.7316
+21.0,0.7272
+21.1,0.7229
+21.2,0.7185
+21.3,0.7140
+21.4,0.7096
+21.5,0.7050
+21.6,0.7005
+21.7,0.6959
+21.8,0.6912
+21.9,0.6866
+22.0,0.6819
+22.1,0.6771
+22.2,0.6723
+22.3,0.6675
+22.4,0.6627
+22.5,0.6578
+22.6,0.6530
+22.7,0.6480
+22.8,0.6430
+22.9,0.6380
+23.0,0.6330
+23.1,0.6280
+23.2,0.6229
+23.3,0.6178
+23.4,0.6126
+23.5,0.6075
+23.6,0.6023
+23.7,0.5971
+23.8,0.5918
+23.9,0.5866
+24.0,0.5813
+24.1,0.5760
+24.2,0.5706
+24.3,0.5653
+24.4,0.5600
+24.5,0.5547
+24.6,0.5493
+24.7,0.5440
+24.8,0.5385
+24.9,0.5332
+25.0,0.5278
+25.1,0.5224
+25.2,0.5170
+25.3,0.5115
+25.4,0.5061
+25.5,0.5007
+25.6,0.4952
+25.7,0.4898
+25.8,0.4844
+25.9,0.4789
+26.0,0.4735
+26.1,0.4681
+26.2,0.4627
+26.3,0.4572
+26.4,0.4518
+26.5,0.4464
+26.6,0.4410
+26.7,0.4356
+26.8,0.4303
+26.9,0.4249
+27.0,0.4194
+27.1,0.4143
+27.2,0.4089
+27.3,0.4036
+27.4,0.3983
+27.5,0.3931
+27.6,0.3878
+27.7,0.3826
+27.8,0.3774
+27.9,0.3724
+28.0,0.3672
+28.1,0.3621
+28.2,0.3571
+28.3,0.3520
+28.4,0.3470
+28.5,0.3420
+28.6,0.3370
+28.7,0.3320
+28.8,0.3271
+28.9,0.3223
+29.0,0.3174
+29.1,0.3126
+29.2,0.3078
+29.3,0.3031
+29.4,0.2983
+29.5,0.2936
+29.6,0.2890
+29.7,0.2845
+29.8,0.2801
+29.9,0.2756
+30.0,0.2711
+30.1,0.2667
+30.2,0.2623
+30.3,0.2580
+30.4,0.2537
+30.5,0.2495
+30.6,0.2453
+30.7,0.2411
+30.8,0.2370
+30.9,0.2329
+31.0,0.2289
+31.1,0.2250
+31.2,0.2210
+31.3,0.2171
+31.4,0.2133
+31.5,0.2095
+31.6,0.2057
+31.7,0.2019
+31.8,0.1983
+31.9,0.1947
+32.0,0.1912
+32.1,0.1876
+32.2,0.1842
+32.3,0.1807
+32.4,0.1773
+32.5,0.1740
+32.6,0.1707
+32.7,0.1674
+32.8,0.1642
+32.9,0.1611
+33.0,0.1580
+33.1,0.1549
+33.2,0.1520
+33.3,0.1490
+33.4,0.1461
+33.5,0.1432
+33.6,0.1404
+33.7,0.1376
+33.8,0.1348
+33.9,0.1321
+34.0,0.1294
+34.1,0.1268
+34.2,0.1242
+34.3,0.1217
+34.4,0.1193
+34.5,0.1168
+34.6,0.1144
+34.7,0.1120
+34.8,0.1097
+34.9,0.1074
+35.0,0.1052
+35.1,0.1029
+35.2,0.1008
+35.3,0.0987
+35.4,0.0966
+35.5,0.0946
+35.6,0.0925
+35.7,0.0905
+35.8,0.0886
+35.9,0.0867
+36.0,0.0848
+36.1,0.0830
+36.2,0.0812
+36.3,0.0794
+36.4,0.0777
+36.5,0.0760
+36.6,0.0743
+36.7,0.0727
+36.8,0.0711
+36.9,0.0696
+37.0,0.0680
+37.1,0.0665
+37.2,0.0651
+37.3,0.0636
+37.4,0.0622
+37.5,0.0608
+37.6,0.0595
+37.7,0.0581
+37.8,0.0568
+37.9,0.0555
+38.0,0.0543
+38.1,0.0531
+38.2,0.0519
+38.3,0.0507
+38.4,0.0495
+38.5,0.0484
+38.6,0.0473
+38.7,0.0462
+38.8,0.0452
+38.9,0.0441
+39.0,0.0431
+39.1,0.0421
+39.2,0.0412
+39.3,0.0402
+39.4,0.0393
+39.5,0.0384
+39.6,0.0375
+39.7,0.0366
+39.8,0.0358
+39.9,0.0350
+40.0,0.0342
diff --git a/Build/source/utils/asymptote/doc/xasy.1x b/Build/source/utils/asymptote/doc/xasy.1x
new file mode 100644
index 00000000000..e882db25212
--- /dev/null
+++ b/Build/source/utils/asymptote/doc/xasy.1x
@@ -0,0 +1,27 @@
+.\" Hey, EMACS: -*- nroff -*-
+.TH XASY 1x "27 Nov 2007"
+.SH NAME
+asy \- script-based vector graphics language
+.SH SYNOPSIS
+.B xasy
+.RI " [-x magnification] [filename]"
+.SH DESCRIPTION
+\fBAsymptote\fP is a powerful descriptive vector graphics language for
+technical drawing, inspired by MetaPost but with an improved C++\-like syntax.
+Asymptote provides for figures the same high\-quality level of typesetting that
+LaTeX does for scientific text.
+.PP
+\fBxasy\fP is a GUI for Asymptote that allows for final figure adjustments.
+
+.SH OPTIONS
+.TP
+.B \-x magnification
+Initial zoom.
+
+.SH SEE ALSO
+Asymptote and xasy are documented fully in the Asymptote Info page.
+.SH AUTHOR
+Asymptote was written by Andy Hammerlindl, John Bowman, and Tom Prince.
+.PP
+This manual page was written by Hubert Chan for the Debian project (but may
+be used by others).
diff --git a/Build/source/utils/asymptote/drawclipbegin.h b/Build/source/utils/asymptote/drawclipbegin.h
new file mode 100644
index 00000000000..5bc2d1f7c37
--- /dev/null
+++ b/Build/source/utils/asymptote/drawclipbegin.h
@@ -0,0 +1,90 @@
+/*****
+ * drawclipbegin.h
+ * John Bowman
+ *
+ * Begin clip of picture to specified path.
+ *****/
+
+#ifndef DRAWCLIPBEGIN_H
+#define DRAWCLIPBEGIN_H
+
+#include "drawelement.h"
+#include "path.h"
+#include "drawpath.h"
+
+namespace camp {
+
+class drawClipBegin : public drawSuperPathPenBase {
+ bool gsave;
+ bool stroke;
+public:
+ void noncyclic() {
+ reportError("cannot clip to non-cyclic path");
+ }
+
+ drawClipBegin(const vm::array& src, bool stroke, pen pentype, bool gsave=true)
+ : drawSuperPathPenBase(src,pentype), gsave(gsave), stroke(stroke) {
+ if(!stroke && !cyclic()) noncyclic();
+ }
+
+ virtual ~drawClipBegin() {}
+
+ void bounds(bbox& b, iopipestream& iopipe, boxvector& vbox,
+ bboxlist& bboxstack) {
+ bboxstack.push_back(b);
+ bbox bpath;
+ if(stroke) strokebounds(bpath);
+ else drawSuperPathPenBase::bounds(bpath,iopipe,vbox,bboxstack);
+ bboxstack.push_back(bpath);
+ }
+
+ bool begingroup() {return true;}
+
+ void save(bool b) {
+ gsave=b;
+ }
+
+ bool draw(psfile *out) {
+ if(gsave) out->gsave();
+ if(empty()) return true;
+
+ writepath(out);
+ if(stroke) strokepath(out);
+ out->clip(pentype);
+ return true;
+ }
+
+ bool write(texfile *out, const bbox& bpath) {
+ if(gsave) out->gsave();
+ if(empty()) return true;
+
+ out->verbatim(settings::beginpicture(out->texengine));
+ out->verbatim("(");
+ double width=bpath.right-bpath.left;
+ double height=bpath.top-bpath.bottom;
+ out->write(width*ps2tex);
+ out->verbatim(",");
+ out->write(height*ps2tex);
+ out->verbatimline(")%");
+
+ out->beginspecial();
+ out->beginraw();
+ writeshiftedpath(out);
+ if(stroke) strokepath(out);
+ out->clip(pentype);
+ out->endraw();
+ out->endspecial();
+
+ return true;
+ }
+
+ drawElement *transformed(const transform& t)
+ {
+ return new drawClipBegin(transpath(t),stroke,transpen(t));
+ }
+
+};
+
+}
+
+#endif
diff --git a/Build/source/utils/asymptote/drawclipend.h b/Build/source/utils/asymptote/drawclipend.h
new file mode 100644
index 00000000000..d6b2ef33199
--- /dev/null
+++ b/Build/source/utils/asymptote/drawclipend.h
@@ -0,0 +1,65 @@
+/*****
+ * drawclipend.h
+ * John Bowman
+ *
+ * End clip of picture to specified path.
+ *****/
+
+#ifndef DRAWCLIPEND_H
+#define DRAWCLIPEND_H
+
+#include "drawclipbegin.h"
+#include "path.h"
+
+namespace camp {
+
+class drawClipEnd : public drawElement {
+ bool grestore;
+ drawClipBegin *partner;
+public:
+ drawClipEnd(bool grestore=true, drawClipBegin *partner=NULL) :
+ grestore(grestore), partner(partner) {}
+
+ virtual ~drawClipEnd() {}
+
+ bool endclip() {return true;}
+
+ void bounds(bbox& b, iopipestream&, boxvector&, bboxlist& bboxstack) {
+ if(bboxstack.size() < 2)
+ reportError("endclip without matching beginclip");
+ b.clip(bboxstack.back());
+ bboxstack.pop_back();
+ b += bboxstack.back();
+ bboxstack.pop_back();
+ }
+
+ bool endgroup() {return true;}
+
+ void save(bool b) {
+ grestore=b;
+ if(partner) partner->save(b);
+ }
+
+ bool draw(psfile *out) {
+ if(grestore) out->grestore();
+ return true;
+ }
+
+ bool write(texfile *out, const bbox& bpath) {
+ out->verbatimline(settings::endpicture(out->texengine));
+ out->verbatim("\\kern");
+ double width=bpath.right-bpath.left;
+ out->write(-width*ps2tex);
+ out->verbatim(settings::texunits(out->texengine));
+ out->verbatimline("%");
+ if(grestore) out->grestore();
+ return true;
+ }
+
+};
+
+}
+
+GC_DECLARE_PTRFREE(camp::drawClipEnd);
+
+#endif
diff --git a/Build/source/utils/asymptote/drawelement.h b/Build/source/utils/asymptote/drawelement.h
new file mode 100644
index 00000000000..f2108591e5f
--- /dev/null
+++ b/Build/source/utils/asymptote/drawelement.h
@@ -0,0 +1,310 @@
+/*****
+ * drawelement.h
+ * Andy Hammerlindl 2002/06/06
+ *
+ * Abstract base class of any drawable item in camp.
+ *****/
+
+#ifndef DRAWELEMENT_H
+#define DRAWELEMENT_H
+
+#include <vector>
+
+#include "common.h"
+#include "bbox.h"
+#include "bbox3.h"
+#include "pen.h"
+#include "psfile.h"
+#include "texfile.h"
+#include "prcfile.h"
+#include "glrender.h"
+
+namespace camp {
+
+class box {
+ pair p[4];
+public:
+
+ box() {}
+ box(const pair& a, const pair& b, const pair& c, const pair& d) {
+ p[0]=a; p[1]=b; p[2]=c; p[3]=d;
+ }
+
+// Returns true if the line a--b intersects box b.
+ bool intersect(const pair& a, const pair& b) const
+ {
+ for(Int i=0; i < 4; ++i) {
+ pair A=p[i];
+ pair B=p[i < 3 ? i+1 : 0];
+ double de=(b.x-a.x)*(A.y-B.y)-(A.x-B.x)*(b.y-a.y);
+ if(de != 0.0) {
+ de=1.0/de;
+ double t=((A.x-a.x)*(A.y-B.y)-(A.x-B.x)*(A.y-a.y))*de;
+ double T=((b.x-a.x)*(A.y-a.y)-(A.x-a.x)*(b.y-a.y))*de;
+ if(0 <= t && t <= 1 && 0 <= T && T <= 1) return true;
+ }
+ }
+ return false;
+ }
+
+ pair operator [] (Int i) const {return p[i];}
+
+ bool intersect(const box& b) const {
+ for(Int i=0; i < 4; ++i) {
+ pair A=b[i];
+ pair B=b[i < 3 ? i+1 : 0];
+ if(intersect(A,B)) return true;
+ }
+ return false;
+ }
+
+// Returns true iff the point z lies in the region bounded by b.
+ bool inside(const pair& z) const {
+ bool c=false;
+ for(Int i=0; i < 3; ++i) {
+ pair pi=p[i];
+ pair pj=p[i < 3 ? i+1 : 0];
+ if(((pi.y <= z.y && z.y < pj.y) || (pj.y <= z.y && z.y < pi.y)) &&
+ z.x < pi.x+(pj.x-pi.x)*(z.y-pi.y)/(pj.y-pi.y)) c=!c;
+ }
+ return c;
+ }
+
+ double xmax() {
+ return max(max(max(p[0].x,p[1].x),p[2].x),p[3].x);
+ }
+
+ double ymax() {
+ return max(max(max(p[0].y,p[1].y),p[2].y),p[3].y);
+ }
+
+ double xmin() {
+ return min(min(min(p[0].x,p[1].x),p[2].x),p[3].x);
+ }
+
+ double ymin() {
+ return min(min(min(p[0].y,p[1].y),p[2].y),p[3].y);
+ }
+
+};
+
+typedef mem::vector<box> boxvector;
+
+typedef mem::list<bbox> bboxlist;
+
+class drawElement : public gc
+{
+public:
+ virtual ~drawElement() {}
+
+ static pen lastpen;
+
+ // Adjust the bbox of the picture based on the addition of this
+ // element. The iopipestream is needed for determining label sizes.
+ virtual void bounds(bbox&, iopipestream&, boxvector&, bboxlist&) {}
+ virtual void bounds(bbox3&) {}
+
+ virtual void bounds(pair &b, double (*m)(double, double),
+ double (*x)(const triple&, double*),
+ double (*y)(const triple&, double*),
+ double *t, bool &first){}
+
+ virtual bool islabel() {return false;}
+
+ virtual bool islayer() {return false;}
+
+ virtual bool is3D() {return false;}
+
+ virtual bool endclip() {return false;}
+
+ virtual bool begingroup() {return false;}
+
+ virtual bool endgroup() {return false;}
+
+ virtual void save(bool b) {}
+
+ // Output to a PostScript file
+ virtual bool draw(psfile *) {
+ return false;
+ }
+
+ // Output to a TeX file
+ virtual bool write(texfile *, const bbox&) {
+ return false;
+ }
+
+ // Output to a PRC file
+ virtual bool write(prcfile *) {
+ return false;
+ }
+
+ // Used to compute deviation of a surface from a quadrilateral.
+ virtual void displacement() {}
+
+ // Render with OpenGL
+ virtual void render(GLUnurbs *nurb, double size2,
+ const triple& Min, const triple& Max,
+ double perspective, bool transparent) {}
+
+ // Transform as part of a picture.
+ virtual drawElement *transformed(const transform&) {
+ return this;
+ }
+
+ virtual drawElement *transformed(const vm::array&) {
+ return this;
+ }
+};
+
+// Base class for drawElements that involve paths.
+class drawPathBase : public virtual drawElement {
+protected:
+ path p;
+
+ path transpath(const transform& t) const {
+ return p.transformed(t);
+ }
+
+public:
+ drawPathBase() {}
+ drawPathBase(path p) : p(p) {}
+
+ virtual ~drawPathBase() {}
+
+ virtual void bounds(bbox& b, iopipestream&, boxvector&, bboxlist&) {
+ b += p.bounds();
+ }
+
+ virtual void writepath(psfile *out) {
+ out->write(p);
+ }
+
+ virtual void writeshiftedpath(texfile *out) {
+ out->writeshifted(p);
+ }
+
+};
+
+// Base class for drawElements that involve paths and pens.
+class drawPathPenBase : public drawPathBase {
+protected:
+ pen pentype;
+
+ pen transpen(const transform& t) const {
+ return camp::transformed(shiftless(t),pentype);
+ }
+
+public:
+ drawPathPenBase(path p, pen pentype) :
+ drawPathBase(p), pentype(pentype) {}
+
+ drawPathPenBase(pen pentype) :
+ pentype(pentype) {}
+
+ virtual bool empty() {
+ return p.empty();
+ }
+
+ virtual bool cyclic() {
+ return p.cyclic();
+ }
+
+ void strokebounds(bbox& b, const path& p);
+
+ virtual void penSave(psfile *out)
+ {
+ if (!pentype.getTransform().isIdentity())
+ out->gsave();
+ }
+
+ virtual void penTranslate(psfile *out)
+ {
+ transform t=pentype.getTransform();
+ if (!t.isIdentity())
+ out->translate(shiftpair(t));
+ }
+
+ virtual void penConcat(psfile *out)
+ {
+ transform t=pentype.getTransform();
+ if (!t.isIdentity())
+ out->concat(shiftless(t));
+ }
+
+ virtual void penRestore(psfile *out)
+ {
+ if (!pentype.getTransform().isIdentity())
+ out->grestore();
+ }
+
+
+};
+
+// Base class for drawElements that involve superpaths and pens.
+class drawSuperPathPenBase : public drawPathPenBase {
+protected:
+ vm::array P;
+ size_t size;
+ bbox bpath;
+
+ vm::array transpath(const transform& t) const {
+ vm::array *Pt=new vm::array(size);
+ for(size_t i=0; i < size; i++)
+ (*Pt)[i]=vm::read<path>(P,i).transformed(t);
+ return *Pt;
+ }
+
+public:
+ drawSuperPathPenBase(const vm::array& P, pen pentype) :
+ drawPathPenBase(pentype), P(P), size(P.size()) {}
+
+ bool empty() {
+ for(size_t i=0; i < size; i++)
+ if(vm::read<path>(P,i).size() != 0) return false;
+ return true;
+ }
+
+ bool cyclic() {
+ for(size_t i=0; i < size; i++)
+ if(!vm::read<path>(P,i).cyclic()) return false;
+ return true;
+ }
+
+ void bounds(bbox& b, iopipestream&, boxvector&, bboxlist&) {
+ for(size_t i=0; i < size; i++)
+ bpath += vm::read<path>(P,i).bounds();
+ b += bpath;
+ }
+
+ void strokepath(psfile *out) {
+ // strokepath and evenodd are incompatible
+ static pen zerowinding=pen((FillRule) ZEROWINDING);
+ pentype=pentype+zerowinding;
+ out->setpen(pentype);
+ out->strokepath();
+ }
+
+ void strokebounds(bbox& b) {
+ for(size_t i=0; i < size; i++)
+ drawPathPenBase::strokebounds(bpath,vm::read<path>(P,i));
+ b += bpath;
+ }
+
+ void writepath(psfile *out) {
+ for(size_t i=0; i < size; i++)
+ out->write(vm::read<path>(P,i),i == 0);
+ }
+
+ void writeshiftedpath(texfile *out) {
+ for(size_t i=0; i < size; i++)
+ out->writeshifted(vm::read<path>(P,i),i == 0);
+ }
+};
+
+}
+
+GC_DECLARE_PTRFREE(camp::box);
+GC_DECLARE_PTRFREE(camp::drawElement);
+
+#endif
+
diff --git a/Build/source/utils/asymptote/drawfill.cc b/Build/source/utils/asymptote/drawfill.cc
new file mode 100644
index 00000000000..af32b95e475
--- /dev/null
+++ b/Build/source/utils/asymptote/drawfill.cc
@@ -0,0 +1,174 @@
+/*****
+ * drawfill.cc
+ * Andy Hammerlindl 2002/06/06
+ *
+ * Stores a cyclic path that will outline a filled shape in a picture.
+ *****/
+
+#include "drawfill.h"
+
+namespace camp {
+
+void drawAxialShade::palette(psfile *out)
+{
+ pentype.convert();
+ penb.convert();
+
+ colorspace=(ColorSpace) max(pentype.colorspace(),penb.colorspace());
+
+ switch(colorspace) {
+ case RGB:
+ {
+ if (pentype.grayscale()) pentype.greytorgb();
+ else if (penb.grayscale()) penb.greytorgb();
+ break;
+ }
+
+ case CMYK:
+ {
+ if (pentype.grayscale()) pentype.greytocmyk();
+ else if (penb.grayscale()) penb.greytocmyk();
+
+ if (pentype.rgb()) pentype.rgbtocmyk();
+ else if (penb.rgb()) penb.rgbtocmyk();
+ break;
+ }
+ default:
+ break;
+ }
+
+ out->gsave();
+}
+
+bool drawFill::draw(psfile *out)
+{
+ if(pentype.invisible() || empty()) return true;
+
+ palette(out);
+ writepath(out);
+ fill(out);
+ return true;
+}
+
+drawElement *drawFill::transformed(const transform& t)
+{
+ return new drawFill(transpath(t),stroke,transpen(t));
+}
+
+drawElement *drawLatticeShade::transformed(const transform& t)
+{
+ return new drawLatticeShade(transpath(t),stroke,pentype,pens);
+}
+
+drawElement *drawAxialShade::transformed(const transform& t)
+{
+ pair A=t*a, B=t*b;
+ return new drawAxialShade(transpath(t),stroke,pentype,A,penb,B);
+}
+
+drawElement *drawRadialShade::transformed(const transform& t)
+{
+ pair A=t*a, B=t*b;
+ double RA=length(t*(a+ra)-A);
+ double RB=length(t*(b+rb)-B);
+ return new drawRadialShade(transpath(t),stroke,pentype,A,RA,penb,B,RB);
+}
+
+drawElement *drawGouraudShade::transformed(const transform& t)
+{
+ size_t size=vertices.size();
+ vm::array *Vertices=new vm::array(size);
+ for(size_t i=0; i < size; i++)
+ (*Vertices)[i]=t*vm::read<pair>(vertices,i);
+
+ return new drawGouraudShade(transpath(t),stroke,pentype,pens,*Vertices,edges);
+}
+
+drawElement *drawTensorShade::transformed(const transform& t)
+{
+ size_t size=boundaries.size();
+ size_t zsize=z.size();
+ vm::array *Boundaries=new vm::array(size);
+ vm::array *Z=new vm::array(zsize);
+
+ for(size_t i=0; i < size; i++)
+ (*Boundaries)[i]=vm::read<path>(boundaries,i).transformed(t);
+
+ for(size_t i=0; i < zsize; i++) {
+ vm::array *zi=vm::read<vm::array *>(z,i);
+ size_t zisize=checkArray(zi);
+ vm::array *Zi=new vm::array(zisize);
+ (*Z)[i]=Zi;
+ for(size_t j=0; j < zisize; j++)
+ (*Zi)[j]=t*vm::read<pair>(zi,j);
+ }
+
+ return new drawTensorShade(transpath(t),stroke,pentype,pens,*Boundaries,*Z);
+}
+
+bool drawFunctionShade::write(texfile *out, const bbox& box)
+{
+ if(empty()) return true;
+
+ const char *units=
+ settings::texunits(settings::getSetting<string>("tex"));
+
+ ColorSpace colorspace=pentype.colorspace();
+ size_t ncomponents=ColorComponents[colorspace];
+
+ out->verbatim("\\pdfobj stream attr {/FunctionType 4");
+ out->verbatim("/Domain [0 1 0 1]");
+ out->verbatim("/Range [");
+ for(size_t i=0; i < ncomponents; ++i)
+ out->verbatim("0 1 ");
+ out->verbatim("]}{{");
+ out->verbatimline(shader);
+ out->verbatimline("}}%");
+ out->verbatimline("\\edef\\lastobj{\\the\\pdflastobj}\\pdfrefobj\\lastobj");
+
+ out->verbatim("\\setbox\\ASYbox=\\hbox to ");
+ double Hoffset=out->hoffset();
+ double hoffset=(bpath.Max().getx()-Hoffset)*ps2tex;
+ out->write(hoffset);
+ out->verbatim(units);
+ out->verbatim(" {");
+ out->verbatim("\\vbox to ");
+ out->write((box.top-box.bottom)*ps2tex);
+ out->verbatim(units);
+ out->verbatimline(" {\\vfil%");
+ out->gsave();
+ out->beginspecial();
+ out->beginraw();
+ writeshiftedpath(out);
+ if(stroke) strokepath(out);
+ out->clip(pentype);
+ out->verbatimline("/Sh sh");
+ out->endraw();
+ out->endspecial();
+ out->grestore();
+ out->verbatimline("}\\hfil}%");
+
+ out->verbatimline("\\pdfxform resources {");
+ out->verbatimline("/Shading << /Sh << /ShadingType 1");
+ out->verbatim("/Matrix [");
+
+ out->write(shift(pair(-Hoffset,-box.bottom))*matrix(bpath.Min(),bpath.Max()));
+ out->verbatimline("]");
+ out->verbatim("/Domain [0 1 0 1]");
+ out->verbatimline("/ColorSpace /Device"+ColorDeviceSuffix[colorspace]);
+ out->verbatimline("/Function \\lastobj\\space 0 R >> >>}\\ASYbox");
+
+ out->verbatimline("\\pdfrefxform\\the\\pdflastxform");
+ out->verbatim("\\kern");
+ out->write(-hoffset);
+ out->verbatim(units);
+ out->verbatimline("%");
+ return true;
+}
+
+drawElement *drawFunctionShade::transformed(const transform& t)
+{
+ return new drawFunctionShade(transpath(t),stroke,pentype,shader);
+}
+
+} // namespace camp
diff --git a/Build/source/utils/asymptote/drawfill.h b/Build/source/utils/asymptote/drawfill.h
new file mode 100644
index 00000000000..71e2c9042c2
--- /dev/null
+++ b/Build/source/utils/asymptote/drawfill.h
@@ -0,0 +1,186 @@
+/*****
+ * drawfill.h
+ * Andy Hammerlindl 2002/06/06
+ *
+ * Stores a cyclic path that will outline a filled shape in a picture.
+ *****/
+
+#ifndef DRAWFILL_H
+#define DRAWFILL_H
+
+#include "drawelement.h"
+#include "path.h"
+
+namespace camp {
+
+class drawFill : public drawSuperPathPenBase {
+protected:
+ bool stroke;
+public:
+ void noncyclic() {
+ reportError("non-cyclic path cannot be filled");
+ }
+
+ drawFill(const vm::array& src, bool stroke, pen pentype)
+ : drawSuperPathPenBase(src,pentype), stroke(stroke) {
+ if(!stroke && !cyclic()) noncyclic();
+ }
+
+ virtual ~drawFill() {}
+
+ bool draw(psfile *out);
+ virtual void palette(psfile *out) {
+ penSave(out);
+ penTranslate(out);
+ }
+ virtual void fill(psfile *out) {
+ out->setpen(pentype);
+ if(stroke) out->strokepath();
+ out->fill(pentype);
+ penRestore(out);
+ };
+
+ drawElement *transformed(const transform& t);
+};
+
+class drawShade : public drawFill {
+public:
+ drawShade(const vm::array& src, bool stroke, pen pentype)
+ : drawFill(src,stroke,pentype) {}
+
+ void bounds(bbox& b, iopipestream& iopipe, boxvector& vbox,
+ bboxlist& bboxstack) {
+ if(stroke) strokebounds(b);
+ else drawSuperPathPenBase::bounds(b,iopipe,vbox,bboxstack);
+ }
+
+ virtual void shade(psfile *out)=0;
+ void fill(psfile *out) {
+ if(stroke) strokepath(out);
+ out->clip(pentype.Fillrule());
+ shade(out);
+ out->grestore();
+ }
+};
+
+class drawLatticeShade : public drawShade {
+protected:
+ vm::array pens;
+public:
+ drawLatticeShade(const vm::array& src, bool stroke, pen pentype,
+ const vm::array& pens)
+ : drawShade(src,stroke,pentype), pens(pens) {}
+
+ void palette(psfile *out) {
+ out->gsave();
+ }
+
+ void shade(psfile *out) {
+ out->latticeshade(pens,bpath);
+ }
+
+ drawElement *transformed(const transform& t);
+};
+
+class drawAxialShade : public drawShade {
+protected:
+ pair a;
+ pen penb;
+ pair b;
+ ColorSpace colorspace;
+public:
+ drawAxialShade(const vm::array& src, bool stroke, pen pentype,
+ pair a, pen penb, pair b)
+ : drawShade(src,stroke,pentype), a(a), penb(penb), b(b) {}
+
+ void palette(psfile *out);
+
+ void shade(psfile *out) {
+ out->gradientshade(true,colorspace,pentype,a,0,penb,b,0);
+ }
+
+ drawElement *transformed(const transform& t);
+};
+
+class drawRadialShade : public drawAxialShade {
+protected:
+ double ra;
+ double rb;
+public:
+ drawRadialShade(const vm::array& src, bool stroke,
+ pen pentype, pair a, double ra, pen penb, pair b, double rb)
+ : drawAxialShade(src,stroke,pentype,a,penb,b), ra(ra), rb(rb) {}
+
+ void shade(psfile *out) {
+ out->gradientshade(false,colorspace,pentype,a,ra,penb,b,rb);
+ }
+
+ drawElement *transformed(const transform& t);
+};
+
+class drawGouraudShade : public drawShade {
+protected:
+ vm::array pens,vertices,edges;
+public:
+ drawGouraudShade(const vm::array& src, bool stroke, pen pentype,
+ const vm::array& pens, const vm::array& vertices,
+ const vm::array& edges)
+ : drawShade(src,stroke,pentype), pens(pens), vertices(vertices),
+ edges(edges) {}
+
+ void palette(psfile *out) {
+ out->gsave();
+ }
+
+ void shade(psfile *out) {
+ out->gouraudshade(pens,vertices,edges);
+ }
+
+ drawElement *transformed(const transform& t);
+};
+
+class drawTensorShade : public drawShade {
+protected:
+ vm::array pens,boundaries,z;
+public:
+ drawTensorShade(const vm::array& src, bool stroke,
+ pen pentype, const vm::array& pens,
+ const vm::array& boundaries, const vm::array& z)
+ : drawShade(src,stroke,pentype), pens(pens), boundaries(boundaries), z(z) {}
+
+ void palette(psfile *out) {
+ out->gsave();
+ }
+
+ void shade(psfile *out) {
+ out->tensorshade(pens,boundaries,z);
+ }
+
+ drawElement *transformed(const transform& t);
+};
+
+class drawFunctionShade : public drawFill {
+protected:
+ string shader;
+public:
+ drawFunctionShade(const vm::array& src, bool stroke, pen pentype,
+ const string& shader)
+ : drawFill(src,stroke,pentype), shader(shader) {
+ if(!settings::pdf(settings::getSetting<string>("tex")))
+ reportError("functionshade requires -tex pdftex or -tex pdflatex");
+ }
+
+ virtual ~drawFunctionShade() {}
+
+ bool draw(psfile *out) {return false;}
+
+ bool write(texfile *, const bbox&);
+
+ bool islabel() {return true;}
+
+ drawElement *transformed(const transform& t);
+};
+
+}
+
+#endif
diff --git a/Build/source/utils/asymptote/drawgrestore.h b/Build/source/utils/asymptote/drawgrestore.h
new file mode 100644
index 00000000000..7f1b62fe630
--- /dev/null
+++ b/Build/source/utils/asymptote/drawgrestore.h
@@ -0,0 +1,35 @@
+/*****
+ * drawgrestore.h
+ * John Bowman
+ *
+ * Output PostScript grestore to picture.
+ *****/
+
+#ifndef DRAWGRESTORE_H
+#define DRAWGRESTORE_H
+
+#include "drawelement.h"
+
+namespace camp {
+
+class drawGrestore : public drawElement {
+public:
+ drawGrestore() {}
+ virtual ~drawGrestore() {}
+
+ bool draw(psfile *out) {
+ out->grestore();
+ return true;
+ }
+
+ bool write(texfile *out, const bbox&) {
+ out->grestore();
+ return true;
+ }
+};
+
+}
+
+GC_DECLARE_PTRFREE(camp::drawGrestore);
+
+#endif
diff --git a/Build/source/utils/asymptote/drawgroup.h b/Build/source/utils/asymptote/drawgroup.h
new file mode 100644
index 00000000000..4e2339387f5
--- /dev/null
+++ b/Build/source/utils/asymptote/drawgroup.h
@@ -0,0 +1,38 @@
+/*****
+ * drawgroup.h
+ * John Bowman
+ *
+ * Group elements in a picture to be deconstructed as a single object.
+ *****/
+
+#ifndef DRAWGROUP_H
+#define DRAWGROUP_H
+
+#include "drawelement.h"
+
+namespace camp {
+
+class drawBegin : public drawElement {
+public:
+ drawBegin() {}
+
+ virtual ~drawBegin() {}
+
+ bool begingroup() {return true;}
+};
+
+class drawEnd : public drawElement {
+public:
+ drawEnd() {}
+
+ virtual ~drawEnd() {}
+
+ bool endgroup() {return true;}
+};
+
+}
+
+GC_DECLARE_PTRFREE(camp::drawBegin);
+GC_DECLARE_PTRFREE(camp::drawEnd);
+
+#endif
diff --git a/Build/source/utils/asymptote/drawgsave.h b/Build/source/utils/asymptote/drawgsave.h
new file mode 100644
index 00000000000..bddc3a1dba0
--- /dev/null
+++ b/Build/source/utils/asymptote/drawgsave.h
@@ -0,0 +1,35 @@
+/*****
+ * drawgsave.h
+ * John Bowman
+ *
+ * Output PostScript gsave to picture.
+ *****/
+
+#ifndef DRAWGSAVE_H
+#define DRAWGSAVE_H
+
+#include "drawelement.h"
+
+namespace camp {
+
+class drawGsave : public drawElement {
+public:
+ drawGsave() {}
+ virtual ~drawGsave() {}
+
+ bool draw(psfile *out) {
+ out->gsave();
+ return true;
+ }
+
+ bool write(texfile *out, const bbox&) {
+ out->gsave();
+ return true;
+ }
+};
+
+}
+
+GC_DECLARE_PTRFREE(camp::drawGsave);
+
+#endif
diff --git a/Build/source/utils/asymptote/drawimage.h b/Build/source/utils/asymptote/drawimage.h
new file mode 100644
index 00000000000..a0f2aff2b09
--- /dev/null
+++ b/Build/source/utils/asymptote/drawimage.h
@@ -0,0 +1,72 @@
+/*****
+ * drawimage.h
+ * John Bowman
+ *
+ * Stores a image that has been added to a picture.
+ *****/
+
+#ifndef DRAWIMAGE_H
+#define DRAWIMAGE_H
+
+#include "drawelement.h"
+#include "array.h"
+#include "pen.h"
+
+namespace camp {
+
+enum imagetype {PALETTE, NOPALETTE, RAW};
+
+class drawImage : public drawElement {
+ vm::array image,palette;
+ unsigned char *raw; // For internal use; not buffered, may be overwritten.
+ size_t width,height;
+ transform t;
+ bool antialias;
+ imagetype type;
+public:
+ drawImage(const vm::array& image, const vm::array& palette,
+ const transform& t, bool antialias, imagetype type=PALETTE)
+ : image(image), palette(palette), t(t), antialias(antialias), type(type) {}
+
+ drawImage(const vm::array& image, const transform& t, bool antialias)
+ : image(image), t(t), antialias(antialias), type(NOPALETTE) {}
+ drawImage(unsigned char *raw, size_t width, size_t height, const transform& t,
+ bool antialias)
+ : raw(raw), width(width), height(height), t(t), antialias(antialias),
+ type(RAW) {}
+
+ virtual ~drawImage() {}
+
+ void bounds(bbox& b, iopipestream&, boxvector&, bboxlist&) {
+ b += t*pair(0,0);
+ b += t*pair(1,1);
+ }
+
+ bool draw(psfile *out) {
+ out->gsave();
+ out->concat(t);
+ switch(type) {
+ case PALETTE:
+ out->image(image,palette,antialias);
+ break;
+ case NOPALETTE:
+ out->image(image,antialias);
+ break;
+ case RAW:
+ out->rawimage(raw,width,height,antialias);
+ break;
+ }
+
+ out->grestore();
+
+ return true;
+ }
+
+ drawElement *transformed(const transform& T) {
+ return new drawImage(image,palette,T*t,antialias,type);
+ }
+};
+
+}
+
+#endif
diff --git a/Build/source/utils/asymptote/drawlabel.cc b/Build/source/utils/asymptote/drawlabel.cc
new file mode 100644
index 00000000000..b6f0590ae1c
--- /dev/null
+++ b/Build/source/utils/asymptote/drawlabel.cc
@@ -0,0 +1,310 @@
+/*****
+ * drawlabel.cc
+ * John Bowman 2003/04/07
+ *
+ * Add a label to a picture.
+ *****/
+
+#include <sstream>
+
+#include "drawlabel.h"
+#include "settings.h"
+#include "util.h"
+#include "lexical.h"
+
+using namespace settings;
+
+namespace camp {
+
+string texready=string("(Please type a command or say `\\end')\n*");
+pen drawElement::lastpen;
+
+void drawLabel::labelwarning(const char *action)
+{
+ cerr << "warning: label \"" << label
+ << "\" " << action << " to avoid overwriting" << endl;
+}
+
+int drawLabel::wait(iopipestream &tex, const char *s, const char **abort,
+ bool ignore)
+{
+ int rc=tex.wait(s,abort);
+ if(rc > 0) {
+ if(fataltex[rc-1]) {
+ tex.pipeclose();
+ ignore=false;
+ } else {
+ tex << "\n";
+ tex.wait(s,abort);
+ tex << "\n";
+ tex.wait(s,abort);
+ }
+ if(!ignore) {
+ string s=tex.message();
+ tex.shred();
+ reportError(s);
+ }
+ }
+ tex.shred();
+ return rc;
+}
+
+bool drawLabel::texbounds(iopipestream& tex, string& s, const char **abort,
+ bool warn)
+{
+ string texbuf;
+ tex << "\\setbox\\ASYbox=\\hbox{" << stripblanklines(s) << "}\n\n";
+ int rc=wait(tex,texready.c_str(),abort,getSetting<bool>("inlinetex"));
+ if(rc) {
+ tex << "\\show 0\n";
+ tex.wait("\n*");
+ if(warn) {
+ if(getSetting<bool>("debug")) {
+ ostringstream buf;
+ buf << "Cannot determine size of label \"" << s << "\"";
+ reportWarning(buf);
+ }
+ return false;
+ }
+ return false;
+ }
+
+ tex << "\\showthe\\wd\\ASYbox\n";
+ tex >> texbuf;
+
+ string cannotread="Cannot read label ";
+ if(texbuf[0] == '>' && texbuf[1] == ' ')
+ try {
+ width=lexical::cast<double>(texbuf.c_str()+2,true)*tex2ps;
+ } catch(lexical::bad_cast&) {
+ reportError(cannotread+"width");
+ }
+ else reportError(cannotread+"width");
+ tex << "\n";
+ wait(tex,"\n*",abort);
+
+ tex << "\\showthe\\ht\\ASYbox\n";
+ tex >> texbuf;
+ if(texbuf[0] == '>' && texbuf[1] == ' ')
+ try {
+ height=lexical::cast<double>(texbuf.c_str()+2,true)*tex2ps;
+ } catch(lexical::bad_cast&) {
+ reportError(cannotread+"height");
+ }
+ else reportError(cannotread+"height");
+ tex << "\n";
+ wait(tex,"\n*",abort);
+
+ tex << "\\showthe\\dp\\ASYbox\n";
+ tex >> texbuf;
+ if(texbuf[0] == '>' && texbuf[1] == ' ')
+ try {
+ depth=lexical::cast<double>(texbuf.c_str()+2,true)*tex2ps;
+ } catch(lexical::bad_cast&) {
+ reportError(cannotread+"depth");
+ }
+ else reportError(cannotread+"depth");
+ tex << "\n";
+ wait(tex,"\n*",abort);
+
+ return true;
+}
+
+inline double urand()
+{
+ static const double factor=2.0/RAND_MAX;
+ return rand()*factor-1.0;
+}
+
+void drawLabel::getbounds(iopipestream& tex, const string& texengine)
+{
+ if(havebounds) return;
+ havebounds=true;
+
+ const char **abort=texabort(texengine);
+ bool Latex=latex(texengine);
+
+ if(Latex) {
+ if(setlatexfont(tex,pentype,lastpen))
+ wait(tex,"\n*",abort);
+ }
+ if(settexfont(tex,pentype,lastpen,Latex))
+ wait(tex,"\n*",abort);
+
+ lastpen=pentype;
+
+ bool nullsize=size.empty();
+ if(!texbounds(tex,label,abort,nullsize) && !nullsize)
+ texbounds(tex,size,abort,false);
+ enabled=true;
+
+ Align=inverse(T)*align;
+ double scale0=max(fabs(Align.getx()),fabs(Align.gety()));
+ if(scale0) Align *= 0.5/scale0;
+ Align -= pair(0.5,0.5);
+ double Depth=(pentype.Baseline() == NOBASEALIGN) ? depth :
+ -depth*Align.gety();
+ texAlign=Align;
+ const double vertical=height+depth;
+ if(Depth > 0) texAlign += pair(0.0,Depth/vertical);
+ Align.scale(width,vertical);
+ Align += pair(0.0,Depth-depth);
+ Align=T*Align;
+}
+
+void drawLabel::bounds(bbox& b, iopipestream& tex, boxvector& labelbounds,
+ bboxlist&)
+{
+ string texengine=getSetting<string>("tex");
+ if(texengine == "none") {b += position; return;}
+
+ getbounds(tex,texengine);
+
+ // alignment point
+ pair p=position+Align;
+ const double vertical=height+depth;
+ const double fuzz=pentype.size()*0.1+0.3;
+ pair A=p+T*pair(-fuzz,-fuzz);
+ pair B=p+T*pair(-fuzz,vertical+fuzz);
+ pair C=p+T*pair(width+fuzz,vertical+fuzz);
+ pair D=p+T*pair(width+fuzz,-fuzz);
+
+ if(pentype.Overwrite() != ALLOW && label != "") {
+ size_t n=labelbounds.size();
+ box Box=box(A,B,C,D);
+ for(size_t i=0; i < n; i++) {
+ if(labelbounds[i].intersect(Box)) {
+ switch(pentype.Overwrite()) {
+ case SUPPRESS:
+ labelwarning("suppressed");
+ case SUPPRESSQUIET:
+ suppress=true;
+ return;
+ case MOVE:
+ labelwarning("moved");
+ default:
+ break;
+ }
+
+ pair Align=(align == pair(0,0)) ? unit(pair(urand(),urand())) :
+ unit(align);
+ double s=0.1*pentype.size();
+ double dx=0, dy=0;
+ if(Align.getx() > 0.1) dx=labelbounds[i].xmax()-Box.xmin()+s;
+ if(Align.getx() < -0.1) dx=labelbounds[i].xmin()-Box.xmax()-s;
+ if(Align.gety() > 0.1) dy=labelbounds[i].ymax()-Box.ymin()+s;
+ if(Align.gety() < -0.1) dy=labelbounds[i].ymin()-Box.ymax()-s;
+ pair offset=pair(dx,dy);
+ position += offset;
+ A += offset;
+ B += offset;
+ C += offset;
+ D += offset;
+ Box=box(A,B,C,D);
+ i=0;
+ }
+ }
+ labelbounds.resize(n+1);
+ labelbounds[n]=Box;
+ }
+
+ Box=bbox();
+ Box += A;
+ Box += B;
+ Box += C;
+ Box += D;
+
+ b += Box;
+}
+
+void drawLabel::checkbounds()
+{
+ if(!havebounds)
+ reportError("drawLabel::write called before bounds");
+}
+
+bool drawLabel::write(texfile *out, const bbox&)
+{
+ checkbounds();
+ if(suppress || pentype.invisible() || !enabled) return true;
+ out->setpen(pentype);
+ out->put(label,T,position,texAlign);
+ return true;
+}
+
+drawElement *drawLabel::transformed(const transform& t)
+{
+ return new drawLabel(label,size,t*T,t*position,
+ length(align)*unit(shiftless(t)*align),pentype);
+}
+
+void drawLabelPath::bounds(bbox& b, iopipestream& tex, boxvector&, bboxlist&)
+{
+ string texengine=getSetting<string>("tex");
+ if(texengine == "none") {b += position; return;}
+
+ getbounds(tex,texengine);
+ double L=p.arclength();
+
+ double s1,s2;
+ if(justify == "l") {
+ s1=0.0;
+ s2=width;
+ } else if(justify == "r") {
+ s1=L-width;
+ s2=L;
+ } else {
+ double s=0.5*L;
+ double h=0.5*width;
+ s1=s-h;
+ s2=s+h;
+ }
+
+ double Sx=shift.getx();
+ double Sy=shift.gety();
+ s1 += Sx;
+ s2 += Sx;
+
+ if(width > L || (!p.cyclic() && (s1 < 0 || s2 > L))) {
+ ostringstream buf;
+ buf << "Cannot fit label \"" << label << "\" to path";
+ reportError(buf);
+ }
+
+ path q=p.subpath(p.arctime(s1),p.arctime(s2));
+
+ b += q.bounds(Sy,Sy+height);
+ Box=b;
+}
+
+bool drawLabelPath::write(texfile *out, const bbox&)
+{
+ bbox b=Box;
+ double Hoffset=getSetting<bool>("inlinetex") ? b.right : b.left;
+ b.shift(pair(-Hoffset,-b.bottom));
+
+ checkbounds();
+ if(drawLabel::pentype.invisible()) return true;
+ out->setpen(drawLabel::pentype);
+ out->verbatimline("\\psset{unit=1pt}%");
+ out->verbatim("\\pstextpath[");
+ out->verbatim(justify);
+ out->verbatim("]");
+ out->writepair(shift);
+ out->verbatim("{\\pstVerb{");
+ out->beginraw();
+ writeshiftedpath(out);
+ out->endraw();
+ out->verbatim("}}{");
+ out->verbatim(label);
+ out->verbatimline("}");
+ return true;
+}
+
+drawElement *drawLabelPath::transformed(const transform& t)
+{
+ return new drawLabelPath(label,size,transpath(t),justify,shift,
+ transpen(t));
+}
+
+} //namespace camp
diff --git a/Build/source/utils/asymptote/drawlabel.h b/Build/source/utils/asymptote/drawlabel.h
new file mode 100644
index 00000000000..14c2122f676
--- /dev/null
+++ b/Build/source/utils/asymptote/drawlabel.h
@@ -0,0 +1,86 @@
+/*****
+ * drawlabel.h
+ * John Bowman 2003/03/14
+ *
+ * Add a label to a picture.
+ *****/
+
+#ifndef DRAWLABEL_H
+#define DRAWLABEL_H
+
+#include "drawelement.h"
+#include "path.h"
+#include "angle.h"
+#include "transform.h"
+
+namespace camp {
+
+class drawLabel : public virtual drawElement {
+protected:
+ string label,size;
+ transform T; // A linear (shiftless) transformation.
+ pair position;
+ pair align;
+ pair scale;
+ pen pentype;
+ double width,height,depth;
+ bool havebounds;
+ bool suppress;
+ pair Align;
+ pair texAlign;
+ bbox Box;
+ bool enabled;
+
+public:
+ drawLabel(string label, string size, transform T, pair position,
+ pair align, pen pentype)
+ : label(label), size(size), T(shiftless(T)), position(position),
+ align(align), pentype(pentype), width(0.0), height(0.0), depth(0.0),
+ havebounds(false), suppress(false), enabled(false) {}
+
+ virtual ~drawLabel() {}
+
+ void getbounds(iopipestream& tex, const string& texengine);
+
+ void checkbounds();
+
+ void bounds(bbox& b, iopipestream&, boxvector&, bboxlist&);
+
+ bool texbounds(iopipestream& tex, string& s, const char **abort, bool warn);
+
+ int wait(iopipestream &tex, const char *s, const char **abort,
+ bool ignore=false);
+
+ bool islabel() {
+ return true;
+ }
+
+ bool write(texfile *out, const bbox&);
+
+ drawElement *transformed(const transform& t);
+
+ void labelwarning(const char *action);
+};
+
+class drawLabelPath : public drawLabel, public drawPathPenBase {
+private:
+ string justify;
+ pair shift;
+public:
+ drawLabelPath(string label, string size, path src,
+ string justify, pair shift, pen pentype) :
+ drawLabel(label,size,identity,pair(0.0,0.0),align,pentype),
+ drawPathPenBase(src,pentype), justify(justify), shift(shift) {}
+
+ virtual ~drawLabelPath() {}
+
+ void bounds(bbox& b, iopipestream& tex, boxvector&, bboxlist&);
+
+ bool write(texfile *out, const bbox&);
+
+ drawElement *transformed(const transform& t);
+};
+
+}
+
+#endif
diff --git a/Build/source/utils/asymptote/drawlayer.h b/Build/source/utils/asymptote/drawlayer.h
new file mode 100644
index 00000000000..05876afdfd0
--- /dev/null
+++ b/Build/source/utils/asymptote/drawlayer.h
@@ -0,0 +1,42 @@
+/*****
+ * drawlayer.h
+ * John Bowman
+ *
+ * Start a new postscript/TeX layer in picture.
+ *****/
+
+#ifndef DRAWLAYER_H
+#define DRAWLAYER_H
+
+#include "drawelement.h"
+
+namespace camp {
+
+class drawLayer : public drawElement {
+public:
+ drawLayer() {}
+
+ virtual ~drawLayer() {}
+
+ bool islayer() {return true;}
+};
+
+class drawNewPage : public drawLayer {
+public:
+ drawNewPage() {}
+
+ virtual ~drawNewPage() {}
+
+ bool islabel() {return true;}
+
+ bool write(texfile *out, const bbox&) {
+ out->verbatimline("\\newpage");
+ return true;
+ }
+};
+
+}
+
+GC_DECLARE_PTRFREE(camp::drawLayer);
+
+#endif
diff --git a/Build/source/utils/asymptote/drawpath.cc b/Build/source/utils/asymptote/drawpath.cc
new file mode 100644
index 00000000000..c1d2c85efc0
--- /dev/null
+++ b/Build/source/utils/asymptote/drawpath.cc
@@ -0,0 +1,173 @@
+/*****
+ * drawpath.cc
+ * Andy Hammerlindl 2002/06/06
+ *
+ * Stores a path that has been added to a picture.
+ *****/
+
+#include <sstream>
+#include <vector>
+#include <cfloat>
+
+#include "drawpath.h"
+#include "psfile.h"
+#include "util.h"
+
+namespace camp {
+
+
+double PatternLength(double arclength, const std::vector<double>& pat,
+ bool cyclic, double penwidth)
+{
+ double sum=0.0;
+
+ size_t n=pat.size();
+ for(unsigned i=0; i < n; i ++)
+ sum += pat[i]*penwidth;
+
+ if(sum == 0.0) return 0.0;
+
+ if(n % 2 == 1) sum *= 2.0; // On/off pattern repeats after 2 cycles.
+
+ // Fix bounding box resolution problem. Example:
+ // asy -f pdf testlinetype; gv -scale -2 testlinetype.pdf
+ if(!cyclic && pat[0] == 0) sum += 1.0e-3*penwidth;
+
+ double terminator=(cyclic && arclength >= 0.5*sum) ? 0.0 : pat[0]*penwidth;
+ int ncycle=(int)((arclength-terminator)/sum+0.5);
+
+ return (ncycle >= 1 || terminator >= 0.75*arclength) ?
+ ncycle*sum+terminator : 0.0;
+}
+
+pen adjustdash(pen& p, double arclength, bool cyclic)
+{
+ pen q=p;
+ // Adjust dash sizes to fit arclength; also compensate for linewidth.
+ string stroke=q.stroke();
+
+ if(!stroke.empty()) {
+ double penwidth=q.linetype().scale ? q.width() : 1.0;
+ double factor=penwidth;
+
+ std::vector<double> pat;
+
+ istringstream ibuf(stroke);
+ double l;
+ while(ibuf >> l) {
+ if(l < 0) l=0;
+ pat.push_back(l);
+ }
+
+ size_t n=pat.size();
+
+ if(q.linetype().adjust) {
+ if(arclength) {
+ if(n == 0) return q;
+
+ double denom=PatternLength(arclength,pat,cyclic,penwidth);
+ if(denom != 0.0) factor *= arclength/denom;
+ }
+ }
+
+ factor=max(factor,0.1);
+
+ ostringstream buf;
+ buf.setf(std::ios::fixed);
+ if(n > 0) {
+ for(size_t i=0; i < n-1; i++)
+ buf << pat[i]*factor << " ";
+ buf << pat[n-1]*factor;
+ }
+ q.setstroke(buf.str());
+ q.setoffset(q.linetype().offset*factor);
+ }
+ return q;
+}
+
+// Account for square or extended pen cap contributions to bounding box.
+void cap(bbox& b, double t, path p, pen pentype) {
+ transform T=pentype.getTransform();
+
+ double h=0.5*pentype.width();
+ pair v=p.dir(t);
+ transform S=rotate(conj(v))*shiftless(T);
+ double xx=S.getxx(), xy=S.getxy();
+ double yx=S.getyx(), yy=S.getyy();
+ double y=hypot(yx,yy);
+ if(y == 0) return;
+ double numer=xx*yx+xy*yy;
+ double x=numer/y;
+ pair z=shift(T)*p.point(t);
+
+ switch(pentype.cap()) {
+ case 0:
+ {
+ pair d=rotate(v)*pair(x,y)*h;
+ b += z+d;
+ b += z-d;
+ break;
+ }
+ case 2:
+ {
+ transform R=rotate(v);
+ double w=(xx*yy-xy*yx)/y;
+ pair dp=R*pair(x+w,y)*h;
+ pair dm=R*pair(x-w,y)*h;
+ b += z+dp;
+ b += z+dm;
+ b += z-dp;
+ b += z-dm;
+ break;
+ }
+ }
+}
+
+void drawPathPenBase::strokebounds(bbox& b, const path& p)
+{
+ Int l=p.length();
+ if(l < 0) return;
+
+ bbox penbounds=pentype.bounds();
+
+ if(cyclic() || pentype.cap() == 1) {
+ b += pad(p.bounds(),penbounds);
+ return;
+ }
+
+ b += p.internalbounds(penbounds);
+
+ cap(b,0,p,pentype);
+ cap(b,l,p,pentype);
+}
+
+bool drawPath::draw(psfile *out)
+{
+ Int n = p.size();
+ if (n == 0 || pentype.invisible())
+ return true;
+
+ pen pen0=adjustdash(pentype,p.arclength(),p.cyclic());
+
+ penSave(out);
+ penTranslate(out);
+
+ out->write(p);
+
+ penConcat(out);
+
+ out->setpen(pen0);
+
+ out->stroke();
+
+ penRestore(out);
+
+ return true;
+}
+
+drawElement *drawPath::transformed(const transform& t)
+{
+ return new drawPath(transpath(t), transpen(t));
+}
+
+} //namespace camp
diff --git a/Build/source/utils/asymptote/drawpath.h b/Build/source/utils/asymptote/drawpath.h
new file mode 100644
index 00000000000..c18ed3d628a
--- /dev/null
+++ b/Build/source/utils/asymptote/drawpath.h
@@ -0,0 +1,34 @@
+/*****
+ * drawpath.h
+ * Andy Hammerlindl 2002/06/06
+ *
+ * Stores a path that has been added to a picture.
+ *****/
+
+#ifndef DRAWPATH_H
+#define DRAWPATH_H
+
+#include "drawelement.h"
+#include "path.h"
+
+namespace camp {
+
+class drawPath : public drawPathPenBase {
+public:
+ drawPath(path src, pen pentype) : drawPathPenBase(src, pentype) {}
+
+ virtual ~drawPath() {}
+
+ void bounds(bbox& b, iopipestream&, boxvector&, bboxlist&) {
+ strokebounds(b,p);
+ }
+
+ bool draw(psfile *out);
+
+ drawElement *transformed(const transform& t);
+};
+
+pen adjustdash(pen& p, double arclength, bool cyclic);
+}
+
+#endif
diff --git a/Build/source/utils/asymptote/drawpath3.cc b/Build/source/utils/asymptote/drawpath3.cc
new file mode 100644
index 00000000000..75c9181acd3
--- /dev/null
+++ b/Build/source/utils/asymptote/drawpath3.cc
@@ -0,0 +1,99 @@
+/*****
+ * drawpath3.cc
+ *
+ * Stores a path3 that has been added to a picture.
+ *****/
+
+#include "drawpath3.h"
+
+namespace camp {
+
+using vm::array;
+
+inline void store(Triple& control, const triple& v)
+{
+ control[0]=v.getx();
+ control[1]=v.gety();
+ control[2]=v.getz();
+}
+
+bool drawPath3::write(prcfile *out)
+{
+ Int n=g.length();
+ if(n == 0 || invisible)
+ return true;
+
+ if(straight) {
+ controls=new Triple[n+1];
+ for(Int i=0; i <= n; ++i)
+ store(controls[i],g.point(i));
+ out->add(new PRCline(out,n+1,controls,color,scale3D));
+ } else {
+ int m=3*n+1;
+ controls=new Triple[m];
+ store(controls[0],g.point((Int) 0));
+ store(controls[1],g.postcontrol((Int) 0));
+ size_t k=1;
+ for(Int i=1; i < n; ++i) {
+ store(controls[++k],g.precontrol(i));
+ store(controls[++k],g.point(i));
+ store(controls[++k],g.postcontrol(i));
+ }
+ store(controls[++k],g.precontrol((Int) n));
+ store(controls[++k],g.point((Int) n));
+ out->add(new PRCBezierCurve(out,3,m,controls,color));
+ }
+ return true;
+}
+
+void drawPath3::render(GLUnurbs *nurb, double, const triple&, const triple&,
+ double, bool transparent)
+{
+#ifdef HAVE_LIBGL
+ Int n=g.length();
+ if(n == 0 || invisible || ((color.A < 1.0) ^ transparent))
+ return;
+
+ GLfloat Diffuse[]={0.0,0.0,0.0,color.A};
+ glMaterialfv(GL_FRONT,GL_DIFFUSE,Diffuse);
+
+ static GLfloat Black[]={0.0,0.0,0.0,1.0};
+ glMaterialfv(GL_FRONT,GL_AMBIENT,Black);
+
+ GLfloat Emissive[]={color.R,color.G,color.B,color.A};
+ glMaterialfv(GL_FRONT,GL_EMISSION,Emissive);
+
+ glMaterialfv(GL_FRONT,GL_SPECULAR,Black);
+
+ glMaterialf(GL_FRONT,GL_SHININESS,128.0);
+
+ if(straight) {
+ glBegin(GL_LINE_STRIP);
+ for(Int i=0; i <= n; ++i) {
+ triple v=g.point(i);
+ glVertex3f(v.getx(),v.gety(),v.getz());
+ }
+ glEnd();
+ } else {
+ for(Int i=0; i < n; ++i) {
+ static GLfloat knots[8]={0.0,0.0,0.0,0.0,1.0,1.0,1.0,1.0};
+ static GLfloat controlpoints[12];
+ store(controlpoints,g.point(i));
+ store(controlpoints+3,g.postcontrol(i));
+ store(controlpoints+6,g.precontrol(i+1));
+ store(controlpoints+9,g.point(i+1));
+
+ gluBeginCurve(nurb);
+ gluNurbsCurve(nurb,8,knots,3,controlpoints,4,GL_MAP1_VERTEX_3);
+ gluEndCurve(nurb);
+ }
+ }
+#endif
+}
+
+drawElement *drawPath3::transformed(const array& t)
+{
+ return new drawPath3(t,this);
+}
+
+} //namespace camp
diff --git a/Build/source/utils/asymptote/drawpath3.h b/Build/source/utils/asymptote/drawpath3.h
new file mode 100644
index 00000000000..25e9ffadf6d
--- /dev/null
+++ b/Build/source/utils/asymptote/drawpath3.h
@@ -0,0 +1,64 @@
+/*****
+ * drawpath3.h
+ *
+ * Stores a path3 that has been added to a picture.
+ *****/
+
+#ifndef DRAWPATH3_H
+#define DRAWPATH3_H
+
+#include "drawelement.h"
+#include "path3.h"
+
+namespace camp {
+
+class drawPath3 : public drawElement {
+protected:
+ const path3 g;
+ bool straight;
+ RGBAColour color;
+ bool invisible;
+ triple Min,Max;
+ Triple *controls;
+public:
+ drawPath3(path3 g, const pen&p) :
+ g(g), straight(g.piecewisestraight()), color(rgba(p)),
+ invisible(p.invisible()), Min(g.min()), Max(g.max()), controls(NULL) {}
+
+ drawPath3(const vm::array& t, const drawPath3 *s) :
+ g(camp::transformed(t,s->g)), straight(s->straight), color(s->color),
+ invisible(s->invisible), Min(g.min()), Max(g.max()), controls(NULL) {}
+
+ virtual ~drawPath3() {
+ if(controls) delete controls;
+ }
+
+ bool is3D() {return true;}
+
+ void bounds(bbox3& B) {
+ B.add(Min);
+ B.add(Max);
+ }
+
+ void bounds(pair &b, double (*m)(double, double),
+ double (*x)(const triple&, double*),
+ double (*y)(const triple&, double*),
+ double *t, bool &first) {
+ pair z=g.bounds(m,x,y,t);
+ if(first) {
+ b=z;
+ first=false;
+ } else b=pair(m(b.getx(),z.getx()),m(b.gety(),z.gety()));
+ }
+
+ bool write(prcfile *out);
+
+ void render(GLUnurbs*, double, const triple&, const triple&, double,
+ bool transparent);
+
+ drawElement *transformed(const vm::array& t);
+};
+
+}
+
+#endif
diff --git a/Build/source/utils/asymptote/drawsurface.cc b/Build/source/utils/asymptote/drawsurface.cc
new file mode 100644
index 00000000000..af6f0cd8722
--- /dev/null
+++ b/Build/source/utils/asymptote/drawsurface.cc
@@ -0,0 +1,299 @@
+/*****
+ * drawsurface.cc
+ *
+ * Stores a surface that has been added to a picture.
+ *****/
+
+#include "drawsurface.h"
+
+namespace camp {
+
+const double pixel=1.0; // Adaptive rendering constant.
+
+using vm::array;
+triple drawSurface::c3[];
+
+inline void initMatrix(GLfloat *v, double x, double ymin, double zmin,
+ double ymax, double zmax)
+{
+ v[0]=x;
+ v[1]=ymin;
+ v[2]=zmin;
+ v[3]=1.0;
+ v[4]=x;
+ v[5]=ymin;
+ v[6]=zmax;
+ v[7]=1.0;
+ v[8]=x;
+ v[9]=ymax;
+ v[10]=zmin;
+ v[11]=1.0;
+ v[12]=x;
+ v[13]=ymax;
+ v[14]=zmax;
+ v[15]=1.0;
+}
+
+void drawSurface::bounds(bbox3& b)
+{
+ static double c1[16];
+
+ for(int i=0; i < 16; ++i)
+ c1[i]=controls[i][0];
+ double c0=c1[0];
+ double xmin=bound(c1,min,b.empty ? c0 : min(c0,b.left));
+ double xmax=bound(c1,max,b.empty ? c0 : max(c0,b.right));
+
+ for(int i=0; i < 16; ++i)
+ c1[i]=controls[i][1];
+ c0=c1[0];
+ double ymin=bound(c1,min,b.empty ? c0 : min(c0,b.bottom));
+ double ymax=bound(c1,max,b.empty ? c0 : max(c0,b.top));
+
+ for(int i=0; i < 16; ++i)
+ c1[i]=controls[i][2];
+ c0=c1[0];
+ double zmin=bound(c1,min,b.empty ? c0 : min(c0,b.lower));
+ double zmax=bound(c1,max,b.empty ? c0 : max(c0,b.upper));
+
+ Min=triple(xmin,ymin,zmin);
+ Max=triple(xmax,ymax,zmax);
+
+ b.add(Min);
+ b.add(Max);
+}
+
+void drawSurface::bounds(pair &b, double (*m)(double, double),
+ double (*x)(const triple&, double*),
+ double (*y)(const triple&, double*),
+ double *t, bool &first)
+{
+ for(int i=0; i < 16; ++i) {
+ double *ci=controls[i];
+ c3[i]=triple(ci[0],ci[1],ci[2]);
+ }
+
+ if(first) {
+ triple v=c3[0];
+ b=pair(x(v,t),y(v,t));
+ first=false;
+ }
+
+ b=pair(bound(c3,m,x,t,b.getx()),bound(c3,m,y,t,b.gety()));
+}
+
+bool drawSurface::write(prcfile *out)
+{
+ if(invisible)
+ return true;
+
+ PRCMaterial m(ambient,diffuse,emissive,specular,opacity,shininess);
+ out->add(new PRCBezierSurface(out,3,3,4,4,controls,m,granularity));
+
+ return true;
+}
+
+// return the perpendicular displacement of a point z from the plane
+// through u with unit normal n.
+inline triple displacement2(const Triple& z, const Triple& u, const triple& n)
+{
+ triple Z=triple(z)-triple(u);
+ return n != triple(0,0,0) ? dot(Z,n)*n : Z;
+}
+
+inline triple maxabs(triple u, triple v)
+{
+ return triple(max(fabs(u.getx()),fabs(v.getx())),
+ max(fabs(u.gety()),fabs(v.gety())),
+ max(fabs(u.getz()),fabs(v.getz())));
+}
+
+inline triple displacement(const Triple& z0, const Triple& c0,
+ const Triple& c1, const Triple& z1)
+{
+ triple Z0(z0);
+ triple Z1(z1);
+ return maxabs(displacement(triple(c0[0],c0[1],c0[2]),Z0,Z1),
+ displacement(triple(c1[0],c1[1],c1[2]),Z0,Z1));
+}
+
+void drawSurface::displacement()
+{
+#ifdef HAVE_LIBGL
+ initMatrix(v1,Min.getx(),Min.gety(),Min.getz(),Max.gety(),Max.getz());
+ initMatrix(v2,Max.getx(),Min.gety(),Min.getz(),Max.gety(),Max.getz());
+
+ for(int i=0; i < 16; ++i)
+ store(c+3*i,controls[i]);
+
+ static const triple zero;
+ havenormal=normal != zero;
+ havetransparency=havecolors ? colors[3]+colors[7]+colors[11]+colors[15] < 4.0
+ : diffuse.A < 1.0;
+ if(havenormal) {
+ store(Normal,normal);
+ d=zero;
+
+ if(!straight) {
+ for(int i=1; i < 16; ++i)
+ d=camp::maxabs(d,camp::displacement2(controls[i],controls[0],normal));
+
+ dperp=d;
+
+ for(int i=0; i < 4; ++i)
+ d=camp::maxabs(d,camp::displacement(controls[4*i],controls[4*i+1],
+ controls[4*i+2],controls[4*i+3]));
+ for(int i=0; i < 4; ++i)
+ d=camp::maxabs(d,camp::displacement(controls[i],controls[i+4],
+ controls[i+8],controls[i+12]));
+ }
+ }
+#endif
+}
+
+inline double fraction(double d, double size)
+{
+ return size == 0 ? 1.0 : min(fabs(d)/size,1.0);
+}
+
+// estimate the viewport fraction associated with the displacement d
+inline double fraction(const triple& d, const triple& size)
+{
+ return max(max(fraction(d.getx(),size.getx()),
+ fraction(d.gety(),size.gety())),
+ fraction(d.getz(),size.getz()));
+}
+
+void drawSurface::render(GLUnurbs *nurb, double size2,
+ const triple& Min, const triple& Max,
+ double perspective, bool transparent)
+{
+#ifdef HAVE_LIBGL
+ if(invisible || (havetransparency ^ transparent)) return;
+
+ static GLfloat v[16];
+
+ glPushMatrix();
+ glMultMatrixf(v1);
+ glGetFloatv(GL_MODELVIEW_MATRIX,v);
+ glPopMatrix();
+
+ bbox3 B(v[0],v[1],v[2]);
+ B.addnonempty(v[4],v[5],v[6]);
+ B.addnonempty(v[8],v[9],v[10]);
+ B.addnonempty(v[12],v[13],v[14]);
+
+ glPushMatrix();
+ glMultMatrixf(v2);
+ glGetFloatv(GL_MODELVIEW_MATRIX,v);
+ glPopMatrix();
+
+ B.addnonempty(v[0],v[1],v[2]);
+ B.addnonempty(v[4],v[5],v[6]);
+ B.addnonempty(v[8],v[9],v[10]);
+ B.addnonempty(v[12],v[13],v[14]);
+
+ triple M=B.Max();
+ triple m=B.Min();
+
+ double s;
+ if(perspective) {
+ double f=m.getz()*perspective;
+ double F=M.getz()*perspective;
+ s=max(f,F);
+ if(M.getx() < min(f*Min.getx(),F*Min.getx()) ||
+ m.getx() > max(f*Max.getx(),F*Max.getx()) ||
+ M.gety() < min(f*Min.gety(),F*Min.gety()) ||
+ m.gety() > max(f*Max.gety(),F*Max.gety()) ||
+ M.getz() < Min.getz() ||
+ m.getz() > Max.getz()) return;
+ } else {
+ s=1.0;
+ if(M.getx() < Min.getx() || m.getx() > Max.getx() ||
+ M.gety() < Min.gety() || m.gety() > Max.gety() ||
+ M.getz() < Min.getz() || m.getz() > Max.getz()) return;
+ }
+
+ bool ambientdiffuse=true;
+ bool emission=true;
+
+ if(havecolors) {
+ glEnable(GL_COLOR_MATERIAL);
+ if(lighton) {
+ glColorMaterial(GL_FRONT_AND_BACK,GL_AMBIENT_AND_DIFFUSE);
+ ambientdiffuse=false;
+ } else {
+ glColorMaterial(GL_FRONT_AND_BACK,GL_EMISSION);
+ emission=false;
+ }
+ }
+
+ if(ambientdiffuse) {
+ GLfloat Diffuse[]={diffuse.R,diffuse.G,diffuse.B,diffuse.A};
+ glMaterialfv(GL_FRONT_AND_BACK,GL_DIFFUSE,Diffuse);
+
+ GLfloat Ambient[]={ambient.R,ambient.G,ambient.B,ambient.A};
+ glMaterialfv(GL_FRONT_AND_BACK,GL_AMBIENT,Ambient);
+ }
+
+ if(emission) {
+ GLfloat Emissive[]={emissive.R,emissive.G,emissive.B,emissive.A};
+ glMaterialfv(GL_FRONT_AND_BACK,GL_EMISSION,Emissive);
+ }
+
+ GLfloat Specular[]={specular.R,specular.G,specular.B,specular.A};
+ glMaterialfv(GL_FRONT_AND_BACK,GL_SPECULAR,Specular);
+
+ glMaterialf(GL_FRONT_AND_BACK,GL_SHININESS,128.0*shininess);
+
+ triple size3=triple(s*(Max.getx()-Min.getx()),s*(Max.gety()-Min.gety()),
+ Max.getz()-Min.getz());
+
+ if(!havenormal || (!straight && (fraction(d,size3)*size2 >= pixel ||
+ granularity == 0))) {
+ if(lighton) {
+ if(havenormal && fraction(dperp,size3)*size2 <= 0.1) {
+ glNormal3fv(Normal);
+ gluNurbsCallback(nurb,GLU_NURBS_NORMAL,NULL);
+ } else
+ gluNurbsCallback(nurb,GLU_NURBS_NORMAL,(_GLUfuncptr) glNormal3fv);
+ }
+ static GLfloat bezier[]={0.0,0.0,0.0,0.0,1.0,1.0,1.0,1.0};
+ gluBeginSurface(nurb);
+ gluNurbsSurface(nurb,8,bezier,8,bezier,3,12,c,4,4,GL_MAP2_VERTEX_3);
+ if(havecolors) {
+ static GLfloat linear[]={0.0,0.0,1.0,1.0};
+ gluNurbsSurface(nurb,4,linear,4,linear,4,8,colors,2,2,GL_MAP2_COLOR_4);
+ }
+
+ gluEndSurface(nurb);
+ } else {
+ glBegin(GL_QUADS);
+ if(lighton)
+ glNormal3fv(Normal);
+ if(havecolors)
+ glColor4fv(colors);
+ glVertex3fv(c);
+ if(havecolors)
+ glColor4fv(colors+4);
+ glVertex3fv(c+9);
+ if(havecolors)
+ glColor4fv(colors+12);
+ glVertex3fv(c+45);
+ if(havecolors)
+ glColor4fv(colors+8);
+ glVertex3fv(c+36);
+ glEnd();
+ }
+
+ if(havecolors)
+ glDisable(GL_COLOR_MATERIAL);
+#endif
+}
+
+drawElement *drawSurface::transformed(const array& t)
+{
+ return new drawSurface(t,this);
+}
+
+} //namespace camp
diff --git a/Build/source/utils/asymptote/drawsurface.h b/Build/source/utils/asymptote/drawsurface.h
new file mode 100644
index 00000000000..2bd8aeea4d4
--- /dev/null
+++ b/Build/source/utils/asymptote/drawsurface.h
@@ -0,0 +1,145 @@
+/*****
+ * drawsurface.h
+ *
+ * Stores a surface that has been added to a picture.
+ *****/
+
+#ifndef DRAWSURFACE_H
+#define DRAWSURFACE_H
+
+#include "drawelement.h"
+#include "triple.h"
+#include "arrayop.h"
+#include "path3.h"
+
+namespace camp {
+
+class drawSurface : public drawElement {
+protected:
+ Triple controls[16];
+ bool straight;
+ RGBAColour diffuse;
+ RGBAColour ambient;
+ RGBAColour emissive;
+ RGBAColour specular;
+ double opacity;
+ double shininess;
+ double granularity;
+ triple normal;
+ bool lighton;
+
+ bool invisible;
+ triple Min,Max;
+ static triple c3[16];
+ GLfloat *colors;
+ bool havecolors;
+
+#ifdef HAVE_LIBGL
+ GLfloat c[48];
+ triple d; // Maximum deviation of surface from a quadrilateral.
+ triple dperp;
+ GLfloat v1[16];
+ GLfloat v2[16];
+ GLfloat Normal[3];
+ bool havenormal;
+ bool havetransparency;
+#endif
+
+ void storecolor(int i, const vm::array &pens, int j) {
+ pen p=vm::read<camp::pen>(pens,j);
+ p.torgb();
+ colors[i]=p.red();
+ colors[i+1]=p.green();
+ colors[i+2]=p.blue();
+ colors[i+3]=p.opacity();
+ }
+
+public:
+ drawSurface(const vm::array& g, bool straight, const vm::array&p,
+ double opacity, double shininess, double granularity,
+ triple normal, bool lighton, const vm::array &pens) :
+ straight(straight), opacity(opacity), shininess(shininess),
+ granularity(granularity), normal(unit(normal)), lighton(lighton) {
+ string wrongsize=
+ "Bezier surface patch requires 4x4 array of triples and array of 4 pens";
+ if(checkArray(&g) != 4 || checkArray(&p) != 4)
+ reportError(wrongsize);
+
+ pen surfacepen=vm::read<camp::pen>(p,0);
+ invisible=surfacepen.invisible();
+
+ diffuse=rgba(surfacepen);
+ ambient=rgba(vm::read<camp::pen>(p,1));
+ emissive=rgba(vm::read<camp::pen>(p,2));
+ specular=rgba(vm::read<camp::pen>(p,3));
+
+#ifdef HAVE_LIBGL
+ int size=checkArray(&pens);
+ havecolors=size > 0;
+ if(havecolors) {
+ colors=new GLfloat[16];
+ if(size != 4) reportError(wrongsize);
+ storecolor(0,pens,0);
+ storecolor(4,pens,1);
+ storecolor(12,pens,2);
+ storecolor(8,pens,3);
+ }
+#endif
+
+ size_t k=0;
+ for(size_t i=0; i < 4; ++i) {
+ vm::array *gi=vm::read<vm::array*>(g,i);
+ size_t gisize=checkArray(gi);
+ if(gisize != 4)
+ reportError(wrongsize);
+ for(size_t j=0; j < 4; ++j) {
+ triple v=vm::read<triple>(gi,j);
+ controls[k][0]=v.getx();
+ controls[k][1]=v.gety();
+ controls[k][2]=v.getz();
+ ++k;
+ }
+ }
+ }
+
+ drawSurface(const vm::array& t, const drawSurface *s) :
+ straight(s->straight), diffuse(s->diffuse), ambient(s->ambient),
+ emissive(s->emissive), specular(s->specular), opacity(s->opacity),
+ shininess(s->shininess), granularity(s->granularity), lighton(s->lighton),
+ invisible(s->invisible), colors(s->colors), havecolors(s->havecolors) {
+ for(size_t i=0; i < 16; ++i) {
+ const double *c=s->controls[i];
+ triple v=run::operator *(t,triple(c[0],c[1],c[2]));
+ controls[i][0]=v.getx();
+ controls[i][1]=v.gety();
+ controls[i][2]=v.getz();
+ }
+ normal=run::multshiftless(t,s->normal);
+ }
+
+ bool is3D() {return true;}
+
+ void bounds(bbox3& b);
+
+ void bounds(pair &b, double (*m)(double, double),
+ double (*x)(const triple&, double*),
+ double (*y)(const triple&, double*),
+ double *t, bool &first);
+
+ virtual ~drawSurface() {
+ if(havecolors)
+ delete[] colors;
+ }
+
+ bool write(prcfile *out);
+
+ void displacement();
+ void render(GLUnurbs *nurb, double, const triple& Min, const triple& Max,
+ double perspective, bool transparent);
+
+ drawElement *transformed(const vm::array& t);
+};
+
+}
+
+#endif
diff --git a/Build/source/utils/asymptote/drawverbatim.h b/Build/source/utils/asymptote/drawverbatim.h
new file mode 100644
index 00000000000..24c5be45d14
--- /dev/null
+++ b/Build/source/utils/asymptote/drawverbatim.h
@@ -0,0 +1,57 @@
+/*****
+ * drawverbatim.h
+ * John Bowman 2003/03/18
+ *
+ * Add verbatim postscript to picture.
+ *****/
+
+#ifndef DRAWVERBATIM_H
+#define DRAWVERBATIM_H
+
+#include "drawelement.h"
+
+namespace camp {
+
+enum Language {PostScript,TeX};
+
+class drawVerbatim : public drawElement {
+private:
+ Language language;
+ string text;
+ bool havebounds;
+ pair min,max;
+public:
+ drawVerbatim(Language language, const string& text) :
+ language(language), text(text), havebounds(false) {}
+
+ drawVerbatim(Language language, const string& text, pair min,
+ pair max) :
+ language(language), text(text), havebounds(true), min(min), max(max) {}
+
+ virtual ~drawVerbatim() {}
+
+ void bounds(bbox& b, iopipestream&, boxvector&, bboxlist&) {
+ if(havebounds) {
+ b += min;
+ b += max;
+ }
+ }
+
+ bool islabel() {
+ return language == TeX;
+ }
+
+ bool draw(psfile *out) {
+ if(language == PostScript) out->verbatimline(text);
+ return true;
+ }
+
+ bool write(texfile *out, const bbox&) {
+ if(language == TeX) out->verbatimline(stripblanklines(text));
+ return true;
+ }
+};
+
+}
+
+#endif
diff --git a/Build/source/utils/asymptote/entry.cc b/Build/source/utils/asymptote/entry.cc
new file mode 100644
index 00000000000..99869abb87a
--- /dev/null
+++ b/Build/source/utils/asymptote/entry.cc
@@ -0,0 +1,365 @@
+/*****
+ * entry.cc
+ * Andy Hammerlindl 2002/08/29
+ *
+ * All variables, built-in functions and user-defined functions reside
+ * within the same namespace. To keep track of all these, table of
+ * "entries" is used.
+ *****/
+
+#include <iostream>
+
+#include <cmath>
+#include <utility>
+#include "entry.h"
+#include "coder.h"
+
+using types::signature;
+
+namespace trans {
+
+bool entry::pr::check(action act, coder &c) {
+ // We assume PUBLIC permissions and one's without an associated record are not
+ // stored.
+ assert(perm!=PUBLIC && r!=0);
+ return c.inTranslation(r->getLevel()) ||
+ (perm == RESTRICTED && act != WRITE);
+}
+
+void entry::pr::report(action act, position pos, coder &c) {
+ if (!c.inTranslation(r->getLevel())) {
+ if (perm == PRIVATE) {
+ em.error(pos);
+ em << "accessing private field outside of structure";
+ }
+ else if (perm == RESTRICTED && act == WRITE) {
+ em.error(pos);
+ em << "modifying non-public field outside of structure";
+ }
+ }
+}
+
+entry::entry(entry &e1, entry &e2) : where(e2.where), pos(e2.pos) {
+ perms.insert(perms.end(), e1.perms.begin(), e1.perms.end());
+ perms.insert(perms.end(), e2.perms.begin(), e2.perms.end());
+}
+
+entry::entry(entry &base, permission perm, record *r)
+ : where(base.where), pos(base.pos) {
+ perms.insert(perms.end(), base.perms.begin(), base.perms.end());
+ addPerm(perm, r);
+}
+
+bool entry::checkPerm(action act, coder &c) {
+ for (mem::list<pr>::iterator p=perms.begin(); p != perms.end(); ++p)
+ if (!p->check(act, c))
+ return false;
+ return true;
+}
+
+void entry::reportPerm(action act, position pos, coder &c) {
+ for (mem::list<pr>::iterator p=perms.begin(); p != perms.end(); ++p)
+ p->report(act, pos, c);
+}
+
+
+varEntry::varEntry(varEntry &qv, varEntry &v)
+ : entry(qv,v), t(v.t),
+ location(new qualifiedAccess(qv.location, qv.getLevel(), v.location)) {}
+
+frame *varEntry::getLevel() {
+ record *r=dynamic_cast<record *>(t);
+ assert(r);
+ return r->getLevel();
+}
+
+void varEntry::encode(action act, position pos, coder &c) {
+ reportPerm(act, pos, c);
+ getLocation()->encode(act, pos, c);
+}
+
+void varEntry::encode(action act, position pos, coder &c, frame *top) {
+ reportPerm(act, pos, c);
+ getLocation()->encode(act, pos, c, top);
+}
+
+varEntry *qualifyVarEntry(varEntry *qv, varEntry *v)
+{
+ return qv ? (v ? new varEntry(*qv,*v) : qv) : v;
+}
+
+
+bool tenv::add(symbol *dest,
+ names_t::value_type &x, varEntry *qualifier, coder &c)
+{
+ if (!x.second.empty()) {
+ tyEntry *ent=x.second.front();
+ if (ent->checkPerm(READ, c)) {
+ enter(dest, qualifyTyEntry(qualifier, ent));
+ return true;
+ }
+ }
+ return false;
+}
+
+void tenv::add(tenv& source, varEntry *qualifier, coder &c) {
+ // Enter each distinct (unshadowed) name,type pair.
+ for(names_t::iterator p = source.names.begin(); p != source.names.end(); ++p)
+ add(p->first, *p, qualifier, c);
+}
+
+bool tenv::add(symbol *src, symbol *dest,
+ tenv& source, varEntry *qualifier, coder &c) {
+ names_t::iterator p = source.names.find(src);
+ if (p != source.names.end())
+ return add(dest, *p, qualifier, c);
+ else
+ return false;
+}
+
+#ifdef NOHASH //{{{
+void venv::add(venv& source, varEntry *qualifier, coder &c)
+{
+ // Enter each distinct (unshadowed) name,type pair.
+ for(names_t::iterator p = source.names.begin();
+ p != source.names.end();
+ ++p)
+ add(p->first, p->first, source, qualifier, c);
+}
+
+bool venv::add(symbol *src, symbol *dest,
+ venv& source, varEntry *qualifier, coder &c)
+{
+ bool added=false;
+ name_t &list=source.names[src];
+ types::overloaded set; // To keep track of what is shadowed.
+
+ for(name_iterator p = list.begin();
+ p != list.end();
+ ++p) {
+ varEntry *v=*p;
+ if (!equivalent(v->getType(), &set)) {
+ set.addDistinct(v->getType(), src->special);
+ if (v->checkPerm(READ, c)) {
+ enter(dest, qualifyVarEntry(qualifier, v));
+ added=true;
+ }
+ }
+ }
+
+ return added;
+}
+
+varEntry *venv::lookByType(symbol *name, ty *t)
+{
+ // Find first applicable function.
+ name_t &list = names[name];
+ for(name_iterator p = list.begin();
+ p != list.end();
+ ++p) {
+ if (equivalent((*p)->getType(), t))
+ return *p;
+ }
+ return 0;
+}
+
+void venv::list(record *module)
+{
+ bool where=settings::getSetting<bool>("where");
+ // List all functions and variables.
+ for(names_t::iterator N = names.begin(); N != names.end(); ++N) {
+ symbol *s=N->first;
+ name_t &list=names[s];
+ for(name_iterator p = list.begin(); p != list.end(); ++p) {
+ if(!module || (*p)->whereDefined() == module) {
+ if(where) cout << (*p)->getPos();
+ (*p)->getType()->printVar(cout, s);
+ cout << ";\n";
+ }
+ }
+ }
+ flush(cout);
+}
+
+varEntry *venv::lookInTopScope(symbol *name, ty *t)
+{
+ scope_t &scope = scopes.front();
+ for (scope_iterator p = scope.lower_bound(name);
+ p != scope.upper_bound(name);
+ ++p) {
+ if (name == p->first &&
+ equivalent(t, p->second->getType(), name->special))
+ return p->second;
+ }
+ return 0;
+}
+
+ty *venv::getType(symbol *name)
+{
+ types::overloaded set;
+
+ // Find all applicable functions in scope.
+ name_t &list = names[name];
+
+ for(name_iterator p = list.begin();
+ p != list.end();
+ ++p) {
+ set.addDistinct((*p)->getType(), name->special);
+ }
+
+ return set.simplify();
+}
+// }}}
+#else // {{{
+
+ostream& operator<< (ostream& out, const venv::key &k) {
+ k.t->printVar(out, k.name);
+ return out;
+}
+
+#if TEST_COLLISION
+bool venv::keyeq::operator()(const key k, const key l) const {
+ keyhash kh;
+ if (kh(k)==kh(l)) {
+ if (base(k,l))
+ return true;
+ else {
+ cerr << "collision: " << endl;
+ cerr << " " << k << " -> " << kh(k) << endl;
+ cerr << " " << l << " -> " << kh(l) << endl;
+ }
+ }
+ return false;
+}
+#else
+bool venv::keyeq::operator()(const key k, const key l) const {
+#if 0
+ cerr << "k.t = " << k.t << " " << k << endl;
+ cerr << "l.t = " << l.t << " " << l << endl;
+#endif
+ return k.name==l.name &&
+ (k.name->special ? equivalent(k.t, l.t) :
+ equivalent(k.t->getSignature(),
+ l.t->getSignature()));
+}
+#endif
+
+void venv::remove(key k) {
+ //cerr << "removing: " << k << endl;
+ value *&val=all[k];
+ assert(val);
+ if (val->next) {
+ val->next->shadowed=false;
+ value *temp=val->next;
+ val->next=0;
+ val=temp;
+ }
+ else
+ all.erase(k);
+
+ // Don't erase it from scopes.top() as that will be popped of the stack at
+ // the end of endScope anyway.
+
+ names[k.name].pop_front();
+}
+
+void venv::enter(symbol *name, varEntry *v) {
+ assert(!scopes.empty());
+ key k(name, v);
+#ifdef DEBUG_ENTRY
+ cout << "entering: " << k << " (t=" << k.t << ")" << endl;
+#endif
+ value *val=new value(v);
+
+#ifdef DEBUG_ENTRY
+ keymap::iterator p=all.find(k);
+ if (p!=all.end()) {
+ cout << " over: " << p->first << endl;
+ }
+#endif
+
+ val->next=all[k];
+ if (val->next)
+ val->next->shadowed=true;
+
+ all[k]=val;
+ scopes.top().insert(keymultimap::value_type(k,val));
+ names[k.name].push_front(val);
+}
+
+void venv::add(venv& source, varEntry *qualifier, coder &c)
+{
+ // Enter each distinct (unshadowed) name,type pair.
+ for(keymap::iterator p = source.all.begin(); p != source.all.end(); ++p) {
+ varEntry *v=p->second->v;
+ if (v->checkPerm(READ, c))
+ enter(p->first.name, qualifyVarEntry(qualifier, v));
+ }
+}
+
+bool venv::add(symbol *src, symbol *dest,
+ venv& source, varEntry *qualifier, coder &c)
+{
+ bool added=false;
+ values &list=source.names[src];
+
+ for (values::iterator p=list.begin(); p!=list.end(); ++p)
+ if (!(*p)->shadowed) {
+ varEntry *v=(*p)->v;
+ if (v->checkPerm(READ, c)) {
+ enter(dest, qualifyVarEntry(qualifier, v));
+ added=true;
+ }
+ }
+
+ return added;
+}
+
+
+ty *venv::getType(symbol *name)
+{
+ //cerr << "getType: " << *name << endl;
+ types::overloaded set;
+ values &list=names[name];
+
+ for (values::iterator p=list.begin(); p!=list.end(); ++p)
+ if (!(*p)->shadowed)
+ set.add((*p)->v->getType());
+
+ return set.simplify();
+}
+
+void venv::listValues(symbol *name, values &vals, record *module)
+{
+ ostream& out=cout;
+
+ bool where=settings::getSetting<bool>("where");
+ for(values::iterator p = vals.begin(); p != vals.end(); ++p) {
+ if(!module || (*p)->v->whereDefined() == module) {
+ if(where) out << (*p)->v->getPos();
+ if ((*p)->shadowed)
+ out << " <shadowed> ";
+ (*p)->v->getType()->printVar(out, name);
+ out << ";\n";
+ }
+ }
+ flush(out);
+}
+
+void venv::list(record *module)
+{
+ // List all functions and variables.
+ for(namemap::iterator N = names.begin(); N != names.end(); ++N)
+ listValues(N->first, N->second,module);
+}
+
+void venv::completions(mem::list<symbol *>& l, string start)
+{
+ for(namemap::iterator N = names.begin(); N != names.end(); ++N)
+ if (prefix(start, *(N->first)) && !N->second.empty())
+ l.push_back(N->first);
+}
+
+#endif // }}}
+
+} // namespace trans
diff --git a/Build/source/utils/asymptote/entry.h b/Build/source/utils/asymptote/entry.h
new file mode 100644
index 00000000000..c4ad2bef451
--- /dev/null
+++ b/Build/source/utils/asymptote/entry.h
@@ -0,0 +1,392 @@
+/*****
+ * entry.h
+ * Andy Hammerlindl 2002/08/29
+ *
+ * All variables, built-in functions and user-defined functions reside
+ * within the same namespace. To keep track of all these, a table of
+ * "entries" is used.
+ *****/
+
+#ifndef ENTRY_H
+#define ENTRY_H
+
+#include <iostream>
+
+#include "common.h"
+#include "frame.h"
+#include "table.h"
+#include "types.h"
+#include "modifier.h"
+
+using sym::symbol;
+using types::ty;
+using types::signature;
+
+// Forward declaration.
+namespace types {
+class record;
+}
+using types::record;
+
+namespace trans {
+
+// An entry is associated to a name in the (variable or type) environment, and
+// has permission based on the enclosing records where it was defined or
+// imported.
+class entry : public gc {
+ struct pr {
+ permission perm;
+ record *r;
+
+ pr(permission perm, record *r)
+ : perm(perm), r(r) {}
+
+ // Returns true if the permission allows access in this context.
+ bool check(action act, coder &c);
+
+ // Reports an error if permission is not allowed.
+ void report(action act, position pos, coder &c);
+ };
+
+ mem::list<pr> perms;
+
+ void addPerm(permission perm, record *r) {
+ // Only store restrictive permissions.
+ if (perm != PUBLIC && r)
+ perms.push_back(pr(perm,r));
+ }
+
+ // The record where the variable or type is defined, or 0 if the entry is
+ // not a field.
+ record *where;
+
+ // The location (file and line number) where the entry was defined.
+ position pos;
+
+public:
+ entry(record *where, position pos) : where(where), pos(pos) {}
+ entry(permission perm, record *r, record *where, position pos)
+ : where(where), pos(pos) {
+ addPerm(perm, r);
+ }
+
+ // (Non-destructively) merges two entries, appending permission lists.
+ // The 'where' member is taken from the second entry.
+ entry(entry &e1, entry &e2);
+
+ // Create an entry with one more permission in the list.
+ entry(entry &base, permission perm, record *r);
+
+ bool checkPerm(action act, coder &c);
+ void reportPerm(action act, position pos, coder &c);
+
+ record *whereDefined() {
+ return where;
+ }
+
+ position getPos() {
+ return pos;
+ }
+};
+
+class varEntry : public entry {
+ ty *t;
+ access *location;
+
+public:
+ varEntry(ty *t, access *location, record *where, position pos)
+ : entry(where, pos), t(t), location(location) {}
+
+ varEntry(ty *t, access *location, permission perm, record *r,
+ record *where, position pos)
+ : entry(perm, r, where, pos), t(t), location(location) {}
+
+ // (Non-destructively) merges two varEntries, creating a qualified varEntry.
+ varEntry(varEntry &qv, varEntry &v);
+
+ ty *getType()
+ { return t; }
+
+ signature *getSignature()
+ {
+ return t->getSignature();
+ }
+
+ access *getLocation()
+ { return location; }
+
+ frame *getLevel();
+
+ // Encodes the access, but also checks permissions.
+ void encode(action act, position pos, coder &c);
+ void encode(action act, position pos, coder &c, frame *top);
+};
+
+varEntry *qualifyVarEntry(varEntry *qv, varEntry *v);
+
+// As looked-up types can be allocated in a new expression, we need to know
+// what frame they should be allocated on. Type entries store this extra
+// information along with the type.
+class tyEntry : public entry {
+public:
+ ty *t;
+ varEntry *v; // NOTE: Name isn't very descriptive.
+
+ tyEntry(ty *t, varEntry *v, record *where, position pos)
+ : entry(where, pos), t(t), v(v) {}
+
+ tyEntry(tyEntry *base, permission perm, record *r)
+ : entry(*base, perm, r), t(base->t), v(base->v) {}
+
+ // Records need a varEntry that refers back to the qualifier qv; i.e. in
+ // the last new of the code
+ // struct A {
+ // struct B {}
+ // }
+ // A a=new A;
+ // unravel a;
+ // new B;
+ // we need to put a's frame on the stack before allocating an instance of B.
+ // NOTE: A possible optimization could be to only qualify the varEntry if
+ // the type is a record, as other types don't use the varEntry.
+private:
+ tyEntry(tyEntry *base, varEntry *qv)
+ : entry(*base, *qv), t(base->t), v(qualifyVarEntry(qv, base->v)) {}
+
+public:
+ // Since the constructor can only be used when qv is non-null it is private
+ // for safety reasons, and we provide this method instead.
+ friend tyEntry *qualifyTyEntry(varEntry *qv, tyEntry *ent);
+};
+
+inline tyEntry *qualifyTyEntry(varEntry *qv, tyEntry *ent) {
+ return qv ? new tyEntry(ent, qv) : ent;
+}
+
+// The type environment.
+class tenv : public sym::table<tyEntry *> {
+ bool add(symbol *dest, names_t::value_type &x, varEntry *qualifier,
+ coder &c);
+public:
+ // Add the entries in one environment to another, if qualifier is
+ // non-null, it is a record and the source environment is its types. The
+ // coder is used to see which entries are accessible and should be added.
+ void add(tenv& source, varEntry *qualifier, coder &c);
+
+ // Adds entries of the name src in source as the name dest, returning true if
+ // any were added.
+ bool add(symbol *src, symbol *dest,
+ tenv& source, varEntry *qualifier, coder &c);
+};
+
+#ifdef NOHASH //{{{
+class venv : public sym::table<varEntry*> {
+public:
+ venv() {}
+
+ // This is an optimization in the hashtable version that is duplicated here
+ // for compatibility. It is identical to venv().
+ struct file_env_tag {};
+ venv(file_env_tag) {}
+
+#if 0
+ // Look for a function that exactly matches the signature given.
+ varEntry *lookExact(symbol *name, signature *key);
+#endif
+
+ // Add the entries in one environment to another, if qualifier is
+ // non-null, it is a record and the source environment are its fields.
+ // The coder is necessary to check which variables are accessible and
+ // should be added.
+ void add(venv& source, varEntry *qualifier, coder &c);
+
+ // Add all unshadowed variables from source of the name src as variables
+ // named dest. Returns true if at least one was added.
+ bool add(symbol *src, symbol *dest,
+ venv& source, varEntry *qualifier, coder &c);
+
+ // Look for a function that exactly matches the type given.
+ varEntry *lookByType(symbol *name, ty *t);
+
+ // Checks if a function was added in the top scope as two identical
+ // functions cannot be defined in one scope.
+ varEntry *lookInTopScope(symbol *name, ty *t);
+
+ // Return the type of the variable, if name is overloaded, return an
+ // overloaded type.
+ ty *getType(symbol *name);
+
+ friend std::ostream& operator<< (std::ostream& out, const venv& ve);
+
+ // Prints a list of the variables to the standard output.
+ void list(record *module=0);
+};
+
+//}}}
+#else //{{{
+
+// venv implemented with a hash table.
+class venv {
+ struct key : public gc {
+ symbol *name;
+ ty *t;
+
+ key(symbol *name, ty *t)
+ : name(name), t(t) {}
+
+ key(symbol *name, varEntry *v)
+ : name(name), t(v->getType()) {}
+ };
+ friend ostream& operator<< (ostream& out, const venv::key &k);
+
+ struct value : public gc {
+ varEntry *v;
+ bool shadowed;
+ value *next; // The entry (of the same key) that this one shadows.
+
+ value(varEntry *v)
+ : v(v), shadowed(false), next(0) {}
+ };
+ struct namehash {
+ size_t operator()(const symbol *name) const {
+ return (size_t)name;
+ }
+ };
+ struct nameeq {
+ bool operator()(const symbol *s, const symbol *t) const {
+ return s==t;
+ }
+ };
+ struct keyhash {
+ size_t hashSig(ty *t) const {
+ signature *sig=t->getSignature();
+ return sig ? sig->hash() : 0;
+ }
+ size_t operator()(const key k) const {
+ return (size_t)(k.name) * 107 +
+ (k.name->special ? k.t->hash() : hashSig(k.t));
+ }
+ };
+ struct keyeq {
+#define TEST_COLLISION 0
+#if TEST_COLLISION
+ bool base(const key k, const key l) const {
+ return k.name==l.name &&
+ (k.name->special ? equivalent(k.t, l.t) :
+ equivalent(k.t->getSignature(),
+ l.t->getSignature()));
+ }
+ bool operator()(const key k, const key l) const;
+#else
+ bool operator()(const key k, const key l) const;
+#endif
+ };
+
+
+ // A hash table used to quickly look up a variable once its name and type are
+ // known. Includes all scopes.
+ typedef mem::unordered_map<key, value *, keyhash, keyeq> keymap;
+ keymap all;
+
+ // Similar hashes, one for each scope level.
+ typedef mem::unordered_multimap<key, value *, keyhash, keyeq> keymultimap;
+ typedef mem::stack<keymultimap> mapstack;
+ mapstack scopes;
+
+ // A hash table indexed solely on the name, storing for each name the list of
+ // all values of that name. Used to get the (possibly overloaded) type
+ // of the name.
+ typedef mem::list<value *> values;
+ typedef mem::unordered_map<symbol *, values, namehash, nameeq> namemap;
+ namemap names;
+
+ void listValues(symbol *name, values &vals, record *module);
+
+ // Helper function for endScope.
+ void remove(key k);
+
+ // These are roughly the size the hashtables will be after loading the
+ // builtin functions and plain module.
+ static const size_t fileAllSize=2000;
+ static const size_t namesAllSize=1000;
+public:
+ venv() {
+ beginScope();
+ }
+
+ // Most file level modules automatically import plain, so allocate hashtables
+ // big enough to hold it in advance.
+ struct file_env_tag {};
+ venv(file_env_tag)
+ : all(fileAllSize), names(namesAllSize)
+ {
+ beginScope();
+ }
+
+ void enter(symbol *name, varEntry *v);
+
+ // Add the entries in one environment to another, if qualifier is
+ // non-null, it is a record and entries of the source environment are its
+ // fields. The coder is necessary to check which variables are accessible and
+ // should be added.
+ void add(venv& source, varEntry *qualifier, coder &c);
+
+ // Add all unshadowed variables from source of the name src as variables
+ // named dest. Returns true if at least one was added.
+ bool add(symbol *src, symbol *dest,
+ venv& source, varEntry *qualifier, coder &c);
+
+ bool lookInTopScope(key k) {
+ return scopes.top().find(k)!=scopes.top().end();
+ }
+
+ // Look for a function that exactly matches the type given.
+ bool lookInTopScope(symbol *name, ty *t) {
+ return lookInTopScope(key(name, t));
+ }
+
+ varEntry *lookByType(key k) {
+ keymap::const_iterator p=all.find(k);
+ return p!=all.end() ? p->second->v : 0;
+ }
+
+ // Look for a function that exactly matches the type given.
+ varEntry *lookByType(symbol *name, ty *t) {
+ return lookByType(key(name, t));
+ }
+
+ ty *getType(symbol *name);
+
+ void beginScope() {
+ scopes.push(keymultimap());
+ }
+ void endScope() {
+ keymultimap &scope=scopes.top();
+ for (keymultimap::iterator p=scope.begin(); p!=scope.end(); ++p) {
+ remove(p->first);
+ }
+ scopes.pop();
+ }
+
+ // Adds the definitions of the top-level scope to the level underneath,
+ // and then removes the top scope.
+ void collapseScope() {
+ // NOTE: May be expensively copying a large hash table.
+ keymultimap top=scopes.top();
+ scopes.pop();
+
+ keymultimap& underneath=scopes.top();
+ underneath.insert(top.begin(), top.end());
+ }
+
+ // Prints a list of the variables to the standard output.
+ void list(record *module=0);
+
+ // Adds to l, all names prefixed by start.
+ void completions(mem::list<symbol *>& l, string start);
+};
+#endif
+
+} // namespace trans
+
+#endif //ENTRY_H
diff --git a/Build/source/utils/asymptote/env.cc b/Build/source/utils/asymptote/env.cc
new file mode 100644
index 00000000000..465b07a8caf
--- /dev/null
+++ b/Build/source/utils/asymptote/env.cc
@@ -0,0 +1,158 @@
+/*****
+ * env.h
+ * Andy Hammerlindl 2002/6/20
+ *
+ * Keeps track of the namespaces of variables and types when traversing
+ * the abstract syntax.
+ *****/
+
+#include "env.h"
+#include "record.h"
+#include "genv.h"
+#include "builtin.h"
+
+using namespace types;
+
+namespace absyntax {
+void clearCachedCalls();
+}
+
+namespace trans {
+
+// Instances of this class are passed to types::ty objects so that they can call
+// back to env when checking casting of subtypes.
+class envCaster : public caster {
+ protoenv &e;
+ symbol *name;
+public:
+ envCaster(protoenv &e, symbol *name)
+ : e(e), name(name) {}
+
+ access *operator() (ty *target, ty *source) {
+ return e.lookupCast(target, source, name);
+ }
+
+ bool castable(ty *target, ty *source) {
+ return e.castable(target, source, name);
+ }
+};
+
+access *protoenv::baseLookupCast(ty *target, ty *source, symbol *name) {
+ static identAccess id;
+
+ assert(target->kind != ty_overloaded &&
+ source->kind != ty_overloaded);
+
+ // If errors already exist, don't report more. This may, however, cause
+ // problems with resoving the signature of an overloaded function. The
+ // abstract syntax should check if any of the parameters had an error before
+ // finding the signature.
+ if (target->kind == ty_error || source->kind == ty_error)
+ return &id;
+ else if (equivalent(target,source))
+ return &id;
+ else {
+ varEntry *v=lookupVarByType(name,new function(target,source));
+ return v ? v->getLocation() : 0;
+ }
+}
+
+access *protoenv::lookupCast(ty *target, ty *source, symbol *name) {
+ access *a=baseLookupCast(target, source, name);
+ if (a)
+ return a;
+
+ envCaster ec(*this, name);
+ return source->castTo(target, ec);
+}
+
+bool protoenv::castable(ty *target, ty *source, symbol *name) {
+ struct castTester : public tester {
+ protoenv &e;
+ symbol *name;
+
+ castTester(protoenv &e, symbol *name)
+ : e(e), name(name) {}
+
+ bool base(ty *t, ty *s) {
+ access *a=e.baseLookupCast(t, s, name);
+ if (a)
+ return true;
+
+ envCaster ec(e, name);
+ return s->castable(t, ec);
+ }
+ };
+
+ castTester ct(*this, name);
+ return ct.test(target,source);
+}
+
+ty *protoenv::castTarget(ty *target, ty *source, symbol *name) {
+ struct resolver : public collector {
+ protoenv &e;
+ symbol *name;
+
+ resolver(protoenv &e, symbol *name)
+ : e(e), name(name) {}
+
+ types::ty *base(types::ty *target, types::ty *source) {
+ return e.castable(target, source, name) ? target : 0;
+ }
+ };
+
+ resolver r(*this, name);
+ return r.collect(target, source);
+}
+
+ty *protoenv::castSource(ty *target, ty *source, symbol *name) {
+ struct resolver : public collector {
+ protoenv &e;
+ symbol *name;
+
+ resolver(protoenv &e, symbol *name)
+ : e(e), name(name) {}
+
+ types::ty *base(types::ty *target, types::ty *source) {
+ return e.castable(target, source, name) ? source : 0;
+ }
+ };
+
+ resolver r(*this, name);
+ return r.collect(target, source);
+}
+
+void protoenv::addArrayOps(array *a)
+{
+ trans::addArrayOps(ve, a);
+}
+
+void protoenv::addRecordOps(record *r)
+{
+ trans::addRecordOps(ve, r);
+}
+
+void protoenv::addFunctionOps(function *f)
+{
+ trans::addFunctionOps(ve, f);
+}
+
+env::env(genv &ge)
+ : protoenv(venv::file_env_tag()), ge(ge)
+{
+ // NOTE: May want to make this initial environment into a "builtin" module,
+ // and then import the builtin module.
+ base_tenv(te);
+ base_venv(ve);
+}
+
+env::~env()
+{
+}
+
+record *env::getModule(symbol *id, string filename)
+{
+ return ge.getModule(id, filename);
+}
+
+}
diff --git a/Build/source/utils/asymptote/env.h b/Build/source/utils/asymptote/env.h
new file mode 100644
index 00000000000..221ff98df81
--- /dev/null
+++ b/Build/source/utils/asymptote/env.h
@@ -0,0 +1,175 @@
+/*****
+ * env.h
+ * Andy Hammerlindl 2002/6/20
+ *
+ * Keeps track of the namespaces of variables and types when traversing
+ * the abstract syntax.
+ *****/
+
+#ifndef ENV_H
+#define ENV_H
+
+#include "errormsg.h"
+#include "entry.h"
+#include "types.h"
+#include "util.h"
+
+namespace types {
+class record;
+}
+
+namespace trans {
+
+using sym::symbol;
+using types::ty;
+using types::function;
+using types::record;
+
+class genv;
+
+// Keeps track of the name bindings of variables and types. This is used for
+// the fields of a record, whereas the derived class env is used for unqualified
+// names in translation.
+class protoenv {
+//protected:
+public:
+ // These tables keep track of type and variable definitions.
+ tenv te;
+ venv ve;
+
+ access *baseLookupCast(ty *target, ty *source, symbol *name);
+
+public:
+ // Start an environment for a file-level module.
+ protoenv() {}
+
+ protoenv(venv::file_env_tag tag)
+ : ve(tag) {}
+
+ protoenv(const protoenv&);
+
+ void beginScope()
+ {
+ te.beginScope(); ve.beginScope();
+ }
+ void endScope()
+ {
+ te.endScope(); ve.endScope();
+ }
+ void collapseScope()
+ {
+ te.collapseScope(); ve.collapseScope();
+ }
+
+ tyEntry *lookupTyEntry(symbol *s)
+ {
+ return te.look(s);
+ }
+
+ ty *lookupType(symbol *s)
+ {
+ tyEntry *ent=lookupTyEntry(s);
+ return ent ? ent->t : 0;
+ }
+
+ varEntry *lookupVarByType(symbol *name, ty *t)
+ {
+ // Search in local vars.
+ return ve.lookByType(name, t);
+ }
+
+ access *lookupInitializer(ty *t)
+ {
+ // The initializer's type is a function returning the desired type.
+ function *it=new function(t);
+ varEntry *v=lookupVarByType(symbol::initsym,it);
+
+ // If not in the environment, try the type itself.
+ return v ? v->getLocation() : t->initializer();
+ }
+
+ // Find the function that handles casting between the types.
+ // The name is "operator cast" for implicitCasting and "operator ecast" for
+ // explicit.
+ access *lookupCast(ty *target, ty *source, symbol *name);
+ bool castable(ty *target, ty *source, symbol *name);
+
+ // Given overloaded types, this resolves which types should be the target and
+ // the source of the cast.
+ ty *castTarget(ty *target, ty *source, symbol *name);
+ ty *castSource(ty *target, ty *source, symbol *name);
+
+ ty *varGetType(symbol *name)
+ {
+ return ve.getType(name);
+ }
+
+ void addType(symbol *name, tyEntry *desc)
+ {
+ te.enter(name, desc);
+ }
+
+ void addVar(symbol *name, varEntry *desc)
+ {
+ // Don't check for multiple variables, as this makes adding casts
+ // and initializers harder.
+ ve.enter(name, desc);
+ }
+
+ // Add another environment, say from a record.
+ void add(protoenv &source, varEntry *qualifier, coder &c)
+ {
+ te.add(source.te, qualifier, c);
+ ve.add(source.ve, qualifier, c);
+ }
+
+ // Add variables and types of name src from another environment under the
+ // name dest in this environment.
+ bool add(symbol *src, symbol *dest,
+ protoenv &source, varEntry *qualifier, coder &c)
+ {
+ return te.add(src, dest, source.te, qualifier, c) |
+ ve.add(src, dest, source.ve, qualifier, c);
+ }
+
+ // Add the standard functions for a new type.
+ void addArrayOps(types::array *t);
+ void addRecordOps(types::record *r);
+ void addFunctionOps(types::function *f);
+
+ void list(record *r=0)
+ {
+ ve.list(r);
+ }
+
+ // Adds to a list the keywords in the environment that start with the given
+ // prefix. Used for automatic completion at the interactive prompt.
+ typedef mem::list<symbol *> symbol_list;
+ void completions(symbol_list &l, string start)
+ {
+ te.completions(l, start);
+ ve.completions(l, start);
+ }
+
+private: // Non-copyable
+ void operator=(const protoenv&);
+};
+
+// Environment used in translating statements and expressions at all scopes. As
+// opposed to protoenv which is suitable for keeping track of the fields of
+// records, this also keeps track of the global env, for loading modules.
+class env : public protoenv {
+ // The global environment - keeps track of modules.
+ genv &ge;
+public:
+ // Start an environment for a file-level module.
+ env(genv &ge);
+
+ ~env();
+
+ record *getModule(symbol *id, string filename);
+};
+
+} // namespace trans
+
+#endif
diff --git a/Build/source/utils/asymptote/envcompleter.cc b/Build/source/utils/asymptote/envcompleter.cc
new file mode 100644
index 00000000000..6c8135f0edd
--- /dev/null
+++ b/Build/source/utils/asymptote/envcompleter.cc
@@ -0,0 +1,58 @@
+/*****
+ * envcompleter.cc
+ * Andy Hammerlindl 2006/07/31
+ *
+ * Implements a text completion function for readline based on symbols in the
+ * environment.
+ *****/
+
+#include <fstream>
+
+#include "table.h"
+#include "envcompleter.h"
+
+namespace trans {
+
+bool basicListLoaded=false;
+envCompleter::symbol_list basicList;
+
+static void loadBasicList() {
+ assert(basicListLoaded==false);
+
+#define ADD(word) basicList.push_back(symbol::literalTrans(#word))
+#include "keywords.cc"
+#undef ADD
+
+ basicListLoaded=true;
+}
+
+void envCompleter::basicCompletions(symbol_list &l, string start) {
+ if (!basicListLoaded)
+ loadBasicList();
+
+ for(symbol_list::iterator p = basicList.begin(); p != basicList.end(); ++p)
+ if (prefix(start, **p))
+ l.push_back(*p);
+}
+
+void envCompleter::makeList(const char *text) {
+ l.clear();
+ basicCompletions(l, text);
+ e.completions(l, text);
+ index=l.begin();
+}
+
+char *envCompleter::operator () (const char *text, int state) {
+ if (state==0)
+ makeList(text);
+
+ if (index==l.end())
+ return 0;
+ else {
+ symbol *name=*index;
+ ++index;
+ return StrdupMalloc((string) *name);
+ }
+}
+
+} // namespace trans
diff --git a/Build/source/utils/asymptote/envcompleter.h b/Build/source/utils/asymptote/envcompleter.h
new file mode 100644
index 00000000000..8af7f5bff38
--- /dev/null
+++ b/Build/source/utils/asymptote/envcompleter.h
@@ -0,0 +1,41 @@
+/*****
+ * envcompleter.h
+ * Andy Hammerlindl 2006/07/31
+ *
+ * Implements a text completion function for readline based on symbols in the
+ * environment.
+ *****/
+
+#ifndef ENVCOMPLETER_H
+#define ENVCOMPLETER_H
+
+#include "env.h"
+#include "interact.h"
+
+namespace trans {
+
+class envCompleter : public interact::completer {
+public:
+ typedef protoenv::symbol_list symbol_list;
+
+private:
+ protoenv &e;
+ symbol_list l;
+ symbol_list::iterator index;
+
+ // These are completions that don't come from the environment, such as
+ // keywords. They are read from the keywords file.
+ static void basicCompletions(symbol_list &l, string start);
+
+ void makeList(const char *text);
+
+public:
+ envCompleter(protoenv &e)
+ : e(e), l(), index(l.end()) {}
+
+ char *operator () (const char *text, int state);
+};
+
+} // namespace trans
+
+#endif // ENVCOMPLETER_H
diff --git a/Build/source/utils/asymptote/errormsg.cc b/Build/source/utils/asymptote/errormsg.cc
new file mode 100644
index 00000000000..3b7b3e9020d
--- /dev/null
+++ b/Build/source/utils/asymptote/errormsg.cc
@@ -0,0 +1,104 @@
+/*****
+ * errormsg.cc
+ * Andy Hammerlindl 2002/06/17
+ *
+ * Used in all phases of the compiler to give error messages.
+ *****/
+
+#include <cstdio>
+#include <cstdlib>
+#include <cstdarg>
+
+#include "errormsg.h"
+
+
+position nullPos;
+static nullPosInitializer nullPosInit;
+
+bool errorstream::interrupt=false;
+
+ostream& operator<< (ostream& out, const position& pos)
+{
+ if (!pos)
+ return out;
+
+ out << pos.file->name() << ": ";
+ out << pos.line << "." << pos.column << ": ";
+ return out;
+}
+
+void errorstream::clear()
+{
+ sync();
+ anyErrors = anyWarnings = false;
+}
+
+void errorstream::message(position pos, const string& s)
+{
+ if (floating) out << endl;
+ out << pos << s;
+ floating = true;
+}
+
+void errorstream::compiler(position pos)
+{
+ message(pos,"compiler: ");
+ anyErrors = true;
+}
+
+void errorstream::compiler()
+{
+ message(nullPos,"compiler: ");
+ anyErrors = true;
+}
+
+void errorstream::runtime(position pos)
+{
+ message(pos,"runtime: ");
+ anyErrors = true;
+}
+
+void errorstream::error(position pos)
+{
+ message(pos,"");
+ anyErrors = true;
+}
+
+void errorstream::warning(position pos)
+{
+ message(pos,"warning: ");
+ anyWarnings = true;
+}
+
+void errorstream::fatal(position pos)
+{
+ message(pos,"abort: ");
+ anyErrors = true;
+}
+
+void errorstream::trace(position pos)
+{
+ static position lastpos;
+ if(!pos || (pos.match(lastpos.filename()) && pos.match(lastpos.Line())))
+ return;
+ lastpos=pos;
+ message(pos,"");
+ sync();
+}
+
+void errorstream::cont()
+{
+ floating = false;
+}
+
+void errorstream::sync()
+{
+ if (floating) out << endl;
+ floating = false;
+}
+
+void outOfMemory()
+{
+ cerr << "error: out of memory" << endl;
+ exit(1);
+}
diff --git a/Build/source/utils/asymptote/errormsg.h b/Build/source/utils/asymptote/errormsg.h
new file mode 100644
index 00000000000..2b152445881
--- /dev/null
+++ b/Build/source/utils/asymptote/errormsg.h
@@ -0,0 +1,204 @@
+/*****
+ * errormsg.h
+ * Andy Hammerlindl 2002/06/17
+ *
+ * Used in all phases of the compiler to give error messages.
+ *****/
+
+#ifndef ERRORMSG_H
+#define ERRORMSG_H
+
+#include <iostream>
+#include "common.h"
+#include "settings.h"
+
+using std::ostream;
+
+struct handled_error {}; // Exception to process next file.
+struct interrupted {}; // Exception to interrupt execution.
+struct quit {}; // Exception to quit current operation.
+struct eof {}; // Exception to exit interactive mode.
+
+class fileinfo : public gc {
+ string filename;
+ size_t lineNum;
+
+public:
+ fileinfo(string filename, size_t lineNum=1)
+ : filename(filename), lineNum(lineNum) {}
+
+ size_t line() const
+ {
+ return lineNum;
+ }
+
+ string name() const {
+ return filename;
+ }
+
+ // Specifies a newline symbol at the character position given.
+ void newline() {
+ ++lineNum;
+ }
+
+};
+
+inline bool operator == (const fileinfo& a, const fileinfo& b)
+{
+ return a.line() == b.line() && a.name() == b.name();
+}
+
+
+
+class position : public gc {
+ fileinfo *file;
+ size_t line;
+ size_t column;
+
+public:
+ void init(fileinfo *f, Int p) {
+ file = f;
+ if (file) {
+ line = file->line();
+ column = p;
+ } else {
+ line = column = 0;
+ }
+ }
+
+ string filename() const
+ {
+ return file ? file->name() : "";
+ }
+
+ size_t Line() const
+ {
+ return line;
+ }
+
+ size_t Column() const
+ {
+ return column;
+ }
+
+ bool match(const string& s) {
+ return file && file->name() == s;
+ }
+
+ bool match(size_t l) {
+ return line == l;
+ }
+
+ bool matchColumn(size_t c) {
+ return column == c;
+ }
+
+ bool operator! () const
+ {
+ return (file == 0);
+ }
+
+ friend ostream& operator << (ostream& out, const position& pos);
+
+};
+
+extern position nullPos;
+
+struct nullPosInitializer {
+ nullPosInitializer() {nullPos.init(NULL,0);}
+};
+
+inline bool operator == (const position& a, const position& b)
+{
+ return a.Line() == b.Line() && a.Column() == b.Column() &&
+ a.filename() == b.filename();
+}
+
+class errorstream {
+ ostream& out;
+ bool anyErrors;
+ bool anyWarnings;
+ bool floating; // Was a message output without a terminating newline?
+
+ // Is there an error that warrants the asy process to return 1 instead of 0?
+ bool anyStatusErrors;
+
+public:
+ static bool interrupt; // Is there a pending interrupt?
+
+ errorstream(ostream& out = cerr)
+ : out(out), anyErrors(false), anyWarnings(false), floating(false),
+ anyStatusErrors(false) {}
+
+
+ void clear();
+
+ void message(position pos, const string& s);
+
+ void Interrupt(bool b) {
+ interrupt=b;
+ }
+
+ // An error is encountered, not in the user's code, but in the way the
+ // compiler works! This may be augmented in the future with a message
+ // to contact the compiler writers.
+ void compiler();
+ void compiler(position pos);
+
+ // An error encountered when running compiled code. This method does
+ // not stop the executable, but the executable should be stopped
+ // shortly after calling this method.
+ void runtime(position pos);
+
+ // Errors encountered when compiling making it impossible to run the code.
+ void error(position pos);
+
+ // Indicate potential problems in the code, but the code is still usable.
+ void warning(position pos);
+
+ // Single a fatal error and execute the main process.
+ void fatal(position pos);
+
+ // Print out position in code to aid debugging.
+ void trace(position pos);
+
+ // Sends stuff to out to print.
+ // NOTE: May later make it do automatic line breaking for long messages.
+ template<class T>
+ errorstream& operator << (const T& x) {
+ flush(out);
+ out << x;
+ return *this;
+ }
+
+ // Reporting errors to the stream may be incomplete. This draws the
+ // appropriate newlines or file excerpts that may be needed at the end.
+ void sync();
+
+ void cont();
+
+ bool errors() const {
+ return anyErrors;
+ }
+
+ bool warnings() const {
+ return anyWarnings || errors();
+ }
+
+ void statusError() {
+ anyStatusErrors=true;
+ }
+
+ // Returns true if no errors have occured that should be reported by the
+ // return value of the process.
+ bool processStatus() const {
+ return !anyStatusErrors;
+ }
+};
+
+extern errorstream em;
+void outOfMemory();
+
+GC_DECLARE_PTRFREE(nullPosInitializer);
+
+#endif
diff --git a/Build/source/utils/asymptote/errors b/Build/source/utils/asymptote/errors
new file mode 100644
index 00000000000..fad3454ce1e
--- /dev/null
+++ b/Build/source/utils/asymptote/errors
@@ -0,0 +1,92 @@
+errortest.asy: 12.4: no matching variable 'x.y'
+errortest.asy: 16.11: no matching variable of name 'z'
+errortest.asy: 20.3: no matching variable 'x'
+errortest.asy: 27.3: no type of name 'x'
+errortest.asy: 28.3: no type of name 'x'
+errortest.asy: 29.3: no type of name 'x'
+errortest.asy: 30.10: no type of name 'x'
+errortest.asy: 32.5: no type of name 'x'
+errortest.asy: 33.5: no type of name 'x'
+errortest.asy: 34.5: no type of name 'x'
+errortest.asy: 35.12: no type of name 'x'
+errortest.asy: 41.4: no matching variable 'x.y'
+errortest.asy: 48.6: no matching variable 'm.u.v'
+errortest.asy: 55.12: no matching field of name 'z' in 'm'
+errortest.asy: 62.4: no matching variable 'm.z'
+errortest.asy: 75.4: no matching field or type of name 'u' in 'm'
+errortest.asy: 77.5: no matching field or type of name 'u' in 'm'
+errortest.asy: 84.3: expression cannot be used as an address
+errortest.asy: 89.3: use of variable 'f' is ambiguous
+errortest.asy: 91.4: use of variable 'm.f' is ambiguous
+errortest.asy: 97.11: array initializer used for non-array
+errortest.asy: 98.12: array initializer used for non-array
+errortest.asy: 103.4: no matching variable 'f.m'
+errortest.asy: 108.4: no matching variable 'x.m'
+errortest.asy: 116.12: no matching field of name 'z' in 'point'
+errortest.asy: 124.4: no matching variable 'p.z'
+errortest.asy: 132.4: use of variable 'p.f' is ambiguous
+errortest.asy: 140.4: no matching variable 'p.z'
+errortest.asy: 151.4: no matching function 'f()'
+errortest.asy: 152.4: no matching function 'f(string)'
+errortest.asy: 160.4: cannot call 'void f(int)' without parameters
+errortest.asy: 168.7: no matching function 'operator +(point)'
+errortest.asy: 173.10: types in conditional expression do not match
+errortest.asy: 178.10: type of conditional expression is ambiguous
+errortest.asy: 183.5: cannot convert 'int()' to 'int' in assignment
+errortest.asy: 188.5: assignment is ambiguous
+errortest.asy: 194.24: function must return a value
+errortest.asy: 200.11: type 'int' is not a structure
+errortest.asy: 209.3: allocation of struct 'b' is not in a valid scope
+errortest.asy: 219.3: break statement outside of a loop
+errortest.asy: 223.3: continue statement outside of a loop
+errortest.asy: 228.5: function cannot return a value
+errortest.asy: 234.5: function must return a value
+errortest.asy: 241.11: function must return a value
+errortest.asy: 244.11: function must return a value
+errortest.asy: 290.3: built-in functions cannot be modified
+errortest.asy: 298.18: cannot cast 'string' to 'int'
+errortest.asy: 312.4: accessing private field outside of structure
+errortest.asy: 313.4: accessing private field outside of structure
+errortest.asy: 314.4: accessing private field outside of structure
+errortest.asy: 314.4: accessing private field outside of structure
+errortest.asy: 315.4: modifying non-public field outside of structure
+errortest.asy: 316.4: modifying non-public field outside of structure
+errortest.asy: 318.4: accessing private field outside of structure
+errortest.asy: 319.4: accessing private field outside of structure
+errortest.asy: 320.4: accessing private field outside of structure
+errortest.asy: 321.4: modifying non-public field outside of structure
+errortest.asy: 330.18: no matching types or fields of name 'x'
+errortest.asy: 331.18: no matching types or fields of name 'f'
+errortest.asy: 341.3: modifying non-public field outside of structure
+errortest.asy: 342.3: modifying non-public field outside of structure
+errortest.asy: 344.3: modifying non-public field outside of structure
+errortest.asy: 350.4: accessing private field outside of structure
+errortest.asy: 351.4: accessing private field outside of structure
+errortest.asy: 353.4: accessing private field outside of structure
+errortest.asy: 354.4: accessing private field outside of structure
+errortest.asy: 360.18: no matching types or fields of name 'T'
+errortest.asy: 367.4: accessing private field outside of structure
+errortest.asy: 368.4: accessing private field outside of structure
+errortest.asy: 370.4: accessing private field outside of structure
+errortest.asy: 371.4: accessing private field outside of structure
+errortest.asy: 378.18: no matching types or fields of name 'T'
+errortest.asy: 386.11: modifying non-public field outside of structure
+errortest.asy: 387.11: modifying non-public field outside of structure
+errortest.asy: 388.11: modifying non-public field outside of structure
+errortest.asy: 389.11: modifying non-public field outside of structure
+errortest.asy: 393.3: modifying non-public field outside of structure
+errortest.asy: 394.3: modifying non-public field outside of structure
+errortest.asy: 395.3: modifying non-public field outside of structure
+errortest.asy: 396.3: modifying non-public field outside of structure
+errortest.asy: 400.3: modifying non-public field outside of structure
+errortest.asy: 401.3: modifying non-public field outside of structure
+errortest.asy: 402.3: modifying non-public field outside of structure
+errortest.asy: 403.3: modifying non-public field outside of structure
+errortest.asy: 407.11: modifying non-public field outside of structure
+errortest.asy: 408.11: modifying non-public field outside of structure
+errortest.asy: 409.11: modifying non-public field outside of structure
+errortest.asy: 410.11: modifying non-public field outside of structure
+errortest.asy: 411.3: modifying non-public field outside of structure
+errortest.asy: 412.3: modifying non-public field outside of structure
+errortest.asy: 413.3: modifying non-public field outside of structure
+errortest.asy: 414.3: modifying non-public field outside of structure
diff --git a/Build/source/utils/asymptote/errortest.asy b/Build/source/utils/asymptote/errortest.asy
new file mode 100644
index 00000000000..500a3972e1f
--- /dev/null
+++ b/Build/source/utils/asymptote/errortest.asy
@@ -0,0 +1,415 @@
+/*****
+ * errortest.asy
+ * Andy Hammerlindl 2003/08/08
+ *
+ * This struct attempts to trigger every error message reportable by the
+ * compiler to ensure that errors are being reported properly.
+ *****/
+
+// name.cc
+{
+ // line 33
+ x.y = 5;
+}
+{
+ // line 50
+ int x = z;
+}
+{
+ // line 67
+ x = 5;
+}
+{
+ // line 84 - unreachable
+}
+{
+ // line 95
+ x y1;
+ x y2();
+ x y3(int);
+ int y4(x);
+ struct m {
+ x y1;
+ x y2();
+ x y3(int);
+ int y4(x);
+ }
+}
+{
+ // line 130
+ int x;
+ x.y = 4;
+}
+{
+ // line 156
+ struct m {
+ int x,y;
+ }
+ m.u.v = 5;
+}
+{
+ // line 186
+ struct m {
+ int x,y;
+ }
+ int x = m.z;
+}
+{
+ // line 217
+ struct m {
+ int x,y;
+ }
+ m.z = 5;
+}
+{
+ // line 249 - unreachable
+}
+{
+ // line 272 - not testable without typedef
+}
+{
+ // line 283
+ struct m {
+ int x,y;
+ }
+ m.u v;
+ struct mm {
+ m.u v;
+ }
+}
+
+// exp.h
+{
+ // line 109
+ 5 = 4;
+}
+{
+ // line 136
+ int f, f();
+ f;
+ struct m { int f, f(); }
+ m.f;
+}
+
+// exp.cc
+{
+ // line 40
+ int x = {};
+ int y = {4, 5, 6};
+}
+{
+ // line 110
+ int f(), f(int);
+ f.m = 5;
+}
+{
+ // line 122
+ int x;
+ x.m = 5;
+}
+{
+ // line 147
+ struct point {
+ int x,y;
+ }
+ point p;
+ int x = p.z;
+}
+{
+ // line 157
+ struct point {
+ int x, y;
+ }
+ point p;
+ p.z;
+}
+{
+ // line 163
+ struct point {
+ int f(), f(int);
+ }
+ point p;
+ p.f;
+}
+{
+ // line 204
+ struct point {
+ int x, y;
+ }
+ point p;
+ p.z = 5;
+}
+{
+ // line 229 - unreachable
+}
+{
+ // lines 261 and 275 - wait for subscript to be fully implemented.
+}
+{
+ // line 515
+ void f(int), f(int, int);
+ f();
+ f("Hello?");
+}
+{
+ // line 520 - not yet testable (need int->float casting or the like)
+}
+{
+ // line 525
+ void f(int);
+ f();
+}
+{
+ // line 649
+ struct point {
+ int x,y;
+ }
+ point p;
+ p = +p;
+}
+{
+ // line 1359
+ int x, f();
+ (true) ? x : f;
+}
+{
+ // line 1359
+ int a, a(), b, b();
+ (true) ? a : b;
+}
+{
+ // line 1581
+ int x, f();
+ x = f;
+}
+{
+ // line 1586
+ int a, a(), b, b();
+ a = b;
+}
+
+// newexp.cc
+{
+ // line 34
+ int f() = new int () {
+ int x = 5;
+ };
+}
+{
+ // line 64
+ int x = new int;
+}
+{
+ // line 72
+ struct a {
+ struct b {
+ }
+ }
+
+ new a.b;
+}
+
+// stm.cc
+{
+ // line 86
+ 5;
+}
+{
+ // line 246
+ break;
+}
+{
+ // line 261
+ continue;
+}
+{
+ // line 282
+ void f() {
+ return 17;
+ }
+}
+{
+ // line 288
+ int f() {
+ return;
+ }
+}
+
+// dec.cc
+{
+ // line 378
+ int f() {
+ int x = 5;
+ }
+ int g() {
+ if (true)
+ return 7;
+ }
+}
+
+// env.h
+{
+ // line 99
+ struct m {}
+ struct m {}
+}
+{
+ // line 109
+ int f() {
+ return 1;
+ }
+ int f() {
+ return 2;
+ }
+
+ int x = 1;
+ int x = 2;
+
+ struct m {
+ int f() {
+ return 1;
+ }
+ int f() {
+ return 2;
+ }
+
+ int x = 1;
+ int x = 2;
+ }
+}
+
+// env.cc
+{
+ // line 107 - currently unreachable as no built-ins are currently used
+ // in records.
+}
+{
+ // line 140
+ // Assuming there is a built-in function void abort(string):
+ void f(string);
+ abort = f;
+}
+{
+ // line 168 - currently unreachable as no built-in functions are
+ // currently used in records.
+}
+{
+ // line 222
+ int x = "Hello";
+}
+
+// Test permissions.
+{
+ struct A {
+ private int x=4;
+ restricted int y=5;
+
+ private void f() {}
+ restricted void g() {}
+ }
+
+ A a;
+ a.x;
+ a.x = 4;
+ a.x += 5;
+ a.y = 6;
+ a.y += 7;
+
+ a.f;
+ a.f();
+ a.f = new void() {};
+ a.g = new void() {};
+}
+{
+ struct A {
+ private int x=4;
+ private void f() {}
+ }
+
+ A a;
+ from a unravel x;
+ from a unravel f;
+}
+{
+ struct A {
+ restricted int y=5;
+ restricted void g() {}
+ }
+
+ A a;
+ from a unravel y,g;
+ y = 6;
+ y += 7;
+
+ g = new void() {};
+}
+{
+ struct A {
+ private typedef int T;
+ }
+ A.T x;
+ A.T x=4;
+ int y=2;
+ A.T x=y;
+ A.T x=17+3*y;
+}
+{
+ struct A {
+ private typedef int T;
+ }
+ from A unravel T;
+}
+{
+ struct A {
+ private typedef int T;
+ }
+ A a;
+ a.T x;
+ a.T x=4;
+ int y=2;
+ a.T x=y;
+ a.T x=17+3*y;
+}
+{
+ struct A {
+ private typedef int T;
+ }
+ A a;
+ from a unravel T;
+}
+
+// Read-only settings
+// Ensure that the safe and globalwrite options can't be modified inside the
+// code.
+{
+ access settings;
+ settings.safe=false;
+ settings.safe=true;
+ settings.globalwrite=false;
+ settings.globalwrite=true;
+}
+{
+ from settings access safe, globalwrite;
+ safe=false;
+ safe=true;
+ globalwrite=false;
+ globalwrite=true;
+}
+{
+ from settings access safe as x, globalwrite as y;
+ x=false;
+ x=true;
+ y=false;
+ y=true;
+}
+{
+ import settings;
+ settings.safe=false;
+ settings.safe=true;
+ settings.globalwrite=false;
+ settings.globalwrite=true;
+ safe=false;
+ safe=true;
+ globalwrite=false;
+ globalwrite=true;
+}
diff --git a/Build/source/utils/asymptote/examples/.cvsignore b/Build/source/utils/asymptote/examples/.cvsignore
new file mode 100644
index 00000000000..359703608e5
--- /dev/null
+++ b/Build/source/utils/asymptote/examples/.cvsignore
@@ -0,0 +1,2 @@
+*.eps
+*.gif
diff --git a/Build/source/utils/asymptote/examples/100d.views b/Build/source/utils/asymptote/examples/100d.views
new file mode 100644
index 00000000000..b3a1be12936
--- /dev/null
+++ b/Build/source/utils/asymptote/examples/100d.views
@@ -0,0 +1,3 @@
+{0 0 -14.425469398498535}{0 0 1}{14.425469398498535}{}{27.905145957890003}
+{0.3336401879787445 -0.0024074832908809185 -14.015975952148438}{-0.7636404037475586 -0.17614173889160156 0.6211501359939575}{15.868016873340485}{-58.88738872302071}{27.905145957890003}
+[Arbitrary Label]{0.3336401879787445 -0.0024074832908809185 -14.015975952148438}{-0.8299760222434998 0.19688645005226135 -0.5218961238861084}{15.868016035928465}{-94.62674045286937}{27.905145957890003}
diff --git a/Build/source/utils/asymptote/examples/BezierPatch.asy b/Build/source/utils/asymptote/examples/BezierPatch.asy
new file mode 100644
index 00000000000..0e6b477eb13
--- /dev/null
+++ b/Build/source/utils/asymptote/examples/BezierPatch.asy
@@ -0,0 +1,14 @@
+import three;
+
+size(10cm);
+currentlight=(0,0,1);
+
+surface s=surface(patch(new triple[][] {
+ {(0,0,0),(1,0,0),(1,0,0),(2,0,0)},
+ {(0,1,0),(1,0,1),(1,0,1),(2,1,0)},
+ {(0,1,0),(1,0,-1),(1,0,-1),(2,1,0)},
+ {(0,2,0),(1,2,0),(1,2,0),(2,2,0)}}));
+
+draw(s,yellow);
+draw(s.s[0].vequals(0.5),squarecap+2bp+blue,currentlight);
+draw(s.s[0].uequals(0.5),squarecap+2bp+red,currentlight);
diff --git a/Build/source/utils/asymptote/examples/BezierSurface.asy b/Build/source/utils/asymptote/examples/BezierSurface.asy
new file mode 100644
index 00000000000..65410deebca
--- /dev/null
+++ b/Build/source/utils/asymptote/examples/BezierSurface.asy
@@ -0,0 +1,38 @@
+import three;
+
+string viewpoint="{-24.132780075073242 7.2992024421691895 7.695427417755127}{0.8244762420654297 -0.563306450843811 0.0540805421769619}{35.62141440580922}{17.392748820528627}{}";
+
+//viewpoint=getstring("viewpoint",viewpoint);
+currentprojection=perspective(viewpoint);
+
+currentlight=adobe;
+
+triple[][][] P={{
+ {(-1.6,0,1.875),(-1.6,-0.3,1.875),(-1.5,-0.3,2.1),(-1.5,0,2.1)},
+ {(-2.3,0,1.875),(-2.3,-0.3,1.875),(-2.5,-0.3,2.1),(-2.5,0,2.1)},
+ {(-2.7,0,1.875),(-2.7,-0.3,1.875),(-3,-0.3,2.1),(-3,0,2.1)},
+ {(-2.7,0,1.65),(-2.7,-0.3,1.65),(-3,-0.3,1.65),(-3,0,1.65)}
+ },{
+ {(-2.7,0,1.65),(-2.7,-0.3,1.65),(-3,-0.3,1.65),(-3,0,1.65)},
+ {(-2.7,0,1.425),(-2.7,-0.3,1.425),(-3,-0.3,1.2),(-3,0,1.2)},
+ {(-2.5,0,0.975),(-2.5,-0.3,0.975),(-2.65,-0.3,0.7275),(-2.65,0,0.7275)},
+ {(-2,0,0.75),(-2,-0.3,0.75),(-1.9,-0.3,0.45),(-1.9,0,0.45)}
+ },{
+ {(-2.7,0,1.65),(-2.7,0.3,1.65),(-3,0.3,1.65),(-3,0,1.65)},
+ {(-2.7,0,1.875),(-2.7,0.3,1.875),(-3,0.3,2.1),(-3,0,2.1)},
+ {(-2.3,0,1.875),(-2.3,0.3,1.875),(-2.5,0.3,2.1),(-2.5,0,2.1)},
+ {(-1.6,0,1.875),(-1.6,0.3,1.875),(-1.5,0.3,2.1),(-1.5,0,2.1)}
+ },{
+ {(-2,0,0.75),(-2,0.3,0.75),(-1.9,0.3,0.45),(-1.9,0,0.45)},
+ {(-2.5,0,0.975),(-2.5,0.3,0.975),(-2.65,0.3,0.7275),(-2.65,0,0.7275)},
+ {(-2.7,0,1.425),(-2.7,0.3,1.425),(-3,0.3,1.2),(-3,0,1.2)},
+ {(-2.7,0,1.65),(-2.7,0.3,1.65),(-3,0.3,1.65),(-3,0,1.65)}
+ }};
+
+picture pic;
+size(pic,15cm);
+size3(pic,10cm);
+draw(pic,surface(P),blue);
+
+add(embed("label",pic),(0,0),N);
+label(cameralink("label"),(0,0),10S,fontsize(24pt));
diff --git a/Build/source/utils/asymptote/examples/Coons.asy b/Build/source/utils/asymptote/examples/Coons.asy
new file mode 100644
index 00000000000..9f59d152575
--- /dev/null
+++ b/Build/source/utils/asymptote/examples/Coons.asy
@@ -0,0 +1,6 @@
+size(200);
+
+pen[] p={red,green,blue,magenta};
+path g=(0,0){dir(45)}..(1,0)..(1,1)..(0,1)..cycle;
+tensorshade(g,p);
+dot(g);
diff --git a/Build/source/utils/asymptote/examples/Gouraud.asy b/Build/source/utils/asymptote/examples/Gouraud.asy
new file mode 100644
index 00000000000..d49813e5e66
--- /dev/null
+++ b/Build/source/utils/asymptote/examples/Gouraud.asy
@@ -0,0 +1,18 @@
+size(200);
+
+pen[] p={red,green,blue,magenta};
+pair[] z={(-1,0),(0,0),(0,1),(1,0)};
+int[] edges={0,0,0,1};
+gouraudshade(z[0]--z[2]--z[3]--cycle,p,z,edges);
+
+draw(z[0]--z[1]--z[2]--cycle);
+draw(z[1]--z[3]--z[2],dashed);
+
+dot(Label,z[0],W);
+dot(Label,z[1],S);
+dot(Label,z[2],N);
+dot(Label,z[3],E);
+
+label("0",z[0]--z[1],S,red);
+label("1",z[1]--z[2],E,red);
+label("2",z[2]--z[0],NW,red);
diff --git a/Build/source/utils/asymptote/examples/Gouraudcontour.asy b/Build/source/utils/asymptote/examples/Gouraudcontour.asy
new file mode 100644
index 00000000000..1cf788869a2
--- /dev/null
+++ b/Build/source/utils/asymptote/examples/Gouraudcontour.asy
@@ -0,0 +1,31 @@
+import graph;
+import palette;
+import contour;
+
+size(200);
+
+int n=100;
+
+real[] x=new real[n];
+real[] y=new real[n];
+real[] f=new real[n];
+
+real F(real a, real b) {return a^2+b^2;}
+
+real r() {return 1.1*(rand()/randMax*2-1);}
+
+for(int i=0; i < n; ++i) {
+ x[i]=r();
+ y[i]=r();
+ f[i]=F(x[i],y[i]);
+}
+
+pen Tickpen=black;
+pen tickpen=gray+0.5*linewidth(currentpen);
+pen[] Palette=BWRainbow();
+
+bounds range=image(x,y,f,Range(0,2),Palette);
+draw(contour(pairs(x,y),f,new real[]{0.25,0.5,1},operator ..));
+
+palette("$f(x,y)$",range,point(NW)+(0,0.5),point(NE)+(0,0.8),Top,Palette,
+ PaletteTicks(Tickpen,tickpen));
diff --git a/Build/source/utils/asymptote/examples/Klein.asy b/Build/source/utils/asymptote/examples/Klein.asy
new file mode 100644
index 00000000000..ba3bccd87e9
--- /dev/null
+++ b/Build/source/utils/asymptote/examples/Klein.asy
@@ -0,0 +1,19 @@
+import graph3;
+
+size(200,0);
+currentprojection=perspective(40,-100,40);
+
+// From http://local.wasp.uwa.edu.au/~pbourke/surfaces_curves/klein/
+triple f(pair t) {
+ real u=t.x;
+ real v=t.y;
+ real r=4*(1-cos(u)/2);
+ real x=6*cos(u)*(1+sin(u))+(u < pi ? r*cos(u)*cos(v) : r*cos(v+pi));
+ real y=16*sin(u)+(u < pi ? r*sin(u)*cos(v) : 0);
+ real z=r*sin(v);
+ return (x,y,z);
+}
+
+pen p=rgb(0.2,0.5,0.7);
+
+draw(surface(f,(0,0),(2pi,2pi),60,60),lightgray,meshpen=p);
diff --git a/Build/source/utils/asymptote/examples/Pythagoras.asy b/Build/source/utils/asymptote/examples/Pythagoras.asy
new file mode 100644
index 00000000000..f4ea68fe432
--- /dev/null
+++ b/Build/source/utils/asymptote/examples/Pythagoras.asy
@@ -0,0 +1,22 @@
+size(0,150);
+import geometry;
+
+real a=3;
+real b=4;
+real c=hypot(a,b);
+
+pair z1=(0,b);
+pair z2=(a,0);
+pair z3=(a+b,0);
+perpendicular(z1,NE,z1--z2,blue);
+perpendicular(z3,NW,blue);
+draw(square((0,0),z3));
+draw(square(z1,z2));
+
+real d=0.3;
+pair v=unit(z2-z1);
+draw(baseline("$a$"),-d*I--z2-d*I,red,Bars,Arrows,PenMargins);
+draw(baseline("$b$"),z2-d*I--z3-d*I,red,Arrows,Bars,PenMargins);
+draw("$c$",z3+z2*I-d*v--z2-d*v,red,Arrows,PenMargins);
+draw("$a$",z3+d--z3+z2*I+d,red,Arrows,Bars,PenMargins);
+draw("$b$",z3+z2*I+d--z3+z3*I+d,red,Arrows,Bars,PenMargins);
diff --git a/Build/source/utils/asymptote/examples/PythagoreanTree.asy b/Build/source/utils/asymptote/examples/PythagoreanTree.asy
new file mode 100644
index 00000000000..8ea66650bf3
--- /dev/null
+++ b/Build/source/utils/asymptote/examples/PythagoreanTree.asy
@@ -0,0 +1,20 @@
+size(250);
+
+real a=3;
+real b=4;
+real c=hypot(a,b);
+
+transform ta=shift(c,c)*rotate(-aCos(a/c))*scale(a/c)*shift(-c);
+transform tb=shift(0,c)*rotate(aCos(b/c))*scale(b/c);
+
+picture Pythagorean(int n) {
+ picture pic;
+ fill(pic,scale(c)*unitsquare,1/(n+1)*green+n/(n+1)*brown);
+ if(n == 0) return pic;
+ picture branch=Pythagorean(--n);
+ add(pic,ta*branch);
+ add(pic,tb*branch);
+ return pic;
+}
+
+add(Pythagorean(12));
diff --git a/Build/source/utils/asymptote/examples/RiemannSurface.asy b/Build/source/utils/asymptote/examples/RiemannSurface.asy
new file mode 100644
index 00000000000..68c8f237a19
--- /dev/null
+++ b/Build/source/utils/asymptote/examples/RiemannSurface.asy
@@ -0,0 +1,13 @@
+import graph3;
+import palette;
+
+size(200,300,keepAspect=false);
+//settings.nothin=true;
+
+currentprojection=orthographic(10,10,30);
+currentlight=(10,10,5);
+triple f(pair t) {return (exp(t.x)*cos(t.y),exp(t.x)*sin(t.y),t.y);}
+
+surface s=surface(f,(-4,-2pi),(0,4pi),30,60);
+s.colors(palette(s.map(zpart),Rainbow()));
+draw(s,meshpen=black);
diff --git a/Build/source/utils/asymptote/examples/RiemannSurfaceRoot.asy b/Build/source/utils/asymptote/examples/RiemannSurfaceRoot.asy
new file mode 100644
index 00000000000..50cb9ead31d
--- /dev/null
+++ b/Build/source/utils/asymptote/examples/RiemannSurfaceRoot.asy
@@ -0,0 +1,17 @@
+// Riemann surface of z^{1/n}
+import graph3;
+import palette;
+
+int n=3;
+
+size(200,300,keepAspect=false);
+//settings.nothin=true;
+
+currentprojection=orthographic(10,10,30);
+currentlight=(10,10,5);
+triple f(pair t) {return (t.x*cos(t.y),t.x*sin(t.y),t.x^(1/n)*sin(t.y/n));}
+
+surface s=surface(f,(0,0),(1,2pi*n),30,60);
+s.colors(palette(s.map(zpart),Rainbow()));
+
+draw(s,meshpen=black);
diff --git a/Build/source/utils/asymptote/examples/Sierpinski.asy b/Build/source/utils/asymptote/examples/Sierpinski.asy
new file mode 100644
index 00000000000..d1664045d9f
--- /dev/null
+++ b/Build/source/utils/asymptote/examples/Sierpinski.asy
@@ -0,0 +1,17 @@
+size(10cm);
+
+// Draw Sierpinski triangle with top vertex A, side s, and depth q.
+void Sierpinski(pair A, real s, int q, bool top=true)
+{
+ pair B=A-(1,sqrt(2))*s/2;
+ pair C=B+s;
+ if(top) draw(A--B--C--cycle);
+ draw((A+B)/2--(B+C)/2--(A+C)/2--cycle);
+ if(q > 0) {
+ Sierpinski(A,s/2,q-1,false);
+ Sierpinski((A+B)/2,s/2,q-1,false);
+ Sierpinski((A+C)/2,s/2,q-1,false);
+ }
+}
+
+Sierpinski((0,1),1,5);
diff --git a/Build/source/utils/asymptote/examples/advection.asy b/Build/source/utils/asymptote/examples/advection.asy
new file mode 100644
index 00000000000..ea993ff0fc8
--- /dev/null
+++ b/Build/source/utils/asymptote/examples/advection.asy
@@ -0,0 +1,87 @@
+size(0,22cm);
+
+texpreamble("
+\usepackage{bm}
+\def\v{\bm}
+\def\grad{\v\nabla}
+\def\cross{{\v\times}}
+\def\curl{\grad\cross}
+\def\del{\nabla}
+");
+
+defaultpen(fontsize(10pt));
+
+real margin=1.5mm;
+
+object IC=draw("initial condition $\v U_0$",box,(0,1),
+ margin,black,FillDraw(palegray));
+object Adv0=draw("Lagrangian state $\v U(t)$",ellipse,(1,1),
+ margin,red,FillDraw(palered));
+object Adv=draw("Lagrangian prediction $\v U(t+\tau)$",ellipse,(1,0),
+ margin,red,FillDraw(palered));
+object AdvD=draw("diffused parcels",ellipse,(1.8,1),
+ margin,red,FillDraw(palered));
+object Ur=draw("rearranged $\v \widetilde U$",box,(0,0),
+ margin,orange+gray,FillDraw(paleyellow));
+object Ui=draw("interpolated $\v \widetilde U$",box,(1,-1),
+ margin,blue,FillDraw(paleblue));
+object Crank=draw("${\cal L}^{-1}(-\tau){\cal L}(\tau)\v \widetilde U$",
+ box,(0.5,-1),margin,blue,FillDraw(paleblue));
+object CrankR=draw("${\cal L}^{-1}(-\tau){\cal L}(\tau)\v \widetilde U$",
+ box,(0,-1),margin,orange+gray,FillDraw(paleyellow));
+object Urout=draw(minipage("\center{Lagrangian rearranged solution~$\v U_R$}",
+ 100pt),box,(0,-2),margin,orange+gray,
+ FillDraw(paleyellow));
+object Diff=draw("$\v D\del^2 \v \widetilde U$",box,(0.75,-1.5),
+ margin,blue,FillDraw(paleblue));
+object UIout=draw(minipage("\center{semi-Lagrangian solution~$\v U_I$}",80pt),
+ box,(0.5,-2),margin,FillDraw(palered+paleyellow));
+object psi=draw("$\psi=\del^{-2}\omega$",box,(1.6,-1),
+ margin,darkgreen,FillDraw(palegreen));
+object vel=draw("$\v v=\v{\hat z} \cross\grad\psi$",box,(1.6,-0.5),
+ margin,darkgreen,FillDraw(palegreen));
+
+add(new void(frame f, transform t) {
+ pair padv=0.5*(point(Adv0,S,t)+point(Adv,N,t));
+ picture pic;
+ draw(pic,"initialize",point(IC,E,t)--point(Adv0,W,t),RightSide,Arrow,
+ PenMargin);
+ draw(pic,minipage("\flushright{advect: Runge-Kutta}",80pt),
+ point(Adv0,S,t)--point(Adv,N,t),RightSide,red,Arrow,PenMargin);
+ draw(pic,Label("Lagrange $\rightarrow$ Euler",0.45),
+ point(Adv,W,t)--point(Ur,E,t),5LeftSide,orange+gray,
+ Arrow,PenMargin);
+ draw(pic,"Lagrange $\rightarrow$ Euler",point(Adv,S,t)--point(Ui,N,t),
+ RightSide,blue,Arrow,PenMargin);
+ draw(pic,point(Adv,E,t)--(point(AdvD,S,t).x,point(Adv,E,t).y),red,
+ Arrow(Relative(0.7)),PenMargin);
+ draw(pic,minipage("\flushleft{diffuse: multigrid Crank--Nicholson}",80pt),
+ point(Ui,W,t)--point(Crank,E,t),5N,blue,MidArrow,PenMargin);
+ draw(pic,minipage("\flushleft{diffuse: multigrid Crank--Nicholson}",80pt),
+ point(Ur,S,t)--point(CrankR,N,t),LeftSide,orange+gray,Arrow,PenMargin);
+ draw(pic,"output",point(CrankR,S,t)--point(Urout,N,t),RightSide,
+ orange+gray,Arrow,PenMargin);
+ draw(pic,point(Ui,S,t)--point(Diff,N,t),blue,MidArrow,PenMargin);
+ draw(pic,point(Crank,S,t)--point(Diff,N,t),blue,MidArrow,PenMargin);
+ label(pic,"subtract",point(Diff,N,t),12N,blue);
+ draw(pic,Label("Euler $\rightarrow$ Lagrange",0.5),
+ point(Diff,E,t)--(point(AdvD,S,t).x,point(Diff,E,t).y)--
+ (point(AdvD,S,t).x,point(Adv,E,t).y),RightSide,blue,
+ Arrow(position=1.5),PenMargin);
+ dot(pic,(point(AdvD,S,t).x,point(Adv,E,t).y),red);
+ draw(pic,(point(AdvD,S,t).x,point(Adv,E,t).y)--point(AdvD,S,t),red,Arrow,
+ PenMargin);
+ draw(pic,"output",point(Crank,S,t)--point(UIout,N,t),RightSide,brown,Arrow,
+ PenMargin);
+ draw(pic,Label("$t+\tau\rightarrow t$",0.45),
+ point(AdvD,W,t)--point(Adv0,E,t),2.5LeftSide,red,Arrow,PenMargin);
+ draw(pic,point(psi,N,t)--point(vel,S,t),darkgreen,Arrow,PenMargin);
+ draw(pic,Label("self-advection",4.5),point(vel,N,t)--
+ arc((point(vel,N,t).x,point(Adv,E,t).y),5,270,90)--
+ (point(vel,N,t).x,padv.y)--
+ padv,LeftSide,darkgreen,Arrow,PenMargin);
+ draw(pic,Label("multigrid",0.5,S),point(Ui,E,t)--point(psi,W,t),darkgreen,
+ Arrow,PenMargin);
+
+ add(f,pic.fit());
+ });
diff --git a/Build/source/utils/asymptote/examples/alignbox.asy b/Build/source/utils/asymptote/examples/alignbox.asy
new file mode 100644
index 00000000000..8f216c6a10c
--- /dev/null
+++ b/Build/source/utils/asymptote/examples/alignbox.asy
@@ -0,0 +1,9 @@
+real margin=1.5mm;
+
+object left=align(object("$x^2$",ellipse,margin),W);
+add(left);
+object right=align(object("$\sin x$",ellipse,margin),4E);
+add(right);
+currentpicture.add(new void(frame f, transform t) {
+ draw(f,point(left,NE,t)--point(right,W,t));
+ });
diff --git a/Build/source/utils/asymptote/examples/alignedaxis.asy b/Build/source/utils/asymptote/examples/alignedaxis.asy
new file mode 100644
index 00000000000..542dcb9bc60
--- /dev/null
+++ b/Build/source/utils/asymptote/examples/alignedaxis.asy
@@ -0,0 +1,107 @@
+import graph;
+
+real Freq=60.0;
+real margin=5mm;
+
+pair exp(pair x) {
+ return exp(x.x)*(cos(x.y)+I*sin(x.y));
+}
+
+real Merr(real x, real w) {
+ real tau=x/(2*Freq);
+ return 20*log(abs((tau*w+tau/(exp(I*2*pi*Freq*tau)-1))*(I*2*pi*Freq)));
+}
+
+real Aerr(real x, real w) {
+ real tau=x/(2*Freq);
+ return degrees((tau*w+tau/(exp(I*2*pi*Freq*tau)-1))*(I*2*pi*Freq));
+}
+
+picture pic1;
+scale(pic1,Log,Linear);
+real Merr1(real x){return Merr(x,1);}
+draw(pic1,graph(pic1,Merr1,1e-4,1),black+1.2);
+
+ylimits(pic1,-60,20);
+yaxis(pic1,"magnitude (dB)",LeftRight,RightTicks(new
+ real[] {-60,-40,-20,0,20}));
+xaxis(pic1,"$f/f_\mathrm{Ny}$",BottomTop,LeftTicks(N=5));
+yequals(pic1,0,Dotted);
+yequals(pic1,-20,Dotted);
+yequals(pic1,-40,Dotted);
+xequals(pic1,1e-3,Dotted);
+xequals(pic1,1e-2,Dotted);
+xequals(pic1,1e-1,Dotted);
+
+size(pic1,100,100,point(pic1,SW),point(pic1,NE));
+
+label(pic1,"$\theta=1$",point(pic1,N),2N);
+
+frame f1=pic1.fit();
+add(f1);
+
+picture pic1p;
+scale(pic1p,Log,Linear);
+real Aerr1(real x){return Aerr(x,1);}
+draw(pic1p,graph(pic1p,Aerr1,1e-4,1),black+1.2);
+
+ylimits(pic1p,-5,95);
+yaxis(pic1p,"phase (deg)",LeftRight,RightTicks(new real[] {0,45,90}));
+xaxis(pic1p,"$f/f_\mathrm{Ny}$",BottomTop,LeftTicks(N=5));
+yequals(pic1p,0,Dotted);
+yequals(pic1p,45,Dotted);
+yequals(pic1p,90,Dotted);
+xequals(pic1p,1e-3,Dotted);
+xequals(pic1p,1e-2,Dotted);
+xequals(pic1p,1e-1,Dotted);
+
+size(pic1p,100,100,point(pic1p,SW),point(pic1p,NE));
+
+frame f1p=pic1p.fit();
+f1p=shift(0,min(f1).y-max(f1p).y-margin)*f1p;
+add(f1p);
+
+picture pic2;
+scale(pic2,Log,Linear);
+real Merr2(real x){return Merr(x,0.75);}
+draw(pic2,graph(pic2,Merr2,1e-4,1),black+1.2);
+
+ylimits(pic2,-60,20);
+yaxis(pic2,"magnitude (dB)",LeftRight,RightTicks(new
+ real[] {-60,-40,-20,0,20}));
+xaxis(pic2,"$f/f_\mathrm{Ny}$",BottomTop,LeftTicks(N=5));
+yequals(pic2,0,Dotted);
+yequals(pic2,-20,Dotted);
+yequals(pic2,-40,Dotted);
+xequals(pic2,1e-3,Dotted);
+xequals(pic2,1e-2,Dotted);
+xequals(pic2,1e-1,Dotted);
+
+size(pic2,100,100,point(pic2,SW),point(pic2,NE));
+
+label(pic2,"$\theta=0.75$",point(pic2,N),2N);
+
+frame f2=pic2.fit();
+f2=shift(max(f1).x-min(f2).x+margin)*f2;
+add(f2);
+
+picture pic2p;
+scale(pic2p,Log,Linear);
+real Aerr2(real x){return Aerr(x,0.75);}
+draw(pic2p,graph(pic2p,Aerr2,1e-4,1),black+1.2);
+
+ylimits(pic2p,-5,95);
+yaxis(pic2p,"phase (deg)",LeftRight,RightTicks(new real[] {0,45.1,90}));
+xaxis(pic2p,"$f/f_\mathrm{Ny}$",BottomTop,LeftTicks(N=5));
+yequals(pic2p,0,Dotted);
+yequals(pic2p,45,Dotted);
+yequals(pic2p,90,Dotted);
+xequals(pic2p,1e-3,Dotted);
+xequals(pic2p,1e-2,Dotted);
+xequals(pic2p,1e-1,Dotted);
+
+size(pic2p,100,100,point(pic2p,SW),point(pic2p,NE));
+
+frame f2p=pic2p.fit();
+f2p=shift(max(f1p).x-min(f2p).x+margin,min(f2).y-max(f2p).y-margin)*f2p;
+add(f2p);
diff --git a/Build/source/utils/asymptote/examples/animations/cube.asy b/Build/source/utils/asymptote/examples/animations/cube.asy
new file mode 100644
index 00000000000..001e54466d8
--- /dev/null
+++ b/Build/source/utils/asymptote/examples/animations/cube.asy
@@ -0,0 +1,46 @@
+import math;
+import bsp;
+import animation;
+
+size(100,100);
+
+animation a;
+
+void face(face[] faces, path3 p, int j, int k) {
+ picture pic=faces.push(p);
+ filldraw(pic,project(p),Pen(j));
+ int sign=(k % 2 == 0) ? 1 : -1;
+ transform t=scale(4)*transform(dir(p,0,sign),dir(p,0,-sign));
+ label(pic,t*(string) j,project(0.5*(min(p)+max(p))));
+}
+
+void snapshot(transform3 t)
+{
+ static transform3 s=shift(-0.5*(X+Y+Z));
+ save();
+
+ face[] faces;
+ int j=-1;
+ transform3 T=t*s;
+ for(int k=0; k < 2; ++k) {
+ face(faces,T*plane((1,0,0),(0,1,0),(0,0,k)),++j,k);
+ face(faces,T*plane((0,1,0),(0,0,1),(k,0,0)),++j,k);
+ face(faces,T*plane((0,0,1),(1,0,0),(0,k,0)),++j,k);
+ }
+ add(faces);
+
+ a.add();
+ restore();
+}
+
+int n=50;
+
+real step=360/n;
+for(int i=0; i < n; ++i)
+ snapshot(rotate(i*step,X));
+for(int i=0; i < n; ++i)
+ snapshot(rotate(i*step,Y));
+for(int i=0; i < n; ++i)
+ snapshot(rotate(i*step,Z));
+
+a.movie(loops=10,delay=50);
diff --git a/Build/source/utils/asymptote/examples/animations/dice.u3d b/Build/source/utils/asymptote/examples/animations/dice.u3d
new file mode 100644
index 00000000000..ae14b756a16
--- /dev/null
+++ b/Build/source/utils/asymptote/examples/animations/dice.u3d
Binary files differ
diff --git a/Build/source/utils/asymptote/examples/animations/earthmoon.asy b/Build/source/utils/asymptote/examples/animations/earthmoon.asy
new file mode 100644
index 00000000000..abd8ac9f431
--- /dev/null
+++ b/Build/source/utils/asymptote/examples/animations/earthmoon.asy
@@ -0,0 +1,77 @@
+import graph3;
+import solids;
+import three;
+import animate;
+
+settings.render=2;
+settings.tex="pdflatex";
+settings.prc=false;
+settings.thick=false;
+settings.outformat="mpg";
+currentprojection=orthographic(5,4,2);
+currentlight=light(specular=black,(0.1,-0.1,1));
+
+size(15cm,0);
+
+animation A;
+
+real Rst=20, Rl=0.7, Rtl=5;
+real ast=20, est=0.3, bst=ast*sqrt(1-est^2), cst=ast*est;
+real atl=5, etl=0.8, btl=atl*sqrt(1-etl^2), ctl=atl*etl;
+
+real xST(real t) {return ast*cos(t)+cst;}
+real yST(real t) {return bst*sin(t);}
+real zST(real t) {return 0;}
+
+real xTL(real t) {return atl*cos(27*t);}
+real yTL(real t) {return btl*sin(27*t);}
+real zTL(real t) {return 0;}
+
+
+real xLl(real t) {return Rl*cos(27*t);}
+real yLl(real t) {return Rl*sin(27*t);}
+real zLl(real t) {return 0;}
+
+real xTt(real t) {return Rtl*cos(100*(t))/5;}
+real yTt(real t) {return Rtl*sin(100*(t))/5;}
+real zTt(real t) {return 0;}
+
+real xl(real t) {return xST(t)+xTL(t)+xLl(t);}
+real yl(real t) {return yST(t)+yTL(t)+yLl(t);}
+real zl(real t) {return 0;}
+
+real xt(real t) {return xST(t)+xTt(t);}
+real yt(real t) {return yST(t)+yTt(t);}
+real zt(real t) {return 0;}
+
+real xL(real t) {return xST(t)+xTL(t);}
+real yL(real t) {return yST(t)+yTL(t);}
+real zL(real t) {return 0;}
+
+path3 Pl=graph(xl,yl,zl,0,2*pi,1000),Pt=graph(xt,yt,zt,0,2*pi,3000),
+Pts=graph(xST,yST,zST,0,2*pi,500);
+
+picture pic;
+
+draw(pic,Pl,lightgray);
+draw(pic,Pt,lightblue);
+draw(pic,Pts,blue+dashed);
+
+draw(pic,shift(cst,0,0)*scale3(Rtl/2)*unitsphere,yellow);
+
+surface terre=scale3(Rtl/5)*unitsphere;
+surface lune=scale3(Rl)*unitsphere;
+
+int n=100;
+real step=2pi/n;
+for(int i=0; i < n; ++i) {
+ real k=i*step;
+ add(pic);
+ draw(shift(xL(k),yL(k),0)*lune,lightgray);
+ draw(shift(xST(k),yST(k),0)*terre,lightblue+lightgreen);
+ A.add();
+ erase();
+}
+
+A.movie(BBox(1mm,Fill(Black)),delay=500,
+ options="-density 288x288 -geometry 50%x");
diff --git a/Build/source/utils/asymptote/examples/animations/embeddedmovie.asy b/Build/source/utils/asymptote/examples/animations/embeddedmovie.asy
new file mode 100644
index 00000000000..98dfd424db8
--- /dev/null
+++ b/Build/source/utils/asymptote/examples/animations/embeddedmovie.asy
@@ -0,0 +1,24 @@
+// An embedded movie;
+//
+// See http://www.tug.org/tex-archive/macros/latex/contrib/movie15/README
+// for documentation of the options.
+
+import embed; // Add embedded movie
+//import external; // Add external movie (use this form under Linux).
+
+// Generated needed mpeg file if it doesn't already exist.
+asy("mpg","wheel");
+
+// Produce a pdf file.
+settings.outformat="pdf";
+
+settings.twice=true;
+
+// An embedded movie:
+label(embed("wheel.mpg","poster,text=wheel.mpg,label=wheel.mpg",20cm,5.6cm),
+ (0,0),N);
+
+// An optional button:
+label(link("wheel.mpg","Play","play"),(0,0),S);
+
+
diff --git a/Build/source/utils/asymptote/examples/animations/embeddedu3d.asy b/Build/source/utils/asymptote/examples/animations/embeddedu3d.asy
new file mode 100644
index 00000000000..1116c216fe2
--- /dev/null
+++ b/Build/source/utils/asymptote/examples/animations/embeddedu3d.asy
@@ -0,0 +1,6 @@
+// An embedded U3D object;
+//
+import embed;
+
+label(embed("dice.u3d","poster,text=(dice.u3d),3Droo=27,label=dice",settings.paperwidth,settings.paperheight));
+
diff --git a/Build/source/utils/asymptote/examples/animations/externalmovie.asy b/Build/source/utils/asymptote/examples/animations/externalmovie.asy
new file mode 100644
index 00000000000..77c99528307
--- /dev/null
+++ b/Build/source/utils/asymptote/examples/animations/externalmovie.asy
@@ -0,0 +1,17 @@
+// Embed a movie to be run in an external window.
+
+import external;
+
+// External movies require the pdflatex engine.
+settings.tex="pdflatex";
+
+// Generated needed mpeg file if it doesn't already exist.
+asy("mpg","wheel");
+
+// Produce a pdf file.
+settings.outformat="pdf";
+
+// External movie: viewable even with the Linux version of acroread.
+label(embed("wheel.mpg"),(0,0),N);
+
+label(link("wheel.mpg","Play"),(0,0),S);
diff --git a/Build/source/utils/asymptote/examples/animations/heatequation.asy b/Build/source/utils/asymptote/examples/animations/heatequation.asy
new file mode 100644
index 00000000000..3c5708e583f
--- /dev/null
+++ b/Build/source/utils/asymptote/examples/animations/heatequation.asy
@@ -0,0 +1,76 @@
+import graph3;
+import palette;
+import animate;
+
+settings.tex="pdflatex";
+settings.render=0;
+settings.prc=false;
+unitsize(1cm);
+
+animation a;
+
+currentprojection=perspective(-20,-18,18);
+currentlight=light(1,1,10);
+
+int n=26;
+real L=2.5;
+real dx=2*L/n;
+real CFL=0.125;
+real dt=CFL*dx^2;
+
+real[][] Z=new real[n][n];
+real[][] W=new real[n][n];
+
+guide initcond1=shift((-1,-1))*scale(0.5)*unitcircle;
+guide initcond2=shift((0.5,0))*yscale(1.2)*unitcircle;
+
+real f(pair p) {return (inside(initcond1,p)||inside(initcond2,p)) ? 2 : 0;}
+
+//Initialize
+for(int i=0; i < n; ++i)
+ for (int j=0; j < n; ++j)
+ Z[i][j]=f((-L,-L)+(2*L/n)*(i,j));
+
+real f(pair t) {
+ int i=round((n/2)*(t.x/L+1));
+ int j=round((n/2)*(t.y/L+1));
+ if(i > n-1) i=n-1;
+ if(j > n-1) j=n-1;
+ return Z[i][j];
+}
+
+surface sf;
+
+void advanceZ(int iter=20) {
+ for(int k=0; k < iter; ++k) {
+ for(int i=0; i < n; ++i)
+ for(int j=0; j < n; ++j) W[i][j]=0;
+ for(int i=1; i < n-1; ++i)
+ for(int j=1; j< n-1; ++j)
+ W[i][j]=Z[i][j]+(dt/dx^2)*(Z[i+1][j]+Z[i-1][j]+Z[i][j-1]+Z[i][j+1]
+ -4*Z[i][j]);
+ for(int i=0; i < n; ++i)
+ for(int j=0; j < n; ++j)
+ Z[i][j]=W[i][j];
+ };
+}
+
+pen[] Pal=Rainbow(96);
+
+int endframe=40;
+
+for(int fr=0; fr < endframe; ++fr) {
+ if(fr == 0) {// smoothing of initial state; no Spline, but full grid
+ advanceZ(3);
+ sf=surface(f,(-L,-L),(L,L),nx=n);
+ } else // use Spline and fewer grid points to save memory
+ sf=surface(f,(-L,-L),(L,L),nx=round(n/2),Spline);
+ sf.colors(palette(sf.map(zpart),Pal[0:round(48*max(sf).z)]));
+ draw(sf);
+ a.add();
+ erase();
+ advanceZ(30);
+};
+
+label(a.pdf(delay=400,"controls,loop"));
+shipout(bbox(3mm,darkblue+3bp+miterjoin,FillDraw(fillpen=paleblue)),"pdf");
diff --git a/Build/source/utils/asymptote/examples/animations/inlinemovie.tex b/Build/source/utils/asymptote/examples/animations/inlinemovie.tex
new file mode 100644
index 00000000000..3fa61b6673b
--- /dev/null
+++ b/Build/source/utils/asymptote/examples/animations/inlinemovie.tex
@@ -0,0 +1,51 @@
+\documentclass{article}
+\usepackage[inline]{asymptote}
+%\usepackage{asymptote}
+\usepackage{animate}
+\begin{document}
+
+Here is an inline PDF movie, generated with the commands
+\begin{verbatim}
+pdflatex inlinemovie
+asy inlinemovie
+pdflatex inlinemovie
+\end{verbatim}
+
+\begin{center}
+\begin{asy}
+import animate;
+animation A=animation("movie1");
+real h=2pi/10;
+
+picture pic;
+unitsize(pic,2cm);
+for(int i=0; i < 10; ++i) {
+ draw(pic,expi(i*h)--expi((i+1)*h));
+ A.add(pic);
+}
+label(A.pdf("controls",delay=50,keep=!settings.inlinetex));
+\end{asy}
+%Uncomment the following line when not using the [inline] package option:
+%\ASYanimategraphics[controls,loop]{20}{movie1}{}{}
+\end{center}
+
+And here is another one, clickable but without the control panel:
+\begin{center}
+\begin{asy}
+import animate;
+animation A=animation("movie2");
+real h=2pi/10;
+
+picture pic;
+unitsize(pic,2cm);
+for(int i=0; i < 10; ++i) {
+ draw(pic,expi(-i*h)--expi(-(i+1)*h),red);
+ A.add(pic);
+}
+label(A.pdf(keep=!settings.inlinetex));
+\end{asy}
+%Uncomment the following line when not using the [inline] package option:
+%\ASYanimategraphics[controls,loop]{10}{movie2}{}{}
+\end{center}
+
+\end{document}
diff --git a/Build/source/utils/asymptote/examples/animations/inlinemovie3.tex b/Build/source/utils/asymptote/examples/animations/inlinemovie3.tex
new file mode 100644
index 00000000000..c46a17d3e59
--- /dev/null
+++ b/Build/source/utils/asymptote/examples/animations/inlinemovie3.tex
@@ -0,0 +1,41 @@
+\documentclass{article}
+\usepackage[inline]{asymptote}
+%\usepackage{asymptote}
+\usepackage{animate}
+\begin{document}
+
+Here is an inline 3D PDF movie, generated with the commands
+\begin{verbatim}
+pdflatex inlinemovie
+asy inlinemovie
+pdflatex inlinemovie
+\end{verbatim}
+
+\begin{center}
+\begin{asy}
+settings.render=4;
+settings.prc=false;
+
+import graph3;
+import animate;
+currentprojection=orthographic(1,-2,0.5);
+currentlight=(1,1,20);
+animation A=animation("movie3");
+int n=20;
+for(int i=0; i < n; ++i) {
+ picture pic;
+ size3(pic,12cm,12cm,8cm);
+ limits((-2,-2,-2),(2,2,2));
+ real k=i/n*pi;
+ real f(pair z) {return 4cos(abs(z)-k)*exp(-abs(z)/6);}
+ draw(pic,surface(f,(-4pi,-4pi),(4pi,4pi),Spline),paleblue);
+ draw(pic,shift(i*6Z/n)*unitsphere,yellow);
+ A.add(pic);
+}
+label(A.pdf("autoplay,loop",delay=20,keep=!settings.inlinetex));
+\end{asy}
+%Uncomment the following line when not using the [inline] package option:
+%\ASYanimategraphics[autoplay,loop]{50}{movie3}{}{}
+\end{center}
+\end{document}
+
diff --git a/Build/source/utils/asymptote/examples/animations/pdfmovie.asy b/Build/source/utils/asymptote/examples/animations/pdfmovie.asy
new file mode 100644
index 00000000000..0f9cbc96445
--- /dev/null
+++ b/Build/source/utils/asymptote/examples/animations/pdfmovie.asy
@@ -0,0 +1,20 @@
+import animate;
+import patterns;
+
+settings.tex="pdflatex";
+
+animation a;
+
+add("brick",brick(black));
+
+int n=20;
+for(int i=0; i < 3.5n; ++i) {
+ picture pic;
+ size(pic,100);
+ path g=circle((0,sin(pi/n*i)),1);
+ fill(pic,g,mediumred);
+ fill(pic,g,pattern("brick"));
+ a.add(pic);
+}
+
+label(a.pdf("controls",multipage=false));
diff --git a/Build/source/utils/asymptote/examples/animations/slidemovies.asy b/Build/source/utils/asymptote/examples/animations/slidemovies.asy
new file mode 100644
index 00000000000..205f94fbc85
--- /dev/null
+++ b/Build/source/utils/asymptote/examples/animations/slidemovies.asy
@@ -0,0 +1,47 @@
+// Slide demo.
+// Command-line options to enable stepping and/or reverse video:
+// asy [-u stepping=true] [-u reverse=true] slidedemo
+
+orientation=Landscape;
+
+settings.tex="pdflatex";
+
+import slide;
+
+// Optional movie modules:
+import animate; // For portable embedded PDF movies
+access external; // For portable external movies
+access embed; // For non-portable embedded movies
+
+usersetting();
+
+titlepage("Slides with {\tt Asymptote}: Animations","John C. Bowman",
+ "University of Alberta","\today","http://asymptote.sf.net");
+
+title("Embedded PDF movies (portable)");
+animation a=animation("A");
+animation b=animation("B");
+int n=20;
+for(int i=0; i < 2n; ++i) {
+ picture pic;
+ size(pic,100);
+ draw(pic,shift(0,sin(pi/n*i))*unitsquare);
+ a.add(pic);
+ if(i < 1.5n) b.add(rotate(45)*pic);
+}
+display(a.pdf("autoplay,loop,controls",multipage=false));
+display(b.pdf("controls",multipage=false));
+
+// Generated needed files if they don't already exist.
+asy("mpg","wheel");
+
+title("External Movie (portable)");
+display(external.embed("wheel.mpg",
+ "poster,text=wheel.mpg,label=wheel.mpg",20cm,5.6cm));
+display(external.link("wheel.mpg","Play","play"));
+
+title("Embedded Movie (not portable)");
+display(embed.embed("wheel.mpg",
+ "poster,text=wheel.mpg,label=wheel.mpg",
+ 20cm,5.6cm));
+display(embed.link("wheel.mpg","Play","play"));
diff --git a/Build/source/utils/asymptote/examples/animations/sphere.asy b/Build/source/utils/asymptote/examples/animations/sphere.asy
new file mode 100644
index 00000000000..e6bcb589add
--- /dev/null
+++ b/Build/source/utils/asymptote/examples/animations/sphere.asy
@@ -0,0 +1,44 @@
+import solids;
+import animation;
+
+currentprojection=orthographic((0,5,2));
+currentlight=(0,5,5);
+settings.thick=false;
+
+int nbpts=200;
+real step=2*pi/nbpts;
+int angle=10;
+
+unitsize(1cm);
+
+triple[] P=new triple[nbpts];
+for(int i=0; i < nbpts; ++i) {
+ real t=-pi+i*step;
+ P[i]=(3sin(t)*cos(2t),3sin(t)*sin(2t),3cos(t));
+}
+
+transform3 t=rotate(angle,(0,0,0),(1,0.25,0.25));
+revolution r=sphere(O,3);
+draw(surface(r),lightgrey);
+skeleton s;
+r.transverse(s,reltime(r.g,0.5));
+r.longitudinal(s);
+draw(s.transverse.back,linetype("8 8",8));
+draw(s.transverse.front);
+
+animation A;
+
+for(int phi=0; phi < 360; phi += angle) {
+ bool[] front=new bool[nbpts];
+ save();
+ for(int i=0; i < nbpts; ++i) {
+ P[i]=t*P[i];
+ front[i]=dot(P[i],currentprojection.camera) > 0;
+ }
+ draw(segment(P,front,operator ..),1mm+blue+extendcap);
+ draw(segment(P,!front,operator ..),grey);
+ A.add();
+ restore();
+}
+
+A.movie(0,200);
diff --git a/Build/source/utils/asymptote/examples/animations/torusanimation.asy b/Build/source/utils/asymptote/examples/animations/torusanimation.asy
new file mode 100644
index 00000000000..9073ab2b56a
--- /dev/null
+++ b/Build/source/utils/asymptote/examples/animations/torusanimation.asy
@@ -0,0 +1,41 @@
+import graph3;
+import animation;
+import solids;
+
+settings.tex="pdflatex";
+settings.prc=false;
+settings.render=4;
+
+currentprojection=orthographic((0,5,2));
+currentlight=(0,5,5);
+unitsize(1cm);
+
+real R=3;
+real a=1;
+int n=8;
+
+path3[] p=new path3[n];
+animation A;
+
+for(int i=0; i < n; ++i) {
+ triple g(real s) {
+ return ((R-a*cos(2*pi*s))*cos(2*pi/(1+i+s)),
+ (R-a*cos(2*pi*s))*sin(2*pi/(1+i+s)),
+ -a*sin(2*pi*s));
+ }
+ p[i]=graph(g,0,1,operator ..);
+}
+
+revolution torus=revolution(shift(R*X)*Circle(O,a,Y,32),Z);
+surface s=surface(torus);
+
+for(int i=0; i < n; ++i){
+ picture fig;
+ size3(fig,400);
+ draw(fig,s,yellow);
+ for(int j=0;j <= i; ++j)
+ draw(fig,p[j],blue+linewidth(4));
+ A.add(fig);
+}
+
+A.movie(BBox(10,Fill(rgb(0.98,0.98,0.9))),delay=100);
diff --git a/Build/source/utils/asymptote/examples/animations/wavepacket.asy b/Build/source/utils/asymptote/examples/animations/wavepacket.asy
new file mode 100644
index 00000000000..72d35e59c84
--- /dev/null
+++ b/Build/source/utils/asymptote/examples/animations/wavepacket.asy
@@ -0,0 +1,85 @@
+// Author : Philippe Ivaldi
+// 2006/11/10
+
+import animation;
+import graph;
+
+unitsize(x=2cm,y=1.5cm);
+
+typedef real realfcn(real);
+
+real lambda=4;
+real T=2;
+real [] k=new real[3];
+real [] w=new real[3];
+k[0]=2pi/lambda;
+w[0]=2pi/T;
+real dk=-.5;
+k[1]=k[0]-dk;
+k[2]=k[0]+dk;
+real dw=1;
+w[1]=w[0]-dw;
+w[2]=w[0]+dw;
+
+real vp=w[1]/k[1];
+real vg=dw/dk;
+
+realfcn F(real x) {
+ return new real(real t) {
+ return cos(k[1]*x-w[1]*t)+cos(k[2]*x-w[2]*t);
+ };
+};
+
+realfcn G(real x) {
+ return new real(real t) {
+ return 2*cos(0.5*(k[2]-k[1])*x+0.5*(w[1]-w[2])*t);
+ };
+};
+
+realfcn operator -(realfcn f) {return new real(real t) {return -f(t);};};
+
+animation A;
+
+real tmax=abs(2pi/dk);
+real xmax=abs(2pi/dw);
+
+pen envelope=0.8*blue;
+pen fillpen=lightgrey;
+
+int n=50;
+real step=tmax/(n-1);
+for(int i=0; i < n; ++i) {
+ save();
+ real t=i*step;
+ real a=xmax*t/tmax-xmax/pi;
+ real b=xmax*t/tmax;
+ path f=graph(F(t),a,b);
+ path g=graph(G(t),a,b);
+ path h=graph(-G(t),a,b);
+ fill(buildcycle(reverse(f),g),fillpen);
+ draw(f);
+ draw(g,envelope);
+ draw(h,envelope);
+ A.add();
+ restore();
+}
+
+for(int i=0; i < n; ++i) {
+ save();
+ real t=i*step;
+ real a=-xmax/pi;
+ real b=xmax;
+ path f=graph(F(t),a,b);
+ path g=graph(G(t),a,b);
+ path h=graph(-G(t),a,b);
+ path B=box((-xmax/pi,-2),(xmax,2));
+ fill(buildcycle(reverse(f),g,B),fillpen);
+ fill(buildcycle(f,g,reverse(B)),fillpen);
+ draw(f);
+ draw(g,envelope);
+ draw(h,envelope);
+ A.add();
+ restore();
+}
+
+A.movie(0,10);
diff --git a/Build/source/utils/asymptote/examples/animations/wheel.asy b/Build/source/utils/asymptote/examples/animations/wheel.asy
new file mode 100644
index 00000000000..2ea45f75613
--- /dev/null
+++ b/Build/source/utils/asymptote/examples/animations/wheel.asy
@@ -0,0 +1,53 @@
+import graph;
+import animation;
+
+size(0,200);
+
+defaultpen(3);
+dotfactor=4;
+
+pair wheelpoint(real t)
+{
+ return (t+cos(t),-sin(t));
+}
+
+guide wheel(guide g=nullpath, real a, real b, int n)
+{
+ real width=(b-a)/n;
+ for(int i=0; i <= n; ++i) {
+ real t=a+width*i;
+ g=g--wheelpoint(t);
+ }
+ return g;
+}
+
+real t1=0;
+real t2=t1+2*pi;
+
+draw(circle((0,0),1));
+draw(wheel(t1,t2,100),linetype("0 2"));
+yequals(Label("$y=-1$",1.0),-1,extend=true,linetype("4 4"));
+xaxis(Label("$x$",align=3SW),0);
+yaxis("$y$",0,1.2);
+pair z1=wheelpoint(t1);
+pair z2=wheelpoint(t2);
+dot(z1);
+dot(z2);
+
+animation a;
+
+int n=10;
+real dt=(t2-t1)/n;
+for(int i=0; i <= n; ++i) {
+ save();
+
+ real t=t1+dt*i;
+ draw(circle((t,0),1),red);
+ dot(wheelpoint(t));
+
+ a.add(); // Add currentpicture to animation.
+ restore();
+}
+
+// Produce the final merged gif.
+a.movie(BBox(0.25cm),loops=10,delay=250);
diff --git a/Build/source/utils/asymptote/examples/annotation.asy b/Build/source/utils/asymptote/examples/annotation.asy
new file mode 100644
index 00000000000..d52e15b4f76
--- /dev/null
+++ b/Build/source/utils/asymptote/examples/annotation.asy
@@ -0,0 +1,13 @@
+import annotate;
+settings.outformat="pdf";
+
+size(200);
+
+draw(unitcircle);
+dot((0,0));
+annotate("O","(0,0)",(0,0));
+annotate("A","(1,0)",(1,0));
+annotate("B","(0,1)",(0,1));
+annotate("C","(-1,0)",(-1,0));
+annotate("D","(0,-1)",(0,-1));
+
diff --git a/Build/source/utils/asymptote/examples/arrows3.asy b/Build/source/utils/asymptote/examples/arrows3.asy
new file mode 100644
index 00000000000..21121c46d18
--- /dev/null
+++ b/Build/source/utils/asymptote/examples/arrows3.asy
@@ -0,0 +1,20 @@
+import three;
+
+size(15cm);
+
+currentprojection=perspective(24,14,13,showtarget=false,autoadjust=false);
+currentlight=light(gray(0.5),specularfactor=3,viewport=false,
+ (0.5,-0.5,-0.25),(0.5,0.5,0.25),(0.5,0.5,1),(-0.5,-0.5,-1));
+
+defaultpen(0.75mm);
+
+path3 g=arc(O,1,90,-60,90,60);
+transform3 t=shift(invert(3S,O));
+
+draw(g,blue,Arrows3(TeXHead3),currentlight);
+draw(scale3(3)*g,green,ArcArrows3(HookHead3),currentlight);
+draw(scale3(6)*g,red,Arrows3(DefaultHead3),currentlight);
+
+draw(t*g,blue,Arrows3(TeXHead2),currentlight);
+draw(t*scale3(3)*g,green,ArcArrows3(HookHead2,NoFill),currentlight);
+draw(t*scale3(6)*g,red,Arrows3(DefaultHead2(normal=Z)),currentlight);
diff --git a/Build/source/utils/asymptote/examples/buildcycle.asy b/Build/source/utils/asymptote/examples/buildcycle.asy
new file mode 100644
index 00000000000..e4e7f8c7c96
--- /dev/null
+++ b/Build/source/utils/asymptote/examples/buildcycle.asy
@@ -0,0 +1,22 @@
+size(200);
+
+real w=1.35;
+
+path[] p;
+for(int k=0; k < 2; ++k) {
+ int i=2+2*k;
+ int ii=i^2;
+ p[k]=(w/ii,1){1,-ii}::(w/i,1/i)::(w,1/ii){ii,-1};
+}
+
+path q0=(0,0)--(w,0.5);
+path q1=(0,0)--(w,1.5);
+draw(q0); draw(p[0]); draw(q1); draw(p[1]);
+path s=buildcycle(q0,p[0],q1,p[1]);
+fill(s,mediumgrey);
+
+label("$P$",intersectionpoint(p[0],q0),N);
+label("$Q$",intersectionpoint(p[0],q1),E);
+label("$R$",intersectionpoint(p[1],q1),W);
+label("$S$",intersectionpoint(p[1],q0),S);
+label("$f > 0$",0.5*(min(s)+max(s)),UnFill);
diff --git a/Build/source/utils/asymptote/examples/cardioid.asy b/Build/source/utils/asymptote/examples/cardioid.asy
new file mode 100644
index 00000000000..49a3c55207e
--- /dev/null
+++ b/Build/source/utils/asymptote/examples/cardioid.asy
@@ -0,0 +1,15 @@
+import graph;
+
+size(0,100);
+
+real f(real t) {return 1+cos(t);}
+
+path g=polargraph(f,0,2pi,operator ..)--cycle;
+filldraw(g,pink);
+
+xaxis("$x$",above=true);
+yaxis("$y$",above=true);
+
+dot("$(a,0)$",(1,0),N);
+dot("$(2a,0)$",(2,0),N+E);
+
diff --git a/Build/source/utils/asymptote/examples/centroidfg.asy b/Build/source/utils/asymptote/examples/centroidfg.asy
new file mode 100644
index 00000000000..2e26454cdbe
--- /dev/null
+++ b/Build/source/utils/asymptote/examples/centroidfg.asy
@@ -0,0 +1,38 @@
+import graph;
+size(0,150);
+
+int a=-1, b=1;
+
+real f(real x) {return x^3-x+2;}
+real g(real x) {return x^2;}
+
+draw(graph(f,a,b,operator ..),red);
+draw(graph(g,a,b,operator ..),blue);
+
+xaxis();
+
+int n=5;
+
+real width=(b-a)/(real) n;
+for(int i=0; i <= n; ++i) {
+ real x=a+width*i;
+ draw((x,g(x))--(x,f(x)));
+}
+
+labelx("$a$",a);
+labelx("$b$",b);
+draw((a,0)--(a,g(a)),dotted);
+draw((b,0)--(b,g(b)),dotted);
+
+real m=a+0.73*(b-a);
+arrow("$f(x)$",(m,f(m)),N,red);
+arrow("$g(x)$",(m,g(m)),E,0.8cm,blue);
+
+int j=2;
+real xi=b-j*width;
+real xp=xi+width;
+real xm=0.5*(xi+xp);
+pair dot=(xm,0.5*(f(xm)+g(xm)));
+dot(dot,darkgreen+4.0);
+arrow("$\left(x,\frac{f(x)+g(x)}{2}\right)$",dot,NE,2cm,darkgreen);
+
diff --git a/Build/source/utils/asymptote/examples/cheese.asy b/Build/source/utils/asymptote/examples/cheese.asy
new file mode 100644
index 00000000000..f283f5c8115
--- /dev/null
+++ b/Build/source/utils/asymptote/examples/cheese.asy
@@ -0,0 +1,12 @@
+import graph3;
+import palette;
+import contour3;
+size(400);
+
+real f(real x, real y, real z) {
+ return cos(x)*sin(y)+cos(y)*sin(z)+cos(z)*sin(x);
+}
+
+surface sf=surface(contour3(f,(-2pi,-2pi,-2pi),(2pi,2pi,2pi),12));
+sf.colors(palette(sf.map(abs),Gradient(red,yellow)));
+draw(sf,nolight);
diff --git a/Build/source/utils/asymptote/examples/circles.asy b/Build/source/utils/asymptote/examples/circles.asy
new file mode 100644
index 00000000000..69f5cf244a4
--- /dev/null
+++ b/Build/source/utils/asymptote/examples/circles.asy
@@ -0,0 +1,33 @@
+size(6cm,0);
+import math;
+
+currentpen=magenta;
+
+real r1=1;
+real r2=sqrt(7);
+real r3=4;
+pair O=0;
+
+path c1=circle(O,r1);
+draw(c1,green);
+draw(circle(O,r2),green);
+draw(circle(O,r3),green);
+
+real x=-0.6;
+real y=-0.8;
+real yD=0.3;
+pair A=(sqrt(r1^2-y^2),y);
+pair B=(-sqrt(r2^2-y^2),y);
+pair C=(x,sqrt(r3^2-x^2));
+
+pair d=A+r2*dir(B--C);
+pair D=intersectionpoint(c1,A--d);
+
+draw(A--B--C--cycle);
+draw(interp(A,D,-0.5)--interp(A,D,1.5),blue);
+
+dot("$O$",O,S,red);
+dot("$A$",A,dir(C--A,B--A),red);
+dot("$B$",B,dir(C--B,A--B),red);
+dot("$C$",C,dir(A--C,B--C),red);
+dot("$D$",D,red);
diff --git a/Build/source/utils/asymptote/examples/coag.asy b/Build/source/utils/asymptote/examples/coag.asy
new file mode 100644
index 00000000000..de976cb145b
--- /dev/null
+++ b/Build/source/utils/asymptote/examples/coag.asy
@@ -0,0 +1,16 @@
+size(0,200);
+import graph;
+
+pair z0=(0,0);
+pair m0=(0,1);
+pair tg=(1.5,0);
+pair mt=m0+tg;
+pair tf=(3,0);
+
+draw(m0--mt{dir(-70)}..{dir(0)}2tg+m0/4);
+xtick("$T_g$",tg,N);
+label("$M(t)$",mt,2NE);
+labely("$M_0$",m0);
+
+xaxis(Label("$t$",align=2S),Arrow);
+yaxis(Arrow);
diff --git a/Build/source/utils/asymptote/examples/colorplanes.asy b/Build/source/utils/asymptote/examples/colorplanes.asy
new file mode 100644
index 00000000000..16bef25b545
--- /dev/null
+++ b/Build/source/utils/asymptote/examples/colorplanes.asy
@@ -0,0 +1,22 @@
+size(6cm,0);
+import bsp;
+
+real u=2.5;
+real v=1;
+
+currentprojection=oblique;
+
+path3 y=plane((2u,0,0),(0,2v,0),(-u,-v,0));
+path3 l=rotate(90,Z)*rotate(90,Y)*y;
+path3 g=rotate(90,X)*rotate(90,Y)*y;
+
+face[] faces;
+pen[] p={red,green,blue,black};
+int[] edges={0,0,0,2};
+gouraudshade(faces.push(y),project(y),p,edges);
+gouraudshade(faces.push(l),project(l),p,edges);
+gouraudshade(faces.push(g),project(g),new pen[]{cyan,magenta,yellow,black},
+ edges);
+
+add(faces);
+
diff --git a/Build/source/utils/asymptote/examples/condor.asy b/Build/source/utils/asymptote/examples/condor.asy
new file mode 100644
index 00000000000..d109335e3bf
--- /dev/null
+++ b/Build/source/utils/asymptote/examples/condor.asy
@@ -0,0 +1,32 @@
+// Peter Luschny's Condor function
+// http://www.luschny.de/math/asy/ElCondorYElGamma.html
+
+import palette;
+import graph3;
+
+size(300,300,IgnoreAspect);
+currentprojection=orthographic(0,-1,0,center=true);
+currentlight=adobe;
+real K=7;
+
+triple condor(pair t)
+{
+ real y=t.y;
+ real x=t.x*y;
+ real e=gamma(y+1);
+ real ymx=y-x;
+ real ypx=y+x;
+ real a=gamma((ymx+1)/2);
+ real b=gamma((ymx+2)/2);
+ real c=gamma((ypx+1)/2);
+ real d=gamma((ypx+2)/2);
+ real A=cos(pi*ymx);
+ real B=cos(pi*ypx);
+ return (x,y,log(e)+log(a)*((A-1)/2)+log(b)*((-A-1)/2)+log(c)*((B-1)/2)+
+ log(d)*((-B-1)/2));
+}
+
+surface s=surface(condor,(-1,0),(1,K),64);
+s.colors(palette(s.map(zpart),Rainbow()));
+
+draw(s,meshpen=black);
diff --git a/Build/source/utils/asymptote/examples/cones.asy b/Build/source/utils/asymptote/examples/cones.asy
new file mode 100644
index 00000000000..4f28796cb92
--- /dev/null
+++ b/Build/source/utils/asymptote/examples/cones.asy
@@ -0,0 +1,16 @@
+import solids;
+
+size(200);
+currentprojection=orthographic(5,4,2);
+
+revolution upcone=cone(-Z,1,1);
+revolution downcone=cone(Z,1,-1);
+draw(surface(upcone),green);
+draw(surface(downcone),green);
+draw(upcone,5,blue,longitudinalpen=nullpen);
+draw(downcone,5,blue,longitudinalpen=nullpen);
+
+revolution cone=shift(2Y-2X)*cone(1,1);
+
+draw(surface(cone),green);
+draw(cone,5,blue);
diff --git a/Build/source/utils/asymptote/examples/conicurv.asy b/Build/source/utils/asymptote/examples/conicurv.asy
new file mode 100644
index 00000000000..cb678710c11
--- /dev/null
+++ b/Build/source/utils/asymptote/examples/conicurv.asy
@@ -0,0 +1,49 @@
+// Original name : conicurv.mp
+// Author : L. Nobre G.
+// Translators : J. Pienaar (2004) and John Bowman (2005)
+
+import three;
+texpreamble("\usepackage{bm}");
+
+size(300,0);
+
+currentprojection=perspective(10,-5,5.44);
+
+real theta=30, width=3, shortradius=2, bord=2, refsize=1, vecsize=2;
+real height=0.3, anglar=1.75, totup=3;
+real longradius=shortradius+width*Cos(theta), updiff=width*Sin(theta);
+
+triple iplow=(0,shortradius,0), iphig=(0,longradius,updiff);
+triple oplow=(-shortradius,0,0), ophig=(-longradius,0,updiff);
+triple aplow=-iplow, aphig=(0,-longradius,updiff);
+triple eplow=-oplow, ephig=(longradius,0,updiff);
+triple anglebase=(0,longradius,0), centre=interp(iplow,iphig,0.5)+(0,0,height);
+triple central=(0,0,centre.z), refo=(0,0.5*centre.y,centre.z);
+triple refx=refsize*(0,Cos(theta),Sin(theta));
+triple refy=refsize*(0,-Sin(theta),Cos(theta));
+
+draw("$\theta$",arc(iplow,iplow+0.58*(iphig-iplow),anglebase),E);
+
+draw(central,linewidth(2bp));
+draw(iplow--iphig);
+draw(oplow--ophig);
+draw(aplow--aphig);
+draw(eplow--ephig);
+draw(iphig--anglebase--aplow,dashed);
+draw(oplow--eplow,dashed);
+draw(central--centre,dashed);
+
+draw((0,0,-bord)--(0,longradius+bord,-bord)--(0,longradius+bord,totup)
+ --(0,0,totup)--cycle);
+draw(Label("$y$",1),refo--refo+refy,SW,Arrow3);
+draw(Label("$x$",1),refo--refo+refx,SE,Arrow3);
+
+draw(Label("$\vec{R}_N$",1),centre--centre+vecsize*refy,E,Arrow3);
+draw(Label("$\vec{F}_a$",1),centre--centre+vecsize*refx,N,Arrow3);
+draw(Label("$\vec{F}_c$",1),centre--centre+vecsize*Y,NE,Arrow3);
+draw(Label("$\vec{P}$",1),centre--centre-vecsize*Z,E,Arrow3);
+draw(Label("$\vec{v}$",1),centre--centre+vecsize*X,E,Arrow3);
+draw(centre,10pt+blue);
+
+draw(circle((0,0,updiff),longradius),linewidth(2bp));
+draw(circle(O,shortradius),linewidth(2bp));
diff --git a/Build/source/utils/asymptote/examples/controlsystem.asy b/Build/source/utils/asymptote/examples/controlsystem.asy
new file mode 100644
index 00000000000..0829bc90d51
--- /dev/null
+++ b/Build/source/utils/asymptote/examples/controlsystem.asy
@@ -0,0 +1,39 @@
+size(0,4cm);
+import flowchart;
+
+block delay=roundrectangle("$e^{-sT_t}$",(0.33,0));
+block system=roundrectangle("$\frac{s+3}{s^2+0.3s+1}$",(0.6,0));
+block controller=roundrectangle("$0.06\left( 1 + \frac{1}{s}\right)$",
+ (0.45,-0.25));
+block sum1=circle("",(0.15,0),mindiameter=0.3cm);
+block junction1=circle("",(0.75,0),fillpen=currentpen);
+
+draw(delay);
+draw(system);
+draw(controller);
+draw(sum1);
+draw(junction1);
+
+add(new void(picture pic, transform t) {
+ draw(pic,Label("$u$",0.5,N),path(new pair[]{t*(0,0),sum1.left(t)},
+ Horizontal),Arrow,PenMargin);
+
+ draw(pic,path(new pair[]{sum1.right(t),delay.left(t)},Horizontal),Arrow,
+ PenMargin);
+ label(pic,"-",sum1.bottom(t),ESE);
+
+ draw(pic,path(new pair[]{delay.right(t),system.left(t)},Horizontal),Arrow,
+ PenMargin);
+
+ draw(pic,path(new pair[]{system.right(t),junction1.left(t)},Horizontal),
+ PenMargin);
+
+ draw(pic,Label("$y$",0.5,N),path(new pair[]{junction1.right(t),t*(0.9,0)},
+ Horizontal),Arrow,PenMargin);
+
+ draw(pic,path(new pair[]{junction1.bottom(t),controller.right(t)},Vertical),
+ Arrow,PenMargin);
+
+ draw(pic,path(new pair[]{controller.left(t),sum1.bottom(t)},Horizontal),
+ Arrow,PenMargin);
+ });
diff --git a/Build/source/utils/asymptote/examples/cos2theta.asy b/Build/source/utils/asymptote/examples/cos2theta.asy
new file mode 100644
index 00000000000..1be0c519fb1
--- /dev/null
+++ b/Build/source/utils/asymptote/examples/cos2theta.asy
@@ -0,0 +1,15 @@
+import graph;
+size(0,100);
+
+real f(real t) {return cos(2*t);}
+
+path g=polargraph(f,0,2pi,operator ..)--cycle;
+fill(g,green+white);
+xaxis("$x$",above=true);
+yaxis("$y$",above=true);
+draw(g);
+
+dot(Label,(1,0),NE);
+dot(Label,(0,1),NE);
+
+
diff --git a/Build/source/utils/asymptote/examples/cosaddition.asy b/Build/source/utils/asymptote/examples/cosaddition.asy
new file mode 100644
index 00000000000..f6ce8de62a4
--- /dev/null
+++ b/Build/source/utils/asymptote/examples/cosaddition.asy
@@ -0,0 +1,26 @@
+size(0,200);
+import geometry;
+
+real A=130;
+real B=40;
+
+pair O=(0,0);
+pair R=(1,0);
+pair P=dir(A);
+pair Q=dir(B);
+
+draw(circle(O,1.0));
+draw(Q--O--P);
+draw(P--Q,red);
+draw(O--Q--R--cycle);
+
+draw("$A$",arc(R,O,P,0.3),blue,Arrow,PenMargin);
+draw("$B$",arc(R,O,Q,0.6),blue,Arrow,PenMargin);
+pair S=(Cos(B),0);
+draw(Q--S,blue);
+perpendicular(S,NE,blue);
+
+dot(O);
+dot("$R=(1,0)$",R);
+dot("$P=(\cos A,\sin A)$",P,dir(O--P)+W);
+dot("$Q=(\cos B,\sin B)$",Q,dir(O--Q));
diff --git a/Build/source/utils/asymptote/examples/cpkcolors.asy b/Build/source/utils/asymptote/examples/cpkcolors.asy
new file mode 100644
index 00000000000..ddc7e286d58
--- /dev/null
+++ b/Build/source/utils/asymptote/examples/cpkcolors.asy
@@ -0,0 +1,259 @@
+/*
+ * Copyright (C) 2003-2005 Miguel, Jmol Development, www.jmol.org
+ *
+ * Contact: miguel@jmol.org
+ *
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+string[] Element={
+ "Xx", // 0
+ "H", // 1
+ "He", // 2
+ "Li", // 3
+ "Be", // 4
+ "B", // 5
+ "C", // 6
+ "N", // 7
+ "O", // 8
+ "F", // 9
+ "Ne", // 10
+ "Na", // 11
+ "Mg", // 12
+ "Al", // 13
+ "Si", // 14
+ "P", // 15
+ "S", // 16
+ "Cl", // 17
+ "Ar", // 18
+ "K", // 19
+ "Ca", // 20
+ "Sc", // 21
+ "Ti", // 22
+ "V", // 23
+ "Cr", // 24
+ "Mn", // 25
+ "Fe", // 26
+ "Co", // 27
+ "Ni", // 28
+ "Cu", // 29
+ "Zn", // 30
+ "Ga", // 31
+ "Ge", // 32
+ "As", // 33
+ "Se", // 34
+ "Br", // 35
+ "Kr", // 36
+ "Rb", // 37
+ "Sr", // 38
+ "Y", // 39
+ "Zr", // 40
+ "Nb", // 41
+ "Mo", // 42
+ "Tc", // 43
+ "Ru", // 44
+ "Rh", // 45
+ "Pd", // 46
+ "Ag", // 47
+ "Cd", // 48
+ "In", // 49
+ "Sn", // 50
+ "Sb", // 51
+ "Te", // 52
+ "I", // 53
+ "Xe", // 54
+ "Cs", // 55
+ "Ba", // 56
+ "La", // 57
+ "Ce", // 58
+ "Pr", // 59
+ "Nd", // 60
+ "Pm", // 61
+ "Sm", // 62
+ "Eu", // 63
+ "Gd", // 64
+ "Tb", // 65
+ "Dy", // 66
+ "Ho", // 67
+ "Er", // 68
+ "Tm", // 69
+ "Yb", // 70
+ "Lu", // 71
+ "Hf", // 72
+ "Ta", // 73
+ "W", // 74
+ "Re", // 75
+ "Os", // 76
+ "Ir", // 77
+ "Pt", // 78
+ "Au", // 79
+ "Hg", // 80
+ "Tl", // 81
+ "Pb", // 82
+ "Bi", // 83
+ "Po", // 84
+ "At", // 85
+ "Rn", // 86
+ "Fr", // 87
+ "Ra", // 88
+ "Ac", // 89
+ "Th", // 90
+ "Pa", // 91
+ "U", // 92
+ "Np", // 93
+ "Pu", // 94
+ "Am", // 95
+ "Cm", // 96
+ "Bk", // 97
+ "Cf", // 98
+ "Es", // 99
+ "Fm", // 100
+ "Md", // 101
+ "No", // 102
+ "Lr", // 103
+ "Rf", // 104
+ "Db", // 105
+ "Sg", // 106
+ "Bh", // 107
+ "Hs", // 108
+ "Mt", // 109
+ /*
+ "Ds", // 110
+ "Uuu",// 111
+ "Uub",// 112
+ "Uut",// 113
+ "Uuq",// 114
+ "Uup",// 115
+ "Uuh",// 116
+ "Uus",// 117
+ "Uuo",// 118
+ */
+};
+
+// Default table of CPK atom colors
+// (ghemical colors with a few proposed modifications).
+string[] Hexcolor={
+ "FF1493", // Xx 0
+ "FFFFFF", // H 1
+ "D9FFFF", // He 2
+ "CC80FF", // Li 3
+ "C2FF00", // Be 4
+ "FFB5B5", // B 5
+ "909090", // C 6 - changed from ghemical
+ "3050F8", // N 7 - changed from ghemical
+ "FF0D0D", // O 8
+ "90E050", // F 9 - changed from ghemical
+ "B3E3F5", // Ne 10
+ "AB5CF2", // Na 11
+ "8AFF00", // Mg 12
+ "BFA6A6", // Al 13
+ "F0C8A0", // Si 14 - changed from ghemical
+ "FF8000", // P 15
+ "FFFF30", // S 16
+ "1FF01F", // Cl 17
+ "80D1E3", // Ar 18
+ "8F40D4", // K 19
+ "3DFF00", // Ca 20
+ "E6E6E6", // Sc 21
+ "BFC2C7", // Ti 22
+ "A6A6AB", // V 23
+ "8A99C7", // Cr 24
+ "9C7AC7", // Mn 25
+ "E06633", // Fe 26 - changed from ghemical
+ "F090A0", // Co 27 - changed from ghemical
+ "50D050", // Ni 28 - changed from ghemical
+ "C88033", // Cu 29 - changed from ghemical
+ "7D80B0", // Zn 30
+ "C28F8F", // Ga 31
+ "668F8F", // Ge 32
+ "BD80E3", // As 33
+ "FFA100", // Se 34
+ "A62929", // Br 35
+ "5CB8D1", // Kr 36
+ "702EB0", // Rb 37
+ "00FF00", // Sr 38
+ "94FFFF", // Y 39
+ "94E0E0", // Zr 40
+ "73C2C9", // Nb 41
+ "54B5B5", // Mo 42
+ "3B9E9E", // Tc 43
+ "248F8F", // Ru 44
+ "0A7D8C", // Rh 45
+ "006985", // Pd 46
+ "C0C0C0", // Ag 47 - changed from ghemical
+ "FFD98F", // Cd 48
+ "A67573", // In 49
+ "668080", // Sn 50
+ "9E63B5", // Sb 51
+ "D47A00", // Te 52
+ "940094", // I 53
+ "429EB0", // Xe 54
+ "57178F", // Cs 55
+ "00C900", // Ba 56
+ "70D4FF", // La 57
+ "FFFFC7", // Ce 58
+ "D9FFC7", // Pr 59
+ "C7FFC7", // Nd 60
+ "A3FFC7", // Pm 61
+ "8FFFC7", // Sm 62
+ "61FFC7", // Eu 63
+ "45FFC7", // Gd 64
+ "30FFC7", // Tb 65
+ "1FFFC7", // Dy 66
+ "00FF9C", // Ho 67
+ "00E675", // Er 68
+ "00D452", // Tm 69
+ "00BF38", // Yb 70
+ "00AB24", // Lu 71
+ "4DC2FF", // Hf 72
+ "4DA6FF", // Ta 73
+ "2194D6", // W 74
+ "267DAB", // Re 75
+ "266696", // Os 76
+ "175487", // Ir 77
+ "D0D0E0", // Pt 78 - changed from ghemical
+ "FFD123", // Au 79 - changed from ghemical
+ "B8B8D0", // Hg 80 - changed from ghemical
+ "A6544D", // Tl 81
+ "575961", // Pb 82
+ "9E4FB5", // Bi 83
+ "AB5C00", // Po 84
+ "754F45", // At 85
+ "428296", // Rn 86
+ "420066", // Fr 87
+ "007D00", // Ra 88
+ "70ABFA", // Ac 89
+ "00BAFF", // Th 90
+ "00A1FF", // Pa 91
+ "008FFF", // U 92
+ "0080FF", // Np 93
+ "006BFF", // Pu 94
+ "545CF2", // Am 95
+ "785CE3", // Cm 96
+ "8A4FE3", // Bk 97
+ "A136D4", // Cf 98
+ "B31FD4", // Es 99
+ "B31FBA", // Fm 100
+ "B30DA6", // Md 101
+ "BD0D87", // No 102
+ "C70066", // Lr 103
+ "CC0059", // Rf 104
+ "D1004F", // Db 105
+ "D90045", // Sg 106
+ "E00038", // Bh 107
+ "E6002E", // Hs 108
+ "EB0026" // Mt 109
+};
+
+
diff --git a/Build/source/utils/asymptote/examples/curvedlabel.asy b/Build/source/utils/asymptote/examples/curvedlabel.asy
new file mode 100644
index 00000000000..2ff4c6c34ec
--- /dev/null
+++ b/Build/source/utils/asymptote/examples/curvedlabel.asy
@@ -0,0 +1,4 @@
+size(200);
+import labelpath;
+labelpath("This is a test of curved labels in Asymptote (implemented with the {\tt PSTricks pstextpath} macro).",reverse(rotate(-90)*unitcircle));
+
diff --git a/Build/source/utils/asymptote/examples/curvedlabel3.asy b/Build/source/utils/asymptote/examples/curvedlabel3.asy
new file mode 100644
index 00000000000..5bee2342d83
--- /dev/null
+++ b/Build/source/utils/asymptote/examples/curvedlabel3.asy
@@ -0,0 +1,17 @@
+size(200);
+import labelpath3;
+
+path3 g=(1,0,0)..(0,1,1)..(-1,0,0)..(0,-1,1)..cycle;
+path3 g2=shift(-Z)*reverse(unitcircle3);
+
+string txt1="\hbox{This is a test of \emph{curved} 3D labels in
+\textbf{Asymptote} (implemented with {\tt texpath}).}";
+
+string txt2="This is a test of curved labels in Asymptote\\(implemented
+without the {\tt PSTricks pstextpath} macro).";
+
+draw(surface(g),paleblue+opacity(0.5));
+draw(labelpath(txt1,subpath(g,0,reltime(g,0.95)),angle=-90),orange);
+
+draw(g2,1bp+red);
+draw(labelpath(txt2,subpath(g2,0,3.9),angle=180,optional=rotate(-70,X)*Z));
diff --git a/Build/source/utils/asymptote/examples/cyclohexane.asy b/Build/source/utils/asymptote/examples/cyclohexane.asy
new file mode 100644
index 00000000000..d0121d8ea7e
--- /dev/null
+++ b/Build/source/utils/asymptote/examples/cyclohexane.asy
@@ -0,0 +1,73 @@
+import three;
+
+currentprojection = perspective(300,-650,500);
+
+surface carbon = scale3(70)*unitsphere; // 70 pm
+surface hydrogen = scale3(25)*unitsphere; // 25 pm
+
+real alpha = 90+aSin(1/3);
+
+real CCbond = 156; // 156 pm
+real CHbond = 110; // 110 pm
+
+triple c1 = (0,0,0);
+triple h1 = c1+CHbond*Z;
+triple c2 = rotate(alpha,c1,c1+Y)*(CCbond*Z);
+triple h2 = rotate(120,c1,c2)*h1;
+triple h3 = c2-CHbond*Z;
+triple h4 = rotate(120,c2,c1)*h3;
+
+triple c3 = rotate(120,c2,h3)*c1;
+triple h5 = c3+CHbond*Z;
+triple h6 = rotate(-120,c3,c2)*h5;
+
+triple c4 = rotate(-120,c3,h5)*c2;
+triple h7 = c4-CHbond*Z;
+triple h8 = rotate(120,c4,c3)*h7;
+
+triple c5 = rotate(120,c4,h7)*c3;
+triple h9 = c5+CHbond*Z;
+triple h10 = rotate(-120,c5,c4)*h9;
+
+triple c6 = rotate(-120,c5,h9)*c4;
+triple h11 = c6-CHbond*Z;
+triple h12 = rotate(120,c6,c5)*h11;
+
+draw(shift(c1)*carbon,black);
+draw(shift(c2)*carbon,black);
+draw(shift(c3)*carbon,black);
+draw(shift(c4)*carbon,black);
+draw(shift(c5)*carbon,black);
+draw(shift(c6)*carbon,black);
+
+
+draw(shift(h1)*hydrogen,lightgray);
+draw(shift(h2)*hydrogen,lightgray);
+draw(shift(h3)*hydrogen,lightgray);
+draw(shift(h4)*hydrogen,lightgray);
+draw(shift(h5)*hydrogen,lightgray);
+draw(shift(h6)*hydrogen,lightgray);
+draw(shift(h7)*hydrogen,lightgray);
+draw(shift(h8)*hydrogen,lightgray);
+draw(shift(h9)*hydrogen,lightgray);
+draw(shift(h10)*hydrogen,lightgray);
+draw(shift(h11)*hydrogen,lightgray);
+draw(shift(h12)*hydrogen,lightgray);
+
+
+pen thick = linewidth(10);
+
+draw(c1--c2--c3--c4--c5--c6--cycle,thick);
+
+draw(c1--h1,thick);
+draw(c1--h2,thick);
+draw(c2--h3,thick);
+draw(c2--h4,thick);
+draw(c3--h5,thick);
+draw(c3--h6,thick);
+draw(c4--h7,thick);
+draw(c4--h8,thick);
+draw(c5--h9,thick);
+draw(c5--h10,thick);
+draw(c6--h11,thick);
+draw(c6--h12,thick);
diff --git a/Build/source/utils/asymptote/examples/cylinder.asy b/Build/source/utils/asymptote/examples/cylinder.asy
new file mode 100644
index 00000000000..c574f577bbd
--- /dev/null
+++ b/Build/source/utils/asymptote/examples/cylinder.asy
@@ -0,0 +1,7 @@
+import solids;
+
+size(0,100);
+
+revolution r=cylinder(O,1,1.5,Y+Z);
+draw(surface(r),green);
+draw(r,blue);
diff --git a/Build/source/utils/asymptote/examples/delu.asy b/Build/source/utils/asymptote/examples/delu.asy
new file mode 100644
index 00000000000..7f9853eb51c
--- /dev/null
+++ b/Build/source/utils/asymptote/examples/delu.asy
@@ -0,0 +1,29 @@
+size(7cm,0);
+
+pair z1=(1,-0.25);
+pair v1=dir(45);
+pair z2=-z1;
+pair v2=0.75*dir(260);
+pair z3=(z1.x,-3);
+
+// A centered random number
+real crand() {return unitrand()-0.5;}
+
+guide g;
+pair lastz;
+for(int i=0; i < 60; ++i) {
+ pair z=0.75*lastz+(crand(),crand());
+ g=g..2.5*z;
+ lastz=z;
+}
+g=shift(0,-.5)*g..cycle;
+
+draw(g,gray(0.7));
+
+draw("$r$",z1--z2,RightSide,red,Arrows,DotMargins);
+draw(z1--z1+v1,Arrow);
+draw(z2--z2+v2,Arrow);
+draw(z3--z3+v1-v2,green,Arrow);
+
+dot("1",z1,S,blue);
+dot("2",z2,NW,blue);
diff --git a/Build/source/utils/asymptote/examples/dimension.asy b/Build/source/utils/asymptote/examples/dimension.asy
new file mode 100644
index 00000000000..1244ba84e68
--- /dev/null
+++ b/Build/source/utils/asymptote/examples/dimension.asy
@@ -0,0 +1,23 @@
+size(12cm,0);
+
+void distance(picture pic=currentpicture, pair A, pair B, Label L="", real n=0,
+ pen p=currentpen)
+{
+ real d=3mm;
+ path g=A--B;
+ transform T=shift(-n*d*unit(B-A)*I);
+ pic.add(new void(frame f, transform t) {
+ picture opic;
+ path G=T*t*g;
+ draw(opic,Label(L,Center,UnFill(1)),G,p,Arrows(NoFill),Bars,PenMargins);
+ add(f,opic.fit());
+ });
+ pic.addBox(min(g),max(g),T*min(p),T*max(p));
+}
+
+pair A=(0,0), B=(3,3);
+
+dot(A);
+dot(B);
+
+distance(A,B,"$\ell$",1);
diff --git a/Build/source/utils/asymptote/examples/dragon.asy b/Build/source/utils/asymptote/examples/dragon.asy
new file mode 100644
index 00000000000..08fcb61f5c0
--- /dev/null
+++ b/Build/source/utils/asymptote/examples/dragon.asy
@@ -0,0 +1,66 @@
+pair crease(pair z1, pair z2, bool left)
+{
+ pair dz = z2 - z1;
+
+ if (left)
+ return z1 + dz * (0.5, 0.5);
+ else
+ return z1 + dz * (0.5, -0.5);
+}
+
+pair[] fold(pair[] oldz)
+{
+ int n = oldz.length;
+ pair[] newz = new pair[2n-1];
+
+ for (int i = 0; i < n-1; ++i)
+ {
+ newz[2i] = oldz[i];
+ newz[2i+1] = crease(oldz[i], oldz[i+1], i%2==0);
+ }
+
+ newz[2(n-1)] = oldz[n-1];
+
+ return newz;
+}
+
+pair[] dragon(int n, pair[] base={})
+{
+ if (base.length == 0)
+ if (n%2 == 0)
+ base = new pair[] {(0,0), (1,1) };
+ else
+ base = new pair[] {(0,0), (1,0) };
+
+ pair[] z = base;
+
+ for (int i = 1; i < n; ++i)
+ z = fold(z);
+
+ return z;
+}
+
+void drawtris(pair[] z, pen p = currentpen)
+{
+ int n = z.length;
+
+ for (int i = 0; i < n-2; i+=2)
+ fill(z[i]--z[i+1]--z[i+2]--cycle, p);
+}
+
+void drawtris(pair[] z, pen p1, pen p2)
+{
+ int n = z.length;
+
+ for (int i = 0; i < n-2; i+=2)
+ fill(z[i]--z[i+1]--z[i+2]--cycle, 2i < n-1 ? p1 : p2);
+}
+
+size(500,0);
+
+int n = 10;
+
+drawtris(dragon(n, new pair[] {(0,0), (1,0)}), black);
+drawtris(dragon(n, new pair[] {(0,0), (0,-1)}), blue);
+drawtris(dragon(n, new pair[] {(0,0), (-1,0)}), red);
+drawtris(dragon(n, new pair[] {(0,0), (0,1)}), green);
diff --git a/Build/source/utils/asymptote/examples/electromagnetic.asy b/Build/source/utils/asymptote/examples/electromagnetic.asy
new file mode 100644
index 00000000000..058c7c5c574
--- /dev/null
+++ b/Build/source/utils/asymptote/examples/electromagnetic.asy
@@ -0,0 +1,47 @@
+import graph;
+import palette;
+texpreamble("\usepackage[amssymb,thinqspace,thinspace]{SIunits}");
+
+size(800,200);
+
+real c=3e8;
+real nm=1e-9;
+real freq(real lambda) {return c/(lambda*nm);}
+real lambda(real f) {return c/(f*nm);}
+
+real fmin=10;
+real fmax=1e23;
+
+scale(Log(true),Linear(true));
+xlimits(fmin,fmax);
+ylimits(0,1);
+
+real uv=freq(400);
+real ir=freq(700);
+
+bounds visible=bounds(Scale(uv).x,Scale(ir).x);
+palette(visible,uv,ir+(0,2),Bottom,Rainbow(),invisible);
+
+xaxis(Label("\hertz",1),Bottom,RightTicks,above=true);
+
+real log10Left(real x) {return -log10(x);}
+real pow10Left(real x) {return pow10(-x);}
+
+scaleT LogLeft=scaleT(log10Left,pow10Left,logarithmic=true);
+
+picture q=secondaryX(new void(picture p) {
+ scale(p,LogLeft,Linear);
+ xlimits(p,lambda(fmax),lambda(fmin));
+ ylimits(p,0,1);
+ xaxis(p,Label("\nano\metre",1),Top,LeftTicks(DefaultLogFormat,n=10));
+ });
+
+add(q,above=true);
+
+margin margin=PenMargin(0,0);
+draw("radio",Scale((10,1))--Scale((5e12,1)),N,Arrow);
+draw("infrared",Scale((1e12,1.5))--Scale(shift(0,1.5)*ir),Arrows,margin);
+draw("UV",Scale(shift(0,1.5)*uv)--Scale((1e17,1.5)),Arrows,margin);
+draw("x-rays",Scale((1e16,1))--Scale((1e21,1)),N,Arrows);
+draw("$\gamma$-rays",Scale((fmax,1.5))--Scale((2e18,1.5)),Arrow);
+
diff --git a/Build/source/utils/asymptote/examples/elevation.asy b/Build/source/utils/asymptote/examples/elevation.asy
new file mode 100644
index 00000000000..4e4579d98a9
--- /dev/null
+++ b/Build/source/utils/asymptote/examples/elevation.asy
@@ -0,0 +1,15 @@
+import graph3;
+import grid3;
+import palette;
+
+currentprojection=orthographic(0.8,1,1);
+
+size(400,300,IgnoreAspect);
+
+real f(pair z) {return cos(2*pi*z.x)*sin(2*pi*z.y);}
+
+surface s=surface(f,(-1/2,-1/2),(1/2,1/2),50,Spline);
+
+draw(s,mean(palette(s.map(zpart),Rainbow())),black);
+
+grid3(XYZgrid);
diff --git a/Build/source/utils/asymptote/examples/epix.asy b/Build/source/utils/asymptote/examples/epix.asy
new file mode 100644
index 00000000000..df0cd3d336c
--- /dev/null
+++ b/Build/source/utils/asymptote/examples/epix.asy
@@ -0,0 +1,14 @@
+import graph3;
+
+size(200,200,IgnoreAspect);
+
+currentprojection=perspective(4,2,3);
+
+real f(pair z) {return z.y^3/2-3z.x^2*z.y;}
+
+draw(surface(f,(-1,-1),(1,1),nx=10,Spline),green);
+draw(Label("$y$",1),(0,0,0)--(0,2,0),red,Arrow3);
+
+draw(Label("$x$",1),(0,0,0)--(2,0,0),red,Arrow3);
+draw(Label("$z$",1),(0,0,0)--(0,0,2.5),red,Arrow3);
+label("$z=\frac{1}{2}y^3-3x^2y$",(1,1,1),NE);
diff --git a/Build/source/utils/asymptote/examples/equilateral.asy b/Build/source/utils/asymptote/examples/equilateral.asy
new file mode 100644
index 00000000000..d68e0d02225
--- /dev/null
+++ b/Build/source/utils/asymptote/examples/equilateral.asy
@@ -0,0 +1,12 @@
+size(10cm,0);
+import math;
+
+pair b=(0,0), c=(1,0);
+pair a=extension(b,b+dir(60),c,c+dir(120));
+pair d=extension(b,b+dir(30),a,a+dir(270));
+
+draw(a--b--c--a--d--b^^d--c);
+label("$A$",a,N);
+label("$B$",b,W);
+label("$C$",c,E);
+label("$D$",d,S);
diff --git a/Build/source/utils/asymptote/examples/equilchord.asy b/Build/source/utils/asymptote/examples/equilchord.asy
new file mode 100644
index 00000000000..ae3665b1a66
--- /dev/null
+++ b/Build/source/utils/asymptote/examples/equilchord.asy
@@ -0,0 +1,21 @@
+import graph3;
+
+size(0,150);
+currentprojection=perspective(5,-4,6);
+currentlight=(-1,-1,2);
+real t=0.5;
+
+real F(pair z) {
+ return (z.x^2+z.y^2 <= 1) ? sqrt(3)*(sqrt(1-z.x^2)-abs(z.y)) : 0;
+}
+
+real a=1.5;
+draw((-a,-a,0)--(-a,a,0)--(a,a,0)--(a,-a,0)--cycle,lightgray);
+
+xaxis3(Label("$x$",1),red,Arrow3);
+yaxis3(Label("$y$",1),red,Arrow3);
+draw(circle((0,0,0),1),dashed);
+draw(surface(F,(-1,-1),(t,1),20,monotonic),green,black);
+real y=sqrt(1-t^2);
+draw((t,y,0)--(t,-y,0)--(t,0,sqrt(3)*y)--cycle,blue);
+label("$1$",(1,0,0),-Y+X);
diff --git a/Build/source/utils/asymptote/examples/extrudedcontour.asy b/Build/source/utils/asymptote/examples/extrudedcontour.asy
new file mode 100644
index 00000000000..b5ad885a350
--- /dev/null
+++ b/Build/source/utils/asymptote/examples/extrudedcontour.asy
@@ -0,0 +1,22 @@
+import contour;
+import palette;
+import graph3;
+currentprojection=orthographic(25,10,10);
+size(0,12cm);
+real a=3;
+real b=4;
+real f(pair z) {return (z.x+z.y)/(2+cos(z.x)*sin(z.y));}
+guide[][] g=contour(f,(-10,-10),(10,10),new real[]{8},150);
+
+for(guide p:g[0]){
+ draw(extrude(p,8Z),palered);
+ draw(path3(p),red+2pt);
+}
+
+draw(lift(f,g),red+2pt);
+
+surface s=surface(f,(0,0),(10,10),20,Spline);
+s.colors(palette(s.map(zpart),Rainbow()+opacity(0.5)));
+draw(s);
+axes3("$x$","$y$","$z$",Arrow3);
+
diff --git a/Build/source/utils/asymptote/examples/fano.asy b/Build/source/utils/asymptote/examples/fano.asy
new file mode 100644
index 00000000000..12286d7006e
--- /dev/null
+++ b/Build/source/utils/asymptote/examples/fano.asy
@@ -0,0 +1,28 @@
+import math;
+
+size(100,0);
+
+pair z4=(0,0);
+pair z7=(2,0);
+pair z1=point(rotate(60)*(z4--z7),1);
+
+pair z5=interp(z4,z7,0.5);
+pair z3=interp(z7,z1,0.5);
+pair z2=interp(z1,z4,0.5);
+pair z6=extension(z4,z3,z7,z2);
+
+draw(z4--z7--z1--cycle);
+draw(z4--z3);
+draw(z7--z2);
+draw(z1--z5);
+draw(circle(z6,abs(z3-z6)));
+
+label("1",z1,dir(z5--z1));
+label("2",z2,dir(z7--z2));
+label("3",z3,dir(z4--z3));
+label("4",z4,dir(z3--z4));
+label("5",z5,dir(z1--z5));
+label("6",z6,2.5E+0.1*N);
+label("7",z7,dir(z2--z7));
+
+
diff --git a/Build/source/utils/asymptote/examples/fermi.asy b/Build/source/utils/asymptote/examples/fermi.asy
new file mode 100644
index 00000000000..c74da952ab2
--- /dev/null
+++ b/Build/source/utils/asymptote/examples/fermi.asy
@@ -0,0 +1,40 @@
+import feynman;
+
+// set default line width to 0.8bp
+currentpen = linewidth(0.8);
+
+// scale all other defaults of the feynman module appropriately
+fmdefaults();
+
+// disable middle arrows
+currentarrow = None;
+
+// define vertex and external points
+
+pair xu = (-40,+45);
+pair xl = (-40,-45);
+pair yu = (+40,+45);
+pair yl = (+40,-45);
+
+pair zu = ( 0,+ 5);
+pair zl = ( 0,- 5);
+
+// define mid points
+
+pair mxu = (xu+zu)/2;
+pair mxl = (xl+zl)/2;
+pair myu = (yu+zu)/2;
+pair myl = (yl+zl)/2;
+
+// draw fermion lines
+drawFermion(xu--zu--yu);
+drawFermion(xl--zl--yl);
+
+// draw vertices
+drawVertexOX(zu);
+drawVertexOX(zl);
+
+// draw gluon. Note that the underlying fermion line is blotted out.
+drawGluon(arc((0,0),mxu,myl,CW));
+
+// shipout
diff --git a/Build/source/utils/asymptote/examples/filesurface.asy b/Build/source/utils/asymptote/examples/filesurface.asy
new file mode 100644
index 00000000000..42275715a0b
--- /dev/null
+++ b/Build/source/utils/asymptote/examples/filesurface.asy
@@ -0,0 +1,34 @@
+import graph3;
+import palette;
+
+size3(200,IgnoreAspect);
+
+file in=line(input("filesurface.dat"));
+real[] x=in;
+real[] y=in;
+
+real[][] f=dimension(in,0,0);
+
+triple f(pair t) {
+ int i=round(t.x);
+ int j=round(t.y);
+ return (x[i],y[j],f[i][j]);
+}
+
+surface s=surface(f,(0,0),(x.length-1,y.length-1),x.length-1,y.length-1);
+real[] level=uniform(min(f)*(1-sqrtEpsilon),max(f)*(1+sqrtEpsilon),4);
+
+s.colors(palette(s.map(new real(triple v) {return find(level >= v.z);}),
+ Rainbow()));
+
+draw(s,meshpen=thick());
+
+triple m=currentpicture.userMin;
+triple M=currentpicture.userMax;
+triple target=0.5*(m+M);
+currentprojection=perspective(camera=target+realmult(dir(68,225),M-m),
+ target=target);
+
+xaxis3("$x$",Bounds(),InTicks);
+yaxis3("$y$",Bounds(),InTicks(Step=1,step=0.1));
+zaxis3("$z$",Bounds(),InTicks);
diff --git a/Build/source/utils/asymptote/examples/filesurface.dat b/Build/source/utils/asymptote/examples/filesurface.dat
new file mode 100644
index 00000000000..16d5966f6be
--- /dev/null
+++ b/Build/source/utils/asymptote/examples/filesurface.dat
@@ -0,0 +1,12 @@
+1 12 24 36 60 84 120 180 240 360
+2005 2005.083333 2005.166667 2005.25 2005.333333 2005.416667 2005.5 2005.583333 2005.666667 2005.75 2005.833333 2005.916667 2006 2006.083333 2006.166667 2006.25 2006.333333 2006.416667 2006.5 2006.583333 2006.666667 2006.75 2006.833333 2006.916667 2007 2007.083333 2007.166667 2007.25 2007.333333 2007.416667 2007.5 2007.583333 2007.666667 2007.75 2007.833333 2007.916667 2008 2008.083333 2008.166667 2008.25 2008.333333 2008.416667 2008.5 2008.583333 2008.666667 2008.75 2008.833333 2008.916667
+2.111 2.1039 2.103 2.1047 2.1041 2.1039 2.1064 2.1126 2.1152 2.1209 2.2225 2.4112 2.3885 2.4586 2.6333 2.6489 2.6926 2.8691 2.9389 3.0941 3.1572 3.3501 3.4214 3.64 3.6159 3.6511 3.8439 3.859 3.9194 4.0982 4.105 4.3081 4.4339 4.2355 4.216 4.7114 4.1973 4.1821 4.3046 4.3691 4.3874 4.4724 4.4716 4.4875 4.6599 4.8313 3.8433 2.9929
+2.223809524 2.228 2.246190476 2.165238095 2.092727273 1.997272727 2.07185 2.14 2.128636364 2.327619048 2.577272727 2.67 2.717727273 2.793 2.978695652 3.094210526 3.175 3.271363636 3.415238095 3.489565217 3.573333333 3.664090909 3.723636364 3.773157895 3.914090909 3.9605 3.982727273 4.132105263 4.254545455 4.398095238 4.44 4.228695652 4.088 4.09 4.044090909 4.0855 3.870909091 3.631904762 3.711052632 3.955909091 4.141428571 4.562380952 4.575217391 4.36952381 4.210909091 2.93173913 2.3795 2.007727273
+2.431904762 2.4595 2.517142857 2.367619048 2.237272727 2.077727273 2.18235 2.253913043 2.222727273 2.484761905 2.743636364 2.804285714 2.862272727 2.968 3.192173913 3.343157895 3.381818182 3.462727273 3.574285714 3.575652174 3.602380952 3.657272727 3.677727273 3.744210526 3.926818182 3.954 3.922272727 4.105263158 4.255454545 4.464285714 4.475 4.183478261 4.0595 4.090434783 3.898636364 3.9975 3.68 3.334761905 3.402105263 3.781818182 4.07047619 4.624761905 4.542608696 4.178095238 4.008636364 3.151304348 2.641 2.375
+2.638095238 2.6685 2.735714286 2.562380952 2.416818182 2.241363636 2.33035 2.400869565 2.340454545 2.60952381 2.865454545 2.895238095 2.949545455 3.0775 3.297826087 3.477368421 3.521363636 3.589545455 3.685714286 3.640434783 3.614761905 3.674545455 3.668636364 3.742631579 3.938636364 3.9625 3.91 4.106842105 4.258636364 4.496666667 4.496818182 4.210869565 4.0975 4.138695652 3.933181818 4.027 3.719090909 3.413809524 3.434210526 3.818636364 4.071428571 4.622380952 4.56826087 4.157619048 3.993181818 3.358695652 2.8285 2.594090909
+2.996190476 3.015 3.124761905 2.920952381 2.753181818 2.581818182 2.6606 2.710869565 2.595 2.829047619 3.082272727 3.056190476 3.080909091 3.2445 3.45173913 3.664736842 3.703181818 3.74 3.82047619 3.726956522 3.655714286 3.712727273 3.669090909 3.753157895 3.970454545 4.0055 3.914090909 4.126315789 4.273181818 4.538095238 4.537727273 4.25826087 4.1655 4.210869565 3.982727273 4.1085 3.829545455 3.600952381 3.591578947 3.941363636 4.137619048 4.65952381 4.622173913 4.201428571 4.126363636 3.774782609 3.2075 2.983181818
+3.265714286 3.2665 3.405238095 3.21 3.04 2.87 2.9277 2.959565217 2.819545455 3.021428571 3.238636364 3.144761905 3.143636364 3.3225 3.536086957 3.798421053 3.85 3.867727273 3.91047619 3.803043478 3.706666667 3.757727273 3.700454545 3.775263158 4.003181818 4.037368421 3.938181818 4.156315789 4.288636364 4.566190476 4.546363636 4.31173913 4.23 4.27 4.076818182 4.185 3.949545455 3.793333333 3.730526316 4.043636364 4.219047619 4.636190476 4.62173913 4.258095238 4.190454545 3.967826087 3.53 3.192272727
+3.593809524 3.5845 3.745238095 3.543333333 3.381363636 3.209545455 3.249 3.282173913 3.122272727 3.285714286 3.488181818 3.380952381 3.344545455 3.497 3.674347826 3.935789474 4.004090909 4.004545455 4.029047619 3.906956522 3.778095238 3.817272727 3.75 3.811052632 4.055909091 4.091 3.99 4.203157895 4.330454545 4.614285714 4.590454545 4.393913043 4.344 4.397391304 4.234545455 4.346 4.165 4.105238095 4.044210526 4.252727273 4.398571429 4.718571429 4.705217391 4.407142857 4.379090909 4.255652174 3.998 3.514545455
+3.78952381 3.7435 3.9255 3.75 3.582272727 3.451363636 3.50775 3.513913043 3.359545455 3.494761905 3.665909091 3.551428571 3.504545455 3.6535 3.812608696 4.098421053 4.167272727 4.175909091 4.186666667 4.056086957 3.908571429 3.916363636 3.824545455 3.882105263 4.12 4.162 4.089090909 4.306315789 4.423181818 4.699047619 4.661818182 4.504782609 4.4985 4.519565217 4.402272727 4.5115 4.382727273 4.366666667 4.336842105 4.509545455 4.613809524 4.861428571 4.877391304 4.636666667 4.659545455 4.482173913 4.2535 3.744545455
+3.99 3.9085 4.098571429 3.944285714 3.771363636 3.609090909 3.6536 3.640869565 3.488181818 3.604761905 3.755454545 3.634285714 3.565909091 3.7165 3.866521739 4.151052632 4.235454545 4.235909091 4.249047619 4.116086957 3.961904762 3.953333333 3.855714286 3.92 4.153636364 4.1985 4.139090909 4.365789474 4.471818182 4.747142857 4.695454545 4.55 4.572 4.590434783 4.500909091 4.602 4.504090909 4.513809524 4.521052632 4.656818182 4.733809524 4.899047619 4.935652174 4.746190476 4.776818182 4.598695652 4.4835 3.900454545
+4.137142857 4.0305 4.213333333 4.08 3.902727273 3.739090909 3.774285714 3.757391304 3.598181818 3.706190476 3.842272727 3.712 3.629545455 3.771 3.919565217 4.231111111 4.295909091 4.306818182 4.31 4.170434783 4.000952381 3.99 3.881818182 3.943684211 4.176818182 4.2195 4.163636364 4.387368421 4.480454545 4.758095238 4.710454545 4.559565217 4.595 4.612173913 4.544090909 4.64 4.57 4.58 4.614736842 4.702727273 4.768571429 4.884761905 4.905652174 4.741904762 4.775454545 4.496521739 4.3585 3.738636364
diff --git a/Build/source/utils/asymptote/examples/fillcontour.asy b/Build/source/utils/asymptote/examples/fillcontour.asy
new file mode 100644
index 00000000000..1b93e002fff
--- /dev/null
+++ b/Build/source/utils/asymptote/examples/fillcontour.asy
@@ -0,0 +1,29 @@
+import graph;
+import palette;
+import contour;
+
+size(12cm,IgnoreAspect);
+
+pair a=(pi/2,0);
+pair b=(1.5*pi+epsilon,2pi);
+
+real f(real x, real y) {return cos(x)*sin(y);}
+
+int N=100;
+int Divs=10;
+
+defaultpen(1bp);
+
+bounds range=bounds(-1,1);
+
+real[] Cvals=uniform(range.min,range.max,Divs);
+guide[][] g=contour(f,a,b,Cvals,N,operator --);
+
+pen[] Palette=quantize(Rainbow(),Divs);
+
+pen[][] interior=interior(g,extend(Palette,grey,black));
+fill(g,interior);
+draw(g);
+
+palette("$f(x,y)$",range,point(SE)+(0.5,0),point(NE)+(1,0),Right,Palette,
+ PaletteTicks("$%+#0.1f$",N=Divs));
diff --git a/Build/source/utils/asymptote/examples/fin.asy b/Build/source/utils/asymptote/examples/fin.asy
new file mode 100644
index 00000000000..8fe88f3dc0e
--- /dev/null
+++ b/Build/source/utils/asymptote/examples/fin.asy
@@ -0,0 +1,152 @@
+import three;
+import palette;
+
+int N = 26;
+real[] C = array(N,0);
+real[][] A = new real[N][N];
+for(int i = 0; i < N; ++i)
+ for(int j = 0; j < N; ++j)
+ A[i][j] = 0;
+
+real Tb = 100; // deg C
+real h = 240; // 240 W/m^2 K
+real k = 240; // W/m K
+real Tinf = 20; // deg C
+real L = 12; // cm
+real t = 2; // cm
+
+real delta = 0.01; // 1 cm = 0.01 m
+
+// (1,2)-(2,2)-(3,2)-...-(13,2)
+// | | | |
+// (1,1)-(2,1)-(3,1)-...-(13,1)
+//
+// |
+// \ /
+// V
+//
+// 13-14-15-...-24-25
+// | | | ... | |
+// 0- 1- 2-...-11-12
+
+// but, note zero-based array indexing, so counting starts at 0
+int indexof(int m, int n)
+{
+ return 13(n-1)+m-1;
+}
+
+int i = 0;
+
+// fixed temperature bottom left
+A[i][indexof(1,1)] = 1; C[i] = Tb;
+++i;
+// fixed temperature middle left
+A[i][indexof(1,2)] = 1; C[i] = Tb;
+++i;
+
+// interior nodes
+for(int m = 2; m<13; ++m)
+{
+ A[i][indexof(m,2)] = -4;
+ A[i][indexof(m-1,2)] = A[i][indexof(m+1,2)] = 1;
+ A[i][indexof(m,1)] = 2;
+ C[i] = 0;
+ ++i;
+}
+
+// convective bottom side nodes
+for(int m = 2; m<13; ++m)
+{
+ A[i][indexof(m,1)] = -(2+h*delta/k);
+ A[i][indexof(m-1,1)] = A[i][indexof(m+1,1)] = 0.5;
+ A[i][indexof(m,2)] = 1;
+ C[i] = -h*delta*Tinf/k;
+ ++i;
+}
+
+// convective bottom right corner node
+A[i][indexof(13,2)] = A[i][indexof(12,1)] = 0.5;
+A[i][indexof(13,1)] = -(1+h*delta/k);
+C[i] = -h*delta*Tinf/k;
+++i;
+
+// convective middle right side node
+A[i][indexof(13,2)] = -(2+h*delta/k);
+A[i][indexof(13,1)] = 1;
+A[i][indexof(12,2)] = 1;
+C[i] = -h*delta*Tinf/k;
+++i;
+
+real[] T = solve(A,C);
+
+pen[] Palette = Gradient(256,blue,cyan,yellow,orange,red);
+
+real[][] T = {T[0:13],T[13:26],T[0:13]};
+T = transpose(T);
+
+size3(15cm);
+real w = 10;
+real h = 5;
+currentprojection = orthographic(2*(L,h,w),Y);
+draw((L,t,0)--(L,0,0)--(L,0,w)--(0,0,w)--(0,-h,w));
+draw((0,t,w)--(0,t+h,w)--(0,t+h,0)--(0,t,0));
+draw((L,0,w)--(L,t,w)--(0,t,w)--(0,t,0)--(L,t,0)--(L,t,w));
+
+real wo2 = 0.5*w;
+draw((0,0,wo2)--(0,t,wo2)--(L,t,wo2)--(L,0,wo2)--cycle);
+
+// centre points
+surface square = surface(shift(-0.5,-0.5,wo2)*unitsquare3);
+surface bottomsquare = surface(shift(-0.5,-0.5,wo2)*scale(1,0.5,1)*unitsquare3);
+surface topsquare = surface(shift(-0.5,0,wo2)*scale(1,0.5,1)*unitsquare3);
+surface leftsquare = surface(shift(-0.5,-0.5,wo2)*scale(0.5,1,1)*unitsquare3);
+surface rightsquare = surface(shift(0,-0.5,wo2)*scale(0.5,1,1)*unitsquare3);
+surface NEcorner = surface(shift(0,0,wo2)*scale(0.5,0.5,1)*unitsquare3);
+surface SEcorner = surface(shift(0,-0.5,wo2)*scale(0.5,0.5,1)*unitsquare3);
+surface SWcorner = surface(shift(-0.5,-0.5,wo2)*scale(0.5,0.5,1)*unitsquare3);
+surface NWcorner = surface(shift(-0.5,0,wo2)*scale(0.5,0.5,1)*unitsquare3);
+
+material lookupColour(int m,int n)
+{
+ int index = round(Palette.length*(T[m-1][n-1]-60)/(100-60));
+ if(index >= Palette.length) index = Palette.length-1;
+ return emissive(Palette[index]);
+}
+
+draw(shift(0,1,0)*rightsquare,lookupColour(1,2));
+for(int i = 2; i < 13; ++i)
+{
+ draw(shift(i-1,1,0)*square,lookupColour(i,2));
+}
+draw(shift(12,1,0)*leftsquare,lookupColour(13,2));
+
+draw(shift(0,2,0)*SEcorner,lookupColour(1,3));
+draw(shift(0,0,0)*NEcorner,lookupColour(1,1));
+for(int i = 2; i < 13; ++i)
+{
+ draw(shift(i-1,0,0)*topsquare,lookupColour(i,1));
+ draw(shift(i-1,2,0)*bottomsquare,lookupColour(i,3));
+}
+draw(shift(12,2,0)*SWcorner,lookupColour(13,3));
+draw(shift(12,0,0)*NWcorner,lookupColour(13,1));
+
+// annotations
+draw("$x$",(0,-h/2,w)--(L/4,-h/2,w),Y,Arrow3(HookHead2(normal=Z)),BeginBar3(Y));
+draw("$y$",(0,0,1.05*w)--(0,2t,1.05*w),Z,Arrow3(HookHead2(normal=X)),
+ BeginBar3(Z));
+draw("$z$",(L,-h/2,0)--(L,-h/2,w/4),Y,Arrow3(HookHead2(normal=X)),BeginBar3(Y));
+
+draw("$L$",(0,-h/4,w)--(L,-h/4,w),-Y,Arrows3(HookHead2(normal=Z)),
+ Bars3(Y),PenMargins2);
+draw("$w$",(L,-h/4,0)--(L,-h/4,w),-Y,Arrows3(HookHead2(normal=X)),
+ Bars3(Y),PenMargins2);
+draw("$t$",(1.05*L,0,0)--(1.05*L,t,0),-2Z,Arrows3(HookHead2(normal=Z)),
+ Bars3(X),PenMargins2);
+
+label(ZY()*"$T_b$",(0,t+h/2,wo2));
+
+label("$h$,$T_\infty$",(L/2,t+h/2,0),Y);
+path3 air = (L/2,t+h/3,w/3.5)--(1.5*L/2,t+2*h/3,w/8);
+draw(air,EndArrow3(TeXHead2));
+draw(shift(0.5,0,0)*air,EndArrow3(TeXHead2));
+draw(shift(1.0,0,0)*air,EndArrow3(TeXHead2));
diff --git a/Build/source/utils/asymptote/examples/fjortoft.asy b/Build/source/utils/asymptote/examples/fjortoft.asy
new file mode 100644
index 00000000000..0ef81ca2c09
--- /dev/null
+++ b/Build/source/utils/asymptote/examples/fjortoft.asy
@@ -0,0 +1,27 @@
+size(15cm,0);
+
+pair d=(1.5,1);
+real s=d.x+1;
+
+picture box(string s) {
+ picture pic;
+ draw(pic,box(0,d));
+ label(pic,s,d/2);
+ return pic;
+}
+
+add(box("$k_1$"));
+add(shift(s)*box("$k_2$"));
+add(shift(s)^2*box("$k_3$"));
+
+path g=(d.x,d.y/2)--(s,d.y/2);
+path G=(d.x/2,-(s-d.x))--(d.x/2,0);
+
+draw(Label(baseline("$\ldots$")),shift(-s)*g,BeginArrow,BeginPenMargin);
+draw(Label("$Z_1$"),g,BeginArrow,BeginPenMargin);
+draw(Label("$E_1$",LeftSide),g,Blank);
+draw(Label("$Z_3$"),shift(s)*g,Arrow,PenMargin);
+draw(Label("$E_3$",LeftSide),shift(s)*g,Blank);
+draw(Label("$Z_2$"),shift(s)*G,Arrow,PenMargin);
+draw(Label("$E_2$",LeftSide),shift(s)*G,Blank);
+draw(Label(baseline("$\ldots$")),shift(s)^2*g,Arrow,PenMargin);
diff --git a/Build/source/utils/asymptote/examples/floatingdisk.asy b/Build/source/utils/asymptote/examples/floatingdisk.asy
new file mode 100644
index 00000000000..2e99ec9c2c1
--- /dev/null
+++ b/Build/source/utils/asymptote/examples/floatingdisk.asy
@@ -0,0 +1,24 @@
+import trembling;
+settings.outformat="pdf";
+size(6cm,0);
+
+real R=1/5;
+real h=0.5;
+real d=1/12;
+real l=.7;
+
+pair pA=(-l,0);
+pair pB=(l,0);
+
+path waterline=tremble(addnodes(pA..pB,1),angle=10,frequency=0.1,random=50);
+path disk=shift(0,-d)*(scale(R)*unitcircle);
+path water=waterline--(l,-h)--(-l,-h)--(-l,0)--cycle;
+path container=(l,1/7)--(l,-h)--(-l,-h)--(-l,1/7);
+
+filldraw(disk,red,linewidth(.3));
+fill(water,mediumgrey+opacity(0.5));
+draw(waterline);
+
+draw(container,linewidth(1.5));
+
+shipout(bbox(2mm,Fill(white)));
diff --git a/Build/source/utils/asymptote/examples/floor.asy b/Build/source/utils/asymptote/examples/floor.asy
new file mode 100644
index 00000000000..96e71812c01
--- /dev/null
+++ b/Build/source/utils/asymptote/examples/floor.asy
@@ -0,0 +1,28 @@
+import graph;
+unitsize(1cm);
+
+real Floor(real x) {return floor(x);}
+
+pair[] Close;
+pair[] Open;
+
+bool3 branch(real x) {
+ static real lasty;
+ static bool first=true;
+ real y=floor(x);
+ bool samebranch=first || lasty == y;
+ first=false;
+ if(samebranch) lasty=x;
+ else {
+ Close.push((x,lasty));
+ Open.push((x,y));
+ }
+ lasty=y;
+ return samebranch ? true : default;
+};
+
+draw(graph(Floor,-5.5,5.5,500,branch));
+axes("$x$","$\lfloor x\rfloor$",red);
+
+dot(Close);
+dot(Open,UnFill);
diff --git a/Build/source/utils/asymptote/examples/fractaltree.asy b/Build/source/utils/asymptote/examples/fractaltree.asy
new file mode 100644
index 00000000000..c9775ec69d7
--- /dev/null
+++ b/Build/source/utils/asymptote/examples/fractaltree.asy
@@ -0,0 +1,27 @@
+size(200);
+
+path ltrans(path p,int d)
+{
+ path a=rotate(65)*scale(0.4)*p;
+ return shift(point(p,(1/d)*length(p))-point(a,0))*a;
+}
+path rtrans(path p, int d)
+{
+ path a=reflect(point(p,0),point(p,length(p)))*rotate(65)*scale(0.35)*p;
+ return shift(point(p,(1/d)*length(p))-point(a,0))*a;
+}
+
+void drawtree(int depth, path branch)
+{
+ if(depth == 0) return;
+ real breakp=(1/depth)*length(branch);
+ draw(subpath(branch,0,breakp),deepgreen);
+ drawtree(depth-1,subpath(branch,breakp,length(branch)));
+ drawtree(depth-1,ltrans(branch,depth));
+ drawtree(depth-1,rtrans(branch,depth));
+ return;
+}
+
+path start=(0,0)..controls (-1/10,1/3) and (-1/20,2/3)..(1/20,1);
+drawtree(6,start);
+
diff --git a/Build/source/utils/asymptote/examples/functionshading.asy b/Build/source/utils/asymptote/examples/functionshading.asy
new file mode 100644
index 00000000000..7cdeb6f4bf4
--- /dev/null
+++ b/Build/source/utils/asymptote/examples/functionshading.asy
@@ -0,0 +1,31 @@
+size(200);
+
+settings.tex="pdflatex";
+
+// PostScript Calculator routine to convert from [0,1]x[0,1] to RG:
+string redgreen="0";
+
+// PostScript Calculator routine to convert from [0,1]x[0,1] to HS to RGB:
+// (http://www.texample.net/tikz/examples/hsv-shading):
+string hsv="0.5 sub exch 0.5 sub exch
+2 copy 2 copy 0 eq exch 0 eq and { pop pop 0.0 } {atan 360.0 div}
+ifelse dup 360 eq { pop 0.0 }{} ifelse 3 1 roll dup mul exch dup mul add
+sqrt 2.5 mul 0.25 sub 1 1 index 1.0
+eq { 3 1 roll pop pop dup dup } { 3 -1 roll 6.0 mul dup 4 1 roll floor dup
+5 1 roll 3 index sub neg 1.0 3 index sub 2 index mul 6 1 roll dup 3 index
+mul neg 1.0 add 2 index mul 7 1 roll neg 1.0 add 2 index mul neg 1.0 add 1
+index mul 7 2 roll pop pop dup 0 eq { pop exch pop } { dup 1 eq { pop exch
+4 1 roll exch pop } { dup 2 eq { pop 4 1 roll pop } { dup 3 eq { pop exch 4
+2 roll pop } { dup 4 eq { pop exch pop 3 -1 roll } { pop 3 1 roll exch pop
+} ifelse } ifelse } ifelse } ifelse } ifelse } ifelse cvr 3 1 roll cvr 3 1
+roll cvr 3 1 roll";
+
+path p=unitcircle;
+functionshade(p,rgb(zerowinding),redgreen);
+layer();
+draw(p);
+
+path g=shift(2*dir(-45))*p;
+functionshade(g,rgb(zerowinding),hsv);
+layer();
+draw(g);
diff --git a/Build/source/utils/asymptote/examples/galleon.asy b/Build/source/utils/asymptote/examples/galleon.asy
new file mode 100644
index 00000000000..6cd0f4545df
--- /dev/null
+++ b/Build/source/utils/asymptote/examples/galleon.asy
@@ -0,0 +1,14 @@
+import obj;
+
+size(15cm);
+currentprojection=orthographic(0,2,5,up=Y);
+
+// A compressed version of the required data file may be obtained from:
+// http://www.cs.technion.ac.il/~irit/data/Viewpoint/galleon.obj.gz
+
+pen[] surfacepen={darkred,brown,darkred+orange,heavyred,heavyred,darkred+orange,
+ palegreen+blue+lightgrey,darkred,darkred,yellow,darkred,white,
+ white,white,white,white,white};
+surfacepen.cyclic(true);
+
+draw(obj("galleon.obj",verbose=false,surfacepen));
diff --git a/Build/source/utils/asymptote/examples/gamma.asy b/Build/source/utils/asymptote/examples/gamma.asy
new file mode 100644
index 00000000000..f92dd775abb
--- /dev/null
+++ b/Build/source/utils/asymptote/examples/gamma.asy
@@ -0,0 +1,24 @@
+import graph;
+size(300,IgnoreAspect);
+
+bool3 branch(real x)
+{
+ static int lastsign=0;
+ if(x <= 0 && x == floor(x)) return false;
+ int sign=sgn(gamma(x));
+ bool b=lastsign == 0 || sign == lastsign;
+ lastsign=sign;
+ return b ? true : default;
+}
+
+draw(graph(gamma,-4,4,n=2000,branch),red);
+
+scale(false);
+xlimits(-4,4);
+ylimits(-6,6);
+crop();
+
+xaxis("$x$",RightTicks(NoZero));
+yaxis(LeftTicks(NoZero));
+
+label("$\Gamma(x)$",(1,2),red);
diff --git a/Build/source/utils/asymptote/examples/gamma3.asy b/Build/source/utils/asymptote/examples/gamma3.asy
new file mode 100644
index 00000000000..1e400152a93
--- /dev/null
+++ b/Build/source/utils/asymptote/examples/gamma3.asy
@@ -0,0 +1,29 @@
+import graph3;
+import palette;
+
+size(12cm,IgnoreAspect);
+currentprojection=orthographic(1,-2,1);
+
+real X=4.5;
+real M=abs(gamma((X,0)));
+
+pair Gamma(pair z)
+{
+ return (z.x > 0 || z != floor(z.x)) ? gamma(z) : M;
+}
+
+real f(pair z) {return min(abs(Gamma(z)),M);}
+
+surface s=surface(f,(-2.1,-2),(X,2),70,Spline);
+
+real Arg(triple v)
+{
+ return degrees(Gamma((v.x,v.y)),warn=false);
+}
+
+s.colors(palette(s.map(Arg),Wheel()));
+draw(s);
+
+xaxis3("$\mathop{\rm Re} z$",Bounds,InTicks);
+yaxis3("$\mathop{\rm Im} z$",Bounds,InTicks(beginlabel=false));
+zaxis3("$|\Gamma(z)|$",Bounds,InTicks);
diff --git a/Build/source/utils/asymptote/examples/grid.asy b/Build/source/utils/asymptote/examples/grid.asy
new file mode 100644
index 00000000000..a607ac78e28
--- /dev/null
+++ b/Build/source/utils/asymptote/examples/grid.asy
@@ -0,0 +1,7 @@
+import math;
+size(100,0);
+
+add(shift(-5,-5)*grid(10,10));
+
+dot((0,0),red);
+
diff --git a/Build/source/utils/asymptote/examples/hierarchy.asy b/Build/source/utils/asymptote/examples/hierarchy.asy
new file mode 100644
index 00000000000..fdb833e652a
--- /dev/null
+++ b/Build/source/utils/asymptote/examples/hierarchy.asy
@@ -0,0 +1,9 @@
+texpreamble("\def\Ham{\mathop {\rm Ham}\nolimits}");
+pair align=2N;
+frame f;
+ellipse(f,Label("$\Ham(r,2)$",(0,0)),lightblue,Fill,above=false);
+ellipse(f,Label("BCH Codes",point(f,N),align),green,Fill,above=false);
+ellipse(f,Label("Cyclic Codes",point(f,N),align),lightmagenta,Fill,above=false);
+ellipse(f,Label("Linear Codes",point(f,N),align),-4mm,orange,Fill,above=false);
+box(f,Label("General Codes",point(f,N),align),2mm,yellow,Fill,above=false);
+add(f);
diff --git a/Build/source/utils/asymptote/examples/hyperboloid.asy b/Build/source/utils/asymptote/examples/hyperboloid.asy
new file mode 100644
index 00000000000..10d3609f5d0
--- /dev/null
+++ b/Build/source/utils/asymptote/examples/hyperboloid.asy
@@ -0,0 +1,8 @@
+size(200);
+import solids;
+
+currentprojection=perspective(4,4,3);
+revolution hyperboloid=revolution(new real(real x) {return sqrt(1+x*x);},
+ -2,2,20,operator..,X);
+draw(surface(hyperboloid),green);
+draw(hyperboloid,6,blue,longitudinalpen=nullpen);
diff --git a/Build/source/utils/asymptote/examples/hyperboloidsilhouette.asy b/Build/source/utils/asymptote/examples/hyperboloidsilhouette.asy
new file mode 100644
index 00000000000..1187208a670
--- /dev/null
+++ b/Build/source/utils/asymptote/examples/hyperboloidsilhouette.asy
@@ -0,0 +1,9 @@
+size(200);
+import solids;
+settings.render=0;
+settings.prc=false;
+
+currentprojection=perspective(4,4,3);
+revolution hyperboloid=revolution(new real(real x) {return sqrt(1+x*x);},
+ -2,2,20,operator..,X);
+draw(hyperboloid.silhouette(64),blue);
diff --git a/Build/source/utils/asymptote/examples/imagehistogram.asy b/Build/source/utils/asymptote/examples/imagehistogram.asy
new file mode 100644
index 00000000000..d3bdc783757
--- /dev/null
+++ b/Build/source/utils/asymptote/examples/imagehistogram.asy
@@ -0,0 +1,47 @@
+import stats;
+import graph;
+import palette;
+import contour;
+
+size(20cm);
+
+scale(false);
+
+pair[] data=new pair[50000];
+for(int i=0; i < data.length; ++i)
+ data[i]=Gaussrandpair();
+
+// Histogram limits and number of bins
+pair datamin=(-0.15,-0.15);
+pair datamax=(0.15,0.15);
+int Nx=30;
+int Ny=30;
+
+int[][] bins=frequency(data,datamin,datamax,Nx,Ny);
+
+real[] values=new real[Nx*Ny];
+pair[] points=new pair[Nx*Ny];
+int k=0;
+real dx=(datamax.x-datamin.x)/Nx;
+real dy=(datamax.y-datamin.y)/Ny;
+for(int i=0; i < Nx; ++i) {
+ for(int j=0; j < Ny; ++j) {
+ values[k]=bins[i][j];
+ points[k]=(datamin.x+(i+0.5)*dx,datamin.y+(j+0.5)*dy);
+ ++k;
+ }
+}
+
+// Create a color palette
+pen[] InvGrayscale(int NColors=256) {
+ real ninv=1.0/(NColors-1.0);
+ return sequence(new pen(int i) {return gray(1-17*i*ninv);},NColors);
+}
+
+// Draw the histogram, with axes
+bounds range=image(points,values,Range(0,40),InvGrayscale());
+draw(contour(points,values,new real[] {1,2,3,4,8,12,16,20,24,28,32,36,40},
+ operator--),blue);
+xaxis("$x$",BottomTop,LeftTicks,above=true);
+yaxis("$y$",LeftRight,RightTicks,above=true);
+
diff --git a/Build/source/utils/asymptote/examples/impact.asy b/Build/source/utils/asymptote/examples/impact.asy
new file mode 100644
index 00000000000..b58d381f26a
--- /dev/null
+++ b/Build/source/utils/asymptote/examples/impact.asy
@@ -0,0 +1,28 @@
+// Contributed by Philippe Ivaldi.
+
+import graph3 ;
+import contour;
+size (6cm,0);
+currentprojection=orthographic(1,1,1) ;
+
+real rc=1, hc=2, c=rc/hc;
+draw(shift(hc*Z)*scale(rc,rc,-hc)*unitcone,blue);
+
+triple Os=(0.5,0.5,1);
+real r=0.5;
+draw(shift(Os)*scale3(r)*unitsphere,red);
+
+real a=1+1/c^2;
+real b=abs(Os)^2-r^2;
+
+real f(pair z)
+{
+ real x=z.x, y=z.y;
+ return a*x^2-2*Os.x*x+a*y^2-2*Os.y*y-2*Os.z*sqrt(x^2+y^2)/c+b;
+}
+
+real g(pair z){return (sqrt(z.x^2+z.y^2))/c;}
+
+draw(lift(g,contour(f,(-rc,-rc),(rc,rc),new real[]{0})),linewidth(2bp)+yellow);
+
+axes3("$x$","$y$","$z$",Arrow3);
diff --git a/Build/source/utils/asymptote/examples/integraltest.asy b/Build/source/utils/asymptote/examples/integraltest.asy
new file mode 100644
index 00000000000..c45b1eb8f17
--- /dev/null
+++ b/Build/source/utils/asymptote/examples/integraltest.asy
@@ -0,0 +1,38 @@
+import graph;
+size(300,150,IgnoreAspect);
+
+real f(real x) {return 1/x^(1.1);}
+pair F(real x) {return (x,f(x));}
+
+dotfactor=7;
+
+void subinterval(real a, real b)
+{
+ path g=box((a,0),(b,f(b)));
+ filldraw(g,lightgray);
+ draw(box((a,f(a)),(b,0)));
+}
+
+int a=1, b=9;
+
+xaxis("$x$",0,b);
+yaxis("$y$",0);
+
+draw(graph(f,a,b,operator ..),red);
+
+int n=2;
+
+for(int i=a; i <= b; ++i) {
+ if(i < b) subinterval(i,i+1);
+ if(i <= n) labelx(i);
+ dot(F(i));
+}
+
+int i=n;
+labelx("$\ldots$",++i);
+labelx("$k$",++i);
+labelx("$k+1$",++i);
+labelx("$\ldots$",++i);
+
+arrow("$f(x)$",F(i-1.5),NE,1.5cm,red,Margin(0,0.5));
+
diff --git a/Build/source/utils/asymptote/examples/interpolate1.asy b/Build/source/utils/asymptote/examples/interpolate1.asy
new file mode 100644
index 00000000000..9f8367a52a4
--- /dev/null
+++ b/Build/source/utils/asymptote/examples/interpolate1.asy
@@ -0,0 +1,213 @@
+// Lagrange and Hermite interpolation in Asymptote
+// Author: Olivier Guibé
+
+import interpolate;
+import graph;
+
+// Test 1: The Runge effect in the Lagrange interpolation of 1/(x^2+1).
+
+unitsize(2cm);
+xlimits(-5,5);
+ylimits(-1,1,Crop);
+
+real f(real x) {return(1/(x^2+1));}
+real df(real x) {return(-2*x/(x^2+1)^2);}
+
+real a=-5, b=5;
+int n=15;
+real[] x,y,dy;
+x=a+(b-a)*sequence(n+1)/n;
+y=map(f,x);
+dy=map(df,x);
+for(int i=0; i <= n; ++i)
+ dot((x[i],y[i]),5bp+blue);
+horner h=diffdiv(x,y);
+fhorner p=fhorner(h);
+draw(graph(p,a,b,n=500),"$x\longmapsto{}L_{"+string(n)+"}$");
+draw(graph(f,a,b),red,"$x\longmapsto{}\frac{1}{x^2+1}$");
+
+xaxis("$x$",BottomTop,LeftTicks);
+yaxis("$y$",LeftRight,RightTicks);
+attach(legend(),point(10S),30S);
+shipout("runge1");
+
+erase();
+
+// Test 2: The Runge effect in the Hermite interpolation of 1/(x^2+1).
+
+real f(real x) {return(1/(x^2+1));}
+real df(real x) {return(-2*x/(x^2+1)^2);}
+
+real a=-5, b=5;
+int n=16;
+real[] x,y,dy;
+x=a+(b-a)*sequence(n+1)/n;
+y=map(f,x);
+dy=map(df,x);
+for(int i=0; i <= n; ++i)
+ dot((x[i],y[i]),5bp+blue);
+horner h=hdiffdiv(x,y,dy);
+fhorner ph=fhorner(h);
+draw(graph(p,a,b,n=500),"$x\longmapsto{}H_{"+string(n)+"}$");
+draw(graph(f,a,b),red,"$x\longmapsto{}\frac{1}{x^2+1}$");
+
+unitsize(2cm);
+xlimits(-5,5);
+ylimits(-1,5,Crop);
+
+xaxis("$x$",BottomTop,LeftTicks);
+yaxis("$y$",LeftRight,RightTicks);
+attach(legend(),point(10S),30S);
+
+shipout("runge2");
+
+erase();
+
+// Test 3: The Runge effect does not occur for all functions:
+// Lagrange interpolation of a function whose successive derivatives
+// are bounded by a constant M (here M=1) is shown here to converge.
+
+real f(real x) {return(sin(x));}
+real df(real x) {return(cos(x));}
+
+real a=-5, b=5;
+int n=16;
+real[] x,y,dy;
+x=a+(b-a)*sequence(n+1)/n;
+y=map(f,x);
+dy=map(df,x);
+for(int i=0; i <= n; ++i)
+ dot((x[i],y[i]),5bp+blue);
+horner h=diffdiv(x,y);
+fhorner p=fhorner(h);
+
+draw(graph(p,a,b,n=500),"$x\longmapsto{}L_{"+string(n)+"}$");
+draw(graph(f,a,b),red,"$x\longmapsto{}\cos(x)$");
+
+xaxis("$x$",BottomTop,LeftTicks);
+yaxis("$y$",LeftRight,RightTicks);
+attach(legend(),point(10S),30S);
+shipout("runge3");
+
+erase();
+
+// Test 4: However, one notes here that numerical artifacts may arise
+// from limit precision (typically 1e-16).
+
+real f(real x) {return(sin(x));}
+real df(real x) {return(cos(x));}
+
+real a=-5, b=5;
+int n=72;
+real[] x,y,dy;
+x=a+(b-a)*sequence(n+1)/n;
+y=map(f,x);
+dy=map(df,x);
+for(int i=0; i <= n; ++i)
+ dot((x[i],y[i]),5bp+blue);
+horner h=diffdiv(x,y);
+fhorner p=fhorner(h);
+
+draw(graph(p,a,b,n=500),"$x\longmapsto{}L_{"+string(n)+"}$");
+draw(graph(f,a,b),red,"$x\longmapsto{}\cos(x)$");
+ylimits(-1,5,Crop);
+xaxis("$x$",BottomTop,LeftTicks);
+yaxis("$y$",LeftRight,RightTicks);
+attach(legend(),point(10S),30S);
+
+shipout("runge4");
+
+erase();
+
+// Test 5: The situation is much better using Tchebychev points.
+
+unitsize(2cm);
+xlimits(-5,5);
+ylimits(-1,2,Crop);
+
+real f(real x) {return(1/(x^2+1));}
+real df(real x) {return(-2*x/(x^2+1)^2);}
+
+real a=-5, b=5;
+int n=16;
+real[] x,y,dy;
+fhorner p,ph,ph1;
+for(int i=0; i <= n; ++i)
+ x[i]=(a+b)/2+(b-a)/2*cos((2*i+1)/(2*n+2)*pi);
+y=map(f,x);
+dy=map(df,x);
+for(int i=0; i <= n; ++i)
+ dot((x[i],y[i]),5bp+blue);
+horner h=diffdiv(x,y);
+fhorner p=fhorner(h);
+
+draw(graph(p,a,b,n=500),"$x\longmapsto{}T_{"+string(n)+"}$");
+draw(graph(f,a,b),red,"$x\longmapsto{}\frac{1}{x^2+1}$");
+
+xaxis("$x$",BottomTop,LeftTicks);
+yaxis("$y$",LeftRight,RightTicks);
+attach(legend(),point(10S),30S);
+
+shipout("runge5");
+
+erase();
+
+// Test 6: Adding a few more Tchebychev points yields a very good result.
+
+unitsize(2cm);
+xlimits(-5,5);
+ylimits(-1,2,Crop);
+
+real f(real x) {return(1/(x^2+1));}
+real df(real x) {return(-2*x/(x^2+1)^2);}
+
+real a=-5, b=5;
+int n=26;
+real[] x,y,dy;
+for(int i=0; i <= n; ++i)
+ x[i]=(a+b)/2+(b-a)/2*cos((2*i+1)/(2*n+2)*pi);
+y=map(f,x);
+dy=map(df,x);
+for(int i=0; i <= n; ++i)
+ dot((x[i],y[i]),5bp+blue);
+horner h=diffdiv(x,y);
+fhorner p=fhorner(h);
+draw(graph(p,a,b,n=500),"$x\longmapsto{}T_{"+string(n)+"}$");
+draw(graph(f,a,b),red,"$x\longmapsto{}\frac{1}{x^2+1}$");
+
+xaxis("$x$",BottomTop,LeftTicks);
+yaxis("$y$",LeftRight,RightTicks);
+attach(legend(),point(10S),30S);
+
+
+shipout("runge6");
+
+erase();
+
+// Test 7: Another Tchebychev example.
+
+unitsize(2cm);
+xlimits(-2,2);
+ylimits(-0.5,2,Crop);
+
+real f(real x) {return(sqrt(abs(x-1)));}
+
+real a=-2, b=2;
+int n=30;
+real[] x,y,dy;
+for(int i=0; i <= n; ++i)
+ x[i]=(a+b)/2+(b-a)/2*cos((2*i+1)/(2*n+2)*pi);
+y=map(f,x);
+dy=map(df,x);
+for(int i=0; i <= n; ++i)
+ dot((x[i],y[i]),5bp+blue);
+horner h=diffdiv(x,y);
+fhorner p=fhorner(h);
+draw(graph(p,a,b,n=500),"$x\longmapsto{}T_{"+string(n)+"}$");
+draw(graph(f,a,b),red,"$x\longmapsto{}\sqrt{|x-1|}$");
+
+xaxis("$x$",BottomTop,LeftTicks);
+yaxis("$y$",LeftRight,RightTicks);
+attach(legend(),point(10S),30S);
+
+shipout("runge7");
diff --git a/Build/source/utils/asymptote/examples/jump.asy b/Build/source/utils/asymptote/examples/jump.asy
new file mode 100644
index 00000000000..7ae19be3886
--- /dev/null
+++ b/Build/source/utils/asymptote/examples/jump.asy
@@ -0,0 +1,14 @@
+import graph;
+size(4inches,0);
+
+real f1(real x) {return (1+x^2);}
+real f2(real x) {return (4-x);}
+
+xaxis("$x$",LeftTicks,Arrow);
+yaxis("$y$",RightTicks,Arrow);
+
+draw("$y=1+x^2$",graph(f1,-2,1));
+dot((1,f1(1)),UnFill);
+
+draw("$y=4-x$",graph(f2,1,5),LeftSide,red,Arrow);
+dot((1,f2(1)),red);
diff --git a/Build/source/utils/asymptote/examples/label3.asy b/Build/source/utils/asymptote/examples/label3.asy
new file mode 100644
index 00000000000..5c966b0d9a5
--- /dev/null
+++ b/Build/source/utils/asymptote/examples/label3.asy
@@ -0,0 +1,7 @@
+import three;
+
+currentprojection=perspective(1,1,1,up=Y);
+
+label("$\displaystyle\int_{-\infty}^{+\infty} e^{-\alpha x^2}\,dx=
+\sqrt{\frac{\pi}{\alpha}}$",O,blue);
+
diff --git a/Build/source/utils/asymptote/examples/label3ribbon.asy b/Build/source/utils/asymptote/examples/label3ribbon.asy
new file mode 100644
index 00000000000..d974b2fb748
--- /dev/null
+++ b/Build/source/utils/asymptote/examples/label3ribbon.asy
@@ -0,0 +1,6 @@
+import three;
+
+currentprojection=perspective(100,100,200,up=Y);
+
+draw(extrude(texpath("$\displaystyle\int_{-\infty}^{+\infty}e^{-\alpha x^2}\,dx=
+\sqrt{\frac{\pi}{\alpha}}$"),2Z),blue);
diff --git a/Build/source/utils/asymptote/examples/label3solid.asy b/Build/source/utils/asymptote/examples/label3solid.asy
new file mode 100644
index 00000000000..5eb955ff482
--- /dev/null
+++ b/Build/source/utils/asymptote/examples/label3solid.asy
@@ -0,0 +1,6 @@
+import three;
+
+currentprojection=perspective(100,100,200,up=Y);
+
+draw(extrude("$\displaystyle\int_{-\infty}^{+\infty}e^{-\alpha x^2}\,dx=
+\sqrt{\frac{\pi}{\alpha}}$",2Z),blue);
diff --git a/Build/source/utils/asymptote/examples/labelbox.asy b/Build/source/utils/asymptote/examples/labelbox.asy
new file mode 100644
index 00000000000..cd61a9da69c
--- /dev/null
+++ b/Build/source/utils/asymptote/examples/labelbox.asy
@@ -0,0 +1,11 @@
+size(0,100);
+real margin=2mm;
+pair z1=(0,1);
+pair z0=(0,0);
+
+object label1=draw("small box",box,z1,margin);
+object label0=draw("LARGE ELLIPSE",ellipse,z0,margin);
+
+add(new void(frame f, transform t) {
+ draw(f,point(label1,SW,t){SW}..{SW}point(label0,NNE,t));
+ });
diff --git a/Build/source/utils/asymptote/examples/laserlattice.asy b/Build/source/utils/asymptote/examples/laserlattice.asy
new file mode 100644
index 00000000000..da4d9a49b7c
--- /dev/null
+++ b/Build/source/utils/asymptote/examples/laserlattice.asy
@@ -0,0 +1,44 @@
+import graph;
+import palette;
+
+int n=256;
+pen[] Palette=BWRainbow();
+
+real w(real w0, real z0, real z) {return w0*sqrt(1+(z/z0)^2);}
+
+real pot(real lambda, real w0, real r, real z)
+{
+ real z0=pi*w0^2/lambda, kappa=2pi/lambda;
+ return exp(-2*(r/w(w0,z0,z))^2)*cos(kappa*z)^2;
+}
+
+picture make_field(real lambda, real w0)
+{
+ real[][] v=new real[n][n];
+ for(int i=0; i < n; ++i)
+ for(int j=0; j < n; ++j)
+ v[i][j]=pot(lambda,w0,i-n/2,abs(j-n/2));
+
+ picture p=new picture;
+ size(p,250,250,IgnoreAspect);
+ real xm=-n/lambda, ym=-n/(2*w0), xx=n/lambda, yx=n/(2*w0);
+ image(p,v,(xm,ym),(xx,yx),Palette);
+ xlimits(p,xm,xx);
+ ylimits(p,ym,yx);
+ xaxis(p,"{\Large $z/\frac{\lambda}{2}$}",BottomTop,LeftTicks);
+ yaxis(p,"{\Large $r/w_0$}",LeftRight,RightTicks);
+ label(p,format("{\LARGE $w_0/\lambda=%.2f$}",w0/lambda),point(p,NW),5N);
+
+ return p;
+}
+
+picture p=make_field(160,80);
+picture q=make_field(80,80);
+picture r=make_field(16,80);
+picture s=make_field(2,80);
+
+real margin=1cm;
+add(p.fit(),(0,0),margin*NW);
+add(q.fit(),(0,0),margin*NE);
+add(r.fit(),(0,0),margin*SW);
+add(s.fit(),(0,0),margin*SE);
diff --git a/Build/source/utils/asymptote/examples/latticeshading.asy b/Build/source/utils/asymptote/examples/latticeshading.asy
new file mode 100644
index 00000000000..c6689fa72d5
--- /dev/null
+++ b/Build/source/utils/asymptote/examples/latticeshading.asy
@@ -0,0 +1,7 @@
+size(200);
+
+pen[][] p={{white,grey,black},
+ {red,green,blue},
+ {cyan,magenta,yellow}};
+
+latticeshade(unitsquare,p);
diff --git a/Build/source/utils/asymptote/examples/lever.asy b/Build/source/utils/asymptote/examples/lever.asy
new file mode 100644
index 00000000000..e30de87540f
--- /dev/null
+++ b/Build/source/utils/asymptote/examples/lever.asy
@@ -0,0 +1,23 @@
+size(200,0);
+
+pair z0=(0,0);
+pair z1=(2,0);
+pair z2=(5,0);
+pair zf=z1+0.75*(z2-z1);
+
+draw(z1--z2);
+dot(z1,red+0.15cm);
+dot(z2,darkgreen+0.3cm);
+label("$m$",z1,1.2N,red);
+label("$M$",z2,1.5N,darkgreen);
+label("$\hat{\ }$",zf,0.2*S,fontsize(24)+blue);
+
+pair s=-0.2*I;
+draw("$x$",z0+s--z1+s,N,red,Arrows,Bars,PenMargins);
+
+s=-0.5*I;
+draw("$\bar{x}$",z0+s--zf+s,blue,Arrows,Bars,PenMargins);
+
+s=-0.95*I;
+draw("$X$",z0+s--z2+s,darkgreen,Arrows,Bars,PenMargins);
+
diff --git a/Build/source/utils/asymptote/examples/limit.asy b/Build/source/utils/asymptote/examples/limit.asy
new file mode 100644
index 00000000000..ef71928941e
--- /dev/null
+++ b/Build/source/utils/asymptote/examples/limit.asy
@@ -0,0 +1,28 @@
+size(200,200,IgnoreAspect);
+import graph;
+
+real L=1;
+real epsilon=0.25;
+
+real a(int n) {return L+1/n;}
+
+for(int i=1; i < 20; ++i)
+ dot((i,a(i)));
+
+real N=1/epsilon;
+
+xaxis(Label("$n$",align=2S));
+yaxis(Label("$a_n$",0.85));
+
+xtick("$2$",2);
+ytick("$\frac{3}{2}$",3/2);
+ytick("$2$",2);
+
+yequals(Label("$L$",0,up),L,extend=true,blue);
+yequals(Label("$L+\epsilon$",1,NW),L+epsilon,extend=true,red+dashed);
+yequals(Label("$L-\epsilon$",1,SW),L-epsilon,extend=true,red+dashed);
+
+xequals(N,extend=true,darkgreen+dashed);
+labelx(shift(0,-10)*"$N=\frac{1}{\epsilon}$",N,E,darkgreen);
+
+label("$a_n=1+\frac{1}{n},\quad \epsilon=\frac{1}{4}$",point((0,1)),10S+E);
diff --git a/Build/source/utils/asymptote/examples/lines.asy b/Build/source/utils/asymptote/examples/lines.asy
new file mode 100644
index 00000000000..9749f73a350
--- /dev/null
+++ b/Build/source/utils/asymptote/examples/lines.asy
@@ -0,0 +1,10 @@
+import math;
+
+int n=7;
+
+size(200,0);
+
+draw(unitcircle,red);
+for (int i=0; i < n-1; ++i)
+ for (int j=i+1; j < n; ++j)
+ drawline(unityroot(n,i),unityroot(n,j),blue);
diff --git a/Build/source/utils/asymptote/examples/log.asy b/Build/source/utils/asymptote/examples/log.asy
new file mode 100644
index 00000000000..532b7b782b6
--- /dev/null
+++ b/Build/source/utils/asymptote/examples/log.asy
@@ -0,0 +1,14 @@
+import graph;
+
+size(150,0);
+
+real f(real x) {return log(x);}
+pair F(real x) {return (x,f(x));}
+
+xaxis("$x$",0);
+yaxis("$y$");
+
+draw(graph(f,0.01,10,operator ..));
+
+labelx(1,SSE);
+label("$\log x$",F(7),SE);
diff --git a/Build/source/utils/asymptote/examples/logdown.asy b/Build/source/utils/asymptote/examples/logdown.asy
new file mode 100644
index 00000000000..25d10ed978e
--- /dev/null
+++ b/Build/source/utils/asymptote/examples/logdown.asy
@@ -0,0 +1,13 @@
+import graph;
+size(200,IgnoreAspect);
+
+real log10Down(real x) {return -log10(x);}
+real pow10Down(real x) {return pow10(-x);}
+
+scaleT LogDown=scaleT(log10Down,pow10Down,logarithmic=true);
+scale(Linear,LogDown);
+
+draw(graph(exp,-5,5));
+
+yaxis("$y$",RightTicks(Label(Fill(white)),DefaultLogFormat),BeginArrow);
+xaxis("$x$",LeftTicks(NoZero),EndArrow);
diff --git a/Build/source/utils/asymptote/examples/logo3.asy b/Build/source/utils/asymptote/examples/logo3.asy
new file mode 100644
index 00000000000..6fc73dc9470
--- /dev/null
+++ b/Build/source/utils/asymptote/examples/logo3.asy
@@ -0,0 +1,33 @@
+import three;
+
+size(560,320,IgnoreAspect);
+size3(140,80,15);
+currentprojection=perspective(-3,20,10,up=Y);
+currentlight=adobe;
+
+path[] outline;
+
+real a=-0.4;
+real b=0.95;
+real y1=-5;
+real y2=-3y1/2;
+path A=(a,0){dir(10)}::{dir(89.5)}(0,y2);
+outline.push(A);
+outline.push((0,y1){dir(88.3)}::{dir(20)}(b,0));
+real c=0.5*a;
+pair z=(0,2.5);
+path[] text = shift(0,2)*scale(0.01,0.15)*
+ texpath(Label("{\it symptote}",z,0.25*E+0.169S,fontsize(24)));
+outline.append(text);
+pair w=(0,1.7);
+outline.push(intersectionpoint(A,w-1--w)--w);
+outline.push((0,y1)--(0,y2));
+outline.push((a,0)--(b,0));
+
+for(path p : outline)
+ draw(extrude(p,-0.1Z),material(lightgray,shininess=1.0));
+
+draw(path3(outline),red+linewidth(0));
+
+draw(surface(text),red,nolight);
+
diff --git a/Build/source/utils/asymptote/examples/lowint.asy b/Build/source/utils/asymptote/examples/lowint.asy
new file mode 100644
index 00000000000..e4bf1c55606
--- /dev/null
+++ b/Build/source/utils/asymptote/examples/lowint.asy
@@ -0,0 +1,11 @@
+size(100,0);
+import graph;
+import lowupint;
+
+real a=-0.8, b=1.2;
+real c=1.0/sqrt(3.0);
+
+partition(a,b,c,min);
+
+arrow("$f(x)$",F(0.5*(a+b)),NNE,red);
+label("$\cal{L}$",(0.5*(a+b),f(0.5*(a+b))/2));
diff --git a/Build/source/utils/asymptote/examples/lowupint.asy b/Build/source/utils/asymptote/examples/lowupint.asy
new file mode 100644
index 00000000000..3a14cd91104
--- /dev/null
+++ b/Build/source/utils/asymptote/examples/lowupint.asy
@@ -0,0 +1,31 @@
+import graph;
+
+real f(real x) {return x^3-x+2;}
+pair F(real x) {return (x,f(x));}
+
+void rectangle(real a, real b, real c, real h(real,real))
+{
+ real height=(a < c && c < b) ? f(c) : h(f(a),f(b));
+ pair p=(a,0), q=(b,height);
+ path g=box(p,q);
+ fill(g,lightgray);
+ draw(g);
+}
+
+void partition(real a, real b, real c, real h(real,real))
+{
+ rectangle(a,a+.4,c,h);
+ rectangle(a+.4,a+.6,c,h);
+ rectangle(a+.6,a+1.2,c,h);
+ rectangle(a+1.2,a+1.6,c,h);
+ rectangle(a+1.6,a+1.8,c,h);
+ rectangle(a+1.8,b,c,h);
+
+ draw((a,0)--(F(a)));
+ draw((b,0)--(F(b)));
+
+ draw(graph(f,a,b,operator ..),red);
+ draw((a,0)--(b,0));
+ labelx("$a$",a);
+ labelx("$b$",b);
+}
diff --git a/Build/source/utils/asymptote/examples/magnetic.asy b/Build/source/utils/asymptote/examples/magnetic.asy
new file mode 100644
index 00000000000..4dc187f5770
--- /dev/null
+++ b/Build/source/utils/asymptote/examples/magnetic.asy
@@ -0,0 +1,17 @@
+import graph3;
+import contour3;
+
+size(200,0);
+currentprojection=orthographic((6,8,2),up=Y);
+
+real a(real z) {return (z < 6) ? 1 : exp((abs(z)-6)/4);}
+real b(real z) {return 1/a(z);}
+real B(real z) {return 1-0.5cos(pi*z/10);}
+
+real f(real x, real y, real z) {return 0.5B(z)*(a(z)*x^2+b(z)*y^2)-1;}
+
+draw(surface(contour3(f,(-2,-2,-10),(2,2,10),10)),blue+opacity(0.75));
+
+xaxis3(Label("$x$",1),red);
+yaxis3(Label("$y$",1),red);
+zaxis3(Label("$z$",1),red);
diff --git a/Build/source/utils/asymptote/examples/markregular.asy b/Build/source/utils/asymptote/examples/markregular.asy
new file mode 100644
index 00000000000..716599fbcf1
--- /dev/null
+++ b/Build/source/utils/asymptote/examples/markregular.asy
@@ -0,0 +1,26 @@
+import graph;
+
+size(10cm,0);
+
+real xmin=-4,xmax=4;
+real ymin=-2,ymax=10;
+
+real f(real x) {return x^2;}
+
+marker cross=marker(scale(4)*rotate(45)*cross(4),
+ markuniform(new pair(real t) {return Scale((t,f(t)));},
+ xmin,xmax,round(2*(xmax-xmin))),1bp+red);
+
+draw(graph(f,xmin,xmax,n=400),linewidth(1bp),cross);
+
+ylimits(-2.5,10,Crop);
+
+xaxis(Label("$x$",position=EndPoint, align=NE),xmin=xmin,xmax=xmax,
+ Ticks(scale(.7)*Label(align=E),NoZero,begin=false,beginlabel=false,
+ end=false,endlabel=false,Step=1,step=.25,
+ Size=1mm, size=.5mm,pTick=black,ptick=gray),Arrow);
+
+yaxis(Label("$y$",position=EndPoint, align=NE),ymin=ymin,ymax=ymax,
+ Ticks(scale(.7)*Label(),NoZero,begin=false,beginlabel=false,
+ end=false,endlabel=false,Step=1,step=.25,Size=1mm,size=.5mm,
+ pTick=black,ptick=gray),Arrow);
diff --git a/Build/source/utils/asymptote/examples/mosaic.asy b/Build/source/utils/asymptote/examples/mosaic.asy
new file mode 100644
index 00000000000..0f19117c4b3
--- /dev/null
+++ b/Build/source/utils/asymptote/examples/mosaic.asy
@@ -0,0 +1,165 @@
+// Calendar example contributed by Jens Schwaiger
+
+// transformations
+path similarpath(pair a, pair b, path p) {
+ // transform p into a path starting at a and ending at b
+ pair first;
+ pair last;
+ path p_;
+ first=point(p,0);
+ last=point(p,length(p));
+ p_=shift(-first)*p;
+ p_=rotate(degrees(b-a))*p_;
+ p_=scale(abs(b-a)/abs(last-first))*p_;
+ p_=shift(a)*p_;
+ return p_;
+}
+
+path c_line(path p) {
+ // returns the path obtained by adding to p a copy rotated
+ // around the endpoint of p by 180 degrees
+ // works only if the initial point and the endpoint of p are different
+ // a c_line is symetric with respect to the center of
+ // the straight line between its endpoints
+ //
+ return p..rotate(180,point(p,length(p)))*reverse(p);
+}
+
+path tounitcircle(path p, int n=300) {
+ // the transformation pair x --> x/sqrt(1+abs(x)^2)
+ // is a bijection from the plane to the open unitdisk
+ real l=arclength(p);
+ path ghlp;
+ for(int i=0; i <= n; ++i) {
+ real at=arctime(p,l/n*i);
+ pair phlp=point(p,at);
+ real trhlp=1/(1+abs(phlp)^2)^(1/2);
+ ghlp=ghlp--trhlp*phlp;
+ }
+ if(cyclic(p)) {ghlp=ghlp--cycle;}
+ return ghlp;
+}
+
+void centershade(picture pic=currentpicture, path p, pen in, pen out,
+ pen drawpen=currentpen) {
+ pair center=0.5(max(p)+min(p));
+ real radius=0.5abs(max(p)-min(p));
+ radialshade(pic,p,in,center,0,out,center,radius);
+ draw(pic,p,drawpen);
+}
+
+pair zentrum(path p) {return 0.5(min(p)+max(p));}
+
+//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+real scalefactor=19/13; // For output: height=scalefactor*width
+real outputwidth=13cm;
+picture kalender;// at first we produce a calendar for february 2006
+texpreamble("\usepackage[latin1]{inputenc}");
+size(outputwidth,0);
+real yc=0.5;
+pair diff=(-3.5,5*yc);
+pen farbe(int j) {
+ pen hlp=0.8white;
+ if(j % 7 == 6) {hlp=red+white;}
+ return hlp;}
+
+// farbe=German word for color
+path kasten=yscale(yc)*unitsquare;
+// Kasten is a German word meaning something like box
+path Gkasten=shift((0,2*yc)+diff)*xscale(7)*yscale(2)*kasten;
+path tage[]= new path[7]; // Tag=day
+string wochentag[]={"MO","DI","MI","DO","FR","SA","SO"};
+path[][] bx= new path[6][7];
+string[][] entry= new string[6][7];
+bool[][] holiday=new bool[6][7];
+
+// Now the necessary information for February 2006
+int start=2;
+int days=28;
+for(int i=0; i < entry.length; ++i) {
+ for(int j=0; j < entry[0].length; ++j) {
+ int day=i*7+j-start+1;
+ entry[i][j]=(day > 0 && day <= days ? (string) day : "");
+ holiday[i][j]=false;
+ }
+}
+
+for(int j=0; j < 7; ++j) {
+ tage[j]=shift((j,yc)+diff)*kasten;
+ filldraw(tage[j],farbe(j),black+2bp);
+ label(wochentag[j],zentrum(tage[j]),Palatino());
+ for(int i=0; i < 6; ++i) {bx[i][j]=shift((j,-yc*i)+diff)*kasten;
+ filldraw(bx[i][j],farbe(j),black+2bp);
+ if(holiday[i][j]) {filldraw(bx[i][j],farbe(6),black+2bp);};
+ };
+};
+filldraw(Gkasten,0.3white,black+2bp);
+for(int j=0; j < 7; ++j)
+ for(int i=0; i < 6 ; ++i) {label(entry[i][j],zentrum(bx[i][j]),Palatino());}
+label("\Huge Februar 2006",zentrum(Gkasten),Palatino()+white);
+// Zentrum=center; Februar=february
+add(kalender,currentpicture);
+erase();
+
+// Now the mosaic is constructed
+pair a[]=new pair[4];
+path p[]=new path[4];
+path q[]=new path[4];
+path kontur[]=new path[5];
+picture temppic;
+
+a[1]=(0,0);
+a[2]=(1,0);
+a[3]=(0,1); // a triangle with abs(a[2]-a[1])=abs(a[3]-a[1]
+ // and a right angle at a[1];
+q[1]=(0,0){dir(-20)}::{dir(20)}(0.2,0){dir(-140)}..{dir(0)}(0.3,-0.2){dir(0)}..
+{dir(140)}(0.4,0){dir(20)}..{dir(-20)}(1,0);
+q[2]=(0,0){dir(20)}..{dir(-20)}(0.8,0){dir(-140)}..{dir(0)}(0.9,-0.3){dir(0)}..
+{dir(140)}(1,0);
+q[2]=c_line(q[2]);
+p[1]=similarpath(a[1],a[2],q[1]);// arbitrary path from a[1] to a[2]
+p[2]=similarpath(a[2],a[3],q[2]);// arbitrary c_line from a[2] to a[3]
+p[3]=rotate(90,a[1])*reverse(p[1]);//
+kontur[1]=p[1]..p[2]..p[3]..cycle;// first tile
+kontur[2]=rotate(90,a[1])*kontur[1];// second
+kontur[3]=rotate(180,a[1])*kontur[1];// third
+kontur[4]=rotate(270,a[1])*kontur[1];// fourth
+pair tri=2*(interp(a[2],a[3],0.5)-a[1]);
+pair trii=rotate(90)*tri;
+// translations of kontur[i], i=1,2,3,4, with respect to
+// j*tri+k*trii
+// fill the plane
+
+for(int j=-4; j < 4; ++j)
+ for(int k=-4; k < 4; ++k) {
+ transform tr=shift(j*tri+k*trii);
+ for(int i=1; i < 5; ++i) {
+ centershade(temppic,tr*kontur[i],(1-i/10)*white,
+ (1-i/10)*chartreuse,black+2bp);
+ }
+ }
+
+// Now we produce the bijective images inside
+// a suitably scaled unitcircle
+for(int k=-1; k < 2; ++k)
+ for(int l=-1; l < 2; ++l) {
+ transform tr=shift(k*tri+l*trii);
+ for(int i=1; i < 5; ++i) {
+ centershade(temppic,scale(2.5)*tounitcircle(tr*kontur[i],380),
+ (1-i/10)*white,(1-i/10)*orange,black+2bp);
+ }
+ }
+
+add(temppic);
+
+// We clip the picture to a suitable box
+pair piccenter=0.5*(temppic.min()+temppic.max());
+pair picbox=temppic.max()-temppic.min();
+real picwidth=picbox.x;
+transform trialtrans=shift(0,-1.5)*shift(piccenter)*yscale(scalefactor)*
+ scale(0.25picwidth)*shift((-0.5,-0.5))*identity();
+clip(trialtrans*unitsquare);
+
+// add the calendar at a suitable position
+add(kalender.fit(0.75*outputwidth),interp(point(S),point(N),1/13));
diff --git a/Build/source/utils/asymptote/examples/mosquito.asy b/Build/source/utils/asymptote/examples/mosquito.asy
new file mode 100644
index 00000000000..288e253bfca
--- /dev/null
+++ b/Build/source/utils/asymptote/examples/mosquito.asy
@@ -0,0 +1,82 @@
+size(9cm,10cm,IgnoreAspect);
+
+pair d=(1,0.25);
+real s=1.6d.x;
+real y=0.6;
+defaultpen(fontsize(8));
+
+picture box(string s, pair z=(0,0)) {
+ picture pic;
+ draw(pic,box(-d/2,d/2));
+ label(pic,s,(0,0));
+ return shift(z)*pic;
+}
+
+label("Birds",(0,y));
+picture removed=box("Removed ($R_B$)");
+picture infectious=box("Infectious ($I_B$)",(0,-1.5));
+picture susceptible=box("Susceptible ($S_B$)",(0,-3));
+
+add(removed);
+add(infectious);
+add(susceptible);
+
+label("Mosquitoes",(s,y));
+picture larval=box("Larval ($L_M$)",(s,0));
+picture susceptibleM=box("Susceptible ($S_M$)",(s,-1));
+picture exposed=box("Exposed ($E_M$)",(s,-2));
+picture infectiousM=box("Infectious ($I_M$)",(s,-3));
+
+add(larval);
+add(susceptibleM);
+add(exposed);
+add(infectiousM);
+
+path ls=point(larval,S)--point(susceptibleM,N);
+path se=point(susceptibleM,S)--point(exposed,N);
+path ei=point(exposed,S)--point(infectiousM,N);
+path si=point(susceptible,N)--point(infectious,S);
+
+draw(minipage("\flushright{recovery rate ($g$) \& death rate from virus
+($\mu_V$)}",40pt),point(infectious,N)--point(removed,S),LeftSide,Arrow,
+ PenMargin);
+
+draw(si,LeftSide,Arrow,PenMargin);
+
+draw(minipage("\flushright{maturation rate ($m$)}",50pt),ls,RightSide,
+ Arrow,PenMargin);
+draw(minipage("\flushright{viral incubation rate ($k$)}",40pt),ei,
+ RightSide,Arrow,PenMargin);
+
+path ise=point(infectious,E)--point(se,0.5);
+
+draw("$(ac)$",ise,LeftSide,dashed,Arrow,PenMargin);
+label(minipage("\flushleft{biting rate $\times$ transmission
+probability}",50pt),point(infectious,SE),dir(-60)+S);
+
+path isi=point(infectiousM,W)--point(si,2.0/3);
+
+draw("$(ab)$",isi,LeftSide,dashed,Arrow,PenMargin);
+draw(se,LeftSide,Arrow,PenMargin);
+
+real t=2.0;
+draw("$\beta_M$",
+ point(susceptibleM,E){right}..tension t..{left}point(larval,E),
+ 2*(S+SE),red,Arrow(Fill,0.5));
+draw(minipage("\flushleft{birth rate ($\beta_M$)}",20pt),
+ point(exposed,E){right}..tension t..{left}point(larval,E),2SW,red,
+ Arrow(Fill,0.5));
+draw("$\beta_M$",
+ point(infectiousM,E){right}..tension t..{left}point(larval,E),2SW,
+ red,Arrow(Fill,0.5));
+
+path arrow=(0,0)--0.75cm*dir(35);
+draw(point(larval,NNE),
+ Label(minipage("\flushleft{larval death rate ($\mu_L$)}",45pt),1),
+ arrow,blue,Arrow);
+draw(point(susceptibleM,NNE),
+ Label(minipage("\flushleft{adult death rate ($\mu_A$)}",20pt),1),
+ arrow,N,blue,Arrow);
+draw(point(exposed,NNE),Label("$\mu_A$",1),arrow,blue,Arrow);
+draw(point(infectiousM,NNE),Label("$\mu_A$",1),arrow,blue,Arrow);
+
diff --git a/Build/source/utils/asymptote/examples/near_earth.asy b/Build/source/utils/asymptote/examples/near_earth.asy
new file mode 100644
index 00000000000..afdf64c6b5c
--- /dev/null
+++ b/Build/source/utils/asymptote/examples/near_earth.asy
@@ -0,0 +1,56 @@
+import three;
+import math;
+texpreamble("\usepackage{bm}");
+
+size(300,0);
+
+pen thickp=linewidth(0.5mm);
+real radius=0.8, lambda=37, aux=60;
+
+currentprojection=perspective(4,1,2);
+
+// Planes
+pen bg=gray(0.9)+opacity(0.5);
+draw(surface((1.2,0,0)--(1.2,0,1.2)--(0,0,1.2)--(0,0,0)--cycle),bg);
+draw(surface((0,1.2,0)--(0,1.2,1.2)--(0,0,1.2)--(0,0,0)--cycle),bg);
+draw(surface((1.2,0,0)--(1.2,1.2,0)--(0,1.2,0)--(0,0,0)--cycle),bg);
+
+real r=1.5;
+pen p=rgb(0,0.7,0);
+draw(Label("$x$",1),O--r*X,p,Arrow3);
+draw(Label("$y$",1),O--r*Y,p,Arrow3);
+draw(Label("$z$",1),O--r*Z,p,Arrow3);
+label("$\rm O$",(0,0,0),W);
+
+// Point Q
+triple pQ=radius*dir(lambda,aux);
+draw(O--radius*dir(90,aux),dashed);
+label("$\rm Q$",pQ,N+3*W);
+draw("$\lambda$",arc(O,0.15pQ,0.15*Z),N+0.3E);
+
+// Particle
+triple m=pQ-(0.26,-0.4,0.28);
+real width=5;
+dot("$m$",m,SE,linewidth(width));
+draw("$\bm{\rho}$",(0,0,0)--m,Arrow3,PenMargin3(0,width));
+draw("$\bm{r}$",pQ--m,Arrow3,PenMargin3(0,width));
+
+// Spherical octant
+real r=sqrt(pQ.x^2+pQ.y^2);
+draw(arc((0,0,pQ.z),(r,0,pQ.z),(0,r,pQ.z)),dashed);
+draw(arc(O,radius*Z,radius*dir(90,aux)),dashed);
+draw(arc(O,radius*Z,radius*X),thickp);
+draw(arc(O,radius*Z,radius*Y),thickp);
+draw(arc(O,radius*X,radius*Y),thickp);
+
+// Moving axes
+triple i=dir(90+lambda,aux);
+triple k=unit(pQ);
+triple j=cross(k,i);
+
+draw(Label("$x$",1),pQ--pQ+0.2*i,2W,red,Arrow3);
+draw(Label("$y$",1),pQ--pQ+0.32*j,red,Arrow3);
+draw(Label("$z$",1),pQ--pQ+0.26*k,red,Arrow3);
+
+draw("$\bm{R}$",O--pQ,Arrow3,PenMargin3);
+draw("$\omega\bm{K}$",arc(0.9Z,0.2,90,-120,90,160,CW),1.2N,Arrow3);
diff --git a/Build/source/utils/asymptote/examples/oneoverx.asy b/Build/source/utils/asymptote/examples/oneoverx.asy
new file mode 100644
index 00000000000..5d9775d44dc
--- /dev/null
+++ b/Build/source/utils/asymptote/examples/oneoverx.asy
@@ -0,0 +1,17 @@
+import graph;
+size(200,IgnoreAspect);
+
+real f(real x) {return 1/x;};
+
+bool3 branch(real x)
+{
+ static int lastsign=0;
+ if(x == 0) return false;
+ int sign=sgn(x);
+ bool b=lastsign == 0 || sign == lastsign;
+ lastsign=sign;
+ return b ? true : default;
+}
+
+draw(graph(f,-1,1,branch));
+axes("$x$","$y$",red);
diff --git a/Build/source/utils/asymptote/examples/orthocenter.asy b/Build/source/utils/asymptote/examples/orthocenter.asy
new file mode 100644
index 00000000000..3a4b314f68f
--- /dev/null
+++ b/Build/source/utils/asymptote/examples/orthocenter.asy
@@ -0,0 +1,41 @@
+import geometry;
+import math;
+
+size(7cm,0);
+
+real theta=degrees(asin(0.5/sqrt(7)));
+
+pair B=(0,sqrt(7));
+pair A=B+2sqrt(3)*dir(270-theta);
+pair C=A+sqrt(21);
+pair O=0;
+
+pair Ap=extension(A,O,B,C);
+pair Bp=extension(B,O,C,A);
+pair Cp=extension(C,O,A,B);
+
+perpendicular(Ap,NE,Ap--O,blue);
+perpendicular(Bp,NE,Bp--C,blue);
+perpendicular(Cp,NE,Cp--O,blue);
+
+draw(A--B--C--cycle);
+
+currentpen=black;
+
+draw("1",A--O,-0.25*I*dir(A--O));
+draw(O--Ap);
+draw("$\sqrt{7}$",B--O,LeftSide);
+draw(O--Bp);
+draw("4",C--O);
+draw(O--Cp);
+
+dot("$O$",O,1.5*dir(B--Bp,Cp--C),red);
+dot("$A$",A,1.5*dir(C--A,B--A),red);
+dot("$B$",B,NW,red);
+dot("$C$",C,dir(A--C,B--C),red);
+dot("$A'$",Ap,dir(A--Ap),red);
+dot("$B'$",Bp,dir(B--Bp),red);
+dot("$C'$",Cp,dir(C--Cp),red);
+
+label(graphic("piicon.eps","width=2.5cm"),Ap,5ENE,red);
+
diff --git a/Build/source/utils/asymptote/examples/parametricelevation.asy b/Build/source/utils/asymptote/examples/parametricelevation.asy
new file mode 100644
index 00000000000..0c800f3f4ac
--- /dev/null
+++ b/Build/source/utils/asymptote/examples/parametricelevation.asy
@@ -0,0 +1,10 @@
+import graph3;
+import palette;
+size(200);
+
+currentprojection=orthographic(4,2,4);
+
+triple f(pair z) {return expi(z.x,z.y);}
+
+surface s=surface(f,(0,0),(pi,2pi),30);
+draw(s,mean(palette(s.map(zpart),BWRainbow())),black,nolight);
diff --git a/Build/source/utils/asymptote/examples/parametricsurface.asy b/Build/source/utils/asymptote/examples/parametricsurface.asy
new file mode 100644
index 00000000000..d020bbe6e7f
--- /dev/null
+++ b/Build/source/utils/asymptote/examples/parametricsurface.asy
@@ -0,0 +1,22 @@
+import graph3;
+
+size(200,0);
+currentprojection=orthographic(4,0,2);
+
+real R=2;
+real a=1.9;
+
+triple f(pair t) {
+ return ((R+a*cos(t.y))*cos(t.x),(R+a*cos(t.y))*sin(t.x),a*sin(t.y));
+}
+
+pen p=rgb(0.2,0.5,0.7);
+
+// surface only
+//draw(surface(f,(0,0),(2pi,2pi),30,15));
+
+// mesh only
+//draw(surface(f,(0,0),(2pi,2pi),30,15),nullpen,meshpen=p);
+
+// surface & mesh
+draw(surface(f,(0,0),(2pi,2pi),30,15),lightgray,meshpen=p);
diff --git a/Build/source/utils/asymptote/examples/partialsurface.asy b/Build/source/utils/asymptote/examples/partialsurface.asy
new file mode 100644
index 00000000000..2e8ad34d834
--- /dev/null
+++ b/Build/source/utils/asymptote/examples/partialsurface.asy
@@ -0,0 +1,29 @@
+import graph3;
+import palette;
+
+size(0,300);
+currentprojection=perspective(3,-2,2);
+
+real V(real r) {return r^4-r^2;}
+real V(pair pos) {return V(abs(pos));}
+
+real R=1/sqrt(2);
+real z=-0.2;
+
+bool active(pair pos) {return abs(pos) < R;}
+bool above(pair pos) {return V(pos) >= z;}
+
+pair a=(-1.5,-1);
+pair b=(0.5,1);
+real f=1.2;
+
+draw(plane(f*(b.x-a.x,0,z),(0,f*(b.y-a.y),z),(a.x,a.y,z)),
+ lightgrey+opacity(0.5));
+
+surface s=surface(V,a,b,40,Spline,active);
+draw(s,mean(palette(s.map(new real(triple v) {
+ return above((v.x,v.y)) ? 1 : 0;}),
+ new pen[] {lightblue,lightgreen})),black);
+
+xaxis3(Label("$\phi^\dagger\phi$",1),red,Arrow3);
+zaxis3(Label("$V(\phi^\dagger\phi)$",1),0,0.3,red,Arrow3);
diff --git a/Build/source/utils/asymptote/examples/pdb.asy b/Build/source/utils/asymptote/examples/pdb.asy
new file mode 100644
index 00000000000..bef21dc2277
--- /dev/null
+++ b/Build/source/utils/asymptote/examples/pdb.asy
@@ -0,0 +1,157 @@
+import three;
+import cpkcolors;
+
+// A sample Protein Data Bank file for this example is available from
+// http://ndbserver.rutgers.edu/ftp/NDB/coordinates/na-biol/100d.pdb1
+
+bool getviews=true;
+
+currentlight=adobe;
+//currentlight=nolight;
+
+size(200);
+currentprojection=perspective(30,30,15);
+
+// Uncomment this line for more accurate (but slower) PDF rendering
+//dotgranularity=0;
+
+pen chainpen=green;
+pen hetpen=purple;
+
+string filename="100d.pdb1";
+//string filename=getstring("filename");
+
+string prefix=stripextension(filename);
+file data=input(filename);
+
+pen color(string e)
+{
+ e=replace(e," ","");
+ int n=length(e);
+ if(n < 1) return currentpen;
+ if(n > 1) e=substr(e,0,1)+downcase(substr(e,1,n-1));
+ int index=find(Element == e);
+ if(index < 0) return currentpen;
+ return rgb(Hexcolor[index]);
+}
+
+// ATOM
+string[] name,altLoc,resName,chainID,iCode,element,charge;
+int[] serial,resSeq;
+real[][] occupancy,tempFactor;
+
+bool newchain=true;
+
+struct bond
+{
+ int i,j;
+ void operator init(int i, int j) {
+ this.i=i;
+ this.j=j;
+ }
+}
+
+bond[] bonds;
+
+struct atom
+{
+ string name;
+ triple v;
+ void operator init(string name, triple v) {
+ this.name=name;
+ this.v=v;
+ }
+}
+
+struct chain
+{
+ int[] serial;
+ atom[] a;
+}
+
+int[] serials;
+chain[] chains;
+atom[] atoms;
+
+while(true) {
+ string line=data;
+ if(eof(data)) break;
+ string record=replace(substr(line,0,6)," ","");
+ if(record == "TER") {newchain=true; continue;}
+ bool ATOM=record == "ATOM";
+ bool HETATOM=record == "HETATM";
+ int serial;
+
+ atom a;
+ if(ATOM || HETATOM) {
+ serial=(int) substr(line,6,5);
+ a.name=substr(line,76,2);
+ a.v=((real) substr(line,30,8),
+ (real) substr(line,38,8),
+ (real) substr(line,46,8));
+ }
+ if(ATOM) {
+ if(newchain) {
+ chains.push(new chain);
+ newchain=false;
+ }
+ chain c=chains[chains.length-1];
+ c.serial.push(serial);
+ c.a.push(a);
+ continue;
+ }
+ if(HETATOM) {
+ serials.push(serial);
+ atoms.push(a);
+ }
+ if(record == "CONECT") {
+ int k=0;
+ int i=(int) substr(line,6,5);
+ while(true) {
+ string s=replace(substr(line,11+k,5)," ","");
+ if(s == "") break;
+ k += 5;
+ int j=(int) s;
+ if(j <= i) continue;
+ bonds.push(bond(i,j));
+ }
+ }
+}
+
+write("Number of atomic chains: ",chains.length);
+
+int natoms;
+for(chain c : chains) {
+ for(int i=0; i < c.a.length-1; ++i)
+ draw(c.a[i].v--c.a[i+1].v,chainpen,currentlight);
+ for(atom a : c.a)
+ dot(a.v,color(a.name),currentlight);
+ natoms += c.a.length;
+}
+
+write("Number of chained atoms: ",natoms);
+write("Number of hetero atoms: ",atoms.length);
+
+for(atom h : atoms)
+ dot(h.v,color(h.name),currentlight);
+
+write("Number of hetero bonds: ",bonds.length);
+
+for(bond b : bonds) {
+ triple v(int i) {return atoms[find(serials == i)].v;}
+ draw(v(b.i)--v(b.j),hetpen,currentlight);
+}
+
+string options;
+string viewfilename=prefix+".views";
+
+if(!error(input(viewfilename,check=false)))
+ options="3Dviews="+viewfilename;
+
+if(getviews) {
+ picture pic;
+ add(pic,embed("label",currentpicture,options=options),(0,0),N);
+ label(pic,cameralink("label"),(0,0),S,fontsize(12pt));
+ shipout(prefix,pic,options=options);
+} else
+ shipout(prefix,options=options);
diff --git a/Build/source/utils/asymptote/examples/phase.asy b/Build/source/utils/asymptote/examples/phase.asy
new file mode 100644
index 00000000000..7256ffc515c
--- /dev/null
+++ b/Build/source/utils/asymptote/examples/phase.asy
@@ -0,0 +1,18 @@
+import graph;
+size(8cm,6cm,IgnoreAspect);
+
+pair S0=(4,0.2);
+pair S1=(2,3);
+pair S8=(0.5,0);
+
+xaxis("$S$");
+yaxis(Label("$I$",0.5));
+
+draw(S0{curl 0}..tension 1.5..S1{W}..tension 1.5..{curl 0}S8,Arrow(Fill,0.4));
+draw((S1.x,0)..S1,dashed);
+draw((0,S1.y)..S1,dotted);
+
+labelx("$\frac{\gamma}{\beta}$",S1.x);
+labelx("$S_\infty$",S8.x);
+labely("$I_{\max}$",S1.y);
+
diff --git a/Build/source/utils/asymptote/examples/piicon.eps b/Build/source/utils/asymptote/examples/piicon.eps
new file mode 100644
index 00000000000..56bf59bde96
--- /dev/null
+++ b/Build/source/utils/asymptote/examples/piicon.eps
@@ -0,0 +1,1135 @@
+%!PS-Adobe-3.0 EPSF-3.0
+%%BoundingBox: 0 0 147 144
+%%HiResBoundingBox: 0.000000 0.000000 147.000000 144.000000
+%.........................................
+%%Creator: AFPL Ghostscript 814 (epswrite)
+%%CreationDate: 2005/05/07 23:32:22
+%%DocumentData: Clean7Bit
+%%LanguageLevel: 2
+%%EndComments
+%%BeginProlog
+% This copyright applies to everything between here and the %%EndProlog:
+% Copyright (C) 2004 artofcode LLC, Benicia, CA. All rights reserved.
+%%BeginResource: procset GS_epswrite_2_0_1001
+/GS_epswrite_2_0_1001 80 dict dup begin
+/PageSize 2 array def/setpagesize{ PageSize aload pop 3 index eq exch
+4 index eq and{ pop pop pop}{ PageSize dup 1
+5 -1 roll put 0 4 -1 roll put dup null eq {false} {dup where} ifelse{ exch get exec}
+{ pop/setpagedevice where
+{ pop 1 dict dup /PageSize PageSize put setpagedevice}
+{ /setpage where{ pop PageSize aload pop pageparams 3 {exch pop} repeat
+setpage}if}ifelse}ifelse}ifelse} bind def
+/!{bind def}bind def/#{load def}!/N/counttomark #
+/rG{3{3 -1 roll 255 div}repeat setrgbcolor}!/G{255 div setgray}!/K{0 G}!
+/r6{dup 3 -1 roll rG}!/r5{dup 3 1 roll rG}!/r3{dup rG}!
+/w/setlinewidth #/J/setlinecap #
+/j/setlinejoin #/M/setmiterlimit #/d/setdash #/i/setflat #
+/m/moveto #/l/lineto #/c/rcurveto #
+/p{N 2 idiv{N -2 roll rlineto}repeat}!
+/P{N 0 gt{N -2 roll moveto p}if}!
+/h{p closepath}!/H{P closepath}!
+/lx{0 rlineto}!/ly{0 exch rlineto}!/v{0 0 6 2 roll c}!/y{2 copy c}!
+/re{4 -2 roll m exch dup lx exch ly neg lx h}!
+/^{3 index neg 3 index neg}!
+/f{P fill}!/f*{P eofill}!/s{H stroke}!/S{P stroke}!
+/q/gsave #/Q/grestore #/rf{re fill}!
+/Y{P clip newpath}!/Y*{P eoclip newpath}!/rY{re Y}!
+/|={pop exch 4 1 roll 1 array astore cvx 3 array astore cvx exch 1 index def exec}!
+/|{exch string readstring |=}!
+/+{dup type/nametype eq{2 index 7 add -3 bitshift 2 index mul}if}!
+/@/currentfile #/${+ @ |}!
+/B{{2 copy string{readstring pop}aload pop 4 array astore cvx
+3 1 roll}repeat pop pop true}!
+/Ix{[1 0 0 1 11 -2 roll exch neg exch neg]exch}!
+/,{true exch Ix imagemask}!/If{false exch Ix imagemask}!/I{exch Ix image}!
+/Ic{exch Ix false 3 colorimage}!
+/F{/Columns counttomark 3 add -2 roll/Rows exch/K -1/BlackIs1 true>>
+/CCITTFaxDecode filter}!/FX{<</EndOfBlock false F}!
+/X{/ASCII85Decode filter}!/@X{@ X}!/&2{2 index 2 index}!
+/@F{@ &2<<F}!/@C{@X &2 FX}!
+/$X{+ @X |}!/&4{4 index 4 index}!/$F{+ @ &4<<F |}!/$C{+ @X &4 FX |}!
+/IC{3 1 roll 10 dict begin 1{/ImageType/Interpolate/Decode/DataSource
+/ImageMatrix/BitsPerComponent/Height/Width}{exch def}forall
+currentdict end image}!
+/~{@ read {pop} if}!
+end readonly def
+%%EndResource
+/pagesave null def
+%%EndProlog
+%%Page: 1 1
+%%BeginPageSetup
+GS_epswrite_2_0_1001 begin
+/pagesave save store 197 dict begin
+0.1 0.1 scale
+%%EndPageSetup
+gsave mark
+Q q
+0 0 250000 250000 re
+Y
+q[1470 0 0 1440 0 0]concat
+147 144 8[147 0 0 -144 0 144]@X false 3
+colorimage
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W,urr2rts7Z*U`K_\Jms=`eDnV)BF^#aQnF?PYs8N#ss8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W,urr2rts6f@F>Y#U0HO],N3WK,=
+aI!gMUk8XHs8;cjs8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!rr2oss8Vfco#@%As6tC0iGZDf&oh%mnF5uJs8W)trr<#u
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+rr2oss8VNUn6AL!Wd>3;]fH,mNQ@M*[&/KUs8W#oqZ$Tqs8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8N#ss8W,mo^^"g,QI7\
+pYfu%M\9r3)=[.cs8W,urr2rts8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8N#ss8W,en*jRQ'rlTik.NeTs,G-g)7QPss8W,sr;-Hns8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W)trr<#up@\!rR3_h&IJ;Z3]S[5<=;p\unc/Xhrr2oss8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W)trr<#umdKXM8/8.O%Hb>a
+s8S)$RMiW6KE(uOr;?Eks8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W,urr)lss7,UF`0_bKnUC5hB"Ea,CfVJCnF?PYs8N#s
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W,urr2rts6f@F>Y#U0HO],N3WK,=c(,`_W.Y-Ms8;fks8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!r;6?js8T$jM6ML5
+s7h<Ag1@gL%Vo&_n*olIs8W)trr<#us8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!rr2oss8VNUn6AL!Wd>3;]fH,mNm4+4\Z1;^s8W#pqZ$Tq
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8;cjs8W+uSV"1u"981Qp"EibL(8$")Xm1cs8W,urr2rts8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8N#ss8W,en*jRQ'rlWj
+k.<YRs,kQt)S)l#s8W,sr;-Hns8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W#oqZ$TqXeLKXJcu,LM"95+\:kE.<>t>qnc/Xh
+rr2oss8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W)trr<#un*faK8/8+O%Hb;`s8S5+Sf5/>KE(uOr;?Eks8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W,sqtg?ms0/;O
+\:Y"cq2+[p?FGLsAPsH7n+$GXs8N#ss8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W,urr2rts6oFG=\9F.HO],L3WK,Ac(5iaWe:?Os8;fk
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!r;6?js8T@"K=HXAs8.]Fe6]J7%:`6Rn*ffHs8W)trr<#us8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!rr2oss8VQVn5r3r
+WI,0;]K-#lOj0I9\>k2]s8W#pqZ$Tqs8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8;cjs8W,+Vh;O:#ljd[o$gmNK+2?f)Xm.b
+s8W,urr2rts8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8N#ss8W,emdO4H'rlWjk.<YRs,kTu)S<#%s8W,sr;-Hns8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W#oqZ$Tq
+[&8YhL^O1ZN:PJ$["Aiu:E&]jnc/Xhrr2oss8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W)trr<#umdBRE7hr%O%Hb8_s8S5,Sf5;BKE(uO
+r;?Eks8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W,sr;-Hns0en]\qpdor/C3r=gWek@87[-n*pAWs8N#ss8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W,urr2rts6f=E
+<C[e(Hk#5M3WK,AcCPreWe:?Os8;fks8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!r;?Eks8TU.L:`?Ns8@oIdoj&2%U_sH
+mdBQDs8W)trr<#us8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W)trr<#u
+rr2opr;-BiqYg?grVcZnrr2orrr<#urr2oss8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!rr2oss8VNTn5VsnWdG9<]K-#lOj9O:]W6\bs8W#pqZ$Tqs8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8;fk
+s8W,/X+n6H$NL'ao$^[IK+;9_([g_[s8W,urr2rts8W-!s8W-!s8W-!s8W-!s8W,urr2rts8N#s
+rr2orrr2rts8W)ts8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8N#srr2oss8W&qqu-Kks8W,urr2rts8N#ss8W,urqu`mqYgBjs8N#srr;usrr<#u
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8N#ss8W,emdO4H'rlWjk.<YRs,kTu)SE,'
+s8W,sr;-Hns8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W#pqZ$Tq];p\$NXPmdORpn"[=Jco8f-m_n,NFfrr2oss8W-!s8W-!
+s8W-!s8W,urr2ors8W,trVQQlr;ZfsrVZNjrVZZorr2ors8W,urr2rts8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W,urr2rts8N#sr;?Hls8Vcao#.kmf=m!]Z$Y9R\G>pq
+q"OL^s8W)ts8N#qrVZNkrr2rts8W-!s8W)us8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W)trr<#u
+mdBRE7hr%O%Hb5^s8S5,Sf58BKE(uOr;?Eks8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W,sr;-Hns1PLg^lAj'rfH^!;71rb
+>"KOtmdL2Us8N#ss8W-!s8W-!s8W-!s8N#srr2rts8Doos8W,pq"XIOnc&Oes8W,urr2lpr;Q]p
+s8W,urr2rts8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8N#ss8W,urr2inqu?]r
+e^;=:O@[*C#j/r`gUJuhW@c,U+j$NXcF8GTb-h9Ls8N#srr2oqrVQTnrVuots8W-!s8N&us8W-!
+s8W-!s8W-!s8W-!s8W,urr2rts6f=E<C[e(Hk#5N3WK,AcCPreX+UHPs8;fks8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+r;?Eks8Ta6L;T#[s8A#Icr%&u%Tu@>mI'HCs8W)trr2orrVc`prr2orrr2orrr2opr;-Hns5;SM
+W/jN?H6LM?I,NShp\=X`r;?QnrVlfprr2orrr2orrr2orrr2orrr2orrr2orrr2orrr2orrr2or
+rr2orrr2orrr)fpr;?Hks8UBc[W>CRY'^QLb=)C-KDtn7rr%fUomcYi?/2nBaI!gkX&RWbP4J,-
+s8W,urr2loqYpKmrr2orrr2orrr2orrr2orrr2orrr2orrVc]ps8VKSmo2alWI#*9]/fokOj0I9
+]W6\bs8Vunq>UBmrr2orrr2orrr2orrr2orrr2orrr2orrr2orrr2orrr2orrr2orrr2orrr2or
+s8W,urr2rts8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W)trr<#u
+rr2orrr2inrV?9dqYL-dqY^3dr:p$\s8W,1WeA<O%0-9ema"b6J.>aR)!L5Os8N&oq>:*frVuot
+rr2oss8W)trr)fns8W,Ncb"mA$aYEkeY+,8TbP\<)Ph]tfZpl(s8W)trVlfqs8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W,urr2rtrr2rtLO3$79*'r`'<[$.e"nGHX=E,2/a^D>
+q:]3Unp:<7PQ1T?p#0?8ZR<h`-e,h`o^_GMs8W,urr2ors8W-!s8W-!s8W-!s8W-!s8W-!s8N#s
+s8W,emdO7J's2oolG#@Zs-(m))SW>+s8W,sr;-Hns8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8N#ss8W,urr2cjr;6Birr2oss8W)trr<#us8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8N#ss8W,urr2flrVHBgrr2oss8W)trr<#us8W-!s8W#pqZ$Tq]W?k*NXYscORCCk
+YCI*d7i:X]nGiOgs8W,oq"O=Kn+-&>o()>@nF-)FqqTW1F&`O)B+)>2*o<b=s5@8`q1\@a9>Q]#
+]:W6to_%S<p@@bCnaZ5@nal>AoC;ABnaZ2?nac5?oC;ABnaZ5@nal;@oC;ABnF,oBq>SUV[:)N-
+E`Wm0AdOT:%\n=^UNmEJHk3Z@'ul@Sd@MH?ZS;$t;#^!3s8S>]np'3-0ufP*`3P'Zl1=B4p[RbB
+nF,u<nFQ/<oC25?nF,r;n+,r9nauJIi8EZl5o-)7%G@pDq!s?[PT$g#IJWmAmd9H3n+,u:o'l,=
+nF,u<nFQ/=oC28@nF6&=nFQ/=oC28@nF6)?nal;@oC;AAo()DOrr2rts8;fnrVc`qs8W)trr<#u
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!rr2oss8W)trqlTkr;?Nns8W#pr;6Bf['[qoE2%]+Y'G;r
+H$QT=GcQ(9]Qn6tcC,CGqMjmd:U5T`903c%D52E'YC_A85X:#'!)a+0?3^^A#7"N>#[dc<9`P/i
+82VZWE!3_/);D2CpYTEZs-!?MHJ>GCT6M/$,>naPEs`7b#RP/M$"jPNBF5)]$41MT$#U%VE!Zki
+#mtVY$?-=ZE!cqk$Oh%[#@R`=@fusG1FPUr6kW`o&5"nk<'Lt1:C2GR!0qL-Xah(uN#0m5*p^L#
+r9//#s-NQGDq:a!LLVnJ&pY'(KbG/G&JKL('71?*HP.!?&efa-'7LQ.Ih<<B#mkV]$uumjF:o74
+%h<Ui%sS^$J.`NE&efa-'7UW.IM*<@&JKL&'719&HOpa7&.j.!&:+itH4:@.$Oq.b%<2XZD%R@r
+BkaEN[E\aOrqlTkrr2oss8W)trr<#us8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W,urr2orrr<#uqtp<hr;HWorr<#u
+[C+4lBqlI^I0p@7$k&18)PJ8rX!8mn-Rl;A,f*DI@+Cn_s7hT@b>5Bo"'A6.,q?__0!QoXZ8FPT
+5=!CS4ioiOaZr275XELY7*J"ec::CNA5uNZ@L&o^&BBqNkIWSLoRQu<Ms.Z'Nb8PV2O@-5i(Qhj
+92*f/9[up6ePAul:J]P;:tAH?ek]/o:f?(L<8LYThGmP2=BOQb=lNLbiDEY=>[?&i?J/OffN__@
+=&uD3>)6Tc;dr?&Kk(@ZGSIQ>(!rBfm__3foR[#APk)s^TlguM;P@/qpKq:g?XN#)?ftg(k[7c^
+?si/+?g1s*l!n2h@:AM1@-h9.l=")e@:8A.?g(m)l!Rl_?si/+?g1s*kZqKW?!c`$?fta%jBc-Q
+>@$>q?0,6oi)a%=<E7mP:tSB5eLN2Z#7#oS8s&oGqYgBlrr2orrr2rts8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8N#s
+s8W,urr2cjr;HTns8W)2][Ai&N!'<7,:0Nr=Q!k+n8E:=B4pO;@-1HkhcEt;;HWF)>BA5a&-)Hc
+m`JD/IfNnVGuI`/='!jO<S:2HfM#&j8l!i-:=Dj2dS!<_92*c,9[-1&cU1(K3Ac@g57<Ec&$gg$
+hPqt%nU:H1K\WI?M/5XK7aFLmb="eB6UT$a6cVP^_a$Q+5XN@R6Gl#S_`^9'4[?tL5fGlO`B?K)
+4?pbH4Mj9E^,nBl4$(2?42Ep<^,J'i2`f/;1r(1TFs\7t9f`]/?3m*F'tK/8go)FniFW&hQM]E6
+_iY[28s(GN^b[jU0Jg0m1Uf%o[kKVI0Jg0l1Uf%o[P0MG0Jg-l1U\tn[P0MH0f-9m1Uf%o[kT\J
+0Jg0k1:Akm[PTkM1c;]u27GJ%[l?CZ3BFc53kmg@_EC0&5=37R7*&V=hfEl5(Drl87ZRNKrr2os
+rr2oss8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!rr2oss8W-!s8DoqqYL-is8TmMdlKOH"9sK=42c#SojhY!5=!(,+J&rNL^=B=
+"pf__#C6U\FoVMo6SUs]V&01,N:"\]Z%WWP1+N>)Gm4It"9`rM"*aeIGQ7eh!!%'?!H8#?E<#uW
+!!$s<!,quBFTVhu!X3]q+XhSA$F5="i3=g4r/LO2E6=FM4"NAl!-ePIDu]o[!!.-@!HS5AEW?,\
+!!.*?!HS5@E<#uV!!$a6!,DQ7BE/$I!!$d7!,qo<D?'ZP!!$g8!,DQ7B`J-G!<Hs>"aC(OJcl3V
+*uZ5(6j\lj(9`B-c^GgHdo$/FQi,]C]8-h:(et&2C]OQF!!$L/!+Q!/@fQL=!!$L/!+#X*?N:(;
+!!$U2!+Gp.?iU1:!!$L/!+Z'0@fQLB!!$j9!,MW8C]FHO!!$g8!,MW8CB+?M!!$m:!,qo<EW?,\
+!!$m<"*uj`[rHKc'c)n;ZHW@Ks8;fns8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W)trr2ors8W,rqu$Kos7GpVI=/(##^@jO[W$6\
+>@->9-`I7RIK0@a!!$L/!*K:%9E5&V!!#1a!B^>^4?tPDfqoeipPA4X9X'0_82q"X!&O]V3<0%=
+!!"tY!&srY2ZNhN!!#Oi!'pSb8cSic!!#Uk!&srY2#mV<!!"qZ!"<O7$,;H8mDqcss.Ao+9<3IT
+*#1F5!&=QU0E;),!!"\Q!&+BQ0E;),!!"\Q!&"<P0`V2?!<>=m$qL@!63%!O!!"YP!%n6O/cYl(
+!!"VO!&"<P/H>c#!!"DI!%%[G0`V2(!!!*B&ccfF#H!"had!_:bt7s7PPsBC]8I7J*BFZB<t5[/
+%Lu&?%S7-?8.Q5'*$&8u(Kq7U5Re,d&e[tS(0(eQ7h-##%Lu,B%o3E849,@0!!"ML!%S$L.f]Q"
+!!"VO!&"<P0E;)+!!"YP!&4HR2ZNhQ!!$F-!-h%+bYCse6q!:>s8W)ts8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!rr2oss8W)trqu]m
+rVc]fp%LmEOT>N<@V"b>C[`c&XT8NN!!$j:!au'/57%WU"pQeO7UM"/SUGpLJ:E`3Jsq7/:=#@E
+s7qH<a\/dg&5GG&F*34hJs(V5O+2Y?J:N`1J<Nhn+*V<OJq@0H=sm-/(+ggOG^5$pJW5//MLU,4
+JqTY$=A+-K"43JVq;Q&eq30^=,Bd6-GBo-uJW##-M1:#1It*6'ItrN'LOXf.JV&c(GC<@N'7OXI
+kN7D@?Q_s#'RG(TJUrQ*ItN6#KR\K)It*-$ItN6#K7AB'It**#It<-#Jp_s$L51Xs>=Da]!2b5a
+a,q/2b";X5QMB08["Ah-^T@>2s6oCCnaZ/@oCV;3lCaJn`N+"5[QaEQHIT6#cH!Njq"jLKn*f`6
+qYL&u\@Qj,H@^X$It**#ItN6#K7AB(It*-$ItrN'LOXf/JUrc+HA<"A2uiqQ!!$dP)OG/PnLH,\
+jlPe-s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W)trr<#urVc`lqY^Bns08iO"U/fr0=5tKr('E(#RQ4c!,;Q:@K6Bm!!"3,5$#M9`:s#u
+p@e.Ys8W)trqu]js8W,5Y(afT%KH?]m`A,)J.GXK([UPXs8W,urr2oqr;Zfskhj>,T,7P%HN3V^
+jKB\[?N?adJH,ZLr;6Bjrr2orrr<#up\F`3C.FJ%"Q6L7s88&Oem,J3&Du0[s8W,trVZ]qs8W-!
+s8W-!s8W&qqZ$Tq`jh8JL]mbHEW>ZZhk_-FC)ld6o)Jairr2oss8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W)trr<#uq"aeq>YA-]!2k>daHRP9cqOK>QhAd'X*bE-d(o\]s8;fls8W,dmdX4=%B+CL
+l+f=Zs,kEi&@A3Ys8W,sqtg?ms8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W)trqcKf
+s8W+EH$fSl-3OH]!WmaU?f<Uk\UK"2s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!rr2oss8W&rrqlTks8W,'Yg!1LGY1TUF*%%%.B3@JEWQ;U
+!<Gsr!%C)q;o$2as8W&rrVliss8;fnq>'m`qYU'^pAb0m\u^P&Nt)-eL[N8WY^d6b72G(Mm/R+c
+q"XX`s8VWYm\kRKnBao0qiTmA0Vit)@8.^)l0SHMs7uKdqYL'bqYKs\p](9n]=b^g:CY.#')(@"
+s7VAhOq<Y!7J6EQqtp6cq>0saqYL'bq>'jcrr;6Jl\K6lgSu_&r/U3h9:Tl#Wh>+Hs8VlgpA4X^
+qYL'bqYL'bqYL'bqYL'bqYL'bqYL'bqYL'bqYL$`q>UBlq"jkt>YA9c!3(MgcBfFDd8L#ERHqjU
+a.Pp"r;QZnqu?]rmdKUO9GsmY&EUSds8S)"R2`N2L&_2Qqtp3frVlfqrqu]lq>'m`qYL'bqYL'b
+qYL'bqYL'bqYL'bqYL'bqYKs\q#CBo\@B$K!%%^H=9&>@7S(Z_43`/$\,ZL.s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W)trr<#urVc]nrVl`mqaa86
+"9a9`@-D68lkUJ-!!$d;"ChH54:)<BZ*C\9s8W)trqu]lqtp<jrr2orrr<#urr2opr;-Hns1GIf
+_iG9,r.j^_8[*aV<CI_imI1)Ts8Mupp\F^!Sl=[Y/H>a8p!$4PP8\L?!0rXrs8W,rqtg<krr2or
+rr2oss8VunqZ$TqW1Sd0B)q><70!:TjgR(-CDZI/n,NFfrr2orrr2orrqu]ks8W,#TnT@e!;kY`
+s7_6"V&tA$(?t)Js8W,urr)lss8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!rr2oss8W&rrVlfp
+q"jl#?V4iu!N^klc^>[GfNA1RRd7jLcDX_<qu$Kos6f@D>tPm4HO],N3WK,=aI*pPVM"pKs8;cj
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!rr2orrr2rts7#OH%1Off!)3FnD)OAd
+:/9V78<j/Sr;Zfss8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+rr2oss8W&rrVc]orVZU]6])6ZMf<S-<E@c\$\n]^C'=cD!!!p193V#]o`"jhr;?KiqtpBlrr<#u
+rr2oss8W-!s8W-!r;?Eks8Ta5L;&ZVs87Q<btP?m%p2:;m-X<Bs8N&us1kgl_MnZtqM>(1CsSLg
+P&(Lo2&#6>mJm4drr2lqrr2rts8W-!rr2orrr2rts6T+;N,'6\U`]X5NUkIsW-Jfub.RcSs8Doo
+rr2orrr2rts6Aq;L1_O^W?_H@MY,G"XaC;%E(Kp*s8W,urr2orrr2rts8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!rr2oss8W&rrVc]nqtp:r<C:Cl!j@4pd$l$Nfj"LVRcM+9aei#:s8VQVmTiBu
+Wd>3;]fH,mNQIS+[]"iYs8W#pqZ$Tqs8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8N#s
+rVc]ps8VHPl3n(H!!#[m!,aeY^JRqd%M3:BnF-DWs8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W)trr<#urVc]nrVl`mr'Ec3&JLRYHMp?*c3"5t!!$[4!)<n007SJ.
+oCMMPs8Vunqu6Tos8W,urr2rts8W-!s8W-!s8W-!s8;fks8W,1X+n6E%0-6Xm`eG/J.GgS([LGT
+s8W,Jc+L?8')LQps7hK1W[=Zo'j='8[^NOBs8W&qr;Q]prr2oss8W-!s8N#srr2oss8VNUno7hS
+`0(c2m!A^"I'S5%Xe'k=s8W&qqYpKnr;?Hls8T*kKr&hjr8(c[pkIS*-@oJ._n`e^s8W#pr;Q]p
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!rr2oss8Vunqu?]r]"5Hs(]ekb%BP1!
+d[M3PhIHTcS`774c`:46m-\1O(92]ik.NeTs,P9l)7ZYus8W,sr;-Hns8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W,urr2rts8Dops8W,gnF$hs0E;)O!!%1B<SB8f_g-O6s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!rr2oss8W&rrVc]or;?I[6^&K0Uj77b
+4$CC\!d=\IB)hp$!s9RN[(-/9s8)TgrVc]ps8W-!s8N#ss8W,urr2rts8N#srr2orrr2flq>^Kp
+\>b1oM@BO^J*tTSZ@NNi8J^[[mem(aZB.H3ZRPqSRIA!Z^Ps+;5lch"J,fQKqYL'gs8W)trr<#u
+s8W-!s8W-!s8N#sr;?Eks8T3pJ"^f]o\!IKqN0:(+FIZ@mdTfIs8W&rrVuotlg*qmBcZ!.,QI\"
+o[['HIKkXP9)JSes8Murrr2orrr<#us8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+rr2oss8Vunqu?]r['[1f)Zk7f%BP0ueY+&]iFr8kSEIXB]9u/m8K+XW%Hb5]s8S5+Sf52>KE(uO
+qtp3grr2orrr2orrr2orrr2orrr2orrr2orrr2orrr)fpqYL*bq>:$bqu?]rZEgh;!'1)[A.9'/
+DJo"\(RobuV>pSqs8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W)trr<#u
+rVc]nrVl`mqa3c9+<dh2H2]NR[K$;J!s3!7!^?tt,dXhas8W,oq"Xjfrr<#us8W,urr2orrqu]l
+q>'paqY^3dr;Q]ps8W,sqtg?ms0nq^\:k4gpNH,Q9=9?^>Y#S&qZ"L?L;o;Zs87ZNk%iJ;)hqf*
+Cgfj1qu-Qps82]kqtp<ks8W)trr2orr;?Nhq>:$br:]jYs8W+dP_Xos!:%?^s8SJL]fVd0([UMR
+rVccjp\4^fs/DZGTPso+g0agQM:ngTHs$Zj^:4.Bs7lBbqYL*cqYU-cqtg0dqYL*cqYU-cr;HTn
+s8W-!s8W-!s8DoqqYL*cqYU-cqtg0dqYL*cqY^'\p](9nYHP2T)$"h_$a,1!eY+&\i+E#hRcqUL
+Tlpp:FV3lN2#mT7e"RhqXb6ZRs8;fks8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8N#s
+rVc`qs8TF3]*&6j!!$4'!I%./cXg\T!<R/J\&\OKs8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!rr2oss8W&rrVc]or;?FZ7$]&DZ#t9g.P._&!,r)FAcMf`91rXbp%84]rVZTk
+s8W,urr2lprqcKgr;?Nns8W)trr2ors8W,urr2N[oCDJDn*f`Ds8T3nJ$st7s7'mrbtGBq%r#&d
+^q-VRL)oX1>kIE=etXXcGSa(7#.(\Cs8W,dmI'cEq#CBorr2oqrVl`mrVuotrr2oss8W)trr<#u
+o()=,Bc#3g)?9Ggr7u%^Er`D@N;rqXs8W,Vf<hl<&G=7,s8S;]i(pn:!1SdDs8W-!rr2orrr<#u
+s8W-!s8W-!s8W-!rr2oss8W)trqu]ms8W,sr;HWorr<#urr2oss8W-!s8W-!s8W-!s8W#pr;Zfs
+`lGta3"1:F$a#+!etO5_i+2lfQhAa!Wd5,pTIp3DPKK@5\#4QMrr;KVmIKi=o()ABo(2GCoCDJD
+o()DCo(2GCo^VJDoCM\AlgKIYRtcWq7RhP$!(?kfB+,3*923fQEqKtTP<hKcs8W,urr2rts8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W)trr<#urVc]nrVl`mr'No<-7H0BGk`U7WW3$:
+"U/B9!%^`7>5S3ns8W,rqtpEns82]kr;?Nns8W-!s7Z0\qYL)u\&`T1S:5phF*"8h%UfMF@gWNR
+!<[3m,<*T+'*%0%o#aD2L^um0.f]QS#R+E>$>9_M@0H[;!!$:,"'uHICBk)U!<HCc3d\`\cN!qE
+qtp?ls8972b\qHrH@)];H)c7>X))^Q;*HGFN=PX@C]F!]aHI'dE`m^:[!-\f75Ql37kf=2@s`K=
+D,NGY.4.ndF+].PH$Q65H_l(9V0mWdI!_];I&24<VL!QaJqC#glgb#Ts8DoqrVc]]m-TIZUO.?a
+I!hf=I&24<VgEchH[D]<H`2+2UQ(8G2E,1l(]\tl$*/Xoe=I`Xh-L'\Qh&U*_3#M&O')Yl<!<@r
+#RFK:#?V6;=pPC;#7"Q?#[[fBAI&QR#7+rJ#\jVND$^Mi#mtYP!+,^+A,u^R&e^?f3kT0@n7?1s
+)B,"D!*m+Hc2[hDr;?Nns8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!rr2oss8W)trr<#u
+r;?I[7$Af>X`\mb-7>_l!,i#EA,lT[8kN4_qtg9irqu]lqtp?ir;HZqs8)TgkND5iMmGQ1L&_9h
+#mteT!-\VPM\d8)0JU'r35.F9_Dsd"7Rau!MBr5R8b0k_Z%O,m:<?%!g.=rf7nD'"9$p.$cpgUP
+7n:ff5fPrN`%s9b#ml(l%nQ*Tmf!+`9MC$<!-o(fRL^$q%M4j8&<I8/U,FT&V0N(+a%?=2RHM"3
+G?5F\#)i`kM[pGj#nEI-"criiNW]ZQ#nN=-$&JW^IK0A!!!%KK!.4bHHN4%n!!%?G!."VFHN=.o
+$4:gXYfZqFs0fDS#RF</!G)62H2mqj!!%<F!.+\GIfKJ!!!.TM!J:@PKFeZX)&no)1HB\_!NLYe
+d@2-NeQ2_MMY>OmV03;(/92j[[4!K*-n2;L/@$iZYV.Z:0f$9p1V#G(^,\9k4?peP7*.qicV73d
+>[?Au@d%B6l"Ol"AS1?i42D%'HiX7K[C"0Xs8W#prVuots8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8N#srr2oqrVl`mqEdN.)&]&jGlB*@XT/?="U/B9!%1B2<r;dkrVc]jq>:*frVlfq
+s8W,6^="r!Jcl6u"p]i--`p-=eR;qOCM`KZEV='[mo39=:/BA4:!lR,e4E6LY(@_e`&I(t0s6*O
+5XNFW7En1gb!eeC7nLlo8]jRqb=bLR92<r.9@%BjnjuL$!!$&WMPHE#YQ+Z.='=F$EV=*[nS;q3
+C2<<VDuNL+Vh\dhh5i"(r0$Zu=K[,^C1ObeC]%m[l=O\rB5$^JC@#VJl"4SlB4gIEC$o\MmqHP-
+Bkm-JB^fVJnRu\-Bkd!KB^BMOnL#`g%Luk=p%1jKCB+?=1c;dVBC'/>l!\/h@qG%>B'a)?l==Mk
+AnUIBB'j)=l=+8j?=)h_3C%[f!3(Dbb*<k2^c;5?:$Af*Vgogt@G,.#l<dr]?=)Yr>i8[dhH3k8
+;cMLK;UnQ>eOiQ`7nLom7`mq]`B$)p2)Vfs19_fDTEPLL!!$70#Z7t9`rH)=qYL*hs8W)trr<#u
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W,urr2rts7uKfs8W+FHDUlNKm7nC2)`#G!-&/G@fQKY
+8kN.^r;-?hrVHBfrr2oss8KaHe2]RF!!%'c-)t-PiG`c.@V+k!:!kaT\/l``',?T;%>P,lI0'Ot
+!!.$=!,VlBB:sJejKC,lX=LE*'I"Dq!!%*A!Gqf:E<#uT!!$d7!,DQ7C]FHN!<[aT?fj+"ZiC).
+<)e!38Uq'QM/-qt+<dE`#_Wd%NXuk`&/1*9'9d$(*6=BYqWN#"mt&fQ%8&ZN#S*C@(Q]CLQPUR,
+(E8\X)j_?[QPpj5*$(Lg*h+,iS/`T?*?^jk*h!rdSf8]C)&\fE=klG9cO:5#jQ,>8'Lr-'DbX$W
+;,Z![(RZ<fSfJoD*?L^h*LdlbQl$d/()`GS(mc!TOqeh!&/(9V*[u26$DVna]o3`RRiT\?+Ld1<
+75dsD#*B<'KaJ0>$4;Ci#_E6dI0Bh$"U02R!d4PDC]FHO!!$d7!,)?4@fQL>!!$"#!_WLn92/-#
+p%A%WrVcZlrVuotrr2orrr2rts8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8N#ss8W,sr;HZqs0oJ`
+$4MJuB^J;]c2[ig!s2s4!%gf8=oA3pqtp<gqu$Kork?+p3]`#r!-BP9Y@hS<Bl!3(6,a]\Qj*hH
+!!.*?!+Gp.>lXk"!!#1_!&srY0*__J%hDVJ$V>VH&&XSR_iu@EIh,OD)Z]q)&.Co/"#^Pr8Ic5)
+%Ll,D%o<6+<#m!KCi/eZ(7,"$7!!F"*?ArB-EC`km03fF!!$%"!'pSb4ok[M!!#P=*?qY;%HbAf
+s641OW?m+%'*&#1!!$1&!([(i7fWNZ!!#Oi!([(i8,rW\!!#Oi!(R"h8,rW^!!#pt!+,^+>Q=bE
+?<uVK27sY=EilIL!<Gam!dS-[juPQ:!!$1'!D<Cm8,rW\!!#Oi!([(i7fWN[!!#Ff!(6ee6N@*V
+!!#Rs!t/-m!ge!FWe)(lKGg(n#ppQ5!!#Cf!BpJ`4obRA!!"qX!&afW2?3_2#6mL*%TNuJ9b%Y-
+%Lu)B&4Qg,1dsiJOH?C(kiqs?q#CBor;?Kms8W)trr2ors8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W)trr2orrVc`nr;8cDNB]\LA7Y!1#_W3ZB)hon8kNLhr;-<fr;?Kjp%A#M8WEcNDCI'=
+BPR!ND"'AD\d8au!!$j9!+>j-9)nrK&.h>8"YN;8@Yor2It*B"G'pg0])):"nF?1*E^u4'!j74s
+P&D(04:H+,%VJ<4@9cLsoCVPAnFcJHhr!Ds"_'AK]O"t+!!%3U&m@Re?iU17:J]G6:X]:DD?pJ0
+H$P3tJsUt:PCS4TJUN3(A.cqK)W%PCbF9W?EY18]&N_TqI!_'.JXV+=Q[jUTJ:O/?J=M.?S:H-[
+J:O/=I[Z+MVFX3h!!"/B!)a::MIpMf)]YIi*+a24GlRh2&.st7BC$`aUBh-+I!h93JY%CARt-$Z
+J:O,>J=(k;R"0^SJ:O&<J=1q<Q[XCMKnc:":IccK!*))]>X8?o8fE&'Lk1,?It*N/Iuf)/Mgp58
+It*?,JVnVoHapSsqYL*Xn*ff:naZ/>naZ,<nEp#GpAb0ms8W)rr;HTmrVuots8W,urr2rts8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!rr2oss8Vojqu?]rG^-5%'UO&gr#?`K!!$a6!)+"<.dcWj
+r;?Qos8TC1bl\)c)]bV`B'a>NnMN8:#mu@d!,V]9=onag"9^YP7:)"8QKdYunaZ)Bp\+Xes8N#s
+s8W-!s8W#pr;Zfs^V76J3"8A6!\PMo(C^@@3rs,.;"jY[s8W,pq>:3ls+cB*!!$D2?/n:@a8c3N
+,U?'&E0^J(Eb&eJ1H)]B!*MlbDZBb8rr2rsrr2rtrr<#uIr7c?C'D/+)m4f.M/!bj/-)oKJcGcM
+r;6Bjrr2rts8W-!s8W-!s8W-!s8W-!rr2ooqu$Kos*fE]!!#S:-`Cj!o)JcB=BLQ5J<g089-kp\
+DK,:L!.T6<W;lntqYL-hrr2rts8W-!s8W-!s8W-!s8W-!s8W-!s8W)trr<#unF5t&KnPD@I$^%O
+lg3s;s8W)trr2ors8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8N#ss8W,sr;HKgqu-Km
+rr2oss8W)trr<#us8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W)trr<#ur;?Nns8TR;cO1/3
+CMN?)6H&p)EWH2E!!"=MZ*OE0s8W-!ZEhdV!-Ue#c#e%&5=!0p$\\Q\CB+?<!!#"k&O1erOR)5u
+q>'dbs8W)trr<#ur;?Nhq>0saqYBs`r;?Klrr2lprVc]nkj%MlM1pY:ItWAr]=YQNrr;ooqu-Kl
+qYL-is8R4aUAt:BD/Sqi,c1PA=?SfP&eS7\(78rUnJN75!!#97J;XC,s7Q'YqYL*`p\=dgs2Dme
+:cel1>RZ<u&m.C!2(B=-mHsoPs7uKeqYL*cqYU-cqtg0dqYL*cqYU-cqt^'bq>'pfs8>M\FoVMJ
+5XE@q?KD.eATMpQ.4J!l!*qE=[q0.;!!$PYI[gB;s7Q'ZqYL*cqYU-cqtg0dqYL*cqYU-cqtg0d
+qYL*cqYU*aqY^9hs8W,urr2rts8N#sqYL*cqYL'bqYL'bqYL'bqYL'bqYL'bq>'mbr;?Qnrr)fp
+rr2orrr2orrr)fprr2oss8W)trr<#us8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W,urr2orrr)fpr;?FU5E%]ga(8iI"p]\[!Fu014%i4Ms8W,ko^mQZV[Eod<`\*kC@<#YRfEG,
+!<HU/!'q2/5(A'CmHs9?s8W-!s8;fmqYL'erVlfqrr2ors8W,urr2rts8W-!rr2oss8W&rr;Q]p
+s8W,urr2orrr<#ur;?Klrr)iqrr<#uoCMSa%V$k6WG6/8%1S-o!(M6ZM]3UX/2"8;@HI[qIK0@9
+[^N^Gs8W#pr;Q]ps8W,sr;?Tps1Q"N1arhl.17jZ%CimQs8W,sr;?Qnrr2ors8W-!s8W-!s8W-!
+s8W,urr2orrr<#ul07=<$VCC!G[Fh;4?gR]!+N%2\f)Jb!!$_*9[QL-e,TJV\@BQYs8W#pr;Q]p
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!rr2oss8W)trqcKfqYL'cqtg<krVuots8W,urr2rts8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8N#ss8W,pq>:3ls*/dh',-[UGPiI'TE"t,!!#\(&1Hl1li7"b
+7Rht0!,l7QkZqNT#RZ=e!,;W><WE+K9hf*ho^i%[rVlfqqYL*frVc`prr<#urr2oss8W-!s8W-!
+s8W-!s8W-!s8N#ss8W-!s8W)trVHBeqYL'bqYC'er;Q]ps8W,sr;?Tps1,\]!!$A":=;p7eGoSa
++X(-2EK:)"@9H^g7nCi(!+lr\8b;QDs8W,urr2rts8N#ss8W,trVZ]qs5;kq^:h5Sq"ajcr;Q]p
+rr2rsrr2rts8W-!s8W-!s8W-!s8W-!s8W,qqYU<ms+cAu!!#J.*Lpn^nduP"():,VXK2C%8HAm<
+?=2eS3kkt,B(PWes8W,urr2rts8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W,urr2rts8;fns8W,.\'GEkK558l
+5siNj!-/)@>6"XM['[4?s8PDPK`hR1C2<9@=l'AgK)bmb!Wl.""!OtU\,ZL.rVc]kqYU6irVuot
+s8W,urr2rts8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8N#s
+qYL-is8R:eQiI,'B5-fe0s^i[?R[EuCi#=9!-W$iln:&r!!#c>H'\L1s82]krr2oss8W)trr2or
+s8W,sr;?Qnrr<#urr2opr;?Tps8N#srr2oss8W-!s8W-!s8W-!s8W-!s8N#srr2rts85>UC]FH>
+3BOo`A*EsnD-:"rIt)tK!'Lf%NFZVe+X<oj#>XdXmf3=erVc`qs8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+rr2orrr2lprqu]l5<k2o5fdGFl3.EC!Wcg3!'3_E>6"X$77E"<#_d28oM/33!sO2V!GVT78HT&8
+['[7@s8VrlqYgBks8W-!s8W)trr<#us8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W)trr<#uoCMMa&R67qSn`*4',?Z1!(:sPJg2LZ()`QVD=S>TOoPJM
+L5)#os8Vrlqu?]rs8W-!s8W)trr<#us8W,trVcZlr;Q]prr2oss8W)trr<#us8W-!s8W-!s8W-!
+s8W-!s8W)trr<#unaZ#W%7L6sFB;W#84h,-!)B#QYEkKQ!!#A-+.[7co*,MX6:,qss8Drrs8N#s
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W)trr<#uq>'pfs8R=gWtQ59G'<d&*M!01B`J-+$k+K_s7q(kW;lpE
+E,bJA9$dS?HNF4^!Wkar#plpa[/^1+q>'mdrr2rts8N#ss8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!rr2orrr2rts6Ak9"pSd(5/g]/hZ*Y!
+#R=(EEe+;p@lZTb>?p.f!-ASV;![H5s8W,trVlfqrr<#us8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!rr2opr;?Tps0oJO!!#b#$]/J.lm!dQ"U/6#mHR>;CB+?6
+/M=/CD=RZ,EIWJ:s8W,qqYU<ms8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!rr2oss8W#prVuot\$sZj%>8S7nNK1V
+!!%!>!F#O(+iVF:]tN&#"aXZgl;:I0!<RTL!bVK51eUJOp%@tUrVcZlr;Zfsrr2orrr2rts8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8N#s
+qYL*hs8Rb*VuQg3@q=gc42([p?n*X0F*!6>!+9,>j?c8T!!$OE'h@lenGiOgrr2oss8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!qYL'gs8RV"NrT/L
+-7>X*D=Io>MA6k-jQ,).&NKgkB0&/h?!ZCh!*al"PlLd`qYL*grr2rts8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8N#s
+rr2oqrVl`mr'*E*5![1t@d4+$J-#d_!!"oe@r&lqeGoSc:/KMN@d"%&K`V<g!!#;W8n%Voq>^Kp
+qtp9js8W)trr2ors8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W)trr2oss8W*c6@B:PNc8n.)B>4H!).`dOB,D>!!%RcC@3GuW;lok
+H?teTs8Vrlqu6Tos8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W)trr2oss8W$h8T4Y0=ueXT@:JI$!+pV+U&Y/l$O]Q,!,YS1e4E<\!!$<8\\nIIs8;fm
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W,urr2rts7uKgs8W+DGcDDkQ[!`O*$1[O!,2E58KAg)X/j)=!c:Csb\V1g
+&/1-*!,MW88J)O]mHs<@s8W#pr;Zfss8W,urr2rts8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!rr2orrr2rts6An8"pS<j2nWL*j95a;
+!!#B4H%R(VAfVqdBl!5L&rlql4be]Qs8W,qqYL6ls8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W,urr2rts7,XH%LkW&!,k\2e4i`i!!#l[P,caMb5_N.
+!sEpY@H9@+]EegRoCMVSs8W)trr<#us8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8N#ss8W,rqu$Kos1#Sb$4MH!C@OSW`rH*[
+!!$.)"=pOQXVVds4$:;uEV1.dQiI,'!Wl7$![>"Y[f?C-qtp9js8W)trr<#us8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8N#s
+qYL*hs8Rh-V>pU+?!lYW6,N[&AJl=SUSFpk!,"J]aAuC"!!$sH$V]mPlMpnarVc`prr2rts8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8N#srVc`qs8VENljXA(
+!!.LXAEbd'[/pG<s8W+NJqa7*3t;g^A7b!K,,>GK:%7Z>s8W,trVliss8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W)trr2or
+rVc`nr;8`CO$5hLAS(-2#D)sWA,lTj:/4ti;Oo0aZ#OgZ*?C^O!,_i><s&OQ['[@Cs8W#pr;Zfs
+rr2oss8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W)trr2oss8W*c6@B+GMJ[;(+!@0U!)?d(FFo+6!!$J:@d-*@_#OIG
+(DfF/o'cVYs8N#ss8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8)Ths8W+RL6_f>6PgW,BPQuN(RYC/9)nqkL5)6!!(IqLSSN*5"pp,Q6?rP1rVlfr
+rr2oss8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!rr2orrr2lprr<#t6puhO*MR\!q]-`K!!$a6!(SUm3coJ:$4Mi6FS[I;WrN-:
+!s;^0"=pjd\c;^0qYL'gs8W)trr2ors8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!rr2orrr2rts6An7"U8-c1V."(k6D9E
+!!#6@MNV(DP6(i<CMWD_,GG/<7XBB;s8W,qqYU9krr<#us8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W,urr2cjqu?]rH?thV!)5("Y\S%F!!%:57<ee3r's7k
+!!$"N/Zil-o`+u4It+Ess8Vrlqu?]rs8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!r;?Nns8TI5bmOr2DK,;/3PGInE<#uA
+%1P"7G)-P9IplaI8kR>.!-/)@?iU0UZEgq=s8VrlqZ$Tqrr2orrr2rts8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8N#s
+qYL*hs8Rh-UAt:'>[HJX7)o9-BFthChVQrp$sb5-WbH28#mu=c!)0r6_#OH7r;?Kms8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!rr2oss8VWZmM$@(
+!!$Xu7)i;1huEa[K7fcqs83001&q;c3B=i]?fqCh?%%*ds8W,qqYU9krr<#us8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W)trr<#u
+r;?CW6'=l6do]f2!!@ZO!Fu01/Pf/G8P5-s0",P2mg9DV!<Hj6!'3eI>Q=a'r;?Klrr2orrr2or
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W)trr2oss8W*c6@/nBMJ[8'+!R?X!)ZZnE4rs,!!$Iu8^(%1f)Peh
+%Ltqtna?GWs8N#srr2oss8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8N#ss8W,hnaR%t:&k9:?!cJS5K3['>J%MgrVcU&%8$U#C.q@K9MNt9!+*4H`W,u<
+r;?Kms8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W,qqYU<ms*fEo&e^@KFScjlQN.#$!!#/i?tY+EXpYYqG'<a0-DphDC]FH2
+&eZ\\m-F]Os8N#srr2orrr2rts8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!rr2orrr2rts6An7"pS6d1V."(k6D9E
+!!#-LR\Gb!VuQg-AnLBj3kPFm=\22(s8W#rrr;usrr<#us8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W,urr2inr;Zfs\$s*P!)*k5N+ltm*Zq'\#?(<jp$_A=
+$49Z2!-VXTiB06>#RG,8oC`.`s8N#ss8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!qYL-is8R+\YX(V#;,YmD!-/&><sAjY
+G'/i](lVg0k=J7k!!%'@!+5d,-F0q_s8W,rqu$Kos8N#ss8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8N#s
+qYL*hs8Rh-V>pU+?=2bZ6cT0,BFk_Ahr!-'(0V4\O_\b'*$1UM!(DEgNrT.ZqYL'gs8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W,qqYU<ms+#W_
+!!#P=.]dN*o`,&E5X9Yqs8Rh.OT5AE$4DSuAEbKlYQb;1nF5lGs8W&rrr<#us8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+o^q_m)Kf4fj#/m+!!$O0!)E_#3=#q/92*]AAEX4&K`V<h!!#)S9O%Pss8N#srr2orrr2rts8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W)trr2oss8W*d6@K7KMf!D(+!@3V!)cKaC@L]["U/?d0!f,#l3%<B
+!!#[$\%Mb@s8;fmrr2oss8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8N#srr2rts85DYDu]lF4[6nk?fV1e@![-ds8W+EH&Ve(6PL?$BkcrD&!9.EIfKHI
+rr2rsrr2rts8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8Vrlr;ZfsEcS3@3Q,3/i!^*Q!!79C!.$t!aDPnf'Gco5!,DQ78J)O]
+m-O*=s8W)trr2orrr2oss8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!rr2orrr2rts6An8"pS?m34rX-jou'@
+!!#*LR\6+<Z2al*;cMCC:=9+BCCUh;naZ#Hs8W)trr<#us8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W)trr<#unaZ#V%7L6sG$%r+5t&fp!+<.>_Z0Z9
+IX[[b!(eIaVf$JK!!%=nI&R)Fs8)Ths8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W,rqu-Qps0]8[$4DGn?fu0>nQK2Y
+@V"_;B^Zr^T)\k1!WlC)"!b1[[K$:,r;?Kms8W)trr<#us8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8N#s
+qYL-is8Re+W;lp4?t&+Z5/R@#BF>21qu#u3H`$iDD.RDK1,ZN@!*;``CB+>2rr2rsrr2rts8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!rr2opr;?Tps0oJO
+!!#b#$]/J.lm!dS"p\6#nac_[s$fIm!!$.W1:(\/mJm6$I!_Ufs8Vrlqu6Tos8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+rr2orrr2rts%?"D!!$[S+eh(]^,J*e&/($)!ce8@<!*4P['[FEs8W#pr;Zfsrr2oss8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W,urr2orrr2oss8W*c6@o[XP&G=3)B5.G!)Q9[@/'Ee%hDkY(7K#ToGAI5
+!!#97J;XC,s8)Tgs8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!qYL'gs8RV"O8o8M,q#U-Dt3r3KL/"Ss8W,gnEg\p3rf7n4?gMa>MfD\?A4*,
+s8W,qqYU<ms8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8N#srr2oss8V]^omM7b$k-GB!)3Fn:&k8`!<G+c#r&]l\,ZL.
+qYL'gs8W)trr2ors8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W,sr;?Tps1,\W!!$%f7*8e>huEe%
+!!#R']u9[>q#^_,1GlUL@H@UpHiO.7[^N^Gs8W#pr;Q]ps8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W)trr2oss8W!g8T=_1?9:?c?t&*r!+^P-V#UJp
+mHs<Q&5N9+D,!jW7Rt`-#&<Mkn,NFfrVc`qs8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W)trr<#urr2opr;HZqs6T+?
+L5).HJ"(n9QA($Rm-O$;s8W#pr;Zfsrr2orrr2rts8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8N#s
+qtp<ks8R:eQiI,(Bkcul27W\eA.fMEs8W%RLo::R?<ULg7nCi(!+lr\8b;QDs8W,urr2rts8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W,urr2rts7,XI
+%1P`+!,tt@g.=r_!!#lKK:;i?s6&S0$O]i4!-VURjuY]@#7"`/o(;t^s8N#ss8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W)trr<#urr2onqY^?lrr<#urr2orrr2rts8N#sr;?Kms8W)trr2ors8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W,urr2orrr<#unaZ/]&7He-UMF];&JL6+!(D$QLB%;REcR`O!-;jhm4U/s
+!!#c>H'\L1s82]krr2oss8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8N#sr;?Kms8TX?^&S.,$42AuB'^imX9Ac4kND+0s8Rb*NrT/C$4DW!AEbNmXp,,7
+o()AOs8W)trr<#us8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W)trr<#us8W,trVlZiqtg0dqYL*cqYL0hrVuot
+s8W,urr2rts8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!rr2opr;HZqs1#S]!!$P-;:eWAeGoSi
+!!#9r]YFLHrsT<?)BGDbD=S>TOoPJML5)#os8Vrlqu?]rs8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8)Tgs8W+LJ;XC-6QmYICM`PN%ZV&2<:B;D
+s8W+JIZOO05nk&uBP6ZJ)4:sE;tT_Ps8W,urr2rts8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W)trr2or
+rr2rts8PGRF9;YtDf,+o-`-kD?4ml4rr2c*]#F^M=$Agc>?g%d!-ASV;![H5s8W,trVlfqrr<#u
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W,urr2cjr;Zfs
+I!hC`!)ba7\7]I?!!$e\HD1B=s8W-!J:O'g!(S1VT5SZA!!%OlFe\p9s8)Tirr2oss8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W&rrr<#um-F!C#[B,?\79+9#muFf!(2*[NW9%YH[D%Y!*ru>j?c8T
+!!$OE'h@lenGiOgrr2oss8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!rr2oss8VWZmh6@*!!$_'9$U@7g&M+PJ:Npbs8W-!s*B!Y!!#bF/Zs#1oDel2
+I=8!ms8Vrlqu?]rs8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!rr2ooqu$Kos*fEk!!$_A@H9[>`W-!Q
+%LteilKJ9Js$T8&!<[siC@3GtW;lokH?teTs8Vrlqu6Tos8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8N#ss8W,hnaR%t:]LK=?XMnX5/R@#=1GcU
+s8W,gnEgo(5QCdm1,HCLAa9<rAq5E,s8W,qqYU9krr<#us8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W)trr2or
+s8W,joCEJ'=r&!ED/Jh^)O^X+;+=#[s8W,hnaQhh<$<KbBkm&H&WHbj5DFoTs8W,qqYL6ls8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W,urr2inr;Zfs
+\$s$N!)*e1MJ$Sg+<dKb#[-]fo)JainF5iU%R:!oANW/l>$Bha!*4T!OoPI]qYL*hs8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W,urr2inr;Zfs\@BT[!+/;hcW+$&!!%0B!(jT+^An65[C*pQ!+J5]b#MKu
+!!%!I$UsCIkPtS^rVc]orr2rts8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W,qqYL6ls+#W[!!#G5-DYHpo*c%d&.hV+nF$>Vs7#OH%Lu&1!,>,!cV@6b
+!!$E;\\nIIs8;fms8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8N#srr2onqYU<ms*&[X!!%(WD=T52Y5eQ/
+'bs(%m-F]Os*]<c!!$M?A*H0@_>jR@8P+%(s8N#ss8N#ss8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8N#srr2rts8>M\D#aQ>2E/-WAa9<rB6\Zl
+s8W,urr;NYnI5q(!!$q;<S9Z*b6A/ao()GQs8W)trr<#us8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8Doq
+s8W,dmI1PpBe1j?BPHlC%Z(/c8Ul5Qs8W-!s858RJHlI:CM`Ma,,,&;7Y$#Ns8W,qqYU9krr<#u
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W)trr<#u
+naYuV%Qj^kDGX-Y:f5aC!*4i/UAt8ns8W,blg+ue;?-]??XVtV4N%C-AFT*Zs8W,trVliss8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W,urr2flr;ZfsIXe$k!,?.YlU=:a!!$sI%n5dJkPtS^lK[[>#[K,>[qTXG
+#RcCf!Dp88^An65r;?Klrr2rts8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W,trVliss6T+>$kQYH#(UB%lSLK0#7G22m-juSrr<#uL51ij!'U`!M.^Me
+1,QNH$Y8i!oDejjrr2oss8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8N#srr2oss8V]_ndc=:*ZgqpFSHjuSH&Xl
+7n@CnrVHQos+Q9)!!$>.=PZqTfDknj%1ktuna?GWs8N#ss8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8N#sqYL*hs8Rb,PQ1\R+!@+mDtOteSI#[%
+o'u2Jrr<#us+#WZ!!#=s&s$dAm3sKd#74T)o()h\s8N#ss8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W)trqu]m
+s8W,/\]OmPBhM1I?<uIn$%N!U4GAQOs8W-!s8R:fUAt::DJei&3Of%h?:de.s8Vuqrr;usrr<#u
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8)Th
+s8W+LJ=QZ?;)'l5EHCdQ"+ip2HN4$Dq>'sgs8RV$PlLeS(DrBPC[iJgU(.f=o^q_Ss8W)trr<#u
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W,urr2cjr;ZfsGB]VY!-rR)oeSD2!!$[I),0;[kPtS^oCMPa'4)UuS8`NC
+*?L^N!(MKhMuWhWqYL'gs8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W,urr2ors8W,t7nR_#!+J5\`+3B@!!$Y\J#32Fs7Q'[s8W+LJsZN<8KAkA
+DK,@U$B0+OVuQesqYL-hrr2rts8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8N#srr2oss8VENmLKqE/haPIDY+MSO8o8O
+H?tGJs8W)trp&b8"UJm%3PK'9lN@KH!!#Nt\%2P=s8;fmrr2oss8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!rr2oss8VWYljXIi!!%%=<7b)Kg&M+W
+K8-'!s8Vcbq#CBoJ:a6j!)+U_TlY;M!<e1)IB<JKs8)Tis8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W)trqcKh
+s8W+PL8FqNAn,?4923e6!-J8A3k2]0s8W-!s8Re.VuQg/?XVqe:"'(BC_R^_oCMMPs8W)trr<#u
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8N#s
+s8W,io(!;(;ucuFA7aph6,a!6C@(<Us8W,pq>1-ks+#]k!!#e@.&V62q#CGIH[Vmns8Vrlr;Q]p
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!rr2orrr2ors8W-!6:?G9&!D-ZqB[Ja!!$+k88eJ-rr2oss8Vs`7!Sb6Jo5Gq
+0f--9!)e)gRK*<eqtp<jrr2rts8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W&rrr<#ulg3sF%Trr@KP>2i/M=:5$Y/buo`+skq>'mes8RV$S,`Oc
+.kIfFG5M=?I!gCBs8W,qqY^Bns8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!r;?Kms8TX?_Z0[=6q#.,AEF.*K)bm@
+L51ums8W)ts75^L#mscY,c5U&o+i41!!#KCLmA#?s8)Ths8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W,qqYL6ls+Z>j!!#A&)4"rOoGo$J
+#RXf+nac_[s7uKes8W+LJtE#C;(aQ*FERBZ!.0*BWW3"uqYL-is8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W)trqlTj
+s8W+CGb"g7F)>g`4?^=W!,2rU6KmXos8W-!s8TR<`W-!J6Uf+(?fM+eGmb'\lg!g9s8W&rrr2or
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8N#s
+qYL*hs8RS!PlLeV,:0+'EVC%YPRnL/oCVVRs8VojqZ$TqJ:aHp!)tU*Y]Y*b!!%@nI]<AIs8)Ti
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!rr2orrr2rts7,XN&JSq(-`V0*oG8=0!!#qf86c,os7uKfs8W+JJ"?W?AS,N=
+7n:Z$!,*)a8FuHBs8W,urr2rts8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8)Ths8W+LJt2lA;)'l5F`mEY!./m6V#UJpqYL-dqYU<ms+#]o
+!!#nM0X5\@q>^MBI"&'ps8Vrlr;Zfss8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8N#sr;?Nns8TU>bQ%WY<EIsV<SIKTFoVM6
+\@K?Rs8W#prVuor77_q7$&NS>oI;Dl!!#oCHBnO1s8)Thrr2oss8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W,urr2cjr;ZfsH@24_!*;9H^hINN
+!!$e`JZ&PJs8)ThqYL*hs8RV$T)\jf/hjGMFnl";H[L:As8W,qqY^Bns8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W,urr2orrr2os
+s8W*d7!o:IMK<k6-nDA!!+Q]Z6LjU6s8W-!s8VWZnH]J,-nDE;DtO\UOoPJML5:uls8Vrlqu?]r
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+rr2oss8V]^mM$L)!!$e&8'>(?irB'eIt+0ls8Vrlqtg0ds8W+LJt)f@:b40#Fa!Z_!.90CWW3"u
+qYL-is8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!rr2oqrVliss6K";#n(<+4ht`EljOAZ!!#T?JWTp3s7lBcs8W,0]#t'RCJ7IN
+='4;Z!-\h]8*fI's8W,trVc`prr<#us8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8N#ss8W,hna?nt8H8a1<*.^L;V1sL<ecF%s8W,qqYU-cqu?]r
+J:a9k!)OsjWHNI]!!%OrIB!8Hs8)Tis8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8N#sqYL-is8RP!VZ6^=CMW?&6,`g(D[m=I
+lg![5s8Vojqu?]rGBfSW!,cRfm63hR!!$Cu9R-U;rr2osrr2oss8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W&srr<#un*f]R&5iK0H"1CH
+5XEBn#\iYln,NFfrVc`lqYU<ms+#]k!!#e@-_tp-pAb5JH[Vsps8Vrlr;Zfss8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W,urr2orrr<#u
+lg4!J%qHq3Wc<(S(E&S?!*)N\?2ss)rVc`qs8V]^ne)[B'Gm*TE:bA#UAt9bJ:Na]s8Vrlqu6To
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W,urr2rts7,[N$P-AC#(gQ&lS13(#7G/7o(;t^s8N#sqYL*hs8RV$R/d4[+siq'Eqoe@L3e3I
+s8W,qqY^?lrr<#us8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!rr2onqY^Bns+H-'!!$J7?K"mafDkts!!#<p\\.tBs82]js8W,blg=r_A2,mL
+C2<5C$AJN]:q*sKs8W,sr;?Qnrr<#us8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!r;?Kms8TX@]`8%-&e^=CD"8bpV$[]?o()DPs8W)trqcKg
+s8W+LJscT=9->@KE,t^V#)R_UXT/>#qYL-is8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W)trr2orrVc`qs8GARKaS?NF`mO..B<FK>XqA)
+s8W&rrVlZiqu?]rKnlE'!*rc3hbmA(!!$sI&4Q-Zmf3=err2oss8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8)Tgs8W+LJ;=1*66IGC
+D/T%`)4Cm?;"F/Fs8W,urr2cjqu?]rJ:a-g!(\1RS8E0<&.t'l7="q5rVlfrrr2oss8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W,urr2inr;Zfs
+\@K]]!*r)bb[FuC#Rc:c!(2HpPQ1[_qYL*cqY^Bns)rU^!!%4[D=BPF\,ZM88P="%s82fps8N#s
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W,urr2cjqu?]rJqTTn!)4mmW,m(T"UKoN7XP18rr2osrr2onqYU<ms+#]d!!#J,*1(JXnf/[C
+#ms2nna6AVs8N#ss8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8N#srr2orrr<#us$]D$"9jBrEV)1L[K$;?',=((lfnHLs8Dops8W,jo^`V-?l^>^
+EH:gn*1Hp.7Y$#Is8W,qqYL6ls8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W,qqYU<ms+#]m!!#nS2R[XHoDel7I=J9ss8Vrlqu?]r
+qYL*hs8RV$PQ1\R)&e`UC[iMiUC%K6o(2DOs8W)trr<#us8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W)trr)fps8W,blg4rb@l?6WCi/YQ&WQhk9Rq_\
+s8W,qqYU3gr;Zfs\$s0R!*qfS`FWQA!sa;U!(XK,\c;^0r;?Klrr2rts8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8N#sqYL-is8RCmS,`Ol
+4[-brBBoNtC4(N.s8W,qqY^?lrqcKgs8W+NKTZ<87M?N!C2<8`-)UtU=n;.Ss8W,urr2rts8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!rr2orrr2cjr;Zfs
+IY"L!!-N$km6a:\!!%!K&4c$NkPtS^rVc`lqYU<ms*oNf!!$M<A*$9Tbl@`Z'c9U8oC;k\s8N#s
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W)trr<#uoCMDb(d\3&CIUk=>$Kqc!+15+U&Y/mqYL*hs8VrlqZ$TqJ:N7P!'Li)NbE.p
+.4_P+$XN>ooDejjrr2oss8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!rVc`qs8VNTn-on?-Rc!8EV(%aQ2gnb7nHtcs8W)ts8N#srr2rts85;VJ-Q@5
+DfG>$0!50S;L*SSs8W,rqu$Hmrr<#us8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W,urr2rts7,UI%1c)3!-2(@g/:l&!!$&SLn=YHs8)Th
+s8W,sr;?Tps1#YR!!#[s$AN8/l8:K0"q"r4o(;t^s8N#ss8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W)trqlTjs8W+JJ>3)EC1(K3:/B7;!d4PE6+FG8
+s8W,sr;?Qnrr<#unaZ)S$<nl,XE/@Q'GZc2!(M^!Q2gmaqYL*hs8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!rr2oss8VW[ndQ14
+!!7LYB';HF`<6H\m-O3@s8W&rrr<#urr2oss8VWZndH(4!!7LYA`l3A`<HW^nF6&Ls8W&srr<#u
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!rr2orrr2rts7,[N
+&.r:j*M7Frq&prV!!$"h87qo%rr)fprr2opr;HZqs1,_a!!$_)9@$gHhZ*Y#$Oo_olKJ9Js8Doq
+rr2oss8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8Doqs8W,bm-P,h=p51cBkm)f/Zo<dA+K3_s8W,urr2rts8Drrs8W,fn*^Yr;ucoB
+>[?8W8'V>HDY!Aks8W,urr2rts8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8N#sr;?Nns8TU=bQ%WY:f>qL>MfD`I/j7@\@B?Ss8W#pr;Q]pqYL-is8R=gRfEG)
+Bkcs"6Grj(?qF%9s8W)trr;usrr<#us8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8Vrlqu?]rL5;&o!(IqJRVcm5)]YFU$X</ko)Jai
+rr2oss8W)trr<#unaZ)Y&kr?+DGO-Z:f>sH!+`UNa8c2>r;?Kms8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W,urr2orrr)fps8W*d7=PRMMK<n7.kI_$!+lr^6h0^7
+s8W,urr2orrr<#uoCMPc'j_UlQZ@-@,:'#a!(_WjOT5@\qYL*grr2rts8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W,qqYU<ms+#Wc
+!!#Y?.B.?.pC@gs&/8%6o^Vt]s8N#ss8W,urr2rts7,XJ%M2#.!,P%jaC&E<!!$AUJ!p?:s8)Th
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!rr2opr;?Tps1#VZ
+!!$=n7`]+OkQq]R!!#K<J<0a1s82]krr2orrr2rts6Ak9"pep#27R@9lj!lO!!,p*\A&"Cs8;fm
+rr2oss8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!qYL*hs8RV$SH&Xe1GlI[FS5\7H$=P0s8W,qqY^?lrr<#urr2oss8V]^mM$L%
+!!$Uj34Nd?mJm6*I=S0os8Vrlr;Q]ps8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W)trr2orrr2rts8PMWF92SoE,kG.3P,7kB+u1[m-X-=s8W&rrr<#uqYL*hs8Re.VuQg-
+>[?8_:XT4CD@R4EnaYuGs8W)trr<#us8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8)Ths8W+LJtW/E<&m"PD/AV?!-*I<WW3"u
+qYL*hs8W-!s8N#sqYL*hs8RCmR/d4c0JTbRG52+<H@11@s8W,qqY^Bns8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W,urr2lprr<#ulg*mC$=bkK\8H3S&JL<-!)%WaM?!VU
+qYL*grr2orrr2oss8W$b7!o"<Jo>Su0f$!6!*Vl`B`J,1rr2rsrr2rts8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8Vrlqu?]r
+J:aEo!*2<L_.@6E!!$e`J>`GIs8)Thrr2oss8W-!s8)Ths8W+NKU`#B:*M!XEH:d\%$!YCI/j6G
+rr2rsrr2rts8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!rr2onqY^Bns*oTt
+!!$qNBBr#VaT)<`!!,3l\@;M<s8;fmrr2orrr2rts7,XL#Raf^.&q<,obA:-!!#KCLmA#?s8)Th
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W,qqYU<ms+#]o!!$(e6cNVHkPtTnIY"?qs8Vrlqu?]rs8W,urr2cjqZ$Tq
+It*:T!(.P?Q"t4)+<[Eb$<$Ean,NFfrr2oss8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W)trr2ors8W,bm-P5mA0N7qEc_!o*16d,<_#\hs8W,urr;usrr2orr;?Nns8TX@b5_NW
+8kdN8>MfD\G7+mRl07@1s8W)trr2ors8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!qYL*hs8RV$U&Y0q6q#+)@d!dl@t0')
+s8W,qqYU<ms8W-!s8W,sr;?Tps1#YU!!#e$$\iA/lRt!##n:G:oCW(_s8N#ss8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W,urr2cjqu?]rKSH<'!+B&8hc<e5!!@BE!(s`1^]4?6
+r;?Klrr2orrqlTjs8W+CGFSX5DJO(W4[?mb!+8AlGQ7^Brr2rsrr2rts8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8)Th
+s8W+LJtrAH=@>Tu?sr*s!+UM0V#UJpqYL*hs8W-!s8W-!rr2oss8VW[ndQ14!!%:TA*--H`rlZ_
+m-O3@s8W&rrr<#us8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8N#srr2oqrVlisr^0).
+$P&8@Fnm=2VZ6^,'c0.*naHMXs8N#srr2orrr2rts7>jR&J\[m*1:bdq&giR!!#Q?J<0a1s8)Th
+rr2oss8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W,urr2cjqu?]rJ:aQs!*Vc\a^AK;!!$JXJY`>Gs8)Ths8W-!s8W-!s8Doq
+s8W,fn*UVq8cSj0;Gu%F=53cU>(qa's8W,qqYU9krr<#us8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W)trqu]ls8W,/\]=aN?V*i8@:A4&$A&6X7"9`Gs8W,rqtpBlrr2orr;?Kms8TR;_Z0[C
+4[-eqAa'@)K)bmD[^WmKs8W#pr;Q]ps8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W,qqYU<ms+#]t!!$7r9$LXIirB'g
+It=Eqs8Vrlqu?]rs8W-!s8W)trr<#uoCMGc(e"E)BKeYrA7as)!,-h2V>pSqqYL*hs8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!rr2orrr2ors8W-!77MP*#(gl8oeSJ7!!$XE'M.WYlMpna
+rVc`qs8W)trqcKgs8W+KJ"6Q>AR]3484h#*!,NDh:\42Js8W,urr2rts8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8N#s
+qYL-is8R@lT)\js9MNi=>MoJ]@"3a%s8W,qqYU<ms8W-!s8W,urr2cjr;ZfsH@2.]!)t[/[<$H_
+!!%=hH)1K?s8)Tirr2oss8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8N#srVc`qs8VENm0F&0
+2`SEdD=7uHM?!WMJ:a*es8Vrlqu6Torr2orrr2ors8W,u77`1>$&ieBoI;Do!!#i@HB%t)s82]j
+rr2oss8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W)trr<#uoCMA`(IA*%D+m[O='+5Y!*t)*U&Y/mqYL*hs8W-!s8W-!
+s8W,qqYU<ms+#Wd!!#Y9,,&mlp(\F4%h`"7o'l\Zs8N#ss8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W,urr2orrqcKhs8W+JJZ8\MF_Y^Z6:8]l!-&M\8*]C&s8W,trVlfqrr2orrr2oss8V?JlN[]&
+0ep"MD=IuCM#[NT\[oZXs8W#pr;Zfss8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W,urr2rts7,XH%1kc)!-(k5ePoT(
+!!$,NJtN)Cs8)Ths8W-!s8W-!s8N#sqYL*hs8Re.O8o8J%han:C@3Z*Xp58@o()DPs8W)trr<#u
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W,trVliss6f=E$k?ns-`M-,pD4^6!!$(j8R;Ars8N#t
+rr2orrr2orrqcKgs8W+RLo(.P?WgRg;H)3J!-&J[7e-!8s8W,urr2orrr<#us8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+rr2oss8VWZmg]su!!%"><SLGNec5\MJ:a<ks8Vrlqu?]rs8W-!s8W-!s8Doqs8W,cm-G/n<r`5G
+@q+Rl8B_&6?FdYds8W,sr;?Qnrr<#us8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8N#sqtp<ks8ROuUAt:.
+?t&(j:t5OIG5qY2\@B3Os8W#pr;Q]ps8W,urr2ors8W-!6q)M(!J,-+nhW/3!!$4m88A2)r;Q]q
+rr2oss8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8N#ss8W,hna?o!7K<F.=BXBV;:Y^I<If[js8W,qqYU<ms8W-!
+s8W-!s8W)trr<#unaYuU&3g-pDbEaJ>[6:h!*t)(RfEEfqYL*hs8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W,urr2orrr<#unac5^&muXuS98uM,:'&b!*2T\BE/#2rVc`prr2orrr2orrVc`qs8VENklqGs
+,q,^3EV't^Q2gnWL5;5ss8Vrlqu?]rs8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W)trr<#unaZ)X&P)m%E*?K%
+;c;3I!*"K#R/d3dqYL*hs8W-!s8W-!s8W,urr2ors8W,s8PF"%!+.TAZuL*X!!%1fH_pcBs8)Ti
+rr2oss8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!rr2opr;HZqs1#Sa!!$e3;:\uWhuEn.!!#d(\AJ:Gs8;fm
+rr2oss8W-!s8)Ths8W+RLn+MG>Yn8G>?p(d!-ek]9Bk^'s8W,urr2orrr<#us8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W,urr2rts75aL%hhG5!,u+Gh,@5&!!#uKJt)f?s8)Ths8W-!s8W-!s8W-!s8W,qqYL6ls+#W\
+!!#S6,GK-rp(nO4%hi:@o^r1`s8N#ss8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W)trr2orrVc`qs8PGTJHuXA
+FER@//?8aNB,)4MnaZ&Is8W)trr2ors8W,urr2flr;ZfsGB]h_!-2jkmQEeL!!$@t9QpI9rr2os
+rr2oss8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!rr2oss8VWZljXId!!%(B=kZePec5\NJ:a?ls8Vrlqu?]r
+s8W-!s8W-!s8N#sr;?Kms8TR<]`8(0#n)T(C@*i8[g!(Jlg+!=s8W&rrr2ors8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W,urr2inrVuot\@BZ]!+JMkc"(AJ$4MUg!(MHgNrT.Zqtp9irr2rts8N#srr2oss8V]^oFM[H
+*$(VjEVU[uT)\j^J:N[[s8VrlqYpKns8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8N#srr2rts8>DYF8u;T
+='"'S<7h0N<e#^ms8W,qqYU<ms8W-!s8W-!s8W-!s8N#ss8W,hna6hs7fWO3=BO<W<SIKR>_\'1
+s8W,qqYU<ms8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8N#srr2oqrVliss$T;)"pfs'EqV1C[K$;?&emq)mHX`Os8Doq
+s8W-!s8W-!s8;fms8W,0\]=aN?9git@q4[(#CujT8%,n;s8W,sr;?Qnrr<#us8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8)Ths8W+KJYrJJ>u4DK<`e)W!*t#&U&Y/mqYL*grr2rts8W-!s8W-!s8W)trr2os
+s8W!g961(5@66WdCi/P>!-*4,UAt8nqtp<jrr2rts8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W)trqu]ms8W,/\B+^N?pmH+
+B4pK;%Yt)b8Ul;Ts8W,qqYU9krr2ors8W,urr2flr;ZfsG^,VV!,6(XlpX@b!!$[J)G0PlnGiOg
+rr2oss8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W,urr2cjqu?]rIXn*l!*Vobb[+W8!!$MYJYrJIs8)Th
+s8W-!s8W-!s8W-!s8W-!s8VrlqZ$TqJ:N[\!(eI_VfQnR(`/MM'OUJ'oDejjrr2orrr2rts8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+rr2orrr2lprr<#u6q2V0#_mA?p,"Y8!!$[F'hn#^li7"brVc`prr2rts8W-!rr2oss8V]^o+DdF
+'Gm'TEV1P&VZ6]kH$YGLs8Vunqu6Tos8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W,qqYU<ms+5ot
+!!#t\5/:`AlMpp-77_S$s8Drrs8N#ss8W-!s8W-!s8W-!rr2opr;?Tps0fDK!!#[t$\i;.lT./C
+!!$<8]#XjNs8;fms8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8N#sr;?Nns8TU=a8c3I6:Jt.BBfj7LB%<GIt<g`s8Vrlqu6To
+rr2oss8W)trqu]ls8W,.\&/1G?9(*[BkZi=$AJN\9t7aKs8W,sr;?Tps8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!qYL'gs8RV"NW9&O1GuRZEUsDCM$jb_naZ#Hs8W)trr<#us8W-!s8W-!s8W-!
+rr2oss8V]^nJ3!@!!$t6:XWKRiW&seG^5\Vs8Vunr;Q]ps8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W,urr2orrr2oss8W*f7XYCCKQ2#'
+2E8/G!+uoY9C;-4s8W,trVlfqrr<#us8W,urr2cjqu?]rIt*sg!+TJIj\/@p!!$jO)H-.snGiOg
+rr2orrr2rts8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8;fms8W,0]"n@H;^*H]F)q'i'Trk9?h3dZ
+s8W,urr2rts8W-!s8W-!s8W-!s8N#sqtp<ks8R@jOT5A[/hjVOEV'\NM\?n7naZ/Ls8W)trr2or
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+rr2opr;?Tps1#VX!!$4d5Jh2OmLKkd!!#ZBJsHB9s8)Thrr2orrr2rts8W-!rr2orrr<#ur^BA6
+#RZK/EqCn7X8i5sH$YSPs8Vunqu6Tos8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W)trr<#u
+o()A]&75hWNG<;$+<dKb$=N5emf3=erVc`qs8W-!s8W-!s8W-!s8W-!s8;fms8W,/\\S7G;%+"q
+D/Jc!27<Jb?+IPfs8W,sr;?Qnrr<#us8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W)trr2orqYL-is8R=gScAb4DK##.5JdC#D%7+GlK[R4s8W&rrr2or
+s8W-!s8W)trr2ors8W,`l0AQ[?na=CCMiPK%Z(/c;7O0Rs8W,sr;?Tps8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W,trVliss6oFC$OoZ/"bC9!l9.AH!!#iKL7J;Ds8)Thrr2oss8W-!s8W-!
+s8W,urr2orrr<#uoCMJd(/Fo1E_]K\?XVjn!,G%oDu]k;rr2rsrr2rts8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W&rrr<#umI'EQ&o0!LZZ'jR
+&epK/!*)N\>6"X&rr2rsrr2orrr<#us8W,urr2cjqu?]rKnu].!+oG>hbm>&!!$pQ)HQG"nc/Xh
+rr2orrr2rts8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!rr2orrr<#urC0D'!!$nB?/\RWe,TJN
+J:OBos8Vrlqu?]rs8W-!s8W-!s8W-!s8W,urr2flr;ZfsJ:a6j!*1KuXE/LX'Gd#B$ruQVkl:\_
+rr2orrr2rts8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+rr2ooqu$Kos*fHm!!$bDA*HQXci=)i!!,6m\@MY>s8;fmrr2oss8W-!s8W-!rr2orrr<#us$K5*
+"pTa"E:bk?Z2al$H$YYRs8Vunqu6Tos8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+qYL*hs8RV"T`>'p7S([/@,q:fDad3Cs8W#rrr;usrr<#us8W-!s8W-!s8W-!s8W,trVliss6K"9
+$4Kl9#D6Z&l:+4a!!$,VM51+Ns8)Thrr2oss8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W)trr2ors8W,ho(!>(@3-J`Ec_$t+J/W6<_#\ks8W)srVlfqrr2or
+s8W-!s8W)trr2ors8W,`l0AQ\>q@S3D/SqS%ugPh<Oo]Zs8W,sr;?Tps8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W)trqcKgs8W+PL6hl?:GO`5E,b@T%>bH%:\!uDs8W,urr2rts8W-!
+s8W-!s8W-!s8N#srr2orrr<#us$oV'!!$Ot7`]:Xkl:^*77M_*s8N#ss8N#ss8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W,urr2inrVuot\@Kf`!,>D1fNVS9
+!!@NI!)0o4_#OH7r;?Klrr2rts8W-!s8W,urr2cjr;ZfsKnlT,!+K&5gf%/)!!%'O&kDH\mJm4d
+rr2orrr2rts8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W&rrr<#ulg*pD$==ScQZ-m9
+*[%*U!*-M<_>jQ8r;?Klrr2rts8W-!s8W-!s8W-!s8N#sqYL*hs8Rh0S,`Ob+<dD!EqUOrTa(m.
+m-F!;s8W&rrr<#us8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+rr2orrr<#us$K2%#RQ<-F8.7:XT/?5'Gj4.naHMXs8N#srr2oss8W-!s8N#srr2orrr<#us$T;,
+!sO9rE:bh=ZN'u.7n@(gs8Drrs8N#ss8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W,urr2rts7>jQ&f+OM"Fk)uks.SQ!!#fFJ<^*6s8)Thrr2oss8W-!s8W-!s8W-!s8W)trr2or
+s8W,`l0&Ka:B1HF@:A1i9[<\=>)%j,s8W,qqYU9krr<#us8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8Doqs8W,blg5#eB0JQ!BP?]?%Yk#a8:Q2Rs8W,rqu$Hmrr<#u
+s8W-!s8W)trqu]ls8W,0\\8%D;)0o6Ci/_Q&<6_j;7O0Ss8W,sr;?Tps8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!rr2onqY^Bns*8m^!!$D,=4pVTg&M+c8PF@.s8N#ss8N#s
+s8W-!s8W-!s8W-!s8W-!s8W)trr2oss8W'g8p(+6@m3/rBPHl7!,R+5W;lntqYL*hs8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W,urr2cjr;ZfsJqU-(!-E'omliqP
+!!$aB%S5pOlMpnarVc`qs8W-!s8W-!rr2orrr2cjqu?]rH$YbV!+K2;iDNV+!!$pQ)HZFunGiOg
+rr2orrr2rts8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!qYL*hs8Rk2T)\jj
+3'+]fD!hH4KF/,[l07=0s8W)trr2ors8W-!s8W-!s8W-!s8W,urr2cjqu?]rJ:a?m!)Y-oWH37[
+!!@muGcC`Cs8)Tirr2oss8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W,qqY^Bns*B!n&J::NG52pkQ2gnj*?d]@p%&._s8N#srr2oss8W-!s8N#srVc`qs8VKRlk'q=
+%M4_>E:Y\8Z2al&H?tbSs8Vunqu6Tos8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W)trr)fps8W,blg"f`=;MmCEH1Up,bb8=98A=hs8W,qqYU9krr<#us8W-!s8W-!s8W-!
+rr2onqYU<ms*oTb!!#P+)3\iOn00'P$kQV6oCDq]s8N#ss8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8N#srr2rts8G>RM_Hru@q4U($%N!U9gD'HrVcTms8W)trr2or
+s8W,urr2rts7uKfs8W+LJsQH;<'<F^Bl!/F%>Xua9";FGs8W,sr;?Tps8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W)trr2oss8W*f7XtI=G\_$Z6UScl!+/5eDZBb8
+rr2rsrr2orrr<#us8W-!s8W)trr2orrVc`qs8>G[?2st&%1e>2C$I6%Z3q1FoCVSQs8W)trr<#u
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W)trr<#uo'u)P$!9hoeko>q
+!!%-A!Dj7;,4P*hs8W,trVccrs8N#srr2onqYU<ms6f=@&/.tB"+FlokXS.d!!$M"8TXq3s8N#s
+rr2orrr2rts8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W,urr2cjqu?]r
+L5;],!+/>kcX1)@!!7HS%8#mOl2Ue`rVc`prr2rts8N#ss8W-!s8VrlqZ$Tq\@K!I!#tt?@1Np-
+D/JbY(nYkkW;lntqYL-hrr2rts8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W,urr2ors8W,u77WD+7*SV.ec5\m!!HF)"!FnUZ2ak(qYL'aq>0saqu6Tos8W,rqtNfZC]FH?
+/1muDEVC:gR/d4b\@BKWs8W#prVlfqs8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!rr2orrr2rts68e5#n(&^+es+"pDtHK!!#iHK:)]=s7uKfs8W,urr2orrr2or
+qtp9irr;ooqaEtG!!#"Z!c9)*TQPDR#766=KWb@Ts8)Tis8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W,qqY^Bns*/gi.4hi7A*F%!IfKUZ!!>"Z"p_H?ZiC(*
+rVc]lqu$9cp;+Va4[30O!(R8"Jm`!H;,YsF!,4qpGQ7^BrVc`prr2orrr<#us8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!rr2orrr<#us$]G&!!%:WB'MiUaoDEX
+&en%,md0uRs7lBbqYL'bqYL3jrr)fpp%@rM9i(fi+9MjX!!.148',1KkReGPl07R7s8W&rrr2or
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8N#sr;?Nns8T:-bTeF0
+D/]%[(6ee"B`SE9!sC:X!!u.f:Pt*jGBn]R));@#1B7DO!!.=(3Os3Qq&(-@!!#g)\]+UKs8;fn
+rr2oss8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8N#s
+r;?Kms8TU>a8c3H3]t2jB^?3@NW9&W9200uqtU3ks8N#sqtp9hrVNn,ZO%'U!<OMK#?Lm+C_IMF
+FEI.(/$D0&JH,ZLrr2rsrr2rts8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8N#ss8W,ioCWe4J6u^I6Uo/t!dObJAcW*<!X)$o!%IsK,6.]t!!#mt"(qZ=Hn[:]
+H@,QO4i%*u>YS%>s8W&srr2orrr2ors8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W)trr2orrVc`qs8PMWIfot-Ci&W"34f.kF8u;)7S$jAMMlt8JpD]j
+'Gr(u"s3gF3<KLj!!6m:#(fcPfP,'d#Rc-l]$:9Ts8;fnrr2oss8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W)trqu]ms8W,"XNMY,TlkSX3]t+Y#(ZaSDZBiL
+!<ls8#AO8BD?'`X%M=^l9$Vd2r]WN^!!$:t:4rH@qYgBlrr2orrr2rts8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W)trqu]ms8W,/\]OmP><bEl
+Ci/_W(6ALuD#jZ-!!")@!#P\9*<6(%!X)I'"_7T7D[$K$8P76THiF6QKR/$Fs8W,qqY^Bns8N#s
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W)trr2os
+s8W*n:6ZhEVfHkU?<uJ7-`@LdM[0ZE$kA.<,G.=ka)c=pCMWDT(RkR5C4Lo8o^qeUs8W&rrVuot
+rr2oss8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W,urr2orrr2ors8W$j:4WBFE+3AB?!lS"%>k,fD$1,W":/?:#\!c:B)hsM!<dZd*1^JHjDf26
+"p^)V8<!KEqYgBlrr2orrr2rts8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!rr2orrr2orrqlTks8W,&YgO*uP!;4WBkd-QD";=Wm;$P.D/JuR?fiRYX8i6D
+4$JG:_pn_ds8)TirVc`qs8W)trr<#us8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W,urr2orrr)fpqu$=]8rEfUJo,>oAS13N,GYPOJH?"%
+!X*oX$AKZIU/+V7F`dIO8_+OhNdQ;Xo^qhVs8W)trr<#urr2oss8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!rr2oss8W)trqcKhs8W,-\'8`,XXl,r
+-7>T/*i'\nSf]/C(`Rp<CSeMMd/X.GrVc`lqYU9krr<#urr2oss8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!rr2oss8W&rrr)fp
+r;?I`98roOG>1faE,bSgC@#)*gg"+@CMN6UDtd..h]<o85<tOJ^XiGbs8)TirVc`qs8W)trr<#u
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+rr2oss8W)trqu]mrr2opr;?<`q6I?JCi>qsJu[trmITrBrVc`qs8W#prVQKis8W,urr2orrr<#u
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!rr2oss8W&rrVuoto_%p(IAmnsHl!Zf,q$&U1r(t-_'gh<+<d(:6']$neGfLH
+rVc`lqY^?lrr<#urr2oss8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!rr2rsrr2rts8;fnqYL-hrr2rts8N#srr2oss8W)trqcKh
+qu$Elrr2rts8N#ss8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!rr2oss8W&rrqu]mr;?NjqtdY+c#7U%
+I"&MIGd)UGXl\[2q"adds8W#prVQKjs8W,urr2ors8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W,urr2rts8N#s
+rr2opr;HHfqtg0erVc`prr2orrr<#urr2oss8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+rr2oss8W)trqcKhrr2oss8W)trr<#us8W,urr2rts8;fnqtp?krr2rts8N#ss8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!rr2oss8W)trr2orqu$Egq>C*cr;$3eqYL-grVlfqrr<#u
+rr2oss8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!
+s8W-!s8W-!s8W-!s8W-!s8W-!s8W-!~>
+Q
+cleartomark end end pagesave restore showpage
+%%PageTrailer
+%%Trailer
+%%Pages: 1
diff --git a/Build/source/utils/asymptote/examples/pipeintersection.asy b/Build/source/utils/asymptote/examples/pipeintersection.asy
new file mode 100644
index 00000000000..b22574c13c2
--- /dev/null
+++ b/Build/source/utils/asymptote/examples/pipeintersection.asy
@@ -0,0 +1,13 @@
+import graph3;
+
+currentprojection=orthographic(5,4,2);
+currentlight=adobe;
+
+size(12cm,0);
+
+real f(pair z) {return min(sqrt(1-z.x^2),sqrt(1-z.y^2));}
+
+surface s=surface(f,(0,0),(1,1),40,Spline);
+
+transform3 t=rotate(90,O,Z), t2=t*t, t3=t2*t, i=xscale3(-1)*zscale3(-1);
+draw(surface(s,t*s,t2*s,t3*s,i*s,i*t*s,i*t2*s,i*t3*s),blue);
diff --git a/Build/source/utils/asymptote/examples/planeproject.asy b/Build/source/utils/asymptote/examples/planeproject.asy
new file mode 100644
index 00000000000..ab8980b613e
--- /dev/null
+++ b/Build/source/utils/asymptote/examples/planeproject.asy
@@ -0,0 +1,18 @@
+import graph3;
+
+size3(200,IgnoreAspect);
+
+currentprojection=orthographic(4,6,3);
+
+real x(real t) {return 1+cos(2pi*t);}
+real y(real t) {return 1+sin(2pi*t);}
+real z(real t) {return t;}
+
+path3 p=graph(x,y,z,0,1,operator ..);
+
+draw(p,Arrow3);
+draw(planeproject(XY*unitsquare3)*p,red,Arrow3);
+draw(planeproject(YZ*unitsquare3)*p,green,Arrow3);
+draw(planeproject(ZX*unitsquare3)*p,blue,Arrow3);
+
+axes3("$x$","$y$","$z$");
diff --git a/Build/source/utils/asymptote/examples/polararea.asy b/Build/source/utils/asymptote/examples/polararea.asy
new file mode 100644
index 00000000000..42d3729914c
--- /dev/null
+++ b/Build/source/utils/asymptote/examples/polararea.asy
@@ -0,0 +1,38 @@
+import math;
+import graph;
+
+size(0,150);
+
+real f(real t) {return 5+cos(10*t);}
+
+xaxis("$x$");
+yaxis("$y$");
+
+real theta1=pi/8;
+real theta2=pi/3;
+path k=graph(f,theta1,theta2,operator ..);
+real rmin=min(k).y;
+real rmax=max(k).y;
+draw((0,0)--rmax*expi(theta1),dotted);
+draw((0,0)--rmax*expi(theta2),dotted);
+
+path g=polargraph(f,theta1,theta2,operator ..);
+path h=(0,0)--g--cycle;
+fill(h,lightgray);
+draw(h);
+
+real thetamin=3*pi/10;
+real thetamax=2*pi/10;
+pair zmin=polar(f(thetamin),thetamin);
+pair zmax=polar(f(thetamax),thetamax);
+draw((0,0)--zmin,dotted+red);
+draw((0,0)--zmax,dotted+blue);
+
+draw("$\theta_*$",arc((0,0),0.5*rmin,0,degrees(thetamin)),red+fontsize(10),
+ PenMargins);
+draw("$\theta^*$",arc((0,0),0.5*rmax,0,degrees(thetamax)),blue+fontsize(10),
+ PenMargins);
+
+draw(arc((0,0),rmin,degrees(theta1),degrees(theta2)),red,PenMargins);
+draw(arc((0,0),rmax,degrees(theta1),degrees(theta2)),blue,PenMargins);
+
diff --git a/Build/source/utils/asymptote/examples/polarcircle.asy b/Build/source/utils/asymptote/examples/polarcircle.asy
new file mode 100644
index 00000000000..c08160cde69
--- /dev/null
+++ b/Build/source/utils/asymptote/examples/polarcircle.asy
@@ -0,0 +1,30 @@
+import math;
+import graph;
+size(0,100);
+
+real f(real t) {return 2*cos(t);}
+pair F(real x) {return (x,f(x));}
+
+draw(polargraph(f,0,pi,operator ..));
+
+defaultpen(fontsize(10));
+
+xaxis("$x$");
+yaxis("$y$");
+
+real theta=radians(50);
+real r=f(theta);
+draw("$\theta$",arc((0,0),0.5,0,degrees(theta)),red,Arrow,PenMargins);
+
+pair z=polar(r,theta);
+draw(z--(z.x,0),dotted+red);
+draw((0,0)--(z.x,0),dotted+red);
+label("$r\cos\theta$",(0.5*z.x,0),0.5*S,red);
+label("$r\sin\theta$",(z.x,0.5*z.y),0.5*E,red);
+dot("$(x,y)$",z,N);
+draw("r",(0,0)--z,0.5*unit(z)*I,blue,Arrow,DotMargin);
+
+dot("$(a,0)$",(1,0),NE);
+dot("$(2a,0)$",(2,0),NE);
+
+
diff --git a/Build/source/utils/asymptote/examples/poster.asy b/Build/source/utils/asymptote/examples/poster.asy
new file mode 100644
index 00000000000..d476dd079de
--- /dev/null
+++ b/Build/source/utils/asymptote/examples/poster.asy
@@ -0,0 +1,32 @@
+orientation=Landscape;
+import slide;
+import graph;
+
+defaultpen(deepblue);
+
+real f(real x) {return (x != 0) ? x*sin(1/x) : 0;}
+pair F(real x) {return (x,f(x));}
+
+xaxis(background,grey);
+yaxis(background,-0.25,0.25,grey);
+real a=1.2/pi;
+draw(background,graph(background,f,-a,a,10000),grey);
+label(background,"$x\sin\frac{1}{x}$",F(0.92/pi),3SE,grey+fontsize(14));
+frame f=background.fit();
+box(f,RadialShade(yellow,0.6*yellow+red),above=false);
+background.erase();
+add(background,f);
+
+title("Young Researchers' Conference",align=3S,fontsize(48));
+center("University of Alberta, Edmonton, April 1--2, 2006");
+
+skip(4);
+
+center("A general conference for\\
+the mathematical and statistical sciences\\
+for graduate students, by graduate students.",fontsize(32));
+
+label("Registration and abstract submission online.",(0,-0.5));
+
+label("\tt http://www.pims.math.ca/science/2006/06yrc/",point(SW),NE,
+ black+fontsize(18));
diff --git a/Build/source/utils/asymptote/examples/progrid.asy b/Build/source/utils/asymptote/examples/progrid.asy
new file mode 100644
index 00000000000..20400b7148a
--- /dev/null
+++ b/Build/source/utils/asymptote/examples/progrid.asy
@@ -0,0 +1 @@
+label("$\displaystyle X_i = \sum_{j=1}^{N} a_{ij} f_j$");
diff --git a/Build/source/utils/asymptote/examples/projectelevation.asy b/Build/source/utils/asymptote/examples/projectelevation.asy
new file mode 100644
index 00000000000..19918c241c9
--- /dev/null
+++ b/Build/source/utils/asymptote/examples/projectelevation.asy
@@ -0,0 +1,18 @@
+import graph3;
+import grid3;
+import palette;
+
+currentprojection=orthographic(0.8,1,2);
+
+size(400,300,IgnoreAspect);
+
+real f(pair z) {return cos(2*pi*z.x)*sin(2*pi*z.y);}
+
+surface s=surface(f,(-1/2,-1/2),(1/2,1/2),50,Spline);
+
+surface S=planeproject(unitsquare3)*s;
+S.colors(palette(s.map(zpart),Rainbow()));
+draw(S,nolight);
+draw(s,lightgray+opacity(0.7));
+
+grid3(XYZgrid);
diff --git a/Build/source/utils/asymptote/examples/projectrevolution.asy b/Build/source/utils/asymptote/examples/projectrevolution.asy
new file mode 100644
index 00000000000..fe639b3b901
--- /dev/null
+++ b/Build/source/utils/asymptote/examples/projectrevolution.asy
@@ -0,0 +1,15 @@
+import solids;
+import palette;
+
+currentprojection=orthographic(20,0,3);
+
+size(400,300,IgnoreAspect);
+
+revolution r=revolution(new real(real x) {return sin(x)*exp(-x/2);},
+ 0,2pi,operator ..,Z);
+surface s=surface(r);
+
+surface S=planeproject(shift(-Z)*unitsquare3)*s;
+S.colors(palette(s.map(zpart),Rainbow()));
+draw(S);
+draw(s,lightgray);
diff --git a/Build/source/utils/asymptote/examples/rainbow.asy b/Build/source/utils/asymptote/examples/rainbow.asy
new file mode 100644
index 00000000000..c85282a87b1
--- /dev/null
+++ b/Build/source/utils/asymptote/examples/rainbow.asy
@@ -0,0 +1,12 @@
+size(200);
+
+pen indigo=rgb(102/255,0,238/255);
+
+void rainbow(path g) {
+ draw(new path[] {scale(1.3)*g,scale(1.2)*g,scale(1.1)*g,g,
+ scale(0.9)*g,scale(0.8)*g,scale(0.7)*g},
+ new pen[] {red,orange,yellow,green,blue,indigo,purple});
+}
+
+rainbow((1,0){N}..(0,1){W}..{S}(-1,0));
+rainbow(scale(4)*shift(-0.5,-0.5)*unitsquare);
diff --git a/Build/source/utils/asymptote/examples/randompath3.asy b/Build/source/utils/asymptote/examples/randompath3.asy
new file mode 100644
index 00000000000..56382d19b89
--- /dev/null
+++ b/Build/source/utils/asymptote/examples/randompath3.asy
@@ -0,0 +1,3 @@
+import three;
+size(300);
+draw(randompath3(100),red,currentlight);
diff --git a/Build/source/utils/asymptote/examples/ring.asy b/Build/source/utils/asymptote/examples/ring.asy
new file mode 100644
index 00000000000..54e0e25d489
--- /dev/null
+++ b/Build/source/utils/asymptote/examples/ring.asy
@@ -0,0 +1,5 @@
+size(0,100);
+path unitcircle=E..N..W..S..cycle;
+path g=scale(2)*unitcircle;
+radialshade(unitcircle^^g,yellow+evenodd,(0,0),1.0,yellow+brown,(0,0),2);
+
diff --git a/Build/source/utils/asymptote/examples/roundpath.asy b/Build/source/utils/asymptote/examples/roundpath.asy
new file mode 100644
index 00000000000..e6d31c6bc9c
--- /dev/null
+++ b/Build/source/utils/asymptote/examples/roundpath.asy
@@ -0,0 +1,32 @@
+// example file for 'roundedpath.asy'
+// written by stefan knorr
+
+// import needed packages
+import roundedpath;
+
+// define open and closed path
+path A = (0,0)--(10,10)--(30,10)--(20,0)--(30,-10)--(10,-10);
+path B = A--cycle;
+
+draw(shift(-60,0)*A, green);
+draw(shift(-30,0)*roundedpath(A,1), red);
+
+// draw open path and some modifications
+for (int i = 1; i < 20; ++i)
+ draw(roundedpath(A,i/4), rgb(1 - i*0.049, 0, i*0.049) + linewidth(0.5));
+
+draw(shift(-60,-30)*B, green);
+draw(shift(-30,-30)*roundedpath(B,1), red);
+
+//draw closed path and some modifications
+for (int i = 1; i < 20; ++i) // only round edges
+ draw(shift(0,-30)*roundedpath(B,i/4), rgb(0.5, i*0.049,0) + linewidth(0.5));
+
+for (int i = 1; i < 20; ++i) // round edged and scale
+ draw(shift(0,-60)*roundedpath(B,i/4,1-i/50), rgb(1, 1 - i*0.049,i*0.049) + linewidth(0.5));
+
+for (int i = 1; i < 50; ++i) // shift (round edged und scaled shifted version)
+ draw(shift(-30,-60)*shift(10,0)*roundedpath(shift(-10,0)*B,i/10,1-i/80), rgb( i*0.024, 1 - i*0.024,0) + linewidth(0.5));
+
+for (int i = 1; i < 20; ++i) // shift (round edged und scaled shifted version)
+ draw(shift(-60,-60)*shift(10,0)*roundedpath(shift(-10,0)*B,i/4,1-i/50), gray(i/40));
diff --git a/Build/source/utils/asymptote/examples/sacone.asy b/Build/source/utils/asymptote/examples/sacone.asy
new file mode 100644
index 00000000000..9cdd0e138af
--- /dev/null
+++ b/Build/source/utils/asymptote/examples/sacone.asy
@@ -0,0 +1,23 @@
+size(0,150);
+
+pair z0=(0,0);
+real r=1;
+real h=1;
+real l=sqrt(r^2+h^2);
+real a=(1-r/l)*360;
+real a1=a/2;
+real a2=360-a/2;
+path g=arc(z0,r,a1,a2);
+fill((0,0)--g--cycle,lightgreen);
+draw(g);
+pair z1=point(g,0);
+pair z2=point(g,length(g));
+
+real r2=1.1*r;
+path c=arc(0,r2,a1,a2);
+draw("$2\pi r$",c,red,Arrows,Bars,PenMargins);
+pen edge=blue+0.5mm;
+draw("$\ell$",z0--z1,0.5*SE,edge);
+draw(z0--z2,edge);
+draw(arc(z0,r,a2-360,a1),grey+dashed);
+dot(0);
diff --git a/Build/source/utils/asymptote/examples/sacone3D.asy b/Build/source/utils/asymptote/examples/sacone3D.asy
new file mode 100644
index 00000000000..1ed60da0351
--- /dev/null
+++ b/Build/source/utils/asymptote/examples/sacone3D.asy
@@ -0,0 +1,13 @@
+import solids;
+
+size(0,75);
+real r=1;
+real h=1;
+
+revolution R=cone(r,h);
+draw(surface(R),lightgreen+opacity(0.5));
+pen edge=blue+0.25mm;
+draw("$\ell$",(0,r,0)--(0,0,h),W,edge);
+draw("$r$",(0,0,0)--(r,0,0),red+dashed);
+draw((0,0,0)--(0,0,h),red+dashed);
+dot(h*Z);
diff --git a/Build/source/utils/asymptote/examples/sacylinder.asy b/Build/source/utils/asymptote/examples/sacylinder.asy
new file mode 100644
index 00000000000..06f7909d52a
--- /dev/null
+++ b/Build/source/utils/asymptote/examples/sacylinder.asy
@@ -0,0 +1,26 @@
+import graph;
+size(0,100);
+
+real r=1;
+real h=3;
+
+yaxis(dashed);
+
+real m=0.475*h;
+
+draw((r,0)--(r,h));
+label("$L$",(r,0.5*h),E);
+
+real s=4;
+
+pair z1=(s,0);
+pair z2=z1+(2*pi*r,h);
+filldraw(box(z1,z2),lightgreen);
+pair zm=0.5*(z1+z2);
+label("$L$",(z1.x,zm.y),W);
+label("$2\pi r$",(zm.x,z2.y),N);
+draw("$r$",(0,m)--(r,m),N,red,Arrows);
+
+draw((0,1.015h),yscale(0.5)*arc(0,0.25cm,-250,70),red,ArcArrow);
+
+
diff --git a/Build/source/utils/asymptote/examples/sacylinder3D.asy b/Build/source/utils/asymptote/examples/sacylinder3D.asy
new file mode 100644
index 00000000000..e44f78e8e72
--- /dev/null
+++ b/Build/source/utils/asymptote/examples/sacylinder3D.asy
@@ -0,0 +1,14 @@
+import solids;
+size(0,100);
+
+real r=1;
+real h=3;
+
+revolution R=cylinder(-h/2*Z,r,h);
+draw(surface(R),lightgreen+opacity(0.5));
+draw((0,0,-h/2)--(0,0,h/2),dashed);
+dot((0,0,-h/2));
+dot((0,0,h/2));
+draw("$L$",(0,r,-h/2)--(0,r,h/2),W,black);
+draw("$r$",(0,0,-h/2)--(0,r,-h/2),red);
+draw(arc(O,1,90,90,90,0),red,Arrow3);
diff --git a/Build/source/utils/asymptote/examples/shade.asy b/Build/source/utils/asymptote/examples/shade.asy
new file mode 100644
index 00000000000..66b8880fd4b
--- /dev/null
+++ b/Build/source/utils/asymptote/examples/shade.asy
@@ -0,0 +1,4 @@
+
+size(100,0);
+radialshade(unitsquare,yellow,(0,0),0,red,(0,0),1);
+
diff --git a/Build/source/utils/asymptote/examples/shadestroke.asy b/Build/source/utils/asymptote/examples/shadestroke.asy
new file mode 100644
index 00000000000..44f0b6e8a3f
--- /dev/null
+++ b/Build/source/utils/asymptote/examples/shadestroke.asy
@@ -0,0 +1,5 @@
+size(100);
+
+radialshade(W..N..E--(0,0),stroke=true,
+ red+linewidth(30),(0,0),0.25,yellow,(0,0),1);
+
diff --git a/Build/source/utils/asymptote/examples/shellmethod.asy b/Build/source/utils/asymptote/examples/shellmethod.asy
new file mode 100644
index 00000000000..c1c0155ae3a
--- /dev/null
+++ b/Build/source/utils/asymptote/examples/shellmethod.asy
@@ -0,0 +1,39 @@
+import graph3;
+import solids;
+
+size(400);
+currentprojection=perspective(0,-1,30,up=Y);
+currentlight=light(gray(0.75),(0.25,-0.25,1),(0,1,0));
+
+pen color=green;
+real alpha=240;
+
+real f(real x) {return 2x^2-x^3;}
+pair F(real x) {return (x,f(x));}
+triple F3(real x) {return (x,f(x),0);}
+
+int n=10;
+path3[] blocks=new path3[n];
+for(int i=1; i <= n; ++i) {
+ real height=f((i-0.5)*2/n);
+ real left=(i-1)*2/n;
+ real right=i*2/n;
+ blocks[i-1]=
+ (left,0,0)--(left,height,0)--(right,height,0)--(right,0,0)--cycle;
+}
+
+path p=graph(F,0,2,n,operator ..)--cycle;
+surface s=surface(p);
+path3 p3=path3(p);
+
+revolution a=revolution(p3,Y,0,alpha);
+draw(surface(a),color);
+draw(rotate(alpha,Y)*s,color);
+for(int i=0; i < n; ++i)
+ draw(surface(blocks[i]),color+opacity(0.5),black);
+draw(p3);
+
+xaxis3(Label("$x$",1,align=2X),Arrow3);
+yaxis3(Label("$y$",1,align=2Y),ymax=1.4,dashed,Arrow3);
+arrow("$y=2x^2-x^3$",XYplane(F(1.8)),X+Z,1.5cm,red,Arrow3(DefaultHead2));
+draw(arc(1.17Y,0.3,90,0,7.5,180),ArcArrow3);
diff --git a/Build/source/utils/asymptote/examples/shellsqrtx01.asy b/Build/source/utils/asymptote/examples/shellsqrtx01.asy
new file mode 100644
index 00000000000..c4edec122c8
--- /dev/null
+++ b/Build/source/utils/asymptote/examples/shellsqrtx01.asy
@@ -0,0 +1,34 @@
+import graph3;
+import solids;
+size(0,150);
+currentprojection=orthographic(1,0,10,up=Y);
+pen color=green;
+real alpha=-240;
+
+real f(real x) {return sqrt(x);}
+pair F(real x) {return (x,f(x));}
+triple F3(real x) {return (x,f(x),0);}
+
+path p=graph(F,0,1,n=30,operator ..)--(1,0)--cycle;
+path3 p3=path3(p);
+
+revolution a=revolution(p3,X,alpha,0);
+draw(surface(a),color);
+draw(p3,blue);
+
+surface s=surface(p);
+draw(s,color);
+draw(rotate(alpha,X)*s,color);
+
+xaxis3(Label("$x$",1),xmax=1.25,dashed,Arrow3);
+yaxis3(Label("$y$",1),Arrow3);
+
+dot("$(1,1)$",(1,1,0));
+arrow("$y=\sqrt{x}$",F3(0.8),Y,0.75cm,red);
+
+real r=0.4;
+draw(F3(r)--(1,f(r),0),red);
+real x=(1+r)/2;
+
+draw("$r$",(x,0,0)--(x,f(r),0),X+0.2Z,red,Arrow3,PenMargin3);
+draw(arc(1.1X,0.4,90,90,3,-90),Arrow3);
diff --git a/Build/source/utils/asymptote/examples/sin1x.asy b/Build/source/utils/asymptote/examples/sin1x.asy
new file mode 100644
index 00000000000..637943691f1
--- /dev/null
+++ b/Build/source/utils/asymptote/examples/sin1x.asy
@@ -0,0 +1,16 @@
+import graph;
+size(200,0);
+
+real f(real x) {return (x != 0) ? sin(1/x) : 0;}
+real T(real x) {return 2/(x*pi);}
+
+real a=-4/pi, b=4/pi;
+int n=150,m=5;
+
+xaxis("$x$",red);
+yaxis(red);
+
+draw(graph(f,a,-T(m),n)--graph(f,-m,-(m+n),n,T)--(0,f(0))--graph(f,m+n,m,n,T)--
+ graph(f,T(m),b,n));
+
+label("$\sin\frac{1}{x}$",(b,f(b)),SW);
diff --git a/Build/source/utils/asymptote/examples/sinc.asy b/Build/source/utils/asymptote/examples/sinc.asy
new file mode 100644
index 00000000000..cd0d377e633
--- /dev/null
+++ b/Build/source/utils/asymptote/examples/sinc.asy
@@ -0,0 +1,19 @@
+import graph3;
+import contour;
+
+currentprojection=orthographic(1,-2,1);
+currentlight=(1,-1,0.5);
+
+size(12cm,0);
+
+real sinc(pair z) {
+ real r=2pi*abs(z);
+ return r != 0 ? sin(r)/r : 1;
+}
+
+draw(lift(sinc,contour(sinc,(-2,-2),(2,2),new real[] {0})),red);
+draw(surface(sinc,(-2,-2),(2,2),Spline),lightgray+opacity(0.5));
+
+xaxis3("$x$",Bounds,InTicks);
+yaxis3("$y$",Bounds,InTicks(beginlabel=false));
+zaxis3("$z$",Bounds,InTicks);
diff --git a/Build/source/utils/asymptote/examples/sinxlex.asy b/Build/source/utils/asymptote/examples/sinxlex.asy
new file mode 100644
index 00000000000..912fa3c889b
--- /dev/null
+++ b/Build/source/utils/asymptote/examples/sinxlex.asy
@@ -0,0 +1,24 @@
+import geometry;
+
+size(0,100);
+real theta=30;
+
+pair A=(0,0);
+pair B=dir(theta);
+pair C=(1,0);
+pair D=(1,Tan(theta));
+pair E=(Cos(theta),0);
+
+filldraw(A--C{N}..B--cycle,lightgrey);
+draw(B--C--D--cycle);
+draw(B--E);
+
+draw("$x$",arc(C,A,B,0.7),RightSide,Arrow,PenMargin);
+
+dot("$A$",A,W);
+dot("$B$",B,NW);
+dot("$C$",C);
+dot("$D$",D);
+dot(("$E$"),E,S);
+label("$1$",A--B,LeftSide);
+
diff --git a/Build/source/utils/asymptote/examples/slidedemo.asy b/Build/source/utils/asymptote/examples/slidedemo.asy
new file mode 100644
index 00000000000..cd1f05b4124
--- /dev/null
+++ b/Build/source/utils/asymptote/examples/slidedemo.asy
@@ -0,0 +1,118 @@
+// Slide demo.
+// Command-line options to enable stepping and/or reverse video:
+// asy [-u stepping=true] [-u reverse=true] slidedemo
+
+orientation=Landscape;
+
+import slide;
+import three;
+
+viewportsize=pagewidth-2pagemargin;
+
+usersetting();
+
+// Commands to generate optional bibtex citations:
+// asy slidedemo
+// bibtex slidedemo_
+// asy slidedemo
+//
+bibliographystyle("alpha");
+
+// Generated needed files if they don't already exist.
+asy(nativeformat(),"Pythagoras","log","PythagoreanTree");
+
+// Optional background color or header:
+// import x11colors;
+// fill(background,box((-1,-1),(1,1)),Azure);
+// label(background,"Header",(0,startposition.y));
+
+titlepage(title="Slides with {\tt Asymptote}: A Demo",
+ author="John C. Bowman",
+ institution="University of Alberta",
+ date="\today",
+ url="http://asymptote.sf.net");
+
+outline("Basic Commands");
+item("item");
+subitem("subitem");
+remark("remark");
+item("draw \cite{Hobby86,Knuth86b}");
+item("figure");
+item("embedded and external animations: see {\tt slidemovie.asy}");
+
+title("Items");
+item("First item.");
+subitem("First subitem.");
+subitem("Second subitem.");
+item("Second item.");
+equation("a^2+b^2=c^2.");
+equations("\frac{\sin^2\theta+\cos^2\theta}{\cos^2\theta}
+&=&\frac{1}{\cos^2\theta}\nonumber\\
+&=&\sec^2\theta.");
+remark("A remark.");
+item("To enable pausing between bullets:");
+remark("{\tt asy -u stepping=true}");
+item("To enable reverse video:");
+remark("{\tt asy -u reverse=true}");
+
+title("Can draw on a slide, preserving the aspect ratio:");
+picture pic,pic2;
+draw(pic,unitcircle);
+add(pic.fit(15cm));
+step();
+fill(pic2,unitcircle,paleblue);
+label(pic2,"$\pi$",(0,0),fontsize(500));
+add(pic2.fit(15cm));
+
+newslide();
+item("The slide \Red{title} \Green{can} \Blue{be} omitted.");
+figure("Pythagoras","height=12cm",
+ "A simple proof of Pythagoras' Theorem.");
+
+newslide();
+item("Single skip:");
+skip();
+item("Double skip:");
+skip(2);
+figure(new string[] {"log."+nativeformat(),"PythagoreanTree."+nativeformat()},
+ "width=10cm",new string[] {"{\tt log.asy}","{\tt PythagoreanTree.asy}"},
+ "Examples of {\tt Asymptote} output.");
+
+title("Embedded Interactive 3D Graphics");
+picture pic;
+import graph3;
+import solids;
+viewportmargin=(0,1cm);
+currentprojection=orthographic(1,0,10,up=Y);
+pen color=green;
+real alpha=-240;
+real f(real x) {return sqrt(x);}
+pair F(real x) {return (x,f(x));}
+triple F3(real x) {return (x,f(x),0);}
+path p=graph(pic,F,0,1,n=30,operator ..)--(1,0)--cycle;
+path3 p3=path3(p);
+revolution a=revolution(p3,X,alpha,0);
+draw(pic,surface(a),color);
+draw(pic,p3,blue);
+surface s=surface(p);
+draw(pic,s,color);
+draw(pic,rotate(alpha,X)*s,color);
+xaxis3(pic,Label("$x$",1),xmax=1.25,dashed,Arrow3);
+yaxis3(pic,Label("$y$",1),Arrow3);
+dot(pic,"$(1,1)$",(1,1,0));
+arrow(pic,"$y=\sqrt{x}$",F3(0.8),Y,0.75cm,red);
+real r=0.4;
+draw(pic,F3(r)--(1,f(r),0),red);
+real x=(1+r)/2;
+draw(pic,"$r$",(x,0,0)--(x,f(r),0),X+0.2Z,red,Arrow3);
+draw(pic,arc(1.1X,0.4,90,90,3,-90),Arrow3);
+add(pic.fit(8.5cm));
+
+viewportsize=viewportmargin=0;
+title("\mbox{Asymptote: 2D \& 3D Vector Graphics Language}");
+asyinclude("logo3");
+skip();
+center("\tt http://asymptote.sf.net");
+center("(freely available under the GNU public license)");
+
+bibliography("refs");
diff --git a/Build/source/utils/asymptote/examples/slidedemo_.bbl b/Build/source/utils/asymptote/examples/slidedemo_.bbl
new file mode 100644
index 00000000000..b3e55e47eee
--- /dev/null
+++ b/Build/source/utils/asymptote/examples/slidedemo_.bbl
@@ -0,0 +1,13 @@
+\begin{thebibliography}{Knu86}
+
+\bibitem[Hob86]{Hobby86}
+John~D. Hobby.
+\newblock Smooth, easy to compute interpolating splines.
+\newblock {\em Discrete Comput. Geom.}, 1:123--140, 1986.
+
+\bibitem[Knu86]{Knuth86b}
+Donald~E. Knuth.
+\newblock {\em The METAFONTbook}.
+\newblock Addison-Wesley, Reading, Massachusetts, 1986.
+
+\end{thebibliography}
diff --git a/Build/source/utils/asymptote/examples/slidemovies.asy b/Build/source/utils/asymptote/examples/slidemovies.asy
new file mode 100644
index 00000000000..ec724cf3326
--- /dev/null
+++ b/Build/source/utils/asymptote/examples/slidemovies.asy
@@ -0,0 +1,46 @@
+// Slide demo.
+// Command-line options to enable stepping and/or reverse video:
+// asy [-u stepping=true] [-u reverse=true] slidedemo
+
+orientation=Landscape;
+
+settings.tex="pdflatex";
+
+import slide;
+
+// Optional movie modules:
+import animate; // For portable embedded PDF movies
+import external; // For portable external movies
+import embed; // For non-portable embedded movies
+
+usersetting();
+
+titlepage("Slides with {\tt Asymptote}: Animations","John C. Bowman",
+ "University of Alberta","\today","http://asymptote.sf.net");
+
+title("Embedded PDF movies (portable)");
+animation a=animation("A");
+animation b=animation("B");
+int n=20;
+for(int i=0; i < 2n; ++i) {
+ picture pic;
+ size(pic,100);
+ draw(pic,shift(0,sin(pi/n*i))*unitsquare);
+ a.add(pic);
+ if(i < 1.5n) b.add(rotate(45)*pic);
+}
+display(a.pdf("autoplay,loop,controls"));
+display(b.pdf("controls"));
+
+title("External Movie (portable)");
+display(external.embed("animations/wheel.mpg",
+ "poster,text=wheel.mpg,label=wheel.mpg",20cm,5.6cm));
+display(external.link("animations/wheel.mpg","Play","play"));
+
+title("Embedded Movie (not portable)");
+// Generated needed files if they don't already exist.
+asy("mpg","animations/wheel");
+display(embed.embed("animations/wheel.mpg",
+ "poster,text=wheel.mpg,label=wheel.mpg",
+ 20cm,5.6cm));
+display(embed.link("animations/wheel.mpg","Play","play"));
diff --git a/Build/source/utils/asymptote/examples/smoothelevation.asy b/Build/source/utils/asymptote/examples/smoothelevation.asy
new file mode 100644
index 00000000000..29ee84ba688
--- /dev/null
+++ b/Build/source/utils/asymptote/examples/smoothelevation.asy
@@ -0,0 +1,24 @@
+import graph3;
+import grid3;
+import palette;
+
+if(settings.render <= 0) settings.prc=false;
+
+currentprojection=orthographic(1,2,13);
+
+size(400,300,IgnoreAspect);
+
+real f(pair z) {return cos(2*pi*z.x)*sin(2*pi*z.y);}
+
+surface s=surface(f,(-1/2,-1/2),(1/2,1/2),20,Spline);
+s.colors(palette(s.map(zpart),Rainbow()));
+
+draw(s);
+
+scale(true);
+
+xaxis3(Label("$x$",0.5),Bounds,InTicks);
+yaxis3(Label("$y$",0.5),Bounds,InTicks);
+zaxis3(Label("$z$",0.5),Bounds,InTicks(beginlabel=false));
+
+grid3(XYZgrid);
diff --git a/Build/source/utils/asymptote/examples/sphere.asy b/Build/source/utils/asymptote/examples/sphere.asy
new file mode 100644
index 00000000000..8c5a444d01a
--- /dev/null
+++ b/Build/source/utils/asymptote/examples/sphere.asy
@@ -0,0 +1,6 @@
+import three;
+
+size(200);
+currentprojection=orthographic(5,4,3);
+
+draw(unitsphere,green);
diff --git a/Build/source/utils/asymptote/examples/spheresilhouette.asy b/Build/source/utils/asymptote/examples/spheresilhouette.asy
new file mode 100644
index 00000000000..795efb00660
--- /dev/null
+++ b/Build/source/utils/asymptote/examples/spheresilhouette.asy
@@ -0,0 +1,9 @@
+import solids;
+settings.render=0;
+settings.prc=false;
+
+size(200);
+
+revolution r=sphere(O,1);
+draw(r,1,longitudinalpen=nullpen);
+draw(r.silhouette());
diff --git a/Build/source/utils/asymptote/examples/sphereskeleton.asy b/Build/source/utils/asymptote/examples/sphereskeleton.asy
new file mode 100644
index 00000000000..ca8b8c3d584
--- /dev/null
+++ b/Build/source/utils/asymptote/examples/sphereskeleton.asy
@@ -0,0 +1,9 @@
+size(100);
+import solids;
+
+currentprojection=orthographic(5,4,2);
+
+revolution sphere=sphere(1);
+draw(surface(sphere),green+opacity(0.2));
+draw(sphere,m=7,blue);
+
diff --git a/Build/source/utils/asymptote/examples/sphericalharmonic.asy b/Build/source/utils/asymptote/examples/sphericalharmonic.asy
new file mode 100644
index 00000000000..471bcaae9cd
--- /dev/null
+++ b/Build/source/utils/asymptote/examples/sphericalharmonic.asy
@@ -0,0 +1,12 @@
+import graph3;
+import palette;
+size(200);
+
+currentprojection=orthographic(4,2,4);
+
+real r(real theta, real phi) {return 1+0.5*(sin(2*theta)*sin(2*phi))^2;}
+
+triple f(pair z) {return r(z.x,z.y)*expi(z.x,z.y);}
+
+surface s=surface(f,(0,0),(pi,2pi),50);
+draw(s,mean(palette(s.map(abs),Gradient(yellow,red))),nolight);
diff --git a/Build/source/utils/asymptote/examples/spiral.asy b/Build/source/utils/asymptote/examples/spiral.asy
new file mode 100644
index 00000000000..a417ea06a7f
--- /dev/null
+++ b/Build/source/utils/asymptote/examples/spiral.asy
@@ -0,0 +1,12 @@
+size(0,150);
+import graph;
+
+real f(real t) {return exp(-t/(2pi));}
+
+draw(polargraph(f,0,20*pi,operator ..));
+
+xaxis("$x$",-infinity,1.3);
+yaxis("$y$",-infinity,1);
+
+labelx(1);
+labelx("$e^{-1}$",1.0/exp(1),SE);
diff --git a/Build/source/utils/asymptote/examples/spline.asy b/Build/source/utils/asymptote/examples/spline.asy
new file mode 100644
index 00000000000..9d79ef3a962
--- /dev/null
+++ b/Build/source/utils/asymptote/examples/spline.asy
@@ -0,0 +1,25 @@
+import graph;
+import interpolate;
+
+size(15cm,15cm,IgnoreAspect);
+
+real a=1997, b=2002;
+int n=5;
+real[] xpt=a+sequence(n+1)*(b-a)/n;
+real[] ypt={31,36,26,22,21,24};
+horner h=diffdiv(xpt,ypt);
+fhorner L=fhorner(h);
+
+scale(false,true);
+
+pen p=linewidth(1);
+
+draw(graph(L,a,b),dashed+black+p,"Lagrange interpolation");
+draw(graph(xpt,ypt,Hermite(natural)),red+p,"natural spline");
+draw(graph(xpt,ypt,Hermite(monotonic)),blue+p,"monotone spline");
+xaxis("$x$",BottomTop,LeftTicks(Step=1,step=0.25));
+yaxis("$y$",LeftRight,RightTicks(Step=5));
+
+dot(pairs(xpt,ypt),4bp+gray(0.3));
+
+attach(legend(),point(10S),30S);
diff --git a/Build/source/utils/asymptote/examples/spring.asy b/Build/source/utils/asymptote/examples/spring.asy
new file mode 100644
index 00000000000..cbfb256eee4
--- /dev/null
+++ b/Build/source/utils/asymptote/examples/spring.asy
@@ -0,0 +1,33 @@
+pair coilpoint(real lambda, real r, real t)
+{
+ return (2.0*lambda*t+r*cos(t),r*sin(t));
+}
+
+guide coil(guide g=nullpath, real lambda, real r, real a, real b, int n)
+{
+ real width=(b-a)/n;
+ for(int i=0; i <= n; ++i) {
+ real t=a+width*i;
+ g=g..coilpoint(lambda,r,t);
+ }
+ return g;
+}
+
+void drawspring(real x, string label) {
+ real r=8;
+ real t1=-pi;
+ real t2=10*pi;
+ real lambda=(t2-t1+x)/(t2-t1);
+ pair b=coilpoint(lambda,r,t1);
+ pair c=coilpoint(lambda,r,t2);
+ pair a=b-20;
+ pair d=c+20;
+
+ draw(a--b,BeginBar(2*barsize()));
+ draw(c--d);
+ draw(coil(lambda,r,t1,t2,100));
+ dot(d);
+
+ pair h=20*I;
+ draw(label,a-h--d-h,red,Arrow,Bars,PenMargin);
+}
diff --git a/Build/source/utils/asymptote/examples/spring0.asy b/Build/source/utils/asymptote/examples/spring0.asy
new file mode 100644
index 00000000000..fd6cdf82938
--- /dev/null
+++ b/Build/source/utils/asymptote/examples/spring0.asy
@@ -0,0 +1,4 @@
+import spring;
+
+drawspring(0,"$L$");
+
diff --git a/Build/source/utils/asymptote/examples/spring2.asy b/Build/source/utils/asymptote/examples/spring2.asy
new file mode 100644
index 00000000000..e3eec5f39f5
--- /dev/null
+++ b/Build/source/utils/asymptote/examples/spring2.asy
@@ -0,0 +1,4 @@
+import spring;
+
+drawspring(40.0,"$L+x$");
+
diff --git a/Build/source/utils/asymptote/examples/sqrtx01.asy b/Build/source/utils/asymptote/examples/sqrtx01.asy
new file mode 100644
index 00000000000..2ca9ac697d6
--- /dev/null
+++ b/Build/source/utils/asymptote/examples/sqrtx01.asy
@@ -0,0 +1,25 @@
+import graph3;
+import solids;
+size(0,150);
+currentprojection=perspective(1.5,0,10,Y);
+pen color=green+opacity(0.75);
+
+real f(real x){return sqrt(x);}
+pair F(real x){return (x,f(x));}
+triple F3(real x){return (x,f(x),0);}
+
+path p=graph(F,0,1,n=20,operator ..);
+path3 p3=path3(p);
+
+revolution a=revolution(p3,X,0,360);
+draw(surface(a),color);
+draw(p3,blue);
+
+real x=relpoint(p,0.5).x;
+
+xaxis3(Label("$x$",1),xmax=1.5,dashed,Arrow3);
+yaxis3(Label("$y$",1),Arrow3);
+dot(Label("$(1,1)$"),(1,1,0));
+arrow(Label("$y=\sqrt{x}$"),F3(0.7),Y,0.75cm,red);
+draw(arc(1.2X,0.4,90,90,175,-40,CW),Arrow3);
+draw("$r$",(x,0,0)--F3(x),red,Arrow3,PenMargin3);
diff --git a/Build/source/utils/asymptote/examples/sqrtx01y1.asy b/Build/source/utils/asymptote/examples/sqrtx01y1.asy
new file mode 100644
index 00000000000..c944f43d268
--- /dev/null
+++ b/Build/source/utils/asymptote/examples/sqrtx01y1.asy
@@ -0,0 +1,24 @@
+import graph3;
+import solids;
+size(0,150);
+currentprojection=perspective(0,1,10,up=Y);
+
+real f(real x) {return sqrt(x);}
+pair F(real x) {return (x,f(x));}
+triple F3(real x) {return (x,f(x),0);}
+
+path p=graph(F,0,1,n=25,operator ..);
+path3 p3=path3(p);
+
+revolution a=revolution(p3,Y,0,360);
+draw(surface(a),green);
+draw(p3,blue);
+
+xtick((0,0,0));
+xtick((1,0,0));
+
+xaxis3(Label("$x$",1),Arrow3);
+yaxis3(Label("$y$",1),ymax=1.5,dashed,Arrow3);
+dot(Label("$(1,1)$"),(1,1,0));
+arrow("$y=\sqrt{x}$",F3(0.5),X,0.75cm,red);
+draw(arc(1.2Y,0.3,90,0,7.5,140),Arrow3);
diff --git a/Build/source/utils/asymptote/examples/star.asy b/Build/source/utils/asymptote/examples/star.asy
new file mode 100644
index 00000000000..3a7afb2529b
--- /dev/null
+++ b/Build/source/utils/asymptote/examples/star.asy
@@ -0,0 +1,13 @@
+size(100);
+import math;
+
+int n=5;
+path p;
+
+int i=0;
+do {
+ p=p--unityroot(n,i);
+ i=(i+2) % n;
+} while(i != 0);
+
+filldraw(p--cycle,red+evenodd);
diff --git a/Build/source/utils/asymptote/examples/stroke3.asy b/Build/source/utils/asymptote/examples/stroke3.asy
new file mode 100644
index 00000000000..6b386c3a0c9
--- /dev/null
+++ b/Build/source/utils/asymptote/examples/stroke3.asy
@@ -0,0 +1,2 @@
+import three;
+draw(O--X,red,currentlight);
diff --git a/Build/source/utils/asymptote/examples/strokepath.asy b/Build/source/utils/asymptote/examples/strokepath.asy
new file mode 100644
index 00000000000..ee18b1c9bfe
--- /dev/null
+++ b/Build/source/utils/asymptote/examples/strokepath.asy
@@ -0,0 +1,17 @@
+path g=scale(100)*unitcircle;
+pen p=linewidth(1cm);
+
+frame f;
+// Equivalent to draw(f,g,p):
+fill(f,strokepath(g,p),red);
+shipout("strokepathframe",f);
+shipped=false;
+
+size(400);
+
+// Equivalent to draw(g,p):
+currentpicture.add(new void(frame f, transform t) {
+ fill(f,strokepath(t*g,p),red);
+ });
+currentpicture.addPath(g,p);
+
diff --git a/Build/source/utils/asymptote/examples/strokeshade.asy b/Build/source/utils/asymptote/examples/strokeshade.asy
new file mode 100644
index 00000000000..f9413091d1c
--- /dev/null
+++ b/Build/source/utils/asymptote/examples/strokeshade.asy
@@ -0,0 +1,4 @@
+size(100);
+guide g=(0,0)..controls(70,30) and (-40,30)..(30,0);
+latticeshade(g,stroke=true,linewidth(10),
+ new pen[][] {{red,orange,yellow},{green,blue,purple}});
diff --git a/Build/source/utils/asymptote/examples/tanh.asy b/Build/source/utils/asymptote/examples/tanh.asy
new file mode 100644
index 00000000000..21d4decb1a6
--- /dev/null
+++ b/Build/source/utils/asymptote/examples/tanh.asy
@@ -0,0 +1,13 @@
+import graph;
+size(100,0);
+
+real f(real x) {return tanh(x);}
+pair F(real x) {return (x,f(x));}
+
+xaxis("$x$");
+yaxis("$y$");
+
+draw(graph(f,-2.5,2.5,operator ..));
+
+label("$\tanh x$",F(1.5),1.25*N);
+
diff --git a/Build/source/utils/asymptote/examples/teapot.asy b/Build/source/utils/asymptote/examples/teapot.asy
new file mode 100644
index 00000000000..4b23aecb3b9
--- /dev/null
+++ b/Build/source/utils/asymptote/examples/teapot.asy
@@ -0,0 +1,202 @@
+import three;
+
+size(20cm);
+
+currentprojection=perspective(250,-250,250,center=true);
+
+triple[][][] Q={
+ {
+ {(39.68504,0.0,68.03150),(39.68504,-22.22362,68.03150),(22.22362,-39.68504,68.03150),(0.0,-39.68504,68.03150)},
+ {(37.91339,0.0,71.75197),(37.91339,-21.23150,71.75197),(21.23150,-37.91339,71.75197),(0.0,-37.91339,71.75197)},
+ {(40.74803,0.0,71.75197),(40.74803,-22.81890,71.75197),(22.81890,-40.74803,71.75197),(0.0,-40.74803,71.75197)},
+ {(42.51969,0.0,68.03150),(42.51969,-23.81102,68.03150),(23.81102,-42.51969,68.03150),(0.0,-42.51969,68.03150)},
+ },
+ {
+ {(0.0,-39.68504,68.03150),(-22.22362,-39.68504,68.03150),(-39.68504,-22.22362,68.03150),(-39.68504,0.0,68.03150)},
+ {(0.0,-37.91339,71.75197),(-21.23150,-37.91339,71.75197),(-37.91339,-21.23150,71.75197),(-37.91339,0.0,71.75197)},
+ {(0.0,-40.74803,71.75197),(-22.81890,-40.74803,71.75197),(-40.74803,-22.81890,71.75197),(-40.74803,0.0,71.75197)},
+ {(0.0,-42.51969,68.03150),(-23.81102,-42.51969,68.03150),(-42.51969,-23.81102,68.03150),(-42.51969,0.0,68.03150)},
+ },
+ {
+ {(-39.68504,0.0,68.03150),(-39.68504,22.22362,68.03150),(-22.22362,39.68504,68.03150),(0.0,39.68504,68.03150)},
+ {(-37.91339,0.0,71.75197),(-37.91339,21.23150,71.75197),(-21.23150,37.91339,71.75197),(0.0,37.91339,71.75197)},
+ {(-40.74803,0.0,71.75197),(-40.74803,22.81890,71.75197),(-22.81890,40.74803,71.75197),(0.0,40.74803,71.75197)},
+ {(-42.51969,0.0,68.03150),(-42.51969,23.81102,68.03150),(-23.81102,42.51969,68.03150),(0.0,42.51969,68.03150)},
+ },
+ {
+ {(0.0,39.68504,68.03150),(22.22362,39.68504,68.03150),(39.68504,22.22362,68.03150),(39.68504,0.0,68.03150)},
+ {(0.0,37.91339,71.75197),(21.23150,37.91339,71.75197),(37.91339,21.23150,71.75197),(37.91339,0.0,71.75197)},
+ {(0.0,40.74803,71.75197),(22.81890,40.74803,71.75197),(40.74803,22.81890,71.75197),(40.74803,0.0,71.75197)},
+ {(0.0,42.51969,68.03150),(23.81102,42.51969,68.03150),(42.51969,23.81102,68.03150),(42.51969,0.0,68.03150)},
+ },
+ {
+ {(42.51969,0.0,68.03150),(42.51969,-23.81102,68.03150),(23.81102,-42.51969,68.03150),(0.0,-42.51969,68.03150)},
+ {(49.60629,0.0,53.14960),(49.60629,-27.77952,53.14960),(27.77952,-49.60629,53.14960),(0.0,-49.60629,53.14960)},
+ {(56.69291,0.0,38.26771),(56.69291,-31.74803,38.26771),(31.74803,-56.69291,38.26771),(0.0,-56.69291,38.26771)},
+ {(56.69291,0.0,25.51181),(56.69291,-31.74803,25.51181),(31.74803,-56.69291,25.51181),(0.0,-56.69291,25.51181)},
+ },
+ {
+ {(0.0,-42.51969,68.03150),(-23.81102,-42.51969,68.03150),(-42.51969,-23.81102,68.03150),(-42.51969,0.0,68.03150)},
+ {(0.0,-49.60629,53.14960),(-27.77952,-49.60629,53.14960),(-49.60629,-27.77952,53.14960),(-49.60629,0.0,53.14960)},
+ {(0.0,-56.69291,38.26771),(-31.74803,-56.69291,38.26771),(-56.69291,-31.74803,38.26771),(-56.69291,0.0,38.26771)},
+ {(0.0,-56.69291,25.51181),(-31.74803,-56.69291,25.51181),(-56.69291,-31.74803,25.51181),(-56.69291,0.0,25.51181)},
+ },
+ {
+ {(-42.51969,0.0,68.03150),(-42.51969,23.81102,68.03150),(-23.81102,42.51969,68.03150),(0.0,42.51969,68.03150)},
+ {(-49.60629,0.0,53.14960),(-49.60629,27.77952,53.14960),(-27.77952,49.60629,53.14960),(0.0,49.60629,53.14960)},
+ {(-56.69291,0.0,38.26771),(-56.69291,31.74803,38.26771),(-31.74803,56.69291,38.26771),(0.0,56.69291,38.26771)},
+ {(-56.69291,0.0,25.51181),(-56.69291,31.74803,25.51181),(-31.74803,56.69291,25.51181),(0.0,56.69291,25.51181)},
+ },
+ {
+ {(0.0,42.51969,68.03150),(23.81102,42.51969,68.03150),(42.51969,23.81102,68.03150),(42.51969,0.0,68.03150)},
+ {(0.0,49.60629,53.14960),(27.77952,49.60629,53.14960),(49.60629,27.77952,53.14960),(49.60629,0.0,53.14960)},
+ {(0.0,56.69291,38.26771),(31.74803,56.69291,38.26771),(56.69291,31.74803,38.26771),(56.69291,0.0,38.26771)},
+ {(0.0,56.69291,25.51181),(31.74803,56.69291,25.51181),(56.69291,31.74803,25.51181),(56.69291,0.0,25.51181)},
+ },
+ {
+ {(56.69291,0.0,25.51181),(56.69291,-31.74803,25.51181),(31.74803,-56.69291,25.51181),(0.0,-56.69291,25.51181)},
+ {(56.69291,0.0,12.75590),(56.69291,-31.74803,12.75590),(31.74803,-56.69291,12.75590),(0.0,-56.69291,12.75590)},
+ {(42.51969,0.0,6.377957),(42.51969,-23.81102,6.377957),(23.81102,-42.51969,6.377957),(0.0,-42.51969,6.377957)},
+ {(42.51969,0.0,4.251961),(42.51969,-23.81102,4.251961),(23.81102,-42.51969,4.251961),(0.0,-42.51969,4.251961)},
+ },
+ {
+ {(0.0,-56.69291,25.51181),(-31.74803,-56.69291,25.51181),(-56.69291,-31.74803,25.51181),(-56.69291,0.0,25.51181)},
+ {(0.0,-56.69291,12.75590),(-31.74803,-56.69291,12.75590),(-56.69291,-31.74803,12.75590),(-56.69291,0.0,12.75590)},
+ {(0.0,-42.51969,6.377957),(-23.81102,-42.51969,6.377957),(-42.51969,-23.81102,6.377957),(-42.51969,0.0,6.377957)},
+ {(0.0,-42.51969,4.251961),(-23.81102,-42.51969,4.251961),(-42.51969,-23.81102,4.251961),(-42.51969,0.0,4.251961)},
+ },
+ {
+ {(-56.69291,0.0,25.51181),(-56.69291,31.74803,25.51181),(-31.74803,56.69291,25.51181),(0.0,56.69291,25.51181)},
+ {(-56.69291,0.0,12.75590),(-56.69291,31.74803,12.75590),(-31.74803,56.69291,12.75590),(0.0,56.69291,12.75590)},
+ {(-42.51969,0.0,6.377957),(-42.51969,23.81102,6.377957),(-23.81102,42.51969,6.377957),(0.0,42.51969,6.377957)},
+ {(-42.51969,0.0,4.251961),(-42.51969,23.81102,4.251961),(-23.81102,42.51969,4.251961),(0.0,42.51969,4.251961)},
+ },
+ {
+ {(0.0,56.69291,25.51181),(31.74803,56.69291,25.51181),(56.69291,31.74803,25.51181),(56.69291,0.0,25.51181)},
+ {(0.0,56.69291,12.75590),(31.74803,56.69291,12.75590),(56.69291,31.74803,12.75590),(56.69291,0.0,12.75590)},
+ {(0.0,42.51969,6.377957),(23.81102,42.51969,6.377957),(42.51969,23.81102,6.377957),(42.51969,0.0,6.377957)},
+ {(0.0,42.51969,4.251961),(23.81102,42.51969,4.251961),(42.51969,23.81102,4.251961),(42.51969,0.0,4.251961)},
+ },
+ {
+ {(-45.35433,0.0,57.40157),(-45.35433,-8.503932,57.40157),(-42.51969,-8.503932,63.77952),(-42.51969,0.0,63.77952)},
+ {(-65.19685,0.0,57.40157),(-65.19685,-8.503932,57.40157),(-70.86614,-8.503932,63.77952),(-70.86614,0.0,63.77952)},
+ {(-76.53543,0.0,57.40157),(-76.53543,-8.503932,57.40157),(-85.03937,-8.503932,63.77952),(-85.03937,0.0,63.77952)},
+ {(-76.53543,0.0,51.02362),(-76.53543,-8.503932,51.02362),(-85.03937,-8.503932,51.02362),(-85.03937,0.0,51.02362)},
+ },
+ {
+ {(-42.51969,0.0,63.77952),(-42.51969,8.503932,63.77952),(-45.35433,8.503932,57.40157),(-45.35433,0.0,57.40157)},
+ {(-70.86614,0.0,63.77952),(-70.86614,8.503932,63.77952),(-65.19685,8.503932,57.40157),(-65.19685,0.0,57.40157)},
+ {(-85.03937,0.0,63.77952),(-85.03937,8.503932,63.77952),(-76.53543,8.503932,57.40157),(-76.53543,0.0,57.40157)},
+ {(-85.03937,0.0,51.02362),(-85.03937,8.503932,51.02362),(-76.53543,8.503932,51.02362),(-76.53543,0.0,51.02362)},
+ },
+ {
+ {(-76.53543,0.0,51.02362),(-76.53543,-8.503932,51.02362),(-85.03937,-8.503932,51.02362),(-85.03937,0.0,51.02362)},
+ {(-76.53543,0.0,44.64566),(-76.53543,-8.503932,44.64566),(-85.03937,-8.503932,38.26771),(-85.03937,0.0,38.26771)},
+ {(-70.86614,0.0,31.88976),(-70.86614,-8.503932,31.88976),(-75.11811,-8.503932,26.57480),(-75.11811,0.0,26.57480)},
+ {(-56.69291,0.0,25.51181),(-56.69291,-8.503932,25.51181),(-53.85826,-8.503932,17.00787),(-53.85826,0.0,17.00787)},
+ },
+ {
+ {(-85.03937,0.0,51.02362),(-85.03937,8.503932,51.02362),(-76.53543,8.503932,51.02362),(-76.53543,0.0,51.02362)},
+ {(-85.03937,0.0,38.26771),(-85.03937,8.503932,38.26771),(-76.53543,8.503932,44.64566),(-76.53543,0.0,44.64566)},
+ {(-75.11811,0.0,26.57480),(-75.11811,8.503932,26.57480),(-70.86614,8.503932,31.88976),(-70.86614,0.0,31.88976)},
+ {(-53.85826,0.0,17.00787),(-53.85826,8.503932,17.00787),(-56.69291,8.503932,25.51181),(-56.69291,0.0,25.51181)},
+ },
+ {
+ {(48.18897,0.0,40.39370),(48.18897,-18.70866,40.39370),(48.18897,-18.70866,17.00787),(48.18897,0.0,17.00787)},
+ {(73.70078,0.0,40.39370),(73.70078,-18.70866,40.39370),(87.87401,-18.70866,23.38582),(87.87401,0.0,23.38582)},
+ {(65.19685,0.0,59.52755),(65.19685,-7.086619,59.52755),(68.03150,-7.086619,57.40157),(68.03150,0.0,57.40157)},
+ {(76.53543,0.0,68.03150),(76.53543,-7.086619,68.03150),(93.54330,-7.086619,68.03150),(93.54330,0.0,68.03150)},
+ },
+ {
+ {(48.18897,0.0,17.00787),(48.18897,18.70866,17.00787),(48.18897,18.70866,40.39370),(48.18897,0.0,40.39370)},
+ {(87.87401,0.0,23.38582),(87.87401,18.70866,23.38582),(73.70078,18.70866,40.39370),(73.70078,0.0,40.39370)},
+ {(68.03150,0.0,57.40157),(68.03150,7.086619,57.40157),(65.19685,7.086619,59.52755),(65.19685,0.0,59.52755)},
+ {(93.54330,0.0,68.03150),(93.54330,7.086619,68.03150),(76.53543,7.086619,68.03150),(76.53543,0.0,68.03150)},
+ },
+ {
+ {(76.53543,0.0,68.03150),(76.53543,-7.086619,68.03150),(93.54330,-7.086619,68.03150),(93.54330,0.0,68.03150)},
+ {(79.37007,0.0,70.15748),(79.37007,-7.086619,70.15748),(99.92125,-7.086619,70.68897),(99.92125,0.0,70.68897)},
+ {(82.20472,0.0,70.15748),(82.20472,-4.251961,70.15748),(97.79527,-4.251961,71.22047),(97.79527,0.0,71.22047)},
+ {(79.37007,0.0,68.03150),(79.37007,-4.251961,68.03150),(90.70866,-4.251961,68.03150),(90.70866,0.0,68.03150)},
+ },
+ {
+ {(93.54330,0.0,68.03150),(93.54330,7.086619,68.03150),(76.53543,7.086619,68.03150),(76.53543,0.0,68.03150)},
+ {(99.92125,0.0,70.68897),(99.92125,7.086619,70.68897),(79.37007,7.086619,70.15748),(79.37007,0.0,70.15748)},
+ {(97.79527,0.0,71.22047),(97.79527,4.251961,71.22047),(82.20472,4.251961,70.15748),(82.20472,0.0,70.15748)},
+ {(90.70866,0.0,68.03150),(90.70866,4.251961,68.03150),(79.37007,4.251961,68.03150),(79.37007,0.0,68.03150)},
+ },
+ {
+ {(0.0,0.0,89.29133),(0.0,0.0,89.29133),(0.0,0.0,89.29133),(0.0,0.0,89.29133)},
+ {(22.67716,0.0,89.29133),(22.67716,-12.75590,89.29133),(12.75590,-22.67716,89.29133),(0.0,-22.67716,89.29133)},
+ {(0.0,0.0,80.78740),(0.0,0.0,80.78740),(0.0,0.0,80.78740),(0.0,0.0,80.78740)},
+ {(5.669294,0.0,76.53543),(5.669294,-3.174809,76.53543),(3.174809,-5.669294,76.53543),(0.0,-5.669294,76.53543)},
+ },
+ {
+ {(0.0,0.0,89.29133),(0.0,0.0,89.29133),(0.0,0.0,89.29133),(0.0,0.0,89.29133)},
+ {(0.0,-22.67716,89.29133),(-12.75590,-22.67716,89.29133),(-22.67716,-12.75590,89.29133),(-22.67716,0.0,89.29133)},
+ {(0.0,0.0,80.78740),(0.0,0.0,80.78740),(0.0,0.0,80.78740),(0.0,0.0,80.78740)},
+ {(0.0,-5.669294,76.53543),(-3.174809,-5.669294,76.53543),(-5.669294,-3.174809,76.53543),(-5.669294,0.0,76.53543)},
+ },
+ {
+ {(0.0,0.0,89.29133),(0.0,0.0,89.29133),(0.0,0.0,89.29133),(0.0,0.0,89.29133)},
+ {(-22.67716,0.0,89.29133),(-22.67716,12.75590,89.29133),(-12.75590,22.67716,89.29133),(0.0,22.67716,89.29133)},
+ {(0.0,0.0,80.78740),(0.0,0.0,80.78740),(0.0,0.0,80.78740),(0.0,0.0,80.78740)},
+ {(-5.669294,0.0,76.53543),(-5.669294,3.174809,76.53543),(-3.174809,5.669294,76.53543),(0.0,5.669294,76.53543)},
+ },
+ {
+ {(0.0,0.0,89.29133),(0.0,0.0,89.29133),(0.0,0.0,89.29133),(0.0,0.0,89.29133)},
+ {(0.0,22.67716,89.29133),(12.75590,22.67716,89.29133),(22.67716,12.75590,89.29133),(22.67716,0.0,89.29133)},
+ {(0.0,0.0,80.78740),(0.0,0.0,80.78740),(0.0,0.0,80.78740),(0.0,0.0,80.78740)},
+ {(0.0,5.669294,76.53543),(3.174809,5.669294,76.53543),(5.669294,3.174809,76.53543),(5.669294,0.0,76.53543)},
+ },
+ {
+ {(5.669294,0.0,76.53543),(5.669294,-3.174809,76.53543),(3.174809,-5.669294,76.53543),(0.0,-5.669294,76.53543)},
+ {(11.33858,0.0,72.28346),(11.33858,-6.349609,72.28346),(6.349609,-11.33858,72.28346),(0.0,-11.33858,72.28346)},
+ {(36.85039,0.0,72.28346),(36.85039,-20.63622,72.28346),(20.63622,-36.85039,72.28346),(0.0,-36.85039,72.28346)},
+ {(36.85039,0.0,68.03150),(36.85039,-20.63622,68.03150),(20.63622,-36.85039,68.03150),(0.0,-36.85039,68.03150)},
+ },
+ {
+ {(0.0,-5.669294,76.53543),(-3.174809,-5.669294,76.53543),(-5.669294,-3.174809,76.53543),(-5.669294,0.0,76.53543)},
+ {(0.0,-11.33858,72.28346),(-6.349609,-11.33858,72.28346),(-11.33858,-6.349609,72.28346),(-11.33858,0.0,72.28346)},
+ {(0.0,-36.85039,72.28346),(-20.63622,-36.85039,72.28346),(-36.85039,-20.63622,72.28346),(-36.85039,0.0,72.28346)},
+ {(0.0,-36.85039,68.03150),(-20.63622,-36.85039,68.03150),(-36.85039,-20.63622,68.03150),(-36.85039,0.0,68.03150)},
+ },
+ {
+ {(-5.669294,0.0,76.53543),(-5.669294,3.174809,76.53543),(-3.174809,5.669294,76.53543),(0.0,5.669294,76.53543)},
+ {(-11.33858,0.0,72.28346),(-11.33858,6.349609,72.28346),(-6.349609,11.33858,72.28346),(0.0,11.33858,72.28346)},
+ {(-36.85039,0.0,72.28346),(-36.85039,20.63622,72.28346),(-20.63622,36.85039,72.28346),(0.0,36.85039,72.28346)},
+ {(-36.85039,0.0,68.03150),(-36.85039,20.63622,68.03150),(-20.63622,36.85039,68.03150),(0.0,36.85039,68.03150)},
+ },
+ {
+ {(0.0,5.669294,76.53543),(3.174809,5.669294,76.53543),(5.669294,3.174809,76.53543),(5.669294,0.0,76.53543)},
+ {(0.0,11.33858,72.28346),(6.349609,11.33858,72.28346),(11.33858,6.349609,72.28346),(11.33858,0.0,72.28346)},
+ {(0.0,36.85039,72.28346),(20.63622,36.85039,72.28346),(36.85039,20.63622,72.28346),(36.85039,0.0,72.28346)},
+ {(0.0,36.85039,68.03150),(20.63622,36.85039,68.03150),(36.85039,20.63622,68.03150),(36.85039,0.0,68.03150)},
+ },
+ {
+ {(0.0,0.0,0.0),(0.0,0.0,0.0),(0.0,0.0,0.0),(0.0,0.0,0.0)},
+ {(40.39370,0.0,0.0),(40.39370,22.62047,0.0),(22.62047,40.39370,0.0),(0.0,40.39370,0.0)},
+ {(42.51969,0.0,2.12598),(42.51969,23.81102,2.12598),(23.81102,42.51969,2.12598),(0.0,42.51969,2.12598)},
+ {(42.51969,0.0,4.251961),(42.51969,23.81102,4.251961),(23.81102,42.51969,4.251961),(0.0,42.51969,4.251961)},
+ },
+ {
+ {(0.0,0.0,0.0),(0.0,0.0,0.0),(0.0,0.0,0.0),(0.0,0.0,0.0)},
+ {(0.0,40.39370,0.0),(-22.62047,40.39370,0.0),(-40.39370,22.62047,0.0),(-40.39370,0.0,0.0)},
+ {(0.0,42.51969,2.12598),(-23.81102,42.51969,2.12598),(-42.51969,23.81102,2.12598),(-42.51969,0.0,2.12598)},
+ {(0.0,42.51969,4.251961),(-23.81102,42.51969,4.251961),(-42.51969,23.81102,4.251961),(-42.51969,0.0,4.251961)},
+ },
+ {
+ {(0.0,0.0,0.0),(0.0,0.0,0.0),(0.0,0.0,0.0),(0.0,0.0,0.0)},
+ {(-40.39370,0.0,0.0),(-40.39370,-22.62047,0.0),(-22.62047,-40.39370,0.0),(0.0,-40.39370,0.0)},
+ {(-42.51969,0.0,2.12598),(-42.51969,-23.81102,2.12598),(-23.81102,-42.51969,2.12598),(0.0,-42.51969,2.12598)},
+ {(-42.51969,0.0,4.251961),(-42.51969,-23.81102,4.251961),(-23.81102,-42.51969,4.251961),(0.0,-42.51969,4.251961)},
+ },
+ {
+ {(0.0,0.0,0.0),(0.0,0.0,0.0),(0.0,0.0,0.0),(0.0,0.0,0.0)},
+ {(0.0,-40.39370,0.0),(22.62047,-40.39370,0.0),(40.39370,-22.62047,0.0),(40.39370,0.0,0.0)},
+ {(0.0,-42.51969,2.12598),(23.81102,-42.51969,2.12598),(42.51969,-23.81102,2.12598),(42.51969,0.0,2.12598)},
+ {(0.0,-42.51969,4.251961),(23.81102,-42.51969,4.251961),(42.51969,-23.81102,4.251961),(42.51969,0.0,4.251961)},
+ }
+};
+
+draw(surface(Q),blue);
diff --git a/Build/source/utils/asymptote/examples/tensor.asy b/Build/source/utils/asymptote/examples/tensor.asy
new file mode 100644
index 00000000000..3791b032b92
--- /dev/null
+++ b/Build/source/utils/asymptote/examples/tensor.asy
@@ -0,0 +1,8 @@
+size(200);
+
+pen[][] p={{red,green,blue,cyan},{green,blue,rgb(black),magenta}};
+path G=(0,0){dir(-120)}..(1,0)..(1,1)..(0,1)..cycle;
+path[] g={G,subpath(G,1,2)..(2,1)..(2,0)..cycle};
+pair[][] z={{(0.5,0.5),(0.5,0.5),(0.5,0.5),(0.5,0.5)},{(2,0.5),(2,0.5),(1.5,0.5),(2,0.5)}};
+tensorshade(g,p,z);
+dot(g);
diff --git a/Build/source/utils/asymptote/examples/thermodynamics.asy b/Build/source/utils/asymptote/examples/thermodynamics.asy
new file mode 100644
index 00000000000..cfcc3d0e98e
--- /dev/null
+++ b/Build/source/utils/asymptote/examples/thermodynamics.asy
@@ -0,0 +1,131 @@
+// example file for roundedpath() in roundedpath.asy
+// written by stefan knorr
+
+
+// import needed packages
+import roundedpath;
+
+// function definition
+picture CreateKOOS(real Scale, string legend) // draw labeled coordinate system as picture
+{
+ picture ReturnPic;
+ real S = 1.2*Scale;
+ draw(ReturnPic, ((-S,0)--(S,0)), bar = EndArrow); // x axis
+ draw(ReturnPic, ((0,-S)--(0,S)), bar = EndArrow); // y axis
+ label(ReturnPic, "$\varepsilon$", (S,0), SW); // x axis label
+ label(ReturnPic, "$\sigma$", (0,S), SW); // y axis label
+ label(ReturnPic, legend, (0.7S, -S), NW); // add label 'legend'
+ return ReturnPic; // return picture
+}
+
+
+// some global definitions
+real S = 13mm; // universal scale factor for the whole file
+real grad = 0.25; // gradient for lines
+real radius = 0.04; // radius for the rounded path'
+real lw = 2; // linewidth
+pair A = (-1, -1); // start point for graphs
+pair E = ( 1, 1); // end point for graphs
+path graph; // local graph
+pen ActPen; // actual pen for each drawing
+picture T[]; // vector of all four diagrams
+real inc = 2.8; // increment-offset for combining pictures
+
+//////////////////////////////////////// 1st diagram
+T[1] = CreateKOOS(S, "$T_1$"); // initialise T[1] as empty diagram with label $T_1$
+graph = A; // # pointwise definition of current path 'graph'
+graph = graph -- (A.x + grad*1.6, A.y + 1.6); // #
+graph = graph -- (E.x - grad*0.4, E.y - 0.4); // #
+graph = graph -- E; // #
+
+graph = roundedpath(graph, radius, S); // round edges of 'graph' using roundedpath() in roundedpath.asy
+ActPen = rgb(0,0,0.6) + linewidth(lw); // define pen for drawing in 1st diagram
+draw(T[1], graph, ActPen); // draw 'graph' with 'ActPen' into 'T[1]' (1st hysteresis branch)
+draw(T[1], rotate(180,(0,0))*graph, ActPen); // draw rotated 'graph' (2nd hysteresis branch)
+
+graph = (0,0) -- (grad*0.6, 0.6) -- ( (grad*0.6, 0.6) + (0.1, 0) ); // define branch from origin to hysteresis
+graph = roundedpath(graph, radius, S); // round this path
+draw(T[1], graph, ActPen); // draw this path into 'T[1]'
+
+
+//////////////////////////////////////// 2nd diagram
+T[2] = CreateKOOS(S, "$T_2$"); // initialise T[2] as empty diagram with label $T_2$
+graph = A; // # pointwise definition of current path 'graph'
+graph = graph -- (A.x + grad*1.3, A.y + 1.3); // #
+graph = graph -- (E.x - grad*0.7 , E.y - 0.7); // #
+graph = graph -- E; // #
+
+graph = roundedpath(graph, radius, S); // round edges of 'graph' using roundedpath() in roundedpath.asy
+ActPen = rgb(0.2,0,0.4) + linewidth(lw); // define pen for drawing in 2nd diagram
+draw(T[2], graph, ActPen); // draw 'graph' with 'ActPen' into 'T[2]' (1st hysteresis branch)
+draw(T[2], rotate(180,(0,0))*graph, ActPen); // draw rotated 'graph' (2nd hysteresis branch)
+
+graph = (0,0) -- (grad*0.3, 0.3) -- ( (grad*0.3, 0.3) + (0.1, 0) ); // define branch from origin to hysteresis
+graph = roundedpath(graph, radius, S); // round this path
+draw(T[2], graph, ActPen); // draw this path into 'T[2]'
+
+
+//////////////////////////////////////// 3rd diagram
+T[3] = CreateKOOS(S, "$T_3$"); // initialise T[3] as empty diagram with label $T_3$
+graph = A; // # pointwise definition of current path 'graph'
+graph = graph -- (A.x + grad*0.7, A.y + 0.7); // #
+graph = graph -- ( - grad*0.3 , - 0.3); // #
+graph = graph -- (0,0); // #
+graph = graph -- (grad*0.6, 0.6); // #
+graph = graph -- (E.x - grad*0.4, E.y - 0.4); // #
+graph = graph -- E; // #
+
+graph = roundedpath(graph, radius, S); // round edges of 'graph' using roundedpath() in roundedpath.asy
+ActPen = rgb(0.6,0,0.2) + linewidth(lw); // define pen for drawing in 3rd diagram
+draw(T[3], graph, ActPen); // draw 'graph' with 'ActPen' into 'T[3]' (1st hysteresis branch)
+draw(T[3], rotate(180,(0,0))*graph, ActPen); // draw rotated 'graph' (2nd hysteresis branch)
+
+
+//////////////////////////////////////// 4th diagram
+T[4] = CreateKOOS(S, "$T_4$"); // initialise T[4] as empty diagram with label $T_4$
+graph = A; // # pointwise definition of current path 'graph'
+graph = graph -- (A.x + grad*0.4, A.y + 0.4); // #
+graph = graph -- ( - grad*0.6 , - 0.6); // #
+graph = graph -- (0,0); // #
+graph = graph -- (grad*0.9, 0.9); // #
+graph = graph -- (E.x - grad*0.1, E.y - 0.1); // #
+graph = graph -- E; // #
+
+graph = roundedpath(graph, radius, S); // round edges of 'graph' using roundedpath() in roundedpath.asy
+ActPen = rgb(0.6,0,0) + linewidth(lw); // define pen for drawing in 4th diagram
+draw(T[4], graph, ActPen); // draw 'graph' with 'ActPen' into 'T[4]' (1st hysteresis branch)
+draw(T[4], rotate(180,(0,0))*graph, ActPen); // draw rotated 'graph' (3nd hysteresis branch)
+
+
+// add some labels and black dots to the first two pictures
+pair SWW = (-0.8, -0.6);
+label(T[1], "$\sigma_f$", (0, 0.6S), NE); // sigma_f
+draw(T[1], (0, 0.6S), linewidth(3) + black);
+label(T[2], "$\sigma_f$", (0, 0.3S), NE); // sigma_f
+draw(T[2], (0, 0.3S), linewidth(3) + black);
+label(T[1], "$\varepsilon_p$", (0.7S, 0), SWW); // epsilon_p
+draw(T[1], (0.75S, 0), linewidth(3) + black);
+label(T[2], "$\varepsilon_p$", (0.7S, 0), SWW); // epsilon_p
+draw(T[2], (0.75S, 0), linewidth(3) + black);
+
+
+// add all pictures T[1...4] to the current one
+add(T[1],(0,0));
+add(T[2],(1*inc*S,0));
+add(T[3],(2*inc*S,0));
+add(T[4],(3*inc*S,0));
+
+
+// draw line of constant \sigma and all intersection points with the graphs in T[1...4]
+ActPen = linewidth(1) + dashed + gray(0.5); // pen definition
+draw((-S, 0.45*S)--((3*inc+1)*S, 0.45*S), ActPen); // draw backgoundline
+label("$\sigma_s$", (-S, 0.45S), W); // label 'sigma_s'
+
+path mark = scale(2)*unitcircle; // define mark-symbol to be used for intersections
+ActPen = linewidth(1) + gray(0.5); // define pen for intersection mark
+draw(shift(( 1 - grad*0.55 + 0*inc)*S, 0.45*S)*mark, ActPen); // # draw all intersections
+draw(shift((-1 + grad*1.45 + 0*inc)*S, 0.45*S)*mark, ActPen); // #
+draw(shift(( 1 - grad*0.55 + 1*inc)*S, 0.45*S)*mark, ActPen); // #
+draw(shift(( 1 - grad*0.55 + 2*inc)*S, 0.45*S)*mark, ActPen); // #
+draw(shift(( grad*0.45 + 2*inc)*S, 0.45*S)*mark, ActPen); // #
+draw(shift(( grad*0.45 + 3*inc)*S, 0.45*S)*mark, ActPen); // #
diff --git a/Build/source/utils/asymptote/examples/torus.asy b/Build/source/utils/asymptote/examples/torus.asy
new file mode 100644
index 00000000000..33d6e6ddb1a
--- /dev/null
+++ b/Build/source/utils/asymptote/examples/torus.asy
@@ -0,0 +1,7 @@
+size(200);
+import solids;
+
+currentprojection=perspective(5,4,4);
+
+revolution torus=revolution(shift(3X)*Circle(O,1,Y,32),Z,90,345);
+draw(surface(torus),green);
diff --git a/Build/source/utils/asymptote/examples/transparency.asy b/Build/source/utils/asymptote/examples/transparency.asy
new file mode 100644
index 00000000000..02196a02ee9
--- /dev/null
+++ b/Build/source/utils/asymptote/examples/transparency.asy
@@ -0,0 +1,9 @@
+size(0,150);
+
+settings.outformat="pdf";
+
+begingroup();
+fill(shift(1.5dir(120))*unitcircle,green+opacity(0.75));
+fill(shift(1.5dir(60))*unitcircle,red+opacity(0.75));
+fill(unitcircle,blue+opacity(0.75));
+endgroup();
diff --git a/Build/source/utils/asymptote/examples/treetest.asy b/Build/source/utils/asymptote/examples/treetest.asy
new file mode 100644
index 00000000000..dbdf973c508
--- /dev/null
+++ b/Build/source/utils/asymptote/examples/treetest.asy
@@ -0,0 +1,22 @@
+import drawtree;
+
+treeLevelStep = 2cm;
+
+TreeNode root = makeNode( "Root" );
+TreeNode child1 = makeNode( root, "Child\_1" );
+TreeNode child2 = makeNode( root, "Child\_2" );
+
+TreeNode gchild1 = makeNode( child1, "Grandchild\_1" );
+TreeNode gchild2 = makeNode( child1, "Grandchild\_2" );
+
+TreeNode gchild3 = makeNode( child1, "Grandchild\_3" );
+TreeNode gchild4 = makeNode( child1, "Grandchild\_4" );
+
+
+TreeNode gchild11 = makeNode( child2, "Grandchild\_1" );
+TreeNode gchild22 = makeNode( child2, "Grandchild\_2" );
+
+TreeNode ggchild1 = makeNode( gchild1, "Great Grandchild\_1" );
+
+draw( root, (0,0) );
+
diff --git a/Build/source/utils/asymptote/examples/trefoilknot.asy b/Build/source/utils/asymptote/examples/trefoilknot.asy
new file mode 100644
index 00000000000..fb10e3def0e
--- /dev/null
+++ b/Build/source/utils/asymptote/examples/trefoilknot.asy
@@ -0,0 +1,23 @@
+import tube;
+import graph3;
+import palette;
+currentlight=adobe;
+
+size(0,8cm);
+currentprojection=perspective(1,1,1,up=-Y);
+
+int e=1;
+real x(real t) {return cos(t)+2*cos(2t);}
+real y(real t) {return sin(t)-2*sin(2t);}
+real z(real t) {return 2*e*sin(3t);}
+
+path3 p=scale3(2)*graph(x,y,z,0,2pi,50,operator ..)&cycle;
+
+pen[] pens=Gradient(6,red,blue,purple);
+pens.push(yellow);
+for (int i=pens.length-2; i >= 0 ; --i)
+ pens.push(pens[i]);
+
+path sec=scale(0.25)*texpath("$\pi$")[0];
+coloredpath colorsec=coloredpath(sec, pens,colortype=coloredNodes);
+draw(tube(p,colorsec));
diff --git a/Build/source/utils/asymptote/examples/triads.asy b/Build/source/utils/asymptote/examples/triads.asy
new file mode 100644
index 00000000000..73088197e25
--- /dev/null
+++ b/Build/source/utils/asymptote/examples/triads.asy
@@ -0,0 +1,52 @@
+import graph;
+
+path p=(10,75)..(15,85)..(20,90)..(35,85)..(40,79)--(78,30)..(85,15)..(87,5);
+
+pair l=point(p,3.5);
+pair m=point(p,4.5);
+pair s=point(p,4.9);
+
+pen c=linewidth(1.5);
+pair o=(m.x,0.5(m.x+l.y));
+
+pen d=c+darkgreen;
+
+void drawarrow(string s="", pair p, pair q, side side=RightSide,
+ bool upscale=false, pen c)
+{
+ path g=p{dir(-5)}..{dir(-85)}q;
+ if(upscale) g=reverse(g);
+ draw(s,g,side,c,Arrow(Fill,0.65));
+}
+
+void spectrum(pair l,pair m, pair s) {
+ draw(p,c);
+
+ d += 4.0;
+ dot("$p$",l,SW,d);
+ dot("$q$",m,SW,d);
+ dot("$k$",s,SW,d);
+
+ xaxis("$k$",0);
+ yaxis("$E(k)$",0);
+}
+
+drawarrow("$T_p$",l,m,true,blue);
+drawarrow("$T_k$",m,s,LeftSide,red);
+spectrum(l,m,s);
+shipout("triadpqk");
+
+erase();
+
+drawarrow("$-T_p$",l,m,LeftSide,red);
+drawarrow("$-T_q$",m,s,true,blue);
+spectrum(l,s,m);
+shipout("triadpkq");
+
+erase();
+
+drawarrow("$T_k$",l,m,true,blue);
+drawarrow("$T_q$",m,s,LeftSide,red);
+spectrum(m,s,l);
+
+shipout("triadkpq");
diff --git a/Build/source/utils/asymptote/examples/triangle.asy b/Build/source/utils/asymptote/examples/triangle.asy
new file mode 100644
index 00000000000..60388a78515
--- /dev/null
+++ b/Build/source/utils/asymptote/examples/triangle.asy
@@ -0,0 +1,12 @@
+size(0,100);
+import geometry;
+
+triangle t=triangle(b=3,alpha=90,c=4);
+
+dot((0,0));
+
+draw(t);
+draw(rotate(90)*t,red);
+draw(shift((-4,0))*t,blue);
+draw(reflect((0,0),(1,0))*t,green);
+draw(slant(2)*t,magenta);
diff --git a/Build/source/utils/asymptote/examples/triceratops.asy b/Build/source/utils/asymptote/examples/triceratops.asy
new file mode 100644
index 00000000000..e640a6b37f9
--- /dev/null
+++ b/Build/source/utils/asymptote/examples/triceratops.asy
@@ -0,0 +1,9 @@
+import obj;
+
+size(15cm);
+currentprojection=orthographic(0,2,5,up=Y);
+
+// A compressed version of the required data file may be obtained from:
+// http://www.cs.technion.ac.il/~irit/data/Viewpoint/galleon.obj.gz
+
+draw(obj("triceratops.obj",brown));
diff --git a/Build/source/utils/asymptote/examples/tvgen.asy b/Build/source/utils/asymptote/examples/tvgen.asy
new file mode 100644
index 00000000000..ade90e89211
--- /dev/null
+++ b/Build/source/utils/asymptote/examples/tvgen.asy
@@ -0,0 +1,1314 @@
+/* tvgen - draw pm5544-like television test cards.
+ * Copyright (C) 2007, 2009, Servaas Vandenberghe.
+ *
+ * The tvgen code below 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 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program 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 tvgen: see the file COPYING. If not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ * tvgen-1.1/tvgen.asy
+ * This asy script generates pm5544-like television test cards. The image
+ * parameters were derived from a 1990 recording. The basic parameters
+ * conform to itu-r bt.470, bt.601, and bt.709. There is no unique image
+ * since local variants exist and parameters have varied over time.
+ */
+//papertype="a4";
+import plain;
+int verbose=settings.verbose/*+2*/; /* uncomment for debug info */
+
+/* tv dot coordinates --> PS points */
+pair tvps(real col, real row, real xd, real yd, int Nv) {
+ real psx, psy;
+ psx=col*xd; psy=(Nv-row)*yd;
+ return (psx,psy);
+}
+path tvrect(int lc, int tr, int rc, int br, real xd, real yd, int Nv) {
+ real lx, ty, rx, by;
+ pair[] z;
+
+ lx=lc*xd; ty=(Nv-tr)*yd;
+ rx=rc*xd; by=(Nv-br)*yd;
+ /* bl br tr tl */
+ z[0]=(lx, by);
+ z[1]=(rx, by);
+ z[2]=(rx, ty);
+ z[3]=(lx, ty);
+
+ return z[0]--z[1]--z[2]--z[3]--cycle;
+}
+
+/********************* image aspect ratio markers ********************/
+void rimarkers(real rimage, int Nh, int Nhc, int os, int Nvc, int Nsy, pen pdef, real xd, real yd, int Nv) {
+ int[] ridefN={ 4, 16 };
+ int[] ridefD={ 3, 9 };
+ int i;
+
+ for(i=0; i<2; ++i) {
+ real rid=ridefN[i]/ridefD[i];
+
+ if(rimage>rid) {
+ int off, offa, offb;
+
+ /* Nhdef=Nh/rimage*rid */
+ off=round(Nh/rimage*rid/2);
+ offa=off+os;
+ offb=off-os;
+ // write(offa,offb);
+
+ if(2*offa<Nh) {
+ int hy, tr, br;
+ path zz;
+
+ hy=floor(Nsy/3);
+ tr=Nvc-hy;
+ br=Nvc+hy;
+
+ zz=tvrect(Nhc+offb, tr, Nhc+offa, br, xd,yd,Nv);
+ //dot(zz);
+ fill(zz, p=pdef);
+ zz=tvrect(Nhc-offa, tr, Nhc-offb, br, xd,yd,Nv);
+ fill(zz, p=pdef);
+ }
+ }
+ } /* for i */
+ return;
+}
+
+/************* cross hatch: line pairing, center interlace test *************/
+void centerline(int[] coff, int[] coffa, int[] coffb, int Nhc, int divsx,
+ int os, int[] rcrowc, int Nvc, int divsy,
+ pair ccenter, real[] rcoff, pair[] rcright, pair[] rcleft,
+ pen pdef, real xd, real yd, int Nv) {
+ pair[] z;
+ int col;
+ pen pblack=pdef+gray(0.0), pwhite=pdef+gray(1.0);
+
+ z[0]=rcright[divsy];
+
+ col=Nhc+coff[0];
+ z[1]=tvps(col,rcrowc[divsy], xd,yd,Nv);
+ z[2]=tvps(col,rcrowc[divsy-1], xd,yd,Nv);
+ col=Nhc-coff[0];
+ z[3]=tvps(col,rcrowc[divsy-1], xd,yd,Nv);
+ z[4]=tvps(col,rcrowc[divsy], xd,yd,Nv);
+
+ z[5]=rcleft[divsy];
+ z[6]=rcleft[divsy+1];
+
+ z[7]=tvps(col,rcrowc[divsy+1], xd,yd,Nv);
+ z[8]=tvps(col,rcrowc[divsy+2], xd,yd,Nv);
+ col=Nhc+coff[0];
+ z[9]=tvps(col,rcrowc[divsy+2], xd,yd,Nv);
+ z[10]=tvps(col,rcrowc[divsy+1], xd,yd,Nv);
+
+ z[11]=rcright[divsy+1];
+ fill(z[1]--z[2]--z[3]--z[4] //--z[5]--z[6]
+ --arc(ccenter, z[5], z[6])
+ --z[7]--z[8]--z[9]--z[10] //--z[11]--z[0]
+ --arc(ccenter,z[11], z[0])
+ --cycle, p=pblack);
+
+ int i, maxoff, rows, tr, br;
+ path zz;
+
+ maxoff=floor(rcoff[divsy]);
+
+ /* center cross: vertical and horizontal centerline */
+ rows=min(Nvc-rcrowc[divsy-1], rcrowc[divsy+2]-Nvc);
+ tr=Nvc-rows;
+ br=Nvc+rows;
+ //write("centerline long: rows tr br ", rows, tr, br);
+ zz=tvrect(Nhc-os, tr, Nhc+os, br, xd,yd,Nv);
+ fill(zz, p=pwhite);
+ zz=tvrect(Nhc-maxoff,Nvc-1, Nhc+maxoff,Nvc+1, xd,yd,Nv);
+ fill(zz, p=pwhite);
+
+ /* vertical short lines */
+ rows=min(Nvc-rcrowc[divsy], rcrowc[divsy+1]-Nvc);
+ tr=Nvc-rows;
+ br=Nvc+rows;
+ if(verbose>1)
+ write("centerline: rows tr br ", rows, tr, br);
+ for(i=0; i<=divsx; ++i) {
+ int off;
+
+ off=coff[i];
+ if(off<maxoff) {
+ int offa, offb;
+ path zzv;
+ offa=coffa[i];
+ offb=coffb[i];
+
+ zzv=tvrect(Nhc+offb, tr, Nhc+offa, br, xd,yd,Nv);
+ fill(zzv, p=pwhite);
+ zzv=tvrect(Nhc-offa, tr, Nhc-offb, br, xd,yd,Nv);
+ fill(zzv, p=pwhite);
+ }
+ }
+ return;
+}
+
+/************************ topbw **************************************/
+void topbw(int[] coff, int Nhc, int os, int urow, int trow, int brow,
+ pair ccenter, pair rclt, pair rclb, pair rcrt, pair rcrb,
+ pen pdef, real xd, real yd, int Nv) {
+ pen pblack=pdef+gray(0.0), pwhite=pdef+gray(1.0);
+ pair[] ze;
+ path zext, zref, zint;
+ int off, col, cr;
+
+ off=ceil((coff[2]+coff[3])/2);
+ ze[0]=tvps(Nhc+off,trow, xd,yd,Nv);
+ ze[1]=rcrt;
+ ze[2]=rclt;
+ ze[3]=tvps(Nhc-off,trow, xd,yd,Nv);
+ ze[4]=tvps(Nhc-off,brow, xd,yd,Nv);
+ col=Nhc-coff[2]-os;
+ ze[5]=tvps(col,brow, xd,yd,Nv);
+ ze[6]=tvps(col,trow, xd,yd,Nv);
+ cr=col+3*os; /* reflection test black pulse */
+ zref=tvrect(col,trow, cr,brow, xd,yd,Nv);
+ ze[7]=tvps(cr,trow, xd,yd,Nv);
+ ze[8]=tvps(cr,brow, xd,yd,Nv);
+ ze[9]=tvps(Nhc+off,brow, xd,yd,Nv);
+ //dot(ze);
+
+ zext=ze[0] // --ze[1]--ze[2]
+ --arc(ccenter, ze[1], ze[2])
+ --ze[3]--ze[4]--ze[5]--ze[6]--ze[7]--ze[8]--ze[9]--cycle;
+
+ off=ceil((coff[1]+coff[2])/2);
+ zint=tvrect(Nhc-off,urow, Nhc+off,trow, xd,yd,Nv);
+
+ /* paths are completely resolved; no free endpoint conditions */
+ fill(zext^^reverse(zint), p=pwhite);
+ fill(zint, p=pblack);
+ fill(zref, p=pblack);
+
+ fill(arc(ccenter,rclt,rclb)--ze[4]--ze[3]--cycle, p=pblack);
+ fill(arc(ccenter,rcrb,rcrt)--ze[0]--ze[9]--cycle, p=pblack);
+ return;
+}
+
+/************************ testtone **************************************/
+/* x on circle -> return y>=0
+ * in:
+ * x x-coordinate relative to origin
+ * crad circle radius in y units, true size=crad*yd
+ */
+real testcircx(real x, real crad, real xd, real yd) {
+ real relx, phi, y;
+
+ relx=x*xd/yd/crad;
+ if(relx>1) {
+ phi=0;
+ } else {
+ phi=acos(relx);
+ }
+ y=crad*sin(phi); // or (x*xd)^2+(y*yd)^2=(crad*yd)^2
+
+ return y;
+}
+/* y on circle -> return x>=0 */
+real testcircy(real y, real crad, real xd, real yd) {
+ real rely, phi, x;
+
+ rely=y/crad;
+ if(rely>1) {
+ phi=pi/2;
+ } else {
+ phi=asin(rely);
+ }
+ x=crad*cos(phi)*yd/xd; // or (x*xd)^2+(y*yd)^2=(crad*yd)^2
+
+ return x;
+}
+
+/* brow>trow && xb>xt */
+void testtone(real Tt, int trow, int brow,
+ real ccol, real crow, real crad,
+ pen pdef, real xd, real yd, int Nv) {
+ int blocks, i;
+ real yt, xt, yb, xb, Ttt=Tt/2;
+ pair ccenter;
+
+ yt=crow-trow;
+ xt=testcircy(yt, crad, xd, yd);
+ yb=crow-brow;
+ xb=testcircy(yb, crad, xd, yd);
+ //write('#xt yt\t',xt,yt); write('#xb yb\t',xb,yb);
+
+ ccenter=tvps(ccol,crow, xd,yd,Nv);
+
+ blocks=floor(2*xb/Tt);
+
+ for(i=-blocks-1; i<=blocks; ++i) {
+ real tl, tr;
+ path zz;
+
+ tl=max(-xb,min(i*Ttt,xb)); /* limit [-xb..xb] */
+ tr=max(-xb,min((i+1)*Ttt,xb));
+
+ if(tl<-xt && tr<=-xt || tr>xt && tl>=xt) { /* top full circle */
+ pair[] z;
+ real yl, yr;
+
+ yl=testcircx(tl, crad, xd, yd);
+ yr=testcircx(tr, crad, xd, yd);
+
+ z[0]=tvps(ccol+tl,brow, xd,yd,Nv);
+ z[1]=tvps(ccol+tr,brow, xd,yd,Nv);
+ z[2]=tvps(ccol+tr,crow-yr, xd,yd,Nv);
+ z[3]=tvps(ccol+tl,crow-yl, xd,yd,Nv);
+
+ zz=z[0]--z[1]--arc(ccenter,z[2],z[3])--cycle;
+ } else if(tl<-xt) { /* tl in circel, tr not, partial */
+ pair[] z;
+ real yl;
+
+ yl=testcircx(tl, crad, xd, yd);
+
+ z[0]=tvps(ccol+tl,brow, xd,yd,Nv);
+ z[1]=tvps(ccol+tr,brow, xd,yd,Nv);
+ z[2]=tvps(ccol+tr,trow, xd,yd,Nv);
+ z[3]=tvps(ccol-xt,trow, xd,yd,Nv);
+ z[4]=tvps(ccol+tl,crow-yl, xd,yd,Nv);
+
+ zz=z[0]--z[1]--z[2]--arc(ccenter,z[3],z[4])--cycle;
+ } else if(tr>xt) { /* tr in circle, tl not, partial */
+ pair[] z;
+ real yr;
+
+ yr=testcircx(tr, crad, xd, yd);
+
+ z[0]=tvps(ccol+tl,brow, xd,yd,Nv);
+ z[1]=tvps(ccol+tr,brow, xd,yd,Nv);
+ z[2]=tvps(ccol+tr,crow-yr, xd,yd,Nv);
+ z[3]=tvps(ccol+xt,trow, xd,yd,Nv);
+ z[4]=tvps(ccol+tl,trow, xd,yd,Nv);
+ zz=z[0]--z[1]--arc(ccenter,z[2],z[3])--z[4]--cycle;
+ } else { /* full block */
+ pair[] z;
+
+ z[0]=tvps(ccol+tr,trow, xd,yd,Nv);
+ z[1]=tvps(ccol+tl,trow, xd,yd,Nv);
+ z[2]=tvps(ccol+tl,brow, xd,yd,Nv);
+ z[3]=tvps(ccol+tr,brow, xd,yd,Nv);
+ zz=z[0]--z[1]--z[2]--z[3]--cycle;
+ }
+
+ if(tl<tr) {
+ if(i%2 == 0) {
+ fill(zz, p=pdef+gray(0.0));
+ } else {
+ fill(zz, p=pdef+gray(0.75));
+ }
+ }
+ }
+ return;
+}
+
+/************************ color bars *************************************/
+void colorbars(int[] coff, int Nhc, int trow, int crow, int brow,
+ pair ccenter, pair rclt, pair rclb, pair rcrt, pair rcrb,
+ pen pdef, real xd, real yd, int Nv) {
+ real cI=0.75;
+ real[] cR={ cI, 0, 0, cI, cI, 0 };
+ real[] cG={ cI, cI, cI, 0, 0, 0 };
+ real[] cB={ 0, cI, 0, cI, 0, cI };
+ int cmax=2, poff, rows, i;
+
+ rows=brow-trow;
+ poff=0;
+ for(i=0; i<=cmax; ++i) {
+ int off;
+ int ii=2*i, il=cmax-i, ir=i+cmax+1;
+ path zzl, zzr;
+
+ off=ceil((coff[1+ii]+coff[2+ii])/2);
+ if(i!=0 && i<cmax) {
+ zzr=tvrect(Nhc+poff,trow, Nhc+off,brow, xd,yd,Nv);
+ zzl=tvrect(Nhc-off,trow, Nhc-poff,brow, xd,yd,Nv);
+ } else {
+ if(i==0) {
+ int col, pcol;
+ pair[] zl, zr;
+
+ col=Nhc+off;
+ pcol=Nhc+poff;
+ zr[0]=tvps(col,trow, xd,yd,Nv);
+ zr[1]=tvps(pcol,trow, xd,yd,Nv);
+ zr[2]=tvps(pcol,crow, xd,yd,Nv);
+ zr[3]=tvps(Nhc+coff[0],crow, xd,yd,Nv);
+ zr[4]=tvps(Nhc+coff[0],brow, xd,yd,Nv);
+ zr[5]=tvps(col,brow, xd,yd,Nv);
+ zzr=zr[0]--zr[1]--zr[2]--zr[3]--zr[4]--zr[5]--cycle;
+
+ col=Nhc-off;
+ pcol=Nhc-poff;
+ zl[0]=tvps(pcol,trow, xd,yd,Nv);
+ zl[1]=tvps(col,trow, xd,yd,Nv);
+ zl[2]=tvps(col,brow, xd,yd,Nv);
+ zl[3]=tvps(Nhc-coff[0],brow, xd,yd,Nv);
+ zl[4]=tvps(Nhc-coff[0],crow, xd,yd,Nv);
+ zl[5]=tvps(pcol,crow, xd,yd,Nv);
+ zzl=zl[0]--zl[1]--zl[2]--zl[3]--zl[4]--zl[5]--cycle;
+ } else {
+ int pcol;
+ pair[] zl, zr;
+
+ pcol=Nhc+poff;
+ zr[0]=tvps(pcol,brow, xd,yd,Nv);
+ zr[1]=rcrb;
+ zr[2]=rcrt;
+ zr[3]=tvps(pcol,trow, xd,yd,Nv);
+ zzr=zr[0]--arc(ccenter,zr[1],zr[2])--zr[3]--cycle;
+
+ pcol=Nhc-poff;
+ zl[0]=tvps(pcol,trow, xd,yd,Nv);
+ zl[1]=rclt;
+ zl[2]=rclb;
+ zl[3]=tvps(pcol,brow, xd,yd,Nv);
+ zzl=zl[0]--arc(ccenter,zl[1],zl[2])--zl[3]--cycle;
+ }
+ }
+ fill(zzr, p=pdef+rgb(cR[ir], cG[ir], cB[ir]));
+ fill(zzl, p=pdef+rgb(cR[il], cG[il], cB[il]));
+
+ poff=off;
+ }
+ return;
+}
+
+/************************ test frequencies ****************************/
+/* in
+ * theta rad
+ * freq 1/hdot
+ * step hdot
+ * out
+ * new phase theta
+ */
+real addphase(real theta, real freq, real step) {
+ real cycles, thetaret;
+ int coverflow;
+
+ cycles=freq*step;
+ coverflow=floor(abs(cycles));
+ if(coverflow>1) {
+ thetaret=0;
+ } else {
+ real dpi=2*pi;
+
+ cycles-=coverflow*sgn(cycles);
+ thetaret=theta+cycles*dpi; /* cycles=(-1 .. 1) */
+
+ if(thetaret>pi) {
+ thetaret-=dpi;
+ } else if(thetaret<-pi) {
+ thetaret-=dpi;
+ }
+ }
+
+ //write("addphase: ", step, theta, thetaret);
+ return thetaret;
+}
+
+void testfreqs(real[] ftones, int[] coff, int Nhc, int trow,int crow,int brow,
+ pair ccenter, pair rclt, pair rclb, pair rcrt, pair rcrb,
+ pen pdef, real xd, real yd, int Nv) {
+ int[] divc;
+ real[] divfl, divfr;
+ int i, divs, coffmax, off, divnext;
+ real fl, fr, thr, thl;
+
+ /* Segment info for PAL continental test card
+ * segment i extends from [divc[i] .. divc[i+1]) with frequency divf[i]
+ */
+ divs=2; // the number of segments on the right, total=2*divs+1
+ divc[0]=0;
+ for(i=0; i<=divs; ++i) {
+ int ii=i*2, il=divs-i, ir=divs+i;
+
+ divc[i+1]=ceil((coff[ii]+coff[ii+1])/2); /* xdot distance to center */
+
+ divfl[i]=ftones[divs-i];
+ divfr[i]=ftones[divs+i];
+ }
+ coffmax=divc[divs+1];
+
+ int trowlim=coff[0];
+ int tr;
+
+ tr=crow;
+
+ divnext=0;
+ fl=0;
+ fr=0;
+ thl=0;
+ thr=0;
+ // draw a vertical line at off..off+1
+ for(off=0; off<coffmax; ++off) {
+ real ampl, ampr;
+ int col;
+ path zz;
+
+ if(off==trowlim) {
+ tr=trow;
+ }
+
+ if(off == divc[divnext]) {
+ /* switch frequency: cycles=0.5*fcur+0.5*fnext */
+ thl=addphase(thl, fl, -0.5);
+ thr=addphase(thr, fr, 0.5);
+ fl=divfl[divnext];
+ fr=divfr[divnext];
+ thl=addphase(thl, fl, -0.5);
+ thr=addphase(thr, fr, 0.5);
+
+ ++divnext;
+ // thl=pi; thr=pi;
+ //write(off, fl, fr);
+ } else {
+ thl=addphase(thl, fl, -1);
+ thr=addphase(thr, fr, 1);
+ // thl=0; thr=0;
+ }
+
+ ampl=(1+sin(thl))/2;
+ ampr=(1+sin(thr))/2;
+ //write(off, thr, ampr);
+
+ col=Nhc-off-1;
+ zz=tvrect(col,tr, col+1,brow, xd,yd,Nv);
+ fill(zz, p=pdef+gray(ampl));
+ col=Nhc+off;
+ zz=tvrect(col,tr, col+1,brow, xd,yd,Nv);
+ fill(zz, p=pdef+gray(ampr));
+ }
+
+ pair[] z;
+ z[0]=tvps(Nhc-coffmax,trow, xd,yd,Nv);
+ z[1]=tvps(Nhc-coffmax,brow, xd,yd,Nv);
+ fill(z[0]--arc(ccenter,rclt,rclb)--z[1]--cycle, p=pdef+gray(0.0));
+ z[0]=tvps(Nhc+coffmax,brow, xd,yd,Nv);
+ z[1]=tvps(Nhc+coffmax,trow, xd,yd,Nv);
+ fill(z[0]--arc(ccenter,rcrb,rcrt)--z[1]--cycle, p=pdef+gray(0.0));
+ return;
+}
+
+/************************ gray bars **************************************/
+void graybars(int[] coff, int Nhc, int trow, int brow,
+ pair ccenter, pair rclt, pair rclb, pair rcrt, pair rcrb,
+ pen pdef, real xd, real yd, int Nv) {
+ int[] gs={0, 51, 102, 153, 204, 255};
+ int cmax=2, poff, rows, i;
+
+ rows=brow-trow;
+ poff=0;
+ for(i=0; i<=cmax; ++i) {
+ int off;
+ int ii=2*i, il=cmax-i, ir=i+cmax+1;
+ path zzl, zzr;
+
+ off=ceil((coff[1+ii]+coff[2+ii])/2);
+ if(i<cmax) {
+ zzl=tvrect(Nhc-off,trow, Nhc-poff,brow, xd,yd,Nv);
+ zzr=tvrect(Nhc+poff,trow, Nhc+off,brow, xd,yd,Nv);
+ } else {
+ int pcol;
+ pair zlt, zlb, zrt, zrb;
+
+ pcol=Nhc-poff;
+ zlt=tvps(pcol,trow, xd,yd,Nv);
+ zlb=tvps(pcol,brow, xd,yd,Nv);
+ zzl=zlt--arc(ccenter,rclt,rclb)--zlb--cycle;
+
+ pcol=Nhc+poff;
+ zrb=tvps(pcol,brow, xd,yd,Nv);
+ zrt=tvps(pcol,trow, xd,yd,Nv);
+ zzr=zrb--arc(ccenter,rcrb,rcrt)--zrt--cycle;
+ }
+ fill(zzl, p=pdef+gray(gs[il]/255));
+ fill(zzr, p=pdef+gray(gs[ir]/255));
+
+ poff=off;
+ }
+ return;
+}
+
+/************************ bottom bw **************************************/
+void bottombw(int off, int Nhc, int trow, int brow,
+ pair ccenter, pair rclt, pair rclb, pair rcrt, pair rcrb,
+ pen pdef, real xd, real yd, int Nv) {
+ int rows;
+ pair zt, zb;
+ path zz;
+
+ rows=brow-trow;
+ zz=tvrect(Nhc-off,trow, Nhc+off,brow, xd,yd,Nv);
+ fill(zz, p=pdef+gray(0.0));
+
+ zt=tvps(Nhc-off,trow, xd,yd,Nv);
+ zb=tvps(Nhc-off,brow, xd,yd,Nv);
+ fill(zt--arc(ccenter,rclt,rclb)--zb--cycle, p=pdef+gray(1.0));
+
+ zb=tvps(Nhc+off,brow, xd,yd,Nv);
+ zt=tvps(Nhc+off,trow, xd,yd,Nv);
+ fill(zb--arc(ccenter,rcrb,rcrt)--zt--cycle, p=pdef+gray(1.0));
+ return;
+}
+
+/************************ bottom circle **************************************/
+void bottomcirc(int off, int Nhc, int trow, real cx, real cy, real crad,
+ pair ccenter, pair rclt, pair rcrt,
+ pen pdef, real xd, real yd, int Nv) {
+ real cI=0.75;
+ real xl, yl, xr, yr, phil, phir;
+ pair ccleft, ccright;
+ pair[] z;
+
+ xl=Nhc-off-cx;
+ phil=acos(xl*xd/yd/crad);
+ yl=crad*sin(phil); // or (x*xd)^2+(y*yd)^2=(crad*yd)^2
+ ccleft=tvps(cx+xl,cy+yl, xd,yd,Nv);
+ //write(xl,yl);
+
+ xr=Nhc+off-cx;
+ phir=acos(xr*xd/yd/crad);
+ yr=crad*sin(phir);
+ ccright=tvps(cx+xr,cy+yr, xd,yd,Nv);
+
+ //dot(ccright); dot(ccleft);
+ // red center
+ z[0]=tvps(Nhc-off,trow, xd,yd,Nv);
+ z[1]=ccleft;
+ z[2]=ccright;
+ z[3]=tvps(Nhc+off,trow, xd,yd,Nv);
+ fill(z[0]--arc(ccenter,z[1],z[2])--z[3]--cycle, p=pdef+rgb(cI,0,0));
+
+ // yellow
+ z[0]=tvps(Nhc-off,trow, xd,yd,Nv);
+ z[1]=rclt;
+ z[2]=ccleft;
+ fill(z[0]--arc(ccenter,z[1],z[2])--cycle, p=pdef+rgb(cI,cI,0));
+ z[0]=tvps(Nhc+off,trow, xd,yd,Nv);
+ z[1]=ccright;
+ z[2]=rcrt;
+ fill(z[0]--arc(ccenter,z[1],z[2])--cycle, p=pdef+rgb(cI,cI,0));
+
+ return;
+}
+
+/****************************** PAL ears ***********************************
+ * left y R G B
+ * 0.55 98 162 140
+ * 0.5 103 128 191
+ * 0.5 152 128 64
+ * 0.45 157 93 115
+ * right
+ * 0.6 153 168 76
+ * 0.4 102 87 179
+ *
+ * in: dright= -1 left ear, +1 right ear
+ */
+void palears(int[] coff, int[] coffa, int[] coffb, int Nhc,
+ int[] rcrowt, int[] rcrowb, int Nvc, int divsy, int dright,
+ pen pdef, real xd, real yd, int Nv) {
+ /* the amplitude of (u,v) as seen on a vectorscope,
+ * max 0.296 Vn for 100% saturation in W and V ears.
+ * cvbs: 0.7*( y +/- |u+jv| ) = -0.24 .. 0.93 V
+ * maxima: ebu 75/0 bars 0.70, bbc 100/25 0.88, 100/0 bars 0.93
+ * burst: 0.150 Vcvbs, 21.4 IRE or 0.214 V normalized.
+ * luma: modulated for monochrome compatibility, 1990 version.
+ * choice: set amplitude of subcarrier equal to amplitude of colorburst.
+ */
+ real cI=0.214;
+
+ /* (u,v) for zero G-y, phase of -34.5 degrees */
+ real wr=0.299, wb=0.114, wg=1-wr-wb; /* wg=0.587, y=wr*R+wg*G+wb*B */
+ real wu=0.493, wv=0.877; /* u=wu*(B-y) v=wv*(R-y) */
+ real colu=wu*wg/wb, colv=-wv*wg/wr; /* for w=(G-y)/0.696 == 0 */
+
+ /* ears: U==0 W==0 W==0 U==0 */
+ real[] cyl={ 0.55, 0.5, 0.5, 0.45 };
+ real[] cul={ 0, colu, -colu, 0 };
+ real[] cvl={ -1, colv, -colv, 1 };
+
+ /* ears: V==0 W==0 W==0 V==0 */
+ real[] cyr={ 0.60, 0.5, 0.5, 0.40 };
+ real[] cur={ -1, colu, -colu, 1 };
+ real[] cvr={ 0, colv, -colv, 0 };
+
+ real[] cy, cu, cv;
+ pair[] z;
+ path[] zz;
+ int lcol, ccol, cicol, rcol, i;
+
+ if(dright>0) {
+ cy=cyr; cu=cur; cv=cvr;
+ } else {
+ cy=cyl; cu=cul; cv=cvl;
+ }
+
+ lcol=Nhc+dright*coffa[5];
+ ccol=Nhc+dright*coff[6];
+ cicol=Nhc+dright*coffa[6];
+ rcol=Nhc+dright*coffb[7];
+
+ int urow, trow, crow, brow, arow;
+ urow=rcrowb[divsy-5];
+ trow=rcrowt[divsy-3];
+ crow=Nvc;
+ brow=rcrowb[divsy+4];
+ arow=rcrowt[divsy+6];
+
+ z[0]=tvps(ccol,urow, xd,yd,Nv);
+ z[1]=tvps(ccol,trow, xd,yd,Nv);
+ z[2]=tvps(cicol,trow, xd,yd,Nv);
+ z[3]=tvps(cicol,crow, xd,yd,Nv);
+ z[4]=tvps(rcol,crow, xd,yd,Nv);
+ z[5]=tvps(rcol,urow, xd,yd,Nv);
+ zz[0]=z[0]--z[1]--z[2]--z[3]--z[4]--z[5]--cycle;
+
+ zz[1]=tvrect(lcol,urow, ccol,trow, xd,yd,Nv);
+ zz[2]=tvrect(lcol,brow, ccol,arow, xd,yd,Nv);
+
+ z[0]=tvps(ccol,arow, xd,yd,Nv);
+ z[1]=tvps(ccol,brow, xd,yd,Nv);
+ z[2]=tvps(cicol,brow, xd,yd,Nv);
+ z[3]=tvps(cicol,crow, xd,yd,Nv);
+ z[4]=tvps(rcol,crow, xd,yd,Nv);
+ z[5]=tvps(rcol,arow, xd,yd,Nv);
+ zz[3]=z[0]--z[1]--z[2]--z[3]--z[4]--z[5]--cycle;
+
+ for(i=0; i<4; ++i) {
+ real y, u, v, A, ph, By, Ry, Gy, R, G, B;
+
+ y=cy[i];
+ u=cu[i];
+ v=cv[i];
+
+ A=hypot(u,v);
+ ph= (u!=0 || v!=0) ? atan2(v,u) : 0.0;
+ if(v>=0) {
+ if(ph<0) ph=ph+pi;
+ } else {
+ if(ph>0) ph=ph-pi;
+ }
+ if(A>0) {
+ u=u/A*cI;
+ v=v/A*cI;
+ }
+
+ By=u/wu;
+ Ry=v/wv;
+ Gy=(-wr*Ry-wb*By)/wg;
+ //write(y,Gy,A,ph*180/pi);
+
+ R=Ry+y;
+ G=Gy+y;
+ B=By+y;
+ if(verbose > 1)
+ write(y,round(R*255),round(G*255),round(B*255));
+
+ fill(zz[i], p=pdef+rgb(R,G,B));
+ }
+ return;
+}
+
+/****************************** NTSC bars ***********************************
+ * amplitude equals color burst smpte (pm: -V +U)
+ * y campl sat R G B
+ * left 0.5 0.21 70% -I?
+ * right 0.5 0.17 60% +Q?
+ */
+void ntscbars(int[] coff, int[] coffa, int[] coffb, int Nhc,
+ int[] rcrowt, int[] rcrowb, int Nvc, int divsy, int dright,
+ pen pdef, real xd, real yd, int Nv) {
+ /* The amplitude of (i,q) as seen on a vectorscope,
+ * max 0.292 Vn for 100% saturation in I==0 ears.
+ * burst: 0.143 Vcvbs, 20 IRE or 0.200 V normalized.
+ * pedestal: (yp,up,vp)=(p,0,0)+(1-p)*(y,u,v), p=0.075.
+ * choice: equal amplitude for colorburst and subcarrier.
+ */
+ real campl=0.200/0.925;
+
+ /* wg=0.587, y=wr*R+wg*G+wb*B */
+ real wr=0.299, wb=0.114, wg=1-wr-wb;
+ /* iT : iq -> RyBy : rotation+scaling */
+ real iT11=0.95, iT12=0.62, iT21=-1.11, iT22=1.71;
+
+ /* bars -2 -1 0 1 2 */
+ real[] cyl={ 0.50, 0.50, 0, 0.50, 0.50 };
+ real[] cil={ 0, 0, 0, -1, 1 };
+ real[] cql={ -1, 1, 0, 0, 0 };
+ int[] offil={ 6, 7, 5, 7, 6 };
+
+ real cy, ci, cq;
+ int dri, dris, offi, lcol, rcol, i;
+
+ if(dright>=0) {
+ dris=1;
+ } else {
+ dris=-1;
+ }
+ if(dright<-2 || dright>2) {
+ dri=2;
+ } else {
+ dri=2+dright;
+ }
+
+ cy=cyl[dri]; ci=cil[dri]; cq=cql[dri];
+ offi=offil[dri];
+ lcol=Nhc+dris*coffa[offi];
+ rcol=Nhc+dris*coffb[offi+1];
+
+ real A, By, Ry, Gy, R, G, B;
+
+ A=hypot(ci,cq);
+ if(A>0) {
+ ci=ci/A*campl;
+ cq=cq/A*campl;
+ }
+ Ry=iT11*ci+iT12*cq;
+ By=iT21*ci+iT22*cq;
+ Gy=(-wr*Ry-wb*By)/wg;
+ //write(cy,Ry,Gy,By);
+
+ R=Ry+cy;
+ G=Gy+cy;
+ B=By+cy;
+ if(verbose > 1)
+ write(cy,ci,cq,round(R*255),round(G*255),round(B*255));
+
+ for(i=-divsy; i<=divsy; ++i) {
+ path zz;
+ int brow, trow;
+
+ if(i>-divsy) {
+ trow=rcrowb[divsy+i];
+ } else {
+ trow=floor((rcrowb[divsy+i]+rcrowt[divsy+i+1])/2);
+ }
+
+ if(divsy>i) {
+ brow=rcrowt[divsy+i+1];
+ } else {
+ brow=floor((rcrowb[divsy+i]+rcrowt[divsy+i+1])/2);
+ }
+
+ zz=tvrect(lcol,brow, rcol,trow, xd,yd,Nv);
+ fill(zz, p=pdef+rgb(R,G,B));
+ }
+
+ return;
+}
+
+
+/****************************** main ***********************************/
+/* Conversion to bitmap:
+ * EPSPNG='gs -dQUIET -dNOPAUSE -dBATCH -sDEVICE=png16m'
+ * asy -u bsys=2 -u colortv=1 -u os=1 -a Z tvgen
+ * $EPSPNG -r132x144 -g720x576 -sOutputFile=tvgen.png tvgen.eps
+ *
+ * asy -u bsys=2 -u colortv=1 -u os=1 tvgen
+ */
+int bsys=2, colortv=1, os=1;
+
+/* bsys: broadcast system
+ * bsys im aspect Nh
+ * 0 4/3 704 guaranteed analog broadcast itu-r bt.470
+ * 1 4/3 720 new broadcast, most TV station logos and animations
+ * 2 15/11 720 total aperture analog 4/3, 1.37 film DVDs
+ * 3 20/11 720 total aperture analog 16/9, 1.85 film DVDs
+ * 4 4/3 768 bsys=0, square dot analog broadcast
+ * 5 4/3 768 bsys=1, square dot cable TV info channel
+ * 6 131/96 786 bsys=2, total square dot broadcast camera
+ * 7 16/9 720 new broadcast 16/9, SD from HD-1440 or itu-r bt.709
+ * 8 4/3 704 525 analog broadcast itu-r bt.470 711*485
+ * 9 4/3 720 525 new broadcast
+ * 10 15/11 720 525 total aperture analog broadcast
+ * 11 16/9 1920 1250, 1080 square dot at 12.5 frames/second
+ * 12 4/3 1600 1250, 1200 square dot at 12.5 frames/second
+ *
+ * colortv:
+ * set 0 for monochrome crosshatch, 1 for pal ears, 2 for ntsc bars
+ *
+ * os: horizontal oversampling, typical values for 13.5MHz:
+ * 2 4/3 704*576, 15/11 720*576
+ * 4 4/3 720*480
+ * 5 4/3 704*480, 15/11 720*480, 4/3 768*576 14.4MHz
+ * 8 4/3 720*576, 20/11 720*576
+ * 12 704->768 rerastering
+ * 16 720->768 rerastering
+ */
+access settings;
+usersetting();
+
+if(bsys<0 || bsys>12 || colortv<0 || colortv>3 || os<=0 || os>16) {
+ write('Error: bad user input: bsys, colortv, os=\t', bsys, colortv, os);
+ abort('Bad option -u bsys=N ?');
+}
+
+int[] bNdot=
+ { 12, 16, 12, 16, 1, 1, 1, 64, 10, 8, 10, 1, 1 };
+int[] bDdot=
+ { 11, 15, 11, 11, 1, 1, 1, 45, 11, 9, 11, 1, 1 };
+int[] bNh=
+ { 704, 720, 720, 720, 768, 768, 786, 720, 704, 720, 720, 1920, 1600 };
+int[] bNv=
+ { 576, 576, 576, 576, 576, 576, 576, 576, 480, 480, 480, 1080, 1200 };
+real[] bfs=
+ { 13.5,13.5,13.5,13.5, 14.75,14.4,14.75,13.5, 13.5,13.5,13.5, 36, 30 };
+int[] bNsy=
+ { 42, 42, 42, 42, 42, 42, 42, 42, 34, 34, 34, 78, 90 };
+int[] bNsh=
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
+
+/* active lines for a 625 line frame
+ * The number of active video lines decreased around 1997.
+ * old: 3 run in + 575 visible + 3 run out = 581 lines
+ * new: 6 teletext and WSS + 575 visible
+ * Hence the image center shifted down by 3 lines. Thus
+ * old TV + new testcard = bottom is cut off,
+ * new TV + old testcard = top is cut off.
+ *
+ * To generate the old testcard either use Nv=582 Nsh=0 or Nv=576 Nsh=3.
+ *
+ * aspect ratio
+ * rimage=xsize/ysize rimage=rdot*Nh/Nv
+ * Nh=704 dots
+ * Nv=576 lines
+ * rd=ri*Nv/Nh=4/3*9/11=12/11
+ *
+ * Nv: 480=2^5*3*5 576=2^6*3^2
+ * Nh: 704=2^6*11 720=2^4*3^2*5
+ *
+ * horizontal line distance for pre 1997 test pattern
+ * top 8 lines, 13 squares of Ny=43 lines, bottom 9 lines
+ * top 12 lines, 13 squares of Ny=42 lines, bottom 18 lines
+ * pairs are from odd even field
+ * Interlace test: Ny must be odd for a cross-hatch without centerline.
+ *
+ * squares: ly=Nsy, lx=rd*Nsx, lx=ly ==> Nsx=Nsy/rd={ 39.4, 38.5 }
+ * x line width 230 ns -> 3 dots
+ * bottom 2.9us red -> 39.15 dots
+ *
+ * resolution DPI from image aspect ratio
+ * Rv=Nv/ly, ly=4in
+ * ri=Ni/Di, Ni={4,15,16} Di={3,11,9}
+ * lx=ri*ly
+ *
+ * Rh=Nh/lx=Di*(Nh/(Ni*ly))
+ * ==> ri=4/Di => Nh=k*16
+ * ri=15/Di => Nh=k*60
+ * ri=16/Di => Nh=k*64
+ *
+ * resolution DPI from dot aspect ratio, general algorithm,
+ *
+ * rd=Nd/Dd=ldx/ldy
+ *
+ * assume 1 dot = Nd x Dd square subdots at a resolution of k, in dpi, then
+ *
+ * ldx=Nd/k, ldy=Dd/k ==> Rh=k/Nd, Rv=k/Dd
+ *
+ * choosing k=m*Nd*Dd for integer Rh and Rv gives
+ *
+ * ldx=1/(m*Dd), ldy=1/(m*Nd), Rh=m*Dd, Rv=m*Nd
+ *
+ * and
+ *
+ * lx=Nh*ldx=Nh/(m*Dd), ly=Nv*ldy=Nv/(m*Nd)
+ *
+ * so choose m for the intended height Ly, in inch, as
+ *
+ * m=round(Nv/(Ly*Nd))
+ *
+ * which limits Ly<=Nv/Nd since Rv>=Nd.
+ */
+//cm=72/2.540005;
+real Ly, ly, lx, ysize, xsize, rimage, xd, yd, pwidth;
+int Nd, Dd, m, Nh, Nv, Nshift, Na, Nsy;
+real fs, Ttone;
+
+Nd=bNdot[bsys];
+Dd=bDdot[bsys]*os;
+Nh=bNh[bsys]*os;
+Nv=bNv[bsys];
+
+Ly=4; // 4 inch vertical size
+m=floor(0.5+Nv/(Ly*Nd));
+if(m<1) m=1;
+ly=Nv/(m*Nd);
+lx=Nh/(m*Dd);
+
+ysize=ly*1inch;
+xsize=lx*1inch;
+rimage=xsize/ysize;
+if(verbose > 1)
+ write('#Nd Dd m ri:\t', Nd, Dd, m, rimage);
+//size(xsize,ysize,Aspect); // should not have any effect
+
+Nsy=bNsy[bsys]; // grating size in lines 42,43, 34,35
+Nshift=bNsh[bsys]; // shift image up: pre 1997 =3, 2007 =0
+fs=1e6*bfs[bsys]*os;
+Na=0; // add 1,0,-1 to height of hor center squares for even Na+Nsy
+
+Ttone=fs/250e3; // period of ft=250 kHz, fs/ft=54
+real[] ftones={0.8e6/fs, 1.8e6/fs, 2.8e6/fs, 3.8e6/fs, 4.8e6/fs};
+
+xd=xsize/Nh;
+yd=ysize/Nv;
+pwidth=min(abs(xd),abs(yd));
+
+pen pdefault=squarecap+linewidth(pwidth);
+pen pblack=pdefault+gray(0.0);
+pen pwhite=pdefault+gray(1.0);
+
+/**** calculate grating repeats and size in tv dots ****/
+// horizontal lines
+int divsy, rdisty, Nvc, Nt, Nb;
+
+Nvc=floor(Nv/2)-Nshift;
+divsy=floor(((Nv-Na-2)/Nsy-1)/2); // (Nv-Na-2)/2-Nsy/2 dots for Nsy lengths
+rdisty=Na+Nsy*(1+2*divsy);
+Nt=Nvc-ceil(rdisty/2);
+Nb=Nv-Nt-rdisty;
+if(verbose > 1)
+ write('#divsy t b: \t',divsy,Nt,Nb);
+
+/* Nsyc: center square height
+ * line pairing test: verify distance of center to top and bot
+ * distance is odd ==> top=even/odd, cent=odd/even, bot=even/odd
+ *
+ * Nsyc odd: not possible
+ *
+ * Nsyc even:
+ * Nsyc/2 odd --> OK
+ * Nsyc/2 even --> stagger the raster one line upwards
+ *
+ * rcrowt top dist of hor line
+ * rcrowc true center for color info, distance to top of image.
+ * rcrowb bot dist of hor line
+ *
+ * Nt=Nvc-(offu+divsy*Nsy);
+ * Nb=Nv-( Nvc-(offd-divsy*Nsy) );
+ * ==> Nt+Nb=Nv-Nsyc-2*divsy*Nsy
+ */
+int Nsyc, offu, offd, Nyst=0, i;
+int[] rcrowt, rcrowc, rcrowb;
+
+Nsyc=Nsy+Na;
+offu=floor(Nsyc/2);
+offd=offu-Nsyc;
+if(Nsyc%2 != 0) {
+ Nyst=1;
+} else if(Nsyc%4 == 0) {
+ Nyst=1; /* stagger */
+}
+for(i=0; i<=divsy; ++i) {
+ int iu, id, ou, od, ru, rd;
+
+ iu=divsy-i;
+ id=divsy+i+1;
+
+ ou=offu+Nsy*i;
+ od=offd-Nsy*i;
+ if(verbose > 1)
+ write(ou,od);
+ rcrowc[iu]=Nvc-ou;
+ rcrowc[id]=Nvc-od;
+
+ ru=Nvc-(ou+Nyst);
+ rd=Nvc-(od+Nyst);
+
+ rcrowt[iu]=ru-1;
+ rcrowb[iu]=ru+1;
+
+ rcrowt[id]=rd-1;
+ rcrowb[id]=rd+1;
+}
+Nt=floor((rcrowt[0]+rcrowb[0])/2);
+Nb=Nv-Nt-Nsyc-2*Nsy*divsy;
+if(verbose > 1)
+ write('#st t b: \t',Nyst,Nt,Nb);
+
+/* vertical lines
+ * (Nh-2*os)/2-Nsx/2 dots available for divisions of Nsx dots.
+ * At least 5 dots margin left and right ==> use -10*os
+ */
+real lsq, Nsx;
+int divsx, Nhc, Nl;
+
+lsq=Nsy*yd;
+Nsx=lsq/xd;
+divsx=floor(((Nh-10*os)/Nsx-1)/2);
+Nhc=round(Nh/2);
+Nl=Nhc-round((1+2*divsx)*Nsx/2);
+if(verbose > 1)
+ write('#Nsx divsx Nl:\t',Nsx,divsx,Nl);
+
+/**** draw gray background ****/
+{
+ path zz;
+ //zz=tvrect(0,0, Nh,Nv, xd,yd,Nv);
+ /* keep white canvas for castellations */
+ zz=tvrect(Nl,Nt, Nh-Nl,Nv-Nb, xd,yd,Nv);
+ fill(zz, p=pdefault+gray(0.5));
+ //dot(zz);
+}
+/**** draw center circle ****/
+real cx, cy, crad;
+pair ccenter;
+path ccirc;
+cx=Nh/2;
+cy=Nv/2-Nshift;
+crad=6*Nsy;
+if(Nv%2 != 0) {
+ crad+=0.5;
+}
+ccenter=tvps(cx,cy, xd,yd,Nv);
+ccirc=circle(ccenter, crad*yd);
+if(colortv<=0) {
+ draw(ccirc, p=pwhite+linewidth(2*yd));
+}
+
+/****** draw 2*divsy+2 horizontal lines **********************************/
+real[] rcang, rcoff;
+pair[] rcright, rcleft;
+int i, iend=2*divsy+1;
+for(i=0; i<=iend; ++i) {
+ real y, phi, x;
+ path zzh;
+ pair zd;
+
+ zzh=tvrect(0,rcrowt[i], Nh,rcrowb[i], xd,yd,Nv);
+ fill(zzh, p=pwhite);
+
+ y=cy-rcrowc[i];
+ //write(roff);
+ if(abs(y)<crad) {
+ phi=asin(y/crad);
+ } else {
+ phi=pi/2;
+ }
+ rcang[i]=phi;
+ x=(crad*cos(phi))*yd/xd;
+ rcoff[i]=x;
+ zd=tvps(cx+x,cy-y, xd,yd,Nv);
+ rcright[i]=zd;
+ //dot(zd);
+ zd=tvps(cx-x,cy-y, xd,yd,Nv);
+ rcleft[i]=zd;
+}
+
+/****** draw 2*divsx+2 vertical lines ***************************/
+int[] coff, coffa, coffb;
+int poffa=0, ccenterwhite=divsx%2;
+for(i=0; i<=divsx; ++i) {
+ real cdist=(1+2*i)*Nsx;
+ int off, offa, offb;
+ path zzv;
+
+ off=round(cdist/2);
+ //write(cdist,off);
+ offa=off+os;
+ offb=off-os;
+
+ coff[i]=off;
+ coffa[i]=offa;
+ coffb[i]=offb;
+
+ //write(Nhc-offa);
+ zzv=tvrect(Nhc+offb,0, Nhc+offa,Nv, xd,yd,Nv);
+ fill(zzv, p=pwhite);
+ zzv=tvrect(Nhc-offa,0, Nhc-offb,Nv, xd,yd,Nv);
+ fill(zzv, p=pwhite);
+
+ /** top castellations, must end with black **/
+ if(i%2 == ccenterwhite) {
+ int j, jnum;
+
+ if(poffa == 0) {
+ poffa=-offb;
+ jnum=1;
+ } else {
+ jnum=2;
+ }
+
+ for(j=0; j<jnum; ++j) {
+ int lc, rc;
+ path zzc;
+
+ if(j==0) {
+ lc=Nhc+poffa;
+ rc=Nhc+offb;
+ } else {
+ lc=Nhc-offb;
+ rc=Nhc-poffa;
+ }
+
+ zzc=tvrect(lc,0, rc,Nt-1, xd,yd,Nv);
+ fill(zzc, p=pblack);
+ zzc=tvrect(lc,Nv-Nb+1, rc,Nv, xd,yd,Nv);
+ fill(zzc, p=pblack);
+ }
+ }
+
+ poffa=offa;
+}
+//write(coff);
+
+/** left and right castellations **/
+/* The bottom right red rectangle tests for a non causal color FIR
+ * filter in the receiver. The last 2..4 dots then typically appear
+ * colorless, green, or cyan.
+ *
+ * This comes from the fact that the chroma subcarrier is of lower
+ * bandwidth than luma and thus continues after the last active sample.
+ * These trailing (y,u,v) samples result from a signal to zero
+ * transition and depend on the transmit and receive filters. Samples
+ * from VHS, system B/G/D/K, system I, or a DVD player output are
+ * different. Nevertheless, a sharpening filter uses this data and so
+ * adds false color to the last dots.
+ */
+int lc, rc;
+iend=2*divsy+1;
+lc=Nhc-coffa[divsx];
+rc=Nhc+coffa[divsx];
+for(i=1; i<=iend; ++i) {
+ pen pcast;
+ if(i == iend && colortv>0) {
+ pcast=pdefault+rgb(0.75,0.0,0);
+ } else {
+ pcast=pblack;
+ }
+ if(i%2 == 1) {
+ int tr, br;
+ path zzc;
+
+ tr=rcrowb[i-1];
+ br=rcrowt[i];
+ zzc=tvrect( 0,tr, lc,br, xd,yd,Nv);
+ fill(zzc, p=pblack);
+ zzc=tvrect(rc,tr, Nh,br, xd,yd,Nv);
+ fill(zzc, p=pcast);
+ }
+}
+
+/****** markers for 4/3 aspect ratio ******/
+if(rimage>4/3)
+ rimarkers(rimage, Nh, Nhc, os, Nvc, Nsy, pwhite, xd, yd, Nv);
+
+/****** line pairing center ******/
+centerline(coff, coffa, coffb, Nhc, divsx, os, rcrowc, Nvc, divsy,
+ ccenter, rcoff, rcright, rcleft, pdefault, xd, yd, Nv);
+
+if(colortv>0) {
+ /* topbw structure */
+ topbw(coff, Nhc, os, rcrowc[divsy-5], rcrowc[divsy-4], rcrowc[divsy-3],
+ ccenter, rcleft[divsy-4], rcleft[divsy-3], rcright[divsy-4],
+ rcright[divsy-3], pdefault, xd, yd, Nv);
+
+ /* 250 kHz */
+ testtone(Ttone, rcrowc[divsy-3], rcrowc[divsy-2],
+ cx, cy, crad, pdefault, xd, yd, Nv);
+
+ /* color bars */
+ colorbars(coff, Nhc, rcrowc[divsy-2], rcrowc[divsy-1], rcrowc[divsy],
+ ccenter, rcleft[divsy-2], rcleft[divsy], rcright[divsy-2],
+ rcright[divsy], pdefault, xd, yd, Nv);
+
+ /* test frequencies */
+ testfreqs(ftones, coff, Nhc, rcrowc[divsy+1], rcrowc[divsy+2],
+ rcrowc[divsy+3], ccenter, rcleft[divsy+1], rcleft[divsy+3],
+ rcright[divsy+1],rcright[divsy+3], pdefault, xd, yd, Nv);
+
+ /* gray bars */
+ graybars(coff, Nhc, rcrowc[divsy+3], rcrowc[divsy+4], ccenter,
+ rcleft[divsy+3], rcleft[divsy+4],
+ rcright[divsy+3], rcright[divsy+4], pdefault, xd,yd,Nv);
+
+ /* PAL ears */
+ if(colortv==1) {
+ palears(coff,coffa,coffb, Nhc, rcrowt, rcrowb, Nvc, divsy, -1,
+ pdefault, xd, yd, Nv);
+ palears(coff,coffa,coffb, Nhc, rcrowt, rcrowb, Nvc, divsy, 1,
+ pdefault, xd, yd, Nv);
+ } else if(colortv==2) {
+ ntscbars(coff,coffa,coffb, Nhc, rcrowt, rcrowb, Nvc, divsy, -1,
+ pdefault, xd, yd, Nv);
+ ntscbars(coff,coffa,coffb, Nhc, rcrowt, rcrowb, Nvc, divsy, 1,
+ pdefault, xd, yd, Nv);
+ ntscbars(coff,coffa,coffb, Nhc, rcrowt, rcrowb, Nvc, divsy, -2,
+ pdefault, xd, yd, Nv);
+ ntscbars(coff,coffa,coffb, Nhc, rcrowt, rcrowb, Nvc, divsy, 2,
+ pdefault, xd, yd, Nv);
+ }
+
+ /* bottom wh - black - wh */
+ bottombw(round((coff[2]+coff[3])/2), Nhc, rcrowc[divsy+4], rcrowc[divsy+5],
+ ccenter, rcleft[divsy+4], rcleft[divsy+5],
+ rcright[divsy+4], rcright[divsy+5], pdefault, xd, yd, Nv);
+
+ /* bottom yellow red circle */
+ bottomcirc(coff[0], Nhc, rcrowc[divsy+5], cx, cy, crad,
+ ccenter, rcleft[divsy+5], rcright[divsy+5], pdefault, xd, yd, Nv);
+}
+
+/********************** set id *********************/
+{ /* dpi */
+ pair rpos=tvps(Nhc,round((rcrowc[divsy-4]+rcrowc[divsy-5])/2), xd,yd,Nv);
+ string iRhor, iRver, ires;
+ real Rh, Rv;
+
+ Rh=Nh/xsize*inch;
+ Rv=Nv/ysize*inch;
+ iRhor=format("%.4gx", Rh);
+ iRver=format("%.4gdpi", Rv);
+ ires=insert(iRver,0, iRhor);
+
+ /* size info */
+ int rowbot=round((rcrowc[divsy+4]+rcrowc[divsy+5])/2);
+ pair tpos=tvps(Nhc,rowbot, xd,yd,Nv);
+ string ihor, iver, itot, iasp, ifm;
+ real asp, fm;
+
+ ihor=format("%ix",Nh);
+ iver=format("%i ",Nv);
+ itot=insert(iver,0, ihor);
+ asp=xsize/ysize;
+ iasp=format("%.3g ",asp);
+ fm=fs/1e6;
+ ifm=format("%.4gMHz",fm);
+ itot=insert(iasp,0, itot);
+ itot=insert(ifm,0, itot);
+
+ /* size of square */
+ int rowNsy=round((rcrowc[divsy+5]+rcrowc[divsy+6])/2);
+ pair Npos=tvps(Nhc+round((coff[4]+coff[5])/2),rowNsy, xd,yd,Nv);
+ string iNsy=format("%i",Nsy);
+
+ pen pbw;
+ if(colortv>0) {
+ pbw=pdefault+gray(1.0);
+ } else {
+ pbw=pdefault+gray(0.0);
+ }
+ label(ires, rpos, p=pbw);
+ label(itot, tpos, p=pbw);
+ label(iNsy, Npos, p=pbw);
+ if(verbose > 1)
+ write('#res:\t', ires, itot, iNsy);
+}
+
diff --git a/Build/source/utils/asymptote/examples/twistedtubes.asy b/Build/source/utils/asymptote/examples/twistedtubes.asy
new file mode 100644
index 00000000000..420e3898986
--- /dev/null
+++ b/Build/source/utils/asymptote/examples/twistedtubes.asy
@@ -0,0 +1,28 @@
+import graph3;
+import palette;
+
+size(300,300,keepAspect=true);
+
+real w=0.4;
+
+real f(triple t) {return sin(t.x);}
+triple f1(pair t) {return (cos(t.x)-2cos(w*t.y),sin(t.x)-2sin(w*t.y),t.y);}
+triple f2(pair t) {return (cos(t.x)+2cos(w*t.y),sin(t.x)+2sin(w*t.y),t.y);}
+triple f3(pair t) {return (cos(t.x)+2sin(w*t.y),sin(t.x)-2cos(w*t.y),t.y);}
+triple f4(pair t) {return (cos(t.x)-2sin(w*t.y),sin(t.x)+2cos(w*t.y),t.y);}
+
+surface s1=surface(f1,(0,0),(2pi,10),25,15);
+surface s2=surface(f2,(0,0),(2pi,10),25,15);
+surface s3=surface(f3,(0,0),(2pi,10),25,15);
+surface s4=surface(f4,(0,0),(2pi,10),25,15);
+
+pen[] Rainbow=Rainbow();
+s1.colors(palette(s1.map(f),Rainbow));
+s2.colors(palette(s2.map(f),Rainbow));
+s3.colors(palette(s3.map(f),Rainbow));
+s4.colors(palette(s4.map(f),Rainbow));
+
+draw(s1,meshpen=black);
+draw(s2,meshpen=black);
+draw(s3,meshpen=black);
+draw(s4,meshpen=black);
diff --git a/Build/source/utils/asymptote/examples/unitcircle.asy b/Build/source/utils/asymptote/examples/unitcircle.asy
new file mode 100644
index 00000000000..582f5f3c1ff
--- /dev/null
+++ b/Build/source/utils/asymptote/examples/unitcircle.asy
@@ -0,0 +1,14 @@
+size(0,150);
+
+pair z0=0;
+pair z1=1;
+real theta=30;
+pair z=dir(theta);
+
+draw(circle(z0,1));
+filldraw(z0--arc(z0,1,0,theta)--cycle,lightgrey);
+dot(z0);
+dot(Label,z1);
+dot("$(x,y)=(\cos\theta,\sin\theta)$",z);
+arrow("area $\frac{\theta}{2}$",dir(0.5*theta),2E);
+draw("$\theta$",arc(z0,0.7,0,theta),LeftSide,Arrow,PenMargin);
diff --git a/Build/source/utils/asymptote/examples/upint.asy b/Build/source/utils/asymptote/examples/upint.asy
new file mode 100644
index 00000000000..b488358ec6a
--- /dev/null
+++ b/Build/source/utils/asymptote/examples/upint.asy
@@ -0,0 +1,13 @@
+import graph;
+import lowupint;
+
+size(100,0);
+
+real a=-0.8, b=1.2;
+real c=-1.0/sqrt(3.0);
+
+partition(a,b,c,max);
+
+arrow("$f(x)$",F(0.5*(a+b)),NNE,red);
+label("$\cal{U}$",(0.5*(a+b),f(0.5*(a+b))/2));
+
diff --git a/Build/source/utils/asymptote/examples/vectorfield3.asy b/Build/source/utils/asymptote/examples/vectorfield3.asy
new file mode 100644
index 00000000000..b8583c3b8d6
--- /dev/null
+++ b/Build/source/utils/asymptote/examples/vectorfield3.asy
@@ -0,0 +1,26 @@
+import graph3;
+
+size(12cm,0);
+
+currentprojection=orthographic(1,-2,1);
+currentlight=(1,-1,0.5);
+
+real f(pair z) {return abs(z)^2;}
+
+path3 gradient(pair z) {
+ static real dx=sqrt(realEpsilon), dy=dx;
+ return O--((f(z+dx)-f(z-dx))/2dx,(f(z+I*dy)-f(z-I*dy))/2dy,0);
+}
+
+pair A=(-1,-1);
+pair B=(1,1);
+
+triple F(pair z) {return (z.x,z.y,0);}
+
+add(vectorfield(gradient,F,A,B,red));
+
+draw(surface(f,A,B,50),gray+opacity(0.5));
+
+xaxis3(XY()*"$x$",OutTicks(XY()*Label));
+yaxis3(XY()*"$y$",InTicks(YX()*Label));
+zaxis3("$z$",OutTicks());
diff --git a/Build/source/utils/asymptote/examples/venn.asy b/Build/source/utils/asymptote/examples/venn.asy
new file mode 100644
index 00000000000..f56440ba0a4
--- /dev/null
+++ b/Build/source/utils/asymptote/examples/venn.asy
@@ -0,0 +1,37 @@
+size(0,150);
+
+pen colour1=red;
+pen colour2=green;
+
+pair z0=(0,0);
+pair z1=(-1,0);
+pair z2=(1,0);
+real r=1.5;
+path c1=circle(z1,r);
+path c2=circle(z2,r);
+fill(c1,colour1);
+fill(c2,colour2);
+
+picture intersection;
+fill(intersection,c1,colour1+colour2);
+clip(intersection,c2);
+
+add(intersection);
+
+draw(c1);
+draw(c2);
+
+label("$A$",z1);
+label("$B$",z2);
+
+pair z=(0,-2);
+real m=3;
+margin BigMargin=Margin(0,m*dot(unit(z1-z),unit(z0-z)));
+
+draw(Label("$A\cap B$",0),conj(z)--z0,Arrow,BigMargin);
+draw(Label("$A\cup B$",0),z--z0,Arrow,BigMargin);
+draw(z--z1,Arrow,Margin(0,m));
+draw(z--z2,Arrow,Margin(0,m));
+
+shipout(bbox(0.25cm));
+currentpicture.uptodate=true;
diff --git a/Build/source/utils/asymptote/examples/vertexshading.asy b/Build/source/utils/asymptote/examples/vertexshading.asy
new file mode 100644
index 00000000000..284ca3230de
--- /dev/null
+++ b/Build/source/utils/asymptote/examples/vertexshading.asy
@@ -0,0 +1,10 @@
+import three;
+//settings.prc=false;
+
+size(200);
+
+currentprojection=perspective(4,5,5);
+
+draw(surface(unitcircle3,new pen[] {red,green,blue,white}));
+draw(surface(shift(Z)*unitsquare3,
+ new pen[] {red,green+opacity(0.5),blue,black}));
diff --git a/Build/source/utils/asymptote/examples/washermethod.asy b/Build/source/utils/asymptote/examples/washermethod.asy
new file mode 100644
index 00000000000..032ed6cbc85
--- /dev/null
+++ b/Build/source/utils/asymptote/examples/washermethod.asy
@@ -0,0 +1,36 @@
+import graph3;
+import solids;
+size(0,150);
+currentprojection=perspective(0,0,11,up=Y);
+
+pen color1=green+opacity(0.25);
+pen color2=red;
+real alpha=250;
+
+real f(real x) {return 2x^2-x^3;}
+pair F(real x) {return (x,f(x));}
+triple F3(real x) {return (x,f(x),0);}
+
+ngraph=12;
+path[] p={graph(F,0.7476,1.8043,Spline)--cycle,
+ graph(F,0.7,0.7476,Spline)--graph(F,1.7787,1.8043,Spline)--cycle,
+ graph(F,0,0.7,Spline)--graph(F,1.8043,2,Spline)--cycle};
+
+pen[] pn=new pen[] {color1,color2,color1};
+
+for(int i=0; i < p.length; ++i) {
+ revolution a=revolution(path3(p[i]),Y,0,alpha);
+ draw(surface(a),pn[i]);
+
+ surface s=surface(p[i]);
+ draw(s,pn[i]);
+ draw(rotate(alpha,Y)*s,pn[i]);
+}
+
+draw((4/3,0,0)--F3(4/3),dashed);
+xtick("$\frac{4}{3}$",(4/3,0,0));
+
+xaxis3(Label("$x$",1),Arrow3);
+yaxis3(Label("$y$",1),ymax=1.25,dashed,Arrow3);
+arrow("$y=2x^2-x^3$",F3(1.6),X+Y,0.75cm,red);
+draw(arc(1.1Y,0.3,90,0,7.5,180),Arrow3);
diff --git a/Build/source/utils/asymptote/examples/wedge.asy b/Build/source/utils/asymptote/examples/wedge.asy
new file mode 100644
index 00000000000..9e0f8355308
--- /dev/null
+++ b/Build/source/utils/asymptote/examples/wedge.asy
@@ -0,0 +1,21 @@
+import graph3;
+import solids;
+size(0,150);
+currentprojection=perspective(8,10,2);
+currentlight=adobe;
+
+draw(circle(O,4,Z));
+draw(shift(-4Z)*scale(4,4,8)*unitcylinder,green+opacity(0.2));
+
+triple F(real x){return (x,sqrt(16-x^2),sqrt((16-x^2)/3));}
+path3 p=graph(F,0,4,operator ..);
+path3 q=reverse(p)--rotate(180,(0,4,4/sqrt(3)))*p--cycle;
+draw(surface(q--cycle),red);
+
+real t=2;
+path3 triangle=(t,0,0)--(t,sqrt(16-t^2),0)--F(t)--cycle;
+draw(surface(triangle),blue);
+
+xaxis3("$x$",Arrow3,PenMargin3(0,0.25));
+yaxis3("$y$",Arrow3,PenMargin3(0,0.25));
+zaxis3("$z$",dashed,Arrow3);
diff --git a/Build/source/utils/asymptote/examples/workcone.asy b/Build/source/utils/asymptote/examples/workcone.asy
new file mode 100644
index 00000000000..5b4f8c94ad5
--- /dev/null
+++ b/Build/source/utils/asymptote/examples/workcone.asy
@@ -0,0 +1,40 @@
+import solids;
+size(0,150);
+currentprojection=orthographic(0,-30,5);
+
+real r=4;
+real h=10;
+real s=8;
+real x=r*s/h;
+
+real sr=5;
+real xr=r*sr/h;
+
+real s1=sr-0.1;
+real x1=r*s1/h;
+
+real s2=sr+0.2;
+real x2=r*s2/h;
+
+path3 p=(0,0,0)--(x,0,s);
+revolution a=revolution(p,Z);
+draw(surface(a,4),lightblue+opacity(0.5));
+
+path3 q=(x,0,s)--(r,0,h);
+revolution b=revolution(q,Z);
+draw(surface(b),white+opacity(0.5));
+
+draw((-r-1,0,0)--(r+1,0,0));
+draw((0,0,0)--(0,0,h+1),dashed);
+
+path3 w=(x1,0,s1)--(x2,0,s2)--(0,0,s2);
+revolution b=revolution(w,Z);
+draw(surface(b),blue+opacity(0.5));
+draw(circle((0,0,s2),x2));
+draw(circle((0,0,s1),x1));
+
+draw("$x$",(xr,0,0)--(xr,0,sr),red,Arrow3,PenMargin3);
+draw("$r$",(0,0,sr)--(xr,0,sr),N,red);
+draw((string) r,(0,0,h)--(r,0,h),N,red);
+draw((string) h,(r,0,0)--(r,0,h),red,Arrow3,PenMargin3);
+draw((string) s,(-x,0,0)--(-x,0,s),W,red,Arrow3,Bar3,PenMargin3);
diff --git a/Build/source/utils/asymptote/examples/xsin1x.asy b/Build/source/utils/asymptote/examples/xsin1x.asy
new file mode 100644
index 00000000000..f03714b79df
--- /dev/null
+++ b/Build/source/utils/asymptote/examples/xsin1x.asy
@@ -0,0 +1,10 @@
+import graph;
+size(300,0);
+
+real f(real x) {return (x != 0.0) ? x * sin(1.0 / x) : 0.0;}
+pair F(real x) {return (x,f(x));}
+
+xaxis("$x$",red);
+yaxis(red);
+draw(graph(f,-1.2/pi,1.2/pi,1000));
+label("$x\sin\frac{1}{x}$",F(1.1/pi),NW);
diff --git a/Build/source/utils/asymptote/examples/xxsq01.asy b/Build/source/utils/asymptote/examples/xxsq01.asy
new file mode 100644
index 00000000000..11a035f0418
--- /dev/null
+++ b/Build/source/utils/asymptote/examples/xxsq01.asy
@@ -0,0 +1,30 @@
+import graph3;
+import solids;
+size(0,150);
+currentprojection=perspective(0,0,10,up=Y);
+
+pen color=green;
+real alpha=250;
+
+real f(real x) {return x^2;}
+pair F(real x) {return (x,f(x));}
+triple F3(real x) {return (x,f(x),0);}
+
+path p=graph(F,0,1,n=10,operator ..)--cycle;
+path3 p3=path3(p);
+
+revolution a=revolution(p3,X,-alpha,0);
+draw(surface(a),color);
+
+surface s=surface(p);
+draw(s,color);
+draw(rotate(-alpha,X)*s,color);
+
+draw(p3,blue);
+
+xaxis3(Label("$x$",1),xmax=1.25,dashed,Arrow3);
+yaxis3(Label("$y$",1),Arrow3);
+dot(Label("$(1,1)$"),(1,1,0),X+Y);
+arrow("$y=x$",(0.7,0.7,0),Y,0.75cm,red);
+arrow("$y=x^2$",F3(0.7),X,0.75cm,red);
+draw(arc(1.1X,0.3,90,90,3,-90),Arrow3);
diff --git a/Build/source/utils/asymptote/examples/xxsq01x-1.asy b/Build/source/utils/asymptote/examples/xxsq01x-1.asy
new file mode 100644
index 00000000000..2c4c9ec363c
--- /dev/null
+++ b/Build/source/utils/asymptote/examples/xxsq01x-1.asy
@@ -0,0 +1,34 @@
+import graph3;
+import solids;
+size(300);
+currentprojection=perspective(0,2,10,up=Y);
+currentlight=(0.25,-0.25,5);
+
+pen color=green;
+
+real f(real x) {return x^2;}
+pair F(real x) {return (x,f(x));}
+triple F3(real x) {return (x,f(x),0);}
+
+path p=graph(F,0,1,n=10,operator ..)--cycle;
+path3 p3=path3(p);
+
+revolution a=revolution(-X,p3,Y,0,180);
+draw(surface(a),color);
+surface s=surface(p);
+draw(s,color);
+transform3 t=shift(-2X)*rotate(180,Y);
+draw(t*s,color);
+draw(p3);
+draw(t*p3);
+
+draw((-1,0,0)--(-1,1,0),dashed);
+xaxis3(Label("$x$",1),Arrow3);
+yaxis3(Label("$y$",1),Arrow3);
+dot(Label("$(1,1)$"),(1,1,0));
+dot(Label("$(-1,1)$"),(-1,1,0),W);
+arrow("$y=x^{2}$",F3(0.7),X,1cm,red);
+arrow("$y=x$",(0.3,0.3,0),X,1.5cm,red);
+draw(circle((-1,1,0),2,Y),dashed);
+draw((-1,1,0)--(1,1,0),dashed);
+draw(shift(-X)*arc(0.02Y,0.3,90,0,0,0,CW),Arrow3);
diff --git a/Build/source/utils/asymptote/examples/xxsq01y.asy b/Build/source/utils/asymptote/examples/xxsq01y.asy
new file mode 100644
index 00000000000..14cf177256e
--- /dev/null
+++ b/Build/source/utils/asymptote/examples/xxsq01y.asy
@@ -0,0 +1,32 @@
+import solids;
+size(0,150);
+currentprojection=perspective(0,0,10);
+pen color=green;
+real alpha=240;
+
+real f(real x) {return x^2;}
+pair F(real x) {return (x,f(x));}
+triple F3(real x) {return (x,f(x),0);}
+
+path p=graph(F,0,1,n=10,operator ..)--cycle;
+path3 p3=path3(p);
+
+draw(surface(revolution(p3,Y,0,alpha)),color);
+
+surface s=surface(p);
+draw(s,color);
+draw(rotate(alpha,Y)*s,color);
+
+draw(p3,blue);
+
+xaxis3(Label("$x$",1),Arrow3);
+yaxis3(Label("$y$",1),ymax=1.25,dashed,Arrow3);
+
+dot("$(1,1)$",(1,1,0),X);
+arrow("$y=x^{2}$",F3(0.7),X,0.75cm,red);
+arrow("$y=x$",(0.8,0.8,0),Y,1cm,red);
+
+real r=0.4;
+draw((r,f(r),0)--(r,r,0),red);
+draw("$r$",(0,(f(r)+r)*0.5,0)--(r,(f(r)+r)*0.5,0),N,red,Arrows3,PenMargins3);
+draw(arc(1.1Y,0.3,90,0,7.5,180),Arrow3);
diff --git a/Build/source/utils/asymptote/examples/yingyang.asy b/Build/source/utils/asymptote/examples/yingyang.asy
new file mode 100644
index 00000000000..68b0d0eea74
--- /dev/null
+++ b/Build/source/utils/asymptote/examples/yingyang.asy
@@ -0,0 +1,7 @@
+size(0,25cm);
+guide center=(0,1){W}..tension 0.8..(0,0){(1,-.5)}..tension 0.8..{W}(0,-1);
+
+draw((0,1)..(-1,0)..(0,-1));
+filldraw(center{E}..{N}(1,0)..{W}cycle);
+unfill(circle((0,0.5),0.125));
+fill(circle((0,-0.5),0.125));
diff --git a/Build/source/utils/asymptote/exp.cc b/Build/source/utils/asymptote/exp.cc
new file mode 100644
index 00000000000..6ec234212de
--- /dev/null
+++ b/Build/source/utils/asymptote/exp.cc
@@ -0,0 +1,1166 @@
+/*****
+ * exp.cc
+ * andy hammerlindl 2002/8/19
+ *
+ * represents the abstract syntax tree for the expressions in the
+ * language. this is translated into virtual machine code using trans()
+ * and with the aid of the environment class.
+ *****/
+
+#include "exp.h"
+#include "errormsg.h"
+#include "runtime.h"
+#include "coenv.h"
+#include "application.h"
+#include "dec.h"
+#include "stm.h"
+#include "inst.h"
+
+namespace absyntax {
+
+using namespace types;
+using namespace trans;
+using vm::inst;
+using mem::vector;
+
+
+void exp::prettyprint(ostream &out, Int indent)
+{
+ prettyname(out, "exp",indent);
+}
+
+void exp::transAsType(coenv &e, types::ty *target) {
+ types::ty *t=trans(e);
+ assert(t->kind==ty_error || equivalent(t,target));
+}
+
+void exp::transToType(coenv &e, types::ty *target)
+{
+ types::ty *source=e.e.castSource(target, cgetType(e), symbol::castsym);
+ if (source==0) {
+ types::ty *sources=cgetType(e);
+ em.error(getPos());
+ em << "cannot cast ";
+ if (sources->kind==ty_overloaded)
+ em << "expression";
+ else
+ em << "'" << *sources << "'";
+ em << " to '" << *target << "'";
+ }
+ else if (source->kind==ty_overloaded) {
+ em.error(getPos());
+ em << "expression is ambiguous in cast to '" << *target << "'";
+ }
+ else {
+ transAsType(e, source);
+ e.implicitCast(getPos(), target, source);
+ }
+}
+
+void exp::testCachedType(coenv &e) {
+ if (ct != 0) {
+ types::ty *t = getType(e);
+ if (!equivalent(t, ct)) {
+ em.compiler(getPos());
+ em << "cached type '" << *ct
+ << "' doesn't match actual type '" << *t;
+ }
+ }
+}
+
+void exp::transCall(coenv &e, types::ty *target)
+{
+ transAsType(e, target);
+ e.c.encode(inst::popcall);
+}
+
+exp *exp::evaluate(coenv &e, types::ty *target) {
+ return new tempExp(e, this, target);
+}
+
+
+tempExp::tempExp(coenv &e, varinit *v, types::ty *t)
+ : exp(v->getPos()), a(e.c.allocLocal()), t(t)
+{
+ v->transToType(e, t);
+ a->encode(WRITE, getPos(), e.c);
+ e.c.encode(inst::pop);
+}
+
+types::ty *tempExp::trans(coenv &e) {
+ a->encode(READ, getPos(), e.c);
+ return t;
+}
+
+
+varEntryExp::varEntryExp(position pos, types::ty *t, access *a)
+ : exp(pos), v(new trans::varEntry(t, a, 0, position())) {}
+varEntryExp::varEntryExp(position pos, types::ty *t, vm::bltin f)
+ : exp(pos), v(new trans::varEntry(t, new bltinAccess(f), 0, position())) {}
+
+types::ty *varEntryExp::getType(coenv &) {
+ return v->getType();
+}
+
+types::ty *varEntryExp::trans(coenv &e) {
+ v->encode(READ, getPos(), e.c);
+ return getType(e);
+}
+
+void varEntryExp::transAct(action act, coenv &e, types::ty *target) {
+ assert(equivalent(getType(e),target));
+ v->encode(act, getPos(), e.c);
+}
+void varEntryExp::transAsType(coenv &e, types::ty *target) {
+ transAct(READ, e, target);
+}
+void varEntryExp::transWrite(coenv &e, types::ty *target) {
+ transAct(WRITE, e, target);
+}
+void varEntryExp::transCall(coenv &e, types::ty *target) {
+ transAct(CALL, e, target);
+}
+
+
+void nameExp::prettyprint(ostream &out, Int indent)
+{
+ prettyname(out, "nameExp",indent);
+
+ value->prettyprint(out, indent+1);
+}
+
+
+void fieldExp::pseudoName::prettyprint(ostream &out, Int indent)
+{
+ // This should never be called.
+ prettyindent(out, indent);
+ out << "pseudoName" << "\n";
+
+ object->prettyprint(out, indent+1);
+}
+
+void fieldExp::prettyprint(ostream &out, Int indent)
+{
+ prettyindent(out, indent);
+ out << "fieldExp '" << *field << "'\n";
+
+ object->prettyprint(out, indent+1);
+}
+
+types::ty *fieldExp::getObject(coenv& e)
+{
+ types::ty *t = object->cgetType(e);
+ if (t->kind == ty_overloaded) {
+ t=((overloaded *)t)->signatureless();
+ if(!t) return primError();
+ }
+ return t;
+}
+
+
+array *arrayExp::getArrayType(coenv &e)
+{
+ types::ty *a = set->cgetType(e);
+ if (a->kind == ty_overloaded) {
+ a = ((overloaded *)a)->signatureless();
+ if (!a)
+ return 0;
+ }
+
+ switch (a->kind) {
+ case ty_array:
+ return (array *)a;
+ case ty_error:
+ return 0;
+ default:
+ return 0;
+ }
+}
+
+array *arrayExp::transArray(coenv &e)
+{
+ types::ty *a = set->cgetType(e);
+ if (a->kind == ty_overloaded) {
+ a = ((overloaded *)a)->signatureless();
+ if (!a) {
+ em.error(set->getPos());
+ em << "expression is not an array";
+ return 0;
+ }
+ }
+
+ set->transAsType(e, a);
+
+ switch (a->kind) {
+ case ty_array:
+ return (array *)a;
+ case ty_error:
+ return 0;
+ default:
+ em.error(set->getPos());
+ em << "expression is not an array";
+ return 0;
+ }
+}
+
+// Checks if the expression can be translated as an array.
+bool isAnArray(coenv &e, exp *x)
+{
+ types::ty *t=x->cgetType(e);
+ if (t->kind == ty_overloaded)
+ t=dynamic_cast<overloaded *>(t)->signatureless();
+ return t && t->kind==ty_array;
+}
+
+
+void subscriptExp::prettyprint(ostream &out, Int indent)
+{
+ prettyindent(out, indent);
+ out << "subscriptExp\n";
+
+ set->prettyprint(out, indent+1);
+ index->prettyprint(out, indent+1);
+}
+
+types::ty *subscriptExp::trans(coenv &e)
+{
+ array *a = transArray(e);
+ if (!a)
+ return primError();
+
+ if (isAnArray(e, index)) {
+ index->transToType(e, types::IntArray());
+ e.c.encode(inst::builtin, run::arrayIntArray);
+ return getArrayType(e);
+ }
+ else {
+ index->transToType(e, types::primInt());
+ e.c.encode(inst::builtin,
+ a->celltype->kind==ty_array ? run::arrayArrayRead :
+ run::arrayRead);
+ return a->celltype;
+ }
+}
+
+types::ty *subscriptExp::getType(coenv &e)
+{
+ array *a = getArrayType(e);
+ return a ? (isAnArray(e, index) ? a : a->celltype) :
+ primError();
+}
+
+void subscriptExp::transWrite(coenv &e, types::ty *t)
+{
+ array *a = transArray(e);
+ if (!a)
+ return;
+ assert(equivalent(a->celltype, t));
+
+ index->transToType(e, types::primInt());
+ e.c.encode(inst::builtin, run::arrayWrite);
+}
+
+
+void slice::prettyprint(ostream &out, Int indent)
+{
+ prettyname(out, "slice", indent);
+ if (left)
+ left->prettyprint(out, indent+1);
+ else
+ prettyname(out, "left omitted", indent+1);
+ if (right)
+ right->prettyprint(out, indent+1);
+ else
+ prettyname(out, "right omitted", indent+1);
+}
+
+void slice::trans(coenv &e)
+{
+ if (left)
+ left->transToType(e, types::primInt());
+ else
+ // If the left index is omitted it can be assumed to be zero.
+ e.c.encode(inst::intpush, (Int)0);
+
+ if (right)
+ right->transToType(e, types::primInt());
+}
+
+
+void sliceExp::prettyprint(ostream &out, Int indent)
+{
+ prettyname(out, "sliceExp", indent);
+ set->prettyprint(out, indent+1);
+ index->prettyprint(out, indent+1);
+}
+
+types::ty *sliceExp::trans(coenv &e)
+{
+ array *a = transArray(e);
+ if (!a)
+ return primError();
+
+ index->trans(e);
+
+ e.c.encode(inst::builtin, index->getRight() ? run::arraySliceRead :
+ run::arraySliceReadToEnd);
+
+ return a;
+}
+
+types::ty *sliceExp::getType(coenv &e)
+{
+ array *a = getArrayType(e);
+ return a ? a : primError();
+}
+
+void sliceExp::transWrite(coenv &e, types::ty *t)
+{
+ array *a = transArray(e);
+ if (!a)
+ return;
+ assert(equivalent(a, t));
+
+ index->trans(e);
+
+ e.c.encode(inst::builtin, index->getRight() ? run::arraySliceWrite :
+ run::arraySliceWriteToEnd);
+}
+
+void thisExp::prettyprint(ostream &out, Int indent)
+{
+ prettyname(out, "thisExp", indent);
+}
+
+types::ty *thisExp::trans(coenv &e)
+{
+ if (!e.c.encodeThis()) {
+ em.error(getPos());
+ em << "static use of 'this' expression";
+ }
+ return cgetType(e);
+}
+
+types::ty *thisExp::getType(coenv &e)
+{
+ return e.c.thisType();
+}
+
+void scaleExp::prettyprint(ostream &out, Int indent)
+{
+ exp *left=getLeft(); exp *right=getRight();
+
+ prettyname(out, "scaleExp",indent);
+ left->prettyprint(out, indent+1);
+ right->prettyprint(out, indent+1);
+}
+
+types::ty *scaleExp::trans(coenv &e)
+{
+ exp *left=getLeft(); exp *right=getRight();
+
+ types::ty *lt = left->cgetType(e);
+ if (lt->kind != types::ty_Int && lt->kind != types::ty_real) {
+ if (lt->kind != types::ty_error) {
+ em.error(left->getPos());
+ em << "only numeric constants can do implicit scaling";
+ }
+ right->trans(e);
+ return types::primError();
+ }
+
+ if (!right->scalable()) {
+ em.warning(right->getPos());
+ em << "implicit scaling may be unintentional";
+ }
+
+ // Defer to the binaryExp for multiplication.
+ return binaryExp::trans(e);
+}
+
+
+void intExp::prettyprint(ostream &out, Int indent)
+{
+ prettyindent(out,indent);
+ out << "intExp: " << value << "\n";
+}
+
+types::ty *intExp::trans(coenv &e)
+{
+ e.c.encode(inst::intpush,value);
+
+ return types::primInt();
+}
+
+
+void realExp::prettyprint(ostream &out, Int indent)
+{
+ prettyindent(out, indent);
+ out << "realExp: " << value << "\n";
+}
+
+types::ty *realExp::trans(coenv &e)
+{
+ e.c.encode(inst::constpush,(item)value);
+
+ return types::primReal();
+}
+
+void stringExp::prettyprint(ostream &out, Int indent)
+{
+ prettyindent(out, indent);
+ out << "stringExp '" << str << "'\n";
+}
+
+types::ty *stringExp::trans(coenv &e)
+{
+ e.c.encode(inst::constpush,(item) string(str));
+
+ return types::primString();
+}
+
+
+void booleanExp::prettyprint(ostream &out, Int indent)
+{
+ prettyindent(out, indent);
+ out << "booleanExp: " << value << "\n";
+}
+
+types::ty *booleanExp::trans(coenv &e)
+{
+ e.c.encode(inst::constpush,(item)value);
+
+ return types::primBoolean();
+}
+
+void newPictureExp::prettyprint(ostream &out, Int indent)
+{
+ prettyname(out, "newPictureExp",indent);
+}
+
+types::ty *newPictureExp::trans(coenv &e)
+{
+ e.c.encode(inst::builtin, run::newPicture);
+
+ return types::primPicture();
+}
+
+void cycleExp::prettyprint(ostream &out, Int indent)
+{
+ prettyname(out, "cycleExp",indent);
+}
+
+types::ty *cycleExp::trans(coenv &e)
+{
+ e.c.encode(inst::builtin, run::newCycleToken);
+
+ return types::primCycleToken();
+}
+
+void nullPathExp::prettyprint(ostream &out, Int indent)
+{
+ prettyname(out, "nullPathExp",indent);
+}
+
+types::ty *nullPathExp::trans(coenv &e)
+{
+ e.c.encode(inst::builtin, run::nullPath);
+
+ return types::primPath();
+}
+
+void nullExp::prettyprint(ostream &out, Int indent)
+{
+ prettyname(out, "nullExp",indent);
+}
+
+types::ty *nullExp::trans(coenv &)
+{
+ // Things get put on the stack when ty_null
+ // is cast to an appropriate type
+ return types::primNull();
+}
+
+
+void quoteExp::prettyprint(ostream &out, Int indent)
+{
+ prettyname(out, "quoteExp", indent);
+ value->prettyprint(out, indent+1);
+}
+
+types::ty *quoteExp::trans(coenv &e)
+{
+ e.c.encode(inst::constpush,(item)value);
+
+ return types::primCode();
+}
+
+void explist::prettyprint(ostream &out, Int indent)
+{
+ prettyname(out, "explist",indent);
+ for (expvector::iterator p = exps.begin();
+ p != exps.end(); ++p)
+ (*p)->prettyprint(out, indent+1);
+}
+
+
+void argument::prettyprint(ostream &out, Int indent)
+{
+ prettyindent(out, indent);
+ out << "explist";
+ if (name)
+ out << " '" << *name << "'";
+ out << '\n';
+
+ val->prettyprint(out, indent+1);
+}
+
+void arglist::prettyprint(ostream &out, Int indent)
+{
+ prettyname(out, "arglist",indent);
+ for (argvector::iterator p = args.begin();
+ p != args.end(); ++p)
+ p->prettyprint(out, indent+1);
+}
+
+void callExp::prettyprint(ostream &out, Int indent)
+{
+ prettyname(out, "callExp",indent);
+
+ callee->prettyprint(out, indent+1);
+ args->prettyprint(out, indent+1);
+}
+
+signature *callExp::argTypes(coenv &e)
+{
+ signature *source=new signature;
+
+ size_t n = args->size();
+ for (size_t i = 0; i < n; i++) {
+ argument a=(*args)[i];
+ types::ty *t = a.val->cgetType(e);
+ if (t->kind == types::ty_error)
+ return 0;
+ source->add(types::formal(t,a.name));
+ }
+
+ if (args->rest.val) {
+ argument a=args->rest;
+ types::ty *t = a.val->cgetType(e);
+ if (t->kind == types::ty_error)
+ return 0;
+ source->addRest(types::formal(t,a.name));
+ }
+
+ return source;
+}
+
+application *callExp::resolve(coenv &e, overloaded *o, signature *source,
+ bool tacit) {
+ app_list l=multimatch(e.e, o, source, *args);
+
+ if (l.empty()) {
+ //cerr << "l is empty\n";
+ if (!tacit) {
+ em.error(getPos());
+
+ symbol *s = callee->getName();
+ if (s)
+ em << "no matching function \'" << *s;
+ else
+ em << "no matching function for signature \'";
+ em << *source << "\'";
+ }
+
+ return 0;
+ }
+ else if (l.size() > 1) { // This may take O(n) time.
+ //cerr << "l is full\n";
+ if (!tacit) {
+ em.error(getPos());
+
+ symbol *s = callee->getName();
+ if(s)
+ em << "call of function \'" << *s;
+ else
+ em << "call with signature \'";
+ em << *source << "\' is ambiguous";
+ }
+
+ return 0;
+ }
+ else {
+ //cerr << "l is singleton\n";
+ return l.front();
+ }
+}
+
+bool hasNamedParameters(signature *sig) {
+ for (size_t i=0; i < sig->getNumFormals(); ++i)
+ if (sig->getFormal(i).name)
+ return true;
+ return false;
+}
+
+void callExp::reportMismatch(symbol *s, function *ft, signature *source)
+{
+ const char *separator=ft->getSignature()->getNumFormals() > 1 ? "\n" : " ";
+
+ em.error(getPos());
+ em << "cannot call" << separator << "'" << *ft->getResult() << " ";
+ if(s)
+ em << *s;
+ em << *ft->getSignature() << "'" << separator;
+
+ if (ft->getSignature()->isOpen && hasNamedParameters(source))
+ em << "with named parameters";
+ else
+ switch(source->getNumFormals()) {
+ case 0:
+ em << "without parameters";
+ break;
+ case 1:
+ em << "with parameter '" << *source << "'";
+ break;
+ default:
+ em << "with parameters\n'" << *source << "'";
+ }
+}
+
+void callExp::reportArgErrors(coenv &e)
+{
+ // Cycle through the parameters to report all errors.
+ // NOTE: This may report inappropriate ambiguity errors.
+ for (size_t i = 0; i < args->size(); i++) {
+ (*args)[i].val->trans(e);
+ }
+ if (args->rest.val)
+ args->rest.val->trans(e);
+}
+
+application *callExp::getApplication(coenv &e)
+{
+ // First figure out the signature of what we want to call.
+ signature *source=argTypes(e);
+
+ if (!source)
+ return 0;
+
+ // Figure out what function types we can call.
+ trans::ty *ft = callee->cgetType(e);
+ switch (ft->kind) {
+ case ty_error:
+ // Report callee errors.
+ //cerr << "reporting callee errors\n";
+ callee->trans(e);
+ return 0;
+ case ty_function: {
+ application *a=application::match(e.e, (function *)ft, source, *args);
+ if (!a) {
+ //cerr << "reporting mismatch\n";
+ reportMismatch(callee->getName(), (function *)ft, source);
+ }
+ //cerr << "returning function\n";
+ return a;
+ }
+ case ty_overloaded:
+ //cerr << "resolving overloaded\n";
+ return resolve(e, (overloaded *)ft, source, false);
+ default:
+ //cerr << "not a function\n";
+ em.error(getPos());
+ symbol *s = callee->getName();
+ if (s)
+ em << "\'" << *s << "\' is not a function";
+ else
+ em << "called expression is not a function";
+ return 0;
+ }
+}
+
+types::ty *callExp::trans(coenv &e)
+{
+#if 0
+ cerr << "callExp::trans() called for ";
+ if (callee->getName())
+ cerr << *callee->getName();
+ cerr << endl;
+#endif
+
+#ifdef DEBUG_CACHE
+ if (ca)
+ assert(equivalent(ca->getType(), getApplication(e)->getType()));
+#endif
+ application *a= ca ? ca : getApplication(e);
+
+ // The cached application is no longer needed after translation, so
+ // let it be garbage collected.
+ ca=0;
+
+ if (!a) {
+ reportArgErrors(e);
+ return primError();
+ }
+
+ // To simulate left-to-right order of evaluation, produce the
+ // side-effects for the callee.
+ assert(a);
+ function *t=a->getType();
+ assert(t);
+ exp *temp=callee->evaluate(e, t);
+
+ // Let the application handle the argument translation.
+ a->transArgs(e);
+
+ // Translate the call.
+ temp->transCall(e, t);
+
+ assert(ct==0 || equivalent(ct, t->result));
+ return t->result;
+}
+
+types::ty *callExp::getType(coenv &e)
+{
+ // First figure out the signature of what we want to call.
+ signature *source=argTypes(e);
+ if (!source)
+ return types::primError();
+
+ // Figure out what function types we can call.
+ trans::ty *ft = callee->cgetType(e);
+
+ switch (ft->kind) {
+ case ty_function:
+ return ((function *)ft)->result;
+ case ty_overloaded: {
+ application *a=resolve(e, (overloaded *)ft, source, true);
+ if (a) {
+ // Cache the application to avoid calling multimatch again later.
+ ca=a;
+ return ca->getType()->result;
+ }
+ else
+ return primError();
+ }
+ default:
+ return primError();
+ }
+}
+
+void pairExp::prettyprint(ostream &out, Int indent)
+{
+ prettyname(out, "pairExp",indent);
+
+ x->prettyprint(out, indent+1);
+ y->prettyprint(out, indent+1);
+}
+
+types::ty *pairExp::trans(coenv &e)
+{
+ x->transToType(e, types::primReal());
+ y->transToType(e, types::primReal());
+
+ e.c.encode(inst::builtin, run::realRealToPair);
+
+ return types::primPair();
+}
+
+void tripleExp::prettyprint(ostream &out, Int indent)
+{
+ prettyname(out, "tripleExp",indent);
+
+ x->prettyprint(out, indent+1);
+ y->prettyprint(out, indent+1);
+ z->prettyprint(out, indent+1);
+}
+
+types::ty *tripleExp::trans(coenv &e)
+{
+ x->transToType(e, types::primReal());
+ y->transToType(e, types::primReal());
+ z->transToType(e, types::primReal());
+
+ e.c.encode(inst::builtin, run::realRealRealToTriple);
+
+ return types::primTriple();
+}
+
+void transformExp::prettyprint(ostream &out, Int indent)
+{
+ prettyname(out, "transformExp",indent);
+
+ x->prettyprint(out, indent+1);
+ y->prettyprint(out, indent+1);
+ xx->prettyprint(out, indent+1);
+ xy->prettyprint(out, indent+1);
+ yx->prettyprint(out, indent+1);
+ yy->prettyprint(out, indent+1);
+}
+
+types::ty *transformExp::trans(coenv &e)
+{
+ x->transToType(e, types::primReal());
+ y->transToType(e, types::primReal());
+ xx->transToType(e, types::primReal());
+ xy->transToType(e, types::primReal());
+ yx->transToType(e, types::primReal());
+ yy->transToType(e, types::primReal());
+
+ e.c.encode(inst::builtin, run::real6ToTransform);
+
+ return types::primTransform();
+}
+
+void castExp::prettyprint(ostream &out, Int indent)
+{
+ prettyname(out, "castExp",indent);
+
+ target->prettyprint(out, indent+1);
+ castee->prettyprint(out, indent+1);
+}
+
+types::ty *castExp::tryCast(coenv &e, types::ty *t, types::ty *s,
+ symbol *csym)
+{
+ types::ty *ss=e.e.castSource(t, s, csym);
+ if (ss == 0) {
+ return 0;
+ }
+ if (ss->kind == ty_overloaded) {
+ em.error(getPos());
+ em << "cast is ambiguous";
+ return primError();
+ }
+ else {
+ castee->transAsType(e, ss);
+
+ access *a=e.e.lookupCast(t, ss, csym);
+ assert(a);
+ a->encode(CALL, getPos(), e.c);
+ return ss;
+ }
+}
+
+types::ty *castExp::trans(coenv &e)
+{
+ target->addOps(e, (record *)0);
+ types::ty *t=target->trans(e);
+
+ types::ty *s=castee->cgetType(e);
+
+ if (!tryCast(e, t, s, symbol::ecastsym))
+ if (!tryCast(e, t, s, symbol::castsym)) {
+ em.error(getPos());
+ em << "cannot cast '" << *s << "' to '" << *t << "'";
+ }
+
+ return t;
+}
+
+types::ty *castExp::getType(coenv &e)
+{
+ return target->trans(e, true);
+}
+
+
+void conditionalExp::prettyprint(ostream &out, Int indent)
+{
+ prettyname(out, "conditionalExp",indent);
+
+ test->prettyprint(out, indent+1);
+ onTrue->prettyprint(out, indent+1);
+ onFalse->prettyprint(out, indent+1);
+}
+
+void conditionalExp::baseTransToType(coenv &e, types::ty *target) {
+ test->transToType(e, types::primBoolean());
+
+ Int tlabel = e.c.fwdLabel();
+ e.c.useLabel(inst::cjmp,tlabel);
+
+ onFalse->transToType(e, target);
+
+ Int end = e.c.fwdLabel();
+ e.c.useLabel(inst::jmp,end);
+
+ e.c.defLabel(tlabel);
+ onTrue->transToType(e, target);
+
+ e.c.defLabel(end);
+}
+
+void conditionalExp::transToType(coenv &e, types::ty *target)
+{
+ if (isAnArray(e, test)) {
+ if (target->kind != ty_array) {
+ em.error(getPos());
+ em << "cannot cast vectorized conditional to '" << *target << "'";
+ }
+ test->transToType(e, types::boolArray());
+ onTrue->transToType(e, target);
+ onFalse->transToType(e, target);
+ e.c.encode(inst::builtin, run::arrayConditional);
+ }
+ else {
+ baseTransToType(e, target);
+ }
+}
+
+types::ty *promote(coenv &e, types::ty *x, types::ty *y)
+{
+ struct promoter : public collector {
+ env &e;
+
+ promoter(env &e)
+ : e(e) {}
+
+ types::ty *both (types::ty *x, types::ty *y) {
+ overloaded *o=new overloaded;
+ o->add(x); o->add(y);
+ return o;
+ }
+
+ types::ty *base (types::ty *x, types::ty *y) {
+ if (equivalent(x,y))
+ return x;
+ else {
+ bool castToFirst=e.castable(x, y, symbol::castsym);
+ bool castToSecond=e.castable(y, x, symbol::castsym);
+
+ return (castToFirst && castToSecond) ? both(x,y) :
+ castToFirst ? x :
+ castToSecond ? y :
+ 0;
+ }
+ }
+ };
+
+ promoter p(e.e);
+ return p.collect(x,y);
+}
+
+types::ty *conditionalExp::trans(coenv &e)
+{
+ types::ty *tt=onTrue->cgetType(e);
+ types::ty *ft=onFalse->cgetType(e);
+
+ if (tt->kind==ty_error)
+ return onTrue->trans(e);
+ if (ft->kind==ty_error)
+ return onFalse->trans(e);
+
+ types::ty *t=promote(e, tt, ft);
+ if (!t) {
+ em.error(getPos());
+ em << "types in conditional expression do not match";
+ return primError();
+ }
+ else if (t->kind == ty_overloaded) {
+ em.error(getPos());
+ em << "type of conditional expression is ambiguous";
+ return primError();
+ }
+
+ transToType(e,t);
+ return t;
+}
+
+types::ty *conditionalExp::getType(coenv &e)
+{
+ types::ty *tt=onTrue->cgetType(e);
+ types::ty *ft=onFalse->cgetType(e);
+ if (tt->kind==ty_error || ft->kind==ty_error)
+ return primError();
+
+ types::ty *t = promote(e, tt, ft);
+ return t ? t : primError();
+}
+
+
+void orExp::prettyprint(ostream &out, Int indent)
+{
+ prettyname(out, "orExp", indent);
+
+ left->prettyprint(out, indent+1);
+ right->prettyprint(out, indent+1);
+}
+
+types::ty *orExp::trans(coenv &e)
+{
+ // a || b
+ // translates into
+ // a ? true : b
+ booleanExp be(pos, true);
+ conditionalExp ce(pos, left, &be, right);
+ ce.baseTransToType(e, primBoolean());
+
+ return getType(e);
+}
+
+
+void andExp::prettyprint(ostream &out, Int indent)
+{
+ prettyname(out, "andExp", indent);
+
+ left->prettyprint(out, indent+1);
+ right->prettyprint(out, indent+1);
+}
+
+types::ty *andExp::trans(coenv &e)
+{
+ // a && b
+ // translates into
+ // a ? b : false
+ booleanExp be(pos, false);
+ conditionalExp ce(pos, left, right, &be);
+ ce.baseTransToType(e, primBoolean());
+
+ return getType(e);
+}
+
+
+void joinExp::prettyprint(ostream &out, Int indent)
+{
+ prettyname(out, "joinExp",indent);
+
+ callee->prettyprint(out, indent+1);
+ args->prettyprint(out, indent+1);
+}
+
+
+void specExp::prettyprint(ostream &out, Int indent)
+{
+ prettyindent(out,indent);
+ out << "specExp '" << *op << "' "
+ << (s==camp::OUT ? "out" :
+ s==camp::IN ? "in" :
+ "invalid side") << '\n';
+
+ arg->prettyprint(out, indent+1);
+}
+
+types::ty *specExp::trans(coenv &e)
+{
+ intExp ie(getPos(), (Int)s);
+ binaryExp be(getPos(), arg, op, &ie);
+ return be.trans(e);
+}
+
+types::ty *specExp::getType(coenv &e)
+{
+ intExp ie(getPos(), (Int)s);
+ binaryExp be(getPos(), arg, op, &ie);
+ return be.cgetType(e);
+}
+
+void assignExp::prettyprint(ostream &out, Int indent)
+{
+ prettyname(out, "assignExp",indent);
+
+ dest->prettyprint(out, indent+1);
+ value->prettyprint(out, indent+1);
+}
+
+void assignExp::transAsType(coenv &e, types::ty *target)
+{
+ // For left-to-right order, we have to evaluate the side-effects of the
+ // destination first.
+ exp *temp=dest->evaluate(e, target);
+ ultimateValue(temp)->transToType(e, target);
+ temp->transWrite(e, target);
+}
+
+types::ty *assignExp::trans(coenv &e)
+{
+ exp *uvalue=ultimateValue(dest);
+ types::ty *lt = dest->cgetType(e), *rt = uvalue->cgetType(e);
+
+ if (lt->kind == ty_error)
+ return dest->trans(e);
+ if (rt->kind == ty_error)
+ return uvalue->trans(e);
+
+ types::ty *t = e.e.castTarget(lt, rt, symbol::castsym);
+ if (!t) {
+ em.error(getPos());
+ em << "cannot convert '" << *rt << "' to '" << *lt << "' in assignment";
+ return primError();
+ }
+ else if (t->kind == ty_overloaded) {
+ em.error(getPos());
+ em << "assignment is ambiguous";
+ return primError();
+ }
+ else {
+ transAsType(e, t);
+ return t;
+ }
+}
+
+types::ty *assignExp::getType(coenv &e)
+{
+ types::ty *lt = dest->cgetType(e), *rt = ultimateValue(dest)->cgetType(e);
+ if (lt->kind==ty_error || rt->kind==ty_error)
+ return primError();
+ types::ty *t = e.e.castTarget(lt, rt, symbol::castsym);
+
+ return t ? t : primError();
+}
+
+
+void selfExp::prettyprint(ostream &out, Int indent)
+{
+ prettyindent(out, indent);
+ out << "selfExp '" << *op << "'\n";
+
+ dest->prettyprint(out, indent+1);
+ value->prettyprint(out, indent+1);
+}
+
+
+void prefixExp::prettyprint(ostream &out, Int indent)
+{
+ prettyindent(out, indent);
+ out << "prefixExp '" << *op << "'\n";
+
+ dest->prettyprint(out, indent+1);
+}
+
+types::ty *prefixExp::trans(coenv &e)
+{
+ // Convert into the operation and the assign.
+ // NOTE: This can cause multiple evaluations.
+ intExp ie(getPos(), 1);
+ selfExp se(getPos(), dest, op, &ie);
+
+ return se.trans(e);
+}
+
+types::ty *prefixExp::getType(coenv &e)
+{
+ // Convert into the operation and the assign.
+ intExp ie(getPos(), 1);
+ selfExp se(getPos(), dest, op, &ie);
+
+ return se.getType(e);
+}
+
+void postfixExp::prettyprint(ostream &out, Int indent)
+{
+ prettyindent(out, indent);
+ out << "postfixExp <illegal>";
+ out << "postfixExp <illegal> '" << *op << "'\n";
+
+ dest->prettyprint(out, indent+1);
+}
+
+types::ty *postfixExp::trans(coenv &)
+{
+ em.error(getPos());
+ em << "postfix expressions are not allowed";
+ return primError();
+}
+
+
+} // namespace absyntax
+
diff --git a/Build/source/utils/asymptote/exp.h b/Build/source/utils/asymptote/exp.h
new file mode 100644
index 00000000000..ad6cd3afa3b
--- /dev/null
+++ b/Build/source/utils/asymptote/exp.h
@@ -0,0 +1,966 @@
+/*****
+ * exp.h
+ * Andy Hammerlindl 2002/8/19
+ *
+ * Represents the abstract syntax tree for the expressions in the
+ * language. this is translated into virtual machine code using trans()
+ * and with the aid of the environment class.
+ *****/
+
+#ifndef EXP_H
+#define EXP_H
+
+#include "types.h"
+#include "symbol.h"
+#include "absyn.h"
+#include "varinit.h"
+#include "name.h"
+#include "guideflags.h"
+
+namespace trans {
+class coenv;
+class application;
+}
+
+namespace absyntax {
+
+using trans::coenv;
+using trans::application;
+using trans::access;
+using sym::symbol;
+using types::record;
+using types::array;
+
+class exp : public varinit {
+protected:
+ // The cached type (from a call to cgetType).
+ types::ty *ct;
+public:
+ exp(position pos)
+ : varinit(pos), ct(0) {}
+
+ void prettyprint(ostream &out, Int indent);
+
+ // When reporting errors with function calls, it is nice to say "no
+ // function f(int)" instead of "no function matching signature
+ // (int)." Hence, this method returns the name of the expression if
+ // there is one.
+ virtual symbol *getName()
+ {
+ return 0;
+ }
+
+ // Checks if the expression can be used as the right side of a scale
+ // expression. ie. 3sin(x)
+ // If a "non-scalable" expression is scaled a warning is issued.
+ virtual bool scalable() { return true; }
+
+ // Specifies if the value of the expression should be written to interactive
+ // prompt if typed as a stand-alone expression. For example:
+ // > 2+3;
+ // should write 5, but
+ // > x=2+3;
+ // shouldn't. (These choices are largely aesthetic)
+ virtual bool writtenToPrompt() { return true; }
+
+ // Translates the expression to the given target type. This should only be
+ // called with a type returned by getType(). It does not perform implicit
+ // casting.
+ virtual void transAsType(coenv &e, types::ty *target);
+
+ // Translates the expression to the given target type, possibly using an
+ // implicit cast.
+ void transToType(coenv &e, types::ty *target);
+
+ // Translates the expression and returns the resultant type.
+ // For some expressions, this will be ambiguous and return an error.
+ // Trans may only return ty_error, if it (or one of its recursively
+ // called children in the syntax tree) reported an error to em.
+ virtual types::ty *trans(coenv &) = 0;
+
+ // getType() figures out the type of the expression without translating
+ // the code into the virtual machine language or reporting errors to em.
+ // This must follow a few rules to ensure proper translation:
+ // 1. If this returns a valid type, t, trans(e) must return t or
+ // report an error, and transToType(e, t) must run either reporting
+ // an error or reporting no error and yielding the same result as
+ // trans(e).
+ // 2. If this returns a superposition of types (ie. for overloaded
+ // functions), trans must not return a singular type, and every
+ // type in the superposition must run without error properly
+ // if fed to transAsType(e, t).
+ // 3. If this returns ty_error, then so must a call to trans(e) and any
+ // call to trans, transAsType, or transToType must report an error
+ // to em.
+ // 4. Any call to transAsType(e, t) with a type that is not returned by
+ // getType() (or one of the subtypes in case of a superposition)
+ // must report an error.
+ // Any call to transToType(e, t) with a type that is not returned by
+ // getType() (or one of the subtypes in case of a superposition)
+ // or any type not implicitly castable from the above must report an
+ // error.
+ virtual types::ty *getType(coenv &) = 0;
+
+ // Same result as getType, but caches the result so that subsequent
+ // calls are faster. For this to work correctly, the expression should
+ // only be used in one place, so the environment doesn't change between
+ // calls.
+ virtual types::ty *cgetType(coenv &e) {
+#ifdef DEBUG_CACHE
+ testCachedType(e);
+#endif
+ return ct ? ct : ct = getType(e);
+ }
+
+ void testCachedType(coenv &e);
+
+ // The expression is being used as an address to write to. This writes code
+ // so that the value on top of stack is put into the address (but not popped
+ // off the stack).
+ virtual void transWrite(coenv &, types::ty *) {
+ em.error(getPos());
+ em << "expression cannot be used as an address";
+ }
+
+ // Translates code for calling a function. The arguments, in the order they
+ // appear in the function's signature, must all be on the stack.
+ virtual void transCall(coenv &e, types::ty *target);
+
+ // This is used to ensure the proper order and number of evaluations. When
+ // called, it immediately translates code to perform the side-effects
+ // consistent with a corresponding call to transAsType(e, target).
+ //
+ // The return value, called an evaluation for lack of a better name, is
+ // another expression that responds to the trans methods exactly as would the
+ // original expression, but without producing side-effects. It is also no
+ // longer overloaded, due to the resolution effected by giving a target type
+ // to evaluate().
+ //
+ // The methods transAsType, transWrite, and transCall of the evaluation must
+ // be called with the same target type as the original call to evaluate.
+ // When evaluate() is called during the translation of a function, that
+ // function must still be in translation when the evaluation is translated.
+ //
+ // The base implementation uses a tempExp (see below). This is
+ // sufficient for most expressions.
+ virtual exp *evaluate(coenv &e, types::ty *target);
+
+ // NOTE: could add a "side-effects" method which says if the expression has
+ // side-effects. This might allow some small optimizations in translating.
+};
+
+class tempExp : public exp {
+ access *a;
+ types::ty *t;
+
+public:
+ tempExp(coenv &e, varinit *v, types::ty *t);
+
+ types::ty *trans(coenv &e);
+
+ types::ty *getType(coenv &) {
+ return t;
+ }
+};
+
+// Wrap a varEntry so that it can be used as an expression.
+class varEntryExp : public exp {
+ trans::varEntry *v;
+public:
+ varEntryExp(position pos, trans::varEntry *v)
+ : exp(pos), v(v) {}
+ varEntryExp(position pos, types::ty *t, access *a);
+ varEntryExp(position pos, types::ty *t, vm::bltin f);
+
+ types::ty *getType(coenv &);
+ types::ty *trans(coenv &e);
+
+ void transAct(action act, coenv &e, types::ty *target);
+ void transAsType(coenv &e, types::ty *target);
+ void transWrite(coenv &e, types::ty *target);
+ void transCall(coenv &e, types::ty *target);
+};
+
+class nameExp : public exp {
+ name *value;
+
+public:
+ nameExp(position pos, name *value)
+ : exp(pos), value(value) {}
+
+ nameExp(position pos, symbol *id)
+ : exp(pos), value(new simpleName(pos, id)) {}
+
+ void prettyprint(ostream &out, Int indent);
+
+ symbol *getName()
+ {
+ return value->getName();
+ }
+
+ void transAsType(coenv &e, types::ty *target) {
+ value->varTrans(trans::READ, e, target);
+
+ // After translation, the cached type is no longer needed and should be
+ // garbage collected. This could presumably be done in every class derived
+ // from exp, but here it is most important as nameExp can have heavily
+ // overloaded types cached.
+ ct=0;
+ }
+
+ types::ty *trans(coenv &e) {
+ types::ty *t=cgetType(e);
+ if (t->kind == types::ty_error) {
+ em.error(getPos());
+ em << "no matching variable \'" << *value << "\'";
+ return types::primError();
+ }
+ if (t->kind == types::ty_overloaded) {
+ em.error(getPos());
+ em << "use of variable \'" << *value << "\' is ambiguous";
+ return types::primError();
+ }
+ else {
+ transAsType(e, t);
+ return t;
+ }
+ }
+
+ types::ty *getType(coenv &e) {
+ types::ty *t=value->varGetType(e);
+ return t ? t : types::primError();
+ }
+
+ void transWrite(coenv &e, types::ty *target) {
+ value->varTrans(trans::WRITE, e, target);
+
+ ct=0; // See note in transAsType.
+ }
+
+ void transCall(coenv &e, types::ty *target) {
+ value->varTrans(trans::CALL, e, target);
+
+ ct=0; // See note in transAsType.
+ }
+
+ exp *evaluate(coenv &, types::ty *) {
+ // Names have no side-effects.
+ return this;
+ }
+};
+
+// Most fields accessed are handled as parts of qualified names, but in cases
+// like f().x or (new t).x, a separate expression is needed.
+class fieldExp : public nameExp {
+ exp *object;
+ symbol *field;
+
+ // fieldExp has a lot of common functionality with qualifiedName, so we
+ // essentially hack qualifiedName, by making our object expression look
+ // like a name.
+ class pseudoName : public name {
+ exp *object;
+
+ public:
+ pseudoName(exp *object)
+ : name(object->getPos()), object(object) {}
+
+ // As a variable:
+ void varTrans(trans::action act, coenv &e, types::ty *target) {
+ assert(act == trans::READ);
+ object->transToType(e, target);
+ }
+ types::ty *varGetType(coenv &e) {
+ return object->getType(e);
+ }
+
+ // As a type:
+ types::ty *typeTrans(coenv &, bool tacit = false) {
+ if (!tacit) {
+ em.error(getPos());
+ em << "expression is not a type";
+ }
+ return types::primError();
+ }
+
+ trans::varEntry *getVarEntry(coenv &) {
+ em.compiler(getPos());
+ em << "expression cannot be used as part of a type";
+ return 0;
+ }
+
+ trans::tyEntry *tyEntryTrans(coenv &) {
+ em.compiler(getPos());
+ em << "expression cannot be used as part of a type";
+ return 0;
+ }
+
+ trans::frame *tyFrameTrans(coenv &) {
+ return 0;
+ }
+
+ void prettyprint(ostream &out, Int indent);
+ void print(ostream& out) const {
+ out << "<exp>";
+ }
+ symbol *getName() {
+ return object->getName();
+ }
+ };
+
+ // Try to get this into qualifiedName somehow.
+ types::ty *getObject(coenv &e);
+
+public:
+ fieldExp(position pos, exp *object, symbol *field)
+ : nameExp(pos, new qualifiedName(pos,
+ new pseudoName(object),
+ field)),
+ object(object), field(field) {}
+
+ void prettyprint(ostream &out, Int indent);
+
+ symbol *getName()
+ {
+ return field;
+ }
+
+ exp *evaluate(coenv &e, types::ty *) {
+ // Evaluate the object.
+ return new fieldExp(getPos(),
+ new tempExp(e, object, getObject(e)),
+ field);
+ }
+};
+
+class arrayExp : public exp {
+protected:
+ exp *set;
+
+ array *getArrayType(coenv &e);
+ array *transArray(coenv &e);
+
+public:
+ arrayExp(position pos, exp *set)
+ : exp(pos), set(set) {}
+};
+
+
+class subscriptExp : public arrayExp {
+ exp *index;
+
+public:
+ subscriptExp(position pos, exp *set, exp *index)
+ : arrayExp(pos, set), index(index) {}
+
+ void prettyprint(ostream &out, Int indent);
+
+ types::ty *trans(coenv &e);
+ types::ty *getType(coenv &e);
+ void transWrite(coenv &e, types::ty *target);
+
+ exp *evaluate(coenv &e, types::ty *) {
+ return new subscriptExp(getPos(),
+ new tempExp(e, set, getArrayType(e)),
+ new tempExp(e, index, types::primInt()));
+ }
+};
+
+class slice : public absyn {
+ exp *left;
+ exp *right;
+
+public:
+ slice(position pos, exp *left, exp *right)
+ : absyn(pos), left(left), right(right) {}
+
+ void prettyprint(ostream &out, Int indent);
+
+ exp *getLeft() { return left; }
+ exp *getRight() { return right; }
+
+ // Translates code to put the left and right expressions on the stack (in that
+ // order). If left is omitted, zero is pushed on the stack in it's place. If
+ // right is omitted, nothing is pushed in its place.
+ void trans(coenv &e);
+
+ slice *evaluate(coenv &e) {
+ return new slice(getPos(),
+ left ? new tempExp(e, left, types::primInt()) : 0,
+ right ? new tempExp(e, right, types::primInt()) : 0);
+ }
+};
+
+class sliceExp : public arrayExp {
+ slice *index;
+
+public:
+ sliceExp(position pos, exp *set, slice *index)
+ : arrayExp(pos, set), index(index) {}
+
+ void prettyprint(ostream &out, Int indent);
+
+ types::ty *trans(coenv &e);
+ types::ty *getType(coenv &e);
+ void transWrite(coenv &e, types::ty *target);
+
+ exp *evaluate(coenv &e, types::ty *) {
+ return new sliceExp(getPos(),
+ new tempExp(e, set, getArrayType(e)),
+ index->evaluate(e));
+ }
+};
+
+
+// The expression "this," that evaluates to the lexically enclosing record.
+class thisExp : public exp {
+public:
+ thisExp(position pos)
+ : exp(pos) {}
+
+ void prettyprint(ostream &out, Int indent);
+
+ types::ty *trans(coenv &e);
+ types::ty *getType(coenv &e);
+};
+
+class literalExp : public exp {
+public:
+ literalExp(position pos)
+ : exp(pos) {}
+
+ bool scalable() { return false; }
+};
+
+class intExp : public literalExp {
+ Int value;
+
+public:
+ intExp(position pos, Int value)
+ : literalExp(pos), value(value) {}
+
+ void prettyprint(ostream &out, Int indent);
+
+ types::ty *trans(coenv &e);
+ types::ty *getType(coenv &) { return types::primInt(); }
+};
+
+class realExp : public literalExp {
+protected:
+ double value;
+
+public:
+ realExp(position pos, double value)
+ : literalExp(pos), value(value) {}
+
+ void prettyprint(ostream &out, Int indent);
+
+ types::ty *trans(coenv &e);
+ types::ty *getType(coenv &) { return types::primReal(); }
+};
+
+
+class stringExp : public literalExp {
+ string str;
+
+public:
+ stringExp(position pos, string str)
+ : literalExp(pos), str(str) {}
+
+ void prettyprint(ostream &out, Int indent);
+
+ types::ty *trans(coenv &e);
+ types::ty *getType(coenv &) { return types::primString(); }
+};
+
+class booleanExp : public literalExp {
+ bool value;
+
+public:
+ booleanExp(position pos, bool value)
+ : literalExp(pos), value(value) {}
+
+ void prettyprint(ostream &out, Int indent);
+
+ types::ty *trans(coenv &e);
+ types::ty *getType(coenv &) { return types::primBoolean(); }
+};
+
+class cycleExp : public literalExp {
+
+public:
+ cycleExp(position pos)
+ : literalExp(pos) {}
+
+ void prettyprint(ostream &out, Int indent);
+
+ types::ty *trans(coenv &e);
+ types::ty *getType(coenv &) { return types::primCycleToken(); }
+};
+
+class newPictureExp : public literalExp {
+
+public:
+ newPictureExp(position pos)
+ : literalExp(pos) {}
+
+ void prettyprint(ostream &out, Int indent);
+
+ types::ty *trans(coenv &e);
+ types::ty *getType(coenv &) { return types::primPicture(); }
+};
+
+class nullPathExp : public literalExp {
+
+public:
+ nullPathExp(position pos)
+ : literalExp(pos) {}
+
+ void prettyprint(ostream &out, Int indent);
+
+ types::ty *trans(coenv &e);
+ types::ty *getType(coenv &) { return types::primPath(); }
+};
+
+class nullExp : public literalExp {
+
+public:
+ nullExp(position pos)
+ : literalExp(pos) {}
+
+ void prettyprint(ostream &out, Int indent);
+
+ types::ty *trans(coenv &e);
+ types::ty *getType(coenv &) { return types::primNull(); }
+};
+
+class quoteExp : public exp {
+ runnable *value;
+
+public:
+ quoteExp(position pos, runnable *value)
+ : exp(pos), value(value) {}
+
+ void prettyprint(ostream &out, Int indent);
+
+ types::ty *trans(coenv &e);
+ types::ty *getType(coenv &) { return types::primCode(); }
+};
+
+// A list of expressions used in a function call.
+class explist : public absyn {
+ typedef mem::vector<exp *> expvector;
+ expvector exps;
+
+public:
+ explist(position pos)
+ : absyn(pos) {}
+
+ virtual ~explist() {}
+
+ virtual void add(exp *e) {
+ exps.push_back(e);
+ }
+
+ virtual void prettyprint(ostream &out, Int indent);
+
+ virtual size_t size() {
+ return exps.size();
+ }
+
+ virtual exp * operator[] (size_t index) {
+ return exps[index];
+ }
+};
+
+struct argument {
+ exp *val;
+ symbol *name;
+
+#if 0
+ argument(exp *val=0, symbol *name=0)
+ : val(val), name(name) {}
+#endif
+
+ void prettyprint(ostream &out, Int indent);
+};
+
+class arglist : public gc {
+public:
+ typedef mem::vector<argument> argvector;
+ argvector args;
+ argument rest;
+
+ arglist()
+ : args(), rest() {}
+
+ virtual ~arglist() {}
+
+ virtual void addFront(argument a) {
+ args.insert(args.begin(), a);
+ }
+
+ virtual void addFront(exp *val, symbol *name=0) {
+ argument a; a.val=val; a.name=name;
+ addFront(a);
+ }
+
+ virtual void add(argument a) {
+ args.push_back(a);
+ }
+
+ virtual void add(exp *val, symbol *name=0) {
+ argument a; a.val=val; a.name=name;
+ add(a);
+ }
+
+ virtual void prettyprint(ostream &out, Int indent);
+
+ virtual size_t size() {
+ return args.size();
+ }
+
+ virtual argument operator[] (size_t index) {
+ return args[index];
+ }
+
+ virtual argument getRest() {
+ return rest;
+ }
+};
+
+// callExp has a global cache of resolved overloaded functions. This clears
+// this cache so the associated data can be garbage collected.
+void clearCachedCalls();
+
+class callExp : public exp {
+protected:
+ exp *callee;
+ arglist *args;
+
+private:
+ // Per object caching - Cache the application when it's determined.
+ application *ca;
+
+ types::signature *argTypes(coenv& e);
+ void reportArgErrors(coenv &e);
+ application *resolve(coenv &e,
+ types::overloaded *o,
+ types::signature *source,
+ bool tacit);
+ application *resolveWithCache(coenv &e,
+ types::overloaded *o,
+ types::signature *source,
+ bool tacit);
+ void reportMismatch(symbol *s,
+ types::function *ft,
+ types::signature *source);
+ application *getApplication(coenv &e);
+
+public:
+ callExp(position pos, exp *callee, arglist *args)
+ : exp(pos), callee(callee), args(args), ca(0) { assert(args); }
+
+ callExp(position pos, exp *callee)
+ : exp(pos), callee(callee), args(new arglist()), ca(0) {}
+
+ callExp(position pos, exp *callee, exp *arg1)
+ : exp(pos), callee(callee), args(new arglist()), ca(0) {
+ args->add(arg1);
+ }
+
+ callExp(position pos, exp *callee, exp *arg1, exp *arg2)
+ : exp(pos), callee(callee), args(new arglist()), ca(0) {
+ args->add(arg1);
+ args->add(arg2);
+ }
+
+ callExp(position pos, exp *callee, exp *arg1, exp *arg2, exp *arg3)
+ : exp(pos), callee(callee), args(new arglist()), ca(0) {
+ args->add(arg1);
+ args->add(arg2);
+ args->add(arg3);
+ }
+
+ void prettyprint(ostream &out, Int indent);
+
+ types::ty *trans(coenv &e);
+ types::ty *getType(coenv &e);
+};
+
+class pairExp : public exp {
+ exp *x;
+ exp *y;
+
+public:
+ pairExp(position pos, exp *x, exp *y)
+ : exp(pos), x(x), y(y) {}
+
+ void prettyprint(ostream &out, Int indent);
+
+ types::ty *trans(coenv &e);
+ types::ty *getType(coenv &) { return types::primPair(); }
+};
+
+class tripleExp : public exp {
+ exp *x;
+ exp *y;
+ exp *z;
+
+public:
+ tripleExp(position pos, exp *x, exp *y, exp *z)
+ : exp(pos), x(x), y(y), z(z) {}
+
+ void prettyprint(ostream &out, Int indent);
+
+ types::ty *trans(coenv &e);
+ types::ty *getType(coenv &) { return types::primTriple(); }
+};
+
+class transformExp : public exp {
+ exp *x;
+ exp *y;
+ exp *xx,*xy,*yx,*yy;
+
+public:
+ transformExp(position pos, exp *x, exp *y, exp *xx, exp *xy, exp *yx,
+ exp *yy)
+ : exp(pos), x(x), y(y), xx(xx), xy(xy), yx(yx), yy(yy) {}
+
+ void prettyprint(ostream &out, Int indent);
+
+ types::ty *trans(coenv &e);
+ types::ty *getType(coenv &) { return types::primTransform(); }
+};
+
+class castExp : public exp {
+ ty *target;
+ exp *castee;
+
+ types::ty *tryCast(coenv &e, types::ty *t, types::ty *s,
+ symbol *csym);
+public:
+ castExp(position pos, ty *target, exp *castee)
+ : exp(pos), target(target), castee(castee) {}
+
+ void prettyprint(ostream &out, Int indent);
+
+ types::ty *trans(coenv &e);
+ types::ty *getType(coenv &e);
+};
+
+class nullaryExp : public callExp {
+public:
+ nullaryExp(position pos, symbol *op)
+ : callExp(pos, new nameExp(pos, op)) {}
+};
+
+class unaryExp : public callExp {
+public:
+ unaryExp(position pos, exp *base, symbol *op)
+ : callExp(pos, new nameExp(pos, op), base) {}
+};
+
+class binaryExp : public callExp {
+public:
+ binaryExp(position pos, exp *left, symbol *op, exp *right)
+ : callExp(pos, new nameExp(pos, op), left, right) {}
+};
+
+// Scaling expressions such as 3sin(x).
+class scaleExp : public binaryExp {
+ exp *getLeft() {
+ return (*this->args)[0].val;
+ }
+ exp *getRight() {
+ return (*this->args)[1].val;
+ }
+public:
+ scaleExp(position pos, exp *left, exp *right)
+ : binaryExp(pos, left, symbol::trans("*"), right) {}
+
+ void prettyprint(ostream &out, Int indent);
+
+ types::ty *trans(coenv &e);
+ //types::ty *getType(coenv &e);
+
+ bool scalable() { return false; }
+};
+
+// Used for tension, which takes two real values, and a boolean to denote if it
+// is a tension atleast case.
+class ternaryExp : public callExp {
+public:
+ ternaryExp(position pos, exp *left, symbol *op, exp *right, exp *last)
+ : callExp(pos, new nameExp(pos, op), left, right, last) {}
+};
+
+// The a ? b : c ternary operator.
+class conditionalExp : public exp {
+ exp *test;
+ exp *onTrue;
+ exp *onFalse;
+
+public:
+ conditionalExp(position pos, exp *test, exp *onTrue, exp *onFalse)
+ : exp(pos), test(test), onTrue(onTrue), onFalse(onFalse) {}
+
+ void prettyprint(ostream &out, Int indent);
+
+ void baseTransToType(coenv &e, types::ty *target);
+
+ void transToType(coenv &e, types::ty *target);
+ types::ty *trans(coenv &e);
+ types::ty *getType(coenv &e);
+
+};
+
+class andOrExp : public exp {
+protected:
+ exp *left;
+ symbol *op;
+ exp *right;
+
+public:
+ andOrExp(position pos, exp *left, symbol *op, exp *right)
+ : exp(pos), left(left), op(op), right(right) {}
+
+ virtual types::ty *trans(coenv &e) = 0;
+ virtual types::ty *getType(coenv &) {
+ return types::primBoolean();
+ }
+};
+
+class orExp : public andOrExp {
+public:
+ orExp(position pos, exp *left, symbol *op, exp *right)
+ : andOrExp(pos, left, op, right) {}
+
+ void prettyprint(ostream &out, Int indent);
+
+ types::ty *trans(coenv &e);
+};
+
+class andExp : public andOrExp {
+public:
+ andExp(position pos, exp *left, symbol *op, exp *right)
+ : andOrExp(pos, left, op, right) {}
+
+ void prettyprint(ostream &out, Int indent);
+
+ types::ty *trans(coenv &e);
+};
+
+class joinExp : public callExp {
+public:
+ joinExp(position pos, symbol *op)
+ : callExp(pos, new nameExp(pos, op)) {}
+
+ void pushFront(exp *e) {
+ args->addFront(e);
+ }
+ void pushBack(exp *e) {
+ args->add(e);
+ }
+
+ void prettyprint(ostream &out, Int indent);
+};
+
+class specExp : public exp {
+ symbol *op;
+ exp *arg;
+ camp::side s;
+
+public:
+ specExp(position pos, symbol *op, exp *arg, camp::side s=camp::OUT)
+ : exp(pos), op(op), arg(arg), s(s) {}
+
+ void setSide(camp::side ss) {
+ s=ss;
+ }
+
+ void prettyprint(ostream &out, Int indent);
+
+ types::ty *trans(coenv &e);
+ types::ty *getType(coenv &e);
+};
+
+class assignExp : public exp {
+protected:
+ exp *dest;
+ exp *value;
+
+ // This is basically a hook to facilitate selfExp. dest is given as an
+ // argument since it will be a temporary in translation in order to avoid
+ // multiple evaluation.
+ virtual exp *ultimateValue(exp *) {
+ return value;
+ }
+
+public:
+ assignExp(position pos, exp *dest, exp *value)
+ : exp(pos), dest(dest), value(value) {}
+
+ void prettyprint(ostream &out, Int indent);
+
+ // Don't write the result of an assignment to the prompt.
+ bool writtenToPrompt() { return false; }
+
+ void transAsType(coenv &e, types::ty *target);
+ types::ty *trans(coenv &e);
+ types::ty *getType(coenv &e);
+};
+
+class selfExp : public assignExp {
+ symbol *op;
+
+ exp *ultimateValue(exp *dest) {
+ return new binaryExp(getPos(), dest, op, value);
+ }
+
+public:
+ selfExp(position pos, exp *dest, symbol *op, exp *value)
+ : assignExp(pos, dest, value), op(op) {}
+
+ void prettyprint(ostream &out, Int indent);
+};
+
+class prefixExp : public exp {
+ exp *dest;
+ symbol *op;
+
+public:
+ prefixExp(position pos, exp *dest, symbol *op)
+ : exp(pos), dest(dest), op(op) {}
+
+ void prettyprint(ostream &out, Int indent);
+
+ bool scalable() { return false; }
+
+ // Don't write the result to the prompt.
+ bool writtenToPrompt() { return false; }
+
+ types::ty *trans(coenv &e);
+ types::ty *getType(coenv &e);
+};
+
+// Postfix expresions are illegal. This is caught here as we can give a
+// more meaningful error message to the user, rather than a "parse
+// error."
+class postfixExp : public exp {
+ exp *dest;
+ symbol *op;
+
+public:
+ postfixExp(position pos, exp *dest, symbol *op)
+ : exp(pos), dest(dest), op(op) {}
+
+ void prettyprint(ostream &out, Int indent);
+
+ types::ty *trans(coenv &e);
+ types::ty *getType(coenv &) { return types::primError(); }
+};
+
+} // namespace absyntax
+
+#endif
diff --git a/Build/source/utils/asymptote/fftw++.cc b/Build/source/utils/asymptote/fftw++.cc
new file mode 100644
index 00000000000..df4ecaeb4c4
--- /dev/null
+++ b/Build/source/utils/asymptote/fftw++.cc
@@ -0,0 +1,16 @@
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#ifdef HAVE_LIBFFTW3
+#include "fftw++.h"
+
+std::ifstream fftw::ifWisdom;
+std::ofstream fftw::ofWisdom;
+bool fftw::Wise=false;
+
+// User settings:
+unsigned int fftw::effort=FFTW_PATIENT;
+const char *fftw::WisdomName=".wisdom";
+
+#endif
diff --git a/Build/source/utils/asymptote/fftw++.h b/Build/source/utils/asymptote/fftw++.h
new file mode 100644
index 00000000000..e3cb3d2b2f2
--- /dev/null
+++ b/Build/source/utils/asymptote/fftw++.h
@@ -0,0 +1,909 @@
+/* Fast Fourier transform C++ header class for the FFTW3 Library
+ Copyright (C) 2004 John C. Bowman, University of Alberta
+
+ This program 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 3 of the License, or
+ (at your option) any later version.
+
+ This program 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 program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#ifndef __fftwpp_h__
+#define __fftwpp_h__ 1
+
+#define __FFTWPP_H_VERSION__ 1.03
+
+#include <cstdlib>
+#include <fstream>
+#include <iostream>
+#include <fftw3.h>
+
+#ifndef __Complex_h__
+#include <complex>
+typedef std::complex<double> Complex;
+#endif
+
+#ifdef __Array_h__
+using Array::array1;
+using Array::array2;
+using Array::array3;
+
+static array1<Complex> NULL1;
+static array2<Complex> NULL2;
+static array3<Complex> NULL3;
+#endif
+
+inline Complex *FFTWComplex(size_t size)
+{
+ static const size_t offset = sizeof(size_t)/sizeof(Complex)+
+ (sizeof(size_t) % sizeof(Complex) > 0);
+ void *alloc=fftw_malloc((size+offset)*sizeof(Complex));
+ if(size && !alloc) std::cerr << std::endl << "Memory limits exceeded"
+ << std::endl;
+ *(size_t *) alloc=size;
+ Complex*p=(Complex *)alloc+offset;
+ for(size_t i=0; i < size; i++) new(p+i) Complex;
+ return p;
+}
+
+inline double *FFTWdouble(size_t size)
+{
+ static const size_t offset = sizeof(size_t)/sizeof(Complex)+
+ (sizeof(size_t) % sizeof(Complex) > 0);
+ void *alloc=fftw_malloc(size*sizeof(double)+offset*sizeof(Complex));
+ if(size && !alloc) std::cerr << std::endl << "Memory limits exceeded"
+ << std::endl;
+ *(size_t *) alloc=size;
+ double*p=(double*)((Complex *)alloc+offset);
+ for(size_t i=0; i < size; i++) new(p+i) double;
+ return p;
+}
+
+template<class T>
+inline void FFTWdelete(T *p)
+{
+ static const size_t offset = sizeof(size_t)/sizeof(Complex)+
+ (sizeof(size_t) % sizeof(Complex) > 0);
+ void *alloc=(Complex *)p-offset;
+ size_t size=*(size_t *) alloc;
+ for(size_t i=size-1; i > 0; i--) ((T *) p)[i].~T();
+ ((T *) p)[0].~T();
+ fftw_free(alloc);
+}
+
+inline void fftw_export_wisdom(void (*emitter)(char c, std::ofstream& s),
+ std::ofstream& s)
+{
+ fftw_export_wisdom((void (*) (char, void *)) emitter,(void *) &s);
+}
+
+inline int fftw_import_wisdom(int (*g)(std::ifstream& s), std::ifstream &s)
+{
+ return fftw_import_wisdom((int (*) (void *)) g,(void *) &s);
+}
+
+inline void PutWisdom(char c, std::ofstream& s) {s.put(c);}
+inline int GetWisdom(std::ifstream& s) {return s.get();}
+
+// Base clase for fft routines
+//
+class fftw {
+protected:
+ unsigned int size;
+ int sign;
+ double norm;
+ bool shift;
+
+ bool inplace;
+ fftw_plan plan;
+
+ static unsigned int effort;
+ static bool Wise;
+ static const char *WisdomName;
+ static std::ifstream ifWisdom;
+ static std::ofstream ofWisdom;
+
+ unsigned int Dist(unsigned int n, unsigned int stride, unsigned int dist) {
+ return dist ? dist : ((stride == 1) ? n : 1);
+ }
+
+ unsigned int realsize(unsigned int n, Complex *in, Complex *out) {
+ return n/2+(!out || in == out);
+ }
+
+ unsigned int realsize(unsigned int n, Complex *in, double *out) {
+ return realsize(n,in,(Complex *) out);
+ }
+
+ // Shift the Fourier origin to (nx/2,0)
+ void Shift(Complex *data, unsigned int nx, unsigned int ny) {
+ const unsigned int nyp=ny/2+1;
+ Complex *pstop=data+nx*nyp;
+ int pinc=2*nyp;
+ for(Complex *p=data+nyp; p < pstop; p += pinc) {
+ //#pragma ivdep
+ for(unsigned int j=0; j < nyp; j++) p[j]=-p[j];
+ }
+ }
+
+ // Shift the Fourier origin to (nx/2,ny/2,0)
+ void Shift(Complex *data, unsigned int nx, unsigned int ny,
+ unsigned int nz) {
+ const unsigned int nzp=nz/2+1;
+ const unsigned int nyzp=ny*nzp;
+ const unsigned int pinc=2*nzp;
+ Complex *p,*pstop;
+ p=pstop=data;
+ for(unsigned i=0; i < nx; i++) {
+ if(i % 2) p -= nzp;
+ else p += nzp;
+ pstop += nyzp;
+ for(; p < pstop; p += pinc) {
+ //#pragma ivdep
+ for(unsigned int k=0; k < nzp; k++) p[k]=-p[k];
+ }
+ }
+ }
+
+public:
+ fftw(unsigned int size, int sign, unsigned int n=0) :
+ size(size), sign(sign), norm(1.0/(n ? n : size)), shift(false) {}
+
+ virtual ~fftw() {}
+
+ virtual fftw_plan Plan(Complex *in, Complex *out)=0;
+
+ inline void CheckAlign(Complex *p, const char *s) {
+ if((size_t) p % sizeof(Complex) == 0) return;
+ std::cerr << "WARNING: " << s << " array is not " << sizeof(Complex)
+ << "-byte aligned: address " << p << std::endl;
+ }
+
+ void Setup(Complex *in, Complex *out=NULL) {
+ if(!Wise) LoadWisdom();
+ bool alloc=!in;
+ if(alloc) in=FFTWComplex(size);
+#ifndef NO_CHECK_ALIGN
+ CheckAlign(in,"constructor input");
+ if(out) CheckAlign(out,"constructor output");
+ else out=in;
+#else
+ if(!out) out=in;
+#endif
+ inplace=(out==in);
+ plan=Plan(in,out);
+ if(!plan) {
+ std::cerr << "Unable to construct FFTW plan" << std::endl;
+ exit(1);
+ }
+
+ if(alloc) FFTWdelete(in);
+ SaveWisdom();
+ }
+
+ void Setup(Complex *in, double *out) {Setup(in,(Complex *) out);}
+ void Setup(double *in, Complex *out) {Setup((Complex *) in,out);}
+
+ void LoadWisdom() {
+ ifWisdom.open(WisdomName);
+ fftw_import_wisdom(GetWisdom,ifWisdom);
+ ifWisdom.close();
+ Wise=true;
+ }
+
+ void SaveWisdom() {
+ ofWisdom.open(WisdomName);
+ fftw_export_wisdom(PutWisdom,ofWisdom);
+ ofWisdom.close();
+ }
+
+ virtual void Execute(Complex *in, Complex *out) {
+ fftw_execute_dft(plan,(fftw_complex *) in,(fftw_complex *) out);
+ }
+
+ void Setout(Complex *in, Complex *&out) {
+#ifndef NO_CHECK_ALIGN
+ CheckAlign(in,"input");
+ if(out) CheckAlign(out,"output");
+ else out=in;
+#else
+ if(!out) out=in;
+#endif
+ if(inplace ^ (out == in)) {
+ std::cerr << "ERROR: fft constructor and call must be either both in place or out of place" << std::endl;
+ exit(1);
+ }
+ }
+
+ void fft(Complex *in, Complex *out=NULL) {
+ Setout(in,out);
+ Execute(in,out);
+ }
+
+ void fft(double *in, Complex *out) {
+ fft((Complex *) in,out);
+ }
+
+ void fft(Complex *in, double *out) {
+ fft(in,(Complex *) out);
+ }
+
+ void fft0(Complex *in, Complex *out=NULL) {
+ Setout(in,out);
+ shift=true;
+ Execute(in,out);
+ shift=false;
+ }
+
+ void fft0(double *in, Complex *out) {
+ fft0((Complex *) in,out);
+ }
+
+ void fft0(Complex *in, double *out) {
+ fft0(in,(Complex *) out);
+ }
+
+ void Normalize(Complex *out) {
+ for(unsigned int i=0; i < size; i++) out[i] *= norm;
+ }
+
+ virtual void fftNormalized(Complex *in, Complex *out=NULL) {
+ Setout(in,out);
+ Execute(in,out);
+ Normalize(out);
+ }
+
+ void fftNormalized(Complex *in, double *out) {
+ fftNormalized(in,(Complex *) out);
+ }
+
+ void fftNormalized(double *in, Complex *out) {
+ fftNormalized((Complex *) in,out);
+ }
+
+ void fft0Normalized(Complex *in, Complex *out=NULL) {
+ Setout(in,out);
+ shift=true;
+ Execute(in,out);
+ shift=false;
+ Normalize(out);
+ }
+
+ void fft0Normalized(Complex *in, double *out) {
+ fft0Normalized(in,(Complex *) out);
+ }
+
+ void fft0Normalized(double *in, Complex *out) {
+ fft0Normalized((Complex *) in,out);
+ }
+
+ void fftNormalized(Complex *in, Complex *out,
+ unsigned int nx, unsigned int m,
+ unsigned int stride, unsigned int dist) {
+ if(stride == 1 && dist == nx) fftw::fftNormalized(in,out);
+ else if(stride == nx && dist == 1) fftw::fftNormalized(in,out);
+ else {
+ Setout(in,out);
+ Execute(in,out);
+ for(unsigned int k=0; k < m; k++) {
+ for(unsigned int j=0; j < nx; j++) {
+ out[j*stride+k*dist] *= norm;
+ }
+ }
+ }
+ }
+
+};
+
+// Compute the complex Fourier transform of n complex values.
+// Before calling fft(), the arrays in and out (which may coincide) must be
+// allocated as Complex[n].
+//
+// Out-of-place usage:
+//
+// fft1d Forward(n,-1,in,out);
+// Forward.fft(in,out);
+//
+// fft1d Backward(n,1,out,in);
+// Backward.fft(out,in);
+//
+// fft1d Backward(n,1,out,in);
+// Backward.fftNormalized(out,in); // True inverse of Forward.fft(in,out);
+//
+// In-place usage:
+//
+// fft1d Forward(n,-1);
+// Forward.fft(in);
+//
+// fft1d Backward(n,1);
+// Backward.fft(in);
+//
+class fft1d : public fftw {
+ unsigned int nx;
+public:
+ fft1d(unsigned int nx, int sign, Complex *in=NULL, Complex *out=NULL)
+ : fftw(nx,sign), nx(nx) {Setup(in,out);}
+
+#ifdef __Array_h__
+ fft1d(int sign, const array1<Complex>& in, const array1<Complex>& out=NULL1)
+ : fftw(in.Nx(),sign), nx(in.Nx()) {Setup(in,out);}
+#endif
+
+ fftw_plan Plan(Complex *in, Complex *out) {
+ return fftw_plan_dft_1d(nx,(fftw_complex *) in,(fftw_complex *) out,
+ sign,effort);
+ }
+};
+
+// Compute the complex Fourier transform of m complex vectors, each of
+// length n.
+// Before calling fft(), the arrays in and out (which may coincide) must be
+// allocated as Complex[m*n].
+//
+// Out-of-place usage:
+//
+// mfft1d Forward(n,-1,m,stride,dist,in,out);
+// Forward.fft(in,out);
+//
+// In-place usage:
+//
+// mfft1d Forward(n,-1,m,stride,dist);
+// Forward.fft(in);
+//
+// Notes:
+// stride is the spacing between the elements of each Complex vector;
+// dist is the spacing between the first elements of the vectors;
+//
+//
+class mfft1d : public fftw {
+ unsigned int nx;
+ unsigned int m;
+ unsigned int stride;
+ unsigned int dist;
+public:
+ mfft1d(unsigned int nx, int sign, unsigned int m=1, unsigned int stride=1,
+ unsigned int dist=0, Complex *in=NULL, Complex *out=NULL)
+ : fftw((nx-1)*stride+(m-1)*Dist(nx,stride,dist)+1,sign,nx),
+ nx(nx), m(m), stride(stride), dist(Dist(nx,stride,dist))
+ {Setup(in,out);}
+
+ fftw_plan Plan(Complex *in, Complex *out) {
+ int n[1]={nx};
+ return fftw_plan_many_dft(1,n,m,
+ (fftw_complex *) in,NULL,stride,dist,
+ (fftw_complex *) out,NULL,stride,dist,
+ sign,effort);
+ }
+
+ void fftNormalized(Complex *in, Complex *out=NULL) {
+ fftw::fftNormalized(in,out,nx,m,stride,dist);
+ }
+};
+
+// Compute the complex Fourier transform of n real values, using phase sign -1.
+// Before calling fft(), the array in must be allocated as double[n] and
+// the array out must be allocated as Complex[n/2+1]. The arrays in and out
+// may coincide, in which case they must both be allocated as Complex[n/2+1].
+//
+// Out-of-place usage:
+//
+// rcfft1d Forward(n,in,out);
+// Forward.fft(in,out);
+//
+// In-place usage:
+//
+// rcfft1d Forward(n);
+// Forward.fft(out);
+//
+// Notes:
+// in contains the n real values stored as a Complex array;
+// out contains the first n/2+1 Complex Fourier values.
+//
+class rcfft1d : public fftw {
+ unsigned int nx;
+public:
+ rcfft1d(unsigned int nx, Complex *out=NULL)
+ : fftw(nx/2+1,-1,nx), nx(nx) {Setup(out);}
+
+ rcfft1d(unsigned int nx, double *in, Complex *out=NULL)
+ : fftw(nx/2+1,-1,nx), nx(nx) {Setup(in,out);}
+
+#ifdef __Array_h__
+ rcfft1d(const array1<Complex>& in)
+ : fftw(in.Size(),-1,2*(in.Nx()-1)), nx(2*(in.Nx()-1)) {Setup(in);}
+
+ rcfft1d(const array1<double>& in, const array1<Complex>& out)
+ : fftw(out.Size(),-1,in.Size()), nx(in.Nx()) {Setup(in,out);}
+#endif
+
+ fftw_plan Plan(Complex *in, Complex *out) {
+ return fftw_plan_dft_r2c_1d(nx,(double *) in,(fftw_complex *) out, effort);
+ }
+
+ void Execute(Complex *in, Complex *out) {
+ fftw_execute_dft_r2c(plan,(double *) in,(fftw_complex *) out);
+ }
+};
+
+// Compute the real inverse Fourier transform of the n/2+1 Complex values
+// corresponding to the non-negative part of the frequency spectrum, using
+// phase sign +1.
+// Before calling fft(), the array in must be allocated as Complex[n/2+1]
+// and the array out must be allocated as double[n]. The arrays in and out
+// may coincide, in which case they must both be allocated as Complex[n/2+1].
+//
+// Out-of-place usage:
+//
+// crfft1d Backward(n,in,out);
+// Backward.fft(in,out);
+//
+// In-place usage:
+//
+// crfft1d Backward(n);
+// Backward.fft(in);
+//
+// Notes:
+// in contains the first n/2+1 Complex Fourier values.
+// out contains the n real values stored as a Complex array;
+//
+class crfft1d : public fftw {
+ unsigned int nx;
+public:
+ crfft1d(unsigned int nx, Complex *in=NULL)
+ : fftw(nx/2+1,1,nx), nx(nx) {Setup(in);}
+
+ crfft1d(unsigned int nx, Complex *in, double *out)
+ : fftw(realsize(nx,in,out),1,nx), nx(nx) {Setup(in,out);}
+
+#ifdef __Array_h__
+ crfft1d(const array1<Complex>& in)
+ : fftw(in.Size(),1,2*(in.Nx()-1)), nx(2*(in.Nx()-1)) {Setup(in);}
+
+ crfft1d(const array1<Complex>& in, const array1<double>& out)
+ : fftw(out.Size()/2,1,out.Size()), nx(out.Nx()) {Setup(in,out);}
+#endif
+
+ fftw_plan Plan(Complex *in, Complex *out) {
+ return fftw_plan_dft_c2r_1d(nx,(fftw_complex *) in,(double *) out,effort);
+ }
+
+ void Execute(Complex *in, Complex *out) {
+ fftw_execute_dft_c2r(plan,(fftw_complex *) in,(double *) out);
+ }
+};
+
+// Compute the real Fourier transform of m real vectors, each of length n,
+// using phase sign -1. Before calling fft(), the array in must be
+// allocated as double[m*n] and the array out must be allocated as
+// Complex[m*(n/2+1)]. The arrays in and out may coincide, in which case
+// they must both be allocated as Complex[m*(n/2+1)].
+//
+// Out-of-place usage:
+//
+// mrcfft1d Forward(n,m,stride,dist,in,out);
+// Forward.fft(in,out);
+//
+// In-place usage:
+//
+// mrcfft1d Forward(n,m,stride,dist);
+// Forward.fft(out);
+//
+// Notes:
+// stride is the spacing between the elements of each Complex vector;
+// dist is the spacing between the first elements of the vectors;
+// in contains the n real values stored as a Complex array;
+// out contains the first n/2+1 Complex Fourier values.
+//
+class mrcfft1d : public fftw {
+ unsigned int nx;
+ unsigned int m;
+ unsigned int stride;
+ unsigned int dist;
+public:
+ mrcfft1d(unsigned int nx, unsigned int m=1, unsigned int stride=1,
+ unsigned int dist=0, Complex *out=NULL)
+ : fftw(nx/2*stride+(m-1)*Dist(nx,stride,dist)+1,-1,nx), nx(nx), m(m),
+ stride(stride), dist(Dist(nx,stride,dist)) {Setup(out);}
+
+ mrcfft1d(unsigned int nx, unsigned int m=1, unsigned int stride=1,
+ unsigned int dist=0, double *in=NULL, Complex *out=NULL)
+ : fftw(nx/2*stride+(m-1)*Dist(nx,stride,dist)+1,-1,nx), nx(nx), m(m),
+ stride(stride), dist(Dist(nx,stride,dist)) {Setup(in,out);}
+
+ fftw_plan Plan(Complex *in, Complex *out) {
+ const int n[1]={nx};
+ return fftw_plan_many_dft_r2c(1,n,m,
+ (double *) in,NULL,stride,2*dist,
+ (fftw_complex *) out,NULL,stride,dist,
+ effort);
+ }
+
+ void Execute(Complex *in, Complex *out) {
+ fftw_execute_dft_r2c(plan,(double *) in,(fftw_complex *) out);
+ }
+
+ void fftNormalized(Complex *in, Complex *out=NULL) {
+ fftw::fftNormalized(in,out,nx/2+1,m,stride,dist);
+ }
+};
+
+// Compute the real inverse Fourier transform of m complex vectors, each of
+// length n/2+1, corresponding to the non-negative parts of the frequency
+// spectra, using phase sign +1. Before calling fft(), the array in must be
+// allocated as Complex[m*(n/2+1)] and the array out must be allocated as
+// double[m*n]. The arrays in and out may coincide, in which case they
+// must both be allocated as Complex[m*(n/2+1)].
+//
+// Out-of-place usage:
+//
+// mcrfft1d Backward(n,m,stride,dist,in,out);
+// Backward.fft(in,out);
+//
+// In-place usage:
+//
+// mcrfft1d Backward(n,m,stride,dist);
+// Backward.fft(out);
+//
+// Notes:
+// stride is the spacing between the elements of each Complex vector;
+// dist is the spacing between the first elements of the vectors;
+// in contains the first n/2+1 Complex Fourier values.
+// out contains the n real values stored as a Complex array;
+//
+class mcrfft1d : public fftw {
+ unsigned int nx;
+ unsigned int m;
+ unsigned int stride;
+ unsigned int dist;
+public:
+ mcrfft1d(unsigned int nx, unsigned int m=1, unsigned int stride=1,
+ unsigned int dist=0, Complex *in=NULL)
+ : fftw(nx/2*stride+(m-1)*Dist(nx,stride,dist)+1,1,nx),
+ nx(nx), m(m), stride(stride), dist(Dist(nx,stride,dist)) {Setup(in);}
+
+ mcrfft1d(unsigned int nx, unsigned int m=1, unsigned int stride=1,
+ unsigned int dist=0, Complex *in=NULL, double *out=NULL)
+ : fftw((realsize(nx,in,out)-1)*stride+(m-1)*Dist(nx,stride,dist)+1,1,nx),
+ nx(nx), m(m), stride(stride), dist(Dist(nx,stride,dist)) {Setup(in,out);}
+
+ fftw_plan Plan(Complex *in, Complex *out) {
+ const int n[1]={nx};
+ return fftw_plan_many_dft_c2r(1,n,m,
+ (fftw_complex *) in,NULL,stride,dist,
+ (double *) out,NULL,stride,2*dist,
+ effort);
+ }
+
+ void Execute(Complex *in, Complex *out) {
+ fftw_execute_dft_c2r(plan,(fftw_complex *) in,(double *) out);
+ }
+
+ void fftNormalized(Complex *in, Complex *out=NULL) {
+ fftw::fftNormalized(in,out,(nx/2+1),m,stride,dist);
+ }
+};
+
+// Compute the complex two-dimensional Fourier transform of nx times ny
+// complex values. Before calling fft(), the arrays in and out (which may
+// coincide) must be allocated as Complex[nx*ny].
+//
+// Out-of-place usage:
+//
+// fft2d Forward(nx,ny,-1,in,out);
+// Forward.fft(in,out);
+//
+// fft2d Backward(nx,ny,1,out,in);
+// Backward.fft(out,in);
+//
+// fft2d Backward(nx,ny,1,out,in);
+// Backward.fftNormalized(out,in); // True inverse of Forward.fft(in,out);
+//
+// In-place usage:
+//
+// fft2d Forward(nx,ny,-1);
+// Forward.fft(in);
+//
+// fft2d Backward(nx,ny,1);
+// Backward.fft(in);
+//
+// Note:
+// in[ny*i+j] contains the ny Complex values for each i=0,...,nx-1.
+//
+class fft2d : public fftw {
+ unsigned int nx;
+ unsigned int ny;
+public:
+ fft2d(unsigned int nx, unsigned int ny, int sign, Complex *in=NULL,
+ Complex *out=NULL)
+ : fftw(nx*ny,sign), nx(nx), ny(ny) {Setup(in,out);}
+
+#ifdef __Array_h__
+ fft2d(int sign, const array2<Complex>& in, const array2<Complex>& out=NULL2)
+ : fftw(in.Size(),sign), nx(in.Nx()), ny(in.Ny()) {Setup(in,out);}
+#endif
+
+ fftw_plan Plan(Complex *in, Complex *out) {
+ return fftw_plan_dft_2d(nx,ny,(fftw_complex *) in,(fftw_complex *) out,
+ sign,effort);
+ }
+};
+
+// Compute the complex two-dimensional Fourier transform of nx times ny real
+// values, using phase sign -1.
+// Before calling fft(), the array in must be allocated as double[nx*ny] and
+// the array out must be allocated as Complex[nx*(ny/2+1)]. The arrays in
+// and out may coincide, in which case they must both be allocated as
+// Complex[nx*(ny/2+1)].
+//
+// Out-of-place usage:
+//
+// rcfft2d Forward(nx,ny,in,out);
+// Forward.fft(in,out); // Origin of Fourier domain at (0,0)
+// Forward.fft0(in,out); // Origin of Fourier domain at (nx/2,0)
+//
+//
+// In-place usage:
+//
+// rcfft2d Forward(nx,ny);
+// Forward.fft(in); // Origin of Fourier domain at (0,0)
+// Forward.fft0(in); // Origin of Fourier domain at (nx/2,0)
+//
+// Notes:
+// in contains the nx*ny real values stored as a Complex array;
+// out contains the upper-half portion (ky >= 0) of the Complex transform.
+//
+class rcfft2d : public fftw {
+ unsigned int nx;
+ unsigned int ny;
+public:
+ rcfft2d(unsigned int nx, unsigned int ny, Complex *out=NULL) :
+ fftw(nx*(ny/2+1),-1,nx*ny), nx(nx), ny(ny) {Setup(out);}
+
+ rcfft2d(unsigned int nx, unsigned int ny, double *in, Complex *out=NULL) :
+ fftw(nx*(ny/2+1),-1,nx*ny), nx(nx), ny(ny) {Setup(in,out);}
+
+#ifdef __Array_h__
+ rcfft2d(const array2<Complex>& in) :
+ fftw(in.Size(),-1,in.Nx()*2*(in.Ny()-1)), nx(in.Nx()), ny(2*(in.Ny()-1))
+ {Setup(in);}
+
+ rcfft2d(const array2<double>& in, const array2<Complex>& out) :
+ fftw(out.Size(),-1,in.Size()), nx(in.Nx()), ny(in.Ny()) {Setup(in,out);}
+#endif
+
+ fftw_plan Plan(Complex *in, Complex *out) {
+ return fftw_plan_dft_r2c_2d(nx,ny,(double *) in,(fftw_complex *) out,
+ effort);
+ }
+
+ void Execute(Complex *in, Complex *out) {
+ if(shift) Shift(in,nx,ny);
+ fftw_execute_dft_r2c(plan,(double *) in,(fftw_complex *) out);
+ }
+};
+
+// Compute the real two-dimensional inverse Fourier transform of the
+// nx*(ny/2+1) Complex values corresponding to the spectral values in the
+// half-plane ky >= 0, using phase sign +1.
+// Before calling fft(), the array in must be allocated as
+// Complex[nx*(ny+1)/2] and the array out must be allocated as
+// double[nx*ny]. The arrays in and out may coincide, in which case they
+// must both be allocated as Complex[nx*(ny/2+1)].
+//
+// Out-of-place usage:
+//
+// crfft2d Backward(nx,ny,in,out);
+// Backward.fft(in,out); // Origin of Fourier domain at (0,0)
+// Backward.fft0(in,out); // Origin of Fourier domain at (nx/2,0)
+//
+//
+// In-place usage:
+//
+// crfft2d Backward(nx,ny);
+// Backward.fft(in); // Origin of Fourier domain at (0,0)
+// Backward.fft0(in); // Origin of Fourier domain at (nx/2,0)
+//
+// Notes:
+// in contains the upper-half portion (ky >= 0) of the Complex transform;
+// out contains the nx*ny real values stored as a Complex array.
+//
+class crfft2d : public fftw {
+ unsigned int nx;
+ unsigned int ny;
+public:
+ crfft2d(unsigned int nx, unsigned int ny, Complex *in=NULL)
+ : fftw(nx*(ny/2+1),1,nx*ny), nx(nx), ny(ny) {Setup(in);}
+
+ crfft2d(unsigned int nx, unsigned int ny, Complex *in, double *out)
+ : fftw(nx*(realsize(ny,in,out)),1,nx*ny), nx(nx), ny(ny) {Setup(in,out);}
+
+#ifdef __Array_h__
+ crfft2d(const array2<Complex>& in) :
+ fftw(in.Size(),1,in.Nx()*2*(in.Ny()-1)), nx(in.Nx()), ny(2*(in.Ny()-1))
+ {Setup(in);}
+
+ crfft2d(const array2<Complex>& in, const array2<double>& out) :
+ fftw(out.Size()/2,1,out.Size()), nx(out.Nx()), ny(out.Ny())
+ {Setup(in,out);}
+#endif
+
+ fftw_plan Plan(Complex *in, Complex *out) {
+ return fftw_plan_dft_c2r_2d(nx,ny,(fftw_complex *) in,(double *) out,
+ effort);
+ }
+
+ void Execute(Complex *in, Complex *out) {
+ fftw_execute_dft_c2r(plan,(fftw_complex *) in,(double *) out);
+ if(shift) Shift(out,nx,ny);
+ }
+};
+
+// Compute the complex three-dimensional Fourier transform of
+// nx times ny times nz complex values. Before calling fft(), the arrays in
+// and out (which may coincide) must be allocated as Complex[nx*ny*nz].
+//
+// Out-of-place usage:
+//
+// fft3d Forward(nx,ny,nz,-1,in,out);
+// Forward.fft(in,out);
+//
+// fft3d Backward(nx,ny,nz,1,out,in);
+// Backward.fft(out,in);
+//
+// fft3d Backward(nx,ny,nz,1,out,in);
+// Backward.fftNormalized(out,in); // True inverse of Forward.fft(in,out);
+//
+// In-place usage:
+//
+// fft3d Forward(nx,ny,nz,-1);
+// Forward.fft(in);
+//
+// fft3d Backward(nx,ny,nz,1);
+// Backward.fft(in);
+//
+// Note:
+// in[nz*(ny*i+j)+k] contains the (i,j,k)th Complex value,
+// indexed by i=0,...,nx-1, j=0,...,ny-1, and k=0,...,nz-1.
+//
+class fft3d : public fftw {
+ unsigned int nx;
+ unsigned int ny;
+ unsigned int nz;
+public:
+ fft3d(unsigned int nx, unsigned int ny, unsigned int nz,
+ int sign, Complex *in=NULL, Complex *out=NULL)
+ : fftw(nx*ny*nz,sign), nx(nx), ny(ny), nz(nz) {Setup(in,out);}
+
+#ifdef __Array_h__
+ fft3d(int sign, const array3<Complex>& in, const array3<Complex>& out=NULL3)
+ : fftw(in.Size(),sign), nx(in.Nx()), ny(in.Ny()), nz(in.Nz())
+ {Setup(in,out);}
+#endif
+
+ fftw_plan Plan(Complex *in, Complex *out) {
+ return fftw_plan_dft_3d(nx,ny,nz,(fftw_complex *) in,
+ (fftw_complex *) out, sign, effort);
+ }
+};
+
+// Compute the complex two-dimensional Fourier transform of
+// nx times ny times nz real values, using phase sign -1.
+// Before calling fft(), the array in must be allocated as double[nx*ny*nz]
+// and the array out must be allocated as Complex[nx*ny*(nz/2+1)]. The
+// arrays in and out may coincide, in which case they must both be allocated as
+// Complex[nx*ny*(nz/2+1)].
+//
+// Out-of-place usage:
+//
+// rcfft3d Forward(nx,ny,nz,in,out);
+// Forward.fft(in,out); // Origin of Fourier domain at (0,0)
+// Forward.fft0(in,out); // Origin of Fourier domain at (nx/2,ny/2,0)
+//
+//
+// In-place usage:
+//
+// rcfft3d Forward(nx,ny,nz);
+// Forward.fft(in); // Origin of Fourier domain at (0,0)
+// Forward.fft0(in); // Origin of Fourier domain at (nx/2,ny/2,0)
+//
+// Notes:
+// in contains the nx*ny*nz real values stored as a Complex array;
+// out contains the upper-half portion (kz >= 0) of the Complex transform.
+//
+class rcfft3d : public fftw {
+ unsigned int nx;
+ unsigned int ny;
+ unsigned int nz;
+public:
+ rcfft3d(unsigned int nx, unsigned int ny, unsigned int nz, Complex *out=NULL)
+ : fftw(nx*ny*(nz/2+1),-1,nx*ny*nz), nx(nx), ny(ny), nz(nz) {Setup(out);}
+
+ rcfft3d(unsigned int nx, unsigned int ny, unsigned int nz, double *in,
+ Complex *out=NULL) : fftw(nx*ny*(nz/2+1),-1,nx*ny*nz),
+ nx(nx), ny(ny), nz(nz) {Setup(in,out);}
+
+#ifdef __Array_h__
+ rcfft3d(const array3<Complex>& in) :
+ fftw(in.Size(),-1,in.Nx()*in.Ny()*2*(in.Nz()-1)),
+ nx(in.Nx()), ny(in.Ny()), nz(2*(in.Nz()-1)) {Setup(in);}
+
+ rcfft3d(const array3<double>& in, const array3<Complex>& out) :
+ fftw(out.Size(),-1,in.Size()),
+ nx(in.Nx()), ny(in.Ny()), nz(in.Nz()) {Setup(in,out);}
+#endif
+
+ fftw_plan Plan(Complex *in, Complex *out) {
+ return fftw_plan_dft_r2c_3d(nx,ny,nz,(double *) in,(fftw_complex *) out,
+ effort);
+ }
+
+ void Execute(Complex *in, Complex *out) {
+ if(shift) Shift(in,nx,ny,nz);
+ fftw_execute_dft_r2c(plan,(double *) in,(fftw_complex *) out);
+ }
+};
+
+// Compute the real two-dimensional inverse Fourier transform of the
+// nx*ny*(nz/2+1) Complex values corresponding to the spectral values in the
+// half-plane kz >= 0, using phase sign +1.
+// Before calling fft(), the array in must be allocated as
+// Complex[nx*ny*(nz+1)/2] and the array out must be allocated as
+// double[nx*ny*nz]. The arrays in and out may coincide, in which case they
+// must both be allocated as Complex[nx*ny*(nz/2+1)].
+//
+// Out-of-place usage:
+//
+// crfft3d Backward(nx,ny,nz,in,out);
+// Backward.fft(in,out); // Origin of Fourier domain at (0,0)
+// Backward.fft0(in,out); // Origin of Fourier domain at (nx/2,ny/2,0)
+//
+// In-place usage:
+//
+// crfft3d Backward(nx,ny,nz);
+// Backward.fft(in); // Origin of Fourier domain at (0,0)
+// Backward.fft0(in); // Origin of Fourier domain at (nx/2,ny/2,0)
+//
+// Notes:
+// in contains the upper-half portion (kz >= 0) of the Complex transform;
+// out contains the nx*ny*nz real values stored as a Complex array.
+//
+class crfft3d : public fftw {
+ unsigned int nx;
+ unsigned int ny;
+ unsigned int nz;
+public:
+ crfft3d(unsigned int nx, unsigned int ny, unsigned int nz, Complex *in=NULL)
+ : fftw(nx*ny*(nz/2+1),1,nx*ny*nz), nx(nx), ny(ny), nz(nz)
+ {Setup(in);}
+ crfft3d(unsigned int nx, unsigned int ny, unsigned int nz, Complex *in,
+ double *out) : fftw(nx*ny*(realsize(nz,in,out)),1,nx*ny*nz),
+ nx(nx), ny(ny), nz(nz) {Setup(in,out);}
+#ifdef __Array_h__
+ crfft3d(const array3<Complex>& in) :
+ fftw(in.Size(),1,in.Nx()*in.Ny()*2*(in.Nz()-1)),
+ nx(in.Nx()), ny(in.Ny()), nz(2*(in.Nz()-1)) {Setup(in);}
+
+ crfft3d(const array3<Complex>& in, const array3<double>& out) :
+ fftw(out.Size()/2,1,out.Size()),
+ nx(out.Nx()), ny(out.Ny()), nz(out.Nz()) {Setup(in,out);}
+#endif
+
+ fftw_plan Plan(Complex *in, Complex *out) {
+ return fftw_plan_dft_c2r_3d(nx,ny,nz,(fftw_complex *) in,(double *) out,
+ effort);
+ }
+
+ void Execute(Complex *in, Complex *out) {
+ fftw_execute_dft_c2r(plan,(fftw_complex *) in,(double *) out);
+ if(shift) Shift(out,nx,ny,nz);
+ }
+};
+
+#endif
diff --git a/Build/source/utils/asymptote/fileio.cc b/Build/source/utils/asymptote/fileio.cc
new file mode 100644
index 00000000000..125326af5eb
--- /dev/null
+++ b/Build/source/utils/asymptote/fileio.cc
@@ -0,0 +1,168 @@
+/******
+ * fileio.cc
+ * Tom Prince and John Bowman 2004/08/10
+ *
+ * Handle input/output
+ ******/
+
+#include "fileio.h"
+#include "settings.h"
+
+namespace camp {
+
+string tab="\t";
+string newline="\n";
+
+ofile Stdout("");
+file nullfile("",false,false,true);
+
+void ifile::ignoreComment()
+{
+ if(comment == 0) return;
+ int c;
+ bool eol=(stream->peek() == '\n');
+ if(eol && csvmode && nullfield) return;
+ for(;;) {
+ while(isspace(c=stream->peek())) {
+ stream->ignore();
+ whitespace += (char) c;
+ }
+ if(c == comment) {
+ whitespace="";
+ while((c=stream->peek()) != '\n' && c != EOF)
+ stream->ignore();
+ if(c == '\n')
+ stream->ignore();
+ } else {if(eol) stream->unget(); return;}
+ }
+}
+
+bool ifile::eol()
+{
+ int c;
+ while(isspace(c=stream->peek())) {
+ if(c == '\n') return true;
+ else {
+ stream->ignore();
+ whitespace += (char) c;
+ }
+ }
+ return false;
+}
+
+bool ifile::nexteol()
+{
+ int c;
+ if(nullfield) {
+ nullfield=false;
+ return true;
+ }
+
+ while(isspace(c=stream->peek())) {
+ if(c == '\n' && comma) {
+ nullfield=true;
+ return false;
+ }
+ stream->ignore();
+ if(c == '\n') {
+ while(isspace(c=stream->peek())) {
+ if(c == '\n') {nullfield=true; return true;}
+ else {
+ stream->ignore();
+ whitespace += (char) c;
+ }
+ }
+ return true;
+ }
+ else whitespace += (char) c;
+ }
+ return false;
+}
+
+void ifile::csv()
+{
+ comma=false;
+ nullfield=false;
+ if(!csvmode || stream->eof()) return;
+ std::ios::iostate rdstate=stream->rdstate();
+ if(stream->fail()) stream->clear();
+ int c=stream->peek();
+ if(c == ',') stream->ignore();
+ else if(c == '\n') {
+ stream->ignore();
+ if(linemode && stream->peek() != EOF) stream->unget();
+ } else stream->clear(rdstate);
+ if(c == ',') comma=true;
+}
+
+void ifile::Read(string& val)
+{
+ string s;
+ if(wordmode) {
+ whitespace="";
+ while(isspace(stream->peek())) stream->ignore();
+ }
+ if(csvmode || wordmode) {
+ bool quote=false;
+ while(stream->good()) {
+ int c=stream->peek();
+ if(c == '"') {quote=!quote; stream->ignore(); continue;}
+ if(!quote) {
+ if(comment && c == comment) {
+ while((c=stream->peek()) != '\n' && c != EOF)
+ stream->ignore();
+ if(s.empty() && c == '\n') {
+ stream->ignore();
+ continue;
+ }
+ }
+ if(csvmode && (c == ',' || c == '\n'))
+ break;
+ if(wordmode && isspace(c))
+ break;
+ }
+ s += (char) stream->get();
+ }
+ } else
+ getline(*stream,s);
+
+ if(comment) {
+ size_t p=0;
+ while((p=s.find(comment,p)) < string::npos) {
+ if(p+1 < s.length() && s[p+1] == comment) {
+ s.erase(p,1);
+ ++p;
+ } else {
+ s.erase(p);
+ break;
+ }
+ }
+ }
+ val=whitespace+s;
+}
+
+void ofile::writeline()
+{
+ if(standard && interact::query && !vm::indebugger) {
+ Int scroll=settings::getScroll();
+ if(scroll && interact::lines > 0 && interact::lines % scroll == 0) {
+ for(;;) {
+ if(!cin.good()) {
+ *stream << newline;
+ cin.clear();
+ break;
+ }
+ int c=cin.get();
+ if(c == '\n') break;
+ // Discard any additional characters
+ while(cin.good() && cin.get() != '\n');
+ if(c == 's') {interact::query=false; break;}
+ if(c == 'q') {interact::query=false; interact::lines=0; throw quit();}
+ }
+ } else *stream << newline;
+ ++interact::lines;
+ } else *stream << newline;
+ if(errorstream::interrupt) {interact::lines=0; throw interrupted();}
+}
+
+} // namespace camp
diff --git a/Build/source/utils/asymptote/fileio.h b/Build/source/utils/asymptote/fileio.h
new file mode 100644
index 00000000000..18ac10207ef
--- /dev/null
+++ b/Build/source/utils/asymptote/fileio.h
@@ -0,0 +1,685 @@
+/******
+ * fileio.h
+ * Tom Prince and John Bowman 2004/05/10
+ *
+ * Handle input/output
+ ******/
+
+#ifndef FILEIO_H
+#define FILEIO_H
+
+#include <fstream>
+#include <iostream>
+#include <sstream>
+
+#include "common.h"
+
+#ifdef HAVE_RPC_RPC_H
+#include "xstream.h"
+#endif
+
+#include "pair.h"
+#include "triple.h"
+#include "guide.h"
+#include "pen.h"
+
+#include "camperror.h"
+#include "interact.h"
+#include "errormsg.h"
+#include "util.h"
+#include "process.h"
+
+namespace vm {
+extern bool indebugger;
+}
+
+namespace camp {
+
+extern string tab;
+extern string newline;
+
+class file : public gc {
+protected:
+ string name;
+ Int nx,ny,nz; // Array dimensions
+ bool linemode; // Array reads will stop at eol instead of eof.
+ bool csvmode; // Read comma-separated values.
+ bool wordmode; // Delimit strings by white space instead of eol.
+ bool singlereal; // Read/write single-precision XDR/binary reals.
+ bool singleint; // Read/write single-precision XDR/binary ints.
+ bool closed; // File has been closed.
+ bool check; // Check whether input file exists.
+ bool standard; // Standard input/output
+ bool binary; // Read in binary mode.
+
+ bool nullfield; // Used to detect a final null field in csv+line mode.
+ string whitespace;
+ size_t index; // Terminator index.
+public:
+
+ bool Standard() {return standard;}
+
+ void standardEOF() {
+#if defined(HAVE_LIBREADLINE) && defined(HAVE_LIBCURSES)
+ cout << endl;
+#endif
+ }
+
+ template<class T>
+ void purgeStandard(T&) {
+ if(standard) {
+ int c;
+ if(cin.eof())
+ standardEOF();
+ else {
+ cin.clear();
+ while((c=cin.peek()) != EOF) {
+ cin.ignore();
+ if(c == '\n') break;
+ }
+ }
+ }
+ }
+
+ void purgeStandard(string&) {
+ if(cin.eof())
+ standardEOF();
+ }
+
+ void dimension(Int Nx=-1, Int Ny=-1, Int Nz=-1) {nx=Nx; ny=Ny; nz=Nz;}
+
+ file(const string& name, bool check=true, bool binary=false,
+ bool closed=false) :
+ name(name), linemode(false), csvmode(false),
+ singlereal(false), singleint(true),
+ closed(closed), check(check), standard(name.empty()),
+ binary(binary), nullfield(false), whitespace("") {dimension();}
+
+ virtual void open() {}
+
+ void Check() {
+ if(error()) {
+ ostringstream buf;
+ buf << "Cannot open file \"" << name << "\".";
+ reportError(buf);
+ }
+ }
+
+ virtual ~file() {}
+
+ virtual const char* Mode() {return "";}
+
+ bool isOpen() {
+ if(closed) {
+ ostringstream buf;
+ buf << "I/O operation attempted on ";
+ if(name != "") buf << "closed file \'" << name << "\'.";
+ else buf << "null file.";
+ reportError(buf);
+ }
+ return true;
+ }
+
+ string filename() {return name;}
+ virtual bool eol() {return false;}
+ virtual bool nexteol() {return false;}
+ virtual bool text() {return false;}
+ virtual bool eof() {return true;}
+ virtual bool error() {return true;}
+ virtual void close() {}
+ virtual void clear() {}
+ virtual Int precision(Int) {return 0;}
+ virtual void flush() {}
+ virtual size_t tell() {return 0;}
+ virtual void seek(Int, bool=true) {}
+
+ void unsupported(const char *rw, const char *type) {
+ ostringstream buf;
+ buf << rw << " of type " << type << " not supported in " << Mode()
+ << " mode.";
+ reportError(buf);
+ }
+
+ void noread(const char *type) {unsupported("Read",type);}
+ void nowrite(const char *type) {unsupported("Write",type);}
+
+ virtual void Read(bool&) {noread("bool");}
+ virtual void Read(Int&) {noread("int");}
+ virtual void Read(double&) {noread("real");}
+ virtual void Read(float&) {noread("real");}
+ virtual void Read(pair&) {noread("pair");}
+ virtual void Read(triple&) {noread("triple");}
+ virtual void Read(char&) {noread("char");}
+ virtual void Read(string&) {noread("string");}
+ virtual void readwhite(string&) {noread("string");}
+
+ virtual void write(bool) {nowrite("bool");}
+ virtual void write(Int) {nowrite("int");}
+ virtual void write(double) {nowrite("real");}
+ virtual void write(const pair&) {nowrite("pair");}
+ virtual void write(const triple&) {nowrite("triple");}
+ virtual void write(const string&) {nowrite("string");}
+ virtual void write(const pen&) {nowrite("pen");}
+ virtual void write(guide *) {nowrite("guide");}
+ virtual void write(const transform&) {nowrite("transform");}
+ virtual void writeline() {nowrite("string");}
+
+ virtual void ignoreComment() {};
+ virtual void csv() {};
+
+ template<class T>
+ void ignoreComment(T&) {
+ ignoreComment();
+ }
+
+ void ignoreComment(string&) {}
+ void ignoreComment(char&) {}
+
+ template<class T>
+ void read(T& val) {
+ if(binary) Read(val);
+ else {
+ if(standard) clear();
+ if(errorstream::interrupt) throw interrupted();
+ else {
+ ignoreComment(val);
+ val=T();
+ if(!nullfield)
+ Read(val);
+ csv();
+ whitespace="";
+ }
+ }
+ }
+
+ Int Nx() {return nx;}
+ Int Ny() {return ny;}
+ Int Nz() {return nz;}
+
+ void Nx(Int n) {nx=n;}
+ void Ny(Int n) {ny=n;}
+ void Nz(Int n) {nz=n;}
+
+ void LineMode(bool b) {linemode=b;}
+ bool LineMode() {return linemode;}
+
+ void CSVMode(bool b) {csvmode=b; if(b) wordmode=false;}
+ bool CSVMode() {return csvmode;}
+
+ void WordMode(bool b) {wordmode=b; if(b) csvmode=false;}
+ bool WordMode() {return wordmode;}
+
+ void SingleReal(bool b) {singlereal=b;}
+ bool SingleReal() {return singlereal;}
+
+ void SingleInt(bool b) {singleint=b;}
+ bool SingleInt() {return singleint;}
+};
+
+class ifile : public file {
+protected:
+ istream *stream;
+ std::fstream *fstream;
+ char comment;
+ std::ios::openmode mode;
+ bool comma;
+
+public:
+ ifile(const string& name, char comment, bool check=true,
+ std::ios::openmode mode=std::ios::in) :
+ file(name,check), stream(NULL), fstream(NULL), comment(comment), mode(mode),
+ comma(false) {
+ stream=&cin;
+ }
+
+ // Binary file
+ ifile(const string& name, bool check=true,
+ std::ios::openmode mode=std::ios::in) :
+ file(name,check,true), mode(mode) {}
+
+ ~ifile() {close();}
+
+ void open() {
+ if(standard) {
+ if(mode & std::ios::binary)
+ reportError("Cannot open standard input in binary mode");
+ stream=&cin;
+ } else {
+ stream=fstream=new std::fstream(name.c_str(),mode);
+ if(mode & std::ios::out) {
+ checkLocal(name);
+ if(error()) {
+ delete fstream;
+ std::ofstream f(name.c_str());
+ f.close();
+ }
+ stream=fstream=new std::fstream(name.c_str(),mode);
+ }
+ index=processData().ifile.add(fstream);
+ if(check) Check();
+ }
+ }
+
+ const char* Mode() {return "input";}
+
+ bool eol();
+ bool nexteol();
+
+ bool text() {return true;}
+ bool eof() {return stream->eof();}
+ bool error() {return stream->fail();}
+
+ void close() {
+ if(!standard && fstream) {
+ fstream->close();
+ closed=true;
+ delete fstream;
+ fstream=NULL;
+ processData().ifile.remove(index);
+ }
+ }
+
+ void clear() {stream->clear();}
+
+ void seek(Int pos, bool begin=true) {
+ if(!standard && fstream) {
+ clear();
+ fstream->seekg(pos,begin ? std::ios::beg : std::ios::end);
+ }
+ }
+
+ size_t tell() {
+ if(fstream)
+ return fstream->tellg();
+ else
+ return 0;
+ }
+
+ void csv();
+
+ virtual void ignoreComment();
+
+ // Skip over white space
+ void readwhite(string& val) {val=string(); *stream >> val;}
+
+ void Read(bool &val) {string t; readwhite(t); val=(t == "true");}
+ void Read(Int& val) {*stream >> val;}
+ void Read(double& val) {*stream >> val;}
+ void Read(pair& val) {*stream >> val;}
+ void Read(triple& val) {*stream >> val;}
+ void Read(char& val) {stream->get(val);}
+ void Read(string& val);
+};
+
+class iofile : public ifile {
+public:
+ iofile(const string& name, char comment=0) :
+ ifile(name,true,comment,std::ios::in | std::ios::out) {}
+
+ Int precision(Int p) {
+ return p == 0 ? stream->precision() : stream->precision(p);
+ }
+ void flush() {if(fstream) fstream->flush();}
+
+ void write(bool val) {*fstream << (val ? "true " : "false ");}
+ void write(Int val) {*fstream << val;}
+ void write(double val) {*fstream << val;}
+ void write(const pair& val) {*fstream << val;}
+ void write(const triple& val) {*fstream << val;}
+ void write(const string& val) {*fstream << val;}
+ void write(const pen& val) {*fstream << val;}
+ void write(guide *val) {*fstream << *val;}
+ void write(const transform& val) {*fstream << val;}
+
+ void writeline() {
+ *fstream << newline;
+ if(errorstream::interrupt) throw interrupted();
+ }
+};
+
+class ofile : public file {
+protected:
+ ostream *stream;
+ std::ofstream *fstream;
+ std::ios::openmode mode;
+public:
+ ofile(const string& name, std::ios::openmode mode=std::ios::trunc) :
+ file(name), stream(NULL), fstream(NULL), mode(mode) {
+ stream=&cout;
+ }
+
+ ~ofile() {close();}
+
+ void open() {
+ if(standard) {
+ if(mode & std::ios::binary)
+ reportError("Cannot open standard output in binary mode");
+ stream=&cout;
+ } else {
+ checkLocal(name);
+ stream=fstream=new std::ofstream(name.c_str(),mode | std::ios::trunc);
+ index=processData().ofile.add(fstream);
+ Check();
+ }
+ }
+
+ const char* Mode() {return "output";}
+
+ bool text() {return true;}
+ bool eof() {return stream->eof();}
+ bool error() {return stream->fail();}
+
+ void close() {
+ if(!standard && fstream) {
+ fstream->close();
+ closed=true;
+ delete fstream;
+ fstream=NULL;
+ processData().ofile.remove(index);
+ }
+ }
+ void clear() {stream->clear();}
+ Int precision(Int p) {
+ return p == 0 ? stream->precision() : stream->precision(p);
+ }
+ void flush() {stream->flush();}
+
+ void seek(Int pos, bool begin=true) {
+ if(!standard && fstream) {
+ clear();
+ fstream->seekp(pos,begin ? std::ios::beg : std::ios::end);
+ }
+ }
+
+ size_t tell() {
+ if(fstream)
+ return fstream->tellp();
+ else
+ return 0;
+ }
+
+ void write(bool val) {*stream << (val ? "true " : "false ");}
+ void write(Int val) {*stream << val;}
+ void write(double val) {*stream << val;}
+ void write(const pair& val) {*stream << val;}
+ void write(const triple& val) {*stream << val;}
+ void write(const string& val) {*stream << val;}
+ void write(const pen& val) {*stream << val;}
+ void write(guide *val) {*stream << *val;}
+ void write(const transform& val) {*stream << val;}
+
+ void writeline();
+};
+
+class ibfile : public ifile {
+public:
+ ibfile(const string& name, bool check=true,
+ std::ios::openmode mode=std::ios::in) :
+ ifile(name,check,mode | std::ios::binary) {}
+ template<class T>
+ void iread(T& val) {
+ val=T();
+ fstream->read((char *) &val,sizeof(T));
+ }
+
+ void Read(bool& val) {iread(val);}
+ void Read(Int& val) {
+ if(singleint) {int ival; iread(ival); val=ival;}
+ else iread(val);
+ }
+ void Read(char& val) {iread(val);}
+ void Read(string& val) {iread(val);}
+
+ void Read(double& val) {
+ if(singlereal) {float fval; iread(fval); val=fval;}
+ else iread(val);
+ }
+};
+
+class iobfile : public ibfile {
+public:
+ iobfile(const string& name) : ibfile(name,true,std::ios::in | std::ios::out)
+ {}
+
+ void flush() {if(fstream) fstream->flush();}
+
+ template<class T>
+ void iwrite(T val) {
+ fstream->write((char *) &val,sizeof(T));
+ }
+
+ void write(bool val) {iwrite(val);}
+ void write(Int val) {
+ if(singleint) iwrite(intcast(val));
+ else iwrite(val);
+ }
+ void write(const string& val) {iwrite(val);}
+ void write(const pen& val) {iwrite(val);}
+ void write(guide *val) {iwrite(val);}
+ void write(const transform& val) {iwrite(val);}
+ void write(double val) {
+ if(singlereal) iwrite((float) val);
+ else iwrite(val);
+ }
+ void write(const pair& val) {
+ write(val.getx());
+ write(val.gety());
+ }
+ void write(const triple& val) {
+ write(val.getx());
+ write(val.gety());
+ write(val.getz());
+ }
+ void writeline() {}
+};
+
+class obfile : public ofile {
+public:
+ obfile(const string& name) : ofile(name,std::ios::binary) {}
+
+ template<class T>
+ void iwrite(T val) {
+ fstream->write((char *) &val,sizeof(T));
+ }
+
+ void write(bool val) {iwrite(val);}
+ void write(Int val) {
+ if(singleint) iwrite(intcast(val));
+ else iwrite(val);
+ }
+ void write(const string& val) {iwrite(val);}
+ void write(const pen& val) {iwrite(val);}
+ void write(guide *val) {iwrite(val);}
+ void write(const transform& val) {iwrite(val);}
+ void write(double val) {
+ if(singlereal) iwrite((float) val);
+ else iwrite(val);
+ }
+ void write(const pair& val) {
+ write(val.getx());
+ write(val.gety());
+ }
+ void write(const triple& val) {
+ write(val.getx());
+ write(val.gety());
+ write(val.getz());
+ }
+
+ void writeline() {}
+};
+
+#ifdef HAVE_RPC_RPC_H
+
+class ixfile : public file {
+protected:
+ xdr::ioxstream *fstream;
+ xdr::xios::open_mode mode;
+public:
+ ixfile(const string& name, bool check=true,
+ xdr::xios::open_mode mode=xdr::xios::in) :
+ file(name,check,true), fstream(NULL), mode(mode) {}
+
+ void open() {
+ fstream=new xdr::ioxstream(name.c_str(),mode);
+ index=processData().ixfile.add(fstream);
+ if(check) Check();
+ }
+
+ void close() {
+ if(fstream) {
+ fstream->close();
+ closed=true;
+ delete fstream;
+ fstream=NULL;
+ processData().ixfile.remove(index);
+ }
+ }
+
+ ~ixfile() {close();}
+
+ const char* Mode() {return "xinput";}
+
+ bool eof() {return fstream ? fstream->eof() : true;}
+ bool error() {return fstream ? fstream->fail() : true;}
+
+ void clear() {if(fstream) fstream->clear();}
+
+ void seek(Int pos, bool begin=true) {
+ if(!standard && fstream) {
+ clear();
+ fstream->seek(pos,begin ? xdr::xios::beg : xdr::xios::end);
+ }
+ }
+
+ size_t tell() {
+ if(fstream)
+ return fstream->tell();
+ else
+ return 0;
+ }
+
+ void Read(Int& val) {
+ if(singleint) {int ival=0; *fstream >> ival; val=ival;}
+ else {
+ val=0;
+ *fstream >> val;
+ }
+ }
+ void Read(double& val) {
+ if(singlereal) {float fval=0.0; *fstream >> fval; val=fval;}
+ else {
+ val=0.0;
+ *fstream >> val;
+ }
+ }
+ void Read(pair& val) {
+ double x,y;
+ Read(x);
+ Read(y);
+ val=pair(x,y);
+ }
+ void Read(triple& val) {
+ double x,y,z;
+ Read(x);
+ Read(y);
+ Read(z);
+ val=triple(x,y,z);
+ }
+};
+
+class ioxfile : public ixfile {
+public:
+ ioxfile(const string& name) : ixfile(name,true,xdr::xios::out) {}
+
+ void flush() {if(fstream) fstream->flush();}
+
+ void write(Int val) {
+ if(singleint) *fstream << intcast(val);
+ else *fstream << val;
+ }
+ void write(double val) {
+ if(singlereal) *fstream << (float) val;
+ else *fstream << val;
+ }
+ void write(const pair& val) {
+ write(val.getx());
+ write(val.gety());
+ }
+ void write(const triple& val) {
+ write(val.getx());
+ write(val.gety());
+ write(val.getz());
+ }
+};
+
+class oxfile : public file {
+ xdr::oxstream *fstream;
+public:
+ oxfile(const string& name) : file(name), fstream(NULL) {}
+
+ void open() {
+ fstream=new xdr::oxstream((checkLocal(name),name.c_str()),xdr::xios::trunc);
+ index=processData().oxfile.add(fstream);
+ Check();
+ }
+
+ void close() {
+ if(fstream) {
+ fstream->close();
+ closed=true;
+ delete fstream;
+ fstream=NULL;
+ processData().oxfile.remove(index);
+ }
+ }
+
+ ~oxfile() {close();}
+
+ const char* Mode() {return "xoutput";}
+
+ bool eof() {return fstream ? fstream->eof() : true;}
+ bool error() {return fstream ? fstream->fail() : true;}
+ void clear() {if(fstream) fstream->clear();}
+ void flush() {if(fstream) fstream->flush();}
+
+ void seek(Int pos, bool begin=true) {
+ if(!standard && fstream) {
+ clear();
+ fstream->seek(pos,begin ? xdr::xios::beg : xdr::xios::end);
+ }
+ }
+
+ size_t tell() {
+ if(fstream)
+ return fstream->tell();
+ else
+ return 0;
+ }
+
+ void write(Int val) {
+ if(singleint) *fstream << intcast(val);
+ else *fstream << val;
+ }
+ void write(double val) {
+ if(singlereal) *fstream << (float) val;
+ else *fstream << val;
+ }
+ void write(const pair& val) {
+ write(val.getx());
+ write(val.gety());
+ }
+ void write(const triple& val) {
+ write(val.getx());
+ write(val.gety());
+ write(val.getz());
+ }
+};
+
+#endif
+
+extern ofile Stdout;
+extern file nullfile;
+
+} // namespace camp
+
+#endif // FILEIO_H
diff --git a/Build/source/utils/asymptote/flatguide.cc b/Build/source/utils/asymptote/flatguide.cc
new file mode 100644
index 00000000000..bfc26dfd041
--- /dev/null
+++ b/Build/source/utils/asymptote/flatguide.cc
@@ -0,0 +1,49 @@
+/*****
+ * flatguide.cc
+ * Andy Hammerlindl 2005/02/23
+ *
+ * The data structure that builds up a knotlist. This is done by calling in
+ * order the methods to set knots, specifiers, and tensions.
+ * Used by the guide solving routines.
+ *****/
+
+#include "flatguide.h"
+
+namespace camp {
+
+void flatguide::addPre(path& p, Int j)
+{
+ setSpec(new controlSpec(p.precontrol(j),p.straight(j-1)),IN);
+}
+void flatguide::addPoint(path& p, Int j)
+{
+ add(p.point(j));
+}
+void flatguide::addPost(path& p, Int j)
+{
+ setSpec(new controlSpec(p.postcontrol(j),p.straight(j)),OUT);
+}
+
+void flatguide::uncheckedAdd(path p, bool allowsolve)
+{
+ Int n=p.length();
+ if(n < 0) return;
+ int nminus1=n-1;
+ if(!allowsolve && p.cyclic()) addPre(p,0);
+ for(Int i=0; i < nminus1;) {
+ addPoint(p,i);
+ addPost(p,i);
+ ++i;
+ addPre(p,i);
+ }
+ addPoint(p,nminus1);
+ addPost(p,nminus1);
+ if(allowsolve || !p.cyclic()) {
+ addPre(p,n);
+ addPoint(p,n);
+ }
+}
+
+spec flatguide::open;
+
+}
diff --git a/Build/source/utils/asymptote/flatguide.h b/Build/source/utils/asymptote/flatguide.h
new file mode 100644
index 00000000000..c4d5c9bce67
--- /dev/null
+++ b/Build/source/utils/asymptote/flatguide.h
@@ -0,0 +1,190 @@
+/*****
+ * flatguide.h
+ * Andy Hammerlindl 2005/02/23
+ *
+ * The data structure that builds up a knotlist. This is done by calling in
+ * order the methods to set knots, specifiers, and tensions.
+ * Used by the guide solving routines.
+ *
+ * NOTE: figure out how nullpath{}..a should be handled.
+ *****/
+
+#ifndef FLATGUIDE_H
+#define FLATGUIDE_H
+
+#include "knot.h"
+#include "guideflags.h"
+
+namespace camp {
+
+class flatguide
+{
+ // A cached solution of the path. When traversing through a tree of guides,
+ // if a cycle tag is encountered, then the path is solved up to that point.
+ // If the guide continues from there (which rarely occurs in practice), all of
+ // the control points solved are added as control specifiers, and then solved
+ // into a path again. In the (usual) case that a cycle ends a path, the
+ // cached path avoids this second pass.
+ bool solved;
+
+ // Used by reverse(guide) to indicate the presence of an unresolved
+ // interior cycle.
+ bool precycle;
+
+ path p;
+
+ cvector<knot> nodes;
+
+ // Information before the first knot. For a non-cyclic guide, this is
+ // ignored. For a cyclic guide, it may be useful, but I can't determine a
+ // sensible way to use it yet.
+ tension tout;
+ spec *out;
+
+ // Information for the next knot to come.
+ tension tin;
+ spec *in;
+
+ static spec open;
+
+ tension& tref(side s)
+ {
+ switch (s) {
+ case OUT:
+ return nodes.empty() ? tout : nodes.back().tout;
+ case IN:
+ default:
+ return tin;
+ }
+ }
+
+ // Returns a reference to a spec* so that it may be assigned.
+ spec*& sref(side s)
+ {
+ switch (s) {
+ case OUT:
+ return nodes.empty() ? out : nodes.back().out;
+ case IN:
+ default:
+ return in;
+ }
+ }
+
+ void addPre(path& p, Int j);
+ void addPoint(path& p, Int j);
+ void addPost(path& p, Int j);
+
+ void clearNodes() {
+ nodes.clear();
+ in=&open;
+ tin=tension();
+ }
+ void clearPath() {
+ p=path();
+ solved=false;
+ }
+
+ void uncheckedAdd(path p, bool allowsolve=true);
+
+ // Sets solved to false, indicating that the path has been updated since last
+ // being solved. Also, copies a solved path back in as knots and control
+ // specifiers, as it will have to be solved again.
+ void update() {
+ if (solved) {
+ solved=false;
+ clearNodes();
+ add(p);
+ clearPath();
+ }
+ }
+
+public:
+ flatguide()
+ : solved(true), precycle(false), p(), out(&open), in(&open) {}
+
+ Int size() const {
+ return (Int) nodes.size();
+ }
+
+ knot Nodes(Int i) const {
+ return nodes[i];
+ }
+
+ void setTension(tension t, side s) {
+ update();
+ tref(s)=t;
+ }
+ void setSpec(spec *p, side s) {
+ assert(p);
+ update();
+ spec *&ref=sref(s);
+ // Control specifiers trump normal direction specifiers.
+ if (!ref || !ref->controlled() || p->controlled())
+ ref=p;
+ }
+
+ void add(pair z) {
+ update();
+ // Push the pair onto the vector as a knot, using the current in-specifier
+ // and in-tension for the in side for the knot. Use default values for the
+ // out side, as those will be set after the point is added.
+ nodes.push_back(knot(z,in,&open,tin,tension()));
+
+ // Reset the in-spec and in-tension to defaults;
+ tin=tension();
+ in=&open;
+ }
+
+ // Reverts to an empty state.
+ void add(path p, bool allowsolve=true) {
+ update();
+ uncheckedAdd(p,allowsolve);
+ }
+
+ void clear() {
+ clearNodes();
+ clearPath();
+ }
+
+ void close() {
+ if(!nodes.empty()) {
+ nodes.front().in=in;
+ nodes.front().tin=tin;
+ }
+ }
+
+ void resolvecycle() {
+ if(!nodes.empty())
+ nodes.push_back(nodes.front());
+ }
+
+ void precyclic(bool b) {
+ precycle=b;
+ }
+
+ bool precyclic() {
+ return precycle;
+ }
+
+ // Once all information has been added, release the flat result.
+ simpleknotlist list(bool cycles=false) {
+ if(cycles && !nodes.empty()) close();
+ return simpleknotlist(nodes,cycles);
+ }
+
+ // Yield a path from the guide as represented here.
+ path solve(bool cycles=false) {
+ if (solved)
+ return p;
+ else {
+ simpleknotlist l=list(cycles);
+ p=camp::solve(l);
+ solved=true;
+ return p;
+ }
+ }
+};
+
+} // namespace camp
+
+#endif // FLATGUIDE_H
diff --git a/Build/source/utils/asymptote/fpu.h b/Build/source/utils/asymptote/fpu.h
new file mode 100644
index 00000000000..5fa7205b43f
--- /dev/null
+++ b/Build/source/utils/asymptote/fpu.h
@@ -0,0 +1,40 @@
+#ifndef FPU_H
+#define FPU_H
+
+#ifdef HAVE_FENV_H
+#ifdef _GNU_SOURCE
+#define HAVE_FEENABLEEXCEPT
+#endif
+#endif
+
+#ifdef HAVE_FEENABLEEXCEPT
+#include <fenv.h>
+
+inline Int fpu_exceptions() {
+ Int excepts=0;
+#ifdef FE_INVALID
+ excepts |= FE_INVALID;
+#endif
+#ifdef FE_DIVBYZERO
+ excepts |= FE_DIVBYZERO;
+#endif
+#ifdef FE_OVERFLOW
+ excepts |= FE_OVERFLOW;
+#endif
+ return excepts;
+}
+
+inline void fpu_trap(bool trap=true)
+{
+ // Conditionally trap FPU exceptions on NaN, zero divide and overflow.
+ if(trap) feenableexcept(fpu_exceptions());
+ else fedisableexcept(fpu_exceptions());
+}
+
+#else
+
+inline void fpu_trap(bool=true) {}
+
+#endif
+
+#endif
diff --git a/Build/source/utils/asymptote/frame.h b/Build/source/utils/asymptote/frame.h
new file mode 100644
index 00000000000..9f3db9247a4
--- /dev/null
+++ b/Build/source/utils/asymptote/frame.h
@@ -0,0 +1,76 @@
+/*****
+ * frame.h
+ * Andy Hammerlindl 2002/07/22
+ *
+ * Describes the frame levels for the functions of the language.
+ * Also creates accesses for the variable for automated loading
+ * and saving of variables.
+ *****/
+
+#ifndef FRAME_H
+#define FRAME_H
+
+#include <cassert>
+
+#include "access.h"
+
+namespace trans {
+
+class frame : public gc {
+ frame *parent;
+ size_t numFormals;
+ Int numLocals;
+
+public:
+ frame(frame *parent, size_t numFormals)
+ : parent(parent), numFormals(numFormals), numLocals(0) {}
+
+ size_t getNumFormals() {
+ return numFormals;
+ }
+ Int getNumLocals() {
+ return numLocals;
+ }
+
+ frame *getParent() {
+ return parent;
+ }
+
+ Int size() {
+ return (Int) (1+numFormals+numLocals);
+ }
+
+ access *accessFormal(size_t index) {
+ assert(index < numFormals);
+ return new localAccess((Int) (1 + index), this);
+ }
+
+ access *allocLocal() {
+ return new localAccess((Int) (1 + numFormals + numLocals++), this);
+ }
+
+ // Checks if the frame f is a descendent of this frame.
+ // For our purposes, a frame is its own descendant.
+ bool isDescendant(frame *f)
+ {
+ while (f != 0) {
+ if (f == this)
+ return true;
+ f = f->parent;
+ }
+ return false;
+ }
+};
+
+inline void print(ostream& out, frame *f) {
+ out << f;
+ if (f != 0) {
+ out << " -> ";
+ print(out, f->getParent());
+ }
+}
+
+} // namespace trans
+
+#endif
+
diff --git a/Build/source/utils/asymptote/fundec.cc b/Build/source/utils/asymptote/fundec.cc
new file mode 100644
index 00000000000..016e300321e
--- /dev/null
+++ b/Build/source/utils/asymptote/fundec.cc
@@ -0,0 +1,305 @@
+/*****
+ * fundec.h
+ * Andy Hammerlindl 2002/8/29
+ *
+ * Defines the semantics for defining functions. Both the newexp syntax, and
+ * the abbreviated C-style function definition.
+ *****/
+
+#include "fundec.h"
+#include "errormsg.h"
+#include "coenv.h"
+#include "stm.h"
+#include "runtime.h"
+
+namespace absyntax {
+
+using namespace trans;
+using namespace types;
+using mem::list;
+
+varinit *Default=new definit(nullPos);
+
+void formal::prettyprint(ostream &out, Int indent)
+{
+ prettyname(out, "formal",indent);
+
+ base->prettyprint(out, indent+1);
+ if (start) start->prettyprint(out, indent+1);
+ if (defval) defval->prettyprint(out, indent+1);
+}
+
+types::formal formal::trans(coenv &e, bool encodeDefVal, bool tacit) {
+ return types::formal(getType(e,tacit),
+ getName(),
+ encodeDefVal ? (bool) getDefaultValue() : 0,
+ getExplicit());
+}
+
+types::ty *formal::getType(coenv &e, bool tacit) {
+ types::ty *bt = base->trans(e, tacit);
+ types::ty *t = start ? start->getType(bt, e, tacit) : bt;
+ if (t->kind == ty_void && !tacit) {
+ em.error(getPos());
+ em << "cannot declare parameters of type void";
+ return primError();
+ }
+
+ return t;
+}
+
+void formal::addOps(coenv &e, record *r) {
+ base->addOps(e, r);
+ if (start)
+ start->addOps(base->trans(e, true), e, r);
+}
+
+void formals::prettyprint(ostream &out, Int indent)
+{
+ prettyname(out, "formals",indent);
+
+ for(list<formal *>::iterator p = fields.begin(); p != fields.end(); ++p)
+ (*p)->prettyprint(out, indent+1);
+}
+
+void formals::addToSignature(signature& sig,
+ coenv &e, bool encodeDefVal, bool tacit) {
+ for(list<formal *>::iterator p = fields.begin(); p != fields.end(); ++p)
+ sig.add((*p)->trans(e, encodeDefVal, tacit));
+
+ if (rest) {
+ if (!tacit && rest->getDefaultValue()) {
+ em.error(rest->getPos());
+ em << "rest parameters cannot have default values";
+ }
+ sig.addRest(rest->trans(e, encodeDefVal, tacit));
+ }
+}
+
+// Returns the types of each parameter as a signature.
+// encodeDefVal means that it will also encode information regarding
+// the default values into the signature
+signature *formals::getSignature(coenv &e, bool encodeDefVal, bool tacit)
+{
+ signature *sig = new signature;
+ addToSignature(*sig,e,encodeDefVal,tacit);
+ return sig;
+}
+
+
+// Returns the corresponding function type, assuming it has a return
+// value of types::ty *result.
+function *formals::getType(types::ty *result, coenv &e,
+ bool encodeDefVal,
+ bool tacit)
+{
+ function *ft = new function(result);
+ addToSignature(ft->sig,e,encodeDefVal,tacit);
+ return ft;
+}
+
+void formals::addOps(coenv &e, record *r)
+{
+ for(list<formal *>::iterator p = fields.begin(); p != fields.end(); ++p)
+ (*p)->addOps(e, r);
+
+ if (rest)
+ rest->addOps(e, r);
+}
+
+// Another helper class. Does an assignment, but relying only on the
+// destination for the type.
+class basicAssignExp : public exp {
+ exp *dest;
+ varinit *value;
+public:
+ basicAssignExp(position pos, exp *dest, varinit *value)
+ : exp(pos), dest(dest), value(value) {}
+
+ types::ty *getType(coenv &e) {
+ return dest->getType(e);
+ }
+
+ types::ty *trans(coenv &e) {
+ // This doesn't handle overloaded types for the destination.
+ value->transToType(e, getType(e));
+ dest->transWrite(e, getType(e));
+ return getType(e);
+ }
+};
+
+void transDefault(coenv &e, position pos, varEntry *v, varinit *init) {
+ // This roughly translates into the expression
+ // if (isDefault(x))
+ // x=init;
+ // where x is the variable in v and isDefault is a function that tests
+ // whether x is the default argument token.
+ varEntryExp vee(pos, v);
+ ifStm is(pos,
+ new callExp(pos,
+ new varEntryExp(pos,
+ new function(primBoolean(), v->getType()),
+ run::isDefault),
+ &vee),
+ new expStm(pos,
+ new basicAssignExp(pos,
+ &vee,
+ init)));
+ is.trans(e);
+}
+
+void formal::transAsVar(coenv &e, Int index) {
+ symbol *name = getName();
+ if (name) {
+ trans::access *a = e.c.accessFormal(index);
+ assert(a);
+
+ // Suppress error messages because they will already be reported
+ // when the formals are translated to yield the type earlier.
+ types::ty *t = getType(e, true);
+ varEntry *v = new varEntry(t, a, 0, getPos());
+
+ // Translate the default argument before adding the formal to the
+ // environment, consistent with the initializers of variables.
+ if (defval)
+ transDefault(e, getPos(), v, defval);
+
+ e.e.addVar(name, v);
+ }
+}
+
+void formals::trans(coenv &e)
+{
+ Int index = 0;
+
+ for (list<formal *>::iterator p=fields.begin(); p!=fields.end(); ++p) {
+ (*p)->transAsVar(e, index);
+ ++index;
+ }
+
+ if (rest) {
+ rest->transAsVar(e, index);
+ ++index;
+ }
+}
+
+void fundef::prettyprint(ostream &out, Int indent)
+{
+ result->prettyprint(out, indent+1);
+ params->prettyprint(out, indent+1);
+ body->prettyprint(out, indent+1);
+}
+
+function *fundef::transType(coenv &e, bool tacit) {
+ bool encodeDefVal=true;
+ return params->getType(result->trans(e, tacit), e, encodeDefVal, tacit);
+}
+
+function *fundef::transTypeAndAddOps(coenv &e, record *r, bool tacit) {
+ result->addOps(e,r);
+ params->addOps(e,r);
+
+ function *ft=transType(e, tacit);
+ e.e.addFunctionOps(ft);
+ if (r)
+ r->e.addFunctionOps(ft);
+
+ return ft;
+}
+
+varinit *fundef::makeVarInit(function *ft) {
+ struct initializer : public varinit {
+ fundef *f;
+ function *ft;
+
+ initializer(fundef *f, function *ft)
+ : varinit(f->getPos()), f(f), ft(ft) {}
+
+ void prettyprint(ostream &out, Int indent) {
+ prettyname(out, "initializer", indent);
+ }
+
+ void transToType(coenv &e, types::ty *target) {
+ assert(ft==target);
+ f->baseTrans(e, ft);
+ }
+ };
+
+ return new initializer(this, ft);
+}
+
+void fundef::baseTrans(coenv &e, types::function *ft)
+{
+ // Create a new function environment.
+ coder fc = e.c.newFunction(ft);
+ coenv fe(fc,e.e);
+
+ // Translate the function.
+ fe.e.beginScope();
+ params->trans(fe);
+
+ body->trans(fe);
+
+ types::ty *rt = ft->result;
+ if (rt->kind != ty_void &&
+ rt->kind != ty_error &&
+ !body->returns()) {
+ em.error(body->getPos());
+ em << "function must return a value";
+ }
+
+ fe.e.endScope();
+
+ // Put an instance of the new function on the stack.
+ vm::lambda *l = fe.c.close();
+ e.c.encode(inst::pushclosure);
+ e.c.encode(inst::makefunc, l);
+}
+
+types::ty *fundef::trans(coenv &e) {
+ // I don't see how addFunctionOps can be useful here.
+ // For instance, in
+ //
+ // new void() {} == null
+ //
+ // callExp has to search for == before translating either argument, and the
+ // operator cannot be added before translation. (getType() is not allowed to
+ // manipulate the environment.)
+ // A new function expression is assigned to a variable, given as a return
+ // value, or used as an argument to a function. In any of these
+ //
+ // We must still addOps though, for the return type and formals. ex:
+ //
+ // new guide[] (guide f(int)) {
+ // return sequence(f, 10);
+ // };
+ function *ft=transTypeAndAddOps(e, (record *)0, false);
+ assert(ft);
+
+ baseTrans(e, ft);
+
+ return ft;
+}
+
+void fundec::prettyprint(ostream &out, Int indent)
+{
+ prettyindent(out, indent);
+ out << "fundec '" << *id << "'\n";
+
+ fun.prettyprint(out, indent);
+}
+
+void fundec::trans(coenv &e)
+{
+ transAsField(e,0);
+}
+
+void fundec::transAsField(coenv &e, record *r)
+{
+ function *ft = fun.transTypeAndAddOps(e, r, false);
+ assert(ft);
+
+ createVar(getPos(), e, r, id, ft, fun.makeVarInit(ft));
+}
+
+} // namespace absyntax
diff --git a/Build/source/utils/asymptote/fundec.h b/Build/source/utils/asymptote/fundec.h
new file mode 100644
index 00000000000..058bd95e366
--- /dev/null
+++ b/Build/source/utils/asymptote/fundec.h
@@ -0,0 +1,138 @@
+/*****
+ * fundec.h
+ * Andy Hammerlindl 2002/8/29
+ *
+ * Defines the semantics for defining functions. Both the newexp syntax, and
+ * the abbreviated C-style function definition.
+ *****/
+
+#ifndef FUNDEC_H
+#define FUNDEC_H
+
+#include "dec.h"
+#include "exp.h"
+
+namespace absyntax {
+
+class formal : public absyn {
+ ty *base;
+ decidstart *start;
+ bool Explicit;
+ varinit *defval;
+
+public:
+ formal(position pos, ty *base, decidstart *start=0, varinit *defval=0,
+ bool Explicit= false)
+ : absyn(pos), base(base), start(start), Explicit(Explicit),
+ defval(defval) {}
+
+ virtual void prettyprint(ostream &out, Int indent);
+
+ // Build the corresponding types::formal to put into a signature.
+ types::formal trans(coenv &e, bool encodeDefVal, bool tacit=false);
+
+ // Add the formal parameter to the environment to prepare for the
+ // function body's translation.
+ virtual void transAsVar(coenv &e, Int index);
+
+ types::ty *getType(coenv &e, bool tacit=false);
+
+ virtual void addOps(coenv &e, record *r);
+
+ varinit *getDefaultValue() {
+ return defval;
+ }
+
+ symbol *getName() {
+ return start ? start->getName() : 0;
+ }
+
+ bool getExplicit() {
+ return Explicit;
+ }
+};
+
+class formals : public absyn {
+ //friend class funheader;
+
+ mem::list<formal *> fields;
+ formal *rest;
+
+ void addToSignature(types::signature& sig,
+ coenv &e, bool encodeDefVal, bool tacit);
+public:
+ formals(position pos)
+ : absyn(pos), rest(0) {}
+
+ virtual ~formals() {}
+
+ virtual void prettyprint(ostream &out, Int indent);
+
+ virtual void add(formal *f) {
+ fields.push_back(f);
+ }
+
+ virtual void addRest(formal *f) {
+ rest = f;
+ }
+
+ // Returns the types of each parameter as a signature.
+ // encodeDefVal means that it will also encode information regarding
+ // the default values into the signature
+ types::signature *getSignature(coenv &e,
+ bool encodeDefVal = false,
+ bool tacit = false);
+
+ // Returns the corresponding function type, assuming it has a return
+ // value of "result."
+ types::function *getType(types::ty *result, coenv &e,
+ bool encodeDefVal = false,
+ bool tacit = false);
+
+ virtual void addOps(coenv &e, record *r);
+
+ // Add the formal parameters to the environment to prepare for the
+ // function body's translation.
+ virtual void trans(coenv &e);
+};
+
+class fundef : public exp {
+ ty *result;
+ formals *params;
+ stm *body;
+
+public:
+ fundef(position pos, ty *result, formals *params, stm *body)
+ : exp(pos), result(result), params(params), body(body) {}
+
+ virtual void prettyprint(ostream &out, Int indent);
+
+ varinit *makeVarInit(types::function *ft);
+ virtual void baseTrans(coenv &e, types::function *ft);
+ virtual types::ty *trans(coenv &e);
+
+ virtual types::function *transType(coenv &e, bool tacit);
+ virtual types::function *transTypeAndAddOps(coenv &e, record *r, bool tacit);
+ virtual types::ty *getType(coenv &e) {
+ return transType(e, true);
+ }
+};
+
+class fundec : public dec {
+ symbol *id;
+ fundef fun;
+
+public:
+ fundec(position pos, ty *result, symbol *id, formals *params, stm *body)
+ : dec(pos), id(id), fun(pos, result, params, body) {}
+
+ void prettyprint(ostream &out, Int indent);
+
+ void trans(coenv &e);
+
+ void transAsField(coenv &e, record *r);
+};
+
+} // namespace absyntax
+
+#endif
diff --git a/Build/source/utils/asymptote/genv.cc b/Build/source/utils/asymptote/genv.cc
new file mode 100644
index 00000000000..bb0a325d6b5
--- /dev/null
+++ b/Build/source/utils/asymptote/genv.cc
@@ -0,0 +1,120 @@
+/*****
+ * genv.cc
+ * Andy Hammerlindl 2002/08/29
+ *
+ * This is the global environment for the translation of programs. In
+ * actuality, it is basically a module manager. When a module is
+ * requested, it looks for the corresponding filename, and if found,
+ * parses and translates the file, returning the resultant module.
+ *
+ * genv sets up the basic type bindings and function bindings for
+ * builtin functions, casts and operators, and imports plain (if set),
+ * but all other initialization is done by the local environment defined
+ * in env.h.
+ *****/
+
+#include <sstream>
+#include <unistd.h>
+#include <bits/stl_algo.h>
+
+#include "genv.h"
+#include "env.h"
+#include "dec.h"
+#include "stm.h"
+#include "types.h"
+#include "settings.h"
+#include "runtime.h"
+#include "parser.h"
+#include "locate.h"
+#include "interact.h"
+#include "builtin.h"
+
+using namespace types;
+using settings::getSetting;
+using settings::Setting;
+
+
+namespace trans {
+
+genv::genv()
+ : imap()
+{
+ // Add settings as a module. This is so that the init file ~/.asy/config.asy
+ // can set settings.
+ imap["settings"]=settings::getSettingsModule();
+
+ // Translate plain in advance, if we're using autoplain.
+ if(getSetting<bool>("autoplain")) {
+ Setting("autoplain")=false;
+
+ // Translate plain without autoplain.
+ getModule(symbol::trans("plain"), "plain");
+
+ Setting("autoplain")=true;
+ }
+#ifdef HAVE_LIBGSL
+ imap["gsl"]=trans::getGSLModule();
+#endif
+}
+
+record *genv::loadModule(symbol *id, string filename) {
+ // Get the abstract syntax tree.
+ absyntax::file *ast = parser::parseFile(filename,"Loading");
+
+ inTranslation.push_front(filename);
+
+ em.sync();
+
+ record *r=ast->transAsFile(*this, id);
+
+ inTranslation.remove(filename);
+
+ return r;
+}
+
+void genv::checkRecursion(string filename) {
+ if (find(inTranslation.begin(), inTranslation.end(), filename) !=
+ inTranslation.end()) {
+ em.sync();
+ em << "error: recursive loading of module '" << filename << "'\n";
+ em.sync();
+ throw handled_error();
+ }
+}
+
+record *genv::getModule(symbol *id, string filename) {
+ checkRecursion(filename);
+
+ record *r=imap[filename];
+ if (r)
+ return r;
+ else {
+ record *r=loadModule(id, filename);
+ // Don't add an erroneous module to the dictionary in interactive mode, as
+ // the user may try to load it again.
+ if (!interact::interactive || !em.errors())
+ imap[filename]=r;
+
+ return r;
+ }
+
+}
+
+typedef vm::stack::importInitMap importInitMap;
+
+importInitMap *genv::getInitMap()
+{
+ struct initMap : public importInitMap, public gc {
+ genv &ge;
+ initMap(genv &ge)
+ : ge(ge) {}
+ lambda *operator[](string s) {
+ record *r=ge.imap[s];
+ return r ? r->getInit() : 0;
+ }
+ };
+
+ return new initMap(*this);
+}
+
+} // namespace trans
diff --git a/Build/source/utils/asymptote/genv.h b/Build/source/utils/asymptote/genv.h
new file mode 100644
index 00000000000..051b7b6e030
--- /dev/null
+++ b/Build/source/utils/asymptote/genv.h
@@ -0,0 +1,61 @@
+/*****
+ * genv.h
+ * Andy Hammerlindl 2002/08/29
+ *
+ * This is the global environment for the translation of programs. In
+ * actuality, it is basically a module manager. When a module is
+ * requested, it looks for the corresponding filename, and if found,
+ * parses and translates the file, returning the resultant module.
+ *
+ * genv sets up the basic type bindings and function bindings for
+ * builtin functions, casts and operators, and imports plain (if set),
+ * but all other initialization, is done by the local environmet defined
+ * in env.h.
+ *****/
+
+#ifndef GENV_H
+#define GENV_H
+
+#include "common.h"
+#include "table.h"
+#include "record.h"
+#include "absyn.h"
+#include "access.h"
+#include "coenv.h"
+#include "stack.h"
+
+using types::record;
+using vm::lambda;
+
+namespace trans {
+
+class genv {
+ // The initializer functions for imports, indexed by filename.
+ typedef mem::map<CONST string,record *> importMap;
+ importMap imap;
+
+ // List of modules in translation. Used to detect and prevent infinite
+ // recursion in loading modules.
+ mem::list<string> inTranslation;
+
+ // Checks for recursion in loading, reporting an error and throwing an
+ // exception if it occurs.
+ void checkRecursion(string filename);
+
+ // Translate a module to build the record type.
+ record *loadModule(symbol *name, string s);
+
+public:
+ genv();
+
+ // Get an imported module, translating if necessary.
+ record *getModule(symbol *name, string s);
+
+ // Uses the filename->record map to build a filename->initializer map to be
+ // used at runtime.
+ vm::stack::importInitMap *getInitMap();
+};
+
+} // namespace trans
+
+#endif
diff --git a/Build/source/utils/asymptote/getopt.c b/Build/source/utils/asymptote/getopt.c
new file mode 100644
index 00000000000..9bafa453c62
--- /dev/null
+++ b/Build/source/utils/asymptote/getopt.c
@@ -0,0 +1,1055 @@
+/* Getopt for GNU.
+ NOTE: getopt is now part of the C library, so if you don't know what
+ "Keep this file name-space clean" means, talk to drepper@gnu.org
+ before changing it!
+ Copyright (C) 1987,88,89,90,91,92,93,94,95,96,98,99,2000,2001
+ Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C 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.
+
+ The GNU C 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 the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/* This tells Alpha OSF/1 not to define a getopt prototype in <stdio.h>.
+ Ditto for AIX 3.2 and <stdlib.h>. */
+#ifndef _NO_PROTO
+# define _NO_PROTO
+#endif
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#if !defined __STDC__ || !__STDC__
+/* This is a separate conditional since some stdc systems
+ reject `defined (const)'. */
+# ifndef const
+# define const
+# endif
+#endif
+
+#include <stdio.h>
+
+/* Comment out all this code if we are using the GNU C Library, and are not
+ actually compiling the library itself. This code is part of the GNU C
+ Library, but also included in many other GNU distributions. Compiling
+ and linking in this code is a waste when using the GNU C library
+ (especially if it is a shared library). Rather than having every GNU
+ program understand `configure --with-gnu-libc' and omit the object files,
+ it is simpler to just do this in the source for each such file. */
+
+#define GETOPT_INTERFACE_VERSION 2
+#if !defined _LIBC && defined __GLIBC__ && __GLIBC__ >= 2
+# include <gnu-versions.h>
+# if _GNU_GETOPT_INTERFACE_VERSION == GETOPT_INTERFACE_VERSION
+# define ELIDE_CODE
+# endif
+#endif
+
+#ifndef ELIDE_CODE
+
+
+/* This needs to come after some library #include
+ to get __GNU_LIBRARY__ defined. */
+#ifdef __GNU_LIBRARY__
+/* Don't include stdlib.h for non-GNU C libraries because some of them
+ contain conflicting prototypes for getopt. */
+# include <stdlib.h>
+# include <unistd.h>
+#endif /* GNU C library. */
+
+#ifdef VMS
+# include <unixlib.h>
+# if HAVE_STRING_H - 0
+# include <string.h>
+# endif
+#endif
+
+#ifndef _
+/* This is for other GNU distributions with internationalized messages. */
+# if defined HAVE_LIBINTL_H || defined _LIBC
+# include <libintl.h>
+# ifndef _
+# define _(msgid) gettext (msgid)
+# endif
+# else
+# define _(msgid) (msgid)
+# endif
+#endif
+
+/* This version of `getopt' appears to the caller like standard Unix `getopt'
+ but it behaves differently for the user, since it allows the user
+ to intersperse the options with the other arguments.
+
+ As `getopt' works, it permutes the elements of ARGV so that,
+ when it is done, all the options precede everything else. Thus
+ all application programs are extended to handle flexible argument order.
+
+ Setting the environment variable POSIXLY_CORRECT disables permutation.
+ Then the behavior is completely standard.
+
+ GNU application programs can use a third alternative mode in which
+ they can distinguish the relative order of options and other arguments. */
+
+#include "getopt.h"
+
+/* For communication from `getopt' to the caller.
+ When `getopt' finds an option that takes an argument,
+ the argument value is returned here.
+ Also, when `ordering' is RETURN_IN_ORDER,
+ each non-option ARGV-element is returned here. */
+
+char *optarg;
+
+/* Index in ARGV of the next element to be scanned.
+ This is used for communication to and from the caller
+ and for communication between successive calls to `getopt'.
+
+ On entry to `getopt', zero means this is the first call; initialize.
+
+ When `getopt' returns -1, this is the index of the first of the
+ non-option elements that the caller should itself scan.
+
+ Otherwise, `optind' communicates from one call to the next
+ how much of ARGV has been scanned so far. */
+
+/* 1003.2 says this must be 1 before any call. */
+int optind = 1;
+
+/* Formerly, initialization of getopt depended on optind==0, which
+ causes problems with re-calling getopt as programs generally don't
+ know that. */
+
+int __getopt_initialized;
+
+/* The next char to be scanned in the option-element
+ in which the last option character we returned was found.
+ This allows us to pick up the scan where we left off.
+
+ If this is zero, or a null string, it means resume the scan
+ by advancing to the next ARGV-element. */
+
+static char *nextchar;
+
+/* Callers store zero here to inhibit the error message
+ for unrecognized options. */
+
+int opterr = 1;
+
+/* Set to an option character which was unrecognized.
+ This must be initialized on some systems to avoid linking in the
+ system's own getopt implementation. */
+
+int optopt = '?';
+
+/* Describe how to deal with options that follow non-option ARGV-elements.
+
+ If the caller did not specify anything,
+ the default is REQUIRE_ORDER if the environment variable
+ POSIXLY_CORRECT is defined, PERMUTE otherwise.
+
+ REQUIRE_ORDER means don't recognize them as options;
+ stop option processing when the first non-option is seen.
+ This is what Unix does.
+ This mode of operation is selected by either setting the environment
+ variable POSIXLY_CORRECT, or using `+' as the first character
+ of the list of option characters.
+
+ PERMUTE is the default. We permute the contents of ARGV as we scan,
+ so that eventually all the non-options are at the end. This allows options
+ to be given in any order, even with programs that were not written to
+ expect this.
+
+ RETURN_IN_ORDER is an option available to programs that were written
+ to expect options and other ARGV-elements in any order and that care about
+ the ordering of the two. We describe each non-option ARGV-element
+ as if it were the argument of an option with character code 1.
+ Using `-' as the first character of the list of option characters
+ selects this mode of operation.
+
+ The special argument `--' forces an end of option-scanning regardless
+ of the value of `ordering'. In the case of RETURN_IN_ORDER, only
+ `--' can cause `getopt' to return -1 with `optind' != ARGC. */
+
+static enum
+{
+ REQUIRE_ORDER, PERMUTE, RETURN_IN_ORDER
+} ordering;
+
+/* Value of POSIXLY_CORRECT environment variable. */
+static char *posixly_correct;
+
+#ifdef __GNU_LIBRARY__
+/* We want to avoid inclusion of string.h with non-GNU libraries
+ because there are many ways it can cause trouble.
+ On some systems, it contains special magic macros that don't work
+ in GCC. */
+# include <string.h>
+# define my_index strchr
+#else
+
+# if HAVE_STRING_H
+# include <string.h>
+# else
+# include <strings.h>
+# endif
+
+/* Avoid depending on library functions or files
+ whose names are inconsistent. */
+
+#ifndef getenv
+extern char *getenv ();
+#endif
+
+static char *
+my_index (str, chr)
+ const char *str;
+ int chr;
+{
+ while (*str)
+ {
+ if (*str == chr)
+ return (char *) str;
+ str++;
+ }
+ return 0;
+}
+
+/* If using GCC, we can safely declare strlen this way.
+ If not using GCC, it is ok not to declare it. */
+#ifdef __GNUC__
+/* Note that Motorola Delta 68k R3V7 comes with GCC but not stddef.h.
+ That was relevant to code that was here before. */
+# if (!defined __STDC__ || !__STDC__) && !defined strlen
+/* gcc with -traditional declares the built-in strlen to return int,
+ and has done so at least since version 2.4.5. -- rms. */
+extern int strlen (const char *);
+# endif /* not __STDC__ */
+#endif /* __GNUC__ */
+
+#endif /* not __GNU_LIBRARY__ */
+
+/* Handle permutation of arguments. */
+
+/* Describe the part of ARGV that contains non-options that have
+ been skipped. `first_nonopt' is the index in ARGV of the first of them;
+ `last_nonopt' is the index after the last of them. */
+
+static int first_nonopt;
+static int last_nonopt;
+
+#ifdef _LIBC
+/* Stored original parameters.
+ XXX This is no good solution. We should rather copy the args so
+ that we can compare them later. But we must not use malloc(3). */
+extern int __libc_argc;
+extern char **__libc_argv;
+
+/* Bash 2.0 gives us an environment variable containing flags
+ indicating ARGV elements that should not be considered arguments. */
+
+# ifdef USE_NONOPTION_FLAGS
+/* Defined in getopt_init.c */
+extern char *__getopt_nonoption_flags;
+
+static int nonoption_flags_max_len;
+static int nonoption_flags_len;
+# endif
+
+# ifdef USE_NONOPTION_FLAGS
+# define SWAP_FLAGS(ch1, ch2) \
+ if (nonoption_flags_len > 0) \
+ { \
+ char __tmp = __getopt_nonoption_flags[ch1]; \
+ __getopt_nonoption_flags[ch1] = __getopt_nonoption_flags[ch2]; \
+ __getopt_nonoption_flags[ch2] = __tmp; \
+ }
+# else
+# define SWAP_FLAGS(ch1, ch2)
+# endif
+#else /* !_LIBC */
+# define SWAP_FLAGS(ch1, ch2)
+#endif /* _LIBC */
+
+/* Exchange two adjacent subsequences of ARGV.
+ One subsequence is elements [first_nonopt,last_nonopt)
+ which contains all the non-options that have been skipped so far.
+ The other is elements [last_nonopt,optind), which contains all
+ the options processed since those non-options were skipped.
+
+ `first_nonopt' and `last_nonopt' are relocated so that they describe
+ the new indices of the non-options in ARGV after they are moved. */
+
+#if defined __STDC__ && __STDC__
+static void exchange (char **);
+#endif
+
+static void
+exchange (argv)
+ char **argv;
+{
+ int bottom = first_nonopt;
+ int middle = last_nonopt;
+ int top = optind;
+ char *tem;
+
+ /* Exchange the shorter segment with the far end of the longer segment.
+ That puts the shorter segment into the right place.
+ It leaves the longer segment in the right place overall,
+ but it consists of two parts that need to be swapped next. */
+
+#if defined _LIBC && defined USE_NONOPTION_FLAGS
+ /* First make sure the handling of the `__getopt_nonoption_flags'
+ string can work normally. Our top argument must be in the range
+ of the string. */
+ if (nonoption_flags_len > 0 && top >= nonoption_flags_max_len)
+ {
+ /* We must extend the array. The user plays games with us and
+ presents new arguments. */
+ char *new_str = malloc (top + 1);
+ if (new_str == NULL)
+ nonoption_flags_len = nonoption_flags_max_len = 0;
+ else
+ {
+ memset (__mempcpy (new_str, __getopt_nonoption_flags,
+ nonoption_flags_max_len),
+ '\0', top + 1 - nonoption_flags_max_len);
+ nonoption_flags_max_len = top + 1;
+ __getopt_nonoption_flags = new_str;
+ }
+ }
+#endif
+
+ while (top > middle && middle > bottom)
+ {
+ if (top - middle > middle - bottom)
+ {
+ /* Bottom segment is the short one. */
+ int len = middle - bottom;
+ register int i;
+
+ /* Swap it with the top part of the top segment. */
+ for (i = 0; i < len; i++)
+ {
+ tem = argv[bottom + i];
+ argv[bottom + i] = argv[top - (middle - bottom) + i];
+ argv[top - (middle - bottom) + i] = tem;
+ SWAP_FLAGS (bottom + i, top - (middle - bottom) + i);
+ }
+ /* Exclude the moved bottom segment from further swapping. */
+ top -= len;
+ }
+ else
+ {
+ /* Top segment is the short one. */
+ int len = top - middle;
+ register int i;
+
+ /* Swap it with the bottom part of the bottom segment. */
+ for (i = 0; i < len; i++)
+ {
+ tem = argv[bottom + i];
+ argv[bottom + i] = argv[middle + i];
+ argv[middle + i] = tem;
+ SWAP_FLAGS (bottom + i, middle + i);
+ }
+ /* Exclude the moved top segment from further swapping. */
+ bottom += len;
+ }
+ }
+
+ /* Update records for the slots the non-options now occupy. */
+
+ first_nonopt += (optind - last_nonopt);
+ last_nonopt = optind;
+}
+
+/* Initialize the internal data when the first call is made. */
+
+#if defined __STDC__ && __STDC__
+static const char *_getopt_initialize (int, char *const *, const char *);
+#endif
+static const char *
+_getopt_initialize (argc, argv, optstring)
+ int argc;
+ char *const *argv;
+ const char *optstring;
+{
+ /* Start processing options with ARGV-element 1 (since ARGV-element 0
+ is the program name); the sequence of previously skipped
+ non-option ARGV-elements is empty. */
+
+ first_nonopt = last_nonopt = optind;
+
+ nextchar = NULL;
+
+ posixly_correct = getenv ("POSIXLY_CORRECT");
+
+ /* Determine how to handle the ordering of options and nonoptions. */
+
+ if (optstring[0] == '-')
+ {
+ ordering = RETURN_IN_ORDER;
+ ++optstring;
+ }
+ else if (optstring[0] == '+')
+ {
+ ordering = REQUIRE_ORDER;
+ ++optstring;
+ }
+ else if (posixly_correct != NULL)
+ ordering = REQUIRE_ORDER;
+ else
+ ordering = PERMUTE;
+
+#if defined _LIBC && defined USE_NONOPTION_FLAGS
+ if (posixly_correct == NULL
+ && argc == __libc_argc && argv == __libc_argv)
+ {
+ if (nonoption_flags_max_len == 0)
+ {
+ if (__getopt_nonoption_flags == NULL
+ || __getopt_nonoption_flags[0] == '\0')
+ nonoption_flags_max_len = -1;
+ else
+ {
+ const char *orig_str = __getopt_nonoption_flags;
+ int len = nonoption_flags_max_len = strlen (orig_str);
+ if (nonoption_flags_max_len < argc)
+ nonoption_flags_max_len = argc;
+ __getopt_nonoption_flags =
+ (char *) malloc (nonoption_flags_max_len);
+ if (__getopt_nonoption_flags == NULL)
+ nonoption_flags_max_len = -1;
+ else
+ memset (__mempcpy (__getopt_nonoption_flags, orig_str, len),
+ '\0', nonoption_flags_max_len - len);
+ }
+ }
+ nonoption_flags_len = nonoption_flags_max_len;
+ }
+ else
+ nonoption_flags_len = 0;
+#endif
+
+ return optstring;
+}
+
+/* Scan elements of ARGV (whose length is ARGC) for option characters
+ given in OPTSTRING.
+
+ If an element of ARGV starts with '-', and is not exactly "-" or "--",
+ then it is an option element. The characters of this element
+ (aside from the initial '-') are option characters. If `getopt'
+ is called repeatedly, it returns successively each of the option characters
+ from each of the option elements.
+
+ If `getopt' finds another option character, it returns that character,
+ updating `optind' and `nextchar' so that the next call to `getopt' can
+ resume the scan with the following option character or ARGV-element.
+
+ If there are no more option characters, `getopt' returns -1.
+ Then `optind' is the index in ARGV of the first ARGV-element
+ that is not an option. (The ARGV-elements have been permuted
+ so that those that are not options now come last.)
+
+ OPTSTRING is a string containing the legitimate option characters.
+ If an option character is seen that is not listed in OPTSTRING,
+ return '?' after printing an error message. If you set `opterr' to
+ zero, the error message is suppressed but we still return '?'.
+
+ If a char in OPTSTRING is followed by a colon, that means it wants an arg,
+ so the following text in the same ARGV-element, or the text of the following
+ ARGV-element, is returned in `optarg'. Two colons mean an option that
+ wants an optional arg; if there is text in the current ARGV-element,
+ it is returned in `optarg', otherwise `optarg' is set to zero.
+
+ If OPTSTRING starts with `-' or `+', it requests different methods of
+ handling the non-option ARGV-elements.
+ See the comments about RETURN_IN_ORDER and REQUIRE_ORDER, above.
+
+ Long-named options begin with `--' instead of `-'.
+ Their names may be abbreviated as long as the abbreviation is unique
+ or is an exact match for some defined option. If they have an
+ argument, it follows the option name in the same ARGV-element, separated
+ from the option name by a `=', or else the in next ARGV-element.
+ When `getopt' finds a long-named option, it returns 0 if that option's
+ `flag' field is nonzero, the value of the option's `val' field
+ if the `flag' field is zero.
+
+ The elements of ARGV aren't really const, because we permute them.
+ But we pretend they're const in the prototype to be compatible
+ with other systems.
+
+ LONGOPTS is a vector of `struct option' terminated by an
+ element containing a name which is zero.
+
+ LONGIND returns the index in LONGOPT of the long-named option found.
+ It is only valid when a long-named option has been found by the most
+ recent call.
+
+ If LONG_ONLY is nonzero, '-' as well as '--' can introduce
+ long-named options. */
+
+int
+_getopt_internal (argc, argv, optstring, longopts, longind, long_only)
+ int argc;
+ char *const *argv;
+ const char *optstring;
+ const struct option *longopts;
+ int *longind;
+ int long_only;
+{
+ int print_errors = opterr;
+ if (optstring[0] == ':')
+ print_errors = 0;
+
+ if (argc < 1)
+ return -1;
+
+ optarg = NULL;
+
+ if (optind == 0 || !__getopt_initialized)
+ {
+ if (optind == 0)
+ optind = 1; /* Don't scan ARGV[0], the program name. */
+ optstring = _getopt_initialize (argc, argv, optstring);
+ __getopt_initialized = 1;
+ }
+
+ /* Test whether ARGV[optind] points to a non-option argument.
+ Either it does not have option syntax, or there is an environment flag
+ from the shell indicating it is not an option. The later information
+ is only used when the used in the GNU libc. */
+#if defined _LIBC && defined USE_NONOPTION_FLAGS
+# define NONOPTION_P (argv[optind][0] != '-' || argv[optind][1] == '\0' \
+ || (optind < nonoption_flags_len \
+ && __getopt_nonoption_flags[optind] == '1'))
+#else
+# define NONOPTION_P (argv[optind][0] != '-' || argv[optind][1] == '\0')
+#endif
+
+ if (nextchar == NULL || *nextchar == '\0')
+ {
+ /* Advance to the next ARGV-element. */
+
+ /* Give FIRST_NONOPT & LAST_NONOPT rational values if OPTIND has been
+ moved back by the user (who may also have changed the arguments). */
+ if (last_nonopt > optind)
+ last_nonopt = optind;
+ if (first_nonopt > optind)
+ first_nonopt = optind;
+
+ if (ordering == PERMUTE)
+ {
+ /* If we have just processed some options following some non-options,
+ exchange them so that the options come first. */
+
+ if (first_nonopt != last_nonopt && last_nonopt != optind)
+ exchange ((char **) argv);
+ else if (last_nonopt != optind)
+ first_nonopt = optind;
+
+ /* Skip any additional non-options
+ and extend the range of non-options previously skipped. */
+
+ while (optind < argc && NONOPTION_P)
+ optind++;
+ last_nonopt = optind;
+ }
+
+ /* The special ARGV-element `--' means premature end of options.
+ Skip it like a null option,
+ then exchange with previous non-options as if it were an option,
+ then skip everything else like a non-option. */
+
+ if (optind != argc && !strcmp (argv[optind], "--"))
+ {
+ optind++;
+
+ if (first_nonopt != last_nonopt && last_nonopt != optind)
+ exchange ((char **) argv);
+ else if (first_nonopt == last_nonopt)
+ first_nonopt = optind;
+ last_nonopt = argc;
+
+ optind = argc;
+ }
+
+ /* If we have done all the ARGV-elements, stop the scan
+ and back over any non-options that we skipped and permuted. */
+
+ if (optind == argc)
+ {
+ /* Set the next-arg-index to point at the non-options
+ that we previously skipped, so the caller will digest them. */
+ if (first_nonopt != last_nonopt)
+ optind = first_nonopt;
+ return -1;
+ }
+
+ /* If we have come to a non-option and did not permute it,
+ either stop the scan or describe it to the caller and pass it by. */
+
+ if (NONOPTION_P)
+ {
+ if (ordering == REQUIRE_ORDER)
+ return -1;
+ optarg = argv[optind++];
+ return 1;
+ }
+
+ /* We have found another option-ARGV-element.
+ Skip the initial punctuation. */
+
+ nextchar = (argv[optind] + 1
+ + (longopts != NULL && argv[optind][1] == '-'));
+ }
+
+ /* Decode the current option-ARGV-element. */
+
+ /* Check whether the ARGV-element is a long option.
+
+ If long_only and the ARGV-element has the form "-f", where f is
+ a valid short option, don't consider it an abbreviated form of
+ a long option that starts with f. Otherwise there would be no
+ way to give the -f short option.
+
+ On the other hand, if there's a long option "fubar" and
+ the ARGV-element is "-fu", do consider that an abbreviation of
+ the long option, just like "--fu", and not "-f" with arg "u".
+
+ This distinction seems to be the most useful approach. */
+
+ if (longopts != NULL
+ && (argv[optind][1] == '-'
+ || (long_only && (argv[optind][2] || !my_index (optstring, argv[optind][1])))))
+ {
+ char *nameend;
+ const struct option *p;
+ const struct option *pfound = NULL;
+ int exact = 0;
+ int ambig = 0;
+ int indfound = -1;
+ int option_index;
+
+ for (nameend = nextchar; *nameend && *nameend != '='; nameend++)
+ /* Do nothing. */ ;
+
+ /* Test all long options for either exact match
+ or abbreviated matches. */
+ for (p = longopts, option_index = 0; p->name; p++, option_index++)
+ if (!strncmp (p->name, nextchar, nameend - nextchar))
+ {
+ if ((unsigned int) (nameend - nextchar)
+ == (unsigned int) strlen (p->name))
+ {
+ /* Exact match found. */
+ pfound = p;
+ indfound = option_index;
+ exact = 1;
+ break;
+ }
+ else if (pfound == NULL)
+ {
+ /* First nonexact match found. */
+ pfound = p;
+ indfound = option_index;
+ }
+ else if (long_only
+ || pfound->has_arg != p->has_arg
+ || pfound->flag != p->flag
+ || pfound->val != p->val)
+ /* Second or later nonexact match found. */
+ ambig = 1;
+ }
+
+ if (ambig && !exact)
+ {
+ if (print_errors)
+ fprintf (stderr, _("%s: option `%s' is ambiguous\n"),
+ argv[0], argv[optind]);
+ nextchar += strlen (nextchar);
+ optind++;
+ optopt = 0;
+ return '?';
+ }
+
+ if (pfound != NULL)
+ {
+ option_index = indfound;
+ optind++;
+ if (*nameend)
+ {
+ /* Don't test has_arg with >, because some C compilers don't
+ allow it to be used on enums. */
+ if (pfound->has_arg)
+ optarg = nameend + 1;
+ else
+ {
+ if (print_errors)
+ {
+ if (argv[optind - 1][1] == '-')
+ /* --option */
+ fprintf (stderr,
+ _("%s: option `--%s' doesn't allow an argument\n"),
+ argv[0], pfound->name);
+ else
+ /* +option or -option */
+ fprintf (stderr,
+ _("%s: option `%c%s' doesn't allow an argument\n"),
+ argv[0], argv[optind - 1][0], pfound->name);
+ }
+
+ nextchar += strlen (nextchar);
+
+ optopt = pfound->val;
+ return '?';
+ }
+ }
+ else if (pfound->has_arg == 1)
+ {
+ if (optind < argc)
+ optarg = argv[optind++];
+ else
+ {
+ if (print_errors)
+ fprintf (stderr,
+ _("%s: option `%s' requires an argument\n"),
+ argv[0], argv[optind - 1]);
+ nextchar += strlen (nextchar);
+ optopt = pfound->val;
+ return optstring[0] == ':' ? ':' : '?';
+ }
+ }
+ nextchar += strlen (nextchar);
+ if (longind != NULL)
+ *longind = option_index;
+ if (pfound->flag)
+ {
+ *(pfound->flag) = pfound->val;
+ return 0;
+ }
+ return pfound->val;
+ }
+
+ /* Can't find it as a long option. If this is not getopt_long_only,
+ or the option starts with '--' or is not a valid short
+ option, then it's an error.
+ Otherwise interpret it as a short option. */
+ if (!long_only || argv[optind][1] == '-'
+ || my_index (optstring, *nextchar) == NULL)
+ {
+ if (print_errors)
+ {
+ if (argv[optind][1] == '-')
+ /* --option */
+ fprintf (stderr, _("%s: unrecognized option `--%s'\n"),
+ argv[0], nextchar);
+ else
+ /* +option or -option */
+ fprintf (stderr, _("%s: unrecognized option `%c%s'\n"),
+ argv[0], argv[optind][0], nextchar);
+ }
+ nextchar = (char *) "";
+ optind++;
+ optopt = 0;
+ return '?';
+ }
+ }
+
+ /* Look at and handle the next short option-character. */
+
+ {
+ char c = *nextchar++;
+ char *temp = my_index (optstring, c);
+
+ /* Increment `optind' when we start to process its last character. */
+ if (*nextchar == '\0')
+ ++optind;
+
+ if (temp == NULL || c == ':')
+ {
+ if (print_errors)
+ {
+ if (posixly_correct)
+ /* 1003.2 specifies the format of this message. */
+ fprintf (stderr, _("%s: illegal option -- %c\n"),
+ argv[0], c);
+ else
+ fprintf (stderr, _("%s: invalid option -- %c\n"),
+ argv[0], c);
+ }
+ optopt = c;
+ return '?';
+ }
+ /* Convenience. Treat POSIX -W foo same as long option --foo */
+ if (temp[0] == 'W' && temp[1] == ';')
+ {
+ char *nameend;
+ const struct option *p;
+ const struct option *pfound = NULL;
+ int exact = 0;
+ int ambig = 0;
+ int indfound = 0;
+ int option_index;
+
+ /* This is an option that requires an argument. */
+ if (*nextchar != '\0')
+ {
+ optarg = nextchar;
+ /* If we end this ARGV-element by taking the rest as an arg,
+ we must advance to the next element now. */
+ optind++;
+ }
+ else if (optind == argc)
+ {
+ if (print_errors)
+ {
+ /* 1003.2 specifies the format of this message. */
+ fprintf (stderr, _("%s: option requires an argument -- %c\n"),
+ argv[0], c);
+ }
+ optopt = c;
+ if (optstring[0] == ':')
+ c = ':';
+ else
+ c = '?';
+ return c;
+ }
+ else
+ /* We already incremented `optind' once;
+ increment it again when taking next ARGV-elt as argument. */
+ optarg = argv[optind++];
+
+ /* optarg is now the argument, see if it's in the
+ table of longopts. */
+
+ for (nextchar = nameend = optarg; *nameend && *nameend != '='; nameend++)
+ /* Do nothing. */ ;
+
+ /* Test all long options for either exact match
+ or abbreviated matches. */
+ for (p = longopts, option_index = 0; p->name; p++, option_index++)
+ if (!strncmp (p->name, nextchar, nameend - nextchar))
+ {
+ if ((unsigned int) (nameend - nextchar) == strlen (p->name))
+ {
+ /* Exact match found. */
+ pfound = p;
+ indfound = option_index;
+ exact = 1;
+ break;
+ }
+ else if (pfound == NULL)
+ {
+ /* First nonexact match found. */
+ pfound = p;
+ indfound = option_index;
+ }
+ else
+ /* Second or later nonexact match found. */
+ ambig = 1;
+ }
+ if (ambig && !exact)
+ {
+ if (print_errors)
+ fprintf (stderr, _("%s: option `-W %s' is ambiguous\n"),
+ argv[0], argv[optind]);
+ nextchar += strlen (nextchar);
+ optind++;
+ return '?';
+ }
+ if (pfound != NULL)
+ {
+ option_index = indfound;
+ if (*nameend)
+ {
+ /* Don't test has_arg with >, because some C compilers don't
+ allow it to be used on enums. */
+ if (pfound->has_arg)
+ optarg = nameend + 1;
+ else
+ {
+ if (print_errors)
+ fprintf (stderr, _("\
+%s: option `-W %s' doesn't allow an argument\n"),
+ argv[0], pfound->name);
+
+ nextchar += strlen (nextchar);
+ return '?';
+ }
+ }
+ else if (pfound->has_arg == 1)
+ {
+ if (optind < argc)
+ optarg = argv[optind++];
+ else
+ {
+ if (print_errors)
+ fprintf (stderr,
+ _("%s: option `%s' requires an argument\n"),
+ argv[0], argv[optind - 1]);
+ nextchar += strlen (nextchar);
+ return optstring[0] == ':' ? ':' : '?';
+ }
+ }
+ nextchar += strlen (nextchar);
+ if (longind != NULL)
+ *longind = option_index;
+ if (pfound->flag)
+ {
+ *(pfound->flag) = pfound->val;
+ return 0;
+ }
+ return pfound->val;
+ }
+ nextchar = NULL;
+ return 'W'; /* Let the application handle it. */
+ }
+ if (temp[1] == ':')
+ {
+ if (temp[2] == ':')
+ {
+ /* This is an option that accepts an argument optionally. */
+ if (*nextchar != '\0')
+ {
+ optarg = nextchar;
+ optind++;
+ }
+ else
+ optarg = NULL;
+ nextchar = NULL;
+ }
+ else
+ {
+ /* This is an option that requires an argument. */
+ if (*nextchar != '\0')
+ {
+ optarg = nextchar;
+ /* If we end this ARGV-element by taking the rest as an arg,
+ we must advance to the next element now. */
+ optind++;
+ }
+ else if (optind == argc)
+ {
+ if (print_errors)
+ {
+ /* 1003.2 specifies the format of this message. */
+ fprintf (stderr,
+ _("%s: option requires an argument -- %c\n"),
+ argv[0], c);
+ }
+ optopt = c;
+ if (optstring[0] == ':')
+ c = ':';
+ else
+ c = '?';
+ }
+ else
+ /* We already incremented `optind' once;
+ increment it again when taking next ARGV-elt as argument. */
+ optarg = argv[optind++];
+ nextchar = NULL;
+ }
+ }
+ return c;
+ }
+}
+
+int
+getopt (argc, argv, optstring)
+ int argc;
+ char *const *argv;
+ const char *optstring;
+{
+ return _getopt_internal (argc, argv, optstring,
+ (const struct option *) 0,
+ (int *) 0,
+ 0);
+}
+
+#endif /* Not ELIDE_CODE. */
+
+#ifdef TEST
+
+/* Compile with -DTEST to make an executable for use in testing
+ the above definition of `getopt'. */
+
+int
+main (argc, argv)
+ int argc;
+ char **argv;
+{
+ int c;
+ int digit_optind = 0;
+
+ while (1)
+ {
+ int this_option_optind = optind ? optind : 1;
+
+ c = getopt (argc, argv, "abc:d:0123456789");
+ if (c == -1)
+ break;
+
+ switch (c)
+ {
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ case '8':
+ case '9':
+ if (digit_optind != 0 && digit_optind != this_option_optind)
+ printf ("digits occur in two different argv-elements.\n");
+ digit_optind = this_option_optind;
+ printf ("option %c\n", c);
+ break;
+
+ case 'a':
+ printf ("option a\n");
+ break;
+
+ case 'b':
+ printf ("option b\n");
+ break;
+
+ case 'c':
+ printf ("option c with value `%s'\n", optarg);
+ break;
+
+ case '?':
+ break;
+
+ default:
+ printf ("?? getopt returned character code 0%o ??\n", c);
+ }
+ }
+
+ if (optind < argc)
+ {
+ printf ("non-option ARGV-elements: ");
+ while (optind < argc)
+ printf ("%s ", argv[optind++]);
+ printf ("\n");
+ }
+
+ exit (0);
+}
+
+#endif /* TEST */
diff --git a/Build/source/utils/asymptote/getopt.h b/Build/source/utils/asymptote/getopt.h
new file mode 100644
index 00000000000..06485480814
--- /dev/null
+++ b/Build/source/utils/asymptote/getopt.h
@@ -0,0 +1,180 @@
+/* Declarations for getopt.
+ Copyright (C) 1989-1994, 1996-1999, 2001 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C 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.
+
+ The GNU C 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 the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _GETOPT_H
+
+#ifndef __need_getopt
+# define _GETOPT_H 1
+#endif
+
+/* If __GNU_LIBRARY__ is not already defined, either we are being used
+ standalone, or this is the first header included in the source file.
+ If we are being used with glibc, we need to include <features.h>, but
+ that does not exist if we are standalone. So: if __GNU_LIBRARY__ is
+ not defined, include <ctype.h>, which will pull in <features.h> for us
+ if it's from glibc. (Why ctype.h? It's guaranteed to exist and it
+ doesn't flood the namespace with stuff the way some other headers do.) */
+#if !defined __GNU_LIBRARY__
+# include <ctype.h>
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* For communication from `getopt' to the caller.
+ When `getopt' finds an option that takes an argument,
+ the argument value is returned here.
+ Also, when `ordering' is RETURN_IN_ORDER,
+ each non-option ARGV-element is returned here. */
+
+ extern char *optarg;
+
+/* Index in ARGV of the next element to be scanned.
+ This is used for communication to and from the caller
+ and for communication between successive calls to `getopt'.
+
+ On entry to `getopt', zero means this is the first call; initialize.
+
+ When `getopt' returns -1, this is the index of the first of the
+ non-option elements that the caller should itself scan.
+
+ Otherwise, `optind' communicates from one call to the next
+ how much of ARGV has been scanned so far. */
+
+ extern int optind;
+
+/* Callers store zero here to inhibit the error message `getopt' prints
+ for unrecognized options. */
+
+ extern int opterr;
+
+/* Set to an option character which was unrecognized. */
+
+ extern int optopt;
+
+#ifndef __need_getopt
+/* Describe the long-named options requested by the application.
+ The LONG_OPTIONS argument to getopt_long or getopt_long_only is a vector
+ of `struct option' terminated by an element containing a name which is
+ zero.
+
+ The field `has_arg' is:
+ no_argument (or 0) if the option does not take an argument,
+ required_argument (or 1) if the option requires an argument,
+ optional_argument (or 2) if the option takes an optional argument.
+
+ If the field `flag' is not NULL, it points to a variable that is set
+ to the value given in the field `val' when the option is found, but
+ left unchanged if the option is not found.
+
+ To have a long-named option do something other than set an `int' to
+ a compiled-in constant, such as set a value from `optarg', set the
+ option's `flag' field to zero and its `val' field to a nonzero
+ value (the equivalent single-letter option character, if there is
+ one). For long options that have a zero `flag' field, `getopt'
+ returns the contents of the `val' field. */
+
+ struct option
+ {
+# if (defined __STDC__ && __STDC__) || defined __cplusplus
+ const char *name;
+# else
+ char *name;
+# endif
+ /* has_arg can't be an enum because some compilers complain about
+ type mismatches in all the code that assumes it is an int. */
+ int has_arg;
+ int *flag;
+ int val;
+ };
+
+/* Names for the values of the `has_arg' field of `struct option'. */
+
+# define no_argument 0
+# define required_argument 1
+# define optional_argument 2
+#endif /* need getopt */
+
+
+/* Get definitions and prototypes for functions to process the
+ arguments in ARGV (ARGC of them, minus the program name) for
+ options given in OPTS.
+
+ Return the option character from OPTS just read. Return -1 when
+ there are no more options. For unrecognized options, or options
+ missing arguments, `optopt' is set to the option letter, and '?' is
+ returned.
+
+ The OPTS string is a list of characters which are recognized option
+ letters, optionally followed by colons, specifying that that letter
+ takes an argument, to be placed in `optarg'.
+
+ If a letter in OPTS is followed by two colons, its argument is
+ optional. This behavior is specific to the GNU `getopt'.
+
+ The argument `--' causes premature termination of argument
+ scanning, explicitly telling `getopt' that there are no more
+ options.
+
+ If OPTS begins with `--', then non-option arguments are treated as
+ arguments to the option '\0'. This behavior is specific to the GNU
+ `getopt'. */
+
+#if (defined __STDC__ && __STDC__) || defined __cplusplus
+# ifdef __GNU_LIBRARY__
+/* Many other libraries have conflicting prototypes for getopt, with
+ differences in the consts, in stdlib.h. To avoid compilation
+ errors, only prototype getopt for the GNU C library. */
+ extern int getopt (int __argc, char *const *__argv, const char *__shortopts);
+# else /* not __GNU_LIBRARY__ */
+/* extern int getopt (); */
+# endif /* __GNU_LIBRARY__ */
+
+# ifndef __need_getopt
+ extern int getopt_long (int __argc, char *const *__argv, const char *__shortopts,
+ const struct option *__longopts, int *__longind);
+ extern int getopt_long_only (int __argc, char *const *__argv,
+ const char *__shortopts,
+ const struct option *__longopts, int *__longind);
+
+/* Internal only. Users should not call this directly. */
+ extern int _getopt_internal (int __argc, char *const *__argv,
+ const char *__shortopts,
+ const struct option *__longopts, int *__longind,
+ int __long_only);
+# endif
+#else /* not __STDC__ */
+ extern int getopt ();
+# ifndef __need_getopt
+ extern int getopt_long ();
+ extern int getopt_long_only ();
+
+ extern int _getopt_internal ();
+# endif
+#endif /* __STDC__ */
+
+#ifdef __cplusplus
+}
+#endif
+
+/* Make sure we later can get all the definitions and declarations. */
+#undef __need_getopt
+
+#endif /* getopt.h */
diff --git a/Build/source/utils/asymptote/getopt1.c b/Build/source/utils/asymptote/getopt1.c
new file mode 100644
index 00000000000..22a7efbdd19
--- /dev/null
+++ b/Build/source/utils/asymptote/getopt1.c
@@ -0,0 +1,188 @@
+/* getopt_long and getopt_long_only entry points for GNU getopt.
+ Copyright (C) 1987,88,89,90,91,92,93,94,96,97,98
+ Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C 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.
+
+ The GNU C 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 the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "getopt.h"
+
+#if !defined __STDC__ || !__STDC__
+/* This is a separate conditional since some stdc systems
+ reject `defined (const)'. */
+#ifndef const
+#define const
+#endif
+#endif
+
+#include <stdio.h>
+
+/* Comment out all this code if we are using the GNU C Library, and are not
+ actually compiling the library itself. This code is part of the GNU C
+ Library, but also included in many other GNU distributions. Compiling
+ and linking in this code is a waste when using the GNU C library
+ (especially if it is a shared library). Rather than having every GNU
+ program understand `configure --with-gnu-libc' and omit the object files,
+ it is simpler to just do this in the source for each such file. */
+
+#define GETOPT_INTERFACE_VERSION 2
+#if !defined _LIBC && defined __GLIBC__ && __GLIBC__ >= 2
+#include <gnu-versions.h>
+#if _GNU_GETOPT_INTERFACE_VERSION == GETOPT_INTERFACE_VERSION
+#define ELIDE_CODE
+#endif
+#endif
+
+#ifndef ELIDE_CODE
+
+
+/* This needs to come after some library #include
+ to get __GNU_LIBRARY__ defined. */
+#ifdef __GNU_LIBRARY__
+#include <stdlib.h>
+#endif
+
+#ifndef NULL
+#define NULL 0
+#endif
+
+int
+getopt_long (argc, argv, options, long_options, opt_index)
+ int argc;
+ char *const *argv;
+ const char *options;
+ const struct option *long_options;
+ int *opt_index;
+{
+ return _getopt_internal (argc, argv, options, long_options, opt_index, 0);
+}
+
+/* Like getopt_long, but '-' as well as '--' can indicate a long option.
+ If an option that starts with '-' (not '--') doesn't match a long option,
+ but does match a short option, it is parsed as a short option
+ instead. */
+
+int
+getopt_long_only (argc, argv, options, long_options, opt_index)
+ int argc;
+ char *const *argv;
+ const char *options;
+ const struct option *long_options;
+ int *opt_index;
+{
+ return _getopt_internal (argc, argv, options, long_options, opt_index, 1);
+}
+
+
+#endif /* Not ELIDE_CODE. */
+
+#ifdef TEST
+
+#include <stdio.h>
+
+int
+main (argc, argv)
+ int argc;
+ char **argv;
+{
+ int c;
+ int digit_optind = 0;
+
+ while (1)
+ {
+ int this_option_optind = optind ? optind : 1;
+ int option_index = 0;
+ static struct option long_options[] =
+ {
+ {"add", 1, 0, 0},
+ {"append", 0, 0, 0},
+ {"delete", 1, 0, 0},
+ {"verbose", 0, 0, 0},
+ {"create", 0, 0, 0},
+ {"file", 1, 0, 0},
+ {0, 0, 0, 0}
+ };
+
+ c = getopt_long (argc, argv, "abc:d:0123456789",
+ long_options, &option_index);
+ if (c == -1)
+ break;
+
+ switch (c)
+ {
+ case 0:
+ printf ("option %s", long_options[option_index].name);
+ if (optarg)
+ printf (" with arg %s", optarg);
+ printf ("\n");
+ break;
+
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ case '8':
+ case '9':
+ if (digit_optind != 0 && digit_optind != this_option_optind)
+ printf ("digits occur in two different argv-elements.\n");
+ digit_optind = this_option_optind;
+ printf ("option %c\n", c);
+ break;
+
+ case 'a':
+ printf ("option a\n");
+ break;
+
+ case 'b':
+ printf ("option b\n");
+ break;
+
+ case 'c':
+ printf ("option c with value `%s'\n", optarg);
+ break;
+
+ case 'd':
+ printf ("option d with value `%s'\n", optarg);
+ break;
+
+ case '?':
+ break;
+
+ default:
+ printf ("?? getopt returned character code 0%o ??\n", c);
+ }
+ }
+
+ if (optind < argc)
+ {
+ printf ("non-option ARGV-elements: ");
+ while (optind < argc)
+ printf ("%s ", argv[optind++]);
+ printf ("\n");
+ }
+
+ exit (0);
+}
+
+#endif /* TEST */
diff --git a/Build/source/utils/asymptote/glrender.cc b/Build/source/utils/asymptote/glrender.cc
new file mode 100644
index 00000000000..29136c36358
--- /dev/null
+++ b/Build/source/utils/asymptote/glrender.cc
@@ -0,0 +1,1306 @@
+/*****
+ * glrender.cc
+ * John Bowman and Orest Shardt
+ * Render 3D Bezier paths and surfaces.
+ *****/
+
+#include <stdlib.h>
+#include <fstream>
+#include <cstring>
+#include <sys/time.h>
+#include <signal.h>
+
+#include "common.h"
+
+namespace gl {
+bool glthread=false;
+bool initialize=true;
+}
+
+#ifdef HAVE_LIBGL
+
+// For CYGWIN
+#ifndef FGAPI
+#define FGAPI GLUTAPI
+#endif
+#ifndef FGAPIENTRY
+#define FGAPIENTRY APIENTRY
+#endif
+
+#define GLUT_BUILDING_LIB
+
+#include "picture.h"
+#include "arcball.h"
+#include "bbox3.h"
+#include "drawimage.h"
+#include "interact.h"
+#include "tr.h"
+
+#ifdef FREEGLUT
+#include <GL/freeglut_ext.h>
+#endif
+
+namespace gl {
+
+using camp::picture;
+using camp::drawImage;
+using camp::transform;
+using camp::pair;
+using camp::triple;
+using vm::array;
+using camp::bbox3;
+using settings::getSetting;
+using settings::Setting;
+
+const double moveFactor=1.0;
+const double zoomFactor=1.05;
+const double zoomFactorStep=0.1;
+const double spinStep=60.0; // Degrees per second
+const double arcballRadius=750.0;
+const double resizeStep=1.2;
+
+double Aspect;
+bool View;
+bool Iconify=false;
+int Oldpid;
+string Prefix;
+const picture* Picture;
+string Format;
+int Width,Height;
+int fullWidth,fullHeight;
+int oldWidth,oldHeight;
+double oWidth,oHeight;
+int screenWidth,screenHeight;
+int maxWidth;
+int maxHeight;
+int maxTileWidth;
+int maxTileHeight;
+
+double *T;
+
+bool Xspin,Yspin,Zspin;
+bool Menu;
+bool Motion;
+bool ignorezoom;
+
+int Fitscreen;
+int Mode;
+
+double H;
+double xmin,xmax;
+double ymin,ymax;
+double zmin,zmax;
+
+double Xmin,Xmax;
+double Ymin,Ymax;
+double X,Y;
+
+int minimumsize=50; // Minimum initial rendering window width and height
+
+const double degrees=180.0/M_PI;
+const double radians=1.0/degrees;
+
+size_t Nlights;
+triple *Lights;
+double *Diffuse;
+double *Ambient;
+double *Specular;
+bool ViewportLighting;
+bool queueExport=false;
+bool antialias;
+
+int x0,y0;
+int mod;
+
+double lastangle;
+
+double Zoom;
+double lastzoom;
+
+GLfloat Rotate[16];
+Arcball arcball;
+
+GLUnurbs *nurb;
+
+int window;
+
+void *glrenderWrapper(void *a);
+
+#ifdef HAVE_LIBPTHREAD
+pthread_t mainthread;
+
+pthread_cond_t initSignal=PTHREAD_COND_INITIALIZER;
+pthread_mutex_t initLock=PTHREAD_MUTEX_INITIALIZER;
+
+pthread_cond_t quitSignal=PTHREAD_COND_INITIALIZER;
+pthread_mutex_t quitLock=PTHREAD_MUTEX_INITIALIZER;
+
+pthread_cond_t readySignal=PTHREAD_COND_INITIALIZER;
+pthread_mutex_t readyLock=PTHREAD_MUTEX_INITIALIZER;
+#endif
+
+inline void lock()
+{
+#ifdef HAVE_LIBPTHREAD
+ if(glthread)
+ pthread_mutex_lock(&readyLock);
+#endif
+}
+
+inline void unlock()
+{
+#ifdef HAVE_LIBPTHREAD
+ if(glthread)
+ pthread_mutex_unlock(&readyLock);
+#endif
+
+}
+
+template<class T>
+inline T min(T a, T b)
+{
+ return (a < b) ? a : b;
+}
+
+template<class T>
+inline T max(T a, T b)
+{
+ return (a > b) ? a : b;
+}
+
+void lighting()
+{
+ for(size_t i=0; i < Nlights; ++i) {
+ GLenum index=GL_LIGHT0+i;
+ triple Lighti=Lights[i];
+ GLfloat position[]={Lighti.getx(),Lighti.gety(),Lighti.getz(),0.0};
+ glLightfv(index,GL_POSITION,position);
+ }
+}
+
+void initlighting()
+{
+ glEnable(GL_LIGHTING);
+ glLightModeli(GL_LIGHT_MODEL_TWO_SIDE,getSetting<bool>("twosided"));
+
+ for(size_t i=0; i < Nlights; ++i) {
+ GLenum index=GL_LIGHT0+i;
+ glEnable(index);
+
+ size_t i4=4*i;
+
+ GLfloat diffuse[]={Diffuse[i4],Diffuse[i4+1],Diffuse[i4+2],Diffuse[i4+3]};
+ glLightfv(index,GL_DIFFUSE,diffuse);
+
+ GLfloat ambient[]={Ambient[i4],Ambient[i4+1],Ambient[i4+2],Ambient[i4+3]};
+ glLightfv(index,GL_AMBIENT,ambient);
+
+ GLfloat specular[]={Specular[i4],Specular[i4+1],Specular[i4+2],
+ Specular[i4+3]};
+ glLightfv(index,GL_SPECULAR,specular);
+ }
+
+ static size_t lastNlights=0;
+ for(size_t i=Nlights; i < lastNlights; ++i) {
+ GLenum index=GL_LIGHT0+i;
+ glDisable(index);
+ }
+ lastNlights=Nlights;
+
+ if(ViewportLighting)
+ lighting();
+}
+
+void setDimensions(int Width, int Height, double X, double Y)
+{
+ double Aspect=((double) Width)/Height;
+ double X0=X*(xmax-xmin)/(lastzoom*Width);
+ double Y0=Y*(ymax-ymin)/(lastzoom*Height);
+ if(H == 0.0) {
+ double xsize=Xmax-Xmin;
+ double ysize=Ymax-Ymin;
+ if(xsize < ysize*Aspect) {
+ double r=0.5*ysize*Zoom*Aspect;
+ xmin=-r-X0;
+ xmax=r-X0;
+ ymin=Ymin*Zoom-Y0;
+ ymax=Ymax*Zoom-Y0;
+ } else {
+ double r=0.5*xsize*Zoom/Aspect;
+ xmin=Xmin*Zoom-X0;
+ xmax=Xmax*Zoom-X0;
+ ymin=-r-Y0;
+ ymax=r-Y0;
+ }
+ } else {
+ double r=H*Zoom;
+ xmin=-r*Aspect-X0;
+ xmax=r*Aspect-X0;
+ ymin=-r-Y0;
+ ymax=r-Y0;
+ }
+}
+
+void setProjection()
+{
+ glMatrixMode(GL_PROJECTION);
+ glLoadIdentity();
+ setDimensions(Width,Height,X,Y);
+ if(H == 0.0)
+ glOrtho(xmin,xmax,ymin,ymax,-zmax,-zmin);
+ else
+ glFrustum(xmin,xmax,ymin,ymax,-zmax,-zmin);
+ glMatrixMode(GL_MODELVIEW);
+ arcball.set_params(vec2(0.5*Width,0.5*Height),arcballRadius/Zoom);
+}
+
+bool capsize(int& width, int& height)
+{
+ bool resize=false;
+ if(width > maxWidth) {
+ width=maxWidth;
+ resize=true;
+ }
+ if(height > maxHeight) {
+ height=maxHeight;
+ resize=true;
+ }
+ return resize;
+}
+
+void reshape0(int width, int height)
+{
+ X=X/Width*width;
+ Y=Y/Height*height;
+
+ Width=width;
+ Height=height;
+
+ setProjection();
+ glViewport(0,0,Width,Height);
+}
+
+void update()
+{
+ lastzoom=Zoom;
+ glLoadIdentity();
+ double cz=0.5*(zmin+zmax);
+ glTranslatef(0,0,cz);
+ glMultMatrixf(Rotate);
+ glTranslatef(0,0,-cz);
+ setProjection();
+ glutPostRedisplay();
+}
+
+void drawscene(double Width, double Height)
+{
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+
+ if(!ViewportLighting)
+ lighting();
+
+ triple m(xmin,ymin,zmin);
+ triple M(xmax,ymax,zmax);
+ double perspective=H == 0.0 ? 0.0 : 1.0/zmax;
+
+ double size2=hypot(Width,Height);
+
+ glEnable(GL_BLEND);
+ // Render opaque objects
+ Picture->render(nurb,size2,m,M,perspective,false);
+
+ // Enable transparency
+ glEnable(GL_BLEND);
+ glDepthMask(GL_FALSE);
+
+ // Render transparent objects
+ Picture->render(nurb,size2,m,M,perspective,true);
+ glDepthMask(GL_TRUE);
+ glDisable(GL_BLEND);
+}
+
+// Return x divided by y rounded up to the nearest integer.
+int Quotient(int x, int y)
+{
+ return (x+y-1)/y;
+}
+
+void Export()
+{
+ glReadBuffer(GL_BACK_LEFT);
+ glPixelStorei(GL_PACK_ALIGNMENT,1);
+ glFinish();
+ try {
+ size_t ndata=3*fullWidth*fullHeight;
+ unsigned char *data=new unsigned char[ndata];
+ if(data) {
+ TRcontext *tr=trNew();
+ int width=Quotient(fullWidth,Quotient(fullWidth,min(maxTileWidth,Width)));
+ int height=Quotient(fullHeight,Quotient(fullHeight,
+ min(maxTileHeight,Height)));
+ if(settings::verbose > 1)
+ cout << "Exporting " << Prefix << " as " << fullWidth << "x"
+ << fullHeight << " image" << " using tiles of size "
+ << width << "x" << height << endl;
+
+ trTileSize(tr,width,height,0);
+ trImageSize(tr,fullWidth,fullHeight);
+ trImageBuffer(tr,GL_RGB,GL_UNSIGNED_BYTE,data);
+
+ setDimensions(fullWidth,fullHeight,X/Width*fullWidth,Y/Width*fullWidth);
+ if(H == 0.0)
+ trOrtho(tr,xmin,xmax,ymin,ymax,-zmax,-zmin);
+ else
+ trFrustum(tr,xmin,xmax,ymin,ymax,-zmax,-zmin);
+
+ size_t count=0;
+ do {
+ trBeginTile(tr);
+ drawscene(fullWidth,fullHeight);
+ ++count;
+ } while (trEndTile(tr));
+ if(settings::verbose > 1)
+ cout << count << " tile" << (count > 1 ? "s" : "") << " drawn" << endl;
+ trDelete(tr);
+
+ picture pic;
+ double w=oWidth;
+ double h=oHeight;
+ double Aspect=((double) fullWidth)/fullHeight;
+ if(w > h*Aspect) w=(int) (h*Aspect+0.5);
+ else h=(int) (w/Aspect+0.5);
+ // Render an antialiased image.
+ drawImage *Image=new drawImage(data,fullWidth,fullHeight,
+ transform(0.0,0.0,w,0.0,0.0,h),antialias);
+ pic.append(Image);
+ pic.shipout(NULL,Prefix,Format,0.0,false,View);
+ delete Image;
+ delete[] data;
+ }
+ } catch(handled_error) {
+ } catch(std::bad_alloc&) {
+ outOfMemory();
+ }
+ setProjection();
+}
+
+void LockedExport()
+{
+ if(interact::interactive)
+ lock();
+ Export();
+ if(interact::interactive)
+ unlock();
+}
+
+void windowposition(int& x, int& y, int width=Width, int height=Height)
+{
+ pair z=getSetting<pair>("position");
+ x=(int) z.getx();
+ y=(int) z.gety();
+ if(x < 0) {
+ x += screenWidth-width;
+ if(x < 0) x=0;
+ }
+ if(y < 0) {
+ y += screenHeight-height;
+ if(y < 0) y=0;
+ }
+}
+
+void setsize(int w, int h, int minsize=0)
+{
+ int x,y;
+
+ if(minsize) {
+ if(w < minsize) {
+ h=(int) (h*(double) minsize/w+0.5);
+ w=minsize;
+ }
+
+ if(h < minsize) {
+ w=(int) (w*(double) minsize/h+0.5);
+ h=minsize;
+ }
+ }
+
+ capsize(w,h);
+ windowposition(x,y,w,h);
+ glutPositionWindow(x,y);
+ glutReshapeWindow(w,h);
+ reshape0(w,h);
+ glutPostRedisplay();
+}
+
+void fullscreen()
+{
+ Width=screenWidth;
+ Height=screenHeight;
+#ifdef __CYGWIN__
+ glutFullScreen();
+#else
+ glutPositionWindow(0,0);
+ glutReshapeWindow(Width,Height);
+ reshape0(Width,Height);
+ glutPostRedisplay();
+#endif
+}
+
+void fitscreen()
+{
+ switch(Fitscreen) {
+ case 0: // Original size
+ {
+ setsize(oldWidth,oldHeight,minimumsize);
+ break;
+ }
+ case 1: // Fit to screen in one dimension
+ {
+ oldWidth=Width;
+ oldHeight=Height;
+ int w=screenWidth;
+ int h=screenHeight;
+ if(w >= h*Aspect) w=(int) (h*Aspect+0.5);
+ else h=(int) (w/Aspect+0.5);
+ setsize(w,h,minimumsize);
+ break;
+ }
+ case 2: // Full screen
+ {
+ fullscreen();
+ break;
+ }
+ }
+}
+
+void togglefitscreen()
+{
+ ++Fitscreen;
+ if(Fitscreen > 2) Fitscreen=0;
+ fitscreen();
+}
+
+void updateHandler(int)
+{
+ initlighting();
+ update();
+ if(interact::interactive) {
+ glutShowWindow();
+ glutShowWindow(); // Call twice to work around apparent freeglut bug.
+ } else if(glthread) fitscreen();
+}
+
+void autoExport()
+{
+ if(!Iconify)
+ glutShowWindow();
+ Export();
+ if(!Iconify)
+ glutHideWindow();
+}
+
+void exportHandler(int)
+{
+#ifdef HAVE_LIBPTHREAD
+ if(glthread)
+ wait(readySignal,readyLock);
+#endif
+ initlighting();
+ autoExport();
+}
+
+void reshape(int width, int height)
+{
+ if(glthread) {
+ static bool initialize=true;
+ if(initialize) {
+ initialize=false;
+ signal(SIGUSR1,updateHandler);
+ signal(SIGUSR2,exportHandler);
+ unlock();
+ }
+ }
+
+ if(capsize(width,height))
+ glutReshapeWindow(width,height);
+
+ reshape0(width,height);
+}
+
+#ifdef HAVE_LIBPTHREAD
+void endwait(pthread_cond_t& signal, pthread_mutex_t& lock)
+{
+ pthread_cond_signal(&signal);
+}
+void wait(pthread_cond_t& signal, pthread_mutex_t& lock)
+{
+ pthread_mutex_lock(&lock);
+ pthread_cond_signal(&signal);
+ pthread_cond_wait(&signal,&lock);
+ endwait(signal,lock);
+ pthread_mutex_unlock(&lock);
+}
+
+#endif
+
+void quit()
+{
+ if(glthread) {
+ if(interact::interactive) {
+ glutHideWindow();
+ } else {
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+ glutSwapBuffers();
+ }
+#ifdef HAVE_LIBPTHREAD
+ if(!interact::interactive) {
+ pthread_mutex_lock(&quitLock);
+ pthread_cond_signal(&quitSignal);
+ pthread_mutex_unlock(&quitLock);
+ }
+#endif
+ } else {
+ glutDestroyWindow(window);
+ exit(0);
+ }
+}
+
+void display()
+{
+ if(interact::interactive)
+ lock();
+ drawscene(Width,Height);
+ glutSwapBuffers();
+ if(queueExport) {
+ Export();
+ queueExport=false;
+ }
+ if(interact::interactive)
+ unlock();
+ if(!glthread) {
+ if(Oldpid != 0 && waitpid(Oldpid,NULL,WNOHANG) != Oldpid) {
+ kill(Oldpid,SIGHUP);
+ Oldpid=0;
+ }
+ }
+}
+
+void move(int x, int y)
+{
+ if(x > 0 && y > 0) {
+ X += (x-x0)*Zoom;
+ Y += (y0-y)*Zoom;
+ x0=x; y0=y;
+ update();
+ }
+}
+
+void capzoom()
+{
+ static double maxzoom=sqrt(DBL_MAX);
+ static double minzoom=1/maxzoom;
+ if(Zoom <= minzoom) Zoom=minzoom;
+ if(Zoom >= maxzoom) Zoom=maxzoom;
+
+}
+
+void disableMenu()
+{
+ glutDetachMenu(GLUT_RIGHT_BUTTON);
+ Menu=false;
+}
+
+void zoom(int x, int y)
+{
+ if(ignorezoom) {ignorezoom=false; y0=y; return;}
+ if(x > 0 && y > 0) {
+ if(Menu) {
+ disableMenu();
+ y0=y;
+ return;
+ }
+ Motion=true;
+ static const double limit=log(0.1*DBL_MAX)/log(zoomFactor);
+ lastzoom=Zoom;
+ double s=zoomFactorStep*(y-y0);
+ if(fabs(s) < limit) {
+ Zoom *= pow(zoomFactor,s);
+ capzoom();
+ y0=y;
+ setProjection();
+ glutPostRedisplay();
+ }
+ }
+}
+
+void mousewheel(int wheel, int direction, int x, int y)
+{
+ lastzoom=Zoom;
+ if(direction > 0)
+ Zoom /= zoomFactor;
+ else
+ Zoom *= zoomFactor;
+
+ capzoom();
+ setProjection();
+ glutPostRedisplay();
+}
+
+void rotate(int x, int y)
+{
+ if(x > 0 && y > 0) {
+ if(Menu) {
+ disableMenu();
+ arcball.mouse_down(x,Height-y);
+ return;
+ }
+ Motion=true;
+ arcball.mouse_motion(x,Height-y,0,
+ mod == GLUT_ACTIVE_SHIFT, // X rotation only
+ mod == GLUT_ACTIVE_CTRL); // Y rotation only
+
+ for(int i=0; i < 4; ++i) {
+ const vec4& roti=arcball.rot[i];
+ int i4=4*i;
+ for(int j=0; j < 4; ++j)
+ Rotate[i4+j]=roti[j];
+ }
+
+ update();
+ }
+}
+
+double Degrees(int x, int y)
+{
+ return atan2(0.5*Height-y-Y,x-0.5*Width-X)*degrees;
+}
+
+void updateArcball()
+{
+ for(int i=0; i < 4; ++i) {
+ int i4=4*i;
+ vec4& roti=arcball.rot[i];
+ for(int j=0; j < 4; ++j)
+ roti[j]=Rotate[i4+j];
+ }
+ update();
+}
+
+void rotateX(double step)
+{
+ glLoadIdentity();
+ glRotatef(step,1,0,0);
+ glMultMatrixf(Rotate);
+ glGetFloatv(GL_MODELVIEW_MATRIX,Rotate);
+ updateArcball();
+}
+
+void rotateY(double step)
+{
+ glLoadIdentity();
+ glRotatef(step,0,1,0);
+ glMultMatrixf(Rotate);
+ glGetFloatv(GL_MODELVIEW_MATRIX,Rotate);
+ updateArcball();
+}
+
+void rotateZ(double step)
+{
+ glLoadIdentity();
+ glRotatef(step,0,0,1);
+ glMultMatrixf(Rotate);
+ glGetFloatv(GL_MODELVIEW_MATRIX,Rotate);
+ updateArcball();
+}
+
+void rotateZ(int x, int y)
+{
+ if(x > 0 && y > 0) {
+ if(Menu) {
+ disableMenu();
+ x=x0; y=y0;
+ return;
+ }
+ Motion=true;
+ double angle=Degrees(x,y);
+ rotateZ(angle-lastangle);
+ lastangle=angle;
+ }
+}
+
+#ifndef GLUT_WHEEL_UP
+#define GLUT_WHEEL_UP 3
+#endif
+
+#ifndef GLUT_WHEEL_DOWN
+#define GLUT_WHEEL_DOWN 4
+#endif
+
+// Mouse bindings.
+// LEFT: rotate
+// SHIFT LEFT: zoom
+// CTRL LEFT: shift
+// MIDDLE: menu
+// RIGHT: zoom
+// SHIFT RIGHT: rotateX
+// CTRL RIGHT: rotateY
+// ALT RIGHT: rotateZ
+void mouse(int button, int state, int x, int y)
+{
+ if(button == GLUT_WHEEL_UP) {
+ mousewheel(0,1,x,y);
+ return;
+ }
+ if(button == GLUT_WHEEL_DOWN) {
+ mousewheel(0,-1,x,y);
+ return;
+ }
+
+ mod=glutGetModifiers();
+
+ if(button == GLUT_RIGHT_BUTTON) {
+ if(state == GLUT_UP && !Motion) {
+ glutAttachMenu(GLUT_RIGHT_BUTTON);
+ Menu=true;
+ return;
+ }
+ }
+
+ if(Menu) disableMenu();
+ else Motion=false;
+
+ if(state == GLUT_DOWN) {
+ if(button == GLUT_LEFT_BUTTON && mod == GLUT_ACTIVE_CTRL) {
+ x0=x; y0=y;
+ glutMotionFunc(move);
+ return;
+ }
+ if((button == GLUT_LEFT_BUTTON && mod == GLUT_ACTIVE_SHIFT) ||
+ (button == GLUT_RIGHT_BUTTON && mod == 0)) {
+ y0=y;
+ glutMotionFunc(zoom);
+ return;
+ }
+ if(button == GLUT_RIGHT_BUTTON && mod == GLUT_ACTIVE_ALT) {
+ lastangle=Degrees(x,y);
+ glutMotionFunc(rotateZ);
+ return;
+ }
+ arcball.mouse_down(x,Height-y);
+ glutMotionFunc(rotate);
+ } else
+ arcball.mouse_up();
+}
+
+timeval lasttime;
+
+double spinstep()
+{
+ timeval tv;
+ gettimeofday(&tv,NULL);
+ double step=spinStep*(tv.tv_sec-lasttime.tv_sec+
+ ((double) tv.tv_usec-lasttime.tv_usec)/1000000.0);
+ lasttime=tv;
+ return step;
+}
+
+void xspin()
+{
+ rotateX(spinstep());
+}
+
+void yspin()
+{
+ rotateY(spinstep());
+}
+
+void zspin()
+{
+ rotateZ(spinstep());
+}
+
+void initTimer()
+{
+ gettimeofday(&lasttime,NULL);
+}
+
+void expand()
+{
+ setsize((int) (Width*resizeStep+0.5),(int) (Height*resizeStep+0.5));
+}
+
+void shrink()
+{
+ setsize(max((int) (Width/resizeStep+0.5),1),
+ max((int) (Height/resizeStep+0.5),1));
+}
+
+void idleFunc(void (*f)())
+{
+ initTimer();
+ glutIdleFunc(f);
+}
+
+void mode()
+{
+ switch(Mode) {
+ case 0:
+ for(size_t i=0; i < Nlights; ++i)
+ glEnable(GL_LIGHT0+i);
+ glPolygonMode(GL_FRONT_AND_BACK,GL_FILL);
+ gluNurbsProperty(nurb,GLU_DISPLAY_MODE,GLU_FILL);
+ ++Mode;
+ break;
+ case 1:
+ for(size_t i=0; i < Nlights; ++i)
+ glDisable(GL_LIGHT0+i);
+ gluNurbsProperty(nurb,GLU_DISPLAY_MODE,GLU_OUTLINE_POLYGON);
+ glPolygonMode(GL_FRONT_AND_BACK,GL_LINE);
+ ++Mode;
+ break;
+ case 2:
+ gluNurbsProperty(nurb,GLU_DISPLAY_MODE,GLU_OUTLINE_PATCH);
+ Mode=0;
+ break;
+ }
+ glutPostRedisplay();
+}
+
+void idle()
+{
+ glutIdleFunc(NULL);
+ Xspin=Yspin=Zspin=false;
+}
+
+void spinx()
+{
+ if(Xspin)
+ idle();
+ else {
+ idleFunc(xspin);
+ Xspin=true;
+ Yspin=Zspin=false;
+ }
+}
+
+void spiny()
+{
+ if(Yspin)
+ idle();
+ else {
+ idleFunc(yspin);
+ Yspin=true;
+ Xspin=Zspin=false;
+ }
+}
+
+void spinz()
+{
+ if(Zspin)
+ idle();
+ else {
+ idleFunc(zspin);
+ Zspin=true;
+ Xspin=Yspin=false;
+ }
+}
+
+void home()
+{
+ idle();
+ X=Y=0.0;
+ arcball.init();
+ glLoadIdentity();
+ glGetFloatv(GL_MODELVIEW_MATRIX,Rotate);
+ lastzoom=Zoom=1.0;
+}
+
+void write(const char *text, const double *v)
+{
+ cout << text << "=(" << v[0] << "," << v[1] << "," << v[2] << ")";
+}
+
+void camera()
+{
+ double cz=0.5*(zmin+zmax);
+ camp::Triple vCamera,vTarget,vUp;
+
+ for(int i=0; i < 3; ++i) {
+ double sumCamera=0.0, sumTarget=0.0, sumUp=0.0;
+ for(int j=0; j < 4; ++j) {
+ sumCamera += T[4*i+j]*(Rotate[4*j+3]-cz*Rotate[4*j+2]);
+ sumUp += T[4*i+j]*(Rotate[4*j+3]+Rotate[4*j+1]);
+ sumTarget += T[4*i+j]*Rotate[4*j+3];
+ }
+ vCamera[i]=sumCamera;
+ vUp[i]=sumUp-sumTarget;
+ vTarget[i]=sumTarget;
+ }
+
+ triple Camera=triple(vCamera);
+ triple Up=triple(vUp);
+ triple Target=triple(vTarget);
+
+ cout << "camera=" << Camera << "," << endl
+ << "up=" << Up << "," << endl
+ << "target=" << Target << endl << endl;
+}
+
+void keyboard(unsigned char key, int x, int y)
+{
+ switch(key) {
+ case 'h':
+ home();
+ update();
+ break;
+ case 'f':
+ togglefitscreen();
+ break;
+ case 'x':
+ spinx();
+ break;
+ case 'y':
+ spiny();
+ break;
+ case 'z':
+ spinz();
+ break;
+ case 's':
+ idle();
+ break;
+ case 'm':
+ mode();
+ break;
+ case 'e':
+ LockedExport();
+ break;
+ case 'c':
+ camera();
+ break;
+ case '+':
+ case '=':
+ expand();
+ break;
+ case '-':
+ case '_':
+ shrink();
+ break;
+ case 17: // Ctrl-q
+ case 'q':
+ if(!Format.empty()) LockedExport();
+ quit();
+ break;
+ }
+}
+
+enum Menu {HOME,FITSCREEN,XSPIN,YSPIN,ZSPIN,STOP,MODE,EXPORT,CAMERA,QUIT};
+
+void menu(int choice)
+{
+ disableMenu();
+ ignorezoom=true;
+ Motion=true;
+ switch (choice) {
+ case HOME: // Home
+ home();
+ update();
+ break;
+ case FITSCREEN:
+ togglefitscreen();
+ break;
+ case XSPIN:
+ spinx();
+ break;
+ case YSPIN:
+ spiny();
+ break;
+ case ZSPIN:
+ spinz();
+ break;
+ case STOP:
+ idle();
+ break;
+ case MODE:
+ mode();
+ break;
+ case EXPORT:
+ queueExport=true;
+ break;
+ case CAMERA:
+ camera();
+ break;
+ case QUIT:
+ quit();
+ break;
+ }
+}
+
+void setosize()
+{
+ oldWidth=(int) ceil(oWidth);
+ oldHeight=(int) ceil(oHeight);
+}
+
+void init()
+{
+ string options=string(settings::argv0)+" ";
+ if(Iconify)
+ options += "-iconic ";
+ options += getSetting<string>("glOptions");
+ char **argv=args(options.c_str(),true);
+ int argc=0;
+ while(argv[argc] != NULL)
+ ++argc;
+
+ glutInit(&argc,argv);
+
+ screenWidth=glutGet(GLUT_SCREEN_WIDTH);
+ screenHeight=glutGet(GLUT_SCREEN_HEIGHT);
+}
+
+// angle=0 means orthographic.
+void glrender(const string& prefix, const picture *pic, const string& format,
+ double width, double height,
+ double angle, const triple& m, const triple& M, double *t,
+ size_t nlights, triple *lights, double *diffuse,
+ double *ambient, double *specular, bool Viewportlighting,
+ bool view, int oldpid)
+{
+#ifndef __CYGWIN__
+ Iconify=getSetting<bool>("iconify");
+#endif
+
+ width=max(width,1.0);
+ height=max(height,1.0);
+
+ static bool initializedView=false;
+
+ if(view || initializedView) lock();
+
+ Prefix=prefix;
+ Picture=pic;
+ Format=format;
+ T=t;
+ Nlights=min(nlights,(size_t) GL_MAX_LIGHTS);
+ Lights=lights;
+ Diffuse=diffuse;
+ Ambient=ambient;
+ Specular=specular;
+ ViewportLighting=Viewportlighting;
+ View=view;
+ Oldpid=oldpid;
+
+ static bool initialized=false;
+
+ if(!initialized) {
+ init();
+ Fitscreen=1;
+ }
+
+ Xmin=m.getx();
+ Xmax=M.getx();
+ Ymin=m.gety();
+ Ymax=M.gety();
+ zmin=m.getz();
+ zmax=M.getz();
+ H=angle != 0.0 ? -tan(0.5*angle*radians)*zmax : 0.0;
+
+ Menu=false;
+ Motion=true;
+ ignorezoom=false;
+ Mode=0;
+
+ if(!initialized || !interact::interactive) {
+ antialias=getSetting<Int>("antialias") > 1;
+ double expand=getSetting<double>("render");
+ if(expand < 0)
+ expand *= (Format.empty() || Format == "eps" || Format == "pdf")
+ ? -2.0 : -1.0;
+ if(antialias) expand *= 2.0;
+
+ // Force a hard viewport limit to work around direct rendering bugs.
+ // Alternatively, one can use -glOptions=-indirect (with a performance
+ // penalty).
+ pair maxViewport=getSetting<pair>("maxviewport");
+ maxWidth=(int) ceil(maxViewport.getx());
+ maxHeight=(int) ceil(maxViewport.gety());
+ if(maxWidth <= 0) maxWidth=max(maxHeight,2);
+ if(maxHeight <= 0) maxHeight=max(maxWidth,2);
+ if(screenWidth <= 0) screenWidth=maxWidth;
+ if(screenHeight <= 0) screenHeight=maxHeight;
+
+ oWidth=width;
+ oHeight=height;
+ Aspect=width/height;
+
+ fullWidth=(int) ceil(expand*width);
+ fullHeight=(int) ceil(expand*height);
+
+ Width=min(fullWidth,screenWidth);
+ Height=min(fullHeight,screenHeight);
+
+ if(Width > Height*Aspect)
+ Width=min((int) (ceil(Height*Aspect)),screenWidth);
+ else
+ Height=min((int) (ceil(Width/Aspect)),screenHeight);
+
+ Aspect=((double) Width)/Height;
+
+ pair maxtile=getSetting<pair>("maxtile");
+ maxTileWidth=(int) maxtile.getx();
+ maxTileHeight=(int) maxtile.gety();
+ if(maxTileWidth <= 0) maxTileWidth=screenWidth;
+ if(maxTileHeight <= 0) maxTileHeight=screenHeight;
+
+ setosize();
+
+ if(View && settings::verbose > 1)
+ cout << "Rendering " << prefix << " as " << Width << "x" << Height
+ << " image" << endl;
+ }
+
+#ifdef HAVE_LIBPTHREAD
+ if(initializedView && glthread) {
+ if(View)
+ pthread_kill(mainthread,SIGUSR1);
+ else
+ pthread_kill(mainthread,SIGUSR2);
+ unlock();
+ return;
+ }
+#endif
+
+ unsigned int displaymode=GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH;
+
+ bool havewindow=initialized && glthread;
+
+ if(View) {
+ int x,y;
+ if(havewindow)
+ glutDestroyWindow(window);
+
+ windowposition(x,y);
+ glutInitWindowPosition(x,y);
+ glutInitWindowSize(1,1);
+ Int multisample=getSetting<Int>("multisample");
+ if(multisample <= 1) multisample=0;
+ if(multisample)
+ displaymode |= GLUT_MULTISAMPLE;
+ glutInitDisplayMode(displaymode);
+
+ ostringstream buf;
+ int samples;
+#ifdef FREEGLUT
+#ifdef GLUT_INIT_MAJOR_VERSION
+ while(true) {
+ if(multisample > 0)
+ glutSetOption(GLUT_MULTISAMPLE,multisample);
+#endif
+#endif
+ string title=string(settings::PROGRAM)+": "+prefix+
+ " [Double click right button for menu]";
+ window=glutCreateWindow(title.c_str());
+ GLint samplebuf[1];
+ glGetIntegerv(GL_SAMPLES,samplebuf);
+ samples=samplebuf[0];
+#ifdef FREEGLUT
+#ifdef GLUT_INIT_MAJOR_VERSION
+ if(samples < multisample) {
+ --multisample;
+ if(multisample > 1) {
+ glutDestroyWindow(window);
+ continue;
+ }
+ }
+ break;
+ }
+#endif
+#endif
+ if(samples > 1) {
+ if(settings::verbose > 1 && samples > 1)
+ cout << "Multisampling enabled with sample width " << samples << endl;
+ }
+ glutShowWindow();
+ } else if(!havewindow) {
+ glutInitWindowSize(maxTileWidth,maxTileHeight);
+ glutInitDisplayMode(displaymode);
+ window=glutCreateWindow("");
+ glutHideWindow();
+ }
+
+ initialized=true;
+
+ glClearColor(1.0,1.0,1.0,1.0);
+
+ glMatrixMode(GL_MODELVIEW);
+
+ home();
+
+ if(View) {
+ if(!getSetting<bool>("fitscreen"))
+ Fitscreen=0;
+ fitscreen();
+ setosize();
+ }
+
+ glEnable(GL_DEPTH_TEST);
+ glEnable(GL_MAP1_VERTEX_3);
+ glEnable(GL_MAP2_VERTEX_3);
+ glEnable(GL_MAP2_COLOR_4);
+
+ glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
+
+ nurb=gluNewNurbsRenderer();
+ if(nurb == NULL)
+ outOfMemory();
+ gluNurbsProperty(nurb,GLU_SAMPLING_METHOD,GLU_PARAMETRIC_ERROR);
+ gluNurbsProperty(nurb,GLU_SAMPLING_TOLERANCE,0.5);
+ gluNurbsProperty(nurb,GLU_PARAMETRIC_TOLERANCE,1.0);
+ gluNurbsProperty(nurb,GLU_CULLING,GLU_TRUE);
+
+ // The callback tesselation algorithm avoids artifacts at degenerate control
+ // points.
+ gluNurbsProperty(nurb,GLU_NURBS_MODE,GLU_NURBS_TESSELLATOR);
+ gluNurbsCallback(nurb,GLU_NURBS_BEGIN,(_GLUfuncptr) glBegin);
+ gluNurbsCallback(nurb,GLU_NURBS_VERTEX,(_GLUfuncptr) glVertex3fv);
+ gluNurbsCallback(nurb,GLU_NURBS_END,(_GLUfuncptr) glEnd);
+ gluNurbsCallback(nurb,GLU_NURBS_COLOR,(_GLUfuncptr) glColor4fv);
+ mode();
+
+ initlighting();
+
+ if(View) {
+ initializedView=true;
+ glutReshapeFunc(reshape);
+ glutDisplayFunc(display);
+ glutKeyboardFunc(keyboard);
+ glutMouseFunc(mouse);
+
+ glutCreateMenu(menu);
+ glutAddMenuEntry("(h) Home",HOME);
+ glutAddMenuEntry("(f) Fitscreen",FITSCREEN);
+ glutAddMenuEntry("(x) X spin",XSPIN);
+ glutAddMenuEntry("(y) Y spin",YSPIN);
+ glutAddMenuEntry("(z) Z spin",ZSPIN);
+ glutAddMenuEntry("(s) Stop",STOP);
+ glutAddMenuEntry("(m) Mode",MODE);
+ glutAddMenuEntry("(e) Export",EXPORT);
+ glutAddMenuEntry("(c) Camera",CAMERA);
+ glutAddMenuEntry("(q) Quit" ,QUIT);
+
+ glutAttachMenu(GLUT_MIDDLE_BUTTON);
+
+ glutMainLoop();
+ } else {
+ if(glthread) {
+ exportHandler(0);
+ } else {
+ autoExport();
+ quit();
+ }
+ }
+}
+
+} // namespace gl
+
+#endif
diff --git a/Build/source/utils/asymptote/glrender.h b/Build/source/utils/asymptote/glrender.h
new file mode 100644
index 00000000000..de906795ff9
--- /dev/null
+++ b/Build/source/utils/asymptote/glrender.h
@@ -0,0 +1,66 @@
+/*****
+ * glrender.h
+ * Render 3D Bezier paths and surfaces.
+ *****/
+
+#ifndef GLRENDER_H
+#define GLRENDER_H
+
+#include "common.h"
+
+#ifdef HAVE_LIBGL
+
+#include <csignal>
+
+#ifdef __APPLE__
+#include <OpenGL/gl.h>
+#include <OpenGL/glext.h>
+#include <OpenGL/glu.h>
+#include <GLUT/glut.h>
+#ifdef GLU_TESS_CALLBACK_TRIPLEDOT
+typedef GLvoid (* _GLUfuncptr)(...);
+#else
+typedef GLvoid (* _GLUfuncptr)();
+#endif
+#else
+#include <GL/gl.h>
+#include <GL/glext.h>
+#include <GL/glu.h>
+#include <GL/glut.h>
+#endif
+
+namespace camp {
+class picture;
+
+inline void store(GLfloat *f, double *C)
+{
+ f[0]=C[0];
+ f[1]=C[1];
+ f[2]=C[2];
+}
+
+inline void store(GLfloat *control, const camp::triple& v)
+{
+ control[0]=v.getx();
+ control[1]=v.gety();
+ control[2]=v.getz();
+}
+}
+
+namespace gl {
+void glrender(const string& prefix, const camp::picture* pic,
+ const string& format, double width, double height,
+ double angle, const camp::triple& m, const camp::triple& M,
+ double *t, size_t nlights, camp::triple *lights, double *diffuse,
+ double *ambient, double *specular, bool viewportlighting,
+ bool view, int oldpid=0);
+}
+
+#else
+typedef void GLUnurbs;
+typedef float GLfloat;
+#endif
+
+#endif
+
+
diff --git a/Build/source/utils/asymptote/guide.cc b/Build/source/utils/asymptote/guide.cc
new file mode 100644
index 00000000000..b46c269290d
--- /dev/null
+++ b/Build/source/utils/asymptote/guide.cc
@@ -0,0 +1,37 @@
+/*****
+ * guide.cc
+ * Andy Hammerlindl 2005/02/23
+ *
+ *****/
+
+#include "guide.h"
+
+namespace camp {
+
+void multiguide::flatten(flatguide& g, bool allowsolve)
+{
+ size_t n=v.size();
+ if(n > 0) {
+ for(size_t i=0; i+1 < n; ++i) {
+ v[i]->flatten(g,allowsolve);
+ if(!allowsolve && v[i]->cyclic()) {
+ g.precyclic(true);
+ g.resolvecycle();
+ }
+ }
+ v[n-1]->flatten(g,allowsolve);
+ }
+}
+
+void multiguide::print(ostream& out) const
+{
+ side lastLoc=JOIN;
+ for(size_t i=0; i < v.size(); ++i) {
+ side loc=v[i]->printLocation();
+ adjustLocation(out,lastLoc,loc);
+ v[i]->print(out);
+ lastLoc=loc;
+ }
+}
+
+} // namespace camp
diff --git a/Build/source/utils/asymptote/guide.h b/Build/source/utils/asymptote/guide.h
new file mode 100644
index 00000000000..103e05afa41
--- /dev/null
+++ b/Build/source/utils/asymptote/guide.h
@@ -0,0 +1,307 @@
+/*****
+ * guide.h
+ * Andy Hammerlindl 2005/02/23
+ *
+ *****/
+
+#ifndef GUIDE_H
+#define GUIDE_H
+
+#include <iostream>
+#include "knot.h"
+#include "flatguide.h"
+#include "settings.h"
+
+namespace camp {
+
+// Abstract base class for guides.
+class guide : public gc {
+protected:
+public:
+ virtual ~guide() {}
+
+ // Returns the path that the guide represents.
+ virtual path solve() {
+ return path();
+ }
+
+ // Add the information in the guide to the flatguide, so that it can be
+ // solved via the knotlist solving routines.
+ // Returns true if guide has an interior cycle token.
+ virtual void flatten(flatguide&, bool allowsolve=true)=0;
+
+ virtual bool cyclic() {return false;}
+
+ virtual void print(ostream& out) const {
+ out << "nullpath";
+ }
+
+ // Needed so that multiguide can know where to put in ".." symbols.
+ virtual side printLocation() const {
+ return END;
+ }
+
+};
+
+inline ostream& operator<< (ostream& out, const guide& g)
+{
+ g.print(out);
+ return out;
+}
+
+// Draws dots between two printings of guides, if their locations are such that
+// the dots are necessary.
+inline void adjustLocation(ostream& out, side l1, side l2)
+{
+ if (l1 == END)
+ out << endl;
+ if ((l1 == END || l1 == OUT) && (l2 == IN || l2 == END))
+ out << "..";
+}
+
+// A guide representing a pair.
+class pairguide : public guide {
+ pair z;
+
+public:
+ void flatten(flatguide& g, bool=true) {
+ g.add(z);
+ }
+
+ pairguide(pair z)
+ : z(z) {}
+
+ path solve() {
+ return path(z);
+ }
+
+ void print(ostream& out) const {
+ out << z;
+ }
+
+ side printLocation() const {
+ return END;
+ }
+};
+
+
+// A guide representing a path.
+class pathguide : public guide {
+ path p;
+
+public:
+ void flatten(flatguide& g, bool allowsolve=true) {
+ g.add(p,allowsolve);
+ }
+
+ pathguide(path p)
+ : p(p) {}
+
+ path solve() {
+ return p;
+ }
+
+ bool cyclic() {return p.cyclic();}
+
+ void print(ostream& out) const {
+ out << p;
+ }
+
+ side printLocation() const {
+ return END;
+ }
+};
+
+// Tension expressions are evaluated to this class before being cast to a guide,
+// so that they can be cast to other types (such as guide3) instead.
+class tensionSpecifier : public gc {
+ double out,in;
+ bool atleast;
+
+public:
+ tensionSpecifier(double val, bool atleast=false)
+ : out(val), in(val), atleast(atleast) {}
+ tensionSpecifier(double out, double in, bool atleast=false)
+ : out(out), in(in), atleast(atleast) {}
+
+ double getOut() const { return out; }
+ double getIn() const { return in; }
+ bool getAtleast() const { return atleast; }
+};
+
+
+// A guide giving tension information (as part of a join).
+class tensionguide : public guide {
+ tension tout,tin;
+
+public:
+ void flatten(flatguide& g, bool=true) {
+ g.setTension(tin,IN);
+ g.setTension(tout,OUT);
+ }
+
+ tensionguide(tensionSpecifier spec)
+ : tout(spec.getOut(), spec.getAtleast()),
+ tin(spec.getIn(), spec.getAtleast()) {}
+
+ void print(ostream& out) const {
+ out << (tout.atleast ? ".. tension atleast " : ".. tension ")
+ << tout.val << " and " << tin.val << " ..";
+ }
+
+ side printLocation() const {
+ return JOIN;
+ }
+};
+
+// Similar to tensionSpecifier, curl expression are evaluated to this type
+// before being cast to guides.
+class curlSpecifier : public gc {
+ double value;
+ side s;
+
+public:
+ curlSpecifier(double value, side s)
+ : value(value), s(s) {}
+
+ double getValue() const { return value; }
+ side getSide() const { return s; }
+};
+
+// A guide giving a specifier.
+class specguide : public guide {
+ spec *p;
+ side s;
+
+public:
+ void flatten(flatguide& g, bool=true) {
+ g.setSpec(p,s);
+ }
+
+ specguide(spec *p, side s)
+ : p(p), s(s) {}
+
+ specguide(curlSpecifier spec)
+ : p(new curlSpec(spec.getValue())), s(spec.getSide()) {}
+
+ void print(ostream& out) const {
+ out << *p;
+ }
+
+ side printLocation() const {
+ return s;
+ }
+};
+
+// A guide for explicit control points between two knots. This could be done
+// with two specguides, instead, but this prints nicer, and is easier to encode.
+class controlguide : public guide {
+ pair zout, zin;
+
+public:
+ void flatten(flatguide& g, bool=true) {
+ g.setSpec(new controlSpec(zout), OUT);
+ g.setSpec(new controlSpec(zin), IN);
+ }
+
+ controlguide(pair zout,pair zin)
+ : zout(zout),zin(zin) {}
+ controlguide(pair z)
+ : zout(z),zin(z) {}
+
+ void print(ostream& out) const {
+ out << ".. controls "
+ << zout << " and " << zin << " ..";
+ }
+
+ side printLocation() const {
+ return JOIN;
+ }
+};
+
+// A guide that is a sequence of other guides. This is used, for instance is
+// joins, where we have the left and right guide, and possibly specifiers and
+// tensions in between.
+typedef mem::vector<guide *> guidevector;
+
+class multiguide : public guide {
+ guidevector v;
+
+public:
+
+ void flatten(flatguide&, bool=true);
+
+ bool cyclic() {
+ size_t n=v.size();
+ if(n < 1) return false;
+ return v[n-1]->cyclic();
+ }
+
+ multiguide(guidevector& v)
+ : v(v) {}
+
+ path solve() {
+ if (settings::verbose>3) {
+ cerr << "solving guide:\n";
+ print(cerr); cerr << "\n\n";
+ }
+
+ flatguide g;
+ this->flatten(g);
+ path p=g.solve(false);
+
+ if (settings::verbose>3)
+ cerr << "solved as:\n" << p << "\n\n";
+
+ return p;
+ }
+
+ void print(ostream& out) const;
+
+ side printLocation() const {
+ return v.back()->printLocation();
+ }
+};
+
+struct cycleToken : public gc {};
+
+// A guide representing the cycle token.
+class cycletokguide : public guide {
+public:
+ void flatten(flatguide& g, bool allowsolve=true) {
+ // If cycles occur in the midst of a guide, the guide up to that point
+ // should be solved as a path. Any subsequent guide will work with that
+ // path locked in place.
+ if(allowsolve)
+ g.solve(true);
+ else
+ g.close();
+ }
+
+ bool cyclic() {return true;}
+
+ path solve() {
+ // Just a cycle on it's own makes an empty guide.
+ return path();
+ }
+
+ void print(ostream& out) const {
+ out << "cycle";
+ }
+
+ side printLocation() const {
+ return END;
+ }
+};
+
+} // namespace camp
+
+GC_DECLARE_PTRFREE(camp::pairguide);
+GC_DECLARE_PTRFREE(camp::tensionSpecifier);
+GC_DECLARE_PTRFREE(camp::tensionguide);
+GC_DECLARE_PTRFREE(camp::curlSpecifier);
+GC_DECLARE_PTRFREE(camp::controlguide);
+GC_DECLARE_PTRFREE(camp::cycleToken);
+GC_DECLARE_PTRFREE(camp::cycletokguide);
+
+#endif // GUIDE_H
diff --git a/Build/source/utils/asymptote/guideflags.h b/Build/source/utils/asymptote/guideflags.h
new file mode 100644
index 00000000000..37131422d29
--- /dev/null
+++ b/Build/source/utils/asymptote/guideflags.h
@@ -0,0 +1,17 @@
+/*****
+ * guideflags.h
+ * Tom Prince 2004/5/12
+ *
+ * These flags are used to indicate what specifications of the join are
+ * put on the stack.
+ *****/
+#ifndef GUIDEFLAGS_H
+#define GUIDEFLAGS_H
+
+namespace camp {
+
+enum side { OUT, IN, END, JOIN };
+
+}
+
+#endif //GUIDEFLAGS_H
diff --git a/Build/source/utils/asymptote/inst.h b/Build/source/utils/asymptote/inst.h
new file mode 100644
index 00000000000..c4f7efb8f86
--- /dev/null
+++ b/Build/source/utils/asymptote/inst.h
@@ -0,0 +1,63 @@
+/*****
+ * inst.h
+ * Andy Hammerlindl 2002/06/27
+ *
+ * Descibes the items and instructions that are used by the virtual machine.
+ *****/
+
+#ifndef INST_H
+#define INST_H
+
+#include <iterator>
+#include <iostream>
+
+#include "errormsg.h"
+#include "item.h"
+#include "vm.h"
+
+namespace vm {
+
+// Forward declarations
+struct inst; class stack; class program;
+
+// A function "lambda," that is, the code that runs a function.
+// It also need the closure of the enclosing module or function to run.
+struct lambda : public gc {
+ // The instructions to follow.
+ program *code;
+
+ // The number of parameters of the function. This does not include the
+ // closure of the enclosing module or function.
+ size_t params;
+
+ // The total number of items that will be stored in the closure of this
+ // function. Includes the higher closure, the parameters, and the local
+ // variables.
+ // NOTE: In order to help garbage collection, this could be modified to
+ // have one array store escaping items, and another to store non-
+ // escaping items.
+ size_t vars;
+};
+
+// The code run is just a string of instructions. The ops are actual commands
+// to be run, but constants, labels, and other objects can be in the code.
+struct inst : public gc {
+ enum opcode {
+ pop, intpush, constpush,
+ varpush, varsave, fieldpush, fieldsave,
+ builtin, jmp, cjmp, njmp, popcall,
+ pushclosure, makefunc, ret,
+ alloc, pushframe, popframe
+ };
+ opcode op;
+ position pos;
+ item ref;
+};
+template<typename T>
+inline T get(const inst& it)
+{ return get<T>(it.ref); }
+
+} // namespace vm
+
+#endif
+
diff --git a/Build/source/utils/asymptote/install-sh b/Build/source/utils/asymptote/install-sh
new file mode 100755
index 00000000000..08572bfd3c9
--- /dev/null
+++ b/Build/source/utils/asymptote/install-sh
@@ -0,0 +1,510 @@
+#!/bin/sh
+# install - install a program, script, or datafile
+
+scriptversion=2006-10-14.15J
+
+# This originates from X11R5 (mit/util/scripts/install.sh), which was
+# later released in X11R6 (xc/config/util/install.sh) with the
+# following copyright and license.
+#
+# Copyright (C) 1994 X Consortium
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to
+# deal in the Software without restriction, including without limitation the
+# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+# sell copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC-
+# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+#
+# Except as contained in this notice, the name of the X Consortium shall not
+# be used in advertising or otherwise to promote the sale, use or other deal-
+# ings in this Software without prior written authorization from the X Consor-
+# tium.
+#
+#
+# FSF changes to this file are in the public domain.
+#
+# Calling this script install-sh is preferred over install.sh, to prevent
+# `make' implicit rules from creating a file called install from it
+# when there is no Makefile.
+#
+# This script is compatible with the BSD install script, but was written
+# from scratch.
+
+nl='
+'
+IFS=" "" $nl"
+
+# set DOITPROG to echo to test this script
+
+# Don't use :- since 4.3BSD and earlier shells don't like it.
+doit="${DOITPROG-}"
+if test -z "$doit"; then
+ doit_exec=exec
+else
+ doit_exec=$doit
+fi
+
+# Put in absolute file names if you don't have them in your path;
+# or use environment vars.
+
+mvprog="${MVPROG-mv}"
+cpprog="${CPPROG-cp}"
+chmodprog="${CHMODPROG-chmod}"
+chownprog="${CHOWNPROG-chown}"
+chgrpprog="${CHGRPPROG-chgrp}"
+stripprog="${STRIPPROG-strip}"
+rmprog="${RMPROG-rm}"
+mkdirprog="${MKDIRPROG-mkdir}"
+
+posix_glob=
+posix_mkdir=
+
+# Desired mode of installed file.
+mode=0755
+
+chmodcmd=$chmodprog
+chowncmd=
+chgrpcmd=
+stripcmd=
+rmcmd="$rmprog -f"
+mvcmd="$mvprog"
+src=
+dst=
+dir_arg=
+dstarg=
+no_target_directory=
+
+usage="Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE
+ or: $0 [OPTION]... SRCFILES... DIRECTORY
+ or: $0 [OPTION]... -t DIRECTORY SRCFILES...
+ or: $0 [OPTION]... -d DIRECTORIES...
+
+In the 1st form, copy SRCFILE to DSTFILE.
+In the 2nd and 3rd, copy all SRCFILES to DIRECTORY.
+In the 4th, create DIRECTORIES.
+
+Options:
+-c (ignored)
+-d create directories instead of installing files.
+-g GROUP $chgrpprog installed files to GROUP.
+-m MODE $chmodprog installed files to MODE.
+-o USER $chownprog installed files to USER.
+-s $stripprog installed files.
+-t DIRECTORY install into DIRECTORY.
+-T report an error if DSTFILE is a directory.
+--help display this help and exit.
+--version display version info and exit.
+
+Environment variables override the default commands:
+ CHGRPPROG CHMODPROG CHOWNPROG CPPROG MKDIRPROG MVPROG RMPROG STRIPPROG
+"
+
+while test $# -ne 0; do
+ case $1 in
+ -c) shift
+ continue;;
+
+ -d) dir_arg=true
+ shift
+ continue;;
+
+ -g) chgrpcmd="$chgrpprog $2"
+ shift
+ shift
+ continue;;
+
+ --help) echo "$usage"; exit $?;;
+
+ -m) mode=$2
+ shift
+ shift
+ case $mode in
+ *' '* | *' '* | *'
+'* | *'*'* | *'?'* | *'['*)
+ echo "$0: invalid mode: $mode" >&2
+ exit 1;;
+ esac
+ continue;;
+
+ -o) chowncmd="$chownprog $2"
+ shift
+ shift
+ continue;;
+
+ -p) shift
+ continue;;
+
+ -s) stripcmd=$stripprog
+ shift
+ continue;;
+
+ -t) dstarg=$2
+ shift
+ shift
+ continue;;
+
+ -T) no_target_directory=true
+ shift
+ continue;;
+
+ --version) echo "$0 $scriptversion"; exit $?;;
+
+ --) shift
+ break;;
+
+ -*) echo "$0: invalid option: $1" >&2
+ exit 1;;
+
+ *) break;;
+ esac
+done
+
+if test $# -ne 0 && test -z "$dir_arg$dstarg"; then
+ # When -d is used, all remaining arguments are directories to create.
+ # When -t is used, the destination is already specified.
+ # Otherwise, the last argument is the destination. Remove it from $@.
+ for arg
+ do
+ if test -n "$dstarg"; then
+ # $@ is not empty: it contains at least $arg.
+ set fnord "$@" "$dstarg"
+ shift # fnord
+ fi
+ shift # arg
+ dstarg=$arg
+ done
+fi
+
+if test $# -eq 0; then
+ if test -z "$dir_arg"; then
+ echo "$0: no input file specified." >&2
+ exit 1
+ fi
+ # It's OK to call `install-sh -d' without argument.
+ # This can happen when creating conditional directories.
+ exit 0
+fi
+
+if test -z "$dir_arg"; then
+ trap '(exit $?); exit' 1 2 13 15
+
+ # Set umask so as not to create temps with too-generous modes.
+ # However, 'strip' requires both read and write access to temps.
+ case $mode in
+ # Optimize common cases.
+ *644) cp_umask=133;;
+ *755) cp_umask=22;;
+
+ *[0-7])
+ if test -z "$stripcmd"; then
+ u_plus_rw=
+ else
+ u_plus_rw='% 200'
+ fi
+ cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;;
+ *)
+ if test -z "$stripcmd"; then
+ u_plus_rw=
+ else
+ u_plus_rw=,u+rw
+ fi
+ cp_umask=$mode$u_plus_rw;;
+ esac
+fi
+
+for src
+do
+ # Protect names starting with `-'.
+ case $src in
+ -*) src=./$src ;;
+ esac
+
+ if test -n "$dir_arg"; then
+ dst=$src
+ dstdir=$dst
+ test -d "$dstdir"
+ dstdir_status=$?
+ else
+
+ # Waiting for this to be detected by the "$cpprog $src $dsttmp" command
+ # might cause directories to be created, which would be especially bad
+ # if $src (and thus $dsttmp) contains '*'.
+ if test ! -f "$src" && test ! -d "$src"; then
+ echo "$0: $src does not exist." >&2
+ exit 1
+ fi
+
+ if test -z "$dstarg"; then
+ echo "$0: no destination specified." >&2
+ exit 1
+ fi
+
+ dst=$dstarg
+ # Protect names starting with `-'.
+ case $dst in
+ -*) dst=./$dst ;;
+ esac
+
+ # If destination is a directory, append the input filename; won't work
+ # if double slashes aren't ignored.
+ if test -d "$dst"; then
+ if test -n "$no_target_directory"; then
+ echo "$0: $dstarg: Is a directory" >&2
+ exit 1
+ fi
+ dstdir=$dst
+ dst=$dstdir/`basename "$src"`
+ dstdir_status=0
+ else
+ # Prefer dirname, but fall back on a substitute if dirname fails.
+ dstdir=`
+ (dirname "$dst") 2>/dev/null ||
+ expr X"$dst" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$dst" : 'X\(//\)[^/]' \| \
+ X"$dst" : 'X\(//\)$' \| \
+ X"$dst" : 'X\(/\)' \| . 2>/dev/null ||
+ echo X"$dst" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)[^/].*/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'
+ `
+
+ test -d "$dstdir"
+ dstdir_status=$?
+ fi
+ fi
+
+ obsolete_mkdir_used=false
+
+ if test $dstdir_status != 0; then
+ case $posix_mkdir in
+ '')
+ # Create intermediate dirs using mode 755 as modified by the umask.
+ # This is like FreeBSD 'install' as of 1997-10-28.
+ umask=`umask`
+ case $stripcmd.$umask in
+ # Optimize common cases.
+ *[2367][2367]) mkdir_umask=$umask;;
+ .*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;;
+
+ *[0-7])
+ mkdir_umask=`expr $umask + 22 \
+ - $umask % 100 % 40 + $umask % 20 \
+ - $umask % 10 % 4 + $umask % 2
+ `;;
+ *) mkdir_umask=$umask,go-w;;
+ esac
+
+ # With -d, create the new directory with the user-specified mode.
+ # Otherwise, rely on $mkdir_umask.
+ if test -n "$dir_arg"; then
+ mkdir_mode=-m$mode
+ else
+ mkdir_mode=
+ fi
+
+ posix_mkdir=false
+ case $umask in
+ *[123567][0-7][0-7])
+ # POSIX mkdir -p sets u+wx bits regardless of umask, which
+ # is incompatible with FreeBSD 'install' when (umask & 300) != 0.
+ ;;
+ *)
+ tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$
+ trap 'ret=$?; rmdir "$tmpdir/d" "$tmpdir" 2>/dev/null; exit $ret' 0
+
+ if (umask $mkdir_umask &&
+ exec $mkdirprog $mkdir_mode -p -- "$tmpdir/d") >/dev/null 2>&1
+ then
+ if test -z "$dir_arg" || {
+ # Check for POSIX incompatibilities with -m.
+ # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or
+ # other-writeable bit of parent directory when it shouldn't.
+ # FreeBSD 6.1 mkdir -m -p sets mode of existing directory.
+ ls_ld_tmpdir=`ls -ld "$tmpdir"`
+ case $ls_ld_tmpdir in
+ d????-?r-*) different_mode=700;;
+ d????-?--*) different_mode=755;;
+ *) false;;
+ esac &&
+ $mkdirprog -m$different_mode -p -- "$tmpdir" && {
+ ls_ld_tmpdir_1=`ls -ld "$tmpdir"`
+ test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1"
+ }
+ }
+ then posix_mkdir=:
+ fi
+ rmdir "$tmpdir/d" "$tmpdir"
+ else
+ # Remove any dirs left behind by ancient mkdir implementations.
+ rmdir ./$mkdir_mode ./-p ./-- 2>/dev/null
+ fi
+ trap '' 0;;
+ esac;;
+ esac
+
+ if
+ $posix_mkdir && (
+ umask $mkdir_umask &&
+ $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir"
+ )
+ then :
+ else
+
+ # The umask is ridiculous, or mkdir does not conform to POSIX,
+ # or it failed possibly due to a race condition. Create the
+ # directory the slow way, step by step, checking for races as we go.
+
+ case $dstdir in
+ /*) prefix=/ ;;
+ -*) prefix=./ ;;
+ *) prefix= ;;
+ esac
+
+ case $posix_glob in
+ '')
+ if (set -f) 2>/dev/null; then
+ posix_glob=true
+ else
+ posix_glob=false
+ fi ;;
+ esac
+
+ oIFS=$IFS
+ IFS=/
+ $posix_glob && set -f
+ set fnord $dstdir
+ shift
+ $posix_glob && set +f
+ IFS=$oIFS
+
+ prefixes=
+
+ for d
+ do
+ test -z "$d" && continue
+
+ prefix=$prefix$d
+ if test -d "$prefix"; then
+ prefixes=
+ else
+ if $posix_mkdir; then
+ (umask=$mkdir_umask &&
+ $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break
+ # Don't fail if two instances are running concurrently.
+ test -d "$prefix" || exit 1
+ else
+ case $prefix in
+ *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;;
+ *) qprefix=$prefix;;
+ esac
+ prefixes="$prefixes '$qprefix'"
+ fi
+ fi
+ prefix=$prefix/
+ done
+
+ if test -n "$prefixes"; then
+ # Don't fail if two instances are running concurrently.
+ (umask $mkdir_umask &&
+ eval "\$doit_exec \$mkdirprog $prefixes") ||
+ test -d "$dstdir" || exit 1
+ obsolete_mkdir_used=true
+ fi
+ fi
+ fi
+
+ if test -n "$dir_arg"; then
+ { test -z "$chowncmd" || $doit $chowncmd "$dst"; } &&
+ { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } &&
+ { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false ||
+ test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1
+ else
+
+ # Make a couple of temp file names in the proper directory.
+ dsttmp=$dstdir/_inst.$$_
+ rmtmp=$dstdir/_rm.$$_
+
+ # Trap to clean up those temp files at exit.
+ trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0
+
+ # Copy the file name to the temp name.
+ (umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") &&
+
+ # and set any options; do chmod last to preserve setuid bits.
+ #
+ # If any of these fail, we abort the whole thing. If we want to
+ # ignore errors from any of these, just make sure not to ignore
+ # errors from the above "$doit $cpprog $src $dsttmp" command.
+ #
+ { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } \
+ && { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } \
+ && { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } \
+ && { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } &&
+
+ # Now 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.
+ {
+ if test -f "$dst"; then
+ $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
+ }
+ else
+ :
+ fi
+ } &&
+
+ # Now rename the file to the real destination.
+ $doit $mvcmd "$dsttmp" "$dst"
+ }
+ } || exit 1
+
+ trap '' 0
+ fi
+done
+
+# Local variables:
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "scriptversion="
+# time-stamp-format: "%:y-%02m-%02d.%02H"
+# time-stamp-end: "$"
+# End:
diff --git a/Build/source/utils/asymptote/interact.cc b/Build/source/utils/asymptote/interact.cc
new file mode 100644
index 00000000000..43c7184ffe2
--- /dev/null
+++ b/Build/source/utils/asymptote/interact.cc
@@ -0,0 +1,197 @@
+/*****
+ * interact.cc
+ *
+ * The glue between the lexical analyzer and the readline library.
+ *****/
+
+#include <cstdlib>
+#include <cassert>
+#include <iostream>
+#include <sstream>
+#include <sys/wait.h>
+#include <sys/types.h>
+#include <unistd.h>
+#include <csignal>
+
+#include "interact.h"
+
+#if defined(HAVE_LIBREADLINE) && defined(HAVE_LIBCURSES)
+#include <readline/readline.h>
+#include <readline/history.h>
+#endif
+
+#include "util.h"
+#include "errormsg.h"
+
+using namespace settings;
+
+namespace run {
+void init_readline(bool);
+}
+
+namespace interact {
+
+bool interactive=false;
+bool uptodate=true;
+int lines=0;
+bool query=false;
+
+bool tty=isatty(STDIN_FILENO);
+completer *currentCompleter=0;
+
+void setCompleter(completer *c) {
+ currentCompleter=c;
+}
+
+char *call_completer(const char *text, int state) {
+ return currentCompleter ? (*currentCompleter)(text, state) : 0;
+}
+
+#if defined(HAVE_LIBREADLINE) && defined(HAVE_LIBCURSES)
+void init_completion() {
+ rl_completion_entry_function=call_completer;
+
+ rl_completion_append_character='\0'; // Don't add a space after a match.
+
+ // Build a string containing all characters that separate words to be
+ // completed. All characters that can't form part of an identifier are
+ // treated as break characters.
+ static char break_characters[128];
+ Int j=0;
+ for (unsigned char c=9; c<128; ++c)
+ if (!isalnum(c) && c != '_') {
+ break_characters[j]=c;
+ ++j;
+ }
+ break_characters[j]='\0';
+ rl_completer_word_break_characters=break_characters;
+}
+#endif
+
+char *(*Readline)(const char *prompt);
+
+char *verbatimreadline(const char *prompt)
+{
+ if(!cin.good()) {cin.clear(); return NULL;}
+ cout << prompt;
+ string s;
+ getline(cin,s);
+ return StrdupMalloc(s);
+}
+
+void pre_readline()
+{
+#if defined(HAVE_LIBREADLINE) && defined(HAVE_LIBCURSES)
+ if(tty) {
+ run::init_readline(getSetting<bool>("tabcompletion"));
+ Readline=readline;
+ } else
+#endif
+ Readline=verbatimreadline;
+}
+
+void init_interactive()
+{
+#if defined(HAVE_LIBREADLINE) && defined(HAVE_LIBCURSES)
+ if(tty) {
+ init_completion();
+ read_history(historyname.c_str());
+ }
+#endif
+}
+
+string simpleline(string prompt) {
+ // Rebind tab key, as the setting tabcompletion may be changed at runtime.
+ pre_readline();
+
+ // Get a line from the user.
+ char *line=Readline(prompt.c_str());
+
+ // Reset scroll count.
+ interact::lines=0;
+ interact::query=tty;
+
+ // Ignore keyboard interrupts while taking input.
+ errorstream::interrupt=false;
+
+ if(line) {
+ string s=line;
+ free(line);
+ return s;
+ } else {
+ cout << endl;
+ if(!tty || getSetting<bool>("exitonEOF"))
+ throw eof();
+ return "\n";
+ }
+}
+
+void addToHistory(string line) {
+#if defined(HAVE_LIBREADLINE) && defined(HAVE_LIBCURSES)
+ // Only add it if it has something other than newlines.
+ if(tty && line.find_first_not_of('\n') != string::npos) {
+ add_history(line.c_str());
+ }
+#endif
+}
+
+string getLastHistoryLine() {
+#if defined(HAVE_LIBREADLINE) && defined(HAVE_LIBCURSES)
+ if(tty && history_length > 0) {
+ HIST_ENTRY *entry=history_list()[history_length-1];
+ if(!entry) {
+ em.compiler();
+ em << "cannot access last history line";
+ return "";
+ } else
+ return entry->line;
+ } else
+#endif
+ return "";
+}
+
+void setLastHistoryLine(string line) {
+#if defined(HAVE_LIBREADLINE) && defined(HAVE_LIBCURSES)
+ if(tty) {
+ if (history_length > 0) {
+ HIST_ENTRY *entry=remove_history(history_length-1);
+
+ if(!entry) {
+ em.compiler();
+ em << "cannot modify last history line";
+ } else {
+ free(entry->line);
+ free(entry);
+ }
+ }
+ addToHistory(line);
+ }
+#endif
+}
+
+void deleteLastLine() {
+#if defined(HAVE_LIBREADLINE) && defined(HAVE_LIBCURSES)
+ if(tty) {
+ HIST_ENTRY *entry=remove_history(history_length-1);
+ if(!entry) {
+ em.compiler();
+ em << "cannot delete last history line";
+ } else {
+ free(entry->line);
+ free(entry);
+ }
+ }
+#endif
+}
+
+void cleanup_interactive() {
+#if defined(HAVE_LIBREADLINE) && defined(HAVE_LIBCURSES)
+ // Write the history file.
+ if(tty) {
+ stifle_history(intcast(getSetting<Int>("historylines")));
+ write_history(historyname.c_str());
+ }
+#endif
+}
+
+} // namespace interact
diff --git a/Build/source/utils/asymptote/interact.h b/Build/source/utils/asymptote/interact.h
new file mode 100644
index 00000000000..317496b52d4
--- /dev/null
+++ b/Build/source/utils/asymptote/interact.h
@@ -0,0 +1,52 @@
+/*****
+ * interact.h
+ *
+ * The glue between the lexical analyzer and the readline library.
+ *****/
+
+#ifndef INTERACT_H
+#define INTERACT_H
+
+#include "common.h"
+
+namespace interact {
+
+extern bool interactive;
+extern bool uptodate;
+extern int lines; // Interactive scroll count
+extern bool query; // Enable interactive scrolling;
+
+void init_interactive();
+
+// Read a line from the input, without any processing.
+string simpleline(string prompt);
+
+// Add a line of input to the readline history.
+void addToHistory(string line);
+
+// Functions to work with the most recently entered line in the history.
+string getLastHistoryLine();
+void setLastHistoryLine(string line);
+
+// Remove the line last added to the history.
+void deleteLastLine();
+
+// Write out the history of input lines to the history file.
+void cleanup_interactive();
+
+// This class is used to set a text completion function for readline. A class
+// is used instead the usual function pointer so that information such as the
+// current environment can be coded into the function (mimicking a closure).
+class completer : public gc {
+public:
+ virtual ~completer() {};
+ virtual char *operator () (const char *text, int state) = 0;
+};
+
+void setCompleter(completer *c);
+
+#define YY_READ_BUF_SIZE YY_BUF_SIZE
+
+}
+
+#endif // INTERACT_H
diff --git a/Build/source/utils/asymptote/item.h b/Build/source/utils/asymptote/item.h
new file mode 100644
index 00000000000..9df090cc948
--- /dev/null
+++ b/Build/source/utils/asymptote/item.h
@@ -0,0 +1,201 @@
+/*****
+ * inst.h
+ * Tom Prince and John Bowman 2005/04/12
+ *
+ * Descibes the items that are used by the virtual machine.
+ *****/
+
+#ifndef ITEM_H
+#define ITEM_H
+
+#include "common.h"
+#include <typeinfo>
+
+
+namespace vm {
+
+class item;
+class bad_item_value {};
+
+template<typename T>
+T get(const item&);
+
+class item : public gc {
+public:
+ bool empty()
+ { return *kind == typeid(void); }
+
+ item()
+ : kind(&typeid(void)) {}
+
+#ifndef Int
+ item(Int i)
+ : kind(&typeid(Int)), i(i) {}
+#endif
+ item(int i)
+ : kind(&typeid(Int)), i(i) {}
+ item(double x)
+ : kind(&typeid(double)), x(x) {}
+ item(bool b)
+ : kind(&typeid(bool)), b(b) {}
+
+#ifndef Int
+ item& operator= (int a)
+ { kind=&typeid(Int); i=a; return *this; }
+#endif
+ item& operator= (Int a)
+ { kind=&typeid(Int); i=a; return *this; }
+ item& operator= (double a)
+ { kind=&typeid(double); x=a; return *this; }
+ item& operator= (bool a)
+ { kind=&typeid(bool); b=a; return *this; }
+
+ template<class T>
+ item(T *p)
+ : kind(&typeid(T)), p((void *) p) {}
+
+ template<class T>
+ item(const T &p)
+ : kind(&typeid(T)), p(new(UseGC) T(p)) {}
+
+ template<class T>
+ item& operator= (T *a)
+ { kind=&typeid(T); p=(void *) a; return *this; }
+
+ template<class T>
+ item& operator= (const T &it)
+ { kind=&typeid(T); p=new(UseGC) T(it); return *this; }
+
+ template<typename T>
+ friend inline T get(const item&);
+
+ friend inline bool isdefault(const item&);
+ friend inline bool isarray(const item&);
+
+ const std::type_info &type() const
+ { return *kind; }
+
+ friend ostream& operator<< (ostream& out, const item& i);
+
+private:
+
+ const std::type_info *kind;
+
+ union {
+ Int i;
+ double x;
+ bool b;
+ void *p;
+ };
+
+ template <typename T>
+ struct help;
+
+ template <typename T>
+ struct help<T*> {
+ static T* unwrap(const item& it)
+ {
+ if (*it.kind == typeid(T))
+ return (T*) it.p;
+ throw vm::bad_item_value();
+ }
+ };
+
+ template <typename T>
+ struct help {
+ static T& unwrap(const item& it)
+ {
+ if (*it.kind == typeid(T))
+ return *(T*) it.p;
+ throw vm::bad_item_value();
+ }
+ };
+};
+
+class frame : public gc {
+ typedef mem::vector<item> vars_t;
+ vars_t vars;
+public:
+ frame(size_t size)
+ : vars(size)
+ {}
+
+ item& operator[] (size_t n)
+ { return vars[n]; }
+ item operator[] (size_t n) const
+ { return vars[n]; }
+
+ size_t size()
+ { return vars.size(); }
+
+ // Extends vars to ensure it has a place for any variable indexed up to n.
+ void extend(size_t n) {
+ if (vars.size() < n)
+ vars.resize(n);
+ }
+};
+
+template<typename T>
+inline T get(const item& it)
+{
+ return item::help<T>::unwrap(it);
+}
+
+#ifndef Int
+template <>
+inline int get<int>(const item&)
+{
+ throw vm::bad_item_value();
+}
+#endif
+
+template <>
+inline Int get<Int>(const item& it)
+{
+ if (*it.kind == typeid(Int))
+ return it.i;
+ throw vm::bad_item_value();
+}
+
+template <>
+inline double get<double>(const item& it)
+{
+ if (*it.kind == typeid(double))
+ return it.x;
+ throw vm::bad_item_value();
+}
+
+template <>
+inline bool get<bool>(const item& it)
+{
+ if (*it.kind == typeid(bool))
+ return it.b;
+ throw vm::bad_item_value();
+}
+
+// This serves as the object for representing a default argument.
+struct default_t : public gc {};
+
+inline bool isdefault(const item& it)
+{
+ return *it.kind == typeid(default_t);
+}
+
+inline ostream& operator<< (ostream& out, const item& i)
+{
+ out << "type " << i.type().name();
+ if (i.type() == typeid(Int))
+ cout << ", value = " << get<Int>(i) << endl;
+ else if (i.type() == typeid(double))
+ cout << ", value = " << get<double>(i) << endl;
+ else if (i.type() == typeid(string))
+ cout << ", value = " << get<string>(i) << endl;
+ else out << endl;
+ return out;
+}
+
+} // namespace vm
+
+GC_DECLARE_PTRFREE(vm::default_t);
+
+#endif // ITEM_H
diff --git a/Build/source/utils/asymptote/keywords.cc b/Build/source/utils/asymptote/keywords.cc
new file mode 100644
index 00000000000..97f7dac517c
--- /dev/null
+++ b/Build/source/utils/asymptote/keywords.cc
@@ -0,0 +1,45 @@
+/*****
+ * This file is automatically generated by keywords.pl.
+ * Changes will be overwritten.
+ *****/
+
+ADD(and);
+ADD(controls);
+ADD(tension);
+ADD(atleast);
+ADD(curl);
+ADD(if);
+ADD(else);
+ADD(while);
+ADD(for);
+ADD(do);
+ADD(return);
+ADD(break);
+ADD(continue);
+ADD(struct);
+ADD(typedef);
+ADD(new);
+ADD(access);
+ADD(import);
+ADD(unravel);
+ADD(from);
+ADD(include);
+ADD(quote);
+ADD(static);
+ADD(public);
+ADD(private);
+ADD(restricted);
+ADD(this);
+ADD(explicit);
+ADD(true);
+ADD(false);
+ADD(null);
+ADD(cycle);
+ADD(newframe);
+ADD(operator);
+ADD(quit);
+ADD(q);
+ADD(exit);
+ADD(reset);
+ADD(help);
+ADD(input);
diff --git a/Build/source/utils/asymptote/keywords.pl b/Build/source/utils/asymptote/keywords.pl
new file mode 100755
index 00000000000..d3b48c5220c
--- /dev/null
+++ b/Build/source/utils/asymptote/keywords.pl
@@ -0,0 +1,60 @@
+#!/usr/bin/env perl
+#####
+# keywords.pl
+# Andy Hammerlindl 2006/07/31
+#
+# Extract keywords from camp.l and list them in a keywords file. These
+# keywords are used in autocompletion at the interactive prompt.
+#####
+
+# Extra keywords to add that aren't automatically extracted, currently none.
+@extrawords = ();
+
+
+open(keywords, ">keywords.cc") ||
+ die("Couldn't open keywords.out for writing.");
+
+print keywords <<END;
+/*****
+ * This file is automatically generated by keywords.pl.
+ * Changes will be overwritten.
+ *****/
+
+END
+
+sub add {
+ print keywords "ADD(".$_[0].");\n";
+}
+
+foreach $word (@extrawords) {
+ add($word);
+}
+
+open(camp, "camp.l") || die("Couldn't open camp.l");
+
+# Search for the %% separator, after which the definitions start.
+while (<camp>) {
+ if (/^%%\s*$/) {
+ last; # Break out of the loop.
+ }
+}
+
+# Grab simple keyword definitions from camp.l
+while (<camp>) {
+ if (/^%%\s*$/) {
+ last; # A second %% indicates the end of definitions.
+ }
+ if (/^([A-Za-z_][A-Za-z0-9_]*)\s*\{/) {
+ add($1);
+ }
+}
+
+# Grab the special commands from the interactive prompt.
+open(process, "process.cc") || dir("Couldn't open process.cc");
+
+while (<process>) {
+ if (/^\s*ADDCOMMAND\(\s*([A-Za-z_][A-Za-z0-9_]*),/) {
+ add($1);
+ }
+}
+
diff --git a/Build/source/utils/asymptote/knot.cc b/Build/source/utils/asymptote/knot.cc
new file mode 100644
index 00000000000..0180c4c6b2d
--- /dev/null
+++ b/Build/source/utils/asymptote/knot.cc
@@ -0,0 +1,840 @@
+/*****
+ * knot.cc
+ * Andy Hammerlindl 2005/02/10
+ *
+ * Describes a knot, a point and its neighbouring specifiers, used as an
+ * intermediate structure in solving paths.
+ *****/
+
+#include "knot.h"
+#include "util.h"
+
+#include "angle.h"
+#include "settings.h"
+
+namespace camp {
+
+/***** Debugging *****/
+//bool tracing_solving=false;
+
+template <typename T>
+ostream& info(ostream& o, string name, cvector<T>& v)
+{
+ if (settings::verbose > 3) {
+ o << name << ":\n\n";
+
+ for(Int i=0; i < (Int) v.size(); ++i)
+ o << v[i] << endl;
+
+ o << endl;
+ }
+ return o;
+}
+
+ostream& info(ostream& o, string name, knotlist& l)
+{
+ if (settings::verbose > 3) {
+ o << name << ":\n\n";
+
+ for(Int i=0; i < (Int) l.size(); ++i)
+ o << l[i] << endl;
+
+ if (l.cyclic())
+ o << "cyclic" << endl;
+
+ o << endl;
+ }
+ return o;
+}
+
+#define INFO(x) info(cerr,#x,x)
+
+/***** Auxillary computation functions *****/
+
+// Computes the relative distance of a control point given the angles.
+// The name is somewhat misleading as the velocity (with respect to the
+// variable that parameterizes the path) is relative to the distance
+// between the knots and even then, is actually three times this.
+// The routine is based on the velocity function in Section 131 of the MetaPost
+// code, but differs in that it automatically accounts for the tension and
+// bounding with tension atleast.
+double velocity(double theta, double phi, tension t)
+{
+ static const double VELOCITY_BOUND = 4.0;
+ static const double a = sqrt(2.0);
+ static const double b = 1.0/16.0;
+ static const double c = 1.5*(sqrt(5.0)-1.0);
+ static const double d = 1.5*(3.0-sqrt(5.0));
+
+ double st = sin(theta), ct = cos(theta),
+ sf = sin(phi), cf = cos(phi);
+
+ double denom = t.val * (3.0 + c*ct + d*cf);
+
+ double r = denom != 0.0 ? (2.0 + a*(st - b*sf)*(sf - b*st)*(ct-cf)) / denom
+ : VELOCITY_BOUND;
+
+ //cerr << " velocity(" << theta << "," << phi <<")= " << r << endl;
+ if (r > VELOCITY_BOUND)
+ r = VELOCITY_BOUND;
+
+ // Apply boundedness condition for tension atleast cases.
+ if (t.atleast)
+ {
+ double sine = sin(theta + phi);
+ if ((st >= 0.0 && sf >= 0.0 && sine > 0.0) ||
+ (st <= 0.0 && sf <= 0.0 && sine < 0.0))
+ {
+ double rmax = sf / sine;
+ if (r > rmax)
+ r = rmax;
+ }
+ }
+
+ return r;
+}
+
+double niceAngle(pair z)
+{
+ return z.gety() == 0 ? z.getx() >= 0 ? 0 : PI
+ : angle(z);
+}
+
+// Ensures an angle is in the range between -PI and PI.
+double reduceAngle(double angle)
+{
+ return angle > PI ? angle - 2.0*PI :
+ angle < -PI ? angle + 2.0*PI :
+ angle;
+}
+
+
+bool interesting(tension t)
+{
+ return t.val!=1.0 || t.atleast==true;
+}
+
+bool interesting(spec *s)
+{
+ return !s->open();
+}
+
+ostream& operator<<(ostream& out, const knot& k)
+{
+ if (interesting(k.tin))
+ out << k.tin << " ";
+ if (interesting(k.in))
+ out << *k.in << " ";
+ out << k.z;
+ if (interesting(k.out))
+ out << " " << *k.out;
+ if (interesting(k.tout))
+ out << " " << k.tout;
+ return out;
+}
+
+
+eqn dirSpec::eqnOut(Int j, knotlist& l, cvector<double>&, cvector<double>&)
+{
+ // When choosing the control points, the path will come out the first knot
+ // going straight to the next knot rotated by the angle theta.
+ // Therefore, the angle theta we want is the difference between the
+ // specified heading given and the heading to the next knot.
+ double theta=reduceAngle(given-niceAngle(l[j+1].z-l[j].z));
+
+ // Give a simple linear equation to ensure this theta is picked.
+ return eqn(0.0,1.0,0.0,theta);
+}
+
+eqn dirSpec::eqnIn(Int j, knotlist& l, cvector<double>&, cvector<double>&)
+{
+ double theta=reduceAngle(given-niceAngle(l[j].z-l[j-1].z));
+ return eqn(0.0,1.0,0.0,theta);
+}
+
+eqn curlSpec::eqnOut(Int j, knotlist& l, cvector<double>&,
+ cvector<double>& psi)
+{
+ double alpha=l[j].alpha();
+ double beta=l[j+1].beta();
+
+ double chi=alpha*alpha*gamma/(beta*beta);
+
+ double C=alpha*chi+3-beta;
+ double D=(3.0-alpha)*chi+beta;
+
+ return eqn(0.0,C,D,-D*psi[j+1]);
+}
+
+eqn curlSpec::eqnIn(Int j, knotlist& l, cvector<double>&, cvector<double>&)
+{
+ double alpha=l[j-1].alpha();
+ double beta=l[j].beta();
+
+ double chi=beta*beta*gamma/(alpha*alpha);
+
+ double A=(3-beta)*chi+alpha;
+ double B=beta*chi+3-alpha;
+
+ return eqn(A,B,0.0,0.0);
+}
+
+spec *controlSpec::outPartner(pair z)
+{
+ static curlSpec curl;
+ return cz==z ? (spec *)&curl : (spec *)new dirSpec(z-cz);
+}
+
+spec *controlSpec::inPartner(pair z)
+{
+ static curlSpec curl;
+ return cz==z ? (spec *)&curl : (spec *)new dirSpec(cz-z);
+}
+
+// Compute the displacement between points. The j-th result is the distance
+// between knot j and knot j+1.
+struct dzprop : public knotprop<pair> {
+ dzprop(knotlist& l)
+ : knotprop<pair>(l) {}
+
+ pair solo(Int) { return pair(0,0); }
+ pair start(Int j) { return l[j+1].z - l[j].z; }
+ pair mid(Int j) { return l[j+1].z - l[j].z; }
+ pair end(Int) { return pair(0,0); }
+};
+
+// Compute the distance between points, using the already computed dz. This
+// doesn't use the infomation in the knots, but the knotprop class is useful as
+// it takes care of the iteration for us.
+struct dprop : public knotprop<double> {
+ cvector<pair>& dz;
+
+ dprop(knotlist &l, cvector<pair>& dz)
+ : knotprop<double>(l), dz(dz) {}
+
+ double solo(Int j) { return length(dz[j]); }
+ double start(Int j) { return length(dz[j]); }
+ double mid(Int j) { return length(dz[j]); }
+ double end(Int j) { return length(dz[j]); }
+};
+
+// Compute the turning angles (psi) between points, using the already computed
+// dz.
+struct psiprop : public knotprop<double> {
+ cvector<pair>& dz;
+
+ psiprop(knotlist &l, cvector<pair>& dz)
+ : knotprop<double>(l), dz(dz) {}
+
+ double solo(Int) { return 0; }
+
+ // We set the starting and ending psi to zero.
+ double start(Int) { return 0; }
+ double end(Int) { return 0; }
+
+ double mid(Int j) { return niceAngle(dz[j]/dz[j-1]); }
+};
+
+struct eqnprop : public knotprop<eqn> {
+ cvector<double>& d;
+ cvector<double>& psi;
+
+ eqnprop(knotlist &l, cvector<double>& d, cvector<double>& psi)
+ : knotprop<eqn>(l), d(d), psi(psi) {}
+
+ eqn solo(Int) {
+ assert(False);
+ return eqn(0.0,1.0,0.0,0.0);
+ }
+
+ eqn start(Int j) {
+ // Defer to the specifier, as it knows the specifics.
+ return dynamic_cast<endSpec *>(l[j].out)->eqnOut(j,l,d,psi);
+ }
+
+ eqn end(Int j) {
+ return dynamic_cast<endSpec *>(l[j].in)->eqnIn(j,l,d,psi);
+ }
+
+ eqn mid(Int j) {
+ double lastAlpha = l[j-1].alpha();
+ double thisAlpha = l[j].alpha();
+ double thisBeta = l[j].beta();
+ double nextBeta = l[j+1].beta();
+
+ // Values based on the linear approximation of the curvature coming
+ // into the knot with respect to theta[j-1] and theta[j].
+ double inFactor = 1.0/(thisBeta*thisBeta*d[j-1]);
+ double A = lastAlpha*inFactor;
+ double B = (3.0 - lastAlpha)*inFactor;
+
+ // Values based on the linear approximation of the curvature going out of
+ // the knot with respect to theta[j] and theta[j+1].
+ double outFactor = 1.0/(thisAlpha*thisAlpha*d[j]);
+ double C = (3.0 - nextBeta)*outFactor;
+ double D = nextBeta*outFactor;
+
+ return eqn(A,B+C,D,-B*psi[j]-D*psi[j+1]);
+ }
+};
+
+// If the system of equations is homogeneous (ie. we are solving for x in
+// Ax=0), there is no need to solve for theta; we can just use zeros for the
+// thetas. In fact, our general solving method may not work in this case.
+// A common example of this is
+//
+// a{curl 1}..{curl 1}b
+//
+// which arises when solving a one-length path a..b or in a larger path a
+// section a--b.
+bool homogeneous(cvector<eqn>& e)
+{
+ for(cvector<eqn>::iterator p=e.begin(); p!=e.end(); ++p)
+ if (p->aug != 0)
+ return false;
+ return true;
+}
+
+// Checks whether the equation being solved will be solved as a straight
+// path from the first point to the second.
+bool straightSection(cvector<eqn>& e)
+{
+ return e.size()==2 && e.front().aug==0 && e.back().aug==0;
+}
+
+struct weqn : public eqn {
+ double w;
+ weqn(double pre, double piv, double post, double aug, double w=0)
+ : eqn(pre,piv,post,aug), w(w) {}
+
+ friend ostream& operator<< (ostream& out, const weqn we)
+ {
+ return out << (eqn &)we << " + " << we.w << " * theta[0]";
+ }
+};
+
+weqn scale(weqn q) {
+ assert(q.pre == 0 && q.piv != 0);
+ return weqn(0,1,q.post/q.piv,q.aug/q.piv,q.w/q.piv);
+}
+
+/* Recalculate the equations in the form:
+ * theta[j] + post * theta[j+1] = aug + w * theta[0]
+ *
+ * Used as the first step in solve cyclic equations.
+ */
+cvector<weqn> recalc(cvector<eqn>& e)
+{
+ Int n=(Int) e.size();
+ cvector<weqn> we;
+ weqn lasteqn(0,1,0,0,1);
+ we.push_back(lasteqn); // As a placeholder.
+ for (Int j=1; j < n; j++) {
+ // Subtract a factor of the last equation so that the first entry is
+ // zero, then procede to scale it.
+ eqn& q=e[j];
+ lasteqn=scale(weqn(0,q.piv-q.pre*lasteqn.post,q.post,
+ q.aug-q.pre*lasteqn.aug,-q.pre*lasteqn.w));
+ we.push_back(lasteqn);
+ }
+ // To keep all of the infomation enocoded in the linear equations, we need
+ // to augment the computation to replace our trivial start weqn with a
+ // real one. To do this, we take one more step in the iteration and
+ // compute the weqn for j=n, since n=0 (mod n).
+ {
+ eqn& q=e[0];
+ we.front()=scale(weqn(0,q.piv-q.pre*lasteqn.post,q.post,
+ q.aug-q.pre*lasteqn.aug,-q.pre*lasteqn.w));
+ }
+ return we;
+}
+
+double solveForTheta0(cvector<weqn>& we)
+{
+ // Solve for theta[0]=theta[n].
+ // How we do this is essentially to write out the first equation as:
+ //
+ // theta[n] = aug[0] + w[0]*theta[0] - post[0]*theta[1]
+ //
+ // and then use the next equation to substitute in for theta[1]:
+ //
+ // theta[1] = aug[1] + w[1]*theta[0] - post[1]*theta[2]
+ //
+ // and so on until we have an equation just in terms of theta[0] and
+ // theta[n] (which are the same theta).
+ //
+ // The loop invariant maintained is that after j iterations, we have
+ // theta[n]= a + b*theta[0] + c*theta[j]
+ Int n=(Int) we.size();
+ double a=0,b=0,c=1;
+ for (Int j=0;j<n;++j) {
+ weqn& q=we[j];
+ a+=c*q.aug;
+ b+=c*q.w;
+ c=-c*q.post;
+ }
+
+ // After the iteration we have
+ //
+ // theta[n] = a + b*theta[0] + c*theta[n]
+ //
+ // where theta[n]=theta[0], so
+ return a/(1.0-(b+c));
+}
+
+cvector<double> backsubCyclic(cvector<weqn>& we, double theta0)
+{
+ Int n=(Int) we.size();
+ cvector<double> thetas;
+ double lastTheta=theta0;
+ for (Int j=1;j<=n;++j)
+ {
+ weqn& q=we[n-j];
+ assert(q.pre == 0 && q.piv == 1);
+ double theta=-q.post*lastTheta+q.aug+q.w*theta0;
+ thetas.push_back(theta);
+ lastTheta=theta;
+ }
+ reverse(thetas.begin(),thetas.end());
+ return thetas;
+}
+
+// For the non-cyclic equations, do row operation to put the matrix into
+// reduced echelon form, ie. calculates equivalent equations but with pre=0 and
+// piv=1 for each eqn.
+struct ref : public knotprop<eqn> {
+ cvector<eqn>& e;
+ eqn lasteqn;
+
+ ref(knotlist& l, cvector<eqn>& e)
+ : knotprop<eqn>(l), e(e), lasteqn(0,1,0,0) {}
+
+ // Scale the equation so that the pivot (diagonal) entry is one, and save
+ // the new equation as lasteqn.
+ eqn scale(eqn q) {
+ assert(q.pre == 0 && q.piv != 0);
+ return lasteqn = eqn(0,1,q.post/q.piv,q.aug/q.piv);
+ }
+
+ eqn start(Int j) {
+ return scale(e[j]);
+ }
+ eqn mid(Int j) {
+ // Subtract a factor of the last equation so that the first entry is
+ // zero, then procede to scale it.
+ eqn& q=e[j];
+ return scale(eqn(0,q.piv-q.pre*lasteqn.post,q.post,
+ q.aug-q.pre*lasteqn.aug));
+ }
+ // The end case is the same as the middle case.
+};
+
+// Once the matrix is in reduced echelon form, we can solve for the values by
+// back-substitution. This algorithm works from the bottom-up, so backCompute
+// must be used to get the answer.
+struct backsub : public knotprop<double> {
+ cvector<eqn>& e;
+ double lastTheta;
+
+ backsub(knotlist& l, cvector<eqn>& e)
+ : knotprop<double>(l), e(e) {}
+
+ double end(Int j) {
+ eqn& q=e[j];
+ assert(q.pre == 0 && q.piv == 1 && q.post == 0);
+ double theta=q.aug;
+ lastTheta=theta;
+ return theta;
+ }
+
+ double mid(Int j) {
+ eqn& q=e[j];
+ assert(q.pre == 0 && q.piv == 1);
+ double theta=-q.post*lastTheta+q.aug;
+ lastTheta=theta;
+ return theta;
+ }
+
+ // start is the same as mid.
+};
+
+// Once the equations have been determined, solve for the thetas.
+cvector<double> solveThetas(knotlist& l, cvector<eqn>& e)
+{
+ if (homogeneous(e))
+ // We are solving Ax=0, so a solution is zero for every theta.
+ return cvector<double>(e.size(),0);
+ else if (l.cyclic()) {
+ // The knotprop template is unusually unhelpful in this case, so I
+ // won't use it here. The algorithm breaks into three passes on the
+ // object. The old Asymptote code used a two-pass method, but I
+ // implemented this to stay closer to the MetaPost source code.
+ // This might be something to look at for optimization.
+ cvector<weqn> we=recalc(e);
+ INFO(we);
+ double theta0=solveForTheta0(we);
+ return backsubCyclic(we, theta0);
+ }
+ else { /* Non-cyclic case. */
+ /* First do row operations to get it into reduced echelon form. */
+ cvector<eqn> el=ref(l,e).compute();
+
+ /* Then, do back substitution. */
+ return backsub(l,el).backCompute();
+ }
+}
+
+// Once thetas have been solved, determine the first control point of every
+// join.
+struct postcontrolprop : public knotprop<pair> {
+ cvector<pair>& dz;
+ cvector<double>& psi;
+ cvector<double>& theta;
+
+ postcontrolprop(knotlist& l, cvector<pair>& dz,
+ cvector<double>& psi, cvector<double>& theta)
+ : knotprop<pair>(l), dz(dz), psi(psi), theta(theta) {}
+
+ double phi(Int j) {
+ /* The third angle: psi + theta + phi = 0 */
+ return -psi[j] - theta[j];
+ }
+
+ double vel(Int j) {
+ /* Use the standard velocity function. */
+ return velocity(theta[j],phi(j+1),l[j].tout);
+ }
+
+ // start is the same as mid.
+
+ pair mid(Int j) {
+ // Put a control point at the relative distance determined by the velocity,
+ // and at an angle determined by theta.
+ return l[j].z + vel(j)*expi(theta[j])*dz[j];
+ }
+
+ // The end postcontrol is the same as the last knot.
+ pair end(Int j) {
+ return l[j].z;
+ }
+};
+
+// Determine the first control point of every join.
+struct precontrolprop : public knotprop<pair> {
+ cvector<pair>& dz;
+ cvector<double>& psi;
+ cvector<double>& theta;
+
+ precontrolprop(knotlist& l, cvector<pair>& dz,
+ cvector<double>& psi, cvector<double>& theta)
+ : knotprop<pair>(l), dz(dz), psi(psi), theta(theta) {}
+
+ double phi(Int j) {
+ return -psi[j] - theta[j];
+ }
+
+ double vel(Int j) {
+ return velocity(phi(j),theta[j-1],l[j].tin);
+ }
+
+ // The start precontrol is the same as the first knot.
+ pair start(Int j) {
+ return l[j].z;
+ }
+ pair mid(Int j) {
+ return l[j].z - vel(j)*expi(-phi(j))*dz[j-1];
+ }
+
+ // end is the same as mid.
+};
+
+// Puts solved controls into a protopath starting at the given index.
+// By convention, the first knot is not coded, as it is assumed to be coded by
+// the previous section (or it is the first breakpoint and encoded as a special
+// case).
+struct encodeControls : public knoteffect {
+ protopath& p;
+ Int k;
+ cvector<pair>& pre;
+ cvector<pair>& post;
+
+ encodeControls(protopath& p, Int k,
+ cvector<pair>& pre, knotlist& l, cvector<pair>& post)
+ : knoteffect(l), p(p), k(k), pre(pre), post(post) {}
+
+ void encodePre(Int j) {
+ p.pre(k+j)=pre[j];
+ }
+ void encodePoint(Int j) {
+ p.point(k+j)=l[j].z;
+ }
+ void encodePost(Int j) {
+ p.post(k+j)=post[j];
+ }
+
+ void solo(Int) {
+#if 0
+ encodePoint(j);
+#endif
+ }
+ void start(Int j) {
+#if 0
+ encodePoint(j);
+#endif
+ encodePost(j);
+ }
+ void mid(Int j) {
+ encodePre(j);
+ encodePoint(j);
+ encodePost(j);
+ }
+ void end(Int j) {
+ encodePre(j);
+ encodePoint(j);
+ }
+};
+
+void encodeStraight(protopath& p, Int k, knotlist& l)
+{
+ pair a=l.front().z;
+ double at=l.front().tout.val;
+ pair b=l.back().z;
+ double bt=l.back().tin.val;
+ pair step=(b-a)/3.0;
+
+ if (at==1.0 && bt==1.0) {
+ p.straight(k)=true;
+ p.post(k)=a+step;
+ p.pre(k+1)=b-step;
+ p.point(k+1)=b;
+ }
+ else {
+ p.post(k)=a+step/at;
+ p.pre(k+1)=b-step/bt;
+ p.point(k+1)=b;
+ }
+}
+
+void solveSection(protopath& p, Int k, knotlist& l)
+{
+ if (l.length()>0) {
+ info(cerr, "solving section", l);
+
+ // Calculate useful properties.
+ cvector<pair> dz = dzprop(l) .compute();
+ cvector<double> d = dprop(l,dz).compute();
+ cvector<double> psi = psiprop(l,dz).compute();
+
+ INFO(dz); INFO(d); INFO(psi);
+
+ // Build and solve the linear equations for theta.
+ cvector<eqn> e = eqnprop(l,d,psi).compute();
+ INFO(e);
+
+ if (straightSection(e))
+ // Handle straight section as special case.
+ encodeStraight(p,k,l);
+ else {
+ cvector<double> theta = solveThetas(l,e);
+ INFO(theta);
+
+ // Calculate the control points.
+ cvector<pair> post = postcontrolprop(l,dz,psi,theta).compute();
+ cvector<pair> pre = precontrolprop(l,dz,psi,theta).compute();
+
+ // Encode the results into the protopath.
+ encodeControls(p,k,pre,l,post).exec();
+ }
+ }
+}
+
+// Find the first breakpoint in the knotlist, ie. where we can start solving a
+// non-cyclic section. If the knotlist is fully cyclic, then this returns
+// NOBREAK.
+// This must be called with a knot that has all of its implicit specifiers in
+// place.
+const Int NOBREAK=-1;
+Int firstBreakpoint(knotlist& l)
+{
+ for (Int j=0;j<l.size();++j)
+ if (!l[j].out->open())
+ return j;
+ return NOBREAK;
+}
+
+// Once a breakpoint, a, is found, find where the next breakpoint after it is.
+// This must be called with a knot that has all of its implicit specifiers in
+// place, so that breakpoint can be identified by either an in or out specifier
+// that is not open.
+Int nextBreakpoint(knotlist& l, Int a)
+{
+ // This is guaranteed to terminate if a is the index of a breakpoint. If the
+ // path is non-cyclic it will stop at or before the last knot which must be a
+ // breakpoint. If the path is cyclic, it will stop at or before looping back
+ // around to a which is a breakpoint.
+ Int j=a+1;
+ while (l[j].in->open())
+ ++j;
+ return j;
+}
+
+// Write out the controls for section of the form
+// a.. control b and c ..d
+void writeControls(protopath& p, Int a, knotlist& l)
+{
+ // By convention, the first point will already be encoded.
+ p.straight(a)=dynamic_cast<controlSpec *>(l[a].out)->straight;
+ p.post(a)=dynamic_cast<controlSpec *>(l[a].out)->cz;
+ p.pre(a+1)=dynamic_cast<controlSpec *>(l[a+1].in)->cz;
+ p.point(a+1)=l[a+1].z;
+}
+
+// Solves a path that has all of its specifiers laid out explicitly.
+path solveSpecified(knotlist& l)
+{
+ protopath p(l.size(),l.cyclic());
+
+ Int first=firstBreakpoint(l);
+ if (first==NOBREAK)
+ /* We are solving a fully cyclic path, so do it in one swoop. */
+ solveSection(p,0,l);
+ else {
+ // Encode the first point.
+ p.point(first)=l[first].z;
+
+ // If the path is cyclic, we should stop where we started (modulo the
+ // length of the path); otherwise, just stop at the end.
+ Int last=l.cyclic() ? first+l.length()
+ : l.length();
+ Int a=first;
+ while (a!=last) {
+ if (l[a].out->controlled()) {
+ assert(l[a+1].in->controlled());
+
+ // Controls are already picked, just write them out.
+ writeControls(p,a,l);
+ ++a;
+ }
+ else {
+ // Find the section a to b and solve it, putting the result (starting
+ // from index a into our protopath.
+ Int b=nextBreakpoint(l,a);
+ subknotlist section(l,a,b);
+ solveSection(p,a,section);
+ a=b;
+ }
+ }
+
+ // For a non-cyclic path, the end control points need to be set.
+ p.controlEnds();
+ }
+
+ return p.fix();
+}
+
+/* If a knot is open on one side and restricted on the other, this replaces the
+ * open side with a restriction determined by the restriction on the other
+ * side. After this, any knot will either have two open specs or two
+ * restrictions.
+ */
+struct partnerUp : public knoteffect {
+ partnerUp(knotlist& l)
+ : knoteffect(l) {}
+
+ void mid(Int j) {
+ knot& k=l[j];
+ if (k.in->open() && !k.out->open())
+ k.in=k.out->inPartner(k.z);
+ else if (!k.in->open() && k.out->open())
+ k.out=k.in->outPartner(k.z);
+ }
+};
+
+/* Ensures a non-cyclic path has direction specifiers at the ends, adding curls
+ * if there are none.
+ */
+void curlEnds(knotlist& l)
+{
+ static curlSpec endSpec;
+
+ if (!l.cyclic()) {
+ if (l.front().in->open())
+ l.front().in=&endSpec;
+ if (l.back().out->open())
+ l.back().out=&endSpec;
+ }
+}
+
+/* If a point occurs twice in a row in a knotlist, write in controls
+ * between the two knots at that point (unless it already has controls).
+ */
+struct controlDuplicates : public knoteffect {
+ controlDuplicates(knotlist& l)
+ : knoteffect(l) {}
+
+ void solo(Int) { /* One point ==> no duplicates */ }
+ // start is the same as mid.
+ void mid(Int j) {
+ knot &k1=l[j];
+ knot &k2=l[j+1];
+ if (!k1.out->controlled() && k1.z==k2.z) {
+ k1.out=k2.in=new controlSpec(k1.z,true);
+ }
+ }
+ void end(Int) { /* No next point to compare with. */ }
+};
+
+path solve(knotlist& l)
+{
+ if (l.empty())
+ return path();
+ else {
+ info(cerr, "input knotlist", l);
+ curlEnds(l);
+ controlDuplicates(l).exec();
+ partnerUp(l).exec();
+ info(cerr, "specified knotlist", l);
+ return solveSpecified(l);
+ }
+}
+
+// Code for Testing
+#if 0
+path solveSimple(cvector<pair>& z)
+{
+ // The two specifiers used: an open spec and a curl spec for the ends.
+ spec open;
+
+// curlSpec curl;
+// curlSpec curly(2.0);
+// dirSpec E(0);
+// dirSpec N(PI/2.0);
+
+ controlSpec here(pair(150,150));
+
+ // Encode the knots as open in the knotlist.
+ cvector<knot> nodes;
+ for (cvector<pair>::iterator p=z.begin(); p!=z.end(); ++p) {
+ knot k;
+ k.z=*p;
+ k.in=k.out=&open;
+
+ nodes.push_back(k);
+ }
+
+ // Substitute in a curl spec for the ends.
+ //nodes.front().out=nodes.back().in=&curl;
+
+ // Test direction specifiers.
+ //nodes.front().tout=2;
+ //nodes.front().out=nodes.back().in=&curly;
+
+ //nodes[0].out=nodes[0].in=&E;
+ nodes[1].out=nodes[2].in=&here;
+
+ simpleknotlist l(nodes,false);
+ return solve(l);
+}
+#endif
+
+} // namespace camp
diff --git a/Build/source/utils/asymptote/knot.h b/Build/source/utils/asymptote/knot.h
new file mode 100644
index 00000000000..aaf49a4c036
--- /dev/null
+++ b/Build/source/utils/asymptote/knot.h
@@ -0,0 +1,533 @@
+/*****
+ * knot.h
+ * Andy Hammerlindl 200/02/10
+ *
+ * Describes a knot, a point and its neighbouring specifiers, used as an
+ * intermediate structure in solving paths.
+ *****/
+
+#ifndef KNOT_H
+#define KNOT_H
+
+#include <iostream>
+#include <vector>
+#include <algorithm>
+
+#include "mod.h"
+#include "pair.h"
+#include "path.h"
+
+namespace camp {
+
+using mem::vector;
+
+// The choice of branch cuts of atan2 disguishes between y=+0.0 and y=-0.0 in
+// the case where x<0. This can lead to strange looking paths being
+// calculated from guides of the form a..b..cycle. To avoid these degenerate
+// cases, the niceAngle routine moves the branch cut so that the sign of a
+// zero won't matter.
+double niceAngle(pair z);
+
+// A cyclic vector: ie. a vector where the index is taken mod the size of the
+// vector.
+template <typename T>
+class cvector : public vector<T> {
+public:
+ cvector() {}
+ cvector(size_t n) : vector<T>(n) {}
+ cvector(size_t n, const T& t) : vector<T>(n,t) {}
+ cvector(const vector<T>& v) : vector<T>(v) {}
+
+ T& operator[](Int j) {
+ return vector<T>::operator[](imod(j,(Int) this->size()));
+ }
+ const T& operator[](Int j) const {
+ return vector<T>::operator[](imod(j,(Int) this->size()));
+ }
+};
+
+// Forward declaration.
+class knotlist;
+
+/* A linear equation (one of a set of equations to solve for direction through
+ knots in a path). The i-th equation is:
+
+ pre*theta[i-1] + piv*theta[i] + post*theta[i+1] = aug
+
+ where indices are taken mod n.
+*/
+struct eqn {
+ double pre,piv,post,aug;
+ eqn(double pre, double piv, double post, double aug)
+ : pre(pre), piv(piv), post(post), aug(aug) {}
+
+ friend ostream& operator<< (ostream& out, const eqn& e)
+ {
+ return out << e.pre << " * pre + "
+ << e.piv << " * piv + "
+ << e.post << " * post = "
+ << e.aug;
+ }
+};
+
+
+// A direction specifier, telling how the path behaves coming in or out of a
+// point. The base class represents the "open" specifier.
+class spec : public gc {
+public:
+ virtual ~spec() {}
+
+ // If the knot is open, it gives no restriction on the behavior of the
+ // path.
+ virtual bool open() { return true; }
+ virtual bool controlled() { return false; }
+ virtual pair control() {return pair(0.0,0.0);}
+ virtual double curl() { return -1.0; }
+ virtual pair dir() { return pair(0.0,0.0); }
+
+ // When a knot has a restriction on one side but is open on the other, the
+ // restriction implies a restriction on the other side. This is the partner
+ // restriction defined here, where the pair argument is for the location of
+ // the knot.
+ virtual spec *outPartner(pair) { return this; }
+ virtual spec *inPartner(pair) { return this; }
+
+ virtual void print(ostream&) const {}
+};
+
+inline ostream& operator<< (ostream& out, spec& s)
+{
+ s.print(out);
+ return out;
+}
+
+
+// Specifier used at an endpoint.
+class endSpec : public spec {
+public:
+ bool open() { return false; }
+
+ // Returns an equation used to solve for the thetas along the knot. These are
+ // called by eqnprop in the non-cyclic case for the first and last equations.
+ virtual eqn eqnOut(Int j, knotlist& l,
+ cvector<double>& d, cvector<double>& psi) = 0;
+ virtual eqn eqnIn (Int j, knotlist& l,
+ cvector<double>& d, cvector<double>& psi) = 0;
+};
+
+// A specifier with a given direction (in radians).
+class dirSpec : public endSpec {
+ double given;
+public:
+ // Direction should be given in the range [-PI,PI]
+ dirSpec(double given)
+ : given(given) {}
+ dirSpec(pair z)
+ : given(niceAngle(z)) {}
+
+ pair dir() { return expi(given); }
+
+ eqn eqnOut(Int j, knotlist& l, cvector<double>& d, cvector<double>& psi);
+ eqn eqnIn (Int j, knotlist& l, cvector<double>& d, cvector<double>& psi);
+
+ void print(ostream& out) const {
+ out << "{dir(" << degrees(given) << ")}";
+ }
+};
+
+// A curl specifier. The curvature at the end knot should be gamma times the
+// curvature at the neighbouring knot.
+class curlSpec : public endSpec {
+ double gamma;
+public:
+ // Gamma should be non-negative.
+ curlSpec(double gamma=1.0)
+ : gamma(gamma) {
+ if(gamma < 0)
+ reportError("curl cannot be less than 0");
+ }
+
+ double curl() { return gamma; }
+
+ eqn eqnOut(Int j, knotlist& l, cvector<double>& d, cvector<double>& psi);
+ eqn eqnIn (Int j, knotlist& l, cvector<double>& d, cvector<double>& psi);
+
+ void print(ostream& out) const {
+ out << "{curl " << gamma << "}";
+ }
+};
+
+
+// A specifier with a control point. All information for this portion of the
+// curve has been determined.
+class controlSpec : public spec {
+public:
+ pair cz;
+ bool straight;
+
+ controlSpec(pair cz, bool straight=false)
+ : cz(cz), straight(straight) {}
+
+ bool open() { return false; }
+ bool controlled() { return true; }
+ pair control() { return cz; }
+
+ // The partner spec will be a dirSpec in the same direction the specifier
+ // takes the path, unless the velocity is zero, then it uses a curl
+ // specifier.
+ spec *outPartner(pair);
+ spec *inPartner(pair);
+
+ void print(ostream& out) const {
+ // NOTE: This format cannot be read back in.
+ out << "{control " << cz << "}";
+ }
+};
+
+
+// The tension information for one side of a knot.
+struct tension {
+ double val;
+ bool atleast;
+
+ tension(double val=1.0, bool atleast=false)
+ : val(val), atleast(atleast) {
+ if(val < 0.75)
+ reportError("tension cannot be less than 3/4");
+ }
+};
+
+inline
+ostream& operator<<(ostream& out, tension t)
+{
+ return out << "tension" << (t.atleast ? " atleast " : " ") << t.val;
+}
+
+// A knot, a point with specifiers to double the path coming in and going out
+// of the knot.
+struct knot {
+ pair z;
+ spec *in;
+ spec *out;
+ tension tin, tout;
+
+ knot() {}
+ knot(pair z, spec *in, spec *out,
+ tension tin=tension(), tension tout=tension())
+ : z(z), in(in), out(out), tin(tin), tout(tout) {}
+
+ double alpha() { return 1.0/tout.val; }
+ double beta() { return 1.0/tin.val; }
+};
+
+ostream& operator<<(ostream& out, const knot& k);
+
+// Abstract base class for a section of a guide.
+class knotlist {
+public:
+ virtual ~knotlist() {}
+
+ virtual Int length() = 0;
+ virtual bool cyclic() = 0;
+
+ // Returns the number of knots.
+ Int size() {
+ return cyclic() ? length() : length() + 1;
+ }
+ bool empty() {
+ return size()==0;
+ }
+
+ virtual knot& cell(Int) = 0;
+ virtual knot& operator[] (Int i) {
+#if 0
+ assert(cyclic() || (0 <= i && i <= length())); // Bounds check.
+#endif
+ return cell(i);
+ }
+ knot& front() {
+ return (*this)[0];
+ }
+ knot& back() {
+ return (*this)[length()];
+ }
+};
+
+
+// Defines a knotlist as a piece of another knotlist.
+class subknotlist : public knotlist {
+ knotlist& l;
+ Int a,b;
+public:
+ subknotlist(knotlist& l, Int a, Int b)
+ : l(l), a(a), b(b) {}
+
+ Int length() { return b-a; }
+ bool cyclic() { return false; }
+ knot& cell(Int i) { return l[a+i]; }
+};
+
+struct simpleknotlist : public knotlist {
+ cvector<knot> nodes;
+ bool cycles;
+
+ simpleknotlist(cvector<knot> nodes, bool cycles=false)
+ : nodes(nodes), cycles(cycles) {}
+
+ Int length() { return cycles ? (Int) nodes.size() : (Int) nodes.size() - 1; }
+ bool cyclic() { return cycles; }
+ knot& cell(Int j) { return nodes[j]; }
+};
+
+// A protopath is a path being made.
+struct protopath {
+ bool cycles;
+ Int n;
+ mem::vector<solvedKnot> nodes;
+
+ protopath(Int n, bool cycles)
+ : cycles(cycles), n(n), nodes(n) {}
+
+ solvedKnot& operator[](Int j) {
+ return nodes[imod(j,n)];
+ }
+
+ bool& straight(Int j) {
+ return (*this)[j].straight;
+ }
+ pair& pre(Int j) {
+ return (*this)[j].pre;
+ }
+ pair& point(Int j) {
+ return (*this)[j].point;
+ }
+ pair& post(Int j) {
+ return (*this)[j].post;
+ }
+
+ void controlEnds() {
+ if (!cycles) {
+ solvedKnot& start=(*this)[0];
+ solvedKnot& end=(*this)[n-1];
+
+ start.pre=start.point;
+ end.post=end.point;
+ }
+ }
+ // Once all the controls are set, return the final (constant) path.
+ path fix() {
+ return path(nodes,n,cycles);
+ }
+};
+
+
+// Represents properties that can be computed along a knotlist.
+// Examples include distances (d), turning angles (psi), and the linear
+// equations used to solve for the thetas.
+template <typename T>
+class knotprop {
+protected:
+ knotlist& l;
+
+ // Calculate the property for the usual case in the iteration (and for a
+ // cyclic knot, the only case), at the index given.
+ virtual T mid(Int) = 0;
+
+ // The special cases, these default to the usual case: mid.
+ virtual T solo(Int j) // Calculates the property for a list of length 0.
+ {
+ return mid(j);
+ }
+ virtual T start(Int j) // Calculates it at the start of the list.
+ {
+ return mid(j);
+ }
+ virtual T end(Int j) // Calculate it at the end.
+ {
+ return mid(j);
+ }
+
+ virtual cvector<T> linearCompute()
+ {
+ Int n=l.length();
+ cvector<T> v;
+ if (n==0)
+ v.push_back(solo(0));
+ else {
+ v.push_back(start(0));
+ for (Int j=1; j<n; ++j)
+ v.push_back(mid(j));
+ v.push_back(end(n));
+ }
+ return v;
+ }
+
+ virtual cvector<T> cyclicCompute()
+ {
+ Int n=l.length();
+ cvector<T> v;
+ for (Int j=0; j<n; ++j)
+ v.push_back(mid(j));
+ return v;
+ }
+
+ virtual cvector<T> linearBackCompute()
+ {
+ Int n=l.length();
+ cvector<T> v;
+ if (n==0)
+ v.push_back(solo(0));
+ else {
+ v.push_back(end(n));
+ for (Int j=1; j<n; ++j)
+ v.push_back(mid(n-j));
+ v.push_back(start(0));
+ }
+ return v;
+ }
+
+ virtual cvector<T> cyclicBackCompute()
+ {
+ Int n=l.length();
+ cvector<T> v;
+ for (Int j=1; j<=n; ++j)
+ v.push_back(mid(n-j));
+ return v;
+ }
+
+public:
+ virtual ~knotprop() {}
+
+ virtual cvector<T> compute() {
+ return l.cyclic() ? cyclicCompute() : linearCompute();
+ }
+
+ // Compute the values in the opposite order. This is needed for instance if
+ // the i-th calculation needed a result computed in the i+1-th, such as in the
+ // back substitution for solving thetas.
+ virtual cvector<T> backCompute() {
+ cvector<T> v=l.cyclic() ? cyclicBackCompute() : linearBackCompute();
+
+ // Even though they are computed in the backwards order, return them in the
+ // standard order.
+ reverse(v.begin(),v.end());
+ return v;
+ }
+
+ knotprop(knotlist& l)
+ : l(l) {}
+};
+
+// A knot transforms, it takes in one knotlist and transforms it knot for knot
+// into a new one.
+class knottrans : public knotprop<knot> {
+protected:
+ virtual knot mid(Int j) {
+ /* By default, just copy the knot. */
+ return l[j];
+ }
+
+public:
+ virtual ~knottrans() {}
+
+ knottrans(knotlist& l)
+ : knotprop<knot>(l) {}
+
+ virtual simpleknotlist trans() {
+ return simpleknotlist(compute(),l.cyclic());
+ }
+};
+
+// Like a knotprop, but it doesn't compute a vector of values for the knot. It
+// iterates over the knotlist calling method for side-effect. For instance,
+// this is used to plug control points into protopaths.
+class knoteffect {
+protected:
+ knotlist& l;
+
+ virtual void mid(Int) = 0;
+
+ // The special cases, these default to the usual case: mid.
+ virtual void solo(Int j) {
+ mid(j);
+ }
+ virtual void start(Int j) {
+ mid(j);
+ }
+ virtual void end(Int j) {
+ mid(j);
+ }
+
+ virtual void linearExec()
+ {
+ Int n=l.length();
+ if (n==0)
+ solo(0);
+ else {
+ start(0);
+ for (Int j=1; j<n; ++j)
+ mid(j);
+ end(n);
+ }
+ }
+
+ virtual void cyclicExec()
+ {
+ Int n=l.length();
+ for (Int j=0; j<n; ++j)
+ mid(j);
+ }
+
+ virtual void linearBackExec()
+ {
+ Int n=l.length();
+ if (n==0)
+ solo(0);
+ else {
+ end(n);
+ for (Int j=1; j<n; ++j)
+ mid(n-j);
+ start(0);
+ }
+ }
+
+ virtual void cyclicBackExec()
+ {
+ Int n=l.length();
+ for (Int j=1; j<=n; ++j)
+ mid(n-j);
+ }
+
+public:
+ virtual ~knoteffect() {}
+
+ virtual void exec() {
+ if (l.cyclic())
+ cyclicExec();
+ else
+ linearExec();
+ }
+
+ virtual void backCompute() {
+ if (l.cyclic())
+ cyclicBackExec();
+ else
+ linearBackExec();
+ }
+
+ knoteffect(knotlist& l)
+ : l(l) {}
+};
+
+path solve(knotlist& l);
+
+path solveSimple(cvector<pair>& z);
+
+double velocity(double theta, double phi, tension t);
+
+} // namespace camp
+
+GC_DECLARE_PTRFREE(camp::eqn);
+GC_DECLARE_PTRFREE(camp::tension);
+
+#endif // KNOT_H
diff --git a/Build/source/utils/asymptote/lex.yy.cc b/Build/source/utils/asymptote/lex.yy.cc
new file mode 100644
index 00000000000..3b82bfa9671
--- /dev/null
+++ b/Build/source/utils/asymptote/lex.yy.cc
@@ -0,0 +1,3191 @@
+#line 2 "lex.yy.cc"
+
+#line 4 "lex.yy.cc"
+
+#define YY_INT_ALIGNED short int
+
+/* A lexical scanner generated by flex */
+
+/* %not-for-header */
+
+/* %if-c-only */
+/* %if-not-reentrant */
+
+/* %endif */
+/* %endif */
+/* %ok-for-header */
+
+#define FLEX_SCANNER
+#define YY_FLEX_MAJOR_VERSION 2
+#define YY_FLEX_MINOR_VERSION 5
+#define YY_FLEX_SUBMINOR_VERSION 35
+#if YY_FLEX_SUBMINOR_VERSION > 0
+#define FLEX_BETA
+#endif
+
+/* %if-c++-only */
+/* %endif */
+
+/* %if-c-only */
+
+/* %endif */
+
+/* %if-c-only */
+
+/* %endif */
+
+/* First, we deal with platform-specific or compiler-specific issues. */
+
+/* begin standard C headers. */
+/* %if-c-only */
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+#include <stdlib.h>
+/* %endif */
+
+/* %if-tables-serialization */
+/* %endif */
+/* end standard C headers. */
+
+/* %if-c-or-c++ */
+/* flex integer type definitions */
+
+#ifndef FLEXINT_H
+#define FLEXINT_H
+
+/* C99 systems have <inttypes.h>. Non-C99 systems may or may not. */
+
+#if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
+
+/* C99 says to define __STDC_LIMIT_MACROS before including stdint.h,
+ * if you want the limit (max/min) macros for int types.
+ */
+#ifndef __STDC_LIMIT_MACROS
+#define __STDC_LIMIT_MACROS 1
+#endif
+
+#include <inttypes.h>
+typedef int8_t flex_int8_t;
+typedef uint8_t flex_uint8_t;
+typedef int16_t flex_int16_t;
+typedef uint16_t flex_uint16_t;
+typedef int32_t flex_int32_t;
+typedef uint32_t flex_uint32_t;
+#else
+typedef signed char flex_int8_t;
+typedef short int flex_int16_t;
+typedef int flex_int32_t;
+typedef unsigned char flex_uint8_t;
+typedef unsigned short int flex_uint16_t;
+typedef unsigned int flex_uint32_t;
+#endif /* ! C99 */
+
+/* Limits of integral types. */
+#ifndef INT8_MIN
+#define INT8_MIN (-128)
+#endif
+#ifndef INT16_MIN
+#define INT16_MIN (-32767-1)
+#endif
+#ifndef INT32_MIN
+#define INT32_MIN (-2147483647-1)
+#endif
+#ifndef INT8_MAX
+#define INT8_MAX (127)
+#endif
+#ifndef INT16_MAX
+#define INT16_MAX (32767)
+#endif
+#ifndef INT32_MAX
+#define INT32_MAX (2147483647)
+#endif
+#ifndef UINT8_MAX
+#define UINT8_MAX (255U)
+#endif
+#ifndef UINT16_MAX
+#define UINT16_MAX (65535U)
+#endif
+#ifndef UINT32_MAX
+#define UINT32_MAX (4294967295U)
+#endif
+
+#endif /* ! FLEXINT_H */
+
+/* %endif */
+
+/* %if-c++-only */
+/* %endif */
+
+#ifdef __cplusplus
+
+/* The "const" storage-class-modifier is valid. */
+#define YY_USE_CONST
+
+#else /* ! __cplusplus */
+
+/* C99 requires __STDC__ to be defined as 1. */
+#if defined (__STDC__)
+
+#define YY_USE_CONST
+
+#endif /* defined (__STDC__) */
+#endif /* ! __cplusplus */
+
+#ifdef YY_USE_CONST
+#define yyconst const
+#else
+#define yyconst
+#endif
+
+/* %not-for-header */
+
+/* Returned upon end-of-file. */
+#define YY_NULL 0
+/* %ok-for-header */
+
+/* %not-for-header */
+
+/* Promotes a possibly negative, possibly signed char to an unsigned
+ * integer for use as an array index. If the signed char is negative,
+ * we want to instead treat it as an 8-bit unsigned char, hence the
+ * double cast.
+ */
+#define YY_SC_TO_UI(c) ((unsigned int) (unsigned char) c)
+/* %ok-for-header */
+
+/* %if-reentrant */
+/* %endif */
+
+/* %if-not-reentrant */
+
+/* %endif */
+
+/* Enter a start condition. This macro really ought to take a parameter,
+ * but we do it the disgusting crufty way forced on us by the ()-less
+ * definition of BEGIN.
+ */
+#define BEGIN (yy_start) = 1 + 2 *
+
+/* Translate the current start state into a value that can be later handed
+ * to BEGIN to return to the state. The YYSTATE alias is for lex
+ * compatibility.
+ */
+#define YY_START (((yy_start) - 1) / 2)
+#define YYSTATE YY_START
+
+/* Action number for EOF rule of a given start state. */
+#define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1)
+
+/* Special action meaning "start processing a new file". */
+#define YY_NEW_FILE yyrestart(yyin )
+
+#define YY_END_OF_BUFFER_CHAR 0
+
+/* Size of default input buffer. */
+#ifndef YY_BUF_SIZE
+#define YY_BUF_SIZE 16384
+#endif
+
+/* The state buf must be large enough to hold one state per character in the main buffer.
+ */
+#define YY_STATE_BUF_SIZE ((YY_BUF_SIZE + 2) * sizeof(yy_state_type))
+
+#ifndef YY_TYPEDEF_YY_BUFFER_STATE
+#define YY_TYPEDEF_YY_BUFFER_STATE
+typedef struct yy_buffer_state *YY_BUFFER_STATE;
+#endif
+
+/* %if-not-reentrant */
+extern int yyleng;
+/* %endif */
+
+/* %if-c-only */
+/* %if-not-reentrant */
+extern FILE *yyin, *yyout;
+/* %endif */
+/* %endif */
+
+#define EOB_ACT_CONTINUE_SCAN 0
+#define EOB_ACT_END_OF_FILE 1
+#define EOB_ACT_LAST_MATCH 2
+
+ #define YY_LESS_LINENO(n)
+
+/* Return all but the first "n" matched characters back to the input stream. */
+#define yyless(n) \
+ do \
+ { \
+ /* Undo effects of setting up yytext. */ \
+ int yyless_macro_arg = (n); \
+ YY_LESS_LINENO(yyless_macro_arg);\
+ *yy_cp = (yy_hold_char); \
+ YY_RESTORE_YY_MORE_OFFSET \
+ (yy_c_buf_p) = yy_cp = yy_bp + yyless_macro_arg - YY_MORE_ADJ; \
+ YY_DO_BEFORE_ACTION; /* set up yytext again */ \
+ } \
+ while ( 0 )
+
+#define unput(c) yyunput( c, (yytext_ptr) )
+
+#ifndef YY_TYPEDEF_YY_SIZE_T
+#define YY_TYPEDEF_YY_SIZE_T
+typedef size_t yy_size_t;
+#endif
+
+#ifndef YY_STRUCT_YY_BUFFER_STATE
+#define YY_STRUCT_YY_BUFFER_STATE
+struct yy_buffer_state
+ {
+/* %if-c-only */
+ FILE *yy_input_file;
+/* %endif */
+
+/* %if-c++-only */
+/* %endif */
+
+ char *yy_ch_buf; /* input buffer */
+ char *yy_buf_pos; /* current position in input buffer */
+
+ /* Size of input buffer in bytes, not including room for EOB
+ * characters.
+ */
+ yy_size_t yy_buf_size;
+
+ /* Number of characters read into yy_ch_buf, not including EOB
+ * characters.
+ */
+ int yy_n_chars;
+
+ /* Whether we "own" the buffer - i.e., we know we created it,
+ * and can realloc() it to grow it, and should free() it to
+ * delete it.
+ */
+ int yy_is_our_buffer;
+
+ /* Whether this is an "interactive" input source; if so, and
+ * if we're using stdio for input, then we want to use getc()
+ * instead of fread(), to make sure we stop fetching input after
+ * each newline.
+ */
+ int yy_is_interactive;
+
+ /* Whether we're considered to be at the beginning of a line.
+ * If so, '^' rules will be active on the next match, otherwise
+ * not.
+ */
+ int yy_at_bol;
+
+ int yy_bs_lineno; /**< The line count. */
+ int yy_bs_column; /**< The column count. */
+
+ /* Whether to try to fill the input buffer when we reach the
+ * end of it.
+ */
+ int yy_fill_buffer;
+
+ int yy_buffer_status;
+
+#define YY_BUFFER_NEW 0
+#define YY_BUFFER_NORMAL 1
+ /* When an EOF's been seen but there's still some text to process
+ * then we mark the buffer as YY_EOF_PENDING, to indicate that we
+ * shouldn't try reading from the input source any more. We might
+ * still have a bunch of tokens to match, though, because of
+ * possible backing-up.
+ *
+ * When we actually see the EOF, we change the status to "new"
+ * (via yyrestart()), so that the user can continue scanning by
+ * just pointing yyin at a new input file.
+ */
+#define YY_BUFFER_EOF_PENDING 2
+
+ };
+#endif /* !YY_STRUCT_YY_BUFFER_STATE */
+
+/* %if-c-only Standard (non-C++) definition */
+/* %not-for-header */
+
+/* %if-not-reentrant */
+
+/* Stack of input buffers. */
+static size_t yy_buffer_stack_top = 0; /**< index of top of stack. */
+static size_t yy_buffer_stack_max = 0; /**< capacity of stack. */
+static YY_BUFFER_STATE * yy_buffer_stack = 0; /**< Stack as an array. */
+/* %endif */
+/* %ok-for-header */
+
+/* %endif */
+
+/* We provide macros for accessing buffer states in case in the
+ * future we want to put the buffer states in a more general
+ * "scanner state".
+ *
+ * Returns the top of the stack, or NULL.
+ */
+#define YY_CURRENT_BUFFER ( (yy_buffer_stack) \
+ ? (yy_buffer_stack)[(yy_buffer_stack_top)] \
+ : NULL)
+
+/* Same as previous macro, but useful when we know that the buffer stack is not
+ * NULL or when we need an lvalue. For internal use only.
+ */
+#define YY_CURRENT_BUFFER_LVALUE (yy_buffer_stack)[(yy_buffer_stack_top)]
+
+/* %if-c-only Standard (non-C++) definition */
+
+/* %if-not-reentrant */
+/* %not-for-header */
+
+/* yy_hold_char holds the character lost when yytext is formed. */
+static char yy_hold_char;
+static int yy_n_chars; /* number of characters read into yy_ch_buf */
+int yyleng;
+
+/* Points to current character in buffer. */
+static char *yy_c_buf_p = (char *) 0;
+static int yy_init = 0; /* whether we need to initialize */
+static int yy_start = 0; /* start state number */
+
+/* Flag which is used to allow yywrap()'s to do buffer switches
+ * instead of setting up a fresh yyin. A bit of a hack ...
+ */
+static int yy_did_buffer_switch_on_eof;
+/* %ok-for-header */
+
+/* %endif */
+
+void yyrestart (FILE *input_file );
+void yy_switch_to_buffer (YY_BUFFER_STATE new_buffer );
+YY_BUFFER_STATE yy_create_buffer (FILE *file,int size );
+void yy_delete_buffer (YY_BUFFER_STATE b );
+void yy_flush_buffer (YY_BUFFER_STATE b );
+void yypush_buffer_state (YY_BUFFER_STATE new_buffer );
+void yypop_buffer_state (void );
+
+static void yyensure_buffer_stack (void );
+static void yy_load_buffer_state (void );
+static void yy_init_buffer (YY_BUFFER_STATE b,FILE *file );
+
+#define YY_FLUSH_BUFFER yy_flush_buffer(YY_CURRENT_BUFFER )
+
+YY_BUFFER_STATE yy_scan_buffer (char *base,yy_size_t size );
+YY_BUFFER_STATE yy_scan_string (yyconst char *yy_str );
+YY_BUFFER_STATE yy_scan_bytes (yyconst char *bytes,int len );
+
+/* %endif */
+
+void *yyalloc (yy_size_t );
+void *yyrealloc (void *,yy_size_t );
+void yyfree (void * );
+
+#define yy_new_buffer yy_create_buffer
+
+#define yy_set_interactive(is_interactive) \
+ { \
+ if ( ! YY_CURRENT_BUFFER ){ \
+ yyensure_buffer_stack (); \
+ YY_CURRENT_BUFFER_LVALUE = \
+ yy_create_buffer(yyin,YY_BUF_SIZE ); \
+ } \
+ YY_CURRENT_BUFFER_LVALUE->yy_is_interactive = is_interactive; \
+ }
+
+#define yy_set_bol(at_bol) \
+ { \
+ if ( ! YY_CURRENT_BUFFER ){\
+ yyensure_buffer_stack (); \
+ YY_CURRENT_BUFFER_LVALUE = \
+ yy_create_buffer(yyin,YY_BUF_SIZE ); \
+ } \
+ YY_CURRENT_BUFFER_LVALUE->yy_at_bol = at_bol; \
+ }
+
+#define YY_AT_BOL() (YY_CURRENT_BUFFER_LVALUE->yy_at_bol)
+
+/* %% [1.0] yytext/yyin/yyout/yy_state_type/yylineno etc. def's & init go here */
+
+#define FLEX_DEBUG
+
+typedef unsigned char YY_CHAR;
+
+FILE *yyin = (FILE *) 0, *yyout = (FILE *) 0;
+
+typedef int yy_state_type;
+
+extern int yylineno;
+
+int yylineno = 1;
+
+extern char *yytext;
+#define yytext_ptr yytext
+
+/* %if-c-only Standard (non-C++) definition */
+
+static yy_state_type yy_get_previous_state (void );
+static yy_state_type yy_try_NUL_trans (yy_state_type current_state );
+static int yy_get_next_buffer (void );
+static void yy_fatal_error (yyconst char msg[] );
+
+/* %endif */
+
+/* Done after the current pattern has been matched and before the
+ * corresponding action - sets up yytext.
+ */
+#define YY_DO_BEFORE_ACTION \
+ (yytext_ptr) = yy_bp; \
+/* %% [2.0] code to fiddle yytext and yyleng for yymore() goes here \ */\
+ yyleng = (size_t) (yy_cp - yy_bp); \
+ (yy_hold_char) = *yy_cp; \
+ *yy_cp = '\0'; \
+/* %% [3.0] code to copy yytext_ptr to yytext[] goes here, if %array \ */\
+ (yy_c_buf_p) = yy_cp;
+
+/* %% [4.0] data tables for the DFA and the user's section 1 definitions go here */
+#define YY_NUM_RULES 122
+#define YY_END_OF_BUFFER 123
+/* This struct is not used in this scanner,
+ but its presence is necessary. */
+struct yy_trans_info
+ {
+ flex_int32_t yy_verify;
+ flex_int32_t yy_nxt;
+ };
+static yyconst flex_int16_t yy_accept[335] =
+ { 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 123, 121, 28, 29, 29, 59, 119, 68,
+ 46, 66, 120, 34, 35, 44, 42, 31, 43, 40,
+ 45, 103, 32, 33, 53, 50, 55, 49, 68, 117,
+ 36, 121, 37, 47, 117, 117, 117, 117, 117, 117,
+ 117, 117, 117, 117, 117, 117, 117, 117, 117, 117,
+ 38, 67, 39, 68, 4, 3, 3, 4, 4, 10,
+ 7, 7, 6, 10, 27, 13, 13, 12, 27, 122,
+ 116, 111, 112, 111, 114, 114, 114, 114, 114, 114,
+ 116, 116, 114, 116, 114, 114, 115, 116, 114, 114,
+
+ 29, 52, 68, 73, 57, 48, 71, 62, 69, 64,
+ 70, 63, 104, 118, 30, 72, 104, 103, 0, 61,
+ 54, 51, 56, 117, 29, 74, 60, 117, 117, 117,
+ 117, 117, 117, 117, 84, 117, 117, 117, 117, 117,
+ 80, 117, 117, 117, 117, 117, 117, 117, 117, 117,
+ 117, 117, 117, 117, 117, 117, 117, 58, 3, 2,
+ 1, 7, 0, 0, 5, 0, 7, 9, 8, 13,
+ 0, 0, 11, 0, 13, 14, 22, 22, 15, 16,
+ 17, 18, 19, 20, 21, 0, 112, 114, 114, 113,
+ 114, 115, 112, 65, 41, 0, 30, 0, 104, 0,
+
+ 0, 104, 117, 75, 117, 117, 117, 117, 117, 117,
+ 117, 117, 83, 117, 117, 117, 90, 117, 117, 117,
+ 117, 117, 117, 117, 117, 117, 117, 117, 117, 117,
+ 117, 117, 0, 0, 23, 23, 25, 0, 0, 104,
+ 117, 117, 117, 117, 79, 117, 81, 117, 117, 94,
+ 117, 117, 117, 107, 117, 117, 117, 117, 117, 117,
+ 117, 117, 117, 101, 105, 117, 117, 117, 24, 26,
+ 0, 104, 117, 117, 86, 117, 117, 108, 117, 106,
+ 117, 117, 117, 117, 117, 117, 96, 117, 117, 117,
+ 117, 117, 117, 117, 82, 91, 117, 117, 117, 117,
+
+ 92, 117, 117, 117, 117, 98, 117, 85, 97, 88,
+ 117, 117, 117, 78, 117, 117, 117, 95, 117, 117,
+ 99, 117, 77, 89, 93, 87, 76, 102, 109, 110,
+ 117, 117, 100, 0
+ } ;
+
+static yyconst flex_int32_t yy_ec[256] =
+ { 0,
+ 1, 1, 1, 1, 1, 1, 1, 1, 2, 3,
+ 1, 1, 4, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 2, 5, 6, 1, 7, 8, 9, 10, 11,
+ 12, 13, 14, 15, 16, 17, 18, 19, 19, 19,
+ 19, 20, 20, 20, 20, 21, 21, 22, 23, 24,
+ 25, 26, 27, 28, 29, 29, 29, 29, 29, 29,
+ 30, 30, 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30, 30, 30,
+ 31, 32, 33, 34, 30, 1, 35, 36, 37, 38,
+
+ 39, 40, 30, 41, 42, 30, 43, 44, 45, 46,
+ 47, 48, 49, 50, 51, 52, 53, 54, 55, 56,
+ 57, 30, 58, 59, 60, 61, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1
+ } ;
+
+static yyconst flex_int32_t yy_meta[62] =
+ { 0,
+ 1, 1, 2, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 3, 3,
+ 3, 1, 1, 1, 1, 1, 1, 1, 3, 3,
+ 1, 1, 1, 1, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 1, 1, 1,
+ 1
+ } ;
+
+static yyconst flex_int16_t yy_base[342] =
+ { 0,
+ 0, 0, 59, 61, 63, 67, 72, 77, 0, 0,
+ 109, 0, 536, 537, 537, 537, 532, 509, 537, 526,
+ 507, 522, 537, 537, 537, 65, 69, 537, 68, 81,
+ 78, 154, 508, 537, 61, 504, 63, 537, 500, 0,
+ 537, 102, 537, 147, 139, 477, 130, 479, 134, 145,
+ 154, 143, 477, 136, 471, 484, 470, 162, 475, 479,
+ 537, 460, 537, 537, 537, 537, 515, 499, 503, 537,
+ 537, 512, 203, 211, 537, 537, 511, 218, 248, 537,
+ 537, 537, 537, 510, 487, 504, 537, 497, 495, 492,
+ 490, 484, 83, 480, 172, 476, 0, 207, 469, 537,
+
+ 537, 537, 537, 537, 537, 537, 537, 537, 537, 486,
+ 537, 206, 210, 537, 0, 537, 217, 225, 241, 537,
+ 537, 537, 537, 0, 498, 537, 537, 463, 461, 454,
+ 458, 450, 445, 457, 0, 442, 444, 447, 440, 442,
+ 0, 440, 450, 431, 441, 445, 441, 446, 434, 181,
+ 213, 434, 437, 425, 429, 426, 433, 537, 537, 537,
+ 537, 537, 267, 283, 537, 236, 471, 537, 537, 537,
+ 303, 308, 537, 262, 470, 537, 259, 262, 537, 537,
+ 537, 537, 537, 537, 537, 301, 537, 537, 537, 537,
+ 456, 0, 468, 537, 306, 312, 0, 317, 322, 276,
+
+ 333, 325, 431, 0, 430, 433, 415, 422, 421, 425,
+ 419, 411, 0, 416, 413, 415, 418, 413, 406, 401,
+ 410, 401, 400, 398, 398, 396, 397, 396, 407, 406,
+ 409, 399, 353, 362, 309, 537, 354, 368, 376, 357,
+ 391, 406, 397, 166, 0, 400, 0, 396, 398, 0,
+ 386, 382, 384, 0, 398, 397, 389, 391, 379, 378,
+ 385, 389, 383, 0, 0, 386, 369, 383, 537, 537,
+ 384, 360, 370, 368, 0, 356, 354, 0, 362, 0,
+ 341, 353, 351, 319, 318, 330, 0, 320, 314, 321,
+ 298, 301, 300, 285, 0, 0, 267, 264, 264, 261,
+
+ 0, 262, 246, 229, 235, 0, 235, 0, 0, 0,
+ 213, 213, 203, 0, 202, 167, 152, 0, 163, 138,
+ 0, 132, 0, 0, 0, 0, 0, 0, 0, 0,
+ 140, 59, 0, 537, 405, 408, 411, 414, 89, 65,
+ 417
+ } ;
+
+static yyconst flex_int16_t yy_def[342] =
+ { 0,
+ 334, 1, 335, 335, 336, 336, 337, 337, 338, 338,
+ 334, 11, 334, 334, 334, 334, 334, 334, 334, 334,
+ 334, 334, 334, 334, 334, 334, 334, 334, 334, 334,
+ 334, 334, 334, 334, 334, 334, 334, 334, 334, 339,
+ 334, 334, 334, 334, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339, 339, 339,
+ 334, 334, 334, 334, 334, 334, 334, 334, 334, 334,
+ 334, 334, 334, 334, 334, 334, 334, 334, 334, 334,
+ 334, 334, 334, 334, 334, 334, 334, 334, 334, 334,
+ 334, 334, 334, 334, 334, 334, 340, 334, 334, 334,
+
+ 334, 334, 334, 334, 334, 334, 334, 334, 334, 334,
+ 334, 334, 334, 334, 341, 334, 334, 334, 334, 334,
+ 334, 334, 334, 339, 334, 334, 334, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 334, 334, 334,
+ 334, 334, 334, 334, 334, 334, 334, 334, 334, 334,
+ 334, 334, 334, 334, 334, 334, 334, 334, 334, 334,
+ 334, 334, 334, 334, 334, 334, 334, 334, 334, 334,
+ 334, 340, 334, 334, 334, 334, 341, 334, 334, 334,
+
+ 334, 334, 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 334, 334, 334, 334, 334, 334, 334, 334,
+ 339, 339, 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339, 334, 334,
+ 334, 334, 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339, 339, 339,
+
+ 339, 339, 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 0, 334, 334, 334, 334, 334, 334,
+ 334
+ } ;
+
+static yyconst flex_int16_t yy_nxt[599] =
+ { 0,
+ 14, 15, 16, 17, 18, 19, 20, 21, 22, 23,
+ 24, 25, 26, 27, 28, 29, 30, 31, 32, 32,
+ 32, 33, 34, 35, 36, 37, 38, 39, 40, 40,
+ 41, 42, 43, 44, 45, 46, 47, 48, 49, 50,
+ 40, 51, 40, 40, 40, 52, 53, 54, 55, 56,
+ 57, 58, 59, 40, 60, 40, 40, 61, 62, 63,
+ 64, 66, 67, 66, 67, 71, 72, 192, 73, 71,
+ 72, 68, 73, 68, 76, 77, 69, 106, 69, 76,
+ 77, 78, 108, 110, 103, 121, 78, 123, 103, 107,
+ 114, 124, 111, 109, 74, 115, 333, 112, 74, 113,
+
+ 113, 113, 116, 79, 101, 125, 189, 188, 79, 81,
+ 82, 83, 84, 85, 81, 86, 87, 87, 81, 81,
+ 81, 88, 89, 81, 90, 91, 87, 81, 81, 81,
+ 92, 81, 93, 94, 95, 81, 96, 97, 97, 81,
+ 98, 81, 99, 97, 97, 97, 97, 97, 97, 97,
+ 97, 97, 97, 97, 97, 97, 97, 97, 97, 97,
+ 97, 97, 97, 97, 97, 97, 81, 87, 81, 100,
+ 117, 126, 118, 118, 118, 128, 132, 136, 332, 138,
+ 127, 144, 133, 331, 129, 147, 134, 330, 148, 137,
+ 130, 139, 119, 141, 140, 145, 188, 189, 142, 143,
+
+ 152, 329, 153, 328, 163, 163, 164, 276, 165, 187,
+ 193, 154, 165, 162, 167, 277, 168, 327, 155, 171,
+ 171, 172, 195, 173, 196, 196, 196, 173, 113, 113,
+ 113, 223, 224, 198, 166, 199, 199, 199, 163, 164,
+ 326, 117, 169, 118, 118, 118, 325, 225, 119, 174,
+ 170, 175, 324, 176, 201, 200, 201, 176, 323, 202,
+ 202, 202, 226, 119, 171, 172, 177, 178, 163, 163,
+ 164, 322, 165, 321, 176, 320, 165, 235, 235, 176,
+ 236, 236, 179, 180, 163, 233, 164, 181, 165, 239,
+ 319, 239, 165, 182, 240, 240, 240, 183, 166, 184,
+
+ 318, 185, 317, 186, 171, 171, 172, 316, 173, 171,
+ 234, 172, 173, 173, 166, 237, 315, 173, 314, 237,
+ 237, 237, 198, 313, 196, 196, 196, 269, 269, 237,
+ 196, 196, 196, 198, 174, 196, 196, 196, 312, 174,
+ 199, 199, 199, 202, 202, 202, 201, 311, 201, 310,
+ 119, 202, 202, 202, 163, 163, 164, 309, 165, 308,
+ 238, 307, 165, 171, 171, 172, 306, 173, 270, 305,
+ 304, 173, 270, 270, 270, 240, 240, 240, 272, 272,
+ 272, 271, 270, 271, 166, 303, 272, 272, 272, 239,
+ 302, 239, 301, 174, 240, 240, 240, 271, 300, 271,
+
+ 299, 298, 272, 272, 272, 65, 65, 65, 70, 70,
+ 70, 75, 75, 75, 80, 80, 80, 197, 297, 197,
+ 296, 295, 294, 293, 292, 291, 290, 289, 288, 287,
+ 286, 285, 284, 283, 282, 281, 280, 279, 278, 275,
+ 274, 273, 268, 267, 266, 265, 264, 263, 262, 261,
+ 260, 259, 258, 257, 256, 255, 254, 253, 252, 251,
+ 250, 249, 248, 247, 246, 245, 244, 243, 242, 241,
+ 187, 188, 170, 162, 232, 231, 230, 229, 228, 227,
+ 222, 221, 220, 219, 218, 217, 216, 215, 214, 213,
+ 212, 211, 210, 209, 208, 207, 206, 205, 204, 203,
+
+ 101, 194, 188, 189, 188, 188, 188, 191, 188, 190,
+ 189, 188, 187, 170, 162, 161, 160, 159, 158, 157,
+ 156, 151, 150, 149, 146, 135, 131, 103, 122, 120,
+ 105, 104, 103, 102, 101, 334, 13, 334, 334, 334,
+ 334, 334, 334, 334, 334, 334, 334, 334, 334, 334,
+ 334, 334, 334, 334, 334, 334, 334, 334, 334, 334,
+ 334, 334, 334, 334, 334, 334, 334, 334, 334, 334,
+ 334, 334, 334, 334, 334, 334, 334, 334, 334, 334,
+ 334, 334, 334, 334, 334, 334, 334, 334, 334, 334,
+ 334, 334, 334, 334, 334, 334, 334, 334
+
+ } ;
+
+static yyconst flex_int16_t yy_chk[599] =
+ { 0,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 3, 3, 4, 4, 5, 5, 340, 5, 6,
+ 6, 3, 6, 4, 7, 7, 3, 26, 4, 8,
+ 8, 7, 27, 29, 35, 35, 8, 37, 37, 26,
+ 31, 339, 29, 27, 5, 31, 332, 30, 6, 30,
+
+ 30, 30, 31, 7, 42, 42, 93, 93, 8, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
+ 32, 44, 32, 32, 32, 45, 47, 49, 331, 50,
+ 44, 52, 47, 322, 45, 54, 47, 320, 54, 49,
+ 45, 50, 32, 51, 50, 52, 95, 95, 51, 51,
+
+ 58, 319, 58, 317, 73, 73, 73, 244, 73, 98,
+ 98, 58, 73, 74, 74, 244, 74, 316, 58, 78,
+ 78, 78, 112, 78, 112, 112, 112, 78, 113, 113,
+ 113, 150, 150, 117, 73, 117, 117, 117, 166, 166,
+ 315, 118, 74, 118, 118, 118, 313, 151, 113, 78,
+ 79, 79, 312, 79, 119, 117, 119, 79, 311, 119,
+ 119, 119, 151, 118, 174, 174, 79, 79, 163, 163,
+ 163, 307, 163, 305, 79, 304, 163, 177, 177, 79,
+ 178, 178, 79, 79, 164, 164, 164, 79, 164, 200,
+ 303, 200, 164, 79, 200, 200, 200, 79, 163, 79,
+
+ 302, 79, 300, 79, 171, 171, 171, 299, 171, 172,
+ 172, 172, 171, 172, 164, 186, 298, 172, 297, 186,
+ 186, 186, 195, 294, 195, 195, 195, 235, 235, 186,
+ 196, 196, 196, 198, 171, 198, 198, 198, 293, 172,
+ 199, 199, 199, 202, 202, 202, 201, 292, 201, 291,
+ 196, 201, 201, 201, 233, 233, 233, 290, 233, 289,
+ 199, 288, 233, 234, 234, 234, 286, 234, 237, 285,
+ 284, 234, 237, 237, 237, 240, 240, 240, 272, 272,
+ 272, 238, 237, 238, 233, 283, 238, 238, 238, 239,
+ 282, 239, 281, 234, 239, 239, 239, 271, 279, 271,
+
+ 277, 276, 271, 271, 271, 335, 335, 335, 336, 336,
+ 336, 337, 337, 337, 338, 338, 338, 341, 274, 341,
+ 273, 268, 267, 266, 263, 262, 261, 260, 259, 258,
+ 257, 256, 255, 253, 252, 251, 249, 248, 246, 243,
+ 242, 241, 232, 231, 230, 229, 228, 227, 226, 225,
+ 224, 223, 222, 221, 220, 219, 218, 217, 216, 215,
+ 214, 212, 211, 210, 209, 208, 207, 206, 205, 203,
+ 193, 191, 175, 167, 157, 156, 155, 154, 153, 152,
+ 149, 148, 147, 146, 145, 144, 143, 142, 140, 139,
+ 138, 137, 136, 134, 133, 132, 131, 130, 129, 128,
+
+ 125, 110, 99, 96, 94, 92, 91, 90, 89, 88,
+ 86, 85, 84, 77, 72, 69, 68, 67, 62, 60,
+ 59, 57, 56, 55, 53, 48, 46, 39, 36, 33,
+ 22, 21, 20, 18, 17, 13, 334, 334, 334, 334,
+ 334, 334, 334, 334, 334, 334, 334, 334, 334, 334,
+ 334, 334, 334, 334, 334, 334, 334, 334, 334, 334,
+ 334, 334, 334, 334, 334, 334, 334, 334, 334, 334,
+ 334, 334, 334, 334, 334, 334, 334, 334, 334, 334,
+ 334, 334, 334, 334, 334, 334, 334, 334, 334, 334,
+ 334, 334, 334, 334, 334, 334, 334, 334
+
+ } ;
+
+static yy_state_type yy_last_accepting_state;
+static char *yy_last_accepting_cpos;
+
+extern int yy_flex_debug;
+int yy_flex_debug = 1;
+
+static yyconst flex_int16_t yy_rule_linenum[122] =
+ { 0,
+ 180, 181, 183, 189, 193, 194, 204, 205, 206, 207,
+ 211, 212, 222, 223, 224, 225, 226, 227, 228, 229,
+ 230, 231, 236, 241, 247, 253, 261, 264, 265, 266,
+ 267, 268, 269, 270, 271, 272, 273, 274, 275, 276,
+ 277, 278, 279, 280, 281, 282, 283, 284, 285, 286,
+ 287, 288, 289, 290, 291, 292, 293, 294, 295, 296,
+ 297, 298, 299, 300, 301, 302, 303, 304, 306, 307,
+ 308, 309, 310, 311, 313, 314, 315, 316, 317, 319,
+ 320, 321, 322, 323, 324, 325, 326, 327, 328, 329,
+ 330, 331, 332, 333, 334, 335, 336, 338, 339, 340,
+
+ 341, 342, 345, 352, 359, 361, 363, 365, 367, 370,
+ 372, 373, 379, 383, 387, 391, 394, 398, 399, 400,
+ 404
+ } ;
+
+/* The intent behind this definition is that it'll catch
+ * any uses of REJECT which flex missed.
+ */
+#define REJECT reject_used_but_not_detected
+#define yymore() yymore_used_but_not_detected
+#define YY_MORE_ADJ 0
+#define YY_RESTORE_YY_MORE_OFFSET
+char *yytext;
+#line 1 "camp.l"
+#line 2 "camp.l"
+/*****
+ * camp.l
+ * Andy Hammerlindl 2002/06/14
+ *
+ * The lexical analyzer of the Asymptote language.
+ *****/
+
+#include <iostream>
+#include <fstream>
+#include <sstream>
+
+#include "util.h"
+#include "modifier.h"
+#include "exp.h"
+#include "stm.h"
+#include "fundec.h"
+#include "errormsg.h"
+#include "interact.h"
+#include "lexical.h"
+
+using namespace absyntax;
+using mem::string;
+
+#include "camp.tab.h"
+
+#define YY_NO_UNPUT
+
+fileinfo* fi;
+Int tokPos;
+Int charPos;
+//int commentDepth = 0;
+
+bool eof;
+string eofMessage;
+
+extern errorstream em;
+
+extern "C" int yywrap(void)
+{
+ charPos=1;
+ return 1;
+}
+
+typedef size_t (*input_f) (char* bif, size_t max_size);
+
+input_f yy_input = NULL;
+
+void setlexer(input_f input, string filename)
+{
+ YY_FLUSH_BUFFER;
+ yywrap();
+ fi = new fileinfo(filename);
+ yy_input = input;
+ tokPos = charPos = 1;
+
+ eof=false;
+ eofMessage="<no eof>";
+}
+
+#define YY_INPUT(buf,result,max_size) {result=yy_input(buf,max_size);}
+
+position lexerPos()
+{
+ position p;
+ p.init(fi, tokPos);
+ return p;
+}
+
+namespace {
+position here()
+
+{
+ return lexerPos();
+}
+
+void adjust()
+{
+ tokPos = charPos;
+ charPos += yyleng;
+ yylval.pos = here();
+}
+
+void makesymbol(bool op=true, string text = yytext)
+{
+ adjust();
+ yylval.ps.pos=here();
+ yylval.ps.sym=op ? symbol::opTrans(text) : symbol::literalTrans(text);
+}
+
+void makeselfsymbol(bool op=true, string text = yytext)
+{
+ /* Copy all but the last digit, which should be an =. */
+ assert(text[text.length()-1] == '=');
+ text.erase(text.length()-1);
+ makesymbol(op,text);
+}
+
+void makemod(trans::modifier mod) {
+ yylval.mod.pos=here();
+ yylval.mod.val=mod;
+}
+
+void makeperm(trans::permission perm) {
+ yylval.perm.pos=here();
+ yylval.perm.val=perm;
+}
+
+void newline()
+{
+ fi->newline();
+ charPos = tokPos = 1;
+}
+
+void error(void)
+{
+ em.error(here());
+}
+
+}
+
+
+// Used by the lexer rules to flag an unexpected end of input. The message is
+// the error message that should be reported, and may differ if, say the input
+// ends in the middle of a string or comment.
+void setEOF(string message) {
+ eof=true;
+ eofMessage=message;
+}
+
+// Called by code outside of the lexer to see if a parse error was caused by
+// running out of input.
+bool lexerEOF()
+{
+ return eof;
+}
+
+// Called by code outside of the lexer when it wants to report the unexpected
+// eof as an error (instead of looking for more input).
+void reportEOF() {
+ assert(eof);
+ error();
+ em << eofMessage;
+ em.sync();
+}
+
+string stringbuild;
+
+namespace {
+void append(char c)
+{
+ stringbuild.push_back(c);
+ yylval.pos = here();
+}
+
+void getstring(void)
+{
+ // NOTE: Replace here() with a position at the start of the string.
+ makesymbol(false,stringbuild);
+ string().swap(stringbuild);
+}
+}
+
+
+
+
+
+
+#line 964 "lex.yy.cc"
+
+#define INITIAL 0
+#define lexcomment 1
+#define texstring 2
+#define cstring 3
+#define lexformat 4
+#define opname 5
+
+#ifndef YY_NO_UNISTD_H
+/* Special case for "unistd.h", since it is non-ANSI. We include it way
+ * down here because we want the user's section 1 to have been scanned first.
+ * The user has a chance to override it with an option.
+ */
+/* %if-c-only */
+#include <unistd.h>
+/* %endif */
+/* %if-c++-only */
+/* %endif */
+#endif
+
+#ifndef YY_EXTRA_TYPE
+#define YY_EXTRA_TYPE void *
+#endif
+
+/* %if-c-only Reentrant structure and macros (non-C++). */
+/* %if-reentrant */
+/* %if-c-only */
+
+static int yy_init_globals (void );
+
+/* %endif */
+/* %if-reentrant */
+/* %endif */
+/* %endif End reentrant structures and macros. */
+
+/* Accessor methods to globals.
+ These are made visible to non-reentrant scanners for convenience. */
+
+int yylex_destroy (void );
+
+int yyget_debug (void );
+
+void yyset_debug (int debug_flag );
+
+YY_EXTRA_TYPE yyget_extra (void );
+
+void yyset_extra (YY_EXTRA_TYPE user_defined );
+
+FILE *yyget_in (void );
+
+void yyset_in (FILE * in_str );
+
+FILE *yyget_out (void );
+
+void yyset_out (FILE * out_str );
+
+int yyget_leng (void );
+
+char *yyget_text (void );
+
+int yyget_lineno (void );
+
+void yyset_lineno (int line_number );
+
+/* %if-bison-bridge */
+/* %endif */
+
+/* Macros after this point can all be overridden by user definitions in
+ * section 1.
+ */
+
+#ifndef YY_SKIP_YYWRAP
+#ifdef __cplusplus
+extern "C" int yywrap (void );
+#else
+extern int yywrap (void );
+#endif
+#endif
+
+/* %not-for-header */
+
+ static void yyunput (int c,char *buf_ptr );
+
+/* %ok-for-header */
+
+/* %endif */
+
+#ifndef yytext_ptr
+static void yy_flex_strncpy (char *,yyconst char *,int );
+#endif
+
+#ifdef YY_NEED_STRLEN
+static int yy_flex_strlen (yyconst char * );
+#endif
+
+#ifndef YY_NO_INPUT
+/* %if-c-only Standard (non-C++) definition */
+/* %not-for-header */
+
+#ifdef __cplusplus
+static int yyinput (void );
+#else
+static int input (void );
+#endif
+/* %ok-for-header */
+
+/* %endif */
+#endif
+
+/* %if-c-only */
+
+/* %endif */
+
+/* Amount of stuff to slurp up with each read. */
+#ifndef YY_READ_BUF_SIZE
+#define YY_READ_BUF_SIZE 8192
+#endif
+
+/* Copy whatever the last rule matched to the standard output. */
+#ifndef ECHO
+/* %if-c-only Standard (non-C++) definition */
+/* This used to be an fputs(), but since the string might contain NUL's,
+ * we now use fwrite().
+ */
+#define ECHO fwrite( yytext, yyleng, 1, yyout )
+/* %endif */
+/* %if-c++-only C++ definition */
+/* %endif */
+#endif
+
+/* Gets input and stuffs it into "buf". number of characters read, or YY_NULL,
+ * is returned in "result".
+ */
+#ifndef YY_INPUT
+#define YY_INPUT(buf,result,max_size) \
+/* %% [5.0] fread()/read() definition of YY_INPUT goes here unless we're doing C++ \ */\
+ if ( YY_CURRENT_BUFFER_LVALUE->yy_is_interactive ) \
+ { \
+ int c = '*'; \
+ unsigned n; \
+ for ( n = 0; n < max_size && \
+ (c = getc( yyin )) != EOF && c != '\n'; ++n ) \
+ buf[n] = (char) c; \
+ if ( c == '\n' ) \
+ buf[n++] = (char) c; \
+ if ( c == EOF && ferror( yyin ) ) \
+ YY_FATAL_ERROR( "input in flex scanner failed" ); \
+ result = n; \
+ } \
+ else \
+ { \
+ errno=0; \
+ while ( (result = fread(buf, 1, max_size, yyin))==0 && ferror(yyin)) \
+ { \
+ if( errno != EINTR) \
+ { \
+ YY_FATAL_ERROR( "input in flex scanner failed" ); \
+ break; \
+ } \
+ errno=0; \
+ clearerr(yyin); \
+ } \
+ }\
+\
+/* %if-c++-only C++ definition \ */\
+/* %endif */
+
+#endif
+
+/* No semi-colon after return; correct usage is to write "yyterminate();" -
+ * we don't want an extra ';' after the "return" because that will cause
+ * some compilers to complain about unreachable statements.
+ */
+#ifndef yyterminate
+#define yyterminate() return YY_NULL
+#endif
+
+/* Number of entries by which start-condition stack grows. */
+#ifndef YY_START_STACK_INCR
+#define YY_START_STACK_INCR 25
+#endif
+
+/* Report a fatal error. */
+#ifndef YY_FATAL_ERROR
+/* %if-c-only */
+#define YY_FATAL_ERROR(msg) yy_fatal_error( msg )
+/* %endif */
+/* %if-c++-only */
+/* %endif */
+#endif
+
+/* %if-tables-serialization structures and prototypes */
+/* %not-for-header */
+
+/* %ok-for-header */
+
+/* %not-for-header */
+
+/* %tables-yydmap generated elements */
+/* %endif */
+/* end tables serialization structures and prototypes */
+
+/* %ok-for-header */
+
+/* Default declaration of generated scanner - a define so the user can
+ * easily add parameters.
+ */
+#ifndef YY_DECL
+#define YY_DECL_IS_OURS 1
+/* %if-c-only Standard (non-C++) definition */
+
+extern int yylex (void);
+
+#define YY_DECL int yylex (void)
+/* %endif */
+/* %if-c++-only C++ definition */
+/* %endif */
+#endif /* !YY_DECL */
+
+/* Code executed at the beginning of each rule, after yytext and yyleng
+ * have been set up.
+ */
+#ifndef YY_USER_ACTION
+#define YY_USER_ACTION
+#endif
+
+/* Code executed at the end of each rule. */
+#ifndef YY_BREAK
+#define YY_BREAK break;
+#endif
+
+/* %% [6.0] YY_RULE_SETUP definition goes here */
+#define YY_RULE_SETUP \
+ YY_USER_ACTION
+
+/* %not-for-header */
+
+/** The main scanner function which does all the work.
+ */
+YY_DECL
+{
+ register yy_state_type yy_current_state;
+ register char *yy_cp, *yy_bp;
+ register int yy_act;
+
+/* %% [7.0] user's declarations go here */
+#line 177 "camp.l"
+
+
+#line 1214 "lex.yy.cc"
+
+ if ( !(yy_init) )
+ {
+ (yy_init) = 1;
+
+#ifdef YY_USER_INIT
+ YY_USER_INIT;
+#endif
+
+ if ( ! (yy_start) )
+ (yy_start) = 1; /* first start state */
+
+ if ( ! yyin )
+/* %if-c-only */
+ yyin = stdin;
+/* %endif */
+/* %if-c++-only */
+/* %endif */
+
+ if ( ! yyout )
+/* %if-c-only */
+ yyout = stdout;
+/* %endif */
+/* %if-c++-only */
+/* %endif */
+
+ if ( ! YY_CURRENT_BUFFER ) {
+ yyensure_buffer_stack ();
+ YY_CURRENT_BUFFER_LVALUE =
+ yy_create_buffer(yyin,YY_BUF_SIZE );
+ }
+
+ yy_load_buffer_state( );
+ }
+
+ while ( 1 ) /* loops until end-of-file is reached */
+ {
+/* %% [8.0] yymore()-related code goes here */
+ yy_cp = (yy_c_buf_p);
+
+ /* Support of yytext. */
+ *yy_cp = (yy_hold_char);
+
+ /* yy_bp points to the position in yy_ch_buf of the start of
+ * the current run.
+ */
+ yy_bp = yy_cp;
+
+/* %% [9.0] code to set up and find next match goes here */
+ yy_current_state = (yy_start);
+yy_match:
+ do
+ {
+ register YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)];
+ if ( yy_accept[yy_current_state] )
+ {
+ (yy_last_accepting_state) = yy_current_state;
+ (yy_last_accepting_cpos) = yy_cp;
+ }
+ while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
+ {
+ yy_current_state = (int) yy_def[yy_current_state];
+ if ( yy_current_state >= 335 )
+ yy_c = yy_meta[(unsigned int) yy_c];
+ }
+ yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
+ ++yy_cp;
+ }
+ while ( yy_base[yy_current_state] != 537 );
+
+yy_find_action:
+/* %% [10.0] code to find the action number goes here */
+ yy_act = yy_accept[yy_current_state];
+ if ( yy_act == 0 )
+ { /* have to back up */
+ yy_cp = (yy_last_accepting_cpos);
+ yy_current_state = (yy_last_accepting_state);
+ yy_act = yy_accept[yy_current_state];
+ }
+
+ YY_DO_BEFORE_ACTION;
+
+/* %% [11.0] code for yylineno update goes here */
+
+do_action: /* This label is used only to access EOF actions. */
+
+/* %% [12.0] debug code goes here */
+ if ( yy_flex_debug )
+ {
+ if ( yy_act == 0 )
+ fprintf( stderr, "--scanner backing up\n" );
+ else if ( yy_act < 122 )
+ fprintf( stderr, "--accepting rule at line %ld (\"%s\")\n",
+ (long)yy_rule_linenum[yy_act], yytext );
+ else if ( yy_act == 122 )
+ fprintf( stderr, "--accepting default rule (\"%s\")\n",
+ yytext );
+ else if ( yy_act == 123 )
+ fprintf( stderr, "--(end of buffer or a NUL)\n" );
+ else
+ fprintf( stderr, "--EOF (start condition %d)\n", YY_START );
+ }
+
+ switch ( yy_act )
+ { /* beginning of action switch */
+/* %% [13.0] actions go here */
+ case 0: /* must back up */
+ /* undo the effects of YY_DO_BEFORE_ACTION */
+ *yy_cp = (yy_hold_char);
+ yy_cp = (yy_last_accepting_cpos);
+ yy_current_state = (yy_last_accepting_state);
+ goto yy_find_action;
+
+case 1:
+YY_RULE_SETUP
+#line 180 "camp.l"
+{adjust(); /*commentDepth++;*/}
+ YY_BREAK
+case 2:
+YY_RULE_SETUP
+#line 181 "camp.l"
+{adjust(); /*commentDepth--;*/
+ /*if (commentDepth == 0)*/ BEGIN INITIAL; }
+ YY_BREAK
+case 3:
+/* rule 3 can match eol */
+YY_RULE_SETUP
+#line 183 "camp.l"
+{adjust(); newline(); continue; }
+ YY_BREAK
+case YY_STATE_EOF(lexcomment):
+#line 184 "camp.l"
+{adjust();
+ setEOF("comment not terminated");
+ BEGIN INITIAL;
+ return GARBAGE;
+ }
+ YY_BREAK
+case 4:
+YY_RULE_SETUP
+#line 189 "camp.l"
+{adjust(); continue; }
+ YY_BREAK
+
+
+case 5:
+/* rule 5 can match eol */
+*yy_cp = (yy_hold_char); /* undo effects of setting up yytext */
+(yy_c_buf_p) = yy_cp = yy_bp + 1;
+YY_DO_BEFORE_ACTION; /* set up yytext again */
+YY_RULE_SETUP
+#line 193 "camp.l"
+{adjust(); BEGIN INITIAL;}
+ YY_BREAK
+case 6:
+YY_RULE_SETUP
+#line 194 "camp.l"
+{adjust();
+ BEGIN INITIAL;
+ getstring();
+ return STRING; }
+ YY_BREAK
+case YY_STATE_EOF(texstring):
+#line 198 "camp.l"
+{adjust();
+ setEOF("string not terminated");
+ BEGIN INITIAL;
+ getstring();
+ return GARBAGE;
+ }
+ YY_BREAK
+case 7:
+/* rule 7 can match eol */
+YY_RULE_SETUP
+#line 204 "camp.l"
+{adjust(); newline(); append('\n'); continue; }
+ YY_BREAK
+case 8:
+YY_RULE_SETUP
+#line 205 "camp.l"
+{adjust(); append('\\'); append('\\'); continue; }
+ YY_BREAK
+case 9:
+YY_RULE_SETUP
+#line 206 "camp.l"
+{adjust(); append('\"'); continue; }
+ YY_BREAK
+case 10:
+YY_RULE_SETUP
+#line 207 "camp.l"
+{adjust(); append(*yytext); }
+ YY_BREAK
+
+
+case 11:
+/* rule 11 can match eol */
+*yy_cp = (yy_hold_char); /* undo effects of setting up yytext */
+(yy_c_buf_p) = yy_cp = yy_bp + 1;
+YY_DO_BEFORE_ACTION; /* set up yytext again */
+YY_RULE_SETUP
+#line 211 "camp.l"
+{adjust(); BEGIN INITIAL;}
+ YY_BREAK
+case 12:
+YY_RULE_SETUP
+#line 212 "camp.l"
+{adjust();
+ BEGIN INITIAL;
+ getstring();
+ return STRING; }
+ YY_BREAK
+case YY_STATE_EOF(cstring):
+#line 216 "camp.l"
+{adjust();
+ setEOF("string not terminated");
+ BEGIN INITIAL;
+ getstring();
+ return GARBAGE;
+ }
+ YY_BREAK
+case 13:
+/* rule 13 can match eol */
+YY_RULE_SETUP
+#line 222 "camp.l"
+{adjust(); newline(); append('\n'); continue; }
+ YY_BREAK
+case 14:
+YY_RULE_SETUP
+#line 223 "camp.l"
+{adjust(); append(yytext[1]); continue; }
+ YY_BREAK
+case 15:
+YY_RULE_SETUP
+#line 224 "camp.l"
+{adjust(); append('\a'); continue; }
+ YY_BREAK
+case 16:
+YY_RULE_SETUP
+#line 225 "camp.l"
+{adjust(); append('\b'); continue; }
+ YY_BREAK
+case 17:
+YY_RULE_SETUP
+#line 226 "camp.l"
+{adjust(); append('\f'); continue; }
+ YY_BREAK
+case 18:
+YY_RULE_SETUP
+#line 227 "camp.l"
+{adjust(); append('\n'); continue; }
+ YY_BREAK
+case 19:
+YY_RULE_SETUP
+#line 228 "camp.l"
+{adjust(); append('\r'); continue; }
+ YY_BREAK
+case 20:
+YY_RULE_SETUP
+#line 229 "camp.l"
+{adjust(); append('\t'); continue; }
+ YY_BREAK
+case 21:
+YY_RULE_SETUP
+#line 230 "camp.l"
+{adjust(); append('\v'); continue; }
+ YY_BREAK
+case 22:
+YY_RULE_SETUP
+#line 231 "camp.l"
+{adjust();
+ char x=(char)(yytext[1]-'0');
+ append(x);
+ continue;
+ }
+ YY_BREAK
+case 23:
+YY_RULE_SETUP
+#line 236 "camp.l"
+{adjust();
+ char x=(char)((yytext[1]-'0')*8+yytext[2]-'0');
+ append(x);
+ continue;
+ }
+ YY_BREAK
+case 24:
+YY_RULE_SETUP
+#line 241 "camp.l"
+{adjust();
+ char x=(char)((yytext[1]-'0')*64+(yytext[2]-'0')*8
+ +yytext[3]-'0');
+ append(x);
+ continue;
+ }
+ YY_BREAK
+case 25:
+YY_RULE_SETUP
+#line 247 "camp.l"
+{adjust();
+ char x=(char) (yytext[2] <= '9' ? yytext[2]-'0' :
+ 10+yytext[2]-'A');
+ append(x);
+ continue;
+ }
+ YY_BREAK
+case 26:
+YY_RULE_SETUP
+#line 253 "camp.l"
+{adjust();
+ char x=(char) ((yytext[2] <= '9' ? yytext[2]-'0' :
+ 10+yytext[2]-'A')*16
+ +(yytext[3] <= '9' ? yytext[3]-'0' :
+ 10+yytext[3]-'A'));
+ append(x);
+ continue;
+ }
+ YY_BREAK
+case 27:
+YY_RULE_SETUP
+#line 261 "camp.l"
+{adjust(); append(*yytext); }
+ YY_BREAK
+
+case 28:
+YY_RULE_SETUP
+#line 264 "camp.l"
+{adjust(); continue;}
+ YY_BREAK
+case 29:
+/* rule 29 can match eol */
+YY_RULE_SETUP
+#line 265 "camp.l"
+{adjust(); newline(); continue;}
+ YY_BREAK
+case 30:
+YY_RULE_SETUP
+#line 266 "camp.l"
+{adjust(); continue;}
+ YY_BREAK
+case 31:
+YY_RULE_SETUP
+#line 267 "camp.l"
+{adjust(); return ','; }
+ YY_BREAK
+case 32:
+YY_RULE_SETUP
+#line 268 "camp.l"
+{adjust(); return ':'; }
+ YY_BREAK
+case 33:
+YY_RULE_SETUP
+#line 269 "camp.l"
+{adjust(); return ';'; }
+ YY_BREAK
+case 34:
+YY_RULE_SETUP
+#line 270 "camp.l"
+{adjust(); return '('; }
+ YY_BREAK
+case 35:
+YY_RULE_SETUP
+#line 271 "camp.l"
+{adjust(); return ')'; }
+ YY_BREAK
+case 36:
+YY_RULE_SETUP
+#line 272 "camp.l"
+{adjust(); return '['; }
+ YY_BREAK
+case 37:
+YY_RULE_SETUP
+#line 273 "camp.l"
+{adjust(); return ']'; }
+ YY_BREAK
+case 38:
+YY_RULE_SETUP
+#line 274 "camp.l"
+{adjust(); return '{'; }
+ YY_BREAK
+case 39:
+YY_RULE_SETUP
+#line 275 "camp.l"
+{adjust(); return '}'; }
+ YY_BREAK
+case 40:
+YY_RULE_SETUP
+#line 276 "camp.l"
+{adjust(); return '.'; }
+ YY_BREAK
+case 41:
+YY_RULE_SETUP
+#line 277 "camp.l"
+{adjust(); return ELLIPSIS; }
+ YY_BREAK
+case 42:
+YY_RULE_SETUP
+#line 278 "camp.l"
+{makesymbol(); return '+'; }
+ YY_BREAK
+case 43:
+YY_RULE_SETUP
+#line 279 "camp.l"
+{makesymbol(); return '-'; }
+ YY_BREAK
+case 44:
+YY_RULE_SETUP
+#line 280 "camp.l"
+{makesymbol(); return '*'; }
+ YY_BREAK
+case 45:
+YY_RULE_SETUP
+#line 281 "camp.l"
+{makesymbol(); return '/'; }
+ YY_BREAK
+case 46:
+YY_RULE_SETUP
+#line 282 "camp.l"
+{makesymbol(); return '%'; }
+ YY_BREAK
+case 47:
+YY_RULE_SETUP
+#line 283 "camp.l"
+{makesymbol(); return '^'; }
+ YY_BREAK
+case 48:
+YY_RULE_SETUP
+#line 284 "camp.l"
+{makesymbol(true,"^"); return '^'; }
+ YY_BREAK
+case 49:
+YY_RULE_SETUP
+#line 285 "camp.l"
+{adjust(); return '?'; }
+ YY_BREAK
+case 50:
+YY_RULE_SETUP
+#line 286 "camp.l"
+{adjust(); return ASSIGN; }
+ YY_BREAK
+case 51:
+YY_RULE_SETUP
+#line 287 "camp.l"
+{makesymbol(); return EQ; }
+ YY_BREAK
+case 52:
+YY_RULE_SETUP
+#line 288 "camp.l"
+{makesymbol(); return NEQ; }
+ YY_BREAK
+case 53:
+YY_RULE_SETUP
+#line 289 "camp.l"
+{makesymbol(); return LT; }
+ YY_BREAK
+case 54:
+YY_RULE_SETUP
+#line 290 "camp.l"
+{makesymbol(); return LE; }
+ YY_BREAK
+case 55:
+YY_RULE_SETUP
+#line 291 "camp.l"
+{makesymbol(); return GT; }
+ YY_BREAK
+case 56:
+YY_RULE_SETUP
+#line 292 "camp.l"
+{makesymbol(); return GE; }
+ YY_BREAK
+case 57:
+YY_RULE_SETUP
+#line 293 "camp.l"
+{makesymbol(); return CAND; }
+ YY_BREAK
+case 58:
+YY_RULE_SETUP
+#line 294 "camp.l"
+{makesymbol(); return COR; }
+ YY_BREAK
+case 59:
+YY_RULE_SETUP
+#line 295 "camp.l"
+{makesymbol(); return LOGNOT; }
+ YY_BREAK
+case 60:
+YY_RULE_SETUP
+#line 296 "camp.l"
+{makesymbol(); return CARETS; }
+ YY_BREAK
+case 61:
+YY_RULE_SETUP
+#line 297 "camp.l"
+{makesymbol(); return COLONS; }
+ YY_BREAK
+case 62:
+YY_RULE_SETUP
+#line 298 "camp.l"
+{makesymbol(); return INCR; }
+ YY_BREAK
+case 63:
+YY_RULE_SETUP
+#line 299 "camp.l"
+{makesymbol(); return DOTS; }
+ YY_BREAK
+case 64:
+YY_RULE_SETUP
+#line 300 "camp.l"
+{makesymbol(); return DASHES; }
+ YY_BREAK
+case 65:
+YY_RULE_SETUP
+#line 301 "camp.l"
+{makesymbol(); return LONGDASH; }
+ YY_BREAK
+case 66:
+YY_RULE_SETUP
+#line 302 "camp.l"
+{makesymbol(); return AMPERSAND; }
+ YY_BREAK
+case 67:
+YY_RULE_SETUP
+#line 303 "camp.l"
+{makesymbol(); return BAR; }
+ YY_BREAK
+case 68:
+YY_RULE_SETUP
+#line 304 "camp.l"
+{makesymbol(); return OPERATOR; }
+ YY_BREAK
+case 69:
+YY_RULE_SETUP
+#line 306 "camp.l"
+{makeselfsymbol(); return ADD; }
+ YY_BREAK
+case 70:
+YY_RULE_SETUP
+#line 307 "camp.l"
+{makeselfsymbol(); return SUBTRACT; }
+ YY_BREAK
+case 71:
+YY_RULE_SETUP
+#line 308 "camp.l"
+{makeselfsymbol(); return TIMES; }
+ YY_BREAK
+case 72:
+YY_RULE_SETUP
+#line 309 "camp.l"
+{makeselfsymbol(); return DIVIDE; }
+ YY_BREAK
+case 73:
+YY_RULE_SETUP
+#line 310 "camp.l"
+{makeselfsymbol(); return MOD; }
+ YY_BREAK
+case 74:
+YY_RULE_SETUP
+#line 311 "camp.l"
+{makeselfsymbol(); return EXPONENT; }
+ YY_BREAK
+case 75:
+YY_RULE_SETUP
+#line 313 "camp.l"
+{adjust(); return AND; }
+ YY_BREAK
+case 76:
+YY_RULE_SETUP
+#line 314 "camp.l"
+{makesymbol(); return CONTROLS; }
+ YY_BREAK
+case 77:
+YY_RULE_SETUP
+#line 315 "camp.l"
+{makesymbol(); return TENSION; }
+ YY_BREAK
+case 78:
+YY_RULE_SETUP
+#line 316 "camp.l"
+{makesymbol(); return ATLEAST; }
+ YY_BREAK
+case 79:
+YY_RULE_SETUP
+#line 317 "camp.l"
+{makesymbol(); return CURL; }
+ YY_BREAK
+case 80:
+YY_RULE_SETUP
+#line 319 "camp.l"
+{adjust(); return IF; }
+ YY_BREAK
+case 81:
+YY_RULE_SETUP
+#line 320 "camp.l"
+{adjust(); return ELSE; }
+ YY_BREAK
+case 82:
+YY_RULE_SETUP
+#line 321 "camp.l"
+{adjust(); return WHILE; }
+ YY_BREAK
+case 83:
+YY_RULE_SETUP
+#line 322 "camp.l"
+{adjust(); return FOR; }
+ YY_BREAK
+case 84:
+YY_RULE_SETUP
+#line 323 "camp.l"
+{adjust(); return DO; }
+ YY_BREAK
+case 85:
+YY_RULE_SETUP
+#line 324 "camp.l"
+{adjust(); return RETURN_; }
+ YY_BREAK
+case 86:
+YY_RULE_SETUP
+#line 325 "camp.l"
+{adjust(); return BREAK; }
+ YY_BREAK
+case 87:
+YY_RULE_SETUP
+#line 326 "camp.l"
+{adjust(); return CONTINUE; }
+ YY_BREAK
+case 88:
+YY_RULE_SETUP
+#line 327 "camp.l"
+{adjust(); return STRUCT; }
+ YY_BREAK
+case 89:
+YY_RULE_SETUP
+#line 328 "camp.l"
+{adjust(); return TYPEDEF; }
+ YY_BREAK
+case 90:
+YY_RULE_SETUP
+#line 329 "camp.l"
+{adjust(); return NEW; }
+ YY_BREAK
+case 91:
+YY_RULE_SETUP
+#line 330 "camp.l"
+{adjust(); return ACCESS; }
+ YY_BREAK
+case 92:
+YY_RULE_SETUP
+#line 331 "camp.l"
+{adjust(); return IMPORT; }
+ YY_BREAK
+case 93:
+YY_RULE_SETUP
+#line 332 "camp.l"
+{adjust(); return UNRAVEL; }
+ YY_BREAK
+case 94:
+YY_RULE_SETUP
+#line 333 "camp.l"
+{adjust(); return FROM; }
+ YY_BREAK
+case 95:
+YY_RULE_SETUP
+#line 334 "camp.l"
+{adjust(); return INCLUDE; }
+ YY_BREAK
+case 96:
+YY_RULE_SETUP
+#line 335 "camp.l"
+{adjust(); return QUOTE; }
+ YY_BREAK
+case 97:
+YY_RULE_SETUP
+#line 336 "camp.l"
+{adjust(); makemod(trans::EXPLICIT_STATIC);
+ return MODIFIER; }
+ YY_BREAK
+case 98:
+YY_RULE_SETUP
+#line 338 "camp.l"
+{adjust(); makeperm(trans::PUBLIC); return PERM; }
+ YY_BREAK
+case 99:
+YY_RULE_SETUP
+#line 339 "camp.l"
+{adjust(); makeperm(trans::PRIVATE); return PERM; }
+ YY_BREAK
+case 100:
+YY_RULE_SETUP
+#line 340 "camp.l"
+{adjust(); makeperm(trans::RESTRICTED); return PERM; }
+ YY_BREAK
+case 101:
+YY_RULE_SETUP
+#line 341 "camp.l"
+{adjust(); return THIS; }
+ YY_BREAK
+case 102:
+YY_RULE_SETUP
+#line 342 "camp.l"
+{adjust(); return EXPLICIT; }
+ YY_BREAK
+case 103:
+YY_RULE_SETUP
+#line 345 "camp.l"
+try {
+ adjust(); yylval.e= new intExp(here(), lexical::cast<Int>(yytext));
+ } catch (lexical::bad_cast&) {
+ error();
+ em << "invalid integer";
+ yylval.e= new intExp(here(), 0);
+ } return LIT;
+ YY_BREAK
+case 104:
+YY_RULE_SETUP
+#line 352 "camp.l"
+try {
+ adjust(); yylval.e= new realExp(here(), lexical::cast<double>(yytext));
+ } catch (lexical::bad_cast&) {
+ error();
+ em << "invalid real";
+ yylval.e= new realExp(here(), 0);
+ } return LIT;
+ YY_BREAK
+case 105:
+YY_RULE_SETUP
+#line 359 "camp.l"
+{
+ adjust(); yylval.e= new booleanExp(here(), true); return LIT; }
+ YY_BREAK
+case 106:
+YY_RULE_SETUP
+#line 361 "camp.l"
+{
+ adjust(); yylval.e= new booleanExp(here(), false); return LIT; }
+ YY_BREAK
+case 107:
+YY_RULE_SETUP
+#line 363 "camp.l"
+{
+ adjust(); yylval.e= new nullExp(here()); return LIT; }
+ YY_BREAK
+case 108:
+YY_RULE_SETUP
+#line 365 "camp.l"
+{
+ adjust(); yylval.e= new cycleExp(here()); return LIT; }
+ YY_BREAK
+case 109:
+YY_RULE_SETUP
+#line 367 "camp.l"
+{
+ adjust(); yylval.e= new newPictureExp(here()); return LIT; }
+ YY_BREAK
+case 110:
+YY_RULE_SETUP
+#line 370 "camp.l"
+{adjust(); BEGIN opname; }
+ YY_BREAK
+
+case 111:
+YY_RULE_SETUP
+#line 372 "camp.l"
+{adjust(); continue;}
+ YY_BREAK
+case 112:
+/* rule 112 can match eol */
+YY_RULE_SETUP
+#line 373 "camp.l"
+{adjust(); newline(); continue;}
+ YY_BREAK
+case YY_STATE_EOF(opname):
+#line 374 "camp.l"
+{adjust();
+ setEOF("missing operator name");
+ BEGIN INITIAL;
+ return GARBAGE;
+ }
+ YY_BREAK
+case 113:
+YY_RULE_SETUP
+#line 379 "camp.l"
+{ makesymbol(true, "^");
+ BEGIN INITIAL;
+ return ID;
+ }
+ YY_BREAK
+case 114:
+YY_RULE_SETUP
+#line 383 "camp.l"
+{
+ makesymbol();
+ BEGIN INITIAL;
+ return ID;}
+ YY_BREAK
+case 115:
+YY_RULE_SETUP
+#line 387 "camp.l"
+{
+ makesymbol(true);
+ BEGIN INITIAL;
+ return ID; }
+ YY_BREAK
+case 116:
+YY_RULE_SETUP
+#line 391 "camp.l"
+{}
+ YY_BREAK
+
+case 117:
+YY_RULE_SETUP
+#line 394 "camp.l"
+{
+ makesymbol(false);
+ return ID; }
+ YY_BREAK
+case 118:
+YY_RULE_SETUP
+#line 398 "camp.l"
+{adjust(); /*commentDepth = 1;*/ BEGIN lexcomment; }
+ YY_BREAK
+case 119:
+YY_RULE_SETUP
+#line 399 "camp.l"
+{adjust(); BEGIN texstring; }
+ YY_BREAK
+case 120:
+YY_RULE_SETUP
+#line 400 "camp.l"
+{adjust(); BEGIN cstring; }
+ YY_BREAK
+case YY_STATE_EOF(INITIAL):
+case YY_STATE_EOF(lexformat):
+#line 402 "camp.l"
+{ setEOF("unexpected end of input"); yyterminate(); }
+ YY_BREAK
+case 121:
+YY_RULE_SETUP
+#line 404 "camp.l"
+{
+ adjust(); error(); em <<"invalid token '" << yytext << "'"; }
+ YY_BREAK
+case 122:
+YY_RULE_SETUP
+#line 407 "camp.l"
+ECHO;
+ YY_BREAK
+#line 2059 "lex.yy.cc"
+
+ case YY_END_OF_BUFFER:
+ {
+ /* Amount of text matched not including the EOB char. */
+ int yy_amount_of_matched_text = (int) (yy_cp - (yytext_ptr)) - 1;
+
+ /* Undo the effects of YY_DO_BEFORE_ACTION. */
+ *yy_cp = (yy_hold_char);
+ YY_RESTORE_YY_MORE_OFFSET
+
+ if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_NEW )
+ {
+ /* We're scanning a new file or input source. It's
+ * possible that this happened because the user
+ * just pointed yyin at a new source and called
+ * yylex(). If so, then we have to assure
+ * consistency between YY_CURRENT_BUFFER and our
+ * globals. Here is the right place to do so, because
+ * this is the first action (other than possibly a
+ * back-up) that will match for the new input source.
+ */
+ (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars;
+ YY_CURRENT_BUFFER_LVALUE->yy_input_file = yyin;
+ YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = YY_BUFFER_NORMAL;
+ }
+
+ /* Note that here we test for yy_c_buf_p "<=" to the position
+ * of the first EOB in the buffer, since yy_c_buf_p will
+ * already have been incremented past the NUL character
+ * (since all states make transitions on EOB to the
+ * end-of-buffer state). Contrast this with the test
+ * in input().
+ */
+ if ( (yy_c_buf_p) <= &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] )
+ { /* This was really a NUL. */
+ yy_state_type yy_next_state;
+
+ (yy_c_buf_p) = (yytext_ptr) + yy_amount_of_matched_text;
+
+ yy_current_state = yy_get_previous_state( );
+
+ /* Okay, we're now positioned to make the NUL
+ * transition. We couldn't have
+ * yy_get_previous_state() go ahead and do it
+ * for us because it doesn't know how to deal
+ * with the possibility of jamming (and we don't
+ * want to build jamming into it because then it
+ * will run more slowly).
+ */
+
+ yy_next_state = yy_try_NUL_trans( yy_current_state );
+
+ yy_bp = (yytext_ptr) + YY_MORE_ADJ;
+
+ if ( yy_next_state )
+ {
+ /* Consume the NUL. */
+ yy_cp = ++(yy_c_buf_p);
+ yy_current_state = yy_next_state;
+ goto yy_match;
+ }
+
+ else
+ {
+/* %% [14.0] code to do back-up for compressed tables and set up yy_cp goes here */
+ yy_cp = (yy_c_buf_p);
+ goto yy_find_action;
+ }
+ }
+
+ else switch ( yy_get_next_buffer( ) )
+ {
+ case EOB_ACT_END_OF_FILE:
+ {
+ (yy_did_buffer_switch_on_eof) = 0;
+
+ if ( yywrap( ) )
+ {
+ /* Note: because we've taken care in
+ * yy_get_next_buffer() to have set up
+ * yytext, we can now set up
+ * yy_c_buf_p so that if some total
+ * hoser (like flex itself) wants to
+ * call the scanner after we return the
+ * YY_NULL, it'll still work - another
+ * YY_NULL will get returned.
+ */
+ (yy_c_buf_p) = (yytext_ptr) + YY_MORE_ADJ;
+
+ yy_act = YY_STATE_EOF(YY_START);
+ goto do_action;
+ }
+
+ else
+ {
+ if ( ! (yy_did_buffer_switch_on_eof) )
+ YY_NEW_FILE;
+ }
+ break;
+ }
+
+ case EOB_ACT_CONTINUE_SCAN:
+ (yy_c_buf_p) =
+ (yytext_ptr) + yy_amount_of_matched_text;
+
+ yy_current_state = yy_get_previous_state( );
+
+ yy_cp = (yy_c_buf_p);
+ yy_bp = (yytext_ptr) + YY_MORE_ADJ;
+ goto yy_match;
+
+ case EOB_ACT_LAST_MATCH:
+ (yy_c_buf_p) =
+ &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)];
+
+ yy_current_state = yy_get_previous_state( );
+
+ yy_cp = (yy_c_buf_p);
+ yy_bp = (yytext_ptr) + YY_MORE_ADJ;
+ goto yy_find_action;
+ }
+ break;
+ }
+
+ default:
+ YY_FATAL_ERROR(
+ "fatal flex scanner internal error--no action found" );
+ } /* end of action switch */
+ } /* end of scanning one token */
+} /* end of yylex */
+/* %ok-for-header */
+
+/* %if-c++-only */
+/* %not-for-header */
+
+/* %ok-for-header */
+
+/* %endif */
+
+/* yy_get_next_buffer - try to read in a new buffer
+ *
+ * Returns a code representing an action:
+ * EOB_ACT_LAST_MATCH -
+ * EOB_ACT_CONTINUE_SCAN - continue scanning from current position
+ * EOB_ACT_END_OF_FILE - end of file
+ */
+/* %if-c-only */
+static int yy_get_next_buffer (void)
+/* %endif */
+/* %if-c++-only */
+/* %endif */
+{
+ register char *dest = YY_CURRENT_BUFFER_LVALUE->yy_ch_buf;
+ register char *source = (yytext_ptr);
+ register int number_to_move, i;
+ int ret_val;
+
+ if ( (yy_c_buf_p) > &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] )
+ YY_FATAL_ERROR(
+ "fatal flex scanner internal error--end of buffer missed" );
+
+ if ( YY_CURRENT_BUFFER_LVALUE->yy_fill_buffer == 0 )
+ { /* Don't try to fill the buffer, so this is an EOF. */
+ if ( (yy_c_buf_p) - (yytext_ptr) - YY_MORE_ADJ == 1 )
+ {
+ /* We matched a single character, the EOB, so
+ * treat this as a final EOF.
+ */
+ return EOB_ACT_END_OF_FILE;
+ }
+
+ else
+ {
+ /* We matched some text prior to the EOB, first
+ * process it.
+ */
+ return EOB_ACT_LAST_MATCH;
+ }
+ }
+
+ /* Try to read more data. */
+
+ /* First move last chars to start of buffer. */
+ number_to_move = (int) ((yy_c_buf_p) - (yytext_ptr)) - 1;
+
+ for ( i = 0; i < number_to_move; ++i )
+ *(dest++) = *(source++);
+
+ if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_EOF_PENDING )
+ /* don't do the read, it's not guaranteed to return an EOF,
+ * just force an EOF
+ */
+ YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars) = 0;
+
+ else
+ {
+ int num_to_read =
+ YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1;
+
+ while ( num_to_read <= 0 )
+ { /* Not enough room in the buffer - grow it. */
+
+ /* just a shorter name for the current buffer */
+ YY_BUFFER_STATE b = YY_CURRENT_BUFFER;
+
+ int yy_c_buf_p_offset =
+ (int) ((yy_c_buf_p) - b->yy_ch_buf);
+
+ if ( b->yy_is_our_buffer )
+ {
+ int new_size = b->yy_buf_size * 2;
+
+ if ( new_size <= 0 )
+ b->yy_buf_size += b->yy_buf_size / 8;
+ else
+ b->yy_buf_size *= 2;
+
+ b->yy_ch_buf = (char *)
+ /* Include room in for 2 EOB chars. */
+ yyrealloc((void *) b->yy_ch_buf,b->yy_buf_size + 2 );
+ }
+ else
+ /* Can't grow it, we don't own it. */
+ b->yy_ch_buf = 0;
+
+ if ( ! b->yy_ch_buf )
+ YY_FATAL_ERROR(
+ "fatal error - scanner input buffer overflow" );
+
+ (yy_c_buf_p) = &b->yy_ch_buf[yy_c_buf_p_offset];
+
+ num_to_read = YY_CURRENT_BUFFER_LVALUE->yy_buf_size -
+ number_to_move - 1;
+
+ }
+
+ if ( num_to_read > YY_READ_BUF_SIZE )
+ num_to_read = YY_READ_BUF_SIZE;
+
+ /* Read in more data. */
+ YY_INPUT( (&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]),
+ (yy_n_chars), (size_t) num_to_read );
+
+ YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars);
+ }
+
+ if ( (yy_n_chars) == 0 )
+ {
+ if ( number_to_move == YY_MORE_ADJ )
+ {
+ ret_val = EOB_ACT_END_OF_FILE;
+ yyrestart(yyin );
+ }
+
+ else
+ {
+ ret_val = EOB_ACT_LAST_MATCH;
+ YY_CURRENT_BUFFER_LVALUE->yy_buffer_status =
+ YY_BUFFER_EOF_PENDING;
+ }
+ }
+
+ else
+ ret_val = EOB_ACT_CONTINUE_SCAN;
+
+ if ((yy_size_t) ((yy_n_chars) + number_to_move) > YY_CURRENT_BUFFER_LVALUE->yy_buf_size) {
+ /* Extend the array by 50%, plus the number we really need. */
+ yy_size_t new_size = (yy_n_chars) + number_to_move + ((yy_n_chars) >> 1);
+ YY_CURRENT_BUFFER_LVALUE->yy_ch_buf = (char *) yyrealloc((void *) YY_CURRENT_BUFFER_LVALUE->yy_ch_buf,new_size );
+ if ( ! YY_CURRENT_BUFFER_LVALUE->yy_ch_buf )
+ YY_FATAL_ERROR( "out of dynamic memory in yy_get_next_buffer()" );
+ }
+
+ (yy_n_chars) += number_to_move;
+ YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] = YY_END_OF_BUFFER_CHAR;
+ YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] = YY_END_OF_BUFFER_CHAR;
+
+ (yytext_ptr) = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[0];
+
+ return ret_val;
+}
+
+/* yy_get_previous_state - get the state just before the EOB char was reached */
+
+/* %if-c-only */
+/* %not-for-header */
+
+ static yy_state_type yy_get_previous_state (void)
+/* %endif */
+/* %if-c++-only */
+/* %endif */
+{
+ register yy_state_type yy_current_state;
+ register char *yy_cp;
+
+/* %% [15.0] code to get the start state into yy_current_state goes here */
+ yy_current_state = (yy_start);
+
+ for ( yy_cp = (yytext_ptr) + YY_MORE_ADJ; yy_cp < (yy_c_buf_p); ++yy_cp )
+ {
+/* %% [16.0] code to find the next state goes here */
+ register YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1);
+ if ( yy_accept[yy_current_state] )
+ {
+ (yy_last_accepting_state) = yy_current_state;
+ (yy_last_accepting_cpos) = yy_cp;
+ }
+ while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
+ {
+ yy_current_state = (int) yy_def[yy_current_state];
+ if ( yy_current_state >= 335 )
+ yy_c = yy_meta[(unsigned int) yy_c];
+ }
+ yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
+ }
+
+ return yy_current_state;
+}
+
+/* yy_try_NUL_trans - try to make a transition on the NUL character
+ *
+ * synopsis
+ * next_state = yy_try_NUL_trans( current_state );
+ */
+/* %if-c-only */
+ static yy_state_type yy_try_NUL_trans (yy_state_type yy_current_state )
+/* %endif */
+/* %if-c++-only */
+/* %endif */
+{
+ register int yy_is_jam;
+ /* %% [17.0] code to find the next state, and perhaps do backing up, goes here */
+ register char *yy_cp = (yy_c_buf_p);
+
+ register YY_CHAR yy_c = 1;
+ if ( yy_accept[yy_current_state] )
+ {
+ (yy_last_accepting_state) = yy_current_state;
+ (yy_last_accepting_cpos) = yy_cp;
+ }
+ while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
+ {
+ yy_current_state = (int) yy_def[yy_current_state];
+ if ( yy_current_state >= 335 )
+ yy_c = yy_meta[(unsigned int) yy_c];
+ }
+ yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
+ yy_is_jam = (yy_current_state == 334);
+
+ return yy_is_jam ? 0 : yy_current_state;
+}
+
+/* %if-c-only */
+
+ static void yyunput (int c, register char * yy_bp )
+/* %endif */
+/* %if-c++-only */
+/* %endif */
+{
+ register char *yy_cp;
+
+ yy_cp = (yy_c_buf_p);
+
+ /* undo effects of setting up yytext */
+ *yy_cp = (yy_hold_char);
+
+ if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 )
+ { /* need to shift things up to make room */
+ /* +2 for EOB chars. */
+ register int number_to_move = (yy_n_chars) + 2;
+ register char *dest = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[
+ YY_CURRENT_BUFFER_LVALUE->yy_buf_size + 2];
+ register char *source =
+ &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move];
+
+ while ( source > YY_CURRENT_BUFFER_LVALUE->yy_ch_buf )
+ *--dest = *--source;
+
+ yy_cp += (int) (dest - source);
+ yy_bp += (int) (dest - source);
+ YY_CURRENT_BUFFER_LVALUE->yy_n_chars =
+ (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_buf_size;
+
+ if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 )
+ YY_FATAL_ERROR( "flex scanner push-back overflow" );
+ }
+
+ *--yy_cp = (char) c;
+
+/* %% [18.0] update yylineno here */
+
+ (yytext_ptr) = yy_bp;
+ (yy_hold_char) = *yy_cp;
+ (yy_c_buf_p) = yy_cp;
+}
+/* %if-c-only */
+
+/* %endif */
+
+/* %if-c-only */
+#ifndef YY_NO_INPUT
+#ifdef __cplusplus
+ static int yyinput (void)
+#else
+ static int input (void)
+#endif
+
+/* %endif */
+/* %if-c++-only */
+/* %endif */
+{
+ int c;
+
+ *(yy_c_buf_p) = (yy_hold_char);
+
+ if ( *(yy_c_buf_p) == YY_END_OF_BUFFER_CHAR )
+ {
+ /* yy_c_buf_p now points to the character we want to return.
+ * If this occurs *before* the EOB characters, then it's a
+ * valid NUL; if not, then we've hit the end of the buffer.
+ */
+ if ( (yy_c_buf_p) < &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] )
+ /* This was really a NUL. */
+ *(yy_c_buf_p) = '\0';
+
+ else
+ { /* need more input */
+ int offset = (yy_c_buf_p) - (yytext_ptr);
+ ++(yy_c_buf_p);
+
+ switch ( yy_get_next_buffer( ) )
+ {
+ case EOB_ACT_LAST_MATCH:
+ /* This happens because yy_g_n_b()
+ * sees that we've accumulated a
+ * token and flags that we need to
+ * try matching the token before
+ * proceeding. But for input(),
+ * there's no matching to consider.
+ * So convert the EOB_ACT_LAST_MATCH
+ * to EOB_ACT_END_OF_FILE.
+ */
+
+ /* Reset buffer status. */
+ yyrestart(yyin );
+
+ /*FALLTHROUGH*/
+
+ case EOB_ACT_END_OF_FILE:
+ {
+ if ( yywrap( ) )
+ return EOF;
+
+ if ( ! (yy_did_buffer_switch_on_eof) )
+ YY_NEW_FILE;
+#ifdef __cplusplus
+ return yyinput();
+#else
+ return input();
+#endif
+ }
+
+ case EOB_ACT_CONTINUE_SCAN:
+ (yy_c_buf_p) = (yytext_ptr) + offset;
+ break;
+ }
+ }
+ }
+
+ c = *(unsigned char *) (yy_c_buf_p); /* cast for 8-bit char's */
+ *(yy_c_buf_p) = '\0'; /* preserve yytext */
+ (yy_hold_char) = *++(yy_c_buf_p);
+
+/* %% [19.0] update BOL and yylineno */
+
+ return c;
+}
+/* %if-c-only */
+#endif /* ifndef YY_NO_INPUT */
+/* %endif */
+
+/** Immediately switch to a different input stream.
+ * @param input_file A readable stream.
+ *
+ * @note This function does not reset the start condition to @c INITIAL .
+ */
+/* %if-c-only */
+ void yyrestart (FILE * input_file )
+/* %endif */
+/* %if-c++-only */
+/* %endif */
+{
+
+ if ( ! YY_CURRENT_BUFFER ){
+ yyensure_buffer_stack ();
+ YY_CURRENT_BUFFER_LVALUE =
+ yy_create_buffer(yyin,YY_BUF_SIZE );
+ }
+
+ yy_init_buffer(YY_CURRENT_BUFFER,input_file );
+ yy_load_buffer_state( );
+}
+
+/** Switch to a different input buffer.
+ * @param new_buffer The new input buffer.
+ *
+ */
+/* %if-c-only */
+ void yy_switch_to_buffer (YY_BUFFER_STATE new_buffer )
+/* %endif */
+/* %if-c++-only */
+/* %endif */
+{
+
+ /* TODO. We should be able to replace this entire function body
+ * with
+ * yypop_buffer_state();
+ * yypush_buffer_state(new_buffer);
+ */
+ yyensure_buffer_stack ();
+ if ( YY_CURRENT_BUFFER == new_buffer )
+ return;
+
+ if ( YY_CURRENT_BUFFER )
+ {
+ /* Flush out information for old buffer. */
+ *(yy_c_buf_p) = (yy_hold_char);
+ YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p);
+ YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars);
+ }
+
+ YY_CURRENT_BUFFER_LVALUE = new_buffer;
+ yy_load_buffer_state( );
+
+ /* We don't actually know whether we did this switch during
+ * EOF (yywrap()) processing, but the only time this flag
+ * is looked at is after yywrap() is called, so it's safe
+ * to go ahead and always set it.
+ */
+ (yy_did_buffer_switch_on_eof) = 1;
+}
+
+/* %if-c-only */
+static void yy_load_buffer_state (void)
+/* %endif */
+/* %if-c++-only */
+/* %endif */
+{
+ (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars;
+ (yytext_ptr) = (yy_c_buf_p) = YY_CURRENT_BUFFER_LVALUE->yy_buf_pos;
+ yyin = YY_CURRENT_BUFFER_LVALUE->yy_input_file;
+ (yy_hold_char) = *(yy_c_buf_p);
+}
+
+/** Allocate and initialize an input buffer state.
+ * @param file A readable stream.
+ * @param size The character buffer size in bytes. When in doubt, use @c YY_BUF_SIZE.
+ *
+ * @return the allocated buffer state.
+ */
+/* %if-c-only */
+ YY_BUFFER_STATE yy_create_buffer (FILE * file, int size )
+/* %endif */
+/* %if-c++-only */
+/* %endif */
+{
+ YY_BUFFER_STATE b;
+
+ b = (YY_BUFFER_STATE) yyalloc(sizeof( struct yy_buffer_state ) );
+ if ( ! b )
+ YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" );
+
+ b->yy_buf_size = size;
+
+ /* yy_ch_buf has to be 2 characters longer than the size given because
+ * we need to put in 2 end-of-buffer characters.
+ */
+ b->yy_ch_buf = (char *) yyalloc(b->yy_buf_size + 2 );
+ if ( ! b->yy_ch_buf )
+ YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" );
+
+ b->yy_is_our_buffer = 1;
+
+ yy_init_buffer(b,file );
+
+ return b;
+}
+
+/** Destroy the buffer.
+ * @param b a buffer created with yy_create_buffer()
+ *
+ */
+/* %if-c-only */
+ void yy_delete_buffer (YY_BUFFER_STATE b )
+/* %endif */
+/* %if-c++-only */
+/* %endif */
+{
+
+ if ( ! b )
+ return;
+
+ if ( b == YY_CURRENT_BUFFER ) /* Not sure if we should pop here. */
+ YY_CURRENT_BUFFER_LVALUE = (YY_BUFFER_STATE) 0;
+
+ if ( b->yy_is_our_buffer )
+ yyfree((void *) b->yy_ch_buf );
+
+ yyfree((void *) b );
+}
+
+/* %if-c-only */
+
+#ifndef __cplusplus
+extern int isatty (int );
+#endif /* __cplusplus */
+
+/* %endif */
+
+/* %if-c++-only */
+/* %endif */
+
+/* Initializes or reinitializes a buffer.
+ * This function is sometimes called more than once on the same buffer,
+ * such as during a yyrestart() or at EOF.
+ */
+/* %if-c-only */
+ static void yy_init_buffer (YY_BUFFER_STATE b, FILE * file )
+/* %endif */
+/* %if-c++-only */
+/* %endif */
+
+{
+ int oerrno = errno;
+
+ yy_flush_buffer(b );
+
+ b->yy_input_file = file;
+ b->yy_fill_buffer = 1;
+
+ /* If b is the current buffer, then yy_init_buffer was _probably_
+ * called from yyrestart() or through yy_get_next_buffer.
+ * In that case, we don't want to reset the lineno or column.
+ */
+ if (b != YY_CURRENT_BUFFER){
+ b->yy_bs_lineno = 1;
+ b->yy_bs_column = 0;
+ }
+
+/* %if-c-only */
+
+ b->yy_is_interactive = file ? (isatty( fileno(file) ) > 0) : 0;
+
+/* %endif */
+/* %if-c++-only */
+/* %endif */
+ errno = oerrno;
+}
+
+/** Discard all buffered characters. On the next scan, YY_INPUT will be called.
+ * @param b the buffer state to be flushed, usually @c YY_CURRENT_BUFFER.
+ *
+ */
+/* %if-c-only */
+ void yy_flush_buffer (YY_BUFFER_STATE b )
+/* %endif */
+/* %if-c++-only */
+/* %endif */
+{
+ if ( ! b )
+ return;
+
+ b->yy_n_chars = 0;
+
+ /* We always need two end-of-buffer characters. The first causes
+ * a transition to the end-of-buffer state. The second causes
+ * a jam in that state.
+ */
+ b->yy_ch_buf[0] = YY_END_OF_BUFFER_CHAR;
+ b->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR;
+
+ b->yy_buf_pos = &b->yy_ch_buf[0];
+
+ b->yy_at_bol = 1;
+ b->yy_buffer_status = YY_BUFFER_NEW;
+
+ if ( b == YY_CURRENT_BUFFER )
+ yy_load_buffer_state( );
+}
+
+/* %if-c-or-c++ */
+/** Pushes the new state onto the stack. The new state becomes
+ * the current state. This function will allocate the stack
+ * if necessary.
+ * @param new_buffer The new state.
+ *
+ */
+/* %if-c-only */
+void yypush_buffer_state (YY_BUFFER_STATE new_buffer )
+/* %endif */
+/* %if-c++-only */
+/* %endif */
+{
+ if (new_buffer == NULL)
+ return;
+
+ yyensure_buffer_stack();
+
+ /* This block is copied from yy_switch_to_buffer. */
+ if ( YY_CURRENT_BUFFER )
+ {
+ /* Flush out information for old buffer. */
+ *(yy_c_buf_p) = (yy_hold_char);
+ YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p);
+ YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars);
+ }
+
+ /* Only push if top exists. Otherwise, replace top. */
+ if (YY_CURRENT_BUFFER)
+ (yy_buffer_stack_top)++;
+ YY_CURRENT_BUFFER_LVALUE = new_buffer;
+
+ /* copied from yy_switch_to_buffer. */
+ yy_load_buffer_state( );
+ (yy_did_buffer_switch_on_eof) = 1;
+}
+/* %endif */
+
+/* %if-c-or-c++ */
+/** Removes and deletes the top of the stack, if present.
+ * The next element becomes the new top.
+ *
+ */
+/* %if-c-only */
+void yypop_buffer_state (void)
+/* %endif */
+/* %if-c++-only */
+/* %endif */
+{
+ if (!YY_CURRENT_BUFFER)
+ return;
+
+ yy_delete_buffer(YY_CURRENT_BUFFER );
+ YY_CURRENT_BUFFER_LVALUE = NULL;
+ if ((yy_buffer_stack_top) > 0)
+ --(yy_buffer_stack_top);
+
+ if (YY_CURRENT_BUFFER) {
+ yy_load_buffer_state( );
+ (yy_did_buffer_switch_on_eof) = 1;
+ }
+}
+/* %endif */
+
+/* %if-c-or-c++ */
+/* Allocates the stack if it does not exist.
+ * Guarantees space for at least one push.
+ */
+/* %if-c-only */
+static void yyensure_buffer_stack (void)
+/* %endif */
+/* %if-c++-only */
+/* %endif */
+{
+ int num_to_alloc;
+
+ if (!(yy_buffer_stack)) {
+
+ /* First allocation is just for 2 elements, since we don't know if this
+ * scanner will even need a stack. We use 2 instead of 1 to avoid an
+ * immediate realloc on the next call.
+ */
+ num_to_alloc = 1;
+ (yy_buffer_stack) = (struct yy_buffer_state**)yyalloc
+ (num_to_alloc * sizeof(struct yy_buffer_state*)
+ );
+ if ( ! (yy_buffer_stack) )
+ YY_FATAL_ERROR( "out of dynamic memory in yyensure_buffer_stack()" );
+
+ memset((yy_buffer_stack), 0, num_to_alloc * sizeof(struct yy_buffer_state*));
+
+ (yy_buffer_stack_max) = num_to_alloc;
+ (yy_buffer_stack_top) = 0;
+ return;
+ }
+
+ if ((yy_buffer_stack_top) >= ((yy_buffer_stack_max)) - 1){
+
+ /* Increase the buffer to prepare for a possible push. */
+ int grow_size = 8 /* arbitrary grow size */;
+
+ num_to_alloc = (yy_buffer_stack_max) + grow_size;
+ (yy_buffer_stack) = (struct yy_buffer_state**)yyrealloc
+ ((yy_buffer_stack),
+ num_to_alloc * sizeof(struct yy_buffer_state*)
+ );
+ if ( ! (yy_buffer_stack) )
+ YY_FATAL_ERROR( "out of dynamic memory in yyensure_buffer_stack()" );
+
+ /* zero only the new slots.*/
+ memset((yy_buffer_stack) + (yy_buffer_stack_max), 0, grow_size * sizeof(struct yy_buffer_state*));
+ (yy_buffer_stack_max) = num_to_alloc;
+ }
+}
+/* %endif */
+
+/* %if-c-only */
+/** Setup the input buffer state to scan directly from a user-specified character buffer.
+ * @param base the character buffer
+ * @param size the size in bytes of the character buffer
+ *
+ * @return the newly allocated buffer state object.
+ */
+YY_BUFFER_STATE yy_scan_buffer (char * base, yy_size_t size )
+{
+ YY_BUFFER_STATE b;
+
+ if ( size < 2 ||
+ base[size-2] != YY_END_OF_BUFFER_CHAR ||
+ base[size-1] != YY_END_OF_BUFFER_CHAR )
+ /* They forgot to leave room for the EOB's. */
+ return 0;
+
+ b = (YY_BUFFER_STATE) yyalloc(sizeof( struct yy_buffer_state ) );
+ if ( ! b )
+ YY_FATAL_ERROR( "out of dynamic memory in yy_scan_buffer()" );
+
+ b->yy_buf_size = size - 2; /* "- 2" to take care of EOB's */
+ b->yy_buf_pos = b->yy_ch_buf = base;
+ b->yy_is_our_buffer = 0;
+ b->yy_input_file = 0;
+ b->yy_n_chars = b->yy_buf_size;
+ b->yy_is_interactive = 0;
+ b->yy_at_bol = 1;
+ b->yy_fill_buffer = 0;
+ b->yy_buffer_status = YY_BUFFER_NEW;
+
+ yy_switch_to_buffer(b );
+
+ return b;
+}
+/* %endif */
+
+/* %if-c-only */
+/** Setup the input buffer state to scan a string. The next call to yylex() will
+ * scan from a @e copy of @a str.
+ * @param yystr a NUL-terminated string to scan
+ *
+ * @return the newly allocated buffer state object.
+ * @note If you want to scan bytes that may contain NUL values, then use
+ * yy_scan_bytes() instead.
+ */
+YY_BUFFER_STATE yy_scan_string (yyconst char * yystr )
+{
+
+ return yy_scan_bytes(yystr,strlen(yystr) );
+}
+/* %endif */
+
+/* %if-c-only */
+/** Setup the input buffer state to scan the given bytes. The next call to yylex() will
+ * scan from a @e copy of @a bytes.
+ * @param bytes the byte buffer to scan
+ * @param len the number of bytes in the buffer pointed to by @a bytes.
+ *
+ * @return the newly allocated buffer state object.
+ */
+YY_BUFFER_STATE yy_scan_bytes (yyconst char * yybytes, int _yybytes_len )
+{
+ YY_BUFFER_STATE b;
+ char *buf;
+ yy_size_t n;
+ int i;
+
+ /* Get memory for full buffer, including space for trailing EOB's. */
+ n = _yybytes_len + 2;
+ buf = (char *) yyalloc(n );
+ if ( ! buf )
+ YY_FATAL_ERROR( "out of dynamic memory in yy_scan_bytes()" );
+
+ for ( i = 0; i < _yybytes_len; ++i )
+ buf[i] = yybytes[i];
+
+ buf[_yybytes_len] = buf[_yybytes_len+1] = YY_END_OF_BUFFER_CHAR;
+
+ b = yy_scan_buffer(buf,n );
+ if ( ! b )
+ YY_FATAL_ERROR( "bad buffer in yy_scan_bytes()" );
+
+ /* It's okay to grow etc. this buffer, and we should throw it
+ * away when we're done.
+ */
+ b->yy_is_our_buffer = 1;
+
+ return b;
+}
+/* %endif */
+
+#ifndef YY_EXIT_FAILURE
+#define YY_EXIT_FAILURE 2
+#endif
+
+/* %if-c-only */
+static void yy_fatal_error (yyconst char* msg )
+{
+ (void) fprintf( stderr, "%s\n", msg );
+ exit( YY_EXIT_FAILURE );
+}
+/* %endif */
+/* %if-c++-only */
+/* %endif */
+
+/* Redefine yyless() so it works in section 3 code. */
+
+#undef yyless
+#define yyless(n) \
+ do \
+ { \
+ /* Undo effects of setting up yytext. */ \
+ int yyless_macro_arg = (n); \
+ YY_LESS_LINENO(yyless_macro_arg);\
+ yytext[yyleng] = (yy_hold_char); \
+ (yy_c_buf_p) = yytext + yyless_macro_arg; \
+ (yy_hold_char) = *(yy_c_buf_p); \
+ *(yy_c_buf_p) = '\0'; \
+ yyleng = yyless_macro_arg; \
+ } \
+ while ( 0 )
+
+/* Accessor methods (get/set functions) to struct members. */
+
+/* %if-c-only */
+/* %if-reentrant */
+/* %endif */
+
+/** Get the current line number.
+ *
+ */
+int yyget_lineno (void)
+{
+
+ return yylineno;
+}
+
+/** Get the input stream.
+ *
+ */
+FILE *yyget_in (void)
+{
+ return yyin;
+}
+
+/** Get the output stream.
+ *
+ */
+FILE *yyget_out (void)
+{
+ return yyout;
+}
+
+/** Get the length of the current token.
+ *
+ */
+int yyget_leng (void)
+{
+ return yyleng;
+}
+
+/** Get the current token.
+ *
+ */
+
+char *yyget_text (void)
+{
+ return yytext;
+}
+
+/* %if-reentrant */
+/* %endif */
+
+/** Set the current line number.
+ * @param line_number
+ *
+ */
+void yyset_lineno (int line_number )
+{
+
+ yylineno = line_number;
+}
+
+/** Set the input stream. This does not discard the current
+ * input buffer.
+ * @param in_str A readable stream.
+ *
+ * @see yy_switch_to_buffer
+ */
+void yyset_in (FILE * in_str )
+{
+ yyin = in_str ;
+}
+
+void yyset_out (FILE * out_str )
+{
+ yyout = out_str ;
+}
+
+int yyget_debug (void)
+{
+ return yy_flex_debug;
+}
+
+void yyset_debug (int bdebug )
+{
+ yy_flex_debug = bdebug ;
+}
+
+/* %endif */
+
+/* %if-reentrant */
+/* %if-bison-bridge */
+/* %endif */
+/* %endif if-c-only */
+
+/* %if-c-only */
+static int yy_init_globals (void)
+{
+ /* Initialization is the same as for the non-reentrant scanner.
+ * This function is called from yylex_destroy(), so don't allocate here.
+ */
+
+ (yy_buffer_stack) = 0;
+ (yy_buffer_stack_top) = 0;
+ (yy_buffer_stack_max) = 0;
+ (yy_c_buf_p) = (char *) 0;
+ (yy_init) = 0;
+ (yy_start) = 0;
+
+/* Defined in main.c */
+#ifdef YY_STDINIT
+ yyin = stdin;
+ yyout = stdout;
+#else
+ yyin = (FILE *) 0;
+ yyout = (FILE *) 0;
+#endif
+
+ /* For future reference: Set errno on error, since we are called by
+ * yylex_init()
+ */
+ return 0;
+}
+/* %endif */
+
+/* %if-c-only SNIP! this currently causes conflicts with the c++ scanner */
+/* yylex_destroy is for both reentrant and non-reentrant scanners. */
+int yylex_destroy (void)
+{
+
+ /* Pop the buffer stack, destroying each element. */
+ while(YY_CURRENT_BUFFER){
+ yy_delete_buffer(YY_CURRENT_BUFFER );
+ YY_CURRENT_BUFFER_LVALUE = NULL;
+ yypop_buffer_state();
+ }
+
+ /* Destroy the stack itself. */
+ yyfree((yy_buffer_stack) );
+ (yy_buffer_stack) = NULL;
+
+ /* Reset the globals. This is important in a non-reentrant scanner so the next time
+ * yylex() is called, initialization will occur. */
+ yy_init_globals( );
+
+/* %if-reentrant */
+/* %endif */
+ return 0;
+}
+/* %endif */
+
+/*
+ * Internal utility routines.
+ */
+
+#ifndef yytext_ptr
+static void yy_flex_strncpy (char* s1, yyconst char * s2, int n )
+{
+ register int i;
+ for ( i = 0; i < n; ++i )
+ s1[i] = s2[i];
+}
+#endif
+
+#ifdef YY_NEED_STRLEN
+static int yy_flex_strlen (yyconst char * s )
+{
+ register int n;
+ for ( n = 0; s[n]; ++n )
+ ;
+
+ return n;
+}
+#endif
+
+void *yyalloc (yy_size_t size )
+{
+ return (void *) malloc( size );
+}
+
+void *yyrealloc (void * ptr, yy_size_t size )
+{
+ /* The cast to (char *) in the following accommodates both
+ * implementations that use char* generic pointers, and those
+ * that use void* generic pointers. It works with the latter
+ * because both ANSI C and C++ allow castless assignment from
+ * any pointer type to void*, and deal with argument conversions
+ * as though doing an assignment.
+ */
+ return (void *) realloc( (char *) ptr, size );
+}
+
+void yyfree (void * ptr )
+{
+ free( (char *) ptr ); /* see yyrealloc() for (char *) cast */
+}
+
+/* %if-tables-serialization definitions */
+/* %define-yytables The name for this specific scanner's tables. */
+#define YYTABLES_NAME "yytables"
+/* %endif */
+
+/* %ok-for-header */
+
+#line 407 "camp.l"
diff --git a/Build/source/utils/asymptote/lexical.h b/Build/source/utils/asymptote/lexical.h
new file mode 100644
index 00000000000..fc3879961d6
--- /dev/null
+++ b/Build/source/utils/asymptote/lexical.h
@@ -0,0 +1,23 @@
+#ifndef __lexical_h__
+#define __lexical_h__ 1
+
+#include <sstream>
+
+#include "common.h"
+
+namespace lexical {
+
+class bad_cast {};
+
+template <typename T>
+T cast(const string& s, bool tolerant=false)
+{
+ istringstream is(s);
+ T value;
+ if(is && is >> value && ((is >> std::ws).eof() || tolerant)) return value;
+ throw bad_cast();
+}
+
+}
+
+#endif
diff --git a/Build/source/utils/asymptote/locate.cc b/Build/source/utils/asymptote/locate.cc
new file mode 100644
index 00000000000..98e2ff79ff4
--- /dev/null
+++ b/Build/source/utils/asymptote/locate.cc
@@ -0,0 +1,102 @@
+/*****
+ * locate.cc
+ * Tom Prince 2005/03/24
+ *
+ * Locate files in search path.
+ *****/
+
+#include <unistd.h>
+
+#include "settings.h"
+#include "util.h"
+#include "locate.h"
+
+
+
+namespace settings {
+
+namespace fs {
+
+string extension(string name)
+{
+ size_t n = name.rfind(".");
+ if (n != string::npos)
+ return name.substr(n);
+ else
+ return string();
+}
+
+bool exists(string filename)
+{
+ return ::access(filename.c_str(), R_OK) == 0;
+}
+
+} // namespace fs
+
+
+file_list_t searchPath;
+
+// Returns list of possible filenames, accounting for extensions.
+file_list_t mungeFileName(string id)
+{
+ string ext = fs::extension(id);
+ file_list_t files;
+ if (ext == "."+settings::suffix) {
+ files.push_back(id);
+ files.push_back(id+"."+settings::suffix);
+ } else {
+ files.push_back(id+"."+settings::suffix);
+ files.push_back(id);
+ }
+ return files;
+}
+
+// Join a directory with the given filename, to give the path to the file. This
+// also avoids unsightly joins such as './file.asy' in favour of 'file.asy' and
+// 'dir//file.asy' in favour of 'dir/file.asy'
+string join(string dir, string file)
+{
+ return dir == "." ? file :
+ *dir.rbegin() == '/' ? dir + file :
+ dir + "/" + file;
+}
+
+// Find the appropriate file, first looking in the local directory, then the
+// directory given in settings, and finally the global system directory.
+string locateFile(string id)
+{
+ if(id.empty()) return "";
+ file_list_t filenames = mungeFileName(id);
+ for (file_list_t::iterator leaf = filenames.begin();
+ leaf != filenames.end();
+ ++leaf) {
+#ifdef __CYGWIN__
+ size_t p;
+ while ((p=leaf->find('\\')) < string::npos)
+ (*leaf)[p]='/';
+ if ((p=leaf->find(':')) < string::npos && p > 0) {
+ (*leaf)[p]='/';
+ leaf->insert(0,"/cygdrive/");
+ }
+#endif
+
+ if ((*leaf)[0] == '/') {
+ string file = *leaf;
+ if (fs::exists(file))
+ return file;
+ } else {
+ for (file_list_t::iterator dir = searchPath.begin();
+ dir != searchPath.end();
+ ++dir) {
+ string file = join(*dir,*leaf);
+ if (fs::exists(file))
+ return file;
+ }
+ }
+ }
+ return string();
+}
+
+} // namespace settings
+
+
diff --git a/Build/source/utils/asymptote/locate.h b/Build/source/utils/asymptote/locate.h
new file mode 100644
index 00000000000..915a5e9d593
--- /dev/null
+++ b/Build/source/utils/asymptote/locate.h
@@ -0,0 +1,31 @@
+/*****
+ * locate.h
+ * Tom Prince 2005/03/24
+ *
+ * Locate files in search path.
+ *****/
+
+#ifndef LOCATE_H
+#define LOCATE_H
+
+#include "common.h"
+
+namespace settings {
+
+typedef mem::list<string> file_list_t;
+extern file_list_t searchPath;
+
+// Find the appropriate file, first looking in the local directory, then the
+// directory given in settings, and finally the global system directory.
+string locateFile(string id);
+
+namespace fs {
+
+// Check to see if a file of given name exists.
+bool exists(string filename);
+
+}
+
+} // namespace settings
+
+#endif // LOCATE_H
diff --git a/Build/source/utils/asymptote/main.cc b/Build/source/utils/asymptote/main.cc
new file mode 100644
index 00000000000..f5ea21128e5
--- /dev/null
+++ b/Build/source/utils/asymptote/main.cc
@@ -0,0 +1,196 @@
+/************
+*
+* This file is part of the vector graphics language Asymptote
+* Copyright (C) 2004 Andy Hammerlindl, John C. Bowman, Tom Prince
+* http://asymptote.sourceforge.net
+*
+* This program 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 3 of the License, or
+* (at your option) any later version.
+*
+* This program 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 program. If not, see <http://www.gnu.org/licenses/>.
+*
+*************/
+
+#include <iostream>
+#include <csignal>
+#include <cstdlib>
+#include <cerrno>
+#include <sys/wait.h>
+#include <sys/types.h>
+
+#include "common.h"
+
+#ifdef HAVE_LIBSIGSEGV
+#include <sigsegv.h>
+#endif
+
+#include "errormsg.h"
+#include "fpu.h"
+#include "settings.h"
+#include "locate.h"
+#include "interact.h"
+#include "process.h"
+
+#include "stack.h"
+
+using namespace settings;
+
+errorstream em;
+using interact::interactive;
+
+namespace run {
+void purge();
+}
+
+#ifdef HAVE_LIBSIGSEGV
+void stackoverflow_handler (int, stackoverflow_context_t)
+{
+ em.runtime(vm::getPos());
+ cerr << "Stack overflow" << endl;
+ abort();
+}
+
+int sigsegv_handler (void *, int emergency)
+{
+ if(!emergency) return 0; // Really a stack overflow
+ em.runtime(vm::getPos());
+ if(gl::glthread)
+ cerr << "Stack overflow or segmentation fault: rerun with -nothreads"
+ << endl;
+ else
+ cerr << "Segmentation fault" << endl;
+ abort();
+}
+#endif
+
+void setsignal(RETSIGTYPE (*handler)(int))
+{
+#ifdef HAVE_LIBSIGSEGV
+ char mystack[16384];
+ stackoverflow_install_handler(&stackoverflow_handler,
+ mystack,sizeof (mystack));
+ sigsegv_install_handler(&sigsegv_handler);
+#endif
+ signal(SIGBUS,handler);
+ signal(SIGFPE,handler);
+}
+
+void signalHandler(int)
+{
+ // Print the position and trust the shell to print an error message.
+ em.runtime(vm::getPos());
+
+ signal(SIGBUS,SIG_DFL);
+ signal(SIGFPE,SIG_DFL);
+}
+
+void interruptHandler(int)
+{
+ em.Interrupt(true);
+}
+
+// Run the config file.
+void doConfig(string file)
+{
+ bool autoplain=getSetting<bool>("autoplain");
+ bool listvariables=getSetting<bool>("listvariables");
+ if(autoplain) Setting("autoplain")=false; // Turn off for speed.
+ if(listvariables) Setting("listvariables")=false;
+
+ runFile(file);
+
+ if(autoplain) Setting("autoplain")=true;
+ if(listvariables) Setting("listvariables")=true;
+}
+
+struct Args
+{
+ int argc;
+ char **argv;
+ Args(int argc, char **argv) : argc(argc), argv(argv) {}
+};
+
+void *asymain(void *A)
+{
+ setsignal(signalHandler);
+
+ Args *args=(Args *) A;
+ fpu_trap(trap());
+
+ if(interactive) {
+ signal(SIGINT,interruptHandler);
+ processPrompt();
+ } else if (getSetting<bool>("listvariables") && numArgs()==0) {
+ try {
+ doUnrestrictedList();
+ } catch(handled_error) {
+ em.statusError();
+ }
+ } else {
+ int n=numArgs();
+ if(n == 0)
+ processFile("-");
+ else
+ for(int ind=0; ind < n; ind++) {
+ processFile(string(getArg(ind)),n > 1);
+ try {
+ if(ind < n-1)
+ setOptions(args->argc,args->argv);
+ } catch(handled_error) {
+ em.statusError();
+ }
+ }
+ }
+
+ if(getSetting<bool>("wait")) {
+ int status;
+ while(wait(&status) > 0);
+ }
+ exit(em.processStatus() || interact::interactive ? 0 : 1);
+}
+
+int main(int argc, char *argv[])
+{
+ setsignal(signalHandler);
+
+ try {
+ setOptions(argc,argv);
+ } catch(handled_error) {
+ em.statusError();
+ }
+
+ Args args(argc,argv);
+#ifdef HAVE_LIBGL
+ gl::glthread=getSetting<bool>("threads");
+#ifdef HAVE_LIBPTHREAD
+
+ if(gl::glthread) {
+ pthread_t thread;
+ try {
+ if(pthread_create(&thread,NULL,asymain,&args) == 0) {
+ gl::mainthread=pthread_self();
+ while(true) {
+ gl::endwait(gl::readySignal,gl::readyLock);
+ gl::endwait(gl::quitSignal,gl::quitLock);
+ gl::wait(gl::initSignal,gl::initLock);
+ camp::glrenderWrapper();
+ gl::initialize=true;
+ }
+ }
+ } catch(std::bad_alloc&) {
+ outOfMemory();
+ }
+ }
+#endif
+ gl::glthread=false;
+#endif
+ asymain(&args);
+}
diff --git a/Build/source/utils/asymptote/mathop.h b/Build/source/utils/asymptote/mathop.h
new file mode 100644
index 00000000000..97772d8e799
--- /dev/null
+++ b/Build/source/utils/asymptote/mathop.h
@@ -0,0 +1,319 @@
+/*****
+ * mathop.h
+ * Tom Prince 2005/3/18
+ *
+ * Defines some runtime functions used by the stack machine.
+ *
+ *****/
+
+#ifndef MATHOP_H
+#define MATHOP_H
+
+#include <sstream>
+
+#include "stack.h"
+#include "mod.h"
+#include "triple.h"
+
+namespace run {
+
+template <typename T>
+struct less {
+ bool operator() (T x, T y, size_t=0) {return x < y;}
+};
+
+template <typename T>
+struct lessequals {
+ bool operator() (T x, T y, size_t=0) {return x <= y;}
+};
+
+template <typename T>
+struct equals {
+ bool operator() (T x, T y, size_t=0) {return x == y;}
+};
+
+template <typename T>
+struct greaterequals {
+ bool operator() (T x, T y, size_t=0) {return x >= y;}
+};
+
+template <typename T>
+struct greater {
+ bool operator() (T x, T y, size_t=0) {return x > y;}
+};
+
+template <typename T>
+struct notequals {
+ bool operator() (T x, T y, size_t=0) {return x != y;}
+};
+
+template <typename T>
+struct And {
+ bool operator() (T x, T y, size_t=0) {return x && y;}
+};
+
+template <typename T>
+struct Or {
+ bool operator() (T x, T y, size_t=0) {return x || y;}
+};
+
+template <typename T>
+struct Xor {
+ bool operator() (T x, T y, size_t=0) {return x ^ y;}
+};
+
+template <typename T>
+struct plus {
+ T operator() (T x, T y, size_t=0) {return x+y;}
+};
+
+template <typename T>
+struct minus {
+ T operator() (T x, T y, size_t=0) {return x-y;}
+};
+
+template <typename T>
+struct times {
+ T operator() (T x, T y, size_t=0) {return x*y;}
+};
+
+template <>
+struct times<camp::triple> {
+ camp::triple operator() (double x, camp::triple y, size_t=0) {return x*y;}
+};
+
+template <typename T>
+struct timesR {
+ T operator () (T y, double x, size_t=0) {return x*y;}
+};
+
+extern void dividebyzero(size_t i=0);
+extern void integeroverflow(size_t i=0);
+
+template <typename T>
+struct divide {
+ T operator() (T x, T y, size_t i=0) {
+ if(y == 0) dividebyzero(i);
+ return x/y;
+ }
+};
+
+template <>
+struct divide<camp::triple> {
+ camp::triple operator() (camp::triple x, double y, size_t=0) {return x/y;}
+};
+
+inline bool validInt(double x) {
+ return x > Int_MIN-0.5 && x < Int_MAX+0.5;
+}
+
+inline void checkInt(double x, size_t i)
+{
+ if(validInt(x)) return;
+ integeroverflow(i);
+}
+
+inline Int Intcast(double x)
+{
+ if(validInt(x)) return (Int) x;
+ integeroverflow(0);
+ return 0;
+}
+
+template<>
+struct plus<Int> {
+ Int operator() (Int x, Int y, size_t i=0) {
+ if((y > 0 && x > Int_MAX-y) || (y < 0 && x < Int_MIN-y))
+ integeroverflow(i);
+ return x+y;
+ }
+};
+
+template<>
+struct minus<Int> {
+ Int operator() (Int x, Int y, size_t i=0) {
+ if((y < 0 && x > Int_MAX+y) || (y > 0 && x < Int_MIN+y))
+ integeroverflow(i);
+ return x-y;
+ }
+};
+
+template<>
+struct times<Int> {
+ Int operator() (Int x, Int y, size_t i=0) {
+ if(y == 0) return 0;
+ if(y < 0) {y=-y; x=-x;}
+ if(x > Int_MAX/y || x < Int_MIN/y)
+ integeroverflow(i);
+ return x*y;
+ }
+};
+
+template<>
+struct divide<Int> {
+ double operator() (Int x, Int y, size_t i=0) {
+ if(y == 0) dividebyzero(i);
+ return ((double) x)/(double) y;
+ }
+};
+
+template <class T>
+void Negate(vm::stack *s)
+{
+ T a=vm::pop<T>(s);
+ s->push(-a);
+}
+
+inline Int Negate(Int x, size_t i=0) {
+ if(x < -Int_MAX) integeroverflow(i);
+ return -x;
+}
+
+template<>
+inline void Negate<Int>(vm::stack *s)
+{
+ s->push(Negate(vm::pop<Int>(s)));
+}
+
+inline double pow(double x, double y)
+{
+#ifndef HAVE_POW
+ return exp(y*log(x));
+#else
+ return ::pow(x,y);
+#endif
+}
+
+template<class T>
+T pow(T x, Int y)
+{
+ if(y == 0) return 1.0;
+ if(x == 0.0 && y > 0) return 0.0;
+ if(y < 0) {y=-y; x=1/x;}
+
+ T r=1.0;
+ for(;;) {
+ if(y & 1) r *= x;
+ if((y >>= 1) == 0) return r;
+ x *= x;
+ }
+}
+
+template <typename T>
+struct power {
+ T operator() (T x, T y, size_t=0) {return pow(x,y);}
+};
+
+template <>
+struct power<Int> {
+ Int operator() (Int x, Int p, size_t i=0) {
+ if(p == 0) return 1;
+ Int sign=1;
+ if(x < 0) {
+ if(p % 2) sign=-1;
+ x=-x;
+ }
+ if(p > 0) {
+ if(x == 0) return 0;
+ Int r = 1;
+ for(;;) {
+ if(p & 1) {
+ if(r > Int_MAX/x) integeroverflow(i);
+ r *= x;
+ }
+ if((p >>= 1) == 0)
+ return sign*r;
+ if(x > Int_MAX/x) integeroverflow(i);
+ x *= x;
+ }
+ } else {
+ if(x == 1) return sign;
+ ostringstream buf;
+ if(i > 0) buf << "array element " << i << ": ";
+ buf << "Only 1 and -1 can be raised to negative exponents as integers.";
+ vm::error(buf);
+ return 0;
+ }
+ }
+};
+
+template <typename T>
+struct mod {
+ T operator() (T x, T y, size_t i=0) {
+ if(y == 0) dividebyzero(i);
+ return portableMod(x,y);
+ }
+};
+
+template <typename T>
+struct min {
+ T operator() (T x, T y, size_t=0) {return x < y ? x : y;}
+};
+
+template <typename T>
+struct max {
+ T operator() (T x, T y, size_t=0) {return x > y ? x : y;}
+};
+
+template<class T>
+inline T Min(T a, T b)
+{
+ return (a < b) ? a : b;
+}
+
+template<class T>
+inline T Max(T a, T b)
+{
+ return (a > b) ? a : b;
+}
+
+template <typename T>
+struct minbound {
+ camp::pair operator() (camp::pair z, camp::pair w) {
+ return camp::pair(Min(z.getx(),w.getx()),Min(z.gety(),w.gety()));
+ }
+ camp::triple operator() (camp::triple u, camp::triple v) {
+ return camp::triple(Min(u.getx(),v.getx()),Min(u.gety(),v.gety()),
+ Min(u.getz(),v.getz()));
+ }
+};
+
+template <typename T>
+struct maxbound {
+ camp::pair operator() (camp::pair z, camp::pair w) {
+ return camp::pair(Max(z.getx(),w.getx()),Max(z.gety(),w.gety()));
+ }
+ camp::triple operator() (camp::triple u, camp::triple v) {
+ return camp::triple(Max(u.getx(),v.getx()),Max(u.gety(),v.gety()),
+ Max(u.getz(),v.getz()));
+ }
+};
+
+template <double (*func)(double)>
+void realReal(vm::stack *s)
+{
+ double x=vm::pop<double>(s);
+ s->push(func(x));
+}
+
+template <class T, template <class S> class op>
+void binaryOp(vm::stack *s)
+{
+ T b=vm::pop<T>(s);
+ T a=vm::pop<T>(s);
+ s->push(op<T>()(a,b));
+}
+
+template <class T>
+void interp(vm::stack *s)
+{
+ double t=vm::pop<double>(s);
+ T b=vm::pop<T>(s);
+ T a=vm::pop<T>(s);
+ s->push((1-t)*a+t*b);
+}
+
+} // namespace run
+
+#endif //MATHOP_H
+
diff --git a/Build/source/utils/asymptote/memory.h b/Build/source/utils/asymptote/memory.h
new file mode 100644
index 00000000000..63c5291b130
--- /dev/null
+++ b/Build/source/utils/asymptote/memory.h
@@ -0,0 +1,177 @@
+/****
+ * memory.h
+ *
+ * Interface to the Boehm Garbage Collector.
+ *****/
+
+#ifndef MEMORY_H
+#define MEMORY_H
+
+#include <list>
+#include <vector>
+#include <stack>
+#include <map>
+#include <string>
+#include <sstream>
+
+#ifndef NOHASH
+#ifndef __GNUC_PREREQ
+#define __GNUC_PREREQ(maj, min) (0)
+# endif
+#if __GNUC_PREREQ(4,3)
+#include <tr1/unordered_map>
+#define EXT std::tr1
+#else
+#define EXT __gnu_cxx
+#include <ext/hash_map>
+#define unordered_map hash_map
+#define unordered_multimap hash_multimap
+#endif
+#endif
+
+#ifdef __DECCXX_LIBCXX_RH70
+#define CONST
+#else
+#define CONST const
+#endif
+
+#ifdef USEGC
+
+#define GC_THREADS
+#include <gc.h>
+
+#ifdef GC_DEBUG
+extern "C" {
+#include <gc_backptr.h>
+}
+#endif
+
+inline void *asy_malloc(size_t n)
+{
+#ifdef GC_DEBUG
+ if(void *mem=GC_debug_malloc_ignore_off_page(n, GC_EXTRAS))
+#else
+ if(void *mem=GC_malloc_ignore_off_page(n))
+#endif
+ return mem;
+ throw std::bad_alloc();
+}
+
+inline void *asy_malloc_atomic(size_t n)
+{
+#ifdef GC_DEBUG
+ if(void *mem=GC_debug_malloc_atomic_ignore_off_page(n, GC_EXTRAS))
+#else
+ if(void *mem=GC_malloc_atomic_ignore_off_page(n))
+#endif
+ return mem;
+ throw std::bad_alloc();
+}
+
+#undef GC_MALLOC
+#undef GC_MALLOC_ATOMIC
+
+#define GC_MALLOC(sz) asy_malloc(sz)
+#define GC_MALLOC_ATOMIC(sz) asy_malloc_atomic(sz)
+
+#include <gc_allocator.h>
+#include <gc_cpp.h>
+
+#else // USEGC
+
+using std::allocator;
+#define gc_allocator allocator
+
+class gc {};
+class gc_cleanup {};
+
+enum GCPlacement {UseGC, NoGC, PointerFreeGC};
+
+inline void* operator new(size_t size, GCPlacement) {
+ return operator new(size);
+}
+
+inline void* operator new[](size_t size, GCPlacement) {
+ return operator new(size);
+}
+
+template<class T>
+struct GC_type_traits {};
+
+#define GC_DECLARE_PTRFREE(T) \
+ template<> struct GC_type_traits<T> {}
+
+#endif // USEGC
+
+namespace mem {
+
+#define GC_CONTAINER(KIND) \
+ template <typename T> \
+ struct KIND : public std::KIND<T, gc_allocator<T> >, public gc { \
+ KIND() : std::KIND<T, gc_allocator<T> >() {} \
+ KIND(size_t n) : std::KIND<T, gc_allocator<T> >(n) {} \
+ KIND(size_t n, const T& t) : std::KIND<T, gc_allocator<T> >(n,t) {} \
+ }
+
+GC_CONTAINER(list);
+GC_CONTAINER(vector);
+
+template <typename T, typename Container = vector<T> >
+struct stack : public std::stack<T, Container>, public gc {
+};
+
+#undef GC_CONTAINER
+
+#define GC_CONTAINER(KIND) \
+ template <typename Key, typename T, typename Compare = std::less<Key> > \
+ struct KIND : public \
+ std::KIND<Key,T,Compare,gc_allocator<std::pair<Key,T> > >, public gc { \
+ KIND() : std::KIND<Key,T,Compare,gc_allocator<std::pair<Key,T> > > () {} \
+ }
+
+GC_CONTAINER(map);
+GC_CONTAINER(multimap);
+
+#undef GC_CONTAINER
+
+#ifndef NOHASH
+#define GC_CONTAINER(KIND) \
+ template <typename Key, typename T, \
+ typename Hash = EXT::hash<Key>, \
+ typename Eq = std::equal_to<Key> > \
+ struct KIND : public \
+ EXT::KIND<Key,T,Hash,Eq,gc_allocator<std::pair<Key, T> > >, public gc { \
+ KIND() : EXT::KIND<Key,T,Hash,Eq,gc_allocator<std::pair<Key, T> > > () {} \
+ KIND(size_t n) \
+ : EXT::KIND<Key,T,Hash,Eq,gc_allocator<std::pair<Key, T> > > (n) {} \
+ }
+
+GC_CONTAINER(unordered_map);
+GC_CONTAINER(unordered_multimap);
+
+#undef GC_CONTAINER
+#undef EXT
+#endif
+
+#ifdef USEGC
+typedef std::basic_string<char,std::char_traits<char>,
+ gc_allocator<char> > string;
+typedef std::basic_stringstream<char,std::char_traits<char>,
+ gc_allocator<char> > stringstream;
+typedef std::basic_istringstream<char,std::char_traits<char>,
+ gc_allocator<char> > istringstream;
+typedef std::basic_ostringstream<char,std::char_traits<char>,
+ gc_allocator<char> > ostringstream;
+typedef std::basic_stringbuf<char,std::char_traits<char>,
+ gc_allocator<char> > stringbuf;
+#else
+typedef std::string string;
+typedef std::stringstream stringstream;
+typedef std::istringstream istringstream;
+typedef std::ostringstream ostringstream;
+typedef std::stringbuf stringbuf;
+#endif // USEGC
+
+} // namespace mem
+
+#endif
diff --git a/Build/source/utils/asymptote/mod.h b/Build/source/utils/asymptote/mod.h
new file mode 100644
index 00000000000..89d017c6ced
--- /dev/null
+++ b/Build/source/utils/asymptote/mod.h
@@ -0,0 +1,41 @@
+/*****
+ * mod.h
+ * Andy Hammerlindl 2005/03/16
+ *
+ * Definition of implementation-independent mod function.
+ *****/
+
+#ifndef MOD_H
+#define MOD_H
+
+#include <cmath>
+
+#include "common.h"
+
+using std::fmod;
+
+inline Int Mod(Int x, Int y) {return x % y;}
+inline double Mod(double x, double y) {return fmod(x,y);}
+
+template<typename T>
+inline T portableMod(T x,T y)
+{
+// Implementation-independent definition of mod; ensure that result has
+// same sign as divisor
+ T val=Mod(x,y);
+ if((y > 0 && val < 0) || (y < 0 && val > 0)) val += y;
+ return val;
+}
+
+inline Int imod(Int x, Int y)
+{
+ return portableMod<Int>(x,y);
+}
+
+inline Int imod(Int i, size_t n) {
+ i %= (Int) n;
+ if(i < 0) i += (Int) n;
+ return i;
+}
+
+#endif
diff --git a/Build/source/utils/asymptote/modifier.h b/Build/source/utils/asymptote/modifier.h
new file mode 100644
index 00000000000..856da9d5c0e
--- /dev/null
+++ b/Build/source/utils/asymptote/modifier.h
@@ -0,0 +1,41 @@
+/*****
+ * modifier.h
+ * Andy Hammerlindl 2002/08/29
+ *
+ * Permissions for variables.
+ * PUBLIC means the variable can be read or written anywhere.
+ * RESTRICTED means it can be read anywhere, but written only in the record.
+ * PRIVATE means it can only be accessed in the record.
+ *
+ * The modifiers static declares that variable to be allocated, are allocated in
+ * the parent's frame, and code is translated into the parent's frame.
+ *****/
+
+#ifndef MODIFIER_H
+#define MODIFIER_H
+
+namespace trans {
+
+// Permission tokens defined in camp.y for accessing a variable outside of
+// its lexically enclosing record.
+enum permission {
+ RESTRICTED,
+ PUBLIC,
+ PRIVATE
+};
+
+const permission DEFAULT_PERM=PUBLIC;
+
+enum modifier {
+ DEFAULT_STATIC,
+ DEFAULT_DYNAMIC,
+ EXPLICIT_STATIC,
+ EXPLICIT_DYNAMIC
+};
+
+} // namespace trans
+
+GC_DECLARE_PTRFREE(trans::permission);
+GC_DECLARE_PTRFREE(trans::modifier);
+
+#endif
diff --git a/Build/source/utils/asymptote/name.cc b/Build/source/utils/asymptote/name.cc
new file mode 100644
index 00000000000..41280351ccf
--- /dev/null
+++ b/Build/source/utils/asymptote/name.cc
@@ -0,0 +1,326 @@
+/*****
+ * name.cc
+ * Andy Hammerlindl2002/07/14
+ *
+ * Qualified names (such as x, f, builtin.sin, a.b.c.d, etc.) can be used
+ * either as variables or a type names. This class stores qualified
+ * names used in nameExp and nameTy in the abstract syntax, and
+ * implements the exp and type functions.
+ *****/
+
+#include "name.h"
+#include "frame.h"
+#include "record.h"
+#include "coenv.h"
+#include "inst.h"
+
+namespace absyntax {
+using namespace types;
+using trans::access;
+using trans::qualifiedAccess;
+using trans::action;
+using trans::READ;
+using trans::WRITE;
+using trans::CALL;
+using vm::inst;
+
+
+types::ty *signatureless(types::ty *t) {
+ if (overloaded *o=dynamic_cast<overloaded *>(t))
+ return o->signatureless();
+ else
+ return (t && !t->getSignature()) ? t : 0;
+}
+
+
+void name::forceEquivalency(action act, coenv &e,
+ types::ty *target, types::ty *source)
+{
+ if (act == READ)
+ e.implicitCast(getPos(), target, source);
+ else if (!equivalent(target, source)) {
+ em.compiler(getPos());
+ em << "type mismatch in variable: "
+ << *target
+ << " vs " << *source;
+ }
+}
+
+frame *name::frameTrans(coenv &e)
+{
+ if (types::ty *t=signatureless(varGetType(e))) {
+ if (t->kind == types::ty_record) {
+ varTrans(READ, e, t);
+ return ((record *)t)->getLevel();
+ }
+ else
+ return 0;
+ }
+ else
+ return tyFrameTrans(e);
+}
+
+
+types::ty *name::getType(coenv &e, bool tacit)
+{
+ types::ty *t=signatureless(varGetType(e));
+ if (!tacit && t && t->kind == ty_error)
+ // Report errors associated with regarding the name as a variable.
+ varTrans(trans::READ, e, t);
+ return t ? t : typeTrans(e, tacit);
+}
+
+
+varEntry *simpleName::getVarEntry(coenv &e)
+{
+ types::ty *t=signatureless(varGetType(e));
+ return t ? e.e.lookupVarByType(id, t) : 0;
+}
+
+void simpleName::varTrans(action act, coenv &e, types::ty *target)
+{
+ varEntry *v = e.e.lookupVarByType(id, target);
+
+ if (v) {
+ v->encode(act, getPos(), e.c);
+ forceEquivalency(act, e, target, v->getType());
+ }
+ else {
+ em.error(getPos());
+ em << "no matching variable of name \'" << *id << "\'";
+ }
+}
+
+types::ty *simpleName::varGetType(coenv &e)
+{
+ return e.e.varGetType(id);
+}
+
+types::ty *simpleName::typeTrans(coenv &e, bool tacit)
+{
+ types::ty *t = e.e.lookupType(id);
+ if (t) {
+ return t;
+ }
+ else {
+ if (!tacit) {
+ em.error(getPos());
+ em << "no type of name \'" << *id << "\'";
+ }
+ return primError();
+ }
+}
+
+tyEntry *simpleName::tyEntryTrans(coenv &e)
+{
+ tyEntry *ent = e.e.lookupTyEntry(id);
+ if (!ent) {
+ em.error(getPos());
+ em << "no type of name \'" << *id << "\'";
+ return new tyEntry(primError(), 0, 0, position());
+ }
+ return ent;
+}
+
+frame *simpleName::tyFrameTrans(coenv &e)
+{
+ tyEntry *ent = e.e.lookupTyEntry(id);
+ if (ent && ent->t->kind==types::ty_record && ent->v) {
+ ent->v->encode(READ, getPos(), e.c);
+ return ent->v->getLevel();
+ }
+ else
+ return 0;
+}
+
+void simpleName::prettyprint(ostream &out, Int indent)
+{
+ prettyindent(out, indent);
+ out << "simpleName '" << *id << "'\n";
+}
+
+
+record *qualifiedName::castToRecord(types::ty *t, bool tacit)
+{
+ switch (t->kind) {
+ case ty_overloaded:
+ if (!tacit) {
+ em.compiler(qualifier->getPos());
+ em << "name::getType returned overloaded";
+ }
+ return 0;
+ case ty_record:
+ return (record *)t;
+ case ty_error:
+ return 0;
+ default:
+ if (!tacit) {
+ em.error(qualifier->getPos());
+ em << "type \'" << *t << "\' is not a structure";
+ }
+ return 0;
+ }
+}
+
+bool qualifiedName::varTransVirtual(action act, coenv &e,
+ types::ty *target, types::ty *qt)
+{
+ varEntry *v = qt->virtualField(id, target->getSignature());
+ if (v) {
+ // Push qualifier onto stack.
+ qualifier->varTrans(READ, e, qt);
+
+ if (act == WRITE) {
+ em.error(getPos());
+ em << "virtual field '" << *id << "' of '" << *qt
+ << "' cannot be modified";
+ }
+ else {
+ // Call instead of reading as it is a virtual field.
+ v->encode(CALL, getPos(), e.c);
+ e.implicitCast(getPos(), target, v->getType());
+
+ if (act == CALL)
+ // In this case, the virtual field will construct a vm::func object
+ // and push it on the stack.
+ // Then, pop and call the function.
+ e.c.encode(inst::popcall);
+ }
+
+ // A virtual field was used.
+ return true;
+ }
+
+ // No virtual field.
+ return false;
+}
+
+void qualifiedName::varTransField(action act, coenv &e,
+ types::ty *target, record *r)
+{
+ varEntry *v = r->e.lookupVarByType(id, target);
+
+ if (v) {
+ frame *f = qualifier->frameTrans(e);
+ if (f)
+ v->encode(act, getPos(), e.c, f);
+ else
+ v->encode(act, getPos(), e.c);
+
+ forceEquivalency(act, e, target, v->getType());
+ }
+ else {
+ em.error(getPos());
+ em << "no matching field of name \'" << *id << "\' in \'" << *r << "\'";
+ }
+}
+
+void qualifiedName::varTrans(action act, coenv &e, types::ty *target)
+{
+ types::ty *qt = qualifier->getType(e);
+
+ // Use virtual fields if applicable.
+ if (varTransVirtual(act, e, target, qt))
+ return;
+
+ record *r = castToRecord(qt);
+ if (r)
+ varTransField(act, e, target, r);
+}
+
+types::ty *qualifiedName::varGetType(coenv &e)
+{
+ types::ty *qt = qualifier->getType(e, true);
+
+ // Look for virtual fields.
+ types::ty *t = qt->virtualFieldGetType(id);
+ if (t)
+ return t;
+
+ record *r = castToRecord(qt, true);
+ return r ? r->e.varGetType(id) : 0;
+}
+
+trans::varEntry *qualifiedName::getVarEntry(coenv &e)
+{
+ varEntry *qv = qualifier->getVarEntry(e);
+
+ types::ty *qt = qualifier->getType(e, true);
+ record *r = castToRecord(qt, true);
+ if (r) {
+ types::ty *t = signatureless(r->e.varGetType(id));
+ varEntry *v = t ? r->e.lookupVarByType(id, t) : 0;
+ return trans::qualifyVarEntry(qv,v);
+ }
+ else
+ return qv;
+}
+
+types::ty *qualifiedName::typeTrans(coenv &e, bool tacit)
+{
+ types::ty *rt = qualifier->getType(e, tacit);
+
+ record *r = castToRecord(rt, tacit);
+ if (!r)
+ return primError();
+
+ tyEntry *ent = r->e.lookupTyEntry(id);
+ if (ent) {
+ if (!tacit)
+ ent->reportPerm(READ, getPos(), e.c);
+ return ent->t;
+ }
+ else {
+ if (!tacit) {
+ em.error(getPos());
+ em << "no matching field or type of name \'" << *id << "\' in \'"
+ << *r << "\'";
+ }
+ return primError();
+ }
+}
+
+tyEntry *qualifiedName::tyEntryTrans(coenv &e)
+{
+ types::ty *rt = qualifier->getType(e, false);
+
+ record *r = castToRecord(rt, false);
+ if (!r)
+ return new tyEntry(primError(), 0, 0, position());
+
+ tyEntry *ent = r->e.lookupTyEntry(id);
+ if (!ent) {
+ em.error(getPos());
+ em << "no matching type of name \'" << *id << "\' in \'"
+ << *r << "\'";
+ return new tyEntry(primError(), 0, 0, position());
+ }
+ ent->reportPerm(READ, getPos(), e.c);
+
+ return trans::qualifyTyEntry(qualifier->getVarEntry(e), ent);
+}
+
+frame *qualifiedName::tyFrameTrans(coenv &e)
+{
+ frame *f=qualifier->frameTrans(e);
+ tyEntry *ent = e.e.lookupTyEntry(id);
+ if (ent && ent->t->kind==types::ty_record && ent->v) {
+ if (f)
+ ent->v->encode(READ, getPos(), e.c, f);
+ else
+ ent->v->encode(READ, getPos(), e.c);
+ return ent->v->getLevel();
+ }
+ else
+ return f;
+}
+
+void qualifiedName::prettyprint(ostream &out, Int indent)
+{
+ prettyindent(out, indent);
+ out << "qualifiedName '" << *id << "'\n";
+
+ qualifier->prettyprint(out, indent+1);
+}
+
+} // namespace absyntax
diff --git a/Build/source/utils/asymptote/name.h b/Build/source/utils/asymptote/name.h
new file mode 100644
index 00000000000..9864d5e13ae
--- /dev/null
+++ b/Build/source/utils/asymptote/name.h
@@ -0,0 +1,167 @@
+/*****
+ * name.h
+ * Andy Hammerlindl 2002/07/14
+ *
+ * Qualified names (such as x, f, builtin.sin, a.b.c.d, etc.) can be used
+ * either as variables or a type names. This class stores qualified
+ * names used in nameExp and nameTy in the abstract syntax, and
+ * implements the exp and type functions.
+ *****/
+
+#ifndef NAME_H
+#define NAME_H
+
+#include "absyn.h"
+#include "types.h"
+#include "frame.h"
+#include "access.h"
+
+namespace trans {
+class coenv;
+class varEntry;
+class tyEntry;
+}
+namespace types {
+class record;
+}
+
+namespace absyntax {
+
+using trans::coenv;
+using trans::action;
+using types::record;
+using std::ostream;
+
+class name : public absyn {
+public:
+ name(position pos)
+ : absyn(pos) {}
+
+ // Helper function - ensures target and source match up, using casting in the
+ // case of a read. Issues errors on failure.
+ void forceEquivalency(action act, coenv &e,
+ types::ty *target, types::ty *source);
+
+ // Used for determining the type when the context does not establish
+ // the name as a variable or a type. First, the function looks for a
+ // non-function variable fitting the description. If one fits, the
+ // type of the variable is returned. Failing that, the function looks
+ // for a fitting type and returns that. If nothing is found, an
+ // appropriate error is reported and ty_error is returned.
+ // Because this is used only on qualifiers (ie. names to the left of a
+ // dot), it does not look at function variables.
+ // Tacit means that no error messages will be reported to the user.
+ virtual types::ty *getType(coenv &e, bool tacit = false);
+
+ // Pushes the highest level frame possible onto the stack. Returning
+ // the frame pushed. If no frame can be pushed, returns 0.
+ // NOTE: This duplicates some functionality with getVarEntry.
+ virtual trans::frame *frameTrans(coenv &e);
+ // Helper function for the case where the name is known to be a type.
+ virtual trans::frame *tyFrameTrans(coenv &e) = 0;
+
+ // Constructs the varEntry part of the tyEntry for the name. Like
+ // getType, this is called on the qualifier, instead of the full name.
+ // This reports no errors, and returns 0 if there is no varEntry to
+ // use.
+ virtual trans::varEntry *getVarEntry(coenv &e) = 0;
+
+ // As a variable:
+ // Translates the name (much like an expression).
+ virtual void varTrans(action act, coenv &e, types::ty *target) = 0;
+ // Returns the possible variable types. Unlike exp, returns 0 if none
+ // match.
+ virtual types::ty *varGetType(coenv &e) = 0;
+
+ // As a type:
+ // Determines the type, as used in a variable declaration.
+ virtual types::ty *typeTrans(coenv &e, bool tacit = false) = 0;
+ // Constructs the tyEntry of the name, needed so that we know the
+ // parent frame for allocating new objects of that type. Reports
+ // errors as typeTrans() does with tacit=false.
+ virtual trans::tyEntry *tyEntryTrans(coenv &e) = 0;
+
+ virtual void prettyprint(ostream &out, Int indent) = 0;
+ virtual void print(ostream& out) const {
+ out << "<base name>";
+ }
+
+ virtual symbol *getName() = 0;
+};
+
+inline ostream& operator<< (ostream& out, const name& n) {
+ n.print(out);
+ return out;
+}
+
+class simpleName : public name {
+ symbol *id;
+
+public:
+ simpleName(position pos, symbol *id)
+ : name(pos), id(id) {}
+
+ trans::varEntry *getVarEntry(coenv &e);
+
+ // As a variable:
+ void varTrans(action act, coenv &e, types::ty *target);
+ types::ty *varGetType(coenv &);
+
+ // As a type:
+ types::ty *typeTrans(coenv &e, bool tacit = false);
+ virtual trans::tyEntry *tyEntryTrans(coenv &e);
+ trans::frame *tyFrameTrans(coenv &e);
+
+ void prettyprint(ostream &out, Int indent);
+ void print(ostream& out) const {
+ out << *id;
+ }
+ symbol *getName() {
+ return id;
+ }
+};
+
+
+class qualifiedName : public name {
+ name *qualifier;
+ symbol *id;
+
+ // Gets the record type associated with the qualifier. Reports an
+ // error and returns null if the type is not a record.
+ record *castToRecord(types::ty *t, bool tacit = false);
+
+ // Translates as a virtual field, if possible. qt is the type of the
+ // qualifier. Return true if there was a matching virtual field.
+ bool varTransVirtual(action act, coenv &e,
+ types::ty *target, types::ty *qt);
+
+ // Translates as an ordinary (non-virtual) field of a record, r.
+ void varTransField(action act, coenv &e,
+ types::ty *target, record *r);
+public:
+ qualifiedName(position pos, name *qualifier, symbol *id)
+ : name(pos), qualifier(qualifier), id(id) {}
+
+ trans::varEntry *getVarEntry(coenv &e);
+
+ // As a variable:
+ void varTrans(action act, coenv &, types::ty *target);
+ types::ty *varGetType(coenv &);
+
+ // As a type:
+ types::ty *typeTrans(coenv &e, bool tacit = false);
+ trans::tyEntry *tyEntryTrans(coenv &e);
+ trans::frame *tyFrameTrans(coenv &e);
+
+ void prettyprint(ostream &out, Int indent);
+ void print(ostream& out) const {
+ out << *qualifier << "." << *id;
+ }
+ symbol *getName() {
+ return id;
+ }
+};
+
+} // namespace absyntax
+
+#endif
diff --git a/Build/source/utils/asymptote/newexp.cc b/Build/source/utils/asymptote/newexp.cc
new file mode 100644
index 00000000000..ddf3f07e7a4
--- /dev/null
+++ b/Build/source/utils/asymptote/newexp.cc
@@ -0,0 +1,180 @@
+/*****
+ * newexp.cc
+ * Andy Hammerlindl 2003/07/28
+ *
+ * Handles the abstract syntax for expressions the create new objects,
+ * such as record, array, and function constructors.
+ *****/
+
+#include "newexp.h"
+#include "stm.h"
+#include "runtime.h"
+#include "coenv.h"
+#include "inst.h"
+
+using namespace types;
+using trans::coder;
+using trans::coenv;
+using vm::inst;
+
+namespace absyntax {
+
+void printFrame(frame *f) {
+ if (f == 0) {
+ cerr << '0';
+ }
+ else {
+ cerr << f << " of ";
+ printFrame(f->getParent());
+ }
+}
+
+bool newRecordExp::encodeLevel(position pos, coenv &e, trans::tyEntry *ent)
+{
+ record *r = dynamic_cast<record *>(ent->t);
+ assert(r);
+
+ // The level needed on which to allocate the record.
+ frame *level = r->getLevel()->getParent();
+
+ if (ent->v) {
+ // Put the record on the stack. For instance, in code like
+ // import imp;
+ // new imp.t;
+ // we are putting the instance of imp on the stack, so we can use it to
+ // allocate an instance of imp.t.
+ ent->v->getLocation()->encode(trans::READ, pos, e.c);
+
+ // Adjust to the right frame. For instance, in the last new in
+ // struct A {
+ // struct B {
+ // static struct C {}
+ // }
+ // B b=new B;
+ // }
+ // A a=new A;
+ // new a.b.C;
+ // we push a.b onto the stack, but need a as the enclosing frame for
+ // allocating an instance of C.
+ record *q = dynamic_cast<record *>(ent->v->getType());
+ return e.c.encode(level, q->getLevel());
+ }
+ else
+ return e.c.encode(level);
+}
+
+types::ty *newRecordExp::transFromTyEntry(position pos, coenv &e,
+ trans::tyEntry *ent)
+{
+ types::ty *t = ent->t;
+ if (t->kind == ty_error)
+ return t;
+ else if (t->kind != ty_record) {
+ em.error(pos);
+ em << "type '" << *t << "' is not a structure";
+ return primError();
+ }
+
+ // Put the enclosing frame on the stack.
+ if (!encodeLevel(pos, e, ent)) {
+ em.error(pos);
+ em << "allocation of struct '" << *t << "' is not in a valid scope";
+ return primError();
+ }
+
+ record *r = dynamic_cast<record *>(t);
+ assert(r);
+
+ // Encode the allocation.
+ e.c.encode(inst::makefunc,r->getInit());
+ e.c.encode(inst::popcall);
+
+ return t;
+}
+
+types::ty *newRecordExp::trans(coenv &e)
+{
+ return transFromTyEntry(getPos(), e, result->transAsTyEntry(e, 0));
+}
+
+types::ty *newRecordExp::getType(coenv &e)
+{
+ types::ty *t = result->trans(e, true);
+ if (t->kind != ty_error && t->kind != ty_record)
+ return primError();
+ else
+ return t;
+}
+
+void newArrayExp::prettyprint(ostream &out, Int indent)
+{
+ prettyname(out,"newArrayExp",indent);
+
+ celltype->prettyprint(out, indent+1);
+ if (dimexps) dimexps->prettyprint(out, indent+1);
+ if (dims) dims->prettyprint(out, indent+1);
+ if (ai) ai->prettyprint(out, indent+1);
+}
+
+types::ty *newArrayExp::trans(coenv &e)
+{
+ types::ty *c = celltype->trans(e);
+ if (c->kind == ty_void) {
+ em.error(getPos());
+ em << "cannot declare array of type void";
+ return primError();
+ }
+
+ if (dims)
+ c = dims->truetype(c);
+
+ if (ai) {
+ ai->transToType(e, c);
+ return c;
+ } else if (dimexps || dims) {
+ if (dimexps) {
+ for (size_t i = 0; i < dimexps->size(); ++i) {
+ (*dimexps)[i]->transToType(e, types::primInt());
+ c = new types::array(c);
+ }
+ }
+ if (dims) {
+ for (size_t i = 0; i < dims->size(); ++i) {
+ e.c.encode(inst::intpush,0);
+ }
+ }
+ e.c.encode(inst::intpush,
+ (Int) ((dimexps ? dimexps->size():0)
+ + (dims ? dims->size():0)));
+ e.c.encode(inst::builtin, run::newDeepArray);
+
+ return c;
+ } else {
+ em.compiler(getPos());
+ em << "new array expression must have either dims or dimexps";
+ return primError();
+ }
+}
+
+types::ty *newArrayExp::getType(coenv &e)
+{
+ types::ty *c = celltype->trans(e);
+ if (c->kind == ty_void) {
+ return primError();
+ }
+ if (dims)
+ c = dims->truetype(c);
+
+ if (dimexps) {
+ Int depth = (Int)dimexps->size();
+ while (depth > 0) {
+ c = new types::array(c);
+ depth--;
+ }
+ }
+
+ return c;
+}
+
+
+} // namespace absyntax
diff --git a/Build/source/utils/asymptote/newexp.h b/Build/source/utils/asymptote/newexp.h
new file mode 100644
index 00000000000..989846a797b
--- /dev/null
+++ b/Build/source/utils/asymptote/newexp.h
@@ -0,0 +1,58 @@
+/*****
+ * newexp.h
+ * Andy Hammerlindl 2003/07/28
+ *
+ * Handles the abstract syntax for expressions the create new objects,
+ * such as record, array, and function constructors.
+ *****/
+
+#ifndef NEWEXP_H
+#define NEWEXP_H
+
+#include "exp.h"
+#include "dec.h"
+#include "fundec.h"
+#include "entry.h"
+
+namespace absyntax {
+
+typedef fundef newFunctionExp;
+
+class newRecordExp : public exp {
+ ty *result;
+
+ static bool encodeLevel(position pos, coenv &e, trans::tyEntry *ent);
+public:
+ newRecordExp(position pos, ty *result)
+ : exp(pos), result(result) {}
+
+ static types::ty *transFromTyEntry(position pos, coenv &e,
+ trans::tyEntry *ent);
+
+ types::ty *trans(coenv &e);
+ types::ty *getType(coenv &e);
+};
+
+class newArrayExp : public exp {
+ ty *celltype;
+ explist *dimexps;
+ dimensions *dims;
+ arrayinit *ai;
+
+public:
+ newArrayExp(position pos,
+ ty *celltype,
+ explist *dimexps,
+ dimensions *dims,
+ arrayinit *ai)
+ : exp(pos), celltype(celltype), dimexps(dimexps), dims(dims), ai(ai) {}
+
+ void prettyprint(ostream &out, Int indent);
+
+ types::ty *trans(coenv &e);
+ types::ty *getType(coenv &e);
+};
+
+} // namespace absyntax
+
+#endif
diff --git a/Build/source/utils/asymptote/pair.h b/Build/source/utils/asymptote/pair.h
new file mode 100644
index 00000000000..7d2716fb991
--- /dev/null
+++ b/Build/source/utils/asymptote/pair.h
@@ -0,0 +1,229 @@
+/*****
+ * pair.h
+ * Andy Hammerlindl 2002/05/16
+ *
+ * Stores a two-dimensional point similar to the pair type in MetaPost.
+ * In some cases, pairs behave as complex numbers.
+ *
+ * A pair is a guide as a pair alone can be used to describe a path.
+ * The solve and subsolve methods are fairly straight forward as solve
+ * returns a path with just the pair and subsolve just adds the pair to
+ * the structure.
+ *****/
+
+#ifndef PAIR_H
+#define PAIR_H
+
+#include <cassert>
+#include <cmath>
+
+#include "common.h"
+#include "angle.h"
+
+namespace camp {
+
+class pair : public gc {
+ double x;
+ double y;
+
+public:
+ pair() : x(0.0), y(0.0) {}
+ pair(double x, double y=0.0) : x(x), y(y) {}
+
+ double getx() const { return x; }
+ double gety() const { return y; }
+
+ bool isreal() {return y == 0;}
+
+ friend pair operator+ (const pair& z, const pair& w)
+ {
+ return pair(z.x + w.x, z.y + w.y);
+ }
+
+ friend pair operator- (const pair& z, const pair& w)
+ {
+ return pair(z.x - w.x, z.y - w.y);
+ }
+
+ friend pair operator- (const pair& z)
+ {
+ return pair(-z.x, -z.y);
+ }
+
+ // Complex multiplication
+ friend pair operator* (const pair& z, const pair& w)
+ {
+ return pair(z.x*w.x - z.y*w.y, z.x*w.y + w.x*z.y);
+ }
+
+ const pair& operator+= (const pair& w)
+ {
+ x += w.x;
+ y += w.y;
+ return *this;
+ }
+
+ const pair& operator-= (const pair& w)
+ {
+ x -= w.x;
+ y -= w.y;
+ return *this;
+ }
+
+ const pair& operator*= (const pair& w)
+ {
+ (*this) = (*this) * w;
+ return (*this);
+ }
+
+ const pair& operator/= (const pair& w)
+ {
+ (*this) = (*this) / w;
+ return (*this);
+ }
+
+ const pair& scale (double xscale, double yscale)
+ {
+ x *= xscale;
+ y *= yscale;
+ return *this;
+ }
+
+ friend pair operator/ (const pair &z, double t)
+ {
+ if (t == 0.0)
+ reportError("division by 0");
+ t=1.0/t;
+ return pair(z.x*t, z.y*t);
+ }
+
+ friend pair operator/ (const pair& z, const pair& w)
+ {
+ if (!w.nonZero())
+ reportError("divison by pair (0,0)");
+
+ double t = 1.0 / (w.x*w.x + w.y*w.y);
+ return pair(t*(z.x*w.x + z.y*w.y),
+ t*(-z.x*w.y + w.x*z.y));
+ }
+
+ friend bool operator== (const pair& z, const pair& w)
+ {
+ return z.x == w.x && z.y == w.y;
+ }
+
+ friend bool operator!= (const pair& z, const pair& w)
+ {
+ return z.x != w.x || z.y != w.y;
+ }
+
+ double abs2() const
+ {
+ return x*x + y*y;
+ }
+
+ double length() const
+ {
+ return sqrt(abs2());
+ }
+
+ friend double length(const pair& z)
+ {
+ return z.length();
+ }
+
+ double angle() const
+ {
+ return camp::angle(x,y);
+ }
+
+ friend double angle(const pair& z)
+ {
+ return z.angle();
+ }
+
+ friend pair unit(const pair& z)
+ {
+ double scale=z.length();
+ if(scale != 0.0) scale=1.0/scale;
+ return pair(z.x*scale,z.y*scale);
+ }
+
+ friend pair conj(const pair& z)
+ {
+ return pair(z.x,-z.y);
+ }
+
+ friend double dot(const pair& z, const pair& w)
+ {
+ return z.getx()*w.getx()+z.gety()*w.gety();
+ }
+
+// Return the principal branch of the square root (non-negative real part).
+ friend pair Sqrt(const pair& z) {
+ double mag=z.length();
+ if(mag == 0.0) return pair(0.0,0.0);
+ else if(z.x > 0) {
+ double re=sqrt(0.5*(mag+z.x));
+ return pair(re,0.5*z.y/re);
+ } else {
+ double im=sqrt(0.5*(mag-z.x));
+ if(z.y < 0) im=-im;
+ return pair(0.5*z.y/im,im);
+ }
+ }
+
+ bool nonZero() const
+ {
+ return x != 0.0 || y != 0.0;
+ }
+
+ friend istream& operator >> (istream& s, pair& z)
+ {
+ char c;
+ s >> std::ws;
+ bool paren=s.peek() == '('; // parenthesis are optional
+ if(paren) s >> c;
+ s >> z.x >> std::ws;
+ if(!s.eof() && s.peek() == ',') s >> c >> z.y;
+ else z.y=0.0;
+ if(paren) {
+ s >> std::ws;
+ if(s.peek() == ')') s >> c;
+ }
+
+ return s;
+ }
+
+ friend ostream& operator << (ostream& out, const pair& z)
+ {
+ out << "(" << z.x << "," << z.y << ")";
+ return out;
+ }
+
+ friend class box;
+};
+
+// Calculates exp(i * theta), useful for unit vectors.
+inline pair expi(double theta)
+{
+ if(theta == 0.0) return pair(1.0,0.0); // Frequently occurring case
+ return pair(cos(theta),sin(theta));
+}
+
+// Complex exponentiation
+inline pair pow(const pair& z, const pair& w)
+{
+ double u=w.getx();
+ double v=w.gety();
+ if(z == 0.0) return w == 0.0 ? 1.0 : 0.0;
+ double logr=0.5*log(z.abs2());
+ double th=z.angle();
+ return exp(logr*u-th*v)*expi(logr*v+th*u);
+}
+
+} //namespace camp
+
+GC_DECLARE_PTRFREE(camp::pair);
+
+#endif
diff --git a/Build/source/utils/asymptote/parser.cc b/Build/source/utils/asymptote/parser.cc
new file mode 100644
index 00000000000..cbeb54fe230
--- /dev/null
+++ b/Build/source/utils/asymptote/parser.cc
@@ -0,0 +1,146 @@
+/*****
+ * parser.cc
+ * Tom Prince 2004/01/10
+ *
+ *****/
+
+#include <fstream>
+#include <sstream>
+
+#include "common.h"
+
+#ifdef HAVE_SYS_STAT_H
+#include <sys/stat.h>
+#endif
+
+#include "interact.h"
+#include "locate.h"
+#include "errormsg.h"
+#include "parser.h"
+
+// The lexical analysis and parsing functions used by parseFile.
+void setlexer(size_t (*input) (char* bif, size_t max_size), string filename);
+extern bool yyparse(void);
+extern int yydebug;
+extern int yy_flex_debug;
+static const int YY_NULL = 0;
+extern bool lexerEOF();
+extern void reportEOF();
+
+namespace parser {
+
+namespace yy { // Lexers
+
+std::streambuf *sbuf = NULL;
+
+size_t stream_input(char *buf, size_t max_size)
+{
+ size_t count= sbuf ? sbuf->sgetn(buf,max_size) : 0;
+ return count ? count : YY_NULL;
+}
+
+} // namespace yy
+
+void debug(bool state)
+{
+ // For debugging the machine-generated lexer and parser.
+ yy_flex_debug = yydebug = state;
+}
+
+namespace {
+void error(const string& filename)
+{
+ em.sync();
+ em << "error: could not load module '" << filename << "'\n";
+ em.sync();
+ throw handled_error();
+}
+}
+
+absyntax::file *doParse(size_t (*input) (char* bif, size_t max_size),
+ const string& filename, bool extendable=false)
+{
+ setlexer(input,filename);
+ absyntax::file *root = yyparse() == 0 ? absyntax::root : 0;
+ absyntax::root = 0;
+ yy::sbuf = 0;
+
+ if (!root) {
+ if (lexerEOF()) {
+ if (extendable) {
+ return 0;
+ } else {
+ // Have the lexer report the error.
+ reportEOF();
+ }
+ }
+
+ em.error(nullPos);
+ if(!interact::interactive)
+ error(filename);
+ else
+ throw handled_error();
+ }
+
+ return root;
+}
+
+absyntax::file *parseStdin()
+{
+ debug(false);
+ yy::sbuf = cin.rdbuf();
+ return doParse(yy::stream_input,"-");
+}
+
+absyntax::file *parseFile(const string& filename,
+ const char *nameOfAction)
+{
+ if(filename == "-")
+ return parseStdin();
+
+ string file = settings::locateFile(filename);
+
+ if(file.empty())
+ error(filename);
+
+ if(nameOfAction && settings::verbose > 1)
+ cerr << nameOfAction << " " << filename << " from " << file << endl;
+
+ debug(false);
+
+ std::filebuf filebuf;
+ if(!filebuf.open(file.c_str(),std::ios::in))
+ error(filename);
+
+#ifdef HAVE_SYS_STAT_H
+ // Check that the file is not a directory.
+ static struct stat buf;
+ if(stat(file.c_str(),&buf) == 0) {
+ if(S_ISDIR(buf.st_mode))
+ error(filename);
+ }
+#endif
+
+ // Check that the file can actually be read.
+ try {
+ filebuf.sgetc();
+ } catch (...) {
+ error(filename);
+ }
+
+ yy::sbuf = &filebuf;
+ return doParse(yy::stream_input,file);
+}
+
+absyntax::file *parseString(const string& code,
+ const string& filename,
+ bool extendable)
+{
+ debug(false);
+ stringbuf buf(code);
+ yy::sbuf = &buf;
+ return doParse(yy::stream_input,filename,extendable);
+}
+
+} // namespace parser
+
diff --git a/Build/source/utils/asymptote/parser.h b/Build/source/utils/asymptote/parser.h
new file mode 100644
index 00000000000..b297d5e86cd
--- /dev/null
+++ b/Build/source/utils/asymptote/parser.h
@@ -0,0 +1,29 @@
+/*****
+ * parser.h
+ * Tom Prince 2004/01/10
+ *
+ *****/
+
+#ifndef PARSER_H
+#define PARSER_H
+
+#include "common.h"
+#include "absyn.h"
+
+namespace parser {
+
+// Opens and parses the file returning the abstract syntax tree. If
+// there is an unrecoverable parse error, returns null.
+absyntax::file *parseFile(const string& filename,
+ const char *nameOfAction);
+
+// Parses string and returns the abstract syntax tree. Any error in lexing or
+// parsing will be reported and a handled_error thrown. If the string is
+// "extendable", then a parse error simply due to running out of input will not
+// throw an exception, but will return null.
+absyntax::file *parseString(const string& code,
+ const string& filename,
+ bool extendable=false);
+} // namespace parser
+
+#endif // PARSER_H
diff --git a/Build/source/utils/asymptote/patches/README b/Build/source/utils/asymptote/patches/README
new file mode 100644
index 00000000000..6197ca84f0a
--- /dev/null
+++ b/Build/source/utils/asymptote/patches/README
@@ -0,0 +1,34 @@
+The optional patches to flex-2.5.31 and bison-2.0a in this directory fix a
+number of problems with warning and/or error messages generated by strict
+compilers.
+
+A modified version of dvipdf that accepts common dvips options is included.
+
+The file gcc3.3.2curses.patch can be used to patch the broken curses.h header
+files (or a local copy thereof in the current directory) on some AIX and
+IRIX systems.
+
+The file gc6.8_AIX.patch fixes an incorrect Boehm garbage collector
+prototype in the file gc6.8/include/gc.h (version 6.8).
+
+The file gc-7.0nomem.patch avoids segmentation faults with gc-7.0 on
+out-of-memory errors.
+
+A patch to provide full functionality in the Asymptote backend to pstoedit
+(http://pstoedit.net) is provided in the file pstoedit-3.45asy.patch.
+
+The file TkAlpha-Imaging-1.1.6.patch is a revised patch that fixes
+transparency support in PIL for xasy (this supercedes an obsolete patch
+of the same name included in Asymptote 1.36, which resulted in very slow
+rendering). Application of this patch is strongly recommended.
+
+The file movie15_dvipdfmx.patch brings the xelatex/dvipdfmx-enhanced
+version of movie15.sty available at
+http://cvs.ktug.or.kr/viewcvs/dvipdfmx/contrib/latex/movie15.sty.sample?revision=1.1
+up-to-date with the latest official 2008/10/08 version. For convenience the
+patched version is also included as movie15_dvipdfmx.sty; it should be
+renamed to movie15.sty and installed in the local latex directory.
+
+The file movie15_20090323.patch works around a problem with 3Dgetview that
+shows up under Windows XP in the 2009/03/23 version of movie15.sty.
+
diff --git a/Build/source/utils/asymptote/patches/TkAlpha-Imaging-1.1.6.patch b/Build/source/utils/asymptote/patches/TkAlpha-Imaging-1.1.6.patch
new file mode 100644
index 00000000000..30ee1ffa31a
--- /dev/null
+++ b/Build/source/utils/asymptote/patches/TkAlpha-Imaging-1.1.6.patch
@@ -0,0 +1,156 @@
+diff -ru Imaging-1.1.6/Tk/tkImaging.c Imaging-1.1.6J/Tk/tkImaging.c
+--- Imaging-1.1.6/Tk/tkImaging.c 2006-12-03 04:37:29.000000000 -0700
++++ Imaging-1.1.6J/Tk/tkImaging.c 2007-11-14 20:22:02.000000000 -0700
+@@ -48,6 +48,9 @@
+ for the Tcl_CreateCommand command. */
+ #define USE_COMPAT_CONST
+
++#define CONST84 const
++#define CONST84_RETURN const
++
+ #include "tk.h"
+
+ #include "Imaging.h"
+@@ -76,6 +79,13 @@
+ Imaging im;
+ Tk_PhotoHandle photo;
+ Tk_PhotoImageBlock block;
++ int renderalpha;
++ char *max_alpha_area;
++ int maxarea;
++ Tk_PhotoImageBlock run;
++
++ unsigned char back[3]={255,255,255};
++ char *background=getenv("PIL_BACKGROUND");
+
+ if (argc != 3) {
+ Tcl_AppendResult(interp, "usage: ", argv[0],
+@@ -117,6 +127,15 @@
+
+ /* Mode */
+
++#ifndef MAX_ALPHA_AREA
++#define MAX_ALPHA_AREA 10000;
++#endif
++
++ maxarea=MAX_ALPHA_AREA;
++ max_alpha_area=getenv("PIL_MAX_ALPHA_AREA");
++ if(max_alpha_area != NULL) maxarea=atoi(max_alpha_area);
++ renderalpha=(maxarea < 0) ? 1 : (im->xsize*im->ysize < maxarea);
++
+ if (strcmp(im->mode, "1") == 0 || strcmp(im->mode, "L") == 0) {
+ block.pixelSize = 1;
+ block.offset[0] = block.offset[1] = block.offset[2] = 0;
+@@ -125,7 +144,10 @@
+ block.offset[0] = 0;
+ block.offset[1] = 1;
+ block.offset[2] = 2;
+- block.offset[3] = 0; /* no alpha (or reserved, under 8.2) */
++ if(renderalpha && strcmp(im->mode,"RGBA") == 0)
++ block.offset[3] = 3; /* alpha (or reserved, under 8.2) */
++ else
++ block.offset[3] = 0; /* no alpha */
+ } else {
+ Tcl_AppendResult(interp, "Bad mode", (char*) NULL);
+ return TCL_ERROR;
+@@ -140,15 +162,30 @@
+ src_yoffset * im->linesize +
+ src_xoffset * im->pixelsize;
+ #endif
+-
+- if (strcmp(im->mode, "RGBA") == 0) {
+- /* Copy non-transparent pixels to photo image */
++ if (!renderalpha && strcmp(im->mode, "RGBA") == 0) {
++ int bytes =block.height*block.pitch;
++ unsigned char *pixelPtr;
+ int x, y;
+- Tk_PhotoImageBlock run;
++ int j;
++
++ /* Buffer image block for pseudo-antialiasing */
++ if (bytes <= 0)
++ bytes=1;
++ pixelPtr=(unsigned char *) malloc(bytes);
++ if (!pixelPtr) {
++ Tcl_AppendResult(interp, "bad display memory", (char*) NULL);
++ return TCL_ERROR;
++ }
+
+- /* Clear current contents */
+- Tk_PhotoBlank(photo);
++ /* Copy non-transparent pixels to photo image */
+
++ if(background && strlen(background) == 6) {
++ for(j=0; j < 3; ++j) {
++ char h[3]={background[2*j],background[2*j+1],0};
++ back[j]=strtol(h,NULL,16);
++ }
++ }
++
+ /* Setup run descriptor */
+ run.height = 1;
+ run.pitch = block.pitch;
+@@ -161,13 +198,19 @@
+ /* Copy opaque runs to photo image */
+ for (y = 0; y < block.height; y++) {
+ unsigned char* p = block.pixelPtr + y*block.pitch;
+- unsigned char* s = p;
++ unsigned char* q = pixelPtr + y*block.pitch;
++ unsigned char* s = q;
+ int w = 0;
+ for (x = 0; x < block.width; x++) {
+ if (p[3]) {
+ /* opaque: add pixel to current run */
+- if (w == 0)
+- s = p;
++ double opacity=p[3]/255.0;
++ double transparency=1.0-opacity;
++ q[0]=(int) (opacity*p[0]+transparency*back[0]);
++ q[1]=(int) (opacity*p[1]+transparency*back[1]);
++ q[2]=(int) (opacity*p[2]+transparency*back[2]);
++ if (w == 0)
++ s = q;
+ w = w + 1;
+ } else if (s) {
+ /* copy run to photo image */
+@@ -179,6 +222,7 @@
+ w = 0;
+ }
+ p += block.pixelSize;
++ q += block.pixelSize;
+ }
+ if (w > 0) {
+ /* copy final run, if any */
+@@ -188,10 +232,15 @@
+ }
+ }
+
+- } else
+-
+- /* Copy opaque block to photo image, and leave the rest to TK */
+- Tk_PhotoPutBlock(photo, &block, 0, 0, block.width, block.height);
++ } else {
++ /* Copy block to photo image, and leave the rest to TK */
++ Tk_PhotoPutBlock(photo, &block, 0, 0, block.width, block.height);
++
++ if (strcmp(im->mode, "RGBA") == 0)
++ /* Tk workaround: we need apply ToggleComplexAlphaIfNeeded */
++ /* (fixed in Tk 8.5a3) */
++ Tk_PhotoSetSize(photo, block.width, block.height);
++ }
+
+ return TCL_OK;
+ }
+diff -ru Imaging-1.1.6/_imagingtk.c Imaging-1.1.6J/_imagingtk.c
+--- Imaging-1.1.6/_imagingtk.c 2006-12-03 04:51:25.000000000 -0700
++++ Imaging-1.1.6J/_imagingtk.c 2007-11-14 17:42:54.000000000 -0700
+@@ -17,6 +17,9 @@
+ #include "Python.h"
+ #include "Imaging.h"
+
++#define CONST84 const
++#define CONST84_RETURN const
++
+ #include "tk.h"
+
+ /* must link with Tk/tkImaging.c */
diff --git a/Build/source/utils/asymptote/patches/TkAlpha-Imaging-1.1.6msdos.patch b/Build/source/utils/asymptote/patches/TkAlpha-Imaging-1.1.6msdos.patch
new file mode 100644
index 00000000000..8e946963685
--- /dev/null
+++ b/Build/source/utils/asymptote/patches/TkAlpha-Imaging-1.1.6msdos.patch
@@ -0,0 +1,52 @@
+--- Imaging-1.1.6/Tk/tkImaging.c.orig 2006-12-03 04:37:29.000000000 -0700
++++ Imaging-1.1.6/Tk/tkImaging.c 2007-05-15 11:37:54.000000000 -0600
+@@ -39,10 +39,7 @@
+ * See the README file for information on usage and redistribution.
+ */
+
+-/* This is needed for (at least) Tk 8.4.1, otherwise the signature of
+-** Tk_PhotoPutBlock changes.
+-*/
+-#define USE_COMPOSITELESS_PHOTO_PUT_BLOCK
++#define TKMAJORMINOR (TK_MAJOR_VERSION*1000 + TK_MINOR_VERSION)
+
+ /* This is needed for (at least) Tk 8.4.6 and later, to avoid warnings
+ for the Tcl_CreateCommand command. */
+@@ -125,7 +122,10 @@
+ block.offset[0] = 0;
+ block.offset[1] = 1;
+ block.offset[2] = 2;
+- block.offset[3] = 0; /* no alpha (or reserved, under 8.2) */
++ if(strcmp(im->mode,"RGBA")==0)
++ block.offset[3] = 3; /*alpha (or reserved, under 8.2)*/
++ else
++ block.offset[3] = 0; /* no alpha */
+ } else {
+ Tcl_AppendResult(interp, "Bad mode", (char*) NULL);
+ return TCL_ERROR;
+@@ -140,7 +140,7 @@
+ src_yoffset * im->linesize +
+ src_xoffset * im->pixelsize;
+ #endif
+-
++#if TKMAJORMINOR < 8004 /* Tk < 8.4.0 */
+ if (strcmp(im->mode, "RGBA") == 0) {
+ /* Copy non-transparent pixels to photo image */
+ int x, y;
+@@ -193,6 +193,16 @@
+ /* Copy opaque block to photo image, and leave the rest to TK */
+ Tk_PhotoPutBlock(photo, &block, 0, 0, block.width, block.height);
+
++#else /* Tk >= 8.4.0 */
++ Tk_PhotoPutBlock(photo, &block, 0, 0, block.width, block.height,
++ TK_PHOTO_COMPOSITE_SET);
++ if (strcmp(im->mode, "RGBA") == 0)
++ /* Tk workaround: we need apply ToggleComplexAlphaIfNeeded */
++ /* (fixed in Tk 8.5a3) */
++ Tk_PhotoSetSize(photo, block.width, block.height);
++#endif
++
++
+ return TCL_OK;
+ }
+
diff --git a/Build/source/utils/asymptote/patches/bison.patch b/Build/source/utils/asymptote/patches/bison.patch
new file mode 100644
index 00000000000..5f7e4fe1dcd
--- /dev/null
+++ b/Build/source/utils/asymptote/patches/bison.patch
@@ -0,0 +1,206 @@
+diff -ru bison-2.0a/data/yacc.c bison-2.0aJ/data/yacc.c
+--- bison-2.0a/data/yacc.c 2005-05-21 11:12:32.000000000 -0600
++++ bison-2.0aJ/data/yacc.c 2005-06-30 18:14:16.509158136 -0600
+@@ -237,7 +237,7 @@
+
+ # ifdef YYSTACK_ALLOC
+ /* Pacify GCC's `empty if-body' warning. */
+-# define YYSTACK_FREE(Ptr) do { /* empty */; } while (0)
++# define YYSTACK_FREE(Ptr) { /* empty */; }
+ # ifndef YYSTACK_ALLOC_MAXIMUM
+ /* The OS might guarantee only one guard page at the bottom of the stack,
+ and a page size can be as small as 4096 bytes. So we cannot safely
+@@ -291,19 +291,20 @@
+ /* Copy COUNT objects from FROM to TO. The source and destination do
+ not overlap. */
+ # ifndef YYCOPY
+-# if defined (__GNUC__) && 1 < __GNUC__
++# if defined (__GNUC__)
++# if 1 < __GNUC__
+ # define YYCOPY(To, From, Count) \
+ __builtin_memcpy (To, From, (Count) * sizeof (*(From)))
+-# else
++# endif
++# endif
++# endif
++# ifndef YYCOPY
+ # define YYCOPY(To, From, Count) \
+- do \
+ { \
+ YYSIZE_T yyi; \
+ for (yyi = 0; yyi < (Count); yyi++) \
+ (To)[yyi] = (From)[yyi]; \
+- } \
+- while (0)
+-# endif
++ }
+ # endif
+
+ /* Relocate STACK from its old location to the new one. The
+@@ -312,15 +313,13 @@
+ stack. Advance YYPTR to a properly aligned location for the next
+ stack. */
+ # define YYSTACK_RELOCATE(Stack) \
+- do \
+ { \
+ YYSIZE_T yynewbytes; \
+ YYCOPY (&yyptr->Stack, Stack, yysize); \
+ Stack = &yyptr->Stack; \
+ yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \
+ yyptr += yynewbytes / sizeof (*yyptr); \
+- } \
+- while (0)
++ }
+
+ #endif
+
+@@ -487,6 +486,7 @@
+ #define YYACCEPT goto yyacceptlab
+ #define YYABORT goto yyabortlab
+ #define YYERROR goto yyerrorlab
++int yy_false=false; /* Used to suppress compiler warning about unused label */
+
+
+ /* Like YYERROR except do call yyerror. This remains here temporarily
+@@ -498,7 +498,7 @@
+ #define YYRECOVERING() (!!yyerrstatus)
+
+ #define YYBACKUP(Token, Value) \
+-do \
++{ \
+ if (yychar == YYEMPTY && yylen == 1) \
+ { \
+ yychar = (Token); \
+@@ -512,7 +512,7 @@
+ yyerror (]b4_yyerror_args[_("syntax error: cannot back up")); \
+ YYERROR; \
+ } \
+-while (0)
++}
+
+
+ #define YYTERROR 1
+@@ -526,7 +526,7 @@
+ #define YYRHSLOC(Rhs, K) ((Rhs)[K])
+ #ifndef YYLLOC_DEFAULT
+ # define YYLLOC_DEFAULT(Current, Rhs, N) \
+- do \
++ { \
+ if (N) \
+ { \
+ (Current).first_line = YYRHSLOC (Rhs, 1).first_line; \
+@@ -541,7 +541,7 @@
+ (Current).first_column = (Current).last_column = \
+ YYRHSLOC (Rhs, 0).last_column; \
+ } \
+- while (0)
++ }
+ #endif
+
+
+@@ -550,7 +550,7 @@
+ we won't break user code: when these are the locations we know. */
+
+ #ifndef YY_LOCATION_PRINT
+-# if YYLTYPE_IS_TRIVIAL
++# ifdef YYLTYPE_IS_TRIVIAL
+ # define YY_LOCATION_PRINT(File, Loc) \
+ fprintf (File, "%d.%d-%d.%d", \
+ (Loc).first_line, (Loc).first_column, \
+@@ -578,13 +578,13 @@
+ # endif
+
+ # define YYDPRINTF(Args) \
+-do { \
++{ \
+ if (yydebug) \
+ YYFPRINTF Args; \
+-} while (0)
++}
+
+ # define YY_SYMBOL_PRINT(Title, Type, Value, Location) \
+-do { \
++{ \
+ if (yydebug) \
+ { \
+ YYFPRINTF (stderr, "%s ", Title); \
+@@ -592,7 +592,7 @@
+ Type, Value]b4_location_if([, Location])[); \
+ YYFPRINTF (stderr, "\n"); \
+ } \
+-} while (0)
++}
+
+ /*------------------------------------------------------------------.
+ | yy_stack_print -- Print the state stack from its BOTTOM up to its |
+@@ -610,10 +610,10 @@
+ }
+
+ # define YY_STACK_PRINT(Bottom, Top) \
+-do { \
++{ \
+ if (yydebug) \
+ yy_stack_print ((Bottom), (Top)); \
+-} while (0)
++}
+
+
+ /*------------------------------------------------.
+@@ -634,10 +634,10 @@
+ }
+
+ # define YY_REDUCE_PRINT(Rule) \
+-do { \
++{ \
+ if (yydebug) \
+ yy_reduce_print (Rule); \
+-} while (0)
++}
+
+ /* Nonzero means print parse trace. It is left uninitialized so that
+ multiple parsers can coexist. */
+@@ -826,7 +826,7 @@
+
+ /* When reducing, the number of symbols on the RHS of the reduced
+ rule. */
+- int yylen;
++ int yylen=0;
+
+ YYDPRINTF ((stderr, "Starting parse\n"));
+
+@@ -874,7 +874,7 @@
+ yyssp++;
+
+ yysetstate:
+- *yyssp = yystate;
++ *yyssp = (short int) yystate;
+
+ if (yyss + yystacksize - 1 <= yyssp)
+ {
+@@ -1222,12 +1222,6 @@
+ `---------------------------------------------------*/
+ yyerrorlab:
+
+- /* Pacify compilers like GCC when the user code never invokes
+- YYERROR and the label yyerrorlab therefore never appears in user
+- code. */
+- if (0)
+- goto yyerrorlab;
+-
+ ]b4_location_if([[ yyerror_range[0] = yylsp[1-yylen];
+ yylsp -= yylen;
+ ]])[yyvsp -= yylen;
+@@ -1297,6 +1291,13 @@
+ `-----------------------------------*/
+ yyabortlab:
+ yyresult = 1;
++
++ /* Pacify compilers like GCC when the user code never invokes
++ YYERROR and the label yyerrorlab therefore never appears in user
++ code. */
++ if (yy_false)
++ goto yyerrorlab;
++
+ goto yyreturn;
+
+ #ifndef yyoverflow
diff --git a/Build/source/utils/asymptote/patches/cygwin_glu.patch b/Build/source/utils/asymptote/patches/cygwin_glu.patch
new file mode 100644
index 00000000000..0125a4bca60
--- /dev/null
+++ b/Build/source/utils/asymptote/patches/cygwin_glu.patch
@@ -0,0 +1,87 @@
+--- w32api.orig/GL/glu.h 2008-09-26 08:26:56.000000000 -0600
++++ w32api/GL/glu.h 2008-09-27 23:39:33.000000000 -0600
+@@ -43,6 +44,10 @@
+
+ /*************************************************************/
+
++/* Extensionsx */
++#define GLU_EXT_object_space_tess 1
++#define GLU_EXT_nurbs_tessellator 1
++
+ /* Boolean */
+ #define GLU_FALSE 0
+ #define GLU_TRUE 1
+@@ -50,6 +55,7 @@
+ /* Version */
+ #define GLU_VERSION_1_1 1
+ #define GLU_VERSION_1_2 1
++#define GLU_VERSION_1_3 1
+
+ /* StringName */
+ #define GLU_VERSION 100800
+@@ -66,6 +72,34 @@
+ #define GLU_OUTLINE_POLYGON 100240
+ #define GLU_OUTLINE_PATCH 100241
+
++/* NurbsCallback */
++#define GLU_NURBS_ERROR 100103
++#define GLU_ERROR 100103
++#define GLU_NURBS_BEGIN 100164
++#define GLU_NURBS_BEGIN_EXT 100164
++#define GLU_NURBS_VERTEX 100165
++#define GLU_NURBS_VERTEX_EXT 100165
++#define GLU_NURBS_NORMAL 100166
++#define GLU_NURBS_NORMAL_EXT 100166
++#define GLU_NURBS_COLOR 100167
++#define GLU_NURBS_COLOR_EXT 100167
++#define GLU_NURBS_TEXTURE_COORD 100168
++#define GLU_NURBS_TEX_COORD_EXT 100168
++#define GLU_NURBS_END 100169
++#define GLU_NURBS_END_EXT 100169
++#define GLU_NURBS_BEGIN_DATA 100170
++#define GLU_NURBS_BEGIN_DATA_EXT 100170
++#define GLU_NURBS_VERTEX_DATA 100171
++#define GLU_NURBS_VERTEX_DATA_EXT 100171
++#define GLU_NURBS_NORMAL_DATA 100172
++#define GLU_NURBS_NORMAL_DATA_EXT 100172
++#define GLU_NURBS_COLOR_DATA 100173
++#define GLU_NURBS_COLOR_DATA_EXT 100173
++#define GLU_NURBS_TEXTURE_COORD_DATA 100174
++#define GLU_NURBS_TEX_COORD_DATA_EXT 100174
++#define GLU_NURBS_END_DATA 100175
++#define GLU_NURBS_END_DATA_EXT 100175
++
+ /* NurbsError */
+ #define GLU_NURBS_ERROR1 100251
+ #define GLU_NURBS_ERROR2 100252
+@@ -114,8 +148,18 @@
+ #define GLU_SAMPLING_METHOD 100205
+ #define GLU_U_STEP 100206
+ #define GLU_V_STEP 100207
++#define GLU_NURBS_MODE 100160
++#define GLU_NURBS_MODE_EXT 100160
++#define GLU_NURBS_TESSELLATOR 100161
++#define GLU_NURBS_TESSELLATOR_EXT 100161
++#define GLU_NURBS_RENDERER 100162
++#define GLU_NURBS_RENDERER_EXT 100162
+
+ /* NurbsSampling */
++#define GLU_OBJECT_PARAMETRIC_ERROR 100208
++#define GLU_OBJECT_PARAMETRIC_ERROR_EXT 100208
++#define GLU_OBJECT_PATH_LENGTH 100209
++#define GLU_OBJECT_PATH_LENGTH_EXT 100209
+ #define GLU_PATH_LENGTH 100215
+ #define GLU_PARAMETRIC_ERROR 100216
+ #define GLU_DOMAIN_DISTANCE 100217
+@@ -220,7 +260,11 @@
+ #define GLU_TESS_MAX_COORD 1.0e150
+
+ /* Internal convenience typedefs */
++#ifdef __cplusplus
+ typedef void (APIENTRY *_GLUfuncptr)();
++#else
++typedef void (APIENTRY *_GLUfuncptr)(GLvoid);
++#endif
+
+ GLAPI void APIENTRY gluBeginCurve (GLUnurbs* nurb);
+ GLAPI void APIENTRY gluBeginPolygon (GLUtesselator* tess);
diff --git a/Build/source/utils/asymptote/patches/cygwin_xdr.patch b/Build/source/utils/asymptote/patches/cygwin_xdr.patch
new file mode 100644
index 00000000000..4dae5b6eb27
--- /dev/null
+++ b/Build/source/utils/asymptote/patches/cygwin_xdr.patch
@@ -0,0 +1,447 @@
+diff -ru rpc.broken/auth.h rpc/auth.h
+--- rpc.broken/auth.h 2005-03-10 14:32:52.000000000 -0700
++++ rpc/auth.h 2005-08-02 02:09:08.000000000 -0600
+@@ -62,7 +62,7 @@
+ AUTH_FAILED=7 /* some unknown reason */
+ };
+
+-#if (mc68000 || sparc || vax || i386)
++#if (mc68000 || sparc || vax || __i386__)
+ typedef u_long u_int32; /* 32-bit unsigned integers */
+ #endif
+
+diff -ru rpc.broken/xdr.h rpc/xdr.h
+--- rpc.broken/xdr.h 2005-03-10 14:32:54.000000000 -0700
++++ rpc/xdr.h 2005-08-02 01:56:46.000000000 -0600
+@@ -1,4 +1,3 @@
+-/* @(#)xdr.h 2.2 88/07/29 4.0 RPCSRC */
+ /*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+@@ -6,28 +5,27 @@
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+- *
++ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+- *
++ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+- *
++ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+- *
++ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+- *
++ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California 94043
+ */
+-/* @(#)xdr.h 1.19 87/04/22 SMI */
+
+ /*
+ * xdr.h, External Data Representation Serialization Routines.
+@@ -35,8 +33,17 @@
+ * Copyright (C) 1984, Sun Microsystems, Inc.
+ */
+
+-#ifndef __XDR_HEADER__
+-#define __XDR_HEADER__
++#ifndef _RPC_XDR_H
++#define _RPC_XDR_H 1
++
++#include <features.h>
++#include <sys/types.h>
++#include <rpc/types.h>
++
++/* We need FILE. */
++#include <stdio.h>
++
++__BEGIN_DECLS
+
+ /*
+ * XDR provides a conventional way for converting between C data
+@@ -47,10 +54,10 @@
+ *
+ * Each data type provides a single procedure which takes two arguments:
+ *
+- * bool_t
+- * xdrproc(xdrs, argresp)
+- * XDR *xdrs;
+- * <type> *argresp;
++ * bool_t
++ * xdrproc(xdrs, argresp)
++ * XDR *xdrs;
++ * <type> *argresp;
+ *
+ * xdrs is an instance of a XDR handle, to which or from which the data
+ * type is to be converted. argresp is a pointer to the structure to be
+@@ -74,17 +81,66 @@
+ * request.
+ */
+ enum xdr_op {
+- XDR_ENCODE=0,
+- XDR_DECODE=1,
+- XDR_FREE=2
++ XDR_ENCODE = 0,
++ XDR_DECODE = 1,
++ XDR_FREE = 2
+ };
+
+ /*
+ * This is the number of bytes per unit of external data.
+ */
+ #define BYTES_PER_XDR_UNIT (4)
++/*
++ * This only works if the above is a power of 2. But it's defined to be
++ * 4 by the appropriate RFCs. So it will work. And it's normally quicker
++ * than the old routine.
++ */
++#if 1
++#define RNDUP(x) (((x) + BYTES_PER_XDR_UNIT - 1) & ~(BYTES_PER_XDR_UNIT - 1))
++#else /* this is the old routine */
+ #define RNDUP(x) ((((x) + BYTES_PER_XDR_UNIT - 1) / BYTES_PER_XDR_UNIT) \
+ * BYTES_PER_XDR_UNIT)
++#endif
++
++/*
++ * The XDR handle.
++ * Contains operation which is being applied to the stream,
++ * an operations vector for the particular implementation (e.g. see xdr_mem.c),
++ * and two private fields for the use of the particular implementation.
++ */
++typedef struct XDR XDR;
++struct XDR
++ {
++ enum xdr_op x_op; /* operation; fast additional param */
++ struct xdr_ops
++ {
++ bool_t (*x_getlong) (XDR *__xdrs, long *__lp);
++ /* get a long from underlying stream */
++ bool_t (*x_putlong) (XDR *__xdrs, __const long *__lp);
++ /* put a long to " */
++ bool_t (*x_getbytes) (XDR *__xdrs, caddr_t __addr, u_int __len);
++ /* get some bytes from " */
++ bool_t (*x_putbytes) (XDR *__xdrs, __const char *__addr, u_int __len);
++ /* put some bytes to " */
++ u_int (*x_getpostn) (__const XDR *__xdrs);
++ /* returns bytes off from beginning */
++ bool_t (*x_setpostn) (XDR *__xdrs, u_int __pos);
++ /* lets you reposition the stream */
++ int32_t *(*x_inline) (XDR *__xdrs, u_int __len);
++ /* buf quick ptr to buffered data */
++ void (*x_destroy) (XDR *__xdrs);
++ /* free privates of this xdr_stream */
++ bool_t (*x_getint32) (XDR *__xdrs, int32_t *__ip);
++ /* get a int from underlying stream */
++ bool_t (*x_putint32) (XDR *__xdrs, __const int32_t *__ip);
++ /* put a int to " */
++ }
++ *x_ops;
++ caddr_t x_public; /* users' data */
++ caddr_t x_private; /* pointer to private data */
++ caddr_t x_base; /* private used for position info */
++ u_int x_handy; /* extra private word */
++ };
+
+ /*
+ * A xdrproc_t exists for each data type which is to be encoded or decoded.
+@@ -93,43 +149,31 @@
+ * The opaque pointer generally points to a structure of the data type
+ * to be decoded. If this pointer is 0, then the type routines should
+ * allocate dynamic storage of the appropriate size and return it.
+- * bool_t (*xdrproc_t)(XDR *, caddr_t *);
++ * bool_t (*xdrproc_t)(XDR *, caddr_t *);
+ */
+-typedef bool_t (*xdrproc_t)();
++typedef bool_t (*xdrproc_t) (XDR *, void *,...);
+
+-/*
+- * The XDR handle.
+- * Contains operation which is being applied to the stream,
+- * an operations vector for the paticular implementation (e.g. see xdr_mem.c),
+- * and two private fields for the use of the particular impelementation.
+- */
+-typedef struct {
+- enum xdr_op x_op; /* operation; fast additional param */
+- struct xdr_ops {
+- bool_t (*x_getlong)(); /* get a long from underlying stream */
+- bool_t (*x_putlong)(); /* put a long to " */
+- bool_t (*x_getbytes)();/* get some bytes from " */
+- bool_t (*x_putbytes)();/* put some bytes to " */
+- u_int (*x_getpostn)();/* returns bytes off from beginning */
+- bool_t (*x_setpostn)();/* lets you reposition the stream */
+- long * (*x_inline)(); /* buf quick ptr to buffered data */
+- void (*x_destroy)(); /* free privates of this xdr_stream */
+- } *x_ops;
+- caddr_t x_public; /* users' data */
+- caddr_t x_private; /* pointer to private data */
+- caddr_t x_base; /* private used for position info */
+- int x_handy; /* extra private word */
+-} XDR;
+
+ /*
+ * Operations defined on a XDR handle
+ *
+- * XDR *xdrs;
+- * long *longp;
+- * caddr_t addr;
+- * u_int len;
+- * u_int pos;
+- */
++ * XDR *xdrs;
++ * int32_t *int32p;
++ * long *longp;
++ * caddr_t addr;
++ * u_int len;
++ * u_int pos;
++ */
++#define XDR_GETINT32(xdrs, int32p) \
++ (*(xdrs)->x_ops->x_getint32)(xdrs, int32p)
++#define xdr_getint32(xdrs, int32p) \
++ (*(xdrs)->x_ops->x_getint32)(xdrs, int32p)
++
++#define XDR_PUTINT32(xdrs, int32p) \
++ (*(xdrs)->x_ops->x_putint32)(xdrs, int32p)
++#define xdr_putint32(xdrs, int32p) \
++ (*(xdrs)->x_ops->x_putint32)(xdrs, int32p)
++
+ #define XDR_GETLONG(xdrs, longp) \
+ (*(xdrs)->x_ops->x_getlong)(xdrs, longp)
+ #define xdr_getlong(xdrs, longp) \
+@@ -165,12 +209,16 @@
+ #define xdr_inline(xdrs, len) \
+ (*(xdrs)->x_ops->x_inline)(xdrs, len)
+
+-#define XDR_DESTROY(xdrs) \
+- if ((xdrs)->x_ops->x_destroy) \
+- (*(xdrs)->x_ops->x_destroy)(xdrs)
+-#define xdr_destroy(xdrs) \
+- if ((xdrs)->x_ops->x_destroy) \
+- (*(xdrs)->x_ops->x_destroy)(xdrs)
++#define XDR_DESTROY(xdrs) \
++ do { \
++ if ((xdrs)->x_ops->x_destroy) \
++ (*(xdrs)->x_ops->x_destroy)(xdrs); \
++ } while (0)
++#define xdr_destroy(xdrs) \
++ do { \
++ if ((xdrs)->x_ops->x_destroy) \
++ (*(xdrs)->x_ops->x_destroy)(xdrs); \
++ } while (0)
+
+ /*
+ * Support struct for discriminated unions.
+@@ -183,93 +231,143 @@
+ * If there is no match and no default routine it is an error.
+ */
+ #define NULL_xdrproc_t ((xdrproc_t)0)
+-struct xdr_discrim {
+- int value;
+- xdrproc_t proc;
++struct xdr_discrim
++{
++ int value;
++ xdrproc_t proc;
+ };
+
+ /*
+- * In-line routines for fast encode/decode of primitve data types.
++ * Inline routines for fast encode/decode of primitive data types.
+ * Caveat emptor: these use single memory cycles to get the
+ * data from the underlying buffer, and will fail to operate
+ * properly if the data is not aligned. The standard way to use these
+ * is to say:
+- * if ((buf = XDR_INLINE(xdrs, count)) == NULL)
+- * return (FALSE);
+- * <<< macro calls >>>
++ * if ((buf = XDR_INLINE(xdrs, count)) == NULL)
++ * return (FALSE);
++ * <<< macro calls >>>
+ * where ``count'' is the number of bytes of data occupied
+ * by the primitive data types.
+ *
+ * N.B. and frozen for all time: each data type here uses 4 bytes
+ * of external representation.
+ */
+-#define IXDR_GET_LONG(buf) ((long)ntohl((u_long)*(buf)++))
+-#define IXDR_PUT_LONG(buf, v) (*(buf)++ = (long)htonl((u_long)v))
+
+-#define IXDR_GET_BOOL(buf) ((bool_t)IXDR_GET_LONG(buf))
+-#define IXDR_GET_ENUM(buf, t) ((t)IXDR_GET_LONG(buf))
+-#define IXDR_GET_U_LONG(buf) ((u_long)IXDR_GET_LONG(buf))
+-#define IXDR_GET_SHORT(buf) ((short)IXDR_GET_LONG(buf))
+-#define IXDR_GET_U_SHORT(buf) ((u_short)IXDR_GET_LONG(buf))
+-
+-#define IXDR_PUT_BOOL(buf, v) IXDR_PUT_LONG((buf), ((long)(v)))
+-#define IXDR_PUT_ENUM(buf, v) IXDR_PUT_LONG((buf), ((long)(v)))
+-#define IXDR_PUT_U_LONG(buf, v) IXDR_PUT_LONG((buf), ((long)(v)))
+-#define IXDR_PUT_SHORT(buf, v) IXDR_PUT_LONG((buf), ((long)(v)))
+-#define IXDR_PUT_U_SHORT(buf, v) IXDR_PUT_LONG((buf), ((long)(v)))
++#define IXDR_GET_INT32(buf) ((int32_t)ntohl((uint32_t)*(buf)++))
++#define IXDR_PUT_INT32(buf, v) (*(buf)++ = (int32_t)htonl((uint32_t)(v)))
++#define IXDR_GET_U_INT32(buf) ((uint32_t)IXDR_GET_INT32(buf))
++#define IXDR_PUT_U_INT32(buf, v) IXDR_PUT_INT32(buf, (int32_t)(v))
++
++/* WARNING: The IXDR_*_LONG defines are removed by Sun for new platforms
++ * and shouldn't be used any longer. Code which use this defines or longs
++ * in the RPC code will not work on 64bit Solaris platforms !
++ */
++#define IXDR_GET_LONG(buf) ((long)IXDR_GET_U_INT32(buf))
++#define IXDR_PUT_LONG(buf, v) ((long)IXDR_PUT_INT32(buf, (long)(v)))
++#define IXDR_GET_U_LONG(buf) ((u_long)IXDR_GET_LONG(buf))
++#define IXDR_PUT_U_LONG(buf, v) IXDR_PUT_LONG(buf, (long)(v))
++
++
++#define IXDR_GET_BOOL(buf) ((bool_t)IXDR_GET_LONG(buf))
++#define IXDR_GET_ENUM(buf, t) ((t)IXDR_GET_LONG(buf))
++#define IXDR_GET_SHORT(buf) ((short)IXDR_GET_LONG(buf))
++#define IXDR_GET_U_SHORT(buf) ((u_short)IXDR_GET_LONG(buf))
++
++#define IXDR_PUT_BOOL(buf, v) IXDR_PUT_LONG(buf, (long)(v))
++#define IXDR_PUT_ENUM(buf, v) IXDR_PUT_LONG(buf, (long)(v))
++#define IXDR_PUT_SHORT(buf, v) IXDR_PUT_LONG(buf, (long)(v))
++#define IXDR_PUT_U_SHORT(buf, v) IXDR_PUT_LONG(buf, (long)(v))
+
+ /*
+ * These are the "generic" xdr routines.
+- */
+-extern bool_t xdr_void();
+-extern bool_t xdr_int();
+-extern bool_t xdr_u_int();
+-extern bool_t xdr_long();
+-extern bool_t xdr_u_long();
+-extern bool_t xdr_short();
+-extern bool_t xdr_u_short();
+-extern bool_t xdr_int64_t();
+-extern bool_t xdr_u_int64_t();
+-extern bool_t xdr_bool();
+-extern bool_t xdr_enum();
+-extern bool_t xdr_array();
+-extern bool_t xdr_bytes();
+-extern bool_t xdr_opaque();
+-extern bool_t xdr_string();
+-extern bool_t xdr_union();
+-extern bool_t xdr_char();
+-extern bool_t xdr_u_char();
+-extern bool_t xdr_vector();
+-extern bool_t xdr_float();
+-extern bool_t xdr_double();
+-extern bool_t xdr_reference();
+-extern bool_t xdr_pointer();
+-extern bool_t xdr_wrapstring();
++ * None of these can have const applied because it's not possible to
++ * know whether the call is a read or a write to the passed parameter
++ * also, the XDR structure is always updated by some of these calls.
++ */
++extern bool_t xdr_void (void);
++extern bool_t xdr_short (XDR *__xdrs, short *__sp);
++extern bool_t xdr_u_short (XDR *__xdrs, u_short *__usp);
++extern bool_t xdr_int (XDR *__xdrs, int *__ip);
++extern bool_t xdr_u_int (XDR *__xdrs, u_int *__up);
++extern bool_t xdr_long (XDR *__xdrs, long *__lp);
++extern bool_t xdr_u_long (XDR *__xdrs, u_long *__ulp);
++extern bool_t xdr_int8_t (XDR *__xdrs, int8_t *__ip);
++extern bool_t xdr_uint8_t (XDR *__xdrs, uint8_t *__up);
++extern bool_t xdr_int16_t (XDR *__xdrs, int16_t *__ip);
++extern bool_t xdr_uint16_t (XDR *__xdrs, uint16_t *__up);
++extern bool_t xdr_int32_t (XDR *__xdrs, int32_t *__ip);
++extern bool_t xdr_uint32_t (XDR *__xdrs, uint32_t *__up);
++extern bool_t xdr_int64_t (XDR *__xdrs, int64_t *__ip);
++extern bool_t xdr_uint64_t (XDR *__xdrs, uint64_t *__up);
++extern bool_t xdr_bool (XDR *__xdrs, bool_t *__bp);
++extern bool_t xdr_enum (XDR *__xdrs, enum_t *__ep);
++extern bool_t xdr_array (XDR * _xdrs, caddr_t *__addrp, u_int *__sizep,
++ u_int __maxsize, u_int __elsize, xdrproc_t __elproc)
++ ;
++extern bool_t xdr_bytes (XDR *__xdrs, char **__cpp, u_int *__sizep,
++ u_int __maxsize);
++extern bool_t xdr_opaque (XDR *__xdrs, caddr_t __cp, u_int __cnt);
++extern bool_t xdr_string (XDR *__xdrs, char **__cpp, u_int __maxsize);
++extern bool_t xdr_union (XDR *__xdrs, enum_t *__dscmp, char *__unp,
++ __const struct xdr_discrim *__choices,
++ xdrproc_t dfault);
++extern bool_t xdr_char (XDR *__xdrs, char *__cp);
++extern bool_t xdr_u_char (XDR *__xdrs, u_char *__cp);
++extern bool_t xdr_vector (XDR *__xdrs, char *__basep, u_int __nelem,
++ u_int __elemsize, xdrproc_t __xdr_elem);
++extern bool_t xdr_float (XDR *__xdrs, float *__fp);
++extern bool_t xdr_double (XDR *__xdrs, double *__dp);
++extern bool_t xdr_reference (XDR *__xdrs, caddr_t *__xpp, u_int __size,
++ xdrproc_t __proc);
++extern bool_t xdr_pointer (XDR *__xdrs, char **__objpp,
++ u_int __obj_size, xdrproc_t __xdr_obj);
++extern bool_t xdr_wrapstring (XDR *__xdrs, char **__cpp);
++extern u_long xdr_sizeof (xdrproc_t, void *);
+
+ /*
+ * Common opaque bytes objects used by many rpc protocols;
+ * declared here due to commonality.
+ */
+-#define MAX_NETOBJ_SZ 1024
+-struct netobj {
+- u_int n_len;
+- char *n_bytes;
++#define MAX_NETOBJ_SZ 1024
++struct netobj
++{
++ u_int n_len;
++ char *n_bytes;
+ };
+ typedef struct netobj netobj;
+-extern bool_t xdr_netobj();
++extern bool_t xdr_netobj (XDR *__xdrs, struct netobj *__np);
+
+ /*
+ * These are the public routines for the various implementations of
+ * xdr streams.
+ */
+-extern void xdrmem_create(); /* XDR using memory buffers */
+-extern void xdrstdio_create(); /* XDR using stdio library */
+-extern void xdrrec_create(); /* XDR pseudo records for tcp */
+-extern bool_t xdrrec_endofrecord(); /* make end of xdr record */
+-extern bool_t xdrrec_skiprecord(); /* move to beginning of next record */
+-extern bool_t xdrrec_eof(); /* true if no more input */
++
++/* XDR using memory buffers */
++extern void xdrmem_create (XDR *__xdrs, __const caddr_t __addr,
++ u_int __size, enum xdr_op __xop);
++
++/* XDR using stdio library */
++extern void xdrstdio_create (XDR *__xdrs, FILE *__file, enum xdr_op __xop)
++ ;
++
++/* XDR pseudo records for tcp */
++extern void xdrrec_create (XDR *__xdrs, u_int __sendsize,
++ u_int __recvsize, caddr_t __tcp_handle,
++ int (*__readit) (char *, char *, int),
++ int (*__writeit) (char *, char *, int));
++
++/* make end of xdr record */
++extern bool_t xdrrec_endofrecord (XDR *__xdrs, bool_t __sendnow);
++
++/* move to beginning of next record */
++extern bool_t xdrrec_skiprecord (XDR *__xdrs);
++
++/* true if no more input */
++extern bool_t xdrrec_eof (XDR *__xdrs);
+
+ /* free memory buffers for xdr */
+-extern void xdr_free(xdrproc_t proc, char *objp);
++extern void xdr_free (xdrproc_t __proc, char *__objp);
++
++__END_DECLS
+
+-#endif /* !__XDR_HEADER__ */
++#endif /* rpc/xdr.h */
diff --git a/Build/source/utils/asymptote/patches/dvipdf b/Build/source/utils/asymptote/patches/dvipdf
new file mode 100755
index 00000000000..5c98e943206
--- /dev/null
+++ b/Build/source/utils/asymptote/patches/dvipdf
@@ -0,0 +1,54 @@
+#!/bin/sh
+# $Id: dvipdf 3949 2009-02-04 05:53:23Z jcbowman $
+# Convert DVI to PDF.
+#
+# Please contact Andrew Ford <A.Ford@ford-mason.co.uk> with any questions
+# about this file.
+#
+# Based on ps2pdf
+
+# This definition is changed on install to match the
+# executable name set in the makefile
+GS_EXECUTABLE=gs
+
+
+OPTIONS=""
+DVIPSOPTIONS=""
+while true
+do
+ case "$1" in
+ -R*) DVIPSOPTIONS="$DVIPSOPTIONS $1";;
+ -z) DVIPSOPTIONS="$DVIPSOPTIONS -z" ;;
+ -pp) shift; DVIPSOPTIONS="$DVIPSOPTIONS -pp $1" ;;
+ -p) shift; DVIPSOPTIONS="$DVIPSOPTIONS -p $1" ;;
+ -t) shift; DVIPSOPTIONS="$DVIPSOPTIONS -t $1" ;;
+ -T) shift; DVIPSOPTIONS="$DVIPSOPTIONS -T $1" ;;
+ -l) shift; DVIPSOPTIONS="$DVIPSOPTIONS -l $1" ;;
+ -?*) OPTIONS="$OPTIONS $1" ;;
+ *) break ;;
+ esac
+ shift
+done
+
+if [ $# -lt 1 -o $# -gt 2 ]; then
+ echo "Usage: `basename $0` [options...] input.dvi [output.pdf]" 1>&2
+ exit 1
+fi
+
+infile=$1;
+
+if [ $# -eq 1 ]
+then
+ case "${infile}" in
+ *.dvi) base=`basename "${infile}" .dvi` ;;
+ *) base=`basename "${infile}"` ;;
+ esac
+ outfile="${base}".pdf
+else
+ outfile=$2
+fi
+
+# We have to include the options twice because -I only takes effect if it
+# appears before other options.
+exec dvips $DVIPSOPTIONS -q -f "$infile" | $GS_EXECUTABLE $OPTIONS -q -dNOPAUSE -dBATCH -sDEVICE=pdfwrite -sstdout=%stderr -sOutputFile="$outfile" $OPTIONS -c .setpdfwrite -
+
diff --git a/Build/source/utils/asymptote/patches/flex.patch b/Build/source/utils/asymptote/patches/flex.patch
new file mode 100644
index 00000000000..1e9137fc172
--- /dev/null
+++ b/Build/source/utils/asymptote/patches/flex.patch
@@ -0,0 +1,205 @@
+diff -ru flex-2.5.31/flex.skl flex-2.5.31J/flex.skl
+--- flex-2.5.31/flex.skl Mon Mar 31 18:51:38 2003
++++ flex-2.5.31J/flex.skl Sat Nov 13 14:00:09 2004
+@@ -488,7 +488,7 @@
+
+ #ifndef YY_TYPEDEF_YY_SIZE_T
+ #define YY_TYPEDEF_YY_SIZE_T
+-typedef unsigned int yy_size_t;
++typedef size_t yy_size_t;
+ #endif
+
+ #ifndef YY_STRUCT_YY_BUFFER_STATE
+@@ -515,7 +515,7 @@
+ /* Number of characters read into yy_ch_buf, not including EOB
+ * characters.
+ */
+- int yy_n_chars;
++ size_t yy_n_chars;
+
+ /* Whether we "own" the buffer - i.e., we know we created it,
+ * and can realloc() it to grow it, and should free() it to
+@@ -604,7 +604,7 @@
+ %not-for-header
+ /* yy_hold_char holds the character lost when yytext is formed. */
+ static char yy_hold_char;
+-static int yy_n_chars; /* number of characters read into yy_ch_buf */
++static size_t yy_n_chars; /* number of characters read into yy_ch_buf */
+ int yyleng;
+
+ /* Points to current character in buffer. */
+@@ -641,7 +641,7 @@
+
+ YY_BUFFER_STATE yy_scan_buffer M4_YY_PARAMS( char *base, yy_size_t size M4_YY_PROTO_LAST_ARG );
+ YY_BUFFER_STATE yy_scan_string M4_YY_PARAMS( yyconst char *yy_str M4_YY_PROTO_LAST_ARG );
+-YY_BUFFER_STATE yy_scan_bytes M4_YY_PARAMS( yyconst char *bytes, int len M4_YY_PROTO_LAST_ARG );
++YY_BUFFER_STATE yy_scan_bytes M4_YY_PARAMS( yyconst char *bytes, size_t len M4_YY_PROTO_LAST_ARG );
+
+ %endif
+
+@@ -758,7 +758,7 @@
+ size_t yy_buffer_stack_max; /**< capacity of stack. */
+ YY_BUFFER_STATE * yy_buffer_stack; /**< Stack as an array. */
+ char yy_hold_char;
+- int yy_n_chars;
++ size_t yy_n_chars;
+ int yyleng_r;
+ char *yy_c_buf_p;
+ int yy_init;
+@@ -938,7 +938,7 @@
+ %not-for-header
+ m4_ifdef( [[M4_YY_NO_UNPUT]],,
+ [[
+- static void yyunput M4_YY_PARAMS( int c, char *buf_ptr M4_YY_PROTO_LAST_ARG);
++ void yyunput M4_YY_PARAMS( int c, char *buf_ptr M4_YY_PROTO_LAST_ARG);
+ ]])
+ %ok-for-header
+ %endif
+@@ -1248,7 +1248,7 @@
+ yy_load_buffer_state( M4_YY_CALL_ONLY_ARG );
+ }
+
+- while ( 1 ) /* loops until end-of-file is reached */
++ for ( ;; ) /* loops until end-of-file is reached */
+ {
+ %% [8.0] yymore()-related code goes here
+ yy_cp = YY_G(yy_c_buf_p);
+@@ -1580,7 +1580,7 @@
+
+ if ( b->yy_is_our_buffer )
+ {
+- int new_size = b->yy_buf_size * 2;
++ size_t new_size = b->yy_buf_size * 2;
+
+ if ( new_size <= 0 )
+ b->yy_buf_size += b->yy_buf_size / 8;
+@@ -1694,7 +1694,7 @@
+ %if-c-only
+ m4_ifdef( [[M4_YY_NO_UNPUT]],,
+ [[
+- static void yyunput YYFARGS2( int,c, register char *,yy_bp)
++ void yyunput YYFARGS2( int,c, register char *,yy_bp)
+ %endif
+ %if-c++-only
+ void yyFlexLexer::yyunput( int c, register char* yy_bp)
+@@ -1711,7 +1711,7 @@
+ if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 )
+ { /* need to shift things up to make room */
+ /* +2 for EOB chars. */
+- register int number_to_move = YY_G(yy_n_chars) + 2;
++ register size_t number_to_move = YY_G(yy_n_chars) + 2;
+ register char *dest = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[
+ YY_CURRENT_BUFFER_LVALUE->yy_buf_size + 2];
+ register char *source =
+@@ -1777,7 +1777,7 @@
+
+ else
+ { /* need more input */
+- int offset = YY_G(yy_c_buf_p) - YY_G(yytext_ptr);
++ long offset = YY_G(yy_c_buf_p) - YY_G(yytext_ptr);
+ ++YY_G(yy_c_buf_p);
+
+ switch ( yy_get_next_buffer( M4_YY_CALL_ONLY_ARG ) )
+@@ -2156,7 +2156,7 @@
+ void yyFlexLexer::yyensure_buffer_stack(void)
+ %endif
+ {
+- int num_to_alloc;
++ size_t num_to_alloc;
+ M4_YY_DECL_GUTS_VAR();
+
+ if (!YY_G(yy_buffer_stack)) {
+@@ -2271,12 +2271,12 @@
+ * M4_YY_DOC_PARAM
+ * @return the newly allocated buffer state object.
+ */
+-YY_BUFFER_STATE yy_scan_bytes YYFARGS2( yyconst char *,bytes, int ,len)
++YY_BUFFER_STATE yy_scan_bytes YYFARGS2( yyconst char *,bytes, size_t ,len)
+ {
+ YY_BUFFER_STATE b;
+ char *buf;
+ yy_size_t n;
+- int i;
++ size_t i;
+ m4_dnl M4_YY_DECL_GUTS_VAR();
+
+ /* Get memory for full buffer, including space for trailing EOB's. */
+diff -ru flex-2.5.31/gen.c flex-2.5.31J/gen.c
+--- flex-2.5.31/gen.c Sun Mar 30 12:58:44 2003
++++ flex-2.5.31J/gen.c Sat Nov 13 14:00:09 2004
+@@ -55,6 +55,14 @@
+ * 0 elements of its arrays, too.)
+ */
+
++static const char *get_yy_char_decl (void)
++{
++ return (gentables)
++ ? "static yyconst YY_CHAR %s[%d] =\n { 0,\n"
++ : "static yyconst YY_CHAR * %s = 0;\n";
++}
++
++
+ static const char *get_int16_decl (void)
+ {
+ return (gentables)
+@@ -468,7 +476,7 @@
+ register int i, j;
+ int numrows;
+
+- out_str_dec (get_int32_decl (), "yy_ec", csize);
++ out_str_dec (get_yy_char_decl (), "yy_ec", csize);
+
+ for (i = 1; i < csize; ++i) {
+ if (caseins && (i >= 'A') && (i <= 'Z'))
+@@ -870,11 +878,11 @@
+ if (worry_about_NULs && !nultrans) {
+ if (useecs)
+ (void) sprintf (char_map,
+- "(*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : %d)",
++ "(*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : (YY_CHAR) %d)",
+ NUL_ec);
+ else
+ (void) sprintf (char_map,
+- "(*yy_cp ? YY_SC_TO_UI(*yy_cp) : %d)",
++ "(*yy_cp ? YY_SC_TO_UI(*yy_cp) : (YY_CHAR) %d)",
+ NUL_ec);
+ }
+
+@@ -1277,7 +1285,7 @@
+ fputs (_("\n\nMeta-Equivalence Classes:\n"),
+ stderr);
+
+- out_str_dec (get_int32_decl (), "yy_meta", numecs + 1);
++ out_str_dec (get_yy_char_decl (), "yy_meta", numecs + 1);
+ buf_prints (&yydmap_buf,
+ "\t{YYTD_ID_META, (void**)&yy_meta, sizeof(%s)},\n",
+ "flex_int32_t");
+@@ -1522,11 +1530,11 @@
+ if (yymore_used && !yytext_is_array) {
+ indent_puts ("YY_G(yytext_ptr) -= YY_G(yy_more_len); \\");
+ indent_puts
+- ("yyleng = (size_t) (yy_cp - YY_G(yytext_ptr)); \\");
++ ("yyleng = (int) (yy_cp - YY_G(yytext_ptr)); \\");
+ }
+
+ else
+- indent_puts ("yyleng = (size_t) (yy_cp - yy_bp); \\");
++ indent_puts ("yyleng = (int) (yy_cp - yy_bp); \\");
+
+ /* Now also deal with copying yytext_ptr to yytext if needed. */
+ skelout (); /* %% [3.0] - break point in skel */
+diff -ru flex-2.5.31/flexint.h flex-2.5.31J/flexint.h
+--- flex-2.5.31/flexint.h Mon Dec 9 07:14:49 2002
++++ flex-2.5.31J/flexint.h Sat Nov 13 14:13:00 2004
+@@ -5,7 +5,10 @@
+
+ /* C99 systems have <inttypes.h>. Non-C99 systems may or may not. */
+
+-#if defined __STDC_VERSION__ && __STDC_VERSION__ >= 199901L
++#ifndef __STDC_VERSION__
++#define __STDC_VERSION__ 0
++#endif
++#if __STDC_VERSION__ >= 199901L
+ #include <inttypes.h>
+ typedef int8_t flex_int8_t;
+ typedef uint8_t flex_uint8_t;
diff --git a/Build/source/utils/asymptote/patches/gc-7.0nomem.patch b/Build/source/utils/asymptote/patches/gc-7.0nomem.patch
new file mode 100644
index 00000000000..4cc2058f4c8
--- /dev/null
+++ b/Build/source/utils/asymptote/patches/gc-7.0nomem.patch
@@ -0,0 +1,21 @@
+*** gc_hdrs.h.orig Tue Jun 5 14:01:25 2007
+--- gc_hdrs.h Thu Oct 18 14:32:03 2007
+***************
+*** 112,119 ****
+ hhdr = hce -> hce_hdr; \
+ } else { \
+ hhdr = HEADER_CACHE_MISS(p, hce, source); \
+- if (0 == hhdr) goto exit_label; \
+ } \
+ }
+
+ typedef struct bi {
+--- 112,119 ----
+ hhdr = hce -> hce_hdr; \
+ } else { \
+ hhdr = HEADER_CACHE_MISS(p, hce, source); \
+ } \
++ if (0 == hhdr) goto exit_label; \
+ }
+
+ typedef struct bi {
diff --git a/Build/source/utils/asymptote/patches/gc6.8_AIX.patch b/Build/source/utils/asymptote/patches/gc6.8_AIX.patch
new file mode 100644
index 00000000000..4fdddd81c78
--- /dev/null
+++ b/Build/source/utils/asymptote/patches/gc6.8_AIX.patch
@@ -0,0 +1,7 @@
+*** gc.h.orig Fri Jul 7 18:10:16 2006
+--- gc.h Mon Feb 12 12:30:48 2007
+***************
+*** 981 ****
+! # define GC_INIT() { GC_add_roots(GC_DATASTART, GC_DATAEND); }
+--- 981 ----
+! # define GC_INIT() { GC_add_roots((char *) GC_DATASTART, (char *) GC_DATAEND); }
diff --git a/Build/source/utils/asymptote/patches/gcc3.3.2curses.patch b/Build/source/utils/asymptote/patches/gcc3.3.2curses.patch
new file mode 100644
index 00000000000..34d75aaa48b
--- /dev/null
+++ b/Build/source/utils/asymptote/patches/gcc3.3.2curses.patch
@@ -0,0 +1,7 @@
+*** curses.h.orig Sun Feb 11 21:43:36 2007
+--- curses.h Sun Feb 11 21:43:21 2007
+***************
+*** 1302 ****
+! #if defined(__USE_FIXED_PROTOTYPES__) || defined(__cplusplus) || defined (__STRICT_ANSI__)
+--- 1302 ----
+! #if 0 && (defined(__USE_FIXED_PROTOTYPES__) || defined(__cplusplus) || defined (__STRICT_ANSI__))
diff --git a/Build/source/utils/asymptote/patches/movie15_20090323.patch b/Build/source/utils/asymptote/patches/movie15_20090323.patch
new file mode 100644
index 00000000000..953b0214c89
--- /dev/null
+++ b/Build/source/utils/asymptote/patches/movie15_20090323.patch
@@ -0,0 +1,11 @@
+--- old/movie15.sty 2009-05-14 16:21:46.437500000 -0700
++++ movie15.sty 2009-05-14 17:09:00.984375000 -0700
+@@ -2796,7 +2796,7 @@
+ var spc=String.fromCharCode(32);%
+ var nl=String.fromCharCode(10);%
+ var charht=2;%
+- var res='VIEW\%={<insert descriptive name here (optional)>}'+nl;%
++ var res='VIEW\%={<insert\ descriptive\ name\ here\ (optional)>}'+nl;%
+ var x = (Math.abs(coo.x) < 1e-12 ? 0 : coo.x);%
+ var y = (Math.abs(coo.y) < 1e-12 ? 0 : coo.y);%
+ var z = (Math.abs(coo.z) < 1e-12 ? 0 : coo.z);%
diff --git a/Build/source/utils/asymptote/patches/movie15_dvipdfmx.patch b/Build/source/utils/asymptote/patches/movie15_dvipdfmx.patch
new file mode 100644
index 00000000000..a748d81c84c
--- /dev/null
+++ b/Build/source/utils/asymptote/patches/movie15_dvipdfmx.patch
@@ -0,0 +1,43 @@
+--- /usr/local/src/dvipdfmx/contrib/latex/movie15.sty.sample 2008-06-07 03:59:38.000000000 -0600
++++ movie15.sty 2009-02-12 21:21:43.000000000 -0700
+@@ -9,7 +9,7 @@
+ %
+
+ \NeedsTeXFormat{LaTeX2e}
+-\ProvidesPackage{movie15}[2008/01/16]
++\ProvidesPackage{movie15}[2008/10/08]
+ \RequirePackage{keyval}
+ \RequirePackage{ifthen}
+ \RequirePackage{ifpdf}
+@@ -809,7 +809,7 @@
+ \if@MXV@externalviewer\else%
+ %appearance dict dummy, to be shared by all 3D annots
+ \ifthenelse{\isundefined{\@MXV@apdict}}{%
+- \pdfobj stream {}\pdfrefobj\pdflastobj%
++ \pdfobj stream attr {/BBox [0 0 0.001 0.001]} {}\pdfrefobj\pdflastobj%
+ \xdef\@MXV@apdict{/AP << /N \the\pdflastobj\space 0 R >>}%
+ }{}%
+ %3D reference dict
+@@ -1037,7 +1037,7 @@
+ \if@MXV@externalviewer\else%
+ %appearance dict dummy, to be shared by all 3D annots
+ \ifthenelse{\isundefined{\@MXV@apdict}}{%
+- \special{pdf:stream @apdict\space()}%
++ \special{pdf:stream @apdict\space()<</BBox[0 0 0.001 0.001]>>}%
+ \xdef\@MXV@apdict{/AP << /N @apdict >>}%
+ }{}%
+ %3D reference dict
+@@ -1367,6 +1367,13 @@
+ ()%
+ }%
+ }%
++ \pdfmark{%
++ pdfmark=/PUT,%
++ Raw={%
++ {apdict}
++ <</BBox [0 0 0.001 0.001]>>
++ }%
++ }%
+ \xdef\@MXV@apdict{/AP << /N {apdict}>>}%
+ }{}%
+ %3D reference dict
diff --git a/Build/source/utils/asymptote/patches/movie15_dvipdfmx.sty b/Build/source/utils/asymptote/patches/movie15_dvipdfmx.sty
new file mode 100644
index 00000000000..fa3ac0aa929
--- /dev/null
+++ b/Build/source/utils/asymptote/patches/movie15_dvipdfmx.sty
@@ -0,0 +1,4259 @@
+% Copyright 2004--2008 Alexander Grahn
+%
+% This material is subject to the LaTeX Project Public License. See
+% http://www.ctan.org/tex-archive/help/Catalogue/licenses.lppl.html
+% for the details of that license.
+%
+% This package allows inclusion of multimedia content into PDF files
+% following Adobe's PDF-1.5 and 1.6 specifications.
+%
+
+\NeedsTeXFormat{LaTeX2e}
+\ProvidesPackage{movie15}[2008/10/08]
+\RequirePackage{keyval}
+\RequirePackage{ifthen}
+\RequirePackage{ifpdf}
+\RequirePackage{ifdraft}
+
+\newboolean{@MXV@iiiDfeat} % enable 3D features from PDF-1.6 spec?
+\setboolean{@MXV@iiiDfeat}{false}%
+\newboolean{@MXV@iiid} %set to true if a 3D file is being embedded
+\newboolean{@MXV@draft} %according to global setting
+\newboolean{@MXV@@draft} %per inclusion setting
+
+\ifdraft{%globally set by document class
+ \setboolean{@MXV@draft}{true}%
+}{%
+ \setboolean{@MXV@draft}{false}%
+}%
+
+%override global setting
+\DeclareOption{draft}{%
+ \setboolean{@MXV@draft}{true}%
+}
+\DeclareOption{final}{%
+ \setboolean{@MXV@draft}{false}%
+}
+
+\DeclareOption{3D}{%
+ \setboolean{@MXV@iiiDfeat}{true}%
+}
+
+\newboolean{@MXV@dvips}
+\newboolean{@MXV@dvipdfmx}
+\ifpdf
+ \setboolean{@MXV@dvips}{true}
+\else
+ \setboolean{@MXV@dvips}{false}
+\fi
+\setboolean{@MXV@dvipdfmx}{false}
+
+\DeclareOption{dvips}{%
+ \setboolean{@MXV@dvips}{true}%
+ \setboolean{@MXV@dvipdfmx}{false}%
+}
+\DeclareOption{dvipdfmx}{%
+ \setboolean{@MXV@dvips}{false}%
+ \setboolean{@MXV@dvipdfmx}{true}%
+}
+
+\DeclareOption*{%
+ \PackageWarning{movie15}{Unknown option \CurrentOption}
+}
+
+\ProcessOptions*\relax
+
+%testing for correct TeX version,
+\ifpdf
+ \ifnum\pdftexversion<120
+ \PackageError{movie15}{%
+ pdfeTeX, version >= 1.20, required
+ }{%
+ Install a more recent version!
+ }%
+ \fi
+\fi
+
+\ifx\@undefined\pdfmdfivesum
+ \def\pdfmdfivesum file #1{#1}
+\fi
+
+%for conditionals where \ifthenelse doesn't work
+\gdef\@MXV@if#1{\csname if#1\endcsname}%
+
+\newboolean{@MXV@beamer} %set to true if beamer class has been loaded
+%\newboolean{@MXV@powerdot} %the same for
+\newboolean{@MXV@presentation} %used with presentation making package?
+\newboolean{@MXV@hide} %contents hidden on the current slide?
+\@ifclassloaded{beamer}{%
+ \setboolean{@MXV@beamer}{true}%
+ \setboolean{@MXV@presentation}{true}%
+}{%
+ \setboolean{@MXV@beamer}{false}%
+ \setboolean{@MXV@presentation}{false}%
+}
+%\@ifclassloaded{powerdot}{%
+% \setboolean{@MXV@powerdot}{true}%
+% \setboolean{@MXV@presentation}{true}%
+%}{%
+% \setboolean{@MXV@powerdot}{false}%
+% \setboolean{@MXV@presentation}{false}%
+%}
+
+\AtBeginDocument{%
+ \provideboolean{Hy@colorlinks}% set by hyperref
+ \ifHy@colorlinks% coloured (movieref-)link text instead of link border
+ \gdef\@MXV@pdfborder{/Border [0 0 0]}%
+ \else%
+ \gdef\@MXV@pdfborder{}%
+ \fi%
+}
+
+\RequirePackage{everyshi}%
+\newcount\@MXV@page% counter for absolute page number
+\EveryShipout{%
+ \global\advance\@MXV@page by 1%
+}
+
+%define our own label making commands
+\def\@MXV@newlabel#1#2{{%
+ \expandafter\xdef\csname#1\endcsname{#2}}}%
+
+\def\@MXV@getlabelvalue#1{%
+ \expandafter\ifx\csname#1\endcsname\relax%
+ undefined%
+ \else%
+ \csname#1\endcsname%
+ \fi%
+}%
+
+%macro for writing labels to external *.aux file
+\def\@MXV@labeltoaux#1#2{%
+ \@bsphack\protected@write\@auxout{}{%
+ \string\@MXV@newlabel{#1}{#2}%
+ \string\@MXV@newlabel{@#1@}{\@MXV@getlabelvalue{#1}}%
+ }\@esphack%
+ \ifthenelse{%
+ \equal{\@MXV@getlabelvalue{#1}}{undefined}\OR%
+ %double check that the value hasn't changed
+ \NOT\equal{\@MXV@getlabelvalue{#1}}{\@MXV@getlabelvalue{@#1@}}%
+ }{%
+ \ifthenelse{\isundefined{\@MXV@warning}}{% issue warning only once, at end
+ \gdef\@MXV@warning{}% of document
+ \AtEndDocument{%
+ \PackageWarningNoLine{movie15}{%
+ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\MessageBreak
+ @@ Rerun to get object references right! @@\MessageBreak
+ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@}%
+ }%
+ }{}%
+ }{}%
+}%
+%
+\ifpdf%
+ %for storing pdf object numbers (must be counters)
+ \newcount\@MXV@adict%
+ \newcount\@MXV@aadict%
+ %
+ %returns pdf page object number
+ \def\@MXV@pdfpageref#1{%
+ \expandafter\ifx\csname#1\endcsname\relax%
+ 0%
+ \else%
+ \expandafter\pdfpageref\csname#1\endcsname\space%
+ \fi%
+ }%
+\else\if@MXV@dvipdfmx%do nothing
+\else%
+ \PassOptionsToPackage{pdfmark}{hyperref}%
+\fi\fi
+
+%counter for absolute number of inclusions,
+%used for labelling each annotation
+\newcount\@MXV@includes
+
+%counter for absolute number of movie players
+\newcount\@MXV@players
+
+%counter for absolute number of movierefs
+\newcount\@MXV@links
+
+%measuring things
+%textbox
+\newdimen\@MXV@width
+\newdimen\@MXV@height
+\newdimen\@MXV@depth
+\newdimen\@MXV@totalheight
+\newdimen\@MXV@@boxdepth
+%for centring the textbox within display box
+\newdimen\@MXV@traiselen
+\newdimen\@MXV@braiselen
+%for compatibility options
+\newdimen\@MXV@start
+\newdimen\@MXV@end
+
+%stores textbox given as argument to text option
+\newsavebox{\@MXV@textbox}
+
+%some booleans we need
+\newboolean{@MXV@autoplay}
+\newboolean{@MXV@autostop}
+\newboolean{@MXV@autoresume}
+\newboolean{@MXV@autoclose}
+\newboolean{@MXV@autopause}
+\newboolean{@MXV@mouse}%mouse interaction
+\newboolean{@MXV@inline}%inline movie data
+\newboolean{@MXV@attachment}%make embedded file extractable?
+\newboolean{@MXV@externalviewer}%if true, screen annot will be removed
+\newboolean{@MXV@url}
+\newboolean{@MXV@boxopt}%true if text option is set
+\newboolean{@MXV@textoverposter}
+\newboolean{@MXV@runposter}% render poster from movie at runtime
+\newboolean{@MXV@linkplay}% for \movieref command
+\newboolean{@MXV@linkpause}
+\newboolean{@MXV@linkresume}
+\newboolean{@MXV@linkstop}
+\newboolean{@MXV@linkclose}
+\newboolean{@MXV@linkreset}
+\newboolean{@MXV@issound}
+
+%macro to reset all macros and booleans
+\def\@MXV@reset{%
+ \setboolean{@MXV@autoplay}{false}%
+ \setboolean{@MXV@autostop}{true}%
+ \setboolean{@MXV@autoresume}{false}%
+ \setboolean{@MXV@autopause}{false}%
+ \setboolean{@MXV@autoclose}{false}%
+ \setboolean{@MXV@mouse}{false}%
+ \setboolean{@MXV@inline}{true}%
+ \setboolean{@MXV@attachment}{true}%
+ \setboolean{@MXV@externalviewer}{false}%
+ \setboolean{@MXV@issound}{false}%
+ \setboolean{@MXV@url}{false}%
+ \setboolean{@MXV@boxopt}{false}%
+ \setboolean{@MXV@textoverposter}{true}%
+ \setboolean{@MXV@runposter}{false}%
+ \setboolean{@MXV@linkplay}{true}%
+ \setboolean{@MXV@linkpause}{false}%
+ \setboolean{@MXV@linkresume}{false}%
+ \setboolean{@MXV@linkstop}{false}%
+ \setboolean{@MXV@linkclose}{false}%
+ \setboolean{@MXV@linkreset}{false}%
+ \setboolean{@MXV@requirereopen}{false}%
+ \ifthenelse{\boolean{@MXV@draft}}{%
+ \setboolean{@MXV@@draft}{true}%
+ }{%
+ \setboolean{@MXV@@draft}{false}%
+ }%
+ %
+ \gdef\@MXV@label{}% for movieref
+ \gdef\@MXV@@label{}% for movieref
+ \gdef\@MXV@mime{@MXV@auto}%
+ \gdef\@MXV@player{}%
+ \gdef\@MXV@fsentry{}%
+ \gdef\@MXV@repeat{}%
+ \gdef\@MXV@@repeat{}%
+ \gdef\@MXV@volume{100}%
+ \gdef\@MXV@@volume{}%
+ \gdef\@MXV@ctrls{}%
+ \gdef\@MXV@@ctrls{}%
+ \gdef\@MXV@palindrome{}%
+ \gdef\@MXV@rate{}%
+ \gdef\@MXV@startat{}%
+ \gdef\@MXV@@startat{}%
+ \gdef\@MXV@endat{}%
+ \gdef\@MXV@poevent{}%
+ \gdef\@MXV@pcevent{}%
+ \gdef\@MXV@box##1##2##3{\raisebox{0pt}[##2][##3]{\makebox[##1]{}}}%
+ \setlength{\@MXV@depth}{0pt}%
+ \setlength{\@MXV@height}{0pt}%
+ \setlength{\@MXV@width}{0pt}%
+ \setlength{\@MXV@braiselen}{0pt}%
+ \setlength{\@MXV@traiselen}{0pt}%
+ \gdef\@MXV@boxdepth{}%
+ \gdef\@MXV@boxheight{}%
+ \gdef\@MXV@boxwidth{}%
+ %
+ \ifthenelse{\boolean{@MXV@iiiDfeat}}{%
+ \setboolean{@MXV@iiid}{false}%
+ \gdef\@MXV@aac{30}% aperture angle of camera
+ \gdef\@MXV@roll{0}% camera roll angle
+ \gdef\@MXV@background{}%
+ \gdef\@MXV@jscriptiiidfile{}%
+ \gdef\@MXV@coo{0 0 0}% centre of orbit
+ \gdef\@MXV@ctoc{0 -1 0}% centre of orbit to camera vector
+ \gdef\@MXV@roo{0}% radius of orbit
+ \gdef\@MXV@viewsfile{}% file containing views of the 3D object
+ \setboolean{@MXV@viewsprovided}{false}%
+ \setboolean{@MXV@defaultviewprovided}{false}%
+ \gdef\@MXV@iiidview{}%
+ \gdef\@MXV@iiidtoolb{/TB false}% don't show toolbar by default
+ \gdef\@MXV@iiidia{}% 3D interactive by default
+ \gdef\@MXV@calc{}% camera aperture for coo and roo calculation
+ \setboolean{@MXV@iiidgetview}{false}%
+ \gdef\@MXV@iiidopt{}% option string to be passed to internal macro
+ \setboolean{@MXV@resource}{false}%
+ \gdef\@MXV@resourcetree{}% name tree of embedded 3D resources
+ \xdef\@MXV@animstyle{}%
+ \gdef\@MXV@iiidpalindrome{/Subtype/Linear}% forward
+ \gdef\@MXV@iiidrate{}% animation speed
+ \global\@MXV@iiidrepeat=-1% repeat count
+ \gdef\@MXV@lights{}% default lighting scheme
+ \gdef\@MXV@render{}% default render mode scheme
+ }{}%
+}%
+
+%missing package error message
+\def\@MXV@missing#1{%
+ \PackageError{movie15}{%
+ Package `#1' has not been loaded yet
+ }{%
+ Put the line `\protect\usepackage{#1}' somewhere after
+ `\protect\usepackage{movie15}' to the preamble of your
+ document!
+ }%
+}
+
+%3D-need-be-enabled error message
+\def\@MXV@neediiiD{%
+ \PackageError{movie15}{%
+ If you wish to embed 3D objects, enable the\MessageBreak
+ 3D feature first by passing option `3D' to movie15!\MessageBreak
+ Make sure the `fp' package for fixed point calculus\MessageBreak
+ is installed in your TeX system
+ }{Package `fp' is available from CTAN.}%
+}
+
+%macro to guess the mime type of the media file
+\def\@MXV@guessmime#1#2{%
+ \ifthenelse{\equal{#2}{aiff}\OR\equal{#2}{AIFF}\OR%
+ \equal{#2}{aif}\OR\equal{#2}{AIF}\OR%
+ \equal{#2}{aifc}\OR\equal{#2}{AIFC}}{%
+ \gdef\@MXV@mime{audio/aiff}%
+ }{%
+ \ifthenelse{\equal{#2}{wav}\OR\equal{#2}{WAV}}{%
+ \gdef\@MXV@mime{audio/wav}%
+ }{%
+ \ifthenelse{\equal{#2}{wma}\OR\equal{#2}{WMA}}{%
+ \gdef\@MXV@mime{audio/x-ms-wma}%
+ }{%
+ \ifthenelse{\equal{#2}{wmv}\OR\equal{#2}{WMV}}{%
+ \gdef\@MXV@mime{video/x-ms-wmv}%
+ }{%
+ \ifthenelse{\equal{#2}{au}\OR\equal{#2}{AU}\OR%
+ \equal{#2}{snd}\OR\equal{#2}{SND}}{%
+ \gdef\@MXV@mime{audio/basic}%
+ }{%
+ \ifthenelse{\equal{#2}{mid}\OR\equal{#2}{MID}\OR%
+ \equal{#2}{rmi}\OR\equal{#2}{RMI}}{%
+ \gdef\@MXV@mime{audio/midi}%
+ }{%
+ \ifthenelse{\equal{#2}{mov}\OR\equal{#2}{MOV}\OR%
+ \equal{#2}{qt}\OR\equal{#2}{QT}}{%
+ \gdef\@MXV@mime{video/quicktime}%
+ }{%
+ \ifthenelse{\equal{#2}{mp3}\OR\equal{#2}{MP3}\OR%
+ \equal{#2}{m3u}\OR\equal{#2}{M3U}}{%
+ \gdef\@MXV@mime{audio/x-mp3}%
+ }{%
+ \ifthenelse{\equal{#2}{mp4}\OR\equal{#2}{MP4}}{%
+ \gdef\@MXV@mime{video/mp4}%
+ }{%
+ \ifthenelse{\equal{#2}{avi}\OR\equal{#2}{AVI}}{%
+ \gdef\@MXV@mime{video/avi}%
+ }{%
+ \ifthenelse{\equal{#2}{gif}\OR\equal{#2}{GIF}}{%
+ \gdef\@MXV@mime{image/gif}%
+ }{%
+ \ifthenelse{\equal{#2}{mpeg}\OR\equal{#2}{MPEG}\OR%
+ \equal{#2}{mpg}\OR\equal{#2}{MPG}}{%
+ \gdef\@MXV@mime{video/mpeg}%
+ }{%
+ \ifthenelse{\equal{#2}{smil}\OR\equal{#2}{SMIL}}{%
+ \gdef\@MXV@mime{application/smil}%
+ }{%
+ \ifthenelse{\equal{#2}{swf}\OR\equal{#2}{SWF}}{%
+ \gdef\@MXV@mime{application/x-shockwave-flash}%
+ }{%
+ \ifthenelse{\equal{#2}{prc}\OR\equal{#2}{PRC}}{%
+ \ifthenelse{\boolean{@MXV@iiiDfeat}}{%
+ \setboolean{@MXV@iiid}{true}%
+ \gdef\@MXV@mime{model/prc}% (unofficial)
+ \gdef\@MXV@iiidsubtype{PRC}%
+ }{%
+ \@MXV@neediiiD%
+ }%
+ }{%
+ \ifthenelse{\equal{#2}{u3d}\OR\equal{#2}{U3D}}{%
+ \ifthenelse{\boolean{@MXV@iiiDfeat}}{%
+ \setboolean{@MXV@iiid}{true}%
+ \gdef\@MXV@mime{model/u3d}% (unofficial)
+ \gdef\@MXV@iiidsubtype{U3D}%
+ }{%
+ \@MXV@neediiiD%
+ }%
+ }{%
+ \ifthenelse{\equal{#2}{ra}\OR\equal{#2}{RA}}{
+ \gdef\@MXV@mime{audio/vnd.rn-realaudio}%
+ }{%
+ \ifthenelse{%
+ \equal{#2}{rv}\OR\equal{#2}{RV}\OR
+ \equal{#2}{rm}\OR\equal{#2}{RM}%
+ }{%
+ \gdef\@MXV@mime{application/vnd.rn-realmedia}%
+ }{%
+ \PackageError{movie15}{%
+ I couldn't determine MIME type of file:\MessageBreak`#1':\MessageBreak
+ Unknown file name extension: `#2'
+ }{%
+ When using media files of unknown type or with a\MessageBreak
+ non-standard file name extension, the MIME type must\MessageBreak
+ explicitly be specified. Try option `mimetype=<mime type>'!
+ }%
+ }}}}}}}}}}}}}}}}}}%
+}
+
+%sets @MXV@issound boolean
+\def\@MXV@@issound#1/#2:{% argument: \@MXV@mime.
+ \def\@MXV@firstarg{#1}%
+ \def\@MXV@audio{audio}%
+ \ifx\@MXV@firstarg\@MXV@audio%
+ \setboolean{@MXV@issound}{true}%
+ \fi%
+}
+
+%draft box
+\def\@MXV@draftbox#1#2#3#4{%width height depth filename
+ \edef\@MXV@oldfboxsep{\the\fboxsep}%
+ \setlength{\fboxsep}{-\fboxrule}%
+ \framebox[#1][l]{%
+ \vrule width 0pt height #2 depth #3%
+ \edef\@tempa{#4}%
+ \raisebox{\depth}[0pt][0pt]{ \ttfamily\expandafter\strip@prefix\meaning\@tempa}%
+ }%
+ \setlength{\fboxsep}{\@MXV@oldfboxsep}%
+}
+
+\ifthenelse{\boolean{@MXV@iiiDfeat}}{% 3D related definitions and macros
+ \RequirePackage{fp}% needed for fixed point calculus
+ \newread\@MXV@@viewsfile% file handle for views file
+ \newcount\@MXV@viewscount%counter for number of 3D views per inclusion
+ \newboolean{@MXV@viewsprovided}%3d views file provided?
+ \newboolean{@MXV@iiidgetview}% print current 3D settings?
+ \newboolean{@MXV@defaultviewprovided}%default 3D view provided?
+ \newboolean{@MXV@resource}%3d resource file provided?
+ \ifpdf\else\newcount\@MXV@rescount\fi% number of embedded resource files
+ \newcount\@MXV@iiidrepeat% play count
+ \newcount\@MXV@iiidoncurpage%index of 3D annot on current page
+ \global\@MXV@iiidoncurpage=0%
+ \gdef\@MXV@oldpage{0}% needed together with previous counter
+
+ %macro for building the transformation matrix
+ \def\@MXV@ciiwmatrix#1 #2 #3 #4 #5 #6 #7 #8 {%
+ % #1,#2,#3 centre of orbit coordinates (coo)
+ % #4,#5,#6 centre of orbit to camera direction vector (c2c)
+ % #7 orbital radius (roo)
+ % #8 camera roll (roll)
+ %view vector (opposite to c2c)
+ \FPupn\@MXV@viewx{#4 neg}%
+ \FPupn\@MXV@viewy{#5 neg}%
+ \FPupn\@MXV@viewz{#6 neg}%
+ %normalize view vector
+ \FPupn\@MXV@modulo{\@MXV@viewx{} copy mul %
+ \@MXV@viewy{} copy mul + %
+ \@MXV@viewz{} copy mul + 2 swap root%
+ }%
+ \FPupn\@MXV@viewx{\@MXV@viewx{} \@MXV@modulo{} div}%
+ \FPupn\@MXV@viewy{\@MXV@viewy{} \@MXV@modulo{} div}%
+ \FPupn\@MXV@viewz{\@MXV@viewz{} \@MXV@modulo{} div}%
+ %camera roll
+ \FPupn\@MXV@sinroll{#8 180.0 div \FPpi{} mul sin}%
+ \FPupn\@MXV@cosroll{#8 180.0 div \FPpi{} mul cos}%
+ %
+ %top and bottom views
+ \FPupn\@MXV@leftx{-1.0}%
+ \FPupn\@MXV@lefty{0.0}%
+ \FPupn\@MXV@leftz{0.0}%
+ %
+ \FPifneg\@MXV@viewz% top view
+ %up-vector
+ \FPupn\@MXV@upx{0.0}%
+ \FPupn\@MXV@upy{1.0}%
+ \FPupn\@MXV@upz{0.0}%
+ \else% bottom view
+ %up-vector
+ \FPupn\@MXV@upx{0.0}%
+ \FPupn\@MXV@upy{-1.0}%
+ \FPupn\@MXV@upz{0.0}%
+ \fi%
+ \FPupn\@MXV@sumxy{\@MXV@viewx{} abs \@MXV@viewy{} abs add}%
+ \FPifeq\@MXV@sumxy{0}\else% other views than top and bottom
+ %up-vector = up_world - (up_world dot view) view
+ \FPupn\@MXV@upx{\@MXV@viewz{} \@MXV@viewx{} mul neg}%
+ \FPupn\@MXV@upy{\@MXV@viewz{} \@MXV@viewy{} mul neg}%
+ \FPupn\@MXV@upz{\@MXV@viewz{} \@MXV@viewz{} mul neg 1.0 add}%
+ %normalize up-vector
+ \FPupn\@MXV@modulo{\@MXV@upx{} copy mul \@MXV@upy{} copy %
+ mul + \@MXV@upz{} copy mul + 2 swap root}%
+ \FPupn\@MXV@upx{\@MXV@upx{} \@MXV@modulo{} div}%
+ \FPupn\@MXV@upy{\@MXV@upy{} \@MXV@modulo{} div}%
+ \FPupn\@MXV@upz{\@MXV@upz{} \@MXV@modulo{} div}%
+ %left vector = up x view
+ \FPupn\@MXV@leftx{\@MXV@viewz{} \@MXV@upy{} mul %
+ \@MXV@viewy{} \@MXV@upz{} mul sub}%
+ \FPupn\@MXV@lefty{\@MXV@viewx{} \@MXV@upz{} mul %
+ \@MXV@viewz{} \@MXV@upx{} mul sub}%
+ \FPupn\@MXV@leftz{\@MXV@viewy{} \@MXV@upx{} mul %
+ \@MXV@viewx{} \@MXV@upy{} mul sub}%
+ %normalize left vector
+ \FPupn\@MXV@modulo{\@MXV@leftx{} copy mul \@MXV@lefty{} %
+ copy mul + \@MXV@leftz{} copy mul + 2 swap root}%
+ \FPupn\@MXV@leftx{\@MXV@leftx{} \@MXV@modulo{} div}%
+ \FPupn\@MXV@lefty{\@MXV@lefty{} \@MXV@modulo{} div}%
+ \FPupn\@MXV@leftz{\@MXV@leftz{} \@MXV@modulo{} div}%
+ \fi%
+ %apply camera roll
+ \FPupn\@MXV@leftxprime{\@MXV@leftx{} \@MXV@cosroll{} mul \@MXV@upx{} \@MXV@sinroll{} mul +}%
+ \FPupn\@MXV@leftyprime{\@MXV@lefty{} \@MXV@cosroll{} mul \@MXV@upy{} \@MXV@sinroll{} mul +}%
+ \FPupn\@MXV@leftzprime{\@MXV@leftz{} \@MXV@cosroll{} mul \@MXV@upz{} \@MXV@sinroll{} mul +}%
+ \FPupn\@MXV@upxprime{\@MXV@upx{} \@MXV@cosroll{} mul \@MXV@leftx{} \@MXV@sinroll{} mul sub}%
+ \FPupn\@MXV@upyprime{\@MXV@upy{} \@MXV@cosroll{} mul \@MXV@lefty{} \@MXV@sinroll{} mul sub}%
+ \FPupn\@MXV@upzprime{\@MXV@upz{} \@MXV@cosroll{} mul \@MXV@leftz{} \@MXV@sinroll{} mul sub}%
+ \FPupn\@MXV@leftx{\@MXV@leftxprime}%
+ \FPupn\@MXV@lefty{\@MXV@leftyprime}%
+ \FPupn\@MXV@leftz{\@MXV@leftzprime}%
+ \FPupn\@MXV@upx{\@MXV@upxprime}%
+ \FPupn\@MXV@upy{\@MXV@upyprime}%
+ \FPupn\@MXV@upz{\@MXV@upzprime}%
+ %rotation matrix
+ \xdef\@MXV@matrix{\@MXV@leftx\space\@MXV@lefty\space\@MXV@leftz\space%
+ \@MXV@upx\space\@MXV@upy\space\@MXV@upz\space%
+ \@MXV@viewx\space\@MXV@viewy\space\@MXV@viewz}%
+ %translation vector
+ \FPupn\@MXV@roo{#7 abs}%
+ \FPifeq\@MXV@roo{0}\FPupn\@MXV@roo{0.000000000000000001}\fi%
+ \FPupn\@MXV@transx{#1 \@MXV@roo{} \@MXV@viewx{} mul sub}%
+ \FPupn\@MXV@transy{#2 \@MXV@roo{} \@MXV@viewy{} mul sub}%
+ \FPupn\@MXV@transz{#3 \@MXV@roo{} \@MXV@viewz{} mul sub}%
+ %transformation matrix
+ \xdef\@MXV@matrix{%
+ \@MXV@matrix\space\@MXV@transx\space\@MXV@transy\space\@MXV@transz%
+ }%
+ }
+
+ %macro for parsing one line of 3D views file
+ \newcommand{\@MXV@parseline}[6][]{%
+ \xdef\@MXV@xname{#1}% name of the view (optional)
+ \ifthenelse{\equal{#2}{}}{%
+ \xdef\@MXV@coo{0 0 0}%
+ }{%
+ \xdef\@MXV@coo{#2}%
+ }%
+ \ifthenelse{\equal{#3}{}}{%
+ \xdef\@MXV@ctoc{0 -1 0}%
+ }{%
+ \xdef\@MXV@ctoc{#3}%
+ }%
+ \ifthenelse{\equal{#4}{}}{%
+ \xdef\@MXV@roo{0}%
+ }{%
+ \xdef\@MXV@roo{#4}%
+ }%
+ \ifthenelse{\equal{#5}{}}{%
+ \xdef\@MXV@roll{0}%
+ }{%
+ \xdef\@MXV@roll{#5}%
+ }%
+ \ifthenelse{\equal{#6}{}}{%
+ \xdef\@MXV@aac{30}%
+ }{%
+ \xdef\@MXV@aac{#6}%
+ }%
+ }
+
+ %macro for generating an array of 3D views (varray)
+ \def\@MXV@buildva{%
+ \global\@MXV@viewscount=0%
+ \xdef\@MXV@varray{}% empty varray
+ %
+ %default view
+ \edef\@MXV@args{\@MXV@coo\space\@MXV@ctoc\space\@MXV@roo\space\@MXV@roll\space}%
+ \expandafter\@MXV@ciiwmatrix\@MXV@args% build C2W matrix
+ \xdef\@MXV@xname{Default}%
+ \@MXV@viewobj% create pdf object of 3D view
+ \edef\@MXV@defaultview{\@MXV@@viewobj}%
+ %
+ %read out 3D views file
+ \IfFileExists{\@MXV@viewsfile}{%
+ \edef\@MXV@endlinechar{\the\endlinechar}%
+ \endlinechar=-1% suppress trailing space at input line end
+ \openin\@MXV@@viewsfile=\@MXV@viewsfile%
+ \loop%
+ \read\@MXV@@viewsfile to \@MXV@inputline%
+ \if\@MXV@inputline\relax\else%
+ \expandafter\@MXV@parseline\@MXV@inputline%
+ \edef\@MXV@args{\@MXV@coo\space\@MXV@ctoc\space\@MXV@roo\space\@MXV@roll\space}%
+ \expandafter\@MXV@ciiwmatrix\@MXV@args% build C2W matrix
+ \global\advance\@MXV@viewscount by 1%
+ \ifthenelse{\equal{\@MXV@xname}{}}{%
+ \xdef\@MXV@xname{View \the\@MXV@viewscount}%
+ }{}%
+ \@MXV@viewobj% create pdf object of 3D view
+ %append current view obj ref to VA array
+ \xdef\@MXV@varray{\@MXV@varray\space\@MXV@@viewobj}%
+ \setboolean{@MXV@viewsprovided}{true}%
+ \repeat%
+ \closein\@MXV@@viewsfile%
+ \endlinechar=\@MXV@endlinechar% reset endlinechar
+ }{}%
+ %
+ %make the first view in the VA array the default view, if no default one has
+ %explicitly been provided, but if the VA array itself is empty too (no
+ %additional views provided) use our fallback view (c2c=0 -1 0) as default
+ \ifthenelse{\NOT\boolean{@MXV@defaultviewprovided}%
+ \AND\boolean{@MXV@viewsprovided}}{%
+ \xdef\@MXV@defaultview{/3DV /F}%
+ }{%
+ \xdef\@MXV@defaultview{/3DV \@MXV@defaultview}%
+ }%
+ }
+
+ %following macros, including the 3D inclusion macro have driver specific
+ %implementations
+ \ifpdf%
+ %pdfLaTeX versions
+ %macro for creating 3D view object
+ \def\@MXV@viewobj{%
+ %projection dict
+ \pdfobj {<</Subtype/P/FOV \@MXV@aac/PS/Min>>}%
+ \pdfrefobj\pdflastobj%
+ %
+ \pdfobj {<<%
+ /MS/M% define the view as C2W matrix
+ /CO \@MXV@roo% orbital radius
+ /P \the\pdflastobj\space 0 R%
+ /C2W [\@MXV@matrix]%
+ /XN(\@MXV@xname)% name of the view appearing in the drop down list
+ \@MXV@background%
+ \@MXV@lights%
+ \@MXV@render%
+ >>}\pdfrefobj\pdflastobj%
+ \xdef\@MXV@@viewobj{\the\pdflastobj\space 0 R}%
+ }%
+
+ %macro for creating resource objects from 3D and image files, to be used
+ %in 3D JavaScript
+ \def\@MXV@addresource#1{%
+ %determine file type
+ \filename@parse{#1}%
+ \ifthenelse{%
+ \equal{\filename@ext}{u3d}\OR%
+ \equal{\filename@ext}{U3D}%
+ }{%
+ \def\@MXV@restype{U3D}%
+ }{%
+ \def\@MXV@restype{image}%
+ }%
+ \ifthenelse{\equal{\@MXV@restype}{image}}{%
+ %embed the same image file only once
+ \ifthenelse{\equal{\@MXV@getlabelvalue{\pdfmdfivesum file {#1}}}{undefined}}{%
+ \immediate\pdfximage {#1}%
+ \xdef\@MXV@resourcetree{% build name tree for embedded resources
+ \@MXV@resourcetree\space (#1) \the\pdflastximage\space 0 R%
+ }%
+ \@MXV@newlabel{\pdfmdfivesum file {#1}}{\the\pdflastximage}%
+ }{%
+ \xdef\@MXV@resourcetree{%
+ \@MXV@resourcetree\space (#1) \@MXV@getlabelvalue{\pdfmdfivesum file {#1}}\space 0 R%
+ }%
+ }%
+ }{%
+ %embed the same 3D file only once
+ \ifthenelse{\equal{\@MXV@getlabelvalue{\pdfmdfivesum file {#1}}}{undefined}}{%
+ \pdfobj stream %
+ attr {%
+ /Subtype/\@MXV@restype%
+ }%
+ file {#1}%
+ \pdfrefobj\pdflastobj%
+ \xdef\@MXV@resourcetree{%
+ \@MXV@resourcetree\space (#1) \the\pdflastobj\space 0 R%
+ }%
+ \@MXV@newlabel{\pdfmdfivesum file {#1}}{\the\pdflastobj}%
+ }{%
+ \xdef\@MXV@resourcetree{%
+ \@MXV@resourcetree\space (#1) \@MXV@getlabelvalue{\pdfmdfivesum file {#1}}\space 0 R%
+ }%
+ }%
+ }%
+ }
+
+ %3D inclusion macro
+ \newcommand{\@MXV@includeiiid}[5][]{%
+ %insert box or poster
+ \@MXV@box{#2}{#3}{#4}%
+ %
+ \if@MXV@externalviewer\else%
+ \setkeys{MXV@iiid}{#1}%process deferred options
+ \ifnum\@MXV@iiidrepeat=0\else%
+ \edef\@MXV@animstyle{% animation style dict
+ /AN <<%
+ \@MXV@iiidpalindrome\@MXV@iiidrate/PC \the\@MXV@iiidrepeat%
+ >>%
+ }%
+ \fi%
+ %java script file, stream object
+ \IfFileExists{\@MXV@jscriptiiidfile}{%
+ \pdfobj stream file {\@MXV@jscriptiiidfile}%
+ \pdfrefobj\pdflastobj%
+ \xdef\@MXV@jscriptiiid{/OnInstantiate \the\pdflastobj\space 0 R}%
+ }{\xdef\@MXV@jscriptiiid{}}%
+ %
+ %build the array of 3D views
+ \@MXV@buildva%
+ \fi%
+ %
+ %3D stream object
+ \if@MXV@inline%
+ \ifthenelse{%
+ \NOT\boolean{@MXV@presentation}\OR%
+ \equal{\@MXV@getlabelvalue{\@MXV@label.3dstream}}{undefined}%
+ }{%
+ \pdfobj stream%
+ attr {%
+ /Subtype/\@MXV@iiidsubtype%
+ \if@MXV@externalviewer\else%
+ /VA [\@MXV@varray]%
+ /DV/F% use first entry in VA as default view
+ \@MXV@animstyle%
+ \@MXV@jscriptiiid%
+ \if@MXV@resource%
+ /Resources <<%
+ /Names [\@MXV@resourcetree]%
+ >>%
+ \fi%
+ \fi%
+ }%
+ file {#5}%
+ \pdfrefobj\pdflastobj%
+ \edef\@MXV@iiidstream{\the\pdflastobj}%
+ \if@MXV@presentation%
+ \@MXV@newlabel{\@MXV@label.3dstream}{\@MXV@iiidstream}%
+ \fi%
+ }{%
+ \edef\@MXV@iiidstream{\@MXV@getlabelvalue{\@MXV@label.3dstream}}%
+ }%
+ \fi%
+ %
+ \makebox[0pt][r]{\makebox[#2][l]{%
+ %insert FileAttachment annotation
+ \ifthenelse{\boolean{@MXV@inline}\AND\boolean{@MXV@externalviewer}%
+% since Reader 7.0.7, we cannot place a file attachment annot behind
+% the 3D annot :-(
+% \OR\boolean{@MXV@attachment}
+ }{%
+ \pdfannot width #2 height #3 depth #4 {%
+ /Subtype /FileAttachment%
+ /F 0%
+ /T (\@MXV@filename)%
+ /Contents (3D Object (\@MXV@mime))%
+ \if@MXV@externalviewer%
+ /Name/Paperclip%
+ /C [1 1 1]%
+ \else%
+ /AP <</N<<>>/R<<>>/D<<>>>>%
+ \fi%
+ /FS <<%
+ /F(#5)%
+ /Type/Filespec%
+ /EF << /F \@MXV@iiidstream\space 0 R >>%
+ >>%
+ }%
+ }{%
+ \if@MXV@url%
+ %insert Link annotation, if 3D file is a URL
+ \pdfannot width #2 height #3 depth #4 {%
+ /Subtype /Link%
+ /F 0%
+ \if@MXV@externalviewer%
+ \@MXV@urlattr%
+ \else%
+ /H /N%
+ /Border [0 0 0]%
+ \fi%
+ /A <</URI (#5) /S/URI>>%
+ /Contents (3D Object (\@MXV@mime))%
+ }%
+ \else%
+ %else insert Launch action for local external 3D file
+ \if@MXV@inline\else%
+ \pdfannot width #2 height #3 depth #4 {%
+ /Subtype /Link%
+ /F 0%
+ \if@MXV@externalviewer%
+ \@MXV@runattr%
+ \else%
+ /H /N%
+ /Border [0 0 0]%
+ \fi%
+ /A <<%
+ /F (#5)%
+ /S /Launch%
+ >>%
+ /Contents (3D Object (\@MXV@mime))%
+ }%
+ \fi%
+ \fi%
+ }%
+ %
+ \if@MXV@externalviewer\else%
+ %appearance dict dummy, to be shared by all 3D annots
+ \ifthenelse{\isundefined{\@MXV@apdict}}{%
+ \pdfobj stream attr {/BBox [0 0 0.001 0.001]} {}\pdfrefobj\pdflastobj%
+ \xdef\@MXV@apdict{/AP << /N \the\pdflastobj\space 0 R >>}%
+ }{}%
+ %3D reference dict
+ \if@MXV@presentation%
+ \ifthenelse{%
+ \equal{\@MXV@getlabelvalue{\@MXV@label.3dref}}{undefined}%
+ }{%
+ \pdfobj {<<%
+ /Type/3DRef%
+ /3DD \@MXV@iiidstream\space 0 R% 3D stream object
+ >>}\pdfrefobj\pdflastobj%
+ \edef\@MXV@iiidstreamorref{\the\pdflastobj}%
+ \@MXV@newlabel{\@MXV@label.3dref}{\the\pdflastobj}%
+ }{%
+ \edef\@MXV@iiidstreamorref{\@MXV@getlabelvalue{\@MXV@label.3dref}}%
+ }%
+ \else%
+ \edef\@MXV@iiidstreamorref{\@MXV@iiidstream}%
+ \fi%
+ %annotation object of subtype `3D'
+ \pdfannot width #2 height #3 depth #4 {%
+ /Subtype/3D%
+ /F 4% we cannot put F 5 here; bug in Reader; 3D annot would be
+ /T (\@MXV@filename)% disabled even if plugin were available
+ /Contents (3D Object (\@MXV@mime))%
+ \ifx\@MXV@@label\@empty\else%
+ /NM (\@MXV@@label)%
+ \fi%
+ /P \@MXV@pdfpageref{@MXV@annot\the\@MXV@includes.page}%
+ \@MXV@apdict% /AP <</N<<>>/R<<>>/D<<>>>> doesn't work here
+ \@MXV@defaultview%
+ \@MXV@iiidia%
+ /3DD \@MXV@iiidstreamorref\space 0 R% 3D stream or reference object
+ /3DA << \@MXV@activation\@MXV@deactivation\@MXV@iiidtoolb >>%
+ }%
+ %label for later annot obj number determination, to be used in
+ %movieref's
+ \ifx\@MXV@@label\@empty\else%
+ \@MXV@labeltoaux{@MXV@\@MXV@@label.annot}{\the\pdflastannot}%
+ \@MXV@newlabel{@MXV@\@MXV@@label.annot}{\the\pdflastannot}%
+ \fi%
+ \fi}}%
+ }%
+ \else\if@MXV@dvipdfmx%
+ %dvipdfmx versions
+ %macro for creating 3D view object
+ \def\@MXV@viewobj{%
+ %projection dict
+ \special{pdf:obj @pdict\the\@MXV@includes_\the\@MXV@viewscount <<%
+ /Subtype/P/FOV \@MXV@aac/PS/Min%
+ >>}%
+ %
+ \special{pdf:obj @viewobj\the\@MXV@includes_\the\@MXV@viewscount <<%
+ /MS/M% define the view as C2W matrix
+ /CO \@MXV@roo% orbital radius
+ /P @pdict\the\@MXV@includes_\the\@MXV@viewscount%
+ /C2W [\@MXV@matrix]%
+ /XN(\@MXV@xname)% name of the view appearing in the drop down list
+ \@MXV@background%
+ \@MXV@lights%
+ \@MXV@render%
+ >>}%
+ \xdef\@MXV@@viewobj{@viewobj\the\@MXV@includes_\the\@MXV@viewscount}%
+ }%
+
+ %macro for creating resource objects from 3D and image files, to be used
+ %in 3D JavaScript
+ \def\@MXV@addresource#1{%
+ %determine file type
+ \filename@parse{#1}%
+ \ifthenelse{%
+ \equal{\filename@ext}{u3d}\OR%
+ \equal{\filename@ext}{U3D}%
+ }{%
+ \def\@MXV@restype{U3D}%
+ }{%
+ \def\@MXV@restype{image}%
+ }%
+ \ifthenelse{\equal{\@MXV@restype}{image}}{%
+ %embed the same image file only once
+ \ifthenelse{\equal{\@MXV@getlabelvalue{\pdfmdfivesum file {#1}}}{undefined}}{%
+ %increment counter of embedded resource files
+ \global\advance\@MXV@rescount by 1%
+ %create Image XObject from next raster image
+ \special{pdf:image @resource\the\@MXV@rescount\space(#1)}%
+ \xdef\@MXV@resourcetree{% build name tree for embedded resources
+ \@MXV@resourcetree\space(#1) @resource\the\@MXV@rescount%
+ }%
+ \@MXV@newlabel{\pdfmdfivesum file {#1}}{@resource\the\@MXV@rescount}%
+ }{%
+ \xdef\@MXV@resourcetree{%
+ \@MXV@resourcetree\space(#1) \@MXV@getlabelvalue{\pdfmdfivesum file {#1}}%
+ }%
+ }%
+ }{%
+ %embed the same 3D file only once
+ \ifthenelse{\equal{\@MXV@getlabelvalue{\pdfmdfivesum file {#1}}}{undefined}}{%
+ \global\advance\@MXV@rescount by 1%
+ \special{pdf:fstream @resource\the\@MXV@rescount\space(#1) <<%
+ /Subtype/\@MXV@restype>>}%
+ \xdef\@MXV@resourcetree{%
+ \@MXV@resourcetree\space(#1) @resource\the\@MXV@rescount%
+ }%
+ \@MXV@newlabel{\pdfmdfivesum file {#1}}{@resource\the\@MXV@rescount}%
+ }{%
+ \xdef\@MXV@resourcetree{%
+ \@MXV@resourcetree\space(#1) \@MXV@getlabelvalue{\pdfmdfivesum file {#1}}%
+ }%
+ }%
+ }%
+ }
+
+ %3D inclusion macro
+ \newcommand{\@MXV@includeiiid}[5][]{%
+ %insert box or poster
+ \@MXV@box{#2}{#3}{#4}%
+ %
+ \if@MXV@externalviewer\else%
+ \setkeys{MXV@iiid}{#1}%process deferred options
+ \ifnum\@MXV@iiidrepeat=0\else%
+ \edef\@MXV@animstyle{% animation style dict
+ /AN <<%
+ \@MXV@iiidpalindrome\@MXV@iiidrate/PC \the\@MXV@iiidrepeat%
+ >>%
+ }%
+ \fi%
+ %java script file, stream object
+ \IfFileExists{\@MXV@jscriptiiidfile}{%
+ \special{pdf:fstream @jscriptiiid\the\@MXV@includes\space(\@MXV@jscriptiiidfile)}%
+ \xdef\@MXV@jscriptiiid{/OnInstantiate @jscriptiiid\the\@MXV@includes}%
+ }{\xdef\@MXV@jscriptiiid{}}%
+ %
+ %build the array of 3D views
+ \@MXV@buildva%
+ \fi%
+ %
+ %3D stream object
+ \if@MXV@inline%
+ \ifthenelse{%
+ \NOT\boolean{@MXV@presentation}\OR%
+ \equal{\@MXV@getlabelvalue{\@MXV@label.3dstream}}{undefined}%
+ }{%
+ \special{pdf:fstream @iiiDfile\the\@MXV@includes\space(#5) <<%
+ /Subtype/\@MXV@iiidsubtype%
+ \if@MXV@externalviewer\else%
+ /VA [\@MXV@varray]%
+ /DV/F% use first entry in VA as default view
+ \@MXV@animstyle%
+ \@MXV@jscriptiiid%
+ \if@MXV@resource%
+ /Resources <</Names [\@MXV@resourcetree]>>%
+ \fi%
+ \fi%
+ >>}%
+ \edef\@MXV@iiidstream{@iiiDfile\the\@MXV@includes}%
+ \if@MXV@presentation%
+ \@MXV@newlabel{\@MXV@label.3dstream}{\@MXV@iiidstream}%
+ \fi%
+ }{%
+ \edef\@MXV@iiidstream{\@MXV@getlabelvalue{\@MXV@label.3dstream}}%
+ }%
+ \fi%
+ %
+ \makebox[0pt][r]{\makebox[#2][l]{%
+ %insert FileAttachment annotation
+ \ifthenelse{\boolean{@MXV@inline}\AND\boolean{@MXV@externalviewer}%
+% since Reader 7.0.7, we cannot place a file attachment annot behind
+% the 3D annot :-(
+% \OR\boolean{@MXV@attachment}
+ }{%
+ \special{pdf:annot width \the#2 height \the#3 depth \the#4 <<%
+ /Subtype /FileAttachment%
+ /F 0%
+ /T (\@MXV@filename)%
+ /Contents (3D Object (\@MXV@mime))%
+ \if@MXV@externalviewer%
+ /Name/Paperclip%
+ /C [1 1 1]%
+ \else%
+ /AP <</N<<>>/R<<>>/D<<>>>>%
+ \fi%
+ /FS <<%
+ /F(#5)%
+ /Type/Filespec%
+ /EF << /F \@MXV@iiidstream >>%
+ >>%
+ >>}%
+ }{%
+ \if@MXV@url%
+ %insert Link annotation, if 3D file is a URL
+ \special{pdf:annot width \the#2 height \the#3 depth \the#4 <<%
+ /Subtype /Link%
+ /F 0%
+ \if@MXV@externalviewer%
+ \@MXV@urlattr%
+ \else%
+ /H /N%
+ /Border [0 0 0]%
+ \fi%
+ /A <</URI (#5) /S/URI>>%
+ /Contents (3D Object (\@MXV@mime))%
+ >>}%
+ \else%
+ %else insert Launch action for local external 3D file
+ \if@MXV@inline\else%
+ \special{pdf:annot width \the#2 height \the#3 depth \the#4 <<%
+ /Subtype /Link%
+ /F 0%
+ \if@MXV@externalviewer%
+ \@MXV@runattr%
+ \else%
+ /H /N%
+ /Border [0 0 0]%
+ \fi%
+ /A <<%
+ /F (#5)%
+ /S /Launch%
+ >>%
+ /Contents (3D Object (\@MXV@mime))%
+ >>}%
+ \fi%
+ \fi%
+ }%
+ %
+ \if@MXV@externalviewer\else%
+ %appearance dict dummy, to be shared by all 3D annots
+ \ifthenelse{\isundefined{\@MXV@apdict}}{%
+ \special{pdf:stream @apdict\space()<</BBox[0 0 0.001 0.001]>>}%
+ \xdef\@MXV@apdict{/AP << /N @apdict >>}%
+ }{}%
+ %3D reference dict
+ \if@MXV@presentation%
+ \ifthenelse{%
+ \equal{\@MXV@getlabelvalue{\@MXV@label.3dref}}{undefined}%
+ }{%
+ \special{pdf:obj @iiiDref\the\@MXV@includes <<%
+ /Type/3DRef%
+ /3DD \@MXV@iiidstream% 3D stream object
+ >>}%
+ \edef\@MXV@iiidstreamorref{@iiiDref\the\@MXV@includes}%
+ \@MXV@newlabel{\@MXV@label.3dref}{\the\pdflastobj}%
+ }{%
+ \edef\@MXV@iiidstreamorref{\@MXV@getlabelvalue{\@MXV@label.3dref}}%
+ }%
+ \else%
+ \edef\@MXV@iiidstreamorref{\@MXV@iiidstream}%
+ \fi%
+ %annotation object of subtype `3D'
+ \special{pdf:annot @3Dannot\the\@MXV@includes\space width \the#2 height \the#3 depth \the#4 <<%
+ /Subtype/3D%
+ /F 4% we cannot put F 5 here; bug in Reader; 3D annot would be
+ /T (\@MXV@filename)% disabled even if plugin were available
+ /Contents (3D Object (\@MXV@mime))%
+ \ifx\@MXV@@label\@empty\else%
+ /NM (\@MXV@@label)%
+ \fi%
+ /P @thispage%
+ \@MXV@apdict% /AP <</N<<>>/R<<>>/D<<>>>> doesn't work here
+ \@MXV@defaultview%
+ \@MXV@iiidia%
+ /3DD \@MXV@iiidstreamorref% 3D stream or reference object
+ /3DA << \@MXV@activation\@MXV@deactivation\@MXV@iiidtoolb >>%
+ >>}%
+ %label for later annot obj number determination, to be used in
+ %movieref's
+ \ifx\@MXV@@label\@empty\else%
+ \@MXV@labeltoaux{@MXV@\@MXV@@label.annot}{@3Dannot\the\@MXV@includes}%
+ \@MXV@newlabel{@MXV@\@MXV@@label.annot}{@3Dannot\the\@MXV@includes}%
+ \fi%
+ \fi}}%
+ }%
+ \else%
+ %dvips versions
+ %macro for creating 3D view object and associated projection dict
+ \def\@MXV@viewobj{%
+ %projection dict
+ \pdfmark{%
+ pdfmark=/OBJ,%
+ Raw={%
+ /_objdef {pdict\the\@MXV@includes_\the\@MXV@viewscount}%
+ /type/dict%
+ }%
+ }%
+ \pdfmark{%
+ pdfmark=/PUT,%
+ Raw={%
+ {pdict\the\@MXV@includes_\the\@MXV@viewscount} <<%
+ /Subtype/P/FOV \@MXV@aac/PS/Min%
+ >>%
+ }%
+ }%
+ %
+ \pdfmark{%
+ pdfmark=/OBJ,%
+ Raw={%
+ /type/dict%
+ /_objdef {viewobj\the\@MXV@includes_\the\@MXV@viewscount}%
+ }%
+ }%
+ \pdfmark{%
+ pdfmark=/PUT,%
+ Raw={%
+ {viewobj\the\@MXV@includes_\the\@MXV@viewscount} <<%
+ /MS/M%
+ /CO \@MXV@roo%
+ /P {pdict\the\@MXV@includes_\the\@MXV@viewscount}%
+ /C2W[\@MXV@matrix]%
+ /XN(\@MXV@xname)%
+ \@MXV@background%
+ \@MXV@lights%
+ \@MXV@render%
+ >>%
+ }%
+ }%
+ \xdef\@MXV@@viewobj{{viewobj\the\@MXV@includes_\the\@MXV@viewscount}}%
+ }%
+ %
+ %macro for creating resource objects from 3D and image files
+ \def\@MXV@addresource#1{%
+ %determine file type
+ \filename@parse{#1}%
+ \ifthenelse{%
+ \equal{\filename@ext}{u3d}\OR%
+ \equal{\filename@ext}{U3D}%
+ }{%
+ \def\@MXV@restype{U3D}%
+ }{%
+ \def\@MXV@restype{image}%
+ }%
+ \ifthenelse{\equal{\@MXV@restype}{image}}{%
+ %embed the same image file only once
+ \ifthenelse{\equal{\@MXV@getlabelvalue{\pdfmdfivesum file {#1}}}{undefined}}{%
+ %increment counter of embedded resource files
+ \global\advance\@MXV@rescount by 1%
+ %create Image XObject from next raster image
+ \special{ps:% read image resource from file
+ [ /_objdef {resource\the\@MXV@rescount} /NI pdfmark
+ save gsave
+ {
+ /showpage {} def
+ /setpagedevice /pop load def
+ newpath clip
+ (#1) run
+ } ?pdfmark
+ 0 0 1 [1 0 0 1 0 0] {} image %empty dummy, in case #1 is not
+ grestore restore %a valid image file
+ }%
+ \xdef\@MXV@resourcetree{% build name tree for embedded resources
+ \@MXV@resourcetree\space (#1) {resource\the\@MXV@rescount}%
+ }%
+ \@MXV@newlabel{\pdfmdfivesum file {#1}}{resource\the\@MXV@rescount}%
+ }{%
+ \xdef\@MXV@resourcetree{%
+ \@MXV@resourcetree\space (#1) {\@MXV@getlabelvalue{\pdfmdfivesum file {#1}}}%
+ }%
+ }%
+ }{%
+ %embed the same 3D file only once
+ \ifthenelse{\equal{\@MXV@getlabelvalue{\pdfmdfivesum file {#1}}}{undefined}}{%
+ \global\advance\@MXV@rescount by 1%
+ \special{ps:
+ [ /_objdef {resource\the\@MXV@rescount} /type/stream /OBJ pdfmark
+ [ {resource\the\@MXV@rescount} <<%
+ /Subtype/\@MXV@restype%
+ >> /PUT pdfmark%
+ [ {resource\the\@MXV@rescount} (#1) (r) file /PUT pdfmark
+ }%
+ \xdef\@MXV@resourcetree{%
+ \@MXV@resourcetree\space (#1) {resource\the\@MXV@rescount}%
+ }%
+ \@MXV@newlabel{\pdfmdfivesum file {#1}}{resource\the\@MXV@rescount}%
+ }{%
+ \xdef\@MXV@resourcetree{%
+ \@MXV@resourcetree\space (#1) {\@MXV@getlabelvalue{\pdfmdfivesum file {#1}}}%
+ }%
+ }%
+ }%
+ }
+ %
+ %3D inclusion macro
+ \newcommand{\@MXV@includeiiid}[5][]{%
+ %
+ \if@MXV@externalviewer\else%
+ \setkeys{MXV@iiid}{#1}%process deferred options
+ \ifnum\@MXV@iiidrepeat=0\else%
+ \edef\@MXV@animstyle{% animation style dict
+ /AN <<%
+ \@MXV@iiidpalindrome\@MXV@iiidrate/PC \the\@MXV@iiidrepeat%
+ >>%
+ }%
+ \fi%
+ %java script file, stream object
+ \IfFileExists{\@MXV@jscriptiiidfile}{%
+ \pdfmark{%
+ pdfmark=/OBJ,%
+ Raw={%
+ /_objdef {jscriptiiid\the\@MXV@includes}%
+ /type/stream%
+ }%
+ }%
+ \pdfmark{%
+ pdfmark=/PUT,%
+ Raw={%
+ {jscriptiiid\the\@MXV@includes}%
+ (\@MXV@jscriptiiidfile) (r) file%
+ }%
+ }%
+ \xdef\@MXV@jscriptiiid{%
+ /OnInstantiate {jscriptiiid\the\@MXV@includes}%
+ }%
+ }{\def\@MXV@jscriptiiid{}}%
+ %
+ %build the array of 3D views
+ \@MXV@buildva%
+ \fi%
+ %
+ %3D stream object
+ \if@MXV@inline%
+ \ifthenelse{%
+ \NOT\boolean{@MXV@presentation}\OR%
+ \equal{\@MXV@getlabelvalue{\@MXV@label.3dstream}}{undefined}%
+ }{%
+ \pdfmark{%
+ pdfmark=/OBJ,%
+ Raw={%
+ /_objdef {iiiDfile\the\@MXV@includes}%
+ /type/stream%
+ }%
+ }%
+ \pdfmark{%
+ pdfmark=/PUT,%
+ Raw={%
+ {iiiDfile\the\@MXV@includes} <<%
+ /Subtype/\@MXV@iiidsubtype%
+ \if@MXV@externalviewer\else%
+ /VA [\@MXV@varray]%
+ /DV/F% use first entry in VA as default view
+ \@MXV@animstyle%
+ \if@MXV@resource%
+ /Resources <<%
+ /Names [\@MXV@resourcetree]%
+ >>%
+ \fi%
+ \@MXV@jscriptiiid%
+ \fi%
+ >>%
+ }%
+ }%
+ \pdfmark{%
+ pdfmark=/PUT,%
+ Raw={%
+ {iiiDfile\the\@MXV@includes}%
+ (#5) (r) file%
+ }%
+ }%
+ \edef\@MXV@iiidstream{iiiDfile\the\@MXV@includes}%
+ \if@MXV@presentation%
+ \@MXV@newlabel{\@MXV@label.3dstream}{\@MXV@iiidstream}%
+ \fi%
+ }{%
+ \edef\@MXV@iiidstream{\@MXV@getlabelvalue{\@MXV@label.3dstream}}%
+ }%
+ \fi%
+ %
+ %insert FileAttachment annotation
+ \ifthenelse{\boolean{@MXV@inline}\AND\boolean{@MXV@externalviewer}%
+% \OR\boolean{@MXV@attachment}
+ }{%
+ \makebox[0pt][l]{%
+ \pdfmark[\phantom{\@MXV@box{#2}{#3}{#4}}]{%
+ pdfmark=/ANN,%
+ Subtype=/FileAttachment,%
+ Raw={%
+ /F 0%
+ /T (\@MXV@filename)%
+ /Contents (3D Object (\@MXV@mime))%
+ \if@MXV@externalviewer%
+ /Name/Paperclip%
+ /C [1 1 1]%
+ \else%
+ /AP <</N<<>>/R<<>>/D<<>>>>%
+ \fi%
+ /FS <<%
+ /F(#5)%
+ /Type/Filespec%
+ /EF <</F {\@MXV@iiidstream}>>%
+ >>%
+ }%
+ }%
+ }%
+ }{%
+ \if@MXV@url%
+ %insert Link annotation, if 3D file is a URL
+ \makebox[0pt][l]{%
+ \pdfmark[\phantom{\@MXV@box{#2}{#3}{#4}}]{%
+ pdfmark=/ANN,%
+ Subtype=/Link,%
+ Raw={%
+ /F 0%
+ \if@MXV@externalviewer%
+ /C [\@urlbordercolor]%
+ /H \@pdfhighlight%
+ \else%
+ /H /N%
+ /Border [0 0 0]%
+ \fi%
+ /Action <</URI (#5) /S/URI>>%
+ /Contents (3D Object (\@MXV@mime))%
+ }%
+ }%
+ }%
+ \else%
+ %else insert Launch action for local external 3D file
+ \if@MXV@inline\else%
+ \makebox[0pt][l]{%
+ \pdfmark[\phantom{\@MXV@box{#2}{#3}{#4}}]{%
+ pdfmark=/ANN,%
+ Subtype=/Link,%
+ Raw={%
+ /F 0%
+ \if@MXV@externalviewer%
+ /C [\@urlbordercolor]%
+ /H \@pdfhighlight%
+ \else%
+ /H /N%
+ /Border [0 0 0]%
+ \fi%
+ /Action <<%
+ /F (#5)%
+ /S /Launch%
+ >>%
+ /Contents (3D Object (\@MXV@mime))%
+ }%
+ }%
+ }%
+ \fi%
+ \fi%
+ }%
+ \if@MXV@externalviewer%
+ \phantom{\@MXV@box{#2}{#3}{#4}}%
+ \else%
+ %appearance dict dummy, to be shared by all 3D annots
+ \ifthenelse{\isundefined{\@MXV@apdict}}{%
+ \pdfmark{%
+ pdfmark=/OBJ,%
+ Raw={%
+ /_objdef {apdict}%
+ /type/stream%
+ }%
+ }%
+ \pdfmark{%
+ pdfmark=/PUT,%
+ Raw={%
+ {apdict}%
+ ()%
+ }%
+ }%
+ \pdfmark{%
+ pdfmark=/PUT,%
+ Raw={%
+ {apdict}
+ <</BBox [0 0 0.001 0.001]>>
+ }%
+ }%
+ \xdef\@MXV@apdict{/AP << /N {apdict}>>}%
+ }{}%
+ %3D reference dict
+ \if@MXV@presentation%
+ \ifthenelse{%
+ \equal{\@MXV@getlabelvalue{\@MXV@label.3dref}}{undefined}%
+ }{%
+ \pdfmark{%
+ pdfmark=/OBJ,%
+ Raw={%
+ /_objdef {iiiDref\the\@MXV@includes}%
+ /type/dict%
+ }%
+ }%
+ \pdfmark{%
+ pdfmark=/PUT,%
+ Raw={%
+ {iiiDref\the\@MXV@includes} <<%
+ /Type/3DRef%
+ /3DD {\@MXV@iiidstream}% 3D stream object
+ >>%
+ }%
+ }%
+ \edef\@MXV@iiidstreamorref{iiiDref\the\@MXV@includes}%
+ \@MXV@newlabel{\@MXV@label.3dref}{\@MXV@iiidstreamorref}%
+ }{%
+ \edef\@MXV@iiidstreamorref{\@MXV@getlabelvalue{\@MXV@label.3dref}}%
+ }%
+ \else%
+ \edef\@MXV@iiidstreamorref{\@MXV@iiidstream}%
+ \fi%
+ %annotation object of subtype `3D'
+ \pdfmark[\phantom{\@MXV@box{#2}{#3}{#4}}]{%
+ pdfmark=/ANN,%
+ Subtype=/3D,%
+ Raw={%
+ /_objdef {3Dannot\the\@MXV@includes}%
+ /F 4%
+ /T (\@MXV@filename)%
+ \ifx\@MXV@@label\@empty\else%
+ /NM (\@MXV@@label)%
+ \fi%
+ /Contents (3D Object (\@MXV@mime))%
+ /P {ThisPage}%
+ \@MXV@apdict% /AP <</N<<>>/R<<>>/D<<>>>> doesn't work here
+ \@MXV@defaultview%
+ \@MXV@iiidia%
+ /3DD {\@MXV@iiidstreamorref}% 3D stream or reference object
+ /3DA <<\@MXV@activation\@MXV@deactivation\@MXV@iiidtoolb>>%
+ }%
+ }%
+ \ifx\@MXV@@label\@empty\else%
+ \@MXV@labeltoaux{@MXV@\@MXV@@label.annot}{\the\@MXV@includes}%
+ \@MXV@newlabel{@MXV@\@MXV@@label.annot}{\the\@MXV@includes}%
+ \fi%
+ \fi%
+ }%
+ \fi\fi%
+}{}
+
+%settings for newly opened media players
+\def\@MXV@settings#1#2#3#4#5#6#7{%
+ var settings={%
+ privateData: {%
+ paused: false
+ },
+ autoPlay: false,
+ visible: false,
+ volume: #7
+ #1% showUI (controls)
+ #2% palindrome
+ #3% repeat
+ #4% rate
+ #5% startAt
+ #6% endAt
+ };
+}
+
+%JavaScript event handler routines for 2D media activation
+\def\@MXV@events#1#2#3{% #1: playerid, #2: mouse?, #3: autoplay?
+ var events=new app.media.Events({%
+ %on focus change from one movie to another, events are fired in the
+ %following order: (1) onBlur, (2) onFocus, (3) afterBlur, (4) afterFocus
+ onBlur: function (e) {%
+ if(focusonplayer > 0){%
+ focusonplayer=0;
+ }
+ },
+ afterBlur: function (e) {%
+ %only resume if we click outside of any media
+ if(focusonplayer==0){%
+ try{
+ e.target.settings.privateData.paused=false;
+ e.target.play();
+ }catch(e){}
+ }
+ },
+ onFocus: function (e) {%
+ focusonplayer=#1;
+ },
+ afterFocus: function (e) {%
+ if(!e.target.isPlaying){%play on click if paused
+ try{
+ e.target.settings.privateData.paused=false;
+ e.target.play();
+ if(!e.target.isPlaying){%still not playing?!
+ %sometimes play() fails, in particular if the movie has reached
+ %its end before getting the focus; but this works:
+ if(
+ e.target.settings.startAt.time
+ || e.target.settings.startAt.frame
+ || e.target.settings.startAt.marker
+ || e.target.id == 'vnd.adobe.swname:AAPL_QuickTime'
+ ){
+ e.target.seek(e.target.settings.startAt);
+ }else{
+ e.target.stop();
+ }
+ e.target.play();
+ }
+ }
+ catch (e){}
+ }
+ \@MXV@if{#2}%
+ else{%
+ %media can only be paused if mouse option is set
+ try{
+ e.target.pause();
+ e.target.settings.privateData.paused=true;
+ }catch (e){}
+ }
+ \fi%
+ \if@MXV@issound\else e.target.visible=true;\fi%
+ },
+ onPlay: function (e) {%
+ e.target.settings.privateData.paused=false;
+ },
+ onPause: function (e) {%
+ e.target.settings.privateData.paused=true;
+ },
+ afterReady: function (e) {%
+ try{
+ if(
+ e.target.settings.startAt.time
+ || e.target.settings.startAt.frame
+ || e.target.settings.startAt.marker
+ ){
+ e.target.play();
+ e.target.pause();
+ e.target.stop();
+ e.target.settings.privateData.paused=false;
+ e.target.seek(e.target.settings.startAt);
+ }
+ \if@MXV@issound\else e.target.visible=true;\fi%
+ \@MXV@if{#3}
+ e.target.settings.privateData.paused=false;
+ e.target.play();
+ \fi
+ }
+ catch (e){}
+ }
+ });
+}%
+
+%output driver specific implementations of the 2D inclusion macro
+\ifpdf%
+ %pdfLaTeX version
+ \def\@MXV@includemovie#1#2#3#4{%
+ %insert box or poster
+ \@MXV@box{#1}{#2}{#3}%
+ %
+ \if@MXV@externalviewer\else%
+ %new action dict
+ \pdfobj reserveobjnum%
+ \@MXV@adict=\pdflastobj%
+ %
+ %new additional actions dict
+ \pdfobj reserveobjnum%
+ \@MXV@aadict=\pdflastobj%
+ %
+ \fi%
+ %embedded file entry `/EF'
+ \if@MXV@inline%
+ %embed the same media file only once
+ \ifthenelse{\equal{\@MXV@getlabelvalue{\pdfmdfivesum file {#4}}}{undefined}}{%
+ \pdfobj stream %
+ attr {%
+ /Type/EmbeddedFile%
+ /Subtype (\@MXV@mime)%
+ }%
+ file {#4}%
+ \pdfrefobj\pdflastobj%
+ \edef\@MXV@efentry{%
+ /EF << /F \the\pdflastobj\space 0 R >>%
+ }%
+ \@MXV@newlabel{\pdfmdfivesum file {#4}}{\the\pdflastobj}%
+ }{%
+ \edef\@MXV@efentry{%
+ /EF << /F \@MXV@getlabelvalue{\pdfmdfivesum file {#4}}\space 0 R >>%
+ }%
+ }%
+ \else\def\@MXV@efentry{}\fi%
+ %
+ \ifthenelse{\boolean{@MXV@externalviewer}\AND\NOT\boolean{@MXV@inline}}{}{%
+ %new file specification object
+ \pdfobj {<<%
+ /F(#4)%
+ \@MXV@fsentry%
+ \@MXV@efentry%
+ /Type/Filespec%
+ >>}\pdfrefobj\pdflastobj%
+ \edef\@MXV@filespec{\the\pdflastobj}%
+ }%
+ %
+ \makebox[0pt][r]{\makebox[#1][l]{%
+ %insert FileAttachment annotation
+ \ifthenelse{\boolean{@MXV@inline}\AND\boolean{@MXV@externalviewer}\OR%
+ \boolean{@MXV@attachment}%
+ }{%
+ \pdfannot width #1 height #2 depth #3 {%
+ /Subtype /FileAttachment%
+ /F 0%
+ /T (\@MXV@filename)%
+ /Contents (Media File (\@MXV@mime))%
+ \if@MXV@externalviewer%
+ %a coloured border, as with external links, would be much nicer
+ /Name/Paperclip%
+ /C [1 1 1]%
+ \else%
+ /AP <</N<<>>/R<<>>/D<<>>>>%
+ \fi%
+ /FS \@MXV@filespec\space 0 R%
+ }%
+ }{%
+ \if@MXV@url%
+ %insert Link annotation, if media file is a URL
+ \pdfannot width #1 height #2 depth #3 {%
+ /Subtype /Link%
+ /F 0%
+ \if@MXV@externalviewer%
+ \@MXV@urlattr%
+ \else%
+ /H /N%
+ /Border [0 0 0]%
+ \fi%
+ /A <</URI (#4) /S/URI>>%
+ /Contents (Media File (\@MXV@mime))%
+ }%
+ \else%
+ %else insert Launch action for local external media file
+ \if@MXV@inline\else%
+ \pdfannot width #1 height #2 depth #3 {%
+ /Subtype /Link%
+ /F 0%
+ \if@MXV@externalviewer%
+ \@MXV@runattr%
+ \else%
+ /H /N%
+ /Border [0 0 0]%
+ \fi%
+ /A <<%
+ /F (#4)%
+ /S /Launch%
+ >>%
+ /Contents (Media File (\@MXV@mime))%
+ }%
+ \fi%
+ \fi%
+ }%
+ %
+ \if@MXV@externalviewer\else%
+ %annotation object of subtype `Screen'
+ \pdfannot width #1 height #2 depth #3 {%
+ /Subtype /Screen%
+ /Border [0 0 0]% no border (PDF-1.1)
+ /BS <</S/S/W 0>>% no border (PDF-1.5)
+ /F 5% disable annot if multimedia is not available
+ /T (\@MXV@filename)%
+ /Contents (Media File (\@MXV@mime))%
+ /P \@MXV@pdfpageref{@MXV@annot\the\@MXV@includes.page} 0 R%
+ /A \the\@MXV@adict\space 0 R%
+ /AA \the\@MXV@aadict\space 0 R%
+ /AP <</N<<>>/R<<>>/D<<>>>>%
+ }\edef\@MXV@screenannot{\the\pdflastannot}%
+ %label for later annot obj number determination, to be used in
+ %movieref's only
+ \ifx\@MXV@@label\@empty\else%
+ \@MXV@labeltoaux{@MXV@\@MXV@@label.annot}{\@MXV@screenannot}%
+ \@MXV@newlabel{@MXV@\@MXV@@label.annot}{\@MXV@screenannot}%
+ \fi%
+ %
+ %new media clip object of subtype `Media Clip Data' (/S/MCD)
+ \pdfobj {<<%
+ /D \@MXV@filespec\space 0 R%
+ /P <</TF(TEMPACCESS)>>%
+ /S/MCD%
+ /CT (\@MXV@mime)%
+ >>}\pdfrefobj\pdflastobj%
+ %
+ %new rendition object of subtype `Media Rendition' (/S/MR)
+ \pdfobj {<<%
+ /C \the\pdflastobj\space 0 R%
+ /S/MR%
+ /SP <</BE<</O 0.0>>>>%
+ /P <<%
+ \@MXV@player%
+ /BE <<%
+ /F 2%
+ \@MXV@@repeat\@MXV@@volume\@MXV@@ctrls%
+ /D <</S /F>>%
+ >>%
+ >>%
+ >>}\edef\@MXV@mediarendition{\the\pdflastobj}\pdfrefobj\pdflastobj%
+ %label for later rendition obj number determination
+ \ifx\@MXV@@label\@empty\else%
+ \@MXV@labeltoaux{@MXV@\@MXV@@label.rendition}{\@MXV@mediarendition}%
+ \@MXV@newlabel{@MXV@\@MXV@@label.rendition}{\@MXV@mediarendition}%
+ \fi%
+ %
+ %action dictionary
+ \pdfobj useobjnum \@MXV@adict {<<%
+ /R \@MXV@mediarendition\space 0 R%
+ /S/Rendition%
+ /OP 0% fallback if /JS doesn't work or is empty
+ \@MXV@activationjsentry%
+ /AN \@MXV@screenannot\space 0 R%
+ >>}\pdfrefobj\pdflastobj%
+ %
+ %create play/stop/resume/pause actions
+ \pdfobj {<<%
+ /R \@MXV@mediarendition\space 0 R%
+ /S/Rendition%
+ \@MXV@pageopenopentry% /OP fallback if /JS doesn't work
+ \@MXV@pageopenjsentry%
+ /AN \@MXV@screenannot\space 0 R%
+ >>}\edef\@MXV@pageopenaction{\the\pdflastobj}\pdfrefobj\pdflastobj%
+ %
+ \pdfobj {<<%
+ /R \@MXV@mediarendition\space 0 R%
+ /S/Rendition%
+ \@MXV@pagecloseopentry%
+ \@MXV@pageclosejsentry%
+ /AN \@MXV@screenannot\space 0 R%
+ >>}\edef\@MXV@pagecloseaction{\the\pdflastobj}\pdfrefobj\pdflastobj%
+ %
+ %populate additional actions dictionary
+ \pdfobj useobjnum \@MXV@aadict {<<%
+ /PO \@MXV@pageopenaction\space 0 R%
+ /PC \@MXV@pagecloseaction\space 0 R%
+ >>}\pdfrefobj\pdflastobj%
+ \fi}}%
+ }%
+\else\if@MXV@dvipdfmx
+ %dvipdfmx version
+ \def\@MXV@includemovie#1#2#3#4{%
+ %insert box or poster
+ \@MXV@box{#1}{#2}{#3}%
+ %
+ \if@MXV@externalviewer\else%
+ %new action dict
+ \special{pdf:obj @MXV@adict\the\@MXV@includes << >>}%
+ %
+ %new additional actions dict
+ \special{pdf:obj @MXV@aadict\the\@MXV@includes << >>}%
+ %
+ \fi%
+ %embedded file entry `/EF'
+ \if@MXV@inline%
+ %embed the same media file only once
+ \ifthenelse{\equal{\@MXV@getlabelvalue{\pdfmdfivesum file {#4}}}{undefined}}{%
+ \special{pdf:fstream @fstream\the\@MXV@includes\space(#4) <<%
+ /Type/EmbeddedFile%
+ /Subtype (\@MXV@mime)%
+ >>}%
+ \edef\@MXV@efentry{%
+ /EF << /F @fstream\the\@MXV@includes >>%
+ }%
+ \@MXV@newlabel{\pdfmdfivesum file {#4}}{@fstream\the\@MXV@includes}%
+ }{%
+ \edef\@MXV@efentry{%
+ /EF << /F \@MXV@getlabelvalue{\pdfmdfivesum file {#4}} >>%
+ }%
+ }%
+ \else\def\@MXV@efentry{}\fi%
+ %
+ \ifthenelse{\boolean{@MXV@externalviewer}\AND\NOT\boolean{@MXV@inline}}{}{%
+ %new file specification object
+ \special{pdf:obj @filespec\the\@MXV@includes <<%
+ /F(#4)%
+ \@MXV@fsentry%
+ \@MXV@efentry%
+ /Type/Filespec%
+ >>}%
+ \edef\@MXV@filespec{@filespec\the\@MXV@includes}%
+ }%
+ %
+ \makebox[0pt][r]{\makebox[#1][l]{%
+ %insert FileAttachment annotation
+ \ifthenelse{\boolean{@MXV@inline}\AND\boolean{@MXV@externalviewer}\OR%
+ \boolean{@MXV@attachment}%
+ }{%
+ \special{pdf:annot width \the#1 height \the#2 depth \the#3 <<%
+ /Subtype /FileAttachment%
+ /F 0%
+ /T (\@MXV@filename)%
+ /Contents (Media File (\@MXV@mime))%
+ \if@MXV@externalviewer%
+ %a coloured border, as with external links, would be much nicer
+ /Name/Paperclip%
+ /C [1 1 1]%
+ \else%
+ /AP <</N<<>>/R<<>>/D<<>>>>%
+ \fi%
+ /FS \@MXV@filespec%
+ >>}%
+ }{%
+ \if@MXV@url%
+ %insert Link annotation, if media file is a URL
+ \special{pdf:annot width \the#1 height \the#2 depth \the#3 <<%
+ /Subtype /Link%
+ /F 0%
+ \if@MXV@externalviewer%
+ \@MXV@urlattr%
+ \else%
+ /H /N%
+ /Border [0 0 0]%
+ \fi%
+ /A <</URI (#4) /S/URI>>%
+ /Contents (Media File (\@MXV@mime))%
+ >>}%
+ \else%
+ %else insert Launch action for local external media file
+ \if@MXV@inline\else%
+ \special{pdf:annot width \the#1 height \the#2 depth \the#3 <<%
+ /Subtype /Link%
+ /F 0%
+ \if@MXV@externalviewer%
+ \@MXV@runattr%
+ \else%
+ /H /N%
+ /Border [0 0 0]%
+ \fi%
+ /A <<%
+ /F (#4)%
+ /S /Launch%
+ >>%
+ /Contents (Media File (\@MXV@mime))%
+ >>}%
+ \fi%
+ \fi%
+ }%
+ %
+ \if@MXV@externalviewer\else%
+ %annotation object of subtype `Screen'
+ \special{pdf:annot @screenannot\the\@MXV@includes\space width \the#1 height \the#2 depth \the#3 <<%
+ /Subtype /Screen%
+ /Border [0 0 0]% no border (PDF-1.1)
+ /BS <</S/S/W 0>>% no border (PDF-1.5)
+ /F 5% disable annot if multimedia is not available
+ /T (\@MXV@filename)%
+ /Contents (Media File (\@MXV@mime))%
+ /P @thispage%
+ /A @MXV@adict\the\@MXV@includes%
+ /AA @MXV@aadict\the\@MXV@includes%
+ /AP <</N<<>>/R<<>>/D<<>>>>%
+ >>}%
+ \edef\@MXV@screenannot{@screenannot\the\@MXV@includes}%
+ %label for later annot obj number determination, to be used in
+ %movieref's only
+ \ifx\@MXV@@label\@empty\else%
+ \@MXV@labeltoaux{@MXV@\@MXV@@label.annot}{\@MXV@screenannot}%
+ \@MXV@newlabel{@MXV@\@MXV@@label.annot}{\@MXV@screenannot}%
+ \fi%
+ %
+ %new media clip object of subtype `Media Clip Data' (/S/MCD)
+ \special{pdf:obj @mediaclipdata\the\@MXV@includes <<%
+ /D \@MXV@filespec%
+ /P <</TF(TEMPACCESS)>>%
+ /S/MCD%
+ /CT (\@MXV@mime)%
+ >>}%
+ %
+ %new rendition object of subtype `Media Rendition' (/S/MR)
+ \special{pdf:obj @mediarendition\the\@MXV@includes <<%
+ /C @mediaclipdata\the\@MXV@includes%
+ /S/MR%
+ /SP <</BE<</O 0.0>>>>%
+ /P <<%
+ \@MXV@player%
+ /BE <<%
+ /F 2%
+ \@MXV@@repeat\@MXV@@volume\@MXV@@ctrls%
+ /D <</S /F>>%
+ >>%
+ >>%
+ >>}%
+ \edef\@MXV@mediarendition{@mediarendition\the\@MXV@includes}%
+ %label for later rendition obj number determination
+ \ifx\@MXV@@label\@empty\else%
+ \@MXV@labeltoaux{@MXV@\@MXV@@label.rendition}{\@MXV@mediarendition}%
+ \@MXV@newlabel{@MXV@\@MXV@@label.rendition}{\@MXV@mediarendition}%
+ \fi%
+ %
+ %action dictionary
+ \special{pdf:put @MXV@adict\the\@MXV@includes <<%
+ /R \@MXV@mediarendition%
+ /S/Rendition%
+ /OP 0% fallback if /JS doesn't work or is empty
+ \@MXV@activationjsentry%
+ /AN \@MXV@screenannot%
+ >>}%
+ %
+ %create play/stop/resume/pause actions
+ \special{pdf:obj @pageopenaction\the\@MXV@includes <<%
+ /R \@MXV@mediarendition%
+ /S/Rendition%
+ \@MXV@pageopenopentry% /OP fallback if /JS doesn't work
+ \@MXV@pageopenjsentry%
+ /AN \@MXV@screenannot%
+ >>}%
+ \edef\@MXV@pageopenaction{@pageopenaction\the\@MXV@includes}%
+ %
+ \special{pdf:obj @pagecloseaction\the\@MXV@includes <<%
+ /R \@MXV@mediarendition%
+ /S/Rendition%
+ \@MXV@pagecloseopentry%
+ \@MXV@pageclosejsentry%
+ /AN \@MXV@screenannot%
+ >>}%
+ \edef\@MXV@pagecloseaction{@pagecloseaction\the\@MXV@includes}%
+ %
+ %populate additional actions dictionary
+ \special{pdf:put @MXV@aadict\the\@MXV@includes <<%
+ /PO \@MXV@pageopenaction%
+ /PC \@MXV@pagecloseaction%
+ >>}%
+ \fi}}%
+ }%
+\else%
+ %dvips version
+ \def\@MXV@includemovie#1#2#3#4{%
+ %insert FileAttachment annotation
+ \ifthenelse{\boolean{@MXV@inline}\AND\boolean{@MXV@externalviewer}\OR%
+ \boolean{@MXV@attachment}%
+ }{%
+ \makebox[0pt][l]{%
+ \pdfmark[\phantom{\@MXV@box{#1}{#2}{#3}}]{%
+ pdfmark=/ANN,%
+ Subtype=/FileAttachment,%
+ Raw={%
+ /F 0%
+ /T (\@MXV@filename)%
+ /Contents (Media File (\@MXV@mime))%
+ \if@MXV@externalviewer%
+ /Name/Paperclip%
+ /C [1 1 1]%
+ \else%
+ /AP <</N<<>>/R<<>>/D<<>>>>%
+ \fi%
+ /FS {filespec\the\@MXV@includes}%
+ }%
+ }%
+ }%
+ }{%
+ \if@MXV@url%
+ %insert Link annotation, if media file is a URL
+ \makebox[0pt][l]{%
+ \pdfmark[\phantom{\@MXV@box{#1}{#2}{#3}}]{%
+ pdfmark=/ANN,%
+ Subtype=/Link,%
+ Raw={%
+ /F 0%
+ \if@MXV@externalviewer%
+ /C [\@urlbordercolor]%
+ /H \@pdfhighlight%
+ \else%
+ /H /N%
+ /Border [0 0 0]%
+ \fi%
+ /Action <</URI (#4) /S/URI>>%
+ /Contents (Media File (\@MXV@mime))%
+ }%
+ }%
+ }%
+ \else%
+ %else insert Launch action for local external media file
+ \if@MXV@inline\else%
+ \makebox[0pt][l]{%
+ \pdfmark[\phantom{\@MXV@box{#1}{#2}{#3}}]{%
+ pdfmark=/ANN,%
+ Subtype=/Link,%
+ Raw={%
+ /F 0%
+ \if@MXV@externalviewer%
+ /C [\@urlbordercolor]%
+ /H \@pdfhighlight%
+ \else%
+ /H /N%
+ /Border [0 0 0]%
+ \fi%
+ /Action <<%
+ /F (#4)%
+ /S /Launch%
+ >>%
+ /Contents (Media File (\@MXV@mime))%
+ }%
+ }%
+ }%
+ \fi%
+ \fi%
+ }%
+ %
+ \if@MXV@externalviewer%
+ \@MXV@box{#1}{#2}{#3}%
+ \else%
+ %annotation object of subtype `Screen'
+ \pdfmark[\@MXV@box{#1}{#2}{#3}]{%
+ pdfmark=/ANN,%
+ Subtype=/Screen,%
+ Border={0 0 0},%
+ Raw={%
+ /_objdef {screenannot\the\@MXV@includes}%
+ /F 5%
+ /T (\@MXV@filename)%
+ /Contents (Media File (\@MXV@mime))%
+ /BS <</S/S/W 0>>% no border (PDF-1.5)
+ /P {ThisPage}%
+ /AA {aadict\the\@MXV@includes}%
+ /AP <</N<<>>/R<<>>/D<<>>>>%
+ }%
+ }%
+ \ifx\@MXV@@label\@empty\else%
+ \@MXV@labeltoaux{@MXV@\@MXV@@label.annot}{\the\@MXV@includes}%
+ \@MXV@newlabel{@MXV@\@MXV@@label.annot}{\the\@MXV@includes}%
+ \fi%
+ %
+ %entire action entry moved outside screen annotation
+ \pdfmark{%
+ pdfmark=/PUT,%
+ Raw={%
+ {screenannot\the\@MXV@includes} <<%
+ /A <<%
+ /R {mediarendition\the\@MXV@includes}%
+ /S/Rendition%
+ /OP 0% fallback, if /JS doesn't work or is empty
+ \@MXV@activationjsentry%
+ /AN {screenannot\the\@MXV@includes}%
+ >>%
+ >>%
+ }%
+ }%
+ %
+ %new rendition object of subtype `Media Rendition' (/S/MR)
+ \pdfmark{%
+ pdfmark=/OBJ,%
+ Raw={%
+ /type/dict%
+ /_objdef {mediarendition\the\@MXV@includes}%
+ }%
+ }%
+ \pdfmark{%
+ pdfmark=/PUT,%
+ Raw={%
+ {mediarendition\the\@MXV@includes} <<%
+ /C {mediaclipdata\the\@MXV@includes}%
+ /S/MR%
+ %screen parameters: fully transparent, hidden if audio mime type
+ /SP <</BE<</O 0.0>>>>%
+ /P <<%Media Play Parameters
+ \@MXV@player%
+ /BE <<%Parameters need only be honored by the player in
+ %the best effort sense
+ /F 2%scale media's width and height to fit the
+ %annotation rectangle
+ \@MXV@@repeat\@MXV@@volume\@MXV@@ctrls%
+ /D <</S /F>>%movie remains opened
+ >>%
+ >>%
+ >>%
+ }%
+ }%
+ %
+ %new media clip object of subtype `Media Clip Data' (/S/MCD)
+ \pdfmark{%
+ pdfmark=/OBJ,%
+ Raw={%
+ /_objdef {mediaclipdata\the\@MXV@includes}%
+ /type/dict%
+ }%
+ }%
+ \pdfmark{%
+ pdfmark=/PUT,%
+ Raw={%
+ {mediaclipdata\the\@MXV@includes} <<%
+ /D {filespec\the\@MXV@includes}%
+ /P <</TF(TEMPACCESS)>>%
+ /S/MCD%
+ /CT (\@MXV@mime)% mime type
+ >>%
+ }%
+ }%
+ \fi%
+ %
+ %new file specification object
+ \ifthenelse{\boolean{@MXV@externalviewer}\AND\NOT\boolean{@MXV@inline}}{}{%
+ \pdfmark{%
+ pdfmark=/OBJ,%
+ Raw={%
+ /_objdef {filespec\the\@MXV@includes}%
+ /type/dict%
+ }%
+ }%
+ \pdfmark{%
+ pdfmark=/PUT,%
+ Raw={%
+ {filespec\the\@MXV@includes} <<%
+ \@MXV@fsentry
+ /F(#4)% file name
+ /Type/Filespec%
+ >>%
+ }%
+ }%
+ }%
+ %
+ %embedded file entry `/EF'
+ \if@MXV@inline%
+ %embed the same media file only once
+ \ifthenelse{\equal{\@MXV@getlabelvalue{\pdfmdfivesum file {#4}}}{undefined}}{%
+ %new stream object
+ \pdfmark{%
+ pdfmark=/OBJ,%
+ Raw={%
+ /_objdef {fstream\the\@MXV@includes}%
+ /type/stream%
+ }%
+ }%
+ \pdfmark{%
+ pdfmark=/PUT,%
+ Raw={%
+ {fstream\the\@MXV@includes}%
+ (#4) (r) file% read in file contents
+ }%
+ }%
+ \pdfmark{%
+ pdfmark=/PUT,%
+ Raw={%
+ {fstream\the\@MXV@includes} <<%
+ /Type/EmbeddedFile%
+ /Subtype(\@MXV@mime)%
+ >>%
+ }%
+ }%
+ \edef\@MXV@moviestream{fstream\the\@MXV@includes}%
+ \@MXV@newlabel{\pdfmdfivesum file {#4}}{fstream\the\@MXV@includes}%
+ }{%
+ \edef\@MXV@moviestream{\@MXV@getlabelvalue{\pdfmdfivesum file {#4}}}%
+ }%
+ % put the embedded file entry into file spec object
+ \pdfmark{%
+ pdfmark=/PUT,%
+ Raw={%
+ {filespec\the\@MXV@includes} <<%
+ /EF << /F {\@MXV@moviestream} >>%
+ >>%
+ }%
+ }%
+ \fi%
+ %
+ \if@MXV@externalviewer\else%
+ %create actions for page open/close events
+ \pdfmark{%
+ pdfmark=/OBJ,%
+ Raw={%
+ /_objdef {pageopenaction\the\@MXV@includes}%
+ /type/dict%
+ }%
+ }%
+ \pdfmark{%
+ pdfmark=/PUT,%
+ Raw={%
+ {pageopenaction\the\@MXV@includes} <<%
+ /R {mediarendition\the\@MXV@includes}%
+ /S/Rendition%
+ \@MXV@pageopenopentry% /OP fallback, if /JS doesn't work
+ \@MXV@pageopenjsentry%
+ /AN {screenannot\the\@MXV@includes}%
+ >>%
+ }%
+ }%
+ \pdfmark{%
+ pdfmark=/OBJ,%
+ Raw={%
+ /_objdef {pagecloseaction\the\@MXV@includes}%
+ /type/dict%
+ }%
+ }%
+ \pdfmark{%
+ pdfmark=/PUT,%
+ Raw={%
+ {pagecloseaction\the\@MXV@includes} <<%
+ /R {mediarendition\the\@MXV@includes}%
+ /S/Rendition%
+ \@MXV@pagecloseopentry%
+ \@MXV@pageclosejsentry%
+ /AN {screenannot\the\@MXV@includes}%
+ >>%
+ }%
+ }%
+ %
+ %create and populate additional actions dictionary, always add entries
+ %for page open/close events
+ \pdfmark{%
+ pdfmark=/OBJ,%
+ Raw={%
+ /type/dict%
+ /_objdef {aadict\the\@MXV@includes}%
+ }%
+ }%
+ %
+ \pdfmark{%
+ pdfmark=/PUT,%
+ Raw={%
+ {aadict\the\@MXV@includes} <<%
+ /PO {pageopenaction\the\@MXV@includes}%
+ /PC {pagecloseaction\the\@MXV@includes}%
+ >>%
+ }%
+ }%
+ \fi%
+ }%
+\fi\fi
+
+%definition of user command `\includemovie'
+\newcommand{\includemovie}[4][]{%
+ %test for hyperref package
+ \ifpdf\else%
+ \ifthenelse{\isundefined{\pdfmark}\AND\isundefined{\@pdfm@mark}}{\@MXV@missing{hyperref}}{}%
+ \fi%
+ %
+ \leavevmode%
+ \@MXV@reset% all macros and options
+ \setkeys{MXV@user}{#1}% parse options
+ %
+ %total height of text
+ \@MXV@totalheight=\@MXV@height%
+ \advance\@MXV@totalheight by \@MXV@depth%
+ %traiselen=distance at which text is to be raised to centre it vertically
+ %braiselen=vertical centre of media box (auxiliary measure)
+ \@MXV@traiselen=0.5\@MXV@height%
+ \advance\@MXV@traiselen by -0.5\@MXV@depth%
+ %
+ \ifthenelse{\equal{#3}{}}{% no height argument
+ \@MXV@braiselen=0.5\@MXV@height%
+ }{%override height of text, height argument given
+ \@MXV@braiselen=#3%
+ \@MXV@braiselen=0.5\@MXV@braiselen%
+ \setlength{\@MXV@height}{#3}%
+ }%
+ %
+ \ifthenelse{\equal{\@MXV@boxdepth}{}}{% no depth option given
+ \ifthenelse{\lengthtest{\@MXV@totalheight>\@MXV@height}}{%
+ %depth of text only taken into account, if the total height
+ %is smaller than the height of the display box
+ \advance\@MXV@braiselen by -0.5\@MXV@depth%
+ }{%
+ \@MXV@depth=0pt%
+ }%
+ }{%override depth of text, depth option given
+ \setlength{\@MXV@@boxdepth}{\@MXV@boxdepth}%
+ \advance\@MXV@braiselen by -0.5\@MXV@@boxdepth%
+ \setlength{\@MXV@depth}{\@MXV@boxdepth}%
+ }%
+ %finally centre text vertically
+ \ifthenelse{\NOT\equal{#3}{}\OR\NOT\equal{\@MXV@boxdepth}{}}{%
+ \advance\@MXV@traiselen by -\@MXV@braiselen%
+ \@MXV@traiselen=-\@MXV@traiselen%
+ \savebox{\@MXV@textbox}{\raisebox{\@MXV@traiselen}[0pt][0pt]{%
+ \usebox{\@MXV@textbox}}}%
+ }{}%
+ \ifthenelse{\equal{#2}{}}{}{%override horiz. dimension of text
+ \setlength{\@MXV@width}{#2}%
+ %centre text horizontally
+ \savebox{\@MXV@textbox}{\makebox[\@MXV@width][c]{\usebox{\@MXV@textbox}}}%
+ }%
+ %
+ %find out whether the contents should be hidden or not (for presentations)
+ \setboolean{@MXV@hide}{false}%
+% \ifthenelse{\boolean{@MXV@powerdot}}{%
+% \ifthenelse{\boolean{pd@overlay}}{}{%
+% \ifthenelse{\pd@method=2}{}{%
+% \setboolean{@MXV@hide}{true}%
+% }%
+% }%
+% }{}%
+ \ifthenelse{\boolean{@MXV@beamer}}{%
+ \ifthenelse{\boolean{beamer@anotherslide}}{%
+ \setboolean{@MXV@hide}{true}%
+ }{}%
+ }{}%
+ %
+ \ifthenelse{\boolean{@MXV@hide}}{%
+ %insert whitespace instead of annot
+ \phantom{\vrule width \@MXV@width height \@MXV@height depth \@MXV@depth}%
+ }{%
+ \ifthenelse{\NOT\boolean{@MXV@url}\AND\boolean{@MXV@inline}}{%
+ \IfFileExists{#4}{}{%
+ \PackageError{movie15}{%
+ File `#4' cannot be opened for embedding.\MessageBreak
+ Did you forget to set option `url' or `inline=false'?
+ }{%
+ Try any of the options `url' or `inline=false'!
+ }%
+ }%
+ }{}%
+ %
+ %guess the mime type based on the filename extension
+ \filename@parse{#4}%
+ \ifthenelse{\equal{\@MXV@mime}{@MXV@auto}}{%
+ \@MXV@guessmime{#4}{\filename@ext}}{}%
+ \if\filename@ext\relax%
+ \xdef\@MXV@filename{\filename@base}%
+ \else%
+ \xdef\@MXV@filename{\filename@base.\filename@ext}%
+ \fi%
+ \expandafter\@MXV@@issound\@MXV@mime:%
+ %
+ %if 3D object is not embedded inline we must use some external player :(
+ \ifthenelse{%
+ \boolean{@MXV@iiid}%
+ \AND\NOT\boolean{@MXV@inline}%
+ }{%
+ \setboolean{@MXV@externalviewer}{true}%
+ }{}%
+ %
+ %some link attributes (if hyperref not loaded)
+ \ifthenelse{\isundefined{\@pdfborder}}{%
+ \def\@MXV@urlattr{}%
+ \def\@MXV@runattr{}%
+ }{%
+ \edef\@MXV@urlattr{%
+ \if@MXV@beamer%
+ /Border [1 1 1]%
+ \else%
+ /Border [\@pdfborder]%
+ \fi%
+ /C [\@urlbordercolor]%
+ /H \@pdfhighlight%
+ }%
+ \edef\@MXV@runattr{%
+ \if@MXV@beamer%
+ /Border [1 1 1]%
+ \else%
+ /Border [\@pdfborder]%
+ \fi%
+ /C [\@runbordercolor]%
+ /H \@pdfhighlight%
+ }%
+ }%
+ %
+ \global\advance\@MXV@includes by 1%increment counter
+ %
+ %label this annotation for later page number determination
+ \@MXV@labeltoaux{@MXV@annot\the\@MXV@includes.page}{%
+ \noexpand\the\@MXV@page}%
+ %
+ %label this annotation for later annot id number determination &
+ %check for multiply-defined labels
+ % \@MXV@label --> automatic (presentation mode) or user defined label
+ % \@MXV@@label = \@MXV@label (non presentation doc classes)
+ % \@MXV@@label = \@MXV@label + physical page No. (presentation mode)
+ \ifx\@MXV@label\@empty%
+ %when used with presentation packages, annots must be labelled,
+ %use the media file name, if no label provided
+ \ifthenelse{\boolean{@MXV@presentation}}{%
+ \xdef\@MXV@label{#4}%
+ }{}%
+ \fi%
+ \ifx\@MXV@label\@empty\else%
+ \ifthenelse{\boolean{@MXV@presentation}}{%
+ %in presentation mode, the label must be extended by the physical page No.
+ \xdef\@MXV@@label{\@MXV@label.\@MXV@getlabelvalue{@MXV@annot\the\@MXV@includes.page}}%
+ }{%
+ \xdef\@MXV@@label{\@MXV@label}%
+ }%
+ \fi%
+ \ifx\@MXV@@label\@empty\else%
+ \ifthenelse{%
+ \NOT\equal{\@MXV@getlabelvalue{@MXV@\@MXV@@label.annotid}}{undefined}%
+ \AND%
+ \NOT\equal{\@MXV@getlabelvalue{@MXV@\@MXV@@label.annotid}}{%
+ \the\@MXV@includes}%
+ }{%
+ \PackageWarning{movie15}{%
+ Label `\@MXV@label' multiply defined%
+ }%
+ \ifthenelse{\isundefined{\@MXV@multiwarning}}{%
+ \gdef\@MXV@multiwarning{}%
+ \AtEndDocument{%
+ \PackageWarningNoLine{movie15}{%
+ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\MessageBreak
+ @@ There were multiply-defined labels! @@\MessageBreak
+ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@}%
+ }%
+ }{}%
+ }{}%
+ \if@MXV@@draft%
+ \@MXV@labeltoaux{@MXV@\@MXV@label.draft}{true}%
+ \else%
+ \@MXV@labeltoaux{@MXV@\@MXV@label.draft}{false}%
+ \fi%
+ \@MXV@labeltoaux{@MXV@\@MXV@@label.annotid}{\the\@MXV@includes}%
+ \if@MXV@presentation\else%
+ \@MXV@newlabel{@MXV@\@MXV@@label.annotid}{\the\@MXV@includes}%
+ \fi%
+ \fi%
+ %
+ \ifthenelse{\boolean{@MXV@@draft}}{}{%
+ \ifthenelse{\boolean{@MXV@externalviewer}}{%
+ \ifx\@MXV@label\@empty\else%
+ \@MXV@labeltoaux{@MXV@\@MXV@label.externalviewer}{true}%
+ \@MXV@newlabel{@MXV@\@MXV@label.externalviewer}{true}%
+ \fi%
+ }{%
+ %what is to be put into movie link annot depends on the following
+ \ifx\@MXV@label\@empty\else%
+ \@MXV@labeltoaux{@MXV@\@MXV@label.externalviewer}{false}%
+ \@MXV@newlabel{@MXV@\@MXV@label.externalviewer}{false}%
+ \fi%
+ %
+ %depending on options do content specific stuff
+ \ifthenelse{\boolean{@MXV@iiid}}{%
+ % #### 3D ####
+ \if@MXV@externalviewer\else%
+ \ifthenelse{\equal{\@MXV@iiidpalindrome}{/Subtype/Oscillating}}{%
+ \global\multiply\@MXV@iiidrepeat by 2%
+ }{}%
+ \ifthenelse{\boolean{@MXV@autoplay}\OR\boolean{@MXV@autoresume}}{%
+ \def\@MXV@activation{/A/PV/AIS/L}% open 3D object, run animation
+ }{%
+ \if@MXV@runposter%
+ \def\@MXV@activation{/A/PV/AIS/I}%open 3D obj but don't run animation
+ \else%
+ \def\@MXV@activation{/A/XA}% explicit activation by user
+ \fi%
+ }%
+ \if@MXV@autostop%
+ \def\@MXV@deactivation{/D/PI/DIS/I}%
+ \else%
+ \if@MXV@autopause%
+ \def\@MXV@deactivation{/D/PI/DIS/I}%
+ \else%
+ \if@MXV@autoclose%
+ \def\@MXV@deactivation{/D/PI/DIS/U}%
+ \else%@MXV@continue
+ \def\@MXV@deactivation{/D/PI/DIS/L}%
+ \fi%
+ \fi%
+ \fi%
+ %counter for 3D inclusion on current page
+ \ifthenelse{%
+ \equal{%
+ \@MXV@getlabelvalue{@MXV@annot\the\@MXV@includes.page}%
+ }{\@MXV@oldpage}%
+ }{%
+ \global\advance\@MXV@iiidoncurpage by 1%
+ }{%
+ \global\@MXV@iiidoncurpage=1%
+ }%
+ \xdef\@MXV@oldpage{\@MXV@getlabelvalue{%
+ @MXV@annot\the\@MXV@includes.page}}%
+ \fi%
+ \ifx\@MXV@label\@empty\else%
+ \@MXV@labeltoaux{@MXV@\@MXV@label.3D}{true}%
+ \@MXV@newlabel{@MXV@\@MXV@label.3D}{true}%
+ \@MXV@labeltoaux{@MXV@\@MXV@label.3Dlights}{\@MXV@lights}%
+ \@MXV@newlabel{@MXV@\@MXV@label.3Dlights}{\@MXV@lights}%
+ \@MXV@labeltoaux{@MXV@\@MXV@label.3Drender}{\@MXV@render}%
+ \@MXV@newlabel{@MXV@\@MXV@label.3Drender}{\@MXV@render}%
+ \fi%
+ \ifx\@MXV@@label\@empty\else%
+ \@MXV@labeltoaux{@MXV@\@MXV@@label.3Doncurpage}{\the\@MXV@iiidoncurpage}%
+ \@MXV@newlabel{@MXV@\@MXV@@label.3Doncurpage}{\the\@MXV@iiidoncurpage}%
+ \fi%
+ }{%#### 2D ####
+ %get the player ID
+ \if@MXV@presentation%
+ \ifthenelse{%
+ \equal{\@MXV@getlabelvalue{@MXV@\@MXV@label.playerid}}{undefined}%
+ }{%
+ \global\advance\@MXV@players by 1%increment counter
+ }{%
+ \global\@MXV@players=\@MXV@getlabelvalue{@MXV@\@MXV@label.playerid}%
+ }%
+ \@MXV@labeltoaux{@MXV@\@MXV@label.playerid}{\the\@MXV@players}%
+ \@MXV@newlabel{@MXV@\@MXV@label.playerid}{\the\@MXV@players}%
+ \edef\@MXV@currplayer{\the\@MXV@players}%
+ \else%
+ \ifx\@MXV@label\@empty\else%
+ \@MXV@labeltoaux{@MXV@\@MXV@label.playerid}{\the\@MXV@includes}%
+ \@MXV@newlabel{@MXV@\@MXV@label.playerid}{\the\@MXV@includes}%
+ \fi%
+ \edef\@MXV@currplayer{\the\@MXV@includes}%
+ \fi%
+ %
+ \ifx\@MXV@startat\@empty% default start position
+ \gdef\@MXV@startat{, startAt: 0}%
+ \fi%
+ %write player settings to aux file
+ \ifx\@MXV@label\@empty\else%
+ \@MXV@labeltoaux{@MXV@\@MXV@label.mouse}{%
+ \if@MXV@mouse true\else false\fi}%
+ \@MXV@labeltoaux{@MXV@\@MXV@label.showUI}{\@MXV@ctrls}%
+ \@MXV@labeltoaux{@MXV@\@MXV@label.palindrome}{\@MXV@palindrome}%
+ \@MXV@labeltoaux{@MXV@\@MXV@label.repeat}{\@MXV@repeat}%
+ \@MXV@labeltoaux{@MXV@\@MXV@label.rate}{\@MXV@rate}%
+ \@MXV@labeltoaux{@MXV@\@MXV@label.startAt}{\@MXV@startat}%
+ \@MXV@labeltoaux{@MXV@\@MXV@label.endAt}{\@MXV@endat}%
+ \@MXV@labeltoaux{@MXV@\@MXV@label.volume}{\@MXV@volume}%
+ \@MXV@labeltoaux{@MXV@\@MXV@label.autoplay}{%
+ \if@MXV@autoplay true\else false\fi}%
+ \@MXV@labeltoaux{@MXV@\@MXV@label.3D}{false}%
+ \@MXV@labeltoaux{@MXV@\@MXV@label.issound}{%
+ \if@MXV@issound true\else false\fi}%
+ %
+ \@MXV@newlabel{@MXV@\@MXV@label.mouse}{%
+ \if@MXV@mouse true\else false\fi}%
+ \@MXV@newlabel{@MXV@\@MXV@label.showUI}{\@MXV@ctrls}%
+ \@MXV@newlabel{@MXV@\@MXV@label.palindrome}{\@MXV@palindrome}%
+ \@MXV@newlabel{@MXV@\@MXV@label.repeat}{\@MXV@repeat}%
+ \@MXV@newlabel{@MXV@\@MXV@label.rate}{\@MXV@rate}%
+ \@MXV@newlabel{@MXV@\@MXV@label.startAt}{\@MXV@startat}%
+ \@MXV@newlabel{@MXV@\@MXV@label.endAt}{\@MXV@endat}%
+ \@MXV@newlabel{@MXV@\@MXV@label.volume}{\@MXV@volume}%
+ \@MXV@newlabel{@MXV@\@MXV@label.autoplay}{%
+ \if@MXV@autoplay true\else false\fi}%
+ \@MXV@newlabel{@MXV@\@MXV@label.3D}{false}%
+ \@MXV@newlabel{@MXV@\@MXV@label.issound}{%
+ \if@MXV@issound true\else false\fi}%
+ %
+ \fi%
+ %
+ \ifthenelse{\boolean{@MXV@autoplay}\OR\boolean{@MXV@runposter}}{%
+ \xdef\@MXV@pageopenopentry{/OP 4}%
+ }{%
+ \if@MXV@autoresume%
+ \xdef\@MXV@pageopenopentry{/OP 3}%
+ \else%
+ \xdef\@MXV@pageopenopentry{/OP 2}%
+ \fi%
+ }%
+ %
+ \if@MXV@autostop%
+ \xdef\@MXV@pagecloseopentry{/OP 1}%
+ \else%
+ \if@MXV@autopause%
+ \xdef\@MXV@pagecloseopentry{/OP 2}%
+ \else%
+ \if@MXV@autoclose%
+ \xdef\@MXV@pagecloseopentry{/OP 1}%
+ \else% @MXV@continue
+ \xdef\@MXV@pagecloseopentry{/OP 3}%
+ \fi%
+ \fi%
+ \fi%
+ %
+ %JavaScripts for playback control
+ %script for page invisible event
+ \if@MXV@autopause%
+ \xdef\@MXV@pageclosejsentry{%
+ /JS (
+ try{%
+ if(player\@MXV@currplayer.isPlaying){%
+ player\@MXV@currplayer.pause();
+ player\@MXV@currplayer.settings.privateData.paused=true;
+ }
+ focusonplayer=-1; %page change
+ player\@MXV@currplayer.visible=false;
+ }
+ catch(e){}
+ )%
+ }%
+ \else%
+ \if@MXV@autostop%
+ \xdef\@MXV@pageclosejsentry{%
+ /JS (
+ try{%
+ player\@MXV@currplayer.settings.privateData.paused=false;
+ %players tend to be bugged, always stop from playing state
+ if(!player\@MXV@currplayer.isPlaying){
+ player\@MXV@currplayer.play();
+ }
+ player\@MXV@currplayer.stop();
+ if(
+ player\@MXV@currplayer.settings.startAt.time
+ || player\@MXV@currplayer.settings.startAt.frame
+ || player\@MXV@currplayer.settings.startAt.marker
+ || player\@MXV@currplayer.id ==
+ 'vnd.adobe.swname:AAPL_QuickTime'
+ ){
+ player\@MXV@currplayer.seek(%
+ player\@MXV@currplayer.settings.startAt);
+ }
+ focusonplayer=-1;
+ player\@MXV@currplayer.visible=false;
+ }
+ catch(e){}
+ )%
+ }%
+ \else%
+ \if@MXV@autoclose%
+ \xdef\@MXV@pageclosejsentry{%
+ /JS (
+ try{%
+ player\@MXV@currplayer.close(app.media.closeReason.general);
+ focusonplayer=-1; %page change
+ player\@MXV@currplayer.visible=false;
+ }
+ catch(e){}
+ )%
+ }%
+ \else%
+ \xdef\@MXV@pageclosejsentry{%@MXV@continue
+ /JS (
+ try{%
+ focusonplayer=-1; %page change
+ player\@MXV@currplayer.visible=false;
+ }
+ catch(e){}
+ )%
+ }%
+ \fi%
+ \fi%
+ \fi%
+ %
+ %script for activation/resume on page open event
+ \xdef\@MXV@pageopenjsentry{%
+ /JS (
+ try{%
+ if(player\@MXV@currplayer.isOpen){%
+ %drag the player on the current slide (presentation mode)
+ player\@MXV@currplayer.page=this.pageNum;
+ %... and make it visible
+ \if@MXV@issound\else player\@MXV@currplayer.visible=true;\fi%
+ %
+ %start or resume media which have autoplay option set;
+ %also resume paused media which have autoresume option set
+ \if@MXV@autoplay%
+ player\@MXV@currplayer.settings.privateData.paused=false;
+ player\@MXV@currplayer.play();
+ if(!player\@MXV@currplayer.isPlaying){% still not playing?!
+ if(
+ player\@MXV@currplayer.settings.startAt.time
+ || player\@MXV@currplayer.settings.startAt.frame
+ || player\@MXV@currplayer.settings.startAt.marker
+ || player\@MXV@currplayer.id=='vnd.adobe.swname:AAPL_QuickTime'
+ ){
+ player\@MXV@currplayer.seek(
+ player\@MXV@currplayer.settings.startAt);
+ }else{
+ player\@MXV@currplayer.stop();
+ }
+ player\@MXV@currplayer.play();
+ }
+ \else%
+ \if@MXV@autoresume%
+ if(player\@MXV@currplayer.settings.privateData.paused){%
+ player\@MXV@currplayer.settings.privateData.paused=false;
+ player\@MXV@currplayer.play();
+ if(!player\@MXV@currplayer.isPlaying){%
+ if(
+ player\@MXV@currplayer.settings.startAt.time
+ || player\@MXV@currplayer.settings.startAt.frame
+ || player\@MXV@currplayer.settings.startAt.marker
+ || player\@MXV@currplayer.id ==
+ 'vnd.adobe.swname:AAPL_QuickTime'
+ ){
+ player\@MXV@currplayer.seek(%
+ player\@MXV@currplayer.settings.startAt);
+ }else{
+ player\@MXV@currplayer.stop();%
+ }
+ player\@MXV@currplayer.play();
+ }
+ }
+ \fi%
+ \fi%
+ }
+ else{%
+ throw 'isClosed';
+ }
+ }
+ catch(e){%
+ \@MXV@if{\if@MXV@autoplay true\else\if@MXV@runposter true\else %
+ false\fi\fi}%
+ if(focusonplayer==undefined){%
+ var focusonplayer=0; %shared by all annots
+ }
+ \@MXV@settings{\@MXV@ctrls}{\@MXV@palindrome}{\@MXV@repeat}%
+ {\@MXV@rate}{\@MXV@startat}{\@MXV@endat}{\@MXV@volume}%
+ \@MXV@events{\@MXV@currplayer}%
+ {\if@MXV@mouse true\else false\fi}%
+ {\if@MXV@autoplay true\else false\fi}%
+ var player\@MXV@currplayer=app.media.openPlayer({%
+ settings: settings,
+ events: events
+ });
+ \fi%
+ }%
+ )
+ }%
+ %
+ %script for normal activation by mouse click
+ \xdef\@MXV@activationjsentry{%
+ /JS (
+ app.focusRect=true;%
+ if(focusonplayer==undefined){%
+ var focusonplayer=0; %shared by all annots
+ }
+ \@MXV@settings{\@MXV@ctrls}{\@MXV@palindrome}{\@MXV@repeat}%
+ {\@MXV@rate}{\@MXV@startat}{\@MXV@endat}{\@MXV@volume}%
+ \@MXV@events{\@MXV@currplayer}{\if@MXV@mouse true\else false\fi}%
+ {true}%
+ var player\@MXV@currplayer=app.media.openPlayer({%
+ settings: settings,
+ events: events
+ });
+ )
+ }%
+ }%
+ }%
+ }% draft?
+ %
+ %insert link target, if media has been labelled
+ \ifthenelse{\NOT\equal{\@MXV@@label}{}}{%
+ \raisebox{\@MXV@height}{%
+ \ifpdf%
+ \pdfdest name {@MXV@\@MXV@@label} xyz %
+ \else%
+ \hypertarget{@MXV@\@MXV@@label}{}%
+ \fi%
+ }%
+ }{}%
+ %
+ \ifthenelse{\boolean{@MXV@@draft}}{%
+ \makebox[0pt][l]{\usebox{\@MXV@textbox}}%
+ \@MXV@draftbox{\@MXV@width}{\@MXV@height}{\@MXV@depth}{#4}%
+ }{%
+ %insert textbox, obscured by poster
+ \ifthenelse{\boolean{@MXV@boxopt}\AND\NOT\boolean{@MXV@textoverposter}}{%
+ \makebox[0pt][l]{\usebox{\@MXV@textbox}}%
+ }{}%
+ %
+ %insert annotation
+ \ifthenelse{\boolean{@MXV@iiid}}{%
+ \edef\@MXV@iiidopt{[\@MXV@iiidopt]}%
+ \expandafter\@MXV@includeiiid\@MXV@iiidopt{\@MXV@width}{\@MXV@height}{\@MXV@depth}{#4}%
+ }{%
+ \@MXV@includemovie{\@MXV@width}{\@MXV@height}{\@MXV@depth}{#4}%
+ }%
+ %
+ %insert textbox, overprinting the poster
+ \ifthenelse{\boolean{@MXV@boxopt}\AND\boolean{@MXV@textoverposter}}{%
+ \makebox[0pt][r]{\usebox{\@MXV@textbox}}%
+ }{}%
+ }%
+ }%
+}
+
+%for remote control of media
+\newcommand\movieref[3][]{%
+ \ifpdf\else%
+ \ifthenelse{\isundefined{\pdfmark}\AND\isundefined{\@pdfm@mark}}{\@MXV@missing{hyperref}}{}%
+ \fi%
+ \leavevmode%
+ % save text argument
+ \savebox{\@MXV@textbox}{\ifHy@colorlinks\color{\@linkcolor}\fi#3}%
+ %
+ %find out whether the contents should be hidden or not (for presentations)
+ \setboolean{@MXV@hide}{false}%
+% \ifthenelse{\boolean{@MXV@powerdot}}{%
+% \ifthenelse{\boolean{pd@overlay}}{}{%
+% \ifthenelse{\pd@method=2}{}{%
+% \setboolean{@MXV@hide}{true}%
+% }%
+% }%
+% }{}%
+ \ifthenelse{\boolean{@MXV@beamer}}{%
+ \ifthenelse{\boolean{beamer@anotherslide}}{%
+ \setboolean{@MXV@hide}{true}%
+ }{}%
+ }{}%
+ %
+ \ifthenelse{\boolean{@MXV@hide}}{%
+ %put whitespace instead of link annot
+ \phantom{\usebox{\@MXV@textbox}}%
+ }{%
+ \@MXV@reset%
+ %
+ \xdef\@MXV@label{#2}%
+ %
+ \global\advance\@MXV@links by 1%increment link counter
+ %
+ %label this link for later page number determination
+ \@MXV@labeltoaux{@MXV@link\the\@MXV@links.page}{\noexpand\the\@MXV@page}%
+ %
+ \ifthenelse{\boolean{@MXV@presentation}}{%
+ %in presentation mode the label must be extended by the physical page No.
+ \xdef\@MXV@@label{\@MXV@label.\@MXV@getlabelvalue{@MXV@link\the\@MXV@links.page}}%
+ }{%
+ \xdef\@MXV@@label{\@MXV@label}%
+ }%
+ %
+ %check if label is defined at all
+ \ifthenelse{\equal{\@MXV@getlabelvalue{@MXV@\@MXV@@label.annotid}}{undefined}}{%
+ \usebox{\@MXV@textbox}% write out text box
+ \PackageWarning{movie15}{%
+ Reference `\@MXV@label' on page \thepage \space undefined%
+ }%
+ \ifthenelse{\isundefined{\@MXV@undefwarning}}{%
+ \gdef\@MXV@undefwarning{}%
+ \AtEndDocument{%
+ \PackageWarningNoLine{movie15}{%
+ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\MessageBreak%
+ @@ There were undefined references! @@\MessageBreak%
+ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@}%
+ }%
+ }{}%
+ }{%
+ \ifthenelse{\equal{\@MXV@getlabelvalue{@MXV@\@MXV@label.draft}}{true}}{%
+ \setboolean{@MXV@@draft}{true}% if the screen annotation is in draft mode
+ }{}%
+ \if@MXV@@draft\else%
+ \ifthenelse{\equal{\@MXV@getlabelvalue{@MXV@\@MXV@label.externalviewer}}{true}}{%
+ \setboolean{@MXV@externalviewer}{true}%
+ }{%
+ \setboolean{@MXV@externalviewer}{false}%
+ }%
+ \if@MXV@externalviewer\else%
+ %movieref used in 3D context?
+ \ifthenelse{\equal{\@MXV@getlabelvalue{@MXV@\@MXV@label.3D}}{true}}{%
+ \ifthenelse{\boolean{@MXV@iiiDfeat}}{%
+ \setboolean{@MXV@iiid}{true}%
+ }{%
+ \@MXV@neediiiD%
+ }%
+ }{}%
+ %
+ %actions completely different in 3D & 2D context
+ \ifthenelse{\boolean{@MXV@iiid}}{% #### 3D ####
+ %retrieve default lighting scheme
+ \ifthenelse{\equal{\@MXV@getlabelvalue{@MXV@\@MXV@label.3Dlights}}{undefined}}{%
+ \edef\@MXV@lights{}%
+ }{%
+ \edef\@MXV@lights{\@MXV@getlabelvalue{@MXV@\@MXV@label.3Dlights}}%
+ }%
+ %retrieve default render mode
+ \ifthenelse{\equal{\@MXV@getlabelvalue{@MXV@\@MXV@label.3Drender}}{undefined}}{%
+ \edef\@MXV@render{}%
+ }{%
+ \edef\@MXV@render{\@MXV@getlabelvalue{@MXV@\@MXV@label.3Drender}}%
+ }%
+ \setkeys{MXV@user}{#1}%
+ \if@MXV@defaultviewprovided% define a new view,
+ %using any of the coo, c2c, roo, caa options
+ \xdef\@MXV@xname{}%
+ \edef\@MXV@args{\@MXV@coo\space\@MXV@ctoc\space\@MXV@roo\space\@MXV@roll\space}%
+ \expandafter\@MXV@ciiwmatrix\@MXV@args% build C2W matrix
+ \@MXV@viewobj% create pdf object of 3D view
+ \edef\@MXV@iiidview{\@MXV@@viewobj}%
+ %else use the indexed view specified by option `3Dviewindex'
+ \fi%
+ %
+ %create JavaScript (options 3Djscript, 3Dcalculate, 3Dgetview)
+ \ifthenelse{\NOT\equal{\@MXV@jscriptiiidfile}{}%
+ \OR\NOT\equal{\@MXV@calc}{}%
+ \OR\boolean{@MXV@iiidgetview}%
+ }{%
+ \edef\@MXV@linkjscriptiiid{%
+ try{%
+ %fill hash (annot3D) with refs to Annot3D objects
+ annot3D['\@MXV@label']=getAnnots3D(%
+ \@MXV@getlabelvalue{%
+ @MXV@annot\@MXV@getlabelvalue{@MXV@\@MXV@@label.annotid}.page%
+ }-1%
+ )[\@MXV@getlabelvalue{@MXV@\@MXV@@label.3Doncurpage}-1];%
+ annot3D['\@MXV@label'].activated=true;%
+ }catch(e){%
+ try{%
+ annot3D=new Array;%
+ annot3D['\@MXV@label']=getAnnots3D(%
+ \@MXV@getlabelvalue{%
+ @MXV@annot\@MXV@getlabelvalue{@MXV@\@MXV@@label.annotid}.page%
+ }-1%
+ )[\@MXV@getlabelvalue{@MXV@\@MXV@@label.3Doncurpage}-1];%
+ annot3D['\@MXV@label'].activated=true;%
+ }catch(e){%
+ var spc=String.fromCharCode(32);%
+ app.alert('3D' + spc + 'annotation' + spc + 'could' + spc +%
+ 'not' + spc + 'be' + spc + 'activated!');%
+ }%
+ }%
+ }%
+ \if@MXV@iiidgetview%
+ \edef\@MXV@linkjscriptiiid{%
+ \@MXV@linkjscriptiiid
+ try{
+ %JavaScript to print the camera settings of the current view
+ var camera=annot3D['\@MXV@label'].context3D.scene.cameras.getByIndex(0);%
+ var coo=camera.targetPosition;%
+ var c2c=camera.position.subtract(coo);%
+ var roo=c2c.length;%
+ c2c.normalize();%
+ %
+ %assemble result string
+ %{<coo_x> <coo_y> <coo_z>}{<c2c_x> <c2c_y> <c2c_z>}{<roo>}{<aac>}
+ var spc=String.fromCharCode(32);%
+ var res='{';%
+ var x = (Math.abs(coo.x) < 1e-18 ? 0 : coo.x);%
+ var y = (Math.abs(coo.y) < 1e-18 ? 0 : coo.y);%
+ var z = (Math.abs(coo.z) < 1e-18 ? 0 : coo.z);%
+ if(Math.sqrt(x*x + y*y + z*z) > 0){%
+ res+=util.printf('\%s' + spc + '\%s' + spc + '\%s',%
+ (Math.abs(x) < 1.001e-6 && Math.abs(x) > 0 ?%
+ util.printf('\%.18f', x): x),%
+ (Math.abs(y) < 1.001e-6 && Math.abs(y) > 0 ?%
+ util.printf('\%.18f', y): y),%
+ (Math.abs(z) < 1.001e-6 && Math.abs(z) > 0 ?%
+ util.printf('\%.18f', z): z)%
+ );%
+ }%
+ res+='}{';%
+ x = (Math.abs(c2c.x) < 1e-18 ? 0 : c2c.x);%
+ y = (Math.abs(c2c.y) < 1e-18 ? 0 : c2c.y);%
+ z = (Math.abs(c2c.z) < 1e-18 ? 0 : c2c.z);%
+ if(!(x==0 && y==-1 && z==0)){%
+ res+=util.printf('\%s' + spc + '\%s' + spc + '\%s',%
+ (Math.abs(x) < 1.001e-6 && Math.abs(x) > 0 ?%
+ util.printf('\%.18f', x): x),%
+ (Math.abs(y) < 1.001e-6 && Math.abs(y) > 0 ?%
+ util.printf('\%.18f', y): y),%
+ (Math.abs(z) < 1.001e-6 && Math.abs(z) > 0 ?%
+ util.printf('\%.18f', z): z)%
+ );%
+ }%
+ res+='}{';%
+ if(roo > 0.11e-17){%
+ res+=util.printf('\%s',%
+ (roo < 1.001e-6 ? util.printf('\%.18f', roo): roo)%
+ );%
+ }%
+ res+='}{';%
+ %determine the camera roll (camera.roll is bugged)
+ %camera up-vector from camera.up, the latter being the positional vector
+ %of the actual camera up-vector tip
+ var up = camera.up.subtract(camera.position);%
+ up.normalize();%
+ %find the camera up-vector up0, that corresponds to zero roll
+ %(Gram-Schmitt orthogonalisation)
+ var worldup=new annot3D['\@MXV@label'].context3D.Vector3();%
+ worldup.set(0,0,1);%
+ var out=c2c.scale(-1);%
+ var up0=worldup.subtract(out.scale(out.dot(worldup)));%
+ up0.normalize();%
+ var up0xup=up0.cross(up);%
+ var roll=0;%
+ if(up0xup.length>0){%
+ up0xup.normalize();%
+ var up0dotup=up.dot(up0);%
+ up0dotup=(Math.abs(up0dotup) > 1 ? Math.round(up0dotup) : up0dotup);%
+ %compute the angle between camera up and up0 vectors
+ roll=Math.acos(up0dotup)*180/Math.PI*out.dot(up0xup);%
+ }%
+ if(util.printf('\%.5f', roll)!=0){%
+ res+=util.printf('\%s', roll);%
+ }%
+ res+='}{';%
+ aac=camera.fov * 180/Math.PI;%
+ if(util.printf('\%.5f', aac)!=30){%
+ res+=util.printf('\%s',%
+ (Math.abs(aac) < 1.001e-6 ? util.printf('\%.18f', aac): aac)%
+ );%
+ }%
+ res+='}';%
+ %open pop-up displaying the result string
+ var settings={%
+ initialize: function(dialog) {%
+ dialog.load({%
+ 'text': res%
+ });%
+ },%
+ description: {%
+ name: 'Current' + spc + '3D' + spc + 'Camera' + spc + 'Settings',%
+ elements: [%
+ {%
+ type: 'static_text',%
+ name: 'Add' + spc + 'the' + spc + 'following' + spc + 'line' + spc +%
+ 'to' + spc + 'a' + spc + 'file' + spc + 'of' + spc +%
+ 'predefined' + spc + 'views.' + spc +%
+ '(See' + spc + 'option' + spc + '3Dviews!)'%
+ },%
+ {%
+ type: 'edit_text',%
+ item_id: 'text',%
+ alignment: 'align_fill',%
+ readonly: false%
+ },%
+ {%
+ type: 'ok',%
+ ok_name: 'Close'%
+ }%
+ ]%
+ }%
+ };%
+ app.execDialog(settings);%
+ }catch(e){%
+ var spc=String.fromCharCode(32);%
+ app.alert('Error' + spc + 'while' + spc + 'executing' + spc +%
+ '3Dgetview:' + spc + e);%
+ }%
+ }%
+ \fi%
+ \ifx\@MXV@calc\@empty\else%
+ \edef\@MXV@linkjscriptiiid{%
+ \@MXV@linkjscriptiiid
+ try{
+% console.show();
+% console.clear();
+ %constructor for doubly linked list
+ function List(){%
+ this.first_node=null;%
+ this.last_node=new Node(undefined);%
+ }%
+ List.prototype.push_back=function(x){%
+ var new_node=new Node(x);%
+ if(this.first_node==null){%
+ this.first_node=new_node;%
+ new_node.prev=null;%
+ }else{%
+ new_node.prev=this.last_node.prev;%
+ new_node.prev.next=new_node;%
+ }%
+ new_node.next=this.last_node;%
+ this.last_node.prev=new_node;%
+ };%
+ List.prototype.move_to_front=function(it){%
+ var node=it.get();%
+ if(node.next!=null && node.prev!=null){%
+ node.next.prev=node.prev;%
+ node.prev.next=node.next;%
+ node.prev=null;%
+ node.next=this.first_node;%
+ this.first_node.prev=node;%
+ this.first_node=node;%
+ }%
+ };%
+ List.prototype.begin=function(){%
+ var i=new Iterator();%
+ i.target=this.first_node;%
+ return(i);%
+ };%
+ List.prototype.end=function(){%
+ var i=new Iterator();%
+ i.target=this.last_node;%
+ return(i);%
+ };%
+ function Iterator(it){%
+ if( it!=undefined ){%
+ this.target=it.target;%
+ }else {%
+ this.target=null;%
+ }%
+ }%
+ Iterator.prototype.set=function(it){this.target=it.target;};%
+ Iterator.prototype.get=function(){return(this.target);};%
+ Iterator.prototype.deref=function(){return(this.target.data);};%
+ Iterator.prototype.incr=function(){%
+ if(this.target.next!=null){this.target=this.target.next;}%
+ };%
+ %constructor for node objects that populate the linked list
+ function Node(x){%
+ this.prev=null;%
+ this.next=null;%
+ this.data=x;%
+ }%
+ function sqr(r){return(r*r);}%helper function
+ %The following code borrows heavily from Bernd Gaertners `Miniball' software,
+ %originally written in C++, for computing the smallest enclosing ball of a
+ %set of points; see: http://www.inf.ethz.ch/personal/gaertner/miniball.html
+ function Basis(){%
+ this.m=0;%
+ this.q0=new Array(3);%
+ this.z=new Array(4);%
+ this.f=new Array(4);%
+ this.v=new Array(new Array(3), new Array(3), new Array(3), new Array(3));%
+ this.a=new Array(new Array(3), new Array(3), new Array(3), new Array(3));%
+ this.c=new Array(new Array(3), new Array(3), new Array(3), new Array(3));%
+ this.sqr_r=new Array(4);%
+ this.current_c=this.c[0];%
+ this.current_sqr_r=0;%
+ this.reset();%
+ }%
+ Basis.prototype.center=function(){return(this.current_c);};%
+ Basis.prototype.size=function(){return(this.m);};%
+ Basis.prototype.pop=function(){--this.m;};%
+ Basis.prototype.excess=function(p){%
+ var e=-this.current_sqr_r;%
+ for(var k=0;k<3;++k){%
+ e+=sqr(p[k]-this.current_c[k]);%
+ }%
+ return(e);%
+ };%
+ Basis.prototype.reset=function(){%
+ this.m=0;%
+ for(var j=0;j<3;++j){%
+ this.c[0][j]=0;%
+ }%
+ this.current_c=this.c[0];%
+ this.current_sqr_r=-1;%
+ };%
+ Basis.prototype.push=function(p){%
+ var i, j;%
+ var eps=1e-32;%
+ if(this.m==0){%
+ for(i=0;i<3;++i){%
+ this.q0[i]=p[i];%
+ }%
+ for(i=0;i<3;++i){%
+ this.c[0][i]=this.q0[i];%
+ }%
+ this.sqr_r[0]=0;%
+ }else {%
+ for(i=0;i<3;++i){%
+ this.v[this.m][i]=p[i]-this.q0[i];%
+ }%
+ for(i=1;i<this.m;++i){%
+ this.a[this.m][i]=0;%
+ for(j=0;j<3;++j){%
+ this.a[this.m][i]+=this.v[i][j]*this.v[this.m][j];%
+ }%
+ this.a[this.m][i]*=(2/this.z[i]);%
+ }%
+ for(i=1;i<this.m;++i){%
+ for(j=0;j<3;++j){%
+ this.v[this.m][j]-=this.a[this.m][i]*this.v[i][j];%
+ }%
+ }%
+ this.z[this.m]=0;%
+ for(j=0;j<3;++j){%
+ this.z[this.m]+=sqr(this.v[this.m][j]);%
+ }%
+ this.z[this.m]*=2;%
+ if(this.z[this.m]<eps*this.current_sqr_r){%
+ return(false);%
+ }%
+ var e=-this.sqr_r[this.m-1];%
+ for(i=0;i<3;++i){%
+ e+=sqr(p[i]-this.c[this.m-1][i]);%
+ }%
+ this.f[this.m]=e/this.z[this.m];%
+ for(i=0;i<3;++i){%
+ this.c[this.m][i]=this.c[this.m-1][i]+this.f[this.m]*this.v[this.m][i];%
+ }%
+ this.sqr_r[this.m]=this.sqr_r[this.m-1]+e*this.f[this.m]/2;%
+ }%
+ this.current_c=this.c[this.m];%
+ this.current_sqr_r=this.sqr_r[this.m];%
+ ++this.m;%
+ return(true);%
+ };%
+ function Miniball(){%
+ this.L=new List();%
+ this.B=new Basis();%
+ this.support_end=new Iterator();%
+ }%
+ Miniball.prototype.mtf_mb=function(it){%
+ var i=new Iterator(it);%
+ this.support_end.set(this.L.begin());%
+ if((this.B.size())==4){return;}%
+ for(var k=new Iterator(this.L.begin());k.get()!=i.get();){%
+ var j=new Iterator(k);%
+ k.incr();%
+ if(this.B.excess(j.deref()) > 0){%
+ if(this.B.push(j.deref())){%
+ this.mtf_mb(j);%
+ this.B.pop();%
+ if(this.support_end.get()==j.get()){%
+ this.support_end.incr();%
+ }%
+ this.L.move_to_front(j);%
+ }%
+ }%
+ }%
+ };%
+ Miniball.prototype.check_in=function(b){%
+ this.L.push_back(b);%
+ };%
+ Miniball.prototype.build=function(){%
+ this.B.reset();%
+ this.support_end.set(this.L.begin());%
+ this.mtf_mb(this.L.end());%
+ };%
+ Miniball.prototype.center=function(){%
+ return(this.B.center());%
+ };%
+ Miniball.prototype.radius=function(){%
+ return(Math.sqrt(this.B.current_sqr_r));%
+ };%
+ %create Miniball object
+ var mb=new Miniball();%
+ %aperture angle of the virtual camera
+ var aac=\@MXV@calc;%
+ %list of mesh nodes
+ var meshes=annot3D['\@MXV@label'].context3D.scene.meshes;%
+ %auxiliary vectors
+ var dir=new annot3D['\@MXV@label'].context3D.Vector3();%
+ var up=new annot3D['\@MXV@label'].context3D.Vector3();%
+ var corner=new annot3D['\@MXV@label'].context3D.Vector3();%
+ %auxiliary 4x4 matrix
+ var bbox4x4=new annot3D['\@MXV@label'].context3D.Matrix4x4();%
+ %iterate over all mesh nodes in the scene
+ for(i=0;i<meshes.count;i++){%
+ var mesh=meshes.getByIndex(i);%
+ %get the bbox of the mesh (local coordinates)
+ var bbox=mesh.computeBoundingBox();%
+ %local to parent transformation matrix
+ var trans=mesh.transform.transpose;%
+ %build local to world transformation matrix by recursively
+ %multiplying the parent's transf. matrix on the left
+ var parent=mesh.parent;%
+ while(parent.transform){%
+ trans=parent.transform.transpose.multiply(trans);%
+ parent=parent.parent;%
+ }%
+ %transform the local bounding box corner coordinates to
+ %world coordinates for bounding sphere determination;
+ %Matrix4x4 method transformDirection(<Vector3>) seems
+ %to be bugged, therefore we must resort to the
+ %multiply(<Matrix4x4>) method using an auxiliary matrix
+ %which contains the local bounding box corner coordinates
+ %
+ %auxiliary matrix from bbox.min coordinates
+ bbox4x4.setView(bbox.min, dir, up);%
+ %transform to world coordinates
+ bbox4x4=trans.multiply(bbox4x4.transpose);%
+ %extract the transformed coordinates
+ corner.set(bbox4x4.transpose.translation);%
+ %check-in corner position into Miniball
+ mb.check_in(new Array(corner.x, corner.y, corner.z));%
+ %the same procedure with bbox.max
+ bbox4x4.setView(bbox.max, dir, up);%
+ bbox4x4=trans.multiply(bbox4x4.transpose);%
+ corner.set(bbox4x4.transpose.translation);%
+ mb.check_in(new Array(corner.x, corner.y, corner.z));%
+ %and with all remaining 6 bbox corners
+ corner.set(bbox.min.x, bbox.max.y, bbox.max.z);%
+ bbox4x4.setView(corner, dir, up);%
+ bbox4x4=trans.multiply(bbox4x4.transpose);%
+ corner.set(bbox4x4.transpose.translation);%
+ mb.check_in(new Array(corner.x, corner.y, corner.z));%
+ corner.set(bbox.min.x, bbox.min.y, bbox.max.z);%
+ bbox4x4.setView(corner, dir, up);%
+ bbox4x4=trans.multiply(bbox4x4.transpose);%
+ corner.set(bbox4x4.transpose.translation);%
+ mb.check_in(new Array(corner.x, corner.y, corner.z));%
+ corner.set(bbox.min.x, bbox.max.y, bbox.min.z);%
+ bbox4x4.setView(corner, dir, up);%
+ bbox4x4=trans.multiply(bbox4x4.transpose);%
+ corner.set(bbox4x4.transpose.translation);%
+ mb.check_in(new Array(corner.x, corner.y, corner.z));%
+ corner.set(bbox.max.x, bbox.min.y, bbox.min.z);%
+ bbox4x4.setView(corner, dir, up);%
+ bbox4x4=trans.multiply(bbox4x4.transpose);%
+ corner.set(bbox4x4.transpose.translation);%
+ mb.check_in(new Array(corner.x, corner.y, corner.z));%
+ corner.set(bbox.max.x, bbox.min.y, bbox.max.z);%
+ bbox4x4.setView(corner, dir, up);%
+ bbox4x4=trans.multiply(bbox4x4.transpose);%
+ corner.set(bbox4x4.transpose.translation);%
+ mb.check_in(new Array(corner.x, corner.y, corner.z));%
+ corner.set(bbox.max.x, bbox.max.y, bbox.min.z);%
+ bbox4x4.setView(corner, dir, up);%
+ bbox4x4=trans.multiply(bbox4x4.transpose);%
+ corner.set(bbox4x4.transpose.translation);%
+ mb.check_in(new Array(corner.x, corner.y, corner.z));%
+ }%
+ %compute the smallest enclosing bounding sphere
+ mb.build();%
+ %bounding sphere centre
+ var coo=new annot3D['\@MXV@label'].context3D.Vector3();%
+ coo.set((mb.center())[0], (mb.center())[1], (mb.center())[2]);%
+ %radius of orbit
+ var roo=mb.radius()/ Math.sin(aac * Math.PI/ 360.);%
+ %result string
+ var res='';%
+ var spc=String.fromCharCode(32);%
+ if(aac!=30){%
+ res+=util.printf('3Daac=\%s,' + spc,%
+ (Math.abs(aac) < 1.001e-6 && Math.abs(aac) > 0 ?%
+ util.printf('\%.18f', aac): aac)%
+ );%
+ }%
+ if(coo.length){%
+ res+=util.printf( '3Dcoo=\%s' + spc + '\%s' + spc + '\%s,'%
+ + spc,%
+ (Math.abs(coo.x) < 1.001e-6 && Math.abs(coo.x) > 0 ?%
+ util.printf('\%.18f', coo.x): coo.x),%
+ (Math.abs(coo.y) < 1.001e-6 && Math.abs(coo.y) > 0 ?%
+ util.printf('\%.18f', coo.y): coo.y),%
+ (Math.abs(coo.z) < 1.001e-6 && Math.abs(coo.z) > 0 ?%
+ util.printf('\%.18f', coo.z): coo.z)%
+ );%
+ }%
+ res+=util.printf(%
+ '3Droo=\%s,' + spc, (roo < 1.001e-6 ? util.printf('\%.18f', roo): roo)
+ );%
+ var settings={%
+ initialize: function(dialog){%
+ dialog.load({%
+ 'text': res%
+ });%
+ },%
+ description: {%
+ name: '3D' + spc + 'Camera' + spc + 'Settings',%
+ elements: [%
+ {%
+ type: 'static_text',%
+ name: 'Copy' + spc + 'and' + spc + 'paste' + spc +%
+ 'the' + spc + 'following' + spc + 'to' + spc +%
+ 'the' + spc + 'option' + spc + 'list' + spc +%
+ 'of' + spc + spc + '\string\\\string\\includemovie!'%
+ },%
+ {%
+ type: 'edit_text',%
+ item_id: 'text',%
+ alignment: 'align_fill',%
+ readonly: false%
+ },%
+ {%
+ type: 'ok',%
+ ok_name: 'Close'%
+ }%
+ ]%
+ }%
+ };%
+ app.execDialog(settings);%
+ }catch(e){%
+ var spc=String.fromCharCode(32);%
+ app.alert('Error' + spc + 'while' + spc + 'executing' + spc +%
+ '3Dcalculate:' + spc + e);%
+ }%
+ }%
+ \fi%
+ %create stream from user provided JavaScript file
+ \ifx\@MXV@jscriptiiidfile\@empty\else%
+ \ifthenelse{% create only once
+ \equal{\@MXV@getlabelvalue{\pdfmdfivesum file {\@MXV@jscriptiiidfile}}}{undefined}%
+ }{%
+ \ifpdf%
+ \pdfobj stream file {\@MXV@jscriptiiidfile}%
+ \pdfrefobj\pdflastobj%
+ \edef\@MXV@userjscriptiiidstream{\the\pdflastobj\space 0 R}%
+ \@MXV@newlabel{\pdfmdfivesum file {\@MXV@jscriptiiidfile}}{\the\pdflastobj}%
+ \else\if@MXV@dvipdfmx
+ \special{pdf:fstream @linkuserjscriptiiid\the\@MXV@links\space(\@MXV@jscriptiiidfile)}%
+ \edef\@MXV@userjscriptiiidstream{@linkuserjscriptiid\the\@MXV@links}%
+ \@MXV@newlabel{\pdfmdfivesum file {\@MXV@jscriptiiidfile}}{@linkuserjscriptiid\the\@MXV@links}%
+ \else%
+ \pdfmark{%
+ pdfmark=/OBJ,%
+ Raw={%
+ /_objdef {linkuserjscriptiiid\the\@MXV@links}%
+ /type/stream%
+ }%
+ }%
+ \pdfmark{%
+ pdfmark=/PUT,%
+ Raw={%
+ {linkuserjscriptiiid\the\@MXV@links}%
+ (\@MXV@jscriptiiidfile) (r) file%
+ }%
+ }%
+ \edef\@MXV@userjscriptiiidstream{%
+ {linkuserjscriptiiid\the\@MXV@links}%
+ }%
+ \@MXV@newlabel{\pdfmdfivesum file {\@MXV@jscriptiiidfile}}%
+ {linkuserjscriptiiid\the\@MXV@links}%
+ \fi\fi%
+ }{%
+ \ifpdf%
+ \edef\@MXV@userjscriptiiidstream{%
+ \@MXV@getlabelvalue{\pdfmdfivesum file {\@MXV@jscriptiiidfile}}\space 0 R%
+ }%
+ \else%
+ \edef\@MXV@userjscriptiiidstream{%
+ {\@MXV@getlabelvalue{\pdfmdfivesum file {\@MXV@jscriptiiidfile}}}%
+ }%
+ \fi%
+ }%
+ \fi%
+ \edef\@MXV@jscriptiiidaction{%
+ /Next <<%
+ /S/JavaScript%
+ /JS (\@MXV@linkjscriptiiid)%
+ \ifx\@MXV@jscriptiiidfile\@empty\else%
+ /Next <<%
+ /S/JavaScript%
+ /JS \@MXV@userjscriptiiidstream% user provided script
+ >>%
+ \fi%
+ >>%
+ }%
+ }{\edef\@MXV@jscriptiiidaction{}}%
+ }{% #### 2D ####
+ \setkeys{MXV@user}{#1}%
+ %retrieve original settings
+ \ifthenelse{\equal{\@MXV@getlabelvalue{@MXV@\@MXV@label.mouse}}{true}}{%
+ \setboolean{@MXV@mouse}{true}%
+ }{%
+ \setboolean{@MXV@mouse}{false}%
+ }%
+ \edef\@MXV@ctrls{\@MXV@getlabelvalue{@MXV@\@MXV@label.showUI}}%
+ \edef\@MXV@palindrome{\@MXV@getlabelvalue{@MXV@\@MXV@label.palindrome}}%
+ \edef\@MXV@repeat{\@MXV@getlabelvalue{@MXV@\@MXV@label.repeat}}%
+ \edef\@MXV@rate{\@MXV@getlabelvalue{@MXV@\@MXV@label.rate}}%
+ \edef\@MXV@startat{\@MXV@getlabelvalue{@MXV@\@MXV@label.startAt}}%
+ \edef\@MXV@endat{\@MXV@getlabelvalue{@MXV@\@MXV@label.endAt}}%
+ \edef\@MXV@volume{\@MXV@getlabelvalue{@MXV@\@MXV@label.volume}}%
+ \if@MXV@linkreset\else%
+ \setkeys{MXV@user}{#1}%override with new settings
+ \fi%
+ %
+ \edef\@MXV@operation{}%
+ %
+ %get the player ID
+ \edef\@MXV@currplayer{\@MXV@getlabelvalue{@MXV@\@MXV@label.playerid}}%
+ %
+ %see whether a sound inclusion is being referenced
+ \ifthenelse{\equal{\@MXV@getlabelvalue{@MXV@\@MXV@label.issound}}{true}}{%
+ \setboolean{@MXV@issound}{true}%
+ }{%
+ \setboolean{@MXV@issound}{false}%
+ }%
+ %
+ %create /OP and /JS entries
+ \if@MXV@linkplay%
+ \edef\@MXV@operation{%
+ /OP 0%
+ /JS (%
+ if(focusonplayer==undefined){%
+ var focusonplayer=0; %shared by all annots
+ }%
+ \@MXV@settings{\@MXV@ctrls}{\@MXV@palindrome}{\@MXV@repeat}%
+ {\@MXV@rate}{\@MXV@startat}{\@MXV@endat}{\@MXV@volume}%
+ \@MXV@events{\@MXV@currplayer}%
+ {\if@MXV@mouse true\else false\fi}%
+ {true}%
+ \if@MXV@requirereopen\else
+ try{%
+ \ifx\@MXV@@startat\@empty
+ player\@MXV@currplayer.seek(%
+ player\@MXV@currplayer.settings.startAt%
+ );
+ \else
+ player\@MXV@currplayer.seek(\@MXV@@startat);
+ \fi
+ player\@MXV@currplayer.play();
+ \ifx\@MXV@@startat\@empty
+ player\@MXV@currplayer.seek(%
+ player\@MXV@currplayer.settings.startAt%
+ );
+ \else
+ player\@MXV@currplayer.seek(\@MXV@@startat);
+ \fi
+ }%
+ catch(e)\@charlb%
+ \fi%
+ try{%
+ if(player\@MXV@currplayer.isOpen){%
+ player\@MXV@currplayer.close(%
+ app.media.closeReason.general);
+ player\@MXV@currplayer=null;
+ }%
+ }%
+ catch(e){}%
+ %
+ try{%
+ var player\@MXV@currplayer=app.media.openPlayer({%
+ settings: settings,%
+ events: events%
+ });%
+ }%
+ catch (e){}%
+ \if@MXV@requirereopen\else
+ \@charrb%
+ \fi%
+ )%
+ }%
+ \fi%
+ \if@MXV@linkresume% resume/pause
+ \edef\@MXV@operation{%
+ /OP 3%
+ /JS (%
+ try{%
+ \if@MXV@issound\else player\@MXV@currplayer.visible=true;\fi%
+ if(!player\@MXV@currplayer.isPlaying){%
+ player\@MXV@currplayer.settings.privateData.paused=false;
+ player\@MXV@currplayer.play();
+ if(!player\@MXV@currplayer.isPlaying){%
+ %media at end will restart from beginning
+ if(
+ player\@MXV@currplayer.settings.startAt.time
+ || player\@MXV@currplayer.settings.startAt.frame
+ || player\@MXV@currplayer.settings.startAt.marker
+ || player\@MXV@currplayer.id ==
+ 'vnd.adobe.swname:AAPL_QuickTime'
+ ){
+ player\@MXV@currplayer.seek(
+ player\@MXV@currplayer.settings.startAt);
+ }else{
+ player\@MXV@currplayer.stop();
+ }
+ player\@MXV@currplayer.play();
+ }%
+ }%
+ else{%
+ player\@MXV@currplayer.pause();
+ player\@MXV@currplayer.settings.privateData.paused=true;
+ }%
+ }%
+ catch(e){% open new player if not yet open
+ if(focusonplayer==undefined){%
+ var focusonplayer=0; %shared by all annots
+ }%
+ \@MXV@settings{\@MXV@ctrls}{\@MXV@palindrome}{\@MXV@repeat}%
+ {\@MXV@rate}{\@MXV@startat}{\@MXV@endat}{\@MXV@volume}%
+ \@MXV@events{\@MXV@currplayer}%
+ {\if@MXV@mouse true\else false\fi}%
+ {true}%
+ try{%
+ var player\@MXV@currplayer=app.media.openPlayer({%
+ settings: settings,%
+ events: events%
+ });
+ }%
+ catch (e){}%
+ }%
+ )%
+ }%
+ \fi%
+ \if@MXV@linkstop%
+ \edef\@MXV@operation{%
+ /OP 1%
+ /JS (%
+ try{%
+ if(!player\@MXV@currplayer.isPlaying){%
+ player\@MXV@currplayer.settings.privateData.paused=false;
+ player\@MXV@currplayer.play();
+ }%
+ player\@MXV@currplayer.stop();
+ if(
+ player\@MXV@currplayer.settings.startAt.time
+ || player\@MXV@currplayer.settings.startAt.frame
+ || player\@MXV@currplayer.settings.startAt.marker
+ || player\@MXV@currplayer.id ==
+ 'vnd.adobe.swname:AAPL_QuickTime'
+ ){
+ player\@MXV@currplayer.seek(%
+ player\@MXV@currplayer.settings.startAt);
+ }
+ }%
+ catch(e){}%
+ )%
+ }%
+ \fi%
+ \if@MXV@linkpause% pause/resume
+ \edef\@MXV@operation{%
+ /OP 2%
+ /JS (%
+ try{%
+ \if@MXV@issound\else player\@MXV@currplayer.visible=true;\fi%
+ if(!player\@MXV@currplayer.isPlaying){%
+ player\@MXV@currplayer.settings.privateData.paused=false;
+ player\@MXV@currplayer.play();
+ if(!player\@MXV@currplayer.isPlaying){%
+ %media at end will restart from beginning
+ if(
+ player\@MXV@currplayer.settings.startAt.time
+ || player\@MXV@currplayer.settings.startAt.frame
+ || player\@MXV@currplayer.settings.startAt.marker
+ || player\@MXV@currplayer.id ==
+ 'vnd.adobe.swname:AAPL_QuickTime'
+ ){
+ player\@MXV@currplayer.seek(
+ player\@MXV@currplayer.settings.startAt);
+ }else{
+ player\@MXV@currplayer.stop();
+ }
+ player\@MXV@currplayer.play();
+ }%
+ }%
+ else{%
+ player\@MXV@currplayer.pause();
+ player\@MXV@currplayer.settings.privateData.paused=true;
+ }%
+ }%
+ catch(e){% open new player if not yet open
+ if(focusonplayer==undefined){%
+ var focusonplayer=0; %shared by all annots
+ }%
+ \@MXV@settings{\@MXV@ctrls}{\@MXV@palindrome}{\@MXV@repeat}%
+ {\@MXV@rate}{\@MXV@startat}{\@MXV@endat}{\@MXV@volume}%
+ \@MXV@events{\@MXV@currplayer}%
+ {\if@MXV@mouse true\else false\fi}%
+ {true}%
+ try{%
+ var player\@MXV@currplayer=app.media.openPlayer({%
+ settings: settings,%
+ events: events%
+ });
+ }%
+ catch (e){}%
+ }%
+ )%
+ }%
+ \fi%
+ \if@MXV@linkclose%
+ \edef\@MXV@operation{%
+ /OP 1%
+ /JS (%
+ try{%
+ player\@MXV@currplayer.close(%
+ app.media.closeReason.general);
+ player\@MXV@currplayer=null;
+ }%
+ catch(e){}%
+ )%
+ }%
+ \fi%
+ }%
+ \fi%
+ \fi%
+ %
+ \ifpdf%
+ \ifthenelse{\isundefined{\@pdfborder}}{%
+ \def\@MXV@linkattr{}%
+ }{%
+ \edef\@MXV@linkattr{%
+ \if@MXV@beamer%
+ \@MXV@pdfborder%
+ \else%
+ /Border [\@pdfborder]%
+ \fi%
+ /C [\@linkbordercolor]%
+ /H \@pdfhighlight%
+ }%
+ }%
+ %
+ \pdfstartlink%
+ attr{\@MXV@linkattr}%
+ user{%
+ /Subtype /Link%
+ /A <<%
+ /S/GoTo%
+ /D (@MXV@\@MXV@@label)%
+ \if@MXV@@draft\else%
+ \if@MXV@externalviewer\else%
+ \if@MXV@iiid%
+ \ifx\@MXV@iiidview\@empty\else%
+ /Next <<%
+ /S/GoTo3DView%
+ /TA \@MXV@getlabelvalue{@MXV@\@MXV@@label.annot}\space 0 R%
+ /V \@MXV@iiidview%
+ \fi%
+ \@MXV@jscriptiiidaction%
+ \ifx\@MXV@iiidview\@empty\else%
+ >>%
+ \fi%
+ \else%
+ /Next <<%
+ /S/Rendition%
+ /R \@MXV@getlabelvalue{@MXV@\@MXV@@label.rendition}\space 0 R%
+ /AN \@MXV@getlabelvalue{@MXV@\@MXV@@label.annot}\space 0 R%
+ \@MXV@operation%
+ >>%
+ \fi%
+ \fi%
+ \fi%
+ >>%
+ }%
+ \usebox{\@MXV@textbox}% write out text box
+ \pdfendlink%
+ \else\if@MXV@dvipdfmx
+ \ifthenelse{\isundefined{\@pdfborder}}{%
+ \def\@MXV@linkattr{}%
+ }{%
+ \edef\@MXV@linkattr{%
+ \if@MXV@beamer%
+ \@MXV@pdfborder%
+ \else%
+ /Border [\@pdfborder]%
+ \fi%
+ /C [\@linkbordercolor]%
+ /H \@pdfhighlight%
+ }%
+ }%
+ %
+ \special{pdf:bannot <<%
+ \@MXV@linkattr%
+ /Subtype /Link%
+ /A <<%
+ /S/GoTo%
+ /D (@MXV@\@MXV@@label)%
+ \if@MXV@@draft\else%
+ \if@MXV@externalviewer\else%
+ \if@MXV@iiid%
+ \ifx\@MXV@iiidview\@empty\else%
+ /Next <<%
+ /S/GoTo3DView%
+ /TA \@MXV@getlabelvalue{@MXV@\@MXV@@label.annot}%
+ /V \@MXV@iiidview%
+ \fi%
+ \@MXV@jscriptiiidaction%
+ \ifx\@MXV@iiidview\@empty\else%
+ >>%
+ \fi%
+ \else%
+ /Next <<%
+ /S/Rendition%
+ /R \@MXV@getlabelvalue{@MXV@\@MXV@@label.rendition}%
+ /AN \@MXV@getlabelvalue{@MXV@\@MXV@@label.annot}%
+ \@MXV@operation%
+ >>%
+ \fi%
+ \fi%
+ \fi%
+ >>%
+ >>}%
+ \usebox{\@MXV@textbox}% write out text box
+ \special{pdf:eannot}%
+ \else%
+ \pdfmark[{\usebox{\@MXV@textbox}}]{%
+ pdfmark=/ANN,%
+ Subtype=/Link,%
+ Color=\@linkbordercolor,%
+ AcroHighlight=\@pdfhighlight,%
+ Raw={%
+ \@MXV@pdfborder%
+ /_objdef {linkannot\the\@MXV@links}%
+ /Action <<%
+ /S/GoTo%
+ /D/@MXV@\@MXV@@label%
+ \if@MXV@@draft\else%
+ \if@MXV@externalviewer\else%
+ \if@MXV@iiid%
+ \ifx\@MXV@iiidview\@empty\else%
+ /Next <<%
+ /S/GoTo3DView%
+ /TA \@MXV@getlabelvalue{@MXV@\@MXV@@label.annot}%
+ /V \@MXV@iiidview%
+ \fi%
+ \@MXV@jscriptiiidaction%
+ \ifx\@MXV@iiidview\@empty\else%
+ >>%
+ \fi%
+ \else%
+ /Next <<%
+ /S /Rendition%
+ /R {mediarendition\@MXV@getlabelvalue{@MXV@\@MXV@@label.annotid}}%
+ /AN {screenannot\@MXV@getlabelvalue{@MXV@\@MXV@@label.annot}}%
+ \@MXV@operation%
+ >>%
+ \fi%
+ \fi%
+ \fi%
+ >>%
+ }%
+ }%
+ \fi\fi%
+ }%
+ }%
+}
+
+%set to true for certain \movieref options, which require the media player to
+%be re-opened
+\newboolean{@MXV@requirereopen}
+
+%standard keys to be processed first
+%key definitions for options to \includemovie
+\define@key{MXV@user}{draft}[true]{%
+ \setboolean{@MXV@@draft}{#1}%
+}
+\define@key{MXV@user}{final}[true]{%
+ \ifthenelse{\equal{#1}{true}}{%
+ \setboolean{@MXV@@draft}{false}%
+ }{%
+ \setboolean{@MXV@@draft}{true}%
+ }%
+}
+\define@key{MXV@user}{label}{%for use with movieref
+ \gdef\@MXV@label{#1}%
+}
+\define@key{MXV@user}{controls}[true]{%
+ \setboolean{@MXV@requirereopen}{true}%
+ \xdef\@MXV@ctrls{, showUI: #1}%
+ \xdef\@MXV@@ctrls{/C #1}%
+ \ifthenelse{\boolean{@MXV@iiiDfeat}}{%
+ \gdef\@MXV@iiidtoolb{/TB #1}%
+ }{}%
+}
+\define@key{MXV@user}{toolbar}[true]{%
+ \xdef\@MXV@ctrls{, showUI: #1}%
+ \xdef\@MXV@@ctrls{/C #1}%
+ \ifthenelse{\boolean{@MXV@iiiDfeat}}{%
+ \gdef\@MXV@iiidtoolb{/TB #1}%
+ }{}%
+}
+\define@key{MXV@user}{volume}{%
+ \def\@MXV@@volume{/V #1}%
+ \def\@MXV@volume{#1}%
+ \setboolean{@MXV@requirereopen}{true}%
+}
+\define@key{MXV@user}{mimetype}{%
+ \ifthenelse{\equal{#1}{model/u3d}}{%
+ \ifthenelse{\boolean{@MXV@iiiDfeat}}{%
+ \setboolean{@MXV@iiid}{true}%
+ \xdef\@MXV@iiidsubtype{U3D}%
+ }{\@MXV@neediiiD}%
+ }{}%
+ \def\@MXV@mime{#1}%
+}
+\define@key{MXV@user}{playerid}{%
+ \def\@MXV@player{%
+ /PL<</MU [<</PID<</U (vnd.adobe.swname:#1)>>>>]>>%
+ }%
+}
+\define@key{MXV@user}{autoplay}[true]{%
+ \setboolean{@MXV@autoplay}{#1}%
+ \if@MXV@autoplay%
+ \setboolean{@MXV@autoresume}{false}%
+ \fi%
+}
+\define@key{MXV@user}{autostop}[true]{%
+ \setboolean{@MXV@autostop}{#1}%
+ \if@MXV@autostop%
+ \setboolean{@MXV@autopause}{false}%
+ \fi%
+}
+\define@key{MXV@user}{autoresume}[true]{%
+ \setboolean{@MXV@autoresume}{#1}%
+ \if@MXV@autoresume%
+ \setboolean{@MXV@autoplay}{false}%
+ \setboolean{@MXV@autoclose}{false}%
+ \fi%
+}
+\define@key{MXV@user}{autopause}[true]{%
+ \setboolean{@MXV@autopause}{#1}%
+ \if@MXV@autopause%
+ \setboolean{@MXV@autostop}{false}%
+ \setboolean{@MXV@autoclose}{false}%
+ \fi%
+}
+\define@key{MXV@user}{autoclose}[true]{%
+ \setboolean{@MXV@autoclose}{#1}%
+ \if@MXV@autoclose%
+ \setboolean{@MXV@autostop}{false}%
+ \setboolean{@MXV@autopause}{false}%
+ \fi%
+}
+\define@key{MXV@user}{continue}[true]{%
+ \setboolean{@MXV@autostop}{false}%
+ \setboolean{@MXV@autopause}{false}%
+ \setboolean{@MXV@autoclose}{false}%
+}
+\define@key{MXV@user}{open}[true]{%
+ %no longer supported; once open, media remains loaded
+ %to avoid reloading when media is to be played again
+}
+\define@key{MXV@user}{mouse}[true]{%
+ \setboolean{@MXV@mouse}{#1}%
+ \setboolean{@MXV@requirereopen}{true}%
+ \ifthenelse{\equal{false}{#1}\AND\boolean{@MXV@iiiDfeat}}{%
+ \def\@MXV@iiidia{/3DI #1}%
+ }{}%
+}
+\define@key{MXV@user}{palindrome}[true]{%
+ \xdef\@MXV@palindrome{, palindrome: #1}%
+ \setboolean{@MXV@requirereopen}{true}%
+ \ifthenelse{\boolean{@MXV@iiiDfeat}}{%
+ \gdef\@MXV@iiidpalindrome{/Subtype/Oscillating}%
+ }{}%
+}
+\define@key{MXV@user}{rate}{%
+ \setboolean{@MXV@requirereopen}{true}%
+ \xdef\@MXV@rate{, rate: #1}%
+ \ifthenelse{\boolean{@MXV@iiiDfeat}}{%
+ \gdef\@MXV@iiidrate{/TM #1}%
+ }{}%
+}
+\define@key{MXV@user}{repeat}[Infinity]{%
+ \setboolean{@MXV@requirereopen}{true}%
+ \ifthenelse{%
+ \equal{#1}{Infinity}\OR%
+ \equal{#1}{0}%
+ }{%
+ \xdef\@MXV@repeat{, repeat: Infinity}%
+ \xdef\@MXV@@repeat{/RC 0}%
+ }{%
+ \xdef\@MXV@repeat{, repeat: #1}%
+ \xdef\@MXV@@repeat{/RC #1}%
+ }%
+ \ifthenelse{\boolean{@MXV@iiiDfeat}}{%
+ \ifthenelse{\equal{#1}{Infinity}}{%
+ \global\@MXV@iiidrepeat=-1%
+ }{%
+ \global\@MXV@iiidrepeat=#1%
+ }%
+ }{}%
+}
+\define@key{MXV@user}{startat}{%
+ \xdef\@MXV@startat{, startAt: {#1}}%
+ \xdef\@MXV@@startat{{#1}}%
+}
+\define@key{MXV@user}{endat}{%
+ \setboolean{@MXV@requirereopen}{true}%
+ \xdef\@MXV@endat{, endAt: {#1}}%
+}
+\define@key{MXV@user}{poster}[true]{%
+ \ifthenelse{\equal{#1}{true}}{% option without arg
+ \setboolean{@MXV@runposter}{true}%
+ }{%
+ \def\@MXV@box##1##2##3{%
+ \ifpdf%
+ \mbox{\pdfximage width ##1 height ##2 depth ##3 {#1}}%
+ \pdfrefximage\pdflastximage%
+ \else%
+ \ifthenelse{\isundefined{\includegraphics}}{\@MXV@missing{graphics}}{}%
+ \@MXV@totalheight=##2%
+ \advance\@MXV@totalheight by ##3%
+ \raisebox{-##3}[##2][##3]{%
+ \includegraphics[%
+ width=##1,height=##2,totalheight=\@MXV@totalheight,clip]{#1}%
+ }%
+ \fi%
+ }%
+ }%
+}
+\define@key{MXV@user}{externalviewer}[true]{%
+ \setboolean{@MXV@externalviewer}{#1}%
+}
+\define@key{MXV@user}{inline}[true]{%
+ \if@MXV@url%
+ \setboolean{@MXV@inline}{false}%
+ \else%
+ \setboolean{@MXV@inline}{#1}%
+ \fi%
+ \if@MXV@inline\else%
+ \setboolean{@MXV@attachment}{false}%
+ \fi%
+}
+\define@key{MXV@user}{url}[true]{%
+ \setboolean{@MXV@url}{#1}%
+ \if@MXV@url%
+ \setboolean{@MXV@inline}{false}%
+ \setboolean{@MXV@attachment}{false}%
+ \def\@MXV@fsentry{/FS /URL}%
+ \fi%
+}
+\define@key{MXV@user}{attach}[true]{%
+ \setboolean{@MXV@attachment}{#1}%
+ \if@MXV@attachment%
+ \setboolean{@MXV@inline}{true}%
+ \fi%
+}
+\define@key{MXV@user}{text}{%
+ \setboolean{@MXV@boxopt}{true}%
+ \savebox{\@MXV@textbox}{#1}%
+ \@MXV@width=\wd\@MXV@textbox%
+ \@MXV@height=\ht\@MXV@textbox%
+ \@MXV@depth=\dp\@MXV@textbox%
+}
+\define@key{MXV@user}{textoverposter}[true]{%
+ \setboolean{@MXV@textoverposter}{#1}%
+}
+\define@key{MXV@user}{depth}{%set depth of display area
+ \gdef\@MXV@boxdepth{#1}%
+}
+%3D specific options
+\define@key{MXV@user}{3Dbg}{%
+ \ifthenelse{\boolean{@MXV@iiiDfeat}}{%
+ \def\@MXV@background{/BG<</CS/DeviceRGB/C[#1]>>}%
+ }{\@MXV@neediiiD}%
+}
+\define@key{MXV@user}{3Djscript}{%
+ \ifthenelse{\boolean{@MXV@iiiDfeat}}{%
+ \IfFileExists{#1}{%
+ \def\@MXV@jscriptiiidfile{#1}%
+ }{%
+ \PackageError{movie15}{Script file `#1' cannot be opened for embedding%
+ }{%
+ Make sure file `#1' exists and is readable!%
+ }%
+ }%
+ }{\@MXV@neediiiD}%
+}
+\define@key{MXV@user}{3Dcoo}{%
+ \ifthenelse{\boolean{@MXV@iiiDfeat}}{%
+ \def\@MXV@coo{#1}%
+ \setboolean{@MXV@defaultviewprovided}{true}%
+ }{\@MXV@neediiiD}%
+}
+\define@key{MXV@user}{3Dc2c}{%
+ \ifthenelse{\boolean{@MXV@iiiDfeat}}{%
+ \def\@MXV@ctoc{#1}%
+ \setboolean{@MXV@defaultviewprovided}{true}%
+ }{\@MXV@neediiiD}%
+}
+\define@key{MXV@user}{3Droo}{%
+ \ifthenelse{\boolean{@MXV@iiiDfeat}}{%
+ \def\@MXV@roo{#1}%
+ \setboolean{@MXV@defaultviewprovided}{true}%
+ }{\@MXV@neediiiD}%
+}
+\define@key{MXV@user}{3Daac}{%
+ \ifthenelse{\boolean{@MXV@iiiDfeat}}{%
+ \def\@MXV@aac{#1}%
+ \setboolean{@MXV@defaultviewprovided}{true}%
+ }{\@MXV@neediiiD}%
+}
+\define@key{MXV@user}{3Droll}{%
+ \ifthenelse{\boolean{@MXV@iiiDfeat}}{%
+ \def\@MXV@roll{#1}%
+ \setboolean{@MXV@defaultviewprovided}{true}%
+ }{\@MXV@neediiiD}%
+}
+\define@key{MXV@user}{3Dviews}{%
+ \ifthenelse{\boolean{@MXV@iiiDfeat}}{%
+ \IfFileExists{#1}{%
+ \def\@MXV@viewsfile{#1}%
+ }{%
+ \PackageError{movie15}{3D views file `#1' cannot be opened%
+ }{%
+ Make sure file `#1' exists and is readable!%
+ }%
+ }%
+ }{\@MXV@neediiiD}%
+}
+\define@key{MXV@user}{3Dlights}{%
+ \ifthenelse{\boolean{@MXV@iiiDfeat}}{%
+ \gdef\@MXV@lights{/LS <</Subtype/#1>>}%
+ }{\@MXV@neediiiD}%
+}
+\define@key{MXV@user}{3Drender}{%
+ \ifthenelse{\boolean{@MXV@iiiDfeat}}{%
+ \gdef\@MXV@render{/RM <</Subtype/#1>>}%
+ }{\@MXV@neediiiD}%
+}
+%options for \movieref command
+\define@key{MXV@user}{play}[true]{%
+ \setboolean{@MXV@linkplay}{#1}%
+ \if@MXV@linkplay%
+ \setboolean{@MXV@linkpause}{false}%
+ \setboolean{@MXV@linkresume}{false}%
+ \setboolean{@MXV@linkstop}{false}%
+ \setboolean{@MXV@linkclose}{false}%
+ \fi%
+}
+\define@key{MXV@user}{pause}[true]{%
+ \setboolean{@MXV@linkpause}{#1}%
+ \if@MXV@linkpause%
+ \setboolean{@MXV@linkresume}{false}%
+ \setboolean{@MXV@linkstop}{false}%
+ \setboolean{@MXV@linkclose}{false}%
+ \setboolean{@MXV@linkplay}{false}%
+ \fi%
+}
+\define@key{MXV@user}{resume}[true]{%
+ \setboolean{@MXV@linkresume}{#1}%
+ \if@MXV@linkresume%
+ \setboolean{@MXV@linkpause}{false}%
+ \setboolean{@MXV@linkstop}{false}%
+ \setboolean{@MXV@linkclose}{false}%
+ \setboolean{@MXV@linkplay}{false}%
+ \fi%
+}
+\define@key{MXV@user}{stop}[true]{%
+ \setboolean{@MXV@linkstop}{#1}%
+ \if@MXV@linkstop%
+ \setboolean{@MXV@linkpause}{false}%
+ \setboolean{@MXV@linkresume}{false}%
+ \setboolean{@MXV@linkclose}{false}%
+ \setboolean{@MXV@linkplay}{false}%
+ \fi%
+}
+\define@key{MXV@user}{close}[true]{%
+ \setboolean{@MXV@linkclose}{#1}%
+ \if@MXV@linkclose%
+ \setboolean{@MXV@linkpause}{false}%
+ \setboolean{@MXV@linkresume}{false}%
+ \setboolean{@MXV@linkstop}{false}%
+ \setboolean{@MXV@linkplay}{false}%
+ \fi%
+}
+\define@key{MXV@user}{reset}[true]{%
+ \setboolean{@MXV@linkreset}{#1}%
+ \if@MXV@linkreset%
+ \setboolean{@MXV@requirereopen}{true}%
+ \fi%
+}
+\define@key{MXV@user}{default}[true]{% synonyme for `reset'
+ \setboolean{@MXV@linkreset}{#1}%
+ \if@MXV@linkreset%
+ \setboolean{@MXV@requirereopen}{true}%
+ \fi%
+}
+\define@key{MXV@user}{3Dviewindex}{%
+ \ifthenelse{\boolean{@MXV@iiiDfeat}}{%
+ \ifthenelse{%
+ \equal{#1}{F}%
+ \OR\equal{#1}{L}%
+ \OR\equal{#1}{N}%
+ \OR\equal{#1}{P}%
+ \OR\equal{#1}{D}%
+ }{%
+ \gdef\@MXV@iiidview{/#1}% any of F, L, N, P, D
+ }{%
+ \gdef\@MXV@iiidview{#1}% number (index)
+ }%
+ \setboolean{@MXV@defaultviewprovided}{false}%
+ }{\@MXV@neediiiD}%
+}
+\define@key{MXV@user}{3Dcalculate}[30]{%
+ %calculate optimal 3D settings for roo and coo for a given aac
+ \ifthenelse{\boolean{@MXV@iiiDfeat}}{%
+ \gdef\@MXV@calc{#1}%
+ }{\@MXV@neediiiD}%
+}
+\define@key{MXV@user}{3Dgetview}[true]{%
+ %print current 3D camera settings
+ \ifthenelse{\boolean{@MXV@iiiDfeat}}{%
+ \setboolean{@MXV@iiidgetview}{#1}%
+ }{\@MXV@neediiiD}%
+}
+\define@key{MXV@user}{3Dresource}{%
+ \ifthenelse{\boolean{@MXV@iiiDfeat}}{%
+ \IfFileExists{#1}{%
+ \setboolean{@MXV@resource}{true}%
+ \xdef\@MXV@iiidopt{3Dresource=#1, \@MXV@iiidopt}%
+ }{%
+ \PackageError{movie15}{3D resource file `#1' cannot be opened%
+ }{%
+ Make sure file `#1' exists and is readable!%
+ }%
+ }%
+ }{\@MXV@neediiiD}%
+}
+
+%compatibility options for \movie and \hyperlinkmovie commands
+\define@key{MXV@user}{borderwidth}{%
+ %ignored; acroread doesn't draw borders around screen annots anyway
+}
+\define@key{MXV@user}{height}{%set height of display area
+ \gdef\@MXV@boxheight{#1}%
+}
+\define@key{MXV@user}{width}{%set width of display area
+ \gdef\@MXV@boxwidth{#1}%
+}
+\define@key{MXV@user}{autostart}[true]{%
+ \xdef\@MXV@autostart{, autoplay=#1}%
+}
+\define@key{MXV@user}{loop}[Infinity]{%
+ \xdef\@MXV@loop{, repeat=#1}%
+}
+\define@key{MXV@user}{once}[]{%
+ \xdef\@MXV@loop{, repeat=1}%
+}
+\define@key{MXV@user}{showcontrols}[true]{%
+ \xdef\@MXV@showcontrols{, controls=#1}%
+}
+\define@key{MXV@user}{start}{%
+ \gdef\@MXV@starttime##1s{%
+ \global\@MXV@start=##1pt%
+ }%
+ \@MXV@starttime #1%
+}
+\define@key{MXV@user}{duration}{%
+ \gdef\@MXV@durationtime##1s{%
+ \global\@MXV@end=##1pt%
+ }%
+ \@MXV@durationtime #1%
+}
+
+%options to be passed to internal macro \@MXV@includeiiid
+\define@key{MXV@iiid}{3Dresource}{%
+ \@MXV@addresource{#1}%
+}
+
+%compatibility macros
+\providecommand\movie[3][]{%
+ \ifpdf\else%
+ \ifthenelse{\isundefined{\pdfmark}\AND\isundefined{\@pdfm@mark}}{\@MXV@missing{hyperref}}{}%
+ \fi%
+ \leavevmode%
+ \@MXV@reset%
+ \def\@MXV@autostart{}\def\@MXV@loop{}\def\@MXV@showcontrols{}%
+ \def\@MXV@starttime{}\def\@MXV@durationtime{}%
+ \setkeys{MXV@user}{#1}%
+ %
+ %sanity checks
+ \if@MXV@boxopt%
+ \PackageError{movie15}{%
+ Option `text' cannot be used with command `\string\movie'.\MessageBreak
+ Instead, put text into the 1st argument of `\string\movie'
+ }{}%
+ \fi%
+ %
+ \ifx\@MXV@durationtime\@empty\else\ifx\@MXV@startat\@empty\else%
+ \PackageError{movie15}{%
+ Options `startat' and `duration' cannot be used\MessageBreak
+ together.\MessageBreak
+ Possible combinations are `startat'/`endat',\MessageBreak
+ `start'/`endat' or `start'/`duration'
+ }{}%
+ \fi\fi%
+ %
+ %option list
+ \edef\@MXV@movieoptions{#1\@MXV@autostart\@MXV@loop\@MXV@showcontrols}%
+ %
+ %determine playback section
+ \ifx\@MXV@starttime\@empty\else%
+ \edef\@MXV@movieoptions{\@MXV@movieoptions, %
+ startat=time:\strip@pt\@MXV@start}%
+ \fi%
+ \ifx\@MXV@durationtime\@empty\else%
+ \advance\@MXV@end by \@MXV@start%
+ \edef\@MXV@movieoptions{\@MXV@movieoptions, %
+ endat=time:\strip@pt\@MXV@end}%
+ \fi%
+ %
+ %text option from 2nd argument
+ \savebox{\@MXV@textbox}{#2}%
+ \edef\@MXV@movieoptions{[\@MXV@movieoptions, text={\noexpand\usebox{%
+ \noexpand\@MXV@textbox}}]}%
+ \expandafter%
+ \includemovie\@MXV@movieoptions{\@MXV@boxwidth}{\@MXV@boxheight}{#3}%
+}
+
+\newcommand\hyperlinkmovie[3][]{%
+ \ifpdf\else%
+ \ifthenelse{\isundefined{\pdfmark}\AND\isundefined{\@pdfm@mark}}{\@MXV@missing{hyperref}}{}%
+ \fi%
+ \leavevmode%
+ \@MXV@reset%
+ \def\@MXV@autostart{}\def\@MXV@loop{}\def\@MXV@showcontrols{}%
+ \def\@MXV@starttime{}\def\@MXV@durationtime{}%
+ \setkeys{MXV@user}{#1}%
+ %
+ %sanity check
+ \ifx\@MXV@durationtime\@empty\else\ifx\@MXV@startat\@empty\else%
+ \PackageError{movie15}{%
+ Options `startat' and `duration' cannot be used\MessageBreak
+ together.\MessageBreak
+ Possible combinations are `startat'/`endat',\MessageBreak
+ `start'/`endat' or `start'/`duration'
+ }{}%
+ \fi\fi%
+ %
+ %option list
+ \edef\@MXV@movieoptions{#1\@MXV@autostart\@MXV@loop\@MXV@showcontrols}%
+ %
+ %determine playback section
+ \ifx\@MXV@starttime\@empty\else%
+ \edef\@MXV@movieoptions{\@MXV@movieoptions, %
+ startat=time:\strip@pt\@MXV@start}%
+ \fi%
+ \ifx\@MXV@durationtime\@empty\else%
+ \advance\@MXV@end by \@MXV@start%
+ \edef\@MXV@movieoptions{\@MXV@movieoptions, %
+ endat=time:\strip@pt\@MXV@end}%
+ \fi%
+ %
+ \edef\@MXV@movieoptions{[\@MXV@movieoptions]}%
+ \expandafter\movieref\@MXV@movieoptions{#2}{#3}%
+}
diff --git a/Build/source/utils/asymptote/patches/pstoedit-3.45asy.patch b/Build/source/utils/asymptote/patches/pstoedit-3.45asy.patch
new file mode 100644
index 00000000000..da289bba0c0
--- /dev/null
+++ b/Build/source/utils/asymptote/patches/pstoedit-3.45asy.patch
@@ -0,0 +1,182 @@
+diff -ru pstoedit-3.45/src/cppcomp.h pstoedit-3.45J/src/cppcomp.h
+--- pstoedit-3.45/src/cppcomp.h 2007-07-22 05:27:40.000000000 -0600
++++ pstoedit-3.45J/src/cppcomp.h 2009-02-11 23:20:06.000000000 -0700
+@@ -22,6 +22,8 @@
+
+ */
+
++#include <cstring>
++
+ #ifdef _MSC_VER
+ # ifndef DLLEXPORT
+ # define DLLEXPORT __declspec( dllexport )
+@@ -242,7 +244,7 @@
+ *de = 0;
+ } else {
+ cerr << "buffer overflow in strcpy_s. Input string: '" << so << "' count: " << count << " sourcelen " << sourcelen << " buffersize " << de_size << endl;
+- exit(1);
++ _exit(1);
+ }
+ }
+ static inline void strcpy_s(char * de, size_t de_size, const char * so) {
+diff -ru pstoedit-3.45/src/drvasy.cpp pstoedit-3.45J/src/drvasy.cpp
+--- pstoedit-3.45/src/drvasy.cpp 2007-07-22 05:27:30.000000000 -0600
++++ pstoedit-3.45J/src/drvasy.cpp 2007-12-08 16:22:58.000000000 -0700
+@@ -58,7 +58,8 @@
+ clipmode(false),
+ evenoddmode(false),
+ firstpage(true),
+- imgcount(0)
++ imgcount(0),
++ level(0)
+ {
+ // Output copyright information
+ outf << "// Converted from PostScript(TM) to Asymptote by pstoedit\n"
+@@ -76,6 +77,29 @@
+ options=0;
+ }
+
++void drvASY::save()
++{
++ while(gsavestack.size() && gsavestack.front()) {
++ gsavestack.pop_front();
++ outf << "gsave();" << endl;
++ ++level;
++ clipstack.push_back(false);
++ }
++}
++
++void drvASY::restore() {
++ while(gsavestack.size() && !gsavestack.front()) {
++ gsavestack.pop_front();
++ while(clipstack.size() > 0) {
++ if(clipstack.back())
++ outf << "endclip();" << endl;
++ clipstack.pop_back();
++ }
++ outf << "grestore();" << endl;
++ if(level > 0) --level;
++ }
++}
++
+ // Output a path
+ void drvASY::print_coords()
+ {
+@@ -84,11 +108,7 @@
+ bool havecycle=false;
+ bool firstpoint=false;
+
+- while(gsavestack.size() && gsavestack.front()) {
+- gsavestack.pop_front();
+- outf << "gsave();" << endl;
+- clipstack.push_back(false);
+- }
++ save();
+
+ if (fillmode || clipmode) {
+ for (unsigned int n = 0; n < numberOfElementsInPath(); n++) {
+@@ -247,16 +267,7 @@
+ outf << ");" << endl;
+ }
+ }
+-
+- while(gsavestack.size() && !gsavestack.front()) {
+- gsavestack.pop_front();
+- if(clipstack.size() > 0) {
+- if(clipstack.back())
+- outf << "endclip();" << endl;
+- clipstack.pop_back();
+- }
+- outf << "grestore();" << endl;
+- }
++ restore();
+ }
+
+ // Each page will produce a different figure
+@@ -272,6 +283,8 @@
+
+ void drvASY::show_image(const PSImage & imageinfo)
+ {
++ restore();
++
+ if (outBaseName == "" ) {
+ errf << "images cannot be handled via standard output. Use an output file" << endl;
+ return;
+@@ -285,9 +298,13 @@
+ ostringstream buf;
+ buf << outBaseName << "." << imgcount << ".eps";
+
+- outf << "label(graphic(\"" << buf.str() << "\"),("
++ outf << "label(graphic(\"" << buf.str() << "\",\"bb="
++ << ll.x_ << " " << ll.y_ << " " << ur.x_ << " " << ur.y_ << "\"),("
+ << ll.x_ << "," << ll.y_ << "),align);" << endl;
+- outf << "layer();" << endl;
++
++ // Try to draw image in a separate layer.
++ if(level == 0)
++ outf << "layer();" << endl;
+
+ ofstream outi(buf.str().c_str());
+ if (!outi) {
+@@ -304,6 +321,8 @@
+ // Output a text string
+ void drvASY::show_text(const TextInfo & textinfo)
+ {
++ restore();
++
+ // Change fonts
+ string thisFontName(textinfo.currentFontName.value());
+ string thisFontWeight(textinfo.currentFontWeight.value());
+@@ -361,7 +380,8 @@
+ if(prevFontAngle != 0.0) outf << "rotate(" << prevFontAngle << ")*(";
+ bool texify=false;
+ bool quote=false;
+- for (const char *c = textinfo.thetext.value(); *c; c++) {
++ const char *c=textinfo.thetext.value();
++ if(*c) for (; *c; c++) {
+ if (*c >= ' ' && *c != '\\' && *c <= '~') {
+ if(!texify) {
+ if(quote) outf << "\"+";
+@@ -383,7 +403,7 @@
+ }
+ outf << "\\char" << (int) *c;
+ }
+- }
++ } else outf << "\"\"";
+ if(quote) outf << "\"";
+ if(texify) outf << ")";
+ if(prevFontAngle != 0.0) outf << ")";
+diff -ru pstoedit-3.45/src/drvasy.h pstoedit-3.45J/src/drvasy.h
+--- pstoedit-3.45/src/drvasy.h 2007-07-22 05:27:40.000000000 -0600
++++ pstoedit-3.45J/src/drvasy.h 2007-12-08 16:22:51.000000000 -0700
+@@ -58,6 +58,8 @@
+
+ private:
+ void print_coords();
++ void save();
++ void restore();
+ // Previous values of graphics state variables
+ string prevFontName;
+ string prevFontWeight;
+@@ -80,6 +82,9 @@
+
+ int imgcount;
+
++ unsigned int level;
++ // gsave nesting level
++
+ std::list<bool> clipstack;
+ std::list<bool> gsavestack;
+ };
+diff -ru pstoedit-3.45/src/dynload.cpp pstoedit-3.45J/src/dynload.cpp
+--- pstoedit-3.45/src/dynload.cpp 2007-07-22 05:27:36.000000000 -0600
++++ pstoedit-3.45J/src/dynload.cpp 2009-02-11 15:28:59.000000000 -0700
+@@ -93,7 +93,7 @@
+ {
+ if (handle) {
+ cerr << "error: DynLoader has already opened a library" << endl;
+- exit(1);
++ _exit(1);
+ }
+ const unsigned int size = strlen(libname_P) + 1;
+ char *fulllibname = new char[size];
diff --git a/Build/source/utils/asymptote/path.cc b/Build/source/utils/asymptote/path.cc
new file mode 100644
index 00000000000..0ad028d5cc5
--- /dev/null
+++ b/Build/source/utils/asymptote/path.cc
@@ -0,0 +1,1340 @@
+/*****
+ * path.cc
+ * Andy Hammerlindl 2002/06/06
+ *
+ * Stores and returns information on a predefined path.
+ *
+ * When changing the path algorithms, also update the corresponding
+ * three-dimensional algorithms in path3.cc.
+ *****/
+
+#include "path.h"
+#include "util.h"
+#include "angle.h"
+#include "camperror.h"
+#include "mathop.h"
+#include "arrayop.h"
+#include "predicates.h"
+#include "rounding.h"
+
+namespace camp {
+
+const double BigFuzz=10000.0*DBL_EPSILON;
+const double Fuzz=1000.0*DBL_EPSILON;
+const double Fuzz2=Fuzz*Fuzz;
+const double sqrtFuzz=sqrt(Fuzz);
+const double third=1.0/3.0;
+
+path nullpath;
+
+void checkEmpty(Int n) {
+ if(n == 0)
+ reportError("nullpath has no points");
+}
+
+// Accurate computation of sqrt(1+x)-1.
+inline double sqrt1pxm1(double x)
+{
+ return x/(sqrt(1.0+x)+1.0);
+}
+inline pair sqrt1pxm1(pair x)
+{
+ return x/(Sqrt(1.0+x)+1.0);
+}
+
+// Solve for the real roots of the quadratic equation ax^2+bx+c=0.
+quadraticroots::quadraticroots(double a, double b, double c)
+{
+ if(a == 0.0) {
+ if(b != 0.0) {
+ distinct=quadraticroots::ONE;
+ roots=1;
+ t1=-c/b;
+ } else if(c == 0.0) {
+ distinct=quadraticroots::MANY;
+ roots=1;
+ t1=0.0;
+ } else {
+ distinct=quadraticroots::NONE;
+ roots=0;
+ }
+ } else if(b == 0.0) {
+ double x=-c/a;
+ if(x >= 0.0) {
+ distinct=quadraticroots::TWO;
+ roots=2;
+ t2=sqrt(x);
+ t1=-t2;
+ } else {
+ distinct=quadraticroots::NONE;
+ roots=0;
+ }
+ } else {
+ double factor=0.5*b/a;
+ double x=-2.0*c/(b*factor);
+ if(x > -1.0) {
+ distinct=quadraticroots::TWO;
+ roots=2;
+ double sqrtm1=sqrt1pxm1(x);
+ double r2=factor*sqrtm1;
+ double r1=-r2-2.0*factor;
+ if(r1 <= r2) {
+ t1=r1;
+ t2=r2;
+ } else {
+ t1=r2;
+ t2=r1;
+ }
+ } else if(x == -1.0) {
+ distinct=quadraticroots::ONE;
+ roots=2;
+ t1=t2=-factor;
+ } else {
+ distinct=quadraticroots::NONE;
+ roots=0;
+ }
+ }
+}
+
+// Solve for the complex roots of the quadratic equation ax^2+bx+c=0.
+Quadraticroots::Quadraticroots(pair a, pair b, pair c)
+{
+ if(a == 0.0) {
+ if(b != 0.0) {
+ roots=1;
+ z1=-c/b;
+ } else if(c == 0.0) {
+ roots=1;
+ z1=0.0;
+ } else
+ roots=0;
+ } else {
+ roots=2;
+ if(b == 0.0) {
+ z1=Sqrt(-c/a);
+ z2=-z1;
+ } else {
+ pair factor=0.5*b/a;
+ pair x=-2.0*c/(b*factor);
+ pair sqrtm1=sqrt1pxm1(x);
+ z1=factor*sqrtm1;
+ z2=-z1-2.0*factor;
+ }
+ }
+}
+
+inline bool goodroot(double a, double b, double c, double t)
+{
+ return goodroot(t) && quadratic(a,b,c,t) >= 0.0;
+}
+
+// Accurate computation of cbrt(sqrt(1+x)+1)-cbrt(sqrt(1+x)-1).
+inline double cbrtsqrt1pxm(double x)
+{
+ double s=sqrt1pxm1(x);
+ return 2.0/(cbrt(x+2.0*(sqrt(1.0+x)+1.0))+cbrt(x)+cbrt(s*s));
+}
+
+// Taylor series of cos((atan(1.0/w)+pi)/3.0).
+static inline double costhetapi3(double w)
+{
+ static const double c1=1.0/3.0;
+ static const double c3=-19.0/162.0;
+ static const double c5=425.0/5832.0;
+ static const double c7=-16829.0/314928.0;
+ double w2=w*w;
+ double w3=w2*w;
+ double w5=w3*w2;
+ return c1*w+c3*w3+c5*w5+c7*w5*w2;
+}
+
+// Solve for the real roots of the cubic equation ax^3+bx^2+cx+d=0.
+cubicroots::cubicroots(double a, double b, double c, double d)
+{
+ static const double ninth=1.0/9.0;
+ static const double fiftyfourth=1.0/54.0;
+
+ // Remove roots at numerical infinity.
+ if(fabs(a) <= Fuzz*(fabs(b)+fabs(c)*Fuzz+fabs(d)*Fuzz2)) {
+ quadraticroots q(b,c,d);
+ roots=q.roots;
+ if(q.roots >= 1) t1=q.t1;
+ if(q.roots == 2) t2=q.t2;
+ return;
+ }
+
+ // Detect roots at numerical zero.
+ if(fabs(d) <= Fuzz*(fabs(c)+fabs(b)*Fuzz+fabs(a)*Fuzz2)) {
+ quadraticroots q(a,b,c);
+ roots=q.roots+1;
+ t1=0;
+ if(q.roots >= 1) t2=q.t1;
+ if(q.roots == 2) t3=q.t2;
+ return;
+ }
+
+ double ainv=1.0/a;
+ b *= ainv; c *= ainv; d *= ainv;
+
+ double b2=b*b;
+ double Q=3.0*c-b2;
+ if(fabs(Q) < Fuzz*(3.0*fabs(c)+fabs(b2)))
+ Q=0.0;
+
+ double R=(3.0*Q+b2)*b-27.0*d;
+ if(fabs(R) < Fuzz*((3.0*fabs(Q)+fabs(b2))*fabs(b)+27.0*fabs(d)))
+ R=0.0;
+
+ Q *= ninth;
+ R *= fiftyfourth;
+
+ double Q3=Q*Q*Q;
+ double R2=R*R;
+ double D=Q3+R2;
+ double mthirdb=-b*third;
+
+ if(D > 0.0) {
+ roots=1;
+ t1=mthirdb;
+ if(R2 != 0.0) t1 += cbrt(R)*cbrtsqrt1pxm(Q3/R2);
+ } else {
+ roots=3;
+ double v=0.0,theta;
+ if(R2 > 0.0) {
+ v=sqrt(-D/R2);
+ theta=atan(v);
+ } else theta=0.5*PI;
+ double factor=2.0*sqrt(-Q)*(R >= 0 ? 1 : -1);
+
+ t1=mthirdb+factor*cos(third*theta);
+ t2=mthirdb-factor*cos(third*(theta-PI));
+ t3=mthirdb;
+ if(R2 > 0.0)
+ t3 -= factor*((v < 100.0) ? cos(third*(theta+PI)) : costhetapi3(1.0/v));
+ }
+}
+
+pair path::point(double t) const
+{
+ checkEmpty(n);
+
+ Int i = Floor(t);
+ Int iplus;
+ t = fmod(t,1);
+ if (t < 0) t += 1;
+
+ if (cycles) {
+ i = imod(i,n);
+ iplus = imod(i+1,n);
+ }
+ else if (i < 0)
+ return nodes[0].point;
+ else if (i >= n-1)
+ return nodes[n-1].point;
+ else
+ iplus = i+1;
+
+ double one_t = 1.0-t;
+
+ pair a = nodes[i].point,
+ b = nodes[i].post,
+ c = nodes[iplus].pre,
+ d = nodes[iplus].point,
+ ab = one_t*a + t*b,
+ bc = one_t*b + t*c,
+ cd = one_t*c + t*d,
+ abc = one_t*ab + t*bc,
+ bcd = one_t*bc + t*cd,
+ abcd = one_t*abc + t*bcd;
+
+ return abcd;
+}
+
+pair path::precontrol(double t) const
+{
+ checkEmpty(n);
+
+ Int i = Floor(t);
+ Int iplus;
+ t = fmod(t,1);
+ if (t < 0) t += 1;
+
+ if (cycles) {
+ i = imod(i,n);
+ iplus = imod(i+1,n);
+ }
+ else if (i < 0)
+ return nodes[0].pre;
+ else if (i >= n-1)
+ return nodes[n-1].pre;
+ else
+ iplus = i+1;
+
+ double one_t = 1.0-t;
+
+ pair a = nodes[i].point,
+ b = nodes[i].post,
+ c = nodes[iplus].pre,
+ ab = one_t*a + t*b,
+ bc = one_t*b + t*c,
+ abc = one_t*ab + t*bc;
+
+ return (abc == a) ? nodes[i].pre : abc;
+}
+
+
+pair path::postcontrol(double t) const
+{
+ checkEmpty(n);
+
+ Int i = Floor(t);
+ Int iplus;
+ t = fmod(t,1);
+ if (t < 0) t += 1;
+
+ if (cycles) {
+ i = imod(i,n);
+ iplus = imod(i+1,n);
+ }
+ else if (i < 0)
+ return nodes[0].post;
+ else if (i >= n-1)
+ return nodes[n-1].post;
+ else
+ iplus = i+1;
+
+ double one_t = 1.0-t;
+
+ pair b = nodes[i].post,
+ c = nodes[iplus].pre,
+ d = nodes[iplus].point,
+ bc = one_t*b + t*c,
+ cd = one_t*c + t*d,
+ bcd = one_t*bc + t*cd;
+
+ return (bcd == d) ? nodes[iplus].post : bcd;
+}
+
+path path::reverse() const
+{
+ mem::vector<solvedKnot> nodes(n);
+ Int len=length();
+ for (Int i = 0, j = len; i < n; i++, j--) {
+ nodes[i].pre = postcontrol(j);
+ nodes[i].point = point(j);
+ nodes[i].post = precontrol(j);
+ nodes[i].straight = straight(j-1);
+ }
+ return path(nodes, n, cycles);
+}
+
+path path::subpath(Int a, Int b) const
+{
+ if(empty()) return path();
+
+ if (a > b) {
+ const path &rp = reverse();
+ Int len=length();
+ path result = rp.subpath(len-a, len-b);
+ return result;
+ }
+
+ if (!cycles) {
+ if (a < 0)
+ a = 0;
+ if (b > n-1)
+ b = n-1;
+ }
+
+ Int sn = b-a+1;
+ mem::vector<solvedKnot> nodes(sn);
+
+ for (Int i = 0, j = a; j <= b; i++, j++) {
+ nodes[i].pre = precontrol(j);
+ nodes[i].point = point(j);
+ nodes[i].post = postcontrol(j);
+ nodes[i].straight = straight(j);
+ }
+ nodes[0].pre = nodes[0].point;
+ nodes[sn-1].post = nodes[sn-1].point;
+
+ return path(nodes, sn);
+}
+
+inline pair split(double t, const pair& x, const pair& y) { return x+(y-x)*t; }
+
+inline void splitCubic(solvedKnot sn[], double t, const solvedKnot& left_,
+ const solvedKnot& right_)
+{
+ solvedKnot &left=(sn[0]=left_), &mid=sn[1], &right=(sn[2]=right_);
+ if(left.straight) {
+ mid.point=split(t,left.point,right.point);
+ pair deltaL=third*(mid.point-left.point);
+ left.post=left.point+deltaL;
+ mid.pre=mid.point-deltaL;
+ pair deltaR=third*(right.point-mid.point);
+ mid.post=mid.point+deltaR;
+ right.pre=right.point-deltaR;
+ mid.straight=true;
+ } else {
+ pair x=split(t,left.post,right.pre); // m1
+ left.post=split(t,left.point,left.post); // m0
+ right.pre=split(t,right.pre,right.point); // m2
+ mid.pre=split(t,left.post,x); // m3
+ mid.post=split(t,x,right.pre); // m4
+ mid.point=split(t,mid.pre,mid.post); // m5
+ }
+}
+
+path path::subpath(double a, double b) const
+{
+ if(empty()) return path();
+
+ if (a > b) {
+ const path &rp = reverse();
+ Int len=length();
+ return rp.subpath(len-a, len-b);
+ }
+
+ solvedKnot aL, aR, bL, bR;
+ if (!cycles) {
+ if (a < 0) {
+ a = 0;
+ if (b < 0)
+ b = 0;
+ }
+ if (b > n-1) {
+ b = n-1;
+ if (a > n-1)
+ a = n-1;
+ }
+ aL = nodes[(Int)floor(a)];
+ aR = nodes[(Int)ceil(a)];
+ bL = nodes[(Int)floor(b)];
+ bR = nodes[(Int)ceil(b)];
+ } else {
+ if(run::validInt(a) && run::validInt(b)) {
+ aL = nodes[imod((Int) floor(a),n)];
+ aR = nodes[imod((Int) ceil(a),n)];
+ bL = nodes[imod((Int) floor(b),n)];
+ bR = nodes[imod((Int) ceil(b),n)];
+ } else reportError("invalid path index");
+ }
+
+ if (a == b) return path(point(a));
+
+ solvedKnot sn[3];
+ path p = subpath(Ceil(a), Floor(b));
+ if (a > floor(a)) {
+ if (b < ceil(a)) {
+ splitCubic(sn,a-floor(a),aL,aR);
+ splitCubic(sn,(b-a)/(ceil(b)-a),sn[1],sn[2]);
+ return path(sn[0],sn[1]);
+ }
+ splitCubic(sn,a-floor(a),aL,aR);
+ p=concat(path(sn[1],sn[2]),p);
+ }
+ if (ceil(b) > b) {
+ splitCubic(sn,b-floor(b),bL,bR);
+ p=concat(p,path(sn[0],sn[1]));
+ }
+ return p;
+}
+
+// Special case of subpath for paths of length 1 used by intersect.
+void path::halve(path &first, path &second) const
+{
+ solvedKnot sn[3];
+ splitCubic(sn,0.5,nodes[0],nodes[1]);
+ first=path(sn[0],sn[1]);
+ second=path(sn[1],sn[2]);
+}
+
+// Calculate the coefficients of a Bezier derivative divided by 3.
+static inline void derivative(pair& a, pair& b, pair& c,
+ const pair& z0, const pair& c0,
+ const pair& c1, const pair& z1)
+{
+ a=z1-z0+3.0*(c0-c1);
+ b=2.0*(z0+c1)-4.0*c0;
+ c=c0-z0;
+}
+
+bbox path::bounds() const
+{
+ if(!box.empty) return box;
+
+ if (empty()) {
+ // No bounds
+ return bbox();
+ }
+
+ Int len=length();
+ box.add(point(len));
+
+ for (Int i = 0; i < len; i++) {
+ addpoint(box,i);
+ if(straight(i)) continue;
+
+ pair a,b,c;
+ derivative(a,b,c,point(i),postcontrol(i),precontrol(i+1),point(i+1));
+
+ // Check x coordinate
+ quadraticroots x(a.getx(),b.getx(),c.getx());
+ if(x.distinct != quadraticroots::NONE && goodroot(x.t1))
+ addpoint(box,i+x.t1);
+ if(x.distinct == quadraticroots::TWO && goodroot(x.t2))
+ addpoint(box,i+x.t2);
+
+ // Check y coordinate
+ quadraticroots y(a.gety(),b.gety(),c.gety());
+ if(y.distinct != quadraticroots::NONE && goodroot(y.t1))
+ addpoint(box,i+y.t1);
+ if(y.distinct == quadraticroots::TWO && goodroot(y.t2))
+ addpoint(box,i+y.t2);
+ }
+ return box;
+}
+
+bbox path::bounds(double min, double max) const
+{
+ bbox box;
+
+ Int len=length();
+ for (Int i = 0; i < len; i++) {
+ addpoint(box,i,min,max);
+ if(straight(i)) continue;
+
+ pair a,b,c;
+ derivative(a,b,c,point(i),postcontrol(i),precontrol(i+1),point(i+1));
+
+ // Check x coordinate
+ quadraticroots x(a.getx(),b.getx(),c.getx());
+ if(x.distinct != quadraticroots::NONE && goodroot(x.t1))
+ addpoint(box,i+x.t1,min,max);
+
+ if(x.distinct == quadraticroots::TWO && goodroot(x.t2))
+ addpoint(box,i+x.t2,min,max);
+
+ // Check y coordinate
+ quadraticroots y(a.gety(),b.gety(),c.gety());
+ if(y.distinct != quadraticroots::NONE && goodroot(y.t1))
+ addpoint(box,i+y.t1,min,max);
+ if(y.distinct == quadraticroots::TWO && goodroot(y.t2))
+ addpoint(box,i+y.t2,min,max);
+ }
+ addpoint(box,len,min,max);
+ return box;
+}
+
+inline void add(bbox& box, const pair& z, const pair& min, const pair& max)
+{
+ box += z+min;
+ box += z+max;
+}
+
+bbox path::internalbounds(const bbox& padding) const
+{
+ bbox box;
+
+ // Check interior nodes.
+ Int len=length();
+ for (Int i = 1; i < len; i++) {
+ pair pre=point(i)-precontrol(i);
+ pair post=postcontrol(i)-point(i);
+
+ // Check node x coordinate
+ if((pre.getx() >= 0.0) ^ (post.getx() >= 0))
+ add(box,point(i),padding.left,padding.right);
+
+ // Check node y coordinate
+ if((pre.gety() >= 0.0) ^ (post.gety() >= 0))
+ add(box,point(i),pair(0,padding.bottom),pair(0,padding.top));
+ }
+
+ // Check interior segments.
+ for (Int i = 0; i < len; i++) {
+ if(straight(i)) continue;
+
+ pair a,b,c;
+ derivative(a,b,c,point(i),postcontrol(i),precontrol(i+1),point(i+1));
+
+ // Check x coordinate
+ quadraticroots x(a.getx(),b.getx(),c.getx());
+ if(x.distinct != quadraticroots::NONE && goodroot(x.t1))
+ add(box,point(i+x.t1),padding.left,padding.right);
+ if(x.distinct == quadraticroots::TWO && goodroot(x.t2))
+ add(box,point(i+x.t2),padding.left,padding.right);
+
+ // Check y coordinate
+ quadraticroots y(a.gety(),b.gety(),c.gety());
+ if(y.distinct != quadraticroots::NONE && goodroot(y.t1))
+ add(box,point(i+y.t1),pair(0,padding.bottom),pair(0,padding.top));
+ if(y.distinct == quadraticroots::TWO && goodroot(y.t2))
+ add(box,point(i+y.t2),pair(0,padding.bottom),pair(0,padding.top));
+ }
+ return box;
+}
+
+// {{{ Arclength Calculations
+
+static pair a,b,c;
+
+static double ds(double t)
+{
+ double dx=quadratic(a.getx(),b.getx(),c.getx(),t);
+ double dy=quadratic(a.gety(),b.gety(),c.gety(),t);
+ return sqrt(dx*dx+dy*dy);
+}
+
+// Calculates arclength of a cubic using adaptive simpson integration.
+double path::cubiclength(Int i, double goal) const
+{
+ const pair& z0=point(i);
+ const pair& z1=point(i+1);
+ double L;
+ if(straight(i)) {
+ L=(z1-z0).length();
+ 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");
+ L=3.0*integral;
+ if(goal < 0 || goal >= L) return L;
+
+ double t=goal/L;
+ goal *= third;
+ static double dxmin=sqrt(DBL_EPSILON);
+ if(!unsimpson(goal,ds,0.0,t,100.0*DBL_EPSILON,integral,1.0,dxmin))
+ reportError("nesting capacity exceeded in computing arctime");
+ return -t;
+}
+
+double path::arclength() const
+{
+ if (cached_length != -1) return cached_length;
+
+ double L=0.0;
+ for (Int i = 0; i < n-1; i++) {
+ L += cubiclength(i);
+ }
+ if(cycles) L += cubiclength(n-1);
+ cached_length = L;
+ return cached_length;
+}
+
+double path::arctime(double goal) const
+{
+ if (cycles) {
+ if (goal == 0 || cached_length == 0) return 0;
+ if (goal < 0) {
+ const path &rp = this->reverse();
+ double result = -rp.arctime(-goal);
+ return result;
+ }
+ if (cached_length > 0 && goal >= cached_length) {
+ Int loops = (Int)(goal / cached_length);
+ goal -= loops*cached_length;
+ return loops*n+arctime(goal);
+ }
+ } else {
+ if (goal <= 0)
+ return 0;
+ if (cached_length > 0 && goal >= cached_length)
+ return n-1;
+ }
+
+ double l,L=0;
+ for (Int i = 0; i < n-1; i++) {
+ l = cubiclength(i,goal);
+ if (l < 0)
+ return (-l+i);
+ else {
+ L += l;
+ goal -= l;
+ if (goal <= 0)
+ return i+1;
+ }
+ }
+ if (cycles) {
+ l = cubiclength(n-1,goal);
+ if (l < 0)
+ return -l+n-1;
+ if (cached_length > 0 && cached_length != L+l) {
+ reportError("arclength != length.\n"
+ "path::arclength(double) must have broken semantics.\n"
+ "Please report this error.");
+ }
+ cached_length = L += l;
+ goal -= l;
+ return arctime(goal)+n;
+ }
+ else {
+ cached_length = L;
+ return length();
+ }
+}
+
+// }}}
+
+// {{{ Direction Time Calulation
+// Algorithm Stolen from Knuth's MetaFont
+inline double cubicDir(const solvedKnot& left, const solvedKnot& right,
+ const pair& rot)
+{
+ pair a,b,c;
+ derivative(a,b,c,left.point,left.post,right.pre,right.point);
+ a *= rot; b *= rot; c *= rot;
+
+ quadraticroots ret(a.gety(),b.gety(),c.gety());
+ switch(ret.distinct) {
+ case quadraticroots::MANY:
+ case quadraticroots::ONE:
+ {
+ if(goodroot(a.getx(),b.getx(),c.getx(),ret.t1)) return ret.t1;
+ } break;
+
+ case quadraticroots::TWO:
+ {
+ if(goodroot(a.getx(),b.getx(),c.getx(),ret.t1)) return ret.t1;
+ if(goodroot(a.getx(),b.getx(),c.getx(),ret.t2)) return ret.t2;
+ } break;
+
+ case quadraticroots::NONE:
+ break;
+ }
+
+ return -1;
+}
+
+// TODO: Check that we handle corner cases.
+// Velocity(t) == (0,0)
+double path::directiontime(const pair& dir) const {
+ if (dir == pair(0,0)) return 0;
+ pair rot = pair(1,0)/unit(dir);
+
+ double t; double pre,post;
+ for (Int i = 0; i < n-1+cycles; ) {
+ t = cubicDir(this->nodes[i],(cycles && i==n-1) ? nodes[0]:nodes[i+1],rot);
+ if (t >= 0) return i+t;
+ i++;
+ if (cycles || i != n-1) {
+ pair Pre = (point(i)-precontrol(i))*rot;
+ pair Post = (postcontrol(i)-point(i))*rot;
+ static pair zero(0.0,0.0);
+ if(Pre != zero && Post != zero) {
+ pre = angle(Pre);
+ post = angle(Post);
+ if ((pre <= 0 && post >= 0 && pre >= post - PI) ||
+ (pre >= 0 && post <= 0 && pre <= post + PI))
+ return i;
+ }
+ }
+ }
+
+ return -1;
+}
+// }}}
+
+// {{{ Path Intersection Calculations
+
+const unsigned maxdepth=DBL_MANT_DIG;
+const unsigned mindepth=maxdepth-16;
+
+void roots(std::vector<double> &roots, double a, double b, double c, double d)
+{
+ cubicroots r(a,b,c,d);
+ if(r.roots >= 1) roots.push_back(r.t1);
+ if(r.roots >= 2) roots.push_back(r.t2);
+ if(r.roots == 3) roots.push_back(r.t3);
+}
+
+void roots(std::vector<double> &r, double x0, double c0, double c1, double x1,
+ double x)
+{
+ double a=x1-x0+3.0*(c0-c1);
+ double b=3.0*(x0+c1)-6.0*c0;
+ double c=3.0*(c0-x0);
+ double d=x0-x;
+ roots(r,a,b,c,d);
+}
+
+// Return all intersection times of path g with the pair z.
+void intersections(std::vector<double>& T, const path& g, const pair& z,
+ double fuzz)
+{
+ double fuzz2=fuzz*fuzz;
+ Int n=g.length();
+ bool cycles=g.cyclic();
+ for(Int i=0; i < n; ++i) {
+ // Check both directions to circumvent degeneracy.
+ std::vector<double> r;
+ roots(r,g.point(i).getx(),g.postcontrol(i).getx(),
+ g.precontrol(i+1).getx(),g.point(i+1).getx(),z.getx());
+ roots(r,g.point(i).gety(),g.postcontrol(i).gety(),
+ g.precontrol(i+1).gety(),g.point(i+1).gety(),z.gety());
+
+ size_t m=r.size();
+ for(size_t j=0 ; j < m; ++j) {
+ double t=r[j];
+ if(t >= -Fuzz && t <= 1.0+Fuzz) {
+ double s=i+t;
+ if((g.point(s)-z).abs2() <= fuzz2) {
+ if(cycles && s >= n-Fuzz) s=0;
+ T.push_back(s);
+ }
+ }
+ }
+ }
+}
+
+inline bool online(const pair&p, const pair& q, const pair& z, double fuzz)
+{
+ if(p == q) return (z-p).abs2() <= fuzz*fuzz;
+ return (z.getx()-p.getx())*(q.gety()-p.gety()) ==
+ (q.getx()-p.getx())*(z.gety()-p.gety());
+}
+
+// Return all intersection times of path g with the (infinite)
+// line through p and q; if there are an infinite number of intersection points,
+// the returned list is guaranteed to include the endpoint times of
+// the intersection if endpoints=true.
+void lineintersections(std::vector<double>& T, const path& g,
+ const pair& p, const pair& q, double fuzz,
+ bool endpoints=false)
+{
+ Int n=g.length();
+ if(n == 0) {
+ if(online(p,q,g.point((Int) 0),fuzz)) T.push_back(0.0);
+ return;
+ }
+ bool cycles=g.cyclic();
+ double dx=q.getx()-p.getx();
+ double dy=q.gety()-p.gety();
+ double det=p.gety()*q.getx()-p.getx()*q.gety();
+ for(Int i=0; i < n; ++i) {
+ pair z0=g.point(i);
+ pair c0=g.postcontrol(i);
+ pair c1=g.precontrol(i+1);
+ pair z1=g.point(i+1);
+ pair t3=z1-z0+3.0*(c0-c1);
+ pair t2=3.0*(z0+c1)-6.0*c0;
+ pair t1=3.0*(c0-z0);
+ double a=dy*t3.getx()-dx*t3.gety();
+ double b=dy*t2.getx()-dx*t2.gety();
+ double c=dy*t1.getx()-dx*t1.gety();
+ double d=dy*z0.getx()-dx*z0.gety()+det;
+ std::vector<double> r;
+ if(max(max(max(a*a,b*b),c*c),d*d) >
+ Fuzz2*max(max(max(z0.abs2(),z1.abs2()),c0.abs2()),c1.abs2()))
+ roots(r,a,b,c,d);
+ else r.push_back(0.0);
+ if(endpoints) {
+ path h=g.subpath(i,i+1);
+ intersections(r,h,p,fuzz);
+ intersections(r,h,q,fuzz);
+ if(online(p,q,z0,fuzz)) r.push_back(0.0);
+ if(online(p,q,z1,fuzz)) r.push_back(1.0);
+ }
+ size_t m=r.size();
+ for(size_t j=0 ; j < m; ++j) {
+ double t=r[j];
+ if(t >= -Fuzz && t <= 1.0+Fuzz) {
+ double s=i+t;
+ if(cycles && s >= n-Fuzz) s=0;
+ T.push_back(s);
+ }
+ }
+ }
+}
+
+// An optimized implementation of intersections(g,p--q);
+// if there are an infinite number of intersection points, the returned list is
+// only guaranteed to include the endpoint times of the intersection.
+void intersections(std::vector<double>& S, std::vector<double>& T,
+ const path& g, const pair& p, const pair& q, double fuzz)
+{
+ if(q == p) {
+ std::vector<double> S1;
+ intersections(S1,g,p,fuzz);
+ size_t n=S1.size();
+ for(size_t i=0; i < n; ++i) {
+ S.push_back(S1[i]);
+ T.push_back(0);
+ }
+ } else {
+ pair factor=(q-p)/((q-p).abs2());
+ std::vector<double> S1;
+ lineintersections(S1,g,p,q,fuzz,true);
+ size_t n=S1.size();
+ for(size_t i=0; i < n; ++i) {
+ double s=S1[i];
+ pair z=g.point(s);
+ double t=dot(g.point(s)-p,factor);
+ if(t >= -Fuzz && t <= 1.0+Fuzz) {
+ S.push_back(s);
+ T.push_back(t);
+ }
+ }
+ }
+}
+
+void add(std::vector<double>& S, double s, const path& p, double fuzz2)
+{
+ pair P=p.point(s);
+ for(size_t i=0; i < S.size(); ++i)
+ if((p.point(S[i])-P).abs2() <= fuzz2) return;
+ S.push_back(s);
+}
+
+void add(std::vector<double>& S, std::vector<double>& T, double s, double t,
+ const path& p, const path& q, double fuzz2)
+{
+ pair P=p.point(s);
+ for(size_t i=0; i < S.size(); ++i)
+ if((p.point(S[i])-P).abs2() <= fuzz2) return;
+ S.push_back(s);
+ T.push_back(t);
+}
+
+void add(double& s, double& t, std::vector<double>& S, std::vector<double>& T,
+ std::vector<double>& S1, std::vector<double>& T1,
+ double pscale, double qscale, double poffset, double qoffset,
+ const path& p, const path& q, double fuzz, bool single)
+{
+ if(single) {
+ s=s*pscale+poffset;
+ t=t*qscale+qoffset;
+ } else {
+ double fuzz2=4.0*fuzz*fuzz;
+ size_t n=S1.size();
+ for(size_t i=0; i < n; ++i)
+ add(S,T,pscale*S1[i]+poffset,qscale*T1[i]+qoffset,p,q,fuzz2);
+ }
+}
+
+void add(double& s, double& t, std::vector<double>& S, std::vector<double>& T,
+ std::vector<double>& S1, std::vector<double>& T1,
+ const path& p, const path& q, double fuzz, bool single)
+{
+ size_t n=S1.size();
+ if(single) {
+ if(n > 0) {
+ s=S1[0];
+ t=T1[0];
+ }
+ } else {
+ double fuzz2=4.0*fuzz*fuzz;
+ for(size_t i=0; i < n; ++i)
+ add(S,T,S1[i],T1[i],p,q,fuzz2);
+ }
+}
+
+void intersections(std::vector<double>& S, path& g,
+ const pair& p, const pair& q, double fuzz)
+{
+ double fuzz2=fuzz*fuzz;
+ std::vector<double> S1;
+ lineintersections(S1,g,p,q,fuzz);
+ size_t n=S1.size();
+ for(size_t i=0; i < n; ++i)
+ add(S,S1[i],g,fuzz2);
+}
+
+bool intersections(double &s, double &t, std::vector<double>& S,
+ std::vector<double>& T, path& p, path& q,
+ double fuzz, bool single, bool exact, unsigned depth)
+{
+ if(errorstream::interrupt) throw interrupted();
+
+ Int lp=p.length();
+ if(((lp == 1 && p.straight(0)) || lp == 0) && exact) {
+ std::vector<double> T1,S1;
+ intersections(T1,S1,q,p.point((Int) 0),p.point(lp),fuzz);
+ add(s,t,S,T,S1,T1,p,q,fuzz,single);
+ return S1.size() > 0;
+ }
+
+ Int lq=q.length();
+ if(((lq == 1 && q.straight(0)) || lq == 0) && exact) {
+ std::vector<double> S1,T1;
+ intersections(S1,T1,p,q.point((Int) 0),q.point(lq),fuzz);
+ add(s,t,S,T,S1,T1,p,q,fuzz,single);
+ return S1.size() > 0;
+ }
+
+ pair maxp=p.max();
+ pair minp=p.min();
+ pair maxq=q.max();
+ pair minq=q.min();
+
+ if(maxp.getx()+fuzz >= minq.getx() &&
+ maxp.gety()+fuzz >= minq.gety() &&
+ maxq.getx()+fuzz >= minp.getx() &&
+ maxq.gety()+fuzz >= minp.gety()) {
+ // Overlapping bounding boxes
+
+ --depth;
+ if((maxp-minp).length()+(maxq-minq).length() <= fuzz || depth == 0) {
+ if(single) {
+ s=0;
+ t=0;
+ } else {
+ S.push_back(0.0);
+ T.push_back(0.0);
+ }
+ return true;
+ }
+
+ path p1,p2;
+ double pscale,poffset;
+
+ if(lp <= 1) {
+ if(lp == 1) p.halve(p1,p2);
+ if(lp == 0 || p1 == p || p2 == p) {
+ std::vector<double> T1,S1;
+ intersections(T1,S1,q,p.point((Int) 0),p.point((Int) 0),fuzz);
+ add(s,t,S,T,S1,T1,p,q,fuzz,single);
+ return S1.size() > 0;
+ }
+ pscale=poffset=0.5;
+ } else {
+ Int tp=lp/2;
+ p1=p.subpath(0,tp);
+ p2=p.subpath(tp,lp);
+ poffset=tp;
+ pscale=1.0;
+ }
+
+ path q1,q2;
+ double qscale,qoffset;
+
+ if(lq <= 1) {
+ if(lq == 1) q.halve(q1,q2);
+ if(lq == 0 || q1 == q || q2 == q) {
+ std::vector<double> S1,T1;
+ intersections(S1,T1,p,q.point((Int) 0),q.point((Int) 0),fuzz);
+ add(s,t,S,T,S1,T1,p,q,fuzz,single);
+ return S1.size() > 0;
+ }
+ qscale=qoffset=0.5;
+ } else {
+ Int tq=lq/2;
+ q1=q.subpath(0,tq);
+ q2=q.subpath(tq,lq);
+ qoffset=tq;
+ qscale=1.0;
+ }
+
+ bool Short=lp == 1 && lq == 1;
+
+ static size_t maxcount=9;
+ size_t count=0;
+
+ std::vector<double> S1,T1;
+ if(intersections(s,t,S1,T1,p1,q1,fuzz,single,exact,depth)) {
+ add(s,t,S,T,S1,T1,pscale,qscale,0.0,0.0,p,q,fuzz,single);
+ if(single || depth <= mindepth)
+ return true;
+ count += S1.size();
+ if(Short && count > maxcount) return true;
+ }
+
+ S1.clear();
+ T1.clear();
+ if(intersections(s,t,S1,T1,p1,q2,fuzz,single,exact,depth)) {
+ add(s,t,S,T,S1,T1,pscale,qscale,0.0,qoffset,p,q,fuzz,single);
+ if(single || depth <= mindepth)
+ return true;
+ count += S1.size();
+ if(Short && count > maxcount) return true;
+ }
+
+ S1.clear();
+ T1.clear();
+ if(intersections(s,t,S1,T1,p2,q1,fuzz,single,exact,depth)) {
+ add(s,t,S,T,S1,T1,pscale,qscale,poffset,0.0,p,q,fuzz,single);
+ if(single || depth <= mindepth)
+ return true;
+ count += S1.size();
+ if(Short && count > maxcount) return true;
+ }
+
+ S1.clear();
+ T1.clear();
+ if(intersections(s,t,S1,T1,p2,q2,fuzz,single,exact,depth)) {
+ add(s,t,S,T,S1,T1,pscale,qscale,poffset,qoffset,p,q,fuzz,single);
+ if(single || depth <= mindepth)
+ return true;
+ count += S1.size();
+ if(Short && count > maxcount) return true;
+ }
+
+ return S.size() > 0;
+ }
+ return false;
+}
+
+// }}}
+
+ostream& operator<< (ostream& out, const path& p)
+{
+ Int n = p.length();
+ if(n < 0)
+ out << "<nullpath>";
+ else {
+ for(Int i = 0; i < n; i++) {
+ out << p.point(i);
+ if(p.straight(i)) out << "--";
+ else
+ out << ".. controls " << p.postcontrol(i) << " and "
+ << p.precontrol(i+1) << newl << " ..";
+ }
+ if(p.cycles)
+ out << "cycle";
+ else
+ out << p.point(n);
+ }
+ return out;
+}
+
+path concat(const path& p1, const path& p2)
+{
+ Int n1 = p1.length(), n2 = p2.length();
+
+ if (n1 == -1) return p2;
+ if (n2 == -1) return p1;
+ pair a=p1.point(n1);
+ pair b=p2.point((Int) 0);
+
+ mem::vector<solvedKnot> nodes(n1+n2+1);
+
+ Int i = 0;
+ nodes[0].pre = p1.point((Int) 0);
+ for (Int j = 0; j < n1; j++) {
+ nodes[i].point = p1.point(j);
+ nodes[i].straight = p1.straight(j);
+ nodes[i].post = p1.postcontrol(j);
+ nodes[i+1].pre = p1.precontrol(j+1);
+ i++;
+ }
+ for (Int j = 0; j < n2; j++) {
+ nodes[i].point = p2.point(j);
+ nodes[i].straight = p2.straight(j);
+ nodes[i].post = p2.postcontrol(j);
+ nodes[i+1].pre = p2.precontrol(j+1);
+ i++;
+ }
+ nodes[i].point = nodes[i].post = p2.point(n2);
+
+ return path(nodes, i+1);
+}
+
+// Interface to orient2d predicate optimized for pairs.
+double orient2d(const pair& a, const pair& b, const pair& c)
+{
+ double detleft, detright, det;
+ double detsum, errbound;
+ double orient;
+
+ FPU_ROUND_DOUBLE;
+
+ detleft = (a.getx() - c.getx()) * (b.gety() - c.gety());
+ detright = (a.gety() - c.gety()) * (b.getx() - c.getx());
+ det = detleft - detright;
+
+ if (detleft > 0.0) {
+ if (detright <= 0.0) {
+ FPU_RESTORE;
+ return det;
+ } else {
+ detsum = detleft + detright;
+ }
+ } else if (detleft < 0.0) {
+ if (detright >= 0.0) {
+ FPU_RESTORE;
+ return det;
+ } else {
+ detsum = -detleft - detright;
+ }
+ } else {
+ FPU_RESTORE;
+ return det;
+ }
+
+ errbound = ccwerrboundA * detsum;
+ if ((det >= errbound) || (-det >= errbound)) {
+ FPU_RESTORE;
+ return det;
+ }
+
+ double pa[]={a.getx(),a.gety()};
+ double pb[]={b.getx(),b.gety()};
+ double pc[]={c.getx(),c.gety()};
+
+ orient = orient2dadapt(pa, pb, pc, detsum);
+ FPU_RESTORE;
+ return orient;
+}
+
+// Returns true iff the point z lies in or on the bounding box
+// of a,b,c, and d.
+bool insidebbox(const pair& a, const pair& b, const pair& c, const pair& d,
+ const pair& z)
+{
+ bbox B(a);
+ B.addnonempty(b);
+ B.addnonempty(c);
+ B.addnonempty(d);
+ return B.left <= z.getx() && z.getx() <= B.right && B.bottom <= z.gety()
+ && z.gety() <= B.top;
+}
+
+inline bool inrange(double x0, double x1, double x)
+{
+ return (x0 <= x && x <= x1) || (x1 <= x && x <= x0);
+}
+
+// Return true if point z is on z0--z1; otherwise compute contribution to
+// winding number.
+bool checkstraight(const pair& z0, const pair& z1, const pair& z, Int& count)
+{
+ if(z0.gety() <= z.gety() && z.gety() <= z1.gety()) {
+ double side=orient2d(z0,z1,z);
+ if(side == 0.0 && inrange(z0.getx(),z1.getx(),z.getx()))
+ return true;
+ if(z.gety() < z1.gety() && side > 0) ++count;
+ } else if(z1.gety() <= z.gety() && z.gety() <= z0.gety()) {
+ double side=orient2d(z0,z1,z);
+ if(side == 0.0 && inrange(z0.getx(),z1.getx(),z.getx()))
+ return true;
+ if(z.gety() < z0.gety() && side < 0) --count;
+ }
+ return false;
+}
+
+// returns true if point is on curve; otherwise compute contribution to
+// winding number.
+bool checkcurve(const pair& z0, const pair& c0, const pair& c1,
+ const pair& z1, const pair& z, Int& count, unsigned depth)
+{
+ if(depth == 0) return true;
+ --depth;
+ if(insidebbox(z0,c0,c1,z1,z)) {
+ const pair m0=0.5*(z0+c0);
+ const pair m1=0.5*(c0+c1);
+ const pair m2=0.5*(c1+z1);
+ const pair m3=0.5*(m0+m1);
+ const pair m4=0.5*(m1+m2);
+ const pair m5=0.5*(m3+m4);
+ if(checkcurve(z0,m0,m3,m5,z,count,depth) ||
+ checkcurve(m5,m4,m2,z1,z,count,depth)) return true;
+ } else
+ if(checkstraight(z0,z1,z,count)) return true;
+ return false;
+}
+
+// Return the winding number of the region bounded by the (cyclic) path
+// relative to the point z, or the largest odd integer if the point lies on
+// the path.
+Int path::windingnumber(const pair& z) const
+{
+ static const Int undefined=Int_MAX+((Int_MAX % 2)-1);;
+
+ if(!cycles)
+ reportError("path is not cyclic");
+
+ bbox b=bounds();
+
+ if(z.getx() < b.left || z.getx() > b.right ||
+ z.gety() < b.bottom || z.gety() > b.top) return 0;
+
+ Int count=0;
+ for(Int i=0; i < n; ++i)
+ if(straight(i)) {
+ if(checkstraight(point(i),point(i+1),z,count))
+ return undefined;
+ } else
+ if(checkcurve(point(i),postcontrol(i),precontrol(i+1),point(i+1),z,count,
+ maxdepth)) return undefined;
+ return count;
+}
+
+path path::transformed(const transform& t) const
+{
+ mem::vector<solvedKnot> nodes(n);
+
+ for (Int i = 0; i < n; ++i) {
+ nodes[i].pre = t * this->nodes[i].pre;
+ nodes[i].point = t * this->nodes[i].point;
+ nodes[i].post = t * this->nodes[i].post;
+ nodes[i].straight = this->nodes[i].straight;
+ }
+
+ path p(nodes, n, cyclic());
+ return p;
+}
+
+path transformed(const transform& t, const path& p)
+{
+ Int n = p.size();
+ mem::vector<solvedKnot> nodes(n);
+
+ for (Int i = 0; i < n; ++i) {
+ nodes[i].pre = t * p.precontrol(i);
+ nodes[i].point = t * p.point(i);
+ nodes[i].post = t * p.postcontrol(i);
+ nodes[i].straight = p.straight(i);
+ }
+
+ return path(nodes, n, p.cyclic());
+}
+
+path nurb(pair z0, pair z1, pair z2, pair z3,
+ double w0, double w1, double w2, double w3, Int m)
+{
+ mem::vector<solvedKnot> nodes(m+1);
+
+ if(m < 1) reportError("invalid sampling interval");
+
+ double step=1.0/m;
+ for(Int i=0; i <= m; ++i) {
+ double t=i*step;
+ double t2=t*t;
+ double onemt=1.0-t;
+ double onemt2=onemt*onemt;
+ double W0=w0*onemt2*onemt;
+ double W1=w1*3.0*t*onemt2;
+ double W2=w2*3.0*t2*onemt;
+ double W3=w3*t2*t;
+ nodes[i].point=(W0*z0+W1*z1+W2*z2+W3*z3)/(W0+W1+W2+W3);
+ }
+
+ static const double twothirds=2.0/3.0;
+ pair z=nodes[0].point;
+ nodes[0].pre=z;
+ nodes[0].post=twothirds*z+third*nodes[1].point;
+ for(int i=1; i < m; ++i) {
+ pair z0=nodes[i].point;
+ pair zm=nodes[i-1].point;
+ pair zp=nodes[i+1].point;
+ pair pre=twothirds*z0+third*zm;
+ pair pos=twothirds*z0+third*zp;
+ pair dir=unit(pos-pre);
+ nodes[i].pre=z0-length(z0-pre)*dir;
+ nodes[i].post=z0+length(pos-z0)*dir;
+ }
+ z=nodes[m].point;
+ nodes[m].pre=twothirds*z+third*nodes[m-1].point;
+ nodes[m].post=z;
+ return path(nodes,m+1);
+}
+
+} //namespace camp
diff --git a/Build/source/utils/asymptote/path.h b/Build/source/utils/asymptote/path.h
new file mode 100644
index 00000000000..1b31408c4a1
--- /dev/null
+++ b/Build/source/utils/asymptote/path.h
@@ -0,0 +1,456 @@
+/*****
+ * path.h
+ * Andy Hammerlindl 2002/05/16
+ *
+ * Stores a piecewise cubic spline with known control points.
+ *
+ * When changing the path algorithms, also update the corresponding
+ * three-dimensional algorithms in path3.cc and three.asy.
+ *****/
+
+#ifndef PATH_H
+#define PATH_H
+
+#include <cfloat>
+
+#include "mod.h"
+#include "pair.h"
+#include "transform.h"
+#include "bbox.h"
+
+inline double Intcap(double t) {
+ if(t <= Int_MIN) return Int_MIN;
+ if(t >= Int_MAX) return Int_MAX;
+ return t;
+}
+
+// The are like floor and ceil, except they return an integer;
+// if the argument cannot be converted to a valid integer, they return
+// Int_MAX (for positive arguments) or Int_MIN (for negative arguments).
+
+inline Int Floor(double t) {return (Int) floor(Intcap(t));}
+inline Int Ceil(double t) {return (Int) ceil(Intcap(t));}
+
+bool simpson(double& integral, double (*)(double), double a, double b,
+ double acc, double dxmax);
+
+bool unsimpson(double integral, double (*)(double), double a, double& b,
+ double acc, double& area, double dxmax, double dxmin=0);
+
+namespace camp {
+
+void checkEmpty(Int n);
+
+inline Int adjustedIndex(Int i, Int n, bool cycles)
+{
+ checkEmpty(n);
+ if(cycles)
+ return imod(i,n);
+ else if(i < 0)
+ return 0;
+ else if(i >= n)
+ return n-1;
+ else
+ return i;
+}
+
+// Used in the storage of solved path knots.
+struct solvedKnot : public gc {
+ pair pre;
+ pair point;
+ pair post;
+ bool straight;
+ solvedKnot() : straight(false) {}
+
+ friend bool operator== (const solvedKnot& p, const solvedKnot& q)
+ {
+ return p.pre == q.pre && p.point == q.point && p.post == q.post;
+ }
+};
+
+extern const double BigFuzz;
+extern const double Fuzz;
+extern const double Fuzz2;
+extern const double sqrtFuzz;
+
+class path : public gc {
+ bool cycles; // If the path is closed in a loop
+
+ Int n; // The number of knots
+
+ mem::vector<solvedKnot> nodes;
+ mutable double cached_length; // Cache length since path is immutable.
+
+ mutable bbox box;
+ mutable bbox times; // Times where minimum and maximum extents are attained.
+
+public:
+ path()
+ : cycles(false), n(0), nodes(), cached_length(-1) {}
+
+ // Create a path of a single point
+ path(pair z, bool = false)
+ : cycles(false), n(1), nodes(1), cached_length(-1)
+ {
+ nodes[0].pre = nodes[0].point = nodes[0].post = z;
+ nodes[0].straight = false;
+ }
+
+ // Creates path from a list of knots. This will be used by camp
+ // methods such as the guide solver, but should probably not be used by a
+ // user of the system unless he knows what he is doing.
+ path(mem::vector<solvedKnot>& nodes, Int n, bool cycles = false)
+ : cycles(cycles), n(n), nodes(nodes), cached_length(-1)
+ {
+ }
+
+ friend bool operator== (const path& p, const path& q)
+ {
+ return p.cycles == q.cycles && p.nodes == q.nodes;
+ }
+
+public:
+ path(solvedKnot n1, solvedKnot n2)
+ : cycles(false), n(2), nodes(2), cached_length(-1)
+ {
+ nodes[0] = n1;
+ nodes[1] = n2;
+ nodes[0].pre = nodes[0].point;
+ nodes[1].post = nodes[1].point;
+ }
+
+ // Copy constructor
+ path(const path& p)
+ : cycles(p.cycles), n(p.n), nodes(p.nodes), cached_length(p.cached_length),
+ box(p.box)
+ {}
+
+ path unstraighten() const
+ {
+ path P=path(*this);
+ for(int i=0; i < n; ++i)
+ P.nodes[i].straight=false;
+ return P;
+ }
+
+ virtual ~path()
+ {
+ }
+
+ // Getting control points
+ Int size() const
+ {
+ return n;
+ }
+
+ bool empty() const
+ {
+ return n == 0;
+ }
+
+ Int length() const
+ {
+ return cycles ? n : n-1;
+ }
+
+ bool cyclic() const
+ {
+ return cycles;
+ }
+
+ mem::vector<solvedKnot>& Nodes() {
+ return nodes;
+ }
+
+ bool straight(Int t) const
+ {
+ if (cycles) return nodes[imod(t,n)].straight;
+ return (t >= 0 && t < n) ? nodes[t].straight : false;
+ }
+
+ bool piecewisestraight() const
+ {
+ Int L=length();
+ for(Int i=0; i < L; ++i)
+ if(!straight(i)) return false;
+ return true;
+ }
+
+ pair point(Int t) const
+ {
+ return nodes[adjustedIndex(t,n,cycles)].point;
+ }
+
+ pair point(double t) const;
+
+ pair precontrol(Int t) const
+ {
+ return nodes[adjustedIndex(t,n,cycles)].pre;
+ }
+
+ pair precontrol(double t) const;
+
+ pair postcontrol(Int t) const
+ {
+ return nodes[adjustedIndex(t,n,cycles)].post;
+ }
+
+ pair postcontrol(double t) const;
+
+ inline double norm(const pair& z0, const pair& c0, const pair& c1,
+ const pair& z1) const {
+ return Fuzz2*camp::max((c0-z0).abs2(),
+ camp::max((c1-z0).abs2(),(z1-z0).abs2()));
+ }
+
+ pair predir(Int t, bool normalize=true) const {
+ if(!cycles && t <= 0) return pair(0,0);
+ pair z1=point(t);
+ pair c1=precontrol(t);
+ pair dir=3.0*(z1-c1);
+ if(!normalize) return dir;
+ pair z0=point(t-1);
+ pair c0=postcontrol(t-1);
+ double epsilon=norm(z0,c0,c1,z1);
+ if(dir.abs2() > epsilon) return unit(dir);
+ dir=2.0*c1-c0-z1;
+ if(dir.abs2() > epsilon) return unit(dir);
+ return unit(z1-z0+3.0*(c0-c1));
+ }
+
+ pair postdir(Int t, bool normalize=true) const {
+ if(!cycles && t >= n-1) return pair(0,0);
+ pair c0=postcontrol(t);
+ pair z0=point(t);
+ pair dir=3.0*(c0-z0);
+ if(!normalize) return dir;
+ pair z1=point(t+1);
+ pair c1=precontrol(t+1);
+ double epsilon=norm(z0,c0,c1,z1);
+ if(dir.abs2() > epsilon) return unit(dir);
+ dir=z0-2.0*c0+c1;
+ if(dir.abs2() > epsilon) return unit(dir);
+ return unit(z1-z0+3.0*(c0-c1));
+ }
+
+ pair dir(Int t, Int sign, bool normalize=true) const {
+ if(sign == 0) {
+ pair v=predir(t,normalize)+postdir(t,normalize);
+ return normalize ? unit(v) : 0.5*v;
+ }
+ if(sign > 0) return postdir(t,normalize);
+ return predir(t,normalize);
+ }
+
+ pair dir(double t, bool normalize=true) const {
+ if(!cycles) {
+ if(t <= 0) return postdir((Int) 0,normalize);
+ if(t >= n-1) return predir(n-1,normalize);
+ }
+ Int i=Floor(t);
+ t -= i;
+ if(t == 0) return dir(i,0);
+ pair z0=point(i);
+ pair c0=postcontrol(i);
+ pair c1=precontrol(i+1);
+ pair z1=point(i+1);
+ pair a=3.0*(z1-z0)+9.0*(c0-c1);
+ pair b=6.0*(z0+c1)-12.0*c0;
+ pair c=3.0*(c0-z0);
+ pair dir=a*t*t+b*t+c;
+ if(!normalize) return dir;
+ double epsilon=norm(z0,c0,c1,z1);
+ if(dir.abs2() > epsilon) return unit(dir);
+ dir=2.0*a*t+b;
+ if(dir.abs2() > epsilon) return unit(dir);
+ return unit(a);
+ }
+
+ pair postaccel(Int t) const {
+ if(!cycles && t >= n-1) return pair(0,0);
+ pair z0=point(t);
+ pair c0=postcontrol(t);
+ pair c1=precontrol(t+1);
+ return 6.0*(z0+c1)-12.0*c0;
+ }
+
+ pair preaccel(Int t) const {
+ if(!cycles && t <= 0) return pair(0,0);
+ pair z0=point(t-1);
+ pair c0=postcontrol(t-1);
+ pair c1=precontrol(t);
+ pair z1=point(t);
+ return 6.0*(z1+c0)-12.0*c1;
+ }
+
+ pair accel(Int t, Int sign) const {
+ if(sign == 0) return 0.5*(preaccel(t)+postaccel(t));
+ if(sign > 0) return postaccel(t);
+ return preaccel(t);
+ }
+
+ pair accel(double t) const {
+ if(!cycles) {
+ if(t <= 0) return postaccel((Int) 0);
+ if(t >= n-1) return preaccel(n-1);
+ }
+ Int i=Floor(t);
+ t -= i;
+ if(t == 0) return 0.5*(postaccel(i)+preaccel(i));
+ pair z0=point(i);
+ pair c0=postcontrol(i);
+ pair c1=precontrol(i+1);
+ pair z1=point(i+1);
+ return 6.0*t*(z1-z0+3.0*(c0-c1))+6.0*(z0+c1)-12.0*c0;
+ }
+
+ // Returns the path traced out in reverse.
+ path reverse() const;
+
+ // Generates a path that is a section of the old path, using the time
+ // interval given.
+ path subpath(Int start, Int end) const;
+ path subpath(double start, double end) const;
+
+ // Special case of subpath used by intersect.
+ void halve(path &first, path &second) const;
+
+ // Used by picture to determine bounding box.
+ bbox bounds() const;
+
+ pair mintimes() const {
+ checkEmpty(n);
+ bounds();
+ return camp::pair(times.left,times.bottom);
+ }
+
+ pair maxtimes() const {
+ checkEmpty(n);
+ bounds();
+ return camp::pair(times.right,times.top);
+ }
+
+ template<class T>
+ void addpoint(bbox& box, T i) const {
+ box.addnonempty(point(i),times,(double) i);
+ }
+
+ template<class T>
+ void addpoint(bbox& box, T i, double min, double max) const {
+ static const pair I(0,1);
+ pair v=I*dir(i);
+ pair z=point(i);
+ box.add(z+min*v);
+ box.addnonempty(z+max*v);
+ }
+
+ // Return bounding box accounting for padding perpendicular to path.
+ bbox bounds(double min, double max) const;
+
+ // Return bounding box accounting for internal pen padding (but not pencap).
+ bbox internalbounds(const bbox &padding) const;
+
+ double cubiclength(Int i, double goal=-1) const;
+ double arclength () const;
+ double arctime (double l) const;
+ double directiontime(const pair& z) const;
+
+ pair max() const {
+ checkEmpty(n);
+ return bounds().Max();
+ }
+
+ pair min() const {
+ checkEmpty(n);
+ return bounds().Min();
+ }
+
+ // Debugging output
+ friend std::ostream& operator<< (std::ostream& out, const path& p);
+
+// Increment count if the path has a vertical component at t.
+ bool Count(Int& count, double t) const;
+
+// Count if t is in (begin,end] and z lies to the left of point(i+t).
+ void countleft(Int& count, double x, Int i, double t,
+ double begin, double end, double& mint, double& maxt) const;
+
+// Return the winding number of the region bounded by the (cyclic) path
+// relative to the point z.
+ Int windingnumber(const pair& z) const;
+
+ // Transformation
+ path transformed(const transform& t) const;
+
+};
+
+extern path nullpath;
+extern const unsigned maxdepth;
+extern const unsigned mindepth;
+
+bool intersect(double& S, double& T, path& p, path& q, double fuzz,
+ unsigned depth=maxdepth);
+bool intersections(double& s, double& t, std::vector<double>& S,
+ std::vector<double>& T, path& p, path& q,
+ double fuzz, bool single, bool exact,
+ unsigned depth=maxdepth);
+void intersections(std::vector<double>& S, path& g,
+ const pair& p, const pair& q, double fuzz);
+
+
+// Concatenates two paths into a new one.
+path concat(const path& p1, const path& p2);
+
+// Applies a transformation to the path
+path transformed(const transform& t, const path& p);
+
+inline double quadratic(double a, double b, double c, double x)
+{
+ return a*x*x+b*x+c;
+}
+
+class quadraticroots {
+public:
+ enum {NONE=0, ONE=1, TWO=2, MANY} distinct; // Number of distinct real roots.
+ unsigned roots; // Total number of real roots.
+ double t1,t2; // Real roots
+
+ quadraticroots(double a, double b, double c);
+};
+
+class Quadraticroots {
+public:
+ unsigned roots; // Total number of roots.
+ pair z1,z2; // Complex roots
+ Quadraticroots(pair a, pair b, pair c);
+};
+
+class cubicroots {
+public:
+ unsigned roots; // Total number of real roots.
+ double t1,t2,t3;
+ cubicroots(double a, double b, double c, double d);
+};
+
+path nurb(pair z0, pair z1, pair z2, pair z3,
+ double w0, double w1, double w2, double w3, Int m);
+
+double orient2d(const pair& a, const pair& b, const pair& c);
+
+void roots(std::vector<double> &roots, double a, double b, double c, double d);
+void roots(std::vector<double> &r, double x0, double c0, double c1, double x1,
+ double x);
+
+inline bool goodroot(double t)
+{
+ return 0.0 <= t && t <= 1.0;
+}
+
+extern const double third;
+
+}
+
+// Delete the following line to work around problems with old broken compilers.
+GC_DECLARE_PTRFREE(camp::solvedKnot);
+
+#endif
diff --git a/Build/source/utils/asymptote/path3.cc b/Build/source/utils/asymptote/path3.cc
new file mode 100644
index 00000000000..7cfa16647d5
--- /dev/null
+++ b/Build/source/utils/asymptote/path3.cc
@@ -0,0 +1,914 @@
+/*****
+ * path3.cc
+ * John Bowman
+ *
+ * Compute information for a three-dimensional path.
+ *****/
+
+#include <cfloat>
+
+#include "path3.h"
+#include "util.h"
+#include "camperror.h"
+#include "mathop.h"
+
+namespace camp {
+
+using run::operator *;
+using vm::array;
+
+path3 nullpath3;
+
+void checkEmpty3(Int n) {
+ if(n == 0)
+ reportError("nullpath3 has no points");
+}
+
+double bound(triple z0, triple c0, triple c1, triple z1,
+ double (*m)(double, double),
+ double (*f)(const triple&, double*), double *t,
+ double b, int depth)
+{
+ b=m(b,m(f(z0,t),f(z1,t)));
+ if(m(-1.0,1.0)*(b-m(f(c0,t),f(c1,t))) >= -sqrtFuzz || depth == 0)
+ return b;
+ --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);
+
+ // Check both Bezier subpaths.
+ b=bound(z0,m0,m3,m5,m,f,t,b,depth);
+ return bound(m5,m4,m2,z1,m,f,t,b,depth);
+}
+
+triple path3::point(double t) const
+{
+ checkEmpty3(n);
+
+ Int i = Floor(t);
+ Int iplus;
+ t = fmod(t,1);
+ if (t < 0) t += 1;
+
+ if (cycles) {
+ i = imod(i,n);
+ iplus = imod(i+1,n);
+ }
+ else if (i < 0)
+ return nodes[0].point;
+ else if (i >= n-1)
+ return nodes[n-1].point;
+ else
+ iplus = i+1;
+
+ double one_t = 1.0-t;
+
+ triple a = nodes[i].point,
+ b = nodes[i].post,
+ c = nodes[iplus].pre,
+ d = nodes[iplus].point,
+ ab = one_t*a + t*b,
+ bc = one_t*b + t*c,
+ cd = one_t*c + t*d,
+ abc = one_t*ab + t*bc,
+ bcd = one_t*bc + t*cd,
+ abcd = one_t*abc + t*bcd;
+
+ return abcd;
+}
+
+triple path3::precontrol(double t) const
+{
+ checkEmpty3(n);
+
+ Int i = Floor(t);
+ Int iplus;
+ t = fmod(t,1);
+ if (t < 0) t += 1;
+
+ if (cycles) {
+ i = imod(i,n);
+ iplus = imod(i+1,n);
+ }
+ else if (i < 0)
+ return nodes[0].pre;
+ else if (i >= n-1)
+ return nodes[n-1].pre;
+ else
+ iplus = i+1;
+
+ double one_t = 1.0-t;
+
+ triple a = nodes[i].point,
+ b = nodes[i].post,
+ c = nodes[iplus].pre,
+ ab = one_t*a + t*b,
+ bc = one_t*b + t*c,
+ abc = one_t*ab + t*bc;
+
+ return (abc == a) ? nodes[i].pre : abc;
+}
+
+
+triple path3::postcontrol(double t) const
+{
+ checkEmpty3(n);
+
+ Int i = Floor(t);
+ Int iplus;
+ t = fmod(t,1);
+ if (t < 0) t += 1;
+
+ if (cycles) {
+ i = imod(i,n);
+ iplus = imod(i+1,n);
+ }
+ else if (i < 0)
+ return nodes[0].post;
+ else if (i >= n-1)
+ return nodes[n-1].post;
+ else
+ iplus = i+1;
+
+ double one_t = 1.0-t;
+
+ triple b = nodes[i].post,
+ c = nodes[iplus].pre,
+ d = nodes[iplus].point,
+ bc = one_t*b + t*c,
+ cd = one_t*c + t*d,
+ bcd = one_t*bc + t*cd;
+
+ return (bcd == d) ? nodes[iplus].post : bcd;
+}
+
+path3 path3::reverse() const
+{
+ mem::vector<solvedKnot3> nodes(n);
+ Int len=length();
+ for (Int i = 0, j = len; i < n; i++, j--) {
+ nodes[i].pre = postcontrol(j);
+ nodes[i].point = point(j);
+ nodes[i].post = precontrol(j);
+ nodes[i].straight = straight(j-1);
+ }
+ return path3(nodes, n, cycles);
+}
+
+path3 path3::subpath(Int a, Int b) const
+{
+ if(empty()) return path3();
+
+ if (a > b) {
+ const path3 &rp = reverse();
+ Int len=length();
+ path3 result = rp.subpath(len-a, len-b);
+ return result;
+ }
+
+ if (!cycles) {
+ if (a < 0)
+ a = 0;
+ if (b > n-1)
+ b = n-1;
+ }
+
+ Int sn = b-a+1;
+ mem::vector<solvedKnot3> nodes(sn);
+
+ for (Int i = 0, j = a; j <= b; i++, j++) {
+ nodes[i].pre = precontrol(j);
+ nodes[i].point = point(j);
+ nodes[i].post = postcontrol(j);
+ nodes[i].straight = straight(j);
+ }
+ nodes[0].pre = nodes[0].point;
+ nodes[sn-1].post = nodes[sn-1].point;
+
+ return path3(nodes, sn);
+}
+
+inline triple split(double t, const triple& x, const triple& y) {
+ return x+(y-x)*t;
+}
+
+inline void splitCubic(solvedKnot3 sn[], double t, const solvedKnot3& left_,
+ const solvedKnot3& right_)
+{
+ solvedKnot3 &left=(sn[0]=left_), &mid=sn[1], &right=(sn[2]=right_);
+ if(left.straight) {
+ mid.point=split(t,left.point,right.point);
+ triple deltaL=third*(mid.point-left.point);
+ left.post=left.point+deltaL;
+ mid.pre=mid.point-deltaL;
+ triple deltaR=third*(right.point-mid.point);
+ mid.post=mid.point+deltaR;
+ right.pre=right.point-deltaR;
+ mid.straight=true;
+ } else {
+ triple x=split(t,left.post,right.pre); // m1
+ left.post=split(t,left.point,left.post); // m0
+ right.pre=split(t,right.pre,right.point); // m2
+ mid.pre=split(t,left.post,x); // m3
+ mid.post=split(t,x,right.pre); // m4
+ mid.point=split(t,mid.pre,mid.post); // m5
+ }
+}
+
+path3 path3::subpath(double a, double b) const
+{
+ if(empty()) return path3();
+
+ if (a > b) {
+ const path3 &rp = reverse();
+ Int len=length();
+ return rp.subpath(len-a, len-b);
+ }
+
+ solvedKnot3 aL, aR, bL, bR;
+ if (!cycles) {
+ if (a < 0) {
+ a = 0;
+ if (b < 0)
+ b = 0;
+ }
+ if (b > n-1) {
+ b = n-1;
+ if (a > n-1)
+ a = n-1;
+ }
+ aL = nodes[(Int)floor(a)];
+ aR = nodes[(Int)ceil(a)];
+ bL = nodes[(Int)floor(b)];
+ bR = nodes[(Int)ceil(b)];
+ } else {
+ if(run::validInt(a) && run::validInt(b)) {
+ aL = nodes[imod((Int) floor(a),n)];
+ aR = nodes[imod((Int) ceil(a),n)];
+ bL = nodes[imod((Int) floor(b),n)];
+ bR = nodes[imod((Int) ceil(b),n)];
+ } else reportError("invalid path3 index");
+ }
+
+ if (a == b) return path3(point(a));
+
+ solvedKnot3 sn[3];
+ path3 p = subpath(Ceil(a), Floor(b));
+ if (a > floor(a)) {
+ if (b < ceil(a)) {
+ splitCubic(sn,a-floor(a),aL,aR);
+ splitCubic(sn,(b-a)/(ceil(b)-a),sn[1],sn[2]);
+ return path3(sn[0],sn[1]);
+ }
+ splitCubic(sn,a-floor(a),aL,aR);
+ p=concat(path3(sn[1],sn[2]),p);
+ }
+ if (ceil(b) > b) {
+ splitCubic(sn,b-floor(b),bL,bR);
+ p=concat(p,path3(sn[0],sn[1]));
+ }
+ return p;
+}
+
+// Special case of subpath for paths of length 1 used by intersect.
+void path3::halve(path3 &first, path3 &second) const
+{
+ solvedKnot3 sn[3];
+ splitCubic(sn,0.5,nodes[0],nodes[1]);
+ first=path3(sn[0],sn[1]);
+ second=path3(sn[1],sn[2]);
+}
+
+// Calculate the coefficients of a Bezier derivative divided by 3.
+static inline void derivative(triple& a, triple& b, triple& c,
+ const triple& z0, const triple& c0,
+ const triple& c1, const triple& z1)
+{
+ a=z1-z0+3.0*(c0-c1);
+ b=2.0*(z0+c1)-4.0*c0;
+ c=c0-z0;
+}
+
+bbox3 path3::bounds() const
+{
+ if(!box.empty) return box;
+
+ if (empty()) {
+ // No bounds
+ return bbox3();
+ }
+
+ Int len=length();
+ box.add(point(len));
+
+ for (Int i = 0; i < len; i++) {
+ addpoint(box,i);
+ if(straight(i)) continue;
+
+ triple a,b,c;
+ derivative(a,b,c,point(i),postcontrol(i),precontrol(i+1),point(i+1));
+
+ // Check x coordinate
+ quadraticroots x(a.getx(),b.getx(),c.getx());
+ if(x.distinct != quadraticroots::NONE && goodroot(x.t1))
+ addpoint(box,i+x.t1);
+ if(x.distinct == quadraticroots::TWO && goodroot(x.t2))
+ addpoint(box,i+x.t2);
+
+ // Check y coordinate
+ quadraticroots y(a.gety(),b.gety(),c.gety());
+ if(y.distinct != quadraticroots::NONE && goodroot(y.t1))
+ addpoint(box,i+y.t1);
+ if(y.distinct == quadraticroots::TWO && goodroot(y.t2))
+ addpoint(box,i+y.t2);
+
+ // Check z coordinate
+ quadraticroots z(a.getz(),b.getz(),c.getz());
+ if(z.distinct != quadraticroots::NONE && goodroot(z.t1))
+ addpoint(box,i+z.t1);
+ if(z.distinct == quadraticroots::TWO && goodroot(z.t2))
+ addpoint(box,i+z.t2);
+ }
+ return box;
+}
+
+pair path3::bounds(double (*m)(double, double),
+ double (*x)(const triple&, double*),
+ double (*y)(const triple&, double*), double *t) const
+{
+ checkEmpty3(n);
+
+ triple v=point((Int) 0);
+ pair B=pair(x(v,t),y(v,t));
+
+ Int n=length();
+ for(Int i=0; i <= n; ++i) {
+ if(straight(i)) {
+ triple v=point(i);
+ B=pair(m(B.getx(),x(v,t)),m(B.gety(),y(v,t)));
+ } else {
+ triple z0=point(i);
+ triple c0=postcontrol(i);
+ triple c1=precontrol(i+1);
+ triple z1=point(i+1);
+ B=pair(bound(z0,c0,c1,z1,m,x,t,B.getx()),
+ bound(z0,c0,c1,z1,m,y,t,B.gety()));
+ }
+ }
+ return B;
+}
+
+// {{{ Arclength Calculations
+
+static triple a,b,c;
+
+static double ds(double t)
+{
+ double dx=quadratic(a.getx(),b.getx(),c.getx(),t);
+ double dy=quadratic(a.gety(),b.gety(),c.gety(),t);
+ double dz=quadratic(a.getz(),b.getz(),c.getz(),t);
+ return sqrt(dx*dx+dy*dy+dz*dz);
+}
+
+// Calculates arclength of a cubic using adaptive simpson integration.
+double path3::cubiclength(Int i, double goal) const
+{
+ const triple& z0=point(i);
+ const triple& z1=point(i+1);
+ double L;
+ if(straight(i)) {
+ 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);
+
+ 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;
+
+ double t=goal/L;
+ goal *= third;
+ static double dxmin=sqrt(DBL_EPSILON);
+ if(!unsimpson(goal,ds,0.0,t,100.0*DBL_EPSILON,integral,1.0,dxmin))
+ reportError("nesting capacity exceeded in computing arctime");
+ return -t;
+}
+
+double path3::arclength() const
+{
+ if (cached_length != -1) return cached_length;
+
+ double L=0.0;
+ for (Int i = 0; i < n-1; i++) {
+ L += cubiclength(i);
+ }
+ if(cycles) L += cubiclength(n-1);
+ cached_length = L;
+ return cached_length;
+}
+
+double path3::arctime(double goal) const
+{
+ if (cycles) {
+ if (goal == 0 || cached_length == 0) return 0;
+ if (goal < 0) {
+ const path3 &rp = this->reverse();
+ double result = -rp.arctime(-goal);
+ return result;
+ }
+ if (cached_length > 0 && goal >= cached_length) {
+ Int loops = (Int)(goal / cached_length);
+ goal -= loops*cached_length;
+ return loops*n+arctime(goal);
+ }
+ } else {
+ if (goal <= 0)
+ return 0;
+ if (cached_length > 0 && goal >= cached_length)
+ return n-1;
+ }
+
+ double l,L=0;
+ for (Int i = 0; i < n-1; i++) {
+ l = cubiclength(i,goal);
+ if (l < 0)
+ return (-l+i);
+ else {
+ L += l;
+ goal -= l;
+ if (goal <= 0)
+ return i+1;
+ }
+ }
+ if (cycles) {
+ l = cubiclength(n-1,goal);
+ if (l < 0)
+ return -l+n-1;
+ if (cached_length > 0 && cached_length != L+l) {
+ reportError("arclength != length.\n"
+ "path3::arclength(double) must have broken semantics.\n"
+ "Please report this error.");
+ }
+ cached_length = L += l;
+ goal -= l;
+ return arctime(goal)+n;
+ }
+ else {
+ cached_length = L;
+ return length();
+ }
+}
+
+// }}}
+
+// {{{ Path3 Intersection Calculations
+
+// Return all intersection times of path3 g with the triple v.
+void intersections(std::vector<double>& T, const path3& g, const triple& v,
+ double fuzz)
+{
+ double fuzz2=fuzz*fuzz;
+ Int n=g.length();
+ bool cycles=g.cyclic();
+ for(Int i=0; i < n; ++i) {
+ // Check all directions to circumvent degeneracy.
+ std::vector<double> r;
+ roots(r,g.point(i).getx(),g.postcontrol(i).getx(),
+ g.precontrol(i+1).getx(),g.point(i+1).getx(),v.getx());
+ roots(r,g.point(i).gety(),g.postcontrol(i).gety(),
+ g.precontrol(i+1).gety(),g.point(i+1).gety(),v.gety());
+ roots(r,g.point(i).getz(),g.postcontrol(i).getz(),
+ g.precontrol(i+1).getz(),g.point(i+1).getz(),v.getz());
+
+ size_t m=r.size();
+ for(size_t j=0 ; j < m; ++j) {
+ double t=r[j];
+ if(t >= -Fuzz && t <= 1.0+Fuzz) {
+ double s=i+t;
+ if((g.point(s)-v).abs2() <= fuzz2) {
+ if(cycles && s >= n-Fuzz) s=0;
+ T.push_back(s);
+ }
+ }
+ }
+ }
+}
+
+// An optimized implementation of intersections(g,p--q);
+// if there are an infinite number of intersection points, the returned list is
+// only guaranteed to include the endpoint times of the intersection.
+void intersections(std::vector<double>& S, std::vector<double>& T,
+ const path3& g, const triple& p, double fuzz)
+{
+ std::vector<double> S1;
+ intersections(S1,g,p,fuzz);
+ size_t n=S1.size();
+ for(size_t i=0; i < n; ++i) {
+ S.push_back(S1[i]);
+ T.push_back(0);
+ }
+}
+
+void add(std::vector<double>& S, std::vector<double>& T, double s, double t,
+ const path3& p, const path3& q, double fuzz2)
+{
+ triple P=p.point(s);
+ for(size_t i=0; i < S.size(); ++i)
+ if((p.point(S[i])-P).abs2() <= fuzz2) return;
+ S.push_back(s);
+ T.push_back(t);
+}
+
+void add(double& s, double& t, std::vector<double>& S, std::vector<double>& T,
+ std::vector<double>& S1, std::vector<double>& T1,
+ double pscale, double qscale, double poffset, double qoffset,
+ const path3& p, const path3& q, double fuzz, bool single)
+{
+ if(single) {
+ s=s*pscale+poffset;
+ t=t*qscale+qoffset;
+ } else {
+ double fuzz2=4.0*fuzz*fuzz;
+ size_t n=S1.size();
+ for(size_t i=0; i < n; ++i)
+ add(S,T,pscale*S1[i]+poffset,qscale*T1[i]+qoffset,p,q,fuzz2);
+ }
+}
+
+void add(double& s, double& t, std::vector<double>& S, std::vector<double>& T,
+ std::vector<double>& S1, std::vector<double>& T1,
+ const path3& p, const path3& q, double fuzz, bool single)
+{
+ size_t n=S1.size();
+ if(single) {
+ if(n > 0) {
+ s=S1[0];
+ t=T1[0];
+ }
+ } else {
+ double fuzz2=4.0*fuzz*fuzz;
+ for(size_t i=0; i < n; ++i)
+ add(S,T,S1[i],T1[i],p,q,fuzz2);
+ }
+}
+
+bool intersections(double &s, double &t, std::vector<double>& S,
+ std::vector<double>& T, path3& p, path3& q,
+ double fuzz, bool single, bool exact, unsigned depth)
+{
+ if(errorstream::interrupt) throw interrupted();
+
+ Int lp=p.length();
+ if(lp == 0 && exact) {
+ std::vector<double> T1,S1;
+ intersections(T1,S1,q,p.point(lp),fuzz);
+ add(s,t,S,T,S1,T1,p,q,fuzz,single);
+ return S1.size() > 0;
+ }
+
+ Int lq=q.length();
+ if(lq == 0 && exact) {
+ std::vector<double> S1,T1;
+ intersections(S1,T1,p,q.point(lq),fuzz);
+ add(s,t,S,T,S1,T1,p,q,fuzz,single);
+ return S1.size() > 0;
+ }
+
+ triple maxp=p.max();
+ triple minp=p.min();
+ triple maxq=q.max();
+ triple minq=q.min();
+
+ if(maxp.getx()+fuzz >= minq.getx() &&
+ maxp.gety()+fuzz >= minq.gety() &&
+ maxp.getz()+fuzz >= minq.getz() &&
+ maxq.getx()+fuzz >= minp.getx() &&
+ maxq.gety()+fuzz >= minp.gety() &&
+ maxq.getz()+fuzz >= minp.getz()) {
+ // Overlapping bounding boxes
+
+ --depth;
+ if((maxp-minp).length()+(maxq-minq).length() <= fuzz || depth == 0) {
+ if(single) {
+ s=0;
+ t=0;
+ } else {
+ S.push_back(0.0);
+ T.push_back(0.0);
+ }
+ return true;
+ }
+
+ path3 p1,p2;
+ double pscale,poffset;
+
+ if(lp <= 1) {
+ if(lp == 1) p.halve(p1,p2);
+ if(lp == 0 || p1 == p || p2 == p) {
+ std::vector<double> T1,S1;
+ intersections(T1,S1,q,p.point((Int) 0),fuzz);
+ add(s,t,S,T,S1,T1,p,q,fuzz,single);
+ return S1.size() > 0;
+ }
+ pscale=poffset=0.5;
+ } else {
+ Int tp=lp/2;
+ p1=p.subpath(0,tp);
+ p2=p.subpath(tp,lp);
+ poffset=tp;
+ pscale=1.0;
+ }
+
+ path3 q1,q2;
+ double qscale,qoffset;
+
+ if(lq <= 1) {
+ if(lq == 1) q.halve(q1,q2);
+ if(lq == 0 || q1 == q || q2 == q) {
+ std::vector<double> S1,T1;
+ intersections(S1,T1,p,q.point((Int) 0),fuzz);
+ add(s,t,S,T,S1,T1,p,q,fuzz,single);
+ return S1.size() > 0;
+ }
+ qscale=qoffset=0.5;
+ } else {
+ Int tq=lq/2;
+ q1=q.subpath(0,tq);
+ q2=q.subpath(tq,lq);
+ qoffset=tq;
+ qscale=1.0;
+ }
+
+ bool Short=lp == 1 && lq == 1;
+
+ static size_t maxcount=9;
+ size_t count=0;
+
+ std::vector<double> S1,T1;
+ if(intersections(s,t,S1,T1,p1,q1,fuzz,single,exact,depth)) {
+ add(s,t,S,T,S1,T1,pscale,qscale,0.0,0.0,p,q,fuzz,single);
+ if(single || depth <= mindepth)
+ return true;
+ count += S1.size();
+ if(Short && count > maxcount) return true;
+ }
+
+ S1.clear();
+ T1.clear();
+ if(intersections(s,t,S1,T1,p1,q2,fuzz,single,exact,depth)) {
+ add(s,t,S,T,S1,T1,pscale,qscale,0.0,qoffset,p,q,fuzz,single);
+ if(single || depth <= mindepth)
+ return true;
+ count += S1.size();
+ if(Short && count > maxcount) return true;
+ }
+
+ S1.clear();
+ T1.clear();
+ if(intersections(s,t,S1,T1,p2,q1,fuzz,single,exact,depth)) {
+ add(s,t,S,T,S1,T1,pscale,qscale,poffset,0.0,p,q,fuzz,single);
+ if(single || depth <= mindepth)
+ return true;
+ count += S1.size();
+ if(Short && count > maxcount) return true;
+ }
+
+ S1.clear();
+ T1.clear();
+ if(intersections(s,t,S1,T1,p2,q2,fuzz,single,exact,depth)) {
+ add(s,t,S,T,S1,T1,pscale,qscale,poffset,qoffset,p,q,fuzz,single);
+ if(single || depth <= mindepth)
+ return true;
+ count += S1.size();
+ if(Short && count > maxcount) return true;
+ }
+
+ return S.size() > 0;
+ }
+ return false;
+}
+
+// }}}
+
+path3 concat(const path3& p1, const path3& p2)
+{
+ Int n1 = p1.length(), n2 = p2.length();
+
+ if (n1 == -1) return p2;
+ if (n2 == -1) return p1;
+ triple a=p1.point(n1);
+ triple b=p2.point((Int) 0);
+
+ mem::vector<solvedKnot3> nodes(n1+n2+1);
+
+ Int i = 0;
+ nodes[0].pre = p1.point((Int) 0);
+ for (Int j = 0; j < n1; j++) {
+ nodes[i].point = p1.point(j);
+ nodes[i].straight = p1.straight(j);
+ nodes[i].post = p1.postcontrol(j);
+ nodes[i+1].pre = p1.precontrol(j+1);
+ i++;
+ }
+ for (Int j = 0; j < n2; j++) {
+ nodes[i].point = p2.point(j);
+ nodes[i].straight = p2.straight(j);
+ nodes[i].post = p2.postcontrol(j);
+ nodes[i+1].pre = p2.precontrol(j+1);
+ i++;
+ }
+ nodes[i].point = nodes[i].post = p2.point(n2);
+
+ return path3(nodes, i+1);
+}
+
+path3 transformed(const array& t, const path3& p)
+{
+ Int n = p.size();
+ mem::vector<solvedKnot3> nodes(n);
+
+ for (Int i = 0; i < n; ++i) {
+ nodes[i].pre = t * p.precontrol(i);
+ nodes[i].point = t * p.point(i);
+ nodes[i].post = t * p.postcontrol(i);
+ nodes[i].straight = p.straight(i);
+ }
+
+ return path3(nodes, n, p.cyclic());
+}
+
+double xproject(const triple& v, double *t)
+{
+ double x=v.getx();
+ double y=v.gety();
+ double z=v.getz();
+ double f=t[12]*x+t[13]*y+t[14]*z+t[15];
+ if(f == 0.0) run::dividebyzero();
+ return (t[0]*x+t[1]*y+t[2]*z+t[3])/f;
+}
+
+double yproject(const triple& v, double *t)
+{
+ double x=v.getx();
+ double y=v.gety();
+ double z=v.getz();
+ double f=t[12]*x+t[13]*y+t[14]*z+t[15];
+ if(f == 0.0) run::dividebyzero();
+ return (t[4]*x+t[5]*y+t[6]*z+t[7])/f;
+}
+
+double xratio(const triple& v, double *)
+{
+ double z=v.getz();
+ return v.getx()/z;
+}
+
+double yratio(const triple& v, double *)
+{
+ double z=v.getz();
+ return v.gety()/z;
+}
+
+struct Split {
+ double m0,m1,m2,m3,m4,m5;
+ Split(double z0, double c0, double c1, double z1) {
+ m0=0.5*(z0+c0);
+ m1=0.5*(c0+c1);
+ m2=0.5*(c1+z1);
+ m3=0.5*(m0+m1);
+ m4=0.5*(m1+m2);
+ m5=0.5*(m3+m4);
+ }
+};
+
+double cornerbound(double *p, double (*m)(double, double))
+{
+ double b=m(p[0],p[3]);
+ b=m(b,p[12]);
+ return m(b,p[15]);
+}
+
+double controlbound(double *p, double (*m)(double, double))
+{
+ double b=m(p[1],p[2]);
+ b=m(b,p[4]);
+ b=m(b,p[5]);
+ b=m(b,p[6]);
+ b=m(b,p[7]);
+ b=m(b,p[8]);
+ b=m(b,p[9]);
+ b=m(b,p[10]);
+ b=m(b,p[11]);
+ b=m(b,p[13]);
+ return m(b,p[14]);
+}
+
+double cornerbound(triple *p, double (*m)(double, double),
+ double (*f)(const triple&, double*), double *t)
+{
+ double b=m(f(p[0],t),f(p[3],t));
+ b=m(b,f(p[12],t));
+ return m(b,f(p[15],t));
+}
+
+double controlbound(triple *p, double (*m)(double, double),
+ double (*f)(const triple&, double*), double *t)
+{
+ double b=m(f(p[1],t),f(p[2],t));
+ b=m(b,f(p[4],t));
+ b=m(b,f(p[5],t));
+ b=m(b,f(p[6],t));
+ b=m(b,f(p[7],t));
+ b=m(b,f(p[8],t));
+ b=m(b,f(p[9],t));
+ b=m(b,f(p[10],t));
+ b=m(b,f(p[11],t));
+ b=m(b,f(p[13],t));
+ return m(b,f(p[14],t));
+}
+
+double bound(double *p, double (*m)(double, double), double b, int depth)
+{
+ b=m(b,cornerbound(p,m));
+ if(m(-1.0,1.0)*(b-controlbound(p,m)) >= -sqrtFuzz || depth == 0)
+ return b;
+ --depth;
+
+ Split c0(p[0],p[1],p[2],p[3]);
+ Split c1(p[4],p[5],p[6],p[7]);
+ Split c2(p[8],p[9],p[10],p[11]);
+ Split c3(p[12],p[13],p[14],p[15]);
+
+ Split c4(p[12],p[8],p[4],p[0]);
+ Split c5(c3.m0,c2.m0,c1.m0,c0.m0);
+ Split c6(c3.m3,c2.m3,c1.m3,c0.m3);
+ Split c7(c3.m5,c2.m5,c1.m5,c0.m5);
+ Split c8(c3.m4,c2.m4,c1.m4,c0.m4);
+ Split c9(c3.m5,c2.m5,c1.m5,c0.m5);
+ Split c10(p[15],p[11],p[7],p[3]);
+
+ // Check all 4 Bezier subpatches.
+ double s0[]={c4.m5,c5.m5,c6.m5,c7.m5,c4.m3,c5.m3,c6.m3,c7.m3,
+ c4.m0,c5.m0,c6.m0,c7.m0,p[12],c3.m0,c3.m3,c3.m5};
+ b=bound(s0,m,b,depth);
+ double s1[]={p[0],c0.m0,c0.m3,c0.m5,c4.m2,c5.m2,c6.m2,c7.m2,
+ c4.m4,c5.m4,c6.m4,c7.m4,c4.m5,c5.m5,c6.m5,c7.m5};
+ b=bound(s1,m,b,depth);
+ double s2[]={c0.m5,c0.m4,c0.m2,p[3],c7.m2,c8.m2,c9.m2,c10.m2,
+ c7.m4,c8.m4,c9.m4,c10.m4,c7.m5,c8.m5,c9.m5,c10.m5};
+ b=bound(s2,m,b,depth);
+ double s3[]={c7.m5,c8.m5,c9.m5,c10.m5,c7.m3,c8.m3,c9.m3,c10.m3,
+ c7.m0,c8.m0,c9.m0,c10.m0,c3.m5,c3.m4,c3.m2,p[15]};
+ return bound(s3,m,b,depth);
+}
+
+double bound(triple *p, double (*m)(double, double),
+ double (*f)(const triple&, double*), double *t,
+ double b, int depth)
+{
+ b=m(b,cornerbound(p,m,f,t));
+ if(m(-1.0,1.0)*(b-controlbound(p,m,f,t)) >= -sqrtFuzz || depth == 0)
+ return b;
+ --depth;
+
+ Split3 c0(p[0],p[1],p[2],p[3]);
+ Split3 c1(p[4],p[5],p[6],p[7]);
+ Split3 c2(p[8],p[9],p[10],p[11]);
+ Split3 c3(p[12],p[13],p[14],p[15]);
+
+ Split3 c4(p[12],p[8],p[4],p[0]);
+ Split3 c5(c3.m0,c2.m0,c1.m0,c0.m0);
+ Split3 c6(c3.m3,c2.m3,c1.m3,c0.m3);
+ Split3 c7(c3.m5,c2.m5,c1.m5,c0.m5);
+ Split3 c8(c3.m4,c2.m4,c1.m4,c0.m4);
+ Split3 c9(c3.m5,c2.m5,c1.m5,c0.m5);
+ Split3 c10(p[15],p[11],p[7],p[3]);
+
+ // Check all 4 Bezier subpatches.
+
+ triple s0[]={c4.m5,c5.m5,c6.m5,c7.m5,c4.m3,c5.m3,c6.m3,c7.m3,
+ c4.m0,c5.m0,c6.m0,c7.m0,p[12],c3.m0,c3.m3,c3.m5};
+ b=bound(s0,m,f,t,b,depth);
+ triple s1[]={p[0],c0.m0,c0.m3,c0.m5,c4.m2,c5.m2,c6.m2,c7.m2,
+ c4.m4,c5.m4,c6.m4,c7.m4,c4.m5,c5.m5,c6.m5,c7.m5};
+ b=bound(s1,m,f,t,b,depth);
+ triple s2[]={c0.m5,c0.m4,c0.m2,p[3],c7.m2,c8.m2,c9.m2,c10.m2,
+ c7.m4,c8.m4,c9.m4,c10.m4,c7.m5,c8.m5,c9.m5,c10.m5};
+ b=bound(s2,m,f,t,b,depth);
+ triple s3[]={c7.m5,c8.m5,c9.m5,c10.m5,c7.m3,c8.m3,c9.m3,c10.m3,
+ c7.m0,c8.m0,c9.m0,c10.m0,c3.m5,c3.m4,c3.m2,p[15]};
+ return bound(s3,m,f,t,b,depth);
+}
+
+} //namespace camp
+
diff --git a/Build/source/utils/asymptote/path3.h b/Build/source/utils/asymptote/path3.h
new file mode 100644
index 00000000000..4c61b3065d4
--- /dev/null
+++ b/Build/source/utils/asymptote/path3.h
@@ -0,0 +1,386 @@
+/*****
+ * path.h
+ * John Bowman
+ *
+ * Stores a 3D piecewise cubic spline with known control points.
+ *
+ *****/
+
+#ifndef PATH3_H
+#define PATH3_H
+
+#include <cfloat>
+
+#include "mod.h"
+#include "triple.h"
+#include "bbox3.h"
+#include "path.h"
+#include "arrayop.h"
+
+namespace camp {
+
+void checkEmpty3(Int n);
+
+// Used in the storage of solved path3 knots.
+struct solvedKnot3 : public gc {
+ triple pre;
+ triple point;
+ triple post;
+ bool straight;
+ solvedKnot3() : straight(false) {}
+
+ friend bool operator== (const solvedKnot3& p, const solvedKnot3& q)
+ {
+ return p.pre == q.pre && p.point == q.point && p.post == q.post;
+ }
+};
+
+extern const double BigFuzz;
+extern const double Fuzz;
+extern const double Fuzz2;
+extern const double sqrtFuzz;
+
+class path3 : public gc {
+ bool cycles; // If the path3 is closed in a loop
+
+ Int n; // The number of knots
+
+ mem::vector<solvedKnot3> nodes;
+ mutable double cached_length; // Cache length since path3 is immutable.
+
+ mutable bbox3 box;
+ mutable bbox3 times; // Times where minimum and maximum extents are attained.
+
+public:
+ path3()
+ : cycles(false), n(0), nodes(), cached_length(-1) {}
+
+ // Create a path3 of a single point
+ path3(triple z, bool = false)
+ : cycles(false), n(1), nodes(1), cached_length(-1)
+ {
+ nodes[0].pre = nodes[0].point = nodes[0].post = z;
+ nodes[0].straight = false;
+ }
+
+ // Creates path3 from a list of knots. This will be used by camp
+ // methods such as the guide solver, but should probably not be used by a
+ // user of the system unless he knows what he is doing.
+ path3(mem::vector<solvedKnot3>& nodes, Int n, bool cycles = false)
+ : cycles(cycles), n(n), nodes(nodes), cached_length(-1)
+ {
+ }
+
+ friend bool operator== (const path3& p, const path3& q)
+ {
+ return p.cycles == q.cycles && p.nodes == q.nodes;
+ }
+
+public:
+ path3(solvedKnot3 n1, solvedKnot3 n2)
+ : cycles(false), n(2), nodes(2), cached_length(-1)
+ {
+ nodes[0] = n1;
+ nodes[1] = n2;
+ nodes[0].pre = nodes[0].point;
+ nodes[1].post = nodes[1].point;
+ }
+
+ // Copy constructor
+ path3(const path3& p)
+ : cycles(p.cycles), n(p.n), nodes(p.nodes), cached_length(p.cached_length),
+ box(p.box)
+ {}
+
+ virtual ~path3()
+ {
+ }
+
+ // Getting control points
+ Int size() const
+ {
+ return n;
+ }
+
+ bool empty() const
+ {
+ return n == 0;
+ }
+
+ Int length() const
+ {
+ return cycles ? n : n-1;
+ }
+
+ bool cyclic() const
+ {
+ return cycles;
+ }
+
+ mem::vector<solvedKnot3>& Nodes() {
+ return nodes;
+ }
+
+ bool straight(Int t) const
+ {
+ if (cycles) return nodes[imod(t,n)].straight;
+ return (t >= 0 && t < n) ? nodes[t].straight : false;
+ }
+
+ bool piecewisestraight() const
+ {
+ Int L=length();
+ for(Int i=0; i < L; ++i)
+ if(!straight(i)) return false;
+ return true;
+ }
+
+ triple point(Int t) const
+ {
+ return nodes[adjustedIndex(t,n,cycles)].point;
+ }
+
+ triple point(double t) const;
+
+ triple precontrol(Int t) const
+ {
+ return nodes[adjustedIndex(t,n,cycles)].pre;
+ }
+
+ triple precontrol(double t) const;
+
+ triple postcontrol(Int t) const
+ {
+ return nodes[adjustedIndex(t,n,cycles)].post;
+ }
+
+ triple postcontrol(double t) const;
+
+ inline double norm(const triple& z0, const triple& c0, const triple& c1,
+ const triple& z1) const {
+ return Fuzz2*camp::max((c0-z0).abs2(),
+ camp::max((c1-z0).abs2(),(z1-z0).abs2()));
+ }
+
+ triple predir(Int t, bool normalize=true) const {
+ if(!cycles && t <= 0) return triple(0,0,0);
+ triple z1=point(t);
+ triple c1=precontrol(t);
+ triple dir=3.0*(z1-c1);
+ if(!normalize) return dir;
+ triple z0=point(t-1);
+ triple c0=postcontrol(t-1);
+ double epsilon=norm(z0,c0,c1,z1);
+ if(dir.abs2() > epsilon) return unit(dir);
+ dir=2.0*c1-c0-z1;
+ if(dir.abs2() > epsilon) return unit(dir);
+ return unit(z1-z0+3.0*(c0-c1));
+ }
+
+ triple postdir(Int t, bool normalize=true) const {
+ if(!cycles && t >= n-1) return triple(0,0,0);
+ triple c0=postcontrol(t);
+ triple z0=point(t);
+ triple dir=3.0*(c0-z0);
+ triple z1=point(t+1);
+ triple c1=precontrol(t+1);
+ double epsilon=norm(z0,c0,c1,z1);
+ if(!normalize) return dir;
+ if(dir.abs2() > epsilon) return unit(dir);
+ dir=z0-2.0*c0+c1;
+ if(dir.abs2() > epsilon) return unit(dir);
+ return unit(z1-z0+3.0*(c0-c1));
+ }
+
+ triple dir(Int t, Int sign, bool normalize=true) const {
+ if(sign == 0) {
+ triple v=predir(t,normalize)+postdir(t,normalize);
+ return normalize ? unit(v) : 0.5*v;
+ }
+ if(sign > 0) return postdir(t,normalize);
+ return predir(t,normalize);
+ }
+
+ triple dir(double t, bool normalize=true) const {
+ if(!cycles) {
+ if(t <= 0) return postdir((Int) 0,normalize);
+ if(t >= n-1) return predir(n-1,normalize);
+ }
+ Int i=Floor(t);
+ t -= i;
+ if(t == 0) return dir(i,0);
+ triple z0=point(i);
+ triple c0=postcontrol(i);
+ triple c1=precontrol(i+1);
+ triple z1=point(i+1);
+ triple a=3.0*(z1-z0)+9.0*(c0-c1);
+ triple b=6.0*(z0+c1)-12.0*c0;
+ triple c=3.0*(c0-z0);
+ triple dir=a*t*t+b*t+c;
+ if(!normalize) return dir;
+ double epsilon=norm(z0,c0,c1,z1);
+ if(dir.abs2() > epsilon) return unit(dir);
+ dir=2.0*a*t+b;
+ if(dir.abs2() > epsilon) return unit(dir);
+ return unit(a);
+ }
+
+ triple postaccel(Int t) const {
+ if(!cycles && t >= n-1) return triple(0,0,0);
+ triple z0=point(t);
+ triple c0=postcontrol(t);
+ triple c1=precontrol(t+1);
+ return 6.0*(z0+c1)-12.0*c0;
+ }
+
+ triple preaccel(Int t) const {
+ if(!cycles && t <= 0) return triple(0,0,0);
+ triple z0=point(t-1);
+ triple c0=postcontrol(t-1);
+ triple c1=precontrol(t);
+ triple z1=point(t);
+ return 6.0*(z1+c0)-12.0*c1;
+ }
+
+ triple accel(Int t, Int sign) const {
+ if(sign == 0) return 0.5*(preaccel(t)+postaccel(t));
+ if(sign > 0) return postaccel(t);
+ return preaccel(t);
+ }
+
+ triple accel(double t) const {
+ if(!cycles) {
+ if(t <= 0) return postaccel((Int) 0);
+ if(t >= n-1) return preaccel(n-1);
+ }
+ Int i=Floor(t);
+ t -= i;
+ if(t == 0) return 0.5*(postaccel(i)+preaccel(i));
+ triple z0=point(i);
+ triple c0=postcontrol(i);
+ triple c1=precontrol(i+1);
+ triple z1=point(i+1);
+ return 6.0*t*(z1-z0+3.0*(c0-c1))+6.0*(z0+c1)-12.0*c0;
+ }
+
+ // Returns the path3 traced out in reverse.
+ path3 reverse() const;
+
+ // Generates a path3 that is a section of the old path3, using the time
+ // interval given.
+ path3 subpath(Int start, Int end) const;
+ path3 subpath(double start, double end) const;
+
+ // Special case of subpath used by intersect.
+ void halve(path3 &first, path3 &second) const;
+
+ // Used by picture to determine bounding box.
+ bbox3 bounds() const;
+
+ triple mintimes() const {
+ checkEmpty3(n);
+ bounds();
+ return camp::triple(times.left,times.bottom,times.lower);
+ }
+
+ triple maxtimes() const {
+ checkEmpty3(n);
+ bounds();
+ return camp::triple(times.right,times.top,times.upper);
+ }
+
+ template<class T>
+ void addpoint(bbox3& box, T i) const {
+ box.addnonempty(point(i),times,(double) i);
+ }
+
+ double cubiclength(Int i, double goal=-1) const;
+ double arclength () const;
+ double arctime (double l) const;
+
+ triple max() const {
+ checkEmpty3(n);
+ return bounds().Max();
+ }
+
+ triple min() const {
+ checkEmpty3(n);
+ return bounds().Min();
+ }
+
+ pair bounds(double (*m)(double, double),
+ double (*x)(const triple&, double*),
+ double (*y)(const triple&, double*), double *t) const;
+
+
+// Increment count if the path3 has a vertical component at t.
+ bool Count(Int& count, double t) const;
+
+// Count if t is in (begin,end] and z lies to the left of point(i+t).
+ void countleft(Int& count, double x, Int i, double t,
+ double begin, double end, double& mint, double& maxt) const;
+
+// Return the winding number of the region bounded by the (cyclic) path3
+// relative to the point z.
+ Int windingnumber(const triple& z) const;
+};
+
+path3 transformed(const vm::array& t, const path3& p);
+
+extern path3 nullpath3;
+extern const unsigned maxdepth;
+
+bool intersect(double& S, double& T, path3& p, path3& q, double fuzz,
+ unsigned depth=maxdepth);
+bool intersections(double& s, double& t, std::vector<double>& S,
+ std::vector<double>& T, path3& p, path3& q,
+ double fuzz, bool single, bool exact,
+ unsigned depth=maxdepth);
+void intersections(std::vector<double>& S, path3& g,
+ const triple& p, const triple& q, double fuzz);
+
+// Concatenates two path3s into a new one.
+path3 concat(const path3& p1, const path3& p2);
+
+// return the perpendicular displacement of a point z from the line through
+// points p and q.
+inline triple displacement(const triple& z, const triple& p, const triple& q)
+{
+ triple Z=z-p;
+ triple Q=unit(q-p);
+ return Z-dot(Z,Q)*Q;
+}
+
+struct Split3 {
+ triple m0,m1,m2,m3,m4,m5;
+ Split3(triple z0, triple c0, triple c1, triple z1) {
+ m0=0.5*(z0+c0);
+ m1=0.5*(c0+c1);
+ m2=0.5*(c1+z1);
+ m3=0.5*(m0+m1);
+ m4=0.5*(m1+m2);
+ m5=0.5*(m3+m4);
+ }
+};
+
+double xproject(const triple& v, double *t);
+double yproject(const triple& v, double *t);
+
+double xratio(const triple& v, double *t);
+double yratio(const triple& v, double *t);
+
+double bound(triple z0, triple c0, triple c1, triple z1,
+ double (*m)(double, double),
+ double (*f)(const triple&, double*), double *t,
+ double b, int depth=maxdepth);
+double bound(double *p, double (*m)(double, double), double b,
+ int depth=maxdepth);
+double bound(triple *p, double (*m)(double, double),
+ double (*f)(const triple&, double*), double* t, double b,
+ int depth=maxdepth);
+}
+
+// Delete the following line to work around problems with old broken compilers.
+GC_DECLARE_PTRFREE(camp::solvedKnot3);
+
+#endif
diff --git a/Build/source/utils/asymptote/pen.h b/Build/source/utils/asymptote/pen.h
new file mode 100644
index 00000000000..e2a8002e7c5
--- /dev/null
+++ b/Build/source/utils/asymptote/pen.h
@@ -0,0 +1,878 @@
+/*****
+ * pen.h
+ * John Bowman 2003/03/23
+ *
+ *****/
+
+#ifndef PEN_H
+#define PEN_H
+
+#include "transform.h"
+#include "settings.h"
+#include "bbox.h"
+#include "common.h"
+#include "path.h"
+
+namespace camp {
+
+static const string DEFPAT="<default>";
+static const string DEFLATEXFONT="\\usefont{\\ASYencoding}{\\ASYfamily}{\\ASYseries}{\\ASYshape}";
+static const string DEFTEXFONT="cmr12";
+static const double DEFWIDTH=-1;
+static const Int DEFCAP=-1;
+static const Int DEFJOIN=-1;
+static const double DEFMITER=0;
+
+static const struct invisiblepen_t {} invisiblepen={};
+static const struct setlinewidth_t {} setlinewidth={};
+static const struct setfont_t {} setfont={};
+static const struct setfontsize_t {} setfontsize={};
+static const struct setpattern_t {} setpattern={};
+static const struct setlinecap_t {} setlinecap={};
+static const struct setlinejoin_t {} setlinejoin={};
+static const struct setmiterlimit_t {} setmiterlimit={};
+static const struct setoverwrite_t {} setoverwrite={};
+static const struct initialpen_t {} initialpen={};
+static const struct resolvepen_t {} resolvepen={};
+
+static const string Cap[]={"square","round","extended"};
+static const string Join[]={"miter","round","bevel"};
+const Int nCap=sizeof(Cap)/sizeof(string);
+const Int nJoin=sizeof(Join)/sizeof(string);
+
+enum overwrite_t {DEFWRITE=-1,ALLOW,SUPPRESS,SUPPRESSQUIET,MOVE,MOVEQUIET};
+static const string OverwriteTag[]={"Allow","Suppress","SupressQuiet",
+ "Move","MoveQuiet"};
+const Int nOverwrite=sizeof(OverwriteTag)/sizeof(string);
+
+enum FillRule {DEFFILL=-1,ZEROWINDING,EVENODD};
+static const string FillRuleTag[]={"ZeroWinding","EvenOdd"};
+
+const Int nFill=sizeof(FillRuleTag)/sizeof(string);
+
+enum BaseLine {DEFBASE=-1,NOBASEALIGN,BASEALIGN};
+static const string BaseLineTag[]={"NoAlign","Align"};
+const Int nBaseLine=sizeof(BaseLineTag)/sizeof(string);
+
+enum ColorSpace {DEFCOLOR=0,INVISIBLE,GRAYSCALE,RGB,CMYK,PATTERN};
+extern const size_t ColorComponents[];
+static const string ColorDeviceSuffix[]={"","","Gray","RGB","CMYK",""};
+const unsigned nColorSpace=sizeof(ColorDeviceSuffix)/sizeof(string);
+
+
+
+class LineType
+{
+public:
+ string pattern; // The string for the PostScript style line pattern.
+ double offset; // The offset in the pattern at which to start drawing.
+ bool scale; // Scale the line type values by the pen width?
+ bool adjust; // Adjust the line type values to fit the arclength?
+
+ LineType(string pattern, double offset, bool scale, bool adjust) :
+ pattern(pattern), offset(offset), scale(scale), adjust(adjust) {}
+};
+
+static const LineType DEFLINE("default",0,true,true);
+
+inline bool operator == (LineType a, LineType b) {
+ return a.pattern == b.pattern && a.offset == b.offset &&
+ a.scale == b.scale && a.adjust == b.adjust;
+}
+
+class Transparency
+{
+public:
+ string blend;
+ double opacity;
+ Transparency(string blend, double opacity) :
+ blend(blend), opacity(opacity) {}
+};
+
+static const Transparency DEFTRANSP("Compatible",1.0);
+
+inline bool operator == (Transparency a, Transparency b) {
+ return a.blend == b.blend && a.opacity == b.opacity;
+}
+
+static const string BlendMode[]={"Compatible","Normal","Multiply","Screen",
+ "Overlay","SoftLight","HardLight",
+ "ColorDodge","ColorBurn","Darken",
+ "Lighten","Difference","Exclusion",
+ "Hue","Saturation","Color","Luminosity"};
+const Int nBlendMode=sizeof(BlendMode)/sizeof(string);
+
+static const transform nullTransform=transform(0.0,0.0,0.0,0.0,0.0,0.0);
+
+class pen;
+pen& defaultpen();
+
+class pen : public gc {
+ LineType line;
+
+ // Width of line, in PS units.
+ double linewidth;
+ path P; // A polygonal path defining a custom pen nib;
+ // nullpath means the default (typically circular) nib.
+ string font;
+ double fontsize;
+ double lineskip;
+
+ ColorSpace color;
+ double r,g,b; // RGB or CMY value
+ double grey; // grayscale or K value
+
+ string pattern; // The name of the user-defined fill/draw pattern
+ FillRule fillrule; // Zero winding-number (default) or even-odd rule
+ BaseLine baseline; // Align to TeX baseline?
+ Transparency transparency;
+ Int linecap;
+ Int linejoin;
+ double miterlimit;
+ overwrite_t overwrite;
+
+ // The transformation applied to the pen nib for calligraphic effects.
+ // nullTransform means the default (typically identity) transformation.
+ transform t;
+
+public:
+ static double pos0(double x) {return x >= 0 ? x : 0;}
+
+ void greyrange() {if(grey > 1.0) grey=1.0;}
+
+ void rgbrange() {
+ double sat=rgbsaturation();
+ if(sat > 1.0) {
+ double scale=1.0/sat;
+ r *= scale;
+ g *= scale;
+ b *= scale;
+ }
+ }
+
+ void cmykrange() {
+ double sat=cmyksaturation();
+ if(sat > 1.0) {
+ double scale=1.0/sat;
+ r *= scale;
+ g *= scale;
+ b *= scale;
+ grey *= scale;
+ }
+ }
+
+ void colorless() {
+ r=g=b=grey=0.0;
+ color=DEFCOLOR;
+ }
+
+ pen() :
+ line(DEFLINE), linewidth(DEFWIDTH), P(nullpath),
+ font(""), fontsize(0.0), lineskip(0.0), color(DEFCOLOR),
+ r(0), g(0), b(0), grey(0),
+ pattern(DEFPAT), fillrule(DEFFILL), baseline(DEFBASE),
+ transparency(DEFTRANSP),
+ linecap(DEFCAP), linejoin(DEFJOIN), miterlimit(DEFMITER),
+ overwrite(DEFWRITE), t(nullTransform) {}
+
+ pen(const LineType& line, double linewidth, const path& P,
+ const string& font, double fontsize, double lineskip,
+ ColorSpace color, double r, double g, double b, double grey,
+ const string& pattern, FillRule fillrule, BaseLine baseline,
+ const Transparency& transparency,
+ Int linecap, Int linejoin, double miterlimit,
+ overwrite_t overwrite, const transform& t) :
+ line(line), linewidth(linewidth), P(P),
+ font(font), fontsize(fontsize), lineskip(lineskip), color(color),
+ r(r), g(g), b(b), grey(grey),
+ pattern(pattern), fillrule(fillrule), baseline(baseline),
+ transparency(transparency),
+ linecap(linecap), linejoin(linejoin), miterlimit(miterlimit),
+ overwrite(overwrite), t(t) {}
+
+ pen(invisiblepen_t) :
+ line(DEFLINE), linewidth(DEFWIDTH), P(nullpath),
+ font(""), fontsize(0.0), lineskip(0.0), color(INVISIBLE),
+ r(0), g(0), b(0), grey(0),
+ pattern(DEFPAT), fillrule(DEFFILL), baseline(DEFBASE),
+ transparency(DEFTRANSP),
+ linecap(DEFCAP), linejoin(DEFJOIN),
+ overwrite(DEFWRITE), t(nullTransform) {}
+
+ pen(setlinewidth_t, double linewidth) :
+ line(DEFLINE), linewidth(linewidth), P(nullpath),
+ font(""), fontsize(0.0), lineskip(0.0), color(DEFCOLOR),
+ r(0), g(0), b(0), grey(0),
+ pattern(DEFPAT), fillrule(DEFFILL), baseline(DEFBASE),
+ transparency(DEFTRANSP),
+ linecap(DEFCAP), linejoin(DEFJOIN), miterlimit(DEFMITER),
+ overwrite(DEFWRITE), t(nullTransform) {}
+
+ pen(path P) :
+ line(DEFLINE), linewidth(DEFWIDTH), P(P),
+ font(""), fontsize(0.0), lineskip(0.0), color(DEFCOLOR),
+ r(0), g(0), b(0), grey(0),
+ pattern(DEFPAT), fillrule(DEFFILL), baseline(DEFBASE),
+ transparency(DEFTRANSP),
+ linecap(DEFCAP), linejoin(DEFJOIN), miterlimit(DEFMITER),
+ overwrite(DEFWRITE), t(nullTransform) {}
+
+ pen(const LineType& line) :
+ line(line), linewidth(DEFWIDTH), P(nullpath),
+ font(""), fontsize(0.0), lineskip(0.0), color(DEFCOLOR),
+ r(0), g(0), b(0), grey(0),
+ pattern(DEFPAT), fillrule(DEFFILL), baseline(DEFBASE),
+ transparency(DEFTRANSP),
+ linecap(DEFCAP), linejoin(DEFJOIN), miterlimit(DEFMITER),
+ overwrite(DEFWRITE), t(nullTransform) {}
+
+ pen(setfont_t, string font) :
+ line(DEFLINE), linewidth(DEFWIDTH), P(nullpath),
+ font(font), fontsize(0.0), lineskip(0.0), color(DEFCOLOR),
+ r(0), g(0), b(0), grey(0),
+ pattern(DEFPAT), fillrule(DEFFILL), baseline(DEFBASE),
+ transparency(DEFTRANSP),
+ linecap(DEFCAP), linejoin(DEFJOIN), miterlimit(DEFMITER),
+ overwrite(DEFWRITE), t(nullTransform) {}
+
+ pen(setfontsize_t, double fontsize, double lineskip) :
+ line(DEFLINE), linewidth(DEFWIDTH), P(nullpath),
+ font(""), fontsize(fontsize), lineskip(lineskip), color(DEFCOLOR),
+ r(0), g(0), b(0), grey(0),
+ pattern(DEFPAT), fillrule(DEFFILL), baseline(DEFBASE),
+ transparency(DEFTRANSP),
+ linecap(DEFCAP), linejoin(DEFJOIN), miterlimit(DEFMITER),
+ overwrite(DEFWRITE), t(nullTransform) {}
+
+ pen(setpattern_t, const string& pattern) :
+ line(DEFLINE), linewidth(DEFWIDTH), P(nullpath),
+ font(""), fontsize(0.0), lineskip(0.0), color(PATTERN),
+ r(0), g(0), b(0), grey(0),
+ pattern(pattern), fillrule(DEFFILL), baseline(DEFBASE),
+ transparency(DEFTRANSP),
+ linecap(DEFCAP), linejoin(DEFJOIN), miterlimit(DEFMITER),
+ overwrite(DEFWRITE), t(nullTransform) {}
+
+ pen(FillRule fillrule) :
+ line(DEFLINE), linewidth(DEFWIDTH), P(nullpath),
+ font(""), fontsize(0.0), lineskip(0.0), color(DEFCOLOR),
+ r(0), g(0), b(0), grey(0),
+ pattern(DEFPAT), fillrule(fillrule), baseline(DEFBASE),
+ transparency(DEFTRANSP),
+ linecap(DEFCAP), linejoin(DEFJOIN), miterlimit(DEFMITER),
+ overwrite(DEFWRITE), t(nullTransform) {}
+
+ pen(BaseLine baseline) :
+ line(DEFLINE), linewidth(DEFWIDTH), P(nullpath),
+ font(""), fontsize(0.0), lineskip(0.0), color(DEFCOLOR),
+ r(0), g(0), b(0), grey(0),
+ pattern(DEFPAT), fillrule(DEFFILL), baseline(baseline),
+ transparency(DEFTRANSP),
+ linecap(DEFCAP), linejoin(DEFJOIN), miterlimit(DEFMITER),
+ overwrite(DEFWRITE), t(nullTransform) {}
+
+ pen(const Transparency& transparency) :
+ line(DEFLINE), linewidth(DEFWIDTH), P(nullpath),
+ font(""), fontsize(0.0), lineskip(0.0), color(DEFCOLOR),
+ r(0), g(0), b(0), grey(0),
+ pattern(DEFPAT), fillrule(DEFFILL), baseline(DEFBASE),
+ transparency(transparency),
+ linecap(DEFCAP), linejoin(DEFJOIN), miterlimit(DEFMITER),
+ overwrite(DEFWRITE), t(nullTransform) {}
+
+ pen(setlinecap_t, Int linecap) :
+ line(DEFLINE), linewidth(DEFWIDTH), P(nullpath),
+ font(""), fontsize(0.0), lineskip(0.0), color(DEFCOLOR),
+ r(0), g(0), b(0), grey(0),
+ pattern(DEFPAT), fillrule(DEFFILL), baseline(DEFBASE),
+ transparency(DEFTRANSP),
+ linecap(linecap), linejoin(DEFJOIN), miterlimit(DEFMITER),
+ overwrite(DEFWRITE), t(nullTransform) {}
+
+ pen(setlinejoin_t, Int linejoin) :
+ line(DEFLINE), linewidth(DEFWIDTH), P(nullpath),
+ font(""), fontsize(0.0), lineskip(0.0), color(DEFCOLOR),
+ r(0), g(0), b(0), grey(0),
+ pattern(DEFPAT), fillrule(DEFFILL), baseline(DEFBASE),
+ transparency(DEFTRANSP),
+ linecap(DEFCAP), linejoin(linejoin), overwrite(DEFWRITE),
+ t(nullTransform) {}
+
+ pen(setmiterlimit_t, double miterlimit) :
+ line(DEFLINE), linewidth(DEFWIDTH), P(nullpath),
+ font(""), fontsize(0.0), lineskip(0.0), color(DEFCOLOR),
+ r(0), g(0), b(0), grey(0),
+ pattern(DEFPAT), fillrule(DEFFILL), baseline(DEFBASE),
+ transparency(DEFTRANSP),
+ linecap(DEFCAP), linejoin(DEFJOIN), miterlimit(miterlimit),
+ overwrite(DEFWRITE), t(nullTransform) {}
+
+ pen(setoverwrite_t, overwrite_t overwrite) :
+ line(DEFLINE), linewidth(DEFWIDTH), P(nullpath),
+ font(""), fontsize(0.0), lineskip(0.0), color(DEFCOLOR),
+ r(0), g(0), b(0), grey(0),
+ pattern(DEFPAT), fillrule(DEFFILL), baseline(DEFBASE),
+ transparency(DEFTRANSP),
+ linecap(DEFCAP), linejoin(DEFJOIN), miterlimit(DEFMITER),
+ overwrite(overwrite), t(nullTransform) {}
+
+ explicit pen(double grey) :
+ line(DEFLINE), linewidth(DEFWIDTH), P(nullpath),
+ font(""), fontsize(0.0), lineskip(0.0), color(GRAYSCALE),
+ r(0.0), g(0.0), b(0.0), grey(pos0(grey)),
+ pattern(DEFPAT), fillrule(DEFFILL), baseline(DEFBASE),
+ transparency(DEFTRANSP),
+ linecap(DEFCAP), linejoin(DEFJOIN), miterlimit(DEFMITER),
+ overwrite(DEFWRITE), t(nullTransform)
+ {greyrange();}
+
+ pen(double r, double g, double b) :
+ line(DEFLINE), linewidth(DEFWIDTH), P(nullpath),
+ font(""), fontsize(0.0), lineskip(0.0), color(RGB),
+ r(pos0(r)), g(pos0(g)), b(pos0(b)), grey(0.0),
+ pattern(DEFPAT), fillrule(DEFFILL), baseline(DEFBASE),
+ transparency(DEFTRANSP),
+ linecap(DEFCAP), linejoin(DEFJOIN), miterlimit(DEFMITER),
+ overwrite(DEFWRITE), t(nullTransform)
+ {rgbrange();}
+
+ pen(double c, double m, double y, double k) :
+ line(DEFLINE), linewidth(DEFWIDTH), P(nullpath),
+ font(""), fontsize(0.0), lineskip(0.0), color(CMYK),
+ r(pos0(c)), g(pos0(m)), b(pos0(y)), grey(pos0(k)),
+ pattern(DEFPAT), fillrule(DEFFILL), baseline(DEFBASE),
+ transparency(DEFTRANSP),
+ linecap(DEFCAP), linejoin(DEFJOIN), miterlimit(DEFMITER),
+ overwrite(DEFWRITE), t(nullTransform)
+ {cmykrange();}
+
+ // Construct one pen from another, resolving defaults
+ pen(resolvepen_t, const pen& p) :
+ line(LineType(p.stroke(),p.line.offset,p.line.scale,p.line.adjust)),
+ linewidth(p.width()), P(p.Path()),
+ font(p.Font()), fontsize(p.size()), lineskip(p.Lineskip()),
+ color(p.colorspace()),
+ r(p.red()), g(p.green()), b(p.blue()), grey(p.gray()),
+ pattern(""), fillrule(p.Fillrule()), baseline(p.Baseline()),
+ transparency(Transparency(p.blend(), p.opacity())),
+ linecap(p.cap()), linejoin(p.join()), miterlimit(p.miter()),
+ overwrite(p.Overwrite()), t(p.getTransform()) {}
+
+ static pen initialpen() {
+ return pen(LineType("",0,true,true),0.5,nullpath,"",12.0,12.0*1.2,
+ GRAYSCALE,
+ 0.0,0.0,0.0,0.0,"",ZEROWINDING,NOBASEALIGN,
+ DEFTRANSP,1,1,10.0,ALLOW,identity);
+ }
+
+ pen(initialpen_t) :
+ line(DEFLINE), linewidth(-2.0), P(nullpath),
+ font("<invalid>"), fontsize(-1.0), lineskip(-1.0), color(INVISIBLE),
+ r(0.0), g(0.0), b(0.0), grey(0.0),
+ pattern(DEFPAT), fillrule(DEFFILL), baseline(NOBASEALIGN),
+ transparency(DEFTRANSP),linecap(-2), linejoin(-2), miterlimit(-1.0),
+ overwrite(DEFWRITE), t(nullTransform) {}
+
+ double width() const {
+ return linewidth == DEFWIDTH ? defaultpen().linewidth : linewidth;
+ }
+
+ path Path() const {
+ return P.empty() ? defaultpen().P : P;
+ }
+
+ double size() const {
+ return fontsize == 0.0 ? defaultpen().fontsize : fontsize;
+ }
+
+ string Font() const {
+ if(font.empty()) {
+ if(defaultpen().font.empty())
+ if(settings::latex(settings::getSetting<string>("tex")))
+ return DEFLATEXFONT;
+ else {
+ ostringstream buf;
+ buf << "\\font\\ASYfont=" << DEFTEXFONT << " at " << size()
+ << "pt\\ASYfont";
+ return buf.str();
+ }
+ else return defaultpen().font;
+ }
+ return font;
+ }
+
+ double Lineskip() const {
+ return lineskip == 0.0 ? defaultpen().lineskip : lineskip;
+ }
+
+ string stroke() const {
+ return line == DEFLINE ? defaultpen().line.pattern : line.pattern;
+ }
+
+ LineType linetype() const {
+ return line == DEFLINE ? defaultpen().line : line;
+ }
+
+ void setstroke(const string& s) {line.pattern=s;}
+ void setoffset(const double& offset) {line.offset=offset;}
+
+ string fillpattern() const {
+ return pattern == DEFPAT ? (string)"" : pattern;
+ }
+
+ FillRule Fillrule() const {
+ return fillrule == DEFFILL ? defaultpen().fillrule : fillrule;
+ }
+
+ bool evenodd() const {
+ return Fillrule() == EVENODD;
+ }
+
+ bool inside(Int count) const {
+ return evenodd() ? count % 2 : count != 0;
+ }
+
+ BaseLine Baseline() const {
+ return baseline == DEFBASE ? defaultpen().baseline : baseline;
+ }
+
+ Transparency transp() const {
+ return transparency == DEFTRANSP ? defaultpen().transparency : transparency;
+ }
+
+ string blend() const {
+ return transparency == DEFTRANSP ? defaultpen().transparency.blend :
+ transparency.blend;
+ }
+
+ double opacity() const {
+ return transparency == DEFTRANSP ? defaultpen().transparency.opacity :
+ transparency.opacity;
+ }
+
+ Int cap() const {
+ return linecap == DEFCAP ? defaultpen().linecap : linecap;
+ }
+
+ Int join() const {
+ return linejoin == DEFJOIN ? defaultpen().linejoin : linejoin;
+ }
+
+ double miter() const {
+ return miterlimit == DEFMITER ? defaultpen().miterlimit : miterlimit;
+ }
+
+ overwrite_t Overwrite() const {
+ return overwrite == DEFWRITE ? defaultpen().overwrite : overwrite;
+ }
+
+ ColorSpace colorspace() const {
+ return color == DEFCOLOR ? defaultpen().color : color;
+ }
+
+ bool invisible() const {return colorspace() == INVISIBLE;}
+
+ bool grayscale() const {return colorspace() == GRAYSCALE;}
+
+ bool rgb() const {return colorspace() == RGB;}
+
+ bool cmyk() const {return colorspace() == CMYK;}
+
+ double gray() const {return color == DEFCOLOR ? defaultpen().grey : grey;}
+
+ double red() const {return color == DEFCOLOR ? defaultpen().r : r;}
+
+ double green() const {return color == DEFCOLOR ? defaultpen().g : g;}
+
+ double blue() const {return color == DEFCOLOR ? defaultpen().b : b;}
+
+ double cyan() const {return red();}
+
+ double magenta() const {return green();}
+
+ double yellow() const {return blue();}
+
+ double black() const {return gray();}
+
+ double rgbsaturation() const {return max(max(r,g),b);}
+
+ double cmyksaturation() const {return max(rgbsaturation(),black());}
+
+ void greytorgb() {
+ r=g=b=grey; grey=0.0;
+ color=RGB;
+ }
+
+ void rgbtogrey() {
+ grey=0.299*r+0.587*g+0.114*b; // Standard YUV luminosity coefficients
+ r=g=b=0.0;
+ color=GRAYSCALE;
+ }
+
+ void greytocmyk() {
+ grey=1.0-grey;
+ color=CMYK;
+ }
+
+ void rgbtocmyk() {
+ double sat=rgbsaturation();
+ grey=1.0-sat;
+ if(sat) {
+ double scale=1.0/sat;
+ r=1.0-r*scale;
+ g=1.0-g*scale;
+ b=1.0-b*scale;
+ }
+ color=CMYK;
+ }
+
+ void cmyktorgb() {
+ double sat=1.0-grey;
+ r=(1.0-r)*sat;
+ g=(1.0-g)*sat;
+ b=(1.0-b)*sat;
+ grey=0.0;
+ color=RGB;
+ }
+
+ void cmyktogrey() {
+ cmyktorgb();
+ rgbtogrey();
+ }
+
+ void togrey() {
+ if(rgb()) rgbtogrey();
+ else if(cmyk()) cmyktogrey();
+ }
+
+ void torgb() {
+ if(cmyk()) cmyktorgb();
+ else if(grayscale()) greytorgb();
+ }
+
+ void tocmyk() {
+ if(rgb()) rgbtocmyk();
+ else if(grayscale()) greytocmyk();
+ }
+
+ void settransparency(const pen& p) {
+ transparency=p.transparency;
+ }
+
+ void convert() {
+ if(settings::gray || settings::bw) {
+ if(rgb()) rgbtogrey();
+ else if(cmyk()) cmyktogrey();
+ if(settings::bw) {grey=(grey == 1.0) ? 1.0 : 0.0;}
+ }
+ else if(settings::rgb && cmyk()) cmyktorgb();
+ else if(settings::cmyk && rgb()) rgbtocmyk();
+ }
+
+ // Try to upgrade to the specified colorspace.
+ bool promote(ColorSpace c) {
+ if(color == c) return true;
+
+ switch(color) {
+ case PATTERN:
+ case INVISIBLE:
+ break;
+ case DEFCOLOR:
+ {
+ return true;
+ break;
+ }
+ break;
+ case GRAYSCALE:
+ {
+ if(c == RGB) {greytorgb(); return true;}
+ else if(c == CMYK) {greytocmyk(); return true;}
+ break;
+ }
+ case RGB:
+ {
+ if(c == CMYK) {rgbtocmyk(); return true;}
+ break;
+ }
+ case CMYK:
+ {
+ break;
+ }
+ }
+ return false;
+ }
+
+ friend pen operator * (double x, const pen& q) {
+ pen p=q;
+ if(x < 0.0) x = 0.0;
+ switch(p.color) {
+ case PATTERN:
+ case INVISIBLE:
+ case DEFCOLOR:
+ break;
+ case GRAYSCALE:
+ {
+ p.grey *= x;
+ p.greyrange();
+ break;
+ }
+ case RGB:
+ {
+ p.r *= x;
+ p.g *= x;
+ p.b *= x;
+ p.rgbrange();
+ break;
+ }
+ case CMYK:
+ {
+ p.r *= x;
+ p.g *= x;
+ p.b *= x;
+ p.grey *= x;
+ p.cmykrange();
+ break;
+ }
+ }
+ return p;
+ }
+
+ friend pen operator + (const pen& p, const pen& q) {
+ pen P=p;
+ pen Q=q;
+
+ if(P.color == PATTERN && P.pattern.empty()) P.color=DEFCOLOR;
+ ColorSpace colorspace=(ColorSpace) max((Int) P.color,(Int) Q.color);
+
+ if(!(p.transparency == DEFTRANSP && q.transparency == DEFTRANSP))
+ P.transparency.opacity=max(p.opacity(),q.opacity());
+
+ switch(colorspace) {
+ case PATTERN:
+ case INVISIBLE:
+ case DEFCOLOR:
+ break;
+ case GRAYSCALE:
+ {
+ P.grey += Q.grey;
+ P.greyrange();
+ break;
+ }
+
+ case RGB:
+ {
+ if(P.color == GRAYSCALE) P.greytorgb();
+ else if(Q.color == GRAYSCALE) Q.greytorgb();
+
+ P.r += Q.r;
+ P.g += Q.g;
+ P.b += Q.b;
+ P.rgbrange();
+ break;
+ }
+
+ case CMYK:
+ {
+ if(P.color == GRAYSCALE) P.greytocmyk();
+ else if(Q.color == GRAYSCALE) Q.greytocmyk();
+
+ if(P.color == RGB) P.rgbtocmyk();
+ else if(Q.color == RGB) Q.rgbtocmyk();
+
+ P.r += Q.r;
+ P.g += Q.g;
+ P.b += Q.b;
+ P.grey += Q.grey;
+ P.cmykrange();
+ break;
+ }
+ }
+
+ return pen(q.line == DEFLINE ? p.line : q.line,
+ q.linewidth == DEFWIDTH ? p.linewidth : q.linewidth,
+ q.P.empty() ? p.P : q.P,
+ q.font.empty() ? p.font : q.font,
+ q.fontsize == 0.0 ? p.fontsize : q.fontsize,
+ q.lineskip == 0.0 ? p.lineskip : q.lineskip,
+ colorspace,P.r,P.g,P.b,P.grey,
+ q.pattern == DEFPAT ? p.pattern : q.pattern,
+ q.fillrule == DEFFILL ? p.fillrule : q.fillrule,
+ q.baseline == DEFBASE ? p.baseline : q.baseline,
+ q.transparency == DEFTRANSP ? p.transparency : q.transparency,
+ q.linecap == DEFCAP ? p.linecap : q.linecap,
+ q.linejoin == DEFJOIN ? p.linejoin : q.linejoin,
+ q.miterlimit == DEFMITER ? p.miterlimit : q.miterlimit,
+ q.overwrite == DEFWRITE ? p.overwrite : q.overwrite,
+ q.t.isNull() ? p.t : q.t);
+ }
+
+ friend pen interpolate(const pen& p, const pen& q, double t) {
+ pen P=p;
+ pen Q=q;
+
+ if(P.color == PATTERN && P.pattern.empty()) P.color=DEFCOLOR;
+ ColorSpace colorspace=(ColorSpace) max((Int) P.color,(Int) Q.color);
+
+ switch(colorspace) {
+ case PATTERN:
+ case INVISIBLE:
+ case DEFCOLOR:
+ case GRAYSCALE:
+ break;
+ case RGB:
+ {
+ if(P.color == GRAYSCALE) P.greytorgb();
+ else if(Q.color == GRAYSCALE) Q.greytorgb();
+ break;
+ }
+
+ case CMYK:
+ {
+ if(P.color == GRAYSCALE) P.greytocmyk();
+ else if(Q.color == GRAYSCALE) Q.greytocmyk();
+
+ if(P.color == RGB) P.rgbtocmyk();
+ else if(Q.color == RGB) Q.rgbtocmyk();
+ break;
+ }
+ }
+
+ return (1-t)*P+t*Q;
+ }
+
+ friend bool operator == (const pen& p, const pen& q) {
+ return p.linetype() == q.linetype()
+ && p.width() == q.width()
+ && p.Path() == q.Path()
+ && p.Font() == q.Font()
+ && p.Lineskip() == q.Lineskip()
+ && p.size() == q.size()
+ && p.colorspace() == q.colorspace()
+ && (!(p.grayscale() || p.cmyk()) || p.gray() == q.gray())
+ && (!(p.rgb() || p.cmyk()) || (p.red() == q.red() &&
+ p.green() == q.green() &&
+ p.blue() == q.blue()))
+ && p.pattern == q.pattern
+ && p.Fillrule() == q.Fillrule()
+ && p.Baseline() == q.Baseline()
+ && p.transp() == q.transp()
+ && p.cap() == q.cap()
+ && p.join() == q.join()
+ && p.miter() == q.miter()
+ && p.Overwrite() == q.Overwrite()
+ && p.t == q.t;
+ }
+
+ friend bool operator != (const pen& p, const pen& q) {
+ return !(p == q);
+ }
+
+ friend ostream& operator << (ostream& out, const pen& p) {
+ out << "(";
+ if(p.line == DEFLINE)
+ out << p.line.pattern;
+ else
+ out << "[" << p.line.pattern << "]";
+ if(p.line.offset)
+ out << p.line.offset;
+ if(!p.line.scale)
+ out << " bp";
+ if(!p.line.adjust)
+ out << " fixed";
+ if(p.linewidth != DEFWIDTH)
+ out << ", linewidth=" << p.linewidth;
+ if(!p.P.empty())
+ out << ", path=" << p.P;
+ if(p.linecap != DEFCAP)
+ out << ", linecap=" << Cap[p.linecap];
+ if(p.linejoin != DEFJOIN)
+ out << ", linejoin=" << Join[p.linejoin];
+ if(p.miterlimit != DEFMITER)
+ out << ", miterlimit=" << p.miterlimit;
+ if(!p.font.empty())
+ out << ", font=\"" << p.font << "\"";
+ if(p.fontsize)
+ out << ", fontsize=" << p.fontsize;
+ if(p.lineskip)
+ out << ", lineskip=" << p.lineskip;
+ if(p.color == INVISIBLE)
+ out << ", invisible";
+ else if(p.color == GRAYSCALE)
+ out << ", gray=" << p.grey;
+ else if(p.color == RGB)
+ out << ", red=" << p.red() << ", green=" << p.green()
+ << ", blue=" << p.blue();
+ else if(p.color == CMYK)
+ out << ", cyan=" << p.cyan() << ", magenta=" << p.magenta()
+ << ", yellow=" << p.yellow() << ", black=" << p.black();
+ if(p.pattern != DEFPAT)
+ out << ", pattern=" << "\"" << p.pattern << "\"";
+ if(p.fillrule != DEFFILL)
+ out << ", fillrule=" << FillRuleTag[p.fillrule];
+ if(p.baseline != DEFBASE)
+ out << ", baseline=" << BaseLineTag[p.baseline];
+ if(!(p.transparency == DEFTRANSP)) {
+ out << ", opacity=" << p.transparency.opacity;
+ out << ", blend=" << p.transparency.blend;
+ }
+ if(p.overwrite != DEFWRITE)
+ out << ", overwrite=" << OverwriteTag[p.overwrite];
+ if(!p.t.isNull())
+ out << ", transform=" << p.t;
+ out << ")";
+
+ return out;
+ }
+
+ const transform getTransform() const {
+ return t.isNull() ? defaultpen().t : t;
+ }
+
+ // The bounds of the circle or ellipse the pen describes.
+ bbox bounds() const
+ {
+ double maxx, maxy;
+ pair shift;
+
+ if(!P.empty()) return P.bounds();
+
+ transform t=getTransform();
+
+ if(t.isIdentity()) {
+ maxx = 1;
+ maxy = 1;
+ shift = pair(0,0);
+ } else {
+ double xx = t.getxx(), xy = t.getxy(),
+ yx = t.getyx(), yy = t.getyy();
+
+ // These are the maximum x and y values that a linear transform can map
+ // a point in the unit circle. This can be proven by the Lagrange
+ // Multiplier theorem or by properties of the dot product.
+ maxx = length(pair(xx,xy));
+ maxy = length(pair(yx,yy));
+
+ shift = t*pair(0,0);
+ }
+
+ bbox b;
+ pair z=0.5*width()*pair(maxx,maxy);
+ b += z + shift;
+ b += -z + shift;
+
+ return b;
+ }
+
+ friend pen transformed(const transform& t, const pen& p) {
+ pen ret = p;
+ if(!p.P.empty()) ret.P = p.P.transformed(t);
+ ret.t = p.t.isNull() ? t : t*p.t;
+ return ret;
+ }
+
+};
+
+pen transformed(const transform& t, const pen &p);
+}
+
+#endif
diff --git a/Build/source/utils/asymptote/picture.cc b/Build/source/utils/asymptote/picture.cc
new file mode 100644
index 00000000000..cade08cceca
--- /dev/null
+++ b/Build/source/utils/asymptote/picture.cc
@@ -0,0 +1,869 @@
+/*****
+ * picture.cc
+ * Andy Hammerlindl 2002/06/06
+ *
+ * Stores a picture as a list of drawElements and handles its output to
+ * PostScript.
+ *****/
+
+#include "errormsg.h"
+#include "picture.h"
+#include "util.h"
+#include "settings.h"
+#include "interact.h"
+#include "drawverbatim.h"
+
+using std::ifstream;
+using std::ofstream;
+
+using namespace settings;
+using namespace gl;
+
+texstream::~texstream() {
+ string name=stripFile(outname())+"texput.";
+ unlink((name+"aux").c_str());
+ unlink((name+"log").c_str());
+ unlink((name+"out").c_str());
+ if(settings::pdf(getSetting<string>("tex")))
+ unlink((name+"pdf").c_str());
+}
+
+namespace camp {
+
+const char *texpathmessage() {
+ ostringstream buf;
+ buf << "the directory containing your " << getSetting<string>("tex")
+ << " engine (" << texcommand() << ")";
+ return Strdup(buf.str());
+}
+
+picture::~picture()
+{
+}
+
+bool picture::epsformat,picture::pdfformat,picture::xobject, picture::pdf;
+bool picture::Labels;
+double picture::paperWidth,picture::paperHeight;
+
+void picture::enclose(drawElement *begin, drawElement *end)
+{
+ assert(begin);
+ assert(end);
+ nodes.push_front(begin);
+ lastnumber=0;
+ lastnumber3=0;
+ for(nodelist::iterator p=nodes.begin(); p != nodes.end(); ++p) {
+ assert(*p);
+ if((*p)->islayer()) {
+ nodes.insert(p,end);
+ ++p;
+ while(p != nodes.end() && (*p)->islayer()) ++p;
+ if(p == nodes.end()) return;
+ nodes.insert(p,begin);
+ }
+ }
+ nodes.push_back(end);
+}
+
+// Insert at beginning of picture.
+void picture::prepend(drawElement *p)
+{
+ assert(p);
+ nodes.push_front(p);
+ lastnumber=0;
+ lastnumber3=0;
+}
+
+void picture::append(drawElement *p)
+{
+ assert(p);
+ nodes.push_back(p);
+}
+
+void picture::add(picture &pic)
+{
+ if (&pic == this) return;
+
+ // STL's funny way of copying one list into another.
+ copy(pic.nodes.begin(), pic.nodes.end(), back_inserter(nodes));
+}
+
+// Insert picture pic at beginning of picture.
+void picture::prepend(picture &pic)
+{
+ if (&pic == this) return;
+
+ copy(pic.nodes.begin(), pic.nodes.end(), inserter(nodes, nodes.begin()));
+ lastnumber=0;
+ lastnumber3=0;
+}
+
+bool picture::havelabels()
+{
+ size_t n=nodes.size();
+ if(n > lastnumber && !labels && getSetting<string>("tex") != "none") {
+ // Check to see if there are any labels yet
+ nodelist::iterator p=nodes.begin();
+ for(size_t i=0; i < lastnumber; ++i) ++p;
+ for(; p != nodes.end(); ++p) {
+ assert(*p);
+ if((*p)->islabel()) {
+ labels=true;
+ break;
+ }
+ }
+ }
+ return labels;
+}
+
+bool picture::have3D()
+{
+ for(nodelist::iterator p=nodes.begin(); p != nodes.end(); ++p) {
+ assert(*p);
+ if((*p)->is3D())
+ return true;
+ }
+ return false;
+}
+
+bbox picture::bounds()
+{
+ size_t n=nodes.size();
+ if(n == lastnumber) return b_cached;
+
+ if(lastnumber == 0) { // Maybe these should be put into a structure.
+ b_cached=bbox();
+ labelbounds.clear();
+ bboxstack.clear();
+ }
+
+ if(havelabels()) texinit();
+
+ nodelist::iterator p=nodes.begin();
+ for(size_t i=0; i < lastnumber; ++i) ++p;
+ for(; p != nodes.end(); ++p) {
+ assert(*p);
+ (*p)->bounds(b_cached,processData().tex,labelbounds,bboxstack);
+
+ // Optimization for interpreters with fixed stack limits.
+ if((*p)->endclip()) {
+ nodelist::iterator q=p;
+ if(q != nodes.begin()) {
+ --q;
+ assert(*q);
+ if((*q)->endclip())
+ (*q)->save(false);
+ }
+ }
+ }
+
+ lastnumber=n;
+ return b_cached;
+}
+
+bbox3 picture::bounds3()
+{
+ size_t n=nodes.size();
+ if(n == lastnumber3) return b3;
+
+ if(lastnumber3 == 0)
+ b3=bbox3();
+
+ nodelist::iterator p=nodes.begin();
+ for(size_t i=0; i < lastnumber3; ++i) ++p;
+ for(; p != nodes.end(); ++p) {
+ assert(*p);
+ (*p)->bounds(b3);
+ }
+
+ lastnumber3=n;
+ return b3;
+}
+
+pair picture::bounds(double (*m)(double, double),
+ double (*x)(const triple&, double*),
+ double (*y)(const triple&, double*),
+ double *t)
+{
+ bool first=true;
+ pair b;
+ for(nodelist::const_iterator p=nodes.begin(); p != nodes.end(); ++p) {
+ assert(*p);
+ (*p)->bounds(b,m,x,y,t,first);
+ }
+ return b;
+}
+
+void picture::texinit()
+{
+ drawElement::lastpen=pen(initialpen);
+ processDataStruct &pd=processData();
+ // Output any new texpreamble commands
+ if(pd.tex.isopen()) {
+ if(pd.TeXpipepreamble.empty()) return;
+ texpreamble(pd.tex,pd.TeXpipepreamble,false);
+ pd.TeXpipepreamble.clear();
+ return;
+ }
+
+ string name=stripFile(outname())+"texput.aux";
+ const char *cname=name.c_str();
+ ofstream writeable(cname);
+ if(!writeable)
+ reportError("Cannot write to "+name);
+ else
+ writeable.close();
+ unlink(cname);
+
+ ostringstream cmd;
+ cmd << texprogram() << " \\scrollmode";
+ pd.tex.open(cmd.str().c_str(),"texpath",texpathmessage());
+ pd.tex.wait("\n*");
+ pd.tex << "\n";
+ texdocumentclass(pd.tex,true);
+
+ texdefines(pd.tex,pd.TeXpreamble,true);
+ pd.TeXpipepreamble.clear();
+}
+
+bool picture::texprocess(const string& texname, const string& outname,
+ const string& prefix, const pair& bboxshift)
+{
+ int status=0;
+ ifstream outfile;
+
+ outfile.open(texname.c_str());
+ if(outfile) {
+ outfile.close();
+ string aux=auxname(prefix,"aux");
+ unlink(aux.c_str());
+ string program=texprogram();
+ ostringstream cmd;
+ cmd << program << " \\nonstopmode\\input '" << texname << "'";
+ bool quiet=verbose <= 1;
+ status=System(cmd,quiet ? 1 : 0,"texpath",texpathmessage());
+ if(!status && getSetting<bool>("twice"))
+ status=System(cmd,quiet ? 1 : 0,"texpath",texpathmessage());
+ if(status) {
+ if(quiet) {
+ ostringstream cmd;
+ cmd << program << " \\scrollmode\\input '" << texname << "'";
+ System(cmd,0);
+ }
+ return false;
+ }
+
+ if(!pdf) {
+ string dviname=auxname(prefix,"dvi");
+ string psname=auxname(prefix,"ps");
+
+ double height=b.top-b.bottom+1.0;
+
+ // Magic dvips offsets:
+ double hoffset=-128.4;
+ double vertical=height;
+ if(!latex(getSetting<string>("tex"))) vertical += 2.0;
+ double voffset=(vertical < 13.0) ? -137.8+vertical : -124.8;
+
+ hoffset += b.left+bboxshift.getx();
+ voffset += paperHeight-height-b.bottom-bboxshift.gety();
+
+ ostringstream dcmd;
+
+ string dvipsrc=getSetting<string>("dir");
+ if(dvipsrc.empty()) dvipsrc=systemDir;
+ dvipsrc += dirsep+"nopapersize.ps";
+ setenv("DVIPSRC",dvipsrc.c_str(),1);
+ string papertype=getSetting<string>("papertype") == "letter" ?
+ "letterSize" : "a4size";
+ dcmd << "'" << getSetting<string>("dvips") << "' -R -Pdownload35 -D600"
+ << " -O" << hoffset << "bp," << voffset << "bp"
+ << " -T" << paperWidth << "bp," << paperHeight << "bp "
+ << getSetting<string>("dvipsOptions") << " -t" << papertype;
+ if(verbose <= 1) dcmd << " -q";
+ dcmd << " -o '" << psname << "' '" << dviname << "'";
+ status=System(dcmd,0,true,"dvips");
+ if(status != 0) return false;
+
+ ifstream fin(psname.c_str());
+ psfile fout(outname,false);
+
+ string s;
+ bool first=true;
+ transform t=shift(bboxshift)*T;
+ bool shift=!t.isIdentity();
+ string beginspecial="TeXDict begin @defspecial";
+ string endspecial="@fedspecial end";
+ while(getline(fin,s)) {
+ if(s.find("%%DocumentPaperSizes:") == 0) continue;
+ if(s.find("%!PS-Adobe-") == 0) {
+ fout.header();
+ } else if(first && s.find("%%BoundingBox:") == 0) {
+ bbox box=b;
+ box.shift(bboxshift);
+ if(verbose > 2) BoundingBox(cout,box);
+ fout.BoundingBox(box);
+ first=false;
+ } else if(shift && s.find(beginspecial) == 0) {
+ fout.verbatimline(s);
+ fout.gsave();
+ fout.concat(t);
+ } else if(shift && s.find(endspecial) == 0) {
+ fout.grestore();
+ fout.verbatimline(s);
+ } else
+ fout.verbatimline(s);
+ }
+ if(!getSetting<bool>("keep")) { // Delete temporary files.
+ unlink(dviname.c_str());
+ unlink(psname.c_str());
+ }
+ }
+
+ if(!getSetting<bool>("keep")) { // Delete temporary files.
+ unlink(texname.c_str());
+ if(!getSetting<bool>("keepaux"))
+ unlink(aux.c_str());
+ unlink(auxname(prefix,"log").c_str());
+ unlink(auxname(prefix,"out").c_str());
+ }
+ if(status == 0) return true;
+ }
+ return false;
+}
+
+int picture::epstopdf(const string& epsname, const string& pdfname)
+{
+ ostringstream cmd;
+
+ cmd << "'" << getSetting<string>("gs")
+ << "' -q -dNOPAUSE -dBATCH -sDEVICE=pdfwrite -dEPSCrop"
+ << " -dSubsetFonts=true -dEmbedAllFonts=true -dMaxSubsetPct=100"
+ << " -dPDFSETTINGS=/prepress -dCompatibilityLevel=1.4";
+ if(safe)
+ cmd << " -dSAFER";
+ if(!getSetting<bool>("autorotate"))
+ cmd << " -dAutoRotatePages=/None";
+ cmd << " -g" << max(ceil(paperWidth),1.0) << "x" << max(ceil(paperHeight),1.0)
+ << " -dDEVICEWIDTHPOINTS=" << max(b.right-b.left,3.0)
+ << " -dDEVICEHEIGHTPOINTS=" << max(b.top-b.bottom,3.0)
+ << " " << getSetting<string>("gsOptions")
+ << " -sOutputFile='" << stripDir(pdfname) << "' '"
+ << stripDir(epsname) << "'";
+
+ string dir=stripFile(pdfname);
+ char *oldPath=NULL;
+ if(!dir.empty()) {
+ oldPath=getPath();
+ setPath(dir.c_str());
+ }
+ int status=System(cmd,0,true,"gs","Ghostscript");
+ if(oldPath != NULL)
+ setPath(oldPath);
+ return status;
+}
+
+bool picture::reloadPDF(const string& Viewer, const string& outname) const
+{
+ static bool needReload=true;
+ static bool haveReload=false;
+
+ // Send javascript code to redraw picture.
+ picture f;
+ string name=getPath()+string("/")+outname;
+ f.append(new drawVerbatim(TeX,"\\ \\pdfannot width 0pt height 0pt { /AA << /PO << /S /JavaScript /JS (try{reload('"+
+ name+"');} catch(e) {} closeDoc(this);) >> >> }"));
+ string reloadprefix="reload";
+ if(needReload) {
+ needReload=false;
+ string texengine=getSetting<string>("tex");
+ Setting("tex")=string("pdflatex");
+ haveReload=f.shipout(NULL,reloadprefix,"pdf",0.0,false,false);
+ Setting("tex")=texengine;
+ }
+ if(haveReload) {
+ ostringstream cmd;
+ cmd << "'" << Viewer << "' ";
+ string pdfreloadOptions=getSetting<string>("pdfreloadOptions");
+ if(!pdfreloadOptions.empty())
+ cmd << pdfreloadOptions << " ";
+ cmd << "'" << reloadprefix << ".pdf'";
+ System(cmd,0,false);
+ }
+ return true;
+}
+
+
+bool picture::postprocess(const string& prename, const string& outname,
+ const string& outputformat, double magnification,
+ bool wait, bool view)
+{
+ static mem::map<CONST string,int> pids;
+ int status=0;
+
+ if((pdf && Labels) || !epsformat) {
+ if(pdfformat) {
+ if(pdf && Labels) {
+ status=rename(prename.c_str(),outname.c_str());
+ if(status != 0)
+ reportError("Cannot rename "+prename+" to "+outname);
+ } else status=epstopdf(prename,outname);
+ } else {
+ ostringstream cmd;
+ double render=fabs(getSetting<double>("render"));
+ if(render == 0) render=1.0;
+ double expand=getSetting<Int>("antialias");
+ if(expand < 2.0) expand=1.0;
+ double res=expand*render*72.0;
+ cmd << "'" << getSetting<string>("convert")
+ << "' -alpha Off -density " << res << "x" << res;
+ if(expand == 1.0)
+ cmd << " +antialias";
+ cmd << " -geometry " << 100.0/expand << "%x"
+ << " " << getSetting<string>("convertOptions")
+ << " '" << nativeformat()+":" << prename << "'"
+ << " '" << outputformat << ":" << outname << "'";
+ status=System(cmd,0,true,"convert");
+ }
+ if(!getSetting<bool>("keep")) unlink(prename.c_str());
+ }
+ if(status != 0) return false;
+
+ if(verbose > 0)
+ cout << "Wrote " << outname << endl;
+ bool View=settings::view() && view;
+ if(View) {
+ if(epsformat || pdfformat) {
+ // Check to see if there is an existing viewer for this outname.
+ mem::map<CONST string,int>::iterator p=pids.find(outname);
+ bool running=(p != pids.end());
+ string Viewer=pdfformat ? getSetting<string>("pdfviewer") :
+ getSetting<string>("psviewer");
+ int pid;
+ if(running) {
+ pid=p->second;
+ if(pid)
+ running=(waitpid(pid, &status, WNOHANG) != pid);
+ }
+
+ bool pdfreload=pdfformat && getSetting<bool>("pdfreload");
+ if(running) {
+ // Tell gv/acroread to reread file.
+ if(Viewer == "gv") kill(pid,SIGHUP);
+ else if(pdfreload) reloadPDF(Viewer,outname);
+ } else {
+ ostringstream cmd;
+ cmd << "'" << Viewer << "' ";
+ string viewerOptions=getSetting<string>(pdfformat ?
+ "pdfviewerOptions" :
+ "psviewerOptions");
+ if(!viewerOptions.empty())
+ cmd << viewerOptions << " ";
+ cmd << "'" << outname << "'";
+ status=System(cmd,0,wait,
+ pdfformat ? "pdfviewer" : "psviewer",
+ pdfformat ? "your PDF viewer" : "your PostScript viewer",
+ &pid);
+ if(status != 0) return false;
+
+ if(!wait) pids[outname]=pid;
+
+ if(pdfreload) {
+ // Work around race conditions in acroread initialization script
+ usleep(getSetting<Int>("pdfreloaddelay"));
+ // Only reload if pdf viewer process is already running.
+ if(waitpid(pid, &status, WNOHANG) == pid)
+ reloadPDF(Viewer,outname);
+ }
+ }
+ } else {
+ ostringstream cmd;
+ cmd << "'" << getSetting<string>("display") << "' '"
+ << outname << "'";
+ string application="your "+outputformat+" viewer";
+ status=System(cmd,0,wait,"display",application.c_str());
+ if(status != 0) return false;
+ }
+ }
+
+ return true;
+}
+
+string Outname(const string& prefix, const string& outputformat,
+ bool standardout)
+{
+ return standardout ? "-" : buildname(prefix,outputformat,"");
+}
+
+bool picture::shipout(picture *preamble, const string& Prefix,
+ const string& format, double magnification,
+ bool wait, bool view)
+{
+ b=bounds();
+
+ bool TeXmode=getSetting<bool>("inlinetex") &&
+ getSetting<string>("tex") != "none";
+ Labels=labels || TeXmode;
+
+ pdf=settings::pdf(getSetting<string>("tex"));
+
+ bool standardout=Prefix == "-";
+ string prefix=standardout ? "out" : Prefix;
+ string preformat=nativeformat();
+ string outputformat=format.empty() ? defaultformat() : format;
+ epsformat=outputformat == "eps";
+ pdfformat=outputformat == "pdf";
+ xobject=magnification > 0;
+ string outname=Outname(prefix,outputformat,standardout);
+ string epsname=epsformat ? (standardout ? "" : outname) :
+ auxname(prefix,"eps");
+ if(Labels)
+ spaceToUnderscore(prefix);
+ string prename=((epsformat && !pdf) || !Labels) ? epsname :
+ auxname(prefix,preformat);
+
+ if((b.empty && !Labels)) { // Output a null file
+ bbox b;
+ b.left=b.bottom=0;
+ b.right=b.top=xobject ? 18 : 1;
+ psfile out(epsname,false);
+ out.prologue(b);
+ out.epilogue();
+ out.close();
+ return postprocess(epsname,outname,outputformat,1.0,wait,view);
+ }
+
+ bool pngxformat=xobject && getSetting<string>("xformat") == "png";
+ if(pngxformat) {
+ // Work around half-pixel bounding box bug in Ghostscript pngalpha driver
+ double fuzz=0.5/magnification;
+ b.top += fuzz;
+ b.right += fuzz;
+ b.bottom -= fuzz;
+ }
+
+ SetPageDimensions();
+
+ paperWidth=getSetting<double>("paperwidth");
+ paperHeight=getSetting<double>("paperheight");
+ Int origin=getSetting<Int>("align");
+
+ pair bboxshift=(origin == ZERO && !pdfformat) ?
+ pair(0.0,0.0) : pair(-b.left,-b.bottom);
+ if(!pdfformat) {
+ bboxshift += getSetting<pair>("offset");
+ if(origin != ZERO && origin != BOTTOM) {
+ double yexcess=max(paperHeight-(b.top-b.bottom+1.0),0.0);
+ if(origin == TOP) bboxshift += pair(0.0,yexcess);
+ else {
+ double xexcess=max(paperWidth-(b.right-b.left+1.0),0.0);
+ bboxshift += pair(0.5*xexcess,0.5*yexcess);
+ }
+ }
+ }
+
+ bool status=true;
+
+ string texname;
+ texfile *tex=NULL;
+
+ if(Labels) {
+ texname=auxname(prefix,"tex");
+ tex=new texfile(texname,b);
+ tex->prologue();
+ }
+
+ nodelist::iterator layerp=nodes.begin();
+ nodelist::iterator p=layerp;
+ unsigned layer=0;
+ mem::list<string> psnameStack;
+
+ bbox bshift=b;
+
+ transparency=false;
+
+ while(p != nodes.end()) {
+ string psname,pdfname;
+ if(Labels) {
+ ostringstream buf;
+ buf << prefix << "_" << layer;
+ psname=buildname(buf.str(),"eps");
+ if(pdf) pdfname=buildname(buf.str(),"pdf");
+ } else {
+ psname=epsname;
+ bshift.shift(bboxshift);
+ }
+ psnameStack.push_back(psname);
+ if(pdf) psnameStack.push_back(pdfname);
+ psfile out(psname,pdfformat);
+ out.prologue(bshift);
+
+ if(!Labels) {
+ out.gsave();
+ out.translate(bboxshift);
+ }
+
+ if(preamble) {
+ // Postscript preamble.
+ nodelist Nodes=preamble->nodes;
+ nodelist::iterator P=Nodes.begin();
+ if(P != Nodes.end()) {
+ out.resetpen();
+ for(; P != Nodes.end(); ++P) {
+ assert(*P);
+ (*P)->draw(&out);
+ }
+ }
+ }
+ out.resetpen();
+
+ bool postscript=false;
+ for(; p != nodes.end(); ++p) {
+ assert(*p);
+ if(Labels && (*p)->islayer()) break;
+ postscript |= (*p)->draw(&out);
+ }
+
+ if(Labels) {
+ tex->beginlayer(pdf ? pdfname : psname,postscript);
+ } else out.grestore();
+
+ out.epilogue();
+ out.close();
+
+ if(out.Transparency())
+ transparency=true;
+
+ if(Labels) {
+ tex->resetpen();
+ if(pdf && !b.empty) {
+ status=(epstopdf(psname,pdfname) == 0);
+ if(!getSetting<bool>("keep")) unlink(psname.c_str());
+ }
+
+ if(status) {
+ for (p=layerp; p != nodes.end(); ++p) {
+ assert(*p);
+ (*p)->write(tex,b);
+ if((*p)->islayer()) {
+ tex->endlayer();
+ layerp=++p;
+ layer++;
+ break;
+ }
+ }
+ }
+ }
+ }
+
+ if(status) {
+ if(TeXmode) {
+ if(Labels && verbose > 0) cout << "Wrote " << texname << endl;
+ delete tex;
+ } else {
+ if(Labels) {
+ tex->epilogue();
+ status=texprocess(texname,prename,prefix,bboxshift);
+ delete tex;
+ if(!getSetting<bool>("keep")) {
+ for(mem::list<string>::iterator p=psnameStack.begin();
+ p != psnameStack.end(); ++p)
+ unlink(p->c_str());
+ }
+ }
+ if(status) {
+ if(xobject) {
+ if(transparency && pngxformat)
+ status=(epstopdf(prename,Outname(prefix,"pdf",standardout)) == 0);
+ } else
+ status=postprocess(prename,outname,outputformat,magnification,wait,
+ view);
+ }
+ }
+ }
+
+ if(!status) reportError("shipout failed");
+
+ return true;
+}
+
+// render viewport with width x height pixels.
+void picture::render(GLUnurbs *nurb, double size2,
+ const triple& Min, const triple& Max,
+ double perspective, bool transparent) const
+{
+ for(nodelist::const_iterator p=nodes.begin(); p != nodes.end(); ++p) {
+ assert(*p);
+ (*p)->render(nurb,size2,Min,Max,perspective,transparent);
+ }
+}
+
+struct Communicate : public gc {
+ string prefix;
+ picture* pic;
+ string format;
+ double width;
+ double height;
+ double angle;
+ triple m;
+ triple M;
+ double *t;
+ size_t nlights;
+ triple *lights;
+ double *diffuse;
+ double *ambient;
+ double *specular;
+ bool viewportlighting;
+ bool view;
+};
+
+Communicate com;
+
+void glrenderWrapper()
+{
+#ifdef HAVE_LIBGL
+ glrender(com.prefix,com.pic,com.format,com.width,com.height,com.angle,
+ com.m,com.M,com.t,com.nlights,com.lights,com.diffuse,com.ambient,
+ com.specular,com.viewportlighting,com.view);
+#endif
+}
+
+extern bool glinitialize;
+
+bool picture::shipout3(const string& prefix, const string& format,
+ double width, double height,
+ double angle, const triple& m, const triple& M,
+ double *t, size_t nlights, triple *lights,
+ double *diffuse, double *ambient, double *specular,
+ bool viewportlighting, bool view)
+{
+#ifdef HAVE_LIBGL
+ bounds3();
+
+ for(nodelist::const_iterator p=nodes.begin(); p != nodes.end(); ++p) {
+ assert(*p);
+ (*p)->displacement();
+ }
+
+ const string outputformat=format.empty() ?
+ getSetting<string>("outformat") : format;
+ bool View=settings::view() && view;
+ static int oldpid=0;
+
+ if(glthread) {
+#ifdef HAVE_LIBPTHREAD
+ if(gl::initialize) {
+ gl::initialize=false;
+ com.prefix=prefix;
+ com.pic=this;
+ com.format=outputformat;
+ com.width=width;
+ com.height=height;
+ com.angle=angle;
+ com.m=m;
+ com.M=M;
+ com.t=t;
+ com.nlights=nlights;
+ com.lights=lights;
+ com.diffuse=diffuse;
+ com.ambient=ambient;
+ com.specular=specular;
+ com.viewportlighting=viewportlighting;
+ com.view=View;
+ wait(initSignal,initLock);
+#ifdef HAVE_LIBPTHREAD
+ if(!View)
+ wait(readySignal,readyLock);
+
+ if(!interact::interactive || !View)
+ wait(quitSignal,quitLock);
+#endif
+ return true;
+ }
+#endif
+ } else {
+ int pid=fork();
+ if(pid == -1)
+ camp::reportError("Cannot fork process");
+ if(pid != 0) {
+ oldpid=pid;
+ waitpid(pid,NULL,interact::interactive && View ? WNOHANG : 0);
+ return true;
+ }
+ }
+
+#ifdef HAVE_LIBPTHREAD
+ if(glthread && !interact::interactive)
+ pthread_mutex_lock(&quitLock);
+#endif
+ glrender(prefix,this,outputformat,width,height,angle,m,M,t,
+ nlights,lights,diffuse,ambient,specular,viewportlighting,View,
+ oldpid);
+#ifdef HAVE_LIBPTHREAD
+ if(glthread) {
+ if(!View)
+ wait(readySignal,readyLock);
+
+ if(!interact::interactive) {
+ pthread_cond_wait(&quitSignal,&quitLock);
+ pthread_mutex_unlock(&quitLock);
+ }
+ }
+ return true;
+#endif
+#else
+ reportError("Cannot render image; please install glut, run ./configure, and recompile");
+#endif
+ return false;
+}
+
+bool picture::shipout3(const string& prefix)
+{
+ bounds3();
+ bool status = true;
+
+ string prcname=buildname(prefix,"prc");
+ prcfile prc(prcname);
+ for(nodelist::iterator p=nodes.begin(); p != nodes.end(); ++p) {
+ assert(*p);
+ (*p)->write(&prc);
+ }
+ if(status)
+ status=prc.finish();
+
+ if(!status) reportError("shipout3 failed");
+
+ if(verbose > 0) cout << "Wrote " << prcname << endl;
+
+ return true;
+}
+
+picture *picture::transformed(const transform& t)
+{
+ picture *pic = new picture;
+
+ nodelist::iterator p;
+ for (p = nodes.begin(); p != nodes.end(); ++p) {
+ assert(*p);
+ pic->append((*p)->transformed(t));
+ }
+ pic->T=transform(t*T);
+
+ return pic;
+}
+
+picture *picture::transformed(const vm::array& t)
+{
+ picture *pic = new picture;
+
+ nodelist::iterator p;
+ for (p = nodes.begin(); p != nodes.end(); ++p) {
+ assert(*p);
+ pic->append((*p)->transformed(t));
+ }
+
+ return pic;
+}
+
+
+} // namespace camp
diff --git a/Build/source/utils/asymptote/picture.h b/Build/source/utils/asymptote/picture.h
new file mode 100644
index 00000000000..59ce0369c34
--- /dev/null
+++ b/Build/source/utils/asymptote/picture.h
@@ -0,0 +1,127 @@
+/*****
+ * picture.h
+ * Andy Hamerlindl 2002/06/06
+ *
+ * Stores a picture as a list of drawElements and handles its output to
+ * PostScript.
+ *****/
+
+#ifndef PICTURE_H
+#define PICTURE_H
+
+#include <sstream>
+#include <iostream>
+
+#include "drawelement.h"
+
+namespace camp {
+
+class picture : public gc {
+private:
+ bool labels;
+ size_t lastnumber;
+ size_t lastnumber3;
+ transform T; // Keep track of accumulative picture transform
+ bbox b;
+ bbox b_cached; // Cached bounding box
+ boxvector labelbounds;
+ bboxlist bboxstack;
+ bool transparency;
+
+ static bool epsformat,pdfformat,xobject,pdf,Labels;
+ static double paperWidth,paperHeight;
+
+public:
+ bbox3 b3; // 3D bounding box
+
+ typedef mem::list<drawElement*> nodelist;
+ nodelist nodes;
+
+ picture() : labels(false), lastnumber(0), lastnumber3(0), T(identity),
+ transparency(false) {}
+
+ // Destroy all of the owned picture objects.
+ ~picture();
+
+ // Prepend an object to the picture.
+ void prepend(drawElement *p);
+
+ // Append an object to the picture.
+ void append(drawElement *p);
+
+ // Enclose each layer with begin and end.
+ void enclose(drawElement *begin, drawElement *end);
+
+ // Add the content of another picture.
+ void add(picture &pic);
+ void prepend(picture &pic);
+
+ bool havelabels();
+ bool have3D();
+
+ bbox bounds();
+ bbox3 bounds3();
+
+ // Projected bounds of 3d picture given transform3 t (not cached).
+ pair bounds(double (*m)(double, double),
+ double (*x)(const triple&, double*),
+ double (*y)(const triple&, double*),
+ double *t=NULL);
+
+ void texinit();
+
+ bool Transparency() {
+ return transparency;
+ }
+
+ int epstopdf(const string& epsname, const string& pdfname);
+
+ bool texprocess(const string& texname, const string& tempname,
+ const string& prefix, const pair& bboxshift);
+
+ bool postprocess(const string& prename, const string& outname,
+ const string& outputformat, double magnification,
+ bool wait, bool view);
+
+ // Ship the picture out to PostScript & TeX files.
+ bool shipout(picture* preamble, const string& prefix,
+ const string& format, double magnification=0.0,
+ bool wait=false, bool view=true);
+
+ void render(GLUnurbs *nurb, double size2,
+ const triple &Min, const triple& Max, double perspective,
+ bool transparent) const;
+ bool shipout3(const string& prefix, const string& format,
+ double width, double height, double angle, const triple& m,
+ const triple& M, double *t, size_t nlights, triple *lights,
+ double *diffuse, double *ambient, double *specular,
+ bool viewportlighting, bool view);
+
+ bool shipout3(const string& prefix); // Embedded PRC
+
+ bool reloadPDF(const string& Viewer, const string& outname) const;
+
+ picture *transformed(const transform& t);
+ picture *transformed(const vm::array& t);
+
+ bool null() {
+ return nodes.empty();
+ }
+
+};
+
+inline picture *transformed(const transform& t, picture *p)
+{
+ return p->transformed(t);
+}
+
+inline picture *transformed(const vm::array& t, picture *p)
+{
+ return p->transformed(t);
+}
+
+const char *texpathmessage();
+
+} //namespace camp
+
+#endif
diff --git a/Build/source/utils/asymptote/pipestream.h b/Build/source/utils/asymptote/pipestream.h
new file mode 100644
index 00000000000..ee8193635c3
--- /dev/null
+++ b/Build/source/utils/asymptote/pipestream.h
@@ -0,0 +1,262 @@
+/* Pipestream: A simple C++ interface to UNIX pipes
+ Version 0.03
+ Copyright (C) 2005-2009 John C. Bowman
+
+ This program 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 3 of the License, or
+ (at your option) any later version.
+
+ This program 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 program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#ifndef PIPESTREAM_H
+#define PIPESTREAM_H
+
+#include <iostream>
+#include <cstring>
+#include <sys/wait.h>
+#include <cerrno>
+#include <sstream>
+#include <unistd.h>
+#include <signal.h>
+
+#include "common.h"
+#include "errormsg.h"
+#include "settings.h"
+#include "util.h"
+#include "interact.h"
+
+// bidirectional stream for reading and writing to pipes
+class iopipestream {
+protected:
+ int in[2];
+ int out[2];
+ static const int BUFSIZE=SHRT_MAX;
+ char buffer[BUFSIZE];
+ int pid;
+ bool pipeopen;
+ ostringstream transcript;
+public:
+
+ void clear() {
+ transcript << buffer;
+ *buffer=0;
+ }
+
+ void shred() {
+ transcript.str("");
+ }
+
+ const string message() const {
+ return transcript.str();
+ }
+
+ void open(const char *command, const char *hint=NULL,
+ const char *application="", int out_fileno=STDOUT_FILENO) {
+ if(pipe(in) == -1) {
+ ostringstream buf;
+ buf << "in pipe failed: " << command << endl;
+ camp::reportError(buf);
+ }
+
+ if(pipe(out) == -1) {
+ ostringstream buf;
+ buf << "out pipe failed: " << command << endl;
+ camp::reportError(buf);
+ }
+ cout.flush(); // Flush stdout to avoid duplicate output.
+
+ int wrapperpid;
+
+ // Portable way of forking that avoids zombie child processes
+ if((wrapperpid=fork()) < 0) {
+ cerr << "fork failed: " << command << endl;
+ exit(-1);
+ }
+
+ if(wrapperpid == 0) {
+ if((pid=fork()) < 0) {
+ ostringstream buf;
+ buf << "fork failed: " << command << endl;
+ camp::reportError(buf);
+ }
+
+ if(pid == 0) {
+ if(interact::interactive) signal(SIGINT,SIG_IGN);
+ close(in[1]);
+ close(out[0]);
+ close(STDIN_FILENO);
+ close(out_fileno);
+ dup2(in[0],STDIN_FILENO);
+ dup2(out[1],out_fileno);
+ close(in[0]);
+ close(out[1]);
+ char **argv=args(command);
+ if(argv) execvp(argv[0],argv);
+ execError(command,hint,application);
+ kill(0,SIGTERM);
+ _exit(-1);
+ }
+ _exit(0);
+ } else {
+ close(out[1]);
+ close(in[0]);
+ *buffer=0;
+ pipeopen=true;
+ waitpid(wrapperpid,NULL,0);
+ }
+ }
+
+ bool isopen() {return pipeopen;}
+
+ iopipestream(): pid(0), pipeopen(false) {}
+
+ iopipestream(const char *command, const char *hint=NULL,
+ const char *application="", int out_fileno=STDOUT_FILENO) :
+ pid(0), pipeopen(false) {
+ open(command,hint,application,out_fileno);
+ }
+
+ virtual void pipeclose() {
+ if(pipeopen) {
+ close(in[1]);
+ close(out[0]);
+ pipeopen=false;
+ }
+ }
+
+ virtual ~iopipestream() {
+ pipeclose();
+ }
+
+ ssize_t readbuffer() {
+ ssize_t nc;
+ char *p=buffer;
+ ssize_t size=BUFSIZE-1;
+ for(;;) {
+ if((nc=read(out[0],p,size)) < 0)
+ camp::reportError("read from pipe failed");
+ p[nc]=0;
+ if(nc == 0) break;
+ if(nc > 0) {
+ if(settings::verbose > 2) cerr << p;
+ if(strchr(p,'\n')) break;
+ p += nc;
+ size -= nc;
+ }
+ }
+ return p+nc-buffer;
+ }
+
+ typedef iopipestream& (*imanip)(iopipestream&);
+ iopipestream& operator << (imanip func) { return (*func)(*this); }
+
+ iopipestream& operator >> (string& s) {
+ readbuffer();
+ s=buffer;
+ return *this;
+ }
+
+ bool tailequals(const char *buf, size_t len, const char *prompt,
+ size_t plen) {
+ const char *a=buf+len;
+ const char *b=prompt+plen;
+ while(b >= prompt) {
+ if(a < buf) return false;
+ if(*a != *b) return false;
+ if(*a == '\n' && *(a-1) == '\r') --a; // Handle MSDOS incompatibility
+ --a; --b;
+ }
+ return true;
+ }
+
+ bool checkabort(const char *abort) {
+ size_t alen=strlen(abort);
+ if(strncmp(buffer,abort,alen) == 0) {
+ clear();
+ return true;
+ }
+ char *p=buffer;
+ while((p=strchr(p,'\n')) != NULL) {
+ ++p;
+ if(strncmp(p,abort,alen) == 0) {
+ clear();
+ return true;
+ }
+ }
+ return false;
+ }
+
+ // returns true if prompt found, false if abort string is received
+ int wait(const char *prompt, const char**abort=NULL) {
+ ssize_t len;
+ size_t plen=strlen(prompt);
+
+ unsigned int n=0;
+ if(abort) {
+ for(;;) {
+ if(abort[n]) n++;
+ else break;
+ }
+ }
+
+ do {
+ len=readbuffer();
+ for(unsigned int i=0; i < n; ++i)
+ if(checkabort(abort[i])) return i+1;
+ } while (!tailequals(buffer,len,prompt,plen));
+ return 0;
+ }
+
+ int wait() {
+ for(;;) {
+ int status;
+ if (waitpid(pid, &status, 0) == -1) {
+ if (errno == ECHILD) return 0;
+ if (errno != EINTR) {
+ ostringstream buf;
+ buf << "Process " << pid << " failed";
+ camp::reportError(buf);
+ }
+ } else {
+ if(WIFEXITED(status)) return WEXITSTATUS(status);
+ else {
+ ostringstream buf;
+ buf << "Process " << pid << " exited abnormally";
+ camp::reportError(buf);
+ }
+ }
+ }
+ }
+
+ void Write(const string &s) {
+ ssize_t size=s.length();
+ if(settings::verbose > 2) cerr << s;
+ if(write(in[1],s.c_str(),size) != size) {
+ camp::reportFatal("write to pipe failed");
+ }
+
+ }
+
+ iopipestream& operator << (const string& s) {
+ Write(s);
+ return *this;
+ }
+
+ template<class T>
+ iopipestream& operator << (T x) {
+ ostringstream os;
+ os << x;
+ Write(os.str());
+ return *this;
+ }
+};
+
+#endif
diff --git a/Build/source/utils/asymptote/prc/Makefile b/Build/source/utils/asymptote/prc/Makefile
new file mode 100644
index 00000000000..cfa9ac9be5d
--- /dev/null
+++ b/Build/source/utils/asymptote/prc/Makefile
@@ -0,0 +1,22 @@
+# Makefile.
+
+CFLAGS = -O3 -g -Wall
+CXX = g++
+
+test: PRCbitStream oPRCFile PRCdouble writePRC test.cc
+ $(CXX) $(CFLAGS) -o test PRCbitStream.o oPRCFile.o PRCdouble.o writePRC.o test.cc -lz
+
+PRCbitStream: PRCbitStream.cc
+ $(CXX) $(CFLAGS) -c PRCbitStream.cc -o PRCbitStream.o
+
+oPRCFile: oPRCFile.cc
+ $(CXX) $(CFLAGS) -c oPRCFile.cc -o oPRCFile.o
+
+PRCdouble: PRCdouble.cc
+ $(CXX) $(CFLAGS) -c PRCdouble.cc -o PRCdouble.o
+
+writePRC: writePRC.cc PRCbitStream
+ $(CXX) $(CFLAGS) -c writePRC.cc -o writePRC.o
+
+clean:
+ rm -f *.o test.prc test
diff --git a/Build/source/utils/asymptote/prc/PRC.h b/Build/source/utils/asymptote/prc/PRC.h
new file mode 100644
index 00000000000..ce04cea4801
--- /dev/null
+++ b/Build/source/utils/asymptote/prc/PRC.h
@@ -0,0 +1,303 @@
+#ifndef __PRC_H
+#define __PRC_H
+
+#include <stdint.h>
+
+const uint32_t PRCVersion=7094; // For Adobe Reader 8 or later
+//const uint32_t PRCVersion=8137; // For Adobe Reader 9 or later
+
+// from Adobe's documentation
+
+#define PRC_TYPE_ROOT 0 // This type does not correspond to any entity
+
+#define PRC_TYPE_ROOT_PRCBase ( PRC_TYPE_ROOT + 1 ) // Abstract root type for any PRC entity.
+#define PRC_TYPE_ROOT_PRCBaseWithGraphics ( PRC_TYPE_ROOT + 2 ) // Abstract root type for any PRC entity which can bear graphics.
+
+#define PRC_TYPE_CRV ( PRC_TYPE_ROOT + 10 ) // Types for PRC geometrical curves
+#define PRC_TYPE_SURF ( PRC_TYPE_ROOT + 75 ) // Types for PRC geometrical surfaces
+#define PRC_TYPE_TOPO ( PRC_TYPE_ROOT + 140 ) // Types for PRC topology
+#define PRC_TYPE_TESS ( PRC_TYPE_ROOT + 170 ) // Types for PRC tessellation
+#define PRC_TYPE_MISC ( PRC_TYPE_ROOT + 200 ) // Types for PRC global data
+#define PRC_TYPE_RI ( PRC_TYPE_ROOT + 230 ) // Types for PRC representation items
+#define PRC_TYPE_ASM ( PRC_TYPE_ROOT + 300 ) // Types for PRC assembly
+#define PRC_TYPE_MKP ( PRC_TYPE_ROOT + 500 ) // Types for PRC markup
+#define PRC_TYPE_GRAPH ( PRC_TYPE_ROOT + 700 ) // Types for PRC graphics
+#define PRC_TYPE_MATH ( PRC_TYPE_ROOT + 900 ) // Types for PRC mathematical operators
+
+#define PRC_TYPE_CRV_Base ( PRC_TYPE_CRV + 1 ) // Abstract type for all geometric curves.
+#define PRC_TYPE_CRV_Blend02Boundary ( PRC_TYPE_CRV + 2 ) // Boundary Curve.
+#define PRC_TYPE_CRV_NURBS ( PRC_TYPE_CRV + 3 ) // Non Uniform BSpline curve.
+#define PRC_TYPE_CRV_Circle ( PRC_TYPE_CRV + 4 ) // Circle.
+#define PRC_TYPE_CRV_Composite ( PRC_TYPE_CRV + 5 ) // Array of oriented curves.
+#define PRC_TYPE_CRV_OnSurf ( PRC_TYPE_CRV + 6 ) // Curve defined by a UV curve on a surface.
+#define PRC_TYPE_CRV_Ellipse ( PRC_TYPE_CRV + 7 ) // Ellipse.
+#define PRC_TYPE_CRV_Equation ( PRC_TYPE_CRV + 8 ) // curve described by specific law elements
+#define PRC_TYPE_CRV_Helix ( PRC_TYPE_CRV + 9 ) // Helix curve.
+#define PRC_TYPE_CRV_Hyperbola ( PRC_TYPE_CRV + 10 ) // Hyperbola.
+#define PRC_TYPE_CRV_Intersection ( PRC_TYPE_CRV + 11 ) // Intersection between 2 surfaces.
+#define PRC_TYPE_CRV_Line ( PRC_TYPE_CRV + 12 ) // Line.
+#define PRC_TYPE_CRV_Offset ( PRC_TYPE_CRV + 13 ) // Offset curve.
+#define PRC_TYPE_CRV_Parabola ( PRC_TYPE_CRV + 14 ) // Parabola.
+#define PRC_TYPE_CRV_PolyLine ( PRC_TYPE_CRV + 15 ) // Polyedric curve.
+#define PRC_TYPE_CRV_Transform ( PRC_TYPE_CRV + 16 ) // Transformed curve.
+
+#define PRC_TYPE_SURF_Base ( PRC_TYPE_SURF + 1 ) // Abstract type for all geometric surfaces.
+#define PRC_TYPE_SURF_Blend01 ( PRC_TYPE_SURF + 2 ) // Blend surface.
+#define PRC_TYPE_SURF_Blend02 ( PRC_TYPE_SURF + 3 ) // Blend Surface.
+#define PRC_TYPE_SURF_Blend03 ( PRC_TYPE_SURF + 4 ) // Blend Surface.
+#define PRC_TYPE_SURF_NURBS ( PRC_TYPE_SURF + 5 ) // Non Uniform BSpline surface.
+#define PRC_TYPE_SURF_Cone ( PRC_TYPE_SURF + 6 ) // Cone.
+#define PRC_TYPE_SURF_Cylinder ( PRC_TYPE_SURF + 7 ) // Cylinder.
+#define PRC_TYPE_SURF_Cylindrical ( PRC_TYPE_SURF + 8 ) // Surface who is defined in cylindrical space.
+#define PRC_TYPE_SURF_Offset ( PRC_TYPE_SURF + 9 ) // Offset surface.
+#define PRC_TYPE_SURF_Pipe ( PRC_TYPE_SURF + 10 ) // Pipe.
+#define PRC_TYPE_SURF_Plane ( PRC_TYPE_SURF + 11 ) // Plane.
+#define PRC_TYPE_SURF_Ruled ( PRC_TYPE_SURF + 12 ) // Ruled surface.
+#define PRC_TYPE_SURF_Sphere ( PRC_TYPE_SURF + 13 ) // Sphere.
+#define PRC_TYPE_SURF_Revolution ( PRC_TYPE_SURF + 14 ) // Surface of revolution.
+#define PRC_TYPE_SURF_Extrusion ( PRC_TYPE_SURF + 15 ) // Surface of extrusion.
+#define PRC_TYPE_SURF_FromCurves ( PRC_TYPE_SURF + 16 ) // Surface from two curves.
+#define PRC_TYPE_SURF_Torus ( PRC_TYPE_SURF + 17 ) // Torus.
+#define PRC_TYPE_SURF_Transform ( PRC_TYPE_SURF + 18 ) // Transformed surface.
+#define PRC_TYPE_SURF_Blend04 ( PRC_TYPE_SURF + 19 ) // defined for future use.
+
+#define PRC_TYPE_TOPO_Context ( PRC_TYPE_TOPO + 1 ) // Self-containing set of topological entities.
+#define PRC_TYPE_TOPO_Item ( PRC_TYPE_TOPO + 2 ) // Abstract root type for any topological entity (body or single item).
+#define PRC_TYPE_TOPO_MultipleVertex ( PRC_TYPE_TOPO + 3 ) // Vertex whose position is the average of all edges' extremity positions to whom it belongs.
+#define PRC_TYPE_TOPO_UniqueVertex ( PRC_TYPE_TOPO + 4 ) // Vertex with one set of coordinates (absolute position).
+#define PRC_TYPE_TOPO_WireEdge ( PRC_TYPE_TOPO + 5 ) // Edge belonging to a wire body / single wire body.
+#define PRC_TYPE_TOPO_Edge ( PRC_TYPE_TOPO + 6 ) // Edge belonging to a brep data.
+#define PRC_TYPE_TOPO_CoEdge ( PRC_TYPE_TOPO + 7 ) // Usage of an edge in a loop.
+#define PRC_TYPE_TOPO_Loop ( PRC_TYPE_TOPO + 8 ) // Array of co edges which delimits a face.
+#define PRC_TYPE_TOPO_Face ( PRC_TYPE_TOPO + 9 ) // Topological face delimiting a shell.
+#define PRC_TYPE_TOPO_Shell ( PRC_TYPE_TOPO + 10 ) // Topological shell (open or closed).
+#define PRC_TYPE_TOPO_Connex ( PRC_TYPE_TOPO + 11 ) // Topological region delimited by one or several shells.
+#define PRC_TYPE_TOPO_Body ( PRC_TYPE_TOPO + 12 ) // Abstract root type for any topological body.
+#define PRC_TYPE_TOPO_SingleWireBody ( PRC_TYPE_TOPO + 13 ) // Single wire body.
+#define PRC_TYPE_TOPO_BrepData ( PRC_TYPE_TOPO + 14 ) // Main entry to solid and surface topology (regular form).
+#define PRC_TYPE_TOPO_SingleWireBodyCompress ( PRC_TYPE_TOPO + 15 ) // Single wire body. (ultra compressed form).
+#define PRC_TYPE_TOPO_BrepDataCompress ( PRC_TYPE_TOPO + 16 ) // Main entry to solid and surface topology (ultra compressed form).
+#define PRC_TYPE_TOPO_WireBody ( PRC_TYPE_TOPO + 17 ) // This type is the main entry to wire topology.
+
+#define PRC_TYPE_TESS_Base ( PRC_TYPE_TESS + 1 ) // Abstract root type for any tessellated entity.
+#define PRC_TYPE_TESS_3D ( PRC_TYPE_TESS + 2 ) // Tessellated faceted data; regular form.
+#define PRC_TYPE_TESS_3D_Compressed ( PRC_TYPE_TESS + 3 ) // Tessellated faceted data; highly compressed form.
+#define PRC_TYPE_TESS_Face ( PRC_TYPE_TESS + 4 ) // Tessellated face.
+#define PRC_TYPE_TESS_3D_Wire ( PRC_TYPE_TESS + 5 ) // Tessellated wireframe.
+#define PRC_TYPE_TESS_Markup ( PRC_TYPE_TESS + 6 ) // Tessellated markup.
+
+#define PRC_TYPE_MISC_Attribute ( PRC_TYPE_MISC + 1 ) // Entity attribute.
+#define PRC_TYPE_MISC_CartesianTransformation ( PRC_TYPE_MISC + 2 ) // Cartesian transformation.
+#define PRC_TYPE_MISC_EntityReference ( PRC_TYPE_MISC + 3 ) // Entity reference.
+#define PRC_TYPE_MISC_MarkupLinkedItem ( PRC_TYPE_MISC + 4 ) // Link between a markup and an entity.
+#define PRC_TYPE_MISC_ReferenceOnPRCBase ( PRC_TYPE_MISC + 5 ) // Reference pointing on a regular entity (not topological).
+#define PRC_TYPE_MISC_ReferenceOnTopology ( PRC_TYPE_MISC + 6 ) // Reference pointing on a topological entity.
+
+#define PRC_TYPE_RI_RepresentationItem ( PRC_TYPE_RI + 1 ) // Basic abstract type for representation items.
+#define PRC_TYPE_RI_BrepModel ( PRC_TYPE_RI + 2 ) // Basic type for surfaces and solids.
+#define PRC_TYPE_RI_Curve ( PRC_TYPE_RI + 3 ) // Basic type for curves.
+#define PRC_TYPE_RI_Direction ( PRC_TYPE_RI + 4 ) // Optional point + vector.
+#define PRC_TYPE_RI_Plane ( PRC_TYPE_RI + 5 ) // Construction plane, as opposed to planar surface.
+#define PRC_TYPE_RI_PointSet ( PRC_TYPE_RI + 6 ) // Set of points.
+#define PRC_TYPE_RI_PolyBrepModel ( PRC_TYPE_RI + 7 ) // Basic type to polyhedral surfaces and solids.
+#define PRC_TYPE_RI_PolyWire ( PRC_TYPE_RI + 8 ) // Polyedric wireframe entity.
+#define PRC_TYPE_RI_Set ( PRC_TYPE_RI + 9 ) // Logical grouping of arbitrary number of representation items.
+#define PRC_TYPE_RI_CoordinateSystem ( PRC_TYPE_RI + 10 ) // Coordinate system.
+
+#define PRC_TYPE_ASM_ModelFile ( PRC_TYPE_ASM + 1 ) // Basic entry type for PRC.
+#define PRC_TYPE_ASM_FileStructure ( PRC_TYPE_ASM + 2 ) // Basic structure for PRC files.
+#define PRC_TYPE_ASM_FileStructureGlobals ( PRC_TYPE_ASM + 3 ) // Basic structure for PRC files : globals.
+#define PRC_TYPE_ASM_FileStructureTree ( PRC_TYPE_ASM + 4 ) // Basic structure for PRC files : tree.
+#define PRC_TYPE_ASM_FileStructureTessellation ( PRC_TYPE_ASM + 5 ) // Basic structure for PRC files : tessellation.
+#define PRC_TYPE_ASM_FileStructureGeometry ( PRC_TYPE_ASM + 6 ) // Basic structure for PRC files : geometry.
+#define PRC_TYPE_ASM_FileStructureExtraGeometry ( PRC_TYPE_ASM + 7 ) // Basic structure for PRC files : extra geometry data.
+#define PRC_TYPE_ASM_ProductOccurence ( PRC_TYPE_ASM + 10 ) // Basic contruct for assemblies.
+#define PRC_TYPE_ASM_PartDefinition ( PRC_TYPE_ASM + 11 ) // Basic construct for parts.
+
+#define PRC_TYPE_MKP_View ( PRC_TYPE_MKP + 1 ) // Grouping of markup by views.
+#define PRC_TYPE_MKP_Markup ( PRC_TYPE_MKP + 2 ) // Basic type for simple markups.
+#define PRC_TYPE_MKP_Leader ( PRC_TYPE_MKP + 3 ) // basic type for markup leader
+#define PRC_TYPE_MKP_AnnotationItem ( PRC_TYPE_MKP + 4 ) // Usage of a markup.
+#define PRC_TYPE_MKP_AnnotationSet ( PRC_TYPE_MKP + 5 ) // Group of annotations.
+#define PRC_TYPE_MKP_AnnotationReference ( PRC_TYPE_MKP + 6 ) // Logical grouping of annotations for reference.
+
+#define PRC_TYPE_GRAPH_Style ( PRC_TYPE_GRAPH + 1 ) // Display style.
+#define PRC_TYPE_GRAPH_Material ( PRC_TYPE_GRAPH + 2 ) // Display material properties.
+#define PRC_TYPE_GRAPH_Picture ( PRC_TYPE_GRAPH + 3 ) // Picture.
+#define PRC_TYPE_GRAPH_TextureApplication ( PRC_TYPE_GRAPH + 11 ) // Texture application.
+#define PRC_TYPE_GRAPH_TextureDefinition ( PRC_TYPE_GRAPH + 12 ) // Texture definition.
+#define PRC_TYPE_GRAPH_TextureTransformation ( PRC_TYPE_GRAPH + 13 ) // Texture transformation.
+#define PRC_TYPE_GRAPH_LinePattern ( PRC_TYPE_GRAPH + 21 ) // One dimensional display style.
+#define PRC_TYPE_GRAPH_FillPattern ( PRC_TYPE_GRAPH + 22 ) // Abstract class for two-dimensional display style.
+#define PRC_TYPE_GRAPH_DottingPattern ( PRC_TYPE_GRAPH + 23 ) // Two-dimensional filling with dots.
+#define PRC_TYPE_GRAPH_HatchingPattern ( PRC_TYPE_GRAPH + 24 ) // Two-dimensional filling with hatches.
+#define PRC_TYPE_GRAPH_SolidPattern ( PRC_TYPE_GRAPH + 25 ) // Two-dimensional filling with particular style (color, material, texture).
+#define PRC_TYPE_GRAPH_VPicturePattern ( PRC_TYPE_GRAPH + 26 ) // Two-dimensional filling with vectorised picture.
+#define PRC_TYPE_GRAPH_AmbientLight ( PRC_TYPE_GRAPH + 31 ) // Scene ambient illumination.
+#define PRC_TYPE_GRAPH_PointLight ( PRC_TYPE_GRAPH + 32 ) // Scene point illumination.
+#define PRC_TYPE_GRAPH_DirectionalLight ( PRC_TYPE_GRAPH + 33 ) // Scene directional illumination.
+#define PRC_TYPE_GRAPH_SpotLight ( PRC_TYPE_GRAPH + 34 ) // Scene spot illumination.
+#define PRC_TYPE_GRAPH_SceneDisplayParameters ( PRC_TYPE_GRAPH + 41 ) // Parameters for scene visualisation.
+#define PRC_TYPE_GRAPH_Camera ( PRC_TYPE_GRAPH + 42 ) //
+
+#define PRC_TYPE_MATH_FCT_1D ( PRC_TYPE_MATH + 1 ) // Basic type for one degree equation object.
+#define PRC_TYPE_MATH_FCT_1D_Polynom ( PRC_TYPE_MATH_FCT_1D + 1 ) // Polynomial equation.
+#define PRC_TYPE_MATH_FCT_1D_Trigonometric ( PRC_TYPE_MATH_FCT_1D + 2 ) // Cosinus based equation.
+#define PRC_TYPE_MATH_FCT_1D_Fraction ( PRC_TYPE_MATH_FCT_1D + 3 ) // Fraction between 2 one degree equation object.
+#define PRC_TYPE_MATH_FCT_1D_ArctanCos ( PRC_TYPE_MATH_FCT_1D + 4 ) // Specific equation.
+#define PRC_TYPE_MATH_FCT_1D_Combination ( PRC_TYPE_MATH_FCT_1D + 5 ) // Combination of one degree equation object.
+#define PRC_TYPE_MATH_FCT_3D ( PRC_TYPE_MATH + 10 ) // Basic type for 3rd degree equation object.
+#define PRC_TYPE_MATH_FCT_3D_Linear ( PRC_TYPE_MATH_FCT_3D + 1 ) // Linear transformation ( with a matrix ).
+#define PRC_TYPE_MATH_FCT_3D_NonLinear ( PRC_TYPE_MATH_FCT_3D + 2 ) // Specific transformation.
+
+#define PRC_PRODUCT_FLAG_DEFAULT 0x0001
+#define PRC_PRODUCT_FLAG_INTERNAL 0x0002
+#define PRC_PRODUCT_FLAG_CONTAINER 0x0004
+#define PRC_PRODUCT_FLAG_CONFIG 0x0008
+#define PRC_PRODUCT_FLAG_VIEW 0x0010
+
+#define PRC_TRANSFORMATION_Identity 0x00
+#define PRC_TRANSFORMATION_Translate 0x01
+#define PRC_TRANSFORMATION_Rotate 0x02
+#define PRC_TRANSFORMATION_Mirror 0x04
+#define PRC_TRANSFORMATION_Scale 0x08
+#define PRC_TRANSFORMATION_NonUniformScale 0x10
+#define PRC_TRANSFORMATION_NonOrtho 0x20
+#define PRC_TRANSFORMATION_Homogeneous 0x40
+
+#define PRC_FACETESSDATA_Polyface 0x0001
+#define PRC_FACETESSDATA_Triangle 0x0002
+#define PRC_FACETESSDATA_TriangleFan 0x0004
+#define PRC_FACETESSDATA_TriangleStripe 0x0008
+#define PRC_FACETESSDATA_PolyfaceOneNormal 0x0010
+#define PRC_FACETESSDATA_TriangleOneNormal 0x0020
+#define PRC_FACETESSDATA_TriangleFanOneNormal 0x0040
+#define PRC_FACETESSDATA_TriangleStripeOneNormal 0x0080
+#define PRC_FACETESSDATA_PolyfaceTextured 0x0100
+#define PRC_FACETESSDATA_TriangleTextured 0x0200
+#define PRC_FACETESSDATA_TriangleFanTextured 0x0400
+#define PRC_FACETESSDATA_TriangleStripeTextured 0x0800
+#define PRC_FACETESSDATA_PolyfaceOneNormalTextured 0x1000
+#define PRC_FACETESSDATA_TriangleOneNormalTextured 0x2000
+#define PRC_FACETESSDATA_TriangleFanOneNormalTextured 0x4000
+#define PRC_FACETESSDATA_TriangleStripeOneNormalTextured 0x8000
+
+#define PRC_TEXTURE_MAPPING_DIFFUSE 0x0001
+#define PRC_TEXTURE_MAPPING_BUMP 0x0002
+#define PRC_TEXTURE_MAPPING_OPACITY 0x0004
+#define PRC_TEXTURE_MAPPING_SPHERICAL_REFLECTION 0x0008
+#define PRC_TEXTURE_MAPPING_CUBICAL_REFLECTION 0x0010
+#define PRC_TEXTURE_MAPPING_REFRACTION 0x0020
+#define PRC_TEXTURE_MAPPING_SPECULAR 0x0040
+#define PRC_TEXTURE_MAPPING_AMBIENT 0x0080
+#define PRC_TEXTURE_MAPPING_EMISSION 0x0100
+#define PRC_TEXTURE_APPLYING_MODE_NONE 0x00 // let the application choose
+#define PRC_TEXTURE_APPLYING_MODE_LIGHTING 0x01 // use lighting mode
+#define PRC_TEXTURE_APPLYING_MODE_ALPHATEST 0x02 // use alpha test
+#define PRC_TEXTURE_APPLYING_MODE_VERTEXCOLOR 0x04 // combine a texture with one-color-per-vertex mode
+
+enum EPRCModellerAttributeType {
+ KEPRCModellerAttributeTypeNull = 0,
+ KEPRCModellerAttributeTypeInt = 1,
+ KEPRCModellerAttributeTypeReal = 2,
+ KEPRCModellerAttributeTypeTime = 3,
+ KEPRCModellerAttributeTypeString = 4
+};
+
+enum EPRCPictureDataFormat {
+ KEPRCPicture_PNG,
+ KEPRCPicture_JPG,
+ KEPRCPicture_BITMAP_RGB_BYTE,
+ KEPRCPicture_BITMAP_RGBA_BYTE,
+ KEPRCPicture_BITMAP_GREY_BYTE,
+ KEPRCPicture_BITMAP_GREYA_BYTE
+};
+
+enum EPRCProductLoadStatus {
+ KEPRCProductLoadStatus_Unknown = 0,
+ KEPRCProductLoadStatus_Error,
+ KEPRCProductLoadStatus_NotLoaded,
+ KEPRCProductLoadStatus_NotLoadable,
+ KEPRCProductLoadStatus_Loaded
+};
+
+enum EPRCExtendType {
+ KEPRCExtendTypeNone = 0,
+ KEPRCExtendTypeExt1 = 2,
+ KEPRCExtendTypeExt2 = 4,
+ KEPRCExtendTypeG1 = 6,
+ KEPRCExtendTypeG1R = 8,
+ KEPRCExtendTypeG1_G2 = 10,
+ KEPRCExtendTypeCInfinity = 12
+};
+
+enum EPRCKnotType {
+ KEPRCKnotTypeUniformKnots,
+ KEPRCKnotTypeUnspecified,
+ KEPRCKnotTypeQuasiUniformKnots,
+ KEPRCKnotTypePiecewiseBezierKnots
+};
+
+enum EPRCBSplineSurfaceForm {
+ KEPRCBSplineSurfaceFormPlane,
+ KEPRCBSplineSurfaceFormCylindrical,
+ KEPRCBSplineSurfaceFormConical,
+ KEPRCBSplineSurfaceFormSpherical,
+ KEPRCBSplineSurfaceFormRevolution,
+ KEPRCBSplineSurfaceFormRuled,
+ KEPRCBSplineSurfaceFormGeneralizedCone,
+ KEPRCBSplineSurfaceFormQuadric,
+ KEPRCBSplineSurfaceFormLinearExtrusion,
+ KEPRCBSplineSurfaceFormUnspecified,
+ KEPRCBSplineSurfaceFormPolynomial
+};
+
+enum EPRCBSplineCurveForm {
+ KEPRCBSplineCurveFormUnspecified,
+ KEPRCBSplineCurveFormPolyline,
+ KEPRCBSplineCurveFormCircularArc,
+ KEPRCBSplineCurveFormEllipticArc,
+ KEPRCBSplineCurveFormParabolicArc,
+ KEPRCBSplineCurveFormHyperbolicArc
+};
+
+enum EPRCTextureMappingType {
+ KEPRCTextureMappingType_Unknown,
+ KEPRCTextureMappingType_Stored,
+ KEPRCTextureMappingType_Parametric,
+ KEPRCTextureMappingType_Operator
+};
+
+enum EPRCTextureFunction {
+ KEPRCTextureFunction_Unknown,
+ KEPRCTextureFunction_Modulate,
+ KEPRCTextureFunction_Replace,
+ KEPRCTextureFunction_Blend,
+ KEPRCTextureFunction_Decal
+};
+
+enum EPRCTextureBlendParameter {
+ KEPRCTextureBlendParameter_Unknown,
+ KEPRCTextureBlendParameter_Zero,
+ KEPRCTextureBlendParameter_One,
+ KEPRCTextureBlendParameter_SrcColor,
+ KEPRCTextureBlendParameter_OneMinusSrcColor,
+ KEPRCTextureBlendParameter_DstColor,
+ KEPRCTextureBlendParameter_OneMinusDstColor,
+ KEPRCTextureBlendParameter_SrcAlpha,
+ KEPRCTextureBlendParameter_OneMinusSrcAlpha,
+ KEPRCTextureBlendParameter_DstAlpha,
+ KEPRCTextureBlendParameter_OneMinusDstAlpha,
+ KEPRCTextureBlendParameter_SrcAlphaSaturate
+};
+
+enum EPRCTextureWrappingMode {
+ KEPRCTextureWrappingMode_Unknown,
+ KEPRCTextureWrappingMode_Repeat,
+ KEPRCTextureWrappingMode_ClampToBorder,
+ KEPRCTextureWrappingMode_Clamp,
+ KEPRCTextureWrappingMode_ClampToEdge,
+ KEPRCTextureWrappingMode_MirroredRepeat
+};
+
+#endif // __PRC_H
diff --git a/Build/source/utils/asymptote/prc/PRCTools/Makefile b/Build/source/utils/asymptote/prc/PRCTools/Makefile
new file mode 100644
index 00000000000..51186e7e76f
--- /dev/null
+++ b/Build/source/utils/asymptote/prc/PRCTools/Makefile
@@ -0,0 +1,48 @@
+CFLAGS = -O3 -Wall
+CXX = g++
+
+makePRC: PRCbitStream oPRCFile PRCdouble writePRC makePRC.cc
+ $(CXX) $(CFLAGS) -o makePRC PRCbitStream.o oPRCFile.o PRCdouble.o writePRC.o makePRC.cc -lz
+
+describePRC: bitData inflation PRCdouble iPRCFile describePRC.cc describeMain.cc
+ $(CXX) $(CFLAGS) -o describePRC bitData.o inflation.o PRCdouble.o iPRCFile.o describePRC.cc describeMain.cc -lz
+
+bitSearchUI: bitSearchUI.cc bitData PRCdouble
+ $(CXX) $(CFLAGS) -o bitSearchUI bitData.o PRCdouble.o bitSearchUI.cc
+
+bitSearchDouble: bitSearchDouble.cc bitData PRCdouble
+ $(CXX) $(CFLAGS) -o bitSearchDouble bitData.o PRCdouble.o bitSearchDouble.cc
+
+extractSections: extractSections.cc iPRCFile inflation bitData PRCdouble
+ $(CXX) $(CFLAGS) -o extractSections iPRCFile.o inflation.o bitData.o PRCdouble.o describePRC.cc extractSections.cc -lz
+
+inflateTest: inflation inflationMain.cc
+ $(CXX) $(CFLAGS) -o inflateTest inflation.o inflationMain.cc -lz
+
+PRCdouble: ../PRCdouble.cc
+ $(CXX) $(CFLAGS) -c ../PRCdouble.cc -o PRCdouble.o
+
+PRCbitStream: ../PRCbitStream.cc
+ $(CXX) $(CFLAGS) -c ../PRCbitStream.cc -o PRCbitStream.o
+
+oPRCFile: ../oPRCFile.cc
+ $(CXX) $(CFLAGS) -c ../oPRCFile.cc -o oPRCFile.o
+
+writePRC: ../writePRC.cc PRCbitStream
+ $(CXX) $(CFLAGS) -c ../writePRC.cc -o writePRC.o
+
+bitData: bitData.cc
+ $(CXX) $(CFLAGS) -c bitData.cc -o bitData.o
+
+inflation: inflation.cc
+ $(CXX) $(CFLAGS) -c inflation.cc -o inflation.o
+
+iPRCFile: iPRCFile.cc
+ $(CXX) $(CFLAGS) -c iPRCFile.cc -o iPRCFile.o
+
+all: makePRC describePRC bitSearchUI bitSearchDouble extractSections inflateTest
+
+tools: all
+
+clean:
+ rm -f *.o describePRC bitSearchUI bitSearchDouble extractSections inflateTest
diff --git a/Build/source/utils/asymptote/prc/PRCTools/bitData.cc b/Build/source/utils/asymptote/prc/PRCTools/bitData.cc
new file mode 100644
index 00000000000..19274a8b4b7
--- /dev/null
+++ b/Build/source/utils/asymptote/prc/PRCTools/bitData.cc
@@ -0,0 +1,258 @@
+/************
+*
+* This file is part of a tool for reading 3D content in the PRC format.
+* Copyright (C) 2008 Orest Shardt <shardtor (at) gmail dot com>
+*
+* This program 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 3 of the License, or
+* (at your option) any later version.
+*
+* This program 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 program. If not, see <http://www.gnu.org/licenses/>.
+*
+*************/
+
+#include "../PRC.h"
+#include "../PRCdouble.h"
+#include "bitData.h"
+
+using std::cout; using std::endl; using std::hex; using std::cerr;
+
+BitPosition BitByBitData::getPosition()
+{
+ BitPosition bp;
+ bp.byteIndex = data - start;
+ bp.bitIndex = 0;
+ for(unsigned char temp = bitMask<<1; temp != 0; temp <<= 1)
+ bp.bitIndex++;
+ return bp;
+}
+
+void BitByBitData::setPosition(const BitPosition& bp)
+{
+ if(bp.byteIndex < length)
+ {
+ data = start + bp.byteIndex;
+ bitMask = 0x80 >> bp.bitIndex;
+ // big-endian, zero based bit index (from 0 to 7)
+ // so 0x80 => bit 0, 0x01 => bit 7
+ // Why? It is easy to see in a hex editor.
+ failed = false;
+ }
+ else
+ {
+ failed = true;
+ }
+}
+
+void BitByBitData::setPosition(unsigned int byte, unsigned int bit)
+{
+ if(byte <= length)
+ {
+ data = start + byte;
+ bitMask = 0x80 >> bit;
+ // big-endian, zero based bit index (from 0 to 7)
+ // so 0x80 => bit 0, 0x01 => bit 7
+ // Why? It is easy to see in a hex editor.
+ failed = false;
+ }
+ else
+ {
+ failed = true;
+ }
+}
+
+void BitByBitData::setShowBits(bool val)
+{
+ showBits = val;
+}
+
+void BitByBitData::tellPosition()
+{
+ BitPosition bp = getPosition();
+ cout << bp.byteIndex << ':' << bp.bitIndex << endl;
+}
+
+bool BitByBitData::readBit()
+{
+ if(!failed)
+ {
+ bool val = *data & bitMask;
+ if(showBits) cout << (val?'1':'0');
+ nextBit();
+ return val;
+ }
+ else
+ return false;
+}
+
+unsigned char BitByBitData::readChar()
+{
+ unsigned char dat = 0;
+ dat |= readBit();
+ for(int a = 0; a < 7; ++a)
+ {
+ dat <<= 1;
+ dat |= readBit();
+ }
+ return dat;
+}
+
+unsigned int BitByBitData::readUnsignedInt()
+{
+ unsigned int result = 0;
+ unsigned int count = 0;
+ while(readBit())
+ {
+ result |= (static_cast<unsigned int>(readChar()) << 8*count++);
+ }
+ if(showBits) cout << " " << result << endl;
+ return result;
+}
+
+std::string BitByBitData::readString()
+{
+ bool isNotNull = readBit();
+ std::string result;
+ if(isNotNull)
+ {
+ unsigned int stringLength = readUnsignedInt();
+ char *buf = new char[stringLength+1];
+ buf[stringLength] = '\0';
+ for(unsigned int a = 0; a < stringLength; ++a)
+ {
+ buf[a] = readChar();
+ }
+ result = buf;
+ delete[] buf;
+ }
+ if(showBits) cout << " " << result << endl;
+ return result;
+}
+
+int BitByBitData::readInt()
+{
+ int result = 0;
+ unsigned int count = 0;
+ while(readBit())
+ {
+ result |= (static_cast<unsigned int>(readChar()) << 8*count++);
+ }
+ result <<= (4-count)*8;
+ result >>= (4-count)*8;
+ if(showBits) cout << " " << result << endl;
+ return result;
+}
+
+
+// Thanks to Michail Vidiassov
+double BitByBitData::readDouble()
+{
+ ieee754_double value;
+ value.d = 0;
+ sCodageOfFrequentDoubleOrExponent *pcofdoe;
+ unsigned int ucofdoe = 0;
+ for(int i = 1; i <= 22; ++i)
+ {
+ ucofdoe <<= 1;
+ ucofdoe |= readBit();
+ if((pcofdoe = getcofdoe(ucofdoe,i)) != NULL)
+ break;
+ }
+ value.d = pcofdoe->u2uod.Value;
+
+ // check if zero
+ if(pcofdoe->NumberOfBits==2 && pcofdoe->Bits==1 && pcofdoe->Type==VT_double)
+ return value.d;
+
+ value.ieee.negative = readBit(); // get sign
+
+ if(pcofdoe->Type == VT_double) // double from list
+ return value.d;
+
+ if(readBit()==0) // no mantissa
+ return value.d;
+
+ // read the mantissa
+ // read uppermost 4 bits of mantissa
+ unsigned char b4 = 0;
+ for(int i = 0; i < 4; ++i)
+ {
+ b4 <<= 1;
+ b4 |= readBit();
+ }
+
+#if defined(WORDS_LITTLE_ENDIAN)
+ *(reinterpret_cast<unsigned char*>(&value)+6) |= b4;
+ unsigned char *lastByte = reinterpret_cast<unsigned char*>(&value)+0;
+ unsigned char *currentByte = reinterpret_cast<unsigned char*>(&value)+5;
+#elif defined(WORDS_BIG_ENDIAN)
+ *(reinterpret_cast<unsigned char*>(&value)+1) |= b4;
+ unsigned char *lastByte = reinterpret_cast<unsigned char*>(&value)+7;
+ unsigned char *currentByte = reinterpret_cast<unsigned char*>(&value)+2;
+#endif
+
+ for(;MOREBYTE(currentByte,lastByte); NEXTBYTE(currentByte))
+ {
+ if(readBit())
+ {
+ // new byte
+ *currentByte = readChar();
+ }
+ else
+ {
+ // get 3 bit offset
+ unsigned int offset = 0;
+ offset |= (readBit() << 2);
+ offset |= (readBit() << 1);
+ offset |= readBit();
+ if(offset == 0)
+ {
+ // fill remaining bytes in mantissa with previous byte
+ unsigned char pByte = BYTEAT(currentByte,1);
+ for(;MOREBYTE(currentByte,lastByte); NEXTBYTE(currentByte))
+ *currentByte = pByte;
+ break;
+ }
+ else if(offset == 6)
+ {
+ // fill remaining bytes except last byte with previous byte
+ unsigned char pByte = BYTEAT(currentByte,1);
+ PREVIOUSBYTE(lastByte);
+ for(;MOREBYTE(currentByte,lastByte); NEXTBYTE(currentByte))
+ *currentByte = pByte;
+ *currentByte = readChar();
+ break;
+ }
+ else
+ {
+ // one repeated byte
+ *currentByte = BYTEAT(currentByte,offset);
+ }
+ }
+ }
+ if(showBits) cout << " " << value.d << endl;
+ return value.d;
+}
+
+void BitByBitData::nextBit()
+{
+ bitMask >>= 1;
+ if(bitMask == 0)
+ {
+ if(data < start+length)
+ data++;
+ else
+ {
+ failed = true;
+ cout << "End of data."<< endl;
+ }
+ bitMask = 0x80;
+ }
+}
diff --git a/Build/source/utils/asymptote/prc/PRCTools/bitData.h b/Build/source/utils/asymptote/prc/PRCTools/bitData.h
new file mode 100644
index 00000000000..44a4fbe8167
--- /dev/null
+++ b/Build/source/utils/asymptote/prc/PRCTools/bitData.h
@@ -0,0 +1,62 @@
+/************
+*
+* This file is part of a tool for reading 3D content in the PRC format.
+* Copyright (C) 2008 Orest Shardt <shardtor (at) gmail dot com>
+*
+* This program 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 3 of the License, or
+* (at your option) any later version.
+*
+* This program 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 program. If not, see <http://www.gnu.org/licenses/>.
+*
+*************/
+
+#ifndef __BITDATA_H
+#define __BITDATA_H
+
+#include <iostream>
+#include <string>
+
+struct BitPosition
+{
+ unsigned int byteIndex;
+ unsigned int bitIndex;
+};
+
+class BitByBitData
+{
+ public:
+ BitByBitData(char* s,unsigned int l) : start(s),data(s),length(l),
+ bitMask(0x80),showBits(false),failed(false) {}
+
+ void tellPosition();
+ BitPosition getPosition();
+ void setPosition(const BitPosition&);
+ void setPosition(unsigned int,unsigned int);
+ void setShowBits(bool);
+ bool readBit();
+ unsigned char readChar();
+
+ unsigned int readUnsignedInt();
+ std::string readString();
+ int readInt();
+ double readDouble();
+
+ private:
+ char *start; // first byte so we know where we are
+ char *data; // last byte read
+ unsigned int length;
+ unsigned char bitMask; // mask to read next bit of current byte
+ bool showBits; // show each bit read?
+ bool failed;
+ void nextBit(); // shift bit mask and get next byte if needed
+};
+
+#endif // __BITDATA_H
diff --git a/Build/source/utils/asymptote/prc/PRCTools/bitSearchDouble.cc b/Build/source/utils/asymptote/prc/PRCTools/bitSearchDouble.cc
new file mode 100644
index 00000000000..5fd70cb9aac
--- /dev/null
+++ b/Build/source/utils/asymptote/prc/PRCTools/bitSearchDouble.cc
@@ -0,0 +1,67 @@
+/************
+*
+* This file is part of a tool for reading 3D content in the PRC format.
+* Copyright (C) 2008 Orest Shardt <shardtor (at) gmail dot com>
+*
+* This program 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 3 of the License, or
+* (at your option) any later version.
+*
+* This program 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 program. If not, see <http://www.gnu.org/licenses/>.
+*
+*************/
+
+#include <iostream>
+#include <fstream>
+#include <iomanip>
+#include "bitData.h"
+
+using namespace std;
+
+int main(int argc, char *argv[])
+{
+ if(argc < 2)
+ {
+ cerr << "Error: Input file not specified." << endl;
+ return 1;
+ }
+ ifstream inFile(argv[1]);
+ if(!inFile)
+ {
+ cerr << "Error: Cannot open input file." << endl;
+ return 1;
+ }
+ inFile.seekg(0,ios::end);
+ unsigned int length = inFile.tellg();
+ inFile.seekg(0,ios::beg);
+
+ char *buf = new char[length];
+
+ inFile.read(buf,length);
+ BitByBitData bbbd(buf,length);
+
+ double dsf;
+ cout << "double to search for: "; cin >> dsf;
+ BitPosition currP;
+ for(currP.byteIndex = 0; currP.byteIndex < length; ++currP.byteIndex)
+ for(currP.bitIndex = 0; currP.bitIndex < 8; ++currP.bitIndex)
+ {
+ bbbd.setPosition(currP);
+ if(bbbd.readDouble() == dsf)
+ {
+ BitPosition bp = bbbd.getPosition();
+ cout << "Found " << dsf << " at " << currP.byteIndex << ':'
+ << currP.bitIndex << " to " << bp.byteIndex << ':' << bp.bitIndex
+ << endl;
+ }
+ }
+ delete[] buf;
+ return 0;
+}
diff --git a/Build/source/utils/asymptote/prc/PRCTools/bitSearchUI.cc b/Build/source/utils/asymptote/prc/PRCTools/bitSearchUI.cc
new file mode 100644
index 00000000000..034143a1ae4
--- /dev/null
+++ b/Build/source/utils/asymptote/prc/PRCTools/bitSearchUI.cc
@@ -0,0 +1,65 @@
+/************
+*
+* This file is part of a tool for reading 3D content in the PRC format.
+* Copyright (C) 2008 Orest Shardt <shardtor (at) gmail dot com>
+*
+* This program 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 3 of the License, or
+* (at your option) any later version.
+*
+* This program 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 program. If not, see <http://www.gnu.org/licenses/>.
+*
+*************/
+
+#include <iostream>
+#include <fstream>
+#include <iomanip>
+#include "bitData.h"
+
+using namespace std;
+
+int main(int argc, char *argv[])
+{
+ if(argc < 2)
+ {
+ cerr << "Error: Input file not specified." << endl;
+ return 1;
+ }
+ ifstream inFile(argv[1]);
+ if(!inFile)
+ {
+ cerr << "Error: Cannot open input file." << endl;
+ return 1;
+ }
+ inFile.seekg(0,ios::end);
+ unsigned int length = inFile.tellg();
+ inFile.seekg(0,ios::beg);
+
+ char *buf = new char[length];
+
+ inFile.read(buf,length);
+ BitByBitData bbbd(buf,length);
+
+ unsigned int uisf;
+ cout << "Unsigned int to search for: "; cin >> uisf;
+ BitPosition currP;
+ for(currP.byteIndex = 0; currP.byteIndex < length; ++currP.byteIndex)
+ for(currP.bitIndex = 0; currP.bitIndex < 8; ++currP.bitIndex)
+ {
+ bbbd.setPosition(currP);
+ if(bbbd.readUnsignedInt() == uisf)
+ {
+ cout << "Found " << uisf << " at " << currP.byteIndex << ':'
+ << currP.bitIndex << endl;
+ }
+ }
+ delete[] buf;
+ return 0;
+}
diff --git a/Build/source/utils/asymptote/prc/PRCTools/describeMain.cc b/Build/source/utils/asymptote/prc/PRCTools/describeMain.cc
new file mode 100644
index 00000000000..329e26fe401
--- /dev/null
+++ b/Build/source/utils/asymptote/prc/PRCTools/describeMain.cc
@@ -0,0 +1,45 @@
+/************
+*
+* This file is part of a tool for reading 3D content in the PRC format.
+* Copyright (C) 2008 Orest Shardt <shardtor (at) gmail dot com>
+*
+* This program 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 3 of the License, or
+* (at your option) any later version.
+*
+* This program 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 program. If not, see <http://www.gnu.org/licenses/>.
+*
+*************/
+
+#include <iostream>
+#include <fstream>
+#include "iPRCFile.h"
+
+using namespace std;
+
+int main(int argc, char* argv[])
+{
+ if(argc < 2)
+ {
+ cerr << "Error: Input file not specified." << endl;
+ return 1;
+ }
+ ifstream inFile(argv[1]);
+ if(!inFile)
+ {
+ cerr << "Error: Cannot open input file." << endl;
+ return 1;
+ }
+
+ iPRCFile myFile(inFile);
+ myFile.describe();
+
+ return 0;
+}
diff --git a/Build/source/utils/asymptote/prc/PRCTools/describePRC.cc b/Build/source/utils/asymptote/prc/PRCTools/describePRC.cc
new file mode 100644
index 00000000000..1efedecb72f
--- /dev/null
+++ b/Build/source/utils/asymptote/prc/PRCTools/describePRC.cc
@@ -0,0 +1,2272 @@
+/************
+*
+* This file is part of a tool for reading 3D content in the PRC format.
+* Copyright (C) 2008 Orest Shardt <shardtor (at) gmail dot com>
+*
+* This program 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 3 of the License, or
+* (at your option) any later version.
+*
+* This program 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 program. If not, see <http://www.gnu.org/licenses/>.
+*
+*************/
+
+#include <iostream>
+#include <fstream>
+#include <iomanip>
+#include <string>
+#include <sstream>
+
+#include "../PRC.h"
+#include "describePRC.h"
+
+using std::ostringstream; using std::cout; using std::endl;
+using std::hex; using std::dec; using std::string; using std::setw;
+using std::setfill;
+
+// describe sections
+
+void describeGlobals(BitByBitData &mData)
+{
+ mData.tellPosition();
+ cout << getIndent() << "--Globals--" << endl;
+ if(!checkSectionCode(mData,PRC_TYPE_ASM_FileStructureGlobals))
+ return;
+ indent();
+
+ describeContentPRCBase(mData,false);
+ unsigned int numberOfReferencedFileStructures = mData.readUnsignedInt();
+ cout << getIndent() << "numberOfReferencedFileStructures "
+ << numberOfReferencedFileStructures << endl;
+ indent();
+ for(unsigned int i = 0; i < numberOfReferencedFileStructures; ++i)
+ {
+ describeCompressedUniqueID(mData);
+ }
+ dedent();
+
+ double tessellation_chord_height_ratio = mData.readDouble();
+ cout << getIndent() << "tessellation_chord_height_ratio "
+ << tessellation_chord_height_ratio << endl;
+
+ double tessellation_angle_degree = mData.readDouble();
+ cout << getIndent() << "tessellation_angle_degree "
+ << tessellation_angle_degree << endl;
+
+ string default_font_family_name = mData.readString();
+ cout << getIndent() << "default_font_family_name \""
+ << default_font_family_name << '\"' << endl;
+
+ unsigned int number_of_fonts = mData.readUnsignedInt();
+ cout << getIndent() << "number_of_fonts " << number_of_fonts << endl;
+
+ indent();
+ for(unsigned int q = 0; q < number_of_fonts; ++q)
+ {
+ string font_name = mData.readString();
+ cout << getIndent() << "font_name \"" << font_name << '\"' << endl;
+ unsigned int char_set = mData.readUnsignedInt();
+ cout << getIndent() << "char_set " << char_set << endl;
+ unsigned int number_of_font_keys = mData.readUnsignedInt();
+ cout << getIndent() << "number_of_font_keys " << number_of_font_keys
+ << endl;
+ indent();
+ for(unsigned int i = 0; i < number_of_font_keys; i++)
+ {
+ unsigned int font_size = mData.readUnsignedInt() - 1;
+ cout << getIndent() << "font_size " << font_size << endl;
+ unsigned char attributes = mData.readChar();
+ cout << getIndent() << "attributes "
+ << static_cast<unsigned int>(attributes) << endl;
+ }
+ dedent();
+ }
+ dedent();
+
+ unsigned int number_of_colours = mData.readUnsignedInt();
+ cout << getIndent() << "number_of_colours " << number_of_colours << endl;
+ indent();
+ for(unsigned int i = 0; i < number_of_colours; ++i)
+ describeRGBColour(mData);
+ dedent();
+
+ unsigned int number_of_pictures = mData.readUnsignedInt();
+ cout << getIndent() << "number_of_pictures " << number_of_pictures << endl;
+ indent();
+ for(unsigned int i=0;i<number_of_pictures;i++)
+ describePicture(mData);
+ dedent();
+
+ unsigned int number_of_texture_definitions = mData.readUnsignedInt();
+ cout << getIndent() << "number_of_texture_definitions "
+ << number_of_texture_definitions << endl;
+ indent();
+ for(unsigned int i=0;i<number_of_texture_definitions;i++)
+ describeTextureDefinition(mData);
+ dedent();
+
+
+ unsigned int number_of_materials = mData.readUnsignedInt();
+ cout << getIndent() << "number_of_materials " << number_of_materials << endl;
+ indent();
+ for(unsigned int i=0;i<number_of_materials;i++)
+ describeMaterial(mData);
+ dedent();
+
+ unsigned int number_of_line_patterns = mData.readUnsignedInt();
+ cout << getIndent() << "number_of_line_patterns "
+ << number_of_line_patterns << endl;
+ indent();
+ for(unsigned int i=0;i<number_of_line_patterns;i++)
+ describeLinePattern(mData);
+ dedent();
+
+ unsigned int number_of_styles = mData.readUnsignedInt();
+ cout << getIndent() << "number_of_styles " << number_of_styles << endl;
+ indent();
+ for(unsigned int i=0;i<number_of_styles;i++)
+ describeCategory1LineStyle(mData);
+ dedent();
+
+ unsigned int number_of_fill_patterns = mData.readUnsignedInt();
+ cout << getIndent() << "number_of_fill_patterns "
+ << number_of_fill_patterns << endl;
+ indent();
+ for(unsigned int i=0;i<number_of_fill_patterns;i++)
+ describeFillPattern(mData);
+ dedent();
+
+ unsigned int number_of_reference_coordinate_systems = mData.readUnsignedInt();
+ cout << getIndent() << "number_of_reference_coordinate_systems "
+ << number_of_reference_coordinate_systems << endl;
+ indent();
+ for(unsigned int i=0;i<number_of_reference_coordinate_systems;i++)
+ //NOTE: must be PRC_TYPE_RI_CoordinateSystem
+ describeRepresentationItem(mData);
+ dedent();
+
+ describeUserData(mData);
+ dedent();
+ mData.tellPosition();
+}
+
+void describeTree(BitByBitData &mData)
+{
+ mData.tellPosition();
+ cout << getIndent() << "--Tree--" << endl;
+ if(!checkSectionCode(mData,PRC_TYPE_ASM_FileStructureTree))
+ return;
+ indent();
+ describeContentPRCBase(mData,false);
+
+ unsigned int number_of_part_definitions = mData.readUnsignedInt();
+ cout << getIndent() << "number_of_part_definitions "
+ << number_of_part_definitions << endl;
+ indent();
+ for(unsigned int i = 0; i < number_of_part_definitions; ++i)
+ {
+ describePartDefinition(mData);
+ }
+ dedent();
+
+ unsigned int number_of_product_occurrences = mData.readUnsignedInt();
+ cout << getIndent() << "number_of_product_occurrences "
+ << number_of_product_occurrences << endl;
+ indent();
+ for(unsigned int i = 0; i < number_of_product_occurrences; ++i)
+ {
+ describeProductOccurrence(mData);
+ }
+ dedent();
+
+ describeFileStructureInternalData(mData);
+
+ describeUserData(mData);
+ dedent();
+ mData.tellPosition();
+}
+
+void describeTessellation(BitByBitData &mData)
+{
+ mData.tellPosition();
+ cout << getIndent() << "--Tessellation--" << endl;
+ if(!checkSectionCode(mData,PRC_TYPE_ASM_FileStructureTessellation))
+ return;
+ indent();
+
+ describeContentPRCBase(mData,false);
+
+ unsigned int number_of_tessellations = mData.readUnsignedInt();
+ cout << getIndent() << "number_of_tessellations "
+ << number_of_tessellations << endl;
+ indent();
+ for(unsigned int i = 0; i < number_of_tessellations; ++i)
+ {
+ unsigned int type = mData.readUnsignedInt();
+ cout << getIndent() << "tessellation type " << type << endl;
+ switch(type)
+ {
+ case PRC_TYPE_TESS_3D:
+ describe3DTess(mData);
+ break;
+ case PRC_TYPE_TESS_3D_Wire:
+ describe3DWireTess(mData);
+ break;
+ case PRC_TYPE_TESS_Markup:
+ describe3DMarkupTess(mData);
+ break;
+ case PRC_TYPE_TESS_3D_Compressed:
+ describeHighlyCompressed3DTess(mData);
+ break;
+ default:
+ cout << getIndent() << "Unrecognized tessellation data type "
+ << type << endl;
+ break;
+ }
+ }
+ dedent();
+
+ describeUserData(mData);
+
+ dedent();
+ mData.tellPosition();
+}
+
+void describeGeometry(BitByBitData &mData)
+{
+ mData.tellPosition();
+ cout << getIndent() << "--Geometry--" << endl;
+ if(!checkSectionCode(mData,PRC_TYPE_ASM_FileStructureGeometry))
+ return;
+ indent();
+
+ describeContentPRCBase(mData,false);
+
+ unsigned int number_of_topological_contexts = mData.readUnsignedInt();
+ cout << getIndent() << "number_of_topological_contexts "
+ << number_of_topological_contexts << endl;
+ indent();
+ for(unsigned int i = 0; i < number_of_topological_contexts; ++i)
+ {
+ describeTopoContext(mData);
+ unsigned int number_of_bodies = mData.readUnsignedInt();
+ cout << getIndent() << "number_of_bodies " << number_of_bodies << endl;
+ for(unsigned int i = 0; i < number_of_bodies; ++i)
+ {
+ describeBody(mData);
+ }
+ }
+ dedent();
+
+ describeUserData(mData);
+ dedent();
+ mData.tellPosition();
+}
+
+void describeExtraGeometry(BitByBitData &mData)
+{
+ mData.tellPosition();
+ cout << getIndent() << "--Extra Geometry--" << endl;
+ if(!checkSectionCode(mData,PRC_TYPE_ASM_FileStructureExtraGeometry))
+ return;
+ indent();
+
+ describeContentPRCBase(mData,false);
+
+ unsigned int number_of_contexts = mData.readUnsignedInt();
+ cout << getIndent() << "number_of_contexts " << number_of_contexts << endl;
+ indent();
+ for(unsigned int i = 0; i < number_of_contexts; ++i)
+ {
+ // geometry summary
+ unsigned int number_of_bodies = mData.readUnsignedInt();
+ cout << getIndent() << "number_of_bodies " << number_of_bodies << endl;
+ indent();
+ for(unsigned int j = 0; j < number_of_bodies; ++j)
+ {
+ unsigned int serial_type = mData.readUnsignedInt();
+ cout << getIndent() << "serial_type " << serial_type << endl;
+ indent();
+ if(isCompressedSerialType(serial_type))
+ cout << getIndent() << "serialTolerance " << mData.readDouble();
+ dedent();
+ }
+ dedent();
+ // context graphics
+ resetCurrentGraphics();
+ unsigned int number_of_treat_types = mData.readUnsignedInt();
+ cout << getIndent() << "number_of_treat_types "
+ << number_of_treat_types << endl;
+ indent();
+ for(unsigned int i = 0; i < number_of_treat_types; ++i)
+ {
+ cout << getIndent() << "element_type " << mData.readUnsignedInt() << endl;
+ unsigned int number_of_elements = mData.readUnsignedInt();
+ cout << getIndent() << "number_of_elements "
+ << number_of_elements << endl;
+ indent();
+ for(unsigned int j = 0; j < number_of_elements; ++j)
+ {
+ if(mData.readBit())
+ {
+ describeGraphics(mData);
+ }
+ else
+ {
+ cout << getIndent() << "Element has no graphics" << endl;
+ }
+ }
+ dedent();
+ }
+ dedent();
+ }
+ dedent();
+
+ describeUserData(mData);
+ dedent();
+ mData.tellPosition();
+}
+
+
+void describeModelFileData(BitByBitData &mData,
+ unsigned int numberOfFileStructures)
+{
+ mData.tellPosition();
+ cout << getIndent() << "--Model File--" << endl;
+ if(!checkSectionCode(mData,PRC_TYPE_ASM_ModelFile))
+ return;
+ indent();
+
+ describeContentPRCBase(mData,false);
+
+ describeUnit(mData);
+ unsigned int numberOfProductOccurrences = mData.readUnsignedInt();
+ cout << getIndent() << "Number of Product Occurrences "
+ << numberOfProductOccurrences << endl;
+ indent();
+ for(unsigned int i = 0; i < numberOfProductOccurrences; ++i)
+ {
+ describeCompressedUniqueID(mData);
+ cout << getIndent() << "index_position + 1 = "
+ << mData.readUnsignedInt() << endl;
+ cout << getIndent() << "active? " << (mData.readBit()?"yes":"no")
+ << endl << endl;
+ }
+ dedent();
+ for(unsigned int i = 0; i < numberOfFileStructures; ++i)
+ {
+ cout << getIndent() << "File Structure Index in Model File "
+ << mData.readUnsignedInt() << endl;
+ }
+
+ describeUserData(mData);
+ dedent();
+ mData.tellPosition();
+}
+
+// subsections
+// void describe(BitByBitData &mData)
+// {
+//
+// }
+
+void describeLight(BitByBitData &mData)
+{
+ unsigned int ID = mData.readUnsignedInt();
+ if(ID == PRC_TYPE_GRAPH_AmbientLight)
+ cout << getIndent() << "--Ambient Light--" << endl;
+ else
+ return;
+
+ indent();
+
+ describeContentPRCBase(mData,true);
+
+ cout << getIndent() << "ambient colour index: " << mData.readUnsignedInt()-1 << endl
+ << getIndent() << "diffuse colour index: " << mData.readUnsignedInt()-1 << endl
+ << getIndent() << "specular colour index: " << mData.readUnsignedInt()-1 << endl;
+
+ describeUserData(mData);
+ describeUserData(mData); // why?
+ dedent();
+}
+
+void describeCamera(BitByBitData &mData)
+{
+ cout << getIndent() << "--Camera--" << endl;
+ if(!checkSectionCode(mData,PRC_TYPE_GRAPH_Camera))
+ return;
+ indent();
+
+ describeContentPRCBase(mData,true);
+
+ cout << getIndent() << (mData.readBit()?"orthographic":"perspective") << endl;
+ cout << getIndent() << "Camera Position" << endl;
+ describeVector3d(mData);
+ cout << getIndent() << "Look At Point" << endl;
+ describeVector3d(mData);
+ cout << getIndent() << "Up" << endl;
+ describeVector3d(mData);
+ cout << getIndent() << "X field of view angle (perspective) || X scale (orthographic) "
+ << mData.readDouble() << endl;
+ cout << getIndent() << "Y field of view angle (perspective) || Y scale (orthographic) "
+ << mData.readDouble() << endl;
+ cout << getIndent() << "aspect ratio x/y " << mData.readDouble() << endl;
+ cout << getIndent() << "near z clipping plane distance from viewer " << mData.readDouble() << endl;
+ cout << getIndent() << "far z clipping plane distance from viewer " << mData.readDouble() << endl;
+ cout << getIndent() << "zoom factor " << mData.readDouble() << endl;
+ dedent();
+}
+
+bool describeContentCurve(BitByBitData &mData)
+{
+ describeBaseGeometry(mData);
+ cout << getIndent() << "extend_info " << mData.readUnsignedInt() << endl;
+ bool is_3d = mData.readBit();
+ cout << getIndent() << "is_3d " << (is_3d?"yes":"no") << endl;
+ return is_3d;
+}
+
+void describeParameterization(BitByBitData &mData)
+{
+ cout << getIndent() << "--Parameterization--" << endl;
+ indent();
+ describeExtent1d(mData);
+ cout << getIndent() << "parameterization_coeff_a " << mData.readDouble()
+ << endl;
+ cout << getIndent() << "parameterization_coeff_b " << mData.readDouble()
+ << endl;
+ dedent();
+}
+
+void describeCurvCircle(BitByBitData &mData)
+{
+ cout << getIndent() << "--Circle--" << endl;
+ indent();
+
+ if(describeContentCurve(mData))
+ describeTransformation3d(mData);
+ else
+ describeTransformation2d(mData);
+
+ describeParameterization(mData);
+
+ cout << getIndent() << "radius " << mData.readDouble() << endl;
+
+ dedent();
+}
+
+void describeCurvLine(BitByBitData &mData)
+{
+ cout << getIndent() << "--Line--" << endl;
+ indent();
+
+ if(describeContentCurve(mData))
+ describeTransformation3d(mData);
+ else
+ describeTransformation2d(mData);
+
+ describeParameterization(mData);
+
+ dedent();
+}
+
+void describeContentWireEdge(BitByBitData &mData)
+{
+ cout << getIndent() << "--WireEdge--" << endl;
+ indent();
+
+ describeBaseTopology(mData);
+
+ describeObject(mData); //3d_curve
+
+ bool curve_trim_interval = mData.readBit();
+ cout << getIndent() << "curve_trim_interval "
+ << (curve_trim_interval?"yes":"no") << endl;
+ if(curve_trim_interval)
+ {
+ describeExtent1d(mData);
+ }
+
+ dedent();
+}
+
+void describeUVParametrization(BitByBitData &mData)
+{
+ cout << getIndent() << "--UV Parameterization--" << endl;
+ indent();
+
+ cout << getIndent() << "swap_uv " << (mData.readBit()?"yes":"no") << endl;
+ cout << getIndent() << "Domain" << endl;
+ indent(); describeExtent2d(mData); dedent();
+ cout << getIndent() << "parameterization_on_u_coeff_a "
+ << mData.readDouble() << endl;
+ cout << getIndent() << "parameterization_on_v_coeff_a "
+ << mData.readDouble() << endl;
+ cout << getIndent() << "parameterization_on_u_coeff_b "
+ << mData.readDouble() << endl;
+ cout << getIndent() << "parameterization_on_v_coeff_b "
+ << mData.readDouble() << endl;
+
+ dedent();
+}
+
+bool isCompressedSerialType(unsigned int type)
+{
+ return false; // TODO: actually check the type!!!
+}
+
+void describeSurfNURBS(BitByBitData &mData)
+{
+ cout << getIndent() << "--NURBS surface--" << endl;
+ indent();
+
+ describeContentSurface(mData);
+
+ bool is_rational = mData.readBit();
+ cout << getIndent() << "is_rational " << (is_rational?"yes":"no") << endl;
+
+ unsigned int degree_in_u = mData.readUnsignedInt();
+ cout << getIndent() << "degree_in_u " << degree_in_u << endl;
+ unsigned int degree_in_v = mData.readUnsignedInt();
+ cout << getIndent() << "degree_in_v " << degree_in_v << endl;
+
+ unsigned int number_of_control_points_in_u = mData.readUnsignedInt()+1;
+ cout << getIndent() << "number_of_control_points_in_u "
+ << number_of_control_points_in_u << endl;
+ unsigned int number_of_control_points_in_v = mData.readUnsignedInt()+1;
+ cout << getIndent() << "number_of_control_points_in_v "
+ << number_of_control_points_in_v << endl;
+
+ unsigned int number_of_knots_in_u = mData.readUnsignedInt()+1;
+ cout << getIndent() << "number_of_knots_in_u "
+ << number_of_knots_in_u << endl;
+ unsigned int number_of_knots_in_v = mData.readUnsignedInt()+1;
+ cout << getIndent() << "number_of_knots_in_v "
+ << number_of_knots_in_v << endl;
+
+ indent();
+ for(unsigned int i = 0; i < number_of_control_points_in_u; ++i)
+ {
+ for(unsigned int j = 0; j < number_of_control_points_in_v; ++j)
+ {
+ double x = mData.readDouble();
+ double y = mData.readDouble();
+ double z = mData.readDouble();
+ cout << getIndent() << "control point " << i << ' ' << j << ": ("
+ << x << ',' << y << ',' << z;
+
+ if(is_rational)
+ cout << ',' << mData.readDouble();
+
+ cout << ')' << endl;
+ }
+ }
+ dedent();
+
+ cout << getIndent() << "knots in u" << endl;
+ indent();
+ for(unsigned int i = 0; i < number_of_knots_in_u; ++i)
+ cout << getIndent() << mData.readDouble() << endl;
+ dedent();
+
+ cout << getIndent() << "knots in v" << endl;
+ indent();
+ for(unsigned int i = 0; i < number_of_knots_in_v; ++i)
+ cout << getIndent() << mData.readDouble() << endl;
+ dedent();
+
+ cout << getIndent() << "knot_type " << mData.readUnsignedInt() << endl;
+ cout << getIndent() << "surface_form " << mData.readUnsignedInt() << endl;
+
+ dedent();
+}
+
+void describeCurvNURBS(BitByBitData &mData)
+{
+ cout << getIndent() << "--NURBS curve--" << endl;
+ indent();
+ describeContentCurve(mData);
+
+ bool is_rational = mData.readBit();
+ cout << getIndent() << "is_rational " << (is_rational?"yes":"no") << endl;
+
+ unsigned int degree = mData.readUnsignedInt();
+ cout << getIndent() << "degree " << degree << endl;
+
+ unsigned int number_of_control_points = mData.readUnsignedInt()+1;
+ cout << getIndent() << "number_of_control_points "
+ << number_of_control_points << endl;
+
+ unsigned int number_of_knots = mData.readUnsignedInt()+1;
+ cout << getIndent() << "number_of_knots " << number_of_knots << endl;
+
+ indent();
+ for(unsigned int i = 0; i < number_of_control_points; ++i)
+ {
+ double x = mData.readDouble();
+ double y = mData.readDouble();
+ double z = mData.readDouble();
+ cout << getIndent() << "control point " << i << ": ("
+ << x << ',' << y << ',' << z;
+
+ if(is_rational)
+ cout << ',' << mData.readDouble();
+
+ cout << ')' << endl;
+ }
+ dedent();
+
+ cout << getIndent() << "knots" << endl;
+ indent();
+ for(unsigned int i = 0; i < number_of_knots; ++i)
+ cout << getIndent() << mData.readDouble() << endl;
+ dedent();
+
+ cout << getIndent() << "knot_type " << mData.readUnsignedInt() << endl;
+ cout << getIndent() << "surface_form " << mData.readUnsignedInt() << endl;
+
+ dedent();
+}
+
+void describeCurvPolyLine(BitByBitData &mData)
+{
+ cout << getIndent() << "--PolyLine--" << endl;
+ indent();
+ describeContentCurve(mData);
+ describeTransformation3d(mData);
+ describeParameterization(mData);
+
+ unsigned int number_of_points = mData.readUnsignedInt();
+ cout << getIndent() << "number_of_points " << number_of_points << endl;
+
+ indent();
+ for(unsigned int i = 0; i < number_of_points; ++i)
+ {
+ describeVector3d(mData);
+ }
+ dedent();
+
+ dedent();
+}
+
+void describeSurfCylinder(BitByBitData &mData)
+{
+ cout << getIndent() << "--Cylinder surface--" << endl;
+ indent();
+
+ describeContentSurface(mData);
+ describeTransformation3d(mData);
+ describeUVParametrization(mData);
+ cout << getIndent() << "radius " << mData.readDouble() << endl;
+
+ dedent();
+}
+
+void describeSurfPlane(BitByBitData &mData)
+{
+ cout << getIndent() << "--Plane surface--" << endl;
+ indent();
+ mData.setShowBits(true);
+ describeContentSurface(mData);
+ mData.tellPosition();
+ //TODO: something is wrong, very wrong!!!
+ // For now, all this does is search until the end of the data block,
+ // assuming that the default parameterization [-inf,inf]x[-inf,inf] was used
+ BitPosition bp = mData.getPosition();
+ double nInf1 = mData.readDouble();
+ double nInf2 = mData.readDouble();
+ double inf1 = mData.readDouble();
+ double inf2 = mData.readDouble();
+ double one1 = mData.readDouble();
+ double one2 = mData.readDouble();
+ double zero1 = mData.readDouble();
+ double zero2 = mData.readDouble();
+ while(!(nInf1 == -12345.0 && nInf2 == -12345.0 && inf1 == 12345.0
+ && inf2 == 12345.0 && one1 == 1.0 && one2 == 1.0 && zero1 == 0.0
+ && zero2 == 0.0))
+ {
+ mData.setPosition(bp);
+ cout << mData.readBit();
+ bp = mData.getPosition();
+
+ nInf1 = mData.readDouble();
+ nInf2 = mData.readDouble();
+ inf1 = mData.readDouble();
+ inf2 = mData.readDouble();
+ one1 = mData.readDouble();
+ one2 = mData.readDouble();
+ zero1 = mData.readDouble();
+ zero2 = mData.readDouble();
+ }
+ cout << endl;
+ if(bp.bitIndex == 0)
+ {
+ bp.bitIndex = 7;
+ --bp.byteIndex;
+ }
+ else
+ {
+ --bp.bitIndex;
+ }
+ mData.setPosition(bp);
+
+/*
+ // this is what the 8137 docs say it should be
+ describeTransformation3d(mData);
+ cout << getIndent() << "UV domain" << endl;
+ indent();
+ cout << getIndent() << "Min: " << endl;
+ describeVector2d(mData);
+ cout << getIndent() << "Max: " << endl;
+ describeVector2d(mData);
+ dedent();
+
+ cout << getIndent() << "u coef. a = " << mData.readDouble() << endl;
+ cout << getIndent() << "v coef. a = " << mData.readDouble() << endl;
+ cout << getIndent() << "u coef. b = " << mData.readDouble() << endl;
+ cout << getIndent() << "v coef. b = " << mData.readDouble() << endl;
+*/
+ mData.setShowBits(false);
+ dedent();
+}
+
+void describeTopoFace(BitByBitData &mData)
+{
+ cout << getIndent() << "--Face--" << endl;
+ indent();
+
+ describeBaseTopology(mData);
+
+ cout << getIndent() << "base_surface" << endl;
+ indent();
+ describeObject(mData);
+ dedent();
+
+ bool surface_trim_domain = mData.readBit();
+ cout << getIndent() << "surface_trim_domain "
+ << (surface_trim_domain?"yes":"no") << endl;
+ if(surface_trim_domain)
+ {
+ indent();
+ describeExtent2d(mData);
+ dedent();
+ }
+
+ bool have_tolerance = mData.readBit();
+ cout << getIndent() << "have_tolerance "
+ << (have_tolerance?"yes":"no") << endl;
+ if(have_tolerance)
+ cout << getIndent() << "tolerance " << mData.readDouble() << endl;
+
+ unsigned int number_of_loops = mData.readUnsignedInt();
+ cout << getIndent() << "number_of_loops " << number_of_loops << endl;
+ cout << getIndent() << "outer_loop_index " << mData.readInt() << endl;
+ indent();
+ for(unsigned int i = 0; i < number_of_loops; ++i)
+ {
+ describeObject(mData);
+ }
+ dedent();
+
+ dedent();
+}
+
+void describeTopoLoop(BitByBitData &mData)
+{
+ cout << getIndent() << "--Loop--" << endl;
+ indent();
+
+ describeBaseTopology(mData);
+
+ cout << getIndent() << "orientation_with_surface "
+ << static_cast<unsigned int>(mData.readChar()) << endl;
+ unsigned int number_of_coedge = mData.readUnsignedInt();
+ cout << getIndent() << "number_of_coedge " << number_of_coedge << endl;
+ indent();
+ for(unsigned int i = 0; i < number_of_coedge; ++i)
+ {
+ describeObject(mData);
+ cout << getIndent() << "neigh_serial_index "
+ << mData.readUnsignedInt() << endl;
+ }
+ dedent();
+
+ dedent();
+}
+
+void describeTopoCoEdge(BitByBitData &mData)
+{
+ cout << getIndent() << "--CoEdge--" << endl;
+ indent();
+
+ describeBaseTopology(mData);
+
+ describeObject(mData); // edge
+ describeObject(mData); // uv_curve
+ cout << getIndent() << "orientation_with_loop "
+ << static_cast<unsigned int>(mData.readChar()) << endl;
+ cout << getIndent() << "orientation_uv_with_loop "
+ << static_cast<unsigned int>(mData.readChar()) << endl;
+ dedent();
+}
+
+void describeTopoEdge(BitByBitData &mData)
+{
+ cout << getIndent() << "--Edge--" << endl;
+ indent();
+
+ describeContentWireEdge(mData);
+
+ describeObject(mData); // vertex_start
+ describeObject(mData); // vertex_end
+
+ bool have_tolerance = mData.readBit();
+ cout << getIndent() << "have_tolerance "
+ << (have_tolerance?"yes":"no") << endl;
+ if(have_tolerance)
+ cout << getIndent() << "tolerance " << mData.readDouble() << endl;
+ dedent();
+}
+
+void describeTopoUniqueVertex(BitByBitData &mData)
+{
+ cout << getIndent() << "--Unique Vertex--" << endl;
+ indent();
+
+ describeBaseTopology(mData);
+ describeVector3d(mData);
+
+ bool have_tolerance = mData.readBit();
+ cout << getIndent() << "have_tolerance "
+ << (have_tolerance?"yes":"no") << endl;
+ if(have_tolerance)
+ cout << getIndent() << "tolerance " << mData.readDouble() << endl;
+
+ dedent();
+}
+
+void describeTopoConnex(BitByBitData &mData)
+{
+ cout << getIndent() << "--Connex--" << endl;
+ indent();
+ describeBaseTopology(mData);
+ unsigned int number_of_shells = mData.readUnsignedInt();
+ cout << getIndent() << "number_of_shells "
+ << number_of_shells << endl;
+ indent();
+ for(unsigned int i = 0; i < number_of_shells; ++i)
+ {
+ // NOTE: this does not check if the objects are actually shells!
+ describeObject(mData);
+ }
+ dedent();
+
+ dedent();
+}
+
+void describeTopoShell(BitByBitData &mData)
+{
+ cout << getIndent() << "--Shell--" << endl;
+ indent();
+
+ describeBaseTopology(mData);
+
+ cout << getIndent() << "shell_is_closed "
+ << (mData.readBit()?"yes":"no") << endl;
+
+ unsigned int number_of_faces = mData.readUnsignedInt();
+ cout << getIndent() << "number_of_faces " << number_of_faces << endl;
+ for(unsigned int i = 0; i < number_of_faces; ++i)
+ {
+ // NOTE: this does not check if the objects are actually faces!
+ describeObject(mData);
+ unsigned char orientation = mData.readChar();
+ cout << getIndent() << "orientation_surface_with_shell "
+ << static_cast<unsigned int>(orientation) << endl;
+ }
+
+ dedent();
+}
+
+void describeObject(BitByBitData &mData)
+{
+ cout << getIndent() << "--Object--" << endl;
+ bool already_stored = mData.readBit();
+ cout << getIndent() << "already_stored "
+ << (already_stored?"yes":"no") << endl;
+ if(already_stored) // reverse of documentation?
+ {
+ cout << getIndent() << "index of stored item "
+ << mData.readUnsignedInt() << endl;
+ }
+ else
+ {
+ unsigned int type = mData.readUnsignedInt();
+ switch(type)
+ {
+ case PRC_TYPE_ROOT:
+ cout << getIndent() << "NULL Object" << endl;
+ break;
+ // topological items
+ case PRC_TYPE_TOPO_Connex:
+ describeTopoConnex(mData);
+ break;
+ case PRC_TYPE_TOPO_Shell:
+ describeTopoShell(mData);
+ break;
+ case PRC_TYPE_TOPO_Face:
+ describeTopoFace(mData);
+ break;
+ case PRC_TYPE_TOPO_Loop:
+ describeTopoLoop(mData);
+ break;
+ case PRC_TYPE_TOPO_CoEdge:
+ describeTopoCoEdge(mData);
+ break;
+ case PRC_TYPE_TOPO_Edge:
+ describeTopoEdge(mData);
+ break;
+ case PRC_TYPE_TOPO_UniqueVertex:
+ describeTopoUniqueVertex(mData);
+ break;
+ case PRC_TYPE_TOPO_WireEdge:
+ describeContentWireEdge(mData);
+ break;
+
+ // curves
+ case PRC_TYPE_CRV_Circle:
+ describeCurvCircle(mData);
+ break;
+ case PRC_TYPE_CRV_NURBS:
+ describeCurvNURBS(mData);
+ break;
+ case PRC_TYPE_CRV_PolyLine:
+ describeCurvPolyLine(mData);
+ break;
+ case PRC_TYPE_CRV_Line:
+ describeCurvLine(mData);
+ break;
+ // surfaces
+ case PRC_TYPE_SURF_NURBS:
+ describeSurfNURBS(mData);
+ break;
+ case PRC_TYPE_SURF_Cylinder:
+ describeSurfCylinder(mData);
+ break;
+ case PRC_TYPE_SURF_Plane:
+ describeSurfPlane(mData);
+ break;
+
+ // topological items
+ case PRC_TYPE_TOPO_Item:
+ case PRC_TYPE_TOPO_MultipleVertex:
+
+
+ // curves
+ case PRC_TYPE_CRV_Base:
+ case PRC_TYPE_CRV_Blend02Boundary:
+ case PRC_TYPE_CRV_Composite:
+ case PRC_TYPE_CRV_OnSurf:
+ case PRC_TYPE_CRV_Ellipse:
+ case PRC_TYPE_CRV_Equation:
+ case PRC_TYPE_CRV_Helix:
+ case PRC_TYPE_CRV_Hyperbola:
+ case PRC_TYPE_CRV_Intersection:
+ case PRC_TYPE_CRV_Offset:
+ case PRC_TYPE_CRV_Parabola:
+ case PRC_TYPE_CRV_Transform:
+
+ // surfaces
+ case PRC_TYPE_SURF_Base:
+ case PRC_TYPE_SURF_Blend01:
+ case PRC_TYPE_SURF_Blend02:
+ case PRC_TYPE_SURF_Blend03:
+ case PRC_TYPE_SURF_Cone:
+ case PRC_TYPE_SURF_Cylindrical:
+ case PRC_TYPE_SURF_Offset:
+ case PRC_TYPE_SURF_Pipe:
+ case PRC_TYPE_SURF_Ruled:
+ case PRC_TYPE_SURF_Sphere:
+ case PRC_TYPE_SURF_Revolution:
+ case PRC_TYPE_SURF_Extrusion:
+ case PRC_TYPE_SURF_FromCurves:
+ case PRC_TYPE_SURF_Torus:
+ case PRC_TYPE_SURF_Transform:
+ case PRC_TYPE_SURF_Blend04:
+ cout << getIndent() << "TODO: Unhandled object of type "
+ << type << endl;
+ break;
+ default:
+ cout << getIndent() << "Invalid object of type " << type << endl;
+ break;
+ }
+ }
+}
+
+void describeBaseTopology(BitByBitData &mData)
+{
+ bool base_information = mData.readBit();
+ cout << getIndent() << "base_information " <<
+ (base_information?"yes":"no") << endl;
+ if(base_information)
+ {
+ describeAttributes(mData);
+ describeName(mData);
+ cout << getIndent() << "identifier " << mData.readUnsignedInt() << endl;
+ }
+}
+
+void describeBaseGeometry(BitByBitData &mData)
+{
+ bool base_information = mData.readBit();
+ cout << getIndent() << "base_information " <<
+ (base_information?"yes":"no") << endl;
+ if(base_information)
+ {
+ describeAttributes(mData);
+ describeName(mData);
+ cout << getIndent() << "identifier " << mData.readUnsignedInt() << endl;
+ }
+}
+
+unsigned int describeContentBody(BitByBitData &mData)
+{
+ describeBaseTopology(mData);
+ unsigned int behaviour = static_cast<unsigned int>(mData.readChar());
+ cout << getIndent() << "behaviour " << behaviour << endl;
+ return behaviour;
+}
+
+void describeContentSurface(BitByBitData &mData)
+{
+ describeBaseGeometry(mData);
+ cout << getIndent() << "extend_info " << mData.readUnsignedInt() << endl;
+}
+
+void describeBody(BitByBitData &mData)
+{
+ cout << getIndent() << "--Body--" << endl;
+ unsigned int type = mData.readUnsignedInt();
+ switch(type)
+ {
+ case PRC_TYPE_TOPO_BrepData:
+ {
+ cout << getIndent() << "--PRC_TYPE_TOPO_BrepData--" << endl;
+ unsigned int behaviour = describeContentBody(mData);
+
+ unsigned int number_of_connex = mData.readUnsignedInt();
+ cout << getIndent() << "number_of_connex " << number_of_connex << endl;
+ indent();
+ for(unsigned int i = 0; i < number_of_connex; ++i)
+ {
+ describeObject(mData);
+ }
+ dedent();
+ if(behaviour != 0)
+ {
+ cout << getIndent() << "bbox " << endl;
+ indent();
+ describeExtent3d(mData);
+ dedent();
+ }
+ break;
+ }
+ case PRC_TYPE_TOPO_SingleWireBody:
+ {
+ cout << getIndent() << "--PRC_TYPE_TOPO_SingleWireBody--" << endl;
+ // unsigned int behaviour = describeContentBody(mData);
+ // TODO: is behaviour needed to get data about how to describe?
+ describeContentBody(mData);
+
+ describeObject(mData); // curve
+
+ break;
+ }
+ case PRC_TYPE_TOPO_BrepDataCompress:
+ case PRC_TYPE_TOPO_SingleWireBodyCompress:
+ cout << getIndent() << "TODO: Unhandled body type " << type << endl;
+ break;
+ default:
+ cout << getIndent() << "Invalid body type " << type << endl;
+ break;
+ }
+}
+
+void describeTopoContext(BitByBitData &mData)
+{
+ cout << getIndent() << "--Topological Context--" << endl;
+ if(!checkSectionCode(mData,PRC_TYPE_TOPO_Context))
+ return;
+ indent();
+
+ describeContentPRCBase(mData,false);
+
+ cout << getIndent() << "behaviour "
+ << static_cast<unsigned int>(mData.readChar()) << endl;
+ cout << getIndent() << "granularity " << mData.readDouble() << endl;
+ cout << getIndent() << "tolerance " << mData.readDouble() << endl;
+
+ bool have_smallest_face_thickness = mData.readBit();
+ cout << getIndent() << "have_smallest_face_thickness "
+ << (have_smallest_face_thickness?"yes":"no") << endl;
+ if(have_smallest_face_thickness)
+ cout << getIndent() << "smallest_thickness " << mData.readDouble() << endl;
+
+ bool have_scale = mData.readBit();
+ cout << getIndent() << "have_scale " << (have_scale?"yes":"no") << endl;
+ if(have_scale)
+ cout << getIndent() << "scale " << mData.readDouble() << endl;
+
+ dedent();
+}
+
+void describeLineAttr(BitByBitData& mData)
+{
+ cout << getIndent() << "index_of_line_style "
+ << mData.readUnsignedInt()-1 << endl;
+}
+
+void describeArrayRGBA(BitByBitData& mData, int number_of_colours,
+ int number_by_vector)
+{
+ // bool new_colour = true; // not currently used
+ for(int i = 0; i < number_by_vector; ++i)
+ {
+ cout << getIndent() << static_cast<unsigned int>(mData.readChar()) << ' ';
+ cout << static_cast<unsigned int>(mData.readChar()) << ' ';
+ cout << static_cast<unsigned int>(mData.readChar()) << endl;
+ //TODO: finish this
+ }
+}
+
+void describeContentBaseTessData(BitByBitData &mData)
+{
+ cout << getIndent() << "is_calculated "
+ << (mData.readBit()?"yes":"no") << endl;
+ unsigned int number_of_coordinates = mData.readUnsignedInt();
+ cout << getIndent() << "number_of_coordinates "
+ << number_of_coordinates << endl;
+ indent();
+ for(unsigned int i = 0; i < number_of_coordinates; ++i)
+ {
+ cout << getIndent() << mData.readDouble() << endl;
+ }
+ dedent();
+}
+
+void describeTessFace(BitByBitData &mData)
+{
+ cout << getIndent() << "--Tessellation Face--" << endl;
+ if(!checkSectionCode(mData,PRC_TYPE_TESS_Face))
+ return;
+ indent();
+
+ unsigned int size_of_line_attributes = mData.readUnsignedInt();
+ cout << getIndent() << "size_of_line_attributes "
+ << size_of_line_attributes << endl;
+ indent();
+ for(unsigned int i = 0; i < size_of_line_attributes; ++i)
+ {
+ describeLineAttr(mData);
+ }
+ dedent();
+
+ unsigned int start_wire = mData.readUnsignedInt();
+ cout << getIndent() << "start_wire " << start_wire << endl;
+ unsigned int size_of_sizes_wire = mData.readUnsignedInt();
+ cout << getIndent() << "size_of_sizes_wire " << size_of_sizes_wire << endl;
+ indent();
+ for(unsigned int i = 0; i < size_of_sizes_wire; ++i)
+ {
+ cout << getIndent() << mData.readUnsignedInt() << endl;
+ }
+ dedent();
+
+
+ unsigned int used_entities_flag = mData.readUnsignedInt();
+ cout << getIndent() << "used_entities_flag " << used_entities_flag << endl;
+
+ unsigned int start_triangulated = mData.readUnsignedInt();
+ cout << getIndent() << "start_triangulated " << start_triangulated << endl;
+ unsigned int size_of_sizes_triangulated = mData.readUnsignedInt();
+ cout << getIndent() << "size_of_sizes_triangulated "
+ << size_of_sizes_triangulated << endl;
+ indent();
+ for(unsigned int i = 0; i < size_of_sizes_triangulated; ++i)
+ {
+ cout << getIndent() << mData.readUnsignedInt() << endl;
+ }
+ dedent();
+
+ cout << getIndent() << "number_of_texture_coordinate_indexes "
+ << mData.readUnsignedInt() << endl;
+
+ bool has_vertex_colors = mData.readBit();
+ cout << getIndent() << "has_vertex_colors "
+ << (has_vertex_colors?"yes":"no") << endl;
+ indent();
+ if(has_vertex_colors)
+ {
+ bool is_rgba = mData.readBit();
+ cout << getIndent() << "is_rgba " << (is_rgba?"yes":"no") << endl;
+
+ bool b_optimised = mData.readBit();
+ cout << getIndent() << "b_optimised " << (b_optimised?"yes":"no") << endl;
+ if(!b_optimised)
+ {
+ indent();
+ //TODO: compute size of Array and pass it instead of 0
+ describeArrayRGBA(mData,0,(is_rgba ? 4 : 3));
+ dedent();
+ }
+ else
+ {
+ // not described
+ // what does this mean? that this should not happen?
+ // or is omitted from the docs?
+ }
+ }
+ dedent();
+
+ if(size_of_line_attributes)
+ {
+ cout << getIndent() << "behaviour " << mData.readUnsignedInt() << endl;
+ }
+
+ dedent();
+}
+
+void describe3DTess(BitByBitData &mData)
+{
+ cout << getIndent() << "--3D Tessellation--" << endl;
+ indent();
+
+ describeContentBaseTessData(mData);
+
+ cout << getIndent() << "has_faces " << (mData.readBit()?"yes":"no") << endl;
+ cout << getIndent() << "has_loops " << (mData.readBit()?"yes":"no") << endl;
+
+ bool must_recalculate_normals = mData.readBit();
+ cout << getIndent() << "must_recalculate_normals "
+ << (must_recalculate_normals?"yes":"no") << endl;
+ indent();
+ if(must_recalculate_normals)
+ {
+ cout << getIndent()
+ << "Docs were wrong: must_recalculate_normals is true." << endl;
+ cout << getIndent() << "normals_recalculation_flags "
+ << static_cast<unsigned int>(mData.readChar()) << endl;
+ cout << getIndent() << "crease_angle " << mData.readDouble() << endl;
+ }
+ dedent();
+
+ unsigned int number_of_normal_coordinates = mData.readUnsignedInt();
+ cout << getIndent() << "number_of_normal_coordinates "
+ << number_of_normal_coordinates << endl;
+ indent();
+ for(unsigned int i = 0; i < number_of_normal_coordinates; ++i)
+ {
+ cout << getIndent() << mData.readDouble() << endl;
+ }
+ dedent();
+
+ unsigned int number_of_wire_indices = mData.readUnsignedInt();
+ cout << getIndent() << "number_of_wire_indices "
+ << number_of_wire_indices << endl;
+ indent();
+ for(unsigned int i = 0; i < number_of_wire_indices; ++i)
+ {
+ cout << getIndent() << mData.readUnsignedInt() << endl;
+ }
+ dedent();
+
+ unsigned int number_of_triangulated_indices = mData.readUnsignedInt();
+ cout << getIndent() << "number_of_triangulated_indices "
+ << number_of_triangulated_indices << endl;
+ indent();
+ for(unsigned int i = 0; i < number_of_triangulated_indices; ++i)
+ {
+ cout << getIndent() << mData.readUnsignedInt() << endl;
+ }
+ dedent();
+
+ unsigned int number_of_face_tessellation = mData.readUnsignedInt();
+ cout << getIndent() << "number_of_face_tessellation "
+ << number_of_face_tessellation << endl;
+ indent();
+ for(unsigned int i = 0; i < number_of_face_tessellation; ++i)
+ {
+ describeTessFace(mData);
+ }
+ dedent();
+
+ unsigned int number_of_texture_coordinates = mData.readUnsignedInt();
+ cout << getIndent() << "number_of_texture_coordinates "
+ << number_of_texture_coordinates << endl;
+ indent();
+ for(unsigned int i = 0; i < number_of_texture_coordinates; ++i)
+ {
+ cout << getIndent() << mData.readDouble() << endl;
+ }
+ dedent();
+
+ dedent();
+}
+
+void describe3DWireTess(BitByBitData &mData)
+{
+ //TODO
+}
+
+void describe3DMarkupTess(BitByBitData &mData)
+{
+ //TODO
+}
+
+void describeHighlyCompressed3DTess(BitByBitData &mData)
+{
+ //TODO
+}
+
+void describeSceneDisplayParameters(BitByBitData &mData)
+{
+ cout << getIndent() << "--Scene Display Parameters--" << endl;
+ if(!checkSectionCode(mData,PRC_TYPE_GRAPH_SceneDisplayParameters))
+ return;
+ indent();
+ describeContentPRCBase(mData,true);
+
+ cout << getIndent() << "is active? " << (mData.readBit()?"yes":"no") << endl;
+
+ unsigned int number_of_lights = mData.readUnsignedInt();
+ cout << getIndent() << "number of lights " << number_of_lights << endl;
+ indent();
+ for(unsigned int i = 0; i < number_of_lights; ++i)
+ {
+ describeLight(mData);
+ }
+ dedent();
+
+ bool camera = mData.readBit();
+ cout << getIndent() << "camera? " << (camera?"yes":"no") << endl;
+ if(camera)
+ describeCamera(mData);
+
+ bool rotation_centre = mData.readBit();
+ cout << getIndent() << "rotation centre? " << (rotation_centre?"yes":"no") << endl;
+ if(rotation_centre)
+ describeVector3d(mData);
+
+ unsigned int number_of_clipping_planes = mData.readUnsignedInt();
+ cout << getIndent() << "number of clipping planes " << number_of_clipping_planes << endl;
+ indent();
+ for(unsigned int i = 0; i < number_of_clipping_planes; ++i)
+ {
+ cout << "Can't describe planes!!!" << endl;
+ //describePlane(mData);
+ }
+ dedent();
+
+ cout << getIndent() << "Background line style index: " << mData.readUnsignedInt()-1 << endl;
+ cout << getIndent() << "Default line style index: " << mData.readUnsignedInt()-1 << endl;
+
+ unsigned int number_of_default_styles_per_type = mData.readUnsignedInt();
+ cout << getIndent() << "number_of_default_styles_per_type " << number_of_default_styles_per_type << endl;
+ indent();
+ for(unsigned int i = 0; i < number_of_default_styles_per_type; ++i)
+ {
+ cout << getIndent() << "type " << mData.readUnsignedInt() << endl;
+ cout << getIndent() << "line style index: " << mData.readUnsignedInt()-1 << endl;
+ }
+ dedent();
+
+ dedent();
+}
+
+void describeCartesionTransformation3d(BitByBitData& mData)
+{
+ cout << getIndent() << "--3d Cartesian Transformation--" << endl;
+ if(!checkSectionCode(mData,PRC_TYPE_MISC_CartesianTransformation))
+ return;
+ indent();
+ unsigned char behaviour = mData.readChar();
+ cout << getIndent() << "behaviour "
+ << static_cast<unsigned int>(behaviour) << endl;
+ if((behaviour & PRC_TRANSFORMATION_Translate) != 0)
+ {
+ cout << getIndent() << "Translation" << endl;
+ describeVector3d(mData);
+ }
+
+ if((behaviour & PRC_TRANSFORMATION_NonOrtho) != 0)
+ {
+ cout << getIndent() << "Non orthogonal transformation" << endl;
+ cout << getIndent() << "X" << endl; describeVector3d(mData);
+ cout << getIndent() << "Y" << endl; describeVector3d(mData);
+ cout << getIndent() << "Z" << endl; describeVector3d(mData);
+ }
+ else if((behaviour & PRC_TRANSFORMATION_Rotate) != 0)
+ {
+ cout << getIndent() << "Rotation" << endl;
+ cout << getIndent() << "X" << endl; describeVector3d(mData);
+ cout << getIndent() << "Y" << endl; describeVector3d(mData);
+ }
+
+ // this is different from the docs!!! but it works...
+ if ((behaviour & PRC_TRANSFORMATION_NonUniformScale) != 0)
+ {
+ cout << getIndent() << "Non-uniform scale by " << endl;
+ describeVector3d(mData);
+ }
+
+ // this is different from the docs!!! but it works...
+ if((behaviour & PRC_TRANSFORMATION_Scale) != 0)
+ {
+ cout << getIndent() << "Uniform Scale by " << mData.readDouble() << endl;
+ }
+
+ if((behaviour & PRC_TRANSFORMATION_Homogeneous) != 0)
+ {
+ cout << getIndent() << "transformation has homogenous values" << endl;
+ cout << getIndent() << "x = " << mData.readDouble() << endl;
+ cout << getIndent() << "y = " << mData.readDouble() << endl;
+ cout << getIndent() << "z = " << mData.readDouble() << endl;
+ cout << getIndent() << "w = " << mData.readDouble() << endl;
+ }
+ dedent();
+}
+
+void describeTransformation3d(BitByBitData& mData)
+{
+ cout << getIndent() << "--3d Transformation--" << endl;
+ indent();
+ bool has_transformation = mData.readBit();
+ cout << getIndent() << "has_transformation "
+ << (has_transformation?"yes":"no") << endl;
+ if(has_transformation)
+ {
+ unsigned char behaviour = mData.readChar();
+ cout << getIndent() << "behaviour "
+ << static_cast<unsigned int>(behaviour) << endl;
+ if((behaviour & PRC_TRANSFORMATION_Translate) != 0)
+ {
+ cout << getIndent() << "Translation" << endl;
+ describeVector3d(mData);
+ }
+ if((behaviour & PRC_TRANSFORMATION_Rotate) != 0)
+ {
+ cout << getIndent() << "Rotation" << endl;
+ cout << getIndent() << "X" << endl; describeVector3d(mData);
+ cout << getIndent() << "Y" << endl; describeVector3d(mData);
+ }
+
+ if((behaviour & PRC_TRANSFORMATION_Scale) != 0)
+ {
+ cout << getIndent() << "Uniform Scale by " << mData.readDouble() << endl;
+ }
+ }
+ dedent();
+}
+
+void describeTransformation2d(BitByBitData& mData)
+{
+ cout << getIndent() << "--2d Transformation--" << endl;
+ indent();
+ bool has_transformation = mData.readBit();
+ cout << "has_transformation " << (has_transformation?"yes":"no") << endl;
+ if(has_transformation)
+ {
+ unsigned char behaviour = mData.readChar();
+ cout << getIndent() << "behaviour "
+ << static_cast<unsigned int>(behaviour) << endl;
+ if((behaviour & PRC_TRANSFORMATION_Translate) != 0)
+ {
+ cout << getIndent() << "Translation" << endl;
+ describeVector2d(mData);
+ }
+ if((behaviour & PRC_TRANSFORMATION_Rotate) != 0)
+ {
+ cout << getIndent() << "Rotation" << endl;
+ cout << getIndent() << "X" << endl; describeVector2d(mData);
+ cout << getIndent() << "Y" << endl; describeVector2d(mData);
+ }
+
+ if((behaviour & PRC_TRANSFORMATION_Scale) != 0)
+ {
+ cout << getIndent() << "Uniform Scale by " << mData.readDouble() << endl;
+ }
+ }
+ dedent();
+}
+
+void describeFileStructureInternalData(BitByBitData &mData)
+{
+ cout << getIndent() << "--File Structure Internal Data--" << endl;
+ if(!checkSectionCode(mData,PRC_TYPE_ASM_FileStructure))
+ return;
+ indent();
+ describeContentPRCBase(mData,false);
+ cout << getIndent() << "next_available_index "
+ << mData.readUnsignedInt() << endl;
+ cout << getIndent() << "index_product_occurence "
+ << mData.readUnsignedInt() << endl;
+ dedent();
+}
+
+void describeProductOccurrence(BitByBitData &mData)
+{
+ cout << getIndent() << "--Product Occurrence--" << endl;
+ if(!checkSectionCode(mData,PRC_TYPE_ASM_ProductOccurence))
+ return;
+ indent();
+
+ describeContentPRCBaseWithGraphics(mData,true);
+
+ cout << getIndent() << "index_part "
+ << static_cast<int>(mData.readUnsignedInt()-1) << endl;
+ unsigned int index_prototype = mData.readUnsignedInt()-1;
+ cout << getIndent() << "index_prototype "
+ << static_cast<int>(index_prototype) << endl;
+ if(index_prototype+1 != 0)
+ {
+ bool prototype_in_same_file_structure = mData.readBit();
+ cout << getIndent() << "prototype_in_same_file_structure "
+ << (prototype_in_same_file_structure?"yes":"no") << endl;
+ if(!prototype_in_same_file_structure)
+ describeCompressedUniqueID(mData);
+ }
+
+ unsigned int index_external_data = mData.readUnsignedInt()-1;
+ cout << getIndent() << "index_external_data "
+ << static_cast<int>(index_external_data) << endl;
+ if(index_external_data+1 != 0)
+ {
+ bool external_data_in_same_file_structure = mData.readBit();
+ cout << getIndent() << "external_data_in_same_file_structure "
+ << (external_data_in_same_file_structure?"yes":"no") << endl;
+ if(!external_data_in_same_file_structure)
+ describeCompressedUniqueID(mData);
+ }
+
+ unsigned int number_of_son_product_occurences = mData.readUnsignedInt();
+ cout << getIndent() << "number_of_son_product_occurences "
+ << number_of_son_product_occurences << endl;
+ indent();
+ for(unsigned int i = 0; i < number_of_son_product_occurences; ++i)
+ cout << getIndent() << mData.readUnsignedInt() << endl;
+ dedent();
+
+ cout << getIndent() << "product_behaviour "
+ << static_cast<unsigned int>(mData.readChar()) << endl;
+
+ describeUnit(mData);
+ cout << getIndent() << "Product information flags "
+ << static_cast<unsigned int>(mData.readChar()) << endl;
+ cout << getIndent() << "product_load_status "
+ << mData.readUnsignedInt() << endl;
+
+ bool has_location = mData.readBit();
+ cout << getIndent() << "has_location " << has_location << endl;
+ if(has_location)
+ {
+ describeCartesionTransformation3d(mData);
+ }
+
+ unsigned int number_of_references = mData.readUnsignedInt();
+ cout << getIndent() << "number_of_references "
+ << number_of_references << endl;
+ indent();
+ for(unsigned int i = 0; i < number_of_references; ++i)
+ {
+ //TODO: describeReferenceToPRCBase(mData);
+ }
+ dedent();
+
+ describeMarkups(mData);
+
+ unsigned int number_of_views = mData.readUnsignedInt();
+ cout << getIndent() << "number_of_views " << number_of_views << endl;
+ indent();
+ for(unsigned int i = 0; i < number_of_views; ++i)
+ {
+ describeAnnotationView(mData);
+ }
+ dedent();
+
+ bool has_entity_filter = mData.readBit();
+ cout << getIndent() << "has_entity_filter "
+ << (has_entity_filter?"yes":"no") << endl;
+ if(has_entity_filter)
+ {
+ //TODO: describeEntityFilter(mData);
+ }
+
+ unsigned int number_of_display_filters = mData.readUnsignedInt();
+ cout << getIndent() << "number_of_display_filters "
+ << number_of_display_filters << endl;
+ indent();
+ for(unsigned int i = 0; i < number_of_display_filters; ++i)
+ {
+ //TODO: describeFilter(mData);
+ }
+ dedent();
+
+ unsigned int number_of_scene_display_parameters = mData.readUnsignedInt();
+ cout << getIndent() << "number_of_scene_display_parameters "
+ << number_of_scene_display_parameters << endl;
+ indent();
+ for(unsigned int i = 0; i < number_of_scene_display_parameters; ++i)
+ {
+ describeSceneDisplayParameters(mData);
+ }
+ dedent();
+
+ describeUserData(mData);
+ dedent();
+}
+
+void describeGraphics(BitByBitData &mData)
+{
+ bool sameGraphicsAsCurrent = mData.readBit();
+ cout << getIndent() << "Same graphics as current graphics? "
+ << (sameGraphicsAsCurrent?"yes":"no") << endl;
+ if(!sameGraphicsAsCurrent)
+ {
+ layer_index = mData.readUnsignedInt()-1;
+ cout << getIndent() << "layer_index " << layer_index << endl;
+ index_of_line_style = mData.readUnsignedInt()-1;
+ cout << getIndent() << "index_of_line_style "
+ << index_of_line_style << endl;
+ unsigned char c1 = mData.readChar();
+ unsigned char c2 = mData.readChar();
+ behaviour_bit_field = c1 | (static_cast<unsigned short>(c2) << 8);
+ cout << getIndent() << "behaviour_bit_field "
+ << behaviour_bit_field << endl;
+ }
+}
+
+void describeContentPRCBaseWithGraphics(BitByBitData &mData, bool efr)
+{
+ describeContentPRCBase(mData,efr);
+ describeGraphics(mData);
+}
+
+void describePartDefinition(BitByBitData &mData)
+{
+ cout << getIndent() << "--Part Definition--" << endl;
+ if(!checkSectionCode(mData,PRC_TYPE_ASM_PartDefinition))
+ return;
+ indent();
+
+ describeContentPRCBaseWithGraphics(mData,true);
+ describeExtent3d(mData);
+
+ unsigned int number_of_representation_items = mData.readUnsignedInt();
+ cout << getIndent() << "number_of_representation_items "
+ << number_of_representation_items << endl;
+ indent();
+ for(unsigned int i = 0; i < number_of_representation_items; ++i)
+ {
+ describeRepresentationItem(mData);
+ }
+ dedent();
+
+ describeMarkups(mData);
+
+ unsigned int number_of_views = mData.readUnsignedInt();
+ cout << getIndent() << "number_of_views " << number_of_views << endl;
+ indent();
+ for(unsigned int i = 0; i < number_of_views; ++i)
+ {
+ describeAnnotationView(mData);
+ }
+ dedent();
+
+ describeUserData(mData);
+ dedent();
+}
+
+void describeMarkups(BitByBitData& mData)
+{
+ cout << getIndent() << "--Markups--" << endl;
+ indent();
+
+ unsigned int number_of_linked_items = mData.readUnsignedInt();
+ cout << getIndent() << "number_of_linked_items "
+ << number_of_linked_items << endl;
+ for(unsigned int i = 0; i < number_of_linked_items; ++i)
+ {
+ cout << "describe linked item!" << endl;
+ }
+
+ unsigned int number_of_leaders = mData.readUnsignedInt();
+ cout << getIndent() << "number_of_leaders " << number_of_leaders << endl;
+ for(unsigned int i = 0; i < number_of_leaders; ++i)
+ {
+ cout << "describe leader!" << endl;
+ }
+
+ unsigned int number_of_markups = mData.readUnsignedInt();
+ cout << getIndent() << "number_of_markups " << number_of_markups << endl;
+ for(unsigned int i=0; i < number_of_markups; ++i)
+ {
+ cout << "describe markup!" << endl;
+ }
+
+ unsigned int number_of_annotation_entities = mData.readUnsignedInt();
+ cout << getIndent() << "number_of_annotation_entities "
+ << number_of_annotation_entities << endl;
+ for(unsigned int i=0; i < number_of_annotation_entities; ++i)
+ {
+ cout << "describe annotation entity!" << endl;
+ }
+
+ dedent();
+}
+
+void describeAnnotationView(BitByBitData &mData)
+{
+ cout << getIndent() << "--Annotation View--" << endl;
+ if(!checkSectionCode(mData,PRC_TYPE_MKP_View))
+ return;
+ indent();
+ describeContentPRCBaseWithGraphics(mData,true);
+ unsigned int number_of_annotations = mData.readUnsignedInt();
+ for(unsigned int i = 0; i < number_of_annotations; ++i)
+ {
+ //TODO: describeReferenceUniqueIdentifier(mData);
+ }
+ //TODO: describePlane(mData);
+ bool scene_display_parameters = mData.readBit();
+ if(scene_display_parameters)
+ {
+ describeSceneDisplayParameters(mData);
+ }
+ describeUserData(mData);
+ dedent();
+}
+
+void describeExtent3d(BitByBitData &mData)
+{ // I suspect the order of min/max should be flipped
+ cout << getIndent() << "Minimum" << endl;
+ indent(); describeVector3d(mData); dedent();
+ cout << getIndent() << "Maximum" << endl;
+ indent(); describeVector3d(mData); dedent();
+}
+
+void describeExtent1d(BitByBitData &mData)
+{
+ cout << getIndent() << "Minimum " << mData.readDouble() << endl;
+ cout << getIndent() << "Maximum " << mData.readDouble() << endl;
+}
+
+void describeExtent2d(BitByBitData &mData)
+{
+ cout << getIndent() << "Minimum" << endl;
+ indent(); describeVector2d(mData); dedent();
+ cout << getIndent() << "Maximum" << endl;
+ indent(); describeVector2d(mData); dedent();
+}
+
+void describeVector3d(BitByBitData &mData)
+{
+ double x = mData.readDouble();
+ double y = mData.readDouble();
+ double z = mData.readDouble();
+ cout << getIndent() << '(' << x << ',' << y << ',' << z << ')' << endl;
+}
+
+void describeVector2d(BitByBitData &mData)
+{
+ double x = mData.readDouble();
+ double y = mData.readDouble();
+ cout << getIndent() << '(' << x << ',' << y << ')' << endl;
+}
+
+void describePicture(BitByBitData &mData)
+{
+ cout << getIndent() << "--Picture--" << endl;
+ unsigned int sectionCode = mData.readUnsignedInt();
+ if(sectionCode != PRC_TYPE_GRAPH_Picture)
+ {
+ cout << getIndent() << "Invalid section code." << endl;
+ }
+
+ describeContentPRCBase(mData,false);
+
+ int format = mData.readInt();
+ switch(format)
+ {
+ case KEPRCPicture_PNG:
+ cout << getIndent() << "PNG format" << endl;
+ break;
+ case KEPRCPicture_JPG:
+ cout << getIndent() << "JPG format" << endl;
+ break;
+ case KEPRCPicture_BITMAP_RGB_BYTE:
+ cout << getIndent() << "gzipped pixel data (see PRC base compression). Each element is a RGB triple. (3 components)" << endl;
+ break;
+ case KEPRCPicture_BITMAP_RGBA_BYTE:
+ cout << getIndent() << "gzipped pixel data (see PRC base compression). Each element is a complete RGBA element. (4 components)" << endl;
+ break;
+ case KEPRCPicture_BITMAP_GREY_BYTE:
+ cout << getIndent() << "gzipped pixel data (see PRC base compression). Each element is a single luminance value. (1 components)" << endl;
+ break;
+ case KEPRCPicture_BITMAP_GREYA_BYTE:
+ cout << getIndent() << "gzipped pixel data (see PRC base compression). Each element is a luminance/alpha pair. (2 components)" << endl;
+ break;
+ default:
+ cout << getIndent() << "Invalid picture format." << endl;
+ break;
+ }
+ cout << getIndent() << "uncompressed_file_index "
+ << mData.readUnsignedInt()-1 << endl;
+ cout << getIndent() << "pixel width " << mData.readUnsignedInt() << endl;
+ cout << getIndent() << "pixel height " << mData.readUnsignedInt() << endl;
+}
+
+void describeTextureDefinition(BitByBitData &mData)
+{
+ cout << getIndent() << "--Texture Definition--" << endl;
+ if(!checkSectionCode(mData,PRC_TYPE_GRAPH_TextureDefinition))
+ return;
+
+ cout << getIndent() << "TODO: Can't describe textures yet." << endl;
+}
+
+void describeMaterial(BitByBitData &mData)
+{
+ cout << getIndent() << "--Material--" << endl;
+ unsigned int code = mData.readUnsignedInt();
+ if(code == PRC_TYPE_GRAPH_Material)
+ {
+ describeContentPRCBase(mData,true);
+ cout << getIndent() << "index of ambient color "
+ << mData.readUnsignedInt() - 1 << endl;
+ cout << getIndent() << "index of diffuse color "
+ << mData.readUnsignedInt() - 1 << endl;
+ cout << getIndent() << "index of emissive color "
+ << mData.readUnsignedInt() - 1 << endl;
+ cout << getIndent() << "index of specular color "
+ << mData.readUnsignedInt() - 1 << endl;
+ cout << getIndent() << "shininess " << mData.readDouble() << endl;
+ cout << getIndent() << "ambient_alpha " << mData.readDouble() << endl;
+ cout << getIndent() << "diffuse_alpha " << mData.readDouble() << endl;
+ cout << getIndent() << "emissive_alpha " << mData.readDouble() << endl;
+ cout << getIndent() << "specular_alpha " << mData.readDouble() << endl;
+ }
+ else if(code == PRC_TYPE_GRAPH_TextureApplication)
+ {
+ describeContentPRCBase(mData,true);
+ cout << getIndent() << "material_generic_index "
+ << mData.readUnsignedInt() - 1 << endl;
+ cout << getIndent() << "texture_definition_index "
+ << mData.readUnsignedInt() - 1 << endl;
+ cout << getIndent() << "next_texture_index "
+ << mData.readUnsignedInt() - 1 << endl;
+ cout << getIndent() << "UV_coordinates_index "
+ << mData.readUnsignedInt() - 1 << endl;
+ }
+ else
+ {
+ cout << getIndent() << "Invalid section code in material definition."
+ << endl;
+ }
+}
+
+void describeLinePattern(BitByBitData &mData)
+{
+ cout << getIndent() << "--Line Pattern--" << endl;
+ if(!checkSectionCode(mData,PRC_TYPE_GRAPH_LinePattern))
+ return;
+ indent();
+
+ describeContentPRCBase(mData,true);
+ unsigned int size_lengths = mData.readUnsignedInt();
+ cout << getIndent() << "size_lengths " << size_lengths << endl;
+ indent();
+ for(unsigned int i=0;i<size_lengths;i++)
+ {
+ cout << getIndent() << "length " << mData.readDouble() << endl;
+ }
+ dedent();
+ cout << getIndent() << "phase " << mData.readDouble() << endl;
+ cout << getIndent() << "is real length "
+ << (mData.readBit()?"yes":"no") << endl;
+
+ dedent();
+}
+
+void describeCategory1LineStyle(BitByBitData &mData)
+{
+ cout << getIndent() << "--Category 1 Line Style--" << endl;
+ if(!checkSectionCode(mData,PRC_TYPE_GRAPH_Style))
+ return;
+ indent();
+
+ // This was missing from the docs!!!!! argh!
+ describeContentPRCBase(mData,true);
+
+
+ cout << getIndent() << "line_width " << mData.readDouble() << " mm" << endl;
+
+ cout << getIndent() << "is_vpicture " << (mData.readBit()?"yes":"no") << endl;
+
+ cout << getIndent() << "line_pattern_index/vpicture_index "
+ << static_cast<int>(mData.readUnsignedInt()-1) << endl;
+ cout << getIndent() << "is_material " << (mData.readBit()?"yes":"no") << endl;
+ cout << getIndent() << "color_index / material_index "
+ << static_cast<int>(mData.readUnsignedInt()-1) << endl;
+
+ bool is_transparency_defined = mData.readBit();
+ cout << getIndent() << "is_transparency_defined "
+ << (is_transparency_defined?"yes":"no") << endl;
+ if(is_transparency_defined)
+ {
+ indent();
+ cout << getIndent() << "transparency "
+ << static_cast<unsigned int>(mData.readChar()) << endl;
+ dedent();
+ }
+
+ bool is_additional_1_defined = mData.readBit();
+ cout << getIndent() << "is_additional_1_defined "
+ << (is_additional_1_defined?"yes":"no") << endl;
+ if(is_additional_1_defined)
+ {
+ indent();
+ cout << getIndent() << "additional_1 "
+ << static_cast<unsigned int>(mData.readChar()) << endl;
+ dedent();
+ }
+
+ bool is_additional_2_defined = mData.readBit();
+ cout << getIndent() << "is_additional_2_defined "
+ << (is_additional_2_defined?"yes":"no") << endl;
+ if(is_additional_2_defined)
+ {
+ indent();
+ cout << getIndent() << "additional_2 "
+ << static_cast<unsigned int>(mData.readChar()) << endl;
+ dedent();
+ }
+
+ bool is_additional_3_defined = mData.readBit();
+ cout << getIndent() << "is_additional_3_defined "
+ << (is_additional_3_defined?"yes":"no") << endl;
+ if(is_additional_3_defined)
+ {
+ indent();
+ cout << getIndent() << "additional_3 "
+ << static_cast<unsigned int>(mData.readChar()) << endl;
+ dedent();
+ }
+ dedent();
+}
+
+void describeFillPattern(BitByBitData &mData)
+{
+ cout << getIndent() << "--Fill Pattern--" << endl;
+ unsigned int type = mData.readUnsignedInt();
+ cout << getIndent() << "type " << type << endl;
+ switch(type)
+ {
+ //TODO: actually describe fill patterns
+ default:
+ cout << getIndent() << "Invalid fill pattern type " << type << endl;
+ }
+}
+
+void describeRepresentationItemContent(BitByBitData &mData)
+{
+ describeContentPRCBaseWithGraphics(mData,true);
+ unsigned int index_local_coordinate_system = mData.readUnsignedInt()-1;
+ unsigned int index_tessellation = mData.readUnsignedInt()-1;
+ //cast to int will not be right for big indices
+ cout << getIndent() << "index_local_coordinate_system "
+ << static_cast<int>(index_local_coordinate_system) << endl;
+ cout << getIndent() << "index_tessellation "
+ << static_cast<int>(index_tessellation) << endl;
+}
+
+void describeRepresentationItem(BitByBitData &mData)
+{
+ cout << getIndent() << "--Representation Item--" << endl;
+ unsigned int type = mData.readUnsignedInt();
+ switch(type)
+ {
+ case PRC_TYPE_RI_Curve:
+ {
+ cout << getIndent() << "--PRC_TYPE_RI_Curve--" << endl;
+ describeRepresentationItemContent(mData);
+ bool has_wire_body = mData.readBit();
+ if(has_wire_body)
+ {
+ cout << getIndent() << "context_id " << mData.readUnsignedInt() << endl;
+ cout << getIndent() << "body_id " << mData.readUnsignedInt() << endl;
+ }
+ describeUserData(mData);
+ break;
+ }
+ case PRC_TYPE_RI_PolyBrepModel:
+ {
+ cout << getIndent() << "--PRC_TYPE_RI_PolyBrepModel--" << endl;
+ describeRepresentationItemContent(mData);
+ cout << getIndent() << "is_closed "
+ << (mData.readBit()?"yes":"no") << endl;
+ describeUserData(mData);
+ break;
+ }
+ case PRC_TYPE_RI_BrepModel:
+ {
+ cout << getIndent() << "--PRC_TYPE_RI_BrepModel--" << endl;
+ describeRepresentationItemContent(mData);
+ bool has_brep_data = mData.readBit();
+ cout << getIndent() << "has_brep_data "
+ << (has_brep_data?"yes":"no") << endl;
+ if(has_brep_data)
+ {
+ cout << getIndent() << "context_id " << mData.readUnsignedInt() << endl;
+ cout << getIndent() << "object_id " << mData.readUnsignedInt() << endl;
+ }
+ cout << getIndent() << "is_closed "
+ << (mData.readBit()?"yes":"no") << endl;
+ describeUserData(mData);
+ break;
+ }
+ case PRC_TYPE_RI_Direction:
+
+ case PRC_TYPE_RI_Plane:
+ case PRC_TYPE_RI_CoordinateSystem:
+ case PRC_TYPE_RI_PointSet:
+ case PRC_TYPE_RI_Set:
+ case PRC_TYPE_RI_PolyWire:
+ cout << getIndent() << "TODO: Unhandled representation item "
+ << type << endl;
+ break;
+ default:
+ cout << getIndent() << "Invalid representation item type "
+ << type << endl;
+ break;
+ }
+}
+
+void describeRGBColour(BitByBitData &mData)
+{
+ cout << getIndent() << "R: " << mData.readDouble();
+ cout << " G: " << mData.readDouble();
+ cout << " B: " << mData.readDouble() << endl;
+}
+
+void describeSchema(BitByBitData &mData)
+{
+ cout << getIndent() << "--Schema--" << endl;
+ indent();
+ unsigned int numSchemas = mData.readUnsignedInt();
+ cout << getIndent() << "Number of Schemas " << numSchemas << endl;
+ if(numSchemas != 0)
+ {
+ cout << "Error: Don't know how to handle multiple schemas." << endl;
+ }
+ dedent();
+}
+
+string currentName;
+int layer_index;
+int index_of_line_style;
+unsigned short behaviour_bit_field;
+
+void resetCurrentGraphics()
+{
+ layer_index = -1;
+ index_of_line_style = -1;
+ behaviour_bit_field = 1;
+}
+
+void unFlushSerialization()
+{
+ currentName = "";
+
+ resetCurrentGraphics();
+}
+
+void describeName(BitByBitData &mData)
+{
+ bool sameNameAsCurrent = mData.readBit();
+ cout << getIndent() << "Same name as current name? "
+ << (sameNameAsCurrent?"yes":"no") << endl;
+ if(!sameNameAsCurrent)
+ currentName = mData.readString();
+ cout << getIndent() << "Name \"" << currentName << '\"' << endl;
+}
+
+void describeUnit(BitByBitData &mData)
+{
+ cout << getIndent() << "Unit is from CAD file? "
+ << (mData.readBit()?"yes":"no") << endl;
+ cout << getIndent() << "Unit is " << mData.readDouble() << " mm" << endl;
+}
+
+void describeAttributes(BitByBitData &mData)
+{
+ cout << getIndent() << "--Attributes--" << endl;
+ indent();
+
+ unsigned int numAttribs = mData.readUnsignedInt();
+ cout << getIndent() << "Number of Attributes " << numAttribs << endl;
+ indent();
+ for(unsigned int i = 0; i < numAttribs; ++i)
+ {
+ cout << getIndent() << "PRC_TYPE_MISC_Attribute "
+ << mData.readUnsignedInt() << endl;
+ bool titleIsInt = mData.readBit();
+ cout << getIndent() << "Title is integer? "
+ << (titleIsInt?"yes":"no") << endl;
+ indent();
+ if(titleIsInt)
+ {
+ cout << getIndent() << "Title " << mData.readUnsignedInt() << endl;
+ }
+ else
+ {
+ cout << getIndent() << "Title \"" << mData.readString() << '\"' << endl;
+ }
+ unsigned int sizeOfAttributeKeys = mData.readUnsignedInt();
+ cout << getIndent() << "Size of Attribute Keys "
+ << sizeOfAttributeKeys << endl;
+ for(unsigned int a = 0; a < sizeOfAttributeKeys; ++a)
+ {
+ bool titleIsInt = mData.readBit();
+ cout << getIndent() << "Title is integer? "
+ << (titleIsInt?"yes":"no") << endl;
+ indent();
+ if(titleIsInt)
+ {
+ cout << getIndent() << "Title " << mData.readUnsignedInt() << endl;
+ }
+ else
+ {
+ cout << getIndent() << "Title \"" << mData.readString() << '\"' << endl;
+ }
+ dedent();
+ unsigned int attributeType = mData.readUnsignedInt();
+ cout << getIndent() << "Attribute Type " << attributeType << endl;
+ switch(attributeType)
+ {
+ case KEPRCModellerAttributeTypeInt:
+ cout << getIndent() << "Attribute Value (int) "
+ << mData.readInt() << endl;
+ break;
+ case KEPRCModellerAttributeTypeReal:
+ cout << getIndent() << "Attribute Value (double) "
+ << mData.readDouble() << endl;
+ break;
+ case KEPRCModellerAttributeTypeTime:
+ cout << getIndent() << "Attribute Value (time_t) "
+ << mData.readUnsignedInt() << endl;
+ break;
+ case KEPRCModellerAttributeTypeString:
+ cout << getIndent() << "Attribute Value (string) \""
+ << mData.readString() << '\"' << endl;
+ break;
+ default:
+ break;
+ }
+ }
+ dedent();
+
+ cout << endl;
+ }
+ dedent();
+
+
+ dedent();
+}
+
+void describeContentPRCBase(BitByBitData &mData, bool typeEligibleForReference)
+{
+ cout << getIndent() << "--ContentPRCBase--" << endl;
+ indent();
+ describeAttributes(mData);
+ describeName(mData);
+ if(typeEligibleForReference)
+ {
+ cout << getIndent() << "CAD_identifier "
+ << mData.readUnsignedInt() << endl;
+ cout << getIndent() << "CAD_persistent_identifier "
+ << mData.readUnsignedInt() << endl;
+ cout << getIndent() << "PRC_unique_identifier "
+ << mData.readUnsignedInt() << endl;
+ }
+ dedent();
+}
+
+void describeCompressedUniqueID(BitByBitData &mData)
+{
+ cout << getIndent() << "UUID: " << hex << setfill('0');
+ for(int i = 0; i < 4; ++i)
+ cout << setw(8) << mData.readUnsignedInt() << ' ';
+ cout << dec << setfill(' ') << endl;
+}
+
+void describeUserData(BitByBitData &mData)
+{
+ unsigned int bits = mData.readUnsignedInt();
+ cout << getIndent() << bits << " bits of user data" << endl;
+ indent();
+ for(unsigned int i = 0; i < bits; ++i)
+ {
+ if(i%64 == 0)
+ cout << getIndent();
+ cout << mData.readBit();
+ if(i%64 == 63)
+ cout << endl;
+ }
+ if(bits%64 != 0)
+ cout << endl;
+ dedent();
+}
+
+bool checkSectionCode(BitByBitData &mData, unsigned int code)
+{
+ unsigned int num = mData.readUnsignedInt();
+ if(code != num)
+ {
+ cout << getIndent() << "Invalid section code " << num <<
+ ". Expected " << code << " at "; mData.tellPosition();
+ return false;
+ }
+ else
+ {
+ cout << getIndent() << "Section code " << code << endl;
+ return true;
+ }
+}
+
+unsigned int currentIndent = 0;
+
+string getIndent()
+{
+ ostringstream out;
+ for(unsigned int i = 0; i < currentIndent; ++i)
+ out << " ";
+ return out.str();
+}
+
+void indent()
+{
+ ++currentIndent;
+}
+
+void dedent()
+{
+ --currentIndent;
+}
diff --git a/Build/source/utils/asymptote/prc/PRCTools/describePRC.h b/Build/source/utils/asymptote/prc/PRCTools/describePRC.h
new file mode 100644
index 00000000000..acafb875dad
--- /dev/null
+++ b/Build/source/utils/asymptote/prc/PRCTools/describePRC.h
@@ -0,0 +1,117 @@
+/************
+*
+* This file is part of a tool for reading 3D content in the PRC format.
+* Copyright (C) 2008 Orest Shardt <shardtor (at) gmail dot com>
+*
+* This program 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 3 of the License, or
+* (at your option) any later version.
+*
+* This program 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 program. If not, see <http://www.gnu.org/licenses/>.
+*
+*************/
+
+#ifndef __DESCRIBE_PRC_H
+#define __DESCRIBE_PRC_H
+
+#include "iPRCFile.h"
+#include "bitData.h"
+
+void describeGlobals(BitByBitData&);
+void describeTree(BitByBitData&);
+void describeTessellation(BitByBitData&);
+void describeGeometry(BitByBitData&);
+void describeExtraGeometry(BitByBitData&);
+void describeModelFileData(BitByBitData&,unsigned int);
+
+void describePicture(BitByBitData&);
+void describeTextureDefinition(BitByBitData&);
+void describeMaterial(BitByBitData&);
+void describeLinePattern(BitByBitData&);
+void describeCategory1LineStyle(BitByBitData&);
+void describeFillPattern(BitByBitData&);
+void describeRepresentationItem(BitByBitData&);
+
+//void describe(BitByBitData&);
+void describeLight(BitByBitData&);
+void describeCamera(BitByBitData&);
+bool describeContentCurve(BitByBitData&);
+void describeCurvCircle(BitByBitData&);
+void describeCurvLine(BitByBitData&);
+void describeCurvNURBS(BitByBitData&);
+void describeCurvPolyLine(BitByBitData&);
+void describeContentWireEdge(BitByBitData&);
+bool isCompressedSerialType(unsigned int);
+void describeUVParametrization(BitByBitData&);
+void describeSurfNURBS(BitByBitData&);
+void describeSurfCylinder(BitByBitData&);
+void describeSurfPlane(BitByBitData&);
+void describeTopoFace(BitByBitData&);
+void describeTopoLoop(BitByBitData&);
+void describeTopoCoEdge(BitByBitData&);
+void describeTopoEdge(BitByBitData&);
+void describeTopoConnex(BitByBitData&);
+void describeTopoShell(BitByBitData&);
+void describeObject(BitByBitData&);
+void describeBaseTopology(BitByBitData&);
+void describeBaseGeometry(BitByBitData&);
+unsigned int describeContentBody(BitByBitData&);
+void describeContentSurface(BitByBitData&);
+void describeBody(BitByBitData&);
+void describeTopoContext(BitByBitData&);
+void describeLineAttr(BitByBitData&);
+void describeArrayRGBA(BitByBitData&,int,int);
+void describeContentBaseTessData(BitByBitData&);
+void describeTessFace(BitByBitData&);
+void describe3DTess(BitByBitData&);
+void describe3DWireTess(BitByBitData&);
+void describe3DMarkupTess(BitByBitData&);
+void describeHighlyCompressed3DTess(BitByBitData&);
+void describeSceneDisplayParameters(BitByBitData&);
+void describeCartesionTransformation3d(BitByBitData&);
+void describeTransformation3d(BitByBitData&);
+void describeTransformation2d(BitByBitData&);
+void describeFileStructureInternalData(BitByBitData&);
+void describeProductOccurrence(BitByBitData&);
+void describeRepresentationItemContent(BitByBitData&);
+void describeMarkups(BitByBitData&);
+void describeAnnotationView(BitByBitData&);
+void describeExtent3d(BitByBitData&);
+void describeExtent2d(BitByBitData&);
+void describeExtent1d(BitByBitData&);
+void describeVector3d(BitByBitData&);
+void describeVector2d(BitByBitData&);
+void describeContentPRCBaseWithGraphics(BitByBitData&,bool);
+void describeGraphics(BitByBitData&);
+void describePartDefinition(BitByBitData&);
+void describeRGBColour(BitByBitData&);
+void describeSchema(BitByBitData&);
+void describeName(BitByBitData&);
+void describeAttributes(BitByBitData&);
+void describeContentPRCBase(BitByBitData&,bool);
+void describeUnit(BitByBitData&);
+void describeCompressedUniqueID(BitByBitData&);
+void describeUserData(BitByBitData&);
+
+extern std::string currentName;
+extern int layer_index;
+extern int index_of_line_style;
+extern unsigned short behaviour_bit_field;
+
+void unFlushSerialization();
+void resetCurrentGraphics();
+
+bool checkSectionCode(BitByBitData&,unsigned int);
+
+std::string getIndent();
+void indent();
+void dedent();
+
+#endif // __DESCRIBE_PRC_H
diff --git a/Build/source/utils/asymptote/prc/PRCTools/extractSections.cc b/Build/source/utils/asymptote/prc/PRCTools/extractSections.cc
new file mode 100644
index 00000000000..865f159698a
--- /dev/null
+++ b/Build/source/utils/asymptote/prc/PRCTools/extractSections.cc
@@ -0,0 +1,46 @@
+/************
+*
+* This file is part of a tool for reading 3D content in the PRC format.
+* Copyright (C) 2008 Orest Shardt <shardtor (at) gmail dot com>
+*
+* This program 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 3 of the License, or
+* (at your option) any later version.
+*
+* This program 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 program. If not, see <http://www.gnu.org/licenses/>.
+*
+*************/
+
+#include <iostream>
+#include <fstream>
+#include "iPRCFile.h"
+
+using namespace std;
+
+int main(int argc, char* argv[])
+{
+ if(argc < 2)
+ {
+ cerr << "Error: Input file not specified." << endl;
+ return 1;
+ }
+ ifstream inFile(argv[1]);
+ if(!inFile)
+ {
+ cerr << "Error: Cannot open input file." << endl;
+ return 1;
+ }
+
+ iPRCFile myFile(inFile);
+ string name(argv[1]);
+ myFile.dumpSections(name.substr(0,name.find(".")).c_str());
+
+ return 0;
+}
diff --git a/Build/source/utils/asymptote/prc/PRCTools/iPRCFile.cc b/Build/source/utils/asymptote/prc/PRCTools/iPRCFile.cc
new file mode 100644
index 00000000000..02967a5478b
--- /dev/null
+++ b/Build/source/utils/asymptote/prc/PRCTools/iPRCFile.cc
@@ -0,0 +1,220 @@
+/************
+*
+* This file is part of a tool for reading 3D content in the PRC format.
+* Copyright (C) 2008 Orest Shardt <shardtor (at) gmail dot com>
+*
+* This program 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 3 of the License, or
+* (at your option) any later version.
+*
+* This program 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 program. If not, see <http://www.gnu.org/licenses/>.
+*
+*************/
+
+#include "bitData.h"
+#include "iPRCFile.h"
+#include "describePRC.h"
+
+using std::vector; using std::istream; using std::ios;
+using std::cout; using std::endl; using std::cerr;
+using std::string;
+
+using std::ofstream;
+using std::ostringstream;
+
+void iPRCFile::dumpSections(string prefix)
+{
+ ofstream out;
+
+ for(unsigned int i = 0; i < fileStructures.size(); ++i)
+ {
+ ostringstream name;
+ name << prefix << "Structure" << i;
+
+ out.open((name.str()+"-Globals.bin").c_str());
+ out.write(fileStructures[i].sections[GLOBALS_SECTION],fileStructures[i].sectionLengths[GLOBALS_SECTION]);
+ out.close();
+
+ out.open((name.str()+"-Tree.bin").c_str());
+ out.write(fileStructures[i].sections[TREE_SECTION],fileStructures[i].sectionLengths[TREE_SECTION]);
+ out.close();
+
+ out.open((name.str()+"-Tessellation.bin").c_str());
+ out.write(fileStructures[i].sections[TESSELLATION_SECTION],fileStructures[i].sectionLengths[TESSELLATION_SECTION]);
+ out.close();
+
+ out.open((name.str()+"-Geometry.bin").c_str());
+ out.write(fileStructures[i].sections[GEOMETRY_SECTION],fileStructures[i].sectionLengths[GEOMETRY_SECTION]);
+ out.close();
+
+ out.open((name.str()+"-ExtraGeometry.bin").c_str());
+ out.write(fileStructures[i].sections[EXTRA_GEOMETRY_SECTION],fileStructures[i].sectionLengths[EXTRA_GEOMETRY_SECTION]);
+ out.close();
+ }
+ out.open((prefix+"-ModelFile.bin").c_str());
+ out.write(modelFileData,modelFileLength);
+ out.close();
+}
+
+void iPRCFile::describe()
+{
+ /*
+ for(int i = 0; i < modelFileLength; ++i)
+ {
+ cout << ' ' << std::hex << std::setw(2) << std::setfill('0') << static_cast<unsigned int>(static_cast<unsigned char>(mfd.readChar()));
+ if(i%16 == 15)
+ cout << endl;
+ }
+ cout << endl;
+ */
+
+ unFlushSerialization();
+ for(unsigned int i = 0; i < fileStructures.size(); ++i)
+ {
+ cout << "File Structure " << i << ":" << endl;
+
+ //describe header
+ char *header = buffer + fileStructureInfos[i].offsets[0];
+ cout << "--Header Section--" << endl;
+ cout << " Signature " << header[0] << header[1] << header[2] << endl;
+ cout << " Minimal version for read " << *(unsigned int*)(header+3) << endl;
+ cout << " Authoring version " << *(unsigned int*)(header+7) << endl;
+ cout << std::hex;
+ cout << " File structure UUID " << *(unsigned int*)(header+11) << ' ' << *(unsigned int*)(header+15) << ' '
+ << *(unsigned int*)(header+19) << ' ' << *(unsigned int*)(header+23) << endl;
+ cout << " Application UUID " << *(unsigned int*)(header+27) << ' ' << *(unsigned int*)(header+31) << ' '
+ << *(unsigned int*)(header+35) << ' ' << *(unsigned int*)(header+39) << endl;
+ cout << std::dec;
+ // uncompressed files
+ unsigned int numberOfUncompressedFiles = *(unsigned int*)(header+43);
+ cout << "Number of uncompressed files " << numberOfUncompressedFiles << endl;
+ char *position = header+47;
+ for(unsigned int j = 0; j < numberOfUncompressedFiles; ++j)
+ {
+ cout << "Uncompressed file " << j << ":" << endl;
+ unsigned int size = *(unsigned int*)position;
+ cout << " size " << size << " bytes" << endl;
+ position += size+sizeof(unsigned int);
+ }
+
+ BitByBitData fileStruct(fileStructures[i].sections[GLOBALS_SECTION],fileStructures[i].sectionLengths[GLOBALS_SECTION]);
+ describeSchema(fileStruct);
+ describeGlobals(fileStruct);
+ unFlushSerialization();
+
+ fileStruct = BitByBitData(fileStructures[i].sections[TREE_SECTION],fileStructures[i].sectionLengths[TREE_SECTION]);
+ describeTree(fileStruct);
+ unFlushSerialization();
+
+ fileStruct = BitByBitData(fileStructures[i].sections[TESSELLATION_SECTION],fileStructures[i].sectionLengths[TESSELLATION_SECTION]);
+ describeTessellation(fileStruct);
+ unFlushSerialization();
+
+ fileStruct = BitByBitData(fileStructures[i].sections[GEOMETRY_SECTION],fileStructures[i].sectionLengths[GEOMETRY_SECTION]);
+ describeGeometry(fileStruct);
+ unFlushSerialization();
+
+ fileStruct = BitByBitData(fileStructures[i].sections[EXTRA_GEOMETRY_SECTION],fileStructures[i].sectionLengths[EXTRA_GEOMETRY_SECTION]);
+ describeExtraGeometry(fileStruct);
+ unFlushSerialization();
+ }
+
+ BitByBitData mfd(modelFileData,modelFileLength);
+
+ describeSchema(mfd);
+ describeModelFileData(mfd,fileStructures.size());
+ unFlushSerialization();
+}
+
+iPRCFile::iPRCFile(istream& in)
+{
+ char PRC[3];
+ in.read(PRC,3);
+ if(PRC[0] != 'P' || PRC[1] != 'R' || PRC[2] != 'C')
+ {
+ cerr << "Error: Invalid file format: PRC not found." << endl;
+ }
+ unsigned int versionForRead,authoringVersion;
+ in.read((char*)&versionForRead,sizeof(versionForRead));
+ in.read((char*)&authoringVersion,sizeof(authoringVersion));
+ cout << "Version for reading " << versionForRead << endl;
+ cout << "Authoring version " << authoringVersion << endl;
+ unsigned int fileStructureUUID[4];
+ in.read((char*)fileStructureUUID,sizeof(fileStructureUUID));
+ //(void*) is for formatting
+ cout << "File structure UUID " << (void*)(fileStructureUUID[0]) << ' ' << (void*)(fileStructureUUID[1]) << ' '
+ << (void*)(fileStructureUUID[2]) << ' ' << (void*)(fileStructureUUID[3]) << endl;
+ unsigned int applicationUUID[4];
+ in.read((char*)applicationUUID,sizeof(applicationUUID));
+ cout << "Application UUID " << (void*)(applicationUUID[0]) << ' ' << (void*)(applicationUUID[1]) << ' '
+ << (void*)(applicationUUID[2]) << ' ' << (void*)(applicationUUID[3]) << endl;
+ unsigned int numberOfFileStructures;
+ in.read((char*)&numberOfFileStructures,sizeof(numberOfFileStructures));
+ cout << "number of file structures " << numberOfFileStructures << endl;
+
+ // load fileStructureInformation
+ for(unsigned int fsi = 0; fsi < numberOfFileStructures; ++fsi)
+ {
+ FileStructureInformation info;
+ in.read((char*)&info.UUID,sizeof(info.UUID));
+ cout << "\tFile structure UUID " << (void*)(info.UUID[0]) << ' ' << (void*)(info.UUID[1]) << ' '
+ << (void*)(info.UUID[2]) << ' ' << (void*)(info.UUID[3]) << endl;
+
+ in.read((char*)&info.reserved,sizeof(info.reserved));
+ cout << "\tReserved " << info.reserved << endl;
+
+ unsigned int numberOfOffsets;
+ in.read((char*)&numberOfOffsets,sizeof(numberOfOffsets));
+ cout << "\tNumber of Offsets " << numberOfOffsets << endl;
+
+ for(unsigned int oi = 0; oi < numberOfOffsets; ++oi)
+ {
+ unsigned int offset;
+ in.read((char*)&offset,sizeof(offset));
+ info.offsets.push_back(offset);
+ cout << "\t\tOffset " << offset << endl;
+ }
+ fileStructureInfos.push_back(info);
+ }
+ in.read((char*)&modelFileOffset,sizeof(modelFileOffset));
+ cout << "Model file offset " << modelFileOffset << endl;
+ in.read((char*)&fileSize,sizeof(fileSize)); // this is not documented
+ cout << "File size " << fileSize << endl;
+
+ in.read((char*)&numberOfUncompressedFiles,sizeof(numberOfUncompressedFiles));
+ cout << "Number of uncompressed files " << numberOfUncompressedFiles << endl;
+ for(unsigned int ufi = 0; ufi < numberOfUncompressedFiles; ++ufi)
+ {
+ unsigned int size;
+ in.read((char*)&size,sizeof(size));
+ in.seekg(size,ios::cur);
+ }
+
+ //read the whole file into memory
+ in.seekg(0,ios::beg);
+ buffer = new char[fileSize];
+ if(!buffer) cerr << "Couldn't get memory." << endl;
+ in.read(buffer,fileSize);
+ //decompress fileStructures
+ for(unsigned int fs = 0; fs < fileStructureInfos.size(); ++fs)
+ {
+ fileStructures.push_back(FileStructure());
+ for(unsigned int i = 1; i < fileStructureInfos[fs].offsets.size(); ++i) // start at 1 since header is decompressed
+ {
+ fileStructures[fs].sections[i-1] = NULL;
+ unsigned int offset = fileStructureInfos[fs].offsets[i];
+ fileStructures[fs].sectionLengths[i-1] = decompress(buffer+offset,fileSize-offset,fileStructures[fs].sections[i-1]);
+ }
+ }
+
+ //decompress modelFileData
+ modelFileData = NULL;
+ modelFileLength = decompress(buffer+modelFileOffset,fileSize-modelFileOffset,modelFileData);
+}
diff --git a/Build/source/utils/asymptote/prc/PRCTools/iPRCFile.h b/Build/source/utils/asymptote/prc/PRCTools/iPRCFile.h
new file mode 100644
index 00000000000..2622cb966d1
--- /dev/null
+++ b/Build/source/utils/asymptote/prc/PRCTools/iPRCFile.h
@@ -0,0 +1,88 @@
+/************
+*
+* This file is part of a tool for reading 3D content in the PRC format.
+* Copyright (C) 2008 Orest Shardt <shardtor (at) gmail dot com>
+*
+* This program 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 3 of the License, or
+* (at your option) any later version.
+*
+* This program 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 program. If not, see <http://www.gnu.org/licenses/>.
+*
+*************/
+
+#ifndef __READPRC_H
+#define __READPRC_H
+
+#include <iostream>
+#include <fstream>
+#include <string>
+#include <vector>
+#include <sstream>
+#include <iomanip>
+#include "../PRC.h"
+#include "inflation.h"
+
+struct FileStructureInformation
+{
+ unsigned int UUID[4];
+ unsigned int reserved;
+ std::vector<unsigned int> offsets;
+};
+
+
+const int GLOBALS_SECTION = 0;
+const int TREE_SECTION = 1;
+const int TESSELLATION_SECTION = 2;
+const int GEOMETRY_SECTION = 3;
+const int EXTRA_GEOMETRY_SECTION = 4;
+
+struct FileStructure
+{
+ unsigned int readVersion;
+ unsigned int authoringVersion;
+ unsigned int fileUUID[4];
+ unsigned int appUUID[4];
+ char* sections[5];
+ unsigned int sectionLengths[5];
+};
+
+class iPRCFile
+{
+ public:
+ iPRCFile(std::istream&);
+
+ ~iPRCFile()
+ {
+ for(unsigned int i = 0; i < fileStructures.size(); ++i)
+ for(unsigned int j = 0; j < 5; ++j)
+ if(fileStructures[i].sections[j] != NULL)
+ free(fileStructures[i].sections[j]);
+ if(modelFileData!=NULL)
+ free(modelFileData);
+ if(buffer != 0)
+ delete[] buffer;
+ }
+
+ void describe();
+ void dumpSections(std::string);
+
+ private:
+ // header data
+ std::vector<FileStructureInformation> fileStructureInfos;
+ std::vector<FileStructure> fileStructures;
+ unsigned int modelFileOffset;
+ char* modelFileData;
+ unsigned int modelFileLength;
+ char *buffer;
+ unsigned int fileSize;
+ unsigned int numberOfUncompressedFiles;
+};
+#endif // __READPRC_H
diff --git a/Build/source/utils/asymptote/prc/PRCTools/inflation.cc b/Build/source/utils/asymptote/prc/PRCTools/inflation.cc
new file mode 100644
index 00000000000..1b2d3c96864
--- /dev/null
+++ b/Build/source/utils/asymptote/prc/PRCTools/inflation.cc
@@ -0,0 +1,90 @@
+/************
+*
+* This file is part of a tool for reading 3D content in the PRC format.
+* Copyright (C) 2008 Orest Shardt <shardtor (at) gmail dot com>
+*
+* This program 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 3 of the License, or
+* (at your option) any later version.
+*
+* This program 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 program. If not, see <http://www.gnu.org/licenses/>.
+*
+*************/
+
+#include "inflation.h"
+
+using std::istream;
+using std::ios;
+using std::cout;
+using std::cerr;
+using std::endl;
+using std::exit;
+
+int decompress(char* inb, int fileLength, char* &outb)
+{
+ const int CHUNK = 16384;
+ unsigned int resultSize = 0;
+
+ outb = (char*) realloc(outb,CHUNK);
+ z_stream strm;
+ strm.zalloc = Z_NULL;
+ strm.zfree = Z_NULL;
+ strm.avail_in = fileLength;
+ strm.next_in = (unsigned char*)inb;
+ strm.opaque = Z_NULL;
+ int code = inflateInit(&strm);
+
+ if(code != Z_OK)
+ return -1;
+
+ strm.next_out = (unsigned char*)outb;
+ strm.avail_out = CHUNK;
+ code = inflate(&strm,Z_NO_FLUSH);
+ resultSize = CHUNK-strm.avail_out;
+
+ unsigned int size = CHUNK;
+ while(code == Z_OK)
+ {
+ outb = (char*) realloc(outb,2*size);
+ if(outb == NULL)
+ {
+ cerr << "Ran out of memory while decompressing." << endl;
+ exit(1);
+ }
+ strm.next_out = (Bytef*)(outb + resultSize);
+ strm.avail_out += size;
+ size *= 2;
+ code = inflate(&strm,Z_NO_FLUSH);
+ resultSize = size - strm.avail_out;
+ }
+
+ code = inflateEnd(&strm);
+ if(code != Z_OK)
+ {
+ free(outb);
+ return 0;
+ }
+
+ return resultSize;
+}
+
+int decompress(istream &input,char* &result)
+{
+ input.seekg(0,ios::end);
+ int fileLength = input.tellg();
+ input.seekg(0,ios::beg);
+
+ char *inb = new char[fileLength];
+ input.read(inb,fileLength);
+
+ int code = decompress(inb,fileLength,result);
+ delete[] inb;
+ return code;
+}
diff --git a/Build/source/utils/asymptote/prc/PRCTools/inflation.h b/Build/source/utils/asymptote/prc/PRCTools/inflation.h
new file mode 100644
index 00000000000..79d29caa7f0
--- /dev/null
+++ b/Build/source/utils/asymptote/prc/PRCTools/inflation.h
@@ -0,0 +1,31 @@
+/************
+*
+* This file is part of a tool for reading 3D content in the PRC format.
+* Copyright (C) 2008 Orest Shardt <shardtor (at) gmail dot com>
+*
+* This program 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 3 of the License, or
+* (at your option) any later version.
+*
+* This program 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 program. If not, see <http://www.gnu.org/licenses/>.
+*
+*************/
+
+#ifndef __INFLATION_H
+#define __INFLATION_H
+
+#include <iostream>
+#include <cstdlib>
+#include <zlib.h>
+
+int decompress(std::istream&,char*&);
+int decompress(char*,int,char*&);
+
+#endif // __INFLATION_H
diff --git a/Build/source/utils/asymptote/prc/PRCTools/inflationMain.cc b/Build/source/utils/asymptote/prc/PRCTools/inflationMain.cc
new file mode 100644
index 00000000000..81beefd26d2
--- /dev/null
+++ b/Build/source/utils/asymptote/prc/PRCTools/inflationMain.cc
@@ -0,0 +1,55 @@
+/************
+*
+* This file is part of a tool for reading 3D content in the PRC format.
+* Copyright (C) 2008 Orest Shardt <shardtor (at) gmail dot com>
+*
+* This program 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 3 of the License, or
+* (at your option) any later version.
+*
+* This program 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 program. If not, see <http://www.gnu.org/licenses/>.
+*
+*************/
+
+#include <cstdlib>
+#include <iostream>
+#include <iomanip>
+#include <fstream>
+#include "inflation.h"
+
+using namespace std;
+
+int main(int argc, char *argv[])
+{
+ if(argc < 2)
+ {
+ cerr << "No file specified." << endl;
+ return 1;
+ }
+
+ ifstream data(argv[1]);
+
+ char *buff = NULL;
+ int dataSize = decompress(data,buff);
+
+ cout << hex;
+
+ for(int i = 0; i < dataSize; ++i)
+ {
+ cout << ' ' << setw(2) << setfill('0')
+ << static_cast<unsigned int>(static_cast<unsigned char>(buff[i]));
+ if(i%16 == 15)
+ cout << endl;
+ }
+ cout << endl << dec << dataSize << " bytes" << endl;
+ free(buff);
+
+ return 0;
+}
diff --git a/Build/source/utils/asymptote/prc/PRCTools/makePRC.cc b/Build/source/utils/asymptote/prc/PRCTools/makePRC.cc
new file mode 100644
index 00000000000..f7573000203
--- /dev/null
+++ b/Build/source/utils/asymptote/prc/PRCTools/makePRC.cc
@@ -0,0 +1,187 @@
+/************
+*
+* This file is part of a tool for producing 3D content in the PRC format.
+* Copyright (C) 2008 Orest Shardt <shardtor (at) gmail dot com>
+*
+* This program 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 3 of the License, or
+* (at your option) any later version.
+*
+* This program 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 program. If not, see <http://www.gnu.org/licenses/>.
+*
+*************/
+
+#include <iostream>
+#include <iomanip>
+#include <fstream>
+#include <unistd.h>
+#include <cstdlib>
+#include "../oPRCFile.h"
+
+using namespace std;
+
+void readPoints(istream &is, unsigned int n, double p[][3])
+{
+ for(unsigned int i = 0; i < n; ++i)
+ {
+ is >> p[i][0] >> p[i][1] >> p[i][2];
+ }
+ if(!is)
+ {
+ cerr << "Error reading list of points." << endl;
+ exit(1);
+ }
+}
+
+void readDoubles(istream &is, unsigned int n, double d[])
+{
+ for(unsigned int i = 0; i < n; ++i)
+ {
+ is >> d[i];
+ }
+ if(!is)
+ {
+ cerr << "Error reading list of doubles." << endl;
+ exit(1);
+ }
+}
+
+int main(int argc, char **argv)
+{
+ const char *oFileName = "output.prc";
+
+ int c;
+ opterr = 0;
+ while ((c = getopt (argc, argv, "o:")) != -1)
+ switch (c)
+ {
+ case 'o':
+ oFileName = optarg;
+ break;
+ case '?':
+ if (optopt == 'o')
+ cerr << "Option '-o' requires an argument, the filename." << endl;
+ else
+ cerr << "Unrecognized option '-" << (char)optopt << "'." << endl;
+ exit(1);
+ break;
+ default:
+ exit(1);
+ }
+ istream *ins = NULL;
+ if(optind < argc)
+ {
+ ins = new ifstream(argv[optind]);
+ if(!*ins)
+ {
+ cerr << "Error opening input file " << argv[optind] << endl;
+ exit(1);
+ }
+ }
+ else
+ {
+ ins = &cin;
+ }
+
+ ofstream outf(oFileName);
+ if(!outf)
+ {
+ cerr << "Error opening output file " << oFileName << endl;
+ exit(1);
+ }
+
+ oPRCFile oPRC(outf);
+
+ string entityType;
+ while(*ins)
+ {
+ *ins >> entityType;
+ if(!*ins) break;
+ if(entityType == "Line")
+ {
+ double r,g,b,a;
+ unsigned int numberOfPoints;
+ *ins >> r >> g >> b >> a >> numberOfPoints;
+ if(!*ins)
+ {
+ cerr << "Error reading line data." << endl;
+ exit(1);
+ }
+ else
+ {
+ double (*points)[3] = new double[numberOfPoints][3];
+ readPoints(*ins,numberOfPoints,points);
+ oPRC.add(new PRCline(&oPRC,numberOfPoints,points,
+ *new RGBAColour(r,g,b,a)));
+ }
+ }
+ else if(entityType == "Curve")
+ {
+ double r,g,b,a;
+ unsigned int numberOfPoints;
+ unsigned int degree;
+ *ins >> r >> g >> b >> a >> degree >> numberOfPoints;
+ if(!*ins)
+ {
+ cerr << "Error reading curve data." << endl;
+ exit(1);
+ }
+ else
+ {
+ double (*points)[3] = new double[numberOfPoints][3];
+ double *knots = new double[degree+numberOfPoints+1];
+ readPoints(*ins,numberOfPoints,points);
+ readDoubles(*ins,degree+numberOfPoints+1,knots);
+ oPRC.add(new PRCcurve(&oPRC,degree,numberOfPoints,points,
+ knots,*new RGBAColour(r,g,b,a)));
+ }
+ }
+ else if(entityType == "Surface")
+ {
+ double r,g,b,a;
+ unsigned int numberOfPointsU,numberOfPointsV;
+ unsigned int degreeU,degreeV;
+ *ins >> r >> g >> b >> a >> degreeU >> degreeV >> numberOfPointsU
+ >> numberOfPointsV;
+ if(!*ins)
+ {
+ cerr << "Error reading surface data." << endl;
+ exit(1);
+ }
+ else
+ {
+ double (*points)[3] = new double[numberOfPointsU*numberOfPointsV][3];
+ double *knotsU = new double[degreeU+numberOfPointsU+1];
+ double *knotsV = new double[degreeV+numberOfPointsV+1];
+ readPoints(*ins,numberOfPointsU*numberOfPointsV,points);
+ readDoubles(*ins,degreeU+numberOfPointsU+1,knotsU);
+ readDoubles(*ins,degreeV+numberOfPointsV+1,knotsV);
+ oPRC.add(new PRCsurface(&oPRC,degreeU,degreeV,numberOfPointsU,
+ numberOfPointsV,points,knotsU,knotsV,
+ *new RGBAColour(r,g,b,a)));
+ }
+ }
+ else
+ {
+ cerr << "Unrecognized entity type " << entityType << endl;
+ exit(1);
+ }
+ }
+
+ if(ins && ins != &cin)
+ delete ins;
+
+
+ oPRC.finish();
+
+ outf.close();
+
+ return 0;
+}
diff --git a/Build/source/utils/asymptote/prc/PRCbitStream.cc b/Build/source/utils/asymptote/prc/PRCbitStream.cc
new file mode 100644
index 00000000000..2aa6d73ce98
--- /dev/null
+++ b/Build/source/utils/asymptote/prc/PRCbitStream.cc
@@ -0,0 +1,385 @@
+/************
+*
+* This file is part of a tool for producing 3D content in the PRC format.
+* Copyright (C) 2008 Orest Shardt <shardtor (at) gmail dot com>
+*
+* This program 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 3 of the License, or
+* (at your option) any later version.
+*
+* This program 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 program. If not, see <http://www.gnu.org/licenses/>.
+*
+*************/
+
+#include <iostream>
+#include <zlib.h>
+#include <stdlib.h>
+#include <string.h>
+#include <cassert>
+#include "PRCbitStream.h"
+#include "PRCdouble.h"
+
+using std::string;
+using std::cerr;
+using std::endl;
+
+void PRCbitStream::compress()
+{
+ const int CHUNK= 1024; // is this reasonable?
+ compressedDataSize = 0;
+
+ z_stream strm;
+ strm.zalloc = Z_NULL;
+ strm.zfree = Z_NULL;
+ strm.opaque = Z_NULL;
+ if(deflateInit(&strm,Z_DEFAULT_COMPRESSION) != Z_OK)
+ {
+ cerr << "Compression initialization failed" << endl;
+ return;
+ }
+ unsigned int sizeAvailable = deflateBound(&strm,getSize());
+ uint8_t *compressedData = (uint8_t*) malloc(sizeAvailable);
+ strm.avail_in = getSize();
+ strm.next_in = (unsigned char*)data;
+ strm.next_out = (unsigned char*)compressedData;
+ strm.avail_out = sizeAvailable;
+
+ int code;
+ unsigned int chunks = 0;
+ while((code = deflate(&strm,Z_FINISH)) == Z_OK)
+ {
+ ++chunks;
+ // strm.avail_out should be 0 if we got Z_OK
+ compressedDataSize = sizeAvailable - strm.avail_out;
+ compressedData = (uint8_t*) realloc(compressedData,CHUNK*chunks);
+ strm.next_out = (Bytef*)(compressedData + compressedDataSize);
+ strm.avail_out += CHUNK;
+ sizeAvailable += CHUNK;
+ }
+ compressedDataSize = sizeAvailable-strm.avail_out;
+
+ if(code != Z_STREAM_END)
+ {
+ cerr << "Compression error" << endl;
+ deflateEnd(&strm);
+ free(compressedData);
+ return;
+ }
+
+ compressed = true;
+
+ free(data);
+ data = compressedData;
+
+ deflateEnd(&strm);
+}
+
+unsigned int PRCbitStream::getSize() const
+{
+ if(compressed)
+ return compressedDataSize;
+ else
+ return byteIndex+1;
+}
+
+uint8_t* PRCbitStream::getData()
+{
+ return data;
+}
+
+PRCbitStream& PRCbitStream::operator <<(bool b)
+{
+ writeBit(b);
+ return *this;
+}
+
+PRCbitStream& PRCbitStream::operator <<(uint32_t u)
+{
+ while(u != 0)
+ {
+ writeBit(1);
+ writeByte(u & 0xFF);
+ u >>= 8;
+ }
+ writeBit(0);
+ return *this;
+}
+
+PRCbitStream& PRCbitStream::operator <<(uint8_t u)
+{
+ writeByte(u);
+ return *this;
+}
+
+PRCbitStream& PRCbitStream::operator <<(int32_t i)
+{
+ uint8_t lastByte = 0;
+ //while(!((current value is 0 and last byte was positive) OR (current value is -1 and last value was negative)))
+ while(!(((i == 0)&&((lastByte & 0x80)==0))||((i == -1)&&((lastByte & 0x80) != 0))))
+ {
+ writeBit(1);
+ lastByte = i & 0xFF;
+ writeByte(lastByte);
+ i >>= 8;
+ }
+ writeBit(0);
+ return *this;
+}
+
+PRCbitStream& PRCbitStream::operator <<(double value)
+{
+ // write a double
+ if(compressed)
+ {
+ cerr << "Cannot write to a stream that has been compressed." << endl;
+ return *this;
+ }
+ union ieee754_double *pid=(union ieee754_double *)&value;
+ int
+ i,
+ fSaveAtEnd;
+ PRCbyte
+ *pb,
+ *pbStart,
+ *pbStop,
+ *pbEnd,
+ *pbResult,
+ bSaveAtEnd = 0;
+ struct sCodageOfFrequentDoubleOrExponent
+ cofdoe,
+ *pcofdoe;
+
+ cofdoe.u2uod.Value=value;
+ pcofdoe = (struct sCodageOfFrequentDoubleOrExponent *)bsearch(
+ &cofdoe,
+ acofdoe,
+ sizeof(acofdoe)/sizeof(pcofdoe[0]),
+ sizeof(pcofdoe[0]),
+ stCOFDOECompare);
+
+ while(pcofdoe>acofdoe && EXPONENT(pcofdoe->u2uod.Value)==EXPONENT((pcofdoe-1)->u2uod.Value))
+ pcofdoe--;
+
+ assert(pcofdoe);
+ while(pcofdoe->Type==VT_double)
+ {
+ if(fabs(value)==pcofdoe->u2uod.Value)
+ break;
+ pcofdoe++;
+ }
+
+ for(i=1<<(pcofdoe->NumberOfBits-1);i>=1;i>>=1)
+ writeBit((pcofdoe->Bits&i)!=0);
+
+ if
+ (
+ !memcmp(&value,stadwZero,sizeof(value))
+ || !memcmp(&value,stadwNegativeZero,sizeof(value))
+ )
+ return *this;
+
+ writeBit(pid->ieee.negative);
+
+ if(pcofdoe->Type==VT_double)
+ return *this;
+
+ if(pid->ieee.mantissa0==0 && pid->ieee.mantissa1==0)
+ {
+ writeBit(0);
+ return *this;
+ }
+
+ writeBit(1);
+
+#if defined(WORDS_LITTLE_ENDIAN)
+ pb=((PRCbyte *)&value)+6;
+#elif defined(WORDS_BIG_ENDIAN)
+ pb=((PRCbyte *)&value)+1;
+#endif
+ //add_bits((*pb)&0x0f,4 STAT_V STAT_DOUBLE);
+ writeBits((*pb)&0x0F,4);
+
+ NEXTBYTE(pb);
+ pbStart=pb;
+#if defined(WORDS_LITTLE_ENDIAN)
+ pbEnd=
+ pbStop= ((PRCbyte *)&value);
+#elif defined(WORDS_BIG_ENDIAN)
+ pbEnd=
+ pbStop= ((PRCbyte *)(&value+1))-1;
+#endif
+
+ if((fSaveAtEnd=(*pbStop!=*BEFOREBYTE(pbStop)))!=0)
+ bSaveAtEnd=*pbEnd;
+ PREVIOUSBYTE(pbStop);
+
+ while(*pbStop==*BEFOREBYTE(pbStop))
+ PREVIOUSBYTE(pbStop);
+
+ for(;MOREBYTE(pb,pbStop);NEXTBYTE(pb))
+ {
+ if(pb!=pbStart && (pbResult=SEARCHBYTE(BEFOREBYTE(pb),*pb,DIFFPOINTERS(pb,pbStart)))!=NULL)
+ {
+ writeBit(0);
+ writeBits(DIFFPOINTERS(pb,pbResult),3);
+ }
+ else
+ {
+ writeBit(1);
+ writeByte(*pb);
+ }
+ }
+
+ if(!MOREBYTE(BEFOREBYTE(pbEnd),pbStop))
+ {
+ if(fSaveAtEnd)
+ {
+ writeBit(0);
+ writeBits(6,3);
+ writeByte(bSaveAtEnd);
+ }
+ else
+ {
+ writeBit(0);
+ writeBits(0,3);
+ }
+ }
+ else
+ {
+ if((pbResult=SEARCHBYTE(BEFOREBYTE(pb),*pb,DIFFPOINTERS(pb,pbStart)))!=NULL)
+ {
+ writeBit(0);
+ writeBits(DIFFPOINTERS(pb,pbResult),3);
+ }
+ else
+ {
+ writeBit(1);
+ writeByte(*pb);
+ }
+ }
+
+ return *this;
+}
+
+PRCbitStream& PRCbitStream::operator <<(const char* s)
+{
+ string str(s);
+ *this << str;
+ return *this;
+}
+
+PRCbitStream& PRCbitStream::operator <<(const string& s)
+{
+ if(s == "")
+ {
+ writeBit(false); // string is NULL
+ return *this;
+ }
+ writeBit(true);
+ size_t l = s.length();
+ *this << static_cast<uint32_t>(l);
+ for(size_t i = 0; i < l; ++i)
+ writeByte(s[i]);
+ return *this;
+}
+
+void PRCbitStream::writeBit(bool b)
+{
+ if(compressed)
+ {
+ cerr << "Cannot write to a stream that has been compressed." << endl;
+ return;
+ }
+
+ if(b)
+ {
+ data[byteIndex] |= (0x80 >> bitIndex);
+ }
+ nextBit();
+}
+
+void PRCbitStream::writeBits(uint32_t u, uint8_t bits)
+{
+ if(bits > 32)
+ return;
+ else
+ {
+ for(uint32_t mask = (1 << (bits-1)); mask != 0; mask >>= 1)
+ {
+ writeBit((u&mask) != 0);
+ }
+ }
+}
+
+void PRCbitStream::writeByte(uint8_t u)
+{
+ if(compressed)
+ {
+ cerr << "Cannot write to a stream that has been compressed." << endl;
+ return;
+ }
+
+ if(bitIndex == 0)
+ {
+ data[byteIndex] = u;
+ nextByte();
+ }
+ else
+ {
+ data[byteIndex] |= (u >> bitIndex);
+ unsigned int obi = bitIndex;
+ nextByte();
+ data[byteIndex] |= (u << (8-obi));
+ bitIndex = obi; // bit index is not changed by writing 8 bits
+ }
+}
+
+void PRCbitStream::nextBit()
+{
+ ++bitIndex;
+ if(bitIndex == 8)
+ {
+ nextByte();
+ }
+}
+
+void PRCbitStream::nextByte()
+{
+ ++byteIndex;
+ if(byteIndex >= allocatedLength)
+ getAChunk();
+ data[byteIndex] = 0; // clear the garbage data
+ bitIndex = 0;
+}
+
+void PRCbitStream::getAChunk()
+{
+ if(allocatedLength==0)
+ data = (uint8_t*)realloc((void*)data,CHUNK_SIZE);
+ else
+ data = (uint8_t*)realloc((void*)data,2*allocatedLength);
+
+ if(data != NULL)
+ {
+ if(allocatedLength==0)
+ {
+ allocatedLength = CHUNK_SIZE;
+ *data = 0; // clear first byte
+ }
+ else
+ allocatedLength *= 2;
+ }
+ else
+ {
+ // warn about memory problem!
+ cerr << "Memory allocation error." << endl;
+ exit(1);
+ }
+}
diff --git a/Build/source/utils/asymptote/prc/PRCbitStream.h b/Build/source/utils/asymptote/prc/PRCbitStream.h
new file mode 100644
index 00000000000..58342812c36
--- /dev/null
+++ b/Build/source/utils/asymptote/prc/PRCbitStream.h
@@ -0,0 +1,70 @@
+/************
+*
+* This file is part of a tool for producing 3D content in the PRC format.
+* Copyright (C) 2008 Orest Shardt <shardtor (at) gmail dot com>
+*
+* This program 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 3 of the License, or
+* (at your option) any later version.
+*
+* This program 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 program. If not, see <http://www.gnu.org/licenses/>.
+*
+*************/
+
+#ifndef __PRC_BIT_STREAM_H
+#define __PRC_BIT_STREAM_H
+
+#include <string>
+#include <stdlib.h>
+#include <stdint.h>
+
+#define CHUNK_SIZE (1024)
+// Is this a reasonable initial size?
+
+class PRCbitStream
+{
+ public:
+ PRCbitStream(uint8_t*& buff, unsigned int l) : byteIndex(0), bitIndex(0),
+ allocatedLength(l), data(buff), compressed(false)
+ {
+ if(data == 0)
+ {
+ getAChunk();
+ }
+ }
+
+ unsigned int getSize() const;
+ uint8_t* getData();
+
+ PRCbitStream& operator <<(const std::string&);
+ PRCbitStream& operator <<(bool);
+ PRCbitStream& operator <<(uint32_t);
+ PRCbitStream& operator <<(uint8_t);
+ PRCbitStream& operator <<(int32_t);
+ PRCbitStream& operator <<(double);
+ PRCbitStream& operator <<(const char*);
+
+ void compress();
+ private:
+ void writeBit(bool);
+ void writeBits(uint32_t,uint8_t);
+ void writeByte(uint8_t);
+ void nextByte();
+ void nextBit();
+ void getAChunk();
+ // bitIndex is "big endian", zero based, location of next bit to write
+ unsigned int byteIndex,bitIndex;
+ unsigned int allocatedLength;
+ uint8_t*& data;
+ bool compressed;
+ uint32_t compressedDataSize;
+};
+
+#endif // __PRC_BIT_STREAM_H
diff --git a/Build/source/utils/asymptote/prc/PRCdouble.cc b/Build/source/utils/asymptote/prc/PRCdouble.cc
new file mode 100644
index 00000000000..c51dd6317da
--- /dev/null
+++ b/Build/source/utils/asymptote/prc/PRCdouble.cc
@@ -0,0 +1,2119 @@
+#include "PRCdouble.h"
+
+// from Adobe's documentation
+
+PRCdword stadwZero[2]={DOUBLEWITHTWODWORD(0x00000000,0x00000000)};
+PRCdword stadwNegativeZero[2]={DOUBLEWITHTWODWORD(0x80000000,0x00000000)};
+
+struct sCodageOfFrequentDoubleOrExponent* getcofdoe(unsigned Bits, short NumberOfBits)
+{
+ struct sCodageOfFrequentDoubleOrExponent *pcofdoe;
+ for(pcofdoe=acofdoe; pcofdoe < acofdoe+NUMBEROFELEMENTINACOFDOE; ++pcofdoe)
+ {
+ if(pcofdoe->NumberOfBits == NumberOfBits && pcofdoe->Bits == Bits)
+ return pcofdoe;
+ }
+ return NULL;
+}
+
+int stCOFDOECompare(const void* pcofdoe1,const void* pcofdoe2)
+{
+ return(EXPONENT(((const struct sCodageOfFrequentDoubleOrExponent *)pcofdoe1)->u2uod.Value)-
+ EXPONENT(((const struct sCodageOfFrequentDoubleOrExponent *)pcofdoe2)->u2uod.Value));
+}
+
+#if defined(WORDS_BIG_ENDIAN)
+void *memrchr(const void *buf,int c,size_t count)
+{
+ unsigned char
+ *pcBuffer=(unsigned char *)buf,
+ *pcBufferEnd=pcBuffer-count;
+
+ for(;pcBuffer>pcBufferEnd;pcBuffer--)
+ if(*pcBuffer==c)
+ return(pcBuffer);
+
+ return(NULL);
+}
+#endif
+
+sCodageOfFrequentDoubleOrExponent acofdoe[NUMBEROFELEMENTINACOFDOE] =
+{
+ {VT_double,2,0x1,{DOUBLEWITHTWODWORDINTREE(0x00000000,0x00000000)}},
+ {VT_exponent,22,0xd1d32,{DOUBLEWITHTWODWORDINTREE(0x00000000,0x00000000)}},
+ {VT_exponent,22,0xd1d33,{DOUBLEWITHTWODWORDINTREE(0x00100000,0x00000000)}},
+ {VT_exponent,22,0xf78d8,{DOUBLEWITHTWODWORDINTREE(0x00200000,0x00000000)}},
+ {VT_exponent,22,0xf78d9,{DOUBLEWITHTWODWORDINTREE(0x00300000,0x00000000)}},
+ {VT_exponent,22,0xf78da,{DOUBLEWITHTWODWORDINTREE(0x00400000,0x00000000)}},
+ {VT_exponent,22,0xf78db,{DOUBLEWITHTWODWORDINTREE(0x00500000,0x00000000)}},
+ {VT_exponent,22,0xf78dc,{DOUBLEWITHTWODWORDINTREE(0x00600000,0x00000000)}},
+ {VT_exponent,22,0xf78dd,{DOUBLEWITHTWODWORDINTREE(0x00700000,0x00000000)}},
+ {VT_exponent,22,0xf78de,{DOUBLEWITHTWODWORDINTREE(0x00800000,0x00000000)}},
+ {VT_exponent,22,0xf78df,{DOUBLEWITHTWODWORDINTREE(0x00900000,0x00000000)}},
+ {VT_exponent,22,0xf78e0,{DOUBLEWITHTWODWORDINTREE(0x00a00000,0x00000000)}},
+ {VT_exponent,22,0xf78e1,{DOUBLEWITHTWODWORDINTREE(0x00b00000,0x00000000)}},
+ {VT_exponent,22,0xf78e2,{DOUBLEWITHTWODWORDINTREE(0x00c00000,0x00000000)}},
+ {VT_exponent,22,0xf78e3,{DOUBLEWITHTWODWORDINTREE(0x00d00000,0x00000000)}},
+ {VT_exponent,22,0xf78e4,{DOUBLEWITHTWODWORDINTREE(0x00e00000,0x00000000)}},
+ {VT_exponent,22,0xf78e5,{DOUBLEWITHTWODWORDINTREE(0x00f00000,0x00000000)}},
+ {VT_exponent,22,0xf78e6,{DOUBLEWITHTWODWORDINTREE(0x01000000,0x00000000)}},
+ {VT_exponent,22,0xf78e7,{DOUBLEWITHTWODWORDINTREE(0x01100000,0x00000000)}},
+ {VT_exponent,22,0xf78e8,{DOUBLEWITHTWODWORDINTREE(0x01200000,0x00000000)}},
+ {VT_exponent,22,0xf78e9,{DOUBLEWITHTWODWORDINTREE(0x01300000,0x00000000)}},
+ {VT_exponent,22,0xf78ea,{DOUBLEWITHTWODWORDINTREE(0x01400000,0x00000000)}},
+ {VT_exponent,22,0xf78eb,{DOUBLEWITHTWODWORDINTREE(0x01500000,0x00000000)}},
+ {VT_exponent,22,0xf78ec,{DOUBLEWITHTWODWORDINTREE(0x01600000,0x00000000)}},
+ {VT_exponent,22,0xf78ed,{DOUBLEWITHTWODWORDINTREE(0x01700000,0x00000000)}},
+ {VT_exponent,22,0xf78ee,{DOUBLEWITHTWODWORDINTREE(0x01800000,0x00000000)}},
+ {VT_exponent,22,0xf78ef,{DOUBLEWITHTWODWORDINTREE(0x01900000,0x00000000)}},
+ {VT_exponent,22,0xf78f0,{DOUBLEWITHTWODWORDINTREE(0x01a00000,0x00000000)}},
+ {VT_exponent,22,0xf78f1,{DOUBLEWITHTWODWORDINTREE(0x01b00000,0x00000000)}},
+ {VT_exponent,22,0xf78f2,{DOUBLEWITHTWODWORDINTREE(0x01c00000,0x00000000)}},
+ {VT_exponent,22,0xf78f3,{DOUBLEWITHTWODWORDINTREE(0x01d00000,0x00000000)}},
+ {VT_exponent,22,0xf78f4,{DOUBLEWITHTWODWORDINTREE(0x01e00000,0x00000000)}},
+ {VT_exponent,22,0xf78f5,{DOUBLEWITHTWODWORDINTREE(0x01f00000,0x00000000)}},
+ {VT_exponent,22,0xf78f6,{DOUBLEWITHTWODWORDINTREE(0x02000000,0x00000000)}},
+ {VT_exponent,22,0xf78f7,{DOUBLEWITHTWODWORDINTREE(0x02100000,0x00000000)}},
+ {VT_exponent,22,0xf78f8,{DOUBLEWITHTWODWORDINTREE(0x02200000,0x00000000)}},
+ {VT_exponent,22,0xf78f9,{DOUBLEWITHTWODWORDINTREE(0x02300000,0x00000000)}},
+ {VT_exponent,22,0xf78fa,{DOUBLEWITHTWODWORDINTREE(0x02400000,0x00000000)}},
+ {VT_exponent,22,0xf78fb,{DOUBLEWITHTWODWORDINTREE(0x02500000,0x00000000)}},
+ {VT_exponent,22,0xf78fc,{DOUBLEWITHTWODWORDINTREE(0x02600000,0x00000000)}},
+ {VT_exponent,22,0xf78fd,{DOUBLEWITHTWODWORDINTREE(0x02700000,0x00000000)}},
+ {VT_exponent,22,0xf78fe,{DOUBLEWITHTWODWORDINTREE(0x02800000,0x00000000)}},
+ {VT_exponent,22,0xf78ff,{DOUBLEWITHTWODWORDINTREE(0x02900000,0x00000000)}},
+ {VT_exponent,22,0x3a8300,{DOUBLEWITHTWODWORDINTREE(0x02a00000,0x00000000)}},
+ {VT_exponent,22,0x3a8301,{DOUBLEWITHTWODWORDINTREE(0x02b00000,0x00000000)}},
+ {VT_exponent,22,0x3a8302,{DOUBLEWITHTWODWORDINTREE(0x02c00000,0x00000000)}},
+ {VT_exponent,22,0x3a8303,{DOUBLEWITHTWODWORDINTREE(0x02d00000,0x00000000)}},
+ {VT_exponent,22,0x3a8304,{DOUBLEWITHTWODWORDINTREE(0x02e00000,0x00000000)}},
+ {VT_exponent,22,0x3a8305,{DOUBLEWITHTWODWORDINTREE(0x02f00000,0x00000000)}},
+ {VT_exponent,22,0x3a8306,{DOUBLEWITHTWODWORDINTREE(0x03000000,0x00000000)}},
+ {VT_exponent,22,0x3a8307,{DOUBLEWITHTWODWORDINTREE(0x03100000,0x00000000)}},
+ {VT_exponent,22,0x3a8308,{DOUBLEWITHTWODWORDINTREE(0x03200000,0x00000000)}},
+ {VT_exponent,22,0x3a8309,{DOUBLEWITHTWODWORDINTREE(0x03300000,0x00000000)}},
+ {VT_exponent,22,0x3a830a,{DOUBLEWITHTWODWORDINTREE(0x03400000,0x00000000)}},
+ {VT_exponent,22,0x3a830b,{DOUBLEWITHTWODWORDINTREE(0x03500000,0x00000000)}},
+ {VT_exponent,22,0x3a830c,{DOUBLEWITHTWODWORDINTREE(0x03600000,0x00000000)}},
+ {VT_exponent,22,0x3a830d,{DOUBLEWITHTWODWORDINTREE(0x03700000,0x00000000)}},
+ {VT_exponent,22,0x3a830e,{DOUBLEWITHTWODWORDINTREE(0x03800000,0x00000000)}},
+ {VT_exponent,22,0x3a830f,{DOUBLEWITHTWODWORDINTREE(0x03900000,0x00000000)}},
+ {VT_exponent,22,0x3a8310,{DOUBLEWITHTWODWORDINTREE(0x03a00000,0x00000000)}},
+ {VT_exponent,22,0x3a8311,{DOUBLEWITHTWODWORDINTREE(0x03b00000,0x00000000)}},
+ {VT_exponent,22,0x3a8312,{DOUBLEWITHTWODWORDINTREE(0x03c00000,0x00000000)}},
+ {VT_exponent,22,0x3a8313,{DOUBLEWITHTWODWORDINTREE(0x03d00000,0x00000000)}},
+ {VT_exponent,22,0x3a8314,{DOUBLEWITHTWODWORDINTREE(0x03e00000,0x00000000)}},
+ {VT_exponent,22,0x3a8315,{DOUBLEWITHTWODWORDINTREE(0x03f00000,0x00000000)}},
+ {VT_exponent,22,0x3a8316,{DOUBLEWITHTWODWORDINTREE(0x04000000,0x00000000)}},
+ {VT_exponent,22,0x3a8317,{DOUBLEWITHTWODWORDINTREE(0x04100000,0x00000000)}},
+ {VT_exponent,22,0x3a8318,{DOUBLEWITHTWODWORDINTREE(0x04200000,0x00000000)}},
+ {VT_exponent,22,0x3a8319,{DOUBLEWITHTWODWORDINTREE(0x04300000,0x00000000)}},
+ {VT_exponent,22,0x3a831a,{DOUBLEWITHTWODWORDINTREE(0x04400000,0x00000000)}},
+ {VT_exponent,22,0x3a831b,{DOUBLEWITHTWODWORDINTREE(0x04500000,0x00000000)}},
+ {VT_exponent,22,0x3a831c,{DOUBLEWITHTWODWORDINTREE(0x04600000,0x00000000)}},
+ {VT_exponent,22,0x3a831d,{DOUBLEWITHTWODWORDINTREE(0x04700000,0x00000000)}},
+ {VT_exponent,22,0x3a831e,{DOUBLEWITHTWODWORDINTREE(0x04800000,0x00000000)}},
+ {VT_exponent,22,0x3a831f,{DOUBLEWITHTWODWORDINTREE(0x04900000,0x00000000)}},
+ {VT_exponent,22,0x3a8320,{DOUBLEWITHTWODWORDINTREE(0x04a00000,0x00000000)}},
+ {VT_exponent,22,0x3a8321,{DOUBLEWITHTWODWORDINTREE(0x04b00000,0x00000000)}},
+ {VT_exponent,22,0x3a8322,{DOUBLEWITHTWODWORDINTREE(0x04c00000,0x00000000)}},
+ {VT_exponent,22,0x3a8323,{DOUBLEWITHTWODWORDINTREE(0x04d00000,0x00000000)}},
+ {VT_exponent,22,0x3a8324,{DOUBLEWITHTWODWORDINTREE(0x04e00000,0x00000000)}},
+ {VT_exponent,22,0x3a8325,{DOUBLEWITHTWODWORDINTREE(0x04f00000,0x00000000)}},
+ {VT_exponent,22,0x3a8326,{DOUBLEWITHTWODWORDINTREE(0x05000000,0x00000000)}},
+ {VT_exponent,22,0x3a8327,{DOUBLEWITHTWODWORDINTREE(0x05100000,0x00000000)}},
+ {VT_exponent,22,0x3a8328,{DOUBLEWITHTWODWORDINTREE(0x05200000,0x00000000)}},
+ {VT_exponent,22,0x3a8329,{DOUBLEWITHTWODWORDINTREE(0x05300000,0x00000000)}},
+ {VT_exponent,22,0x3a832a,{DOUBLEWITHTWODWORDINTREE(0x05400000,0x00000000)}},
+ {VT_exponent,22,0x3a832b,{DOUBLEWITHTWODWORDINTREE(0x05500000,0x00000000)}},
+ {VT_exponent,22,0x3a832c,{DOUBLEWITHTWODWORDINTREE(0x05600000,0x00000000)}},
+ {VT_exponent,22,0x3a832d,{DOUBLEWITHTWODWORDINTREE(0x05700000,0x00000000)}},
+ {VT_exponent,22,0x3a832e,{DOUBLEWITHTWODWORDINTREE(0x05800000,0x00000000)}},
+ {VT_exponent,22,0x3a832f,{DOUBLEWITHTWODWORDINTREE(0x05900000,0x00000000)}},
+ {VT_exponent,22,0x3a8330,{DOUBLEWITHTWODWORDINTREE(0x05a00000,0x00000000)}},
+ {VT_exponent,22,0x3a8331,{DOUBLEWITHTWODWORDINTREE(0x05b00000,0x00000000)}},
+ {VT_exponent,22,0x3a8332,{DOUBLEWITHTWODWORDINTREE(0x05c00000,0x00000000)}},
+ {VT_exponent,22,0x3a8333,{DOUBLEWITHTWODWORDINTREE(0x05d00000,0x00000000)}},
+ {VT_exponent,22,0x3a8334,{DOUBLEWITHTWODWORDINTREE(0x05e00000,0x00000000)}},
+ {VT_exponent,22,0x3a8335,{DOUBLEWITHTWODWORDINTREE(0x05f00000,0x00000000)}},
+ {VT_exponent,22,0x3a8336,{DOUBLEWITHTWODWORDINTREE(0x06000000,0x00000000)}},
+ {VT_exponent,22,0x3a8337,{DOUBLEWITHTWODWORDINTREE(0x06100000,0x00000000)}},
+ {VT_exponent,22,0x3a8338,{DOUBLEWITHTWODWORDINTREE(0x06200000,0x00000000)}},
+ {VT_exponent,22,0x3a8339,{DOUBLEWITHTWODWORDINTREE(0x06300000,0x00000000)}},
+ {VT_exponent,22,0x3a833a,{DOUBLEWITHTWODWORDINTREE(0x06400000,0x00000000)}},
+ {VT_exponent,22,0x3a833b,{DOUBLEWITHTWODWORDINTREE(0x06500000,0x00000000)}},
+ {VT_exponent,22,0x3a833c,{DOUBLEWITHTWODWORDINTREE(0x06600000,0x00000000)}},
+ {VT_exponent,22,0x3a833d,{DOUBLEWITHTWODWORDINTREE(0x06700000,0x00000000)}},
+ {VT_exponent,22,0x3a833e,{DOUBLEWITHTWODWORDINTREE(0x06800000,0x00000000)}},
+ {VT_exponent,22,0x3a833f,{DOUBLEWITHTWODWORDINTREE(0x06900000,0x00000000)}},
+ {VT_exponent,22,0x3a8340,{DOUBLEWITHTWODWORDINTREE(0x06a00000,0x00000000)}},
+ {VT_exponent,22,0x3a8341,{DOUBLEWITHTWODWORDINTREE(0x06b00000,0x00000000)}},
+ {VT_exponent,22,0x3a8342,{DOUBLEWITHTWODWORDINTREE(0x06c00000,0x00000000)}},
+ {VT_exponent,22,0x3a8343,{DOUBLEWITHTWODWORDINTREE(0x06d00000,0x00000000)}},
+ {VT_exponent,22,0x3a8344,{DOUBLEWITHTWODWORDINTREE(0x06e00000,0x00000000)}},
+ {VT_exponent,22,0x3a8345,{DOUBLEWITHTWODWORDINTREE(0x06f00000,0x00000000)}},
+ {VT_exponent,22,0x3a8346,{DOUBLEWITHTWODWORDINTREE(0x07000000,0x00000000)}},
+ {VT_exponent,22,0x3a8347,{DOUBLEWITHTWODWORDINTREE(0x07100000,0x00000000)}},
+ {VT_exponent,22,0x3a8348,{DOUBLEWITHTWODWORDINTREE(0x07200000,0x00000000)}},
+ {VT_exponent,22,0x3a8349,{DOUBLEWITHTWODWORDINTREE(0x07300000,0x00000000)}},
+ {VT_exponent,22,0x3a834a,{DOUBLEWITHTWODWORDINTREE(0x07400000,0x00000000)}},
+ {VT_exponent,22,0x3a834b,{DOUBLEWITHTWODWORDINTREE(0x07500000,0x00000000)}},
+ {VT_exponent,22,0x3a834c,{DOUBLEWITHTWODWORDINTREE(0x07600000,0x00000000)}},
+ {VT_exponent,22,0x3a834d,{DOUBLEWITHTWODWORDINTREE(0x07700000,0x00000000)}},
+ {VT_exponent,22,0x3a834e,{DOUBLEWITHTWODWORDINTREE(0x07800000,0x00000000)}},
+ {VT_exponent,22,0x3a834f,{DOUBLEWITHTWODWORDINTREE(0x07900000,0x00000000)}},
+ {VT_exponent,22,0x3a8350,{DOUBLEWITHTWODWORDINTREE(0x07a00000,0x00000000)}},
+ {VT_exponent,22,0x3a8351,{DOUBLEWITHTWODWORDINTREE(0x07b00000,0x00000000)}},
+ {VT_exponent,22,0x3a8352,{DOUBLEWITHTWODWORDINTREE(0x07c00000,0x00000000)}},
+ {VT_exponent,22,0x3a8353,{DOUBLEWITHTWODWORDINTREE(0x07d00000,0x00000000)}},
+ {VT_exponent,22,0x3a8354,{DOUBLEWITHTWODWORDINTREE(0x07e00000,0x00000000)}},
+ {VT_exponent,22,0x3a8355,{DOUBLEWITHTWODWORDINTREE(0x07f00000,0x00000000)}},
+ {VT_exponent,22,0x3a8356,{DOUBLEWITHTWODWORDINTREE(0x08000000,0x00000000)}},
+ {VT_exponent,22,0x3a8357,{DOUBLEWITHTWODWORDINTREE(0x08100000,0x00000000)}},
+ {VT_exponent,22,0x3a8358,{DOUBLEWITHTWODWORDINTREE(0x08200000,0x00000000)}},
+ {VT_exponent,22,0x3a8359,{DOUBLEWITHTWODWORDINTREE(0x08300000,0x00000000)}},
+ {VT_exponent,22,0x3a835a,{DOUBLEWITHTWODWORDINTREE(0x08400000,0x00000000)}},
+ {VT_exponent,22,0x3a835b,{DOUBLEWITHTWODWORDINTREE(0x08500000,0x00000000)}},
+ {VT_exponent,22,0x3a835c,{DOUBLEWITHTWODWORDINTREE(0x08600000,0x00000000)}},
+ {VT_exponent,22,0x3a835d,{DOUBLEWITHTWODWORDINTREE(0x08700000,0x00000000)}},
+ {VT_exponent,22,0x3a835e,{DOUBLEWITHTWODWORDINTREE(0x08800000,0x00000000)}},
+ {VT_exponent,22,0x3a835f,{DOUBLEWITHTWODWORDINTREE(0x08900000,0x00000000)}},
+ {VT_exponent,22,0x3a8360,{DOUBLEWITHTWODWORDINTREE(0x08a00000,0x00000000)}},
+ {VT_exponent,22,0x3a8361,{DOUBLEWITHTWODWORDINTREE(0x08b00000,0x00000000)}},
+ {VT_exponent,22,0x3a8362,{DOUBLEWITHTWODWORDINTREE(0x08c00000,0x00000000)}},
+ {VT_exponent,22,0x3a8363,{DOUBLEWITHTWODWORDINTREE(0x08d00000,0x00000000)}},
+ {VT_exponent,22,0x3a8364,{DOUBLEWITHTWODWORDINTREE(0x08e00000,0x00000000)}},
+ {VT_exponent,22,0x3a8365,{DOUBLEWITHTWODWORDINTREE(0x08f00000,0x00000000)}},
+ {VT_exponent,22,0x3a8366,{DOUBLEWITHTWODWORDINTREE(0x09000000,0x00000000)}},
+ {VT_exponent,22,0x3a8367,{DOUBLEWITHTWODWORDINTREE(0x09100000,0x00000000)}},
+ {VT_exponent,22,0x3a8368,{DOUBLEWITHTWODWORDINTREE(0x09200000,0x00000000)}},
+ {VT_exponent,22,0x3a8369,{DOUBLEWITHTWODWORDINTREE(0x09300000,0x00000000)}},
+ {VT_exponent,22,0x3a836a,{DOUBLEWITHTWODWORDINTREE(0x09400000,0x00000000)}},
+ {VT_exponent,22,0x3a836b,{DOUBLEWITHTWODWORDINTREE(0x09500000,0x00000000)}},
+ {VT_exponent,22,0x3a836c,{DOUBLEWITHTWODWORDINTREE(0x09600000,0x00000000)}},
+ {VT_exponent,22,0x3a836d,{DOUBLEWITHTWODWORDINTREE(0x09700000,0x00000000)}},
+ {VT_exponent,22,0x3a836e,{DOUBLEWITHTWODWORDINTREE(0x09800000,0x00000000)}},
+ {VT_exponent,22,0x3a836f,{DOUBLEWITHTWODWORDINTREE(0x09900000,0x00000000)}},
+ {VT_exponent,22,0x3a8370,{DOUBLEWITHTWODWORDINTREE(0x09a00000,0x00000000)}},
+ {VT_exponent,22,0x3a8371,{DOUBLEWITHTWODWORDINTREE(0x09b00000,0x00000000)}},
+ {VT_exponent,22,0x3a8372,{DOUBLEWITHTWODWORDINTREE(0x09c00000,0x00000000)}},
+ {VT_exponent,22,0x3a8373,{DOUBLEWITHTWODWORDINTREE(0x09d00000,0x00000000)}},
+ {VT_exponent,22,0x3a8374,{DOUBLEWITHTWODWORDINTREE(0x09e00000,0x00000000)}},
+ {VT_exponent,22,0x3a8375,{DOUBLEWITHTWODWORDINTREE(0x09f00000,0x00000000)}},
+ {VT_exponent,22,0x3a8376,{DOUBLEWITHTWODWORDINTREE(0x0a000000,0x00000000)}},
+ {VT_exponent,22,0x3a8377,{DOUBLEWITHTWODWORDINTREE(0x0a100000,0x00000000)}},
+ {VT_exponent,22,0x3a8378,{DOUBLEWITHTWODWORDINTREE(0x0a200000,0x00000000)}},
+ {VT_exponent,22,0x3a8379,{DOUBLEWITHTWODWORDINTREE(0x0a300000,0x00000000)}},
+ {VT_exponent,22,0x3a837a,{DOUBLEWITHTWODWORDINTREE(0x0a400000,0x00000000)}},
+ {VT_exponent,22,0x3a837b,{DOUBLEWITHTWODWORDINTREE(0x0a500000,0x00000000)}},
+ {VT_exponent,22,0x3a837c,{DOUBLEWITHTWODWORDINTREE(0x0a600000,0x00000000)}},
+ {VT_exponent,22,0x3a837d,{DOUBLEWITHTWODWORDINTREE(0x0a700000,0x00000000)}},
+ {VT_exponent,22,0x3a837e,{DOUBLEWITHTWODWORDINTREE(0x0a800000,0x00000000)}},
+ {VT_exponent,22,0x3a837f,{DOUBLEWITHTWODWORDINTREE(0x0a900000,0x00000000)}},
+ {VT_exponent,22,0x3a8380,{DOUBLEWITHTWODWORDINTREE(0x0aa00000,0x00000000)}},
+ {VT_exponent,22,0x3a8381,{DOUBLEWITHTWODWORDINTREE(0x0ab00000,0x00000000)}},
+ {VT_exponent,22,0x3a8382,{DOUBLEWITHTWODWORDINTREE(0x0ac00000,0x00000000)}},
+ {VT_exponent,22,0x3a8383,{DOUBLEWITHTWODWORDINTREE(0x0ad00000,0x00000000)}},
+ {VT_exponent,22,0x3a8384,{DOUBLEWITHTWODWORDINTREE(0x0ae00000,0x00000000)}},
+ {VT_exponent,22,0x3a8385,{DOUBLEWITHTWODWORDINTREE(0x0af00000,0x00000000)}},
+ {VT_exponent,22,0x3a8386,{DOUBLEWITHTWODWORDINTREE(0x0b000000,0x00000000)}},
+ {VT_exponent,22,0x3a8387,{DOUBLEWITHTWODWORDINTREE(0x0b100000,0x00000000)}},
+ {VT_exponent,22,0x3a8388,{DOUBLEWITHTWODWORDINTREE(0x0b200000,0x00000000)}},
+ {VT_exponent,22,0x3a8389,{DOUBLEWITHTWODWORDINTREE(0x0b300000,0x00000000)}},
+ {VT_exponent,22,0x3a838a,{DOUBLEWITHTWODWORDINTREE(0x0b400000,0x00000000)}},
+ {VT_exponent,22,0x3a838b,{DOUBLEWITHTWODWORDINTREE(0x0b500000,0x00000000)}},
+ {VT_exponent,22,0x3a838c,{DOUBLEWITHTWODWORDINTREE(0x0b600000,0x00000000)}},
+ {VT_exponent,22,0x3a838d,{DOUBLEWITHTWODWORDINTREE(0x0b700000,0x00000000)}},
+ {VT_exponent,22,0x3a838e,{DOUBLEWITHTWODWORDINTREE(0x0b800000,0x00000000)}},
+ {VT_exponent,22,0x3a838f,{DOUBLEWITHTWODWORDINTREE(0x0b900000,0x00000000)}},
+ {VT_exponent,22,0x3a8390,{DOUBLEWITHTWODWORDINTREE(0x0ba00000,0x00000000)}},
+ {VT_exponent,22,0x3a8391,{DOUBLEWITHTWODWORDINTREE(0x0bb00000,0x00000000)}},
+ {VT_exponent,22,0x3a8392,{DOUBLEWITHTWODWORDINTREE(0x0bc00000,0x00000000)}},
+ {VT_exponent,22,0x3a8393,{DOUBLEWITHTWODWORDINTREE(0x0bd00000,0x00000000)}},
+ {VT_exponent,22,0x3a8394,{DOUBLEWITHTWODWORDINTREE(0x0be00000,0x00000000)}},
+ {VT_exponent,22,0x3a8395,{DOUBLEWITHTWODWORDINTREE(0x0bf00000,0x00000000)}},
+ {VT_exponent,22,0x3a8396,{DOUBLEWITHTWODWORDINTREE(0x0c000000,0x00000000)}},
+ {VT_exponent,22,0x3a8397,{DOUBLEWITHTWODWORDINTREE(0x0c100000,0x00000000)}},
+ {VT_exponent,22,0x3a8398,{DOUBLEWITHTWODWORDINTREE(0x0c200000,0x00000000)}},
+ {VT_exponent,22,0x3a8399,{DOUBLEWITHTWODWORDINTREE(0x0c300000,0x00000000)}},
+ {VT_exponent,22,0x3a839a,{DOUBLEWITHTWODWORDINTREE(0x0c400000,0x00000000)}},
+ {VT_exponent,22,0x3a839b,{DOUBLEWITHTWODWORDINTREE(0x0c500000,0x00000000)}},
+ {VT_exponent,22,0x3a839c,{DOUBLEWITHTWODWORDINTREE(0x0c600000,0x00000000)}},
+ {VT_exponent,22,0x3a839d,{DOUBLEWITHTWODWORDINTREE(0x0c700000,0x00000000)}},
+ {VT_exponent,22,0x3a839e,{DOUBLEWITHTWODWORDINTREE(0x0c800000,0x00000000)}},
+ {VT_exponent,22,0x3a839f,{DOUBLEWITHTWODWORDINTREE(0x0c900000,0x00000000)}},
+ {VT_exponent,22,0x3a83a0,{DOUBLEWITHTWODWORDINTREE(0x0ca00000,0x00000000)}},
+ {VT_exponent,22,0x3a83a1,{DOUBLEWITHTWODWORDINTREE(0x0cb00000,0x00000000)}},
+ {VT_exponent,22,0x3a83a2,{DOUBLEWITHTWODWORDINTREE(0x0cc00000,0x00000000)}},
+ {VT_exponent,22,0x3a83a3,{DOUBLEWITHTWODWORDINTREE(0x0cd00000,0x00000000)}},
+ {VT_exponent,22,0x3a83a4,{DOUBLEWITHTWODWORDINTREE(0x0ce00000,0x00000000)}},
+ {VT_exponent,22,0x3a83a5,{DOUBLEWITHTWODWORDINTREE(0x0cf00000,0x00000000)}},
+ {VT_exponent,22,0x3a83a6,{DOUBLEWITHTWODWORDINTREE(0x0d000000,0x00000000)}},
+ {VT_exponent,22,0x3a83a7,{DOUBLEWITHTWODWORDINTREE(0x0d100000,0x00000000)}},
+ {VT_exponent,22,0x3a83a8,{DOUBLEWITHTWODWORDINTREE(0x0d200000,0x00000000)}},
+ {VT_exponent,22,0x3a83a9,{DOUBLEWITHTWODWORDINTREE(0x0d300000,0x00000000)}},
+ {VT_exponent,22,0x3a83aa,{DOUBLEWITHTWODWORDINTREE(0x0d400000,0x00000000)}},
+ {VT_exponent,22,0x3a83ab,{DOUBLEWITHTWODWORDINTREE(0x0d500000,0x00000000)}},
+ {VT_exponent,22,0x3a83ac,{DOUBLEWITHTWODWORDINTREE(0x0d600000,0x00000000)}},
+ {VT_exponent,22,0x3a83ad,{DOUBLEWITHTWODWORDINTREE(0x0d700000,0x00000000)}},
+ {VT_exponent,22,0x3a83ae,{DOUBLEWITHTWODWORDINTREE(0x0d800000,0x00000000)}},
+ {VT_exponent,22,0x3a83af,{DOUBLEWITHTWODWORDINTREE(0x0d900000,0x00000000)}},
+ {VT_exponent,22,0x3a83b0,{DOUBLEWITHTWODWORDINTREE(0x0da00000,0x00000000)}},
+ {VT_exponent,22,0x3a83b1,{DOUBLEWITHTWODWORDINTREE(0x0db00000,0x00000000)}},
+ {VT_exponent,22,0x3a83b2,{DOUBLEWITHTWODWORDINTREE(0x0dc00000,0x00000000)}},
+ {VT_exponent,22,0x3a83b3,{DOUBLEWITHTWODWORDINTREE(0x0dd00000,0x00000000)}},
+ {VT_exponent,22,0x3a83b4,{DOUBLEWITHTWODWORDINTREE(0x0de00000,0x00000000)}},
+ {VT_exponent,22,0x3a83b5,{DOUBLEWITHTWODWORDINTREE(0x0df00000,0x00000000)}},
+ {VT_exponent,22,0x3a83b6,{DOUBLEWITHTWODWORDINTREE(0x0e000000,0x00000000)}},
+ {VT_exponent,22,0x3a83b7,{DOUBLEWITHTWODWORDINTREE(0x0e100000,0x00000000)}},
+ {VT_exponent,22,0x3a83b8,{DOUBLEWITHTWODWORDINTREE(0x0e200000,0x00000000)}},
+ {VT_exponent,22,0x3a83b9,{DOUBLEWITHTWODWORDINTREE(0x0e300000,0x00000000)}},
+ {VT_exponent,22,0x3a83ba,{DOUBLEWITHTWODWORDINTREE(0x0e400000,0x00000000)}},
+ {VT_exponent,22,0x3a83bb,{DOUBLEWITHTWODWORDINTREE(0x0e500000,0x00000000)}},
+ {VT_exponent,22,0x3a83bc,{DOUBLEWITHTWODWORDINTREE(0x0e600000,0x00000000)}},
+ {VT_exponent,22,0x3a83bd,{DOUBLEWITHTWODWORDINTREE(0x0e700000,0x00000000)}},
+ {VT_exponent,22,0x3a83be,{DOUBLEWITHTWODWORDINTREE(0x0e800000,0x00000000)}},
+ {VT_exponent,22,0x3a83bf,{DOUBLEWITHTWODWORDINTREE(0x0e900000,0x00000000)}},
+ {VT_exponent,22,0x3a83c0,{DOUBLEWITHTWODWORDINTREE(0x0ea00000,0x00000000)}},
+ {VT_exponent,22,0x3a83c1,{DOUBLEWITHTWODWORDINTREE(0x0eb00000,0x00000000)}},
+ {VT_exponent,22,0x3a83c2,{DOUBLEWITHTWODWORDINTREE(0x0ec00000,0x00000000)}},
+ {VT_exponent,22,0x3a83c3,{DOUBLEWITHTWODWORDINTREE(0x0ed00000,0x00000000)}},
+ {VT_exponent,22,0x3a83c4,{DOUBLEWITHTWODWORDINTREE(0x0ee00000,0x00000000)}},
+ {VT_exponent,22,0x3a83c5,{DOUBLEWITHTWODWORDINTREE(0x0ef00000,0x00000000)}},
+ {VT_exponent,22,0x3a83c6,{DOUBLEWITHTWODWORDINTREE(0x0f000000,0x00000000)}},
+ {VT_exponent,22,0x3a83c7,{DOUBLEWITHTWODWORDINTREE(0x0f100000,0x00000000)}},
+ {VT_exponent,22,0x3a83c8,{DOUBLEWITHTWODWORDINTREE(0x0f200000,0x00000000)}},
+ {VT_exponent,22,0x3a83c9,{DOUBLEWITHTWODWORDINTREE(0x0f300000,0x00000000)}},
+ {VT_exponent,22,0x3a83ca,{DOUBLEWITHTWODWORDINTREE(0x0f400000,0x00000000)}},
+ {VT_exponent,22,0x3a83cb,{DOUBLEWITHTWODWORDINTREE(0x0f500000,0x00000000)}},
+ {VT_exponent,22,0x3a83cc,{DOUBLEWITHTWODWORDINTREE(0x0f600000,0x00000000)}},
+ {VT_exponent,22,0x3a83cd,{DOUBLEWITHTWODWORDINTREE(0x0f700000,0x00000000)}},
+ {VT_exponent,22,0x3a83ce,{DOUBLEWITHTWODWORDINTREE(0x0f800000,0x00000000)}},
+ {VT_exponent,22,0x3a83cf,{DOUBLEWITHTWODWORDINTREE(0x0f900000,0x00000000)}},
+ {VT_exponent,22,0x3a83d0,{DOUBLEWITHTWODWORDINTREE(0x0fa00000,0x00000000)}},
+ {VT_exponent,22,0x3a83d1,{DOUBLEWITHTWODWORDINTREE(0x0fb00000,0x00000000)}},
+ {VT_exponent,22,0x3a83d2,{DOUBLEWITHTWODWORDINTREE(0x0fc00000,0x00000000)}},
+ {VT_exponent,22,0x3a83d3,{DOUBLEWITHTWODWORDINTREE(0x0fd00000,0x00000000)}},
+ {VT_exponent,22,0x3a83d4,{DOUBLEWITHTWODWORDINTREE(0x0fe00000,0x00000000)}},
+ {VT_exponent,22,0x3a83d5,{DOUBLEWITHTWODWORDINTREE(0x0ff00000,0x00000000)}},
+ {VT_exponent,22,0x3a83d6,{DOUBLEWITHTWODWORDINTREE(0x10000000,0x00000000)}},
+ {VT_exponent,22,0x3a83d7,{DOUBLEWITHTWODWORDINTREE(0x10100000,0x00000000)}},
+ {VT_exponent,22,0x3a83d8,{DOUBLEWITHTWODWORDINTREE(0x10200000,0x00000000)}},
+ {VT_exponent,22,0x3a83d9,{DOUBLEWITHTWODWORDINTREE(0x10300000,0x00000000)}},
+ {VT_exponent,22,0x3a83da,{DOUBLEWITHTWODWORDINTREE(0x10400000,0x00000000)}},
+ {VT_exponent,22,0x3a83db,{DOUBLEWITHTWODWORDINTREE(0x10500000,0x00000000)}},
+ {VT_exponent,22,0x3a83dc,{DOUBLEWITHTWODWORDINTREE(0x10600000,0x00000000)}},
+ {VT_exponent,22,0x3a83dd,{DOUBLEWITHTWODWORDINTREE(0x10700000,0x00000000)}},
+ {VT_exponent,22,0x3a83de,{DOUBLEWITHTWODWORDINTREE(0x10800000,0x00000000)}},
+ {VT_exponent,22,0x3a83df,{DOUBLEWITHTWODWORDINTREE(0x10900000,0x00000000)}},
+ {VT_exponent,22,0x3a83e0,{DOUBLEWITHTWODWORDINTREE(0x10a00000,0x00000000)}},
+ {VT_exponent,22,0x3a83e1,{DOUBLEWITHTWODWORDINTREE(0x10b00000,0x00000000)}},
+ {VT_exponent,22,0x3a83e2,{DOUBLEWITHTWODWORDINTREE(0x10c00000,0x00000000)}},
+ {VT_exponent,22,0x3a83e3,{DOUBLEWITHTWODWORDINTREE(0x10d00000,0x00000000)}},
+ {VT_exponent,22,0x3a83e4,{DOUBLEWITHTWODWORDINTREE(0x10e00000,0x00000000)}},
+ {VT_exponent,22,0x3a83e5,{DOUBLEWITHTWODWORDINTREE(0x10f00000,0x00000000)}},
+ {VT_exponent,22,0x3a83e6,{DOUBLEWITHTWODWORDINTREE(0x11000000,0x00000000)}},
+ {VT_exponent,22,0x3a83e7,{DOUBLEWITHTWODWORDINTREE(0x11100000,0x00000000)}},
+ {VT_exponent,22,0x3a83e8,{DOUBLEWITHTWODWORDINTREE(0x11200000,0x00000000)}},
+ {VT_exponent,22,0x3a83e9,{DOUBLEWITHTWODWORDINTREE(0x11300000,0x00000000)}},
+ {VT_exponent,22,0x3a83ea,{DOUBLEWITHTWODWORDINTREE(0x11400000,0x00000000)}},
+ {VT_exponent,22,0x3a83eb,{DOUBLEWITHTWODWORDINTREE(0x11500000,0x00000000)}},
+ {VT_exponent,22,0x3a83ec,{DOUBLEWITHTWODWORDINTREE(0x11600000,0x00000000)}},
+ {VT_exponent,22,0x3a83ed,{DOUBLEWITHTWODWORDINTREE(0x11700000,0x00000000)}},
+ {VT_exponent,22,0x3a83ee,{DOUBLEWITHTWODWORDINTREE(0x11800000,0x00000000)}},
+ {VT_exponent,22,0x3a83ef,{DOUBLEWITHTWODWORDINTREE(0x11900000,0x00000000)}},
+ {VT_exponent,22,0x3a83f0,{DOUBLEWITHTWODWORDINTREE(0x11a00000,0x00000000)}},
+ {VT_exponent,22,0x3a83f1,{DOUBLEWITHTWODWORDINTREE(0x11b00000,0x00000000)}},
+ {VT_exponent,22,0x3a83f2,{DOUBLEWITHTWODWORDINTREE(0x11c00000,0x00000000)}},
+ {VT_exponent,22,0x3a83f3,{DOUBLEWITHTWODWORDINTREE(0x11d00000,0x00000000)}},
+ {VT_exponent,22,0x3a83f4,{DOUBLEWITHTWODWORDINTREE(0x11e00000,0x00000000)}},
+ {VT_exponent,22,0x3a83f5,{DOUBLEWITHTWODWORDINTREE(0x11f00000,0x00000000)}},
+ {VT_exponent,22,0x3a83f6,{DOUBLEWITHTWODWORDINTREE(0x12000000,0x00000000)}},
+ {VT_exponent,22,0x3a83f7,{DOUBLEWITHTWODWORDINTREE(0x12100000,0x00000000)}},
+ {VT_exponent,22,0x3a83f8,{DOUBLEWITHTWODWORDINTREE(0x12200000,0x00000000)}},
+ {VT_exponent,22,0x3a83f9,{DOUBLEWITHTWODWORDINTREE(0x12300000,0x00000000)}},
+ {VT_exponent,22,0x3a83fa,{DOUBLEWITHTWODWORDINTREE(0x12400000,0x00000000)}},
+ {VT_exponent,22,0x3a83fb,{DOUBLEWITHTWODWORDINTREE(0x12500000,0x00000000)}},
+ {VT_exponent,22,0x3a83fc,{DOUBLEWITHTWODWORDINTREE(0x12600000,0x00000000)}},
+ {VT_exponent,22,0x3a83fd,{DOUBLEWITHTWODWORDINTREE(0x12700000,0x00000000)}},
+ {VT_exponent,22,0x3a83fe,{DOUBLEWITHTWODWORDINTREE(0x12800000,0x00000000)}},
+ {VT_exponent,22,0x3a83ff,{DOUBLEWITHTWODWORDINTREE(0x12900000,0x00000000)}},
+ {VT_exponent,22,0x3a8400,{DOUBLEWITHTWODWORDINTREE(0x12a00000,0x00000000)}},
+ {VT_exponent,22,0x3a8401,{DOUBLEWITHTWODWORDINTREE(0x12b00000,0x00000000)}},
+ {VT_exponent,22,0x3a8402,{DOUBLEWITHTWODWORDINTREE(0x12c00000,0x00000000)}},
+ {VT_exponent,22,0x3a8403,{DOUBLEWITHTWODWORDINTREE(0x12d00000,0x00000000)}},
+ {VT_exponent,22,0x3a8404,{DOUBLEWITHTWODWORDINTREE(0x12e00000,0x00000000)}},
+ {VT_exponent,22,0x3a8405,{DOUBLEWITHTWODWORDINTREE(0x12f00000,0x00000000)}},
+ {VT_exponent,22,0x3a8406,{DOUBLEWITHTWODWORDINTREE(0x13000000,0x00000000)}},
+ {VT_exponent,22,0x3a8407,{DOUBLEWITHTWODWORDINTREE(0x13100000,0x00000000)}},
+ {VT_exponent,22,0x3a8408,{DOUBLEWITHTWODWORDINTREE(0x13200000,0x00000000)}},
+ {VT_exponent,22,0x3a8409,{DOUBLEWITHTWODWORDINTREE(0x13300000,0x00000000)}},
+ {VT_exponent,22,0x3a840a,{DOUBLEWITHTWODWORDINTREE(0x13400000,0x00000000)}},
+ {VT_exponent,22,0x3a840b,{DOUBLEWITHTWODWORDINTREE(0x13500000,0x00000000)}},
+ {VT_exponent,22,0x3a840c,{DOUBLEWITHTWODWORDINTREE(0x13600000,0x00000000)}},
+ {VT_exponent,22,0x3a840d,{DOUBLEWITHTWODWORDINTREE(0x13700000,0x00000000)}},
+ {VT_exponent,22,0x3a840e,{DOUBLEWITHTWODWORDINTREE(0x13800000,0x00000000)}},
+ {VT_exponent,22,0x3a840f,{DOUBLEWITHTWODWORDINTREE(0x13900000,0x00000000)}},
+ {VT_exponent,22,0x3a8410,{DOUBLEWITHTWODWORDINTREE(0x13a00000,0x00000000)}},
+ {VT_exponent,22,0x3a8411,{DOUBLEWITHTWODWORDINTREE(0x13b00000,0x00000000)}},
+ {VT_exponent,22,0x3a8412,{DOUBLEWITHTWODWORDINTREE(0x13c00000,0x00000000)}},
+ {VT_exponent,22,0x3a8413,{DOUBLEWITHTWODWORDINTREE(0x13d00000,0x00000000)}},
+ {VT_exponent,22,0x3a8414,{DOUBLEWITHTWODWORDINTREE(0x13e00000,0x00000000)}},
+ {VT_exponent,22,0x3a8415,{DOUBLEWITHTWODWORDINTREE(0x13f00000,0x00000000)}},
+ {VT_exponent,22,0x3a8416,{DOUBLEWITHTWODWORDINTREE(0x14000000,0x00000000)}},
+ {VT_exponent,22,0x3a8417,{DOUBLEWITHTWODWORDINTREE(0x14100000,0x00000000)}},
+ {VT_exponent,22,0x3a8418,{DOUBLEWITHTWODWORDINTREE(0x14200000,0x00000000)}},
+ {VT_exponent,22,0x3a8419,{DOUBLEWITHTWODWORDINTREE(0x14300000,0x00000000)}},
+ {VT_exponent,22,0x3a841a,{DOUBLEWITHTWODWORDINTREE(0x14400000,0x00000000)}},
+ {VT_exponent,22,0x3a841b,{DOUBLEWITHTWODWORDINTREE(0x14500000,0x00000000)}},
+ {VT_exponent,22,0x3a841c,{DOUBLEWITHTWODWORDINTREE(0x14600000,0x00000000)}},
+ {VT_exponent,22,0x3a841d,{DOUBLEWITHTWODWORDINTREE(0x14700000,0x00000000)}},
+ {VT_exponent,22,0x3a841e,{DOUBLEWITHTWODWORDINTREE(0x14800000,0x00000000)}},
+ {VT_exponent,22,0x3a841f,{DOUBLEWITHTWODWORDINTREE(0x14900000,0x00000000)}},
+ {VT_exponent,22,0x3a8420,{DOUBLEWITHTWODWORDINTREE(0x14a00000,0x00000000)}},
+ {VT_exponent,22,0x3a8421,{DOUBLEWITHTWODWORDINTREE(0x14b00000,0x00000000)}},
+ {VT_exponent,22,0x3a8422,{DOUBLEWITHTWODWORDINTREE(0x14c00000,0x00000000)}},
+ {VT_exponent,22,0x3a8423,{DOUBLEWITHTWODWORDINTREE(0x14d00000,0x00000000)}},
+ {VT_exponent,22,0x3a8424,{DOUBLEWITHTWODWORDINTREE(0x14e00000,0x00000000)}},
+ {VT_exponent,22,0x3a8425,{DOUBLEWITHTWODWORDINTREE(0x14f00000,0x00000000)}},
+ {VT_exponent,22,0x3a8426,{DOUBLEWITHTWODWORDINTREE(0x15000000,0x00000000)}},
+ {VT_exponent,22,0x3a8427,{DOUBLEWITHTWODWORDINTREE(0x15100000,0x00000000)}},
+ {VT_exponent,22,0x3a8428,{DOUBLEWITHTWODWORDINTREE(0x15200000,0x00000000)}},
+ {VT_exponent,22,0x3a8429,{DOUBLEWITHTWODWORDINTREE(0x15300000,0x00000000)}},
+ {VT_exponent,22,0x3a842a,{DOUBLEWITHTWODWORDINTREE(0x15400000,0x00000000)}},
+ {VT_exponent,22,0x3a842b,{DOUBLEWITHTWODWORDINTREE(0x15500000,0x00000000)}},
+ {VT_exponent,22,0x3a842c,{DOUBLEWITHTWODWORDINTREE(0x15600000,0x00000000)}},
+ {VT_exponent,22,0x3a842d,{DOUBLEWITHTWODWORDINTREE(0x15700000,0x00000000)}},
+ {VT_exponent,22,0x3a842e,{DOUBLEWITHTWODWORDINTREE(0x15800000,0x00000000)}},
+ {VT_exponent,22,0x3a842f,{DOUBLEWITHTWODWORDINTREE(0x15900000,0x00000000)}},
+ {VT_exponent,22,0x3a8430,{DOUBLEWITHTWODWORDINTREE(0x15a00000,0x00000000)}},
+ {VT_exponent,22,0x3a8431,{DOUBLEWITHTWODWORDINTREE(0x15b00000,0x00000000)}},
+ {VT_exponent,22,0x3a8432,{DOUBLEWITHTWODWORDINTREE(0x15c00000,0x00000000)}},
+ {VT_exponent,22,0x3a8433,{DOUBLEWITHTWODWORDINTREE(0x15d00000,0x00000000)}},
+ {VT_exponent,22,0x3a8434,{DOUBLEWITHTWODWORDINTREE(0x15e00000,0x00000000)}},
+ {VT_exponent,22,0x3a8435,{DOUBLEWITHTWODWORDINTREE(0x15f00000,0x00000000)}},
+ {VT_exponent,22,0x3a8436,{DOUBLEWITHTWODWORDINTREE(0x16000000,0x00000000)}},
+ {VT_exponent,22,0x3a8437,{DOUBLEWITHTWODWORDINTREE(0x16100000,0x00000000)}},
+ {VT_exponent,22,0x3a8438,{DOUBLEWITHTWODWORDINTREE(0x16200000,0x00000000)}},
+ {VT_exponent,22,0x3a8439,{DOUBLEWITHTWODWORDINTREE(0x16300000,0x00000000)}},
+ {VT_exponent,22,0x3a843a,{DOUBLEWITHTWODWORDINTREE(0x16400000,0x00000000)}},
+ {VT_exponent,22,0x3a843b,{DOUBLEWITHTWODWORDINTREE(0x16500000,0x00000000)}},
+ {VT_exponent,22,0x3a843c,{DOUBLEWITHTWODWORDINTREE(0x16600000,0x00000000)}},
+ {VT_exponent,22,0x3a843d,{DOUBLEWITHTWODWORDINTREE(0x16700000,0x00000000)}},
+ {VT_exponent,22,0x3a843e,{DOUBLEWITHTWODWORDINTREE(0x16800000,0x00000000)}},
+ {VT_exponent,22,0x3a843f,{DOUBLEWITHTWODWORDINTREE(0x16900000,0x00000000)}},
+ {VT_exponent,22,0x3a8440,{DOUBLEWITHTWODWORDINTREE(0x16a00000,0x00000000)}},
+ {VT_exponent,22,0x3a8441,{DOUBLEWITHTWODWORDINTREE(0x16b00000,0x00000000)}},
+ {VT_exponent,22,0x3a8442,{DOUBLEWITHTWODWORDINTREE(0x16c00000,0x00000000)}},
+ {VT_exponent,22,0x3a8443,{DOUBLEWITHTWODWORDINTREE(0x16d00000,0x00000000)}},
+ {VT_exponent,22,0x3a8444,{DOUBLEWITHTWODWORDINTREE(0x16e00000,0x00000000)}},
+ {VT_exponent,22,0x3a8445,{DOUBLEWITHTWODWORDINTREE(0x16f00000,0x00000000)}},
+ {VT_exponent,22,0x3a8446,{DOUBLEWITHTWODWORDINTREE(0x17000000,0x00000000)}},
+ {VT_exponent,22,0x3a8447,{DOUBLEWITHTWODWORDINTREE(0x17100000,0x00000000)}},
+ {VT_exponent,22,0x3a8448,{DOUBLEWITHTWODWORDINTREE(0x17200000,0x00000000)}},
+ {VT_exponent,22,0x3a8449,{DOUBLEWITHTWODWORDINTREE(0x17300000,0x00000000)}},
+ {VT_exponent,22,0x3a844a,{DOUBLEWITHTWODWORDINTREE(0x17400000,0x00000000)}},
+ {VT_exponent,22,0x3a844b,{DOUBLEWITHTWODWORDINTREE(0x17500000,0x00000000)}},
+ {VT_exponent,22,0x3a844c,{DOUBLEWITHTWODWORDINTREE(0x17600000,0x00000000)}},
+ {VT_exponent,22,0x3a844d,{DOUBLEWITHTWODWORDINTREE(0x17700000,0x00000000)}},
+ {VT_exponent,22,0x3a844e,{DOUBLEWITHTWODWORDINTREE(0x17800000,0x00000000)}},
+ {VT_exponent,22,0x3a844f,{DOUBLEWITHTWODWORDINTREE(0x17900000,0x00000000)}},
+ {VT_exponent,22,0x3a8450,{DOUBLEWITHTWODWORDINTREE(0x17a00000,0x00000000)}},
+ {VT_exponent,22,0x3a8451,{DOUBLEWITHTWODWORDINTREE(0x17b00000,0x00000000)}},
+ {VT_exponent,22,0x3a8452,{DOUBLEWITHTWODWORDINTREE(0x17c00000,0x00000000)}},
+ {VT_exponent,22,0x3a8453,{DOUBLEWITHTWODWORDINTREE(0x17d00000,0x00000000)}},
+ {VT_exponent,22,0x3a8454,{DOUBLEWITHTWODWORDINTREE(0x17e00000,0x00000000)}},
+ {VT_exponent,22,0x3a8455,{DOUBLEWITHTWODWORDINTREE(0x17f00000,0x00000000)}},
+ {VT_exponent,22,0x3a8456,{DOUBLEWITHTWODWORDINTREE(0x18000000,0x00000000)}},
+ {VT_exponent,22,0x3a8457,{DOUBLEWITHTWODWORDINTREE(0x18100000,0x00000000)}},
+ {VT_exponent,22,0x3a8458,{DOUBLEWITHTWODWORDINTREE(0x18200000,0x00000000)}},
+ {VT_exponent,22,0x3a8459,{DOUBLEWITHTWODWORDINTREE(0x18300000,0x00000000)}},
+ {VT_exponent,22,0x3a845a,{DOUBLEWITHTWODWORDINTREE(0x18400000,0x00000000)}},
+ {VT_exponent,22,0x3a845b,{DOUBLEWITHTWODWORDINTREE(0x18500000,0x00000000)}},
+ {VT_exponent,22,0x3a845c,{DOUBLEWITHTWODWORDINTREE(0x18600000,0x00000000)}},
+ {VT_exponent,22,0x3a845d,{DOUBLEWITHTWODWORDINTREE(0x18700000,0x00000000)}},
+ {VT_exponent,22,0x3a845e,{DOUBLEWITHTWODWORDINTREE(0x18800000,0x00000000)}},
+ {VT_exponent,22,0x3a845f,{DOUBLEWITHTWODWORDINTREE(0x18900000,0x00000000)}},
+ {VT_exponent,22,0x3a8460,{DOUBLEWITHTWODWORDINTREE(0x18a00000,0x00000000)}},
+ {VT_exponent,22,0x3a8461,{DOUBLEWITHTWODWORDINTREE(0x18b00000,0x00000000)}},
+ {VT_exponent,22,0x3a8462,{DOUBLEWITHTWODWORDINTREE(0x18c00000,0x00000000)}},
+ {VT_exponent,22,0x3a8463,{DOUBLEWITHTWODWORDINTREE(0x18d00000,0x00000000)}},
+ {VT_exponent,22,0x3a8464,{DOUBLEWITHTWODWORDINTREE(0x18e00000,0x00000000)}},
+ {VT_exponent,22,0x3a8465,{DOUBLEWITHTWODWORDINTREE(0x18f00000,0x00000000)}},
+ {VT_exponent,22,0x3a8466,{DOUBLEWITHTWODWORDINTREE(0x19000000,0x00000000)}},
+ {VT_exponent,22,0x3a8467,{DOUBLEWITHTWODWORDINTREE(0x19100000,0x00000000)}},
+ {VT_exponent,22,0x3a8468,{DOUBLEWITHTWODWORDINTREE(0x19200000,0x00000000)}},
+ {VT_exponent,22,0x3a8469,{DOUBLEWITHTWODWORDINTREE(0x19300000,0x00000000)}},
+ {VT_exponent,22,0x3a846a,{DOUBLEWITHTWODWORDINTREE(0x19400000,0x00000000)}},
+ {VT_exponent,22,0x3a846b,{DOUBLEWITHTWODWORDINTREE(0x19500000,0x00000000)}},
+ {VT_exponent,22,0x3a846c,{DOUBLEWITHTWODWORDINTREE(0x19600000,0x00000000)}},
+ {VT_exponent,22,0x3a846d,{DOUBLEWITHTWODWORDINTREE(0x19700000,0x00000000)}},
+ {VT_exponent,22,0x3a846e,{DOUBLEWITHTWODWORDINTREE(0x19800000,0x00000000)}},
+ {VT_exponent,22,0x3a846f,{DOUBLEWITHTWODWORDINTREE(0x19900000,0x00000000)}},
+ {VT_exponent,22,0x3a8470,{DOUBLEWITHTWODWORDINTREE(0x19a00000,0x00000000)}},
+ {VT_exponent,22,0x3a8471,{DOUBLEWITHTWODWORDINTREE(0x19b00000,0x00000000)}},
+ {VT_exponent,22,0x3a8472,{DOUBLEWITHTWODWORDINTREE(0x19c00000,0x00000000)}},
+ {VT_exponent,22,0x3a8473,{DOUBLEWITHTWODWORDINTREE(0x19d00000,0x00000000)}},
+ {VT_exponent,22,0x3a8474,{DOUBLEWITHTWODWORDINTREE(0x19e00000,0x00000000)}},
+ {VT_exponent,22,0x3a8475,{DOUBLEWITHTWODWORDINTREE(0x19f00000,0x00000000)}},
+ {VT_exponent,22,0x3a8476,{DOUBLEWITHTWODWORDINTREE(0x1a000000,0x00000000)}},
+ {VT_exponent,22,0x3a8477,{DOUBLEWITHTWODWORDINTREE(0x1a100000,0x00000000)}},
+ {VT_exponent,22,0x3a8478,{DOUBLEWITHTWODWORDINTREE(0x1a200000,0x00000000)}},
+ {VT_exponent,22,0x3a8479,{DOUBLEWITHTWODWORDINTREE(0x1a300000,0x00000000)}},
+ {VT_exponent,22,0x3a847a,{DOUBLEWITHTWODWORDINTREE(0x1a400000,0x00000000)}},
+ {VT_exponent,22,0x3a847b,{DOUBLEWITHTWODWORDINTREE(0x1a500000,0x00000000)}},
+ {VT_exponent,22,0x3a847c,{DOUBLEWITHTWODWORDINTREE(0x1a600000,0x00000000)}},
+ {VT_exponent,22,0x3a847d,{DOUBLEWITHTWODWORDINTREE(0x1a700000,0x00000000)}},
+ {VT_exponent,22,0x3a847e,{DOUBLEWITHTWODWORDINTREE(0x1a800000,0x00000000)}},
+ {VT_exponent,22,0x3a847f,{DOUBLEWITHTWODWORDINTREE(0x1a900000,0x00000000)}},
+ {VT_exponent,22,0x3a8480,{DOUBLEWITHTWODWORDINTREE(0x1aa00000,0x00000000)}},
+ {VT_exponent,22,0x3a8481,{DOUBLEWITHTWODWORDINTREE(0x1ab00000,0x00000000)}},
+ {VT_exponent,22,0x3a8482,{DOUBLEWITHTWODWORDINTREE(0x1ac00000,0x00000000)}},
+ {VT_exponent,22,0x3a8483,{DOUBLEWITHTWODWORDINTREE(0x1ad00000,0x00000000)}},
+ {VT_exponent,22,0x3a8484,{DOUBLEWITHTWODWORDINTREE(0x1ae00000,0x00000000)}},
+ {VT_exponent,22,0x3a8485,{DOUBLEWITHTWODWORDINTREE(0x1af00000,0x00000000)}},
+ {VT_exponent,22,0x3a8486,{DOUBLEWITHTWODWORDINTREE(0x1b000000,0x00000000)}},
+ {VT_exponent,22,0x3a8487,{DOUBLEWITHTWODWORDINTREE(0x1b100000,0x00000000)}},
+ {VT_exponent,22,0x3a8488,{DOUBLEWITHTWODWORDINTREE(0x1b200000,0x00000000)}},
+ {VT_exponent,22,0x3a8489,{DOUBLEWITHTWODWORDINTREE(0x1b300000,0x00000000)}},
+ {VT_exponent,22,0x3a848a,{DOUBLEWITHTWODWORDINTREE(0x1b400000,0x00000000)}},
+ {VT_exponent,22,0x3a848b,{DOUBLEWITHTWODWORDINTREE(0x1b500000,0x00000000)}},
+ {VT_exponent,22,0x3a848c,{DOUBLEWITHTWODWORDINTREE(0x1b600000,0x00000000)}},
+ {VT_exponent,22,0x3a848d,{DOUBLEWITHTWODWORDINTREE(0x1b700000,0x00000000)}},
+ {VT_exponent,22,0x3a848e,{DOUBLEWITHTWODWORDINTREE(0x1b800000,0x00000000)}},
+ {VT_exponent,22,0x3a848f,{DOUBLEWITHTWODWORDINTREE(0x1b900000,0x00000000)}},
+ {VT_exponent,22,0x3a8490,{DOUBLEWITHTWODWORDINTREE(0x1ba00000,0x00000000)}},
+ {VT_exponent,22,0x3a8491,{DOUBLEWITHTWODWORDINTREE(0x1bb00000,0x00000000)}},
+ {VT_exponent,22,0x3a8492,{DOUBLEWITHTWODWORDINTREE(0x1bc00000,0x00000000)}},
+ {VT_exponent,22,0x3a8493,{DOUBLEWITHTWODWORDINTREE(0x1bd00000,0x00000000)}},
+ {VT_exponent,22,0x3a8494,{DOUBLEWITHTWODWORDINTREE(0x1be00000,0x00000000)}},
+ {VT_exponent,22,0x3a8495,{DOUBLEWITHTWODWORDINTREE(0x1bf00000,0x00000000)}},
+ {VT_exponent,22,0x3a8496,{DOUBLEWITHTWODWORDINTREE(0x1c000000,0x00000000)}},
+ {VT_exponent,22,0x3a8497,{DOUBLEWITHTWODWORDINTREE(0x1c100000,0x00000000)}},
+ {VT_exponent,22,0x3a8498,{DOUBLEWITHTWODWORDINTREE(0x1c200000,0x00000000)}},
+ {VT_exponent,22,0x3a8499,{DOUBLEWITHTWODWORDINTREE(0x1c300000,0x00000000)}},
+ {VT_exponent,22,0x3a849a,{DOUBLEWITHTWODWORDINTREE(0x1c400000,0x00000000)}},
+ {VT_exponent,22,0x3a849b,{DOUBLEWITHTWODWORDINTREE(0x1c500000,0x00000000)}},
+ {VT_exponent,22,0x3a849c,{DOUBLEWITHTWODWORDINTREE(0x1c600000,0x00000000)}},
+ {VT_exponent,22,0x3a849d,{DOUBLEWITHTWODWORDINTREE(0x1c700000,0x00000000)}},
+ {VT_exponent,22,0x3a849e,{DOUBLEWITHTWODWORDINTREE(0x1c800000,0x00000000)}},
+ {VT_exponent,22,0x3a849f,{DOUBLEWITHTWODWORDINTREE(0x1c900000,0x00000000)}},
+ {VT_exponent,22,0x3a84a0,{DOUBLEWITHTWODWORDINTREE(0x1ca00000,0x00000000)}},
+ {VT_exponent,22,0x3a84a1,{DOUBLEWITHTWODWORDINTREE(0x1cb00000,0x00000000)}},
+ {VT_exponent,22,0x3a84a2,{DOUBLEWITHTWODWORDINTREE(0x1cc00000,0x00000000)}},
+ {VT_exponent,22,0x3a84a3,{DOUBLEWITHTWODWORDINTREE(0x1cd00000,0x00000000)}},
+ {VT_exponent,22,0x3a84a4,{DOUBLEWITHTWODWORDINTREE(0x1ce00000,0x00000000)}},
+ {VT_exponent,22,0x3a84a5,{DOUBLEWITHTWODWORDINTREE(0x1cf00000,0x00000000)}},
+ {VT_exponent,22,0x3a84a6,{DOUBLEWITHTWODWORDINTREE(0x1d000000,0x00000000)}},
+ {VT_exponent,22,0x3a84a7,{DOUBLEWITHTWODWORDINTREE(0x1d100000,0x00000000)}},
+ {VT_exponent,22,0x3a84a8,{DOUBLEWITHTWODWORDINTREE(0x1d200000,0x00000000)}},
+ {VT_exponent,22,0x3a84a9,{DOUBLEWITHTWODWORDINTREE(0x1d300000,0x00000000)}},
+ {VT_exponent,22,0x3a84aa,{DOUBLEWITHTWODWORDINTREE(0x1d400000,0x00000000)}},
+ {VT_exponent,22,0x3a84ab,{DOUBLEWITHTWODWORDINTREE(0x1d500000,0x00000000)}},
+ {VT_exponent,22,0x3a84ac,{DOUBLEWITHTWODWORDINTREE(0x1d600000,0x00000000)}},
+ {VT_exponent,22,0x3a84ad,{DOUBLEWITHTWODWORDINTREE(0x1d700000,0x00000000)}},
+ {VT_exponent,22,0x3a84ae,{DOUBLEWITHTWODWORDINTREE(0x1d800000,0x00000000)}},
+ {VT_exponent,22,0x3a84af,{DOUBLEWITHTWODWORDINTREE(0x1d900000,0x00000000)}},
+ {VT_exponent,22,0x3a84b0,{DOUBLEWITHTWODWORDINTREE(0x1da00000,0x00000000)}},
+ {VT_exponent,22,0x3a84b1,{DOUBLEWITHTWODWORDINTREE(0x1db00000,0x00000000)}},
+ {VT_exponent,22,0x3a84b2,{DOUBLEWITHTWODWORDINTREE(0x1dc00000,0x00000000)}},
+ {VT_exponent,22,0x3a84b3,{DOUBLEWITHTWODWORDINTREE(0x1dd00000,0x00000000)}},
+ {VT_exponent,22,0x3a84b4,{DOUBLEWITHTWODWORDINTREE(0x1de00000,0x00000000)}},
+ {VT_exponent,22,0x3a84b5,{DOUBLEWITHTWODWORDINTREE(0x1df00000,0x00000000)}},
+ {VT_exponent,22,0x3a84b6,{DOUBLEWITHTWODWORDINTREE(0x1e000000,0x00000000)}},
+ {VT_exponent,22,0x3a84b7,{DOUBLEWITHTWODWORDINTREE(0x1e100000,0x00000000)}},
+ {VT_exponent,22,0x3a84b8,{DOUBLEWITHTWODWORDINTREE(0x1e200000,0x00000000)}},
+ {VT_exponent,22,0x3a84b9,{DOUBLEWITHTWODWORDINTREE(0x1e300000,0x00000000)}},
+ {VT_exponent,22,0x3a84ba,{DOUBLEWITHTWODWORDINTREE(0x1e400000,0x00000000)}},
+ {VT_exponent,22,0x3a84bb,{DOUBLEWITHTWODWORDINTREE(0x1e500000,0x00000000)}},
+ {VT_exponent,22,0x3a84bc,{DOUBLEWITHTWODWORDINTREE(0x1e600000,0x00000000)}},
+ {VT_exponent,22,0x3a84bd,{DOUBLEWITHTWODWORDINTREE(0x1e700000,0x00000000)}},
+ {VT_exponent,22,0x3a84be,{DOUBLEWITHTWODWORDINTREE(0x1e800000,0x00000000)}},
+ {VT_exponent,22,0x3a84bf,{DOUBLEWITHTWODWORDINTREE(0x1e900000,0x00000000)}},
+ {VT_exponent,22,0x3a84c0,{DOUBLEWITHTWODWORDINTREE(0x1ea00000,0x00000000)}},
+ {VT_exponent,22,0x3a84c1,{DOUBLEWITHTWODWORDINTREE(0x1eb00000,0x00000000)}},
+ {VT_exponent,22,0x3a84c2,{DOUBLEWITHTWODWORDINTREE(0x1ec00000,0x00000000)}},
+ {VT_exponent,22,0x3a84c3,{DOUBLEWITHTWODWORDINTREE(0x1ed00000,0x00000000)}},
+ {VT_exponent,22,0x3a84c4,{DOUBLEWITHTWODWORDINTREE(0x1ee00000,0x00000000)}},
+ {VT_exponent,22,0x3a84c5,{DOUBLEWITHTWODWORDINTREE(0x1ef00000,0x00000000)}},
+ {VT_exponent,22,0x3a84c6,{DOUBLEWITHTWODWORDINTREE(0x1f000000,0x00000000)}},
+ {VT_exponent,22,0x3a84c7,{DOUBLEWITHTWODWORDINTREE(0x1f100000,0x00000000)}},
+ {VT_exponent,22,0x3a84c8,{DOUBLEWITHTWODWORDINTREE(0x1f200000,0x00000000)}},
+ {VT_exponent,22,0x3a84c9,{DOUBLEWITHTWODWORDINTREE(0x1f300000,0x00000000)}},
+ {VT_exponent,22,0x3a84ca,{DOUBLEWITHTWODWORDINTREE(0x1f400000,0x00000000)}},
+ {VT_exponent,22,0x3a84cb,{DOUBLEWITHTWODWORDINTREE(0x1f500000,0x00000000)}},
+ {VT_exponent,22,0x3a84cc,{DOUBLEWITHTWODWORDINTREE(0x1f600000,0x00000000)}},
+ {VT_exponent,22,0x3a84cd,{DOUBLEWITHTWODWORDINTREE(0x1f700000,0x00000000)}},
+ {VT_exponent,22,0x3a84ce,{DOUBLEWITHTWODWORDINTREE(0x1f800000,0x00000000)}},
+ {VT_exponent,22,0x3a84cf,{DOUBLEWITHTWODWORDINTREE(0x1f900000,0x00000000)}},
+ {VT_exponent,22,0x3a84d0,{DOUBLEWITHTWODWORDINTREE(0x1fa00000,0x00000000)}},
+ {VT_exponent,22,0x3a84d1,{DOUBLEWITHTWODWORDINTREE(0x1fb00000,0x00000000)}},
+ {VT_exponent,22,0x3a84d2,{DOUBLEWITHTWODWORDINTREE(0x1fc00000,0x00000000)}},
+ {VT_exponent,22,0x3a84d3,{DOUBLEWITHTWODWORDINTREE(0x1fd00000,0x00000000)}},
+ {VT_exponent,22,0x3a84d4,{DOUBLEWITHTWODWORDINTREE(0x1fe00000,0x00000000)}},
+ {VT_exponent,22,0x3a84d5,{DOUBLEWITHTWODWORDINTREE(0x1ff00000,0x00000000)}},
+ {VT_exponent,22,0x3a84d6,{DOUBLEWITHTWODWORDINTREE(0x20000000,0x00000000)}},
+ {VT_exponent,22,0x3a84d7,{DOUBLEWITHTWODWORDINTREE(0x20100000,0x00000000)}},
+ {VT_exponent,22,0x3a84d8,{DOUBLEWITHTWODWORDINTREE(0x20200000,0x00000000)}},
+ {VT_exponent,22,0x3a84d9,{DOUBLEWITHTWODWORDINTREE(0x20300000,0x00000000)}},
+ {VT_exponent,22,0x3a84da,{DOUBLEWITHTWODWORDINTREE(0x20400000,0x00000000)}},
+ {VT_exponent,22,0x3a84db,{DOUBLEWITHTWODWORDINTREE(0x20500000,0x00000000)}},
+ {VT_exponent,22,0x3a84dc,{DOUBLEWITHTWODWORDINTREE(0x20600000,0x00000000)}},
+ {VT_exponent,22,0x3a84dd,{DOUBLEWITHTWODWORDINTREE(0x20700000,0x00000000)}},
+ {VT_exponent,22,0x3a84de,{DOUBLEWITHTWODWORDINTREE(0x20800000,0x00000000)}},
+ {VT_exponent,22,0x3a84df,{DOUBLEWITHTWODWORDINTREE(0x20900000,0x00000000)}},
+ {VT_exponent,22,0x3a84e0,{DOUBLEWITHTWODWORDINTREE(0x20a00000,0x00000000)}},
+ {VT_exponent,22,0x3a84e1,{DOUBLEWITHTWODWORDINTREE(0x20b00000,0x00000000)}},
+ {VT_exponent,22,0x3a84e2,{DOUBLEWITHTWODWORDINTREE(0x20c00000,0x00000000)}},
+ {VT_exponent,22,0x3a84e3,{DOUBLEWITHTWODWORDINTREE(0x20d00000,0x00000000)}},
+ {VT_exponent,22,0x3a84e4,{DOUBLEWITHTWODWORDINTREE(0x20e00000,0x00000000)}},
+ {VT_exponent,22,0x3a84e5,{DOUBLEWITHTWODWORDINTREE(0x20f00000,0x00000000)}},
+ {VT_exponent,22,0x3a84e6,{DOUBLEWITHTWODWORDINTREE(0x21000000,0x00000000)}},
+ {VT_exponent,22,0x3a84e7,{DOUBLEWITHTWODWORDINTREE(0x21100000,0x00000000)}},
+ {VT_exponent,22,0x3a84e8,{DOUBLEWITHTWODWORDINTREE(0x21200000,0x00000000)}},
+ {VT_exponent,22,0x3a84e9,{DOUBLEWITHTWODWORDINTREE(0x21300000,0x00000000)}},
+ {VT_exponent,22,0x3a84ea,{DOUBLEWITHTWODWORDINTREE(0x21400000,0x00000000)}},
+ {VT_exponent,22,0x3a84eb,{DOUBLEWITHTWODWORDINTREE(0x21500000,0x00000000)}},
+ {VT_exponent,22,0x3a84ec,{DOUBLEWITHTWODWORDINTREE(0x21600000,0x00000000)}},
+ {VT_exponent,22,0x3a84ed,{DOUBLEWITHTWODWORDINTREE(0x21700000,0x00000000)}},
+ {VT_exponent,22,0x3a84ee,{DOUBLEWITHTWODWORDINTREE(0x21800000,0x00000000)}},
+ {VT_exponent,22,0x3a84ef,{DOUBLEWITHTWODWORDINTREE(0x21900000,0x00000000)}},
+ {VT_exponent,22,0x3a84f0,{DOUBLEWITHTWODWORDINTREE(0x21a00000,0x00000000)}},
+ {VT_exponent,22,0x3a84f1,{DOUBLEWITHTWODWORDINTREE(0x21b00000,0x00000000)}},
+ {VT_exponent,22,0x3a84f2,{DOUBLEWITHTWODWORDINTREE(0x21c00000,0x00000000)}},
+ {VT_exponent,22,0x3a84f3,{DOUBLEWITHTWODWORDINTREE(0x21d00000,0x00000000)}},
+ {VT_exponent,22,0x3a84f4,{DOUBLEWITHTWODWORDINTREE(0x21e00000,0x00000000)}},
+ {VT_exponent,22,0x3a84f5,{DOUBLEWITHTWODWORDINTREE(0x21f00000,0x00000000)}},
+ {VT_exponent,22,0x3a84f6,{DOUBLEWITHTWODWORDINTREE(0x22000000,0x00000000)}},
+ {VT_exponent,22,0x3a84f7,{DOUBLEWITHTWODWORDINTREE(0x22100000,0x00000000)}},
+ {VT_exponent,22,0x3a84f8,{DOUBLEWITHTWODWORDINTREE(0x22200000,0x00000000)}},
+ {VT_exponent,22,0x3a84f9,{DOUBLEWITHTWODWORDINTREE(0x22300000,0x00000000)}},
+ {VT_exponent,22,0x3a84fa,{DOUBLEWITHTWODWORDINTREE(0x22400000,0x00000000)}},
+ {VT_exponent,22,0x3a84fb,{DOUBLEWITHTWODWORDINTREE(0x22500000,0x00000000)}},
+ {VT_exponent,22,0x3a84fc,{DOUBLEWITHTWODWORDINTREE(0x22600000,0x00000000)}},
+ {VT_exponent,22,0x3a84fd,{DOUBLEWITHTWODWORDINTREE(0x22700000,0x00000000)}},
+ {VT_exponent,22,0x3a84fe,{DOUBLEWITHTWODWORDINTREE(0x22800000,0x00000000)}},
+ {VT_exponent,22,0x3a84ff,{DOUBLEWITHTWODWORDINTREE(0x22900000,0x00000000)}},
+ {VT_exponent,22,0x3a8500,{DOUBLEWITHTWODWORDINTREE(0x22a00000,0x00000000)}},
+ {VT_exponent,22,0x3a8501,{DOUBLEWITHTWODWORDINTREE(0x22b00000,0x00000000)}},
+ {VT_exponent,22,0x3a8502,{DOUBLEWITHTWODWORDINTREE(0x22c00000,0x00000000)}},
+ {VT_exponent,22,0x3a8503,{DOUBLEWITHTWODWORDINTREE(0x22d00000,0x00000000)}},
+ {VT_exponent,22,0x3a8504,{DOUBLEWITHTWODWORDINTREE(0x22e00000,0x00000000)}},
+ {VT_exponent,22,0x3a8505,{DOUBLEWITHTWODWORDINTREE(0x22f00000,0x00000000)}},
+ {VT_exponent,22,0x3a8506,{DOUBLEWITHTWODWORDINTREE(0x23000000,0x00000000)}},
+ {VT_exponent,22,0x3a8507,{DOUBLEWITHTWODWORDINTREE(0x23100000,0x00000000)}},
+ {VT_exponent,22,0x3a8508,{DOUBLEWITHTWODWORDINTREE(0x23200000,0x00000000)}},
+ {VT_exponent,22,0x3a8509,{DOUBLEWITHTWODWORDINTREE(0x23300000,0x00000000)}},
+ {VT_exponent,22,0x3a850a,{DOUBLEWITHTWODWORDINTREE(0x23400000,0x00000000)}},
+ {VT_exponent,22,0x3a850b,{DOUBLEWITHTWODWORDINTREE(0x23500000,0x00000000)}},
+ {VT_exponent,22,0x3a850c,{DOUBLEWITHTWODWORDINTREE(0x23600000,0x00000000)}},
+ {VT_exponent,22,0x3a850d,{DOUBLEWITHTWODWORDINTREE(0x23700000,0x00000000)}},
+ {VT_exponent,22,0x3a850e,{DOUBLEWITHTWODWORDINTREE(0x23800000,0x00000000)}},
+ {VT_exponent,22,0x3a850f,{DOUBLEWITHTWODWORDINTREE(0x23900000,0x00000000)}},
+ {VT_exponent,22,0x3a8510,{DOUBLEWITHTWODWORDINTREE(0x23a00000,0x00000000)}},
+ {VT_exponent,22,0x3a8511,{DOUBLEWITHTWODWORDINTREE(0x23b00000,0x00000000)}},
+ {VT_exponent,22,0x3a8512,{DOUBLEWITHTWODWORDINTREE(0x23c00000,0x00000000)}},
+ {VT_exponent,22,0x3a8513,{DOUBLEWITHTWODWORDINTREE(0x23d00000,0x00000000)}},
+ {VT_exponent,22,0x3a8514,{DOUBLEWITHTWODWORDINTREE(0x23e00000,0x00000000)}},
+ {VT_exponent,22,0x3a8515,{DOUBLEWITHTWODWORDINTREE(0x23f00000,0x00000000)}},
+ {VT_exponent,22,0x3a8516,{DOUBLEWITHTWODWORDINTREE(0x24000000,0x00000000)}},
+ {VT_exponent,22,0x3a8517,{DOUBLEWITHTWODWORDINTREE(0x24100000,0x00000000)}},
+ {VT_exponent,22,0x3a8518,{DOUBLEWITHTWODWORDINTREE(0x24200000,0x00000000)}},
+ {VT_exponent,22,0x3a8519,{DOUBLEWITHTWODWORDINTREE(0x24300000,0x00000000)}},
+ {VT_exponent,22,0x3a851a,{DOUBLEWITHTWODWORDINTREE(0x24400000,0x00000000)}},
+ {VT_exponent,22,0x3a851b,{DOUBLEWITHTWODWORDINTREE(0x24500000,0x00000000)}},
+ {VT_exponent,22,0x3a851c,{DOUBLEWITHTWODWORDINTREE(0x24600000,0x00000000)}},
+ {VT_exponent,22,0x3a851d,{DOUBLEWITHTWODWORDINTREE(0x24700000,0x00000000)}},
+ {VT_exponent,22,0x3a851e,{DOUBLEWITHTWODWORDINTREE(0x24800000,0x00000000)}},
+ {VT_exponent,22,0x3a851f,{DOUBLEWITHTWODWORDINTREE(0x24900000,0x00000000)}},
+ {VT_exponent,22,0x3a8520,{DOUBLEWITHTWODWORDINTREE(0x24a00000,0x00000000)}},
+ {VT_exponent,22,0x3a8521,{DOUBLEWITHTWODWORDINTREE(0x24b00000,0x00000000)}},
+ {VT_exponent,22,0x3a8522,{DOUBLEWITHTWODWORDINTREE(0x24c00000,0x00000000)}},
+ {VT_exponent,22,0x3a8523,{DOUBLEWITHTWODWORDINTREE(0x24d00000,0x00000000)}},
+ {VT_exponent,22,0x3a8524,{DOUBLEWITHTWODWORDINTREE(0x24e00000,0x00000000)}},
+ {VT_exponent,22,0x3a8525,{DOUBLEWITHTWODWORDINTREE(0x24f00000,0x00000000)}},
+ {VT_exponent,22,0x3a8526,{DOUBLEWITHTWODWORDINTREE(0x25000000,0x00000000)}},
+ {VT_exponent,22,0x3a8527,{DOUBLEWITHTWODWORDINTREE(0x25100000,0x00000000)}},
+ {VT_exponent,22,0x3a8528,{DOUBLEWITHTWODWORDINTREE(0x25200000,0x00000000)}},
+ {VT_exponent,22,0x3a8529,{DOUBLEWITHTWODWORDINTREE(0x25300000,0x00000000)}},
+ {VT_exponent,22,0x3a852a,{DOUBLEWITHTWODWORDINTREE(0x25400000,0x00000000)}},
+ {VT_exponent,22,0x3a852b,{DOUBLEWITHTWODWORDINTREE(0x25500000,0x00000000)}},
+ {VT_exponent,22,0x3a852c,{DOUBLEWITHTWODWORDINTREE(0x25600000,0x00000000)}},
+ {VT_exponent,22,0x3a852d,{DOUBLEWITHTWODWORDINTREE(0x25700000,0x00000000)}},
+ {VT_exponent,22,0x3a852e,{DOUBLEWITHTWODWORDINTREE(0x25800000,0x00000000)}},
+ {VT_exponent,22,0x3a852f,{DOUBLEWITHTWODWORDINTREE(0x25900000,0x00000000)}},
+ {VT_exponent,22,0x3a8530,{DOUBLEWITHTWODWORDINTREE(0x25a00000,0x00000000)}},
+ {VT_exponent,22,0x3a8531,{DOUBLEWITHTWODWORDINTREE(0x25b00000,0x00000000)}},
+ {VT_exponent,22,0x3a8532,{DOUBLEWITHTWODWORDINTREE(0x25c00000,0x00000000)}},
+ {VT_exponent,22,0x3a8533,{DOUBLEWITHTWODWORDINTREE(0x25d00000,0x00000000)}},
+ {VT_exponent,22,0x3a8534,{DOUBLEWITHTWODWORDINTREE(0x25e00000,0x00000000)}},
+ {VT_exponent,22,0x3a8535,{DOUBLEWITHTWODWORDINTREE(0x25f00000,0x00000000)}},
+ {VT_exponent,22,0x3a8536,{DOUBLEWITHTWODWORDINTREE(0x26000000,0x00000000)}},
+ {VT_exponent,22,0x3a8537,{DOUBLEWITHTWODWORDINTREE(0x26100000,0x00000000)}},
+ {VT_exponent,22,0x3a8538,{DOUBLEWITHTWODWORDINTREE(0x26200000,0x00000000)}},
+ {VT_exponent,22,0x3a8539,{DOUBLEWITHTWODWORDINTREE(0x26300000,0x00000000)}},
+ {VT_exponent,22,0x3a853a,{DOUBLEWITHTWODWORDINTREE(0x26400000,0x00000000)}},
+ {VT_exponent,22,0x3a853b,{DOUBLEWITHTWODWORDINTREE(0x26500000,0x00000000)}},
+ {VT_exponent,22,0x3a853c,{DOUBLEWITHTWODWORDINTREE(0x26600000,0x00000000)}},
+ {VT_exponent,22,0x3a853d,{DOUBLEWITHTWODWORDINTREE(0x26700000,0x00000000)}},
+ {VT_exponent,22,0x3a853e,{DOUBLEWITHTWODWORDINTREE(0x26800000,0x00000000)}},
+ {VT_exponent,22,0x3a853f,{DOUBLEWITHTWODWORDINTREE(0x26900000,0x00000000)}},
+ {VT_exponent,22,0x3a8540,{DOUBLEWITHTWODWORDINTREE(0x26a00000,0x00000000)}},
+ {VT_exponent,22,0x3a8541,{DOUBLEWITHTWODWORDINTREE(0x26b00000,0x00000000)}},
+ {VT_exponent,22,0x3a8542,{DOUBLEWITHTWODWORDINTREE(0x26c00000,0x00000000)}},
+ {VT_exponent,22,0x3a8543,{DOUBLEWITHTWODWORDINTREE(0x26d00000,0x00000000)}},
+ {VT_exponent,22,0x3a8544,{DOUBLEWITHTWODWORDINTREE(0x26e00000,0x00000000)}},
+ {VT_exponent,22,0x3a8545,{DOUBLEWITHTWODWORDINTREE(0x26f00000,0x00000000)}},
+ {VT_exponent,22,0x3a8546,{DOUBLEWITHTWODWORDINTREE(0x27000000,0x00000000)}},
+ {VT_exponent,22,0x3a8547,{DOUBLEWITHTWODWORDINTREE(0x27100000,0x00000000)}},
+ {VT_exponent,22,0x3a8548,{DOUBLEWITHTWODWORDINTREE(0x27200000,0x00000000)}},
+ {VT_exponent,22,0x3a8549,{DOUBLEWITHTWODWORDINTREE(0x27300000,0x00000000)}},
+ {VT_exponent,22,0x3a854a,{DOUBLEWITHTWODWORDINTREE(0x27400000,0x00000000)}},
+ {VT_exponent,22,0x3a854b,{DOUBLEWITHTWODWORDINTREE(0x27500000,0x00000000)}},
+ {VT_exponent,22,0x3a854c,{DOUBLEWITHTWODWORDINTREE(0x27600000,0x00000000)}},
+ {VT_exponent,22,0x3a854d,{DOUBLEWITHTWODWORDINTREE(0x27700000,0x00000000)}},
+ {VT_exponent,22,0x3a854e,{DOUBLEWITHTWODWORDINTREE(0x27800000,0x00000000)}},
+ {VT_exponent,22,0x3a854f,{DOUBLEWITHTWODWORDINTREE(0x27900000,0x00000000)}},
+ {VT_exponent,22,0x3a8550,{DOUBLEWITHTWODWORDINTREE(0x27a00000,0x00000000)}},
+ {VT_exponent,22,0x3a8551,{DOUBLEWITHTWODWORDINTREE(0x27b00000,0x00000000)}},
+ {VT_exponent,22,0x3a8552,{DOUBLEWITHTWODWORDINTREE(0x27c00000,0x00000000)}},
+ {VT_exponent,22,0x3a8553,{DOUBLEWITHTWODWORDINTREE(0x27d00000,0x00000000)}},
+ {VT_exponent,22,0x3a8554,{DOUBLEWITHTWODWORDINTREE(0x27e00000,0x00000000)}},
+ {VT_exponent,22,0x3a8555,{DOUBLEWITHTWODWORDINTREE(0x27f00000,0x00000000)}},
+ {VT_exponent,22,0x3a8556,{DOUBLEWITHTWODWORDINTREE(0x28000000,0x00000000)}},
+ {VT_exponent,22,0x3a8557,{DOUBLEWITHTWODWORDINTREE(0x28100000,0x00000000)}},
+ {VT_exponent,22,0x3a8558,{DOUBLEWITHTWODWORDINTREE(0x28200000,0x00000000)}},
+ {VT_exponent,22,0x3a8559,{DOUBLEWITHTWODWORDINTREE(0x28300000,0x00000000)}},
+ {VT_exponent,22,0x3a855a,{DOUBLEWITHTWODWORDINTREE(0x28400000,0x00000000)}},
+ {VT_exponent,22,0x3a855b,{DOUBLEWITHTWODWORDINTREE(0x28500000,0x00000000)}},
+ {VT_exponent,22,0x3a855c,{DOUBLEWITHTWODWORDINTREE(0x28600000,0x00000000)}},
+ {VT_exponent,22,0x3a855d,{DOUBLEWITHTWODWORDINTREE(0x28700000,0x00000000)}},
+ {VT_exponent,22,0x3a855e,{DOUBLEWITHTWODWORDINTREE(0x28800000,0x00000000)}},
+ {VT_exponent,22,0x3a855f,{DOUBLEWITHTWODWORDINTREE(0x28900000,0x00000000)}},
+ {VT_exponent,22,0x3a8560,{DOUBLEWITHTWODWORDINTREE(0x28a00000,0x00000000)}},
+ {VT_exponent,22,0x3a8561,{DOUBLEWITHTWODWORDINTREE(0x28b00000,0x00000000)}},
+ {VT_exponent,22,0x3a8562,{DOUBLEWITHTWODWORDINTREE(0x28c00000,0x00000000)}},
+ {VT_exponent,22,0x3a8563,{DOUBLEWITHTWODWORDINTREE(0x28d00000,0x00000000)}},
+ {VT_exponent,22,0x3a8564,{DOUBLEWITHTWODWORDINTREE(0x28e00000,0x00000000)}},
+ {VT_exponent,22,0x3a8565,{DOUBLEWITHTWODWORDINTREE(0x28f00000,0x00000000)}},
+ {VT_exponent,22,0x3a8566,{DOUBLEWITHTWODWORDINTREE(0x29000000,0x00000000)}},
+ {VT_exponent,22,0x3a8567,{DOUBLEWITHTWODWORDINTREE(0x29100000,0x00000000)}},
+ {VT_exponent,22,0x3a8568,{DOUBLEWITHTWODWORDINTREE(0x29200000,0x00000000)}},
+ {VT_exponent,22,0x3a8569,{DOUBLEWITHTWODWORDINTREE(0x29300000,0x00000000)}},
+ {VT_exponent,22,0x3a856a,{DOUBLEWITHTWODWORDINTREE(0x29400000,0x00000000)}},
+ {VT_exponent,22,0x3a856b,{DOUBLEWITHTWODWORDINTREE(0x29500000,0x00000000)}},
+ {VT_exponent,22,0x3a856c,{DOUBLEWITHTWODWORDINTREE(0x29600000,0x00000000)}},
+ {VT_exponent,22,0x3a856d,{DOUBLEWITHTWODWORDINTREE(0x29700000,0x00000000)}},
+ {VT_exponent,22,0x3a856e,{DOUBLEWITHTWODWORDINTREE(0x29800000,0x00000000)}},
+ {VT_exponent,22,0x3a856f,{DOUBLEWITHTWODWORDINTREE(0x29900000,0x00000000)}},
+ {VT_exponent,22,0x3a8570,{DOUBLEWITHTWODWORDINTREE(0x29a00000,0x00000000)}},
+ {VT_exponent,22,0x3a8571,{DOUBLEWITHTWODWORDINTREE(0x29b00000,0x00000000)}},
+ {VT_exponent,22,0x3a8572,{DOUBLEWITHTWODWORDINTREE(0x29c00000,0x00000000)}},
+ {VT_exponent,22,0x3a8573,{DOUBLEWITHTWODWORDINTREE(0x29d00000,0x00000000)}},
+ {VT_exponent,22,0x3a8574,{DOUBLEWITHTWODWORDINTREE(0x29e00000,0x00000000)}},
+ {VT_exponent,22,0x3a8575,{DOUBLEWITHTWODWORDINTREE(0x29f00000,0x00000000)}},
+ {VT_exponent,22,0x3a8576,{DOUBLEWITHTWODWORDINTREE(0x2a000000,0x00000000)}},
+ {VT_exponent,22,0x3a8577,{DOUBLEWITHTWODWORDINTREE(0x2a100000,0x00000000)}},
+ {VT_exponent,22,0x3a8578,{DOUBLEWITHTWODWORDINTREE(0x2a200000,0x00000000)}},
+ {VT_exponent,22,0x3a8579,{DOUBLEWITHTWODWORDINTREE(0x2a300000,0x00000000)}},
+ {VT_exponent,22,0x3a857a,{DOUBLEWITHTWODWORDINTREE(0x2a400000,0x00000000)}},
+ {VT_exponent,22,0x3a857b,{DOUBLEWITHTWODWORDINTREE(0x2a500000,0x00000000)}},
+ {VT_exponent,22,0x3a857c,{DOUBLEWITHTWODWORDINTREE(0x2a600000,0x00000000)}},
+ {VT_exponent,22,0x3a857d,{DOUBLEWITHTWODWORDINTREE(0x2a700000,0x00000000)}},
+ {VT_exponent,22,0x3a857e,{DOUBLEWITHTWODWORDINTREE(0x2a800000,0x00000000)}},
+ {VT_exponent,22,0x3a857f,{DOUBLEWITHTWODWORDINTREE(0x2a900000,0x00000000)}},
+ {VT_exponent,22,0x3a8580,{DOUBLEWITHTWODWORDINTREE(0x2aa00000,0x00000000)}},
+ {VT_exponent,22,0x3a8581,{DOUBLEWITHTWODWORDINTREE(0x2ab00000,0x00000000)}},
+ {VT_exponent,22,0x3a8582,{DOUBLEWITHTWODWORDINTREE(0x2ac00000,0x00000000)}},
+ {VT_exponent,22,0x3a8583,{DOUBLEWITHTWODWORDINTREE(0x2ad00000,0x00000000)}},
+ {VT_exponent,22,0x3a8584,{DOUBLEWITHTWODWORDINTREE(0x2ae00000,0x00000000)}},
+ {VT_exponent,22,0x3a8585,{DOUBLEWITHTWODWORDINTREE(0x2af00000,0x00000000)}},
+ {VT_exponent,22,0x3a8586,{DOUBLEWITHTWODWORDINTREE(0x2b000000,0x00000000)}},
+ {VT_exponent,22,0x3a8587,{DOUBLEWITHTWODWORDINTREE(0x2b100000,0x00000000)}},
+ {VT_exponent,22,0x3a8588,{DOUBLEWITHTWODWORDINTREE(0x2b200000,0x00000000)}},
+ {VT_exponent,22,0x3a8589,{DOUBLEWITHTWODWORDINTREE(0x2b300000,0x00000000)}},
+ {VT_exponent,22,0x3a858a,{DOUBLEWITHTWODWORDINTREE(0x2b400000,0x00000000)}},
+ {VT_exponent,22,0x3a858b,{DOUBLEWITHTWODWORDINTREE(0x2b500000,0x00000000)}},
+ {VT_exponent,22,0x3a858c,{DOUBLEWITHTWODWORDINTREE(0x2b600000,0x00000000)}},
+ {VT_exponent,22,0x3a858d,{DOUBLEWITHTWODWORDINTREE(0x2b700000,0x00000000)}},
+ {VT_exponent,22,0x3a858e,{DOUBLEWITHTWODWORDINTREE(0x2b800000,0x00000000)}},
+ {VT_exponent,22,0x3a858f,{DOUBLEWITHTWODWORDINTREE(0x2b900000,0x00000000)}},
+ {VT_exponent,22,0x3a8590,{DOUBLEWITHTWODWORDINTREE(0x2ba00000,0x00000000)}},
+ {VT_exponent,22,0x3a8591,{DOUBLEWITHTWODWORDINTREE(0x2bb00000,0x00000000)}},
+ {VT_exponent,22,0x3a8592,{DOUBLEWITHTWODWORDINTREE(0x2bc00000,0x00000000)}},
+ {VT_exponent,22,0x3a8593,{DOUBLEWITHTWODWORDINTREE(0x2bd00000,0x00000000)}},
+ {VT_exponent,22,0x3a8594,{DOUBLEWITHTWODWORDINTREE(0x2be00000,0x00000000)}},
+ {VT_exponent,22,0x3a8595,{DOUBLEWITHTWODWORDINTREE(0x2bf00000,0x00000000)}},
+ {VT_exponent,22,0x3a8596,{DOUBLEWITHTWODWORDINTREE(0x2c000000,0x00000000)}},
+ {VT_exponent,22,0x3a8597,{DOUBLEWITHTWODWORDINTREE(0x2c100000,0x00000000)}},
+ {VT_exponent,22,0x3a8598,{DOUBLEWITHTWODWORDINTREE(0x2c200000,0x00000000)}},
+ {VT_exponent,22,0x3a8599,{DOUBLEWITHTWODWORDINTREE(0x2c300000,0x00000000)}},
+ {VT_exponent,22,0x3a859a,{DOUBLEWITHTWODWORDINTREE(0x2c400000,0x00000000)}},
+ {VT_exponent,22,0x3a859b,{DOUBLEWITHTWODWORDINTREE(0x2c500000,0x00000000)}},
+ {VT_exponent,22,0x3a859c,{DOUBLEWITHTWODWORDINTREE(0x2c600000,0x00000000)}},
+ {VT_exponent,22,0x3a859d,{DOUBLEWITHTWODWORDINTREE(0x2c700000,0x00000000)}},
+ {VT_exponent,22,0x3a859e,{DOUBLEWITHTWODWORDINTREE(0x2c800000,0x00000000)}},
+ {VT_exponent,22,0x3a859f,{DOUBLEWITHTWODWORDINTREE(0x2c900000,0x00000000)}},
+ {VT_exponent,22,0x3a85a0,{DOUBLEWITHTWODWORDINTREE(0x2ca00000,0x00000000)}},
+ {VT_exponent,22,0x3a85a1,{DOUBLEWITHTWODWORDINTREE(0x2cb00000,0x00000000)}},
+ {VT_exponent,22,0x3a85a2,{DOUBLEWITHTWODWORDINTREE(0x2cc00000,0x00000000)}},
+ {VT_exponent,22,0x3a85a3,{DOUBLEWITHTWODWORDINTREE(0x2cd00000,0x00000000)}},
+ {VT_exponent,22,0x3a85a4,{DOUBLEWITHTWODWORDINTREE(0x2ce00000,0x00000000)}},
+ {VT_exponent,22,0x3a85a5,{DOUBLEWITHTWODWORDINTREE(0x2cf00000,0x00000000)}},
+ {VT_exponent,22,0x3a85a6,{DOUBLEWITHTWODWORDINTREE(0x2d000000,0x00000000)}},
+ {VT_exponent,22,0x3a85a7,{DOUBLEWITHTWODWORDINTREE(0x2d100000,0x00000000)}},
+ {VT_exponent,22,0x3a85a8,{DOUBLEWITHTWODWORDINTREE(0x2d200000,0x00000000)}},
+ {VT_exponent,22,0x3a85a9,{DOUBLEWITHTWODWORDINTREE(0x2d300000,0x00000000)}},
+ {VT_exponent,22,0x3a85aa,{DOUBLEWITHTWODWORDINTREE(0x2d400000,0x00000000)}},
+ {VT_exponent,22,0x3a85ab,{DOUBLEWITHTWODWORDINTREE(0x2d500000,0x00000000)}},
+ {VT_exponent,22,0x3a85ac,{DOUBLEWITHTWODWORDINTREE(0x2d600000,0x00000000)}},
+ {VT_exponent,22,0x3a85ad,{DOUBLEWITHTWODWORDINTREE(0x2d700000,0x00000000)}},
+ {VT_exponent,22,0x3a85ae,{DOUBLEWITHTWODWORDINTREE(0x2d800000,0x00000000)}},
+ {VT_exponent,22,0x3a85af,{DOUBLEWITHTWODWORDINTREE(0x2d900000,0x00000000)}},
+ {VT_exponent,22,0x3a85b0,{DOUBLEWITHTWODWORDINTREE(0x2da00000,0x00000000)}},
+ {VT_exponent,22,0x3a85b1,{DOUBLEWITHTWODWORDINTREE(0x2db00000,0x00000000)}},
+ {VT_exponent,22,0x3a85b2,{DOUBLEWITHTWODWORDINTREE(0x2dc00000,0x00000000)}},
+ {VT_exponent,22,0x3a85b3,{DOUBLEWITHTWODWORDINTREE(0x2dd00000,0x00000000)}},
+ {VT_exponent,22,0x3a85b4,{DOUBLEWITHTWODWORDINTREE(0x2de00000,0x00000000)}},
+ {VT_exponent,22,0x3a85b5,{DOUBLEWITHTWODWORDINTREE(0x2df00000,0x00000000)}},
+ {VT_exponent,22,0x3a85b6,{DOUBLEWITHTWODWORDINTREE(0x2e000000,0x00000000)}},
+ {VT_exponent,22,0x3a85b7,{DOUBLEWITHTWODWORDINTREE(0x2e100000,0x00000000)}},
+ {VT_exponent,22,0x3a85b8,{DOUBLEWITHTWODWORDINTREE(0x2e200000,0x00000000)}},
+ {VT_exponent,22,0x3a85b9,{DOUBLEWITHTWODWORDINTREE(0x2e300000,0x00000000)}},
+ {VT_exponent,22,0x3a85ba,{DOUBLEWITHTWODWORDINTREE(0x2e400000,0x00000000)}},
+ {VT_exponent,22,0x3a85bb,{DOUBLEWITHTWODWORDINTREE(0x2e500000,0x00000000)}},
+ {VT_exponent,22,0x3a85bc,{DOUBLEWITHTWODWORDINTREE(0x2e600000,0x00000000)}},
+ {VT_exponent,22,0x3a85bd,{DOUBLEWITHTWODWORDINTREE(0x2e700000,0x00000000)}},
+ {VT_exponent,22,0x3a85be,{DOUBLEWITHTWODWORDINTREE(0x2e800000,0x00000000)}},
+ {VT_exponent,22,0x3a85bf,{DOUBLEWITHTWODWORDINTREE(0x2e900000,0x00000000)}},
+ {VT_exponent,22,0x3a85c0,{DOUBLEWITHTWODWORDINTREE(0x2ea00000,0x00000000)}},
+ {VT_exponent,22,0x3a85c1,{DOUBLEWITHTWODWORDINTREE(0x2eb00000,0x00000000)}},
+ {VT_exponent,22,0x3a85c2,{DOUBLEWITHTWODWORDINTREE(0x2ec00000,0x00000000)}},
+ {VT_exponent,22,0x3a85c3,{DOUBLEWITHTWODWORDINTREE(0x2ed00000,0x00000000)}},
+ {VT_exponent,22,0x3a85c4,{DOUBLEWITHTWODWORDINTREE(0x2ee00000,0x00000000)}},
+ {VT_exponent,22,0x3a85c5,{DOUBLEWITHTWODWORDINTREE(0x2ef00000,0x00000000)}},
+ {VT_exponent,22,0x3a85c6,{DOUBLEWITHTWODWORDINTREE(0x2f000000,0x00000000)}},
+ {VT_exponent,22,0x3a85c7,{DOUBLEWITHTWODWORDINTREE(0x2f100000,0x00000000)}},
+ {VT_exponent,22,0x3a85c8,{DOUBLEWITHTWODWORDINTREE(0x2f200000,0x00000000)}},
+ {VT_exponent,22,0x3a85c9,{DOUBLEWITHTWODWORDINTREE(0x2f300000,0x00000000)}},
+ {VT_exponent,22,0x3a85ca,{DOUBLEWITHTWODWORDINTREE(0x2f400000,0x00000000)}},
+ {VT_exponent,22,0x3a85cb,{DOUBLEWITHTWODWORDINTREE(0x2f500000,0x00000000)}},
+ {VT_exponent,22,0x3a85cc,{DOUBLEWITHTWODWORDINTREE(0x2f600000,0x00000000)}},
+ {VT_exponent,22,0x3a85cd,{DOUBLEWITHTWODWORDINTREE(0x2f700000,0x00000000)}},
+ {VT_exponent,22,0x3a85ce,{DOUBLEWITHTWODWORDINTREE(0x2f800000,0x00000000)}},
+ {VT_exponent,22,0x3a85cf,{DOUBLEWITHTWODWORDINTREE(0x2f900000,0x00000000)}},
+ {VT_exponent,22,0x3a85d0,{DOUBLEWITHTWODWORDINTREE(0x2fa00000,0x00000000)}},
+ {VT_exponent,22,0x3a85d1,{DOUBLEWITHTWODWORDINTREE(0x2fb00000,0x00000000)}},
+ {VT_exponent,22,0x3a85d2,{DOUBLEWITHTWODWORDINTREE(0x2fc00000,0x00000000)}},
+ {VT_exponent,22,0x3a85d3,{DOUBLEWITHTWODWORDINTREE(0x2fd00000,0x00000000)}},
+ {VT_exponent,22,0x3a85d4,{DOUBLEWITHTWODWORDINTREE(0x2fe00000,0x00000000)}},
+ {VT_exponent,22,0x3a85d5,{DOUBLEWITHTWODWORDINTREE(0x2ff00000,0x00000000)}},
+ {VT_exponent,22,0x3a85d6,{DOUBLEWITHTWODWORDINTREE(0x30000000,0x00000000)}},
+ {VT_exponent,22,0x3a85d7,{DOUBLEWITHTWODWORDINTREE(0x30100000,0x00000000)}},
+ {VT_exponent,22,0x3a85d8,{DOUBLEWITHTWODWORDINTREE(0x30200000,0x00000000)}},
+ {VT_exponent,22,0x3a85d9,{DOUBLEWITHTWODWORDINTREE(0x30300000,0x00000000)}},
+ {VT_exponent,22,0x3a85da,{DOUBLEWITHTWODWORDINTREE(0x30400000,0x00000000)}},
+ {VT_exponent,22,0x3a85db,{DOUBLEWITHTWODWORDINTREE(0x30500000,0x00000000)}},
+ {VT_exponent,22,0x3a85dc,{DOUBLEWITHTWODWORDINTREE(0x30600000,0x00000000)}},
+ {VT_exponent,22,0x3a85dd,{DOUBLEWITHTWODWORDINTREE(0x30700000,0x00000000)}},
+ {VT_exponent,22,0x3a85de,{DOUBLEWITHTWODWORDINTREE(0x30800000,0x00000000)}},
+ {VT_exponent,22,0x3a85df,{DOUBLEWITHTWODWORDINTREE(0x30900000,0x00000000)}},
+ {VT_exponent,22,0x3a85e0,{DOUBLEWITHTWODWORDINTREE(0x30a00000,0x00000000)}},
+ {VT_exponent,22,0x3a85e1,{DOUBLEWITHTWODWORDINTREE(0x30b00000,0x00000000)}},
+ {VT_exponent,22,0x3a85e2,{DOUBLEWITHTWODWORDINTREE(0x30c00000,0x00000000)}},
+ {VT_exponent,22,0x3a85e3,{DOUBLEWITHTWODWORDINTREE(0x30d00000,0x00000000)}},
+ {VT_exponent,22,0x3a85e4,{DOUBLEWITHTWODWORDINTREE(0x30e00000,0x00000000)}},
+ {VT_exponent,22,0x3a85e5,{DOUBLEWITHTWODWORDINTREE(0x30f00000,0x00000000)}},
+ {VT_exponent,22,0x3a85e6,{DOUBLEWITHTWODWORDINTREE(0x31000000,0x00000000)}},
+ {VT_exponent,22,0x3a85e7,{DOUBLEWITHTWODWORDINTREE(0x31100000,0x00000000)}},
+ {VT_exponent,22,0x3a85e8,{DOUBLEWITHTWODWORDINTREE(0x31200000,0x00000000)}},
+ {VT_exponent,22,0x3a85e9,{DOUBLEWITHTWODWORDINTREE(0x31300000,0x00000000)}},
+ {VT_exponent,22,0x3a85ea,{DOUBLEWITHTWODWORDINTREE(0x31400000,0x00000000)}},
+ {VT_exponent,22,0x3a85eb,{DOUBLEWITHTWODWORDINTREE(0x31500000,0x00000000)}},
+ {VT_exponent,22,0x3a85ec,{DOUBLEWITHTWODWORDINTREE(0x31600000,0x00000000)}},
+ {VT_exponent,22,0x3a85ed,{DOUBLEWITHTWODWORDINTREE(0x31700000,0x00000000)}},
+ {VT_exponent,22,0x3a85ee,{DOUBLEWITHTWODWORDINTREE(0x31800000,0x00000000)}},
+ {VT_exponent,22,0x3a85ef,{DOUBLEWITHTWODWORDINTREE(0x31900000,0x00000000)}},
+ {VT_exponent,22,0x3a85f0,{DOUBLEWITHTWODWORDINTREE(0x31a00000,0x00000000)}},
+ {VT_exponent,22,0x3a85f1,{DOUBLEWITHTWODWORDINTREE(0x31b00000,0x00000000)}},
+ {VT_exponent,22,0x3a85f2,{DOUBLEWITHTWODWORDINTREE(0x31c00000,0x00000000)}},
+ {VT_exponent,22,0x3a85f3,{DOUBLEWITHTWODWORDINTREE(0x31d00000,0x00000000)}},
+ {VT_exponent,22,0x3a85f4,{DOUBLEWITHTWODWORDINTREE(0x31e00000,0x00000000)}},
+ {VT_exponent,22,0x3a85f5,{DOUBLEWITHTWODWORDINTREE(0x31f00000,0x00000000)}},
+ {VT_exponent,22,0x3a85f6,{DOUBLEWITHTWODWORDINTREE(0x32000000,0x00000000)}},
+ {VT_exponent,22,0x3a85f7,{DOUBLEWITHTWODWORDINTREE(0x32100000,0x00000000)}},
+ {VT_exponent,22,0x3a85f8,{DOUBLEWITHTWODWORDINTREE(0x32200000,0x00000000)}},
+ {VT_exponent,22,0x3a85f9,{DOUBLEWITHTWODWORDINTREE(0x32300000,0x00000000)}},
+ {VT_exponent,22,0x3a85fa,{DOUBLEWITHTWODWORDINTREE(0x32400000,0x00000000)}},
+ {VT_exponent,22,0x3a85fb,{DOUBLEWITHTWODWORDINTREE(0x32500000,0x00000000)}},
+ {VT_exponent,22,0x3a85fc,{DOUBLEWITHTWODWORDINTREE(0x32600000,0x00000000)}},
+ {VT_exponent,22,0x3a85fd,{DOUBLEWITHTWODWORDINTREE(0x32700000,0x00000000)}},
+ {VT_exponent,22,0x3a85fe,{DOUBLEWITHTWODWORDINTREE(0x32800000,0x00000000)}},
+ {VT_exponent,22,0x3a85ff,{DOUBLEWITHTWODWORDINTREE(0x32900000,0x00000000)}},
+ {VT_exponent,22,0x3a8600,{DOUBLEWITHTWODWORDINTREE(0x32a00000,0x00000000)}},
+ {VT_exponent,22,0x3a8601,{DOUBLEWITHTWODWORDINTREE(0x32b00000,0x00000000)}},
+ {VT_exponent,22,0x3a8602,{DOUBLEWITHTWODWORDINTREE(0x32c00000,0x00000000)}},
+ {VT_exponent,22,0x3a8603,{DOUBLEWITHTWODWORDINTREE(0x32d00000,0x00000000)}},
+ {VT_exponent,22,0x3a8604,{DOUBLEWITHTWODWORDINTREE(0x32e00000,0x00000000)}},
+ {VT_exponent,22,0x3a8605,{DOUBLEWITHTWODWORDINTREE(0x32f00000,0x00000000)}},
+ {VT_exponent,22,0x3a8606,{DOUBLEWITHTWODWORDINTREE(0x33000000,0x00000000)}},
+ {VT_exponent,22,0x3a8607,{DOUBLEWITHTWODWORDINTREE(0x33100000,0x00000000)}},
+ {VT_exponent,22,0x3a8608,{DOUBLEWITHTWODWORDINTREE(0x33200000,0x00000000)}},
+ {VT_exponent,22,0x3a8609,{DOUBLEWITHTWODWORDINTREE(0x33300000,0x00000000)}},
+ {VT_exponent,22,0x3a860a,{DOUBLEWITHTWODWORDINTREE(0x33400000,0x00000000)}},
+ {VT_exponent,22,0x3a860b,{DOUBLEWITHTWODWORDINTREE(0x33500000,0x00000000)}},
+ {VT_exponent,22,0x3a860c,{DOUBLEWITHTWODWORDINTREE(0x33600000,0x00000000)}},
+ {VT_exponent,22,0x3a860d,{DOUBLEWITHTWODWORDINTREE(0x33700000,0x00000000)}},
+ {VT_exponent,22,0x3a860e,{DOUBLEWITHTWODWORDINTREE(0x33800000,0x00000000)}},
+ {VT_exponent,22,0x3a860f,{DOUBLEWITHTWODWORDINTREE(0x33900000,0x00000000)}},
+ {VT_exponent,22,0x3a8610,{DOUBLEWITHTWODWORDINTREE(0x33a00000,0x00000000)}},
+ {VT_exponent,22,0x3a8611,{DOUBLEWITHTWODWORDINTREE(0x33b00000,0x00000000)}},
+ {VT_exponent,22,0x3a8612,{DOUBLEWITHTWODWORDINTREE(0x33c00000,0x00000000)}},
+ {VT_exponent,22,0x3a8613,{DOUBLEWITHTWODWORDINTREE(0x33d00000,0x00000000)}},
+ {VT_exponent,22,0x3a8614,{DOUBLEWITHTWODWORDINTREE(0x33e00000,0x00000000)}},
+ {VT_exponent,22,0x3a8615,{DOUBLEWITHTWODWORDINTREE(0x33f00000,0x00000000)}},
+ {VT_exponent,22,0x3a8616,{DOUBLEWITHTWODWORDINTREE(0x34000000,0x00000000)}},
+ {VT_exponent,22,0x3a8617,{DOUBLEWITHTWODWORDINTREE(0x34100000,0x00000000)}},
+ {VT_exponent,22,0x3a8618,{DOUBLEWITHTWODWORDINTREE(0x34200000,0x00000000)}},
+ {VT_exponent,22,0x3a8619,{DOUBLEWITHTWODWORDINTREE(0x34300000,0x00000000)}},
+ {VT_exponent,22,0x3a861a,{DOUBLEWITHTWODWORDINTREE(0x34400000,0x00000000)}},
+ {VT_exponent,22,0x3a861b,{DOUBLEWITHTWODWORDINTREE(0x34500000,0x00000000)}},
+ {VT_exponent,22,0x3a861c,{DOUBLEWITHTWODWORDINTREE(0x34600000,0x00000000)}},
+ {VT_exponent,22,0x3a861d,{DOUBLEWITHTWODWORDINTREE(0x34700000,0x00000000)}},
+ {VT_exponent,22,0x3a861e,{DOUBLEWITHTWODWORDINTREE(0x34800000,0x00000000)}},
+ {VT_exponent,22,0x3a861f,{DOUBLEWITHTWODWORDINTREE(0x34900000,0x00000000)}},
+ {VT_exponent,22,0x3a8620,{DOUBLEWITHTWODWORDINTREE(0x34a00000,0x00000000)}},
+ {VT_exponent,22,0x3a8621,{DOUBLEWITHTWODWORDINTREE(0x34b00000,0x00000000)}},
+ {VT_exponent,22,0x3a8622,{DOUBLEWITHTWODWORDINTREE(0x34c00000,0x00000000)}},
+ {VT_exponent,22,0x3a8623,{DOUBLEWITHTWODWORDINTREE(0x34d00000,0x00000000)}},
+ {VT_exponent,22,0x3a8624,{DOUBLEWITHTWODWORDINTREE(0x34e00000,0x00000000)}},
+ {VT_exponent,22,0x3a8625,{DOUBLEWITHTWODWORDINTREE(0x34f00000,0x00000000)}},
+ {VT_exponent,22,0x3a8626,{DOUBLEWITHTWODWORDINTREE(0x35000000,0x00000000)}},
+ {VT_exponent,22,0x3a8627,{DOUBLEWITHTWODWORDINTREE(0x35100000,0x00000000)}},
+ {VT_exponent,22,0x3a8628,{DOUBLEWITHTWODWORDINTREE(0x35200000,0x00000000)}},
+ {VT_exponent,22,0x3a8629,{DOUBLEWITHTWODWORDINTREE(0x35300000,0x00000000)}},
+ {VT_exponent,18,0xf787,{DOUBLEWITHTWODWORDINTREE(0x35400000,0x00000000)}},
+ {VT_exponent,18,0xd1d4,{DOUBLEWITHTWODWORDINTREE(0x35500000,0x00000000)}},
+ {VT_exponent,19,0x77f9f,{DOUBLEWITHTWODWORDINTREE(0x35600000,0x00000000)}},
+ {VT_exponent,18,0x3b8fb,{DOUBLEWITHTWODWORDINTREE(0x35700000,0x00000000)}},
+ {VT_exponent,19,0x1ef1a,{DOUBLEWITHTWODWORDINTREE(0x35800000,0x00000000)}},
+ {VT_exponent,21,0x1d4315,{DOUBLEWITHTWODWORDINTREE(0x35900000,0x00000000)}},
+ {VT_exponent,16,0x3de2,{DOUBLEWITHTWODWORDINTREE(0x35a00000,0x00000000)}},
+ {VT_exponent,22,0x3a862c,{DOUBLEWITHTWODWORDINTREE(0x35b00000,0x00000000)}},
+ {VT_exponent,22,0x3a862d,{DOUBLEWITHTWODWORDINTREE(0x35c00000,0x00000000)}},
+ {VT_exponent,22,0x3a862e,{DOUBLEWITHTWODWORDINTREE(0x35d00000,0x00000000)}},
+ {VT_exponent,22,0x3a862f,{DOUBLEWITHTWODWORDINTREE(0x35e00000,0x00000000)}},
+ {VT_exponent,22,0x3a8630,{DOUBLEWITHTWODWORDINTREE(0x35f00000,0x00000000)}},
+ {VT_exponent,22,0x3a8631,{DOUBLEWITHTWODWORDINTREE(0x36000000,0x00000000)}},
+ {VT_exponent,22,0x3a8632,{DOUBLEWITHTWODWORDINTREE(0x36100000,0x00000000)}},
+ {VT_exponent,22,0x3a8633,{DOUBLEWITHTWODWORDINTREE(0x36200000,0x00000000)}},
+ {VT_exponent,22,0x3a8634,{DOUBLEWITHTWODWORDINTREE(0x36300000,0x00000000)}},
+ {VT_exponent,22,0x3a8635,{DOUBLEWITHTWODWORDINTREE(0x36400000,0x00000000)}},
+ {VT_exponent,22,0x3a8636,{DOUBLEWITHTWODWORDINTREE(0x36500000,0x00000000)}},
+ {VT_exponent,22,0x3a8637,{DOUBLEWITHTWODWORDINTREE(0x36600000,0x00000000)}},
+ {VT_exponent,22,0x3a8638,{DOUBLEWITHTWODWORDINTREE(0x36700000,0x00000000)}},
+ {VT_exponent,21,0x1d431d,{DOUBLEWITHTWODWORDINTREE(0x36800000,0x00000000)}},
+ {VT_exponent,22,0x3a8639,{DOUBLEWITHTWODWORDINTREE(0x36900000,0x00000000)}},
+ {VT_exponent,22,0x3a863c,{DOUBLEWITHTWODWORDINTREE(0x36a00000,0x00000000)}},
+ {VT_exponent,16,0x3de0,{DOUBLEWITHTWODWORDINTREE(0x36b00000,0x00000000)}},
+ {VT_exponent,18,0x3a95e,{DOUBLEWITHTWODWORDINTREE(0x36c00000,0x00000000)}},
+ {VT_exponent,21,0x1d431f,{DOUBLEWITHTWODWORDINTREE(0x36d00000,0x00000000)}},
+ {VT_exponent,22,0x3a863d,{DOUBLEWITHTWODWORDINTREE(0x36e00000,0x00000000)}},
+ {VT_exponent,22,0x3a8640,{DOUBLEWITHTWODWORDINTREE(0x36f00000,0x00000000)}},
+ {VT_exponent,20,0x34749,{DOUBLEWITHTWODWORDINTREE(0x37000000,0x00000000)}},
+ {VT_exponent,20,0x3474d,{DOUBLEWITHTWODWORDINTREE(0x37100000,0x00000000)}},
+ {VT_exponent,22,0x3a8641,{DOUBLEWITHTWODWORDINTREE(0x37200000,0x00000000)}},
+ {VT_exponent,22,0x3a8642,{DOUBLEWITHTWODWORDINTREE(0x37300000,0x00000000)}},
+ {VT_exponent,22,0x3a8643,{DOUBLEWITHTWODWORDINTREE(0x37400000,0x00000000)}},
+ {VT_exponent,22,0x3a8644,{DOUBLEWITHTWODWORDINTREE(0x37500000,0x00000000)}},
+ {VT_exponent,22,0x3a8645,{DOUBLEWITHTWODWORDINTREE(0x37600000,0x00000000)}},
+ {VT_exponent,22,0x3a8646,{DOUBLEWITHTWODWORDINTREE(0x37700000,0x00000000)}},
+ {VT_exponent,22,0x3a8647,{DOUBLEWITHTWODWORDINTREE(0x37800000,0x00000000)}},
+ {VT_exponent,22,0x3a8648,{DOUBLEWITHTWODWORDINTREE(0x37900000,0x00000000)}},
+ {VT_exponent,22,0x3a8649,{DOUBLEWITHTWODWORDINTREE(0x37a00000,0x00000000)}},
+ {VT_exponent,22,0x3a864a,{DOUBLEWITHTWODWORDINTREE(0x37b00000,0x00000000)}},
+ {VT_exponent,22,0x3a864b,{DOUBLEWITHTWODWORDINTREE(0x37c00000,0x00000000)}},
+ {VT_exponent,22,0x3a864c,{DOUBLEWITHTWODWORDINTREE(0x37d00000,0x00000000)}},
+ {VT_exponent,22,0x3a864d,{DOUBLEWITHTWODWORDINTREE(0x37e00000,0x00000000)}},
+ {VT_exponent,22,0x3a864e,{DOUBLEWITHTWODWORDINTREE(0x37f00000,0x00000000)}},
+ {VT_exponent,22,0x3a864f,{DOUBLEWITHTWODWORDINTREE(0x38000000,0x00000000)}},
+ {VT_exponent,22,0x3a8650,{DOUBLEWITHTWODWORDINTREE(0x38100000,0x00000000)}},
+ {VT_exponent,22,0x3a8651,{DOUBLEWITHTWODWORDINTREE(0x38200000,0x00000000)}},
+ {VT_exponent,22,0x3a8652,{DOUBLEWITHTWODWORDINTREE(0x38300000,0x00000000)}},
+ {VT_exponent,22,0x3a8653,{DOUBLEWITHTWODWORDINTREE(0x38400000,0x00000000)}},
+ {VT_exponent,22,0x3a8654,{DOUBLEWITHTWODWORDINTREE(0x38500000,0x00000000)}},
+ {VT_exponent,22,0x3a8655,{DOUBLEWITHTWODWORDINTREE(0x38600000,0x00000000)}},
+ {VT_exponent,22,0x3a8656,{DOUBLEWITHTWODWORDINTREE(0x38700000,0x00000000)}},
+ {VT_exponent,22,0x3a8657,{DOUBLEWITHTWODWORDINTREE(0x38800000,0x00000000)}},
+ {VT_exponent,22,0x3a8658,{DOUBLEWITHTWODWORDINTREE(0x38900000,0x00000000)}},
+ {VT_exponent,22,0x3a8659,{DOUBLEWITHTWODWORDINTREE(0x38a00000,0x00000000)}},
+ {VT_exponent,22,0x3a865a,{DOUBLEWITHTWODWORDINTREE(0x38b00000,0x00000000)}},
+ {VT_exponent,22,0x3a865b,{DOUBLEWITHTWODWORDINTREE(0x38c00000,0x00000000)}},
+ {VT_exponent,22,0x3a865c,{DOUBLEWITHTWODWORDINTREE(0x38d00000,0x00000000)}},
+ {VT_exponent,22,0x3a865d,{DOUBLEWITHTWODWORDINTREE(0x38e00000,0x00000000)}},
+ {VT_exponent,21,0x1d432f,{DOUBLEWITHTWODWORDINTREE(0x38f00000,0x00000000)}},
+ {VT_exponent,22,0x3a8660,{DOUBLEWITHTWODWORDINTREE(0x39000000,0x00000000)}},
+ {VT_exponent,22,0x3a8661,{DOUBLEWITHTWODWORDINTREE(0x39100000,0x00000000)}},
+ {VT_exponent,22,0x3a8662,{DOUBLEWITHTWODWORDINTREE(0x39200000,0x00000000)}},
+ {VT_exponent,21,0x1d4332,{DOUBLEWITHTWODWORDINTREE(0x39300000,0x00000000)}},
+ {VT_exponent,18,0xd1d5,{DOUBLEWITHTWODWORDINTREE(0x39400000,0x00000000)}},
+ {VT_exponent,18,0x3bfda,{DOUBLEWITHTWODWORDINTREE(0x39500000,0x00000000)}},
+ {VT_exponent,15,0x7528,{DOUBLEWITHTWODWORDINTREE(0x39600000,0x00000000)}},
+ {VT_exponent,15,0x7529,{DOUBLEWITHTWODWORDINTREE(0x39700000,0x00000000)}},
+ {VT_exponent,18,0x3a95f,{DOUBLEWITHTWODWORDINTREE(0x39800000,0x00000000)}},
+ {VT_exponent,17,0x1d434,{DOUBLEWITHTWODWORDINTREE(0x39900000,0x00000000)}},
+ {VT_exponent,19,0x750cd,{DOUBLEWITHTWODWORDINTREE(0x39a00000,0x00000000)}},
+ {VT_exponent,18,0x3a867,{DOUBLEWITHTWODWORDINTREE(0x39b00000,0x00000000)}},
+ {VT_exponent,19,0x771fd,{DOUBLEWITHTWODWORDINTREE(0x39c00000,0x00000000)}},
+ {VT_exponent,15,0x7764,{DOUBLEWITHTWODWORDINTREE(0x39d00000,0x00000000)}},
+ {VT_exponent,20,0xee3f9,{DOUBLEWITHTWODWORDINTREE(0x39e00000,0x00000000)}},
+ {VT_exponent,18,0x3bfdb,{DOUBLEWITHTWODWORDINTREE(0x39f00000,0x00000000)}},
+ {VT_exponent,16,0xeff7,{DOUBLEWITHTWODWORDINTREE(0x3a000000,0x00000000)}},
+ {VT_exponent,18,0xd1d6,{DOUBLEWITHTWODWORDINTREE(0x3a100000,0x00000000)}},
+ {VT_exponent,22,0x3a8663,{DOUBLEWITHTWODWORDINTREE(0x3a200000,0x00000000)}},
+ {VT_exponent,22,0x3a8666,{DOUBLEWITHTWODWORDINTREE(0x3a300000,0x00000000)}},
+ {VT_exponent,18,0x3b8fa,{DOUBLEWITHTWODWORDINTREE(0x3a400000,0x00000000)}},
+ {VT_exponent,17,0x1d435,{DOUBLEWITHTWODWORDINTREE(0x3a500000,0x00000000)}},
+ {VT_exponent,17,0x1dfe4,{DOUBLEWITHTWODWORDINTREE(0x3a600000,0x00000000)}},
+ {VT_exponent,19,0x750d8,{DOUBLEWITHTWODWORDINTREE(0x3a700000,0x00000000)}},
+ {VT_exponent,18,0x3a95b,{DOUBLEWITHTWODWORDINTREE(0x3a800000,0x00000000)}},
+ {VT_exponent,19,0x77f9e,{DOUBLEWITHTWODWORDINTREE(0x3a900000,0x00000000)}},
+ {VT_exponent,19,0x750d9,{DOUBLEWITHTWODWORDINTREE(0x3aa00000,0x00000000)}},
+ {VT_exponent,18,0xd1d7,{DOUBLEWITHTWODWORDINTREE(0x3ab00000,0x00000000)}},
+ {VT_exponent,18,0x3b8ff,{DOUBLEWITHTWODWORDINTREE(0x3ac00000,0x00000000)}},
+ {VT_exponent,17,0x1dc7c,{DOUBLEWITHTWODWORDINTREE(0x3ad00000,0x00000000)}},
+ {VT_exponent,19,0x750da,{DOUBLEWITHTWODWORDINTREE(0x3ae00000,0x00000000)}},
+ {VT_exponent,17,0x7bc2,{DOUBLEWITHTWODWORDINTREE(0x3af00000,0x00000000)}},
+ {VT_exponent,18,0x3bfca,{DOUBLEWITHTWODWORDINTREE(0x3b000000,0x00000000)}},
+ {VT_exponent,19,0x1a3a5,{DOUBLEWITHTWODWORDINTREE(0x3b100000,0x00000000)}},
+ {VT_exponent,17,0x1d4ac,{DOUBLEWITHTWODWORDINTREE(0x3b200000,0x00000000)}},
+ {VT_exponent,18,0x3a86e,{DOUBLEWITHTWODWORDINTREE(0x3b300000,0x00000000)}},
+ {VT_exponent,17,0x1d438,{DOUBLEWITHTWODWORDINTREE(0x3b400000,0x00000000)}},
+ {VT_exponent,18,0x3bfcb,{DOUBLEWITHTWODWORDINTREE(0x3b500000,0x00000000)}},
+ {VT_exponent,19,0x1a3a7,{DOUBLEWITHTWODWORDINTREE(0x3b600000,0x00000000)}},
+ {VT_exponent,17,0x1d4ae,{DOUBLEWITHTWODWORDINTREE(0x3b700000,0x00000000)}},
+ {VT_exponent,18,0x3bfce,{DOUBLEWITHTWODWORDINTREE(0x3b800000,0x00000000)}},
+ {VT_exponent,18,0xf78c,{DOUBLEWITHTWODWORDINTREE(0x3b900000,0x00000000)}},
+ {VT_exponent,17,0x1dfec,{DOUBLEWITHTWODWORDINTREE(0x3ba00000,0x00000000)}},
+ {VT_exponent,17,0x1d439,{DOUBLEWITHTWODWORDINTREE(0x3bb00000,0x00000000)}},
+ {VT_exponent,17,0x68e8,{DOUBLEWITHTWODWORDINTREE(0x3bc00000,0x00000000)}},
+ {VT_exponent,18,0xf786,{DOUBLEWITHTWODWORDINTREE(0x3bd00000,0x00000000)}},
+ {VT_exponent,15,0x771e,{DOUBLEWITHTWODWORDINTREE(0x3be00000,0x00000000)}},
+ {VT_exponent,17,0x1dfe6,{DOUBLEWITHTWODWORDINTREE(0x3bf00000,0x00000000)}},
+ {VT_exponent,15,0x77f8,{DOUBLEWITHTWODWORDINTREE(0x3c000000,0x00000000)}},
+ {VT_exponent,14,0x3bb3,{DOUBLEWITHTWODWORDINTREE(0x3c100000,0x00000000)}},
+ {VT_exponent,14,0x3b8e,{DOUBLEWITHTWODWORDINTREE(0x3c200000,0x00000000)}},
+ {VT_exponent,14,0x3a82,{DOUBLEWITHTWODWORDINTREE(0x3c300000,0x00000000)}},
+ {VT_exponent,14,0x3b96,{DOUBLEWITHTWODWORDINTREE(0x3c400000,0x00000000)}},
+ {VT_exponent,13,0x68f,{DOUBLEWITHTWODWORDINTREE(0x3c500000,0x00000000)}},
+ {VT_exponent,12,0x3d4,{DOUBLEWITHTWODWORDINTREE(0x3c600000,0x00000000)}},
+ {VT_exponent,13,0x1dca,{DOUBLEWITHTWODWORDINTREE(0x3c700000,0x00000000)}},
+ {VT_exponent,12,0x346,{DOUBLEWITHTWODWORDINTREE(0x3c800000,0x00000000)}},
+ {VT_exponent,12,0xee7,{DOUBLEWITHTWODWORDINTREE(0x3c900000,0x00000000)}},
+ {VT_exponent,12,0xeea,{DOUBLEWITHTWODWORDINTREE(0x3ca00000,0x00000000)}},
+ {VT_exponent,11,0x1ed,{DOUBLEWITHTWODWORDINTREE(0x3cb00000,0x00000000)}},
+ {VT_exponent,12,0x3df,{DOUBLEWITHTWODWORDINTREE(0x3cc00000,0x00000000)}},
+ {VT_exponent,11,0x1a2,{DOUBLEWITHTWODWORDINTREE(0x3cd00000,0x00000000)}},
+ {VT_exponent,11,0x56f,{DOUBLEWITHTWODWORDINTREE(0x3ce00000,0x00000000)}},
+ {VT_exponent,11,0xb9,{DOUBLEWITHTWODWORDINTREE(0x3cf00000,0x00000000)}},
+ {VT_exponent,13,0x7b2,{DOUBLEWITHTWODWORDINTREE(0x3d000000,0x00000000)}},
+ {VT_exponent,13,0x1dd8,{DOUBLEWITHTWODWORDINTREE(0x3d100000,0x00000000)}},
+ {VT_exponent,13,0x15ba,{DOUBLEWITHTWODWORDINTREE(0x3d200000,0x00000000)}},
+ {VT_exponent,12,0xee6,{DOUBLEWITHTWODWORDINTREE(0x3d300000,0x00000000)}},
+ {VT_exponent,13,0x15b8,{DOUBLEWITHTWODWORDINTREE(0x3d400000,0x00000000)}},
+ {VT_exponent,14,0xf79,{DOUBLEWITHTWODWORDINTREE(0x3d500000,0x00000000)}},
+ {VT_exponent,14,0x3a81,{DOUBLEWITHTWODWORDINTREE(0x3d600000,0x00000000)}},
+ {VT_exponent,14,0xd1c,{DOUBLEWITHTWODWORDINTREE(0x3d700000,0x00000000)}},
+ {VT_exponent,15,0x7765,{DOUBLEWITHTWODWORDINTREE(0x3d800000,0x00000000)}},
+ {VT_exponent,14,0xf54,{DOUBLEWITHTWODWORDINTREE(0x3d900000,0x00000000)}},
+ {VT_exponent,13,0x15b9,{DOUBLEWITHTWODWORDINTREE(0x3da00000,0x00000000)}},
+ {VT_exponent,13,0x7ab,{DOUBLEWITHTWODWORDINTREE(0x3db00000,0x00000000)}},
+ {VT_exponent,15,0x7500,{DOUBLEWITHTWODWORDINTREE(0x3dc00000,0x00000000)}},
+ {VT_exponent,15,0x1eaa,{DOUBLEWITHTWODWORDINTREE(0x3dd00000,0x00000000)}},
+ {VT_exponent,15,0x7501,{DOUBLEWITHTWODWORDINTREE(0x3de00000,0x00000000)}},
+ {VT_exponent,15,0x1eab,{DOUBLEWITHTWODWORDINTREE(0x3df00000,0x00000000)}},
+ {VT_exponent,14,0x3b97,{DOUBLEWITHTWODWORDINTREE(0x3e000000,0x00000000)}},
+ {VT_exponent,15,0x752a,{DOUBLEWITHTWODWORDINTREE(0x3e100000,0x00000000)}},
+ {VT_exponent,15,0x77fa,{DOUBLEWITHTWODWORDINTREE(0x3e200000,0x00000000)}},
+ {VT_double,10,0xf4,{DOUBLEWITHTWODWORDINTREE(0x3e35798e,0xe2308c3a)}},
+ {VT_exponent,14,0x3a93,{DOUBLEWITHTWODWORDINTREE(0x3e300000,0x00000000)}},
+ {VT_double,11,0x77c,{DOUBLEWITHTWODWORDINTREE(0x3e45798e,0xe2308c3a)}},
+ {VT_exponent,13,0x1dc6,{DOUBLEWITHTWODWORDINTREE(0x3e400000,0x00000000)}},
+ {VT_exponent,13,0x7bd,{DOUBLEWITHTWODWORDINTREE(0x3e500000,0x00000000)}},
+ {VT_exponent,13,0x1dff,{DOUBLEWITHTWODWORDINTREE(0x3e600000,0x00000000)}},
+ {VT_exponent,12,0xefe,{DOUBLEWITHTWODWORDINTREE(0x3e700000,0x00000000)}},
+ {VT_double,8,0xaf,{DOUBLEWITHTWODWORDINTREE(0x3e8ad7f2,0x9abcaf4a)}},
+ {VT_exponent,12,0xeed,{DOUBLEWITHTWODWORDINTREE(0x3e800000,0x00000000)}},
+ {VT_exponent,11,0xb8,{DOUBLEWITHTWODWORDINTREE(0x3e900000,0x00000000)}},
+ {VT_exponent,12,0x3d8,{DOUBLEWITHTWODWORDINTREE(0x3ea00000,0x00000000)}},
+ {VT_exponent,11,0x1eb,{DOUBLEWITHTWODWORDINTREE(0x3eb00000,0x00000000)}},
+ {VT_double,9,0x1d2,{DOUBLEWITHTWODWORDINTREE(0x3ec0c6f7,0xa0b5ed8e)}},
+ {VT_exponent,13,0x1d4b,{DOUBLEWITHTWODWORDINTREE(0x3ec00000,0x00000000)}},
+ {VT_exponent,13,0x7b3,{DOUBLEWITHTWODWORDINTREE(0x3ed00000,0x00000000)}},
+ {VT_exponent,10,0x5d,{DOUBLEWITHTWODWORDINTREE(0x3ee00000,0x00000000)}},
+ {VT_exponent,12,0xeeb,{DOUBLEWITHTWODWORDINTREE(0x3ef00000,0x00000000)}},
+ {VT_exponent,11,0x1ee,{DOUBLEWITHTWODWORDINTREE(0x3f000000,0x00000000)}},
+ {VT_exponent,10,0x5f,{DOUBLEWITHTWODWORDINTREE(0x3f100000,0x00000000)}},
+ {VT_exponent,10,0x2b6,{DOUBLEWITHTWODWORDINTREE(0x3f200000,0x00000000)}},
+ {VT_exponent,9,0x1de,{DOUBLEWITHTWODWORDINTREE(0x3f300000,0x00000000)}},
+ {VT_double,10,0xd0,{DOUBLEWITHTWODWORDINTREE(0x3f454c98,0x5f06f694)}},
+ {VT_double,6,0x9,{DOUBLEWITHTWODWORDINTREE(0x3f4a36e2,0xeb1c432d)}},
+ {VT_exponent,8,0xe8,{DOUBLEWITHTWODWORDINTREE(0x3f400000,0x00000000)}},
+ {VT_double,4,0xf,{DOUBLEWITHTWODWORDINTREE(0x3f50624d,0xd2f1a9fc)}},
+ {VT_exponent,8,0xae,{DOUBLEWITHTWODWORDINTREE(0x3f500000,0x00000000)}},
+ {VT_double,5,0x16,{DOUBLEWITHTWODWORDINTREE(0x3f60624d,0xd2f1a9fc)}},
+ {VT_exponent,7,0x1b,{DOUBLEWITHTWODWORDINTREE(0x3f600000,0x00000000)}},
+ {VT_exponent,7,0x76,{DOUBLEWITHTWODWORDINTREE(0x3f700000,0x00000000)}},
+ {VT_exponent,7,0xa,{DOUBLEWITHTWODWORDINTREE(0x3f800000,0x00000000)}},
+ {VT_exponent,6,0x8,{DOUBLEWITHTWODWORDINTREE(0x3f900000,0x00000000)}},
+ {VT_exponent,6,0xe,{DOUBLEWITHTWODWORDINTREE(0x3fa00000,0x00000000)}},
+ {VT_double,11,0x751,{DOUBLEWITHTWODWORDINTREE(0x3fbe69ad,0x42c3c9ee)}},
+ {VT_exponent,6,0x4,{DOUBLEWITHTWODWORDINTREE(0x3fb00000,0x00000000)}},
+ {VT_exponent,6,0xc,{DOUBLEWITHTWODWORDINTREE(0x3fc00000,0x00000000)}},
+ {VT_exponent,5,0x3,{DOUBLEWITHTWODWORDINTREE(0x3fd00000,0x00000000)}},
+ {VT_double,11,0x777,{DOUBLEWITHTWODWORDINTREE(0x3fe00000,0x00000000)}},
+ {VT_double,9,0x1d6,{DOUBLEWITHTWODWORDINTREE(0x3fefffff,0xf8000002)}},
+ {VT_exponent,4,0x8,{DOUBLEWITHTWODWORDINTREE(0x3fe00000,0x00000000)}},
+ {VT_double,4,0x0,{DOUBLEWITHTWODWORDINTREE(0x3ff00000,0x00000000)}},
+ {VT_exponent,5,0x13,{DOUBLEWITHTWODWORDINTREE(0x3ff00000,0x00000000)}},
+ {VT_exponent,5,0x1b,{DOUBLEWITHTWODWORDINTREE(0x40000000,0x00000000)}},
+ {VT_double,9,0x15a,{DOUBLEWITHTWODWORDINTREE(0x401921fb,0x54442d18)}},
+ {VT_exponent,5,0x17,{DOUBLEWITHTWODWORDINTREE(0x40100000,0x00000000)}},
+ {VT_exponent,5,0x12,{DOUBLEWITHTWODWORDINTREE(0x40200000,0x00000000)}},
+ {VT_double,11,0x774,{DOUBLEWITHTWODWORDINTREE(0x4035ee14,0x80000000)}},
+ {VT_exponent,5,0x19,{DOUBLEWITHTWODWORDINTREE(0x40300000,0x00000000)}},
+ {VT_double,9,0x1d3,{DOUBLEWITHTWODWORDINTREE(0x404ca5dc,0x1a63c1f8)}},
+ {VT_exponent,5,0x1a,{DOUBLEWITHTWODWORDINTREE(0x40400000,0x00000000)}},
+ {VT_double,11,0x77e,{DOUBLEWITHTWODWORDINTREE(0x405bb32f,0xe0000000)}},
+ {VT_double,10,0x5e,{DOUBLEWITHTWODWORDINTREE(0x405c332f,0xe0000000)}},
+ {VT_exponent,5,0x18,{DOUBLEWITHTWODWORDINTREE(0x40500000,0x00000000)}},
+ {VT_double,9,0x1d7,{DOUBLEWITHTWODWORDINTREE(0x40668000,0x00000000)}},
+ {VT_exponent,5,0x1c,{DOUBLEWITHTWODWORDINTREE(0x40600000,0x00000000)}},
+ {VT_double,9,0x1d5,{DOUBLEWITHTWODWORDINTREE(0x40768000,0x00000000)}},
+ {VT_exponent,5,0x14,{DOUBLEWITHTWODWORDINTREE(0x40700000,0x00000000)}},
+ {VT_double,11,0x77d,{DOUBLEWITHTWODWORDINTREE(0x408f4000,0x00000000)}},
+ {VT_exponent,5,0x5,{DOUBLEWITHTWODWORDINTREE(0x40800000,0x00000000)}},
+ {VT_double,10,0xd2,{DOUBLEWITHTWODWORDINTREE(0x409233ff,0xffffffff)}},
+ {VT_double,8,0x3c,{DOUBLEWITHTWODWORDINTREE(0x40923400,0x00000000)}},
+ {VT_double,11,0x753,{DOUBLEWITHTWODWORDINTREE(0x40923400,0x00000001)}},
+ {VT_double,10,0xd3,{DOUBLEWITHTWODWORDINTREE(0x4092abff,0xffffffff)}},
+ {VT_double,8,0x35,{DOUBLEWITHTWODWORDINTREE(0x4092ac00,0x00000000)}},
+ {VT_double,11,0x770,{DOUBLEWITHTWODWORDINTREE(0x4092ac00,0x00000001)}},
+ {VT_exponent,8,0x16,{DOUBLEWITHTWODWORDINTREE(0x40900000,0x00000000)}},
+ {VT_exponent,12,0xee2,{DOUBLEWITHTWODWORDINTREE(0x40a00000,0x00000000)}},
+ {VT_exponent,12,0xee4,{DOUBLEWITHTWODWORDINTREE(0x40b00000,0x00000000)}},
+ {VT_double,7,0x1f,{DOUBLEWITHTWODWORDINTREE(0x40c81c80,0x00000000)}},
+ {VT_exponent,8,0xac,{DOUBLEWITHTWODWORDINTREE(0x40c00000,0x00000000)}},
+ {VT_exponent,13,0x15bb,{DOUBLEWITHTWODWORDINTREE(0x40d00000,0x00000000)}},
+ {VT_exponent,22,0x3a8667,{DOUBLEWITHTWODWORDINTREE(0x40e00000,0x00000000)}},
+ {VT_exponent,22,0x3a86d8,{DOUBLEWITHTWODWORDINTREE(0x40f00000,0x00000000)}},
+ {VT_exponent,22,0x3a86d9,{DOUBLEWITHTWODWORDINTREE(0x41000000,0x00000000)}},
+ {VT_exponent,22,0x3a86da,{DOUBLEWITHTWODWORDINTREE(0x41100000,0x00000000)}},
+ {VT_exponent,17,0x1dc7e,{DOUBLEWITHTWODWORDINTREE(0x41200000,0x00000000)}},
+ {VT_exponent,22,0x3a86db,{DOUBLEWITHTWODWORDINTREE(0x41300000,0x00000000)}},
+ {VT_exponent,22,0x3a86dc,{DOUBLEWITHTWODWORDINTREE(0x41400000,0x00000000)}},
+ {VT_exponent,22,0x3a86dd,{DOUBLEWITHTWODWORDINTREE(0x41500000,0x00000000)}},
+ {VT_exponent,22,0x3a86de,{DOUBLEWITHTWODWORDINTREE(0x41600000,0x00000000)}},
+ {VT_exponent,22,0x3a86df,{DOUBLEWITHTWODWORDINTREE(0x41700000,0x00000000)}},
+ {VT_exponent,22,0x3a86f0,{DOUBLEWITHTWODWORDINTREE(0x41800000,0x00000000)}},
+ {VT_exponent,22,0x3a86f1,{DOUBLEWITHTWODWORDINTREE(0x41900000,0x00000000)}},
+ {VT_exponent,22,0x3a86f2,{DOUBLEWITHTWODWORDINTREE(0x41a00000,0x00000000)}},
+ {VT_exponent,22,0x3a86f3,{DOUBLEWITHTWODWORDINTREE(0x41b00000,0x00000000)}},
+ {VT_double,6,0x2a,{DOUBLEWITHTWODWORDINTREE(0x41cdcd64,0xff800000)}},
+ {VT_exponent,22,0x3a86f4,{DOUBLEWITHTWODWORDINTREE(0x41c00000,0x00000000)}},
+ {VT_exponent,22,0x3a86f5,{DOUBLEWITHTWODWORDINTREE(0x41d00000,0x00000000)}},
+ {VT_exponent,22,0x3a86f6,{DOUBLEWITHTWODWORDINTREE(0x41e00000,0x00000000)}},
+ {VT_exponent,22,0x3a86f7,{DOUBLEWITHTWODWORDINTREE(0x41f00000,0x00000000)}},
+ {VT_exponent,22,0x3a86f8,{DOUBLEWITHTWODWORDINTREE(0x42000000,0x00000000)}},
+ {VT_exponent,22,0x3a86f9,{DOUBLEWITHTWODWORDINTREE(0x42100000,0x00000000)}},
+ {VT_exponent,22,0x3a86fa,{DOUBLEWITHTWODWORDINTREE(0x42200000,0x00000000)}},
+ {VT_exponent,22,0x3a86fb,{DOUBLEWITHTWODWORDINTREE(0x42300000,0x00000000)}},
+ {VT_exponent,22,0x3a86fc,{DOUBLEWITHTWODWORDINTREE(0x42400000,0x00000000)}},
+ {VT_exponent,22,0x3a86fd,{DOUBLEWITHTWODWORDINTREE(0x42500000,0x00000000)}},
+ {VT_exponent,22,0x3a86fe,{DOUBLEWITHTWODWORDINTREE(0x42600000,0x00000000)}},
+ {VT_exponent,22,0x3a86ff,{DOUBLEWITHTWODWORDINTREE(0x42700000,0x00000000)}},
+ {VT_exponent,22,0x3a8740,{DOUBLEWITHTWODWORDINTREE(0x42800000,0x00000000)}},
+ {VT_exponent,22,0x3a8741,{DOUBLEWITHTWODWORDINTREE(0x42900000,0x00000000)}},
+ {VT_exponent,22,0x3a8742,{DOUBLEWITHTWODWORDINTREE(0x42a00000,0x00000000)}},
+ {VT_exponent,22,0x3a8743,{DOUBLEWITHTWODWORDINTREE(0x42b00000,0x00000000)}},
+ {VT_exponent,22,0x3a8744,{DOUBLEWITHTWODWORDINTREE(0x42c00000,0x00000000)}},
+ {VT_exponent,22,0x3a8745,{DOUBLEWITHTWODWORDINTREE(0x42d00000,0x00000000)}},
+ {VT_exponent,22,0x3a8746,{DOUBLEWITHTWODWORDINTREE(0x42e00000,0x00000000)}},
+ {VT_exponent,22,0x3a8747,{DOUBLEWITHTWODWORDINTREE(0x42f00000,0x00000000)}},
+ {VT_exponent,22,0x3a8748,{DOUBLEWITHTWODWORDINTREE(0x43000000,0x00000000)}},
+ {VT_exponent,22,0x3a8749,{DOUBLEWITHTWODWORDINTREE(0x43100000,0x00000000)}},
+ {VT_exponent,22,0x3a874a,{DOUBLEWITHTWODWORDINTREE(0x43200000,0x00000000)}},
+ {VT_exponent,22,0x3a874b,{DOUBLEWITHTWODWORDINTREE(0x43300000,0x00000000)}},
+ {VT_exponent,22,0x3a874c,{DOUBLEWITHTWODWORDINTREE(0x43400000,0x00000000)}},
+ {VT_exponent,22,0x3a874d,{DOUBLEWITHTWODWORDINTREE(0x43500000,0x00000000)}},
+ {VT_exponent,22,0x3a874e,{DOUBLEWITHTWODWORDINTREE(0x43600000,0x00000000)}},
+ {VT_exponent,22,0x3a874f,{DOUBLEWITHTWODWORDINTREE(0x43700000,0x00000000)}},
+ {VT_exponent,22,0x3a8750,{DOUBLEWITHTWODWORDINTREE(0x43800000,0x00000000)}},
+ {VT_exponent,22,0x3a8751,{DOUBLEWITHTWODWORDINTREE(0x43900000,0x00000000)}},
+ {VT_exponent,22,0x3a8752,{DOUBLEWITHTWODWORDINTREE(0x43a00000,0x00000000)}},
+ {VT_exponent,22,0x3a8753,{DOUBLEWITHTWODWORDINTREE(0x43b00000,0x00000000)}},
+ {VT_exponent,22,0x3a8754,{DOUBLEWITHTWODWORDINTREE(0x43c00000,0x00000000)}},
+ {VT_exponent,22,0x3a8755,{DOUBLEWITHTWODWORDINTREE(0x43d00000,0x00000000)}},
+ {VT_exponent,22,0x3a8756,{DOUBLEWITHTWODWORDINTREE(0x43e00000,0x00000000)}},
+ {VT_exponent,22,0x3a8757,{DOUBLEWITHTWODWORDINTREE(0x43f00000,0x00000000)}},
+ {VT_exponent,22,0x3a8758,{DOUBLEWITHTWODWORDINTREE(0x44000000,0x00000000)}},
+ {VT_exponent,15,0x1a3b,{DOUBLEWITHTWODWORDINTREE(0x44100000,0x00000000)}},
+ {VT_exponent,22,0x3a8759,{DOUBLEWITHTWODWORDINTREE(0x44200000,0x00000000)}},
+ {VT_exponent,22,0x3a875a,{DOUBLEWITHTWODWORDINTREE(0x44300000,0x00000000)}},
+ {VT_exponent,22,0x3a875b,{DOUBLEWITHTWODWORDINTREE(0x44400000,0x00000000)}},
+ {VT_exponent,22,0x3a875c,{DOUBLEWITHTWODWORDINTREE(0x44500000,0x00000000)}},
+ {VT_exponent,22,0x3a875d,{DOUBLEWITHTWODWORDINTREE(0x44600000,0x00000000)}},
+ {VT_exponent,22,0x3a875e,{DOUBLEWITHTWODWORDINTREE(0x44700000,0x00000000)}},
+ {VT_exponent,22,0x3a875f,{DOUBLEWITHTWODWORDINTREE(0x44800000,0x00000000)}},
+ {VT_exponent,22,0x3a8760,{DOUBLEWITHTWODWORDINTREE(0x44900000,0x00000000)}},
+ {VT_exponent,22,0x3a8761,{DOUBLEWITHTWODWORDINTREE(0x44a00000,0x00000000)}},
+ {VT_exponent,22,0x3a8762,{DOUBLEWITHTWODWORDINTREE(0x44b00000,0x00000000)}},
+ {VT_exponent,22,0x3a8763,{DOUBLEWITHTWODWORDINTREE(0x44c00000,0x00000000)}},
+ {VT_exponent,22,0x3a8764,{DOUBLEWITHTWODWORDINTREE(0x44d00000,0x00000000)}},
+ {VT_exponent,22,0x3a8765,{DOUBLEWITHTWODWORDINTREE(0x44e00000,0x00000000)}},
+ {VT_exponent,22,0x3a8766,{DOUBLEWITHTWODWORDINTREE(0x44f00000,0x00000000)}},
+ {VT_exponent,22,0x3a8767,{DOUBLEWITHTWODWORDINTREE(0x45000000,0x00000000)}},
+ {VT_exponent,22,0x3a8768,{DOUBLEWITHTWODWORDINTREE(0x45100000,0x00000000)}},
+ {VT_exponent,22,0x3a8769,{DOUBLEWITHTWODWORDINTREE(0x45200000,0x00000000)}},
+ {VT_exponent,22,0x3a876a,{DOUBLEWITHTWODWORDINTREE(0x45300000,0x00000000)}},
+ {VT_exponent,22,0x3a876b,{DOUBLEWITHTWODWORDINTREE(0x45400000,0x00000000)}},
+ {VT_exponent,22,0x3a876c,{DOUBLEWITHTWODWORDINTREE(0x45500000,0x00000000)}},
+ {VT_exponent,22,0x3a876d,{DOUBLEWITHTWODWORDINTREE(0x45600000,0x00000000)}},
+ {VT_exponent,22,0x3a876e,{DOUBLEWITHTWODWORDINTREE(0x45700000,0x00000000)}},
+ {VT_exponent,22,0x3a876f,{DOUBLEWITHTWODWORDINTREE(0x45800000,0x00000000)}},
+ {VT_exponent,22,0x3a8770,{DOUBLEWITHTWODWORDINTREE(0x45900000,0x00000000)}},
+ {VT_exponent,22,0x3a8771,{DOUBLEWITHTWODWORDINTREE(0x45a00000,0x00000000)}},
+ {VT_exponent,22,0x3a8772,{DOUBLEWITHTWODWORDINTREE(0x45b00000,0x00000000)}},
+ {VT_exponent,22,0x3a8773,{DOUBLEWITHTWODWORDINTREE(0x45c00000,0x00000000)}},
+ {VT_exponent,22,0x3a8774,{DOUBLEWITHTWODWORDINTREE(0x45d00000,0x00000000)}},
+ {VT_exponent,22,0x3a8775,{DOUBLEWITHTWODWORDINTREE(0x45e00000,0x00000000)}},
+ {VT_exponent,22,0x3a8776,{DOUBLEWITHTWODWORDINTREE(0x45f00000,0x00000000)}},
+ {VT_exponent,22,0x3a8777,{DOUBLEWITHTWODWORDINTREE(0x46000000,0x00000000)}},
+ {VT_exponent,22,0x3a8778,{DOUBLEWITHTWODWORDINTREE(0x46100000,0x00000000)}},
+ {VT_exponent,22,0x3a8779,{DOUBLEWITHTWODWORDINTREE(0x46200000,0x00000000)}},
+ {VT_exponent,22,0x3a877a,{DOUBLEWITHTWODWORDINTREE(0x46300000,0x00000000)}},
+ {VT_exponent,22,0x3a877b,{DOUBLEWITHTWODWORDINTREE(0x46400000,0x00000000)}},
+ {VT_exponent,22,0x3a877c,{DOUBLEWITHTWODWORDINTREE(0x46500000,0x00000000)}},
+ {VT_exponent,22,0x3a877d,{DOUBLEWITHTWODWORDINTREE(0x46600000,0x00000000)}},
+ {VT_exponent,22,0x3a877e,{DOUBLEWITHTWODWORDINTREE(0x46700000,0x00000000)}},
+ {VT_exponent,22,0x3a877f,{DOUBLEWITHTWODWORDINTREE(0x46800000,0x00000000)}},
+ {VT_exponent,22,0x3a8780,{DOUBLEWITHTWODWORDINTREE(0x46900000,0x00000000)}},
+ {VT_exponent,22,0x3a8781,{DOUBLEWITHTWODWORDINTREE(0x46a00000,0x00000000)}},
+ {VT_exponent,22,0x3a8782,{DOUBLEWITHTWODWORDINTREE(0x46b00000,0x00000000)}},
+ {VT_exponent,22,0x3a8783,{DOUBLEWITHTWODWORDINTREE(0x46c00000,0x00000000)}},
+ {VT_exponent,22,0x3a8784,{DOUBLEWITHTWODWORDINTREE(0x46d00000,0x00000000)}},
+ {VT_exponent,22,0x3a8785,{DOUBLEWITHTWODWORDINTREE(0x46e00000,0x00000000)}},
+ {VT_exponent,22,0x3a8786,{DOUBLEWITHTWODWORDINTREE(0x46f00000,0x00000000)}},
+ {VT_exponent,22,0x3a8787,{DOUBLEWITHTWODWORDINTREE(0x47000000,0x00000000)}},
+ {VT_exponent,22,0x3a8788,{DOUBLEWITHTWODWORDINTREE(0x47100000,0x00000000)}},
+ {VT_exponent,22,0x3a8789,{DOUBLEWITHTWODWORDINTREE(0x47200000,0x00000000)}},
+ {VT_exponent,22,0x3a878a,{DOUBLEWITHTWODWORDINTREE(0x47300000,0x00000000)}},
+ {VT_exponent,22,0x3a878b,{DOUBLEWITHTWODWORDINTREE(0x47400000,0x00000000)}},
+ {VT_exponent,22,0x3a878c,{DOUBLEWITHTWODWORDINTREE(0x47500000,0x00000000)}},
+ {VT_exponent,22,0x3a878d,{DOUBLEWITHTWODWORDINTREE(0x47600000,0x00000000)}},
+ {VT_exponent,22,0x3a878e,{DOUBLEWITHTWODWORDINTREE(0x47700000,0x00000000)}},
+ {VT_exponent,22,0x3a878f,{DOUBLEWITHTWODWORDINTREE(0x47800000,0x00000000)}},
+ {VT_exponent,22,0x3a8790,{DOUBLEWITHTWODWORDINTREE(0x47900000,0x00000000)}},
+ {VT_exponent,22,0x3a8791,{DOUBLEWITHTWODWORDINTREE(0x47a00000,0x00000000)}},
+ {VT_exponent,22,0x3a8792,{DOUBLEWITHTWODWORDINTREE(0x47b00000,0x00000000)}},
+ {VT_exponent,22,0x3a8793,{DOUBLEWITHTWODWORDINTREE(0x47c00000,0x00000000)}},
+ {VT_exponent,22,0x3a8794,{DOUBLEWITHTWODWORDINTREE(0x47d00000,0x00000000)}},
+ {VT_exponent,22,0x3a8795,{DOUBLEWITHTWODWORDINTREE(0x47e00000,0x00000000)}},
+ {VT_exponent,22,0x3a8796,{DOUBLEWITHTWODWORDINTREE(0x47f00000,0x00000000)}},
+ {VT_exponent,22,0x3a8797,{DOUBLEWITHTWODWORDINTREE(0x48000000,0x00000000)}},
+ {VT_exponent,22,0x3a8798,{DOUBLEWITHTWODWORDINTREE(0x48100000,0x00000000)}},
+ {VT_exponent,22,0x3a8799,{DOUBLEWITHTWODWORDINTREE(0x48200000,0x00000000)}},
+ {VT_exponent,22,0x3a879a,{DOUBLEWITHTWODWORDINTREE(0x48300000,0x00000000)}},
+ {VT_exponent,22,0x3a879b,{DOUBLEWITHTWODWORDINTREE(0x48400000,0x00000000)}},
+ {VT_exponent,22,0x3a879c,{DOUBLEWITHTWODWORDINTREE(0x48500000,0x00000000)}},
+ {VT_exponent,22,0x3a879d,{DOUBLEWITHTWODWORDINTREE(0x48600000,0x00000000)}},
+ {VT_exponent,22,0x3a879e,{DOUBLEWITHTWODWORDINTREE(0x48700000,0x00000000)}},
+ {VT_exponent,22,0x3a879f,{DOUBLEWITHTWODWORDINTREE(0x48800000,0x00000000)}},
+ {VT_exponent,22,0x3a87a0,{DOUBLEWITHTWODWORDINTREE(0x48900000,0x00000000)}},
+ {VT_exponent,22,0x3a87a1,{DOUBLEWITHTWODWORDINTREE(0x48a00000,0x00000000)}},
+ {VT_exponent,22,0x3a87a2,{DOUBLEWITHTWODWORDINTREE(0x48b00000,0x00000000)}},
+ {VT_exponent,22,0x3a87a3,{DOUBLEWITHTWODWORDINTREE(0x48c00000,0x00000000)}},
+ {VT_exponent,22,0x3a87a4,{DOUBLEWITHTWODWORDINTREE(0x48d00000,0x00000000)}},
+ {VT_exponent,22,0x3a87a5,{DOUBLEWITHTWODWORDINTREE(0x48e00000,0x00000000)}},
+ {VT_exponent,22,0x3a87a6,{DOUBLEWITHTWODWORDINTREE(0x48f00000,0x00000000)}},
+ {VT_exponent,22,0x3a87a7,{DOUBLEWITHTWODWORDINTREE(0x49000000,0x00000000)}},
+ {VT_exponent,22,0x3a87a8,{DOUBLEWITHTWODWORDINTREE(0x49100000,0x00000000)}},
+ {VT_exponent,22,0x3a87a9,{DOUBLEWITHTWODWORDINTREE(0x49200000,0x00000000)}},
+ {VT_exponent,22,0x3a87aa,{DOUBLEWITHTWODWORDINTREE(0x49300000,0x00000000)}},
+ {VT_exponent,22,0x3a87ab,{DOUBLEWITHTWODWORDINTREE(0x49400000,0x00000000)}},
+ {VT_exponent,22,0x3a87ac,{DOUBLEWITHTWODWORDINTREE(0x49500000,0x00000000)}},
+ {VT_exponent,22,0x3a87ad,{DOUBLEWITHTWODWORDINTREE(0x49600000,0x00000000)}},
+ {VT_exponent,22,0x3a87ae,{DOUBLEWITHTWODWORDINTREE(0x49700000,0x00000000)}},
+ {VT_exponent,22,0x3a87af,{DOUBLEWITHTWODWORDINTREE(0x49800000,0x00000000)}},
+ {VT_exponent,22,0x3a87b0,{DOUBLEWITHTWODWORDINTREE(0x49900000,0x00000000)}},
+ {VT_exponent,22,0x3a87b1,{DOUBLEWITHTWODWORDINTREE(0x49a00000,0x00000000)}},
+ {VT_exponent,22,0x3a87b2,{DOUBLEWITHTWODWORDINTREE(0x49b00000,0x00000000)}},
+ {VT_exponent,22,0x3a87b3,{DOUBLEWITHTWODWORDINTREE(0x49c00000,0x00000000)}},
+ {VT_exponent,22,0x3a87b4,{DOUBLEWITHTWODWORDINTREE(0x49d00000,0x00000000)}},
+ {VT_exponent,22,0x3a87b5,{DOUBLEWITHTWODWORDINTREE(0x49e00000,0x00000000)}},
+ {VT_exponent,22,0x3a87b6,{DOUBLEWITHTWODWORDINTREE(0x49f00000,0x00000000)}},
+ {VT_exponent,22,0x3a87b7,{DOUBLEWITHTWODWORDINTREE(0x4a000000,0x00000000)}},
+ {VT_exponent,22,0x3a87b8,{DOUBLEWITHTWODWORDINTREE(0x4a100000,0x00000000)}},
+ {VT_exponent,22,0x3a87b9,{DOUBLEWITHTWODWORDINTREE(0x4a200000,0x00000000)}},
+ {VT_exponent,22,0x3a87ba,{DOUBLEWITHTWODWORDINTREE(0x4a300000,0x00000000)}},
+ {VT_exponent,22,0x3a87bb,{DOUBLEWITHTWODWORDINTREE(0x4a400000,0x00000000)}},
+ {VT_exponent,22,0x3a87bc,{DOUBLEWITHTWODWORDINTREE(0x4a500000,0x00000000)}},
+ {VT_exponent,22,0x3a87bd,{DOUBLEWITHTWODWORDINTREE(0x4a600000,0x00000000)}},
+ {VT_exponent,22,0x3a87be,{DOUBLEWITHTWODWORDINTREE(0x4a700000,0x00000000)}},
+ {VT_exponent,22,0x3a87bf,{DOUBLEWITHTWODWORDINTREE(0x4a800000,0x00000000)}},
+ {VT_exponent,22,0x3a87c0,{DOUBLEWITHTWODWORDINTREE(0x4a900000,0x00000000)}},
+ {VT_exponent,22,0x3a87c1,{DOUBLEWITHTWODWORDINTREE(0x4aa00000,0x00000000)}},
+ {VT_exponent,22,0x3a87c2,{DOUBLEWITHTWODWORDINTREE(0x4ab00000,0x00000000)}},
+ {VT_exponent,22,0x3a87c3,{DOUBLEWITHTWODWORDINTREE(0x4ac00000,0x00000000)}},
+ {VT_exponent,22,0x3a87c4,{DOUBLEWITHTWODWORDINTREE(0x4ad00000,0x00000000)}},
+ {VT_exponent,22,0x3a87c5,{DOUBLEWITHTWODWORDINTREE(0x4ae00000,0x00000000)}},
+ {VT_exponent,22,0x3a87c6,{DOUBLEWITHTWODWORDINTREE(0x4af00000,0x00000000)}},
+ {VT_exponent,22,0x3a87c7,{DOUBLEWITHTWODWORDINTREE(0x4b000000,0x00000000)}},
+ {VT_exponent,22,0x3a87c8,{DOUBLEWITHTWODWORDINTREE(0x4b100000,0x00000000)}},
+ {VT_exponent,22,0x3a87c9,{DOUBLEWITHTWODWORDINTREE(0x4b200000,0x00000000)}},
+ {VT_exponent,22,0x3a87ca,{DOUBLEWITHTWODWORDINTREE(0x4b300000,0x00000000)}},
+ {VT_exponent,22,0x3a87cb,{DOUBLEWITHTWODWORDINTREE(0x4b400000,0x00000000)}},
+ {VT_exponent,22,0x3a87cc,{DOUBLEWITHTWODWORDINTREE(0x4b500000,0x00000000)}},
+ {VT_exponent,22,0x3a87cd,{DOUBLEWITHTWODWORDINTREE(0x4b600000,0x00000000)}},
+ {VT_exponent,22,0x3a87ce,{DOUBLEWITHTWODWORDINTREE(0x4b700000,0x00000000)}},
+ {VT_exponent,22,0x3a87cf,{DOUBLEWITHTWODWORDINTREE(0x4b800000,0x00000000)}},
+ {VT_exponent,22,0x3a87d0,{DOUBLEWITHTWODWORDINTREE(0x4b900000,0x00000000)}},
+ {VT_exponent,22,0x3a87d1,{DOUBLEWITHTWODWORDINTREE(0x4ba00000,0x00000000)}},
+ {VT_exponent,22,0x3a87d2,{DOUBLEWITHTWODWORDINTREE(0x4bb00000,0x00000000)}},
+ {VT_exponent,22,0x3a87d3,{DOUBLEWITHTWODWORDINTREE(0x4bc00000,0x00000000)}},
+ {VT_exponent,22,0x3a87d4,{DOUBLEWITHTWODWORDINTREE(0x4bd00000,0x00000000)}},
+ {VT_exponent,22,0x3a87d5,{DOUBLEWITHTWODWORDINTREE(0x4be00000,0x00000000)}},
+ {VT_exponent,22,0x3a87d6,{DOUBLEWITHTWODWORDINTREE(0x4bf00000,0x00000000)}},
+ {VT_exponent,22,0x3a87d7,{DOUBLEWITHTWODWORDINTREE(0x4c000000,0x00000000)}},
+ {VT_exponent,22,0x3a87d8,{DOUBLEWITHTWODWORDINTREE(0x4c100000,0x00000000)}},
+ {VT_exponent,22,0x3a87d9,{DOUBLEWITHTWODWORDINTREE(0x4c200000,0x00000000)}},
+ {VT_exponent,22,0x3a87da,{DOUBLEWITHTWODWORDINTREE(0x4c300000,0x00000000)}},
+ {VT_exponent,22,0x3a87db,{DOUBLEWITHTWODWORDINTREE(0x4c400000,0x00000000)}},
+ {VT_exponent,22,0x3a87dc,{DOUBLEWITHTWODWORDINTREE(0x4c500000,0x00000000)}},
+ {VT_exponent,22,0x3a87dd,{DOUBLEWITHTWODWORDINTREE(0x4c600000,0x00000000)}},
+ {VT_exponent,22,0x3a87de,{DOUBLEWITHTWODWORDINTREE(0x4c700000,0x00000000)}},
+ {VT_exponent,22,0x3a87df,{DOUBLEWITHTWODWORDINTREE(0x4c800000,0x00000000)}},
+ {VT_exponent,22,0x3a87e0,{DOUBLEWITHTWODWORDINTREE(0x4c900000,0x00000000)}},
+ {VT_exponent,22,0x3a87e1,{DOUBLEWITHTWODWORDINTREE(0x4ca00000,0x00000000)}},
+ {VT_exponent,22,0x3a87e2,{DOUBLEWITHTWODWORDINTREE(0x4cb00000,0x00000000)}},
+ {VT_exponent,22,0x3a87e3,{DOUBLEWITHTWODWORDINTREE(0x4cc00000,0x00000000)}},
+ {VT_exponent,22,0x3a87e4,{DOUBLEWITHTWODWORDINTREE(0x4cd00000,0x00000000)}},
+ {VT_exponent,22,0x3a87e5,{DOUBLEWITHTWODWORDINTREE(0x4ce00000,0x00000000)}},
+ {VT_exponent,22,0x3a87e6,{DOUBLEWITHTWODWORDINTREE(0x4cf00000,0x00000000)}},
+ {VT_exponent,22,0x3a87e7,{DOUBLEWITHTWODWORDINTREE(0x4d000000,0x00000000)}},
+ {VT_exponent,22,0x3a87e8,{DOUBLEWITHTWODWORDINTREE(0x4d100000,0x00000000)}},
+ {VT_exponent,22,0x3a87e9,{DOUBLEWITHTWODWORDINTREE(0x4d200000,0x00000000)}},
+ {VT_exponent,22,0x3a87ea,{DOUBLEWITHTWODWORDINTREE(0x4d300000,0x00000000)}},
+ {VT_exponent,22,0x3a87eb,{DOUBLEWITHTWODWORDINTREE(0x4d400000,0x00000000)}},
+ {VT_exponent,22,0x3a87ec,{DOUBLEWITHTWODWORDINTREE(0x4d500000,0x00000000)}},
+ {VT_exponent,22,0x3a87ed,{DOUBLEWITHTWODWORDINTREE(0x4d600000,0x00000000)}},
+ {VT_exponent,22,0x3a87ee,{DOUBLEWITHTWODWORDINTREE(0x4d700000,0x00000000)}},
+ {VT_exponent,22,0x3a87ef,{DOUBLEWITHTWODWORDINTREE(0x4d800000,0x00000000)}},
+ {VT_exponent,22,0x3a87f0,{DOUBLEWITHTWODWORDINTREE(0x4d900000,0x00000000)}},
+ {VT_exponent,22,0x3a87f1,{DOUBLEWITHTWODWORDINTREE(0x4da00000,0x00000000)}},
+ {VT_exponent,22,0x3a87f2,{DOUBLEWITHTWODWORDINTREE(0x4db00000,0x00000000)}},
+ {VT_exponent,22,0x3a87f3,{DOUBLEWITHTWODWORDINTREE(0x4dc00000,0x00000000)}},
+ {VT_exponent,22,0x3a87f4,{DOUBLEWITHTWODWORDINTREE(0x4dd00000,0x00000000)}},
+ {VT_exponent,22,0x3a87f5,{DOUBLEWITHTWODWORDINTREE(0x4de00000,0x00000000)}},
+ {VT_exponent,22,0x3a87f6,{DOUBLEWITHTWODWORDINTREE(0x4df00000,0x00000000)}},
+ {VT_exponent,22,0x3a87f7,{DOUBLEWITHTWODWORDINTREE(0x4e000000,0x00000000)}},
+ {VT_exponent,22,0x3a87f8,{DOUBLEWITHTWODWORDINTREE(0x4e100000,0x00000000)}},
+ {VT_exponent,22,0x3a87f9,{DOUBLEWITHTWODWORDINTREE(0x4e200000,0x00000000)}},
+ {VT_exponent,22,0x3a87fa,{DOUBLEWITHTWODWORDINTREE(0x4e300000,0x00000000)}},
+ {VT_exponent,22,0x3a87fb,{DOUBLEWITHTWODWORDINTREE(0x4e400000,0x00000000)}},
+ {VT_exponent,22,0x3a87fc,{DOUBLEWITHTWODWORDINTREE(0x4e500000,0x00000000)}},
+ {VT_exponent,22,0x3a87fd,{DOUBLEWITHTWODWORDINTREE(0x4e600000,0x00000000)}},
+ {VT_exponent,22,0x3a87fe,{DOUBLEWITHTWODWORDINTREE(0x4e700000,0x00000000)}},
+ {VT_exponent,22,0x3a87ff,{DOUBLEWITHTWODWORDINTREE(0x4e800000,0x00000000)}},
+ {VT_exponent,22,0x3a9000,{DOUBLEWITHTWODWORDINTREE(0x4e900000,0x00000000)}},
+ {VT_exponent,22,0x3a9001,{DOUBLEWITHTWODWORDINTREE(0x4ea00000,0x00000000)}},
+ {VT_exponent,22,0x3a9002,{DOUBLEWITHTWODWORDINTREE(0x4eb00000,0x00000000)}},
+ {VT_exponent,22,0x3a9003,{DOUBLEWITHTWODWORDINTREE(0x4ec00000,0x00000000)}},
+ {VT_exponent,22,0x3a9004,{DOUBLEWITHTWODWORDINTREE(0x4ed00000,0x00000000)}},
+ {VT_exponent,22,0x3a9005,{DOUBLEWITHTWODWORDINTREE(0x4ee00000,0x00000000)}},
+ {VT_exponent,22,0x3a9006,{DOUBLEWITHTWODWORDINTREE(0x4ef00000,0x00000000)}},
+ {VT_exponent,22,0x3a9007,{DOUBLEWITHTWODWORDINTREE(0x4f000000,0x00000000)}},
+ {VT_exponent,22,0x3a9008,{DOUBLEWITHTWODWORDINTREE(0x4f100000,0x00000000)}},
+ {VT_exponent,22,0x3a9009,{DOUBLEWITHTWODWORDINTREE(0x4f200000,0x00000000)}},
+ {VT_exponent,22,0x3a900a,{DOUBLEWITHTWODWORDINTREE(0x4f300000,0x00000000)}},
+ {VT_exponent,22,0x3a900b,{DOUBLEWITHTWODWORDINTREE(0x4f400000,0x00000000)}},
+ {VT_exponent,22,0x3a900c,{DOUBLEWITHTWODWORDINTREE(0x4f500000,0x00000000)}},
+ {VT_exponent,22,0x3a900d,{DOUBLEWITHTWODWORDINTREE(0x4f600000,0x00000000)}},
+ {VT_exponent,22,0x3a900e,{DOUBLEWITHTWODWORDINTREE(0x4f700000,0x00000000)}},
+ {VT_exponent,22,0x3a900f,{DOUBLEWITHTWODWORDINTREE(0x4f800000,0x00000000)}},
+ {VT_exponent,22,0x3a9010,{DOUBLEWITHTWODWORDINTREE(0x4f900000,0x00000000)}},
+ {VT_exponent,22,0x3a9011,{DOUBLEWITHTWODWORDINTREE(0x4fa00000,0x00000000)}},
+ {VT_exponent,22,0x3a9012,{DOUBLEWITHTWODWORDINTREE(0x4fb00000,0x00000000)}},
+ {VT_exponent,22,0x3a9013,{DOUBLEWITHTWODWORDINTREE(0x4fc00000,0x00000000)}},
+ {VT_exponent,22,0x3a9014,{DOUBLEWITHTWODWORDINTREE(0x4fd00000,0x00000000)}},
+ {VT_exponent,22,0x3a9015,{DOUBLEWITHTWODWORDINTREE(0x4fe00000,0x00000000)}},
+ {VT_exponent,22,0x3a9016,{DOUBLEWITHTWODWORDINTREE(0x4ff00000,0x00000000)}},
+ {VT_exponent,22,0x3a9017,{DOUBLEWITHTWODWORDINTREE(0x50000000,0x00000000)}},
+ {VT_exponent,22,0x3a9018,{DOUBLEWITHTWODWORDINTREE(0x50100000,0x00000000)}},
+ {VT_exponent,22,0x3a9019,{DOUBLEWITHTWODWORDINTREE(0x50200000,0x00000000)}},
+ {VT_exponent,22,0x3a901a,{DOUBLEWITHTWODWORDINTREE(0x50300000,0x00000000)}},
+ {VT_exponent,22,0x3a901b,{DOUBLEWITHTWODWORDINTREE(0x50400000,0x00000000)}},
+ {VT_exponent,22,0x3a901c,{DOUBLEWITHTWODWORDINTREE(0x50500000,0x00000000)}},
+ {VT_exponent,22,0x3a901d,{DOUBLEWITHTWODWORDINTREE(0x50600000,0x00000000)}},
+ {VT_exponent,22,0x3a901e,{DOUBLEWITHTWODWORDINTREE(0x50700000,0x00000000)}},
+ {VT_exponent,22,0x3a901f,{DOUBLEWITHTWODWORDINTREE(0x50800000,0x00000000)}},
+ {VT_exponent,22,0x3a9020,{DOUBLEWITHTWODWORDINTREE(0x50900000,0x00000000)}},
+ {VT_exponent,22,0x3a9021,{DOUBLEWITHTWODWORDINTREE(0x50a00000,0x00000000)}},
+ {VT_exponent,22,0x3a9022,{DOUBLEWITHTWODWORDINTREE(0x50b00000,0x00000000)}},
+ {VT_exponent,22,0x3a9023,{DOUBLEWITHTWODWORDINTREE(0x50c00000,0x00000000)}},
+ {VT_exponent,22,0x3a9024,{DOUBLEWITHTWODWORDINTREE(0x50d00000,0x00000000)}},
+ {VT_exponent,22,0x3a9025,{DOUBLEWITHTWODWORDINTREE(0x50e00000,0x00000000)}},
+ {VT_exponent,22,0x3a9026,{DOUBLEWITHTWODWORDINTREE(0x50f00000,0x00000000)}},
+ {VT_exponent,22,0x3a9027,{DOUBLEWITHTWODWORDINTREE(0x51000000,0x00000000)}},
+ {VT_exponent,22,0x3a9028,{DOUBLEWITHTWODWORDINTREE(0x51100000,0x00000000)}},
+ {VT_exponent,22,0x3a9029,{DOUBLEWITHTWODWORDINTREE(0x51200000,0x00000000)}},
+ {VT_exponent,22,0x3a902a,{DOUBLEWITHTWODWORDINTREE(0x51300000,0x00000000)}},
+ {VT_exponent,22,0x3a902b,{DOUBLEWITHTWODWORDINTREE(0x51400000,0x00000000)}},
+ {VT_exponent,22,0x3a902c,{DOUBLEWITHTWODWORDINTREE(0x51500000,0x00000000)}},
+ {VT_exponent,22,0x3a902d,{DOUBLEWITHTWODWORDINTREE(0x51600000,0x00000000)}},
+ {VT_exponent,22,0x3a902e,{DOUBLEWITHTWODWORDINTREE(0x51700000,0x00000000)}},
+ {VT_exponent,22,0x3a902f,{DOUBLEWITHTWODWORDINTREE(0x51800000,0x00000000)}},
+ {VT_exponent,22,0x3a9030,{DOUBLEWITHTWODWORDINTREE(0x51900000,0x00000000)}},
+ {VT_exponent,22,0x3a9031,{DOUBLEWITHTWODWORDINTREE(0x51a00000,0x00000000)}},
+ {VT_exponent,22,0x3a9032,{DOUBLEWITHTWODWORDINTREE(0x51b00000,0x00000000)}},
+ {VT_exponent,22,0x3a9033,{DOUBLEWITHTWODWORDINTREE(0x51c00000,0x00000000)}},
+ {VT_exponent,22,0x3a9034,{DOUBLEWITHTWODWORDINTREE(0x51d00000,0x00000000)}},
+ {VT_exponent,22,0x3a9035,{DOUBLEWITHTWODWORDINTREE(0x51e00000,0x00000000)}},
+ {VT_exponent,22,0x3a9036,{DOUBLEWITHTWODWORDINTREE(0x51f00000,0x00000000)}},
+ {VT_exponent,22,0x3a9037,{DOUBLEWITHTWODWORDINTREE(0x52000000,0x00000000)}},
+ {VT_exponent,22,0x3a9038,{DOUBLEWITHTWODWORDINTREE(0x52100000,0x00000000)}},
+ {VT_exponent,22,0x3a9039,{DOUBLEWITHTWODWORDINTREE(0x52200000,0x00000000)}},
+ {VT_exponent,22,0x3a903a,{DOUBLEWITHTWODWORDINTREE(0x52300000,0x00000000)}},
+ {VT_exponent,22,0x3a903b,{DOUBLEWITHTWODWORDINTREE(0x52400000,0x00000000)}},
+ {VT_exponent,22,0x3a903c,{DOUBLEWITHTWODWORDINTREE(0x52500000,0x00000000)}},
+ {VT_exponent,22,0x3a903d,{DOUBLEWITHTWODWORDINTREE(0x52600000,0x00000000)}},
+ {VT_exponent,22,0x3a903e,{DOUBLEWITHTWODWORDINTREE(0x52700000,0x00000000)}},
+ {VT_exponent,22,0x3a903f,{DOUBLEWITHTWODWORDINTREE(0x52800000,0x00000000)}},
+ {VT_exponent,22,0x3a9040,{DOUBLEWITHTWODWORDINTREE(0x52900000,0x00000000)}},
+ {VT_exponent,22,0x3a9041,{DOUBLEWITHTWODWORDINTREE(0x52a00000,0x00000000)}},
+ {VT_exponent,22,0x3a9042,{DOUBLEWITHTWODWORDINTREE(0x52b00000,0x00000000)}},
+ {VT_exponent,22,0x3a9043,{DOUBLEWITHTWODWORDINTREE(0x52c00000,0x00000000)}},
+ {VT_exponent,22,0x3a9044,{DOUBLEWITHTWODWORDINTREE(0x52d00000,0x00000000)}},
+ {VT_exponent,22,0x3a9045,{DOUBLEWITHTWODWORDINTREE(0x52e00000,0x00000000)}},
+ {VT_exponent,22,0x3a9046,{DOUBLEWITHTWODWORDINTREE(0x52f00000,0x00000000)}},
+ {VT_exponent,22,0x3a9047,{DOUBLEWITHTWODWORDINTREE(0x53000000,0x00000000)}},
+ {VT_exponent,22,0x3a9048,{DOUBLEWITHTWODWORDINTREE(0x53100000,0x00000000)}},
+ {VT_exponent,22,0x3a9049,{DOUBLEWITHTWODWORDINTREE(0x53200000,0x00000000)}},
+ {VT_exponent,22,0x3a904a,{DOUBLEWITHTWODWORDINTREE(0x53300000,0x00000000)}},
+ {VT_exponent,22,0x3a904b,{DOUBLEWITHTWODWORDINTREE(0x53400000,0x00000000)}},
+ {VT_exponent,22,0x3a904c,{DOUBLEWITHTWODWORDINTREE(0x53500000,0x00000000)}},
+ {VT_exponent,22,0x3a904d,{DOUBLEWITHTWODWORDINTREE(0x53600000,0x00000000)}},
+ {VT_exponent,22,0x3a904e,{DOUBLEWITHTWODWORDINTREE(0x53700000,0x00000000)}},
+ {VT_exponent,22,0x3a904f,{DOUBLEWITHTWODWORDINTREE(0x53800000,0x00000000)}},
+ {VT_exponent,22,0x3a9050,{DOUBLEWITHTWODWORDINTREE(0x53900000,0x00000000)}},
+ {VT_exponent,22,0x3a9051,{DOUBLEWITHTWODWORDINTREE(0x53a00000,0x00000000)}},
+ {VT_exponent,22,0x3a9052,{DOUBLEWITHTWODWORDINTREE(0x53b00000,0x00000000)}},
+ {VT_exponent,22,0x3a9053,{DOUBLEWITHTWODWORDINTREE(0x53c00000,0x00000000)}},
+ {VT_exponent,22,0x3a9054,{DOUBLEWITHTWODWORDINTREE(0x53d00000,0x00000000)}},
+ {VT_exponent,22,0x3a9055,{DOUBLEWITHTWODWORDINTREE(0x53e00000,0x00000000)}},
+ {VT_exponent,22,0x3a9056,{DOUBLEWITHTWODWORDINTREE(0x53f00000,0x00000000)}},
+ {VT_exponent,22,0x3a9057,{DOUBLEWITHTWODWORDINTREE(0x54000000,0x00000000)}},
+ {VT_exponent,22,0x3a9058,{DOUBLEWITHTWODWORDINTREE(0x54100000,0x00000000)}},
+ {VT_exponent,22,0x3a9059,{DOUBLEWITHTWODWORDINTREE(0x54200000,0x00000000)}},
+ {VT_exponent,22,0x3a905a,{DOUBLEWITHTWODWORDINTREE(0x54300000,0x00000000)}},
+ {VT_exponent,22,0x3a905b,{DOUBLEWITHTWODWORDINTREE(0x54400000,0x00000000)}},
+ {VT_exponent,22,0x3a905c,{DOUBLEWITHTWODWORDINTREE(0x54500000,0x00000000)}},
+ {VT_exponent,22,0x3a905d,{DOUBLEWITHTWODWORDINTREE(0x54600000,0x00000000)}},
+ {VT_exponent,22,0x3a905e,{DOUBLEWITHTWODWORDINTREE(0x54700000,0x00000000)}},
+ {VT_exponent,22,0x3a905f,{DOUBLEWITHTWODWORDINTREE(0x54800000,0x00000000)}},
+ {VT_exponent,22,0x3a9060,{DOUBLEWITHTWODWORDINTREE(0x54900000,0x00000000)}},
+ {VT_exponent,22,0x3a9061,{DOUBLEWITHTWODWORDINTREE(0x54a00000,0x00000000)}},
+ {VT_exponent,22,0x3a9062,{DOUBLEWITHTWODWORDINTREE(0x54b00000,0x00000000)}},
+ {VT_exponent,22,0x3a9063,{DOUBLEWITHTWODWORDINTREE(0x54c00000,0x00000000)}},
+ {VT_exponent,22,0x3a9064,{DOUBLEWITHTWODWORDINTREE(0x54d00000,0x00000000)}},
+ {VT_exponent,22,0x3a9065,{DOUBLEWITHTWODWORDINTREE(0x54e00000,0x00000000)}},
+ {VT_exponent,22,0x3a9066,{DOUBLEWITHTWODWORDINTREE(0x54f00000,0x00000000)}},
+ {VT_exponent,22,0x3a9067,{DOUBLEWITHTWODWORDINTREE(0x55000000,0x00000000)}},
+ {VT_exponent,22,0x3a9068,{DOUBLEWITHTWODWORDINTREE(0x55100000,0x00000000)}},
+ {VT_exponent,22,0x3a9069,{DOUBLEWITHTWODWORDINTREE(0x55200000,0x00000000)}},
+ {VT_exponent,22,0x3a906a,{DOUBLEWITHTWODWORDINTREE(0x55300000,0x00000000)}},
+ {VT_exponent,22,0x3a906b,{DOUBLEWITHTWODWORDINTREE(0x55400000,0x00000000)}},
+ {VT_exponent,22,0x3a906c,{DOUBLEWITHTWODWORDINTREE(0x55500000,0x00000000)}},
+ {VT_exponent,22,0x3a906d,{DOUBLEWITHTWODWORDINTREE(0x55600000,0x00000000)}},
+ {VT_exponent,22,0x3a906e,{DOUBLEWITHTWODWORDINTREE(0x55700000,0x00000000)}},
+ {VT_exponent,22,0x3a906f,{DOUBLEWITHTWODWORDINTREE(0x55800000,0x00000000)}},
+ {VT_exponent,22,0x3a9070,{DOUBLEWITHTWODWORDINTREE(0x55900000,0x00000000)}},
+ {VT_exponent,22,0x3a9071,{DOUBLEWITHTWODWORDINTREE(0x55a00000,0x00000000)}},
+ {VT_exponent,22,0x3a9072,{DOUBLEWITHTWODWORDINTREE(0x55b00000,0x00000000)}},
+ {VT_exponent,22,0x3a9073,{DOUBLEWITHTWODWORDINTREE(0x55c00000,0x00000000)}},
+ {VT_exponent,22,0x3a9074,{DOUBLEWITHTWODWORDINTREE(0x55d00000,0x00000000)}},
+ {VT_exponent,22,0x3a9075,{DOUBLEWITHTWODWORDINTREE(0x55e00000,0x00000000)}},
+ {VT_exponent,22,0x3a9076,{DOUBLEWITHTWODWORDINTREE(0x55f00000,0x00000000)}},
+ {VT_exponent,22,0x3a9077,{DOUBLEWITHTWODWORDINTREE(0x56000000,0x00000000)}},
+ {VT_exponent,22,0x3a9078,{DOUBLEWITHTWODWORDINTREE(0x56100000,0x00000000)}},
+ {VT_exponent,22,0x3a9079,{DOUBLEWITHTWODWORDINTREE(0x56200000,0x00000000)}},
+ {VT_exponent,22,0x3a907a,{DOUBLEWITHTWODWORDINTREE(0x56300000,0x00000000)}},
+ {VT_exponent,22,0x3a907b,{DOUBLEWITHTWODWORDINTREE(0x56400000,0x00000000)}},
+ {VT_exponent,22,0x3a907c,{DOUBLEWITHTWODWORDINTREE(0x56500000,0x00000000)}},
+ {VT_exponent,22,0x3a907d,{DOUBLEWITHTWODWORDINTREE(0x56600000,0x00000000)}},
+ {VT_exponent,22,0x3a907e,{DOUBLEWITHTWODWORDINTREE(0x56700000,0x00000000)}},
+ {VT_exponent,22,0x3a907f,{DOUBLEWITHTWODWORDINTREE(0x56800000,0x00000000)}},
+ {VT_exponent,22,0x3a9080,{DOUBLEWITHTWODWORDINTREE(0x56900000,0x00000000)}},
+ {VT_exponent,22,0x3a9081,{DOUBLEWITHTWODWORDINTREE(0x56a00000,0x00000000)}},
+ {VT_exponent,22,0x3a9082,{DOUBLEWITHTWODWORDINTREE(0x56b00000,0x00000000)}},
+ {VT_exponent,22,0x3a9083,{DOUBLEWITHTWODWORDINTREE(0x56c00000,0x00000000)}},
+ {VT_exponent,22,0x3a9084,{DOUBLEWITHTWODWORDINTREE(0x56d00000,0x00000000)}},
+ {VT_exponent,22,0x3a9085,{DOUBLEWITHTWODWORDINTREE(0x56e00000,0x00000000)}},
+ {VT_exponent,22,0x3a9086,{DOUBLEWITHTWODWORDINTREE(0x56f00000,0x00000000)}},
+ {VT_exponent,22,0x3a9087,{DOUBLEWITHTWODWORDINTREE(0x57000000,0x00000000)}},
+ {VT_exponent,22,0x3a9088,{DOUBLEWITHTWODWORDINTREE(0x57100000,0x00000000)}},
+ {VT_exponent,22,0x3a9089,{DOUBLEWITHTWODWORDINTREE(0x57200000,0x00000000)}},
+ {VT_exponent,22,0x3a908a,{DOUBLEWITHTWODWORDINTREE(0x57300000,0x00000000)}},
+ {VT_exponent,22,0x3a908b,{DOUBLEWITHTWODWORDINTREE(0x57400000,0x00000000)}},
+ {VT_exponent,22,0x3a908c,{DOUBLEWITHTWODWORDINTREE(0x57500000,0x00000000)}},
+ {VT_exponent,22,0x3a908d,{DOUBLEWITHTWODWORDINTREE(0x57600000,0x00000000)}},
+ {VT_exponent,22,0x3a908e,{DOUBLEWITHTWODWORDINTREE(0x57700000,0x00000000)}},
+ {VT_exponent,22,0x3a908f,{DOUBLEWITHTWODWORDINTREE(0x57800000,0x00000000)}},
+ {VT_exponent,22,0x3a9090,{DOUBLEWITHTWODWORDINTREE(0x57900000,0x00000000)}},
+ {VT_exponent,22,0x3a9091,{DOUBLEWITHTWODWORDINTREE(0x57a00000,0x00000000)}},
+ {VT_exponent,22,0x3a9092,{DOUBLEWITHTWODWORDINTREE(0x57b00000,0x00000000)}},
+ {VT_exponent,22,0x3a9093,{DOUBLEWITHTWODWORDINTREE(0x57c00000,0x00000000)}},
+ {VT_exponent,22,0x3a9094,{DOUBLEWITHTWODWORDINTREE(0x57d00000,0x00000000)}},
+ {VT_exponent,22,0x3a9095,{DOUBLEWITHTWODWORDINTREE(0x57e00000,0x00000000)}},
+ {VT_exponent,22,0x3a9096,{DOUBLEWITHTWODWORDINTREE(0x57f00000,0x00000000)}},
+ {VT_exponent,22,0x3a9097,{DOUBLEWITHTWODWORDINTREE(0x58000000,0x00000000)}},
+ {VT_exponent,22,0x3a9098,{DOUBLEWITHTWODWORDINTREE(0x58100000,0x00000000)}},
+ {VT_exponent,22,0x3a9099,{DOUBLEWITHTWODWORDINTREE(0x58200000,0x00000000)}},
+ {VT_exponent,22,0x3a909a,{DOUBLEWITHTWODWORDINTREE(0x58300000,0x00000000)}},
+ {VT_exponent,22,0x3a909b,{DOUBLEWITHTWODWORDINTREE(0x58400000,0x00000000)}},
+ {VT_exponent,22,0x3a909c,{DOUBLEWITHTWODWORDINTREE(0x58500000,0x00000000)}},
+ {VT_exponent,22,0x3a909d,{DOUBLEWITHTWODWORDINTREE(0x58600000,0x00000000)}},
+ {VT_exponent,22,0x3a909e,{DOUBLEWITHTWODWORDINTREE(0x58700000,0x00000000)}},
+ {VT_exponent,22,0x3a909f,{DOUBLEWITHTWODWORDINTREE(0x58800000,0x00000000)}},
+ {VT_exponent,22,0x3a90a0,{DOUBLEWITHTWODWORDINTREE(0x58900000,0x00000000)}},
+ {VT_exponent,22,0x3a90a1,{DOUBLEWITHTWODWORDINTREE(0x58a00000,0x00000000)}},
+ {VT_exponent,22,0x3a90a2,{DOUBLEWITHTWODWORDINTREE(0x58b00000,0x00000000)}},
+ {VT_exponent,22,0x3a90a3,{DOUBLEWITHTWODWORDINTREE(0x58c00000,0x00000000)}},
+ {VT_exponent,22,0x3a90a4,{DOUBLEWITHTWODWORDINTREE(0x58d00000,0x00000000)}},
+ {VT_exponent,22,0x3a90a5,{DOUBLEWITHTWODWORDINTREE(0x58e00000,0x00000000)}},
+ {VT_exponent,22,0x3a90a6,{DOUBLEWITHTWODWORDINTREE(0x58f00000,0x00000000)}},
+ {VT_exponent,22,0x3a90a7,{DOUBLEWITHTWODWORDINTREE(0x59000000,0x00000000)}},
+ {VT_exponent,22,0x3a90a8,{DOUBLEWITHTWODWORDINTREE(0x59100000,0x00000000)}},
+ {VT_exponent,22,0x3a90a9,{DOUBLEWITHTWODWORDINTREE(0x59200000,0x00000000)}},
+ {VT_exponent,22,0x3a90aa,{DOUBLEWITHTWODWORDINTREE(0x59300000,0x00000000)}},
+ {VT_exponent,22,0x3a90ab,{DOUBLEWITHTWODWORDINTREE(0x59400000,0x00000000)}},
+ {VT_exponent,22,0x3a90ac,{DOUBLEWITHTWODWORDINTREE(0x59500000,0x00000000)}},
+ {VT_exponent,22,0x3a90ad,{DOUBLEWITHTWODWORDINTREE(0x59600000,0x00000000)}},
+ {VT_exponent,22,0x3a90ae,{DOUBLEWITHTWODWORDINTREE(0x59700000,0x00000000)}},
+ {VT_exponent,22,0x3a90af,{DOUBLEWITHTWODWORDINTREE(0x59800000,0x00000000)}},
+ {VT_exponent,22,0x3a90b0,{DOUBLEWITHTWODWORDINTREE(0x59900000,0x00000000)}},
+ {VT_exponent,22,0x3a90b1,{DOUBLEWITHTWODWORDINTREE(0x59a00000,0x00000000)}},
+ {VT_exponent,22,0x3a90b2,{DOUBLEWITHTWODWORDINTREE(0x59b00000,0x00000000)}},
+ {VT_exponent,22,0x3a90b3,{DOUBLEWITHTWODWORDINTREE(0x59c00000,0x00000000)}},
+ {VT_exponent,22,0x3a90b4,{DOUBLEWITHTWODWORDINTREE(0x59d00000,0x00000000)}},
+ {VT_exponent,22,0x3a90b5,{DOUBLEWITHTWODWORDINTREE(0x59e00000,0x00000000)}},
+ {VT_exponent,22,0x3a90b6,{DOUBLEWITHTWODWORDINTREE(0x59f00000,0x00000000)}},
+ {VT_exponent,22,0x3a90b7,{DOUBLEWITHTWODWORDINTREE(0x5a000000,0x00000000)}},
+ {VT_exponent,22,0x3a90b8,{DOUBLEWITHTWODWORDINTREE(0x5a100000,0x00000000)}},
+ {VT_exponent,22,0x3a90b9,{DOUBLEWITHTWODWORDINTREE(0x5a200000,0x00000000)}},
+ {VT_exponent,22,0x3a90ba,{DOUBLEWITHTWODWORDINTREE(0x5a300000,0x00000000)}},
+ {VT_exponent,22,0x3a90bb,{DOUBLEWITHTWODWORDINTREE(0x5a400000,0x00000000)}},
+ {VT_exponent,22,0x3a90bc,{DOUBLEWITHTWODWORDINTREE(0x5a500000,0x00000000)}},
+ {VT_exponent,22,0x3a90bd,{DOUBLEWITHTWODWORDINTREE(0x5a600000,0x00000000)}},
+ {VT_exponent,22,0x3a90be,{DOUBLEWITHTWODWORDINTREE(0x5a700000,0x00000000)}},
+ {VT_exponent,22,0x3a90bf,{DOUBLEWITHTWODWORDINTREE(0x5a800000,0x00000000)}},
+ {VT_exponent,22,0x3a90c0,{DOUBLEWITHTWODWORDINTREE(0x5a900000,0x00000000)}},
+ {VT_exponent,22,0x3a90c1,{DOUBLEWITHTWODWORDINTREE(0x5aa00000,0x00000000)}},
+ {VT_exponent,22,0x3a90c2,{DOUBLEWITHTWODWORDINTREE(0x5ab00000,0x00000000)}},
+ {VT_exponent,22,0x3a90c3,{DOUBLEWITHTWODWORDINTREE(0x5ac00000,0x00000000)}},
+ {VT_exponent,22,0x3a90c4,{DOUBLEWITHTWODWORDINTREE(0x5ad00000,0x00000000)}},
+ {VT_exponent,22,0x3a90c5,{DOUBLEWITHTWODWORDINTREE(0x5ae00000,0x00000000)}},
+ {VT_exponent,22,0x3a90c6,{DOUBLEWITHTWODWORDINTREE(0x5af00000,0x00000000)}},
+ {VT_exponent,22,0x3a90c7,{DOUBLEWITHTWODWORDINTREE(0x5b000000,0x00000000)}},
+ {VT_exponent,22,0x3a90c8,{DOUBLEWITHTWODWORDINTREE(0x5b100000,0x00000000)}},
+ {VT_exponent,22,0x3a90c9,{DOUBLEWITHTWODWORDINTREE(0x5b200000,0x00000000)}},
+ {VT_exponent,22,0x3a90ca,{DOUBLEWITHTWODWORDINTREE(0x5b300000,0x00000000)}},
+ {VT_exponent,22,0x3a90cb,{DOUBLEWITHTWODWORDINTREE(0x5b400000,0x00000000)}},
+ {VT_exponent,22,0x3a90cc,{DOUBLEWITHTWODWORDINTREE(0x5b500000,0x00000000)}},
+ {VT_exponent,22,0x3a90cd,{DOUBLEWITHTWODWORDINTREE(0x5b600000,0x00000000)}},
+ {VT_exponent,22,0x3a90ce,{DOUBLEWITHTWODWORDINTREE(0x5b700000,0x00000000)}},
+ {VT_exponent,22,0x3a90cf,{DOUBLEWITHTWODWORDINTREE(0x5b800000,0x00000000)}},
+ {VT_exponent,22,0x3a90d0,{DOUBLEWITHTWODWORDINTREE(0x5b900000,0x00000000)}},
+ {VT_exponent,22,0x3a90d1,{DOUBLEWITHTWODWORDINTREE(0x5ba00000,0x00000000)}},
+ {VT_exponent,22,0x3a90d2,{DOUBLEWITHTWODWORDINTREE(0x5bb00000,0x00000000)}},
+ {VT_exponent,22,0x3a90d3,{DOUBLEWITHTWODWORDINTREE(0x5bc00000,0x00000000)}},
+ {VT_exponent,22,0x3a90d4,{DOUBLEWITHTWODWORDINTREE(0x5bd00000,0x00000000)}},
+ {VT_exponent,22,0x3a90d5,{DOUBLEWITHTWODWORDINTREE(0x5be00000,0x00000000)}},
+ {VT_exponent,22,0x3a90d6,{DOUBLEWITHTWODWORDINTREE(0x5bf00000,0x00000000)}},
+ {VT_exponent,22,0x3a90d7,{DOUBLEWITHTWODWORDINTREE(0x5c000000,0x00000000)}},
+ {VT_exponent,22,0x3a90d8,{DOUBLEWITHTWODWORDINTREE(0x5c100000,0x00000000)}},
+ {VT_exponent,22,0x3a90d9,{DOUBLEWITHTWODWORDINTREE(0x5c200000,0x00000000)}},
+ {VT_exponent,22,0x3a90da,{DOUBLEWITHTWODWORDINTREE(0x5c300000,0x00000000)}},
+ {VT_exponent,22,0x3a90db,{DOUBLEWITHTWODWORDINTREE(0x5c400000,0x00000000)}},
+ {VT_exponent,22,0x3a90dc,{DOUBLEWITHTWODWORDINTREE(0x5c500000,0x00000000)}},
+ {VT_exponent,22,0x3a90dd,{DOUBLEWITHTWODWORDINTREE(0x5c600000,0x00000000)}},
+ {VT_exponent,22,0x3a90de,{DOUBLEWITHTWODWORDINTREE(0x5c700000,0x00000000)}},
+ {VT_exponent,22,0x3a90df,{DOUBLEWITHTWODWORDINTREE(0x5c800000,0x00000000)}},
+ {VT_exponent,22,0x3a90e0,{DOUBLEWITHTWODWORDINTREE(0x5c900000,0x00000000)}},
+ {VT_exponent,22,0x3a90e1,{DOUBLEWITHTWODWORDINTREE(0x5ca00000,0x00000000)}},
+ {VT_exponent,22,0x3a90e2,{DOUBLEWITHTWODWORDINTREE(0x5cb00000,0x00000000)}},
+ {VT_exponent,22,0x3a90e3,{DOUBLEWITHTWODWORDINTREE(0x5cc00000,0x00000000)}},
+ {VT_exponent,22,0x3a90e4,{DOUBLEWITHTWODWORDINTREE(0x5cd00000,0x00000000)}},
+ {VT_exponent,22,0x3a90e5,{DOUBLEWITHTWODWORDINTREE(0x5ce00000,0x00000000)}},
+ {VT_exponent,22,0x3a90e6,{DOUBLEWITHTWODWORDINTREE(0x5cf00000,0x00000000)}},
+ {VT_exponent,22,0x3a90e7,{DOUBLEWITHTWODWORDINTREE(0x5d000000,0x00000000)}},
+ {VT_exponent,22,0x3a90e8,{DOUBLEWITHTWODWORDINTREE(0x5d100000,0x00000000)}},
+ {VT_exponent,22,0x3a90e9,{DOUBLEWITHTWODWORDINTREE(0x5d200000,0x00000000)}},
+ {VT_exponent,22,0x3a90ea,{DOUBLEWITHTWODWORDINTREE(0x5d300000,0x00000000)}},
+ {VT_exponent,22,0x3a90eb,{DOUBLEWITHTWODWORDINTREE(0x5d400000,0x00000000)}},
+ {VT_exponent,22,0x3a90ec,{DOUBLEWITHTWODWORDINTREE(0x5d500000,0x00000000)}},
+ {VT_exponent,22,0x3a90ed,{DOUBLEWITHTWODWORDINTREE(0x5d600000,0x00000000)}},
+ {VT_exponent,22,0x3a90ee,{DOUBLEWITHTWODWORDINTREE(0x5d700000,0x00000000)}},
+ {VT_exponent,22,0x3a90ef,{DOUBLEWITHTWODWORDINTREE(0x5d800000,0x00000000)}},
+ {VT_exponent,22,0x3a90f0,{DOUBLEWITHTWODWORDINTREE(0x5d900000,0x00000000)}},
+ {VT_exponent,22,0x3a90f1,{DOUBLEWITHTWODWORDINTREE(0x5da00000,0x00000000)}},
+ {VT_exponent,22,0x3a90f2,{DOUBLEWITHTWODWORDINTREE(0x5db00000,0x00000000)}},
+ {VT_exponent,22,0x3a90f3,{DOUBLEWITHTWODWORDINTREE(0x5dc00000,0x00000000)}},
+ {VT_exponent,22,0x3a90f4,{DOUBLEWITHTWODWORDINTREE(0x5dd00000,0x00000000)}},
+ {VT_exponent,22,0x3a90f5,{DOUBLEWITHTWODWORDINTREE(0x5de00000,0x00000000)}},
+ {VT_exponent,22,0x3a90f6,{DOUBLEWITHTWODWORDINTREE(0x5df00000,0x00000000)}},
+ {VT_exponent,22,0x3a90f7,{DOUBLEWITHTWODWORDINTREE(0x5e000000,0x00000000)}},
+ {VT_exponent,22,0x3a90f8,{DOUBLEWITHTWODWORDINTREE(0x5e100000,0x00000000)}},
+ {VT_exponent,22,0x3a90f9,{DOUBLEWITHTWODWORDINTREE(0x5e200000,0x00000000)}},
+ {VT_exponent,22,0x3a90fa,{DOUBLEWITHTWODWORDINTREE(0x5e300000,0x00000000)}},
+ {VT_exponent,22,0x3a90fb,{DOUBLEWITHTWODWORDINTREE(0x5e400000,0x00000000)}},
+ {VT_exponent,22,0x3a90fc,{DOUBLEWITHTWODWORDINTREE(0x5e500000,0x00000000)}},
+ {VT_exponent,22,0x3a90fd,{DOUBLEWITHTWODWORDINTREE(0x5e600000,0x00000000)}},
+ {VT_exponent,22,0x3a90fe,{DOUBLEWITHTWODWORDINTREE(0x5e700000,0x00000000)}},
+ {VT_exponent,22,0x3a90ff,{DOUBLEWITHTWODWORDINTREE(0x5e800000,0x00000000)}},
+ {VT_exponent,22,0x3a9100,{DOUBLEWITHTWODWORDINTREE(0x5e900000,0x00000000)}},
+ {VT_exponent,22,0x3a9101,{DOUBLEWITHTWODWORDINTREE(0x5ea00000,0x00000000)}},
+ {VT_exponent,22,0x3a9102,{DOUBLEWITHTWODWORDINTREE(0x5eb00000,0x00000000)}},
+ {VT_exponent,22,0x3a9103,{DOUBLEWITHTWODWORDINTREE(0x5ec00000,0x00000000)}},
+ {VT_exponent,22,0x3a9104,{DOUBLEWITHTWODWORDINTREE(0x5ed00000,0x00000000)}},
+ {VT_exponent,22,0x3a9105,{DOUBLEWITHTWODWORDINTREE(0x5ee00000,0x00000000)}},
+ {VT_exponent,22,0x3a9106,{DOUBLEWITHTWODWORDINTREE(0x5ef00000,0x00000000)}},
+ {VT_exponent,22,0x3a9107,{DOUBLEWITHTWODWORDINTREE(0x5f000000,0x00000000)}},
+ {VT_exponent,22,0x3a9108,{DOUBLEWITHTWODWORDINTREE(0x5f100000,0x00000000)}},
+ {VT_exponent,22,0x3a9109,{DOUBLEWITHTWODWORDINTREE(0x5f200000,0x00000000)}},
+ {VT_exponent,22,0x3a910a,{DOUBLEWITHTWODWORDINTREE(0x5f300000,0x00000000)}},
+ {VT_exponent,22,0x3a910b,{DOUBLEWITHTWODWORDINTREE(0x5f400000,0x00000000)}},
+ {VT_exponent,22,0x3a910c,{DOUBLEWITHTWODWORDINTREE(0x5f500000,0x00000000)}},
+ {VT_exponent,22,0x3a910d,{DOUBLEWITHTWODWORDINTREE(0x5f600000,0x00000000)}},
+ {VT_exponent,22,0x3a910e,{DOUBLEWITHTWODWORDINTREE(0x5f700000,0x00000000)}},
+ {VT_exponent,22,0x3a910f,{DOUBLEWITHTWODWORDINTREE(0x5f800000,0x00000000)}},
+ {VT_exponent,22,0x3a9110,{DOUBLEWITHTWODWORDINTREE(0x5f900000,0x00000000)}},
+ {VT_exponent,22,0x3a9111,{DOUBLEWITHTWODWORDINTREE(0x5fa00000,0x00000000)}},
+ {VT_exponent,22,0x3a9112,{DOUBLEWITHTWODWORDINTREE(0x5fb00000,0x00000000)}},
+ {VT_exponent,22,0x3a9113,{DOUBLEWITHTWODWORDINTREE(0x5fc00000,0x00000000)}},
+ {VT_exponent,22,0x3a9114,{DOUBLEWITHTWODWORDINTREE(0x5fd00000,0x00000000)}},
+ {VT_exponent,22,0x3a9115,{DOUBLEWITHTWODWORDINTREE(0x5fe00000,0x00000000)}},
+ {VT_exponent,22,0x3a9116,{DOUBLEWITHTWODWORDINTREE(0x5ff00000,0x00000000)}},
+ {VT_exponent,22,0x3a9117,{DOUBLEWITHTWODWORDINTREE(0x60000000,0x00000000)}},
+ {VT_exponent,22,0x3a9118,{DOUBLEWITHTWODWORDINTREE(0x60100000,0x00000000)}},
+ {VT_exponent,22,0x3a9119,{DOUBLEWITHTWODWORDINTREE(0x60200000,0x00000000)}},
+ {VT_exponent,22,0x3a911a,{DOUBLEWITHTWODWORDINTREE(0x60300000,0x00000000)}},
+ {VT_exponent,22,0x3a911b,{DOUBLEWITHTWODWORDINTREE(0x60400000,0x00000000)}},
+ {VT_exponent,22,0x3a911c,{DOUBLEWITHTWODWORDINTREE(0x60500000,0x00000000)}},
+ {VT_exponent,22,0x3a911d,{DOUBLEWITHTWODWORDINTREE(0x60600000,0x00000000)}},
+ {VT_exponent,22,0x3a911e,{DOUBLEWITHTWODWORDINTREE(0x60700000,0x00000000)}},
+ {VT_exponent,22,0x3a911f,{DOUBLEWITHTWODWORDINTREE(0x60800000,0x00000000)}},
+ {VT_exponent,22,0x3a9120,{DOUBLEWITHTWODWORDINTREE(0x60900000,0x00000000)}},
+ {VT_exponent,22,0x3a9121,{DOUBLEWITHTWODWORDINTREE(0x60a00000,0x00000000)}},
+ {VT_exponent,22,0x3a9122,{DOUBLEWITHTWODWORDINTREE(0x60b00000,0x00000000)}},
+ {VT_exponent,22,0x3a9123,{DOUBLEWITHTWODWORDINTREE(0x60c00000,0x00000000)}},
+ {VT_exponent,22,0x3a9124,{DOUBLEWITHTWODWORDINTREE(0x60d00000,0x00000000)}},
+ {VT_exponent,22,0x3a9125,{DOUBLEWITHTWODWORDINTREE(0x60e00000,0x00000000)}},
+ {VT_exponent,22,0x3a9126,{DOUBLEWITHTWODWORDINTREE(0x60f00000,0x00000000)}},
+ {VT_exponent,22,0x3a9127,{DOUBLEWITHTWODWORDINTREE(0x61000000,0x00000000)}},
+ {VT_exponent,22,0x3a9128,{DOUBLEWITHTWODWORDINTREE(0x61100000,0x00000000)}},
+ {VT_exponent,22,0x3a9129,{DOUBLEWITHTWODWORDINTREE(0x61200000,0x00000000)}},
+ {VT_exponent,22,0x3a912a,{DOUBLEWITHTWODWORDINTREE(0x61300000,0x00000000)}},
+ {VT_exponent,22,0x3a912b,{DOUBLEWITHTWODWORDINTREE(0x61400000,0x00000000)}},
+ {VT_exponent,22,0x3a912c,{DOUBLEWITHTWODWORDINTREE(0x61500000,0x00000000)}},
+ {VT_exponent,22,0x3a912d,{DOUBLEWITHTWODWORDINTREE(0x61600000,0x00000000)}},
+ {VT_exponent,22,0x3a912e,{DOUBLEWITHTWODWORDINTREE(0x61700000,0x00000000)}},
+ {VT_exponent,22,0x3a912f,{DOUBLEWITHTWODWORDINTREE(0x61800000,0x00000000)}},
+ {VT_exponent,22,0x3a9130,{DOUBLEWITHTWODWORDINTREE(0x61900000,0x00000000)}},
+ {VT_exponent,22,0x3a9131,{DOUBLEWITHTWODWORDINTREE(0x61a00000,0x00000000)}},
+ {VT_exponent,22,0x3a9132,{DOUBLEWITHTWODWORDINTREE(0x61b00000,0x00000000)}},
+ {VT_exponent,22,0x3a9133,{DOUBLEWITHTWODWORDINTREE(0x61c00000,0x00000000)}},
+ {VT_exponent,22,0x3a9134,{DOUBLEWITHTWODWORDINTREE(0x61d00000,0x00000000)}},
+ {VT_exponent,22,0x3a9135,{DOUBLEWITHTWODWORDINTREE(0x61e00000,0x00000000)}},
+ {VT_exponent,22,0x3a9136,{DOUBLEWITHTWODWORDINTREE(0x61f00000,0x00000000)}},
+ {VT_exponent,22,0x3a9137,{DOUBLEWITHTWODWORDINTREE(0x62000000,0x00000000)}},
+ {VT_exponent,22,0x3a9138,{DOUBLEWITHTWODWORDINTREE(0x62100000,0x00000000)}},
+ {VT_exponent,22,0x3a9139,{DOUBLEWITHTWODWORDINTREE(0x62200000,0x00000000)}},
+ {VT_exponent,22,0x3a913a,{DOUBLEWITHTWODWORDINTREE(0x62300000,0x00000000)}},
+ {VT_exponent,22,0x3a913b,{DOUBLEWITHTWODWORDINTREE(0x62400000,0x00000000)}},
+ {VT_exponent,22,0x3a913c,{DOUBLEWITHTWODWORDINTREE(0x62500000,0x00000000)}},
+ {VT_exponent,22,0x3a913d,{DOUBLEWITHTWODWORDINTREE(0x62600000,0x00000000)}},
+ {VT_exponent,22,0x3a913e,{DOUBLEWITHTWODWORDINTREE(0x62700000,0x00000000)}},
+ {VT_exponent,22,0x3a913f,{DOUBLEWITHTWODWORDINTREE(0x62800000,0x00000000)}},
+ {VT_exponent,22,0x3a9140,{DOUBLEWITHTWODWORDINTREE(0x62900000,0x00000000)}},
+ {VT_exponent,22,0x3a9141,{DOUBLEWITHTWODWORDINTREE(0x62a00000,0x00000000)}},
+ {VT_exponent,22,0x3a9142,{DOUBLEWITHTWODWORDINTREE(0x62b00000,0x00000000)}},
+ {VT_exponent,22,0x3a9143,{DOUBLEWITHTWODWORDINTREE(0x62c00000,0x00000000)}},
+ {VT_exponent,22,0x3a9144,{DOUBLEWITHTWODWORDINTREE(0x62d00000,0x00000000)}},
+ {VT_exponent,22,0x3a9145,{DOUBLEWITHTWODWORDINTREE(0x62e00000,0x00000000)}},
+ {VT_exponent,22,0x3a9146,{DOUBLEWITHTWODWORDINTREE(0x62f00000,0x00000000)}},
+ {VT_exponent,22,0x3a9147,{DOUBLEWITHTWODWORDINTREE(0x63000000,0x00000000)}},
+ {VT_exponent,22,0x3a9148,{DOUBLEWITHTWODWORDINTREE(0x63100000,0x00000000)}},
+ {VT_exponent,22,0x3a9149,{DOUBLEWITHTWODWORDINTREE(0x63200000,0x00000000)}},
+ {VT_exponent,22,0x3a914a,{DOUBLEWITHTWODWORDINTREE(0x63300000,0x00000000)}},
+ {VT_exponent,22,0x3a914b,{DOUBLEWITHTWODWORDINTREE(0x63400000,0x00000000)}},
+ {VT_exponent,22,0x3a914c,{DOUBLEWITHTWODWORDINTREE(0x63500000,0x00000000)}},
+ {VT_exponent,22,0x3a914d,{DOUBLEWITHTWODWORDINTREE(0x63600000,0x00000000)}},
+ {VT_exponent,22,0x3a914e,{DOUBLEWITHTWODWORDINTREE(0x63700000,0x00000000)}},
+ {VT_exponent,22,0x3a914f,{DOUBLEWITHTWODWORDINTREE(0x63800000,0x00000000)}},
+ {VT_exponent,22,0x3a9150,{DOUBLEWITHTWODWORDINTREE(0x63900000,0x00000000)}},
+ {VT_exponent,22,0x3a9151,{DOUBLEWITHTWODWORDINTREE(0x63a00000,0x00000000)}},
+ {VT_exponent,22,0x3a9152,{DOUBLEWITHTWODWORDINTREE(0x63b00000,0x00000000)}},
+ {VT_exponent,22,0x3a9153,{DOUBLEWITHTWODWORDINTREE(0x63c00000,0x00000000)}},
+ {VT_exponent,22,0x3a9154,{DOUBLEWITHTWODWORDINTREE(0x63d00000,0x00000000)}},
+ {VT_exponent,22,0x3a9155,{DOUBLEWITHTWODWORDINTREE(0x63e00000,0x00000000)}},
+ {VT_exponent,22,0x3a9156,{DOUBLEWITHTWODWORDINTREE(0x63f00000,0x00000000)}},
+ {VT_exponent,22,0x3a9157,{DOUBLEWITHTWODWORDINTREE(0x64000000,0x00000000)}},
+ {VT_exponent,22,0x3a9158,{DOUBLEWITHTWODWORDINTREE(0x64100000,0x00000000)}},
+ {VT_exponent,22,0x3a9159,{DOUBLEWITHTWODWORDINTREE(0x64200000,0x00000000)}},
+ {VT_exponent,22,0x3a915a,{DOUBLEWITHTWODWORDINTREE(0x64300000,0x00000000)}},
+ {VT_exponent,22,0x3a915b,{DOUBLEWITHTWODWORDINTREE(0x64400000,0x00000000)}},
+ {VT_exponent,22,0x3a915c,{DOUBLEWITHTWODWORDINTREE(0x64500000,0x00000000)}},
+ {VT_exponent,22,0x3a915d,{DOUBLEWITHTWODWORDINTREE(0x64600000,0x00000000)}},
+ {VT_exponent,22,0x3a915e,{DOUBLEWITHTWODWORDINTREE(0x64700000,0x00000000)}},
+ {VT_exponent,22,0x3a915f,{DOUBLEWITHTWODWORDINTREE(0x64800000,0x00000000)}},
+ {VT_exponent,22,0x3a9160,{DOUBLEWITHTWODWORDINTREE(0x64900000,0x00000000)}},
+ {VT_exponent,22,0x3a9161,{DOUBLEWITHTWODWORDINTREE(0x64a00000,0x00000000)}},
+ {VT_exponent,22,0x3a9162,{DOUBLEWITHTWODWORDINTREE(0x64b00000,0x00000000)}},
+ {VT_exponent,22,0x3a9163,{DOUBLEWITHTWODWORDINTREE(0x64c00000,0x00000000)}},
+ {VT_exponent,22,0x3a9164,{DOUBLEWITHTWODWORDINTREE(0x64d00000,0x00000000)}},
+ {VT_exponent,22,0x3a9165,{DOUBLEWITHTWODWORDINTREE(0x64e00000,0x00000000)}},
+ {VT_exponent,22,0x3a9166,{DOUBLEWITHTWODWORDINTREE(0x64f00000,0x00000000)}},
+ {VT_exponent,22,0x3a9167,{DOUBLEWITHTWODWORDINTREE(0x65000000,0x00000000)}},
+ {VT_exponent,22,0x3a9168,{DOUBLEWITHTWODWORDINTREE(0x65100000,0x00000000)}},
+ {VT_exponent,22,0x3a9169,{DOUBLEWITHTWODWORDINTREE(0x65200000,0x00000000)}},
+ {VT_exponent,22,0x3a916a,{DOUBLEWITHTWODWORDINTREE(0x65300000,0x00000000)}},
+ {VT_exponent,22,0x3a916b,{DOUBLEWITHTWODWORDINTREE(0x65400000,0x00000000)}},
+ {VT_exponent,22,0x3a916c,{DOUBLEWITHTWODWORDINTREE(0x65500000,0x00000000)}},
+ {VT_exponent,22,0x3a916d,{DOUBLEWITHTWODWORDINTREE(0x65600000,0x00000000)}},
+ {VT_exponent,22,0x3a916e,{DOUBLEWITHTWODWORDINTREE(0x65700000,0x00000000)}},
+ {VT_exponent,22,0x3a916f,{DOUBLEWITHTWODWORDINTREE(0x65800000,0x00000000)}},
+ {VT_exponent,22,0x3a9170,{DOUBLEWITHTWODWORDINTREE(0x65900000,0x00000000)}},
+ {VT_exponent,22,0x3a9171,{DOUBLEWITHTWODWORDINTREE(0x65a00000,0x00000000)}},
+ {VT_exponent,22,0x3a9172,{DOUBLEWITHTWODWORDINTREE(0x65b00000,0x00000000)}},
+ {VT_exponent,22,0x3a9173,{DOUBLEWITHTWODWORDINTREE(0x65c00000,0x00000000)}},
+ {VT_exponent,22,0x3a9174,{DOUBLEWITHTWODWORDINTREE(0x65d00000,0x00000000)}},
+ {VT_exponent,22,0x3a9175,{DOUBLEWITHTWODWORDINTREE(0x65e00000,0x00000000)}},
+ {VT_exponent,22,0x3a9176,{DOUBLEWITHTWODWORDINTREE(0x65f00000,0x00000000)}},
+ {VT_exponent,22,0x3a9177,{DOUBLEWITHTWODWORDINTREE(0x66000000,0x00000000)}},
+ {VT_exponent,22,0x3a9178,{DOUBLEWITHTWODWORDINTREE(0x66100000,0x00000000)}},
+ {VT_exponent,22,0x3a9179,{DOUBLEWITHTWODWORDINTREE(0x66200000,0x00000000)}},
+ {VT_exponent,22,0x3a917a,{DOUBLEWITHTWODWORDINTREE(0x66300000,0x00000000)}},
+ {VT_exponent,22,0x3a917b,{DOUBLEWITHTWODWORDINTREE(0x66400000,0x00000000)}},
+ {VT_exponent,22,0x3a917c,{DOUBLEWITHTWODWORDINTREE(0x66500000,0x00000000)}},
+ {VT_exponent,22,0x3a917d,{DOUBLEWITHTWODWORDINTREE(0x66600000,0x00000000)}},
+ {VT_exponent,22,0x3a917e,{DOUBLEWITHTWODWORDINTREE(0x66700000,0x00000000)}},
+ {VT_exponent,22,0x3a917f,{DOUBLEWITHTWODWORDINTREE(0x66800000,0x00000000)}},
+ {VT_exponent,22,0x3a9180,{DOUBLEWITHTWODWORDINTREE(0x66900000,0x00000000)}},
+ {VT_exponent,22,0x3a9181,{DOUBLEWITHTWODWORDINTREE(0x66a00000,0x00000000)}},
+ {VT_exponent,22,0x3a9182,{DOUBLEWITHTWODWORDINTREE(0x66b00000,0x00000000)}},
+ {VT_exponent,22,0x3a9183,{DOUBLEWITHTWODWORDINTREE(0x66c00000,0x00000000)}},
+ {VT_exponent,22,0x3a9184,{DOUBLEWITHTWODWORDINTREE(0x66d00000,0x00000000)}},
+ {VT_exponent,22,0x3a9185,{DOUBLEWITHTWODWORDINTREE(0x66e00000,0x00000000)}},
+ {VT_exponent,22,0x3a9186,{DOUBLEWITHTWODWORDINTREE(0x66f00000,0x00000000)}},
+ {VT_exponent,22,0x3a9187,{DOUBLEWITHTWODWORDINTREE(0x67000000,0x00000000)}},
+ {VT_exponent,22,0x3a9188,{DOUBLEWITHTWODWORDINTREE(0x67100000,0x00000000)}},
+ {VT_exponent,22,0x3a9189,{DOUBLEWITHTWODWORDINTREE(0x67200000,0x00000000)}},
+ {VT_exponent,22,0x3a918a,{DOUBLEWITHTWODWORDINTREE(0x67300000,0x00000000)}},
+ {VT_exponent,22,0x3a918b,{DOUBLEWITHTWODWORDINTREE(0x67400000,0x00000000)}},
+ {VT_exponent,22,0x3a918c,{DOUBLEWITHTWODWORDINTREE(0x67500000,0x00000000)}},
+ {VT_exponent,22,0x3a918d,{DOUBLEWITHTWODWORDINTREE(0x67600000,0x00000000)}},
+ {VT_exponent,22,0x3a918e,{DOUBLEWITHTWODWORDINTREE(0x67700000,0x00000000)}},
+ {VT_exponent,22,0x3a918f,{DOUBLEWITHTWODWORDINTREE(0x67800000,0x00000000)}},
+ {VT_exponent,22,0x3a9190,{DOUBLEWITHTWODWORDINTREE(0x67900000,0x00000000)}},
+ {VT_exponent,22,0x3a9191,{DOUBLEWITHTWODWORDINTREE(0x67a00000,0x00000000)}},
+ {VT_exponent,22,0x3a9192,{DOUBLEWITHTWODWORDINTREE(0x67b00000,0x00000000)}},
+ {VT_exponent,22,0x3a9193,{DOUBLEWITHTWODWORDINTREE(0x67c00000,0x00000000)}},
+ {VT_exponent,22,0x3a9194,{DOUBLEWITHTWODWORDINTREE(0x67d00000,0x00000000)}},
+ {VT_exponent,22,0x3a9195,{DOUBLEWITHTWODWORDINTREE(0x67e00000,0x00000000)}},
+ {VT_exponent,22,0x3a9196,{DOUBLEWITHTWODWORDINTREE(0x67f00000,0x00000000)}},
+ {VT_exponent,22,0x3a9197,{DOUBLEWITHTWODWORDINTREE(0x68000000,0x00000000)}},
+ {VT_exponent,22,0x3a9198,{DOUBLEWITHTWODWORDINTREE(0x68100000,0x00000000)}},
+ {VT_exponent,22,0x3a9199,{DOUBLEWITHTWODWORDINTREE(0x68200000,0x00000000)}},
+ {VT_exponent,22,0x3a919a,{DOUBLEWITHTWODWORDINTREE(0x68300000,0x00000000)}},
+ {VT_exponent,22,0x3a919b,{DOUBLEWITHTWODWORDINTREE(0x68400000,0x00000000)}},
+ {VT_exponent,22,0x3a919c,{DOUBLEWITHTWODWORDINTREE(0x68500000,0x00000000)}},
+ {VT_exponent,22,0x3a919d,{DOUBLEWITHTWODWORDINTREE(0x68600000,0x00000000)}},
+ {VT_exponent,22,0x3a919e,{DOUBLEWITHTWODWORDINTREE(0x68700000,0x00000000)}},
+ {VT_exponent,22,0x3a919f,{DOUBLEWITHTWODWORDINTREE(0x68800000,0x00000000)}},
+ {VT_exponent,22,0x3a91a0,{DOUBLEWITHTWODWORDINTREE(0x68900000,0x00000000)}},
+ {VT_exponent,22,0x3a91a1,{DOUBLEWITHTWODWORDINTREE(0x68a00000,0x00000000)}},
+ {VT_exponent,22,0x3a91a2,{DOUBLEWITHTWODWORDINTREE(0x68b00000,0x00000000)}},
+ {VT_exponent,22,0x3a91a3,{DOUBLEWITHTWODWORDINTREE(0x68c00000,0x00000000)}},
+ {VT_exponent,22,0x3a91a4,{DOUBLEWITHTWODWORDINTREE(0x68d00000,0x00000000)}},
+ {VT_exponent,22,0x3a91a5,{DOUBLEWITHTWODWORDINTREE(0x68e00000,0x00000000)}},
+ {VT_exponent,22,0x3a91a6,{DOUBLEWITHTWODWORDINTREE(0x68f00000,0x00000000)}},
+ {VT_exponent,22,0x3a91a7,{DOUBLEWITHTWODWORDINTREE(0x69000000,0x00000000)}},
+ {VT_exponent,22,0x3a91a8,{DOUBLEWITHTWODWORDINTREE(0x69100000,0x00000000)}},
+ {VT_exponent,22,0x3a91a9,{DOUBLEWITHTWODWORDINTREE(0x69200000,0x00000000)}},
+ {VT_exponent,22,0x3a91aa,{DOUBLEWITHTWODWORDINTREE(0x69300000,0x00000000)}},
+ {VT_exponent,22,0x3a91ab,{DOUBLEWITHTWODWORDINTREE(0x69400000,0x00000000)}},
+ {VT_exponent,22,0x3a91ac,{DOUBLEWITHTWODWORDINTREE(0x69500000,0x00000000)}},
+ {VT_exponent,22,0x3a91ad,{DOUBLEWITHTWODWORDINTREE(0x69600000,0x00000000)}},
+ {VT_exponent,22,0x3a91ae,{DOUBLEWITHTWODWORDINTREE(0x69700000,0x00000000)}},
+ {VT_exponent,22,0x3a91af,{DOUBLEWITHTWODWORDINTREE(0x69800000,0x00000000)}},
+ {VT_exponent,22,0x3a91b0,{DOUBLEWITHTWODWORDINTREE(0x69900000,0x00000000)}},
+ {VT_exponent,22,0x3a91b1,{DOUBLEWITHTWODWORDINTREE(0x69a00000,0x00000000)}},
+ {VT_exponent,22,0x3a91b2,{DOUBLEWITHTWODWORDINTREE(0x69b00000,0x00000000)}},
+ {VT_exponent,22,0x3a91b3,{DOUBLEWITHTWODWORDINTREE(0x69c00000,0x00000000)}},
+ {VT_exponent,22,0x3a91b4,{DOUBLEWITHTWODWORDINTREE(0x69d00000,0x00000000)}},
+ {VT_exponent,22,0x3a91b5,{DOUBLEWITHTWODWORDINTREE(0x69e00000,0x00000000)}},
+ {VT_exponent,22,0x3a91b6,{DOUBLEWITHTWODWORDINTREE(0x69f00000,0x00000000)}},
+ {VT_exponent,22,0x3a91b7,{DOUBLEWITHTWODWORDINTREE(0x6a000000,0x00000000)}},
+ {VT_exponent,22,0x3a91b8,{DOUBLEWITHTWODWORDINTREE(0x6a100000,0x00000000)}},
+ {VT_exponent,22,0x3a91b9,{DOUBLEWITHTWODWORDINTREE(0x6a200000,0x00000000)}},
+ {VT_exponent,22,0x3a91ba,{DOUBLEWITHTWODWORDINTREE(0x6a300000,0x00000000)}},
+ {VT_exponent,22,0x3a91bb,{DOUBLEWITHTWODWORDINTREE(0x6a400000,0x00000000)}},
+ {VT_exponent,22,0x3a91bc,{DOUBLEWITHTWODWORDINTREE(0x6a500000,0x00000000)}},
+ {VT_exponent,22,0x3a91bd,{DOUBLEWITHTWODWORDINTREE(0x6a600000,0x00000000)}},
+ {VT_exponent,22,0x3a91be,{DOUBLEWITHTWODWORDINTREE(0x6a700000,0x00000000)}},
+ {VT_exponent,22,0x3a91bf,{DOUBLEWITHTWODWORDINTREE(0x6a800000,0x00000000)}},
+ {VT_exponent,22,0x3a91c0,{DOUBLEWITHTWODWORDINTREE(0x6a900000,0x00000000)}},
+ {VT_exponent,22,0x3a91c1,{DOUBLEWITHTWODWORDINTREE(0x6aa00000,0x00000000)}},
+ {VT_exponent,22,0x3a91c2,{DOUBLEWITHTWODWORDINTREE(0x6ab00000,0x00000000)}},
+ {VT_exponent,22,0x3a91c3,{DOUBLEWITHTWODWORDINTREE(0x6ac00000,0x00000000)}},
+ {VT_exponent,22,0x3a91c4,{DOUBLEWITHTWODWORDINTREE(0x6ad00000,0x00000000)}},
+ {VT_exponent,22,0x3a91c5,{DOUBLEWITHTWODWORDINTREE(0x6ae00000,0x00000000)}},
+ {VT_exponent,22,0x3a91c6,{DOUBLEWITHTWODWORDINTREE(0x6af00000,0x00000000)}},
+ {VT_exponent,22,0x3a91c7,{DOUBLEWITHTWODWORDINTREE(0x6b000000,0x00000000)}},
+ {VT_exponent,22,0x3a91c8,{DOUBLEWITHTWODWORDINTREE(0x6b100000,0x00000000)}},
+ {VT_exponent,22,0x3a91c9,{DOUBLEWITHTWODWORDINTREE(0x6b200000,0x00000000)}},
+ {VT_exponent,22,0x3a91ca,{DOUBLEWITHTWODWORDINTREE(0x6b300000,0x00000000)}},
+ {VT_exponent,22,0x3a91cb,{DOUBLEWITHTWODWORDINTREE(0x6b400000,0x00000000)}},
+ {VT_exponent,22,0x3a91cc,{DOUBLEWITHTWODWORDINTREE(0x6b500000,0x00000000)}},
+ {VT_exponent,22,0x3a91cd,{DOUBLEWITHTWODWORDINTREE(0x6b600000,0x00000000)}},
+ {VT_exponent,22,0x3a91ce,{DOUBLEWITHTWODWORDINTREE(0x6b700000,0x00000000)}},
+ {VT_exponent,22,0x3a91cf,{DOUBLEWITHTWODWORDINTREE(0x6b800000,0x00000000)}},
+ {VT_exponent,22,0x3a91d0,{DOUBLEWITHTWODWORDINTREE(0x6b900000,0x00000000)}},
+ {VT_exponent,22,0x3a91d1,{DOUBLEWITHTWODWORDINTREE(0x6ba00000,0x00000000)}},
+ {VT_exponent,22,0x3a91d2,{DOUBLEWITHTWODWORDINTREE(0x6bb00000,0x00000000)}},
+ {VT_exponent,22,0x3a91d3,{DOUBLEWITHTWODWORDINTREE(0x6bc00000,0x00000000)}},
+ {VT_exponent,22,0x3a91d4,{DOUBLEWITHTWODWORDINTREE(0x6bd00000,0x00000000)}},
+ {VT_exponent,22,0x3a91d5,{DOUBLEWITHTWODWORDINTREE(0x6be00000,0x00000000)}},
+ {VT_exponent,22,0x3a91d6,{DOUBLEWITHTWODWORDINTREE(0x6bf00000,0x00000000)}},
+ {VT_exponent,22,0x3a91d7,{DOUBLEWITHTWODWORDINTREE(0x6c000000,0x00000000)}},
+ {VT_exponent,22,0x3a91d8,{DOUBLEWITHTWODWORDINTREE(0x6c100000,0x00000000)}},
+ {VT_exponent,22,0x3a91d9,{DOUBLEWITHTWODWORDINTREE(0x6c200000,0x00000000)}},
+ {VT_exponent,22,0x3a91da,{DOUBLEWITHTWODWORDINTREE(0x6c300000,0x00000000)}},
+ {VT_exponent,22,0x3a91db,{DOUBLEWITHTWODWORDINTREE(0x6c400000,0x00000000)}},
+ {VT_exponent,22,0x3a91dc,{DOUBLEWITHTWODWORDINTREE(0x6c500000,0x00000000)}},
+ {VT_exponent,22,0x3a91dd,{DOUBLEWITHTWODWORDINTREE(0x6c600000,0x00000000)}},
+ {VT_exponent,22,0x3a91de,{DOUBLEWITHTWODWORDINTREE(0x6c700000,0x00000000)}},
+ {VT_exponent,22,0x3a91df,{DOUBLEWITHTWODWORDINTREE(0x6c800000,0x00000000)}},
+ {VT_exponent,22,0x3a91e0,{DOUBLEWITHTWODWORDINTREE(0x6c900000,0x00000000)}},
+ {VT_exponent,22,0x3a91e1,{DOUBLEWITHTWODWORDINTREE(0x6ca00000,0x00000000)}},
+ {VT_exponent,22,0x3a91e2,{DOUBLEWITHTWODWORDINTREE(0x6cb00000,0x00000000)}},
+ {VT_exponent,22,0x3a91e3,{DOUBLEWITHTWODWORDINTREE(0x6cc00000,0x00000000)}},
+ {VT_exponent,22,0x3a91e4,{DOUBLEWITHTWODWORDINTREE(0x6cd00000,0x00000000)}},
+ {VT_exponent,22,0x3a91e5,{DOUBLEWITHTWODWORDINTREE(0x6ce00000,0x00000000)}},
+ {VT_exponent,22,0x3a91e6,{DOUBLEWITHTWODWORDINTREE(0x6cf00000,0x00000000)}},
+ {VT_exponent,22,0x3a91e7,{DOUBLEWITHTWODWORDINTREE(0x6d000000,0x00000000)}},
+ {VT_exponent,22,0x3a91e8,{DOUBLEWITHTWODWORDINTREE(0x6d100000,0x00000000)}},
+ {VT_exponent,22,0x3a91e9,{DOUBLEWITHTWODWORDINTREE(0x6d200000,0x00000000)}},
+ {VT_exponent,22,0x3a91ea,{DOUBLEWITHTWODWORDINTREE(0x6d300000,0x00000000)}},
+ {VT_exponent,22,0x3a91eb,{DOUBLEWITHTWODWORDINTREE(0x6d400000,0x00000000)}},
+ {VT_exponent,22,0x3a91ec,{DOUBLEWITHTWODWORDINTREE(0x6d500000,0x00000000)}},
+ {VT_exponent,22,0x3a91ed,{DOUBLEWITHTWODWORDINTREE(0x6d600000,0x00000000)}},
+ {VT_exponent,22,0x3a91ee,{DOUBLEWITHTWODWORDINTREE(0x6d700000,0x00000000)}},
+ {VT_exponent,22,0x3a91ef,{DOUBLEWITHTWODWORDINTREE(0x6d800000,0x00000000)}},
+ {VT_exponent,22,0x3a91f0,{DOUBLEWITHTWODWORDINTREE(0x6d900000,0x00000000)}},
+ {VT_exponent,22,0x3a91f1,{DOUBLEWITHTWODWORDINTREE(0x6da00000,0x00000000)}},
+ {VT_exponent,22,0x3a91f2,{DOUBLEWITHTWODWORDINTREE(0x6db00000,0x00000000)}},
+ {VT_exponent,22,0x3a91f3,{DOUBLEWITHTWODWORDINTREE(0x6dc00000,0x00000000)}},
+ {VT_exponent,22,0x3a91f4,{DOUBLEWITHTWODWORDINTREE(0x6dd00000,0x00000000)}},
+ {VT_exponent,22,0x3a91f5,{DOUBLEWITHTWODWORDINTREE(0x6de00000,0x00000000)}},
+ {VT_exponent,22,0x3a91f6,{DOUBLEWITHTWODWORDINTREE(0x6df00000,0x00000000)}},
+ {VT_exponent,22,0x3a91f7,{DOUBLEWITHTWODWORDINTREE(0x6e000000,0x00000000)}},
+ {VT_exponent,22,0x3a91f8,{DOUBLEWITHTWODWORDINTREE(0x6e100000,0x00000000)}},
+ {VT_exponent,22,0x3a91f9,{DOUBLEWITHTWODWORDINTREE(0x6e200000,0x00000000)}},
+ {VT_exponent,22,0x3a91fa,{DOUBLEWITHTWODWORDINTREE(0x6e300000,0x00000000)}},
+ {VT_exponent,22,0x3a91fb,{DOUBLEWITHTWODWORDINTREE(0x6e400000,0x00000000)}},
+ {VT_exponent,22,0x3a91fc,{DOUBLEWITHTWODWORDINTREE(0x6e500000,0x00000000)}},
+ {VT_exponent,22,0x3a91fd,{DOUBLEWITHTWODWORDINTREE(0x6e600000,0x00000000)}},
+ {VT_exponent,22,0x3a91fe,{DOUBLEWITHTWODWORDINTREE(0x6e700000,0x00000000)}},
+ {VT_exponent,22,0x3a91ff,{DOUBLEWITHTWODWORDINTREE(0x6e800000,0x00000000)}},
+ {VT_exponent,22,0x3a9200,{DOUBLEWITHTWODWORDINTREE(0x6e900000,0x00000000)}},
+ {VT_exponent,22,0x3a9201,{DOUBLEWITHTWODWORDINTREE(0x6ea00000,0x00000000)}},
+ {VT_exponent,22,0x3a9202,{DOUBLEWITHTWODWORDINTREE(0x6eb00000,0x00000000)}},
+ {VT_exponent,22,0x3a9203,{DOUBLEWITHTWODWORDINTREE(0x6ec00000,0x00000000)}},
+ {VT_exponent,22,0x3a9204,{DOUBLEWITHTWODWORDINTREE(0x6ed00000,0x00000000)}},
+ {VT_exponent,22,0x3a9205,{DOUBLEWITHTWODWORDINTREE(0x6ee00000,0x00000000)}},
+ {VT_exponent,22,0x3a9206,{DOUBLEWITHTWODWORDINTREE(0x6ef00000,0x00000000)}},
+ {VT_exponent,22,0x3a9207,{DOUBLEWITHTWODWORDINTREE(0x6f000000,0x00000000)}},
+ {VT_exponent,22,0x3a9208,{DOUBLEWITHTWODWORDINTREE(0x6f100000,0x00000000)}},
+ {VT_exponent,22,0x3a9209,{DOUBLEWITHTWODWORDINTREE(0x6f200000,0x00000000)}},
+ {VT_exponent,22,0x3a920a,{DOUBLEWITHTWODWORDINTREE(0x6f300000,0x00000000)}},
+ {VT_exponent,22,0x3a920b,{DOUBLEWITHTWODWORDINTREE(0x6f400000,0x00000000)}},
+ {VT_exponent,22,0x3a920c,{DOUBLEWITHTWODWORDINTREE(0x6f500000,0x00000000)}},
+ {VT_exponent,22,0x3a920d,{DOUBLEWITHTWODWORDINTREE(0x6f600000,0x00000000)}},
+ {VT_exponent,22,0x3a920e,{DOUBLEWITHTWODWORDINTREE(0x6f700000,0x00000000)}},
+ {VT_exponent,22,0x3a920f,{DOUBLEWITHTWODWORDINTREE(0x6f800000,0x00000000)}},
+ {VT_exponent,22,0x3a9210,{DOUBLEWITHTWODWORDINTREE(0x6f900000,0x00000000)}},
+ {VT_exponent,22,0x3a9211,{DOUBLEWITHTWODWORDINTREE(0x6fa00000,0x00000000)}},
+ {VT_exponent,22,0x3a9212,{DOUBLEWITHTWODWORDINTREE(0x6fb00000,0x00000000)}},
+ {VT_exponent,22,0x3a9213,{DOUBLEWITHTWODWORDINTREE(0x6fc00000,0x00000000)}},
+ {VT_exponent,22,0x3a9214,{DOUBLEWITHTWODWORDINTREE(0x6fd00000,0x00000000)}},
+ {VT_exponent,22,0x3a9215,{DOUBLEWITHTWODWORDINTREE(0x6fe00000,0x00000000)}},
+ {VT_exponent,22,0x3a9216,{DOUBLEWITHTWODWORDINTREE(0x6ff00000,0x00000000)}},
+ {VT_exponent,22,0x3a9217,{DOUBLEWITHTWODWORDINTREE(0x70000000,0x00000000)}},
+ {VT_exponent,22,0x3a9218,{DOUBLEWITHTWODWORDINTREE(0x70100000,0x00000000)}},
+ {VT_exponent,22,0x3a9219,{DOUBLEWITHTWODWORDINTREE(0x70200000,0x00000000)}},
+ {VT_exponent,22,0x3a921a,{DOUBLEWITHTWODWORDINTREE(0x70300000,0x00000000)}},
+ {VT_exponent,22,0x3a921b,{DOUBLEWITHTWODWORDINTREE(0x70400000,0x00000000)}},
+ {VT_exponent,22,0x3a921c,{DOUBLEWITHTWODWORDINTREE(0x70500000,0x00000000)}},
+ {VT_exponent,22,0x3a921d,{DOUBLEWITHTWODWORDINTREE(0x70600000,0x00000000)}},
+ {VT_exponent,22,0x3a921e,{DOUBLEWITHTWODWORDINTREE(0x70700000,0x00000000)}},
+ {VT_exponent,22,0x3a921f,{DOUBLEWITHTWODWORDINTREE(0x70800000,0x00000000)}},
+ {VT_exponent,22,0x3a9220,{DOUBLEWITHTWODWORDINTREE(0x70900000,0x00000000)}},
+ {VT_exponent,22,0x3a9221,{DOUBLEWITHTWODWORDINTREE(0x70a00000,0x00000000)}},
+ {VT_exponent,22,0x3a9222,{DOUBLEWITHTWODWORDINTREE(0x70b00000,0x00000000)}},
+ {VT_exponent,22,0x3a9223,{DOUBLEWITHTWODWORDINTREE(0x70c00000,0x00000000)}},
+ {VT_exponent,22,0x3a9224,{DOUBLEWITHTWODWORDINTREE(0x70d00000,0x00000000)}},
+ {VT_exponent,22,0x3a9225,{DOUBLEWITHTWODWORDINTREE(0x70e00000,0x00000000)}},
+ {VT_exponent,22,0x3a9226,{DOUBLEWITHTWODWORDINTREE(0x70f00000,0x00000000)}},
+ {VT_exponent,22,0x3a9227,{DOUBLEWITHTWODWORDINTREE(0x71000000,0x00000000)}},
+ {VT_exponent,22,0x3a9228,{DOUBLEWITHTWODWORDINTREE(0x71100000,0x00000000)}},
+ {VT_exponent,22,0x3a9229,{DOUBLEWITHTWODWORDINTREE(0x71200000,0x00000000)}},
+ {VT_exponent,22,0x3a922a,{DOUBLEWITHTWODWORDINTREE(0x71300000,0x00000000)}},
+ {VT_exponent,22,0x3a922b,{DOUBLEWITHTWODWORDINTREE(0x71400000,0x00000000)}},
+ {VT_exponent,22,0x3a922c,{DOUBLEWITHTWODWORDINTREE(0x71500000,0x00000000)}},
+ {VT_exponent,22,0x3a922d,{DOUBLEWITHTWODWORDINTREE(0x71600000,0x00000000)}},
+ {VT_exponent,22,0x3a922e,{DOUBLEWITHTWODWORDINTREE(0x71700000,0x00000000)}},
+ {VT_exponent,22,0x3a922f,{DOUBLEWITHTWODWORDINTREE(0x71800000,0x00000000)}},
+ {VT_exponent,22,0x3a9230,{DOUBLEWITHTWODWORDINTREE(0x71900000,0x00000000)}},
+ {VT_exponent,22,0x3a9231,{DOUBLEWITHTWODWORDINTREE(0x71a00000,0x00000000)}},
+ {VT_exponent,22,0x3a9232,{DOUBLEWITHTWODWORDINTREE(0x71b00000,0x00000000)}},
+ {VT_exponent,22,0x3a9233,{DOUBLEWITHTWODWORDINTREE(0x71c00000,0x00000000)}},
+ {VT_exponent,22,0x3a9234,{DOUBLEWITHTWODWORDINTREE(0x71d00000,0x00000000)}},
+ {VT_exponent,22,0x3a9235,{DOUBLEWITHTWODWORDINTREE(0x71e00000,0x00000000)}},
+ {VT_exponent,22,0x3a9236,{DOUBLEWITHTWODWORDINTREE(0x71f00000,0x00000000)}},
+ {VT_exponent,22,0x3a9237,{DOUBLEWITHTWODWORDINTREE(0x72000000,0x00000000)}},
+ {VT_exponent,22,0x3a9238,{DOUBLEWITHTWODWORDINTREE(0x72100000,0x00000000)}},
+ {VT_exponent,22,0x3a9239,{DOUBLEWITHTWODWORDINTREE(0x72200000,0x00000000)}},
+ {VT_exponent,22,0x3a923a,{DOUBLEWITHTWODWORDINTREE(0x72300000,0x00000000)}},
+ {VT_exponent,22,0x3a923b,{DOUBLEWITHTWODWORDINTREE(0x72400000,0x00000000)}},
+ {VT_exponent,22,0x3a923c,{DOUBLEWITHTWODWORDINTREE(0x72500000,0x00000000)}},
+ {VT_exponent,22,0x3a923d,{DOUBLEWITHTWODWORDINTREE(0x72600000,0x00000000)}},
+ {VT_exponent,22,0x3a923e,{DOUBLEWITHTWODWORDINTREE(0x72700000,0x00000000)}},
+ {VT_exponent,22,0x3a923f,{DOUBLEWITHTWODWORDINTREE(0x72800000,0x00000000)}},
+ {VT_exponent,22,0x3a9240,{DOUBLEWITHTWODWORDINTREE(0x72900000,0x00000000)}},
+ {VT_exponent,22,0x3a9241,{DOUBLEWITHTWODWORDINTREE(0x72a00000,0x00000000)}},
+ {VT_exponent,22,0x3a9242,{DOUBLEWITHTWODWORDINTREE(0x72b00000,0x00000000)}},
+ {VT_exponent,22,0x3a9243,{DOUBLEWITHTWODWORDINTREE(0x72c00000,0x00000000)}},
+ {VT_exponent,22,0x3a9244,{DOUBLEWITHTWODWORDINTREE(0x72d00000,0x00000000)}},
+ {VT_exponent,22,0x3a9245,{DOUBLEWITHTWODWORDINTREE(0x72e00000,0x00000000)}},
+ {VT_exponent,22,0x3a9246,{DOUBLEWITHTWODWORDINTREE(0x72f00000,0x00000000)}},
+ {VT_exponent,22,0x3a9247,{DOUBLEWITHTWODWORDINTREE(0x73000000,0x00000000)}},
+ {VT_exponent,22,0x3a9248,{DOUBLEWITHTWODWORDINTREE(0x73100000,0x00000000)}},
+ {VT_exponent,22,0x3a9249,{DOUBLEWITHTWODWORDINTREE(0x73200000,0x00000000)}},
+ {VT_exponent,22,0x3a924a,{DOUBLEWITHTWODWORDINTREE(0x73300000,0x00000000)}},
+ {VT_exponent,22,0x3a924b,{DOUBLEWITHTWODWORDINTREE(0x73400000,0x00000000)}},
+ {VT_exponent,22,0x3a924c,{DOUBLEWITHTWODWORDINTREE(0x73500000,0x00000000)}},
+ {VT_exponent,22,0x3a924d,{DOUBLEWITHTWODWORDINTREE(0x73600000,0x00000000)}},
+ {VT_exponent,22,0x3a924e,{DOUBLEWITHTWODWORDINTREE(0x73700000,0x00000000)}},
+ {VT_exponent,22,0x3a924f,{DOUBLEWITHTWODWORDINTREE(0x73800000,0x00000000)}},
+ {VT_exponent,22,0x3a9250,{DOUBLEWITHTWODWORDINTREE(0x73900000,0x00000000)}},
+ {VT_exponent,22,0x3a9251,{DOUBLEWITHTWODWORDINTREE(0x73a00000,0x00000000)}},
+ {VT_exponent,22,0x3a9252,{DOUBLEWITHTWODWORDINTREE(0x73b00000,0x00000000)}},
+ {VT_exponent,22,0x3a9253,{DOUBLEWITHTWODWORDINTREE(0x73c00000,0x00000000)}},
+ {VT_exponent,22,0x3a9254,{DOUBLEWITHTWODWORDINTREE(0x73d00000,0x00000000)}},
+ {VT_exponent,22,0x3a9255,{DOUBLEWITHTWODWORDINTREE(0x73e00000,0x00000000)}},
+ {VT_exponent,22,0x3a9256,{DOUBLEWITHTWODWORDINTREE(0x73f00000,0x00000000)}},
+ {VT_exponent,22,0x3a9257,{DOUBLEWITHTWODWORDINTREE(0x74000000,0x00000000)}},
+ {VT_exponent,22,0x3a9258,{DOUBLEWITHTWODWORDINTREE(0x74100000,0x00000000)}},
+ {VT_exponent,22,0x3a9259,{DOUBLEWITHTWODWORDINTREE(0x74200000,0x00000000)}},
+ {VT_exponent,22,0x3a925a,{DOUBLEWITHTWODWORDINTREE(0x74300000,0x00000000)}},
+ {VT_exponent,22,0x3a925b,{DOUBLEWITHTWODWORDINTREE(0x74400000,0x00000000)}},
+ {VT_exponent,22,0x3a925c,{DOUBLEWITHTWODWORDINTREE(0x74500000,0x00000000)}},
+ {VT_exponent,22,0x3a925d,{DOUBLEWITHTWODWORDINTREE(0x74600000,0x00000000)}},
+ {VT_exponent,22,0x3a925e,{DOUBLEWITHTWODWORDINTREE(0x74700000,0x00000000)}},
+ {VT_exponent,22,0x3a925f,{DOUBLEWITHTWODWORDINTREE(0x74800000,0x00000000)}},
+ {VT_exponent,22,0x3a9260,{DOUBLEWITHTWODWORDINTREE(0x74900000,0x00000000)}},
+ {VT_exponent,22,0x3a9261,{DOUBLEWITHTWODWORDINTREE(0x74a00000,0x00000000)}},
+ {VT_exponent,22,0x3a9262,{DOUBLEWITHTWODWORDINTREE(0x74b00000,0x00000000)}},
+ {VT_exponent,22,0x3a9263,{DOUBLEWITHTWODWORDINTREE(0x74c00000,0x00000000)}},
+ {VT_exponent,22,0x3a9264,{DOUBLEWITHTWODWORDINTREE(0x74d00000,0x00000000)}},
+ {VT_exponent,22,0x3a9265,{DOUBLEWITHTWODWORDINTREE(0x74e00000,0x00000000)}},
+ {VT_exponent,22,0x3a9266,{DOUBLEWITHTWODWORDINTREE(0x74f00000,0x00000000)}},
+ {VT_exponent,22,0x3a9267,{DOUBLEWITHTWODWORDINTREE(0x75000000,0x00000000)}},
+ {VT_exponent,22,0x3a9268,{DOUBLEWITHTWODWORDINTREE(0x75100000,0x00000000)}},
+ {VT_exponent,22,0x3a9269,{DOUBLEWITHTWODWORDINTREE(0x75200000,0x00000000)}},
+ {VT_exponent,22,0x3a926a,{DOUBLEWITHTWODWORDINTREE(0x75300000,0x00000000)}},
+ {VT_exponent,22,0x3a926b,{DOUBLEWITHTWODWORDINTREE(0x75400000,0x00000000)}},
+ {VT_exponent,22,0x3a926c,{DOUBLEWITHTWODWORDINTREE(0x75500000,0x00000000)}},
+ {VT_exponent,22,0x3a926d,{DOUBLEWITHTWODWORDINTREE(0x75600000,0x00000000)}},
+ {VT_exponent,22,0x3a926e,{DOUBLEWITHTWODWORDINTREE(0x75700000,0x00000000)}},
+ {VT_exponent,22,0x3a926f,{DOUBLEWITHTWODWORDINTREE(0x75800000,0x00000000)}},
+ {VT_exponent,22,0x3a9270,{DOUBLEWITHTWODWORDINTREE(0x75900000,0x00000000)}},
+ {VT_exponent,22,0x3a9271,{DOUBLEWITHTWODWORDINTREE(0x75a00000,0x00000000)}},
+ {VT_exponent,22,0x3a9272,{DOUBLEWITHTWODWORDINTREE(0x75b00000,0x00000000)}},
+ {VT_exponent,22,0x3a9273,{DOUBLEWITHTWODWORDINTREE(0x75c00000,0x00000000)}},
+ {VT_exponent,22,0x3a9274,{DOUBLEWITHTWODWORDINTREE(0x75d00000,0x00000000)}},
+ {VT_exponent,22,0x3a9275,{DOUBLEWITHTWODWORDINTREE(0x75e00000,0x00000000)}},
+ {VT_exponent,22,0x3a9276,{DOUBLEWITHTWODWORDINTREE(0x75f00000,0x00000000)}},
+ {VT_exponent,22,0x3a9277,{DOUBLEWITHTWODWORDINTREE(0x76000000,0x00000000)}},
+ {VT_exponent,22,0x3a9278,{DOUBLEWITHTWODWORDINTREE(0x76100000,0x00000000)}},
+ {VT_exponent,22,0x3a9279,{DOUBLEWITHTWODWORDINTREE(0x76200000,0x00000000)}},
+ {VT_exponent,22,0x3a927a,{DOUBLEWITHTWODWORDINTREE(0x76300000,0x00000000)}},
+ {VT_exponent,22,0x3a927b,{DOUBLEWITHTWODWORDINTREE(0x76400000,0x00000000)}},
+ {VT_exponent,22,0x3a927c,{DOUBLEWITHTWODWORDINTREE(0x76500000,0x00000000)}},
+ {VT_exponent,22,0x3a927d,{DOUBLEWITHTWODWORDINTREE(0x76600000,0x00000000)}},
+ {VT_exponent,22,0x3a927e,{DOUBLEWITHTWODWORDINTREE(0x76700000,0x00000000)}},
+ {VT_exponent,22,0x3a927f,{DOUBLEWITHTWODWORDINTREE(0x76800000,0x00000000)}},
+ {VT_exponent,22,0x3a9280,{DOUBLEWITHTWODWORDINTREE(0x76900000,0x00000000)}},
+ {VT_exponent,22,0x3a9281,{DOUBLEWITHTWODWORDINTREE(0x76a00000,0x00000000)}},
+ {VT_exponent,22,0x3a9282,{DOUBLEWITHTWODWORDINTREE(0x76b00000,0x00000000)}},
+ {VT_exponent,22,0x3a9283,{DOUBLEWITHTWODWORDINTREE(0x76c00000,0x00000000)}},
+ {VT_exponent,22,0x3a9284,{DOUBLEWITHTWODWORDINTREE(0x76d00000,0x00000000)}},
+ {VT_exponent,22,0x3a9285,{DOUBLEWITHTWODWORDINTREE(0x76e00000,0x00000000)}},
+ {VT_exponent,22,0x3a9286,{DOUBLEWITHTWODWORDINTREE(0x76f00000,0x00000000)}},
+ {VT_exponent,22,0x3a9287,{DOUBLEWITHTWODWORDINTREE(0x77000000,0x00000000)}},
+ {VT_exponent,22,0x3a9288,{DOUBLEWITHTWODWORDINTREE(0x77100000,0x00000000)}},
+ {VT_exponent,22,0x3a9289,{DOUBLEWITHTWODWORDINTREE(0x77200000,0x00000000)}},
+ {VT_exponent,22,0x3a928a,{DOUBLEWITHTWODWORDINTREE(0x77300000,0x00000000)}},
+ {VT_exponent,22,0x3a928b,{DOUBLEWITHTWODWORDINTREE(0x77400000,0x00000000)}},
+ {VT_exponent,22,0x3a928c,{DOUBLEWITHTWODWORDINTREE(0x77500000,0x00000000)}},
+ {VT_exponent,22,0x3a928d,{DOUBLEWITHTWODWORDINTREE(0x77600000,0x00000000)}},
+ {VT_exponent,22,0x3a928e,{DOUBLEWITHTWODWORDINTREE(0x77700000,0x00000000)}},
+ {VT_exponent,22,0x3a928f,{DOUBLEWITHTWODWORDINTREE(0x77800000,0x00000000)}},
+ {VT_exponent,22,0x3a9290,{DOUBLEWITHTWODWORDINTREE(0x77900000,0x00000000)}},
+ {VT_exponent,22,0x3a9291,{DOUBLEWITHTWODWORDINTREE(0x77a00000,0x00000000)}},
+ {VT_exponent,22,0x3a9292,{DOUBLEWITHTWODWORDINTREE(0x77b00000,0x00000000)}},
+ {VT_exponent,22,0x3a9293,{DOUBLEWITHTWODWORDINTREE(0x77c00000,0x00000000)}},
+ {VT_exponent,22,0x3a9294,{DOUBLEWITHTWODWORDINTREE(0x77d00000,0x00000000)}},
+ {VT_exponent,22,0x3a9295,{DOUBLEWITHTWODWORDINTREE(0x77e00000,0x00000000)}},
+ {VT_exponent,22,0x3a9296,{DOUBLEWITHTWODWORDINTREE(0x77f00000,0x00000000)}},
+ {VT_exponent,22,0x3a9297,{DOUBLEWITHTWODWORDINTREE(0x78000000,0x00000000)}},
+ {VT_exponent,22,0x3a9298,{DOUBLEWITHTWODWORDINTREE(0x78100000,0x00000000)}},
+ {VT_exponent,22,0x3a9299,{DOUBLEWITHTWODWORDINTREE(0x78200000,0x00000000)}},
+ {VT_exponent,22,0x3a929a,{DOUBLEWITHTWODWORDINTREE(0x78300000,0x00000000)}},
+ {VT_exponent,22,0x3a929b,{DOUBLEWITHTWODWORDINTREE(0x78400000,0x00000000)}},
+ {VT_exponent,22,0x3a929c,{DOUBLEWITHTWODWORDINTREE(0x78500000,0x00000000)}},
+ {VT_exponent,22,0x3a929d,{DOUBLEWITHTWODWORDINTREE(0x78600000,0x00000000)}},
+ {VT_exponent,22,0x3a929e,{DOUBLEWITHTWODWORDINTREE(0x78700000,0x00000000)}},
+ {VT_exponent,22,0x3a929f,{DOUBLEWITHTWODWORDINTREE(0x78800000,0x00000000)}},
+ {VT_exponent,22,0x3a92a0,{DOUBLEWITHTWODWORDINTREE(0x78900000,0x00000000)}},
+ {VT_exponent,22,0x3a92a1,{DOUBLEWITHTWODWORDINTREE(0x78a00000,0x00000000)}},
+ {VT_exponent,22,0x3a92a2,{DOUBLEWITHTWODWORDINTREE(0x78b00000,0x00000000)}},
+ {VT_exponent,22,0x3a92a3,{DOUBLEWITHTWODWORDINTREE(0x78c00000,0x00000000)}},
+ {VT_exponent,22,0x3a92a4,{DOUBLEWITHTWODWORDINTREE(0x78d00000,0x00000000)}},
+ {VT_exponent,22,0x3a92a5,{DOUBLEWITHTWODWORDINTREE(0x78e00000,0x00000000)}},
+ {VT_exponent,22,0x3a92a6,{DOUBLEWITHTWODWORDINTREE(0x78f00000,0x00000000)}},
+ {VT_exponent,22,0x3a92a7,{DOUBLEWITHTWODWORDINTREE(0x79000000,0x00000000)}},
+ {VT_exponent,22,0x3a92a8,{DOUBLEWITHTWODWORDINTREE(0x79100000,0x00000000)}},
+ {VT_exponent,22,0x3a92a9,{DOUBLEWITHTWODWORDINTREE(0x79200000,0x00000000)}},
+ {VT_exponent,22,0x3a92aa,{DOUBLEWITHTWODWORDINTREE(0x79300000,0x00000000)}},
+ {VT_exponent,22,0x3a92ab,{DOUBLEWITHTWODWORDINTREE(0x79400000,0x00000000)}},
+ {VT_exponent,22,0x3a92ac,{DOUBLEWITHTWODWORDINTREE(0x79500000,0x00000000)}},
+ {VT_exponent,22,0x3a92ad,{DOUBLEWITHTWODWORDINTREE(0x79600000,0x00000000)}},
+ {VT_exponent,22,0x3a92ae,{DOUBLEWITHTWODWORDINTREE(0x79700000,0x00000000)}},
+ {VT_exponent,22,0x3a92af,{DOUBLEWITHTWODWORDINTREE(0x79800000,0x00000000)}},
+ {VT_exponent,22,0x3a92b0,{DOUBLEWITHTWODWORDINTREE(0x79900000,0x00000000)}},
+ {VT_exponent,22,0x3a92b1,{DOUBLEWITHTWODWORDINTREE(0x79a00000,0x00000000)}},
+ {VT_exponent,22,0x3a92b2,{DOUBLEWITHTWODWORDINTREE(0x79b00000,0x00000000)}},
+ {VT_exponent,22,0x3a92b3,{DOUBLEWITHTWODWORDINTREE(0x79c00000,0x00000000)}},
+ {VT_exponent,22,0x3a92b4,{DOUBLEWITHTWODWORDINTREE(0x79d00000,0x00000000)}},
+ {VT_exponent,22,0x3a92b5,{DOUBLEWITHTWODWORDINTREE(0x79e00000,0x00000000)}},
+ {VT_exponent,22,0x3a92b6,{DOUBLEWITHTWODWORDINTREE(0x79f00000,0x00000000)}},
+ {VT_exponent,22,0x3a92b7,{DOUBLEWITHTWODWORDINTREE(0x7a000000,0x00000000)}},
+ {VT_exponent,22,0x3a92b8,{DOUBLEWITHTWODWORDINTREE(0x7a100000,0x00000000)}},
+ {VT_exponent,22,0x3a92b9,{DOUBLEWITHTWODWORDINTREE(0x7a200000,0x00000000)}},
+ {VT_exponent,22,0x3a92ba,{DOUBLEWITHTWODWORDINTREE(0x7a300000,0x00000000)}},
+ {VT_exponent,22,0x3a92bb,{DOUBLEWITHTWODWORDINTREE(0x7a400000,0x00000000)}},
+ {VT_exponent,22,0x3a92bc,{DOUBLEWITHTWODWORDINTREE(0x7a500000,0x00000000)}},
+ {VT_exponent,22,0x3a92bd,{DOUBLEWITHTWODWORDINTREE(0x7a600000,0x00000000)}},
+ {VT_exponent,22,0x3a92be,{DOUBLEWITHTWODWORDINTREE(0x7a700000,0x00000000)}},
+ {VT_exponent,22,0x3a92bf,{DOUBLEWITHTWODWORDINTREE(0x7a800000,0x00000000)}},
+ {VT_exponent,22,0x3a92c0,{DOUBLEWITHTWODWORDINTREE(0x7a900000,0x00000000)}},
+ {VT_exponent,22,0x3a92c1,{DOUBLEWITHTWODWORDINTREE(0x7aa00000,0x00000000)}},
+ {VT_exponent,22,0x3a92c2,{DOUBLEWITHTWODWORDINTREE(0x7ab00000,0x00000000)}},
+ {VT_exponent,22,0x3a92c3,{DOUBLEWITHTWODWORDINTREE(0x7ac00000,0x00000000)}},
+ {VT_exponent,22,0x3a92c4,{DOUBLEWITHTWODWORDINTREE(0x7ad00000,0x00000000)}},
+ {VT_exponent,22,0x3a92c5,{DOUBLEWITHTWODWORDINTREE(0x7ae00000,0x00000000)}},
+ {VT_exponent,22,0x3a92c6,{DOUBLEWITHTWODWORDINTREE(0x7af00000,0x00000000)}},
+ {VT_exponent,22,0x3a92c7,{DOUBLEWITHTWODWORDINTREE(0x7b000000,0x00000000)}},
+ {VT_exponent,22,0x3a92c8,{DOUBLEWITHTWODWORDINTREE(0x7b100000,0x00000000)}},
+ {VT_exponent,22,0x3a92c9,{DOUBLEWITHTWODWORDINTREE(0x7b200000,0x00000000)}},
+ {VT_exponent,22,0x3a92ca,{DOUBLEWITHTWODWORDINTREE(0x7b300000,0x00000000)}},
+ {VT_exponent,22,0x3a92cb,{DOUBLEWITHTWODWORDINTREE(0x7b400000,0x00000000)}},
+ {VT_exponent,22,0x3a92cc,{DOUBLEWITHTWODWORDINTREE(0x7b500000,0x00000000)}},
+ {VT_exponent,22,0x3a92cd,{DOUBLEWITHTWODWORDINTREE(0x7b600000,0x00000000)}},
+ {VT_exponent,22,0x3a92ce,{DOUBLEWITHTWODWORDINTREE(0x7b700000,0x00000000)}},
+ {VT_exponent,22,0x3a92cf,{DOUBLEWITHTWODWORDINTREE(0x7b800000,0x00000000)}},
+ {VT_exponent,22,0x3a92d0,{DOUBLEWITHTWODWORDINTREE(0x7b900000,0x00000000)}},
+ {VT_exponent,22,0x3a92d1,{DOUBLEWITHTWODWORDINTREE(0x7ba00000,0x00000000)}},
+ {VT_exponent,22,0x3a92d2,{DOUBLEWITHTWODWORDINTREE(0x7bb00000,0x00000000)}},
+ {VT_exponent,22,0x3a92d3,{DOUBLEWITHTWODWORDINTREE(0x7bc00000,0x00000000)}},
+ {VT_exponent,22,0x3a92d4,{DOUBLEWITHTWODWORDINTREE(0x7bd00000,0x00000000)}},
+ {VT_exponent,22,0x3a92d5,{DOUBLEWITHTWODWORDINTREE(0x7be00000,0x00000000)}},
+ {VT_exponent,22,0x3a92d6,{DOUBLEWITHTWODWORDINTREE(0x7bf00000,0x00000000)}},
+ {VT_exponent,22,0x3a92d7,{DOUBLEWITHTWODWORDINTREE(0x7c000000,0x00000000)}},
+ {VT_exponent,22,0x3a92d8,{DOUBLEWITHTWODWORDINTREE(0x7c100000,0x00000000)}},
+ {VT_exponent,22,0x3a92d9,{DOUBLEWITHTWODWORDINTREE(0x7c200000,0x00000000)}},
+ {VT_exponent,22,0x3a92da,{DOUBLEWITHTWODWORDINTREE(0x7c300000,0x00000000)}},
+ {VT_exponent,22,0x3a92db,{DOUBLEWITHTWODWORDINTREE(0x7c400000,0x00000000)}},
+ {VT_exponent,22,0x3a92dc,{DOUBLEWITHTWODWORDINTREE(0x7c500000,0x00000000)}},
+ {VT_exponent,22,0x3a92dd,{DOUBLEWITHTWODWORDINTREE(0x7c600000,0x00000000)}},
+ {VT_exponent,22,0x3a92de,{DOUBLEWITHTWODWORDINTREE(0x7c700000,0x00000000)}},
+ {VT_exponent,22,0x3a92df,{DOUBLEWITHTWODWORDINTREE(0x7c800000,0x00000000)}},
+ {VT_exponent,22,0x3a92e0,{DOUBLEWITHTWODWORDINTREE(0x7c900000,0x00000000)}},
+ {VT_exponent,22,0x3a92e1,{DOUBLEWITHTWODWORDINTREE(0x7ca00000,0x00000000)}},
+ {VT_exponent,22,0x3a92e2,{DOUBLEWITHTWODWORDINTREE(0x7cb00000,0x00000000)}},
+ {VT_exponent,22,0x3a92e3,{DOUBLEWITHTWODWORDINTREE(0x7cc00000,0x00000000)}},
+ {VT_exponent,22,0x3a92e4,{DOUBLEWITHTWODWORDINTREE(0x7cd00000,0x00000000)}},
+ {VT_exponent,22,0x3a92e5,{DOUBLEWITHTWODWORDINTREE(0x7ce00000,0x00000000)}},
+ {VT_exponent,22,0x3a92e6,{DOUBLEWITHTWODWORDINTREE(0x7cf00000,0x00000000)}},
+ {VT_exponent,22,0x3a92e7,{DOUBLEWITHTWODWORDINTREE(0x7d000000,0x00000000)}},
+ {VT_exponent,22,0x3a92e8,{DOUBLEWITHTWODWORDINTREE(0x7d100000,0x00000000)}},
+ {VT_exponent,22,0x3a92e9,{DOUBLEWITHTWODWORDINTREE(0x7d200000,0x00000000)}},
+ {VT_exponent,22,0x3a92ea,{DOUBLEWITHTWODWORDINTREE(0x7d300000,0x00000000)}},
+ {VT_exponent,22,0x3a92eb,{DOUBLEWITHTWODWORDINTREE(0x7d400000,0x00000000)}},
+ {VT_exponent,22,0x3a92ec,{DOUBLEWITHTWODWORDINTREE(0x7d500000,0x00000000)}},
+ {VT_exponent,22,0x3a92ed,{DOUBLEWITHTWODWORDINTREE(0x7d600000,0x00000000)}},
+ {VT_exponent,22,0x3a92ee,{DOUBLEWITHTWODWORDINTREE(0x7d700000,0x00000000)}},
+ {VT_exponent,22,0x3a92ef,{DOUBLEWITHTWODWORDINTREE(0x7d800000,0x00000000)}},
+ {VT_exponent,22,0x3a92f0,{DOUBLEWITHTWODWORDINTREE(0x7d900000,0x00000000)}},
+ {VT_exponent,22,0x3a92f1,{DOUBLEWITHTWODWORDINTREE(0x7da00000,0x00000000)}},
+ {VT_exponent,22,0x3a92f2,{DOUBLEWITHTWODWORDINTREE(0x7db00000,0x00000000)}},
+ {VT_exponent,22,0x3a92f3,{DOUBLEWITHTWODWORDINTREE(0x7dc00000,0x00000000)}},
+ {VT_exponent,22,0x3a92f4,{DOUBLEWITHTWODWORDINTREE(0x7dd00000,0x00000000)}},
+ {VT_exponent,22,0x3a92f5,{DOUBLEWITHTWODWORDINTREE(0x7de00000,0x00000000)}},
+ {VT_exponent,22,0x3a92f6,{DOUBLEWITHTWODWORDINTREE(0x7df00000,0x00000000)}},
+ {VT_exponent,22,0x3a92f7,{DOUBLEWITHTWODWORDINTREE(0x7e000000,0x00000000)}},
+ {VT_exponent,22,0x3a92f8,{DOUBLEWITHTWODWORDINTREE(0x7e100000,0x00000000)}},
+ {VT_exponent,22,0x3a92f9,{DOUBLEWITHTWODWORDINTREE(0x7e200000,0x00000000)}},
+ {VT_exponent,22,0x3a92fa,{DOUBLEWITHTWODWORDINTREE(0x7e300000,0x00000000)}},
+ {VT_exponent,22,0x3a92fb,{DOUBLEWITHTWODWORDINTREE(0x7e400000,0x00000000)}},
+ {VT_exponent,22,0x3a92fc,{DOUBLEWITHTWODWORDINTREE(0x7e500000,0x00000000)}},
+ {VT_exponent,22,0x3a92fd,{DOUBLEWITHTWODWORDINTREE(0x7e600000,0x00000000)}},
+ {VT_exponent,22,0x3a92fe,{DOUBLEWITHTWODWORDINTREE(0x7e700000,0x00000000)}},
+ {VT_exponent,22,0x3a92ff,{DOUBLEWITHTWODWORDINTREE(0x7e800000,0x00000000)}},
+ {VT_exponent,22,0x3a95a0,{DOUBLEWITHTWODWORDINTREE(0x7e900000,0x00000000)}},
+ {VT_exponent,22,0x3a95a1,{DOUBLEWITHTWODWORDINTREE(0x7ea00000,0x00000000)}},
+ {VT_exponent,22,0x3a95a2,{DOUBLEWITHTWODWORDINTREE(0x7eb00000,0x00000000)}},
+ {VT_exponent,22,0x3a95a3,{DOUBLEWITHTWODWORDINTREE(0x7ec00000,0x00000000)}},
+ {VT_exponent,22,0x3a95a4,{DOUBLEWITHTWODWORDINTREE(0x7ed00000,0x00000000)}},
+ {VT_exponent,22,0x3a95a5,{DOUBLEWITHTWODWORDINTREE(0x7ee00000,0x00000000)}},
+ {VT_exponent,22,0x3a95a6,{DOUBLEWITHTWODWORDINTREE(0x7ef00000,0x00000000)}},
+ {VT_exponent,22,0x3a95a7,{DOUBLEWITHTWODWORDINTREE(0x7f000000,0x00000000)}},
+ {VT_exponent,22,0x3a95a8,{DOUBLEWITHTWODWORDINTREE(0x7f100000,0x00000000)}},
+ {VT_exponent,22,0x3a95a9,{DOUBLEWITHTWODWORDINTREE(0x7f200000,0x00000000)}},
+ {VT_exponent,22,0x3a95aa,{DOUBLEWITHTWODWORDINTREE(0x7f300000,0x00000000)}},
+ {VT_exponent,22,0x3a95ab,{DOUBLEWITHTWODWORDINTREE(0x7f400000,0x00000000)}},
+ {VT_exponent,22,0x3a95ac,{DOUBLEWITHTWODWORDINTREE(0x7f500000,0x00000000)}},
+ {VT_exponent,22,0x3a95ad,{DOUBLEWITHTWODWORDINTREE(0x7f600000,0x00000000)}},
+ {VT_exponent,22,0x3a95ae,{DOUBLEWITHTWODWORDINTREE(0x7f700000,0x00000000)}},
+ {VT_exponent,22,0x3a95af,{DOUBLEWITHTWODWORDINTREE(0x7f800000,0x00000000)}},
+ {VT_exponent,22,0x3b8fe0,{DOUBLEWITHTWODWORDINTREE(0x7f900000,0x00000000)}},
+ {VT_exponent,22,0x3b8fe1,{DOUBLEWITHTWODWORDINTREE(0x7fa00000,0x00000000)}},
+ {VT_exponent,22,0x3b8fe2,{DOUBLEWITHTWODWORDINTREE(0x7fb00000,0x00000000)}},
+ {VT_exponent,22,0x3b8fe3,{DOUBLEWITHTWODWORDINTREE(0x7fc00000,0x00000000)}},
+ {VT_exponent,21,0x68e90,{DOUBLEWITHTWODWORDINTREE(0x7fd00000,0x00000000)}},
+ {VT_exponent,21,0x68e91,{DOUBLEWITHTWODWORDINTREE(0x7fe00000,0x00000000)}},
+ {VT_exponent,21,0x68e98,{DOUBLEWITHTWODWORDINTREE(0x7ff80000,0x00000000)}},
+}; // End of acofdoe array
diff --git a/Build/source/utils/asymptote/prc/PRCdouble.h b/Build/source/utils/asymptote/prc/PRCdouble.h
new file mode 100644
index 00000000000..30d49ffd819
--- /dev/null
+++ b/Build/source/utils/asymptote/prc/PRCdouble.h
@@ -0,0 +1,117 @@
+#ifndef __PRC_DOUBLE_H
+#define __PRC_DOUBLE_H
+
+#include <cstdlib>
+#include <cmath>
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+// from Adobe's documentation
+
+union ieee754_double
+{
+ double d;
+ /* This is the IEEE 754 double-precision format. */
+ struct
+ {
+#if defined(WORDS_BIG_ENDIAN)
+ unsigned int negative:1;
+ unsigned int exponent:11;
+ /* Together these comprise the mantissa. */
+ unsigned int mantissa0:20;
+ unsigned int mantissa1:32;
+#endif
+#if defined(WORDS_LITTLE_ENDIAN)
+ /* Together these comprise the mantissa. */
+ unsigned int mantissa1:32;
+ unsigned int mantissa0:20;
+ unsigned int exponent:11;
+ unsigned int negative:1;
+#endif
+ } ieee;
+};
+
+
+
+
+enum ValueType {VT_double,VT_exponent};
+
+struct sCodageOfFrequentDoubleOrExponent
+{
+ short Type;
+ short NumberOfBits;
+ unsigned Bits;
+ union {
+ unsigned ul[2];
+ double Value;
+ } u2uod;
+};
+
+#if defined(WORDS_LITTLE_ENDIAN)
+# define DOUBLEWITHTWODWORD(upper,lower) lower,upper
+# define UPPERPOWER (1)
+# define LOWERPOWER (!UPPERPOWER)
+
+# define NEXTBYTE(pbd) ((pbd)--)
+# define PREVIOUSBYTE(pbd) ((pbd)++)
+# define MOREBYTE(pbd,pbend) ((pbd)>=(pbend))
+# define OFFSETBYTE(pbd,offset) ((pbd)-=offset)
+# define BEFOREBYTE(pbd) ((pbd)+1)
+# define DIFFPOINTERS(p1,p2) ((unsigned)((p2)-(p1)))
+# define SEARCHBYTE(pbstart,b,nb) (unsigned char *)memchr((pbstart),(b),(nb))
+# define BYTEAT(pb,i) *((pb)+(i))
+
+#elif defined(WORDS_BIG_ENDIAN)
+# define DOUBLEWITHTWODWORD(upper,lower) upper,lower
+# define UPPERPOWER (0)
+# define LOWERPOWER (!UPPERPOWER)
+
+# define NEXTBYTE(pbd) ((pbd)++)
+# define PREVIOUSBYTE(pbd) ((pbd)--)
+# define MOREBYTE(pbd,pbend) ((pbd)<=(pbend))
+# define OFFSETBYTE(pbd,offset) ((pbd)+=offset)
+# define BEFOREBYTE(pbd) ((pbd)-1)
+# define DIFFPOINTERS(p1,p2) ((p1)-(p2))
+# define SEARCHBYTE(pbstart,b,nb) (unsigned char *)memrchr((pbstart),(b),(nb))
+# define BYTEAT(pb,i) *((pb)-(i))
+#else
+# error "Big/Little endian to be defined"
+#endif
+
+#define MAXLENGTHFORCOMPRESSEDTYPE ((22+1+1+4+6*(1+8))+7)/8
+
+#define NEGATIVE(d) (((union ieee754_double *)&(d))->ieee.negative)
+#define EXPONENT(d) (((union ieee754_double *)&(d))->ieee.exponent)
+#define MANTISSA0(d) (((union ieee754_double *)&(d))->ieee.mantissa0)
+#define MANTISSA1(d) (((union ieee754_double *)&(d))->ieee.mantissa1)
+
+typedef unsigned char PRCbyte;
+typedef unsigned short PRCword;
+typedef unsigned PRCdword;
+
+extern PRCdword stadwZero[2],stadwNegativeZero[2];
+
+#define NUMBEROFELEMENTINACOFDOE (2077)
+
+#if defined( WORDS_BIG_ENDIAN )
+# define DOUBLEWITHTWODWORDINTREE(upper,lower) {upper,lower}
+#elif defined( WORDS_LITTLE_ENDIAN )
+# define DOUBLEWITHTWODWORDINTREE(upper,lower) {lower,upper}
+#endif
+extern sCodageOfFrequentDoubleOrExponent acofdoe[NUMBEROFELEMENTINACOFDOE];
+
+struct sCodageOfFrequentDoubleOrExponent* getcofdoe(unsigned,short);
+
+#define STAT_V
+#define STAT_DOUBLE
+
+int stCOFDOECompare(const void*,const void*);
+
+#if defined(WORDS_BIG_ENDIAN)
+void *memrchr(const void *,int,size_t);
+#endif
+
+
+#endif // __PRC_DOUBLE_H
diff --git a/Build/source/utils/asymptote/prc/oPRCFile.cc b/Build/source/utils/asymptote/prc/oPRCFile.cc
new file mode 100644
index 00000000000..77e28d76061
--- /dev/null
+++ b/Build/source/utils/asymptote/prc/oPRCFile.cc
@@ -0,0 +1,847 @@
+/************
+*
+* This file is part of a tool for producing 3D content in the PRC format.
+* Copyright (C) 2008 Orest Shardt <shardtor (at) gmail dot com>
+*
+* This program 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 3 of the License, or
+* (at your option) any later version.
+*
+* This program 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 program. If not, see <http://www.gnu.org/licenses/>.
+*
+*************/
+
+#include "oPRCFile.h"
+#include <time.h>
+
+using std::string;
+
+uint32_t PRCentity::getGraphicsIndex()
+{
+ if(useMaterial)
+ return parent->colourMap.size()+parent->getMaterialIndex(material);
+ else
+ return parent->getColourIndex(colour);
+}
+
+void PRCline::writeRepresentationItem(PRCbitStream &out,uint32_t index)
+{
+ out << (uint32_t)(PRC_TYPE_RI_Curve);
+ ContentPRCBase(&EMPTY_ATTRIBUTES,"line",true,makeCADID(),0,makePRCID()).write(out);
+ writeGraphics(out,m1,getGraphicsIndex(),1);
+ out << (uint32_t)0 // index_local_coordinate_system+1
+ << (uint32_t)0; // index_tessellation
+
+ out << true // has wire body
+ << (uint32_t)index+1 // index of context in geometry section
+ << (uint32_t)1; // body index in topological context
+ UserData(0,0).write(out);
+}
+
+void PRCline::writeTopologicalContext(PRCbitStream &out)
+{
+ // topological context
+ out << (uint32_t)(PRC_TYPE_TOPO_Context);
+ EMPTY_CONTENTPRCBASE.write(out);
+ out << (uint8_t)0 // behaviour
+ << 0.0 // granularity
+ << 0.0 // tolerance
+ << false // have smallest face thickness
+ << false; // have scale
+
+ out << (uint32_t)1; // number of bodies
+ // body
+ out << (uint32_t)PRC_TYPE_TOPO_SingleWireBody;
+
+ out << false // base topology: no base information
+ << (uint8_t)0; // content body: behaviour
+ // Not sure what a 0 means, since it satisfies no #define,
+ // but I think it means no bbox
+
+ // wire edge
+ out << false // not already stored
+ << (uint32_t)PRC_TYPE_TOPO_WireEdge
+ << false; // base topology: no base information
+
+ // polyline
+ out << false // not already stored
+ << (uint32_t)PRC_TYPE_CRV_PolyLine
+ << false // base topology: no base information
+ << (uint32_t)KEPRCExtendTypeNone // extend info
+ << true // is 3d
+ << false // no transformation
+ << 0.0 << static_cast<double>(numberOfPoints-1) // parameterization interval
+ << 1.0 // no reparameterization
+ << 0.0 // no reparameterization
+ << (uint32_t)numberOfPoints;
+
+ // points
+ for(uint32_t i = 0; i < numberOfPoints; ++i)
+ out << points[i][0]*scale << points[i][1]*scale << points[i][2]*scale;
+
+ // ending of wire edge
+ out << false; // trim surface domain
+}
+
+void PRCline::writeExtraGeometryContext(PRCbitStream &out)
+{
+ //geometry summary
+ out << (uint32_t)1; // number of bodies
+ out << (uint32_t)PRC_TYPE_TOPO_SingleWireBody; // body's serial type
+ //context graphics
+ out << (uint32_t)0; // number of treat types
+}
+
+void PRCcurve::writeRepresentationItem(PRCbitStream &out,uint32_t index)
+{
+ out << (uint32_t)(PRC_TYPE_RI_Curve);
+ ContentPRCBase(&EMPTY_ATTRIBUTES,"curve",true,makeCADID(),0,makePRCID()).write(out);
+ writeGraphics(out,m1,getGraphicsIndex(),1);
+ out << (uint32_t)0 // index_local_coordinate_system+1
+ << (uint32_t)0; // index_tessellation
+
+ out << true // has wire body
+ << (uint32_t)index+1 // index of context in geometry section
+ << (uint32_t)1; // body index in topological context
+ UserData(0,0).write(out);
+}
+
+void PRCcurve::writeTopologicalContext(PRCbitStream &out)
+{
+ // topological context
+ out << (uint32_t)(PRC_TYPE_TOPO_Context);
+ EMPTY_CONTENTPRCBASE.write(out);
+ out << (uint8_t)0 // behaviour
+ << 0.0 // granularity
+ << 0.0 // tolerance
+ << false // have smallest face thickness
+ << false; // have scale
+
+ out << (uint32_t)1; // number of bodies
+ // body
+ out << (uint32_t)PRC_TYPE_TOPO_SingleWireBody;
+
+ out << false // base topology: no base information
+ << (uint8_t)0; // content body: behaviour
+ // Not sure what a 0 means, since it satisfies no #define,
+ // but I think it means no bbox
+
+ // wire edge
+ out << false // not already stored
+ << (uint32_t)PRC_TYPE_TOPO_WireEdge
+ << false; // base topology: no base information
+
+ // curve
+ out << false // not already stored
+ << (uint32_t)PRC_TYPE_CRV_NURBS
+ << false // base topology: no base information
+ << (uint32_t)KEPRCExtendTypeNone // extend info
+ << true // is 3D
+ << isRational
+ << (uint32_t)degree // degree
+ << (uint32_t)numberOfControlPoints-1 // control points - 1
+ << (uint32_t)degree+numberOfControlPoints; // knots - 1
+
+ // control points
+ for(uint32_t i = 0; i < numberOfControlPoints; ++i)
+ {
+ out << controlPoints[i][0]*scale << controlPoints[i][1]*scale
+ << controlPoints[i][2]*scale;
+ if(isRational)
+ out << weights[i];
+ }
+
+ writeKnots(out);
+
+ out << (uint32_t)KEPRCKnotTypeUnspecified // KEPRCKnotTypePiecewiseBezierKnots
+ << (uint32_t)KEPRCBSplineCurveFormUnspecified; // curve form
+
+ // ending of wire edge
+ out << false; // trim surface domain
+
+}
+
+void PRCcurve::writeExtraGeometryContext(PRCbitStream &out)
+{
+ //geometry summary
+ out << (uint32_t)1; // number of bodies
+ out << (uint32_t)PRC_TYPE_TOPO_SingleWireBody; // body's serial type
+ //context graphics
+ out << (uint32_t)0; // number of treat types
+}
+
+void PRCsurface::writeRepresentationItem(PRCbitStream &out,uint32_t index)
+{
+ out << (uint32_t)(PRC_TYPE_RI_BrepModel);
+ ContentPRCBase(&EMPTY_ATTRIBUTES,"surface",true,makeCADID(),0,makePRCID()).write(out);
+ writeGraphics(out,0,getGraphicsIndex(),1);
+ out << (uint32_t)0 // index_local_coordinate_system+1
+ << (uint32_t)0; // index_tessellation
+
+ out << true // has brep data
+ << (uint32_t)index+1 // index of context in geometry section
+ << (uint32_t)1 // body index in topological context
+ << false; // is closed???? when is it closed?
+ UserData(0,0).write(out);
+}
+
+void PRCsurface::writeTopologicalContext(PRCbitStream &out)
+{
+ // topological context
+ out << (uint32_t)(PRC_TYPE_TOPO_Context);
+ EMPTY_CONTENTPRCBASE.write(out);
+ out << (uint8_t)0 // behaviour
+ << granularity // granularity
+ << 0.0 // tolerance
+ << false // have smallest face thickness
+ << false; // have scale
+
+ out << (uint32_t)1; // number of bodies
+ // body
+ out << (uint32_t)PRC_TYPE_TOPO_BrepData;
+
+ out << false // base topology: no base information
+ << (uint8_t)0 // content body: behaviour. Not sure what a 0 means, since it satisfies no #define, but I think it means no bbox
+ << (uint32_t)1; // number of connex
+
+ // connex
+ out << false // not already stored
+ << (uint32_t)PRC_TYPE_TOPO_Connex
+ << false // base topology: no base information
+ << (uint32_t)1; // number of shells
+
+ // shell
+ out << false // not already stored
+ << (uint32_t)PRC_TYPE_TOPO_Shell
+ << false // base topology: no base information
+ << false // shell is closed
+ << (uint32_t)1; // number of faces
+
+ // face
+ out << false // not already stored
+ << (uint32_t)PRC_TYPE_TOPO_Face
+ << false; // base topology: no base information
+
+ // NURBS
+ out << false // not already stored
+ << (uint32_t)PRC_TYPE_SURF_NURBS
+ << false // base topology: no base information
+ << (uint32_t)KEPRCExtendTypeNone // Extend Info
+ << isRational // is rational
+ << (uint32_t)degreeU // degree in u
+ << (uint32_t)degreeV // degree in v
+ << (uint32_t)numberOfControlPointsU-1 // control points in u - 1
+ << (uint32_t)numberOfControlPointsV-1 // control points in v - 1
+ << (uint32_t)degreeU+numberOfControlPointsU // knots in u - 1
+ << (uint32_t)degreeV+numberOfControlPointsV; // knots in v -1
+
+ // control points
+ for(uint32_t i = 0; i < numberOfControlPointsU*numberOfControlPointsV; ++i)
+ {
+ out << controlPoints[i][0]*scale << controlPoints[i][1]*scale
+ << controlPoints[i][2]*scale;
+ if(isRational)
+ out << weights[i];
+ }
+
+ writeKnots(out);
+
+ out << (uint32_t)KEPRCKnotTypeUnspecified // KEPRCKnotTypePiecewiseBezierKnots
+ << (uint32_t)KEPRCBSplineSurfaceFormUnspecified; // surface form
+
+ // ending of face
+ out << false // trim surface domain
+ << false // have tolerance
+ << (uint32_t)0 // number of loops
+ << (int32_t)-1; // outer loop index
+
+ // ending of shell
+ out << (uint8_t)1;
+ // orientation of surface normal w.r.t. face normal:
+ // 0: same, 1: opposite, 2: unknown, 1 used in example
+}
+
+void PRCsurface::writeExtraGeometryContext(PRCbitStream &out)
+{
+ //geometry summary
+ out << (uint32_t)1; // number of bodies
+ out << (uint32_t)PRC_TYPE_TOPO_BrepData; // body's serial type
+ //context graphics
+ out << (uint32_t)0; // number of treat types
+}
+
+
+void PRCCompressedSection::write(std::ostream &out)
+{
+ if(prepared)
+ out.write((char*)data,getSize());
+}
+
+void PRCCompressedSection::prepare()
+{
+ writeData();
+ compress();
+ prepared = true;
+}
+
+uint32_t PRCCompressedSection::getSize()
+{
+ if(!prepared)
+ return m1;
+ else
+ return out.getSize();
+}
+
+void PRCGlobalsSection::writeData()
+{
+ // even though this is technically not part of this section,
+ // it is handled here for convenience
+ out << (uint32_t)(0); // number of schemas
+ out << (uint32_t)PRC_TYPE_ASM_FileStructureGlobals;
+
+ SingleAttributeData value = {PRCVersion};
+ SingleAttribute sa(false,EMPTY_ATTRIBUTE_TITLE,KEPRCModellerAttributeTypeInt,value);
+ AttributeTitle iv; iv.text = "__PRC_RESERVED_ATTRIBUTE_PRCInternalVersion";
+ Attribute a(false,iv,1,&sa);
+ Attributes as(1,&a);
+ ContentPRCBase(&as).write(out);
+ out << numberOfReferencedFileStructures; // no referencing of file structures
+ out << tessellationChordHeightRatio;
+ out << tessellationAngleDegrees;
+ out << defaultFontFamilyName; // markup serialization helper
+
+ out << numberOfFonts
+ << (uint32_t)parent->colourMap.size();
+ for(std::vector<RGBAColour>::iterator i = parent->colourMap.begin(); i != parent->colourMap.end(); i++)
+ {
+ out << i->R << i->G << i->B;
+ }
+ out << numberOfPictures << numberOfTextureDefinitions;
+
+ out << (uint32_t)parent->materialMap.size(); // number of materials
+ for(std::vector<PRCMaterial>::iterator i = parent->materialMap.begin(); i != parent->materialMap.end(); i++)
+ {
+ out << (uint32_t)PRC_TYPE_GRAPH_Material;
+ ContentPRCBase(&EMPTY_ATTRIBUTES,"",true,makeCADID(),0,makePRCID()).write(out);
+ out << 3*parent->getColourIndex(i->ambient)+1 // ambient + 1
+ << 3*parent->getColourIndex(i->diffuse)+1 // diffuse + 1
+ << 3*parent->getColourIndex(i->emissive)+1 // emissive + 1
+ << 3*parent->getColourIndex(i->specular)+1 // specular + 1
+ << i->shininess // shininess
+ << i->ambient.A // ambient_alpha
+ << i->diffuse.A // diffuse_alpha
+ << i->emissive.A // emissive_alpha
+ << i->specular.A; // specular_alpha
+ }
+
+ out << (uint32_t)1 // number of line patterns hard coded for now
+ << (uint32_t)PRC_TYPE_GRAPH_LinePattern;
+ ContentPRCBase(&EMPTY_ATTRIBUTES,"",true,makeCADID(),0,makePRCID()).write(out);
+ out << (uint32_t)0 // number of lengths
+ << 0.0 // phase
+ << false; // is real length
+
+ out << (uint32_t)(parent->colourMap.size()+parent->materialMap.size()); // number of styles
+ uint32_t index = 0;
+ // colours are written first
+ for(std::vector<RGBAColour>::iterator i = parent->colourMap.begin(); i != parent->colourMap.end(); i++, ++index)
+ {
+ out << (uint32_t)PRC_TYPE_GRAPH_Style;
+ ContentPRCBase(&EMPTY_ATTRIBUTES,"",true,makeCADID(),0,makePRCID()).write(out);
+ out << 0.0 // line width in mm
+ << false // is vpicture
+ << (uint32_t)1 // line pattern index+1
+ << false // is material
+ << (uint32_t)(3*index+1); // 3*color_index+1
+ if(i->A < 1.0)
+ out << true << (uint8_t)(i->A * 256);
+ else
+ out << false;
+ out << false // additional 1 not defined
+ << false // additional 2 not defined
+ << false; // additional 3 not defined
+ }
+ // materials are after colours
+ index = 0;
+ for(std::vector<PRCMaterial>::iterator i = parent->materialMap.begin(); i != parent->materialMap.end(); i++, ++index)
+ {
+ out << (uint32_t)PRC_TYPE_GRAPH_Style;
+ ContentPRCBase(&EMPTY_ATTRIBUTES,"",true,makeCADID(),0,makePRCID()).write(out);
+ out << 0.0 // line width in mm
+ << false // is vpicture
+ << (uint32_t)1 // line pattern index+1
+ << true // is material
+ << index+1; // material_index+1
+ if(i->alpha < 1.0)
+ out << true << (uint8_t)(i->alpha * 256);
+ else
+ out << false;
+ out << false // additional 1 not defined
+ << false // additional 2 not defined
+ << false; // additional 3 not defined
+ }
+ out << numberOfFillPatterns
+ << numberOfReferenceCoordinateSystems;
+ userData.write(out);
+}
+
+void PRCTreeSection::writeData()
+{
+ out << (uint32_t)(PRC_TYPE_ASM_FileStructureTree);
+
+ EMPTY_CONTENTPRCBASE.write(out);
+
+ out << (uint32_t)1; // number of part definitions
+ // part definitions
+ out << (uint32_t)(PRC_TYPE_ASM_PartDefinition);
+ ContentPRCBase(&EMPTY_ATTRIBUTES,"",true,makeCADID(),0,makePRCID()).write(out);
+ writeGraphics(out,m1,m1,1,true);
+ Point3d M=Point3d(1e20,1e20,1e20);
+ Point3d m=Point3d(-1e20,-1e20,-1e20);
+ Extent3d(M,m).write(out);
+
+ out << (uint32_t)parent->fileEntities.size(); // number of representation items
+ for(uint32_t i = 0; i < parent->fileEntities.size(); ++i)
+ {
+ parent->fileEntities[i]->writeRepresentationItem(out,i);
+ }
+
+ writeEmptyMarkups(out);
+
+ out << (uint32_t)0; // no views
+
+ UserData(0,0).write(out);
+ out << (uint32_t)1; // number of product occurrences
+ // only one product occurrence
+ out << (uint32_t)(PRC_TYPE_ASM_ProductOccurence);
+ SingleAttribute sas[3];
+ SingleAttributeData sad;
+ AttributeTitle at;
+
+ at.text = "FilePath";
+ sad.text = "file name not specified";
+ sas[0] = SingleAttribute(false,at,KEPRCModellerAttributeTypeString,sad);
+
+ at.text = "FileSize";
+ sad.integer = 1234;
+ sas[1] = SingleAttribute(false,at,KEPRCModellerAttributeTypeInt,sad);
+
+ at.text = "FileModificationTime";
+ sad.time = time(NULL);
+ sas[2] = SingleAttribute(false,at,KEPRCModellerAttributeTypeInt,sad);
+
+ at.text = "__PRC_RESERVED_ATTRIBUTE_A3DF_ProductInformation";
+ Attribute attr(false,at,3,sas);
+ Attributes attrs(1,&attr);
+ ContentPRCBase(&attrs,"Unknown",true,makeCADID(),0,makePRCID()).write(out);
+
+ writeGraphics(out,m1,m1,1,true);
+ out << (uint32_t)1 // index_part+1
+ << (uint32_t)0 // index_prototype+1
+ << (uint32_t)0 // index_external_data+1
+ << (uint32_t)0 // number of son product occurrences
+ << (uint8_t)0; // product behaviour
+ writeUnit(out,true,10.0);
+ out << (uint8_t)0 // product information flags
+ << (uint32_t)KEPRCProductLoadStatus_Loaded; // product_load_status
+ out << false // has location
+ << (uint32_t)0; // number of references
+ writeEmptyMarkups(out);
+ out << (uint32_t)0 // number_of_views
+ << false // has entity filter
+ << (uint32_t)0 // number_of_display_filters
+ << (uint32_t)0; // number_of_scene_display_parameters
+ UserData(0,0).write(out);
+
+ // File Structure Internal Data
+ out << (uint32_t)(PRC_TYPE_ASM_FileStructure);
+ EMPTY_CONTENTPRCBASE.write(out);
+ out << makePRCID(); // next available index
+ out << (uint32_t)1; // product occurrence index
+
+ UserData(0,0).write(out);
+}
+
+void PRCTessellationSection::writeData()
+{
+ out << (uint32_t)(PRC_TYPE_ASM_FileStructureTessellation);
+
+ EMPTY_CONTENTPRCBASE.write(out);
+ out << (uint32_t)0; // number of tessellations
+ UserData(0,0).write(out); // no user data
+}
+
+void PRCGeometrySection::writeData()
+{
+ out << (uint32_t)(PRC_TYPE_ASM_FileStructureGeometry);
+
+ EMPTY_CONTENTPRCBASE.write(out);
+ out << (uint32_t)parent->fileEntities.size(); // number of topological contexts
+ for(uint32_t i = 0; i < parent->fileEntities.size(); ++i)
+ {
+ parent->fileEntities[i]->writeTopologicalContext(out);
+ }
+
+ UserData(0,0).write(out);
+}
+
+void PRCExtraGeometrySection::writeData()
+{
+ out << (uint32_t)(PRC_TYPE_ASM_FileStructureExtraGeometry);
+
+ EMPTY_CONTENTPRCBASE.write(out);
+ out << (uint32_t)parent->fileEntities.size(); // number of contexts
+ for(uint32_t i = 0; i < parent->fileEntities.size(); ++i)
+ {
+ parent->fileEntities[i]->writeExtraGeometryContext(out);
+ }
+
+ UserData(0,0).write(out);
+}
+
+void PRCModelFile::writeData()
+{
+ // even though this is technically not part of this section,
+ // it is handled here for convenience
+ out << (uint32_t)(0); // number of schemas
+ out << (uint32_t)(PRC_TYPE_ASM_ModelFile);
+
+ SingleAttributeData value = {PRCVersion};
+ SingleAttribute sa(false,EMPTY_ATTRIBUTE_TITLE,KEPRCModellerAttributeTypeInt,value);
+ AttributeTitle at; at.text = "__PRC_RESERVED_ATTRIBUTE_PRCInternalVersion";
+ Attribute a(false,at,1,&sa);
+ Attributes as(1,&a);
+ ContentPRCBase(&as,"PRC file").write(out);
+
+ writeUnit(out,true,10); // unit is 10 mm, and happens to come from a CAD file
+
+ out << (uint32_t)1; // 1 product occurrence
+ //UUID
+ out << parent->fileStructures[0]->header.fileStructureUUID[0]
+ << parent->fileStructures[0]->header.fileStructureUUID[1]
+ << parent->fileStructures[0]->header.fileStructureUUID[2]
+ << parent->fileStructures[0]->header.fileStructureUUID[3];
+ // index+1
+ out << (uint32_t)1;
+ // active
+ out << true;
+ out << (uint32_t)0; // index in model file
+
+ UserData(0,0).write(out);
+}
+
+void makeFileUUID(uint32_t *UUID)
+{
+ // make a UUID
+ static uint32_t count = 0;
+ ++count;
+ // the minimum requirement on UUIDs is that all must be unique in the file
+ UUID[0] = 0x33595341; // some constant
+ UUID[1] = time(NULL); // the time
+ UUID[2] = count;
+ UUID[3] = 0xa5a55a5a; // Something random, not seeded by the time, would be nice. But for now, a constant
+ // maybe add something else to make it more unique
+ // so multiple files can be combined
+ // a hash of some data perhaps?
+}
+
+void makeAppUUID(uint32_t *UUID)
+{
+ UUID[0] = UUID[1] = UUID[2] = UUID[3] = 0;
+}
+
+void writeUINT32_T(std::ostream &out, uint32_t data)
+{
+#ifdef WORDS_BIG_ENDIAN
+ out.write(((char*)&data)+3,1);
+ out.write(((char*)&data)+2,1);
+ out.write(((char*)&data)+1,1);
+ out.write(((char*)&data)+0,1);
+#elif WORDS_LITTLE_ENDIAN
+ out.write(((char*)&data)+0,1);
+ out.write(((char*)&data)+1,1);
+ out.write(((char*)&data)+2,1);
+ out.write(((char*)&data)+3,1);
+#endif
+}
+
+void PRCUncompressedFile::write(std::ostream &out)
+{
+ writeUINT32_T(out,file_size);
+ out.write((char*)data,file_size);
+}
+
+uint32_t PRCUncompressedFile::getSize()
+{
+ return sizeof(file_size)+file_size;
+}
+
+
+void PRCStartHeader::write(std::ostream &out)
+{
+ out.write("PRC",3);
+ writeUINT32_T(out,minimal_version_for_read);
+ writeUINT32_T(out,authoring_version);
+ writeUINT32_T(out,fileStructureUUID[0]);
+ writeUINT32_T(out,fileStructureUUID[1]);
+ writeUINT32_T(out,fileStructureUUID[2]);
+ writeUINT32_T(out,fileStructureUUID[3]);
+
+ writeUINT32_T(out,applicationUUID[0]);
+ writeUINT32_T(out,applicationUUID[1]);
+ writeUINT32_T(out,applicationUUID[2]);
+ writeUINT32_T(out,applicationUUID[3]);
+}
+
+uint32_t PRCStartHeader::getSize()
+{
+ return 3+(2+2*4)*sizeof(uint32_t);
+}
+
+
+void PRCFileStructure::write(std::ostream &out)
+{
+ header.write(out);
+ writeUINT32_T(out,number_of_uncompressed_files);
+ for(uint32_t i = 0; i < number_of_uncompressed_files; ++i)
+ {
+ uncompressedFiles[i].write(out);
+ }
+ globals.write(out);
+ tree.write(out);
+ tessellations.write(out);
+ geometry.write(out);
+ extraGeometry.write(out);
+}
+
+void PRCFileStructure::prepare()
+{
+ globals.prepare();
+ resetGraphicsAndName();
+
+ tree.prepare();
+ resetGraphicsAndName();
+
+ tessellations.prepare();
+ resetGraphicsAndName();
+
+ geometry.prepare();
+ resetGraphicsAndName();
+
+ extraGeometry.prepare();
+ resetGraphicsAndName();
+}
+
+uint32_t PRCFileStructure::getSize()
+{
+ uint32_t size = 0;
+ size += header.getSize();
+ size += sizeof(uint32_t);
+ for(uint32_t i = 0; i < number_of_uncompressed_files; ++i)
+ size += uncompressedFiles[i].getSize();
+ size += globals.getSize();
+ size += tree.getSize();
+ size += tessellations.getSize();
+ size += geometry.getSize();
+ size += extraGeometry.getSize();
+ return size;
+}
+
+
+void PRCFileStructureInformation::write(std::ostream &out)
+{
+ writeUINT32_T(out,UUID[0]);
+ writeUINT32_T(out,UUID[1]);
+ writeUINT32_T(out,UUID[2]);
+ writeUINT32_T(out,UUID[3]);
+
+ writeUINT32_T(out,reserved);
+ writeUINT32_T(out,number_of_offsets);
+ for(uint32_t i = 0; i < number_of_offsets; ++i)
+ {
+ writeUINT32_T(out,offsets[i]);
+ }
+}
+
+uint32_t PRCFileStructureInformation::getSize()
+{
+ return (4+2+number_of_offsets)*sizeof(uint32_t);
+}
+
+void PRCHeader::write(std::ostream &out)
+{
+ startHeader.write(out);
+ writeUINT32_T(out,number_of_file_structures);
+ for(uint32_t i = 0; i < number_of_file_structures; ++i)
+ {
+ fileStructureInformation[i].write(out);
+ }
+ writeUINT32_T(out,model_file_offset);
+ writeUINT32_T(out,file_size);
+ writeUINT32_T(out,number_of_uncompressed_files);
+ for(uint32_t i = 0; i < number_of_uncompressed_files; ++i)
+ {
+ uncompressedFiles[i].write(out);
+ }
+}
+
+uint32_t PRCHeader::getSize()
+{
+ uint32_t size = startHeader.getSize() + sizeof(uint32_t);
+ for(uint32_t i = 0; i < number_of_file_structures; ++i)
+ size += fileStructureInformation[i].getSize();
+ size += 3*sizeof(uint32_t);
+ for(uint32_t i = 0; i < number_of_uncompressed_files; ++i)
+ size += uncompressedFiles[i].getSize();
+ return size;
+}
+
+bool oPRCFile::add(PRCentity *p)
+{
+ fileEntities.push_back(p);
+ if(p->useMaterial)
+ {
+ if(getMaterialIndex(p->material) == m1)
+ {
+ materialMap.push_back(p->material);
+
+ if(getColourIndex(p->material.ambient) == m1)
+ colourMap.push_back(p->material.ambient);
+
+ if(getColourIndex(p->material.diffuse) == m1)
+ colourMap.push_back(p->material.diffuse);
+
+ if(getColourIndex(p->material.emissive) == m1)
+ colourMap.push_back(p->material.emissive);
+
+ if(getColourIndex(p->material.specular) == m1)
+ colourMap.push_back(p->material.specular);
+ }
+ }
+ else
+ {
+ if(getColourIndex(p->colour) == m1)
+ {
+ colourMap.push_back(p->colour);
+ }
+ }
+ return true;
+}
+
+bool oPRCFile::finish()
+{
+ // only one file structure is currently used
+ // prepare data
+ fileStructures[0] = new PRCFileStructure(this,0);
+ fileStructures[0]->header.minimal_version_for_read = PRCVersion;
+ fileStructures[0]->header.authoring_version = PRCVersion;
+ makeFileUUID(fileStructures[0]->header.fileStructureUUID);
+ makeAppUUID(fileStructures[0]->header.applicationUUID);
+ fileStructures[0]->number_of_uncompressed_files = 0;
+
+ // write each section's bit data
+ fileStructures[0]->prepare();
+ modelFile.prepare();
+
+ // create the header
+
+ // fill out enough info so that sizes can be computed correctly
+ header.number_of_uncompressed_files = 0;
+ header.number_of_file_structures = number_of_file_structures;
+ header.fileStructureInformation = new PRCFileStructureInformation[number_of_file_structures];
+ for(uint32_t i = 0; i < number_of_file_structures; ++i)
+ {
+ header.fileStructureInformation[i].UUID[0] = fileStructures[i]->header.fileStructureUUID[0];
+ header.fileStructureInformation[i].UUID[1] = fileStructures[i]->header.fileStructureUUID[1];
+ header.fileStructureInformation[i].UUID[2] = fileStructures[i]->header.fileStructureUUID[2];
+ header.fileStructureInformation[i].UUID[3] = fileStructures[i]->header.fileStructureUUID[3];
+ header.fileStructureInformation[i].reserved = 0;
+ header.fileStructureInformation[i].number_of_offsets = 6;
+ header.fileStructureInformation[i].offsets = new uint32_t[6];
+ }
+
+ header.startHeader.minimal_version_for_read = PRCVersion;
+ header.startHeader.authoring_version = PRCVersion;
+ makeFileUUID(header.startHeader.fileStructureUUID);
+ makeAppUUID(header.startHeader.applicationUUID);
+
+ header.file_size = getSize();
+ header.model_file_offset = header.file_size - modelFile.getSize();
+
+ uint32_t currentOffset = header.getSize();
+
+ for(uint32_t i = 0; i < number_of_file_structures; ++i)
+ {
+ header.fileStructureInformation[i].offsets[0] = currentOffset; // header offset
+ currentOffset += fileStructures[i]->header.getSize() + sizeof(uint32_t);
+ for(uint32_t j = 0; j < fileStructures[i]->number_of_uncompressed_files; ++j)
+ currentOffset += fileStructures[i]->uncompressedFiles[j].getSize();
+ header.fileStructureInformation[i].offsets[1] = currentOffset; // globals offset
+ currentOffset += fileStructures[i]->globals.getSize();
+ header.fileStructureInformation[i].offsets[2] = currentOffset; // tree offset
+ currentOffset += fileStructures[i]->tree.getSize();
+ header.fileStructureInformation[i].offsets[3] = currentOffset; // tessellations offset
+ currentOffset += fileStructures[i]->tessellations.getSize();
+ header.fileStructureInformation[i].offsets[4] = currentOffset; // geometry offset
+ currentOffset += fileStructures[i]->geometry.getSize();
+ header.fileStructureInformation[i].offsets[5] = currentOffset; // extra geometry offset
+ currentOffset += fileStructures[i]->extraGeometry.getSize();
+ }
+
+ // write the data
+ header.write(output);
+
+ for(uint32_t i = 0; i < number_of_file_structures; ++i)
+ {
+ fileStructures[i]->write(output);
+ }
+
+ modelFile.write(output);
+ output.flush();
+
+ for(uint32_t i = 0; i < number_of_file_structures; ++i)
+ delete[] header.fileStructureInformation[i].offsets;
+ delete[] header.fileStructureInformation;
+
+ return true;
+}
+
+uint32_t oPRCFile::getColourIndex(const RGBAColour &c)
+{
+ for(uint32_t i = 0; i < colourMap.size(); ++i)
+ {
+ if(colourMap[i] == c)
+ return i;
+ }
+ return m1;
+}
+
+uint32_t oPRCFile::getMaterialIndex(const PRCMaterial &m)
+{
+ for(uint32_t i = 0; i < materialMap.size(); ++i)
+ {
+ if(materialMap[i] == m)
+ return i;
+ }
+ return m1;
+}
+
+uint32_t oPRCFile::getSize()
+{
+ uint32_t size = header.getSize();
+
+ for(uint32_t i = 0; i < number_of_file_structures; ++i)
+ {
+ size += fileStructures[i]->getSize();
+ }
+
+ size += modelFile.getSize();
+ return size;
+}
diff --git a/Build/source/utils/asymptote/prc/oPRCFile.h b/Build/source/utils/asymptote/prc/oPRCFile.h
new file mode 100644
index 00000000000..1714c60492e
--- /dev/null
+++ b/Build/source/utils/asymptote/prc/oPRCFile.h
@@ -0,0 +1,395 @@
+/************
+*
+* This file is part of a tool for producing 3D content in the PRC format.
+* Copyright (C) 2008 Orest Shardt <shardtor (at) gmail dot com>
+*
+* This program 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 3 of the License, or
+* (at your option) any later version.
+*
+* This program 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 program. If not, see <http://www.gnu.org/licenses/>.
+*
+*************/
+
+#ifndef __O_PRC_FILE_H
+#define __O_PRC_FILE_H
+
+#include <iostream>
+#include <fstream>
+#include <vector>
+#include <string>
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "PRC.h"
+#include "PRCbitStream.h"
+#include "writePRC.h"
+
+class oPRCFile;
+
+struct RGBAColour
+{
+ RGBAColour(double r=0.0, double g=0.0, double b=0.0, double a=1.0) :
+ R(r), G(g), B(b), A(a) {}
+ double R,G,B,A;
+
+ bool operator==(const RGBAColour &c) const
+ {
+ return (R==c.R && G==c.G && B==c.B && A==c.A);
+ }
+};
+
+struct PRCMaterial
+{
+ PRCMaterial() : alpha(1.0),shininess(1.0) {}
+ PRCMaterial(const RGBAColour &a, const RGBAColour &d, const RGBAColour &e,
+ const RGBAColour &s, double p, double h) :
+ ambient(a), diffuse(d), emissive(e), specular(s), alpha(p), shininess(h) {}
+ RGBAColour ambient,diffuse,emissive,specular;
+ double alpha,shininess;
+
+ bool operator==(const PRCMaterial &m) const
+ {
+ return (ambient==m.ambient && diffuse==m.diffuse && emissive==m.emissive
+ && specular==m.specular && shininess==m.shininess);
+ }
+};
+
+class PRCentity
+{
+ public:
+ PRCentity(oPRCFile *p,const RGBAColour &c, double scale = 1.0) :
+ colour(c), useMaterial(false), scale(scale), parent(p) {}
+ PRCentity(oPRCFile *p,const PRCMaterial &m, double scale = 1.0) :
+ material(m), useMaterial(true), scale(scale), parent(p) {}
+ uint32_t getGraphicsIndex();
+ virtual void writeRepresentationItem(PRCbitStream&,uint32_t) = 0;
+ virtual void writeTopologicalContext(PRCbitStream&) = 0;
+ virtual void writeExtraGeometryContext(PRCbitStream&) = 0;
+ RGBAColour colour;
+ PRCMaterial material;
+ bool useMaterial;
+ double scale;
+ virtual ~PRCentity() {}
+ protected:
+ oPRCFile *parent;
+};
+
+class PRCsurface : public PRCentity
+{
+ public:
+ // contructor with colour
+ PRCsurface(oPRCFile *p, uint32_t dU, uint32_t dV, uint32_t nU, uint32_t nV,
+ double cP[][3], double *kU, double *kV, const RGBAColour &c,
+ double scale = 1.0, bool iR = false, double w[] = 0,
+ double g = 0) :
+ PRCentity(p,c,scale), degreeU(dU), degreeV(dV),
+ numberOfControlPointsU(nU), numberOfControlPointsV(nV),
+ knotsU(kU), knotsV(kV), controlPoints(cP),
+ isRational(iR), weights(w), granularity(g) {}
+ // contructor with material
+ PRCsurface(oPRCFile *p, uint32_t dU, uint32_t dV, uint32_t nU, uint32_t nV,
+ double cP[][3], double *kU, double *kV, const PRCMaterial &m,
+ double scale = 1.0, bool iR = false, double w[] = 0,
+ double g = 0) :
+ PRCentity(p,m,scale), degreeU(dU), degreeV(dV),
+ numberOfControlPointsU(nU), numberOfControlPointsV(nV),
+ knotsU(kU), knotsV(kV), controlPoints(cP),
+ isRational(iR), weights(w), granularity(g) {}
+ virtual void writeRepresentationItem(PRCbitStream&,uint32_t);
+ virtual void writeTopologicalContext(PRCbitStream&);
+ virtual void writeExtraGeometryContext(PRCbitStream&);
+ protected:
+ virtual void writeKnots(PRCbitStream &out)
+ {
+ for(uint32_t i = 0; i < degreeU+numberOfControlPointsU+1; ++i)
+ out << knotsU[i];
+ for(uint32_t i = 0; i < degreeV+numberOfControlPointsV+1; ++i)
+ out << knotsV[i];
+ }
+ private:
+ uint32_t degreeU, degreeV, numberOfControlPointsU, numberOfControlPointsV;
+ double *knotsU, *knotsV;
+ double (*controlPoints)[3];
+ bool isRational;
+ double *weights;
+ double granularity;
+};
+
+class PRCline : public PRCentity
+{
+ public:
+ // constructor with colour
+ PRCline(oPRCFile *p, uint32_t n, double P[][3], const RGBAColour &c,
+ double scale = 1.0) :
+ PRCentity(p,c,scale), numberOfPoints(n), points(P) {}
+ // constructor with material
+ PRCline(oPRCFile *p, uint32_t n, double P[][3], const PRCMaterial &m,
+ double scale = 1.0) :
+ PRCentity(p,m,scale), numberOfPoints(n), points(P) {}
+ virtual void writeRepresentationItem(PRCbitStream&,uint32_t);
+ virtual void writeTopologicalContext(PRCbitStream&);
+ virtual void writeExtraGeometryContext(PRCbitStream&);
+ private:
+ uint32_t numberOfPoints;
+ double (*points)[3];
+};
+
+class PRCcurve : public PRCentity
+{
+ public:
+ // constructor with colour
+ PRCcurve(oPRCFile *p, uint32_t d, uint32_t n, double cP[][3], double *k,
+ const RGBAColour &c, double scale = 1.0, bool iR = false,
+ double w[] = 0) :
+ PRCentity(p,c,scale), degree(d), numberOfControlPoints(n), knots(k),
+ controlPoints(cP), isRational(iR), weights(w) {}
+ // constructor with material
+ PRCcurve(oPRCFile *p, uint32_t d, uint32_t n, double cP[][3], double *k,
+ const PRCMaterial &m, double scale = 1.0, bool iR = false,
+ double w[] = 0) :
+ PRCentity(p,m,scale), degree(d), numberOfControlPoints(n), knots(k),
+ controlPoints(cP), isRational(iR), weights(w) {}
+ virtual void writeRepresentationItem(PRCbitStream&,uint32_t);
+ virtual void writeTopologicalContext(PRCbitStream&);
+ virtual void writeExtraGeometryContext(PRCbitStream&);
+ protected:
+ virtual void writeKnots(PRCbitStream &out)
+ {
+ for(uint32_t i = 0; i < degree+numberOfControlPoints+1; ++i)
+ out << knots[i];
+ }
+ private:
+ uint32_t degree, numberOfControlPoints;
+ double *knots;
+ double (*controlPoints)[3];
+ bool isRational;
+ double *weights;
+};
+
+class PRCCompressedSection
+{
+ public:
+ PRCCompressedSection(oPRCFile *p) : data(0),prepared(false),parent(p),
+ out(data,0) {}
+ virtual ~PRCCompressedSection()
+ {
+ free(data);
+ }
+ void write(std::ostream&);
+ void prepare();
+ uint32_t getSize();
+
+ private:
+ virtual void writeData() = 0;
+ uint8_t *data;
+ protected:
+ void compress()
+ {
+ out.compress();
+ }
+ bool prepared;
+ oPRCFile *parent;
+ PRCbitStream out; // order matters: PRCbitStream must be initialized last
+};
+
+class PRCGlobalsSection : public PRCCompressedSection
+{
+ public:
+ PRCGlobalsSection(oPRCFile *p, uint32_t i) :
+ PRCCompressedSection(p),numberOfReferencedFileStructures(0),
+ tessellationChordHeightRatio(2000.0),tessellationAngleDegrees(40.0),
+ defaultFontFamilyName(""),numberOfFonts(0),numberOfPictures(0),
+ numberOfTextureDefinitions(0),numberOfFillPatterns(0),
+ numberOfReferenceCoordinateSystems(0),userData(0,0),index(i) {}
+ uint32_t numberOfReferencedFileStructures;
+ double tessellationChordHeightRatio;
+ double tessellationAngleDegrees;
+ std::string defaultFontFamilyName;
+ uint32_t numberOfFonts,numberOfPictures,numberOfTextureDefinitions;
+ uint32_t numberOfFillPatterns;
+ uint32_t numberOfReferenceCoordinateSystems;
+ UserData userData;
+ private:
+ uint32_t index;
+ virtual void writeData();
+};
+
+class PRCTreeSection : public PRCCompressedSection
+{
+ public:
+ PRCTreeSection(oPRCFile *p, uint32_t i) :
+ PRCCompressedSection(p),index(i) {}
+ private:
+ uint32_t index;
+ virtual void writeData();
+};
+
+class PRCTessellationSection : public PRCCompressedSection
+{
+ public:
+ PRCTessellationSection(oPRCFile *p, uint32_t i) :
+ PRCCompressedSection(p),index(i) {}
+ private:
+ uint32_t index;
+ virtual void writeData();
+};
+
+class PRCGeometrySection : public PRCCompressedSection
+{
+ public:
+ PRCGeometrySection(oPRCFile *p, uint32_t i) :
+ PRCCompressedSection(p),index(i) {}
+ private:
+ uint32_t index;
+ virtual void writeData();
+};
+
+class PRCExtraGeometrySection : public PRCCompressedSection
+{
+ public:
+ PRCExtraGeometrySection(oPRCFile *p, uint32_t i) :
+ PRCCompressedSection(p),index(i) {}
+ private:
+ uint32_t index;
+ virtual void writeData();
+};
+
+class PRCModelFile : public PRCCompressedSection
+{
+ public:
+ PRCModelFile(oPRCFile *p) : PRCCompressedSection(p) {}
+ private:
+ virtual void writeData();
+};
+
+void makeFileUUID(uint32_t*);
+void makeAppUUID(uint32_t*);
+
+class PRCUncompressedFile
+{
+ public:
+ uint32_t file_size;
+ uint8_t *data;
+
+ void write(std::ostream&);
+
+ uint32_t getSize();
+};
+
+class PRCStartHeader
+{
+ public:
+ uint32_t minimal_version_for_read; // PRCVersion
+ uint32_t authoring_version; // PRCVersion
+ uint32_t fileStructureUUID[4];
+ uint32_t applicationUUID[4]; // should be 0
+
+ void write(std::ostream&);
+
+ uint32_t getSize();
+};
+
+class PRCFileStructure
+{
+ private:
+ oPRCFile *parent;
+ uint32_t index;
+ public:
+ PRCStartHeader header;
+ uint32_t number_of_uncompressed_files;
+ PRCUncompressedFile *uncompressedFiles;
+
+ PRCGlobalsSection globals;
+ PRCTreeSection tree;
+ PRCTessellationSection tessellations;
+ PRCGeometrySection geometry;
+ PRCExtraGeometrySection extraGeometry;
+
+ PRCFileStructure(oPRCFile *p, uint32_t i) : parent(p),index(i),
+ globals(p,i),tree(p,i),tessellations(p,i),geometry(p,i),
+ extraGeometry(p,i) {}
+ void write(std::ostream&);
+ void prepare();
+ uint32_t getSize();
+};
+
+class PRCFileStructureInformation
+{
+ public:
+ uint32_t UUID[4];
+ uint32_t reserved; // 0
+ uint32_t number_of_offsets;
+ uint32_t *offsets;
+
+ void write(std::ostream&);
+
+ uint32_t getSize();
+};
+
+class PRCHeader
+{
+ public :
+ PRCStartHeader startHeader;
+ uint32_t number_of_file_structures;
+ PRCFileStructureInformation *fileStructureInformation;
+ uint32_t model_file_offset;
+ uint32_t file_size; // not documented
+ uint32_t number_of_uncompressed_files;
+ PRCUncompressedFile *uncompressedFiles;
+
+ void write(std::ostream&);
+ uint32_t getSize();
+};
+
+class oPRCFile
+{
+ public:
+ oPRCFile(std::ostream &os, uint32_t n=1) :
+ number_of_file_structures(n),
+ fileStructures(new PRCFileStructure*[n]),modelFile(this),
+ fout(NULL),output(os) {}
+
+ oPRCFile(const std::string &name, uint32_t n=1) :
+ number_of_file_structures(n),
+ fileStructures(new PRCFileStructure*[n]),modelFile(this),
+ fout(new std::ofstream(name.c_str())),output(*fout) {}
+
+ ~oPRCFile()
+ {
+ for(uint32_t i = 0; i < number_of_file_structures; ++i)
+ delete fileStructures[i];
+ delete[] fileStructures;
+ if(fout != NULL)
+ delete fout;
+ }
+
+ bool add(PRCentity*);
+ bool finish();
+ uint32_t getColourIndex(const RGBAColour&);
+ uint32_t getMaterialIndex(const PRCMaterial&);
+ uint32_t getSize();
+
+ const uint32_t number_of_file_structures;
+ PRCFileStructure **fileStructures;
+ PRCHeader header;
+ PRCModelFile modelFile;
+ std::vector<PRCentity*> fileEntities;
+ std::vector<RGBAColour> colourMap;
+ std::vector<PRCMaterial> materialMap;
+
+ private:
+ std::ofstream *fout;
+ std::ostream &output;
+};
+
+#endif // __O_PRC_FILE_H
diff --git a/Build/source/utils/asymptote/prc/test.cc b/Build/source/utils/asymptote/prc/test.cc
new file mode 100644
index 00000000000..e450f3acd01
--- /dev/null
+++ b/Build/source/utils/asymptote/prc/test.cc
@@ -0,0 +1,277 @@
+/************
+*
+* This file is part of a tool for producing 3D content in the PRC format.
+* Copyright (C) 2008 Orest Shardt <shardtor (at) gmail dot com>
+*
+* This program 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 3 of the License, or
+* (at your option) any later version.
+*
+* This program 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 program. If not, see <http://www.gnu.org/licenses/>.
+*
+*************/
+
+#include <iostream>
+#include <iomanip>
+#include <fstream>
+#include <cmath>
+#include "oPRCFile.h"
+
+using namespace std;
+
+int main()
+{
+// ofstream outf("test.prc",ios::binary);
+ double knotsU[] = {1,1,1,1,2,2,2,2};
+ double knotsV[] = {1,1,1,1,2,2,2,2};
+ const int NUMBER_OF_PATCHES = 32;
+ double controlPoints[NUMBER_OF_PATCHES][16][3] =
+ {
+ { // Patch 0
+ {1.4,0,2.4},{1.4,-0.784,2.4},{0.784,-1.4,2.4},{0,-1.4,2.4},
+ {1.3375,0,2.53125},{1.3375,-0.749,2.53125},{0.749,-1.3375,2.53125},{0,-1.3375,2.53125},
+ {1.4375,0,2.53125},{1.4375,-0.805,2.53125},{0.805,-1.4375,2.53125},{0,-1.4375,2.53125},
+ {1.5,0,2.4},{1.5,-0.84,2.4},{0.84,-1.5,2.4},{0,-1.5,2.4},
+ },
+ { // Patch 1
+ {0,-1.4,2.4},{-0.784,-1.4,2.4},{-1.4,-0.784,2.4},{-1.4,0,2.4},
+ {0,-1.3375,2.53125},{-0.749,-1.3375,2.53125},{-1.3375,-0.749,2.53125},{-1.3375,0,2.53125},
+ {0,-1.4375,2.53125},{-0.805,-1.4375,2.53125},{-1.4375,-0.805,2.53125},{-1.4375,0,2.53125},
+ {0,-1.5,2.4},{-0.84,-1.5,2.4},{-1.5,-0.84,2.4},{-1.5,0,2.4},
+ },
+ { // Patch 2
+ {-1.4,0,2.4},{-1.4,0.784,2.4},{-0.784,1.4,2.4},{0,1.4,2.4},
+ {-1.3375,0,2.53125},{-1.3375,0.749,2.53125},{-0.749,1.3375,2.53125},{0,1.3375,2.53125},
+ {-1.4375,0,2.53125},{-1.4375,0.805,2.53125},{-0.805,1.4375,2.53125},{0,1.4375,2.53125},
+ {-1.5,0,2.4},{-1.5,0.84,2.4},{-0.84,1.5,2.4},{0,1.5,2.4},
+ },
+ { // Patch 3
+ {0,1.4,2.4},{0.784,1.4,2.4},{1.4,0.784,2.4},{1.4,0,2.4},
+ {0,1.3375,2.53125},{0.749,1.3375,2.53125},{1.3375,0.749,2.53125},{1.3375,0,2.53125},
+ {0,1.4375,2.53125},{0.805,1.4375,2.53125},{1.4375,0.805,2.53125},{1.4375,0,2.53125},
+ {0,1.5,2.4},{0.84,1.5,2.4},{1.5,0.84,2.4},{1.5,0,2.4},
+ },
+ { // Patch 4
+ {1.5,0,2.4},{1.5,-0.84,2.4},{0.84,-1.5,2.4},{0,-1.5,2.4},
+ {1.75,0,1.875},{1.75,-0.98,1.875},{0.98,-1.75,1.875},{0,-1.75,1.875},
+ {2,0,1.35},{2,-1.12,1.35},{1.12,-2,1.35},{0,-2,1.35},
+ {2,0,0.9},{2,-1.12,0.9},{1.12,-2,0.9},{0,-2,0.9},
+ },
+ { // Patch 5
+ {0,-1.5,2.4},{-0.84,-1.5,2.4},{-1.5,-0.84,2.4},{-1.5,0,2.4},
+ {0,-1.75,1.875},{-0.98,-1.75,1.875},{-1.75,-0.98,1.875},{-1.75,0,1.875},
+ {0,-2,1.35},{-1.12,-2,1.35},{-2,-1.12,1.35},{-2,0,1.35},
+ {0,-2,0.9},{-1.12,-2,0.9},{-2,-1.12,0.9},{-2,0,0.9},
+ },
+ { // Patch 6
+ {-1.5,0,2.4},{-1.5,0.84,2.4},{-0.84,1.5,2.4},{0,1.5,2.4},
+ {-1.75,0,1.875},{-1.75,0.98,1.875},{-0.98,1.75,1.875},{0,1.75,1.875},
+ {-2,0,1.35},{-2,1.12,1.35},{-1.12,2,1.35},{0,2,1.35},
+ {-2,0,0.9},{-2,1.12,0.9},{-1.12,2,0.9},{0,2,0.9},
+ },
+ { // Patch 7
+ {0,1.5,2.4},{0.84,1.5,2.4},{1.5,0.84,2.4},{1.5,0,2.4},
+ {0,1.75,1.875},{0.98,1.75,1.875},{1.75,0.98,1.875},{1.75,0,1.875},
+ {0,2,1.35},{1.12,2,1.35},{2,1.12,1.35},{2,0,1.35},
+ {0,2,0.9},{1.12,2,0.9},{2,1.12,0.9},{2,0,0.9},
+ },
+ { // Patch 8
+ {2,0,0.9},{2,-1.12,0.9},{1.12,-2,0.9},{0,-2,0.9},
+ {2,0,0.45},{2,-1.12,0.45},{1.12,-2,0.45},{0,-2,0.45},
+ {1.5,0,0.225},{1.5,-0.84,0.225},{0.84,-1.5,0.225},{0,-1.5,0.225},
+ {1.5,0,0.15},{1.5,-0.84,0.15},{0.84,-1.5,0.15},{0,-1.5,0.15},
+ },
+ { // Patch 9
+ {0,-2,0.9},{-1.12,-2,0.9},{-2,-1.12,0.9},{-2,0,0.9},
+ {0,-2,0.45},{-1.12,-2,0.45},{-2,-1.12,0.45},{-2,0,0.45},
+ {0,-1.5,0.225},{-0.84,-1.5,0.225},{-1.5,-0.84,0.225},{-1.5,0,0.225},
+ {0,-1.5,0.15},{-0.84,-1.5,0.15},{-1.5,-0.84,0.15},{-1.5,0,0.15},
+ },
+ { // Patch 10
+ {-2,0,0.9},{-2,1.12,0.9},{-1.12,2,0.9},{0,2,0.9},
+ {-2,0,0.45},{-2,1.12,0.45},{-1.12,2,0.45},{0,2,0.45},
+ {-1.5,0,0.225},{-1.5,0.84,0.225},{-0.84,1.5,0.225},{0,1.5,0.225},
+ {-1.5,0,0.15},{-1.5,0.84,0.15},{-0.84,1.5,0.15},{0,1.5,0.15},
+ },
+ { // Patch 11
+ {0,2,0.9},{1.12,2,0.9},{2,1.12,0.9},{2,0,0.9},
+ {0,2,0.45},{1.12,2,0.45},{2,1.12,0.45},{2,0,0.45},
+ {0,1.5,0.225},{0.84,1.5,0.225},{1.5,0.84,0.225},{1.5,0,0.225},
+ {0,1.5,0.15},{0.84,1.5,0.15},{1.5,0.84,0.15},{1.5,0,0.15},
+ },
+ { // Patch 12
+ {-1.6,0,2.025},{-1.6,-0.3,2.025},{-1.5,-0.3,2.25},{-1.5,0,2.25},
+ {-2.3,0,2.025},{-2.3,-0.3,2.025},{-2.5,-0.3,2.25},{-2.5,0,2.25},
+ {-2.7,0,2.025},{-2.7,-0.3,2.025},{-3,-0.3,2.25},{-3,0,2.25},
+ {-2.7,0,1.8},{-2.7,-0.3,1.8},{-3,-0.3,1.8},{-3,0,1.8},
+ },
+ { // Patch 13
+ {-1.5,0,2.25},{-1.5,0.3,2.25},{-1.6,0.3,2.025},{-1.6,0,2.025},
+ {-2.5,0,2.25},{-2.5,0.3,2.25},{-2.3,0.3,2.025},{-2.3,0,2.025},
+ {-3,0,2.25},{-3,0.3,2.25},{-2.7,0.3,2.025},{-2.7,0,2.025},
+ {-3,0,1.8},{-3,0.3,1.8},{-2.7,0.3,1.8},{-2.7,0,1.8},
+ },
+ { // Patch 14
+ {-2.7,0,1.8},{-2.7,-0.3,1.8},{-3,-0.3,1.8},{-3,0,1.8},
+ {-2.7,0,1.575},{-2.7,-0.3,1.575},{-3,-0.3,1.35},{-3,0,1.35},
+ {-2.5,0,1.125},{-2.5,-0.3,1.125},{-2.65,-0.3,0.9375},{-2.65,0,0.9375},
+ {-2,0,0.9},{-2,-0.3,0.9},{-1.9,-0.3,0.6},{-1.9,0,0.6},
+ },
+ { // Patch 15
+ {-3,0,1.8},{-3,0.3,1.8},{-2.7,0.3,1.8},{-2.7,0,1.8},
+ {-3,0,1.35},{-3,0.3,1.35},{-2.7,0.3,1.575},{-2.7,0,1.575},
+ {-2.65,0,0.9375},{-2.65,0.3,0.9375},{-2.5,0.3,1.125},{-2.5,0,1.125},
+ {-1.9,0,0.6},{-1.9,0.3,0.6},{-2,0.3,0.9},{-2,0,0.9},
+ },
+ { // Patch 16
+ {1.7,0,1.425},{1.7,-0.66,1.425},{1.7,-0.66,0.6},{1.7,0,0.6},
+ {2.6,0,1.425},{2.6,-0.66,1.425},{3.1,-0.66,0.825},{3.1,0,0.825},
+ {2.3,0,2.1},{2.3,-0.25,2.1},{2.4,-0.25,2.025},{2.4,0,2.025},
+ {2.7,0,2.4},{2.7,-0.25,2.4},{3.3,-0.25,2.4},{3.3,0,2.4},
+ },
+ { // Patch 17
+ {1.7,0,0.6},{1.7,0.66,0.6},{1.7,0.66,1.425},{1.7,0,1.425},
+ {3.1,0,0.825},{3.1,0.66,0.825},{2.6,0.66,1.425},{2.6,0,1.425},
+ {2.4,0,2.025},{2.4,0.25,2.025},{2.3,0.25,2.1},{2.3,0,2.1},
+ {3.3,0,2.4},{3.3,0.25,2.4},{2.7,0.25,2.4},{2.7,0,2.4},
+ },
+ { // Patch 18
+ {2.7,0,2.4},{2.7,-0.25,2.4},{3.3,-0.25,2.4},{3.3,0,2.4},
+ {2.8,0,2.475},{2.8,-0.25,2.475},{3.525,-0.25,2.49375},{3.525,0,2.49375},
+ {2.9,0,2.475},{2.9,-0.15,2.475},{3.45,-0.15,2.5125},{3.45,0,2.5125},
+ {2.8,0,2.4},{2.8,-0.15,2.4},{3.2,-0.15,2.4},{3.2,0,2.4},
+ },
+ { // Patch 19
+ {3.3,0,2.4},{3.3,0.25,2.4},{2.7,0.25,2.4},{2.7,0,2.4},
+ {3.525,0,2.49375},{3.525,0.25,2.49375},{2.8,0.25,2.475},{2.8,0,2.475},
+ {3.45,0,2.5125},{3.45,0.15,2.5125},{2.9,0.15,2.475},{2.9,0,2.475},
+ {3.2,0,2.4},{3.2,0.15,2.4},{2.8,0.15,2.4},{2.8,0,2.4},
+ },
+ { // Patch 20
+ {0,0,3.15},{0,0,3.15},{0,0,3.15},{0,0,3.15},
+ {0.8,0,3.15},{0.8,-0.45,3.15},{0.45,-0.8,3.15},{0,-0.8,3.15},
+ {0,0,2.85},{0,0,2.85},{0,0,2.85},{0,0,2.85},
+ {0.2,0,2.7},{0.2,-0.112,2.7},{0.112,-0.2,2.7},{0,-0.2,2.7},
+ },
+ { // Patch 21
+ {0,0,3.15},{0,0,3.15},{0,0,3.15},{0,0,3.15},
+ {0,-0.8,3.15},{-0.45,-0.8,3.15},{-0.8,-0.45,3.15},{-0.8,0,3.15},
+ {0,0,2.85},{0,0,2.85},{0,0,2.85},{0,0,2.85},
+ {0,-0.2,2.7},{-0.112,-0.2,2.7},{-0.2,-0.112,2.7},{-0.2,0,2.7},
+ },
+ { // Patch 22
+ {0,0,3.15},{0,0,3.15},{0,0,3.15},{0,0,3.15},
+ {-0.8,0,3.15},{-0.8,0.45,3.15},{-0.45,0.8,3.15},{0,0.8,3.15},
+ {0,0,2.85},{0,0,2.85},{0,0,2.85},{0,0,2.85},
+ {-0.2,0,2.7},{-0.2,0.112,2.7},{-0.112,0.2,2.7},{0,0.2,2.7},
+ },
+ { // Patch 23
+ {0,0,3.15},{0,0,3.15},{0,0,3.15},{0,0,3.15},
+ {0,0.8,3.15},{0.45,0.8,3.15},{0.8,0.45,3.15},{0.8,0,3.15},
+ {0,0,2.85},{0,0,2.85},{0,0,2.85},{0,0,2.85},
+ {0,0.2,2.7},{0.112,0.2,2.7},{0.2,0.112,2.7},{0.2,0,2.7},
+ },
+ { // Patch 24
+ {0.2,0,2.7},{0.2,-0.112,2.7},{0.112,-0.2,2.7},{0,-0.2,2.7},
+ {0.4,0,2.55},{0.4,-0.224,2.55},{0.224,-0.4,2.55},{0,-0.4,2.55},
+ {1.3,0,2.55},{1.3,-0.728,2.55},{0.728,-1.3,2.55},{0,-1.3,2.55},
+ {1.3,0,2.4},{1.3,-0.728,2.4},{0.728,-1.3,2.4},{0,-1.3,2.4},
+ },
+ { // Patch 25
+ {0,-0.2,2.7},{-0.112,-0.2,2.7},{-0.2,-0.112,2.7},{-0.2,0,2.7},
+ {0,-0.4,2.55},{-0.224,-0.4,2.55},{-0.4,-0.224,2.55},{-0.4,0,2.55},
+ {0,-1.3,2.55},{-0.728,-1.3,2.55},{-1.3,-0.728,2.55},{-1.3,0,2.55},
+ {0,-1.3,2.4},{-0.728,-1.3,2.4},{-1.3,-0.728,2.4},{-1.3,0,2.4},
+ },
+ { // Patch 26
+ {-0.2,0,2.7},{-0.2,0.112,2.7},{-0.112,0.2,2.7},{0,0.2,2.7},
+ {-0.4,0,2.55},{-0.4,0.224,2.55},{-0.224,0.4,2.55},{0,0.4,2.55},
+ {-1.3,0,2.55},{-1.3,0.728,2.55},{-0.728,1.3,2.55},{0,1.3,2.55},
+ {-1.3,0,2.4},{-1.3,0.728,2.4},{-0.728,1.3,2.4},{0,1.3,2.4},
+ },
+ { // Patch 27
+ {0,0.2,2.7},{0.112,0.2,2.7},{0.2,0.112,2.7},{0.2,0,2.7},
+ {0,0.4,2.55},{0.224,0.4,2.55},{0.4,0.224,2.55},{0.4,0,2.55},
+ {0,1.3,2.55},{0.728,1.3,2.55},{1.3,0.728,2.55},{1.3,0,2.55},
+ {0,1.3,2.4},{0.728,1.3,2.4},{1.3,0.728,2.4},{1.3,0,2.4},
+ },
+ { // Patch 28
+ {0,0,0},{0,0,0},{0,0,0},{0,0,0},
+ {1.425,0,0},{1.425,0.798,0},{0.798,1.425,0},{0,1.425,0},
+ {1.5,0,0.075},{1.5,0.84,0.075},{0.84,1.5,0.075},{0,1.5,0.075},
+ {1.5,0,0.15},{1.5,0.84,0.15},{0.84,1.5,0.15},{0,1.5,0.15},
+ },
+ { // Patch 29
+ {0,0,0},{0,0,0},{0,0,0},{0,0,0},
+ {0,1.425,0},{-0.798,1.425,0},{-1.425,0.798,0},{-1.425,0,0},
+ {0,1.5,0.075},{-0.84,1.5,0.075},{-1.5,0.84,0.075},{-1.5,0,0.075},
+ {0,1.5,0.15},{-0.84,1.5,0.15},{-1.5,0.84,0.15},{-1.5,0,0.15},
+ },
+ { // Patch 30
+ {0,0,0},{0,0,0},{0,0,0},{0,0,0},
+ {-1.425,0,0},{-1.425,-0.798,0},{-0.798,-1.425,0},{0,-1.425,0},
+ {-1.5,0,0.075},{-1.5,-0.84,0.075},{-0.84,-1.5,0.075},{0,-1.5,0.075},
+ {-1.5,0,0.15},{-1.5,-0.84,0.15},{-0.84,-1.5,0.15},{0,-1.5,0.15},
+ },
+ { // Patch 31
+ {0,0,0},{0,0,0},{0,0,0},{0,0,0},
+ {0,-1.425,0},{0.798,-1.425,0},{1.425,-0.798,0},{1.425,0,0},
+ {0,-1.5,0.075},{0.84,-1.5,0.075},{1.5,-0.84,0.075},{1.5,0,0.075},
+ {0,-1.5,0.15},{0.84,-1.5,0.15},{1.5,-0.84,0.15},{1.5,0,0.15},
+ },
+ };
+ oPRCFile file("test.prc");
+ PRCsurface *psn[NUMBER_OF_PATCHES];
+ const int N_COLOURS = 32;
+ RGBAColour colours[N_COLOURS];
+ for(int i = 0; i < N_COLOURS; ++i)
+ {
+ colours[i%N_COLOURS].R = 0.0;
+ colours[i%N_COLOURS].G = (i%N_COLOURS)/static_cast<double>(N_COLOURS);
+ colours[i%N_COLOURS].B = 0.95;
+ colours[i%N_COLOURS].A = 0.75;
+ }
+ for(int i = 0; i < NUMBER_OF_PATCHES; ++i)
+ {
+ psn[i] = new PRCsurface(&file,3,3,4,4,controlPoints[i],knotsU,knotsV,colours[i%N_COLOURS]);
+ file.add(psn[i]);
+ }
+
+ const int NUMBER_OF_POINTS = 31;
+ double points[NUMBER_OF_POINTS][3];
+ for(int i = 0; i < NUMBER_OF_POINTS; ++i)
+ {
+ points[i][0] = 3.5*cos(3.0*i/NUMBER_OF_POINTS*2.0*M_PI);
+ points[i][1] = 3.5*sin(3.0*i/NUMBER_OF_POINTS*2.0*M_PI);
+ points[i][2] = 5.0*i/NUMBER_OF_POINTS-1.0;
+ }
+ double knots[3+NUMBER_OF_POINTS+1];
+ knots[0] = 1;
+ for(int i = 1; i < 3+NUMBER_OF_POINTS; ++i)
+ {
+ knots[i] = (i+2)/3; // integer division is intentional
+ }
+ knots[3+NUMBER_OF_POINTS] = (3+NUMBER_OF_POINTS+1)/3;
+
+ RGBAColour white(1.0,1.0,1.0);
+ PRCcurve pc(&file,3,NUMBER_OF_POINTS,points,knots,white);
+ file.add(&pc);
+
+ RGBAColour red(1.0,0.0,0.0);
+ PRCline pl(&file,NUMBER_OF_POINTS,points,red);
+ file.add(&pl);
+
+ file.finish();
+
+ for(int i = 0; i < NUMBER_OF_PATCHES; ++i)
+ delete psn[i];
+
+ return 0;
+}
diff --git a/Build/source/utils/asymptote/prc/writePRC.cc b/Build/source/utils/asymptote/prc/writePRC.cc
new file mode 100644
index 00000000000..eb476dc7494
--- /dev/null
+++ b/Build/source/utils/asymptote/prc/writePRC.cc
@@ -0,0 +1,178 @@
+/************
+*
+* This file is part of a tool for producing 3D content in the PRC format.
+* Copyright (C) 2008 Orest Shardt <shardtor (at) gmail dot com>
+*
+* This program 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 3 of the License, or
+* (at your option) any later version.
+*
+* This program 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 program. If not, see <http://www.gnu.org/licenses/>.
+*
+*************/
+
+#include "writePRC.h"
+
+void UserData::write(PRCbitStream &pbs)
+{
+ pbs << size;
+ if(size > 0)
+ {
+ uint32_t i = 0;
+ for(; i < size/8; ++i)
+ {
+ pbs << data[i];
+ }
+ if(size % 8 != 0)
+ {
+ for(uint32_t j = 0; j < size%8; ++j) // 0-based, big endian bit counting
+ {
+ pbs << (bool)(data[i] & (0x80 >> j));
+ }
+ }
+ }
+}
+
+void SingleAttribute::write(PRCbitStream &pbs)
+{
+ pbs << titleIsInteger;
+ if(titleIsInteger)
+ pbs << title.integer;
+ else
+ pbs << title.text;
+ pbs << type;
+ switch(type)
+ {
+ case KEPRCModellerAttributeTypeInt:
+ pbs << data.integer;
+ break;
+ case KEPRCModellerAttributeTypeReal:
+ pbs << data.real;
+ break;
+ case KEPRCModellerAttributeTypeTime:
+ pbs << data.time;
+ break;
+ case KEPRCModellerAttributeTypeString:
+ pbs << data.text;
+ break;
+ default:
+ break;
+ }
+}
+
+void Attribute::write(PRCbitStream &pbs)
+{
+ pbs << (uint32_t)PRC_TYPE_MISC_Attribute;
+ pbs << titleIsInteger;
+ if(titleIsInteger)
+ pbs << title.integer;
+ else
+ pbs << title.text;
+ pbs << sizeOfAttributeKeys;
+ for(uint32_t i = 0; i < sizeOfAttributeKeys; ++i)
+ {
+ singleAttributes[i].write(pbs);
+ }
+}
+
+void Attributes::write(PRCbitStream &pbs)
+{
+ pbs << numberOfAttributes;
+ for(uint32_t i = 0; i < numberOfAttributes; ++i)
+ {
+ attributes[i].write(pbs);
+ }
+}
+
+void ContentPRCBase::write(PRCbitStream &pbs)
+{
+ attributes->write(pbs);
+ writeName(pbs,name);
+ if(eligibleForReference)
+ {
+ pbs << CADID << CADPersistentID << PRCID;
+ }
+}
+
+AttributeTitle EMPTY_ATTRIBUTE_TITLE = {(char*)""};
+Attribute EMPTY_ATTRIBUTE(false,EMPTY_ATTRIBUTE_TITLE,0,NULL);
+Attributes EMPTY_ATTRIBUTES(0,0);
+ContentPRCBase EMPTY_CONTENTPRCBASE(&EMPTY_ATTRIBUTES);
+
+std::string currentName;
+void writeName(PRCbitStream &pbs,const std::string &name)
+{
+ pbs << (name == currentName);
+ if(name != currentName)
+ {
+ pbs << name;
+ currentName = name;
+ }
+}
+
+void resetName()
+{
+ currentName = "";
+}
+
+uint32_t layer_index = m1;
+uint32_t index_of_line_style = m1;
+uint32_t behaviour_bit_field = 1;
+
+void writeGraphics(PRCbitStream &pbs,uint32_t l,uint32_t i,uint32_t b,bool force)
+{
+ if(force || layer_index != l || index_of_line_style != i || behaviour_bit_field != b)
+ {
+ pbs << false << (uint32_t)(l+1) << (uint32_t)(i+1)
+ << (uint8_t)(b&0xFF) << (uint8_t)((b>>8)&0xFF);
+ layer_index = l;
+ index_of_line_style = i;
+ behaviour_bit_field = b;
+ }
+ else
+ pbs << true;
+}
+
+void resetGraphics()
+{
+ layer_index = m1;
+ index_of_line_style = m1;
+ behaviour_bit_field = 1;
+}
+
+void resetGraphicsAndName()
+{
+ resetGraphics(); resetName();
+}
+
+uint32_t makeCADID()
+{
+ static uint32_t ID = 1;
+ return ID++;
+}
+
+uint32_t makePRCID()
+{
+ static uint32_t ID = 1;
+ return ID++;
+}
+
+void writeUnit(PRCbitStream &out,bool fromCAD,double unit)
+{
+ out << fromCAD << unit;
+}
+
+void writeEmptyMarkups(PRCbitStream &out)
+{
+ out << (uint32_t)0 // # of linked items
+ << (uint32_t)0 // # of leaders
+ << (uint32_t)0 // # of markups
+ << (uint32_t)0; // # of annotation entities
+}
diff --git a/Build/source/utils/asymptote/prc/writePRC.h b/Build/source/utils/asymptote/prc/writePRC.h
new file mode 100644
index 00000000000..6a4da7a70ba
--- /dev/null
+++ b/Build/source/utils/asymptote/prc/writePRC.h
@@ -0,0 +1,172 @@
+/************
+*
+* This file is part of a tool for producing 3D content in the PRC format.
+* Copyright (C) 2008 Orest Shardt <shardtor (at) gmail dot com>
+*
+* This program 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 3 of the License, or
+* (at your option) any later version.
+*
+* This program 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 program. If not, see <http://www.gnu.org/licenses/>.
+*
+*************/
+
+#ifndef __WRITE_PRC_H
+#define __WRITE_PRC_H
+#include <string>
+#include "PRCbitStream.h"
+#include "PRC.h"
+
+struct Point3d
+{
+ double x,y,z;
+ Point3d(double a, double b, double c) : x(a),y(b),z(c) {}
+ void write(PRCbitStream &out)
+ {
+ out << x << y << z;
+ }
+};
+
+struct Extent3d
+{
+ Point3d min,max;
+ Extent3d(const Point3d &m1, const Point3d& m2) : min(m1),max(m2) {}
+ void write(PRCbitStream &out)
+ {
+ // flip the order? Following the documentation, in a real file, min>max.
+ // Considering the file to be right, min and max can be flipped in both places (here and in description)
+ // resulting in no practical difference.
+ // But in other places (Extent3D and Extent1D), min is really before max, so for consistency
+ // this is left alone.
+ min.write(out);
+ max.write(out);
+ }
+};
+
+class UUID
+{
+ public:
+ UUID(uint32_t u0, uint32_t u1, uint32_t u2, uint32_t u3) :
+ id0(u0),id1(u1),id2(u2),id3(u3) {}
+ void write(PRCbitStream &out)
+ {
+ out << id0 << id1 << id2 << id3;
+ }
+ private:
+ uint32_t id0,id1,id2,id3;
+};
+
+uint32_t makeCADID();
+uint32_t makePRCID();
+void writeUnit(PRCbitStream &,bool,double);
+
+void writeEmptyMarkups(PRCbitStream&);
+
+class UserData
+{
+ public:
+ UserData(uint32_t s = 0, uint8_t* d = 0) : size(s),data(d) {}
+ void write(PRCbitStream&);
+ private:
+ uint32_t size;
+ uint8_t* data;
+};
+
+union SingleAttributeData
+{
+ int32_t integer;
+ double real;
+ uint32_t time;
+ const char *text;
+};
+
+union AttributeTitle
+{
+ const char *text;
+ uint32_t integer;
+};
+
+class SingleAttribute
+{
+ public:
+ SingleAttribute() {}
+ SingleAttribute(bool b,AttributeTitle t,uint32_t y,SingleAttributeData d) :
+ titleIsInteger(b), title(t), type(y), data(d) {}
+ void write(PRCbitStream&);
+ private:
+ bool titleIsInteger;
+ AttributeTitle title;
+ uint32_t type;
+ SingleAttributeData data;
+};
+
+class Attribute
+{
+ public:
+ Attribute(bool t,AttributeTitle v, uint32_t s, SingleAttribute* sa) :
+ titleIsInteger(t),title(v), sizeOfAttributeKeys(s), singleAttributes(sa)
+ {}
+ void write(PRCbitStream &);
+ private:
+ bool titleIsInteger;
+ AttributeTitle title;
+ uint32_t sizeOfAttributeKeys;
+ SingleAttribute *singleAttributes;
+};
+
+class Attributes
+{
+ public:
+ Attributes(uint32_t n, Attribute* a) : numberOfAttributes(n), attributes(a)
+ {}
+ void write(PRCbitStream&);
+ private:
+ uint32_t numberOfAttributes;
+ Attribute *attributes;
+};
+
+class ContentPRCBase
+{
+ public:
+ ContentPRCBase(Attributes *a, std::string n="",bool efr = false,
+ uint32_t ci = 0, uint32_t cpi = 0, uint32_t pi = 0) :
+ attributes(a),name(n),eligibleForReference(efr),CADID(ci),
+ CADPersistentID(cpi),PRCID(pi) {}
+ void write(PRCbitStream&);
+ private:
+ Attributes *attributes;
+ std::string name;
+ bool eligibleForReference;
+ uint32_t CADID, CADPersistentID, PRCID;
+};
+
+extern AttributeTitle EMPTY_ATTRIBUTE_TITLE;
+extern Attribute EMPTY_ATTRIBUTE;
+extern Attributes EMPTY_ATTRIBUTES;
+extern ContentPRCBase EMPTY_CONTENTPRCBASE;
+extern ContentPRCBase EMPTY_CONTENTPRCBASE_WITH_REFERENCE;
+
+extern std::string currentName;
+void writeName(PRCbitStream&,const std::string&);
+void resetName();
+
+extern uint32_t layer_index;
+extern uint32_t index_of_line_style;
+extern uint32_t behaviour_bit_field;
+static const uint32_t m1=(uint32_t)-1;
+
+void writeGraphics(PRCbitStream&,uint32_t=m1,uint32_t=m1,uint32_t=1,bool=false);
+void resetGraphics();
+
+void resetGraphicsAndName();
+
+
+
+#endif //__WRITE_PRC_H
diff --git a/Build/source/utils/asymptote/prcfile.h b/Build/source/utils/asymptote/prcfile.h
new file mode 100644
index 00000000000..9c02470f2fa
--- /dev/null
+++ b/Build/source/utils/asymptote/prcfile.h
@@ -0,0 +1,83 @@
+#ifndef PRCFILE_H
+#define PRCFILE_H
+
+#include "prc/oPRCFile.h"
+
+namespace camp {
+
+const double scale3D=1.0/settings::cm;
+
+inline RGBAColour rgba(pen p) {
+ p.torgb();
+ return RGBAColour(p.red(),p.green(),p.blue(),p.opacity());
+}
+
+class prcfile : public oPRCFile {
+ std::list<PRCentity *> entities;
+public:
+ prcfile(string name) : oPRCFile(name.c_str()) {}
+ ~prcfile() {
+
+ for(std::list<PRCentity *>::iterator p=entities.begin();
+ p != entities.end(); ++p) {
+ assert(*p);
+ delete *p;
+ }
+ }
+
+ void add(PRCentity* e) {
+ entities.push_back(e);
+ oPRCFile::add(e);
+ }
+};
+
+inline void writeBezierKnots(PRCbitStream &out, uint32_t d, uint32_t n)
+{
+ out << (double) 1;
+ for(uint32_t i=1; i < d+n; ++i)
+ out << (double) ((i+2)/d); // integer division is intentional
+ out << (double) ((d+n+1)/d);
+}
+
+class PRCBezierCurve : public PRCcurve
+{
+ uint32_t d;
+ uint32_t n;
+public:
+ PRCBezierCurve(oPRCFile *p, uint32_t d, uint32_t n, double cP[][3],
+ const RGBAColour &c) :
+ PRCcurve(p,d,n,cP,NULL,c,scale3D,false,NULL), d(d), n(n) {}
+ PRCBezierCurve(oPRCFile *p, uint32_t d, uint32_t n, double cP[][3],
+ const PRCMaterial &m) :
+ PRCcurve(p,d,n,cP,NULL,m,scale3D,false,NULL), d(d), n(n) {}
+private:
+ void writeKnots(PRCbitStream &out) {
+ writeBezierKnots(out,d,n);
+ }
+};
+
+class PRCBezierSurface : public PRCsurface
+{
+ uint32_t dU,dV;
+ uint32_t nU,nV;
+public:
+ PRCBezierSurface(oPRCFile *p, uint32_t dU, uint32_t dV, uint32_t nU,
+ uint32_t nV, double cP[][3], const RGBAColour &c,
+ double g=0.0) :
+ PRCsurface(p,dU,dV,nU,nV,cP,NULL,NULL,c,scale3D,false,NULL,g), dU(dU),
+ dV(dV), nU(nU), nV(nV) {}
+ PRCBezierSurface(oPRCFile *p, uint32_t dU, uint32_t dV, uint32_t nU,
+ uint32_t nV, double cP[][3], const PRCMaterial &m,
+ double g=0.0) :
+ PRCsurface(p,dU,dV,nU,nV,cP,NULL,NULL,m,scale3D,false,NULL,g), dU(dU),
+ dV(dV), nU(nU), nV(nV) {}
+private:
+ void writeKnots(PRCbitStream &out) {
+ writeBezierKnots(out,dU,nU);
+ writeBezierKnots(out,dV,nV);
+ }
+};
+
+} //namespace camp
+
+#endif
diff --git a/Build/source/utils/asymptote/predicates.cc b/Build/source/utils/asymptote/predicates.cc
new file mode 100644
index 00000000000..15fc3d4135f
--- /dev/null
+++ b/Build/source/utils/asymptote/predicates.cc
@@ -0,0 +1,2783 @@
+/*****************************************************************************/
+/* */
+/* Routines for Arbitrary Precision Floating-point Arithmetic */
+/* and Fast Robust Geometric Predicates */
+/* (predicates.c) */
+/* */
+/* May 18, 1996 */
+/* */
+/* Placed in the public domain by */
+/* Jonathan Richard Shewchuk */
+/* School of Computer Science */
+/* Carnegie Mellon University */
+/* 5000 Forbes Avenue */
+/* Pittsburgh, Pennsylvania 15213-3891 */
+/* jrs@cs.cmu.edu */
+/* */
+/* This file contains C implementation of algorithms for exact addition */
+/* and multiplication of floating-point numbers, and predicates for */
+/* robustly performing the orientation and incircle tests used in */
+/* computational geometry. The algorithms and underlying theory are */
+/* described in Jonathan Richard Shewchuk. "Adaptive Precision Floating- */
+/* Point Arithmetic and Fast Robust Geometric Predicates." Technical */
+/* Report CMU-CS-96-140, School of Computer Science, Carnegie Mellon */
+/* University, Pittsburgh, Pennsylvania, May 1996. (Submitted to */
+/* Discrete & Computational Geometry.) */
+/* */
+/* This file, the paper listed above, and other information are available */
+/* from the Web page http://www.cs.cmu.edu/~quake/robust.html . */
+/* */
+/*****************************************************************************/
+
+/*****************************************************************************/
+/* */
+/* Using this code: */
+/* */
+/* First, read the short or long version of the paper (from the Web page */
+/* above). */
+/* */
+/* Be sure to call exactinit() once, before calling any of the arithmetic */
+/* functions or geometric predicates. Also be sure to turn on the */
+/* optimizer when compiling this file. */
+/* */
+/* */
+/* Several geometric predicates are defined. Their parameters are all */
+/* points. Each point is an array of two or three floating-point */
+/* numbers. The geometric predicates, described in the papers, are */
+/* */
+/* orient2d(pa, pb, pc) */
+/* orient2dfast(pa, pb, pc) */
+/* orient3d(pa, pb, pc, pd) */
+/* orient3dfast(pa, pb, pc, pd) */
+/* incircle(pa, pb, pc, pd) */
+/* incirclefast(pa, pb, pc, pd) */
+/* insphere(pa, pb, pc, pd, pe) */
+/* inspherefast(pa, pb, pc, pd, pe) */
+/* */
+/* Those with suffix "fast" are approximate, non-robust versions. Those */
+/* without the suffix are adaptive precision, robust versions. There */
+/* are also versions with the suffices "exact" and "slow", which are */
+/* non-adaptive, exact arithmetic versions, which I use only for timings */
+/* in my arithmetic papers. */
+/* */
+/* */
+/* An expansion is represented by an array of floating-point numbers, */
+/* sorted from smallest to largest magnitude (possibly with interspersed */
+/* zeros). The length of each expansion is stored as a separate integer, */
+/* and each arithmetic function returns an integer which is the length */
+/* of the expansion it created. */
+/* */
+/* Several arithmetic functions are defined. Their parameters are */
+/* */
+/* e, f Input expansions */
+/* elen, flen Lengths of input expansions (must be >= 1) */
+/* h Output expansion */
+/* b Input scalar */
+/* */
+/* The arithmetic functions are */
+/* */
+/* grow_expansion(elen, e, b, h) */
+/* grow_expansion_zeroelim(elen, e, b, h) */
+/* expansion_sum(elen, e, flen, f, h) */
+/* expansion_sum_zeroelim1(elen, e, flen, f, h) */
+/* expansion_sum_zeroelim2(elen, e, flen, f, h) */
+/* fast_expansion_sum(elen, e, flen, f, h) */
+/* fast_expansion_sum_zeroelim(elen, e, flen, f, h) */
+/* linear_expansion_sum(elen, e, flen, f, h) */
+/* linear_expansion_sum_zeroelim(elen, e, flen, f, h) */
+/* scale_expansion(elen, e, b, h) */
+/* scale_expansion_zeroelim(elen, e, b, h) */
+/* compress(elen, e, h) */
+/* */
+/* All of these are described in the long version of the paper; some are */
+/* described in the short version. All return an integer that is the */
+/* length of h. Those with suffix _zeroelim perform zero elimination, */
+/* and are recommended over their counterparts. The procedure */
+/* fast_expansion_sum_zeroelim() (or linear_expansion_sum_zeroelim() on */
+/* processors that do not use the round-to-even tiebreaking rule) is */
+/* recommended over expansion_sum_zeroelim(). Each procedure has a */
+/* little note next to it (in the code below) that tells you whether or */
+/* not the output expansion may be the same array as one of the input */
+/* expansions. */
+/* */
+/* */
+/* If you look around below, you'll also find macros for a bunch of */
+/* simple unrolled arithmetic operations, and procedures for printing */
+/* expansions (commented out because they don't work with all C */
+/* compilers) and for generating random floating-point numbers whose */
+/* significand bits are all random. Most of the macros have undocumented */
+/* requirements that certain of their parameters should not be the same */
+/* variable; for safety, better to make sure all the parameters are */
+/* distinct variables. Feel free to send email to jrs@cs.cmu.edu if you */
+/* have questions. */
+/* */
+/*****************************************************************************/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <math.h>
+#include <cfloat>
+#include "predicates.h"
+
+/* FPU control. We MUST have only double precision (not extended precision) */
+#include "rounding.h"
+
+/* On some machines, the exact arithmetic routines might be defeated by the */
+/* use of internal extended precision floating-point registers. Sometimes */
+/* this problem can be fixed by defining certain values to be volatile, */
+/* thus forcing them to be stored to memory and rounded off. This isn't */
+/* a great solution, though, as it slows the arithmetic down. */
+/* */
+/* To try this out, write "#define INEXACT volatile" below. Normally, */
+/* however, INEXACT should be defined to be nothing. ("#define INEXACT".) */
+
+#define INEXACT /* Nothing */
+/* #define INEXACT volatile */
+
+#define REAL double /* float or double */
+#define REALPRINT doubleprint
+#define REALRAND doublerand
+#define NARROWRAND narrowdoublerand
+#define UNIFORMRAND uniformdoublerand
+
+/* Which of the following two methods of finding the absolute values is */
+/* fastest is compiler-dependent. A few compilers can inline and optimize */
+/* the fabs() call; but most will incur the overhead of a function call, */
+/* which is disastrously slow. A faster way on IEEE machines might be to */
+/* mask the appropriate bit, but that's difficult to do in C. */
+
+/*#define Absolute(a) ((a) >= 0.0 ? (a) : -(a)) */
+#define Absolute(a) fabs(a)
+
+/* Many of the operations are broken up into two pieces, a main part that */
+/* performs an approximate operation, and a "tail" that computes the */
+/* roundoff error of that operation. */
+/* */
+/* The operations Fast_Two_Sum(), Fast_Two_Diff(), Two_Sum(), Two_Diff(), */
+/* Split(), and Two_Product() are all implemented as described in the */
+/* reference. Each of these macros requires certain variables to be */
+/* defined in the calling routine. The variables `bvirt', `c', `abig', */
+/* `_i', `_j', `_k', `_l', `_m', and `_n' are declared `INEXACT' because */
+/* they store the result of an operation that may incur roundoff error. */
+/* The input parameter `x' (or the highest numbered `x_' parameter) must */
+/* also be declared `INEXACT'. */
+
+#define Fast_Two_Sum_Tail(a, b, x, y) \
+ bvirt = x - a; \
+ y = b - bvirt
+
+#define Fast_Two_Sum(a, b, x, y) \
+ x = (REAL) (a + b); \
+ Fast_Two_Sum_Tail(a, b, x, y)
+
+#define Fast_Two_Diff_Tail(a, b, x, y) \
+ bvirt = a - x; \
+ y = bvirt - b
+
+#define Fast_Two_Diff(a, b, x, y) \
+ x = (REAL) (a - b); \
+ Fast_Two_Diff_Tail(a, b, x, y)
+
+#define Two_Sum_Tail(a, b, x, y) \
+ bvirt = (REAL) (x - a); \
+ avirt = x - bvirt; \
+ bround = b - bvirt; \
+ around = a - avirt; \
+ y = around + bround
+
+#define Two_Sum(a, b, x, y) \
+ x = (REAL) (a + b); \
+ Two_Sum_Tail(a, b, x, y)
+
+#define Two_Diff_Tail(a, b, x, y) \
+ bvirt = (REAL) (a - x); \
+ avirt = x + bvirt; \
+ bround = bvirt - b; \
+ around = a - avirt; \
+ y = around + bround
+
+#define Two_Diff(a, b, x, y) \
+ x = (REAL) (a - b); \
+ Two_Diff_Tail(a, b, x, y)
+
+#define Split(a, ahi, alo) \
+ c = (REAL) (splitter * a); \
+ abig = (REAL) (c - a); \
+ ahi = c - abig; \
+ alo = a - ahi
+
+#define Two_Product_Tail(a, b, x, y) \
+ Split(a, ahi, alo); \
+ Split(b, bhi, blo); \
+ err1 = x - (ahi * bhi); \
+ err2 = err1 - (alo * bhi); \
+ err3 = err2 - (ahi * blo); \
+ y = (alo * blo) - err3
+
+#define Two_Product(a, b, x, y) \
+ x = (REAL) (a * b); \
+ Two_Product_Tail(a, b, x, y)
+
+/* Two_Product_Presplit() is Two_Product() where one of the inputs has */
+/* already been split. Avoids redundant splitting. */
+
+#define Two_Product_Presplit(a, b, bhi, blo, x, y) \
+ x = (REAL) (a * b); \
+ Split(a, ahi, alo); \
+ err1 = x - (ahi * bhi); \
+ err2 = err1 - (alo * bhi); \
+ err3 = err2 - (ahi * blo); \
+ y = (alo * blo) - err3
+
+/* Two_Product_2Presplit() is Two_Product() where both of the inputs have */
+/* already been split. Avoids redundant splitting. */
+
+#define Two_Product_2Presplit(a, ahi, alo, b, bhi, blo, x, y) \
+ x = (REAL) (a * b); \
+ err1 = x - (ahi * bhi); \
+ err2 = err1 - (alo * bhi); \
+ err3 = err2 - (ahi * blo); \
+ y = (alo * blo) - err3
+
+/* Square() can be done more quickly than Two_Product(). */
+
+#define Square_Tail(a, x, y) \
+ Split(a, ahi, alo); \
+ err1 = x - (ahi * ahi); \
+ err3 = err1 - ((ahi + ahi) * alo); \
+ y = (alo * alo) - err3
+
+#define Square(a, x, y) \
+ x = (REAL) (a * a); \
+ Square_Tail(a, x, y)
+
+/* Macros for summing expansions of various fixed lengths. These are all */
+/* unrolled versions of Expansion_Sum(). */
+
+#define Two_One_Sum(a1, a0, b, x2, x1, x0) \
+ Two_Sum(a0, b , _i, x0); \
+ Two_Sum(a1, _i, x2, x1)
+
+#define Two_One_Diff(a1, a0, b, x2, x1, x0) \
+ Two_Diff(a0, b , _i, x0); \
+ Two_Sum( a1, _i, x2, x1)
+
+#define Two_Two_Sum(a1, a0, b1, b0, x3, x2, x1, x0) \
+ Two_One_Sum(a1, a0, b0, _j, _0, x0); \
+ Two_One_Sum(_j, _0, b1, x3, x2, x1)
+
+#define Two_Two_Diff(a1, a0, b1, b0, x3, x2, x1, x0) \
+ Two_One_Diff(a1, a0, b0, _j, _0, x0); \
+ Two_One_Diff(_j, _0, b1, x3, x2, x1)
+
+#define Four_One_Sum(a3, a2, a1, a0, b, x4, x3, x2, x1, x0) \
+ Two_One_Sum(a1, a0, b , _j, x1, x0); \
+ Two_One_Sum(a3, a2, _j, x4, x3, x2)
+
+#define Four_Two_Sum(a3, a2, a1, a0, b1, b0, x5, x4, x3, x2, x1, x0) \
+ Four_One_Sum(a3, a2, a1, a0, b0, _k, _2, _1, _0, x0); \
+ Four_One_Sum(_k, _2, _1, _0, b1, x5, x4, x3, x2, x1)
+
+#define Four_Four_Sum(a3, a2, a1, a0, b4, b3, b1, b0, x7, x6, x5, x4, x3, x2, \
+ x1, x0) \
+ Four_Two_Sum(a3, a2, a1, a0, b1, b0, _l, _2, _1, _0, x1, x0); \
+ Four_Two_Sum(_l, _2, _1, _0, b4, b3, x7, x6, x5, x4, x3, x2)
+
+#define Eight_One_Sum(a7, a6, a5, a4, a3, a2, a1, a0, b, x8, x7, x6, x5, x4, \
+ x3, x2, x1, x0) \
+ Four_One_Sum(a3, a2, a1, a0, b , _j, x3, x2, x1, x0); \
+ Four_One_Sum(a7, a6, a5, a4, _j, x8, x7, x6, x5, x4)
+
+#define Eight_Two_Sum(a7, a6, a5, a4, a3, a2, a1, a0, b1, b0, x9, x8, x7, \
+ x6, x5, x4, x3, x2, x1, x0) \
+ Eight_One_Sum(a7, a6, a5, a4, a3, a2, a1, a0, b0, _k, _6, _5, _4, _3, _2, \
+ _1, _0, x0); \
+ Eight_One_Sum(_k, _6, _5, _4, _3, _2, _1, _0, b1, x9, x8, x7, x6, x5, x4, \
+ x3, x2, x1)
+
+#define Eight_Four_Sum(a7, a6, a5, a4, a3, a2, a1, a0, b4, b3, b1, b0, x11, \
+ x10, x9, x8, x7, x6, x5, x4, x3, x2, x1, x0) \
+ Eight_Two_Sum(a7, a6, a5, a4, a3, a2, a1, a0, b1, b0, _l, _6, _5, _4, _3, \
+ _2, _1, _0, x1, x0); \
+ Eight_Two_Sum(_l, _6, _5, _4, _3, _2, _1, _0, b4, b3, x11, x10, x9, x8, \
+ x7, x6, x5, x4, x3, x2)
+
+/* Macros for multiplying expansions of various fixed lengths. */
+
+#define Two_One_Product(a1, a0, b, x3, x2, x1, x0) \
+ Split(b, bhi, blo); \
+ Two_Product_Presplit(a0, b, bhi, blo, _i, x0); \
+ Two_Product_Presplit(a1, b, bhi, blo, _j, _0); \
+ Two_Sum(_i, _0, _k, x1); \
+ Fast_Two_Sum(_j, _k, x3, x2)
+
+#define Four_One_Product(a3, a2, a1, a0, b, x7, x6, x5, x4, x3, x2, x1, x0) \
+ Split(b, bhi, blo); \
+ Two_Product_Presplit(a0, b, bhi, blo, _i, x0); \
+ Two_Product_Presplit(a1, b, bhi, blo, _j, _0); \
+ Two_Sum(_i, _0, _k, x1); \
+ Fast_Two_Sum(_j, _k, _i, x2); \
+ Two_Product_Presplit(a2, b, bhi, blo, _j, _0); \
+ Two_Sum(_i, _0, _k, x3); \
+ Fast_Two_Sum(_j, _k, _i, x4); \
+ Two_Product_Presplit(a3, b, bhi, blo, _j, _0); \
+ Two_Sum(_i, _0, _k, x5); \
+ Fast_Two_Sum(_j, _k, x7, x6)
+
+#define Two_Two_Product(a1, a0, b1, b0, x7, x6, x5, x4, x3, x2, x1, x0) \
+ Split(a0, a0hi, a0lo); \
+ Split(b0, bhi, blo); \
+ Two_Product_2Presplit(a0, a0hi, a0lo, b0, bhi, blo, _i, x0); \
+ Split(a1, a1hi, a1lo); \
+ Two_Product_2Presplit(a1, a1hi, a1lo, b0, bhi, blo, _j, _0); \
+ Two_Sum(_i, _0, _k, _1); \
+ Fast_Two_Sum(_j, _k, _l, _2); \
+ Split(b1, bhi, blo); \
+ Two_Product_2Presplit(a0, a0hi, a0lo, b1, bhi, blo, _i, _0); \
+ Two_Sum(_1, _0, _k, x1); \
+ Two_Sum(_2, _k, _j, _1); \
+ Two_Sum(_l, _j, _m, _2); \
+ Two_Product_2Presplit(a1, a1hi, a1lo, b1, bhi, blo, _j, _0); \
+ Two_Sum(_i, _0, _n, _0); \
+ Two_Sum(_1, _0, _i, x2); \
+ Two_Sum(_2, _i, _k, _1); \
+ Two_Sum(_m, _k, _l, _2); \
+ Two_Sum(_j, _n, _k, _0); \
+ Two_Sum(_1, _0, _j, x3); \
+ Two_Sum(_2, _j, _i, _1); \
+ Two_Sum(_l, _i, _m, _2); \
+ Two_Sum(_1, _k, _i, x4); \
+ Two_Sum(_2, _i, _k, x5); \
+ Two_Sum(_m, _k, x7, x6)
+
+/* An expansion of length two can be squared more quickly than finding the */
+/* product of two different expansions of length two, and the result is */
+/* guaranteed to have no more than six (rather than eight) components. */
+
+#define Two_Square(a1, a0, x5, x4, x3, x2, x1, x0) \
+ Square(a0, _j, x0); \
+ _0 = a0 + a0; \
+ Two_Product(a1, _0, _k, _1); \
+ Two_One_Sum(_k, _1, _j, _l, _2, x1); \
+ Square(a1, _j, _1); \
+ Two_Two_Sum(_j, _1, _l, _2, x5, x4, x3, x2)
+
+/* 2^(-p), where p=DBL_MANT_DIG. Used to estimate roundoff errors. */
+static const REAL epsilon=0.5*DBL_EPSILON;
+
+/* 2^ceiling(p/2) + 1. Used to split floats in half. */
+static const REAL splitter=sqrt((DBL_MANT_DIG % 2 ? 2.0 : 1.0)/epsilon)+1.0;
+
+/* A set of coefficients used to calculate maximum roundoff errors. */
+const REAL resulterrbound=(3.0 + 8.0 * epsilon) * epsilon;
+const REAL ccwerrboundA=(3.0 + 16.0 * epsilon) * epsilon;
+const REAL ccwerrboundB=(2.0 + 12.0 * epsilon) * epsilon;
+const REAL ccwerrboundC=(9.0 + 64.0 * epsilon) * epsilon * epsilon;
+const REAL o3derrboundA=(7.0 + 56.0 * epsilon) * epsilon;
+const REAL o3derrboundB=(3.0 + 28.0 * epsilon) * epsilon;
+const REAL o3derrboundC=(26.0 + 288.0 * epsilon) * epsilon * epsilon;
+const REAL iccerrboundA=(10.0 + 96.0 * epsilon) * epsilon;
+const REAL iccerrboundB=(4.0 + 48.0 * epsilon) * epsilon;
+const REAL iccerrboundC=(44.0 + 576.0 * epsilon) * epsilon * epsilon;
+const REAL isperrboundA=(16.0 + 224.0 * epsilon) * epsilon;
+const REAL isperrboundB=(5.0 + 72.0 * epsilon) * epsilon;
+const REAL isperrboundC=(71.0 + 1408.0 * epsilon) * epsilon * epsilon;
+
+/*****************************************************************************/
+/* */
+/* doubleprint() Print the bit representation of a double. */
+/* */
+/* Useful for debugging exact arithmetic routines. */
+/* */
+/*****************************************************************************/
+
+/*
+void doubleprint(number)
+double number;
+{
+ unsigned long long no;
+ unsigned long long sign, expo;
+ int exponent;
+ int i, bottomi;
+
+ no = *(unsigned long long *) &number;
+ sign = no & 0x8000000000000000ll;
+ expo = (no >> 52) & 0x7ffll;
+ exponent = (int) expo;
+ exponent = exponent - 1023;
+ if (sign) {
+ printf("-");
+ } else {
+ printf(" ");
+ }
+ if (exponent == -1023) {
+ printf(
+ "0.0000000000000000000000000000000000000000000000000000_ ( )");
+ } else {
+ printf("1.");
+ bottomi = -1;
+ for (i = 0; i < 52; i++) {
+ if (no & 0x0008000000000000ll) {
+ printf("1");
+ bottomi = i;
+ } else {
+ printf("0");
+ }
+ no <<= 1;
+ }
+ printf("_%d (%d)", exponent, exponent - 1 - bottomi);
+ }
+}
+*/
+
+/*****************************************************************************/
+/* */
+/* floatprint() Print the bit representation of a float. */
+/* */
+/* Useful for debugging exact arithmetic routines. */
+/* */
+/*****************************************************************************/
+
+/*
+void floatprint(number)
+float number;
+{
+ unsigned no;
+ unsigned sign, expo;
+ int exponent;
+ int i, bottomi;
+
+ no = *(unsigned *) &number;
+ sign = no & 0x80000000;
+ expo = (no >> 23) & 0xff;
+ exponent = (int) expo;
+ exponent = exponent - 127;
+ if (sign) {
+ printf("-");
+ } else {
+ printf(" ");
+ }
+ if (exponent == -127) {
+ printf("0.00000000000000000000000_ ( )");
+ } else {
+ printf("1.");
+ bottomi = -1;
+ for (i = 0; i < 23; i++) {
+ if (no & 0x00400000) {
+ printf("1");
+ bottomi = i;
+ } else {
+ printf("0");
+ }
+ no <<= 1;
+ }
+ printf("_%3d (%3d)", exponent, exponent - 1 - bottomi);
+ }
+}
+*/
+
+/*****************************************************************************/
+/* */
+/* expansion_print() Print the bit representation of an expansion. */
+/* */
+/* Useful for debugging exact arithmetic routines. */
+/* */
+/*****************************************************************************/
+
+/*
+void expansion_print(elen, e)
+int elen;
+REAL *e;
+{
+ int i;
+
+ for (i = elen - 1; i >= 0; i--) {
+ REALPRINT(e[i]);
+ if (i > 0) {
+ printf(" +\n");
+ } else {
+ printf("\n");
+ }
+ }
+}
+*/
+
+/*****************************************************************************/
+/* */
+/* doublerand() Generate a double with random 53-bit significand and a */
+/* random exponent in [0, 511]. */
+/* */
+/*****************************************************************************/
+
+/*
+static double doublerand()
+{
+ double result;
+ double expo;
+ long a, b, c;
+ long i;
+
+ a = random();
+ b = random();
+ c = random();
+ result = (double) (a - 1073741824) * 8388608.0 + (double) (b >> 8);
+ for (i = 512, expo = 2; i <= 131072; i *= 2, expo = expo * expo) {
+ if (c & i) {
+ result *= expo;
+ }
+ }
+ return result;
+}
+*/
+
+/*****************************************************************************/
+/* */
+/* narrowdoublerand() Generate a double with random 53-bit significand */
+/* and a random exponent in [0, 7]. */
+/* */
+/*****************************************************************************/
+
+/*
+static double narrowdoublerand()
+{
+ double result;
+ double expo;
+ long a, b, c;
+ long i;
+
+ a = random();
+ b = random();
+ c = random();
+ result = (double) (a - 1073741824) * 8388608.0 + (double) (b >> 8);
+ for (i = 512, expo = 2; i <= 2048; i *= 2, expo = expo * expo) {
+ if (c & i) {
+ result *= expo;
+ }
+ }
+ return result;
+}
+*/
+
+/*****************************************************************************/
+/* */
+/* uniformdoublerand() Generate a double with random 53-bit significand. */
+/* */
+/*****************************************************************************/
+
+/*
+static double uniformdoublerand()
+{
+ double result;
+ long a, b;
+
+ a = random();
+ b = random();
+ result = (double) (a - 1073741824) * 8388608.0 + (double) (b >> 8);
+ return result;
+}
+*/
+
+/*****************************************************************************/
+/* */
+/* floatrand() Generate a float with random 24-bit significand and a */
+/* random exponent in [0, 63]. */
+/* */
+/*****************************************************************************/
+
+/*
+static float floatrand()
+{
+ float result;
+ float expo;
+ long a, c;
+ long i;
+
+ a = random();
+ c = random();
+ result = (float) ((a - 1073741824) >> 6);
+ for (i = 512, expo = 2; i <= 16384; i *= 2, expo = expo * expo) {
+ if (c & i) {
+ result *= expo;
+ }
+ }
+ return result;
+}
+*/
+
+/*****************************************************************************/
+/* */
+/* narrowfloatrand() Generate a float with random 24-bit significand and */
+/* a random exponent in [0, 7]. */
+/* */
+/*****************************************************************************/
+
+/*
+static float narrowfloatrand()
+{
+ float result;
+ float expo;
+ long a, c;
+ long i;
+
+ a = random();
+ c = random();
+ result = (float) ((a - 1073741824) >> 6);
+ for (i = 512, expo = 2; i <= 2048; i *= 2, expo = expo * expo) {
+ if (c & i) {
+ result *= expo;
+ }
+ }
+ return result;
+}
+*/
+
+/*****************************************************************************/
+/* */
+/* uniformfloatrand() Generate a float with random 24-bit significand. */
+/* */
+/*****************************************************************************/
+
+/*
+static float uniformfloatrand()
+{
+ float result;
+ long a;
+
+ a = random();
+ result = (float) ((a - 1073741824) >> 6);
+ return result;
+}
+*/
+
+/*****************************************************************************/
+/* */
+/* fast_expansion_sum_zeroelim() Sum two expansions, eliminating zero */
+/* components from the output expansion. */
+/* */
+/* Sets h = e + f. See the long version of my paper for details. */
+/* */
+/* If round-to-even is used (as with IEEE 754), maintains the strongly */
+/* nonoverlapping property. (That is, if e is strongly nonoverlapping, h */
+/* will be also.) Does NOT maintain the nonoverlapping or nonadjacent */
+/* properties. */
+/* */
+/*****************************************************************************/
+
+static int fast_expansion_sum_zeroelim(int elen, REAL *e,
+ int flen, REAL *f, REAL *h)
+ /* h cannot be e or f. */
+{
+ REAL Q;
+ INEXACT REAL Qnew;
+ INEXACT REAL hh;
+ INEXACT REAL bvirt;
+ REAL avirt, bround, around;
+ int eindex, findex, hindex;
+ REAL enow, fnow;
+
+ enow = e[0];
+ fnow = f[0];
+ eindex = findex = 0;
+ if ((fnow > enow) == (fnow > -enow)) {
+ Q = enow;
+ enow = e[++eindex];
+ } else {
+ Q = fnow;
+ fnow = f[++findex];
+ }
+ hindex = 0;
+ if ((eindex < elen) && (findex < flen)) {
+ if ((fnow > enow) == (fnow > -enow)) {
+ Fast_Two_Sum(enow, Q, Qnew, hh);
+ enow = e[++eindex];
+ } else {
+ Fast_Two_Sum(fnow, Q, Qnew, hh);
+ fnow = f[++findex];
+ }
+ Q = Qnew;
+ if (hh != 0.0) {
+ h[hindex++] = hh;
+ }
+ while ((eindex < elen) && (findex < flen)) {
+ if ((fnow > enow) == (fnow > -enow)) {
+ Two_Sum(Q, enow, Qnew, hh);
+ enow = e[++eindex];
+ } else {
+ Two_Sum(Q, fnow, Qnew, hh);
+ fnow = f[++findex];
+ }
+ Q = Qnew;
+ if (hh != 0.0) {
+ h[hindex++] = hh;
+ }
+ }
+ }
+ while (eindex < elen) {
+ Two_Sum(Q, enow, Qnew, hh);
+ enow = e[++eindex];
+ Q = Qnew;
+ if (hh != 0.0) {
+ h[hindex++] = hh;
+ }
+ }
+ while (findex < flen) {
+ Two_Sum(Q, fnow, Qnew, hh);
+ fnow = f[++findex];
+ Q = Qnew;
+ if (hh != 0.0) {
+ h[hindex++] = hh;
+ }
+ }
+ if ((Q != 0.0) || (hindex == 0)) {
+ h[hindex++] = Q;
+ }
+ return hindex;
+}
+
+/*****************************************************************************/
+/* */
+/* scale_expansion_zeroelim() Multiply an expansion by a scalar, */
+/* eliminating zero components from the */
+/* output expansion. */
+/* */
+/* Sets h = be. See either version of my paper for details. */
+/* */
+/* Maintains the nonoverlapping property. If round-to-even is used (as */
+/* with IEEE 754), maintains the strongly nonoverlapping and nonadjacent */
+/* properties as well. (That is, if e has one of these properties, so */
+/* will h.) */
+/* */
+/*****************************************************************************/
+
+static int scale_expansion_zeroelim(int elen, REAL *e, REAL b, REAL *h)
+ /* e and h cannot be the same. */
+{
+ INEXACT REAL Q, sum;
+ REAL hh;
+ INEXACT REAL product1;
+ REAL product0;
+ int eindex, hindex;
+ REAL enow;
+ INEXACT REAL bvirt;
+ REAL avirt, bround, around;
+ INEXACT REAL c;
+ INEXACT REAL abig;
+ REAL ahi, alo, bhi, blo;
+ REAL err1, err2, err3;
+
+ Split(b, bhi, blo);
+ Two_Product_Presplit(e[0], b, bhi, blo, Q, hh);
+ hindex = 0;
+ if (hh != 0) {
+ h[hindex++] = hh;
+ }
+ for (eindex = 1; eindex < elen; eindex++) {
+ enow = e[eindex];
+ Two_Product_Presplit(enow, b, bhi, blo, product1, product0);
+ Two_Sum(Q, product0, sum, hh);
+ if (hh != 0) {
+ h[hindex++] = hh;
+ }
+ Fast_Two_Sum(product1, sum, Q, hh);
+ if (hh != 0) {
+ h[hindex++] = hh;
+ }
+ }
+ if ((Q != 0.0) || (hindex == 0)) {
+ h[hindex++] = Q;
+ }
+ return hindex;
+}
+
+/*****************************************************************************/
+/* */
+/* estimate() Produce a one-word estimate of an expansion's value. */
+/* */
+/* See either version of my paper for details. */
+/* */
+/*****************************************************************************/
+
+static REAL estimate(int elen, REAL *e)
+{
+ REAL Q;
+ int eindex;
+
+ Q = e[0];
+ for (eindex = 1; eindex < elen; eindex++) {
+ Q += e[eindex];
+ }
+ return Q;
+}
+
+/*****************************************************************************/
+/* */
+/* orient2dfast() Approximate 2D orientation test. Nonrobust. */
+/* orient2dexact() Exact 2D orientation test. Robust. */
+/* orient2dslow() Another exact 2D orientation test. Robust. */
+/* orient2d() Adaptive exact 2D orientation test. Robust. */
+/* */
+/* Return a positive value if the points pa, pb, and pc occur */
+/* in counterclockwise order; a negative value if they occur */
+/* in clockwise order; and zero if they are collinear. The */
+/* result is also a rough approximation of twice the signed */
+/* area of the triangle defined by the three points. */
+/* */
+/* Only the first and last routine should be used; the middle two are for */
+/* timings. */
+/* */
+/* The last three use exact arithmetic to ensure a correct answer. The */
+/* result returned is the determinant of a matrix. In orient2d() only, */
+/* this determinant is computed adaptively, in the sense that exact */
+/* arithmetic is used only to the degree it is needed to ensure that the */
+/* returned value has the correct sign. Hence, orient2d() is usually quite */
+/* fast, but will run more slowly when the input points are collinear or */
+/* nearly so. */
+/* */
+/*****************************************************************************/
+
+REAL orient2dadapt(REAL *pa, REAL *pb, REAL *pc, REAL detsum)
+{
+ INEXACT REAL acx, acy, bcx, bcy;
+ REAL acxtail, acytail, bcxtail, bcytail;
+ INEXACT REAL detleft, detright;
+ REAL detlefttail, detrighttail;
+ REAL det, errbound;
+ REAL B[4], C1[8], C2[12], D[16];
+ INEXACT REAL B3;
+ int C1length, C2length, Dlength;
+ REAL u[4];
+ INEXACT REAL u3;
+ INEXACT REAL s1, t1;
+ REAL s0, t0;
+
+ INEXACT REAL bvirt;
+ REAL avirt, bround, around;
+ INEXACT REAL c;
+ INEXACT REAL abig;
+ REAL ahi, alo, bhi, blo;
+ REAL err1, err2, err3;
+ INEXACT REAL _i, _j;
+ REAL _0;
+
+ acx = (REAL) (pa[0] - pc[0]);
+ bcx = (REAL) (pb[0] - pc[0]);
+ acy = (REAL) (pa[1] - pc[1]);
+ bcy = (REAL) (pb[1] - pc[1]);
+
+ Two_Product(acx, bcy, detleft, detlefttail);
+ Two_Product(acy, bcx, detright, detrighttail);
+
+ Two_Two_Diff(detleft, detlefttail, detright, detrighttail,
+ B3, B[2], B[1], B[0]);
+ B[3] = B3;
+
+ det = estimate(4, B);
+ errbound = ccwerrboundB * detsum;
+ if ((det >= errbound) || (-det >= errbound)) {
+ return det;
+ }
+
+ Two_Diff_Tail(pa[0], pc[0], acx, acxtail);
+ Two_Diff_Tail(pb[0], pc[0], bcx, bcxtail);
+ Two_Diff_Tail(pa[1], pc[1], acy, acytail);
+ Two_Diff_Tail(pb[1], pc[1], bcy, bcytail);
+
+ if ((acxtail == 0.0) && (acytail == 0.0)
+ && (bcxtail == 0.0) && (bcytail == 0.0)) {
+ return det;
+ }
+
+ errbound = ccwerrboundC * detsum + resulterrbound * Absolute(det);
+ det += (acx * bcytail + bcy * acxtail)
+ - (acy * bcxtail + bcx * acytail);
+ if ((det >= errbound) || (-det >= errbound)) {
+ return det;
+ }
+
+ Two_Product(acxtail, bcy, s1, s0);
+ Two_Product(acytail, bcx, t1, t0);
+ Two_Two_Diff(s1, s0, t1, t0, u3, u[2], u[1], u[0]);
+ u[3] = u3;
+ C1length = fast_expansion_sum_zeroelim(4, B, 4, u, C1);
+
+ Two_Product(acx, bcytail, s1, s0);
+ Two_Product(acy, bcxtail, t1, t0);
+ Two_Two_Diff(s1, s0, t1, t0, u3, u[2], u[1], u[0]);
+ u[3] = u3;
+ C2length = fast_expansion_sum_zeroelim(C1length, C1, 4, u, C2);
+
+ Two_Product(acxtail, bcytail, s1, s0);
+ Two_Product(acytail, bcxtail, t1, t0);
+ Two_Two_Diff(s1, s0, t1, t0, u3, u[2], u[1], u[0]);
+ u[3] = u3;
+ Dlength = fast_expansion_sum_zeroelim(C2length, C2, 4, u, D);
+
+ return(D[Dlength - 1]);
+}
+
+REAL orient2d(REAL *pa, REAL *pb, REAL *pc)
+{
+ REAL detleft, detright, det;
+ REAL detsum, errbound;
+ REAL orient;
+
+ FPU_ROUND_DOUBLE;
+
+ detleft = (pa[0] - pc[0]) * (pb[1] - pc[1]);
+ detright = (pa[1] - pc[1]) * (pb[0] - pc[0]);
+ det = detleft - detright;
+
+ if (detleft > 0.0) {
+ if (detright <= 0.0) {
+ FPU_RESTORE;
+ return det;
+ } else {
+ detsum = detleft + detright;
+ }
+ } else if (detleft < 0.0) {
+ if (detright >= 0.0) {
+ FPU_RESTORE;
+ return det;
+ } else {
+ detsum = -detleft - detright;
+ }
+ } else {
+ FPU_RESTORE;
+ return det;
+ }
+
+ errbound = ccwerrboundA * detsum;
+ if ((det >= errbound) || (-det >= errbound)) {
+ FPU_RESTORE;
+ return det;
+ }
+
+ orient = orient2dadapt(pa, pb, pc, detsum);
+ FPU_RESTORE;
+ return orient;
+}
+
+REAL orient2d(REAL ax, REAL ay, REAL bx, REAL by, REAL cx, REAL cy)
+{
+ REAL detleft, detright, det;
+ REAL detsum, errbound;
+ REAL orient;
+
+ FPU_ROUND_DOUBLE;
+
+ detleft = (ax - cx) * (by - cy);
+ detright = (ay - cy) * (bx - cx);
+ det = detleft - detright;
+
+ if (detleft > 0.0) {
+ if (detright <= 0.0) {
+ FPU_RESTORE;
+ return det;
+ } else {
+ detsum = detleft + detright;
+ }
+ } else if (detleft < 0.0) {
+ if (detright >= 0.0) {
+ FPU_RESTORE;
+ return det;
+ } else {
+ detsum = -detleft - detright;
+ }
+ } else {
+ FPU_RESTORE;
+ return det;
+ }
+
+ errbound = ccwerrboundA * detsum;
+ if ((det >= errbound) || (-det >= errbound)) {
+ FPU_RESTORE;
+ return det;
+ }
+
+ REAL pa[]={ax,ay};
+ REAL pb[]={bx,by};
+ REAL pc[]={cx,cy};
+
+ orient = orient2dadapt(pa, pb, pc, detsum);
+ FPU_RESTORE;
+ return orient;
+}
+
+/*****************************************************************************/
+/* */
+/* orient3dfast() Approximate 3D orientation test. Nonrobust. */
+/* orient3dexact() Exact 3D orientation test. Robust. */
+/* orient3dslow() Another exact 3D orientation test. Robust. */
+/* orient3d() Adaptive exact 3D orientation test. Robust. */
+/* */
+/* Return a positive value if the point pd lies below the */
+/* plane passing through pa, pb, and pc; "below" is defined so */
+/* that pa, pb, and pc appear in counterclockwise order when */
+/* viewed from above the plane. Returns a negative value if */
+/* pd lies above the plane. Returns zero if the points are */
+/* coplanar. The result is also a rough approximation of six */
+/* times the signed volume of the tetrahedron defined by the */
+/* four points. */
+/* */
+/* Only the first and last routine should be used; the middle two are for */
+/* timings. */
+/* */
+/* The last three use exact arithmetic to ensure a correct answer. The */
+/* result returned is the determinant of a matrix. In orient3d() only, */
+/* this determinant is computed adaptively, in the sense that exact */
+/* arithmetic is used only to the degree it is needed to ensure that the */
+/* returned value has the correct sign. Hence, orient3d() is usually quite */
+/* fast, but will run more slowly when the input points are coplanar or */
+/* nearly so. */
+/* */
+/*****************************************************************************/
+
+static REAL orient3dadapt(REAL *pa, REAL *pb, REAL *pc, REAL *pd,
+ REAL permanent)
+{
+ INEXACT REAL adx, bdx, cdx, ady, bdy, cdy, adz, bdz, cdz;
+ REAL det, errbound;
+
+ INEXACT REAL bdxcdy1, cdxbdy1, cdxady1, adxcdy1, adxbdy1, bdxady1;
+ REAL bdxcdy0, cdxbdy0, cdxady0, adxcdy0, adxbdy0, bdxady0;
+ REAL bc[4], ca[4], ab[4];
+ INEXACT REAL bc3, ca3, ab3;
+ REAL adet[8], bdet[8], cdet[8];
+ int alen, blen, clen;
+ REAL abdet[16];
+ int ablen;
+ REAL *finnow, *finother, *finswap;
+ REAL fin1[192], fin2[192];
+ int finlength;
+
+ REAL adxtail, bdxtail, cdxtail;
+ REAL adytail, bdytail, cdytail;
+ REAL adztail, bdztail, cdztail;
+ INEXACT REAL at_blarge, at_clarge;
+ INEXACT REAL bt_clarge, bt_alarge;
+ INEXACT REAL ct_alarge, ct_blarge;
+ REAL at_b[4], at_c[4], bt_c[4], bt_a[4], ct_a[4], ct_b[4];
+ int at_blen, at_clen, bt_clen, bt_alen, ct_alen, ct_blen;
+ INEXACT REAL bdxt_cdy1, cdxt_bdy1, cdxt_ady1;
+ INEXACT REAL adxt_cdy1, adxt_bdy1, bdxt_ady1;
+ REAL bdxt_cdy0, cdxt_bdy0, cdxt_ady0;
+ REAL adxt_cdy0, adxt_bdy0, bdxt_ady0;
+ INEXACT REAL bdyt_cdx1, cdyt_bdx1, cdyt_adx1;
+ INEXACT REAL adyt_cdx1, adyt_bdx1, bdyt_adx1;
+ REAL bdyt_cdx0, cdyt_bdx0, cdyt_adx0;
+ REAL adyt_cdx0, adyt_bdx0, bdyt_adx0;
+ REAL bct[8], cat[8], abt[8];
+ int bctlen, catlen, abtlen;
+ INEXACT REAL bdxt_cdyt1, cdxt_bdyt1, cdxt_adyt1;
+ INEXACT REAL adxt_cdyt1, adxt_bdyt1, bdxt_adyt1;
+ REAL bdxt_cdyt0, cdxt_bdyt0, cdxt_adyt0;
+ REAL adxt_cdyt0, adxt_bdyt0, bdxt_adyt0;
+ REAL u[4], v[12], w[16];
+ INEXACT REAL u3;
+ int vlength, wlength;
+ REAL negate;
+
+ INEXACT REAL bvirt;
+ REAL avirt, bround, around;
+ INEXACT REAL c;
+ INEXACT REAL abig;
+ REAL ahi, alo, bhi, blo;
+ REAL err1, err2, err3;
+ INEXACT REAL _i, _j, _k;
+ REAL _0;
+
+ adx = (REAL) (pa[0] - pd[0]);
+ bdx = (REAL) (pb[0] - pd[0]);
+ cdx = (REAL) (pc[0] - pd[0]);
+ ady = (REAL) (pa[1] - pd[1]);
+ bdy = (REAL) (pb[1] - pd[1]);
+ cdy = (REAL) (pc[1] - pd[1]);
+ adz = (REAL) (pa[2] - pd[2]);
+ bdz = (REAL) (pb[2] - pd[2]);
+ cdz = (REAL) (pc[2] - pd[2]);
+
+ Two_Product(bdx, cdy, bdxcdy1, bdxcdy0);
+ Two_Product(cdx, bdy, cdxbdy1, cdxbdy0);
+ Two_Two_Diff(bdxcdy1, bdxcdy0, cdxbdy1, cdxbdy0, bc3, bc[2], bc[1], bc[0]);
+ bc[3] = bc3;
+ alen = scale_expansion_zeroelim(4, bc, adz, adet);
+
+ Two_Product(cdx, ady, cdxady1, cdxady0);
+ Two_Product(adx, cdy, adxcdy1, adxcdy0);
+ Two_Two_Diff(cdxady1, cdxady0, adxcdy1, adxcdy0, ca3, ca[2], ca[1], ca[0]);
+ ca[3] = ca3;
+ blen = scale_expansion_zeroelim(4, ca, bdz, bdet);
+
+ Two_Product(adx, bdy, adxbdy1, adxbdy0);
+ Two_Product(bdx, ady, bdxady1, bdxady0);
+ Two_Two_Diff(adxbdy1, adxbdy0, bdxady1, bdxady0, ab3, ab[2], ab[1], ab[0]);
+ ab[3] = ab3;
+ clen = scale_expansion_zeroelim(4, ab, cdz, cdet);
+
+ ablen = fast_expansion_sum_zeroelim(alen, adet, blen, bdet, abdet);
+ finlength = fast_expansion_sum_zeroelim(ablen, abdet, clen, cdet, fin1);
+
+ det = estimate(finlength, fin1);
+ errbound = o3derrboundB * permanent;
+ if ((det >= errbound) || (-det >= errbound)) {
+ return det;
+ }
+
+ Two_Diff_Tail(pa[0], pd[0], adx, adxtail);
+ Two_Diff_Tail(pb[0], pd[0], bdx, bdxtail);
+ Two_Diff_Tail(pc[0], pd[0], cdx, cdxtail);
+ Two_Diff_Tail(pa[1], pd[1], ady, adytail);
+ Two_Diff_Tail(pb[1], pd[1], bdy, bdytail);
+ Two_Diff_Tail(pc[1], pd[1], cdy, cdytail);
+ Two_Diff_Tail(pa[2], pd[2], adz, adztail);
+ Two_Diff_Tail(pb[2], pd[2], bdz, bdztail);
+ Two_Diff_Tail(pc[2], pd[2], cdz, cdztail);
+
+ if ((adxtail == 0.0) && (bdxtail == 0.0) && (cdxtail == 0.0)
+ && (adytail == 0.0) && (bdytail == 0.0) && (cdytail == 0.0)
+ && (adztail == 0.0) && (bdztail == 0.0) && (cdztail == 0.0)) {
+ return det;
+ }
+
+ errbound = o3derrboundC * permanent + resulterrbound * Absolute(det);
+ det += (adz * ((bdx * cdytail + cdy * bdxtail)
+ - (bdy * cdxtail + cdx * bdytail))
+ + adztail * (bdx * cdy - bdy * cdx))
+ + (bdz * ((cdx * adytail + ady * cdxtail)
+ - (cdy * adxtail + adx * cdytail))
+ + bdztail * (cdx * ady - cdy * adx))
+ + (cdz * ((adx * bdytail + bdy * adxtail)
+ - (ady * bdxtail + bdx * adytail))
+ + cdztail * (adx * bdy - ady * bdx));
+ if ((det >= errbound) || (-det >= errbound)) {
+ return det;
+ }
+
+ finnow = fin1;
+ finother = fin2;
+
+ if (adxtail == 0.0) {
+ if (adytail == 0.0) {
+ at_b[0] = 0.0;
+ at_blen = 1;
+ at_c[0] = 0.0;
+ at_clen = 1;
+ } else {
+ negate = -adytail;
+ Two_Product(negate, bdx, at_blarge, at_b[0]);
+ at_b[1] = at_blarge;
+ at_blen = 2;
+ Two_Product(adytail, cdx, at_clarge, at_c[0]);
+ at_c[1] = at_clarge;
+ at_clen = 2;
+ }
+ } else {
+ if (adytail == 0.0) {
+ Two_Product(adxtail, bdy, at_blarge, at_b[0]);
+ at_b[1] = at_blarge;
+ at_blen = 2;
+ negate = -adxtail;
+ Two_Product(negate, cdy, at_clarge, at_c[0]);
+ at_c[1] = at_clarge;
+ at_clen = 2;
+ } else {
+ Two_Product(adxtail, bdy, adxt_bdy1, adxt_bdy0);
+ Two_Product(adytail, bdx, adyt_bdx1, adyt_bdx0);
+ Two_Two_Diff(adxt_bdy1, adxt_bdy0, adyt_bdx1, adyt_bdx0,
+ at_blarge, at_b[2], at_b[1], at_b[0]);
+ at_b[3] = at_blarge;
+ at_blen = 4;
+ Two_Product(adytail, cdx, adyt_cdx1, adyt_cdx0);
+ Two_Product(adxtail, cdy, adxt_cdy1, adxt_cdy0);
+ Two_Two_Diff(adyt_cdx1, adyt_cdx0, adxt_cdy1, adxt_cdy0,
+ at_clarge, at_c[2], at_c[1], at_c[0]);
+ at_c[3] = at_clarge;
+ at_clen = 4;
+ }
+ }
+ if (bdxtail == 0.0) {
+ if (bdytail == 0.0) {
+ bt_c[0] = 0.0;
+ bt_clen = 1;
+ bt_a[0] = 0.0;
+ bt_alen = 1;
+ } else {
+ negate = -bdytail;
+ Two_Product(negate, cdx, bt_clarge, bt_c[0]);
+ bt_c[1] = bt_clarge;
+ bt_clen = 2;
+ Two_Product(bdytail, adx, bt_alarge, bt_a[0]);
+ bt_a[1] = bt_alarge;
+ bt_alen = 2;
+ }
+ } else {
+ if (bdytail == 0.0) {
+ Two_Product(bdxtail, cdy, bt_clarge, bt_c[0]);
+ bt_c[1] = bt_clarge;
+ bt_clen = 2;
+ negate = -bdxtail;
+ Two_Product(negate, ady, bt_alarge, bt_a[0]);
+ bt_a[1] = bt_alarge;
+ bt_alen = 2;
+ } else {
+ Two_Product(bdxtail, cdy, bdxt_cdy1, bdxt_cdy0);
+ Two_Product(bdytail, cdx, bdyt_cdx1, bdyt_cdx0);
+ Two_Two_Diff(bdxt_cdy1, bdxt_cdy0, bdyt_cdx1, bdyt_cdx0,
+ bt_clarge, bt_c[2], bt_c[1], bt_c[0]);
+ bt_c[3] = bt_clarge;
+ bt_clen = 4;
+ Two_Product(bdytail, adx, bdyt_adx1, bdyt_adx0);
+ Two_Product(bdxtail, ady, bdxt_ady1, bdxt_ady0);
+ Two_Two_Diff(bdyt_adx1, bdyt_adx0, bdxt_ady1, bdxt_ady0,
+ bt_alarge, bt_a[2], bt_a[1], bt_a[0]);
+ bt_a[3] = bt_alarge;
+ bt_alen = 4;
+ }
+ }
+ if (cdxtail == 0.0) {
+ if (cdytail == 0.0) {
+ ct_a[0] = 0.0;
+ ct_alen = 1;
+ ct_b[0] = 0.0;
+ ct_blen = 1;
+ } else {
+ negate = -cdytail;
+ Two_Product(negate, adx, ct_alarge, ct_a[0]);
+ ct_a[1] = ct_alarge;
+ ct_alen = 2;
+ Two_Product(cdytail, bdx, ct_blarge, ct_b[0]);
+ ct_b[1] = ct_blarge;
+ ct_blen = 2;
+ }
+ } else {
+ if (cdytail == 0.0) {
+ Two_Product(cdxtail, ady, ct_alarge, ct_a[0]);
+ ct_a[1] = ct_alarge;
+ ct_alen = 2;
+ negate = -cdxtail;
+ Two_Product(negate, bdy, ct_blarge, ct_b[0]);
+ ct_b[1] = ct_blarge;
+ ct_blen = 2;
+ } else {
+ Two_Product(cdxtail, ady, cdxt_ady1, cdxt_ady0);
+ Two_Product(cdytail, adx, cdyt_adx1, cdyt_adx0);
+ Two_Two_Diff(cdxt_ady1, cdxt_ady0, cdyt_adx1, cdyt_adx0,
+ ct_alarge, ct_a[2], ct_a[1], ct_a[0]);
+ ct_a[3] = ct_alarge;
+ ct_alen = 4;
+ Two_Product(cdytail, bdx, cdyt_bdx1, cdyt_bdx0);
+ Two_Product(cdxtail, bdy, cdxt_bdy1, cdxt_bdy0);
+ Two_Two_Diff(cdyt_bdx1, cdyt_bdx0, cdxt_bdy1, cdxt_bdy0,
+ ct_blarge, ct_b[2], ct_b[1], ct_b[0]);
+ ct_b[3] = ct_blarge;
+ ct_blen = 4;
+ }
+ }
+
+ bctlen = fast_expansion_sum_zeroelim(bt_clen, bt_c, ct_blen, ct_b, bct);
+ wlength = scale_expansion_zeroelim(bctlen, bct, adz, w);
+ finlength = fast_expansion_sum_zeroelim(finlength, finnow, wlength, w,
+ finother);
+ finswap = finnow; finnow = finother; finother = finswap;
+
+ catlen = fast_expansion_sum_zeroelim(ct_alen, ct_a, at_clen, at_c, cat);
+ wlength = scale_expansion_zeroelim(catlen, cat, bdz, w);
+ finlength = fast_expansion_sum_zeroelim(finlength, finnow, wlength, w,
+ finother);
+ finswap = finnow; finnow = finother; finother = finswap;
+
+ abtlen = fast_expansion_sum_zeroelim(at_blen, at_b, bt_alen, bt_a, abt);
+ wlength = scale_expansion_zeroelim(abtlen, abt, cdz, w);
+ finlength = fast_expansion_sum_zeroelim(finlength, finnow, wlength, w,
+ finother);
+ finswap = finnow; finnow = finother; finother = finswap;
+
+ if (adztail != 0.0) {
+ vlength = scale_expansion_zeroelim(4, bc, adztail, v);
+ finlength = fast_expansion_sum_zeroelim(finlength, finnow, vlength, v,
+ finother);
+ finswap = finnow; finnow = finother; finother = finswap;
+ }
+ if (bdztail != 0.0) {
+ vlength = scale_expansion_zeroelim(4, ca, bdztail, v);
+ finlength = fast_expansion_sum_zeroelim(finlength, finnow, vlength, v,
+ finother);
+ finswap = finnow; finnow = finother; finother = finswap;
+ }
+ if (cdztail != 0.0) {
+ vlength = scale_expansion_zeroelim(4, ab, cdztail, v);
+ finlength = fast_expansion_sum_zeroelim(finlength, finnow, vlength, v,
+ finother);
+ finswap = finnow; finnow = finother; finother = finswap;
+ }
+
+ if (adxtail != 0.0) {
+ if (bdytail != 0.0) {
+ Two_Product(adxtail, bdytail, adxt_bdyt1, adxt_bdyt0);
+ Two_One_Product(adxt_bdyt1, adxt_bdyt0, cdz, u3, u[2], u[1], u[0]);
+ u[3] = u3;
+ finlength = fast_expansion_sum_zeroelim(finlength, finnow, 4, u,
+ finother);
+ finswap = finnow; finnow = finother; finother = finswap;
+ if (cdztail != 0.0) {
+ Two_One_Product(adxt_bdyt1, adxt_bdyt0, cdztail, u3, u[2], u[1], u[0]);
+ u[3] = u3;
+ finlength = fast_expansion_sum_zeroelim(finlength, finnow, 4, u,
+ finother);
+ finswap = finnow; finnow = finother; finother = finswap;
+ }
+ }
+ if (cdytail != 0.0) {
+ negate = -adxtail;
+ Two_Product(negate, cdytail, adxt_cdyt1, adxt_cdyt0);
+ Two_One_Product(adxt_cdyt1, adxt_cdyt0, bdz, u3, u[2], u[1], u[0]);
+ u[3] = u3;
+ finlength = fast_expansion_sum_zeroelim(finlength, finnow, 4, u,
+ finother);
+ finswap = finnow; finnow = finother; finother = finswap;
+ if (bdztail != 0.0) {
+ Two_One_Product(adxt_cdyt1, adxt_cdyt0, bdztail, u3, u[2], u[1], u[0]);
+ u[3] = u3;
+ finlength = fast_expansion_sum_zeroelim(finlength, finnow, 4, u,
+ finother);
+ finswap = finnow; finnow = finother; finother = finswap;
+ }
+ }
+ }
+ if (bdxtail != 0.0) {
+ if (cdytail != 0.0) {
+ Two_Product(bdxtail, cdytail, bdxt_cdyt1, bdxt_cdyt0);
+ Two_One_Product(bdxt_cdyt1, bdxt_cdyt0, adz, u3, u[2], u[1], u[0]);
+ u[3] = u3;
+ finlength = fast_expansion_sum_zeroelim(finlength, finnow, 4, u,
+ finother);
+ finswap = finnow; finnow = finother; finother = finswap;
+ if (adztail != 0.0) {
+ Two_One_Product(bdxt_cdyt1, bdxt_cdyt0, adztail, u3, u[2], u[1], u[0]);
+ u[3] = u3;
+ finlength = fast_expansion_sum_zeroelim(finlength, finnow, 4, u,
+ finother);
+ finswap = finnow; finnow = finother; finother = finswap;
+ }
+ }
+ if (adytail != 0.0) {
+ negate = -bdxtail;
+ Two_Product(negate, adytail, bdxt_adyt1, bdxt_adyt0);
+ Two_One_Product(bdxt_adyt1, bdxt_adyt0, cdz, u3, u[2], u[1], u[0]);
+ u[3] = u3;
+ finlength = fast_expansion_sum_zeroelim(finlength, finnow, 4, u,
+ finother);
+ finswap = finnow; finnow = finother; finother = finswap;
+ if (cdztail != 0.0) {
+ Two_One_Product(bdxt_adyt1, bdxt_adyt0, cdztail, u3, u[2], u[1], u[0]);
+ u[3] = u3;
+ finlength = fast_expansion_sum_zeroelim(finlength, finnow, 4, u,
+ finother);
+ finswap = finnow; finnow = finother; finother = finswap;
+ }
+ }
+ }
+ if (cdxtail != 0.0) {
+ if (adytail != 0.0) {
+ Two_Product(cdxtail, adytail, cdxt_adyt1, cdxt_adyt0);
+ Two_One_Product(cdxt_adyt1, cdxt_adyt0, bdz, u3, u[2], u[1], u[0]);
+ u[3] = u3;
+ finlength = fast_expansion_sum_zeroelim(finlength, finnow, 4, u,
+ finother);
+ finswap = finnow; finnow = finother; finother = finswap;
+ if (bdztail != 0.0) {
+ Two_One_Product(cdxt_adyt1, cdxt_adyt0, bdztail, u3, u[2], u[1], u[0]);
+ u[3] = u3;
+ finlength = fast_expansion_sum_zeroelim(finlength, finnow, 4, u,
+ finother);
+ finswap = finnow; finnow = finother; finother = finswap;
+ }
+ }
+ if (bdytail != 0.0) {
+ negate = -cdxtail;
+ Two_Product(negate, bdytail, cdxt_bdyt1, cdxt_bdyt0);
+ Two_One_Product(cdxt_bdyt1, cdxt_bdyt0, adz, u3, u[2], u[1], u[0]);
+ u[3] = u3;
+ finlength = fast_expansion_sum_zeroelim(finlength, finnow, 4, u,
+ finother);
+ finswap = finnow; finnow = finother; finother = finswap;
+ if (adztail != 0.0) {
+ Two_One_Product(cdxt_bdyt1, cdxt_bdyt0, adztail, u3, u[2], u[1], u[0]);
+ u[3] = u3;
+ finlength = fast_expansion_sum_zeroelim(finlength, finnow, 4, u,
+ finother);
+ finswap = finnow; finnow = finother; finother = finswap;
+ }
+ }
+ }
+
+ if (adztail != 0.0) {
+ wlength = scale_expansion_zeroelim(bctlen, bct, adztail, w);
+ finlength = fast_expansion_sum_zeroelim(finlength, finnow, wlength, w,
+ finother);
+ finswap = finnow; finnow = finother; finother = finswap;
+ }
+ if (bdztail != 0.0) {
+ wlength = scale_expansion_zeroelim(catlen, cat, bdztail, w);
+ finlength = fast_expansion_sum_zeroelim(finlength, finnow, wlength, w,
+ finother);
+ finswap = finnow; finnow = finother; finother = finswap;
+ }
+ if (cdztail != 0.0) {
+ wlength = scale_expansion_zeroelim(abtlen, abt, cdztail, w);
+ finlength = fast_expansion_sum_zeroelim(finlength, finnow, wlength, w,
+ finother);
+ finswap = finnow; finnow = finother; finother = finswap;
+ }
+
+ return finnow[finlength - 1];
+}
+
+REAL orient3d(REAL *pa, REAL *pb, REAL *pc, REAL *pd)
+{
+ REAL adx, bdx, cdx, ady, bdy, cdy, adz, bdz, cdz;
+ REAL bdxcdy, cdxbdy, cdxady, adxcdy, adxbdy, bdxady;
+ REAL det;
+ REAL permanent, errbound;
+ REAL orient;
+
+ FPU_ROUND_DOUBLE;
+
+ adx = pa[0] - pd[0];
+ bdx = pb[0] - pd[0];
+ cdx = pc[0] - pd[0];
+ ady = pa[1] - pd[1];
+ bdy = pb[1] - pd[1];
+ cdy = pc[1] - pd[1];
+ adz = pa[2] - pd[2];
+ bdz = pb[2] - pd[2];
+ cdz = pc[2] - pd[2];
+
+ bdxcdy = bdx * cdy;
+ cdxbdy = cdx * bdy;
+
+ cdxady = cdx * ady;
+ adxcdy = adx * cdy;
+
+ adxbdy = adx * bdy;
+ bdxady = bdx * ady;
+
+ det = adz * (bdxcdy - cdxbdy)
+ + bdz * (cdxady - adxcdy)
+ + cdz * (adxbdy - bdxady);
+
+ permanent = (Absolute(bdxcdy) + Absolute(cdxbdy)) * Absolute(adz)
+ + (Absolute(cdxady) + Absolute(adxcdy)) * Absolute(bdz)
+ + (Absolute(adxbdy) + Absolute(bdxady)) * Absolute(cdz);
+ errbound = o3derrboundA * permanent;
+ if ((det > errbound) || (-det > errbound)) {
+ FPU_RESTORE;
+ return det;
+ }
+
+ orient = orient3dadapt(pa, pb, pc, pd, permanent);
+ FPU_RESTORE;
+ return orient;
+}
+
+/*****************************************************************************/
+/* */
+/* incirclefast() Approximate 2D incircle test. Nonrobust. */
+/* incircleexact() Exact 2D incircle test. Robust. */
+/* incircleslow() Another exact 2D incircle test. Robust. */
+/* incircle() Adaptive exact 2D incircle test. Robust. */
+/* */
+/* Return a positive value if the point pd lies inside the */
+/* circle passing through pa, pb, and pc; a negative value if */
+/* it lies outside; and zero if the four points are cocircular.*/
+/* The points pa, pb, and pc must be in counterclockwise */
+/* order, or the sign of the result will be reversed. */
+/* */
+/* Only the first and last routine should be used; the middle two are for */
+/* timings. */
+/* */
+/* The last three use exact arithmetic to ensure a correct answer. The */
+/* result returned is the determinant of a matrix. In incircle() only, */
+/* this determinant is computed adaptively, in the sense that exact */
+/* arithmetic is used only to the degree it is needed to ensure that the */
+/* returned value has the correct sign. Hence, incircle() is usually quite */
+/* fast, but will run more slowly when the input points are cocircular or */
+/* nearly so. */
+/* */
+/*****************************************************************************/
+
+static REAL incircleadapt(REAL *pa, REAL *pb, REAL *pc, REAL *pd,
+ REAL permanent)
+{
+ INEXACT REAL adx, bdx, cdx, ady, bdy, cdy;
+ REAL det, errbound;
+
+ INEXACT REAL bdxcdy1, cdxbdy1, cdxady1, adxcdy1, adxbdy1, bdxady1;
+ REAL bdxcdy0, cdxbdy0, cdxady0, adxcdy0, adxbdy0, bdxady0;
+ REAL bc[4], ca[4], ab[4];
+ INEXACT REAL bc3, ca3, ab3;
+ REAL axbc[8], axxbc[16], aybc[8], ayybc[16], adet[32];
+ int axbclen, axxbclen, aybclen, ayybclen, alen;
+ REAL bxca[8], bxxca[16], byca[8], byyca[16], bdet[32];
+ int bxcalen, bxxcalen, bycalen, byycalen, blen;
+ REAL cxab[8], cxxab[16], cyab[8], cyyab[16], cdet[32];
+ int cxablen, cxxablen, cyablen, cyyablen, clen;
+ REAL abdet[64];
+ int ablen;
+ REAL fin1[1152], fin2[1152];
+ REAL *finnow, *finother, *finswap;
+ int finlength;
+
+ REAL adxtail, bdxtail, cdxtail, adytail, bdytail, cdytail;
+ INEXACT REAL adxadx1, adyady1, bdxbdx1, bdybdy1, cdxcdx1, cdycdy1;
+ REAL adxadx0, adyady0, bdxbdx0, bdybdy0, cdxcdx0, cdycdy0;
+ REAL aa[4], bb[4], cc[4];
+ INEXACT REAL aa3, bb3, cc3;
+ INEXACT REAL ti1, tj1;
+ REAL ti0, tj0;
+ REAL u[4], v[4];
+ INEXACT REAL u3, v3;
+ REAL temp8[8], temp16a[16], temp16b[16], temp16c[16];
+ REAL temp32a[32], temp32b[32], temp48[48], temp64[64];
+ int temp8len, temp16alen, temp16blen, temp16clen;
+ int temp32alen, temp32blen, temp48len, temp64len;
+ REAL axtbb[8], axtcc[8], aytbb[8], aytcc[8];
+ int axtbblen, axtcclen, aytbblen, aytcclen;
+ REAL bxtaa[8], bxtcc[8], bytaa[8], bytcc[8];
+ int bxtaalen, bxtcclen, bytaalen, bytcclen;
+ REAL cxtaa[8], cxtbb[8], cytaa[8], cytbb[8];
+ int cxtaalen, cxtbblen, cytaalen, cytbblen;
+ REAL axtbc[8], aytbc[8], bxtca[8], bytca[8], cxtab[8], cytab[8];
+ int axtbclen = 0, aytbclen = 0;
+ int bxtcalen = 0, bytcalen = 0;
+ int cxtablen = 0, cytablen = 0;
+ REAL axtbct[16], aytbct[16], bxtcat[16], bytcat[16], cxtabt[16], cytabt[16];
+ int axtbctlen, aytbctlen, bxtcatlen, bytcatlen, cxtabtlen, cytabtlen;
+ REAL axtbctt[8], aytbctt[8], bxtcatt[8];
+ REAL bytcatt[8], cxtabtt[8], cytabtt[8];
+ int axtbcttlen, aytbcttlen, bxtcattlen, bytcattlen, cxtabttlen, cytabttlen;
+ REAL abt[8], bct[8], cat[8];
+ int abtlen, bctlen, catlen;
+ REAL abtt[4], bctt[4], catt[4];
+ int abttlen, bcttlen, cattlen;
+ INEXACT REAL abtt3, bctt3, catt3;
+ REAL negate;
+
+ INEXACT REAL bvirt;
+ REAL avirt, bround, around;
+ INEXACT REAL c;
+ INEXACT REAL abig;
+ REAL ahi, alo, bhi, blo;
+ REAL err1, err2, err3;
+ INEXACT REAL _i, _j;
+ REAL _0;
+
+ adx = (REAL) (pa[0] - pd[0]);
+ bdx = (REAL) (pb[0] - pd[0]);
+ cdx = (REAL) (pc[0] - pd[0]);
+ ady = (REAL) (pa[1] - pd[1]);
+ bdy = (REAL) (pb[1] - pd[1]);
+ cdy = (REAL) (pc[1] - pd[1]);
+
+ Two_Product(bdx, cdy, bdxcdy1, bdxcdy0);
+ Two_Product(cdx, bdy, cdxbdy1, cdxbdy0);
+ Two_Two_Diff(bdxcdy1, bdxcdy0, cdxbdy1, cdxbdy0, bc3, bc[2], bc[1], bc[0]);
+ bc[3] = bc3;
+ axbclen = scale_expansion_zeroelim(4, bc, adx, axbc);
+ axxbclen = scale_expansion_zeroelim(axbclen, axbc, adx, axxbc);
+ aybclen = scale_expansion_zeroelim(4, bc, ady, aybc);
+ ayybclen = scale_expansion_zeroelim(aybclen, aybc, ady, ayybc);
+ alen = fast_expansion_sum_zeroelim(axxbclen, axxbc, ayybclen, ayybc, adet);
+
+ Two_Product(cdx, ady, cdxady1, cdxady0);
+ Two_Product(adx, cdy, adxcdy1, adxcdy0);
+ Two_Two_Diff(cdxady1, cdxady0, adxcdy1, adxcdy0, ca3, ca[2], ca[1], ca[0]);
+ ca[3] = ca3;
+ bxcalen = scale_expansion_zeroelim(4, ca, bdx, bxca);
+ bxxcalen = scale_expansion_zeroelim(bxcalen, bxca, bdx, bxxca);
+ bycalen = scale_expansion_zeroelim(4, ca, bdy, byca);
+ byycalen = scale_expansion_zeroelim(bycalen, byca, bdy, byyca);
+ blen = fast_expansion_sum_zeroelim(bxxcalen, bxxca, byycalen, byyca, bdet);
+
+ Two_Product(adx, bdy, adxbdy1, adxbdy0);
+ Two_Product(bdx, ady, bdxady1, bdxady0);
+ Two_Two_Diff(adxbdy1, adxbdy0, bdxady1, bdxady0, ab3, ab[2], ab[1], ab[0]);
+ ab[3] = ab3;
+ cxablen = scale_expansion_zeroelim(4, ab, cdx, cxab);
+ cxxablen = scale_expansion_zeroelim(cxablen, cxab, cdx, cxxab);
+ cyablen = scale_expansion_zeroelim(4, ab, cdy, cyab);
+ cyyablen = scale_expansion_zeroelim(cyablen, cyab, cdy, cyyab);
+ clen = fast_expansion_sum_zeroelim(cxxablen, cxxab, cyyablen, cyyab, cdet);
+
+ ablen = fast_expansion_sum_zeroelim(alen, adet, blen, bdet, abdet);
+ finlength = fast_expansion_sum_zeroelim(ablen, abdet, clen, cdet, fin1);
+
+ det = estimate(finlength, fin1);
+ errbound = iccerrboundB * permanent;
+ if ((det >= errbound) || (-det >= errbound)) {
+ return det;
+ }
+
+ Two_Diff_Tail(pa[0], pd[0], adx, adxtail);
+ Two_Diff_Tail(pa[1], pd[1], ady, adytail);
+ Two_Diff_Tail(pb[0], pd[0], bdx, bdxtail);
+ Two_Diff_Tail(pb[1], pd[1], bdy, bdytail);
+ Two_Diff_Tail(pc[0], pd[0], cdx, cdxtail);
+ Two_Diff_Tail(pc[1], pd[1], cdy, cdytail);
+ if ((adxtail == 0.0) && (bdxtail == 0.0) && (cdxtail == 0.0)
+ && (adytail == 0.0) && (bdytail == 0.0) && (cdytail == 0.0)) {
+ return det;
+ }
+
+ errbound = iccerrboundC * permanent + resulterrbound * Absolute(det);
+ det += ((adx * adx + ady * ady) * ((bdx * cdytail + cdy * bdxtail)
+ - (bdy * cdxtail + cdx * bdytail))
+ + 2.0 * (adx * adxtail + ady * adytail) * (bdx * cdy - bdy * cdx))
+ + ((bdx * bdx + bdy * bdy) * ((cdx * adytail + ady * cdxtail)
+ - (cdy * adxtail + adx * cdytail))
+ + 2.0 * (bdx * bdxtail + bdy * bdytail) * (cdx * ady - cdy * adx))
+ + ((cdx * cdx + cdy * cdy) * ((adx * bdytail + bdy * adxtail)
+ - (ady * bdxtail + bdx * adytail))
+ + 2.0 * (cdx * cdxtail + cdy * cdytail) * (adx * bdy - ady * bdx));
+ if ((det >= errbound) || (-det >= errbound)) {
+ return det;
+ }
+
+ finnow = fin1;
+ finother = fin2;
+
+ if ((bdxtail != 0.0) || (bdytail != 0.0)
+ || (cdxtail != 0.0) || (cdytail != 0.0)) {
+ Square(adx, adxadx1, adxadx0);
+ Square(ady, adyady1, adyady0);
+ Two_Two_Sum(adxadx1, adxadx0, adyady1, adyady0, aa3, aa[2], aa[1], aa[0]);
+ aa[3] = aa3;
+ }
+ if ((cdxtail != 0.0) || (cdytail != 0.0)
+ || (adxtail != 0.0) || (adytail != 0.0)) {
+ Square(bdx, bdxbdx1, bdxbdx0);
+ Square(bdy, bdybdy1, bdybdy0);
+ Two_Two_Sum(bdxbdx1, bdxbdx0, bdybdy1, bdybdy0, bb3, bb[2], bb[1], bb[0]);
+ bb[3] = bb3;
+ }
+ if ((adxtail != 0.0) || (adytail != 0.0)
+ || (bdxtail != 0.0) || (bdytail != 0.0)) {
+ Square(cdx, cdxcdx1, cdxcdx0);
+ Square(cdy, cdycdy1, cdycdy0);
+ Two_Two_Sum(cdxcdx1, cdxcdx0, cdycdy1, cdycdy0, cc3, cc[2], cc[1], cc[0]);
+ cc[3] = cc3;
+ }
+
+ if (adxtail != 0.0) {
+ axtbclen = scale_expansion_zeroelim(4, bc, adxtail, axtbc);
+ temp16alen = scale_expansion_zeroelim(axtbclen, axtbc, 2.0 * adx,
+ temp16a);
+
+ axtcclen = scale_expansion_zeroelim(4, cc, adxtail, axtcc);
+ temp16blen = scale_expansion_zeroelim(axtcclen, axtcc, bdy, temp16b);
+
+ axtbblen = scale_expansion_zeroelim(4, bb, adxtail, axtbb);
+ temp16clen = scale_expansion_zeroelim(axtbblen, axtbb, -cdy, temp16c);
+
+ temp32alen = fast_expansion_sum_zeroelim(temp16alen, temp16a,
+ temp16blen, temp16b, temp32a);
+ temp48len = fast_expansion_sum_zeroelim(temp16clen, temp16c,
+ temp32alen, temp32a, temp48);
+ finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp48len,
+ temp48, finother);
+ finswap = finnow; finnow = finother; finother = finswap;
+ }
+ if (adytail != 0.0) {
+ aytbclen = scale_expansion_zeroelim(4, bc, adytail, aytbc);
+ temp16alen = scale_expansion_zeroelim(aytbclen, aytbc, 2.0 * ady,
+ temp16a);
+
+ aytbblen = scale_expansion_zeroelim(4, bb, adytail, aytbb);
+ temp16blen = scale_expansion_zeroelim(aytbblen, aytbb, cdx, temp16b);
+
+ aytcclen = scale_expansion_zeroelim(4, cc, adytail, aytcc);
+ temp16clen = scale_expansion_zeroelim(aytcclen, aytcc, -bdx, temp16c);
+
+ temp32alen = fast_expansion_sum_zeroelim(temp16alen, temp16a,
+ temp16blen, temp16b, temp32a);
+ temp48len = fast_expansion_sum_zeroelim(temp16clen, temp16c,
+ temp32alen, temp32a, temp48);
+ finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp48len,
+ temp48, finother);
+ finswap = finnow; finnow = finother; finother = finswap;
+ }
+ if (bdxtail != 0.0) {
+ bxtcalen = scale_expansion_zeroelim(4, ca, bdxtail, bxtca);
+ temp16alen = scale_expansion_zeroelim(bxtcalen, bxtca, 2.0 * bdx,
+ temp16a);
+
+ bxtaalen = scale_expansion_zeroelim(4, aa, bdxtail, bxtaa);
+ temp16blen = scale_expansion_zeroelim(bxtaalen, bxtaa, cdy, temp16b);
+
+ bxtcclen = scale_expansion_zeroelim(4, cc, bdxtail, bxtcc);
+ temp16clen = scale_expansion_zeroelim(bxtcclen, bxtcc, -ady, temp16c);
+
+ temp32alen = fast_expansion_sum_zeroelim(temp16alen, temp16a,
+ temp16blen, temp16b, temp32a);
+ temp48len = fast_expansion_sum_zeroelim(temp16clen, temp16c,
+ temp32alen, temp32a, temp48);
+ finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp48len,
+ temp48, finother);
+ finswap = finnow; finnow = finother; finother = finswap;
+ }
+ if (bdytail != 0.0) {
+ bytcalen = scale_expansion_zeroelim(4, ca, bdytail, bytca);
+ temp16alen = scale_expansion_zeroelim(bytcalen, bytca, 2.0 * bdy,
+ temp16a);
+
+ bytcclen = scale_expansion_zeroelim(4, cc, bdytail, bytcc);
+ temp16blen = scale_expansion_zeroelim(bytcclen, bytcc, adx, temp16b);
+
+ bytaalen = scale_expansion_zeroelim(4, aa, bdytail, bytaa);
+ temp16clen = scale_expansion_zeroelim(bytaalen, bytaa, -cdx, temp16c);
+
+ temp32alen = fast_expansion_sum_zeroelim(temp16alen, temp16a,
+ temp16blen, temp16b, temp32a);
+ temp48len = fast_expansion_sum_zeroelim(temp16clen, temp16c,
+ temp32alen, temp32a, temp48);
+ finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp48len,
+ temp48, finother);
+ finswap = finnow; finnow = finother; finother = finswap;
+ }
+ if (cdxtail != 0.0) {
+ cxtablen = scale_expansion_zeroelim(4, ab, cdxtail, cxtab);
+ temp16alen = scale_expansion_zeroelim(cxtablen, cxtab, 2.0 * cdx,
+ temp16a);
+
+ cxtbblen = scale_expansion_zeroelim(4, bb, cdxtail, cxtbb);
+ temp16blen = scale_expansion_zeroelim(cxtbblen, cxtbb, ady, temp16b);
+
+ cxtaalen = scale_expansion_zeroelim(4, aa, cdxtail, cxtaa);
+ temp16clen = scale_expansion_zeroelim(cxtaalen, cxtaa, -bdy, temp16c);
+
+ temp32alen = fast_expansion_sum_zeroelim(temp16alen, temp16a,
+ temp16blen, temp16b, temp32a);
+ temp48len = fast_expansion_sum_zeroelim(temp16clen, temp16c,
+ temp32alen, temp32a, temp48);
+ finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp48len,
+ temp48, finother);
+ finswap = finnow; finnow = finother; finother = finswap;
+ }
+ if (cdytail != 0.0) {
+ cytablen = scale_expansion_zeroelim(4, ab, cdytail, cytab);
+ temp16alen = scale_expansion_zeroelim(cytablen, cytab, 2.0 * cdy,
+ temp16a);
+
+ cytaalen = scale_expansion_zeroelim(4, aa, cdytail, cytaa);
+ temp16blen = scale_expansion_zeroelim(cytaalen, cytaa, bdx, temp16b);
+
+ cytbblen = scale_expansion_zeroelim(4, bb, cdytail, cytbb);
+ temp16clen = scale_expansion_zeroelim(cytbblen, cytbb, -adx, temp16c);
+
+ temp32alen = fast_expansion_sum_zeroelim(temp16alen, temp16a,
+ temp16blen, temp16b, temp32a);
+ temp48len = fast_expansion_sum_zeroelim(temp16clen, temp16c,
+ temp32alen, temp32a, temp48);
+ finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp48len,
+ temp48, finother);
+ finswap = finnow; finnow = finother; finother = finswap;
+ }
+
+ if ((adxtail != 0.0) || (adytail != 0.0)) {
+ if ((bdxtail != 0.0) || (bdytail != 0.0)
+ || (cdxtail != 0.0) || (cdytail != 0.0)) {
+ Two_Product(bdxtail, cdy, ti1, ti0);
+ Two_Product(bdx, cdytail, tj1, tj0);
+ Two_Two_Sum(ti1, ti0, tj1, tj0, u3, u[2], u[1], u[0]);
+ u[3] = u3;
+ negate = -bdy;
+ Two_Product(cdxtail, negate, ti1, ti0);
+ negate = -bdytail;
+ Two_Product(cdx, negate, tj1, tj0);
+ Two_Two_Sum(ti1, ti0, tj1, tj0, v3, v[2], v[1], v[0]);
+ v[3] = v3;
+ bctlen = fast_expansion_sum_zeroelim(4, u, 4, v, bct);
+
+ Two_Product(bdxtail, cdytail, ti1, ti0);
+ Two_Product(cdxtail, bdytail, tj1, tj0);
+ Two_Two_Diff(ti1, ti0, tj1, tj0, bctt3, bctt[2], bctt[1], bctt[0]);
+ bctt[3] = bctt3;
+ bcttlen = 4;
+ } else {
+ bct[0] = 0.0;
+ bctlen = 1;
+ bctt[0] = 0.0;
+ bcttlen = 1;
+ }
+
+ if (adxtail != 0.0) {
+ temp16alen = scale_expansion_zeroelim(axtbclen, axtbc, adxtail, temp16a);
+ axtbctlen = scale_expansion_zeroelim(bctlen, bct, adxtail, axtbct);
+ temp32alen = scale_expansion_zeroelim(axtbctlen, axtbct, 2.0 * adx,
+ temp32a);
+ temp48len = fast_expansion_sum_zeroelim(temp16alen, temp16a,
+ temp32alen, temp32a, temp48);
+ finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp48len,
+ temp48, finother);
+ finswap = finnow; finnow = finother; finother = finswap;
+ if (bdytail != 0.0) {
+ temp8len = scale_expansion_zeroelim(4, cc, adxtail, temp8);
+ temp16alen = scale_expansion_zeroelim(temp8len, temp8, bdytail,
+ temp16a);
+ finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp16alen,
+ temp16a, finother);
+ finswap = finnow; finnow = finother; finother = finswap;
+ }
+ if (cdytail != 0.0) {
+ temp8len = scale_expansion_zeroelim(4, bb, -adxtail, temp8);
+ temp16alen = scale_expansion_zeroelim(temp8len, temp8, cdytail,
+ temp16a);
+ finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp16alen,
+ temp16a, finother);
+ finswap = finnow; finnow = finother; finother = finswap;
+ }
+
+ temp32alen = scale_expansion_zeroelim(axtbctlen, axtbct, adxtail,
+ temp32a);
+ axtbcttlen = scale_expansion_zeroelim(bcttlen, bctt, adxtail, axtbctt);
+ temp16alen = scale_expansion_zeroelim(axtbcttlen, axtbctt, 2.0 * adx,
+ temp16a);
+ temp16blen = scale_expansion_zeroelim(axtbcttlen, axtbctt, adxtail,
+ temp16b);
+ temp32blen = fast_expansion_sum_zeroelim(temp16alen, temp16a,
+ temp16blen, temp16b, temp32b);
+ temp64len = fast_expansion_sum_zeroelim(temp32alen, temp32a,
+ temp32blen, temp32b, temp64);
+ finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp64len,
+ temp64, finother);
+ finswap = finnow; finnow = finother; finother = finswap;
+ }
+ if (adytail != 0.0) {
+ temp16alen = scale_expansion_zeroelim(aytbclen, aytbc, adytail, temp16a);
+ aytbctlen = scale_expansion_zeroelim(bctlen, bct, adytail, aytbct);
+ temp32alen = scale_expansion_zeroelim(aytbctlen, aytbct, 2.0 * ady,
+ temp32a);
+ temp48len = fast_expansion_sum_zeroelim(temp16alen, temp16a,
+ temp32alen, temp32a, temp48);
+ finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp48len,
+ temp48, finother);
+ finswap = finnow; finnow = finother; finother = finswap;
+
+
+ temp32alen = scale_expansion_zeroelim(aytbctlen, aytbct, adytail,
+ temp32a);
+ aytbcttlen = scale_expansion_zeroelim(bcttlen, bctt, adytail, aytbctt);
+ temp16alen = scale_expansion_zeroelim(aytbcttlen, aytbctt, 2.0 * ady,
+ temp16a);
+ temp16blen = scale_expansion_zeroelim(aytbcttlen, aytbctt, adytail,
+ temp16b);
+ temp32blen = fast_expansion_sum_zeroelim(temp16alen, temp16a,
+ temp16blen, temp16b, temp32b);
+ temp64len = fast_expansion_sum_zeroelim(temp32alen, temp32a,
+ temp32blen, temp32b, temp64);
+ finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp64len,
+ temp64, finother);
+ finswap = finnow; finnow = finother; finother = finswap;
+ }
+ }
+ if ((bdxtail != 0.0) || (bdytail != 0.0)) {
+ if ((cdxtail != 0.0) || (cdytail != 0.0)
+ || (adxtail != 0.0) || (adytail != 0.0)) {
+ Two_Product(cdxtail, ady, ti1, ti0);
+ Two_Product(cdx, adytail, tj1, tj0);
+ Two_Two_Sum(ti1, ti0, tj1, tj0, u3, u[2], u[1], u[0]);
+ u[3] = u3;
+ negate = -cdy;
+ Two_Product(adxtail, negate, ti1, ti0);
+ negate = -cdytail;
+ Two_Product(adx, negate, tj1, tj0);
+ Two_Two_Sum(ti1, ti0, tj1, tj0, v3, v[2], v[1], v[0]);
+ v[3] = v3;
+ catlen = fast_expansion_sum_zeroelim(4, u, 4, v, cat);
+
+ Two_Product(cdxtail, adytail, ti1, ti0);
+ Two_Product(adxtail, cdytail, tj1, tj0);
+ Two_Two_Diff(ti1, ti0, tj1, tj0, catt3, catt[2], catt[1], catt[0]);
+ catt[3] = catt3;
+ cattlen = 4;
+ } else {
+ cat[0] = 0.0;
+ catlen = 1;
+ catt[0] = 0.0;
+ cattlen = 1;
+ }
+
+ if (bdxtail != 0.0) {
+ temp16alen = scale_expansion_zeroelim(bxtcalen, bxtca, bdxtail, temp16a);
+ bxtcatlen = scale_expansion_zeroelim(catlen, cat, bdxtail, bxtcat);
+ temp32alen = scale_expansion_zeroelim(bxtcatlen, bxtcat, 2.0 * bdx,
+ temp32a);
+ temp48len = fast_expansion_sum_zeroelim(temp16alen, temp16a,
+ temp32alen, temp32a, temp48);
+ finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp48len,
+ temp48, finother);
+ finswap = finnow; finnow = finother; finother = finswap;
+ if (cdytail != 0.0) {
+ temp8len = scale_expansion_zeroelim(4, aa, bdxtail, temp8);
+ temp16alen = scale_expansion_zeroelim(temp8len, temp8, cdytail,
+ temp16a);
+ finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp16alen,
+ temp16a, finother);
+ finswap = finnow; finnow = finother; finother = finswap;
+ }
+ if (adytail != 0.0) {
+ temp8len = scale_expansion_zeroelim(4, cc, -bdxtail, temp8);
+ temp16alen = scale_expansion_zeroelim(temp8len, temp8, adytail,
+ temp16a);
+ finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp16alen,
+ temp16a, finother);
+ finswap = finnow; finnow = finother; finother = finswap;
+ }
+
+ temp32alen = scale_expansion_zeroelim(bxtcatlen, bxtcat, bdxtail,
+ temp32a);
+ bxtcattlen = scale_expansion_zeroelim(cattlen, catt, bdxtail, bxtcatt);
+ temp16alen = scale_expansion_zeroelim(bxtcattlen, bxtcatt, 2.0 * bdx,
+ temp16a);
+ temp16blen = scale_expansion_zeroelim(bxtcattlen, bxtcatt, bdxtail,
+ temp16b);
+ temp32blen = fast_expansion_sum_zeroelim(temp16alen, temp16a,
+ temp16blen, temp16b, temp32b);
+ temp64len = fast_expansion_sum_zeroelim(temp32alen, temp32a,
+ temp32blen, temp32b, temp64);
+ finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp64len,
+ temp64, finother);
+ finswap = finnow; finnow = finother; finother = finswap;
+ }
+ if (bdytail != 0.0) {
+ temp16alen = scale_expansion_zeroelim(bytcalen, bytca, bdytail, temp16a);
+ bytcatlen = scale_expansion_zeroelim(catlen, cat, bdytail, bytcat);
+ temp32alen = scale_expansion_zeroelim(bytcatlen, bytcat, 2.0 * bdy,
+ temp32a);
+ temp48len = fast_expansion_sum_zeroelim(temp16alen, temp16a,
+ temp32alen, temp32a, temp48);
+ finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp48len,
+ temp48, finother);
+ finswap = finnow; finnow = finother; finother = finswap;
+
+
+ temp32alen = scale_expansion_zeroelim(bytcatlen, bytcat, bdytail,
+ temp32a);
+ bytcattlen = scale_expansion_zeroelim(cattlen, catt, bdytail, bytcatt);
+ temp16alen = scale_expansion_zeroelim(bytcattlen, bytcatt, 2.0 * bdy,
+ temp16a);
+ temp16blen = scale_expansion_zeroelim(bytcattlen, bytcatt, bdytail,
+ temp16b);
+ temp32blen = fast_expansion_sum_zeroelim(temp16alen, temp16a,
+ temp16blen, temp16b, temp32b);
+ temp64len = fast_expansion_sum_zeroelim(temp32alen, temp32a,
+ temp32blen, temp32b, temp64);
+ finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp64len,
+ temp64, finother);
+ finswap = finnow; finnow = finother; finother = finswap;
+ }
+ }
+ if ((cdxtail != 0.0) || (cdytail != 0.0)) {
+ if ((adxtail != 0.0) || (adytail != 0.0)
+ || (bdxtail != 0.0) || (bdytail != 0.0)) {
+ Two_Product(adxtail, bdy, ti1, ti0);
+ Two_Product(adx, bdytail, tj1, tj0);
+ Two_Two_Sum(ti1, ti0, tj1, tj0, u3, u[2], u[1], u[0]);
+ u[3] = u3;
+ negate = -ady;
+ Two_Product(bdxtail, negate, ti1, ti0);
+ negate = -adytail;
+ Two_Product(bdx, negate, tj1, tj0);
+ Two_Two_Sum(ti1, ti0, tj1, tj0, v3, v[2], v[1], v[0]);
+ v[3] = v3;
+ abtlen = fast_expansion_sum_zeroelim(4, u, 4, v, abt);
+
+ Two_Product(adxtail, bdytail, ti1, ti0);
+ Two_Product(bdxtail, adytail, tj1, tj0);
+ Two_Two_Diff(ti1, ti0, tj1, tj0, abtt3, abtt[2], abtt[1], abtt[0]);
+ abtt[3] = abtt3;
+ abttlen = 4;
+ } else {
+ abt[0] = 0.0;
+ abtlen = 1;
+ abtt[0] = 0.0;
+ abttlen = 1;
+ }
+
+ if (cdxtail != 0.0) {
+ temp16alen = scale_expansion_zeroelim(cxtablen, cxtab, cdxtail, temp16a);
+ cxtabtlen = scale_expansion_zeroelim(abtlen, abt, cdxtail, cxtabt);
+ temp32alen = scale_expansion_zeroelim(cxtabtlen, cxtabt, 2.0 * cdx,
+ temp32a);
+ temp48len = fast_expansion_sum_zeroelim(temp16alen, temp16a,
+ temp32alen, temp32a, temp48);
+ finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp48len,
+ temp48, finother);
+ finswap = finnow; finnow = finother; finother = finswap;
+ if (adytail != 0.0) {
+ temp8len = scale_expansion_zeroelim(4, bb, cdxtail, temp8);
+ temp16alen = scale_expansion_zeroelim(temp8len, temp8, adytail,
+ temp16a);
+ finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp16alen,
+ temp16a, finother);
+ finswap = finnow; finnow = finother; finother = finswap;
+ }
+ if (bdytail != 0.0) {
+ temp8len = scale_expansion_zeroelim(4, aa, -cdxtail, temp8);
+ temp16alen = scale_expansion_zeroelim(temp8len, temp8, bdytail,
+ temp16a);
+ finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp16alen,
+ temp16a, finother);
+ finswap = finnow; finnow = finother; finother = finswap;
+ }
+
+ temp32alen = scale_expansion_zeroelim(cxtabtlen, cxtabt, cdxtail,
+ temp32a);
+ cxtabttlen = scale_expansion_zeroelim(abttlen, abtt, cdxtail, cxtabtt);
+ temp16alen = scale_expansion_zeroelim(cxtabttlen, cxtabtt, 2.0 * cdx,
+ temp16a);
+ temp16blen = scale_expansion_zeroelim(cxtabttlen, cxtabtt, cdxtail,
+ temp16b);
+ temp32blen = fast_expansion_sum_zeroelim(temp16alen, temp16a,
+ temp16blen, temp16b, temp32b);
+ temp64len = fast_expansion_sum_zeroelim(temp32alen, temp32a,
+ temp32blen, temp32b, temp64);
+ finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp64len,
+ temp64, finother);
+ finswap = finnow; finnow = finother; finother = finswap;
+ }
+ if (cdytail != 0.0) {
+ temp16alen = scale_expansion_zeroelim(cytablen, cytab, cdytail, temp16a);
+ cytabtlen = scale_expansion_zeroelim(abtlen, abt, cdytail, cytabt);
+ temp32alen = scale_expansion_zeroelim(cytabtlen, cytabt, 2.0 * cdy,
+ temp32a);
+ temp48len = fast_expansion_sum_zeroelim(temp16alen, temp16a,
+ temp32alen, temp32a, temp48);
+ finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp48len,
+ temp48, finother);
+ finswap = finnow; finnow = finother; finother = finswap;
+
+
+ temp32alen = scale_expansion_zeroelim(cytabtlen, cytabt, cdytail,
+ temp32a);
+ cytabttlen = scale_expansion_zeroelim(abttlen, abtt, cdytail, cytabtt);
+ temp16alen = scale_expansion_zeroelim(cytabttlen, cytabtt, 2.0 * cdy,
+ temp16a);
+ temp16blen = scale_expansion_zeroelim(cytabttlen, cytabtt, cdytail,
+ temp16b);
+ temp32blen = fast_expansion_sum_zeroelim(temp16alen, temp16a,
+ temp16blen, temp16b, temp32b);
+ temp64len = fast_expansion_sum_zeroelim(temp32alen, temp32a,
+ temp32blen, temp32b, temp64);
+ finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp64len,
+ temp64, finother);
+ finswap = finnow; finnow = finother; finother = finswap;
+ }
+ }
+
+ return finnow[finlength - 1];
+}
+
+REAL incircle(REAL *pa, REAL *pb, REAL *pc, REAL *pd)
+{
+ REAL adx, bdx, cdx, ady, bdy, cdy;
+ REAL bdxcdy, cdxbdy, cdxady, adxcdy, adxbdy, bdxady;
+ REAL alift, blift, clift;
+ REAL det;
+ REAL permanent, errbound;
+ REAL inc;
+
+ FPU_ROUND_DOUBLE;
+
+ adx = pa[0] - pd[0];
+ bdx = pb[0] - pd[0];
+ cdx = pc[0] - pd[0];
+ ady = pa[1] - pd[1];
+ bdy = pb[1] - pd[1];
+ cdy = pc[1] - pd[1];
+
+ bdxcdy = bdx * cdy;
+ cdxbdy = cdx * bdy;
+ alift = adx * adx + ady * ady;
+
+ cdxady = cdx * ady;
+ adxcdy = adx * cdy;
+ blift = bdx * bdx + bdy * bdy;
+
+ adxbdy = adx * bdy;
+ bdxady = bdx * ady;
+ clift = cdx * cdx + cdy * cdy;
+
+ det = alift * (bdxcdy - cdxbdy)
+ + blift * (cdxady - adxcdy)
+ + clift * (adxbdy - bdxady);
+
+ permanent = (Absolute(bdxcdy) + Absolute(cdxbdy)) * alift
+ + (Absolute(cdxady) + Absolute(adxcdy)) * blift
+ + (Absolute(adxbdy) + Absolute(bdxady)) * clift;
+ errbound = iccerrboundA * permanent;
+ if ((det > errbound) || (-det > errbound)) {
+ FPU_RESTORE;
+ return det;
+ }
+
+ inc = incircleadapt(pa, pb, pc, pd, permanent);
+ FPU_RESTORE;
+ return inc;
+}
+
+REAL incircle(REAL ax, REAL ay, REAL bx, REAL by, REAL cx, REAL cy, REAL dx,
+ REAL dy)
+{
+ REAL adx, bdx, cdx, ady, bdy, cdy;
+ REAL bdxcdy, cdxbdy, cdxady, adxcdy, adxbdy, bdxady;
+ REAL alift, blift, clift;
+ REAL det;
+ REAL permanent, errbound;
+ REAL inc;
+
+ FPU_ROUND_DOUBLE;
+
+ adx = ax - dx;
+ bdx = bx - dx;
+ cdx = cx - dx;
+ ady = ay - dy;
+ bdy = by - dy;
+ cdy = cy - dy;
+
+ bdxcdy = bdx * cdy;
+ cdxbdy = cdx * bdy;
+ alift = adx * adx + ady * ady;
+
+ cdxady = cdx * ady;
+ adxcdy = adx * cdy;
+ blift = bdx * bdx + bdy * bdy;
+
+ adxbdy = adx * bdy;
+ bdxady = bdx * ady;
+ clift = cdx * cdx + cdy * cdy;
+
+ det = alift * (bdxcdy - cdxbdy)
+ + blift * (cdxady - adxcdy)
+ + clift * (adxbdy - bdxady);
+
+ permanent = (Absolute(bdxcdy) + Absolute(cdxbdy)) * alift
+ + (Absolute(cdxady) + Absolute(adxcdy)) * blift
+ + (Absolute(adxbdy) + Absolute(bdxady)) * clift;
+ errbound = iccerrboundA * permanent;
+ if ((det > errbound) || (-det > errbound)) {
+ FPU_RESTORE;
+ return det;
+ }
+
+ REAL pa[]={ax,ay};
+ REAL pb[]={bx,by};
+ REAL pc[]={cx,cy};
+ REAL pd[]={dx,dy};
+
+ inc = incircleadapt(pa, pb, pc, pd, permanent);
+ FPU_RESTORE;
+ return inc;
+}
+
+/*****************************************************************************/
+/* */
+/* inspherefast() Approximate 3D insphere test. Nonrobust. */
+/* insphereexact() Exact 3D insphere test. Robust. */
+/* insphereslow() Another exact 3D insphere test. Robust. */
+/* insphere() Adaptive exact 3D insphere test. Robust. */
+/* */
+/* Return a positive value if the point pe lies inside the */
+/* sphere passing through pa, pb, pc, and pd; a negative value */
+/* if it lies outside; and zero if the five points are */
+/* cospherical. The points pa, pb, pc, and pd must be ordered */
+/* so that they have a positive orientation (as defined by */
+/* orient3d()), or the sign of the result will be reversed. */
+/* */
+/* Only the first and last routine should be used; the middle two are for */
+/* timings. */
+/* */
+/* The last three use exact arithmetic to ensure a correct answer. The */
+/* result returned is the determinant of a matrix. In insphere() only, */
+/* this determinant is computed adaptively, in the sense that exact */
+/* arithmetic is used only to the degree it is needed to ensure that the */
+/* returned value has the correct sign. Hence, insphere() is usually quite */
+/* fast, but will run more slowly when the input points are cospherical or */
+/* nearly so. */
+/* */
+/*****************************************************************************/
+
+static REAL insphereexact(REAL *pa, REAL *pb, REAL *pc, REAL *pd, REAL *pe)
+{
+ INEXACT REAL axby1, bxcy1, cxdy1, dxey1, exay1;
+ INEXACT REAL bxay1, cxby1, dxcy1, exdy1, axey1;
+ INEXACT REAL axcy1, bxdy1, cxey1, dxay1, exby1;
+ INEXACT REAL cxay1, dxby1, excy1, axdy1, bxey1;
+ REAL axby0, bxcy0, cxdy0, dxey0, exay0;
+ REAL bxay0, cxby0, dxcy0, exdy0, axey0;
+ REAL axcy0, bxdy0, cxey0, dxay0, exby0;
+ REAL cxay0, dxby0, excy0, axdy0, bxey0;
+ REAL ab[4], bc[4], cd[4], de[4], ea[4];
+ REAL ac[4], bd[4], ce[4], da[4], eb[4];
+ REAL temp8a[8], temp8b[8], temp16[16];
+ int temp8alen, temp8blen, temp16len;
+ REAL abc[24], bcd[24], cde[24], dea[24], eab[24];
+ REAL abd[24], bce[24], cda[24], deb[24], eac[24];
+ int abclen, bcdlen, cdelen, dealen, eablen;
+ int abdlen, bcelen, cdalen, deblen, eaclen;
+ REAL temp48a[48], temp48b[48];
+ int temp48alen, temp48blen;
+ REAL abcd[96], bcde[96], cdea[96], deab[96], eabc[96];
+ int abcdlen, bcdelen, cdealen, deablen, eabclen;
+ REAL temp192[192];
+ REAL det384x[384], det384y[384], det384z[384];
+ int xlen, ylen, zlen;
+ REAL detxy[768];
+ int xylen;
+ REAL adet[1152], bdet[1152], cdet[1152], ddet[1152], edet[1152];
+ int alen, blen, clen, dlen, elen;
+ REAL abdet[2304], cddet[2304], cdedet[3456];
+ int ablen, cdlen;
+ REAL deter[5760];
+ int deterlen;
+ int i;
+
+ INEXACT REAL bvirt;
+ REAL avirt, bround, around;
+ INEXACT REAL c;
+ INEXACT REAL abig;
+ REAL ahi, alo, bhi, blo;
+ REAL err1, err2, err3;
+ INEXACT REAL _i, _j;
+ REAL _0;
+
+ Two_Product(pa[0], pb[1], axby1, axby0);
+ Two_Product(pb[0], pa[1], bxay1, bxay0);
+ Two_Two_Diff(axby1, axby0, bxay1, bxay0, ab[3], ab[2], ab[1], ab[0]);
+
+ Two_Product(pb[0], pc[1], bxcy1, bxcy0);
+ Two_Product(pc[0], pb[1], cxby1, cxby0);
+ Two_Two_Diff(bxcy1, bxcy0, cxby1, cxby0, bc[3], bc[2], bc[1], bc[0]);
+
+ Two_Product(pc[0], pd[1], cxdy1, cxdy0);
+ Two_Product(pd[0], pc[1], dxcy1, dxcy0);
+ Two_Two_Diff(cxdy1, cxdy0, dxcy1, dxcy0, cd[3], cd[2], cd[1], cd[0]);
+
+ Two_Product(pd[0], pe[1], dxey1, dxey0);
+ Two_Product(pe[0], pd[1], exdy1, exdy0);
+ Two_Two_Diff(dxey1, dxey0, exdy1, exdy0, de[3], de[2], de[1], de[0]);
+
+ Two_Product(pe[0], pa[1], exay1, exay0);
+ Two_Product(pa[0], pe[1], axey1, axey0);
+ Two_Two_Diff(exay1, exay0, axey1, axey0, ea[3], ea[2], ea[1], ea[0]);
+
+ Two_Product(pa[0], pc[1], axcy1, axcy0);
+ Two_Product(pc[0], pa[1], cxay1, cxay0);
+ Two_Two_Diff(axcy1, axcy0, cxay1, cxay0, ac[3], ac[2], ac[1], ac[0]);
+
+ Two_Product(pb[0], pd[1], bxdy1, bxdy0);
+ Two_Product(pd[0], pb[1], dxby1, dxby0);
+ Two_Two_Diff(bxdy1, bxdy0, dxby1, dxby0, bd[3], bd[2], bd[1], bd[0]);
+
+ Two_Product(pc[0], pe[1], cxey1, cxey0);
+ Two_Product(pe[0], pc[1], excy1, excy0);
+ Two_Two_Diff(cxey1, cxey0, excy1, excy0, ce[3], ce[2], ce[1], ce[0]);
+
+ Two_Product(pd[0], pa[1], dxay1, dxay0);
+ Two_Product(pa[0], pd[1], axdy1, axdy0);
+ Two_Two_Diff(dxay1, dxay0, axdy1, axdy0, da[3], da[2], da[1], da[0]);
+
+ Two_Product(pe[0], pb[1], exby1, exby0);
+ Two_Product(pb[0], pe[1], bxey1, bxey0);
+ Two_Two_Diff(exby1, exby0, bxey1, bxey0, eb[3], eb[2], eb[1], eb[0]);
+
+ temp8alen = scale_expansion_zeroelim(4, bc, pa[2], temp8a);
+ temp8blen = scale_expansion_zeroelim(4, ac, -pb[2], temp8b);
+ temp16len = fast_expansion_sum_zeroelim(temp8alen, temp8a, temp8blen, temp8b,
+ temp16);
+ temp8alen = scale_expansion_zeroelim(4, ab, pc[2], temp8a);
+ abclen = fast_expansion_sum_zeroelim(temp8alen, temp8a, temp16len, temp16,
+ abc);
+
+ temp8alen = scale_expansion_zeroelim(4, cd, pb[2], temp8a);
+ temp8blen = scale_expansion_zeroelim(4, bd, -pc[2], temp8b);
+ temp16len = fast_expansion_sum_zeroelim(temp8alen, temp8a, temp8blen, temp8b,
+ temp16);
+ temp8alen = scale_expansion_zeroelim(4, bc, pd[2], temp8a);
+ bcdlen = fast_expansion_sum_zeroelim(temp8alen, temp8a, temp16len, temp16,
+ bcd);
+
+ temp8alen = scale_expansion_zeroelim(4, de, pc[2], temp8a);
+ temp8blen = scale_expansion_zeroelim(4, ce, -pd[2], temp8b);
+ temp16len = fast_expansion_sum_zeroelim(temp8alen, temp8a, temp8blen, temp8b,
+ temp16);
+ temp8alen = scale_expansion_zeroelim(4, cd, pe[2], temp8a);
+ cdelen = fast_expansion_sum_zeroelim(temp8alen, temp8a, temp16len, temp16,
+ cde);
+
+ temp8alen = scale_expansion_zeroelim(4, ea, pd[2], temp8a);
+ temp8blen = scale_expansion_zeroelim(4, da, -pe[2], temp8b);
+ temp16len = fast_expansion_sum_zeroelim(temp8alen, temp8a, temp8blen, temp8b,
+ temp16);
+ temp8alen = scale_expansion_zeroelim(4, de, pa[2], temp8a);
+ dealen = fast_expansion_sum_zeroelim(temp8alen, temp8a, temp16len, temp16,
+ dea);
+
+ temp8alen = scale_expansion_zeroelim(4, ab, pe[2], temp8a);
+ temp8blen = scale_expansion_zeroelim(4, eb, -pa[2], temp8b);
+ temp16len = fast_expansion_sum_zeroelim(temp8alen, temp8a, temp8blen, temp8b,
+ temp16);
+ temp8alen = scale_expansion_zeroelim(4, ea, pb[2], temp8a);
+ eablen = fast_expansion_sum_zeroelim(temp8alen, temp8a, temp16len, temp16,
+ eab);
+
+ temp8alen = scale_expansion_zeroelim(4, bd, pa[2], temp8a);
+ temp8blen = scale_expansion_zeroelim(4, da, pb[2], temp8b);
+ temp16len = fast_expansion_sum_zeroelim(temp8alen, temp8a, temp8blen, temp8b,
+ temp16);
+ temp8alen = scale_expansion_zeroelim(4, ab, pd[2], temp8a);
+ abdlen = fast_expansion_sum_zeroelim(temp8alen, temp8a, temp16len, temp16,
+ abd);
+
+ temp8alen = scale_expansion_zeroelim(4, ce, pb[2], temp8a);
+ temp8blen = scale_expansion_zeroelim(4, eb, pc[2], temp8b);
+ temp16len = fast_expansion_sum_zeroelim(temp8alen, temp8a, temp8blen, temp8b,
+ temp16);
+ temp8alen = scale_expansion_zeroelim(4, bc, pe[2], temp8a);
+ bcelen = fast_expansion_sum_zeroelim(temp8alen, temp8a, temp16len, temp16,
+ bce);
+
+ temp8alen = scale_expansion_zeroelim(4, da, pc[2], temp8a);
+ temp8blen = scale_expansion_zeroelim(4, ac, pd[2], temp8b);
+ temp16len = fast_expansion_sum_zeroelim(temp8alen, temp8a, temp8blen, temp8b,
+ temp16);
+ temp8alen = scale_expansion_zeroelim(4, cd, pa[2], temp8a);
+ cdalen = fast_expansion_sum_zeroelim(temp8alen, temp8a, temp16len, temp16,
+ cda);
+
+ temp8alen = scale_expansion_zeroelim(4, eb, pd[2], temp8a);
+ temp8blen = scale_expansion_zeroelim(4, bd, pe[2], temp8b);
+ temp16len = fast_expansion_sum_zeroelim(temp8alen, temp8a, temp8blen, temp8b,
+ temp16);
+ temp8alen = scale_expansion_zeroelim(4, de, pb[2], temp8a);
+ deblen = fast_expansion_sum_zeroelim(temp8alen, temp8a, temp16len, temp16,
+ deb);
+
+ temp8alen = scale_expansion_zeroelim(4, ac, pe[2], temp8a);
+ temp8blen = scale_expansion_zeroelim(4, ce, pa[2], temp8b);
+ temp16len = fast_expansion_sum_zeroelim(temp8alen, temp8a, temp8blen, temp8b,
+ temp16);
+ temp8alen = scale_expansion_zeroelim(4, ea, pc[2], temp8a);
+ eaclen = fast_expansion_sum_zeroelim(temp8alen, temp8a, temp16len, temp16,
+ eac);
+
+ temp48alen = fast_expansion_sum_zeroelim(cdelen, cde, bcelen, bce, temp48a);
+ temp48blen = fast_expansion_sum_zeroelim(deblen, deb, bcdlen, bcd, temp48b);
+ for (i = 0; i < temp48blen; i++) {
+ temp48b[i] = -temp48b[i];
+ }
+ bcdelen = fast_expansion_sum_zeroelim(temp48alen, temp48a,
+ temp48blen, temp48b, bcde);
+ xlen = scale_expansion_zeroelim(bcdelen, bcde, pa[0], temp192);
+ xlen = scale_expansion_zeroelim(xlen, temp192, pa[0], det384x);
+ ylen = scale_expansion_zeroelim(bcdelen, bcde, pa[1], temp192);
+ ylen = scale_expansion_zeroelim(ylen, temp192, pa[1], det384y);
+ zlen = scale_expansion_zeroelim(bcdelen, bcde, pa[2], temp192);
+ zlen = scale_expansion_zeroelim(zlen, temp192, pa[2], det384z);
+ xylen = fast_expansion_sum_zeroelim(xlen, det384x, ylen, det384y, detxy);
+ alen = fast_expansion_sum_zeroelim(xylen, detxy, zlen, det384z, adet);
+
+ temp48alen = fast_expansion_sum_zeroelim(dealen, dea, cdalen, cda, temp48a);
+ temp48blen = fast_expansion_sum_zeroelim(eaclen, eac, cdelen, cde, temp48b);
+ for (i = 0; i < temp48blen; i++) {
+ temp48b[i] = -temp48b[i];
+ }
+ cdealen = fast_expansion_sum_zeroelim(temp48alen, temp48a,
+ temp48blen, temp48b, cdea);
+ xlen = scale_expansion_zeroelim(cdealen, cdea, pb[0], temp192);
+ xlen = scale_expansion_zeroelim(xlen, temp192, pb[0], det384x);
+ ylen = scale_expansion_zeroelim(cdealen, cdea, pb[1], temp192);
+ ylen = scale_expansion_zeroelim(ylen, temp192, pb[1], det384y);
+ zlen = scale_expansion_zeroelim(cdealen, cdea, pb[2], temp192);
+ zlen = scale_expansion_zeroelim(zlen, temp192, pb[2], det384z);
+ xylen = fast_expansion_sum_zeroelim(xlen, det384x, ylen, det384y, detxy);
+ blen = fast_expansion_sum_zeroelim(xylen, detxy, zlen, det384z, bdet);
+
+ temp48alen = fast_expansion_sum_zeroelim(eablen, eab, deblen, deb, temp48a);
+ temp48blen = fast_expansion_sum_zeroelim(abdlen, abd, dealen, dea, temp48b);
+ for (i = 0; i < temp48blen; i++) {
+ temp48b[i] = -temp48b[i];
+ }
+ deablen = fast_expansion_sum_zeroelim(temp48alen, temp48a,
+ temp48blen, temp48b, deab);
+ xlen = scale_expansion_zeroelim(deablen, deab, pc[0], temp192);
+ xlen = scale_expansion_zeroelim(xlen, temp192, pc[0], det384x);
+ ylen = scale_expansion_zeroelim(deablen, deab, pc[1], temp192);
+ ylen = scale_expansion_zeroelim(ylen, temp192, pc[1], det384y);
+ zlen = scale_expansion_zeroelim(deablen, deab, pc[2], temp192);
+ zlen = scale_expansion_zeroelim(zlen, temp192, pc[2], det384z);
+ xylen = fast_expansion_sum_zeroelim(xlen, det384x, ylen, det384y, detxy);
+ clen = fast_expansion_sum_zeroelim(xylen, detxy, zlen, det384z, cdet);
+
+ temp48alen = fast_expansion_sum_zeroelim(abclen, abc, eaclen, eac, temp48a);
+ temp48blen = fast_expansion_sum_zeroelim(bcelen, bce, eablen, eab, temp48b);
+ for (i = 0; i < temp48blen; i++) {
+ temp48b[i] = -temp48b[i];
+ }
+ eabclen = fast_expansion_sum_zeroelim(temp48alen, temp48a,
+ temp48blen, temp48b, eabc);
+ xlen = scale_expansion_zeroelim(eabclen, eabc, pd[0], temp192);
+ xlen = scale_expansion_zeroelim(xlen, temp192, pd[0], det384x);
+ ylen = scale_expansion_zeroelim(eabclen, eabc, pd[1], temp192);
+ ylen = scale_expansion_zeroelim(ylen, temp192, pd[1], det384y);
+ zlen = scale_expansion_zeroelim(eabclen, eabc, pd[2], temp192);
+ zlen = scale_expansion_zeroelim(zlen, temp192, pd[2], det384z);
+ xylen = fast_expansion_sum_zeroelim(xlen, det384x, ylen, det384y, detxy);
+ dlen = fast_expansion_sum_zeroelim(xylen, detxy, zlen, det384z, ddet);
+
+ temp48alen = fast_expansion_sum_zeroelim(bcdlen, bcd, abdlen, abd, temp48a);
+ temp48blen = fast_expansion_sum_zeroelim(cdalen, cda, abclen, abc, temp48b);
+ for (i = 0; i < temp48blen; i++) {
+ temp48b[i] = -temp48b[i];
+ }
+ abcdlen = fast_expansion_sum_zeroelim(temp48alen, temp48a,
+ temp48blen, temp48b, abcd);
+ xlen = scale_expansion_zeroelim(abcdlen, abcd, pe[0], temp192);
+ xlen = scale_expansion_zeroelim(xlen, temp192, pe[0], det384x);
+ ylen = scale_expansion_zeroelim(abcdlen, abcd, pe[1], temp192);
+ ylen = scale_expansion_zeroelim(ylen, temp192, pe[1], det384y);
+ zlen = scale_expansion_zeroelim(abcdlen, abcd, pe[2], temp192);
+ zlen = scale_expansion_zeroelim(zlen, temp192, pe[2], det384z);
+ xylen = fast_expansion_sum_zeroelim(xlen, det384x, ylen, det384y, detxy);
+ elen = fast_expansion_sum_zeroelim(xylen, detxy, zlen, det384z, edet);
+
+ ablen = fast_expansion_sum_zeroelim(alen, adet, blen, bdet, abdet);
+ cdlen = fast_expansion_sum_zeroelim(clen, cdet, dlen, ddet, cddet);
+ cdelen = fast_expansion_sum_zeroelim(cdlen, cddet, elen, edet, cdedet);
+ deterlen = fast_expansion_sum_zeroelim(ablen, abdet, cdelen, cdedet, deter);
+
+ return deter[deterlen - 1];
+}
+
+static REAL insphereadapt(REAL *pa, REAL *pb, REAL *pc, REAL *pd, REAL *pe,
+ REAL permanent)
+{
+ INEXACT REAL aex, bex, cex, dex, aey, bey, cey, dey, aez, bez, cez, dez;
+ REAL det, errbound;
+
+ INEXACT REAL aexbey1, bexaey1, bexcey1, cexbey1;
+ INEXACT REAL cexdey1, dexcey1, dexaey1, aexdey1;
+ INEXACT REAL aexcey1, cexaey1, bexdey1, dexbey1;
+ REAL aexbey0, bexaey0, bexcey0, cexbey0;
+ REAL cexdey0, dexcey0, dexaey0, aexdey0;
+ REAL aexcey0, cexaey0, bexdey0, dexbey0;
+ REAL ab[4], bc[4], cd[4], da[4], ac[4], bd[4];
+ INEXACT REAL ab3, bc3, cd3, da3, ac3, bd3;
+ REAL abeps, bceps, cdeps, daeps, aceps, bdeps;
+ REAL temp8a[8], temp8b[8], temp8c[8], temp16[16], temp24[24], temp48[48];
+ int temp8alen, temp8blen, temp8clen, temp16len, temp24len, temp48len;
+ REAL xdet[96], ydet[96], zdet[96], xydet[192];
+ int xlen, ylen, zlen, xylen;
+ REAL adet[288], bdet[288], cdet[288], ddet[288];
+ int alen, blen, clen, dlen;
+ REAL abdet[576], cddet[576];
+ int ablen, cdlen;
+ REAL fin1[1152];
+ int finlength;
+
+ REAL aextail, bextail, cextail, dextail;
+ REAL aeytail, beytail, ceytail, deytail;
+ REAL aeztail, beztail, ceztail, deztail;
+
+ INEXACT REAL bvirt;
+ REAL avirt, bround, around;
+ INEXACT REAL c;
+ INEXACT REAL abig;
+ REAL ahi, alo, bhi, blo;
+ REAL err1, err2, err3;
+ INEXACT REAL _i, _j;
+ REAL _0;
+
+ aex = (REAL) (pa[0] - pe[0]);
+ bex = (REAL) (pb[0] - pe[0]);
+ cex = (REAL) (pc[0] - pe[0]);
+ dex = (REAL) (pd[0] - pe[0]);
+ aey = (REAL) (pa[1] - pe[1]);
+ bey = (REAL) (pb[1] - pe[1]);
+ cey = (REAL) (pc[1] - pe[1]);
+ dey = (REAL) (pd[1] - pe[1]);
+ aez = (REAL) (pa[2] - pe[2]);
+ bez = (REAL) (pb[2] - pe[2]);
+ cez = (REAL) (pc[2] - pe[2]);
+ dez = (REAL) (pd[2] - pe[2]);
+
+ Two_Product(aex, bey, aexbey1, aexbey0);
+ Two_Product(bex, aey, bexaey1, bexaey0);
+ Two_Two_Diff(aexbey1, aexbey0, bexaey1, bexaey0, ab3, ab[2], ab[1], ab[0]);
+ ab[3] = ab3;
+
+ Two_Product(bex, cey, bexcey1, bexcey0);
+ Two_Product(cex, bey, cexbey1, cexbey0);
+ Two_Two_Diff(bexcey1, bexcey0, cexbey1, cexbey0, bc3, bc[2], bc[1], bc[0]);
+ bc[3] = bc3;
+
+ Two_Product(cex, dey, cexdey1, cexdey0);
+ Two_Product(dex, cey, dexcey1, dexcey0);
+ Two_Two_Diff(cexdey1, cexdey0, dexcey1, dexcey0, cd3, cd[2], cd[1], cd[0]);
+ cd[3] = cd3;
+
+ Two_Product(dex, aey, dexaey1, dexaey0);
+ Two_Product(aex, dey, aexdey1, aexdey0);
+ Two_Two_Diff(dexaey1, dexaey0, aexdey1, aexdey0, da3, da[2], da[1], da[0]);
+ da[3] = da3;
+
+ Two_Product(aex, cey, aexcey1, aexcey0);
+ Two_Product(cex, aey, cexaey1, cexaey0);
+ Two_Two_Diff(aexcey1, aexcey0, cexaey1, cexaey0, ac3, ac[2], ac[1], ac[0]);
+ ac[3] = ac3;
+
+ Two_Product(bex, dey, bexdey1, bexdey0);
+ Two_Product(dex, bey, dexbey1, dexbey0);
+ Two_Two_Diff(bexdey1, bexdey0, dexbey1, dexbey0, bd3, bd[2], bd[1], bd[0]);
+ bd[3] = bd3;
+
+ temp8alen = scale_expansion_zeroelim(4, cd, bez, temp8a);
+ temp8blen = scale_expansion_zeroelim(4, bd, -cez, temp8b);
+ temp8clen = scale_expansion_zeroelim(4, bc, dez, temp8c);
+ temp16len = fast_expansion_sum_zeroelim(temp8alen, temp8a,
+ temp8blen, temp8b, temp16);
+ temp24len = fast_expansion_sum_zeroelim(temp8clen, temp8c,
+ temp16len, temp16, temp24);
+ temp48len = scale_expansion_zeroelim(temp24len, temp24, aex, temp48);
+ xlen = scale_expansion_zeroelim(temp48len, temp48, -aex, xdet);
+ temp48len = scale_expansion_zeroelim(temp24len, temp24, aey, temp48);
+ ylen = scale_expansion_zeroelim(temp48len, temp48, -aey, ydet);
+ temp48len = scale_expansion_zeroelim(temp24len, temp24, aez, temp48);
+ zlen = scale_expansion_zeroelim(temp48len, temp48, -aez, zdet);
+ xylen = fast_expansion_sum_zeroelim(xlen, xdet, ylen, ydet, xydet);
+ alen = fast_expansion_sum_zeroelim(xylen, xydet, zlen, zdet, adet);
+
+ temp8alen = scale_expansion_zeroelim(4, da, cez, temp8a);
+ temp8blen = scale_expansion_zeroelim(4, ac, dez, temp8b);
+ temp8clen = scale_expansion_zeroelim(4, cd, aez, temp8c);
+ temp16len = fast_expansion_sum_zeroelim(temp8alen, temp8a,
+ temp8blen, temp8b, temp16);
+ temp24len = fast_expansion_sum_zeroelim(temp8clen, temp8c,
+ temp16len, temp16, temp24);
+ temp48len = scale_expansion_zeroelim(temp24len, temp24, bex, temp48);
+ xlen = scale_expansion_zeroelim(temp48len, temp48, bex, xdet);
+ temp48len = scale_expansion_zeroelim(temp24len, temp24, bey, temp48);
+ ylen = scale_expansion_zeroelim(temp48len, temp48, bey, ydet);
+ temp48len = scale_expansion_zeroelim(temp24len, temp24, bez, temp48);
+ zlen = scale_expansion_zeroelim(temp48len, temp48, bez, zdet);
+ xylen = fast_expansion_sum_zeroelim(xlen, xdet, ylen, ydet, xydet);
+ blen = fast_expansion_sum_zeroelim(xylen, xydet, zlen, zdet, bdet);
+
+ temp8alen = scale_expansion_zeroelim(4, ab, dez, temp8a);
+ temp8blen = scale_expansion_zeroelim(4, bd, aez, temp8b);
+ temp8clen = scale_expansion_zeroelim(4, da, bez, temp8c);
+ temp16len = fast_expansion_sum_zeroelim(temp8alen, temp8a,
+ temp8blen, temp8b, temp16);
+ temp24len = fast_expansion_sum_zeroelim(temp8clen, temp8c,
+ temp16len, temp16, temp24);
+ temp48len = scale_expansion_zeroelim(temp24len, temp24, cex, temp48);
+ xlen = scale_expansion_zeroelim(temp48len, temp48, -cex, xdet);
+ temp48len = scale_expansion_zeroelim(temp24len, temp24, cey, temp48);
+ ylen = scale_expansion_zeroelim(temp48len, temp48, -cey, ydet);
+ temp48len = scale_expansion_zeroelim(temp24len, temp24, cez, temp48);
+ zlen = scale_expansion_zeroelim(temp48len, temp48, -cez, zdet);
+ xylen = fast_expansion_sum_zeroelim(xlen, xdet, ylen, ydet, xydet);
+ clen = fast_expansion_sum_zeroelim(xylen, xydet, zlen, zdet, cdet);
+
+ temp8alen = scale_expansion_zeroelim(4, bc, aez, temp8a);
+ temp8blen = scale_expansion_zeroelim(4, ac, -bez, temp8b);
+ temp8clen = scale_expansion_zeroelim(4, ab, cez, temp8c);
+ temp16len = fast_expansion_sum_zeroelim(temp8alen, temp8a,
+ temp8blen, temp8b, temp16);
+ temp24len = fast_expansion_sum_zeroelim(temp8clen, temp8c,
+ temp16len, temp16, temp24);
+ temp48len = scale_expansion_zeroelim(temp24len, temp24, dex, temp48);
+ xlen = scale_expansion_zeroelim(temp48len, temp48, dex, xdet);
+ temp48len = scale_expansion_zeroelim(temp24len, temp24, dey, temp48);
+ ylen = scale_expansion_zeroelim(temp48len, temp48, dey, ydet);
+ temp48len = scale_expansion_zeroelim(temp24len, temp24, dez, temp48);
+ zlen = scale_expansion_zeroelim(temp48len, temp48, dez, zdet);
+ xylen = fast_expansion_sum_zeroelim(xlen, xdet, ylen, ydet, xydet);
+ dlen = fast_expansion_sum_zeroelim(xylen, xydet, zlen, zdet, ddet);
+
+ ablen = fast_expansion_sum_zeroelim(alen, adet, blen, bdet, abdet);
+ cdlen = fast_expansion_sum_zeroelim(clen, cdet, dlen, ddet, cddet);
+ finlength = fast_expansion_sum_zeroelim(ablen, abdet, cdlen, cddet, fin1);
+
+ det = estimate(finlength, fin1);
+ errbound = isperrboundB * permanent;
+ if ((det >= errbound) || (-det >= errbound)) {
+ return det;
+ }
+
+ Two_Diff_Tail(pa[0], pe[0], aex, aextail);
+ Two_Diff_Tail(pa[1], pe[1], aey, aeytail);
+ Two_Diff_Tail(pa[2], pe[2], aez, aeztail);
+ Two_Diff_Tail(pb[0], pe[0], bex, bextail);
+ Two_Diff_Tail(pb[1], pe[1], bey, beytail);
+ Two_Diff_Tail(pb[2], pe[2], bez, beztail);
+ Two_Diff_Tail(pc[0], pe[0], cex, cextail);
+ Two_Diff_Tail(pc[1], pe[1], cey, ceytail);
+ Two_Diff_Tail(pc[2], pe[2], cez, ceztail);
+ Two_Diff_Tail(pd[0], pe[0], dex, dextail);
+ Two_Diff_Tail(pd[1], pe[1], dey, deytail);
+ Two_Diff_Tail(pd[2], pe[2], dez, deztail);
+ if ((aextail == 0.0) && (aeytail == 0.0) && (aeztail == 0.0)
+ && (bextail == 0.0) && (beytail == 0.0) && (beztail == 0.0)
+ && (cextail == 0.0) && (ceytail == 0.0) && (ceztail == 0.0)
+ && (dextail == 0.0) && (deytail == 0.0) && (deztail == 0.0)) {
+ return det;
+ }
+
+ errbound = isperrboundC * permanent + resulterrbound * Absolute(det);
+ abeps = (aex * beytail + bey * aextail)
+ - (aey * bextail + bex * aeytail);
+ bceps = (bex * ceytail + cey * bextail)
+ - (bey * cextail + cex * beytail);
+ cdeps = (cex * deytail + dey * cextail)
+ - (cey * dextail + dex * ceytail);
+ daeps = (dex * aeytail + aey * dextail)
+ - (dey * aextail + aex * deytail);
+ aceps = (aex * ceytail + cey * aextail)
+ - (aey * cextail + cex * aeytail);
+ bdeps = (bex * deytail + dey * bextail)
+ - (bey * dextail + dex * beytail);
+ det += (((bex * bex + bey * bey + bez * bez)
+ * ((cez * daeps + dez * aceps + aez * cdeps)
+ + (ceztail * da3 + deztail * ac3 + aeztail * cd3))
+ + (dex * dex + dey * dey + dez * dez)
+ * ((aez * bceps - bez * aceps + cez * abeps)
+ + (aeztail * bc3 - beztail * ac3 + ceztail * ab3)))
+ - ((aex * aex + aey * aey + aez * aez)
+ * ((bez * cdeps - cez * bdeps + dez * bceps)
+ + (beztail * cd3 - ceztail * bd3 + deztail * bc3))
+ + (cex * cex + cey * cey + cez * cez)
+ * ((dez * abeps + aez * bdeps + bez * daeps)
+ + (deztail * ab3 + aeztail * bd3 + beztail * da3))))
+ + 2.0 * (((bex * bextail + bey * beytail + bez * beztail)
+ * (cez * da3 + dez * ac3 + aez * cd3)
+ + (dex * dextail + dey * deytail + dez * deztail)
+ * (aez * bc3 - bez * ac3 + cez * ab3))
+ - ((aex * aextail + aey * aeytail + aez * aeztail)
+ * (bez * cd3 - cez * bd3 + dez * bc3)
+ + (cex * cextail + cey * ceytail + cez * ceztail)
+ * (dez * ab3 + aez * bd3 + bez * da3)));
+ if ((det >= errbound) || (-det >= errbound)) {
+ return det;
+ }
+
+ return insphereexact(pa, pb, pc, pd, pe);
+}
+
+REAL insphere(REAL *pa, REAL *pb, REAL *pc, REAL *pd, REAL *pe)
+{
+ REAL aex, bex, cex, dex;
+ REAL aey, bey, cey, dey;
+ REAL aez, bez, cez, dez;
+ REAL aexbey, bexaey, bexcey, cexbey, cexdey, dexcey, dexaey, aexdey;
+ REAL aexcey, cexaey, bexdey, dexbey;
+ REAL alift, blift, clift, dlift;
+ REAL ab, bc, cd, da, ac, bd;
+ REAL abc, bcd, cda, dab;
+ REAL aezplus, bezplus, cezplus, dezplus;
+ REAL aexbeyplus, bexaeyplus, bexceyplus, cexbeyplus;
+ REAL cexdeyplus, dexceyplus, dexaeyplus, aexdeyplus;
+ REAL aexceyplus, cexaeyplus, bexdeyplus, dexbeyplus;
+ REAL det;
+ REAL permanent, errbound;
+ REAL ins;
+
+ FPU_ROUND_DOUBLE;
+
+ aex = pa[0] - pe[0];
+ bex = pb[0] - pe[0];
+ cex = pc[0] - pe[0];
+ dex = pd[0] - pe[0];
+ aey = pa[1] - pe[1];
+ bey = pb[1] - pe[1];
+ cey = pc[1] - pe[1];
+ dey = pd[1] - pe[1];
+ aez = pa[2] - pe[2];
+ bez = pb[2] - pe[2];
+ cez = pc[2] - pe[2];
+ dez = pd[2] - pe[2];
+
+ aexbey = aex * bey;
+ bexaey = bex * aey;
+ ab = aexbey - bexaey;
+ bexcey = bex * cey;
+ cexbey = cex * bey;
+ bc = bexcey - cexbey;
+ cexdey = cex * dey;
+ dexcey = dex * cey;
+ cd = cexdey - dexcey;
+ dexaey = dex * aey;
+ aexdey = aex * dey;
+ da = dexaey - aexdey;
+
+ aexcey = aex * cey;
+ cexaey = cex * aey;
+ ac = aexcey - cexaey;
+ bexdey = bex * dey;
+ dexbey = dex * bey;
+ bd = bexdey - dexbey;
+
+ abc = aez * bc - bez * ac + cez * ab;
+ bcd = bez * cd - cez * bd + dez * bc;
+ cda = cez * da + dez * ac + aez * cd;
+ dab = dez * ab + aez * bd + bez * da;
+
+ alift = aex * aex + aey * aey + aez * aez;
+ blift = bex * bex + bey * bey + bez * bez;
+ clift = cex * cex + cey * cey + cez * cez;
+ dlift = dex * dex + dey * dey + dez * dez;
+
+ det = (dlift * abc - clift * dab) + (blift * cda - alift * bcd);
+
+ aezplus = Absolute(aez);
+ bezplus = Absolute(bez);
+ cezplus = Absolute(cez);
+ dezplus = Absolute(dez);
+ aexbeyplus = Absolute(aexbey);
+ bexaeyplus = Absolute(bexaey);
+ bexceyplus = Absolute(bexcey);
+ cexbeyplus = Absolute(cexbey);
+ cexdeyplus = Absolute(cexdey);
+ dexceyplus = Absolute(dexcey);
+ dexaeyplus = Absolute(dexaey);
+ aexdeyplus = Absolute(aexdey);
+ aexceyplus = Absolute(aexcey);
+ cexaeyplus = Absolute(cexaey);
+ bexdeyplus = Absolute(bexdey);
+ dexbeyplus = Absolute(dexbey);
+ permanent = ((cexdeyplus + dexceyplus) * bezplus
+ + (dexbeyplus + bexdeyplus) * cezplus
+ + (bexceyplus + cexbeyplus) * dezplus)
+ * alift
+ + ((dexaeyplus + aexdeyplus) * cezplus
+ + (aexceyplus + cexaeyplus) * dezplus
+ + (cexdeyplus + dexceyplus) * aezplus)
+ * blift
+ + ((aexbeyplus + bexaeyplus) * dezplus
+ + (bexdeyplus + dexbeyplus) * aezplus
+ + (dexaeyplus + aexdeyplus) * bezplus)
+ * clift
+ + ((bexceyplus + cexbeyplus) * aezplus
+ + (cexaeyplus + aexceyplus) * bezplus
+ + (aexbeyplus + bexaeyplus) * cezplus)
+ * dlift;
+ errbound = isperrboundA * permanent;
+ if ((det > errbound) || (-det > errbound)) {
+ FPU_RESTORE;
+ return det;
+ }
+
+ ins = insphereadapt(pa, pb, pc, pd, pe, permanent);
+ FPU_RESTORE;
+ return ins;
+}
diff --git a/Build/source/utils/asymptote/predicates.h b/Build/source/utils/asymptote/predicates.h
new file mode 100644
index 00000000000..b13edf17799
--- /dev/null
+++ b/Build/source/utils/asymptote/predicates.h
@@ -0,0 +1,18 @@
+#ifndef PREDICATES_H
+#define PREDICATES_H
+
+double orient2d(double* pa, double* pb, double* pc);
+double orient2d(double ax, double ay, double bx, double by, double cx,
+ double cy);
+double orient2dadapt(double *pa, double *pb, double *pc, double detsum);
+double orient3d(double* pa, double* pb, double* pc, double* pd);
+double incircle(double* pa, double* pb, double* pc, double* pd);
+double incircle(double ax, double ay, double bx, double by, double cx,
+ double cy, double dx, double dy);
+double insphere(double* pa, double* pb, double* pc, double* pd, double* pe);
+
+extern const double resulterrbound,ccwerrboundA,ccwerrboundB,ccwerrboundC,
+ o3derrboundA,o3derrboundB,o3derrboundC,iccerrboundA,iccerrboundB,
+ iccerrboundC,isperrboundA,isperrboundB,isperrboundC;
+
+#endif
diff --git a/Build/source/utils/asymptote/primitives.h b/Build/source/utils/asymptote/primitives.h
new file mode 100644
index 00000000000..52b3ebcefa4
--- /dev/null
+++ b/Build/source/utils/asymptote/primitives.h
@@ -0,0 +1,40 @@
+/*****
+ * primitives.h
+ * Andy Hammerlindl 2007/04/27
+ *
+ * A list of the primative types in Asymptote, defined using the
+ * PRIMITIVE(name,Name,asyName) macro. This macro should be defined in by the
+ * code including this file for the context at hand.
+ *
+ * name - the name of the type in C++ code ex: boolean
+ * Name - the same name capitalized ex: Boolean
+ * asyName - the name in Asymptote code ex: bool
+ *
+ *****/
+
+// No ifndef because this file may be included multiple times in different
+// contexts.
+
+PRIMITIVE(void,Void,void)
+/* null is not a primitive type. */
+#ifdef PRIMERROR
+PRIMITIVE(error,Error,<error>)
+#endif
+
+PRIMITIVE(boolean,Boolean,bool)
+PRIMITIVE(Int,Int,int)
+PRIMITIVE(real,Real,real)
+PRIMITIVE(string,String,string)
+PRIMITIVE(pair,Pair,pair)
+PRIMITIVE(triple,Triple,triple)
+PRIMITIVE(transform,Transform,transform)
+PRIMITIVE(guide,Guide,guide)
+PRIMITIVE(path,Path,path)
+PRIMITIVE(path3,Path3,path3)
+PRIMITIVE(cycleToken,CycleToken,cycleToken)
+PRIMITIVE(tensionSpecifier,TensionSpecifier,tensionSpecifier)
+PRIMITIVE(curlSpecifier,CurlSpecifier,curlSpecifier)
+PRIMITIVE(pen,Pen,pen)
+PRIMITIVE(picture,Picture,frame)
+PRIMITIVE(file,File,file)
+PRIMITIVE(code,Code,code)
diff --git a/Build/source/utils/asymptote/process.cc b/Build/source/utils/asymptote/process.cc
new file mode 100644
index 00000000000..59fb8c358fa
--- /dev/null
+++ b/Build/source/utils/asymptote/process.cc
@@ -0,0 +1,883 @@
+/*****
+ * process.cc
+ * Andy Hammerlindl 2006/08/19
+ *
+ * Handles processing blocks of code (including files, strings, and the
+ * interactive prompt, for listing and parse-only modes as well as actually
+ * running it.
+ *****/
+
+#include "types.h"
+#include "errormsg.h"
+#include "genv.h"
+#include "stm.h"
+#include "settings.h"
+#include "vm.h"
+#include "program.h"
+#include "interact.h"
+#include "envcompleter.h"
+#include "parser.h"
+#include "fileio.h"
+
+#include "stack.h"
+#include "runtime.h"
+#include "texfile.h"
+
+#include "process.h"
+
+namespace camp {
+pen& defaultpen() {
+ return processData().defaultpen;
+}
+}
+
+namespace run {
+void cleanup();
+void exitFunction(vm::stack *Stack);
+void updateFunction(vm::stack *Stack);
+void purge(Int divisor=0);
+}
+
+namespace vm {
+bool indebugger;
+}
+
+using namespace settings;
+
+using absyntax::file;
+using trans::genv;
+using trans::coenv;
+using trans::env;
+using trans::coder;
+using types::record;
+
+using interact::interactive;
+using interact::uptodate;
+
+using absyntax::runnable;
+using absyntax::block;
+
+mem::stack<processDataStruct *> processDataStack;
+
+processDataStruct &processData() {
+ assert(!processDataStack.empty());
+ return *processDataStack.top();
+}
+
+void init(bool resetpath=true)
+{
+ vm::indebugger=false;
+ uptodate=false;
+ if(resetpath)
+ setPath(""); /* On second and subsequent calls, sets the path
+ to what it was when the program started. */
+}
+
+// This helper class does nothing but call the interactiveTrans method of the
+// base object in place of trans, so that the runnable can exhibit special
+// behaviour when run at the interactive prompt.
+class interactiveRunnable : public runnable {
+ runnable *base;
+
+public:
+ interactiveRunnable(runnable *base)
+ : runnable(base->getPos()), base(base) {}
+
+ void prettyprint(ostream &out, Int indent) {
+ absyntax::prettyname(out, "interactiveRunnable", indent);
+ base->prettyprint(out, indent+1);
+ }
+
+ void trans(coenv &e) {
+ base->interactiveTrans(e);
+ }
+
+ void transAsField(coenv &e, types::record *r) {
+ // There is no interactiveTransAsField, as fields aren't declared at the top
+ // level of the interactive prompt.
+ base->transAsField(e, r);
+ }
+};
+
+enum transMode {
+ TRANS_INTERACTIVE,
+ TRANS_NORMAL
+};
+
+
+// How to run a runnable in runnable-at-a-time mode.
+bool runRunnable(runnable *r, coenv &e, istack &s, transMode tm=TRANS_NORMAL) {
+ e.e.beginScope();
+
+ lambda *codelet= tm==TRANS_INTERACTIVE ?
+ interactiveRunnable(r).transAsCodelet(e) :
+ r->transAsCodelet(e);
+ em.sync();
+ if(!em.errors()) {
+ if(getSetting<bool>("translate")) print(cout,codelet->code);
+ s.run(codelet);
+
+ // Commits the changes made to the environment.
+ e.e.collapseScope();
+ } else {
+ e.e.endScope(); // Remove any changes to the environment.
+
+ // Should an interactive error hurt the status?
+ em.statusError();
+
+ return false;
+ }
+ return true;
+}
+
+void runAutoplain(coenv &e, istack &s) {
+ absyntax::runnable *r=absyntax::autoplainRunnable();
+ runRunnable(r,e,s);
+}
+
+// Abstract base class for the core object being run in line-at-a-time mode, it
+// may be a block of code, file, or interactive prompt.
+struct icore {
+ virtual ~icore() {}
+
+ virtual void doParse() = 0;
+ virtual void doList() = 0;
+
+public:
+
+ // preRun and postRun are the optional activities that take place before and
+ // after running the code specified. They can be overridden by derived class
+ // that wish different behaviour.
+ virtual void preRun(coenv &e, istack &s) {
+ if(getSetting<bool>("autoplain"))
+ runAutoplain(e,s);
+ }
+
+ virtual void run(coenv &e, istack &s, transMode tm=TRANS_NORMAL) = 0;
+
+ virtual void postRun(coenv &, istack &s) {
+ run::exitFunction(&s);
+ }
+
+ virtual void doRun(bool purge=false, transMode tm=TRANS_NORMAL) {
+ em.sync();
+ if(em.errors())
+ return;
+
+ try {
+ if(purge) run::purge();
+
+ genv ge;
+ env base_env(ge);
+ coder base_coder;
+ coenv e(base_coder,base_env);
+
+ vm::interactiveStack s;
+ s.setInitMap(ge.getInitMap());
+ s.setEnvironment(&e);
+
+ preRun(e,s);
+
+ if(purge) run::purge();
+
+ // Now that everything is set up, run the core.
+ run(e,s,tm);
+
+ postRun(e,s);
+
+ } catch(std::bad_alloc&) {
+ outOfMemory();
+ } catch(quit) {
+ } catch(handled_error) {
+ em.statusError();
+ }
+
+ run::cleanup();
+
+ em.clear();
+ }
+
+ virtual void process(bool purge=false) {
+ if (!interactive && getSetting<bool>("parseonly"))
+ doParse();
+ else {
+ // This is not done in preRun as it is not an optional step.
+ processDataStruct data;
+ processDataStack.push(&data);
+
+ if (getSetting<bool>("listvariables"))
+ doList();
+ else
+ doRun(purge);
+
+ processDataStack.pop();
+ }
+ }
+};
+
+// Abstract base class for one-time processing of an abstract syntax tree.
+class itree : public icore {
+ string name;
+
+ block *cachedTree;
+public:
+ itree(string name="<unnamed>")
+ : name(name), cachedTree(0) {}
+
+ // Build the tree, possibly throwing a handled_error if it cannot be built.
+ virtual block *buildTree() = 0;
+
+ virtual block *getTree() {
+ if (cachedTree==0) {
+ try {
+ cachedTree=buildTree();
+ } catch(handled_error) {
+ em.statusError();
+ return 0;
+ }
+ }
+ return cachedTree;
+ }
+
+ virtual string getName() {
+ return name;
+ }
+
+ void doParse() {
+ block *tree=getTree();
+ em.sync();
+ if(tree && !em.errors())
+ tree->prettyprint(cout, 0);
+ }
+
+ void doList() {
+ block *tree=getTree();
+ if (tree) {
+ genv ge;
+ record *r=tree->transAsFile(ge, symbol::trans(getName()));
+ r->e.list(r);
+ }
+ }
+
+ void run(coenv &e, istack &s, transMode tm=TRANS_NORMAL) {
+ block *tree=getTree();
+ if (tree) {
+ for(mem::list<runnable *>::iterator r=tree->stms.begin();
+ r != tree->stms.end(); ++r)
+ if(!em.errors() || getSetting<bool>("debug"))
+ runRunnable(*r,e,s,tm);
+ }
+ }
+
+ void doRun(transMode tm=TRANS_NORMAL) {
+ // Don't prepare an environment to run the code if there isn't any code.
+ if (getTree()) {
+ // This is not done in preRun as it is not an optional step.
+ processDataStruct data;
+ processDataStack.push(&data);
+
+ icore::doRun(false,tm);
+
+ processDataStack.pop();
+ }
+ }
+};
+
+class icode : public itree {
+ block *tree;
+
+public:
+ icode(block *tree, string name="<unnamed>")
+ : itree(name), tree(tree) {}
+
+ block *buildTree() {
+ return tree;
+ }
+};
+
+class istring : public itree {
+ string str;
+
+public:
+ istring(const string& str, string name="<eval>")
+ : itree(name), str(str) {}
+
+ block *buildTree() {
+ return parser::parseString(str, getName());
+ }
+};
+
+class ifile : public itree {
+ string filename;
+ string outname;
+ string outname_save;
+
+public:
+ ifile(const string& filename)
+ : itree(filename),
+ filename(filename),
+ outname((string) (filename == "-" ? settings::outname() :
+ stripDir(stripExt(string(filename), suffix)))) {}
+
+ block *buildTree() {
+ return !filename.empty() ? parser::parseFile(filename,"Loading") : 0;
+ }
+
+ void preRun(coenv& e, istack& s) {
+ outname_save=getSetting<string>("outname");
+ if(stripDir(outname_save).empty())
+ Setting("outname")=outname_save+outname;
+
+ itree::preRun(e, s);
+ }
+
+ void postRun(coenv &e, istack& s) {
+ itree::postRun(e, s);
+
+ Setting("outname")=outname_save;
+ }
+
+ void process(bool purge=false) {
+ try {
+ init();
+ } catch(handled_error) {
+ }
+
+ if (verbose >= 1)
+ cout << "Processing " << outname << endl;
+
+ try {
+ icore::process(purge);
+ }
+ catch(handled_error) {
+ em.statusError();
+ }
+ }
+};
+
+void printGreeting() {
+ if(!getSetting<bool>("quiet"))
+ cout << "Welcome to " << PROGRAM << " version " << VERSION << SVN_REVISION
+ << " (to view the manual, type help)" << endl;
+}
+
+
+// Add a semi-colon terminator, if one is not there.
+string terminateLine(const string line) {
+ return (!line.empty() && *(line.rbegin())!=';') ? (line+";") : line;
+}
+
+// cleanLine changes a C++ style comment (//) into a C-style comment (/* */) so
+// that comments don't absorb subsequent lines of code when multiline input is
+// collapsed to a single line in the history.
+//
+// ex. if (x==1) // test x
+// x=2;
+// becomes
+// if (x==1) /* test x */ x=2 (all on one line)
+//
+// cleanLine is a mess because we have to check that the // is not in a string
+// or c-style comment, which entails re-inventing much of the lexer. The
+// routine handles most cases, but multiline strings lose their newlines when
+// recorded in the history.
+typedef string::size_type size_type;
+const size_type npos=string::npos;
+
+inline size_type min(size_type a, size_type b) {
+ return a < b ? a : b;
+}
+
+// If start is an offset somewhere within a string, this returns the first
+// offset outside of the string. sym is the character used to start the string,
+// ' or ".
+size_type endOfString(const char sym, const string line, size_type start) {
+ size_type endString=line.find(sym, start);
+ if (endString == npos)
+ return npos;
+
+ size_type escapeInString=min(line.find(string("\\")+sym, start),
+ line.find("\\\\", start));
+ if (endString < escapeInString)
+ return endString+1;
+ else
+ return endOfString(sym, line, escapeInString+2);
+}
+
+// If start is an offset somewhere within a C-style comment, this returns the
+// first offset outside of the comment.
+size_type endOfComment(const string line, size_type start) {
+ size_type endComment=line.find("*/", start);
+ if (endComment == npos)
+ return npos;
+ else
+ return endComment+2;
+}
+
+// Find the start of a string literal in the line.
+size_type stringPos(const string line, size_type start) {
+ if (start == npos)
+ return npos;
+
+ size_type pos=line.find_first_of("\'\"", start);
+ if (pos == npos)
+ return npos;
+
+ // Skip over comments /* */ and ignore anything after //
+ size_type startComment=line.find("/*", start);
+ size_type startLineComment=line.find("//", start);
+
+ if (min(startComment,startLineComment) < pos)
+ return stringPos(line,
+ startComment < startLineComment ?
+ endOfComment(line, startComment+2) :
+ npos);
+ else
+ // Nothing to skip over - the symbol actually starts a string.
+ return pos;
+}
+
+// A multiline string should retain its newlines when collapsed to a single
+// line. This converts
+// 'hello
+// there'
+// to
+// 'hello\nthere'
+// and
+// "hello
+// there"
+// to
+// "hello" '\n' "there"
+// If the line doesn't end mid-string, this adds a space to the end to preserve
+// whitespace, since it is the last function to touch the line.
+string endString(const string line, size_type start) {
+ assert(start!=npos);
+
+ size_type pos=stringPos(line, start);
+
+ if (pos==npos)
+ // String ends in normal code.
+ return line+" ";
+ else {
+ char sym=line[pos];
+ size_type eos=endOfString(sym, line, pos+1);
+ if (eos==npos) {
+ // Line ends while in a string, attach a newline symbol.
+ switch (line[pos]) {
+ case '\'':
+ return line+"\\n";
+ case '\"':
+ return line+"\" \'\\n\' \"";
+ default:
+ assert(False);
+ return line;
+ }
+ }
+ else {
+ return endString(line, eos+1);
+ }
+ }
+}
+
+// Find the first // that isn't in a C-style comment or a string.
+size_type slashPos(const string line, size_type start) {
+ if (start == npos)
+ return npos;
+
+ size_type pos=line.find("//", start);
+ if (pos == npos)
+ return npos;
+
+ // Skip over comments /* */ and strings both " " and ' '
+ size_type startComment=line.find("/*", start);
+ size_type startString=line.find_first_of("\'\"", start);
+
+ if (min(startComment,startString) < pos)
+ return slashPos(line,
+ startComment < startString ?
+ endOfComment(line, startComment+2) :
+ endOfString(line[startString], line, startString+1));
+ else
+ // Nothing to skip over - the // actually starts a comment.
+ return pos;
+}
+
+string endCommentOrString(const string line) {
+ size_type pos=slashPos(line, 0);
+ if (pos == npos)
+ return endString(line, 0);
+ else {
+ string sub=line;
+
+ // Replace the first // by /*
+ sub[pos+1]='*';
+
+ // Replace any */ in the comment by *!
+ while ((pos = line.find("*/", pos+2)) != npos)
+ sub[pos+1]='!';
+
+ // Tack on a */ at the end.
+ sub.append(" */ ");
+ return sub;
+ }
+}
+
+bool isSlashed(const string line) {
+ // NOTE: This doesn't fully handle escaped slashed in a string literal.
+ return line[line.size()-1]=='\\';
+}
+string deslash(const string line) {
+ return isSlashed(line) ? line.substr(0,line.size()-1) : line;
+}
+
+// This transforms a line in to the history, so that when more code is added
+// after it, the code behaves the same as if there was a newline between the
+// two lines. This involves changing // style comments to /* */ style comments,
+// and adding explicit newlines to multiline strings.
+string cleanLine(const string line) {
+ // First remove a trailing slash, if there is one.
+ return endCommentOrString(deslash(line));
+}
+
+class iprompt : public icore {
+ // Flag that is set to false to signal the prompt to exit.
+ bool running;
+
+ // Flag that is set to restart the main loop once it has exited.
+ bool restart;
+
+ // Code ran at start-up.
+ string startline;
+
+ // Used for handling quit abbreviation (q).
+ protoenv *einteractive;
+
+ void postRun(coenv &, istack &) {
+ }
+
+ // Commands are chopped into the starting word and the rest of the line.
+ struct commandLine {
+ string line;
+ string word;
+ string rest;
+
+ commandLine(string line) : line(line) {
+ string::iterator c=line.begin();
+
+ // Skip leading whitespace
+ while (c != line.end() && isspace(*c))
+ ++c;
+
+ // Only handle identifiers starting with a letter.
+ if (c != line.end() && isalpha(*c)) {
+ // Store the command name.
+ while (c != line.end() && (isalnum(*c) || *c=='_')) {
+ word.push_back(*c);
+ ++c;
+ }
+ }
+
+ // Copy the rest to rest.
+ while (c != line.end()) {
+ rest.push_back(*c);
+ ++c;
+ }
+
+#if 0
+ cerr << "line: " << line << endl;
+ cerr << "word: " << word << endl;
+ cerr << "rest: " << rest << endl;
+ cerr << "simple: " << simple() << endl;
+#endif
+ }
+
+ // Simple commands have at most spaces or semicolons after the command word.
+ bool simple() {
+ for (string::iterator c=rest.begin(); c != rest.end(); ++c)
+ if (!isspace(*c) && *c != ';')
+ return false;
+ return true;
+ }
+ };
+
+
+ // The interactive prompt has special functions that cannot be implemented as
+ // normal functions. These special funtions take a commandLine as an argument
+ // and return true if they can handle the command. If false is returned, the
+ // line is treated as a normal line of code.
+ // commands is a map of command names to methods which implement the commands.
+ typedef bool (iprompt::*command)(commandLine);
+ typedef mem::map<CONST string, command> commandMap;
+ commandMap commands;
+
+ bool exit(commandLine cl) {
+ if (cl.simple()) {
+ // Don't store exit commands in the history file.
+ interact::deleteLastLine();
+
+ running=false;
+ return true;
+ }
+ else return false;
+ }
+
+ bool q(commandLine cl) {
+ if(einteractive->ve.getType(symbol::trans("q"))) return false;
+ return exit(cl);
+ }
+
+ bool reset(commandLine cl) {
+ if (cl.simple()) {
+ running=false;
+ restart=true;
+ startline="";
+
+ run::purge();
+
+ return true;
+ }
+ else return false;
+ }
+
+ bool help(commandLine cl) {
+ if (cl.simple()) {
+ popupHelp();
+ return true;
+ }
+ else return false;
+ }
+
+
+ bool input(commandLine cl) {
+ string prefix="include ";
+ string line=prefix+cl.rest;
+ running=false;
+ restart=true;
+ startline=line;
+ return true;
+ }
+
+ void initCommands() {
+#define ADDCOMMAND(name, func) \
+ commands[#name]=&iprompt::func
+
+ // keywords.pl looks for ADDCOMMAND to identify special commands in the
+ // auto-completion.
+ ADDCOMMAND(quit,exit);
+ ADDCOMMAND(q,q);
+ ADDCOMMAND(exit,exit);
+ ADDCOMMAND(reset,reset);
+ ADDCOMMAND(help,help);
+ ADDCOMMAND(input,input);
+
+#undef ADDCOMMAND
+ }
+
+ bool handleCommand(string line) {
+ commandLine cl(line);
+ if (cl.word != "") {
+ commandMap::iterator p=commands.find(cl.word);
+ if (p != commands.end()) {
+ // Execute the command.
+ command &com=p->second;
+ return (this->*com)(cl);
+ }
+ else
+ return false;
+ }
+ else
+ return false;
+ }
+
+ void addToHistory(string line) {
+ interact::addToHistory(line);
+ }
+
+ void addToLastLine(string line) {
+ // Here we clean a line at the last possible point, when we know that more
+ // code is going to be appended to it.
+ string last=interact::getLastHistoryLine();
+ interact::setLastHistoryLine(cleanLine(last)+line);
+ }
+
+ void terminateLastHistoryLine() {
+ string last=interact::getLastHistoryLine();
+ interact::setLastHistoryLine(terminateLine(last));
+ }
+
+ // Get input from the interactive prompt. Such input may be over several
+ // user-typed lines if he/she ends a line a with backslash to continue input
+ // on the next line. If continuation is true, the input started on a previous
+ // line and is being continued (either because of a backslash or the parser
+ // detecting it in multiline mode).
+ string getline(bool continuation) {
+ string prompt=getSetting<string>(continuation ? "prompt2" : "prompt");
+ string line=interact::simpleline(prompt);
+
+ if (continuation)
+ addToLastLine(line);
+ else
+ addToHistory(line);
+
+ // If the line ends in a slash, get more input.
+ return isSlashed(line) ? line+"\n"+getline(true) :
+ line;
+ }
+
+ // Continue taking input for a line until it properly parses, or a syntax
+ // error occurs. Returns the parsed code on success, and throws a
+ // handled_error exception on failure.
+ block *parseExtendableLine(string line) {
+ block *code=parser::parseString(line, "-", true);
+ if (code) {
+ return code;
+ } else {
+ string nextline=getline(true);
+ return parseExtendableLine(line+"\n"+nextline);
+ }
+ }
+
+ void runLine(coenv &e, istack &s, string line) {
+ try {
+ if (getSetting<bool>("multiline")) {
+ block *code=parseExtendableLine(line);
+
+ icode i(code);
+ i.run(e,s,TRANS_INTERACTIVE);
+ }
+ else {
+ // Add a semi-colon to the end of the line if one is not there. Do this
+ // to the history as well, so the transcript can be run as regular asy
+ // code. This also makes the history work correctly if the multiline
+ // setting is changed within an interactive session.
+ // It is added to the history at the last possible moment to avoid
+ // tampering with other features, such as using a slash to extend a
+ // line.
+ terminateLastHistoryLine();
+ istring i(terminateLine(line), "-");
+ i.run(e,s,TRANS_INTERACTIVE);
+ }
+
+ run::updateFunction(&s);
+ uptodate=false;
+
+ } catch(handled_error) {
+ vm::indebugger=false;
+ } catch(interrupted&) {
+ // Turn off the interrupted flag.
+ em.Interrupt(false);
+ uptodate=true;
+ cout << endl;
+ } catch(quit&) {
+ }
+
+ // Ignore errors from this line when trying to run subsequent lines.
+ em.clear();
+ }
+
+ void runStartCode(coenv &e, istack &s) {
+ if (!startline.empty())
+ runLine(e, s, startline);
+ }
+
+public:
+ iprompt() : running(false), restart(false), startline("") {
+ initCommands();
+ }
+
+ void doParse() {}
+
+ void doList() {}
+
+ void run(coenv &e, istack &s, transMode=TRANS_NORMAL) {
+ running=true;
+ interact::setCompleter(new trans::envCompleter(e.e));
+ einteractive=&(e.e);
+
+ runStartCode(e, s);
+
+ while (running) {
+ // Read a line from the prompt.
+ string line=getline(false);
+
+ // Check if it is a special command.
+ if (handleCommand(line))
+ continue;
+ else
+ runLine(e, s, line);
+ }
+ }
+
+ void process() {
+ printGreeting();
+ interact::init_interactive();
+ try {
+ setPath("",true);
+ } catch(handled_error) {
+ }
+
+ do {
+ try {
+ init(false);
+ restart=false;
+ icore::process();
+ } catch(interrupted&) {
+ em.Interrupt(false);
+ restart=true;
+ } catch(eof&) {
+ restart=false;
+ }
+ } while(restart);
+
+ interact::cleanup_interactive();
+ }
+};
+
+void processCode(absyntax::block *code) {
+ icode(code).process();
+}
+void processFile(const string& filename, bool purge) {
+ ifile(filename).process(purge);
+}
+void processPrompt() {
+ iprompt().process();
+}
+
+void runCode(absyntax::block *code) {
+ icode(code).doRun();
+}
+void runString(const string& s, bool interactiveWrite) {
+ istring(s).doRun(interactiveWrite ? TRANS_INTERACTIVE : TRANS_NORMAL);
+}
+void runFile(const string& filename) {
+ ifile(filename).doRun();
+}
+void runPrompt() {
+ iprompt().doRun();
+}
+
+void runCodeEmbedded(absyntax::block *code, trans::coenv &e, istack &s) {
+ icode(code).run(e,s);
+}
+void runStringEmbedded(const string& str, trans::coenv &e, istack &s) {
+ istring(str).run(e,s);
+}
+void runPromptEmbedded(trans::coenv &e, istack &s) {
+ iprompt().run(e,s);
+}
+
+void doUnrestrictedList() {
+ processDataStruct data;
+ processDataStack.push(&data);
+
+ genv ge;
+ env base_env(ge);
+ coder base_coder;
+ coenv e(base_coder,base_env);
+
+ if (getSetting<bool>("autoplain"))
+ absyntax::autoplainRunnable()->trans(e);
+
+ processDataStack.pop();
+ e.e.list(0);
+}
+
diff --git a/Build/source/utils/asymptote/process.h b/Build/source/utils/asymptote/process.h
new file mode 100644
index 00000000000..42974ff5cf2
--- /dev/null
+++ b/Build/source/utils/asymptote/process.h
@@ -0,0 +1,117 @@
+/*****
+ * process.h
+ * Andy Hammerlindl 2006/08/19
+ *
+ * Handles processing blocks of code (including files, strings, and the
+ * interactive prompt, for listing and parse-only modes as well as actually
+ * running it.
+ *****/
+
+#ifndef PROCESS_H
+#define PROCESS_H
+
+
+#include "common.h"
+#include "stm.h"
+#include "stack.h"
+#include "pipestream.h"
+#include "callable.h"
+#include "pen.h"
+
+#ifdef HAVE_RPC_RPC_H
+#include "xstream.h"
+#endif
+
+// Process the code respecting the parseonly and listvariables flags of
+// settings.
+void processCode(absyntax::block *code);
+void processFile(const string& filename, bool purge=false);
+void processPrompt();
+
+// Run the code in its own environment.
+void runCode(absyntax::block *code);
+void runString(const string& s, bool interactiveWrite=false);
+void runFile(const string& filename);
+void runPrompt();
+
+// Run the code in a given run-time environment.
+typedef vm::interactiveStack istack;
+void runCodeEmbedded(absyntax::block *code, trans::coenv &e, istack &s);
+void runStringEmbedded(const string& str, trans::coenv &e, istack &s);
+void runPromptEmbedded(trans::coenv &e, istack &s);
+
+// Basic listing.
+void doUnrestrictedList();
+
+template<class T>
+class terminator {
+public:
+ typedef mem::vector<T *> Pointer;
+ Pointer pointer;
+
+ // Return first available index
+ size_t available() {
+ size_t index=0;
+ for(typename Pointer::iterator p=pointer.begin(); p != pointer.end(); ++p) {
+ if(*p == NULL) {return index;}
+ ++index;
+ }
+ pointer.push_back(NULL);
+ return index;
+ }
+
+ size_t add(T *p) {
+ size_t index=available();
+ pointer[index]=p;
+ return index;
+ }
+
+ void remove(size_t index) {
+ pointer[index]=NULL;
+ }
+
+ ~terminator() {
+ for(typename Pointer::iterator p=pointer.begin(); p != pointer.end(); ++p) {
+ if(*p != NULL) {
+ (*p)->~T();
+ (*p)=NULL;
+ }
+ }
+ }
+};
+
+class texstream : public iopipestream {
+public:
+ ~texstream();
+};
+
+struct processDataStruct {
+ texstream tex; // Bi-directional pipe to latex (to find label bbox)
+ mem::list<string> TeXpipepreamble;
+ mem::list<string> TeXpreamble;
+ vm::callable *atExitFunction;
+ vm::callable *atUpdateFunction;
+ vm::callable *atBreakpointFunction;
+ camp::pen defaultpen;
+ camp::pen currentpen;
+
+ terminator<std::ofstream> ofile;
+ terminator<std::fstream> ifile;
+#ifdef HAVE_RPC_RPC_H
+ terminator<xdr::ioxstream> ixfile;
+ terminator<xdr::oxstream> oxfile;
+#endif
+
+ processDataStruct() {
+ atExitFunction=NULL;
+ atUpdateFunction=NULL;
+ atBreakpointFunction=NULL;
+ defaultpen=camp::pen::initialpen();
+ currentpen=camp::pen(camp::DEFLINE);
+ }
+
+};
+
+processDataStruct &processData();
+
+#endif
diff --git a/Build/source/utils/asymptote/program.cc b/Build/source/utils/asymptote/program.cc
new file mode 100644
index 00000000000..fd7b14bfe0e
--- /dev/null
+++ b/Build/source/utils/asymptote/program.cc
@@ -0,0 +1,92 @@
+/*****
+ * program.cc
+ * Tom Prince
+ *
+ * The list of instructions used by the virtual machine.
+ *****/
+
+#include <iostream>
+#include "program.h"
+
+namespace vm {
+
+static const char* opnames[] = {
+ "pop", "intpush", "constpush",
+ "varpush", "varsave", "fieldpush", "fieldsave",
+ "builtin", "jmp", "cjmp", "njmp", "call",
+ "pushclosure", "makefunc", "ret",
+ "alloc", "pushframe", "popframe"
+};
+static const Int numOps = (Int)(sizeof(opnames)/sizeof(char *));
+
+void printInst(ostream& out, const program::label& code,
+ const program::label& base)
+{
+ out.width(4);
+ out << offset(base,code) << " ";
+
+ Int i = (Int)code->op;
+
+ if (i < 0 || i >= numOps) {
+ out << "<<invalid op>> " << i;
+ }
+ out << opnames[i];
+
+ switch (code->op) {
+ case inst::intpush:
+ case inst::varpush:
+ case inst::varsave:
+ case inst::fieldpush:
+ case inst::fieldsave:
+ case inst::alloc:
+ {
+ out << " " << get<Int>(*code);
+ break;
+ }
+
+ case inst::builtin:
+ {
+ out << " " << get<bltin>(*code) << " ";
+ break;
+ }
+
+ case inst::jmp:
+ case inst::cjmp:
+ case inst::njmp:
+ {
+ char f = out.fill('0');
+ out << " i";
+ out.width(4);
+ out << offset(base,get<program::label>(*code));
+ out.fill(f);
+ break;
+ }
+
+ case inst::makefunc:
+ {
+ out << " " << get<lambda*>(*code) << " ";
+ break;
+ }
+
+ default: {
+ /* nothing else to do */
+ break;
+ }
+ };
+}
+
+void print(ostream& out, program *base)
+{
+ program::label code = base->begin();
+ bool active = true;
+ while (active) {
+ if (code->op == inst::ret ||
+ code->op < 0 || code->op >= numOps)
+ active = false;
+ printInst(out, code, base->begin());
+ out << '\n';
+ ++code;
+ }
+}
+
+} // namespace vm
diff --git a/Build/source/utils/asymptote/program.h b/Build/source/utils/asymptote/program.h
new file mode 100644
index 00000000000..c6e37562bc5
--- /dev/null
+++ b/Build/source/utils/asymptote/program.h
@@ -0,0 +1,89 @@
+/*****
+ * program.h
+ * Tom Prince
+ *
+ * The list of instructions used by the virtual machine.
+ *****/
+
+#ifndef PROGRAM_H
+#define PROGRAM_H
+
+#include "common.h"
+#include "inst.h"
+
+namespace vm {
+class inst;
+
+class program : public gc {
+public:
+ class label;
+ program();
+ void encode(inst i);
+ label begin();
+ label end();
+private:
+ friend class label;
+ typedef mem::vector<inst> code_t;
+ code_t code;
+ inst& operator[](size_t);
+};
+
+class program::label
+{
+public: // interface
+ label() : where(0), code() {}
+public: //interface
+ label& operator++();
+ label& operator--();
+ bool operator==(const label& right) const;
+ bool operator!=(const label& right) const;
+ inst& operator*() const;
+ inst* operator->() const;
+ friend ptrdiff_t offset(const label& left,
+ const label& right);
+private:
+ label (size_t where, program* code)
+ : where(where), code(code) {}
+ size_t where;
+ program* code;
+ friend class program;
+};
+
+// Prints one instruction (including arguments) and returns how many
+// positions in the code stream were shown.
+void printInst(std::ostream& out, const program::label& code,
+ const program::label& base);
+
+// Prints code until a ret opcode is printed.
+void print(std::ostream& out, program *base);
+
+// Inline forwarding functions for vm::program
+inline program::program()
+ : code() {}
+inline program::label program::end()
+{ return label(code.size(), this); }
+inline program::label program::begin()
+{ return label(0, this); }
+inline void program::encode(inst i)
+{ code.push_back(i); }
+inline inst& program::operator[](size_t n)
+{ return code[n]; }
+inline program::label& program::label::operator++()
+{ ++where; return *this; }
+inline program::label& program::label::operator--()
+{ --where; return *this; }
+inline bool program::label::operator==(const label& right) const
+{ return (code == right.code) && (where == right.where); }
+inline bool program::label::operator!=(const label& right) const
+{ return !(*this == right); }
+inline inst& program::label::operator*() const
+{ return (*code)[where]; }
+inline inst* program::label::operator->() const
+{ return &**this; }
+inline ptrdiff_t offset(const program::label& left,
+ const program::label& right)
+{ return right.where - left.where; }
+
+} // namespace vm
+
+#endif // PROGRAM_H
diff --git a/Build/source/utils/asymptote/psfile.cc b/Build/source/utils/asymptote/psfile.cc
new file mode 100644
index 00000000000..feb91b34dea
--- /dev/null
+++ b/Build/source/utils/asymptote/psfile.cc
@@ -0,0 +1,688 @@
+/*****
+ * psfile.cc
+ * Andy Hammerlindl 2002/06/10
+ *
+ * Encapsulates the writing of commands to a PostScript file.
+ * Allows identification and removal of redundant commands.
+ *****/
+
+#include <ctime>
+#include <iomanip>
+#include <sstream>
+#include <zlib.h>
+
+#include "psfile.h"
+#include "settings.h"
+#include "errormsg.h"
+#include "array.h"
+
+using std::ofstream;
+using std::setw;
+using vm::array;
+using vm::read;
+
+namespace camp {
+
+void checkColorSpace(ColorSpace colorspace)
+{
+ switch(colorspace) {
+ case DEFCOLOR:
+ case INVISIBLE:
+ reportError("Cannot shade with invisible pen");
+ case PATTERN:
+ reportError("Cannot shade with pattern");
+ break;
+ default:
+ break;
+ }
+}
+
+psfile::psfile(const string& filename, bool pdfformat)
+ : filename(filename), pdfformat(pdfformat), pdf(false),
+ transparency(false), buffer(NULL), out(NULL)
+{
+ if(filename.empty()) out=&cout;
+ else out=new ofstream(filename.c_str());
+ if(!out || !*out)
+ reportError("Cannot write to "+filename);
+}
+
+static const char *inconsistent="inconsistent colorspaces";
+
+void psfile::writefromRGB(unsigned char r, unsigned char g, unsigned char b,
+ ColorSpace colorspace, size_t ncomponents)
+{
+ static const double factor=1.0/255.0;
+ pen p(r*factor,g*factor,b*factor);
+ p.convert();
+ if(!p.promote(colorspace))
+ reportError(inconsistent);
+ write(&p,ncomponents);
+}
+
+inline unsigned char average(unsigned char *a, size_t dx, size_t dy)
+{
+ return ((unsigned) a[0]+(unsigned) a[dx]+(unsigned) a[dy]+
+ (unsigned) a[dx+dy])/4;
+}
+
+void psfile::dealias(unsigned char *a, size_t width, size_t height, size_t n,
+ bool convertrgb, ColorSpace colorspace)
+{
+ // Dealias all but the last row and column of pixels.
+ size_t istop=width-1;
+ size_t jstop=height-1;
+ if(convertrgb) {
+ size_t nwidth=3*width;
+ for(size_t j=0; j < height; ++j) {
+ unsigned char *aj=a+nwidth*j;
+ for(size_t i=0; i < width; ++i) {
+ unsigned char *ai=aj+3*i;
+ if(i < istop && j < jstop)
+ writefromRGB(average(ai,3,nwidth),
+ average(ai+1,3,nwidth),
+ average(ai+2,3,nwidth),colorspace,n);
+ else
+ writefromRGB(ai[0],ai[1],ai[2],colorspace,n);
+ }
+ }
+ } else {
+ size_t nwidth=n*width;
+ for(size_t j=0; j < jstop; ++j) {
+ unsigned char *aj=a+nwidth*j;
+ for(size_t i=0; i < istop; ++i) {
+ unsigned char *ai=aj+n*i;
+ for(size_t k=0; k < n; ++k)
+ ai[k]=average(ai+k,n,nwidth);
+ }
+ }
+ }
+}
+
+void psfile::writeCompressed(const unsigned char *a, size_t size)
+{
+ uLongf compressedSize=compressBound(size);
+ Bytef *compressed=new Bytef[compressedSize];
+
+ if(compress(compressed,&compressedSize,a,size) != Z_OK)
+ reportError("image compression failed");
+
+ encode85 e(out);
+ for(size_t i=0; i < compressedSize; ++i)
+ e.put(compressed[i]);
+}
+
+void psfile::close()
+{
+ if(out) {
+ out->flush();
+ if(!filename.empty()) {
+ if(!out->good())
+ reportError("Cannot write to "+filename);
+ delete out;
+ out=NULL;
+ }
+ }
+}
+
+psfile::~psfile()
+{
+ close();
+}
+
+void psfile::header()
+{
+ Int level=settings::getSetting<Int>("level");
+ *out << "%!PS-Adobe-" << level << ".0 EPSF-" << level << ".0" << newl;
+}
+
+void psfile::prologue(const bbox& box)
+{
+ header();
+ BoundingBox(box);
+ *out << "%%Creator: " << settings::PROGRAM << " " << settings::VERSION
+ << SVN_REVISION << newl;
+
+ time_t t; time(&t);
+ struct tm *tt = localtime(&t);
+ char prev = out->fill('0');
+ *out << "%%CreationDate: " << tt->tm_year + 1900 << "."
+ << setw(2) << tt->tm_mon+1 << "." << setw(2) << tt->tm_mday << " "
+ << setw(2) << tt->tm_hour << ":" << setw(2) << tt->tm_min << ":"
+ << setw(2) << tt->tm_sec << newl;
+ out->fill(prev);
+
+ *out << "%%Pages: 1" << newl;
+ *out << "%%Page: 1 1" << newl;
+
+ if(!pdfformat)
+ *out
+ << "/Setlinewidth {0 exch dtransform dup abs 1 lt {pop 0}{round} ifelse"
+ << newl
+ << "idtransform setlinewidth pop} bind def" << newl;
+}
+
+void psfile::epilogue()
+{
+ *out << "showpage" << newl;
+ *out << "%%EOF" << newl;
+}
+
+void psfile::setcolor(const pen& p, const string& begin="",
+ const string& end="")
+{
+ if(p.cmyk() && (!lastpen.cmyk() ||
+ (p.cyan() != lastpen.cyan() ||
+ p.magenta() != lastpen.magenta() ||
+ p.yellow() != lastpen.yellow() ||
+ p.black() != lastpen.black()))) {
+ *out << begin << p.cyan() << " " << p.magenta() << " " << p.yellow() << " "
+ << p.black() << (pdf ? " k" : " setcmykcolor") << end << newl;
+ } else if(p.rgb() && (!lastpen.rgb() ||
+ (p.red() != lastpen.red() ||
+ p.green() != lastpen.green() ||
+ p.blue() != lastpen.blue()))) {
+ *out << begin << p.red() << " " << p.green() << " " << p.blue()
+ << (pdf ? " rg" : " setrgbcolor") << end << newl;
+ } else if(p.grayscale() && (!lastpen.grayscale() ||
+ p.gray() != lastpen.gray())) {
+ *out << begin << p.gray() << (pdf ? " g" : " setgray") << end << newl;
+ }
+}
+
+void psfile::setopacity(const pen& p)
+{
+ if(p.blend() != lastpen.blend()) {
+ *out << "/" << p.blend() << " .setblendmode" << newl;
+ transparency=true;
+ }
+
+ if(p.opacity() != lastpen.opacity()) {
+ *out << p.opacity() << " .setopacityalpha" << newl;
+ transparency=true;
+ }
+
+ lastpen.settransparency(p);
+}
+
+
+void psfile::setpen(pen p)
+{
+ p.convert();
+
+ setopacity(p);
+
+ if(!p.fillpattern().empty() && p.fillpattern() != lastpen.fillpattern())
+ *out << p.fillpattern() << " setpattern" << newl;
+ else setcolor(p);
+
+ // Defer dynamic linewidth until stroke time in case currentmatrix changes.
+ if(p.width() != lastpen.width()) {
+ *out << p.width() << (pdfformat ? " setlinewidth" : " Setlinewidth")
+ << newl;
+ }
+
+ if(p.cap() != lastpen.cap()) {
+ *out << p.cap() << " setlinecap" << newl;
+ }
+
+ if(p.join() != lastpen.join()) {
+ *out << p.join() << " setlinejoin" << newl;
+ }
+
+ if(p.miter() != lastpen.miter()) {
+ *out << p.miter() << " setmiterlimit" << newl;
+ }
+
+ if(p.stroke() != lastpen.stroke() ||
+ p.linetype().offset != lastpen.linetype().offset) {
+ out->setf(std::ios::fixed);
+ *out << "[" << p.stroke() << "] " << std::setprecision(6)
+ << p.linetype().offset << " setdash" << newl;
+ out->unsetf(std::ios::fixed);
+ }
+
+ lastpen=p;
+}
+
+void psfile::write(const pen& p)
+{
+ if(p.cmyk())
+ *out << p.cyan() << " " << p.magenta() << " " << p.yellow() << " "
+ << p.black();
+ else if(p.rgb())
+ *out << p.red() << " " << p.green() << " " << p.blue();
+ else if(p.grayscale())
+ *out << p.gray();
+}
+
+void psfile::write(path p, bool newPath)
+{
+ Int n = p.size();
+ assert(n != 0);
+
+ if(newPath) newpath();
+
+ pair z0=p.point((Int) 0);
+
+ // Draw points
+ moveto(z0);
+
+ for(Int i = 1; i < n; i++) {
+ if(p.straight(i-1)) lineto(p.point(i));
+ else curveto(p.postcontrol(i-1),p.precontrol(i),p.point(i));
+ }
+
+ if(p.cyclic()) {
+ if(p.straight(n-1)) lineto(z0);
+ else curveto(p.postcontrol(n-1),p.precontrol((Int) 0),z0);
+ closepath();
+ } else {
+ if(n == 1) lineto(z0);
+ }
+}
+
+void psfile::latticeshade(const vm::array& a, const bbox& b)
+{
+ checkLevel();
+ size_t n=a.size();
+ if(n == 0) return;
+
+ array *a0=read<array *>(a,0);
+ size_t m=a0->size();
+ setfirstopacity(*a0);
+
+ ColorSpace colorspace=maxcolorspace2(a);
+ checkColorSpace(colorspace);
+
+ size_t ncomponents=ColorComponents[colorspace];
+
+ *out << "<< /ShadingType 1" << newl
+ << "/Matrix ";
+
+ write(matrix(b.Min(),b.Max()));
+ *out << newl;
+ *out << "/ColorSpace /Device" << ColorDeviceSuffix[colorspace] << newl
+ << "/Function" << newl
+ << "<< /FunctionType 0" << newl
+ << "/Order 1" << newl
+ << "/Domain [0 1 0 1]" << newl
+ << "/Range [";
+ for(size_t i=0; i < ncomponents; ++i)
+ *out << "0 1 ";
+ *out << "]" << newl
+ << "/Decode [";
+ for(size_t i=0; i < ncomponents; ++i)
+ *out << "0 1 ";
+ *out << "]" << newl;
+ *out << "/BitsPerSample 8" << newl;
+ *out << "/Size [" << m << " " << n << "]" << newl
+ << "/DataSource <" << newl;
+
+ beginHex();
+ for(size_t i=n; i > 0;) {
+ array *ai=read<array *>(a,--i);
+ checkArray(ai);
+ size_t aisize=ai->size();
+ if(aisize != m) reportError("shading matrix must be rectangular");
+ for(size_t j=0; j < m; j++) {
+ pen *p=read<pen *>(ai,j);
+ p->convert();
+ if(!p->promote(colorspace))
+ reportError(inconsistent);
+ writeHex(p,ncomponents);
+ }
+ }
+ endHex();
+
+ *out << ">>" << newl
+ << ">>" << newl
+ << "shfill" << newl;
+}
+
+// Axial and radial shading
+void psfile::gradientshade(bool axial, const ColorSpace &colorspace,
+ const pen& pena, const pair& a, double ra,
+ const pen& penb, const pair& b, double rb)
+{
+ checkLevel();
+ setopacity(pena);
+ checkColorSpace(colorspace);
+
+ *out << "<< /ShadingType " << (axial ? "2" : "3") << newl
+ << "/ColorSpace /Device" << ColorDeviceSuffix[colorspace] << newl
+ << "/Coords [";
+ write(a);
+ if(!axial) write(ra);
+ write(b);
+ if(!axial) write(rb);
+ *out << "]" << newl
+ << "/Extend [true true]" << newl
+ << "/Function" << newl
+ << "<< /FunctionType 2" << newl
+ << "/Domain [0 1]" << newl
+ << "/C0 [";
+ write(pena);
+ *out << "]" << newl
+ << "/C1 [";
+ write(penb);
+ *out << "]" << newl
+ << "/N 1" << newl
+ << ">>" << newl
+ << ">>" << newl
+ << "shfill" << newl;
+}
+
+void psfile::gouraudshade(const array& pens, const array& vertices,
+ const array& edges)
+{
+ checkLevel();
+ size_t size=pens.size();
+ if(size == 0) return;
+
+ setfirstopacity(pens);
+ ColorSpace colorspace=maxcolorspace(pens);
+
+ *out << "<< /ShadingType 4" << newl
+ << "/ColorSpace /Device" << ColorDeviceSuffix[colorspace] << newl
+ << "/DataSource [" << newl;
+ for(size_t i=0; i < size; i++) {
+ write(read<Int>(edges,i));
+ write(read<pair>(vertices,i));
+ pen *p=read<pen *>(pens,i);
+ p->convert();
+ if(!p->promote(colorspace))
+ reportError(inconsistent);
+ *out << " ";
+ write(*p);
+ *out << newl;
+ }
+ *out << "]" << newl
+ << ">>" << newl
+ << "shfill" << newl;
+}
+
+// Tensor-product patch shading
+void psfile::tensorshade(const array& pens, const array& boundaries,
+ const array& z)
+{
+ checkLevel();
+ size_t size=pens.size();
+ if(size == 0) return;
+ size_t nz=z.size();
+
+ array *p0=read<array *>(pens,0);
+ if(checkArray(p0) != 4)
+ reportError("4 pens required");
+ setfirstopacity(*p0);
+
+ ColorSpace colorspace=maxcolorspace2(pens);
+ checkColorSpace(colorspace);
+
+ *out << "<< /ShadingType 7" << newl
+ << "/ColorSpace /Device" << ColorDeviceSuffix[colorspace] << newl
+ << "/DataSource [" << newl;
+
+ for(size_t i=0; i < size; i++) {
+ // Only edge flag 0 (new patch) is implemented since the 32% data
+ // compression (for RGB) afforded by other edge flags really isn't worth
+ // the trouble or confusion for the user.
+ write(0);
+ path g=read<path>(boundaries,i);
+ if(!(g.cyclic() && g.size() == 4))
+ reportError("specify cyclic path of length 4");
+ for(Int j=0; j < 4; ++j) {
+ write(g.point(j));
+ write(g.postcontrol(j));
+ write(g.precontrol(j+1));
+ }
+ if(nz == 0) { // Coons patch
+ static double nineth=1.0/9.0;
+ for(Int j=0; j < 4; ++j) {
+ write(nineth*(-4.0*g.point(j)+6.0*(g.precontrol(j)+g.postcontrol(j))
+ -2.0*(g.point(j-1)+g.point(j+1))
+ +3.0*(g.precontrol(j-1)+g.postcontrol(j+1))
+ -g.point(j+2)));
+ }
+ } else {
+ array *zi=read<array *>(z,i);
+ if(checkArray(zi) != 4)
+ reportError("specify 4 internal control points for each path");
+ for(Int j=0; j < 4; ++j)
+ write(read<pair>(zi,j));
+ }
+
+ array *pi=read<array *>(pens,i);
+ if(checkArray(pi) != 4)
+ reportError("specify 4 pens for each path");
+ for(Int j=0; j < 4; ++j) {
+ pen *p=read<pen *>(pi,j);
+ p->convert();
+ if(!p->promote(colorspace))
+ reportError(inconsistent);
+ *out << " ";
+ write(*p);
+ }
+ *out << newl;
+ }
+
+ *out << "]" << newl
+ << ">>" << newl
+ << "shfill" << newl;
+}
+
+inline unsigned char byte(double r) // Map [0,1] to [0,255]
+{
+ if(r < 0.0) r=0.0;
+ else if(r > 1.0) r=1.0;
+ int a=(int)(256.0*r);
+ if(a == 256) a=255;
+ return a;
+}
+
+void psfile::write(pen *p, size_t ncomponents)
+{
+ switch(ncomponents) {
+ case 0:
+ break;
+ case 1:
+ writeByte(byte(p->gray()));
+ break;
+ case 3:
+ writeByte(byte(p->red()));
+ writeByte(byte(p->green()));
+ writeByte(byte(p->blue()));
+ break;
+ case 4:
+ writeByte(byte(p->cyan()));
+ writeByte(byte(p->magenta()));
+ writeByte(byte(p->yellow()));
+ writeByte(byte(p->black()));
+ default:
+ break;
+ }
+}
+
+void psfile::writeHex(pen *p, size_t ncomponents)
+{
+ switch(ncomponents) {
+ case 0:
+ break;
+ case 1:
+ write2(byte(p->gray()));
+ writenewl();
+ break;
+ case 3:
+ write2(byte(p->red()));
+ write2(byte(p->green()));
+ write2(byte(p->blue()));
+ writenewl();
+ break;
+ case 4:
+ write2(byte(p->cyan()));
+ write2(byte(p->magenta()));
+ write2(byte(p->yellow()));
+ write2(byte(p->black()));
+ writenewl();
+ default:
+ break;
+ }
+}
+
+string filter()
+{
+ return settings::getSetting<Int>("level") >= 3 ?
+ "1 (~>) /SubFileDecode filter /ASCII85Decode filter\n/FlateDecode" :
+ "1 (~>) /SubFileDecode filter /ASCII85Decode";
+}
+
+void psfile::imageheader(size_t width, size_t height, ColorSpace colorspace)
+{
+ size_t ncomponents=ColorComponents[colorspace];
+ *out << "/Device" << ColorDeviceSuffix[colorspace] << " setcolorspace"
+ << newl
+ << "<<" << newl
+ << "/ImageType 1" << newl
+ << "/Width " << width << newl
+ << "/Height " << height << newl
+ << "/BitsPerComponent 8" << newl
+ << "/Decode [";
+
+ for(size_t i=0; i < ncomponents; ++i)
+ *out << "0 1 ";
+
+ *out << "]" << newl
+ << "/ImageMatrix [" << width << " 0 0 " << height << " 0 0]" << newl
+ << "/DataSource currentfile " << filter() << " filter" << newl
+ << ">>" << newl
+ << "image" << newl;
+}
+
+void psfile::image(const array& a, const array& P, bool antialias)
+{
+ size_t asize=a.size();
+ size_t Psize=P.size();
+ if(asize == 0 || Psize == 0) return;
+
+ array *a0=read<array *>(a,0);
+ size_t a0size=a0->size();
+ if(a0size == 0) return;
+
+ setfirstopacity(P);
+
+ ColorSpace colorspace=maxcolorspace(P);
+ checkColorSpace(colorspace);
+
+ size_t ncomponents=ColorComponents[colorspace];
+
+ imageheader(a0size,asize,colorspace);
+
+ double min=read<double>(a0,0);
+ double max=min;
+ for(size_t i=0; i < asize; i++) {
+ array *ai=read<array *>(a,i);
+ for(size_t j=0; j < a0size; j++) {
+ double val=read<double>(ai,j);
+ if(val > max) max=val;
+ else if(val < min) min=val;
+ }
+ }
+
+ double step=(max == min) ? 0.0 : (Psize-1)/(max-min);
+
+ beginImage(ncomponents*a0size*asize);
+ for(size_t i=0; i < asize; i++) {
+ array *ai=read<array *>(a,i);
+ for(size_t j=0; j < a0size; j++) {
+ double val=read<double>(ai,j);
+ size_t index=(size_t) ((val-min)*step+0.5);
+ pen *p=read<pen *>(P,index < Psize ? index : Psize-1);
+ p->convert();
+ if(!p->promote(colorspace))
+ reportError(inconsistent);
+ write(p,ncomponents);
+ }
+ }
+ endImage(antialias,a0size,asize,ncomponents);
+}
+
+void psfile::image(const array& a, bool antialias)
+{
+ size_t asize=a.size();
+ if(asize == 0) return;
+
+ array *a0=read<array *>(a,0);
+ size_t a0size=a0->size();
+ if(a0size == 0) return;
+
+ setfirstopacity(*a0);
+
+ ColorSpace colorspace=maxcolorspace2(a);
+ checkColorSpace(colorspace);
+
+ size_t ncomponents=ColorComponents[colorspace];
+
+ imageheader(a0size,asize,colorspace);
+
+ beginImage(ncomponents*a0size*asize);
+ for(size_t i=0; i < asize; i++) {
+ array *ai=read<array *>(a,i);
+ for(size_t j=0; j < a0size; j++) {
+ pen *p=read<pen *>(ai,j);
+ p->convert();
+ if(!p->promote(colorspace))
+ reportError(inconsistent);
+ write(p,ncomponents);
+ }
+ }
+ endImage(antialias,a0size,asize,ncomponents);
+}
+
+void psfile::outImage(bool antialias, size_t width, size_t height,
+ size_t ncomponents)
+{
+ if(antialias) dealias(buffer,width,height,ncomponents);
+ if(settings::getSetting<Int>("level") >= 3)
+ writeCompressed(buffer,count);
+ else {
+ encode85 e(out);
+ for(size_t i=0; i < count; ++i)
+ e.put(buffer[i]);
+ }
+}
+
+void psfile::rawimage(unsigned char *a, size_t width, size_t height,
+ bool antialias)
+{
+ pen p(0.0,0.0,0.0);
+ p.convert();
+ ColorSpace colorspace=p.colorspace();
+ checkColorSpace(colorspace);
+
+ size_t ncomponents=ColorComponents[colorspace];
+
+ imageheader(width,height,colorspace);
+
+ count=ncomponents*width*height;
+ if(colorspace == RGB) {
+ buffer=a;
+ outImage(antialias,width,height,ncomponents);
+ } else {
+ beginImage(count);
+ if(antialias)
+ dealias(a,width,height,ncomponents,true,colorspace);
+ else {
+ size_t height3=3*height;
+ for(size_t i=0; i < width; ++i) {
+ unsigned char *ai=a+height3*i;
+ for(size_t j=0; j < height; ++j) {
+ unsigned char *aij=ai+3*j;
+ writefromRGB(aij[0],aij[1],aij[2],colorspace,ncomponents);
+ }
+ }
+ }
+ endImage(false,width,height,ncomponents);
+ }
+}
+
+} //namespace camp
diff --git a/Build/source/utils/asymptote/psfile.h b/Build/source/utils/asymptote/psfile.h
new file mode 100644
index 00000000000..d68e56e2619
--- /dev/null
+++ b/Build/source/utils/asymptote/psfile.h
@@ -0,0 +1,358 @@
+/*****
+ * psfile.h
+ * Andy Hammerlindl 2002/06/10
+ *
+ * Encapsulates the writing of commands to a PostScript file.
+ * Allows identification and removal of redundant commands.
+ *****/
+
+#ifndef PSFILE_H
+#define PSFILE_H
+
+#include <fstream>
+#include <iomanip>
+#include <sstream>
+
+#include "pair.h"
+#include "path.h"
+#include "bbox.h"
+#include "pen.h"
+#include "array.h"
+
+namespace camp {
+
+inline void BoundingBox(std::ostream& s, const bbox& box)
+{
+ s << "%%BoundingBox: " << std::setprecision(0) << std::fixed
+ << box.LowRes() << newl;
+ s.unsetf(std::ios::fixed);
+ s << "%%HiResBoundingBox: " << std::setprecision(9) << box << newl;
+}
+
+// An ASCII85Encode filter.
+class encode85 {
+ ostream *out;
+ int tuple;
+ int pos;
+ int count;
+ static const int width=72;
+public:
+ encode85(ostream *out) : out(out), tuple(0), pos(0), count(0) {}
+
+ ~encode85() {
+ if(count > 0)
+ encode(tuple, count);
+ if(pos+2 > width)
+ *out << '\n';
+ *out << "~>\n";
+ }
+private:
+ void encode(unsigned int tuple, int count) {
+ unsigned char buf[5], *s=buf;
+ int i=5;
+ do {
+ *s++=tuple % 85;
+ tuple /= 85;
+ } while(--i > 0);
+ i=count;
+ do {
+ *out << (unsigned char) (*--s + '!');
+ if(pos++ >= width) {
+ pos=0;
+ *out << '\n';
+ }
+ } while(i-- > 0);
+ }
+
+public:
+ void put(unsigned char c) {
+ switch (count++) {
+ case 0:
+ tuple |= (c << 24);
+ break;
+ case 1:
+ tuple |= (c << 16);
+ break;
+ case 2:
+ tuple |= (c << 8);
+ break;
+ case 3:
+ tuple |= c;
+ if(tuple == 0) {
+ *out << 'z';
+ if(pos++ >= width) {
+ pos=0;
+ *out << '\n';
+ }
+ } else
+ encode(tuple, count);
+ tuple=0;
+ count=0;
+ break;
+ }
+ }
+};
+
+class psfile {
+ string filename;
+ bool pdfformat; // Is final output format PDF?
+ bool pdf; // Output direct PDF?
+ bool transparency; // Is transparency used?
+ unsigned char *buffer;
+ size_t count;
+ mem::stack<pen> pens;
+
+ void writeHex(pen *p, size_t ncomponents);
+ void write(pen *p, size_t ncomponents);
+ void writefromRGB(unsigned char r, unsigned char g, unsigned char b,
+ ColorSpace colorspace, size_t ncomponents);
+
+ void writeCompressed(const unsigned char *a, size_t size);
+ void dealias(unsigned char *a, size_t width, size_t height, size_t n,
+ bool convertrgb=false, ColorSpace colorspace=DEFCOLOR);
+
+ void beginHex() {
+ out->setf(std::ios::hex,std::ios::basefield);
+ out->fill('0');
+ }
+
+ void endHex() {
+ out->setf(std::ios::dec,std::ios::basefield);
+ out->fill();
+ *out << ">" << endl;
+ }
+
+ void beginImage(size_t n) {
+ buffer=new unsigned char[n];
+ count=0;
+ }
+
+ void outImage(bool antialias, size_t width, size_t height,
+ size_t ncomponents);
+
+ void endImage(bool antialias, size_t width, size_t height,
+ size_t ncomponents) {
+ outImage(antialias,width,height,ncomponents);
+ delete[] buffer;
+ }
+
+ void writeByte(unsigned char n) {
+ buffer[count++]=n;
+ }
+
+ void write2(unsigned n) {
+ *out << std::setw(2) << n;
+ }
+
+protected:
+ pen lastpen;
+ std::ostream *out;
+
+public:
+ psfile(const string& filename, bool pdfformat);
+
+ psfile() {pdf=settings::pdf(settings::getSetting<string>("tex"));}
+
+ ~psfile();
+
+ void BoundingBox(const bbox& box) {
+ camp::BoundingBox(*out,box);
+ }
+
+ void prologue(const bbox& box);
+ void epilogue();
+ void header();
+
+ void close();
+
+ void write(double x) {
+ *out << " " << x;
+ }
+
+ void writenewl() {
+ *out << newl;
+ }
+
+ bool Transparency() {
+ return transparency;
+ }
+
+ void write(pair z) {
+ *out << " " << z.getx() << " " << z.gety();
+ }
+
+ void write(transform t) {
+ if(!pdf) *out << "[";
+ *out << " " << t.getxx() << " " << t.getyx()
+ << " " << t.getxy() << " " << t.getyy()
+ << " " << t.getx() << " " << t.gety();
+ if(!pdf) *out << "]";
+ }
+
+ void resetpen() {
+ lastpen=pen(initialpen);
+ lastpen.convert();
+ }
+
+ void setcolor(const pen& p, const string& begin, const string& end);
+ void setopacity(const pen& p);
+
+ void setpen(pen p);
+
+ void write(const pen& p);
+
+ void write(path p, bool newPath=true);
+
+ void newpath() {
+ if(!pdf) *out << "newpath";
+ }
+
+ void moveto(pair z) {
+ write(z);
+ if(pdf) *out << " m" << newl;
+ else *out << " moveto" << newl;
+ }
+
+ void lineto(pair z) {
+ write(z);
+ if(pdf) *out << " l" << newl;
+ else *out << " lineto" << newl;
+ }
+
+ void curveto(pair zp, pair zm, pair z1) {
+ write(zp); write(zm); write(z1);
+ if(pdf) *out << " c" << newl;
+ else *out << " curveto" << newl;
+ }
+
+ void closepath() {
+ if(pdf) *out << "h" << newl;
+ else *out << "closepath" << newl;
+ }
+
+ void stroke() {
+ if(pdf) *out << "S" << newl;
+ else *out << "stroke" << newl;
+ }
+
+ void strokepath() {
+ if(pdf) reportError("PDF does not support strokepath");
+ else *out << "strokepath" << newl;
+ }
+
+ void fill(const pen &p) {
+ if(p.evenodd()) {
+ if(pdf) *out << "f*" << newl;
+ else *out << "eofill" << newl;
+ } else {
+ if(pdf) *out << "f" << newl;
+ else *out << "fill" << newl;
+ }
+ }
+
+ void clip(const pen &p) {
+ if(p.evenodd()) {
+ if(pdf) *out << "W* n" << newl;
+ else *out << "eoclip" << newl;
+ } else {
+ if(pdf) *out << "W n" << newl;
+ else *out << "clip" << newl;
+ }
+ }
+
+ void checkLevel() {
+ int n=settings::getSetting<Int>("level");
+ if(n < 3)
+ reportError("PostScript shading requires -level 3");
+ }
+
+ void latticeshade(const vm::array& a, const bbox& b);
+
+ void gradientshade(bool axial, const ColorSpace& colorspace,
+ const pen& pena, const pair& a, double ra,
+ const pen& penb, const pair& b, double rb);
+
+ void gouraudshade(const vm::array& pens, const vm::array& vertices,
+ const vm::array& edges);
+ void tensorshade(const vm::array& pens, const vm::array& boundaries,
+ const vm::array& z);
+
+ void imageheader(size_t width, size_t height, ColorSpace colorspace);
+
+ void image(const vm::array& a, const vm::array& p, bool antialias);
+ void image(const vm::array& a, bool antialias);
+ void rawimage(unsigned char *a, size_t width, size_t height, bool antialias);
+
+ void gsave(bool tex=false) {
+ if(pdf) *out << "q";
+ else *out << "gsave";
+ if(!tex) *out << newl;
+ pens.push(lastpen);
+ }
+
+ void grestore(bool tex=false) {
+ if(pens.size() < 1)
+ reportError("grestore without matching gsave");
+ lastpen=pens.top();
+ pens.pop();
+ if(pdf) *out << "Q";
+ else *out << "grestore";
+ if(!tex) *out << newl;
+ }
+
+ void translate(pair z) {
+ if(pdf) *out << " 1 0 0 1 " << newl;
+ write(z);
+ if(pdf) *out << " cm" << newl;
+ *out << " translate" << newl;
+ }
+
+ // Multiply on a transform to the transformation matrix.
+ void concat(transform t) {
+ if(t.isIdentity()) return;
+ write(t);
+ if(pdf) *out << " cm" << newl;
+ else *out << " concat" << newl;
+ }
+
+ void verbatimline(const string& s) {
+ *out << s << newl;
+ }
+
+ void verbatim(const string& s) {
+ *out << s;
+ }
+
+ // Determine shading and image transparency based on first pen.
+ void setfirstopacity(const vm::array& pens) {
+ if(pens.size() > 0) {
+ pen *p=vm::read<pen *>(pens,0);
+ setopacity(*p);
+ }
+ }
+
+ ColorSpace maxcolorspace(const vm::array& pens) {
+ ColorSpace colorspace=DEFCOLOR;
+ size_t size=pens.size();
+ for(size_t i=0; i < size; i++) {
+ pen *p=vm::read<pen *>(pens,i);
+ p->convert();
+ colorspace=max(colorspace,p->colorspace());
+ }
+ return colorspace;
+ }
+
+ ColorSpace maxcolorspace2(const vm::array& penarray) {
+ ColorSpace colorspace=DEFCOLOR;
+ size_t size=penarray.size();
+ for(size_t i=0; i < size; i++)
+ colorspace=max(colorspace,
+ maxcolorspace(vm::read<vm::array>(penarray,i)));
+ return colorspace;
+ }
+
+};
+
+} //namespace camp
+
+#endif
diff --git a/Build/source/utils/asymptote/quaternion.cc b/Build/source/utils/asymptote/quaternion.cc
new file mode 100644
index 00000000000..f492137c267
--- /dev/null
+++ b/Build/source/utils/asymptote/quaternion.cc
@@ -0,0 +1,242 @@
+/***********************************************************************
+
+ 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@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();
+
+ s = (float) cos( DEG2RAD( f ) / 2.0 );
+
+ v = axis * (float) sin(DEG2RAD(f) / 2.0);
+}
+
+/********************************************** 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
+{
+ return (float) RAD2DEG( 2.0 * acos( s ) );
+}
+
+/********************************************* 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 );
+}
diff --git a/Build/source/utils/asymptote/quaternion.h b/Build/source/utils/asymptote/quaternion.h
new file mode 100644
index 00000000000..f58a7445e52
--- /dev/null
+++ b/Build/source/utils/asymptote/quaternion.h
@@ -0,0 +1,114 @@
+/****************************************************************************
+
+ quaternion.h - 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
+
+*****************************************************************************/
+
+#ifndef GLUI_QUATERNION_H
+#define GLUI_QUATERNION_H
+
+#include "algebra3.h"
+#include <cstdio>
+
+/* this line defines a new type: pointer to a function which returns a */
+/* float and takes as argument a float */
+typedef float (*V_FCT_PTR)(float);
+
+/****************************************************************
+ * Quaternion *
+ ****************************************************************/
+
+class quat
+{
+ /*protected: */
+public:
+
+ vec3 v; /* vector component */
+ float s; /* scalar component */
+
+ /*public: */
+
+ /* Constructors */
+
+ quat();
+ quat(float x, float y, float z, float w);
+ quat(const vec3 &v, float s);
+ quat(float s, const vec3 &v);
+ quat(const float *d); /* copy from four-element float array */
+ quat(const double *f); /* copy from four-element double array */
+ quat(const quat &q); /* copy from other quat */
+
+ /* Assignment operators */
+
+ quat &operator = (const quat &v); /* assignment of a quat */
+ quat &operator += (const quat &v); /* incrementation by a quat */
+ quat &operator -= (const quat &v); /* decrementation by a quat */
+ quat &operator *= (float d); /* multiplication by a constant */
+ quat &operator /= (float d); /* division by a constant */
+
+ /* special functions */
+
+ float length() const; /* length of a quat */
+ float length2() const; /* squared length of a quat */
+ quat &normalize(); /* normalize a quat */
+ quat &apply(V_FCT_PTR fct); /* apply a func. to each component */
+ vec3 xform(const vec3 &v ); /* q*v*q-1 */
+ mat4 to_mat4() const;
+ void set_angle(float f); /* set rot angle (degrees) */
+ void scale_angle(float f); /* scale rot angle (degrees) */
+ float get_angle() const; /* set rot angle (degrees) */
+ vec3 get_axis() const; /* get axis */
+
+ void print( FILE *file, const char *name ) const; /* print to a file */
+
+ float &operator [] (int i); /* indexing */
+ const float &operator [] (int i) const; /* indexing */
+
+ void set(float x, float y, float z); /* set quat */
+ void set(const vec3 &v, float s); /* set quat */
+
+ /* friends */
+
+ friend quat operator - (const quat &v); /* -q1 */
+ friend quat operator + (const quat &a, const quat &b); /* q1 + q2 */
+ friend quat operator - (const quat &a, const quat &b); /* q1 - q2 */
+ friend quat operator * (const quat &a, float d); /* q1 * 3.0 */
+ friend quat operator * (float d, const quat &a); /* 3.0 * q1 */
+ friend quat operator * (const quat &a, const quat &b); /* q1 * q2 */
+ friend quat operator / (const quat &a, float d); /* q1 / 3.0 */
+ friend int operator == (const quat &a, const quat &b); /* q1 == q2 ? */
+ friend int operator != (const quat &a, const quat &b); /* q1 != q2 ? */
+ friend void swap(quat &a, quat &b); /* swap q1 &q2 */
+ /*friend quat min(const quat &a, const quat &b); -- min(q1, q2) */
+ /*friend quat max(const quat &a, const quat &b); -- max(q1, q2) */
+ friend quat prod(const quat &a, const quat &b); /* term by term mult*/
+};
+
+/* Utility functions */
+
+quat quat_identity(); /* Returns quaternion identity element */
+quat quat_slerp(const quat &from, const quat &to, float t);
+
+#endif
diff --git a/Build/source/utils/asymptote/record.cc b/Build/source/utils/asymptote/record.cc
new file mode 100644
index 00000000000..b19083d51d4
--- /dev/null
+++ b/Build/source/utils/asymptote/record.cc
@@ -0,0 +1,76 @@
+/*****
+ * record.cc
+ * Tom Prince 2004/07/15
+ *
+ * The type for records and modules in the language.
+ *****/
+
+#include "record.h"
+#include "inst.h"
+#include "runtime.h"
+#include "coder.h"
+
+
+
+namespace types {
+
+record::record(symbol *name, frame *level)
+ : ty(ty_record),
+ name(name),
+ level(level),
+ init(new vm::lambda),
+ e()
+{
+ assert(init);
+}
+
+record::~record()
+{}
+
+record *record::newRecord(symbol *id, bool statically)
+{
+ frame *underlevel = getLevel(statically);
+ assert(underlevel);
+
+ frame *level = new frame(underlevel, 0);
+
+ record *r = new record(id, level);
+ return r;
+}
+
+// Initialize to null by default.
+trans::access *record::initializer() {
+ static trans::bltinAccess a(run::pushNullRecord);
+ return &a;
+}
+
+dummyRecord::dummyRecord(symbol *name)
+ : record(name, new frame(0,0))
+{
+ // Encode the instructions to put an placeholder instance of the record
+ // on the stack.
+ trans::coder c(this, 0);
+ c.closeRecord();
+}
+
+dummyRecord::dummyRecord(string s)
+ : record (symbol::trans(s), new frame(0,0))
+{
+ // Encode the instructions to put an placeholder instance of the record
+ // on the stack.
+ trans::coder c(this, 0);
+ c.closeRecord();
+}
+
+void dummyRecord::add(string name, ty *t, trans::access *a,
+ trans::permission perm) {
+ e.addVar(symbol::trans(name),
+ new trans::varEntry(t, a, perm, this, this, position()));
+}
+
+void dummyRecord::add(string name, function *t, vm::bltin f,
+ trans::permission perm) {
+ add(name, t, new trans::bltinAccess(f), perm);
+}
+
+} // namespace types
diff --git a/Build/source/utils/asymptote/record.h b/Build/source/utils/asymptote/record.h
new file mode 100644
index 00000000000..4e7e66a3b92
--- /dev/null
+++ b/Build/source/utils/asymptote/record.h
@@ -0,0 +1,128 @@
+/*****
+ * record.h
+ * Andy Hammerlindl 2003/07/09
+ *
+ * The type for records and modules in the language.
+ *****/
+
+#ifndef RECORD_H
+#define RECORD_H
+
+#include "types.h"
+#include "env.h"
+#include "frame.h"
+#include "access.h"
+
+namespace vm {
+struct lambda;
+}
+
+using trans::frame;
+using trans::protoenv;
+using trans::varEntry;
+using trans::tyEntry;
+
+namespace types {
+
+struct record : public ty {
+ // The base name of this type.
+ symbol *name;
+
+ // The frame. Like a frame for a function, it allocates the accesses
+ // for fields and specifies the size of the record.
+ frame *level;
+
+ // The runtime representation of the record used by the virtual machine.
+ vm::lambda *init;
+
+public:
+ // The name bindings for fields of the record.
+ protoenv e;
+
+ // These are name bindings that should be added to the enclosing environment
+ // after translation of the record is completed. Constructors implicitly
+ // defined by "operator init" are stored here.
+ protoenv postdefenv;
+
+ record(symbol *name, frame *level);
+ ~record();
+
+ symbol *getName()
+ {
+ return name;
+ }
+
+ bool isReference() {
+ return true;
+ }
+
+ size_t hash() {
+ // Use the pointer, as two records are equivalent only if they are the
+ // same object.
+ return (size_t)this;
+ }
+
+ // Initialize to null by default.
+ trans::access *initializer();
+
+ frame *getLevel(bool statically = false)
+ {
+ if (statically) {
+ frame *f=level->getParent();
+ return f ? f : level;
+ }
+ else
+ return level;
+ }
+
+ vm::lambda *getInit()
+ {
+ return init;
+ }
+
+ // Allocates a new dynamic field in the record.
+ trans::access *allocField(bool statically)
+ {
+ frame *underlevel = getLevel(statically);
+ assert(underlevel);
+ return underlevel->allocLocal();
+ }
+
+ // Create a statically enclosed record from this record.
+ record *newRecord(symbol *id, bool statically);
+
+ void print(ostream& out) const
+ {
+ out << *name;
+ }
+
+ void debug(ostream& out) const
+ {
+ out << "struct " << *name << endl;
+ out << "types:" << endl;
+ out << "re-implement" << endl;
+ //out << te;
+ out << "fields: " << endl;
+ out << "re-implement" << endl;
+ //out << ve;
+ }
+};
+
+// A record that is being used just for its fields and types, and has no real
+// initializer. This is for modules such as settings that are built into the
+// language.
+class dummyRecord : public record {
+public:
+ dummyRecord(symbol *name);
+ dummyRecord(string s);
+
+ // Convenient functions for adding fields.
+ void add(string name, ty *t, trans::access *a,
+ trans::permission perm=trans::PUBLIC);
+ void add(string name, function *t, vm::bltin f,
+ trans::permission perm=trans::PUBLIC);
+};
+
+} //namespace types
+
+#endif
diff --git a/Build/source/utils/asymptote/refaccess.cc b/Build/source/utils/asymptote/refaccess.cc
new file mode 100644
index 00000000000..32bc6607356
--- /dev/null
+++ b/Build/source/utils/asymptote/refaccess.cc
@@ -0,0 +1,54 @@
+/*****
+ * refaccess.cc
+ * Andy Hammerlindl 2005/11/28
+ *
+ * An access which refers to a variable or other object in C++.
+ *****/
+
+#include "refaccess.h"
+
+namespace trans {
+
+using vm::item;
+using vm::stack;
+using vm::pop;
+
+/* itemRefAccess */
+void itemPointerRead(stack *s) {
+ item *p=pop<item *>(s);
+ s->push(*p);
+}
+
+void itemPointerWrite(stack *s) {
+ item *p=pop<item *>(s);
+ item value=pop(s);
+ *p=value;
+ s->push(value);
+}
+
+void itemRefAccess::encode(action act, position, coder &e)
+{
+ e.encode(inst::constpush, (item)ref);
+
+ switch (act) {
+ case READ:
+ e.encode(inst::builtin, itemPointerRead);
+ break;
+ case WRITE:
+ e.encode(inst::builtin, itemPointerWrite);
+ break;
+ case CALL:
+ e.encode(inst::builtin, itemPointerRead);
+ e.encode(inst::popcall);
+ break;
+ };
+}
+
+void itemRefAccess::encode(action act, position pos, coder &e, frame *)
+{
+ // Get rid of the useless top frame.
+ e.encode(inst::pop);
+ encode(act, pos, e);
+}
+
+}
diff --git a/Build/source/utils/asymptote/refaccess.h b/Build/source/utils/asymptote/refaccess.h
new file mode 100644
index 00000000000..c848f8f171d
--- /dev/null
+++ b/Build/source/utils/asymptote/refaccess.h
@@ -0,0 +1,86 @@
+/*****
+ * refaccess.h
+ * Andy Hammerlindl 2003/12/03
+ *
+ * An access which refers to a variable or other object in C++.
+ *****/
+
+#ifndef REFACCESS_H
+#define REFACCESS_H
+
+#include "access.h"
+#include "inst.h"
+#include "coder.h"
+#include "stack.h"
+
+namespace trans {
+
+// Access refers to a piece of data, represented by an item, somewhere in the
+// C++ code.
+class itemRefAccess : public access {
+ vm::item *ref;
+
+public:
+ itemRefAccess(vm::item *ref)
+ : ref(ref) {}
+
+ void encode(action act, position pos, coder &e);
+ void encode(action act, position pos, coder &e, frame *);
+};
+
+// Access refers to an arbitrary piece of data of type T.
+template <class T>
+class refAccess : public access {
+ T *ref;
+
+public:
+ refAccess(T *ref)
+ : ref(ref) {}
+
+ void encode(action act, position pos, coder &e);
+ void encode(action act, position pos, coder &e, frame *);
+};
+
+template <class T>
+void pointerRead(vm::stack *s) {
+ T *ptr=vm::pop<T *>(s);
+ s->push(*ptr);
+}
+
+template <class T>
+void pointerWrite(vm::stack *s) {
+ T *ptr=vm::pop<T *>(s);
+ T value=vm::pop<T>(s);
+ *ptr=value;
+ s->push(value);
+}
+
+template <class T>
+void refAccess<T>::encode(action act, position, coder &e)
+{
+ e.encode(vm::inst::constpush, (vm::item)ref);
+
+ switch (act) {
+ case READ:
+ e.encode(vm::inst::builtin, (bltin) pointerRead<T>);
+ break;
+ case WRITE:
+ e.encode(vm::inst::builtin, (bltin) pointerWrite<T>);
+ break;
+ case CALL:
+ e.encode(vm::inst::builtin, (bltin) pointerRead<T>);
+ e.encode(vm::inst::popcall);
+ break;
+ };
+}
+
+template <class T>
+void refAccess<T>::encode(action act, position pos, coder &e, frame *)
+{
+ // Get rid of the useless top frame.
+ e.encode(vm::inst::pop);
+ encode(act, pos, e);
+}
+
+}
+#endif
diff --git a/Build/source/utils/asymptote/rounding.h b/Build/source/utils/asymptote/rounding.h
new file mode 100644
index 00000000000..a0efe31dc4d
--- /dev/null
+++ b/Build/source/utils/asymptote/rounding.h
@@ -0,0 +1,87 @@
+/* GTS - Library for the manipulation of triangulated surfaces
+ * Copyright (C) 1999 Stéphane Popinet
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#ifdef HAVE_FPU_CONTROL_H
+# include <fpu_control.h>
+# ifdef _FPU_EXTENDED
+# if !defined(__alpha__) || !defined(__GLIBC__)
+# if defined(__arm__)
+ static fpu_control_t fpu_round_double = _FPU_DEFAULT;
+# else
+ static fpu_control_t fpu_round_double =
+ (_FPU_DEFAULT & ~ _FPU_EXTENDED)|_FPU_DOUBLE;
+# endif
+ static fpu_control_t fpu_init;
+# define FPU_ROUND_DOUBLE { _FPU_GETCW(fpu_init);\
+ _FPU_SETCW(fpu_round_double); }
+# define FPU_RESTORE {_FPU_SETCW(fpu_init);}
+# else /* __alpha__ && __GLIBC__ */
+# define FPU_ROUND_DOUBLE
+# define FPU_RESTORE
+# endif /* __alpha__ && __GLIBC__ */
+# else /* not FPU_EXTENDED */
+# define FPU_ROUND_DOUBLE
+# define FPU_RESTORE
+# endif /* not FPU_EXTENDED */
+#else /* not HAVE_FPU_CONTROL_H */
+# ifdef __FreeBSD__
+# include <floatingpoint.h>
+# define FPU_ROUND_DOUBLE (fpsetprec(FP_PD))
+# define FPU_RESTORE (fpsetprec(FP_PE))
+# else /* not __FreeBSD__ */
+# ifdef WIN32
+# ifdef _MSC_VER
+# include <float.h>
+ static unsigned int fpu_init;
+# define FPU_ROUND_DOUBLE (fpu_init = _controlfp (0, 0),\
+ _controlfp (_PC_53, MCW_PC))
+# define FPU_RESTORE (_controlfp (fpu_init, 0xfffff))
+# elif __MINGW32__
+# include <float.h>
+ static unsigned int fpu_init;
+# define FPU_ROUND_DOUBLE (fpu_init = _controlfp (0, 0),\
+ _controlfp (_PC_53, _MCW_PC))
+# define FPU_RESTORE (_controlfp (fpu_init, 0xfffff))
+# else /* not _MSC_VER or __MINGW32__ */
+# error "You need MSVC or MinGW for the Win32 version"
+# endif /* not _MSC_VER or __MINGW32__ */
+# else /* not WIN32 */
+# ifdef __CYGWIN__
+ typedef unsigned int fpu_control_t __attribute__ ((__mode__ (__HI__)));
+ static fpu_control_t fpu_round_double = 0x027f;
+ static fpu_control_t fpu_init;
+# define _FPU_GETCW(cw) __asm__ ("fnstcw %0" : "=m" (*&cw))
+# define _FPU_SETCW(cw) __asm__ ("fldcw %0" : : "m" (*&cw))
+# define FPU_ROUND_DOUBLE { _FPU_GETCW(fpu_init);\
+ _FPU_SETCW(fpu_round_double); }
+# define FPU_RESTORE { _FPU_SETCW(fpu_init);}
+# else /* not __CYGWIN__ */
+# ifdef CPP_HAS_WARNING
+# warning "Unknown CPU: assuming default double precision rounding"
+# endif /* CPP_HAS_WARNING */
+# define FPU_ROUND_DOUBLE
+# define FPU_RESTORE
+# endif /* not __CYGWIN__ */
+# endif /* not WIN32 */
+# endif /* not __FreeBSD__ */
+#endif /* not HAVE_FPU_CONTROL_H */
diff --git a/Build/source/utils/asymptote/runtime.cc b/Build/source/utils/asymptote/runtime.cc
new file mode 100644
index 00000000000..90b78b7302c
--- /dev/null
+++ b/Build/source/utils/asymptote/runtime.cc
@@ -0,0 +1,9027 @@
+/***** Autogenerated from runtime.in; changes will be overwritten *****/
+
+#line 1 "runtime.in"
+/*****
+ * runtime.in
+ * Tom Prince 2005/4/15
+ *
+ * Generate the runtime functions used by the vm::stack machine.
+ *
+ *****/
+
+/* Autogenerated routines are specified like this (separated by a formfeed):
+ type asyname:cname(cparams)
+ {
+ C code
+ }
+
+*/
+
+// Use Void f() instead of void f() to force an explicit Stack argument.
+
+
+#line 63 "runtime.in"
+#include <cfloat>
+#include <time.h>
+#include <sys/times.h>
+#include <locale.h>
+
+#include "angle.h"
+#include "pair.h"
+#include "triple.h"
+#include "transform.h"
+#include "path.h"
+#include "path3.h"
+#include "pen.h"
+#include "guide.h"
+#include "picture.h"
+#include "drawpath.h"
+#include "drawpath3.h"
+#include "drawsurface.h"
+#include "drawfill.h"
+#include "drawclipbegin.h"
+#include "drawclipend.h"
+#include "drawlabel.h"
+#include "drawverbatim.h"
+#include "drawgsave.h"
+#include "drawgrestore.h"
+#include "drawlayer.h"
+#include "drawimage.h"
+#include "drawgroup.h"
+#include "fileio.h"
+#include "genv.h"
+#include "builtin.h"
+#include "texfile.h"
+#include "pipestream.h"
+#include "parser.h"
+#include "stack.h"
+#include "util.h"
+#include "locate.h"
+#include "mathop.h"
+#include "callable.h"
+#include "stm.h"
+#include "lexical.h"
+#include "process.h"
+#include "arrayop.h"
+#include "predicates.h"
+#include "Delaunay.h"
+
+#ifdef HAVE_LIBFFTW3
+#include "fftw++.h"
+#endif
+
+#if defined(HAVE_LIBREADLINE) && defined(HAVE_LIBCURSES)
+#include <readline/readline.h>
+#include <readline/history.h>
+#endif
+
+#if defined(USEGC) && defined(GC_DEBUG) && defined(GC_BACKTRACE)
+ extern "C" {
+ void *GC_generate_random_valid_address(void);
+ void GC_debug_print_heap_obj_proc(void *);
+ }
+#endif
+
+using namespace vm;
+using namespace camp;
+using namespace settings;
+
+namespace run {
+using camp::pair;
+using vm::array;
+using vm::frame;
+using vm::stack;
+using camp::transform;
+using absyntax::runnable;
+
+typedef double real;
+
+#define CURRENTPEN processData().currentpen
+
+typedef array boolarray;
+typedef array Intarray;
+typedef array Intarray2;
+typedef array realarray;
+typedef array realarray2;
+typedef array pairarray;
+typedef array pairarray2;
+typedef array triplearray;
+typedef array triplearray2;
+typedef array patharray;
+typedef array patharray2;
+typedef array guidearray;
+typedef array transformarray;
+typedef array penarray;
+typedef array penarray2;
+typedef array stringarray;
+typedef array stringarray2;
+
+typedef callable callableBp;
+typedef callable callableReal;
+typedef callable callableTransform;
+}
+
+using vm::array;
+using types::function;
+
+#define PRIMITIVE(name,Name,asyName) using types::prim##Name;
+#include <primitives.h>
+#undef PRIMITIVE
+
+using types::boolArray;
+using types::IntArray;
+using types::IntArray2;
+using types::realArray;
+using types::realArray2;
+using types::pairArray;
+using types::pairArray2;
+using types::tripleArray;
+using types::tripleArray2;
+using types::pathArray;
+using types::pathArray2;
+using types::guideArray;
+using types::transformArray;
+using types::penArray;
+using types::penArray2;
+using types::stringArray;
+using types::stringArray2;
+using types::formal;
+
+function *voidFunction()
+{
+ return new function(primVoid());
+}
+
+function *breakpointFunction()
+{
+ return new function(primString(),primString(),primInt(),primInt(),
+ primCode());
+}
+
+function *realRealFunction()
+{
+ return new function(primReal(),primReal());
+}
+
+function *transformFunction()
+{
+ return new function(primTransform());
+}
+
+function *realTripleFunction()
+{
+ return new function(primReal(),primTriple());
+}
+
+const size_t camp::ColorComponents[]={0,0,1,3,4,0};
+
+namespace vm {
+}
+
+namespace run {
+
+const char *invalidargument="invalid argument";
+const char *arrayempty="cannot take min or max of empty array";
+
+// Return the factorial of a non-negative integer using a lookup table.
+Int factorial(Int n)
+{
+ static Int *table;
+ static Int size=0;
+ if(size == 0) {
+ Int f=1;
+ size=2;
+ while(f <= Int_MAX/size)
+ f *= (size++);
+ table=new Int[size];
+ table[0]=f=1;
+ for(Int i=1; i < size; ++i) {
+ f *= i;
+ table[i]=f;
+ }
+ }
+ if(n >= size) integeroverflow(0);
+ return table[n];
+}
+
+static inline Int Round(double x)
+{
+ return Int(x+((x >= 0) ? 0.5 : -0.5));
+}
+
+inline Int sgn(double x)
+{
+ return (x > 0.0 ? 1 : (x < 0.0 ? -1 : 0));
+}
+
+void outOfBounds(const char *op, size_t len, Int n)
+{
+ ostringstream buf;
+ buf << op << " array of length " << len << " with out-of-bounds index " << n;
+ error(buf);
+}
+
+inline item& arrayRead(array *a, Int n)
+{
+ size_t len=checkArray(a);
+ bool cyclic=a->cyclic();
+ if(cyclic && len > 0) n=imod(n,len);
+ else if(n < 0 || n >= (Int) len) outOfBounds("reading",len,n);
+ return (*a)[(unsigned) n];
+}
+
+// Helper function to create deep arrays.
+static array* deepArray(Int depth, Int *dims)
+{
+ assert(depth > 0);
+
+ if (depth == 1) {
+ return new array(dims[0]);
+ } else {
+ Int length = dims[0];
+ depth--; dims++;
+
+ array *a = new array(length);
+
+ for (Int index = 0; index < length; index++) {
+ (*a)[index] = deepArray(depth, dims);
+ }
+ return a;
+ }
+}
+
+array *nop(array *a)
+{
+ return a;
+}
+
+array *Identity(Int n)
+{
+ size_t N=(size_t) n;
+ array *c=new array(N);
+ for(size_t i=0; i < N; ++i) {
+ array *ci=new array(N);
+ (*c)[i]=ci;
+ for(size_t j=0; j < N; ++j)
+ (*ci)[j]=0.0;
+ (*ci)[i]=1.0;
+ }
+ return c;
+}
+
+array *copyArray(array *a)
+{
+ size_t size=checkArray(a);
+ array *c=new array(size);
+ for(size_t i=0; i < size; i++)
+ (*c)[i]=(*a)[i];
+ return c;
+}
+
+inline size_t checkdimension(array *a, size_t dim)
+{
+ size_t size=checkArray(a);
+ if(dim && size != dim) {
+ ostringstream buf;
+ buf << "array of length " << dim << " expected" << endl;
+ error(buf);
+ }
+ return size;
+}
+
+double *copyArrayC(array *a, size_t dim=0)
+{
+ size_t size=checkdimension(a,dim);
+ double *c=new double[size];
+ for(size_t i=0; i < size; i++)
+ c[i]=read<double>(a,i);
+ return c;
+}
+
+triple *copyTripleArrayC(array *a, size_t dim=0)
+{
+ size_t size=checkdimension(a,dim);
+ triple *c=new triple[size];
+ for(size_t i=0; i < size; i++)
+ c[i]=read<triple>(a,i);
+ return c;
+}
+
+array *copyArray2(array *a)
+{
+ size_t size=checkArray(a);
+ array *c=new array(size);
+ for(size_t i=0; i < size; i++) {
+ array *ai=read<array*>(a,i);
+ size_t aisize=checkArray(ai);
+ array *ci=new array(aisize);
+ (*c)[i]=ci;
+ for(size_t j=0; j < aisize; j++)
+ (*ci)[j]=(*ai)[j];
+ }
+ return c;
+}
+
+array *copyArray3(array *a)
+{
+ size_t size=checkArray(a);
+ array *c=new array(size);
+ for(size_t i=0; i < size; i++) {
+ array *ai=read<array*>(a,i);
+ size_t aisize=checkArray(ai);
+ array *ci=new array(aisize);
+ (*c)[i]=ci;
+ for(size_t j=0; j < aisize; j++) {
+ array *aij=read<array*>(ai,j);
+ size_t aijsize=checkArray(aij);
+ array *cij=new array(aijsize);
+ (*ci)[j]=cij;
+ for(size_t k=0; k < aijsize; k++)
+ (*cij)[k]=(*aij)[k];
+ }
+ }
+ return c;
+}
+
+double *copyArray2C(array *a, bool square=true, size_t dim2=0)
+{
+ size_t n=checkArray(a);
+ size_t m=(square || n == 0) ? n : checkArray(read<array*>(a,0));
+ if(n > 0 && dim2 && m != dim2) {
+ ostringstream buf;
+ buf << "second matrix dimension must be " << dim2 << endl;
+ error(buf);
+ }
+
+ double *c=new double[n*m];
+ for(size_t i=0; i < n; i++) {
+ array *ai=read<array*>(a,i);
+ size_t aisize=checkArray(ai);
+ if(aisize == m) {
+ double *ci=c+i*m;
+ for(size_t j=0; j < m; j++)
+ ci[j]=read<double>(ai,j);
+ } else
+ error(square ? "matrix must be square" : "matrix must be rectangular");
+ }
+ return c;
+}
+
+static const char *incommensurate="Incommensurate matrices";
+static const char *singular="Singular matrix";
+static size_t *pivot,*Row,*Col;
+
+triple operator *(const array& t, const triple& v)
+{
+ size_t n=checkArray(&t);
+ if(n != 4) error(incommensurate);
+ array *t0=read<array*>(t,0);
+ array *t1=read<array*>(t,1);
+ array *t2=read<array*>(t,2);
+ array *t3=read<array*>(t,3);
+
+ if(checkArray(t0) != 4 || checkArray(t1) != 4 ||
+ checkArray(t2) != 4 || checkArray(t3) != 4)
+ error(incommensurate);
+
+ double x=v.getx();
+ double y=v.gety();
+ double z=v.getz();
+
+ double f=read<real>(t3,0)*x+read<real>(t3,1)*y+read<real>(t3,2)*z+
+ read<real>(t3,3);
+ if(f == 0.0) run::dividebyzero();
+ f=1.0/f;
+
+ return triple((read<real>(t0,0)*x+read<real>(t0,1)*y+read<real>(t0,2)*z+
+ read<real>(t0,3))*f,
+ (read<real>(t1,0)*x+read<real>(t1,1)*y+read<real>(t1,2)*z+
+ read<real>(t1,3))*f,
+ (read<real>(t2,0)*x+read<real>(t2,1)*y+read<real>(t2,2)*z+
+ read<real>(t2,3))*f);
+}
+
+triple multshiftless(const array& t, const triple& v)
+{
+ size_t n=checkArray(&t);
+ if(n != 4) error(incommensurate);
+ array *t0=read<array*>(t,0);
+ array *t1=read<array*>(t,1);
+ array *t2=read<array*>(t,2);
+ array *t3=read<array*>(t,3);
+
+ if(checkArray(t0) != 4 || checkArray(t1) != 4 ||
+ checkArray(t2) != 4 || checkArray(t3) != 4)
+ error(incommensurate);
+
+ double x=v.getx();
+ double y=v.gety();
+ double z=v.getz();
+
+ double f=read<real>(t3,0)*x+read<real>(t3,1)*y+read<real>(t3,2)*z+
+ read<real>(t3,3);
+ if(f == 0.0) run::dividebyzero();
+ f=1.0/f;
+
+ return triple((read<real>(t0,0)*x+read<real>(t0,1)*y+read<real>(t0,2)*z)*f,
+ (read<real>(t1,0)*x+read<real>(t1,1)*y+read<real>(t1,2)*z)*f,
+ (read<real>(t2,0)*x+read<real>(t2,1)*y+read<real>(t2,2)*z)*f);
+}
+
+static inline void inverseAllocate(size_t n)
+{
+ pivot=new size_t[n];
+ Row=new size_t[n];
+ Col=new size_t[n];
+}
+
+static inline void inverseDeallocate()
+{
+ delete[] pivot;
+ delete[] Row;
+ delete[] Col;
+}
+
+void writestring(stack *s)
+{
+ callable *suffix=pop<callable *>(s,NULL);
+ string S=pop<string>(s);
+ vm::item it=pop(s);
+ bool defaultfile=isdefault(it);
+ camp::file *f=defaultfile ? &camp::Stdout : vm::get<camp::file*>(it);
+ if(!f->isOpen()) return;
+ if(S != "") f->write(S);
+ if(f->text()) {
+ if(suffix) {
+ s->push(f);
+ suffix->call(s);
+ } else if(defaultfile) f->writeline();
+ }
+}
+
+void checkSquare(array *a)
+{
+ size_t n=checkArray(a);
+ for(size_t i=0; i < n; i++)
+ if(checkArray(read<array*>(a,i)) != n)
+ error("matrix a must be square");
+}
+
+// Crout's algorithm for computing the LU decomposition of a square matrix.
+// cf. routine ludcmp (Press et al., Numerical Recipes, 1991).
+Int LUdecompose(double *a, size_t n, size_t* index, bool warn=true)
+{
+ double *vv=new double[n];
+ Int swap=1;
+ for(size_t i=0; i < n; ++i) {
+ double big=0.0;
+ double *ai=a+i*n;
+ for(size_t j=0; j < n; ++j) {
+ double temp=fabs(ai[j]);
+ if(temp > big) big=temp;
+ }
+ if(big == 0.0) {
+ delete[] vv;
+ if(warn) error(singular);
+ else return 0;
+ }
+ vv[i]=1.0/big;
+ }
+ for(size_t j=0; j < n; ++j) {
+ for(size_t i=0; i < j; ++i) {
+ double *ai=a+i*n;
+ double sum=ai[j];
+ for(size_t k=0; k < i; ++k) {
+ sum -= ai[k]*a[k*n+j];
+ }
+ ai[j]=sum;
+ }
+ double big=0.0;
+ size_t imax=j;
+ for(size_t i=j; i < n; ++i) {
+ double *ai=a+i*n;
+ double sum=ai[j];
+ for(size_t k=0; k < j; ++k)
+ sum -= ai[k]*a[k*n+j];
+ ai[j]=sum;
+ double temp=vv[i]*fabs(sum);
+ if(temp >= big) {
+ big=temp;
+ imax=i;
+ }
+ }
+ double *aj=a+j*n;
+ double *aimax=a+imax*n;
+ if(j != imax) {
+ for(size_t k=0; k < n; ++k) {
+ double temp=aimax[k];
+ aimax[k]=aj[k];
+ aj[k]=temp;
+ }
+ swap *= -1;
+ vv[imax]=vv[j];
+ }
+ if(index)
+ index[j]=imax;
+ if(j != n) {
+ double denom=aj[j];
+ if(denom == 0.0) {
+ delete[] vv;
+ if(warn) error(singular);
+ else return 0;
+ }
+ for(size_t i=j+1; i < n; ++i)
+ a[i*n+j] /= denom;
+ }
+ }
+ delete[] vv;
+ return swap;
+}
+
+void dividebyzero(size_t i)
+{
+ ostringstream buf;
+ if(i > 0) buf << "array element " << i << ": ";
+ buf << "Divide by zero";
+ error(buf);
+}
+
+void integeroverflow(size_t i)
+{
+ ostringstream buf;
+ if(i > 0) buf << "array element " << i << ": ";
+ buf << "Integer overflow";
+ error(buf);
+}
+
+#if defined(HAVE_LIBREADLINE) && defined(HAVE_LIBCURSES)
+struct historyState {
+ bool store;
+ HISTORY_STATE state;
+};
+
+typedef mem::map<CONST string, historyState> historyMap_t;
+historyMap_t historyMap;
+static HISTORY_STATE history_save;
+
+// Store a deep copy of the current readline history in dest.
+void store_history(HISTORY_STATE *dest)
+{
+ HISTORY_STATE *src=history_get_history_state();
+ if(src) {
+ *dest=*src;
+ for(Int i=0; i < src->length; ++i)
+ dest->entries[i]=src->entries[i];
+ free(src);
+ }
+}
+
+stringarray* get_history(Int n)
+{
+ int N=intcast(n);
+ if(N <= 0) N=history_length;
+ else N=Min(N,history_length);
+ array *a=new array((size_t) N);
+ int offset=history_length-N+1;
+ for(int i=0; i < N; ++i) {
+ HIST_ENTRY *last=history_get(offset+i);
+ string s=last ? last->line : "";
+ (*a)[i]=s;
+ }
+ return a;
+}
+
+string historyfilename(const string &name)
+{
+ return historyname+"_"+name;
+}
+#endif
+
+#if defined(HAVE_LIBREADLINE) && defined(HAVE_LIBCURSES)
+int readline_startup_hook()
+{
+#ifdef __CYGWIN__
+ rl_set_key("\\M-[3~",rl_delete,rl_get_keymap());
+ rl_set_key("\\M-[2~",rl_overwrite_mode,rl_get_keymap());
+#endif
+ return 0;
+}
+
+void init_readline(bool tabcompletion=true)
+{
+ static bool first=true;
+ if(first) {
+ first=false;
+#ifdef __CYGWIN__
+ rl_startup_hook=readline_startup_hook;
+#endif
+ }
+ rl_bind_key('\t',tabcompletion ? rl_complete : rl_insert);
+}
+#endif
+
+void cleanup()
+{
+ processDataStruct &pd=processData();
+ pd.atExitFunction=NULL;
+ pd.atUpdateFunction=NULL;
+ pd.atBreakpointFunction=NULL;
+
+#if defined(HAVE_LIBREADLINE) && defined(HAVE_LIBCURSES)
+ store_history(&history_save);
+ int nlines=intcast(getSetting<Int>("historylines"));
+ for(historyMap_t::iterator h=historyMap.begin(); h != historyMap.end();
+ ++h) {
+ history_set_history_state(&h->second.state);
+ stifle_history(nlines);
+ if(h->second.store) write_history(historyfilename(h->first).c_str());
+ }
+ history_set_history_state(&history_save);
+#endif
+}
+
+void purge(Int divisor=0)
+{
+#ifdef USEGC
+ if(divisor > 0) GC_set_free_space_divisor((GC_word) divisor);
+ GC_gcollect();
+#endif
+}
+
+void updateFunction(stack *Stack)
+{
+ callable *atUpdateFunction=processData().atUpdateFunction;
+ if(atUpdateFunction && !nullfunc::instance()->compare(atUpdateFunction))
+ atUpdateFunction->call(Stack);
+}
+
+void exitFunction(stack *Stack)
+{
+ callable *atExitFunction=processData().atExitFunction;
+ if(atExitFunction && !nullfunc::instance()->compare(atExitFunction))
+ atExitFunction->call(Stack);
+ cleanup();
+}
+
+default_t def;
+string emptystring;
+array *emptyarray=new array(0);
+string commentchar="#";
+pair zero;
+
+void breakpoint(stack *Stack, runnable *r)
+{
+ callable *atBreakpointFunction=processData().atBreakpointFunction;
+ if(atBreakpointFunction &&
+ !nullfunc::instance()->compare(atBreakpointFunction)) {
+ position curPos=getPos();
+ Stack->push<string>(curPos.filename());
+ Stack->push<Int>((Int) curPos.Line());
+ Stack->push<Int>((Int) curPos.Column());
+ Stack->push(r ? r : item(def));
+ atBreakpointFunction->call(Stack); // returns a string
+ } else Stack->push<string>("");
+}
+
+}
+
+namespace types {
+extern const char *names[];
+}
+
+void checkformat(const char *ptr, bool intformat)
+{
+ while(*ptr != '\0') {
+ if(*ptr != '%') /* While we have regular characters, print them. */
+ ptr++;
+ else { /* We've got a format specifier. */
+ ptr++;
+
+ while(*ptr && strchr ("-+ #0'I", *ptr)) /* Move past flags. */
+ *ptr++;
+
+ if(*ptr == '*')
+ ptr++;
+ else while(isdigit(*ptr)) /* Handle explicit numeric value. */
+ ptr++;
+
+ if(*ptr == '.') {
+ *ptr++; /* Go past the period. */
+ if(*ptr == '*') {
+ ptr++;
+ } else
+ while(isdigit(*ptr)) /* Handle explicit numeric value. */
+ *ptr++;
+ }
+ while(*ptr && strchr ("hlL", *ptr))
+ *ptr++;
+
+ if(*ptr == '%') ++ptr;
+ else if(*ptr != '\0') {
+ if(intformat) {
+ switch(*ptr) {
+ case 'd':
+ case 'i':
+ case 'o':
+ case 'u':
+ case 'x':
+ case 'X':
+ case 'c':
+ break;
+ default:
+ ostringstream buf;
+ buf << "Invalid format '" << *ptr << "' for type "
+ << types::names[types::ty_Int];
+ error(buf);
+ break;
+ }
+ } else {
+ switch(*ptr) {
+ case 'f':
+ case 'F':
+ case 'e':
+ case 'E':
+ case 'g':
+ case 'G':
+ break;
+ default:
+ ostringstream buf;
+ buf << "Invalid format '" << *ptr << "' for type "
+ << types::names[types::ty_real];
+ error(buf);
+ break;
+ }
+ }
+ }
+ } /* End of else statement */
+ }
+}
+
+// Return an angle in the interval [0,360).
+inline double principalBranch(double deg)
+{
+ if(deg < 0) deg += 360;
+ return deg;
+}
+
+static string defaulttransparency=string("Compatible");
+
+static const string defaulttimeformat=string("%a %b %d %T %Z %Y");
+#ifdef HAVE_STRFTIME
+static const size_t nTime=256;
+static char Time[nTime];
+#endif
+
+void clear(string file, Int line, bool warn=false)
+{
+ bpinfo bp(file,line);
+ for(mem::list<bpinfo>::iterator p=bplist.begin(); p != bplist.end(); ++p) {
+ if(*p == bp) {
+ cout << "cleared breakpoint at " << file << ": " << line << endl;
+ bplist.remove(bp);
+ return;
+ }
+ }
+ if(warn)
+ cout << "No such breakpoint at " << file << ": " << line << endl;
+}
+
+Int windingnumber(array *p, camp::pair z)
+{
+ size_t size=checkArray(p);
+ Int count=0;
+ for(size_t i=0; i < size; i++)
+ count += read<path *>(p,i)->windingnumber(z);
+ return count;
+}
+
+string convertname(string name, const string& format, bool check=true)
+{
+ if(name.empty())
+ return buildname(outname(),format,"");
+ else
+ if(check) checkLocal(name);
+ return format.empty() ? name : format+":"+name;
+}
+
+callable *Func;
+stack *FuncStack;
+double wrapFunction(double x)
+{
+ FuncStack->push(x);
+ Func->call(FuncStack);
+ return pop<double>(FuncStack);
+}
+
+callable *compareFunc;
+bool compareFunction(const vm::item& i, const vm::item& j)
+{
+ FuncStack->push(i);
+ FuncStack->push(j);
+ compareFunc->call(FuncStack);
+ return pop<bool>(FuncStack);
+}
+
+void unused(void *)
+{
+}
+
+pair readpair(stringstream& s, bool tex)
+{
+ static const double f=12.0/100.0;
+ double x,y;
+ s >> y;
+ s >> x;
+ return tex ? pair(f*x,-f*y) : pair(x,y);
+}
+
+// Ignore unclosed begingroups but not spurious endgroups.
+const char *nobegin="endgroup without matching begingroup";
+
+// Return the component of vector v perpendicular to a unit vector u.
+inline triple perp(triple v, triple u)
+{
+ return v-dot(v,u)*u;
+}
+
+string ASYo="/ASYo {( ) print 12 string cvs print} bind def";
+string pathforall="{(M) print ASYo ASYo} {(L) print ASYo ASYo} {(C) print ASYo ASYo ASYo ASYo ASYo ASYo} {(c) print} pathforall";
+string currentpoint="print currentpoint ASYo ASYo ";
+
+array *readpath(const string& psname, bool tex, bool keep)
+{
+ array *P=new array(0);
+ ostringstream pipe;
+ pipe << "'" << getSetting<string>("gs")
+ << "' -q -dNOPAUSE -dBATCH";
+ if(safe) pipe << " -dSAFER";
+#ifdef __CYGWIN__
+ string null="NUL";
+#else
+ string null="/dev/null";
+#endif
+ pipe << " -sDEVICE=epswrite -sOutputFile="+null+" '" << psname << "'";
+ iopipestream gs(pipe.str().c_str(),"gs","Ghostscript");
+ stringstream buf;
+ while(true) {
+ string out;
+ gs >> out;
+ buf << out;
+ string s=buf.str();
+ if(gs.tailequals(s.c_str(),s.size(),"E",1)) break;
+ }
+ if(verbose > 2) cout << endl;
+
+ mem::vector<solvedKnot> nodes;
+ solvedKnot node;
+ bool cyclic=false;
+ bool active=false;
+
+ pair offset;
+ while(!buf.eof()) {
+ char c;
+ buf >> c;
+ switch(c) {
+ case 'M':
+ {
+ if(active) {
+ if(cyclic) {
+ if(node.point == nodes[0].point)
+ nodes[0].pre=node.pre;
+ else {
+ pair delta=(nodes[0].point-node.point)*third;
+ node.post=node.point+delta;
+ nodes[0].pre=nodes[0].point-delta;
+ node.straight=true;
+ nodes.push_back(node);
+ }
+ } else {
+ node.post=node.point;
+ node.straight=false;
+ nodes.push_back(node);
+ }
+ P->push(path(nodes,nodes.size(),cyclic));
+ nodes.clear();
+ }
+ active=false;
+ cyclic=false;
+ node.pre=node.point=readpair(buf,tex)-offset;
+ node.straight=false;
+ break;
+ }
+ case 'L':
+ {
+ pair point=readpair(buf,tex)-offset;
+ pair delta=(point-node.point)*third;
+ node.post=node.point+delta;
+ node.straight=true;
+ nodes.push_back(node);
+ active=true;
+ node.pre=point-delta;
+ node.point=point;
+ break;
+ }
+ case 'C':
+ {
+ pair point=readpair(buf,tex)-offset;
+ pair pre=readpair(buf,tex)-offset;
+ node.post=readpair(buf,tex)-offset;
+ node.straight=false;
+ nodes.push_back(node);
+ active=true;
+ node.pre=pre;
+ node.point=point;
+ break;
+ }
+ case 'c':
+ {
+ cyclic=true;
+ break;
+ }
+ case 'Z':
+ {
+ offset=readpair(buf,tex);
+ break;
+ }
+ }
+ }
+
+ if(!keep)
+ unlink(psname.c_str());
+ return P;
+}
+
+pair sin(pair z)
+{
+ return pair(sin(z.getx())*cosh(z.gety()),cos(z.getx())*sinh(z.gety()));
+}
+
+pair exp(pair z)
+{
+ return exp(z.getx())*expi(z.gety());
+}
+
+pair gamma(pair z)
+{
+ static double p[]={0.99999999999980993,676.5203681218851,-1259.1392167224028,
+ 771.32342877765313,-176.61502916214059,12.507343278686905,
+ -0.13857109526572012,9.9843695780195716e-6,
+ 1.5056327351493116e-7};
+ static int n=sizeof(p)/sizeof(double);
+ static double root2pi=sqrt(2*PI);
+ if(z.getx() < 0.5)
+ return PI/(sin(PI*z)*gamma(1.0-z));
+ z -= 1.0;
+ pair x=p[0];
+ for(int i=1; i < n; ++i)
+ x += p[i]/(z+i);
+ pair t=n-1.5+z;
+ return root2pi*pow(t,z+0.5)*exp(-t)*x;
+}
+
+// Autogenerated routines:
+
+
+
+namespace run {
+
+// Initializers
+#line 1026 "runtime.in"
+void IntZero(stack *Stack)
+{
+#line 1027 "runtime.in"
+ {Stack->push<Int>(0); return;}
+}
+
+#line 1032 "runtime.in"
+void realZero(stack *Stack)
+{
+#line 1033 "runtime.in"
+ {Stack->push<real>(0.0); return;}
+}
+
+#line 1037 "runtime.in"
+void boolFalse(stack *Stack)
+{
+#line 1038 "runtime.in"
+ {Stack->push<bool>(false); return;}
+}
+
+#line 1042 "runtime.in"
+void pushNullArray(stack *Stack)
+{
+#line 1043 "runtime.in"
+ {Stack->push<array*>(0); return;}
+}
+
+#line 1047 "runtime.in"
+void pushNullRecord(stack *Stack)
+{
+#line 1048 "runtime.in"
+ {Stack->push<frame*>(0); return;}
+}
+
+#line 1052 "runtime.in"
+void pushNullFunction(stack *Stack)
+{
+#line 1053 "runtime.in"
+ {Stack->push(nullfunc::instance()); return;}
+}
+
+
+// Default operations
+
+// Put the default value token on the stack (in place of an argument when
+// making a function call).
+#line 1062 "runtime.in"
+void pushDefault(stack *Stack)
+{
+#line 1063 "runtime.in"
+ {Stack->push(def); return;}
+}
+
+
+// Test if the value on the stack is the default value token.
+#line 1069 "runtime.in"
+void isDefault(stack *Stack)
+{
+ item i=vm::pop(Stack);
+#line 1070 "runtime.in"
+ {Stack->push<bool>(isdefault(i)); return;}
+}
+
+
+// Logical operations
+#line 1076 "runtime.in"
+// bool !(bool b);
+void gen8(stack *Stack)
+{
+ bool b=vm::pop<bool>(Stack);
+#line 1077 "runtime.in"
+ {Stack->push<bool>(!b); return;}
+}
+
+#line 1082 "runtime.in"
+void boolMemEq(stack *Stack)
+{
+ frame * b=vm::pop<frame *>(Stack);
+ frame * a=vm::pop<frame *>(Stack);
+#line 1083 "runtime.in"
+ {Stack->push<bool>(a == b); return;}
+}
+
+#line 1087 "runtime.in"
+void boolMemNeq(stack *Stack)
+{
+ frame * b=vm::pop<frame *>(Stack);
+ frame * a=vm::pop<frame *>(Stack);
+#line 1088 "runtime.in"
+ {Stack->push<bool>(a != b); return;}
+}
+
+#line 1092 "runtime.in"
+void boolFuncEq(stack *Stack)
+{
+ callable * b=vm::pop<callable *>(Stack);
+ callable * a=vm::pop<callable *>(Stack);
+#line 1093 "runtime.in"
+ {Stack->push<bool>(a->compare(b)); return;}
+}
+
+#line 1097 "runtime.in"
+void boolFuncNeq(stack *Stack)
+{
+ callable * b=vm::pop<callable *>(Stack);
+ callable * a=vm::pop<callable *>(Stack);
+#line 1098 "runtime.in"
+ {Stack->push<bool>(!(a->compare(b))); return;}
+}
+
+
+// Bit operations
+#line 1104 "runtime.in"
+// Int AND(Int a, Int b);
+void gen13(stack *Stack)
+{
+ Int b=vm::pop<Int>(Stack);
+ Int a=vm::pop<Int>(Stack);
+#line 1105 "runtime.in"
+ {Stack->push<Int>(a & b); return;}
+}
+
+#line 1110 "runtime.in"
+// Int OR(Int a, Int b);
+void gen14(stack *Stack)
+{
+ Int b=vm::pop<Int>(Stack);
+ Int a=vm::pop<Int>(Stack);
+#line 1111 "runtime.in"
+ {Stack->push<Int>(a | b); return;}
+}
+
+#line 1115 "runtime.in"
+// Int XOR(Int a, Int b);
+void gen15(stack *Stack)
+{
+ Int b=vm::pop<Int>(Stack);
+ Int a=vm::pop<Int>(Stack);
+#line 1116 "runtime.in"
+ {Stack->push<Int>(a ^ b); return;}
+}
+
+#line 1120 "runtime.in"
+// Int NOT(Int a);
+void gen16(stack *Stack)
+{
+ Int a=vm::pop<Int>(Stack);
+#line 1121 "runtime.in"
+ {Stack->push<Int>(~a); return;}
+}
+
+
+// Casts
+#line 1127 "runtime.in"
+void pairToGuide(stack *Stack)
+{
+ pair z=vm::pop<pair>(Stack);
+#line 1128 "runtime.in"
+ {Stack->push<guide*>(new pairguide(z)); return;}
+}
+
+#line 1133 "runtime.in"
+void pathToGuide(stack *Stack)
+{
+ path p=vm::pop<path>(Stack);
+#line 1134 "runtime.in"
+ {Stack->push<guide*>(new pathguide(p)); return;}
+}
+
+#line 1138 "runtime.in"
+void guideToPath(stack *Stack)
+{
+ guide * g=vm::pop<guide *>(Stack);
+#line 1139 "runtime.in"
+ {Stack->push<path>(g->solve()); return;}
+}
+
+
+// Picture operations
+#line 1145 "runtime.in"
+void newPicture(stack *Stack)
+{
+#line 1146 "runtime.in"
+ {Stack->push<picture*>(new picture()); return;}
+}
+
+#line 1151 "runtime.in"
+// bool empty(picture *f);
+void gen21(stack *Stack)
+{
+ picture * f=vm::pop<picture *>(Stack);
+#line 1152 "runtime.in"
+ {Stack->push<bool>(f->null()); return;}
+}
+
+#line 1156 "runtime.in"
+// void erase(picture *f);
+void gen22(stack *Stack)
+{
+ picture * f=vm::pop<picture *>(Stack);
+#line 1157 "runtime.in"
+ f->nodes.clear();
+}
+
+#line 1161 "runtime.in"
+// pair min(picture *f);
+void gen23(stack *Stack)
+{
+ picture * f=vm::pop<picture *>(Stack);
+#line 1162 "runtime.in"
+ {Stack->push<pair>(f->bounds().Min()); return;}
+}
+
+#line 1166 "runtime.in"
+// pair max(picture *f);
+void gen24(stack *Stack)
+{
+ picture * f=vm::pop<picture *>(Stack);
+#line 1167 "runtime.in"
+ {Stack->push<pair>(f->bounds().Max()); return;}
+}
+
+#line 1171 "runtime.in"
+// void label(picture *f, string *s, string *size, transform t, pair position, pair align, pen p);
+void gen25(stack *Stack)
+{
+ pen p=vm::pop<pen>(Stack);
+ pair align=vm::pop<pair>(Stack);
+ pair position=vm::pop<pair>(Stack);
+ transform t=vm::pop<transform>(Stack);
+ string * size=vm::pop<string *>(Stack);
+ string * s=vm::pop<string *>(Stack);
+ picture * f=vm::pop<picture *>(Stack);
+#line 1173 "runtime.in"
+ f->append(new drawLabel(*s,*size,t,position,align,p));
+}
+
+#line 1177 "runtime.in"
+// bool labels(picture *f);
+void gen26(stack *Stack)
+{
+ picture * f=vm::pop<picture *>(Stack);
+#line 1178 "runtime.in"
+ {Stack->push<bool>(f->havelabels()); return;}
+}
+
+#line 1182 "runtime.in"
+// patharray* _texpath(string *s, pen p=CURRENTPEN);
+void gen27(stack *Stack)
+{
+ pen p=vm::pop<pen>(Stack,CURRENTPEN);
+ string * s=vm::pop<string *>(Stack);
+#line 1183 "runtime.in"
+ array *P=new array(0);
+ if(s->empty()) {Stack->push<patharray*>(P); return;}
+
+ string prefix=outname();
+ spaceToUnderscore(prefix);
+ string psname=auxname(prefix,"ps");
+
+ string texname=auxname(prefix,"tex");
+ string dviname=auxname(prefix,"dvi");
+ bbox b;
+ texfile tex(texname,b,true);
+ tex.miniprologue();
+
+ tex.setfont(p);
+ tex.verbatimline("\\special{ps:");
+ tex.verbatimline(ASYo);
+ tex.verbatimline("/ASY1 true def");
+ tex.verbatimline("/v {neg exch 4 copy 4 2 roll 2 copy 6 2 roll 2 copy (M) print ASYo ASYo (L) print ASYo add ASYo (L) print add ASYo add ASYo (L) print add ASYo ASYo (c) print} bind def");
+ tex.verbatimline("/show {ASY1 {(Z) "+currentpoint+
+ "/ASY1 false def} if currentpoint newpath moveto false charpath "+
+ pathforall+"} bind def}");
+ tex.verbatim(*s);
+ tex.verbatimline("\\special{ps: (E) print}");
+ tex.epilogue(true);
+ tex.close();
+
+ ostringstream cmd;
+ string aux=auxname(prefix,"aux");
+ unlink(aux.c_str());
+ cmd << texprogram(true) << " \\nonstopmode\\input '" << texname << "'";
+ bool quiet=verbose <= 2;
+ int status=System(cmd,quiet ? 1 : 0,"texpath",texpathmessage());
+ if(!status && getSetting<bool>("twice"))
+ status=System(cmd,quiet ? 1 : 0,"texpath",texpathmessage());
+ if(status) {
+ if(quiet) {
+ ostringstream cmd;
+ cmd << texprogram(true) << " \\scrollmode\\input '" << texname << "'";
+ System(cmd,0);
+ }
+ }
+
+ if(!status) {
+ ostringstream cmd;
+ cmd << "'" << getSetting<string>("dvips") << "' -R -Pdownload35 -D600 "
+ << getSetting<string>("dvipsOptions");
+ if(verbose <= 2) cmd << " -q";
+ cmd << " -o '" << psname << "' '" << dviname << "'";
+ status=System(cmd,0,true,"dvips");
+ }
+
+ if(status != 0)
+ error("texpath failed");
+
+ bool keep=getSetting<bool>("keep");
+ if(!keep) { // Delete temporary files.
+ unlink(texname.c_str());
+ if(!getSetting<bool>("keepaux"))
+ unlink(aux.c_str());
+ unlink(auxname(prefix,"log").c_str());
+ unlink(dviname.c_str());
+ }
+ {Stack->push<patharray*>(readpath(psname,true,keep)); return;}
+}
+
+#line 1249 "runtime.in"
+// patharray* _strokepath(path g, pen p=CURRENTPEN);
+void gen28(stack *Stack)
+{
+ pen p=vm::pop<pen>(Stack,CURRENTPEN);
+ path g=vm::pop<path>(Stack);
+#line 1250 "runtime.in"
+ array *P=new array(0);
+ if(g.size() == 0) {Stack->push<patharray*>(P); return;}
+
+ string prefix=outname();
+ spaceToUnderscore(prefix);
+ string psname=auxname(prefix,"ps");
+ bbox b;
+ psfile ps(psname, false);
+ ps.prologue(b);
+ ps.verbatimline(ASYo);
+ ps.verbatimline("/stroke {(Z) "+currentpoint+pathforall+"} bind def");
+ ps.resetpen();
+ ps.setpen(p);
+ ps.write(g);
+ ps.strokepath();
+ ps.stroke();
+ ps.verbatimline("(M) "+currentpoint+"(E) print");
+ ps.epilogue();
+ ps.close();
+ {Stack->push<patharray*>(readpath(psname,false,getSetting<bool>("keep"))); return;}
+}
+
+#line 1273 "runtime.in"
+// void _draw(picture *f, path g, pen p);
+void gen29(stack *Stack)
+{
+ pen p=vm::pop<pen>(Stack);
+ path g=vm::pop<path>(Stack);
+ picture * f=vm::pop<picture *>(Stack);
+#line 1274 "runtime.in"
+ f->append(new drawPath(g,p));
+}
+
+#line 1278 "runtime.in"
+// void fill(picture *f, patharray *g, pen p=CURRENTPEN, bool copy=true);
+void gen30(stack *Stack)
+{
+ bool copy=vm::pop<bool>(Stack,true);
+ pen p=vm::pop<pen>(Stack,CURRENTPEN);
+ patharray * g=vm::pop<patharray *>(Stack);
+ picture * f=vm::pop<picture *>(Stack);
+#line 1279 "runtime.in"
+ array *(*copyarray)(array *a)=copy ? copyArray: nop;
+ f->append(new drawFill(*copyarray(g),false,p));
+}
+
+#line 1284 "runtime.in"
+// void latticeshade(picture *f, patharray *g, bool stroke=false, pen fillrule=CURRENTPEN, penarray2 *p, bool copy=true);
+void gen31(stack *Stack)
+{
+ bool copy=vm::pop<bool>(Stack,true);
+ penarray2 * p=vm::pop<penarray2 *>(Stack);
+ pen fillrule=vm::pop<pen>(Stack,CURRENTPEN);
+ bool stroke=vm::pop<bool>(Stack,false);
+ patharray * g=vm::pop<patharray *>(Stack);
+ picture * f=vm::pop<picture *>(Stack);
+#line 1286 "runtime.in"
+ array *(*copyarray)(array *a)=copy ? copyArray: nop;
+ f->append(new drawLatticeShade(*copyarray(g),stroke,fillrule,*copyarray(p)));
+}
+
+#line 1291 "runtime.in"
+// void axialshade(picture *f, patharray *g, bool stroke=false, pen pena, pair a, pen penb, pair b, bool copy=true);
+void gen32(stack *Stack)
+{
+ bool copy=vm::pop<bool>(Stack,true);
+ pair b=vm::pop<pair>(Stack);
+ pen penb=vm::pop<pen>(Stack);
+ pair a=vm::pop<pair>(Stack);
+ pen pena=vm::pop<pen>(Stack);
+ bool stroke=vm::pop<bool>(Stack,false);
+ patharray * g=vm::pop<patharray *>(Stack);
+ picture * f=vm::pop<picture *>(Stack);
+#line 1293 "runtime.in"
+ array *(*copyarray)(array *a)=copy ? copyArray: nop;
+ f->append(new drawAxialShade(*copyarray(g),stroke,pena,a,penb,b));
+}
+
+#line 1298 "runtime.in"
+// void radialshade(picture *f, patharray *g, bool stroke=false, pen pena, pair a, real ra, pen penb, pair b, real rb, bool copy=true);
+void gen33(stack *Stack)
+{
+ bool copy=vm::pop<bool>(Stack,true);
+ real rb=vm::pop<real>(Stack);
+ pair b=vm::pop<pair>(Stack);
+ pen penb=vm::pop<pen>(Stack);
+ real ra=vm::pop<real>(Stack);
+ pair a=vm::pop<pair>(Stack);
+ pen pena=vm::pop<pen>(Stack);
+ bool stroke=vm::pop<bool>(Stack,false);
+ patharray * g=vm::pop<patharray *>(Stack);
+ picture * f=vm::pop<picture *>(Stack);
+#line 1300 "runtime.in"
+ array *(*copyarray)(array *a)=copy ? copyArray: nop;
+ f->append(new drawRadialShade(*copyarray(g),stroke,pena,a,ra,penb,b,rb));
+}
+
+#line 1305 "runtime.in"
+// void gouraudshade(picture *f, patharray *g, bool stroke=false, pen fillrule=CURRENTPEN, penarray *p, pairarray *z, Intarray *edges, bool copy=true);
+void gen34(stack *Stack)
+{
+ bool copy=vm::pop<bool>(Stack,true);
+ Intarray * edges=vm::pop<Intarray *>(Stack);
+ pairarray * z=vm::pop<pairarray *>(Stack);
+ penarray * p=vm::pop<penarray *>(Stack);
+ pen fillrule=vm::pop<pen>(Stack,CURRENTPEN);
+ bool stroke=vm::pop<bool>(Stack,false);
+ patharray * g=vm::pop<patharray *>(Stack);
+ picture * f=vm::pop<picture *>(Stack);
+#line 1308 "runtime.in"
+ array *(*copyarray)(array *a)=copy ? copyArray: nop;
+ checkArrays(p,z);
+ checkArrays(z,edges);
+ f->append(new drawGouraudShade(*copyarray(g),stroke,fillrule,*copyarray(p),
+ *copyarray(z),*copyarray(edges)));
+}
+
+#line 1316 "runtime.in"
+// void gouraudshade(picture *f, patharray *g, bool stroke=false, pen fillrule=CURRENTPEN, penarray *p, Intarray *edges, bool copy=true);
+void gen35(stack *Stack)
+{
+ bool copy=vm::pop<bool>(Stack,true);
+ Intarray * edges=vm::pop<Intarray *>(Stack);
+ penarray * p=vm::pop<penarray *>(Stack);
+ pen fillrule=vm::pop<pen>(Stack,CURRENTPEN);
+ bool stroke=vm::pop<bool>(Stack,false);
+ patharray * g=vm::pop<patharray *>(Stack);
+ picture * f=vm::pop<picture *>(Stack);
+#line 1319 "runtime.in"
+ array *(*copyarray)(array *a)=copy ? copyArray: nop;
+ size_t n=checkArrays(p,edges);
+ size_t m=checkArray(g);
+ array *z=new array(n);
+ Int k=0;
+ Int in=(Int) n;
+ for(size_t j=0; j < m; ++j) {
+ path *P=read<path *>(g,j);
+ assert(P);
+ Int stop=Min(P->size(),in-k);
+ mem::vector<solvedKnot>& nodes=P->Nodes();
+ for(Int i=0; i < stop; ++i)
+ (*z)[k++]=nodes[i].point;
+ }
+ checkArrays(p,z);
+
+ f->append(new drawGouraudShade(*copyarray(g),stroke,fillrule,*copyarray(p),
+ *z,*copyarray(edges)));
+}
+
+#line 1340 "runtime.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 gen36(stack *Stack)
+{
+ bool copy=vm::pop<bool>(Stack,true);
+ pairarray2 * z=vm::pop<pairarray2 *>(Stack,emptyarray);
+ patharray * b=vm::pop<patharray *>(Stack,NULL);
+ penarray2 * p=vm::pop<penarray2 *>(Stack);
+ pen fillrule=vm::pop<pen>(Stack,CURRENTPEN);
+ bool stroke=vm::pop<bool>(Stack,false);
+ patharray * g=vm::pop<patharray *>(Stack);
+ picture * f=vm::pop<picture *>(Stack);
+#line 1343 "runtime.in"
+ array *(*copyarray)(array *a)=copy ? copyArray: nop;
+ array *(*copyarray2)(array *a)=copy ? copyArray2: nop;
+ if(b == NULL) b=g;
+ size_t n=checkArrays(p,b);
+ size_t nz=checkArray(z);
+ if(nz != 0)
+ checkEqual(nz,n);
+ f->append(new drawTensorShade(*copyarray(g),stroke,fillrule,*copyarray2(p),
+ *copyarray(b),*copyarray2(z)));
+}
+
+#line 1355 "runtime.in"
+// void functionshade(picture *f, patharray *g, bool stroke=false, pen fillrule=CURRENTPEN, string shader=emptystring, bool copy=true);
+void gen37(stack *Stack)
+{
+ bool copy=vm::pop<bool>(Stack,true);
+ string shader=vm::pop<string>(Stack,emptystring);
+ pen fillrule=vm::pop<pen>(Stack,CURRENTPEN);
+ bool stroke=vm::pop<bool>(Stack,false);
+ patharray * g=vm::pop<patharray *>(Stack);
+ picture * f=vm::pop<picture *>(Stack);
+#line 1358 "runtime.in"
+ array *(*copyarray)(array *a)=copy ? copyArray: nop;
+ f->append(new drawFunctionShade(*copyarray(g),stroke,fillrule,shader));
+}
+
+// Clip a picture to a superpath using the given fill rule.
+// Subsequent additions to the picture will not be affected by the clipping.
+#line 1365 "runtime.in"
+// void clip(picture *f, patharray *g, bool stroke=false, pen fillrule=CURRENTPEN, bool copy=true);
+void gen38(stack *Stack)
+{
+ bool copy=vm::pop<bool>(Stack,true);
+ pen fillrule=vm::pop<pen>(Stack,CURRENTPEN);
+ bool stroke=vm::pop<bool>(Stack,false);
+ patharray * g=vm::pop<patharray *>(Stack);
+ picture * f=vm::pop<picture *>(Stack);
+#line 1367 "runtime.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 1373 "runtime.in"
+// void beginclip(picture *f, patharray *g, bool stroke=false, pen fillrule=CURRENTPEN, bool copy=true);
+void gen39(stack *Stack)
+{
+ bool copy=vm::pop<bool>(Stack,true);
+ pen fillrule=vm::pop<pen>(Stack,CURRENTPEN);
+ bool stroke=vm::pop<bool>(Stack,false);
+ patharray * g=vm::pop<patharray *>(Stack);
+ picture * f=vm::pop<picture *>(Stack);
+#line 1375 "runtime.in"
+ array *(*copyarray)(array *a)=copy ? copyArray: nop;
+ f->append(new drawClipBegin(*copyarray(g),stroke,fillrule,false));
+}
+
+#line 1380 "runtime.in"
+// void endclip(picture *f);
+void gen40(stack *Stack)
+{
+ picture * f=vm::pop<picture *>(Stack);
+#line 1381 "runtime.in"
+ f->append(new drawClipEnd(false));
+}
+
+#line 1385 "runtime.in"
+// void gsave(picture *f);
+void gen41(stack *Stack)
+{
+ picture * f=vm::pop<picture *>(Stack);
+#line 1386 "runtime.in"
+ f->append(new drawGsave());
+}
+
+#line 1390 "runtime.in"
+// void grestore(picture *f);
+void gen42(stack *Stack)
+{
+ picture * f=vm::pop<picture *>(Stack);
+#line 1391 "runtime.in"
+ f->append(new drawGrestore());
+}
+
+#line 1395 "runtime.in"
+// void begingroup(picture *f);
+void gen43(stack *Stack)
+{
+ picture * f=vm::pop<picture *>(Stack);
+#line 1396 "runtime.in"
+ f->append(new drawBegin());
+}
+
+#line 1400 "runtime.in"
+// void endgroup(picture *f);
+void gen44(stack *Stack)
+{
+ picture * f=vm::pop<picture *>(Stack);
+#line 1401 "runtime.in"
+ f->append(new drawEnd());
+}
+
+#line 1405 "runtime.in"
+// void add(picture *dest, picture *src);
+void gen45(stack *Stack)
+{
+ picture * src=vm::pop<picture *>(Stack);
+ picture * dest=vm::pop<picture *>(Stack);
+#line 1406 "runtime.in"
+ dest->add(*src);
+}
+
+#line 1410 "runtime.in"
+// void prepend(picture *dest, picture *src);
+void gen46(stack *Stack)
+{
+ picture * src=vm::pop<picture *>(Stack);
+ picture * dest=vm::pop<picture *>(Stack);
+#line 1411 "runtime.in"
+ dest->prepend(*src);
+}
+
+#line 1415 "runtime.in"
+// void postscript(picture *f, string s);
+void gen47(stack *Stack)
+{
+ string s=vm::pop<string>(Stack);
+ picture * f=vm::pop<picture *>(Stack);
+#line 1416 "runtime.in"
+ f->append(new drawVerbatim(PostScript,s));
+}
+
+#line 1420 "runtime.in"
+// void tex(picture *f, string s);
+void gen48(stack *Stack)
+{
+ string s=vm::pop<string>(Stack);
+ picture * f=vm::pop<picture *>(Stack);
+#line 1421 "runtime.in"
+ f->append(new drawVerbatim(TeX,s));
+}
+
+#line 1425 "runtime.in"
+// void postscript(picture *f, string s, pair min, pair max);
+void gen49(stack *Stack)
+{
+ pair max=vm::pop<pair>(Stack);
+ pair min=vm::pop<pair>(Stack);
+ string s=vm::pop<string>(Stack);
+ picture * f=vm::pop<picture *>(Stack);
+#line 1426 "runtime.in"
+ f->append(new drawVerbatim(PostScript,s,min,max));
+}
+
+#line 1430 "runtime.in"
+// void tex(picture *f, string s, pair min, pair max);
+void gen50(stack *Stack)
+{
+ pair max=vm::pop<pair>(Stack);
+ pair min=vm::pop<pair>(Stack);
+ string s=vm::pop<string>(Stack);
+ picture * f=vm::pop<picture *>(Stack);
+#line 1431 "runtime.in"
+ f->append(new drawVerbatim(TeX,s,min,max));
+}
+
+#line 1435 "runtime.in"
+// void texpreamble(string s);
+void gen51(stack *Stack)
+{
+ string s=vm::pop<string>(Stack);
+#line 1436 "runtime.in"
+ string t=s+"\n";
+ processDataStruct &pd=processData();
+ pd.TeXpipepreamble.push_back(t);
+ pd.TeXpreamble.push_back(t);
+}
+
+#line 1443 "runtime.in"
+// void deletepreamble();
+void gen52(stack *)
+{
+#line 1444 "runtime.in"
+ if(getSetting<bool>("inlinetex")) {
+ unlink(auxname(outname(),"pre").c_str());
+ }
+}
+
+#line 1450 "runtime.in"
+// void _labelpath(picture *f, string s, string size, path g, string justify, pair offset, pen p);
+void gen53(stack *Stack)
+{
+ pen p=vm::pop<pen>(Stack);
+ pair offset=vm::pop<pair>(Stack);
+ string justify=vm::pop<string>(Stack);
+ path g=vm::pop<path>(Stack);
+ string size=vm::pop<string>(Stack);
+ string s=vm::pop<string>(Stack);
+ picture * f=vm::pop<picture *>(Stack);
+#line 1452 "runtime.in"
+ f->append(new drawLabelPath(s,size,g,justify,offset,p));
+}
+
+#line 1456 "runtime.in"
+// void texreset();
+void gen54(stack *)
+{
+#line 1457 "runtime.in"
+ processDataStruct &pd=processData();
+ pd.TeXpipepreamble.clear();
+ pd.TeXpreamble.clear();
+ pd.tex.pipeclose();
+}
+
+#line 1464 "runtime.in"
+// void layer(picture *f);
+void gen55(stack *Stack)
+{
+ picture * f=vm::pop<picture *>(Stack);
+#line 1465 "runtime.in"
+ f->append(new drawLayer());
+}
+
+#line 1469 "runtime.in"
+// void newpage(picture *f);
+void gen56(stack *Stack)
+{
+ picture * f=vm::pop<picture *>(Stack);
+#line 1470 "runtime.in"
+ f->append(new drawNewPage());
+}
+
+#line 1474 "runtime.in"
+// void _image(picture *f, realarray2 *data, pair initial, pair final, penarray *palette=NULL, transform t=identity, bool copy=true, bool antialias=false);
+void gen57(stack *Stack)
+{
+ bool antialias=vm::pop<bool>(Stack,false);
+ bool copy=vm::pop<bool>(Stack,true);
+ transform t=vm::pop<transform>(Stack,identity);
+ penarray * palette=vm::pop<penarray *>(Stack,NULL);
+ pair final=vm::pop<pair>(Stack);
+ pair initial=vm::pop<pair>(Stack);
+ realarray2 * data=vm::pop<realarray2 *>(Stack);
+ picture * f=vm::pop<picture *>(Stack);
+#line 1477 "runtime.in"
+ array *(*copyarray)(array *a)=copy ? copyArray: nop;
+ array *(*copyarray2)(array *a)=copy ? copyArray2: nop;
+ f->append(new drawImage(*copyarray2(data),*copyarray(palette),
+ t*matrix(initial,final),antialias));
+}
+
+#line 1484 "runtime.in"
+// void _image(picture *f, penarray2 *data, pair initial, pair final, transform t=identity, bool copy=true, bool antialias=false);
+void gen58(stack *Stack)
+{
+ bool antialias=vm::pop<bool>(Stack,false);
+ bool copy=vm::pop<bool>(Stack,true);
+ transform t=vm::pop<transform>(Stack,identity);
+ pair final=vm::pop<pair>(Stack);
+ pair initial=vm::pop<pair>(Stack);
+ penarray2 * data=vm::pop<penarray2 *>(Stack);
+ picture * f=vm::pop<picture *>(Stack);
+#line 1486 "runtime.in"
+ array *(*copyarray2)(array *a)=copy ? copyArray2: nop;
+ f->append(new drawImage(*copyarray2(data),t*matrix(initial,final),antialias));
+}
+
+#line 1491 "runtime.in"
+// string nativeformat();
+void gen59(stack *Stack)
+{
+#line 1492 "runtime.in"
+ {Stack->push<string>(nativeformat()); return;}
+}
+
+#line 1496 "runtime.in"
+// bool latex();
+void gen60(stack *Stack)
+{
+#line 1497 "runtime.in"
+ {Stack->push<bool>(latex(getSetting<string>("tex"))); return;}
+}
+
+#line 1501 "runtime.in"
+// bool pdf();
+void gen61(stack *Stack)
+{
+#line 1502 "runtime.in"
+ {Stack->push<bool>(pdf(getSetting<string>("tex"))); return;}
+}
+
+#line 1506 "runtime.in"
+// void shipout(string prefix=emptystring, picture *f, picture *preamble=NULL, string format=emptystring, bool wait=false, bool view=true, callableTransform *xform);
+void gen62(stack *Stack)
+{
+ callableTransform * xform=vm::pop<callableTransform *>(Stack);
+ bool view=vm::pop<bool>(Stack,true);
+ bool wait=vm::pop<bool>(Stack,false);
+ string format=vm::pop<string>(Stack,emptystring);
+ picture * preamble=vm::pop<picture *>(Stack,NULL);
+ picture * f=vm::pop<picture *>(Stack);
+ string prefix=vm::pop<string>(Stack,emptystring);
+#line 1509 "runtime.in"
+ if(prefix.empty()) prefix=outname();
+
+ picture *result=new picture;
+ unsigned level=0;
+ picture::nodelist::iterator p;
+ for(p = f->nodes.begin(); p != f->nodes.end(); ++p) {
+ xform->call(Stack);
+ transform t=pop<transform>(Stack);
+ static transform Zero=transform(0.0,0.0,0.0,0.0,0.0,0.0);
+ bool Delete=(t == Zero);
+ picture *group=new picture;
+ assert(*p);
+ if((*p)->endgroup()) error(nobegin);
+ if((*p)->begingroup()) {
+ ++level;
+ while(p != f->nodes.end() && level) {
+ if(!Delete) {
+ drawElement *e=t.isIdentity() ? *p : (*p)->transformed(t);
+ group->append(e);
+ }
+ ++p;
+ if(p == f->nodes.end()) break;
+ assert(*p);
+ if((*p)->begingroup()) ++level;
+ if((*p)->endgroup()) {
+ if(level) --level;
+ else error(nobegin);
+ }
+ }
+ }
+ if(p == f->nodes.end()) break;
+ assert(*p);
+ if(!Delete) {
+ drawElement *e=t.isIdentity() ? *p : (*p)->transformed(t);
+ group->append(e);
+ result->add(*group);
+ }
+ }
+
+ result->shipout(preamble,prefix,format,0.0,wait,view);
+}
+
+#line 1552 "runtime.in"
+// void shipout3(string prefix, picture *f, string format=emptystring, real width, real height, real angle, triple m, triple M, realarray2 *t, triplearray *lights, realarray2 *diffuse, realarray2 *ambient, realarray2 *specular, bool viewportlighting, bool view=true);
+void gen63(stack *Stack)
+{
+ bool view=vm::pop<bool>(Stack,true);
+ bool viewportlighting=vm::pop<bool>(Stack);
+ realarray2 * specular=vm::pop<realarray2 *>(Stack);
+ realarray2 * ambient=vm::pop<realarray2 *>(Stack);
+ realarray2 * diffuse=vm::pop<realarray2 *>(Stack);
+ triplearray * lights=vm::pop<triplearray *>(Stack);
+ realarray2 * t=vm::pop<realarray2 *>(Stack);
+ triple M=vm::pop<triple>(Stack);
+ triple m=vm::pop<triple>(Stack);
+ real angle=vm::pop<real>(Stack);
+ real height=vm::pop<real>(Stack);
+ real width=vm::pop<real>(Stack);
+ string format=vm::pop<string>(Stack,emptystring);
+ picture * f=vm::pop<picture *>(Stack);
+ string prefix=vm::pop<string>(Stack);
+#line 1557 "runtime.in"
+ size_t n=checkArrays(lights,diffuse);
+ checkEqual(n,checkArray(ambient));
+ checkEqual(n,checkArray(specular));
+
+ f->shipout3(prefix,format,width,height,angle,m,M,copyArray2C(t,true,4),n,
+ copyTripleArrayC(lights),copyArray2C(diffuse,false,4),
+ copyArray2C(ambient,false,4),copyArray2C(specular,false,4),
+ viewportlighting,view);
+}
+
+#line 1568 "runtime.in"
+// void shipout3(string prefix, picture *f);
+void gen64(stack *Stack)
+{
+ picture * f=vm::pop<picture *>(Stack);
+ string prefix=vm::pop<string>(Stack);
+#line 1569 "runtime.in"
+ f->shipout3(prefix);
+}
+
+#line 1573 "runtime.in"
+// void deconstruct(picture *f, picture *preamble=NULL, real magnification=1, callableTransform *xform);
+void gen65(stack *Stack)
+{
+ callableTransform * xform=vm::pop<callableTransform *>(Stack);
+ real magnification=vm::pop<real>(Stack,1);
+ picture * preamble=vm::pop<picture *>(Stack,NULL);
+ picture * f=vm::pop<picture *>(Stack);
+#line 1575 "runtime.in"
+ unsigned level=0;
+ unsigned n=0;
+
+ string prefix=outname();
+ string xformat=getSetting<string>("xformat");
+
+ static long arg_max=sysconf(_SC_ARG_MAX);
+ const unsigned maxargs=::min(arg_max/(prefix.size()+xformat.size()+25ul),
+ 256ul);
+
+ cout << xformat << newl;
+ cout << maxargs << newl;
+
+ string preformat=nativeformat();
+ const string Done="Done";
+ const string Error="Error";
+
+ ostringstream cmd;
+
+ // Enforce ghostscript limitations.
+ magnification=::max(magnification,0.0001);
+ real res=::min(::max(magnification*72.0,2.0),8192.0);
+
+ const char *converter=NULL, *hint=NULL;
+
+ bool png=xformat == "png";
+
+ if(magnification > 0.0) {
+ mem::list<string> nameStack;
+ string outname;
+ unsigned arg=0;
+ unsigned batch=0;
+ for(picture::nodelist::iterator p=f->nodes.begin();;) {
+ if(p == f->nodes.end()) break;
+ if(arg == 0) {
+ cmd.str("");
+ ostringstream buf;
+ buf << batch << "_";
+ outname=buildname(prefix+buf.str()+"%d",xformat,"");
+ if(png) {
+ cmd << "'" << getSetting<string>("gs")
+ << "' -q -dNOPAUSE -dBATCH -sDEVICE=pngalpha -dEPSCrop";
+ if(safe)
+ cmd << " -dSAFER";
+ cmd << " -r" << res << "x" << res
+ << " -sOutputFile='" << outname << "'";
+ converter="gs";
+ hint="Ghostscript";
+ } else {
+ cmd << "'" << getSetting<string>("convert")
+ << "' -density " << res << "x" << res
+ << " -transparent white";
+ hint=converter="convert";
+ }
+ }
+
+ picture *group=new picture;
+ xform->call(Stack);
+ transform t=pop<transform>(Stack);
+ assert(*p);
+ if((*p)->endgroup()) {
+ cout << Error << endl;
+ error(nobegin);
+ }
+ if((*p)->begingroup()) {
+ ++level;
+ while(p != f->nodes.end() && level) {
+ drawElement *e=t.isIdentity() ? *p : (*p)->transformed(t);
+ group->append(e);
+ ++p;
+ if(p == f->nodes.end()) break;
+ assert(*p);
+ if((*p)->begingroup()) ++level;
+ if((*p)->endgroup()) {
+ if(level) --level;
+ else {
+ cout << Error << endl;
+ error(nobegin);
+ }
+ }
+ }
+ }
+ if(p != f->nodes.end()) {
+ assert(*p);
+ drawElement *e=t.isIdentity() ? *p : (*p)->transformed(t);
+ group->append(e);
+ bbox b;
+ ostringstream buf;
+ buf << prefix << "_" << n;
+ group->shipout(preamble,buf.str(),preformat,magnification,false,false);
+ string Preformat=png && group->Transparency() ? "pdf" : preformat;
+ string name=buildname(buf.str(),Preformat);
+ nameStack.push_back(name);
+ cmd << " '";
+ if(!png) cmd << preformat+":";
+ cmd << name << "'";
+ b=group->bounds();
+ b *= magnification;
+
+ cout << b << newl;
+ ++n;
+ ++p;
+ ++arg;
+ }
+
+ if(p == f->nodes.end() || arg >= maxargs) {
+ arg=0;
+ ++batch;
+ cout.flush();
+ if(!png)
+ cmd << " -scene 1 '" << xformat << ":" << outname << "'";
+
+ int status=System(cmd,0,true,converter,hint);
+ if(status) {
+ cout << Error << endl;
+ error("deconstruct failed");
+ }
+ }
+ }
+
+ if(!getSetting<bool>("keep")) {
+ for(mem::list<string>::iterator p=nameStack.begin();
+ p != nameStack.end(); ++p)
+ unlink(p->c_str());
+ }
+
+ cout << Done << endl;
+ }
+}
+
+#line 1706 "runtime.in"
+// void purge(Int divisor=0);
+void gen66(stack *Stack)
+{
+ Int divisor=vm::pop<Int>(Stack,0);
+#line 1707 "runtime.in"
+ purge(divisor);
+}
+
+
+// Pen operations
+#line 1713 "runtime.in"
+void newPen(stack *Stack)
+{
+#line 1714 "runtime.in"
+ {Stack->push<pen>(pen()); return;}
+}
+
+#line 1719 "runtime.in"
+// bool ==(pen a, pen b);
+void gen68(stack *Stack)
+{
+ pen b=vm::pop<pen>(Stack);
+ pen a=vm::pop<pen>(Stack);
+#line 1720 "runtime.in"
+ {Stack->push<bool>(a == b); return;}
+}
+
+#line 1724 "runtime.in"
+// bool !=(pen a, pen b);
+void gen69(stack *Stack)
+{
+ pen b=vm::pop<pen>(Stack);
+ pen a=vm::pop<pen>(Stack);
+#line 1725 "runtime.in"
+ {Stack->push<bool>(a != b); return;}
+}
+
+#line 1729 "runtime.in"
+// pen +(pen a, pen b);
+void gen70(stack *Stack)
+{
+ pen b=vm::pop<pen>(Stack);
+ pen a=vm::pop<pen>(Stack);
+#line 1730 "runtime.in"
+ {Stack->push<pen>(a+b); return;}
+}
+
+#line 1734 "runtime.in"
+// pen *(real a, pen b);
+void gen71(stack *Stack)
+{
+ pen b=vm::pop<pen>(Stack);
+ real a=vm::pop<real>(Stack);
+#line 1735 "runtime.in"
+ {Stack->push<pen>(a*b); return;}
+}
+
+#line 1739 "runtime.in"
+// pen *(pen a, real b);
+void gen72(stack *Stack)
+{
+ real b=vm::pop<real>(Stack);
+ pen a=vm::pop<pen>(Stack);
+#line 1740 "runtime.in"
+ {Stack->push<pen>(b*a); return;}
+}
+
+#line 1744 "runtime.in"
+// pair max(pen p);
+void gen73(stack *Stack)
+{
+ pen p=vm::pop<pen>(Stack);
+#line 1745 "runtime.in"
+ {Stack->push<pair>(p.bounds().Max()); return;}
+}
+
+#line 1749 "runtime.in"
+// pair min(pen p);
+void gen74(stack *Stack)
+{
+ pen p=vm::pop<pen>(Stack);
+#line 1750 "runtime.in"
+ {Stack->push<pair>(p.bounds().Min()); return;}
+}
+
+// Reset the meaning of pen default attributes.
+#line 1755 "runtime.in"
+// void resetdefaultpen();
+void gen75(stack *)
+{
+#line 1756 "runtime.in"
+ processData().defaultpen=camp::pen::initialpen();
+}
+
+#line 1760 "runtime.in"
+// void defaultpen(pen p);
+void gen76(stack *Stack)
+{
+ pen p=vm::pop<pen>(Stack);
+#line 1761 "runtime.in"
+ processData().defaultpen=pen(resolvepen,p);
+}
+
+#line 1765 "runtime.in"
+// pen defaultpen();
+void gen77(stack *Stack)
+{
+#line 1766 "runtime.in"
+ {Stack->push<pen>(processData().defaultpen); return;}
+}
+
+#line 1770 "runtime.in"
+// bool invisible(pen p);
+void gen78(stack *Stack)
+{
+ pen p=vm::pop<pen>(Stack);
+#line 1771 "runtime.in"
+ {Stack->push<bool>(p.invisible()); return;}
+}
+
+#line 1775 "runtime.in"
+// pen invisible();
+void gen79(stack *Stack)
+{
+#line 1776 "runtime.in"
+ {Stack->push<pen>(pen(invisiblepen)); return;}
+}
+
+#line 1780 "runtime.in"
+// pen gray(pen p);
+void gen80(stack *Stack)
+{
+ pen p=vm::pop<pen>(Stack);
+#line 1781 "runtime.in"
+ p.togrey();
+ {Stack->push<pen>(p); return;}
+}
+
+#line 1786 "runtime.in"
+// pen rgb(pen p);
+void gen81(stack *Stack)
+{
+ pen p=vm::pop<pen>(Stack);
+#line 1787 "runtime.in"
+ p.torgb();
+ {Stack->push<pen>(p); return;}
+}
+
+#line 1792 "runtime.in"
+// pen cmyk(pen p);
+void gen82(stack *Stack)
+{
+ pen p=vm::pop<pen>(Stack);
+#line 1793 "runtime.in"
+ p.tocmyk();
+ {Stack->push<pen>(p); return;}
+}
+
+#line 1798 "runtime.in"
+// pen interp(pen a, pen b, real t);
+void gen83(stack *Stack)
+{
+ real t=vm::pop<real>(Stack);
+ pen b=vm::pop<pen>(Stack);
+ pen a=vm::pop<pen>(Stack);
+#line 1799 "runtime.in"
+ {Stack->push<pen>(interpolate(a,b,t)); return;}
+}
+
+#line 1803 "runtime.in"
+// pen rgb(real r, real g, real b);
+void gen84(stack *Stack)
+{
+ real b=vm::pop<real>(Stack);
+ real g=vm::pop<real>(Stack);
+ real r=vm::pop<real>(Stack);
+#line 1804 "runtime.in"
+ {Stack->push<pen>(pen(r,g,b)); return;}
+}
+
+#line 1808 "runtime.in"
+// pen cmyk(real c, real m, real y, real k);
+void gen85(stack *Stack)
+{
+ real k=vm::pop<real>(Stack);
+ real y=vm::pop<real>(Stack);
+ real m=vm::pop<real>(Stack);
+ real c=vm::pop<real>(Stack);
+#line 1809 "runtime.in"
+ {Stack->push<pen>(pen(c,m,y,k)); return;}
+}
+
+#line 1813 "runtime.in"
+// pen gray(real gray);
+void gen86(stack *Stack)
+{
+ real gray=vm::pop<real>(Stack);
+#line 1814 "runtime.in"
+ {Stack->push<pen>(pen(gray)); return;}
+}
+
+#line 1818 "runtime.in"
+// realarray* colors(pen p);
+void gen87(stack *Stack)
+{
+ pen p=vm::pop<pen>(Stack);
+#line 1819 "runtime.in"
+ size_t n=ColorComponents[p.colorspace()];
+ array *a=new array(n);
+
+ switch(n) {
+ case 0:
+ break;
+ case 1:
+ (*a)[0]=p.gray();
+ break;
+ case 3:
+ (*a)[0]=p.red();
+ (*a)[1]=p.green();
+ (*a)[2]=p.blue();
+ break;
+ case 4:
+ (*a)[0]=p.cyan();
+ (*a)[1]=p.magenta();
+ (*a)[2]=p.yellow();
+ (*a)[3]=p.black();
+ break;
+ default:
+ break;
+ }
+ {Stack->push<realarray*>(a); return;}
+}
+
+#line 1846 "runtime.in"
+// string colorspace(pen p);
+void gen88(stack *Stack)
+{
+ pen p=vm::pop<pen>(Stack);
+#line 1847 "runtime.in"
+ string s=ColorDeviceSuffix[p.colorspace()];
+ std::transform(s.begin(),s.end(),s.begin(),tolower);
+ {Stack->push<string>(s); return;}
+}
+
+#line 1853 "runtime.in"
+// pen pattern(string *s);
+void gen89(stack *Stack)
+{
+ string * s=vm::pop<string *>(Stack);
+#line 1854 "runtime.in"
+ {Stack->push<pen>(pen(setpattern,*s)); return;}
+}
+
+#line 1858 "runtime.in"
+// string pattern(pen p);
+void gen90(stack *Stack)
+{
+ pen p=vm::pop<pen>(Stack);
+#line 1859 "runtime.in"
+ {Stack->push<string>(p.fillpattern()); return;}
+}
+
+#line 1863 "runtime.in"
+// pen fillrule(Int n);
+void gen91(stack *Stack)
+{
+ Int n=vm::pop<Int>(Stack);
+#line 1864 "runtime.in"
+ {Stack->push<pen>(pen(n >= 0 && n < nFill ? (FillRule) n : DEFFILL)); return;}
+}
+
+#line 1868 "runtime.in"
+// Int fillrule(pen p);
+void gen92(stack *Stack)
+{
+ pen p=vm::pop<pen>(Stack);
+#line 1869 "runtime.in"
+ {Stack->push<Int>(p.Fillrule()); return;}
+}
+
+#line 1873 "runtime.in"
+// pen opacity(real opacity=1.0, string blend=defaulttransparency);
+void gen93(stack *Stack)
+{
+ string blend=vm::pop<string>(Stack,defaulttransparency);
+ real opacity=vm::pop<real>(Stack,1.0);
+#line 1874 "runtime.in"
+ for(Int i=0; i < nBlendMode; ++i)
+ if(blend == BlendMode[i]) {Stack->push<pen>(pen(Transparency(blend,opacity))); return;}
+
+ ostringstream buf;
+ buf << "Unknown blend mode: " << "'" << blend << "'";
+ error(buf);
+}
+
+#line 1883 "runtime.in"
+// real opacity(pen p);
+void gen94(stack *Stack)
+{
+ pen p=vm::pop<pen>(Stack);
+#line 1884 "runtime.in"
+ {Stack->push<real>(p.opacity()); return;}
+}
+
+#line 1888 "runtime.in"
+// string blend(pen p);
+void gen95(stack *Stack)
+{
+ pen p=vm::pop<pen>(Stack);
+#line 1889 "runtime.in"
+ {Stack->push<string>(p.blend()); return;}
+}
+
+#line 1893 "runtime.in"
+// pen linetype(string *s, real offset=0, bool scale=true, bool adjust=true);
+void gen96(stack *Stack)
+{
+ bool adjust=vm::pop<bool>(Stack,true);
+ bool scale=vm::pop<bool>(Stack,true);
+ real offset=vm::pop<real>(Stack,0);
+ string * s=vm::pop<string *>(Stack);
+#line 1894 "runtime.in"
+ {Stack->push<pen>(pen(LineType(*s,offset,scale,adjust))); return;}
+}
+
+#line 1898 "runtime.in"
+// string linetype(pen p=CURRENTPEN);
+void gen97(stack *Stack)
+{
+ pen p=vm::pop<pen>(Stack,CURRENTPEN);
+#line 1899 "runtime.in"
+ {Stack->push<string>(p.stroke()); return;}
+}
+
+#line 1903 "runtime.in"
+// real offset(pen p);
+void gen98(stack *Stack)
+{
+ pen p=vm::pop<pen>(Stack);
+#line 1904 "runtime.in"
+ {Stack->push<real>(p.linetype().offset); return;}
+}
+
+#line 1908 "runtime.in"
+// bool scale(pen p);
+void gen99(stack *Stack)
+{
+ pen p=vm::pop<pen>(Stack);
+#line 1909 "runtime.in"
+ {Stack->push<bool>(p.linetype().scale); return;}
+}
+
+#line 1913 "runtime.in"
+// bool adjust(pen p);
+void gen100(stack *Stack)
+{
+ pen p=vm::pop<pen>(Stack);
+#line 1914 "runtime.in"
+ {Stack->push<bool>(p.linetype().adjust); return;}
+}
+
+#line 1918 "runtime.in"
+// pen adjust(pen p, real arclength, bool cyclic);
+void gen101(stack *Stack)
+{
+ bool cyclic=vm::pop<bool>(Stack);
+ real arclength=vm::pop<real>(Stack);
+ pen p=vm::pop<pen>(Stack);
+#line 1919 "runtime.in"
+ {Stack->push<pen>(adjustdash(p,arclength,cyclic)); return;}
+}
+
+#line 1923 "runtime.in"
+// pen linecap(Int n);
+void gen102(stack *Stack)
+{
+ Int n=vm::pop<Int>(Stack);
+#line 1924 "runtime.in"
+ {Stack->push<pen>(pen(setlinecap,n >= 0 && n < nCap ? n : DEFCAP)); return;}
+}
+
+#line 1928 "runtime.in"
+// Int linecap(pen p=CURRENTPEN);
+void gen103(stack *Stack)
+{
+ pen p=vm::pop<pen>(Stack,CURRENTPEN);
+#line 1929 "runtime.in"
+ {Stack->push<Int>(p.cap()); return;}
+}
+
+#line 1933 "runtime.in"
+// pen linejoin(Int n);
+void gen104(stack *Stack)
+{
+ Int n=vm::pop<Int>(Stack);
+#line 1934 "runtime.in"
+ {Stack->push<pen>(pen(setlinejoin,n >= 0 && n < nJoin ? n : DEFJOIN)); return;}
+}
+
+#line 1938 "runtime.in"
+// Int linejoin(pen p=CURRENTPEN);
+void gen105(stack *Stack)
+{
+ pen p=vm::pop<pen>(Stack,CURRENTPEN);
+#line 1939 "runtime.in"
+ {Stack->push<Int>(p.join()); return;}
+}
+
+#line 1943 "runtime.in"
+// pen miterlimit(real x);
+void gen106(stack *Stack)
+{
+ real x=vm::pop<real>(Stack);
+#line 1944 "runtime.in"
+ {Stack->push<pen>(pen(setmiterlimit,x >= 1.0 ? x : DEFJOIN)); return;}
+}
+
+#line 1948 "runtime.in"
+// real miterlimit(pen p=CURRENTPEN);
+void gen107(stack *Stack)
+{
+ pen p=vm::pop<pen>(Stack,CURRENTPEN);
+#line 1949 "runtime.in"
+ {Stack->push<real>(p.miter()); return;}
+}
+
+#line 1953 "runtime.in"
+// pen linewidth(real x);
+void gen108(stack *Stack)
+{
+ real x=vm::pop<real>(Stack);
+#line 1954 "runtime.in"
+ {Stack->push<pen>(pen(setlinewidth,x >= 0.0 ? x : DEFWIDTH)); return;}
+}
+
+#line 1958 "runtime.in"
+// real linewidth(pen p=CURRENTPEN);
+void gen109(stack *Stack)
+{
+ pen p=vm::pop<pen>(Stack,CURRENTPEN);
+#line 1959 "runtime.in"
+ {Stack->push<real>(p.width()); return;}
+}
+
+#line 1963 "runtime.in"
+// pen fontcommand(string *s);
+void gen110(stack *Stack)
+{
+ string * s=vm::pop<string *>(Stack);
+#line 1964 "runtime.in"
+ {Stack->push<pen>(pen(setfont,*s)); return;}
+}
+
+#line 1968 "runtime.in"
+// string font(pen p=CURRENTPEN);
+void gen111(stack *Stack)
+{
+ pen p=vm::pop<pen>(Stack,CURRENTPEN);
+#line 1969 "runtime.in"
+ {Stack->push<string>(p.Font()); return;}
+}
+
+#line 1973 "runtime.in"
+// pen fontsize(real size, real lineskip);
+void gen112(stack *Stack)
+{
+ real lineskip=vm::pop<real>(Stack);
+ real size=vm::pop<real>(Stack);
+#line 1974 "runtime.in"
+ {Stack->push<pen>(pen(setfontsize,size > 0.0 ? size : 0.0,
+ lineskip > 0.0 ? lineskip : 0.0)); return;}
+}
+
+#line 1979 "runtime.in"
+// real fontsize(pen p=CURRENTPEN);
+void gen113(stack *Stack)
+{
+ pen p=vm::pop<pen>(Stack,CURRENTPEN);
+#line 1980 "runtime.in"
+ {Stack->push<real>(p.size()); return;}
+}
+
+#line 1984 "runtime.in"
+// real lineskip(pen p=CURRENTPEN);
+void gen114(stack *Stack)
+{
+ pen p=vm::pop<pen>(Stack,CURRENTPEN);
+#line 1985 "runtime.in"
+ {Stack->push<real>(p.Lineskip()); return;}
+}
+
+#line 1989 "runtime.in"
+// pen overwrite(Int n);
+void gen115(stack *Stack)
+{
+ Int n=vm::pop<Int>(Stack);
+#line 1990 "runtime.in"
+ {Stack->push<pen>(pen(setoverwrite,n >= 0 && n < nOverwrite ? (overwrite_t) n :
+ DEFWRITE)); return;}
+}
+
+#line 1995 "runtime.in"
+// Int overwrite(pen p=CURRENTPEN);
+void gen116(stack *Stack)
+{
+ pen p=vm::pop<pen>(Stack,CURRENTPEN);
+#line 1996 "runtime.in"
+ {Stack->push<Int>(p.Overwrite()); return;}
+}
+
+#line 2000 "runtime.in"
+// pen basealign(Int n);
+void gen117(stack *Stack)
+{
+ Int n=vm::pop<Int>(Stack);
+#line 2001 "runtime.in"
+ {Stack->push<pen>(pen(n >= 0 && n < nBaseLine ? (BaseLine) n : DEFBASE)); return;}
+}
+
+#line 2005 "runtime.in"
+// Int basealign(pen p=CURRENTPEN);
+void gen118(stack *Stack)
+{
+ pen p=vm::pop<pen>(Stack,CURRENTPEN);
+#line 2006 "runtime.in"
+ {Stack->push<Int>(p.Baseline()); return;}
+}
+
+#line 2010 "runtime.in"
+// transform transform(pen p);
+void gen119(stack *Stack)
+{
+ pen p=vm::pop<pen>(Stack);
+#line 2011 "runtime.in"
+ {Stack->push<transform>(p.getTransform()); return;}
+}
+
+#line 2015 "runtime.in"
+// path nib(pen p);
+void gen120(stack *Stack)
+{
+ pen p=vm::pop<pen>(Stack);
+#line 2016 "runtime.in"
+ {Stack->push<path>(p.Path()); return;}
+}
+
+#line 2020 "runtime.in"
+// pen makepen(path p);
+void gen121(stack *Stack)
+{
+ path p=vm::pop<path>(Stack);
+#line 2021 "runtime.in"
+ {Stack->push<pen>(pen(p)); return;}
+}
+
+#line 2025 "runtime.in"
+// pen colorless(pen p);
+void gen122(stack *Stack)
+{
+ pen p=vm::pop<pen>(Stack);
+#line 2026 "runtime.in"
+ p.colorless();
+ {Stack->push<pen>(p); return;}
+}
+
+// Interactive mode
+#line 2032 "runtime.in"
+// bool interactive();
+void gen123(stack *Stack)
+{
+#line 2033 "runtime.in"
+ {Stack->push<bool>(interact::interactive); return;}
+}
+
+#line 2038 "runtime.in"
+// bool uptodate();
+void gen124(stack *Stack)
+{
+#line 2039 "runtime.in"
+ {Stack->push<bool>(interact::uptodate); return;}
+}
+
+
+// System commands
+#line 2045 "runtime.in"
+// Int system(string s);
+void gen125(stack *Stack)
+{
+ string s=vm::pop<string>(Stack);
+#line 2046 "runtime.in"
+ if(safe) error("system() call disabled; override with option -nosafe");
+ if(s.empty()) {Stack->push<Int>(0); return;}
+ else {Stack->push<Int>(System(s.c_str())); return;}
+}
+
+#line 2053 "runtime.in"
+// bool view();
+void gen126(stack *Stack)
+{
+#line 2054 "runtime.in"
+ {Stack->push<bool>(view()); return;}
+}
+
+#line 2058 "runtime.in"
+// string asydir();
+void gen127(stack *Stack)
+{
+#line 2059 "runtime.in"
+ {Stack->push<string>(systemDir); return;}
+}
+
+#line 2063 "runtime.in"
+// string locale(string s=emptystring);
+void gen128(stack *Stack)
+{
+ string s=vm::pop<string>(Stack,emptystring);
+#line 2064 "runtime.in"
+ char *L=setlocale(LC_ALL,s.empty() ? NULL : s.c_str());
+ {Stack->push<string>(L != NULL ? string(L) : ""); return;}
+}
+
+#line 2069 "runtime.in"
+// void abort(string s=emptystring);
+void gen129(stack *Stack)
+{
+ string s=vm::pop<string>(Stack,emptystring);
+#line 2070 "runtime.in"
+ if(s.empty()) throw handled_error();
+ error(s.c_str());
+}
+
+#line 2075 "runtime.in"
+// void exit();
+void gen130(stack *)
+{
+#line 2076 "runtime.in"
+ throw quit();
+}
+
+#line 2080 "runtime.in"
+// void assert(bool b, string s=emptystring);
+void gen131(stack *Stack)
+{
+ string s=vm::pop<string>(Stack,emptystring);
+ bool b=vm::pop<bool>(Stack);
+#line 2081 "runtime.in"
+ flush(cout);
+ if(!b) {
+ ostringstream buf;
+ buf << "assert FAILED";
+ if(s != "") buf << ": " << s << endl;
+ error(buf);
+ }
+}
+
+#line 2091 "runtime.in"
+// void sleep(Int seconds);
+void gen132(stack *Stack)
+{
+ Int seconds=vm::pop<Int>(Stack);
+#line 2092 "runtime.in"
+ if(seconds <= 0) return;
+ sleep(seconds);
+}
+
+#line 2097 "runtime.in"
+// void usleep(Int microseconds);
+void gen133(stack *Stack)
+{
+ Int microseconds=vm::pop<Int>(Stack);
+#line 2098 "runtime.in"
+ if(microseconds <= 0) return;
+ usleep((unsigned long) microseconds);
+}
+
+#line 2103 "runtime.in"
+// void _eval(string *s, bool embedded, bool interactiveWrite=false);
+void gen134(stack *Stack)
+{
+ bool interactiveWrite=vm::pop<bool>(Stack,false);
+ bool embedded=vm::pop<bool>(Stack);
+ string * s=vm::pop<string *>(Stack);
+#line 2104 "runtime.in"
+ if (embedded) {
+ trans::coenv *e=Stack->getEnvironment();
+ vm::interactiveStack *is=dynamic_cast<vm::interactiveStack *>(Stack);
+ if (e && is) {
+ runStringEmbedded(*s, *e, *is);
+ } else {
+ cerr << "no runtime environment for embedded eval" << endl;
+ }
+ } else {
+ runString(*s,interactiveWrite);
+ }
+}
+
+#line 2118 "runtime.in"
+// void _eval(runnable *s, bool embedded);
+void gen135(stack *Stack)
+{
+ bool embedded=vm::pop<bool>(Stack);
+ runnable * s=vm::pop<runnable *>(Stack);
+#line 2119 "runtime.in"
+ absyntax::block *ast=new absyntax::block(s->getPos(), false);
+ ast->add(s);
+
+ if (embedded) {
+ trans::coenv *e=Stack->getEnvironment();
+ vm::interactiveStack *is=dynamic_cast<vm::interactiveStack *>(Stack);
+ if (e && is) {
+ runCodeEmbedded(ast, *e, *is);
+ } else {
+ cerr << "no runtime environment for embedded eval" << endl;
+ }
+ } else {
+ runCode(ast);
+ }
+}
+
+#line 2136 "runtime.in"
+// string location();
+void gen136(stack *Stack)
+{
+#line 2137 "runtime.in"
+ ostringstream buf;
+ buf << getPos();
+ {Stack->push<string>(buf.str()); return;}
+}
+
+// Wrapper for the stack::load() method.
+#line 2143 "runtime.in"
+void loadModule(stack *Stack)
+{
+ string * index=vm::pop<string *>(Stack);
+#line 2144 "runtime.in"
+ Stack->load(*index);
+}
+
+#line 2148 "runtime.in"
+// string cd(string s=emptystring);
+void gen138(stack *Stack)
+{
+ string s=vm::pop<string>(Stack,emptystring);
+#line 2149 "runtime.in"
+ if(!s.empty() && !globalwrite()) writeDisabled();
+ {Stack->push<string>(setPath(s.c_str())); return;}
+}
+
+#line 2154 "runtime.in"
+// void list(string *s, bool imports=false);
+void gen139(stack *Stack)
+{
+ bool imports=vm::pop<bool>(Stack,false);
+ string * s=vm::pop<string *>(Stack);
+#line 2155 "runtime.in"
+ if(*s == "-") return;
+ trans::genv ge;
+ symbol *name=symbol::trans(*s);
+ record *r=ge.getModule(name,*s);
+ r->e.list(imports ? 0 : r);
+}
+
+
+// Path operations
+#line 2165 "runtime.in"
+void nullPath(stack *Stack)
+{
+#line 2166 "runtime.in"
+ {Stack->push<path>(nullpath); return;}
+}
+
+#line 2171 "runtime.in"
+// bool ==(path a, path b);
+void gen141(stack *Stack)
+{
+ path b=vm::pop<path>(Stack);
+ path a=vm::pop<path>(Stack);
+#line 2172 "runtime.in"
+ {Stack->push<bool>(a == b); return;}
+}
+
+#line 2176 "runtime.in"
+// bool !=(path a, path b);
+void gen142(stack *Stack)
+{
+ path b=vm::pop<path>(Stack);
+ path a=vm::pop<path>(Stack);
+#line 2177 "runtime.in"
+ {Stack->push<bool>(!(a == b)); return;}
+}
+
+#line 2181 "runtime.in"
+// pair point(path p, Int t);
+void gen143(stack *Stack)
+{
+ Int t=vm::pop<Int>(Stack);
+ path p=vm::pop<path>(Stack);
+#line 2182 "runtime.in"
+ {Stack->push<pair>(p.point((Int) t)); return;}
+}
+
+#line 2186 "runtime.in"
+// pair point(path p, real t);
+void gen144(stack *Stack)
+{
+ real t=vm::pop<real>(Stack);
+ path p=vm::pop<path>(Stack);
+#line 2187 "runtime.in"
+ {Stack->push<pair>(p.point(t)); return;}
+}
+
+#line 2191 "runtime.in"
+// pair precontrol(path p, Int t);
+void gen145(stack *Stack)
+{
+ Int t=vm::pop<Int>(Stack);
+ path p=vm::pop<path>(Stack);
+#line 2192 "runtime.in"
+ {Stack->push<pair>(p.precontrol((Int) t)); return;}
+}
+
+#line 2196 "runtime.in"
+// pair precontrol(path p, real t);
+void gen146(stack *Stack)
+{
+ real t=vm::pop<real>(Stack);
+ path p=vm::pop<path>(Stack);
+#line 2197 "runtime.in"
+ {Stack->push<pair>(p.precontrol(t)); return;}
+}
+
+#line 2201 "runtime.in"
+// pair postcontrol(path p, Int t);
+void gen147(stack *Stack)
+{
+ Int t=vm::pop<Int>(Stack);
+ path p=vm::pop<path>(Stack);
+#line 2202 "runtime.in"
+ {Stack->push<pair>(p.postcontrol((Int) t)); return;}
+}
+
+#line 2206 "runtime.in"
+// pair postcontrol(path p, real t);
+void gen148(stack *Stack)
+{
+ real t=vm::pop<real>(Stack);
+ path p=vm::pop<path>(Stack);
+#line 2207 "runtime.in"
+ {Stack->push<pair>(p.postcontrol(t)); return;}
+}
+
+#line 2211 "runtime.in"
+// pair dir(path p, Int t, Int sign=0, bool normalize=true);
+void gen149(stack *Stack)
+{
+ bool normalize=vm::pop<bool>(Stack,true);
+ Int sign=vm::pop<Int>(Stack,0);
+ Int t=vm::pop<Int>(Stack);
+ path p=vm::pop<path>(Stack);
+#line 2212 "runtime.in"
+ {Stack->push<pair>(p.dir(t,sign,normalize)); return;}
+}
+
+#line 2216 "runtime.in"
+// pair dir(path p, real t, bool normalize=true);
+void gen150(stack *Stack)
+{
+ bool normalize=vm::pop<bool>(Stack,true);
+ real t=vm::pop<real>(Stack);
+ path p=vm::pop<path>(Stack);
+#line 2217 "runtime.in"
+ {Stack->push<pair>(p.dir(t,normalize)); return;}
+}
+
+#line 2221 "runtime.in"
+// pair accel(path p, Int t, Int sign=0);
+void gen151(stack *Stack)
+{
+ Int sign=vm::pop<Int>(Stack,0);
+ Int t=vm::pop<Int>(Stack);
+ path p=vm::pop<path>(Stack);
+#line 2222 "runtime.in"
+ {Stack->push<pair>(p.accel(t,sign)); return;}
+}
+
+#line 2226 "runtime.in"
+// pair accel(path p, real t);
+void gen152(stack *Stack)
+{
+ real t=vm::pop<real>(Stack);
+ path p=vm::pop<path>(Stack);
+#line 2227 "runtime.in"
+ {Stack->push<pair>(p.accel(t)); return;}
+}
+
+#line 2231 "runtime.in"
+// real radius(path p, real t);
+void gen153(stack *Stack)
+{
+ real t=vm::pop<real>(Stack);
+ path p=vm::pop<path>(Stack);
+#line 2232 "runtime.in"
+ pair v=p.dir(t,false);
+ pair a=p.accel(t);
+ real d=dot(a,v);
+ real v2=v.abs2();
+ real a2=a.abs2();
+ real denom=v2*a2-d*d;
+ real r=v2*sqrt(v2);
+ {Stack->push<real>(denom > 0 ? r/sqrt(denom) : 0.0); return;}
+}
+
+#line 2243 "runtime.in"
+// path reverse(path p);
+void gen154(stack *Stack)
+{
+ path p=vm::pop<path>(Stack);
+#line 2244 "runtime.in"
+ {Stack->push<path>(p.reverse()); return;}
+}
+
+#line 2248 "runtime.in"
+// path subpath(path p, Int a, Int b);
+void gen155(stack *Stack)
+{
+ Int b=vm::pop<Int>(Stack);
+ Int a=vm::pop<Int>(Stack);
+ path p=vm::pop<path>(Stack);
+#line 2249 "runtime.in"
+ {Stack->push<path>(p.subpath((Int) a, (Int) b)); return;}
+}
+
+#line 2253 "runtime.in"
+// path subpath(path p, real a, real b);
+void gen156(stack *Stack)
+{
+ real b=vm::pop<real>(Stack);
+ real a=vm::pop<real>(Stack);
+ path p=vm::pop<path>(Stack);
+#line 2254 "runtime.in"
+ {Stack->push<path>(p.subpath(a,b)); return;}
+}
+
+#line 2258 "runtime.in"
+// path nurb(pair z0, pair z1, pair z2, pair z3, real w0, real w1, real w2, real w3, Int m);
+void gen157(stack *Stack)
+{
+ Int m=vm::pop<Int>(Stack);
+ real w3=vm::pop<real>(Stack);
+ real w2=vm::pop<real>(Stack);
+ real w1=vm::pop<real>(Stack);
+ real w0=vm::pop<real>(Stack);
+ pair z3=vm::pop<pair>(Stack);
+ pair z2=vm::pop<pair>(Stack);
+ pair z1=vm::pop<pair>(Stack);
+ pair z0=vm::pop<pair>(Stack);
+#line 2260 "runtime.in"
+ {Stack->push<path>(nurb(z0,z1,z2,z3,w0,w1,w2,w3,m)); return;}
+}
+
+#line 2264 "runtime.in"
+// Int length(path p);
+void gen158(stack *Stack)
+{
+ path p=vm::pop<path>(Stack);
+#line 2265 "runtime.in"
+ {Stack->push<Int>(p.length()); return;}
+}
+
+#line 2269 "runtime.in"
+// bool cyclic(path p);
+void gen159(stack *Stack)
+{
+ path p=vm::pop<path>(Stack);
+#line 2270 "runtime.in"
+ {Stack->push<bool>(p.cyclic()); return;}
+}
+
+#line 2274 "runtime.in"
+// bool straight(path p, Int t);
+void gen160(stack *Stack)
+{
+ Int t=vm::pop<Int>(Stack);
+ path p=vm::pop<path>(Stack);
+#line 2275 "runtime.in"
+ {Stack->push<bool>(p.straight(t)); return;}
+}
+
+#line 2279 "runtime.in"
+// path unstraighten(path p);
+void gen161(stack *Stack)
+{
+ path p=vm::pop<path>(Stack);
+#line 2280 "runtime.in"
+ {Stack->push<path>(p.unstraighten()); return;}
+}
+
+#line 2284 "runtime.in"
+// bool piecewisestraight(path p);
+void gen162(stack *Stack)
+{
+ path p=vm::pop<path>(Stack);
+#line 2285 "runtime.in"
+ {Stack->push<bool>(p.piecewisestraight()); return;}
+}
+
+#line 2289 "runtime.in"
+// real arclength(path p);
+void gen163(stack *Stack)
+{
+ path p=vm::pop<path>(Stack);
+#line 2290 "runtime.in"
+ {Stack->push<real>(p.arclength()); return;}
+}
+
+#line 2294 "runtime.in"
+// real arctime(path p, real dval);
+void gen164(stack *Stack)
+{
+ real dval=vm::pop<real>(Stack);
+ path p=vm::pop<path>(Stack);
+#line 2295 "runtime.in"
+ {Stack->push<real>(p.arctime(dval)); return;}
+}
+
+#line 2299 "runtime.in"
+// real dirtime(path p, pair z);
+void gen165(stack *Stack)
+{
+ pair z=vm::pop<pair>(Stack);
+ path p=vm::pop<path>(Stack);
+#line 2300 "runtime.in"
+ {Stack->push<real>(p.directiontime(z)); return;}
+}
+
+#line 2304 "runtime.in"
+// realarray* intersect(path p, path q, real fuzz=-1);
+void gen166(stack *Stack)
+{
+ real fuzz=vm::pop<real>(Stack,-1);
+ path q=vm::pop<path>(Stack);
+ path p=vm::pop<path>(Stack);
+#line 2305 "runtime.in"
+ bool exact=fuzz <= 0.0;
+ if(fuzz < 0)
+ fuzz=BigFuzz*::max(::max(length(p.max()),length(p.min())),
+ ::max(length(q.max()),length(q.min())));
+ std::vector<real> S,T;
+ real s,t;
+ if(intersections(s,t,S,T,p,q,fuzz,true,exact)) {
+ array *V=new array(2);
+ (*V)[0]=s;
+ (*V)[1]=t;
+ {Stack->push<realarray*>(V); return;}
+ } else
+ {Stack->push<realarray*>(new array(0)); return;}
+}
+
+#line 2321 "runtime.in"
+// realarray2* intersections(path p, path q, real fuzz=-1);
+void gen167(stack *Stack)
+{
+ real fuzz=vm::pop<real>(Stack,-1);
+ path q=vm::pop<path>(Stack);
+ path p=vm::pop<path>(Stack);
+#line 2322 "runtime.in"
+ bool exact=fuzz <= 0.0;
+ if(fuzz < 0.0)
+ fuzz=BigFuzz*::max(::max(length(p.max()),length(p.min())),
+ ::max(length(q.max()),length(q.min())));
+ real s,t;
+ std::vector<real> S,T;
+ intersections(s,t,S,T,p,q,fuzz,false,true);
+ size_t n=S.size();
+ if(n == 0 && !exact) {
+ if(intersections(s,t,S,T,p,q,fuzz,true,false)) {
+ array *V=new array(1);
+ array *Vi=new array(2);
+ (*V)[0]=Vi;
+ (*Vi)[0]=s;
+ (*Vi)[1]=t;
+ {Stack->push<realarray2*>(V); return;}
+ }
+ }
+ array *V=new array(n);
+ for(size_t i=0; i < n; ++i) {
+ array *Vi=new array(2);
+ (*V)[i]=Vi;
+ (*Vi)[0]=S[i];
+ (*Vi)[1]=T[i];
+ }
+ stable_sort(V->begin(),V->end(),run::compare2<real>());
+ {Stack->push<realarray2*>(V); return;}
+}
+
+#line 2352 "runtime.in"
+// realarray* intersections(path p, explicit pair a, explicit pair b, real fuzz=-1);
+void gen168(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 2353 "runtime.in"
+ if(fuzz < 0)
+ fuzz=BigFuzz*::max(::max(length(p.max()),length(p.min())),
+ ::max(length(a),length(b)));
+ std::vector<real> S;
+ intersections(S,p,a,b,fuzz);
+ sort(S.begin(),S.end());
+ size_t n=S.size();
+ array *V=new array(n);
+ for(size_t i=0; i < n; ++i)
+ (*V)[i]=S[i];
+ {Stack->push<realarray*>(V); return;}
+}
+
+// Return the intersection point of the extensions of the line segments
+// PQ and pq.
+#line 2369 "runtime.in"
+// pair extension(pair P, pair Q, pair p, pair q);
+void gen169(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 2370 "runtime.in"
+ pair ac=P-Q;
+ pair bd=q-p;
+ real det=ac.getx()*bd.gety()-ac.gety()*bd.getx();
+ if(det == 0) {Stack->push<pair>(pair(infinity,infinity)); return;}
+ {Stack->push<pair>(P+((p.getx()-P.getx())*bd.gety()-(p.gety()-P.gety())*bd.getx())*ac/det); return;}
+}
+
+#line 2378 "runtime.in"
+// Int size(path p);
+void gen170(stack *Stack)
+{
+ path p=vm::pop<path>(Stack);
+#line 2379 "runtime.in"
+ {Stack->push<Int>(p.size()); return;}
+}
+
+#line 2383 "runtime.in"
+// path &(path p, path q);
+void gen171(stack *Stack)
+{
+ path q=vm::pop<path>(Stack);
+ path p=vm::pop<path>(Stack);
+#line 2384 "runtime.in"
+ {Stack->push<path>(camp::concat(p,q)); return;}
+}
+
+#line 2388 "runtime.in"
+// pair min(path p);
+void gen172(stack *Stack)
+{
+ path p=vm::pop<path>(Stack);
+#line 2389 "runtime.in"
+ {Stack->push<pair>(p.min()); return;}
+}
+
+#line 2393 "runtime.in"
+// pair max(path p);
+void gen173(stack *Stack)
+{
+ path p=vm::pop<path>(Stack);
+#line 2394 "runtime.in"
+ {Stack->push<pair>(p.max()); return;}
+}
+
+#line 2398 "runtime.in"
+// realarray* mintimes(path p);
+void gen174(stack *Stack)
+{
+ path p=vm::pop<path>(Stack);
+#line 2399 "runtime.in"
+ array *V=new array(2);
+ pair z=p.mintimes();
+ (*V)[0]=z.getx();
+ (*V)[1]=z.gety();
+ {Stack->push<realarray*>(V); return;}
+}
+
+#line 2407 "runtime.in"
+// realarray* maxtimes(path p);
+void gen175(stack *Stack)
+{
+ path p=vm::pop<path>(Stack);
+#line 2408 "runtime.in"
+ array *V=new array(2);
+ pair z=p.maxtimes();
+ (*V)[0]=z.getx();
+ (*V)[1]=z.gety();
+ {Stack->push<realarray*>(V); return;}
+}
+
+#line 2416 "runtime.in"
+// real relativedistance(real theta, real phi, real t, bool atleast);
+void gen176(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 2417 "runtime.in"
+ {Stack->push<real>(camp::velocity(theta,phi,tension(t,atleast))); return;}
+}
+
+#line 2421 "runtime.in"
+// Int windingnumber(patharray *p, pair z);
+void gen177(stack *Stack)
+{
+ pair z=vm::pop<pair>(Stack);
+ patharray * p=vm::pop<patharray *>(Stack);
+#line 2422 "runtime.in"
+ {Stack->push<Int>(windingnumber(p,z)); return;}
+}
+
+#line 2426 "runtime.in"
+// bool inside(explicit patharray *g, pair z, pen fillrule=CURRENTPEN);
+void gen178(stack *Stack)
+{
+ pen fillrule=vm::pop<pen>(Stack,CURRENTPEN);
+ pair z=vm::pop<pair>(Stack);
+ patharray * g=vm::pop<patharray *>(Stack);
+#line 2427 "runtime.in"
+ {Stack->push<bool>(fillrule.inside(windingnumber(g,z))); return;}
+}
+
+#line 2431 "runtime.in"
+// bool inside(path g, pair z, pen fillrule=CURRENTPEN);
+void gen179(stack *Stack)
+{
+ pen fillrule=vm::pop<pen>(Stack,CURRENTPEN);
+ pair z=vm::pop<pair>(Stack);
+ path g=vm::pop<path>(Stack);
+#line 2432 "runtime.in"
+ {Stack->push<bool>(fillrule.inside(g.windingnumber(z))); return;}
+}
+
+// Determine the side of a--b that c lies on
+// (negative=left, zero=on line, positive=right).
+#line 2438 "runtime.in"
+// real side(pair a, pair b, pair c);
+void gen180(stack *Stack)
+{
+ pair c=vm::pop<pair>(Stack);
+ pair b=vm::pop<pair>(Stack);
+ pair a=vm::pop<pair>(Stack);
+#line 2439 "runtime.in"
+ {Stack->push<real>(orient2d(a,b,c)); return;}
+}
+
+// Determine the side of the counterclockwise circle through a,b,c that d
+// lies on (negative=inside, 0=on circle, positive=right).
+#line 2445 "runtime.in"
+// real incircle(pair a, pair b, pair c, pair d);
+void gen181(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 2446 "runtime.in"
+ {Stack->push<real>(incircle(a.getx(),a.gety(),b.getx(),b.gety(),c.getx(),c.gety(),
+ d.getx(),d.gety())); return;}
+}
+
+
+// Path3 operations
+#line 2453 "runtime.in"
+// path3 path3(triplearray *pre, triplearray *point, triplearray *post, boolarray *straight, bool cyclic);
+void gen182(stack *Stack)
+{
+ bool cyclic=vm::pop<bool>(Stack);
+ boolarray * straight=vm::pop<boolarray *>(Stack);
+ triplearray * post=vm::pop<triplearray *>(Stack);
+ triplearray * point=vm::pop<triplearray *>(Stack);
+ triplearray * pre=vm::pop<triplearray *>(Stack);
+#line 2455 "runtime.in"
+ size_t n=checkArrays(pre,point);
+ checkEqual(n,checkArray(post));
+ checkEqual(n,checkArray(straight));
+ mem::vector<solvedKnot3> nodes(n);
+ for(size_t i=0; i < n; ++i) {
+ nodes[i].pre=read<triple>(pre,i);
+ nodes[i].point=read<triple>(point,i);
+ nodes[i].post=read<triple>(post,i);
+ nodes[i].straight=read<bool>(straight,i);
+ }
+
+ {Stack->push<path3>(path3(nodes,(Int) n,cyclic)); return;}
+}
+
+#line 2471 "runtime.in"
+void nullPath3(stack *Stack)
+{
+#line 2472 "runtime.in"
+ {Stack->push<path3>(nullpath3); return;}
+}
+
+#line 2476 "runtime.in"
+// bool ==(path3 a, path3 b);
+void gen184(stack *Stack)
+{
+ path3 b=vm::pop<path3>(Stack);
+ path3 a=vm::pop<path3>(Stack);
+#line 2477 "runtime.in"
+ {Stack->push<bool>(a == b); return;}
+}
+
+#line 2481 "runtime.in"
+// bool !=(path3 a, path3 b);
+void gen185(stack *Stack)
+{
+ path3 b=vm::pop<path3>(Stack);
+ path3 a=vm::pop<path3>(Stack);
+#line 2482 "runtime.in"
+ {Stack->push<bool>(!(a == b)); return;}
+}
+
+#line 2486 "runtime.in"
+// triple point(path3 p, Int t);
+void gen186(stack *Stack)
+{
+ Int t=vm::pop<Int>(Stack);
+ path3 p=vm::pop<path3>(Stack);
+#line 2487 "runtime.in"
+ {Stack->push<triple>(p.point((Int) t)); return;}
+}
+
+#line 2491 "runtime.in"
+// triple point(path3 p, real t);
+void gen187(stack *Stack)
+{
+ real t=vm::pop<real>(Stack);
+ path3 p=vm::pop<path3>(Stack);
+#line 2492 "runtime.in"
+ {Stack->push<triple>(p.point(t)); return;}
+}
+
+#line 2496 "runtime.in"
+// triple precontrol(path3 p, Int t);
+void gen188(stack *Stack)
+{
+ Int t=vm::pop<Int>(Stack);
+ path3 p=vm::pop<path3>(Stack);
+#line 2497 "runtime.in"
+ {Stack->push<triple>(p.precontrol((Int) t)); return;}
+}
+
+#line 2501 "runtime.in"
+// triple precontrol(path3 p, real t);
+void gen189(stack *Stack)
+{
+ real t=vm::pop<real>(Stack);
+ path3 p=vm::pop<path3>(Stack);
+#line 2502 "runtime.in"
+ {Stack->push<triple>(p.precontrol(t)); return;}
+}
+
+#line 2506 "runtime.in"
+// triple postcontrol(path3 p, Int t);
+void gen190(stack *Stack)
+{
+ Int t=vm::pop<Int>(Stack);
+ path3 p=vm::pop<path3>(Stack);
+#line 2507 "runtime.in"
+ {Stack->push<triple>(p.postcontrol((Int) t)); return;}
+}
+
+#line 2511 "runtime.in"
+// triple postcontrol(path3 p, real t);
+void gen191(stack *Stack)
+{
+ real t=vm::pop<real>(Stack);
+ path3 p=vm::pop<path3>(Stack);
+#line 2512 "runtime.in"
+ {Stack->push<triple>(p.postcontrol(t)); return;}
+}
+
+#line 2516 "runtime.in"
+// triple dir(path3 p, Int t, Int sign=0, bool normalize=true);
+void gen192(stack *Stack)
+{
+ bool normalize=vm::pop<bool>(Stack,true);
+ Int sign=vm::pop<Int>(Stack,0);
+ Int t=vm::pop<Int>(Stack);
+ path3 p=vm::pop<path3>(Stack);
+#line 2517 "runtime.in"
+ {Stack->push<triple>(p.dir(t,sign,normalize)); return;}
+}
+
+#line 2521 "runtime.in"
+// triple dir(path3 p, real t, bool normalize=true);
+void gen193(stack *Stack)
+{
+ bool normalize=vm::pop<bool>(Stack,true);
+ real t=vm::pop<real>(Stack);
+ path3 p=vm::pop<path3>(Stack);
+#line 2522 "runtime.in"
+ {Stack->push<triple>(p.dir(t,normalize)); return;}
+}
+
+#line 2526 "runtime.in"
+// triple accel(path3 p, Int t, Int sign=0);
+void gen194(stack *Stack)
+{
+ Int sign=vm::pop<Int>(Stack,0);
+ Int t=vm::pop<Int>(Stack);
+ path3 p=vm::pop<path3>(Stack);
+#line 2527 "runtime.in"
+ {Stack->push<triple>(p.accel(t,sign)); return;}
+}
+
+#line 2531 "runtime.in"
+// triple accel(path3 p, real t);
+void gen195(stack *Stack)
+{
+ real t=vm::pop<real>(Stack);
+ path3 p=vm::pop<path3>(Stack);
+#line 2532 "runtime.in"
+ {Stack->push<triple>(p.accel(t)); return;}
+}
+
+#line 2536 "runtime.in"
+// real radius(path3 p, real t);
+void gen196(stack *Stack)
+{
+ real t=vm::pop<real>(Stack);
+ path3 p=vm::pop<path3>(Stack);
+#line 2537 "runtime.in"
+ triple v=p.dir(t,false);
+ triple a=p.accel(t);
+ real d=dot(a,v);
+ real v2=v.abs2();
+ real a2=a.abs2();
+ real denom=v2*a2-d*d;
+ real r=v2*sqrt(v2);
+ {Stack->push<real>(denom > 0 ? r/sqrt(denom) : 0.0); return;}
+}
+
+#line 2548 "runtime.in"
+// real radius(triple z0, triple c0, triple c1, triple z1, real t);
+void gen197(stack *Stack)
+{
+ real t=vm::pop<real>(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 2549 "runtime.in"
+ triple v=(3.0*(z1-z0)+9.0*(c0-c1))*t*t+(6.0*(z0+c1)-12.0*c0)*t+3.0*(c0-z0);
+ triple a=6.0*(z1-z0+3.0*(c0-c1))*t+6.0*(z0+c1)-12.0*c0;
+ real d=dot(a,v);
+ real v2=v.abs2();
+ real a2=a.abs2();
+ real denom=v2*a2-d*d;
+ real r=v2*sqrt(v2);
+ {Stack->push<real>(denom > 0 ? r/sqrt(denom) : 0.0); return;}
+}
+
+#line 2560 "runtime.in"
+// path3 reverse(path3 p);
+void gen198(stack *Stack)
+{
+ path3 p=vm::pop<path3>(Stack);
+#line 2561 "runtime.in"
+ {Stack->push<path3>(p.reverse()); return;}
+}
+
+#line 2565 "runtime.in"
+// path3 subpath(path3 p, Int a, Int b);
+void gen199(stack *Stack)
+{
+ Int b=vm::pop<Int>(Stack);
+ Int a=vm::pop<Int>(Stack);
+ path3 p=vm::pop<path3>(Stack);
+#line 2566 "runtime.in"
+ {Stack->push<path3>(p.subpath((Int) a, (Int) b)); return;}
+}
+
+#line 2570 "runtime.in"
+// path3 subpath(path3 p, real a, real b);
+void gen200(stack *Stack)
+{
+ real b=vm::pop<real>(Stack);
+ real a=vm::pop<real>(Stack);
+ path3 p=vm::pop<path3>(Stack);
+#line 2571 "runtime.in"
+ {Stack->push<path3>(p.subpath(a,b)); return;}
+}
+
+#line 2575 "runtime.in"
+// Int length(path3 p);
+void gen201(stack *Stack)
+{
+ path3 p=vm::pop<path3>(Stack);
+#line 2576 "runtime.in"
+ {Stack->push<Int>(p.length()); return;}
+}
+
+#line 2580 "runtime.in"
+// bool cyclic(path3 p);
+void gen202(stack *Stack)
+{
+ path3 p=vm::pop<path3>(Stack);
+#line 2581 "runtime.in"
+ {Stack->push<bool>(p.cyclic()); return;}
+}
+
+#line 2585 "runtime.in"
+// bool straight(path3 p, Int t);
+void gen203(stack *Stack)
+{
+ Int t=vm::pop<Int>(Stack);
+ path3 p=vm::pop<path3>(Stack);
+#line 2586 "runtime.in"
+ {Stack->push<bool>(p.straight(t)); return;}
+}
+
+// Return the component of vector v perpendicular to a unit vector u.
+#line 2591 "runtime.in"
+// triple perp(triple v, triple u);
+void gen204(stack *Stack)
+{
+ triple u=vm::pop<triple>(Stack);
+ triple v=vm::pop<triple>(Stack);
+#line 2592 "runtime.in"
+ {Stack->push<triple>(v-dot(v,u)*u); return;}
+}
+
+// Return the maximum perpendicular deviation of segment i of path3 g
+// from a straight line.
+#line 2598 "runtime.in"
+// real straightness(path3 p, Int t);
+void gen205(stack *Stack)
+{
+ Int t=vm::pop<Int>(Stack);
+ path3 p=vm::pop<path3>(Stack);
+#line 2599 "runtime.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;}
+}
+
+// Return the maximum perpendicular deviation of z0..controls c0 and c1..z1
+// from a straight line.
+#line 2609 "runtime.in"
+// real straightness(triple z0, triple c0, triple c1, triple z1);
+void gen206(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 2610 "runtime.in"
+ triple u=unit(z1-z0);
+ {Stack->push<real>(::max(length(perp(c0-z0,u)),length(perp(c1-z0,u)))); return;}
+}
+
+#line 2615 "runtime.in"
+// bool piecewisestraight(path3 p);
+void gen207(stack *Stack)
+{
+ path3 p=vm::pop<path3>(Stack);
+#line 2616 "runtime.in"
+ {Stack->push<bool>(p.piecewisestraight()); return;}
+}
+
+#line 2620 "runtime.in"
+// real arclength(path3 p);
+void gen208(stack *Stack)
+{
+ path3 p=vm::pop<path3>(Stack);
+#line 2621 "runtime.in"
+ {Stack->push<real>(p.arclength()); return;}
+}
+
+#line 2625 "runtime.in"
+// real arctime(path3 p, real dval);
+void gen209(stack *Stack)
+{
+ real dval=vm::pop<real>(Stack);
+ path3 p=vm::pop<path3>(Stack);
+#line 2626 "runtime.in"
+ {Stack->push<real>(p.arctime(dval)); return;}
+}
+
+#line 2630 "runtime.in"
+// realarray* intersect(path3 p, path3 q, real fuzz=-1);
+void gen210(stack *Stack)
+{
+ real fuzz=vm::pop<real>(Stack,-1);
+ path3 q=vm::pop<path3>(Stack);
+ path3 p=vm::pop<path3>(Stack);
+#line 2631 "runtime.in"
+ bool exact=fuzz <= 0.0;
+ if(fuzz < 0)
+ fuzz=BigFuzz*::max(::max(length(p.max()),length(p.min())),
+ ::max(length(q.max()),length(q.min())));
+
+ std::vector<real> S,T;
+ real s,t;
+ if(intersections(s,t,S,T,p,q,fuzz,true,exact)) {
+ array *V=new array(2);
+ (*V)[0]=s;
+ (*V)[1]=t;
+ {Stack->push<realarray*>(V); return;}
+ } else
+ {Stack->push<realarray*>(new array(0)); return;}
+}
+
+#line 2648 "runtime.in"
+// realarray2* intersections(path3 p, path3 q, real fuzz=-1);
+void gen211(stack *Stack)
+{
+ real fuzz=vm::pop<real>(Stack,-1);
+ path3 q=vm::pop<path3>(Stack);
+ path3 p=vm::pop<path3>(Stack);
+#line 2649 "runtime.in"
+ bool exact=fuzz <= 0.0;
+ if(fuzz < 0)
+ fuzz=BigFuzz*::max(::max(length(p.max()),length(p.min())),
+ ::max(length(q.max()),length(q.min())));
+ bool single=!exact;
+
+ real s,t;
+ std::vector<real> S,T;
+ bool found=intersections(s,t,S,T,p,q,fuzz,single,exact);
+ if(!found) {Stack->push<realarray2*>(new array(0)); return;}
+ array *V;
+ if(single) {
+ V=new array(1);
+ array *Vi=new array(2);
+ (*V)[0]=Vi;
+ (*Vi)[0]=s;
+ (*Vi)[1]=t;
+ } else {
+ size_t n=S.size();
+ V=new array(n);
+ for(size_t i=0; i < n; ++i) {
+ array *Vi=new array(2);
+ (*V)[i]=Vi;
+ (*Vi)[0]=S[i];
+ (*Vi)[1]=T[i];
+ }
+ }
+ stable_sort(V->begin(),V->end(),run::compare2<real>());
+ {Stack->push<realarray2*>(V); return;}
+}
+
+#line 2681 "runtime.in"
+// Int size(path3 p);
+void gen212(stack *Stack)
+{
+ path3 p=vm::pop<path3>(Stack);
+#line 2682 "runtime.in"
+ {Stack->push<Int>(p.size()); return;}
+}
+
+#line 2686 "runtime.in"
+// path3 &(path3 p, path3 q);
+void gen213(stack *Stack)
+{
+ path3 q=vm::pop<path3>(Stack);
+ path3 p=vm::pop<path3>(Stack);
+#line 2687 "runtime.in"
+ {Stack->push<path3>(camp::concat(p,q)); return;}
+}
+
+#line 2691 "runtime.in"
+// triple min(path3 p);
+void gen214(stack *Stack)
+{
+ path3 p=vm::pop<path3>(Stack);
+#line 2692 "runtime.in"
+ {Stack->push<triple>(p.min()); return;}
+}
+
+#line 2696 "runtime.in"
+// triple max(path3 p);
+void gen215(stack *Stack)
+{
+ path3 p=vm::pop<path3>(Stack);
+#line 2697 "runtime.in"
+ {Stack->push<triple>(p.max()); return;}
+}
+
+#line 2701 "runtime.in"
+// realarray* mintimes(path3 p);
+void gen216(stack *Stack)
+{
+ path3 p=vm::pop<path3>(Stack);
+#line 2702 "runtime.in"
+ array *V=new array(3);
+ triple v=p.mintimes();
+ (*V)[0]=v.getx();
+ (*V)[1]=v.gety();
+ (*V)[2]=v.getz();
+ {Stack->push<realarray*>(V); return;}
+}
+
+#line 2711 "runtime.in"
+// realarray* maxtimes(path3 p);
+void gen217(stack *Stack)
+{
+ path3 p=vm::pop<path3>(Stack);
+#line 2712 "runtime.in"
+ array *V=new array(3);
+ triple v=p.maxtimes();
+ (*V)[0]=v.getx();
+ (*V)[1]=v.gety();
+ (*V)[2]=v.getz();
+ {Stack->push<realarray*>(V); return;}
+}
+
+#line 2721 "runtime.in"
+// path3 *(realarray2 *t, path3 g);
+void gen218(stack *Stack)
+{
+ path3 g=vm::pop<path3>(Stack);
+ realarray2 * t=vm::pop<realarray2 *>(Stack);
+#line 2722 "runtime.in"
+ {Stack->push<path3>(transformed(*t,g)); return;}
+}
+
+
+// Guide operations
+#line 2728 "runtime.in"
+void nullGuide(stack *Stack)
+{
+#line 2729 "runtime.in"
+ {Stack->push<guide*>(new pathguide(path())); return;}
+}
+
+#line 2734 "runtime.in"
+void dotsGuide(stack *Stack)
+{
+ guidearray * a=vm::pop<guidearray *>(Stack);
+#line 2735 "runtime.in"
+ guidevector v;
+ size_t size=checkArray(a);
+ for (size_t i=0; i < size; ++i)
+ v.push_back(a->read<guide*>(i));
+
+ {Stack->push<guide*>(new multiguide(v)); return;}
+}
+
+#line 2744 "runtime.in"
+void dashesGuide(stack *Stack)
+{
+ guidearray * a=vm::pop<guidearray *>(Stack);
+#line 2745 "runtime.in"
+ static camp::curlSpec curly;
+ static specguide curlout(&curly, camp::OUT);
+ static specguide curlin(&curly, camp::IN);
+
+ size_t n=checkArray(a);
+
+ // a--b is equivalent to a{curl 1}..{curl 1}b
+ guidevector v;
+ if (n > 0)
+ v.push_back(a->read<guide*>(0));
+
+ if (n==1) {
+ v.push_back(&curlout);
+ v.push_back(&curlin);
+ }
+ else
+ for (size_t i=1; i<n; ++i) {
+ v.push_back(&curlout);
+ v.push_back(&curlin);
+ v.push_back(a->read<guide*>(i));
+ }
+
+ {Stack->push<guide*>(new multiguide(v)); return;}
+}
+
+#line 2771 "runtime.in"
+void newCycleToken(stack *Stack)
+{
+#line 2772 "runtime.in"
+ {Stack->push<cycleToken>(cycleToken()); return;}
+}
+
+#line 2776 "runtime.in"
+// guide* operator cast(cycleToken tok);
+void gen223(stack *Stack)
+{
+ cycleToken tok=vm::pop<cycleToken>(Stack);
+#line 2777 "runtime.in"
+// Avoid unused variable warning messages.
+ unused(&tok);
+ {Stack->push<guide*>(new cycletokguide()); return;}
+}
+
+#line 2783 "runtime.in"
+// guide* operator spec(pair z, Int p);
+void gen224(stack *Stack)
+{
+ Int p=vm::pop<Int>(Stack);
+ pair z=vm::pop<pair>(Stack);
+#line 2784 "runtime.in"
+ camp::side d=(camp::side) p;
+ camp::dirSpec *sp=new camp::dirSpec(z);
+
+ {Stack->push<guide*>(new specguide(sp,d)); return;}
+}
+
+#line 2791 "runtime.in"
+// curlSpecifier operator curl(real gamma, Int p);
+void gen225(stack *Stack)
+{
+ Int p=vm::pop<Int>(Stack);
+ real gamma=vm::pop<real>(Stack);
+#line 2792 "runtime.in"
+ camp::side s=(camp::side) p;
+ {Stack->push<curlSpecifier>(curlSpecifier(gamma,s)); return;}
+}
+
+#line 2797 "runtime.in"
+void curlSpecifierValuePart(stack *Stack)
+{
+ curlSpecifier spec=vm::pop<curlSpecifier>(Stack);
+#line 2798 "runtime.in"
+ {Stack->push<real>(spec.getValue()); return;}
+}
+
+#line 2802 "runtime.in"
+void curlSpecifierSidePart(stack *Stack)
+{
+ curlSpecifier spec=vm::pop<curlSpecifier>(Stack);
+#line 2803 "runtime.in"
+ {Stack->push<Int>(spec.getSide()); return;}
+}
+
+#line 2807 "runtime.in"
+// guide* operator cast(curlSpecifier spec);
+void gen228(stack *Stack)
+{
+ curlSpecifier spec=vm::pop<curlSpecifier>(Stack);
+#line 2808 "runtime.in"
+ {Stack->push<guide*>(new specguide(spec)); return;}
+}
+
+#line 2812 "runtime.in"
+// tensionSpecifier operator tension(real tout, real tin, bool atleast);
+void gen229(stack *Stack)
+{
+ bool atleast=vm::pop<bool>(Stack);
+ real tin=vm::pop<real>(Stack);
+ real tout=vm::pop<real>(Stack);
+#line 2813 "runtime.in"
+ {Stack->push<tensionSpecifier>(tensionSpecifier(tout, tin, atleast)); return;}
+}
+
+#line 2817 "runtime.in"
+void tensionSpecifierOutPart(stack *Stack)
+{
+ tensionSpecifier t=vm::pop<tensionSpecifier>(Stack);
+#line 2818 "runtime.in"
+ {Stack->push<real>(t.getOut()); return;}
+}
+
+#line 2822 "runtime.in"
+void tensionSpecifierInPart(stack *Stack)
+{
+ tensionSpecifier t=vm::pop<tensionSpecifier>(Stack);
+#line 2823 "runtime.in"
+ {Stack->push<real>(t.getIn()); return;}
+}
+
+#line 2827 "runtime.in"
+void tensionSpecifierAtleastPart(stack *Stack)
+{
+ tensionSpecifier t=vm::pop<tensionSpecifier>(Stack);
+#line 2828 "runtime.in"
+ {Stack->push<bool>(t.getAtleast()); return;}
+}
+
+#line 2832 "runtime.in"
+// guide* operator cast(tensionSpecifier t);
+void gen233(stack *Stack)
+{
+ tensionSpecifier t=vm::pop<tensionSpecifier>(Stack);
+#line 2833 "runtime.in"
+ {Stack->push<guide*>(new tensionguide(t)); return;}
+}
+
+#line 2837 "runtime.in"
+// guide* operator controls(pair zout, pair zin);
+void gen234(stack *Stack)
+{
+ pair zin=vm::pop<pair>(Stack);
+ pair zout=vm::pop<pair>(Stack);
+#line 2838 "runtime.in"
+ {Stack->push<guide*>(new controlguide(zout, zin)); return;}
+}
+
+#line 2842 "runtime.in"
+// Int size(guide *g);
+void gen235(stack *Stack)
+{
+ guide * g=vm::pop<guide *>(Stack);
+#line 2843 "runtime.in"
+ flatguide f;
+ g->flatten(f,false);
+ {Stack->push<Int>(f.size()); return;}
+}
+
+#line 2849 "runtime.in"
+// Int length(guide *g);
+void gen236(stack *Stack)
+{
+ guide * g=vm::pop<guide *>(Stack);
+#line 2850 "runtime.in"
+ flatguide f;
+ g->flatten(f,false);
+ {Stack->push<Int>(g->cyclic() ? f.size() : f.size()-1); return;}
+}
+
+#line 2856 "runtime.in"
+// bool cyclic(guide *g);
+void gen237(stack *Stack)
+{
+ guide * g=vm::pop<guide *>(Stack);
+#line 2857 "runtime.in"
+ flatguide f;
+ g->flatten(f,false);
+ {Stack->push<bool>(g->cyclic()); return;}
+}
+
+#line 2863 "runtime.in"
+// pair point(guide *g, Int t);
+void gen238(stack *Stack)
+{
+ Int t=vm::pop<Int>(Stack);
+ guide * g=vm::pop<guide *>(Stack);
+#line 2864 "runtime.in"
+ flatguide f;
+ g->flatten(f,false);
+ {Stack->push<pair>(f.Nodes(adjustedIndex(t,f.size(),g->cyclic())).z); return;}
+}
+
+#line 2870 "runtime.in"
+// pairarray* dirSpecifier(guide *g, Int t);
+void gen239(stack *Stack)
+{
+ Int t=vm::pop<Int>(Stack);
+ guide * g=vm::pop<guide *>(Stack);
+#line 2871 "runtime.in"
+ flatguide f;
+ g->flatten(f,false);
+ Int n=f.size();
+ if(!g->cyclic() && (t < 0 || t >= n-1)) {Stack->push<pairarray*>(new array(0)); return;}
+ array *c=new array(2);
+ (*c)[0]=f.Nodes(t).out->dir();
+ (*c)[1]=f.Nodes(t+1).in->dir();
+ {Stack->push<pairarray*>(c); return;}
+}
+
+#line 2882 "runtime.in"
+// pairarray* controlSpecifier(guide *g, Int t);
+void gen240(stack *Stack)
+{
+ Int t=vm::pop<Int>(Stack);
+ guide * g=vm::pop<guide *>(Stack);
+#line 2883 "runtime.in"
+ flatguide f;
+ g->flatten(f,false);
+ Int n=f.size();
+ if(!g->cyclic() && (t < 0 || t >= n-1)) {Stack->push<pairarray*>(new array(0)); return;}
+ knot curr=f.Nodes(t);
+ knot next=f.Nodes(t+1);
+ if(curr.out->controlled()) {
+ assert(next.in->controlled());
+ array *c=new array(2);
+ (*c)[0]=curr.out->control();
+ (*c)[1]=next.in->control();
+ {Stack->push<pairarray*>(c); return;}
+ } else {Stack->push<pairarray*>(new array(0)); return;}
+}
+
+#line 2899 "runtime.in"
+// tensionSpecifier tensionSpecifier(guide *g, Int t);
+void gen241(stack *Stack)
+{
+ Int t=vm::pop<Int>(Stack);
+ guide * g=vm::pop<guide *>(Stack);
+#line 2900 "runtime.in"
+ flatguide f;
+ g->flatten(f,false);
+ Int n=f.size();
+ if(!g->cyclic() && (t < 0 || t >= n-1)) {Stack->push<tensionSpecifier>(tensionSpecifier(1.0,1.0,false)); return;}
+ knot curr=f.Nodes(t);
+ {Stack->push<tensionSpecifier>(tensionSpecifier(curr.tout.val,f.Nodes(t+1).tin.val,curr.tout.atleast)); return;}
+}
+
+#line 2909 "runtime.in"
+// realarray* curlSpecifier(guide *g, Int t);
+void gen242(stack *Stack)
+{
+ Int t=vm::pop<Int>(Stack);
+ guide * g=vm::pop<guide *>(Stack);
+#line 2910 "runtime.in"
+ flatguide f;
+ g->flatten(f,false);
+ Int n=f.size();
+ if(!g->cyclic() && (t < 0 || t >= n-1)) {Stack->push<realarray*>(new array(0)); return;}
+ array *c=new array(2);
+ real c0=f.Nodes(t).out->curl();
+ real c1=f.Nodes(t+1).in->curl();
+ (*c)[0]=c0 >= 0.0 ? c0 : 1.0;
+ (*c)[1]=c1 >= 0.0 ? c1 : 1.0;
+ {Stack->push<realarray*>(c); return;}
+}
+
+#line 2923 "runtime.in"
+// guide* reverse(guide *g);
+void gen243(stack *Stack)
+{
+ guide * g=vm::pop<guide *>(Stack);
+#line 2924 "runtime.in"
+ flatguide f;
+ g->flatten(f,false);
+ if(f.precyclic())
+ {Stack->push<guide*>(new pathguide(g->solve().reverse())); return;}
+
+ size_t n=f.size();
+ bool cyclic=g->cyclic();
+ guidevector v;
+ if(n >= 0) {
+ size_t start=cyclic ? n : n-1;
+ knot curr=f.Nodes(start);
+ knot next;
+ for(size_t i=start; i > 0; --i) {
+ next=f.Nodes(i-1);
+ v.push_back(new pairguide(curr.z));
+ if(next.out->controlled()) {
+ assert(curr.in->controlled());
+ v.push_back(new controlguide(curr.in->control(),next.out->control()));
+ } else {
+ pair d=curr.in->dir();
+ if(d != zero)
+ v.push_back(new specguide(new dirSpec(-d),camp::OUT));
+ else {
+ real C=curr.in->curl();
+ if(C >= 0.0)
+ v.push_back(new specguide(new curlSpec(C),camp::OUT));
+ }
+ real tout=curr.tin.val;
+ real tin=next.tout.val;
+ bool atleast=next.tout.atleast;
+ if(tout != 1.0 || tin != 1.0 || next.tout.atleast)
+ v.push_back(new tensionguide(tensionSpecifier(tout,tin,atleast)));
+ d=next.out->dir();
+ if(d != zero)
+ v.push_back(new specguide(new dirSpec(-d),camp::IN));
+ else {
+ real C=next.out->curl();
+ if(C >= 0.0)
+ v.push_back(new specguide(new curlSpec(C),camp::IN));
+ }
+ }
+ curr=next;
+ }
+ if(cyclic)
+ v.push_back(new cycletokguide());
+ else
+ v.push_back(new pairguide(next.z));
+
+ }
+ {Stack->push<guide*>(new multiguide(v)); return;}
+}
+
+
+// Three-dimensional picture and surface operations
+#line 2979 "runtime.in"
+// void _draw(picture *f, path3 g, pen p);
+void gen244(stack *Stack)
+{
+ pen p=vm::pop<pen>(Stack);
+ path3 g=vm::pop<path3>(Stack);
+ picture * f=vm::pop<picture *>(Stack);
+#line 2980 "runtime.in"
+ f->append(new drawPath3(g,p));
+}
+
+#line 2985 "runtime.in"
+// void draw(picture *f, triplearray2 *g, bool straight, penarray *p, real opacity, real shininess, real granularity, triple normal, bool lighton, penarray *colors);
+void gen245(stack *Stack)
+{
+ penarray * colors=vm::pop<penarray *>(Stack);
+ bool lighton=vm::pop<bool>(Stack);
+ triple normal=vm::pop<triple>(Stack);
+ real granularity=vm::pop<real>(Stack);
+ real shininess=vm::pop<real>(Stack);
+ real opacity=vm::pop<real>(Stack);
+ penarray * p=vm::pop<penarray *>(Stack);
+ bool straight=vm::pop<bool>(Stack);
+ triplearray2 * g=vm::pop<triplearray2 *>(Stack);
+ picture * f=vm::pop<picture *>(Stack);
+#line 2988 "runtime.in"
+ f->append(new drawSurface(*g,straight,*p,opacity,shininess,granularity,
+ normal,lighton,*colors));
+}
+
+#line 2993 "runtime.in"
+// triple min3(picture *f);
+void gen246(stack *Stack)
+{
+ picture * f=vm::pop<picture *>(Stack);
+#line 2994 "runtime.in"
+ {Stack->push<triple>(f->bounds3().Min()); return;}
+}
+
+#line 2998 "runtime.in"
+// triple max3(picture *f);
+void gen247(stack *Stack)
+{
+ picture * f=vm::pop<picture *>(Stack);
+#line 2999 "runtime.in"
+ {Stack->push<triple>(f->bounds3().Max()); return;}
+}
+
+#line 3003 "runtime.in"
+// pair min(picture *f, realarray2 *t);
+void gen248(stack *Stack)
+{
+ realarray2 * t=vm::pop<realarray2 *>(Stack);
+ picture * f=vm::pop<picture *>(Stack);
+#line 3004 "runtime.in"
+ real *T=copyArray2C(t,4);
+ pair m=f->bounds(::min,xproject,yproject,T);
+ delete[] T;
+ {Stack->push<pair>(m); return;}
+}
+
+#line 3011 "runtime.in"
+// pair max(picture *f, realarray2 *t);
+void gen249(stack *Stack)
+{
+ realarray2 * t=vm::pop<realarray2 *>(Stack);
+ picture * f=vm::pop<picture *>(Stack);
+#line 3012 "runtime.in"
+ real *T=copyArray2C(t,4);
+ pair M=f->bounds(::max,xproject,yproject,T);
+ delete[] T;
+ {Stack->push<pair>(M); return;}
+}
+
+#line 3019 "runtime.in"
+// pair minratio(picture *f);
+void gen250(stack *Stack)
+{
+ picture * f=vm::pop<picture *>(Stack);
+#line 3020 "runtime.in"
+ {Stack->push<pair>(f->bounds(::min,xratio,yratio)); return;}
+}
+
+#line 3024 "runtime.in"
+// pair maxratio(picture *f);
+void gen251(stack *Stack)
+{
+ picture * f=vm::pop<picture *>(Stack);
+#line 3025 "runtime.in"
+ {Stack->push<pair>(f->bounds(::max,xratio,yratio)); return;}
+}
+
+#line 3029 "runtime.in"
+// real minbound(realarray *a, real b);
+void gen252(stack *Stack)
+{
+ real b=vm::pop<real>(Stack);
+ realarray * a=vm::pop<realarray *>(Stack);
+#line 3030 "runtime.in"
+ real *A=copyArrayC(a,16);
+ b=bound(A,::min,b);
+ delete[] A;
+ {Stack->push<real>(b); return;}
+}
+
+#line 3037 "runtime.in"
+// real maxbound(realarray *a, real b);
+void gen253(stack *Stack)
+{
+ real b=vm::pop<real>(Stack);
+ realarray * a=vm::pop<realarray *>(Stack);
+#line 3038 "runtime.in"
+ real *A=copyArrayC(a,16);
+ b=bound(A,::max,b);
+ delete[] A;
+ {Stack->push<real>(b); return;}
+}
+
+#line 3045 "runtime.in"
+// pair minbound(triplearray *a, realarray2 *t, pair b);
+void gen254(stack *Stack)
+{
+ pair b=vm::pop<pair>(Stack);
+ realarray2 * t=vm::pop<realarray2 *>(Stack);
+ triplearray * a=vm::pop<triplearray *>(Stack);
+#line 3046 "runtime.in"
+ triple *A=copyTripleArrayC(a,16);
+ real *T=copyArray2C(t,4);
+ b=pair(bound(A,::min,xproject,T,b.getx()),
+ bound(A,::min,yproject,T,b.gety()));
+ delete[] T;
+ delete[] A;
+ {Stack->push<pair>(b); return;}
+}
+
+#line 3056 "runtime.in"
+// pair maxbound(triplearray *a, realarray2 *t, pair b);
+void gen255(stack *Stack)
+{
+ pair b=vm::pop<pair>(Stack);
+ realarray2 * t=vm::pop<realarray2 *>(Stack);
+ triplearray * a=vm::pop<triplearray *>(Stack);
+#line 3057 "runtime.in"
+ triple *A=copyTripleArrayC(a,16);
+ real *T=copyArray2C(t,4);
+ b=pair(bound(A,::max,xproject,T,b.getx()),
+ bound(A,::max,yproject,T,b.gety()));
+ delete[] T;
+ delete[] A;
+ {Stack->push<pair>(b); return;}
+}
+
+#line 3067 "runtime.in"
+// pair max(path3 g, realarray2 *t);
+void gen256(stack *Stack)
+{
+ realarray2 * t=vm::pop<realarray2 *>(Stack);
+ path3 g=vm::pop<path3>(Stack);
+#line 3068 "runtime.in"
+ real *T=copyArray2C(t,4);
+ pair b=g.bounds(::max,xproject,yproject,T);
+ delete[] T;
+ {Stack->push<pair>(b); return;}
+}
+
+#line 3075 "runtime.in"
+// pair min(path3 g, realarray2 *t);
+void gen257(stack *Stack)
+{
+ realarray2 * t=vm::pop<realarray2 *>(Stack);
+ path3 g=vm::pop<path3>(Stack);
+#line 3076 "runtime.in"
+ real *T=copyArray2C(t,4);
+ pair b=g.bounds(::min,xproject,yproject,T);
+ delete[] T;
+ {Stack->push<pair>(b); return;}
+}
+
+#line 3083 "runtime.in"
+// real change2(triplearray2 *a);
+void gen258(stack *Stack)
+{
+ triplearray2 * a=vm::pop<triplearray2 *>(Stack);
+#line 3084 "runtime.in"
+ size_t n=checkArray(a);
+ if(n == 0) {Stack->push<real>(0.0); return;}
+
+ vm::array *a0=vm::read<vm::array*>(a,0);
+ size_t m=checkArray(a0);
+ if(m == 0) {Stack->push<real>(0.0); return;}
+ triple a00=vm::read<triple>(a0,0);
+ real M=0.0;
+
+ for(size_t i=0; i < n; ++i) {
+ vm::array *ai=vm::read<vm::array*>(a,i);
+ size_t m=checkArray(ai);
+ for(size_t j=0; j < m; ++j) {
+ real a=(vm::read<triple>(ai,j)-a00).abs2();
+ if(a > M) M=a;
+ }
+ }
+ {Stack->push<real>(M); return;}
+}
+
+#line 3105 "runtime.in"
+// bool is3D(picture *f);
+void gen259(stack *Stack)
+{
+ picture * f=vm::pop<picture *>(Stack);
+#line 3106 "runtime.in"
+ {Stack->push<bool>(f->have3D()); return;}
+}
+
+#line 3110 "runtime.in"
+// pair bezier(pair a, pair b, pair c, pair d, real t);
+void gen260(stack *Stack)
+{
+ real t=vm::pop<real>(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 3111 "runtime.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 3117 "runtime.in"
+// pair bezierP(pair a, pair b, pair c, pair d, real t);
+void gen261(stack *Stack)
+{
+ real t=vm::pop<real>(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 3118 "runtime.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 3122 "runtime.in"
+// pair bezierPP(pair a, pair b, pair c, pair d, real t);
+void gen262(stack *Stack)
+{
+ real t=vm::pop<real>(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 3123 "runtime.in"
+ {Stack->push<pair>(6.0*(t*(d-a+3.0*(b-c))+a+c-2.0*b)); return;}
+}
+
+#line 3127 "runtime.in"
+// pair bezierPPP(pair a, pair b, pair c, pair d);
+void gen263(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 3128 "runtime.in"
+ {Stack->push<pair>(6.0*(d-a+3.0*(b-c))); return;}
+}
+
+#line 3132 "runtime.in"
+// triple bezier(triple a, triple b, triple c, triple d, real t);
+void gen264(stack *Stack)
+{
+ real t=vm::pop<real>(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 3133 "runtime.in"
+ real onemt=1-t;
+ real onemt2=onemt*onemt;
+ {Stack->push<triple>(onemt2*onemt*a+t*(3.0*(onemt2*b+t*onemt*c)+t*t*d)); return;}
+}
+
+#line 3139 "runtime.in"
+// triple bezierP(triple a, triple b, triple c, triple d, real t);
+void gen265(stack *Stack)
+{
+ real t=vm::pop<real>(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 3140 "runtime.in"
+ {Stack->push<triple>(3.0*(t*t*(d-a+3.0*(b-c))+t*(2.0*(a+c)-4.0*b)+b-a)); return;}
+}
+
+#line 3144 "runtime.in"
+// triple bezierPP(triple a, triple b, triple c, triple d, real t);
+void gen266(stack *Stack)
+{
+ real t=vm::pop<real>(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 3145 "runtime.in"
+ {Stack->push<triple>(6.0*(t*(d-a+3.0*(b-c))+a+c-2.0*b)); return;}
+}
+
+#line 3149 "runtime.in"
+// triple bezierPPP(triple a, triple b, triple c, triple d);
+void gen267(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 3150 "runtime.in"
+ {Stack->push<triple>(6.0*(d-a+3.0*(b-c))); return;}
+}
+
+
+// String operations
+#line 3156 "runtime.in"
+void emptyString(stack *Stack)
+{
+#line 3157 "runtime.in"
+ {Stack->push<string>(emptystring); return;}
+}
+
+#line 3162 "runtime.in"
+// Int length(string *s);
+void gen269(stack *Stack)
+{
+ string * s=vm::pop<string *>(Stack);
+#line 3163 "runtime.in"
+ {Stack->push<Int>((Int) s->length()); return;}
+}
+
+#line 3167 "runtime.in"
+// Int find(string *s, string t, Int pos=0);
+void gen270(stack *Stack)
+{
+ Int pos=vm::pop<Int>(Stack,0);
+ string t=vm::pop<string>(Stack);
+ string * s=vm::pop<string *>(Stack);
+#line 3168 "runtime.in"
+ size_t n=s->find(t,pos);
+ {Stack->push<Int>(n == string::npos ? (Int) -1 : (Int) n); return;}
+}
+
+#line 3173 "runtime.in"
+// Int rfind(string *s, string t, Int pos=-1);
+void gen271(stack *Stack)
+{
+ Int pos=vm::pop<Int>(Stack,-1);
+ string t=vm::pop<string>(Stack);
+ string * s=vm::pop<string *>(Stack);
+#line 3174 "runtime.in"
+ size_t n=s->rfind(t,pos);
+ {Stack->push<Int>(n == string::npos ? (Int) -1 : (Int) n); return;}
+}
+
+#line 3179 "runtime.in"
+// string reverse(string s);
+void gen272(stack *Stack)
+{
+ string s=vm::pop<string>(Stack);
+#line 3180 "runtime.in"
+ reverse(s.begin(),s.end());
+ {Stack->push<string>(s); return;}
+}
+
+#line 3185 "runtime.in"
+// string insert(string s, Int pos, string t);
+void gen273(stack *Stack)
+{
+ string t=vm::pop<string>(Stack);
+ Int pos=vm::pop<Int>(Stack);
+ string s=vm::pop<string>(Stack);
+#line 3186 "runtime.in"
+ if ((size_t) pos < s.length())
+ {Stack->push<string>(s.insert(pos,t)); return;}
+ {Stack->push<string>(s); return;}
+}
+
+#line 3192 "runtime.in"
+// string substr(string* s, Int pos, Int n=-1);
+void gen274(stack *Stack)
+{
+ Int n=vm::pop<Int>(Stack,-1);
+ Int pos=vm::pop<Int>(Stack);
+ string* s=vm::pop<string*>(Stack);
+#line 3193 "runtime.in"
+ if ((size_t) pos < s->length())
+ {Stack->push<string>(s->substr(pos,n)); return;}
+ {Stack->push<string>(emptystring); return;}
+}
+
+#line 3199 "runtime.in"
+// string erase(string s, Int pos, Int n);
+void gen275(stack *Stack)
+{
+ Int n=vm::pop<Int>(Stack);
+ Int pos=vm::pop<Int>(Stack);
+ string s=vm::pop<string>(Stack);
+#line 3200 "runtime.in"
+ if ((size_t) pos < s.length())
+ {Stack->push<string>(s.erase(pos,n)); return;}
+ {Stack->push<string>(s); return;}
+}
+
+#line 3206 "runtime.in"
+// string downcase(string s);
+void gen276(stack *Stack)
+{
+ string s=vm::pop<string>(Stack);
+#line 3207 "runtime.in"
+ std::transform(s.begin(),s.end(),s.begin(),tolower);
+ {Stack->push<string>(s); return;}
+}
+
+#line 3212 "runtime.in"
+// string upcase(string s);
+void gen277(stack *Stack)
+{
+ string s=vm::pop<string>(Stack);
+#line 3213 "runtime.in"
+ std::transform(s.begin(),s.end(),s.begin(),toupper);
+ {Stack->push<string>(s); return;}
+}
+
+// returns a string constructed by translating all occurrences of the string
+// from in an array of string pairs {from,to} to the string to in string s.
+#line 3220 "runtime.in"
+// string replace(string *S, stringarray2 *translate);
+void gen278(stack *Stack)
+{
+ stringarray2 * translate=vm::pop<stringarray2 *>(Stack);
+ string * S=vm::pop<string *>(Stack);
+#line 3221 "runtime.in"
+ size_t size=checkArray(translate);
+ for(size_t i=0; i < size; i++) {
+ array *a=read<array*>(translate,i);
+ checkArray(a);
+ }
+ const char *p=S->c_str();
+ ostringstream buf;
+ while(*p) {
+ for(size_t i=0; i < size;) {
+ array *a=read<array*>(translate,i);
+ string* from=read<string*>(a,0);
+ size_t len=from->length();
+ if(strncmp(p,from->c_str(),len) != 0) {i++; continue;}
+ buf << read<string>(a,1);
+ p += len;
+ if(*p == 0) {Stack->push<string>(buf.str()); return;}
+ i=0;
+ }
+ buf << *(p++);
+ }
+ {Stack->push<string>(buf.str()); return;}
+}
+
+#line 3245 "runtime.in"
+// string format(string *format, Int x);
+void gen279(stack *Stack)
+{
+ Int x=vm::pop<Int>(Stack);
+ string * format=vm::pop<string *>(Stack);
+#line 3246 "runtime.in"
+ const char *f=format->c_str();
+
+ checkformat(f,true);
+
+ Int size=snprintf(NULL,0,f,x)+1;
+ if(size < 1) size=255; // Workaround for non-C99 compliant systems.
+ char *buf=new char[size];
+ snprintf(buf,size,f,x);
+ string s=string(buf);
+ delete[] buf;
+ {Stack->push<string>(s); return;}
+}
+
+#line 3260 "runtime.in"
+// string format(string *format, real x, string locale=emptystring);
+void gen280(stack *Stack)
+{
+ string locale=vm::pop<string>(Stack,emptystring);
+ real x=vm::pop<real>(Stack);
+ string * format=vm::pop<string *>(Stack);
+#line 3261 "runtime.in"
+ ostringstream out;
+
+ checkformat(format->c_str(),false);
+
+ const char *phantom="\\phantom{+}";
+ const char *p0=format->c_str();
+
+ const char *p=p0;
+ const char *start=NULL;
+ while (*p != 0) {
+ if(*p == '%') {
+ p++;
+ if(*p != '%') {start=p-1; break;}
+ }
+ out << *(p++);
+ }
+
+ if(!start) {Stack->push<string>(out.str()); return;}
+
+ // Allow at most 1 argument
+ while (*p != 0) {
+ if(*p == '*' || *p == '$') {Stack->push<string>(out.str()); return;}
+ if(isupper(*p) || islower(*p)) {p++; break;}
+ p++;
+ }
+
+ const char *tail=p;
+ string f=format->substr(start-p0,tail-start);
+
+ const char *oldlocale=NULL;
+ if(!locale.empty()) {
+ oldlocale=setlocale(LC_ALL,NULL);
+ if(oldlocale) oldlocale=StrdupNoGC(oldlocale);
+ setlocale(LC_ALL,locale.c_str());
+ }
+
+ Int size=snprintf(NULL,0,f.c_str(),x)+1;
+ if(size < 1) size=255; // Workaround for non-C99 compliant systems.
+ char *buf=new char[size];
+ snprintf(buf,size,f.c_str(),x);
+
+ if(oldlocale) {
+ setlocale(LC_ALL,oldlocale);
+ delete[] oldlocale;
+ }
+
+ bool trailingzero=f.find("#") < string::npos;
+ bool plus=f.find("+") < string::npos;
+ bool space=f.find(" ") < string::npos;
+
+ char *q=buf; // beginning of formatted number
+
+ if(*q == ' ') {
+ out << phantom;
+ q++;
+ }
+
+ const char decimal=*(localeconv()->decimal_point);
+
+ // Remove any spurious sign
+ if(*q == '-' || *q == '+') {
+ p=q+1;
+ bool zero=true;
+ while(*p != 0) {
+ if(!isdigit(*p) && *p != decimal) break;
+ if(isdigit(*p) && *p != '0') {zero=false; break;}
+ p++;
+ }
+ if(zero) {
+ q++;
+ if(plus || space) out << phantom;
+ }
+ }
+
+ const char *r=p=q;
+ bool dp=false;
+ while(*r != 0 && (isdigit(*r) || *r == decimal || *r == '+' || *r == '-')) {
+ if(*r == decimal) dp=true;
+ r++;
+ }
+ if(dp) { // Remove trailing zeros and/or decimal point
+ r--;
+ unsigned n=0;
+ while(r > q && *r == '0') {r--; n++;}
+ if(*r == decimal) {r--; n++;}
+ while(q <= r) out << *(q++);
+ if(!trailingzero) q += n;
+ }
+
+ bool zero=(r == p && *r == '0') && !trailingzero;
+
+ // Translate "E+/E-/e+/e-" exponential notation to TeX
+ while(*q != 0) {
+ if((*q == 'E' || *q == 'e') && (*(q+1) == '+' || *(q+1) == '-')) {
+ if(!zero) out << "\\!\\times\\!10^{";
+ bool plus=(*(q+1) == '+');
+ q++;
+ if(plus) q++;
+ if(*q == '-') out << *(q++);
+ while(*q == '0' && (zero || isdigit(*(q+1)))) q++;
+ while(isdigit(*q)) out << *(q++);
+ if(!zero)
+ out << "}";
+ break;
+ }
+ out << *(q++);
+ }
+
+ while(*tail != 0)
+ out << *(tail++);
+
+ delete[] buf;
+
+ {Stack->push<string>(out.str()); return;}
+}
+
+#line 3378 "runtime.in"
+// Int hex(string s);
+void gen281(stack *Stack)
+{
+ string s=vm::pop<string>(Stack);
+#line 3379 "runtime.in"
+ istringstream is(s);
+ is.setf(std::ios::hex,std::ios::basefield);
+ Int value;
+ if(is && is >> value && ((is >> std::ws).eof())) {Stack->push<Int>(value); return;}
+ ostringstream buf;
+ buf << "invalid hexidecimal cast from string \"" << s << "\"";
+ error(buf);
+}
+
+#line 3389 "runtime.in"
+// string string(Int x);
+void gen282(stack *Stack)
+{
+ Int x=vm::pop<Int>(Stack);
+#line 3390 "runtime.in"
+ ostringstream buf;
+ buf << x;
+ {Stack->push<string>(buf.str()); return;}
+}
+
+#line 3396 "runtime.in"
+// string string(real x, Int digits=DBL_DIG);
+void gen283(stack *Stack)
+{
+ Int digits=vm::pop<Int>(Stack,DBL_DIG);
+ real x=vm::pop<real>(Stack);
+#line 3397 "runtime.in"
+ ostringstream buf;
+ buf.precision(digits);
+ buf << x;
+ {Stack->push<string>(buf.str()); return;}
+}
+
+#line 3404 "runtime.in"
+// string time(string format=defaulttimeformat);
+void gen284(stack *Stack)
+{
+ string format=vm::pop<string>(Stack,defaulttimeformat);
+#line 3405 "runtime.in"
+#ifdef HAVE_STRFTIME
+ const time_t bintime=time(NULL);
+ if(!strftime(Time,nTime,format.c_str(),localtime(&bintime))) {Stack->push<string>(""); return;}
+ {Stack->push<string>(Time); return;}
+#else
+ {Stack->push<string>(format); return;}
+#endif
+}
+
+#line 3415 "runtime.in"
+// string time(Int seconds, string format=defaulttimeformat);
+void gen285(stack *Stack)
+{
+ string format=vm::pop<string>(Stack,defaulttimeformat);
+ Int seconds=vm::pop<Int>(Stack);
+#line 3416 "runtime.in"
+#ifdef HAVE_STRFTIME
+ const time_t bintime=seconds;
+ if(!strftime(Time,nTime,format.c_str(),localtime(&bintime))) {Stack->push<string>(""); return;}
+ {Stack->push<string>(Time); return;}
+#else
+// Avoid unused variable warning messages
+ unused(&seconds);
+ {Stack->push<string>(format); return;}
+#endif
+}
+
+#line 3428 "runtime.in"
+// Int seconds(string t=emptystring, string format=emptystring);
+void gen286(stack *Stack)
+{
+ string format=vm::pop<string>(Stack,emptystring);
+ string t=vm::pop<string>(Stack,emptystring);
+#line 3429 "runtime.in"
+#if defined(HAVE_STRPTIME)
+ const time_t bintime=time(NULL);
+ tm tm=*localtime(&bintime);
+ if(t != "" && !strptime(t.c_str(),format.c_str(),&tm)) {Stack->push<Int>(-1); return;}
+ {Stack->push<Int>((Int) mktime(&tm)); return;}
+#else
+ {Stack->push<Int>(-1); return;}
+#endif
+}
+
+#line 3440 "runtime.in"
+// realarray* _cputime();
+void gen287(stack *Stack)
+{
+#line 3441 "runtime.in"
+ static const real ticktime=1.0/sysconf(_SC_CLK_TCK);
+ struct tms buf;
+
+ ::times(&buf);
+ array *t=new array(4);
+ (*t)[0] = ((real) buf.tms_utime)*ticktime;
+ (*t)[1] = ((real) buf.tms_stime)*ticktime;
+ (*t)[2] = ((real) buf.tms_cutime)*ticktime;
+ (*t)[3] = ((real) buf.tms_cstime)*ticktime;
+ {Stack->push<realarray*>(t); return;}
+}
+
+
+// Math
+#line 3456 "runtime.in"
+// real ^(real x, Int y);
+void gen288(stack *Stack)
+{
+ Int y=vm::pop<Int>(Stack);
+ real x=vm::pop<real>(Stack);
+#line 3457 "runtime.in"
+ {Stack->push<real>(pow(x,y)); return;}
+}
+
+#line 3462 "runtime.in"
+// pair ^(pair z, Int y);
+void gen289(stack *Stack)
+{
+ Int y=vm::pop<Int>(Stack);
+ pair z=vm::pop<pair>(Stack);
+#line 3463 "runtime.in"
+ {Stack->push<pair>(pow(z,y)); return;}
+}
+
+#line 3467 "runtime.in"
+// Int quotient(Int x, Int y);
+void gen290(stack *Stack)
+{
+ Int y=vm::pop<Int>(Stack);
+ Int x=vm::pop<Int>(Stack);
+#line 3468 "runtime.in"
+ if(y == 0) dividebyzero();
+ if(y == -1) {Stack->push<Int>(Negate(x)); return;}
+// Implementation-independent definition of integer division: round down
+ {Stack->push<Int>((x-portableMod(x,y))/y); return;}
+}
+
+#line 3475 "runtime.in"
+// Int abs(Int x);
+void gen291(stack *Stack)
+{
+ Int x=vm::pop<Int>(Stack);
+#line 3476 "runtime.in"
+ {Stack->push<Int>(Abs(x)); return;}
+}
+
+#line 3480 "runtime.in"
+// Int sgn(real x);
+void gen292(stack *Stack)
+{
+ real x=vm::pop<real>(Stack);
+#line 3481 "runtime.in"
+ {Stack->push<Int>(sgn(x)); return;}
+}
+
+#line 3485 "runtime.in"
+// Int rand();
+void gen293(stack *Stack)
+{
+#line 3486 "runtime.in"
+ {Stack->push<Int>(rand()); return;}
+}
+
+#line 3490 "runtime.in"
+// void srand(Int seed);
+void gen294(stack *Stack)
+{
+ Int seed=vm::pop<Int>(Stack);
+#line 3491 "runtime.in"
+ srand(intcast(seed));
+}
+
+// a random number uniformly distributed in the interval [0,1]
+#line 3496 "runtime.in"
+// real unitrand();
+void gen295(stack *Stack)
+{
+#line 3497 "runtime.in"
+ {Stack->push<real>(((real) rand())/RAND_MAX); return;}
+}
+
+#line 3501 "runtime.in"
+// Int ceil(real x);
+void gen296(stack *Stack)
+{
+ real x=vm::pop<real>(Stack);
+#line 3502 "runtime.in"
+ {Stack->push<Int>(Intcast(ceil(x))); return;}
+}
+
+#line 3506 "runtime.in"
+// Int floor(real x);
+void gen297(stack *Stack)
+{
+ real x=vm::pop<real>(Stack);
+#line 3507 "runtime.in"
+ {Stack->push<Int>(Intcast(floor(x))); return;}
+}
+
+#line 3511 "runtime.in"
+// Int round(real x);
+void gen298(stack *Stack)
+{
+ real x=vm::pop<real>(Stack);
+#line 3512 "runtime.in"
+ if(validInt(x)) {Stack->push<Int>(Round(x)); return;}
+ integeroverflow(0);
+}
+
+#line 3517 "runtime.in"
+// Int Ceil(real x);
+void gen299(stack *Stack)
+{
+ real x=vm::pop<real>(Stack);
+#line 3518 "runtime.in"
+ {Stack->push<Int>(Ceil(x)); return;}
+}
+
+#line 3522 "runtime.in"
+// Int Floor(real x);
+void gen300(stack *Stack)
+{
+ real x=vm::pop<real>(Stack);
+#line 3523 "runtime.in"
+ {Stack->push<Int>(Floor(x)); return;}
+}
+
+#line 3527 "runtime.in"
+// Int Round(real x);
+void gen301(stack *Stack)
+{
+ real x=vm::pop<real>(Stack);
+#line 3528 "runtime.in"
+ {Stack->push<Int>(Round(Intcap(x))); return;}
+}
+
+#line 3532 "runtime.in"
+// real fmod(real x, real y);
+void gen302(stack *Stack)
+{
+ real y=vm::pop<real>(Stack);
+ real x=vm::pop<real>(Stack);
+#line 3533 "runtime.in"
+ if (y == 0.0) dividebyzero();
+ {Stack->push<real>(fmod(x,y)); return;}
+}
+
+#line 3538 "runtime.in"
+// real atan2(real y, real x);
+void gen303(stack *Stack)
+{
+ real x=vm::pop<real>(Stack);
+ real y=vm::pop<real>(Stack);
+#line 3539 "runtime.in"
+ {Stack->push<real>(atan2(y,x)); return;}
+}
+
+#line 3543 "runtime.in"
+// real hypot(real x, real y);
+void gen304(stack *Stack)
+{
+ real y=vm::pop<real>(Stack);
+ real x=vm::pop<real>(Stack);
+#line 3544 "runtime.in"
+ {Stack->push<real>(hypot(x,y)); return;}
+}
+
+#line 3548 "runtime.in"
+// real remainder(real x, real y);
+void gen305(stack *Stack)
+{
+ real y=vm::pop<real>(Stack);
+ real x=vm::pop<real>(Stack);
+#line 3549 "runtime.in"
+ {Stack->push<real>(remainder(x,y)); return;}
+}
+
+#line 3553 "runtime.in"
+// real J(Int n, real x);
+void gen306(stack *Stack)
+{
+ real x=vm::pop<real>(Stack);
+ Int n=vm::pop<Int>(Stack);
+#line 3554 "runtime.in"
+ {Stack->push<real>(jn(n,x)); return;}
+}
+
+#line 3558 "runtime.in"
+// real Y(Int n, real x);
+void gen307(stack *Stack)
+{
+ real x=vm::pop<real>(Stack);
+ Int n=vm::pop<Int>(Stack);
+#line 3559 "runtime.in"
+ {Stack->push<real>(yn(n,x)); return;}
+}
+
+#line 3563 "runtime.in"
+// real erf(real x);
+void gen308(stack *Stack)
+{
+ real x=vm::pop<real>(Stack);
+#line 3564 "runtime.in"
+ {Stack->push<real>(erf(x)); return;}
+}
+
+#line 3568 "runtime.in"
+// real erfc(real x);
+void gen309(stack *Stack)
+{
+ real x=vm::pop<real>(Stack);
+#line 3569 "runtime.in"
+ {Stack->push<real>(erfc(x)); return;}
+}
+
+#line 3573 "runtime.in"
+// Int factorial(Int n);
+void gen310(stack *Stack)
+{
+ Int n=vm::pop<Int>(Stack);
+#line 3574 "runtime.in"
+ if(n < 0) error(invalidargument);
+ {Stack->push<Int>(factorial(n)); return;}
+}
+
+#line 3578 "runtime.in"
+// Int choose(Int n, Int k);
+void gen311(stack *Stack)
+{
+ Int k=vm::pop<Int>(Stack);
+ Int n=vm::pop<Int>(Stack);
+#line 3579 "runtime.in"
+ if(n < 0 || k < 0 || k > n) error(invalidargument);
+ Int f=1;
+ Int r=n-k;
+ for(Int i=n; i > r; --i) {
+ if(f > Int_MAX/i) integeroverflow(0);
+ f=(f*i)/(n-i+1);
+ }
+ {Stack->push<Int>(f); return;}
+}
+
+#line 3589 "runtime.in"
+// real gamma(real x);
+void gen312(stack *Stack)
+{
+ real x=vm::pop<real>(Stack);
+#line 3590 "runtime.in"
+#ifdef HAVE_TGAMMA
+ {Stack->push<real>(tgamma(x)); return;}
+#else
+ real lg = lgamma(x);
+ {Stack->push<real>(signgam*exp(lg)); return;}
+#endif
+}
+
+// Complex Gamma function
+#line 3600 "runtime.in"
+// pair gamma(explicit pair z);
+void gen313(stack *Stack)
+{
+ pair z=vm::pop<pair>(Stack);
+#line 3601 "runtime.in"
+ {Stack->push<pair>(gamma(z)); return;}
+}
+
+#line 3605 "runtime.in"
+// realarray* quadraticroots(real a, real b, real c);
+void gen314(stack *Stack)
+{
+ real c=vm::pop<real>(Stack);
+ real b=vm::pop<real>(Stack);
+ real a=vm::pop<real>(Stack);
+#line 3606 "runtime.in"
+ quadraticroots q(a,b,c);
+ array *roots=new array(q.roots);
+ if(q.roots >= 1) (*roots)[0]=q.t1;
+ if(q.roots == 2) (*roots)[1]=q.t2;
+ {Stack->push<realarray*>(roots); return;}
+}
+
+#line 3614 "runtime.in"
+// pairarray* quadraticroots(explicit pair a, explicit pair b, explicit pair c);
+void gen315(stack *Stack)
+{
+ pair c=vm::pop<pair>(Stack);
+ pair b=vm::pop<pair>(Stack);
+ pair a=vm::pop<pair>(Stack);
+#line 3615 "runtime.in"
+ Quadraticroots q(a,b,c);
+ array *roots=new array(q.roots);
+ if(q.roots >= 1) (*roots)[0]=q.z1;
+ if(q.roots == 2) (*roots)[1]=q.z2;
+ {Stack->push<pairarray*>(roots); return;}
+}
+
+#line 3623 "runtime.in"
+// realarray* cubicroots(real a, real b, real c, real d);
+void gen316(stack *Stack)
+{
+ real d=vm::pop<real>(Stack);
+ real c=vm::pop<real>(Stack);
+ real b=vm::pop<real>(Stack);
+ real a=vm::pop<real>(Stack);
+#line 3624 "runtime.in"
+ cubicroots q(a,b,c,d);
+ array *roots=new array(q.roots);
+ if(q.roots >= 1) (*roots)[0]=q.t1;
+ if(q.roots >= 2) (*roots)[1]=q.t2;
+ if(q.roots == 3) (*roots)[2]=q.t3;
+ {Stack->push<realarray*>(roots); return;}
+}
+
+
+// Transforms
+#line 3635 "runtime.in"
+// bool ==(transform a, transform b);
+void gen317(stack *Stack)
+{
+ transform b=vm::pop<transform>(Stack);
+ transform a=vm::pop<transform>(Stack);
+#line 3636 "runtime.in"
+ {Stack->push<bool>(a == b); return;}
+}
+
+#line 3641 "runtime.in"
+// bool !=(transform a, transform b);
+void gen318(stack *Stack)
+{
+ transform b=vm::pop<transform>(Stack);
+ transform a=vm::pop<transform>(Stack);
+#line 3642 "runtime.in"
+ {Stack->push<bool>(a != b); return;}
+}
+
+#line 3646 "runtime.in"
+// transform +(transform a, transform b);
+void gen319(stack *Stack)
+{
+ transform b=vm::pop<transform>(Stack);
+ transform a=vm::pop<transform>(Stack);
+#line 3647 "runtime.in"
+ {Stack->push<transform>(a+b); return;}
+}
+
+#line 3651 "runtime.in"
+// transform *(transform a, transform b);
+void gen320(stack *Stack)
+{
+ transform b=vm::pop<transform>(Stack);
+ transform a=vm::pop<transform>(Stack);
+#line 3652 "runtime.in"
+ {Stack->push<transform>(a*b); return;}
+}
+
+#line 3656 "runtime.in"
+// pair *(transform t, pair z);
+void gen321(stack *Stack)
+{
+ pair z=vm::pop<pair>(Stack);
+ transform t=vm::pop<transform>(Stack);
+#line 3657 "runtime.in"
+ {Stack->push<pair>(t*z); return;}
+}
+
+#line 3661 "runtime.in"
+// path *(transform t, path g);
+void gen322(stack *Stack)
+{
+ path g=vm::pop<path>(Stack);
+ transform t=vm::pop<transform>(Stack);
+#line 3662 "runtime.in"
+ {Stack->push<path>(transformed(t,g)); return;}
+}
+
+#line 3666 "runtime.in"
+// pen *(transform t, pen p);
+void gen323(stack *Stack)
+{
+ pen p=vm::pop<pen>(Stack);
+ transform t=vm::pop<transform>(Stack);
+#line 3667 "runtime.in"
+ {Stack->push<pen>(transformed(t,p)); return;}
+}
+
+#line 3671 "runtime.in"
+// picture* *(transform t, picture *f);
+void gen324(stack *Stack)
+{
+ picture * f=vm::pop<picture *>(Stack);
+ transform t=vm::pop<transform>(Stack);
+#line 3672 "runtime.in"
+ {Stack->push<picture*>(transformed(t,f)); return;}
+}
+
+#line 3676 "runtime.in"
+// picture* *(realarray2 *t, picture *f);
+void gen325(stack *Stack)
+{
+ picture * f=vm::pop<picture *>(Stack);
+ realarray2 * t=vm::pop<realarray2 *>(Stack);
+#line 3677 "runtime.in"
+ {Stack->push<picture*>(transformed(*t,f)); return;}
+}
+
+#line 3681 "runtime.in"
+// transform ^(transform t, Int n);
+void gen326(stack *Stack)
+{
+ Int n=vm::pop<Int>(Stack);
+ transform t=vm::pop<transform>(Stack);
+#line 3682 "runtime.in"
+ transform T;
+ if(n < 0) {
+ n=-n;
+ t=inverse(t);
+ }
+ for(Int i=0; i < n; i++) T=T*t;
+ {Stack->push<transform>(T); return;}
+}
+
+#line 3692 "runtime.in"
+void transformXPart(stack *Stack)
+{
+ transform t=vm::pop<transform>(Stack);
+#line 3693 "runtime.in"
+ {Stack->push<real>(t.getx()); return;}
+}
+
+#line 3697 "runtime.in"
+void transformYPart(stack *Stack)
+{
+ transform t=vm::pop<transform>(Stack);
+#line 3698 "runtime.in"
+ {Stack->push<real>(t.gety()); return;}
+}
+
+#line 3702 "runtime.in"
+void transformXXPart(stack *Stack)
+{
+ transform t=vm::pop<transform>(Stack);
+#line 3703 "runtime.in"
+ {Stack->push<real>(t.getxx()); return;}
+}
+
+#line 3707 "runtime.in"
+void transformXYPart(stack *Stack)
+{
+ transform t=vm::pop<transform>(Stack);
+#line 3708 "runtime.in"
+ {Stack->push<real>(t.getxy()); return;}
+}
+
+#line 3712 "runtime.in"
+void transformYXPart(stack *Stack)
+{
+ transform t=vm::pop<transform>(Stack);
+#line 3713 "runtime.in"
+ {Stack->push<real>(t.getyx()); return;}
+}
+
+#line 3717 "runtime.in"
+void transformYYPart(stack *Stack)
+{
+ transform t=vm::pop<transform>(Stack);
+#line 3718 "runtime.in"
+ {Stack->push<real>(t.getyy()); return;}
+}
+
+#line 3722 "runtime.in"
+void real6ToTransform(stack *Stack)
+{
+ real yy=vm::pop<real>(Stack);
+ real yx=vm::pop<real>(Stack);
+ real xy=vm::pop<real>(Stack);
+ real xx=vm::pop<real>(Stack);
+ real y=vm::pop<real>(Stack);
+ real x=vm::pop<real>(Stack);
+#line 3724 "runtime.in"
+ {Stack->push<transform>(transform(x,y,xx,xy,yx,yy)); return;}
+}
+
+#line 3728 "runtime.in"
+// transform shift(transform t);
+void gen334(stack *Stack)
+{
+ transform t=vm::pop<transform>(Stack);
+#line 3729 "runtime.in"
+ {Stack->push<transform>(transform(t.getx(),t.gety(),0,0,0,0)); return;}
+}
+
+#line 3733 "runtime.in"
+// transform shiftless(transform t);
+void gen335(stack *Stack)
+{
+ transform t=vm::pop<transform>(Stack);
+#line 3734 "runtime.in"
+ {Stack->push<transform>(transform(0,0,t.getxx(),t.getxy(),t.getyx(),t.getyy())); return;}
+}
+
+#line 3738 "runtime.in"
+// transform identity();
+void transformIdentity(stack *Stack)
+{
+#line 3739 "runtime.in"
+ {Stack->push<transform>(identity); return;}
+}
+
+#line 3743 "runtime.in"
+// transform inverse(transform t);
+void gen337(stack *Stack)
+{
+ transform t=vm::pop<transform>(Stack);
+#line 3744 "runtime.in"
+ {Stack->push<transform>(inverse(t)); return;}
+}
+
+#line 3748 "runtime.in"
+// transform shift(pair z);
+void gen338(stack *Stack)
+{
+ pair z=vm::pop<pair>(Stack);
+#line 3749 "runtime.in"
+ {Stack->push<transform>(shift(z)); return;}
+}
+
+#line 3753 "runtime.in"
+// transform shift(real x, real y);
+void gen339(stack *Stack)
+{
+ real y=vm::pop<real>(Stack);
+ real x=vm::pop<real>(Stack);
+#line 3754 "runtime.in"
+ {Stack->push<transform>(shift(pair(x,y))); return;}
+}
+
+#line 3758 "runtime.in"
+// transform xscale(real x);
+void gen340(stack *Stack)
+{
+ real x=vm::pop<real>(Stack);
+#line 3759 "runtime.in"
+ {Stack->push<transform>(xscale(x)); return;}
+}
+
+#line 3763 "runtime.in"
+// transform yscale(real y);
+void gen341(stack *Stack)
+{
+ real y=vm::pop<real>(Stack);
+#line 3764 "runtime.in"
+ {Stack->push<transform>(yscale(y)); return;}
+}
+
+#line 3768 "runtime.in"
+// transform scale(real x);
+void gen342(stack *Stack)
+{
+ real x=vm::pop<real>(Stack);
+#line 3769 "runtime.in"
+ {Stack->push<transform>(scale(x)); return;}
+}
+
+#line 3773 "runtime.in"
+// transform scale(real x, real y);
+void gen343(stack *Stack)
+{
+ real y=vm::pop<real>(Stack);
+ real x=vm::pop<real>(Stack);
+#line 3774 "runtime.in"
+ {Stack->push<transform>(xscale(x)*yscale(y)); return;}
+}
+
+#line 3778 "runtime.in"
+// transform slant(real s);
+void gen344(stack *Stack)
+{
+ real s=vm::pop<real>(Stack);
+#line 3779 "runtime.in"
+ {Stack->push<transform>(slant(s)); return;}
+}
+
+#line 3783 "runtime.in"
+// transform rotate(real angle, pair z=0);
+void gen345(stack *Stack)
+{
+ pair z=vm::pop<pair>(Stack,0);
+ real angle=vm::pop<real>(Stack);
+#line 3784 "runtime.in"
+ {Stack->push<transform>(rotatearound(z,radians(angle))); return;}
+}
+
+#line 3788 "runtime.in"
+// transform reflect(pair a, pair b);
+void gen346(stack *Stack)
+{
+ pair b=vm::pop<pair>(Stack);
+ pair a=vm::pop<pair>(Stack);
+#line 3789 "runtime.in"
+ {Stack->push<transform>(reflectabout(a,b)); return;}
+}
+
+
+// Pair operations
+#line 3795 "runtime.in"
+void pairZero(stack *Stack)
+{
+#line 3796 "runtime.in"
+ {Stack->push<pair>(zero); return;}
+}
+
+#line 3801 "runtime.in"
+void realRealToPair(stack *Stack)
+{
+ real y=vm::pop<real>(Stack);
+ real x=vm::pop<real>(Stack);
+#line 3802 "runtime.in"
+ {Stack->push<pair>(pair(x,y)); return;}
+}
+
+#line 3806 "runtime.in"
+void pairNegate(stack *Stack)
+{
+ pair z=vm::pop<pair>(Stack);
+#line 3807 "runtime.in"
+ {Stack->push<pair>(-z); return;}
+}
+
+#line 3811 "runtime.in"
+// real xpart(pair z);
+void pairXPart(stack *Stack)
+{
+ pair z=vm::pop<pair>(Stack);
+#line 3812 "runtime.in"
+ {Stack->push<real>(z.getx()); return;}
+}
+
+#line 3816 "runtime.in"
+// real ypart(pair z);
+void pairYPart(stack *Stack)
+{
+ pair z=vm::pop<pair>(Stack);
+#line 3817 "runtime.in"
+ {Stack->push<real>(z.gety()); return;}
+}
+
+#line 3821 "runtime.in"
+// real length(pair z);
+void gen352(stack *Stack)
+{
+ pair z=vm::pop<pair>(Stack);
+#line 3822 "runtime.in"
+ {Stack->push<real>(z.length()); return;}
+}
+
+#line 3826 "runtime.in"
+// real abs(pair z);
+void gen353(stack *Stack)
+{
+ pair z=vm::pop<pair>(Stack);
+#line 3827 "runtime.in"
+ {Stack->push<real>(z.length()); return;}
+}
+
+#line 3831 "runtime.in"
+// pair sqrt(explicit pair z);
+void gen354(stack *Stack)
+{
+ pair z=vm::pop<pair>(Stack);
+#line 3832 "runtime.in"
+ {Stack->push<pair>(Sqrt(z)); return;}
+}
+
+// Return the angle of z in radians.
+#line 3837 "runtime.in"
+// real angle(pair z, bool warn=true);
+void gen355(stack *Stack)
+{
+ bool warn=vm::pop<bool>(Stack,true);
+ pair z=vm::pop<pair>(Stack);
+#line 3838 "runtime.in"
+ if(!warn && z.getx() == 0.0 && z.gety() == 0.0) {Stack->push<real>(0.0); return;}
+ {Stack->push<real>(z.angle()); return;}
+}
+
+// Return the angle of z in degrees in the interval [0,360).
+#line 3844 "runtime.in"
+// real degrees(pair z, bool warn=true);
+void gen356(stack *Stack)
+{
+ bool warn=vm::pop<bool>(Stack,true);
+ pair z=vm::pop<pair>(Stack);
+#line 3845 "runtime.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;}
+}
+
+// Convert degrees to radians.
+#line 3851 "runtime.in"
+// real radians(real degrees);
+void gen357(stack *Stack)
+{
+ real degrees=vm::pop<real>(Stack);
+#line 3852 "runtime.in"
+ {Stack->push<real>(radians(degrees)); return;}
+}
+
+// Convert radians to degrees.
+#line 3857 "runtime.in"
+// real degrees(real radians);
+void gen358(stack *Stack)
+{
+ real radians=vm::pop<real>(Stack);
+#line 3858 "runtime.in"
+ {Stack->push<real>(degrees(radians)); return;}
+}
+
+// Convert radians to degrees in [0,360).
+#line 3863 "runtime.in"
+// real Degrees(real radians);
+void gen359(stack *Stack)
+{
+ real radians=vm::pop<real>(Stack);
+#line 3864 "runtime.in"
+ {Stack->push<real>(principalBranch(degrees(radians))); return;}
+}
+
+#line 3868 "runtime.in"
+// real Sin(real deg);
+void gen360(stack *Stack)
+{
+ real deg=vm::pop<real>(Stack);
+#line 3869 "runtime.in"
+ {Stack->push<real>(sin(radians(deg))); return;}
+}
+
+#line 3873 "runtime.in"
+// real Cos(real deg);
+void gen361(stack *Stack)
+{
+ real deg=vm::pop<real>(Stack);
+#line 3874 "runtime.in"
+ {Stack->push<real>(cos(radians(deg))); return;}
+}
+
+#line 3878 "runtime.in"
+// real Tan(real deg);
+void gen362(stack *Stack)
+{
+ real deg=vm::pop<real>(Stack);
+#line 3879 "runtime.in"
+ {Stack->push<real>(tan(radians(deg))); return;}
+}
+
+#line 3883 "runtime.in"
+// real aSin(real x);
+void gen363(stack *Stack)
+{
+ real x=vm::pop<real>(Stack);
+#line 3884 "runtime.in"
+ {Stack->push<real>(degrees(asin(x))); return;}
+}
+
+#line 3888 "runtime.in"
+// real aCos(real x);
+void gen364(stack *Stack)
+{
+ real x=vm::pop<real>(Stack);
+#line 3889 "runtime.in"
+ {Stack->push<real>(degrees(acos(x))); return;}
+}
+
+#line 3893 "runtime.in"
+// real aTan(real x);
+void gen365(stack *Stack)
+{
+ real x=vm::pop<real>(Stack);
+#line 3894 "runtime.in"
+ {Stack->push<real>(degrees(atan(x))); return;}
+}
+
+#line 3898 "runtime.in"
+// pair unit(pair z);
+void gen366(stack *Stack)
+{
+ pair z=vm::pop<pair>(Stack);
+#line 3899 "runtime.in"
+ {Stack->push<pair>(unit(z)); return;}
+}
+
+#line 3903 "runtime.in"
+// pair dir(real degrees);
+void gen367(stack *Stack)
+{
+ real degrees=vm::pop<real>(Stack);
+#line 3904 "runtime.in"
+ {Stack->push<pair>(expi(radians(degrees))); return;}
+}
+
+#line 3908 "runtime.in"
+// pair dir(explicit pair z);
+void gen368(stack *Stack)
+{
+ pair z=vm::pop<pair>(Stack);
+#line 3909 "runtime.in"
+ {Stack->push<pair>(unit(z)); return;}
+}
+
+#line 3913 "runtime.in"
+// pair expi(real angle);
+void gen369(stack *Stack)
+{
+ real angle=vm::pop<real>(Stack);
+#line 3914 "runtime.in"
+ {Stack->push<pair>(expi(angle)); return;}
+}
+
+#line 3918 "runtime.in"
+// pair exp(explicit pair z);
+void gen370(stack *Stack)
+{
+ pair z=vm::pop<pair>(Stack);
+#line 3919 "runtime.in"
+ {Stack->push<pair>(exp(z)); return;}
+}
+
+#line 3923 "runtime.in"
+// pair log(explicit pair z);
+void gen371(stack *Stack)
+{
+ pair z=vm::pop<pair>(Stack);
+#line 3924 "runtime.in"
+ {Stack->push<pair>(pair(log(z.length()),z.angle())); return;}
+}
+
+#line 3928 "runtime.in"
+// pair sin(explicit pair z);
+void gen372(stack *Stack)
+{
+ pair z=vm::pop<pair>(Stack);
+#line 3929 "runtime.in"
+ {Stack->push<pair>(sin(z)); return;}
+}
+
+#line 3933 "runtime.in"
+// pair cos(explicit pair z);
+void gen373(stack *Stack)
+{
+ pair z=vm::pop<pair>(Stack);
+#line 3934 "runtime.in"
+ {Stack->push<pair>(pair(cos(z.getx())*cosh(z.gety()),-sin(z.getx())*sinh(z.gety()))); return;}
+}
+
+#line 3938 "runtime.in"
+// pair conj(pair z);
+void gen374(stack *Stack)
+{
+ pair z=vm::pop<pair>(Stack);
+#line 3939 "runtime.in"
+ {Stack->push<pair>(conj(z)); return;}
+}
+
+#line 3943 "runtime.in"
+// pair realmult(pair z, pair w);
+void gen375(stack *Stack)
+{
+ pair w=vm::pop<pair>(Stack);
+ pair z=vm::pop<pair>(Stack);
+#line 3944 "runtime.in"
+ {Stack->push<pair>(pair (z.getx()*w.getx(),z.gety()*w.gety())); return;}
+}
+
+#line 3948 "runtime.in"
+// triple realmult(triple u, triple v);
+void gen376(stack *Stack)
+{
+ triple v=vm::pop<triple>(Stack);
+ triple u=vm::pop<triple>(Stack);
+#line 3949 "runtime.in"
+ {Stack->push<triple>(triple (u.getx()*v.getx(),u.gety()*v.gety(),u.getz()*v.getz())); return;}
+}
+
+// To avoid confusion, a dot product requires explicit pair arguments.
+#line 3954 "runtime.in"
+// real dot(explicit pair z, explicit pair w);
+void gen377(stack *Stack)
+{
+ pair w=vm::pop<pair>(Stack);
+ pair z=vm::pop<pair>(Stack);
+#line 3955 "runtime.in"
+ {Stack->push<real>(dot(z,w)); return;}
+}
+
+
+// Triple operations
+#line 3961 "runtime.in"
+void tripleZero(stack *Stack)
+{
+#line 3962 "runtime.in"
+ static triple zero;
+ {Stack->push<triple>(zero); return;}
+}
+
+#line 3968 "runtime.in"
+void realRealRealToTriple(stack *Stack)
+{
+ real z=vm::pop<real>(Stack);
+ real y=vm::pop<real>(Stack);
+ real x=vm::pop<real>(Stack);
+#line 3969 "runtime.in"
+ {Stack->push<triple>(triple(x,y,z)); return;}
+}
+
+#line 3973 "runtime.in"
+// real xpart(triple v);
+void tripleXPart(stack *Stack)
+{
+ triple v=vm::pop<triple>(Stack);
+#line 3974 "runtime.in"
+ {Stack->push<real>(v.getx()); return;}
+}
+
+#line 3978 "runtime.in"
+// real ypart(triple v);
+void tripleYPart(stack *Stack)
+{
+ triple v=vm::pop<triple>(Stack);
+#line 3979 "runtime.in"
+ {Stack->push<real>(v.gety()); return;}
+}
+
+#line 3983 "runtime.in"
+// real zpart(triple v);
+void tripleZPart(stack *Stack)
+{
+ triple v=vm::pop<triple>(Stack);
+#line 3984 "runtime.in"
+ {Stack->push<real>(v.getz()); return;}
+}
+
+#line 3988 "runtime.in"
+// triple *(real x, triple v);
+void gen383(stack *Stack)
+{
+ triple v=vm::pop<triple>(Stack);
+ real x=vm::pop<real>(Stack);
+#line 3989 "runtime.in"
+ {Stack->push<triple>(x*v); return;}
+}
+
+#line 3993 "runtime.in"
+// triple *(triple v, real x);
+void gen384(stack *Stack)
+{
+ real x=vm::pop<real>(Stack);
+ triple v=vm::pop<triple>(Stack);
+#line 3994 "runtime.in"
+ {Stack->push<triple>(v*x); return;}
+}
+
+#line 3998 "runtime.in"
+// triple /(triple v, real x);
+void gen385(stack *Stack)
+{
+ real x=vm::pop<real>(Stack);
+ triple v=vm::pop<triple>(Stack);
+#line 3999 "runtime.in"
+ {Stack->push<triple>(v/x); return;}
+}
+
+#line 4003 "runtime.in"
+// real length(triple v);
+void gen386(stack *Stack)
+{
+ triple v=vm::pop<triple>(Stack);
+#line 4004 "runtime.in"
+ {Stack->push<real>(v.length()); return;}
+}
+
+#line 4008 "runtime.in"
+// real abs(triple v);
+void gen387(stack *Stack)
+{
+ triple v=vm::pop<triple>(Stack);
+#line 4009 "runtime.in"
+ {Stack->push<real>(v.length()); return;}
+}
+
+#line 4013 "runtime.in"
+// real polar(triple v);
+void gen388(stack *Stack)
+{
+ triple v=vm::pop<triple>(Stack);
+#line 4014 "runtime.in"
+ {Stack->push<real>(v.polar()); return;}
+}
+
+#line 4018 "runtime.in"
+// real azimuth(triple v);
+void gen389(stack *Stack)
+{
+ triple v=vm::pop<triple>(Stack);
+#line 4019 "runtime.in"
+ {Stack->push<real>(v.azimuth()); return;}
+}
+
+#line 4023 "runtime.in"
+// real colatitude(triple v);
+void gen390(stack *Stack)
+{
+ triple v=vm::pop<triple>(Stack);
+#line 4024 "runtime.in"
+ {Stack->push<real>(degrees(v.polar())); return;}
+}
+
+#line 4028 "runtime.in"
+// real latitude(triple v);
+void gen391(stack *Stack)
+{
+ triple v=vm::pop<triple>(Stack);
+#line 4029 "runtime.in"
+ {Stack->push<real>(90.0-degrees(v.polar())); return;}
+}
+
+// Return the longitude of v in [0,360).
+#line 4034 "runtime.in"
+// real longitude(triple v, bool warn=true);
+void gen392(stack *Stack)
+{
+ bool warn=vm::pop<bool>(Stack,true);
+ triple v=vm::pop<triple>(Stack);
+#line 4035 "runtime.in"
+ if(!warn && v.getx() == 0.0 && v.gety() == 0.0) {Stack->push<real>(0.0); return;}
+ {Stack->push<real>(principalBranch(degrees(v.azimuth()))); return;}
+}
+
+#line 4040 "runtime.in"
+// triple unit(triple v);
+void gen393(stack *Stack)
+{
+ triple v=vm::pop<triple>(Stack);
+#line 4041 "runtime.in"
+ {Stack->push<triple>(unit(v)); return;}
+}
+
+#line 4045 "runtime.in"
+// real dot(triple u, triple v);
+void gen394(stack *Stack)
+{
+ triple v=vm::pop<triple>(Stack);
+ triple u=vm::pop<triple>(Stack);
+#line 4046 "runtime.in"
+ {Stack->push<real>(dot(u,v)); return;}
+}
+
+#line 4050 "runtime.in"
+// triple cross(triple u, triple v);
+void gen395(stack *Stack)
+{
+ triple v=vm::pop<triple>(Stack);
+ triple u=vm::pop<triple>(Stack);
+#line 4051 "runtime.in"
+ {Stack->push<triple>(cross(u,v)); return;}
+}
+
+#line 4055 "runtime.in"
+// triple expi(real polar, real azimuth);
+void gen396(stack *Stack)
+{
+ real azimuth=vm::pop<real>(Stack);
+ real polar=vm::pop<real>(Stack);
+#line 4056 "runtime.in"
+ {Stack->push<triple>(expi(polar,azimuth)); return;}
+}
+
+#line 4060 "runtime.in"
+// triple dir(real colatitude, real longitude);
+void gen397(stack *Stack)
+{
+ real longitude=vm::pop<real>(Stack);
+ real colatitude=vm::pop<real>(Stack);
+#line 4061 "runtime.in"
+ {Stack->push<triple>(expi(radians(colatitude),radians(longitude))); return;}
+}
+
+
+// System routines
+#line 4067 "runtime.in"
+// void atupdate(callable *f);
+void gen398(stack *Stack)
+{
+ callable * f=vm::pop<callable *>(Stack);
+#line 4068 "runtime.in"
+ processData().atUpdateFunction=f;
+}
+
+#line 4073 "runtime.in"
+// callable* atupdate();
+void gen399(stack *Stack)
+{
+#line 4074 "runtime.in"
+ {Stack->push<callable*>(processData().atUpdateFunction); return;}
+}
+
+#line 4078 "runtime.in"
+// void atexit(callable *f);
+void gen400(stack *Stack)
+{
+ callable * f=vm::pop<callable *>(Stack);
+#line 4079 "runtime.in"
+ processData().atExitFunction=f;
+}
+
+#line 4083 "runtime.in"
+// callable* atexit();
+void gen401(stack *Stack)
+{
+#line 4084 "runtime.in"
+ {Stack->push<callable*>(processData().atExitFunction); return;}
+}
+
+#line 4088 "runtime.in"
+// void atbreakpoint(callableBp *f);
+void gen402(stack *Stack)
+{
+ callableBp * f=vm::pop<callableBp *>(Stack);
+#line 4089 "runtime.in"
+ processData().atBreakpointFunction=f;
+}
+
+#line 4093 "runtime.in"
+// void breakpoint(runnable *s=NULL);
+void gen403(stack *Stack)
+{
+ runnable * s=vm::pop<runnable *>(Stack,NULL);
+#line 4094 "runtime.in"
+ breakpoint(Stack,s);
+}
+
+#line 4098 "runtime.in"
+// string locatefile(string file);
+void gen404(stack *Stack)
+{
+ string file=vm::pop<string>(Stack);
+#line 4099 "runtime.in"
+ {Stack->push<string>(locateFile(file)); return;}
+}
+
+#line 4103 "runtime.in"
+// void stop(string file, Int line, runnable *s=NULL);
+void gen405(stack *Stack)
+{
+ runnable * s=vm::pop<runnable *>(Stack,NULL);
+ Int line=vm::pop<Int>(Stack);
+ string file=vm::pop<string>(Stack);
+#line 4104 "runtime.in"
+ file=locateFile(file);
+ clear(file,line);
+ cout << "setting breakpoint at " << file << ": " << line << endl;
+ bplist.push_back(bpinfo(file,line,s));
+}
+
+#line 4111 "runtime.in"
+// void breakpoints();
+void gen406(stack *)
+{
+#line 4112 "runtime.in"
+ for(mem::list<bpinfo>::iterator p=bplist.begin(); p != bplist.end(); ++p)
+ cout << p->f.name() << ": " << p->f.line() << endl;
+}
+
+#line 4117 "runtime.in"
+// void clear(string file, Int line);
+void gen407(stack *Stack)
+{
+ Int line=vm::pop<Int>(Stack);
+ string file=vm::pop<string>(Stack);
+#line 4118 "runtime.in"
+ file=locateFile(file);
+ clear(file,line,true);
+}
+
+#line 4123 "runtime.in"
+// void clear();
+void gen408(stack *)
+{
+#line 4124 "runtime.in"
+ bplist.clear();
+}
+
+// Strip directory from string
+#line 4129 "runtime.in"
+// string stripdirectory(string *s);
+void gen409(stack *Stack)
+{
+ string * s=vm::pop<string *>(Stack);
+#line 4130 "runtime.in"
+ {Stack->push<string>(stripDir(*s)); return;}
+}
+
+// Strip directory from string
+#line 4135 "runtime.in"
+// string stripfile(string *s);
+void gen410(stack *Stack)
+{
+ string * s=vm::pop<string *>(Stack);
+#line 4136 "runtime.in"
+ {Stack->push<string>(stripFile(*s)); return;}
+}
+
+// Strip file extension from string
+#line 4141 "runtime.in"
+// string stripextension(string *s);
+void gen411(stack *Stack)
+{
+ string * s=vm::pop<string *>(Stack);
+#line 4142 "runtime.in"
+ {Stack->push<string>(stripExt(*s)); return;}
+}
+
+// Call ImageMagick convert.
+#line 4147 "runtime.in"
+// Int convert(string args=emptystring, string file=emptystring, string format=emptystring);
+void gen412(stack *Stack)
+{
+ string format=vm::pop<string>(Stack,emptystring);
+ string file=vm::pop<string>(Stack,emptystring);
+ string args=vm::pop<string>(Stack,emptystring);
+#line 4149 "runtime.in"
+ ostringstream cmd;
+
+ string name=convertname(file,format);
+ cmd << "'" << getSetting<string>("convert") << "' " << args
+ << " '" << name << "'";
+ bool quiet=verbose <= 1;
+ Int ret=System(cmd,quiet ? 1 : 0,true,"convert","your ImageMagick convert utility");
+
+ if(ret == 0 && verbose > 0)
+ cout << "Wrote " << ((file.empty()) ? name : file) << endl;
+
+ {Stack->push<Int>(ret); return;}
+}
+
+// Call ImageMagick animate.
+#line 4165 "runtime.in"
+// Int animate(string args=emptystring, string file=emptystring, string format=emptystring);
+void gen413(stack *Stack)
+{
+ string format=vm::pop<string>(Stack,emptystring);
+ string file=vm::pop<string>(Stack,emptystring);
+ string args=vm::pop<string>(Stack,emptystring);
+#line 4167 "runtime.in"
+#ifndef __CYGWIN__
+ string name=convertname(file,format,false);
+ if(view()) {
+ ostringstream cmd;
+ cmd << "'" << getSetting<string>("animate") << "' " << args
+ << " '" << name << "'";
+ {Stack->push<Int>(System(cmd,0,false,"animate","your animated GIF viewer")); return;}
+ }
+#endif
+ {Stack->push<Int>(0); return;}
+}
+
+// Delete file named s.
+#line 4181 "runtime.in"
+// Int delete(string *s);
+void gen414(stack *Stack)
+{
+ string * s=vm::pop<string *>(Stack);
+#line 4182 "runtime.in"
+ checkLocal(*s);
+ Int rc=unlink(s->c_str());
+ if(rc == 0 && verbose > 0)
+ cout << "Deleted " << *s << endl;
+ {Stack->push<Int>(rc); return;}
+}
+
+// Rename file "from" to file "to".
+#line 4191 "runtime.in"
+// Int rename(string *from, string *to);
+void gen415(stack *Stack)
+{
+ string * to=vm::pop<string *>(Stack);
+ string * from=vm::pop<string *>(Stack);
+#line 4192 "runtime.in"
+ checkLocal(*from);
+ checkLocal(*to);
+ Int rc=rename(from->c_str(),to->c_str());
+ if(rc == 0 && verbose > 0)
+ cout << "Renamed " << *from << " to " << *to << endl;
+ {Stack->push<Int>(rc); return;}
+}
+
+
+// Array operations
+
+// Create an empty array.
+#line 4205 "runtime.in"
+void emptyArray(stack *Stack)
+{
+#line 4206 "runtime.in"
+ {Stack->push<array*>(new array(0)); return;}
+}
+
+// Create a new array (technically a vector).
+// This array will be multidimensional. First the number of dimensions
+// 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 4215 "runtime.in"
+void newDeepArray(stack *Stack)
+{
+ Int depth=vm::pop<Int>(Stack);
+#line 4216 "runtime.in"
+ assert(depth > 0);
+
+ Int *dims = new Int[depth];
+
+ for (Int index = depth-1; index >= 0; index--) {
+ Int i=pop<Int>(Stack);
+ if(i < 0) error("cannot create a negative length array");
+ dims[index]=i;
+ }
+
+ array *a=deepArray(depth, dims);
+ delete[] dims;
+ {Stack->push<array*>(a); return;}
+}
+
+// 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 4235 "runtime.in"
+void newInitializedArray(stack *Stack)
+{
+ Int n=vm::pop<Int>(Stack);
+#line 4236 "runtime.in"
+ assert(n >= 0);
+
+ array *a = new array(n);
+
+ for (Int index = n-1; index >= 0; index--)
+ (*a)[index] = pop(Stack);
+
+ {Stack->push<array*>(a); return;}
+}
+
+// Similar to newInitializedArray, but after the n elements, append another
+// array to it.
+#line 4249 "runtime.in"
+void newAppendedArray(stack *Stack)
+{
+ Int n=vm::pop<Int>(Stack);
+ array* tail=vm::pop<array*>(Stack);
+#line 4250 "runtime.in"
+ assert(n >= 0);
+
+ array *a = new array(n);
+
+ for (Int index = n-1; index >= 0; index--)
+ (*a)[index] = pop(Stack);
+
+ copy(tail->begin(), tail->end(), back_inserter(*a));
+
+ {Stack->push<array*>(a); return;}
+}
+
+// The function T[] array(int n, T value, int depth=0) produces a array of n
+// copies of x, where each copy is copied up to depth.
+#line 4265 "runtime.in"
+void newDuplicateArray(stack *Stack)
+{
+ Int depth=vm::pop<Int>(Stack,Int_MAX);
+ item value=vm::pop(Stack);
+ Int n=vm::pop<Int>(Stack);
+#line 4266 "runtime.in"
+ if(n < 0) error("cannot create a negative length array");
+ if(depth < 0) error("cannot copy to a negative depth");
+
+ {Stack->push<array*>(new array(n, value, depth)); return;}
+}
+
+// Read an element from an array. Checks for initialization & bounds.
+#line 4274 "runtime.in"
+void arrayRead(stack *Stack)
+{
+ Int n=vm::pop<Int>(Stack);
+ array * a=vm::pop<array *>(Stack);
+#line 4275 "runtime.in"
+ item& i=arrayRead(a,n);
+ if (i.empty()) {
+ ostringstream buf;
+ buf << "read uninitialized value from array at index " << n;
+ error(buf);
+ }
+ {Stack->push(i); return;}
+}
+
+// Slice a substring from an array.
+#line 4286 "runtime.in"
+void arraySliceRead(stack *Stack)
+{
+ Int right=vm::pop<Int>(Stack);
+ Int left=vm::pop<Int>(Stack);
+ array * a=vm::pop<array *>(Stack);
+#line 4287 "runtime.in"
+ checkArray(a);
+ {Stack->push(a->slice(left, right)); return;}
+}
+
+// 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 4294 "runtime.in"
+void arraySliceReadToEnd(stack *Stack)
+{
+ Int left=vm::pop<Int>(Stack);
+ array * a=vm::pop<array *>(Stack);
+#line 4295 "runtime.in"
+ size_t len=checkArray(a);
+ {Stack->push(a->slice(left, (Int)len)); return;}
+}
+
+// Read an element from an array of arrays. Check bounds and initialize
+// as necessary.
+#line 4302 "runtime.in"
+void arrayArrayRead(stack *Stack)
+{
+ Int n=vm::pop<Int>(Stack);
+ array * a=vm::pop<array *>(Stack);
+#line 4303 "runtime.in"
+ item& i=arrayRead(a,n);
+ if (i.empty()) i=new array(0);
+ {Stack->push(i); return;}
+}
+
+// Write an element to an array. Increase size if necessary.
+#line 4310 "runtime.in"
+void arrayWrite(stack *Stack)
+{
+ Int n=vm::pop<Int>(Stack);
+ array * a=vm::pop<array *>(Stack);
+ item value=vm::pop(Stack);
+#line 4311 "runtime.in"
+ size_t len=checkArray(a);
+ bool cyclic=a->cyclic();
+ if(cyclic && len > 0) n=imod(n,len);
+ else {
+ if(cyclic) outOfBounds("writing cyclic",len,n);
+ if(n < 0) outOfBounds("writing",len,n);
+ if(len <= (size_t) n)
+ a->resize(n+1);
+ }
+ (*a)[n] = value;
+ {Stack->push(value); return;}
+}
+
+#line 4325 "runtime.in"
+void arraySliceWrite(stack *Stack)
+{
+ Int right=vm::pop<Int>(Stack);
+ Int left=vm::pop<Int>(Stack);
+ array * dest=vm::pop<array *>(Stack);
+ array * src=vm::pop<array *>(Stack);
+#line 4326 "runtime.in"
+ checkArray(src);
+ checkArray(dest);
+ dest->setSlice(left, right, src);
+ {Stack->push<array*>(src); return;}
+}
+
+#line 4333 "runtime.in"
+void arraySliceWriteToEnd(stack *Stack)
+{
+ Int left=vm::pop<Int>(Stack);
+ array * dest=vm::pop<array *>(Stack);
+ array * src=vm::pop<array *>(Stack);
+#line 4334 "runtime.in"
+ checkArray(src);
+ size_t len=checkArray(dest);
+ dest->setSlice(left, (Int) len, src);
+ {Stack->push<array*>(src); return;}
+}
+
+// Returns the length of an array.
+#line 4342 "runtime.in"
+void arrayLength(stack *Stack)
+{
+ array * a=vm::pop<array *>(Stack);
+#line 4343 "runtime.in"
+ {Stack->push<Int>((Int) checkArray(a)); return;}
+}
+
+// Returns an array of integers representing the keys of the array.
+#line 4348 "runtime.in"
+void arrayKeys(stack *Stack)
+{
+ array * a=vm::pop<array *>(Stack);
+#line 4349 "runtime.in"
+ size_t size=checkArray(a);
+
+ array *keys=new array();
+ for (size_t i=0; i<size; ++i) {
+ item& cell = (*a)[i];
+ if (!cell.empty())
+ keys->push((Int)i);
+ }
+
+ {Stack->push<array*>(keys); return;}
+}
+
+// Return the cyclic flag for an array.
+#line 4363 "runtime.in"
+void arrayCyclicFlag(stack *Stack)
+{
+ array * a=vm::pop<array *>(Stack);
+#line 4364 "runtime.in"
+ checkArray(a);
+ {Stack->push<bool>(a->cyclic()); return;}
+}
+
+// Check to see if an array element is initialized.
+#line 4370 "runtime.in"
+void arrayInitializedHelper(stack *Stack)
+{
+ array * a=vm::pop<array *>(Stack);
+ Int n=vm::pop<Int>(Stack);
+#line 4371 "runtime.in"
+ size_t len=checkArray(a);
+ bool cyclic=a->cyclic();
+ if(cyclic && len > 0) n=imod(n,len);
+ else if(n < 0 || n >= (Int) len) {Stack->push<bool>(false); return;}
+ item&i=(*a)[(unsigned) n];
+ {Stack->push<bool>(!i.empty()); return;}
+}
+
+// Returns the initialize method for an array.
+#line 4381 "runtime.in"
+void arrayInitialized(stack *Stack)
+{
+ array * a=vm::pop<array *>(Stack);
+#line 4382 "runtime.in"
+ {Stack->push<callable*>(new thunk(new bfunc(arrayInitializedHelper),a)); return;}
+}
+
+// The helper function for the cyclic method that sets the cyclic flag.
+#line 4387 "runtime.in"
+void arrayCyclicHelper(stack *Stack)
+{
+ array * a=vm::pop<array *>(Stack);
+ bool b=vm::pop<bool>(Stack);
+#line 4388 "runtime.in"
+ checkArray(a);
+ a->cyclic(b);
+}
+
+// Set the cyclic flag for an array.
+#line 4394 "runtime.in"
+void arrayCyclic(stack *Stack)
+{
+ array * a=vm::pop<array *>(Stack);
+#line 4395 "runtime.in"
+ {Stack->push<callable*>(new thunk(new bfunc(arrayCyclicHelper),a)); return;}
+}
+
+// The helper function for the push method that does the actual operation.
+#line 4400 "runtime.in"
+void arrayPushHelper(stack *Stack)
+{
+ array * a=vm::pop<array *>(Stack);
+ item x=vm::pop(Stack);
+#line 4401 "runtime.in"
+ checkArray(a);
+ a->push(x);
+ {Stack->push(x); return;}
+}
+
+// Returns the push method for an array.
+#line 4408 "runtime.in"
+void arrayPush(stack *Stack)
+{
+ array * a=vm::pop<array *>(Stack);
+#line 4409 "runtime.in"
+ {Stack->push<callable*>(new thunk(new bfunc(arrayPushHelper),a)); return;}
+}
+
+// The helper function for the append method that appends b to a.
+#line 4414 "runtime.in"
+void arrayAppendHelper(stack *Stack)
+{
+ array * a=vm::pop<array *>(Stack);
+ array * b=vm::pop<array *>(Stack);
+#line 4415 "runtime.in"
+ checkArray(a);
+ size_t size=checkArray(b);
+ for(size_t i=0; i < size; i++)
+ a->push((*b)[i]);
+}
+
+// Returns the append method for an array.
+#line 4423 "runtime.in"
+void arrayAppend(stack *Stack)
+{
+ array * a=vm::pop<array *>(Stack);
+#line 4424 "runtime.in"
+ {Stack->push<callable*>(new thunk(new bfunc(arrayAppendHelper),a)); return;}
+}
+
+// The helper function for the pop method.
+#line 4429 "runtime.in"
+void arrayPopHelper(stack *Stack)
+{
+ array * a=vm::pop<array *>(Stack);
+#line 4430 "runtime.in"
+ size_t asize=checkArray(a);
+ if(asize == 0)
+ error("cannot pop element from empty array");
+ {Stack->push(a->pop()); return;}
+}
+
+// Returns the pop method for an array.
+#line 4438 "runtime.in"
+void arrayPop(stack *Stack)
+{
+ array * a=vm::pop<array *>(Stack);
+#line 4439 "runtime.in"
+ {Stack->push<callable*>(new thunk(new bfunc(arrayPopHelper),a)); return;}
+}
+
+// The helper function for the insert method.
+#line 4444 "runtime.in"
+void arrayInsertHelper(stack *Stack)
+{
+ array * a=vm::pop<array *>(Stack);
+ array * x=vm::pop<array *>(Stack);
+ Int i=vm::pop<Int>(Stack);
+#line 4445 "runtime.in"
+ size_t asize=checkArray(a);
+ checkArray(x);
+ if(a->cyclic() && asize > 0) i=imod(i,asize);
+ if(i < 0 || i > (Int) asize)
+ outOfBounds("inserting",asize,i);
+ (*a).insert((*a).begin()+i,(*x).begin(),(*x).end());
+}
+
+// Returns the insert method for an array.
+#line 4455 "runtime.in"
+void arrayInsert(stack *Stack)
+{
+ array * a=vm::pop<array *>(Stack);
+#line 4456 "runtime.in"
+ {Stack->push<callable*>(new thunk(new bfunc(arrayInsertHelper),a)); return;}
+}
+
+// Returns the delete method for an array.
+#line 4461 "runtime.in"
+void arrayDelete(stack *Stack)
+{
+ array * a=vm::pop<array *>(Stack);
+#line 4462 "runtime.in"
+ {Stack->push<callable*>(new thunk(new bfunc(arrayDeleteHelper),a)); return;}
+}
+
+#line 4466 "runtime.in"
+void arrayAlias(stack *Stack)
+{
+ array * b=vm::pop<array *>(Stack);
+ array * a=vm::pop<array *>(Stack);
+#line 4467 "runtime.in"
+ {Stack->push<bool>(a==b); return;}
+}
+
+// Return array formed by indexing array a with elements of integer array b
+#line 4472 "runtime.in"
+void arrayIntArray(stack *Stack)
+{
+ array * b=vm::pop<array *>(Stack);
+ array * a=vm::pop<array *>(Stack);
+#line 4473 "runtime.in"
+ size_t asize=checkArray(a);
+ size_t bsize=checkArray(b);
+ array *r=new array(bsize);
+ bool cyclic=a->cyclic();
+ for(size_t i=0; i < bsize; i++) {
+ Int index=read<Int>(b,i);
+ if(cyclic && asize > 0) index=imod(index,asize);
+ else
+ if(index < 0 || index >= (Int) asize)
+ outOfBounds("reading",asize,index);
+ (*r)[i]=(*a)[index];
+ }
+ {Stack->push<array*>(r); return;}
+}
+
+// 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 4491 "runtime.in"
+// Intarray* complement(Intarray *a, Int n);
+void gen446(stack *Stack)
+{
+ Int n=vm::pop<Int>(Stack);
+ Intarray * a=vm::pop<Intarray *>(Stack);
+#line 4492 "runtime.in"
+ size_t asize=checkArray(a);
+ array *r=new array(0);
+ bool *keep=new bool[n];
+ for(Int i=0; i < n; ++i) keep[i]=true;
+ for(size_t i=0; i < asize; ++i) {
+ Int j=read<Int>(a,i);
+ if(j >= 0 && j < n) keep[j]=false;
+ }
+ for(Int i=0; i < n; i++)
+ if(keep[i]) r->push(i);
+
+ delete[] keep;
+ {Stack->push<Intarray*>(r); return;}
+}
+
+// Generate the sequence {f(i) : i=0,1,...n-1} given a function f and integer n
+#line 4509 "runtime.in"
+void arraySequence(stack *Stack)
+{
+ Int n=vm::pop<Int>(Stack);
+ callable * f=vm::pop<callable *>(Stack);
+#line 4510 "runtime.in"
+ if(n < 0) n=0;
+ array *a=new array(n);
+ for(Int i=0; i < n; ++i) {
+ Stack->push(i);
+ f->call(Stack);
+ (*a)[i]=pop(Stack);
+ }
+ {Stack->push<Intarray*>(a); return;}
+}
+
+// Return the array {0,1,...n-1}
+#line 4522 "runtime.in"
+// Intarray* sequence(Int n);
+void gen448(stack *Stack)
+{
+ Int n=vm::pop<Int>(Stack);
+#line 4523 "runtime.in"
+ if(n < 0) n=0;
+ array *a=new array(n);
+ for(Int i=0; i < n; ++i) {
+ (*a)[i]=i;
+ }
+ {Stack->push<Intarray*>(a); return;}
+}
+
+// Apply a function to each element of an array
+#line 4533 "runtime.in"
+void arrayFunction(stack *Stack)
+{
+ array * a=vm::pop<array *>(Stack);
+ callable * f=vm::pop<callable *>(Stack);
+#line 4534 "runtime.in"
+ size_t size=checkArray(a);
+ array *b=new array(size);
+ for(size_t i=0; i < size; ++i) {
+ Stack->push((*a)[i]);
+ f->call(Stack);
+ (*b)[i]=pop(Stack);
+ }
+ {Stack->push<array*>(b); return;}
+}
+
+#line 4545 "runtime.in"
+void arraySort(stack *Stack)
+{
+ callable * f=vm::pop<callable *>(Stack);
+ array * a=vm::pop<array *>(Stack);
+#line 4546 "runtime.in"
+ array *c=copyArray(a);
+ compareFunc=f;
+ FuncStack=Stack;
+ stable_sort(c->begin(),c->end(),compareFunction);
+ {Stack->push<array*>(c); return;}
+}
+
+#line 4554 "runtime.in"
+// bool all(boolarray *a);
+void gen451(stack *Stack)
+{
+ boolarray * a=vm::pop<boolarray *>(Stack);
+#line 4555 "runtime.in"
+ size_t size=checkArray(a);
+ bool c=true;
+ for(size_t i=0; i < size; i++)
+ if(!get<bool>((*a)[i])) {c=false; break;}
+ {Stack->push<bool>(c); return;}
+}
+
+#line 4563 "runtime.in"
+// boolarray* !(boolarray* a);
+void gen452(stack *Stack)
+{
+ boolarray* a=vm::pop<boolarray*>(Stack);
+#line 4564 "runtime.in"
+ size_t size=checkArray(a);
+ array *c=new array(size);
+ for(size_t i=0; i < size; i++)
+ (*c)[i]=!read<bool>(a,i);
+ {Stack->push<boolarray*>(c); return;}
+}
+
+#line 4572 "runtime.in"
+// Int sum(boolarray *a);
+void gen453(stack *Stack)
+{
+ boolarray * a=vm::pop<boolarray *>(Stack);
+#line 4573 "runtime.in"
+ size_t size=checkArray(a);
+ Int sum=0;
+ for(size_t i=0; i < size; i++)
+ sum += read<bool>(a,i) ? 1 : 0;
+ {Stack->push<Int>(sum); return;}
+}
+
+#line 4581 "runtime.in"
+void arrayCopy(stack *Stack)
+{
+ array * a=vm::pop<array *>(Stack);
+#line 4582 "runtime.in"
+ {Stack->push<array*>(copyArray(a)); return;}
+}
+
+#line 4586 "runtime.in"
+void arrayConcat(stack *Stack)
+{
+ array * a=vm::pop<array *>(Stack);
+#line 4587 "runtime.in"
+ // a is an array of arrays to be concatenated together.
+ // The signature is
+ // T[] concat(... T[][] a);
+
+ size_t numArgs=checkArray(a);
+ size_t resultSize=0;
+ for (size_t i=0; i < numArgs; ++i) {
+ resultSize += checkArray(a->read<array *>(i));
+ }
+
+ array *result=new array(resultSize);
+
+ size_t ri=0;
+ for (size_t i=0; i < numArgs; ++i) {
+ array *arg=a->read<array *>(i);
+ size_t size=checkArray(arg);
+
+ for (size_t j=0; j < size; ++j) {
+ (*result)[ri]=(*arg)[j];
+ ++ri;
+ }
+ }
+
+ {Stack->push<array*>(result); return;}
+}
+
+#line 4614 "runtime.in"
+void array2Copy(stack *Stack)
+{
+ array * a=vm::pop<array *>(Stack);
+#line 4615 "runtime.in"
+ {Stack->push<array*>(copyArray2(a)); return;}
+}
+
+#line 4619 "runtime.in"
+void array3Copy(stack *Stack)
+{
+ array * a=vm::pop<array *>(Stack);
+#line 4620 "runtime.in"
+ {Stack->push<array*>(copyArray3(a)); return;}
+}
+
+#line 4624 "runtime.in"
+void array2Transpose(stack *Stack)
+{
+ array * a=vm::pop<array *>(Stack);
+#line 4625 "runtime.in"
+ size_t asize=checkArray(a);
+ array *c=new array(0);
+ for(size_t i=0; i < asize; i++) {
+ size_t ip=i+1;
+ array *ai=read<array*>(a,i);
+ size_t aisize=checkArray(ai);
+ size_t csize=checkArray(c);
+ if(csize < aisize) {
+ c->resize(aisize);
+ for(size_t j=csize; j < aisize; j++) {
+ (*c)[j]=new array(ip);
+ }
+ }
+ for(size_t j=0; j < aisize; j++) {
+ array *cj=read<array*>(c,j);
+ if(checkArray(cj) < ip) cj->resize(ip);
+ (*cj)[i]=(*ai)[j];
+ }
+ }
+ {Stack->push<array*>(c); return;}
+}
+
+// a is a rectangular 3D array; perm is an Int array indicating the type of
+// 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 4652 "runtime.in"
+void array3Transpose(stack *Stack)
+{
+ array * perm=vm::pop<array *>(Stack);
+ array * a=vm::pop<array *>(Stack);
+#line 4653 "runtime.in"
+ const size_t DIM=3;
+
+ if(checkArray(perm) != DIM) {
+ ostringstream buf;
+ buf << "permutation array must have length " << DIM;
+ error(buf);
+ }
+
+ size_t* size=new size_t[DIM];
+ for(size_t i=0; i < DIM; ++i) size[i]=DIM;
+
+ for(size_t i=0; i < DIM; ++i) {
+ Int p=read<Int>(perm,i);
+ size_t P=(size_t) p;
+ if(p < 0 || P >= DIM) {
+ ostringstream buf;
+ buf << "permutation index out of range: " << p;
+ error(buf);
+ }
+ size[P]=P;
+ }
+
+ for(size_t i=0; i < DIM; ++i)
+ if(size[i] == DIM) error("permutation indices must be distinct");
+
+ static const char *rectangular=
+ "3D transpose implemented for rectangular matrices only";
+
+ size_t isize=size[0]=checkArray(a);
+ array *a0=read<array*>(a,0);
+ size[1]=checkArray(a0);
+ array *a00=read<array*>(a0,0);
+ size[2]=checkArray(a00);
+ for(size_t i=0; i < isize; i++) {
+ array *ai=read<array*>(a,i);
+ size_t jsize=checkArray(ai);
+ if(jsize != size[1]) error(rectangular);
+ for(size_t j=0; j < jsize; j++) {
+ array *aij=read<array*>(ai,j);
+ if(checkArray(aij) != size[2]) error(rectangular);
+ }
+ }
+
+ size_t perm0=(size_t) read<Int>(perm,0);
+ size_t perm1=(size_t) read<Int>(perm,1);
+ size_t perm2=(size_t) read<Int>(perm,2);
+
+ size_t sizep0=size[perm0];
+ size_t sizep1=size[perm1];
+ size_t sizep2=size[perm2];
+
+ array *c=new array(sizep0);
+ for(size_t i=0; i < sizep0; ++i) {
+ array *ci=new array(sizep1);
+ (*c)[i]=ci;
+ for(size_t j=0; j < sizep1; ++j) {
+ array *cij=new array(sizep2);
+ (*ci)[j]=cij;
+ }
+ }
+
+ size_t* i=new size_t[DIM];
+
+ for(i[0]=0; i[0] < size[0]; ++i[0]) {
+ array *a0=read<array*>(a,i[0]);
+ for(i[1]=0; i[1] < size[1]; ++i[1]) {
+ array *a1=read<array*>(a0,i[1]);
+ for(i[2]=0; i[2] < size[2]; ++i[2]) {
+ array *c0=read<array*>(c,i[perm0]);
+ array *c1=read<array*>(c0,i[perm1]);
+ (*c1)[i[perm2]]=read<real>(a1,i[2]);
+ }
+ }
+ }
+
+ delete [] i;
+ delete [] size;
+
+ {Stack->push<array*>(c); return;}
+}
+
+// In a boolean array, find the index of the nth true value or -1 if not found
+// If n is negative, search backwards.
+#line 4737 "runtime.in"
+// Int find(boolarray *a, Int n=1);
+void gen460(stack *Stack)
+{
+ Int n=vm::pop<Int>(Stack,1);
+ boolarray * a=vm::pop<boolarray *>(Stack);
+#line 4738 "runtime.in"
+
+ size_t size=checkArray(a);
+ Int j=-1;
+ if(n > 0)
+ for(size_t i=0; i < size; i++)
+ if(read<bool>(a,i)) {
+ n--; if(n == 0) {j=(Int) i; break;}
+ }
+ if(n < 0)
+ for(size_t i=size; i > 0;)
+ if(read<bool>(a,--i)) {
+ n++; if(n == 0) {j=(Int) i; break;}
+ }
+ {Stack->push<Int>(j); return;}
+}
+
+#line 4755 "runtime.in"
+// bool ==(realarray2 *a, realarray2 *b);
+void gen461(stack *Stack)
+{
+ realarray2 * b=vm::pop<realarray2 *>(Stack);
+ realarray2 * a=vm::pop<realarray2 *>(Stack);
+#line 4756 "runtime.in"
+ size_t n=checkArray(a);
+ if(n != checkArray(b)) {Stack->push<bool>(false); return;}
+
+ size_t n0=n == 0 ? 0 : checkArray(read<array*>(a,0));
+ if(n0 != checkArray(read<array*>(b,0))) {Stack->push<bool>(false); return;}
+
+ for(size_t i=0; i < n; ++i) {
+ array *ai=read<array*>(a,i);
+ array *bi=read<array*>(b,i);
+ for(size_t j=0; j < n0; ++j) {
+ if(read<real>(ai,j) != read<real>(bi,j))
+ {Stack->push<bool>(false); return;}
+ }
+ }
+ {Stack->push<bool>(true); return;}
+}
+
+// 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 4776 "runtime.in"
+void arrayConditional(stack *Stack)
+{
+ array * c=vm::pop<array *>(Stack);
+ array * b=vm::pop<array *>(Stack);
+ array * a=vm::pop<array *>(Stack);
+#line 4777 "runtime.in"
+ size_t size=checkArray(a);
+ array *r=new array(size);
+ if(b && c) {
+ checkArrays(a,b);
+ checkArrays(b,c);
+ for(size_t i=0; i < size; i++)
+ (*r)[i]=read<bool>(a,i) ? (*b)[i] : (*c)[i];
+ } else {
+ r->clear();
+ if(b) {
+ checkArrays(a,b);
+ for(size_t i=0; i < size; i++)
+ if(read<bool>(a,i)) r->push((*b)[i]);
+ } else if(c) {
+ checkArrays(a,c);
+ for(size_t i=0; i < size; i++)
+ if(!read<bool>(a,i)) r->push((*c)[i]);
+ }
+ }
+ {Stack->push<array*>(r); return;}
+}
+
+// Return an n x n identity matrix.
+#line 4801 "runtime.in"
+// realarray2* identity(Int n);
+void gen463(stack *Stack)
+{
+ Int n=vm::pop<Int>(Stack);
+#line 4802 "runtime.in"
+ {Stack->push<realarray2*>(Identity(n)); return;}
+}
+
+// Return the diagonal matrix with diagonal entries given by a.
+#line 4807 "runtime.in"
+void diagonal(stack *Stack)
+{
+ realarray * a=vm::pop<realarray *>(Stack);
+#line 4808 "runtime.in"
+ size_t n=checkArray(a);
+ array *c=new array(n);
+ for(size_t i=0; i < n; ++i) {
+ array *ci=new array(n);
+ (*c)[i]=ci;
+ for(size_t j=0; j < i; ++j)
+ (*ci)[j]=0.0;
+ (*ci)[i]=read<real>(a,i);
+ for(size_t j=i+1; j < n; ++j)
+ (*ci)[j]=0.0;
+ }
+ {Stack->push<realarray2*>(c); return;}
+}
+
+// Return the inverse of an n x n matrix a using Gauss-Jordan elimination.
+#line 4824 "runtime.in"
+// realarray2* inverse(realarray2 *a);
+void gen465(stack *Stack)
+{
+ realarray2 * a=vm::pop<realarray2 *>(Stack);
+#line 4825 "runtime.in"
+ a=copyArray2(a);
+ size_t n=checkArray(a);
+ checkSquare(a);
+
+ inverseAllocate(n);
+
+ for(size_t i=0; i < n; i++)
+ pivot[i]=0;
+
+ size_t col=0, row=0;
+ // This is the main loop over the columns to be reduced.
+ for(size_t i=0; i < n; i++) {
+ real big=0.0;
+ // This is the outer loop of the search for a pivot element.
+ for(size_t j=0; j < n; j++) {
+ array *aj=read<array*>(a,j);
+ if(pivot[j] != 1) {
+ for(size_t k=0; k < n; k++) {
+ if(pivot[k] == 0) {
+ real temp=fabs(read<real>(aj,k));
+ if(temp >= big) {
+ big=temp;
+ row=j;
+ col=k;
+ }
+ } else if(pivot[k] > 1) {
+ inverseDeallocate();
+ error(singular);
+ }
+ }
+ }
+ }
+ ++(pivot[col]);
+
+ // Interchange rows, if needed, to put the pivot element on the diagonal.
+ array *acol=read<array*>(a,col);
+ if(row != col) {
+ array *arow=read<array*>(a,row);
+ for(size_t l=0; l < n; l++) {
+ real temp=read<real>(arow,l);
+ (*arow)[l]=read<real>(acol,l);
+ (*acol)[l]=temp;
+ }
+ }
+
+ Row[i]=row;
+ Col[i]=col;
+
+ // Divide the pivot row by the pivot element.
+ real denom=read<real>(acol,col);
+ if(denom == 0.0) {
+ inverseDeallocate();
+ error(singular);
+ }
+ real pivinv=1.0/denom;
+ (*acol)[col]=1.0;
+ for(size_t l=0; l < n; l++)
+ (*acol)[l]=read<real>(acol,l)*pivinv;
+
+ // Reduce all rows except for the pivoted one.
+ for(size_t k=0; k < n; k++) {
+ if(k != col) {
+ array *ak=read<array*>(a,k);
+ real akcol=read<real>(ak,col);
+ (*ak)[col]=0.0;
+ for(size_t l=0; l < n; l++)
+ (*ak)[l]=read<real>(ak,l)-read<real>(acol,l)*akcol;
+ }
+ }
+ }
+
+ // Unscramble the inverse matrix in view of the column interchanges.
+ for(size_t l=n; l > 0;) {
+ l--;
+ size_t r=Row[l];
+ size_t c=Col[l];
+ if(r != c) {
+ for(size_t k=0; k < n; k++) {
+ array *ak=read<array*>(a,k);
+ real temp=read<real>(ak,r);
+ (*ak)[r]=read<real>(ak,c);
+ (*ak)[c]=temp;
+ }
+ }
+ }
+ inverseDeallocate();
+ {Stack->push<realarray2*>(a); return;}
+}
+
+// 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 4918 "runtime.in"
+// realarray* solve(realarray2 *a, realarray *b, bool warn=true);
+void gen466(stack *Stack)
+{
+ bool warn=vm::pop<bool>(Stack,true);
+ realarray * b=vm::pop<realarray *>(Stack);
+ realarray2 * a=vm::pop<realarray2 *>(Stack);
+#line 4919 "runtime.in"
+ size_t n=checkArray(a);
+
+ if(n == 0) {Stack->push<realarray*>(new array(0)); return;}
+
+ size_t m=checkArray(b);
+ if(m != n) error(incommensurate);
+
+ real *A=copyArray2C(a);
+ size_t *index=new size_t[n];
+
+ if(LUdecompose(A,n,index,warn) == 0)
+ {Stack->push<realarray*>(new array(0)); return;}
+
+ array *x=new array(n);
+
+ real *B=copyArrayC(b);
+
+ for(size_t i=0; i < n; ++i) {
+ size_t ip=index[i];
+ real sum=B[ip];
+ B[ip]=B[i];
+ real *Ai=A+i*n;
+ for(size_t j=0; j < i; ++j)
+ sum -= Ai[j]*B[j];
+ B[i]=sum;
+ }
+
+ for(size_t i=n; i > 0;) {
+ --i;
+ real sum=B[i];
+ real *Ai=A+i*n;
+ for(size_t j=i+1; j < n; ++j)
+ sum -= Ai[j]*B[j];
+ B[i]=sum/Ai[i];
+ }
+
+ for(size_t i=0; i < n; ++i)
+ (*x)[i]=B[i];
+
+ delete[] index;
+ delete[] B;
+ delete[] A;
+
+ {Stack->push<realarray*>(x); return;}
+}
+
+// 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 4969 "runtime.in"
+// realarray2* solve(realarray2 *a, realarray2 *b, bool warn=true);
+void gen467(stack *Stack)
+{
+ bool warn=vm::pop<bool>(Stack,true);
+ realarray2 * b=vm::pop<realarray2 *>(Stack);
+ realarray2 * a=vm::pop<realarray2 *>(Stack);
+#line 4970 "runtime.in"
+ size_t n=checkArray(a);
+
+ if(n == 0) {Stack->push<realarray2*>(new array(0)); return;}
+
+ if(checkArray(b) != n) error(incommensurate);
+ size_t m=checkArray(read<array*>(b,0));
+
+ real *A=copyArray2C(a);
+ real *B=copyArray2C(b,false);
+
+ size_t *index=new size_t[n];
+
+ if(LUdecompose(A,n,index,warn) == 0)
+ {Stack->push<realarray2*>(new array(0)); return;}
+
+ array *x=new array(n);
+
+ for(size_t i=0; i < n; ++i) {
+ real *Ai=A+i*n;
+ real *Bi=B+i*m;
+ real *Bip=B+index[i]*m;
+ for(size_t k=0; k < m; ++k) {
+ real sum=Bip[k];
+ Bip[k]=Bi[k];
+ size_t jk=k;
+ for(size_t j=0; j < i; ++j, jk += m)
+ sum -= Ai[j]*B[jk];
+ Bi[k]=sum;
+ }
+ }
+
+ for(size_t i=n; i > 0;) {
+ --i;
+ real *Ai=A+i*n;
+ real *Bi=B+i*m;
+ for(size_t k=0; k < m; ++k) {
+ real sum=Bi[k];
+ size_t jk=(i+1)*m+k;
+ for(size_t j=i+1; j < n; ++j, jk += m)
+ sum -= Ai[j]*B[jk];
+ Bi[k]=sum/Ai[i];
+ }
+ }
+
+ for(size_t i=0; i < n; ++i) {
+ real *Bi=B+i*m;
+ array *xi=new array(m);
+ (*x)[i]=xi;
+ for(size_t j=0; j < m; ++j)
+ (*xi)[j]=Bi[j];
+ }
+
+ delete[] index;
+ delete[] B;
+ delete[] A;
+
+ {Stack->push<realarray2*>(x); return;}
+}
+
+// Compute the determinant of an n x n matrix.
+#line 5031 "runtime.in"
+// real determinant(realarray2 *a);
+void gen468(stack *Stack)
+{
+ realarray2 * a=vm::pop<realarray2 *>(Stack);
+#line 5032 "runtime.in"
+ real *A=copyArray2C(a);
+ size_t n=checkArray(a);
+
+ real det=LUdecompose(A,n,NULL,false);
+ size_t n1=n+1;
+ for(size_t i=0; i < n; ++i)
+ det *= A[i*n1];
+
+ delete[] A;
+
+ {Stack->push<real>(det); return;}
+}
+
+#line 5046 "runtime.in"
+// realarray* *(realarray2 *a, realarray *b);
+void gen469(stack *Stack)
+{
+ realarray * b=vm::pop<realarray *>(Stack);
+ realarray2 * a=vm::pop<realarray2 *>(Stack);
+#line 5047 "runtime.in"
+ size_t n=checkArray(a);
+ size_t m=checkArray(b);
+ array *c=new array(n);
+ real *B=copyArrayC(b);
+ for(size_t i=0; i < n; ++i) {
+ array *ai=read<array*>(a,i);
+ if(checkArray(ai) != m) error(incommensurate);
+ real sum=0.0;
+ for(size_t j=0; j < m; ++j)
+ sum += read<real>(ai,j)*B[j];
+ (*c)[i]=sum;
+ }
+ delete[] B;
+ {Stack->push<realarray*>(c); return;}
+}
+
+#line 5064 "runtime.in"
+// realarray2* *(realarray2 *a, realarray2 *b);
+void gen470(stack *Stack)
+{
+ realarray2 * b=vm::pop<realarray2 *>(Stack);
+ realarray2 * a=vm::pop<realarray2 *>(Stack);
+#line 5065 "runtime.in"
+ size_t n=checkArray(a);
+
+ size_t nb=checkArray(b);
+ size_t na0=n == 0 ? 0 : checkArray(read<array*>(a,0));
+ if(na0 != nb)
+ error(incommensurate);
+
+ size_t nb0=nb == 0 ? 0 : checkArray(read<array*>(b,0));
+
+ array *c=new array(n);
+
+ real *A=copyArray2C(a,false);
+ real *B=copyArray2C(b,false);
+
+ for(size_t i=0; i < n; ++i) {
+ real *Ai=A+i*nb;
+ array *ci=new array(nb0);
+ (*c)[i]=ci;
+ for(size_t j=0; j < nb0; ++j) {
+ real sum=0.0;
+ size_t kj=j;
+ for(size_t k=0; k < nb; ++k, kj += nb0)
+ sum += Ai[k]*B[kj];
+ (*ci)[j]=sum;
+ }
+ }
+
+ delete[] B;
+ delete[] A;
+
+ {Stack->push<realarray2*>(c); return;}
+}
+
+#line 5099 "runtime.in"
+// triple *(realarray2 *t, triple v);
+void gen471(stack *Stack)
+{
+ triple v=vm::pop<triple>(Stack);
+ realarray2 * t=vm::pop<realarray2 *>(Stack);
+#line 5100 "runtime.in"
+ {Stack->push<triple>(*t*v); return;}
+}
+
+#line 5104 "runtime.in"
+// pair project(triple v, realarray2 *t);
+void gen472(stack *Stack)
+{
+ realarray2 * t=vm::pop<realarray2 *>(Stack);
+ triple v=vm::pop<triple>(Stack);
+#line 5105 "runtime.in"
+ size_t n=checkArray(t);
+ if(n != 4) error(incommensurate);
+ array *t0=read<array*>(t,0);
+ array *t1=read<array*>(t,1);
+ array *t3=read<array*>(t,3);
+ if(checkArray(t0) != 4 || checkArray(t1) != 4 || checkArray(t3) != 4)
+ error(incommensurate);
+
+ real x=v.getx();
+ real y=v.gety();
+ real z=v.getz();
+
+ real f=read<real>(t3,0)*x+read<real>(t3,1)*y+read<real>(t3,2)*z+
+ read<real>(t3,3);
+ if(f == 0.0) dividebyzero();
+ f=1.0/f;
+
+ {Stack->push<pair>(pair((read<real>(t0,0)*x+read<real>(t0,1)*y+read<real>(t0,2)*z+
+ read<real>(t0,3))*f,
+ (read<real>(t1,0)*x+read<real>(t1,1)*y+read<real>(t1,2)*z+
+ read<real>(t1,3))*f)); return;}
+}
+
+// Compute the dot product of vectors a and b.
+#line 5130 "runtime.in"
+// real dot(realarray *a, realarray *b);
+void gen473(stack *Stack)
+{
+ realarray * b=vm::pop<realarray *>(Stack);
+ realarray * a=vm::pop<realarray *>(Stack);
+#line 5131 "runtime.in"
+ size_t n=checkArrays(a,b);
+ real sum=0.0;
+ for(size_t i=0; i < n; ++i)
+ sum += read<real>(a,i)*read<real>(b,i);
+ {Stack->push<real>(sum); return;}
+}
+
+// Solve the problem L\inv f, where f is an n vector and L is the n x n matrix
+//
+// [ b[0] c[0] a[0] ]
+// [ a[1] b[1] c[1] ]
+// [ a[2] b[2] c[2] ]
+// [ ... ]
+// [ c[n-1] a[n-1] b[n-1] ]
+#line 5146 "runtime.in"
+// realarray* tridiagonal(realarray *a, realarray *b, realarray *c, realarray *f);
+void gen474(stack *Stack)
+{
+ realarray * f=vm::pop<realarray *>(Stack);
+ realarray * c=vm::pop<realarray *>(Stack);
+ realarray * b=vm::pop<realarray *>(Stack);
+ realarray * a=vm::pop<realarray *>(Stack);
+#line 5147 "runtime.in"
+ size_t n=checkArrays(a,b);
+ checkEqual(n,checkArray(c));
+ checkEqual(n,checkArray(f));
+
+ array *up=new array(n);
+ array& u=*up;
+
+ if(n == 0) {Stack->push<realarray*>(up); return;}
+
+ // Special case: zero Dirichlet boundary conditions
+ if(read<real>(a,0) == 0.0 && read<real>(c,n-1) == 0.0) {
+ real temp=read<real>(b,0);
+ if(temp == 0.0) dividebyzero();
+ temp=1.0/temp;
+
+ real *work=new real[n];
+ u[0]=read<real>(f,0)*temp;
+ work[0]=-read<real>(c,0)*temp;
+
+ for(size_t i=1; i < n; i++) {
+ real temp=(read<real>(b,i)+read<real>(a,i)*work[i-1]);
+ if(temp == 0.0) {delete[] work; dividebyzero();}
+ temp=1.0/temp;
+ u[i]=(read<real>(f,i)-read<real>(a,i)*read<real>(u,i-1))*temp;
+ work[i]=-read<real>(c,i)*temp;
+ }
+
+ for(size_t i=n-1; i >= 1; i--)
+ u[i-1]=read<real>(u,i-1)+work[i-1]*read<real>(u,i);
+
+ delete[] work;
+ {Stack->push<realarray*>(up); return;}
+ }
+
+ real binv=read<real>(b,0);
+ if(binv == 0.0) dividebyzero();
+ binv=1.0/binv;
+
+ if(n == 1) {u[0]=read<real>(f,0)*binv; {Stack->push<realarray*>(up); return;}}
+ if(n == 2) {
+ real factor=(read<real>(b,0)*read<real>(b,1)-
+ read<real>(a,0)*read<real>(c,1));
+ if(factor== 0.0) dividebyzero();
+ factor=1.0/factor;
+ real temp=(read<real>(b,0)*read<real>(f,1)-
+ read<real>(c,1)*read<real>(f,0))*factor;
+ u[0]=(read<real>(b,1)*read<real>(f,0)-
+ read<real>(a,0)*read<real>(f,1))*factor;
+ u[1]=temp;
+ {Stack->push<realarray*>(up); return;}
+ }
+
+ real *gamma=new real[n-2];
+ real *delta=new real[n-2];
+
+ gamma[0]=read<real>(c,0)*binv;
+ delta[0]=read<real>(a,0)*binv;
+ u[0]=read<real>(f,0)*binv;
+ real beta=read<real>(c,n-1);
+ real fn=read<real>(f,n-1)-beta*read<real>(u,0);
+ real alpha=read<real>(b,n-1)-beta*delta[0];
+
+ for(size_t i=1; i <= n-3; i++) {
+ real alphainv=read<real>(b,i)-read<real>(a,i)*gamma[i-1];
+ if(alphainv == 0.0) {delete[] gamma; delete[] delta; dividebyzero();}
+ alphainv=1.0/alphainv;
+ beta *= -gamma[i-1];
+ gamma[i]=read<real>(c,i)*alphainv;
+ u[i]=(read<real>(f,i)-read<real>(a,i)*read<real>(u,i-1))*alphainv;
+ fn -= beta*read<real>(u,i);
+ delta[i]=-read<real>(a,i)*delta[i-1]*alphainv;
+ alpha -= beta*delta[i];
+ }
+
+ real alphainv=read<real>(b,n-2)-read<real>(a,n-2)*gamma[n-3];
+ if(alphainv == 0.0) {delete[] gamma; delete[] delta; dividebyzero();}
+ alphainv=1.0/alphainv;
+ u[n-2]=(read<real>(f,n-2)-read<real>(a,n-2)*read<real>(u,n-3))
+ *alphainv;
+ beta=read<real>(a,n-1)-beta*gamma[n-3];
+ real dnm1=(read<real>(c,n-2)-read<real>(a,n-2)*delta[n-3])*alphainv;
+ real temp=alpha-beta*dnm1;
+ if(temp == 0.0) {delete[] gamma; delete[] delta; dividebyzero();}
+ u[n-1]=temp=(fn-beta*read<real>(u,n-2))/temp;
+ u[n-2]=read<real>(u,n-2)-dnm1*temp;
+
+ for(size_t i=n-2; i >= 1; i--)
+ u[i-1]=read<real>(u,i-1)-gamma[i-1]*read<real>(u,i)-delta[i-1]*temp;
+
+ delete[] delta;
+ delete[] gamma;
+
+ {Stack->push<realarray*>(up); return;}
+}
+
+// Root solve by Newton-Raphson
+#line 5244 "runtime.in"
+// real newton(Int iterations=100, callableReal *f, callableReal *fprime, real x, bool verbose=false);
+void gen475(stack *Stack)
+{
+ bool verbose=vm::pop<bool>(Stack,false);
+ real x=vm::pop<real>(Stack);
+ callableReal * fprime=vm::pop<callableReal *>(Stack);
+ callableReal * f=vm::pop<callableReal *>(Stack);
+ Int iterations=vm::pop<Int>(Stack,100);
+#line 5246 "runtime.in"
+ static const real fuzz=1000.0*DBL_EPSILON;
+ Int i=0;
+ size_t oldPrec=0;
+ if(verbose)
+ oldPrec=cout.precision(DBL_DIG);
+
+ real diff=DBL_MAX;
+ real lastdiff;
+ do {
+ real x0=x;
+
+ Stack->push(x);
+ fprime->call(Stack);
+ real dfdx=pop<real>(Stack);
+
+ if(dfdx == 0.0) {
+ x=DBL_MAX;
+ break;
+ }
+
+ Stack->push(x);
+ f->call(Stack);
+ real fx=pop<real>(Stack);
+
+ x -= fx/dfdx;
+
+ lastdiff=diff;
+
+ if(verbose)
+ cout << "Newton-Raphson: " << x << endl;
+
+ diff=fabs(x-x0);
+ if(++i == iterations) {
+ x=DBL_MAX;
+ break;
+ }
+ } while (diff != 0.0 && (diff < lastdiff || diff > fuzz*fabs(x)));
+
+ if(verbose)
+ cout.precision(oldPrec);
+ {Stack->push<real>(x); return;}
+}
+
+// Root solve by Newton-Raphson bisection
+// cf. routine rtsafe (Press et al., Numerical Recipes, 1991).
+#line 5292 "runtime.in"
+// real newton(Int iterations=100, callableReal *f, callableReal *fprime, real x1, real x2, bool verbose=false);
+void gen476(stack *Stack)
+{
+ bool verbose=vm::pop<bool>(Stack,false);
+ real x2=vm::pop<real>(Stack);
+ real x1=vm::pop<real>(Stack);
+ callableReal * fprime=vm::pop<callableReal *>(Stack);
+ callableReal * f=vm::pop<callableReal *>(Stack);
+ Int iterations=vm::pop<Int>(Stack,100);
+#line 5294 "runtime.in"
+ static const real fuzz=1000.0*DBL_EPSILON;
+ size_t oldPrec=0;
+ if(verbose)
+ oldPrec=cout.precision(DBL_DIG);
+
+ Stack->push(x1);
+ f->call(Stack);
+ real f1=pop<real>(Stack);
+ if(f1 == 0.0) {Stack->push<real>(x1); return;}
+
+ Stack->push(x2);
+ f->call(Stack);
+ real f2=pop<real>(Stack);
+ if(f2 == 0.0) {Stack->push<real>(x2); return;}
+
+ if((f1 > 0.0 && f2 > 0.0) || (f1 < 0.0 && f2 < 0.0)) {
+ ostringstream buf;
+ buf << "root not bracketed, f(x1)=" << f1 << ", f(x2)=" << f2 << endl;
+ error(buf);
+ }
+
+ real x=0.5*(x1+x2);
+ real dxold=fabs(x2-x1);
+ if(f1 > 0.0) {
+ real temp=x1;
+ x1=x2;
+ x2=temp;
+ }
+
+ if(verbose)
+ cout << "midpoint: " << x << endl;
+
+ real dx=dxold;
+ Stack->push(x);
+ f->call(Stack);
+ real y=pop<real>(Stack);
+
+ Stack->push(x);
+ fprime->call(Stack);
+ real dy=pop<real>(Stack);
+
+ Int j;
+ for(j=0; j < iterations; j++) {
+ if(((x-x2)*dy-y)*((x-x1)*dy-y) >= 0.0 || fabs(2.0*y) > fabs(dxold*dy)) {
+ dxold=dx;
+ dx=0.5*(x2-x1);
+ x=x1+dx;
+ if(verbose)
+ cout << "bisection: " << x << endl;
+ if(x1 == x) {Stack->push<real>(x); return;}
+ } else {
+ dxold=dx;
+ dx=y/dy;
+ real temp=x;
+ x -= dx;
+ if(verbose)
+ cout << "Newton-Raphson: " << x << endl;
+ if(temp == x) {Stack->push<real>(x); return;}
+ }
+ if(fabs(dx) < fuzz*fabs(x)) {Stack->push<real>(x); return;}
+
+ Stack->push(x);
+ f->call(Stack);
+ y=pop<real>(Stack);
+
+ Stack->push(x);
+ fprime->call(Stack);
+ dy=pop<real>(Stack);
+
+ if(y < 0.0) x1=x;
+ else x2=x;
+ }
+ if(verbose)
+ cout.precision(oldPrec);
+ {Stack->push<real>((j == iterations) ? DBL_MAX : x); return;}
+}
+
+#line 5372 "runtime.in"
+// real simpson(callableReal *f, real a, real b, real acc=DBL_EPSILON, real dxmax=0);
+void gen477(stack *Stack)
+{
+ real dxmax=vm::pop<real>(Stack,0);
+ real acc=vm::pop<real>(Stack,DBL_EPSILON);
+ real b=vm::pop<real>(Stack);
+ real a=vm::pop<real>(Stack);
+ callableReal * f=vm::pop<callableReal *>(Stack);
+#line 5374 "runtime.in"
+ real integral;
+ if(dxmax == 0) dxmax=b-a;
+ Func=f;
+ FuncStack=Stack;
+ if(!simpson(integral,wrapFunction,a,b,acc,dxmax))
+ error("nesting capacity exceeded in simpson");
+ {Stack->push<real>(integral); return;}
+}
+
+// Compute the fast Fourier transform of a pair array
+#line 5385 "runtime.in"
+void pairArrayFFT(stack *Stack)
+{
+ Int sign=vm::pop<Int>(Stack,1);
+ pairarray * a=vm::pop<pairarray *>(Stack);
+#line 5386 "runtime.in"
+ unsigned n=(unsigned) checkArray(a);
+#ifdef HAVE_LIBFFTW3
+ array *c=new array(n);
+ if(n) {
+ Complex *f=FFTWComplex(n);
+ fft1d Forward(n,intcast(sign),f);
+
+ for(size_t i=0; i < n; i++) {
+ pair z=read<pair>(a,i);
+ f[i]=Complex(z.getx(),z.gety());
+ }
+ Forward.fft(f);
+
+ for(size_t i=0; i < n; i++) {
+ Complex z=f[i];
+ (*c)[i]=pair(z.real(),z.imag());
+ }
+ FFTWdelete(f);
+ }
+#else
+ unused(&n);
+ unused(&sign);
+ array *c=new array(0);
+#endif // HAVE_LIBFFTW3
+ {Stack->push<pairarray*>(c); return;}
+}
+
+#line 5414 "runtime.in"
+// Intarray2* triangulate(pairarray *z);
+void gen479(stack *Stack)
+{
+ pairarray * z=vm::pop<pairarray *>(Stack);
+#line 5415 "runtime.in"
+ size_t nv=checkArray(z);
+// Call robust version of Gilles Dumoulin's port of Paul Bourke's
+// triangulation code.
+
+ XYZ *pxyz=new XYZ[nv+3];
+ ITRIANGLE *V=new ITRIANGLE[4*nv];
+
+ for(size_t i=0; i < nv; ++i) {
+ pair w=read<pair>(z,i);
+ pxyz[i].p[0]=w.getx();
+ pxyz[i].p[1]=w.gety();
+ pxyz[i].i=(Int) i;
+ }
+
+ Int ntri;
+ Triangulate((Int) nv,pxyz,V,ntri,true,false);
+
+ size_t nt=(size_t) ntri;
+ array *t=new array(nt);
+ for(size_t i=0; i < nt; ++i) {
+ array *ti=new array(3);
+ (*t)[i]=ti;
+ ITRIANGLE *Vi=V+i;
+ (*ti)[0]=pxyz[Vi->p1].i;
+ (*ti)[1]=pxyz[Vi->p2].i;
+ (*ti)[2]=pxyz[Vi->p3].i;
+ }
+
+ delete[] V;
+ delete[] pxyz;
+ {Stack->push<Intarray2*>(t); return;}
+}
+
+
+// File operations
+#line 5451 "runtime.in"
+// bool ==(file *a, file *b);
+void gen480(stack *Stack)
+{
+ file * b=vm::pop<file *>(Stack);
+ file * a=vm::pop<file *>(Stack);
+#line 5452 "runtime.in"
+ {Stack->push<bool>(a == b); return;}
+}
+
+#line 5457 "runtime.in"
+// bool !=(file *a, file *b);
+void gen481(stack *Stack)
+{
+ file * b=vm::pop<file *>(Stack);
+ file * a=vm::pop<file *>(Stack);
+#line 5458 "runtime.in"
+ {Stack->push<bool>(a != b); return;}
+}
+
+#line 5462 "runtime.in"
+void nullFile(stack *Stack)
+{
+#line 5463 "runtime.in"
+ {Stack->push<file*>(&camp::nullfile); return;}
+}
+
+#line 5467 "runtime.in"
+// file* input(string name, bool check=true, string comment=commentchar);
+void gen483(stack *Stack)
+{
+ string comment=vm::pop<string>(Stack,commentchar);
+ bool check=vm::pop<bool>(Stack,true);
+ string name=vm::pop<string>(Stack);
+#line 5468 "runtime.in"
+ char c=comment.empty() ? (char) 0 : comment[0];
+ file *f=new ifile(name,c,check);
+ f->open();
+ {Stack->push<file*>(f); return;}
+}
+
+#line 5475 "runtime.in"
+// file* output(string name, bool update=false, string comment=commentchar);
+void gen484(stack *Stack)
+{
+ string comment=vm::pop<string>(Stack,commentchar);
+ bool update=vm::pop<bool>(Stack,false);
+ string name=vm::pop<string>(Stack);
+#line 5476 "runtime.in"
+ file *f;
+ if(update) {
+ char c=comment.empty() ? (char) 0 : comment[0];
+ f=new iofile(name,c);
+ } else f=new ofile(name);
+ f->open();
+ if(update) f->seek(0,false);
+ {Stack->push<file*>(f); return;}
+}
+
+#line 5487 "runtime.in"
+// file* xinput(string name, bool check=true);
+void gen485(stack *Stack)
+{
+ bool check=vm::pop<bool>(Stack,true);
+ string name=vm::pop<string>(Stack);
+#line 5488 "runtime.in"
+#ifdef HAVE_RPC_RPC_H
+ file *f=new ixfile(name,check);
+ f->open();
+ {Stack->push<file*>(f); return;}
+#else
+ ostringstream buf;
+ buf << name << ": XDR read support not enabled";
+ error(buf);
+ unused(&check); // Suppress unused variable warning
+#endif
+}
+
+#line 5501 "runtime.in"
+// file* xoutput(string name, bool update=false);
+void gen486(stack *Stack)
+{
+ bool update=vm::pop<bool>(Stack,false);
+ string name=vm::pop<string>(Stack);
+#line 5502 "runtime.in"
+#ifdef HAVE_RPC_RPC_H
+ file *f;
+ if(update)
+ f=new ioxfile(name);
+ else f=new oxfile(name);
+ f->open();
+ if(update) f->seek(0,false);
+ {Stack->push<file*>(f); return;}
+#else
+ ostringstream buf;
+ buf << name << ": XDR write support not enabled";
+ error(buf);
+ unused(&update); // Suppress unused variable warning
+#endif
+}
+
+#line 5519 "runtime.in"
+// file* binput(string name, bool check=true);
+void gen487(stack *Stack)
+{
+ bool check=vm::pop<bool>(Stack,true);
+ string name=vm::pop<string>(Stack);
+#line 5520 "runtime.in"
+ file *f=new ibfile(name,check);
+ f->open();
+ {Stack->push<file*>(f); return;}
+}
+
+#line 5526 "runtime.in"
+// file* boutput(string name, bool update=false);
+void gen488(stack *Stack)
+{
+ bool update=vm::pop<bool>(Stack,false);
+ string name=vm::pop<string>(Stack);
+#line 5527 "runtime.in"
+ file *f;
+ if(update) f=new iobfile(name);
+ else f=new obfile(name);
+ f->open();
+ if(update) f->seek(0,false);
+ {Stack->push<file*>(f); return;}
+}
+
+#line 5536 "runtime.in"
+// bool eof(file *File);
+void gen489(stack *Stack)
+{
+ file * File=vm::pop<file *>(Stack);
+#line 5537 "runtime.in"
+ {Stack->push<bool>(File->eof()); return;}
+}
+
+#line 5541 "runtime.in"
+// bool eol(file *File);
+void gen490(stack *Stack)
+{
+ file * File=vm::pop<file *>(Stack);
+#line 5542 "runtime.in"
+ {Stack->push<bool>(File->eol()); return;}
+}
+
+#line 5546 "runtime.in"
+// bool error(file *File);
+void gen491(stack *Stack)
+{
+ file * File=vm::pop<file *>(Stack);
+#line 5547 "runtime.in"
+ {Stack->push<bool>(File->error()); return;}
+}
+
+#line 5551 "runtime.in"
+// void clear(file *File);
+void gen492(stack *Stack)
+{
+ file * File=vm::pop<file *>(Stack);
+#line 5552 "runtime.in"
+ File->clear();
+}
+
+#line 5556 "runtime.in"
+// void close(file *File);
+void gen493(stack *Stack)
+{
+ file * File=vm::pop<file *>(Stack);
+#line 5557 "runtime.in"
+ File->close();
+}
+
+#line 5561 "runtime.in"
+// Int precision(file *File=NULL, Int digits=0);
+void gen494(stack *Stack)
+{
+ Int digits=vm::pop<Int>(Stack,0);
+ file * File=vm::pop<file *>(Stack,NULL);
+#line 5562 "runtime.in"
+ if(File == 0) File=&camp::Stdout;
+ {Stack->push<Int>(File->precision(digits)); return;}
+}
+
+#line 5567 "runtime.in"
+// void flush(file *File);
+void gen495(stack *Stack)
+{
+ file * File=vm::pop<file *>(Stack);
+#line 5568 "runtime.in"
+ File->flush();
+}
+
+#line 5572 "runtime.in"
+// string getc(file *File);
+void gen496(stack *Stack)
+{
+ file * File=vm::pop<file *>(Stack);
+#line 5573 "runtime.in"
+ char c=0;
+ if(File->isOpen()) File->read(c);
+ static char str[1];
+ str[0]=c;
+ {Stack->push<string>(string(str)); return;}
+}
+
+#line 5581 "runtime.in"
+// Int tell(file *File);
+void gen497(stack *Stack)
+{
+ file * File=vm::pop<file *>(Stack);
+#line 5582 "runtime.in"
+ {Stack->push<Int>(File->tell()); return;}
+}
+
+#line 5586 "runtime.in"
+// void seek(file *File, Int pos);
+void gen498(stack *Stack)
+{
+ Int pos=vm::pop<Int>(Stack);
+ file * File=vm::pop<file *>(Stack);
+#line 5587 "runtime.in"
+ File->seek(pos,pos >= 0);
+}
+
+#line 5591 "runtime.in"
+// void seekeof(file *File);
+void gen499(stack *Stack)
+{
+ file * File=vm::pop<file *>(Stack);
+#line 5592 "runtime.in"
+ File->seek(0,false);
+}
+
+// Set file dimensions
+#line 5597 "runtime.in"
+// file* dimension(file *File, Int nx);
+void gen500(stack *Stack)
+{
+ Int nx=vm::pop<Int>(Stack);
+ file * File=vm::pop<file *>(Stack);
+#line 5598 "runtime.in"
+ File->dimension(nx);
+ {Stack->push<file*>(File); return;}
+}
+
+#line 5603 "runtime.in"
+// file* dimension(file *File, Int nx, Int ny);
+void gen501(stack *Stack)
+{
+ Int ny=vm::pop<Int>(Stack);
+ Int nx=vm::pop<Int>(Stack);
+ file * File=vm::pop<file *>(Stack);
+#line 5604 "runtime.in"
+ File->dimension(nx,ny);
+ {Stack->push<file*>(File); return;}
+}
+
+#line 5609 "runtime.in"
+// file* dimension(file *File, Int nx, Int ny, Int nz);
+void gen502(stack *Stack)
+{
+ Int nz=vm::pop<Int>(Stack);
+ Int ny=vm::pop<Int>(Stack);
+ Int nx=vm::pop<Int>(Stack);
+ file * File=vm::pop<file *>(Stack);
+#line 5610 "runtime.in"
+ File->dimension(nx,ny,nz);
+ {Stack->push<file*>(File); return;}
+}
+
+// Set file to read comma-separated values
+#line 5616 "runtime.in"
+// file* csv(file *File, bool b=true);
+void gen503(stack *Stack)
+{
+ bool b=vm::pop<bool>(Stack,true);
+ file * File=vm::pop<file *>(Stack);
+#line 5617 "runtime.in"
+ File->CSVMode(b);
+ {Stack->push<file*>(File); return;}
+}
+
+// Set file to read whitespace-separated values
+#line 5623 "runtime.in"
+// file* word(file *File, bool b=true);
+void gen504(stack *Stack)
+{
+ bool b=vm::pop<bool>(Stack,true);
+ file * File=vm::pop<file *>(Stack);
+#line 5624 "runtime.in"
+ File->WordMode(b);
+ {Stack->push<file*>(File); return;}
+}
+
+// Set file to read arrays in line-at-a-time mode
+#line 5630 "runtime.in"
+// file* line(file *File, bool b=true);
+void gen505(stack *Stack)
+{
+ bool b=vm::pop<bool>(Stack,true);
+ file * File=vm::pop<file *>(Stack);
+#line 5631 "runtime.in"
+ File->LineMode(b);
+ {Stack->push<file*>(File); return;}
+}
+
+// Set file to read/write single-precision XDR values.
+#line 5637 "runtime.in"
+// file* single(file *File, bool b=true);
+void gen506(stack *Stack)
+{
+ bool b=vm::pop<bool>(Stack,true);
+ file * File=vm::pop<file *>(Stack);
+#line 5638 "runtime.in"
+ File->SingleReal(b);
+ File->SingleInt(b);
+ {Stack->push<file*>(File); return;}
+}
+
+// Set file to read/write single-precision real XDR values.
+#line 5645 "runtime.in"
+// file* single(file *File, real x, bool b=true);
+void gen507(stack *Stack)
+{
+ bool b=vm::pop<bool>(Stack,true);
+ real x=vm::pop<real>(Stack);
+ file * File=vm::pop<file *>(Stack);
+#line 5646 "runtime.in"
+ File->SingleReal(b);
+ unused(&x);
+ {Stack->push<file*>(File); return;}
+}
+
+// Set file to read/write single-precision int XDR values.
+#line 5653 "runtime.in"
+// file* single(file *File, Int x, bool b=true);
+void gen508(stack *Stack)
+{
+ bool b=vm::pop<bool>(Stack,true);
+ Int x=vm::pop<Int>(Stack);
+ file * File=vm::pop<file *>(Stack);
+#line 5654 "runtime.in"
+ File->SingleInt(b);
+ unused(&x);
+ {Stack->push<file*>(File); return;}
+}
+
+// Set file to read an array1 (1 Int size followed by a 1d array)
+#line 5661 "runtime.in"
+// file* read1(file *File);
+void gen509(stack *Stack)
+{
+ file * File=vm::pop<file *>(Stack);
+#line 5662 "runtime.in"
+ File->dimension(-2);
+ {Stack->push<file*>(File); return;}
+}
+
+// Set file to read an array2 (2 Int sizes followed by a 2d array)
+#line 5668 "runtime.in"
+// file* read2(file *File);
+void gen510(stack *Stack)
+{
+ file * File=vm::pop<file *>(Stack);
+#line 5669 "runtime.in"
+ File->dimension(-2,-2);
+ {Stack->push<file*>(File); return;}
+}
+
+// Set file to read an array3 (3 Int sizes followed by a 3d array)
+#line 5675 "runtime.in"
+// file* read3(file *File);
+void gen511(stack *Stack)
+{
+ file * File=vm::pop<file *>(Stack);
+#line 5676 "runtime.in"
+ File->dimension(-2,-2,-2);
+ {Stack->push<file*>(File); return;}
+}
+
+// Return the last n lines of the history named name.
+#line 5682 "runtime.in"
+// stringarray* history(string name, Int n=1);
+void gen512(stack *Stack)
+{
+ Int n=vm::pop<Int>(Stack,1);
+ string name=vm::pop<string>(Stack);
+#line 5683 "runtime.in"
+#if defined(HAVE_LIBREADLINE) && defined(HAVE_LIBCURSES)
+ bool newhistory=historyMap.find(name) == historyMap.end();
+
+ string filename;
+
+ if(newhistory) {
+ filename=historyfilename(name);
+ std::ifstream exists(filename.c_str());
+ if(!exists) {Stack->push<stringarray*>(new array(0)); return;}
+ }
+
+ store_history(&history_save);
+ HISTORY_STATE& history=historyMap[name].state;
+ history_set_history_state(&history);
+
+ if(newhistory)
+ read_history(filename.c_str());
+
+ array *a=get_history(n);
+
+ store_history(&history);
+ history_set_history_state(&history_save);
+
+ {Stack->push<stringarray*>(a); return;}
+#else
+ unused(&n);
+ {Stack->push<stringarray*>(new array(0)); return;}
+#endif
+}
+
+// Return the last n lines of the interactive history.
+#line 5715 "runtime.in"
+// stringarray* history(Int n=0);
+void gen513(stack *Stack)
+{
+ Int n=vm::pop<Int>(Stack,0);
+#line 5716 "runtime.in"
+#if defined(HAVE_LIBREADLINE) && defined(HAVE_LIBCURSES)
+ {Stack->push<stringarray*>(get_history(n)); return;}
+#else
+ unused(&n);
+ {Stack->push<stringarray*>(new array(0)); return;}
+#endif
+}
+
+// Prompt for a string using prompt, the GNU readline library, and a
+// local history named name.
+#line 5727 "runtime.in"
+// string readline(string prompt=emptystring, string name=emptystring, bool tabcompletion=false);
+void gen514(stack *Stack)
+{
+ bool tabcompletion=vm::pop<bool>(Stack,false);
+ string name=vm::pop<string>(Stack,emptystring);
+ string prompt=vm::pop<string>(Stack,emptystring);
+#line 5729 "runtime.in"
+ if(!isatty(STDIN_FILENO))
+ {Stack->push<string>(emptystring); return;}
+#if defined(HAVE_LIBREADLINE) && defined(HAVE_LIBCURSES)
+ init_readline(tabcompletion);
+
+ store_history(&history_save);
+ bool newhistory=historyMap.find(name) == historyMap.end();
+ historyState& h=historyMap[name];
+ HISTORY_STATE& history=h.state;
+ history_set_history_state(&history);
+
+ if(newhistory)
+ read_history(historyfilename(name).c_str());
+
+ static char *line=NULL;
+ /* Return the memory to the free pool
+ if the buffer has already been allocated. */
+ if(line) {
+ free(line);
+ line=NULL;
+ }
+
+ /* Get a line from the user. */
+ line=readline(prompt.c_str());
+
+ if(!line) cout << endl;
+
+ history_set_history_state(&history_save);
+
+ {Stack->push<string>(line ? string(line) : emptystring); return;}
+#else
+ cout << prompt;
+ string s;
+ getline(cin,s);
+ unused(&tabcompletion); // Avoid unused variable warning message.
+ {Stack->push<string>(s); return;}
+#endif
+}
+
+// Save a string in a local history named name.
+// If store=true, store the local history in the file historyfilename(name).
+#line 5771 "runtime.in"
+// void saveline(string name, string value, bool store=true);
+void gen515(stack *Stack)
+{
+ bool store=vm::pop<bool>(Stack,true);
+ string value=vm::pop<string>(Stack);
+ string name=vm::pop<string>(Stack);
+#line 5772 "runtime.in"
+#if defined(HAVE_LIBREADLINE) && defined(HAVE_LIBCURSES)
+ store_history(&history_save);
+ bool newhistory=historyMap.find(name) == historyMap.end();
+ historyState& h=historyMap[name];
+ h.store=store;
+ HISTORY_STATE& history=h.state;
+ history_set_history_state(&history);
+
+ if(newhistory)
+ read_history(historyfilename(name).c_str());
+
+ if(value != "") {
+ add_history(value.c_str());
+ if(store) {
+ std::ofstream hout(historyfilename(name).c_str(),std::ios::app);
+ hout << value << endl;
+ }
+ }
+
+ store_history(&history);
+ history_set_history_state(&history_save);
+#else
+ unused(&store);
+#endif
+}
+
+#line 5799 "runtime.in"
+// void generate_random_backtrace();
+void gen516(stack *)
+{
+#line 5800 "runtime.in"
+#if defined(USEGC) && defined(GC_DEBUG) && defined(GC_BACKTRACE)
+ GC_generate_random_backtrace();
+#else
+ error("generate_random_backtrace() requires ./configure --enable-gc-debug");
+#endif
+}
+
+#line 5808 "runtime.in"
+// void print_random_addresses(Int n=1);
+void gen517(stack *Stack)
+{
+ Int n=vm::pop<Int>(Stack,1);
+#line 5809 "runtime.in"
+#if defined(USEGC) && defined(GC_DEBUG) && defined(GC_BACKTRACE)
+ GC_gcollect();
+ for (Int i=0; i < n; ++i)
+ GC_debug_print_heap_obj_proc(GC_base(GC_generate_random_valid_address()));
+#else
+ error("print_random_addresses() requires ./configure --enable-gc-debug");
+ unused(&n); // Avoid unused variable warning message.
+#endif
+}
+
+} // namespace run
+
+namespace trans {
+
+void gen_base_venv(venv &ve)
+{
+#line 1074 "runtime.in"
+ addFunc(ve, run::gen8, primBoolean(), "!", formal(primBoolean(), "b", false, false));
+#line 1102 "runtime.in"
+ addFunc(ve, run::gen13, primInt(), "AND", formal(primInt(), "a", false, false), formal(primInt(), "b", false, false));
+#line 1110 "runtime.in"
+ addFunc(ve, run::gen14, primInt(), "OR", formal(primInt(), "a", false, false), formal(primInt(), "b", false, false));
+#line 1115 "runtime.in"
+ addFunc(ve, run::gen15, primInt(), "XOR", formal(primInt(), "a", false, false), formal(primInt(), "b", false, false));
+#line 1120 "runtime.in"
+ addFunc(ve, run::gen16, primInt(), "NOT", formal(primInt(), "a", false, false));
+#line 1151 "runtime.in"
+ addFunc(ve, run::gen21, primBoolean(), "empty", formal(primPicture(), "f", false, false));
+#line 1156 "runtime.in"
+ addFunc(ve, run::gen22, primVoid(), "erase", formal(primPicture(), "f", false, false));
+#line 1161 "runtime.in"
+ addFunc(ve, run::gen23, primPair(), "min", formal(primPicture(), "f", false, false));
+#line 1166 "runtime.in"
+ addFunc(ve, run::gen24, primPair(), "max", formal(primPicture(), "f", false, false));
+#line 1171 "runtime.in"
+ addFunc(ve, run::gen25, primVoid(), "label", formal(primPicture(), "f", false, false), formal(primString(), "s", false, false), formal(primString(), "size", false, false), formal(primTransform(), "t", false, false), formal(primPair(), "position", false, false), formal(primPair(), "align", false, false), formal(primPen(), "p", false, false));
+#line 1177 "runtime.in"
+ addFunc(ve, run::gen26, primBoolean(), "labels", formal(primPicture(), "f", false, false));
+#line 1182 "runtime.in"
+ addFunc(ve, run::gen27, pathArray() , "_texpath", formal(primString(), "s", false, false), formal(primPen(), "p", true, false));
+#line 1249 "runtime.in"
+ addFunc(ve, run::gen28, pathArray() , "_strokepath", formal(primPath(), "g", false, false), formal(primPen(), "p", true, false));
+#line 1273 "runtime.in"
+ addFunc(ve, run::gen29, primVoid(), "_draw", formal(primPicture(), "f", false, false), formal(primPath(), "g", false, false), formal(primPen(), "p", false, false));
+#line 1278 "runtime.in"
+ addFunc(ve, run::gen30, primVoid(), "fill", formal(primPicture(), "f", false, false), formal(pathArray() , "g", false, false), formal(primPen(), "p", true, false), formal(primBoolean(), "copy", true, false));
+#line 1284 "runtime.in"
+ addFunc(ve, run::gen31, primVoid(), "latticeshade", formal(primPicture(), "f", false, false), formal(pathArray() , "g", false, false), formal(primBoolean(), "stroke", true, false), formal(primPen(), "fillrule", true, false), formal(penArray2() , "p", false, false), formal(primBoolean(), "copy", true, false));
+#line 1291 "runtime.in"
+ addFunc(ve, run::gen32, primVoid(), "axialshade", formal(primPicture(), "f", false, false), formal(pathArray() , "g", false, false), formal(primBoolean(), "stroke", true, false), formal(primPen(), "pena", false, false), formal(primPair(), "a", false, false), formal(primPen(), "penb", false, false), formal(primPair(), "b", false, false), formal(primBoolean(), "copy", true, false));
+#line 1298 "runtime.in"
+ addFunc(ve, run::gen33, primVoid(), "radialshade", formal(primPicture(), "f", false, false), formal(pathArray() , "g", false, false), formal(primBoolean(), "stroke", true, false), formal(primPen(), "pena", false, false), formal(primPair(), "a", false, false), formal(primReal(), "ra", false, false), formal(primPen(), "penb", false, false), formal(primPair(), "b", false, false), formal(primReal(), "rb", false, false), formal(primBoolean(), "copy", true, false));
+#line 1305 "runtime.in"
+ addFunc(ve, run::gen34, primVoid(), "gouraudshade", formal(primPicture(), "f", false, false), formal(pathArray() , "g", false, false), formal(primBoolean(), "stroke", true, false), formal(primPen(), "fillrule", true, false), formal(penArray() , "p", false, false), formal(pairArray(), "z", false, false), formal(IntArray(), "edges", false, false), formal(primBoolean(), "copy", true, false));
+#line 1316 "runtime.in"
+ addFunc(ve, run::gen35, primVoid(), "gouraudshade", formal(primPicture(), "f", false, false), formal(pathArray() , "g", false, false), formal(primBoolean(), "stroke", true, false), formal(primPen(), "fillrule", true, false), formal(penArray() , "p", false, false), formal(IntArray(), "edges", false, false), formal(primBoolean(), "copy", true, false));
+#line 1340 "runtime.in"
+ addFunc(ve, run::gen36, primVoid(), "tensorshade", formal(primPicture(), "f", false, false), formal(pathArray() , "g", false, false), formal(primBoolean(), "stroke", true, false), formal(primPen(), "fillrule", true, false), formal(penArray2() , "p", false, false), formal(pathArray() , "b", true, false), formal(pairArray2(), "z", true, false), formal(primBoolean(), "copy", true, false));
+#line 1355 "runtime.in"
+ addFunc(ve, run::gen37, primVoid(), "functionshade", formal(primPicture(), "f", false, false), formal(pathArray() , "g", false, false), formal(primBoolean(), "stroke", true, false), formal(primPen(), "fillrule", true, false), formal(primString() , "shader", true, false), formal(primBoolean(), "copy", true, false));
+#line 1363 "runtime.in"
+ addFunc(ve, run::gen38, primVoid(), "clip", formal(primPicture(), "f", false, false), formal(pathArray() , "g", false, false), formal(primBoolean(), "stroke", true, false), formal(primPen(), "fillrule", true, false), formal(primBoolean(), "copy", true, false));
+#line 1373 "runtime.in"
+ addFunc(ve, run::gen39, primVoid(), "beginclip", formal(primPicture(), "f", false, false), formal(pathArray() , "g", false, false), formal(primBoolean(), "stroke", true, false), formal(primPen(), "fillrule", true, false), formal(primBoolean(), "copy", true, false));
+#line 1380 "runtime.in"
+ addFunc(ve, run::gen40, primVoid(), "endclip", formal(primPicture(), "f", false, false));
+#line 1385 "runtime.in"
+ addFunc(ve, run::gen41, primVoid(), "gsave", formal(primPicture(), "f", false, false));
+#line 1390 "runtime.in"
+ addFunc(ve, run::gen42, primVoid(), "grestore", formal(primPicture(), "f", false, false));
+#line 1395 "runtime.in"
+ addFunc(ve, run::gen43, primVoid(), "begingroup", formal(primPicture(), "f", false, false));
+#line 1400 "runtime.in"
+ addFunc(ve, run::gen44, primVoid(), "endgroup", formal(primPicture(), "f", false, false));
+#line 1405 "runtime.in"
+ addFunc(ve, run::gen45, primVoid(), "add", formal(primPicture(), "dest", false, false), formal(primPicture(), "src", false, false));
+#line 1410 "runtime.in"
+ addFunc(ve, run::gen46, primVoid(), "prepend", formal(primPicture(), "dest", false, false), formal(primPicture(), "src", false, false));
+#line 1415 "runtime.in"
+ addFunc(ve, run::gen47, primVoid(), "postscript", formal(primPicture(), "f", false, false), formal(primString() , "s", false, false));
+#line 1420 "runtime.in"
+ addFunc(ve, run::gen48, primVoid(), "tex", formal(primPicture(), "f", false, false), formal(primString() , "s", false, false));
+#line 1425 "runtime.in"
+ addFunc(ve, run::gen49, primVoid(), "postscript", formal(primPicture(), "f", false, false), formal(primString() , "s", false, false), formal(primPair(), "min", false, false), formal(primPair(), "max", false, false));
+#line 1430 "runtime.in"
+ addFunc(ve, run::gen50, primVoid(), "tex", formal(primPicture(), "f", false, false), formal(primString() , "s", false, false), formal(primPair(), "min", false, false), formal(primPair(), "max", false, false));
+#line 1435 "runtime.in"
+ addFunc(ve, run::gen51, primVoid(), "texpreamble", formal(primString() , "s", false, false));
+#line 1443 "runtime.in"
+ addFunc(ve, run::gen52, primVoid(), "deletepreamble");
+#line 1450 "runtime.in"
+ addFunc(ve, run::gen53, primVoid(), "_labelpath", formal(primPicture(), "f", false, false), formal(primString() , "s", false, false), formal(primString() , "size", false, false), formal(primPath(), "g", false, false), formal(primString() , "justify", false, false), formal(primPair(), "offset", false, false), formal(primPen(), "p", false, false));
+#line 1456 "runtime.in"
+ addFunc(ve, run::gen54, primVoid(), "texreset");
+#line 1464 "runtime.in"
+ addFunc(ve, run::gen55, primVoid(), "layer", formal(primPicture(), "f", false, false));
+#line 1469 "runtime.in"
+ addFunc(ve, run::gen56, primVoid(), "newpage", formal(primPicture(), "f", false, false));
+#line 1474 "runtime.in"
+ addFunc(ve, run::gen57, primVoid(), "_image", formal(primPicture(), "f", false, false), formal(realArray2(), "data", false, false), formal(primPair(), "initial", false, false), formal(primPair(), "final", false, false), formal(penArray() , "palette", true, false), formal(primTransform(), "t", true, false), formal(primBoolean(), "copy", true, false), formal(primBoolean(), "antialias", true, false));
+#line 1484 "runtime.in"
+ addFunc(ve, run::gen58, primVoid(), "_image", formal(primPicture(), "f", false, false), formal(penArray2() , "data", false, false), formal(primPair(), "initial", false, false), formal(primPair(), "final", false, false), formal(primTransform(), "t", true, false), formal(primBoolean(), "copy", true, false), formal(primBoolean(), "antialias", true, false));
+#line 1491 "runtime.in"
+ addFunc(ve, run::gen59, primString() , "nativeformat");
+#line 1496 "runtime.in"
+ addFunc(ve, run::gen60, primBoolean(), "latex");
+#line 1501 "runtime.in"
+ addFunc(ve, run::gen61, primBoolean(), "pdf");
+#line 1506 "runtime.in"
+ addFunc(ve, run::gen62, primVoid(), "shipout", formal(primString() , "prefix", true, false), formal(primPicture(), "f", false, false), formal(primPicture(), "preamble", true, false), formal(primString() , "format", true, false), formal(primBoolean(), "wait", true, false), formal(primBoolean(), "view", true, false), formal(transformFunction(), "xform", false, false));
+#line 1552 "runtime.in"
+ addFunc(ve, run::gen63, primVoid(), "shipout3", formal(primString() , "prefix", false, false), formal(primPicture(), "f", false, false), formal(primString() , "format", true, false), formal(primReal(), "width", false, false), formal(primReal(), "height", false, false), formal(primReal(), "angle", false, false), formal(primTriple(), "m", false, false), formal(primTriple(), "m", false, false), formal(realArray2(), "t", false, false), formal(tripleArray(), "lights", false, false), formal(realArray2(), "diffuse", false, false), formal(realArray2(), "ambient", false, false), formal(realArray2(), "specular", false, false), formal(primBoolean(), "viewportlighting", false, false), formal(primBoolean(), "view", true, false));
+#line 1568 "runtime.in"
+ addFunc(ve, run::gen64, primVoid(), "shipout3", formal(primString() , "prefix", false, false), formal(primPicture(), "f", false, false));
+#line 1573 "runtime.in"
+ addFunc(ve, run::gen65, primVoid(), "deconstruct", formal(primPicture(), "f", false, false), formal(primPicture(), "preamble", true, false), formal(primReal(), "magnification", true, false), formal(transformFunction(), "xform", false, false));
+#line 1706 "runtime.in"
+ addFunc(ve, run::gen66, primVoid(), "purge", formal(primInt(), "divisor", true, false));
+#line 1719 "runtime.in"
+ addFunc(ve, run::gen68, primBoolean(), "==", formal(primPen(), "a", false, false), formal(primPen(), "b", false, false));
+#line 1724 "runtime.in"
+ addFunc(ve, run::gen69, primBoolean(), "!=", formal(primPen(), "a", false, false), formal(primPen(), "b", false, false));
+#line 1729 "runtime.in"
+ addFunc(ve, run::gen70, primPen(), "+", formal(primPen(), "a", false, false), formal(primPen(), "b", false, false));
+#line 1734 "runtime.in"
+ addFunc(ve, run::gen71, primPen(), "*", formal(primReal(), "a", false, false), formal(primPen(), "b", false, false));
+#line 1739 "runtime.in"
+ addFunc(ve, run::gen72, primPen(), "*", formal(primPen(), "a", false, false), formal(primReal(), "b", false, false));
+#line 1744 "runtime.in"
+ addFunc(ve, run::gen73, primPair(), "max", formal(primPen(), "p", false, false));
+#line 1749 "runtime.in"
+ addFunc(ve, run::gen74, primPair(), "min", formal(primPen(), "p", false, false));
+#line 1754 "runtime.in"
+ addFunc(ve, run::gen75, primVoid(), "resetdefaultpen");
+#line 1760 "runtime.in"
+ addFunc(ve, run::gen76, primVoid(), "defaultpen", formal(primPen(), "p", false, false));
+#line 1765 "runtime.in"
+ addFunc(ve, run::gen77, primPen(), "defaultpen");
+#line 1770 "runtime.in"
+ addFunc(ve, run::gen78, primBoolean(), "invisible", formal(primPen(), "p", false, false));
+#line 1775 "runtime.in"
+ addFunc(ve, run::gen79, primPen(), "invisible");
+#line 1780 "runtime.in"
+ addFunc(ve, run::gen80, primPen(), "gray", formal(primPen(), "p", false, false));
+#line 1786 "runtime.in"
+ addFunc(ve, run::gen81, primPen(), "rgb", formal(primPen(), "p", false, false));
+#line 1792 "runtime.in"
+ addFunc(ve, run::gen82, primPen(), "cmyk", formal(primPen(), "p", false, false));
+#line 1798 "runtime.in"
+ addFunc(ve, run::gen83, primPen(), "interp", formal(primPen(), "a", false, false), formal(primPen(), "b", false, false), formal(primReal(), "t", false, false));
+#line 1803 "runtime.in"
+ addFunc(ve, run::gen84, primPen(), "rgb", formal(primReal(), "r", false, false), formal(primReal(), "g", false, false), formal(primReal(), "b", false, false));
+#line 1808 "runtime.in"
+ addFunc(ve, run::gen85, primPen(), "cmyk", formal(primReal(), "c", false, false), formal(primReal(), "m", false, false), formal(primReal(), "y", false, false), formal(primReal(), "k", false, false));
+#line 1813 "runtime.in"
+ addFunc(ve, run::gen86, primPen(), "gray", formal(primReal(), "gray", false, false));
+#line 1818 "runtime.in"
+ addFunc(ve, run::gen87, realArray(), "colors", formal(primPen(), "p", false, false));
+#line 1846 "runtime.in"
+ addFunc(ve, run::gen88, primString() , "colorspace", formal(primPen(), "p", false, false));
+#line 1853 "runtime.in"
+ addFunc(ve, run::gen89, primPen(), "pattern", formal(primString(), "s", false, false));
+#line 1858 "runtime.in"
+ addFunc(ve, run::gen90, primString() , "pattern", formal(primPen(), "p", false, false));
+#line 1863 "runtime.in"
+ addFunc(ve, run::gen91, primPen(), "fillrule", formal(primInt(), "n", false, false));
+#line 1868 "runtime.in"
+ addFunc(ve, run::gen92, primInt(), "fillrule", formal(primPen(), "p", false, false));
+#line 1873 "runtime.in"
+ addFunc(ve, run::gen93, primPen(), "opacity", formal(primReal(), "opacity", true, false), formal(primString() , "blend", true, false));
+#line 1883 "runtime.in"
+ addFunc(ve, run::gen94, primReal(), "opacity", formal(primPen(), "p", false, false));
+#line 1888 "runtime.in"
+ addFunc(ve, run::gen95, primString() , "blend", formal(primPen(), "p", false, false));
+#line 1893 "runtime.in"
+ addFunc(ve, run::gen96, primPen(), "linetype", formal(primString(), "s", false, false), formal(primReal(), "offset", true, false), formal(primBoolean(), "scale", true, false), formal(primBoolean(), "adjust", true, false));
+#line 1898 "runtime.in"
+ addFunc(ve, run::gen97, primString() , "linetype", formal(primPen(), "p", true, false));
+#line 1903 "runtime.in"
+ addFunc(ve, run::gen98, primReal(), "offset", formal(primPen(), "p", false, false));
+#line 1908 "runtime.in"
+ addFunc(ve, run::gen99, primBoolean(), "scale", formal(primPen(), "p", false, false));
+#line 1913 "runtime.in"
+ addFunc(ve, run::gen100, primBoolean(), "adjust", formal(primPen(), "p", false, false));
+#line 1918 "runtime.in"
+ addFunc(ve, run::gen101, primPen(), "adjust", formal(primPen(), "p", false, false), formal(primReal(), "arclength", false, false), formal(primBoolean(), "cyclic", false, false));
+#line 1923 "runtime.in"
+ addFunc(ve, run::gen102, primPen(), "linecap", formal(primInt(), "n", false, false));
+#line 1928 "runtime.in"
+ addFunc(ve, run::gen103, primInt(), "linecap", formal(primPen(), "p", true, false));
+#line 1933 "runtime.in"
+ addFunc(ve, run::gen104, primPen(), "linejoin", formal(primInt(), "n", false, false));
+#line 1938 "runtime.in"
+ addFunc(ve, run::gen105, primInt(), "linejoin", formal(primPen(), "p", true, false));
+#line 1943 "runtime.in"
+ addFunc(ve, run::gen106, primPen(), "miterlimit", formal(primReal(), "x", false, false));
+#line 1948 "runtime.in"
+ addFunc(ve, run::gen107, primReal(), "miterlimit", formal(primPen(), "p", true, false));
+#line 1953 "runtime.in"
+ addFunc(ve, run::gen108, primPen(), "linewidth", formal(primReal(), "x", false, false));
+#line 1958 "runtime.in"
+ addFunc(ve, run::gen109, primReal(), "linewidth", formal(primPen(), "p", true, false));
+#line 1963 "runtime.in"
+ addFunc(ve, run::gen110, primPen(), "fontcommand", formal(primString(), "s", false, false));
+#line 1968 "runtime.in"
+ addFunc(ve, run::gen111, primString() , "font", formal(primPen(), "p", true, false));
+#line 1973 "runtime.in"
+ addFunc(ve, run::gen112, primPen(), "fontsize", formal(primReal(), "size", false, false), formal(primReal(), "lineskip", false, false));
+#line 1979 "runtime.in"
+ addFunc(ve, run::gen113, primReal(), "fontsize", formal(primPen(), "p", true, false));
+#line 1984 "runtime.in"
+ addFunc(ve, run::gen114, primReal(), "lineskip", formal(primPen(), "p", true, false));
+#line 1989 "runtime.in"
+ addFunc(ve, run::gen115, primPen(), "overwrite", formal(primInt(), "n", false, false));
+#line 1995 "runtime.in"
+ addFunc(ve, run::gen116, primInt(), "overwrite", formal(primPen(), "p", true, false));
+#line 2000 "runtime.in"
+ addFunc(ve, run::gen117, primPen(), "basealign", formal(primInt(), "n", false, false));
+#line 2005 "runtime.in"
+ addFunc(ve, run::gen118, primInt(), "basealign", formal(primPen(), "p", true, false));
+#line 2010 "runtime.in"
+ addFunc(ve, run::gen119, primTransform(), "transform", formal(primPen(), "p", false, false));
+#line 2015 "runtime.in"
+ addFunc(ve, run::gen120, primPath(), "nib", formal(primPen(), "p", false, false));
+#line 2020 "runtime.in"
+ addFunc(ve, run::gen121, primPen(), "makepen", formal(primPath(), "p", false, false));
+#line 2025 "runtime.in"
+ addFunc(ve, run::gen122, primPen(), "colorless", formal(primPen(), "p", false, false));
+#line 2031 "runtime.in"
+ addFunc(ve, run::gen123, primBoolean(), "interactive");
+#line 2038 "runtime.in"
+ addFunc(ve, run::gen124, primBoolean(), "uptodate");
+#line 2043 "runtime.in"
+ addFunc(ve, run::gen125, primInt(), "system", formal(primString() , "s", false, false));
+#line 2053 "runtime.in"
+ addFunc(ve, run::gen126, primBoolean(), "view");
+#line 2058 "runtime.in"
+ addFunc(ve, run::gen127, primString() , "asydir");
+#line 2063 "runtime.in"
+ addFunc(ve, run::gen128, primString() , "locale", formal(primString() , "s", true, false));
+#line 2069 "runtime.in"
+ addFunc(ve, run::gen129, primVoid(), "abort", formal(primString() , "s", true, false));
+#line 2075 "runtime.in"
+ addFunc(ve, run::gen130, primVoid(), "exit");
+#line 2080 "runtime.in"
+ addFunc(ve, run::gen131, primVoid(), "assert", formal(primBoolean(), "b", false, false), formal(primString() , "s", true, false));
+#line 2091 "runtime.in"
+ addFunc(ve, run::gen132, primVoid(), "sleep", formal(primInt(), "seconds", false, false));
+#line 2097 "runtime.in"
+ addFunc(ve, run::gen133, primVoid(), "usleep", formal(primInt(), "microseconds", false, false));
+#line 2103 "runtime.in"
+ addFunc(ve, run::gen134, primVoid(), "_eval", formal(primString(), "s", false, false), formal(primBoolean(), "embedded", false, false), formal(primBoolean(), "interactivewrite", true, false));
+#line 2118 "runtime.in"
+ addFunc(ve, run::gen135, primVoid(), "_eval", formal(primCode(), "s", false, false), formal(primBoolean(), "embedded", false, false));
+#line 2136 "runtime.in"
+ addFunc(ve, run::gen136, primString() , "location");
+#line 2148 "runtime.in"
+ addFunc(ve, run::gen138, primString() , "cd", formal(primString() , "s", true, false));
+#line 2154 "runtime.in"
+ addFunc(ve, run::gen139, primVoid(), "list", formal(primString(), "s", false, false), formal(primBoolean(), "imports", true, false));
+#line 2171 "runtime.in"
+ addFunc(ve, run::gen141, primBoolean(), "==", formal(primPath(), "a", false, false), formal(primPath(), "b", false, false));
+#line 2176 "runtime.in"
+ addFunc(ve, run::gen142, primBoolean(), "!=", formal(primPath(), "a", false, false), formal(primPath(), "b", false, false));
+#line 2181 "runtime.in"
+ addFunc(ve, run::gen143, primPair(), "point", formal(primPath(), "p", false, false), formal(primInt(), "t", false, false));
+#line 2186 "runtime.in"
+ addFunc(ve, run::gen144, primPair(), "point", formal(primPath(), "p", false, false), formal(primReal(), "t", false, false));
+#line 2191 "runtime.in"
+ addFunc(ve, run::gen145, primPair(), "precontrol", formal(primPath(), "p", false, false), formal(primInt(), "t", false, false));
+#line 2196 "runtime.in"
+ addFunc(ve, run::gen146, primPair(), "precontrol", formal(primPath(), "p", false, false), formal(primReal(), "t", false, false));
+#line 2201 "runtime.in"
+ addFunc(ve, run::gen147, primPair(), "postcontrol", formal(primPath(), "p", false, false), formal(primInt(), "t", false, false));
+#line 2206 "runtime.in"
+ addFunc(ve, run::gen148, primPair(), "postcontrol", formal(primPath(), "p", false, false), formal(primReal(), "t", false, false));
+#line 2211 "runtime.in"
+ addFunc(ve, run::gen149, primPair(), "dir", formal(primPath(), "p", false, false), formal(primInt(), "t", false, false), formal(primInt(), "sign", true, false), formal(primBoolean(), "normalize", true, false));
+#line 2216 "runtime.in"
+ addFunc(ve, run::gen150, primPair(), "dir", formal(primPath(), "p", false, false), formal(primReal(), "t", false, false), formal(primBoolean(), "normalize", true, false));
+#line 2221 "runtime.in"
+ addFunc(ve, run::gen151, primPair(), "accel", formal(primPath(), "p", false, false), formal(primInt(), "t", false, false), formal(primInt(), "sign", true, false));
+#line 2226 "runtime.in"
+ addFunc(ve, run::gen152, primPair(), "accel", formal(primPath(), "p", false, false), formal(primReal(), "t", false, false));
+#line 2231 "runtime.in"
+ addFunc(ve, run::gen153, primReal(), "radius", formal(primPath(), "p", false, false), formal(primReal(), "t", false, false));
+#line 2243 "runtime.in"
+ addFunc(ve, run::gen154, primPath(), "reverse", formal(primPath(), "p", false, false));
+#line 2248 "runtime.in"
+ addFunc(ve, run::gen155, primPath(), "subpath", formal(primPath(), "p", false, false), formal(primInt(), "a", false, false), formal(primInt(), "b", false, false));
+#line 2253 "runtime.in"
+ addFunc(ve, run::gen156, primPath(), "subpath", formal(primPath(), "p", false, false), formal(primReal(), "a", false, false), formal(primReal(), "b", false, false));
+#line 2258 "runtime.in"
+ addFunc(ve, run::gen157, primPath(), "nurb", formal(primPair(), "z0", false, false), formal(primPair(), "z1", false, false), formal(primPair(), "z2", false, false), formal(primPair(), "z3", false, false), formal(primReal(), "w0", false, false), formal(primReal(), "w1", false, false), formal(primReal(), "w2", false, false), formal(primReal(), "w3", false, false), formal(primInt(), "m", false, false));
+#line 2264 "runtime.in"
+ addFunc(ve, run::gen158, primInt(), "length", formal(primPath(), "p", false, false));
+#line 2269 "runtime.in"
+ addFunc(ve, run::gen159, primBoolean(), "cyclic", formal(primPath(), "p", false, false));
+#line 2274 "runtime.in"
+ addFunc(ve, run::gen160, primBoolean(), "straight", formal(primPath(), "p", false, false), formal(primInt(), "t", false, false));
+#line 2279 "runtime.in"
+ addFunc(ve, run::gen161, primPath(), "unstraighten", formal(primPath(), "p", false, false));
+#line 2284 "runtime.in"
+ addFunc(ve, run::gen162, primBoolean(), "piecewisestraight", formal(primPath(), "p", false, false));
+#line 2289 "runtime.in"
+ addFunc(ve, run::gen163, primReal(), "arclength", formal(primPath(), "p", false, false));
+#line 2294 "runtime.in"
+ addFunc(ve, run::gen164, primReal(), "arctime", formal(primPath(), "p", false, false), formal(primReal(), "dval", false, false));
+#line 2299 "runtime.in"
+ addFunc(ve, run::gen165, primReal(), "dirtime", formal(primPath(), "p", false, false), formal(primPair(), "z", false, false));
+#line 2304 "runtime.in"
+ addFunc(ve, run::gen166, realArray(), "intersect", formal(primPath(), "p", false, false), formal(primPath(), "q", false, false), formal(primReal(), "fuzz", true, false));
+#line 2321 "runtime.in"
+ addFunc(ve, run::gen167, realArray2(), "intersections", formal(primPath(), "p", false, false), formal(primPath(), "q", false, false), formal(primReal(), "fuzz", true, false));
+#line 2352 "runtime.in"
+ addFunc(ve, run::gen168, realArray(), "intersections", formal(primPath(), "p", false, false), formal(primPair(), "a", false, true), formal(primPair(), "b", false, true), formal(primReal(), "fuzz", true, false));
+#line 2367 "runtime.in"
+ addFunc(ve, run::gen169, primPair(), "extension", formal(primPair(), "p", false, false), formal(primPair(), "q", false, false), formal(primPair(), "p", false, false), formal(primPair(), "q", false, false));
+#line 2378 "runtime.in"
+ addFunc(ve, run::gen170, primInt(), "size", formal(primPath(), "p", false, false));
+#line 2383 "runtime.in"
+ addFunc(ve, run::gen171, primPath(), "&", formal(primPath(), "p", false, false), formal(primPath(), "q", false, false));
+#line 2388 "runtime.in"
+ addFunc(ve, run::gen172, primPair(), "min", formal(primPath(), "p", false, false));
+#line 2393 "runtime.in"
+ addFunc(ve, run::gen173, primPair(), "max", formal(primPath(), "p", false, false));
+#line 2398 "runtime.in"
+ addFunc(ve, run::gen174, realArray(), "mintimes", formal(primPath(), "p", false, false));
+#line 2407 "runtime.in"
+ addFunc(ve, run::gen175, realArray(), "maxtimes", formal(primPath(), "p", false, false));
+#line 2416 "runtime.in"
+ addFunc(ve, run::gen176, primReal(), "relativedistance", formal(primReal(), "theta", false, false), formal(primReal(), "phi", false, false), formal(primReal(), "t", false, false), formal(primBoolean(), "atleast", false, false));
+#line 2421 "runtime.in"
+ addFunc(ve, run::gen177, primInt(), "windingnumber", formal(pathArray() , "p", false, false), formal(primPair(), "z", false, false));
+#line 2426 "runtime.in"
+ addFunc(ve, run::gen178, primBoolean(), "inside", formal(pathArray() , "g", false, true), formal(primPair(), "z", false, false), formal(primPen(), "fillrule", true, false));
+#line 2431 "runtime.in"
+ addFunc(ve, run::gen179, primBoolean(), "inside", formal(primPath(), "g", false, false), formal(primPair(), "z", false, false), formal(primPen(), "fillrule", true, false));
+#line 2436 "runtime.in"
+ addFunc(ve, run::gen180, primReal(), "side", formal(primPair(), "a", false, false), formal(primPair(), "b", false, false), formal(primPair(), "c", false, false));
+#line 2443 "runtime.in"
+ addFunc(ve, run::gen181, primReal(), "incircle", formal(primPair(), "a", false, false), formal(primPair(), "b", false, false), formal(primPair(), "c", false, false), formal(primPair(), "d", false, false));
+#line 2451 "runtime.in"
+ addFunc(ve, run::gen182, primPath3(), "path3", formal(tripleArray(), "pre", false, false), formal(tripleArray(), "point", false, false), formal(tripleArray(), "post", false, false), formal(boolArray(), "straight", false, false), formal(primBoolean(), "cyclic", false, false));
+#line 2476 "runtime.in"
+ addFunc(ve, run::gen184, primBoolean(), "==", formal(primPath3(), "a", false, false), formal(primPath3(), "b", false, false));
+#line 2481 "runtime.in"
+ addFunc(ve, run::gen185, primBoolean(), "!=", formal(primPath3(), "a", false, false), formal(primPath3(), "b", false, false));
+#line 2486 "runtime.in"
+ addFunc(ve, run::gen186, primTriple(), "point", formal(primPath3(), "p", false, false), formal(primInt(), "t", false, false));
+#line 2491 "runtime.in"
+ addFunc(ve, run::gen187, primTriple(), "point", formal(primPath3(), "p", false, false), formal(primReal(), "t", false, false));
+#line 2496 "runtime.in"
+ addFunc(ve, run::gen188, primTriple(), "precontrol", formal(primPath3(), "p", false, false), formal(primInt(), "t", false, false));
+#line 2501 "runtime.in"
+ addFunc(ve, run::gen189, primTriple(), "precontrol", formal(primPath3(), "p", false, false), formal(primReal(), "t", false, false));
+#line 2506 "runtime.in"
+ addFunc(ve, run::gen190, primTriple(), "postcontrol", formal(primPath3(), "p", false, false), formal(primInt(), "t", false, false));
+#line 2511 "runtime.in"
+ addFunc(ve, run::gen191, primTriple(), "postcontrol", formal(primPath3(), "p", false, false), formal(primReal(), "t", false, false));
+#line 2516 "runtime.in"
+ addFunc(ve, run::gen192, primTriple(), "dir", formal(primPath3(), "p", false, false), formal(primInt(), "t", false, false), formal(primInt(), "sign", true, false), formal(primBoolean(), "normalize", true, false));
+#line 2521 "runtime.in"
+ addFunc(ve, run::gen193, primTriple(), "dir", formal(primPath3(), "p", false, false), formal(primReal(), "t", false, false), formal(primBoolean(), "normalize", true, false));
+#line 2526 "runtime.in"
+ addFunc(ve, run::gen194, primTriple(), "accel", formal(primPath3(), "p", false, false), formal(primInt(), "t", false, false), formal(primInt(), "sign", true, false));
+#line 2531 "runtime.in"
+ addFunc(ve, run::gen195, primTriple(), "accel", formal(primPath3(), "p", false, false), formal(primReal(), "t", false, false));
+#line 2536 "runtime.in"
+ addFunc(ve, run::gen196, primReal(), "radius", formal(primPath3(), "p", false, false), formal(primReal(), "t", false, false));
+#line 2548 "runtime.in"
+ addFunc(ve, run::gen197, primReal(), "radius", formal(primTriple(), "z0", false, false), formal(primTriple(), "c0", false, false), formal(primTriple(), "c1", false, false), formal(primTriple(), "z1", false, false), formal(primReal(), "t", false, false));
+#line 2560 "runtime.in"
+ addFunc(ve, run::gen198, primPath3(), "reverse", formal(primPath3(), "p", false, false));
+#line 2565 "runtime.in"
+ addFunc(ve, run::gen199, primPath3(), "subpath", formal(primPath3(), "p", false, false), formal(primInt(), "a", false, false), formal(primInt(), "b", false, false));
+#line 2570 "runtime.in"
+ addFunc(ve, run::gen200, primPath3(), "subpath", formal(primPath3(), "p", false, false), formal(primReal(), "a", false, false), formal(primReal(), "b", false, false));
+#line 2575 "runtime.in"
+ addFunc(ve, run::gen201, primInt(), "length", formal(primPath3(), "p", false, false));
+#line 2580 "runtime.in"
+ addFunc(ve, run::gen202, primBoolean(), "cyclic", formal(primPath3(), "p", false, false));
+#line 2585 "runtime.in"
+ addFunc(ve, run::gen203, primBoolean(), "straight", formal(primPath3(), "p", false, false), formal(primInt(), "t", false, false));
+#line 2590 "runtime.in"
+ addFunc(ve, run::gen204, primTriple(), "perp", formal(primTriple(), "v", false, false), formal(primTriple(), "u", false, false));
+#line 2596 "runtime.in"
+ addFunc(ve, run::gen205, primReal(), "straightness", formal(primPath3(), "p", false, false), formal(primInt(), "t", false, false));
+#line 2607 "runtime.in"
+ addFunc(ve, run::gen206, primReal(), "straightness", formal(primTriple(), "z0", false, false), formal(primTriple(), "c0", false, false), formal(primTriple(), "c1", false, false), formal(primTriple(), "z1", false, false));
+#line 2615 "runtime.in"
+ addFunc(ve, run::gen207, primBoolean(), "piecewisestraight", formal(primPath3(), "p", false, false));
+#line 2620 "runtime.in"
+ addFunc(ve, run::gen208, primReal(), "arclength", formal(primPath3(), "p", false, false));
+#line 2625 "runtime.in"
+ addFunc(ve, run::gen209, primReal(), "arctime", formal(primPath3(), "p", false, false), formal(primReal(), "dval", false, false));
+#line 2630 "runtime.in"
+ addFunc(ve, run::gen210, realArray(), "intersect", formal(primPath3(), "p", false, false), formal(primPath3(), "q", false, false), formal(primReal(), "fuzz", true, false));
+#line 2648 "runtime.in"
+ addFunc(ve, run::gen211, realArray2(), "intersections", formal(primPath3(), "p", false, false), formal(primPath3(), "q", false, false), formal(primReal(), "fuzz", true, false));
+#line 2681 "runtime.in"
+ addFunc(ve, run::gen212, primInt(), "size", formal(primPath3(), "p", false, false));
+#line 2686 "runtime.in"
+ addFunc(ve, run::gen213, primPath3(), "&", formal(primPath3(), "p", false, false), formal(primPath3(), "q", false, false));
+#line 2691 "runtime.in"
+ addFunc(ve, run::gen214, primTriple(), "min", formal(primPath3(), "p", false, false));
+#line 2696 "runtime.in"
+ addFunc(ve, run::gen215, primTriple(), "max", formal(primPath3(), "p", false, false));
+#line 2701 "runtime.in"
+ addFunc(ve, run::gen216, realArray(), "mintimes", formal(primPath3(), "p", false, false));
+#line 2711 "runtime.in"
+ addFunc(ve, run::gen217, realArray(), "maxtimes", formal(primPath3(), "p", false, false));
+#line 2721 "runtime.in"
+ addFunc(ve, run::gen218, primPath3(), "*", formal(realArray2(), "t", false, false), formal(primPath3(), "g", false, false));
+#line 2776 "runtime.in"
+ addFunc(ve, run::gen223, primGuide(), "operator cast", formal(primCycleToken(), "tok", false, false));
+#line 2783 "runtime.in"
+ addFunc(ve, run::gen224, primGuide(), "operator spec", formal(primPair(), "z", false, false), formal(primInt(), "p", false, false));
+#line 2791 "runtime.in"
+ addFunc(ve, run::gen225, primCurlSpecifier(), "operator curl", formal(primReal(), "gamma", false, false), formal(primInt(), "p", false, false));
+#line 2807 "runtime.in"
+ addFunc(ve, run::gen228, primGuide(), "operator cast", formal(primCurlSpecifier(), "spec", false, false));
+#line 2812 "runtime.in"
+ addFunc(ve, run::gen229, primTensionSpecifier(), "operator tension", formal(primReal(), "tout", false, false), formal(primReal(), "tin", false, false), formal(primBoolean(), "atleast", false, false));
+#line 2832 "runtime.in"
+ addFunc(ve, run::gen233, primGuide(), "operator cast", formal(primTensionSpecifier(), "t", false, false));
+#line 2837 "runtime.in"
+ addFunc(ve, run::gen234, primGuide(), "operator controls", formal(primPair(), "zout", false, false), formal(primPair(), "zin", false, false));
+#line 2842 "runtime.in"
+ addFunc(ve, run::gen235, primInt(), "size", formal(primGuide(), "g", false, false));
+#line 2849 "runtime.in"
+ addFunc(ve, run::gen236, primInt(), "length", formal(primGuide(), "g", false, false));
+#line 2856 "runtime.in"
+ addFunc(ve, run::gen237, primBoolean(), "cyclic", formal(primGuide(), "g", false, false));
+#line 2863 "runtime.in"
+ addFunc(ve, run::gen238, primPair(), "point", formal(primGuide(), "g", false, false), formal(primInt(), "t", false, false));
+#line 2870 "runtime.in"
+ addFunc(ve, run::gen239, pairArray(), "dirSpecifier", formal(primGuide(), "g", false, false), formal(primInt(), "t", false, false));
+#line 2882 "runtime.in"
+ addFunc(ve, run::gen240, pairArray(), "controlSpecifier", formal(primGuide(), "g", false, false), formal(primInt(), "t", false, false));
+#line 2899 "runtime.in"
+ addFunc(ve, run::gen241, primTensionSpecifier(), "tensionSpecifier", formal(primGuide(), "g", false, false), formal(primInt(), "t", false, false));
+#line 2909 "runtime.in"
+ addFunc(ve, run::gen242, realArray(), "curlSpecifier", formal(primGuide(), "g", false, false), formal(primInt(), "t", false, false));
+#line 2923 "runtime.in"
+ addFunc(ve, run::gen243, primGuide(), "reverse", formal(primGuide(), "g", false, false));
+#line 2977 "runtime.in"
+ addFunc(ve, run::gen244, primVoid(), "_draw", formal(primPicture(), "f", false, false), formal(primPath3(), "g", false, false), formal(primPen(), "p", false, false));
+#line 2985 "runtime.in"
+ addFunc(ve, run::gen245, primVoid(), "draw", formal(primPicture(), "f", false, false), formal(tripleArray2(), "g", false, false), formal(primBoolean(), "straight", false, false), formal(penArray() , "p", false, false), formal(primReal(), "opacity", false, false), formal(primReal(), "shininess", false, false), formal(primReal(), "granularity", false, false), formal(primTriple(), "normal", false, false), formal(primBoolean(), "lighton", false, false), formal(penArray() , "colors", false, false));
+#line 2993 "runtime.in"
+ addFunc(ve, run::gen246, primTriple(), "min3", formal(primPicture(), "f", false, false));
+#line 2998 "runtime.in"
+ addFunc(ve, run::gen247, primTriple(), "max3", formal(primPicture(), "f", false, false));
+#line 3003 "runtime.in"
+ addFunc(ve, run::gen248, primPair(), "min", formal(primPicture(), "f", false, false), formal(realArray2(), "t", false, false));
+#line 3011 "runtime.in"
+ addFunc(ve, run::gen249, primPair(), "max", formal(primPicture(), "f", false, false), formal(realArray2(), "t", false, false));
+#line 3019 "runtime.in"
+ addFunc(ve, run::gen250, primPair(), "minratio", formal(primPicture(), "f", false, false));
+#line 3024 "runtime.in"
+ addFunc(ve, run::gen251, primPair(), "maxratio", formal(primPicture(), "f", false, false));
+#line 3029 "runtime.in"
+ addFunc(ve, run::gen252, primReal(), "minbound", formal(realArray(), "a", false, false), formal(primReal(), "b", false, false));
+#line 3037 "runtime.in"
+ addFunc(ve, run::gen253, primReal(), "maxbound", formal(realArray(), "a", false, false), formal(primReal(), "b", false, false));
+#line 3045 "runtime.in"
+ addFunc(ve, run::gen254, primPair(), "minbound", formal(tripleArray(), "a", false, false), formal(realArray2(), "t", false, false), formal(primPair(), "b", false, false));
+#line 3056 "runtime.in"
+ addFunc(ve, run::gen255, primPair(), "maxbound", formal(tripleArray(), "a", false, false), formal(realArray2(), "t", false, false), formal(primPair(), "b", false, false));
+#line 3067 "runtime.in"
+ addFunc(ve, run::gen256, primPair(), "max", formal(primPath3(), "g", false, false), formal(realArray2(), "t", false, false));
+#line 3075 "runtime.in"
+ addFunc(ve, run::gen257, primPair(), "min", formal(primPath3(), "g", false, false), formal(realArray2(), "t", false, false));
+#line 3083 "runtime.in"
+ addFunc(ve, run::gen258, primReal(), "change2", formal(tripleArray2(), "a", false, false));
+#line 3105 "runtime.in"
+ addFunc(ve, run::gen259, primBoolean(), "is3D", formal(primPicture(), "f", false, false));
+#line 3110 "runtime.in"
+ addFunc(ve, run::gen260, primPair(), "bezier", formal(primPair(), "a", false, false), formal(primPair(), "b", false, false), formal(primPair(), "c", false, false), formal(primPair(), "d", false, false), formal(primReal(), "t", false, false));
+#line 3117 "runtime.in"
+ addFunc(ve, run::gen261, primPair(), "bezierP", formal(primPair(), "a", false, false), formal(primPair(), "b", false, false), formal(primPair(), "c", false, false), formal(primPair(), "d", false, false), formal(primReal(), "t", false, false));
+#line 3122 "runtime.in"
+ addFunc(ve, run::gen262, primPair(), "bezierPP", formal(primPair(), "a", false, false), formal(primPair(), "b", false, false), formal(primPair(), "c", false, false), formal(primPair(), "d", false, false), formal(primReal(), "t", false, false));
+#line 3127 "runtime.in"
+ addFunc(ve, run::gen263, primPair(), "bezierPPP", formal(primPair(), "a", false, false), formal(primPair(), "b", false, false), formal(primPair(), "c", false, false), formal(primPair(), "d", false, false));
+#line 3132 "runtime.in"
+ addFunc(ve, run::gen264, primTriple(), "bezier", formal(primTriple(), "a", false, false), formal(primTriple(), "b", false, false), formal(primTriple(), "c", false, false), formal(primTriple(), "d", false, false), formal(primReal(), "t", false, false));
+#line 3139 "runtime.in"
+ addFunc(ve, run::gen265, primTriple(), "bezierP", formal(primTriple(), "a", false, false), formal(primTriple(), "b", false, false), formal(primTriple(), "c", false, false), formal(primTriple(), "d", false, false), formal(primReal(), "t", false, false));
+#line 3144 "runtime.in"
+ addFunc(ve, run::gen266, primTriple(), "bezierPP", formal(primTriple(), "a", false, false), formal(primTriple(), "b", false, false), formal(primTriple(), "c", false, false), formal(primTriple(), "d", false, false), formal(primReal(), "t", false, false));
+#line 3149 "runtime.in"
+ addFunc(ve, run::gen267, primTriple(), "bezierPPP", formal(primTriple(), "a", false, false), formal(primTriple(), "b", false, false), formal(primTriple(), "c", false, false), formal(primTriple(), "d", false, false));
+#line 3162 "runtime.in"
+ addFunc(ve, run::gen269, primInt(), "length", formal(primString(), "s", false, false));
+#line 3167 "runtime.in"
+ addFunc(ve, run::gen270, primInt(), "find", formal(primString(), "s", false, false), formal(primString() , "t", false, false), formal(primInt(), "pos", true, false));
+#line 3173 "runtime.in"
+ addFunc(ve, run::gen271, primInt(), "rfind", formal(primString(), "s", false, false), formal(primString() , "t", false, false), formal(primInt(), "pos", true, false));
+#line 3179 "runtime.in"
+ addFunc(ve, run::gen272, primString() , "reverse", formal(primString() , "s", false, false));
+#line 3185 "runtime.in"
+ addFunc(ve, run::gen273, primString() , "insert", formal(primString() , "s", false, false), formal(primInt(), "pos", false, false), formal(primString() , "t", false, false));
+#line 3192 "runtime.in"
+ addFunc(ve, run::gen274, primString() , "substr", formal(primString(), "s", false, false), formal(primInt(), "pos", false, false), formal(primInt(), "n", true, false));
+#line 3199 "runtime.in"
+ addFunc(ve, run::gen275, primString() , "erase", formal(primString() , "s", false, false), formal(primInt(), "pos", false, false), formal(primInt(), "n", false, false));
+#line 3206 "runtime.in"
+ addFunc(ve, run::gen276, primString() , "downcase", formal(primString() , "s", false, false));
+#line 3212 "runtime.in"
+ addFunc(ve, run::gen277, primString() , "upcase", formal(primString() , "s", false, false));
+#line 3218 "runtime.in"
+ addFunc(ve, run::gen278, primString() , "replace", formal(primString(), "s", false, false), formal(stringArray2(), "translate", false, false));
+#line 3245 "runtime.in"
+ addFunc(ve, run::gen279, primString() , "format", formal(primString(), "format", false, false), formal(primInt(), "x", false, false));
+#line 3260 "runtime.in"
+ addFunc(ve, run::gen280, primString() , "format", formal(primString(), "format", false, false), formal(primReal(), "x", false, false), formal(primString() , "locale", true, false));
+#line 3378 "runtime.in"
+ addFunc(ve, run::gen281, primInt(), "hex", formal(primString() , "s", false, false));
+#line 3389 "runtime.in"
+ addFunc(ve, run::gen282, primString() , "string", formal(primInt(), "x", false, false));
+#line 3396 "runtime.in"
+ addFunc(ve, run::gen283, primString() , "string", formal(primReal(), "x", false, false), formal(primInt(), "digits", true, false));
+#line 3404 "runtime.in"
+ addFunc(ve, run::gen284, primString() , "time", formal(primString() , "format", true, false));
+#line 3415 "runtime.in"
+ addFunc(ve, run::gen285, primString() , "time", formal(primInt(), "seconds", false, false), formal(primString() , "format", true, false));
+#line 3428 "runtime.in"
+ addFunc(ve, run::gen286, primInt(), "seconds", formal(primString() , "t", true, false), formal(primString() , "format", true, false));
+#line 3440 "runtime.in"
+ addFunc(ve, run::gen287, realArray(), "_cputime");
+#line 3454 "runtime.in"
+ addFunc(ve, run::gen288, primReal(), "^", formal(primReal(), "x", false, false), formal(primInt(), "y", false, false));
+#line 3462 "runtime.in"
+ addFunc(ve, run::gen289, primPair(), "^", formal(primPair(), "z", false, false), formal(primInt(), "y", false, false));
+#line 3467 "runtime.in"
+ addFunc(ve, run::gen290, primInt(), "quotient", formal(primInt(), "x", false, false), formal(primInt(), "y", false, false));
+#line 3475 "runtime.in"
+ addFunc(ve, run::gen291, primInt(), "abs", formal(primInt(), "x", false, false));
+#line 3480 "runtime.in"
+ addFunc(ve, run::gen292, primInt(), "sgn", formal(primReal(), "x", false, false));
+#line 3485 "runtime.in"
+ addFunc(ve, run::gen293, primInt(), "rand");
+#line 3490 "runtime.in"
+ addFunc(ve, run::gen294, primVoid(), "srand", formal(primInt(), "seed", false, false));
+#line 3495 "runtime.in"
+ addFunc(ve, run::gen295, primReal(), "unitrand");
+#line 3501 "runtime.in"
+ addFunc(ve, run::gen296, primInt(), "ceil", formal(primReal(), "x", false, false));
+#line 3506 "runtime.in"
+ addFunc(ve, run::gen297, primInt(), "floor", formal(primReal(), "x", false, false));
+#line 3511 "runtime.in"
+ addFunc(ve, run::gen298, primInt(), "round", formal(primReal(), "x", false, false));
+#line 3517 "runtime.in"
+ addFunc(ve, run::gen299, primInt(), "Ceil", formal(primReal(), "x", false, false));
+#line 3522 "runtime.in"
+ addFunc(ve, run::gen300, primInt(), "Floor", formal(primReal(), "x", false, false));
+#line 3527 "runtime.in"
+ addFunc(ve, run::gen301, primInt(), "Round", formal(primReal(), "x", false, false));
+#line 3532 "runtime.in"
+ addFunc(ve, run::gen302, primReal(), "fmod", formal(primReal(), "x", false, false), formal(primReal(), "y", false, false));
+#line 3538 "runtime.in"
+ addFunc(ve, run::gen303, primReal(), "atan2", formal(primReal(), "y", false, false), formal(primReal(), "x", false, false));
+#line 3543 "runtime.in"
+ addFunc(ve, run::gen304, primReal(), "hypot", formal(primReal(), "x", false, false), formal(primReal(), "y", false, false));
+#line 3548 "runtime.in"
+ addFunc(ve, run::gen305, primReal(), "remainder", formal(primReal(), "x", false, false), formal(primReal(), "y", false, false));
+#line 3553 "runtime.in"
+ addFunc(ve, run::gen306, primReal(), "J", formal(primInt(), "n", false, false), formal(primReal(), "x", false, false));
+#line 3558 "runtime.in"
+ addFunc(ve, run::gen307, primReal(), "Y", formal(primInt(), "n", false, false), formal(primReal(), "x", false, false));
+#line 3563 "runtime.in"
+ addFunc(ve, run::gen308, primReal(), "erf", formal(primReal(), "x", false, false));
+#line 3568 "runtime.in"
+ addFunc(ve, run::gen309, primReal(), "erfc", formal(primReal(), "x", false, false));
+#line 3573 "runtime.in"
+ addFunc(ve, run::gen310, primInt(), "factorial", formal(primInt(), "n", false, false));
+#line 3578 "runtime.in"
+ addFunc(ve, run::gen311, primInt(), "choose", formal(primInt(), "n", false, false), formal(primInt(), "k", false, false));
+#line 3589 "runtime.in"
+ addFunc(ve, run::gen312, primReal(), "gamma", formal(primReal(), "x", false, false));
+#line 3599 "runtime.in"
+ addFunc(ve, run::gen313, primPair(), "gamma", formal(primPair(), "z", false, true));
+#line 3605 "runtime.in"
+ addFunc(ve, run::gen314, realArray(), "quadraticroots", formal(primReal(), "a", false, false), formal(primReal(), "b", false, false), formal(primReal(), "c", false, false));
+#line 3614 "runtime.in"
+ addFunc(ve, run::gen315, pairArray(), "quadraticroots", formal(primPair(), "a", false, true), formal(primPair(), "b", false, true), formal(primPair(), "c", false, true));
+#line 3623 "runtime.in"
+ addFunc(ve, run::gen316, realArray(), "cubicroots", formal(primReal(), "a", false, false), formal(primReal(), "b", false, false), formal(primReal(), "c", false, false), formal(primReal(), "d", false, false));
+#line 3633 "runtime.in"
+ addFunc(ve, run::gen317, primBoolean(), "==", formal(primTransform(), "a", false, false), formal(primTransform(), "b", false, false));
+#line 3641 "runtime.in"
+ addFunc(ve, run::gen318, primBoolean(), "!=", formal(primTransform(), "a", false, false), formal(primTransform(), "b", false, false));
+#line 3646 "runtime.in"
+ addFunc(ve, run::gen319, primTransform(), "+", formal(primTransform(), "a", false, false), formal(primTransform(), "b", false, false));
+#line 3651 "runtime.in"
+ addFunc(ve, run::gen320, primTransform(), "*", formal(primTransform(), "a", false, false), formal(primTransform(), "b", false, false));
+#line 3656 "runtime.in"
+ addFunc(ve, run::gen321, primPair(), "*", formal(primTransform(), "t", false, false), formal(primPair(), "z", false, false));
+#line 3661 "runtime.in"
+ addFunc(ve, run::gen322, primPath(), "*", formal(primTransform(), "t", false, false), formal(primPath(), "g", false, false));
+#line 3666 "runtime.in"
+ addFunc(ve, run::gen323, primPen(), "*", formal(primTransform(), "t", false, false), formal(primPen(), "p", false, false));
+#line 3671 "runtime.in"
+ addFunc(ve, run::gen324, primPicture(), "*", formal(primTransform(), "t", false, false), formal(primPicture(), "f", false, false));
+#line 3676 "runtime.in"
+ addFunc(ve, run::gen325, primPicture(), "*", formal(realArray2(), "t", false, false), formal(primPicture(), "f", false, false));
+#line 3681 "runtime.in"
+ addFunc(ve, run::gen326, primTransform(), "^", formal(primTransform(), "t", false, false), formal(primInt(), "n", false, false));
+#line 3728 "runtime.in"
+ addFunc(ve, run::gen334, primTransform(), "shift", formal(primTransform(), "t", false, false));
+#line 3733 "runtime.in"
+ addFunc(ve, run::gen335, primTransform(), "shiftless", formal(primTransform(), "t", false, false));
+#line 3738 "runtime.in"
+ addFunc(ve, run::transformIdentity, primTransform(), "identity");
+#line 3743 "runtime.in"
+ addFunc(ve, run::gen337, primTransform(), "inverse", formal(primTransform(), "t", false, false));
+#line 3748 "runtime.in"
+ addFunc(ve, run::gen338, primTransform(), "shift", formal(primPair(), "z", false, false));
+#line 3753 "runtime.in"
+ addFunc(ve, run::gen339, primTransform(), "shift", formal(primReal(), "x", false, false), formal(primReal(), "y", false, false));
+#line 3758 "runtime.in"
+ addFunc(ve, run::gen340, primTransform(), "xscale", formal(primReal(), "x", false, false));
+#line 3763 "runtime.in"
+ addFunc(ve, run::gen341, primTransform(), "yscale", formal(primReal(), "y", false, false));
+#line 3768 "runtime.in"
+ addFunc(ve, run::gen342, primTransform(), "scale", formal(primReal(), "x", false, false));
+#line 3773 "runtime.in"
+ addFunc(ve, run::gen343, primTransform(), "scale", formal(primReal(), "x", false, false), formal(primReal(), "y", false, false));
+#line 3778 "runtime.in"
+ addFunc(ve, run::gen344, primTransform(), "slant", formal(primReal(), "s", false, false));
+#line 3783 "runtime.in"
+ addFunc(ve, run::gen345, primTransform(), "rotate", formal(primReal(), "angle", false, false), formal(primPair(), "z", true, false));
+#line 3788 "runtime.in"
+ addFunc(ve, run::gen346, primTransform(), "reflect", formal(primPair(), "a", false, false), formal(primPair(), "b", false, false));
+#line 3811 "runtime.in"
+ addFunc(ve, run::pairXPart, primReal(), "xpart", formal(primPair(), "z", false, false));
+#line 3816 "runtime.in"
+ addFunc(ve, run::pairYPart, primReal(), "ypart", formal(primPair(), "z", false, false));
+#line 3821 "runtime.in"
+ addFunc(ve, run::gen352, primReal(), "length", formal(primPair(), "z", false, false));
+#line 3826 "runtime.in"
+ addFunc(ve, run::gen353, primReal(), "abs", formal(primPair(), "z", false, false));
+#line 3831 "runtime.in"
+ addFunc(ve, run::gen354, primPair(), "sqrt", formal(primPair(), "z", false, true));
+#line 3836 "runtime.in"
+ addFunc(ve, run::gen355, primReal(), "angle", formal(primPair(), "z", false, false), formal(primBoolean(), "warn", true, false));
+#line 3843 "runtime.in"
+ addFunc(ve, run::gen356, primReal(), "degrees", formal(primPair(), "z", false, false), formal(primBoolean(), "warn", true, false));
+#line 3850 "runtime.in"
+ addFunc(ve, run::gen357, primReal(), "radians", formal(primReal(), "degrees", false, false));
+#line 3856 "runtime.in"
+ addFunc(ve, run::gen358, primReal(), "degrees", formal(primReal(), "radians", false, false));
+#line 3862 "runtime.in"
+ addFunc(ve, run::gen359, primReal(), "Degrees", formal(primReal(), "radians", false, false));
+#line 3868 "runtime.in"
+ addFunc(ve, run::gen360, primReal(), "Sin", formal(primReal(), "deg", false, false));
+#line 3873 "runtime.in"
+ addFunc(ve, run::gen361, primReal(), "Cos", formal(primReal(), "deg", false, false));
+#line 3878 "runtime.in"
+ addFunc(ve, run::gen362, primReal(), "Tan", formal(primReal(), "deg", false, false));
+#line 3883 "runtime.in"
+ addFunc(ve, run::gen363, primReal(), "aSin", formal(primReal(), "x", false, false));
+#line 3888 "runtime.in"
+ addFunc(ve, run::gen364, primReal(), "aCos", formal(primReal(), "x", false, false));
+#line 3893 "runtime.in"
+ addFunc(ve, run::gen365, primReal(), "aTan", formal(primReal(), "x", false, false));
+#line 3898 "runtime.in"
+ addFunc(ve, run::gen366, primPair(), "unit", formal(primPair(), "z", false, false));
+#line 3903 "runtime.in"
+ addFunc(ve, run::gen367, primPair(), "dir", formal(primReal(), "degrees", false, false));
+#line 3908 "runtime.in"
+ addFunc(ve, run::gen368, primPair(), "dir", formal(primPair(), "z", false, true));
+#line 3913 "runtime.in"
+ addFunc(ve, run::gen369, primPair(), "expi", formal(primReal(), "angle", false, false));
+#line 3918 "runtime.in"
+ addFunc(ve, run::gen370, primPair(), "exp", formal(primPair(), "z", false, true));
+#line 3923 "runtime.in"
+ addFunc(ve, run::gen371, primPair(), "log", formal(primPair(), "z", false, true));
+#line 3928 "runtime.in"
+ addFunc(ve, run::gen372, primPair(), "sin", formal(primPair(), "z", false, true));
+#line 3933 "runtime.in"
+ addFunc(ve, run::gen373, primPair(), "cos", formal(primPair(), "z", false, true));
+#line 3938 "runtime.in"
+ addFunc(ve, run::gen374, primPair(), "conj", formal(primPair(), "z", false, false));
+#line 3943 "runtime.in"
+ addFunc(ve, run::gen375, primPair(), "realmult", formal(primPair(), "z", false, false), formal(primPair(), "w", false, false));
+#line 3948 "runtime.in"
+ addFunc(ve, run::gen376, primTriple(), "realmult", formal(primTriple(), "u", false, false), formal(primTriple(), "v", false, false));
+#line 3953 "runtime.in"
+ addFunc(ve, run::gen377, primReal(), "dot", formal(primPair(), "z", false, true), formal(primPair(), "w", false, true));
+#line 3973 "runtime.in"
+ addFunc(ve, run::tripleXPart, primReal(), "xpart", formal(primTriple(), "v", false, false));
+#line 3978 "runtime.in"
+ addFunc(ve, run::tripleYPart, primReal(), "ypart", formal(primTriple(), "v", false, false));
+#line 3983 "runtime.in"
+ addFunc(ve, run::tripleZPart, primReal(), "zpart", formal(primTriple(), "v", false, false));
+#line 3988 "runtime.in"
+ addFunc(ve, run::gen383, primTriple(), "*", formal(primReal(), "x", false, false), formal(primTriple(), "v", false, false));
+#line 3993 "runtime.in"
+ addFunc(ve, run::gen384, primTriple(), "*", formal(primTriple(), "v", false, false), formal(primReal(), "x", false, false));
+#line 3998 "runtime.in"
+ addFunc(ve, run::gen385, primTriple(), "/", formal(primTriple(), "v", false, false), formal(primReal(), "x", false, false));
+#line 4003 "runtime.in"
+ addFunc(ve, run::gen386, primReal(), "length", formal(primTriple(), "v", false, false));
+#line 4008 "runtime.in"
+ addFunc(ve, run::gen387, primReal(), "abs", formal(primTriple(), "v", false, false));
+#line 4013 "runtime.in"
+ addFunc(ve, run::gen388, primReal(), "polar", formal(primTriple(), "v", false, false));
+#line 4018 "runtime.in"
+ addFunc(ve, run::gen389, primReal(), "azimuth", formal(primTriple(), "v", false, false));
+#line 4023 "runtime.in"
+ addFunc(ve, run::gen390, primReal(), "colatitude", formal(primTriple(), "v", false, false));
+#line 4028 "runtime.in"
+ addFunc(ve, run::gen391, primReal(), "latitude", formal(primTriple(), "v", false, false));
+#line 4033 "runtime.in"
+ addFunc(ve, run::gen392, primReal(), "longitude", formal(primTriple(), "v", false, false), formal(primBoolean(), "warn", true, false));
+#line 4040 "runtime.in"
+ addFunc(ve, run::gen393, primTriple(), "unit", formal(primTriple(), "v", false, false));
+#line 4045 "runtime.in"
+ addFunc(ve, run::gen394, primReal(), "dot", formal(primTriple(), "u", false, false), formal(primTriple(), "v", false, false));
+#line 4050 "runtime.in"
+ addFunc(ve, run::gen395, primTriple(), "cross", formal(primTriple(), "u", false, false), formal(primTriple(), "v", false, false));
+#line 4055 "runtime.in"
+ addFunc(ve, run::gen396, primTriple(), "expi", formal(primReal(), "polar", false, false), formal(primReal(), "azimuth", false, false));
+#line 4060 "runtime.in"
+ addFunc(ve, run::gen397, primTriple(), "dir", formal(primReal(), "colatitude", false, false), formal(primReal(), "longitude", false, false));
+#line 4065 "runtime.in"
+ addFunc(ve, run::gen398, primVoid(), "atupdate", formal(voidFunction(), "f", false, false));
+#line 4073 "runtime.in"
+ addFunc(ve, run::gen399, voidFunction(), "atupdate");
+#line 4078 "runtime.in"
+ addFunc(ve, run::gen400, primVoid(), "atexit", formal(voidFunction(), "f", false, false));
+#line 4083 "runtime.in"
+ addFunc(ve, run::gen401, voidFunction(), "atexit");
+#line 4088 "runtime.in"
+ addFunc(ve, run::gen402, primVoid(), "atbreakpoint", formal(breakpointFunction(), "f", false, false));
+#line 4093 "runtime.in"
+ addFunc(ve, run::gen403, primVoid(), "breakpoint", formal(primCode(), "s", true, false));
+#line 4098 "runtime.in"
+ addFunc(ve, run::gen404, primString() , "locatefile", formal(primString() , "file", false, false));
+#line 4103 "runtime.in"
+ addFunc(ve, run::gen405, primVoid(), "stop", formal(primString() , "file", false, false), formal(primInt(), "line", false, false), formal(primCode(), "s", true, false));
+#line 4111 "runtime.in"
+ addFunc(ve, run::gen406, primVoid(), "breakpoints");
+#line 4117 "runtime.in"
+ addFunc(ve, run::gen407, primVoid(), "clear", formal(primString() , "file", false, false), formal(primInt(), "line", false, false));
+#line 4123 "runtime.in"
+ addFunc(ve, run::gen408, primVoid(), "clear");
+#line 4128 "runtime.in"
+ addFunc(ve, run::gen409, primString() , "stripdirectory", formal(primString(), "s", false, false));
+#line 4134 "runtime.in"
+ addFunc(ve, run::gen410, primString() , "stripfile", formal(primString(), "s", false, false));
+#line 4140 "runtime.in"
+ addFunc(ve, run::gen411, primString() , "stripextension", formal(primString(), "s", false, false));
+#line 4146 "runtime.in"
+ addFunc(ve, run::gen412, primInt(), "convert", formal(primString() , "args", true, false), formal(primString() , "file", true, false), formal(primString() , "format", true, false));
+#line 4164 "runtime.in"
+ addFunc(ve, run::gen413, primInt(), "animate", formal(primString() , "args", true, false), formal(primString() , "file", true, false), formal(primString() , "format", true, false));
+#line 4180 "runtime.in"
+ addFunc(ve, run::gen414, primInt(), "delete", formal(primString(), "s", false, false));
+#line 4190 "runtime.in"
+ addFunc(ve, run::gen415, primInt(), "rename", formal(primString(), "from", false, false), formal(primString(), "to", false, false));
+#line 4489 "runtime.in"
+ addFunc(ve, run::gen446, IntArray(), "complement", formal(IntArray(), "a", false, false), formal(primInt(), "n", false, false));
+#line 4521 "runtime.in"
+ addFunc(ve, run::gen448, IntArray(), "sequence", formal(primInt(), "n", false, false));
+#line 4554 "runtime.in"
+ addFunc(ve, run::gen451, primBoolean(), "all", formal(boolArray(), "a", false, false));
+#line 4563 "runtime.in"
+ addFunc(ve, run::gen452, boolArray(), "!", formal(boolArray(), "a", false, false));
+#line 4572 "runtime.in"
+ addFunc(ve, run::gen453, primInt(), "sum", formal(boolArray(), "a", false, false));
+#line 4735 "runtime.in"
+ addFunc(ve, run::gen460, primInt(), "find", formal(boolArray(), "a", false, false), formal(primInt(), "n", true, false));
+#line 4755 "runtime.in"
+ addFunc(ve, run::gen461, primBoolean(), "==", formal(realArray2(), "a", false, false), formal(realArray2(), "b", false, false));
+#line 4800 "runtime.in"
+ addFunc(ve, run::gen463, realArray2(), "identity", formal(primInt(), "n", false, false));
+#line 4823 "runtime.in"
+ addFunc(ve, run::gen465, realArray2(), "inverse", formal(realArray2(), "a", false, false));
+#line 4915 "runtime.in"
+ addFunc(ve, run::gen466, realArray(), "solve", formal(realArray2(), "a", false, false), formal(realArray(), "b", false, false), formal(primBoolean(), "warn", true, false));
+#line 4966 "runtime.in"
+ addFunc(ve, run::gen467, realArray2(), "solve", formal(realArray2(), "a", false, false), formal(realArray2(), "b", false, false), formal(primBoolean(), "warn", true, false));
+#line 5030 "runtime.in"
+ addFunc(ve, run::gen468, primReal(), "determinant", formal(realArray2(), "a", false, false));
+#line 5046 "runtime.in"
+ addFunc(ve, run::gen469, realArray(), "*", formal(realArray2(), "a", false, false), formal(realArray(), "b", false, false));
+#line 5064 "runtime.in"
+ addFunc(ve, run::gen470, realArray2(), "*", formal(realArray2(), "a", false, false), formal(realArray2(), "b", false, false));
+#line 5099 "runtime.in"
+ addFunc(ve, run::gen471, primTriple(), "*", formal(realArray2(), "t", false, false), formal(primTriple(), "v", false, false));
+#line 5104 "runtime.in"
+ addFunc(ve, run::gen472, primPair(), "project", formal(primTriple(), "v", false, false), formal(realArray2(), "t", false, false));
+#line 5129 "runtime.in"
+ addFunc(ve, run::gen473, primReal(), "dot", formal(realArray(), "a", false, false), formal(realArray(), "b", false, false));
+#line 5139 "runtime.in"
+ addFunc(ve, run::gen474, realArray(), "tridiagonal", formal(realArray(), "a", false, false), formal(realArray(), "b", false, false), formal(realArray(), "c", false, false), formal(realArray(), "f", false, false));
+#line 5243 "runtime.in"
+ addFunc(ve, run::gen475, primReal(), "newton", formal(primInt(), "iterations", true, false), formal(realRealFunction(), "f", false, false), formal(realRealFunction(), "fprime", false, false), formal(primReal(), "x", false, false), formal(primBoolean(), "verbose", true, false));
+#line 5290 "runtime.in"
+ addFunc(ve, run::gen476, primReal(), "newton", formal(primInt(), "iterations", true, false), formal(realRealFunction(), "f", false, false), formal(realRealFunction(), "fprime", false, false), formal(primReal(), "x1", false, false), formal(primReal(), "x2", false, false), formal(primBoolean(), "verbose", true, false));
+#line 5372 "runtime.in"
+ addFunc(ve, run::gen477, primReal(), "simpson", formal(realRealFunction(), "f", false, false), formal(primReal(), "a", false, false), formal(primReal(), "b", false, false), formal(primReal(), "acc", true, false), formal(primReal(), "dxmax", true, false));
+#line 5414 "runtime.in"
+ addFunc(ve, run::gen479, IntArray2(), "triangulate", formal(pairArray(), "z", false, false));
+#line 5449 "runtime.in"
+ addFunc(ve, run::gen480, primBoolean(), "==", formal(primFile(), "a", false, false), formal(primFile(), "b", false, false));
+#line 5457 "runtime.in"
+ addFunc(ve, run::gen481, primBoolean(), "!=", formal(primFile(), "a", false, false), formal(primFile(), "b", false, false));
+#line 5467 "runtime.in"
+ addFunc(ve, run::gen483, primFile(), "input", formal(primString() , "name", false, false), formal(primBoolean(), "check", true, false), formal(primString() , "comment", true, false));
+#line 5475 "runtime.in"
+ addFunc(ve, run::gen484, primFile(), "output", formal(primString() , "name", false, false), formal(primBoolean(), "update", true, false), formal(primString() , "comment", true, false));
+#line 5487 "runtime.in"
+ addFunc(ve, run::gen485, primFile(), "xinput", formal(primString() , "name", false, false), formal(primBoolean(), "check", true, false));
+#line 5501 "runtime.in"
+ addFunc(ve, run::gen486, primFile(), "xoutput", formal(primString() , "name", false, false), formal(primBoolean(), "update", true, false));
+#line 5519 "runtime.in"
+ addFunc(ve, run::gen487, primFile(), "binput", formal(primString() , "name", false, false), formal(primBoolean(), "check", true, false));
+#line 5526 "runtime.in"
+ addFunc(ve, run::gen488, primFile(), "boutput", formal(primString() , "name", false, false), formal(primBoolean(), "update", true, false));
+#line 5536 "runtime.in"
+ addFunc(ve, run::gen489, primBoolean(), "eof", formal(primFile(), "file", false, false));
+#line 5541 "runtime.in"
+ addFunc(ve, run::gen490, primBoolean(), "eol", formal(primFile(), "file", false, false));
+#line 5546 "runtime.in"
+ addFunc(ve, run::gen491, primBoolean(), "error", formal(primFile(), "file", false, false));
+#line 5551 "runtime.in"
+ addFunc(ve, run::gen492, primVoid(), "clear", formal(primFile(), "file", false, false));
+#line 5556 "runtime.in"
+ addFunc(ve, run::gen493, primVoid(), "close", formal(primFile(), "file", false, false));
+#line 5561 "runtime.in"
+ addFunc(ve, run::gen494, primInt(), "precision", formal(primFile(), "file", true, false), formal(primInt(), "digits", true, false));
+#line 5567 "runtime.in"
+ addFunc(ve, run::gen495, primVoid(), "flush", formal(primFile(), "file", false, false));
+#line 5572 "runtime.in"
+ addFunc(ve, run::gen496, primString() , "getc", formal(primFile(), "file", false, false));
+#line 5581 "runtime.in"
+ addFunc(ve, run::gen497, primInt(), "tell", formal(primFile(), "file", false, false));
+#line 5586 "runtime.in"
+ addFunc(ve, run::gen498, primVoid(), "seek", formal(primFile(), "file", false, false), formal(primInt(), "pos", false, false));
+#line 5591 "runtime.in"
+ addFunc(ve, run::gen499, primVoid(), "seekeof", formal(primFile(), "file", false, false));
+#line 5596 "runtime.in"
+ addFunc(ve, run::gen500, primFile(), "dimension", formal(primFile(), "file", false, false), formal(primInt(), "nx", false, false));
+#line 5603 "runtime.in"
+ addFunc(ve, run::gen501, primFile(), "dimension", formal(primFile(), "file", false, false), formal(primInt(), "nx", false, false), formal(primInt(), "ny", false, false));
+#line 5609 "runtime.in"
+ addFunc(ve, run::gen502, primFile(), "dimension", formal(primFile(), "file", false, false), formal(primInt(), "nx", false, false), formal(primInt(), "ny", false, false), formal(primInt(), "nz", false, false));
+#line 5615 "runtime.in"
+ addFunc(ve, run::gen503, primFile(), "csv", formal(primFile(), "file", false, false), formal(primBoolean(), "b", true, false));
+#line 5622 "runtime.in"
+ addFunc(ve, run::gen504, primFile(), "word", formal(primFile(), "file", false, false), formal(primBoolean(), "b", true, false));
+#line 5629 "runtime.in"
+ addFunc(ve, run::gen505, primFile(), "line", formal(primFile(), "file", false, false), formal(primBoolean(), "b", true, false));
+#line 5636 "runtime.in"
+ addFunc(ve, run::gen506, primFile(), "single", formal(primFile(), "file", false, false), formal(primBoolean(), "b", true, false));
+#line 5644 "runtime.in"
+ addFunc(ve, run::gen507, primFile(), "single", formal(primFile(), "file", false, false), formal(primReal(), "x", false, false), formal(primBoolean(), "b", true, false));
+#line 5652 "runtime.in"
+ addFunc(ve, run::gen508, primFile(), "single", formal(primFile(), "file", false, false), formal(primInt(), "x", false, false), formal(primBoolean(), "b", true, false));
+#line 5660 "runtime.in"
+ addFunc(ve, run::gen509, primFile(), "read1", formal(primFile(), "file", false, false));
+#line 5667 "runtime.in"
+ addFunc(ve, run::gen510, primFile(), "read2", formal(primFile(), "file", false, false));
+#line 5674 "runtime.in"
+ addFunc(ve, run::gen511, primFile(), "read3", formal(primFile(), "file", false, false));
+#line 5681 "runtime.in"
+ addFunc(ve, run::gen512, stringArray(), "history", formal(primString() , "name", false, false), formal(primInt(), "n", true, false));
+#line 5714 "runtime.in"
+ addFunc(ve, run::gen513, stringArray(), "history", formal(primInt(), "n", true, false));
+#line 5725 "runtime.in"
+ addFunc(ve, run::gen514, primString() , "readline", formal(primString() , "prompt", true, false), formal(primString() , "name", true, false), formal(primBoolean(), "tabcompletion", true, false));
+#line 5769 "runtime.in"
+ addFunc(ve, run::gen515, primVoid(), "saveline", formal(primString() , "name", false, false), formal(primString() , "value", false, false), formal(primBoolean(), "store", true, false));
+#line 5799 "runtime.in"
+ addFunc(ve, run::gen516, primVoid(), "generate_random_backtrace");
+#line 5808 "runtime.in"
+ addFunc(ve, run::gen517, primVoid(), "print_random_addresses", formal(primInt(), "n", true, false));
+}
+
+} // namespace trans
diff --git a/Build/source/utils/asymptote/runtime.h b/Build/source/utils/asymptote/runtime.h
new file mode 100644
index 00000000000..f05fcb2255f
--- /dev/null
+++ b/Build/source/utils/asymptote/runtime.h
@@ -0,0 +1,100 @@
+/***** Autogenerated from runtime.in; changes will be overwritten *****/
+
+#ifndef RUNTIME_H
+#define RUNTIME_H
+
+namespace run {
+void IntZero(vm::stack *);
+void realZero(vm::stack *);
+void boolFalse(vm::stack *);
+void pushNullArray(vm::stack *);
+void pushNullRecord(vm::stack *);
+void pushNullFunction(vm::stack *);
+void pushDefault(vm::stack *);
+void isDefault(vm::stack *);
+void boolMemEq(vm::stack *);
+void boolMemNeq(vm::stack *);
+void boolFuncEq(vm::stack *);
+void boolFuncNeq(vm::stack *);
+void pairToGuide(vm::stack *);
+void pathToGuide(vm::stack *);
+void guideToPath(vm::stack *);
+void newPicture(vm::stack *);
+void newPen(vm::stack *);
+void loadModule(vm::stack *);
+void nullPath(vm::stack *);
+void nullPath3(vm::stack *);
+void nullGuide(vm::stack *);
+void dotsGuide(vm::stack *);
+void dashesGuide(vm::stack *);
+void newCycleToken(vm::stack *);
+void curlSpecifierValuePart(vm::stack *);
+void curlSpecifierSidePart(vm::stack *);
+void tensionSpecifierOutPart(vm::stack *);
+void tensionSpecifierInPart(vm::stack *);
+void tensionSpecifierAtleastPart(vm::stack *);
+void emptyString(vm::stack *);
+void transformXPart(vm::stack *);
+void transformYPart(vm::stack *);
+void transformXXPart(vm::stack *);
+void transformXYPart(vm::stack *);
+void transformYXPart(vm::stack *);
+void transformYYPart(vm::stack *);
+void real6ToTransform(vm::stack *);
+void transformIdentity(vm::stack *);
+void pairZero(vm::stack *);
+void realRealToPair(vm::stack *);
+void pairNegate(vm::stack *);
+void pairXPart(vm::stack *);
+void pairYPart(vm::stack *);
+void tripleZero(vm::stack *);
+void realRealRealToTriple(vm::stack *);
+void tripleXPart(vm::stack *);
+void tripleYPart(vm::stack *);
+void tripleZPart(vm::stack *);
+void emptyArray(vm::stack *);
+void newDeepArray(vm::stack *);
+void newInitializedArray(vm::stack *);
+void newAppendedArray(vm::stack *);
+void newDuplicateArray(vm::stack *);
+void arrayRead(vm::stack *);
+void arraySliceRead(vm::stack *);
+void arraySliceReadToEnd(vm::stack *);
+void arrayArrayRead(vm::stack *);
+void arrayWrite(vm::stack *);
+void arraySliceWrite(vm::stack *);
+void arraySliceWriteToEnd(vm::stack *);
+void arrayLength(vm::stack *);
+void arrayKeys(vm::stack *);
+void arrayCyclicFlag(vm::stack *);
+void arrayInitializedHelper(vm::stack *);
+void arrayInitialized(vm::stack *);
+void arrayCyclicHelper(vm::stack *);
+void arrayCyclic(vm::stack *);
+void arrayPushHelper(vm::stack *);
+void arrayPush(vm::stack *);
+void arrayAppendHelper(vm::stack *);
+void arrayAppend(vm::stack *);
+void arrayPopHelper(vm::stack *);
+void arrayPop(vm::stack *);
+void arrayInsertHelper(vm::stack *);
+void arrayInsert(vm::stack *);
+void arrayDelete(vm::stack *);
+void arrayAlias(vm::stack *);
+void arrayIntArray(vm::stack *);
+void arraySequence(vm::stack *);
+void arrayFunction(vm::stack *);
+void arraySort(vm::stack *);
+void arrayCopy(vm::stack *);
+void arrayConcat(vm::stack *);
+void array2Copy(vm::stack *);
+void array3Copy(vm::stack *);
+void array2Transpose(vm::stack *);
+void array3Transpose(vm::stack *);
+void arrayConditional(vm::stack *);
+void diagonal(vm::stack *);
+void pairArrayFFT(vm::stack *);
+void nullFile(vm::stack *);
+}
+
+#endif // RUNTIME_H
diff --git a/Build/source/utils/asymptote/runtime.in b/Build/source/utils/asymptote/runtime.in
new file mode 100644
index 00000000000..decee0727b1
--- /dev/null
+++ b/Build/source/utils/asymptote/runtime.in
@@ -0,0 +1,5818 @@
+/*****
+ * runtime.in
+ * Tom Prince 2005/4/15
+ *
+ * Generate the runtime functions used by the vm::stack machine.
+ *
+ *****/
+
+/* Autogenerated routines are specified like this (separated by a formfeed):
+ type asyname:cname(cparams)
+ {
+ C code
+ }
+
+*/
+
+// Use Void f() instead of void f() to force an explicit Stack argument.
+
+
+void => primVoid()
+Void => primVoid()
+Int => primInt()
+bool => primBoolean()
+double => primReal()
+real => primReal()
+string* => primString()
+string => primString()
+pen => primPen()
+pair => primPair()
+triple => primTriple()
+path => primPath()
+path3 => primPath3()
+guide* => primGuide()
+cycleToken => primCycleToken()
+tensionSpecifier => primTensionSpecifier()
+curlSpecifier => primCurlSpecifier()
+file* => primFile()
+picture* => primPicture()
+transform => primTransform()
+callable* => voidFunction()
+callableBp* => breakpointFunction()
+callableReal* => realRealFunction()
+callableTransform* => transformFunction()
+runnable* => primCode()
+boolarray* => boolArray()
+Intarray* => IntArray()
+Intarray2* => IntArray2()
+realarray* => realArray()
+realarray2* => realArray2()
+pairarray* => pairArray()
+pairarray2* => pairArray2()
+triplearray* => tripleArray()
+triplearray2* => tripleArray2()
+patharray* => pathArray()
+patharray2* => pathArray2()
+guidearray* => guideArray()
+transformarray* => transformArray()
+penarray* => penArray()
+penarray2* => penArray2()
+stringarray* => stringArray()
+stringarray2* => stringArray2()
+
+#include <cfloat>
+#include <time.h>
+#include <sys/times.h>
+#include <locale.h>
+
+#include "angle.h"
+#include "pair.h"
+#include "triple.h"
+#include "transform.h"
+#include "path.h"
+#include "path3.h"
+#include "pen.h"
+#include "guide.h"
+#include "picture.h"
+#include "drawpath.h"
+#include "drawpath3.h"
+#include "drawsurface.h"
+#include "drawfill.h"
+#include "drawclipbegin.h"
+#include "drawclipend.h"
+#include "drawlabel.h"
+#include "drawverbatim.h"
+#include "drawgsave.h"
+#include "drawgrestore.h"
+#include "drawlayer.h"
+#include "drawimage.h"
+#include "drawgroup.h"
+#include "fileio.h"
+#include "genv.h"
+#include "builtin.h"
+#include "texfile.h"
+#include "pipestream.h"
+#include "parser.h"
+#include "stack.h"
+#include "util.h"
+#include "locate.h"
+#include "mathop.h"
+#include "callable.h"
+#include "stm.h"
+#include "lexical.h"
+#include "process.h"
+#include "arrayop.h"
+#include "predicates.h"
+#include "Delaunay.h"
+
+#ifdef HAVE_LIBFFTW3
+#include "fftw++.h"
+#endif
+
+#if defined(HAVE_LIBREADLINE) && defined(HAVE_LIBCURSES)
+#include <readline/readline.h>
+#include <readline/history.h>
+#endif
+
+#if defined(USEGC) && defined(GC_DEBUG) && defined(GC_BACKTRACE)
+ extern "C" {
+ void *GC_generate_random_valid_address(void);
+ void GC_debug_print_heap_obj_proc(void *);
+ }
+#endif
+
+using namespace vm;
+using namespace camp;
+using namespace settings;
+
+namespace run {
+using camp::pair;
+using vm::array;
+using vm::frame;
+using vm::stack;
+using camp::transform;
+using absyntax::runnable;
+
+typedef double real;
+
+#define CURRENTPEN processData().currentpen
+
+typedef array boolarray;
+typedef array Intarray;
+typedef array Intarray2;
+typedef array realarray;
+typedef array realarray2;
+typedef array pairarray;
+typedef array pairarray2;
+typedef array triplearray;
+typedef array triplearray2;
+typedef array patharray;
+typedef array patharray2;
+typedef array guidearray;
+typedef array transformarray;
+typedef array penarray;
+typedef array penarray2;
+typedef array stringarray;
+typedef array stringarray2;
+
+typedef callable callableBp;
+typedef callable callableReal;
+typedef callable callableTransform;
+}
+
+using vm::array;
+using types::function;
+
+#define PRIMITIVE(name,Name,asyName) using types::prim##Name;
+#include <primitives.h>
+#undef PRIMITIVE
+
+using types::boolArray;
+using types::IntArray;
+using types::IntArray2;
+using types::realArray;
+using types::realArray2;
+using types::pairArray;
+using types::pairArray2;
+using types::tripleArray;
+using types::tripleArray2;
+using types::pathArray;
+using types::pathArray2;
+using types::guideArray;
+using types::transformArray;
+using types::penArray;
+using types::penArray2;
+using types::stringArray;
+using types::stringArray2;
+using types::formal;
+
+function *voidFunction()
+{
+ return new function(primVoid());
+}
+
+function *breakpointFunction()
+{
+ return new function(primString(),primString(),primInt(),primInt(),
+ primCode());
+}
+
+function *realRealFunction()
+{
+ return new function(primReal(),primReal());
+}
+
+function *transformFunction()
+{
+ return new function(primTransform());
+}
+
+function *realTripleFunction()
+{
+ return new function(primReal(),primTriple());
+}
+
+const size_t camp::ColorComponents[]={0,0,1,3,4,0};
+
+namespace vm {
+}
+
+namespace run {
+
+const char *invalidargument="invalid argument";
+const char *arrayempty="cannot take min or max of empty array";
+
+// Return the factorial of a non-negative integer using a lookup table.
+Int factorial(Int n)
+{
+ static Int *table;
+ static Int size=0;
+ if(size == 0) {
+ Int f=1;
+ size=2;
+ while(f <= Int_MAX/size)
+ f *= (size++);
+ table=new Int[size];
+ table[0]=f=1;
+ for(Int i=1; i < size; ++i) {
+ f *= i;
+ table[i]=f;
+ }
+ }
+ if(n >= size) integeroverflow(0);
+ return table[n];
+}
+
+static inline Int Round(double x)
+{
+ return Int(x+((x >= 0) ? 0.5 : -0.5));
+}
+
+inline Int sgn(double x)
+{
+ return (x > 0.0 ? 1 : (x < 0.0 ? -1 : 0));
+}
+
+void outOfBounds(const char *op, size_t len, Int n)
+{
+ ostringstream buf;
+ buf << op << " array of length " << len << " with out-of-bounds index " << n;
+ error(buf);
+}
+
+inline item& arrayRead(array *a, Int n)
+{
+ size_t len=checkArray(a);
+ bool cyclic=a->cyclic();
+ if(cyclic && len > 0) n=imod(n,len);
+ else if(n < 0 || n >= (Int) len) outOfBounds("reading",len,n);
+ return (*a)[(unsigned) n];
+}
+
+// Helper function to create deep arrays.
+static array* deepArray(Int depth, Int *dims)
+{
+ assert(depth > 0);
+
+ if (depth == 1) {
+ return new array(dims[0]);
+ } else {
+ Int length = dims[0];
+ depth--; dims++;
+
+ array *a = new array(length);
+
+ for (Int index = 0; index < length; index++) {
+ (*a)[index] = deepArray(depth, dims);
+ }
+ return a;
+ }
+}
+
+array *nop(array *a)
+{
+ return a;
+}
+
+array *Identity(Int n)
+{
+ size_t N=(size_t) n;
+ array *c=new array(N);
+ for(size_t i=0; i < N; ++i) {
+ array *ci=new array(N);
+ (*c)[i]=ci;
+ for(size_t j=0; j < N; ++j)
+ (*ci)[j]=0.0;
+ (*ci)[i]=1.0;
+ }
+ return c;
+}
+
+array *copyArray(array *a)
+{
+ size_t size=checkArray(a);
+ array *c=new array(size);
+ for(size_t i=0; i < size; i++)
+ (*c)[i]=(*a)[i];
+ return c;
+}
+
+inline size_t checkdimension(array *a, size_t dim)
+{
+ size_t size=checkArray(a);
+ if(dim && size != dim) {
+ ostringstream buf;
+ buf << "array of length " << dim << " expected" << endl;
+ error(buf);
+ }
+ return size;
+}
+
+double *copyArrayC(array *a, size_t dim=0)
+{
+ size_t size=checkdimension(a,dim);
+ double *c=new double[size];
+ for(size_t i=0; i < size; i++)
+ c[i]=read<double>(a,i);
+ return c;
+}
+
+triple *copyTripleArrayC(array *a, size_t dim=0)
+{
+ size_t size=checkdimension(a,dim);
+ triple *c=new triple[size];
+ for(size_t i=0; i < size; i++)
+ c[i]=read<triple>(a,i);
+ return c;
+}
+
+array *copyArray2(array *a)
+{
+ size_t size=checkArray(a);
+ array *c=new array(size);
+ for(size_t i=0; i < size; i++) {
+ array *ai=read<array*>(a,i);
+ size_t aisize=checkArray(ai);
+ array *ci=new array(aisize);
+ (*c)[i]=ci;
+ for(size_t j=0; j < aisize; j++)
+ (*ci)[j]=(*ai)[j];
+ }
+ return c;
+}
+
+array *copyArray3(array *a)
+{
+ size_t size=checkArray(a);
+ array *c=new array(size);
+ for(size_t i=0; i < size; i++) {
+ array *ai=read<array*>(a,i);
+ size_t aisize=checkArray(ai);
+ array *ci=new array(aisize);
+ (*c)[i]=ci;
+ for(size_t j=0; j < aisize; j++) {
+ array *aij=read<array*>(ai,j);
+ size_t aijsize=checkArray(aij);
+ array *cij=new array(aijsize);
+ (*ci)[j]=cij;
+ for(size_t k=0; k < aijsize; k++)
+ (*cij)[k]=(*aij)[k];
+ }
+ }
+ return c;
+}
+
+double *copyArray2C(array *a, bool square=true, size_t dim2=0)
+{
+ size_t n=checkArray(a);
+ size_t m=(square || n == 0) ? n : checkArray(read<array*>(a,0));
+ if(n > 0 && dim2 && m != dim2) {
+ ostringstream buf;
+ buf << "second matrix dimension must be " << dim2 << endl;
+ error(buf);
+ }
+
+ double *c=new double[n*m];
+ for(size_t i=0; i < n; i++) {
+ array *ai=read<array*>(a,i);
+ size_t aisize=checkArray(ai);
+ if(aisize == m) {
+ double *ci=c+i*m;
+ for(size_t j=0; j < m; j++)
+ ci[j]=read<double>(ai,j);
+ } else
+ error(square ? "matrix must be square" : "matrix must be rectangular");
+ }
+ return c;
+}
+
+static const char *incommensurate="Incommensurate matrices";
+static const char *singular="Singular matrix";
+static size_t *pivot,*Row,*Col;
+
+triple operator *(const array& t, const triple& v)
+{
+ size_t n=checkArray(&t);
+ if(n != 4) error(incommensurate);
+ array *t0=read<array*>(t,0);
+ array *t1=read<array*>(t,1);
+ array *t2=read<array*>(t,2);
+ array *t3=read<array*>(t,3);
+
+ if(checkArray(t0) != 4 || checkArray(t1) != 4 ||
+ checkArray(t2) != 4 || checkArray(t3) != 4)
+ error(incommensurate);
+
+ double x=v.getx();
+ double y=v.gety();
+ double z=v.getz();
+
+ double f=read<real>(t3,0)*x+read<real>(t3,1)*y+read<real>(t3,2)*z+
+ read<real>(t3,3);
+ if(f == 0.0) run::dividebyzero();
+ f=1.0/f;
+
+ return triple((read<real>(t0,0)*x+read<real>(t0,1)*y+read<real>(t0,2)*z+
+ read<real>(t0,3))*f,
+ (read<real>(t1,0)*x+read<real>(t1,1)*y+read<real>(t1,2)*z+
+ read<real>(t1,3))*f,
+ (read<real>(t2,0)*x+read<real>(t2,1)*y+read<real>(t2,2)*z+
+ read<real>(t2,3))*f);
+}
+
+triple multshiftless(const array& t, const triple& v)
+{
+ size_t n=checkArray(&t);
+ if(n != 4) error(incommensurate);
+ array *t0=read<array*>(t,0);
+ array *t1=read<array*>(t,1);
+ array *t2=read<array*>(t,2);
+ array *t3=read<array*>(t,3);
+
+ if(checkArray(t0) != 4 || checkArray(t1) != 4 ||
+ checkArray(t2) != 4 || checkArray(t3) != 4)
+ error(incommensurate);
+
+ double x=v.getx();
+ double y=v.gety();
+ double z=v.getz();
+
+ double f=read<real>(t3,0)*x+read<real>(t3,1)*y+read<real>(t3,2)*z+
+ read<real>(t3,3);
+ if(f == 0.0) run::dividebyzero();
+ f=1.0/f;
+
+ return triple((read<real>(t0,0)*x+read<real>(t0,1)*y+read<real>(t0,2)*z)*f,
+ (read<real>(t1,0)*x+read<real>(t1,1)*y+read<real>(t1,2)*z)*f,
+ (read<real>(t2,0)*x+read<real>(t2,1)*y+read<real>(t2,2)*z)*f);
+}
+
+static inline void inverseAllocate(size_t n)
+{
+ pivot=new size_t[n];
+ Row=new size_t[n];
+ Col=new size_t[n];
+}
+
+static inline void inverseDeallocate()
+{
+ delete[] pivot;
+ delete[] Row;
+ delete[] Col;
+}
+
+void writestring(stack *s)
+{
+ callable *suffix=pop<callable *>(s,NULL);
+ string S=pop<string>(s);
+ vm::item it=pop(s);
+ bool defaultfile=isdefault(it);
+ camp::file *f=defaultfile ? &camp::Stdout : vm::get<camp::file*>(it);
+ if(!f->isOpen()) return;
+ if(S != "") f->write(S);
+ if(f->text()) {
+ if(suffix) {
+ s->push(f);
+ suffix->call(s);
+ } else if(defaultfile) f->writeline();
+ }
+}
+
+void checkSquare(array *a)
+{
+ size_t n=checkArray(a);
+ for(size_t i=0; i < n; i++)
+ if(checkArray(read<array*>(a,i)) != n)
+ error("matrix a must be square");
+}
+
+// Crout's algorithm for computing the LU decomposition of a square matrix.
+// cf. routine ludcmp (Press et al., Numerical Recipes, 1991).
+Int LUdecompose(double *a, size_t n, size_t* index, bool warn=true)
+{
+ double *vv=new double[n];
+ Int swap=1;
+ for(size_t i=0; i < n; ++i) {
+ double big=0.0;
+ double *ai=a+i*n;
+ for(size_t j=0; j < n; ++j) {
+ double temp=fabs(ai[j]);
+ if(temp > big) big=temp;
+ }
+ if(big == 0.0) {
+ delete[] vv;
+ if(warn) error(singular);
+ else return 0;
+ }
+ vv[i]=1.0/big;
+ }
+ for(size_t j=0; j < n; ++j) {
+ for(size_t i=0; i < j; ++i) {
+ double *ai=a+i*n;
+ double sum=ai[j];
+ for(size_t k=0; k < i; ++k) {
+ sum -= ai[k]*a[k*n+j];
+ }
+ ai[j]=sum;
+ }
+ double big=0.0;
+ size_t imax=j;
+ for(size_t i=j; i < n; ++i) {
+ double *ai=a+i*n;
+ double sum=ai[j];
+ for(size_t k=0; k < j; ++k)
+ sum -= ai[k]*a[k*n+j];
+ ai[j]=sum;
+ double temp=vv[i]*fabs(sum);
+ if(temp >= big) {
+ big=temp;
+ imax=i;
+ }
+ }
+ double *aj=a+j*n;
+ double *aimax=a+imax*n;
+ if(j != imax) {
+ for(size_t k=0; k < n; ++k) {
+ double temp=aimax[k];
+ aimax[k]=aj[k];
+ aj[k]=temp;
+ }
+ swap *= -1;
+ vv[imax]=vv[j];
+ }
+ if(index)
+ index[j]=imax;
+ if(j != n) {
+ double denom=aj[j];
+ if(denom == 0.0) {
+ delete[] vv;
+ if(warn) error(singular);
+ else return 0;
+ }
+ for(size_t i=j+1; i < n; ++i)
+ a[i*n+j] /= denom;
+ }
+ }
+ delete[] vv;
+ return swap;
+}
+
+void dividebyzero(size_t i)
+{
+ ostringstream buf;
+ if(i > 0) buf << "array element " << i << ": ";
+ buf << "Divide by zero";
+ error(buf);
+}
+
+void integeroverflow(size_t i)
+{
+ ostringstream buf;
+ if(i > 0) buf << "array element " << i << ": ";
+ buf << "Integer overflow";
+ error(buf);
+}
+
+#if defined(HAVE_LIBREADLINE) && defined(HAVE_LIBCURSES)
+struct historyState {
+ bool store;
+ HISTORY_STATE state;
+};
+
+typedef mem::map<CONST string, historyState> historyMap_t;
+historyMap_t historyMap;
+static HISTORY_STATE history_save;
+
+// Store a deep copy of the current readline history in dest.
+void store_history(HISTORY_STATE *dest)
+{
+ HISTORY_STATE *src=history_get_history_state();
+ if(src) {
+ *dest=*src;
+ for(Int i=0; i < src->length; ++i)
+ dest->entries[i]=src->entries[i];
+ free(src);
+ }
+}
+
+stringarray* get_history(Int n)
+{
+ int N=intcast(n);
+ if(N <= 0) N=history_length;
+ else N=Min(N,history_length);
+ array *a=new array((size_t) N);
+ int offset=history_length-N+1;
+ for(int i=0; i < N; ++i) {
+ HIST_ENTRY *last=history_get(offset+i);
+ string s=last ? last->line : "";
+ (*a)[i]=s;
+ }
+ return a;
+}
+
+string historyfilename(const string &name)
+{
+ return historyname+"_"+name;
+}
+#endif
+
+#if defined(HAVE_LIBREADLINE) && defined(HAVE_LIBCURSES)
+int readline_startup_hook()
+{
+#ifdef __CYGWIN__
+ rl_set_key("\\M-[3~",rl_delete,rl_get_keymap());
+ rl_set_key("\\M-[2~",rl_overwrite_mode,rl_get_keymap());
+#endif
+ return 0;
+}
+
+void init_readline(bool tabcompletion=true)
+{
+ static bool first=true;
+ if(first) {
+ first=false;
+#ifdef __CYGWIN__
+ rl_startup_hook=readline_startup_hook;
+#endif
+ }
+ rl_bind_key('\t',tabcompletion ? rl_complete : rl_insert);
+}
+#endif
+
+void cleanup()
+{
+ processDataStruct &pd=processData();
+ pd.atExitFunction=NULL;
+ pd.atUpdateFunction=NULL;
+ pd.atBreakpointFunction=NULL;
+
+#if defined(HAVE_LIBREADLINE) && defined(HAVE_LIBCURSES)
+ store_history(&history_save);
+ int nlines=intcast(getSetting<Int>("historylines"));
+ for(historyMap_t::iterator h=historyMap.begin(); h != historyMap.end();
+ ++h) {
+ history_set_history_state(&h->second.state);
+ stifle_history(nlines);
+ if(h->second.store) write_history(historyfilename(h->first).c_str());
+ }
+ history_set_history_state(&history_save);
+#endif
+}
+
+void purge(Int divisor=0)
+{
+#ifdef USEGC
+ if(divisor > 0) GC_set_free_space_divisor((GC_word) divisor);
+ GC_gcollect();
+#endif
+}
+
+void updateFunction(stack *Stack)
+{
+ callable *atUpdateFunction=processData().atUpdateFunction;
+ if(atUpdateFunction && !nullfunc::instance()->compare(atUpdateFunction))
+ atUpdateFunction->call(Stack);
+}
+
+void exitFunction(stack *Stack)
+{
+ callable *atExitFunction=processData().atExitFunction;
+ if(atExitFunction && !nullfunc::instance()->compare(atExitFunction))
+ atExitFunction->call(Stack);
+ cleanup();
+}
+
+default_t def;
+string emptystring;
+array *emptyarray=new array(0);
+string commentchar="#";
+pair zero;
+
+void breakpoint(stack *Stack, runnable *r)
+{
+ callable *atBreakpointFunction=processData().atBreakpointFunction;
+ if(atBreakpointFunction &&
+ !nullfunc::instance()->compare(atBreakpointFunction)) {
+ position curPos=getPos();
+ Stack->push<string>(curPos.filename());
+ Stack->push<Int>((Int) curPos.Line());
+ Stack->push<Int>((Int) curPos.Column());
+ Stack->push(r ? r : item(def));
+ atBreakpointFunction->call(Stack); // returns a string
+ } else Stack->push<string>("");
+}
+
+}
+
+namespace types {
+extern const char *names[];
+}
+
+void checkformat(const char *ptr, bool intformat)
+{
+ while(*ptr != '\0') {
+ if(*ptr != '%') /* While we have regular characters, print them. */
+ ptr++;
+ else { /* We've got a format specifier. */
+ ptr++;
+
+ while(*ptr && strchr ("-+ #0'I", *ptr)) /* Move past flags. */
+ *ptr++;
+
+ if(*ptr == '*')
+ ptr++;
+ else while(isdigit(*ptr)) /* Handle explicit numeric value. */
+ ptr++;
+
+ if(*ptr == '.') {
+ *ptr++; /* Go past the period. */
+ if(*ptr == '*') {
+ ptr++;
+ } else
+ while(isdigit(*ptr)) /* Handle explicit numeric value. */
+ *ptr++;
+ }
+ while(*ptr && strchr ("hlL", *ptr))
+ *ptr++;
+
+ if(*ptr == '%') ++ptr;
+ else if(*ptr != '\0') {
+ if(intformat) {
+ switch(*ptr) {
+ case 'd':
+ case 'i':
+ case 'o':
+ case 'u':
+ case 'x':
+ case 'X':
+ case 'c':
+ break;
+ default:
+ ostringstream buf;
+ buf << "Invalid format '" << *ptr << "' for type "
+ << types::names[types::ty_Int];
+ error(buf);
+ break;
+ }
+ } else {
+ switch(*ptr) {
+ case 'f':
+ case 'F':
+ case 'e':
+ case 'E':
+ case 'g':
+ case 'G':
+ break;
+ default:
+ ostringstream buf;
+ buf << "Invalid format '" << *ptr << "' for type "
+ << types::names[types::ty_real];
+ error(buf);
+ break;
+ }
+ }
+ }
+ } /* End of else statement */
+ }
+}
+
+// Return an angle in the interval [0,360).
+inline double principalBranch(double deg)
+{
+ if(deg < 0) deg += 360;
+ return deg;
+}
+
+static string defaulttransparency=string("Compatible");
+
+static const string defaulttimeformat=string("%a %b %d %T %Z %Y");
+#ifdef HAVE_STRFTIME
+static const size_t nTime=256;
+static char Time[nTime];
+#endif
+
+void clear(string file, Int line, bool warn=false)
+{
+ bpinfo bp(file,line);
+ for(mem::list<bpinfo>::iterator p=bplist.begin(); p != bplist.end(); ++p) {
+ if(*p == bp) {
+ cout << "cleared breakpoint at " << file << ": " << line << endl;
+ bplist.remove(bp);
+ return;
+ }
+ }
+ if(warn)
+ cout << "No such breakpoint at " << file << ": " << line << endl;
+}
+
+Int windingnumber(array *p, camp::pair z)
+{
+ size_t size=checkArray(p);
+ Int count=0;
+ for(size_t i=0; i < size; i++)
+ count += read<path *>(p,i)->windingnumber(z);
+ return count;
+}
+
+string convertname(string name, const string& format, bool check=true)
+{
+ if(name.empty())
+ return buildname(outname(),format,"");
+ else
+ if(check) checkLocal(name);
+ return format.empty() ? name : format+":"+name;
+}
+
+callable *Func;
+stack *FuncStack;
+double wrapFunction(double x)
+{
+ FuncStack->push(x);
+ Func->call(FuncStack);
+ return pop<double>(FuncStack);
+}
+
+callable *compareFunc;
+bool compareFunction(const vm::item& i, const vm::item& j)
+{
+ FuncStack->push(i);
+ FuncStack->push(j);
+ compareFunc->call(FuncStack);
+ return pop<bool>(FuncStack);
+}
+
+void unused(void *)
+{
+}
+
+pair readpair(stringstream& s, bool tex)
+{
+ static const double f=12.0/100.0;
+ double x,y;
+ s >> y;
+ s >> x;
+ return tex ? pair(f*x,-f*y) : pair(x,y);
+}
+
+// Ignore unclosed begingroups but not spurious endgroups.
+const char *nobegin="endgroup without matching begingroup";
+
+// Return the component of vector v perpendicular to a unit vector u.
+inline triple perp(triple v, triple u)
+{
+ return v-dot(v,u)*u;
+}
+
+string ASYo="/ASYo {( ) print 12 string cvs print} bind def";
+string pathforall="{(M) print ASYo ASYo} {(L) print ASYo ASYo} {(C) print ASYo ASYo ASYo ASYo ASYo ASYo} {(c) print} pathforall";
+string currentpoint="print currentpoint ASYo ASYo ";
+
+array *readpath(const string& psname, bool tex, bool keep)
+{
+ array *P=new array(0);
+ ostringstream pipe;
+ pipe << "'" << getSetting<string>("gs")
+ << "' -q -dNOPAUSE -dBATCH";
+ if(safe) pipe << " -dSAFER";
+#ifdef __CYGWIN__
+ string null="NUL";
+#else
+ string null="/dev/null";
+#endif
+ pipe << " -sDEVICE=epswrite -sOutputFile="+null+" '" << psname << "'";
+ iopipestream gs(pipe.str().c_str(),"gs","Ghostscript");
+ stringstream buf;
+ while(true) {
+ string out;
+ gs >> out;
+ buf << out;
+ string s=buf.str();
+ if(gs.tailequals(s.c_str(),s.size(),"E",1)) break;
+ }
+ if(verbose > 2) cout << endl;
+
+ mem::vector<solvedKnot> nodes;
+ solvedKnot node;
+ bool cyclic=false;
+ bool active=false;
+
+ pair offset;
+ while(!buf.eof()) {
+ char c;
+ buf >> c;
+ switch(c) {
+ case 'M':
+ {
+ if(active) {
+ if(cyclic) {
+ if(node.point == nodes[0].point)
+ nodes[0].pre=node.pre;
+ else {
+ pair delta=(nodes[0].point-node.point)*third;
+ node.post=node.point+delta;
+ nodes[0].pre=nodes[0].point-delta;
+ node.straight=true;
+ nodes.push_back(node);
+ }
+ } else {
+ node.post=node.point;
+ node.straight=false;
+ nodes.push_back(node);
+ }
+ P->push(path(nodes,nodes.size(),cyclic));
+ nodes.clear();
+ }
+ active=false;
+ cyclic=false;
+ node.pre=node.point=readpair(buf,tex)-offset;
+ node.straight=false;
+ break;
+ }
+ case 'L':
+ {
+ pair point=readpair(buf,tex)-offset;
+ pair delta=(point-node.point)*third;
+ node.post=node.point+delta;
+ node.straight=true;
+ nodes.push_back(node);
+ active=true;
+ node.pre=point-delta;
+ node.point=point;
+ break;
+ }
+ case 'C':
+ {
+ pair point=readpair(buf,tex)-offset;
+ pair pre=readpair(buf,tex)-offset;
+ node.post=readpair(buf,tex)-offset;
+ node.straight=false;
+ nodes.push_back(node);
+ active=true;
+ node.pre=pre;
+ node.point=point;
+ break;
+ }
+ case 'c':
+ {
+ cyclic=true;
+ break;
+ }
+ case 'Z':
+ {
+ offset=readpair(buf,tex);
+ break;
+ }
+ }
+ }
+
+ if(!keep)
+ unlink(psname.c_str());
+ return P;
+}
+
+pair sin(pair z)
+{
+ return pair(sin(z.getx())*cosh(z.gety()),cos(z.getx())*sinh(z.gety()));
+}
+
+pair exp(pair z)
+{
+ return exp(z.getx())*expi(z.gety());
+}
+
+pair gamma(pair z)
+{
+ static double p[]={0.99999999999980993,676.5203681218851,-1259.1392167224028,
+ 771.32342877765313,-176.61502916214059,12.507343278686905,
+ -0.13857109526572012,9.9843695780195716e-6,
+ 1.5056327351493116e-7};
+ static int n=sizeof(p)/sizeof(double);
+ static double root2pi=sqrt(2*PI);
+ if(z.getx() < 0.5)
+ return PI/(sin(PI*z)*gamma(1.0-z));
+ z -= 1.0;
+ pair x=p[0];
+ for(int i=1; i < n; ++i)
+ x += p[i]/(z+i);
+ pair t=n-1.5+z;
+ return root2pi*pow(t,z+0.5)*exp(-t)*x;
+}
+
+// Autogenerated routines:
+
+
+
+// Initializers
+
+Int :IntZero()
+{
+ return 0;
+}
+
+real :realZero()
+{
+ return 0.0;
+}
+
+bool :boolFalse()
+{
+ return false;
+}
+
+array* :pushNullArray()
+{
+ return 0;
+}
+
+frame* :pushNullRecord()
+{
+ return 0;
+}
+
+item :pushNullFunction()
+{
+ return nullfunc::instance();
+}
+
+
+// Default operations
+
+// Put the default value token on the stack (in place of an argument when
+// making a function call).
+item :pushDefault()
+{
+ return def;
+}
+
+
+// Test if the value on the stack is the default value token.
+bool :isDefault(item i)
+{
+ return isdefault(i);
+}
+
+
+// Logical operations
+
+bool !(bool b)
+{
+ return !b;
+}
+
+bool :boolMemEq(frame *a, frame *b)
+{
+ return a == b;
+}
+
+bool :boolMemNeq(frame *a, frame *b)
+{
+ return a != b;
+}
+
+bool :boolFuncEq(callable *a, callable *b)
+{
+ return a->compare(b);
+}
+
+bool :boolFuncNeq(callable *a, callable *b)
+{
+ return !(a->compare(b));
+}
+
+
+// Bit operations
+
+Int AND(Int a, Int b)
+{
+ return a & b;
+}
+
+Int OR(Int a, Int b)
+{
+ return a | b;
+}
+
+Int XOR(Int a, Int b)
+{
+ return a ^ b;
+}
+
+Int NOT(Int a)
+{
+ return ~a;
+}
+
+
+// Casts
+
+guide* :pairToGuide(pair z)
+{
+ return new pairguide(z);
+}
+
+guide* :pathToGuide(path p)
+{
+ return new pathguide(p);
+}
+
+path :guideToPath(guide *g)
+{
+ return g->solve();
+}
+
+
+// Picture operations
+
+picture* :newPicture()
+{
+ return new picture();
+}
+
+bool empty(picture *f)
+{
+ return f->null();
+}
+
+void erase(picture *f)
+{
+ f->nodes.clear();
+}
+
+pair min(picture *f)
+{
+ return f->bounds().Min();
+}
+
+pair max(picture *f)
+{
+ return f->bounds().Max();
+}
+
+void label(picture *f, string *s, string *size, transform t, pair position,
+ pair align, pen p)
+{
+ f->append(new drawLabel(*s,*size,t,position,align,p));
+}
+
+bool labels(picture *f)
+{
+ return f->havelabels();
+}
+
+patharray *_texpath(string *s, pen p=CURRENTPEN)
+{
+ array *P=new array(0);
+ if(s->empty()) return P;
+
+ string prefix=outname();
+ spaceToUnderscore(prefix);
+ string psname=auxname(prefix,"ps");
+
+ string texname=auxname(prefix,"tex");
+ string dviname=auxname(prefix,"dvi");
+ bbox b;
+ texfile tex(texname,b,true);
+ tex.miniprologue();
+
+ tex.setfont(p);
+ tex.verbatimline("\\special{ps:");
+ tex.verbatimline(ASYo);
+ tex.verbatimline("/ASY1 true def");
+ tex.verbatimline("/v {neg exch 4 copy 4 2 roll 2 copy 6 2 roll 2 copy (M) print ASYo ASYo (L) print ASYo add ASYo (L) print add ASYo add ASYo (L) print add ASYo ASYo (c) print} bind def");
+ tex.verbatimline("/show {ASY1 {(Z) "+currentpoint+
+ "/ASY1 false def} if currentpoint newpath moveto false charpath "+
+ pathforall+"} bind def}");
+ tex.verbatim(*s);
+ tex.verbatimline("\\special{ps: (E) print}");
+ tex.epilogue(true);
+ tex.close();
+
+ ostringstream cmd;
+ string aux=auxname(prefix,"aux");
+ unlink(aux.c_str());
+ cmd << texprogram(true) << " \\nonstopmode\\input '" << texname << "'";
+ bool quiet=verbose <= 2;
+ int status=System(cmd,quiet ? 1 : 0,"texpath",texpathmessage());
+ if(!status && getSetting<bool>("twice"))
+ status=System(cmd,quiet ? 1 : 0,"texpath",texpathmessage());
+ if(status) {
+ if(quiet) {
+ ostringstream cmd;
+ cmd << texprogram(true) << " \\scrollmode\\input '" << texname << "'";
+ System(cmd,0);
+ }
+ }
+
+ if(!status) {
+ ostringstream cmd;
+ cmd << "'" << getSetting<string>("dvips") << "' -R -Pdownload35 -D600 "
+ << getSetting<string>("dvipsOptions");
+ if(verbose <= 2) cmd << " -q";
+ cmd << " -o '" << psname << "' '" << dviname << "'";
+ status=System(cmd,0,true,"dvips");
+ }
+
+ if(status != 0)
+ error("texpath failed");
+
+ bool keep=getSetting<bool>("keep");
+ if(!keep) { // Delete temporary files.
+ unlink(texname.c_str());
+ if(!getSetting<bool>("keepaux"))
+ unlink(aux.c_str());
+ unlink(auxname(prefix,"log").c_str());
+ unlink(dviname.c_str());
+ }
+ return readpath(psname,true,keep);
+}
+
+patharray *_strokepath(path g, pen p=CURRENTPEN)
+{
+ array *P=new array(0);
+ if(g.size() == 0) return P;
+
+ string prefix=outname();
+ spaceToUnderscore(prefix);
+ string psname=auxname(prefix,"ps");
+ bbox b;
+ psfile ps(psname, false);
+ ps.prologue(b);
+ ps.verbatimline(ASYo);
+ ps.verbatimline("/stroke {(Z) "+currentpoint+pathforall+"} bind def");
+ ps.resetpen();
+ ps.setpen(p);
+ ps.write(g);
+ ps.strokepath();
+ ps.stroke();
+ ps.verbatimline("(M) "+currentpoint+"(E) print");
+ ps.epilogue();
+ ps.close();
+ return readpath(psname,false,getSetting<bool>("keep"));
+}
+
+void _draw(picture *f, path g, pen p)
+{
+ f->append(new drawPath(g,p));
+}
+
+void fill(picture *f, patharray *g, pen p=CURRENTPEN, bool copy=true)
+{
+ array *(*copyarray)(array *a)=copy ? copyArray: nop;
+ f->append(new drawFill(*copyarray(g),false,p));
+}
+
+void latticeshade(picture *f, patharray *g, bool stroke=false,
+ pen fillrule=CURRENTPEN, penarray2 *p, bool copy=true)
+{
+ array *(*copyarray)(array *a)=copy ? copyArray: nop;
+ f->append(new drawLatticeShade(*copyarray(g),stroke,fillrule,*copyarray(p)));
+}
+
+void axialshade(picture *f, patharray *g, bool stroke=false, pen pena, pair a,
+ pen penb, pair b, bool copy=true)
+{
+ array *(*copyarray)(array *a)=copy ? copyArray: nop;
+ f->append(new drawAxialShade(*copyarray(g),stroke,pena,a,penb,b));
+}
+
+void radialshade(picture *f, patharray *g, bool stroke=false, pen pena,
+ pair a, real ra, pen penb, pair b, real rb, bool copy=true)
+{
+ array *(*copyarray)(array *a)=copy ? copyArray: nop;
+ f->append(new drawRadialShade(*copyarray(g),stroke,pena,a,ra,penb,b,rb));
+}
+
+void gouraudshade(picture *f, patharray *g, bool stroke=false,
+ pen fillrule=CURRENTPEN, penarray *p, pairarray *z,
+ Intarray *edges, bool copy=true)
+{
+ array *(*copyarray)(array *a)=copy ? copyArray: nop;
+ checkArrays(p,z);
+ checkArrays(z,edges);
+ f->append(new drawGouraudShade(*copyarray(g),stroke,fillrule,*copyarray(p),
+ *copyarray(z),*copyarray(edges)));
+}
+
+void gouraudshade(picture *f, patharray *g, bool stroke=false,
+ pen fillrule=CURRENTPEN, penarray *p, Intarray *edges,
+ bool copy=true)
+{
+ array *(*copyarray)(array *a)=copy ? copyArray: nop;
+ size_t n=checkArrays(p,edges);
+ size_t m=checkArray(g);
+ array *z=new array(n);
+ Int k=0;
+ Int in=(Int) n;
+ for(size_t j=0; j < m; ++j) {
+ path *P=read<path *>(g,j);
+ assert(P);
+ Int stop=Min(P->size(),in-k);
+ mem::vector<solvedKnot>& nodes=P->Nodes();
+ for(Int i=0; i < stop; ++i)
+ (*z)[k++]=nodes[i].point;
+ }
+ checkArrays(p,z);
+
+ f->append(new drawGouraudShade(*copyarray(g),stroke,fillrule,*copyarray(p),
+ *z,*copyarray(edges)));
+}
+
+void tensorshade(picture *f, patharray *g, bool stroke=false,
+ pen fillrule=CURRENTPEN, penarray2 *p, patharray *b=NULL,
+ pairarray2 *z=emptyarray, bool copy=true)
+{
+ array *(*copyarray)(array *a)=copy ? copyArray: nop;
+ array *(*copyarray2)(array *a)=copy ? copyArray2: nop;
+ if(b == NULL) b=g;
+ size_t n=checkArrays(p,b);
+ size_t nz=checkArray(z);
+ if(nz != 0)
+ checkEqual(nz,n);
+ f->append(new drawTensorShade(*copyarray(g),stroke,fillrule,*copyarray2(p),
+ *copyarray(b),*copyarray2(z)));
+}
+
+void functionshade(picture *f, patharray *g, bool stroke=false,
+ pen fillrule=CURRENTPEN, string shader=emptystring,
+ bool copy=true)
+{
+ array *(*copyarray)(array *a)=copy ? copyArray: nop;
+ f->append(new drawFunctionShade(*copyarray(g),stroke,fillrule,shader));
+}
+
+// Clip a picture to a superpath using the given fill rule.
+// Subsequent additions to the picture will not be affected by the clipping.
+void clip(picture *f, patharray *g, bool stroke=false,
+ pen fillrule=CURRENTPEN, bool copy=true)
+{
+ array *(*copyarray)(array *a)=copy ? copyArray: nop;
+ drawClipBegin *begin=new drawClipBegin(*copyarray(g),stroke,fillrule,true);
+ f->enclose(begin,new drawClipEnd(true,begin));
+}
+
+void beginclip(picture *f, patharray *g, bool stroke=false,
+ pen fillrule=CURRENTPEN, bool copy=true)
+{
+ array *(*copyarray)(array *a)=copy ? copyArray: nop;
+ f->append(new drawClipBegin(*copyarray(g),stroke,fillrule,false));
+}
+
+void endclip(picture *f)
+{
+ f->append(new drawClipEnd(false));
+}
+
+void gsave(picture *f)
+{
+ f->append(new drawGsave());
+}
+
+void grestore(picture *f)
+{
+ f->append(new drawGrestore());
+}
+
+void begingroup(picture *f)
+{
+ f->append(new drawBegin());
+}
+
+void endgroup(picture *f)
+{
+ f->append(new drawEnd());
+}
+
+void add(picture *dest, picture *src)
+{
+ dest->add(*src);
+}
+
+void prepend(picture *dest, picture *src)
+{
+ dest->prepend(*src);
+}
+
+void postscript(picture *f, string s)
+{
+ f->append(new drawVerbatim(PostScript,s));
+}
+
+void tex(picture *f, string s)
+{
+ f->append(new drawVerbatim(TeX,s));
+}
+
+void postscript(picture *f, string s, pair min, pair max)
+{
+ f->append(new drawVerbatim(PostScript,s,min,max));
+}
+
+void tex(picture *f, string s, pair min, pair max)
+{
+ f->append(new drawVerbatim(TeX,s,min,max));
+}
+
+void texpreamble(string s)
+{
+ string t=s+"\n";
+ processDataStruct &pd=processData();
+ pd.TeXpipepreamble.push_back(t);
+ pd.TeXpreamble.push_back(t);
+}
+
+void deletepreamble()
+{
+ if(getSetting<bool>("inlinetex")) {
+ unlink(auxname(outname(),"pre").c_str());
+ }
+}
+
+void _labelpath(picture *f, string s, string size, path g, string justify,
+ pair offset, pen p)
+{
+ f->append(new drawLabelPath(s,size,g,justify,offset,p));
+}
+
+void texreset()
+{
+ processDataStruct &pd=processData();
+ pd.TeXpipepreamble.clear();
+ pd.TeXpreamble.clear();
+ pd.tex.pipeclose();
+}
+
+void layer(picture *f)
+{
+ f->append(new drawLayer());
+}
+
+void newpage(picture *f)
+{
+ f->append(new drawNewPage());
+}
+
+void _image(picture *f, realarray2 *data, pair initial, pair final,
+ penarray *palette=NULL, transform t=identity, bool copy=true,
+ bool antialias=false)
+{
+ array *(*copyarray)(array *a)=copy ? copyArray: nop;
+ array *(*copyarray2)(array *a)=copy ? copyArray2: nop;
+ f->append(new drawImage(*copyarray2(data),*copyarray(palette),
+ t*matrix(initial,final),antialias));
+}
+
+void _image(picture *f, penarray2 *data, pair initial, pair final,
+ transform t=identity, bool copy=true, bool antialias=false)
+{
+ array *(*copyarray2)(array *a)=copy ? copyArray2: nop;
+ f->append(new drawImage(*copyarray2(data),t*matrix(initial,final),antialias));
+}
+
+string nativeformat()
+{
+ return nativeformat();
+}
+
+bool latex()
+{
+ return latex(getSetting<string>("tex"));
+}
+
+bool pdf()
+{
+ return pdf(getSetting<string>("tex"));
+}
+
+void shipout(string prefix=emptystring, picture *f, picture *preamble=NULL,
+ string format=emptystring, bool wait=false, bool view=true,
+ callableTransform *xform)
+{
+ if(prefix.empty()) prefix=outname();
+
+ picture *result=new picture;
+ unsigned level=0;
+ picture::nodelist::iterator p;
+ for(p = f->nodes.begin(); p != f->nodes.end(); ++p) {
+ xform->call(Stack);
+ transform t=pop<transform>(Stack);
+ static transform Zero=transform(0.0,0.0,0.0,0.0,0.0,0.0);
+ bool Delete=(t == Zero);
+ picture *group=new picture;
+ assert(*p);
+ if((*p)->endgroup()) error(nobegin);
+ if((*p)->begingroup()) {
+ ++level;
+ while(p != f->nodes.end() && level) {
+ if(!Delete) {
+ drawElement *e=t.isIdentity() ? *p : (*p)->transformed(t);
+ group->append(e);
+ }
+ ++p;
+ if(p == f->nodes.end()) break;
+ assert(*p);
+ if((*p)->begingroup()) ++level;
+ if((*p)->endgroup()) {
+ if(level) --level;
+ else error(nobegin);
+ }
+ }
+ }
+ if(p == f->nodes.end()) break;
+ assert(*p);
+ if(!Delete) {
+ drawElement *e=t.isIdentity() ? *p : (*p)->transformed(t);
+ group->append(e);
+ result->add(*group);
+ }
+ }
+
+ result->shipout(preamble,prefix,format,0.0,wait,view);
+}
+
+void shipout3(string prefix, picture *f, string format=emptystring,
+ real width, real height, real angle, triple m, triple M,
+ realarray2 *t, triplearray *lights, realarray2 *diffuse,
+ realarray2 *ambient, realarray2 *specular, bool viewportlighting,
+ bool view=true)
+{
+ size_t n=checkArrays(lights,diffuse);
+ checkEqual(n,checkArray(ambient));
+ checkEqual(n,checkArray(specular));
+
+ f->shipout3(prefix,format,width,height,angle,m,M,copyArray2C(t,true,4),n,
+ copyTripleArrayC(lights),copyArray2C(diffuse,false,4),
+ copyArray2C(ambient,false,4),copyArray2C(specular,false,4),
+ viewportlighting,view);
+}
+
+void shipout3(string prefix, picture *f)
+{
+ f->shipout3(prefix);
+}
+
+void deconstruct(picture *f, picture *preamble=NULL, real magnification=1,
+ callableTransform *xform)
+{
+ unsigned level=0;
+ unsigned n=0;
+
+ string prefix=outname();
+ string xformat=getSetting<string>("xformat");
+
+ static long arg_max=sysconf(_SC_ARG_MAX);
+ const unsigned maxargs=::min(arg_max/(prefix.size()+xformat.size()+25ul),
+ 256ul);
+
+ cout << xformat << newl;
+ cout << maxargs << newl;
+
+ string preformat=nativeformat();
+ const string Done="Done";
+ const string Error="Error";
+
+ ostringstream cmd;
+
+ // Enforce ghostscript limitations.
+ magnification=::max(magnification,0.0001);
+ real res=::min(::max(magnification*72.0,2.0),8192.0);
+
+ const char *converter=NULL, *hint=NULL;
+
+ bool png=xformat == "png";
+
+ if(magnification > 0.0) {
+ mem::list<string> nameStack;
+ string outname;
+ unsigned arg=0;
+ unsigned batch=0;
+ for(picture::nodelist::iterator p=f->nodes.begin();;) {
+ if(p == f->nodes.end()) break;
+ if(arg == 0) {
+ cmd.str("");
+ ostringstream buf;
+ buf << batch << "_";
+ outname=buildname(prefix+buf.str()+"%d",xformat,"");
+ if(png) {
+ cmd << "'" << getSetting<string>("gs")
+ << "' -q -dNOPAUSE -dBATCH -sDEVICE=pngalpha -dEPSCrop";
+ if(safe)
+ cmd << " -dSAFER";
+ cmd << " -r" << res << "x" << res
+ << " -sOutputFile='" << outname << "'";
+ converter="gs";
+ hint="Ghostscript";
+ } else {
+ cmd << "'" << getSetting<string>("convert")
+ << "' -density " << res << "x" << res
+ << " -transparent white";
+ hint=converter="convert";
+ }
+ }
+
+ picture *group=new picture;
+ xform->call(Stack);
+ transform t=pop<transform>(Stack);
+ assert(*p);
+ if((*p)->endgroup()) {
+ cout << Error << endl;
+ error(nobegin);
+ }
+ if((*p)->begingroup()) {
+ ++level;
+ while(p != f->nodes.end() && level) {
+ drawElement *e=t.isIdentity() ? *p : (*p)->transformed(t);
+ group->append(e);
+ ++p;
+ if(p == f->nodes.end()) break;
+ assert(*p);
+ if((*p)->begingroup()) ++level;
+ if((*p)->endgroup()) {
+ if(level) --level;
+ else {
+ cout << Error << endl;
+ error(nobegin);
+ }
+ }
+ }
+ }
+ if(p != f->nodes.end()) {
+ assert(*p);
+ drawElement *e=t.isIdentity() ? *p : (*p)->transformed(t);
+ group->append(e);
+ bbox b;
+ ostringstream buf;
+ buf << prefix << "_" << n;
+ group->shipout(preamble,buf.str(),preformat,magnification,false,false);
+ string Preformat=png && group->Transparency() ? "pdf" : preformat;
+ string name=buildname(buf.str(),Preformat);
+ nameStack.push_back(name);
+ cmd << " '";
+ if(!png) cmd << preformat+":";
+ cmd << name << "'";
+ b=group->bounds();
+ b *= magnification;
+
+ cout << b << newl;
+ ++n;
+ ++p;
+ ++arg;
+ }
+
+ if(p == f->nodes.end() || arg >= maxargs) {
+ arg=0;
+ ++batch;
+ cout.flush();
+ if(!png)
+ cmd << " -scene 1 '" << xformat << ":" << outname << "'";
+
+ int status=System(cmd,0,true,converter,hint);
+ if(status) {
+ cout << Error << endl;
+ error("deconstruct failed");
+ }
+ }
+ }
+
+ if(!getSetting<bool>("keep")) {
+ for(mem::list<string>::iterator p=nameStack.begin();
+ p != nameStack.end(); ++p)
+ unlink(p->c_str());
+ }
+
+ cout << Done << endl;
+ }
+}
+
+void purge(Int divisor=0)
+{
+ purge(divisor);
+}
+
+
+// Pen operations
+
+pen :newPen()
+{
+ return pen();
+}
+
+bool ==(pen a, pen b)
+{
+ return a == b;
+}
+
+bool !=(pen a, pen b)
+{
+ return a != b;
+}
+
+pen +(pen a, pen b)
+{
+ return a+b;
+}
+
+pen Operator *(real a, pen b)
+{
+ return a*b;
+}
+
+pen Operator *(pen a, real b)
+{
+ return b*a;
+}
+
+pair max(pen p)
+{
+ return p.bounds().Max();
+}
+
+pair min(pen p)
+{
+ return p.bounds().Min();
+}
+
+// Reset the meaning of pen default attributes.
+void resetdefaultpen()
+{
+ processData().defaultpen=camp::pen::initialpen();
+}
+
+void defaultpen(pen p)
+{
+ processData().defaultpen=pen(resolvepen,p);
+}
+
+pen defaultpen()
+{
+ return processData().defaultpen;
+}
+
+bool invisible(pen p)
+{
+ return p.invisible();
+}
+
+pen invisible()
+{
+ return pen(invisiblepen);
+}
+
+pen gray(pen p)
+{
+ p.togrey();
+ return p;
+}
+
+pen rgb(pen p)
+{
+ p.torgb();
+ return p;
+}
+
+pen cmyk(pen p)
+{
+ p.tocmyk();
+ return p;
+}
+
+pen interp(pen a, pen b, real t)
+{
+ return interpolate(a,b,t);
+}
+
+pen rgb(real r, real g, real b)
+{
+ return pen(r,g,b);
+}
+
+pen cmyk(real c, real m, real y, real k)
+{
+ return pen(c,m,y,k);
+}
+
+pen gray(real gray)
+{
+ return pen(gray);
+}
+
+realarray *colors(pen p)
+{
+ size_t n=ColorComponents[p.colorspace()];
+ array *a=new array(n);
+
+ switch(n) {
+ case 0:
+ break;
+ case 1:
+ (*a)[0]=p.gray();
+ break;
+ case 3:
+ (*a)[0]=p.red();
+ (*a)[1]=p.green();
+ (*a)[2]=p.blue();
+ break;
+ case 4:
+ (*a)[0]=p.cyan();
+ (*a)[1]=p.magenta();
+ (*a)[2]=p.yellow();
+ (*a)[3]=p.black();
+ break;
+ default:
+ break;
+ }
+ return a;
+}
+
+string colorspace(pen p)
+{
+ string s=ColorDeviceSuffix[p.colorspace()];
+ std::transform(s.begin(),s.end(),s.begin(),tolower);
+ return s;
+}
+
+pen pattern(string *s)
+{
+ return pen(setpattern,*s);
+}
+
+string pattern(pen p)
+{
+ return p.fillpattern();
+}
+
+pen fillrule(Int n)
+{
+ return pen(n >= 0 && n < nFill ? (FillRule) n : DEFFILL);
+}
+
+Int fillrule(pen p)
+{
+ return p.Fillrule();
+}
+
+pen opacity(real opacity=1.0, string blend=defaulttransparency)
+{
+ for(Int i=0; i < nBlendMode; ++i)
+ if(blend == BlendMode[i]) return pen(Transparency(blend,opacity));
+
+ ostringstream buf;
+ buf << "Unknown blend mode: " << "'" << blend << "'";
+ error(buf);
+}
+
+real opacity(pen p)
+{
+ return p.opacity();
+}
+
+string blend(pen p)
+{
+ return p.blend();
+}
+
+pen linetype(string *s, real offset=0, bool scale=true, bool adjust=true)
+{
+ return pen(LineType(*s,offset,scale,adjust));
+}
+
+string linetype(pen p=CURRENTPEN)
+{
+ return p.stroke();
+}
+
+real offset(pen p)
+{
+ return p.linetype().offset;
+}
+
+bool scale(pen p)
+{
+ return p.linetype().scale;
+}
+
+bool adjust(pen p)
+{
+ return p.linetype().adjust;
+}
+
+pen adjust(pen p, real arclength, bool cyclic)
+{
+ return adjustdash(p,arclength,cyclic);
+}
+
+pen linecap(Int n)
+{
+ return pen(setlinecap,n >= 0 && n < nCap ? n : DEFCAP);
+}
+
+Int linecap(pen p=CURRENTPEN)
+{
+ return p.cap();
+}
+
+pen linejoin(Int n)
+{
+ return pen(setlinejoin,n >= 0 && n < nJoin ? n : DEFJOIN);
+}
+
+Int linejoin(pen p=CURRENTPEN)
+{
+ return p.join();
+}
+
+pen miterlimit(real x)
+{
+ return pen(setmiterlimit,x >= 1.0 ? x : DEFJOIN);
+}
+
+real miterlimit(pen p=CURRENTPEN)
+{
+ return p.miter();
+}
+
+pen linewidth(real x)
+{
+ return pen(setlinewidth,x >= 0.0 ? x : DEFWIDTH);
+}
+
+real linewidth(pen p=CURRENTPEN)
+{
+ return p.width();
+}
+
+pen fontcommand(string *s)
+{
+ return pen(setfont,*s);
+}
+
+string font(pen p=CURRENTPEN)
+{
+ return p.Font();
+}
+
+pen fontsize(real size, real lineskip)
+{
+ return pen(setfontsize,size > 0.0 ? size : 0.0,
+ lineskip > 0.0 ? lineskip : 0.0);
+}
+
+real fontsize(pen p=CURRENTPEN)
+{
+ return p.size();
+}
+
+real lineskip(pen p=CURRENTPEN)
+{
+ return p.Lineskip();
+}
+
+pen overwrite(Int n)
+{
+ return pen(setoverwrite,n >= 0 && n < nOverwrite ? (overwrite_t) n :
+ DEFWRITE);
+}
+
+Int overwrite(pen p=CURRENTPEN)
+{
+ return p.Overwrite();
+}
+
+pen basealign(Int n)
+{
+ return pen(n >= 0 && n < nBaseLine ? (BaseLine) n : DEFBASE);
+}
+
+Int basealign(pen p=CURRENTPEN)
+{
+ return p.Baseline();
+}
+
+transform transform(pen p)
+{
+ return p.getTransform();
+}
+
+path nib(pen p)
+{
+ return p.Path();
+}
+
+pen makepen(path p)
+{
+ return pen(p);
+}
+
+pen colorless(pen p)
+{
+ p.colorless();
+ return p;
+}
+
+// Interactive mode
+
+bool interactive()
+{
+ return interact::interactive;
+}
+
+bool uptodate()
+{
+ return interact::uptodate;
+}
+
+
+// System commands
+
+Int system(string s)
+{
+ if(safe) error("system() call disabled; override with option -nosafe");
+ if(s.empty()) return 0;
+ else return System(s.c_str());
+}
+
+bool view()
+{
+ return view();
+}
+
+string asydir()
+{
+ return systemDir;
+}
+
+string locale(string s=emptystring)
+{
+ char *L=setlocale(LC_ALL,s.empty() ? NULL : s.c_str());
+ return L != NULL ? string(L) : "";
+}
+
+void abort(string s=emptystring)
+{
+ if(s.empty()) throw handled_error();
+ error(s.c_str());
+}
+
+void exit()
+{
+ throw quit();
+}
+
+void assert(bool b, string s=emptystring)
+{
+ flush(cout);
+ if(!b) {
+ ostringstream buf;
+ buf << "assert FAILED";
+ if(s != "") buf << ": " << s << endl;
+ error(buf);
+ }
+}
+
+void sleep(Int seconds)
+{
+ if(seconds <= 0) return;
+ sleep(seconds);
+}
+
+void usleep(Int microseconds)
+{
+ if(microseconds <= 0) return;
+ usleep((unsigned long) microseconds);
+}
+
+void _eval(string *s, bool embedded, bool interactiveWrite=false)
+{
+ if (embedded) {
+ trans::coenv *e=Stack->getEnvironment();
+ vm::interactiveStack *is=dynamic_cast<vm::interactiveStack *>(Stack);
+ if (e && is) {
+ runStringEmbedded(*s, *e, *is);
+ } else {
+ cerr << "no runtime environment for embedded eval" << endl;
+ }
+ } else {
+ runString(*s,interactiveWrite);
+ }
+}
+
+void _eval(runnable *s, bool embedded)
+{
+ absyntax::block *ast=new absyntax::block(s->getPos(), false);
+ ast->add(s);
+
+ if (embedded) {
+ trans::coenv *e=Stack->getEnvironment();
+ vm::interactiveStack *is=dynamic_cast<vm::interactiveStack *>(Stack);
+ if (e && is) {
+ runCodeEmbedded(ast, *e, *is);
+ } else {
+ cerr << "no runtime environment for embedded eval" << endl;
+ }
+ } else {
+ runCode(ast);
+ }
+}
+
+string location() {
+ ostringstream buf;
+ buf << getPos();
+ return buf.str();
+}
+
+// Wrapper for the stack::load() method.
+void :loadModule(string *index)
+{
+ Stack->load(*index);
+}
+
+string cd(string s=emptystring)
+{
+ if(!s.empty() && !globalwrite()) writeDisabled();
+ return setPath(s.c_str());
+}
+
+void list(string *s, bool imports=false)
+{
+ if(*s == "-") return;
+ trans::genv ge;
+ symbol *name=symbol::trans(*s);
+ record *r=ge.getModule(name,*s);
+ r->e.list(imports ? 0 : r);
+}
+
+
+// Path operations
+
+path :nullPath()
+{
+ return nullpath;
+}
+
+bool ==(path a, path b)
+{
+ return a == b;
+}
+
+bool !=(path a, path b)
+{
+ return !(a == b);
+}
+
+pair point(path p, Int t)
+{
+ return p.point((Int) t);
+}
+
+pair point(path p, real t)
+{
+ return p.point(t);
+}
+
+pair precontrol(path p, Int t)
+{
+ return p.precontrol((Int) t);
+}
+
+pair precontrol(path p, real t)
+{
+ return p.precontrol(t);
+}
+
+pair postcontrol(path p, Int t)
+{
+ return p.postcontrol((Int) t);
+}
+
+pair postcontrol(path p, real t)
+{
+ return p.postcontrol(t);
+}
+
+pair dir(path p, Int t, Int sign=0, bool normalize=true)
+{
+ return p.dir(t,sign,normalize);
+}
+
+pair dir(path p, real t, bool normalize=true)
+{
+ return p.dir(t,normalize);
+}
+
+pair accel(path p, Int t, Int sign=0)
+{
+ return p.accel(t,sign);
+}
+
+pair accel(path p, real t)
+{
+ return p.accel(t);
+}
+
+real radius(path p, real t)
+{
+ pair v=p.dir(t,false);
+ pair a=p.accel(t);
+ real d=dot(a,v);
+ real v2=v.abs2();
+ real a2=a.abs2();
+ real denom=v2*a2-d*d;
+ real r=v2*sqrt(v2);
+ return denom > 0 ? r/sqrt(denom) : 0.0;
+}
+
+path reverse(path p)
+{
+ return p.reverse();
+}
+
+path subpath(path p, Int a, Int b)
+{
+ return p.subpath((Int) a, (Int) b);
+}
+
+path subpath(path p, real a, real b)
+{
+ return p.subpath(a,b);
+}
+
+path nurb(pair z0, pair z1, pair z2, pair z3,
+ real w0, real w1, real w2, real w3, Int m)
+{
+ return nurb(z0,z1,z2,z3,w0,w1,w2,w3,m);
+}
+
+Int length(path p)
+{
+ return p.length();
+}
+
+bool cyclic(path p)
+{
+ return p.cyclic();
+}
+
+bool straight(path p, Int t)
+{
+ return p.straight(t);
+}
+
+path unstraighten(path p)
+{
+ return p.unstraighten();
+}
+
+bool piecewisestraight(path p)
+{
+ return p.piecewisestraight();
+}
+
+real arclength(path p)
+{
+ return p.arclength();
+}
+
+real arctime(path p, real dval)
+{
+ return p.arctime(dval);
+}
+
+real dirtime(path p, pair z)
+{
+ return p.directiontime(z);
+}
+
+realarray* intersect(path p, path q, real fuzz=-1)
+{
+ bool exact=fuzz <= 0.0;
+ if(fuzz < 0)
+ fuzz=BigFuzz*::max(::max(length(p.max()),length(p.min())),
+ ::max(length(q.max()),length(q.min())));
+ std::vector<real> S,T;
+ real s,t;
+ if(intersections(s,t,S,T,p,q,fuzz,true,exact)) {
+ array *V=new array(2);
+ (*V)[0]=s;
+ (*V)[1]=t;
+ return V;
+ } else
+ return new array(0);
+}
+
+realarray2* intersections(path p, path q, real fuzz=-1)
+{
+ bool exact=fuzz <= 0.0;
+ if(fuzz < 0.0)
+ fuzz=BigFuzz*::max(::max(length(p.max()),length(p.min())),
+ ::max(length(q.max()),length(q.min())));
+ real s,t;
+ std::vector<real> S,T;
+ intersections(s,t,S,T,p,q,fuzz,false,true);
+ size_t n=S.size();
+ if(n == 0 && !exact) {
+ if(intersections(s,t,S,T,p,q,fuzz,true,false)) {
+ array *V=new array(1);
+ array *Vi=new array(2);
+ (*V)[0]=Vi;
+ (*Vi)[0]=s;
+ (*Vi)[1]=t;
+ return V;
+ }
+ }
+ array *V=new array(n);
+ for(size_t i=0; i < n; ++i) {
+ array *Vi=new array(2);
+ (*V)[i]=Vi;
+ (*Vi)[0]=S[i];
+ (*Vi)[1]=T[i];
+ }
+ stable_sort(V->begin(),V->end(),run::compare2<real>());
+ return V;
+}
+
+realarray* intersections(path p, explicit pair a, explicit pair b, real fuzz=-1)
+{
+ if(fuzz < 0)
+ fuzz=BigFuzz*::max(::max(length(p.max()),length(p.min())),
+ ::max(length(a),length(b)));
+ std::vector<real> S;
+ intersections(S,p,a,b,fuzz);
+ sort(S.begin(),S.end());
+ size_t n=S.size();
+ array *V=new array(n);
+ for(size_t i=0; i < n; ++i)
+ (*V)[i]=S[i];
+ return V;
+}
+
+// Return the intersection point of the extensions of the line segments
+// PQ and pq.
+pair extension(pair P, pair Q, pair p, pair q)
+{
+ pair ac=P-Q;
+ pair bd=q-p;
+ real det=ac.getx()*bd.gety()-ac.gety()*bd.getx();
+ if(det == 0) return pair(infinity,infinity);
+ return P+((p.getx()-P.getx())*bd.gety()-(p.gety()-P.gety())*bd.getx())*ac/det;
+}
+
+Int size(path p)
+{
+ return p.size();
+}
+
+path &(path p, path q)
+{
+ return camp::concat(p,q);
+}
+
+pair min(path p)
+{
+ return p.min();
+}
+
+pair max(path p)
+{
+ return p.max();
+}
+
+realarray *mintimes(path p)
+{
+ array *V=new array(2);
+ pair z=p.mintimes();
+ (*V)[0]=z.getx();
+ (*V)[1]=z.gety();
+ return V;
+}
+
+realarray *maxtimes(path p)
+{
+ array *V=new array(2);
+ pair z=p.maxtimes();
+ (*V)[0]=z.getx();
+ (*V)[1]=z.gety();
+ return V;
+}
+
+real relativedistance(real theta, real phi, real t, bool atleast)
+{
+ return camp::velocity(theta,phi,tension(t,atleast));
+}
+
+Int windingnumber(patharray *p, pair z)
+{
+ return windingnumber(p,z);
+}
+
+bool inside(explicit patharray *g, pair z, pen fillrule=CURRENTPEN)
+{
+ return fillrule.inside(windingnumber(g,z));
+}
+
+bool inside(path g, pair z, pen fillrule=CURRENTPEN)
+{
+ return fillrule.inside(g.windingnumber(z));
+}
+
+// Determine the side of a--b that c lies on
+// (negative=left, zero=on line, positive=right).
+real side(pair a, pair b, pair c)
+{
+ return orient2d(a,b,c);
+}
+
+// Determine the side of the counterclockwise circle through a,b,c that d
+// lies on (negative=inside, 0=on circle, positive=right).
+real incircle(pair a, pair b, pair c, pair d)
+{
+ return incircle(a.getx(),a.gety(),b.getx(),b.gety(),c.getx(),c.gety(),
+ d.getx(),d.gety());
+}
+
+
+// Path3 operations
+
+path3 path3(triplearray *pre, triplearray *point, triplearray *post,
+ boolarray *straight, bool cyclic)
+{
+ size_t n=checkArrays(pre,point);
+ checkEqual(n,checkArray(post));
+ checkEqual(n,checkArray(straight));
+ mem::vector<solvedKnot3> nodes(n);
+ for(size_t i=0; i < n; ++i) {
+ nodes[i].pre=read<triple>(pre,i);
+ nodes[i].point=read<triple>(point,i);
+ nodes[i].post=read<triple>(post,i);
+ nodes[i].straight=read<bool>(straight,i);
+ }
+
+ return path3(nodes,(Int) n,cyclic);
+}
+
+path3 :nullPath3()
+{
+ return nullpath3;
+}
+
+bool ==(path3 a, path3 b)
+{
+ return a == b;
+}
+
+bool !=(path3 a, path3 b)
+{
+ return !(a == b);
+}
+
+triple point(path3 p, Int t)
+{
+ return p.point((Int) t);
+}
+
+triple point(path3 p, real t)
+{
+ return p.point(t);
+}
+
+triple precontrol(path3 p, Int t)
+{
+ return p.precontrol((Int) t);
+}
+
+triple precontrol(path3 p, real t)
+{
+ return p.precontrol(t);
+}
+
+triple postcontrol(path3 p, Int t)
+{
+ return p.postcontrol((Int) t);
+}
+
+triple postcontrol(path3 p, real t)
+{
+ return p.postcontrol(t);
+}
+
+triple dir(path3 p, Int t, Int sign=0, bool normalize=true)
+{
+ return p.dir(t,sign,normalize);
+}
+
+triple dir(path3 p, real t, bool normalize=true)
+{
+ return p.dir(t,normalize);
+}
+
+triple accel(path3 p, Int t, Int sign=0)
+{
+ return p.accel(t,sign);
+}
+
+triple accel(path3 p, real t)
+{
+ return p.accel(t);
+}
+
+real radius(path3 p, real t)
+{
+ triple v=p.dir(t,false);
+ triple a=p.accel(t);
+ real d=dot(a,v);
+ real v2=v.abs2();
+ real a2=a.abs2();
+ real denom=v2*a2-d*d;
+ real r=v2*sqrt(v2);
+ return denom > 0 ? r/sqrt(denom) : 0.0;
+}
+
+real radius(triple z0, triple c0, triple c1, triple z1, real t)
+{
+ triple v=(3.0*(z1-z0)+9.0*(c0-c1))*t*t+(6.0*(z0+c1)-12.0*c0)*t+3.0*(c0-z0);
+ triple a=6.0*(z1-z0+3.0*(c0-c1))*t+6.0*(z0+c1)-12.0*c0;
+ real d=dot(a,v);
+ real v2=v.abs2();
+ real a2=a.abs2();
+ real denom=v2*a2-d*d;
+ real r=v2*sqrt(v2);
+ return denom > 0 ? r/sqrt(denom) : 0.0;
+}
+
+path3 reverse(path3 p)
+{
+ return p.reverse();
+}
+
+path3 subpath(path3 p, Int a, Int b)
+{
+ return p.subpath((Int) a, (Int) b);
+}
+
+path3 subpath(path3 p, real a, real b)
+{
+ return p.subpath(a,b);
+}
+
+Int length(path3 p)
+{
+ return p.length();
+}
+
+bool cyclic(path3 p)
+{
+ return p.cyclic();
+}
+
+bool straight(path3 p, Int t)
+{
+ return p.straight(t);
+}
+
+// Return the component of vector v perpendicular to a unit vector u.
+triple perp(triple v, triple u)
+{
+ return v-dot(v,u)*u;
+}
+
+// Return the maximum perpendicular deviation of segment i of path3 g
+// from a straight line.
+real straightness(path3 p, Int t)
+{
+ 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 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)
+{
+ triple u=unit(z1-z0);
+ return ::max(length(perp(c0-z0,u)),length(perp(c1-z0,u)));
+}
+
+bool piecewisestraight(path3 p)
+{
+ return p.piecewisestraight();
+}
+
+real arclength(path3 p)
+{
+ return p.arclength();
+}
+
+real arctime(path3 p, real dval)
+{
+ return p.arctime(dval);
+}
+
+realarray* intersect(path3 p, path3 q, real fuzz=-1)
+{
+ bool exact=fuzz <= 0.0;
+ if(fuzz < 0)
+ fuzz=BigFuzz*::max(::max(length(p.max()),length(p.min())),
+ ::max(length(q.max()),length(q.min())));
+
+ std::vector<real> S,T;
+ real s,t;
+ if(intersections(s,t,S,T,p,q,fuzz,true,exact)) {
+ array *V=new array(2);
+ (*V)[0]=s;
+ (*V)[1]=t;
+ return V;
+ } else
+ return new array(0);
+}
+
+realarray2* intersections(path3 p, path3 q, real fuzz=-1)
+{
+ bool exact=fuzz <= 0.0;
+ if(fuzz < 0)
+ fuzz=BigFuzz*::max(::max(length(p.max()),length(p.min())),
+ ::max(length(q.max()),length(q.min())));
+ bool single=!exact;
+
+ real s,t;
+ std::vector<real> S,T;
+ bool found=intersections(s,t,S,T,p,q,fuzz,single,exact);
+ if(!found) return new array(0);
+ array *V;
+ if(single) {
+ V=new array(1);
+ array *Vi=new array(2);
+ (*V)[0]=Vi;
+ (*Vi)[0]=s;
+ (*Vi)[1]=t;
+ } else {
+ size_t n=S.size();
+ V=new array(n);
+ for(size_t i=0; i < n; ++i) {
+ array *Vi=new array(2);
+ (*V)[i]=Vi;
+ (*Vi)[0]=S[i];
+ (*Vi)[1]=T[i];
+ }
+ }
+ stable_sort(V->begin(),V->end(),run::compare2<real>());
+ return V;
+}
+
+Int size(path3 p)
+{
+ return p.size();
+}
+
+path3 &(path3 p, path3 q)
+{
+ return camp::concat(p,q);
+}
+
+triple min(path3 p)
+{
+ return p.min();
+}
+
+triple max(path3 p)
+{
+ return p.max();
+}
+
+realarray *mintimes(path3 p)
+{
+ array *V=new array(3);
+ triple v=p.mintimes();
+ (*V)[0]=v.getx();
+ (*V)[1]=v.gety();
+ (*V)[2]=v.getz();
+ return V;
+}
+
+realarray *maxtimes(path3 p)
+{
+ array *V=new array(3);
+ triple v=p.maxtimes();
+ (*V)[0]=v.getx();
+ (*V)[1]=v.gety();
+ (*V)[2]=v.getz();
+ return V;
+}
+
+path3 Operator *(realarray2 *t, path3 g)
+{
+ return transformed(*t,g);
+}
+
+
+// Guide operations
+
+guide* :nullGuide()
+{
+ return new pathguide(path());
+}
+
+guide* :dotsGuide(guidearray *a)
+{
+ guidevector v;
+ size_t size=checkArray(a);
+ for (size_t i=0; i < size; ++i)
+ v.push_back(a->read<guide*>(i));
+
+ return new multiguide(v);
+}
+
+guide* :dashesGuide(guidearray *a)
+{
+ static camp::curlSpec curly;
+ static specguide curlout(&curly, camp::OUT);
+ static specguide curlin(&curly, camp::IN);
+
+ size_t n=checkArray(a);
+
+ // a--b is equivalent to a{curl 1}..{curl 1}b
+ guidevector v;
+ if (n > 0)
+ v.push_back(a->read<guide*>(0));
+
+ if (n==1) {
+ v.push_back(&curlout);
+ v.push_back(&curlin);
+ }
+ else
+ for (size_t i=1; i<n; ++i) {
+ v.push_back(&curlout);
+ v.push_back(&curlin);
+ v.push_back(a->read<guide*>(i));
+ }
+
+ return new multiguide(v);
+}
+
+cycleToken :newCycleToken()
+{
+ return cycleToken();
+}
+
+guide *operator cast(cycleToken tok)
+{
+// Avoid unused variable warning messages.
+ unused(&tok);
+ return new cycletokguide();
+}
+
+guide* operator spec(pair z, Int p)
+{
+ camp::side d=(camp::side) p;
+ camp::dirSpec *sp=new camp::dirSpec(z);
+
+ return new specguide(sp,d);
+}
+
+curlSpecifier operator curl(real gamma, Int p)
+{
+ camp::side s=(camp::side) p;
+ return curlSpecifier(gamma,s);
+}
+
+real :curlSpecifierValuePart(curlSpecifier spec)
+{
+ return spec.getValue();
+}
+
+Int :curlSpecifierSidePart(curlSpecifier spec)
+{
+ return spec.getSide();
+}
+
+guide *operator cast(curlSpecifier spec)
+{
+ return new specguide(spec);
+}
+
+tensionSpecifier operator tension(real tout, real tin, bool atleast)
+{
+ return tensionSpecifier(tout, tin, atleast);
+}
+
+real :tensionSpecifierOutPart(tensionSpecifier t)
+{
+ return t.getOut();
+}
+
+real :tensionSpecifierInPart(tensionSpecifier t)
+{
+ return t.getIn();
+}
+
+bool :tensionSpecifierAtleastPart(tensionSpecifier t)
+{
+ return t.getAtleast();
+}
+
+guide *operator cast(tensionSpecifier t)
+{
+ return new tensionguide(t);
+}
+
+guide* operator controls(pair zout, pair zin)
+{
+ return new controlguide(zout, zin);
+}
+
+Int size(guide *g)
+{
+ flatguide f;
+ g->flatten(f,false);
+ return f.size();
+}
+
+Int length(guide *g)
+{
+ flatguide f;
+ g->flatten(f,false);
+ return g->cyclic() ? f.size() : f.size()-1;
+}
+
+bool cyclic(guide *g)
+{
+ flatguide f;
+ g->flatten(f,false);
+ return g->cyclic();
+}
+
+pair point(guide *g, Int t)
+{
+ flatguide f;
+ g->flatten(f,false);
+ return f.Nodes(adjustedIndex(t,f.size(),g->cyclic())).z;
+}
+
+pairarray *dirSpecifier(guide *g, Int t)
+{
+ flatguide f;
+ g->flatten(f,false);
+ Int n=f.size();
+ if(!g->cyclic() && (t < 0 || t >= n-1)) return new array(0);
+ array *c=new array(2);
+ (*c)[0]=f.Nodes(t).out->dir();
+ (*c)[1]=f.Nodes(t+1).in->dir();
+ return c;
+}
+
+pairarray *controlSpecifier(guide *g, Int t)
+{
+ flatguide f;
+ g->flatten(f,false);
+ Int n=f.size();
+ if(!g->cyclic() && (t < 0 || t >= n-1)) return new array(0);
+ knot curr=f.Nodes(t);
+ knot next=f.Nodes(t+1);
+ if(curr.out->controlled()) {
+ assert(next.in->controlled());
+ array *c=new array(2);
+ (*c)[0]=curr.out->control();
+ (*c)[1]=next.in->control();
+ return c;
+ } else return new array(0);
+}
+
+tensionSpecifier tensionSpecifier(guide *g, Int t)
+{
+ flatguide f;
+ g->flatten(f,false);
+ Int n=f.size();
+ if(!g->cyclic() && (t < 0 || t >= n-1)) return tensionSpecifier(1.0,1.0,false);
+ knot curr=f.Nodes(t);
+ return tensionSpecifier(curr.tout.val,f.Nodes(t+1).tin.val,curr.tout.atleast);
+}
+
+realarray *curlSpecifier(guide *g, Int t)
+{
+ flatguide f;
+ g->flatten(f,false);
+ Int n=f.size();
+ if(!g->cyclic() && (t < 0 || t >= n-1)) return new array(0);
+ array *c=new array(2);
+ real c0=f.Nodes(t).out->curl();
+ real c1=f.Nodes(t+1).in->curl();
+ (*c)[0]=c0 >= 0.0 ? c0 : 1.0;
+ (*c)[1]=c1 >= 0.0 ? c1 : 1.0;
+ return c;
+}
+
+guide *reverse(guide *g)
+{
+ flatguide f;
+ g->flatten(f,false);
+ if(f.precyclic())
+ return new pathguide(g->solve().reverse());
+
+ size_t n=f.size();
+ bool cyclic=g->cyclic();
+ guidevector v;
+ if(n >= 0) {
+ size_t start=cyclic ? n : n-1;
+ knot curr=f.Nodes(start);
+ knot next;
+ for(size_t i=start; i > 0; --i) {
+ next=f.Nodes(i-1);
+ v.push_back(new pairguide(curr.z));
+ if(next.out->controlled()) {
+ assert(curr.in->controlled());
+ v.push_back(new controlguide(curr.in->control(),next.out->control()));
+ } else {
+ pair d=curr.in->dir();
+ if(d != zero)
+ v.push_back(new specguide(new dirSpec(-d),camp::OUT));
+ else {
+ real C=curr.in->curl();
+ if(C >= 0.0)
+ v.push_back(new specguide(new curlSpec(C),camp::OUT));
+ }
+ real tout=curr.tin.val;
+ real tin=next.tout.val;
+ bool atleast=next.tout.atleast;
+ if(tout != 1.0 || tin != 1.0 || next.tout.atleast)
+ v.push_back(new tensionguide(tensionSpecifier(tout,tin,atleast)));
+ d=next.out->dir();
+ if(d != zero)
+ v.push_back(new specguide(new dirSpec(-d),camp::IN));
+ else {
+ real C=next.out->curl();
+ if(C >= 0.0)
+ v.push_back(new specguide(new curlSpec(C),camp::IN));
+ }
+ }
+ curr=next;
+ }
+ if(cyclic)
+ v.push_back(new cycletokguide());
+ else
+ v.push_back(new pairguide(next.z));
+
+ }
+ return new multiguide(v);
+}
+
+
+// Three-dimensional picture and surface operations
+
+void _draw(picture *f, path3 g, pen p)
+{
+ f->append(new drawPath3(g,p));
+}
+
+void draw(picture *f, triplearray2 *g, bool straight, penarray *p, real opacity,
+ real shininess, real granularity, triple normal, bool lighton,
+ penarray *colors)
+{
+ f->append(new drawSurface(*g,straight,*p,opacity,shininess,granularity,
+ normal,lighton,*colors));
+}
+
+triple min3(picture *f)
+{
+ return f->bounds3().Min();
+}
+
+triple max3(picture *f)
+{
+ return f->bounds3().Max();
+}
+
+pair min(picture *f, realarray2 *t)
+{
+ real *T=copyArray2C(t,4);
+ pair m=f->bounds(::min,xproject,yproject,T);
+ delete[] T;
+ return m;
+}
+
+pair max(picture *f, realarray2 *t)
+{
+ real *T=copyArray2C(t,4);
+ pair M=f->bounds(::max,xproject,yproject,T);
+ delete[] T;
+ return M;
+}
+
+pair minratio(picture *f)
+{
+ return f->bounds(::min,xratio,yratio);
+}
+
+pair maxratio(picture *f)
+{
+ return f->bounds(::max,xratio,yratio);
+}
+
+real minbound(realarray *a, real b)
+{
+ real *A=copyArrayC(a,16);
+ b=bound(A,::min,b);
+ delete[] A;
+ return b;
+}
+
+real maxbound(realarray *a, real b)
+{
+ real *A=copyArrayC(a,16);
+ b=bound(A,::max,b);
+ delete[] A;
+ return b;
+}
+
+pair minbound(triplearray *a, realarray2 *t, pair b)
+{
+ triple *A=copyTripleArrayC(a,16);
+ real *T=copyArray2C(t,4);
+ b=pair(bound(A,::min,xproject,T,b.getx()),
+ bound(A,::min,yproject,T,b.gety()));
+ delete[] T;
+ delete[] A;
+ return b;
+}
+
+pair maxbound(triplearray *a, realarray2 *t, pair b)
+{
+ triple *A=copyTripleArrayC(a,16);
+ real *T=copyArray2C(t,4);
+ b=pair(bound(A,::max,xproject,T,b.getx()),
+ bound(A,::max,yproject,T,b.gety()));
+ delete[] T;
+ delete[] A;
+ return b;
+}
+
+pair max(path3 g, realarray2 *t)
+{
+ real *T=copyArray2C(t,4);
+ pair b=g.bounds(::max,xproject,yproject,T);
+ delete[] T;
+ return b;
+}
+
+pair min(path3 g, realarray2 *t)
+{
+ real *T=copyArray2C(t,4);
+ pair b=g.bounds(::min,xproject,yproject,T);
+ delete[] T;
+ return b;
+}
+
+real change2(triplearray2 *a)
+{
+ size_t n=checkArray(a);
+ if(n == 0) return 0.0;
+
+ vm::array *a0=vm::read<vm::array*>(a,0);
+ size_t m=checkArray(a0);
+ if(m == 0) return 0.0;
+ triple a00=vm::read<triple>(a0,0);
+ real M=0.0;
+
+ for(size_t i=0; i < n; ++i) {
+ vm::array *ai=vm::read<vm::array*>(a,i);
+ size_t m=checkArray(ai);
+ for(size_t j=0; j < m; ++j) {
+ real a=(vm::read<triple>(ai,j)-a00).abs2();
+ if(a > M) M=a;
+ }
+ }
+ return M;
+}
+
+bool is3D(picture *f)
+{
+ return f->have3D();
+}
+
+pair bezier(pair a, pair b, pair c, pair d, real t)
+{
+ real onemt=1-t;
+ real onemt2=onemt*onemt;
+ return onemt2*onemt*a+t*(3.0*(onemt2*b+t*onemt*c)+t*t*d);
+}
+
+pair bezierP(pair a, pair b, pair c, pair d, real t)
+{
+ return 3.0*(t*t*(d-a+3.0*(b-c))+t*(2.0*(a+c)-4.0*b)+b-a);
+}
+
+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);
+}
+
+pair bezierPPP(pair a, pair b, pair c, pair d)
+{
+ return 6.0*(d-a+3.0*(b-c));
+}
+
+triple bezier(triple a, triple b, triple c, triple d, real t)
+{
+ real onemt=1-t;
+ real onemt2=onemt*onemt;
+ return onemt2*onemt*a+t*(3.0*(onemt2*b+t*onemt*c)+t*t*d);
+}
+
+triple bezierP(triple a, triple b, triple c, triple d, real t)
+{
+ return 3.0*(t*t*(d-a+3.0*(b-c))+t*(2.0*(a+c)-4.0*b)+b-a);
+}
+
+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);
+}
+
+triple bezierPPP(triple a, triple b, triple c, triple d)
+{
+ return 6.0*(d-a+3.0*(b-c));
+}
+
+
+// String operations
+
+string :emptyString()
+{
+ return emptystring;
+}
+
+Int length(string *s)
+{
+ return (Int) s->length();
+}
+
+Int find(string *s, string t, Int pos=0)
+{
+ size_t n=s->find(t,pos);
+ return n == string::npos ? (Int) -1 : (Int) n;
+}
+
+Int rfind(string *s, string t, Int pos=-1)
+{
+ size_t n=s->rfind(t,pos);
+ return n == string::npos ? (Int) -1 : (Int) n;
+}
+
+string reverse(string s)
+{
+ reverse(s.begin(),s.end());
+ return s;
+}
+
+string insert(string s, Int pos, string t)
+{
+ if ((size_t) pos < s.length())
+ return s.insert(pos,t);
+ return s;
+}
+
+string substr(string* s, Int pos, Int n=-1)
+{
+ if ((size_t) pos < s->length())
+ return s->substr(pos,n);
+ return emptystring;
+}
+
+string erase(string s, Int pos, Int n)
+{
+ if ((size_t) pos < s.length())
+ return s.erase(pos,n);
+ return s;
+}
+
+string downcase(string s)
+{
+ std::transform(s.begin(),s.end(),s.begin(),tolower);
+ return s;
+}
+
+string upcase(string s)
+{
+ std::transform(s.begin(),s.end(),s.begin(),toupper);
+ return s;
+}
+
+// returns a string constructed by translating all occurrences of the string
+// from in an array of string pairs {from,to} to the string to in string s.
+string replace(string *S, stringarray2 *translate)
+{
+ size_t size=checkArray(translate);
+ for(size_t i=0; i < size; i++) {
+ array *a=read<array*>(translate,i);
+ checkArray(a);
+ }
+ const char *p=S->c_str();
+ ostringstream buf;
+ while(*p) {
+ for(size_t i=0; i < size;) {
+ array *a=read<array*>(translate,i);
+ string* from=read<string*>(a,0);
+ size_t len=from->length();
+ if(strncmp(p,from->c_str(),len) != 0) {i++; continue;}
+ buf << read<string>(a,1);
+ p += len;
+ if(*p == 0) return buf.str();
+ i=0;
+ }
+ buf << *(p++);
+ }
+ return buf.str();
+}
+
+string format(string *format, Int x)
+{
+ const char *f=format->c_str();
+
+ checkformat(f,true);
+
+ Int size=snprintf(NULL,0,f,x)+1;
+ if(size < 1) size=255; // Workaround for non-C99 compliant systems.
+ char *buf=new char[size];
+ snprintf(buf,size,f,x);
+ string s=string(buf);
+ delete[] buf;
+ return s;
+}
+
+string format(string *format, real x, string locale=emptystring)
+{
+ ostringstream out;
+
+ checkformat(format->c_str(),false);
+
+ const char *phantom="\\phantom{+}";
+ const char *p0=format->c_str();
+
+ const char *p=p0;
+ const char *start=NULL;
+ while (*p != 0) {
+ if(*p == '%') {
+ p++;
+ if(*p != '%') {start=p-1; break;}
+ }
+ out << *(p++);
+ }
+
+ if(!start) return out.str();
+
+ // Allow at most 1 argument
+ while (*p != 0) {
+ if(*p == '*' || *p == '$') return out.str();
+ if(isupper(*p) || islower(*p)) {p++; break;}
+ p++;
+ }
+
+ const char *tail=p;
+ string f=format->substr(start-p0,tail-start);
+
+ const char *oldlocale=NULL;
+ if(!locale.empty()) {
+ oldlocale=setlocale(LC_ALL,NULL);
+ if(oldlocale) oldlocale=StrdupNoGC(oldlocale);
+ setlocale(LC_ALL,locale.c_str());
+ }
+
+ Int size=snprintf(NULL,0,f.c_str(),x)+1;
+ if(size < 1) size=255; // Workaround for non-C99 compliant systems.
+ char *buf=new char[size];
+ snprintf(buf,size,f.c_str(),x);
+
+ if(oldlocale) {
+ setlocale(LC_ALL,oldlocale);
+ delete[] oldlocale;
+ }
+
+ bool trailingzero=f.find("#") < string::npos;
+ bool plus=f.find("+") < string::npos;
+ bool space=f.find(" ") < string::npos;
+
+ char *q=buf; // beginning of formatted number
+
+ if(*q == ' ') {
+ out << phantom;
+ q++;
+ }
+
+ const char decimal=*(localeconv()->decimal_point);
+
+ // Remove any spurious sign
+ if(*q == '-' || *q == '+') {
+ p=q+1;
+ bool zero=true;
+ while(*p != 0) {
+ if(!isdigit(*p) && *p != decimal) break;
+ if(isdigit(*p) && *p != '0') {zero=false; break;}
+ p++;
+ }
+ if(zero) {
+ q++;
+ if(plus || space) out << phantom;
+ }
+ }
+
+ const char *r=p=q;
+ bool dp=false;
+ while(*r != 0 && (isdigit(*r) || *r == decimal || *r == '+' || *r == '-')) {
+ if(*r == decimal) dp=true;
+ r++;
+ }
+ if(dp) { // Remove trailing zeros and/or decimal point
+ r--;
+ unsigned n=0;
+ while(r > q && *r == '0') {r--; n++;}
+ if(*r == decimal) {r--; n++;}
+ while(q <= r) out << *(q++);
+ if(!trailingzero) q += n;
+ }
+
+ bool zero=(r == p && *r == '0') && !trailingzero;
+
+ // Translate "E+/E-/e+/e-" exponential notation to TeX
+ while(*q != 0) {
+ if((*q == 'E' || *q == 'e') && (*(q+1) == '+' || *(q+1) == '-')) {
+ if(!zero) out << "\\!\\times\\!10^{";
+ bool plus=(*(q+1) == '+');
+ q++;
+ if(plus) q++;
+ if(*q == '-') out << *(q++);
+ while(*q == '0' && (zero || isdigit(*(q+1)))) q++;
+ while(isdigit(*q)) out << *(q++);
+ if(!zero)
+ out << "}";
+ break;
+ }
+ out << *(q++);
+ }
+
+ while(*tail != 0)
+ out << *(tail++);
+
+ delete[] buf;
+
+ return out.str();
+}
+
+Int hex(string s)
+{
+ istringstream is(s);
+ is.setf(std::ios::hex,std::ios::basefield);
+ Int value;
+ if(is && is >> value && ((is >> std::ws).eof())) return value;
+ ostringstream buf;
+ buf << "invalid hexidecimal cast from string \"" << s << "\"";
+ error(buf);
+}
+
+string string(Int x)
+{
+ ostringstream buf;
+ buf << x;
+ return buf.str();
+}
+
+string string(real x, Int digits=DBL_DIG)
+{
+ ostringstream buf;
+ buf.precision(digits);
+ buf << x;
+ return buf.str();
+}
+
+string time(string format=defaulttimeformat)
+{
+#ifdef HAVE_STRFTIME
+ const time_t bintime=time(NULL);
+ if(!strftime(Time,nTime,format.c_str(),localtime(&bintime))) return "";
+ return Time;
+#else
+ return format;
+#endif
+}
+
+string time(Int seconds, string format=defaulttimeformat)
+{
+#ifdef HAVE_STRFTIME
+ const time_t bintime=seconds;
+ if(!strftime(Time,nTime,format.c_str(),localtime(&bintime))) return "";
+ return Time;
+#else
+// Avoid unused variable warning messages
+ unused(&seconds);
+ return format;
+#endif
+}
+
+Int seconds(string t=emptystring, string format=emptystring)
+{
+#if defined(HAVE_STRPTIME)
+ const time_t bintime=time(NULL);
+ tm tm=*localtime(&bintime);
+ if(t != "" && !strptime(t.c_str(),format.c_str(),&tm)) return -1;
+ return (Int) mktime(&tm);
+#else
+ return -1;
+#endif
+}
+
+realarray *_cputime()
+{
+ static const real ticktime=1.0/sysconf(_SC_CLK_TCK);
+ struct tms buf;
+
+ ::times(&buf);
+ array *t=new array(4);
+ (*t)[0] = ((real) buf.tms_utime)*ticktime;
+ (*t)[1] = ((real) buf.tms_stime)*ticktime;
+ (*t)[2] = ((real) buf.tms_cutime)*ticktime;
+ (*t)[3] = ((real) buf.tms_cstime)*ticktime;
+ return t;
+}
+
+
+// Math
+
+real ^(real x, Int y)
+{
+ return pow(x,y);
+}
+
+pair ^(pair z, Int y)
+{
+ return pow(z,y);
+}
+
+Int quotient(Int x, Int y)
+{
+ if(y == 0) dividebyzero();
+ if(y == -1) return Negate(x);
+// Implementation-independent definition of integer division: round down
+ return (x-portableMod(x,y))/y;
+}
+
+Int abs(Int x)
+{
+ return Abs(x);
+}
+
+Int sgn(real x)
+{
+ return sgn(x);
+}
+
+Int rand()
+{
+ return rand();
+}
+
+void srand(Int seed)
+{
+ srand(intcast(seed));
+}
+
+// a random number uniformly distributed in the interval [0,1]
+real unitrand()
+{
+ return ((real) rand())/RAND_MAX;
+}
+
+Int ceil(real x)
+{
+ return Intcast(ceil(x));
+}
+
+Int floor(real x)
+{
+ return Intcast(floor(x));
+}
+
+Int round(real x)
+{
+ if(validInt(x)) return Round(x);
+ integeroverflow(0);
+}
+
+Int Ceil(real x)
+{
+ return Ceil(x);
+}
+
+Int Floor(real x)
+{
+ return Floor(x);
+}
+
+Int Round(real x)
+{
+ return Round(Intcap(x));
+}
+
+real fmod(real x, real y)
+{
+ if (y == 0.0) dividebyzero();
+ return fmod(x,y);
+}
+
+real atan2(real y, real x)
+{
+ return atan2(y,x);
+}
+
+real hypot(real x, real y)
+{
+ return hypot(x,y);
+}
+
+real remainder(real x, real y)
+{
+ return remainder(x,y);
+}
+
+real J(Int n, real x)
+{
+ return jn(n,x);
+}
+
+real Y(Int n, real x)
+{
+ return yn(n,x);
+}
+
+real erf(real x)
+{
+ return erf(x);
+}
+
+real erfc(real x)
+{
+ return erfc(x);
+}
+
+Int factorial(Int n) {
+ if(n < 0) error(invalidargument);
+ return factorial(n);
+}
+
+Int choose(Int n, Int k) {
+ if(n < 0 || k < 0 || k > n) error(invalidargument);
+ Int f=1;
+ Int r=n-k;
+ for(Int i=n; i > r; --i) {
+ if(f > Int_MAX/i) integeroverflow(0);
+ f=(f*i)/(n-i+1);
+ }
+ return f;
+}
+
+real gamma(real x)
+{
+#ifdef HAVE_TGAMMA
+ return tgamma(x);
+#else
+ real lg = lgamma(x);
+ return signgam*exp(lg);
+#endif
+}
+
+// Complex Gamma function
+pair gamma(explicit pair z)
+{
+ return gamma(z);
+}
+
+realarray *quadraticroots(real a, real b, real c)
+{
+ quadraticroots q(a,b,c);
+ array *roots=new array(q.roots);
+ if(q.roots >= 1) (*roots)[0]=q.t1;
+ if(q.roots == 2) (*roots)[1]=q.t2;
+ return roots;
+}
+
+pairarray *quadraticroots(explicit pair a, explicit pair b, explicit pair c)
+{
+ Quadraticroots q(a,b,c);
+ array *roots=new array(q.roots);
+ if(q.roots >= 1) (*roots)[0]=q.z1;
+ if(q.roots == 2) (*roots)[1]=q.z2;
+ return roots;
+}
+
+realarray *cubicroots(real a, real b, real c, real d)
+{
+ cubicroots q(a,b,c,d);
+ array *roots=new array(q.roots);
+ if(q.roots >= 1) (*roots)[0]=q.t1;
+ if(q.roots >= 2) (*roots)[1]=q.t2;
+ if(q.roots == 3) (*roots)[2]=q.t3;
+ return roots;
+}
+
+
+// Transforms
+
+bool ==(transform a, transform b)
+{
+ return a == b;
+}
+
+bool !=(transform a, transform b)
+{
+ return a != b;
+}
+
+transform +(transform a, transform b)
+{
+ return a+b;
+}
+
+transform Operator *(transform a, transform b)
+{
+ return a*b;
+}
+
+pair Operator *(transform t, pair z)
+{
+ return t*z;
+}
+
+path Operator *(transform t, path g)
+{
+ return transformed(t,g);
+}
+
+pen Operator *(transform t, pen p)
+{
+ return transformed(t,p);
+}
+
+picture * Operator *(transform t, picture *f)
+{
+ return transformed(t,f);
+}
+
+picture * Operator *(realarray2 *t, picture *f)
+{
+ return transformed(*t,f);
+}
+
+transform ^(transform t, Int n)
+{
+ transform T;
+ if(n < 0) {
+ n=-n;
+ t=inverse(t);
+ }
+ for(Int i=0; i < n; i++) T=T*t;
+ return T;
+}
+
+real :transformXPart(transform t)
+{
+ return t.getx();
+}
+
+real :transformYPart(transform t)
+{
+ return t.gety();
+}
+
+real :transformXXPart(transform t)
+{
+ return t.getxx();
+}
+
+real :transformXYPart(transform t)
+{
+ return t.getxy();
+}
+
+real :transformYXPart(transform t)
+{
+ return t.getyx();
+}
+
+real :transformYYPart(transform t)
+{
+ return t.getyy();
+}
+
+transform :real6ToTransform(real x, real y, real xx, real xy,
+ real yx, real yy)
+{
+ return transform(x,y,xx,xy,yx,yy);
+}
+
+transform shift(transform t)
+{
+ return transform(t.getx(),t.gety(),0,0,0,0);
+}
+
+transform shiftless(transform t)
+{
+ return transform(0,0,t.getxx(),t.getxy(),t.getyx(),t.getyy());
+}
+
+transform identity:transformIdentity()
+{
+ return identity;
+}
+
+transform inverse(transform t)
+{
+ return inverse(t);
+}
+
+transform shift(pair z)
+{
+ return shift(z);
+}
+
+transform shift(real x, real y)
+{
+ return shift(pair(x,y));
+}
+
+transform xscale(real x)
+{
+ return xscale(x);
+}
+
+transform yscale(real y)
+{
+ return yscale(y);
+}
+
+transform scale(real x)
+{
+ return scale(x);
+}
+
+transform scale(real x, real y)
+{
+ return xscale(x)*yscale(y);
+}
+
+transform slant(real s)
+{
+ return slant(s);
+}
+
+transform rotate(real angle, pair z=0)
+{
+ return rotatearound(z,radians(angle));
+}
+
+transform reflect(pair a, pair b)
+{
+ return reflectabout(a,b);
+}
+
+
+// Pair operations
+
+pair :pairZero()
+{
+ return zero;
+}
+
+pair :realRealToPair(real x, real y)
+{
+ return pair(x,y);
+}
+
+pair :pairNegate(pair z)
+{
+ return -z;
+}
+
+real xpart:pairXPart(pair z)
+{
+ return z.getx();
+}
+
+real ypart:pairYPart(pair z)
+{
+ return z.gety();
+}
+
+real length(pair z)
+{
+ return z.length();
+}
+
+real abs(pair z)
+{
+ return z.length();
+}
+
+pair sqrt(explicit pair z)
+{
+ return Sqrt(z);
+}
+
+// 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 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()));
+}
+
+// Convert degrees to radians.
+real radians(real degrees)
+{
+ return radians(degrees);
+}
+
+// Convert radians to degrees.
+real degrees(real radians)
+{
+ return degrees(radians);
+}
+
+// Convert radians to degrees in [0,360).
+real Degrees(real radians)
+{
+ return principalBranch(degrees(radians));
+}
+
+real Sin(real deg)
+{
+ return sin(radians(deg));
+}
+
+real Cos(real deg)
+{
+ return cos(radians(deg));
+}
+
+real Tan(real deg)
+{
+ return tan(radians(deg));
+}
+
+real aSin(real x)
+{
+ return degrees(asin(x));
+}
+
+real aCos(real x)
+{
+ return degrees(acos(x));
+}
+
+real aTan(real x)
+{
+ return degrees(atan(x));
+}
+
+pair unit(pair z)
+{
+ return unit(z);
+}
+
+pair dir(real degrees)
+{
+ return expi(radians(degrees));
+}
+
+pair dir(explicit pair z)
+{
+ return unit(z);
+}
+
+pair expi(real angle)
+{
+ return expi(angle);
+}
+
+pair exp(explicit pair z)
+{
+ return exp(z);
+}
+
+pair log(explicit pair z)
+{
+ return pair(log(z.length()),z.angle());
+}
+
+pair sin(explicit pair z)
+{
+ return sin(z);
+}
+
+pair cos(explicit pair z)
+{
+ return pair(cos(z.getx())*cosh(z.gety()),-sin(z.getx())*sinh(z.gety()));
+}
+
+pair conj(pair z)
+{
+ return conj(z);
+}
+
+pair realmult(pair z, pair w)
+{
+ return pair (z.getx()*w.getx(),z.gety()*w.gety());
+}
+
+triple realmult(triple u, triple v)
+{
+ return triple (u.getx()*v.getx(),u.gety()*v.gety(),u.getz()*v.getz());
+}
+
+// To avoid confusion, a dot product requires explicit pair arguments.
+real dot(explicit pair z, explicit pair w)
+{
+ return dot(z,w);
+}
+
+
+// Triple operations
+
+triple :tripleZero()
+{
+ static triple zero;
+ return zero;
+}
+
+triple :realRealRealToTriple(real x, real y, real z)
+{
+ return triple(x,y,z);
+}
+
+real xpart:tripleXPart(triple v)
+{
+ return v.getx();
+}
+
+real ypart:tripleYPart(triple v)
+{
+ return v.gety();
+}
+
+real zpart:tripleZPart(triple v)
+{
+ return v.getz();
+}
+
+triple Operator *(real x, triple v)
+{
+ return x*v;
+}
+
+triple Operator *(triple v, real x)
+{
+ return v*x;
+}
+
+triple /(triple v, real x)
+{
+ return v/x;
+}
+
+real length(triple v)
+{
+ return v.length();
+}
+
+real abs(triple v)
+{
+ return v.length();
+}
+
+real polar(triple v)
+{
+ return v.polar();
+}
+
+real azimuth(triple v)
+{
+ return v.azimuth();
+}
+
+real colatitude(triple v)
+{
+ return degrees(v.polar());
+}
+
+real latitude(triple v)
+{
+ return 90.0-degrees(v.polar());
+}
+
+// Return the longitude of v in [0,360).
+real longitude(triple v, bool warn=true)
+{
+ if(!warn && v.getx() == 0.0 && v.gety() == 0.0) return 0.0;
+ return principalBranch(degrees(v.azimuth()));
+}
+
+triple unit(triple v)
+{
+ return unit(v);
+}
+
+real dot(triple u, triple v)
+{
+ return dot(u,v);
+}
+
+triple cross(triple u, triple v)
+{
+ return cross(u,v);
+}
+
+triple expi(real polar, real azimuth)
+{
+ return expi(polar,azimuth);
+}
+
+triple dir(real colatitude, real longitude)
+{
+ return expi(radians(colatitude),radians(longitude));
+}
+
+
+// System routines
+
+void atupdate(callable *f)
+{
+ processData().atUpdateFunction=f;
+}
+
+callable *atupdate()
+{
+ return processData().atUpdateFunction;
+}
+
+void atexit(callable *f)
+{
+ processData().atExitFunction=f;
+}
+
+callable *atexit()
+{
+ return processData().atExitFunction;
+}
+
+void atbreakpoint(callableBp *f)
+{
+ processData().atBreakpointFunction=f;
+}
+
+void breakpoint(runnable *s=NULL)
+{
+ breakpoint(Stack,s);
+}
+
+string locatefile(string file)
+{
+ return locateFile(file);
+}
+
+void stop(string file, Int line, runnable *s=NULL)
+{
+ file=locateFile(file);
+ clear(file,line);
+ cout << "setting breakpoint at " << file << ": " << line << endl;
+ bplist.push_back(bpinfo(file,line,s));
+}
+
+void breakpoints()
+{
+ for(mem::list<bpinfo>::iterator p=bplist.begin(); p != bplist.end(); ++p)
+ cout << p->f.name() << ": " << p->f.line() << endl;
+}
+
+void clear(string file, Int line)
+{
+ file=locateFile(file);
+ clear(file,line,true);
+}
+
+void clear()
+{
+ bplist.clear();
+}
+
+// Strip directory from string
+string stripdirectory(string *s)
+{
+ return stripDir(*s);
+}
+
+// Strip directory from string
+string stripfile(string *s)
+{
+ return stripFile(*s);
+}
+
+// Strip file extension from string
+string stripextension(string *s)
+{
+ return stripExt(*s);
+}
+
+// Call ImageMagick convert.
+Int convert(string args=emptystring, string file=emptystring,
+ string format=emptystring)
+{
+ ostringstream cmd;
+
+ string name=convertname(file,format);
+ cmd << "'" << getSetting<string>("convert") << "' " << args
+ << " '" << name << "'";
+ bool quiet=verbose <= 1;
+ Int ret=System(cmd,quiet ? 1 : 0,true,"convert","your ImageMagick convert utility");
+
+ if(ret == 0 && verbose > 0)
+ cout << "Wrote " << ((file.empty()) ? name : file) << endl;
+
+ return ret;
+}
+
+// Call ImageMagick animate.
+Int animate(string args=emptystring, string file=emptystring,
+ string format=emptystring)
+{
+#ifndef __CYGWIN__
+ string name=convertname(file,format,false);
+ if(view()) {
+ ostringstream cmd;
+ cmd << "'" << getSetting<string>("animate") << "' " << args
+ << " '" << name << "'";
+ return System(cmd,0,false,"animate","your animated GIF viewer");
+ }
+#endif
+ return 0;
+}
+
+// Delete file named s.
+Int delete(string *s)
+{
+ checkLocal(*s);
+ Int rc=unlink(s->c_str());
+ if(rc == 0 && verbose > 0)
+ cout << "Deleted " << *s << endl;
+ return rc;
+}
+
+// Rename file "from" to file "to".
+Int rename(string *from, string *to)
+{
+ checkLocal(*from);
+ checkLocal(*to);
+ Int rc=rename(from->c_str(),to->c_str());
+ if(rc == 0 && verbose > 0)
+ cout << "Renamed " << *from << " to " << *to << endl;
+ return rc;
+}
+
+
+// Array operations
+
+// Create an empty array.
+array* :emptyArray()
+{
+ return new array(0);
+}
+
+// Create a new array (technically a vector).
+// This array will be multidimensional. First the number of dimensions
+// 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.
+array* :newDeepArray(Int depth)
+{
+ assert(depth > 0);
+
+ Int *dims = new Int[depth];
+
+ for (Int index = depth-1; index >= 0; index--) {
+ Int i=pop<Int>(Stack);
+ if(i < 0) error("cannot create a negative length array");
+ dims[index]=i;
+ }
+
+ array *a=deepArray(depth, dims);
+ delete[] dims;
+ return a;
+}
+
+// Creates an array with elements already specified. First, the number
+// of elements is popped off the stack, followed by each element in
+// reverse order.
+array* :newInitializedArray(Int n)
+{
+ assert(n >= 0);
+
+ array *a = new array(n);
+
+ for (Int index = n-1; index >= 0; index--)
+ (*a)[index] = pop(Stack);
+
+ return a;
+}
+
+// Similar to newInitializedArray, but after the n elements, append another
+// array to it.
+array* :newAppendedArray(array* tail, Int n)
+{
+ assert(n >= 0);
+
+ array *a = new array(n);
+
+ for (Int index = n-1; index >= 0; index--)
+ (*a)[index] = pop(Stack);
+
+ copy(tail->begin(), tail->end(), back_inserter(*a));
+
+ return a;
+}
+
+// The function T[] array(int n, T value, int depth=0) produces a array of n
+// copies of x, where each copy is copied up to depth.
+array* :newDuplicateArray(Int n, item value, Int depth=Int_MAX)
+{
+ if(n < 0) error("cannot create a negative length array");
+ if(depth < 0) error("cannot copy to a negative depth");
+
+ return new array(n, value, depth);
+}
+
+// Read an element from an array. Checks for initialization & bounds.
+item :arrayRead(array *a, Int n)
+{
+ item& i=arrayRead(a,n);
+ if (i.empty()) {
+ ostringstream buf;
+ buf << "read uninitialized value from array at index " << n;
+ error(buf);
+ }
+ return i;
+}
+
+// Slice a substring from an array.
+item :arraySliceRead(array *a, Int left, Int right)
+{
+ checkArray(a);
+ return a->slice(left, right);
+}
+
+// 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.
+item :arraySliceReadToEnd(array *a, Int left)
+{
+ size_t len=checkArray(a);
+ return a->slice(left, (Int)len);
+}
+
+// Read an element from an array of arrays. Check bounds and initialize
+// as necessary.
+item :arrayArrayRead(array *a, Int n)
+{
+ item& i=arrayRead(a,n);
+ if (i.empty()) i=new array(0);
+ return i;
+}
+
+// Write an element to an array. Increase size if necessary.
+item :arrayWrite(item value, array *a, Int n)
+{
+ size_t len=checkArray(a);
+ bool cyclic=a->cyclic();
+ if(cyclic && len > 0) n=imod(n,len);
+ else {
+ if(cyclic) outOfBounds("writing cyclic",len,n);
+ if(n < 0) outOfBounds("writing",len,n);
+ if(len <= (size_t) n)
+ a->resize(n+1);
+ }
+ (*a)[n] = value;
+ return value;
+}
+
+array * :arraySliceWrite(array *src, array *dest, Int left, Int right)
+{
+ checkArray(src);
+ checkArray(dest);
+ dest->setSlice(left, right, src);
+ return src;
+}
+
+array * :arraySliceWriteToEnd(array *src, array *dest, Int left)
+{
+ checkArray(src);
+ size_t len=checkArray(dest);
+ dest->setSlice(left, (Int) len, src);
+ return src;
+}
+
+// Returns the length of an array.
+Int :arrayLength(array *a)
+{
+ return (Int) checkArray(a);
+}
+
+// Returns an array of integers representing the keys of the array.
+array * :arrayKeys(array *a)
+{
+ size_t size=checkArray(a);
+
+ array *keys=new array();
+ for (size_t i=0; i<size; ++i) {
+ item& cell = (*a)[i];
+ if (!cell.empty())
+ keys->push((Int)i);
+ }
+
+ return keys;
+}
+
+// Return the cyclic flag for an array.
+bool :arrayCyclicFlag(array *a)
+{
+ checkArray(a);
+ return a->cyclic();
+}
+
+// Check to see if an array element is initialized.
+bool :arrayInitializedHelper(Int n, array *a)
+{
+ size_t len=checkArray(a);
+ bool cyclic=a->cyclic();
+ if(cyclic && len > 0) n=imod(n,len);
+ else if(n < 0 || n >= (Int) len) return false;
+ item&i=(*a)[(unsigned) n];
+ return !i.empty();
+}
+
+// Returns the initialize method for an array.
+callable* :arrayInitialized(array *a)
+{
+ return new thunk(new bfunc(arrayInitializedHelper),a);
+}
+
+// The helper function for the cyclic method that sets the cyclic flag.
+void :arrayCyclicHelper(bool b, array *a)
+{
+ checkArray(a);
+ a->cyclic(b);
+}
+
+// Set the cyclic flag for an array.
+callable* :arrayCyclic(array *a)
+{
+ return new thunk(new bfunc(arrayCyclicHelper),a);
+}
+
+// The helper function for the push method that does the actual operation.
+item :arrayPushHelper(item x, array *a)
+{
+ checkArray(a);
+ a->push(x);
+ return x;
+}
+
+// Returns the push method for an array.
+callable* :arrayPush(array *a)
+{
+ return new thunk(new bfunc(arrayPushHelper),a);
+}
+
+// The helper function for the append method that appends b to a.
+void :arrayAppendHelper(array *b, array *a)
+{
+ checkArray(a);
+ size_t size=checkArray(b);
+ for(size_t i=0; i < size; i++)
+ a->push((*b)[i]);
+}
+
+// Returns the append method for an array.
+callable* :arrayAppend(array *a)
+{
+ return new thunk(new bfunc(arrayAppendHelper),a);
+}
+
+// The helper function for the pop method.
+item :arrayPopHelper(array *a)
+{
+ size_t asize=checkArray(a);
+ if(asize == 0)
+ error("cannot pop element from empty array");
+ return a->pop();
+}
+
+// Returns the pop method for an array.
+callable* :arrayPop(array *a)
+{
+ return new thunk(new bfunc(arrayPopHelper),a);
+}
+
+// The helper function for the insert method.
+item :arrayInsertHelper(Int i, array *x, array *a)
+{
+ size_t asize=checkArray(a);
+ checkArray(x);
+ if(a->cyclic() && asize > 0) i=imod(i,asize);
+ if(i < 0 || i > (Int) asize)
+ outOfBounds("inserting",asize,i);
+ (*a).insert((*a).begin()+i,(*x).begin(),(*x).end());
+}
+
+// Returns the insert method for an array.
+callable* :arrayInsert(array *a)
+{
+ return new thunk(new bfunc(arrayInsertHelper),a);
+}
+
+// Returns the delete method for an array.
+callable* :arrayDelete(array *a)
+{
+ return new thunk(new bfunc(arrayDeleteHelper),a);
+}
+
+bool :arrayAlias(array *a, array *b)
+{
+ return a==b;
+}
+
+// Return array formed by indexing array a with elements of integer array b
+array* :arrayIntArray(array *a, array *b)
+{
+ size_t asize=checkArray(a);
+ size_t bsize=checkArray(b);
+ array *r=new array(bsize);
+ bool cyclic=a->cyclic();
+ for(size_t i=0; i < bsize; i++) {
+ Int index=read<Int>(b,i);
+ if(cyclic && asize > 0) index=imod(index,asize);
+ else
+ if(index < 0 || index >= (Int) asize)
+ outOfBounds("reading",asize,index);
+ (*r)[i]=(*a)[index];
+ }
+ return r;
+}
+
+// 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].
+Intarray* complement(Intarray *a, Int n)
+{
+ size_t asize=checkArray(a);
+ array *r=new array(0);
+ bool *keep=new bool[n];
+ for(Int i=0; i < n; ++i) keep[i]=true;
+ for(size_t i=0; i < asize; ++i) {
+ Int j=read<Int>(a,i);
+ if(j >= 0 && j < n) keep[j]=false;
+ }
+ for(Int i=0; i < n; i++)
+ if(keep[i]) r->push(i);
+
+ delete[] keep;
+ return r;
+}
+
+// Generate the sequence {f(i) : i=0,1,...n-1} given a function f and integer n
+Intarray* :arraySequence(callable *f, Int n)
+{
+ if(n < 0) n=0;
+ array *a=new array(n);
+ for(Int i=0; i < n; ++i) {
+ Stack->push(i);
+ f->call(Stack);
+ (*a)[i]=pop(Stack);
+ }
+ return a;
+}
+
+// Return the array {0,1,...n-1}
+Intarray *sequence(Int n)
+{
+ if(n < 0) n=0;
+ array *a=new array(n);
+ for(Int i=0; i < n; ++i) {
+ (*a)[i]=i;
+ }
+ return a;
+}
+
+// Apply a function to each element of an array
+array* :arrayFunction(callable *f, array *a)
+{
+ size_t size=checkArray(a);
+ array *b=new array(size);
+ for(size_t i=0; i < size; ++i) {
+ Stack->push((*a)[i]);
+ f->call(Stack);
+ (*b)[i]=pop(Stack);
+ }
+ return b;
+}
+
+array* :arraySort(array *a, callable *f)
+{
+ array *c=copyArray(a);
+ compareFunc=f;
+ FuncStack=Stack;
+ stable_sort(c->begin(),c->end(),compareFunction);
+ return c;
+}
+
+bool all(boolarray *a)
+{
+ size_t size=checkArray(a);
+ bool c=true;
+ for(size_t i=0; i < size; i++)
+ if(!get<bool>((*a)[i])) {c=false; break;}
+ return c;
+}
+
+boolarray* !(boolarray* a)
+{
+ size_t size=checkArray(a);
+ array *c=new array(size);
+ for(size_t i=0; i < size; i++)
+ (*c)[i]=!read<bool>(a,i);
+ return c;
+}
+
+Int sum(boolarray *a)
+{
+ size_t size=checkArray(a);
+ Int sum=0;
+ for(size_t i=0; i < size; i++)
+ sum += read<bool>(a,i) ? 1 : 0;
+ return sum;
+}
+
+array* :arrayCopy(array *a)
+{
+ return copyArray(a);
+}
+
+array* :arrayConcat(array *a)
+{
+ // a is an array of arrays to be concatenated together.
+ // The signature is
+ // T[] concat(... T[][] a);
+
+ size_t numArgs=checkArray(a);
+ size_t resultSize=0;
+ for (size_t i=0; i < numArgs; ++i) {
+ resultSize += checkArray(a->read<array *>(i));
+ }
+
+ array *result=new array(resultSize);
+
+ size_t ri=0;
+ for (size_t i=0; i < numArgs; ++i) {
+ array *arg=a->read<array *>(i);
+ size_t size=checkArray(arg);
+
+ for (size_t j=0; j < size; ++j) {
+ (*result)[ri]=(*arg)[j];
+ ++ri;
+ }
+ }
+
+ return result;
+}
+
+array* :array2Copy(array *a)
+{
+ return copyArray2(a);
+}
+
+array* :array3Copy(array *a)
+{
+ return copyArray3(a);
+}
+
+array* :array2Transpose(array *a)
+{
+ size_t asize=checkArray(a);
+ array *c=new array(0);
+ for(size_t i=0; i < asize; i++) {
+ size_t ip=i+1;
+ array *ai=read<array*>(a,i);
+ size_t aisize=checkArray(ai);
+ size_t csize=checkArray(c);
+ if(csize < aisize) {
+ c->resize(aisize);
+ for(size_t j=csize; j < aisize; j++) {
+ (*c)[j]=new array(ip);
+ }
+ }
+ for(size_t j=0; j < aisize; j++) {
+ array *cj=read<array*>(c,j);
+ if(checkArray(cj) < ip) cj->resize(ip);
+ (*cj)[i]=(*ai)[j];
+ }
+ }
+ return c;
+}
+
+// a is a rectangular 3D array; perm is an Int array indicating the type of
+// 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}.
+array* :array3Transpose(array *a, array *perm)
+{
+ const size_t DIM=3;
+
+ if(checkArray(perm) != DIM) {
+ ostringstream buf;
+ buf << "permutation array must have length " << DIM;
+ error(buf);
+ }
+
+ size_t* size=new size_t[DIM];
+ for(size_t i=0; i < DIM; ++i) size[i]=DIM;
+
+ for(size_t i=0; i < DIM; ++i) {
+ Int p=read<Int>(perm,i);
+ size_t P=(size_t) p;
+ if(p < 0 || P >= DIM) {
+ ostringstream buf;
+ buf << "permutation index out of range: " << p;
+ error(buf);
+ }
+ size[P]=P;
+ }
+
+ for(size_t i=0; i < DIM; ++i)
+ if(size[i] == DIM) error("permutation indices must be distinct");
+
+ static const char *rectangular=
+ "3D transpose implemented for rectangular matrices only";
+
+ size_t isize=size[0]=checkArray(a);
+ array *a0=read<array*>(a,0);
+ size[1]=checkArray(a0);
+ array *a00=read<array*>(a0,0);
+ size[2]=checkArray(a00);
+ for(size_t i=0; i < isize; i++) {
+ array *ai=read<array*>(a,i);
+ size_t jsize=checkArray(ai);
+ if(jsize != size[1]) error(rectangular);
+ for(size_t j=0; j < jsize; j++) {
+ array *aij=read<array*>(ai,j);
+ if(checkArray(aij) != size[2]) error(rectangular);
+ }
+ }
+
+ size_t perm0=(size_t) read<Int>(perm,0);
+ size_t perm1=(size_t) read<Int>(perm,1);
+ size_t perm2=(size_t) read<Int>(perm,2);
+
+ size_t sizep0=size[perm0];
+ size_t sizep1=size[perm1];
+ size_t sizep2=size[perm2];
+
+ array *c=new array(sizep0);
+ for(size_t i=0; i < sizep0; ++i) {
+ array *ci=new array(sizep1);
+ (*c)[i]=ci;
+ for(size_t j=0; j < sizep1; ++j) {
+ array *cij=new array(sizep2);
+ (*ci)[j]=cij;
+ }
+ }
+
+ size_t* i=new size_t[DIM];
+
+ for(i[0]=0; i[0] < size[0]; ++i[0]) {
+ array *a0=read<array*>(a,i[0]);
+ for(i[1]=0; i[1] < size[1]; ++i[1]) {
+ array *a1=read<array*>(a0,i[1]);
+ for(i[2]=0; i[2] < size[2]; ++i[2]) {
+ array *c0=read<array*>(c,i[perm0]);
+ array *c1=read<array*>(c0,i[perm1]);
+ (*c1)[i[perm2]]=read<real>(a1,i[2]);
+ }
+ }
+ }
+
+ delete [] i;
+ delete [] size;
+
+ return c;
+}
+
+// In a boolean array, find the index of the nth true value or -1 if not found
+// If n is negative, search backwards.
+Int find(boolarray *a, Int n=1)
+{
+
+ size_t size=checkArray(a);
+ Int j=-1;
+ if(n > 0)
+ for(size_t i=0; i < size; i++)
+ if(read<bool>(a,i)) {
+ n--; if(n == 0) {j=(Int) i; break;}
+ }
+ if(n < 0)
+ for(size_t i=size; i > 0;)
+ if(read<bool>(a,--i)) {
+ n++; if(n == 0) {j=(Int) i; break;}
+ }
+ return j;
+}
+
+bool Operator ==(realarray2 *a, realarray2 *b)
+{
+ size_t n=checkArray(a);
+ if(n != checkArray(b)) return false;
+
+ size_t n0=n == 0 ? 0 : checkArray(read<array*>(a,0));
+ if(n0 != checkArray(read<array*>(b,0))) return false;
+
+ for(size_t i=0; i < n; ++i) {
+ array *ai=read<array*>(a,i);
+ array *bi=read<array*>(b,i);
+ for(size_t j=0; j < n0; ++j) {
+ if(read<real>(ai,j) != read<real>(bi,j))
+ return false;
+ }
+ }
+ return true;
+}
+
+// construct vector obtained by replacing those elements of b for which the
+// corresponding elements of a are false by the corresponding element of c.
+array* :arrayConditional(array *a, array *b, array *c)
+{
+ size_t size=checkArray(a);
+ array *r=new array(size);
+ if(b && c) {
+ checkArrays(a,b);
+ checkArrays(b,c);
+ for(size_t i=0; i < size; i++)
+ (*r)[i]=read<bool>(a,i) ? (*b)[i] : (*c)[i];
+ } else {
+ r->clear();
+ if(b) {
+ checkArrays(a,b);
+ for(size_t i=0; i < size; i++)
+ if(read<bool>(a,i)) r->push((*b)[i]);
+ } else if(c) {
+ checkArrays(a,c);
+ for(size_t i=0; i < size; i++)
+ if(!read<bool>(a,i)) r->push((*c)[i]);
+ }
+ }
+ return r;
+}
+
+// Return an n x n identity matrix.
+realarray2 *identity(Int n)
+{
+ return Identity(n);
+}
+
+// Return the diagonal matrix with diagonal entries given by a.
+realarray2* :diagonal(realarray *a)
+{
+ size_t n=checkArray(a);
+ array *c=new array(n);
+ for(size_t i=0; i < n; ++i) {
+ array *ci=new array(n);
+ (*c)[i]=ci;
+ for(size_t j=0; j < i; ++j)
+ (*ci)[j]=0.0;
+ (*ci)[i]=read<real>(a,i);
+ for(size_t j=i+1; j < n; ++j)
+ (*ci)[j]=0.0;
+ }
+ return c;
+}
+
+// Return the inverse of an n x n matrix a using Gauss-Jordan elimination.
+realarray2 *inverse(realarray2 *a)
+{
+ a=copyArray2(a);
+ size_t n=checkArray(a);
+ checkSquare(a);
+
+ inverseAllocate(n);
+
+ for(size_t i=0; i < n; i++)
+ pivot[i]=0;
+
+ size_t col=0, row=0;
+ // This is the main loop over the columns to be reduced.
+ for(size_t i=0; i < n; i++) {
+ real big=0.0;
+ // This is the outer loop of the search for a pivot element.
+ for(size_t j=0; j < n; j++) {
+ array *aj=read<array*>(a,j);
+ if(pivot[j] != 1) {
+ for(size_t k=0; k < n; k++) {
+ if(pivot[k] == 0) {
+ real temp=fabs(read<real>(aj,k));
+ if(temp >= big) {
+ big=temp;
+ row=j;
+ col=k;
+ }
+ } else if(pivot[k] > 1) {
+ inverseDeallocate();
+ error(singular);
+ }
+ }
+ }
+ }
+ ++(pivot[col]);
+
+ // Interchange rows, if needed, to put the pivot element on the diagonal.
+ array *acol=read<array*>(a,col);
+ if(row != col) {
+ array *arow=read<array*>(a,row);
+ for(size_t l=0; l < n; l++) {
+ real temp=read<real>(arow,l);
+ (*arow)[l]=read<real>(acol,l);
+ (*acol)[l]=temp;
+ }
+ }
+
+ Row[i]=row;
+ Col[i]=col;
+
+ // Divide the pivot row by the pivot element.
+ real denom=read<real>(acol,col);
+ if(denom == 0.0) {
+ inverseDeallocate();
+ error(singular);
+ }
+ real pivinv=1.0/denom;
+ (*acol)[col]=1.0;
+ for(size_t l=0; l < n; l++)
+ (*acol)[l]=read<real>(acol,l)*pivinv;
+
+ // Reduce all rows except for the pivoted one.
+ for(size_t k=0; k < n; k++) {
+ if(k != col) {
+ array *ak=read<array*>(a,k);
+ real akcol=read<real>(ak,col);
+ (*ak)[col]=0.0;
+ for(size_t l=0; l < n; l++)
+ (*ak)[l]=read<real>(ak,l)-read<real>(acol,l)*akcol;
+ }
+ }
+ }
+
+ // Unscramble the inverse matrix in view of the column interchanges.
+ for(size_t l=n; l > 0;) {
+ l--;
+ size_t r=Row[l];
+ size_t c=Col[l];
+ if(r != c) {
+ for(size_t k=0; k < n; k++) {
+ array *ak=read<array*>(a,k);
+ real temp=read<real>(ak,r);
+ (*ak)[r]=read<real>(ak,c);
+ (*ak)[c]=temp;
+ }
+ }
+ }
+ inverseDeallocate();
+ return a;
+}
+
+// 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.
+realarray *solve(realarray2 *a, realarray *b, bool warn=true)
+{
+ size_t n=checkArray(a);
+
+ if(n == 0) return new array(0);
+
+ size_t m=checkArray(b);
+ if(m != n) error(incommensurate);
+
+ real *A=copyArray2C(a);
+ size_t *index=new size_t[n];
+
+ if(LUdecompose(A,n,index,warn) == 0)
+ return new array(0);
+
+ array *x=new array(n);
+
+ real *B=copyArrayC(b);
+
+ for(size_t i=0; i < n; ++i) {
+ size_t ip=index[i];
+ real sum=B[ip];
+ B[ip]=B[i];
+ real *Ai=A+i*n;
+ for(size_t j=0; j < i; ++j)
+ sum -= Ai[j]*B[j];
+ B[i]=sum;
+ }
+
+ for(size_t i=n; i > 0;) {
+ --i;
+ real sum=B[i];
+ real *Ai=A+i*n;
+ for(size_t j=i+1; j < n; ++j)
+ sum -= Ai[j]*B[j];
+ B[i]=sum/Ai[i];
+ }
+
+ for(size_t i=0; i < n; ++i)
+ (*x)[i]=B[i];
+
+ delete[] index;
+ delete[] B;
+ delete[] A;
+
+ return x;
+}
+
+// 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.
+realarray2 *solve(realarray2 *a, realarray2 *b, bool warn=true)
+{
+ size_t n=checkArray(a);
+
+ if(n == 0) return new array(0);
+
+ if(checkArray(b) != n) error(incommensurate);
+ size_t m=checkArray(read<array*>(b,0));
+
+ real *A=copyArray2C(a);
+ real *B=copyArray2C(b,false);
+
+ size_t *index=new size_t[n];
+
+ if(LUdecompose(A,n,index,warn) == 0)
+ return new array(0);
+
+ array *x=new array(n);
+
+ for(size_t i=0; i < n; ++i) {
+ real *Ai=A+i*n;
+ real *Bi=B+i*m;
+ real *Bip=B+index[i]*m;
+ for(size_t k=0; k < m; ++k) {
+ real sum=Bip[k];
+ Bip[k]=Bi[k];
+ size_t jk=k;
+ for(size_t j=0; j < i; ++j, jk += m)
+ sum -= Ai[j]*B[jk];
+ Bi[k]=sum;
+ }
+ }
+
+ for(size_t i=n; i > 0;) {
+ --i;
+ real *Ai=A+i*n;
+ real *Bi=B+i*m;
+ for(size_t k=0; k < m; ++k) {
+ real sum=Bi[k];
+ size_t jk=(i+1)*m+k;
+ for(size_t j=i+1; j < n; ++j, jk += m)
+ sum -= Ai[j]*B[jk];
+ Bi[k]=sum/Ai[i];
+ }
+ }
+
+ for(size_t i=0; i < n; ++i) {
+ real *Bi=B+i*m;
+ array *xi=new array(m);
+ (*x)[i]=xi;
+ for(size_t j=0; j < m; ++j)
+ (*xi)[j]=Bi[j];
+ }
+
+ delete[] index;
+ delete[] B;
+ delete[] A;
+
+ return x;
+}
+
+// Compute the determinant of an n x n matrix.
+real determinant(realarray2 *a)
+{
+ real *A=copyArray2C(a);
+ size_t n=checkArray(a);
+
+ real det=LUdecompose(A,n,NULL,false);
+ size_t n1=n+1;
+ for(size_t i=0; i < n; ++i)
+ det *= A[i*n1];
+
+ delete[] A;
+
+ return det;
+}
+
+realarray *Operator *(realarray2 *a, realarray *b)
+{
+ size_t n=checkArray(a);
+ size_t m=checkArray(b);
+ array *c=new array(n);
+ real *B=copyArrayC(b);
+ for(size_t i=0; i < n; ++i) {
+ array *ai=read<array*>(a,i);
+ if(checkArray(ai) != m) error(incommensurate);
+ real sum=0.0;
+ for(size_t j=0; j < m; ++j)
+ sum += read<real>(ai,j)*B[j];
+ (*c)[i]=sum;
+ }
+ delete[] B;
+ return c;
+}
+
+realarray2 *Operator *(realarray2 *a, realarray2 *b)
+{
+ size_t n=checkArray(a);
+
+ size_t nb=checkArray(b);
+ size_t na0=n == 0 ? 0 : checkArray(read<array*>(a,0));
+ if(na0 != nb)
+ error(incommensurate);
+
+ size_t nb0=nb == 0 ? 0 : checkArray(read<array*>(b,0));
+
+ array *c=new array(n);
+
+ real *A=copyArray2C(a,false);
+ real *B=copyArray2C(b,false);
+
+ for(size_t i=0; i < n; ++i) {
+ real *Ai=A+i*nb;
+ array *ci=new array(nb0);
+ (*c)[i]=ci;
+ for(size_t j=0; j < nb0; ++j) {
+ real sum=0.0;
+ size_t kj=j;
+ for(size_t k=0; k < nb; ++k, kj += nb0)
+ sum += Ai[k]*B[kj];
+ (*ci)[j]=sum;
+ }
+ }
+
+ delete[] B;
+ delete[] A;
+
+ return c;
+}
+
+triple Operator *(realarray2 *t, triple v)
+{
+ return *t*v;
+}
+
+pair project(triple v, realarray2 *t)
+{
+ size_t n=checkArray(t);
+ if(n != 4) error(incommensurate);
+ array *t0=read<array*>(t,0);
+ array *t1=read<array*>(t,1);
+ array *t3=read<array*>(t,3);
+ if(checkArray(t0) != 4 || checkArray(t1) != 4 || checkArray(t3) != 4)
+ error(incommensurate);
+
+ real x=v.getx();
+ real y=v.gety();
+ real z=v.getz();
+
+ real f=read<real>(t3,0)*x+read<real>(t3,1)*y+read<real>(t3,2)*z+
+ read<real>(t3,3);
+ if(f == 0.0) dividebyzero();
+ f=1.0/f;
+
+ return pair((read<real>(t0,0)*x+read<real>(t0,1)*y+read<real>(t0,2)*z+
+ read<real>(t0,3))*f,
+ (read<real>(t1,0)*x+read<real>(t1,1)*y+read<real>(t1,2)*z+
+ read<real>(t1,3))*f);
+}
+
+// Compute the dot product of vectors a and b.
+real dot(realarray *a, realarray *b)
+{
+ size_t n=checkArrays(a,b);
+ real sum=0.0;
+ for(size_t i=0; i < n; ++i)
+ sum += read<real>(a,i)*read<real>(b,i);
+ return sum;
+}
+
+// Solve the problem L\inv f, where f is an n vector and L is the n x n matrix
+//
+// [ b[0] c[0] a[0] ]
+// [ a[1] b[1] c[1] ]
+// [ a[2] b[2] c[2] ]
+// [ ... ]
+// [ c[n-1] a[n-1] b[n-1] ]
+realarray *tridiagonal(realarray *a, realarray *b, realarray *c, realarray *f)
+{
+ size_t n=checkArrays(a,b);
+ checkEqual(n,checkArray(c));
+ checkEqual(n,checkArray(f));
+
+ array *up=new array(n);
+ array& u=*up;
+
+ if(n == 0) return up;
+
+ // Special case: zero Dirichlet boundary conditions
+ if(read<real>(a,0) == 0.0 && read<real>(c,n-1) == 0.0) {
+ real temp=read<real>(b,0);
+ if(temp == 0.0) dividebyzero();
+ temp=1.0/temp;
+
+ real *work=new real[n];
+ u[0]=read<real>(f,0)*temp;
+ work[0]=-read<real>(c,0)*temp;
+
+ for(size_t i=1; i < n; i++) {
+ real temp=(read<real>(b,i)+read<real>(a,i)*work[i-1]);
+ if(temp == 0.0) {delete[] work; dividebyzero();}
+ temp=1.0/temp;
+ u[i]=(read<real>(f,i)-read<real>(a,i)*read<real>(u,i-1))*temp;
+ work[i]=-read<real>(c,i)*temp;
+ }
+
+ for(size_t i=n-1; i >= 1; i--)
+ u[i-1]=read<real>(u,i-1)+work[i-1]*read<real>(u,i);
+
+ delete[] work;
+ return up;
+ }
+
+ real binv=read<real>(b,0);
+ if(binv == 0.0) dividebyzero();
+ binv=1.0/binv;
+
+ if(n == 1) {u[0]=read<real>(f,0)*binv; return up;}
+ if(n == 2) {
+ real factor=(read<real>(b,0)*read<real>(b,1)-
+ read<real>(a,0)*read<real>(c,1));
+ if(factor== 0.0) dividebyzero();
+ factor=1.0/factor;
+ real temp=(read<real>(b,0)*read<real>(f,1)-
+ read<real>(c,1)*read<real>(f,0))*factor;
+ u[0]=(read<real>(b,1)*read<real>(f,0)-
+ read<real>(a,0)*read<real>(f,1))*factor;
+ u[1]=temp;
+ return up;
+ }
+
+ real *gamma=new real[n-2];
+ real *delta=new real[n-2];
+
+ gamma[0]=read<real>(c,0)*binv;
+ delta[0]=read<real>(a,0)*binv;
+ u[0]=read<real>(f,0)*binv;
+ real beta=read<real>(c,n-1);
+ real fn=read<real>(f,n-1)-beta*read<real>(u,0);
+ real alpha=read<real>(b,n-1)-beta*delta[0];
+
+ for(size_t i=1; i <= n-3; i++) {
+ real alphainv=read<real>(b,i)-read<real>(a,i)*gamma[i-1];
+ if(alphainv == 0.0) {delete[] gamma; delete[] delta; dividebyzero();}
+ alphainv=1.0/alphainv;
+ beta *= -gamma[i-1];
+ gamma[i]=read<real>(c,i)*alphainv;
+ u[i]=(read<real>(f,i)-read<real>(a,i)*read<real>(u,i-1))*alphainv;
+ fn -= beta*read<real>(u,i);
+ delta[i]=-read<real>(a,i)*delta[i-1]*alphainv;
+ alpha -= beta*delta[i];
+ }
+
+ real alphainv=read<real>(b,n-2)-read<real>(a,n-2)*gamma[n-3];
+ if(alphainv == 0.0) {delete[] gamma; delete[] delta; dividebyzero();}
+ alphainv=1.0/alphainv;
+ u[n-2]=(read<real>(f,n-2)-read<real>(a,n-2)*read<real>(u,n-3))
+ *alphainv;
+ beta=read<real>(a,n-1)-beta*gamma[n-3];
+ real dnm1=(read<real>(c,n-2)-read<real>(a,n-2)*delta[n-3])*alphainv;
+ real temp=alpha-beta*dnm1;
+ if(temp == 0.0) {delete[] gamma; delete[] delta; dividebyzero();}
+ u[n-1]=temp=(fn-beta*read<real>(u,n-2))/temp;
+ u[n-2]=read<real>(u,n-2)-dnm1*temp;
+
+ for(size_t i=n-2; i >= 1; i--)
+ u[i-1]=read<real>(u,i-1)-gamma[i-1]*read<real>(u,i)-delta[i-1]*temp;
+
+ delete[] delta;
+ delete[] gamma;
+
+ return up;
+}
+
+// Root solve by Newton-Raphson
+real newton(Int iterations=100, callableReal *f, callableReal *fprime, real x,
+ bool verbose=false)
+{
+ static const real fuzz=1000.0*DBL_EPSILON;
+ Int i=0;
+ size_t oldPrec=0;
+ if(verbose)
+ oldPrec=cout.precision(DBL_DIG);
+
+ real diff=DBL_MAX;
+ real lastdiff;
+ do {
+ real x0=x;
+
+ Stack->push(x);
+ fprime->call(Stack);
+ real dfdx=pop<real>(Stack);
+
+ if(dfdx == 0.0) {
+ x=DBL_MAX;
+ break;
+ }
+
+ Stack->push(x);
+ f->call(Stack);
+ real fx=pop<real>(Stack);
+
+ x -= fx/dfdx;
+
+ lastdiff=diff;
+
+ if(verbose)
+ cout << "Newton-Raphson: " << x << endl;
+
+ diff=fabs(x-x0);
+ if(++i == iterations) {
+ x=DBL_MAX;
+ break;
+ }
+ } while (diff != 0.0 && (diff < lastdiff || diff > fuzz*fabs(x)));
+
+ if(verbose)
+ cout.precision(oldPrec);
+ return x;
+}
+
+// Root solve by Newton-Raphson bisection
+// cf. routine rtsafe (Press et al., Numerical Recipes, 1991).
+real newton(Int iterations=100, callableReal *f, callableReal *fprime, real x1,
+ real x2, bool verbose=false)
+{
+ static const real fuzz=1000.0*DBL_EPSILON;
+ size_t oldPrec=0;
+ if(verbose)
+ oldPrec=cout.precision(DBL_DIG);
+
+ Stack->push(x1);
+ f->call(Stack);
+ real f1=pop<real>(Stack);
+ if(f1 == 0.0) return x1;
+
+ Stack->push(x2);
+ f->call(Stack);
+ real f2=pop<real>(Stack);
+ if(f2 == 0.0) return x2;
+
+ if((f1 > 0.0 && f2 > 0.0) || (f1 < 0.0 && f2 < 0.0)) {
+ ostringstream buf;
+ buf << "root not bracketed, f(x1)=" << f1 << ", f(x2)=" << f2 << endl;
+ error(buf);
+ }
+
+ real x=0.5*(x1+x2);
+ real dxold=fabs(x2-x1);
+ if(f1 > 0.0) {
+ real temp=x1;
+ x1=x2;
+ x2=temp;
+ }
+
+ if(verbose)
+ cout << "midpoint: " << x << endl;
+
+ real dx=dxold;
+ Stack->push(x);
+ f->call(Stack);
+ real y=pop<real>(Stack);
+
+ Stack->push(x);
+ fprime->call(Stack);
+ real dy=pop<real>(Stack);
+
+ Int j;
+ for(j=0; j < iterations; j++) {
+ if(((x-x2)*dy-y)*((x-x1)*dy-y) >= 0.0 || fabs(2.0*y) > fabs(dxold*dy)) {
+ dxold=dx;
+ dx=0.5*(x2-x1);
+ x=x1+dx;
+ if(verbose)
+ cout << "bisection: " << x << endl;
+ if(x1 == x) return x;
+ } else {
+ dxold=dx;
+ dx=y/dy;
+ real temp=x;
+ x -= dx;
+ if(verbose)
+ cout << "Newton-Raphson: " << x << endl;
+ if(temp == x) return x;
+ }
+ if(fabs(dx) < fuzz*fabs(x)) return x;
+
+ Stack->push(x);
+ f->call(Stack);
+ y=pop<real>(Stack);
+
+ Stack->push(x);
+ fprime->call(Stack);
+ dy=pop<real>(Stack);
+
+ if(y < 0.0) x1=x;
+ else x2=x;
+ }
+ if(verbose)
+ cout.precision(oldPrec);
+ return (j == iterations) ? DBL_MAX : x;
+}
+
+real simpson(callableReal *f, real a, real b, real acc=DBL_EPSILON,
+ real dxmax=0)
+{
+ real integral;
+ if(dxmax == 0) dxmax=b-a;
+ Func=f;
+ FuncStack=Stack;
+ if(!simpson(integral,wrapFunction,a,b,acc,dxmax))
+ error("nesting capacity exceeded in simpson");
+ return integral;
+}
+
+// Compute the fast Fourier transform of a pair array
+pairarray* :pairArrayFFT(pairarray *a, Int sign=1)
+{
+ unsigned n=(unsigned) checkArray(a);
+#ifdef HAVE_LIBFFTW3
+ array *c=new array(n);
+ if(n) {
+ Complex *f=FFTWComplex(n);
+ fft1d Forward(n,intcast(sign),f);
+
+ for(size_t i=0; i < n; i++) {
+ pair z=read<pair>(a,i);
+ f[i]=Complex(z.getx(),z.gety());
+ }
+ Forward.fft(f);
+
+ for(size_t i=0; i < n; i++) {
+ Complex z=f[i];
+ (*c)[i]=pair(z.real(),z.imag());
+ }
+ FFTWdelete(f);
+ }
+#else
+ unused(&n);
+ unused(&sign);
+ array *c=new array(0);
+#endif // HAVE_LIBFFTW3
+ return c;
+}
+
+Intarray2 *triangulate(pairarray *z)
+{
+ size_t nv=checkArray(z);
+// Call robust version of Gilles Dumoulin's port of Paul Bourke's
+// triangulation code.
+
+ XYZ *pxyz=new XYZ[nv+3];
+ ITRIANGLE *V=new ITRIANGLE[4*nv];
+
+ for(size_t i=0; i < nv; ++i) {
+ pair w=read<pair>(z,i);
+ pxyz[i].p[0]=w.getx();
+ pxyz[i].p[1]=w.gety();
+ pxyz[i].i=(Int) i;
+ }
+
+ Int ntri;
+ Triangulate((Int) nv,pxyz,V,ntri,true,false);
+
+ size_t nt=(size_t) ntri;
+ array *t=new array(nt);
+ for(size_t i=0; i < nt; ++i) {
+ array *ti=new array(3);
+ (*t)[i]=ti;
+ ITRIANGLE *Vi=V+i;
+ (*ti)[0]=pxyz[Vi->p1].i;
+ (*ti)[1]=pxyz[Vi->p2].i;
+ (*ti)[2]=pxyz[Vi->p3].i;
+ }
+
+ delete[] V;
+ delete[] pxyz;
+ return t;
+}
+
+
+// File operations
+
+bool ==(file *a, file *b)
+{
+ return a == b;
+}
+
+bool !=(file *a, file *b)
+{
+ return a != b;
+}
+
+file* :nullFile()
+{
+ return &camp::nullfile;
+}
+
+file* input(string name, bool check=true, string comment=commentchar)
+{
+ char c=comment.empty() ? (char) 0 : comment[0];
+ file *f=new ifile(name,c,check);
+ f->open();
+ return f;
+}
+
+file* output(string name, bool update=false, string comment=commentchar)
+{
+ file *f;
+ if(update) {
+ char c=comment.empty() ? (char) 0 : comment[0];
+ f=new iofile(name,c);
+ } else f=new ofile(name);
+ f->open();
+ if(update) f->seek(0,false);
+ return f;
+}
+
+file* xinput(string name, bool check=true)
+{
+#ifdef HAVE_RPC_RPC_H
+ file *f=new ixfile(name,check);
+ f->open();
+ return f;
+#else
+ ostringstream buf;
+ buf << name << ": XDR read support not enabled";
+ error(buf);
+ unused(&check); // Suppress unused variable warning
+#endif
+}
+
+file* xoutput(string name, bool update=false)
+{
+#ifdef HAVE_RPC_RPC_H
+ file *f;
+ if(update)
+ f=new ioxfile(name);
+ else f=new oxfile(name);
+ f->open();
+ if(update) f->seek(0,false);
+ return f;
+#else
+ ostringstream buf;
+ buf << name << ": XDR write support not enabled";
+ error(buf);
+ unused(&update); // Suppress unused variable warning
+#endif
+}
+
+file* binput(string name, bool check=true)
+{
+ file *f=new ibfile(name,check);
+ f->open();
+ return f;
+}
+
+file* boutput(string name, bool update=false)
+{
+ file *f;
+ if(update) f=new iobfile(name);
+ else f=new obfile(name);
+ f->open();
+ if(update) f->seek(0,false);
+ return f;
+}
+
+bool eof(file *File)
+{
+ return File->eof();
+}
+
+bool eol(file *File)
+{
+ return File->eol();
+}
+
+bool error(file *File)
+{
+ return File->error();
+}
+
+void clear(file *File)
+{
+ File->clear();
+}
+
+void close(file *File)
+{
+ File->close();
+}
+
+Int precision(file *File=NULL, Int digits=0)
+{
+ if(File == 0) File=&camp::Stdout;
+ return File->precision(digits);
+}
+
+void flush(file *File)
+{
+ File->flush();
+}
+
+string getc(file *File)
+{
+ char c=0;
+ if(File->isOpen()) File->read(c);
+ static char str[1];
+ str[0]=c;
+ return string(str);
+}
+
+Int tell(file *File)
+{
+ return File->tell();
+}
+
+void seek(file *File, Int pos)
+{
+ File->seek(pos,pos >= 0);
+}
+
+void seekeof(file *File)
+{
+ File->seek(0,false);
+}
+
+// Set file dimensions
+file* dimension(file *File, Int nx)
+{
+ File->dimension(nx);
+ return File;
+}
+
+file* dimension(file *File, Int nx, Int ny)
+{
+ File->dimension(nx,ny);
+ return File;
+}
+
+file* dimension(file *File, Int nx, Int ny, Int nz)
+{
+ File->dimension(nx,ny,nz);
+ return File;
+}
+
+// Set file to read comma-separated values
+file* csv(file *File, bool b=true)
+{
+ File->CSVMode(b);
+ return File;
+}
+
+// Set file to read whitespace-separated values
+file* word(file *File, bool b=true)
+{
+ File->WordMode(b);
+ return File;
+}
+
+// Set file to read arrays in line-at-a-time mode
+file* line(file *File, bool b=true)
+{
+ File->LineMode(b);
+ return File;
+}
+
+// Set file to read/write single-precision XDR values.
+file* single(file *File, bool b=true)
+{
+ File->SingleReal(b);
+ File->SingleInt(b);
+ return File;
+}
+
+// Set file to read/write single-precision real XDR values.
+file* single(file *File, real x, bool b=true)
+{
+ File->SingleReal(b);
+ unused(&x);
+ return File;
+}
+
+// Set file to read/write single-precision int XDR values.
+file* single(file *File, Int x, bool b=true)
+{
+ File->SingleInt(b);
+ unused(&x);
+ return File;
+}
+
+// Set file to read an array1 (1 Int size followed by a 1d array)
+file* read1(file *File)
+{
+ File->dimension(-2);
+ return File;
+}
+
+// Set file to read an array2 (2 Int sizes followed by a 2d array)
+file* read2(file *File)
+{
+ File->dimension(-2,-2);
+ return File;
+}
+
+// Set file to read an array3 (3 Int sizes followed by a 3d array)
+file* read3(file *File)
+{
+ File->dimension(-2,-2,-2);
+ return File;
+}
+
+// Return the last n lines of the history named name.
+stringarray* history(string name, Int n=1)
+{
+#if defined(HAVE_LIBREADLINE) && defined(HAVE_LIBCURSES)
+ bool newhistory=historyMap.find(name) == historyMap.end();
+
+ string filename;
+
+ if(newhistory) {
+ filename=historyfilename(name);
+ std::ifstream exists(filename.c_str());
+ if(!exists) return new array(0);
+ }
+
+ store_history(&history_save);
+ HISTORY_STATE& history=historyMap[name].state;
+ history_set_history_state(&history);
+
+ if(newhistory)
+ read_history(filename.c_str());
+
+ array *a=get_history(n);
+
+ store_history(&history);
+ history_set_history_state(&history_save);
+
+ return a;
+#else
+ unused(&n);
+ return new array(0);
+#endif
+}
+
+// Return the last n lines of the interactive history.
+stringarray* history(Int n=0)
+{
+#if defined(HAVE_LIBREADLINE) && defined(HAVE_LIBCURSES)
+ return get_history(n);
+#else
+ unused(&n);
+ return new array(0);
+#endif
+}
+
+// Prompt for a string using prompt, the GNU readline library, and a
+// local history named name.
+string readline(string prompt=emptystring, string name=emptystring,
+ bool tabcompletion=false)
+{
+ if(!isatty(STDIN_FILENO))
+ return emptystring;
+#if defined(HAVE_LIBREADLINE) && defined(HAVE_LIBCURSES)
+ init_readline(tabcompletion);
+
+ store_history(&history_save);
+ bool newhistory=historyMap.find(name) == historyMap.end();
+ historyState& h=historyMap[name];
+ HISTORY_STATE& history=h.state;
+ history_set_history_state(&history);
+
+ if(newhistory)
+ read_history(historyfilename(name).c_str());
+
+ static char *line=NULL;
+ /* Return the memory to the free pool
+ if the buffer has already been allocated. */
+ if(line) {
+ free(line);
+ line=NULL;
+ }
+
+ /* Get a line from the user. */
+ line=readline(prompt.c_str());
+
+ if(!line) cout << endl;
+
+ history_set_history_state(&history_save);
+
+ return line ? string(line) : emptystring;
+#else
+ cout << prompt;
+ string s;
+ getline(cin,s);
+ unused(&tabcompletion); // Avoid unused variable warning message.
+ return s;
+#endif
+}
+
+// Save a string in a local history named name.
+// If store=true, store the local history in the file historyfilename(name).
+void saveline(string name, string value, bool store=true)
+{
+#if defined(HAVE_LIBREADLINE) && defined(HAVE_LIBCURSES)
+ store_history(&history_save);
+ bool newhistory=historyMap.find(name) == historyMap.end();
+ historyState& h=historyMap[name];
+ h.store=store;
+ HISTORY_STATE& history=h.state;
+ history_set_history_state(&history);
+
+ if(newhistory)
+ read_history(historyfilename(name).c_str());
+
+ if(value != "") {
+ add_history(value.c_str());
+ if(store) {
+ std::ofstream hout(historyfilename(name).c_str(),std::ios::app);
+ hout << value << endl;
+ }
+ }
+
+ store_history(&history);
+ history_set_history_state(&history_save);
+#else
+ unused(&store);
+#endif
+}
+
+void generate_random_backtrace()
+{
+#if defined(USEGC) && defined(GC_DEBUG) && defined(GC_BACKTRACE)
+ GC_generate_random_backtrace();
+#else
+ error("generate_random_backtrace() requires ./configure --enable-gc-debug");
+#endif
+}
+
+void print_random_addresses(Int n=1)
+{
+#if defined(USEGC) && defined(GC_DEBUG) && defined(GC_BACKTRACE)
+ GC_gcollect();
+ for (Int i=0; i < n; ++i)
+ GC_debug_print_heap_obj_proc(GC_base(GC_generate_random_valid_address()));
+#else
+ error("print_random_addresses() requires ./configure --enable-gc-debug");
+ unused(&n); // Avoid unused variable warning message.
+#endif
+}
diff --git a/Build/source/utils/asymptote/runtime.pl b/Build/source/utils/asymptote/runtime.pl
new file mode 100755
index 00000000000..74dde0506aa
--- /dev/null
+++ b/Build/source/utils/asymptote/runtime.pl
@@ -0,0 +1,182 @@
+#!/usr/bin/env perl
+######
+# runtime.pl
+# Tom Prince 2004/4/15
+#
+# Generate the runtime functions used by the vm::stack machine.
+#
+#####
+
+$stack = "Stack";
+
+sub clean_type {
+ for (@_) {
+ s/\s//g;
+ }
+}
+
+sub clean_params {
+ for (@_) {
+ s/\n//g;
+ }
+}
+
+my %type_map;
+sub read_types {
+ my @types = split /\n/, shift;
+ for (@types) {
+ my ($type,$code) =
+ m|(\w*(?:\s*\*)?)
+ \s*=>\s*
+ (.*)
+ |x;
+ clean_type($type);
+ $type_map{$type} = $code;
+ }
+}
+
+sub asy_params {
+ my @params = @_;
+ for (@params) {
+ my ($explicit, $type, $name, $default) =
+ m|^\s*
+ (explicit)*\s*(\w*(?:\s*\*)?)
+ \s*
+ (\w*)(=*)|xs;
+ clean_type($type);
+ $_ = "formal(" . $type_map{$type} . ", \"" . lc($name) . "\"" . ", " .
+ ($default ? "true" : "false") . ", " .
+ ($explicit ? "true" : "false") . ")";
+ }
+ return @params;
+}
+
+sub c_params {
+ my @params = @_;
+ for (@params) {
+ my ($explicit, $type, $name, $default, $value) =
+ m|^\s*
+ (explicit)*\s*(\w*(?:\s*\*)?)
+ \s*
+ (\w*)(=*)([\w.+\-]*)|xs;
+ $_ = " $type $name=vm::pop" . ($type =~ /^item$/ ? "" : "<$type>") .
+ "($stack" . ($default ? "," . $value : "") . ");\n";
+ }
+ reverse @params;
+}
+
+$/ = "\f\n";
+
+open STDIN, "<runtime.in";
+open STDOUT, ">runtime.cc";
+
+my $autogenerated=
+"/***** Autogenerated from runtime.in; changes will be overwritten *****/\n\n";
+
+my $source_line = 1;
+
+print $autogenerated;
+
+print "#line $source_line \"runtime.in\"\n";
+$header = <>;
+print $header;
+$source_line += ($header =~ tr/\n//);;
+
+$types = <>;
+$source_line += ($types =~ tr/\n//);;
+
+print "#line $source_line \"runtime.in\"\n";
+$header = <>;
+print $header;
+$source_line += ($header =~ tr/\n//);;
+
+print "\nnamespace run {\n";
+
+read_types($types);
+
+### Begining of `runtime.h'
+push @header, $autogenerated;
+push @header, "#ifndef RUNTIME_H\n";
+push @header, "#define RUNTIME_H\n\n";
+push @header, "namespace run {\n";
+
+my $count = 0;
+while (<>) {
+ my ($comments,$type,$name,$cname,$params,$code) =
+ m|^((?:\s*//[^\n]*\n)*) # comment lines
+ \s*
+ (\w*(?:\s*\*)?) # return type
+ \s*
+ ([^(:]*)\:*([^(]*) # function name
+ \s*
+ \(([\w\s*,=.+\-]*)\) # parameters
+ \s*
+ \{(.*)} # body
+ |xs;
+
+ if($cname) {push @header, "void $cname(vm::stack *);\n";}
+ else {$cname="gen${count}";} # Unique C++ function name
+
+ clean_type($type);
+
+ my @params = split m/,\s*/, $params;
+
+ # Build addFunc call for asymptote
+ if($name) {
+ $name =~ s/Operator\s*//;
+ push @builtin, "#line $source_line \"runtime.in\"\n"
+ . " addFunc(ve, run::" . $cname
+ . ", " . $type_map{$type}
+ . ", " . '"' . $name . '"'
+ . ( @params ? ", " . join(", ",asy_params(@params))
+ : "" )
+ . ");\n";
+ }
+
+ # Handle marshalling of values to/from stack
+ $qualifier = ($type eq "item" ? "" : "<$type>");
+ $code =~ s/\breturn ([^;]*);/{$stack->push$qualifier($1); return;}/g;
+ $args = join("",c_params(@params));
+
+ print $comments;
+ $ncomments = ($comments =~ tr/\n//);
+ $source_line += $ncomments;
+ print "#line $source_line \"runtime.in\"\n";
+ my $prototype=$type . " " . $name . "(" . $params . ");";
+ $nprototype = ($prototype =~ tr/\n//)+1;
+ $source_line += $nprototype;
+ if($name) {
+ clean_params($prototype);
+ print "// $prototype\n";
+ }
+ print "void $cname(stack *";
+ if($type ne "void" or $params ne "") {print $stack;}
+ print ")\n{\n$args";
+ print "#line $source_line \"runtime.in\"";
+ print "$code}\n\n";
+
+ $source_line -= $ncomments+$nprototype;
+ $source_line += ($_ =~ tr/\n//);
+ ++$count;
+}
+
+print "} // namespace run\n";
+
+print "\nnamespace trans {\n\n";
+print "void gen_base_venv(venv &ve)\n{\n";
+print @builtin;
+print "}\n\n";
+print "} // namespace trans\n";
+
+### End of `header.h'
+push @header, "}\n\n";
+push @header, "#endif // RUNTIME_H\n";
+
+undef $/;
+open HEADER, "<", "runtime.h";
+$orig_header = <HEADER>;
+$new_header = join "", @header;
+if ($new_header ne $orig_header) {
+ open HEADER, ">", "runtime.h";
+ print HEADER $new_header;
+}
diff --git a/Build/source/utils/asymptote/settings.cc b/Build/source/utils/asymptote/settings.cc
new file mode 100644
index 00000000000..a4961176660
--- /dev/null
+++ b/Build/source/utils/asymptote/settings.cc
@@ -0,0 +1,1391 @@
+/*****
+ * settings.cc
+ * Andy Hammerlindl 2004/05/10
+ *
+ * Declares a list of global variables that act as settings in the system.
+ *****/
+
+#include <iostream>
+#include <iomanip>
+#include <cstdlib>
+#include <cerrno>
+#include <sys/stat.h>
+#include <cfloat>
+#include <locale.h>
+#include <unistd.h>
+#include <algorithm>
+
+#include "common.h"
+
+#if HAVE_GNU_GETOPT_H
+#include <getopt.h>
+#else
+#include "getopt.h"
+#endif
+
+#include "util.h"
+#include "settings.h"
+#include "interact.h"
+#include "locate.h"
+#include "lexical.h"
+#include "record.h"
+#include "env.h"
+#include "item.h"
+#include "refaccess.h"
+#include "pipestream.h"
+
+#ifdef HAVE_LIBCURSES
+extern "C" {
+
+#ifdef HAVE_NCURSES_CURSES_H
+#include <ncurses/curses.h>
+#include <ncurses/term.h>
+#elif HAVE_NCURSES_H
+#include <ncurses.h>
+#include <term.h>
+#elif HAVE_CURSES_H
+#include <curses.h>
+#include <term.h>
+#endif
+}
+#endif
+
+// Workaround broken curses.h files:
+#ifdef clear
+#undef clear
+#endif
+
+using vm::item;
+
+using trans::itemRefAccess;
+using trans::refAccess;
+using trans::varEntry;
+
+void doConfig(string filename);
+
+namespace settings {
+
+using camp::pair;
+
+string asyInstallDir;
+string defaultXasy="xasy";
+
+#ifdef HAVE_LIBGL
+const bool haveglut=true;
+#else
+const bool haveglut=false;
+#endif
+
+#ifndef __CYGWIN__
+
+bool msdos=false;
+const char *HOME="HOME";
+const char pathSeparator=':';
+string defaultPSViewer="gv";
+#ifdef __APPLE__
+string defaultPDFViewer="open";
+#else
+string defaultPDFViewer="acroread";
+#endif
+string defaultGhostscript="gs";
+string defaultPython;
+string defaultDisplay="display";
+string systemDir=ASYMPTOTE_SYSDIR;
+const string docdir=ASYMPTOTE_DOCDIR;
+void queryRegistry() {}
+const string dirsep="/";
+
+#else
+
+bool msdos=true;
+const char *HOME="USERPROFILE";
+const char pathSeparator=';';
+string defaultPSViewer="gsview32.exe";
+string defaultPDFViewer="AcroRd32.exe";
+string defaultGhostscript="gswin32c.exe";
+string defaultPython="python.exe";
+string defaultDisplay="imdisplay";
+string systemDir;
+const string docdir=".";
+const string dirsep="\\";
+
+#include <dirent.h>
+
+// Use key to look up an entry in the MSWindows registry, respecting wild cards
+string getEntry(const string& key)
+{
+ string path="/proc/registry/HKEY_LOCAL_MACHINE/SOFTWARE/"+key;
+ size_t star;
+ string head;
+ while((star=path.find("*")) < string::npos) {
+ string prefix=path.substr(0,star);
+ string suffix=path.substr(star+1);
+ size_t slash=suffix.find("/");
+ if(slash < string::npos) {
+ path=suffix.substr(slash);
+ suffix=suffix.substr(0,slash);
+ } else {
+ path=suffix;
+ suffix="";
+ }
+ string directory=head+stripFile(prefix);
+ string file=stripDir(prefix);
+ DIR *dir=opendir(directory.c_str());
+ if(dir == NULL) return "";
+ dirent *p;
+ string rsuffix=suffix;
+ reverse(rsuffix.begin(),rsuffix.end());
+ while((p=readdir(dir)) != NULL) {
+ string dname=p->d_name;
+ string rdname=dname;
+ reverse(rdname.begin(),rdname.end());
+ if(dname != "." && dname != ".." &&
+ dname.substr(0,file.size()) == file &&
+ rdname.substr(0,suffix.size()) == rsuffix) {
+ head=directory+p->d_name;
+ break;
+ }
+ }
+ if(p == NULL) return "";
+ }
+ std::ifstream fin((head+path).c_str());
+ if(fin) {
+ string s;
+ getline(fin,s);
+ size_t end=s.find('\0');
+ if(end < string::npos)
+ return s.substr(0,end);
+ }
+ return "";
+}
+
+void queryRegistry()
+{
+ string gs=getEntry("GPL Ghostscript/*/GS_DLL");
+ if(gs.empty())
+ gs=getEntry("AFPL Ghostscript/*/GS_DLL");
+ defaultGhostscript=stripFile(gs)+defaultGhostscript;
+ defaultPDFViewer=getEntry("Adobe/Acrobat Reader/*/InstallPath/@")+"\\"+
+ defaultPDFViewer;
+ defaultPSViewer=getEntry("Ghostgum/GSview/*")+"\\gsview\\"+defaultPSViewer;
+ defaultPython=getEntry("Python/PythonCore/*/InstallPath/@")+defaultPython;
+ systemDir=getEntry("Microsoft/Windows/CurrentVersion/App Paths/Asymptote/Path");
+ defaultXasy=asyInstallDir+"\\"+defaultXasy;
+}
+
+#endif
+
+const char PROGRAM[]=PACKAGE_NAME;
+const char VERSION[]=PACKAGE_VERSION;
+const char BUGREPORT[]=PACKAGE_BUGREPORT;
+
+// The name of the program (as called). Used when displaying help info.
+char *argv0;
+
+// The verbosity setting, a global variable.
+Int verbose;
+
+// Colorspace conversion flags (stored in global variables for efficiency).
+bool gray;
+bool bw;
+bool rgb;
+bool cmyk;
+
+// Disable system calls.
+bool safe=true;
+// Enable writing to (or changing to) other directories
+bool globaloption=false;
+
+bool globalwrite() {return globaloption || !safe;}
+
+const string suffix="asy";
+const string guisuffix="gui";
+
+string initdir;
+string historyname;
+
+// Local versions of the argument list.
+int argCount = 0;
+char **argList = 0;
+
+typedef ::option c_option;
+
+types::dummyRecord *settingsModule;
+
+types::record *getSettingsModule() {
+ return settingsModule;
+}
+
+// The dictionaries of long options and short options.
+class option;
+typedef mem::map<CONST string, option *> optionsMap_t;
+optionsMap_t optionsMap;
+
+typedef mem::map<CONST char, option *> codeMap_t;
+codeMap_t codeMap;
+
+struct option : public gc {
+ string name;
+ char code; // Command line option, i.e. 'V' for -V.
+ bool argument; // If it takes an argument on the command line. This is set
+ // based on whether argname is empty.
+ string argname; // The argument name for printing the description.
+ string desc; // One line description of what the option does.
+ bool cmdlineonly; // If it is only available on the command line.
+ string Default; // A string containing an optional default value.
+
+ option(string name, char code, string argname, string desc,
+ bool cmdlineonly=false, string Default="")
+ : name(name), code(code), argument(!argname.empty()), argname(argname),
+ desc(desc), cmdlineonly(cmdlineonly), Default(Default) {}
+
+ virtual ~option() {}
+
+ // Builds this option's contribution to the optstring argument of get_opt().
+ virtual string optstring() {
+ if (code) {
+ string base;
+ base.push_back(code);
+ if(argument) base.push_back(':');
+ return base;
+ }
+ else return "";
+ }
+
+ // Sets the contribution to the longopt array.
+ virtual void longopt(c_option &o) {
+ o.name=name.c_str();
+ o.has_arg=argument ? 1 : 0;
+ o.flag=0;
+ o.val=0;
+ }
+
+ // Add to the dictionaries of options.
+ virtual void add() {
+ optionsMap[name]=this;
+ if (code)
+ codeMap[code]=this;
+ }
+
+ // Set the option from the command-line argument. Return true if the option
+ // was correctly parsed.
+ virtual bool getOption() = 0;
+
+ void error(string msg) {
+ cerr << endl << argv0 << ": ";
+ if (code)
+ cerr << "-" << code << " ";
+ cerr << "(-" << name << ") " << msg << endl;
+ }
+
+ // The "-f,-outformat format" part of the option.
+ virtual string describeStart() {
+ ostringstream ss;
+ if (code)
+ ss << "-" << code << ",";
+ ss << "-" << name;
+ if (argument)
+ ss << " " << argname;
+ return ss.str();
+ }
+
+ // Outputs description of the command for the -help option.
+ virtual void describe() {
+ // Don't show the option if it has no desciption.
+ if (!desc.empty()) {
+ const unsigned WIDTH=22;
+ string start=describeStart();
+ cerr << std::left << std::setw(WIDTH) << start;
+ if (start.size() >= WIDTH) {
+ cerr << endl;
+ cerr << std::left << std::setw(WIDTH) << "";
+ }
+ cerr << desc;
+ if(cmdlineonly) cerr << "; command-line only";
+ if(Default != "")
+ cerr << " [" << Default << "]";
+ cerr << endl;
+ }
+ }
+
+ virtual void reset() {
+ }
+};
+
+const string noarg;
+
+struct setting : public option {
+ types::ty *t;
+
+private:
+ trans::permission perm;
+ bool added;
+
+ // Flag the setting as secure, so that it can only be set on the command-line,
+ // though it can still be read in Asymptote code.
+ void secure() {
+ assert(!added);
+ perm = trans::RESTRICTED;
+ }
+
+public:
+ setting(string name, char code, string argname, string desc,
+ types::ty *t, string Default)
+ : option(name, code, argname, desc, false,Default),
+ t(t), perm(trans::PUBLIC), added(false) {}
+
+ void reset() = 0;
+
+ virtual trans::access *buildAccess() = 0;
+
+ // Add to the dictionaries of options and to the settings module.
+ virtual void add() {
+ assert(!added);
+
+ option::add();
+ settingsModule->add(name, t, buildAccess(), perm);
+
+ added=true;
+ }
+
+ friend void addSecureSetting(setting *s) {
+ s->secure();
+ s->add();
+ }
+};
+
+struct itemSetting : public setting {
+ item defaultValue;
+ item value;
+
+ itemSetting(string name, char code,
+ string argname, string desc,
+ types::ty *t, item defaultValue, string Default="")
+ : setting(name, code, argname, desc, t, Default),
+ defaultValue(defaultValue) {reset();}
+
+ void reset() {
+ value=defaultValue;
+ }
+
+ trans::access *buildAccess() {
+ return new itemRefAccess(&(value));
+ }
+};
+
+item& Setting(string name) {
+ itemSetting *s=dynamic_cast<itemSetting *>(optionsMap[name]);
+ if(!s) {
+ cerr << "Cannot find setting named '" << name << "'" << endl;
+ exit(-1);
+ }
+ return s->value;
+}
+
+struct boolSetting : public itemSetting {
+ boolSetting(string name, char code, string desc,
+ bool defaultValue=false)
+ : itemSetting(name, code, noarg, desc,
+ types::primBoolean(), (item)defaultValue,
+ defaultValue ? "true" : "false") {}
+
+ bool getOption() {
+ value=(item)true;
+ return true;
+ }
+
+ option *negation(string name) {
+ struct negOption : public option {
+ boolSetting &base;
+
+ negOption(boolSetting &base, string name)
+ : option(name, 0, noarg, ""), base(base) {}
+
+ bool getOption() {
+ base.value=(item)false;
+ return true;
+ }
+ };
+ return new negOption(*this, name);
+ }
+
+ void add() {
+ setting::add();
+ negation("no"+name)->add();
+ if (code) {
+ string nocode="no"; nocode.push_back(code);
+ negation(nocode)->add();
+ }
+ }
+
+ // Set several related boolean options at once. Used for view and trap which
+ // have batch and interactive settings.
+ struct multiOption : public option {
+ typedef mem::list<boolSetting *> setlist;
+ setlist set;
+ multiOption(string name, char code, string desc)
+ : option(name, code, noarg, desc, true) {}
+
+ void add(boolSetting *s) {
+ set.push_back(s);
+ }
+
+ void setValue(bool value) {
+ for (setlist::iterator s=set.begin(); s!=set.end(); ++s)
+ (*s)->value=(item)value;
+ }
+
+ bool getOption() {
+ setValue(true);
+ return true;
+ }
+
+ option *negation(string name) {
+ struct negOption : public option {
+ multiOption &base;
+
+ negOption(multiOption &base, string name)
+ : option(name, 0, noarg, ""), base(base) {}
+
+ bool getOption() {
+ base.setValue(false);
+ return true;
+ }
+ };
+ return new negOption(*this, name);
+ }
+
+ void add() {
+ option::add();
+ negation("no"+name)->add();
+ if (code) {
+ string nocode="no"; nocode.push_back(code);
+ negation(nocode)->add();
+ }
+
+ for (multiOption::setlist::iterator s=set.begin(); s!=set.end(); ++s)
+ (*s)->add();
+ }
+ };
+};
+
+typedef boolSetting::multiOption multiOption;
+
+struct argumentSetting : public itemSetting {
+ argumentSetting(string name, char code,
+ string argname, string desc,
+ types::ty *t, item defaultValue)
+ : itemSetting(name, code, argname, desc, t, defaultValue)
+ {
+ assert(!argname.empty());
+ }
+};
+
+struct stringSetting : public argumentSetting {
+ stringSetting(string name, char code,
+ string argname, string desc,
+ string defaultValue)
+ : argumentSetting(name, code, argname, desc.empty() ? "" :
+ desc+(defaultValue.empty() ? "" : " ["+defaultValue+"]"),
+ types::primString(), (item)defaultValue) {}
+
+ bool getOption() {
+ value=(item)(string)optarg;
+ return true;
+ }
+};
+
+struct userSetting : public argumentSetting {
+ userSetting(string name, char code,
+ string argname, string desc,
+ string defaultValue)
+ : argumentSetting(name, code, argname, desc,
+ types::primString(), (item)defaultValue) {}
+
+ bool getOption() {
+ string s=vm::get<string>(value)+string(optarg);
+ s.push_back(';');
+ value=(item) s;
+ return true;
+ }
+};
+
+string GetEnv(string s, string Default) {
+ transform(s.begin(), s.end(), s.begin(), toupper);
+ string t=Getenv(("ASYMPTOTE_"+s).c_str(),msdos);
+ return t != "" ? string(t) : Default;
+}
+
+struct envSetting : public stringSetting {
+ envSetting(string name, string Default)
+ : stringSetting(name, 0, " ", "", GetEnv(name,Default)) {}
+};
+
+template<class T>
+struct dataSetting : public argumentSetting {
+ string text;
+ dataSetting(const char *text, string name, char code,
+ string argname, string desc, types::ty *type,
+ T defaultValue)
+ : argumentSetting(name, code, argname, desc,
+ type, (item)defaultValue), text(text) {}
+
+ bool getOption() {
+ try {
+ value=(item)lexical::cast<T>(optarg);
+ } catch (lexical::bad_cast&) {
+ error("option requires " + text + " as an argument");
+ return false;
+ }
+ return true;
+ }
+};
+
+template<class T>
+string String(T x)
+{
+ ostringstream buf;
+ buf << x;
+ return buf.str();
+}
+
+template<class T>
+string description(string desc, T defaultValue)
+{
+ return desc.empty() ? "" : desc+" ["+String(defaultValue)+"]";
+}
+
+struct IntSetting : public dataSetting<Int> {
+ IntSetting(string name, char code,
+ string argname, string desc, Int defaultValue=0)
+ : dataSetting<Int>("an int", name, code, argname,
+ description(desc,defaultValue),
+ types::primInt(), defaultValue) {}
+};
+
+struct realSetting : public dataSetting<double> {
+ realSetting(string name, char code,
+ string argname, string desc, double defaultValue=0.0)
+ : dataSetting<double>("a real", name, code, argname,
+ description(desc,defaultValue),
+ types::primReal(), defaultValue) {}
+};
+
+struct pairSetting : public dataSetting<pair> {
+ pairSetting(string name, char code,
+ string argname, string desc, pair defaultValue=0.0)
+ : dataSetting<pair>("a pair", name, code, argname,
+ description(desc,defaultValue),
+ types::primPair(), defaultValue) {}
+};
+
+// For setting the alignment of a figure on the page.
+struct alignSetting : public argumentSetting {
+ alignSetting(string name, char code,
+ string argname, string desc,
+ Int defaultValue=(Int) CENTER)
+ : argumentSetting(name, code, argname, desc,
+ types::primInt(), (item)defaultValue) {}
+
+ bool getOption() {
+ string str=optarg;
+ if (str == "C")
+ value=(Int) CENTER;
+ else if (str == "T")
+ value=(Int) TOP;
+ else if (str == "B")
+ value=(Int) BOTTOM;
+ else if (str == "Z") {
+ value=(Int) ZERO;
+ } else {
+ error("invalid argument for option");
+ return false;
+ }
+ return true;
+ }
+};
+
+template<class T>
+string stringCast(T x)
+{
+ ostringstream buf;
+ buf.precision(DBL_DIG);
+ buf.setf(std::ios::boolalpha);
+ buf << x;
+ return string(buf.str());
+}
+
+template <class T>
+struct refSetting : public setting {
+ T *ref;
+ T defaultValue;
+ string text;
+
+ refSetting(string name, char code, string argname,
+ string desc, types::ty *t, T *ref, T defaultValue,
+ const char *text="")
+ : setting(name, code, argname, desc, t, stringCast(defaultValue)),
+ ref(ref), defaultValue(defaultValue), text(text) {
+ reset();
+ }
+
+ virtual bool getOption() {
+ try {
+ *ref=lexical::cast<T>(optarg);
+ } catch (lexical::bad_cast&) {
+ error("option requires " + text + " as an argument");
+ return false;
+ }
+ return true;
+ }
+
+ virtual void reset() {
+ *ref=defaultValue;
+ }
+
+ trans::access *buildAccess() {
+ return new refAccess<T>(ref);
+ }
+};
+
+struct boolrefSetting : public refSetting<bool> {
+ boolrefSetting(string name, char code, string desc, bool *ref,
+ bool Default=false)
+ : refSetting<bool>(name, code, noarg, desc,
+ types::primBoolean(), ref, Default) {}
+ bool getOption() {
+ *ref=true;
+ return true;
+ }
+
+ option *negation(string name) {
+ struct negOption : public option {
+ boolrefSetting &base;
+
+ negOption(boolrefSetting &base, string name)
+ : option(name, 0, noarg, ""), base(base) {}
+
+ bool getOption() {
+ *(base.ref)=false;
+ return true;
+ }
+ };
+ return new negOption(*this, name);
+ }
+
+ void add() {
+ setting::add();
+ negation("no"+name)->add();
+ if (code) {
+ string nocode="no"; nocode.push_back(code);
+ negation(nocode)->add();
+ }
+ }
+};
+
+struct incrementSetting : public refSetting<Int> {
+ incrementSetting(string name, char code, string desc, Int *ref)
+ : refSetting<Int>(name, code, noarg, desc,
+ types::primInt(), ref, 0) {}
+
+ bool getOption() {
+ // Increment the value.
+ ++(*ref);
+ return true;
+ }
+
+ option *negation(string name) {
+ struct negOption : public option {
+ incrementSetting &base;
+
+ negOption(incrementSetting &base, string name)
+ : option(name, 0, noarg, ""), base(base) {}
+
+ bool getOption() {
+ if(*base.ref) --(*base.ref);
+ return true;
+ }
+ };
+ return new negOption(*this, name);
+ }
+
+ void add() {
+ setting::add();
+ negation("no"+name)->add();
+ if (code) {
+ string nocode="no"; nocode.push_back(code);
+ negation(nocode)->add();
+ }
+ }
+};
+
+struct incrementOption : public option {
+ Int *ref;
+ Int level;
+
+ incrementOption(string name, char code, string desc, Int *ref,
+ Int level=1)
+ : option(name, code, noarg, desc, true), ref(ref), level(level) {}
+
+ bool getOption() {
+ // Increment the value.
+ (*ref) += level;
+ return true;
+ }
+};
+
+void addOption(option *o) {
+ o->add();
+}
+
+void version()
+{
+ cerr << PROGRAM << " version " << VERSION << SVN_REVISION
+ << " [(C) 2004 Andy Hammerlindl, John C. Bowman, Tom Prince]"
+ << endl;
+}
+
+void usage(const char *program)
+{
+ version();
+ cerr << "\t\t\t" << "http://asymptote.sourceforge.net/"
+ << endl
+ << "Usage: " << program << " [options] [file ...]"
+ << endl;
+}
+
+void reportSyntax() {
+ cerr << endl;
+ usage(argv0);
+ cerr << endl << "Type '" << argv0
+ << " -h' for a description of options." << endl;
+ exit(1);
+}
+
+void displayOptions()
+{
+ cerr << endl;
+ cerr << "Options (negate by replacing - with -no): "
+ << endl << endl;
+ for (optionsMap_t::iterator opt=optionsMap.begin();
+ opt!=optionsMap.end();
+ ++opt)
+ opt->second->describe();
+}
+
+struct helpOption : public option {
+ helpOption(string name, char code, string desc)
+ : option(name, code, noarg, desc, true) {}
+
+ bool getOption() {
+ usage(argv0);
+ displayOptions();
+ cerr << endl;
+ exit(0);
+
+ // Unreachable code.
+ return true;
+ }
+};
+
+struct versionOption : public option {
+ versionOption(string name, char code, string desc)
+ : option(name, code, noarg, desc, true) {}
+
+ bool getOption() {
+ version();
+ exit(0);
+
+ // Unreachable code.
+ return true;
+ }
+};
+
+struct divisorOption : public option {
+ divisorOption(string name, char code, string argname, string desc)
+ : option(name, code, argname, desc) {}
+
+ bool getOption() {
+ try {
+#ifdef USEGC
+ Int n=lexical::cast<Int>(optarg);
+ if(n > 0) GC_set_free_space_divisor((GC_word) n);
+#endif
+ } catch (lexical::bad_cast&) {
+ error("option requires an int as an argument");
+ return false;
+ }
+ return true;
+ }
+};
+
+// For security reasons, these options aren't fields of the settings module.
+struct stringOption : public option {
+ char **variable;
+ stringOption(string name, char code, string argname,
+ string desc, char **variable)
+ : option(name, code, argname, desc, true), variable(variable) {}
+
+ bool getOption() {
+ *variable=optarg;
+ return true;
+ }
+};
+
+string build_optstring() {
+ string s;
+ for (codeMap_t::iterator p=codeMap.begin(); p !=codeMap.end(); ++p)
+ s +=p->second->optstring();
+
+ return s;
+}
+
+c_option *build_longopts() {
+ size_t n=optionsMap.size();
+
+ c_option *longopts=new(UseGC) c_option[n+1];
+ Int i=0;
+ for (optionsMap_t::iterator p=optionsMap.begin();
+ p !=optionsMap.end();
+ ++p, ++i)
+ p->second->longopt(longopts[i]);
+
+ longopts[n].name=NULL;
+ longopts[n].has_arg=0;
+ longopts[n].flag=NULL;
+ longopts[n].val=0;
+
+ return longopts;
+}
+
+void resetOptions()
+{
+ for(optionsMap_t::iterator opt=optionsMap.begin(); opt != optionsMap.end();
+ ++opt)
+ if(opt->first != "config" && opt->first != "dir")
+ opt->second->reset();
+}
+
+void getOptions(int argc, char *argv[])
+{
+ bool syntax=false;
+ optind=0;
+
+ string optstring=build_optstring();
+ //cerr << "optstring: " << optstring << endl;
+ c_option *longopts=build_longopts();
+ int long_index = 0;
+
+ errno=0;
+ for(;;) {
+ int c = getopt_long_only(argc,argv,
+ optstring.c_str(), longopts, &long_index);
+ if (c == -1)
+ break;
+
+ if (c == 0) {
+ const char *name=longopts[long_index].name;
+ //cerr << "long option: " << name << endl;
+ if (!optionsMap[name]->getOption())
+ syntax=true;
+ }
+ else if (codeMap.find((char)c) != codeMap.end()) {
+ //cerr << "char option: " << (char)c << endl;
+ if (!codeMap[(char)c]->getOption())
+ syntax=true;
+ }
+ else {
+ syntax=true;
+ }
+
+ errno=0;
+ }
+
+ if (syntax)
+ reportSyntax();
+}
+
+#ifdef USEGC
+void no_GCwarn(char *, GC_word)
+{
+}
+#endif
+
+void initSettings() {
+ static bool initialize=true;
+ if(initialize) {
+ queryRegistry();
+ initialize=false;
+ }
+
+ settingsModule=new types::dummyRecord(symbol::trans("settings"));
+
+ multiOption *view=new multiOption("View", 'V', "View output");
+ view->add(new boolSetting("batchView", 0, "View output in batch mode",
+ msdos));
+ view->add(new boolSetting("multipleView", 0,
+ "View output from multiple batch-mode files",
+ false));
+ view->add(new boolSetting("interactiveView", 0,
+ "View output in interactive mode", true));
+ addOption(view);
+ addOption(new stringSetting("xformat", 0, "format",
+ "GUI deconstruction format","png"));
+ addOption(new stringSetting("outformat", 'f', "format",
+ "Convert each output file to specified format",
+ ""));
+ addOption(new boolSetting("prc", 0,
+ "Embed 3D PRC graphics in PDF output", true));
+ addOption(new boolSetting("toolbar", 0,
+ "Show 3D toolbar in PDF output", true));
+ addOption(new realSetting("render", 0, "n",
+ "Render 3D graphics using n pixels per bp (-1=auto)",
+ haveglut ? -1.0 : 0.0));
+ addOption(new IntSetting("antialias", 0, "n",
+ "Antialiasing width for rasterized output", 2));
+ addOption(new IntSetting("multisample", 0, "n",
+ "Multisampling width for screen images", 4));
+ addOption(new boolSetting("twosided", 0,
+ "Use two-sided 3D lighting model for rendering",
+ true));
+ addOption(new pairSetting("position", 0, "pair",
+ "Initial 3D rendering screen position"));
+ addOption(new pairSetting("maxviewport", 0, "pair",
+ "Maximum viewport size",pair(2048,2048)));
+ addOption(new pairSetting("maxtile", 0, "pair",
+ "Maximum rendering tile size",pair(0,0)));
+ addOption(new boolSetting("iconify", 0,
+ "Iconify rendering window", false));
+ addOption(new boolSetting("thick", 0,
+ "Render thick 3D lines", true));
+ addOption(new boolSetting("thin", 0,
+ "Render thin 3D lines", true));
+ addOption(new boolSetting("threads", 0,
+ "Use POSIX threads for 3D rendering", !msdos));
+ addOption(new boolSetting("fitscreen", 0,
+ "Fit rendered image to screen", true));
+ addOption(new boolSetting("interactiveWrite", 0,
+ "Write expressions entered at the prompt to stdout",
+ true));
+ addOption(new helpOption("help", 'h', "Show summary of options"));
+ addOption(new versionOption("version", 0, "Show version"));
+
+ addOption(new pairSetting("offset", 'O', "pair", "PostScript offset"));
+ addOption(new alignSetting("align", 'a', "C|B|T|Z",
+ "Center, Bottom, Top, or Zero page alignment [Center]"));
+
+ addOption(new boolSetting("debug", 'd', "Enable debugging messages"));
+ addOption(new incrementSetting("verbose", 'v',
+ "Increase verbosity level", &verbose));
+ // Resolve ambiguity with --version
+ addOption(new incrementOption("vv", 0,"", &verbose,2));
+ addOption(new incrementOption("novv", 0,"", &verbose,-2));
+
+ addOption(new boolSetting("keep", 'k', "Keep intermediate files"));
+ addOption(new boolSetting("keepaux", 0,
+ "Keep intermediate LaTeX .aux files"));
+ addOption(new stringSetting("tex", 0,"engine",
+ "latex|pdflatex|xelatex|tex|pdftex|none",
+ "latex"));
+ addOption(new boolSetting("twice", 0,
+ "Run LaTeX twice (to resolve references)"));
+ addOption(new boolSetting("inlinetex", 0, "Generate inline TeX code"));
+ addOption(new boolSetting("embed", 0, "Embed rendered preview image", true));
+ addOption(new boolSetting("auto3D", 0, "Automatically activate 3D scene",
+ true));
+ addOption(new boolSetting("inlineimage", 0,
+ "Generate inline embedded image"));
+ addOption(new boolSetting("parseonly", 'p', "Parse file"));
+ addOption(new boolSetting("translate", 's',
+ "Show translated virtual machine code"));
+ addOption(new boolSetting("tabcompletion", 0,
+ "Interactive prompt auto-completion", true));
+ addOption(new boolSetting("listvariables", 'l',
+ "List available global functions and variables"));
+ addOption(new boolSetting("where", 0,
+ "Show where listed variables are declared"));
+
+ multiOption *mask=new multiOption("mask", 'm',
+ "Mask fpu exceptions");
+ mask->add(new boolSetting("batchMask", 0,
+ "Mask fpu exceptions in batch mode", false));
+ mask->add(new boolSetting("interactiveMask", 0,
+ "Mask fpu exceptions in interactive mode", true));
+ addOption(mask);
+
+ addOption(new boolrefSetting("bw", 0,
+ "Convert all colors to black and white",&bw));
+ addOption(new boolrefSetting("gray", 0, "Convert all colors to grayscale",
+ &gray));
+ addOption(new boolrefSetting("rgb", 0, "Convert cmyk colors to rgb",&rgb));
+ addOption(new boolrefSetting("cmyk", 0, "Convert rgb colors to cmyk",&cmyk));
+
+ addSecureSetting(new boolrefSetting("safe", 0, "Disable system call",
+ &safe, true));
+ addSecureSetting(new boolrefSetting("globalwrite", 0,
+ "Allow write to other directory",
+ &globaloption, false));
+ addSecureSetting(new stringSetting("outname", 'o', "name",
+ "Alternative output directory/filename",
+ ""));
+ addOption(new stringOption("cd", 0, "directory", "Set current directory",
+ &startpath));
+
+#ifdef USEGC
+ addOption(new boolrefSetting("compact", 0,
+ "Conserve memory at the expense of speed",
+ (bool *) &GC_dont_expand));
+ addOption(new divisorOption("divisor", 0, "n",
+ "Garbage collect using purge(divisor=n) [2]"));
+#endif
+
+ addOption(new stringSetting("prompt", 0,"string","Prompt","> "));
+ addOption(new stringSetting("prompt2", 0,"string",
+ "Continuation prompt for multiline input ",
+ ".."));
+ addOption(new boolSetting("multiline", 0,
+ "Input code over multiple lines at the prompt"));
+
+ addOption(new boolSetting("wait", 0,
+ "Wait for child processes to finish before exiting"));
+ // Be interactive even in a pipe
+ addOption(new boolSetting("interactive", 0, ""));
+ addOption(new boolSetting("exitonEOF", 0, "Exit interactive mode on EOF",
+ true));
+
+ addOption(new boolSetting("quiet", 'q',
+ "Suppress welcome message"));
+ addOption(new boolSetting("localhistory", 0,
+ "Use a local interactive history file"));
+ addOption(new IntSetting("historylines", 0, "n",
+ "Retain n lines of history",1000));
+ addOption(new IntSetting("scroll", 0, "n",
+ "Scroll standard output n lines at a time",0));
+ addOption(new IntSetting("level", 0, "n", "Postscript level",3));
+ addOption(new boolSetting("autoplain", 0,
+ "Enable automatic importing of plain",
+ true));
+ addOption(new boolSetting("autorotate", 0,
+ "Enable automatic PDF page rotation",
+ false));
+ addOption(new boolSetting("pdfreload", 0,
+ "Automatically reload document in pdfviewer",
+ false));
+ addOption(new IntSetting("pdfreloaddelay", 0, "usec",
+ "Delay before attempting initial pdf reload"
+ ,750000));
+ addOption(new stringSetting("autoimport", 0, "string",
+ "Module to automatically import", ""));
+ addOption(new userSetting("command", 'c', "string",
+ "Command to autoexecute", ""));
+ addOption(new userSetting("user", 'u', "string",
+ "General purpose user string", ""));
+
+ addOption(new realSetting("paperwidth", 0, "bp", ""));
+ addOption(new realSetting("paperheight", 0, "bp", ""));
+
+ addOption(new stringSetting("dvipsOptions", 0, "string", "", ""));
+ addOption(new stringSetting("convertOptions", 0, "string", "", ""));
+ addOption(new stringSetting("gsOptions", 0, "string", "", ""));
+ addOption(new stringSetting("psviewerOptions", 0, "string", "", ""));
+ addOption(new stringSetting("pdfviewerOptions", 0, "string", "", ""));
+ addOption(new stringSetting("pdfreloadOptions", 0, "string", "", ""));
+ addOption(new stringSetting("glOptions", 0, "string", "", ""));
+
+ addOption(new envSetting("config","config."+suffix));
+ addOption(new envSetting("pdfviewer", defaultPDFViewer));
+ addOption(new envSetting("psviewer", defaultPSViewer));
+ addOption(new envSetting("gs", defaultGhostscript));
+ addOption(new envSetting("texpath", ""));
+ addOption(new envSetting("texcommand", ""));
+ addOption(new envSetting("texdvicommand", ""));
+ addOption(new envSetting("dvips", "dvips"));
+ addOption(new envSetting("convert", "convert"));
+ addOption(new envSetting("display", defaultDisplay));
+ addOption(new envSetting("animate", "animate"));
+ addOption(new envSetting("python", defaultPython));
+ addOption(new envSetting("xasy", defaultXasy));
+ addOption(new envSetting("papertype", "letter"));
+ addOption(new envSetting("dir", ""));
+ addOption(new envSetting("sysdir", systemDir));
+}
+
+// Access the arguments once options have been parsed.
+int numArgs() { return argCount; }
+char *getArg(int n) { return argList[n]; }
+
+void setInteractive() {
+ if(numArgs() == 0 && !getSetting<bool>("listvariables") &&
+ getSetting<string>("command").empty() &&
+ (isatty(STDIN_FILENO) || getSetting<bool>("interactive")))
+ interact::interactive=true;
+
+ historyname=getSetting<bool>("localhistory") ? "."+suffix+"_history"
+ : (initdir+"/history");
+}
+
+bool view() {
+ if (interact::interactive)
+ return getSetting<bool>("interactiveView");
+ else
+ return getSetting<bool>("batchView") &&
+ (numArgs() == 1 || getSetting<bool>("multipleView"));
+}
+
+bool trap() {
+ if (interact::interactive)
+ return !getSetting<bool>("interactiveMask");
+ else
+ return !getSetting<bool>("batchMask");
+}
+
+string outname() {
+ string name=getSetting<string>("outname");
+ return name.empty() ? "out" : name;
+}
+
+void initDir() {
+ initdir=Getenv(HOME,msdos)+"/."+suffix;
+ mkdir(initdir.c_str(),0777);
+}
+
+void setPath() {
+ searchPath.clear();
+ searchPath.push_back(".");
+ string asydir=getSetting<string>("dir");
+ if(asydir != "") {
+ size_t p,i=0;
+ while((p=asydir.find(pathSeparator,i)) < string::npos) {
+ if(p > i) searchPath.push_back(asydir.substr(i,p-i));
+ i=p+1;
+ }
+ if(i < asydir.length()) searchPath.push_back(asydir.substr(i));
+ }
+ searchPath.push_back(initdir);
+ string sysdir=getSetting<string>("sysdir");
+ if(sysdir == "") {
+ iopipestream pipe("kpsewhich --var-value=SELFAUTOPARENT");
+ pipe >> sysdir;
+ size_t size=sysdir.size();
+ if(size > 2) {
+ sysdir.erase(size-1,1);
+ sysdir.append(dirsep+"texmf/asymptote");
+ Setting("sysdir")=sysdir;
+ }
+ }
+ if(sysdir != "")
+ searchPath.push_back(sysdir);
+}
+
+void SetPageDimensions() {
+ string paperType=getSetting<string>("papertype");
+
+ if(paperType == "" &&
+ getSetting<double>("paperwidth") != 0.0 &&
+ getSetting<double>("paperheight") != 0.0) return;
+
+ if(paperType == "letter") {
+ Setting("paperwidth")=8.5*inches;
+ Setting("paperheight")=11.0*inches;
+ } else {
+ Setting("paperwidth")=21.0*cm;
+ Setting("paperheight")=29.7*cm;
+
+ if(paperType != "a4") {
+ cerr << "Unknown paper size \'" << paperType << "\'; assuming a4."
+ << endl;
+ Setting("papertype")=string("a4");
+ }
+ }
+}
+
+bool xelatex(const string& texengine) {
+ return texengine == "xelatex";
+}
+
+bool pdf(const string& texengine) {
+ return texengine == "pdflatex" || texengine == "pdftex" || xelatex(texengine);
+}
+
+bool latex(const string& texengine) {
+ return texengine == "latex" || texengine == "pdflatex" || xelatex(texengine);
+}
+
+string nativeformat() {
+ return pdf(getSetting<string>("tex")) ? "pdf" : "eps";
+}
+
+string defaultformat() {
+ string format=getSetting<string>("outformat");
+ return (format == "") ? nativeformat() : format;
+}
+
+// TeX special command to set up currentmatrix for typesetting labels.
+const char *beginlabel(const string& texengine) {
+ if(pdf(texengine))
+ return xelatex(texengine) ? "\\special{pdf:literal q #5 0 0 cm}" :
+ "\\special{pdf:q #5 0 0 cm}";
+ else
+ return "\\special{ps:gsave currentpoint currentpoint translate [#5 0 0] "
+ "concat neg exch neg exch translate}";
+}
+
+// TeX special command to restore currentmatrix after typesetting labels.
+const char *endlabel(const string& texengine) {
+ if(pdf(texengine))
+ return xelatex(texengine) ? "\\special{pdf:literal Q}" : "\\special{pdf:Q}";
+ else
+ return "\\special{ps:currentpoint grestore moveto}";
+}
+
+// TeX macro to typeset raw postscript code
+const char *rawpostscript(const string& texengine) {
+ if(pdf(texengine))
+ return "\\def\\ASYraw#1{#1}";
+ else
+ return "\\def\\ASYraw#1{\n"
+ "currentpoint currentpoint translate matrix currentmatrix\n"
+ "100 12 div -100 12 div scale\n"
+ "#1\n"
+ "setmatrix neg exch neg exch translate}";
+}
+
+// TeX macro to begin picture
+const char *beginpicture(const string& texengine) {
+ if(latex(texengine))
+ return "\\begin{picture}";
+ else
+ return "\\picture";
+}
+
+// TeX macro to end picture
+const char *endpicture(const string& texengine) {
+ if(latex(texengine))
+ return "\\end{picture}%";
+ else
+ return "\\endpicture%";
+}
+
+// Begin TeX special command.
+const char *beginspecial(const string& texengine) {
+ if(pdf(texengine))
+ return xelatex(texengine) ? "\\special{pdf:literal " : "\\special{pdf:";
+ return "\\special{ps:";
+}
+
+// End TeX special command.
+const char *endspecial() {
+ return "}%";
+}
+
+// Default TeX units.
+const char *texunits(const string& texengine)
+{
+ return xelatex(texengine) ? "bp" : "pt";
+}
+
+
+bool fataltex[]={false,true};
+const char *pdftexerrors[]={"! "," ==> Fatal error",NULL};
+const char *texerrors[]={"! ",NULL};
+
+// Messages that signify a TeX error.
+const char **texabort(const string& texengine)
+{
+ return settings::pdf(texengine) ? pdftexerrors : texerrors;
+}
+
+string texcommand(bool ps)
+{
+ string command;
+ if(ps) {
+ command=getSetting<string>("texdvicommand");
+ if(command == "")
+ command=latex(getSetting<string>("tex")) ? "latex" : "tex";
+ } else
+ command=getSetting<string>("texcommand");
+ return command.empty() ? getSetting<string>("tex") : command;
+}
+
+string texprogram(bool ps)
+{
+ string path=getSetting<string>("texpath");
+ string engine=texcommand(ps);
+ if(!path.empty()) engine=(string) (path+"/"+engine);
+ string program="'"+engine+"'";
+ string dir=stripFile(outname());
+ return dir.empty() ? program : (program+" -output-directory="+dir);
+}
+
+Int getScroll()
+{
+ Int scroll=settings::getSetting<Int>("scroll");
+#ifdef HAVE_LIBCURSES
+ if(scroll < 0) {
+ char *terminal=getenv("TERM");
+ if(terminal) {
+ setupterm(terminal,1,NULL);
+ scroll=lines > 2 ? lines-1 : 1;
+ }
+ }
+#endif
+ return scroll;
+}
+
+void setOptions(int argc, char *argv[])
+{
+ argv0=argv[0];
+
+ cout.precision(DBL_DIG);
+
+ // Make configuration and history directory
+ initDir();
+
+ // Build settings module.
+ initSettings();
+
+ // Read command-line options initially to obtain CONFIG and DIR.
+ getOptions(argc,argv);
+
+ Int Verbose=verbose;
+ resetOptions();
+
+ // Read user configuration file.
+ setPath();
+ string filename=getSetting<string>("config");
+ if(!filename.empty()) {
+ string file=locateFile(filename);
+ if(!file.empty()) {
+ if(Verbose > 1)
+ cerr << "Loading " << filename << " from " << file << endl;
+ doConfig(file);
+ }
+ }
+
+ // Read command-line options again to override configuration file defaults.
+ getOptions(argc,argv);
+
+#ifdef USEGC
+ if(verbose == 0 && !getSetting<bool>("debug")) GC_set_warn_proc(no_GCwarn);
+#endif
+
+ if(setlocale (LC_ALL, "") == NULL && getSetting<bool>("debug"))
+ perror("setlocale");
+
+ // Set variables for the file arguments.
+ argCount = argc - optind;
+ argList = argv + optind;
+
+ // Recompute search path.
+ setPath();
+
+ if(getSetting<double>("paperwidth") != 0.0 &&
+ getSetting<double>("paperheight") != 0.0)
+ Setting("papertype")=string("");
+
+ SetPageDimensions();
+
+ setInteractive();
+}
+
+}
diff --git a/Build/source/utils/asymptote/settings.h b/Build/source/utils/asymptote/settings.h
new file mode 100644
index 00000000000..5a06acb7d8f
--- /dev/null
+++ b/Build/source/utils/asymptote/settings.h
@@ -0,0 +1,121 @@
+/*****
+ * settings.h
+ * Andy Hammerlindl 2004/05/10
+ *
+ * Declares a list of global variables that act as settings in the system.
+ *****/
+
+#ifndef SETTINGS_H
+#define SETTINGS_H
+
+#include <fstream>
+
+#include "common.h"
+#include "pair.h"
+#include "item.h"
+
+namespace types {
+class record;
+}
+
+namespace camp {
+void glrenderWrapper();
+}
+
+namespace gl {
+extern bool glthread;
+extern bool initialize;
+
+#ifdef HAVE_LIBPTHREAD
+extern pthread_cond_t initSignal;
+extern pthread_mutex_t initLock;
+extern pthread_cond_t readySignal;
+extern pthread_mutex_t readyLock;
+extern pthread_cond_t quitSignal;
+extern pthread_mutex_t quitLock;
+extern pthread_t mainthread;
+void wait(pthread_cond_t& signal, pthread_mutex_t& lock);
+void endwait(pthread_cond_t& signal, pthread_mutex_t& lock);
+#endif
+}
+
+namespace settings {
+extern const char PROGRAM[];
+extern const char VERSION[];
+extern const char BUGREPORT[];
+
+extern char *argv0;
+
+extern string systemDir;
+extern const string docdir;
+extern const string dirsep;
+
+extern bool safe;
+
+bool globalwrite();
+
+enum origin {CENTER,BOTTOM,TOP,ZERO};
+
+extern const string suffix;
+extern const string guisuffix;
+
+extern string historyname;
+
+void SetPageDimensions();
+
+types::record *getSettingsModule();
+
+vm::item& Setting(string name);
+
+template <typename T>
+inline T getSetting(string name)
+{
+ return vm::get<T>(Setting(name));
+}
+
+extern Int verbose;
+extern bool gray;
+extern bool bw;
+extern bool rgb;
+extern bool cmyk;
+
+bool view();
+bool trap();
+string outname();
+
+void setOptions(int argc, char *argv[]);
+
+// Access the arguments once options have been parsed.
+int numArgs();
+char *getArg(int n);
+
+Int getScroll();
+
+bool pdf(const string& texengine);
+bool latex(const string& texengine);
+
+string nativeformat();
+string defaultformat();
+
+const char *beginlabel(const string& texengine);
+const char *endlabel(const string& texengine);
+const char *rawpostscript(const string& texengine);
+const char *beginpicture(const string& texengine);
+const char *endpicture(const string& texengine);
+const char *beginspecial(const string& texengine);
+const char *endspecial();
+const char *texunits(const string& texengine);
+
+extern bool fataltex[];
+const char **texabort(const string& texengine);
+
+string texcommand(bool ps=false);
+string texprogram(bool ps=false);
+
+const double inches=72;
+const double cm=inches/2.54;
+}
+
+extern const char *SVN_REVISION;
+
+#endif
diff --git a/Build/source/utils/asymptote/simpson.cc b/Build/source/utils/asymptote/simpson.cc
new file mode 100644
index 00000000000..c17f3545c03
--- /dev/null
+++ b/Build/source/utils/asymptote/simpson.cc
@@ -0,0 +1,221 @@
+#include <cmath>
+#include <cassert>
+#include <cfloat>
+
+// Compute a numerical approximation to an integral via adaptive Simpson's Rule
+// This routine ignores underflow.
+
+const int nest=DBL_MANT_DIG;
+
+typedef struct {
+ bool left; // left interval?
+ double psum, f1t, f2t, f3t, dat, estr;
+} TABLE;
+
+bool // Returns true iff successful.
+simpson(double& integral, // Approximate value of the integral.
+ double (*f)(double), // Pointer to function to be integrated.
+ double a, double b, // Lower, upper limits of integration (a <= b).
+ double acc, // Desired relative accuracy of integral.
+ // Try to make |error| <= acc*abs(integral).
+ double dxmax) // Maximum limit on the width of a subinterval
+// For periodic functions, dxmax should be
+// set to the period or smaller to prevent
+// premature convergence of Simpson's rule.
+{
+ double diff,area,estl,estr,alpha,da,dx,wt,est,fv[5];
+ TABLE table[nest],*p,*pstop;
+ static const double sixth=1.0/6.0;
+
+ bool success=true;
+ p=table;
+ pstop=table+nest-1;
+ p->left=true;
+ p->psum=0.0;
+ alpha=a;
+ da=b-a;
+ fv[0]=(*f)(alpha);
+ fv[2]=(*f)(alpha+0.5*da);
+ fv[4]=(*f)(alpha+da);
+ wt=sixth*da;
+ est=wt*(fv[0]+4.0*fv[2]+fv[4]);
+ area=est;
+
+ // Have estimate est of integral on (alpha, alpha+da).
+ // Bisect and compute estimates on left and right half intervals.
+ // integral is the best value for the integral.
+
+ for(;;) {
+ dx=0.5*da;
+ double arg=alpha+0.5*dx;
+ fv[1]=(*f)(arg);
+ fv[3]=(*f)(arg+dx);
+ wt=sixth*dx;
+ estl=wt*(fv[0]+4.0*fv[1]+fv[2]);
+ estr=wt*(fv[2]+4.0*fv[3]+fv[4]);
+ integral=estl+estr;
+ diff=est-integral;
+ area -= diff;
+
+ if(p >= pstop) success=false;
+ if(!success || (fabs(diff) <= acc*fabs(area) && da <= dxmax)) {
+ // Accept approximate integral.
+ // If it was a right interval, add results to finish at this level.
+ // If it was a left interval, process right interval.
+
+ for(;;) {
+ if(p->left == false) { // process right-half interval
+ alpha += da;
+ p->left=true;
+ p->psum=integral;
+ fv[0]=p->f1t;
+ fv[2]=p->f2t;
+ fv[4]=p->f3t;
+ da=p->dat;
+ est=p->estr;
+ break;
+ }
+ integral += p->psum;
+ if(--p <= table) return success;
+ }
+
+ } else {
+ // Raise level and store information for processing right-half interval.
+ ++p;
+ da=dx;
+ est=estl;
+ p->left=false;
+ p->f1t=fv[2];
+ p->f2t=fv[3];
+ p->f3t=fv[4];
+ p->dat=dx;
+ p->estr=estr;
+ fv[4]=fv[2];
+ fv[2]=fv[1];
+ }
+ }
+}
+
+// Use adaptive Simpson integration to determine the upper limit of
+// integration required to make the definite integral of a continuous
+// non-negative function close to a user specified sum.
+// This routine ignores underflow.
+
+bool // Returns true iff successful.
+unsimpson(double integral, // Given value for the integral.
+ double (*f)(double), // Pointer to function to be integrated.
+ double a, double& b, // Lower, upper limits of integration (a <= b).
+ // The value of b provided on entry is used
+ // as an initial guess; somewhat faster if the
+ // given value is an underestimation.
+ double acc, // Desired relative accuracy of b.
+ // Try to make |integral-area| <= acc*integral.
+ double& area, // Computed integral of f(x) on [a,b].
+ double dxmax, // Maximum limit on the width of a subinterval
+ // For periodic functions, dxmax should be
+ // set to the period or smaller to prevent
+ // premature convergence of Simpson's rule.
+ double dxmin=0) // Lower limit on sampling width.
+{
+ double diff,estl,estr,alpha,da,dx,wt,est,fv[5];
+ double sum,parea,pdiff,b2;
+ TABLE table[nest],*p,*pstop;
+ static const double sixth=1.0/6.0;
+
+ p=table;
+ pstop=table+nest-1;
+ p->psum=0.0;
+ alpha=a;
+ parea=0.0;
+ pdiff=0.0;
+
+ for(;;) {
+ p->left=true;
+ da=b-alpha;
+ fv[0]=(*f)(alpha);
+ fv[2]=(*f)(alpha+0.5*da);
+ fv[4]=(*f)(alpha+da);
+ wt=sixth*da;
+ est=wt*(fv[0]+4.0*fv[2]+fv[4]);
+ area=est;
+
+ // Have estimate est of integral on (alpha, alpha+da).
+ // Bisect and compute estimates on left and right half intervals.
+ // Sum is better value for integral.
+
+ bool cont=true;
+ while(cont) {
+ dx=0.5*da;
+ double arg=alpha+0.5*dx;
+ fv[1]=(*f)(arg);
+ fv[3]=(*f)(arg+dx);
+ wt=sixth*dx;
+ estl=wt*(fv[0]+4.0*fv[1]+fv[2]);
+ estr=wt*(fv[2]+4.0*fv[3]+fv[4]);
+ sum=estl+estr;
+ diff=est-sum;
+
+ assert(sum >= 0.0);
+ area=parea+sum;
+ b2=alpha+da;
+ if(fabs(fabs(integral-area)-fabs(pdiff))+fabs(diff) <= fv[4]*acc*(b2-a)){
+ b=b2;
+ return true;
+ }
+ if(fabs(integral-area) > fabs(pdiff+diff)) {
+ if(integral <= area) {
+ p=table;
+ p->left=true;
+ p->psum=parea;
+ } else {
+ if((fabs(diff) <= fv[4]*acc*da || dx <= dxmin) && da <= dxmax) {
+ // Accept approximate integral sum.
+ // If it was a right interval, add results to finish at this level.
+ // If it was a left interval, process right interval.
+
+ pdiff += diff;
+ for(;;) {
+ if(p->left == false) { // process right-half interval
+ parea += sum;
+ alpha += da;
+ p->left=true;
+ p->psum=sum;
+ fv[0]=p->f1t;
+ fv[2]=p->f2t;
+ fv[4]=p->f3t;
+ da=p->dat;
+ est=p->estr;
+ break;
+ }
+ sum += p->psum;
+ parea -= p->psum;
+ if(--p <= table) {
+ p=table;
+ p->psum=parea=sum;
+ alpha += da;
+ b += b-a;
+ cont=false;
+ break;
+ }
+ }
+ continue;
+ }
+ }
+ }
+ if(p >= pstop) return false;
+// Raise level and store information for processing right-half interval.
+ ++p;
+ da=dx;
+ est=estl;
+ p->psum=0.0;
+ p->left=false;
+ p->f1t=fv[2];
+ p->f2t=fv[3];
+ p->f3t=fv[4];
+ p->dat=dx;
+ p->estr=estr;
+ fv[4]=fv[2];
+ fv[2]=fv[1];
+ }
+ }
+}
diff --git a/Build/source/utils/asymptote/stack.cc b/Build/source/utils/asymptote/stack.cc
new file mode 100644
index 00000000000..ffec3d9b056
--- /dev/null
+++ b/Build/source/utils/asymptote/stack.cc
@@ -0,0 +1,370 @@
+/*****
+ * stack.cc
+ * Andy Hammerlindl 2002/06/27
+ *
+ * The general stack machine used to run compiled camp code.
+ *****/
+
+#include <sstream>
+
+#include "stack.h"
+#include "program.h"
+#include "callable.h"
+#include "errormsg.h"
+#include "util.h"
+#include "runtime.h"
+
+//#define DEBUG_STACK
+
+#ifdef DEBUG_STACK
+#include <iostream>
+
+namespace vm {
+void draw(ostream& out, frame *v);
+}
+#endif
+
+namespace run {
+void breakpoint(vm::stack *Stack, absyntax::runnable *r);
+}
+
+namespace vm {
+
+mem::list<bpinfo> bplist;
+
+namespace {
+position curPos = nullPos;
+const program::label nulllabel;
+}
+
+inline stack::vars_t stack::make_frame(size_t size, vars_t closure)
+{
+ vars_t vars = new frame(1+size);
+ (*vars)[0] = closure;
+ return vars;
+}
+
+void run(lambda *l)
+{
+ func f;
+ f.body = l;
+ stack s;
+ s.run(&f);
+}
+
+void stack::marshall(size_t args, vars_t vars)
+{
+ for (size_t i = args; i > 0; --i)
+ (*vars)[i] = pop();
+}
+
+void stack::run(func *f)
+{
+ lambda *body = f->body;
+
+#ifdef DEBUG_STACK
+ cout << "running lambda: \n";
+ print(cout, body->code);
+ cout << endl;
+#endif
+
+ /* make new activation record */
+ vars_t vars = make_frame(body->params, f->closure);
+ marshall(body->params, vars);
+
+ run(body->code, vars);
+}
+
+void stack::breakpoint(absyntax::runnable *r)
+{
+ lastPos=curPos;
+ indebugger=true;
+ ::run::breakpoint(this,r);
+ string s=vm::pop<string>(this);
+ debugOp=(s.length() > 0) ? s[0] : (char) 0;
+ indebugger=false;
+}
+
+void stack::debug()
+{
+ if(!curPos) return;
+ if(indebugger) {em.clear(); return;}
+
+ switch(debugOp) {
+ case 'i': // inst
+ breakpoint();
+ break;
+ case 's': // step
+ if((!curPos.match(lastPos.filename()) || !curPos.match(lastPos.Line())))
+ breakpoint();
+ break;
+ case 'n': // next
+ if(curPos.match(lastPos.filename()) && !curPos.match(lastPos.Line()))
+ breakpoint();
+ break;
+ case 'f': // file
+ if(!curPos.match(lastPos.filename()))
+ breakpoint();
+ break;
+ case 'r': // return
+ if(curPos.match(breakPos.filename()))
+ breakpoint();
+ break;
+ case 'c': // continue
+ default:
+ for(mem::list<bpinfo>::iterator p=bplist.begin(); p != bplist.end(); ++p) {
+ if(curPos.match(p->f.name()) && curPos.match(p->f.line()) &&
+ (newline || !curPos.match(breakPos.filename()) ||
+ !curPos.match(breakPos.Line()))) {
+ breakPos=curPos;
+ breakpoint(p->r);
+ newline=false;
+ break;
+ }
+ if(!newline &&
+ (curPos.match(lastPos.filename()) && !curPos.match(lastPos.Line())))
+ newline=true;
+ }
+ break;
+ }
+}
+
+void stack::run(program *code, vars_t vars)
+{
+ /* start the new function */
+ program::label ip = code->begin();
+
+ try {
+ for (;;) {
+ const inst &i = *ip;
+ curPos = i.pos;
+
+#ifdef DEBUG_STACK
+ cerr << curPos << "\n";
+ printInst(cerr, ip, body->code->begin());
+ cerr << "\n";
+#endif
+
+ if(settings::verbose > 4) em.trace(curPos);
+
+ if(!bplist.empty()) debug();
+
+ if(errorstream::interrupt) throw interrupted();
+
+ switch (i.op)
+ {
+ case inst::pop:
+ pop();
+ break;
+
+ case inst::intpush:
+ case inst::constpush:
+ push(i.ref);
+ break;
+
+ case inst::varpush:
+ push((*vars)[get<Int>(i)]);
+ break;
+
+ case inst::varsave:
+ (*vars)[get<Int>(i)] = top();
+ break;
+
+ case inst::fieldpush: {
+ vars_t frame = pop<vars_t>();
+ if (!frame)
+ error("dereference of null pointer");
+ push((*frame)[get<Int>(i)]);
+ break;
+ }
+
+ case inst::fieldsave: {
+ vars_t frame = pop<vars_t>();
+ if (!frame)
+ error("dereference of null pointer");
+ (*frame)[get<Int>(i)] = top();
+ break;
+ }
+
+ case inst::builtin: {
+ bltin func = get<bltin>(i);
+ func(this);
+ break;
+ }
+
+ case inst::jmp:
+ ip = get<program::label>(i);
+ continue;
+
+ case inst::cjmp:
+ if (pop<bool>()) { ip = get<program::label>(i); continue; }
+ break;
+
+ case inst::njmp:
+ if (!pop<bool>()) { ip = get<program::label>(i); continue; }
+ break;
+
+ case inst::popcall: {
+ /* get the function reference off of the stack */
+ callable* f = pop<callable*>();
+ f->call(this);
+ break;
+ }
+
+ case inst::pushclosure:
+ push(vars);
+ break;
+
+ case inst::makefunc: {
+ func *f = new func;
+ f->closure = pop<vars_t>();
+ f->body = get<lambda*>(i);
+
+ push((callable*)f);
+ break;
+ }
+
+ case inst::ret: {
+ return;
+ }
+
+ case inst::alloc: {
+ vars->extend(get<Int>(i));
+ break;
+ }
+
+ case inst::pushframe: {
+ vars=make_frame(0, vars);
+ break;
+ }
+
+ case inst::popframe: {
+ vars=get<frame *>((*vars)[0]);
+ break;
+ }
+
+ default:
+ error("Internal VM error: Bad stack operand");
+ }
+
+#ifdef DEBUG_STACK
+ draw(cerr);
+ vm::draw(cerr,vars);
+ cerr << "\n";
+#endif
+
+ ++ip;
+ }
+ } catch (bad_item_value&) {
+ error("Trying to use uninitialized value.");
+ }
+}
+
+void stack::load(string index) {
+ frame *inst=instMap[index];
+ if (inst)
+ push(inst);
+ else {
+ func f;
+ assert(initMap);
+ f.body=(*initMap)[index];
+ assert(f.body);
+ run(&f);
+ instMap[index]=get<frame *>(top());
+ }
+}
+
+
+#ifdef DEBUG_STACK
+#if __GNUC__
+#include <cxxabi.h>
+string demangle(const char *s)
+{
+ int status;
+ char *demangled = abi::__cxa_demangle(s,NULL,NULL,&status);
+ if (status == 0 && demangled) {
+ string str(demangled);
+ free(demangled);
+ return str;
+ } else if (status == -2) {
+ free(demangled);
+ return s;
+ } else {
+ free(demangled);
+ return string("Unknown(") + s + ")";
+ }
+};
+#else
+string demangle(const char* s)
+{
+ return s;
+}
+#endif
+
+void stack::draw(ostream& out)
+{
+// out.setf(out.hex);
+
+ out << "operands:";
+ stack_t::const_iterator left = theStack.begin();
+ if (theStack.size() > 10) {
+ left = theStack.end()-10;
+ out << " ...";
+ }
+
+ while (left != theStack.end())
+ {
+ out << " " << demangle(left->type().name());
+ left++;
+ }
+ out << "\n";
+}
+
+void draw(ostream& out, frame* v)
+{
+ out << "vars: ";
+
+ if (!!v) {
+ out << (!get<frame*>((*v)[0]) ? " 0" : " link");
+ for (size_t i = 1; i < 10 && i < v->size(); i++)
+ out << " " << demangle((*v)[i].type().name());
+ if (v->size() > 10)
+ out << "...";
+ out << "\n";
+ }
+ else
+ out << "\n";
+}
+#endif // DEBUG_STACK
+
+position getPos() {
+ return curPos;
+}
+
+void errornothrow(const char* message)
+{
+ em.error(curPos);
+ em << message;
+ em.sync();
+}
+
+void error(const char* message)
+{
+ errornothrow(message);
+ throw handled_error();
+}
+
+void error(const ostringstream& message)
+{
+ error(message.str().c_str());
+}
+
+interactiveStack::interactiveStack()
+ : globals(new frame(1)) {}
+
+void interactiveStack::run(lambda *codelet) {
+ stack::run(codelet->code, globals);
+}
+
+} // namespace vm
+
diff --git a/Build/source/utils/asymptote/stack.h b/Build/source/utils/asymptote/stack.h
new file mode 100644
index 00000000000..3f1cd983076
--- /dev/null
+++ b/Build/source/utils/asymptote/stack.h
@@ -0,0 +1,167 @@
+/*****
+ * stack.h
+ * Andy Hammerlindl 2002/06/27
+ *
+ * The general stack machine used to run compiled camp code.
+ *****/
+
+#ifndef STACK_H
+#define STACK_H
+
+#include <iostream>
+
+#include "errormsg.h"
+#include "vm.h"
+#include "item.h"
+#include "absyn.h"
+
+namespace vm {
+
+struct func;
+class program;
+class lambda;
+class importInitMap;
+
+struct bpinfo : public gc {
+ fileinfo f;
+ absyntax::runnable *r;
+
+ bpinfo(const string& filename, size_t lineNum,
+ absyntax::runnable *r=NULL) :
+ f(fileinfo(filename,lineNum)), r(r) {}
+};
+
+inline bool operator == (const bpinfo& a, const bpinfo& b)
+{
+ return a.f == b.f;
+}
+
+extern mem::list<bpinfo> bplist;
+
+class runnable;
+
+extern bool indebugger;
+
+class stack {
+public:
+ typedef frame* vars_t;
+
+ struct importInitMap {
+ virtual ~importInitMap() {}
+ virtual lambda *operator[](string) = 0;
+ };
+
+private:
+ // stack for operands
+ typedef mem::vector<item> stack_t;
+ stack_t theStack;
+
+ vars_t make_frame(size_t, vars_t closure);
+
+ void draw(ostream& out);
+
+ // Move arguments from stack to frame.
+ void marshall(size_t args, vars_t vars);
+
+ // The initializer functions for imports, indexed by name.
+ importInitMap *initMap;
+
+ // The stack stores a map of initialized imported modules by name, so that
+ // each module is initialized only once and each import refers to the same
+ // instance.
+ typedef mem::map<CONST string,frame *> importInstanceMap;
+ importInstanceMap instMap;
+
+ // One can associate an environment to embedded code while running.
+ trans::coenv *e;
+
+ // Debugger variables:
+ char debugOp;
+ position lastPos, breakPos;
+ bool newline;
+
+public:
+ stack() : e(0), debugOp(0), lastPos(nullPos),
+ breakPos(nullPos), newline(false) {};
+
+ virtual ~stack() {};
+
+ void setInitMap(importInitMap *i) {
+ initMap=i;
+ }
+
+ void setEnvironment(trans::coenv *e) {
+ this->e=e;
+ }
+
+ trans::coenv *getEnvironment() {
+ return e;
+ }
+
+ // Runs the instruction listed in code, with vars as frame of variables.
+ void run(program *code, vars_t vars);
+
+ // Executes a function on top of the stack.
+ void run(func *f);
+
+ void breakpoint(absyntax::runnable *r=NULL);
+ void debug();
+
+ // Put an import (indexed by name) on top of the stack, initializing it if
+ // necessary.
+ void load(string index);
+
+ // These are so that built-in functions can easily manipulate the stack
+ void push(item next) {
+ theStack.push_back(next);
+ }
+ template <typename T>
+ void push(T next) {
+ push((item)next);
+ }
+ item top() {
+ return theStack.back();
+ }
+ item pop() {
+ item ret = theStack.back();
+ theStack.pop_back();
+ return ret;
+ }
+ template <typename T>
+ T pop()
+ {
+ return get<T>(pop());
+ }
+};
+
+inline item pop(stack* s)
+{
+ return s->pop();
+}
+
+template <typename T>
+inline T pop(stack* s)
+{
+ return get<T>(pop(s));
+}
+
+template <typename T>
+inline T pop(stack* s, T defval)
+{
+ item it=pop(s);
+ return isdefault(it) ? defval : get<T>(it);
+}
+
+class interactiveStack : public stack {
+ vars_t globals;
+public:
+ interactiveStack();
+
+ // Run a codelet, a small piece of code that uses globals as its frame.
+ void run(lambda *codelet);
+};
+
+} // namespace vm
+
+#endif // STACK_H
+
diff --git a/Build/source/utils/asymptote/stm.cc b/Build/source/utils/asymptote/stm.cc
new file mode 100644
index 00000000000..5b09387d431
--- /dev/null
+++ b/Build/source/utils/asymptote/stm.cc
@@ -0,0 +1,383 @@
+/*****
+ * stm.cc
+ * Andy Hammerlindl 2002/8/30
+ *
+ * Statements are everything in the language that do something on their
+ * own. Statements are different from declarations in that statements
+ * do not modify the environment. Translation of a statement puts the
+ * stack code to run it into the instruction stream.
+ *****/
+
+#include <fstream>
+#include "errormsg.h"
+#include "settings.h"
+#include "coenv.h"
+#include "exp.h"
+#include "stm.h"
+
+namespace absyntax {
+
+using namespace trans;
+using namespace types;
+
+void stm::prettyprint(ostream &out, Int indent)
+{
+ prettyname(out,"stm",indent);
+}
+
+
+void emptyStm::prettyprint(ostream &out, Int indent)
+{
+ prettyname(out,"emptyStm",indent);
+}
+
+
+void blockStm::prettyprint(ostream &out, Int indent)
+{
+ prettyname(out,"blockStm",indent);
+
+ base->prettyprint(out, indent+1);
+}
+
+
+void expStm::prettyprint(ostream &out, Int indent)
+{
+ prettyname(out,"expStm",indent);
+
+ body->prettyprint(out, indent+1);
+}
+
+void expStm::baseTrans(coenv &e, exp *expr)
+{
+ types::ty_kind kind = expr->trans(e)->kind;
+ if (kind != types::ty_void)
+ // Remove any value it puts on the stack.
+ e.c.encode(inst::pop);
+}
+
+void expStm::trans(coenv &e) {
+ baseTrans(e, body);
+}
+
+exp *tryToWriteExp(coenv &e, exp *body)
+{
+ // First check if it is the kind of expression that should be written.
+ if (body->writtenToPrompt() &&
+ settings::getSetting<bool>("interactiveWrite"))
+ {
+ types::ty *t=body->cgetType(e);
+ if (t->kind == ty_error) {
+ return body;
+ }
+ else {
+ exp *callee=new nameExp(body->getPos(), symbol::trans("write"));
+ exp *call=new callExp(body->getPos(), callee, body);
+
+ types::ty *ct=call->getType(e);
+ if (ct->kind == ty_error || ct->kind == ty_overloaded) {
+ return body;
+ }
+ else {
+ // Issue a warning if the act of writing turns an ambiguous expression
+ // into an unambiguous one.
+ if (t->kind == ty_overloaded) {
+ em.warning(body->getPos());
+ em << "writing overloaded";
+ if (body->getName())
+ em << " variable '" << *body->getName() << "'";
+ else
+ em << " expression";
+ }
+ return call;
+ }
+ }
+ }
+ else {
+ return body;
+ }
+}
+
+void expStm::interactiveTrans(coenv &e)
+{
+ baseTrans(e, tryToWriteExp(e, body));
+}
+
+
+void ifStm::prettyprint(ostream &out, Int indent)
+{
+ prettyname(out,"ifStm",indent);
+
+ test->prettyprint(out, indent+1);
+ onTrue->prettyprint(out, indent+1);
+ if (onFalse)
+ onFalse->prettyprint(out, indent+1);
+}
+
+void ifStm::trans(coenv &e)
+{
+ test->transToType(e, types::primBoolean());
+
+ Int elseLabel = e.c.fwdLabel();
+ Int end = e.c.fwdLabel();
+
+ e.c.useLabel(inst::njmp,elseLabel);
+
+ onTrue->markTrans(e);
+ e.c.useLabel(inst::jmp,end);
+
+ e.c.defLabel(elseLabel);
+ // Produces efficient code whether or not there is an else clause.
+ if (onFalse)
+ onFalse->markTrans(e);
+
+ e.c.defLabel(end);
+}
+
+
+void transLoopBody(coenv &e, stm *body) {
+ e.c.encodePushFrame();
+ body->markTrans(e);
+ e.c.encodePopFrame();
+}
+
+void whileStm::prettyprint(ostream &out, Int indent)
+{
+ prettyname(out,"whileStm",indent);
+
+ test->prettyprint(out, indent+1);
+ body->prettyprint(out, indent+1);
+}
+
+void whileStm::trans(coenv &e)
+{
+ Int start = e.c.defLabel();
+ e.c.pushContinue(start);
+ test->transToType(e, types::primBoolean());
+
+ Int end = e.c.fwdLabel();
+ e.c.pushBreak(end);
+ e.c.useLabel(inst::njmp,end);
+
+ transLoopBody(e,body);
+
+ e.c.useLabel(inst::jmp,start);
+ e.c.defLabel(end);
+
+ e.c.popBreak();
+ e.c.popContinue();
+}
+
+
+void doStm::prettyprint(ostream &out, Int indent)
+{
+ prettyname(out,"doStm",indent);
+
+ body->prettyprint(out, indent+1);
+ test->prettyprint(out, indent+1);
+}
+
+void doStm::trans(coenv &e)
+{
+ Int testLabel = e.c.fwdLabel();
+ e.c.pushContinue(testLabel);
+ Int end = e.c.fwdLabel();
+ e.c.pushBreak(end);
+
+ Int start = e.c.defLabel();
+
+ transLoopBody(e,body);
+
+ e.c.defLabel(testLabel);
+ test->transToType(e, types::primBoolean());
+ e.c.useLabel(inst::cjmp,start);
+ e.c.defLabel(end);
+
+ e.c.popBreak();
+ e.c.popContinue();
+}
+
+
+void forStm::prettyprint(ostream &out, Int indent)
+{
+ prettyname(out,"forStm",indent);
+
+ if (init) init->prettyprint(out, indent+1);
+ if (test) test->prettyprint(out, indent+1);
+ if (update) update->prettyprint(out, indent+1);
+ body->prettyprint(out, indent+1);
+}
+
+void forStm::trans(coenv &e)
+{
+ // Any vardec in the initializer needs its own scope.
+ e.e.beginScope();
+ if(init) init->markTrans(e);
+
+ Int ctarget = e.c.fwdLabel();
+ e.c.pushContinue(ctarget);
+ Int end = e.c.fwdLabel();
+ e.c.pushBreak(end);
+
+ Int start = e.c.defLabel();
+ if(test) {
+ test->transToType(e, types::primBoolean());
+ e.c.useLabel(inst::njmp,end);
+ }
+
+ transLoopBody(e,body);
+
+ e.c.defLabel(ctarget);
+
+ if (update) update->markTrans(e);
+ e.c.useLabel(inst::jmp,start);
+
+ e.c.defLabel(end);
+
+ e.e.endScope();
+ e.c.popBreak();
+ e.c.popContinue();
+}
+
+void extendedForStm::prettyprint(ostream &out, Int indent)
+{
+ prettyindent(out, indent);
+ out << "extendedForStm: '" << *var << "'\n";
+
+ start->prettyprint(out, indent+1);
+ set->prettyprint(out, indent+1);
+ body->prettyprint(out, indent+1);
+}
+
+void extendedForStm::trans(coenv &e) {
+ // Translate into the syntax:
+ //
+ // start[] a = set;
+ // for (int i=0; i < a.length; ++i) {
+ // start var=a[i];
+ // body
+ // }
+
+ position pos=getPos();
+
+ // Use gensyms for the variable names so as not to pollute the namespace.
+ symbol *a=symbol::gensym("a");
+ symbol *i=symbol::gensym("i");
+
+ // start[] a=set;
+ arrayTy at(pos, start, new dimensions(pos));
+ decid dec1(pos, new decidstart(pos, a), set);
+ vardec(pos, &at, &dec1).trans(e);
+
+ // { start var=a[i]; body }
+ block b(pos);
+ decid dec2(pos, new decidstart(pos, var),
+ new subscriptExp(pos, new nameExp(pos, a),
+ new nameExp(pos, i)));
+ b.add(new vardec(pos, start, &dec2));
+ b.add(body);
+
+
+
+ // for (int i=0; i < a.length; ++i)
+ // <block>
+ forStm(pos, new vardec(pos, new tyEntryTy(pos, primInt()),
+ new decid(pos, new decidstart(pos, i),
+ new intExp(pos, 0))),
+ new binaryExp(pos, new nameExp(pos, i),
+ symbol::trans("<"),
+ new nameExp(pos, new qualifiedName(pos, new simpleName(pos, a),
+ symbol::trans("length")))),
+ new expStm(pos, new prefixExp(pos, new nameExp(pos, i),
+ symbol::trans("+"))),
+ new blockStm(pos, &b)).trans(e);
+}
+
+
+void breakStm::prettyprint(ostream &out, Int indent)
+{
+ prettyname(out,"breakStm",indent);
+}
+
+void breakStm::trans(coenv &e)
+{
+ // Loop bodies have their own frame to declare variables for each iteration.
+ // Pop out of this frame when jumping out of the loop body.
+ e.c.encode(inst::popframe);
+
+ if (!e.c.encodeBreak()) {
+ em.error(getPos());
+ em << "break statement outside of a loop";
+ }
+}
+
+
+void continueStm::prettyprint(ostream &out, Int indent)
+{
+ prettyname(out,"continueStm",indent);
+}
+
+void continueStm::trans(coenv &e)
+{
+ // Loop bodies have their own frame to declare variables for each iteration.
+ // Pop out of this frame when jumping out of the loop body.
+ e.c.encode(inst::popframe);
+
+ if (!e.c.encodeContinue()) {
+ em.error(getPos());
+ em << "continue statement outside of a loop";
+ }
+}
+
+
+void returnStm::prettyprint(ostream &out, Int indent)
+{
+ prettyname(out, "returnStm",indent);
+
+ if (value)
+ value->prettyprint(out, indent+1);
+}
+
+void returnStm::trans(coenv &e)
+{
+ types::ty *t = e.c.getReturnType();
+
+ if (t->kind == ty_void) {
+ if (value) {
+ em.error(getPos());
+ em << "function cannot return a value";
+ }
+ if (e.c.isRecord())
+ e.c.encode(inst::pushclosure);
+ }
+ else {
+ if (value) {
+ value->transToType(e, t);
+ }
+ else {
+ em.error(getPos());
+ em << "function must return a value";
+ }
+ }
+
+ // NOTE: Currently, a return statement in a module definition will end
+ // the initializer. Should this be allowed?
+ e.c.encode(inst::ret);
+}
+
+
+void stmExpList::prettyprint(ostream &out, Int indent)
+{
+ prettyname(out, "stmExpList",indent);
+
+ for (mem::list<stm *>::iterator p = stms.begin(); p != stms.end(); ++p)
+ (*p)->prettyprint(out, indent+1);
+}
+
+void stmExpList::trans(coenv &e)
+{
+ for (mem::list<stm *>::iterator p = stms.begin(); p != stms.end(); ++p)
+ (*p)->markTrans(e);
+}
+
+
+} // namespace absyntax
diff --git a/Build/source/utils/asymptote/stm.h b/Build/source/utils/asymptote/stm.h
new file mode 100644
index 00000000000..ab759dfe4a3
--- /dev/null
+++ b/Build/source/utils/asymptote/stm.h
@@ -0,0 +1,233 @@
+/*****
+ * stm.h
+ * Andy Hammerlindl 2002/8/30
+ *
+ * Statements are objects in the language that do something on their
+ * own. Statements are different from declarations in that statements
+ * do not modify the environment. Translation of a statements puts the
+ * stack code to run it into the instruction stream.
+ *****/
+
+#ifndef STM_H
+#define STM_H
+
+#include "types.h"
+#include "symbol.h"
+#include "dec.h"
+
+namespace trans {
+class coenv;
+}
+
+namespace absyntax {
+
+using trans::coenv;
+using sym::symbol;
+
+class stm : public runnable {
+public:
+ stm(position pos)
+ : runnable(pos) {}
+
+ void prettyprint(ostream &out, Int indent);
+
+ void transAsField(coenv &e, record *) {
+ // Ignore the record.
+ trans(e);
+ }
+
+ void trans(coenv &e) = 0;
+};
+
+class emptyStm : public stm {
+public:
+ emptyStm(position pos)
+ : stm(pos) {}
+
+ void prettyprint(ostream &out, Int indent);
+
+ void trans(coenv &) {}
+};
+
+// Wrapper around a block to use it as a statement.
+class blockStm : public stm {
+ block *base;
+
+public:
+ blockStm(position pos, block *base)
+ : stm(pos), base(base) {}
+
+ void prettyprint(ostream &out, Int indent);
+
+ void trans(coenv &e) {
+ return base->trans(e);
+ }
+
+ // A block is guaranteed to return iff its last statement is
+ // guaranteed to return.
+ bool returns() {
+ return base->returns();
+ }
+
+};
+
+// A statement that consist of a single expression to evaluate.
+class expStm : public stm {
+ exp *body;
+
+ void baseTrans(coenv &e, exp *expr);
+public:
+ expStm(position pos, exp *body)
+ : stm(pos), body(body) {}
+
+ void prettyprint(ostream &out, Int indent);
+
+ void trans(coenv &e);
+
+ // Should be called when running an expStm at the interactive prompt.
+ // The code will "write" the value of the expression at the prompt if
+ // possible.
+ void interactiveTrans(coenv &e);
+};
+
+class ifStm : public stm {
+ exp *test;
+ stm *onTrue;
+ stm *onFalse;
+
+public:
+ ifStm(position pos, exp *test, stm* onTrue, stm* onFalse = 0)
+ : stm(pos), test(test), onTrue(onTrue), onFalse(onFalse) {}
+
+ void prettyprint(ostream &out, Int indent);
+
+ void trans(coenv &e);
+
+ // An if statement is guaranteed to return iff both its pieces are
+ // guaranteed to return.
+ bool returns() {
+ if (onTrue == 0 || onFalse == 0)
+ return false;
+ return onTrue->returns() && onFalse->returns();
+ }
+};
+
+class whileStm : public stm {
+ exp *test;
+ stm *body;
+
+public:
+ whileStm(position pos, exp *test, stm *body)
+ : stm(pos), test(test), body(body) {}
+
+ void prettyprint(ostream &out, Int indent);
+
+ void trans(coenv &e);
+};
+
+class doStm : public stm {
+ stm *body;
+ exp *test;
+
+public:
+ doStm(position pos, stm *body, exp *test)
+ : stm(pos), body(body), test(test) {}
+
+ void prettyprint(ostream &out, Int indent);
+
+ void trans(coenv &e);
+};
+
+class forStm : public stm {
+ runnable *init;
+ exp *test;
+ runnable *update;
+ stm *body;
+
+public:
+ forStm(position pos, runnable *init, exp *test, runnable *update, stm *body)
+ : stm(pos), init(init), test(test), update(update), body(body) {}
+
+ void prettyprint(ostream &out, Int indent);
+
+ void trans(coenv &e);
+};
+
+class extendedForStm : public stm {
+ ty *start;
+ symbol *var;
+ exp *set;
+
+ stm *body;
+
+public:
+ extendedForStm(position pos, ty *start, symbol *var, exp *set, stm *body)
+ : stm(pos), start(start), var(var), set(set), body(body) {}
+
+ void prettyprint(ostream &out, Int indent);
+
+ void trans(coenv &e);
+};
+
+
+class breakStm : public stm {
+public:
+ breakStm(position pos)
+ : stm(pos) {}
+
+ void prettyprint(ostream &out, Int indent);
+
+ void trans(coenv &e);
+};
+
+class continueStm : public stm {
+public:
+ continueStm(position pos)
+ : stm(pos) {}
+
+ void prettyprint(ostream &out, Int indent);
+
+ void trans(coenv &e);
+};
+
+class returnStm : public stm {
+ exp *value;
+
+public:
+ returnStm(position pos, exp *value = 0)
+ : stm(pos), value(value) {}
+
+ void prettyprint(ostream &out, Int indent);
+
+ void trans(coenv &e);
+
+ // A return statement, is of course, guaranteed to return.
+ bool returns() {
+ return true;
+ }
+};
+
+
+// Used at the start of for loops.
+class stmExpList : public stm {
+ mem::list<stm *> stms;
+
+public:
+ stmExpList(position pos)
+ : stm(pos) {}
+
+ // To ensure list deallocates properly.
+ virtual ~stmExpList() {}
+
+ void add(stm *s) {
+ stms.push_back(s);
+ }
+
+ void prettyprint(ostream &out, Int indent);
+
+ void trans(coenv &e);
+};
+
+} // namespace absyntax
+
+#endif
diff --git a/Build/source/utils/asymptote/symbol.cc b/Build/source/utils/asymptote/symbol.cc
new file mode 100644
index 00000000000..0f9a506e839
--- /dev/null
+++ b/Build/source/utils/asymptote/symbol.cc
@@ -0,0 +1,24 @@
+/*****
+ * symbol.cc
+ * Andy Hammerlindl 2002/06/18
+ *
+ * Creates symbols from strings so that multiple calls for a symbol of
+ * the same string will return a pointer to the same object.
+ *****/
+
+#include <cstdio>
+#include "symbol.h"
+
+
+
+namespace sym {
+
+GCInit symbol::initialize;
+
+mem::map<CONST string,symbol> symbol::dict;
+symbol *symbol::initsym=symbol::specialTrans(string("operator init"));
+symbol *symbol::castsym=symbol::specialTrans(string("operator cast"));
+symbol *symbol::ecastsym=symbol::specialTrans(string("operator ecast"));
+
+} // namespace sym
+
diff --git a/Build/source/utils/asymptote/symbol.h b/Build/source/utils/asymptote/symbol.h
new file mode 100644
index 00000000000..e630c5a99b1
--- /dev/null
+++ b/Build/source/utils/asymptote/symbol.h
@@ -0,0 +1,91 @@
+/*****
+ * symbol.h
+ * Andy Hammerlindl 2002/06/18
+ *
+ * Creates symbols from strings so that multiple calls for a symbol of
+ * the same string will return a pointer to the same object.
+ *****/
+
+#ifndef SYMBOL_H
+#define SYMBOL_H
+
+#include <iostream>
+#include <cassert>
+
+#include "common.h"
+
+using std::ostream;
+
+namespace sym {
+
+struct GCInit {
+#ifdef _AIX
+ typedef char * GC_PTR;
+#endif
+ GCInit() {
+#ifdef USEGC
+ GC_set_free_space_divisor(2);
+ GC_dont_expand=0;
+ GC_INIT();
+#endif
+ }
+};
+
+struct symbol {
+ static GCInit initialize;
+private:
+ string name;
+
+public:
+ static mem::map<CONST string,symbol> dict;
+
+ static symbol *specialTrans(string s) {
+ assert(dict.find(s) == dict.end());
+ return &(dict[s]=symbol(s,true));
+ }
+
+ symbol() : special(false) {}
+ symbol(string name, bool special=false)
+ : name(name), special(special) {}
+
+public:
+ friend class mem::map<CONST string,symbol>;
+ bool special; // NOTE: make this const (later).
+
+ static symbol *initsym;
+ static symbol *castsym;
+ static symbol *ecastsym;
+
+ static symbol *literalTrans(string s) {
+ if (dict.find(s) != dict.end())
+ return &dict[s];
+ else
+ return &(dict[s]=symbol(s));
+ }
+
+ static symbol *opTrans(string s) {
+ return literalTrans("operator "+s);
+ }
+
+ static symbol *trans(string s) {
+ // Figure out whether it's an operator or an identifier by looking at the
+ // first character.
+ char c=s[0];
+ return isalpha(c) || c == '_' ? literalTrans(s) : opTrans(s);
+ }
+
+ // Make a symbol that is guaranteed to be unique. It will not match any other
+ // symbol in the namespace.
+ static symbol *gensym(string s) {
+ return new symbol("gensym "+s);
+ }
+
+ operator string () { return string(name); }
+
+ friend ostream& operator<< (ostream& out, const symbol& sym)
+ { return out << sym.name; }
+};
+
+} // namespace sym
+
+#endif
diff --git a/Build/source/utils/asymptote/table.h b/Build/source/utils/asymptote/table.h
new file mode 100644
index 00000000000..e8717cfa8ed
--- /dev/null
+++ b/Build/source/utils/asymptote/table.h
@@ -0,0 +1,141 @@
+/*****
+ * table.h
+ * Andy Hammerlindl 2002/06/18
+ *
+ * Table used to bind symbols to vars and types in a namespace.
+ *****/
+
+#ifndef TABLE_H
+#define TABLE_H
+
+#include <cassert>
+#include <utility>
+
+#include "symbol.h"
+#include "common.h"
+
+namespace sym {
+
+template <class B>
+class table;
+
+template <class B>
+std::ostream& operator<< (std::ostream& out, const table<B>& t);
+
+template <class B>
+class table {
+protected:
+ typedef mem::multimap<symbol*CONST,B> scope_t;
+ typedef typename scope_t::iterator scope_iterator;
+ typedef mem::list<scope_t> scopes_t;
+ typedef mem::list<B> name_t;
+ typedef typename name_t::iterator name_iterator;
+ typedef mem::map<symbol*CONST,name_t> names_t;
+ typedef typename names_t::iterator names_iterator;
+
+ scopes_t scopes;
+ names_t names;
+
+ void remove(symbol *key);
+public :
+ table();
+
+ void enter(symbol *key, B value);
+ B look(symbol *key);
+
+ // Checks if a symbol was added in the last scope. Useful for
+ // stopping multiple definitions.
+ B lookInTopScope(symbol *key);
+
+ // Allows scoping and overloading of symbols of the same name
+ void beginScope();
+ void endScope();
+
+ // Copies all bindings in the top scope to the scope underneath it, and
+ // removes the the top scope.
+ void collapseScope();
+
+ // Adds to l, all names prefixed by start.
+ void completions(mem::list<symbol *>& l, string start);
+
+ friend std::ostream& operator<< <B> (std::ostream& out, const table& t);
+};
+
+template <class B>
+inline table<B>::table()
+{
+ beginScope();
+}
+
+template <class B>
+inline void table<B>::enter(symbol *key, B value)
+{
+ scopes.front().insert(std::make_pair(key,value));
+ names[key].push_front(value);
+}
+
+template <class B>
+inline B table<B>::look(symbol *key)
+{
+ if (!names[key].empty())
+ return names[key].front();
+ return 0;
+}
+
+template <class B>
+inline B table<B>::lookInTopScope(symbol *key)
+{
+ scope_iterator p = scopes.front().find(key);
+ if (p!=scopes.front().end())
+ return p->second;
+ return 0;
+}
+
+template <class B>
+inline void table<B>::beginScope()
+{
+ scopes.push_front(scope_t());
+}
+
+template <class B>
+inline void table<B>::remove(symbol *key)
+{
+ if (!names[key].empty())
+ names[key].pop_front();
+}
+
+template <class B>
+inline void table<B>::endScope()
+{
+ scope_t &scope = scopes.front();
+ for (scope_iterator p = scope.begin(); p != scope.end(); ++p)
+ remove(p->first);
+ scopes.pop_front();
+}
+
+template <class B>
+inline void table<B>::collapseScope()
+{
+ scope_t scope = scopes.front();
+ scopes.pop_front();
+
+ scopes.front().insert(scope.begin(), scope.end());
+}
+
+// Returns true if start is a prefix for name; eg, mac is a prefix of machine.
+inline bool prefix(string start, string name) {
+ return equal(start.begin(), start.end(), name.begin());
+}
+
+template <class B>
+inline void table<B>::completions(mem::list<symbol *>& l, string start)
+{
+ for (names_iterator p = names.begin(); p != names.end(); ++p)
+ if (prefix(start, *(p->first)) && !p->second.empty())
+ l.push_back(p->first);
+}
+
+
+} // namespace sym
+
+#endif
diff --git a/Build/source/utils/asymptote/tests/Makefile b/Build/source/utils/asymptote/tests/Makefile
new file mode 100644
index 00000000000..d05ae0a2169
--- /dev/null
+++ b/Build/source/utils/asymptote/tests/Makefile
@@ -0,0 +1,14 @@
+TESTDIRS = string arith frames types imp array
+
+test: $(TESTDIRS)
+
+$(TESTDIRS)::
+ @echo
+ ../asy -dir ../base $@/*.asy
+
+clean: FORCE
+ rm -f *.eps
+
+distclean: FORCE clean
+
+FORCE:
diff --git a/Build/source/utils/asymptote/tests/TestLib.asy b/Build/source/utils/asymptote/tests/TestLib.asy
new file mode 100644
index 00000000000..a4a4b239927
--- /dev/null
+++ b/Build/source/utils/asymptote/tests/TestLib.asy
@@ -0,0 +1,15 @@
+bool close(pair a, pair b)
+{
+ real norm=(b == 0) ? 1 : max(abs(a),abs(b));
+ return abs(a-b) <= 100*realEpsilon*norm;
+}
+
+void StartTest(string desc)
+{
+ write("Testing " + desc + "...",flush);
+}
+
+void EndTest()
+{
+ write("PASSED.");
+}
diff --git a/Build/source/utils/asymptote/tests/arith/integer.asy b/Build/source/utils/asymptote/tests/arith/integer.asy
new file mode 100644
index 00000000000..a402ca58955
--- /dev/null
+++ b/Build/source/utils/asymptote/tests/arith/integer.asy
@@ -0,0 +1,15 @@
+// Integer arithmetic.
+import TestLib;
+StartTest("integer addition");
+assert(1+1==2);
+EndTest();
+StartTest("integer subtraction");
+assert(2-1==1);
+EndTest();
+StartTest("integer multiplication");
+assert(2*2==4);
+EndTest();
+StartTest("integer division");
+assert(4/2==2);
+EndTest();
+
diff --git a/Build/source/utils/asymptote/tests/arith/pair.asy b/Build/source/utils/asymptote/tests/arith/pair.asy
new file mode 100644
index 00000000000..c815f28b2fa
--- /dev/null
+++ b/Build/source/utils/asymptote/tests/arith/pair.asy
@@ -0,0 +1,20 @@
+import TestLib;
+
+StartTest("complex addition");
+assert((1,0)+(0,1)==(1,1));
+EndTest();
+StartTest("complex subtraction");
+assert((1,0)-(0,1)==(1,-1));
+EndTest();
+StartTest("complex multiplication");
+assert((1,2)*(2,1)==(0,5));
+EndTest();
+StartTest("complex division");
+assert((0,5)/(2,1)==(1,2));
+EndTest();
+StartTest("length(pair)");
+assert(length((0.0,1.0)) == 1.0);
+EndTest();
+StartTest("conj()");
+assert(conj((0.0,1.0))==(0.0, -1.0));
+EndTest();
diff --git a/Build/source/utils/asymptote/tests/arith/real.asy b/Build/source/utils/asymptote/tests/arith/real.asy
new file mode 100644
index 00000000000..1628258cf83
--- /dev/null
+++ b/Build/source/utils/asymptote/tests/arith/real.asy
@@ -0,0 +1,18 @@
+// Real arithmetic.
+
+import TestLib;
+StartTest("real error");
+assert((1.0-1.0) < realEpsilon);
+EndTest();
+StartTest("real addition");
+assert((1.0+1.0) == (2.0));
+EndTest();
+StartTest("real subtraction");
+assert((2.0-1.0) == (1.0));
+EndTest();
+StartTest("real multiplication");
+assert((2.0*2.0) == (4.0));
+EndTest();
+StartTest("real division");
+assert((4.0/2.0) == (2.0));
+EndTest();
diff --git a/Build/source/utils/asymptote/tests/arith/roots.asy b/Build/source/utils/asymptote/tests/arith/roots.asy
new file mode 100644
index 00000000000..d3e5d55f367
--- /dev/null
+++ b/Build/source/utils/asymptote/tests/arith/roots.asy
@@ -0,0 +1,96 @@
+// Roots.
+
+import TestLib;
+real x;
+real[] r;
+
+StartTest("quadratic roots");
+
+r=quadraticroots(1,0,-8);
+assert(r.length == 2);
+r=sort(r);
+x=2sqrt(2);
+assert(close(r[0],-x));
+assert(close(r[1],x));
+
+r=quadraticroots(1,2,1);
+assert(r.length == 2);
+assert(close(r[0],-1));
+assert(close(r[1],-1));
+
+r=quadraticroots(1,0,8);
+assert(r.length == 0);
+
+r=quadraticroots(0,2,3);
+assert(r.length == 1);
+assert(close(r[0],-3/2));
+
+EndTest();
+
+StartTest("cubic roots");
+
+r=cubicroots(1,0,0,-8);
+assert(r.length == 1);
+assert(close(r[0],2));
+
+real[] r=cubicroots(1,3,3,1);
+assert(r.length == 3);
+assert(close(r[0],-1));
+assert(close(r[1],-1));
+assert(close(r[2],-1));
+
+real[] r=cubicroots(1,-3,3,-1);
+assert(r.length == 3);
+assert(close(r[0],1));
+assert(close(r[1],1));
+assert(close(r[2],1));
+
+r=cubicroots(1,0,0,0);
+assert(r.length == 3);
+assert(r[0] == 0);
+assert(r[1] == 0);
+assert(r[2] == 0);
+
+r=cubicroots(1,0,-15,-4);
+assert(r.length == 3);
+r=sort(r);
+assert(close(r[0],-2-sqrt(3)));
+assert(close(r[1],-2+sqrt(3)));
+assert(close(r[2],4));
+
+r=cubicroots(1,0,-15,4);
+assert(r.length == 3);
+r=sort(r);
+assert(close(r[0],-4));
+assert(close(r[1],2-sqrt(3)));
+assert(close(r[2],2+sqrt(3)));
+
+r=cubicroots(1,0,-15,0);
+assert(r.length == 3);
+r=sort(r);
+x=sqrt(15);
+assert(close(r[0],-x));
+assert(r[1] == 0);
+assert(close(r[2],x));
+
+r=cubicroots(1,1,1,0);
+assert(r.length == 1);
+assert(r[0] == 0);
+
+r=cubicroots(1,0,20,-4);
+assert(r.length == 1);
+x=cbrt(54+6sqrt(6081));
+assert(close(r[0],x/3-20/x));
+
+EndTest();
+
+StartTest("newton");
+
+real f(real x) {return cos(x);}
+real dfdx(real x) {return -sin(x);}
+
+assert(close(newton(f,dfdx,1),pi/2));
+assert(newton(f,dfdx,0) == realMax);
+assert(newton(f,dfdx,0,2) == pi/2);
+
+EndTest();
diff --git a/Build/source/utils/asymptote/tests/arith/transform.asy b/Build/source/utils/asymptote/tests/arith/transform.asy
new file mode 100644
index 00000000000..e4e44e387b8
--- /dev/null
+++ b/Build/source/utils/asymptote/tests/arith/transform.asy
@@ -0,0 +1,25 @@
+import TestLib;
+pair x = (1, 2);
+StartTest("identity transform");
+assert(identity()*x == x);
+EndTest();
+StartTest("shift transform");
+assert(shift((1,1))*x == (2, 3));
+assert(shift(1,1)*x == (2, 3));
+EndTest();
+StartTest("scaling transforms");
+assert(xscale(2)*x == (2, 2));
+assert(yscale(2)*x == (1, 4));
+assert(scale(2)*x == (2, 4));
+EndTest();
+StartTest("slant transform");
+assert(slant(1)*x == (3, 2));
+EndTest();
+StartTest("rotation transform");
+assert(length((rotate(90)*x) - (-2,1)) <= realEpsilon);
+assert(rotate(90, x)*x == x);
+EndTest();
+StartTest("reflect transform");
+assert(reflect((-1, -1), (1, 1))*x == (2, 1));
+EndTest();
+
diff --git a/Build/source/utils/asymptote/tests/arith/triple.asy b/Build/source/utils/asymptote/tests/arith/triple.asy
new file mode 100644
index 00000000000..135801b6330
--- /dev/null
+++ b/Build/source/utils/asymptote/tests/arith/triple.asy
@@ -0,0 +1,11 @@
+import TestLib;
+triple t = (1,0,0);
+StartTest("polar()");
+assert(polar(t) == (pi / 2.0) );
+EndTest();
+StartTest("azimuth()");
+assert(azimuth(t) < realEpsilon);
+EndTest();
+StartTest("unit()");
+assert(length(t-unit(t)) < realEpsilon);
+EndTest();
diff --git a/Build/source/utils/asymptote/tests/array/array.asy b/Build/source/utils/asymptote/tests/array/array.asy
new file mode 100644
index 00000000000..106856fd80b
--- /dev/null
+++ b/Build/source/utils/asymptote/tests/array/array.asy
@@ -0,0 +1,49 @@
+import TestLib;
+
+StartTest("array");
+
+{
+ int[] x=array(10, 7);
+ assert(x.length == 10);
+ for (int i=0; i<x.length; ++i)
+ assert(x[i] == 7);
+}
+{
+ int[][] y=array(10, array(10, 7));
+ assert(y.length == 10);
+ for (int i=0; i<y.length; ++i) {
+ assert(y[i].length == 10);
+ for (int j=0; j<y[i].length; ++j)
+ assert(y[i][j] == 7);
+ }
+}
+{
+ int[][] y=array(10, array(10, 7));
+ y[4][5] = 9;
+ assert(y.length == 10);
+ for (int i=0; i<y.length; ++i) {
+ assert(y[i].length == 10);
+ for (int j=0; j<y[i].length; ++j)
+ if (i==4 && j==5)
+ assert(y[i][j] == 9);
+ else
+ assert(y[i][j] == 7);
+ }
+}
+{
+ int[][] y=array(10, array(10, 7), depth=0);
+ y[4][5] = 9;
+ assert(y.length == 10);
+ for (int i=0; i<y.length; ++i) {
+ assert(y[i].length == 10);
+ for (int j=0; j<y[i].length; ++j)
+ if (j==5)
+ assert(y[i][j] == 9);
+ else
+ assert(y[i][j] == 7);
+ }
+}
+
+
+
+EndTest();
diff --git a/Build/source/utils/asymptote/tests/array/delete.asy b/Build/source/utils/asymptote/tests/array/delete.asy
new file mode 100644
index 00000000000..0b00e3f0e46
--- /dev/null
+++ b/Build/source/utils/asymptote/tests/array/delete.asy
@@ -0,0 +1,41 @@
+import TestLib;
+import math;
+
+StartTest("delete");
+
+int[] a=sequence(4);
+a.delete(2);
+assert(all(a == new int[] {0,1,3}));
+
+int[] a=sequence(4);
+a.delete(0,2);
+assert(all(a == new int[] {3}));
+
+int[] a=sequence(4);
+a.delete(1,2);
+assert(all(a == new int[] {0,3}));
+
+int[] a=sequence(4);
+a.delete(2,2);
+assert(all(a == new int[] {0,1,3}));
+
+int[] a=sequence(4);
+a.delete(2,3);
+assert(all(a == new int[] {0,1}));
+
+int[] a=sequence(4);
+a.cyclic(true);
+a.delete(2,3);
+assert(all(a == new int[] {0,1}));
+
+int[] a=sequence(4);
+a.cyclic(true);
+a.delete(2,4);
+assert(all(a == new int[] {1}));
+
+int[] a=sequence(4);
+a.cyclic(true);
+a.delete(3,1);
+assert(all(a == new int[] {2}));
+
+EndTest();
diff --git a/Build/source/utils/asymptote/tests/array/determinant.asy b/Build/source/utils/asymptote/tests/array/determinant.asy
new file mode 100644
index 00000000000..e6086d0b04f
--- /dev/null
+++ b/Build/source/utils/asymptote/tests/array/determinant.asy
@@ -0,0 +1,18 @@
+import TestLib;
+import math;
+
+StartTest("determinant");
+assert(determinant(new real[][] {{0}}) == 0);
+assert(determinant(new real[][] {{1}}) == 1);
+assert(determinant(new real[][] {{1,2},{3,4}}) == -2);
+real e=1e-20;
+assert(close(determinant(new real[][] {{1e,2e},{3e,4e}}),-2e-40));
+assert(close(determinant(new real[][] {{1,2,3},{4,5,6},{7,8,9}}),0));
+assert(close(determinant(new real[][] {{1,2},{1,2}}),0));
+assert(close(determinant(new real[][] {{1,2,3,4},
+ {5,6,7,8},{9,10,11,12},{13,14,15,16}}),0));
+assert(close(determinant(new real[][] {{1,2,3,4},
+ {5,0,7,8},{9,10,0,12},{13,14,15,16}}),-2376));
+assert(close(determinant(new real[][]{{1,-2,3,0},{4,-5,6,2},{-7,-8,10,5},
+ {1,50,1,-2}}),-4588));
+EndTest();
diff --git a/Build/source/utils/asymptote/tests/array/slice.asy b/Build/source/utils/asymptote/tests/array/slice.asy
new file mode 100644
index 00000000000..709263504ce
--- /dev/null
+++ b/Build/source/utils/asymptote/tests/array/slice.asy
@@ -0,0 +1,232 @@
+import TestLib;
+
+StartTest("slice");
+
+int[] x={0,1,2,3,4,5,6,7,8,9};
+
+// Non-cyclic cases.
+assert(all(x[:] == x));
+assert(!alias(x[:],x));
+
+assert(all(x[0:4] == new int[] {0,1,2,3} ));
+assert(all(x[2:4] == new int[] {2,3} ));
+
+assert(all(x[5:] == new int[] {5,6,7,8,9} ));
+assert(all(x[:5] == new int[] {0,1,2,3,4} ));
+
+assert(all(x[3:3] == new int[] {} ));
+assert(all(x[3:4] == new int[] {3} ));
+assert(all(x[98:99] == new int[] {} ));
+
+assert(x[:].cyclicflag == false);
+assert(x[2:].cyclicflag == false);
+assert(x[:7].cyclicflag == false);
+assert(x[3:3].cyclicflag == false);
+assert(x[2:9].cyclicflag == false);
+
+// Cyclic cases
+x.cyclic(true);
+
+assert(all(x[:] == new int[] {0,1,2,3,4,5,6,7,8,9} ));
+assert(all(x[0:4] == new int[] {0,1,2,3} ));
+assert(all(x[2:4] == new int[] {2,3} ));
+
+assert(all(x[5:] == new int[] {5,6,7,8,9} ));
+assert(all(x[-5:] == new int[] {5,6,7,8,9,0,1,2,3,4,5,6,7,8,9} ));
+assert(all(x[:5] == new int[] {0,1,2,3,4} ));
+
+assert(all(x[3:3] == new int[] {} ));
+assert(all(x[3:4] == new int[] {3} ));
+
+assert(all(x[-1:1] == new int[] {9,0} ));
+assert(all(x[9:11] == new int[] {9,0} ));
+assert(all(x[9:21] == new int[] {9,0,1,2,3,4,5,6,7,8,9,0} ));
+assert(all(x[-15:15] == new int[] {5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,
+ 0,1,2,3,4,5,6,7,8,9,0,1,2,3,4}));
+assert(all(x[6728:6729] == new int[] {8} ));
+assert(all(x[-6729:-6728] == new int[] {1} ));
+
+assert(x[:].cyclicflag == false);
+assert(x[2:].cyclicflag == false);
+assert(x[:7].cyclicflag == false);
+assert(x[3:3].cyclicflag == false);
+assert(x[2:9].cyclicflag == false);
+assert(x[5:100].cyclicflag == false);
+
+pair[] z={(1,2), (3,4), (5,6)};
+assert(all(z[1:1] == new pair[] {}));
+assert(all(z[:1] == new pair[] {(1,2)}));
+assert(all(z[1:] == new pair[] {(3,4), (5,6)}));
+assert(all(z[:] == z));
+assert(all(z[1:2] == new pair[] {(3,4)}));
+
+// Writing tests.
+{
+ int[] y={0,1,2,3,4,5,6,7,8,9};
+ int[] z={56,67,78};
+
+ y[:] = z;
+ assert(all(y == z));
+ assert(!alias(y,z));
+}
+{
+ int[] y={0,1,2,3,4,5,6,7,8,9};
+ int[] z={56,67,78};
+ z.cyclic(true);
+
+ y[:] = z;
+ assert(all(y == z));
+ assert(!alias(y,z));
+ assert(y.cyclicflag == false);
+}
+{
+ int[] y={0,1,2,3,4,5,6,7,8,9};
+
+ y[2:3] = y[5:6] = new int[] {77};
+ assert(all(y == new int[] {0,1,77,3,4,77,6,7,8,9}));
+}
+{
+ int[] y={0,1,2,3,4,5,6,7,8,9};
+
+ y[:3] = y[7:] = new int[] {};
+ assert(all(y == new int[] {3,4,5,6}));
+}
+{
+ int[] y={0,1,2,3,4,5,6,7,8,9};
+
+ y[3:5] = new int[] {13,14,15,16,17};
+ assert(all(y == new int[] {0,1,2,13,14,15,16,17,5,6,7,8,9}));
+}
+{
+ int[] y={0,1,2,3,4,5,6,7,8,9};
+ y.cyclic(true);
+ int[] z={56,67,78};
+
+ y[:] = z;
+ assert(all(y == z));
+ assert(!alias(y,z));
+ assert(y.cyclicflag == true);
+}
+{
+ int[] y={0,1,2,3,4,5,6,7,8,9};
+ y.cyclic(true);
+ int[] z={56,67,78};
+ z.cyclic(true);
+
+ y[:] = z;
+ assert(all(y == z));
+ assert(!alias(y,z));
+ assert(y.cyclicflag == true);
+}
+{
+ int[] y={0,1,2,3,4,5,6,7,8,9};
+ y.cyclic(true);
+
+ y[2:3] = y[5:6] = new int[] {77};
+ assert(all(y == new int[] {0,1,77,3,4,77,6,7,8,9}));
+}
+{
+ int[] y={0,1,2,3,4,5,6,7,8,9};
+ y.cyclic(true);
+
+ y[:3] = y[7:] = new int[] {};
+ assert(all(y == new int[] {3,4,5,6}));
+}
+{
+ int[] y={0,1,2,3,4,5,6,7,8,9};
+ y.cyclic(true);
+
+ y[8:] = new int[] {18,19,20,21,22};
+ assert(all(y == new int[] {0,1,2,3,4,5,6,7,18,19,20,21,22}));
+}
+{
+ int[] y={0,1,2,3,4,5,6,7,8,9};
+ y.cyclic(true);
+
+ y[-2:0] = new int[] {18,19,20,21,22};
+ assert(all(y == new int[] {0,1,2,3,4,5,6,7,18,19,20,21,22}));
+}
+{
+ int[] y={0,1,2,3,4,5,6,7,8,9};
+ y.cyclic(true);
+
+ y[18:20] = new int[] {18,19,20,21,22};
+ assert(all(y == new int[] {0,1,2,3,4,5,6,7,18,19,20,21,22}));
+}
+{
+ int[] y={0,1,2,3,4,5,6,7,8,9};
+ y.cyclic(true);
+
+ y[3:5] = new int[] {13,14,15,16,17};
+ assert(all(y == new int[] {0,1,2,13,14,15,16,17,5,6,7,8,9}));
+}
+{
+ int[] y={0,1,2,3,4,5,6,7,8,9};
+ y.cyclic(true);
+
+ y[13:15] = new int[] {13,14,15,16,17};
+ assert(all(y == new int[] {0,1,2,13,14,15,16,17,5,6,7,8,9}));
+}
+{
+ int[] y={0,1,2,3,4,5,6,7,8,9};
+ y.cyclic(true);
+
+ y[3-10:5-10] = new int[] {13,14,15,16,17};
+ assert(all(y == new int[] {0,1,2,13,14,15,16,17,5,6,7,8,9}));
+}
+{
+ int[] y={0,1,2,3,4,5,6,7,8,9};
+ y.cyclic(true);
+
+ y[8:12] = new int[] {18,19,20,21};
+ assert(all(y == new int[] {20,21,2,3,4,5,6,7,18,19}));
+}
+{
+ int[] y={0,1,2,3,4,5,6,7,8,9};
+ y.cyclic(true);
+
+ y[-2:2] = new int[] {18,19,20,21};
+ assert(all(y == new int[] {20,21,2,3,4,5,6,7,18,19}));
+}
+
+// Side Effect Test
+{
+ int state=0;
+ int[] x={0,1,2,3,4,5,6,7,8,9};
+
+ int[] a() {
+ assert(state==0);
+ ++state;
+
+ return x;
+ }
+
+ int l() {
+ assert(state==1);
+ ++state;
+
+ return 2;
+ }
+
+ int r() {
+ assert(state==2);
+ ++state;
+
+ return 6;
+ }
+
+ int[] b() {
+ assert(state==3);
+ ++state;
+
+ return new int[] {77,77};
+ }
+
+ assert(state==0);
+ a()[l():r()]=b();
+ assert(state==4);
+ assert(all(x == new int[] {0,1,77,77,6,7,8,9}));
+}
+
+
+EndTest();
diff --git a/Build/source/utils/asymptote/tests/array/solve.asy b/Build/source/utils/asymptote/tests/array/solve.asy
new file mode 100644
index 00000000000..ec1c4416ba4
--- /dev/null
+++ b/Build/source/utils/asymptote/tests/array/solve.asy
@@ -0,0 +1,35 @@
+import TestLib;
+
+StartTest("solve");
+real[][] a=new real[][] {{1,1,1},{1,2,2},{0,0,1}};
+real[][] b=new real[][] {{3,9},{5,11},{1,3}};
+real[][] x=new real[][] {{1,7},{1,-1,},{1,3}};
+real[][] c=solve(a,b);
+for(int i=0; i < c.length; ++i)
+ for(int j=0; j < c[i].length; ++j)
+ assert(close(c[i][j],x[i][j]));
+
+real[][] a={{1,-2,3,0},{4,-5,6,2},{-7,-8,10,5},{1,50,1,-2}};
+real[] b={7,19,33,3};
+real[] x=solve(a,b);
+real[] c=a*x;
+for(int i=0; i < c.length; ++i)
+ assert(close(c[i],b[i]));
+EndTest();
+
+StartTest("inverse");
+real[][] a=new real[][] {{1,1,1},{1,2,2},{0,0,1}};
+real[][] ainverse=new real[][] {{2,-1,0},{-1,1,-1},{0,0,1}};
+real[][] d=inverse(a);
+real[][] l=d*a;
+real[][] r=a*d;
+real[][] I=identity(a.length);
+for(int i=0; i < d.length; ++i) {
+ for(int j=0; j < d[i].length; ++j) {
+ assert(close(d[i][j],ainverse[i][j]));
+ assert(I[i][j] == (i == j ? 1 : 0));
+ assert(close(l[i][j],I[i][j]));
+ assert(close(r[i][j],I[i][j]));
+ }
+}
+EndTest();
diff --git a/Build/source/utils/asymptote/tests/array/transpose.asy b/Build/source/utils/asymptote/tests/array/transpose.asy
new file mode 100644
index 00000000000..f0366ba8fd1
--- /dev/null
+++ b/Build/source/utils/asymptote/tests/array/transpose.asy
@@ -0,0 +1,55 @@
+import TestLib;
+import math;
+
+StartTest("transpose");
+int n=3;
+real[][] a=new real[n][n];
+real[][] b=new real[n][n];
+for(int i=0; i < n; ++i) {
+ for(int j=0; j < n; ++j) {
+ a[i][j]=b[j][i]=rand();
+ }
+}
+
+bool operator == (real[][] a, real[][] b)
+{
+ int n=a.length;
+ for(int i=0; i < n; ++i)
+ if(!all(a[i] == b[i])) return false;
+ return true;
+}
+
+bool operator == (real[][][] a, real[][][] b)
+{
+ int n=a.length;
+ for(int i=0; i < n; ++i) {
+ real[][] ai=a[i];
+ real[][] bi=b[i];
+ int m=ai.length;
+ for(int j=0; j < m; ++j) {
+ if(!all(ai[j] == bi[j])) return false;
+ }
+ }
+ return true;
+}
+
+assert(a == transpose(b));
+
+int n=3;
+real[][][] a=new real[n][n][n];
+real[][][] b=new real[n][n][n];
+real[][][] c=new real[n][n][n];
+real[][][] d=new real[n][n][n];
+for(int i=0; i < n; ++i) {
+ for(int j=0; j < n; ++j) {
+ for(int k=0; k < n; ++k) {
+ a[i][j][k]=b[j][i][k]=c[i][k][j]=d[k][j][i]=rand();
+ }
+ }
+}
+
+assert(a == transpose(b,new int[] {1,0,2}));
+assert(a == transpose(c,new int[] {0,2,1}));
+assert(a == transpose(d,new int[] {2,1,0}));
+
+EndTest();
diff --git a/Build/source/utils/asymptote/tests/bench/6000circles.asy b/Build/source/utils/asymptote/tests/bench/6000circles.asy
new file mode 100644
index 00000000000..53ebecce27a
--- /dev/null
+++ b/Build/source/utils/asymptote/tests/bench/6000circles.asy
@@ -0,0 +1,17 @@
+size(0,100);
+import math;
+import stats;
+
+currentpen=magenta;
+// A centered random number
+real crand() {return unitrand()*5;}
+
+real r1;
+pair pcenter;
+
+for(int i=0; i < 6000; ++i) {
+
+r1 = unitrand()/10;
+pcenter = ( crand(), crand());
+Draw(circle(pcenter,r1));
+}
diff --git a/Build/source/utils/asymptote/tests/frames/loop.asy b/Build/source/utils/asymptote/tests/frames/loop.asy
new file mode 100644
index 00000000000..ceb65a1ff56
--- /dev/null
+++ b/Build/source/utils/asymptote/tests/frames/loop.asy
@@ -0,0 +1,29 @@
+import TestLib;
+StartTest("loop");
+
+int f();
+for (int i=0; i<10; ++i) {
+ int x=i;
+ for (int j=0; j<10; ++j) {
+ int y=j;
+ if (i==5 && j==7) {
+ f = new int () { return x*y; };
+ }
+ }
+}
+assert(f()==35);
+
+int f();
+
+for (int i=0; i<10; ++i) {
+ int x=i;
+ for (int j=0; j<10; ++j) {
+ int y=j;
+ if (i==5 && j==7) {
+ f = new int () { return i*y; };
+ }
+ }
+}
+assert(f()==70);
+
+EndTest();
diff --git a/Build/source/utils/asymptote/tests/frames/stat.asy b/Build/source/utils/asymptote/tests/frames/stat.asy
new file mode 100644
index 00000000000..d366b193e0d
--- /dev/null
+++ b/Build/source/utils/asymptote/tests/frames/stat.asy
@@ -0,0 +1,14 @@
+import TestLib;
+StartTest("stat");
+struct T {
+ int x;
+ static void f(T t) {
+ t.x=2;
+ }
+}
+
+T t=new T;
+assert(t.x==0);
+T.f(t);
+assert(t.x==2);
+EndTest();
diff --git a/Build/source/utils/asymptote/tests/frames/stat2.asy b/Build/source/utils/asymptote/tests/frames/stat2.asy
new file mode 100644
index 00000000000..ea5863b081a
--- /dev/null
+++ b/Build/source/utils/asymptote/tests/frames/stat2.asy
@@ -0,0 +1,17 @@
+import TestLib;
+StartTest("stat2");
+struct T {
+ int x;
+ static void f(T t) {
+ static void g(T t) {
+ t.x=2;
+ }
+ g(t);
+ }
+}
+
+T t=new T;
+assert(t.x==0);
+T.f(t);
+assert(t.x==2);
+EndTest();
diff --git a/Build/source/utils/asymptote/tests/gc/array.asy b/Build/source/utils/asymptote/tests/gc/array.asy
new file mode 100644
index 00000000000..4b903ad95df
--- /dev/null
+++ b/Build/source/utils/asymptote/tests/gc/array.asy
@@ -0,0 +1,5 @@
+real[] a;
+for (int i = 0; i < 1e7; ++i)
+{
+ a=new real[10];
+}
diff --git a/Build/source/utils/asymptote/tests/gc/file.asy b/Build/source/utils/asymptote/tests/gc/file.asy
new file mode 100644
index 00000000000..5e43b5b6603
--- /dev/null
+++ b/Build/source/utils/asymptote/tests/gc/file.asy
@@ -0,0 +1,7 @@
+for (int i = 0; i < 1e5; ++i)
+{
+ file a=output("out/"+(string) i);
+ write(a,i,endl);
+ close(a);
+}
+
diff --git a/Build/source/utils/asymptote/tests/gc/funcall.asy b/Build/source/utils/asymptote/tests/gc/funcall.asy
new file mode 100644
index 00000000000..d565525420a
--- /dev/null
+++ b/Build/source/utils/asymptote/tests/gc/funcall.asy
@@ -0,0 +1,6 @@
+void g()
+{}
+for (int i = 0; i < 1e7; ++i)
+{
+ g();
+}
diff --git a/Build/source/utils/asymptote/tests/gc/guide.asy b/Build/source/utils/asymptote/tests/gc/guide.asy
new file mode 100644
index 00000000000..af7af28a86a
--- /dev/null
+++ b/Build/source/utils/asymptote/tests/gc/guide.asy
@@ -0,0 +1,5 @@
+guide a=(0,0);
+for (int i = 0; i < 1e7; ++i)
+{
+ guide b=a--a;
+}
diff --git a/Build/source/utils/asymptote/tests/gc/path.asy b/Build/source/utils/asymptote/tests/gc/path.asy
new file mode 100644
index 00000000000..118826eba10
--- /dev/null
+++ b/Build/source/utils/asymptote/tests/gc/path.asy
@@ -0,0 +1,8 @@
+guide a;
+for (int i = 0; i < 1e7; ++i)
+{
+// guide a=a--(1.0,2.0);
+ path p=(1.0,2.0);
+ path q=(3.0,4.0);
+ path a=p--q;
+}
diff --git a/Build/source/utils/asymptote/tests/gc/pen.asy b/Build/source/utils/asymptote/tests/gc/pen.asy
new file mode 100644
index 00000000000..7b8d48dfcec
--- /dev/null
+++ b/Build/source/utils/asymptote/tests/gc/pen.asy
@@ -0,0 +1,4 @@
+for (int i = 0; i < 1e7; ++i)
+{
+ pen p = linetype("test");
+}
diff --git a/Build/source/utils/asymptote/tests/gc/string.asy b/Build/source/utils/asymptote/tests/gc/string.asy
new file mode 100644
index 00000000000..f379b862249
--- /dev/null
+++ b/Build/source/utils/asymptote/tests/gc/string.asy
@@ -0,0 +1,6 @@
+string a="abc";
+for (int i = 0; i < 1e7; ++i)
+{
+ "a"+"b";
+ a=reverse(a);
+}
diff --git a/Build/source/utils/asymptote/tests/gc/struct.asy b/Build/source/utils/asymptote/tests/gc/struct.asy
new file mode 100644
index 00000000000..db3a22280ac
--- /dev/null
+++ b/Build/source/utils/asymptote/tests/gc/struct.asy
@@ -0,0 +1,7 @@
+for (int i = 0; i < 1e7; ++i)
+{
+ picture pic;
+ unitsize(pic, 0.02mm, 0.04mm);
+ draw(pic,unitcircle);
+ shipout(pic);
+}
diff --git a/Build/source/utils/asymptote/tests/gc/transform.asy b/Build/source/utils/asymptote/tests/gc/transform.asy
new file mode 100644
index 00000000000..abeef056564
--- /dev/null
+++ b/Build/source/utils/asymptote/tests/gc/transform.asy
@@ -0,0 +1,6 @@
+path p=unitsquare;
+
+for (int i = 0; i < 1e7; ++i)
+{
+ scale(2.0)*p;
+}
diff --git a/Build/source/utils/asymptote/tests/imp/unravel.asy b/Build/source/utils/asymptote/tests/imp/unravel.asy
new file mode 100644
index 00000000000..0f61326fd66
--- /dev/null
+++ b/Build/source/utils/asymptote/tests/imp/unravel.asy
@@ -0,0 +1,95 @@
+import TestLib;
+StartTest("unravel");
+{
+ struct A {
+ int x=1, y=2, z=3;
+ int y() { return 7; }
+ }
+
+ A a=new A;
+ unravel a;
+ assert(x==1);
+ assert(y==2);
+ assert(z==3);
+ assert(y()==7);
+}
+{
+ struct A {
+ private int x=1;
+ int y=2, z=3;
+ int y() { return 7; }
+ }
+
+ int x=5;
+ A a=new A;
+ unravel a;
+ assert(x==5);
+ assert(y==2);
+ assert(z==3);
+}
+{
+ struct A {
+ public int x=1;
+ int y=2, z=3;
+ int y() { return 7; }
+ }
+
+ int z=5;
+ A a=new A;
+ from a unravel x,y;
+ assert(x==1);
+ assert(y==2);
+ assert(z==5);
+ assert(y()==7);
+}
+{
+ struct A {
+ public int x=1;
+ int y=2, z=3;
+ int y() { return 7; }
+ }
+
+ int y=4;
+ int z=5;
+ A a=new A;
+ from a unravel x,y as blah;
+ assert(x==1);
+ assert(y==4);
+ assert(blah==2);
+ assert(z==5);
+ assert(blah()==7);
+}
+{
+ struct A {
+ struct B {
+ static int x=4;
+ }
+ }
+ A a=new A;
+ int x=3;
+ from a.B unravel x;
+ assert(x==4);
+}
+{
+ struct A {
+ struct B {
+ static int x=4;
+ }
+ }
+ A a=new A;
+ A.B b=new a.B;
+ int x=3;
+ from b unravel x;
+ assert(x==4);
+}
+{
+ struct A {
+ static struct B {
+ static int x=4;
+ }
+ }
+ int x=3;
+ from A.B unravel x;
+ assert(x==4);
+}
+EndTest();
diff --git a/Build/source/utils/asymptote/tests/output/Makefile b/Build/source/utils/asymptote/tests/output/Makefile
new file mode 100644
index 00000000000..2462ea1cae5
--- /dev/null
+++ b/Build/source/utils/asymptote/tests/output/Makefile
@@ -0,0 +1,41 @@
+# Automated testing to see if the output of Asymptote scripts changes when the
+# program is modified.
+
+# How to call asy from the tests/output/name.out directory
+ASY=../../../asy
+
+TESTS=$(basename $(wildcard *.asy))
+
+# This command performs the testing on all scripts.
+diff: $(TESTS:=.diff)
+
+# This builds the reference copies of the output using a trusted version of asy
+ref: $(TESTS:=.ref)
+
+$(TESTS:=.ref) $(TESTS:=.out): %:
+ @echo Generating $@
+ @rm -rf $@
+ @mkdir $@
+ @cd $@; \
+ $(ASY) -v -v -keep ../$(basename $@) \
+ >$(basename $@).stdout 2>$(basename $@).stderr; \
+ ls >$(basename $@).ls; \
+ rm -f *.dvi *.pdf *.gif *.jpg *.jpeg *.png
+
+# Ignore lines with timestamps of the form hh:mm, since the time changes between
+# runs. This regex is fairly broad and it may need to be narrowed.
+$(TESTS:=.diff): %.diff: %.out
+ diff -I "[0-9][0-9]:[0-9][0-9]" -u $(@:.diff=.ref) $(@:.diff=.out)
+
+clean:
+ rm -rf *.out
+
+# The reference copies should only be built at the start, or when the behaviour
+# of Asymptote is intentionally changed, so they are not usually removed by make
+# clean.
+veryclean: clean
+ rm -rf *.ref
+
+# This tells make to build every dependency from scratch, ignoring the dates on
+# files.
+.PHONY: $(TESTS:=.ref) $(TESTS:=.out) $(TESTS:=.diff) diff ref clean veryclean
diff --git a/Build/source/utils/asymptote/tests/output/circle.asy b/Build/source/utils/asymptote/tests/output/circle.asy
new file mode 100644
index 00000000000..e0300acdb8d
--- /dev/null
+++ b/Build/source/utils/asymptote/tests/output/circle.asy
@@ -0,0 +1 @@
+draw(unitcircle);
diff --git a/Build/source/utils/asymptote/tests/output/line.asy b/Build/source/utils/asymptote/tests/output/line.asy
new file mode 100644
index 00000000000..21acd4fc4e5
--- /dev/null
+++ b/Build/source/utils/asymptote/tests/output/line.asy
@@ -0,0 +1 @@
+draw((0,0)--(100,0));
diff --git a/Build/source/utils/asymptote/tests/string/erase.asy b/Build/source/utils/asymptote/tests/string/erase.asy
new file mode 100644
index 00000000000..2b38b61f359
--- /dev/null
+++ b/Build/source/utils/asymptote/tests/string/erase.asy
@@ -0,0 +1,9 @@
+import TestLib;
+StartTest("erase");
+string s = "abcdef";
+assert(erase(s,2,2) == "abef");
+assert(erase(s,-1,2) == "abcdef");
+assert(erase(s,7,1) == "abcdef");
+assert(erase(s,3,0) == "abcdef");
+assert(erase(s,5,2) == "abcde");
+EndTest();
diff --git a/Build/source/utils/asymptote/tests/string/find.asy b/Build/source/utils/asymptote/tests/string/find.asy
new file mode 100644
index 00000000000..cdf6dc6740f
--- /dev/null
+++ b/Build/source/utils/asymptote/tests/string/find.asy
@@ -0,0 +1,8 @@
+import TestLib;
+StartTest("find");
+string s = "abcdefab";
+assert(find(s,"cd") == 2);
+assert(find(s,"cd",3) == -1);
+assert(find(s,"ab") == 0);
+assert(find(s,"ab",1) == 6);
+EndTest();
diff --git a/Build/source/utils/asymptote/tests/string/insert.asy b/Build/source/utils/asymptote/tests/string/insert.asy
new file mode 100644
index 00000000000..2c11a2ef00f
--- /dev/null
+++ b/Build/source/utils/asymptote/tests/string/insert.asy
@@ -0,0 +1,5 @@
+import TestLib;
+StartTest("insert");
+string sub = insert("abef",2,"cd");
+assert(sub == "abcdef");
+EndTest();
diff --git a/Build/source/utils/asymptote/tests/string/length.asy b/Build/source/utils/asymptote/tests/string/length.asy
new file mode 100644
index 00000000000..dafb5d56b91
--- /dev/null
+++ b/Build/source/utils/asymptote/tests/string/length.asy
@@ -0,0 +1,6 @@
+import TestLib;
+StartTest("length");
+assert(length("") == 0);
+assert(length("abc") == 3);
+assert(length("abcdef") == 6);
+EndTest();
diff --git a/Build/source/utils/asymptote/tests/string/rfind.asy b/Build/source/utils/asymptote/tests/string/rfind.asy
new file mode 100644
index 00000000000..2291097a7ed
--- /dev/null
+++ b/Build/source/utils/asymptote/tests/string/rfind.asy
@@ -0,0 +1,8 @@
+import TestLib;
+StartTest("rfind");
+string s = "abcdefab";
+assert(rfind(s,"cd") == 2);
+assert(rfind(s,"cd",1) == -1);
+assert(rfind(s,"ab") == 6);
+assert(rfind(s,"ab",5) == 0);
+EndTest();
diff --git a/Build/source/utils/asymptote/tests/string/substr.asy b/Build/source/utils/asymptote/tests/string/substr.asy
new file mode 100644
index 00000000000..6426895aa39
--- /dev/null
+++ b/Build/source/utils/asymptote/tests/string/substr.asy
@@ -0,0 +1,6 @@
+import TestLib;
+StartTest("substr");
+string s = "abcdef";
+string sub = substr(s,2,2);
+assert(sub == "cd");
+EndTest();
diff --git a/Build/source/utils/asymptote/tests/types/cast.asy b/Build/source/utils/asymptote/tests/types/cast.asy
new file mode 100644
index 00000000000..b1191637554
--- /dev/null
+++ b/Build/source/utils/asymptote/tests/types/cast.asy
@@ -0,0 +1,13 @@
+import TestLib;
+StartTest("cast");
+struct A {
+ public int x;
+}
+A operator cast(int x) {
+ A a=new A;
+ a.x=x;
+ return a;
+}
+A a=7;
+assert(a.x==7);
+EndTest();
diff --git a/Build/source/utils/asymptote/tests/types/constructor.asy b/Build/source/utils/asymptote/tests/types/constructor.asy
new file mode 100644
index 00000000000..7dd13447cfd
--- /dev/null
+++ b/Build/source/utils/asymptote/tests/types/constructor.asy
@@ -0,0 +1,271 @@
+import TestLib;
+StartTest("constructor");
+
+{ // Basic usage. {{{1
+ struct Foo {
+ int x;
+ int y;
+
+ void operator init() {
+ x=2; y=3;
+ }
+
+ void operator init(int x, int y=2x) {
+ this.x=x; this.y=y;
+ }
+
+ void operator init(string s ... int[] vals) {
+ for (int i=0; i<vals.length; ++i)
+ x+=vals[i];
+ y=vals.length;
+ }
+
+ static {
+ {
+ Foo f=new Foo;
+ assert(f.x==0);
+ assert(f.y==0);
+ }
+ {
+ Foo f=Foo();
+ assert(f.x==2);
+ assert(f.y==3);
+ }
+ {
+ Foo f=Foo(7);
+ assert(f.x==7);
+ assert(f.y==14);
+ }
+ {
+ Foo f=Foo(5,40);
+ assert(f.x==5);
+ assert(f.y==40);
+ }
+ {
+ Foo f=Foo(y=5,x=40);
+ assert(f.x==40);
+ assert(f.y==5);
+ }
+ {
+ Foo f=Foo("hello", 1,2,3,4);
+ assert(f.x==10);
+ assert(f.y==4);
+ }
+ }
+ }
+
+ {
+ Foo f=new Foo;
+ assert(f.x==0);
+ assert(f.y==0);
+ }
+ {
+ Foo f=Foo();
+ assert(f.x==2);
+ assert(f.y==3);
+ }
+ {
+ Foo f=Foo(7);
+ assert(f.x==7);
+ assert(f.y==14);
+ }
+ {
+ Foo f=Foo(5,40);
+ assert(f.x==5);
+ assert(f.y==40);
+ }
+ {
+ Foo f=Foo(y=5,x=40);
+ assert(f.x==40);
+ assert(f.y==5);
+ }
+ {
+ Foo f=Foo("hello", 1,2,3,4);
+ assert(f.x==10);
+ assert(f.y==4);
+ }
+}
+
+{ // Assignment {{{1
+ struct Foo {
+ int x;
+
+ static int Foo() {
+ return 7;
+ }
+
+ static assert(Foo()==7);
+
+ void five() {
+ x=5;
+ }
+
+ void six(string s) {
+ x=6;
+ }
+
+ void operator init()=five;
+
+ void operator init(string s) {
+ assert(false);
+ }
+ operator init=six;
+
+ static {
+ assert(Foo().x==5);
+ assert(Foo("milk").x==6);
+ }
+
+ void operator init(int x) {
+ this.x=2x;
+ }
+
+ static Foo constructor(int)=Foo;
+
+ static {
+ assert(constructor(5).x==10);
+ }
+ }
+
+ assert(Foo().x==5);
+ assert(Foo("milk").x==6);
+ assert(Foo.constructor(5).x==10);
+}
+
+{ // Permission {{{1
+ int Foo() {
+ return 3;
+ }
+
+ struct Foo {
+ int x;
+
+ private void operator init() {
+ x=2;
+ }
+ }
+ // The implicit constructor should not be unravelled, as it is private.
+ assert(Foo()==3);
+}
+{ // Shadowing {{{1
+ struct Foo {
+ static Foo Foo() {
+ return null;
+ }
+
+ static assert(Foo()==null);
+
+ void operator init() {
+ }
+
+ static assert(Foo()!=null);
+ }
+
+ assert(Foo()!=null);
+
+ // Can't use Bar because of conflicts with the drawing command.
+ struct Barr {
+ void operator init() {
+ }
+
+ static assert(Barr()!=null);
+
+ static Barr Barr() {
+ return null;
+ }
+
+ static assert(Barr()==null);
+ }
+
+ assert(Barr()!=null);
+
+ struct Blah {
+ void operator init() {
+ }
+
+ static assert(Blah()!=null);
+
+ static Blah Blah() {
+ return null;
+ }
+
+ static assert(Blah()==null);
+ }
+ from Blah unravel Blah;
+
+ assert(Blah()==null);
+}
+
+{ // Static {{{1
+ struct Foo {
+ static int Foo() {
+ return 7;
+ }
+
+ static void operator init() {
+ }
+
+ static assert(Foo()==7);
+ }
+
+ struct Barr {
+ int x;
+
+ void operator init() {
+ x=77;
+ }
+
+ static assert(Barr().x==77);
+
+ static void operator init() {
+ assert(false);
+ }
+
+ static assert(Barr().x==77);
+ }
+
+ assert(Barr().x==77);
+}
+
+{ // Struct name shadowing. {{{1
+ struct Foo {
+ int x;
+ typedef int Foo;
+
+ void operator init() {
+ x=89;
+ }
+
+ static assert(Foo().x==89);
+ }
+
+ assert(Foo().x==89);
+
+ struct Barr {
+ int x;
+ struct Barr {
+ }
+
+ void operator init() {
+ x=89;
+ }
+
+ static assert(Barr().x==89);
+ }
+
+ assert(Barr().x==89);
+}
+
+// File-level {{{1
+// This assumes the file is named constructor.asy
+
+int constructor() {
+ return 44;
+}
+void operator init() {
+ assert(false);
+}
+assert(constructor()==44);
+
+EndTest(); // {{{1
+
diff --git a/Build/source/utils/asymptote/tests/types/ecast.asy b/Build/source/utils/asymptote/tests/types/ecast.asy
new file mode 100644
index 00000000000..d16d7bc4494
--- /dev/null
+++ b/Build/source/utils/asymptote/tests/types/ecast.asy
@@ -0,0 +1,11 @@
+import TestLib;
+StartTest("ecast");
+struct A {
+ public int x;
+}
+int operator ecast(A a) {
+ return a.x;
+}
+A a=new A; a.x=5;
+assert((int)a==5);
+EndTest();
diff --git a/Build/source/utils/asymptote/tests/types/guide.asy b/Build/source/utils/asymptote/tests/types/guide.asy
new file mode 100644
index 00000000000..77400fcfbbf
--- /dev/null
+++ b/Build/source/utils/asymptote/tests/types/guide.asy
@@ -0,0 +1,144 @@
+import TestLib;
+StartTest("guide");
+
+guide g;
+assert(size(g) == 0);
+assert(length(g) == -1);
+
+guide g=(0,0){curl 2}..(1,1){W}..tension 5 and 6 ..{N}(4,2)..{curl 3}(0,1);
+
+g=reverse(reverse(g));
+
+assert(size(g) == 4);
+assert(length(g) == 3);
+
+assert(size((path) g) == 4);
+assert(length((path) g) == 3);
+
+assert(size((guide) (path) g) == 4);
+assert(length((guide) (path) g) == 3);
+
+assert(close(point(g,-1),(0,0)));
+assert(close(point(g,0),(0,0)));
+assert(close(point(g,1),(1,1)));
+assert(close(point(g,3),(0,1)));
+assert(close(point(g,4),(0,1)));
+
+tensionSpecifier t=tensionSpecifier(g,1);
+assert(close(t.out,5));
+assert(close(t.in,6));
+assert(t.atLeast == false);
+
+pair[] z=dirSpecifier(g,0);
+assert(close(z[0],0));
+assert(close(z[1],0));
+
+pair[] z=dirSpecifier(g,1);
+assert(close(z[0],W));
+assert(close(z[1],N));
+
+real[] x=curlSpecifier(g,0);
+assert(close(x[0],2));
+assert(close(x[1],1));
+
+real[] x=curlSpecifier(g,length(g)-1);
+assert(close(x[0],1));
+assert(close(x[1],3));
+
+assert(!cyclic(g));
+assert(!cyclic((path) g));
+assert(!cyclic((guide) (path) g));
+
+guide g=(0,0)..controls (3,5)..(1,1){W}..tension atleast 5 and 6 ..{N}(4,2)..
+controls(1,2) and (2,4).. (0,1)..cycle;
+
+g=reverse(reverse(g));
+
+assert(size(g) == 4);
+assert(length(g) == 4);
+
+assert(size((path) g) == 4);
+assert(length((path) g) == 4);
+
+assert(size((guide) (path) g) == 4);
+assert(length((guide) (path) g) == 4);
+
+tensionSpecifier t=tensionSpecifier(g,1);
+assert(close(t.out,5));
+assert(close(t.in,6));
+assert(t.atLeast == true);
+
+pair[] z=controlSpecifier(g,0);
+assert(close(z[0],(3,5)));
+assert(close(z[1],(3,5)));
+
+pair[] z=controlSpecifier(g,2);
+assert(close(z[0],(1,2)));
+assert(close(z[1],(2,4)));
+
+real[] x=curlSpecifier(g,0);
+assert(close(x[0],1));
+assert(close(x[1],1));
+
+real[] x=curlSpecifier(g,length(g)-1);
+assert(close(x[0],1));
+assert(close(x[1],1));
+
+assert(cyclic(g));
+assert(cyclic((path) g));
+assert(cyclic((guide) (path) g));
+
+guide g=(0,0)..controls (3,5)..(1,1){W}..tension atleast 5 and 6 ..{N}(4,2)..
+cycle..controls(1,2) and (2,4)..(0,1)..cycle;
+
+assert(size(g) == 5);
+assert(length(g) == 5);
+
+assert(size((path) g) == 5);
+assert(length((path) g) == 5);
+
+assert(size((guide) (path) g) == 5);
+assert(length((guide) (path) g) == 5);
+
+pair[] z=dirSpecifier(g,0);
+assert(close(z[0],0));
+assert(close(z[1],0));
+
+pair[] z=dirSpecifier(g,1);
+assert(close(z[0],W));
+assert(close(z[1],N));
+
+tensionSpecifier t=tensionSpecifier(g,1);
+assert(close(t.out,5));
+assert(close(t.in,6));
+assert(t.atLeast == true);
+
+pair[] z=controlSpecifier(g,0);
+assert(close(z[0],(3,5)));
+assert(close(z[1],(3,5)));
+
+real[] x=curlSpecifier(g,0);
+assert(close(x[0],1));
+assert(close(x[1],1));
+
+real[] x=curlSpecifier(g,length(g)-1);
+assert(close(x[0],1));
+assert(close(x[1],1));
+
+assert(cyclic(g));
+assert(cyclic((path) g));
+assert(cyclic((guide) (path) g));
+
+guide g=(0,0)..controls (3,5) and (4,6)..cycle;
+
+g=reverse(g);
+
+assert(size(g) == 1);
+assert(length(g) == 1);
+
+pair[] z=controlSpecifier(g,0);
+assert(close(z[0],(4,6)));
+assert(close(z[1],(3,5)));
+
+EndTest();
+
diff --git a/Build/source/utils/asymptote/tests/types/init.asy b/Build/source/utils/asymptote/tests/types/init.asy
new file mode 100644
index 00000000000..5557bd0676c
--- /dev/null
+++ b/Build/source/utils/asymptote/tests/types/init.asy
@@ -0,0 +1,17 @@
+import TestLib;
+StartTest("init");
+int operator init() { return 7; }
+int x;
+assert(x==7);
+
+struct A {
+ int x=3;
+}
+A a;
+assert(a!=null);
+assert(a.x==3);
+
+A operator init() { return null; }
+A aa;
+assert(aa==null);
+EndTest();
diff --git a/Build/source/utils/asymptote/tests/types/resolve.asy b/Build/source/utils/asymptote/tests/types/resolve.asy
new file mode 100644
index 00000000000..e20962bbd21
--- /dev/null
+++ b/Build/source/utils/asymptote/tests/types/resolve.asy
@@ -0,0 +1,12 @@
+import TestLib;
+StartTest("resolve");
+struct A {} struct B {} struct C {}
+
+int f(B, real) { return 1; }
+int f(C, int) { return 2; }
+B operator cast(A) { return new B; }
+
+assert(f(new A, 3) == 1);
+C operator cast(A) { return new C; }
+assert(f(new A, 3) == 2);
+EndTest();
diff --git a/Build/source/utils/asymptote/tests/types/shadow.asy b/Build/source/utils/asymptote/tests/types/shadow.asy
new file mode 100644
index 00000000000..09d73abc020
--- /dev/null
+++ b/Build/source/utils/asymptote/tests/types/shadow.asy
@@ -0,0 +1,17 @@
+import TestLib;
+StartTest("shadow");
+int x = 1;
+int getX() { return x; }
+void setX(int value) { x=value; }
+
+// Shadow x with another int, but x should still be in memory.
+int x = 2;
+assert(x==2);
+assert(getX()==1);
+x = 4;
+assert(x==4);
+assert(getX()==1);
+setX(7);
+assert(x==4);
+assert(getX()==7);
+EndTest();
diff --git a/Build/source/utils/asymptote/tests/types/spec.asy b/Build/source/utils/asymptote/tests/types/spec.asy
new file mode 100644
index 00000000000..90936446404
--- /dev/null
+++ b/Build/source/utils/asymptote/tests/types/spec.asy
@@ -0,0 +1,61 @@
+import TestLib;
+StartTest("spec");
+
+// Test if the cycle keyword can be used in different contexts.
+{
+ int operator cast(cycleToken) {
+ return 55;
+ }
+ int x=cycle;
+ assert(x==55);
+}
+
+// Test the tensionSpecifier type.
+{
+ tensionSpecifier operator ..(string a, tensionSpecifier t, string b) {
+ return t;
+ }
+ tensionSpecifier t="hello" .. tension 2 .. "joe";
+ assert(t.out==2);
+ assert(t.in==2);
+ assert(t.atLeast==false);
+
+ tensionSpecifier t="hello" .. tension 3 and 2 .. "joe";
+ assert(t.out==3);
+ assert(t.in==2);
+ assert(t.atLeast==false);
+
+ tensionSpecifier t="hello" .. tension atleast 7 .. "joe";
+ assert(t.out==7);
+ assert(t.in==7);
+ assert(t.atLeast==true);
+
+ tensionSpecifier t="hello" .. tension atleast 3 and 2 .. "joe";
+ assert(t.out==3);
+ assert(t.in==2);
+ assert(t.atLeast==true);
+}
+
+// Test the curlSpecifier type.
+{
+ curlSpecifier operator ..(curlSpecifier spec, string b) {
+ return spec;
+ }
+ curlSpecifier operator ..(string a, curlSpecifier spec) {
+ return spec;
+ }
+ curlSpecifier operator ..(string a, curlSpecifier spec, string b) {
+ return spec;
+ }
+
+ curlSpecifier spec="hello"{curl 3}.."joe";
+ assert(spec.value==3);
+ assert(spec.side==JOIN_OUT);
+
+ curlSpecifier spec="hello"..{curl 7}"joe";
+ assert(spec.value==7);
+ assert(spec.side==JOIN_IN);
+}
+
+EndTest();
+
diff --git a/Build/source/utils/asymptote/texfile.cc b/Build/source/utils/asymptote/texfile.cc
new file mode 100644
index 00000000000..b8efab74dd0
--- /dev/null
+++ b/Build/source/utils/asymptote/texfile.cc
@@ -0,0 +1,266 @@
+/*****
+ * texfile.cc
+ * John Bowman 2003/03/14
+ *
+ * Encapsulates the writing of commands to a TeX file.
+ *****/
+
+#include <ctime>
+#include <cfloat>
+
+#include "texfile.h"
+#include "errormsg.h"
+
+using std::ofstream;
+using settings::getSetting;
+
+
+namespace camp {
+
+texfile::texfile(const string& texname, const bbox& box, bool pipe)
+ : box(box)
+{
+ texengine=getSetting<string>("tex");
+ inlinetex=getSetting<bool>("inlinetex");
+ Hoffset=inlinetex ? box.right : box.left;
+ out=new ofstream(texname.c_str());
+ if(!out || !*out)
+ reportError("Cannot write to "+texname);
+ out->setf(std::ios::fixed);
+ out->precision(6);
+ texdocumentclass(*out,pipe);
+ resetpen();
+}
+
+texfile::~texfile()
+{
+ if(out) {
+ delete out;
+ out=NULL;
+ }
+}
+
+void texfile::miniprologue()
+{
+ texpreamble(*out,processData().TeXpreamble,false,true);
+ *out << "\\pagestyle{empty}" << newl;
+ *out << "\\begin{document}" << newl;
+ texfontencoding(*out);
+}
+
+void texfile::prologue()
+{
+ if(inlinetex) {
+ string prename=auxname(getSetting<string>("outname"),"pre");
+ std::ifstream exists(prename.c_str());
+ std::ofstream *outpreamble=
+ new std::ofstream(prename.c_str(),std::ios::app);
+ bool ASYdefines=!exists;
+ texpreamble(*outpreamble,processData().TeXpreamble,ASYdefines,ASYdefines);
+ outpreamble->close();
+ }
+
+ texdefines(*out,processData().TeXpreamble,false);
+ double width=box.right-box.left;
+ double height=box.top-box.bottom;
+ if(settings::pdf(texengine) && !inlinetex) {
+ double voffset=0.0;
+ if(settings::latex(texengine)) {
+ if(height < 12.0) voffset=height-12.0;
+ } else if(height < 10.0) voffset=height-10.0;
+
+ // Work around an apparent xelatex dimension bug
+ double xelatexBug=ps2tex;
+
+ if(width > 0)
+ *out << "\\pdfpagewidth=" << width << "bp" << newl;
+ *out << "\\ifx\\pdfhorigin\\undefined" << newl
+ << "\\hoffset=-1in" << newl
+ << "\\voffset=" << voffset-72.0*xelatexBug << "bp" << newl;
+ if(height > 0)
+ *out << "\\pdfpageheight=" << height*0.5*(1.0+xelatexBug) << "bp"
+ << newl;
+ *out << "\\else" << newl
+ << "\\pdfhorigin=0bp" << newl
+ << "\\pdfvorigin=" << voffset << "bp" << newl;
+ if(height > 0)
+ *out << "\\pdfpageheight=" << height << "bp" << newl;
+ *out << "\\fi" << endl;
+ }
+ if(settings::latex(texengine)) {
+ *out << "\\setlength{\\unitlength}{1pt}" << newl;
+ if(!inlinetex) {
+ *out << "\\pagestyle{empty}" << newl
+ << "\\textheight=" << height+18.0 << "bp" << newl
+ << "\\textwidth=" << width+18.0 << "bp" << newl;
+ if(settings::pdf(texengine))
+ *out << "\\oddsidemargin=-17.61pt" << newl
+ << "\\evensidemargin=\\oddsidemargin" << newl
+ << "\\topmargin=-37.01pt" << newl;
+ *out << "\\begin{document}" << newl;
+ }
+ } else {
+ if(!inlinetex) {
+ *out << "\\footline={}" << newl;
+ if(settings::pdf(texengine)) {
+ *out << "\\hoffset=-20pt" << newl
+ << "\\voffset=0pt" << newl;
+ } else {
+ *out << "\\hoffset=36.6pt" << newl
+ << "\\voffset=54.0pt" << newl;
+ }
+ }
+ }
+}
+
+void texfile::beginlayer(const string& psname, bool postscript)
+{
+ const char *units=settings::texunits(texengine);
+ if(box.right > box.left && box.top > box.bottom) {
+ if(postscript) {
+ *out << "\\includegraphics";
+ if(!settings::pdf(texengine))
+ *out << "[bb=" << box.left << " " << box.bottom << " "
+ << box.right << " " << box.top << "]";
+ *out << "{" << psname << "}%" << newl;
+ if(!inlinetex)
+ *out << "\\kern -" << (box.right-box.left)*ps2tex << units
+ << "%" << newl;
+ } else {
+ *out << "\\leavevmode\\vbox to " << (box.top-box.bottom)*ps2tex
+ << units << "{}%" << newl;
+ if(inlinetex)
+ *out << "\\kern " << (box.right-box.left)*ps2tex << units
+ << "%" << newl;
+ }
+ }
+}
+
+void texfile::endlayer()
+{
+ if(inlinetex && (box.right > box.left && box.top > box.bottom))
+ *out << "\\kern -" << (box.right-box.left)*ps2tex
+ << settings::texunits(texengine) << "%" << newl;
+}
+
+void texfile::writeshifted(path p, bool newPath)
+{
+ write(p.transformed(shift(pair(-Hoffset,-box.bottom))),newPath);
+}
+
+void texfile::setlatexcolor(pen p)
+{
+ if(p.cmyk() && (!lastpen.cmyk() ||
+ (p.cyan() != lastpen.cyan() ||
+ p.magenta() != lastpen.magenta() ||
+ p.yellow() != lastpen.yellow() ||
+ p.black() != lastpen.black()))) {
+ *out << "\\definecolor{ASYcolor}{cmyk}{"
+ << p.cyan() << "," << p.magenta() << "," << p.yellow() << ","
+ << p.black() << "}\\color{ASYcolor}" << newl;
+ } else if(p.rgb() && (!lastpen.rgb() ||
+ (p.red() != lastpen.red() ||
+ p.green() != lastpen.green() ||
+ p.blue() != lastpen.blue()))) {
+ *out << "\\definecolor{ASYcolor}{rgb}{"
+ << p.red() << "," << p.green() << "," << p.blue()
+ << "}\\color{ASYcolor}" << newl;
+ } else if(p.grayscale() && (!lastpen.grayscale() ||
+ p.gray() != lastpen.gray())) {
+ *out << "\\definecolor{ASYcolor}{gray}{"
+ << p.gray()
+ << "}\\color{ASYcolor}" << newl;
+ }
+}
+
+void texfile::setfont(pen p)
+{
+ bool latex=settings::latex(texengine);
+
+ if(latex) setlatexfont(*out,p,lastpen);
+ settexfont(*out,p,lastpen,latex);
+
+ lastpen=p;
+}
+
+void texfile::setpen(pen p)
+{
+ bool latex=settings::latex(texengine);
+
+ p.convert();
+ if(p == lastpen) return;
+
+ if(latex) setlatexcolor(p);
+ else setcolor(p,settings::beginspecial(texengine),settings::endspecial());
+
+ setfont(p);
+}
+
+void texfile::gsave()
+{
+ *out << settings::beginspecial(texengine);
+ psfile::gsave(true);
+ *out << settings::endspecial() << newl;
+}
+
+void texfile::grestore()
+{
+ *out << settings::beginspecial(texengine);
+ psfile::grestore(true);
+ *out << settings::endspecial() << newl;
+}
+
+void texfile::beginspecial()
+{
+ *out << settings::beginspecial(texengine);
+}
+
+void texfile::endspecial()
+{
+ *out << settings::endspecial() << newl;
+}
+
+void texfile::beginraw()
+{
+ *out << "\\ASYraw{" << newl;
+}
+
+void texfile::endraw()
+{
+ *out << "}%" << newl;
+}
+
+void texfile::put(const string& label, const transform& T, const pair& z,
+ const pair& align)
+{
+ double sign=settings::pdf(texengine) ? 1.0 : -1.0;
+
+ if(label.empty()) return;
+
+ bool trans=!T.isIdentity();
+
+ *out << "\\ASYalign";
+ if(trans) *out << "T";
+ *out << "(" << (z.getx()-Hoffset)*ps2tex
+ << "," << (z.gety()-box.bottom)*ps2tex
+ << ")(" << align.getx()
+ << "," << align.gety()
+ << ")";
+ if(trans)
+ *out << "{" << T.getxx() << " " << sign*T.getyx()
+ << " " << sign*T.getxy() << " " << T.getyy() << "}";
+ *out << "{" << label << "}" << newl;
+}
+
+void texfile::epilogue(bool pipe)
+{
+ if(settings::latex(texengine)) {
+ if(!inlinetex || pipe)
+ *out << "\\end{document}" << newl;
+ } else {
+ *out << "\\bye" << newl;
+ }
+ out->flush();
+}
+
+} //namespace camp
diff --git a/Build/source/utils/asymptote/texfile.h b/Build/source/utils/asymptote/texfile.h
new file mode 100644
index 00000000000..e594ab4b7e6
--- /dev/null
+++ b/Build/source/utils/asymptote/texfile.h
@@ -0,0 +1,199 @@
+/*****
+ * texfile.h
+ * John Bowman 2003/03/14
+ *
+ * Encapsulates the writing of commands to a TeX file.
+ *****/
+
+#ifndef TEXFILE_H
+#define TEXFILE_H
+
+#include <fstream>
+#include <iomanip>
+#include <iostream>
+
+#include "common.h"
+#include "pair.h"
+#include "bbox.h"
+#include "pen.h"
+#include "util.h"
+#include "interact.h"
+#include "path.h"
+#include "array.h"
+#include "psfile.h"
+#include "settings.h"
+#include "process.h"
+
+namespace camp {
+
+const double tex2ps=72.0/72.27;
+const double ps2tex=1.0/tex2ps;
+
+template<class T>
+void texdocumentclass(T& out, bool pipe=false)
+{
+ if(settings::latex(settings::getSetting<string>("tex")) &&
+ (pipe || !settings::getSetting<bool>("inlinetex")))
+ out << "\\documentclass[12pt]{article}" << newl;
+}
+
+template<class T>
+void texuserpreamble(T& out,
+ mem::list<string>& preamble=processData().TeXpreamble)
+{
+ for(mem::list<string>::iterator p=preamble.begin();
+ p != preamble.end(); ++p)
+ out << stripblanklines(*p);
+}
+
+template<class T>
+void texfontencoding(T& out)
+{
+ if(settings::latex(settings::getSetting<string>("tex"))) {
+ out << "\\makeatletter%" << newl
+ << "\\let\\ASYencoding\\f@encoding%" << newl
+ << "\\let\\ASYfamily\\f@family%" << newl
+ << "\\let\\ASYseries\\f@series%" << newl
+ << "\\let\\ASYshape\\f@shape%" << newl
+ << "\\makeatother%" << newl;
+ }
+}
+
+template<class T>
+void texpreamble(T& out, mem::list<string>& preamble=processData().TeXpreamble,
+ bool ASYalign=true, bool ASYbase=true)
+{
+ texuserpreamble(out,preamble);
+ string texengine=settings::getSetting<string>("tex");
+ if(ASYbase)
+ out << "\\newbox\\ASYbox" << newl
+ << "\\newdimen\\ASYdimen" << newl
+ << "\\long\\def\\ASYbase#1#2{\\leavevmode\\setbox\\ASYbox=\\hbox{#1}"
+ << "\\ASYdimen=\\ht\\ASYbox%" << newl
+ << "\\setbox\\ASYbox=\\hbox{#2}\\lower\\ASYdimen\\box\\ASYbox}" << newl;
+ if(ASYalign)
+ out << "\\long\\def\\ASYaligned(#1,#2)(#3,#4)#5#6#7{\\leavevmode%" << newl
+ << "\\setbox\\ASYbox=\\hbox{#7}%" << newl
+ << "\\setbox\\ASYbox\\hbox{\\ASYdimen=\\ht\\ASYbox%" << newl
+ << "\\advance\\ASYdimen by\\dp\\ASYbox\\kern#3\\wd\\ASYbox"
+ << "\\raise#4\\ASYdimen\\box\\ASYbox}%" << newl
+ << "\\put(#1,#2){#5\\wd\\ASYbox 0pt\\dp\\ASYbox 0pt\\ht\\ASYbox 0pt"
+ << "\\box\\ASYbox#6}}" << newl
+ << "\\long\\def\\ASYalignT(#1,#2)(#3,#4)#5#6{%" << newl
+ << "\\ASYaligned(#1,#2)(#3,#4){%" << newl
+ << settings::beginlabel(texengine) << "%" << newl
+ << "}{%" << newl
+ << settings::endlabel(texengine) << "%" << newl
+ << "}{#6}}" << newl
+ << "\\long\\def\\ASYalign(#1,#2)(#3,#4)#5{"
+ << "\\ASYaligned(#1,#2)(#3,#4){}{}{#5}}" << newl
+ << settings::rawpostscript(texengine) << newl;
+}
+
+template<class T>
+void texdefines(T& out, mem::list<string>& preamble=processData().TeXpreamble,
+ bool pipe=false)
+{
+ if(pipe || !settings::getSetting<bool>("inlinetex"))
+ texpreamble(out,preamble,!pipe);
+
+ if(pipe) {
+ // Make tex pipe aware of a previously generated aux file.
+ string name=auxname(settings::outname(),"aux");
+ std::ifstream fin(name.c_str());
+ if(fin) {
+ std::ofstream fout("texput.aux");
+ string s;
+ while(getline(fin,s))
+ fout << s << endl;
+ }
+ }
+ texfontencoding(out);
+ if(settings::latex(settings::getSetting<string>("tex"))) {
+ if(pipe || !settings::getSetting<bool>("inlinetex")) {
+ out << "\\usepackage{graphicx}" << newl;
+ if(!pipe) out << "\\usepackage{color}" << newl;
+ }
+ if(pipe)
+ out << "\\begin{document}" << newl;
+ } else {
+ out << "\\input graphicx" << newl;
+ if(!pipe)
+ out << "\\input picture" << newl;
+ }
+}
+
+template<class T>
+bool setlatexfont(T& out, const pen& p, const pen& lastpen)
+{
+ if(p.size() != lastpen.size() || p.Lineskip() != lastpen.Lineskip()) {
+ out << "\\fontsize{" << p.size() << "}{" << p.Lineskip()
+ << "}\\selectfont\n";
+ return true;
+ }
+ return false;
+}
+
+template<class T>
+bool settexfont(T& out, const pen& p, const pen& lastpen, bool latex)
+{
+ string font=p.Font();
+ if(font != lastpen.Font() || (!latex && p.size() != lastpen.size())) {
+ out << font << "%" << newl;
+ return true;
+ }
+ return false;
+}
+
+class texfile : public psfile {
+ bbox box;
+ bool inlinetex;
+ double Hoffset;
+
+public:
+ string texengine;
+
+ texfile(const string& texname, const bbox& box, bool pipe=false);
+ ~texfile();
+
+ void prologue();
+
+ void epilogue(bool pipe=false);
+
+ void setlatexcolor(pen p);
+ void setpen(pen p);
+
+ void setfont(pen p);
+
+ void gsave();
+
+ void grestore();
+
+ void beginspecial();
+
+ void endspecial();
+
+ void beginraw();
+
+ void endraw();
+
+ void writepair(pair z) {
+ *out << z;
+ }
+
+ void miniprologue();
+
+ void writeshifted(path p, bool newPath=true);
+ double hoffset() {return Hoffset;}
+
+ // Draws label transformed by T at position z.
+ void put(const string& label, const transform& T, const pair& z,
+ const pair& Align);
+
+ void beginlayer(const string& psname, bool postscript);
+ void endlayer();
+};
+
+} //namespace camp
+
+#endif
diff --git a/Build/source/utils/asymptote/tr.cc b/Build/source/utils/asymptote/tr.cc
new file mode 100644
index 00000000000..77097ef6680
--- /dev/null
+++ b/Build/source/utils/asymptote/tr.cc
@@ -0,0 +1,496 @@
+/* This file is released under version 2 of the GNU Library General Public
+ * License (see the files LICENSE.LIBRARY and LICENSE).
+ */
+
+/* $Id: tr.c,v 1.9 1998/01/29 16:56:54 brianp Exp $ */
+
+/*
+ * $Log: tr.c,v $
+ * Revision 1.9 1998/01/29 16:56:54 brianp
+ * allow trOrtho() and trFrustum() to be called at any time, minor clean-up
+ *
+ * Revision 1.8 1998/01/28 19:47:39 brianp
+ * minor clean-up for C++
+ *
+ * Revision 1.7 1997/07/21 17:34:38 brianp
+ * added tile borders
+ *
+ * Revision 1.6 1997/07/21 15:47:35 brianp
+ * renamed all "near" and "far" variables
+ *
+ * Revision 1.5 1997/04/26 21:23:25 brianp
+ * added trRasterPos3f function
+ *
+ * Revision 1.4 1997/04/26 19:59:36 brianp
+ * set CurrentTile to -1 before first tile and after last tile
+ *
+ * Revision 1.3 1997/04/22 23:51:15 brianp
+ * added WIN32 header stuff, removed tabs
+ *
+ * Revision 1.2 1997/04/19 23:26:10 brianp
+ * many API changes
+ *
+ * Revision 1.1 1997/04/18 21:53:05 brianp
+ * Initial revision
+ *
+ */
+
+
+/*
+ * Tiled Rendering library
+ * Version 1.1
+ * Copyright (C) Brian Paul
+ */
+
+#include "common.h"
+
+#ifdef HAVE_LIBGL
+
+#include <assert.h>
+#include <math.h>
+#include <stdlib.h>
+#include <stdio.h>
+#ifdef WIN32
+#include <windows.h>
+#endif
+#ifdef __APPLE__
+#include <OpenGL/gl.h>
+#include <OpenGL/glu.h>
+#else
+#include <GL/gl.h>
+#include <GL/glu.h>
+#endif
+#include "tr.h"
+
+
+#define DEFAULT_TILE_WIDTH 256
+#define DEFAULT_TILE_HEIGHT 256
+#define DEFAULT_TILE_BORDER 0
+
+
+struct _TRctx {
+ /* Final image parameters */
+ GLint ImageWidth, ImageHeight;
+ GLenum ImageFormat, ImageType;
+ GLvoid *ImageBuffer;
+
+ /* Tile parameters */
+ GLint TileWidth, TileHeight;
+ GLint TileWidthNB, TileHeightNB;
+ GLint TileBorder;
+ GLenum TileFormat, TileType;
+ GLvoid *TileBuffer;
+
+ /* Projection parameters */
+ GLboolean Perspective;
+ GLdouble Left;
+ GLdouble Right;
+ GLdouble Bottom;
+ GLdouble Top;
+ GLdouble Near;
+ GLdouble Far;
+
+ /* Misc */
+ TRenum RowOrder;
+ GLint Rows, Columns;
+ GLint CurrentTile;
+ GLint CurrentTileWidth, CurrentTileHeight;
+ GLint CurrentRow, CurrentColumn;
+
+ GLint ViewportSave[4];
+};
+
+
+
+/*
+ * Misc setup including computing number of tiles (rows and columns).
+ */
+static void Setup(TRcontext *tr)
+{
+ if (!tr)
+ return;
+
+ tr->Columns = (tr->ImageWidth + tr->TileWidthNB - 1) / tr->TileWidthNB;
+ tr->Rows = (tr->ImageHeight + tr->TileHeightNB - 1) / tr->TileHeightNB;
+ tr->CurrentTile = 0;
+
+ assert(tr->Columns >= 0);
+ assert(tr->Rows >= 0);
+}
+
+
+
+TRcontext *trNew(void)
+{
+ TRcontext *tr = (TRcontext *) calloc(1, sizeof(TRcontext));
+ if (tr) {
+ tr->TileWidth = DEFAULT_TILE_WIDTH;
+ tr->TileHeight = DEFAULT_TILE_HEIGHT;
+ tr->TileBorder = DEFAULT_TILE_BORDER;
+ tr->RowOrder = TR_BOTTOM_TO_TOP;
+ tr->CurrentTile = -1;
+ }
+ return (TRcontext *) tr;
+}
+
+
+void trDelete(TRcontext *tr)
+{
+ if (tr)
+ free(tr);
+}
+
+
+
+void trTileSize(TRcontext *tr, GLint width, GLint height, GLint border)
+{
+ if (!tr)
+ return;
+
+ assert(border >= 0);
+ assert(width >= 1);
+ assert(height >= 1);
+ assert(width >= 2*border);
+ assert(height >= 2*border);
+
+ tr->TileBorder = border;
+ tr->TileWidth = width;
+ tr->TileHeight = height;
+ tr->TileWidthNB = width - 2 * border;
+ tr->TileHeightNB = height - 2 * border;
+ Setup(tr);
+}
+
+
+
+void trTileBuffer(TRcontext *tr, GLenum format, GLenum type, GLvoid *image)
+{
+ if (!tr)
+ return;
+
+ tr->TileFormat = format;
+ tr->TileType = type;
+ tr->TileBuffer = image;
+}
+
+
+
+void trImageSize(TRcontext *tr, GLint width, GLint height)
+{
+ if (!tr)
+ return;
+
+ tr->ImageWidth = width;
+ tr->ImageHeight = height;
+ Setup(tr);
+}
+
+
+void trImageBuffer(TRcontext *tr, GLenum format, GLenum type, GLvoid *image)
+{
+ if (!tr)
+ return;
+
+ tr->ImageFormat = format;
+ tr->ImageType = type;
+ tr->ImageBuffer = image;
+}
+
+
+GLint trGet(TRcontext *tr, TRenum param)
+{
+ if (!tr)
+ return 0;
+
+ switch (param) {
+ case TR_TILE_WIDTH:
+ return tr->TileWidth;
+ case TR_TILE_HEIGHT:
+ return tr->TileHeight;
+ case TR_TILE_BORDER:
+ return tr->TileBorder;
+ case TR_IMAGE_WIDTH:
+ return tr->ImageWidth;
+ case TR_IMAGE_HEIGHT:
+ return tr->ImageHeight;
+ case TR_ROWS:
+ return tr->Rows;
+ case TR_COLUMNS:
+ return tr->Columns;
+ case TR_CURRENT_ROW:
+ if (tr->CurrentTile<0)
+ return -1;
+ else
+ return tr->CurrentRow;
+ case TR_CURRENT_COLUMN:
+ if (tr->CurrentTile<0)
+ return -1;
+ else
+ return tr->CurrentColumn;
+ case TR_CURRENT_TILE_WIDTH:
+ return tr->CurrentTileWidth;
+ case TR_CURRENT_TILE_HEIGHT:
+ return tr->CurrentTileHeight;
+ case TR_ROW_ORDER:
+ return (GLint) tr->RowOrder;
+ default:
+ return 0;
+ }
+}
+
+
+void trRowOrder(TRcontext *tr, TRenum order)
+{
+ if (!tr)
+ return;
+
+ if (order==TR_TOP_TO_BOTTOM || order==TR_BOTTOM_TO_TOP)
+ tr->RowOrder = order;
+}
+
+
+void trOrtho(TRcontext *tr,
+ GLdouble left, GLdouble right,
+ GLdouble bottom, GLdouble top,
+ GLdouble zNear, GLdouble zFar)
+{
+ if (!tr)
+ return;
+
+ tr->Perspective = GL_FALSE;
+ tr->Left = left;
+ tr->Right = right;
+ tr->Bottom = bottom;
+ tr->Top = top;
+ tr->Near = zNear;
+ tr->Far = zFar;
+}
+
+
+void trFrustum(TRcontext *tr,
+ GLdouble left, GLdouble right,
+ GLdouble bottom, GLdouble top,
+ GLdouble zNear, GLdouble zFar)
+{
+ if (!tr)
+ return;
+
+ tr->Perspective = GL_TRUE;
+ tr->Left = left;
+ tr->Right = right;
+ tr->Bottom = bottom;
+ tr->Top = top;
+ tr->Near = zNear;
+ tr->Far = zFar;
+}
+
+
+void trPerspective(TRcontext *tr,
+ GLdouble fovy, GLdouble aspect,
+ GLdouble zNear, GLdouble zFar )
+{
+ GLdouble xmin, xmax, ymin, ymax;
+ ymax = zNear * tan(fovy * 3.14159265 / 360.0);
+ ymin = -ymax;
+ xmin = ymin * aspect;
+ xmax = ymax * aspect;
+ trFrustum(tr, xmin, xmax, ymin, ymax, zNear, zFar);
+}
+
+
+void trBeginTile(TRcontext *tr)
+{
+ GLint matrixMode;
+ GLint tileWidth, tileHeight, border;
+ GLdouble left, right, bottom, top;
+
+ if (!tr)
+ return;
+
+ if (tr->CurrentTile <= 0) {
+ Setup(tr);
+ /* Save user's viewport, will be restored after last tile rendered */
+ glGetIntegerv(GL_VIEWPORT, tr->ViewportSave);
+ }
+
+ /* which tile (by row and column) we're about to render */
+ if (tr->RowOrder==TR_BOTTOM_TO_TOP) {
+ tr->CurrentRow = tr->CurrentTile / tr->Columns;
+ tr->CurrentColumn = tr->CurrentTile % tr->Columns;
+ }
+ else if (tr->RowOrder==TR_TOP_TO_BOTTOM) {
+ tr->CurrentRow = tr->Rows - (tr->CurrentTile / tr->Columns) - 1;
+ tr->CurrentColumn = tr->CurrentTile % tr->Columns;
+ }
+ else {
+ /* This should never happen */
+ abort();
+ }
+ assert(tr->CurrentRow < tr->Rows);
+ assert(tr->CurrentColumn < tr->Columns);
+
+ border = tr->TileBorder;
+
+ /* Compute actual size of this tile with border */
+ if (tr->CurrentRow < tr->Rows-1)
+ tileHeight = tr->TileHeight;
+ else
+ tileHeight = tr->ImageHeight - (tr->Rows-1) * (tr->TileHeightNB) + 2 * border;
+
+ if (tr->CurrentColumn < tr->Columns-1)
+ tileWidth = tr->TileWidth;
+ else
+ tileWidth = tr->ImageWidth - (tr->Columns-1) * (tr->TileWidthNB) + 2 * border;
+
+ /* Save tile size, with border */
+ tr->CurrentTileWidth = tileWidth;
+ tr->CurrentTileHeight = tileHeight;
+
+ glViewport(0, 0, tileWidth, tileHeight); /* tile size including border */
+
+ /* save current matrix mode */
+ glGetIntegerv(GL_MATRIX_MODE, &matrixMode);
+ glMatrixMode(GL_PROJECTION);
+ glLoadIdentity();
+
+ /* compute projection parameters */
+ left = tr->Left + (tr->Right - tr->Left)
+ * (tr->CurrentColumn * tr->TileWidthNB - border) / tr->ImageWidth;
+ right = left + (tr->Right - tr->Left) * tileWidth / tr->ImageWidth;
+ bottom = tr->Bottom + (tr->Top - tr->Bottom)
+ * (tr->CurrentRow * tr->TileHeightNB - border) / tr->ImageHeight;
+ top = bottom + (tr->Top - tr->Bottom) * tileHeight / tr->ImageHeight;
+
+ if (tr->Perspective)
+ glFrustum(left, right, bottom, top, tr->Near, tr->Far);
+ else
+ glOrtho(left, right, bottom, top, tr->Near, tr->Far);
+
+ /* restore user's matrix mode */
+ glMatrixMode(matrixMode);
+}
+
+
+
+int trEndTile(TRcontext *tr)
+{
+ GLint prevRowLength, prevSkipRows, prevSkipPixels;
+
+ if (!tr)
+ return 0;
+
+ assert(tr->CurrentTile>=0);
+
+ /* be sure OpenGL rendering is finished */
+ glFlush();
+
+ /* save current glPixelStore values */
+ glGetIntegerv(GL_PACK_ROW_LENGTH, &prevRowLength);
+ glGetIntegerv(GL_PACK_SKIP_ROWS, &prevSkipRows);
+ glGetIntegerv(GL_PACK_SKIP_PIXELS, &prevSkipPixels);
+ /*glGetIntegerv(GL_PACK_ALIGNMENT, &prevAlignment);*/
+
+ if (tr->TileBuffer) {
+ GLint srcX = tr->TileBorder;
+ GLint srcY = tr->TileBorder;
+ GLint srcWidth = tr->TileWidthNB;
+ GLint srcHeight = tr->TileHeightNB;
+ glReadPixels(srcX, srcY, srcWidth, srcHeight,
+ tr->TileFormat, tr->TileType, tr->TileBuffer);
+ }
+
+ if (tr->ImageBuffer) {
+ GLint srcX = tr->TileBorder;
+ GLint srcY = tr->TileBorder;
+ GLint srcWidth = tr->CurrentTileWidth - 2 * tr->TileBorder;
+ GLint srcHeight = tr->CurrentTileHeight - 2 * tr->TileBorder;
+ GLint destX = tr->TileWidthNB * tr->CurrentColumn;
+ GLint destY = tr->TileHeightNB * tr->CurrentRow;
+
+ /* setup pixel store for glReadPixels */
+ glPixelStorei(GL_PACK_ROW_LENGTH, tr->ImageWidth);
+ glPixelStorei(GL_PACK_SKIP_ROWS, destY);
+ glPixelStorei(GL_PACK_SKIP_PIXELS, destX);
+ /*glPixelStorei(GL_PACK_ALIGNMENT, 1);*/
+
+ /* read the tile into the final image */
+ glReadPixels(srcX, srcY, srcWidth, srcHeight,
+ tr->ImageFormat, tr->ImageType, tr->ImageBuffer);
+ }
+
+ /* restore previous glPixelStore values */
+ glPixelStorei(GL_PACK_ROW_LENGTH, prevRowLength);
+ glPixelStorei(GL_PACK_SKIP_ROWS, prevSkipRows);
+ glPixelStorei(GL_PACK_SKIP_PIXELS, prevSkipPixels);
+ /*glPixelStorei(GL_PACK_ALIGNMENT, prevAlignment);*/
+
+ /* increment tile counter, return 1 if more tiles left to render */
+ tr->CurrentTile++;
+ if (tr->CurrentTile >= tr->Rows * tr->Columns) {
+ /* restore user's viewport */
+ glViewport(tr->ViewportSave[0], tr->ViewportSave[1],
+ tr->ViewportSave[2], tr->ViewportSave[3]);
+ tr->CurrentTile = -1; /* all done */
+ return 0;
+ }
+ else
+ return 1;
+}
+
+
+/*
+ * Replacement for glRastePos3f() which avoids the problem with invalid
+ * raster pos.
+ */
+void trRasterPos3f(TRcontext *tr, GLfloat x, GLfloat y, GLfloat z)
+{
+ if (tr->CurrentTile<0) {
+ /* not doing tile rendering right now. Let OpenGL do this. */
+ glRasterPos3f(x, y, z);
+ }
+ else {
+ GLdouble modelview[16], proj[16];
+ GLint viewport[4];
+ GLdouble winX, winY, winZ;
+
+ /* Get modelview, projection and viewport */
+ glGetDoublev(GL_MODELVIEW_MATRIX, modelview);
+ glGetDoublev(GL_PROJECTION_MATRIX, proj);
+ viewport[0] = 0;
+ viewport[1] = 0;
+ viewport[2] = tr->CurrentTileWidth;
+ viewport[3] = tr->CurrentTileHeight;
+
+ /* Project object coord to window coordinate */
+ if (gluProject(x, y, z, modelview, proj, viewport, &winX, &winY, &winZ)){
+
+ /* set raster pos to window coord (0,0) */
+ glMatrixMode(GL_MODELVIEW);
+ glPushMatrix();
+ glLoadIdentity();
+ glMatrixMode(GL_PROJECTION);
+ glPushMatrix();
+ glLoadIdentity();
+ glOrtho(0.0, tr->CurrentTileWidth,
+ 0.0, tr->CurrentTileHeight, 0.0, 1.0);
+ glRasterPos3f(0.0, 0.0, -winZ);
+
+ /* Now use empty bitmap to adjust raster position to (winX,winY) */
+ {
+ GLubyte bitmap[1] = {0};
+ glBitmap(1, 1, 0.0, 0.0, winX, winY, bitmap);
+ }
+
+ /* restore original matrices */
+ glPopMatrix(); /*proj*/
+ glMatrixMode(GL_MODELVIEW);
+ glPopMatrix();
+ }
+#ifdef DEBUG
+ if (glGetError())
+ printf("GL error!\n");
+#endif
+ }
+}
+
+#endif
diff --git a/Build/source/utils/asymptote/tr.h b/Build/source/utils/asymptote/tr.h
new file mode 100644
index 00000000000..72d1bef0e05
--- /dev/null
+++ b/Build/source/utils/asymptote/tr.h
@@ -0,0 +1,167 @@
+/* This file is released under version 2 of the GNU Library General Public
+ * License (see the files LICENSE.LIBRARY and LICENSE).
+ */
+
+/* $Id: tr.h,v 1.5 1997/07/21 17:34:07 brianp Exp $ */
+
+/*
+ * $Log: tr.h,v $
+ * Revision 1.5 1997/07/21 17:34:07 brianp
+ * added tile borders, incremented version to 1.1
+ *
+ * Revision 1.4 1997/07/21 15:47:35 brianp
+ * renamed all "near" and "far" variables
+ *
+ * Revision 1.3 1997/04/26 21:23:25 brianp
+ * added trRasterPos3f function
+ *
+ * Revision 1.2 1997/04/19 23:26:10 brianp
+ * many API changes
+ *
+ * Revision 1.1 1997/04/18 21:53:05 brianp
+ * Initial revision
+ *
+ */
+
+
+/*
+ * Tiled Rendering library
+ * Version 1.1
+ * Copyright (C) Brian Paul
+ *
+ *
+ * This library allows one to render arbitrarily large images with OpenGL.
+ * The basic idea is to break the image into tiles which are rendered one
+ * at a time. The tiles are assembled together to form the final, large
+ * image. Tiles and images can be of any size.
+ *
+ * Basic usage:
+ *
+ * 1. Allocate a tile rendering context:
+ * TRcontext t = trNew();
+ *
+ * 2. Specify the final image buffer and tile size:
+ * GLubyte image[W][H][4]
+ * trImageSize(t, W, H);
+ * trImageBuffer(t, GL_RGBA, GL_UNSIGNED_BYTE, (GLubyte *) image);
+ *
+ * 3. Setup your projection:
+ * trFrustum(t, left, right, bottom top, near, far);
+ * or
+ * trOrtho(t, left, right, bottom top, near, far);
+ * or
+ * trPerspective(t, fovy, aspect, near, far);
+ *
+ * 4. Render the tiles:
+ * do {
+ * trBeginTile(t);
+ * DrawMyScene();
+ * } while (trEndTile(t));
+ *
+ * You provide the DrawMyScene() function which calls glClear() and
+ * draws all your stuff.
+ *
+ * 5. The image array is now complete. Display it, write it to a file, etc.
+ *
+ * 6. Delete the tile rendering context when finished:
+ * trDelete(t);
+ *
+ */
+
+
+#ifndef TR_H
+#define TR_H
+
+
+#ifdef __APPLE__
+#include <OpenGL/gl.h>
+#else
+#include <GL/gl.h>
+#endif
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+#define TR_VERSION "1.1"
+#define TR_MAJOR_VERSION 1
+#define TR_MINOR_VERSION 1
+
+
+typedef struct _TRctx TRcontext;
+
+
+typedef enum {
+ TR_TILE_WIDTH = 100,
+ TR_TILE_HEIGHT,
+ TR_TILE_BORDER,
+ TR_IMAGE_WIDTH,
+ TR_IMAGE_HEIGHT,
+ TR_ROWS,
+ TR_COLUMNS,
+ TR_CURRENT_ROW,
+ TR_CURRENT_COLUMN,
+ TR_CURRENT_TILE_WIDTH,
+ TR_CURRENT_TILE_HEIGHT,
+ TR_ROW_ORDER,
+ TR_TOP_TO_BOTTOM,
+ TR_BOTTOM_TO_TOP
+} TRenum;
+
+
+
+extern TRcontext *trNew(void);
+
+extern void trDelete(TRcontext *tr);
+
+
+extern void trTileSize(TRcontext *tr, GLint width, GLint height, GLint border);
+
+extern void trTileBuffer(TRcontext *tr, GLenum format, GLenum type,
+ GLvoid *image);
+
+
+extern void trImageSize(TRcontext *tr, GLint width, GLint height);
+
+extern void trImageBuffer(TRcontext *tr, GLenum format, GLenum type,
+ GLvoid *image);
+
+
+extern void trRowOrder(TRcontext *tr, TRenum order);
+
+
+extern GLint trGet(TRcontext *tr, TRenum param);
+
+
+extern void trOrtho(TRcontext *tr,
+ GLdouble left, GLdouble right,
+ GLdouble bottom, GLdouble top,
+ GLdouble zNear, GLdouble zFar);
+
+extern void trFrustum(TRcontext *tr,
+ GLdouble left, GLdouble right,
+ GLdouble bottom, GLdouble top,
+ GLdouble zNear, GLdouble zFar);
+
+extern void trPerspective(TRcontext *tr,
+ GLdouble fovy, GLdouble aspect,
+ GLdouble zNear, GLdouble zFar );
+
+
+extern void trBeginTile(TRcontext *tr);
+
+extern int trEndTile(TRcontext *tr);
+
+
+extern void trRasterPos3f(TRcontext *tr, GLfloat x, GLfloat y, GLfloat z);
+
+
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif
diff --git a/Build/source/utils/asymptote/transform.h b/Build/source/utils/asymptote/transform.h
new file mode 100644
index 00000000000..3d60dfd8069
--- /dev/null
+++ b/Build/source/utils/asymptote/transform.h
@@ -0,0 +1,243 @@
+/*****
+ * transform.h
+ * Andy Hammerlindl 2002/05/22
+ *
+ * The transform datatype stores an affine transformation on the plane
+ * The datamembers are x, y, xx, xy, yx, and yy. A pair (x,y) is
+ * transformed as
+ * x' = t.x + t.xx * x + t.xy * y
+ * y' = t.y + t.yx * x + t.yy * y
+ *****/
+
+#ifndef TRANSFORM_H
+#define TRANSFORM_H
+
+#include <iostream>
+
+#include "pair.h"
+
+namespace camp {
+
+class transform : public gc {
+ double x;
+ double y;
+ double xx;
+ double xy;
+ double yx;
+ double yy;
+
+public:
+ transform()
+ : x(0.0), y(0.0), xx(1.0), xy(0.0), yx(0.0), yy(1.0) {}
+
+ virtual ~transform() {}
+
+ transform(double x, double y,
+ double xx, double xy,
+ double yx, double yy)
+ : x(x), y(y), xx(xx), xy(xy), yx(yx), yy(yy) {}
+
+ double getx() const { return x; }
+ double gety() const { return y; }
+ double getxx() const { return xx; }
+ double getxy() const { return xy; }
+ double getyx() const { return yx; }
+ double getyy() const { return yy; }
+
+ friend transform operator+ (const transform& t, const transform& s)
+ {
+ return transform(t.x + s.x, t.y + s.y,
+ t.xx + s.xx, t.xy + s.xy,
+ t.yx + s.yx, t.yy + s.yy);
+ }
+
+ friend transform operator- (const transform& t, const transform& s)
+ {
+ return transform(t.x - s.x, t.y - s.y,
+ t.xx - s.xx, t.xy - s.xy,
+ t.yx - s.yx, t.yy - s.yy);
+ }
+
+ friend transform operator- (const transform& t)
+ {
+ return transform(-t.x, -t.y,
+ -t.xx, -t.xy,
+ -t.yx, -t.yy);
+ }
+
+ friend pair operator* (const transform& t, const pair& z)
+ {
+ double x = z.getx(), y = z.gety();
+ return pair(t.x + t.xx * x + t.xy * y, t.y + t.yx * x + t.yy * y);
+ }
+
+ // Calculates the composition of t and s, so for a pair, z,
+ // t * (s * z) == (t * s) * z
+ // Can be thought of as matrix multiplication.
+ friend transform operator* (const transform& t, const transform& s)
+ {
+ return transform(t.x + t.xx * s.x + t.xy * s.y,
+ t.y + t.yx * s.x + t.yy * s.y,
+ t.xx * s.xx + t.xy * s.yx,
+ t.xx * s.xy + t.xy * s.yy,
+ t.yx * s.xx + t.yy * s.yx,
+ t.yx * s.xy + t.yy * s.yy);
+ }
+
+ friend bool operator== (const transform& t1, const transform& t2)
+ {
+ return t1.x == t2.x && t1.y == t2.y &&
+ t1.xx == t2.xx && t1.xy == t2.xy &&
+ t1.yx == t2.yx && t1.yy == t2.yy;
+ }
+
+ friend bool operator!= (const transform& t1, const transform& t2)
+ {
+ return !(t1 == t2);
+ }
+
+ bool isIdentity() const
+ {
+ return x == 0.0 && y == 0.0 &&
+ xx == 1.0 && xy == 0.0 && yx == 0.0 && yy == 1.0;
+ }
+
+ bool isNull() const
+ {
+ return x == 0.0 && y == 0.0 &&
+ xx == 0.0 && xy == 0.0 && yx == 0.0 && yy == 0.0;
+ }
+
+ // Calculates the determinant, as if it were a matrix.
+ friend double det(const transform& t)
+ {
+ return t.xx * t.yy - t.xy * t.yx;
+ }
+
+ // Tells if the transformation is invertible (bijective).
+ bool invertible() const
+ {
+ return det(*this) != 0.0;
+ }
+
+ friend transform inverse(const transform& t)
+ {
+ double d = det(t);
+ if (d == 0.0)
+ reportError("inverting singular transform");
+
+ d=1.0/d;
+ return transform((t.xy * t.y - t.yy * t.x)*d,
+ (t.yx * t.x - t.xx * t.y)*d,
+ t.yy*d, -t.xy*d, -t.yx*d, t.xx*d);
+ }
+
+ friend ostream& operator<< (ostream& out, const transform& t)
+ {
+ return out << "(" << t.x << ","
+ << t.y << ","
+ << t.xx << ","
+ << t.xy << ","
+ << t.yx << ","
+ << t.yy << ")";
+ }
+};
+
+// The common transforms
+static const transform identity;
+
+inline transform shift(pair z)
+{
+ return transform (z.getx(), z.gety(), 1.0, 0.0, 0.0, 1.0);
+}
+
+inline transform xscale(double s)
+{
+ return transform (0.0, 0.0, s, 0.0, 0.0, 1.0);
+}
+
+inline transform yscale(double s)
+{
+ return transform (0.0, 0.0, 1.0, 0.0, 0.0, s);
+}
+
+inline transform scale(double s)
+{
+ return transform (0.0, 0.0, s, 0.0, 0.0, s);
+}
+
+inline transform scale(pair z)
+{
+ // Equivalent to multiplication by z.
+ double x = z.getx(), y = z.gety();
+ return transform (0.0, 0.0, x, -y, y, x);
+}
+
+inline transform slant(double s)
+{
+ return transform (0.0, 0.0, 1.0, s, 0.0, 1.0);
+}
+
+inline transform rotate(double theta)
+{
+ double s = sin(theta), c = cos(theta);
+ return transform (0.0, 0.0, c, -s, s, c);
+}
+
+// return rotate(angle(v)) if z != (0,0); otherwise return identity.
+inline transform rotate(pair z)
+{
+ double d=z.length();
+ if(d == 0.0) return identity;
+ d=1.0/d;
+ return transform (0.0, 0.0, d*z.getx(), -d*z.gety(), d*z.gety(), d*z.getx());
+}
+
+inline transform rotatearound(pair z, double theta)
+{
+ // Notice the operators are applied from right to left.
+ // Could be optimized.
+ return shift(z) * rotate(theta) * shift(-z);
+}
+
+inline transform reflectabout(pair z, pair w)
+{
+ if (z == w)
+ reportError("points determining line to reflect about must be distinct");
+
+ // Also could be optimized.
+ transform basis = shift(z) * scale(w-z);
+ transform flip = yscale(-1.0);
+
+ return basis * flip * inverse(basis);
+}
+
+// Remove the x and y components, so the new transform maps zero to zero.
+inline transform shiftless(transform t)
+{
+ return transform(0, 0, t.getxx(), t.getxy(), t.getyx(), t.getyy());
+}
+
+// Return the translational component of t.
+inline transform shift(transform t)
+{
+ return transform(t.getx(), t.gety(), 1.0, 0, 0, 1.0);
+}
+
+// Return the translational component of t.
+inline pair shiftpair(transform t)
+{
+ return (t.getx(), t.gety());
+}
+
+inline transform matrix(pair lb, pair rt)
+{
+ pair size=rt-lb;
+ return transform(lb.getx(),lb.gety(),size.getx(),0,0,size.gety());
+}
+
+} //namespace camp
+
+GC_DECLARE_PTRFREE(camp::transform);
+
+#endif
diff --git a/Build/source/utils/asymptote/triple.h b/Build/source/utils/asymptote/triple.h
new file mode 100644
index 00000000000..e1ea5a41e4d
--- /dev/null
+++ b/Build/source/utils/asymptote/triple.h
@@ -0,0 +1,185 @@
+/*****
+ * triple.h
+ * John Bowman
+ *
+ * Stores a three-dimensional point.
+ *
+ *****/
+
+#ifndef TRIPLE_H
+#define TRIPLE_H
+
+#include <cassert>
+#include <iostream>
+#include <cmath>
+
+#include "common.h"
+#include "angle.h"
+
+namespace camp {
+
+typedef double Triple[3];
+
+class triple : virtual public gc {
+ double x;
+ double y;
+ double z;
+
+public:
+ triple() : x(0.0), y(0.0), z(0.0) {}
+ triple(double x, double y=0.0, double z=0.0) : x(x), y(y), z(z) {}
+ triple(const Triple& v) : x(v[0]), y(v[1]), z(v[2]) {}
+
+ virtual ~triple() {}
+
+ double getx() const { return x; }
+ double gety() const { return y; }
+ double getz() const { return z; }
+
+ friend triple operator+ (const triple& z, const triple& w)
+ {
+ return triple(z.x + w.x, z.y + w.y, z.z + w.z);
+ }
+
+ friend triple operator- (const triple& z, const triple& w)
+ {
+ return triple(z.x - w.x, z.y - w.y, z.z - w.z);
+ }
+
+ friend triple operator- (const triple& z)
+ {
+ return triple(-z.x, -z.y, -z.z);
+ }
+
+ friend triple operator* (double s, const triple& z)
+ {
+ return triple(s*z.x, s*z.y, s*z.z);
+ }
+
+ friend triple operator* (const triple& z, double s)
+ {
+ return triple(z.x*s, z.y*s, z.z*s);
+ }
+
+ friend triple operator/ (const triple& z, double s)
+ {
+ if (s == 0.0)
+ reportError("division by 0");
+ s=1.0/s;
+ return triple(z.x*s, z.y*s, z.z*s);
+ }
+
+ const triple& operator+= (const triple& w)
+ {
+ x += w.x;
+ y += w.y;
+ z += w.z;
+ return *this;
+ }
+
+ const triple& operator-= (const triple& w)
+ {
+ x -= w.x;
+ y -= w.y;
+ z -= w.z;
+ return *this;
+ }
+
+ friend bool operator== (const triple& z, const triple& w)
+ {
+ return z.x == w.x && z.y == w.y && z.z == w.z;
+ }
+
+ friend bool operator!= (const triple& z, const triple& w)
+ {
+ return z.x != w.x || z.y != w.y || z.z != w.z;
+ }
+
+ double abs2() const
+ {
+ return x*x+y*y+z*z;
+ }
+
+ double length() const /* r */
+ {
+ return sqrt(abs2());
+ }
+
+ friend double length(const triple& v)
+ {
+ return v.length();
+ }
+
+ double polar() const /* theta */
+ {
+ double r=length();
+ if (r == 0.0)
+ reportError("taking polar angle of (0,0,0)");
+ return acos(z/r);
+ }
+
+ double azimuth() const /* phi */
+ {
+ return angle(x,y);
+ }
+
+ friend triple unit(const triple& v)
+ {
+ double scale=v.length();
+ if(scale != 0.0) scale=1.0/scale;
+ return triple(v.x*scale,v.y*scale,v.z*scale);
+ }
+
+ friend double dot(const triple& u, const triple& v)
+ {
+ return u.getx()*v.getx()+u.gety()*v.gety()+u.getz()*v.getz();
+ }
+
+ friend triple cross(const triple& u, const triple& v)
+ {
+ return triple(u.gety()*v.getz()-u.getz()*v.gety(),
+ u.getz()*v.getx()-u.getx()*v.getz(),
+ u.getx()*v.gety()-v.getx()*u.gety());
+ }
+
+ // Returns a unit triple in the direction (theta,phi), in radians.
+ friend triple expi(double theta, double phi)
+ {
+ double sintheta=sin(theta);
+ return triple(sintheta*cos(phi),sintheta*sin(phi),cos(theta));
+ }
+
+ friend istream& operator >> (istream& s, triple& z)
+ {
+ char c;
+ s >> std::ws;
+ bool paren=s.peek() == '('; // parenthesis are optional
+ if(paren) s >> c;
+ s >> z.x >> std::ws;
+ if(s.peek() == ',') s >> c >> z.y;
+ else z.y=0.0;
+ if(s.peek() == ',') s >> c >> z.z;
+ else z.z=0.0;
+ if(paren) {
+ s >> std::ws;
+ if(s.peek() == ')') s >> c;
+ }
+
+ return s;
+ }
+
+ friend ostream& operator << (ostream& out, const triple& z)
+ {
+ out << "(" << z.x << "," << z.y << "," << z.z << ")";
+ return out;
+ }
+
+};
+
+triple expi(double theta, double phi);
+
+} //namespace camp
+
+GC_DECLARE_PTRFREE(camp::triple);
+
+#endif
diff --git a/Build/source/utils/asymptote/types.cc b/Build/source/utils/asymptote/types.cc
new file mode 100644
index 00000000000..4b288938d79
--- /dev/null
+++ b/Build/source/utils/asymptote/types.cc
@@ -0,0 +1,525 @@
+/*****
+ * types.cc
+ * Andy Hammerlindl 2002/06/24
+ *
+ * Used by the compiler as a way to keep track of the type of a variable
+ * or expression.
+ *****/
+
+#include <cstdio>
+#include <algorithm>
+
+#include "entry.h"
+#include "types.h"
+#include "runtime.h"
+#include "access.h"
+
+namespace types {
+
+/* Base types */
+#define PRIMITIVE(name,Name,asyName) \
+ primitiveTy p##Name(ty_##name); \
+ ty *prim##Name() { return &p##Name; }
+#define PRIMERROR
+#include <primitives.h>
+#undef PRIMERROR
+#undef PRIMITIVE
+
+nullTy pNull;
+ty *primNull() { return &pNull; }
+
+array boolArray_(primBoolean());
+ty *boolArray() { return &boolArray_; }
+array IntArray_(primInt());
+ty *IntArray() { return &IntArray_; }
+array realArray_(primReal());
+ty *realArray() { return &realArray_; }
+array pairArray_(primPair());
+ty *pairArray() { return &pairArray_; }
+array tripleArray_(primTriple());
+ty *tripleArray() { return &tripleArray_; }
+array stringArray_(primString());
+ty *stringArray() { return &stringArray_; }
+array transformArray_(primTransform());
+ty *transformArray() { return &transformArray_; }
+array pathArray_(primPath());
+ty *pathArray() { return &pathArray_; }
+array penArray_(primPen());
+ty *penArray() { return &penArray_; }
+array guideArray_(primGuide());
+ty *guideArray() { return &guideArray_; }
+
+array boolArray2_(boolArray());
+ty *boolArray2() { return &boolArray2_; }
+array IntArray2_(IntArray());
+ty *IntArray2() { return &IntArray2_; }
+array realArray2_(realArray());
+ty *realArray2() { return &realArray2_; }
+array pairArray2_(pairArray());
+ty *pairArray2() { return &pairArray2_; }
+array tripleArray2_(tripleArray());
+ty *tripleArray2() { return &tripleArray2_; }
+array stringArray2_(stringArray());
+ty *stringArray2() { return &stringArray2_; }
+array pathArray2_(pathArray());
+ty *pathArray2() { return &pathArray2_; }
+array penArray2_(penArray());
+ty *penArray2() { return &penArray2_; }
+
+array boolArray3_(boolArray2());
+ty *boolArray3() { return &boolArray3_; }
+array IntArray3_(IntArray2());
+ty *IntArray3() { return &IntArray3_; }
+array realArray3_(realArray2());
+ty *realArray3() { return &realArray3_; }
+array pairArray3_(pairArray2());
+ty *pairArray3() { return &pairArray3_; }
+array tripleArray3_(tripleArray2());
+ty *tripleArray3() { return &tripleArray3_; }
+array stringArray3_(stringArray2());
+ty *stringArray3() { return &stringArray3_; }
+
+const char *names[] = {
+ "null",
+ "<structure>", "<function>", "<overloaded>",
+
+#define PRIMITIVE(name,Name,asyName) #asyName,
+#define PRIMERROR
+#include <primitives.h>
+#undef PRIMERROR
+#undef PRIMITIVE
+
+ "<array>"
+};
+
+ty::~ty()
+{}
+
+void ty::print(ostream& out) const
+{
+ out << names[kind];
+}
+
+trans::varEntry *primitiveTy::virtualField(symbol *id, signature *sig)
+{
+#define FIELD(Type, name, func) \
+ if (sig == 0 && id == symbol::trans(name)) { \
+ static trans::bltinAccess a(run::func); \
+ static trans::varEntry v(prim##Type(), &a, 0, position()); \
+ return &v; \
+ }
+
+ switch (kind) {
+ case ty_pair:
+ FIELD(Real,"x",pairXPart);
+ FIELD(Real,"y",pairYPart);
+ break;
+ case ty_triple:
+ FIELD(Real,"x",tripleXPart);
+ FIELD(Real,"y",tripleYPart);
+ FIELD(Real,"z",tripleZPart);
+ break;
+ case ty_transform:
+ FIELD(Real,"x",transformXPart);
+ FIELD(Real,"y",transformYPart);
+ FIELD(Real,"xx",transformXXPart);
+ FIELD(Real,"xy",transformXYPart);
+ FIELD(Real,"yx",transformYXPart);
+ FIELD(Real,"yy",transformYYPart);
+ break;
+ case ty_tensionSpecifier:
+ FIELD(Real,"out",tensionSpecifierOutPart);
+ FIELD(Real,"in",tensionSpecifierInPart);
+ FIELD(Boolean,"atLeast",tensionSpecifierAtleastPart);
+ break;
+ case ty_curlSpecifier:
+ FIELD(Real,"value",curlSpecifierValuePart);
+ FIELD(Int,"side",curlSpecifierSidePart);
+ break;
+ default:
+ break;
+ }
+ return 0;
+
+#undef FIELD
+}
+
+ty *ty::virtualFieldGetType(symbol *id)
+{
+ trans::varEntry *v = virtualField(id, 0);
+ return v ? v->getType() : 0;
+}
+
+trans::access *nullTy::castTo(ty *target, caster &) {
+ switch (target->kind) {
+ case ty_array: {
+ static trans::bltinAccess a(run::pushNullArray);
+ return &a;
+ }
+ case ty_record: {
+ static trans::bltinAccess a(run::pushNullRecord);
+ return &a;
+ }
+ case ty_function: {
+ static trans::bltinAccess a(run::pushNullFunction);
+ return &a;
+ }
+ default:
+ return 0;
+ }
+}
+
+trans::access *array::initializer()
+{
+ static trans::bltinAccess a(run::emptyArray);
+ return &a;
+}
+
+ty *array::pushType()
+{
+ if (pushtype == 0)
+ pushtype = new function(celltype,formal(celltype,"x"));
+
+ return pushtype;
+}
+
+ty *array::popType()
+{
+ if (poptype == 0)
+ poptype = new function(celltype);
+
+ return poptype;
+}
+
+ty *array::appendType()
+{
+ if (appendtype == 0)
+ appendtype = new function(primVoid(),formal(this,"a"));
+
+ return appendtype;
+}
+
+ty *array::insertType()
+{
+ if (inserttype == 0) {
+ function *f=new function(primVoid(),formal(primInt(),"i"));
+ f->addRest(this);
+ inserttype = f;
+ }
+
+ return inserttype;
+}
+
+ty *array::deleteType()
+{
+ if (deletetype == 0)
+ deletetype = new function(primVoid(),formal(primInt(),"i",true),
+ formal(primInt(),"j",true));
+
+ return deletetype;
+}
+
+ty *cyclicType() {
+ return new function(primVoid(),formal(primBoolean(),"b"));
+}
+
+ty *initializedType() {
+ return new function(primBoolean(),formal(primInt(),"i"));
+}
+
+ty *array::virtualFieldGetType(symbol *id)
+{
+ return
+ id == symbol::trans("cyclic") ? cyclicType() :
+ id == symbol::trans("push") ? pushType() :
+ id == symbol::trans("pop") ? popType() :
+ id == symbol::trans("append") ? appendType() :
+ id == symbol::trans("insert") ? insertType() :
+ id == symbol::trans("delete") ? deleteType() :
+ id == symbol::trans("initialized") ? initializedType() :
+ ty::virtualFieldGetType(id);
+}
+
+trans::varEntry *array::virtualField(symbol *id, signature *sig)
+{
+ if (sig == 0 && id == symbol::trans("length"))
+ {
+ static trans::bltinAccess a(run::arrayLength);
+ static trans::varEntry v(primInt(), &a, 0, position());
+ return &v;
+ }
+ if (sig == 0 && id == symbol::trans("keys"))
+ {
+ static trans::bltinAccess a(run::arrayKeys);
+ static trans::varEntry v(IntArray(), &a, 0, position());
+ return &v;
+ }
+ if (sig == 0 && id == symbol::trans("cyclicflag"))
+ {
+ static trans::bltinAccess a(run::arrayCyclicFlag);
+ static trans::varEntry v(primBoolean(), &a, 0, position());
+ return &v;
+ }
+ if (id == symbol::trans("cyclic") &&
+ equivalent(sig, cyclicType()->getSignature()))
+ {
+ static trans::bltinAccess a(run::arrayCyclic);
+ static trans::varEntry v(cyclicType(), &a, 0, position());
+ return &v;
+ }
+ if (id == symbol::trans("initialized") &&
+ equivalent(sig, initializedType()->getSignature()))
+ {
+ static trans::bltinAccess a(run::arrayInitialized);
+ static trans::varEntry v(initializedType(), &a, 0, position());
+ return &v;
+ }
+ if (id == symbol::trans("push") &&
+ equivalent(sig, pushType()->getSignature()))
+ {
+ static trans::bltinAccess a(run::arrayPush);
+ // v needs to be dynamic, as the push type differs among arrays.
+ trans::varEntry *v = new trans::varEntry(pushType(), &a, 0, position());
+
+ return v;
+ }
+ if (id == symbol::trans("pop") &&
+ equivalent(sig, popType()->getSignature()))
+ {
+ static trans::bltinAccess a(run::arrayPop);
+ // v needs to be dynamic, as the pop type differs among arrays.
+ trans::varEntry *v = new trans::varEntry(popType(), &a, 0, position());
+
+ return v;
+ }
+ if (id == symbol::trans("append") &&
+ equivalent(sig, appendType()->getSignature()))
+ {
+ static trans::bltinAccess a(run::arrayAppend);
+ // v needs to be dynamic, as the append type differs among arrays.
+ trans::varEntry *v = new trans::varEntry(appendType(), &a, 0, position());
+
+ return v;
+ }
+ if (id == symbol::trans("insert") &&
+ equivalent(sig, insertType()->getSignature()))
+ {
+ static trans::bltinAccess a(run::arrayInsert);
+ // v needs to be dynamic, as the insert type differs among arrays.
+ trans::varEntry *v = new trans::varEntry(insertType(), &a, 0, position());
+
+ return v;
+ }
+ if (id == symbol::trans("delete") &&
+ equivalent(sig, deleteType()->getSignature()))
+ {
+ static trans::bltinAccess a(run::arrayDelete);
+ // v needs to be dynamic, as the delete type differs among arrays.
+ trans::varEntry *v = new trans::varEntry(deleteType(), &a, 0, position());
+
+ return v;
+ }
+ else
+ return ty::virtualField(id, sig);
+}
+
+ostream& operator<< (ostream& out, const formal& f)
+{
+ if (f.Explicit)
+ out << "explicit ";
+ if (f.name)
+ f.t->printVar(out,f.name);
+ else
+ f.t->print(out);
+ if (f.defval)
+ out << "=<default>";
+ return out;
+}
+
+bool equivalent(formal& f1, formal& f2) {
+ // Just test the types.
+ // This will also return true for the rest parameter if both types are null.
+ // NOTE: Is this the right behavior?
+ return equivalent(f1.t,f2.t);
+}
+
+bool argumentEquivalent(formal &f1, formal& f2) {
+ if (f1.name == f2.name) {
+ if (f1.t == 0)
+ return f2.t == 0;
+ else if (f2.t == 0)
+ return false;
+
+ return f1.t->kind != ty_overloaded &&
+ f2.t->kind != ty_overloaded &&
+ equivalent(f1.t, f2.t);
+ }
+ else
+ return false;
+}
+
+ostream& operator<< (ostream& out, const signature& s)
+{
+ if (s.isOpen) {
+ out << "(<open>)";
+ return out;
+ }
+
+ out << "(";
+
+ formal_vector::const_iterator f = s.formals.begin();
+ if (f != s.formals.end()) {
+ out << *f;
+ ++f;
+ }
+ for (; f != s.formals.end(); ++f)
+ out << ", " << *f;
+
+ if (s.rest.t) {
+ if (!s.formals.empty())
+ out << " ";
+ out << "... " << s.rest;
+ }
+
+ out << ")";
+
+ return out;
+}
+
+
+// Equivalence by design does not look at the presence of default values.
+bool equivalent(signature *s1, signature *s2)
+{
+ // Handle null signature
+ if (s1 == 0)
+ return s2 == 0;
+ else if (s2 == 0)
+ return false;
+
+ // Two open signatures are always equivalent, as the formals are ignored.
+ if (s1->isOpen)
+ return s2->isOpen;
+ else if (s2->isOpen)
+ return false;
+
+ if (s1->formals.size() != s2->formals.size())
+ return false;
+
+ return std::equal(s1->formals.begin(),s1->formals.end(),s2->formals.begin(),
+ (bool (*)(formal&,formal&)) equivalent) &&
+ equivalent(s1->rest, s2->rest);
+}
+
+bool argumentEquivalent(signature *s1, signature *s2)
+{
+ // Handle null signature
+ if (s1 == 0)
+ return s2 == 0;
+ else if (s2 == 0)
+ return false;
+
+ if (s1->formals.size() != s2->formals.size())
+ return false;
+
+ return std::equal(s1->formals.begin(),s1->formals.end(),s2->formals.begin(),
+ (bool (*)(formal&,formal&)) argumentEquivalent) &&
+ argumentEquivalent(s1->rest, s2->rest);
+}
+
+size_t signature::hash() {
+ size_t x=2038;
+ for (formal_vector::iterator i=formals.begin(); i!=formals.end(); ++i)
+ x=x*0xFAEC+i->t->hash();
+
+ if (rest.t)
+ x=x*0xACED +rest.t->hash();
+
+ return x;
+}
+
+trans::access *function::initializer() {
+ static trans::bltinAccess a(run::pushNullFunction);
+ return &a;
+}
+
+#if 0
+ty *function::stripDefaults()
+{
+ function *f = new function(result);
+
+ Int n = sig.getNumFormals();
+ for (Int i = 0; i < n; ++i)
+ f->add(sig.getFormal(i), 0);
+
+ return f;
+}
+#endif
+
+// Only add a type with a signature distinct from the ones currently
+// in the overloaded type.
+void overloaded::addDistinct(ty *t, bool special)
+{
+ if (t->kind == ty_overloaded) {
+ overloaded *ot = (overloaded *)t;
+ for (ty_vector::iterator st = ot->sub.begin();
+ st != ot->sub.end();
+ ++st)
+ {
+ this->addDistinct(*st, special);
+ }
+ }
+ else {
+ for (ty_vector::iterator st = this->sub.begin();
+ st != this->sub.end();
+ ++st)
+ {
+ if (equivalent(t, *st, special))
+ return;
+ }
+
+ // Nonequivalent in signature - add it.
+ this->add(t);
+ }
+}
+
+
+ty *overloaded::signatureless()
+{
+ for(ty_vector::iterator t = sub.begin(); t != sub.end(); ++t)
+ if ((*t)->getSignature()==0)
+ return *t;
+
+ return 0;
+}
+
+bool overloaded::castable(ty *target, caster &c)
+{
+ for(ty_vector::iterator s = sub.begin(); s != sub.end(); ++s)
+ if (c.castable(target,*s))
+ return true;
+ return false;
+}
+
+bool equivalent(ty *t1, ty *t2)
+{
+ // The same pointer must point to the same type.
+ if (t1 == t2)
+ return true;
+
+ // Handle empty types (used in equating empty rest parameters).
+ if (t1 == 0 || t2 == 0)
+ return false;
+
+ // Ensure if an overloaded type is compared to a non-overloaded one, that the
+ // overloaded type's method is called.
+ if (t1->kind == ty_overloaded || t2->kind != ty_overloaded)
+ return t1->equiv(t2);
+ return t2->equiv(t1);
+}
+
+bool equivalent(ty *t1, ty *t2, bool special) {
+ return special ? equivalent(t1, t2) :
+ equivalent(t1->getSignature(), t2->getSignature());
+}
+
+} // namespace types
diff --git a/Build/source/utils/asymptote/types.h b/Build/source/utils/asymptote/types.h
new file mode 100644
index 00000000000..4b51c0d56e8
--- /dev/null
+++ b/Build/source/utils/asymptote/types.h
@@ -0,0 +1,606 @@
+/*****
+ * types.h
+ * Andy Hammerlindl 2002/06/20
+ *
+ * Used by the compiler as a way to keep track of the type of a variable
+ * or expression.
+ *
+ *****/
+
+#ifndef TYPES_H
+#define TYPES_H
+
+#include <iostream>
+#include <cstdio>
+#include <cassert>
+
+#include "errormsg.h"
+#include "symbol.h"
+#include "common.h"
+#include "util.h"
+
+using std::ostream;
+
+using sym::symbol;
+
+// Forward declaration.
+namespace trans {
+class access;
+class varEntry;
+}
+namespace absyntax {
+class varinit;
+extern varinit *Default;
+}
+
+namespace types {
+
+enum ty_kind {
+ ty_null,
+ ty_record, // "struct" in Asymptote language
+ ty_function,
+ ty_overloaded,
+
+#define PRIMITIVE(name,Name,asyName) ty_##name,
+#define PRIMERROR
+#include <primitives.h>
+#undef PRIMERROR
+#undef PRIMITIVE
+
+ ty_array
+};
+
+// Forward declarations.
+class ty;
+struct signature;
+
+// Checks if two types are equal in the sense of the language.
+// That is primitive types are equal if they are the same kind.
+// Structures are equal if they come from the same struct definition.
+// Arrays are equal if their cell types are equal.
+bool equivalent(ty *t1, ty *t2);
+
+// If special is true, this is the same as above. If special is false, just the
+// signatures are compared.
+bool equivalent(ty *t1, ty *t2, bool special);
+
+class caster {
+public:
+ virtual ~caster() {}
+ virtual trans::access *operator() (ty *target, ty *source) = 0;
+ virtual bool castable(ty *target, ty *source) = 0;
+};
+
+class ty : public gc {
+public:
+ const ty_kind kind;
+ ty(ty_kind kind)
+ : kind(kind) {}
+ virtual ~ty();
+
+ virtual void print (ostream& out) const;
+ virtual void printVar (ostream& out, symbol *name) const {
+ print(out);
+ out << " " << *name;
+ }
+
+
+ // Returns true if the type is a user-defined type or the null type.
+ // While the pair, path, etc. are stored by reference, this is
+ // transparent to the user.
+ virtual bool isReference() {
+ return true;
+ }
+
+ virtual signature *getSignature() {
+ return 0;
+ }
+
+ virtual bool primitive() {
+ return false;
+ }
+
+ // If a default initializer is not stored in the environment, the abstract
+ // syntax asks the type if it has a "default" default initializer, by calling
+ // this method.
+ virtual trans::access *initializer() {
+ return 0;
+ }
+
+ // If a cast function is not stored in the environment, ask the type itself.
+ // This handles null->record casting, and the like. The caster is used as a
+ // callback to the environment for casts of subtypes.
+ virtual trans::access *castTo(ty *, caster &) {
+ return 0;
+ }
+
+ // Just checks if a cast is possible.
+ virtual bool castable(ty *target, caster &c) {
+ return castTo(target, c);
+ }
+
+ // For pair's x and y, and array's length, this is a special type of
+ // "field".
+ // In actually, it returns a function which takes the object as its
+ // parameter and returns the necessary result.
+ // These should not have public permission, as modifying them would
+ // have strange results.
+ virtual trans::varEntry *virtualField(symbol *, signature *) {
+ return 0;
+ }
+
+ // varGetType for virtual fields.
+ // Unless you are using functions for virtual fields, the base implementation
+ // should work fine.
+ virtual ty *virtualFieldGetType(symbol *id);
+
+#if 0
+ // Returns the type. In case of functions, return the equivalent type
+ // but with no default values for parameters.
+ virtual ty *stripDefaults()
+ {
+ return this;
+ }
+#endif
+
+ // Returns true if the other type is equivalent to this one.
+ // The general function equivalent should be preferably used, as it properly
+ // handles overloaded type comparisons.
+ virtual bool equiv(ty *other)
+ {
+ return this==other;
+ }
+
+
+ // Returns a number for the type for use in a hash table. Equivalent types
+ // must yield the same number.
+ virtual size_t hash() = 0;
+};
+
+class primitiveTy : public ty {
+public:
+ primitiveTy(ty_kind kind)
+ : ty(kind) {}
+
+ bool primitive() {
+ return true;
+ }
+
+ bool isReference() {
+ return false;
+ }
+
+ virtual trans::varEntry *virtualField(symbol *, signature *);
+
+ bool equiv(ty *other)
+ {
+ return this->kind==other->kind;
+ }
+
+ size_t hash() {
+ return (size_t)kind + 47;
+ }
+};
+
+class nullTy : public primitiveTy {
+public:
+ nullTy()
+ : primitiveTy(ty_null) {}
+
+ bool isReference() {
+ return true;
+ }
+
+ trans::access *castTo(ty *target, caster &);
+
+ size_t hash() {
+ return (size_t)kind + 47;
+ }
+};
+
+// Ostream output, just defer to print.
+inline ostream& operator<< (ostream& out, const ty& t)
+{ t.print(out); return out; }
+
+struct array : public ty {
+ ty *celltype;
+ ty *pushtype;
+ ty *poptype;
+ ty *appendtype;
+ ty *inserttype;
+ ty *deletetype;
+
+ array(ty *celltype)
+ : ty(ty_array), celltype(celltype), pushtype(0), poptype(0),
+ appendtype(0), inserttype(0), deletetype(0) {}
+
+ virtual bool isReference() {
+ return true;
+ }
+
+ bool equiv(ty *other) {
+ return other->kind==ty_array &&
+ equivalent(this->celltype,((array *)other)->celltype);
+ }
+
+ size_t hash() {
+ return 1007 * celltype->hash();
+ }
+
+ Int depth() {
+ if (array *cell=dynamic_cast<array *>(celltype))
+ return cell->depth() + 1;
+ else
+ return 1;
+ }
+
+ void print(ostream& out) const
+ { out << *celltype << "[]"; }
+
+ ty *pushType();
+ ty *popType();
+ ty *appendType();
+ ty *insertType();
+ ty *deleteType();
+
+ // Initialize to an empty array by default.
+ trans::access *initializer();
+
+ // NOTE: General vectorization of casts would be here.
+
+ // Add length and push as virtual fields.
+ ty *virtualFieldGetType(symbol *id);
+ trans::varEntry *virtualField(symbol *id, signature *sig);
+};
+
+/* Base types */
+#define PRIMITIVE(name,Name,asyName) ty *prim##Name();
+#define PRIMERROR
+#include <primitives.h>
+#undef PRIMERROR
+#undef PRIMITIVE
+
+ty *primNull();
+
+ty *boolArray();
+ty *IntArray();
+ty *realArray();
+ty *pairArray();
+ty *tripleArray();
+ty *stringArray();
+ty *transformArray();
+ty *pathArray();
+ty *penArray();
+ty *guideArray();
+
+ty *boolArray2();
+ty *IntArray2();
+ty *realArray2();
+ty *pairArray2();
+ty *tripleArray2();
+ty *stringArray2();
+ty *pathArray2();
+ty *penArray2();
+
+ty *boolArray3();
+ty *IntArray3();
+ty *realArray3();
+ty *pairArray3();
+ty *tripleArray3();
+ty *stringArray3();
+
+struct formal {
+ ty *t;
+ symbol *name;
+ absyntax::varinit *defval;
+ bool Explicit;
+
+ formal(ty *t,
+ symbol *name=0,
+ bool optional=false,
+ bool Explicit=false)
+ : t(t), name(name),
+ defval(optional ? absyntax::Default : 0), Explicit(Explicit) {}
+
+ formal(ty *t,
+ const char *name,
+ bool optional=false,
+ bool Explicit=false)
+ : t(t), name(symbol::trans(name)),
+ defval(optional ? absyntax::Default : 0), Explicit(Explicit) {}
+
+ friend ostream& operator<< (ostream& out, const formal& f);
+};
+
+bool equivalent(formal& f1, formal& f2);
+bool argumentEquivalent(formal &f1, formal& f2);
+
+typedef mem::vector<formal> formal_vector;
+
+// Holds the parameters of a function and if they have default values
+// (only applicable in some cases).
+struct signature : public gc {
+ formal_vector formals;
+
+ // Formal for the rest parameter. If there is no rest parameter, then the
+ // type is null.
+ formal rest;
+
+ bool isOpen;
+
+ signature()
+ : rest(0), isOpen(false)
+ {}
+
+ static const struct OPEN_t {} OPEN;
+
+ explicit signature(OPEN_t) : rest(0), isOpen(true) {}
+
+ signature(signature &sig)
+ : formals(sig.formals), rest(sig.rest), isOpen(sig.isOpen)
+ {}
+
+ virtual ~signature() {}
+
+ void add(formal f) {
+ formals.push_back(f);
+ }
+
+ void addRest(formal f) {
+ rest=f;
+ }
+
+ bool hasRest() {
+ return rest.t;
+ }
+ size_t getNumFormals() {
+ return rest.t ? formals.size() + 1 : formals.size();
+ }
+
+ formal& getFormal(size_t n) {
+ assert(n < formals.size());
+ return formals[n];
+ }
+
+ formal& getRest() {
+ return rest;
+ }
+
+ friend ostream& operator<< (ostream& out, const signature& s);
+
+ friend bool equivalent(signature *s1, signature *s2);
+
+ // Check if a signature of argument types (as opposed to formal parameters)
+ // are equivalent. Here, the arguments, if named, must have the same names,
+ // and (for simplicity) no overloaded arguments are allowed.
+ friend bool argumentEquivalent(signature *s1, signature *s2);
+#if 0
+ friend bool castable(signature *target, signature *source);
+ friend Int numFormalsMatch(signature *s1, signature *s2);
+#endif
+
+ size_t hash();
+};
+
+struct function : public ty {
+ ty *result;
+ signature sig;
+
+ function(ty *result)
+ : ty(ty_function), result(result) {}
+ function(ty *result, signature::OPEN_t)
+ : ty(ty_function), result(result), sig(signature::OPEN) {}
+ function(ty *result, signature *sig)
+ : ty(ty_function), result(result), sig(*sig) {}
+ function(ty *result, formal f1)
+ : ty(ty_function), result(result) {
+ add(f1);
+ }
+ function(ty *result, formal f1, formal f2)
+ : ty(ty_function), result(result) {
+ add(f1);
+ add(f2);
+ }
+ function(ty *result, formal f1, formal f2, formal f3)
+ : ty(ty_function), result(result) {
+ add(f1);
+ add(f2);
+ add(f3);
+ }
+ function(ty *result, formal f1, formal f2, formal f3, formal f4)
+ : ty(ty_function), result(result) {
+ add(f1);
+ add(f2);
+ add(f3);
+ add(f4);
+ }
+ virtual ~function() {}
+
+ void add(formal f) {
+ sig.add(f);
+ }
+
+ void addRest(formal f) {
+ sig.addRest(f);
+ }
+
+ virtual bool isReference() {
+ return true;
+ }
+
+ bool equiv(ty *other)
+ {
+ if (other->kind==ty_function) {
+ function *that=(function *)other;
+ return equivalent(this->result,that->result) &&
+ equivalent(&this->sig,&that->sig);
+ }
+ else return false;
+ }
+
+ size_t hash() {
+ return sig.hash()*0x1231+result->hash();
+ }
+
+ void print(ostream& out) const
+ { out << *result << sig; }
+
+ void printVar (ostream& out, symbol *name) const {
+ result->printVar(out,name);
+ out << sig;
+ }
+
+ ty *getResult() {
+ return result;
+ }
+
+ signature *getSignature() {
+ return &sig;
+ }
+
+#if 0
+ ty *stripDefaults();
+#endif
+
+ // Initialized to null.
+ trans::access *initializer();
+};
+
+typedef mem::vector<ty *> ty_vector;
+
+// This is used in getType expressions when an overloaded variable is accessed.
+class overloaded : public ty {
+public:
+ ty_vector sub;
+public:
+ overloaded()
+ : ty(ty_overloaded) {}
+ virtual ~overloaded() {}
+
+ bool equiv(ty *other)
+ {
+ for(ty_vector::iterator i=sub.begin();i!=sub.end();++i)
+ if (equivalent(*i,other))
+ return true;
+ return false;
+ }
+
+ size_t hash() {
+ // Overloaded types should not be hashed.
+ assert(False);
+ return 0;
+ }
+
+ void add(ty *t) {
+ if (t->kind == ty_overloaded) {
+ overloaded *ot = (overloaded *)t;
+ copy(ot->sub.begin(), ot->sub.end(),
+ inserter(this->sub, this->sub.end()));
+ }
+ else
+ sub.push_back(t);
+ }
+
+ // Only add a type distinct from the ones currently in the overloaded type.
+ // If special is false, just the distinct signatures are added.
+ void addDistinct(ty *t, bool special=false);
+
+ // If there are less than two overloaded types, the type isn't really
+ // overloaded. This gives a more appropriate type in this case.
+ ty *simplify() {
+ switch (sub.size()) {
+ case 0:
+ return 0;
+ case 1: {
+ return sub.front();
+ }
+ default:
+ return new overloaded(*this);
+ }
+ }
+
+ // Returns the signature-less type of the set.
+ ty *signatureless();
+
+ // True if one of the subtypes is castable.
+ bool castable(ty *target, caster &c);
+
+ // Use default printing for now.
+};
+
+// This is used to encapsulate iteration over the subtypes of an overloaded
+// type. The base method need only be implemented to handle non-overloaded
+// types.
+class collector {
+public:
+ virtual ~collector() {}
+ virtual ty *base(ty *target, ty *source) = 0;
+
+ virtual ty *collect(ty *target, ty *source) {
+ if (overloaded *o=dynamic_cast<overloaded *>(target)) {
+ ty_vector &sub=o->sub;
+
+ overloaded *oo=new overloaded;
+ for(ty_vector::iterator x = sub.begin(); x != sub.end(); ++x) {
+ types::ty *t=collect(*x, source);
+ if (t)
+ oo->add(t);
+ }
+
+ return oo->simplify();
+ }
+ else if (overloaded *o=dynamic_cast<overloaded *>(source)) {
+ ty_vector &sub=o->sub;
+
+ overloaded *oo=new overloaded;
+ for(ty_vector::iterator y = sub.begin(); y != sub.end(); ++y) {
+ // NOTE: A possible speed optimization would be to replace this with a
+ // call to base(), but this is only correct if we can guarantee that an
+ // overloaded type has no overloaded sub-types.
+ types::ty *t=collect(target, *y);
+ if (t)
+ oo->add(t);
+ }
+
+ return oo->simplify();
+ }
+ else
+ return base(target, source);
+ }
+};
+
+class tester {
+public:
+ virtual ~tester() {}
+ virtual bool base(ty *target, ty *source) = 0;
+
+ virtual bool test(ty *target, ty *source) {
+ if (overloaded *o=dynamic_cast<overloaded *>(target)) {
+ ty_vector &sub=o->sub;
+
+ for(ty_vector::iterator x = sub.begin(); x != sub.end(); ++x)
+ if (test(*x, source))
+ return true;
+
+ return false;
+ }
+ else if (overloaded *o=dynamic_cast<overloaded *>(source)) {
+ ty_vector &sub=o->sub;
+
+ for(ty_vector::iterator y = sub.begin(); y != sub.end(); ++y)
+ if (base(target, *y))
+ return true;
+
+ return false;
+ }
+ else
+ return base(target, source);
+ }
+};
+
+} // namespace types
+
+GC_DECLARE_PTRFREE(types::primitiveTy);
+GC_DECLARE_PTRFREE(types::nullTy);
+
+#endif
diff --git a/Build/source/utils/asymptote/util.cc b/Build/source/utils/asymptote/util.cc
new file mode 100644
index 00000000000..b9557870f91
--- /dev/null
+++ b/Build/source/utils/asymptote/util.cc
@@ -0,0 +1,386 @@
+/*****
+ * util.cc
+ * John Bowman
+ *
+ * A place for useful utility functions.
+ *****/
+
+#include <cassert>
+#include <iostream>
+#include <cstdio>
+#include <cfloat>
+#include <sstream>
+#include <cerrno>
+#include <sys/wait.h>
+#include <sys/param.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <signal.h>
+#include <cstring>
+#include <algorithm>
+
+#include "util.h"
+#include "settings.h"
+#include "errormsg.h"
+#include "camperror.h"
+#include "interact.h"
+
+using namespace settings;
+
+bool False=false;
+
+namespace vm {
+void error(const char* message);
+}
+
+char *Strdup(string s)
+{
+ size_t size=s.size()+1;
+ char *dest=new(UseGC) char[size];
+ std::memcpy(dest,s.c_str(),size*sizeof(char));
+ return dest;
+}
+
+char *StrdupNoGC(string s)
+{
+ size_t size=s.size()+1;
+ char *dest=new char[size];
+ std::memcpy(dest,s.c_str(),size*sizeof(char));
+ return dest;
+}
+
+char *StrdupMalloc(string s)
+{
+ size_t size=s.size()+1;
+ char *dest=(char *) std::malloc(size);
+ std::memcpy(dest,s.c_str(),size*sizeof(char));
+ return dest;
+}
+
+string stripDir(string name)
+{
+ size_t p;
+#ifdef __CYGWIN__
+ p=name.rfind('\\');
+ if(p < string::npos) name.erase(0,p+1);
+#endif
+ p=name.rfind('/');
+ if(p < string::npos) name.erase(0,p+1);
+ return name;
+}
+
+string stripFile(string name)
+{
+ size_t p;
+ bool dir=false;
+#ifdef __CYGWIN__
+ p=name.rfind('\\');
+ if(p < string::npos) {
+ dir=true;
+ name.erase(p+1);
+ }
+#endif
+ p=name.rfind('/');
+ if(p < string::npos) {
+ dir=true;
+ name.erase(p+1);
+ }
+
+ return dir ? name : "";
+}
+
+string stripExt(string name, const string& ext)
+{
+ string suffix="."+ext;
+ size_t p=name.rfind(suffix);
+ size_t n=suffix.length();
+ if(n == 1 || p == name.length()-n)
+ return name.substr(0,p);
+ else return name;
+}
+
+void backslashToSlash(string& s)
+{
+ size_t p;
+ while((p=s.find('\\')) < string::npos)
+ s[p]='/';
+}
+
+void spaceToUnderscore(string& s)
+{
+ size_t p;
+ while((p=s.find(' ')) < string::npos)
+ s[p]='_';
+}
+
+string Getenv(const char *name, bool msdos)
+{
+ char *s=getenv(name);
+ if(!s) return "";
+ string S=string(s);
+ if(msdos) backslashToSlash(S);
+ return S;
+}
+
+void writeDisabled()
+{
+ camp::reportError("Write/cd to other directories disabled; override with option -globalwrite");
+}
+
+bool globalwrite(string name)
+{
+ string outname=settings::outname();
+ return (!outname.empty() && name.substr(0,outname.size()) == outname) ||
+ globalwrite();
+}
+
+void checkLocal(string name)
+{
+ if(globalwrite(name)) return;
+#ifdef __CYGWIN__
+ if(name.rfind('\\') < string::npos) writeDisabled();
+#endif
+ if(name.rfind('/') < string::npos) writeDisabled();
+ return;
+}
+
+string buildname(string name, string suffix, string aux)
+{
+ if(!globalwrite(name))
+ name=stripDir(name);
+
+ name=stripExt(name,defaultformat());
+ name += aux;
+ if(!suffix.empty()) name += "."+suffix;
+ return name;
+}
+
+string auxname(string filename, string suffix)
+{
+ return buildname(filename,suffix,"_");
+}
+
+char **args(const char *command, bool quiet)
+{
+ if(command == NULL) return NULL;
+
+ size_t n=0;
+ char **argv=NULL;
+ for(int pass=0; pass < 2; ++pass) {
+ if(pass) argv=new char*[n+1];
+ ostringstream buf;
+ const char *p=command;
+ bool empty=true;
+ bool quote=false;
+ n=0;
+ char c;
+ while((c=*(p++))) {
+ if(!quote && c == ' ') {
+ if(!empty) {
+ if(pass) {
+ argv[n]=StrdupNoGC(buf.str());
+ buf.str("");
+ }
+ empty=true;
+ n++;
+ }
+ } else {
+ empty=false;
+ if(c == '\'') quote=!quote;
+ else if(pass) buf << c;
+ }
+ }
+ if(!empty) {
+ if(pass) argv[n]=StrdupNoGC(buf.str());
+ n++;
+ }
+ }
+
+ if(!quiet && settings::verbose > 1) {
+ cerr << argv[0];
+ for(size_t m=1; m < n; ++m) cerr << " " << argv[m];
+ cerr << endl;
+ }
+
+ argv[n]=NULL;
+ return argv;
+}
+
+void execError(const char *command, const char *hint, const char *application)
+{
+ cerr << "Cannot execute " << command << endl;
+ if(*application == 0) application=hint;
+ if(hint) {
+ string s=string(hint);
+ transform(s.begin(), s.end(), s.begin(), toupper);
+ cerr << "Please put in " << getSetting<string>("config")
+ << ": " << endl << endl
+ << "import settings;" << endl
+ << hint << "=\"PATH\";" << endl << endl
+ << "where PATH denotes the correct path to "
+ << application << "." << endl << endl
+ << "Alternatively, set the environment variable ASYMPTOTE_" << s
+ << endl << "or use the command line option -" << hint
+ << "=\"PATH\"" << endl;
+ }
+}
+
+// quiet: 0=none; 1=suppress stdout; 2=suppress stdout+stderr.
+
+int System(const char *command, int quiet, bool wait,
+ const char *hint, const char *application, int *ppid)
+{
+ int status;
+
+ if(!command) return 1;
+
+ cout.flush(); // Flush stdout to avoid duplicate output.
+
+ char **argv=args(command);
+
+ int pid=fork();
+ if(pid == -1)
+ camp::reportError("Cannot fork process");
+
+ if(pid == 0) {
+ if(interact::interactive) signal(SIGINT,SIG_IGN);
+ if(quiet) {
+ static int null=creat("/dev/null",O_WRONLY);
+ close(STDOUT_FILENO);
+ dup2(null,STDOUT_FILENO);
+ if(quiet == 2) {
+ close(STDERR_FILENO);
+ dup2(null,STDERR_FILENO);
+ }
+ }
+ if(argv) {
+ execvp(argv[0],argv);
+ execError(argv[0],hint,application);
+ _exit(-1);
+ }
+ }
+
+ if(ppid) *ppid=pid;
+ for(;;) {
+ if(waitpid(pid, &status, wait ? 0 : WNOHANG) == -1) {
+ if(errno == ECHILD) return 0;
+ if(errno != EINTR) {
+ if(quiet < 2) {
+ ostringstream msg;
+ msg << "Command failed: " << command;
+ camp::reportError(msg);
+ }
+ }
+ } else {
+ if(!wait) return 0;
+ if(WIFEXITED(status)) {
+ if(argv) {
+ char **p=argv;
+ char *s;
+ while((s=*(p++)) != NULL)
+ delete [] s;
+ delete [] argv;
+ }
+ return WEXITSTATUS(status);
+ } else {
+ if(quiet < 2) {
+ ostringstream msg;
+ msg << "Command exited abnormally: " << command;
+ camp::reportError(msg);
+ }
+ }
+ }
+ }
+}
+
+int System(const ostringstream& command, int quiet, bool wait,
+ const char *hint, const char *application, int *pid)
+{
+ return System(command.str().c_str(),quiet,wait,hint,application,pid);
+}
+
+string stripblanklines(const string& s)
+{
+ string S=string(s);
+ bool blank=true;
+ const char *t=S.c_str();
+ size_t len=S.length();
+
+ for(size_t i=0; i < len; i++) {
+ if(t[i] == '\n') {
+ if(blank) S[i]=' ';
+ else blank=true;
+ } else if(t[i] != '\t' && t[i] != ' ') blank=false;
+ }
+ return S;
+}
+
+char *startpath=NULL;
+
+void noPath()
+{
+ camp::reportError("Cannot get current path");
+}
+
+char *getPath(char *p)
+{
+ static size_t size=MAXPATHLEN;
+ if(!p) p=new(UseGC) char[size];
+ if(!p) noPath();
+ else while(getcwd(p,size) == NULL) {
+ if(errno == ERANGE) {
+ size *= 2;
+ p=new(UseGC) char[size];
+ } else {noPath(); p=NULL;}
+ }
+ return p;
+}
+
+const char *setPath(const char *s, bool quiet)
+{
+ if(startpath == NULL) startpath=getPath(startpath);
+ if(s == NULL || *s == 0) s=startpath;
+ int rc=chdir(s);
+ if(rc != 0) {
+ ostringstream buf;
+ buf << "Cannot change to directory '" << s << "'";
+ camp::reportError(buf);
+ }
+ char *p=getPath();
+ if(p && (!interact::interactive || quiet) && verbose > 1)
+ cout << "cd " << p << endl;
+ return p;
+}
+
+void popupHelp() {
+ // If the popped-up help is already running, pid stores the pid of the viewer.
+ static int pid=0;
+
+ // Status is ignored.
+ static int status=0;
+
+ // If the help viewer isn't running (or its last run has termined), launch the
+ // viewer again.
+ if (pid==0 || (waitpid(pid, &status, WNOHANG) == pid)) {
+ ostringstream cmd;
+ cmd << "'" << getSetting<string>("pdfviewer") << "' "
+ << docdir << "/asymptote.pdf";
+ status=System(cmd,0,false,"pdfviewer","your PDF viewer",&pid);
+ }
+}
+
+unsigned unsignedcast(Int n)
+{
+ if(n < 0 || n/2 > INT_MAX)
+ vm::error("Unsigned integer argument is outside valid range");
+ return (unsigned) n;
+}
+
+int intcast(Int n)
+{
+ if(Abs(n) > INT_MAX)
+ vm::error("Integer argument is outside valid range");
+ return (int) n;
+}
diff --git a/Build/source/utils/asymptote/util.h b/Build/source/utils/asymptote/util.h
new file mode 100644
index 00000000000..940d346e4e9
--- /dev/null
+++ b/Build/source/utils/asymptote/util.h
@@ -0,0 +1,124 @@
+/*****
+ * util.h
+ * Andy Hammerlindl 2004/05/10
+ *
+ * A place for useful utility functions.
+ *****/
+
+#ifndef UTIL_H
+#define UTIL_H
+
+#include <sys/types.h>
+#include <iostream>
+#include <cstdlib>
+
+#include "common.h"
+
+#include <strings.h>
+
+// Duplicate a string.
+char *Strdup(string s);
+char *StrdupNoGC(string s);
+char *StrdupMalloc(string s);
+
+// Strip the directory from a filename.
+string stripDir(string name);
+
+// Strip the file from a filename, returning the directory.
+string stripFile(string name);
+
+// Strip the extension from a filename.
+string stripExt(string name, const string& suffix="");
+
+void writeDisabled();
+
+// Check if global writes are disabled and name contains a directory.
+void checkLocal(string name);
+
+// Construct a filename from the original, adding aux at the end, and
+// changing the suffix.
+string buildname(string filename, string suffix="", string aux="");
+
+// Construct an alternate filename for a temporary file in the current
+// directory.
+string auxname(string filename, string suffix="");
+
+// Return an argv array corresponding to the fields in command delimited
+// by spaces not within matching single quotes.
+char **args(const char *command, bool quiet=false);
+
+// Similar to the standard system call except allows interrupts and does
+// not invoke a shell.
+int System(const char *command, int quiet=0, bool wait=true,
+ const char *hint=NULL, const char *application="",
+ int *pid=NULL);
+int System(const ostringstream& command, int quiet=0, bool wait=true,
+ const char *hint=NULL, const char *application="",
+ int *pid=NULL);
+
+#if defined(__DECCXX_LIBCXX_RH70)
+extern "C" int kill(pid_t pid, Int sig) throw();
+extern "C" char *strsignal(Int sig);
+extern "C" double asinh(double x);
+extern "C" double acosh(double x);
+extern "C" double atanh(double x);
+extern "C" double cbrt(double x);
+extern "C" double erf(double x);
+extern "C" double erfc(double x);
+extern "C" double tgamma(double x);
+extern "C" double remainder(double x, double y);
+extern "C" double hypot(double x, double y) throw();
+extern "C" double jn(Int n, double x);
+extern "C" double yn(Int n, double x);
+#endif
+
+#if defined(__mips)
+extern "C" double tgamma(double x);
+#endif
+
+#if defined(__DECCXX_LIBCXX_RH70) || defined(__CYGWIN__)
+extern "C" int snprintf(char *str, size_t size, const char *format,...);
+extern "C" int fileno(FILE *);
+extern "C" char *strptime(const char *s, const char *format, struct tm *tm);
+extern "C" int setenv(const char *name, const char *value, int overwrite);
+#endif
+
+extern bool False;
+
+// Strip blank lines (which would break the bidirectional TeX pipe)
+string stripblanklines(const string& s);
+
+extern char *currentpath;
+
+const char *startPath();
+const char* setPath(const char *s, bool quiet=false);
+const char *changeDirectory(const char *s);
+extern char *startpath;
+
+void backslashToSlash(string& s);
+void spaceToUnderscore(string& s);
+string Getenv(const char *name, bool msdos);
+char *getPath(char *p=NULL);
+
+void execError(const char *command, const char *hint, const char *application);
+
+// This invokes a viewer to display the manual. Subsequent calls will only
+// pop-up a new viewer if the old one has been closed.
+void popupHelp();
+
+inline Int Abs(Int x) {
+#ifdef HAVE_LONG_LONG
+ return llabs(x);
+#else
+#ifdef HAVE_LONG
+ return labs(x);
+#else
+ return abs(x);
+#endif
+#endif
+}
+
+unsigned unsignedcast(Int n);
+int intcast(Int n);
+
+#endif
diff --git a/Build/source/utils/asymptote/varinit.cc b/Build/source/utils/asymptote/varinit.cc
new file mode 100644
index 00000000000..9b53dae8500
--- /dev/null
+++ b/Build/source/utils/asymptote/varinit.cc
@@ -0,0 +1,79 @@
+/*****
+ * varinit.cc
+ * Andy Hammerlindl 2005/07/01
+ *
+ * Variable initializer are syntax that finish code such as
+ * int var = ...
+ * As such, they are translated to yield a certain type, the type of the
+ * variable. Expressions are a special case that can be translated without an
+ * associated variable or its type.
+ *****/
+
+#include "varinit.h"
+#include "coenv.h"
+#include "runtime.h"
+
+namespace absyntax {
+
+using namespace types;
+using namespace trans;
+
+void definit::prettyprint(ostream &out, Int indent)
+{
+ prettyname(out, "definit",indent);
+}
+
+void definit::transToType(coenv &e, types::ty *target)
+{
+ if (target->kind != ty_error) {
+ access *a=e.e.lookupInitializer(target);
+
+ if (a)
+ a->encode(CALL, getPos(), e.c);
+ else {
+ em.error(getPos());
+ em << "no default initializer for type '" << *target << "'";
+ }
+ }
+}
+
+void arrayinit::prettyprint(ostream &out, Int indent)
+{
+ prettyname(out, "arrayinit",indent);
+
+ for (mem::list<varinit *>::iterator p = inits.begin(); p != inits.end(); ++p)
+ (*p)->prettyprint(out, indent+2);
+ if (rest)
+ rest->prettyprint(out, indent+1);
+}
+
+void arrayinit::transMaker(coenv &e, Int size, bool rest) {
+ // Push the number of cells and call the array maker.
+ e.c.encode(inst::intpush, size);
+ e.c.encode(inst::builtin, rest ? run::newAppendedArray :
+ run::newInitializedArray);
+}
+
+void arrayinit::transToType(coenv &e, types::ty *target)
+{
+ types::ty *celltype;
+ if (target->kind != types::ty_array) {
+ em.error(getPos());
+ em << "array initializer used for non-array";
+ celltype = types::primError();
+ }
+ else {
+ celltype = ((types::array *)target)->celltype;
+ }
+
+ // Push the values on the stack.
+ for (mem::list<varinit *>::iterator p = inits.begin(); p != inits.end(); ++p)
+ (*p)->transToType(e, celltype);
+
+ if (rest)
+ rest->transToType(e, target);
+
+ transMaker(e, (Int)inits.size(), (bool)rest);
+}
+
+} // namespace absyntax
diff --git a/Build/source/utils/asymptote/varinit.h b/Build/source/utils/asymptote/varinit.h
new file mode 100644
index 00000000000..721242dac29
--- /dev/null
+++ b/Build/source/utils/asymptote/varinit.h
@@ -0,0 +1,87 @@
+/*****
+ * varinit.h
+ * Andy Hammerlindl 2005/07/01
+ *
+ * Variable initializers are syntax that finish code such as
+ * Int var = ...
+ * As such, they are translated to yield a certain type, the type of the
+ * variable. Expressions are a special case that can be translated without an
+ * associated variable or its type.
+ *****/
+
+#ifndef VARINIT_H
+#define VARINIT_H
+
+#include "types.h"
+#include "symbol.h"
+#include "absyn.h"
+
+namespace absyntax {
+
+using trans::coenv;
+using trans::access;
+using sym::symbol;
+using types::array;
+
+class varinit : public absyn {
+public:
+ varinit(position pos)
+ : absyn(pos) {}
+
+ // This determines what instruction are needed to put the associated
+ // value onto the stack, then adds those instructions to the current
+ // lambda in e.
+ // In some expressions and initializers, the target type needs to be
+ // known in order to translate properly. For most expressions, this is
+ // kept to a minimum.
+ // For expression, this also allows an implicit cast, hence the name.
+ virtual void transToType(coenv &e, types::ty *target) = 0;
+};
+
+// A default initializer. For example:
+// int a;
+// is in some sense equivalent to
+// int a=0;
+// where the definit for Int is a function that returns 0.
+class definit : public varinit {
+public:
+ definit(position pos)
+ : varinit(pos) {}
+
+ void prettyprint(ostream &out, Int indent);
+
+ void transToType(coenv &e, types::ty *target);
+};
+
+class arrayinit : public varinit {
+ mem::list<varinit *> inits;
+
+ varinit *rest;
+public:
+ arrayinit(position pos)
+ : varinit(pos), rest(0) {}
+
+ virtual ~arrayinit()
+ {}
+
+ void prettyprint(ostream &out, Int indent);
+
+ // Encodes the instructions to make an array from size elements on the stack.
+ static void transMaker(coenv &e, Int size, bool rest);
+
+ void transToType(coenv &e, types::ty *target);
+
+ void add(varinit *init) {
+ inits.push_back(init);
+ }
+
+ void addRest(varinit *init) {
+ rest=init;
+ }
+
+ friend class joinExp;
+};
+
+} // namespace absyntax
+
+#endif
diff --git a/Build/source/utils/asymptote/vm.h b/Build/source/utils/asymptote/vm.h
new file mode 100644
index 00000000000..ba666dc64d5
--- /dev/null
+++ b/Build/source/utils/asymptote/vm.h
@@ -0,0 +1,26 @@
+/*****
+ * vm.h
+ * Tom Prince 2005/06/17
+ *
+ * Interface to the virtual machine.
+ *****/
+
+#ifndef VM_H
+#define VM_H
+
+#include "errormsg.h"
+
+namespace vm {
+
+class lambda; class stack;
+typedef void (*bltin)(stack *s);
+
+void run(lambda *l);
+position getPos();
+void errornothrow(const char* message);
+void error(const char* message);
+void error(const ostringstream& message);
+
+} // namespace vm
+
+#endif // VM_H
diff --git a/Build/source/utils/asymptote/wce b/Build/source/utils/asymptote/wce
new file mode 100755
index 00000000000..39aea5724f2
--- /dev/null
+++ b/Build/source/utils/asymptote/wce
@@ -0,0 +1,11 @@
+#!/bin/sh
+echo -n "Testing errors..."
+./asy -noautoplain -debug errortest 2> errors.temp
+result=`diff errors.temp errors`
+if [ "$result" = "" ]; then
+echo PASSED.
+else
+echo FAILED.
+echo "$result"
+exit 1
+fi
diff --git a/Build/source/utils/asymptote/xstream.h b/Build/source/utils/asymptote/xstream.h
new file mode 100644
index 00000000000..b1d91fa38cc
--- /dev/null
+++ b/Build/source/utils/asymptote/xstream.h
@@ -0,0 +1,253 @@
+/* C++ interface to the XDR External Data Representation I/O routines
+ Version 1.46
+ Copyright (C) 1999-2007 John C. Bowman
+
+ This program 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 3 of the License, or
+ (at your option) any later version.
+
+ This program 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 program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#ifndef __xstream_h__
+#define __xstream_h__ 1
+
+#ifndef _ALL_SOURCE
+#define _ALL_SOURCE 1
+#endif
+
+#include <cstdio>
+
+#include <sys/types.h>
+#include <rpc/types.h>
+
+#define quad_t long long
+
+#ifdef __CYGWIN__
+extern "C" int fseeko(FILE *, off_t, int);
+extern "C" off_t ftello(FILE *);
+#define xdr_longlong_t xdr_int64_t
+#endif
+
+#ifdef _POSIX_SOURCE
+#undef _POSIX_SOURCE
+#include <rpc/rpc.h>
+#define _POSIX_SOURCE
+#else
+#include <rpc/rpc.h>
+#endif
+
+namespace xdr {
+
+class xbyte {
+ unsigned char c;
+public:
+ xbyte() {}
+ xbyte(unsigned char c0) : c(c0) {}
+ xbyte(int c0) : c((unsigned char) c0) {}
+ xbyte(unsigned int c0) : c((unsigned char) c0) {}
+ int byte() const {return c;}
+ operator unsigned char () const {return c;}
+};
+
+class xios {
+public:
+ enum io_state {goodbit=0, eofbit=1, failbit=2, badbit=4};
+ enum open_mode {in=1, out=2, app=8, trunc=16};
+ enum seekdir {beg=SEEK_SET, cur=SEEK_CUR, end=SEEK_END};
+private:
+ int _state;
+public:
+ int good() const { return _state == 0; }
+ int eof() const { return _state & eofbit; }
+ int fail() const { return !good();}
+ int bad() const { return _state & badbit; }
+ void clear(int state = 0) {_state=state;}
+ void set(int flag) {_state |= flag;}
+ operator void*() const { return fail() ? (void*)0 : (void*)(-1); }
+ int operator!() const { return fail(); }
+};
+
+class xstream : public xios {
+protected:
+ FILE *buf;
+public:
+ virtual ~xstream() {}
+ xstream() {buf=NULL;}
+
+ void precision(int) {}
+
+ xstream& seek(off_t pos, seekdir dir=beg) {
+ if(buf) {
+ clear();
+ if(fseeko(buf,pos,dir) != 0) set(failbit);
+ }
+ return *this;
+ }
+ off_t tell() {
+ return ftello(buf);
+ }
+};
+
+#define IXSTREAM(T,N) ixstream& operator >> (T& x) \
+ {if(!xdr_##N(&xdri, &x)) set(eofbit); return *this;}
+
+#define OXSTREAM(T,N) oxstream& operator << (T x) \
+ {if(!xdr_##N(&xdro, &x)) set(badbit); return *this;}
+
+class ixstream : virtual public xstream {
+protected:
+ XDR xdri;
+public:
+ void open(const char *filename, open_mode=in) {
+ clear();
+ buf=fopen(filename,"r");
+ if(buf) xdrstdio_create(&xdri,buf,XDR_DECODE);
+ else set(badbit);
+ }
+
+ void close() {
+ if(buf) {
+#ifndef _CRAY
+ xdr_destroy(&xdri);
+#endif
+ fclose(buf);
+ buf=NULL;
+ }
+ }
+
+ ixstream() {}
+ ixstream(const char *filename) {open(filename);}
+ ixstream(const char *filename, open_mode mode) {open(filename,mode);}
+ virtual ~ixstream() {close();}
+
+ typedef ixstream& (*imanip)(ixstream&);
+ ixstream& operator >> (imanip func) { return (*func)(*this); }
+
+ IXSTREAM(int,int);
+ IXSTREAM(unsigned int,u_int);
+ IXSTREAM(long,long);
+ IXSTREAM(long long,longlong_t);
+ IXSTREAM(unsigned long,u_long);
+ IXSTREAM(short,short);
+ IXSTREAM(unsigned short,u_short);
+ IXSTREAM(char,char);
+#ifndef _CRAY
+ IXSTREAM(unsigned char,u_char);
+#endif
+ IXSTREAM(float,float);
+ IXSTREAM(double,double);
+
+ ixstream& operator >> (xbyte& x) {
+ x=fgetc(buf);
+ if(x.byte() == EOF) set(eofbit);
+ return *this;
+ }
+};
+
+class oxstream : virtual public xstream {
+protected:
+ XDR xdro;
+public:
+ void open(const char *filename, open_mode mode=trunc) {
+ clear();
+ buf=fopen(filename,(mode & app) ? "a" : "w");
+ if(buf) xdrstdio_create(&xdro,buf,XDR_ENCODE);
+ else set(badbit);
+ }
+
+ void close() {
+ if(buf) {
+#ifndef _CRAY
+ xdr_destroy(&xdro);
+#endif
+ fclose(buf);
+ buf=NULL;
+ }
+ }
+
+ oxstream() {}
+ oxstream(const char *filename) {open(filename);}
+ oxstream(const char *filename, open_mode mode) {open(filename,mode);}
+ virtual ~oxstream() {close();}
+
+ oxstream& flush() {if(buf) fflush(buf); return *this;}
+
+ typedef oxstream& (*omanip)(oxstream&);
+ oxstream& operator << (omanip func) { return (*func)(*this); }
+
+ OXSTREAM(int,int);
+ OXSTREAM(unsigned int,u_int);
+ OXSTREAM(long,long);
+ OXSTREAM(long long,longlong_t);
+ OXSTREAM(unsigned long,u_long);
+ OXSTREAM(short,short);
+ OXSTREAM(unsigned short,u_short);
+ OXSTREAM(char,char);
+#ifndef _CRAY
+ OXSTREAM(unsigned char,u_char);
+#endif
+ OXSTREAM(float,float);
+ OXSTREAM(double,double);
+
+ oxstream& operator << (xbyte x) {
+ if(fputc(x.byte(),buf) == EOF) set(badbit);
+ return *this;
+ }
+};
+
+class ioxstream : public ixstream, public oxstream {
+public:
+ void open(const char *filename, open_mode mode=out) {
+ clear();
+ if(mode & app)
+ buf=fopen(filename,"a+");
+ else if(mode & trunc)
+ buf=fopen(filename,"w+");
+ else if(mode & out) {
+ buf=fopen(filename,"r+");
+ if(!buf)
+ buf=fopen(filename,"w+");
+ } else
+ buf=fopen(filename,"r");
+ if(buf) {
+ xdrstdio_create(&xdri,buf,XDR_DECODE);
+ xdrstdio_create(&xdro,buf,XDR_ENCODE);
+ } else set(badbit);
+ }
+
+ void close() {
+ if(buf) {
+#ifndef _CRAY
+ xdr_destroy(&xdri);
+ xdr_destroy(&xdro);
+#endif
+ fclose(buf);
+ buf=NULL;
+ }
+ }
+
+ ioxstream() {}
+ ioxstream(const char *filename) {open(filename);}
+ ioxstream(const char *filename, open_mode mode) {open(filename,mode);}
+ virtual ~ioxstream() {close();}
+};
+
+inline oxstream& endl(oxstream& s) {s.flush(); return s;}
+inline oxstream& flush(oxstream& s) {s.flush(); return s;}
+
+#undef IXSTREAM
+#undef OXSTREAM
+
+}
+
+#undef quad_t
+
+#endif